跳到主要内容Java 核心技术面试指南:基础、JVM 与框架实战 | 极客日志Javajava
Java 核心技术面试指南:基础、JVM 与框架实战
本文系统梳理 Java 核心技术面试要点,涵盖基础语法、集合框架、JVM 内存模型与垃圾回收机制、多线程并发编程中的锁与线程池应用,以及 Spring 生态下的 IOC/AOP、MyBatis 映射原理和 Spring Boot 自动配置策略。内容去除了冗余推广信息,专注于技术干货与实战解析,帮助开发者构建清晰的知识体系。
KernelLab0 浏览 一、基础篇
1.1 Java 语言特点
Java 具有简单易学、类库丰富、面向对象、跨平台(基于 JVM)、安全可靠及支持多线程等特点。其中面向对象是核心,能有效降低耦合度并提高内聚性。
1.2 面向对象与面向过程的区别
面向过程侧重于分析解决问题的步骤,以函数为单位逐步实现,性能较高但后期维护可能牵一发而动全身,常用于单片机或嵌入式开发。面向对象则以对象为最小单位,通过封装、继承和多态特性描述事物行为,易维护、易复用、易扩展,适合设计低耦合系统,但性能略低于面向过程。
1.3 八种基本数据类型及封装类
| 基本类型 | 大小(字节) | 默认值 | 封装类 |
|---|
| byte | 1 | (byte)0 | Byte |
| short | 2 | (short)0 | Short |
| int | 4 | 0 | Integer |
| long | 8 | 0L | Long |
| float | 4 | 0.0f | Float |
| double | 8 | 0.0d | Double |
| boolean | - | false | Boolean |
| char | 2 | \u0000 | Character |
注:int 是基本类型,Integer 是引用类型。int 默认值为 0,Integer 默认为 null,因此 Integer 能区分 0 和 null。基本类型声明时自动分配空间,引用类型需实例化。boolean 在 JVM 中无专用字节码指令,编译后使用 int 代替,数组中则编码为 byte 数组。
1.4 标识符命名规则
标识符可包含字母、数字、$和_,不能以数字开头且非关键字。规范上,类名采用大驼峰式(首字母大写),变量和方法名采用小驼峰式(首字母小写)。
1.5 instanceof 关键字作用
instanceof用于测试对象是否为类的实例。用法:boolean result = obj instanceof Class。若 obj 为 null 或无法转换,编译器会报错或返回 false。注意基本类型不能使用 instanceof。
int i = 0;
System.out.println(i instanceof Integer);
Integer integer = new Integer(1);
System.out.println(integer instanceof Integer);
System.out.println( Object);
null
instanceof
1.6 自动装箱与拆箱
装箱是将基本类型转换为包装器类型(如 int 转 Integer),调用 valueOf(int);拆箱反之,调用 intValue()。Java SE5 前需手动 new Integer(10),SE5 后可直接赋值。
public class Main {
public static void main(String[] args) {
Integer i1 = 100; Integer i2 = 100;
Integer i3 = 200; Integer i4 = 200;
System.out.println(i1 == i2);
System.out.println(i3 == i4);
}
}
原因:Integer 缓存范围为 [-128, 127]。范围内数值从缓存获取,范围外创建新对象。浮点数因数量无限,无此类缓存机制。
1.7 重载与重写的区别
重写 (Override):发生在父子类之间,方法名、参数列表、返回类型必须相同,访问权限不能更低,不能抛出更宽泛的异常。
重载 (Overload):同一类中,同名方法参数列表不同(类型、个数、顺序),返回值类型不影响重载判定。
1.8 equals 与==的区别
==比较内存地址或基本类型的值;equals默认比较地址,但通常被重写以比较内容。阿里规范推荐常量在前使用 equals 以防空指针。
1.9 Hashcode 的作用
Hashcode 用于集合快速定位存储区域。当集合插入元素时,先计算 hashcode 定位位置,若无冲突直接存储;若有冲突则调用 equals 比较。哈希冲突处理常用拉链法、开放定址法或再哈希法。
1.10 String、StringBuffer 和 StringBuilder 的区别
String是不可变的字符数组,每次修改生成新对象。StringBuffer和StringBuilder底层均为可变字符数组,频繁操作建议使用。StringBuffer线程安全(加锁),StringBuilder非线程安全(性能更高)。
1.11 ArrayList 和 LinkedList 的区别
ArrayList 基于数组,查询快(O(1)),增删慢(需移动数据)。LinkedList 基于双向链表,增删快,查询慢。两者均有序且允许重复。
1.12 HashMap 和 Hashtable 的区别
HashMap 继承 AbstractMap,Hashtable 继承 Dictionary。HashMap 允许 key 为 null,Hashtable 不允许。HashMap 线程不安全但效率高,Hashtable 线程安全但效率低。高并发场景推荐使用 ConcurrentHashMap。
1.13 Collection 包结构与 Collections 区别
Collection 是集合接口根接口(含 Set、List 等)。Collections 是工具类,提供静态方法实现搜索、排序等操作,不可实例化。
1.14 四种引用类型
- 强引用:常见引用,OOM 时不被回收。
- 软引用:内存不足时回收,适用于缓存。
- 弱引用:GC 发现即回收,如 WeakHashMap。
- 虚引用:回收前放入 ReferenceQueue,用于资源释放。
1.15 泛型特点
泛型允许代码重用,约束集合元素类型。编译期检查类型安全,运行期存在类型擦除。
1.16 创建对象的方式
1.17 深拷贝与浅拷贝
浅拷贝复制对象本身,引用仍指向原对象;深拷贝复制对象及其引用的所有对象。
1.18 final 用法
修饰类不可继承,修饰方法不可重写,修饰变量不可变(引用不变内容可变)。final 域有重排序规则限制。
1.19 static 用法
修饰变量/方法属于类共享,也可用于静态块初始化或静态内部类、静态导包。
1.20 浮点数精度问题
3 * 0.1 == 0.3 返回 false,因浮点数无法精确表示。
1.21 += 与 a=a+b 区别
+= 进行隐式类型转换,a=a+b 不会。例如 byte b = 127; b += 1; 合法,b = b + 1; 编译报错。
1.22 try catch finally 执行顺序
finally 总会执行。若 try 中有 return,finally 在 return 表达式运算后执行,返回值已确定。finally 中不建议 return。
1.23 Exception 与 Error 结构
Exception 分 Checked(编译检查)和 RuntimeException(运行时)。Error 是系统级错误,程序无法修复,如 OOM。
1.24 OOM 与 SOF 情况
OOM 常因堆内存满、栈溢出、常量池满或方法区溢出引起。SOF 多由递归过深或死循环导致。
1.25 线程、进程概念
进程是程序执行实例,独立资源单元。线程是进程内执行单元,共享内存,轻量级。
1.26 线程状态
新建、可运行、运行、阻塞(等待、同步、其他)、死亡。
1.27 IO 流分类
按流向分输入/输出,按单元分字节/字符,按角色分节点/处理流。基类包括 InputStream/Reader 和 OutputStream/Writer。
1.28 反射原理与作用
运行时动态获取类信息并调用方法。典型应用如 JDBC 加载驱动。优点灵活,缺点性能较低且破坏封装。
1.29 List, Set, Map 区别
List 有序可重复,Set 无序不重复,Map 键值对存储,Key 唯一。
二、JVM 篇
2.1 JVM 内存模型
线程私有:程序计数器、虚拟机栈、本地方法栈。线程共享:堆、方法区。
2.2 类加载过程
加载 -> 验证 -> 准备 -> 解析 -> 初始化。双亲委派模式避免类重复加载和 API 篡改。
2.3 垃圾回收算法
标记 - 清除、复制、标记 - 压缩。分代收集将堆分为新生代(复制算法)和老年代(标记 - 清除/整理)。G1 和 ZGC 是较新的收集器,旨在减少停顿时间。
2.4 堆与栈区别
栈存局部变量和方法调用,连续无碎片;堆存对象实例,不连续可能有碎片。栈小堆大。
2.5 Full GC 触发条件
旧生代不足、PermGen/Metaspace 满、CMS 失败、Minor GC 晋升平均大于剩余空间。
2.6 类加载器
启动类加载器、扩展类加载器、系统类加载器、用户自定义类加载器。
2.7 判断对象存活
引用计数法(无法解决循环引用)、可达性分析法(GC Roots 向下搜索)。
2.8 调优命令与工具
jps, jstat, jmap, jstack, jinfo。可视化工具包括 jconsole, jvisualvm, MAT。
2.9 JDK 1.8 元空间变动
永久代移除,改用 Native 内存的元空间。默认无上限,受系统内存限制。
三、多线程&并发篇
3.1 实现多线程方式
继承 Thread、实现 Runnable、实现 Callable、使用线程池。
3.2 停止线程
推荐设置标志位或使用 interrupt()。stop() 和 suspend() 已废弃。
3.3 notify() 与 notifyAll()
notify() 唤醒一个线程,可能导致死锁;notifyAll() 唤醒所有,更安全。wait() 应配合 while 循环使用。
3.4 sleep() 与 wait() 区别
sleep() 不释放锁,wait() 释放锁。sleep() 属 Thread 类,wait() 属 Object 类。
3.5 volatile 关键字
保证可见性和禁止指令重排,不保证原子性。适用于状态标记和单例双重检锁。
3.6 start() 与 run() 区别
start() 启动新线程,run() 只是普通方法调用。
3.7 synchronized 与 ReentrantLock 区别
synchronized 是原生关键字,ReentrantLock 是 API。后者支持公平锁、中断等待和绑定多个条件。
3.8 线程顺序执行
3.9 SynchronizedMap 与 ConcurrentHashMap 区别
3.10 线程安全定义
多线程访问无不确定结果。Vector 线程安全,ArrayList 非线程安全。
3.11 yield 方法作用
3.12 submit() 与 execute() 区别
execute() 无返回值,submit() 返回 Future 对象。
3.13 线程池好处
3.14 线程池创建方式
构造 ThreadPoolExecutor 或使用 Executors 工具类(Fixed, Single, Cached 等)。
3.15 双重校验锁单例
需配合 volatile 防止指令重排导致未初始化对象返回。
四、Spring 篇
4.1 IOC 与 AOP
IOC(控制反转)将对象创建权交给容器,DI(依赖注入)是其实现方式。AOP(面向切面)封装横切逻辑,如日志、事务。
4.2 @Autowired 与 @Resource 区别
@Autowired 按类型注入,@Resource 默认按名称注入。
4.3 依赖注入方式
4.4 Spring MVC 流程
DispatcherServlet -> HandlerMapping -> HandlerAdapter -> Controller -> ModelAndView -> ViewResolver -> View。
4.5 SpringMVC 注解
@RequestMapping, @RequestBody, @ResponseBody 等。
4.6 Bean 生命周期
实例化 -> 属性注入 -> Aware 接口 -> BeanPostProcessor -> 初始化 -> DisposableBean -> 销毁。
4.7 Bean 作用域
singleton, prototype, request, session, global-session。
4.8 设计模式应用
工厂模式(BeanFactory)、单例模式、代理模式(AOP)、模板方法、观察者模式。
五、MyBatis 篇
5.1 MyBatis 概述
半 ORM 框架,关注 SQL,灵活高效。支持 XML 或注解配置。
5.2 #{} 与 ${} 区别
5.3 字段名不一致处理
5.4 分页原理
RowBounds 内存分页或插件拦截 SQL 添加物理分页语句。
5.5 批量插入
开启 Batch 模式,循环执行 insert 后统一 commit。
5.6 延迟加载
5.7 缓存机制
一级缓存(Session 级),二级缓存(Mapper 级)。
六、SpringBoot 篇
6.1 SpringBoot 优势
简化配置、自动配置、独立运行(内嵌 Tomcat)、无需 WAR 部署。
6.2 核心注解
@SpringBootApplication 包含 @Configuration, @EnableAutoConfiguration, @ComponentScan。
6.3 Starters 理解
启动器集成依赖,一站式解决功能需求,如 spring-boot-starter-web。
6.4 热部署方式
Spring Loaded, Spring Boot DevTools。
6.5 配置文件加载顺序
命令行 > 环境变量 > YAML/Properties > 默认值。
6.6 Actuator 监视器
6.7 异常处理
使用 @ControllerAdvice 全局捕获。
相关免费在线工具
- Keycode 信息
查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online
- Escape 与 Native 编解码
JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online
- JavaScript / HTML 格式化
使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online
- JavaScript 压缩与混淆
Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online
- Base64 字符串编码/解码
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
- Base64 文件转换器
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online