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