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

46 阅读6分钟

面试现场:大厂Java岗,谢飞机的生死三轮拷问

面试官(推了推眼镜):请进。

谢飞机(紧张地搓手):您好您好,我是谢飞机,三年Java经验,精通HelloWorld和Ctrl+C/V……

面试官(面无表情):我们开始吧。


🟢 第一轮:基础稳如老狗,还能抢救一下

Q1:说说 ArrayList 和 LinkedList 的区别?

谢飞机:这个我会!ArrayList 是基于数组的,查询快,增删慢;LinkedList 是链表结构,增删快,查询慢。就像——查字典用 ArrayList,改作文用 LinkedList!

面试官(微微点头):嗯,回答得还挺形象,不错。

Q2:HashMap 的底层结构是什么?

谢飞机:数组 + 链表 + 红黑树!JDK8之后,链表长度超过8转红黑树,防止哈希冲突导致性能下降。

面试官:还可以,那扩容机制呢?

谢飞机:默认负载因子0.75,容量满了就翻倍……复制过去,emmm……有点像搬家,但容易丢数据——哦不,是rehash!

面试官:勉强过关。

Q3:ConcurrentHashMap 如何保证线程安全?

谢飞机:分段锁!JDK7是Segment,JDK8改成了CAS + synchronized,只锁链表头或红黑树根节点,效率更高!

面试官(略显惊讶):你还真知道点东西……继续。


🟡 第二轮:多线程一出手,谢飞机就发抖

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

谢飞机:七个!corePoolSize、maximumPoolSize、keepAliveTime、unit、workQueue、threadFactory、handler!我背过!

面试官:很好,那如果队列满了且线程数达到最大,会发生什么?

谢飞机:那就……新建线程?不对……等等,应该是执行拒绝策略!比如 AbortPolicy 直接抛异常!

面试官:还行。那常见的工作队列有哪些?

谢飞机:ArrayBlockingQueue、LinkedBlockingQueue、SynchronousQueue……SynchronousQueue 是快递代收柜,不存件,必须有人立马取!

面试官:比喻可以,但别太离谱。

Q5:Spring 中 Bean 的作用域有哪些?

谢飞机:singleton、prototype、request、session、application……单例是默认的,prototype 每次 getBean 都新创建!

面试官:那 singleton 一定是线程安全的吗?

谢飞机:当然!一个类一个实例嘛……等等,要是有成员变量……那可能……看运气?

面试官(皱眉):……这题你不会就直说。


🔴 第三轮:架构一问,原形毕露

Q6:Dubbo 的核心组件有哪些?

谢飞机:Provider、Consumer、Registry、Monitor、Container……注册中心一般是ZooKeeper!

面试官:调用过程说一下。

谢飞机:Consumer 调 Provider,先去 ZooKeeper 找地址,然后……直接打电话?不是,是走Netty通信!

面试官:……还算凑合。那 xxl-job 如何实现任务调度高可用?

谢飞机:多个执行器?主从备份?脑裂?啊……我只知道它能定时跑脚本……

面试官:Redis 的持久化机制呢?

谢飞机:RDB 是拍照,AOF 是记账本!但同时开的话,重启优先用 AOF!

面试官:那数据一致性怎么保证?

谢飞机:加个@Transactional?

面试官(扶额):那是数据库的……

Q7:MySQL 的索引失效场景有哪些?

谢飞机:左模糊 like '%abc' 会失效,or 连接没都建索引也会……函数操作字段也不行,比如 where year(create_time)=2024!

面试官:还行。最后一个问题:DDD 的核心概念有哪些?

谢飞机:Domain……Drive……Design?领域驱动设计!领域模型、聚合根、值对象……Repository 是仓库,像京东物流!

面试官(叹气):概念背了,但明显没实战过。


面试官:今天就到这里,你的基础知识还行,但深度和系统设计能力还需要提升。回去等通知吧。

谢飞机(松一口气):好嘞!等您电话,我手机24小时开机,连充电宝都焊手上了!


💡 参考答案详解(小白也能懂)

1. ArrayList vs LinkedList

  • ArrayList:基于动态数组,内存连续,支持随机访问(O(1)),但插入删除需移动元素(O(n))。
  • LinkedList:双向链表,每个节点含前后指针,插入删除快(O(1)),但访问需遍历(O(n))。
  • 适用场景:频繁查询用 ArrayList,频繁增删用 LinkedList。

2. HashMap 底层结构与扩容

  • 结构:数组 + 链表(JDK8前)→ 数组 + 链表/红黑树(JDK8+)。
  • 哈希冲突:通过拉链法解决,链表长度≥8且数组长度≥64时转红黑树。
  • 扩容:初始容量16,负载因子0.75,阈值12。达到后扩容为2倍,重新计算索引位置(rehash)。
  • 线程不安全:多线程下可能导致死循环(JDK7)或数据覆盖(JDK8)。

3. ConcurrentHashMap 线程安全机制

  • JDK7:分段锁 Segment,每段独立加锁,提高并发度。
  • JDK8:放弃 Segment,采用 CAS + synchronized。对 Node 数组头节点加锁,锁粒度更小,性能更好。
  • size() 实现:通过 baseCount 和 CounterCell 数组避免竞争,类似 LongAdder。

4. 线程池七大参数

  • corePoolSize:核心线程数,常驻内存。
  • maximumPoolSize:最大线程数。
  • keepAliveTime & unit:非核心线程空闲存活时间。
  • workQueue:任务队列,如 LinkedBlockingQueue(无界)、SynchronousQueue(同步移交)。
  • threadFactory:创建线程的工厂,可自定义命名。
  • handler:拒绝策略,如 AbortPolicy(抛异常)、CallerRunsPolicy(调用者线程执行)。

5. Spring Bean 作用域

  • singleton:容器中唯一实例,共享对象。
  • prototype:每次获取都创建新实例。
  • request/session/application:Web 场景下对应生命周期。
  • ⚠️ 注意:singleton 不等于线程安全!若 Bean 有状态(成员变量),仍需同步控制。

6. Dubbo 调用流程

  1. 启动时,Provider 向 Registry 注册服务。
  2. Consumer 从 Registry 订阅服务地址。
  3. Consumer 通过代理发起调用,经 Netty 发送 RPC 请求。
  4. Provider 接收并执行,返回结果。
  5. Monitor 收集调用统计。

7. Redis 持久化

  • RDB:定时快照,恢复快,适合备份,但可能丢失最后一次数据。
  • AOF:记录每条写命令,日志式,数据更安全,但文件大、恢复慢。
  • 混合模式(Redis 4.0+):RDB 前镜像 + AOF 增量日志,兼顾速度与安全。

8. MySQL 索引失效场景

  • 使用函数或表达式:WHERE YEAR(create_time) = 2024
  • 左模糊匹配:LIKE '%java'
  • OR 条件未全部索引:a=1 OR b=2,但 b 无索引
  • 类型转换:字符串字段传数字,触发隐式转换
  • 最左前缀原则破坏:联合索引 (a,b,c),查询用 (b,c) 或 (c)

9. DDD 核心概念

  • 实体(Entity):有唯一标识,生命周期持续变化。
  • 值对象(Value Object):无标识,通过属性判断相等,如地址。
  • 聚合(Aggregate):一组相关对象的集合,由聚合根统一管理。
  • 聚合根(Aggregate Root):聚合的入口,外部只能通过它访问内部对象。
  • Repository:提供聚合的持久化接口,屏蔽底层细节。
  • 领域服务(Domain Service):处理跨实体的业务逻辑。

✅ 总结:谢飞机虽然搞笑,但这些问题都是大厂高频考点!建议收藏,反复学习。