加入收藏 | 设为首页 | 会员中心 | 我要投稿 云计算网_泰州站长网 (http://www.0523zz.com/)- 视觉智能、AI应用、CDN、行业物联网、智能数字人!
当前位置: 首页 > 站长学院 > MySql教程 > 正文

面试官:你看过Redis数据结构底层实现吗?

发布时间:2019-06-22 04:22:53 所属栏目:MySql教程 来源:奔头哥
导读:副标题#e# 面试中,redis也是很受面试官亲睐的一部分。我向在这里讲的是redis的底层数据结构,而不是你理解的五大数据结构。你有没有想过redis底层是怎样的数据结构呢,他们和我们java中的HashMap、List、等使用的数据结构有什么区别呢。 1. 字符串处理(str
副标题[/!--empirenews.page--]

面试中,redis也是很受面试官亲睐的一部分。我向在这里讲的是redis的底层数据结构,而不是你理解的五大数据结构。你有没有想过redis底层是怎样的数据结构呢,他们和我们java中的HashMap、List、等使用的数据结构有什么区别呢。

1. 字符串处理(string)

我们都知道redis是用C语言写,但是C语言处理字符串和数组的成本是很高的,下面我分别说几个例子。

没有数据结构支撑的几个问题

  1.  极其容易造成缓冲区溢出问题,比如用strcat(),在用这个函数之前必须要先给目标变量分配足够的空间,否则就会溢出。
  2.  如果要获取字符串的长度,没有数据结构的支撑,可能就需要遍历,它的复杂度是O(N)
  3.  内存重分配。C字符串的每次变更(曾长或缩短)都会对数组作内存重分配。同样,如果是缩短,没有处理好多余的空间,也会造成内存泄漏。

好了,Redis自己构建了一种名叫Simple dynamic string(SDS)的数据结构,他分别对这几个问题作了处理。我们先来看看它的结构源码:

  1. struct sdshdr{  
  2.      //记录buf数组中已使用字节的数量  
  3.      //等于 SDS 保存字符串的长度  
  4.      int len;  
  5.      //记录 buf 数组中未使用字节的数量  
  6.      int free;  
  7.      //字节数组,用于保存字符串  
  8.      char buf[];  

再来说说它的优点:

  1.  开发者不用担心字符串变更造成的内存溢出问题。
  2.  常数时间复杂度获取字符串长度len字段。
  3.  空间预分配free字段,会默认留够一定的空间防止多次重分配内存。

更多了解:https://redis.io/topics/internals-sds

这就是string的底层实现,更是redis对所有字符串数据的处理方式(SDS会被嵌套到别的数据结构里使用)。

2. 链表

Redis的链表在双向链表上扩展了头、尾节点、元素数等属性。

面试官:你看过Redis数据结构底层实现吗?

2.1 源码

ListNode节点数据结构:

  1. typedef  struct listNode{  
  2.        //前置节点  
  3.        struct listNode *prev;  
  4.        //后置节点  
  5.        struct listNode *next;  
  6.        //节点的值  
  7.        void *value;    
  8. }listNode 

链表数据结构:

  1. typedef struct list{  
  2.      //表头节点  
  3.      listNode *head;  
  4.      //表尾节点  
  5.      listNode *tail;  
  6.      //链表所包含的节点数量  
  7.      unsigned long len;  
  8.      //节点值复制函数  
  9.      void (*free) (void *ptr);  
  10.      //节点值释放函数  
  11.      void (*free) (void *ptr);  
  12.      //节点值对比函数  
  13.      int (*match) (void *ptr,void *key);  
  14. }list; 

从上面可以看到,Redis的链表有这几个特点:

  1.  可以直接获得头、尾节点。
  2.  常数时间复杂度得到链表长度。
  3.  是双向链表。

3. 字典(Hash)

Redis的Hash,就是在数组+链表的基础上,进行了一些rehash优化等。

面试官:你看过Redis数据结构底层实现吗?

3.1 数据结构源码

哈希表:

  1. typedef struct dictht {  
  2.     // 哈希表数组  
  3.     dictEntry **table;  
  4.     // 哈希表大小  
  5.     unsigned long size;  
  6.     // 哈希表大小掩码,用于计算索引值  
  7.     // 总是等于 size - 1  
  8.     unsigned long sizemask;  
  9.     // 该哈希表已有节点的数量  
  10.     unsigned long used;  
  11. } dictht; 

(编辑:云计算网_泰州站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读