NoSQL_Redis 面试专题手册
💡 本章节共收录 3511 道面试真题,建议每天复习 10-20 题。
Q1: Redis中跳表为什么查询效率高?
【核心解析】 跳表通过多层索引实现O(logN)平均查询复杂度;每层索引是下层索引的子集,支持快速跳跃;插入和删除时通过随机层数维护平衡;相比平衡树实现简单,并发友好。
Q2: Redis RDB持久化是如何写入的?
【核心解析】 RDB通过fork子进程生成快照;父进程继续处理请求,子进程将内存数据写入临时RDB文件;写时复制技术减少内存开销;完成后替换旧RDB文件;支持手动SAVE和自动配置触发。
Q3: Redis的常见数据结构有哪些?压缩列表为什么会连锁更新?哈希表、跳表的特点?
【核心解析】 String、Hash、List、Set、ZSet;压缩列表连锁更新:插入或删除导致后续节点长度编码变化,引发多次重新分配;哈希表:O(1)查找,渐进式rehash;跳表:有序,O(logN)查找,支持范围查询
Q4: 如何确保Redis的性能和数据一致性,在高并发场景下?
【核心解析】 使用Redis集群或主从复制提升性能;采用读写分离(主写从读);使用缓存策略如缓存穿透/击穿/雪崩的防护;数据一致性可通过延迟双删、设置过期时间、使用分布式锁或消息队列异步同步。
Q5: Redisson实现分布式锁的原理和场景?
【核心解析】 原理:基于Redis的SETNX命令和Lua脚本实现原子性加锁、解锁,支持可重入、自动续期(看门狗)。场景:高并发下资源互斥访问,如秒杀、订单创建、分布式任务调度。
Q6: Redis实现分布式锁有哪些方式?A线程拿到分布式锁但运行时间超过锁过期时间,B线程能拿到锁吗?
【核心解析】 常用方式:SETNX+EXPIRE(原子性需Lua脚本或SET NX EX)、Redisson看门狗机制、RedLock算法;若A线程锁过期,B线程可获取锁,但可能导致并发问题,需通过续期(看门狗)或业务逻辑保证幂等;建议设置合理过期时间并搭配续期机制。
Q7: Redis的发布订阅原理是什么?
【核心解析】 发布者将消息发送到频道;订阅者订阅频道接收消息;基于推模式,实时性高;消息不持久化,丢失风险;适用于实时通知、聊天等场景
Q8: Redis的拦截器是什么?请解释其原理和应用场景。
【核心解析】 Redis拦截器通常指通过Redis实现请求拦截或限流的功能;原理是利用Redis的原子操作(如INCR、EXPIRE)实现计数器或令牌桶;常见应用场景包括API限流、防重复提交、黑名单拦截;实现方式包括使用Lua脚本保证原子性;注意设置合理的过期时间和并发控制。
Q9: Redis 的持久化机制有哪些?请详细说明 RDB 和 AOF 的原理、优缺点及适用场景。
【核心解析】 RDB:基于快照的持久化,通过 fork 子进程将内存数据写入临时文件,替换旧文件;优点:文件紧凑,恢复快,适合备份;缺点:可能丢失最后一次快照后的数据,fork 时可能阻塞;AOF:记录每次写操作命令,以追加方式写入文件;优点:数据安全性高(可配置每秒同步),文件可读;缺点:文件体积大,恢复慢;混合持久化(Redis 4.0+):结合 RDB 和 AOF,AOF 重写时生成 RDB 格式;适用场景:RDB 适合大规模数据恢复和备份,AOF 适合对数据完整性要求高的场景。
Q10: 什么是缓存击穿、缓存穿透和缓存雪崩?分别如何解决?
【核心解析】 缓存穿透:查询不存在的数据,导致请求直接打到数据库;解决:布隆过滤器、缓存空对象(设置较短过期时间);缓存击穿:热点 key 过期,大量并发请求直接访问数据库;解决:互斥锁(如 SETNX)、逻辑过期(不设置物理过期时间,后台异步更新);缓存雪崩:大量 key 同时过期或 Redis 宕机,导致数据库压力激增;解决:设置随机过期时间、使用集群或哨兵、限流降级。
Q11: 布隆过滤器的原理是什么?它什么情况下会误判?误判率受哪些因素影响?与普通 bitmap 有什么区别?
【核心解析】 原理:使用多个哈希函数将元素映射到一个位数组中的多个位置,置为 1;查询时检查所有映射位是否都为 1,若有一个为 0 则不存在,全为 1 则可能存在;误判原因:哈希冲突导致不同元素映射到相同位,导致不存在的元素被误判为存在;误判率影响因素:位数组大小 m、哈希函数个数 k、插入元素数量 n;关系:m 越大误判率越低,k 存在最优值;与 bitmap 区别:bitmap 每个位对应一个元素,无误判;布隆过滤器节省空间但存在误判;布隆过滤器加哈希函数目的:减少冲突,降低误判率。
Q12: 如何用Redis实现分布式锁?你实现的分布式锁是乐观锁还是悲观锁?CAS实现的乐观锁有什么局限性?
【核心解析】 使用SETNX命令加锁,设置过期时间防止死锁;释放锁时使用Lua脚本保证原子性;属于乐观锁;CAS局限性:ABA问题、自旋开销、无法解决超时导致的锁失效
Q13: Redis服务重启之后,数据会丢吗?Redis的持久化方法有哪些?
【核心解析】 可能丢失数据,取决于持久化配置;RDB快照:定期保存全量数据,丢失较多;AOF日志:记录写操作,可配置每秒同步,丢失少;混合持久化结合两者
Q14: Redis怎么做高可用?主节点从节点切换时会不会丢数据?Redis锁怎么应对这种问题,可能会出现怎样的不一致?
【核心解析】 使用哨兵或集群实现高可用;主从切换可能丢失数据(异步复制);Redis锁应对:使用Redlock算法,在多个节点加锁;不一致:锁已过期但业务未完成,导致并发问题
Q15: Redis怎么防止缓存击穿?
【核心解析】 使用互斥锁(分布式锁)控制并发访问;设置热点数据永不过期;提前预加载;使用布隆过滤器过滤无效请求
Q16: 项目中的布隆过滤器、互斥锁、逻辑过期分别是解决什么问题的
【核心解析】 布隆过滤器:解决缓存穿透,快速判断key不存在;互斥锁:解决缓存击穿,保证只有一个线程重建缓存;逻辑过期:解决缓存雪崩,通过设置过期时间分散缓存失效;三者结合可有效保护数据库。
Q17: HyperLogLog、ZSet、Bitmap的底层原理和适用场景是什么
【核心解析】 HyperLogLog:基于概率算法,用于基数统计,占用内存小(12KB),误差约0.81%;ZSet:基于跳跃表和哈希表,用于有序集合,支持范围查询和排序;Bitmap:基于位数组,用于布尔值存储,节省空间,适合统计活跃用户等。
Q18: Redis支持哪些数据结构?
【核心解析】 String(字符串)、List(列表)、Set(集合)、Hash(哈希)、Zset(有序集合);此外还有HyperLogLog、Bitmap、Geospatial等高级结构。
Q19: Redis的跳表(Skip List)是什么?
【核心解析】 跳表是一种有序数据结构,通过多层索引实现快速查找;平均时间复杂度O(log n);Redis的Zset底层使用跳表实现;支持范围查询和排序。
Q20: Redis的RDB和AOF两种持久化机制有什么区别?
【核心解析】 RDB:快照持久化,定期保存全量数据,文件紧凑,恢复快,但可能丢失数据;AOF:追加日志,记录每次写操作,数据更安全,但文件大,恢复慢;可混合使用。
Q21: AOF里记录的是什么内容?
【核心解析】 记录Redis的写命令(如SET、LPUSH等),以文本协议格式存储;包括命令本身和参数;重写时压缩为最小命令集。
Q22: Redis的发布订阅模式原理是什么?是否建立了长连接?
【核心解析】 发布订阅模式:发布者将消息发送到频道,订阅者接收频道消息;原理:Redis维护频道与订阅者的映射,消息通过推送方式传递;长连接:订阅者与Redis保持TCP长连接,实时接收消息;缺点:消息不持久化,丢失后无法恢复。
Q23: Redis分布式锁怎么实现的?
【核心解析】 常用命令:SETNX + EXPIRE 或 SET key value NX EX seconds;Redlock算法:多节点加锁,过半节点成功则获取锁;注意事项:设置超时时间防止死锁;释放锁时使用Lua脚本保证原子性;考虑时钟漂移和网络延迟。
Q24: Redis的过期删除策略有哪些?请详细说明。
【核心解析】 惰性删除:访问key时检查是否过期,过期则删除;定期删除:将过期key放入字典,定时扫描部分数据删除,有SLOW和FAST两种模式;两者配合使用。
Q25: Redis缓存击穿
【核心解析】 缓存击穿指热点key过期,大量请求直接打到数据库;解决方案:互斥锁(setnx)、逻辑过期(不设置物理过期,后台更新)、永不过期+异步更新;布隆过滤器可预防缓存穿透,但对击穿无效。
Q26: 有没有缓存穿透问题?如何解决?
【核心解析】 缓存穿透:查询不存在的数据,导致请求直接打到数据库;解决方案:布隆过滤器过滤不存在key、缓存空对象(设置较短过期时间)、接口限流降级。
Q27: 什么是缓存击穿和缓存雪崩?如何解决?
【核心解析】 缓存击穿:热点key过期,高并发访问数据库;解决:互斥锁、逻辑过期、永不过期。缓存雪崩:大量key同时过期或Redis宕机;解决:过期时间随机化、多级缓存、Redis高可用。
Q28: 什么是缓存击穿、穿透?布隆过滤器的作用、底层结构、大小如何设置?与商品量、用户量、订单量的关系?
【核心解析】 缓存击穿:热点key过期导致高并发请求数据库;穿透:查询不存在的数据;布隆过滤器用于快速判断元素是否存在,底层是位数组+多个哈希函数;大小根据预期元素数量和误判率计算,公式:m = -n*ln(p)/(ln2)^2;商品量、用户量、订单量影响n值。
Q29: 讲一下布隆过滤器的原理。
【核心解析】 布隆过滤器是一种概率型数据结构,用于判断元素是否在集合中;使用多个哈希函数将元素映射到位数组;查询时若所有位为1则可能存在,否则一定不存在;存在误判率,但不可删除元素。
Q30: 如何用Redis实现分布式锁?你实现的分布式锁是乐观锁还是悲观锁?CAS实现的乐观锁有什么局限性?
【核心解析】 使用SETNX命令加锁,设置过期时间防止死锁;释放锁时使用Lua脚本保证原子性;属于乐观锁;CAS(Compare and Swap)的局限性包括ABA问题、自旋消耗CPU、无法解决重入问题、单点故障风险。
Q31: Lua脚本里干了什么,为什么可以实现原子化?
【核心解析】 Lua脚本在Redis中执行多个命令,保证原子性;Redis单线程执行脚本,期间不执行其他命令;用于实现复杂逻辑如分布式锁、限流等。
Q32: Redis的缓存击穿概念给我讲一下。怎么解决?
【核心解析】 缓存击穿:热点key过期,大量请求直接打到数据库;解决方案:互斥锁(如SETNX)、逻辑过期(异步更新)、热点数据永不过期、布隆过滤器。
Q33: 布隆过滤器的工作原理是什么?在Redis中如何使用?
【核心解析】 布隆过滤器是一种空间效率高的概率数据结构,用于判断一个元素是否在集合中,存在误判但不会漏判;由位数组和多个哈希函数组成;添加元素时通过哈希函数映射到位数组的多个位置并置为1;查询时检查对应位是否都为1,若有一个为0则一定不存在;Redis中通过bitmap或RedisBloom模块实现;适用于缓存穿透防护、去重等场景。
Q34: Redis为什么性能强?单线程模型如何工作?
【核心解析】 Redis基于内存操作,数据读写速度快;采用单线程模型,避免了多线程上下文切换和锁竞争;使用IO多路复用技术(如epoll)处理大量客户端连接;数据结构简单高效;单线程模型下所有命令串行执行,保证了原子性;但单线程也限制了CPU密集型操作的性能。
Q35: Redis持久化方式有哪些?请介绍下。
【核心解析】 RDB(快照)和AOF(追加文件);RDB是定时全量快照,适合备份和恢复;AOF记录每次写操作,可配置同步策略(每秒/每次/不同步);AOF文件体积大,恢复慢;RDB可能丢失较多数据;可同时开启两者。
Q36: 先后执行set name 张三和set name 李四,在AOF持久化过程中都写入AOF文件吗?
【核心解析】 都写入;AOF记录每条写命令;最终AOF文件包含两条set命令;恢复时按顺序执行;可通过重写压缩。
Q37: Redis高可用方案有哪些?
【核心解析】 主从复制;哨兵模式(Sentinel);Redis Cluster;客户端分片;持久化+备份。
Q38: Redis Cluster集群如何分配key在哪个slot?
【核心解析】 使用CRC16(key) mod 16384计算哈希槽;每个节点负责一部分槽;客户端或代理重定向;支持动态迁移槽。
Q39: 一般什么情况下会用Redis?
【核心解析】 缓存热点数据;分布式锁;计数器;排行榜;消息队列;会话管理;限流。
Q40: String类型,如果value大小几十兆会怎么样?
【核心解析】 占用大量内存;网络传输慢;阻塞其他操作;建议拆分或使用其他数据结构;可能触发内存淘汰。
Q41: Set类型元素个数过多怎么办?
【核心解析】 使用哈希分片;改用Sorted Set或List;限制集合大小;定期清理;使用Redis Cluster分散存储。
Q42: 如何实现Redis分布式锁?需要注意哪些问题?
【核心解析】 使用SET NX EX命令;设置过期时间防止死锁;使用Redlock算法保证高可用;注意锁的续期和释放的原子性。
Q43: Redis在项目中主要用来做什么?
【核心解析】 缓存、分布式锁、计数器、消息队列、Session共享、排行榜等
Q44: Redis的Zset(有序集合)底层数据结构是什么?请详细说明跳表和哈希表的协作方式。
【核心解析】 Zset由跳表(skiplist)和哈希表(dict)实现;哈希表用于O(1)查询元素对应的score;跳表用于按score排序和范围查询;跳表是多级索引结构,叶子节点是单链表,索引节点随机分布,类似B+树但更灵活。
Q45: Redis分布式锁的实现原理和注意事项是什么?
【核心解析】 使用SET NX EX命令实现;设置合理过期时间防止死锁;释放锁时使用Lua脚本保证原子性;考虑Redlock算法;注意时钟漂移问题;可结合Redisson等客户端库
Q46: Redis缓存三剑客(缓存穿透、缓存击穿、缓存雪崩)是什么?如何解决?
【核心解析】 缓存穿透:查询不存在的数据,解决方案包括布隆过滤器、缓存空对象;缓存击穿:热点key过期,解决方案包括互斥锁、逻辑过期;缓存雪崩:大量key同时过期,解决方案包括随机过期时间、多级缓存、限流降级
Q47: Redis的Pipeline和事务有什么区别?
【核心解析】 Pipeline:批量发送命令,减少网络开销,不保证原子性;事务(MULTI/EXEC):保证原子性,但命令在exec前不执行;Pipeline可结合事务使用;事务不支持回滚;Pipeline性能更高
Q48: Redis事务的原子性如何保证?EXEC命令能保证原子性吗?
【核心解析】 Redis事务通过MULTI、EXEC、DISCARD、WATCH实现;EXEC保证事务内所有命令连续执行,不被其他命令打断;但不支持回滚,部分命令失败不影响其他命令;WATCH用于乐观锁
Q49: Redis 如何保证事务的原子性?事务中的命令是顺序执行的吗?
【核心解析】 Redis 事务通过 MULTI/EXEC 保证原子性,但不支持回滚;事务中的命令是顺序执行的,但不会立即执行,而是入队后一次性执行。
Q50: Redis 的 RDB 和 AOF 持久化机制有什么区别?
【核心解析】 RDB 是快照持久化,定期保存全量数据,恢复快但可能丢失数据;AOF 是追加日志,记录写操作,数据更安全但文件大、恢复慢。
Q51: 缓存穿透怎么处理?
【核心解析】 布隆过滤器过滤不存在的数据;缓存空对象并设置较短过期时间;接口层增加参数校验;使用互斥锁或限流;热点数据预加载
Q52: Redis如何实现分布式锁?开锁哪一步需要原子操作?Redis常见数据结构及Zset底层原理。
【核心解析】 SETNX + EXPIRE原子操作(或Redlock);开锁:使用Lua脚本保证原子性;常见数据结构:String、Hash、List、Set、Zset;Zset底层:跳表+哈希表,支持范围查询和排序
Q53: 请解释缓存穿透、缓存击穿和缓存雪崩(缓存三兄弟)的概念、原因及解决方案。
【核心解析】 缓存穿透:查询不存在数据,解决方案包括布隆过滤器、空值缓存;缓存击穿:热点key失效,解决方案包括互斥锁、永不过期;缓存雪崩:大量key同时过期,解决方案包括随机过期时间、多级缓存、限流降级
Q54: 布隆过滤器的原理是什么?如果布隆过滤器判断不存在,就一定不存在吗?判断存在,就一定存在吗?
【核心解析】 布隆过滤器使用多个哈希函数将元素映射到位数组;判断不存在时一定不存在(无假阴性);判断存在时可能有假阳性(误判率);可通过增加位数组大小和哈希函数数量降低误判率
Q55: Redis的Bitmap底层物理结构是怎样的?
【核心解析】 Bitmap本质是字符串(SDS),按位操作;每个字节8位,最大长度2^32位;支持位运算(AND/OR/XOR)和位统计(BITCOUNT);物理存储连续,适合大量布尔值场景
Q56: Redis有哪些存储结构?你是如何使用的?
【核心解析】 String(缓存、计数器)、Hash(对象存储)、List(消息队列)、Set(去重、交集)、Sorted Set(排行榜)、Bitmap(签到)、HyperLogLog(基数统计)、GEO(地理位置);使用场景:缓存热点数据、分布式锁(String)、限流(List)、点赞(Set)等。
Q57: Redis的内存淘汰策略有哪些?
【核心解析】 noeviction(不淘汰,返回错误)、allkeys-lru(所有键LRU)、volatile-lru(设置过期时间的键LRU)、allkeys-random、volatile-random、volatile-ttl(淘汰即将过期的);Redis4.0后新增LFU策略(allkeys-lfu、volatile-lfu)。
Q58: 一致性哈希和普通哈希有什么不同?
【核心解析】 普通哈希对节点数取模,节点增减导致大量数据迁移;一致性哈希将哈希值空间组织成环,节点和数据都映射到环上;数据顺时针存储到最近节点;节点增减只影响相邻节点;引入虚拟节点解决数据倾斜问题。
Q59: LRU2缓存满了怎么办?
【核心解析】 LRU2(Two Queues)维护两个队列:最近访问队列和频繁访问队列;缓存满时,优先淘汰最近访问队列的尾部(LRU);频繁访问队列中的元素被再次访问时提升到队列头部;淘汰时检查两个队列,选择最久未使用的。
Q60: 缓存三件套:布隆过滤器、分布式锁、随机TTL的原理是什么?
【核心解析】 布隆过滤器:位数组+多个哈希函数,判断元素一定不存在或可能存在;分布式锁:Redis SETNX + 过期时间,防止死锁;随机TTL:为缓存设置随机过期时间,避免缓存雪崩;布隆过滤器用于缓存穿透,分布式锁用于缓存击穿,随机TTL用于缓存雪崩。
Q61: Redis缓存穿透、击穿、雪崩如何产生,如何解决?
【核心解析】 缓存穿透:查询不存在的数据,大量请求直接打到数据库,解决:布隆过滤器、缓存空对象;缓存击穿:热点key过期,大量并发请求直接访问数据库,解决:互斥锁、逻辑过期;缓存雪崩:大量key同时过期或Redis宕机,解决:随机过期时间、多级缓存、Redis高可用
Q62: 布隆过滤器的作用是什么?缓存穿透、击穿、雪崩有什么区别?
【核心解析】 布隆过滤器:判断元素是否存在,防止缓存穿透;穿透:查不存在数据;击穿:热点key过期;雪崩:大量key同时过期或Redis宕机;解决方式不同
Q63: Redis如何保证高可用?
【核心解析】 主从复制实现数据冗余;哨兵模式实现自动故障转移;Redis Cluster实现数据分片和分布式高可用;持久化(RDB/AOF)防止数据丢失。
Q64: 除了做缓存和分布式锁,Redis还能做什么?
【核心解析】 消息队列(List/Stream);计数器(INCR);排行榜(Sorted Set);分布式限流;位图(Bitmap)统计;地理空间(GEO);发布订阅(Pub/Sub)。
Q65: Redis 分布式锁的 key 怎么设计?
【核心解析】 使用业务唯一标识作为key,如订单号或用户ID;结合前缀区分不同业务;设置合理的过期时间防止死锁;使用SET NX EX命令原子性加锁;释放锁时使用Lua脚本保证原子性。
Q66: 缓存击穿、缓存穿透、缓存雪崩怎么处理?
【核心解析】 缓存穿透:布隆过滤器或缓存空对象;缓存击穿:互斥锁或热点数据永不过期;缓存雪崩:设置随机过期时间、多级缓存、限流降级。
Q67: ZSet 数据结构怎么实现点赞排行榜功能?
【核心解析】 使用ZSet存储用户ID和点赞时间戳作为score;按score排序实现排行榜;使用ZINCRBY更新点赞数;使用ZREVRANGE获取排名前N的用户;定期清理过期数据。
Q68: 请描述基于Lua脚本和消息队列(MQ)的异步方案的具体业务流程,以及Lua脚本在其中的作用。
【核心解析】 Lua脚本保证原子性操作,如扣减库存和生成订单;MQ用于异步处理后续流程(如发货通知);流程:用户请求→Lua脚本执行库存扣减→发送消息到MQ→消费者异步处理业务逻辑。
Q69: 请解释布隆过滤器的原理、优缺点及其在项目中的应用场景。
【核心解析】 原理:使用多个哈希函数将元素映射到位数组,判断元素一定不存在或可能存在;优点:节省空间、查询快;缺点:有误判率、无法删除元素;应用场景:缓存穿透防护、去重、垃圾邮件过滤等。
Q70: Redisson分布式锁的底层实现是什么?与红锁(RedLock)相比有何异同?
【核心解析】 Redisson基于Redis的SETNX+Lua脚本实现可重入锁;利用看门狗机制自动续期;红锁在多个Redis节点上获取锁,需要半数以上节点同意,解决单点故障;Redisson锁默认是公平锁,红锁更强调分布式环境下的安全性。
Q71: Redis中字符串类型是如何存储的?为什么采用这种存储方式?
【核心解析】 Redis使用SDS(简单动态字符串)存储字符串;SDS有len、free、buf字段,支持O(1)长度获取;预分配空间减少内存分配次数;二进制安全,可存储任意数据。
Q72: 为什么使用Redis作为缓存?MySQL直接查询不够吗?
【核心解析】 Redis基于内存,读写速度快,降低MySQL负载;支持丰富数据结构,适合缓存复杂对象;可设置过期时间,自动淘汰;但需考虑缓存一致性、穿透、雪崩等问题。
Q73: 为什么Redis使用跳表(skiplist)而不是平衡树实现有序集合?
【核心解析】 跳表实现简单,代码易维护;范围查询效率高;插入删除操作局部性更好;内存占用相对较低;支持平均O(logN)的查找性能。
Q74: 基于Redis的发布订阅实现的动态配置中心,消息丢失了怎么办?
【核心解析】 Redis Pub/Sub不保证消息可靠性;可改用Redis Stream或消息队列;增加持久化机制;消费者主动拉取最新配置;实现消息确认机制。
Q75: 如何基于Redis实现分布式锁?如何防止死锁?如何实现可重入锁?
【核心解析】 使用SETNX加锁,设置过期时间防止死锁;使用Lua脚本保证原子性;可重入锁通过记录线程标识和重入计数实现,使用Hash结构存储。
Q76: 为什么选择Redis做缓存?Redis还有哪些应用场景?
【核心解析】 高性能:基于内存,读写快;丰富数据结构:String、Hash、List、Set、Sorted Set等;支持持久化;分布式锁;计数器;消息队列(Pub/Sub或Stream);排行榜;限流
Q77: Redis实现分布式锁的原理是什么?
【核心解析】 使用SETNX命令;设置过期时间防止死锁;使用Lua脚本保证原子性;Redlock算法实现高可用;释放锁时校验value(如UUID)防止误删
Q78: Redis 有多少种持久化策略?请详细讲讲 RDB 的过程。
【核心解析】 两种持久化策略:RDB(快照)和AOF(追加文件);RDB通过fork子进程将内存数据生成快照文件;触发方式:手动(SAVE/BGSAVE)和自动(配置save规则);BGSAVE过程:fork子进程,子进程写临时RDB文件,完成后替换旧文件;优点:文件紧凑、恢复快;缺点:可能丢失最后一次快照后的数据。
Q79: 什么是缓存穿透和缓存击穿?如何解决?
【核心解析】 缓存穿透:查询不存在的数据,导致请求直达数据库;解决:布隆过滤器、缓存空对象;缓存击穿:热点key过期,大量请求同时访问数据库;解决:互斥锁、热点数据永不过期、使用分布式锁。
Q80: 假如有非常高的并发,单 Redis 抗不住,如何解决数据同步问题?
【核心解析】 使用Redis集群(如Redis Cluster)分片存储;主从复制+哨兵实现高可用;数据同步:主节点写,从节点异步复制;使用一致性哈希或槽分配;考虑读写分离,但注意数据一致性;使用代理如Twemproxy或Codis。
Q81: 假如你用的是集群 Redis,缓存穿透或其他问题还存在吗?
【核心解析】 缓存穿透问题依然存在,因为集群不改变请求不存在key的行为;解决:布隆过滤器可分布式实现;缓存击穿问题依然存在,热点key可能集中在某个节点;解决:本地缓存、互斥锁;集群可分散流量,但需注意节点故障。
Q82: Redisson 分布式锁的性能测过吗?
【核心解析】 Redisson分布式锁基于Redis,性能较高;支持可重入、自动续期(看门狗);性能测试需考虑网络延迟、锁粒度;与ZooKeeper锁相比,Redis锁性能更好但可靠性稍弱;建议压测获取QPS和响应时间。
Q83: zset的底层结构是什么?跳表的时间复杂度是多少?
【核心解析】 zset底层使用跳表(skiplist)和哈希表;跳表支持有序性,哈希表支持O(1)查找;跳表插入、删除、查找时间复杂度O(log n)。
Q84: 多级缓存一般怎么实现?
【核心解析】 本地缓存(如Caffeine)+ 分布式缓存(如Redis)+ 数据库;先查本地缓存,未命中查Redis,再未命中查数据库;缓存失效策略:TTL、LRU;缓存一致性:更新数据库后删除或更新缓存。
Q85: Redis为什么在高并发情况下表现得比较好?
【核心解析】 基于内存,读写速度快;单线程模型避免锁竞争;IO多路复用处理多个连接;数据结构简单高效;支持持久化但非强依赖;主从复制和哨兵提高可用性;高性能网络库(如epoll)
Q86: Redis布隆过滤器如何解决缓存穿透?如何控制误判率?
【核心解析】 布隆过滤器判断数据不存在则直接返回,避免查数据库;误判率由哈希函数个数和位数组大小决定;通过公式计算最优参数,误判率可控制在1%以下。
Q87: Redisson可重入锁的实现原理是什么?如何处理锁续期和死锁?
【核心解析】 基于Redis的Hash结构,记录线程ID和重入次数;通过Lua脚本保证原子性;看门狗机制自动续期(默认30秒);死锁通过设置过期时间,超时自动释放。
Q88: Redis的ZSet底层是怎么实现的?
【核心解析】 当数据量较小时使用压缩列表(ziplist);数据量较大时使用跳表(skiplist)和哈希表;跳表支持有序性操作和范围查询;哈希表用于快速查找元素分数;跳表节点包含元素、分数和后退指针;跳表层级随机生成
Q89: Redis Pipeline是原子性的吗?Pipeline部分成功如何定位和解决?
【核心解析】 Pipeline不是原子性操作,它只是批量发送命令,服务端仍逐条执行;部分成功时需检查返回结果,每个命令对应一个响应;可通过记录发送命令顺序,对比响应结果定位失败命令;解决:重试失败命令或使用事务(MULTI/EXEC)保证原子性
Q90: Redis支持哪些数据结构?
【核心解析】 String(字符串)、List(列表)、Set(集合)、Hash(哈希)、ZSet(有序集合);此外还有HyperLogLog、Bitmap、Geospatial等;每种数据结构底层实现不同,如String用SDS,List用quicklist,Hash用ziplist或hashtable
Q91: Redis Zset在数据量比较小时,底层采用的数据结构是什么?
【核心解析】 当元素数量小于128且元素大小小于64字节时,使用压缩列表(ziplist);否则使用跳表(skiplist)和哈希表;压缩列表节省内存,但插入删除效率较低
Q92: 缓存击穿、穿透、雪崩是什么?如何用多级缓存解决?
【核心解析】 缓存穿透:查询不存在的数据,导致请求直达DB;解决:布隆过滤器、缓存空值;缓存击穿:热点key过期,高并发访问DB;解决:互斥锁、永不过期;缓存雪崩:大量key同时过期或Redis宕机;解决:过期时间随机化、多级缓存(本地缓存+Redis)、降级限流;多级缓存:本地缓存(如Caffeine)作为一级,Redis作为二级,减少对DB压力
Q93: Redis有哪些数据结构?底层用了哪些数据结构?
【核心解析】 外部:String、List、Set、ZSet、Hash;底层:简单动态字符串、双向链表、压缩列表、跳表、整数集合、字典。
Q94: Redis过期删除策略和内存淘汰策略是什么?
【核心解析】 过期删除:惰性删除、定期删除;内存淘汰:noeviction、allkeys-lru、volatile-lru、allkeys-random、volatile-random、volatile-ttl。
Q95: Redis的Zset底层数据结构是什么?跳表的底层实现是怎样的?压缩列表的连锁更新问题及listpack如何解决?
【核心解析】 Zset底层使用跳表(skiplist)和哈希表;跳表是一种多层链表,支持快速查找;压缩列表(ziplist)在元素变化时可能引发连锁更新,listpack通过固定大小编码避免连锁更新。
Q96: Redis常用指令有哪些?
【核心解析】 字符串:SET、GET;哈希:HSET、HGET;列表:LPUSH、RPOP;集合:SADD、SMEMBERS;有序集合:ZADD、ZRANGE;键操作:EXPIRE、DEL;事务:MULTI、EXEC。
Q97: Lua脚本在Redis中有什么作用?除了Redis还在别的地方用过吗?
【核心解析】 Redis中Lua脚本用于原子性执行多条命令,减少网络开销;其他场景:Nginx(OpenResty)、游戏开发、嵌入式系统等。
Q98: 什么是缓存击穿、穿透、雪崩?如何解决?
【核心解析】 缓存穿透:查询不存在的数据,解决方案:布隆过滤器、缓存空值;缓存击穿:热点key过期,解决方案:互斥锁、永不过期;缓存雪崩:大量key同时过期,解决方案:随机过期时间、多级缓存。
Q99: 如何使用Redis分布式锁实现限流?
【核心解析】 利用SETNX命令加锁并设置过期时间;使用Lua脚本保证原子性;考虑锁续期和防误删;结合令牌桶或漏桶算法。
Q100: Redis 中 ZSet 的底层数据结构是什么?如何实现范围查询(如 ZRANGEBYSCORE)?
【核心解析】 ZSet 底层使用 ziplist(元素少时)或 skiplist + hashtable(元素多时);ziplist 紧凑存储,skiplist 支持有序范围查询,hashtable 用于 O(1) 查找分值;ZRANGEBYSCORE 通过 skiplist 按分值范围遍历。
Q101: Redis 分布式锁的实现原理是什么?如何保证解锁的原子性?
【核心解析】 使用 SETNX 命令加锁,设置过期时间防止死锁;解锁时使用 Lua 脚本原子性地检查锁持有者并删除;Lua 脚本保证判断和删除操作的原子性;推荐使用 Redisson 等客户端实现。
Q102: Redis 有哪些基本数据结构?请列举。
【核心解析】 String(字符串)、List(列表)、Set(集合)、ZSet(有序集合)、Hash(哈希);此外还有 HyperLogLog、Bitmap、Geospatial 等。
Q103: Redis 哨兵模式的工作原理是什么?如何实现故障转移?
【核心解析】 哨兵模式由多个哨兵节点监控主从节点;当主节点下线,哨兵通过投票选举新主节点;选择从节点中复制偏移量最大的作为新主;故障转移后,哨兵通知客户端新主地址。
Q104: Redis Cluster 如何实现数据分片?
【核心解析】 Redis Cluster 使用哈希槽(hash slot)分片,共16384个槽;每个节点负责一部分槽;键通过 CRC16(key) % 16384 计算槽号;客户端可重定向到正确节点。
Q105: 如何设计一个高并发评论系统,支持热度排序、实时更新和深分页优化?
【核心解析】 使用Redis有序集合(Sorted Set)存储评论热度,key=video:{video_id}:comments:hot,score=hot_score,member=comment_id;热度计算公式:hot_score = log10(like_count×2 + reply_count) + (create_time - 固定基点时间戳)/衰减因子;通过ZREVRANGE命令高效获取热度前N条评论并支持分页;时间排序分页使用WHERE create_time < 上一页最后一条时间避免LIMIT M,N性能问题;评论发布/删除同步更新数据库并异步发送MQ消息,由Worker重新计算缓存;点赞/回复通过MQ异步触发hot_score重算并更新Redis有序集合分数;多级缓存:本地缓存热门视频前几页热评(TTL 10秒),Redis缓存核心有序集合;缓存击穿时使用分布式锁控制仅一个请求回源建缓存。