跳到主要内容Java 面试核心考点与实战解析 | 极客日志Javajava算法
Java 面试核心考点与实战解析
Java 面试中的高频考点,涵盖基础语法、集合框架、多线程并发、IO 流、JVM 原理及 Spring 生态等核心内容。通过对比 JDK 与 JRE、equals 与 ==、HashMap 实现原理等经典问题,结合代码示例深入解析底层机制。旨在帮助开发者梳理知识体系,应对技术面试挑战。
21772838014 浏览 本文涵盖 Java 基础、容器、多线程、反射、Web、异常、网络、设计模式、Spring 全家桶、ORM、MQ、中间件、数据库及 JVM 等核心模块。
1. JDK 和 JRE 有什么区别?
- JDK:Java Development Kit,开发工具包,提供开发和运行环境。
- JRE:Java Runtime Environment,运行环境,仅包含运行所需组件。
简单来说,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));
x 和 y 指向常量池中的同一对象,所以为 true;new String() 开辟了堆内存,地址不同,故为 false。而 equals 默认比较引用,但 String 类重写了该方法进行值比较。
equals 的本质
Object 类的 equals 方法本质上就是 this == obj。String 和 Integer 等类重写了它,将其变为值比较。
class Cat {
public Cat(String name) { this.name = name; }
private String name;
public String getName() { return name; }
}
Cat c1 = new Cat("王磊");
();
System.out.println(c1.equals(c2));
Cat
c2
=
new
Cat
"王磊"
未重写 equals 时,即使内容相同,返回也是 false。因为比较的是地址。
3. 两个对象的 hashCode() 相同,则 equals() 也一定为 true,对吗?
不对。hashCode 相等只意味着哈希值相同,可能存在哈希冲突,此时 equals() 不一定为 true。
String str1 = "通话";
String str2 = "重地";
System.out.println(str1.hashCode() + " | " + str2.hashCode());
System.out.println(str1.equals(str2));
执行结果会显示 hash 码相同但 equals 为 false。散列表中键值对的哈希值相等并不代表键值对本身相等。
4. final 在 Java 中有什么作用?
- 修饰类:该类不能被继承(最终类)。
- 修饰方法:该方法不能被重写。
- 修饰变量:成为常量,必须初始化且不可修改。
5. Java 中的 Math.round(-1.5) 等于多少?
等于 -1。Math.round 采用四舍五入逻辑,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:可变,线程安全(synchronized),性能略低。
- StringBuilder:可变,非线程安全,性能高于 StringBuffer。
单线程下推荐 StringBuilder,多线程下推荐 StringBuffer。
8. String str="i"与 String str=new String('i')一样吗?
不一样。前者分配在常量池,后者分配在堆内存。如果常量池中已有该字符串,new String 会复用常量池的引用,但仍会在堆创建新对象。
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 表示不可继承,而抽象类旨在被继承,两者矛盾。
14. 接口和抽象类有什么区别?
- 实现方式:抽象类用 extends,接口用 implements。
- 构造函数:抽象类有,接口无。
- 继承数量:类可实现多个接口,但只能继承一个抽象类。
- 访问修饰符:接口方法默认为 public,抽象类方法任意。
15. Java 中 IO 流分为几种?
按功能分:输入流、输出流。
按类型分:字节流(8 位)、字符流(16 位)。
16. BIO、NIO、AIO 有什么区别?
- BIO:同步阻塞 IO,传统模式,并发能力低。
- NIO:同步非阻塞 IO,基于 Channel 和多路复用,支持高并发。
- AIO:异步非阻塞 IO(NIO2),基于事件和回调机制。
17. Files 的常用方法都有哪些?
- exists(): 检测路径是否存在
- createFile()/createDirectory(): 创建文件/目录
- delete(): 删除
- copy()/move(): 复制/移动
- read()/write(): 读写
18. Java 容器都有哪些?
- Collection: List (ArrayList, LinkedList), 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 允许 null,Hashtable 不允许。
- 线程安全:Hashtable 线程安全,HashMap 非线程安全。
- 推荐:单线程用 HashMap,多线程用 ConcurrentHashMap。
22. 如何决定使用 HashMap 还是 TreeMap?
- 插入/删除/定位:选 HashMap,效率更高。
- 有序遍历 Key:选 TreeMap。
23. 说一下 HashMap 的实现原理?
基于 Hash 算法。put(key, value) 时计算 key 的 hashCode,确定 bucket 位置。若 hash 冲突,链表存储;JDK 1.8+ 当链表过长时转为红黑树,提升查询效率。
24. 说一下 HashSet 的实现原理?
底层基于 HashMap。所有元素存入 HashMap 的 key 中,value 为固定对象 PRESENT。因此不允许重复值。
25. ArrayList 和 LinkedList 的区别是什么?
- 结构:ArrayList 动态数组,LinkedList 双向链表。
- 随机访问:ArrayList O(1),LinkedList O(n)。
- 增删:非首尾操作,LinkedList 更高效(无需移动数据)。
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 不安全。
- 扩容: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);
}
特点:Fail-Fast 机制,遍历时集合被修改会抛出 ConcurrentModificationException。
33. Iterator 和 ListIterator 有什么区别?
- 范围:Iterator 遍历 Set/List,ListIterator 仅遍历 List。
- 方向:Iterator 单向,ListIterator 双向。
- 功能:ListIterator 支持添加、替换元素及获取索引。
34. 怎么确保一个集合不能被修改?
使用 Collections.unmodifiableCollection() 创建只读视图,任何修改操作将抛出 UnsupportedOperationException。
35. 并行和并发有什么区别?
- 并行:多核 CPU 同时处理多个任务。
- 并发:单核 CPU 通过时间片轮转交替执行,宏观上同时。
36. 线程和进程的区别?
进程是资源分配单位,线程是调度执行单位。一个进程可包含多个线程,共享进程资源。
37. 守护线程是什么?
运行在后台的特殊线程,不阻止 JVM 退出。例如垃圾回收线程。
38. 创建线程有哪几种方式?
- 继承 Thread 类并重写 run()
- 实现 Runnable 接口
- 实现 Callable 接口(可返回值)
39. 说一下 runnable 和 callable 有什么区别?
Runnable 无返回值,Callable 有返回值且可抛异常。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() 唤醒所有。notifyAll 更安全,避免死锁风险。
43. 线程的 run() 和 start() 有什么区别?
start() 启动新线程执行 run();run() 只是普通方法调用,不会启动新线程。
44. 创建线程池有哪几种方式?
- newSingleThreadExecutor:单线程顺序执行
- newCachedThreadPool:缓存线程池,适合大量短时任务
- newFixedThreadPool:定长线程池
- newScheduledThreadPool:定时任务
- newWorkStealingPool:工作窃取,利用多核
- ThreadPoolExecutor:最原始方式,可自定义参数
45. 线程池都有哪些状态?
RUNNING、SHUTDOWN、STOP、TIDYING、TERMINATED。
46. 线程池中 submit() 和 execute() 方法有什么区别?
execute() 仅接受 Runnable;submit() 接受 Runnable 和 Callable,可获取 Future 返回值。
47. 在 Java 程序中怎么保证多线程的运行安全?
- 使用并发包(java.util.concurrent)
- synchronized 关键字
- Lock 显式锁
Lock lock = new ReentrantLock();
lock.lock();
try {
} finally {
lock.unlock();
}
48. 多线程中 synchronized 锁升级的原理是什么?
Java 6 后优化了 synchronized。锁状态从偏向锁 -> 轻量级锁(自旋) -> 重量级锁(OS 互斥量)。目的是减少性能消耗。
49. 什么是死锁?
两个或多个线程互相持有对方需要的锁,导致永久阻塞。
50. 怎么防止死锁?
- 设置超时时间 tryLock(timeout)
- 使用并发工具类代替手写锁
- 降低锁粒度
- 避免嵌套锁
51. ThreadLocal 是什么?有哪些使用场景?
为每个线程提供独立变量副本。常用于数据库连接管理、Session 管理等。
52. 说一下 synchronized 底层实现原理?
基于 monitorenter/monitorexit 指令。早期依赖 OS 互斥锁(重量级),Java 6 后引入偏向锁、轻量级锁优化性能。
53. synchronized 和 volatile 的区别是什么?
- 作用:volatile 修饰变量,synchronized 修饰块/方法/类。
- 原子性:volatile 不保证原子性,synchronized 保证。
- 阻塞:volatile 不阻塞,synchronized 可能阻塞。
54. synchronized 和 Lock 有什么区别?
- 灵活性:Lock 更灵活,需手动加锁释放;synchronized 自动释放。
- 异常处理:synchronized 异常自动释放,Lock 需 finally 释放。
- 获取状态:Lock 可判断是否获取成功。
55. synchronized 和 ReentrantLock 区别是什么?
ReentrantLock 功能更强(公平锁、中断响应),但需手动管理生命周期;synchronized 使用简单,JVM 优化后性能已大幅提升。
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. 深拷贝和浅拷贝区别是什么?
- 浅拷贝:复制对象本身及基本类型成员,引用类型仍指向原对象。
- 深拷贝:递归复制所有成员,完全独立。
64. JSP 和 servlet 有什么区别?
JSP 本质是 Servlet。Servlet 侧重控制逻辑,JSP 侧重视图展示,便于 HTML 嵌入。
65. JSP 有哪些内置对象?作用分别是什么?
request、response、pageContext、session、application、out、config、page、exception。共 9 个,分别封装请求、响应、会话、配置等信息。
66. 说一下 JSP 的 4 种作用域?
- page:页面级别
- request:请求级别
- session:会话级别
- application:全局级别
67. session 和 cookie 有什么区别?
- 存储位置:session 在服务端,cookie 在客户端。
- 安全性:cookie 易被篡改,session 更安全。
- 容量:cookie 有限制,session 取决于服务器内存。
相关免费在线工具
- 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