Redis 面试题经常给人一种“夺命连环问”的感觉:从数据结构问到缓存,从缓存问到分布式锁,再从分布式锁追问到集群脑裂和 Redis 日志,很多人在技术群里能聊几句,真到面试现场却容易卡壳。原因不是你没有背过题,而是你习惯按“知识点”去记,面试官却按“问题链路”去问。只要他连续追问三个“为什么”,原本背好的答案就接不住了。
我自己的建议很直接:不要按“85 问、100 问”这样的清单去死磕,而是把 Redis 面试拆成四块主线——数据结构、缓存、分布式锁、集群高可用。每块都按“场景 → 方案 → 实现细节 → 边界 → 追问”来准备。这篇文章就按这个思路走,把所有高频追问点串起来,最后再给一份 3 天的实操学习计划,以及我在本地环境、客户端工具、日志排查里踩过的坑。你按这个框架准备,大概率不会出现“面试官换个说法就不会”的情况。
1. 先想清楚 Redis 面试到底面什么
很多人的准备方式是把网上流传的 Redis 面试题合集从头背到尾,背着背着就乱。原因很简单:题目之间本来就有强关联,你不知道面试官问这道题是为了引出哪条线,就只能在单点上打转。
1.1 为什么 85 问听着夸张,其实底层就四块
Redis 的面试题看起来数量庞大,但高频问题几乎都逃不开四条主线:
- 数据类型与底层结构:String、Hash、List、Set、ZSet,以及底层 SDS、跳表、压缩列表、quicklist 等。
- 缓存设计:缓存穿透、缓存击穿、缓存雪崩、缓存一致性、淘汰策略、分布式缓存的使用边界。
- 分布式锁:为什么需要分布式锁、Redis 实现分布式锁的细节、看门狗、红锁、主从切换导致的锁失效。
- 高可用与集群:主从复制、哨兵、Cluster、槽位、扩容、脑裂、数据丢失、故障转移。
这四块不是孤立的。面试官问“Redis 为什么快”可以引到单线程模型,再引到 IO 多路复用,再引到数据结构设计;问“缓存和数据库一致性”可以引到延迟双删、消息队列、版本号,再引到分布式锁;问“分布式锁”可以引到 set 命令参数、Redisson、主从切换,最后落在集群高可用上。所以你要准备的不是孤立答案,而是这些答案之间的跳转路径。
1.2 面试官希望通过一个问题看到你的哪些能力
我用一个很常见的例子来说明。面试官问:“Redis 为什么快?”如果你只回答“单线程、内存操作、IO 多路复用”,这只能说明你背过八股。如果他接着问“为什么单线程还能处理大量并发?”你再回答“因为 Redis 完全基于内存操作,CPU 不是瓶颈”,其实也不太够。真正有价值的回答是:先解释 Redis 以事件循环为核心,再说明文件事件处理器如何复用 epoll,再补充 Redis 的瓶颈通常在于网络 IO 和内存/Fork 成本,而不是 CPU。
这个回答过程展示了三件事:
- 你能把概念串起来,而不是背定义。
- 你知道性能的边界在哪里,而不是只说优点。
- 你理解面试官追问背后的意图,而不是急着证明自己知道。
所以准备面试时,不要只在答案里写“单线程模型”,还要准备“为什么单线程”“单线程哪里可能成为瓶颈”“6.0 之后为什么引入多线程 IO 处理网络读写”这三层内容。
1.3 怎么准备才能不被“夺命连环问”带节奏
我给自己的准备方法是:每个高频知识点都写一张“问答卡片”,卡片上只写四个部分——场景、做法、细节、坑。以“缓存穿透”为例:
- 场景:大量请求查询一个不存在的 key,缓存里没有,数据库里也没有。
- 做法:缓存空值、布隆过滤器、参数校验。
- 细节:空值设置过期时间;布隆过滤器可能存在误判;用布隆过滤器时要注意 key 的粒度。
- 坑:缓存空值会让缓存内存上升;布隆过滤器不适合精确计数场景;极端情况下恶意请求打满布隆过滤器。
这样准备出来的答案,面试官想往下追,你也能顺着往下走。他不会觉得你在背题,反而会觉得你确实处理过相关问题。
2. Redis 数据结构考的不是命名,是选择逻辑
很多人背了五种基本类型的命令,也能说出“String 存字符串,Hash 存对象”,但一遇到场景题就翻车。原因是面试官关心的不是你知不知道命令,而是你能不能根据内存、查询方式、范围操作来选择合适的数据结构。
2.1 五种基本类型和底层编码
这五种类型必须能脱口而出,同时还得知道它们在不同编码下的存储变化:
- String:字符串、整数、二进制安全。底层可以是整数编码、embstr、raw。
- Hash:适合存对象。底层可以是 ziplist、hashtable;在 Redis 7.0 之后 listpack 取代了部分 ziplist 场景。
- List:适合消息队列、时间线。底层可以是 quicklist,Redis 7.0 之后的 listpack 相关实现也更常见。
- Set:适合去重、标签、共同好友。底层可以是 intset、hashtable。
- ZSet:适合排行榜、延迟队列。底层可以是 ziplist 或 skiplist + dict。
面试时不要只说出“底层是什么”,还要能解释“为什么这样设计”。比如 Hash 字段少、值小时用紧凑结构,字段增多或值变大后转成 hashtable;ZSet 用跳表是为了支持范围查找,同时用 dict 保证单 key 查询也能 O(1)。这种“为什么”才是加分项。
这里有个很容易踩的坑:不同 Redis 版本的默认配置不一样。面试时如果你只说“Hash 默认用 ziplist”,其实在 7.0 之后很多地方已经换成 listpack,所以更稳妥的说法是“在满足一定条件时使用紧凑结构,条件不满足后转换为标准结构”。这样既不影响答案框架,也不会被版本细节卡住。
2.2 面试常问的底层结构:SDS、跳表、压缩列表
这部分最容易让人头疼,但面试官并不指望你把源码背全,他更想看到你能讲清楚“SDS 为什么比 C 字符串安全”。《Redis 设计与实现》里讲得很清楚:SDS 增加了长度字段,获取长度是 O(1),避免缓冲区溢出,还能减少修改字符串时内存重分配次数,二进制安全。
跳表的问题也类似。你需要知道它为什么适合有序集合:可以在 O(log N) 范围内查找、删除、插入,同时容易实现范围查询。相比平衡树,跳表实现简单,层数通过随机生成来维持平衡,读多写少的场景里表现稳定。
压缩列表和 listpack 是近几年面试题里的新热点。你不需要逐行读源码,但要理解它的设计目标:节省内存。连续内存块保存多个元素,避免指针占用大量空间。缺点也很明显,更新、插入、删除时可能需要连锁更新,性能不稳定。所以 Redis 才对紧凑结构的使用条件做了限制。
2.3 真实场景里怎么选型
笔试和面试里经常出现“如何实现一个点赞系统”“如何实现好友关注”“如何实现排行榜”这类问题。答案的关键不是命令,而是选择逻辑:
- 点赞/收藏:用 Set,因为天然去重,求交集、并集也方便。
- 排行榜:用 ZSet,score 存分数,member 存用户 ID,可以快速取 Top N。
- 对象存储:用 Hash,字段对应属性,适合更新某个字段。
- 消息队列:可以用 List + BRPOPLPUSH,也可以考虑 Stream,但别把 Redis 当成可靠消息系统来用。
- 最新列表:用 List 的 LTRIM 或者 ZSet 按时间排序。
面试时最怕你只说“用这个类型”,却不解释为什么。只要补上一句“因为 Set 可以去重,而且支持集合操作,所以适合关注关系”,整个答案的颗粒度就完全不同。
3. 缓存相关的追问通常从“缓存失效”开始
Redis 在业务里最常见的角色就是分布式缓存。面试官问缓存基本不会只问“什么是缓存击穿”,而是会把缓存失效问题、缓存一致性、淘汰策略放在一起问。这个模块一定要准备成一套体系。
3.1 缓存穿透、击穿、雪崩的区别和应对
这三个概念很多人背得熟,但真正回答时会混在一起。我建议你用“查什么、坏在哪里、影响多大”来区分:
- 缓存穿透:查询一个不存在的 key。缓存和数据库里都没有,请求直接打到数据库。应对方式是参数校验、缓存空值、布隆过滤器。
- 缓存击穿:一个热点 key 失效的瞬间,大量并发请求同时回源数据库。应对方式是互斥锁、热点数据不过期、逻辑过期。
- 缓存雪崩:大量 key 在同一段时间内失效,或者 Redis 实例宕机,导致大量请求落到数据库。应对方式是过期时间加随机值、多级缓存、服务降级、哨兵高可用。
这里最容易犯的错误是:把“击穿”说成“穿透导致的数据库压力剧增”。这两个问题虽然都能把数据库压垮,但本质不同。击穿是“有数据但缓存失效”,穿透是“根本没有数据”。你在回答时最好先一句话概括本质,再展开应对方式。这样面试官能立刻抓住你的逻辑。
3.2 缓存一致性到底怎么答
缓存一致性是面试里的重灾区。面试官常问:“更新数据库和更新缓存,顺序应该怎么样?”这个问题没有绝对标准答案,但有面试官愿意听的结构。
第一步,先说明强一致性很难保证。只要 Redis 和 MySQL 是两个独立组件,就一定存在时间窗口。业务上一般接受最终一致性。
第二步,按场景选择方案:
- 读多写少:先更新数据库,再删除缓存。这是最常见做法,因为删除缓存成本低,下一次读请求自然会重建缓存。
- 写多读少:可以更新数据库后删除缓存,但在高并发下可能出现旧缓存被重建、数据不一致的问题。
- 延迟双删:更新数据库后,删除缓存,过一小段时间再次删除。目的是解决旧读请求把脏数据写回缓存的问题。但延迟时间很难定,所以只适合对一致性要求偏高的场景,不能当成银弹。
- 消息队列异步删除:把删除缓存操作发到 MQ,由消费者执行。可以配合重试,保证最终删除成功。
第三步,主动说一句边界:“如果业务允许短暂不一致,通常先更新数据库再删缓存就够;如果不允许,就要引入 binlog 订阅或者 MQ,但代价会明显变大。”这句话一出来,面试官就知道你不是只会背书。
3.3 缓存淘汰和内存策略
Redis 默认会在内存达到 maxmemory 时触发淘汰策略。面试题常问“Redis 内存满了怎么办”,其实就是在考察淘汰策略。
常见策略:
- noeviction:不淘汰,直接报错。
- volatile-lru:只对设置了过期时间的 key 做 LRU。
- allkeys-lru:所有 key 做 LRU。
- volatile-lfu:对设置了过期时间的 key 做 LFU。
- allkeys-lfu:所有 key 做 LFU。
- volatile-random:对设置了过期时间的 key 随机淘汰。
- allkeys-random:所有 key 随机淘汰。
选择依据是业务对热数据的敏感程度。比如大部分缓存场景用 allkeys-lru 就够了,因为 Redis 默认并不保证冷数据一定被淘汰,只是近似 LRU。如果你希望更准确地识别热数据,可以改用 LFU,但 LFU 需要更长时间统计访问频率,内存也会有额外开销。
另外一个容易追问的点是:Redis 的 LRU 是近似 LRU,不是严格 LRU。Redis 在内存中抽样,再根据访问时间淘汰最久没访问的 key。这种设计避免维护完整 LRU 链表带来的额外内存和性能开销。面试时主动说明这一点,通常会加分。
4. 分布式锁最容易翻车,先把实现细节吃透
分布式锁是 Redis 面试里最容易被追到穷尽的部分。原因很简单:单机锁好理解,但分布式锁涉及网络、超时、主从切换、时钟跳跃、GC 停顿等一堆边界。面试官只要连续问“锁失效了怎么办”“主从切换后锁丢了怎么办”,很多人的答案就开始含糊。
4.1 单机锁和分布式锁的差异
在单机服务里,你通常用 synchronized 或 ReentrantLock。但在分布式环境下,多个服务进程需要抢同一份公共资源,单机锁就不管用了。分布式锁的核心目的:在同一时间内,多个进程里只能有一个进程持有锁,并执行临界区代码。
Redis 能当分布式锁的组件,原因是它足够快、足够简单,而且大多数公司已经具备 Redis 运维能力。但要注意,Redis 分布式锁并不是“绝对可靠”,它靠的是“超时时间 + 唯一标识 + 原子操作”来降低风险,而不是消除风险。
4.2 基于 Redis 的实现和边界
最早的实现方式是:
SET lock_key unique_value NX PX 30000这行命令的意思是:只有当 lock_key 不存在时才设置成功,并设置过期时间为 30000 毫秒,value 用唯一标识防止误删。
释放锁时不能直接DEL,必须先比对 value 再删除,并且要用 Lua 脚本保证原子性:
if redis.call("get", KEYS[1]) == ARGV[1] then return redis.call("del", KEYS[1]) else return 0 end这套做法看起来简单,但边界很多:
- 如果业务执行时间超过锁过期时间,锁提前释放,其他线程就能拿到锁,原线程还在执行。解决思路是让锁持有方续期,而不是把过期时间无限调大。
- 如果某个线程持锁后发生极端阻塞,锁过期会导致并发冲突。解决思路是设置合理的过期时间,并在临界区代码里加“检查点”或“暂时无解”的说明。
- 如果删除锁时用
DEL,可能把别人已经获取到的锁删掉,所以必须用唯一标识比对。
这些边界问题一定要在面试时主动讲出来。面试官最喜欢听到“我知道这里存在过期问题,所以用看门狗续期”之类的话。
4.3 Redisson 和看门狗
Redisson 是 Java 生态里常用的 Redis 客户端,它的分布式锁实现已经处理了很多细节。常见用法是:
RLock lock = redissonClient.getLock("order:pay:2026"); if (lock.tryLock(10, TimeUnit.SECONDS)) { try { // 业务逻辑 } finally { lock.unlock(); } }Redisson 的看门狗机制:默认锁在获取之后,会有一个后台线程每隔一段时间检查锁是否还存在,如果业务还没执行完,就自动续期,避免锁过期。
但看门狗不是万能的。如果 Redisson 客户端本身发生长时间 GC 停顿,或者客户端进程被暂停,看门狗线程也可能没有及时续期。面试时如果只答“用 Redisson 就解决了”,非常容易暴露深度不足。更稳的回答是:Redisson 能解决大部分业务场景下的锁过期问题,但如果你需要严格的互斥保障,还要考虑进程暂停、网络分区等情况,这就已经接近分布式系统理论边界了。
4.4 面试官追问主从切换和 Redlock 时怎么答
Redis 主从架构下,锁数据是先写到主节点,再异步复制到从节点。如果主节点刚写入锁就宕机,从节点晋升为主节点后,旧主节点上的锁丢失,其他线程就可能获取到同一把锁。这就是“主从切换导致锁失效”。
Redlock 的解决思路是:不再依赖单个 Redis 实例,而是同时向多个独立的 Redis 节点请求加锁,需要超过一半节点加锁成功,并且加锁总耗时小于锁过期时间,才认为加锁成功。
面试时你应该说清楚 Redlock 的适用条件和争议:
- 好处:避免了单个 Redis 实例故障导致的锁丢失,在少数派节点故障时仍然可用。
- 问题:它依赖节点间没有时钟漂移,而且“超过一半节点”并不等于绝对安全;网络分区、垃圾回收暂停、进程阻塞都可能导致多个客户端同时持有锁。
不要直接说“Redlock 没用”或“Redis 分布式锁完全正确”,而是说:“普通业务场景里,基于单个 Redis 主从的分布式锁基本够用;如果业务要求非常严格的互斥,就要评估 Redlock 的复杂度和理论局限。”这个回答比单纯背书要有说服力得多。
5. 集群和高可用不是背架构,要讲清楚故障链路
Redis 集群相关的面试题看起来是在考“哨兵怎么工作”“Cluster 槽位怎么分布”,实际上考的是“如果一台机器挂了,你的系统会发生什么,你能怎么恢复”。这部分要重点准备故障链路。
5.1 主从复制的基础流程
主从复制是 Redis 高可用的基础。它的核心流程是:从节点向主节点发起同步请求,先做全量同步,再持续做增量同步。
流程大致是:
- 从节点发送
PSYNC命令。 - 主节点返回
FULLRESYNC,触发全量复制。 - 主节点执行
BGSAVE生成 RDB 快照,同时把新写入命令记录到缓冲区。 - 将 RDB 文件发送给从节点。
- 从节点加载 RDB 后,主节点再把缓冲区里的增量命令继续发给从节点。
面试时不要只说“主从复制就是把数据同步过去”,要补充几个关键点:
BGSAVE会 fork 子进程,如果内存很大,fork 可能耗时,导致复制延迟。- 全量复制期间主节点有新写入,会通过 repl_backlog 缓冲区补发。
- 网络不稳定时,从节点会尝试增量同步;如果 repl_backlog 太小,可能退化为全量复制。
这些问题实际运维中很常见。如果你能说清楚“复制延迟怎么排查”,比如通过INFO replication看master_repl_offset和slave_repl_offset的差距,面试官会认为你有真实运维经验。
5.2 哨兵模式如何做故障转移
哨兵解决的是主节点挂了之后,自动把某个从节点提升为主节点的问题。核心概念是:哨兵节点会定期向主从节点发送命令,如果主节点客观下线,就执行故障转移。
面试常问的细节:
- 主观下线:单个哨兵发现主节点没响应。
- 客观下线:多个哨兵都判定主节点不可用,达到 quorum。
- 故障转移:哨兵集群会选举 leader,然后从从节点里选一个执行
SLAVEOF NO ONE,其他从节点重新指向新主节点。 - 客户端感知:哨兵会发布通知,客户端需要把主节点地址换成新主节点。
难点在于:故障转移期间会不会丢数据?答案是可能。因为主从复制是异步的,主节点还没来得及把最后的写入复制给从节点,主节点就宕机了。即使设置min-slaves-to-write和min-slaves-max-lag,也只是降低风险,不能完全避免。
面试时你还需要说清楚哨兵并不是 Redis Cluster,它只负责主从切换,不负责数据分片。如果业务数据量已经超过单机内存,哨兵模式仍然受限于单机容量,这时才需要 Cluster。
5.3 Cluster 的槽位和扩容思路
Redis Cluster 的核心是数据分片。整个 key 空间被划分为 16384 个槽位,每个主节点负责一部分槽位。客户端根据 key 的 CRC16 值 mod 16384 决定它落在哪个槽位。
面试高频点:
- 为什么是 16384?CRC16 最多产生 2^16 种值,16384 是 2^14。官方设计时考虑过心跳包大小、节点数量上限和场景复杂度,最后选用 16384。不需要背得很精确,但要知道这不是拍脑袋,而是权衡了网络开销和节点扩展性。
- 槽位怎么迁移?Cluster 支持在线扩容,把部分槽位从已有节点迁移到新节点,迁移过程中会涉及阻塞和非阻塞的迁移命令。
- key 怎么保证同一个节点?用 hash tag,让包含相同
{}部分的 key 落在同一个槽位。 - 客户端怎么处理 MOVED 和 ASK?MOVED 表示客户端需要重定向到正确节点,ASK 表示槽位正在迁移,客户端需要尝试新节点。
集群模式下的命令限制也很重要:多 key 操作必须保证 key 在同一个槽位,所以批量操作经常需要设计 hash tag。面试官如果问“在 Cluster 里可以随便用mget吗”,答案就是不行,会出现跨槽位错误。这时你要主动给出解决办法。
5.4 脑裂、数据丢失和运维排查
脑裂通常出现在哨兵模式下:主节点和哨兵集群之间网络不通,哨兵认为主节点挂了,于是选出一个新主节点,但老主节点还在继续接收写入。等网络恢复后,老主节点降级为从节点,它这段时间收到的写入会全部丢失,这就是脑裂导致的数据丢失。
应对方式主要有:
- 调整
min-replicas-to-write,让主节点在从节点数量不足或延迟过大时拒绝写入,尽量减少脑裂期间产生的写入。 - 调整
min-replicas-max-lag,控制从节点同步延迟阈值。 - 部署上尽量让哨兵和主节点之间网络可靠。
运维排查时,先看 Redis 日志,再看INFO replication,确认主从偏移量。很多问题不是功能不支持,而是配置参数、网络抖动、内存和磁盘空间导致。面试时你可以举例:主从复制延迟过大,不一定是从节点性能差,也可能是主节点写入了大量大 key,导致 RDB 全量同步频繁触发。这种判断能体现你的排查能力。
6. Redis 面试准备中的环境、工具和日志排查
有不少人面试前只在网上刷题,没有在本地跑过 Redis。结果一遇到涉及安装、连接、日志的问题,就只能靠猜。我建议花半天时间把本地环境搭建起来,把常用命令、客户端工具和日志位置都过一遍。
6.1 本地装一个 Redis:下载、连接工具和版本确认
Redis 在 Windows 上不是官方原生支持的,官方推荐在 Linux 或 WSL 上运行。如果你只是想快速学习,可以选以下方式:
- 在云服务器或本地 Linux 虚拟机里安装 Redis。
- 在 Windows 上用 WSL2 跑 Redis。
- 用 Docker 起一个 Redis 容器。
- 如果你必须在 Windows 直接跑,可以用第三方移植版,但要注意版本可能滞后,生产环境不建议用。
这里以 Docker 为例:
docker run -d --name my-redis -p 6379:6379 redis:7.2启动后,可以用redis-cli进入命令行:
docker exec -it my-redis redis-cli 127.0.0.1:6379> ping PONG 127.0.0.1:6379> info server如果是本地安装,安装完成后先看版本:
redis-server --version面试常见问题“你怎么确认当前 Redis 版本和运行状态”就对应这条命令,以及INFO命令里的 server 和 repl 部分。
连接工具方面,很多人会用到 Redis Desktop Manager 或 Another Redis Desktop Manager。这类可视化工具适合查看 key、修改缓存、观察过期时间,但面试时最好不要只依赖图形界面,因为面试现场通常没有可视化工具,你还是要会redis-cli。至少要掌握-h、-p、-a参数,以及常用数据类型的增删改查命令。
6.2 通过日志和监控判断问题
Redis 日志位置和级别会影响你排查问题的速度。启动时可以用--logfile指定日志文件,也可以用logfile ""让日志输出到标准输出。在 Docker 容器里,直接看容器日志:
docker logs my-redis本地启动时,如果你发现 Redis 启动失败,第一步不是去改配置,而是看错误信息。常见的启动失败原因包括:
- 端口被占用,改成其他端口或用
redis-cli -p指定。 - 配置文件里的
dir目录不存在,导致 RDB 持久化失败。 - 日志级别和通知相关配置不正确,导致一堆 WARNING。
daemonize yes配置后,日志输出位置容易忽略。
运行时出现慢查询,可以用SLOWLOG查看:
127.0.0.1:6379> SLOWLOG GET 10通过慢日志可以判断是不是有大 key、复杂命令或者网络返回慢。面试时如果问“Redis 为什么变慢了”,你可以从 CPU、内存、网络、持久化、大 key、慢查询几个维度展开,定位链路比背一个结论重要得多。
6.3 可视化工具和命令行结合
可视化工具适合学习阶段快速观察数据,但排查问题的主战场仍然是redis-cli。比如:
KEYS pattern:可以查 key,但生产环境慎用,会阻塞。SCAN cursor:更适合遍历 key,避免阻塞。MONITOR:可以看到实时命令,但生产环境不要乱开。INFO:查看内存、复制、持久化、CPU 等运行时状态。
面试时如果你说自己用过可视化工具,面试官基本不会深究;但如果你说自己会看INFO replication、INFO memory、INFO stats,他会觉得你具备生产经验。所以准备面试时,不要忽略命令行基本功。
7. 3 天学习计划怎么安排才更合理
标题里说的“3 天学会”更像是一个宣传口号,但如果你把内容压缩得很有效,三天确实能建立一个系统化框架。关键在于不要平均用力,而是按“高频考点优先级”来安排。
7.1 第一天:数据结构、持久化和缓存
第一天重点打基础:
- 熟悉 String、Hash、List、Set、ZSet 的基本命令和典型应用场景。
- 理解底层编码结构:SDS、ziplist、listpack、quicklist、skiplist。
- 掌握 RDB 和 AOF 的区别、触发条件、优缺点。
- 刷缓存穿透、击穿、雪崩、一致性、淘汰策略的高频题。
第一天晚上,动手在本地写一个小项目:用 Redis 做一个简单缓存,模拟缓存穿透和击穿场景。不一定要很复杂,关键是能跑通,并且能把日志、命令、效果对应起来。
7.2 第二天:分布式锁和高可用
第二天集中进攻分布式锁和集群:
- 手动实现一个基于
SET NX PX的分布式锁。 - 用 Lua 脚本实现安全释放锁。
- 了解 Redisson 的看门狗机制和源码思路。
- 理解主从复制、哨兵、Cluster 的基本流程和故障转移。
- 尝试用 Docker 配置一个主从复制或哨兵环境。
第二天最重要的不是记住所有命令,而是把“锁丢失、超时、主从切换、脑裂”这四类故障推导一遍。每一类都要能说清楚“问题是怎么出现的,有什么缓解方案”。
7.3 第三天:真题模拟和查漏补缺
第三天用来做模拟面试。不要只看题,可以自己给自己出题,或者用录音软件把你的回答录下来回听。回听时重点关注两点:
- 有没有用术语但解释不清楚。
- 有没有只说结论但没有场景和边界。
如果你能连续回答完以下八个问题不断档,说明准备得比较扎实:
- Redis 为什么快?
- String 和 Hash 存对象怎么选?
- 缓存穿透怎么解决?
- 缓存和数据库一致性怎么保证?
- 分布式锁底层怎么实现?
- Redis 主从复制过程是什么?
- 哨兵如何工作?
- Cluster 怎么扩容?
如果你想更严格,可以再加几个追问:主从切换时锁丢失怎么办?缓存淘汰策略选 LRU 还是 LFU?Big Key 怎么处理?生产环境 Redis 变慢怎么排查?
8. 回答面试题时最容易出现的四种问题
即使你知识点都懂了,答题方式也可能让面试官误解。我整理了四个最常见的问题,准备面试时可以对照检查。
8.1 背概念但不谈场景
最典型的表现是:面试官问“你用 Redis 做什么”,你回答“做缓存”。听起来没错,但其实没有信息量。更好的回答是:“我在某个订单查询场景里,用它缓存用户订单列表快照,key 按用户维度设计,过期时间加上随机值防止雪崩,数据库更新后主动删除缓存。”这样就把场景、技术、细节、坑全部串起来了。
8.2 动不动就说“Redis 是单线程的”
这句话本身不准确。Redis 的命令处理部分在 6.0 之前是单线程,但持久化、主从同步、部分删除操作等都有子进程或后台线程。6.0 之后又引入了多线程 IO 来处理网络读写。如果你只答“Redis 是单线程”,遇到版本追问就很容易被纠正。
建议说成:Redis 命令执行核心是单线程模型,所以不需要考虑传统并发控制;Redis 6.0 之后对网络读写引入多线程,但命令执行仍然是单线程。这样既准确,又显得你关注过版本更新。
8.3 不主动交代边界
很多 Redis 解决方案都有适用边界,比如缓存空值、延迟双删、分布式锁、集群模式下的多 key 操作。如果你不主动说明边界,面试官会认为你只见过“书本场景”,没见过“生产冲突”。
比如延迟双删,你可以这样收尾:“这个方案只适合对一致性要求偏高的业务,并且延迟时间难以精确控制,所以我通常建议用 MQ 异步重试来替代。”这句话说明你思考过方案的局限。
8.4 忽略版本差异和运维环境
Redis 2.8、3.0、4.0、6.0、7.0 之间差异很大。3.0 开始支持 Cluster,4.0 引入混合持久化和 LFU,6.0 引入多线程 IO,7.0 引入 Function 和命令分组执行等。面试时如果讲某个特性,最好先加一句“我目前主要使用 Redis 6.x 或 7.x”。这样既避免版本混淆,也体现你在实际环境里有过研究。
运维环境也很重要。比如你在讲哨兵时,不要默认“哨兵只有一台”,因为生产环境至少要部署 3 个哨兵节点,否则哨兵本身就成了单点。面试官比较喜欢听到这种“部署数量”级别的细节。
最后留一个问题给自己:Redis 面试题数量再多,核心也就四块。你不需要记住所有零散问题,只需要把“场景 → 方案 → 细节 → 坑 → 版本/环境边界”这条链路练熟。真正到面试现场,你会有一种感觉:不是每个问题都见过,但每个问题都能顺着链路往下推。这才是把 Redis 吃透后的状态。