小米 Java 软件开发工程师二面面经
1. 你们系统的 QPS 是多少?如果流量突然翻了 10 倍,你的架构哪些地方会先垮掉?
- 回答:这是一个考查系统瓶颈分析能力的开放题。 分析点:首先是数据库(连接数爆满、IOPS 达到上限);其次是缓存热点(单 Key 突发流量导致 Redis 分片压力过大);然后是带宽与线程池(RPC 调用耗时增加导致 Web 容器线程枯竭)。对策:需要提到限流、熔断、数据库读写分离/分库分表、消息队列削峰填谷以及热点缓存探测机制。
2. 既然提到分库分表,分表键(Sharding Key)如何选择?如何处理跨库查询?
- 回答: 选择:通常选查询最频繁的维度(如 user_id),保证同一用户数据落入同库。跨库查询: 映射表法:在 Redis 或另一张表记录非唯一键与分表键的关系。基因法:将部分 user_id 的哈希特征植入其他业务字段中。异构索引:利用 ES 同步全量数据,复杂查询走 ES。
3. 在分布式事务中,2PC 和 TCC 各自的适用场景是什么?为什么大厂很少用 2PC?
- 回答: 2PC:强一致性,但存在同步阻塞、协调者单点故障和脑裂问题,性能极差。TCC:最终一致性,性能好,但业务侵入性极高(需实现 Try、Confirm、Cancel)。大厂实践:多使用基于消息队列的最终一致性方案,通过本地消息表或事务消息确保操作的原子性。
4. 线上环境出现 CPU Load 很高但 CPU 利用率却不高,可能是什么原因?
- 回答:Load 代表等待运行的任务队列长度。 常见原因:I/O 等待(磁盘坏道、网络阻塞);上下文切换频繁(线程开得太多,竞争激烈);内存换页(Swapping)(物理内存不足)。定位:使用 vmstat 查看 b 列(阻塞进程)和 wa 列(IO 等待时间)。
5. 你们如何保证 Redis 与 MySQL 的数据一致性?为什么不建议用“双删”?
- 回答: 主流方案:先更新数据库,再删除缓存。配合 Canal 监听 Binlog 异步重试删除,确保最终一致性。不推荐双删的原因:第二次删除的时间点(延迟时间)极难掌控,在读高并发下依然可能导致脏数据,且逻辑复杂、性能损耗大。
6. 如果 Redis 发生了大 Key 或者是热 Key,你是如何监控并处理的?
- 回答: 监控:使用 redis-cli --bigkeys 定期扫描;或者在代理层(如 Codis)进行统计。处理:大 Key 进行拆分或使用 unlink 异步删除;热 Key 使用**本地多级缓存(Caffeine)**或者在 Redis 侧做副本分片冗余。
7. 谈谈 Zookeeper 的 ZAB 协议,它与 Raft 协议最大的区别在哪里?
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
Java面试圣经 文章被收录于专栏
Java面试圣经,带你练透java圣经
查看6道真题和解析