跳到主要内容
Java 核心面试题与答案详解 | 极客日志
Java java 算法
Java 核心面试题与答案详解 涵盖 Java 基础、容器、多线程、反射、Web 等核心考点。解析 JDK 与 JRE 区别、equals 与 == 差异、集合类线程安全策略及锁机制原理。适合面试准备与技术复盘。
栈溢出 发布于 2026/3/16 更新于 2026/4/26 2 浏览Java 核心面试题与答案详解
本文涵盖十九个模块,包括:Java 基础、容器、多线程、反射、对象拷贝、Java Web、异常、网络、设计模式、Spring/Spring MVC、Spring Boot/Spring Cloud、Hibernate、MyBatis、RabbitMQ、Kafka、Zookeeper、MySQL、Redis、JVM。
Java 基础
1. JDK 和 JRE 有什么区别?
JDK (Java Development Kit):Java 开发工具包,提供开发环境和运行环境。
JRE (Java Runtime Environment):Java 运行环境,为 Java 程序运行提供所需环境。
具体来说,JDK 包含了 JRE,同时还包含了编译 Java 源码的编译器 javac 以及调试和分析工具。简单来说:若只需运行 Java 程序,安装 JRE 即可;若要编写 Java 程序,则需安装 JDK。
2. == 和 equals 的区别是什么?
== 解读
对于基本类型和引用类型,== 的作用效果不同:
基本类型:比较的是值是否相同。
引用类型:比较的是引用地址是否相同。
String x = "string" ;
String y = "string" ;
String z = new String ("string" );
System.out.println(x == y);
System.out.println(x == z);
System.out.println(x.equals(y));
System.out.println(x.equals(z));
代码解读:x 和 y 指向常量池中的同一个引用,所以 == 为 true;new String() 开辟了新的堆内存空间,所以 == 结果为 false;equals 比较的是值,结果都为 true。
equals 解读
equals 本质上就是 ==,但 String 和 Integer 等类重写了该方法,将其变为值比较。
默认情况下 Object 类的 equals 源码如下:
public boolean equals (Object obj) {
return (this == obj);
}
当两个相同值的自定义对象比较时,输出结果为 false,因为默认比较的是引用。
而 String 重写了 equals 方法,将引用比较改为内容比较:
public {
( == anObject) { ; }
(anObject String) {
(String) anObject;
value.length;
(n == anotherString.value.length) {
v1[] = value;
v2[] = anotherString.value;
;
(n-- != ) {
(v1[i] != v2[i]) ;
i++;
}
;
}
}
;
}
boolean
equals
(Object anObject)
if
this
return
true
if
instanceof
String
anotherString
=
int
n
=
if
char
char
int
i
=
0
while
0
if
return
false
return
true
return
false
总结 :== 对基本类型比较值,对引用类型比较地址;equals 默认比较地址,但多数类(如 String、Integer)重写后比较值。
3. 两个对象的 hashCode() 相同,则 equals() 也一定为 true,对吗? 不对。hashCode() 相同,equals() 不一定为 true。
String str1 = "通话" ;
String str2 = "重地" ;
System.out.println(String.format("str1:%d | str2:%d" , str1.hashCode(), str2.hashCode()));
System.out.println(str1.equals(str2));
执行结果显示哈希值相同,但 equals 返回 false。在散列表中,哈希值相等仅表示键值对的哈希位置可能相同,并不代表键值对本身相等。
4. final 在 Java 中有什么作用?
修饰类:该类不能被继承。
修饰方法:该方法不能被重写。
修饰变量:称为常量,必须初始化且值不可修改。
5. Java 中的 Math.round(-1.5) 等于多少? 等于 -1。数轴上取值时,中间值(0.5)向右取整,正 0.5 往上取整,负 0.5 直接舍弃。
6. String 属于基础的数据类型吗? 不属于。基础类型有 8 种:byte、boolean、char、short、int、float、long、double。String 属于对象。
7. Java 中操作字符串都有哪些类?它们之间有什么区别? 主要有 String、StringBuffer、StringBuilder。
String :不可变对象,每次操作生成新对象。
StringBuffer / StringBuilder :可变对象,可在原有基础上操作。
区别 :StringBuffer 线程安全,StringBuilder 非线程安全但性能更高。单线程推荐 StringBuilder,多线程推荐 StringBuffer。
8. String str="i"与 String str=new String('i')一样吗?
9. 如何将字符串反转? 使用 StringBuilder 或 StringBuffer 的 reverse() 方法。
StringBuffer stringBuffer = new StringBuffer ();
stringBuffer.append("abcdefg" );
System.out.println(stringBuffer.reverse());
StringBuilder stringBuilder = new StringBuilder ();
stringBuilder.append("abcdefg" );
System.out.println(stringBuilder.reverse());
10. String 类的常用方法有哪些?
indexOf():返回指定字符索引。
charAt():返回指定索引处字符。
replace():字符串替换。
trim():去除两端空白。
split():分割字符串。
getBytes():返回 byte 数组。
length():返回长度。
toLowerCase() / toUpperCase():大小写转换。
substring():截取字符串。
equals():字符串比较。
11. 抽象类必须要有抽象方法吗? abstract class Cat {
public static void sayHi () {
System.out.println("hi~" );
}
}
12. 普通类和抽象类有哪些区别?
普通类不能包含抽象方法,抽象类可以。
抽象类不能直接实例化,普通类可以。
13. 抽象类能使用 final 修饰吗?
14. 接口和抽象类有什么区别?
实现方式 :抽象类用 extends,接口用 implements。
构造函数 :抽象类可以有,接口不能有。
数量限制 :类可实现多个接口,但只能继承一个抽象类。
访问修饰符 :接口方法默认为 public,抽象类方法可为任意修饰符。
15. Java 中 IO 流分为几种?
按功能:输入流(input)、输出流(output)。
按类型:字节流和字符流。
区别 :字节流按 8 位传输,字符流按 16 位传输。
16. BIO、NIO、AIO 有什么区别?
BIO (Block IO):同步阻塞式,模式简单,并发能力低。
NIO (Non Blocking IO):同步非阻塞,通过 Channel 通讯,支持多路复用。
AIO (Asynchronous IO):异步非阻塞,基于事件和回调机制。
17. Files 的常用方法有哪些?
exists():检测路径是否存在。
createFile() / createDirectory():创建文件/目录。
delete():删除文件/目录。
copy() / move():复制/移动文件。
size():查看文件大小。
read() / write():读写文件。
容器
18. Java 容器都有哪些?
Collection :List(ArrayList, LinkedList, Vector, Stack)、Set(HashSet, LinkedHashSet, TreeSet)。
Map :HashMap, LinkedHashMap, TreeMap, ConcurrentHashMap, Hashtable。
19. Collection 和 Collections 有什么区别?
Collection :集合接口,提供基本操作通用方法,所有集合都是其子类。
Collections :包装类,包含静态方法(如排序),不能被实例化。
20. List、Set、Map 之间的区别是什么?
List :有序,可重复。
Set :无序(HashSet),不可重复。
Map :键唯一,值可重复。
21. HashMap 和 Hashtable 有什么区别?
存储 :HashMap 允许 key 和 value 为 null,Hashtable 不允许。
线程安全 :Hashtable 线程安全,HashMap 非线程安全。
推荐 :Hashtable 是遗留类不建议使用。单线程用 HashMap,多线程用 ConcurrentHashMap。
22. 如何决定使用 HashMap 还是 TreeMap?
插入、删除、定位快:选 HashMap。
需要有序遍历 Key:选 TreeMap。
23. 说一下 HashMap 的实现原理? 基于 Hash 算法。put(key, value) 时计算 key.hashCode() 得到 hash 值,存入 bucket。hash 冲突时使用链表或红黑树存储。冲突少用链表,多用红黑树。
24. 说一下 HashSet 的实现原理? 基于 HashMap 实现,底层用 HashMap 保存元素,不允许重复值。
25. ArrayList 和 LinkedList 的区别是什么?
结构 :ArrayList 是动态数组,LinkedList 是双向链表。
随机访问 :ArrayList 效率高,LinkedList 需遍历。
增删效率 :非首尾操作,LinkedList 效率较高,ArrayList 需移动下标。
推荐 :频繁读取用 ArrayList,频繁增删用 LinkedList。
26. 如何实现数组和 List 之间的转换?
数组转 List:Arrays.asList(array)。
List 转数组:list.toArray()。
List<String> list = new ArrayList <>();
list.add("王磊" );
list.toArray();
String[] array = {"王磊" , "的博客" };
Arrays.asList(array);
27. ArrayList 和 Vector 的区别是什么?
线程安全 :Vector 使用 synchronized 线程安全,ArrayList 非线程安全。
性能 :ArrayList 优于 Vector。
扩容 :Vector 每次增加 1 倍,ArrayList 增加 50%。
28. Array 和 ArrayList 有何区别?
类型 :Array 可存基本类型和对象,ArrayList 只能存对象。
大小 :Array 固定大小,ArrayList 自动扩展。
方法 :ArrayList 内置方法更多(addAll, removeAll 等)。
29. 在 Queue 中 poll() 和 remove() 有什么区别?
相同点 :都返回并删除第一个元素。
不同点 :空队列时,poll() 返回 null,remove() 抛出 NoSuchElementException 异常。
30. 哪些集合类是线程安全的? Vector、Hashtable、Stack 是线程安全的。JDK 1.5 后并发包提供了 ConcurrentHashMap 替代 Hashtable。
31. 迭代器 Iterator 是什么? 提供遍历任何 Collection 的接口,取代 Enumeration,允许在迭代过程中移除元素。
32. Iterator 怎么使用?有什么特点? List<String> list = new ArrayList <>();
Iterator<String> it = list.iterator();
while (it.hasNext()) {
String obj = it.next();
System.out.println(obj);
}
特点:更安全,遍历时集合被修改会抛出 ConcurrentModificationException。
33. Iterator 和 ListIterator 有什么区别?
范围 :Iterator 遍历 Set 和 List,ListIterator 仅遍历 List。
方向 :Iterator 单向,ListIterator 双向。
功能 :ListIterator 可添加、替换元素及获取索引。
34. 怎么确保一个集合不能被修改? 使用 Collections.unmodifiableCollection(Collection c) 创建只读集合,修改操作会抛出 UnsupportedOperationException。
多线程
35. 并行和并发有什么区别?
并行 :多处理器同时处理多个任务。
并发 :单核 CPU 时间片轮流执行,逻辑上同时。
36. 线程和进程的区别? 一个程序至少有一个进程,一个进程至少有一个线程。多线程可增加执行速度。
37. 守护线程是什么? 运行在后台的特殊进程,独立于控制终端。例如垃圾回收线程。
38. 创建线程有哪几种方式?
继承 Thread 重写 run 方法。
实现 Runnable 接口。
实现 Callable 接口。
39. 说一下 runnable 和 callable 有什么区别? Runnable 无返回值,Callable 可获取返回值,Callable 是 Runnable 的补充。
40. 线程有哪些状态?
NEW:尚未启动。
RUNNABLE:正在执行。
BLOCKED:阻塞(锁或 IO)。
WAITING:永久等待。
TIMED_WAITING:等待指定时间。
TERMINATED:执行完成。
41. sleep() 和 wait() 有什么区别?
来源 :sleep() 来自 Thread,wait() 来自 Object。
锁 :sleep() 不释放锁,wait() 释放锁。
唤醒 :sleep() 时间到自动恢复,wait() 可用 notify()/notifyAll() 唤醒。
42. notify() 和 notifyAll() 有什么区别? notify() 唤醒一个线程,notifyAll() 唤醒所有线程。notifyAll() 将所有等待线程移至锁池参与竞争。
43. 线程的 run() 和 start() 有什么区别? start() 启动线程,run() 执行代码。run() 可重复调用,start() 只能调用一次。
44. 创建线程池有哪几种方式? 最核心的是 ThreadPoolExecutor,其他多为封装:
newSingleThreadExecutor():单线程,顺序执行。
newCachedThreadPool():缓存线程,大量短时间任务。
newFixedThreadPool(int nThreads):固定线程数。
newScheduledThreadPool():定时或周期性调度。
newWorkStealingPool():ForkJoinPool,工作窃取算法。
45. 线程池都有哪些状态?
RUNNING:接受新任务,处理等待队列。
SHUTDOWN:不接受新任务,处理等待队列。
STOP:不接受新任务,中断正在执行任务。
TIDYING:任务销毁,workCount 为 0,执行 terminated()。
TERMINATED:terminated() 结束后进入此状态。
46. 线程池中 submit() 和 execute() 方法有什么区别?
execute():仅执行 Runnable。
submit():可执行 Runnable 和 Callable,Callable 可获取返回值。
47. 在 Java 程序中怎么保证多线程的运行安全?
使用安全类(java.util.concurrent)。
使用 synchronized 锁。
使用 Lock 手动锁。
Lock lock = new ReentrantLock ();
lock.lock();
try {
System.out.println("获得锁" );
} finally {
System.out.println("释放锁" );
lock.unlock();
}
48. 多线程中 synchronized 锁升级的原理是什么? 锁对象头中有 threadid 字段。首次访问设为偏向锁,再次访问判断 threadid。不一致升级为轻量级锁(自旋),自旋失败升级为重量级锁。目的是降低锁带来的性能消耗。
49. 什么是死锁? 线程 A 持有锁 a 尝试获取锁 b,线程 B 持有锁 b 尝试获取锁 a,互相阻塞。
50. 怎么防止死锁?
使用 tryLock(long timeout, TimeUnit unit) 设置超时。
使用 java.util.concurrent 并发类代替手写锁。
降低锁粒度,减少同步代码块。
51. ThreadLocal 是什么?有哪些使用场景? 为每个线程提供独立变量副本,互不影响。经典场景:数据库连接、Session 管理。
52. 说一下 synchronized 底层实现原理? 由 monitorenter/monitorexit 指令实现。Java 6 前依赖操作系统互斥锁(重量级),Java 6 后引入偏向锁、轻量级锁、重量级锁三种 monitor 实现,改进性能。
53. synchronized 和 volatile 的区别是什么?
修饰 :volatile 修饰变量,synchronized 修饰类、方法、代码段。
原子性 :volatile 仅保证可见性,synchronized 保证可见性和原子性。
阻塞 :volatile 不阻塞,synchronized 可能阻塞。
54. synchronized 和 Lock 有什么区别?
范围 :synchronized 可修饰类、方法、代码块;Lock 仅代码块。
释放 :synchronized 自动释放,Lock 需手动 unlock。
反馈 :Lock 可获知是否成功获取锁。
55. synchronized 和 ReentrantLock 区别是什么?
ReentrantLock 更灵活,但必须配合释放锁动作。
synchronized 无需手动释放,不易死锁。
ReentrantLock 仅适用于代码块,synchronized 适用范围更广。
56. 说一下 atomic 的原理? 利用 CAS (Compare And Swap) 和 volatile 及 native 方法保证原子操作,避免 synchronized 高开销。
反射
57. 什么是反射? 运行状态下,任意类都能知道其属性和方法,任意对象都能调用其方法和属性。这种动态获取信息和调用的功能称为反射。
58. 什么是 Java 序列化?什么情况下需要序列化? 保存对象在内存中的状态,并可还原。适用场景:保存到文件/数据库、网络套接字传输、RMI 远程调用。
59. 动态代理是什么?有哪些应用? 运行时动态生成代理类。应用:Spring AOP、Hibernate 查询、Mock 测试、RPC、注解处理。
60. 怎么实现动态代理?
JDK 原生:基于接口。
CGLIB:基于继承当前类的子类。
对象拷贝
61. 为什么要使用克隆? 当需要新对象保存当前对象的'状态'时使用,特别是对象包含已修改的属性时。
62. 如何实现对象克隆?
实现 Cloneable 接口并重写 clone()。
实现 Serializable 接口,通过序列化和反序列化实现深度克隆。
63. 深拷贝和浅拷贝区别是什么?
浅拷贝 :复制对象本身及值类型成员,引用类型成员不复制。
深拷贝 :复制对象本身及所有成员变量(包括引用指向的对象)。
Java Web
64. JSP 和 servlet 有什么区别? JSP 是 Servlet 技术的扩展,本质是 Servlet。Servlet 逻辑在 Java 文件中,与 HTML 分离,侧重控制;JSP 是 Java 与 HTML 组合,侧重视图。
65. JSP 有哪些内置对象?作用分别是什么?
request:封装客户端请求参数。
response:封装服务器响应。
pageContext:获取其他对象。
session:封装用户会话。
application:封装服务器运行环境。
out:输出流对象。
config:Web 应用配置。
page:JSP 页面本身(相当于 this)。
exception:封装异常对象。
66. 说一下 JSP 的 4 种作用域?
page :与页面相关。
request :与一次请求相关。
session :与用户会话相关。
application :与整个 Web 应用相关(全局)。
67. session 和 cookie 有什么区别?
存储位置 :session 在服务端,cookie 在浏览器端。
安全性 :cookie 安全性一般,易伪造;session 相对安全。
容量限制 :cookie 有容量和个数限制;session 取决于服务端资源。
多样性 :session 可存 Redis、DB 等;cookie 仅浏览器。
相关免费在线工具 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