写在文章开头Java 基础是面试中的必考内容,但知识点零散、概念繁多,很多同学在复习时往往感到无从下手,难以形成系统的知识体系。为了帮助大家高效备考,本文对 Java 核心基础知识进行了系统梳理,涵盖语法特性、面向对象、集合框架、并发编程等高频面试考点。通过阅读本文,你将收获:📌系统化的知识脉络:从基础概念到进阶特性,建立完整的 Java 知识体系🎯高频面试考点汇总:聚焦面试常见问题,提升备考效率💡深度原理解析:不仅知其然,更知其所以然你好,我是SharkChili,Java Guide 核心维护者之一,对 Redis、Nightingale 等知名开源项目有深度源码研究经验。熟悉 Java、Go 等多语言技术栈,现任某知名黑厂高级研发。🌟 开源项目贡献mini-redis:教学级 Redis 精简实现,助力分布式缓存原理学习🔗 https://github.com/shark-ctrl/mini-redis(欢迎 Star Contribute)📚 公众号价值分享企业级架构设计、性能优化、源码解析等核心技术干货,涵盖分布式系统、微服务治理、大数据处理等实战领域,并探索面向AI的vibe coding等现代开发范式。👥 加入技术社群关注公众号,回复【加群】获取联系方式,与众多技术爱好者交流分布式架构、微服务等前沿技术!Java 语言概述Java 语言简介Java 是 1995 年由 Sun 公司推出的一门高级编程语言,具备以下核心特点:简单易学:相较于 C/C++,Java 没有指针概念,程序操作更加安全便捷平台无关性:通过 JVM 实现"一次编写,到处运行",无需针对不同平台重新编译面向对象:以对象为中心组织代码,支持封装、继承、多态。不同于 C++ 的多继承,Java 采用更简洁的接口机制编译与解释并存:源代码先编译为字节码(.class),再由 JVM 解释执行,兼顾效率与灵活性高可靠性:编译期与运行时双重检查,有效避免内存操作错误和数据损坏安全性:专为网络/分布式环境设计,在防病毒、防篡改方面做了诸多努力网络编程支持:提供简洁易用的网络 API,性能表现同样出色多线程支持:内置多线程机制,方便开发并发应用Java 与 C++ 的区别编译机制Java 属于半编译、半解释型语言,通过javac编译器生成 JVM 可识别的字节码(.class),再由 JVM 解释执行。执行效率相对依赖解释器,但跨平台能力出色。为解决纯解释执行效率低的问题,JVM 引入了JIT(即时编译,Just-In-Time Compilation)技术。JIT 在运行时监测代码执行频率,将热点代码(HotSpot)直接编译为机器码缓存,后续调用直接执行机器码,无需再解释执行,从而大幅提升性能。C++ 属于编译型语言,代码编译后直接生成机器码执行,执行效率高、性能优秀。但因直接服务于特定操作系统,跨平台能力相对较弱。主要区别对比项JavaC++继承机制单继承类,多继承接口支持多继承内存管理JVM 自动管理手动管理参数传递仅值传递值传递、引用、指针系统资源控制受 JVM 限制,不够底层可直接操作底层资源Java 中的 final 关键字final关键字可以修饰类、方法、变量,分别具有以下特性:final 修饰类:类不可被继承publicfinalclassString{// String类不能被其他类继承}// 编译报错:cannot inherit from final StringclassMyStringextendsString{}final 修饰方法:方法不可被重写classParent{publicfinalvoidrun(){System.out.println("Parent running");}}classChildextendsParent{// 编译报错:method is final and cannot be overriddenpublicvoidrun(){System.out.println("Child running");}}final 修饰变量:变量不可被修改(常量)publicclassExample{publicstaticfinalintMAX_SIZE=100;publicfinalStringNAME="test";publicvoidtest(){// MAX_SIZE = 200; // 编译报错// NAME = "new"; // 编译报错}}Java 三种技术架构Java 有三种主要技术架构:架构全称定位Java SEStandard Edition标准版,桌面和服务器应用开发的基础Java EEEnterprise Edition企业版,分布式企业应用(现更名为 Jakarta EE)Java MEMicro Edition微版,嵌入式/移动设备(已逐步淘汰)Java SE:包含 Java 语言、JVM、核心类库,是其他版本的基础Java EE:在 SE 基础上扩展,提供 Servlet、JSP、EJB、JPA 等企业级 API。目前主流框架为 Spring Boot,实际仍基于 Java EE 规范Java ME:面向资源受限设备,已逐渐被 Android 取代注:Java EE 已更名为 Jakarta EE,传统企业级开发多使用 Spring Boot 框架JVM 与编译机制JVM 工作原理JVM(Java Virtual Machine)是 Java 平台的核心组成部分,负责运行 Java 字节码。其核心工作流程如下:┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ Java 源 │ ──► │ Java 字节 │ ──► │ JVM │ ──► │ 机器码 │ │ 代码 .java │ │ 码 .class │ │ 解释/编译 │ │ 执行 │ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ javac JIT CPU详细流程:编译阶段:源代码(.java)通过javac编译器编译为字节码文件(.class)加载阶段:类加载器(ClassLoader)将字节码加载到 JVM执行阶段:解释执行:JVM 逐行解释字节码JIT 编译:热点代码被即时编译为机器码缓存,提升执行效率操作系统调用:机器码通过底层操作系统调度到 CPU 执行JVM 的核心作用:作用说明平台无关性一次编译,处处运行内存管理自动垃圾回收(GC)安全性字节码校验,防止恶意操作JDK 与 JRE 的区别JDK(Java Development Kit)和JRE(Java Runtime Environment)是 Java 开发中的两个核心概念:组件说明JREJava 运行环境,仅能运行 Java 程序(包含 JVM + 类库)JDKJava 开发工具包,包含 JRE + 编译工具(javac)+ 开发工具如何选择?场景安装只运行 Java 程序JRE 即可开发 Java 程序必须安装 JDK运行 JSP/Servlet 等 Web 程序必须安装 JDK建议:无论开发还是运行,都建议直接安装 JDK,避免后续因编译需求反复配置。字节码文件及其优势字节码(Bytecode)是 Java 编译后的中间代码格式(.class 文件),是 JVM 能识别的指令集。Java 代码执行流程:Java 源代码 → javac 编译 → 字节码文件 → JVM 解释/JIT 编译 → 机器码 → CPU 执行字节码的优势:优势说明平台无关性字节码不针对特定操作系统,只需不同平台安装对应 JVM 即可运行安全性字节码需通过类加载器验证,防止恶意代码直接操作底层系统JIT 优化JVM 可将热点字节码编译为机器码缓存,执行次数越多速度越快注意:字节码运行效率低于直接编译的机器码,但 JIT 编译器通过热点检测和缓存机制,能有效弥补这一差距。JDK 9 的 AOT 编译技术AOT(Ahead-of-Time)是 JDK 9 引入的编译技术,在程序运行前将字节码直接编译为机器码。优势:优势说明启动速度快避免运行时编译开销全局优化编译时进行整体代码分析劣势:劣势说明不支持动态特性反射、动态加载类、动态代理等无法静态确定不支持运行时优化无法根据实际运行情况动态调整实际应用:纯 Java 生态中 AOT 很少直接使用。Java 应用通常是长期运行的服务端程序,JIT 的热点优化已足够。若需极快启动,可关注GraalVM Native Image技术。数据类型Java 基本数据类型Java 有 8 种基本数据类型,分为四类:分类类型字节位数默认值整数byte180整数short2160整数int4320整数long8640L浮点float4320f浮点double8640d字符char216‘\u0000’布尔boolean1-false为什么整数类型字节数不同?计算机用不同位数存储数据,位数越多表示的范围越大:byte(8位):最小整数单位,能表示 -128~127。常用于:二进制数据流、网络协议、文件字节short(16位):2个字节,能表示约 -3万~3万。常用于:年龄(0-150)、月份(1-12)、RGB 颜色值int(32位):4个字节,能表示约 -21亿~21亿,日常开发最常用的整数类型。常用于:ID、计数、金额long(64位):8个字节,能表示超大范围。常用于:时间戳(毫秒)、大数值计算理解要点:byte 是最小单元,short 是 2 个 byte,int 是 4 个 byte,long 是 8 个 byte。位数翻倍,范围呈指数增长。选类型时,够用就行,越大的类型越占内存。为什么 float 是 4 字节、double 是 8 字节?浮点数用科学计数法存储,由三部分组成:符号位 + 指数位 + 尾数位float(单精度):1位符号 + 8位指数 + 23位尾数 = 32位 = 4字节double(双精度):1位符号 + 11位指数 + 52位尾数 = 64位 = 8字节应用场景:金融计算用 double(精度高),3D 游戏图形用 float(够用且省内存)。为什么 char 是 2 字节?char 用来存储字符。英文用 1 字节(ASCII),但中文、日文等需要更多字符。Unicode 要覆盖全世界所有文字,1 字节不够,所以 char 用 2 字节(UTF-16)。为什么 boolean 是 1 字节?布尔只需表示 true/false 两种状态,理论上 1 位就够。但 JVM 以字节为单位寻址,所以 boolean 占 1 字节。引用类型与基本类型的区别什么是引用类型?基本类型存储的是值本身,而引用类型存储的是对象在内存中的地址。栈内存 堆内存 ┌─────────┐ ┌─────────────────┐ │ 10 │ │ │ └─────────┘ │ String 对象 │ 基本类型:直接存储值 │ address="Tom" │ └────────┬────────┘ ┌─────────┐ │ │ 0x0010 │ ─────────────────────────────┘ └─────────┘ 引用类型:存储对象地址为什么需要引用类型?基本类型只能存简单数据,无法表达复杂对象对象较大,存在堆内存中,通过地址引用访问多个变量可引用同一对象,节省内存栈内存 堆内存 ┌─────────┐ ┌─────────────────┐ │ 0x0010 │ ──┐ │ │ └─────────┘ │ │ 用户对象 │ ┌─────────┐ ├── 都指向 ─────────▶│ │ │ 0x0010 │ ──┘ 同一对象 │ age=18 │ └─────────┘ └─────────────────┘ p1 p2 ← 两个引用指向同一对象Java 引用类型分为三种:类型关键字示例类类型classString、Object接口类型interfaceRunnable、Comparable数组类型[]int[]、String[]String 专题String 为什么是不可变的?String 是不可变类,这是 Java 设计中的重要特性。不可变的原因:String 是 final 类,无法被继承内部存储数据的 char[] 是 final 的没有暴露修改数据的方法public final class String { private final char[] value; // value 数组不可变 // 没有 setValue() 等修改方法 }什么是不可变?不可变不是说变量不能重新赋值,而是对象创建后其内部数据不能被修改:Strings="hello";s="world";// 变量 s 可以重新指向新对象// 但下面这个操作会编译报错,因为字符串内容不可修改// s[0] = 'H'; // 编译错误String 的"修改"其实是创建新对象:Strings="hello";Strings2=s.concat("world");// concat 返回新字符串,不修改原对象System.out.println(s);// 输出 "hello",s 未改变System.out.println(s2);// 输出 "helloworld"不可变性带来的好处:线程安全:堆内存(字符串常量池) ┌─────────────────────────────────┐ │ │ │ "hello" │◀── 线程1: String s1 = "hello" │ @0x0010 │◀── 线程2: String s2 = "hello" │ │ 两个线程指向同一个对象 │ │ └─────────────────────────────────┘ 线程1 ──s1引用──▶ "hello" ◀──s2引用── 线程2 无需同步:String 不可变,多线程共享安全hashCode 可缓存:String 作为 HashMap 的 key 时,由于不可变,hashCode 可以缓存,避免重复计算。安全性:数据库连接、文件路径等使用 String,防止被篡改。String + int 发生了什么?当 String 与其他类型使用+运算符时,会触发字符串拼接,系统自动将其他类型转换为字符串后拼接。Stringa="999";intb=1;System.out.println(a+b);// 输出 "9991",不是 1000!原理:编译器将+操作转换为 StringBuilder 拼接a + b ↓ 编译器转换为 ↓ new StringBuilder() .append(a) // "999" .append(b) // "1" .toString() // "9991"如何让 int 参与数学运算?Stringa="999";intb=1;// 方式一:先转换再运算System.out.println(Integer.parseInt(a)+b);// 1000// 方式二:括号改变运算顺序System.out.println
一文搞懂 Java 核心技术
写在文章开头Java 基础是面试中的必考内容,但知识点零散、概念繁多,很多同学在复习时往往感到无从下手,难以形成系统的知识体系。为了帮助大家高效备考,本文对 Java 核心基础知识进行了系统梳理,涵盖语法特性、面向对象、集合框架、并发编程等高频面试考点。通过阅读本文,你将收获:📌系统化的知识脉络:从基础概念到进阶特性,建立完整的 Java 知识体系🎯高频面试考点汇总:聚焦面试常见问题,提升备考效率💡深度原理解析:不仅知其然,更知其所以然你好,我是SharkChili,Java Guide 核心维护者之一,对 Redis、Nightingale 等知名开源项目有深度源码研究经验。熟悉 Java、Go 等多语言技术栈,现任某知名黑厂高级研发。🌟 开源项目贡献mini-redis:教学级 Redis 精简实现,助力分布式缓存原理学习🔗 https://github.com/shark-ctrl/mini-redis(欢迎 Star Contribute)📚 公众号价值分享企业级架构设计、性能优化、源码解析等核心技术干货,涵盖分布式系统、微服务治理、大数据处理等实战领域,并探索面向AI的vibe coding等现代开发范式。👥 加入技术社群关注公众号,回复【加群】获取联系方式,与众多技术爱好者交流分布式架构、微服务等前沿技术!Java 语言概述Java 语言简介Java 是 1995 年由 Sun 公司推出的一门高级编程语言,具备以下核心特点:简单易学:相较于 C/C++,Java 没有指针概念,程序操作更加安全便捷平台无关性:通过 JVM 实现"一次编写,到处运行",无需针对不同平台重新编译面向对象:以对象为中心组织代码,支持封装、继承、多态。不同于 C++ 的多继承,Java 采用更简洁的接口机制编译与解释并存:源代码先编译为字节码(.class),再由 JVM 解释执行,兼顾效率与灵活性高可靠性:编译期与运行时双重检查,有效避免内存操作错误和数据损坏安全性:专为网络/分布式环境设计,在防病毒、防篡改方面做了诸多努力网络编程支持:提供简洁易用的网络 API,性能表现同样出色多线程支持:内置多线程机制,方便开发并发应用Java 与 C++ 的区别编译机制Java 属于半编译、半解释型语言,通过javac编译器生成 JVM 可识别的字节码(.class),再由 JVM 解释执行。执行效率相对依赖解释器,但跨平台能力出色。为解决纯解释执行效率低的问题,JVM 引入了JIT(即时编译,Just-In-Time Compilation)技术。JIT 在运行时监测代码执行频率,将热点代码(HotSpot)直接编译为机器码缓存,后续调用直接执行机器码,无需再解释执行,从而大幅提升性能。C++ 属于编译型语言,代码编译后直接生成机器码执行,执行效率高、性能优秀。但因直接服务于特定操作系统,跨平台能力相对较弱。主要区别对比项JavaC++继承机制单继承类,多继承接口支持多继承内存管理JVM 自动管理手动管理参数传递仅值传递值传递、引用、指针系统资源控制受 JVM 限制,不够底层可直接操作底层资源Java 中的 final 关键字final关键字可以修饰类、方法、变量,分别具有以下特性:final 修饰类:类不可被继承publicfinalclassString{// String类不能被其他类继承}// 编译报错:cannot inherit from final StringclassMyStringextendsString{}final 修饰方法:方法不可被重写classParent{publicfinalvoidrun(){System.out.println("Parent running");}}classChildextendsParent{// 编译报错:method is final and cannot be overriddenpublicvoidrun(){System.out.println("Child running");}}final 修饰变量:变量不可被修改(常量)publicclassExample{publicstaticfinalintMAX_SIZE=100;publicfinalStringNAME="test";publicvoidtest(){// MAX_SIZE = 200; // 编译报错// NAME = "new"; // 编译报错}}Java 三种技术架构Java 有三种主要技术架构:架构全称定位Java SEStandard Edition标准版,桌面和服务器应用开发的基础Java EEEnterprise Edition企业版,分布式企业应用(现更名为 Jakarta EE)Java MEMicro Edition微版,嵌入式/移动设备(已逐步淘汰)Java SE:包含 Java 语言、JVM、核心类库,是其他版本的基础Java EE:在 SE 基础上扩展,提供 Servlet、JSP、EJB、JPA 等企业级 API。目前主流框架为 Spring Boot,实际仍基于 Java EE 规范Java ME:面向资源受限设备,已逐渐被 Android 取代注:Java EE 已更名为 Jakarta EE,传统企业级开发多使用 Spring Boot 框架JVM 与编译机制JVM 工作原理JVM(Java Virtual Machine)是 Java 平台的核心组成部分,负责运行 Java 字节码。其核心工作流程如下:┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ Java 源 │ ──► │ Java 字节 │ ──► │ JVM │ ──► │ 机器码 │ │ 代码 .java │ │ 码 .class │ │ 解释/编译 │ │ 执行 │ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ javac JIT CPU详细流程:编译阶段:源代码(.java)通过javac编译器编译为字节码文件(.class)加载阶段:类加载器(ClassLoader)将字节码加载到 JVM执行阶段:解释执行:JVM 逐行解释字节码JIT 编译:热点代码被即时编译为机器码缓存,提升执行效率操作系统调用:机器码通过底层操作系统调度到 CPU 执行JVM 的核心作用:作用说明平台无关性一次编译,处处运行内存管理自动垃圾回收(GC)安全性字节码校验,防止恶意操作JDK 与 JRE 的区别JDK(Java Development Kit)和JRE(Java Runtime Environment)是 Java 开发中的两个核心概念:组件说明JREJava 运行环境,仅能运行 Java 程序(包含 JVM + 类库)JDKJava 开发工具包,包含 JRE + 编译工具(javac)+ 开发工具如何选择?场景安装只运行 Java 程序JRE 即可开发 Java 程序必须安装 JDK运行 JSP/Servlet 等 Web 程序必须安装 JDK建议:无论开发还是运行,都建议直接安装 JDK,避免后续因编译需求反复配置。字节码文件及其优势字节码(Bytecode)是 Java 编译后的中间代码格式(.class 文件),是 JVM 能识别的指令集。Java 代码执行流程:Java 源代码 → javac 编译 → 字节码文件 → JVM 解释/JIT 编译 → 机器码 → CPU 执行字节码的优势:优势说明平台无关性字节码不针对特定操作系统,只需不同平台安装对应 JVM 即可运行安全性字节码需通过类加载器验证,防止恶意代码直接操作底层系统JIT 优化JVM 可将热点字节码编译为机器码缓存,执行次数越多速度越快注意:字节码运行效率低于直接编译的机器码,但 JIT 编译器通过热点检测和缓存机制,能有效弥补这一差距。JDK 9 的 AOT 编译技术AOT(Ahead-of-Time)是 JDK 9 引入的编译技术,在程序运行前将字节码直接编译为机器码。优势:优势说明启动速度快避免运行时编译开销全局优化编译时进行整体代码分析劣势:劣势说明不支持动态特性反射、动态加载类、动态代理等无法静态确定不支持运行时优化无法根据实际运行情况动态调整实际应用:纯 Java 生态中 AOT 很少直接使用。Java 应用通常是长期运行的服务端程序,JIT 的热点优化已足够。若需极快启动,可关注GraalVM Native Image技术。数据类型Java 基本数据类型Java 有 8 种基本数据类型,分为四类:分类类型字节位数默认值整数byte180整数short2160整数int4320整数long8640L浮点float4320f浮点double8640d字符char216‘\u0000’布尔boolean1-false为什么整数类型字节数不同?计算机用不同位数存储数据,位数越多表示的范围越大:byte(8位):最小整数单位,能表示 -128~127。常用于:二进制数据流、网络协议、文件字节short(16位):2个字节,能表示约 -3万~3万。常用于:年龄(0-150)、月份(1-12)、RGB 颜色值int(32位):4个字节,能表示约 -21亿~21亿,日常开发最常用的整数类型。常用于:ID、计数、金额long(64位):8个字节,能表示超大范围。常用于:时间戳(毫秒)、大数值计算理解要点:byte 是最小单元,short 是 2 个 byte,int 是 4 个 byte,long 是 8 个 byte。位数翻倍,范围呈指数增长。选类型时,够用就行,越大的类型越占内存。为什么 float 是 4 字节、double 是 8 字节?浮点数用科学计数法存储,由三部分组成:符号位 + 指数位 + 尾数位float(单精度):1位符号 + 8位指数 + 23位尾数 = 32位 = 4字节double(双精度):1位符号 + 11位指数 + 52位尾数 = 64位 = 8字节应用场景:金融计算用 double(精度高),3D 游戏图形用 float(够用且省内存)。为什么 char 是 2 字节?char 用来存储字符。英文用 1 字节(ASCII),但中文、日文等需要更多字符。Unicode 要覆盖全世界所有文字,1 字节不够,所以 char 用 2 字节(UTF-16)。为什么 boolean 是 1 字节?布尔只需表示 true/false 两种状态,理论上 1 位就够。但 JVM 以字节为单位寻址,所以 boolean 占 1 字节。引用类型与基本类型的区别什么是引用类型?基本类型存储的是值本身,而引用类型存储的是对象在内存中的地址。栈内存 堆内存 ┌─────────┐ ┌─────────────────┐ │ 10 │ │ │ └─────────┘ │ String 对象 │ 基本类型:直接存储值 │ address="Tom" │ └────────┬────────┘ ┌─────────┐ │ │ 0x0010 │ ─────────────────────────────┘ └─────────┘ 引用类型:存储对象地址为什么需要引用类型?基本类型只能存简单数据,无法表达复杂对象对象较大,存在堆内存中,通过地址引用访问多个变量可引用同一对象,节省内存栈内存 堆内存 ┌─────────┐ ┌─────────────────┐ │ 0x0010 │ ──┐ │ │ └─────────┘ │ │ 用户对象 │ ┌─────────┐ ├── 都指向 ─────────▶│ │ │ 0x0010 │ ──┘ 同一对象 │ age=18 │ └─────────┘ └─────────────────┘ p1 p2 ← 两个引用指向同一对象Java 引用类型分为三种:类型关键字示例类类型classString、Object接口类型interfaceRunnable、Comparable数组类型[]int[]、String[]String 专题String 为什么是不可变的?String 是不可变类,这是 Java 设计中的重要特性。不可变的原因:String 是 final 类,无法被继承内部存储数据的 char[] 是 final 的没有暴露修改数据的方法public final class String { private final char[] value; // value 数组不可变 // 没有 setValue() 等修改方法 }什么是不可变?不可变不是说变量不能重新赋值,而是对象创建后其内部数据不能被修改:Strings="hello";s="world";// 变量 s 可以重新指向新对象// 但下面这个操作会编译报错,因为字符串内容不可修改// s[0] = 'H'; // 编译错误String 的"修改"其实是创建新对象:Strings="hello";Strings2=s.concat("world");// concat 返回新字符串,不修改原对象System.out.println(s);// 输出 "hello",s 未改变System.out.println(s2);// 输出 "helloworld"不可变性带来的好处:线程安全:堆内存(字符串常量池) ┌─────────────────────────────────┐ │ │ │ "hello" │◀── 线程1: String s1 = "hello" │ @0x0010 │◀── 线程2: String s2 = "hello" │ │ 两个线程指向同一个对象 │ │ └─────────────────────────────────┘ 线程1 ──s1引用──▶ "hello" ◀──s2引用── 线程2 无需同步:String 不可变,多线程共享安全hashCode 可缓存:String 作为 HashMap 的 key 时,由于不可变,hashCode 可以缓存,避免重复计算。安全性:数据库连接、文件路径等使用 String,防止被篡改。String + int 发生了什么?当 String 与其他类型使用+运算符时,会触发字符串拼接,系统自动将其他类型转换为字符串后拼接。Stringa="999";intb=1;System.out.println(a+b);// 输出 "9991",不是 1000!原理:编译器将+操作转换为 StringBuilder 拼接a + b ↓ 编译器转换为 ↓ new StringBuilder() .append(a) // "999" .append(b) // "1" .toString() // "9991"如何让 int 参与数学运算?Stringa="999";intb=1;// 方式一:先转换再运算System.out.println(Integer.parseInt(a)+b);// 1000// 方式二:括号改变运算顺序System.out.println