跳到主要内容
极客日志极客日志
首页博客AI提示词GitHub精选代理工具
搜索
|注册
博客列表
Javajava

Java 核心面试知识点梳理与实战解析

Java 面试涵盖基础语法、集合框架、多线程并发、IO 模型、反射序列化及主流框架等核心领域。内容深入讲解 equals/hashCode 机制、HashMap 底层原理、线程池状态与锁升级、BIO/NIO/AIO 区别等高频考点。结合代码示例与源码分析,帮助开发者系统梳理知识体系,提升面试应对能力。

宁静发布于 2026/2/120 浏览
Java 核心面试知识点梳理与实战解析

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 即可;如果需要编写 Java 程序,则必须安装 JDK。

2. == 和 equals 的区别是什么?

== 解读 对于基本类型和引用类型,== 的作用效果不同:

  • 基本类型:比较的是值是否相同。
  • 引用类型:比较的是引用地址是否相同。
String x = "string";
String y = "string";
String z = new String("string");
System.out.println(x == y); // true
System.out.println(x == z); // false
System.out.println(x.equals(y)); // true
System.out.println(x.equals(z)); // true

x 和 y 指向常量池中的同一个对象,所以 == 为 true。new String() 开辟了新的堆内存空间,所以 == 为 false。而 equals 默认比较引用,但 String 类重写了该方法,改为比较内容值。

equals 解读 Object 类的 equals 方法本质上就是 ==。看下面的自定义类示例:

class Cat {
    public Cat(String name) { this.name = name; }
    private String name;
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
}
Cat c1 = new Cat("王磊");
Cat c2 = new Cat("王磊");
System.out.println(c1.equals(c2)); // false

输出结果为 false,因为默认情况下比较的是内存地址。进入 Object 源码可见:return (this == obj);。

而 String 类重写了 equals 方法,将引用比较改成了值比较,所以两个内容相同的 String 对象 equals 返回 true。

总结:== 对基本类型比值,对引用类型比地址;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));

执行结果会显示两者的 hashCode 相同(哈希冲突),但 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')一样吗?

不一样,内存分配方式不同。

  • String str="i":分配到常量池中。
  • String str=new String("i"):分配到堆内存中。

9. 如何将字符串反转?

使用 StringBuilder 或 StringBuffer 的 reverse() 方法。

// StringBuffer
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append("abcdefg");
System.out.println(stringBuffer.reverse()); // gfedcba

// StringBuilder
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("abcdefg");
System.out.println(stringBuilder.reverse()); // gfedcba

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 修饰吗?

不能。final 表示不可继承,这与抽象类的设计目的矛盾,编译器会报错。

14. 接口和抽象类有什么区别?

  • 实现:抽象类子类用 extends,接口用 implements。
  • 构造函数:抽象类可以有,接口不能有。
  • 数量:类可实现多个接口,但只能继承一个抽象类。
  • 修饰符:接口方法默认 public,抽象类方法任意。

15. Java 中 IO 流分为几种?

  • 按功能:输入流(input)、输出流(output)。
  • 按类型:字节流和字符流。
  • 区别:字节流按 8 位传输,字符流按 16 位传输。

16. BIO、NIO、AIO 有什么区别?

  • BIO:Block IO,同步阻塞式 IO,模式简单但并发能力低。
  • NIO:Non IO,同步非阻塞 IO,通过 Channel 通讯,支持多路复用。
  • AIO:Asynchronous IO,异步非阻塞 IO,基于事件和回调机制。

17. Files 的常用方法有哪些?

  • exists(): 检测路径是否存在。
  • createFile()/createDirectory(): 创建文件/目录。
  • delete(): 删除。
  • copy()/move(): 复制/移动。
  • size(): 查看大小。
  • read()/write(): 读写。

容器

18. Java 容器都有哪些?

主要分为 Collection 和 Map 两大类。

  • 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:无序(部分实现有序),不可重复。
  • 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 保存元素,不允许重复值。相关操作直接调用 HashMap 方法。

25. ArrayList 和 LinkedList 的区别是什么?

  • 结构:ArrayList 是动态数组,LinkedList 是双向链表。
  • 随机访问:ArrayList 效率高,LinkedList 需遍历。
  • 增删:非首尾操作 LinkedList 效率较高,ArrayList 需移动下标。
  • 建议:频繁读取用 ArrayList,频繁增删用 LinkedList。

26. 如何实现数组和 List 之间的转换?

  • 数组转 List:Arrays.asList(array)
  • List 转数组:list.toArray()
// list to array
List<String> list = new ArrayList<>();
list.add("王磊");
list.toArray();

// array to list
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. 创建线程有哪几种方式?

  1. 继承 Thread 重写 run 方法。
  2. 实现 Runnable 接口。
  3. 实现 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():工作窃取算法,并行处理。

45. 线程池都有哪些状态?

  • RUNNING:接受新任务,处理等待队列。
  • SHUTDOWN:不接受新任务,继续处理。
  • STOP:不接受新任务,中断正在执行任务。
  • TIDYING:任务销毁,workCount 为 0,执行 terminated()。
  • TERMINATED:terminated() 结束后状态。

46. 线程池中 submit() 和 execute() 方法有什么区别?

  • execute():只能执行 Runnable。
  • submit():可执行 Runnable 和 Callable,可获取返回值。

47. 在 Java 程序中怎么保证多线程的运行安全?

  1. 使用安全类(java.util.concurrent)。
  2. 使用 synchronized 锁。
  3. 使用 Lock 手动锁。
Lock lock = new ReentrantLock();
lock.lock();
try {
    System.out.println("获得锁");
} finally {
    System.out.println("释放锁");
    lock.unlock();
}

48. 多线程中 synchronized 锁升级的原理是什么?

锁升级是为了降低性能消耗。Java 6 后优化为:偏向锁 -> 轻量级锁 -> 重量级锁。

  • 偏向锁:首次访问设置线程 ID,再次访问直接匹配。
  • 轻量级锁:不一致时自旋循环获取锁。
  • 重量级锁:自旋失败后升级为重量级锁,依赖操作系统互斥量。

49. 什么是死锁?

线程 A 持有锁 a 请求锁 b,线程 B 持有锁 b 请求锁 a,互相阻塞无法继续。

50. 怎么防止死锁?

  • 使用 tryLock 设置超时时间。
  • 使用 java.util.concurrent 并发类代替手写锁。
  • 降低锁粒度,减少同步代码块。

51. ThreadLocal 是什么?有哪些使用场景?

为每个线程提供独立变量副本,互不影响。经典场景:数据库连接、Session 管理。

52. 说一下 synchronized 底层实现原理?

由 monitorenter/monitorexit 指令实现。Java 6 前依赖操作系统互斥锁(重量级),Java 6 后引入三种锁实现改进性能。

53. synchronized 和 volatile 的区别是什么?

  • 修饰:volatile 修饰变量,synchronized 修饰类/方法/代码块。
  • 原子性:volatile 仅保证可见性,synchronized 保证可见性和原子性。
  • 阻塞:volatile 不阻塞,synchronized 可能阻塞。

54. synchronized 和 Lock 有什么区别?

  • 范围:synchronized 可修饰类/方法/块,Lock 仅代码块。
  • 释放:synchronized 自动释放,Lock 需手动 unlock,不当使用易死锁。
  • 判断:Lock 可判断是否获取成功,synchronized 不行。

55. synchronized 和 ReentrantLock 区别是什么?

  • 灵活性:ReentrantLock 更灵活,但需配合释放。
  • 使用:synchronized 无需手动释放,ReentrantLock 必须手动。
  • 范围: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. 为什么要使用克隆?

当需要保存当前对象状态的新对象时,克隆方法可复制已修改的属性,而 new 出来的对象属性仍为初始值。

62. 如何实现对象克隆?

  1. 实现 Cloneable 接口并重写 clone() 方法。
  2. 实现 Serializable 接口,通过序列化和反序列化实现深度克隆。

63. 深拷贝和浅拷贝区别是什么?

  • 浅拷贝:复制对象本身及值类型成员,引用类型成员未复制。
  • 深拷贝:复制对象本身及所有成员变量(包括引用对象)。

目录

  1. Java 核心面试知识点梳理与实战解析
  2. Java 基础
  3. 1. JDK 和 JRE 有什么区别?
  4. 2. == 和 equals 的区别是什么?
  5. 3. 两个对象的 hashCode() 相同,则 equals() 也一定为 true,对吗?
  6. 4. final 在 Java 中有什么作用?
  7. 5. Java 中的 Math.round(-1.5) 等于多少?
  8. 6. String 属于基础的数据类型吗?
  9. 7. Java 中操作字符串都有哪些类?它们之间有什么区别?
  10. 8. String str="i"与 String str=new String(“i”)一样吗?
  11. 9. 如何将字符串反转?
  12. 10. String 类的常用方法有哪些?
  13. 11. 抽象类必须要有抽象方法吗?
  14. 12. 普通类和抽象类有哪些区别?
  15. 13. 抽象类能使用 final 修饰吗?
  16. 14. 接口和抽象类有什么区别?
  17. 15. Java 中 IO 流分为几种?
  18. 16. BIO、NIO、AIO 有什么区别?
  19. 17. Files 的常用方法有哪些?
  20. 容器
  21. 18. Java 容器都有哪些?
  22. 19. Collection 和 Collections 有什么区别?
  23. 20. List、Set、Map 之间的区别是什么?
  24. 21. HashMap 和 Hashtable 有什么区别?
  25. 22. 如何决定使用 HashMap 还是 TreeMap?
  26. 23. 说一下 HashMap 的实现原理?
  27. 24. 说一下 HashSet 的实现原理?
  28. 25. ArrayList 和 LinkedList 的区别是什么?
  29. 26. 如何实现数组和 List 之间的转换?
  30. 27. ArrayList 和 Vector 的区别是什么?
  31. 28. Array 和 ArrayList 有何区别?
  32. 29. 在 Queue 中 poll() 和 remove() 有什么区别?
  33. 30. 哪些集合类是线程安全的?
  34. 31. 迭代器 Iterator 是什么?
  35. 32. Iterator 怎么使用?有什么特点?
  36. 33. Iterator 和 ListIterator 有什么区别?
  37. 34. 怎么确保一个集合不能被修改?
  38. 多线程
  39. 35. 并行和并发有什么区别?
  40. 36. 线程和进程的区别?
  41. 37. 守护线程是什么?
  42. 38. 创建线程有哪几种方式?
  43. 39. 说一下 runnable 和 callable 有什么区别?
  44. 40. 线程有哪些状态?
  45. 41. sleep() 和 wait() 有什么区别?
  46. 42. notify() 和 notifyAll() 有什么区别?
  47. 43. 线程的 run() 和 start() 有什么区别?
  48. 44. 创建线程池有哪几种方式?
  49. 45. 线程池都有哪些状态?
  50. 46. 线程池中 submit() 和 execute() 方法有什么区别?
  51. 47. 在 Java 程序中怎么保证多线程的运行安全?
  52. 48. 多线程中 synchronized 锁升级的原理是什么?
  53. 49. 什么是死锁?
  54. 50. 怎么防止死锁?
  55. 51. ThreadLocal 是什么?有哪些使用场景?
  56. 52. 说一下 synchronized 底层实现原理?
  57. 53. synchronized 和 volatile 的区别是什么?
  58. 54. synchronized 和 Lock 有什么区别?
  59. 55. synchronized 和 ReentrantLock 区别是什么?
  60. 56. 说一下 atomic 的原理?
  61. 反射
  62. 57. 什么是反射?
  63. 58. 什么是 Java 序列化?什么情况下需要序列化?
  64. 59. 动态代理是什么?有哪些应用?
  65. 60. 怎么实现动态代理?
  66. 对象拷贝
  67. 61. 为什么要使用克隆?
  68. 62. 如何实现对象克隆?
  69. 63. 深拷贝和浅拷贝区别是什么?
  • 💰 8折买阿里云服务器限时8折了解详情
  • 💰 8折买阿里云服务器限时8折购买
  • 🦞 5分钟部署阿里云小龙虾了解详情
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog

更多推荐文章

查看全部
  • 具身智能年度报告:4 万次真机评测揭示模型真实能力,榜首成功率仅 51%
  • 仓颉语言 MVVM 架构实现与现代 UI 最佳实践
  • Python Selenium 自动化测试实战:从入门到企业级应用
  • 基于自然语言交互的 AI 爬虫工具实战解析
  • Ubuntu 25.04 物理机安装指南
  • 腾讯开源 HunyuanVideo 1.5:8.3B 参数模型支持消费级显卡部署
  • AI 网关实战:使用 Vercel AI Gateway 快速接入大模型
  • 2025 年 AI IDE 深度评测:从功能效率转向生态壁垒
  • JDK 17 安装与环境配置实战指南
  • Pybind11 实战:让 Python 无缝调用 C++ 函数
  • 基于 FastAPI 自动构建 SSE MCP 服务器
  • FastGPT 集成 MCP 协议构建工具增强型智能体
  • 2024 年常见 Redis 面试题:同步机制详解
  • HTML/CSS 文本字体与字号设置实战指南
  • 生产环境部署 Java 11:关键注意事项与许可变更
  • 基于 Django 与 Vue 的大学生兼职管理系统设计与实现
  • 算法题解:LeetCode 389 找不同
  • 使用 Python 字典处理文本文件并上传至 Web 服务
  • 基于 Prefect 框架的 Python 可视化爬虫项目实战
  • 计算机图形学:基础概念与技术概览

相关免费在线工具

  • 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