面试官:Java线程池核心参数说一下?谢飞机:飞机没油了,得加满!

42 阅读6分钟

面试现场:大厂Java岗技术连环拷问实录

面试官:请坐。我们开始吧。

第一轮:Java基础与多线程

Q1:讲讲HashMap的底层结构?

谢飞机:嗯……HashMap嘛,就是Map的一种实现,它用的是数组加链表——哦不,是数组加红黑树!当链表长度超过8就转成红黑树,提高查找效率。

面试官:不错,那初始容量和加载因子是多少?

谢飞机:默认初始容量是16,加载因子0.75,到12的时候就开始扩容啦!

面试官:还行,理解到位。

Q3:ArrayList和LinkedList的区别?

谢飞机:这个我知道!ArrayList是基于数组的,查询快,增删慢;LinkedList是双向链表,增删快,查询慢!就像飞机起飞要跑道(数组),而直升机可以原地起降(链表)!

面试官:……比喻倒是挺形象。

Q4:volatile关键字的作用?

谢飞机:volatile能让变量立刻同步到主内存,保证可见性,还能禁止指令重排!比如单例模式里就用它防止线程拿到半初始化对象。

面试官:还可以,进入下一轮。

第二轮:JUC与并发编程

Q1:线程池的核心参数有哪些?

谢飞机:有六个!corePoolSize、maximumPoolSize、keepAliveTime、unit、workQueue、threadFactory、handler!我背得可熟了!

面试官:那如果任务很多,线程池怎么处理?

谢飞机:先用核心线程,然后放队列,队列满了再开新线程到最大值,再不行就执行拒绝策略!

面试官:那四种拒绝策略说一下?

谢飞机:AbortPolicy、CallerRunsPolicy……还有……嗯……那个不让进的,叫什么来着?哦对,DiscardPolicy!还有一个是扔最老的,叫DiscardOldestPolicy!

面试官:勉强及格。继续。

Q4:Synchronized和ReentrantLock区别?

谢飞机:synchronized是关键字,JVM层面的,自动释放锁;ReentrantLock是API,手动加锁解锁,还能设置公平锁、尝试获取锁!

面试官:那ReentrantLock底层是怎么实现的?

谢飞机:呃……是基于AQS吧?AbstractQueuedSynchronizer……像排队上厕所,谁拿到钥匙谁进去……

面试官:……下一个问题。

第三轮:微服务与中间件

Q1:Spring Boot自动装配原理?

谢飞机:通过@EnableAutoConfiguration注解,加载META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports里面的配置类,然后根据条件注解@ConditionalOnClass等决定是否生效!

面试官:不错,那starter是怎么工作的?

谢飞机:starter就是一个依赖包,里面包含了自动配置类和默认配置,引入就能用,比如spring-boot-starter-web,一引入就自动配好Tomcat和MVC!

Q3:Dubbo的架构组成?

谢飞机:Provider提供服务,Consumer调用,Registry注册中心,Monitor监控,Container容器启动……调用过程像点外卖,下单(调用)、骑手接单(注册)、送餐(通信)!

面试官:……你这脑回路挺清奇。

Q4:Redis持久化机制?

谢飞机:RDB是快照,AOF是日志追加。RDB恢复快但可能丢数据,AOF更安全但文件大!

面试官:那混合持久化呢?

谢飞机:混合?是不是把RDB和AOF拼在一起?像鸡尾酒一样调一杯?

面试官:……你知道MySQL的索引失效场景吗?

谢飞机:啊?索引还能失效?我以为建了就一直有效啊!难道是……太久没用被系统删了?

面试官:……

面试官:今天就到这里,你的表现……很有特点。回去等通知吧。

谢飞机:好的!我相信飞机会起飞的!


参考答案详解

1. HashMap底层结构

  • 基于数组 + 链表/红黑树实现(JDK8+)
  • 初始容量16,加载因子0.75,阈值12
  • 扩容为原来的2倍
  • hash冲突通过拉链法解决,链表长度≥8且数组长度≥64时转红黑树
  • 线程不安全,多线程环境下使用ConcurrentHashMap

2. ArrayList vs LinkedList

  • ArrayList:动态数组,内存连续,支持随机访问(O(1)),扩容机制为1.5倍增长,增删元素需移动数据(O(n))
  • LinkedList:双向链表,内存非连续,插入删除快(O(1)),查询慢(O(n))
  • 使用场景:频繁查询用ArrayList,频繁增删用LinkedList

3. volatile关键字

  • 保证变量的可见性:一个线程修改后立即写回主内存,其他线程能读到最新值
  • 禁止指令重排序:通过内存屏障实现
  • 不保证原子性:如i++操作仍需synchronized或AtomicInteger
  • 典型应用:双重检查单例模式中的instance字段

4. 线程池核心参数(ThreadPoolExecutor)

  1. corePoolSize:核心线程数,即使空闲也不销毁(除非设置allowCoreThreadTimeOut)
  2. maximumPoolSize:最大线程数
  3. keepAliveTime:非核心线程空闲存活时间
  4. unit:时间单位
  5. workQueue:阻塞队列,如ArrayBlockingQueue、LinkedBlockingQueue
  6. threadFactory:创建线程的工厂
  7. handler:拒绝策略

5. 拒绝策略

  • AbortPolicy:抛出RejectedExecutionException(默认)
  • CallerRunsPolicy:由提交任务的线程执行任务
  • DiscardPolicy:默默丢弃任务
  • DiscardOldestPolicy:丢弃队列中最老的任务,然后重试提交当前任务

6. Synchronized vs ReentrantLock

| 对比项 | synchronized | ReentrantLock | |--------|--------------|---------------| | 实现层面 | JVM内置锁 | JDK API实现 | | 锁释放 | 自动释放 | 必须手动unlock() | | 公平性 | 非公平 | 可设置为公平锁 | | 中断响应 | 不可中断 | 可响应中断(lockInterruptibly) | | 尝试获取 | 不支持 | 支持tryLock() | | 条件等待 | wait()/notify() | Condition配合await()/signal() |

7. Spring Boot自动装配

  • @SpringBootApplication 包含 @EnableAutoConfiguration
  • 加载 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 文件中的自动配置类
  • 通过 @Conditional 系列注解控制是否生效,如:
    • @ConditionalOnClass:类路径存在指定类
    • @ConditionalOnMissingBean:容器中不存在指定Bean
    • @ConditionalOnProperty:配置文件中存在指定属性
  • 自动配置类通常带有 @Configuration 和 @Bean

8. Dubbo架构

  • Provider:暴露服务的服务提供方
  • Consumer:调用远程服务的服务消费方
  • Registry:注册中心(ZooKeeper、Nacos等),服务注册与发现
  • Monitor:监控中心,统计调用次数、耗时等
  • Container:服务运行容器
  • 调用流程:Consumer从Registry获取Provider地址 → 直连调用(RPC)→ 结果返回

9. Redis持久化

  • RDB(快照)
    • 定时生成数据集的时间点快照
    • 文件紧凑,恢复速度快
    • 可能丢失最后一次快照后的数据
  • AOF(追加日志)
    • 记录每条写命令,重启时重新执行
    • 更安全,可配置fsync策略(每秒、每次写入等)
    • 文件通常比RDB大,恢复慢
  • 混合持久化(Redis 4.0+)
    • 开启AOF时,fork子进程创建RDB快照,将RDB内容写入AOF文件开头,后续命令以AOF格式追加
    • 兼具RDB恢复快和AOF数据安全的优点
    • 配置:aof-use-rdb-preamble yes

10. MySQL索引失效场景

  • 使用函数或表达式:WHERE YEAR(create_time) = 2023
  • 左模糊查询:LIKE '%abc'
  • OR连接非索引字段:WHERE indexed_col = 1 OR non_indexed_col = 2
  • 类型转换:索引字段为字符串,查询用数字 WHERE name = 123
  • 最左前缀原则破坏:联合索引 (a,b,c),查询条件仅用 b 或 c
  • 数据分布倾斜:MySQL优化器认为全表扫描更快时(如区分度低)

本文纯属虚构,如有雷同,说明你也面过类似的试。