面试题答案
一键面试Redis跳跃表结构
- 节点结构:
- 每个节点包含一个分值(score),用于排序。例如,在一个存储成绩的跳跃表中,score可以是学生的考试分数。
- 一个或多个层(level),每层包含一个指向下一个节点的指针和跨度(span)。跨度记录了当前节点到下一个节点之间的节点数。
- 一个对象(obj),用于存储实际的数据,如学生的姓名等。
- 头节点和尾节点:
- 头节点是跳跃表的起始节点,它的层数量通常会比其他节点多,方便快速定位。尾节点的所有层指针都指向NULL。
- 层结构:
- 跳跃表的层是随机生成的,每一层形成一个有序链表。高层链表中的节点是底层链表节点的子集,高层链表的节点稀疏,底层链表的节点密集。例如,最上层链表可能每5个节点才有一个,而下一层可能每3个节点有一个,最底层则包含所有节点。
相比普通链表提升检索效率的原理
- 分层结构:
- 普通链表检索时,只能依次遍历每个节点,时间复杂度为O(n)。而跳跃表通过分层,在高层链表中可以快速跨越大量节点。例如,在一个有1000个节点的跳跃表中,假设高层链表每100个节点有一个,从高层链表开始检索,最多只需遍历10个节点就可以定位到目标节点所在的大致范围,然后再在底层链表中精确查找,大大减少了遍历次数,平均时间复杂度降为O(log n)。
- 随机化层高:
- 跳跃表的层高是随机生成的,根据概率,大部分节点的层高较低,少部分节点的层高较高。这种随机化的层高分布,保证了跳跃表在插入和删除操作后仍能保持较好的检索效率。
API使用场景举例
- zadd命令:
- 场景:用于向有序集合(基于跳跃表实现)中添加成员及其分值。例如,在一个排行榜应用中,要添加新的用户成绩。
- 示例:
zadd leaderboard 100 "user1"
,表示将用户user1
的成绩100添加到名为leaderboard
的有序集合中。
- zrange命令:
- 场景:获取有序集合中指定范围内的成员。例如,在排行榜中获取前10名用户。
- 示例:
zrange leaderboard 0 9
,表示获取leaderboard
有序集合中排名第1到第10的用户。
- zscore命令:
- 场景:获取有序集合中某个成员的分值。例如,查询某个用户在排行榜中的成绩。
- 示例:
zscore leaderboard "user1"
,返回user1
在leaderboard
中的成绩。