Redis常见数据结构以及使用场景分别是什么?

资讯 3年前
2.05K

大家好,我是阿秀。

大家五一过的怎么样啊?有没有出去玩,哦不,有没有被堵在路上...

机智的我选择呆在实验室里看B站技术视频和《计算机程序的构造和解释》。

五一结束之后再出去溜达溜达,嘿嘿,完美避开游客高峰期。

阿秀五一期间除了疯狂卷肝视频之外也没闲着,还把以前自己做的 Redis 笔记好好整理了一遍,大概整理出 25 道高频面试题。由于篇幅原因,一次性更新 25 道题导致整体太过冗长,很多人可能根本看不过来,所以 Redis 篇打算分为两期更新。

另外,C++、操作系统、计算机网络、MySQL 的硬核面试资料均已更新完毕,如果有还没看过的可以先去看看啦。

《逆袭进大厂系列》(包含C++、操作系统、计算机网络、MySQL、Redis、情景题)

下面就把本期的 Redis 分享给大家吧。

1、听说过Redis吗?它是什么?

Redis是一个数据库,不过与传统数据库不同的是Redis的数据库是存在内存中,所以读写速度非常快,因此 Redis被广泛应用于缓存方向。

除此之外,Redis也经常用来做分布式锁,Redis提供了多种数据类型来支持不同的业务场景。除此之外,Redis 支持事务持久化、LUA脚本、LRU驱动事件、多种集群方案。

2、Redis的五种数据结构整理简单动态字符串(Simple Dynamic String,SDS)

Redis没有直接使用C语言传统的字符串,而是自己构建了一种名为简单动态字符串(Simple dynamic string,SDS)的抽象类型,并将SDS用作Redis的默认字符串表示。

其实SDS等同于C语言中的char * ,但它可以存储任意二进制数据,不能像C语言字符串那样以字符’’来标识字符串的结 束,因此它必然有个长度字段。

定义struct sdshdr {
   // 记录buf数组中已使用字节的数量
   // 等于sds所保存字符串的长度
   int len;
   
   // 记录buf数组中未使用字节的数量
   int free;
   
   // 字节数组,用于保存字符串
   char buf[];
}
优点获取字符串长度的复杂度为O(1)。杜绝缓冲区溢出。减少修改字符串长度时所需要的内存重分配次数。二进制安全。兼容部分C字符串函数。

它具有很常规的 set/get 操作,value 可以是String也可以是数字,一般做一些复杂的计数功能的缓存。

链表

当有一个列表键包含了数量比较多的元素,又或者列表中包含的元素都是比较长的额字符串时,Redis就会使用链表作为列表建的底层实现。

节点底层结构typedef struct listNode {
   // 前置节点
   struct listNode *prev;
   // 后置节点
   struct listNode *next;
   // 节点的值
   void *value;
} listNode;
list底层结构typedef struct list {
   // 表头节点
   listNode *head;
   // 表尾节点
   listNode *tail;
   // 链表所包含的节点数量
   unsigned long len;
   // 节点值复制函数
   void *(*dup)(void *ptr);
   // 节点值是放过函数
   void (*free)(void *ptr);
   // 节点值对比函数
   int(*match)(void *ptr, void *key);
} list;
特性链表被广泛用于实现Redis的各种功能,比如列表建、发布与订阅、慢查询、监视器等。每个链表节点由一个listNode结构来表示,每个节点都有一个指向前置节点和后置节点的指针,所以Redis的链表实现是双端链表。每个链表使用一个list结构表示,这个结构带有表头节点指针、表尾节点指针,以及链表长度等信息。因为链表表头的前置节点和表尾节点的后置节点都指向NULL,所以Redis的链表实现是无环链表。通过为链表设置不同的类型特定函数,Redis的链表可以用于保存各种不同类型的值。字典

字典的底层是哈希表,类似 C++中的 map ,也就是键值对。

© 版权声明

相关文章