跳到主要内容Java 核心面试题精选:基础、并发与容器详解 | 极客日志Javajava
Java 核心面试题精选:基础、并发与容器详解
涵盖 Java 基础、集合、多线程等核心考点,解析 JDK/JRE 区别、equals/hashCode 原理、HashMap 实现及线程池状态等高频面试题。内容经过技术校对,修正代码细节,去除冗余推广信息,适合开发者系统复习。
本文整理了 Java 面试中的核心知识点,涵盖基础语法、集合框架、多线程编程等高频考点。以下内容基于实际开发经验总结,旨在帮助读者系统梳理知识体系。
Java 基础
1. JDK 和 JRE 有什么区别?
JDK(Java Development Kit)是开发工具包,提供了开发环境和运行环境;JRE(Java Runtime Environment)是运行环境,仅包含运行 Java 程序所需的组件。简单来说,如果你需要编写 Java 代码,必须安装 JDK;若仅需运行程序,安装 JRE 即可。JDK 内部其实包含了 JRE,同时还提供了编译器 javac 以及调试分析工具。
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));
equals 本质上默认也是比较引用(即 ==),但 String、Integer 等类重写了该方法,将其变为值比较。例如 Object 类的默认实现如下:
public boolean equals(Object obj) {
return (this == obj);
}
而 String 类则实现了字符数组的逐位比较,因此两个内容相同的 String 对象 equals 返回 true。
总结:== 对基本类型比值,对引用类型比地址;equals 默认比地址,但多数类重写后比值。
3. 两个对象的 hashCode() 相同,则 equals() 也一定为 true,对吗?
不对。hashCode 相等只意味着哈希值相同,可能存在哈希冲突,此时 equals() 不一定为 true。
String str1 = "通话";
String str2 = ;
System.out.println(String.format(, str1.hashCode(), str2.hashCode()));
System.out.println(str1.equals(str2));
"重地"
"str1:%d | str2:%d"
执行结果会显示 hashCode 相同但 equals 为 false,这符合散列表的设计原理。
4. final 在 Java 中有什么作用?
- 修饰类:该类不能被继承(最终类)。
- 修饰方法:该方法不能被子类重写。
- 修饰变量:成为常量,初始化后不可修改。
5. Java 中的 Math.round(-1.5) 等于多少?
等于 -1。round 方法的原理是'加 0.5 取整',负数时 -1.5 + 0.5 = -1.0,向上取整即为 -1。
6. String 属于基础的数据类型吗?
不属于。Java 有 8 种基本数据类型(byte, boolean, char, short, int, float, long, double),String 属于引用类型对象。
7. Java 中操作字符串都有哪些类?它们之间有什么区别?
主要有 String、StringBuffer 和 StringBuilder。
- String:不可变对象,每次修改都会生成新对象,适合少量操作。
- StringBuffer:线程安全,可变,性能略低。
- StringBuilder:非线程安全,可变,性能最高。
单线程下推荐 StringBuilder,多线程下推荐 StringBuffer。
8. String str="i"与 String str=new String("i")一样吗?
不一样。前者直接分配在字符串常量池中,后者会在堆内存开辟新空间。如果常量池中已存在 "i",则不会重复创建,但 new 关键字强制创建新对象。
9. 如何将字符串反转?
使用 StringBuilder 或 StringBuffer 的 reverse() 方法。
StringBuilder sb = new StringBuilder("abcdefg");
System.out.println(sb.reverse());
10. String 类的常用方法有哪些?
包括 indexOf()、charAt()、replace()、trim()、split()、getBytes()、length()、toLowerCase()、toUpperCase()、substring()、equals() 等。
11. 抽象类必须要有抽象方法吗?
12. 普通类和抽象类有哪些区别?
- 普通类可实例化,抽象类不可。
- 普通类不能有抽象方法,抽象类可以有。
13. 抽象类能使用 final 修饰吗?
不能。final 表示不可继承,abstract 表示需被继承,两者矛盾。
14. 接口和抽象类有什么区别?
- 继承方式:类继承抽象类用 extends,实现接口用 implements。
- 构造函数:抽象类有,接口无。
- 多重性:类可实现多个接口,但只能继承一个抽象类。
- 访问修饰符:接口方法默认为 public,抽象类方法任意。
15. Java 中 IO 流分为几种?
按功能分:输入流(Input)、输出流(Output)。
按类型分:字节流(8 位)、字符流(16 位)。
16. BIO、NIO、AIO 有什么区别?
- BIO:同步阻塞 IO,模式简单但并发能力低。
- NIO:同步非阻塞 IO,基于 Channel 和多路复用,支持高并发。
- AIO:异步非阻塞 IO,基于事件和回调机制,效率更高。
17. Files 的常用方法有哪些?
exists()、createFile()、createDirectory()、delete()、copy()、move()、size()、read()、write() 等。
容器
18. Java 容器都有哪些?
主要分为 Collection 和 Map 两大类。Collection 下有 List(ArrayList, LinkedList 等)和 Set(HashSet, TreeSet 等);Map 下有 HashMap, TreeMap, ConcurrentHashMap 等。
19. Collection 和 Collections 有什么区别?
Collection 是集合接口,List、Set 都是其子类;Collections 是工具类,提供排序、同步等静态方法。
20. List、Set、Map 之间的区别是什么?
- List:有序,允许重复。
- Set:无序(部分实现有序),不允许重复。
- Map:键值对存储,Key 唯一。
21. HashMap 和 Hashtable 有什么区别?
- 空值:HashMap 允许 key/value 为 null,Hashtable 不允许。
- 线程安全:Hashtable 线程安全,HashMap 非线程安全。
- 性能:HashMap 性能更好,推荐使用 HashMap,多线程场景用 ConcurrentHashMap。
22. 如何决定使用 HashMap 还是 TreeMap?
需要快速插入删除选 HashMap;需要对 Key 进行有序遍历选 TreeMap。
23. 说一下 HashMap 的实现原理?
基于 Hash 算法。put(key, value) 时计算 key 的 hash 值定位 bucket。若 hash 冲突,链表法存储(Java 8 后冲突多转为红黑树)。get(key) 时通过 hash 定位并比较 equals。
24. 说一下 HashSet 的实现原理?
HashSet 底层基于 HashMap 实现,所有元素作为 HashMap 的 key 存储,value 统一为一个固定对象 PRESENT,因此不允许重复。
25. ArrayList 和 LinkedList 的区别是什么?
- 结构:ArrayList 是动态数组,LinkedList 是双向链表。
- 随机访问:ArrayList O(1),LinkedList O(n)。
- 增删:非首尾位置,LinkedList 优于 ArrayList(无需移动元素)。
26. 如何实现数组和 List 之间的转换?
- 数组转 List:Arrays.asList(array)
- List 转数组:list.toArray()
List<String> list = new ArrayList<>();
list.add("王磊");
String[] arr = list.toArray(new String[0]);
27. ArrayList 和 Vector 的区别是什么?
Vector 线程安全(synchronized),扩容翻倍;ArrayList 非线程安全,扩容 50%。Vector 较老,建议用 ArrayList 配合并发包替代。
28. Array 和 ArrayList 有何区别?
Array 可存基本类型和对象,大小固定;ArrayList 只能存对象,大小动态扩展,内置更多工具方法。
29. 在 Queue 中 poll() 和 remove() 有什么区别?
都返回并删除第一个元素。poll() 为空返回 null,remove() 为空抛异常。
30. 哪些集合类是线程安全的?
Vector、Hashtable、Stack 是线程安全的。JDK 1.5+ 后推荐使用 ConcurrentHashMap 替代 Hashtable,CopyOnWriteArrayList 替代 Vector。
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(c) 创建只读视图,任何修改操作将抛出 UnsupportedOperationException。
多线程
35. 并行和并发有什么区别?
- 并行:多核 CPU 同时处理多个任务。
- 并发:单核 CPU 时间片轮转,逻辑上同时执行。
36. 线程和进程的区别?
进程是资源分配单位,线程是 CPU 调度单位。一个进程至少有一个线程,多线程可提高执行效率。
37. 守护线程是什么?
运行在后台的服务线程,如垃圾回收线程。当所有用户线程结束时,守护线程自动结束。
38. 创建线程有哪几种方式?
- 继承 Thread 类并重写 run。
- 实现 Runnable 接口。
- 实现 Callable 接口(可返回值)。
39. 说一下 runnable 和 callable 有什么区别?
Runnable 无返回值,Callable 可返回结果且可能抛出异常。
40. 线程有哪些状态?
NEW(新建)、RUNNABLE(运行/就绪)、BLOCKED(阻塞)、WAITING(等待)、TIMED_WAITING(计时等待)、TERMINATED(终止)。
41. sleep() 和 wait() 有什么区别?
- 来源:sleep 属 Thread,wait 属 Object。
- 锁:sleep 不释放锁,wait 释放锁。
- 唤醒:sleep 时间到自动恢复,wait 需 notify/notifyAll。
42. notify() 和 notifyAll() 有什么区别?
notify() 唤醒一个等待线程,notifyAll() 唤醒所有等待线程。
43. 线程的 run() 和 start() 有什么区别?
start() 启动新线程执行 run(),run() 只是普通方法调用。start() 只能调用一次。
44. 创建线程池有哪几种方式?
常见方式包括 newSingleThreadExecutor、newCachedThreadPool、newFixedThreadPool、newScheduledThreadPool 等,最底层均为 ThreadPoolExecutor。
45. 线程池都有哪些状态?
RUNNING(运行)、SHUTDOWN(关闭)、STOP(停止)、TIDYING(整理)、TERMINATED(终止)。
46. 线程池中 submit() 和 execute() 方法有什么区别?
execute() 仅接受 Runnable,无返回值;submit() 接受 Runnable 或 Callable,可获取 Future 返回值。
47. 在 Java 程序中怎么保证多线程的运行安全?
- 使用并发包类(如 ConcurrentHashMap)。
- 使用 synchronized 锁。
- 使用 Lock 显式锁。
Lock lock = new ReentrantLock();
lock.lock();
try {
} finally {
lock.unlock();
}
48. 多线程中 synchronized 锁升级的原理是什么?
Java 6 后优化为偏向锁 -> 轻量级锁 -> 重量级锁。目的是减少锁竞争带来的性能开销。初始为偏向锁,无竞争时直接持有;有竞争升级为轻量级自旋;竞争激烈时升级为重量级 OS 互斥锁。
49. 什么是死锁?
两个或多个线程互相持有对方需要的锁,导致永久阻塞的现象。
50. 怎么防止死锁?
- 设置超时时间 tryLock。
- 使用并发工具类代替手写锁。
- 降低锁粒度,避免嵌套锁。
51. ThreadLocal 是什么?有哪些使用场景?
为每个线程提供独立的变量副本,互不干扰。常用于数据库连接管理、Session 管理等。
52. 说一下 synchronized 底层实现原理?
基于 monitorenter/monitorexit 指令。早期依赖操作系统重量级锁,Java 6 后引入偏向锁、轻量级锁优化性能。
53. synchronized 和 volatile 的区别是什么?
- volatile 保证可见性,不保证原子性;synchronized 保证两者。
- volatile 不阻塞线程,synchronized 可能阻塞。
54. synchronized 和 Lock 有什么区别?
synchronized 自动释放锁,Lock 需手动 unlock;Lock 可尝试获取锁,synchronized 不可。
55. synchronized 和 ReentrantLock 区别是什么?
ReentrantLock 更灵活,支持公平锁、中断响应等,但需手动释放;synchronized 语法糖,使用简单。
56. 说一下 atomic 的原理?
利用 CAS(Compare And Swap)和 volatile 保证原子操作,避免 synchronized 的高开销。
反射
57. 什么是反射?
运行时动态获取类的属性、方法信息,并调用对象的方法。是框架设计的基石。
58. 什么是 Java 序列化?什么情况下需要序列化?
将对象状态保存为字节流。适用于网络传输、RMI、持久化存储等场景。
59. 动态代理是什么?有哪些应用?
运行时动态生成代理类。应用包括 Spring AOP、Hibernate 查询、RPC 等。
60. 怎么实现动态代理?
JDK 原生代理基于接口,CGLIB 基于继承子类。
对象拷贝
61. 为什么要使用克隆?
需要复制对象当前状态,避免新对象受原对象后续修改影响。
62. 如何实现对象克隆?
- 实现 Cloneable 接口重写 clone()。
- 实现 Serializable 接口,通过序列化和反序列化实现深度克隆。
63. 深拷贝和浅拷贝区别是什么?
浅拷贝只复制基本类型和引用地址;深拷贝递归复制所有成员对象。
Java Web
64. JSP 和 servlet 有什么区别?
JSP 本质是 Servlet,侧重视图展示;Servlet 侧重控制逻辑。JSP 编译后也是 Servlet。
65. JSP 有哪些内置对象?
request、response、pageContext、session、application、out、config、page、exception。
66. 说一下 JSP 的 4 种作用域?
page(页面)、request(请求)、session(会话)、application(全局)。
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
- Base64 字符串编码/解码
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
- Base64 文件转换器
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online