北京即时设计有限公司 Java 一面面经
面试题目
- 自我介绍
- Java 基本类型和包装类型的区别
- 面向对象三大特征及其讲解
- Exception 和 Error 的区别
- JVM 内存区域的组成
- 类加载双亲委派机制
- JVM 线程私有区域中不会 OOM 的区域
- 导致 OOM 的场景
- 开发中 OOM 问题排查经历
- 垃圾回收算法
- HashMap 的 put 存储过程
- HashMap 为什么先用链表后用红黑树
- ConcurrentHashMap 和 HashMap 的区别及底层结构
- AQS 定义及其两种模式
- 线程池的核心属性
- 线程池参数作用及任务执行流程
- 线程池中线程执行抛出异常后的处理
- 线程池拒绝策略
- 终止的线程能否重新启动及方式
- Spring Boot 启动过程
- Spring 常用注解
- @Resource 和 @Autowired 的区别
- 是否封装过自定义注解
- 熟悉的设计模式
- SQL 查询执行过程
- 索引建立、生效条件及查询优化
- 项目中 Redis 使用场景
- 优惠券领取失败的处理方案
- 如何防止优惠券超发、超领
- 针对优惠券配置错误导致超卖的应急与预防机制
- 算法题:寻找最长回文子串
参考解析
- JVM 内存区域:分为堆(线程共享)、栈(线程私有)、方法区(元空间)、程序计数器(线程私有)、本地方法栈。程序计数器是唯一不会发生 OOM 的区域。
- HashMap 与 ConcurrentHashMap:HashMap 线程不安全,基于数组+链表+红黑树;ConcurrentHashMap 通过 CAS+synchronized 实现线程安全,JDK 8 后不再使用分段锁。
- 线程池执行流程:任务提交先判断核心线程池是否满,不满则创建;满则尝试入队;队列满则判断最大线程数;再满则执行拒绝策略。
- Redis 超发控制:通常采用 Redis + Lua 脚本保证“查询+扣减”原子性,或通过 Redis 分布式锁/库存扣减记录实现,利用乐观锁或 Redis 预减库存处理高并发。
- SQL 优化:遵循最左前缀原则、避免计算导致索引失效、减少 Select * 使用、适当使用覆盖索引,利用 Explain 查看执行计划。