⚙️ Java 核心技术架构
- Java 体系结构 (JDK / JRE / JVM)
- JDK (Java Development Kit):Java 开发工具包,包含 JRE 以及编译器 (
javac)、打包工具 (jar)、调试器等开发工具。 - JRE (Java Runtime Environment):Java 运行环境,包含 JVM 和核心类库,是运行 Java 程序所必需的环境。
- JVM (Java Virtual Machine):Java 虚拟机,跨平台的核心。负责将
.class字节码文件解释或编译成特定平台的机器指令执行。 - JVM 运行时数据区 (内存模型)
- 程序计数器 (PC Register):记录当前线程执行的字节码行号指示器。
- 虚拟机栈 (JVM Stack):描述 Java 方法执行的内存模型。每个方法执行时创建栈帧(局部变量表、操作数栈、动态链接、返回地址)。
- 本地方法栈 (Native Method Stack):为 JVM 使用到的 Native 方法服务。
- 堆 (Heap):JVM 管理的最大内存区域,存放对象实例和数组,是垃圾收集器 (GC) 的主要工作区域。
- 方法区 (Method Area):存储已被加载的类信息、常量、静态变量、JIT 编译后的代码。JDK 8 之后称为元空间 (Metaspace),使用本地内存 (Native Memory) 而非 JVM 堆内存。
- 类加载机制与双亲委派模型
- 加载 (Loading):获取类的二进制字节流,转化为方法区的运行时数据结构。
- 链接 (Linking):包含验证 (Verification)、准备 (Preparation, 分配内存并赋零值)、解析 (Resolution)。
- 初始化 (Initialization):执行类构造器
<clinit>()方法,执行静态代码块和静态变量赋值。 Bootstrap ClassLoader(C++实现,加载 rt.jar)Extension ClassLoader(加载 ext 目录)Application ClassLoader(加载 ClassPath 目录)- 垃圾回收算法与 GC 收集器
- 引用计数法:存在循环引用问题,JVM 未采用。
- 可达性分析算法 (GC Roots):从 GC Roots (如虚拟机栈引用的对象、静态变量、常量) 向下搜索,不可达的对象即为可回收。
- 标记-清除 (Mark-Sweep):产生内存碎片。
- 复制 (Copying):适用于新生代,解决碎片问题,但浪费空间。
- 标记-整理 (Mark-Compact):适用于老年代,移动对象,无碎片但需要 STW (Stop The World)。
- 分代收集:新生代用复制算法,老年代用标记-清除或标记-整理。
- Serial / Serial Old:单线程,Client 模式。
- Parallel Scavenge / Old:吞吐量优先。
- CMS (Concurrent Mark Sweep):低延迟,但会产生浮动垃圾和内存碎片 (JDK 14 被移除)。
- G1 (Garbage-First):将堆划分为多个 Region,兼顾吞吐与延迟,JDK 9 默认。
- ZGC / Shenandoah:超低延迟 (<10ms),支持 TB 级内存,JDK 11/15+ 生产可用。
- 基础数据类型与面向对象
- 封装:隐藏内部实现细节,通过 getter/setter 暴露访问接口,保证数据安全。
- 继承:使用
extends实现代码复用,Java 仅支持单继承,但支持多接口实现 (implements)。 - 多态:同一方法作用于不同对象产生不同行为。实现方式:方法重写 (Override)、重载 (Overload)、向上转型、动态绑定。
- 集合框架 (Collections Framework)
- List (有序,可重复):
ArrayList:基于动态数组,查询快,增删慢。默认容量 10,扩容 1.5 倍。LinkedList:基于双向链表,增删快,查询慢。可作为栈/队列使用。
- Set (无序,不可重复):
HashSet:底层 HashMap,依赖 hashCode() 和 equals() 保证唯一性。TreeSet:底层红黑树,元素自然排序或自定义比较器。
HashMap:JDK 8+ 采用 数组+链表+红黑树。链表长度 >8 且数组长度 >=64 时转为红黑树,查找时间复杂度 O(log n)。ConcurrentHashMap:线程安全。JDK 8 摒弃分段锁,采用 CAS + synchronized 锁住链表/红黑树头节点,并发度极高。- 多线程与并发编程 (JUC)
corePoolSize:核心线程数。maximumPoolSize:最大线程数。keepAliveTime:非核心线程空闲存活时间。unit:时间单位。workQueue:阻塞队列 (Array, Linked, Synchronous 等)。threadFactory:线程工厂。handler:拒绝策略 (Abort, CallerRuns, Discard, DiscardOldest)。synchronized:JVM 层面锁,经历偏向锁 -> 轻量级锁 -> 重量级锁的升级过程。ReentrantLock:API 层面锁,支持公平锁、响应中断、超时获取。基于 AQS (AbstractQueuedSynchronizer) 实现。- CAS (Compare-And-Swap):无锁算法,硬件级别原子操作。可能产生 ABA 问题,可用
AtomicStampedReference解决。 - IO 模型与 NIO 架构
- BIO (同步阻塞):一个连接一个线程。适用于连接数少且固定。
- NIO (同步非阻塞):多路复用器 (Selector) 轮询。适用于高并发、短连接。
- AIO (异步非阻塞):基于事件回调机制。适用于重负载、长连接。
- Buffer (缓冲区):数据的容器,核心是 position, limit, capacity。
- Channel (通道):双向的数据传输通道 (FileChannel, SocketChannel)。
- Selector (多路复用器):单线程监听多个 Channel 的事件 (连接、读、写)。
- Spring 核心与生态体系
- IoC (控制反转):将对象的创建和依赖关系的管理交给 Spring 容器,通过 DI (依赖注入) 实现解耦。
- AOP (面向切面编程):将日志、事务、权限等非业务逻辑抽离为切面,通过动态代理 (JDK Proxy / CGLIB) 织入目标对象。
- 服务注册与发现:Nacos, Eureka, Consul
- 负载均衡:Ribbon, Spring Cloud LoadBalancer
- 服务调用:OpenFeign
- 服务网关:Spring Cloud Gateway
- 熔断降级:Sentinel, Hystrix
- 持久层与中间件
- MyBatis:半自动 ORM,支持自定义 SQL、动态 XML 映射,灵活度高,国内主流。
- Hibernate / Spring Data JPA:全自动 ORM,面向对象操作数据库,适合标准化 CRUD。
- Redis:基于内存的 K-V 数据库。用于缓存、分布式锁、排行榜。常用数据结构:String, Hash, List, Set, ZSet。
- 消息队列 (MQ):Kafka (高吞吐/日志), RabbitMQ (路由灵活/延迟低), RocketMQ (金融级可靠/阿里开源)。作用:异步、解耦、削峰。
- Elasticsearch:分布式 Lucene 搜索引擎,用于全文检索和日志分析 (ELK 栈)。
- MySQL 索引底层原理与优化
- 非叶子节点不存数据:B+树只有叶子节点存储真实数据,非叶子节点仅作为索引。这使得每个磁盘页(Page)能容纳更多的索引键,树的高度更矮胖,极大减少磁盘 I/O 次数。
- 范围查询优势:B+树的所有叶子节点通过双向链表相连,非常适合范围查询(如
BETWEEN),而 B 树需要繁琐的中序遍历。 - 聚簇索引:叶子节点存储完整的行数据。InnoDB 默认使用主键作为聚簇索引。
- 非聚簇索引:叶子节点存储主键值。回表:通过二级索引查到主键后,需再去聚簇索引树查询完整数据。
- 覆盖索引:查询的列全部包含在二级索引树中,无需回表,性能极高。
- 事务隔离级别与 MVCC 原理
- 隐藏字段:
trx_id(最近修改该行的事务ID),roll_pointer(回滚指针,指向 undo log 中的旧版本)。 - Undo Log 版本链:每次修改数据都会将旧版本写入 undo log,并通过 roll_pointer 串联成链表。
- Read View (读视图):事务执行快照读(普通 select)时生成的可见性视图。包含:
m_ids(生成ReadView时所有活跃事务ID列表),min_trx_id,max_trx_id,creator_trx_id。 - 可见性判断规则:通过比对版本链上节点的
trx_id与 Read View 的区间,决定当前版本是否对当前事务可见。RC 级别每次 select 都重新生成 Read View,RR 级别只在第一次 select 时生成。 - 分库分表与分布式 ID
- 垂直拆分:按业务功能拆分到不同数据库(如用户库、订单库);或将表中不常用的宽字段拆分到扩展表。
- 水平拆分:单表数据量过大(通常超过千万级),按哈希或时间范围将数据路由到不同的物理表中(如
order_01,order_02)。 - 中间件:ShardingSphere (JDBC层拦截), MyCat (Proxy层拦截)。
- UUID:本地生成,无需网络请求。缺点:无序字符串,太长,导致 MySQL B+树频繁页分裂,插入性能极差。
- 数据库自增 (号段模式):每次从 DB 批量获取一个号段(如 1000-2000)在内存中分配,减轻 DB 压力。
- 雪花算法 (Snowflake):Twitter开源。生成 64 bit 的 Long 型整数。
- CAP 定理与 BASE 理论
- C (Consistency) 一致性:所有节点在同一时间的数据完全一致。
- A (Availability) 可用性:服务一直可用,且能在正常时间内响应。
- P (Partition tolerance) 分区容错性:遇到网络分区故障时,系统仍能继续运行。
- Basically Available (基本可用):允许损失部分可用性(如响应时间变长、降级页面)。
- Soft state (软状态):允许系统中的数据存在中间状态,且该状态不影响系统可用性。
- Eventually consistent (最终一致性):经过一段时间后,所有节点的数据副本能够达到一致。
- 分布式事务解决方案
- 2PC (两阶段提交):分为准备阶段和提交阶段。存在同步阻塞、单点故障、数据不一致等缺点。
- TCC (Try-Confirm-Cancel):业务层面的 2PC。 优点:性能高,无长事务锁。缺点:代码侵入性极强,需实现三个接口及处理幂等、悬挂等问题。
- Try:资源预留和业务检查。
- Confirm:执行实际业务,不作任何检查。
- Cancel:释放 Try 阶段预留的资源。
- 本地消息表:利用本地事务保证“业务操作+消息写入”的原子性,再通过定时任务轮询发送 MQ,消费者消费后更新消息状态。实现可靠的最终一致性。
- Seata AT 模式:阿里开源的无侵入分布式事务方案。一阶段拦截 SQL,解析生成前置/后置镜像,提交本地事务并记录
undo_log;二阶段若全局提交则异步清理日志,若回滚则利用undo_log反向补偿。 - 分布式锁与高并发缓存架构
- 缓存穿透:查询根本不存在的数据,请求直达 DB。解法:缓存空对象 (设短过期)、布隆过滤器 (Bloom Filter) 拦截。
- 缓存击穿:某个热点 Key 突然过期,海量并发请求瞬间打到 DB。解法:互斥锁 (SETNX 重建缓存)、逻辑过期 (不设 TTL,代码判断时间戳异步更新)。
- 缓存雪崩:大量 Key 同时过期,或 Redis 宕机。解法:过期时间加随机值、Redis 高可用集群、服务降级/限流。
- JDK 8 革命性特性 (基石)
- JDK 9 - 17 核心演进
var局部变量类型推断:var list = new ArrayList<String>();- JDK 11 移除 Java EE 模块,引入新的 HTTP Client API (支持 HTTP/2 和 WebSocket)。
- Switch 表达式:支持
->箭头语法,支持返回值,无需break防止穿透。 - Record 记录类 (JDK 16):不可变数据载体。编译器自动生成构造器、getter、
equals、hashCode、toString。 - 密封类 (Sealed Classes, JDK 17):限制哪些类可以继承或实现它。使用
sealed和permits关键字,增强领域建模的安全性。 - JDK 21 LTS 颠覆性创新 (虚拟线程)
- 原理:虚拟线程是轻量级线程,由 JVM 调度。大量虚拟线程复用少量的平台线程(Carrier Thread)。
- Unmount 机制:当虚拟线程遇到 I/O 阻塞(如数据库查询、网络请求)时,会自动从平台线程上卸载(Unmount),让出平台线程去执行其他虚拟线程。I/O 完成后再重新挂载。
- 优势:可以用写同步阻塞代码的方式,达到异步非阻塞的超高吞吐量。轻松支持百万级并发连接。
- JVM 核心调优参数配置
-Xms/-Xmx:设置堆初始值和最大值。生产环境强烈建议设置一致,避免堆内存震荡带来的 GC 停顿。-Xmn:设置年轻代大小。通常设置为整个堆的 1/3 到 1/2。-Xss:设置每个线程的栈大小。通常 1M 足够,设置过大浪费内存。-XX:MetaspaceSize/-XX:MaxMetaspaceSize:限制元空间大小,防止类加载过多导致 OOM。-XX:+UseG1GC:启用 G1 收集器 (JDK 9+ 默认)。-XX:MaxGCPauseMillis=200:设置 G1 期望的最大 GC 停顿时间目标。-XX:+PrintGCDetails(JDK 8) 或-Xlog:gc*:file=gc.log(JDK 9+):开启 GC 日志,用于后续分析 GC 频率和停顿时间。-XX:+HeapDumpOnOutOfMemoryError:发生 OOM 时自动 Dump 堆内存快照,极其重要!- 常见线上故障排查实战
- 使用
top命令找出 CPU 占用最高的进程 PID。 - 使用
top -Hp <PID>找出该进程下 CPU 占用最高的线程 TID。 - 将 TID 转换为 16 进制:
printf "%x\n" <TID>。 - 导出线程栈:
jstack <PID> > thread.log。 - 在日志中搜索 16 进制的 TID,定位到具体的代码行号(通常是死循环、频繁 GC 或正则回溯)。
- 查看 Histogram (直方图) 找出占用内存最大的对象。
- 查看 Dominator Tree (支配树) 分析 GC Roots 引用链,找到无法被回收的“大对象”究竟是被哪个静态集合或缓存死死咬住。
- 现代诊断神器:Arthas 常用命令
dashboard:实时显示系统的线程、内存、GC 概况。thread:查看当前线程堆栈信息,支持找出最忙(CPU最高)的线程。watch:观察方法的调用参数、返回值、抛出的异常。 示例:watch com.example.UserService getUser "{params,returnObj}" -x 2trace:方法内部调用路径追踪,输出各节点耗时,快速定位性能瓶颈。 示例:trace com.example.OrderService createOrder '#cost > 100'jad:反编译内存中加载的类的源码,确认线上代码是否部署正确。redefine / retransform:热更新。本地编译好 .class 文件传到服务器,通过此命令直接替换内存中的类,紧急修复线上小 Bug (无需重启)。- SOLID 面向对象设计原则
- S - 单一职责原则 (SRP):一个类应该只有一个引起它变化的原因。高内聚,降低类的复杂度。
- O - 开闭原则 (OCP):对扩展开放,对修改封闭。通过抽象和多态来应对需求变更(如策略模式)。
- L - 里氏替换原则 (LSP):所有引用基类的地方必须能透明地使用其子类的对象。子类可以扩展父类的功能,但不能改变父类原有的逻辑。
- I - 接口隔离原则 (ISP):客户端不应该依赖它不需要的接口。将臃肿的接口拆分为多个细粒度的接口。
- D - 依赖倒置原则 (DIP):高层模块不应该依赖低层模块,二者都应该依赖其抽象。面向接口编程,而非面向实现编程。
- 创建型与结构型模式实战
- 饿汉式:类加载时实例化,线程安全,但可能造成资源浪费。
- 双重检查锁 (DCL):利用
volatile关键字禁止指令重排,结合synchronized实现懒汉式且保证线程安全与性能。 - 静态内部类:利用类加载机制保证延迟加载与线程安全,代码优雅。
- 枚举 (Enum):《Effective Java》推荐。天然防反射攻击和反序列化破坏单例。
- JDK 动态代理:基于接口实现。利用
java.lang.reflect.Proxy和InvocationHandler在运行时生成代理类。 - CGLIB 动态代理:基于继承实现。利用 ASM 字节码框架生成目标类的子类。如果目标类被
final修饰则无法代理。 - 行为型模式与 Spring 事件驱动
- 继承
ApplicationEvent定义事件。 - 实现
ApplicationListener或使用@EventListener注解定义监听器。 - 通过
ApplicationEventPublisher.publishEvent()发布事件。 - 进阶:使用
@TransactionalEventListener可以实现“事务提交后再触发事件”,避免事务回滚但消息已发出的尴尬问题;结合@Async可实现异步解耦。
+
三者关系
口诀:JDK 包含 JRE,JRE 包含 JVM。
+
线程私有区域
线程共享区域
+
类加载过程
双亲委派模型 (Parents Delegation Model)
工作过程:如果一个类加载器收到了类加载请求,它不会自己先去加载,而是把请求委托给父类加载器,依次递归,直到 Bootstrap ClassLoader。只有当父加载器反馈无法加载时,子加载器才尝试自己加载。
核心类加载器层次:
安全 避免重复加载
+
判断对象存活
经典垃圾回收算法
主流垃圾收集器
📘 Java 基础语法教程
+
八大基本数据类型
byte, short, int, long, float, double, boolean, char。对应的包装类 (如 Integer) 提供了自动装箱/拆箱机制 (底层调用 valueOf() 和 xxxValue())。
面向对象三大特性
// 多态示例
Animal a = new Dog(); // 向上转型
a.eat(); // 实际调用 Dog 的 eat() 方法
+
Collection 接口 (单列数据)
Map 接口 (键值对)
🚀 Java 进阶核心教程
+
线程创建与生命周期
实现方式:继承 Thread、实现 Runnable、实现 Callable (有返回值)。生命周期包括:新建、就绪、运行、阻塞、死亡。
线程池核心参数 (ThreadPoolExecutor)
锁机制与 AQS
+
三种 IO 模型对比
NIO 核心三大组件
Netty 是基于 NIO 的顶级网络框架,广泛用于 RPC 和即时通讯。
🏗️ Java 框架与生态
+
Spring Core 两大基石
Spring Boot
核心理念:"约定优于配置" (Convention over Configuration)。提供 Starter 依赖管理、内嵌 Web 容器 (Tomcat/Jetty)、自动配置 (Auto-Configuration),极大简化开发流程。
Spring Cloud 微服务组件
+
持久层框架
核心中间件
🗄️ 数据库与高级应用
+
为什么使用 B+ 树而不是 B 树?
聚簇索引 vs 非聚簇索引 (二级索引)
最左前缀匹配原则
联合索引 (a, b, c),查询条件必须从索引的最左列开始并且不能跳过索引中的列。例如 where a=1 and c=3 只能用到 a 的索引,c 无法利用索引树(但在 MySQL 8.0 优化器中可能通过索引下推 Index Condition Pushdown 部分优化)。
+
ACID 与 四大隔离级别
| 隔离级别 | 脏读 | 不可重复读 | 幻读 | 性能 |
|---|---|---|---|---|
| Read Uncommitted | 可能 | 可能 | 可能 | 最高 |
| Read Committed (Oracle默认) | 避免 | 可能 | 可能 | 高 |
| Repeatable Read (MySQL默认) | 避免 | 避免 | 可能(MySQL通过MVCC+间隙锁避免) | 中 |
| Serializable | 避免 | 避免 | 避免 | 最低 |
MVCC (多版本并发控制) 核心机制
InnoDB 在 RR 级别下通过 MVCC 解决读写冲突,实现不加锁的读,极大提高并发度。
+
分库分表策略
分布式 ID 生成方案
结构:1位符号位(0) + 41位时间戳(毫秒级,可用69年) + 10位机器ID(支持1024个节点) + 12位序列号(每毫秒4096个ID)
优点:整体趋势递增,本地生成无网络开销,性能极高。
🌐 分布式系统设计
+
CAP 定理 (布鲁尔定理)
一个分布式系统最多只能同时满足以下三项中的两项:
架构选择:分布式系统必须满足 P。因此只能在 CP (如 Zookeeper, Redis Cluster) 和 AP (如 Eureka, Cassandra, DynamoDB) 之间权衡。
BASE 理论
是对 CAP 中 AP 的延伸,核心思想是即使无法做到强一致性,但可以通过适当方式使系统达到最终一致性。
+
常见分布式事务模式
+
分布式锁实现方案对比
| 方案 | 原理 | 优缺点 |
|---|---|---|
| Redis | SET key value NX PX + Lua脚本删除 | 性能极高。缺点是主从切换可能导致锁丢失 (可用 Redlock 算法缓解)。 |
| Zookeeper | 创建临时顺序节点,监听前一个节点删除事件 | 强一致性,可靠性高。缺点是性能不如 Redis,存在客户端创建连接开销。 |
| 数据库 | 唯一索引或 FOR UPDATE 悲观锁 | 实现简单。缺点是性能最差,容易拖垮 DB,仅适合低并发场景。 |
Redisson 看门狗 (Watch Dog):解决“业务没执行完,锁却过期了”的问题。后台线程每隔 10s (默认锁时间的1/3) 自动给锁续期。
缓存高并发三大问题
✨ Java 现代特性演进 (JDK 8 - 21)
+
Lambda 表达式与函数式接口
允许将函数作为方法参数传递。核心依赖 @FunctionalInterface 注解的接口(只有一个抽象方法)。常用内置接口:Predicate, Function, Consumer, Supplier。
Stream API
提供一种高效且易于迭代的处理数据的方式。支持链式操作,分为:创建、中间操作(filter, map, sorted, distinct)、终端操作(collect, count, forEach, reduce)。
List<String> names = users.stream()
.filter(u -> u.getAge() > 18)
.map(User::getName)
.sorted()
.collect(Collectors.toList());
Optional 类
一个容器对象,代表一个值存在或不存在。用于优雅地处理 null 值,避免 NullPointerException。常用方法:orElse(), orElseGet(), map(), ifPresent()。
+
JDK 9 模块化系统 (Project Jigsaw)
将 JDK 拆分为多个模块,通过 module-info.java 声明模块依赖与暴露的包。减小 JRE 体积,强化封装(强封装:默认不反射访问私有成员)。
JDK 10 / 11 语法糖
JDK 14 - 17 现代语法
+
虚拟线程 (Virtual Threads / Project Loom)
Java 并发编程的范式颠覆。传统的平台线程(Platform Thread)与操作系统内核线程是 1:1 映射,创建和上下文切换成本极高(通常受限于几千个并发)。
// 创建并启动虚拟线程
Thread.startVirtualThread(() -> {
System.out.println("Hello from Virtual Thread!");
});
// 使用 ExecutorService
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
IntStream.range(0, 100_000).forEach(i -> {
executor.submit(() -> {
Thread.sleep(Duration.ofSeconds(1)); // 阻塞不会占用平台线程
return i;
});
});
}
模式匹配 (Pattern Matching)
支持 switch 和 instanceof 的类型模式匹配,甚至支持解构 Record 类的内部组件,大幅减少样板代码。
🛠️ 性能调优与线上排错
+
内存与堆栈设置
GC 收集器与日志参数
+
CPU 100% 飙高排查步骤
内存泄漏 (OOM) 分析
利用 jmap -dump:format=b,file=heap.hprof <PID> 导出快照(或依赖启动参数自动生成的 dump 文件)。使用 MAT (Memory Analyzer Tool) 或 VisualVM 打开:
死锁排查
执行 jstack -l <PID>,直接拉到日志最底部,JVM 会自动检测并打印出 "Found one Java-level deadlock" 的详细信息及相互等待的锁对象。
+
什么是 Arthas?
Alibaba 开源的 Java 诊断工具。无需重启服务,即可在命令行实时监控、排查线上问题、甚至动态修改代码。
核心高频命令
🏛️ 设计模式与架构思维
+
+
单例模式 (Singleton) 最佳实践
代理模式 (Proxy)
Spring AOP 的核心。分为:
+
策略模式 + 工厂模式 (消除 if-else)
将不同的业务逻辑封装为独立的策略类(实现统一接口),通过 Map 或 Spring 容器管理策略实例。根据传入的参数(如 type)直接从容器中获取对应的策略执行,彻底消灭臃肿的 if-else/switch 分支。
观察者模式 (Observer) 与 Spring Event
定义对象间的一对多依赖关系。当一个对象状态改变时,所有依赖者都会收到通知并自动更新。解耦生产者和消费者。
Spring 中的实现:
🔍 未找到匹配的教程内容,请尝试其他关键词(如:MVCC, Arthas, 虚拟线程, G1, 雪花算法)。