跳到主要内容Java 核心面试题与实战解析 | 极客日志Javajava算法
Java 核心面试题与实战解析
Java 核心面试题与实战解析涵盖了基础语法、集合框架、多线程并发、Web 技术、主流框架及中间件等 19 个模块。内容深入探讨 JDK 与 JRE 区别、HashMap 底层原理、线程池状态流转、锁升级机制及 Spring 生态配置等关键技术点,旨在帮助开发者系统梳理知识体系,提升面试通过率与技术深度。
1qazxsw20 浏览 本文整理了 Java 开发领域 19 个核心模块的 208 道高频面试题,涵盖基础、容器、并发、Web、框架及中间件等方向。内容旨在帮助开发者系统梳理知识体系,应对技术面试挑战。
Java 基础
JDK 和 JRE 有什么区别?
JDK(Java Development Kit)是开发工具包,提供了开发环境和运行环境;JRE(Java Runtime Environment)是运行环境,仅包含运行所需组件。
简单来说,如果你需要编写 Java 程序,必须安装 JDK;如果只需运行程序,安装 JRE 即可。JDK 内部其实包含了 JRE,同时还提供了编译器 javac 以及调试分析工具。
== 和 equals 的区别是什么?
== 对于基本类型比较的是值是否相同,对于引用类型比较的是内存地址是否一致。
equals 本质上也是 ==,但像 String、Integer 这类类重写了该方法,将其变成了值比较。
代码示例:
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 方法,默认比较的是引用地址。例如两个值相同的 Cat 对象,直接调用 equals 会返回 false。
两个对象的 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));
final 在 Java 中有什么作用?
- 修饰类:该类不能被继承。
- 修饰方法:该方法不能被子类重写。
- 修饰变量:成为常量,初始化后不可修改。
Java 中的 Math.round(-1.5) 等于多少?
等于 -1。因为在数轴上取值时,中间值(0.5)向右取整,所以正 0.5 往上取整,负 0.5 则是直接舍弃小数部分。
String 属于基础的数据类型吗?
不属于。Java 有 8 种基本数据类型(byte、boolean、char、short、int、float、long、double),String 属于对象。
Java 中操作字符串都有哪些类?它们之间有什么区别?
主要有 String、StringBuffer、StringBuilder。
- String:不可变对象,每次操作都会生成新对象,指针指向新对象。
- StringBuffer:可变对象,线程安全,性能略低。
- StringBuilder:可变对象,非线程安全,性能高于 StringBuffer。
建议单线程下用 StringBuilder,多线程下用 StringBuffer。
String str="i"与 String str=new String('i')一样吗?
如何将字符串反转?
使用 StringBuilder 或 StringBuffer 的 reverse() 方法。
String 类的常用方法都有那些?
包括 indexOf()、charAt()、replace()、trim()、split()、getBytes()、length()、toLowerCase()、toUpperCase()、substring()、equals() 等。
抽象类必须要有抽象方法吗?
普通类和抽象类有哪些区别?
- 普通类不能包含抽象方法,抽象类可以。
- 抽象类不能直接实例化,普通类可以。
抽象类能使用 final 修饰吗?
不能。final 表示不可继承,而抽象类的设计初衷就是为了让其他类继承,两者矛盾。
接口和抽象类有什么区别?
- 实现方式:子类用 extends 继承抽象类,用 implements 实现接口。
- 构造函数:抽象类可以有,接口不能有。
- 数量限制:类可以实现多个接口,但只能继承一个抽象类。
- 访问修饰符:接口方法默认为 public,抽象类方法可以是任意修饰符。
Java 中 IO 流分为几种?
按功能分:输入流(input)、输出流(output)。
按类型分:字节流和字符流。字节流按 8 位传输,字符流按 16 位传输。
BIO、NIO、AIO 有什么区别?
- BIO:同步阻塞式 IO,模式简单但并发处理能力低。
- NIO:同步非阻塞 IO,通过 Channel 通讯,支持多路复用。
- AIO:异步非阻塞 IO(NIO2),基于事件和回调机制。
Files 的常用方法都有哪些?
包括 exists()、createFile()、createDirectory()、delete()、copy()、move()、size()、read()、write() 等。
容器
Java 容器都有哪些?
主要分为 Collection 和 Map 两大类。
Collection 下有 List(ArrayList、LinkedList、Vector、Stack)和 Set(HashSet、LinkedHashSet、TreeSet)。
Map 下有 HashMap、LinkedHashMap、TreeMap、ConcurrentHashMap、Hashtable 等。
Collection 和 Collections 有什么区别?
- Collection:集合接口,List、Set 都是其子类。
- Collections:包装类,提供静态方法(如排序),不能被实例化。
List、Set、Map 之间的区别是什么?
- List:有序,可重复。
- Set:无序(HashSet),不可重复。
- Map:键唯一,值可重复。
HashMap 和 Hashtable 有什么区别?
- 存储:HashMap 允许 key 和 value 为 null,Hashtable 不允许。
- 线程安全:Hashtable 是线程安全的,HashMap 是非线程安全的。
- 推荐使用:Hashtable 是遗留类不建议使用,单线程用 HashMap,多线程用 ConcurrentHashMap。
如何决定使用 HashMap 还是 TreeMap?
如果需要快速插入、删除、定位,选 HashMap;如果需要按键有序遍历,选 TreeMap。
说一下 HashMap 的实现原理?
基于 Hash 算法。put(key, value) 时计算 hash 值存入 bucket。hash 冲突时使用链表或红黑树存储。冲突少用链表,冲突多用红黑树。
说一下 HashSet 的实现原理?
基于 HashMap 实现,底层用 HashMap 保存元素,不允许重复值。
ArrayList 和 LinkedList 的区别是什么?
- 数据结构:ArrayList 是动态数组,LinkedList 是双向链表。
- 随机访问:ArrayList 效率高,LinkedList 需移动指针。
- 增删效率:非首尾操作,LinkedList 优于 ArrayList。
频繁读取用 ArrayList,频繁增删用 LinkedList。
如何实现数组和 List 之间的转换?
- 数组转 List:Arrays.asList(array)
- List 转数组:list.toArray()
ArrayList 和 Vector 的区别是什么?
- 线程安全:Vector 使用 synchronized 线程安全,ArrayList 非线程安全。
- 扩容:Vector 扩容 1 倍,ArrayList 扩容 50%。
- 性能:ArrayList 优于 Vector。
Array 和 ArrayList 有何区别?
- 类型:Array 可存基本类型和对象,ArrayList 只能存对象。
- 大小:Array 固定,ArrayList 自动扩展。
- 方法:ArrayList 内置方法更多(如 addAll、removeAll)。
在 Queue 中 poll() 和 remove() 有什么区别?
- 相同点:都返回并删除第一个元素。
- 不同点:poll() 无元素返回 null,remove() 抛出异常。
哪些集合类是线程安全的?
Vector、Hashtable、Stack 是线程安全的。JDK 1.5 后,concurrent 包提供了 ConcurrentHashMap 等替代方案。
迭代器 Iterator 是什么?
提供遍历任何 Collection 的接口,取代了 Enumeration,允许在迭代过程中移除元素。
Iterator 怎么使用?有什么特点?
使用 hasNext() 判断,next() 获取元素。特点是更安全,遍历中修改集合会抛出 ConcurrentModificationException。
Iterator 和 ListIterator 有什么区别?
- 范围:Iterator 可遍历 Set 和 List,ListIterator 只能遍历 List。
- 方向:Iterator 单向,ListIterator 双向。
- 功能:ListIterator 支持添加、替换、获取索引。
怎么确保一个集合不能被修改?
使用 Collections.unmodifiableCollection(Collection c) 创建只读集合,修改会抛出 UnsupportedOperationException。
多线程
并行和并发有什么区别?
- 并行:多核处理器同时处理多个任务。
- 并发:单核 CPU 通过时间片轮流执行多个任务,逻辑上同时。
线程和进程的区别?
一个程序至少有一个进程,一个进程至少有一个线程。多线程可增加执行速度。
守护线程是什么?
运行在后台的特殊进程,独立于控制终端,如垃圾回收线程。
创建线程有哪几种方式?
- 继承 Thread 重写 run 方法。
- 实现 Runnable 接口。
- 实现 Callable 接口。
说一下 runnable 和 callable 有什么区别?
runnable 无返回值,callable 有返回值,callable 可看作是 runnable 的补充。
线程有哪些状态?
NEW、RUNNABLE、BLOCKED、WAITING、TIMED_WAITING、TERMINATED。
sleep() 和 wait() 有什么区别?
- 来源:sleep() 来自 Thread,wait() 来自 Object。
- 锁:sleep() 不释放锁,wait() 释放锁。
- 唤醒:sleep() 时间到自动恢复,wait() 需 notify()/notifyAll() 唤醒。
notify() 和 notifyAll() 有什么区别?
notify() 唤醒一个线程,notifyAll() 唤醒所有线程。notifyAll() 会将全部线程由等待池移到锁池参与竞争。
线程的 run() 和 start() 有什么区别?
start() 启动线程,run() 执行代码。run() 可重复调用,start() 只能调用一次。
创建线程池有哪几种方式?
常见方式包括 newSingleThreadExecutor、newCachedThreadPool、newFixedThreadPool、newScheduledThreadPool、newWorkStealingPool 等。最核心的是 ThreadPoolExecutor,上面方式多为对其封装。
线程池都有哪些状态?
RUNNING、SHUTDOWN、STOP、TIDYING、TERMINATED。
线程池中 submit() 和 execute() 方法有什么区别?
execute() 只能执行 Runnable,submit() 可执行 Runnable 和 Callable(可获取返回值)。
在 Java 程序中怎么保证多线程的运行安全?
- 使用安全类(如 concurrent 包)。
- 使用 synchronized 锁。
- 使用 Lock 手动锁。
多线程中 synchronized 锁升级的原理是什么?
锁升级是为了降低性能消耗。从偏向锁升级为轻量级锁,再升级为重量级锁。Java 6 后优化了 synchronized 实现,减少了用户态到内核态的切换开销。
什么是死锁?
线程 A 持有锁 a 请求锁 b,线程 B 持有锁 b 请求锁 a,互相阻塞无法继续执行。
怎么防止死锁?
- 使用 tryLock 设置超时时间。
- 使用 concurrent 包代替手写锁。
- 降低锁粒度,减少同步代码块。
ThreadLocal 是什么?有哪些使用场景?
为每个线程提供独立变量副本,互不影响。经典场景:数据库连接管理、Session 管理。
说一下 synchronized 底层实现原理?
由 monitorenter/monitorexit 指令实现。Java 6 前是重量级锁,之后引入偏向锁、轻量级锁、重量级锁三种 monitor 实现,大幅提升性能。
synchronized 和 volatile 的区别是什么?
- 修饰:volatile 修饰变量,synchronized 修饰类、方法、代码段。
- 原子性:volatile 仅保证可见性,synchronized 保证可见性和原子性。
- 阻塞:volatile 不阻塞,synchronized 可能阻塞。
synchronized 和 Lock 有什么区别?
- 范围:synchronized 可修饰类、方法、代码块,Lock 只能代码块。
- 释放:synchronized 自动释放,Lock 需手动释放。
- 检测:Lock 可判断是否获取成功,synchronized 不行。
synchronized 和 ReentrantLock 区别是什么?
ReentrantLock 更灵活但需手动释放,synchronized 使用简单且异常自动释放。Java 6 后 synchronized 性能已大幅改进。
说一下 atomic 的原理?
利用 CAS (Compare And Swap) 和 volatile 及 native 方法保证原子操作,避免 synchronized 高开销。
反射
什么是反射?
运行时动态获取类的属性和方法,动态调用对象方法的功能。
什么是 Java 序列化?什么情况下需要序列化?
保存对象内存状态以便后续读取。场景:保存到文件/数据库、网络传输、RMI 远程调用。
动态代理是什么?有哪些应用?
运行时动态生成代理类。应用:Spring AOP、Hibernate 查询、RPC、注解处理等。
怎么实现动态代理?
JDK 原生代理基于接口,CGLIB 基于继承子类。
对象拷贝
为什么要使用克隆?
当需要新对象保存当前对象的状态,而 new 出来的对象属性均为初始值时,使用克隆。
如何实现对象克隆?
- 实现 Cloneable 接口并重写 clone()。
- 实现 Serializable 接口,通过序列化反序列化实现深度克隆。
深拷贝和浅拷贝区别是什么?
- 浅拷贝:只复制对象本身和值类型成员,引用类型未复制。
- 深拷贝:复制对象及其所有成员变量。
Java Web
JSP 和 servlet 有什么区别?
JSP 是 servlet 的简易方式,侧重视图;Servlet 侧重控制逻辑,Java 与 HTML 分离更好。
JSP 有哪些内置对象?作用分别是什么?
request(请求参数)、response(响应)、pageContext(获取其他对象)、session(会话)、application(全局环境)、out(输出流)、config(配置)、page(页面本身 this)、exception(异常)。
说一下 JSP 的 4 种作用域?
- page:页面相关。
- request:请求相关。
- session:会话相关。
- application:全局相关。
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
- Base64 字符串编码/解码
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online