Redis面试都卷到C语言去了。。。

Redis 面试都卷到 C 去了。有个小伙伴在前两天找松哥模面的时候如是说到。

是啊,没办法,自从 Java 八股文这个概念被提出来并且逐步在 Java 程序员中强化之后,现在各种各样的八股文手册,有免费的有付费的,琳琅满目。

单纯的八股文已经区分不出 Java 猿水平的高低了,所以现在面试总会卷出新高度。

这次是小伙伴面试时候被问到一个 SDS 的问题,也就是 Redis 中 String 字符串的底层实现原理。

我来和小伙伴们简单聊一聊这个话题。

一 String 类型

Redis 中有一个 String 类型,使用频率还比较高,我们日常做缓存、分布式锁都会用到。

很多小伙伴也都知道 Redis 是用 C 写的,那么就有一个问题,Redis 中的 String,底层数据结构是什么样的?

是不是就是 C 中的 String 呢?

二 C 中的 String

玩过 C 的小伙伴应该知道,C 语言本身并没有内置的 String 类型,但是 C 语言中可以使用字符数组(char array[])或指向字符的指针(char *pointer)来表示字符串。在 C 语言中,字符串是以空字符 '\0' 结尾的字符序列。例如:

char *str1 = "Hello, World!";

在这个例子中,str1 是一个指向字符串字面量 “Hello, World!” 的指针。

当我们在 Redis 中使用 String 的时候,很多小伙伴可能会想这个 String 可能就是 C 中的 String 吧?并不是!

为什么不直接使用 C 中的 String 呢?主要有以下几种考虑:

  1. char* 这种方式无法直接获取到字符串的长度,只能逐个字符去遍历,很明显效率低。
  2. C 中的字符串使用 \0 去表示字符串结束,这就导致我们没法在字符串中存储二进制数据,因为二进制中的数据可能会和 \0 冲突。
  3. C 中字符串在创建的时候长度和内存大小就都确定下来了,后期如果缩容和扩容都是创建新数组然后拷贝内容,操作方式过于麻烦。

有鉴于此,Redis 自己搞了个 SDS,全称是 Simple Dynamic String。这个 SDS 和 C 中的字符串的关系,有点像我们 Java 中 List 和数组的关系,有点

三 SDS

为了解决上述问题,小伙伴们可以先想想,我们都需要哪些东西呢?

  • 首先得有一个存储字符的 char 数组吧。
  • 数组的总长度得有一个变量记录下来吧。
  • 数组已经使用的长度得记录下来吧。

这是三个最基本的属性。

3.1 SDS 类型

当然在具体实践中还有一个 flags 属性,这个属性用来表示 SDS 的类型,因为 Redis 设计了几种不同的 SDS 类型,这样的设计主要是为了节省内存。

从这里可以看到,一共有五种不同的 SDS 类型,分别是:

  1. sdshdr5
  2. sdshdr8
  3. sdshdr16
  4. sdshdr32
  5. sdshdr64

从注释中可以看到,sdshdr5 其实没有使用,另外四个的区别主要在于数组长度和分配空间长度的差异。

以 sdshdr16 为例,uint16_t 表示 16 位无符号 int 值,能表示的最大值是 2^16-1,所以它的 buf 数组的最大长度就是 2^16。

按照这样的设计,其实 Redis 的字符串能够存储超大的字符串,例如,sdshdr32 类型意味着能够存储的字符长度是 2^32,一个字符占一个字节,就是 4GB。

可是实际上 Redis 的字符串存不了这么长的,Redis 内部会对字符串的长度进行限制,最大是 512MB。

当然实际生产中我们不建议这么搞,一般字符串最好不要超过 1MB。

3.2 编码格式

为了提升效率,SDS 中使用的编码格式也会根据情况来定。

  • 如果是数字类型,且数字长度小于 20,就会使用 int 编码。

  • 长度小于等于 44 字节的字符串,使用 embstr 编码。
  • 长度大于 44 字节的字符串使用 raw 编码。

3.3 其他特点

不同于 C 中的字符串,SDS 可以存储二进制数据,因为 SDS 不再通过 \0 去判断字符串结束,因为有一个 len 变量存储了字符串的长度。

同时,SDS 在字符串扩容的时候也会进行预分配,这些机制类似于咱们 Java 中 ArrayList 扩容、HashMap 扩容,扩容时会预留空间,避免频繁扩容。

同时,缩容的时候并不会立马释放多余空间,防止后续又要扩容。

四 小结

大致就这些东西,其实也不难。

松哥最近也录了一个 Redis 视频课,基于目前最新版的 Redis 来讲解,从用法到原理到经典面试题都有涉及,感兴趣的小伙伴可以看下。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/409583.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

秃姐学AI系列之:GoogLeNet + 代码实现

目录 GoogLeNet —— 含并行连结的网络 卷积层超参数 Inception块:小学生才做选择,我全要! 为什么要用Inception块? GoogLeNet架构 详细展开每个Stage Stage 1 & 2 Stage 3 Stage 4 & 5 Inception 有各种后续变…

CocosCreator3.8 IOS 构建插屏无法去除的解决方案

CocosCreator3.8 IOS 构建插屏无法去除的解决方案 在实际项目开发过程中,我们通常无需CocosCreator 自带的插屏,一般采用自定义加载页面。 然后在构建IOS 项目时,启用(禁用)插屏无法操作,如下图所示&#…

Unity Protobuf3 GC 问题(反序列化)

背景:Unity接入的是 Google Protobuf 3.21.12 版本,排查下来反序列化过程中的一些GC点,处理了几个严重的,网上也有一些分析,这里就不一一展开,默认读者已经略知一二了。 如果下面有任何问题请评论区留言提…

Web攻防之应急响应(一)

目录 1. 前言 2. 靶场准备 3. 应急场景 4. 应急实战 4.1 查看服务器开放端口 4.2 通过远程链接工具连接服务器 4.3 寻找中间件日志 4.4. 查看并下载日志 4.5 初步分析日志 4.6 查看安全分析报告 4.6 从被篡改的页面开始 4.6 通过修改的文件时间进一步分析日志信息 4.…

如何给10000张图片快速打标签,一招教你节省上千小时!看这期就够了!免费素材管理插件分享

如果给1万张图片打标签,你会怎么做?如果你用过eagle或者billfish的话,那么你一定知道,他们都没有支持用AI来自动给素材打标签。 一旦我们素材多起来的时候,手动输入,键盘都要打冒烟了,效率太低…

企业级NoSql数据库Redis集群

数据库主要分为两大类:关系型数据库与 NoSQL 数据库 关系型数据库 ,是建立在关系模型基础上的数据库,其借助于集合代数等数学概念和方法来处理数据库 中的数据主流的 MySQL 、 Oracle 、 MS SQL Server 和 DB2 都属于这类传统数据库。 …

中仕公考怎么样?2025国考报名流程介绍!

现在是八月下旬,距离2025年国考的开始日期越来越近,今天来给大家分享一下国考报名的流程,希望大家提前做个了解。 报考时间(参考去年) 职位表发布:24年10月中旬 网上报名:24年10月中下旬 报名确认:24年…

昂科烧录器支持Melexis迈来芯的位置传感器MLX90365KDC

芯片烧录行业领导者-昂科技术近日发布最新的烧录软件更新及新增支持的芯片型号列表,其中Melexis迈来芯的位置传感器MLX90365KDC已经被昂科的通用烧录平台AP8000所支持。 MLX90365KDC是第II代Triaxis位置传感器IC。 这款单片器件可凭借其表面的集磁点(IMC)&#xf…

ai变声:视频怎么变音?分享6个语音变声器,视频变声不再难!

想过如何让自己的直播内容更吸引人吗?你是否希望通过变声器来打造独特的声音效果?或者,如何用创意声音提升观众的互动体验呢?随着直播行业的不断发展,每位主播都在努力寻找吸引观众的独特方式,而变声器正是…

鸿蒙南向开发:测试框架xdevice核心组件

简介 xdevice是OpenHarmony中为测试框架的核心组件,提供用例执行所依赖的相关服务。 xdevice主要包括以下几个主要模块: command,用户与测试平台命令行交互模块,提供用户输入命令解析,命令处理。config,…

【机器学习】梯度下降算法

梯度下降算法 这篇博客更加详细,以下只是我个人的理解 梯度下降算法原理讲解——机器学习-CSDN博客 梯度下降算法是一种优化算法,通过梯度下降找到函数最小值时的自变量值。 其基本思想是沿着梯度方向的反方向更新参数,直到逼近函数的极值…

DaxPay:一套开源支付网关系统【送源码】

项目介绍 DaxPay是一套开源支付网关系统,已经对接支付宝、微信支付、云闪付相关的接口。可以独立部署,提供接口供业务系统进行调用,不对原有系统产生影响 特色功能 封装各类支付通道的接口为统一的接口,方便业务系统进行调用&am…

wps题注为表格或图片编号

word中为表格添加题注: 问题:多次或多人编辑导致--序号不能联动更新(域代码不一致,如图) 所以是否可以批量替换word里的域代码?如果可以这问题就解决了————失败 解决办法: 如图,复制表头&…

uni-app 手记集。

1、uni-app 是一个使用 Vue.js 开发的前端应用的框架&#xff0c;所以不会Vue.js的小伙伴可以先去看看Vue.js的基础教学。 2、.vue文件结构 <template><div class"container"></div> </template><script type"text/ecmascript-6&q…

Code Llama: Open Foundation Models for Code论文阅读

整体介绍 Code Llama 发布了3款模型&#xff0c;包括基础模型、Python 专有模型和指令跟随模型&#xff0c;参数量分别为 7B、13B、34B 和 70B。这些模型在长达 16k tokens 的序列上训练。都是基于 Llama 2。 作者针对infilling (FIM) 、长上下文、指令专门做了微调 long-con…

内网穿透的应用-戴森球计划利用cpolar内网穿透实现好友异地远程联机游戏

文章目录 游戏简介1. 下载MOD2.配置cpolar内网穿透3. 主机开启联机3.1 玩家加入游戏 4. 配置固定的TCP端口5. 游玩体验 游戏简介 《戴森球计划》是一款融合了科幻冒险与经营管理元素的优秀游戏。玩家将在浩瀚宇宙中探索未知星球&#xff0c;建立从零开始的工业帝国&#xff0c…

流媒体服务器如何让WebRTC支持H.265,同时又能支持Web js硬解码、软解码(MSE硬解、WASM软解)

为了这一整套的解决方案&#xff0c;调研研发整整花费了差不多半年多的时间&#xff0c;需达成的目标&#xff1a; 流媒体服务器端不需要将H.265转码成H.264&#xff0c;就能让Chrome解码播放H.265&#xff1b; 注意&#xff1a;现在很多市面上的软硬件通过转码H.265成H.264的…

xss-labs靶场6-10关

第六关 使用a标签&#xff0c;发现a标签可以。 "><a hreFjavascript:alert(aa)>aa</a> 点击aa 第七关 使用双写绕过 1"><ScscriptRipt>alert(1)</ScscriptRipt> 第八关 将javascript:alert(1)进行编码 然后将编码输入再次点击链…

day8JS-作用域

1. 变量的作用域(变量函数) 作用域是变量的可作用范围&#xff0c;变量只有在自己的作用域下才会生效。 函数会产生作用域&#xff0c;在函数内定义的变量只能在函数内使用。 2. 作用域分类 局部作用域&#xff1a; 函数内定义的变量和形参的作用域就是局部作用域&#xff1b;这…

基于SpringBoot的酒店管理系统

你好呀&#xff0c;我是计算机学姐码农小野&#xff01;如果有相关需求&#xff0c;可以私信联系我。 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SpringBoot框架技术 工具&#xff1a;IDEA/Eclipse、Navicat、Maven 系统展示 首页 用户注册界面…