面灵AI→

北京小厂 Java 一面:线程池、联合索引与 Spring 事务失效

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

《面试题目》

  1. 自我介绍。
  2. 介绍一下你的一个项目(agent 代码平台),说一下你印象深刻的问题和解决方法。
  3. 创建线程的方法有哪些?
  4. 自定义线程池了解吗?
  5. 能不能介绍一下线程池的参数?
  6. 一个任务被提交给线程池的流程是怎样的?拒绝策略有哪些?
  7. 介绍一下 JVM 的内存区域。
  8. 堆被细分为哪些区域?
  9. 垃圾回收算法了解吗?
  10. MySQL 的索引有哪些?
  11. 联合索引 a,b,c,d 四个字段,条件为 a=1,b=2,d>6,c=5,使用了联合索引的哪些字段?查询顺序影响索引结果吗?
  12. Spring Boot 自动装配原理是什么?
  13. Redis 的持久化机制,两种方法各有什么优缺点?
  14. Spring 怎么使用事务?
  15. Spring 事务什么时候失效?
  16. 项目启动的时候要做一些特殊的逻辑处理,比如扫描某张表,怎么去做?
  17. @PostConstruct 有什么用?知道吗,用过吗?
  18. 反问:面试改进建议、业务范围。

《参考解析》

线程池七参数与提交流程:核心线程数、最大线程数、空闲存活时间、时间单位、工作队列、线程工厂、拒绝策略。任务提交后先看核心线程是否满,未满则新建核心线程;满了进队列;队列满了再扩到最大线程数;仍满则触发拒绝策略——AbortPolicy 抛异常、CallerRunsPolicy 由提交线程执行、DiscardPolicy 静默丢弃、DiscardOldestPolicy 丢队首。回答时补一句「队列长度和最大线程数要一起看,无界队列会让 maximumPoolSize 形同虚设」会更扎实。

联合索引 a,b,c,d 那题:条件是 a=1、b=2、c=5 三个等值加 d>6 一个范围,最左前缀可以一路用到 c,d 用索引下推或范围扫描过滤,四列都能参与;SQL 里条件的书写顺序由优化器重排,不影响执行计划。要记住的规则是「范围条件之后的列无法继续用于索引定位」,这里 d>6 恰好是最后一列,所以不受影响。

JVM 内存与堆划分:线程私有的是程序计数器、虚拟机栈、本地方法栈;线程共享的是堆和方法区(JDK 8 之后是元空间,位于本地内存)。堆按分代分为新生代(Eden 与两块 Survivor)和老年代,默认比例 8:1:1,比例可调的目的是让存活对象尽快进入老年代,减少复制开销。

Redis 持久化:RDB 是某一时刻的全量快照,文件紧凑、恢复快,但两次快照之间的数据会丢,fork 时也可能阻塞;AOF 追加写命令,按 everysec 配置最多丢一秒,文件大、恢复慢,支持重写压缩。生产上常见是两者同开,用 RDB 做冷备、AOF 保证丢数据窗口。

Spring 事务失效的典型场景:同类内部方法直接调用(绕过代理)、方法不是 public、异常被 catch 掉或抛的是受检异常而没配 rollbackFor、事务方法被 final 修饰、多线程里执行、Bean 没有被 Spring 管理、数据库引擎不支持事务。用 @Transactional 时最好显式写明 rollbackFor 和传播行为。

启动时做初始化逻辑的几种写法:@PostConstruct(依赖注入完成后执行一次,适合本 Bean 的初始化)、实现 InitializingBean 的 afterPropertiesSet、实现 ApplicationRunner 或 CommandLineRunner(容器启动完成后执行,能拿到启动参数)、监听 ApplicationReadyEvent。扫表这类重活更适合放在 Runner 里,避免拖慢容器启动。