# JavaEE初阶核心知识点全梳理(面试复习版)
> 本文基于《Java后端极速唤醒计划》的Day 1-2内容,结合多份PDF学习资料,系统整理了JavaEE初阶必须掌握的**JVM、多线程、网络编程、HTTP/HTTPS**四大核心模块。目标读者是“学过但遗忘了”的复习者,每个知识点都配有**面试高频考点**和**一句话记忆口诀**。
---
## 一、计算机基础与JVM
### 1.1 计算机工作基础
**冯诺依曼体系结构**是现代计算机的基石:
| 组件 | 功能 |
| :--- | :--- |
| CPU(中央处理器) | 进行算术运算和逻辑判断 |
| 存储器 | 分为外存和内存,用二进制存储数据 |
| 输入设备 | 用户给计算机发号施令 |
| 输出设备 | 计算机向用户汇报结果 |
**存储速度与容量关系**(面试常考):
- 容量:硬盘 > 内存 >> CPU缓存
- 速度:CPU缓存 >> 内存 > 硬盘
### 1.2 JVM内存结构(高频考点⭐⭐⭐⭐⭐)
JVM运行时数据区分为**线程共享**和**线程私有**两类:
| 区域 | 线程共享 | 存储内容 | 异常 |
| :--- | :--- | :--- | :--- |
| **堆(Heap)** | ✅ 是 | 所有对象实例、数组、字符串常量池 | OutOfMemoryError |
| **元空间(Metaspace)** | ✅ 是 | 类元数据、静态变量 | OutOfMemoryError |
| **虚拟机栈(Stack)** | ❌ 否 | 局部变量表、操作数栈、方法出口 | StackOverflowError |
| **本地方法栈** | ❌ 否 | native方法调用 | StackOverflowError |
| **程序计数器(PC)** | ❌ 否 | 当前执行字节码的行号 | 无 |
> **面试话术**:“堆和元空间是线程共享的,栈和PC是线程私有的。对象存在堆里,局部变量存在栈里。”
### 1.3 垃圾回收(GC)机制
**可达性分析算法**:从GC Roots出发,不可达的对象被标记为可回收。
**GC Roots包括**:
- 虚拟机栈(栈帧局部变量)引用的对象
- 静态变量(`static`)引用的对象
- 活跃的线程(`Thread`)
- JNI引用
**分代收集**:
- **年轻代**:复制算法(Eden + S0 + S1,比例8:1:1)
- **老年代**:标记-整理/标记-清除算法
**引用类型对比**:
| 类型 | 回收时机 | 典型应用 |
| :--- | :--- | :--- |
| 强引用 | 永不回收(OOM也不回收) | 普通对象 |
| 软引用 | 内存不足时回收 | 内存敏感缓存 |
| 弱引用 | 下次GC一定回收 | ThreadLocal |
| 虚引用 | 随时回收 | 跟踪对象回收状态 |
> **记忆口诀**:“强死不收,软满才收,弱遇则收,虚不拿收。”
---
## 二、多线程编程(面试重灾区⭐⭐⭐⭐⭐)
### 2.1 进程与线程的区别
| 维度 | 进程 | 线程 |
| :--- | :--- | :--- |
| 资源分配 | 系统分配资源的最小单位 | 系统调度的最小单位 |
| 内存 | 进程间不共享内存 | 同一进程的线程共享内存 |
| 创建开销 | 大 | 小(比进程轻量) |
| 健壮性 | 一个进程挂了不影响其他进程 | 一个线程挂了可能带走整个进程 |
### 2.2 线程的创建方式
```java
// 方法1:继承Thread类
class MyThread extends Thread {
public void run() { System.out.println("线程执行"); }
}
new MyThread().start();
// 方法2:实现Runnable接口
class MyRunnable implements Runnable {
public void run() { System.out.println("线程执行"); }
}
new Thread(new MyRunnable()).start();
// 方法3:Lambda表达式(最简洁)
new Thread(() -> System.out.println("线程执行")).start();
```
### 2.3 线程的六大状态(高频必问)
| 状态 | 含义 |
| :--- | :--- |
| **NEW** | 线程创建,尚未调用start() |
| **RUNNABLE** | 可运行(正在运行/等待CPU调度) |
| **BLOCKED** | 阻塞等待获取锁(synchronized) |
| **WAITING** | 无限等待(wait()不带超时) |
| **TIMED_WAITING** | 有限等待(sleep()/wait(超时)) |
| **TERMINATED** | 线程执行完毕 |
**状态转移关键点**:
- BLOCKED:等待获取锁
- WAITING:等待其他线程唤醒(notify)
- TIMED_WAITING:等待超时或被唤醒
> **记忆口诀**:“NEW完start变RUN,RUN要等锁变BLOCK,wait一下进WAITING,sleep一下TIMED,run完最后TERMINATED。”
### 2.4 线程安全与synchronized
**线程不安全的三大原因**:
1. 线程调度是抢占式的(随机)
2. 多个线程修改共享数据
3. 操作不是原子的(如 `i++` 包含读-改-写三步)
**synchronized特性**:
- **互斥**:同一把锁,一个线程持有,其他线程阻塞
- **可重入**:同一线程可多次获取同一把锁(不会死锁)
**synchronized使用方式**:
```java
// 1. 修饰代码块(锁指定对象)
synchronized (locker) { count++; }
// 2. 修饰普通方法(锁当前对象this)
public synchronized void method() { }
// 3. 修饰静态方法(锁类的Class对象)
public synchronized static void method() { }
```
**线程安全类对比**:
| 线程不安全 | 线程安全(不建议用) | 线程安全(推荐) |
| :--- | :--- | :--- |
| ArrayList | Vector | CopyOnWriteArrayList |
| HashMap | Hashtable | ConcurrentHashMap |
| StringBuilder | StringBuffer | — |
> **注意**:`String`是不可变类,本身线程安全。
### 2.5 volatile关键字
**作用**:保证**内存可见性**,禁止指令重排序。
**原理**:强制读写主内存,不使用CPU缓存(工作内存)。
**注意**:volatile **不保证原子性**!`volatile int count; count++` 仍然不安全。
> **面试金句**:“volatile解决可见性,synchronized解决原子性+可见性。两者分工不同。”
### 2.6 wait()和notify()
**核心规则**:
- `wait()` 释放锁,进入等待状态
- `notify()` 唤醒一个等待线程
- `notifyAll()` 唤醒所有等待线程
- **必须**在 `synchronized` 代码块中调用
```java
synchronized (locker) {
locker.wait(); // 等待唤醒
locker.notify(); // 唤醒一个
}
```
### 2.7 死锁(面试杀手题)
**死锁的四个必要条件**(必须全部满足):
1. **互斥使用**:资源被一个线程占用时,其他不能使用
2. **不可抢占**:资源只能由占有者主动释放
3. **请求和保持**:占有一个资源的同时请求另一个
4. **循环等待**:线程间形成等待环路
**破坏方法**:最容易破坏的是**循环等待**——采用**锁排序**,所有线程按固定顺序获取锁。
### 2.8 线程池(ThreadPoolExecutor)
**七大核心参数**(面试必须背出):
| 参数 | 含义 |
| :--- | :--- |
| `corePoolSize` | 核心线程数(正式员工) |
| `maximumPoolSize` | 最大线程数(正式+临时) |
| `keepAliveTime` | 临时工空闲存活时间 |
| `unit` | 时间单位 |
| `workQueue` | 阻塞队列(存储任务) |
| `threadFactory` | 线程工厂 |
| `handler` | 拒绝策略 |
**任务提交流程**:
1. 核心线程未满 → 创建核心线程执行
2. 核心线程已满 → 任务入队列
3. 队列已满 → 创建临时线程执行
4. 线程数达最大 → 执行拒绝策略
**拒绝策略**:
- `AbortPolicy`:抛异常(默认)
- `CallerRunsPolicy`:调用者自己执行
- `DiscardOldestPolicy`:丢弃最老任务
- `DiscardPolicy`:丢弃新任务
---
## 三、网络编程基础
### 3.1 网络分层模型
**TCP/IP五层模型**:
| 层级 | 核心协议 | 设备 |
| :--- | :--- | :--- |
| 应用层 | HTTP、HTTPS、DNS | — |
| 传输层 | TCP、UDP | — |
| 网络层 | IP、ICMP | 路由器 |
| 数据链路层 | 以太网 | 交换机 |
| 物理层 | 网线、光纤 | 集线器 |
### 3.2 TCP三次握手(建立连接)
```
客户端 服务端
| SYN (Seq=x) |
|------------------>|
| SYN+ACK (Seq=y, Ack=x+1) |
|<------------------|
| ACK (Ack=y+1) |
|------------------>|
| 连接建立 |
```
**为什么三次?** 防止过期的SYN请求建立错误连接,确保双方都具备收发能力。
### 3.3 TCP四次挥手(释放连接)
**TIME_WAIT状态**(高频面试):
- 持续2MSL(约60秒)
- 作用:确保最后一个ACK被收到;让网络中残留数据消失
- **隐患**:大量短连接会导致TIME_WAIT积压,耗尽端口号
**解决方案**:使用连接池复用连接。
### 3.4 TCP vs UDP对比
| 维度 | TCP | UDP |
| :--- | :--- | :--- |
| 连接 | 有连接 | 无连接 |
| 可靠性 | 可靠传输(确认+重传) | 不可靠 |
| 传输方式 | 面向字节流 | 面向数据报(最大64K) |
| 效率 | 较低 | 较高 |
| 场景 | 文件传输、HTTP | 视频通话、DNS |
> **面试题**:“如何用UDP实现可靠传输?”——在应用层引入序列号、确认应答、超时重传机制(参考TCP的设计)。
---
## 四、HTTP/HTTPS协议(后端开发必备)
### 4.1 HTTP请求格式
```
请求行:GET /api/user/1 HTTP/1.1
请求头:Host: example.com
Authorization: Bearer eyJhbGciOi...
Content-Type: application/json
空行
请求体:{"name": "张三"}
```
### 4.2 HTTP响应格式
```
响应行:HTTP/1.1 200 OK
响应头:Content-Type: text/html
Content-Length: 1234
空行
响应体:<html>...</html>