面试现场:水货程序员谢飞机大战Java面试官

4 阅读4分钟

面试现场:水货程序员谢飞机大战Java面试官

第一轮:基础不牢,地动山摇

面试官:谢飞机同学,请介绍一下HashMap的底层实现原理。

谢飞机:HashMap嘛,就是数组加链表!哦对,JDK8以后还有红黑树!

面试官:不错,那什么时候会转换成红黑树呢?

谢飞机:嗯...好像是链表长度超过8的时候?

面试官:很好!那为什么选择8这个阈值呢?

谢飞机:因为...因为8是个好数字?(挠头)

面试官:(无奈)好吧...那说说ArrayList和LinkedList的区别?

谢飞机:ArrayList查询快,LinkedList增删快!

面试官:为什么?

谢飞机:因为...一个用数组,一个用链表!(得意)

面试官:嗯,基础概念还行。

第二轮:并发编程,一脸懵圈

面试官:说说线程池的核心参数有哪些?

谢飞机:核心线程数、最大线程数...还有...还有那个队列大小!

面试官:还有两个参数呢?

谢飞机:啊?还有吗?我以为就这三个...(慌张)

面试官:那说说synchronized和ReentrantLock的区别?

谢飞机:synchronized是关键字,ReentrantLock是类!

面试官:还有什么区别?

谢飞机:ReentrantLock...可以中断?还能设置超时?(不确定的语气)

面试官:Volatile关键字的作用是什么?

谢飞机:保证可见性!禁止指令重排序!(这次回答得很自信)

面试官:不错,这个问题答得挺好。

第三轮:框架源码,彻底露馅

面试官:Spring Bean的生命周期说一下?

谢飞机:实例化、初始化...然后就可以用了!

面试官:具体有哪些步骤?

谢飞机:就是...先new出来,然后调用init方法...(开始胡扯)

面试官:Spring Boot自动配置的原理?

谢飞机:@EnableAutoConfiguration注解!然后...Spring Boot很智能,会自动帮我们配置!(双手一摊)

面试官:Redis缓存穿透怎么解决?

谢飞机:布隆过滤器!还有...缓存空值!

面试官:MySQL索引失效的场景有哪些?

谢飞机:like '%xxx' 会导致失效,还有...函数操作?(声音越来越小)

面试官:好的,谢飞机同学,今天面试就到这里。你先回去等通知吧。

谢飞机:面试官,我能问一下我表现怎么样吗?

面试官:(微笑)你回去等通知就好...


技术答案详解

HashMap底层原理

HashMap在JDK8中的底层实现是数组+链表+红黑树。当链表长度达到8且数组长度>=64时,链表会转换为红黑树,以降低查找时间复杂度从O(n)到O(logn)。选择阈值8是因为泊松分布表明,在随机hashCodes的情况下,链表长度达到8的概率非常低(约0.00000006),所以这是一个合理的平衡点。

ArrayList vs LinkedList

  • ArrayList:基于动态数组实现,支持随机访问(O(1)),但在中间插入/删除元素需要移动后续元素(O(n))
  • LinkedList:基于双向链表实现,插入/删除操作只需修改指针(O(1)),但随机访问需要遍历(O(n))

线程池核心参数

线程池有7个核心参数:

  1. corePoolSize:核心线程数
  2. maximumPoolSize:最大线程数
  3. keepAliveTime:非核心线程空闲存活时间
  4. unit:时间单位
  5. workQueue:工作队列
  6. threadFactory:线程工厂
  7. handler:拒绝策略

synchronized vs ReentrantLock

  • synchronized:JVM内置锁,自动释放,不可中断,非公平锁
  • ReentrantLock:API层面的锁,需手动释放,可中断,可设置公平/非公平,支持条件变量

Volatile关键字

Volatile提供两个保证:

  1. 可见性:保证不同线程对变量的操作对其他线程立即可见
  2. 禁止指令重排序:通过内存屏障防止编译器和处理器重排序

Spring Bean生命周期

完整的Bean生命周期包括:

  1. 实例化(Instantiation)
  2. 属性赋值(Populate properties)
  3. Aware接口回调
  4. BeanPostProcessor前置处理
  5. InitializingBean.afterPropertiesSet()和init-method
  6. BeanPostProcessor后置处理
  7. 使用阶段
  8. DisposableBean.destroy()和destroy-method

Spring Boot自动配置原理

通过@EnableAutoConfiguration导入AutoConfigurationImportSelector,该类通过SpringFactoriesLoader加载META-INF/spring.factories中的自动配置类。配合@Conditional系列注解实现条件化配置。

Redis缓存穿透解决方案

  1. 布隆过滤器:在缓存层前增加布隆过滤器,快速判断key是否存在
  2. 缓存空值:对查询结果为空的key也进行缓存,设置较短过期时间
  3. 参数校验:对明显非法的请求参数直接拦截

MySQL索引失效场景

  1. 最左前缀原则:复合索引未使用最左列
  2. LIKE模糊查询:'%xxx'开头的模糊查询
  3. 函数操作:对索引列使用函数或表达式
  4. 类型转换:字符串和数字比较导致隐式转换
  5. OR条件:OR连接的条件中部分字段无索引
  6. NOT条件:使用!=、<>、NOT IN等