面灵AI

Momenta 后端面试:预约超卖、缓存一致性与长事务

时间
2026-09
来源
牛客网

《面试题目》

  1. 能否介绍自己和参与较深的项目,说明负责的部分?
  2. 热门充电站同一时段收到大量预约,怎样避免资源超卖?
  3. 怎样设计支持多个服务协同的灰度发布系统?
  4. Cache Aside 为什么不能天然提供数据库与缓存的强一致?
  5. 先删缓存再更新数据库,会出现什么并发问题?
  6. 用数据库变更日志驱动缓存失效时,怎样处理事件乱序?
  7. InnoDB 的 MVCC 怎样工作?
  8. Undo Log、Read View 和版本链分别负责什么?
  9. 可重复读下的主键查询命中索引,为什么仍可能很慢?
  10. 长事务会给 MySQL 带来哪些影响?
  11. 在线修改大表结构,怎样控制对业务的阻塞?
  12. Redis Lua 脚本具有原子执行特性,为什么仍可能影响可用性?
  13. Redis Cluster 扩容迁移槽位时,客户端会遇到哪些变化?
  14. 怎样设计能处理机器时钟回拨的分布式限流器?

《参考解析》

容量判断必须和扣减放在一起

可以把“剩余容量足够”作为数据库更新条件,并检查受影响的行数;预约记录、容量扣减与同一次请求的去重需要形成一致的业务结果。重复请求应返回同一预约结果,取消操作也不能重复释放容量。Redis 前置拦截可以减轻压力,但不能代替最终数据层的容量约束。

缓存不一致要画出两个请求的时间线

先删除缓存后,另一个请求可能读到数据库旧值并回填;随后数据库更新完成,缓存却留下旧值。先更新数据库再删缓存也存在删除失败和并发旧值回填的窗口。可以结合可重试失效事件、版本检查与过期机制缩小影响,但应明确业务允许多长时间的不一致。

只执行删除时,旧事件通常只是多删一次;如果事件处理还包含重新加载或写入,乱序就可能把旧值覆盖到新值上。回答时先说明消费者究竟做了什么,再决定版本号放在哪里。

长事务会让历史版本留得更久

一致性读通过可见性规则选择记录版本;需要保留旧快照时,相关历史版本不能随意清理。长事务也可能长时间占用锁,所以检查事务耗时和检查单条慢 SQL 不是一回事。把远程调用、文件处理或人工等待放进数据库事务,会拉长这段时间。

Lua 的原子执行不等于跨系统事务

脚本执行期间不会和其他命令交错,因此应控制循环次数和数据规模,避免让一个请求长时间占住实例。脚本中的 Redis 更新即使完成,也不能让另一个数据库的写入自动一起提交。原子执行也不表示脚本运行出错时,之前的写入一定回滚。

限流先定义时钟与状态来源

单机计算时间间隔可以使用单调时钟;多机共享额度时,不能假定各机器的单调时钟值可直接比较。需要集中维护限流状态,或明确时钟误差与分片额度的容忍范围。检测到时间回退时,不应让补充令牌的差值变成负数或额外发放额度,同时记录异常以便定位。