面试现场:谢飞机大战互联网大厂面试官
第一轮: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 强调以业务为中心拆分微服务,避免贫血模型,提升系统可维护性。