Java面试连环炮:谢飞机被面试官虐哭的三轮拷问!

39 阅读4分钟

面试现场:谢飞机大战互联网大厂面试官

第一轮:Java 基础与集合类

面试官:请说说 HashMap 的底层结构? 谢飞机:嗯……是数组加链表,JDK8 后链表太长会转成红黑树! 面试官:很好。那为什么初始容量是16,负载因子是0.75? 谢飞机:因为……16 是 2 的幂,方便位运算!0.75 是为了平衡空间和时间,再高就容易冲突! 面试官:不错。那 ArrayList 和 LinkedList 有什么区别? 谢飞机:ArrayList 是数组,查询快;LinkedList 是双向链表,增删快! 面试官:可以,基础还行。


第二轮:并发编程与 JVM

面试官:线程池的核心参数有哪些? 谢飞机:corePoolSize、maxPoolSize、workQueue、threadFactory、handler! 面试官:如果队列满了且线程数达到最大呢? 谢飞机:就执行拒绝策略,比如 AbortPolicy 直接抛异常! 面试官:synchronized 和 ReentrantLock 区别? 谢飞机:synchronized 是关键字,自动释放锁;ReentrantLock 是类,要手动 unlock,还能尝试获取锁! 面试官:那 volatile 能保证原子性吗? 谢飞机:能啊!它能让变量立即刷新到主内存! 面试官:❌不能!volatile 只保证可见性和有序性,不保证原子性!


第三轮:分布式与中间件

面试官:Redis 持久化机制有哪几种? 谢飞机:RDB 快照和 AOF 日志追加! 面试官:MySQL 的索引失效场景有哪些? 谢飞机:like 左模糊、类型转换、函数操作字段…… 面试官:SpringBoot 自动装配原理? 谢飞机:靠 @SpringBootApplication 注解,里面有个 @EnableAutoConfiguration,会加载 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 里面的配置类! 面试官:最后一个问题:DDD 的核心概念是什么? 谢飞机:就是领域驱动设计嘛,用聚合根、实体、值对象……呃……然后微服务按业务划分! 面试官:回答得比较混乱。这样吧,我们这边先记录一下,你回去等通知吧。


答案详解

1. HashMap 底层结构

HashMap 在 JDK8 之前采用数组 + 链表,解决哈希冲突使用链地址法。当链表长度超过 8 且数组长度 ≥ 64 时,链表转为红黑树,提升查找效率至 O(logN)。扩容机制为 2 倍扩容,通过扰动函数减少哈希碰撞。

初始容量 16 是为了保证散列均匀,负载因子 0.75 是性能与空间的权衡点——过高导致频繁碰撞,过低浪费内存。

2. ArrayList vs LinkedList

  • ArrayList:基于动态数组,支持随机访问(O(1)),扩容机制为 1.5 倍增长,但插入删除需移动元素(O(N))。
  • LinkedList:双向链表实现,插入删除快(O(1)),但遍历慢(O(N)),且每个节点额外存储前后指针,内存开销大。

3. 线程池核心参数

  • corePoolSize:核心线程数,即使空闲也不销毁(除非设置 allowCoreThreadTimeOut)
  • maxPoolSize:最大线程数
  • workQueue:阻塞队列,如 LinkedBlockingQueue、ArrayBlockingQueue
  • threadFactory:创建线程的工厂
  • handler:拒绝策略,常见有 AbortPolicy、CallerRunsPolicy 等

执行流程:提交任务 → 核心线程是否满?否则创建 → 否则进队列 → 队列满?→ 创建非核心线程 → 达到最大线程数?→ 执行拒绝策略。

4. volatile 不保证原子性

volatile 仅确保:

  • 可见性:一个线程修改后立即写回主内存,其他线程能读到最新值
  • 有序性:禁止指令重排序(通过内存屏障) 但像 i++ 这种复合操作(读-改-写)仍可能出错,需用 synchronized 或 AtomicInteger。

5. Redis 持久化

  • RDB:定时快照,恢复速度快,适合备份,但可能丢失最后一次快照后的数据。
  • AOF:记录每条写命令,数据更安全,可通过 rewrite 优化日志,但文件体积大,恢复慢。 生产环境建议两者结合使用。

6. MySQL 索引失效场景

  • 使用 LIKE '%xx' 左模糊
  • 对字段进行函数操作:WHERE YEAR(create_time) = 2024
  • 类型隐式转换:字符串字段传数字
  • OR 条件中部分字段无索引
  • 最左前缀原则破坏:联合索引 (a,b,c) 查询条件未包含 a

7. SpringBoot 自动装配

启动类上的 @SpringBootApplication 包含 @EnableAutoConfiguration,该注解通过 @Import(AutoConfigurationImportSelector.class) 加载 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 文件中的自动配置类。这些配置类使用 @ConditionalOnXXX 注解按条件加载 Bean,实现“约定优于配置”。

8. DDD 核心概念

  • 领域(Domain):业务核心逻辑
  • 实体(Entity):有唯一标识的对象
  • 值对象(Value Object):无 ID,只关注属性值
  • 聚合根(Aggregate Root):聚合的入口,保证一致性边界
  • 仓储(Repository):提供聚合的数据访问抽象
  • 领域事件(Domain Event):表示领域中发生的事 DDD 强调以业务为中心拆分微服务,避免贫血模型,提升系统可维护性。