跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
Javajava算法

Java 面试核心考点解析:基础、JVM 与并发编程实战

涵盖 Java 面试的核心领域,包括基础语法、JVM 内存模型、垃圾回收机制、多线程并发编程以及 Spring 生态系统的 IOC、AOP 和 Bean 生命周期。内容梳理了 HashMap 与 Hashtable 区别、volatile 关键字原理、线程池构建策略、MyBatis 分页机制及 Spring Boot 自动配置逻辑。旨在帮助开发者系统复习关键技术点,应对实际面试场景中的深度提问。

CodeArtist发布于 2026/3/26更新于 2026/10/2689 浏览
Java 面试核心考点解析:基础、JVM 与并发编程实战

一、基础篇

1.1 Java 语言有哪些特点
  1. 简单易学,拥有丰富的类库。
  2. 面向对象(Java 最重要的特性,降低程序耦合度,提高内聚性)。
  3. 与平台无关性(JVM 是 Java 跨平台使用的根本)。
  4. 可靠安全。
  5. 支持多线程。
1.2 面向对象和面向过程的区别

面向过程:分析解决问题的步骤,用函数实现。性能较高,常用于单片机、嵌入式开发。以函数为单位,逐步完成,后期维护可能牵一发而动全身。

面向对象:以对象为最小单位,将事务分解成各个对象。目的是描述事物在解决问题过程中的行为。具有封装、继承、多态特性,易维护、易复用、易扩展,能设计出低耦合系统。但性能略低于面向过程。

1.3 八种基本数据类型的大小及封装类
基本类型大小(字节)默认值封装类
byte1(byte)0Byte
short2(short)0Short
int40Integer
long80LLong
float40.0fFloat
double80.0dDouble
boolean-falseBoolean
char2\u0000Character

注:

  1. int 是基本类型,Integer 是引用类型。int 默认值为 0,Integer 为 null。这有助于区分 0 和 null。使用引用前必须实例化,否则会报错。
  2. 基本类型声明时自动分配空间;引用类型仅分配引用空间,需实例化开辟数据空间。数组赋值复制的是引用,修改一个会影响另一个。
  3. JVM 中无 boolean 专用字节码指令,表达式操作使用 int 代替,boolean 数组编码为 byte 数组。单用占 4 字节,数组中占 1 字节。这是为了适配 32 位 CPU 的高效存取。
1.4 标识符的命名规则

含义:程序中自定义的内容,如类名、方法名、变量名等。

硬性要求:

  • 包含英文字母、0-9、$、_。
  • 不能以数字开头。
  • 不是关键字。

规范建议:

  • 类名:首字符大写,后续单词首字母大写(大驼峰式)。
  • 变量/方法名:首字母小写,后续单词首字母大写(小驼峰式)。
1.5 instanceof 关键字的作用

用于测试对象是否属于某个类的实例。

boolean result = obj instanceof Class;
  • obj 为对象,Class 为类或接口。
  • 若 obj 是该类或其子类、接口的实现类,返回 true。
  • 注意:编译器会检查转换可行性。基本类型不能使用 instanceof。
  • 若 obj 为 null,返回 false。
1.6 Java 自动装箱与拆箱
  • 装箱:基本类型转包装器类型(如 int -> Integer),调用 Integer.valueOf(int)。
  • 拆箱:包装器类型转基本类型(如 Integer -> int),调用 Integer.intValue()。

面试题示例:

public class Main {
    public static void main(String[] args) {
        Integer i1 = 100; Integer i2 = 100;
        Integer i3 = 200; Integer i4 = 200;
        System.out.println(i1 == i2); // true
        System.out.println(i3 == i4); // false
    }
}

原因:Integer.valueOf 内部使用了缓存池(-128 到 127)。在此范围内的数值直接返回缓存对象引用,超出范围则创建新对象。

1.7 重载和重写的区别

重写 (Override):

  • 发生在父类与子类之间。
  • 方法名、参数列表、返回类型(子类可为父类返回类型的子类)必须相同。
  • 访问权限不能小于父类方法。
  • 不能抛出比父类更宽泛的检查异常。

重载 (Overload):

  • 同一类中,同名方法但参数列表不同(类型、个数、顺序)。
  • 返回值类型不影响重载判断。
1.8 equals 与 == 的区别
  • ==:比较内存地址。对于基本类型比较值,对于对象比较引用地址。
  • equals:比较内容。Object 类中的 equals 默认等同于 ==,通常需重写(如 String)。
  • 建议:阿里代码规范推荐使用 equals 比较对象,且常量在前(避免空指针)。
1.9 Hashcode 的作用

用于集合查找效率优化。通过哈希算法将对象映射到存储区域。若位置已有元素,则调用 equals 比较。hashCode 方法本质是根据内存地址换算出的值,帮助快速定位物理位置。

1.10 String、StringBuffer 和 StringBuilder 的区别
  • String:不可变字符数组。每次修改生成新对象。
  • StringBuffer:可变字符数组,线程安全(加锁),性能稍低。
  • StringBuilder:可变字符数组,非线程安全,性能高。
  • 建议:频繁字符串操作使用 StringBuffer 或 StringBuilder。
1.11 ArrayList 和 LinkedList 的区别
  • ArrayList:基于数组,查询快 O(1),增删慢(需移动数据)。可自动扩容。
  • LinkedList:双向链表,增删快,查询慢 O(n)。适合频繁插入删除场景。
1.12 HashMap 和 Hashtable 的区别
  1. 父类:HashMap 继承 AbstractMap,Hashtable 继承 Dictionary。
  2. null 支持:HashMap 允许 key 为 null(唯一),value 可为 null;Hashtable 不允许。
  3. 线程安全:HashMap 不安全;Hashtable 每个方法 synchronized,线程安全但效率低。
  4. 扩容:HashMap 初始 16,扩容 2 倍;Hashtable 初始 11,扩容 2 倍 +1。
  5. hash 计算:HashMap 异或移位,Hashtable 直接 hashcode。
  6. 替代方案:多线程建议使用 ConcurrentHashMap。
1.13 Collection 包结构与 Collections 的区别
  • Collection:集合根接口,子接口有 Set、List 等。
  • Collections:工具类,提供静态方法(搜索、排序、同步化),不可实例化。
1.14 Java 的四种引用
  1. 强引用:最常见,OOM 时不回收。String str = new String("str")。
  2. 软引用:内存不足时回收。适用于缓存场景。
  3. 弱引用:GC 发现即回收。WeakHashMap 的 Key 常用此方式。
  4. 虚引用:回收前放入 ReferenceQueue。用于资源释放前的处理。
1.15 泛型常用特点

Java SE 1.5 引入。允许编写被不同类型对象重用的代码。约束集合类型,避免运行时类型转换错误。

1.16 Java 创建对象的方式
  1. new 关键字。
  2. 反射机制 (Class.newInstance)。
  3. Clone 机制。
  4. 序列化机制。
1.17 两个不相等的对象能有相同的 hashCode 吗

有可能,即 Hash 冲突。处理方式包括拉链法、开放定址法、再哈希法。

1.18 深拷贝和浅拷贝的区别
  • 浅拷贝:复制对象本身,引用仍指向原对象。
  • 深拷贝:复制对象及其引用的所有对象,完全独立。
1.19 final 的用法
  1. 类不可继承。
  2. 方法不可重写。
  3. 变量不可变(引用不变,内容可变;或基本类型值不变)。
  4. JVM 尝试内联优化。
  5. 编译期常量存入常量池。
1.20 static 的用法
  1. 静态变量/方法(类共享)。
  2. 静态块(初始化)。
  3. 静态内部类。
  4. 静态导包(import static)。
1.21 3*0.1==0.3 返回值

false。浮点数精度问题,不能完全精确表示。

1.22 a=a+b 与 a+=b 的区别

+= 会进行隐式类型转换,a=a+b 不会。例如 byte 运算结果提升为 int,直接赋值报错,需用 +=。

1.23 try catch finally 执行顺序

finally 总会执行(除非 JVM 退出)。finally 在 return 表达式运算后执行,但不改变已保存的返回值。finally 中不建议 return。

1.24 Exception 与 Error 包结构
  • RuntimeException:运行时异常,编译器不检查(如 NullPointerException)。
  • CheckedException:被检查异常,必须处理或声明抛出(如 IOException)。
  • Error:严重错误,程序无法修复(如 OutOfMemoryError)。
1.25 OOM 与 SOF 常见情况
  • OOM:堆溢出(对象过多)、栈溢出(递归过深)、元空间溢出(类加载过多)。
  • SOF:递归太深或死循环导致栈容量超限。
1.26 线程、程序、进程概念
  • 程序:静态代码文件。
  • 进程:程序的一次执行,动态,占用资源。
  • 线程:进程内的执行单元,轻量级,共享进程资源。
1.27 线程状态

新建、可运行、运行、阻塞(等待、同步、其他)、死亡。

1.28 Java IO 流
  • 流向:输入/输出。
  • 单元:字节/字符。
  • 角色:节点/处理。
  • 基类:InputStream/Reader, OutputStream/Writer。
1.29 反射的作用与原理

运行时获取类信息并调用方法。用于 JDBC、框架(Hibernate/Struts)。优点灵活,缺点性能低、破坏封装。可通过 setAccessible(true) 优化。

1.30 List, Set, Map 区别
  • List:有序,可重复。
  • Set:无序,不可重复。
  • Map:键值对,Key 不可重复。

二、JVM 篇

2.1 JVM 内存模型
  • 线程独占:栈、本地方法栈、程序计数器。
  • 线程共享:堆、方法区。
2.2 内存区域详解
  1. 栈:存储局部变量、操作栈等。方法入栈出栈。
  2. 本地方法栈:Native 方法服务。
  3. 程序计数器:记录当前执行的字节码行号。
  4. 堆:存放对象实例,GC 主要区域。分新生代、老年代。
  5. 方法区:类信息、常量、静态变量。JDK 1.8 后为元空间。
2.3 类加载与卸载
  • 过程:加载、验证、准备、解析、初始化。
  • 双亲委派:委托父加载器,保证核心 API 安全。
  • 回收:永久代/元空间满会触发 Full GC。
2.4 垃圾回收算法
  • 标记 - 清除:标记后清除,有碎片。
  • 复制:新生代常用,无碎片,浪费空间。
  • 标记 - 压缩:老年代常用,整理碎片。
  • G1/ZGC:现代收集器,追求低停顿。
2.5 堆和栈的区别
  • 功能:栈存局部变量,堆存对象。
  • 共享:栈私有,堆共享。
  • 异常:栈满抛 StackOverflowError,堆满抛 OutOfMemoryError。
2.6 触发 Full GC 的情况
  1. 旧生代空间不足。
  2. 永久代/元空间满。
  3. CMS 出现 promotion failed 或 concurrent mode failure。
  4. Minor GC 晋升平均大小大于剩余空间。
2.7 为什么 Java 平台无关

JVM 屏蔽了底层硬件差异,执行字节码。源文件编译为字节码,由 JVM 解释或 JIT 编译执行。

2.8 对象分配规则

优先 Eden 区,大对象直接进入老年代,长期存活进入老年代,动态年龄判断,空间分配担保。

2.9 对象创建过程

检查常量池 -> 分配内存(指针碰撞/空闲列表/TLAB)-> 初始化零值 -> 设置对象头。

2.10 判断对象回收
  • 引用计数:简单但有循环引用问题。
  • 可达性分析:从 GC Roots 向下搜索,不可达即回收。
2.11 JDK 1.8 元空间变动

移除永久代,使用 Native 内存的元空间。默认无限,受系统内存限制。

三、多线程&并发篇

3.1 实现多线程的方法
  1. 继承 Thread 类。
  2. 实现 Runnable 接口。
  3. 实现 Callable 接口(配合 FutureTask)。
  4. 使用线程池(ExecutorService)。
3.2 停止线程

推荐设置退出标志或使用 interrupt。stop/suspend 已废弃,不安全。

3.3 notify() 和 notifyAll()
  • notify:唤醒一个等待线程,可能导致死锁。
  • notifyAll:唤醒所有,更安全。wait 应配合 while 循环检查条件。
3.4 sleep() 和 wait() 区别
  • sleep:Thread 类,不释放锁,时间到自动恢复。
  • wait:Object 类,释放锁,需 notify 唤醒。
3.5 volatile 关键字

保证可见性和禁止指令重排序。不保证原子性。适用于状态标记和单例模式双重检锁。

3.6 start() 和 run() 区别

start() 启动新线程,run() 只是普通方法调用。

3.7 synchronized 原理

底层依赖 monitor 对象。JDK 1.6 后引入偏向锁、轻量级锁、自旋锁等优化。字节码指令为 monitorenter/monitorexit。

3.8 synchronized 使用方式
  1. 修饰实例方法:锁定当前对象实例。
  2. 修饰静态方法:锁定当前类 Class 对象。
  3. 修饰代码块:指定锁定对象。
3.9 线程池理解
  • 好处:降低资源消耗,提高响应速度,提高可管理性。
  • 核心参数:corePoolSize, maximumPoolSize, keepAliveTime, workQueue 等。
3.10 线程池创建
  1. 构造 ThreadPoolExecutor。
  2. Executors 工具类(Fixed, Cached, Single, Scheduled)。
3.11 submit() 和 execute() 区别

execute() 无返回值,submit() 返回 Future 对象,可获取结果或异常。

3.12 Synchronized vs ReentrantLock
  • synchronized:关键字,JVM 实现,自动释放锁,非公平。
  • ReentrantLock:API,手动 lock/unlock,支持公平锁、中断等待、多条件变量。
3.13 线程安全定义

多线程访问同一代码,结果与单线程一致。Vector 是线程安全的,ArrayList 不是。

3.14 单例模式(双重检锁)
public class Singleton {
    private volatile static Singleton uniqueInstance;
    private Singleton() {}
    public static Singleton getInstance() {
        if (uniqueInstance == null) {
            synchronized (Singleton.class) {
                if (uniqueInstance == null) {
                    uniqueInstance = new Singleton();
                }
            }
        }
        return uniqueInstance;
    }
}

volatile 防止指令重排,确保对象初始化完成后再赋值。

四、Spring 篇

4.1 IOC 和 AOP
  • IOC:控制反转,依赖注入。容器管理对象生命周期和依赖关系。工厂模式体现。
  • AOP:面向切面,分离横切关注点(日志、事务)。代理模式体现(JDK/CGLIB)。
4.2 @Autowired 和 @Resource 区别
  • @Autowired:Spring 注解,按类型注入,可配 required=false。
  • @Resource:J2EE 标准,默认按名称注入,可指定 name/type。
4.3 依赖注入方式
  1. 构造器注入(推荐)。
  2. Setter 方法注入。
  3. 接口注入(较少用)。
4.4 Spring MVC 流程

DispatcherServlet -> HandlerMapping -> HandlerAdapter -> Controller -> ModelAndView -> ViewResolver -> View -> Response。

4.5 Spring Bean 生命周期

实例化 -> 属性注入 -> Aware 接口回调 -> BeanPostProcessor 前置 -> InitializingBean/init-method -> BeanPostProcessor 后置 -> 销毁 DisposableBean/destroy-method。

4.6 Bean 作用域

singleton(默认), prototype, request, session, global-session。

五、MyBatis 篇

5.1 MyBatis 简介

半 ORM 框架,关注 SQL 本身,灵活度高,减少 JDBC 冗余代码。

5.2 #{} 和 ${} 区别
  • #{}:预编译(PreparedStatement),防 SQL 注入。
  • ${}:字符串替换,有注入风险。
5.3 字段名与属性名不一致
  1. SQL 别名映射。
  2. resultMap 配置映射。
5.4 批量插入

开启 batch 模式 sqlSession,循环 insert 后 commit。

5.5 延迟加载

CGLIB 代理,调用关联对象时触发查询。配置 lazyLoadingEnabled=true。

六、SpringBoot 篇

6.1 什么是 Spring Boot

简化 Spring 应用开发,约定大于配置。内嵌 Tomcat,无需 WAR 部署,自动配置。

6.2 核心注解

@SpringBootApplication,组合了 @Configuration, @EnableAutoConfiguration, @ComponentScan。

6.3 Starters 是什么

启动器,集成依赖包。如 spring-boot-starter-web。

6.4 热部署

Spring Loaded 或 Spring Boot DevTools。

6.5 配置文件加载顺序

命令行 > 环境变量 > jar 包外配置 > jar 包内配置 > 默认值。application 为主,bootstrap 用于配置中心。

目录

  1. 一、基础篇
  2. 1.1 Java 语言有哪些特点
  3. 1.2 面向对象和面向过程的区别
  4. 1.3 八种基本数据类型的大小及封装类
  5. 1.4 标识符的命名规则
  6. 1.5 instanceof 关键字的作用
  7. 1.6 Java 自动装箱与拆箱
  8. 1.7 重载和重写的区别
  9. 1.8 equals 与 == 的区别
  10. 1.9 Hashcode 的作用
  11. 1.10 String、StringBuffer 和 StringBuilder 的区别
  12. 1.11 ArrayList 和 LinkedList 的区别
  13. 1.12 HashMap 和 Hashtable 的区别
  14. 1.13 Collection 包结构与 Collections 的区别
  15. 1.14 Java 的四种引用
  16. 1.15 泛型常用特点
  17. 1.16 Java 创建对象的方式
  18. 1.17 两个不相等的对象能有相同的 hashCode 吗
  19. 1.18 深拷贝和浅拷贝的区别
  20. 1.19 final 的用法
  21. 1.20 static 的用法
  22. 1.21 3*0.1==0.3 返回值
  23. 1.22 a=a+b 与 a+=b 的区别
  24. 1.23 try catch finally 执行顺序
  25. 1.24 Exception 与 Error 包结构
  26. 1.25 OOM 与 SOF 常见情况
  27. 1.26 线程、程序、进程概念
  28. 1.27 线程状态
  29. 1.28 Java IO 流
  30. 1.29 反射的作用与原理
  31. 1.30 List, Set, Map 区别
  32. 二、JVM 篇
  33. 2.1 JVM 内存模型
  34. 2.2 内存区域详解
  35. 2.3 类加载与卸载
  36. 2.4 垃圾回收算法
  37. 2.5 堆和栈的区别
  38. 2.6 触发 Full GC 的情况
  39. 2.7 为什么 Java 平台无关
  40. 2.8 对象分配规则
  41. 2.9 对象创建过程
  42. 2.10 判断对象回收
  43. 2.11 JDK 1.8 元空间变动
  44. 三、多线程&并发篇
  45. 3.1 实现多线程的方法
  46. 3.2 停止线程
  47. 3.3 notify() 和 notifyAll()
  48. 3.4 sleep() 和 wait() 区别
  49. 3.5 volatile 关键字
  50. 3.6 start() 和 run() 区别
  51. 3.7 synchronized 原理
  52. 3.8 synchronized 使用方式
  53. 3.9 线程池理解
  54. 3.10 线程池创建
  55. 3.11 submit() 和 execute() 区别
  56. 3.12 Synchronized vs ReentrantLock
  57. 3.13 线程安全定义
  58. 3.14 单例模式(双重检锁)
  59. 四、Spring 篇
  60. 4.1 IOC 和 AOP
  61. 4.2 @Autowired 和 @Resource 区别
  62. 4.3 依赖注入方式
  63. 4.4 Spring MVC 流程
  64. 4.5 Spring Bean 生命周期
  65. 4.6 Bean 作用域
  66. 五、MyBatis 篇
  67. 5.1 MyBatis 简介
  68. 5.2 #{} 和 ${} 区别
  69. 5.3 字段名与属性名不一致
  70. 5.4 批量插入
  71. 5.5 延迟加载
  72. 六、SpringBoot 篇
  73. 6.1 什么是 Spring Boot
  74. 6.2 核心注解
  75. 6.3 Starters 是什么
  76. 6.4 热部署
  77. 6.5 配置文件加载顺序

更多推荐文章

查看全部
  • 高空长航时无人机热管理系统中抗辐照 MCU 的可靠性验证与应用
  • 一键切换网络配置:IP+MAC+主机名联动
  • 网络安全入门指南:成为安全工程师的必备技能与学习路径
  • OpenClaw 跨平台安装指南:Windows、macOS 与 Linux 环境配置
  • C++ 显式类型转换详解:四种 Cast 用法对比
  • C++红黑树实现:从插入修正到平衡验证
  • 自然语言处理在客户服务领域的实战应用
  • OpenCode 深度体验与架构揭秘:终端里的 AI 编程助手
  • 企业级 Code RAG 与代码库 Copilot 深度架构指南
  • 麦橘超然 Flux 本地部署与低显存优化实战
  • cJSON 1.7.19 源码精读:从数据结构到解析生成
  • Flutter与Web混合开发实践
  • 鸿蒙金融理财应用:架构设计、安全与体验优化
  • Python 十大实用技巧:爬虫、自动化与数据处理
  • VS Code 前端开发必备插件推荐及配置教程
  • Web 渗透测试全流程实操:从概念到漏洞利用
  • 一周科技热点:苏姿丰谈芯片多元化,Gartner 预测 GenAI 趋势
  • LangChain 智能体中间件如何参与 Agent、Model 和 Tool 交互
  • 基于 Claude MCP 协议的智能体落地示例
  • 前端监控实战:构建高可用的 Web 应用

相关免费在线工具

  • 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