面灵AI

携程 Java 秋招一面:缓存延迟、订单耗时与系统可靠性

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

《面试题目》

  1. 项目中怎样使用 Redis,如何保证缓存与数据库一致?
  2. Canal 同步的 500 毫秒延迟来自哪里,如何优化?
  3. 需要缓存的数据特别大时怎么办?
  4. 创建订单耗时很长时,如何定位和处理?
  5. 下游接口无法降级时怎么办?
  6. MySQL 有哪些隔离级别,哪些场景会让索引无法有效使用?
  7. synchronized 和 ReentrantLock 分别做什么,有什么区别?
  8. synchronized 能锁 String 和 Long 对象吗?
  9. 类加载有哪些阶段?
  10. 如何计算一个对象的大小?
  11. 如何创建类的实例?
  12. 如何设计一个可靠的系统?
  13. 项目里如何使用熔断,何时触发,何时恢复?

《参考解析》

500 毫秒先拆成几段

从数据库提交,到变更记录被读取、排队、消费,再到缓存写入,每段都可能引入等待。用同一条记录的时间点计算各段延迟,再检查拉取批次、队列积压、消费速度与网络耗时。若系统时钟不同步,跨机器时间差也可能失真。没有测量前,不能把这 500 毫秒直接归因于 Canal。

订单慢不等于全改异步

先区分数据库锁等待、慢 SQL、外部接口和应用排队。订单是否成立必须依赖的步骤,应有清晰的成功条件;通知等允许延后的工作可以异步执行。关键下游不可用且没有合法降级结果时,可以限流或明确失败,不能返回虚假的下单成功。重试仍应复用同一个业务请求标识。

锁对象要稳定且归自己管理

synchronized 的监视器对象可以是 String 或 Long,但字符串常量可能被其他代码共享,装箱对象也可能来自缓存;给变量重新赋值又可能换掉锁对象。通常用私有且不再替换的锁对象,确保竞争线程锁住的是同一个实例。

熔断恢复需要少量探测

熔断条件应基于时间窗口中的请求量、失败比例或慢请求情况,避免一两次失败就切断服务。打开后等待一定时间,再放行少量请求判断依赖是否恢复;探测失败继续保持熔断。限流、超时和并发隔离也要一起考虑,防止大量等待把调用方拖垮。