从语言核心到企业级
小哲的公司接了一个银行项目——招标文件第一条:技术栈必须是 Java。他用 Python 写了十三年系统,这次决定系统学 Java:从 JavaSE 的语言核心、JVM、并发,一路走到 JavaEE 的 Servlet、Spring 全家桶、工程化落地。周师傅说:Java 的世界,一杯咖啡的时间不够,但十站刚刚好。
为什么要学 Java
JavaSE vs JavaEE:一杯咖啡的江湖师傅!公司接了银行核心系统的改造项目,招标要求 Java 技术栈——我用 Python 写了十几年,现在得学 Java 了!JavaSE 和 JavaEE 到底啥关系?
先立框架——Java 分「三兄弟」:
- JavaSE(标准版):语言的「核心」——语法、面向对象、集合、并发、JVM。地基中的地基,必须扎实。
- JavaEE(企业版,现名 Jakarta EE):企业应用的「标准」——Servlet、Web 服务、事务、消息等一揽子规范。
- 框架层(Spring 等):把 JavaEE 规范「更好用」的实现——Spring Boot 已是事实标准。
一句话:JavaSE 是「语言」,JavaEE 是「企业应用的规范」,Spring 是「把规范做到好用」的框架——三层递进,缺一不可。
记住一句话:Java 的江湖,入门靠语法,立足靠 JVM 和并发,扬名靠 Spring 生态。走,第一站,先把语言核心捡起来——你有 Python 底子,学起来会很快。
JavaSE 基础:语言核心
JVM · 面向对象 · 集合 · 泛型 · 异常Java 的「语法」只是外壳,真正的灵魂是 JVM(一次编译到处运行)和面向对象(一切皆对象)。有 Python 基础的话,这站主要学「差异」。
先建立三个「Java 世界观」:
- JVM 与字节码:Java 源码编译成字节码(.class),JVM 负责跑——「一次编译,到处运行」。这也是 Java 性能调优的核心舞台(第 2 站展开)。
- 强类型 + 面向对象:所有变量必须声明类型;一切皆对象(类/继承/多态/封装四件套)。Python 是鸭子类型,Java 是「先立规矩再干活」。
- 集合框架:List(有序)/ Set(去重)/ Map(键值)——Java 后端的「武器库」,面试必考。
public class Main { // 类 = 一切代码的容器
public static void main(String[] args) { // 入口方法
System.out.println("你好,Java!");
}
}
// Python: print("你好,Python!") —— 看到差距了吧:Java 仪式感十足
// 面向对象四件套速览
class Account { // 封装:属性私有
private double balance;
public void deposit(double v) { balance += v; } // 方法公开
}
interface Payable { void pay(double v); } // 接口:多态的地基
class CreditCard implements Payable { ... } // 实现接口
// 集合框架(后端日常)
List<String> names = new ArrayList<>(); // 有序
Set<Long> ids = new HashSet<>(); // 去重
Map<String, Integer> scores = new HashMap<>(); // 键值
// 泛型:一套代码多种类型(第一本的老朋友)
List<Account> accounts = new ArrayList<>();
// 异常:try/catch/finally(第一本老朋友)
try { risky(); } catch (IOException e) { log(e); } finally { cleanup(); }
JavaSE 基础术语
- JDK / JRE / JVM:开发工具包 / 运行环境 / 虚拟机——三者的包含关系(JDK ⊃ JRE ⊃ JVM)。
- 字节码(.class):编译产物——JVM 的执行对象,跨平台的关键。
- 面向对象四件套:封装、继承、多态、抽象——Java 的立身之本。
- 基本类型 vs 包装类:int/Integer、double/Double——自动装箱拆箱的坑。
- 集合框架:List/Set/Map + 实现类(ArrayList/HashSet/HashMap)——选对容器是基本功。
- 泛型 / 异常 / 注解:类型安全 / 错误处理 / 元数据——Java 的三大语法支柱。
- String 不可变:字符串拼接用 StringBuilder——性能常识。
本站收获:JavaSE 基础 = JVM/字节码(跨平台)+ 面向对象四件套 + 集合框架 + 泛型异常注解。有 Python 底子,语法两天就熟——难的是「类型思维」和「JVM 世界观」。
JVM 内存与 GC
堆/栈/方法区 · 垃圾回收 · G1/ZGC · 调优参数Java 程序员和 Python 程序员最大的不同:Java 要懂「内存怎么分、垃圾怎么收」。JVM 就是 Java 应用的「操作系统」——这是面试重灾区,也是排障主战场。
JVM 内存分区,先记图:
- 堆(Heap):对象的老家——new 出来的对象都在这,分新生代(伊甸园/幸存区)和老年代。GC 的主战场。
- 栈(Stack):每个线程一块——局部变量和方法调用帧。栈溢出(StackOverflowError)就是递归太深。
- 方法区/元空间:类的元信息、静态变量、常量池。
垃圾回收(GC):JVM 自动找「没人引用的对象」并回收(第一本的老朋友:GC vs 手动管理)。判断标准是可达性分析——从 GC Roots 出发,够不到的就是垃圾。回收器进化:Serial → CMS → G1(当前默认,可控停顿)→ ZGC(毫秒级停顿,超大堆)。
┌────────────── JVM 内存 ──────────────┐
│ 堆 Heap(对象):新生代 + 老年代 │ ← GC 主战场
│ 新生代:伊甸园 Eden → 幸存区 S0/S1 │ 大部分对象朝生夕死
│ 老年代:熬过多次 GC 的对象 │
│ 栈 Stack(每线程):局部变量/方法帧 │ ← 溢出=递归太深
│ 方法区/元空间:类信息/静态变量/常量 │
└─────────────────────────────────────┘
【调优参数(-X 家族)】
-Xms2g -Xmx2g 初始/最大堆(生产要相等,防抖动)
-Xss512k 栈大小
-XX:+UseG1GC 用 G1(默认)
-XX:MaxGCPauseMillis=100 GC 停顿目标
【GC 触发与回收器】
新生代满 → Minor GC(快)
老年代满 → Full GC(慢,卡顿元凶)
G1:把堆分成 Region,优先回收「垃圾最多」的区域
ZGC:并发回收,停顿 < 10ms(超大堆场景)
【OOM 与排查(第9站展开)】
OutOfMemoryError: Java heap space 堆满了
GC overhead limit exceeded 回收太多次还满
【Java 与 Python 内存对比】
Python:引用计数 + 分代 GC(CPython 的痛)
Java:可达性分析 + 成熟的分代 GC——大厂后端首选
JVM 术语
- 堆 / 栈 / 方法区:对象 / 线程局部 / 类元信息——三分天下。
- 新生代 / 老年代:朝生夕死 vs 老而不死——分代回收的依据。
- 可达性分析:从 GC Roots 出发找垃圾——判断对象死活的标准。
- GC Roots:栈帧引用、静态变量、常量等——垃圾判断的「起点」。
- G1 / ZGC:现代回收器——可控停顿 / 毫秒级停顿。
- Minor GC / Full GC:新生代快回收 / 全堆大回收(卡顿元凶)。
- -Xmx / -Xms:堆大小配置——OOM 的第一道防线。
本站收获:JVM = 堆(对象)+ 栈(线程)+ GC(自动回收)。调优不是炫技——「堆设多大、用什么回收器、Full GC 频率」直接决定应用稳不稳。面试必问,排障必用。
并发编程:多线程与锁
线程池 · synchronized · Lock · volatile · JUC后端高并发的核心战场——Java 并发是面试最深的水,也是线上「扣库存、发券、秒杀」这些场景的命根子。学完并发,你才敢说自己会 Java 后端。
并发三大问:线程怎么建?数据怎么同步?任务怎么复用?
- 建线程:继承 Thread / 实现 Runnable / 实现 Callable——但生产基本不直接 new 线程,而是用线程池(复用,避免频繁创建销毁的开销)。
- 同步:synchronized(内置锁,简单)vs Lock(显式锁,可超时可中断);volatile(可见性,不保证原子性);并发容器(ConcurrentHashMap 等)。
- 线程池:ThreadPoolExecutor——核心线程数、最大线程数、队列、拒绝策略——四大参数是面试必考。
底层兵器:CAS(乐观锁,无锁编程的基础)和 AQS(同步器框架,Lock/信号量都基于它)。
// 线程池:复用线程,控制并发度
ThreadPoolExecutor pool = new ThreadPoolExecutor(
10, // 核心线程数:常驻 10 个
50, // 最大线程数:高峰 50 个
60, TimeUnit.SECONDS,// 空闲回收时间
new ArrayBlockingQueue<>(100), // 任务队列:缓冲
new ThreadPoolExecutor.CallerRunsPolicy() // 拒绝策略
);
// 同步:synchronized vs Lock
synchronized (lock) { balance -= amount; } // 简单内置锁
Lock lock = new ReentrantLock();
if (lock.tryLock(3, TimeUnit.SECONDS)) { // 可超时!
try { balance -= amount; } finally { lock.unlock(); }
}
// volatile:可见性(不加锁的轻量同步)
volatile boolean running = true; // 多线程都能看到最新值
// 并发容器:高并发安全的「武器库」
ConcurrentHashMap<String, Integer> cache = new ConcurrentHashMap<>();
CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>();
【CAS vs AQS(底层)】
CAS:Compare And Swap——无锁比较交换(乐观锁)
AQS:抽象同步队列——ReentrantLock/Semaphore 的骨架
【四大并发问题】
原子性(加锁)· 可见性(volatile)· 有序性(指令重排)
死锁(两个线程互相等对方的锁——排查靠 dump)
库存 100 件、同时 1 万人抢——裸写 `if(stock>0) stock--` 必然超卖。解法:数据库乐观锁(`UPDATE ... WHERE stock > 0`)+ 应用层限流 + 线程池控并发——再加 Redis 预扣库存。Java 并发知识在这里全部用上,超卖率归零。
并发术语
- 线程池(ThreadPoolExecutor):四大参数——核心/最大/队列/拒绝策略。
- synchronized vs Lock:内置锁 vs 显式锁——后者可超时可中断。
- volatile:可见性、不保证原子性——轻量同步。
- JUC 并发容器:ConcurrentHashMap / CopyOnWriteArrayList——高并发安全集合。
- CAS:乐观锁无锁编程——「比较再交换」。
- AQS:同步器骨架——Lock/信号量都基于它。
- 死锁 / 原子性 / 可见性 / 有序性:并发四大坑——面试连环问。
本站收获:并发 = 线程池复用线程 + 锁保原子性 + 并发容器护数据 + CAS/AQS 打底。秒杀、扣库存、发券——所有高并发场景的答案都在这一站。
IO 与网络:Netty
BIO/NIO/AIO · Netty · Socket 编程「百万连接」「高吞吐网关」这些词背后,是 Java 的 IO 模型进化史:从一请求一线程的 BIO,到事件驱动的 NIO,再到封神框架 Netty。
IO 三代进化:
- BIO(阻塞 IO):一个连接一个线程,阻塞等数据——简单但线程开销大,撑不起高并发。
- NIO(非阻塞 IO):一个线程管 N 个连接(Selector 多路复用器)——事件来了才处理,线程数大减。
- AIO(异步 IO):真正异步回调——但 Java 生态用得少。
Netty:基于 NIO 的高性能网络框架——Dubbo、RocketMQ、Spark 底层都在用。核心概念:Channel(连接)、EventLoop(事件循环线程)、Pipeline(处理器链)、编解码器。它是 Java 网络编程的「内功」。
【BIO:一连接一线程】
Thread1 ← 连接1(阻塞等待数据)
Thread2 ← 连接2
Thread3 ← 连接3
→ 10000 连接 = 10000 线程 = 内存爆炸
【NIO:一线程多连接(Selector)】
Thread ← Selector(多路复用器)← 连接1/2/3...
事件驱动:哪个连接有数据,处理哪个
→ 10000 连接 = 1 个线程搞定(事件模型)
【Netty 架构(重点概念)】
Channel:一条连接
EventLoop:事件循环线程(一个 EventLoop 管多个 Channel)
Pipeline:处理器链(入站/出站 Handler)
ChannelHandler:业务处理器(编解码/业务逻辑)
编解码器:ByteBuf 与对象的互转(Protobuf/JSON)
【Netty 的应用】
Dubbo(RPC)、RocketMQ(消息)、Spark(网络通信)
→ 学 Netty = 看懂半个中间件源码
【对比 Python】
Python asyncio 也是事件驱动——思路一样(第九本 Flink 的背压也是同源)
IO 术语
- BIO / NIO / AIO:阻塞 / 非阻塞多路复用 / 异步——三代进化。
- Selector(多路复用器):一个线程监听 N 个通道的事件——NIO 的灵魂。
- Netty:NIO 高性能网络框架——中间件的事实底层。
- EventLoop / Pipeline / Handler:事件循环 / 处理器链 / 业务处理——Netty 三件套。
- 零拷贝:减少数据复制——Netty 高性能的秘密武器之一。
- 背压:下游慢自动限速——和 Flink 同源的思想。
本站收获:IO = BIO 简单扛不住、NIO 事件驱动省线程、Netty 封装到位被全网用。学 Netty 不是为了写框架,是为了读懂 Dubbo/RocketMQ 这些「大厂零件」。
JavaEE:Servlet 与容器
Servlet · Tomcat · Filter · JSP · Jakarta EEJavaSE 是「语言」,JavaEE 是「企业应用的规范」——而 Servlet 是 JavaEE 的起点:Web 请求怎么进来、怎么处理、怎么响应,全在这套规范里。
先认识主角:
- Servlet:Java 处理 HTTP 请求的「标准组件」——一个类,收到请求、处理、返回响应。
- Tomcat(Web 容器):Servlet 的「宿舍」——管理 Servlet 的生命周期(加载/实例化/调用/销毁),监听端口接收 HTTP 请求。
- Filter(过滤器):请求的「安检门」——登录校验、编码、日志,在进 Servlet 前拦截。
- JSP:老式动态页面技术(已被前后端分离取代,但老项目还在)。
JavaEE 现在叫 Jakarta EE——除了 Servlet,还包含 JPA(持久化)、EJB(企业组件)、JMS(消息)等一堆规范。不过真实世界:这些规范大多被 Spring「更好用」地实现了——下一站的主角。
浏览器 → GET /api/account/100
↓
Tomcat(Web 容器,监听 8080)
↓ 解析 HTTP 请求
Filter 链(安检门:登录校验 → 编码 → 日志)
↓ 通过
Servlet(业务处理)
↓ 调用 Service/DAO → 数据库
↓ 返回 JSON
Tomcat 打包 HTTP 响应 → 浏览器
【Servlet 核心(简版)】
public class AccountServlet extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
Long id = Long.parseLong(req.getParameter("id"));
Account account = accountService.findById(id);
writeJson(resp, account); // 返回 JSON
}
}
【Servlet 生命周期(面试必问)】
加载 → 实例化 → init(一次)→ service(每次请求)
→ destroy(销毁)——容器全包,程序员只写业务
【Filter 用法】
doFilter 里:before 处理(校验)→ chain.doFilter(放行)→ after(日志)
【Tomcat 核心参数】
线程池(maxThreads)、连接数(acceptCount)
连接器协议:BIO(老)/ NIO(现代,第4站知识)
JavaEE 术语
- Servlet:HTTP 处理标准组件——JavaEE 的起点。
- Tomcat / Web 容器:Servlet 的宿主——管理生命周期 + 解析 HTTP。
- Filter 过滤器:请求安检门——鉴权/编码/日志的经典位置。
- Jakarta EE(原 JavaEE):企业应用规范集合——Servlet/JPA/EJB/JMS。
- Servlet 生命周期:init → service → destroy——面试必问。
- JSP:老式模板技术——了解即可,新项目已不用。
- war 包:Web 应用的打包格式(部署到 Tomcat)。
本站收获:JavaEE 起点 = Servlet 处理请求 + Tomcat 当宿主 + Filter 做安检。虽然真实开发已被 Spring 接管,但理解「请求如何被处理」这条链路,是看懂一切 Java Web 的地基。
Spring 全家桶:企业之王
IoC/DI · AOP · Spring MVC · Spring Boot/CloudJavaEE 规范是「标准」,Spring 是「让标准好用一万倍」的框架——Java 后端十有八九跑在 Spring 上。这一站是整个 Java 生态的「王炸」。
Spring 家族四大核心:
- IoC(控制反转)/ DI(依赖注入):对象不由你 new,交给 Spring 容器管;要用啥,声明一下自动注入——解耦的核心。
- AOP(面向切面编程):把「日志、事务、鉴权」这些横切逻辑抽出来统一织入——不污染业务代码(第十一本的装饰器/元编程在 Java 的形态)。
- Spring MVC:Web 层的 MVC 框架——Controller/Service/DAO 三层标准结构。
- Spring Boot:自动配置 + 内嵌 Tomcat——「约定优于配置」,一个 jar 就跑起来,Java 后端的事实标准入口。
- Spring Cloud:微服务全家桶——服务发现/网关/配置中心/熔断(第十一本微服务的 Java 落地)。
@SpringBootApplication // 启动类:自动配置全开
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
@RestController // Controller 层:接请求
@RequestMapping("/api/accounts")
public class AccountController {
@Autowired // DI:依赖注入,不用自己 new
private AccountService service;
@GetMapping("/{id}")
public Account get(@PathVariable Long id) {
return service.findById(id);
}
}
@Service // Service 层:业务逻辑
public class AccountService { ... }
@Repository // DAO 层:数据库(第7站)
public interface AccountMapper { ... }
【IoC 与 AOP 一句话】
IoC:对象生命周期交给容器——你要啥我给你啥
AOP:横切逻辑(日志/事务)织入——业务代码不掺杂质
【Spring Boot 魔法】
内嵌 Tomcat → 一个 jar 直接跑(不用装容器!)
自动配置 → 引入依赖即生效
application.yml → 集中配置(第4站 K8s ConfigMap 喂给它)
【Spring Cloud 微服务(衔接第11本)】
Nacos/Eureka 注册中心 · Gateway 网关 · OpenFeign 调用
Sentinel 熔断限流 · Config 配置中心 → 微服务全家桶
银行项目要求 Java 技术栈——小哲用 Spring Boot 3 起步:一个启动类 + 三层结构,第一天就搭出可运行的骨架;配合 Spring Cloud 接微服务治理,老项目的 JavaEE 遗留模块用 Servlet 兼容——技术栈切换平滑落地。
Spring 术语
- IoC / DI:控制反转 / 依赖注入——对象容器化管理。
- AOP:面向切面——日志/事务/鉴权的统一织入。
- Spring MVC:Controller/Service/DAO 三层——Java Web 标准结构。
- Spring Boot:自动配置 + 内嵌容器——事实标准的入口。
- Spring Cloud:微服务全家桶——注册中心/网关/熔断。
- @Autowired / @Service / @RestController:注解驱动——元编程的 Java 形态。
- 约定优于配置:Boot 的设计哲学——少写配置多干活。
本站收获:Spring = IoC 管对象 + AOP 切横切 + Boot 自动配置 + Cloud 上微服务。这一站学完,你写的就不再是「Java 代码」而是「能上线的 Java 应用」。
数据库访问:JDBC 到 ORM
JDBC · 连接池 · MyBatis/JPA · 事务 · 锁后端 70% 的代码是「和数据库打交道」。从手写 JDBC 到 MyBatis/JPA,Java 的数据库访问有完整进化链——事务和锁是面试永恒的主题。
进化链四步:
- JDBC:最原始的数据库 API——手写连接、手写 SQL、手写结果集。慢、繁琐、易错。
- 连接池(HikariCP):数据库连接「复用」——建连接很贵,池子随取随还(Spring Boot 默认内置)。
- ORM 框架:MyBatis(SQL 半自动,国内主流)vs JPA/Hibernate(全自动实体映射,国外主流)——把「结果集」变成「对象」。
- 事务管理:Spring @Transactional——「要么全成要么全不成」(第一本老朋友:ACID)。
再加锁的世界观:乐观锁(version 字段,冲突重试)vs 悲观锁(SELECT FOR UPDATE,直接锁行)——第 3 站并发知识的数据库版。
@Mapper
public interface AccountMapper {
@Select("SELECT * FROM accounts WHERE id = #{id}")
Account findById(Long id);
}
// 事务:转账 = 扣 A + 加 B,必须一起成功
@Service
public class TransferService {
@Transactional // 事务边界:失败全回滚
public void transfer(Long fromId, Long toId, BigDecimal amount) {
accountMapper.debit(fromId, amount); // 扣款
accountMapper.credit(toId, amount); // 加款
// 任一失败 → 全部回滚,钱不会消失
}
}
// 乐观锁:库存扣减(防超卖,第3站并发知识落地)
@Update("UPDATE products SET stock = stock - 1, version = version + 1 " +
"WHERE id = #{id} AND stock > 0 AND version = #{version}")
int deductStock(Long id, int version); // 影响行数=0 说明冲突,重试
【ORM 二选一】
MyBatis:SQL 自己写(灵活、国内主流)
JPA/Hibernate:实体自动映射(开发快、国外主流)
【连接池参数】
maximumPoolSize(最大连接)、connectionTimeout(获取超时)
→ 连接池耗尽 = 数据库扛不住的第一个信号
【慢查询排查】
数据库慢查询日志 + EXPLAIN 看索引(第八本老朋友)
银行项目核心:转账。@Transactional 保证「扣款+加款」原子性;乐观锁防并发重复扣减;HikariCP 连接池扛住峰值。上线后压测 2000 TPS 不丢一笔——事务 + 锁 + 连接池三件套,Java 银行系统的日常。
数据库访问术语
- JDBC:Java 数据库连接的原始 API。
- 连接池(HikariCP):连接复用——性能生命线。
- ORM(MyBatis / JPA):SQL 与对象的桥——MyBatis 半自动 / JPA 全自动。
- @Transactional:声明式事务——ACID 的 Java 形态。
- 乐观锁 / 悲观锁:version 重试 vs SELECT FOR UPDATE。
- MyBatis 动态 SQL:if/foreach 拼条件——复杂查询的利器。
- Mapper / DAO:数据访问层——分层架构的底层。
本站收获:数据库 = JDBC 打底 + 连接池保性能 + ORM 提效率 + @Transactional 保事务 + 锁防并发。CRUD 人人会写,「事务和锁」才是区分初级和高级的分水岭。
工程化:构建测试部署
Maven/Gradle · JUnit · SLF4J · 打包部署代码写好了,怎么变成「能上线的产品」?构建工具、单元测试、日志、打包部署——工程化是把「会写代码」升级成「会交付」的必修课。
工程化四件套:
- 构建工具(Maven/Gradle):依赖管理 + 编译打包——`pom.xml` 声明依赖,`mvn package` 出 jar。Gradle 更快更现代。
- 单元测试(JUnit):每个方法的小测试——`@Test` + 断言。配 Mockito 模拟依赖(第二本 SAST/测试老朋友)。
- 日志(SLF4J + Logback):统一日志门面 + 实现——分级(debug/info/warn/error),生产排障的「黑匣子」(第十二本 ELK 的 Java 原料)。
- 打包部署:Spring Boot 打 fat jar → Docker 镜像 → K8s(第十三本老朋友)——Java 应用的现代部署链。
<!-- Maven pom.xml:依赖声明 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- mvn clean package → 一个可运行 jar -->
// JUnit 单元测试
class TransferServiceTest {
@Test
void transfer_should_deduct_and_credit() {
// given / when / then 三段式
service.transfer(1L, 2L, new BigDecimal("100"));
assertEquals(new BigDecimal("-100"), accountMapper.balance(1L));
}
}
// 日志(SLF4J 门面)
private static final Logger log = LoggerFactory.getLogger(AccountService.class);
log.info("查询账户 id={}", id); // 生产排障靠它
log.error("转账失败 from={} to={}", fromId, toId, e);
【部署链(现代 Java 应用)】
源码 → Maven 构建 → jar 包 → Docker 镜像
→ 镜像仓库 → K8s 部署(第13本老朋友)
→ 日志进 ELK(第12本老朋友)→ 监控告警
→ 全链路自动化:CI/CD(第2本老朋友)
【Java 版本选择(2026)】
LTS 版本是王道:Java 17(现役主流)/ Java 21(新 LTS)
每半年一个非 LTS,别追新——生产用 LTS
【IDE 与效率】
IntelliJ IDEA(事实标准)· Lombok 省样板代码
代码规范:阿里巴巴 Java 开发手册(国内事实标准)
工程化术语
- Maven / Gradle:依赖管理 + 构建——pom.xml / build.gradle。
- JUnit / Mockito:单元测试 + 依赖模拟——测试金字塔的基层。
- SLF4J / Logback:日志门面 + 实现——分级日志是排障黑匣子。
- fat jar / Docker:Spring Boot 可执行 jar → 容器镜像——现代部署形态。
- LTS 版本:Java 17 / 21——生产只选 LTS。
- Lombok:@Data 等注解消除样板代码——写 Java 的快乐源泉。
- 阿里开发手册:国内 Java 编码规范事实标准。
本站收获:工程化 = Maven 管依赖 + JUnit 保质量 + SLF4J 留日志 + Docker/K8s 做部署。会写代码的是「开发」,能交付的是「工程师」——差距就在这四件套。
性能排障:实战内功
OOM 排查 · jstat/jmap · Arthas · 线程 dump · 调优线上 OOM、CPU 飙高、接口突然变慢——「会写」和「会救」之间隔着一整套排障工具链。这一站,是 Java 工程师的「急诊科」。
三大经典故障与兵器库:
- OOM(内存溢出):堆满了——先看堆 dump(jmap 导出),再分析「谁占了大头」——往往是缓存无限膨胀、大对象泄漏、连接没关。
- CPU 飙高:top 找进程 → 线程 dump(jstack)→ 找 RUNNABLE 线程 → 看栈定位热点代码——往往是死循环、正则回溯、GC 疯狂。
- 接口变慢:慢查询 → 连接池耗尽 → 锁竞争 → GC 频繁——逐层排查。
现代排查神器:Arthas(阿里开源)——线上直接看方法调用耗时、反编译、热更新,Java 排障的「瑞士军刀」。
【兵器库】
jps / jstat :看进程 / JVM 状态(GC 频率、堆使用)
jmap :导出堆 dump(OOM 分析)
jstack :线程 dump(死锁/热点线程)
jcmd / jinfo :诊断 / 看启动参数
Arthas :线上神兵——方法耗时/反编译/热更新
可视化:VisualVM / JProfiler / MAT(堆分析)
【OOM 排查七步(实战流程)】
① 启动参数加 -XX:+HeapDumpOnOutOfMemoryError(自动留证据)
② 等 OOM → 拿到 dump 文件
③ MAT/VisualVM 打开 → 看「Dominator Tree」(谁占内存)
④ 定位大对象/泄漏点(缓存无限涨?连接没关?)
⑤ 修代码(限流缓存/close 资源/分批加载)
⑥ 压测验证不再 OOM
⑦ 加监控(堆使用率告警,第12本 ELK 老朋友)
【接口慢排查口诀】
先看数据库慢查询 → 再看连接池 → 再看锁等待
→ 再看 GC 频率 → 最后看代码热点(Arthas trace)
【JVM 调优参数清单(生产标配)】
-Xms = -Xmx(防抖动)· -XX:+UseG1GC · 最大停顿目标
-XX:+HeapDumpOnOutOfMemoryError(必加!)
-XX:MetaspaceSize(元空间初始值)
凌晨告警:订单服务 OOM 重启。小哲用 HeapDumpOnOutOfMemoryError 留下的 dump → MAT 一查:ConcurrentHashMap 缓存无限膨胀(key 是用户 ID,只加不删)→ 根因:缓存没设过期、没加容量上限 → 修复:加 Caffeine 本地缓存 + 容量上限。三天后再没 OOM——「工具 + 流程」就是 Java 工程师的内功。
排障术语
- jmap / jstack / jstat:堆 dump / 线程 dump / JVM 状态——三件基础兵器。
- Arthas:线上诊断神器——方法耗时、反编译、热更新。
- OOM 排查流程:留 dump → 分析 Dominator → 定位泄漏 → 修复 → 压测。
- 线程 dump 看死锁:两个线程互等锁——jstack 一眼定位。
- CPU 飙高排查:top → jstack → 热点线程栈 → 代码热点。
- MAT / VisualVM:堆分析工具——OOM 的「验尸官」。
- HeapDumpOnOutOfMemoryError:OOM 自动留证据——生产必加。
本站收获:排障 = jmap/jstack 看内存线程 + Arthas 线上诊断 + OOM 七步流程 + 调优参数打底。会写代码值 30 分,会救火的 Java 工程师才值 100 分。
学习路线:从入门到进阶
3 个月计划 · OCP 认证 · 职业方向 · Java 17+ 新特性知识体系讲完了,怎么落地成「能力」?这一站给学习路线、认证参考、职业方向,还有面试官最爱问的「新特性」——学完就能上战场。
3 个月学习计划(有编程基础版):
- 第 1 月(JavaSE):语法 + 面向对象 + 集合 + 异常 + IO——配合 LeetCode 练手。
- 第 2 月(进阶):JVM 内存/GC + 并发 + Netty 基础——面试深水区。
- 第 3 月(企业级):Servlet 原理 + Spring Boot 实战 + MyBatis + 一个完整项目(如秒杀系统)——项目是面试的敲门砖。
认证:OCP(Oracle 认证 Java 程序员)——入门证书,加分项不是必需品;项目经验和源码理解更值钱。方向:Java 后端 → 分布式/高并发 → 架构师。
// ① record:不可变数据类(一行顶十行)
public record Order(Long id, BigDecimal amount) {}
Order o = new Order(1L, new BigDecimal("99.9"));
o.id(); // 自动有访问器,不用写 getter
// ② switch 表达式(更简洁)
String level = switch (score / 10) {
case 9, 10 -> "A";
case 7, 8 -> "B";
default -> "C";
};
// ③ 文本块(多行字符串)
String sql = """
SELECT * FROM orders
WHERE status = 'PAID'
""";
// ④ sealed 密封类(限制继承范围)
public sealed interface Payable permits Card, Cash, Crypto {}
public record Card() implements Payable {}
【学习资源】
书:《Java 核心技术》《Effective Java》《深入理解 Java 虚拟机》
在线:廖雪峰 Java 教程、阿里巴巴 Java 开发手册
练手:写一个「秒杀系统」(并发+事务+Redis 全家桶)
刷题:LeetCode(面试算法关)
【职业方向(Java 后端)】
CRUD 工程师 → 业务开发 → 中间件/基础架构 → 架构师
Java 后端需求量大:银行/电商/政务/金融——中年危机?不存在的
(大厂岗位:Java 开发、后端工程师、中间件开发、大数据开发)
【避坑清单】
✗ 只学语法不学 JVM(面试必挂)
✗ 不写项目光背八股(一问项目就露馅)
✗ 追新版本不用 LTS(生产事故)
✗ 忽略并发和事务(后端大忌)
学习路线术语
- 3 个月路线:SE 语法 → JVM/并发 → Spring 实战项目。
- OCP 认证:Oracle Java 认证——入门加分项。
- Java 17/21 LTS:生产选 LTS——新特性 record/switch/文本块。
- 秒杀系统项目:并发+事务+缓存全家桶——面试最佳作品。
- 职业路径:业务开发 → 中间件 → 架构师。
- 八股 vs 实战:背概念过不了面试,项目才是硬通货。
本站收获:路线 = 1 月语法 + 2 月 JVM 并发 + 3 月 Spring 实战。认证是门票、项目是硬通货、新特性是加分——「会背八股」不如「写过秒杀」。
知识点速查 + 面试高频题
面试前最后一页JavaSE → JavaEE 知识全景表
| 领域 | 核心知识点 | 一句话人话 |
|---|---|---|
| JavaSE 基础 | JVM/字节码、面向对象、集合、泛型、异常 | 语言的「核心语法」 |
| JVM | 堆/栈/方法区、GC、G1/ZGC、-Xmx 调优 | Java 的「操作系统」 |
| 并发 | 线程池、synchronized/Lock、volatile、JUC、CAS/AQS | 高并发的「命根子」 |
| IO/网络 | BIO/NIO/AIO、Netty(EventLoop/Pipeline) | 高性能网络的「内功」 |
| JavaEE | Servlet、Tomcat、Filter、Jakarta EE | 企业应用的「老根」 |
| Spring | IoC/DI、AOP、MVC、Boot、Cloud | 企业开发的「王炸」 |
| 数据库 | JDBC、连接池、MyBatis/JPA、事务、乐观锁 | CRUD 背后的「学问」 |
| 工程化 | Maven/Gradle、JUnit、SLF4J、Docker/K8s 部署 | 会交付的「门槛」 |
| 排障 | jmap/jstack、Arthas、OOM 七步、调优参数 | 会救火的「内功」 |
面试高频题速记
- JDK/JRE/JVM 关系?→ JDK ⊃ JRE ⊃ JVM——开发包/运行环境/虚拟机。
- 为什么 Java 跨平台?→ 字节码 + JVM——「一次编译,到处运行」。
- HashMap 原理?→ 数组+链表+红黑树,hash 定位——面试永恒题。
- synchronized 和 Lock 区别?→ 内置锁 vs 显式锁(可超时/可中断/公平性)。
- 线程池参数?→ 核心/最大/队列/拒绝策略——必须背熟。
- JVM 内存分区?→ 堆/栈/方法区/程序计数器/本地方法栈。
- GC 怎么判断对象可回收?→ 可达性分析(GC Roots 出发)。
- Spring IoC 是什么?→ 对象由容器管理,依赖注入——解耦。
- @Transactional 失效场景?→ 同类内部调用/异常被吞/非 public——高频坑。
- OOM 怎么排查?→ HeapDump → MAT → Dominator → 定位泄漏。
入门靠语法,立足靠 JVM 和并发,扬名靠 Spring 生态。
一条完整的 Java 后端之路;
它不性感,但它养活了大半个软件世界的企业系统——
这就是一杯咖啡的力量。