Java面试官:谢飞机,你这水平也敢来面大厂?
第一轮:基础拷问,还能顶住
面试官:请介绍一下HashMap的底层结构。
谢飞机:哦!这个我知道!是数组+链表,还有红黑树!JDK8之后加的!
面试官(点头):不错,那什么时候转红黑树?
谢飞机:嗯……数组长度大于8?
面试官:接近了,是当链表长度≥8 且 数组长度≥64 才会转换。
谢飞机:哦哦,那我记错了,但差不多!
面试官:ArrayList和LinkedList的区别?
谢飞机:ArrayList是数组,查询快;LinkedList是链表,增删快!
面试官:很好。那线程安全的List有哪些?
谢飞机:Vector!还有……CopyOnWriteArrayList!我还用过!
面试官:可以,基础还行。
第二轮:深入JUC,开始飘了
面试官:ThreadPoolExecutor的核心参数有哪些?
谢飞机:corePoolSize、maximumPoolSize、workQueue、keepAliveTime……还有,呃……拒绝策略!
面试官:说说四种拒绝策略。
谢飞机:AbortPolicy,直接抛异常;CallerRunsPolicy,让调用者执行;DiscardPolicy,丢掉任务……第四个是……DiscardOldestPolicy!对,扔最老的任务!
面试官:还行。那Synchronized和ReentrantLock区别?
谢飞机:Synchronized是关键字,自动释放锁;ReentrantLock要手动unlock!
面试官:公平锁呢?
谢飞机:ReentrantLock默认是公平锁!
面试官:错,默认是非公平锁。
谢飞机:啊?我以为是公平的……
面试官:继续。volatile关键字作用?
谢飞机:防止指令重排!还有保证可见性!
面试官:能保证原子性吗?
谢飞机:能吧……应该能……
面试官:不能!volatile不保证原子性,要用Atomic类或者锁。
第三轮:架构连环炮,彻底炸裂
面试官:Spring Bean的作用域有哪些?
谢飞机:singleton、prototype,还有request、session……application?
面试官:OK。那Bean的生命周期?
谢飞机:new一个对象,然后初始化……注入属性……最后销毁?
面试官:说得太模糊。那SpringBoot自动装配原理?
谢飞机:@EnableAutoConfiguration,它会扫描META-INF/spring.factories,把配置类加载进来!
面试官:不错。那Dubbo的负载均衡策略?
谢飞机:随机、轮询、最少活跃数……还有哈希!一致性哈希!
面试官:RabbitMQ如何保证消息不丢失?
谢飞机:发完就没了啊……消费者消费就行了吧……
面试官:……你需要持久化、确认机制、手动ACK。
面试官:MySQL索引失效场景?
谢飞机:like '%abc' 就失效!还有or连接!
面试官:不错。那redo log和binlog区别?
谢飞机:都是日志……一个InnoDB用,一个MySQL用?
面试官:……
面试官:Redis的持久化方式?
谢飞机:RDB和AOF!RDB是快照,AOF是追加日志!
面试官:那Docker和虚拟机区别?
谢飞机:Docker轻!虚拟机重!一个用宿主机内核,一个自己带系统!
面试官:设计模式了解哪些?
谢飞机:单例!工厂!代理!装饰器!观察者!我都会!
面试官:DDD是什么?
谢飞机:Domain……Driven Design?领域驱动设计!
面试官:……就这?
谢飞机:嗯……听说过,没用过……
面试官:好了,今天先到这里。你的表现……还可以提升。回去等通知吧。
谢飞机:好嘞!我回去等您电话!
参考答案详解
1. HashMap底层结构
- JDK8之前:数组 + 链表
- JDK8之后:数组 + 链表 + 红黑树(链表长度≥8 且 数组长度≥64时转换)
- 扩容:loadFactor=0.75,初始容量16,扩容2倍
2. ArrayList vs LinkedList
- ArrayList:基于动态数组,支持随机访问,查询O(1),插入删除O(n)
- LinkedList:双向链表,插入删除O(1),查询O(n)
- 线程安全:Vector(同步方法)、CopyOnWriteArrayList(写时复制)
3. ThreadPoolExecutor参数
- corePoolSize:核心线程数
- maximumPoolSize:最大线程数
- workQueue:任务队列
- keepAliveTime:空闲线程存活时间
- unit:时间单位
- threadFactory:线程工厂
- handler:拒绝策略
拒绝策略
- AbortPolicy:抛出RejectedExecutionException
- CallerRunsPolicy:由提交任务的线程执行
- DiscardPolicy:默默丢弃
- DiscardOldestPolicy:丢弃队列中最老任务,重试提交
4. Synchronized vs ReentrantLock
| 特性 | Synchronized | ReentrantLock | |------|---------------|--------------| | 关键字/类 | 关键字 | 类 | | 自动释放 | 是 | 否(需手动unlock) | | 公平锁 | 否 | 可设置(默认非公平) | | 条件等待 | wait/notify | Condition |
5. volatile
- 保证可见性:修改后立即写回主内存
- 禁止指令重排:通过内存屏障
- 不保证原子性:如i++操作仍需synchronized或AtomicInteger
6. Spring Bean作用域
- singleton:单例(默认)
- prototype:每次获取新实例
- request:每次请求创建
- session:每个会话一个实例
- application:整个ServletContext生命周期
7. Bean生命周期
- 实例化(new)
- 属性赋值(DI)
- 调用Aware接口(如BeanNameAware)
- BeanPostProcessor前置处理
- 初始化(InitializingBean / @PostConstruct)
- BeanPostProcessor后置处理
- 使用
- 销毁(DisposableBean / @PreDestroy)
8. SpringBoot自动装配
- @SpringBootApplication → @EnableAutoConfiguration
- 加载META-INF/spring.factories中的自动配置类
- Conditional条件注解控制是否生效
- 最终通过@Bean注册到IOC容器
9. Dubbo负载均衡
- RandomLoadBalance:权重随机(默认)
- RoundRobinLoadBalance:轮询
- LeastActiveLoadBalance:最少活跃调用数
- ConsistentHashLoadBalance:一致性哈希
10. RabbitMQ消息不丢失
- 生产者:开启confirm模式,确保消息到达Broker
- Broker:消息持久化(queue、message、exchange)
- 消费者:手动ACK,避免自动ACK导致消费失败丢失
11. MySQL索引失效场景
- LIKE以%开头
- OR连接非索引字段
- 类型转换(如字符串字段传数字)
- 函数操作(如WHERE YEAR(create_time)=2024)
- 最左前缀原则破坏
12. redo log vs binlog
| | redo log | binlog | |---|--------|--------| | 层级 | InnoDB存储引擎 | Server层 | | 内容 | 物理日志(页修改) | 逻辑日志(SQL语句) | | 用途 | 崩溃恢复 | 主从复制、数据恢复 | | 刷盘时机 | 事务提交时 | 根据sync_binlog配置 |
13. Redis持久化
- RDB:定时快照,恢复快,可能丢数据
- AOF:记录写命令,appendonly模式,可每秒同步(fsync)
- 混合模式(4.0+):RDB+AOF增量
14. Docker vs VM
| | Docker | 虚拟机 | |---|--------|--------| | 架构 | 容器,共享宿主机内核 | Hypervisor,模拟完整硬件 | | 启动速度 | 秒级 | 分钟级 | | 资源占用 | 少 | 多 | | 隔离性 | 进程级 | 系统级 |
15. 设计模式(常用)
- 创建型:单例、工厂、建造者
- 结构型:代理、装饰器、适配器
- 行为型:观察者、策略、模板方法
16. DDD(领域驱动设计)
- 核心思想:以业务领域为核心驱动开发
- 概念:实体(Entity)、值对象(Value Object)、聚合根(Aggregate Root)、仓储(Repository)、领域服务(Domain Service)
- 分层架构:表现层、应用层、领域层、基础设施层
- 适合复杂业务系统,避免贫血模型