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'开头的字符序列。例如:

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

当我们在 Redis 中经常使用 String 的时刻,很多小同伴或者会想这个 String 或者就是 C 中的 String 吧?并不是!

为什么不间接经常使用 C 中的 String 呢?关键有以下几种思考:

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

三 SDS

为了处置上述疑问,小同伴们可以先想想,我们都须要哪些物品呢?

这是三个最基本的属性。

3.1 SDS 类型

当然在详细通常中还有一个 flags 属性,这个属性用来示意 SDS 的类型,由于 Redis 设计了几种不同的 SDS 类型,这样的设计关键是为了节俭内存。

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

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

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

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

可是实践上 Redis 的字符串存不了这么长的,Redis 外部会对字符串的长度启动限度,最大是 512MB。

当然实践消费中我们不倡导这么搞,普通字符串最好不要超越 1MB。

3.2 编码格局

为了优化效率,SDS 中经常使用的编码格局也会依据状况来定。

3.3 其余特点

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

同时,SDS 在字符串扩容的时刻也会启动预调配,这些机制相似于我们 Java 中 ArrayList 扩容、HashMap 扩容,扩容时会预留空间,防止频繁扩容。

同时,缩容的时刻并不会立马监禁多余空间,防止后续又要扩容。

您可能还会对下面的文章感兴趣: