面试现场:大厂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 调用流程
- 启动时,Provider 向 Registry 注册服务。
- Consumer 从 Registry 订阅服务地址。
- Consumer 通过代理发起调用,经 Netty 发送 RPC 请求。
- Provider 接收并执行,返回结果。
- 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):处理跨实体的业务逻辑。
✅ 总结:谢飞机虽然搞笑,但这些问题都是大厂高频考点!建议收藏,反复学习。