九方智投控股 后端 一面面经
- 轮次
- 一面
- 时间
- 2026-09
- 来源
- 牛客网
《面试题目》
- 讲讲你的项目。
- 简单介绍一下这几个项目当中哪一个比较有意思。
- 你是怎么处理时序竞争的?
- 你说你做过数据统计,那你们这个性能大概是什么样的?
- 我主要关心你的性能是什么,你们有没有什么性能指标,比如一个页面加载需要多久之类的?
- 你做完优化性能提升了多少?
- 你有没有关注过后续的性能指标,哪一段耗时最多之类的?
- 既然你们找到了性能基准,肯定有后续的一些优化的点,你有做后续的性能优化吗?
- 讲一下缓存穿透、缓存击穿、缓存雪崩。
- 问一个场景:Redis 里做缓存,接口去更新了数据库,可能会出现数据库更新了但缓存没更新、导致读到旧数据的情况,你有没有什么好的解决方案?
- 如果先更新数据库、再删缓存,理论上删完缓存后下次读会从库里拿新数据回填,不应该有旧数据。但现实中会出问题,为啥会出现问题(并发时序错乱)?
《参考解析》
- 怎么挑”有意思”的项目:这题考的是你能不能判断技术含量,不是让你报流水账。选一个自己真正做过决策的项目,用”业务问题 → 难点在哪 → 我做的方案 → 取舍 → 可验证结果”讲完,控制在两分钟;其余项目一句话带过。别挑听起来最炫但自己只写了两行调用代码的那个,面试官一定会顺着往下钻。
- 时序竞争的处理:先定位竞争发生在哪一层——同一进程内的共享状态用锁、原子操作或串行化队列;跨进程/跨实例的用分布式锁、数据库唯一约束或乐观锁(版本号、CAS);消息乱序则靠幂等键加去重表。工程上优先考虑”不共享”:把状态收敛到单点、按业务键做分片,往往比加一把大锁更划算。回答时最好带上真实场景里选这种方案的原因和它带来的代价(延迟、复杂度、可用性)。
- 性能指标怎么答:指标要能落到口径上,否则等于没说。前端体验看首屏/页面加载时间(P50 与 P95 都要)、接口看 QPS 与 RT 分位、后端看慢查询数量和 CPU/内存水位;每个数字都要说清是压测值还是线上值、样本范围多大、和什么基准比。优化前后给对比,并说明优化手段(索引、缓存、批量、异步、连接池、SQL 改写)各自贡献了多少——只说”提升了很多”会被继续追着问。
- 缓存穿透、击穿、雪崩:穿透是查一个数据库里也不存在的 key,每次请求都穿到库层——用空值缓存加短过期、布隆过滤器或参数校验挡住;击穿是某个热点 key 过期瞬间大量并发打到库上——用互斥锁/单飞重建、热点 key 逻辑过期或永不过期加后台刷新;雪崩是大批 key 同时失效或缓存整体不可用——给过期时间加随机抖动、多级缓存、集群高可用,并在缓存层加限流和降级兜底。三者都别忘了最后一道:数据库侧的限流与熔断,缓存方案再全也不能假设它永远命中。
- 先更新库再删缓存为什么还会读到旧数据:典型是”读请求比写请求慢”的并发交错——读请求没命中缓存,去库里读到旧值,此时写请求完成了更新并删掉缓存,读请求才把旧值写回缓存,脏数据就留在缓存里直到下次过期。此外还有几种常见来源:删除缓存失败(网络抖动/实例挂掉)没有重试补偿;主从延迟导致删缓存后从库还是旧值;缓存与数据库操作不在同一事务里,中途异常导致只做了一半。对应手段是延迟双删、把删除操作投进消息队列并重试(binlog 订阅做补偿)、给缓存设较短过期时间兜底,关键数据直接从库读或加版本号校验。更彻底的做法是让缓存的写只走一个入口并串行化,或者干脆用”更新时删缓存 + 读时单飞重建”避免旧值回填。