跳到主要内容Java 面试核心知识点梳理:基础、JVM 与并发编程 | 极客日志Javajava算法
Java 面试核心知识点梳理:基础、JVM 与并发编程
本文涵盖 Java 基础数据类型、集合框架、JVM 内存模型及垃圾回收机制、多线程并发处理、Spring 容器原理及 AOP、MyBatis 映射配置等核心面试题。重点解析 HashMap 扩容、volatile 可见性、线程池参数调优及 Spring Bean 生命周期,帮助开发者系统梳理技术栈,应对面试挑战。
ByteFlow0 浏览 一、基础篇
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。基本类型声明时自动分配空间,引用类型需实例化。数组赋值仅复制引用,修改一个会影响另一个。
1.4 标识符命名规则
标识符可包含字母、数字、$、_,不能以数字开头且非关键字。规范上,类名用大驼峰(如 MyClass),变量和方法名用小驼峰(如 myMethod)。
1.5 instanceof 关键字
用于测试对象是否为类的实例。用法:boolean result = obj instanceof Class。若 obj 为 null 则返回 false。编译器会检查类型转换可行性,无法确定的类型在运行时判断。
1.6 自动装箱与拆箱
装箱:基本类型转包装器类型(如 int -> Integer),调用 valueOf()。
拆箱:包装器类型转基本类型(如 Integer -> int),调用 intValue()。
面试题:
public class Main {
public {
; ;
; ;
System.out.println(i1 == i2);
System.out.println(i3 == i4);
}
}
static
void
main
(String[] args)
Integer
i1
=
100
Integer
i2
=
100
Integer
i3
=
200
Integer
i4
=
200
原因:Integer.valueOf() 内部使用缓存池 [-128, 127]。在此范围内返回缓存对象引用,范围外创建新对象。
1.7 重载与重写
重写 (Override):发生在父子类之间,方法名、参数列表、返回类型必须相同,访问权限不能更低,不能抛出更宽泛的异常。
重载 (Overload):同一类中,同名方法参数列表不同(类型、个数、顺序),返回值类型不影响重载判定。
1.8 equals 与 == 的区别
== 比较内存地址(指针操作),对于基本类型比较值。
equals 比较内容,默认调用 Object.equals 等同于 ==,通常需重写(如 String)。阿里规范建议常量在前写 str.equals(obj) 防止空指针。
1.9 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。
- Null 支持:HashMap 允许 key 为 null(唯一),value 可为 null;Hashtable 不允许。
- 线程安全:HashMap 不安全,Hashtable 全方法加锁。高并发推荐 ConcurrentHashMap(分段锁)。
- 扩容:HashMap 初始 16,Hashtable 11。
1.13 Collection 与 Collections
Collection 是集合根接口(List, Set 等)。
Collections 是工具类,提供静态方法(排序、同步等),不可实例化。
1.14 引用类型(强、软、弱、虚)
- 强引用:OOM 也不回收(如
new String())。
- 软引用:内存不足时回收,适合缓存。
- 弱引用:GC 发现即回收,如 WeakHashMap。
- 虚引用:回收前放入 ReferenceQueue,用于资源释放。
1.15 泛型
Java SE 1.5+ 引入,实现代码重用。编译期检查类型安全,运行期存在类型擦除。
1.16 创建对象方式
1.17 Hash 冲突处理
1.18 深拷贝与浅拷贝
浅拷贝只复制对象本身,引用仍指向原对象;深拷贝连同引用的对象一起复制。
1.19 final 用法
修饰类不可继承,方法不可重写,变量不可变。final 域有重排序规则限制,利于优化。
1.20 static 用法
静态变量/方法共享,静态块初始化,静态内部类,静态导包。
1.21 浮点数精度
3 * 0.1 == 0.3 返回 false,因浮点数无法精确表示。
1.22 += 与 + 的区别
+= 有隐式类型转换,a += b 等价于 a = (type)(a + b),而 a = a + b 无转换,可能导致编译错误。
1.23 try catch finally
finally 总会执行。return 表达式运算后保存值,finally 执行不改变该值。finally 中不建议 return。
1.24 Exception 与 Error
- RuntimeException:编译器不检查,如 NullPointerException。
- CheckedException:必须处理,如 IOException。
- Error:系统级错误,如 OutOfMemoryError。
1.25 OOM 与 SOF
- OOM:堆溢出(对象过多)、栈溢出(递归过深)、元空间溢出(类加载过多)。
- SOF:StackOverflowError,通常由死循环或深层递归引起。
1.26 线程、进程、程序
程序是静态文件,进程是动态执行单元,线程是进程内更小执行单位,共享内存资源。
1.27 线程状态
新建、可运行、运行、阻塞(等待、同步、其他)、死亡。
1.28 IO 流分类
1.29 反射机制
运行时获取类信息并调用方法。用于 JDBC、框架。缺点性能低、破坏封装。可通过 setAccessible 优化。
1.30 List, Set, Map 区别
List 有序可重复,Set 无序不重复,Map 键值对存储。
二、JVM 篇
2.1 JVM 内存模型
- 线程私有:程序计数器、虚拟机栈、本地方法栈。
- 线程共享:堆、方法区。
2.2 内存区域详解
- 栈:存储局部变量表、操作栈等,方法调用入栈,返回出栈。
- 堆:存放对象实例,分新生代(Eden, Survivor)和老年代。
- 方法区:存储类信息、常量、静态变量。JDK 1.8 后为元空间。
2.3 类加载与卸载
加载、验证、准备、解析、初始化。双亲委派模式避免重复加载和 API 篡改。分代回收算法针对不同存活周期对象采用不同策略。
2.4 垃圾回收算法
标记 - 清除、复制、标记 - 压缩。常用分代收集(G1, ZGC)。G1 将堆分为 Region,减少停顿时间。
2.5 堆和栈的区别
栈存逻辑(局部变量),堆存数据(对象)。栈连续无碎片,堆不连续可能有碎片。栈小堆大。
2.6 Full GC 触发条件
旧生代不足、PermGen/Metaspace 满、CMS 失败、Minor GC 晋升平均大于剩余空间。
2.7 JVM 是什么
2.8 对象结构
对象头(Mark Word, Klass Pointer)、实例数据、对齐填充。
2.9 对象分配规则
优先 Eden 区,大对象进老年代,长期存活进老年代,空间分配担保。
2.10 对象创建过程
检查常量池 -> 分配内存(TLAB)-> 初始化零值 -> 设置对象头。
2.11 类生命周期
加载、连接(验证、准备、解析)、初始化、使用、卸载。
2.12 判断对象存活
引用计数法(无法解决循环引用)、可达性分析(GC Roots)。
2.13 永久代回收
JDK 8 前永久代满会触发 Full GC。JDK 8 后元空间位于本地内存。
2.14 调优命令
jps, jstat, jmap, jhat, jstack, jinfo。
2.15 调优工具
jconsole, jvisualvm, MAT, GChisto。
2.16 Minor GC 与 Full GC
新生代不够用触发 Minor GC,堆内存不足或特定条件触发 Full GC。
2.17 垃圾回收机制
虚拟机自动管理,低优先级线程扫描未引用对象并回收。
2.18 类加载器
2.19 OOM 处理
排查内存泄漏(MAT 分析 dump)、调整堆参数(-Xmx)、优化代码减少对象创建。
2.20 JDK 1.8 变动
三、多线程&并发篇
3.1 实现多线程方式
继承 Thread、实现 Runnable、实现 Callable、线程池。
3.2 停止线程
推荐使用标志位中断,避免使用 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 wait/notify 位置
定义在 Object 类,因为锁属于对象而非线程。
3.8 synchronized 原理
底层依靠 monitorenter/monitorexit 指令。JDK 1.6 后优化了偏向锁、轻量级锁等。
3.9 interrupted 与 isInterrupted
3.10 synchronized vs ReentrantLock
synchronized 是关键字,ReentrantLock 是 API。后者支持公平锁、可中断、绑定多个条件。
3.11 线程顺序执行
使用 join() 方法,T3.join(T2), T2.join(T1)。
3.12 SynchronizedMap vs ConcurrentHashMap
3.13 线程安全定义
3.14 yield 方法
3.15 submit() 与 execute()
execute 无返回值,submit 返回 Future。
3.16 synchronized 使用场景
修饰实例方法(对象锁)、静态方法(类锁)、代码块(指定对象锁)。避免锁定 String 常量。
3.17 双重校验锁单例
public class Singleton {
private volatile static Singleton uniqueInstance;
private Singleton() {}
public static Singleton getInstance() {
if (uniqueInstance == null) {
synchronized (Singleton.class) {
if (uniqueInstance == null) {
uniqueInstance = new Singleton();
}
}
}
return uniqueInstance;
}
}
3.18 线程池理解
降低资源消耗、提高响应速度、便于管理。常用 Executors 创建(Fixed, Cached, Single, Scheduled)。
3.19 创建线程池
推荐通过 ThreadPoolExecutor 构造方法自定义参数,避免直接使用 Executors 导致 OOM。
四、Spring 篇
4.1 IOC 与 AOP
IOC(控制反转)将对象创建权交给容器,DI(依赖注入)是其实现方式。AOP(面向切面)封装横切逻辑(日志、事务)。
4.2 @Autowired vs @Resource
@Autowired 按类型注入,@Resource 默认按名称注入。
4.3 依赖注入方式
4.4 Spring 概述
轻量级 IoC/AOP 容器,简化企业应用开发。模块包括 Core, Context, AOP, Web, MVC 等。
4.5 Spring MVC 流程
DispatcherServlet -> HandlerMapping -> HandlerAdapter -> Controller -> ModelAndView -> ViewResolver -> View。
4.6 重定向与转发
forward: 转发,redirect: 重定向。
4.7 常用注解
@RequestMapping, @RequestBody, @ResponseBody。
4.8 AOP 实现
JDK 动态代理(接口)和 CGLIB(类)。AspectJ 为静态代理,Spring AOP 为动态代理。
4.9 Bean 生命周期
实例化 -> 属性注入 -> Aware 接口 -> BeanPostProcessor 前置 -> 初始化 -> BeanPostProcessor 后置 -> 销毁。
4.10 Bean 作用域
singleton, prototype, request, session, global-session。
4.11 设计模式
五、MyBatis 篇
5.1 MyBatis 简介
半 ORM 框架,关注 SQL,灵活度高,消除 JDBC 冗余。
5.2 优缺点
优点:灵活、解耦、兼容性好。缺点:SQL 编写工作量大、移植性差。
5.3 #{} 与 ${}
5.4 字段映射
5.5 分页原理
RowBounds 内存分页或插件拦截 SQL 添加物理分页语句。
5.6 批量插入
使用 ExecutorType.BATCH 模式,提交前不刷新。
5.7 延迟加载
基于 CGLIB 代理,调用关联属性时再查数据库。
5.8 缓存
一级缓存(Session 级),二级缓存(Namespace 级,需 Serializable)。
相关免费在线工具
- 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
- 加密/解密文本
使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
- Gemini 图片去水印
基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online