第一轮:Java基础与多线程
面试官:请介绍一下Java线程池的核心参数。
谢飞机:呃……线程池?是不是就是new Thread()然后.start()就行?
面试官:……我们说的是ThreadPoolExecutor。
谢飞机:哦!那个啊,我知道!有核心线程数、最大线程数、队列,还有keepAliveTime,对吧?
面试官:不错,那这些参数分别起什么作用?
谢飞机:核心线程数是常驻的,最大线程数是最多能开多少个,队列用来排队任务,keepAliveTime是多余的线程空闲多久就销毁。
面试官:很好,理解得挺到位。
面试官:那如果队列满了,新任务会怎么样?
谢飞机:嗯……系统自动处理?
面试官:会触发拒绝策略。你知道有哪些拒绝策略吗?
谢飞机:AbortPolicy?好像听说过,别的我就不太清楚了……
第二轮:JUC与并发容器
面试官:ConcurrentHashMap是如何实现线程安全的?
谢飞机:加了synchronized?
面试官:JDK 1.8之后呢?
谢飞机:呃……CAS + synchronized?分段锁?我有点乱……
面试官:基本方向对。那它和Hashtable的区别是什么?
谢飞机:Hashtable慢,ConcurrentHashMap快?
面试官:……可以这么理解,但不够准确。
面试官:volatile关键字的作用是什么?
谢飞机:防止指令重排!还有保证可见性!
面试官:很好,那它能保证原子性吗?
谢飞机:能……吧?
面试官:不能。需要配合CAS或其他机制。
第三轮:Spring生态与中间件
面试官:Spring Bean的作用域有哪些?
谢飞机:singleton和prototype!
面试官:还有呢?
谢飞机:request、session……我还真没用过其他的。
面试官:可以。那Spring Boot自动装配的原理是什么?
谢飞机:@SpringBootApplication注解?里面有个@EnableAutoConfiguration,它会去加载META-INF/spring.factories文件里的配置类。
面试官:非常棒!
面试官:Redis的持久化机制了解吗?
谢飞机:RDB是快照,AOF是日志……但具体怎么配置我忘了。
面试官:那MySQL的索引失效场景有哪些?
谢飞机:比如用函数、like左边通配、or连接不用索引字段……
面试官:不错。最后一个问题,Dockerfile中的COPY和ADD有什么区别?
谢飞机:ADD更高级?能从URL下载?
面试官:是的,但一般推荐用COPY。
面试官:今天先到这里,回去等通知吧。
答案详解
1. 线程池核心参数
ThreadPoolExecutor有7个参数:
- corePoolSize:核心线程数,即使空闲也不会被回收(除非设置allowCoreThreadTimeOut)
- maximumPoolSize:最大线程数
- keepAliveTime:非核心线程空闲存活时间
- unit:时间单位
- workQueue:阻塞队列,如ArrayBlockingQueue、LinkedBlockingQueue
- threadFactory:线程创建工厂
- handler:拒绝策略,包括AbortPolicy(抛异常)、CallerRunsPolicy(调用者线程执行)、DiscardPolicy(丢弃)、DiscardOldestPolicy(丢弃队列中最老的任务)
2. ConcurrentHashMap
JDK 1.8后采用CAS + synchronized(对链表头或红黑树根节点加锁),替代了之前的分段锁(ReentrantLock),提高了并发性能。相比Hashtable,它只锁部分数据,性能更好。
3. volatile
保证内存可见性和禁止指令重排序,但不保证复合操作的原子性(如i++)。
4. Spring Bean作用域
- singleton:单例
- prototype:每次获取都创建新实例
- request:每个HTTP请求一个实例
- session:每个HTTP会话一个实例
- application:每个ServletContext生命周期一个实例
5. Spring Boot自动装配
通过@EnableAutoConfiguration导入AutoConfigurationImportSelector,读取META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports(旧版为spring.factories)中的自动配置类,结合条件注解(@ConditionalOnClass等)决定是否加载。
6. Redis持久化
- RDB:定时快照,恢复快,可能丢失数据
- AOF:记录写命令,数据更安全,文件更大,恢复慢
7. MySQL索引失效
- 对字段使用函数或运算
- like以%开头
- or连接的字段未全部建索引
- 类型转换(如字符串字段传数字)
- 最左前缀原则破坏
8. Docker COPY vs ADD
- COPY:仅支持本地文件复制
- ADD:支持本地文件复制和远程URL下载,还支持自动解压tar文件。但因行为复杂,官方推荐优先使用COPY。