游乐游手机版
首页/AI热点日报/热点详情

台州餐饮发票开具流程步骤与材料详解

类型:热点整理2026-07-25
针对Redis缓存问题,需先区分穿透、击穿、雪崩:穿透指请求不存在数据,处理包括参数校验、缓存空值、布隆过滤器;击穿指热点key过期,可用互斥锁(原子命令)或逻辑过期异步刷新;雪崩指大量key同时过期或Redis不可用,采用随机TTL、预热、本地缓存、限流降级等分层策略。

最近在浏览 Java 后端秋招提前批的面经时,发现 Redis 被频繁提及。面试官往往不会问“Redis 有哪些数据结构”这样泛泛的问题,而是直接从项目切入:你的简历中写了缓存优化,那么缓存穿透、缓存击穿、缓存雪崩分别如何处理?为什么这样处理?线上是否真的实施过?

这道题看起来像八股文,但其实很容易被追问到底。很多人一开始就背答案:“穿透用布隆过滤器,击穿用互斥锁,雪崩加随机过期时间”,结果面试官再追问两句就回答不上来了。

更推荐按照“一次请求的完整流程”来回答。

先明确这三个概念的区别

缓存穿透,指的是请求的数据原本就不存在。例如,有人不断查询 id 为负数的商品,缓存中自然没有,数据库里也不存在。每次请求都直接打到数据库,这才是真正的穿透。

缓存击穿,是指某个热点 key 突然过期失效。例如首页推荐配置、爆款商品库存、秒杀活动信息等,平时都由缓存承担压力,但一旦 key 过期,大量请求瞬间同时涌向数据库。

缓存雪崩,是指一批 key 在同一时间集体过期,或者 Redis 集群本身短暂不可用。这不再是单个热点 key 的问题,而是缓存层整体失守。

面试时先把这三个概念区分清楚,后续才有深入讨论的空间。否则,如果你把击穿说成穿透,面试官基本会认为你只是机械背题。

缓存穿透:不要只提布隆过滤器

缓存穿透的第一层防护其实是参数校验。

如果业务要求商品 id 必须是正整数,那么负数、超长字符串、明显不合法的枚举值,应在入口处直接拦截。不要让这类请求进入缓存层,更要避免它们打到数据库。

第二层才是缓存空值。当数据库查询不到结果时,将空结果也写入缓存,并设置较短的过期时间,例如几十秒到几分钟。这样同一个不存在的 key 就不会反复访问数据库。

布隆过滤器更适合更重的场景:数据集合相对稳定、非法 key 数量庞大、数据库压力已经明显升高。它的特点是可能误判某个 key 存在,但不会把真实存在的数据误判为不存在。因此,它适合作为前置过滤,但不能完全依赖它作为最终判断依据。

一个比较稳妥的回答可以这样组织:

  • 首先进行入参校验,拦截明显非法的请求;
  • 当数据库查询为空时,缓存空值,避免同一个不存在的 key 反复穿透数据库;
  • 如果非法 key 规模较大,再将合法 id 集合放入布隆过滤器进行前置判断。

如果面试官继续追问“缓存空值是否会污染 Redis”,你可以回答:空值的 TTL 要设置得短、value 要尽量小,并且只针对高频不存在的 key 进行缓存,而不是对所有未命中都无脑写入。

缓存击穿:互斥锁并非简单执行 SETNX

热点 key 过期时,最糟糕的情况是大量线程同时查询数据库并同时回写缓存。

常见做法是使用互斥锁:只有成功获取锁的线程去查询数据库并重建缓存,其他线程则等待一段时间后重试,或者直接返回旧数据。

这里有一个关键点,不要使用“SETNX后跟EXPIRE”这种组合。这两个命令是分开的,并非原子操作,如果中间进程崩溃,可能导致死锁。在Redis中,更推荐使用一条SET命令,同时带上NX和EX参数,将“仅当key不存在时设置”和“过期时间”合并为一个原子操作。解锁时还需要校验value,通常使用Lua脚本来确保只删除自己的锁。

如果业务允许短暂使用旧数据,那么逻辑过期方案会更优雅:缓存中不仅存放数据,还附带一个逻辑过期时间。当请求发现逻辑过期时,不会立即让所有线程去查询数据库,而是由一个线程异步刷新缓存,其他线程则继续使用旧数据。

这种方案在首页配置、排行榜、推荐位等场景中非常常见。用户看到几十秒前的数据影响不大,但数据库被击穿就是真正的事故。

我会这样回答:

  • 对于强一致性要求高的热点 key,使用互斥锁重建缓存;
  • 对于读多写少、允许短暂旧值的场景,采用逻辑过期加异步刷新;
  • 锁必须设置过期时间,value 要唯一,删除锁时需校验 owner。

这几句话比单纯背诵“互斥锁”更有深度。

缓存雪崩:随机 TTL 只是基础手段

缓存雪崩的典型原因主要有两个。

一个是大量 key 同时过期。例如,批量导入缓存时,全部设置成30分钟,半小时后同时失效。这种情况可以通过随机 TTL 来缓解:在基础过期时间上增加一段随机抖动,使 key 的失效时间分散开。

另一个是缓存服务本身不可用。这已经不是随机 TTL 能够应对的了。需要看系统是否具备本地缓存、限流、降级、熔断等机制,以及核心数据能否提前预热。

面试时可以从多个层次来阐述:

  • 过期时间层:TTL 添加随机值,避免同一批 key 同时失效。
  • 热点数据层:在上线或活动开始前进行预热,不等待用户请求触发重建。
  • 系统保护层:本地缓存兜底、接口限流、数据库保护、非核心功能降级。

如果你的项目只是普通后台系统,没有高并发活动,也不必硬编秒杀场景。可以说:“我没做过秒杀,但在后台字典、配置缓存中会使用随机 TTL,避免定时任务批量刷新导致同时过期。”这样的回答反而更真实可信。

面试官真正关注的是,并非名词本身

这道题最后通常会回归到项目实战。

如果你的简历中提到了 Redis,请提前想清楚以下几个问题:

  • 哪些数据使用了缓存?为什么这些数据适合缓存?
  • key 如何设计?是否包含前缀、版本号、业务 id?
  • TTL 设置多长时间?是固定值还是带有随机值?
  • 数据更新时,是删除缓存、更新缓存,还是采用延迟双删策略?
  • 如果缓存未命中,数据库能否承受压力?是否有限流措施?

这比背十页 Redis 面试题更关键。

我自己准备这类问题时,会将简历中的项目描述输入到面灵 AI,让它以面试官的口吻连续追问五轮。第一轮通常还能回答,但到第三轮就能发现哪些地方自己还没有真正想清楚。

来源:https://segmentfault.com/a/1190000048073421

相关热点

继续查看同栏目近期热点。

延伸阅读

补充最近整理过的热点入口。