面经-zset调跳表

384 阅读2分钟

什么是跳表

  • zset结构体里面一个是跳表,一个哈希表
  • 跳表是在链表基础上改进过来的,实现了一种「多层」的有序链表,这样的好处是能快读定位数据

2ae0ed790c7e7403f215acb2bd82e884.png

如果我们要在链表中查找节点 4 这个元素,只能从头开始遍历链表,需要查找 4 次,而使用了跳表后,只需要查找 2 次就能定位到节点 4,因为可以在头节点直接从 L2 层级跳到节点 3,然后再往前遍历找到节点 4。

复杂度 O(logN)。

  • 跳表使用了二分查找思想,对原来的有序单链表加一级索引。索引层有两个指针,一个指向下一个节点,一个down指针,可以使查找更快

20210830153124580.png

20210830155358392.png

  • 通过建立索引的方式,对于数据量越大的有序链表,通过建立多级索引,查找效率提升会非常明显。

  • 这种链表加多级索引的结构 就是 跳表

时间复杂度 空间复杂度

image.png 在跳表查询时,每一级索引 最多需要遍历3个节点

那么在跳表中查询数据的时间复杂度就是     每一层遍历的节点数乘以层数 ⁡,因此跳表中查找的时间复杂度就是**O(logn). ** 与二分查找的时间复杂度相同。

  • 空间:o(n)

为什么不用红黑树

  • 区间查找效率高
  • 跳表灵活,他可以通过改变抽取间隔,灵活的平衡空间复杂度和时间复杂度
  • 跳表容易实现,代码简单

什么时候使用跳表

如果一个有序集合包含的元素数量比较多,又或者有序集合中元素的成员(member)是比较长的字符串时,Redis就会使用跳跃表来作为有序集合键的底层实现。

压缩列表 -- 为了节省内存而开发的连续内存块组成的

本质上是一个字节数组,包含任意多个节点,每个节点可以保存一个字节数组或者一个整数值。当有序集合或散列表的元素个数比较少,且元素都是短字符串时,Redis便使用压缩列表作为其底层数据存储结构

  • 保存元素(member)数量小于128
  • 每个元素(member)长度小于64字节

在数据量较少的时候,ziplist充分体现了它内存的优势,又不会影响整体的查询效率

image.png

  1. zlbytes:整个列表字节数
  2. zltail:尾节点到头节点的偏移量
  3. zllen:记录节点数量 image.png
  4. previous_entry_length:前一个节点的长度
  5. encoding:记录本节点的类型和长度属性
  6. content:内容