缓存与性能
021 缓存穿透指的是什么?
难度: 基础
- A. 查询不存在的数据,缓存与数据库都无结果,请求持续打到数据库
- B. 缓存突然全部失效
- C. 单个热点 key 过期后并发重建
- D. 缓存与数据库数据不一致
查看答案与解析
正确答案A
正确原因: 穿透针对“查无此数据”,每次请求都绕过缓存直达数据库。
关键边界: 可用空值缓存、布隆过滤器或参数校验缓解。
错误选项辨析: 全部失效是雪崩,单 key 热点重建是击穿,不一致是另一类问题。
022 缓存击穿指的是什么?
难度: 基础
- A. 单个热点 key 过期瞬间,大量并发请求同时打到数据库
- B. 所有缓存 key 同时过期
- C. 数据库被写满
- D. 缓存命中率 100%
查看答案与解析
正确答案A
正确原因: 击穿是单个热点 key 失效,重建瞬间请求全部回源。
关键边界: 可用互斥锁重建、逻辑过期或热点预热应对。
错误选项辨析: 群体失效是雪崩,写满与命中率无关。
023 缓存雪崩指的是什么?
难度: 基础
- A. 单个 key 被频繁更新
- B. 大量 key 在同一时段集中过期或缓存整体宕机,请求涌向数据库
- C. 缓存命中率过高
- D. 数据库连接数过少
查看答案与解析
正确答案B
正确原因: 雪崩是群体性失效,数据库瞬时压力激增。
关键边界: 过期时间加随机抖动、多级缓存、限流降级可缓解。
错误选项辨析: 单个 key 更新不是雪崩,命中率高是好事,连接数少是结果而非定义。
024 Cache Aside(旁路缓存)模式的更新流程是?
难度: 基础
- A. 写时先删缓存,再更新数据库
- B. 读时先查缓存,未命中再查库并回填;写时先更新库,再删除缓存
- C. 写时只更新缓存,不碰数据库
- D. 读时永远不写缓存
查看答案与解析
正确答案B
正确原因: 先更库后删缓存是标准做法,可避免缓存长期持有旧值。
关键边界: 并发窗口内仍可能短暂不一致,配合过期时间兜底。
错误选项辨析: 先删缓存再更库在并发下易产生旧值回填,只更新缓存会丢写。
025 先更新数据库再删除缓存,仍可能不一致的原因是?
难度: 基础
- A. 删除缓存必然失败
- B. 数据库不支持更新
- C. 并发下旧读先于删缓存执行并回填,短暂旧数据;最终由过期时间兜底
- D. 缓存必须立即强一致
查看答案与解析
正确答案C
正确原因: 删除与回填之间存在竞态窗口,旧数据可能短暂残留。
关键边界: 可加延迟双删、订阅 binlog 或缩短 TTL 收敛。
错误选项辨析: 删除不一定失败,强一致需要额外机制,缓存本质是弱一致。
026 Redis 的过期删除机制是?
难度: 基础
- A. 只在启动时检查一次
- B. 每次写入前全量扫描
- C. 惰性删除加定期删除结合
- D. 过期 key 立即同步删除且不占 CPU
查看答案与解析
正确答案C
正确原因: 惰性删除在访问时发现过期即删,定期删除后台抽样清理。
关键边界: 两者配合控制内存占用与 CPU 开销,过期 key 不保证立即消失。
错误选项辨析: 启动时检查、全量扫描、零成本删除都不符合实际机制。
027 布隆过滤器用于缓存穿透治理的原理是?
难度: 进阶
- A. 精确判断 key 是否存在于数据库
- B. 替代数据库存储所有数据
- C. 能删除任意已加入的元素
- D. 用多个哈希位判断“一定不存在”,过滤掉不存在 key 的查询
查看答案与解析
正确答案D
正确原因: 布隆过滤器把所有位都命中才认为可能存在,只要有位未命中就一定不存在。
关键边界: 存在误判(可能把不存在判为存在),但不会漏判,标准实现不支持删除。
错误选项辨析: 它不存数据也不精确判存在,误判特性决定了只能拦截“一定不存在”。
028 热点 key 过期后防止击穿的“互斥锁重建”是?
难度: 进阶
- A. 所有线程同时重建,越快越好
- B. 锁只需要在数据库上加
- C. 重建完成后不需要回填缓存
- D. 只允许一个线程重建缓存,其余线程短暂等待或返回旧值
查看答案与解析
正确答案D
正确原因: 用 SETNX 分布式锁控制单点重建,降低数据库瞬时压力。
关键边界: 需处理锁过期、重建失败与等待超时。
错误选项辨析: 并发重建正是击穿的原因,缓存锁与数据库锁位置不同,重建后必须回填。
029 逻辑过期方案的做法是?
难度: 进阶
- A. 缓存值内嵌过期时间,读时发现逻辑过期则异步重建并短暂返回旧值
- B. 依赖 Redis 原生 TTL 立即删除
- C. 逻辑过期后直接返回空
- D. 逻辑过期与 TTL 完全相同
查看答案与解析
正确答案A
正确原因: 逻辑过期不依赖 TTL 删除,读仍返回旧数据,后台线程异步刷新。
关键边界: 需防并发重建,可配合分布式锁。
错误选项辨析: 逻辑过期是业务层时间戳,不触发删除,不返回空,与 TTL 机制不同。
030 大 key 与热 key 对 Redis 的影响是?
难度: 进阶
- A. 大 key 阻塞命令执行与复制;热 key 使单节点 CPU 与网络成为瓶颈
- B. 两者对性能都没有影响
- C. 大 key 会自动压缩为小 key
- D. 热 key 会自动迁移到其他节点
查看答案与解析
正确答案A
正确原因: 大 key 的操作耗时阻塞单线程,热 key 让单个节点承受集中流量。
关键边界: 大 key 用 Hash 分段拆分,热 key 用副本打散与本地缓存缓解。
错误选项辨析: 两者影响显著,不会自动压缩或迁移。
031 Pipeline 的核心收益是?
难度: 进阶
- A. 保证命令原子执行
- B. 一次 RTT 发送多条命令,显著降低网络往返开销
- C. 减少命令总数
- D. 让 Redis 并行处理命令
查看答案与解析
正确答案B
正确原因: Pipeline 把多条命令打包发送并批量读取响应,减少 RTT 与系统调用。
关键边界: 不保证原子性,批次过大会占用内存积压响应。
错误选项辨析: 原子性靠事务或 Lua,命令总数不变,Redis 仍串行执行。
032 Lua 脚本在 Redis 中的执行特性是?
难度: 进阶
- A. 脚本内可以异步并行执行
- B. 脚本整体原子执行,期间其他命令不会穿插
- C. 脚本执行可被其他客户端打断
- D. Lua 脚本只能读不能写
查看答案与解析
正确答案B
正确原因: Redis 将脚本作为整体原子执行,读改写逻辑不会被穿插。
关键边界: 脚本应短小,长脚本会阻塞其他命令,影响吞吐。
错误选项辨析: 脚本同步执行不可打断,且支持读写。
033 SET key value NX EX seconds 相比 SETNX 加 EXPIRE 分开执行的优点是?
难度: 进阶
- A. 命令数量更多,网络开销更大
- B. NX 与 EX 互斥,不能同时使用
- C. 加锁与设置过期原子完成,避免加锁后崩溃导致锁永不释放
- D. 这种写法不返回任何结果
查看答案与解析
正确答案C
正确原因: 单条命令原子完成加锁与过期设置,消除两步之间的故障窗口。
关键边界: 释放锁时仍要用 Lua 校验 value 再删除。
错误选项辨析: 它减少命令数,NX 与 EX 可组合,且会返回 OK 或 nil。
034 分布式锁释放时为什么要用 Lua 比较 value 再 DEL?
难度: 进阶
- A. 让删除操作更快
- B. Lua 是唯一能 DEL 的方式
- C. 防止误删他人持有的锁(锁已过期且被其他线程重新获取)
- D. 为了统计删除次数
查看答案与解析
正确答案C
正确原因: GET 与 DEL 分开存在竞态,可能删除他人刚获取的锁,Lua 原子完成校验加删除。
关键边界: value 应使用唯一标识(如 UUID)区分持有者。
错误选项辨析: Lua 是为原子性而非性能,DEL 本身可用,关键是校验。
035 缓存与数据库最终一致性的工程方案是?
难度: 实战
- A. 完全依赖数据库触发缓存,无需任何代码
- B. 只更新缓存不更新数据库
- C. 任何情况下缓存都必须实时强一致
- D. 订阅 binlog(如 Canal)异步删除或更新缓存,结合重试与 TTL 兜底
查看答案与解析
正确答案D
正确原因: 变更订阅解耦业务,失败可重试补偿,配合短 TTL 最终收敛。
关键边界: 最终一致不等于实时一致,业务需按场景设计容忍度。
错误选项辨析: 需要应用或中间件配合,缓存不能替代数据库,强一致需要专门设计。
036 应对热点 key 的常见手段是?
难度: 实战
- A. 把热点 key 的 TTL 设成无限长
- B. 删除热点 key 让请求回源
- C. 增加副本数量但与读取逻辑无关
- D. 本地缓存加 key 打散(多副本)加限流降级
查看答案与解析
正确答案D
正确原因: 热 key 打散成多个副本分散读压力,本地缓存承接部分流量,必要时限流。
关键边界: 多副本更新需要一致性处理,副本失效时要及时清理。
错误选项辨析: 无限 TTL 会放大过期风险,删除 key 会回源,副本需要读取逻辑配合。
037 缓存命中率的含义与价值是?
难度: 基础
- A. 命中的读请求占比,越高表示数据库承担的读越少
- B. 命中率只影响写入速度
- C. 命中率 100% 表示缓存未工作
- D. 命中率无法通过监控观测
查看答案与解析
正确答案A
正确原因: 命中率是缓存核心指标,反映缓存对数据库读压力的分流效果。
关键边界: 命中率低要排查过期策略、key 设计与淘汰配置。
错误选项辨析: 命中率影响读路径,100% 是理想状态,且可监控。
038 缓存粒度(整对象 vs 字段级)的选择依据是?
难度: 基础
- A. 粒度越小一定越省内存
- B. 按访问模式权衡——整对象简单但更新粒度粗,字段级更精准但更复杂
- C. 必须缓存整张表
- D. 粒度与读写比例无关
查看答案与解析
正确答案B
正确原因: 高频更新个别字段时字段级更优,读多整取时整对象更简单高效。
关键边界: 粒度选择要结合命中率、序列化成本与一致性需求。
错误选项辨析: 粒度小不等于省内存,缓存整表不合理,读写模式是核心依据。
039 多级缓存(本地加 Redis)的主要考量是?
难度: 进阶
- A. 本地缓存越多越好,无需管理
- B. 多级缓存可以自动强一致
- C. 本地缓存延迟最低但存在多实例一致性成本,需控制更新与失效
- D. 本地缓存不适合任何场景
查看答案与解析
正确答案C
正确原因: 每级缓存都有命中率与一致性问题,本地缓存要处理多实例同步。
关键边界: 热点静态数据适合本地缓存,动态数据需谨慎。
错误选项辨析: 缓存需要治理而非堆叠,多级缓存不自动强一致,也有适用场景。
040 缓存服务故障时的降级策略是?
难度: 实战
- A. 无限重试直到缓存恢复
- B. 停掉所有业务请求
- C. 提高缓存超时让请求长时间等待
- D. 限流加直接回源数据库并缩短超时,保护数据库不被拖垮
查看答案与解析
正确答案D
正确原因: 故障时快速失败、限流并直连数据库,防止雪崩式打挂后端。
关键边界: 必要时启用降级默认值,事后恢复缓存并预热。
错误选项辨析: 无限重试会放大压力,停业务与长等待都会伤害可用性。