25年12月小红书Java开发工程师 一面
1. Java 8中Lambda表达式底层是如何实现的?
思路
核心讲“动态生成匿名内部类+invokedynamic指令”,区分编译期与运行期逻辑,避免只说“语法糖”的模糊回答。
回答示例
Lambda表达式本质是语法糖,底层通过「动态生成匿名内部类 + JVM的invokedynamic指令」实现,核心流程:
- 编译期:编译器不会直接生成匿名内部类的字节码,而是将Lambda表达式转换成
invokedynamic指令(动态调用点),记录Lambda的逻辑(如参数、方法体); - 运行期:JVM首次执行
invokedynamic时,会通过LambdaMetafactory动态生成一个实现了对应函数式接口的匿名内部类(如Runnable、Consumer),并生成该类的实例; - 执行逻辑:后续调用Lambda时,直接调用该匿名内部类的接口方法(如run()、accept())。
验证方式:通过javap -v反编译class文件,能看到invokedynamic指令;运行时用lambda.getClass().getName(),会得到类似XXX$$Lambda$1/0x0000000800660840的动态类名。
2. 接口中的default方法解决了什么问题?
思路
核心讲“接口升级兼容问题”,结合实际场景(如集合框架升级),说明default方法的设计初衷。
回答示例
default方法(默认方法)是Java 8为接口新增的特性,核心解决接口升级的兼容性问题:
- 问题背景:Java 8前,接口只能定义抽象方法,若给已有接口新增方法,所有实现类都必须重写该方法,否则编译报错(比如给Collection接口加stream()方法,所有自定义Collection实现类都要改);
- 解决方式:default方法允许在接口中定义带方法体的默认实现,实现类可直接继承该实现,无需强制重写;
- 典型场景:Java 8给Collection、List等接口新增stream()、forEach()等方法时,通过default方法实现,保证已有几十万实现类无需修改即可兼容。
补充:default方法还能解决“多继承”的部分场景(接口多实现时,若多个接口有同名default方法,实现类必须显式重写,避免冲突)。
3. Error和Exception的根本区别是什么?
思路
从“设计目的、处理方式、严重程度”三个核心维度区分,结合典型例子,避免只说“Error不可捕获”的片面回答。
回答示例
Error和Exception都继承自Throwable,根本区别在于是否属于应用程序可处理的异常:
维度 |
Error(错误) |
Exception(异常) |
设计目的 |
表示JVM/系统级别的严重错误,应用程序无法恢复 |
表示应用程序级别的异常,可捕获并处理 |
处理方式 |
无需捕获(捕获也无法解决),属于Unchecked |
分为Checked(必须捕获,如IOException)和Unchecked(可选捕获,如NullPointerException) |
典型例子 |
OutOfMemoryError、StackOverflowError、NoClassDefFoundError |
IOException(IO异常)、SQLException(数据库异常)、NullPointerException(空指针) |
严重程度 |
致命的,会导致程序崩溃/退出 |
非致命的,处理后程序可继续运行 |
核心总结:Error是“系统级故障”,应用管不了;Exception是“应用级问题”,应用可处理。
4. TreeMap插入元素时如何维持红黑树平衡?
思路
先讲红黑树的5条核心规则,再讲插入后的“变色+旋转”调整逻辑,突出关键步骤。
回答示例
TreeMap底层是红黑树(自平衡的二叉查找树),插入元素时,先按Key的比较结果找到插入位置,再通过「变色+旋转」维持红黑树的5条核心规则:
- 节点要么红,要么黑;
- 根节点是黑;
- 叶子节点(NIL)是黑;
- 红节点的子节点必须是黑(无连续红节点);
- 任意节点到其所有叶子节点的路径,黑节点数量相同。
插入后的调整逻辑(核心步骤):
- 默认插入红节点:减少黑节点路径变化的概率,降低调整复杂度;
- 判断父节点颜色:
最终目标:通过最少的旋转/变色,恢复红黑树的5条规则,保证树的高度平衡(最长路径≤最短路径的2倍)。
5. HashSet判断元素重复时先比较什么?
思路
核心讲“hashCode()优先,equals()兜底”,结合HashSet的底层(HashMap),解释判断逻辑的本质。
回答示例
HashSet底层基于HashMap实现(元素存在HashMap的key中,value是固定的PRESENT对象),判断元素重复的核心逻辑是:
- 先比较hashCode():计算两个元素的hashCode值,若不相等,直接判定为不同元素;
- hashCode相等时,再比较equals():若equals()返回true,判定为重复元素,插入失败;若返回false,判定为不同元素(哈希冲突),会以链表/红黑树形式存储在同一哈希桶中。
核心规则:hashCode()相等是equals()相,即:
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
本专栏在精不在多,内容分为八股文、大厂真实面经,面试通过后将offer和面试题私发给我,可退还专栏的收益部分费用。欢迎大家共建专栏
查看18道真题和解析