面灵AI→

SHEIN 二面:Redis 库存扣减与缓存一致性

轮次
二面
时间
2026-09
来源
牛客网

《面试题目》

  1. 能挑之前的一个项目来展开介绍一下吗?你觉得当时最大的挑战是什么?或者说解决的印象比较深刻、比较难的一个事是什么?
  2. 项目中用 Redis 设计一个类似于具有事务性的原子化操作,有考虑过数据库和缓存的数据怎么一致吗?
  3. 如果下单超时失败了,这时候可能只扣了 Redis 里面的库存,实际上最终数据库里的库存没有扣减,这种情况怎么解决?
  4. Lua 脚本里面有什么样的逻辑?
  5. 真正购买成功时用户要经过订单系统、促销系统做扣减,这些流程不能在 Redis Lua 脚本里面去写,那么实际的流程是怎么样的?
  6. Redis 有稳定性的一些隐患吗?怎么解决?
  7. 介绍下 RAG 项目。
  8. 有考虑过自己想找一份什么样的工作、做哪一方面吗?有规划过吗?
  9. 除了刚才讲到的 RAG 系统,日常会用 AI 做些什么样的事?

《参考解析》

Redis 原子扣减与缓存一致性:先说清职责——Redis 只做”预占/预扣”,数据库才是权威库存。写路径是:Redis 用 Lua 原子地判断并扣减预占库存 → 下单成功记录订单 → 通过事务消息或本地消息表把扣减事件可靠投递到 MQ → 消费端在数据库里 UPDATE stock = stock - n WHERE stock >= n(靠行锁和条件保证不超卖),幂等键用订单号去重。缓存一致性上,纯 cache-aside 的”先更新 DB 再删缓存”已经够用,需要更稳就加延迟双删或在 binlog 订阅(Canal)驱动的删除;还有一种是把缓存当作唯一读源、写只写 DB 并失效缓存。无论哪种,最后都要有对账任务:定期比对 Redis 预占总量、DB 扣减总量和订单量,差异单人工或自动补偿,这才是能扛住事故的答案。

下单超时只扣了 Redis 没扣 DB 怎么办:核心是”预占要有租约、要有补偿”。做法:预占时记录一条流水(订单号、sku、数量、状态=预占中)并给 Redis 预占键设 TTL;支付成功后把状态置为已确认,再触发 DB 扣减;超时未支付/流程异常时,靠 Redis 键过期事件或延迟消息(RocketMQ 延迟消息、时间轮)触发回滚,把预占数量加回去,并把流水置为已释放。所有动作都带订单号做幂等(回滚只能执行一次),消费端失败就重试到成功或进死信,最后用定时对账兜底修复”钱货不一致”的单据。

Lua 脚本里写什么:脚本承担的是”读—判断—写”必须原子完成的那一小段:取库存 key、判断是否 >= 购买数量、DECRBY 扣减、记录预占(写一个带订单号的占位 key 或 Sorted Set)、返回结果码(成功/库存不足/重复提交)。要强调边界:Lua 里不能做网络调用和耗时操作(会阻塞 Redis 单线程),入参只用 KEYS/ARGV 传;Redis Cluster 下所有操作的 key 必须在同一个 slot,通常用 hash tag 把 {sku:123}:stock 和 {sku:123}:hold 绑到同一分片;脚本要控制在几十行内并用 EVALSHA 缓存减少传输。

完整下单链路为什么不能全塞进 Lua:订单、促销、优惠、风控、积分是不同服务,各自有自己的库和事务语义,塞进 Redis 单线程脚本既写不了跨系统事务,也会把 Redis 拖死。真实流程是”预占 + 异步编排”:接入层调订单服务下单 → 在 Redis Lua 里做库存预占(秒杀场景的第一道闸)→ 发消息,库存服务落库扣减、促销服务核销、订单服务更新状态,各自幂等 → 任一步失败就把整单标记失败并发补偿消息回滚预占 → 全部成功才让订单进入待支付/已支付。中间需要状态机(预占中/已确认/已释放)和超时兜底,讲清这些比讲”用了 Redis”重要得多。

Redis 的稳定性隐患与解法:可以按维度答:① 持久化——AOF 默认 everysec 最多丢 1 秒数据,RDB 丢得更多,核心数据不能只信 Redis;② 复制与故障切换——主从异步复制,主挂时未同步的写会丢,锁也可能丢,重要场景上哨兵/Cluster 并用数据库唯一约束兜底;③ 集群——slot 迁移期间的 MOVED/ASK、大 key 迁移阻塞、跨 slot 事务不可用;④ 容量与淘汰——设 maxmemory 与 noeviction/allkeys-lru 策略,避免内存打满后被 OOM 杀掉;⑤ 缓存三兄弟——穿透(布隆过滤器 + 空值缓存)、击穿(互斥重建或逻辑过期)、雪崩(过期时间加随机、多级缓存、集群);⑥ 慢查询与大 key——禁用 KEYS,用 SCAN,大 key 拆分,删除走 UNLINK 或分批;⑦ 监控——命中率、连接数、阻塞命令、主从延迟、慢日志。

RAG 项目与个人规划怎么答:15 分钟的二面时间有限,RAG 只要一支线讲清”解决什么业务问题—链路怎么搭(切分、向量召回、rerank、拼上下文、引用)—线上指标与 badcase 怎么迭代”,把细节留给面试官追问。规划类问题要贴着岗位答:想做后端/交易或基础架构方向,理由是可迁移的技术深度与业务复杂度,而不是空泛的”想成长”。被问日常怎么用 AI,讲真实场景(写脚本、读陌生代码、辅助排查、生成测试)加一句边界(关键逻辑自己 review)。