背景介绍
这里给大家分享一道很有趣的面试题。
面试过程
面试官:redis我看你有使用过,说一下redis的基本类型吧?
A:String,Hash,Set,List,Zset。
面试官:redis中string类型的实现有没有了解过?
A:(喵喵喵?)
面试官:回家等通知吧。
面试反思
作为一个爱学习的好孩子,遇到不会的当然要努力学习了,于是查阅了良多资料,算是把这个问题给搞明白了,下面且听我慢慢道来~
Redis的底层数据结构
经过查阅资料,发现Redis的底层数据结构分为八种
- Long类型的整数
- embstr 编码的简单动态字符串
- 简单动态字符串
- 字典
- 双端链表
- 压缩列表
- 整数集合
- 跳跃表和字典
简单动态字符串
Redis底层是用C语言写的,C语言中的字符串就是一个简单的字符数组,Redis中为了实现方便的扩展、安全和性能,自己定义了一个结构用来存储字符串。
我们叫它简单动态字符串(simple dynamic string)。
该数据结构中除了保存字符串,还保存了free(表示字符串剩余的空间)以及len(当前子字符串的长度)。
相比于C中的字符串,Redis这样做有几点好处:
- 获取字符串长度的复杂度为O(1)
由于sdshdr结构中定义了len用来保存当前字符串长度,因此不必像C中一样遍历字符串来得到长度。 - 不会造成缓冲区溢出
C中使用函数将一个字符串添加到另一个字符串默认是认为字符串剩余空间足够容纳添加的,但是事实可能并不够,会造成缓冲溢出。
但是Redis在每一次执行字符串拼接的过程前都会判断当前剩余的free是否能够存下需要拼接的字符串,因此不会造成溢出。 - 减少修改字符串带来的内存重分配次数
Redis采用了内存预分配方法,每次扩容都会额外预留一些空间方便下次扩容来减少这些操作的出现频率。 - 二进制安全
- 兼容部分C字符串函数
后续
最近因为换工作的原因,耽误了更新,从这周起恢复每周至少一篇的博客更新,敬请期待~