26年2月神州数码 Java开发工程师 一面
1. Java中Error与Exception的根本区别?举例说明VirtualMachineError触发场景
思路
从“错误性质、处理方式、恢复可能性”拆解核心区别,结合VirtualMachineError的具体触发场景说明。
回答示例
维度 |
Error(错误) |
Exception(异常) |
根本性质 |
JVM层面的严重问题,属于“不可恢复的系统错误” |
应用层面的问题,属于“可处理的业务/运行时问题” |
处理方式 |
无法通过try-catch捕获恢复,JVM通常终止线程/进程 |
可通过try-catch捕获并处理,程序可继续执行 |
设计目的 |
告知开发者“系统级故障”,无需编码处理 |
告知开发者“应用级异常”,需编码容错/恢复 |
VirtualMachineError触发场景:
VirtualMachineError是Error的子类,代表JVM自身故障,典型场景:
OutOfMemoryError:堆/元空间/直接内存耗尽(如无限创建对象、动态生成大量类);StackOverflowError:方法递归调用过深(如无终止条件的递归);InternalError:JVM内部错误(如GC算法崩溃、类加载器损坏);OutOfMemoryError: Metaspace:元空间溢出(如频繁热部署导致类元数据堆积)。
2. ConcurrentHashMap在JDK1.8中,TreeBin节点如何保证红黑树操作的线程安全?
思路
核心讲TreeBin的“内置锁+CAS+自旋”机制,区分红黑树操作的加锁逻辑与链表的CAS逻辑。
回答示例
JDK1.8中ConcurrentHashMap的TreeBin是红黑树的容器节点,保证线程安全的核心机制:
- 内置锁(synchronized):
- 读写分离:
- CAS辅助:
对比:链表节点用CAS直接操作,红黑树因操作复杂(旋转/平衡),需加锁保证原子性。
3. 线程池四种拒绝策略中,CallerRunsPolicy对系统稳定性的影响?
思路
先讲CallerRunsPolicy的执行逻辑,再分析“兜底执行”对系统的正反影响。
回答示例
1. CallerRunsPolicy核心逻辑
当线程池满(核心线程+非核心线程达上限,队列也满)时,由提交任务的线程自己执行该任务,而非抛出异常/丢弃任务。
2. 对系统稳定性的影响
正面影响:
- 避免任务丢失:相比AbortPolicy(抛异常)、DiscardPolicy(丢弃),能保证任务最终被执行;
- 天然限流:提交线程执行任务时,会阻塞当前请求(如Tomcat主线程),间接降低请求提交速率,避免线程池过载崩溃。
负面影响:
- 阻塞提交线程:若提交线程是核心业务线程(如Tomcat处理请求的线程),会导致主线程阻塞,响应延迟升高;
- 性能降级:提交线程执行任务会占用核心线程资源,可能导致整个系统吞吐量下降;
- 级联阻塞风险:若提交线程大量阻塞,可能引发上游系统超时/重试,加剧系统压力。
适用场景:
低并发、非核心任务(如日志收集),或需要“尽力执行”且允许性能降级的场景。
4. JVM栈帧中局部变量表与操作数栈的协作关系?
思路
先定义两个结构的作用,再通过方法执行流程说明协作逻辑。
回答示例
栈帧是方法执行的基本单位,局部变量表和操作数栈是栈帧的核心组成,协作关系如下:
- 各自作用:
- 协作流程(以
int add(int a, int b)为例):
核心:局部变量表是“数据存储区”,操作数栈是“运算区”,方法执行的本质是“局部变量表→操作数栈运算→局部变量表/返回值”的数据流转换。
5. InnoDB行锁记录锁(Record Lock)加在索引的哪个位置?
思路
明确记录锁加在“索引的叶子节点”,区分聚簇索引与二级索引的加锁位置,强调“无索引退化为表锁”。
回答示例
InnoDB的Record Lock(记录锁)是行锁的核心,加锁位置:
- 核心规则:Record Lock加在索引的叶子节点上,而非数据行本身;
- 不同索引的加锁位置:
- 关键补充:
6. @Autowired按类型注入失败时,如何通过@Qualifier指定Bean?
思路
讲@Qualifier的核心(按Bean名称匹配),分“字段注入、方法注入、构造器注入”三种场景举例。
回答示例
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
本专栏在精不在多,内容分为八股文、大厂真实面经,面试通过后将offer和面试题私发给我,可退还专栏的收益部分费用。欢迎大家共建专栏