面试官:Java线程池的核心参数了解吗?谢飞机:会用new Thread就不错了!

43 阅读4分钟

面试官:Java线程池的核心参数了解吗?谢飞机:会用new Thread就不错了!

面试官:请坐,先简单介绍一下自己。

谢飞机:面试官好,我叫谢飞机,三年Java开发经验,精通SSH、SSM,会用Spring Boot,能写SQL,会敲Linux命令,会画圈(UML)……

面试官:咳咳,我们开始吧。


第一轮:基础热身 —— Java 核心与集合类

面试官:ArrayList 和 LinkedList 的区别是什么?

谢飞机:这个我知道!ArrayList 是基于数组的,查询快,增删慢;LinkedList 是基于链表的,增删快,查询慢!

面试官:不错,理解到位。

谢飞机:那必须的,我还知道 ArrayList 默认初始容量是10,扩容是1.5倍!

面试官:很好。那 HashMap 的底层结构呢?

谢飞机:嗯……是数组加链表,JDK8之后链表长度超过8变成红黑树!

面试官:那如果两个 key 的 hash 值一样,怎么处理?

谢飞机:放在同一个桶里,形成链表或者红黑树,通过 equals 比较 key!

面试官:回答得很好,继续。


第二轮:进阶挑战 —— 多线程与线程池

面试官:说说你对线程池的理解,ThreadPoolExecutor 的核心参数有哪些?

谢飞机:核心参数?有 corePoolSize、maximumPoolSize……还有 keepAliveTime,队列……好像是 BlockingQueue……

面试官:那 workQueue 有哪些常见实现?

谢飞机:ArrayBlockingQueue、LinkedBlockingQueue……PriorityBlockingQueue!我项目里都用过!

面试官:那你项目中用的是哪种?为什么?

谢飞机:我……一般用 Executors.newFixedThreadPool(),方便!

面试官:……(皱眉)那你了解它背后的 LinkedBlockingQueue 容量是多少吗?

谢飞机:啊?默认……无限大?好像是 Integer.MAX_VALUE……哦不对,应该是 1024?

面试官:它是无界的,容易导致 OOM。为什么不推荐使用 Executors 创建线程池?

谢飞机:因为……规范不让用?阿里手册写了……

面试官:(点头)算是答到了点上。


第三轮:综合实战 —— Spring 与分布式组件

面试官:Spring 中 Bean 的作用域有哪些?

谢飞机:singleton、prototype,还有 request、session……我用得最多是 singleton!

面试官:Bean 的生命周期了解吗?

谢飞机:实例化、填充属性、初始化……销毁!中间还能加后置处理器!

面试官:不错。那你说说 Redis 的持久化机制?

谢飞机:RDB 是快照,AOF 是日志追加,可以同时开!

面试官:那如果 Redis 宕机,哪个数据更完整?

谢飞机:当然是 AOF!它每秒同步一次,比 RDB 准!

面试官:如果开启 appendfsync always 呢?

谢飞机:那……每次写都同步,最安全!就是慢一点……

面试官:很好。最后一个问题:Dubbo 的负载均衡策略有哪些?

谢飞机:随机、轮询、最少活跃调用数……还有……一致性哈希!

面试官:如果某个服务节点响应特别慢,Dubbo 怎么感知并剔除?

谢飞机:呃……超时了就重试别的?监控?心跳?我配过超时时间,但没深入看过……

面试官:(微笑)今天就到这里,你的基础知识还不错,有些细节还需要加强。回去等通知吧。

谢飞机:好的好的,谢谢面试官!我回去就把 Executors 全换成 ThreadPoolExecutor!


参考答案详解

1. ArrayList vs LinkedList

  • ArrayList:基于动态数组,支持随机访问(O(1)),扩容机制为 oldCapacity + (oldCapacity >> 1),即1.5倍。
  • LinkedList:双向链表,插入删除快(O(1)),但遍历慢(O(n)),且占用更多内存(前后指针)。

使用场景:频繁查询用 ArrayList,频繁增删用 LinkedList。

2. HashMap 底层原理

  • JDK8 之前:数组 + 链表
  • JDK8 之后:数组 + 链表 + 红黑树(当链表长度 ≥ 8 且数组长度 ≥ 64 时转换)
  • Hash 冲突:通过拉链法解决,equals 判断 key 是否相同。
  • 扩容:loadFactor 默认 0.75,达到阈值后扩容为原大小2倍,并 rehash。

3. ThreadPoolExecutor 核心参数

  • corePoolSize:核心线程数,即使空闲也不会回收(除非设置 allowCoreThreadTimeOut)
  • maximumPoolSize:最大线程数
  • keepAliveTime:非核心线程空闲存活时间
  • unit:时间单位
  • workQueue:任务队列,常用:
    • ArrayBlockingQueue:有界队列
    • LinkedBlockingQueue:无界队列(Executors.newFixedThreadPool 使用,默认容量 Integer.MAX_VALUE)
    • SynchronousQueue:不存储元素,每个插入必须等待取出(newCachedThreadPool 使用)
    • PriorityBlockingQueue:优先级队列
  • threadFactory:线程创建工厂
  • handler:拒绝策略(AbortPolicy、CallerRunsPolicy 等)

为什么不推荐 Executors?

  • newFixedThreadPool 使用无界队列,可能导致大量任务堆积,OOM。
  • newSingleThreadExecutor 同理。
  • newCachedThreadPool 最大线程数为 Integer.MAX_VALUE,可能创建过多线程,系统崩溃。

4. Spring Bean 作用域

  • singleton:容器唯一实例(默认)
  • prototype:每次获取都新建实例
  • request:每个 HTTP 请求一个实例(Web 环境)
  • session:每个 HTTP session 一个实例
  • application:每个 ServletContext 一个实例

5. Redis 持久化

  • RDB:定时快照,恢复快,数据可能丢失(最后一次快照后数据)
  • AOF:记录所有写命令,数据更完整,文件大,恢复慢
  • appendfsync always:每次写操作都同步到磁盘,最安全,性能最差
  • 推荐:RDB + AOF 混合使用(Redis 4.0+)

6. Dubbo 负载均衡

  • RandomLoadBalance:按权重随机(默认)
  • RoundRobinLoadBalance:轮询
  • LeastActiveLoadBalance:最少活跃调用数(避免慢节点积压)
  • ConsistentHashLoadBalance:一致性哈希,相同参数请求同节点

节点健康检测:通过心跳机制(默认 2s 一次),失败一定次数后从注册中心剔除。