Skip to content

第38章:Redis 面试宝典与总复习 ​

38.1 知识体系完整回顾 ​

Redis 知识体系
├── 核心概念
│   ├── 内存数据库(快的原因:内存+单线程+IO多路复用)
│   └── KV 模型(Key→Value,8种数据类型)
├── 五大基本类型
│   ├── String(缓存/计数器/分布式锁)
│   ├── Hash(用户信息/购物车)
│   ├── List(消息队列/最新列表)
│   ├── Set(标签/共同好友/抽奖)
│   └── ZSet(排行榜/延时队列)
├── 高级类型
│   ├── Bitmap(签到)
│   ├── HyperLogLog(UV统计)
│   ├── Geo(附近的人)
│   └── Stream(可靠消息队列)
├── 持久化
│   ├── RDB(快照→恢复快)
│   ├── AOF(日志→数据安全)
│   └── 混合持久化(4.0+)
├── 高可用
│   ├── 主从(读写分离)
│   ├── Sentinel(自动故障转移)
│   └── Cluster(数据分片,16384槽)
├── 高级特性
│   ├── 事务(不支持回滚)
│   ├── Lua 脚本(原子性)
│   ├── Pipeline(减少RTT)
│   ├── Pub/Sub(不持久)
│   └── 过期+淘汰(惰性+定期+LRU/LFU)
└── 实践
    ├── go-redis 客户端
    ├── 缓存穿透/击穿/雪崩
    ├── 分布式锁(SET NX EX)
    └── bigkey/热key处理

38.2 高频面试题 40 题 ​

基础概念 ​

Q1:Redis 为什么快?

三点:①纯内存操作;②单线程避免锁竞争和上下文切换;③IO 多路复用。

Q2:Redis 单线程为什么还这么快?

瓶颈在网络 I/O 而不是 CPU。单线程省去了线程切换和锁的开销。Redis 6.0+ 把网络读写改成了多线程,但命令执行仍是单线程。

Q3:Redis 和 MySQL 的区别?

Redis 是内存数据库(快、容量小),MySQL 是磁盘数据库(慢、容量大)。Redis 适合缓存热数据,MySQL 存全量数据。

数据类型 ​

Q4:五种基本类型及应用场景?

String=缓存/计数/锁,Hash=对象/购物车,List=消息队列,Set=标签/共同好友,ZSet=排行榜。

Q5:ZSet 底层是什么结构?

跳表(skiplist)+ 哈希表。跳表支持 O(logN) 范围查询和排名,哈希表支持 O(1) 查询分数。

Q6:ZSet 为什么用跳表而不用红黑树?

跳表实现简单(100行 vs 300行),天然支持范围查询,概率平衡无需旋转。

Q7:Hash 和 String(JSON) 存对象,该用哪个?

大部分场景用 Hash(更新单字段方便)。String(JSON) 适合:字段少、整体读写、需要缓存序列化对象。

Q8:Scan 为什么比 Keys 安全?

Keys 遍历所有 Key(O(N)),阻塞主线程。Scan 分批返回(O(1)每次),不阻塞。

持久化 ​

Q9:RDB vs AOF 的优缺点?

RDB=快照(紧凑、恢复快、可能丢数据),AOF=日志(安全、文件大、恢复慢)。生产推荐两者同时开启。

Q10:AOF 什么时候重写?

AOF 文件大小超过上次重写后的指定百分比(auto-aof-rewrite-percentage 100)。

Q11:混合持久化是什么?

Redis 4.0+:AOF 文件前半部分是 RDB 格式的快照,后半部分是增量 AOF。兼顾恢复速度和数据安全。

高可用 ​

Q12:Sentinel 工作原理?

监控 Master → 主观下线(SDOWN) → 客观下线(ODOWN,多数投票) → 选举 Leader Sentinel → 选最优 Slave 提升为 Master → 通知客户端。

Q13:Cluster 数据怎么分布的?

CRC16(key) % 16384 → 哈希槽 → 槽均匀分布到各节点。16384 个槽。

Q14:Cluster 中跨 Key 操作怎么处理?

用 Hash Tag {user:1}:name 让相关 Key 落在同一个槽。

缓存三大问题 ​

Q15:缓存穿透是什么?怎么解决?

查一个不存在的数据,绕过缓存直击 DB。解决:①布隆过滤器;②缓存空值(短期)。

Q16:缓存击穿是什么?怎么解决?

一个热 Key 过期,大量请求同时打到 DB。解决:①互斥锁;②永不过期 + 异步更新。

Q17:缓存雪崩是什么?怎么解决?

大量 Key 同时过期,DB 瞬间被打爆。解决:①过期时间加随机值;②多级缓存;③限流降级。

分布式 ​

Q18:分布式锁怎么实现?

SET lock:key unique_value NX EX 30。加锁用 SETNX,解锁用 Lua 判断 value 后 DEL(防误删)。

Q19:Redlock 算法是什么?

在 N 个独立的 Redis Master 上分别加锁,超过半数成功才算加锁成功。防止单点 Redis 故障导致锁失效。

Q20:如何保证 DB 和缓存一致性?

延迟双删:先删缓存 → 更新 DB → 延迟后再删缓存。或异步更新:先更新 DB → 通过 MQ/Canal 异步更新缓存。

优化 ​

Q21:bigkey 怎么发现和处理?

redis-cli --bigkeys 扫描。处理:拆分大 Key、UNLINK 异步删除。

Q22:热 key 怎么处理?

①客户端本地缓存;②多副本热 Key;③读写分离(读 Slave)。

Q23:内存淘汰策略有哪些?

noeviction(不淘汰)、allkeys-lru(LRU淘汰)、volatile-lru、allkeys-lfu、volatile-lfu、random 等。

场景设计 ​

Q24:设计一个排行榜

ZSet:ZADD rank 9500 张三 + ZREVRANGE rank 0 9 WITHSCORES 取 Top10。

Q25:设计一个计数器

INCR 原子递增。高并发下批量合并:本地计数 + 定时刷到 Redis。

Q26:设计一个消息队列

简单用 List(BLPOP),可靠用 Stream(消费者组+ACK)。


38.3 进阶学习路线 ​

  1. 阅读 Redis 源码(重点:dict、skiplist、ae 事件循环)
  2. 阅读《Redis 设计与实现》(黄健宏)
  3. 学习 Redis 协议(RESP)
  4. 参与 Redis 社区贡献

最后的话 ​

你从零开始,走完了 38 章的 Redis 学习旅程。掌握了从基础命令到集群部署、从缓存策略到 Go 实战的全链路技能。

Redis 最强大的不是"快",而是它的数据结构和组合方式。学会用 Redis 的思维(KV + 数据结构)解决问题,你就是一个合格的 Redis 工程师。

祝你成为一名优秀的后端工程师!

把零散知识,整理成可以反复走的路。