小药药武汉Java后端一面面经
《面试题目》
- 为什么 MySQL 使用 B+ 树作为索引结构?
- 什么是索引回表?
- 多表联查有哪些实现方式?(内连接、左外连接、右外连接的区别)
- 【场景题】如何关联查询”用户日志表”和”用户详情表”,获取某天有操作记录的用户及其详情?
- 【性能优化】连接查询时,应该用小表驱动大表还是大表驱动小表?为什么?面试官追问:当 user_info(3300万)LEFT JOIN user_log(1100条)时,驱动表选择是否正确?关联字段是否有索引?
- 微服务调用链中,如果出现”部分成功、部分失败”的情况,如何保证数据一致性?除了同步补偿机制,还了解哪些分布式事务方案?
- 线上服务器 CPU 飙高,如何排查定位问题?
- 【场景题】Controller 中有两个无依赖关系的耗时方法(各5秒),顺序执行需10秒,如何优化?使用线程池并行后,主线程如何同步等待子线程结果?
- 【场景题】200万条数据导出 Excel,如何进行性能优化?先分析瓶颈在哪里,分批查询用游标分页还是偏移分页,多线程如何分工?
- 平时如何使用 AI 工具辅助编码?具体流程和方法论是什么?
- AI 的上下文窗口有限,如何解决长期记忆/经验沉淀的问题?
- 用过哪些 AI 编程工具?CC Switch 是做什么的?
- AI 生成的代码,如何验证其正确性?AI 能否自己编写单元测试并自我修正?
- 【场景题】如果给你5天时间紧急开发一个独立系统(如积分商城),会如何利用 AI 加速?
- 接到一个新需求后,开发启动流程是怎样的?是先构思架构再动手,还是边写边改?
《参考解析》
-
MySQL索引与联表:InnoDB用B+树而非哈希表是因为支持范围查询和排序,且树高低(千万级数据通常3-4层)保证磁盘IO次数可控;哈希索引虽然等值查询O(1)但不支持范围扫描。索引回表指通过辅助索引找到主键值后,还需回到聚簇索引查完整行数据,因此覆盖索引(select的字段都在索引里)能避免回表。大表驱动小表 vs 小表驱动大表:MySQL的嵌套循环连接应始终用小表(结果集小的一方)作为驱动表,减少内层循环次数;本例中user_log只有1100条应作为驱动表去关联user_info的3300万数据,同时确保关联字段有索引,否则每次内层查询都是全表扫描。
-
分布式事务一致性:微服务部分成功部分失败的场景,常见方案有:TCC(Try-Confirm-Cancel,业务侵入性强但性能好)、Saga模式(长事务拆分为多个本地事务+补偿动作)、基于消息队列的最终一致性(本地消息表/事务消息保证发送与业务操作原子性)、以及2PC/3PC(强一致但性能差、协调者单点风险)。互联网高并发场景通常优先选最终一致性方案。
-
CPU飙高排查:标准流程是
top定位高CPU的进程PID,再用top -Hp <pid>找到具体线程TID,将TID转16进制后在jstack <pid>输出中grep对应的nid,定位到具体线程栈,常见原因是死循环、频繁GC(配合jstat -gcutil确认)、正则回溯或锁竞争激烈。 -
并行优化耗时方法:两个无依赖的5秒方法可以用线程池(如
CompletableFuture.supplyAsync配合自定义线程池)并行提交,主线程通过CompletableFuture.allOf(...).join()或get()阻塞等待两个子任务结果都返回后再继续,避免共用默认ForkJoinPool导致和其他任务抢占资源;若直接返回不等待,会导致响应提前返回但子任务结果丢失或后续依赖的数据未准备好。 -
大数据量导出优化:200万条数据导出前需先分析瓶颈——是查询慢(缺索引/大偏移量offset分页导致越翻越慢)还是写Excel慢(POI一次性加载OOM)。优化思路:查询用游标分页(
where id > 上次最大id limit N)代替limit offset,N,避免深分页扫描问题;写文件用SXSSFWorkbook(POI流式写入,固定内存窗口)避免OOM;可将查询与写入分批次、多线程并行处理不同数据段,最后合并或直接流式写入同一个Sheet。