feat(appendix): 添加多个交互式演示组件,完善 AI/Infra 等章节内容

- 新增 Vibe Coding 全栈相关演示组件 (DeveloperSkillShift, FrontendTriad, BackendCore 等)
- 新增 RAG 相关组件 (RAGPipeline, ChunkingStrategy, Retrieval 等)
- 新增 Embedding & Vector 相关组件 (EmbeddingConcept, VectorSimilarity 等)
- 新增 AI Native App 设计组件 (AINativeArch, PromptDesign 等)
- 新增 Infrastructure as Code 组件 (IaCConcept, TerraformWorkflow 等)
- 新增 DNS & HTTPS 演示组件 (DnsResolution, HttpsHandshake 等)
- 新增 Model Finetuning 组件 (FinetuningPipeline 等)
- 更新多个章节的 markdown 内容,集成交互式演示
This commit is contained in:
sanbuphy
2026-02-24 18:22:58 +08:00
parent b5a55811cc
commit 3af119a598
86 changed files with 20311 additions and 340 deletions
@@ -1,9 +1,24 @@
# 算法思维入门
::: tip 🎯 核心问题
::: tip 前言
**如何高效地解决问题?** 你可能遇到过这样的困惑:同一个问题,有人写的代码跑几秒就出结果,有人写的跑几分钟还在转。差别往往在于算法。本章带你理解算法的核心思维方式。
:::
**这篇文章会带你学什么?**
学完这章后,你将获得:
- **问题拆解能力**:面对复杂问题,能想到用分治、递归等策略拆解,而不是一上来就写代码
- **效率判断能力**:用大 O 表示法判断两种解法哪个更高效,而不是凭感觉猜测
- **复杂度思维**:写代码前先估算数据规模和时间要求,选择合适的算法级别
- **后续学习基础**:为高级数据结构、分布式系统、机器学习打下基础
| 章节 | 内容 | 核心概念 |
|-----|------|---------|
| **第 1 章** | 二分查找 | 分治思想、O(log n) |
| **第 2 章** | 排序算法 | 冒泡、快排、归并 |
| **第 3 章** | 复杂度分析 | 时间复杂度、空间复杂度 |
---
## 0. 全景图:算法是什么?
@@ -16,6 +16,8 @@
**这篇文章会带你学什么?**
学完这章后,你将掌握从输入网址到页面显示的完整技术流程,理解浏览器与服务器如何协同工作。这些知识是后续学习 API、接口、网络安全等技术的基石,也是排查"网页打不开"、"加载慢"等日常问题的关键。
| 章节 | 内容 | 核心概念 |
|-----|------|---------|
| **第 1 章** | URL 解析 | 网址的结构和作用 |
@@ -1,10 +1,23 @@
# 什么是数据的编码与传输?
> 💡 **学习指南**:当你给朋友发一张照片、发一条微信,或者下载一个几 GB 的游戏时,这些信息是怎么穿过大半个地球、完好无损地出现在你的屏幕上的?
>
> 本章节会围绕一个经常困扰新手的问题展开:**为什么我收到的文件变成了乱码?**
>
> 顺着这个问题,我们将彻底揭开计算机底层最核心的三大基石:**编码、存储与传输**。
::: tip 前言
当你给朋友发一张照片、发一条微信,或者下载一个几 GB 的游戏时,这些信息是怎么穿过大半个地球、完好无损地出现在你的屏幕上的?本章节会围绕一个经常困扰新手的问题展开:**为什么我收到的文件变成了乱码?** 顺着这个问题,我们将彻底揭开计算机底层最核心的三大基石:**编码、存储与传输**。
:::
**这篇文章会带你学什么?**
学完这章后,你将获得:
- **乱码排查能力**:遇到"文件打开是乱码"时,能从编码角度分析原因,而不是简单认为"文件坏了"
- **跨平台意识**:处理数据交换时,知道为什么要关注编码格式和字节序
- **编码世界观**:理解计算机如何用 0 和 1 表示世间万物——从文字到图像到复杂对象
- **后续学习基础**:为网络协议、文件格式、序列化技术打下基础
| 章节 | 内容 | 核心概念 |
|-----|------|---------|
| **第 1 章** | 字符编码 | ASCII、UTF-8、GBK |
| **第 2 章** | 数据存储 | 二进制、字节序 |
| **第 3 章** | 数据传输 | 序列化、压缩 |
在开始之前,我们需要先明确一个经常被新手忽略的物理事实:
@@ -1,9 +1,25 @@
# 数据结构
::: tip 🎯 核心问题
::: tip 前言
**如何高效地组织和存储数据?** 你可能遇到过这样的困惑:为什么有些程序处理几万条数据很快,有些处理几百条就卡住了?答案往往在于数据结构的选择。本章带你理解常见数据结构的特点和适用场景。
:::
**这篇文章会带你学什么?**
学完这章后,你将获得:
- **选型决策能力**:知道什么时候用数组快速访问,什么时候用链表灵活插入
- **性能分析视角**:能判断性能问题是数据结构选择不当,还是算法效率低下
- **权衡思维**:理解"空间换时间"与"时间换空间",知道没有完美的数据结构
- **后续学习基础**:为数据库、缓存系统、搜索引擎等技术打下基础
| 章节 | 内容 | 核心概念 |
|-----|------|---------|
| **第 1 章** | 线性结构 | 数组、链表、栈、队列 |
| **第 2 章** | 哈希结构 | 哈希表、冲突处理 |
| **第 3 章** | 树形结构 | 二叉树、B树、堆 |
| **第 4 章** | 图结构 | 有向图、无向图、遍历算法 |
---
## 0. 全景图:数据结构是什么?
@@ -1,12 +1,27 @@
# 操作系统:给电脑请个"大管家"
::: tip 🎯 核心问题
::: tip 前言
**有了完美的 CPU 和无限的内存,电脑就能直接用了吗?**
在上一章,我们见证了晶体管如何组合成强大的 CPU。但即使你拥有最顶级的硬件,如果直接让它们工作,连在屏幕上显示一个字母都需要写几百行晦涩的机器指令。不仅麻烦,还极其危险——稍有差池,你的代码就可能把别人的数据覆盖掉。
为了解决这些噩梦,**操作系统(Operating System, 简称 OS)**诞生了。它是挡在你和冰冷硬件之间的一层最伟大的"软件"。本章我们将抛开深奥的代码,用通俗的比喻,看看这个"超级管家"是如何把杂乱无章的硬件调教得服服帖帖的。
:::
**这篇文章会带你学什么?**
学完这章后,你将获得:
- **问题排查能力**:遇到"程序卡死"、"内存不足"时,能从操作系统层面分析原因
- **术语理解深度**:理解"多进程"、"虚拟内存"、"文件权限"解决的是什么问题
- **系统观思维**:理解程序不是孤立运行的,而是与操作系统、其他进程、硬件资源密切交互
- **后续学习基础**:为并发编程、系统调优、容器技术打下基础
| 章节 | 内容 | 核心概念 |
|-----|------|---------|
| **第 1 章** | 进程管理 | CPU 时分复用、时间片轮转 |
| **第 2 章** | 内存管理 | 虚拟内存、分页机制 |
| **第 3 章** | 文件系统 | 文件组织、目录结构 |
---
## 0. 全景图:没有操作系统会怎样?
@@ -0,0 +1,452 @@
# 从按下电源到访问网站发生了什么
::: tip 前言
你有没有想过,当你按下电脑电源键,到最终在浏览器中看到网页,这中间到底发生了什么?
这个过程涉及**硬件启动**、**操作系统加载**、**网络通信**等多个环节。理解这个过程,能帮助你建立对计算机系统的整体认知,也是成为全栈工程师的必经之路。
:::
**你会学到什么?**
- 电脑从通电到显示桌面的完整过程
- 操作系统是如何启动的
- 浏览器是如何工作的
- 当你访问一个 URL 时,网络请求是如何完成的
---
## 1. 按下电源:硬件的觉醒
### 1.1 电源启动
当你按下电源键,**电源单元(PSU)** 开始工作,把交流电(220V)转换成直流电(12V、5V、3.3V 等),为各个硬件部件供电。
```
电源按钮 → 电源单元(PSU) → 直流电输出 → 供给主板各部件
```
### 1.2 主板芯片组唤醒
电源稳定后,**主板芯片组**开始工作,它就像电脑的"总调度员",负责协调各个硬件部件。
### 1.3 CPU 复位
CPU 接收到复位信号后,把内部所有寄存器和缓存清零,从一个预设的地址开始执行指令。这个地址通常指向 **BIOS/UEFI** 芯片。
<PowerOnDemo />
---
## 2. BIOS/UEFI:硬件的自检
### 2.1 什么是 BIOS/UEFI
**BIOSBasic Input/Output System** 是电脑启动后第一个运行的程序,存储在主板的一个**只读芯片**中。
**UEFIUnified Extensible Firmware Interface** 是 BIOS 的升级版,更安全、更现代。现在的电脑大多使用 UEFI。
### 2.2 BIOS/UEFI 做了什么?
1. **硬件自检(POST**:检查内存、显卡、键盘等部件是否正常
2. **初始化硬件**:设置硬件工作模式
3. **启动顺序**:按照设定顺序,尝试从硬盘/U 盘/网络启动
```
BIOS/UEFI 工作流程:
┌─────────────────────────────────────┐
│ 1. 硬件自检 (POST) │
│ - 检查内存是否正常 │
│ - 检查显卡是否正常 │
│ - 检查键盘/鼠标是否正常 │
├─────────────────────────────────────┤
│ 2. 初始化硬件 │
│ - 设置硬件工作模式 │
│ - 配置中断向量表 │
├─────────────────────────────────────┤
│ 3. 寻找启动设备 │
│ - 按启动顺序查找可启动设备 │
│ - 读取启动扇区 │
└─────────────────────────────────────┘
```
如果发现问题,主板会发出**蜂鸣声**(不同次数代表不同错误)。
### 2.3 启动顺序
BIOS/UEFI 会按照设定的**启动顺序**查找启动设备:
1. 硬盘(最常见)
2. U 盘/光盘(重装系统时用)
3. 网络( PXE 启动,企业批量部署用)
找到第一个可启动设备后,读取它的**启动扇区(Boot Sector)**,把控制权交给操作系统。
---
## 3. 操作系统启动:从内核到桌面
### 3.1 什么是操作系统?
**操作系统(Operating System,简称 OS** 是管理计算机硬件和软件资源的程序集合。它就像一个"大管家",帮我们管理内存、CPU、文件等资源,让我们不需要直接和硬件打交道。
常见的操作系统:
| 操作系统 | 特点 | 典型设备 |
|---------|------|---------|
| **Windows** | 生态丰富,兼容性好 | 桌面电脑、笔记本 |
| **macOS** | 苹果生态,流畅稳定 | Mac 电脑 |
| **Linux** | 开源免费,服务器首选 | 服务器、嵌入式设备 |
| **Android** | 移动端 Linux | 手机、平板 |
| **iOS** | 苹果移动端 | iPhone、iPad |
### 3.2 操作系统的启动过程
当你从硬盘启动时,操作系统的启动过程如下:
<BootProcessDemo />
#### 第一步:引导程序(Bootloader
硬盘的第一个扇区存放着**引导程序(Bootloader)**,它的任务是把操作系统内核加载到内存中。
- **Windows**Bootloader 叫 `bootmgr`
- **Linux**:常见的引导程序有 `GRUB``rEFInd`
```
引导程序工作流程:
┌─────────────────────────────────────┐
│ 1. 读取硬盘分区表 │
│ 2. 找到操作系统分区 │
│ 3. 加载操作系统内核到内存 │
│ 4. 跳转到内核入口点 │
└─────────────────────────────────────┘
```
#### 第二步:内核加载(Kernel
操作系统**内核(Kernel)** 是操作系统的核心,负责管理内存、CPU、进程等核心功能。
```
内核的主要功能:
┌─────────────────────────────────────┐
│ • 进程管理 - 创建/调度进程 │
│ • 内存管理 - 分配/回收内存 │
│ • 文件系统 - 管理文件存储 │
│ • 设备驱动 - 控制硬件设备 │
│ • 网络通信 - 处理网络协议 │
└─────────────────────────────────────┘
```
#### 第三步:系统服务启动
内核加载后,会启动各种**系统服务**:
- **Windows 服务**:更新服务、安全中心、打印机服务
- **Linux 服务**:SSH 服务、网络服务、图形界面(GNOME、KDE)
```
Windows 启动过程:
BIOS → MBR → bootmgr → winload.exe → ntoskrnl.exe → 系统服务 → 桌面
Linux 启动过程:
BIOS → GRUB → vmlinuz (内核) → systemd → 系统服务 → 桌面环境
```
#### 第四步:显示桌面
最后,操作系统启动**图形界面(GUI)**,显示桌面:
- **Windows**explorer.exe(资源管理器)显示桌面
- **Linux**GNOME、KDE、XFCE 等桌面环境
- **macOS**Finder 显示桌面
```
桌面出现的过程:
┌─────────────────────────────────────┐
│ 1. 显卡驱动加载 │
│ 2. 显示服务器启动 │
│ (Windows: Desktop Window Manager)│
│ (Linux: X Server / Wayland) │
│ 3. 桌面环境启动 │
│ 4. 显示桌面背景和图标 │
└─────────────────────────────────────┘
```
<DesktopDemo />
---
## 4. 打开浏览器:应用程序的启动
### 4.1 应用程序的启动过程
当你双击浏览器图标时,操作系统会:
1. **查找可执行文件**:根据文件关联,找到浏览器的 `.exe`Windows)或可执行文件
2. **创建进程**:为浏览器创建一个新的**进程**
3. **加载程序**:把浏览器的代码从硬盘加载到内存
4. **初始化**:启动浏览器的主线程、渲染引擎、网络引擎等
```
浏览器启动过程:
┌─────────────────────────────────────┐
│ 1. 双击图标 │
│ 2. 操作系统查找浏览器可执行文件 │
│ 3. 创建浏览器进程 │
│ 4. 加载浏览器代码到内存 │
│ 5. 初始化各模块(渲染、网络、JS) │
│ 6. 显示浏览器窗口 │
└─────────────────────────────────────┘
```
### 4.2 浏览器的主要组成部分
现代浏览器是一个复杂的"操作系统",主要由以下部分组成:
| 模块 | 功能 |
|-----|------|
| **用户界面** | 地址栏、标签页、书签等 |
| **浏览器引擎** | 协调 UI 和渲染引擎 |
| **渲染引擎** | 解析 HTML/CSS,显示网页 |
| **JavaScript 引擎** | 执行 JavaScript 代码 |
| **网络模块** | 发送 HTTP 请求 |
| **UI 后端** | 绘制基础 UI 组件 |
| **数据存储** | Cookie、LocalStorage 等 |
<BrowserArchitectureDemo />
---
## 5. 访问 URL:网络请求的全过程
### 5.1 什么是 URL
**URLUniform Resource Locator** 是资源的地址,就像生活中的地址一样,用来定位互联网上的资源。
```
URL 的结构:
┌─────────────────────────────────────────────────────────┐
│ https:// │ www.example.com │ /path/to/page │ ?query=1 │
│ 协议 │ 域名 │ 路径 │ 查询 │
└─────────────────────────────────────────────────────────┘
```
- **协议(Protocol**:用什么方式访问(http、https、ftp 等)
- **域名(Domain)**:服务器的地址
- **路径(Path)**:资源在服务器上的位置
- **查询(Query)**:额外的参数
### 5.2 访问 URL 的完整过程
当你访问 `https://www.example.com` 时,发生了这些事情:
<URLRequestDemo />
#### 第一步:URL 解析
浏览器首先**解析 URL**,提取出协议、域名、路径等信息。
```
URL 解析过程:
https://www.example.com/index.html
协议: https
域名: www.example.com
路径: /index.html
```
#### 第二步:DNS 解析
计算机通过网络访问服务器,但网络用的是 **IP 地址**(如 93.184.216.34),而不是域名。所以需要把域名转换成 IP 地址,这个过程叫 **DNS 解析**
```
DNS 解析流程:
┌─────────────────────────────────────────────────────────┐
│ 浏览器缓存 → hosts 文件 → 本地 DNS 缓存 → DNS 服务器 │
└─────────────────────────────────────────────────────────┘
实际过程:
1. 浏览器检查缓存(最近访问过吗?)
2. 操作系统检查 DNS 缓存
3. 向 DNS 服务器发送查询请求
4. DNS 服务器返回 IP 地址
```
#### 第三步:建立 TCP 连接
拿到 IP 地址后,浏览器要与服务器建立 **TCP 连接**。TCP 是传输层协议,保证数据可靠传输。
```
TCP 三次握手:
┌─────────────────────────────────────────────────────────┐
│ 客户端 → 服务器:SYN(同步请求) │
│ 服务器 → 客户端:SYN-ACK(确认并同步) │
│ 客户端 → 服务器:ACK(确认) │
│ ↓ │
│ 连接建立完成! │
└─────────────────────────────────────────────────────────┘
```
如果是 **HTTPS**,还需要进行 **TLS/SSL 握手**,建立加密通道。
#### 第四步:发送 HTTP 请求
连接建立后,浏览器向服务器发送 **HTTP 请求**
```
HTTP 请求格式:
┌─────────────────────────────────────────────────────────┐
│ GET /index.html HTTP/1.1 │
│ Host: www.example.com │
│ User-Agent: Mozilla/5.0... │
│ Accept: text/html │
│ │
│ (空行) │
└─────────────────────────────────────────────────────────┘
```
常见的 HTTP 方法:
| 方法 | 含义 | 用途 |
|-----|------|-----|
| **GET** | 获取资源 | 浏览网页 |
| **POST** | 提交数据 | 登录、提交表单 |
| **PUT** | 上传资源 | 文件上传 |
| **DELETE** | 删除资源 | 删除数据 |
#### 第五步:服务器处理请求
服务器(通常是 **Web 服务器** 如 Nginx、Apache)收到请求后:
1. **解析请求**:理解客户端想要什么
2. **处理业务**:调用后端程序(如 Python、Node.js、Java
3. **查询数据库**:获取需要的数据
4. **生成响应**:把数据组装成 HTML、JSON 等格式
```
服务器处理流程:
┌─────────────────────────────────────────────────────────┐
│ 1. Web 服务器接收请求 (Nginx/Apache) │
│ 2. 根据路径找到对应的处理程序 │
│ 3. 执行后端代码 (API、业务逻辑) │
│ 4. 如需查询数据库,获取数据 │
│ 5. 组装响应 (HTML/JSON/CSS/JS) │
│ 6. 返回 HTTP 响应 │
└─────────────────────────────────────────────────────────┘
```
#### 第六步:返回 HTTP 响应
服务器返回 **HTTP 响应**,包含状态码、响应头和响应体:
```
HTTP 响应格式:
┌─────────────────────────────────────────────────────────┐
│ HTTP/1.1 200 OK │
│ Content-Type: text/html │
│ Content-Length: 1234 │
│ │
│ <!DOCTYPE html> │
│ <html>...</html> │
└─────────────────────────────────────────────────────────┘
```
常见的状态码:
| 状态码 | 含义 |
|-------|------|
| **200** | 成功 |
| **301/302** | 重定向 |
| **404** | 资源未找到 |
| **500** | 服务器错误 |
#### 第七步:浏览器渲染页面
浏览器收到响应后,开始**渲染页面**:
<RenderingDemo />
1. **解析 HTML**:构建 DOM 树
2. **解析 CSS**:计算样式,构建渲染树
3. **执行 JavaScript**:执行页面中的 JS 代码
4. **绘制页面**:把内容显示到屏幕上
```
浏览器渲染过程:
┌─────────────────────────────────────────────────────────┐
│ 1. HTML 解析 → DOM 树 │
│ 2. CSS 解析 → 样式规则 │
│ 3. DOM + CSS → 渲染树 │
│ 4. 布局计算 → 每个元素的大小位置 │
│ 5. 绘制 → 像素显示到屏幕 │
│ 6. 合成 → 多层合并显示 │
└─────────────────────────────────────────────────────────┘
```
---
## 6. 完整流程回顾
让我们把整个过程串起来:
<FullProcessDemo />
```
从按下电源到访问网站的完整流程:
┌──────────────────────────────────────────────────────────────────┐
│ 1. 按下电源 │
│ └── 电源启动 → 主板唤醒 → CPU 复位 → 执行 BIOS/UEFI │
├──────────────────────────────────────────────────────────────────┤
│ 2. BIOS/UEFI 启动 │
│ └── 硬件自检 → 寻找启动设备 → 读取引导程序 │
├──────────────────────────────────────────────────────────────────┤
│ 3. 操作系统启动 │
│ └── 引导程序 → 加载内核 → 启动服务 → 显示桌面 │
├──────────────────────────────────────────────────────────────────┤
│ 4. 打开浏览器 │
│ └── 双击图标 → 创建进程 → 加载程序 → 显示窗口 │
├──────────────────────────────────────────────────────────────────┤
│ 5. 访问 URL │
│ └── URL 解析 → DNS 解析 → TCP 连接 → HTTP 请求 │
│ → 服务器处理 → HTTP 响应 → 浏览器渲染 → 显示网页 │
└──────────────────────────────────────────────────────────────────┘
```
---
## 7. 知识地图
这一章涉及的知识领域:
```
计算机系统概览
├── 硬件基础
│ ├── 电源 (PSU)
│ ├── 主板芯片组
│ └── CPU
├── BIOS/UEFI
│ ├── POST 自检
│ ├── 启动顺序
│ └── 引导程序
├── 操作系统
│ ├── 内核 (Kernel)
│ ├── 系统服务
│ └── 桌面环境
├── 应用程序
│ ├── 进程管理
│ └── 程序加载
└── 网络通信
├── DNS 解析
├── TCP/IP 协议
├── HTTP 协议
└── 浏览器渲染
```
::: tip 继续学习
如果你想深入了解某个环节,可以继续学习:
- **从晶体管到 CPU**:了解计算机硬件基础
- **操作系统(进程/内存/文件系统)**:深入理解操作系统
- **计算机网络**:深入理解网络协议
:::
@@ -1,6 +1,23 @@
# 编程语言图谱
> 💡 **学习指南**:为什么有这么多编程语言?该学哪个?本章带你从"语言演化"到"编程范式"到"如何选择",建立对编程语言全景的理解。**结论先行:没有最好的语言,只有最适合场景的语言。**
::: tip 前言
为什么有这么多编程语言?该学哪个?本章带你从"语言演化"到"编程范式"到"如何选择",建立对编程语言全景的理解。**结论先行:没有最好的语言,只有最适合场景的语言。**
:::
**这篇文章会带你学什么?**
学完这章后,你将获得:
- **理性选型能力**:面对"学什么语言"时,能根据项目需求做出判断,而不是盲目跟风
- **范式理解深度**:理解"面向对象"、"函数式编程"是不同的思维方式,而不仅仅是语法差异
- **历史演进视角**:看到 70 多年语言演化——从手写 0 和 1 到自然语言生成代码
- **后续学习基础**:为理解新语言设计理念、技术选型决策打下基础
| 章节 | 内容 | 核心概念 |
|-----|------|---------|
| **第 1 章** | 语言演化 | 从机器语言到高级语言 |
| **第 2 章** | 编程范式 | 命令式、面向对象、函数式 |
| **第 3 章** | 语言选择 | 场景驱动的选型方法 |
---
@@ -1,9 +1,25 @@
# 从晶体管到 CPU
::: tip 核心问题
::: tip 前言
**计算机是怎么"思考"的?** 你可能知道 CPU 是电脑的"大脑",但这个大脑到底是怎么工作的?它怎么从一堆金属和塑料变成能执行程序、处理数据的智能设备?本章带你从最底层的晶体管开始,一步步理解 CPU 的构造原理。
:::
**这篇文章会带你学什么?**
学完这章后,你将获得:
- **术语理解能力**:听到"CPU 主频"、"多核"、"指令集"不再一头雾水,能理解背后的物理原理
- **代码执行视角**:看到一行代码如何经过取指、解码、执行、写回,最终变成屏幕上的像素点
- **抽象层次思维**:理解每一层如何向上层提供服务,又如何隐藏下层的复杂性
- **后续学习基础**:为计算机体系结构、嵌入式开发、性能优化打下基础
| 章节 | 内容 | 核心概念 |
|-----|------|---------|
| **第 1 章** | 晶体管 | 数字世界的开关 |
| **第 2 章** | 逻辑门 | 布尔运算的物理实现 |
| **第 3 章** | 功能单元 | 加法器、寄存器、多路选择器 |
| **第 4 章** | CPU 核心 | 取指、解码、执行、写回 |
---
## 0. 全景图:从沙子到智能
@@ -201,6 +217,8 @@
- **内部总线 (Internal Bus)**:系统里的传送带,负责在各个模块之间搬运数据和信号。
- **控制单元 (Control Unit)**:总指挥。它的使命就是从内存中读取用 0 和 1 组成的指令,解析出应该做什么,并向其他模块传达具体的控制信号,调度它们各司其职。
<MinCpuDemo />
### 4.2 CPU 是如何执行指令的?
不管写下的高级编程语言有多么复杂,最终都会变成内存中的一条条底层指令。CPU 执行任何指令的过程,本质上都在重复以下典型的四个步骤:
@@ -1,6 +1,22 @@
# 类型系统与编译原理入门
> 💡 **学习指南**:当你写下 `int x = 10 + 5;` 时,编译器是如何理解每个字符、检查类型是否正确、最终生成机器指令的?本章用两个核心概念——**类型系统**和**编译流程**——帮你理解编程语言背后的"翻译机制"。
::: tip 前言
当你写下 `int x = 10 + 5;` 时,编译器是如何理解每个字符、检查类型是否正确、最终生成机器指令的?本章用两个核心概念——**类型系统**和**编译流程**——帮你理解编程语言背后的"翻译机制"。
:::
**这篇文章会带你学什么?**
学完这章后,你将获得:
- **问题诊断能力**:看到 `TypeError` 报错时,能快速定位是类型不匹配还是隐式转换惹的祸
- **语言选择依据**:理解为什么 TypeScript 适合大型项目、Python 适合快速原型开发
- **类型安全思维**:在写代码时就预见可能的类型错误,而不是等到运行时才发现
- **后续学习基础**:为编译原理、语言设计等高级话题打下基础
| 章节 | 内容 | 核心概念 |
|-----|------|---------|
| **第 1 章** | 类型系统 | 静态/动态类型、强/弱类型 |
| **第 2 章** | 编译流程 | 词法分析、语法分析、代码生成 |
---
@@ -0,0 +1,413 @@
# Vibe Coding 时代下的全栈开发
::: tip 前言
**什么是 Vibe Coding** 简单说,就是"用自然语言写代码"——你用中文或英文描述想要什么,AI 帮你生成代码。这彻底改变了软件开发的游戏规则。
但这里有个关键问题:**AI 能帮你写代码,但 AI 不能替你思考。** 你仍然需要知道"要写什么"、"为什么这么写"、"怎么判断对错"。这正是本章要帮你建立的基础认知框架。
:::
**这篇文章会带你学什么?**
学完这章后,你将获得:
- **领域全景认知**:知道前端、后端、AI 算法等方向分别做什么
- **技术选型能力**:面对"学什么语言/框架"时,能做出理性判断
- **成长路径清晰**:了解从零基础到 3-5 年经验工程师的技能演进
- **Vibe Coding 思维**:理解在 AI 辅助时代,哪些能力变得更重要
| 章节 | 内容 | 核心概念 |
|-----|------|---------|
| **第 1 章** | 计算机领域全景 | 前端、后端、移动端、AI、运维 |
| **第 2 章** | 什么是前端 | 用户能感知的界面层 |
| **第 3 章** | 什么是后端 | 幕后的服务器逻辑 |
| **第 4 章** | 编程语言图谱 | 与计算机沟通的工具 |
| **第 5 章** | 全栈工程师 | 前后端通吃的多面手 |
| **第 6 章** | AI 算法工程师 | 让机器学会思考 |
| **第 7 章** | 成长路径 | 从入门到精通的路线图 |
---
## 0. Vibe Coding:软件开发的新范式
### 0.1 什么是 Vibe Coding
想象一下以前的软件开发:
```
传统开发流程:
你 → 学习语法 → 写代码 → 调试 → 查文档 → 修改 → 运行
↑___________________反复循环___________________↓
```
现在有了 AI 辅助:
```
Vibe Coding 流程:
你 → 用自然语言描述需求 → AI 生成代码 → 你审核修改 → 运行
↑____________快速迭代____________↓
```
**核心变化**:从"怎么写代码"变成"怎么描述需求"。
### 0.2 Vibe Coding 时代,什么能力更重要?
<DeveloperSkillShiftDemo />
::: tip 💡 关键洞察
AI 能帮你写代码,但以下能力 AI 替代不了:
- **判断力**:知道 AI 生成的代码对不对、好不好
- **架构思维**:知道系统该怎么设计、模块该怎么划分
- **领域知识**:理解业务逻辑,知道"要做什么"
- **调试能力**:出问题时知道从哪里排查
:::
---
## 1. 计算机领域全景图
在深入各个方向之前,先建立一个全局认知。
<ComputerFieldMapDemo />
### 1.1 用"餐厅"比喻理解各领域
把一个软件系统想象成一家**餐厅**:
| 领域 | 餐厅角色 | 做什么 | 产出物 |
|-----|---------|--------|--------|
| **前端** | 装修 + 菜单 + 服务员 | 用户能看到、能交互的一切 | 网页、小程序、App 界面 |
| **后端** | 厨房 + 仓库 | 处理业务逻辑、存储数据 | API、数据库、服务器程序 |
| **移动端** | 外卖窗口 | 手机上的应用体验 | iOS/Android App |
| **AI/算法** | 研发部 | 让系统变"聪明" | 推荐模型、图像识别、智能对话 |
| **运维/DevOps** | 物业 + 安保 | 保证系统稳定运行 | 部署脚本、监控系统、安全防护 |
| **数据工程** | 财务 + 分析师 | 数据采集、存储、分析 | 数据管道、报表、仪表盘 |
### 1.2 各领域的技术栈速览
不要被这些名词吓到,这里只是让你"见过"它们:
| 领域 | 核心语言 | 常用框架/工具 | 典型产出 |
|-----|---------|--------------|---------|
| 前端 | JavaScript, TypeScript | React, Vue, CSS | 网页、管理后台 |
| 后端 | Node.js, Go, Java, Python | Express, Gin, Spring | API 服务 |
| 移动端 | Swift, Kotlin, Dart | SwiftUI, Jetpack, Flutter | 手机 App |
| AI/算法 | Python | PyTorch, TensorFlow | 模型、算法 |
| 运维 | Shell, Python | Docker, Kubernetes | 部署方案 |
::: tip 💡 给新手的建议
不要试图一次学完所有东西。先选一个方向深入,建立"根据地",再横向扩展。全栈不是"什么都懂一点",而是"有一个核心强项,其他方向能用"。
:::
---
## 2. 什么是前端?
### 2.1 一句话定义
**前端 = 用户能直接看到、点击、交互的部分。**
当你打开一个网页:
- 页面的布局、颜色、字体 → 前端
- 点击按钮后的动画效果 → 前端
- 表单输入、数据展示 → 前端
- 页面怎么适配手机屏幕 → 前端
### 2.2 前端三件套
<FrontendTriadDemo />
**用"装修房子"来比喻**
| 技术 | 装修角色 | 职责 |
|-----|---------|------|
| **HTML** | 房屋结构 | 墙在哪、门在哪、房间怎么划分 |
| **CSS** | 装饰风格 | 墙什么颜色、家具怎么摆、灯光效果 |
| **JavaScript** | 智能家居 | 开关灯、窗帘自动开合、安防系统 |
### 2.3 前端框架:为什么要用?
原生 HTML/CSS/JS 能写网页,为什么还要学 React、Vue 这些框架?
<FrontendFrameworkDemo />
**核心原因**:当页面变得复杂(比如淘宝、微信网页版),直接操作 DOM 会变得非常混乱。框架帮你"管理复杂性"。
### 2.4 前端工程师的一天
```
9:00 查看设计稿,理解要做什么功能
10:00 用 React/Vue 写组件代码
12:00 午休
14:00 和后端对接 API,调试数据展示
16:00 修复 bug,优化页面性能
18:00 代码评审,和团队讨论技术方案
```
---
## 3. 什么是后端?
### 3.1 一句话定义
**后端 = 用户看不到,但支撑整个系统运转的逻辑。**
当你网购下单:
- 验证你的账号密码 → 后端
- 检查商品库存 → 后端
- 计算优惠价格 → 后端
- 生成订单、扣款 → 后端
- 通知仓库发货 → 后端
### 3.2 后端的核心职责
<BackendCoreDemo />
**用"餐厅厨房"来比喻**
| 后端职责 | 厨房类比 | 具体内容 |
|---------|---------|---------|
| **API 设计** | 菜单设计 | 定义"用户能点什么菜"、"怎么点" |
| **业务逻辑** | 烹饪过程 | 处理订单、计算价格、验证权限 |
| **数据存储** | 仓库管理 | 把数据存进数据库、查询数据 |
| **性能优化** | 厨房效率 | 缓存、异步处理、负载均衡 |
| **安全防护** | 食品安全 | 防止 SQL 注入、权限控制 |
### 3.3 后端语言怎么选?
| 语言 | 特点 | 适合场景 |
|-----|------|---------|
| **Node.js** | 前端友好,JavaScript 全栈 | 中小型项目、快速原型 |
| **Go** | 高性能、并发强 | 高并发服务、微服务架构 |
| **Java** | 生态成熟、企业级 | 大型企业系统、银行 |
| **Python** | 简洁、AI 生态好 | 数据处理、AI 服务 |
::: tip 💡 新手建议
如果你已经会 JavaScript(前端基础),Node.js 是最自然的后端入门选择。一套语言,前后端都能写。
:::
### 3.4 后端工程师的一天
```
9:00 查看 API 需求文档
10:00 设计数据库表结构
11:00 写 API 接口代码
14:00 和前端联调,修复接口问题
16:00 优化慢查询,处理线上问题
18:00 代码评审,写技术文档
```
---
## 4. 编程语言图谱
### 4.1 编程语言是什么?
**编程语言 = 人类和计算机沟通的桥梁。**
计算机只认识 0 和 1,人类习惯说自然语言。编程语言是中间层:
- 人类用编程语言写代码(比 0/1 好理解)
- 计算机把编程语言翻译成机器指令
### 4.2 语言分类
<ProgrammingLanguageMapDemo />
**按运行方式分类**
| 类型 | 原理 | 代表语言 | 特点 |
|-----|------|---------|------|
| **编译型** | 先翻译成机器码,再运行 | C, C++, Go, Rust | 运行快,编译慢 |
| **解释型** | 边翻译边运行 | Python, JavaScript, Ruby | 开发快,运行慢 |
| **字节码型** | 折中方案 | Java, Kotlin, C# | 平衡性能和开发效率 |
**按类型系统分类**
| 类型 | 特点 | 代表语言 |
|-----|------|---------|
| **静态类型** | 变量类型写代码时确定 | Java, TypeScript, Go |
| **动态类型** | 变量类型运行时确定 | Python, JavaScript, Ruby |
| **强类型** | 类型检查严格,不自动转换 | Python, Java |
| **弱类型** | 类型检查宽松,会自动转换 | JavaScript, PHP |
### 4.3 该学哪门语言?
<LanguageSelectionDemo />
::: tip 💡 选择原则
没有"最好的语言",只有"最适合场景的语言"。新手建议:
1. **先学一门,学深**:建立编程思维
2. **再学第二门,对比**:理解语言设计差异
3. **按需学习**:根据项目需求选择
:::
---
## 5. 全栈工程师:前后端通吃
### 5.1 什么是全栈?
**全栈工程师 = 能独立完成前端 + 后端开发的工程师。**
<FullstackSkillDemo />
### 5.2 全栈的优势
| 优势 | 说明 |
|-----|------|
| **独立完成项目** | 从需求到上线,一个人搞定 |
| **沟通成本低** | 不需要前后端来回扯皮 |
| **技术视野广** | 理解整个系统如何运作 |
| **创业友好** | 快速验证想法,MVP 开发 |
### 5.3 全栈的挑战
| 挑战 | 说明 |
|-----|------|
| **深度 vs 广度** | 容易"什么都懂一点,什么都不精" |
| **技术更新快** | 前后端技术都在快速演进 |
| **精力分散** | 需要同时关注多个领域 |
### 5.4 全栈成长建议
```
第 1 阶段:建立根据地
└── 选一个方向深入(建议从前端或后端开始)
└── 达到能独立完成项目的水平
第 2 阶段:横向扩展
└── 学习另一个方向的基础
└── 能完成简单的全栈项目
第 3 阶段:融会贯通
└── 理解前后端如何协作
└── 能设计完整的技术架构
第 4 阶段:持续精进
└── 在某个领域保持深度
└── 其他领域保持"能用"水平
```
---
## 6. AI 算法工程师:让机器学会思考
### 6.1 AI 工程师 vs 传统开发
<AIvsTraditionalDemo />
| 维度 | 传统开发 | AI 算法工程师 |
|-----|---------|--------------|
| **核心任务** | 实现确定性的业务逻辑 | 训练模型、优化算法 |
| **思维方式** | "如果 A 则执行 B" | "让机器从数据中学习规律" |
| **代码产出** | 功能模块、系统 | 模型、训练脚本 |
| **调试方式** | 断点、日志 | 看指标、调超参 |
| **成功标准** | 功能正确、无 bug | 准确率、召回率达标 |
### 6.2 AI 工程师的技能树
```
AI 算法工程师
├── 数学基础
│ ├── 线性代数(矩阵运算)
│ ├── 概率统计(分布、期望)
│ └── 微积分(梯度、优化)
├── 编程能力
│ ├── Python(主力语言)
│ ├── PyTorch / TensorFlow(深度学习框架)
│ └── 数据处理(Pandas, NumPy
├── 机器学习
│ ├── 监督学习(分类、回归)
│ ├── 无监督学习(聚类、降维)
│ └── 模型评估方法
└── 深度学习
├── 神经网络基础
├── CNN(图像)
├── RNN / Transformer(序列)
└── 大模型(LLM)
```
### 6.3 AI 工程师的一天
```
9:00 查看模型训练结果,分析指标
10:00 数据预处理,清洗训练数据
12:00 午休
14:00 调整模型结构,尝试新方案
16:00 跑实验,对比不同方案效果
18:00 写实验报告,和团队讨论下一步
```
### 6.4 Vibe Coding 时代的 AI 工程师
AI 辅助开发对 AI 工程师的影响:
| 变化 | 说明 |
|-----|------|
| **代码生成** | AI 能生成训练脚本、数据处理代码 |
| **论文阅读** | AI 能帮你总结论文要点 |
| **实验记录** | AI 能帮你整理实验结果 |
| **不变的是** | 对问题的理解、对结果的判断、对方向的把握 |
---
## 7. 成长路径:从入门到精通
### 7.1 3-5 年成长路线图
<CareerPathDemo />
### 7.2 各阶段能力要求
| 阶段 | 时间 | 核心能力 | 典型产出 |
|-----|------|---------|---------|
| **入门** | 0-1 年 | 掌握一门语言 + 基础工具 | 能完成简单功能模块 |
| **进阶** | 1-2 年 | 熟悉一个技术栈 + 工程化 | 能独立完成中型项目 |
| **高级** | 2-3 年 | 深入一个领域 + 架构能力 | 能设计系统方案 |
| **资深** | 3-5 年 | 技术深度 + 业务理解 + 团队协作 | 能主导大型项目 |
### 7.3 Vibe Coding 时代的学习策略
<LearningStrategyDemo />
::: tip 💡 核心建议
1. **基础比工具重要**:语言特性、数据结构、算法思维是根基
2. **实践比理论重要**:做项目是最好的学习方式
3. **思考比记忆重要**:理解"为什么"比记住"怎么做"更有价值
4. **AI 是工具不是拐杖**:用 AI 加速学习,不要用 AI 替代思考
:::
---
## 8. 总结:Vibe Coding 时代的核心竞争力
回顾本章,我们建立了计算机领域的全局认知:
1. **领域划分**:前端、后端、移动端、AI、运维、数据——各有侧重
2. **技术选型**:没有最好的技术,只有最适合场景的技术
3. **成长路径**:先深后广,建立根据地再横向扩展
4. **AI 时代**AI 能帮你写代码,但不能替你思考
### Vibe Coding 时代的三层能力
```
┌─────────────────────────────────────────┐
│ 第 3 层:判断力(AI 替代不了) │
│ - 知道什么是对的 │
│ - 知道什么是好的 │
│ - 知道该往哪个方向走 │
├─────────────────────────────────────────┤
│ 第 2 层:架构思维(AI 辅助) │
│ - 系统设计能力 │
│ - 模块划分能力 │
│ - 技术选型能力 │
├─────────────────────────────────────────┤
│ 第 1 层:代码实现(AI 擅长) │
│ - 语法编写 │
│ - API 调用 │
│ - 常见模式实现 │
└─────────────────────────────────────────┘
```
@@ -0,0 +1,566 @@
# 领域特定语言(DSL):后端世界中那些"不像代码的代码"
::: tip 前言
在一个真实案例中,工程师 Armin 在新公司用 AI 构建了一套基础设施服务,总计约 4 万行代码(Go + YAML + Pulumi + SDK 胶水代码),其中超过 90% 由 AI 生成。这个案例中出现了许多初学者不熟悉的术语:YAML、Pulumi、HCL、Lua、SDK 胶水代码……它们既不是 Python,也不是 JavaScript,却在后端项目中无处不在。本文将从一个统一的视角——**领域特定语言(DSL)**——来系统地介绍这些技术。
:::
**本文的学习目标**
在后端开发中,除了用通用编程语言(Python、Go、Java 等)编写的业务逻辑之外,还存在大量**用途各异、语法各异、但都不属于通用编程语言**的文件和代码。它们有一个共同的上位概念:**DSLDomain-Specific Language,领域特定语言)**。
学完本文后,你将能够:
- 理解 DSL 与通用编程语言(GPL)的本质区别
- 掌握 DSL 的分类体系:数据序列化格式、嵌入式脚本语言、基础设施定义语言
- 区分 XML、JSON、YAML、TOML、CSV、Protobuf 等数据格式的适用场景
- 理解 Lua 等嵌入式脚本语言的设计目的
- 解释 TerraformHCL)和 Pulumi 的原理与区别
- 理解 OpenAPI 规范与 SDK 自动生成的工作原理
- 判断哪些类型的代码适合交给 AI 生成
| 章节 | 主题 | 核心概念 |
|-----|------|---------|
| **第 1 章** | DSL 总论 | DSL vs GPL 的定义、分类体系与全景图 |
| **第 2 章** | 数据序列化格式 | XML、JSON、YAML、TOML、CSV、Protobuf 等 |
| **第 3 章** | 嵌入式脚本语言 | Lua 等语言的设计哲学与典型应用 |
| **第 4 章** | 基础设施即代码 | TerraformHCL)、Pulumi 的原理与对比 |
| **第 5 章** | 胶水代码与 SDK 生成 | OpenAPI 规范与客户端代码自动生成 |
| **第 6 章** | AI 与 DSL 的关系 | 为什么 AI 特别擅长生成 DSL 代码 |
---
## 1. DSL 总论:通用语言之外的另一个世界
### 1.1 什么是 DSL
**DSLDomain-Specific Language,领域特定语言)** 是为某个特定领域或特定任务设计的语言。与之相对的是 **GPLGeneral-Purpose Language,通用编程语言)**,如 Python、Java、Go、C++ 等——它们被设计为可以解决任意计算问题。
两者的核心区别:
| 维度 | GPL(通用编程语言) | DSL(领域特定语言) |
|------|-------------------|-------------------|
| **设计目标** | 解决任意计算问题 | 解决某个特定领域的问题 |
| **表达范围** | 图灵完备,理论上可以计算任何东西 | 通常有意限制表达范围 |
| **学习成本** | 较高,需要理解完整的语言体系 | 较低,只需理解该领域的概念 |
| **典型代表** | Python、Java、Go、C++、JavaScript | SQL、HTML/CSS、正则表达式、YAML、HCL |
你其实早就在使用 DSL 了:
- **SQL** 是数据库查询领域的 DSL——你用 `SELECT * FROM users WHERE age > 18` 来查数据,而不是用 Python 手写遍历逻辑
- **HTML/CSS** 是网页结构与样式领域的 DSL——你用标签和属性描述页面,而不是用 C++ 操作像素
- **正则表达式** 是文本模式匹配领域的 DSL——你用 `\d{3}-\d{4}` 匹配电话号码,而不是手写字符比较循环
### 1.2 DSL 的分类
DSL 可以按照"是否具备图灵完备性"分为两大类:
**外部 DSLExternal DSL**
拥有独立的语法和解析器,不依附于任何通用编程语言。用户编写的代码由专用的解释器或编译器处理。
- 纯数据描述型:JSON、YAML、XML、TOML、CSV、Protobuf(不含任何逻辑)
- 查询/操作型:SQL、GraphQL、正则表达式(有限的逻辑能力)
- 领域建模型:HCLTerraform)、Dockerfile、Nginx 配置语法(声明式描述特定领域的状态)
**内部 DSLInternal DSL / Embedded DSL**
寄生在某门通用编程语言内部,利用宿主语言的语法来构建领域专用的表达方式。代码本身是合法的宿主语言代码,但读起来像是一门专用语言。
- Pulumi(用 TypeScript/Python/Go 编写,但 API 设计得像声明式配置)
- Ruby on Rails 的路由定义(`get '/users', to: 'users#index'`,合法的 Ruby 代码,但读起来像配置)
- 测试框架中的断言语法(`expect(value).toBe(42)`,合法的 JavaScript,但读起来像自然语言)
### 1.3 后端项目中的 DSL 全景图
在一个典型的后端项目中,你会遇到以下几类 DSL:
```
后端项目中的 DSL
├── 数据序列化格式(描述数据结构)
│ ├── 文本格式:JSON、YAML、XML、TOML、CSV、INI
│ └── 二进制格式:Protobuf、MessagePack、Avro、BSON
├── 嵌入式脚本语言(可编程的配置层)
│ ├── Lua(游戏引擎、Nginx、Redis
│ ├── GDScriptGodot 引擎)
│ └── Jsonnet(配置模板生成)
├── 基础设施与运维 DSL(声明式描述系统状态)
│ ├── HCLTerraform
│ ├── Dockerfile / Docker Compose YAML
│ └── Nginx / Apache 配置语法
└── 接口描述语言(描述 API 契约)
├── OpenAPI / Swagger
├── Protocol Buffers.proto 文件)
└── GraphQL Schema
```
理解了这张全景图,后续章节将逐一展开每个分支。
---
## 2. 数据序列化格式:用文本描述结构化数据
### 2.1 什么是数据序列化?
**序列化(Serialization** 是指将内存中的数据结构(对象、字典、数组等)转换为一种可存储或可传输的文本/字节流的过程。反过来,从文本/字节流还原为内存中的数据结构,称为**反序列化(Deserialization**。
数据序列化格式是 DSL 中最基础的一类——它们属于纯数据描述型外部 DSL,不具备任何逻辑能力,只负责静态地描述"值是什么"。
### 2.2 为什么需要这些格式?
假设你开发了一个后端服务,数据库地址为 `localhost:5432`。如果将这个地址硬编码在源代码中,本地开发没有问题,但部署到生产环境时,数据库地址变为 `db.prod.company.com:5432`,你就需要修改源代码并重新编译。
工程实践中的通用做法是:**将可变的参数从代码中分离出来,存放在独立的配置文件中。** 程序在启动时读取配置文件,根据其中的值来决定行为。
除了配置之外,数据序列化格式还广泛用于:系统间的数据交换(API 请求/响应)、数据持久化存储、跨语言通信等场景。
### 2.3 人类可读的文本格式
以下是工程中最常见的文本序列化格式,按历史顺序介绍。
**INI**
最早期的配置格式,起源于 Windows 系统。结构简单,由节(section)和键值对组成:
```ini
[database]
host = localhost
port = 5432
[server]
debug = true
```
优点是可读性强。局限在于不支持嵌套结构和数组类型,无法表达复杂配置。目前主要出现在遗留系统和部分 Linux 配置中(如 `php.ini``my.cnf`)。
**CSV**
**CSVComma-Separated Values,逗号分隔值)** 是最简单的表格数据格式:
```csv
name,age,city
Alice,30,Beijing
Bob,25,Shanghai
```
每行是一条记录,字段之间用逗号分隔。CSV 广泛用于数据导入导出、电子表格交换、数据分析管道。它的局限是只能表达扁平的二维表格,不支持嵌套结构,且没有类型信息(所有值都是字符串)。
**XML**
**XMLeXtensible Markup Language,可扩展标记语言)** 诞生于 1998 年,曾经是数据交换的主流标准:
```xml
<?xml version="1.0" encoding="UTF-8"?>
<config>
<database>
<host>localhost</host>
<port>5432</port>
</database>
<server>
<debug>true</debug>
<allowed_origins>
<origin>https://example.com</origin>
<origin>https://app.example.com</origin>
</allowed_origins>
</server>
</config>
```
XML 的表达力非常强,支持嵌套、属性、命名空间、Schema 验证等高级特性。但它的语法冗长——大量的开闭标签导致信噪比低,手动编写和阅读的体验较差。
XML 在以下领域仍然广泛使用:
- Java 生态(Maven 的 `pom.xml`、Spring 配置、Android 布局文件)
- 企业级 Web 服务(SOAP 协议)
- 办公文档格式(`.docx``.xlsx` 本质上是 ZIP 压缩的 XML 文件集合)
- RSS/Atom 订阅源、SVG 矢量图形
**JSON**
**JSONJavaScript Object Notation** 诞生于 2001 年,因其简洁性迅速取代 XML 成为 Web API 数据交换的事实标准:
```json
{
"database": {
"host": "localhost",
"port": 5432
},
"server": {
"debug": true
}
}
```
优点是结构清晰,几乎所有编程语言都有原生解析支持。主要缺点是**不支持注释**,且大量的括号和引号在手动编写时容易出错。JSON 同时也是前端项目配置的标准格式(`package.json``tsconfig.json`)。
**YAML**
**YAMLYAML Ain't Markup Language** 同样诞生于 2001 年,是目前后端和 DevOps 领域使用最广泛的配置格式。Docker Compose、Kubernetes、GitHub Actions 等工具均采用 YAML
```yaml
# 数据库配置
database:
host: localhost
port: 5432
# 服务器配置
server:
debug: true
allowed_origins:
- https://example.com
- https://app.example.com
```
优点是支持注释、语法简洁、可表达复杂嵌套结构。缺点是**依赖缩进来表示层级关系**,缩进错误会导致解析失败,这是初学者最常遇到的问题。
> 补充:YAML 的全称 "YAML Ain't Markup Language" 是一个递归缩写。
**TOML**
**TOMLTom's Obvious Minimal Language** 诞生于 2013 年,被 Rust 的包管理器 Cargo 和 Python 的 `pyproject.toml` 采用:
```toml
[database]
host = "localhost"
port = 5432
[server]
debug = true
allowed_origins = [
"https://example.com",
"https://app.example.com"
]
```
TOML 试图兼顾 INI 的简洁性和 YAML 的表达力,同时避免缩进敏感带来的问题。
### 2.4 二进制序列化格式
上述格式都是人类可读的文本。在对性能和体积有更高要求的场景中,还存在一类**二进制序列化格式**——它们牺牲可读性,换取更小的体积和更快的解析速度。
| 格式 | 开发方 | 特点 | 典型使用场景 |
|------|-------|------|------------|
| **Protocol Buffers (Protobuf)** | Google | 需要预定义 `.proto` Schema 文件,强类型,体积极小 | gRPC 通信、Google 内部服务、高性能微服务 |
| **MessagePack** | 社区 | 类似 JSON 的二进制版本,无需 Schema | Redis 内部编码、跨语言高性能通信 |
| **Avro** | Apache | 支持 Schema 演进,适合大数据场景 | Hadoop / Kafka 生态的数据序列化 |
| **BSON** | MongoDB | JSON 的二进制扩展,支持更多数据类型 | MongoDB 数据库内部存储格式 |
以 Protocol Buffers 为例,需要先定义 Schema
```protobuf
// user.proto
syntax = "proto3";
message User {
string name = 1;
int32 age = 2;
string email = 3;
}
```
然后通过编译器(`protoc`)自动生成各语言的序列化/反序列化代码。这种"先定义 Schema,再生成代码"的模式与后文将介绍的 OpenAPI SDK 生成思路一致。
### 2.5 完整对比
| 格式 | 类型 | 诞生年代 | 可读性 | 支持注释 | 典型使用场景 |
|------|------|---------|--------|---------|------------|
| **INI** | 文本 | 1980s | 高 | ✅ | 系统配置、遗留项目 |
| **CSV** | 文本 | 1972 | 高 | ❌ | 数据导入导出、表格交换 |
| **XML** | 文本 | 1998 | 中 | ✅ | Java 生态、企业级 Web 服务、文档格式 |
| **JSON** | 文本 | 2001 | 高 | ❌ | Web API 数据交换、前端配置 |
| **YAML** | 文本 | 2001 | 高 | ✅ | Docker、K8s、CI/CD、后端服务配置 |
| **TOML** | 文本 | 2013 | 高 | ✅ | Rust / Python 项目配置 |
| **Protobuf** | 二进制 | 2008 | 无 | — | gRPC、高性能微服务通信 |
| **MessagePack** | 二进制 | 2008 | 无 | — | 高性能跨语言通信 |
| **Avro** | 二进制 | 2009 | 无 | — | Hadoop / Kafka 大数据管道 |
| **BSON** | 二进制 | 2009 | 无 | — | MongoDB 内部存储 |
**要点**:所有这些格式的本质功能相同——**将结构化数据转换为可存储、可传输的形式**。文本格式优先考虑人类可读性和易编辑性;二进制格式优先考虑解析性能和传输体积。选择哪种格式取决于具体场景的需求权衡。
---
## 3. 嵌入式脚本语言:可编程的配置层
### 3.1 概念定义
Python、JavaScript、Go 等语言是通用编程语言(General-Purpose Language),它们可以独立运行,构建完整的应用程序。
与之不同,还有一类语言**专门设计为嵌入到其他宿主程序中运行**,为宿主程序提供可编程的扩展能力。这类语言被称为**嵌入式脚本语言(Embedded Scripting Language**。
它们解决的核心问题是:**当静态配置文件(YAML/JSON)的表达力不够,需要引入条件判断、循环等逻辑时,如何在不修改宿主程序源码的前提下实现动态行为。**
### 3.2 Lua:最具代表性的嵌入式脚本语言
Lua(葡萄牙语中"月亮"的意思)是一门极其轻量的脚本语言,整个解释器编译后仅几百 KB。它的设计目标不是独立运行,而是作为可嵌入的扩展层。
Lua 的典型应用场景:
- **游戏引擎**:《魔兽世界》的插件系统、《Roblox》的游戏脚本均使用 Lua。游戏引擎用 C/C++ 实现核心渲染和物理计算,将关卡逻辑、NPC 对话等频繁变动的部分交给 Lua 脚本。这样,策划人员修改游戏内容时不需要重新编译引擎。
- **Web 服务器**OpenResty 将 Lua 嵌入 Nginx 内部,使运维人员可以用 Lua 脚本实现请求过滤、限流、鉴权等逻辑,而无需修改 Nginx 的 C 源码。
- **数据库**:Redis 支持将 Lua 脚本发送到服务端执行,用于实现需要原子性保证的复合操作(如"先读后写")。
以下是一段嵌入在 NginxOpenResty)中的 Lua 脚本示例:
```lua
-- 功能:对 /api/secret 路径进行 token 鉴权
local uri = ngx.var.uri
local token = ngx.req.get_headers()["Authorization"]
if uri == "/api/secret" and token ~= "Bearer my-secret-token" then
ngx.status = 403
ngx.say("Access denied")
return ngx.exit(403)
end
```
### 3.3 其他嵌入式脚本语言
| 语言 | 宿主环境 | 典型用途 |
|------|---------|---------|
| **Lua** | 游戏引擎、NginxOpenResty)、Redis | 游戏逻辑、网关策略、缓存操作 |
| **VimScript / Lua** | Vim / Neovim 编辑器 | 编辑器插件开发 |
| **Emacs Lisp** | Emacs 编辑器 | 编辑器行为自定义 |
| **GDScript** | Godot 游戏引擎 | 游戏逻辑脚本 |
| **Jsonnet** | Kubernetes 生态 / 配置生成工具 | 模板化生成大量相似的 JSON/YAML 配置 |
**要点**:嵌入式脚本语言在 DSL 分类中属于**内部 DSL 与外部 DSL 的交界地带**——它们是独立的语言(有自己的语法和解释器),但设计目标是嵌入宿主程序运行,而非独立构建应用。它们填补了"静态配置文件"(纯数据描述型 DSL)与"通用编程语言"(GPL)之间的空白:当配置需要表达逻辑(条件判断、循环、函数调用)时,嵌入一门轻量脚本语言是工程上的标准解决方案。
---
## 4. 基础设施即代码(Infrastructure as Code
### 4.1 什么是"基础设施"
在后端工程中,"基础设施"Infrastructure)指的是应用程序运行所依赖的底层资源:
- 计算资源:服务器(虚拟机或容器)
- 数据存储:数据库实例、对象存储桶
- 网络:防火墙规则、负载均衡器、DNS 配置
- 中间件:消息队列、缓存集群
在云计算时代,这些资源通过云服务商(如 AWS、阿里云、腾讯云)的控制台以图形界面的方式创建和管理。
### 4.2 手动管理的局限性
通过控制台手动操作在小规模项目中可行,但随着项目规模增长,会暴露以下问题:
1. **不可重复**:操作步骤没有记录,无法精确复现同一套环境
2. **不可审计**:无法追溯"谁在什么时间修改了什么配置"
3. **不可协作**:操作过程无法纳入版本控制,无法进行代码审查
4. **容易出错**:手动操作在生产环境中存在误操作风险
**基础设施即代码(Infrastructure as Code,简称 IaC** 的核心思想是:**用代码来声明式地定义基础设施资源,使其具备版本控制、自动化执行和可重复部署的能力。**
### 4.3 Terraform
Terraform 是目前使用最广泛的 IaC 工具,由 HashiCorp 公司开发。它使用专用的 **HCLHashiCorp Configuration Language** 语言。
Terraform 采用**声明式**范式:用户描述期望的最终状态,Terraform 自动计算从当前状态到目标状态所需的操作。
```hcl
# 定义一台云服务器
resource "aws_instance" "my_server" {
ami = "ami-0c55b159cbfafe1f0" # 操作系统镜像
instance_type = "t3.micro" # 实例规格
tags = {
Name = "my-first-server"
}
}
# 定义一个 PostgreSQL 数据库实例
resource "aws_db_instance" "my_database" {
engine = "postgres"
instance_class = "db.t3.micro"
username = "admin"
password = "please-use-secrets-manager"
}
```
执行流程:
```bash
terraform plan # 预览将要执行的变更
terraform apply # 确认并执行,自动在云平台创建资源
```
### 4.4 Pulumi
Pulumi 提供了另一种思路:**直接使用通用编程语言(TypeScript、Python、Go 等)来定义基础设施**,而非学习专用的 HCL 语法。
同样的服务器定义,用 Pulumi + TypeScript 表达如下:
```typescript
import * as aws from "@pulumi/aws";
const server = new aws.ec2.Instance("my-server", {
ami: "ami-0c55b159cbfafe1f0",
instanceType: "t3.micro",
tags: { Name: "my-first-server" },
});
const bucket = new aws.s3.Bucket("my-bucket", {
acl: "private",
});
export const serverIp = server.publicIp;
```
由于使用的是通用编程语言,开发者可以利用循环、条件判断、函数抽象等语言特性来处理复杂的基础设施逻辑。
### 4.5 Terraform 与 Pulumi 的对比
| 维度 | Terraform | Pulumi |
|------|-----------|--------|
| **语言** | HCL(专用语言) | TypeScript / Python / Go 等通用语言 |
| **学习成本** | 需要学习 HCL 语法 | 使用已掌握的编程语言,学习成本较低 |
| **社区生态** | 非常成熟,几乎覆盖所有云服务商 | 快速增长中,但规模小于 Terraform |
| **适用场景** | 运维团队主导的标准化基础设施管理 | 开发者主导的项目,需要复杂逻辑的场景 |
| **AI 代码生成适配度** | 高(模式固定) | 很高(本质是通用编程语言代码) |
**要点**:IaC 工具中的 HCL 是一种典型的外部 DSL——它有独立的语法和解析器,专门用于声明式描述基础设施状态。而 Pulumi 则采用内部 DSL 的策略——用通用编程语言的语法来表达领域特定的概念。两者目标一致(将基础设施管理从手动操作转为代码驱动),路径不同(专用语言 vs 通用语言)。代码可以纳入 Git 版本控制、进行团队审查、自动化执行和回滚。
---
## 5. 胶水代码与 SDK 自动生成
### 5.1 什么是胶水代码
在软件工程中,**胶水代码(Glue Code)** 指的是本身不包含业务逻辑,仅用于连接两个系统或模块的代码。
典型的胶水代码包括:
- 前端调用后端 API 时编写的 HTTP 请求代码(URL 拼接、请求头设置、响应解析)
- 后端服务 A 调用服务 B 接口时编写的 HTTP 客户端代码
- 不同编程语言之间的接口适配代码
这类代码的特征是:**高度重复、模式固定、但不可省略。**
### 5.2 OpenAPI 规范与代码自动生成
既然胶水代码具有高度的模式化特征,工程界的解决方案是:**先用标准格式描述 API 接口,再用工具自动生成客户端代码。**
**OpenAPI 规范**(前身为 Swagger)是描述 REST API 的行业标准。它使用 YAML 或 JSON 格式,精确定义 API 的路径、参数、请求体和响应结构:
```yaml
openapi: 3.0.0
info:
title: 邮件服务 API
version: 1.0.0
paths:
/emails:
post:
summary: 发送邮件
requestBody:
content:
application/json:
schema:
type: object
properties:
to:
type: string
example: "user@example.com"
subject:
type: string
body:
type: string
responses:
'200':
description: 发送成功
```
基于这份规范文件,使用 `openapi-generator` 等工具可以自动生成多种语言的客户端 SDK:
- **Python**`client.emails.send(to="user@example.com", subject="Hi", body="Hello")`
- **TypeScript**`client.emails.send({ to: "user@example.com", subject: "Hi", body: "Hello" })`
- **Go**`client.Emails.Send(ctx, &SendEmailRequest{To: "user@example.com", ...})`
生成的 SDK 封装了 HTTP 请求的所有细节,调用方无需关心 URL 路径、请求方法、序列化格式等底层实现。
### 5.3 重新理解 Armin 的案例
回到本文开头的案例,现在可以准确理解其中每个组成部分:
| 组成部分 | 性质 | 说明 |
|---------|------|------|
| **Go** | 业务逻辑代码 | 邮件收发服务的核心功能实现 |
| **YAML** | 配置文件 | 服务配置、CI/CD 流水线定义、OpenAPI 规范文件 |
| **Pulumi** | 基础设施代码 | 用 Go/TypeScript 定义云资源(服务器、数据库、网络) |
| **SDK 胶水代码** | 自动生成的客户端库 | 从 OpenAPI 规范自动生成的 Python 和 TypeScript SDK |
其中 YAML 配置、Pulumi 资源定义、SDK 胶水代码这三类均属于高度模式化、有明确规范约束的代码,这正是 AI 代码生成能力最强的领域。因此"4 万行代码中 90% 由 AI 生成"是合理的。
---
## 6. AI 与 DSL 的关系
### 6.1 AI 代码生成的适用性分析
| 特征维度 | 适合 AI 生成 | 不适合 AI 生成 |
|---------|-------------|---------------|
| **模式化程度** | 高度重复,存在固定模板 | 需要创造性设计,无先例可循 |
| **规范约束** | 有明确的 schema 或语法规范 | 需求模糊,边界不清晰 |
| **上下文依赖** | 局部自洽,单个定义不依赖全局理解 | 需要理解整个系统的架构意图 |
| **可验证性** | 可被工具自动校验(如 `terraform validate`) | 只能依靠人工判断设计合理性 |
本文介绍的四类技术——配置文件、嵌入式脚本、IaC 代码、SDK 胶水代码——均具备左列的特征。这解释了为什么 AI 在这些领域的代码生成效果显著优于业务逻辑代码。
### 6.2 评估框架
在判断某段代码是否适合交给 AI 生成时,可以参考以下三个标准:
1. **是否存在现成的规范或 schema?** —— 存在则 AI 友好
2. **是否属于大量重复的模式?** —— 是则 AI 友好
3. **生成结果能否被工具自动验证?** —— 能则 AI 友好
三项均满足的代码(如从 OpenAPI 规范生成 SDK、用 Terraform 批量定义同构资源),可以高度依赖 AI 生成。三项均不满足的代码(如设计一个新的分布式一致性协议),仍需要工程师自行完成。
---
## 7. 术语表
| 术语 | 全称 / 中文 | 定义 |
|------|------------|------|
| **DSL** | Domain-Specific Language / 领域特定语言 | 为特定领域设计的语言,与通用编程语言相对 |
| **GPL** | General-Purpose Language / 通用编程语言 | 可解决任意计算问题的编程语言,如 Python、Java、Go |
| **外部 DSL** | External DSL | 拥有独立语法和解析器的领域特定语言,如 SQL、HCL、YAML |
| **内部 DSL** | Internal DSL / Embedded DSL | 寄生在通用编程语言内部、利用宿主语法构建的领域专用表达,如 Pulumi |
| **数据序列化** | Data Serialization | 将内存中的数据结构转换为可存储或可传输的格式的过程 |
| **INI** | Initialization | 最早期的键值对配置格式,起源于 Windows 系统 |
| **CSV** | Comma-Separated Values / 逗号分隔值 | 用逗号分隔字段的纯文本表格格式 |
| **XML** | eXtensible Markup Language / 可扩展标记语言 | 基于标签的文本数据格式,表达力强但语法冗长 |
| **JSON** | JavaScript Object Notation | 基于键值对的轻量数据交换格式,Web API 的事实标准 |
| **YAML** | YAML Ain't Markup Language | 基于缩进的配置文件格式,后端和 DevOps 领域广泛使用 |
| **TOML** | Tom's Obvious Minimal Language | 显式语法的配置格式,Rust 和 Python 生态常用 |
| **Protobuf** | Protocol Buffers | Google 开发的二进制序列化格式,需预定义 Schema,体积小、速度快 |
| **MessagePack** | — | 类似 JSON 的二进制序列化格式,无需 Schema |
| **Lua** | — | 轻量级嵌入式脚本语言,常用于游戏引擎、Web 服务器和数据库扩展 |
| **IaC** | Infrastructure as Code / 基础设施即代码 | 用代码定义和管理云计算资源的工程实践 |
| **Terraform** | — | HashiCorp 开发的 IaC 工具,使用 HCL 声明式语言 |
| **HCL** | HashiCorp Configuration Language | Terraform 使用的专用配置语言 |
| **Pulumi** | — | 支持通用编程语言的 IaC 工具 |
| **OpenAPI** | — | 描述 REST API 接口的行业标准规范(前身为 Swagger) |
| **SDK** | Software Development Kit / 软件开发工具包 | 封装了 API 调用细节的客户端库 |
| **胶水代码** | Glue Code | 不含业务逻辑,仅用于连接两个系统的适配代码 |
---
## 总结
后端工程中存在大量非业务逻辑代码。它们有一个共同的上位概念:**DSL(领域特定语言)**——为特定领域设计的、与通用编程语言相对的语言。
本文介绍的 DSL 可以归为四个类别:
1. **数据序列化格式**XML / JSON / YAML / TOML / CSV / Protobuf 等)—— 纯数据描述型外部 DSL,将结构化数据转换为可存储、可传输的形式
2. **嵌入式脚本语言**(Lua 等)—— 介于配置与通用语言之间,为宿主程序提供可编程的扩展能力
3. **基础设施定义语言**HCL / Dockerfile 等)—— 声明式外部 DSL,描述系统期望状态;Pulumi 则以内部 DSL 的方式实现同一目标
4. **接口描述语言与胶水代码生成**OpenAPI / .proto)—— 通过规范描述自动生成系统间的连接代码
理解 DSL 这一分类框架后,面对后端项目中各类"不像代码的代码"时,可以快速识别其性质:它属于哪类 DSL、解决什么领域的问题、为什么不用通用编程语言来写。
同时,由于 DSL 代码具有高度模式化、规范驱动、可自动验证的特征,它们也是当前 AI 代码生成技术最有效的应用领域。
@@ -1,3 +1,173 @@
# 域名、DNS 与 HTTPS
> 待实现
::: tip 前言
**当你在浏览器输入 `www.google.com` 并按下回车,背后发生了什么?** 这个看似简单的动作,背后涉及域名解析、DNS 查询、TLS 加密握手等一系列精密的协作过程。理解这些机制,是每个开发者的必修课——它直接关系到你的网站能不能被访问、数据会不会被窃取。
:::
**这篇文章会带你学什么?**
学完这章后,你将获得:
- **DNS 原理**:理解域名如何被翻译成 IP 地址的完整过程
- **记录类型**:掌握 A、CNAME、MX 等常见 DNS 记录的用途
- **HTTPS 机制**:理解 TLS 握手如何建立安全连接
- **证书体系**:了解数字证书的信任链和验证机制
- **安全意识**:明白为什么 HTTPS 是现代 Web 的底线要求
| 章节 | 内容 | 核心概念 |
|-----|------|---------|
| **第 1 章** | DNS 解析 | 递归查询、迭代查询 |
| **第 2 章** | DNS 记录 | A、CNAME、MX、TXT |
| **第 3 章** | HTTPS 与 TLS | 握手过程、加密通信 |
| **第 4 章** | 证书信任链 | CA、根证书、中间证书 |
| **第 5 章** | HTTP vs HTTPS | 明文 vs 加密、安全对比 |
---
## 0. 全景图:从域名到安全连接
互联网的通信基于 IP 地址(如 142.250.80.46),但人类记不住这些数字。于是我们发明了**域名系统(DNS)**——互联网的"电话簿",把人类可读的域名翻译成机器可读的 IP 地址。
但光能找到服务器还不够。如果通信内容是明文传输的,任何中间人都能窃听、篡改你的数据。**HTTPS** 就是解决这个问题的——它在 HTTP 之上加了一层 TLS 加密,确保数据在传输过程中的机密性和完整性。
::: tip 一次完整的网页访问
1. **域名解析**:浏览器问 DNS "www.google.com 的 IP 是多少?"DNS 回答 "142.250.80.46"
2. **TCP 连接**:浏览器与服务器建立 TCP 三次握手
3. **TLS 握手**:双方协商加密算法、验证证书、交换密钥
4. **加密通信**:所有 HTTP 数据通过加密通道传输
:::
---
## 1. DNS 解析:互联网的"电话簿"
DNSDomain Name System)的工作原理就像查电话簿:你知道对方的名字(域名),需要查到对方的电话号码(IP 地址)。但互联网的"电话簿"不是一本,而是一个分层的分布式系统。
<DnsResolutionDemo />
::: tip DNS 解析的四个步骤
1. **浏览器缓存**:先查本地缓存,如果之前访问过这个域名,直接用缓存的 IP
2. **递归解析器**:缓存没命中,请求发给 ISP 的递归解析器(如 8.8.8.8
3. **逐级查询**:递归解析器依次询问根域名服务器 → 顶级域服务器(.com)→ 权威域名服务器(google.com
4. **返回结果**:权威服务器返回最终 IP,递归解析器缓存结果并返回给浏览器
:::
| 层级 | 服务器 | 职责 | 数量 |
|------|-------|------|------|
| 根域 | Root Server | 知道所有顶级域的地址 | 全球 13 组 |
| 顶级域 | TLD Server | 管理 .com、.cn、.org 等 | 每个后缀一组 |
| 权威域 | Authoritative | 存储具体域名的 DNS 记录 | 每个域名至少 2 个 |
| 递归解析器 | Resolver | 代替用户完成整个查询过程 | ISP 或公共 DNS |
---
## 2. DNS 记录类型:域名背后的"配置表"
DNS 不只是把域名翻译成 IP。通过不同类型的 DNS 记录,你可以控制邮件投递、域名跳转、服务发现等多种行为。理解这些记录类型,是配置域名和排查网络问题的基础。
<DnsRecordTypeDemo />
| 记录类型 | 用途 | 示例 |
|---------|------|------|
| A | 域名 → IPv4 地址 | `example.com → 93.184.216.34` |
| AAAA | 域名 → IPv6 地址 | `example.com → 2606:2800:220:1:...` |
| CNAME | 域名 → 另一个域名(别名) | `www.example.com → example.com` |
| MX | 指定邮件服务器 | `example.com → mail.example.com` |
| TXT | 存储文本信息 | SPF 验证、域名所有权验证 |
| NS | 指定权威域名服务器 | `example.com → ns1.example.com` |
::: tip 实际场景中的 DNS 配置
- **部署网站**:添加 A 记录指向服务器 IP,或 CNAME 指向 CDN 域名
- **配置邮箱**:添加 MX 记录指向邮件服务器,TXT 记录配置 SPF/DKIM 防垃圾邮件
- **验证域名所有权**:云服务商要求你添加特定 TXT 记录来证明你拥有这个域名
- **负载均衡**:同一域名配置多条 A 记录,DNS 轮询分发流量
:::
---
## 3. HTTPS 与 TLS:给数据穿上"防弹衣"
HTTP 协议的数据是明文传输的——就像寄明信片,邮递员(中间人)可以随意阅读内容。HTTPS 在 HTTP 之上加了一层 TLSTransport Layer Security)加密,相当于把明信片装进了密封信封。
TLS 握手是建立安全连接的关键步骤,它在正式传输数据之前,完成身份验证和密钥协商。
<HttpsHandshakeDemo />
::: tip TLS 1.3 握手的核心步骤
1. **Client Hello**:客户端发送支持的加密算法列表和一个随机数
2. **Server Hello**:服务器选择加密算法,返回数字证书和随机数
3. **证书验证**:客户端验证服务器证书是否可信(检查 CA 签名、有效期、域名匹配)
4. **密钥交换**:双方通过 ECDHE 算法协商出一个共享密钥(不在网络上传输密钥本身)
5. **加密通信**:后续所有数据使用协商好的对称密钥加密传输
:::
| 特性 | TLS 1.2 | TLS 1.3 |
|------|---------|---------|
| 握手往返次数 | 2-RTT | 1-RTT(首次)/ 0-RTT(恢复) |
| 密钥交换 | RSA 或 ECDHE | 仅 ECDHE(前向安全) |
| 加密算法 | 支持较多旧算法 | 仅保留安全算法 |
| 性能 | 较慢 | 更快 |
---
## 4. 证书信任链:凭什么相信这个网站?
TLS 握手中最关键的一步是"证书验证"。浏览器怎么判断一个网站的证书是真的,而不是攻击者伪造的?答案是**证书信任链**——一个层层背书的信任体系。
<CertificateChainDemo />
::: tip 证书信任链的三层结构
1. **根证书(Root CA**:由受信任的证书颁发机构签发,预装在操作系统和浏览器中。这是信任的"锚点"。
2. **中间证书(Intermediate CA**:由根 CA 签发,用于签发终端证书。根 CA 不直接签发网站证书,是为了安全隔离。
3. **终端证书(Leaf Certificate**:你的网站实际使用的证书,由中间 CA 签发,包含域名、公钥、有效期等信息。
:::
| 证书类型 | 验证级别 | 颁发速度 | 适用场景 |
|---------|---------|---------|---------|
| DV(域名验证) | 仅验证域名所有权 | 分钟级 | 个人网站、博客 |
| OV(组织验证) | 验证组织身份 | 数天 | 企业官网 |
| EV(扩展验证) | 严格验证组织 | 数周 | 银行、金融机构 |
| 通配符证书 | 覆盖所有子域名 | 视类型而定 | 多子域名场景 |
---
## 5. HTTP vs HTTPS:为什么加密是底线?
2024 年,全球超过 95% 的网页流量已经通过 HTTPS 传输。Chrome 浏览器会对 HTTP 网站标记"不安全"警告,搜索引擎也会降低 HTTP 网站的排名。HTTPS 不再是"可选项",而是现代 Web 的底线要求。
<DnsHttpsComparisonDemo />
| 维度 | HTTP | HTTPS |
|------|------|-------|
| 数据传输 | 明文,可被窃听 | 加密,无法被窃听 |
| 身份验证 | 无,无法确认服务器身份 | 有,通过证书验证服务器 |
| 数据完整性 | 无保护,可被篡改 | 有保护,篡改会被检测 |
| 端口 | 80 | 443 |
| SEO 影响 | 搜索排名降低 | 搜索排名加分 |
| 浏览器表现 | 显示"不安全"警告 | 显示锁图标 |
::: tip 免费获取 HTTPS 证书
**Let's Encrypt** 是一个免费、自动化的证书颁发机构,让任何网站都能零成本启用 HTTPS。配合 Certbot 工具,可以一键申请和自动续期证书。大多数云平台和 CDN 服务商也提供免费的 SSL 证书。
:::
---
## 总结
域名、DNS 和 HTTPS 是互联网基础设施的三大支柱。DNS 让我们用人类可读的名字访问网站,HTTPS 确保通信过程安全可信。
回顾本章的关键要点:
1. **DNS 是分层系统**:根域 → 顶级域 → 权威域,逐级查询,缓存加速
2. **记录类型各有用途**:A 记录指向 IP,CNAME 做别名,MX 管邮件,TXT 做验证
3. **TLS 握手建立信任**:证书验证 + 密钥协商,TLS 1.3 只需 1-RTT
4. **证书信任链**:根 CA → 中间 CA → 终端证书,层层背书
5. **HTTPS 是底线**:免费证书(Let's Encrypt)让加密零门槛
## 延伸阅读
- [How DNS Works](https://howdns.works/) - 漫画形式讲解 DNS 工作原理
- [Let's Encrypt 文档](https://letsencrypt.org/docs/) - 免费 SSL 证书申请指南
- [Cloudflare Learning Center](https://www.cloudflare.com/learning/dns/what-is-dns/) - DNS 和网络安全系统教程
- [TLS 1.3 RFC 8446](https://datatracker.ietf.org/doc/html/rfc8446) - TLS 1.3 协议规范
- [SSL Labs](https://www.ssllabs.com/ssltest/) - 在线检测网站 HTTPS 配置质量
@@ -1,3 +1,158 @@
# 故障排查与应急响应
> 待实现
::: tip 前言
**凌晨三点,手机疯狂震动,线上服务全面瘫痪——你该怎么办?** 对于任何互联网团队来说,故障不是"会不会发生"的问题,而是"什么时候发生"的问题。优秀的团队不是不出故障,而是出了故障能快速响应、高效恢复,并从中学习避免重蹈覆辙。
:::
**这篇文章会带你学什么?**
学完这章后,你将获得:
- **分级意识**:掌握 P0~P4 事故严重程度分级标准
- **响应流程**:理解从发现到恢复的完整事故响应时间线
- **组织协作**:了解事故指挥体系中的角色分工和协作机制
- **告警体系**:掌握告警升级策略,确保关键问题不被遗漏
- **复盘方法**:学会用"五个为什么"挖掘根因,写出有价值的复盘报告
| 章节 | 内容 | 核心概念 |
|-----|------|---------|
| **第 1 章** | 严重程度分级 | P0~P4、影响范围评估 |
| **第 2 章** | 响应时间线 | 发现→响应→恢复→复盘 |
| **第 3 章** | 指挥体系 | IC、通信官、技术负责人 |
| **第 4 章** | 告警升级 | 分级告警、逐级升级 |
| **第 5 章** | 事后复盘 | 五个为什么、无责文化 |
---
## 0. 全景图:故障是最好的老师
Netflix 有一个著名的工具叫 Chaos Monkey——它会随机杀掉生产环境的服务器。听起来疯狂,但背后的逻辑很清晰:**与其等故障找上门,不如主动制造故障来锻炼团队的应急能力**。
应急响应不是靠临场发挥,而是靠**流程、角色、工具**三位一体的体系化建设。就像消防队不是火灾发生时才组建的——他们平时就在训练、演练、维护装备。
::: tip 应急响应的四个核心要素
- **快速发现**:完善的监控和告警体系,确保问题在用户感知之前被发现
- **高效协作**:清晰的角色分工和沟通机制,避免混乱中的重复劳动
- **快速恢复**:优先恢复服务,而不是优先找根因。先止血,再治病
- **持续改进**:每次故障都是学习机会,通过复盘不断完善系统和流程
:::
---
## 1. 严重程度分级:不是所有故障都要"全员出动"
一个按钮颜色显示错误和整个支付系统瘫痪,显然不是同一个级别的问题。**事故分级**的目的是让团队用合适的力度响应合适级别的问题——既不过度反应浪费资源,也不轻视问题导致损失扩大。
<SeverityLevelDemo />
| 级别 | 名称 | 影响范围 | 响应要求 | 示例 |
|------|------|---------|---------|------|
| P0 | 致命 | 核心业务完全不可用 | 立即响应,全员待命 | 支付系统瘫痪、数据泄露 |
| P1 | 严重 | 核心功能严重受损 | 15 分钟内响应 | 登录失败率 > 50%、API 大面积超时 |
| P2 | 重要 | 部分功能异常 | 1 小时内响应 | 搜索结果不准确、部分页面 500 |
| P3 | 一般 | 非核心功能异常 | 工作时间处理 | 头像加载失败、非关键通知延迟 |
| P4 | 轻微 | 体验问题 | 排入迭代计划 | UI 错位、文案错误 |
::: tip 分级的关键原则
- **影响用户数**:影响 100% 用户的 P2 可能比影响 1% 用户的 P1 更紧急
- **业务损失**:直接影响收入的问题(支付、下单)优先级更高
- **可降级处理**:如果有临时方案可以缓解影响,可以适当降级处理
- **动态调整**:随着排查深入,级别可能上调或下调
:::
---
## 2. 响应时间线:从发现到复盘的完整流程
一次事故响应就像一场接力赛,每个阶段都有明确的目标和交接点。清晰的时间线能让团队在混乱中保持有序。
<IncidentTimelineDemo />
::: tip 事故响应的五个阶段
1. **检测(Detection**:通过监控告警、用户反馈或内部巡检发现异常。目标:尽早发现,缩短 MTTD(平均检测时间)。
2. **响应(Response**:确认事故、评估严重程度、召集响应团队、建立沟通频道。目标:快速组织起有效的响应力量。
3. **缓解(Mitigation**:采取临时措施恢复服务,如回滚部署、切换备用节点、限流降级。目标:先止血,恢复用户体验。
4. **修复(Resolution**:找到根本原因并彻底修复。目标:消除隐患,防止复发。
5. **复盘(Postmortem**:回顾整个过程,分析根因,制定改进措施。目标:从故障中学习,让系统更健壮。
:::
| 指标 | 含义 | 优化方向 |
|------|------|---------|
| MTTD | 平均检测时间 | 完善监控覆盖、降低告警阈值 |
| MTTR | 平均恢复时间 | 自动化恢复、预案演练 |
| MTBF | 平均故障间隔 | 提升系统可靠性、消除单点故障 |
---
## 3. 指挥体系:谁来指挥这场"战斗"?
大型事故中最怕的不是技术难题,而是**混乱**——十几个人同时在排查,没人知道别人在做什么,关键信息在各个群里碎片化传播。事故指挥体系(Incident Command System)就是为了解决这个问题。
<IncidentCommandDemo />
::: tip 三个核心角色
1. **事故指挥官(Incident Commander, IC**:整个事故响应的总负责人。负责决策、协调资源、把控节奏。IC 不一定是技术最强的人,但必须是最冷静、最有全局观的人。
2. **通信官(Communication Lead**:负责对外沟通——更新状态页、通知客户、同步管理层。让 IC 和技术人员专注于解决问题,不被沟通事务打断。
3. **技术负责人(Tech Lead**:负责技术层面的排查和修复。组织技术人员分工协作,向 IC 汇报进展和方案。
:::
---
## 4. 告警升级:确保关键问题不被遗漏
告警系统是事故响应的"眼睛"。但告警太少会漏报,告警太多会导致"告警疲劳"——当每天收到几百条告警时,真正重要的那条很容易被淹没。**告警升级策略**就是解决这个问题的关键。
<AlertEscalationDemo />
::: tip 告警升级的三层机制
1. **一线响应(L1**:告警触发后,先通知值班工程师。如果 15 分钟内未确认,自动升级。
2. **二线升级(L2**:通知团队负责人和相关领域专家。如果 30 分钟内未缓解,继续升级。
3. **三线升级(L3**:通知技术总监和管理层,启动全面应急响应。
:::
| 告警级别 | 通知方式 | 响应时限 | 升级条件 |
|---------|---------|---------|---------|
| Warning | IM 消息 | 工作时间处理 | 持续 30 分钟未恢复 |
| Critical | 电话 + IM | 15 分钟内确认 | 未确认或未缓解 |
| Fatal | 电话轰炸 + 短信 | 5 分钟内响应 | 自动升级至管理层 |
---
## 5. 事后复盘:从故障中学习
事故恢复后,最重要的一步是**复盘(Postmortem)**。复盘不是为了追责,而是为了找到系统性的改进机会。Google、Meta 等公司都奉行"无责复盘"文化——关注"系统为什么允许这个错误发生",而不是"谁犯了这个错误"。
<PostmortemDemo />
::: tip "五个为什么"分析法
从表面现象出发,连续追问"为什么",直到找到根本原因:
1. **为什么服务挂了?** → 数据库连接池耗尽
2. **为什么连接池耗尽?** → 慢查询占用连接不释放
3. **为什么有慢查询?** → 缺少索引,全表扫描
4. **为什么缺少索引?** → 新表上线时没有 DBA 审核
5. **为什么没有审核?** → 没有强制的 SQL 审核流程
根因不是"某个人忘了加索引",而是"缺少 SQL 审核流程"。修复根因才能防止复发。
:::
---
## 总结
故障排查与应急响应是每个技术团队的必备能力。它不是靠英雄主义的个人发挥,而是靠体系化的流程、清晰的角色分工和持续的复盘改进。
回顾本章的关键要点:
1. **分级响应**:P0~P4 分级确保用合适的力度应对合适级别的问题
2. **时间线清晰**:检测→响应→缓解→修复→复盘,每个阶段目标明确
3. **指挥体系**:IC + 通信官 + 技术负责人,分工协作避免混乱
4. **告警升级**:分级告警 + 自动升级,确保关键问题不被遗漏
5. **无责复盘**:用"五个为什么"挖掘根因,关注系统改进而非个人追责
## 延伸阅读
- [Google SRE Book - Incident Response](https://sre.google/sre-book/managing-incidents/) - Google 的事故管理实践
- [PagerDuty Incident Response Guide](https://response.pagerduty.com/) - PagerDuty 开源的应急响应指南
- [Atlassian Incident Management](https://www.atlassian.com/incident-management) - Atlassian 的事故管理最佳实践
- [Learning from Incidents](https://www.learningfromincidents.io/) - 从事故中学习的社区资源
- [Chaos Engineering (O'Reilly)](https://www.oreilly.com/library/view/chaos-engineering/9781492043850/) - 混沌工程原理与实践
@@ -1,3 +1,173 @@
# 基础设施即代码
> 待实现
::: tip 前言
**你有没有经历过这种噩梦:线上服务器挂了,但没人记得当初是怎么配置的?** 手动登录服务器、凭记忆敲命令、祈祷不要敲错——这就是传统运维的日常。基础设施即代码(Infrastructure as CodeIaC)彻底改变了这一切:用代码来定义和管理基础设施,让服务器配置像软件一样可版本控制、可复现、可审计。
:::
**这篇文章会带你学什么?**
学完这章后,你将获得:
- **核心概念**:理解 IaC 是什么,为什么它是现代运维的基石
- **工作流认知**:掌握 Terraform 的 Write → Plan → Apply → Destroy 四阶段流程
- **工具选型**:了解 Terraform、Pulumi、CloudFormation 等主流工具的优劣
- **风险意识**:理解配置漂移的危害和检测方法
- **最佳实践**:掌握 IaC 项目的工程化管理方法
| 章节 | 内容 | 核心概念 |
|-----|------|---------|
| **第 1 章** | IaC 概念 | 手动运维 vs 代码化管理 |
| **第 2 章** | Terraform 工作流 | Write → Plan → Apply |
| **第 3 章** | 工具对比 | Terraform、Pulumi、CDK |
| **第 4 章** | 配置漂移 | 检测、预防、修复 |
| **第 5 章** | 最佳实践 | 模块化、状态管理、CI/CD |
---
## 0. 全景图:为什么基础设施也需要"源代码"?
想象你是一个厨师。如果每道菜都凭感觉做,今天放一勺盐、明天放两勺,味道永远不稳定。但如果你把配方写下来——精确到每种调料的克数——任何人都能复现同样的味道。
基础设施管理面临的是同样的问题。一台服务器的配置可能涉及操作系统、网络规则、安全组、存储卷、环境变量等几十个参数。手动配置不仅容易出错,而且**不可复现、不可审计、不可回滚**。
::: tip IaC 的核心价值
- **可复现**:同一份代码,无论执行多少次,结果都一样(幂等性)
- **可版本控制**:基础设施变更通过 Git 管理,谁改了什么、为什么改,一目了然
- **可审计**:所有变更都有记录,满足合规要求
- **可自动化**:通过 CI/CD 流水线自动部署,消除人为操作风险
- **可协作**:团队成员通过 Pull Request 审查基础设施变更,就像审查代码一样
:::
---
## 1. IaC 概念:从"手动点击"到"代码声明"
传统运维的工作方式是:登录云平台控制台,手动点击创建服务器、配置网络、设置安全组。这种方式在管理几台服务器时还能应付,但当规模扩大到几十、几百台时,就变成了噩梦。
IaC 的核心思想是:**用声明式代码描述你想要的基础设施状态,让工具自动帮你实现**。你不需要告诉工具"先创建 VPC,再创建子网,再创建安全组"(命令式),只需要说"我要一个这样的网络环境"(声明式),工具会自动计算出需要执行的步骤。
<IaCConceptDemo />
| 维度 | 手动运维 | 基础设施即代码 |
|------|---------|--------------|
| 操作方式 | 登录控制台点击 | 编写代码文件 |
| 可复现性 | 依赖文档和记忆 | 代码即文档,100% 可复现 |
| 变更追踪 | 无记录或记录不全 | Git 版本控制,完整历史 |
| 协作方式 | 口头沟通、文档传递 | Pull Request 审查 |
| 回滚能力 | 手动逆向操作 | git revert + 重新 apply |
| 一致性 | 环境间差异大 | 开发/测试/生产完全一致 |
::: tip 声明式 vs 命令式
- **声明式(Declarative**:描述"我要什么",工具自动计算"怎么做"。Terraform、CloudFormation 采用这种方式。优点是幂等性好,缺点是灵活性受限。
- **命令式(Imperative**:描述"怎么做",一步步执行。Ansible、Shell 脚本采用这种方式。优点是灵活,缺点是难以保证幂等性。
- **混合式**Pulumi、AWS CDK 用通用编程语言编写,兼具声明式的状态管理和命令式的灵活性。
:::
---
## 2. Terraform 工作流:Write → Plan → Apply
Terraform 是目前最流行的 IaC 工具,由 HashiCorp 开发。它的工作流程清晰直观,分为四个阶段,就像软件开发的"编码→审查→部署→清理"。
<TerraformWorkflowDemo />
::: tip 四阶段工作流
1. **Write(编写)**:用 HCLHashiCorp Configuration Language)编写基础设施定义文件(.tf)。声明你需要的资源:服务器、数据库、网络等。
2. **Plan(计划)**:运行 `terraform plan`,Terraform 会对比当前状态和目标状态,生成一份"执行计划"——告诉你它打算创建、修改、删除哪些资源。这是安全网,让你在真正执行前确认变更。
3. **Apply(执行)**:确认计划无误后,运行 `terraform apply`,Terraform 按计划创建或修改资源。执行完成后,当前状态会保存到状态文件(terraform.tfstate)。
4. **Destroy(销毁)**:不再需要时,运行 `terraform destroy` 清理所有资源,避免产生不必要的费用。
:::
| 命令 | 作用 | 是否修改基础设施 | 使用场景 |
|------|------|----------------|---------|
| `terraform init` | 初始化项目,下载 Provider | 否 | 首次使用或添加新 Provider |
| `terraform plan` | 预览变更,生成执行计划 | 否 | 每次变更前必须执行 |
| `terraform apply` | 执行变更,创建/修改资源 | 是 | 确认 plan 后执行 |
| `terraform destroy` | 销毁所有资源 | 是 | 清理测试环境、下线服务 |
| `terraform state` | 查看/管理状态文件 | 视操作而定 | 状态迁移、资源导入 |
---
## 3. 工具对比:选择适合你的 IaC 工具
IaC 领域有多种工具,各有侧重。选择工具时需要考虑团队技术栈、云平台、项目规模等因素。没有"最好"的工具,只有最适合你场景的工具。
<IaCToolComparisonDemo />
| 工具 | 语言 | 云平台支持 | 学习曲线 | 适用场景 |
|------|------|-----------|---------|---------|
| Terraform | HCL | 多云(AWS/Azure/GCP | 中等 | 多云环境、团队协作 |
| Pulumi | Python/TS/Go | 多云 | 低(熟悉编程语言) | 开发者友好、复杂逻辑 |
| AWS CloudFormation | JSON/YAML | 仅 AWS | 中等 | 纯 AWS 环境 |
| AWS CDK | Python/TS/Java | 仅 AWS | 低 | AWS + 编程语言偏好 |
| Ansible | YAML | 多云 + 裸机 | 低 | 配置管理、混合环境 |
::: tip 如何选择?
- **初创团队 / 单云**CloudFormation(AWS)或对应云平台原生工具,生态集成最好
- **多云 / 中大型团队**Terraform,社区最大、Provider 最丰富、招聘最容易
- **开发者主导的团队**:Pulumi 或 CDK,用熟悉的编程语言写基础设施,IDE 支持好
- **需要配置管理**:Ansible,擅长服务器内部配置(安装软件、修改配置文件)
:::
---
## 4. 配置漂移:无声的定时炸弹
配置漂移(Configuration Drift)是 IaC 实践中最隐蔽的敌人。它指的是**实际基础设施状态与代码定义的状态之间逐渐产生偏差**。
这种偏差通常是怎么产生的?有人为了"快速修复"一个线上问题,直接登录控制台手动改了安全组规则;有人为了调试,临时加大了某台服务器的配置但忘了改回来。这些"小改动"日积月累,最终导致代码和实际环境严重脱节。
<ConfigDriftDemo />
::: tip 配置漂移的危害
1. **不可复现**:代码描述的环境和实际环境不一致,新建环境时会出问题
2. **回滚失败**:以为回滚到上一版本就能恢复,但实际环境已经被手动修改过
3. **安全隐患**:手动开放的端口、放宽的权限可能被遗忘,成为攻击入口
4. **审计失效**:合规审计基于代码,但代码不反映真实状态
:::
| 预防措施 | 说明 |
|---------|------|
| 禁止手动变更 | 通过 IAM 策略限制控制台操作权限 |
| 定期漂移检测 | 定时运行 `terraform plan` 检查差异 |
| 自动修复 | 检测到漂移后自动执行 apply 恢复一致性 |
| 变更审计 | 开启 CloudTrail 等审计日志,追踪所有变更来源 |
---
## 5. 最佳实践:让 IaC 项目可持续演进
IaC 代码和应用代码一样,需要良好的工程实践来保证可维护性。随着基础设施规模增长,没有章法的 IaC 代码会变成另一种形式的"技术债"。
<IaCBestPracticeDemo />
::: tip 六条核心最佳实践
1. **模块化**:将可复用的基础设施抽象为模块(如 VPC 模块、数据库模块),避免复制粘贴。就像写函数一样,一处定义、多处调用。
2. **环境隔离**:开发、测试、生产使用独立的状态文件和变量文件,通过 workspace 或目录结构隔离。
3. **远程状态管理**:状态文件(tfstate)存储在远程后端(S3 + DynamoDB),支持团队协作和状态锁定,避免并发冲突。
4. **敏感信息管理**:密码、密钥等敏感信息不要写在代码里,使用 Vault、AWS Secrets Manager 等工具管理。
5. **CI/CD 集成**:将 terraform plan 集成到 PR 流程,apply 通过流水线自动执行,杜绝本地手动操作。
6. **代码审查**:基础设施变更和应用代码一样需要 Code Review,尤其是涉及安全组、IAM 策略的变更。
:::
---
## 总结
基础设施即代码是现代云原生运维的基石。它把"不可描述的手动操作"变成了"可版本控制的代码",让基础设施管理从"艺术"变成了"工程"。
回顾本章的关键要点:
1. **IaC 的本质**:用代码声明基础设施的期望状态,让工具自动实现
2. **Terraform 工作流**Write → Plan → Apply 三步走,Plan 是安全网
3. **工具选型**:多云选 Terraform,单云选原生工具,开发者团队选 Pulumi
4. **配置漂移**:最隐蔽的风险,需要通过流程和工具双重防护
5. **工程化管理**:模块化、环境隔离、远程状态、CI/CD 集成缺一不可
## 延伸阅读
- [Terraform 官方教程](https://developer.hashicorp.com/terraform/tutorials) - 从零开始学 Terraform
- [Pulumi 文档](https://www.pulumi.com/docs/) - 用编程语言写基础设施
- [AWS CDK Workshop](https://cdkworkshop.com/) - AWS CDK 实战教程
- [Infrastructure as Code (O'Reilly)](https://www.oreilly.com/library/view/infrastructure-as-code/9781098114664/) - IaC 领域的经典书籍
- [Spacelift Blog](https://spacelift.io/blog) - IaC 最佳实践和行业趋势
@@ -1,3 +1,164 @@
# AI 原生应用设计
> 待实现
::: tip 前言
**为什么有些 AI 产品让人惊艳,而有些只是"套壳 ChatGPT"** 差别不在于用了多强的模型,而在于产品是否从底层就围绕 AI 的特性来设计。AI 原生应用不是在传统应用上"加个聊天框",而是重新思考用户交互、系统架构和产品逻辑的全新范式。
:::
**这篇文章会带你学什么?**
学完这章后,你将获得:
- **范式认知**:理解 AI 原生应用与传统应用的本质区别
- **设计原则**:掌握 AI 原生产品设计的核心原则
- **Prompt 工程**:了解如何设计高质量的 Prompt 来驱动 AI 能力
- **交互模式**:认识 AI 时代的新型用户交互范式
- **架构思维**:理解 AI 应用的请求处理流程和系统架构
| 章节 | 内容 | 核心概念 |
|-----|------|---------|
| **第 1 章** | 架构对比 | 传统应用 vs AI 原生应用 |
| **第 2 章** | 设计原则 | AI-First 思维、不确定性设计 |
| **第 3 章** | Prompt 工程 | 系统提示词、模板设计 |
| **第 4 章** | 交互模式 | 流式输出、多模态、Agent |
| **第 5 章** | 请求流程 | AI 应用的完整生命周期 |
---
## 0. 全景图:从"加个 AI"到"AI 原生"
过去几年,很多产品的 AI 化路径是这样的:有一个现成的应用,然后在某个角落加一个"AI 助手"按钮。这种做法就像在马车上装一个引擎——能跑,但远不如从头设计一辆汽车。
**AI 原生应用**是一种全新的产品思维:从第一行代码开始,就把 AI 作为核心能力来设计,而不是事后附加的功能。
::: tip 传统应用 vs AI 原生应用
- **传统应用**:用户操作 → 确定性逻辑 → 确定性结果。每次点击"提交订单",流程完全一样。
- **AI 原生应用**:用户意图 → AI 理解 → 概率性结果。同样的问题,每次回答可能略有不同。
- **核心转变**:从"编写规则"到"描述意图",从"确定性"到"概率性",从"操作界面"到"对话界面"。
:::
---
## 1. 架构对比:两种完全不同的世界
传统应用的架构是"请求-响应"模型:用户点击按钮,后端执行确定性逻辑,返回确定性结果。整个过程可预测、可测试、可复现。
AI 原生应用则引入了一个全新的角色——**大语言模型**。它像一个"智能中间层",接收自然语言输入,输出自然语言结果。这带来了架构上的根本性变化。
<AINativeArchDemo />
| 维度 | 传统应用 | AI 原生应用 |
|------|---------|------------|
| 输入方式 | 表单、按钮、下拉框 | 自然语言、图片、语音 |
| 处理逻辑 | if-else、规则引擎 | LLM 推理、Prompt 驱动 |
| 输出特性 | 确定性、可复现 | 概率性、每次可能不同 |
| 延迟特征 | 毫秒级 | 秒级(需要流式输出) |
| 错误处理 | 明确的错误码 | 幻觉、拒绝回答、答非所问 |
| 成本模型 | 固定计算资源 | 按 token 计费,成本波动大 |
::: tip 架构演进的三个阶段
1. **AI 增强型**:在现有应用中嵌入 AI 功能(如自动补全、智能推荐)
2. **AI 协作型**:AI 作为核心交互方式,但仍有传统 UI 兜底(如 Notion AI、GitHub Copilot
3. **AI 原生型**:整个产品围绕 AI 构建,去掉 AI 产品就不成立(如 ChatGPT、Cursor、Midjourney
:::
---
## 2. 设计原则:AI 原生产品的"宪法"
设计 AI 原生应用不能照搬传统软件的设计思路。AI 的概率性、延迟性和不可预测性,要求我们建立一套全新的设计原则。
<AIDesignPrincipleDemo />
::: tip 五大核心设计原则
1. **拥抱不确定性**:AI 的输出不是 100% 可靠的,产品设计必须考虑"AI 可能出错"的情况。提供编辑、重试、反馈机制,让用户始终拥有控制权。
2. **渐进式信任**:不要一开始就让 AI 做高风险决策。先从低风险场景建立用户信任,再逐步扩展 AI 的自主权。
3. **透明可解释**:让用户知道 AI 在做什么、为什么这么做。展示推理过程、引用来源、标注置信度。
4. **人机协作**:AI 不是替代人,而是增强人。最好的设计是让 AI 做初稿,人做终审。
5. **优雅降级**:当 AI 服务不可用或结果不理想时,产品仍然可用。永远有 Plan B。
:::
---
## 3. Prompt 工程:AI 应用的"编程语言"
在传统应用中,你用代码告诉计算机做什么。在 AI 原生应用中,你用 Prompt 告诉模型做什么。**Prompt 就是 AI 时代的编程语言**——写得好,AI 表现惊艳;写得差,AI 胡说八道。
<PromptDesignDemo />
::: tip Prompt 设计的四层结构
1. **系统提示词(System Prompt**:定义 AI 的角色、能力边界和行为规范。这是"宪法"级别的指令,用户看不到但始终生效。
2. **上下文注入(Context**:通过 RAG 检索到的相关文档、用户历史记录等,为 AI 提供回答所需的背景信息。
3. **用户输入(User Message**:用户的实际问题或指令。
4. **输出格式约束(Format**:指定 AI 的输出格式(JSON、Markdown、特定模板),确保结果可被程序解析。
:::
| Prompt 技巧 | 说明 | 效果 |
|------------|------|------|
| 角色设定 | "你是一个资深前端工程师" | 提升专业领域回答质量 |
| Few-shot 示例 | 给出 2-3 个输入输出示例 | 让模型理解期望的格式和风格 |
| 思维链(CoT | "请一步步思考" | 提升复杂推理的准确性 |
| 输出约束 | "用 JSON 格式回答" | 确保输出可被程序解析 |
| 负面指令 | "不要编造不确定的信息" | 减少幻觉和错误信息 |
---
## 4. 交互模式:AI 时代的用户体验
AI 原生应用催生了一批全新的交互模式。传统应用的交互是"点击-等待-查看",而 AI 应用的交互更像是"对话-观察-调整"。
<AIUXPatternDemo />
::: tip 四种核心交互模式
1. **流式输出(Streaming**:AI 生成内容时逐字显示,而不是等全部生成完再展示。这大幅降低了用户的感知等待时间,也让用户可以在生成过程中判断方向是否正确。
2. **多轮对话(Multi-turn**:通过上下文记忆实现连续对话,用户可以逐步细化需求。关键挑战是上下文窗口管理和对话历史压缩。
3. **多模态交互(Multimodal**:支持文本、图片、语音、文件等多种输入方式,AI 也能输出图片、代码、表格等多种格式。
4. **Agent 模式(Agentic**:AI 不只是回答问题,而是自主规划、执行多步骤任务。用户给出目标,AI 自行拆解步骤并逐一完成。
:::
---
## 5. 请求流程:一次 AI 调用的完整生命周期
当用户在 AI 应用中发送一条消息,背后发生了什么?理解这个完整流程,是构建可靠 AI 应用的基础。
<AIAppFlowDemo />
::: tip 请求处理的六个阶段
1. **输入预处理**:校验用户输入、内容安全审核、敏感信息脱敏
2. **上下文组装**:拼接系统提示词、检索相关文档(RAG)、加载对话历史
3. **模型调用**:将组装好的 Prompt 发送给 LLM API,开启流式响应
4. **输出后处理**:格式化输出、内容安全过滤、结构化数据提取
5. **结果缓存**:对常见问题缓存结果,降低成本和延迟
6. **监控记录**:记录 token 用量、响应时间、用户反馈,用于持续优化
:::
| 阶段 | 关键考量 | 常见问题 |
|------|---------|---------|
| 输入预处理 | 注入攻击防护、长度限制 | Prompt 注入、越狱攻击 |
| 上下文组装 | token 预算分配、信息优先级 | 上下文溢出、关键信息被截断 |
| 模型调用 | 超时处理、重试策略、流式传输 | API 限流、网络超时 |
| 输出后处理 | 格式校验、幻觉检测 | 输出格式不符预期 |
| 缓存策略 | 语义缓存 vs 精确缓存 | 缓存命中率低 |
| 监控告警 | 成本监控、质量评估 | token 成本失控 |
---
## 总结
AI 原生应用设计不是简单地在传统应用上叠加 AI 功能,而是从架构、交互、工程实践等维度进行全面重构。
回顾本章的关键要点:
1. **架构转变**:从确定性逻辑到概率性推理,AI 原生应用需要全新的架构思维
2. **设计原则**:拥抱不确定性、渐进式信任、透明可解释、人机协作、优雅降级
3. **Prompt 是核心**Prompt 工程是 AI 应用的"编程语言",直接决定产品质量
4. **交互革新**:流式输出、多轮对话、多模态、Agent 模式重新定义了用户体验
5. **全链路思维**:从输入预处理到监控告警,每个环节都需要针对 AI 特性专门设计
## 延伸阅读
- [Google PAIR Guidelines](https://pair.withgoogle.com/) - Google 的人机交互 AI 设计指南
- [OpenAI Prompt Engineering Guide](https://platform.openai.com/docs/guides/prompt-engineering) - 官方 Prompt 工程最佳实践
- [Anthropic Prompt Engineering](https://docs.anthropic.com/en/docs/build-with-claude/prompt-engineering) - Claude 的 Prompt 设计指南
- [Nielsen Norman Group: AI UX](https://www.nngroup.com/topic/artificial-intelligence/) - AI 用户体验研究
- [Building LLM Applications](https://www.oreilly.com/library/view/building-llm-powered/9781835462317/) - 构建 LLM 应用的实战指南
@@ -1,3 +1,193 @@
# Embedding 与向量检索
> 待实现
::: tip 前言
**计算机怎么理解"猫和狗很像,但和汽车不像"这件事?** 对人类来说这是常识,但对计算机来说,"猫"、"狗"、"汽车"不过是三个毫无关联的字符串。Embedding(嵌入)技术就是解决这个问题的关键——它把文字变成数字向量,让计算机也能理解语义上的"远近亲疏"。
:::
**这篇文章会带你学什么?**
学完这章后,你将获得:
- **直觉理解**:明白 Embedding 是什么,为什么"猫"和"狗"的向量会靠近
- **相似度计算**:掌握余弦相似度、欧氏距离等核心度量方法
- **索引原理**:理解向量数据库如何在百万级数据中毫秒级检索
- **技术选型**:了解主流向量数据库的特点和适用场景
- **端到端流程**:掌握从文本到向量到检索的完整 Pipeline
| 章节 | 内容 | 核心概念 |
|-----|------|---------|
| **第 1 章** | Embedding 概念 | 语义空间、向量表示 |
| **第 2 章** | 相似度计算 | 余弦相似度、欧氏距离 |
| **第 3 章** | 向量索引 | 暴力搜索 vs ANN |
| **第 4 章** | 向量数据库 | Pinecone、Milvus、Chroma |
| **第 5 章** | 端到端 Pipeline | 文本→向量→存储→查询 |
---
## 0. 全景图:从文字到数字的桥梁
在自然语言处理的世界里,有一个根本性的挑战:**计算机只认识数字,不认识文字**。
早期的做法是给每个词分配一个编号(One-Hot 编码),比如"猫"=001"狗"=010"汽车"=100。但这样做有个致命问题:**所有词之间的距离都一样远**。"猫"到"狗"的距离和"猫"到"汽车"的距离完全相同——这显然不符合我们的直觉。
Embedding 的革命性在于:它把每个词映射到一个**稠密的低维向量空间**,让语义相近的词自然聚集在一起。在这个空间里,"猫"和"狗"靠得很近,而"汽车"则在远处——计算机终于能"理解"语义了。
::: tip 从 One-Hot 到 Embedding 的飞跃
- **One-Hot**:维度 = 词表大小(可能几万维),每个向量只有一个 1,其余全是 0,稀疏且无语义
- **Embedding**:维度通常 768~1536,每个数字都有意义,稠密且富含语义信息
- **关键突破**Word2Vec2013)证明了"词的含义可以用它的上下文来定义",开启了 Embedding 时代
:::
---
## 1. Embedding 概念:把文字变成坐标
Embedding 的核心思想可以用一句话概括:**用一组数字(向量)来表示一个词或句子的含义**。
想象一个二维坐标系。我们把"猫"放在坐标 (0.2, 0.7)"狗"放在 (0.3, 0.6)"汽车"放在 (0.9, 0.1)。你会发现"猫"和"狗"的坐标很接近,而"汽车"离它们很远。这就是 Embedding 的直觉——**语义相似度变成了空间距离**。
<EmbeddingConceptDemo />
::: tip Embedding 的三个关键特性
1. **语义聚类**:相似含义的词会自动聚集在一起(动物一簇、食物一簇、科技一簇)
2. **类比关系**:向量运算可以表达语义关系,经典例子:king - man + woman ≈ queen
3. **维度含义**:每个维度隐式编码了某种语义特征(如"是否是动物"、"大小"、"情感倾向"等)
:::
| 编码方式 | 维度 | 语义信息 | 典型应用 |
|---------|------|---------|---------|
| One-Hot | 词表大小(~50000 | 无 | 传统 NLP |
| Word2Vec | 100~300 | 词级语义 | 词相似度、类比推理 |
| BERT Embedding | 768 | 上下文语义 | 句子理解、问答 |
| OpenAI text-embedding-3 | 1536~3072 | 深层语义 | RAG、语义搜索 |
---
## 2. 相似度计算:向量之间有多"近"?
有了向量表示,下一个问题自然是:**怎么衡量两个向量有多相似?** 这就像在地图上衡量两个城市有多近——你可以量直线距离,也可以看方向是否一致。
<VectorSimilarityDemo />
::: tip 两种核心度量
- **余弦相似度(Cosine Similarity**:衡量两个向量的**方向**是否一致,值域 [-1, 1]。1 表示方向完全相同,0 表示正交(无关),-1 表示完全相反。文本语义比较的首选,因为它不受向量长度影响。
- **欧氏距离(Euclidean Distance**:衡量两个向量端点之间的**直线距离**,值域 [0, ∞)。0 表示完全重合,值越大越不相似。适合需要考虑"绝对大小"的场景。
:::
| 度量方式 | 公式直觉 | 值域 | 适用场景 |
|---------|---------|------|---------|
| 余弦相似度 | 看方向,忽略长度 | [-1, 1] | 文本语义搜索、推荐系统 |
| 欧氏距离 | 看端点直线距离 | [0, ∞) | 图像特征、聚类分析 |
| 点积 | 方向 × 长度 | (-∞, +∞) | 归一化向量的快速计算 |
| 曼哈顿距离 | 沿坐标轴走的距离 | [0, ∞) | 高维稀疏向量 |
---
## 3. 向量索引:如何在百万向量中毫秒检索?
假设你有 100 万条文档,每条都转成了 1536 维的向量。用户提了一个问题,你需要找到最相似的 10 条。最直接的方法是逐一计算相似度——但这意味着要做 100 万次 1536 维的向量运算,太慢了。
这就是**向量索引**要解决的问题:**用空间换时间,通过预处理建立索引结构,让检索速度从 O(n) 降到近似 O(log n)**。
<VectorIndexDemo />
::: tip 暴力搜索 vs 近似最近邻(ANN)
- **暴力搜索(Flat)**:逐一比较,100% 准确但速度慢。适合数据量小(< 10 万)的场景。
- **IVF(倒排文件索引)**:先把向量空间划分成若干区域(聚类),查询时只搜索最近的几个区域。像是把图书馆按主题分区,找书时只去相关区域。
- **HNSW(分层可导航小世界图)**:构建多层图结构,从粗粒度到细粒度逐层导航。像是先看世界地图定位到国家,再看省级地图,最后看街道地图。
- **PQ(乘积量化)**:把高维向量压缩成短编码,牺牲少量精度换取大幅内存节省。适合超大规模数据集。
:::
| 索引类型 | 构建速度 | 查询速度 | 召回率 | 内存占用 | 适用规模 |
|---------|---------|---------|-------|---------|---------|
| Flat(暴力) | 无需构建 | 慢 | 100% | 高 | < 10 万 |
| IVF | 中等 | 快 | 95%+ | 中 | 10 万~1000 万 |
| HNSW | 慢 | 很快 | 99%+ | 高 | 10 万~1000 万 |
| PQ | 中等 | 快 | 90%+ | 很低 | > 1000 万 |
| IVF-PQ | 中等 | 快 | 92%+ | 低 | > 1 亿 |
---
## 4. 向量数据库:专为向量而生的存储引擎
有了向量和索引算法,你需要一个地方来存储和管理它们。传统数据库(MySQL、PostgreSQL)擅长处理结构化数据,但对高维向量的相似度搜索力不从心。**向量数据库**就是为这个场景专门设计的。
<VectorDatabaseDemo />
::: tip 向量数据库的核心能力
1. **高效存储**:针对高维浮点向量优化的存储格式
2. **ANN 检索**:内置多种近似最近邻索引算法(HNSW、IVF 等)
3. **元数据过滤**:支持在向量搜索的同时按标签、时间等条件过滤
4. **实时更新**:支持动态增删改向量,无需重建整个索引
5. **水平扩展**:分布式架构支持亿级向量规模
:::
| 数据库 | 类型 | 特点 | 适用场景 |
|-------|------|------|---------|
| Pinecone | 全托管云服务 | 零运维、开箱即用 | 快速原型、中小规模生产 |
| Milvus | 开源分布式 | 高性能、可扩展 | 大规模生产环境 |
| Chroma | 开源轻量 | 嵌入式、API 简洁 | 本地开发、小型项目 |
| Weaviate | 开源云原生 | 内置向量化、GraphQL | 需要自动向量化的场景 |
| Qdrant | 开源高性能 | Rust 实现、过滤强 | 需要复杂过滤的场景 |
| pgvector | PG 扩展 | 复用现有 PG 基础设施 | 已有 PostgreSQL 的团队 |
---
## 5. 端到端 Pipeline:从文本到检索的完整流程
理解了各个组件后,让我们把它们串起来,看看一个完整的向量检索系统是怎么工作的。
整个流程分为两条线:**离线写入**(把文档变成向量存起来)和**在线查询**(把问题变成向量去搜索)。
<EmbeddingPipelineDemo />
::: tip 离线写入流程
1. **文档加载**:从各种来源(PDF、网页、数据库)读取原始文本
2. **文本预处理**:清洗、去噪、标准化(去掉 HTML 标签、特殊字符等)
3. **文本分块**:按策略将长文本切分为合适大小的片段(200~500 tokens
4. **向量化**:调用嵌入模型(如 OpenAI text-embedding-3-small)将每个片段转为向量
5. **存入向量数据库**:将向量和原始文本、元数据一起写入数据库
:::
::: tip 在线查询流程
1. **接收查询**:用户输入自然语言问题
2. **查询向量化**:用同一个嵌入模型将问题转为向量
3. **相似度检索**:在向量数据库中搜索 Top-K 最相似的文档片段
4. **后处理**:重排序、去重、元数据过滤
5. **返回结果**:将最相关的文档片段返回给调用方(或交给 LLM 生成回答)
:::
| 环节 | 关键选择 | 推荐方案 |
|------|---------|---------|
| 嵌入模型 | 精度 vs 成本 vs 速度 | OpenAI text-embedding-3-small(性价比高) |
| 分块策略 | 粒度 vs 语义完整性 | 递归分块,200~500 tokens |
| 向量数据库 | 规模 vs 运维成本 | 小项目用 Chroma,生产用 Pinecone/Milvus |
| 相似度度量 | 语义 vs 精确 | 余弦相似度(文本场景首选) |
| Top-K 值 | 召回率 vs 噪音 | 先检索 20 条,重排序后取 Top 5 |
---
## 总结
Embedding 与向量检索是连接"人类语言"和"机器理解"的桥梁,也是 RAG、语义搜索、推荐系统等 AI 应用的基础设施。
回顾本章的关键要点:
1. **Embedding 的本质**:把文本映射到高维向量空间,让语义相似度变成空间距离
2. **相似度度量**:余弦相似度关注方向(适合文本),欧氏距离关注绝对距离
3. **索引是性能关键**:HNSW 和 IVF 让百万级向量的检索降到毫秒级
4. **向量数据库选型**:小项目用 Chroma/pgvector,生产环境用 Pinecone/Milvus
5. **端到端思维**:从文档加载到最终检索,每个环节的选择都会影响最终效果
## 延伸阅读
- [OpenAI Embeddings 文档](https://platform.openai.com/docs/guides/embeddings) - 官方嵌入模型使用指南
- [Pinecone Learning Center](https://www.pinecone.io/learn/) - 向量数据库和检索的系统教程
- [FAISS Wiki](https://github.com/facebookresearch/faiss/wiki) - Facebook 开源的向量检索库文档
- [Word2Vec 原始论文](https://arxiv.org/abs/1301.3781) - Embedding 时代的开山之作
- [MTEB 排行榜](https://huggingface.co/spaces/mteb/leaderboard) - 嵌入模型性能对比排行榜
@@ -1,3 +1,173 @@
# 模型微调与部署
> 待实现
::: tip 前言
**大模型很强,但它不懂你的业务。** GPT-4 能写诗、能编程,但它不知道你公司的产品术语、不了解你行业的专业规范。微调(Fine-tuning)就是让通用大模型"学会"你的专业知识的过程——就像给一个博学的通才做岗前培训,让它变成你的领域专家。
:::
**这篇文章会带你学什么?**
学完这章后,你将获得:
- **流程认知**:掌握从数据准备到模型上线的完整微调流水线
- **数据工程**:了解微调数据的格式要求和质量标准
- **高效微调**:理解 LoRA 等参数高效微调技术的原理和优势
- **模型压缩**:掌握量化技术如何让大模型在消费级硬件上运行
- **部署实践**:了解模型服务的主流架构和选型策略
| 章节 | 内容 | 核心概念 |
|-----|------|---------|
| **第 1 章** | 微调流水线 | 数据→训练→评估→部署 |
| **第 2 章** | 训练数据 | 数据格式、质量控制 |
| **第 3 章** | LoRA 微调 | 低秩适配、参数高效 |
| **第 4 章** | 模型量化 | FP16、INT8、INT4 |
| **第 5 章** | 模型部署 | 推理服务、API 网关 |
---
## 0. 全景图:为什么需要微调?
大语言模型的训练分为两个阶段:**预训练**和**微调**。预训练是在海量通用数据上学习语言能力,微调是在特定任务数据上学习专业能力。
打个比方:预训练像是上大学——学习通识知识,什么都懂一点;微调像是入职培训——针对具体岗位学习专业技能。
::: tip 什么时候需要微调?
- **特定输出格式**:需要模型始终以固定 JSON 格式输出
- **专业领域知识**:医疗、法律、金融等领域的专业术语和规范
- **语言风格迁移**:让模型用特定的语气、风格回答(如客服话术)
- **小众语言支持**:提升模型在特定语言上的表现
- **成本优化**:用小模型微调替代大模型调用,降低推理成本
:::
---
## 1. 微调流水线:从数据到上线的完整旅程
微调不是"把数据丢给模型就完事"。它是一个严谨的工程流程,每个环节都会影响最终效果。
<FinetuningPipelineDemo />
::: tip 微调的五个阶段
1. **数据准备**:收集、清洗、标注训练数据,这是最耗时也最关键的环节
2. **模型选择**:选择合适的基座模型(Base Model),如 Llama 3、Qwen、Mistral
3. **训练配置**:设置学习率、batch size、epoch 数等超参数
4. **训练执行**:在 GPU 上运行训练,监控 loss 曲线和评估指标
5. **评估上线**:在测试集上评估效果,通过后部署为 API 服务
:::
| 阶段 | 关键动作 | 常见陷阱 |
|------|---------|---------|
| 数据准备 | 清洗、去重、格式化 | 数据质量差导致模型"学坏" |
| 模型选择 | 评估基座模型能力 | 模型太大训练不动,太小效果差 |
| 训练配置 | 调整超参数 | 学习率过高导致灾难性遗忘 |
| 训练执行 | 监控 loss 和指标 | 过拟合、训练不收敛 |
| 评估上线 | A/B 测试、灰度发布 | 测试集泄漏导致评估虚高 |
---
## 2. 训练数据:微调效果的天花板
在微调中有一句老话:**"Garbage in, garbage out"**。训练数据的质量直接决定了微调效果的上限。100 条高质量数据的效果,往往好过 10000 条低质量数据。
<TrainingDataDemo />
::: tip 微调数据的三种常见格式
1. **指令格式(Instruction**:最常用的格式,包含 instruction(指令)、input(输入)、output(期望输出)三个字段。适合训练模型遵循指令。
2. **对话格式(Chat**:多轮对话形式,包含 system、user、assistant 角色的消息列表。适合训练聊天机器人。
3. **补全格式(Completion**:简单的 prompt-completion 对,适合文本生成、代码补全等场景。
:::
| 数据质量维度 | 说明 | 检查方法 |
|------------|------|---------|
| 准确性 | 答案必须正确无误 | 人工审核、专家校验 |
| 一致性 | 相似问题的回答风格一致 | 抽样对比检查 |
| 多样性 | 覆盖足够多的场景和变体 | 统计问题类型分布 |
| 去重 | 避免重复样本导致过拟合 | 文本去重、语义去重 |
| 数据量 | 通常 500~5000 条高质量数据即可 | 从少量开始,逐步增加 |
---
## 3. LoRA:用 1% 的参数实现 90% 的效果
全量微调(Full Fine-tuning)需要更新模型的所有参数——对于一个 70B 参数的模型,这意味着需要数百 GB 的显存和大量的 GPU 算力。对大多数团队来说,这不现实。
LoRALow-Rank Adaptation)提供了一个优雅的解决方案:**冻结原始模型参数,只训练一小组新增的低秩矩阵**。这些矩阵的参数量通常只有原模型的 0.1%~1%,但能达到接近全量微调的效果。
<LoRADemo />
::: tip LoRA 的核心思想
原始模型的权重矩阵 W 是一个巨大的矩阵(如 4096×4096)。LoRA 不直接修改 W,而是在旁边加一个"旁路"W' = W + BA,其中 B 和 A 是两个小矩阵(如 4096×8 和 8×4096)。训练时只更新 B 和 A,原始 W 保持不变。
- **秩(Rank)**:r 值越大,表达能力越强,但参数量也越多。通常 r=8~64 就够用
- **合并部署**:训练完成后,可以把 BA 合并回 W,推理时零额外开销
:::
| 微调方式 | 可训练参数 | 显存需求 | 训练速度 | 效果 |
|---------|-----------|---------|---------|------|
| 全量微调 | 100% | 极高 | 慢 | 最好 |
| LoRA | 0.1%~1% | 低 | 快 | 接近全量 |
| QLoRA | 0.1%~1% | 更低 | 中等 | 略低于 LoRA |
| Prompt Tuning | < 0.01% | 极低 | 很快 | 有限 |
---
## 4. 模型量化:让大模型"瘦身"
一个 70B 参数的模型,如果用 FP32(32 位浮点数)存储,需要 280GB 显存——没有几块顶级 GPU 根本跑不起来。量化(Quantization)技术通过降低数值精度来压缩模型体积,让大模型能在消费级硬件上运行。
<ModelQuantizationDemo />
::: tip 量化的核心权衡
量化本质上是**精度换空间**的权衡。FP32 → FP16 几乎无损,INT8 有轻微损失,INT4 会有明显但通常可接受的质量下降。关键是找到你场景下的最佳平衡点。
- **FP16(半精度)**:体积减半,质量几乎无损,是训练和推理的默认选择
- **INT8(8 位整数)**:体积再减半,质量损失很小,适合大多数推理场景
- **INT44 位整数)**:体积仅为 FP32 的 1/8,质量有一定损失,适合资源受限场景
:::
| 精度 | 每参数字节 | 70B 模型体积 | 质量损失 | 适用场景 |
|------|-----------|-------------|---------|---------|
| FP32 | 4 字节 | ~280 GB | 无 | 训练基准 |
| FP16 | 2 字节 | ~140 GB | 几乎无 | 标准训练和推理 |
| INT8 | 1 字节 | ~70 GB | 很小 | 生产推理 |
| INT4 | 0.5 字节 | ~35 GB | 可接受 | 边缘设备、本地部署 |
---
## 5. 模型部署:从实验室到生产环境
模型训练好了,量化压缩了,最后一步是把它部署成可供调用的服务。模型部署不只是"把模型跑起来",还涉及并发处理、负载均衡、成本控制等工程问题。
<ModelServingDemo />
::: tip 三种主流部署方案
1. **API 服务商**:直接使用 OpenAI、Anthropic 等厂商的 API。零运维,按 token 付费,适合快速验证和中小规模使用。
2. **自托管推理服务**:用 vLLM、TGI 等框架在自己的 GPU 服务器上部署。成本可控,数据不出域,适合有隐私要求或大规模调用的场景。
3. **Serverless 推理**:使用 AWS SageMaker、Replicate 等平台,按请求付费,自动扩缩容。适合流量波动大的场景。
:::
| 部署方案 | 成本模型 | 延迟 | 运维复杂度 | 适用场景 |
|---------|---------|------|-----------|---------|
| API 服务商 | 按 token 计费 | 中等 | 零 | 快速原型、中小规模 |
| vLLM 自部署 | GPU 租赁费用 | 低 | 高 | 大规模、隐私敏感 |
| Serverless | 按请求计费 | 冷启动较高 | 低 | 流量波动大 |
| 边缘部署 | 硬件一次性投入 | 极低 | 中 | 离线场景、IoT |
---
## 总结
模型微调与部署是让大模型从"通用工具"变成"专业助手"的关键环节。从数据准备到模型上线,每一步都需要工程化的思维和实践。
回顾本章的关键要点:
1. **微调是岗前培训**:让通用模型学会特定领域的知识和行为模式
2. **数据质量决定上限**:100 条高质量数据胜过 10000 条低质量数据
3. **LoRA 是效率之王**:用不到 1% 的参数实现接近全量微调的效果
4. **量化是部署利器**:INT4 量化让 70B 模型在单卡上运行成为可能
5. **部署方案因地制宜**:快速验证用 API,大规模用自部署,波动大用 Serverless
## 延伸阅读
- [Hugging Face PEFT 文档](https://huggingface.co/docs/peft) - 参数高效微调库官方文档
- [vLLM 文档](https://docs.vllm.ai/) - 高性能 LLM 推理引擎
- [Unsloth](https://github.com/unslothai/unsloth) - 2x 加速的 LoRA 微调框架
- [GGUF 格式说明](https://github.com/ggerganov/ggml/blob/master/docs/gguf.md) - llama.cpp 使用的量化模型格式
- [OpenAI Fine-tuning Guide](https://platform.openai.com/docs/guides/fine-tuning) - OpenAI 官方微调指南
@@ -1,3 +1,161 @@
# RAG 架构
# RAG:检索增强生成
> 待实现
::: tip 前言
**为什么 ChatGPT 有时候会"一本正经地胡说八道"?** 大语言模型的知识来自训练数据,但训练数据有截止日期,也不包含你公司的内部文档。RAGRetrieval-Augmented Generation,检索增强生成)就是解决这个问题的核心技术——让 AI 在回答之前,先去"查资料"。
:::
**这篇文章会带你学什么?**
学完这章后,你将获得:
- **核心概念理解**:明白 RAG 是什么、为什么需要它,以及它如何解决大模型的"幻觉"问题
- **完整流程认知**:掌握从文档加载、分块、向量化到检索、生成的端到端流程
- **技术选型能力**:了解不同分块策略、检索方法的优劣,能根据场景做出选择
- **架构演进视角**:理解 RAG 从 Naive 到 Advanced 再到 Modular 的演进路线
- **实践决策能力**:知道什么时候该用 RAG、什么时候该用微调
| 章节 | 内容 | 核心概念 |
|-----|------|---------|
| **第 1 章** | RAG 基础流程 | 索引、检索、生成三阶段 |
| **第 2 章** | 文本分块策略 | 固定分块、语义分块、递归分块 |
| **第 3 章** | 检索技术 | 向量检索、关键词检索、混合检索 |
| **第 4 章** | 架构演进 | Naive RAG → Advanced RAG → Modular RAG |
| **第 5 章** | RAG vs 微调 | 两种方案的适用场景对比 |
---
## 0. 全景图:为什么大模型需要"查资料"?
想象你是一个博学的教授,读过无数书籍。但如果有人问你"昨天公司的销售数据是多少",你肯定答不上来——因为这些信息不在你读过的书里。
大语言模型面临的就是同样的困境:
- **知识有截止日期**:GPT-4 的训练数据截止到某个时间点,之后发生的事它不知道
- **缺乏私有知识**:你公司的内部文档、产品手册、客户数据,模型从未见过
- **容易产生幻觉**:当模型不确定答案时,它倾向于"编造"一个看起来合理的回答
::: tip RAG 的核心思想
RAG 的解决方案非常直觉:**在让模型回答之前,先帮它找到相关的参考资料**。就像开卷考试——你不需要记住所有知识,只需要知道去哪里找、怎么找。
RAG = 检索(Retrieval+ 增强(Augmented+ 生成(Generation
:::
---
## 1. RAG 基础流程:索引、检索、生成
RAG 的工作流程可以分为两个阶段:**离线索引**和**在线查询**。
离线阶段就像图书馆的编目工作——把所有书籍分类、编号、上架,方便日后查找。在线阶段则是读者来图书馆查资料的过程——根据问题找到相关书籍,然后综合信息给出回答。
<RAGPipelineDemo />
::: tip 三个核心阶段
1. **索引阶段(Indexing**:将原始文档加载、清洗、分块,然后通过嵌入模型转化为向量,存入向量数据库。这是一次性的准备工作。
2. **检索阶段(Retrieval**:用户提问时,将问题也转化为向量,在向量数据库中搜索最相似的文档片段。
3. **生成阶段(Generation**:将检索到的文档片段和用户问题一起拼接为 Prompt,交给大模型生成最终回答。
:::
| 阶段 | 输入 | 输出 | 关键技术 |
|------|------|------|---------|
| 索引 | 原始文档 | 向量数据库 | 文本分块、嵌入模型 |
| 检索 | 用户问题 | Top-K 文档片段 | 向量相似度、重排序 |
| 生成 | 问题 + 上下文 | 最终回答 | Prompt 工程、LLM |
---
## 2. 文本分块:把大象装进冰箱
文本分块是 RAG 中最容易被忽视、却对效果影响最大的环节。为什么需要分块?因为大模型的上下文窗口有限,我们不可能把整本书塞进去。更重要的是,**分块的质量直接决定了检索的质量**。
想象你在图书馆找一本书的某个知识点。如果整本书是一个"块",检索到了也没用——你还是得翻遍全书。但如果按章节甚至段落分块,就能精准定位到你需要的内容。
<ChunkingStrategyDemo />
::: tip 分块策略的选择
- **固定大小分块**:按字符数或 token 数切分,简单粗暴但可能切断语义
- **递归分块**:先按段落分,段落太长再按句子分,保持语义完整性
- **语义分块**:用嵌入模型判断语义边界,相似度突变处切分
- **文档结构分块**:利用 Markdown 标题、HTML 标签等结构信息分块
没有"最好"的分块策略,只有最适合你数据的策略。一般建议从递归分块开始,chunk 大小 200-500 tokensoverlap 10-20%。
:::
---
## 3. 检索技术:如何找到最相关的内容?
分块完成后,下一个关键问题是:**用户提了一个问题,怎么从成千上万个文档片段中找到最相关的那几个?**
这就像在一个巨大的图书馆里找书。你可以按书名关键词搜索(关键词检索),也可以描述你想要的内容让图书管理员帮你找(语义检索),最好的方式是两者结合(混合检索)。
<RetrievalDemo />
| 检索方式 | 原理 | 优势 | 劣势 |
|---------|------|------|------|
| 关键词检索(BM25) | 基于词频和逆文档频率 | 精确匹配、速度快 | 无法理解语义、同义词失效 |
| 向量检索 | 基于嵌入向量的余弦相似度 | 理解语义、支持模糊匹配 | 对专有名词不敏感 |
| 混合检索 | 融合关键词和向量检索结果 | 兼顾精确和语义 | 需要调权重、复杂度高 |
::: tip 重排序(Reranking
检索到候选文档后,通常还需要一步"重排序"。初始检索追求召回率(尽量不遗漏),重排序追求精确率(把最相关的排到最前面)。常用的重排序模型有 Cohere Rerank、BGE Reranker 等,它们使用交叉编码器对 query-document 对进行精细打分。
:::
---
## 4. 架构演进:从简单到智能
RAG 技术在短短两年内经历了三代演进,每一代都在解决上一代的痛点。
<RAGArchitectureDemo />
::: tip 三代 RAG 架构对比
- **Naive RAG2023**:最基础的"索引→检索→生成"流程,实现简单但效果有限。问题包括:检索质量不稳定、无法处理复杂查询、容易引入噪音上下文。
- **Advanced RAG2024**:在 Naive RAG 基础上增加了查询改写、混合检索、重排序、上下文压缩等优化环节,显著提升了检索精度和生成质量。
- **Modular RAG2025**:将 RAG 拆解为可插拔的模块,支持路由判断、自适应检索、自我反思等高级能力。可根据查询类型动态选择最优处理流程。
:::
---
## 5. RAG vs 微调:该选哪个?
当你想让大模型掌握特定领域的知识时,通常有两条路:RAG 和微调(Fine-tuning)。它们不是互斥的,而是互补的。
打个比方:**微调像是让学生上培训班**,把知识内化到大脑里;**RAG 像是给学生发参考书**,考试时可以翻阅。两种方式各有优劣,关键看你的具体需求。
<RAGvsFineTuningDemo />
| 维度 | RAG | 微调 |
|------|-----|------|
| 知识更新 | 实时更新,改文档即可 | 需要重新训练 |
| 成本 | 低(无需 GPU 训练) | 高(需要训练资源) |
| 可解释性 | 高(可追溯来源) | 低(知识内化在权重中) |
| 适用场景 | 知识库问答、文档检索 | 风格迁移、特定任务优化 |
| 幻觉控制 | 较好(有参考依据) | 一般(仍可能幻觉) |
::: tip 实践建议
大多数场景下,**先试 RAG**。RAG 的优势在于:不需要训练、知识可实时更新、回答可追溯来源。只有当你需要改变模型的"行为模式"(比如输出格式、语言风格、推理方式)时,才考虑微调。最强的方案往往是 **RAG + 微调** 的组合。
:::
---
## 总结
RAG 是当前让大模型"落地"最实用的技术之一。它的核心价值在于:让模型的回答有据可查、知识可实时更新、幻觉可有效控制。
回顾本章的关键要点:
1. **RAG 解决的核心问题**:大模型知识过时、缺乏私有数据、容易幻觉
2. **三阶段流程**:索引(离线准备)→ 检索(在线查找)→ 生成(综合回答)
3. **分块是基础**:分块质量直接决定检索质量,选择合适的分块策略至关重要
4. **检索是关键**:混合检索 + 重排序是目前效果最好的组合
5. **架构在演进**:从 Naive RAG 到 Modular RAG,系统越来越智能和灵活
6. **RAG 和微调互补**:大多数场景先试 RAG,需要改变模型行为时再考虑微调
## 延伸阅读
- [LangChain RAG 教程](https://python.langchain.com/docs/tutorials/rag/) - 最流行的 RAG 框架实战指南
- [LlamaIndex 文档](https://docs.llamaindex.ai/) - 专注于 RAG 的框架,提供丰富的数据连接器
- [RAG Survey 论文](https://arxiv.org/abs/2312.10997) - 全面的 RAG 技术综述
- [Chunking Strategies](https://www.pinecone.io/learn/chunking-strategies/) - Pinecone 的分块策略详解
- [向量数据库对比](https://superlinked.com/vector-db-comparison) - 主流向量数据库的功能对比
@@ -214,7 +214,55 @@ function getPayAmount(employee) {
---
## 5. 总结
## 5. AI 助力:用大模型提升代码质量
大模型在代码质量领域已经非常实用,它可以充当你的"24 小时在线的代码审查员"。
### 5.1 识别代码坏味道
> **提示词**
> ```
> 请审查以下代码,识别其中的代码坏味道(Code Smell),包括但不限于:
> 过长函数、魔法数字、重复代码、过深嵌套、过长参数列表。
> 对每个问题给出具体位置、问题描述和改进建议。
>
> [粘贴你的代码]
> ```
### 5.2 自动重构
> **提示词**
> ```
> 请对以下代码进行重构,要求:
> 1. 不改变外部行为
> 2. 使用提炼函数、卫语句替代嵌套等手法
> 3. 改善命名,消除魔法数字
> 4. 解释每一步重构的理由
>
> [粘贴你的代码]
> ```
### 5.3 模拟 Code Review
> **提示词**
> ```
> 请以资深开发者的视角审查这段代码,从以下维度给出反馈:
> - 正确性:逻辑是否有 Bug?边界条件是否处理?
> - 可读性:命名是否清晰?结构是否易懂?
> - 性能:是否有明显的性能问题?
> - 安全性:是否有注入或数据泄露风险?
> 用"建议"而非"命令"的语气,给出改进方案。
>
> [粘贴你的代码]
> ```
::: tip AI 使用建议
AI 的重构建议需要你自己验证——跑测试确认行为没变。把 AI 当作"提建议的同事",而不是"无条件信任的权威"。
:::
---
## 6. 总结
回顾这一路,我们从识别问题到解决问题,建立了一套完整的代码质量改进体系:
@@ -207,7 +207,55 @@ calculatePrice(100, 'svip') // 60
---
## 5. 总结
## 5. AI 助力:用大模型学习和应用设计模式
大模型可以帮你识别代码中适合使用设计模式的场景,并给出具体的重构方案。
### 5.1 识别适用模式
> **提示词**
> ```
> 分析以下代码,判断是否存在可以用设计模式改进的地方。
> 如果有,请说明:
> 1. 当前代码的问题
> 2. 推荐使用哪种设计模式
> 3. 重构后的代码示例
> 4. 为什么这个模式适合这个场景
>
> [粘贴你的代码]
> ```
### 5.2 用具体场景学习模式
> **提示词**
> ```
> 用一个"外卖点餐系统"的真实场景,分别演示以下设计模式的应用:
> - 工厂模式:创建不同类型的订单
> - 观察者模式:订单状态变化通知
> - 策略模式:不同的配送费计算规则
>
> 用 JavaScript 代码示例,每个模式先展示不用模式的问题,
> 再展示用模式后的改进。
> ```
### 5.3 判断是否过度设计
> **提示词**
> ```
> 审查以下代码,判断是否存在过度设计的问题。
> 是否有不必要的抽象、用不到的设计模式、或过早的优化?
> 如果有,请建议如何简化,遵循 KISS 原则。
>
> [粘贴你的代码]
> ```
::: tip AI 使用建议
让 AI 用你熟悉的业务场景来解释设计模式,比看抽象的 UML 图有效得多。但记住:AI 可能倾向于推荐更复杂的方案,你需要自己判断是否真的需要。
:::
---
## 6. 总结
1. **创建型模式**:解决"如何创建对象"的问题,让创建过程更灵活
2. **结构型模式**:解决"如何组织代码"的问题,让结构更清晰
@@ -142,7 +142,55 @@ git commit -m "fix: 修复 README 中的安装命令拼写错误"
---
## 5. 总结
## 5. AI 助力:用大模型加速开源贡献
大模型可以帮你快速理解陌生代码库、写出高质量的 PR 描述、甚至辅助 Code Review。
### 5.1 快速理解陌生代码库
> **提示词**
> ```
> 我刚 clone 了一个开源项目,请帮我分析以下目录结构,
> 说明每个目录/文件的职责,以及代码的整体架构和数据流向。
> 我想修复一个登录相关的 Bug,应该从哪里开始看?
>
> [粘贴 tree 命令输出或目录结构]
> ```
### 5.2 写 PR 描述
> **提示词**
> ```
> 根据以下 git diff,帮我写一份 Pull Request 描述,包括:
> - 标题(简洁,说明改了什么)
> - 改动说明(为什么改、改了什么)
> - 测试方法(如何验证改动正确)
> - 关联 Issue(如果有)
> 用英文撰写,语气专业友好。
>
> [粘贴 git diff 输出]
> ```
### 5.3 辅助翻译文档
> **提示词**
> ```
> 将以下中文技术文档翻译为英文,要求:
> 1. 技术术语使用业界通用的英文表达
> 2. 代码注释和变量名不翻译
> 3. 保持 Markdown 格式不变
> 4. 语气自然流畅,不要机翻感
>
> [粘贴中文文档]
> ```
::: tip AI 使用建议
用 AI 写 PR 描述时,确保你自己理解了每一行改动。审查者可能会问你为什么这么改——如果你答不上来,说明你还没真正理解。
:::
---
## 6. 总结
1. **流程**Fork → Branch → Commit → PR → Review → Merge
2. **许可证**:MIT 最宽松,GPL 最严格,根据需求选择
@@ -148,7 +148,55 @@ Strict-Transport-Security: max-age=31536000
---
## 4. 总结
## 4. AI 助力:用大模型提升安全防护
大模型可以充当你的"安全顾问",帮你审计代码漏洞、生成安全方案。
### 4.1 代码安全审计
> **提示词**
> ```
> 请对以下代码进行安全审计,检查是否存在:
> - XSS 漏洞(未转义的用户输入)
> - SQL 注入(字符串拼接查询)
> - CSRF 风险(缺少 Token 验证)
> - 敏感数据泄露(硬编码密钥、明文密码)
> 对每个问题给出风险等级、具体位置和修复方案。
>
> [粘贴你的代码]
> ```
### 4.2 生成安全配置
> **提示词**
> ```
> 我的项目使用 Express.js + PostgreSQL,即将部署上线。
> 请生成一份完整的安全配置清单,包括:
> - HTTP 安全头配置代码
> - CORS 配置
> - 数据库连接的安全设置
> - 环境变量管理方案
> 给出可直接使用的代码片段。
> ```
### 4.3 解释漏洞原理
> **提示词**
> ```
> 用一个具体的例子,解释 CSRF 攻击的完整流程:
> 1. 攻击者如何构造恶意页面
> 2. 为什么浏览器会自动携带 Cookie
> 3. 服务端如何用 CSRF Token 防御
> 用代码演示攻击和防御的完整过程。
> ```
::: tip AI 使用建议
AI 的安全审计不能替代专业的安全测试。把它当作第一道筛查,关键系统仍需专业安全团队审计。
:::
---
## 5. 总结
1. **安全思维**:永不信任外部输入,最小权限,纵深防御
2. **常见攻击**XSS、SQL 注入、CSRF 是最高频的 Web 安全威胁
@@ -151,7 +151,58 @@ for (let i = items.length - 1; i >= 0; i--) { ... }
---
## 5. 总结
## 5. AI 助力:用大模型提升文档质量
大模型在技术写作领域几乎是"天赋异禀"——生成文档、改善表达、翻译内容都是它的强项。
### 5.1 生成 API 文档
> **提示词**
> ```
> 根据以下 Express 路由代码,生成完整的 API 文档,包括:
> - 端点路径和方法
> - 请求参数(路径参数、查询参数、请求体)及类型
> - 成功和错误的响应示例
> - 使用 curl 的调用示例
>
> [粘贴你的路由代码]
> ```
### 5.2 改善技术写作
> **提示词**
> ```
> 请改善以下技术文档的表达,要求:
> 1. 语言简洁清晰,去掉冗余表述
> 2. 用主动语态替代被动语态
> 3. 专业术语保持准确
> 4. 添加必要的代码示例
> 保持原意不变,只改善表达质量。
>
> [粘贴你的文档内容]
> ```
### 5.3 生成 README
> **提示词**
> ```
> 根据以下项目信息,生成一份高质量的 README.md:
> - 项目名称:[名称]
> - 一句话描述:[描述]
> - 技术栈:[列出]
> - 核心功能:[列出]
>
> 要求包含:项目简介、快速开始、功能特性、
> 安装步骤(含代码)、使用示例、贡献指南、许可证。
> ```
::: tip AI 使用建议
AI 生成的文档要检查技术细节是否准确——它可能编造不存在的 API 参数或错误的返回值。始终对照实际代码验证。
:::
---
## 6. 总结
1. **类型匹配**:不同文档有不同的结构和写法
2. **清晰优先**:具体、准确、面向读者
@@ -119,7 +119,55 @@
---
## 4. 总结
## 4. AI 助力:用大模型辅助技术选型
大模型可以帮你快速调研技术方案、对比优劣、生成决策报告。
### 4.1 技术方案对比
> **提示词**
> ```
> 我需要为一个电商项目选择数据库,候选方案:
> MySQL、PostgreSQL、MongoDB。
> 项目特点:读多写少、需要复杂查询、数据量预计千万级。
>
> 请从以下维度对比三个方案:
> 性能、生态、学习曲线、运维成本、扩展性。
> 用表格形式呈现,并给出最终推荐和理由。
> ```
### 4.2 生成架构决策记录(ADR)
> **提示词**
> ```
> 帮我写一份架构决策记录(ADR),格式如下:
> - 标题:选择 Vue 3 作为前端框架
> - 背景:[项目背景和需求]
> - 候选方案:React, Vue 3, Svelte
> - 决策:Vue 3
> - 理由:[基于团队能力、生态、性能等维度]
> - 后果:[选择后的影响和风险]
> ```
### 4.3 调研新技术
> **提示词**
> ```
> 我在考虑是否在项目中引入 Bun 替代 Node.js,请帮我分析:
> 1. Bun 相比 Node.js 的核心优势和劣势
> 2. 当前生态成熟度(npm 兼容性、主流框架支持)
> 3. 生产环境使用的风险点
> 4. 适合和不适合使用 Bun 的场景
> 给出客观评估,不要只说优点。
> ```
::: tip AI 使用建议
AI 的知识有时效性——它可能不了解最新版本的变化。对于快速迭代的技术,用 AI 做初步调研后,务必查阅官方文档确认最新信息。
:::
---
## 5. 总结
1. **技术雷达**:了解技术的成熟度,区分采纳/试验/评估/暂缓
2. **选型维度**:团队能力 > 社区生态 > 性能需求 > 维护状态
@@ -149,7 +149,53 @@ TDD 适合逻辑密集的代码(算法、业务规则、数据转换),但
---
## 5. 总结
## 5. AI 助力:用大模型提升测试效率
大模型在测试领域的能力已经非常强大——它可以帮你生成测试用例、发现边界条件、甚至写出完整的测试代码。
### 5.1 生成单元测试
> **提示词**
> ```
> 请为以下函数编写单元测试,使用 Vitest 框架,要求:
> 1. 遵循 AAA 模式(Arrange-Act-Assert
> 2. 覆盖正常路径、边界条件和错误路径
> 3. 每个测试用例有清晰的中文描述
>
> [粘贴你的函数代码]
> ```
### 5.2 发现边界条件
> **提示词**
> ```
> 分析以下函数,列出所有可能的边界条件和极端输入场景,
> 包括:空值、零、负数、超大数、特殊字符、并发情况等。
> 对每个场景说明预期行为和可能的风险。
>
> [粘贴你的函数代码]
> ```
### 5.3 从需求生成测试(TDD 辅助)
> **提示词**
> ```
> 我要实现一个购物车模块,需求如下:
> - 添加商品、删除商品、修改数量
> - 自动计算总价(含折扣)
> - 库存不足时提示错误
>
> 请按照 TDD 思路,先写出测试用例(不写实现),
> 使用 Vitest,覆盖所有核心场景。
> ```
::: tip AI 使用建议
AI 生成的测试要检查断言是否有意义——避免 `expect(true).toBe(true)` 这种无效测试。好的测试应该在代码出错时真的能失败。
:::
---
## 6. 总结
1. **测试金字塔**:底层多、顶层少,平衡速度与真实度
2. **单元测试**:遵循 FIRST 原则和 AAA 模式,测试核心逻辑
+5
View File
@@ -8,6 +8,11 @@
从晶体管到操作系统,深入了解计算机如何工作:
<NavGrid>
<NavCard
href="/zh-cn/appendix/1-computer-fundamentals/vibe-coding-fullstack"
title="Vibe Coding 时代下的全栈开发"
description="AI 辅助时代,前端、后端、编程语言、全栈工程师的成长路径全景图"
/>
<NavCard
href="/zh-cn/appendix/1-computer-fundamentals/transistor-to-cpu"
title="从晶体管到 CPU"