第一轮:Java基础与多线程
面试官:请介绍一下Java中线程池的核心参数。
谢飞机:呃……线程池?是不是就是new Thread()然后.start()就行啦?
面试官(皱眉):那是手动创建线程。我说的是ThreadPoolExecutor的七个核心参数。
谢飞机:哦!我知道!有corePoolSize、maximumPoolSize,还有……keepAliveTime!对吧?
面试官:不错,那workQueue和threadFactory呢?
谢飞机:workQueue是用来排队任务的,threadFactory是造线程的工厂——就像我妈生我一样!
面试官(忍不住笑):虽然比喻奇怪,但还算说得过去。
第二轮:JUC与并发容器
面试官:ConcurrentHashMap是如何实现线程安全的?
谢飞机:它用了synchronized锁整个map!
面试官:那是早期版本。JDK 1.8之后呢?
谢飞机:啊?难道……它用ReentrantLock分段锁?
面试官:再想想。
谢飞机:不会是……CAS + synchronized?
面试官:勉强及格。具体是怎么结合的?
谢飞机:这个……等我查下百度……
面试官(摇头):我们继续。
第三轮:Spring与分布式
面试官:Spring中Bean的作用域有哪些?
谢飞机:singleton和prototype!request和session我也知道!
面试官:很好。那Spring Boot自动装配原理?
谢飞机:就是加个@SpringBootApplication,然后Spring自己就会找配置类!
面试官:背后的机制呢?
谢飞机:应该是……反射+注解扫描?
面试官:还行。最后一个问题:Redis的持久化机制?
谢飞机:RDB是定时拍快照,AOF是记日志,每条命令都写进去!
面试官:那两者如何选择?
谢飞机:要看老板心情吧……
面试官(叹气):今天就到这里,回去等通知吧。
参考答案详解
1. 线程池七大参数
corePoolSize:核心线程数,即使空闲也不会被回收。maximumPoolSize:最大线程数。keepAliveTime:非核心线程空闲存活时间。unit:时间单位。workQueue:阻塞队列,如LinkedBlockingQueue。threadFactory:线程创建工厂,可自定义命名规则。handler:拒绝策略,如AbortPolicy、CallerRunsPolicy等。
2. ConcurrentHashMap(JDK 1.8)
- 使用 CAS + synchronized 实现高效并发。
- 数组元素第一个节点通过CAS插入。
- 链表或红黑树头节点加synchronized锁,锁粒度小。
- 相比Segment分段锁,减少了锁竞争。
3. Spring Bean作用域
- singleton:单例(默认)。
- prototype:每次获取新实例。
- request/session/application:Web相关作用域。
4. Spring Boot自动装配
@EnableAutoConfiguration导入AutoConfigurationImportSelector。- 加载
META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports文件中的自动配置类。 - 通过条件注解(@ConditionalOnClass等)按需加载。
5. Redis持久化
- RDB:定时生成数据快照,恢复快,可能丢失最后一次快照后的数据。
- AOF:记录每一个写操作命令,通过重放恢复数据。可配置fsync频率(always/everysec/no),安全性高但文件大。
- 建议:生产环境可同时开启,重启时优先使用AOF恢复。