+
+
+
+
+
+
+
+
+
+
+
+
+
+
🐧
+
Loading kernel...
+
+
+
+
+
+
+
+
+
+ {{ s.ok ? '●' : '○' }}
+ {{ s.name }}
+
+
+
+
+
+
+
+
+ {{ ic.icon }}
+ {{ ic.label }}
+
+
+
+
+ 09:57
+
+
+
+
-
-
{{ step.name }}
-
{{ step.desc }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 💡
+ {{ currentStage.analogy }}
@@ -17,66 +131,367 @@
diff --git a/docs/.vitepress/theme/components/appendix/computer-fundamentals/OSBootInteractiveDemo.vue b/docs/.vitepress/theme/components/appendix/computer-fundamentals/OSBootInteractiveDemo.vue
new file mode 100644
index 0000000..534793a
--- /dev/null
+++ b/docs/.vitepress/theme/components/appendix/computer-fundamentals/OSBootInteractiveDemo.vue
@@ -0,0 +1,763 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
🖥️
+
操作系统
+
管理硬件和软件资源
计算机的"大管家"
+
+
+ {{ os.icon }}
+ {{ os.name }}
+
+
+
+
+
+
+
+
+
+ {{ i + 1 }}
+ {{ step }}
+
+
+
+
+
+
+
+
+
⚙️
+
{{ kernelName }}
+
+
+
+ {{ kernelProgress > (i + 1) * 20 ? '✓' : '○' }}
+ {{ m }}
+
+
+
+
+
+
+
+
+
+ {{ svc.icon }}
+ {{ svc.name }}
+ {{ svcProgress > i * 15 ? '●' : '○' }}
+
+
+
+
+
+
+
+
+
+
+ {{ ic.icon }}
+ {{ ic.label }}
+
+
+
+ 🪟
+
+ {{ app }}
+
+ {{ currentTime }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 💡
+ {{ currentStage.analogy }}
+
+
+
+
+
+
+
+
+
+ {{ os.icon }}
+ {{ os.name }}
+
+ {{ os.feature }}
+ {{ os.device }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/.vitepress/theme/components/appendix/file-storage/CDNAccelerationDemo.vue b/docs/.vitepress/theme/components/appendix/file-storage/CDNAccelerationDemo.vue
new file mode 100644
index 0000000..5a74c25
--- /dev/null
+++ b/docs/.vitepress/theme/components/appendix/file-storage/CDNAccelerationDemo.vue
@@ -0,0 +1,123 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ cdnEnabled ? '5ms' : '200ms' }}
+
+
+
+
+
+ 缓存未命中时回源
+
+
+
+
+
+
+
+
首字节时间 (TTFB)
+
+
{{ cdnEnabled ? '~30ms' : '~200ms' }}
+
+
+
下载 1MB 图片
+
+
{{ cdnEnabled ? '~50ms' : '~800ms' }}
+
+
+
+
+
+
+
+
diff --git a/docs/.vitepress/theme/components/appendix/file-storage/FileStorageTypeDemo.vue b/docs/.vitepress/theme/components/appendix/file-storage/FileStorageTypeDemo.vue
new file mode 100644
index 0000000..c72d1fe
--- /dev/null
+++ b/docs/.vitepress/theme/components/appendix/file-storage/FileStorageTypeDemo.vue
@@ -0,0 +1,114 @@
+
+
+
+
+
+
+
+
{{ t.icon }}
+
{{ t.name }}
+
+
+
+
+
{{ current.name }}
+
{{ current.desc }}
+
+
+
访问方式
+
{{ current.access }}
+
+
+
典型场景
+
{{ current.scenario }}
+
+
+
代表产品
+
{{ current.products }}
+
+
+
扩展性
+
{{ current.scalability }}
+
+
+
+
+
+
+
+
+
diff --git a/docs/.vitepress/theme/components/appendix/file-storage/FileUploadFlowDemo.vue b/docs/.vitepress/theme/components/appendix/file-storage/FileUploadFlowDemo.vue
new file mode 100644
index 0000000..1d393ed
--- /dev/null
+++ b/docs/.vitepress/theme/components/appendix/file-storage/FileUploadFlowDemo.vue
@@ -0,0 +1,135 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
{{ i + 1 }}
+
+
{{ step.title }}
+
{{ step.desc }}
+
{{ step.note }}
+
+
+
+
+
+
+
+
+ ⚠️ 服务端中转:文件经过你的服务器,占用带宽和内存,大文件容易超时
+
+
+ ✅ 客户端直传:文件直接上传到 OSS,服务器只负责签发凭证,高效且省资源
+
+
+
+
+
+
+
+
diff --git a/docs/.vitepress/theme/components/appendix/project-architecture/ArchitectureComparisonDemo.vue b/docs/.vitepress/theme/components/appendix/project-architecture/ArchitectureComparisonDemo.vue
new file mode 100644
index 0000000..9286e14
--- /dev/null
+++ b/docs/.vitepress/theme/components/appendix/project-architecture/ArchitectureComparisonDemo.vue
@@ -0,0 +1,551 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
{{ layer.duty }}
+
🌰 {{ layer.example }}
+
+
+ ↓
+ {{ layer.arrow }}
+
+
+
+
+
+
+
+
+
+
{{ layer.duty }}
+
🌰 {{ layer.example }}
+
+
+ ↓
+ {{ layer.arrow }}
+
+
+
+
+
+
+
+
+
+
+
+
📁 典型文件
+
+ {{ file }}
+
+
+
+
+
+
+
+
+ 💡
+ 核心思想:好的架构就像整理好的空间——前端像衣柜(按功能分类展示),后端像厨房(按流程分工协作)。点击上方层次查看详情!
+
+
+
+
+
+
+
diff --git a/docs/.vitepress/theme/components/appendix/rate-limiting/BackpressureDemo.vue b/docs/.vitepress/theme/components/appendix/rate-limiting/BackpressureDemo.vue
new file mode 100644
index 0000000..98e9871
--- /dev/null
+++ b/docs/.vitepress/theme/components/appendix/rate-limiting/BackpressureDemo.vue
@@ -0,0 +1,173 @@
+
+
+
+
+
+
+
+ 生产速率:
+
+ {{ produceRate }}/s
+
+
+ 消费速率:
+
+ {{ consumeRate }}/s
+
+
+
+
+
+
+
+
+
+
生产者
+
+ {{ produceRate }}/s
+
+
+
+
+
缓冲区 ({{ bufferSize }}/{{ maxBuffer }})
+
+
{{ statusText }}
+
+
+
+
消费者
+
{{ consumeRate }}/s
+
+
+
+
+
背压处理策略:
+
+
+
{{ s.name }}
+
{{ s.desc }}
+
{{ s.example }}
+
+
+
+
+
+
+
+
+
diff --git a/docs/.vitepress/theme/components/appendix/rate-limiting/RateLimitAlgorithmDemo.vue b/docs/.vitepress/theme/components/appendix/rate-limiting/RateLimitAlgorithmDemo.vue
new file mode 100644
index 0000000..2520728
--- /dev/null
+++ b/docs/.vitepress/theme/components/appendix/rate-limiting/RateLimitAlgorithmDemo.vue
@@ -0,0 +1,219 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 通过
+ {{ passed }}
+
+
+ 拒绝
+ {{ rejected }}
+
+
+ 剩余令牌
+ {{ tokens }}
+
+
+ 桶中排队
+ {{ bucketQueue }}
+
+
+ 窗口内请求
+ {{ windowCount }}
+
+
+
+
+
+ {{ log.time }}
+ {{ log.msg }}
+
+
+
+
+
+
{{ currentAlgo.label }}
+
{{ currentAlgo.desc }}
+
+
+
+
+
+
+
diff --git a/docs/.vitepress/theme/components/appendix/rate-limiting/RateLimiterDemo.vue b/docs/.vitepress/theme/components/appendix/rate-limiting/RateLimiterDemo.vue
new file mode 100644
index 0000000..63dbcdf
--- /dev/null
+++ b/docs/.vitepress/theme/components/appendix/rate-limiting/RateLimiterDemo.vue
@@ -0,0 +1,204 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 已发送
+ {{ totalSent }}
+
+
+ 通过
+ {{ passed }}
+
+
+ 拒绝
+ {{ rejected }}
+
+
+ 剩余令牌
+ {{ tokens }}
+
+
+
+
+
+ {{ req.status === 'pass' ? '✅' : '❌' }}
+ 请求 #{{ req.id }}
+ {{ req.time }}
+
+
+
+
+
+
{{ currentAlgo.label }}
+
{{ currentAlgo.desc }}
+
+
+
+
+
+
+
diff --git a/docs/.vitepress/theme/components/appendix/search-engines/InvertedIndexDemo.vue b/docs/.vitepress/theme/components/appendix/search-engines/InvertedIndexDemo.vue
new file mode 100644
index 0000000..08450d6
--- /dev/null
+++ b/docs/.vitepress/theme/components/appendix/search-engines/InvertedIndexDemo.vue
@@ -0,0 +1,145 @@
+
+
+
+
+
+
+
+
+
+
+
+
原始文档
+
+ Doc {{ doc.id }}
+ {{ doc.text }}
+
+
+
+
+
倒排索引表
+
+
+ {{ word }}
+ →
+
+ [{{ id }}]
+
+
+
+
+
+
+
+ 命中文档:{{ matchedDocs.map(id => 'Doc ' + id).join('、') }}
+
+
+ 未找到匹配文档
+
+
+
+
+
+
+
diff --git a/docs/.vitepress/theme/components/appendix/search-engines/SearchRelevanceDemo.vue b/docs/.vitepress/theme/components/appendix/search-engines/SearchRelevanceDemo.vue
new file mode 100644
index 0000000..62a55cb
--- /dev/null
+++ b/docs/.vitepress/theme/components/appendix/search-engines/SearchRelevanceDemo.vue
@@ -0,0 +1,126 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
#{{ i + 1 }}
+
+
{{ r.title }}
+
{{ r.snippet }}
+
+
+
+
{{ r.score.toFixed(2) }}
+
+
+
+
+
+
BM25 评分因子
+
+
+
词频 (TF)
+
关键词在文档中出现的次数越多,得分越高(但有上限)
+
+
+
逆文档频率 (IDF)
+
越稀有的词权重越高,"的"这种常见词权重很低
+
+
+
文档长度
+
较短文档中出现关键词,比长文档中出现更有意义
+
+
+
+
+
+
+
+
+
diff --git a/docs/.vitepress/theme/index.js b/docs/.vitepress/theme/index.js
index 2f33b83..5d905e4 100644
--- a/docs/.vitepress/theme/index.js
+++ b/docs/.vitepress/theme/index.js
@@ -206,7 +206,11 @@ import LearningStrategyDemo from './components/appendix/computer-fundamentals/Le
import VibeCodingFlowDemo from './components/appendix/computer-fundamentals/VibeCodingFlowDemo.vue'
import PowerOnDemo from './components/appendix/computer-fundamentals/PowerOnDemo.vue'
import BootProcessDemo from './components/appendix/computer-fundamentals/BootProcessDemo.vue'
+import BiosUefiDemo from './components/appendix/computer-fundamentals/BiosUefiDemo.vue'
+import BiosUefiInteractiveDemo from './components/appendix/computer-fundamentals/BiosUefiInteractiveDemo.vue'
+import AppLaunchDemo from './components/appendix/computer-fundamentals/AppLaunchDemo.vue'
import DesktopDemo from './components/appendix/computer-fundamentals/DesktopDemo.vue'
+import OSBootInteractiveDemo from './components/appendix/computer-fundamentals/OSBootInteractiveDemo.vue'
import BrowserArchitectureDemo from './components/appendix/computer-fundamentals/BrowserArchitectureDemo.vue'
import URLRequestDemo from './components/appendix/computer-fundamentals/URLRequestDemo.vue'
import RenderingDemo from './components/appendix/computer-fundamentals/RenderingDemo.vue'
@@ -758,6 +762,28 @@ import IncidentCommandDemo from './components/appendix/incident-response/Inciden
import AlertEscalationDemo from './components/appendix/incident-response/AlertEscalationDemo.vue'
import PostmortemDemo from './components/appendix/incident-response/PostmortemDemo.vue'
+// Async Task Queues Components
+import AsyncTaskFlowDemo from './components/appendix/async-task-queues/AsyncTaskFlowDemo.vue'
+import TaskWorkerDemo from './components/appendix/async-task-queues/TaskWorkerDemo.vue'
+import TaskRetryDemo from './components/appendix/async-task-queues/TaskRetryDemo.vue'
+import AsyncComparisonDemo from './components/appendix/async-task-queues/AsyncComparisonDemo.vue'
+
+// File Storage Components
+import FileStorageTypeDemo from './components/appendix/file-storage/FileStorageTypeDemo.vue'
+import FileUploadFlowDemo from './components/appendix/file-storage/FileUploadFlowDemo.vue'
+import CDNAccelerationDemo from './components/appendix/file-storage/CDNAccelerationDemo.vue'
+
+// Rate Limiting Components
+import RateLimitAlgorithmDemo from './components/appendix/rate-limiting/RateLimitAlgorithmDemo.vue'
+import BackpressureDemo from './components/appendix/rate-limiting/BackpressureDemo.vue'
+
+// Search Engines Components Registration
+import InvertedIndexDemo from './components/appendix/search-engines/InvertedIndexDemo.vue'
+import SearchRelevanceDemo from './components/appendix/search-engines/SearchRelevanceDemo.vue'
+
+// Project Architecture Components
+import ArchitectureComparisonDemo from './components/appendix/project-architecture/ArchitectureComparisonDemo.vue'
+
export default {
extends: DefaultTheme,
Layout,
@@ -969,7 +995,11 @@ export default {
app.component('VibeCodingFlowDemo', VibeCodingFlowDemo)
app.component('PowerOnDemo', PowerOnDemo)
app.component('BootProcessDemo', BootProcessDemo)
+ app.component('BiosUefiDemo', BiosUefiDemo)
+ app.component('BiosUefiInteractiveDemo', BiosUefiInteractiveDemo)
+ app.component('AppLaunchDemo', AppLaunchDemo)
app.component('DesktopDemo', DesktopDemo)
+ app.component('OSBootInteractiveDemo', OSBootInteractiveDemo)
app.component('BrowserArchitectureDemo', BrowserArchitectureDemo)
app.component('URLRequestDemo', URLRequestDemo)
app.component('RenderingDemo', RenderingDemo)
@@ -1533,6 +1563,28 @@ export default {
app.component('IncidentCommandDemo', IncidentCommandDemo)
app.component('AlertEscalationDemo', AlertEscalationDemo)
app.component('PostmortemDemo', PostmortemDemo)
+
+ // Async Task Queues Components Registration
+ app.component('AsyncTaskFlowDemo', AsyncTaskFlowDemo)
+ app.component('TaskWorkerDemo', TaskWorkerDemo)
+ app.component('TaskRetryDemo', TaskRetryDemo)
+ app.component('AsyncComparisonDemo', AsyncComparisonDemo)
+
+ // File Storage Components Registration
+ app.component('FileStorageTypeDemo', FileStorageTypeDemo)
+ app.component('FileUploadFlowDemo', FileUploadFlowDemo)
+ app.component('CDNAccelerationDemo', CDNAccelerationDemo)
+
+ // Rate Limiting Components Registration
+ app.component('RateLimitAlgorithmDemo', RateLimitAlgorithmDemo)
+ app.component('BackpressureDemo', BackpressureDemo)
+
+ // Search Engines Components Registration
+ app.component('InvertedIndexDemo', InvertedIndexDemo)
+ app.component('SearchRelevanceDemo', SearchRelevanceDemo)
+
+ // Project Architecture Components Registration
+ app.component('ArchitectureComparisonDemo', ArchitectureComparisonDemo)
},
setup() {
const route = useRoute()
diff --git a/docs/zh-cn/appendix/1-computer-fundamentals/algorithm-thinking.md b/docs/zh-cn/appendix/1-computer-fundamentals/algorithm-thinking.md
index c035d7d..b036cf2 100644
--- a/docs/zh-cn/appendix/1-computer-fundamentals/algorithm-thinking.md
+++ b/docs/zh-cn/appendix/1-computer-fundamentals/algorithm-thinking.md
@@ -69,6 +69,11 @@
**生活类比**:猜数字游戏。我想一个 1-100 的数,你每次猜中间,我告诉你大了还是小了。最多猜 7 次就能猜中(因为 2⁷ = 128 > 100)。
:::
+👇 **动手试试看**:
+下面这个演示展示了二分查找的工作原理,你可以选择顺序查找或二分查找来对比:
+
+
+
### 1.2 为什么二分查找这么快?
| 数据量 | 线性查找 | 二分查找 |
@@ -78,7 +83,17 @@
| 1,000,000 | 1,000,000 次 | 20 次 |
| 1,000,000,000 | 1,000,000,000 次 | 30 次 |
-::: tip 💡 对数增长的威力
+::: tip � 逐行解读这张表
+**第一列(数据量)**:要查找的数据有多少。可以看到数据量从 100 增长到 10 亿(扩大了 1000 万倍!)
+
+**第二列(线性查找)**:最"笨"的方法,从第一个开始一个一个找。查找次数等于数据量,数据量越大,查找次数越多。
+
+**第三列(二分查找)**:聪明的方法,每次排除一半。查找次数只和数据量的对数有关,即使 10 亿数据也只需要 30 次!
+
+**对比结论**:当数据量达到 100 万时,线性查找需要 100 万次,二分查找只需要 20 次——差距达 5 万倍!
+:::
+
+::: tip � 对数增长的威力
二分查找的时间复杂度是 O(log n),这意味着:
- 10 亿数据,最多查找 30 次
@@ -102,6 +117,20 @@
| **归并排序** | O(n log n) | 稳定排序 | 需要稳定性的场景 |
| **堆排序** | O(n log n) | 原地排序 | 内存受限场景 |
+::: tip 📊 逐行解读这张表
+**冒泡排序**:最基础的排序算法,就像水底的气泡往上冒一样。简单易懂,但速度最慢。适合学习排序思想,不适合实际使用。
+
+**选择排序**:每次选出最小的放到前面。也很简单,但无论数据是否有序都要做同样多的比较。
+
+**插入排序**:像打扑克牌时整理手牌一样。把每个元素插入到前面已经排好序的部分中。对近乎有序的数据效率很高。
+
+**快速排序**:实际开发中最常用的排序。平均情况下最快,但最坏情况(数据已经有序)会退化到 O(n²)。
+
+**归并排序**:采用"分而治之"的思想,总是 O(n log n),但需要额外空间。适合需要稳定排序的场景。
+
+**堆排序**:利用堆这种数据结构的排序,原地排序(不需要额外空间),但实际运行往往比快速排序慢。
+:::
+
### 2.2 为什么快速排序"快"?
::: tip 💡 快速排序的原理
@@ -120,6 +149,11 @@
**生活类比**:整理书架。先抽出一本书,把比它薄的放左边,比它厚的放右边。然后对左右两堆分别重复这个过程。
:::
+👇 **动手试试看**:
+下面这个演示展示了排序算法的可视化,你可以生成数组,观察冒泡排序和快速排序的过程对比:
+
+
+
---
## 3. 递归:自己调用自己
@@ -153,6 +187,16 @@ function factorial(n) {
| **性能** | 稍慢(函数调用开销) | 更快 |
| **适用场景** | 树遍历、分治算法 | 简单重复任务 |
+::: tip 📊 逐行解读这张表
+**代码简洁度**:递归通常只需要几行代码就能表达复杂的逻辑(如遍历树结构),而用循环可能需要更多的变量和嵌套。
+
+**内存消耗**:递归会使用"调用栈"来保存每一层的信息,就像叠盘子一样,每递归一层就多一个盘子。循环则不需要这种开销。
+
+**性能**:每次函数调用都有开销(参数传递、栈操作等),所以递归通常比循环慢一些。
+
+**适用场景**:递归擅长处理本身就是递归结构的问题(如文件树、DOM 树);循环擅长简单的重复操作(如遍历数组)。
+:::
+
::: warning ⚠️ 递归的陷阱
**栈溢出**:递归层次太深,调用栈空间耗尽。
@@ -162,6 +206,11 @@ function factorial(n) {
- 限制递归深度
:::
+👇 **动手试试看**:
+下面这个演示展示了递归的调用过程,观察函数如何自己调用自己:
+
+
+
---
## 4. 贪心算法:每步选最优
@@ -197,6 +246,11 @@ function factorial(n) {
**教训**:贪心算法简单高效,但不总是能得到最优解。使用前要证明问题满足贪心条件。
:::
+👇 **动手试试看**:
+下面这个演示展示了贪心算法的实际效果,你可以尝试不同的硬币组合,观察贪心策略的表现:
+
+
+
---
## 5. 算法设计范式
@@ -208,6 +262,21 @@ function factorial(n) {
| **动态规划** | 记录子问题的解 | 背包问题、最短路径 | 有重叠子问题 |
| **回溯** | 试错,走不通就回退 | 八皇后、全排列 | 搜索问题 |
+::: tip 📊 逐行解读这张表
+**分治**:把大问题拆成小问题,分别解决后再合并。就像整理房间,先分成客厅、卧室、厨房分别打扫,最后整体整洁。
+
+**贪心**:每步都选当前最好的,不考虑长远后果。像吃饭时先挑最喜欢吃的菜,可能不是最优的吃法,但速度快。
+
+**动态规划**:记住中间结果,避免重复计算。像记笔记,下次遇到同样问题直接查答案,不用重新推导。
+
+**回溯**:走不通就退回来重试。像走迷宫,此路不通就返回上一个路口尝试别的路。
+:::
+
+👇 **动手试试看**:
+下面这个演示展示了不同算法设计范式的特点和应用场景:
+
+
+
---
## 6. 总结:算法是解决问题的艺术
diff --git a/docs/zh-cn/appendix/1-computer-fundamentals/data-structures.md b/docs/zh-cn/appendix/1-computer-fundamentals/data-structures.md
index df0b1d4..77dea1e 100644
--- a/docs/zh-cn/appendix/1-computer-fundamentals/data-structures.md
+++ b/docs/zh-cn/appendix/1-computer-fundamentals/data-structures.md
@@ -1,230 +1,293 @@
# 数据结构
::: tip 前言
-**如何高效地组织和存储数据?** 你可能遇到过这样的困惑:为什么有些程序处理几万条数据很快,有些处理几百条就卡住了?答案往往在于数据结构的选择。本章带你理解常见数据结构的特点和适用场景。
+**程序 = 数据结构 + 算法。** 前面我们学了 CPU 如何执行指令、操作系统如何管理资源。但程序要处理的核心对象是**数据**——用户信息、商品列表、社交关系……这些数据怎么在内存里组织,直接决定了程序的快慢。你可能遇到过这样的困惑:为什么有些程序处理几万条数据很快,有些处理几百条就卡住了?答案往往就在于**数据结构的选择**。
:::
**这篇文章会带你学什么?**
学完这章后,你将获得:
-- **选型决策能力**:知道什么时候用数组快速访问,什么时候用链表灵活插入
-- **性能分析视角**:能判断性能问题是数据结构选择不当,还是算法效率低下
+- **直觉判断力**:看到一个需求,脑子里自动浮现该用什么数据结构
+- **性能分析视角**:能判断性能瓶颈是数据结构选错了,还是算法效率低
- **权衡思维**:理解"空间换时间"与"时间换空间",知道没有完美的数据结构
-- **后续学习基础**:为数据库、缓存系统、搜索引擎等技术打下基础
+- **代码阅读能力**:看到 HashMap、Stack、Queue 这些词不再陌生
+- **后续学习基础**:为数据库索引、缓存系统、搜索引擎等技术打下基础
| 章节 | 内容 | 核心概念 |
|-----|------|---------|
-| **第 1 章** | 线性结构 | 数组、链表、栈、队列 |
-| **第 2 章** | 哈希结构 | 哈希表、冲突处理 |
-| **第 3 章** | 树形结构 | 二叉树、B树、堆 |
-| **第 4 章** | 图结构 | 有向图、无向图、遍历算法 |
+| **第 1 章** | 全景图 | 四大类数据结构、分类标准 |
+| **第 2 章** | 线性结构 | 数组、链表、栈、队列 |
+| **第 3 章** | 哈希表 | 哈希函数、冲突处理、O(1) 查找 |
+| **第 4 章** | 树形结构 | 二叉树、文件系统树、DOM 树 |
+| **第 5 章** | 图结构 | 有向图、无向图、遍历算法 |
+| **第 6 章** | 性能对比 | 时间复杂度、空间复杂度 |
+| **第 7 章** | 选型指南 | 场景分析、决策流程 |
---
-## 0. 全景图:数据结构是什么?
+## 1. 全景图:数据结构是什么?
想象你要整理一堆书:
-- **堆在地上**:找书要一本本翻(链表)
-- **按编号放书架**:直接去对应位置拿(数组)
-- **按类别分柜子**:先找柜子再找书(哈希表)
-- **按书名排序**:二分查找,每次排除一半(树)
+- **堆在地上**:找书要一本本翻——这就是最原始的存储
+- **按编号放书架**:直接去对应位置拿——这就是**数组**
+- **按类别分柜子**:先确定柜子再找书——这就是**哈希表**
+- **按书名排序放多层架**:每次排除一半——这就是**树**
-不同的整理方式,找书的效率天差地别。**数据结构就是数据的"整理方式"**。
+不同的整理方式,找书的效率天差地别。**数据结构就是数据的"整理方式"**——它决定了数据怎么存、怎么找、怎么改。
-
+
-**常见数据结构分类:**
+所有数据结构可以归为四大类:
-| 类型 | 特点 | 典型代表 | 适用场景 |
-|------|------|---------|---------|
-| **线性结构** | 数据排成一排 | 数组、链表、栈、队列 | 顺序处理、历史记录 |
-| **哈希结构** | 键值对映射 | 哈希表 | 快速查找、缓存 |
-| **树形结构** | 层次关系 | 二叉树、B树 | 排序、搜索、文件系统 |
-| **图结构** | 网状关系 | 有向图、无向图 | 社交网络、路径规划 |
+| 类型 | 数据关系 | 典型代表 | 生活类比 |
+|------|---------|---------|---------|
+| **线性结构** | 一对一,排成一排 | 数组、链表、栈、队列 | 火车车厢、排队队伍 |
+| **哈希结构** | 键→值映射 | 哈希表、字典、集合 | 图书馆索引卡片 |
+| **树形结构** | 一对多,层级关系 | 二叉树、B树、堆 | 家族族谱、文件夹 |
+| **图结构** | 多对多,网状关系 | 有向图、无向图 | 地铁线路图、社交网络 |
-::: tip 📊 逐行解读这张表
-**线性结构**:最简单的数据组织方式,数据一个接一个排列。数组适合随机访问,链表适合频繁插入删除。
-
-**哈希结构**:用"键"直接找到"值",查找速度最快。但需要处理"冲突"问题(两个键映射到同一位置)。
-
-**树形结构**:有层次关系的数据。二叉搜索树适合排序和搜索,B树适合磁盘存储(数据库索引)。
-
-**图结构**:最复杂的结构,表示任意的关系网络。社交网络、地图导航都用图来建模。
+::: tip 为什么要学这么多种?
+因为**没有万能的数据结构**。每种结构都是在"查找速度"、"插入速度"、"内存占用"之间做权衡。就像你不会用书包装家具,也不会用卡车送一封信——选对工具,事半功倍。
:::
---
-## 1. 线性结构:最基础的组织方式
+## 2. 线性结构:最基础的组织方式
-### 1.1 数组:连续存储
+线性结构是最直觉的数据组织方式——数据一个接一个排列,就像火车车厢。但"怎么连接"和"从哪端操作"的不同,产生了四种变体,各有各的绝活。
-::: tip 💡 数组的特点
-**数组**是一块连续的内存空间,每个元素大小相同。
+
-**优点**:
-- 随机访问快:`arr[100]` 直接计算地址,O(1)
-- 缓存友好:连续存储,CPU 缓存命中率高
+### 2.1 数组 vs 链表:两种截然不同的存储方式
-**缺点**:
-- 插入删除慢:需要移动后面所有元素,O(n)
-- 大小固定:需要预先分配空间
+数组和链表是最基础的两种线性结构,它们的核心区别在于**内存布局**:
-**生活类比**:一排编号的储物柜,每个柜子大小相同。找第 10 号柜子直接去,但要在中间插入一个柜子,后面的都要往后挪。
+| 对比维度 | 数组 | 链表 |
+|---------|------|------|
+| **内存布局** | 连续的一整块 | 散落在各处,用指针串起来 |
+| **访问第 n 个** | 直接算地址,O(1) | 从头一个个找,O(n) |
+| **中间插入** | 后面的都要挪,O(n) | 改两个指针就行,O(1) |
+| **大小** | 创建时就固定了 | 随时可以增长 |
+| **生活类比** | 一排编号储物柜 | 寻宝游戏的线索链 |
+
+::: tip 什么时候用数组?什么时候用链表?
+- **数据量已知、频繁按位置访问** → 数组(比如学生成绩表、像素矩阵)
+- **数据量未知、频繁插入删除** → 链表(比如播放列表、撤销历史)
+- **不确定?** → 先用数组。大多数场景下,数组的缓存友好性带来的性能优势更大
:::
-### 1.2 链表:节点相连
+### 2.2 栈和队列:加了"规矩"的线性结构
-::: tip 💡 链表的特点
-**链表**由一系列节点组成,每个节点包含数据和指向下一个节点的指针。
+栈和队列本质上就是数组或链表,只是**限制了操作方式**。看起来功能变少了,但正是这种限制让它们有了明确的用途:
-**优点**:
-- 插入删除快:只需修改指针,O(1)
-- 大小灵活:可以动态增长
+| 结构 | 规则 | 操作 | 类比 | 你写的代码里在哪? |
+|------|------|------|------|-----------------|
+| **栈** | 后进先出 (LIFO) | push / pop | 一摞盘子 | 函数调用栈、浏览器后退、Ctrl+Z 撤销 |
+| **队列** | 先进先出 (FIFO) | enqueue / dequeue | 排队买票 | 任务调度、消息队列、打印队列 |
-**缺点**:
-- 访问慢:要从头开始遍历,O(n)
-- 额外空间:每个节点需要存储指针
-
-**生活类比**:寻宝游戏,每个线索指向下一个地点。要找第 10 个线索,必须从第 1 个开始一步步找。
-:::
-
-### 1.3 栈和队列:受限的线性结构
-
-| 结构 | 规则 | 操作 | 类比 | 应用 |
-|------|------|------|------|------|
-| **栈** | 后进先出 (LIFO) | push/pop | 一摞盘子 | 函数调用、撤销操作 |
-| **队列** | 先进先出 (FIFO) | enqueue/dequeue | 排队买票 | 任务调度、消息队列 |
-
-::: tip 💡 为什么要有"受限"的结构?
-栈和队列看起来比数组、链表功能少,但正是这种"限制"让它们有明确的用途:
-
-- **栈**:函数调用时,最后调用的函数最先返回
-- **队列**:任务调度时,先来的任务先处理
-
-限制带来简洁,简洁带来高效。
+::: tip 为什么"限制"反而是好事?
+想象一个只有"放盘子"和"拿盘子"两个操作的栈——你永远不会拿错顺序。**限制带来确定性,确定性带来可靠性。** 函数调用栈就是靠"后进先出"保证最后调用的函数最先返回,如果允许随意访问中间的函数,程序就乱套了。
:::
---
-## 2. 哈希表:最快的查找
+## 3. 哈希表:最快的查找
-### 2.1 哈希表原理
+线性结构的查找都不够快——数组要遍历 O(n),即使排好序用二分查找也要 O(log n)。有没有一种结构能做到 **O(1) 直接找到**?有,就是哈希表。
-::: tip 💡 哈希表如何工作?
-**哈希表**通过"哈希函数"把键映射到数组索引。
+
-**工作流程**:
-1. 输入键(如 "apple")
-2. 哈希函数计算:`hash("apple") = 3`
-3. 直接去数组索引 3 的位置找
+### 3.1 哈希表的核心思想
-**冲突处理**:
-- 两个不同的键可能映射到同一索引
-- 解决方法:链地址法(同一位置用链表存储多个值)
+哈希表的原理其实很简单:
-**生活类比**:图书馆按书名首字母分柜子。"Apple" 开头的书都放 A 柜,"Banana" 开头的放 B 柜。找书时先确定柜子,再在柜子里找。
-:::
+1. 你给一个**键**(比如 "apple")
+2. **哈希函数**把键算成一个数字(比如 `hash("apple") = 3`)
+3. 直接去数组的第 3 个位置找——不用遍历,一步到位
-### 2.2 哈希表的时间复杂度
+这就像图书馆的索引系统:你不用在一排排书架上找,查索引卡片就能直接定位到书的位置。
-| 操作 | 平均情况 | 最坏情况 |
-|------|---------|---------|
+### 3.2 哈希冲突:两个键撞车了怎么办?
+
+两个不同的键可能算出同一个索引——这叫**哈希冲突**。就像两本书的索引号相同,都指向同一个位置。
+
+| 解决方法 | 原理 | 类比 |
+|---------|------|------|
+| **链地址法** | 同一位置用链表存多个值 | 同一个柜子里放多本书 |
+| **开放寻址法** | 冲突了就往后找空位 | 柜子满了就放隔壁柜子 |
+
+### 3.3 哈希表的性能
+
+| 操作 | 平均情况 | 最坏情况(全部冲突) |
+|------|---------|-------------------|
| **查找** | O(1) | O(n) |
| **插入** | O(1) | O(n) |
| **删除** | O(1) | O(n) |
-::: warning ⚠️ 什么时候会退化?
-当所有键都映射到同一个索引时,哈希表退化为链表,所有操作变成 O(n)。
+::: warning 什么时候会退化?
+当所有键都映射到同一个索引时,哈希表退化为链表,所有操作变成 O(n)。避免方法:选择好的哈希函数 + 动态扩容(负载因子超过阈值时扩容)。
+:::
-**避免方法**:
-- 选择好的哈希函数
-- 动态扩容(负载因子超过阈值时扩容)
+::: tip 哈希表在你的代码里无处不在
+- JavaScript 的 `{}` 对象和 `Map` → 哈希表
+- Python 的 `dict` → 哈希表
+- Java 的 `HashMap` → 哈希表
+- 数据库的索引 → 底层也用哈希
+
+你每次写 `user["name"]` 或 `map.get("key")`,背后都是哈希表在工作。
:::
---
-## 3. 树:层次结构
+## 4. 树形结构:层级关系的表达
-### 3.1 二叉搜索树
+哈希表查找快,但数据是无序的。如果你需要**既能快速查找,又能保持数据有序**,就需要树形结构了。
+
+树的核心特征:每个节点可以有多个"孩子",但只有一个"父亲"(根节点除外)。这种一对多的层级关系,在现实中随处可见。
+
+
+
+### 4.1 二叉搜索树:有序的树
+
+二叉搜索树有一个简单但强大的规则:**左小右大**。
-::: tip 💡 二叉搜索树的规则
-**二叉搜索树**是一种特殊的二叉树:
- 左子树的所有值 < 根节点
- 右子树的所有值 > 根节点
-**查找过程**:
-1. 从根节点开始
-2. 如果目标值 < 当前值,往左走
-3. 如果目标值 > 当前值,往右走
-4. 每次比较排除一半节点
+查找时,每次比较都能排除一半节点,时间复杂度 O(log n)。就像猜数字游戏——"比 50 大还是小?""大。""比 75 大还是小?"——每次排除一半。
-**时间复杂度**:O(log n),但最坏情况(变成链表)是 O(n)
-:::
+### 4.2 平衡树:防止退化
-### 3.2 平衡树
+二叉搜索树有个问题:如果数据按顺序插入(1, 2, 3, 4, 5),树会退化成一条链,查找变回 O(n)。平衡树通过自动调整结构来避免这个问题:
-为了防止二叉搜索树退化,引入了**平衡树**:
+| 类型 | 平衡策略 | 特点 | 典型应用 |
+|------|---------|------|---------|
+| **AVL 树** | 严格平衡(高度差 ≤ 1) | 查找最快,插入删除稍慢 | 需要频繁查找的场景 |
+| **红黑树** | 近似平衡 | 综合性能好 | Java TreeMap、Linux 内核 |
+| **B 树** | 多路平衡,一个节点存多个值 | 减少磁盘 I/O | 数据库索引 |
-| 类型 | 平衡方式 | 特点 |
-|------|---------|------|
-| **AVL 树** | 严格平衡(高度差 ≤ 1) | 查找最快,插入删除稍慢 |
-| **红黑树** | 近似平衡 | 综合性能好,应用最广 |
-| **B 树** | 多路平衡 | 适合磁盘存储,数据库索引 |
-
----
-
-## 4. 如何选择数据结构?
-
-| 需求 | 推荐结构 | 原因 |
-|------|---------|------|
-| **快速随机访问** | 数组 | O(1) 索引访问 |
-| **频繁插入删除** | 链表 | O(1) 插入删除 |
-| **快速查找** | 哈希表 | O(1) 平均查找 |
-| **有序数据** | 平衡树 | O(log n) 查找,保持有序 |
-| **最近使用** | 栈 | LIFO 特性 |
-| **任务排队** | 队列 | FIFO 特性 |
-
-::: tip 💡 选择数据结构的心法
-**没有最好的数据结构,只有最合适的数据结构。**
-
-选择时要考虑:
-1. **主要操作是什么?** 查找?插入?删除?
-2. **数据量多大?** 小数据量差别不大,大数据量要慎重
-3. **数据有序吗?** 有序数据可以用二分查找
-4. **内存限制?** 某些结构需要额外空间
+::: tip 树在你的代码里在哪?
+- **文件系统**:文件夹嵌套就是树结构
+- **HTML DOM**:`` → `` → `
` → `
` 就是一棵树
+- **数据库索引**:B+ 树让百万级数据的查找只需要 3-4 次磁盘读取
+- **JSON/XML**:嵌套的数据格式本质上就是树
:::
---
-## 5. 总结:数据结构是程序的基础
+## 5. 图结构:复杂关系的网络
-让我们用一个比喻总结各种数据结构:
+树只能表示"一对多"的层级关系。但现实中很多关系是"多对多"的——你的朋友也有朋友,城市之间有多条路可以走。这种**任意节点之间都可能有连接**的结构,就是图。
-| 结构 | 比喻 | 核心特点 |
-|------|------|---------|
-| **数组** | 编号储物柜 | 访问快,插入慢 |
-| **链表** | 寻宝线索 | 插入快,访问慢 |
-| **栈** | 一摞盘子 | 后进先出 |
-| **队列** | 排队队伍 | 先进先出 |
-| **哈希表** | 分类柜子 | 查找最快 |
-| **树** | 家族族谱 | 层次结构 |
+
-::: tip 💡 核心启示
-**数据结构决定了程序的效率上限。**
+### 5.1 图的三种形态
-- 选对数据结构,问题迎刃而解
-- 选错数据结构,再好的算法也无济于事
+| 类型 | 特点 | 类比 | 典型应用 |
+|------|------|------|---------|
+| **无向图** | 边没有方向,A→B 等于 B→A | 微信好友(互相的) | 社交网络、通信网络 |
+| **有向图** | 边有方向,A→B 不等于 B→A | 微博关注(单向的) | 网页链接、依赖关系 |
+| **带权图** | 边有权重(距离、费用等) | 城市间的公路(有里程数) | 地图导航、最短路径 |
-理解数据结构,就是理解"如何高效地组织数据"。这是每个程序员的基本功。
+### 5.2 图的遍历
+
+图的遍历比线性结构复杂,因为可能有环(A→B→C→A),需要记录"已访问"的节点:
+
+| 遍历方式 | 策略 | 类比 | 适用场景 |
+|---------|------|------|---------|
+| **BFS(广度优先)** | 先访问所有邻居,再访问邻居的邻居 | 水波纹扩散 | 最短路径、层级遍历 |
+| **DFS(深度优先)** | 一条路走到底,走不通再回头 | 走迷宫 | 路径搜索、连通性判断 |
+
+::: tip 图在现实中的应用
+- **地图导航**:城市是节点,道路是边,导航就是在图上找最短路径
+- **社交网络**:用户是节点,关注/好友是边,"你可能认识的人"就是图算法推荐的
+- **包管理器**:npm/pip 的依赖关系就是有向图,`npm install` 就是在做图的拓扑排序
:::
---
+## 6. 性能对比:一张表看清所有数据结构
+
+学了这么多数据结构,它们的性能到底差多少?下面这个交互式对比能帮你建立直觉:
+
+
+
+**核心性能对比表:**
+
+| 数据结构 | 访问 | 查找 | 插入 | 删除 | 空间 |
+|---------|------|------|------|------|------|
+| **数组** | O(1) | O(n) | O(n) | O(n) | O(n) |
+| **链表** | O(n) | O(n) | O(1) | O(1) | O(n) |
+| **栈/队列** | O(n) | O(n) | O(1) | O(1) | O(n) |
+| **哈希表** | — | O(1) | O(1) | O(1) | O(n) |
+| **二叉搜索树** | — | O(log n) | O(log n) | O(log n) | O(n) |
+| **图** | — | O(V+E) | O(1) | O(E) | O(V+E) |
+
+::: tip 怎么读这张表?
+- **O(1)**:不管数据量多大,操作时间恒定——最快
+- **O(log n)**:数据量翻倍,时间只多一步——很快
+- **O(n)**:数据量翻倍,时间也翻倍——一般
+- **O(V+E)**:取决于节点数和边数——图的特殊表示
+
+注意:这些都是**平均情况**。最坏情况下,哈希表会退化到 O(n),二叉搜索树也会退化到 O(n)。
+:::
+
+---
+
+## 7. 选型指南:该用哪种数据结构?
+
+学了这么多数据结构,面对实际需求时该怎么选?关键是**从需求出发**,问自己几个问题:
+
+1. **最频繁的操作是什么?** 查找?插入?删除?遍历?
+2. **数据之间有什么关系?** 一对一?一对多?多对多?
+3. **数据量有多大?** 几十条和几百万条的最优选择可能完全不同
+4. **需要有序吗?** 是否需要按某种顺序遍历数据
+
+
+
+**快速决策流程:**
+
+| 你的需求 | 推荐结构 | 原因 |
+|---------|---------|------|
+| 按位置快速访问 | 数组 | O(1) 随机访问 |
+| 频繁在中间插入删除 | 链表 | O(1) 插入删除,不用移动元素 |
+| 后进先出(撤销、递归) | 栈 | LIFO 语义天然匹配 |
+| 先进先出(任务队列) | 队列 | FIFO 语义天然匹配 |
+| 按键快速查找 | 哈希表 | O(1) 平均查找 |
+| 有序数据 + 快速查找 | 二叉搜索树 | O(log n) 查找且保持有序 |
+| 复杂多对多关系 | 图 | 能表达任意节点间的连接 |
+
+::: tip 实际开发中的经验法则
+- **80% 的场景**用数组和哈希表就够了
+- **需要有序**时考虑树
+- **关系复杂**时考虑图
+- **不确定?** 先用最简单的,遇到性能问题再换。过早优化是万恶之源
+:::
+
+---
+
+## 总结
+
+> 数据结构是程序的骨架。**数组**像一排编号储物柜,按位置取东西最快;**链表**像寻宝线索链,插入删除最灵活;**哈希表**像图书馆索引,按名字找东西最快;**树**像家族族谱,表达层级关系且保持有序;**图**像地铁线路图,表达任意复杂的网状关系。没有最好的数据结构,只有最合适的——关键是理解每种结构的优势和代价,根据实际需求做出权衡。
+
+---
+
## 延伸阅读
-- **数据结构实现**:自己动手实现各种数据结构,加深理解
-- **高级数据结构**:学习跳表、布隆过滤器、并查集等
-- **数据库索引**:了解 B+ 树在数据库中的应用
-- **缓存设计**:学习 LRU 缓存如何结合哈希表和链表
+| 主题 | 推荐资源 |
+|------|---------|
+| 数据结构可视化 | [VisuAlgo](https://visualgo.net/) - 动画演示各种数据结构和算法 |
+| 算法与数据结构 | 《算法图解》- Aditya Bhargava,图文并茂适合入门 |
+| 深入理解 | 《数据结构与算法分析》- Mark Allen Weiss |
+| 刷题练习 | [LeetCode](https://leetcode.cn/) - 按数据结构分类练习 |
+
+---
+
+## 下一步
+
+现在你已经掌握了数据结构的核心知识。接下来可以继续学习:
+
+- **[算法思维](./algorithm-thinking.md)**:学会用排序、搜索、递归、动态规划等算法思维解决问题
+- **[编程语言](./programming-languages.md)**:了解不同编程语言如何实现这些数据结构
diff --git a/docs/zh-cn/appendix/1-computer-fundamentals/power-on-to-web.md b/docs/zh-cn/appendix/1-computer-fundamentals/power-on-to-web.md
index d215cec..3884157 100644
--- a/docs/zh-cn/appendix/1-computer-fundamentals/power-on-to-web.md
+++ b/docs/zh-cn/appendix/1-computer-fundamentals/power-on-to-web.md
@@ -52,47 +52,7 @@ CPU 接收到复位信号后,把内部所有寄存器和缓存清零,从一
## 2. BIOS/UEFI:硬件的自检
-### 2.1 什么是 BIOS/UEFI?
-
-**BIOS(Basic Input/Output System)** 是电脑启动后第一个运行的程序,存储在主板的一个**只读芯片**中。
-
-**UEFI(Unified 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)**,把控制权交给操作系统。
+
---
@@ -104,94 +64,7 @@ BIOS/UEFI 会按照设定的**启动顺序**查找启动设备:
## 3. 操作系统启动:从内核到桌面
-### 3.1 什么是操作系统?
-
-**操作系统(Operating System,简称 OS)** 是管理计算机硬件和软件资源的程序集合。它就像一个"大管家",帮我们管理内存、CPU、文件等资源,让我们不需要直接和硬件打交道。
-
-常见的操作系统:
-
-| 操作系统 | 特点 | 典型设备 |
-|---------|------|---------|
-| **Windows** | 生态丰富,兼容性好 | 桌面电脑、笔记本 |
-| **macOS** | 苹果生态,流畅稳定 | Mac 电脑 |
-| **Linux** | 开源免费,服务器首选 | 服务器、嵌入式设备 |
-| **Android** | 移动端 Linux | 手机、平板 |
-| **iOS** | 苹果移动端 | iPhone、iPad |
-
-### 3.2 操作系统的启动过程
-
-当你从硬盘启动时,操作系统的启动过程如下:
-
-
-
-#### 第一步:引导程序(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. 显示桌面背景和图标 │
-└─────────────────────────────────────┘
-```
-
-
+
---
diff --git a/docs/zh-cn/appendix/1-computer-fundamentals/programming-languages.md b/docs/zh-cn/appendix/1-computer-fundamentals/programming-languages.md
index a93b281..cc19c33 100644
--- a/docs/zh-cn/appendix/1-computer-fundamentals/programming-languages.md
+++ b/docs/zh-cn/appendix/1-computer-fundamentals/programming-languages.md
@@ -99,7 +99,7 @@ SELECT name FROM users WHERE active = true
- **JavaScript(弱类型)**:`"11"` — 悄悄帮你转了
- **Python(强类型)**:`TypeError` — 让你自己想清楚
-想深入了解类型系统?→ [类型系统与编译原理入门](./type-systems-compilers)
+想深入了解类型系统?→ [类型系统入门](./type-systems) | [编译原理入门](./compilers)
---
@@ -147,6 +147,7 @@ SELECT name FROM users WHERE active = true
:::
**下一步学习**:
-- [类型系统与编译原理入门](./type-systems-compilers) - 深入理解类型系统和编译过程
+- [编译原理入门](./compilers) - 深入理解编译过程和代码优化
+- [类型系统入门](./type-systems) - 深入理解类型系统和类型安全
- [数据结构](./data-structures) - 理解数据的组织方式
- [算法思维入门](./algorithm-thinking) - 学习解决问题的方法
diff --git a/docs/zh-cn/appendix/2-development-tools/debugging-art.md b/docs/zh-cn/appendix/2-development-tools/debugging-art.md
index 415935d..e08db22 100644
--- a/docs/zh-cn/appendix/2-development-tools/debugging-art.md
+++ b/docs/zh-cn/appendix/2-development-tools/debugging-art.md
@@ -1,2 +1,432 @@
# 调试的艺术
-> 待实现
+
+::: tip 前言
+**代码写完了,运行报错——然后呢?** 很多新手在这一步就卡住了,盯着屏幕不知所措。调试(Debug)是编程中最核心的技能之一,甚至比写代码本身更重要。因为写代码只占开发时间的 30%,剩下的 70% 都在理解问题、定位 Bug、验证修复。
+:::
+
+**这篇文章会带你学什么?**
+
+学完这章后,你将获得:
+
+- **调试思维**:建立系统化的问题定位方法,不再"瞎猜"
+- **错误阅读能力**:看懂报错信息,从错误堆栈中快速定位问题
+- **常用调试方法**:掌握二分法、橡皮鸭、最小复现等经典调试技巧
+- **工具使用能力**:了解断点调试、日志调试、网络调试等工具的使用场景
+- **AI 辅助调试**:学会用 AI 加速调试过程,但不依赖 AI
+
+| 章节 | 内容 | 核心概念 |
+|-----|------|---------|
+| **第 1 章** | 读懂错误信息 | 错误类型、堆栈追踪 |
+| **第 2 章** | 经典调试方法 | 二分法、橡皮鸭、最小复现 |
+| **第 3 章** | 调试工具箱 | 断点、日志、网络抓包 |
+| **第 4 章** | AI 时代的调试 | AI 辅助 + 人工判断 |
+| **第 5 章** | 调试心态与习惯 | 防御性编程、调试日志 |
+
+---
+
+## 0. 全景图:调试是一种科学方法
+
+调试不是"碰运气",而是一个严谨的科学过程。物理学家做实验的方法论,完全适用于调试:
+
+1. **观察现象**:程序出了什么问题?报了什么错?
+2. **提出假设**:可能是什么原因导致的?
+3. **设计实验**:怎么验证这个假设?
+4. **验证结论**:假设对了就修复,错了就换一个假设
+
+::: tip 调试的黄金法则
+- **先复现,再修复**:不能稳定复现的 Bug,修了也不知道是不是真的修好了
+- **一次只改一个变量**:同时改多处,就不知道是哪个改动解决了问题
+- **相信证据,不相信直觉**:你觉得"不可能是这里的问题",往往就是这里的问题
+- **最近改了什么?**:80% 的 Bug 都是最近的改动引入的
+:::
+
+---
+
+## 1. 读懂错误信息:报错不是敌人,是线索
+
+新手最常犯的错误:看到报错就慌,直接关掉或者忽略。其实,**错误信息是程序在告诉你哪里出了问题**——它是你最好的朋友。
+
+### 1.1 错误的三大类型
+
+| 类型 | 什么时候出现 | 举例 | 严重程度 |
+|-----|------------|------|---------|
+| **语法错误** | 代码还没运行就报错 | 少了括号、拼错关键字 | 最容易修 |
+| **运行时错误** | 代码运行到某一行崩溃 | 访问不存在的变量、除以零 | 中等难度 |
+| **逻辑错误** | 代码能运行,但结果不对 | 计算公式写错、条件判断反了 | 最难发现 |
+
+### 1.2 如何阅读错误堆栈
+
+以 JavaScript 为例,一个典型的错误信息:
+
+```
+TypeError: Cannot read properties of undefined (reading 'name')
+ at getUserName (app.js:15:23)
+ at handleClick (app.js:42:10)
+ at HTMLButtonElement. (app.js:58:5)
+```
+
+**从上往下读**:
+
+1. **第一行**:错误类型 + 错误描述 → `TypeError`,试图读取 `undefined` 的 `name` 属性
+2. **第二行**:出错的函数和位置 → `getUserName` 函数,`app.js` 第 15 行第 23 列
+3. **后续行**:调用链 → 谁调用了这个函数?`handleClick` → 按钮点击事件
+
+::: tip 阅读堆栈的口诀
+**从上往下找原因,从下往上找源头。** 第一行告诉你"出了什么错",最后一行告诉你"从哪里开始的"。
+:::
+
+### 1.3 常见错误类型速查
+
+| 错误名称 | 含义 | 常见原因 |
+|---------|------|---------|
+| `SyntaxError` | 语法错误 | 括号不匹配、少了逗号 |
+| `TypeError` | 类型错误 | 对 `undefined`/`null` 做操作 |
+| `ReferenceError` | 引用错误 | 使用了未声明的变量 |
+| `RangeError` | 范围错误 | 数组越界、递归太深 |
+| `NetworkError` | 网络错误 | API 请求失败、跨域问题 |
+| `404 Not Found` | 资源不存在 | URL 写错、文件被删除 |
+| `500 Internal Server Error` | 服务器内部错误 | 后端代码崩溃 |
+
+### 1.4 Python 错误信息对比
+
+Python 的堆栈和 JavaScript 相反——**从下往上读**:
+
+```python
+Traceback (most recent call last):
+ File "main.py", line 10, in
+ result = calculate(data)
+ File "main.py", line 5, in calculate
+ return data["price"] * data["quantity"]
+KeyError: 'quantity'
+```
+
+**最后一行**才是错误原因:`KeyError: 'quantity'`,字典里没有 `quantity` 这个键。
+
+::: tip 不同语言,同一个思路
+不管什么语言,错误信息都包含三个关键信息:**什么错**(错误类型)、**哪里错**(文件和行号)、**为什么错**(错误描述)。学会提取这三个信息,就能读懂任何语言的报错。
+:::
+
+---
+
+## 2. 经典调试方法:前人总结的智慧
+
+这些方法不需要任何工具,只需要你的大脑。它们是所有高级调试技巧的基础。
+
+### 2.1 二分法调试
+
+**核心思想**:把问题范围缩小一半,再缩小一半,直到找到根源。
+
+**场景**:代码很长,不知道哪一段出了问题。
+
+**步骤**:
+
+1. 在代码中间加一个 `console.log`(或 `print`)
+2. 如果中间点之前就出错了 → 问题在上半部分
+3. 如果中间点之后才出错 → 问题在下半部分
+4. 对出错的那一半,重复上述步骤
+
+```
+100 行代码出了 Bug
+ ↓ 在第 50 行加 log
+问题在 50-100 行
+ ↓ 在第 75 行加 log
+问题在 50-75 行
+ ↓ 在第 62 行加 log
+问题在第 60-62 行!
+```
+
+::: tip 二分法的威力
+100 行代码,最多只需要 7 次(log₂100 ≈ 7)就能定位到具体行。1000 行也只需要 10 次。
+:::
+
+### 2.2 橡皮鸭调试法
+
+**核心思想**:把问题一行一行地"讲"给别人听(或者一只橡皮鸭),讲着讲着你自己就发现问题了。
+
+**为什么有效?** 因为"写代码"和"解释代码"用的是大脑的不同区域。当你被迫用语言描述每一步逻辑时,那些你"以为对了"的假设会暴露出来。
+
+**实践方法**:
+
+1. 打开出问题的代码
+2. 逐行解释:"这一行做了什么?为什么要这么做?"
+3. 当你说出"嗯,这里应该是……等等"的时候,Bug 往往就在那里
+
+### 2.3 最小复现
+
+**核心思想**:把复杂的问题简化到最小,只保留能触发 Bug 的最少代码。
+
+**为什么重要?**
+
+- 复杂系统中,Bug 可能被其他代码"掩盖"
+- 最小复现能排除干扰因素,让问题一目了然
+- 也方便你向别人求助——没人愿意看你 500 行代码
+
+**步骤**:
+
+1. 创建一个新的空文件
+2. 只复制和问题相关的代码
+3. 逐步删减,直到删掉任何一行 Bug 就消失
+4. 剩下的就是 Bug 的根源
+
+### 2.4 回退法(Git Bisect)
+
+**核心思想**:如果代码"之前是好的,现在坏了",那就找到是哪次提交引入的问题。
+
+```bash
+# Git 自带的二分查找工具
+git bisect start
+git bisect bad # 标记当前版本有 Bug
+git bisect good abc123 # 标记某个正常的旧版本
+# Git 会自动切换到中间的提交,你测试后告诉它 good 或 bad
+# 重复几次就能找到引入 Bug 的那次提交
+```
+
+::: tip 调试方法选择指南
+| 情况 | 推荐方法 |
+|-----|---------|
+| 不知道哪一段代码出错 | 二分法 |
+| 逻辑看起来对但结果不对 | 橡皮鸭 |
+| 复杂系统中的 Bug | 最小复现 |
+| "之前好好的突然坏了" | 回退法 / Git Bisect |
+:::
+
+---
+
+## 3. 调试工具箱:用对工具事半功倍
+
+方法论是基础,但好的工具能让调试效率翻倍。
+
+### 3.1 console.log / print:最朴素也最实用
+
+**适用场景**:快速查看变量值、确认代码执行到了哪里。
+
+```javascript
+// JavaScript
+console.log('函数被调用了,参数是:', data)
+console.log('计算结果:', result)
+console.table(arrayData) // 表格形式展示数组/对象
+```
+
+```python
+# Python
+print(f"当前值: {value}")
+print(f"类型: {type(data)}") # 检查数据类型
+```
+
+**进阶技巧**:
+
+| 方法 | 用途 |
+|-----|------|
+| `console.log()` | 普通输出 |
+| `console.warn()` | 黄色警告,容易在大量日志中找到 |
+| `console.error()` | 红色错误 |
+| `console.table()` | 表格展示数组和对象 |
+| `console.time()` / `console.timeEnd()` | 测量代码执行时间 |
+| `console.trace()` | 打印调用堆栈 |
+
+### 3.2 断点调试:逐行执行,看清每一步
+
+**适用场景**:逻辑复杂,需要一步步跟踪代码执行过程。
+
+**在浏览器中**(Chrome DevTools):
+
+1. 打开开发者工具(F12)→ Sources 面板
+2. 找到源代码文件,点击行号设置断点
+3. 触发相关操作,代码会在断点处暂停
+4. 用控制按钮逐步执行:
+ - **继续**(F8):运行到下一个断点
+ - **单步跳过**(F10):执行当前行,不进入函数内部
+ - **单步进入**(F11):进入函数内部
+ - **单步跳出**(Shift+F11):跳出当前函数
+
+**在 VS Code 中**:
+
+1. 点击行号左侧设置断点(红色圆点)
+2. 按 F5 启动调试
+3. 在"变量"面板查看所有变量的当前值
+4. 在"监视"面板添加你关心的表达式
+
+::: tip 断点 vs console.log
+**console.log** 适合快速验证,用完就删。**断点调试**适合深入分析复杂逻辑。两者不是替代关系,而是互补关系。
+:::
+
+### 3.3 网络调试:前后端之间的问题
+
+**适用场景**:页面显示不对,但不确定是前端的问题还是后端返回的数据有问题。
+
+**Chrome DevTools → Network 面板**:
+
+| 查看内容 | 能发现什么问题 |
+|---------|--------------|
+| **状态码** | 404(地址错)、500(服务器崩了)、403(没权限) |
+| **请求参数** | 前端发送的数据对不对 |
+| **响应数据** | 后端返回的数据格式对不对 |
+| **请求时间** | 哪个接口太慢,拖慢了页面 |
+| **请求头** | Token 有没有带、Content-Type 对不对 |
+
+**调试口诀**:先看状态码,再看请求参数,最后看响应数据。
+
+### 3.4 调试工具选择速查
+
+| 问题类型 | 推荐工具 |
+|---------|---------|
+| 变量值不对 | console.log / 断点 |
+| 逻辑执行顺序不对 | 断点调试 |
+| API 请求失败 | Network 面板 |
+| 页面样式不对 | Elements 面板(检查 CSS) |
+| 性能问题 | Performance 面板 / console.time |
+| 内存泄漏 | Memory 面板 |
+
+---
+
+## 4. AI 时代的调试:让 AI 当你的助手
+
+AI 工具(ChatGPT、Claude、Cursor 等)能大幅加速调试过程,但前提是你得知道怎么用。
+
+### 4.1 AI 擅长什么?
+
+| AI 擅长 | AI 不擅长 |
+|--------|----------|
+| 解释错误信息的含义 | 理解你的业务逻辑 |
+| 提供常见问题的解决方案 | 判断哪个方案最适合你的项目 |
+| 生成调试代码片段 | 复现只在特定环境出现的 Bug |
+| 分析代码中的潜在问题 | 理解复杂的系统上下文 |
+
+### 4.2 向 AI 提问的正确姿势
+
+**差的提问**:
+> "我的代码报错了,帮我看看"
+
+**好的提问**:
+> "我在用 React 写一个表单组件,提交时报错 `TypeError: Cannot read properties of undefined (reading 'email')`。以下是相关代码:[贴代码]。我已经确认 API 返回的数据格式是正确的,问题可能出在前端数据处理。"
+
+**提问模板**:
+
+```
+1. 我在做什么:[背景]
+2. 期望的行为:[应该怎样]
+3. 实际的行为:[实际怎样]
+4. 错误信息:[完整报错]
+5. 相关代码:[贴代码]
+6. 我已经尝试了:[排除了什么]
+```
+
+### 4.3 AI 调试的陷阱
+
+::: warning AI 调试的三个坑
+1. **AI 可能"自信地胡说"**:AI 给的方案看起来很合理,但可能完全不对。永远要自己验证。
+2. **AI 不了解你的上下文**:它不知道你的项目结构、依赖版本、运行环境。你需要提供足够的上下文。
+3. **过度依赖 AI 会退化调试能力**:如果每次报错都直接丢给 AI,你永远学不会自己调试。建议先自己分析 5 分钟,再求助 AI。
+:::
+
+### 4.4 AI + 人工的最佳组合
+
+```
+遇到 Bug
+ ↓
+第 1 步:自己读错误信息(1 分钟)
+ ↓
+第 2 步:自己提出假设(2 分钟)
+ ↓
+第 3 步:快速验证假设(2 分钟)
+ ↓
+卡住了?→ 把错误信息 + 代码 + 你的分析发给 AI
+ ↓
+AI 给出建议 → 你判断是否合理 → 验证
+```
+
+---
+
+## 5. 调试心态与习惯:从"救火"到"防火"
+
+最好的调试是不需要调试。养成好习惯,能从源头减少 Bug。
+
+### 5.1 防御性编程
+
+**核心思想**:写代码时就假设"一切都可能出错",提前做好防护。
+
+```javascript
+// 差:假设 data 一定存在
+const name = data.user.name
+
+// 好:防御性写法
+const name = data?.user?.name ?? '未知用户'
+```
+
+```python
+# 差:假设文件一定能打开
+content = open('config.json').read()
+
+# 好:防御性写法
+try:
+ content = open('config.json').read()
+except FileNotFoundError:
+ print("配置文件不存在,使用默认配置")
+ content = '{}'
+```
+
+### 5.2 写好日志
+
+日志是"事后调试"的关键。线上环境不能打断点,只能靠日志。
+
+| 日志级别 | 用途 | 举例 |
+|---------|------|------|
+| **DEBUG** | 开发时的详细信息 | 变量值、函数参数 |
+| **INFO** | 正常的业务流程 | "用户登录成功"、"订单创建" |
+| **WARN** | 不影响功能但需要注意 | "缓存未命中"、"重试第 2 次" |
+| **ERROR** | 出错了,需要处理 | "数据库连接失败"、"API 超时" |
+
+::: tip 好日志的标准
+一条好的日志应该回答:**什么时候**、**在哪里**、**发生了什么**、**关键数据是什么**。
+```
+[2025-01-15 14:30:22] [ERROR] [OrderService] 创建订单失败
+ 用户ID: 12345, 商品ID: 67890, 原因: 库存不足
+```
+:::
+
+### 5.3 调试检查清单
+
+遇到 Bug 时,按这个顺序排查:
+
+1. **读错误信息**:错误类型、文件、行号
+2. **最近改了什么?**:用 `git diff` 看最近的改动
+3. **能复现吗?**:找到稳定的复现步骤
+4. **缩小范围**:用二分法或最小复现定位
+5. **提出假设并验证**:一次只改一个变量
+6. **修复后回归测试**:确保修复没有引入新问题
+
+### 5.4 新手常踩的调试陷阱
+
+| 陷阱 | 正确做法 |
+|-----|---------|
+| 不看报错就开始改代码 | 先完整阅读错误信息 |
+| 同时改好几个地方 | 一次只改一处,验证后再改下一处 |
+| 改完不测试就提交 | 每次修改后都运行测试 |
+| 只在自己电脑上测试 | 考虑不同环境(浏览器、系统、网络) |
+| 调试完不清理 console.log | 提交前删除所有调试代码 |
+| 遇到问题就重启/重装 | 先理解问题原因,重启只是临时方案 |
+
+---
+
+## 6. 总结
+
+调试是一门手艺,需要刻意练习。回顾本章的核心要点:
+
+1. **调试是科学方法**:观察 → 假设 → 实验 → 验证,不是碰运气
+2. **错误信息是朋友**:学会从报错中提取"什么错、哪里错、为什么错"
+3. **经典方法永不过时**:二分法、橡皮鸭、最小复现是所有调试的基础
+4. **工具要用对场景**:console.log 快速验证,断点深入分析,Network 排查接口
+5. **AI 是助手不是拐杖**:先自己分析,再让 AI 辅助,最后自己验证
+6. **防火胜于救火**:防御性编程、好的日志习惯能从源头减少 Bug
+
+::: tip 记住这句话
+**每个 Bug 都是一次学习机会。** 你修过的每一个 Bug,都在帮你建立"模式识别"能力——下次遇到类似问题,你会更快地定位到原因。
+:::
+
+---
+
+## 延伸阅读
+
+- [Chrome DevTools 官方文档](https://developer.chrome.com/docs/devtools/) — 浏览器调试工具的完整指南
+- [VS Code Debugging](https://code.visualstudio.com/docs/editor/debugging) — VS Code 断点调试教程
+- [How to Debug Anything](https://www.debuggingbook.org/) — 系统化调试方法论
diff --git a/docs/zh-cn/appendix/3-browser-and-frontend/frontend-project-architecture.md b/docs/zh-cn/appendix/3-browser-and-frontend/frontend-project-architecture.md
new file mode 100644
index 0000000..1e134ad
--- /dev/null
+++ b/docs/zh-cn/appendix/3-browser-and-frontend/frontend-project-architecture.md
@@ -0,0 +1,648 @@
+# 前端项目架构设计
+
+::: tip 🎯 核心问题
+**文件越放越乱,代码越写越难找,如何设计一个清晰、可维护的前端项目结构?** 这就像问:你是把所有衣服都扔进一个箱子,还是按季节、类型、颜色分类整理?好的项目架构能让团队协作更高效,让代码维护更轻松。
+:::
+
+---
+
+## 1. 为什么要关注项目架构?
+
+### 1.1 从小项目到大项目的演变
+
+很多初学者刚开始写前端时,项目结构非常简单:
+
+```
+my-project/
+├── index.html
+├── style.css
+└── app.js
+```
+
+三个文件搞定一切,简单直接。但随着项目增长,问题开始出现:
+
+- **页面多了**:`page1.html`, `page2.html`... 文件散落在根目录
+- **组件多了**:按钮、弹窗、表单各自为政,复用困难
+- **工具函数多了**:到处复制粘贴,改一个地方要改十处
+- **样式冲突了**:全局 CSS 互相覆盖,调试困难
+
+**问题的本质**:没有"章法",文件随意存放,就像把春夏秋冬的衣服都扔进一个箱子。
+
+### 1.2 好的架构像整理好的衣柜
+
+想象一个整理好的衣柜:
+
+| 区域 | 存放物品 | 特点 |
+|------|----------|------|
+| **挂衣区** | 外套、衬衫 | 常穿,方便取用 |
+| **抽屉区** | 内衣、袜子 | 分类摆放,整齐 |
+| **隔板区** | 毛衣、裤子 | 叠放,节省空间 |
+| **顶层区** | 换季衣物 | 不常用,收纳起来 |
+
+**好的项目架构**就是把代码也这样组织:每一类文件有自己的"位置",团队成员都知道该去哪找、该往哪放。
+
+::: tip 💡 通俗比喻:餐厅后厨的组织
+把前端项目想象成一家餐厅的后厨:
+
+- **`src/pages/`(页面区)** = 出餐口:每个订单对应一个成品菜
+- **`src/components/`(组件区)** = 备料台:切好的蔬菜、调好的酱料,随时可用
+- **`src/utils/`(工具区)** = 工具柜:刀、勺、温度计等通用工具
+- **`src/assets/`(食材区)** = 冷藏库:图片、字体、样式等原材料
+- **`src/services/`(服务层)** = 传菜窗口:与外部(服务员/后端)交互
+
+**关键点**:每个区域职责明确,不会混乱。你不会在冷藏库里切菜,也不会把刀具扔进汤锅。
+:::
+
+---
+
+## 2. 经典目录结构解析
+
+### 2.1 标准目录结构(以 Vue/React 为例)
+
+一个中大型前端项目的典型结构如下:
+
+```
+my-frontend-project/
+├── public/ # 静态资源(不经过构建)
+│ ├── favicon.ico
+│ ├── index.html
+│ └── robots.txt
+├── src/
+│ ├── assets/ # 项目资源(会被构建工具处理)
+│ │ ├── images/
+│ │ ├── fonts/
+│ │ └── styles/
+│ │ ├── variables.scss # 变量定义
+│ │ ├── mixins.scss # 混入样式
+│ │ └── global.css # 全局样式
+│ ├── components/ # 通用组件
+│ │ ├── common/ # 全局通用组件
+│ │ │ ├── Button/
+│ │ │ │ ├── index.vue
+│ │ │ │ ├── Button.scss
+│ │ │ │ └── Button.test.js
+│ │ │ ├── Modal/
+│ │ │ └── Loading/
+│ │ └── business/ # 业务组件
+│ │ ├── UserCard/
+│ │ └── ProductList/
+│ ├── views/ 或 pages/ # 页面组件
+│ │ ├── Home/
+│ │ ├── About/
+│ │ └── User/
+│ │ ├── Profile/
+│ │ └── Settings/
+│ ├── router/ 或 navigation/ # 路由配置
+│ │ └── index.js
+│ ├── stores/ 或 state/ # 状态管理
+│ │ ├── user.js
+│ │ └── app.js
+│ ├── services/ 或 api/ # API 服务
+│ │ ├── user.js
+│ │ └── product.js
+│ ├── utils/ 或 helpers/ # 工具函数
+│ │ ├── request.js # 请求封装
+│ │ ├── storage.js # 本地存储
+│ │ └── format.js # 格式化工具
+│ ├── hooks/ 或 composables/ # 组合式函数
+│ │ ├── useAuth.js
+│ │ └── useLoading.js
+│ ├── directives/ # 自定义指令
+│ ├── plugins/ # 插件配置
+│ ├── constants/ # 常量定义
+│ ├── types/ 或 @types/ # TypeScript 类型
+│ └── App.vue 或 App.jsx # 根组件
+│ └── main.js 或 main.ts # 入口文件
+├── tests/ # 测试文件
+│ ├── unit/
+│ └── e2e/
+├── .env # 环境变量
+├── .env.development
+├── .env.production
+├── vite.config.js # 构建配置
+├── package.json
+└── README.md
+```
+
+::: tip 📊 从图解中你能看到什么?
+**分层逻辑**:
+
+- **`public/` vs `src/assets/`**:前者直接复制到输出目录,后者会被构建工具处理(压缩、转译、添加哈希值)
+- **`components/` vs `views/`**:组件是"零件",页面是"成品"。一个页面由多个组件组装而成
+- **`services/` 独立出来**:把 API 调用集中管理,方便统一处理错误、加载状态、请求拦截
+
+**依赖方向**:
+
+```
+views/pages → components → utils/hooks
+ ↓
+services → stores
+```
+
+上层可以调用下层,但下层不应该依赖上层。
+:::
+
+### 2.2 按功能组织 vs 按类型组织
+
+项目结构有两种主流的组织方式:
+
+#### 方式一:按类型组织(Type-based)
+
+```
+src/
+├── components/
+│ ├── Button.vue
+│ ├── Modal.vue
+│ └── Card.vue
+├── views/
+│ ├── Home.vue
+│ ├── User.vue
+│ └── Product.vue
+├── stores/
+│ ├── user.js
+│ └── product.js
+└── services/
+ ├── user.js
+ └── product.js
+```
+
+**优点**:
+- 结构清晰,同类文件在一起
+- 适合小型项目,一目了然
+
+**缺点**:
+- 修改一个功能要跨多个目录
+- 大型项目中文件过多,难以定位
+
+#### 方式二:按功能组织(Feature-based)
+
+```
+src/
+├── features/
+│ ├── auth/
+│ │ ├── components/
+│ │ │ ├── LoginForm.vue
+│ │ │ └── RegisterForm.vue
+│ │ ├── stores/
+│ │ │ └── authStore.js
+│ │ ├── services/
+│ │ │ └── authApi.js
+│ │ ├── hooks/
+│ │ │ └── useAuth.js
+│ │ └── index.js # 统一导出
+│ ├── user/
+│ │ ├── components/
+│ │ ├── stores/
+│ │ └── services/
+│ └── product/
+│ ├── components/
+│ ├── stores/
+│ └── services/
+├── shared/ # 共享资源
+│ ├── components/
+│ ├── utils/
+│ └── styles/
+└── App.vue
+```
+
+**优点**:
+- 高内聚,修改一个功能在一个目录完成
+- 便于团队协作,不同人负责不同 feature
+- 易于删除或重构,不会散落各处
+
+**缺点**:
+- 初期设计需要考虑 feature 划分
+- 共享组件需要额外考虑
+
+::: tip 💡 如何选择?
+| 项目规模 | 推荐方式 | 原因 |
+|----------|----------|------|
+| 小型项目(< 10 个页面) | 按类型组织 | 简单直接,快速上手 |
+| 中大型项目(> 20 个页面) | 按功能组织 | 便于维护,团队协作 |
+| 微前端/大型应用 | 按功能 + 模块拆分 | 独立部署,团队自治 |
+
+**实际建议**:很多项目采用"混合模式"——整体按功能组织,内部按类型细分。
+:::
+
+---
+
+## 3. 各目录的职责与最佳实践
+
+### 3.1 `components/` 组件目录
+
+组件是前端项目的核心,良好的组件设计能大幅提升开发效率。
+
+#### 组件分类
+
+```
+components/
+├── common/ # 通用组件(跨项目可复用)
+│ ├── Button/
+│ ├── Input/
+│ ├── Modal/
+│ └── Loading/
+├── business/ # 业务组件(项目特定)
+│ ├── UserCard/
+│ ├── ProductItem/
+│ └── OrderTable/
+└── layout/ # 布局组件
+ ├── Header/
+ ├── Sidebar/
+ └── Footer/
+```
+
+#### 单文件组件结构
+
+每个组件建议包含以下文件:
+
+```
+Button/
+├── index.vue # 主组件(或 .tsx/.jsx)
+├── Button.scss # 样式(可选 CSS Modules)
+├── Button.test.js # 单元测试
+├── Button.stories.js # Storybook 文档(可选)
+├── types.ts # 类型定义(TS 项目)
+└── index.ts # 统一导出
+```
+
+::: details 📝 组件代码示例
+```vue
+
+
+
+
+
+
+
+
+```
+:::
+
+### 3.2 `views/` 或 `pages/` 页面目录
+
+页面是用户看到的"成品",通常对应路由。
+
+```
+views/
+├── Home/ # 首页
+│ ├── index.vue
+│ ├── components/ # 页面私有组件
+│ │ ├── HeroSection.vue
+│ │ └── FeatureList.vue
+│ └── hooks/ # 页面私有 hooks
+│ └── useHomeData.js
+├── User/
+│ ├── Profile/
+│ ├── Settings/
+│ └── OrderHistory/
+└── Product/
+ ├── List/
+ └── Detail/
+```
+
+**最佳实践**:
+- 页面组件保持"薄",逻辑下沉到 hooks 或 services
+- 页面私有组件放在页面目录下,避免污染全局
+- 复杂页面可以进一步拆分子目录
+
+### 3.3 `services/` 或 `api/` 服务层
+
+集中管理所有 API 调用,统一处理请求/响应拦截。
+
+```
+services/
+├── request.js # 请求实例配置(axios/fetch 封装)
+├── user.js # 用户相关 API
+├── product.js # 商品相关 API
+├── order.js # 订单相关 API
+└── index.js # 统一导出
+```
+
+::: details 📝 服务层代码示例
+```javascript
+// services/request.js
+import axios from 'axios'
+import { useAuthStore } from '@/stores/auth'
+
+const request = axios.create({
+ baseURL: import.meta.env.VITE_API_BASE_URL,
+ timeout: 10000
+})
+
+// 请求拦截器
+request.interceptors.request.use(
+ (config) => {
+ const authStore = useAuthStore()
+ if (authStore.token) {
+ config.headers.Authorization = `Bearer ${authStore.token}`
+ }
+ return config
+ }
+)
+
+// 响应拦截器
+request.interceptors.response.use(
+ (response) => response.data,
+ (error) => {
+ if (error.response?.status === 401) {
+ // 统一处理登录过期
+ window.location.href = '/login'
+ }
+ return Promise.reject(error)
+ }
+)
+
+export default request
+```
+
+```javascript
+// services/user.js
+import request from './request'
+
+export const userApi = {
+ login: (data) => request.post('/auth/login', data),
+ register: (data) => request.post('/auth/register', data),
+ getProfile: () => request.get('/user/profile'),
+ updateProfile: (data) => request.put('/user/profile', data)
+}
+```
+:::
+
+### 3.4 `stores/` 状态管理
+
+```
+stores/
+├── index.js # store 入口
+├── auth.js # 认证状态
+├── user.js # 用户信息
+├── app.js # 应用级状态(主题、语言等)
+└── cart.js # 购物车状态
+```
+
+**建议**:
+- 按功能拆分 store,避免单个文件过大
+- 区分全局状态和局部状态,不要什么都放全局
+- 使用组合式 API(Pinia/Vuex 4+)更灵活
+
+### 3.5 `utils/` 工具函数
+
+```
+utils/
+├── format.js # 格式化(日期、金额等)
+├── storage.js # 本地存储封装
+├── validate.js # 表单验证
+├── dom.js # DOM 操作
+├── date.js # 日期处理
+└── index.js # 统一导出
+```
+
+**原则**:
+- 纯函数优先,便于测试
+- 单一职责,一个函数只做一件事
+- 添加 JSDoc 注释,说明参数和返回值
+
+::: details 📝 工具函数示例
+```javascript
+// utils/storage.js
+const STORAGE_PREFIX = 'myapp_'
+
+export const storage = {
+ get(key) {
+ const value = localStorage.getItem(STORAGE_PREFIX + key)
+ try {
+ return JSON.parse(value)
+ } catch {
+ return value
+ }
+ },
+
+ set(key, value) {
+ localStorage.setItem(
+ STORAGE_PREFIX + key,
+ typeof value === 'string' ? value : JSON.stringify(value)
+ )
+ },
+
+ remove(key) {
+ localStorage.removeItem(STORAGE_PREFIX + key)
+ }
+}
+```
+:::
+
+### 3.6 `hooks/` 或 `composables/` 组合式函数
+
+```
+hooks/
+├── useAuth.js # 认证逻辑
+├── useLoading.js # 加载状态
+├── usePagination.js # 分页逻辑
+├── useForm.js # 表单处理
+└── useWebsocket.js # WebSocket
+```
+
+::: details 📝 Hook 示例
+```javascript
+// hooks/useLoading.js
+import { ref } from 'vue'
+
+export function useLoading() {
+ const loading = ref(false)
+
+ const withLoading = async (fn) => {
+ loading.value = true
+ try {
+ return await fn()
+ } finally {
+ loading.value = false
+ }
+ }
+
+ return { loading, withLoading }
+}
+
+// 使用
+const { loading, withLoading } = useLoading()
+const fetchData = () => withLoading(async () => {
+ const data = await api.getData()
+ list.value = data
+})
+```
+:::
+
+---
+
+## 4. 知名开源项目的架构参考
+
+### 4.1 Vue 3 官方仓库
+
+```
+vue/
+├── packages/
+│ ├── vue/ # 核心包
+│ ├── reactivity/ # 响应式系统
+│ ├── runtime-core/ # 运行时核心
+│ ├── runtime-dom/ # DOM 运行时
+│ ├── compiler-sfc/ # 单文件组件编译器
+│ └── shared/ # 共享工具
+├── scripts/ # 构建脚本
+└── tsconfig.json
+```
+
+**特点**:
+- Monorepo 结构,多个包统一管理
+- 按功能拆分 package,职责清晰
+- 共享工具提取到 shared 包
+
+### 4.2 React 官方仓库
+
+```
+react/
+├── packages/
+│ ├── react/ # React 核心
+│ ├── react-dom/ # DOM 渲染器
+│ ├── react-reconciler/ # 协调器
+│ ├── scheduler/ # 调度器
+│ └── shared/ # 共享代码
+├── fixtures/ # 测试用例
+└── scripts/
+```
+
+**特点**:
+- 核心与渲染器分离(react vs react-dom)
+- reconciler 独立,支持多平台
+- scheduler 单独抽离,可独立使用
+
+### 4.3 Ant Design Vue
+
+```
+ant-design-vue/
+├── components/ # 组件目录
+│ ├── button/
+│ ├── modal/
+│ └── ...
+├── docs/ # 文档
+├── site/ # 官网
+├── tests/ # 测试
+└── typings/ # 类型定义
+```
+
+**特点**:
+- 组件与文档分离
+- 每个组件独立目录,包含 demo、test、style
+- 统一的类型定义
+
+### 4.4 Next.js(全栈框架)
+
+```
+my-nextjs-app/
+├── app/ # App Router(新版)
+│ ├── page.js # 页面
+│ ├── layout.js # 布局
+│ ├── loading.js # 加载状态
+│ └── api/ # API 路由
+├── components/ # 组件
+├── lib/ # 工具函数
+├── public/ # 静态资源
+└── styles/ # 全局样式
+```
+
+**特点**:
+- 约定式路由,文件即路由
+- 内置 loading、error、layout 等约定文件
+- API 路由与页面共存
+
+---
+
+## 5. 架构设计原则与检查清单
+
+### 5.1 核心原则
+
+| 原则 | 说明 | 实践建议 |
+|------|------|----------|
+| **单一职责** | 一个模块只做一件事 | 组件、函数保持简洁 |
+| **高内聚低耦合** | 相关代码放在一起,减少依赖 | 按功能组织目录 |
+| **可预测性** | 代码行为符合直觉 | 命名清晰,结构一致 |
+| **可测试性** | 便于编写单元测试 | 纯函数、依赖注入 |
+| **可扩展性** | 新功能容易添加 | 预留扩展点,避免硬编码 |
+
+### 5.2 检查清单
+
+**目录结构**:
+- [ ] 是否有清晰的目录划分?
+- [ ] 新成员能否快速找到文件位置?
+- [ ] 是否避免了过深的嵌套(建议不超过 4 层)?
+
+**组件设计**:
+- [ ] 组件是否单一职责?
+- [ ] Props 是否清晰、可预测?
+- [ ] 是否提取了可复用的逻辑到 hooks?
+
+**代码组织**:
+- [ ] 是否避免了循环依赖?
+- [ ] 工具函数是否纯函数优先?
+- [ ] 常量、配置是否集中管理?
+
+**团队协作**:
+- [ ] 是否有编码规范文档?
+- [ ] 是否有文件命名约定?
+- [ ] 代码审查是否关注架构问题?
+
+---
+
+## 6. 总结
+
+::: tip 💡 核心思想
+好的前端项目架构不是一成不变的,而是随着项目发展不断演进的。关键是建立清晰的**组织原则**和**命名约定**,让团队成员达成共识。
+
+**记住这几点**:
+1. **先简单后复杂**:小项目不要过度设计
+2. **按功能组织**:中大型项目推荐 Feature-based
+3. **统一约定**:命名、结构、代码风格保持一致
+4. **持续重构**:定期审视架构,及时调整
+
+**最终目标**:让代码像整理好的衣柜一样,想找什么立刻能找到,新成员也能快速上手。
+:::
+
+---
+
+## 参考资源
+
+- [Vue 风格指南](https://vuejs.org/style-guide/)
+- [React 项目结构建议](https://react.dev/learn/thinking-in-react)
+- [Bulletproof React - 架构指南](https://github.com/alan2207/bulletproof-react)
+- [Feature Sliced Design](https://feature-sliced.design/)
diff --git a/docs/zh-cn/appendix/3-browser-and-frontend/html-css-layout.md b/docs/zh-cn/appendix/3-browser-and-frontend/html-css-layout.md
index 5e1c627..3553dea 100644
--- a/docs/zh-cn/appendix/3-browser-and-frontend/html-css-layout.md
+++ b/docs/zh-cn/appendix/3-browser-and-frontend/html-css-layout.md
@@ -434,69 +434,365 @@ Flexbox 是现代 CSS 最常用的布局方式。它让元素自动排列对齐
| `flex-wrap` | 是否换行 | `nowrap`、`wrap` |
| `gap` | 元素间距 | `10px`、`1rem` |
-### 3.7 SCSS:CSS 的"升级版"
+### 3.7 CSS 预处理器:SCSS/SASS 与 LESS
::: tip 🎯 真实场景
你写了一个项目,CSS 文件有 2000 行。后来要改主题色,你发现:
- 主色调 `#3b82f6` 出现了 50 次
-- 改一个颜色要全局搜索替换
-- 还要担心漏改了某个地方
+- 改一个颜色要全局搜索替换,还要担心漏改
+- 选择器写成 `.nav .nav-list .nav-item .nav-link` 又长又难维护
-**SCSS 解决的问题**:变量、嵌套、混入、模块化
+**CSS 预处理器**就是来解决这些问题的。它让 CSS 也能"编程":有变量、有嵌套、能复用代码。
:::
-**SCSS 示例**:
+#### 3.7.1 什么是 CSS 预处理器?
-```scss
-// 1. 变量:定义主题色
-$primary-color: #3b82f6;
+**用人话解释**:预处理器是一种"更聪明的 CSS"。你用更强大的语法写样式,然后它帮你**编译**成普通 CSS,浏览器就能正常识别了。
-// 2. 嵌套:父子关系一目了然
-.card {
- background: white;
-
- h2 {
- color: $primary-color;
- }
-
- &:hover {
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
- }
-}
-```
+**为什么要用?**
-**编译后变成普通 CSS**:
+| 痛点 | 原生 CSS | 预处理器 |
+|------|----------|----------|
+| 颜色重复出现 | 到处复制粘贴 | 定义变量,一处修改全局生效 |
+| 选择器层级太深 | 写成一长串 | 嵌套语法,层级一目了然 |
+| 相同样式重复写 | 复制粘贴 | 混入(Mixin),像函数一样复用 |
+
+#### 3.7.2 三大预处理器对比
+
+| 特性 | 原生 CSS | **SCSS/SASS** | **LESS** |
+|------|----------|---------------|----------|
+| **变量写法** | `--primary` | `$primary` | `@primary` |
+| **嵌套语法** | ❌ 不支持 | ✅ 支持 | ✅ 支持 |
+| **混入(复用代码)** | ❌ 不支持 | ✅ `@mixin` | ✅ `.mixin()` |
+| **学习难度** | 简单 | 中等 | 中等 |
+| **流行程度** | - | ⭐⭐⭐ 最流行 | ⭐⭐ 较流行 |
+
+**简单记忆**:
+- **SCSS**:用 `$` 符号,Bootstrap 5 在用,生态最好
+- **LESS**:用 `@` 符号,和 CSS 的 `@media` 写法一致,容易上手
+
+#### 3.7.3 核心功能对比示例
+
+##### 1. 变量:一处修改,全局生效
+
+**场景**:主题色 `#3b82f6` 在 20 个地方用到,要改成红色。
+
+
+
```css
-.card {
- background: white;
-}
-.card h2 {
- color: #3b82f6;
-}
-.card:hover {
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
+/* 要改 20 处,容易漏 */
+.button { background: #3b82f6; }
+.link { color: #3b82f6; }
+.border { border-color: #3b82f6; }
+```
+
+
+
+
+```scss
+$primary: #3b82f6;
+
+.button { background: $primary; }
+.link { color: $primary; }
+.border { border-color: $primary; }
+/* 改 $primary 一处即可 */
+```
+
+
+
+
+```less
+@primary: #3b82f6;
+
+.button { background: @primary; }
+.link { color: @primary; }
+.border { border-color: @primary; }
+/* 改 @primary 一处即可 */
+```
+
+
+
+
+##### 2. 嵌套:层级关系一目了然
+
+**场景**:导航栏里有多层结构。
+
+
+
+
+```css
+/* 写成一长串,难看出层级关系 */
+.navbar .nav-list .nav-item .nav-link { }
+.navbar .nav-list .nav-item .nav-link:hover { }
+```
+
+
+
+
+```scss
+.navbar {
+ .nav-list {
+ .nav-item {
+ .nav-link {
+ &:hover { } /* & 表示父选择器 */
+ }
+ }
+ }
}
```
-**SCSS vs Less vs 原生 CSS**:
+
+
-| 特性 | 原生 CSS | SCSS | Less |
-|------|----------|------|------|
-| 变量 | ✅ `--var` | ✅ `$var` | ✅ `@var` |
-| 嵌套 | ❌ | ✅ | ✅ |
-| 混入 | ❌ | ✅ `@mixin` | ✅ `.mixin()` |
-| 学习曲线 | 简单 | 中等 | 中等 |
+```less
+.navbar {
+ .nav-list {
+ .nav-item {
+ .nav-link {
+ &:hover { }
+ }
+ }
+ }
+}
+```
+
+
+
+
+##### 3. 混入(Mixin):复用代码片段
+
+**场景**:多个按钮都需要"居中显示"的样式。
+
+
+
+
+```css
+/* 复制粘贴 3 次 */
+.btn-primary {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
+.btn-secondary {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
+```
+
+
+
+
+```scss
+@mixin center {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
+
+.btn-primary { @include center; }
+.btn-secondary { @include center; }
+```
+
+
+
+
+```less
+.center() {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
+
+.btn-primary { .center(); }
+.btn-secondary { .center(); }
+```
+
+
+
+
+#### 3.7.4 如何选择?
+
+| 情况 | 推荐选择 |
+|------|----------|
+| 刚开始学,项目小 | **原生 CSS**(先打好基础) |
+| 项目用 Bootstrap 5 | **SCSS**(Bootstrap 源码是 SCSS) |
+| 团队熟悉 `@` 符号 | **LESS**(和 CSS 的 `@media` 写法一致) |
+| 需要复杂逻辑(循环、条件) | **SCSS**(功能更强大) |
+
+#### 3.7.5 在项目中使用
+
+**Vite 项目(最简单)**:
+
+```bash
+# 安装 sass
+npm install -D sass
+
+# 直接使用 .scss 或 .less 文件
+```
::: tip 💡 新手建议
-1. **先学好原生 CSS**:预处理器只是"语法糖",本质还是 CSS
-2. **项目大了再用 SCSS**:小项目直接写 CSS 更简单
-3. **现代 CSS 已经支持变量**:`--primary-color: #3b82f6;` 原生就能用
+1. **先学好原生 CSS**:预处理器只是"语法糖",不懂 CSS 基础会越用越乱
+2. **小项目不用强上**:CSS 不到 200 行,直接写 CSS 更简单
+3. **从 SCSS 开始**:语法和 CSS 几乎一样,只是多了 `$` 变量
+4. **不要嵌套太深**:超过 3 层会让代码难维护
:::
+#### 3.7.6 不同技术栈的文件组织对比
+
+**同样的项目,用不同技术栈,文件结构有什么不同?**
+
+
+
+
+```
+my-website/
+├── index.html # 页面结构
+├── about.html
+├── css/
+│ ├── reset.css # 重置样式
+│ ├── layout.css # 布局样式
+│ ├── components.css # 组件样式
+│ └── style.css # 主样式(可能上千行)
+├── js/
+│ └── main.js
+└── images/
+ └── logo.png
+```
+
+**特点**:
+- CSS 集中在一个或几个文件
+- 改样式要来回切换 HTML 和 CSS 文件
+- 样式容易互相冲突
+
+
+
+
+```
+src/
+├── components/ # 组件文件夹
+│ ├── Button/
+│ │ ├── Button.vue # 模板 + 样式 + 逻辑
+│ │ └── Button.test.js
+│ ├── Header/
+│ │ └── Header.vue
+│ └── Footer/
+│ └── Footer.vue
+├── views/ # 页面文件夹
+│ ├── Home.vue
+│ └── About.vue
+├── App.vue # 根组件
+└── main.js # 入口文件
+```
+
+**Button.vue 内部结构**:
+```vue
+
+
+
+
+
+
+
+```
+
+
+
+
+```
+src/
+├── assets/
+│ └── styles/
+│ ├── _variables.scss # 变量:颜色、间距等
+│ ├── _mixins.scss # 混入:复用代码块
+│ ├── _functions.scss # 函数:颜色计算等
+│ └── global.scss # 全局样式入口
+├── components/
+│ ├── Button/
+│ │ └── Button.vue # 组件内用 @import 引入变量
+│ └── Card/
+│ └── Card.vue
+├── views/
+│ ├── Home.vue
+│ └── About.vue
+├── App.vue
+└── main.js
+```
+
+**_variables.scss**:
+```scss
+$primary: #3b82f6;
+$secondary: #64748b;
+$spacing-sm: 8px;
+$spacing-md: 16px;
+```
+
+**Button.vue**:
+```vue
+
+```
+
+
+
+
+```
+src/
+├── components/
+│ ├── Button.vue # 不需要 style 块
+│ ├── Card.vue
+│ └── Header.vue
+├── views/
+│ ├── Home.vue
+│ └── About.vue
+├── App.vue
+└── main.js
+
+# 配置文件(根目录)
+tailwind.config.js # 主题配置
+tailwind.css # 基础样式入口
+```
+
+**Button.vue**(没有 style 块):
+```vue
+
+
+
+```
+
+**特点**:
+- 没有单独的样式文件
+- 类名就是样式(`bg-blue-500` = 蓝色背景)
+- 配置集中在 `tailwind.config.js`
+
+
+
+
+**核心区别总结**:
+
+| 技术栈 | 样式文件位置 | 主题管理 | 代码复用 |
+|--------|-------------|----------|----------|
+| 原生 HTML+CSS | 集中式 `css/` 文件夹 | 搜索替换 | 复制粘贴 |
+| Vue + CSS | 分散在 `.vue` 组件内 | 搜索替换 | 复制粘贴 |
+| Vue + SCSS | 组件内 + `styles/` 公共文件 | 变量统一管理 | 混入复用 |
+| Vue + Tailwind | 无(类名里) | `tailwind.config.js` | 类名组合 |
+
### 3.8 如何记住这么多 CSS 属性?
::: tip 🎯 新手困惑
diff --git a/docs/zh-cn/appendix/4-server-and-backend/async-task-queues.md b/docs/zh-cn/appendix/4-server-and-backend/async-task-queues.md
index 241d581..84e9737 100644
--- a/docs/zh-cn/appendix/4-server-and-backend/async-task-queues.md
+++ b/docs/zh-cn/appendix/4-server-and-backend/async-task-queues.md
@@ -1,3 +1,151 @@
# 异步任务队列与生产消费模型
-> 待实现
+::: tip 前言
+**用户点了"导出报表"按钮,然后盯着转圈的加载动画等了 30 秒——这合理吗?** 当一个操作需要几秒甚至几分钟才能完成时,让用户干等着显然不是好体验。异步任务队列就是解决这个问题的核心架构模式——把耗时操作丢到后台去处理,让用户立刻得到响应。
+:::
+
+**这篇文章会带你学什么?**
+
+学完这章后,你将获得:
+
+- **同步异步对比**:理解为什么某些操作必须异步化,以及异步化带来的用户体验提升
+- **生产消费模型**:掌握 Producer-Consumer 模式的核心思想和工作流程
+- **Worker 池机制**:了解任务如何被分发到多个 Worker 并行处理
+- **可靠性保障**:掌握任务重试、幂等性、死信队列等保障机制
+- **技术选型能力**:了解主流异步任务框架的特点和适用场景
+
+| 章节 | 内容 | 核心概念 |
+|-----|------|---------|
+| **第 1 章** | 为什么需要异步 | 同步阻塞 vs 异步非阻塞 |
+| **第 2 章** | 生产消费模型 | Producer、Queue、Consumer |
+| **第 3 章** | Worker 工作池 | 并发处理、任务分发 |
+| **第 4 章** | 可靠性保障 | 重试策略、幂等性、死信队列 |
+| **第 5 章** | 框架选型 | Celery、Sidekiq、Bull、RQ |
+
+---
+
+## 0. 全景图:为什么不能让用户"干等着"?
+
+想象你去餐厅点餐。好的餐厅会在你点完餐后立刻给你一个取餐号,然后你可以去找座位、玩手机,等餐好了再来取。而不是让你站在柜台前,盯着厨师做完整道菜。
+
+Web 应用中有很多类似的"做菜"操作:
+
+- **发送邮件/短信**:调用第三方 API,可能需要几秒
+- **生成报表/PDF**:大量数据计算,可能需要几十秒
+- **图片/视频处理**:压缩、转码、加水印,可能需要几分钟
+- **数据同步**:跨系统数据同步,耗时不确定
+
+::: tip 异步任务的核心思想
+把耗时操作从"请求-响应"的主流程中剥离出来,放到后台队列中异步处理。用户提交请求后立刻得到"已收到,正在处理"的响应,处理完成后通过通知、轮询或 WebSocket 告知结果。
+:::
+
+---
+
+## 1. 同步 vs 异步:一个订单的故事
+
+当用户提交一个订单时,后端需要做很多事情:扣减库存、创建订单记录、发送确认邮件、更新推荐系统、记录审计日志……
+
+在同步模式下,这些操作串行执行,用户必须等所有操作完成才能看到结果。在异步模式下,只需要完成核心操作(扣减库存、创建订单),其余操作丢到队列里后台处理。
+
+
+
+| 对比维度 | 同步处理 | 异步处理 |
+|---------|---------|---------|
+| 用户等待时间 | 所有操作总耗时 | 仅核心操作耗时 |
+| 系统吞吐量 | 低(线程被阻塞) | 高(快速释放线程) |
+| 失败影响 | 非核心失败导致整体失败 | 非核心失败不影响主流程 |
+| 实现复杂度 | 简单 | 需要额外的队列基础设施 |
+| 数据一致性 | 强一致 | 最终一致 |
+
+::: tip 什么时候该用异步?
+三个判断标准:**耗时长**(超过 1-2 秒)、**非核心**(失败不应影响主流程)、**可延迟**(不需要立刻得到结果)。满足其中任意两个,就应该考虑异步化。
+:::
+
+---
+
+## 2. 生产消费模型:任务的"流水线"
+
+异步任务队列的核心是经典的 **生产者-消费者模式(Producer-Consumer Pattern)**。这个模式有三个角色:
+
+- **生产者(Producer)**:产生任务的一方,通常是 Web 服务器处理用户请求时
+- **队列(Queue)**:存储待处理任务的缓冲区,通常用 Redis、RabbitMQ 等实现
+- **消费者(Consumer/Worker)**:从队列中取出任务并执行的工作进程
+
+
+
+::: tip 队列的三大价值
+1. **解耦**:生产者不需要知道谁来处理任务,消费者不需要知道任务从哪来
+2. **削峰填谷**:突发流量时任务先堆积在队列中,消费者按自己的节奏处理
+3. **可靠性**:任务持久化在队列中,即使消费者崩溃也不会丢失
+:::
+
+| 组件 | 职责 | 常见实现 |
+|------|------|---------|
+| 消息中间件 | 存储和转发任务消息 | Redis、RabbitMQ、Kafka |
+| 序列化器 | 将任务参数序列化/反序列化 | JSON、MessagePack、Pickle |
+| 调度器 | 管理定时任务和延迟任务 | Cron、APScheduler、node-cron |
+| 结果存储 | 保存任务执行结果 | Redis、数据库、S3 |
+
+---
+
+## 3. 可靠性保障:任务不能"丢了"也不能"重复"
+
+在分布式环境中,网络抖动、服务重启、资源不足等问题随时可能发生。异步任务系统必须具备完善的可靠性保障机制。
+
+最核心的两个问题:**任务丢失**(消费者处理到一半崩溃了)和**重复执行**(任务被投递了两次)。
+
+
+
+::: tip 可靠性三板斧
+1. **ACK 机制**:消费者处理完任务后才发送确认(ACK),未确认的任务会被重新投递
+2. **重试策略**:任务失败后按策略重试,指数退避 + 抖动是最佳实践
+3. **幂等性设计**:同一个任务执行多次和执行一次的效果相同,通过唯一 ID 去重实现
+:::
+
+| 机制 | 解决的问题 | 实现方式 |
+|------|-----------|---------|
+| ACK 确认 | 任务丢失 | 处理完成后手动确认,超时未确认则重新投递 |
+| 死信队列(DLQ) | 反复失败的"毒消息" | 重试超过上限后转入死信队列,人工介入处理 |
+| 幂等性 | 重复执行 | 用任务唯一 ID 做去重,数据库唯一约束 |
+| 优先级队列 | 任务饥饿 | 高优先级任务优先处理,避免被低优先级任务阻塞 |
+| 超时控制 | 任务卡死 | 设置最大执行时间,超时自动终止并重试 |
+
+---
+
+## 4. 框架选型:选择适合你的工具
+
+不同语言生态有不同的异步任务框架,它们在功能丰富度、性能、易用性上各有侧重。选择框架时,首先考虑你的技术栈,然后根据项目规模和需求做决定。
+
+
+
+::: tip 选型建议
+- **Python 项目**:中大型用 Celery,小型用 RQ
+- **Node.js 项目**:首选 BullMQ(Bull 的下一代)
+- **Ruby 项目**:Sidekiq 几乎是唯一选择
+- **Java 项目**:Spring 生态用 Spring Batch,高吞吐用 Kafka Streams
+- **Go 项目**:Asynq(基于 Redis)或 Machinery
+
+如果你的项目已经在用 Redis,那么基于 Redis 的方案(Celery+Redis、BullMQ、Sidekiq)是最简单的起步方式。
+:::
+
+---
+
+## 总结
+
+异步任务队列是后端架构中不可或缺的基础设施。它让系统能够优雅地处理耗时操作,提升用户体验的同时提高系统吞吐量。
+
+回顾本章的关键要点:
+
+1. **异步化的判断标准**:耗时长、非核心、可延迟,满足两个就该异步化
+2. **生产消费模型**:Producer → Queue → Consumer,三者解耦协作
+3. **Worker 池**:多个 Worker 并行消费,提高处理能力
+4. **可靠性保障**:ACK 确认 + 重试策略 + 幂等性,三者缺一不可
+5. **框架选型**:根据技术栈和项目规模选择,Redis 是最常见的消息中间件
+
+## 延伸阅读
+
+- [Celery 官方文档](https://docs.celeryq.dev/) - Python 最流行的分布式任务队列
+- [BullMQ 文档](https://docs.bullmq.io/) - Node.js 高性能任务队列
+- [Sidekiq Wiki](https://github.com/sidekiq/sidekiq/wiki) - Ruby 生态的任务处理标杆
+- [RabbitMQ Tutorials](https://www.rabbitmq.com/tutorials) - 消息中间件入门教程
+- [异步任务最佳实践](https://brandur.org/job-drain) - 任务队列的设计模式与陷阱
diff --git a/docs/zh-cn/appendix/4-server-and-backend/backend-project-architecture.md b/docs/zh-cn/appendix/4-server-and-backend/backend-project-architecture.md
new file mode 100644
index 0000000..5ca5971
--- /dev/null
+++ b/docs/zh-cn/appendix/4-server-and-backend/backend-project-architecture.md
@@ -0,0 +1,751 @@
+# 后端项目架构设计
+
+::: tip 🎯 核心问题
+**API 越写越多,代码越来越乱,如何设计一个清晰、可维护的后端项目结构?** 这就像问:你是把所有工具都扔进一个抽屉,还是按功能分类整理?好的项目架构能让团队协作更高效,让系统扩展更轻松。
+:::
+
+---
+
+## 1. 为什么要关注后端项目架构?
+
+### 1.1 从小脚本到大系统的演变
+
+很多初学者刚开始写后端时,代码结构非常简单:
+
+```python
+# app.py - 所有代码在一个文件
+from flask import Flask, request, jsonify
+import sqlite3
+
+app = Flask(__name__)
+
+@app.route('/users', methods=['GET'])
+def get_users():
+ conn = sqlite3.connect('db.sqlite')
+ users = conn.execute('SELECT * FROM users').fetchall()
+ return jsonify(users)
+
+@app.route('/users', methods=['POST'])
+def create_user():
+ data = request.json
+ conn = sqlite3.connect('db.sqlite')
+ conn.execute('INSERT INTO users (name, email) VALUES (?, ?)',
+ (data['name'], data['email']))
+ conn.commit()
+ return jsonify({'message': 'User created'})
+
+# 还有订单、商品、支付...所有接口都在这个文件
+```
+
+几百行代码搞定一切,简单直接。但随着业务发展,问题开始出现:
+
+- **接口多了**:一个文件几千行,找代码像"考古"
+- **逻辑复杂了**:业务规则散落在各处,修改容易遗漏
+- **数据库操作重复**:到处写 SQL,改表结构要改几十处
+- **测试困难**:代码耦合严重,单元测试难以编写
+
+**问题的本质**:没有"章法",所有的逻辑都堆在一起,就像把所有的工具、零件、说明书都扔进一个抽屉。
+
+### 1.2 好的架构像整理好的车间
+
+想象一个整理好的工厂车间:
+
+| 区域 | 功能 | 特点 |
+|------|------|------|
+| **原料区** | 存放原材料 | 分类摆放,标签清晰 |
+| **加工区** | 生产加工 | 流水线作业,工序明确 |
+| **质检区** | 质量检查 | 统一标准,严格把关 |
+| **成品区** | 存放成品 | 整齐有序,易于出库 |
+| **工具室** | 存放工具 | 按需借用,用完归还 |
+
+**好的后端架构**就是把代码也这样组织:每一层只关心自己的职责,数据像流水一样在各层之间传递。
+
+::: tip 💡 通俗比喻:餐厅后厨的组织
+把后端系统想象成一家餐厅的后厨:
+
+- **`controllers/`(出餐口)** = 服务员接单:接收订单、核对信息、上菜
+- **`services/`(厨师团队)** = 厨师做菜:按照菜谱加工、协调各工序
+- **`repositories/`(仓库管理)** = 仓管取料:从仓库取食材、记录库存
+- **`models/`(菜谱标准)** = 菜谱定义:宫保鸡丁需要什么料、什么口味
+- **`utils/`(工具柜)** = 厨具存放:刀、勺、秤等通用工具
+
+**关键点**:每个角色职责明确,不会越界。服务员不会自己炒菜,厨师不会擅自改菜谱。
+:::
+
+---
+
+## 2. 经典分层架构详解
+
+### 2.1 四层架构(Controller-Service-Repository-Model)
+
+最经典的后端分层架构如下:
+
+```
+my-backend-project/
+├── src/
+│ ├── controllers/ # 控制器层(Controller)
+│ │ ├── userController.js
+│ │ ├── orderController.js
+│ │ └── index.js
+│ ├── services/ # 业务逻辑层(Service)
+│ │ ├── userService.js
+│ │ ├── orderService.js
+│ │ └── index.js
+│ ├── repositories/ # 数据访问层(Repository/DAO)
+│ │ ├── userRepository.js
+│ │ └── index.js
+│ ├── models/ # 数据模型层(Model/Entity)
+│ │ ├── user.js
+│ │ ├── order.js
+│ │ └── index.js
+│ ├── middlewares/ # 中间件
+│ │ ├── auth.js
+│ │ ├── errorHandler.js
+│ │ └── validator.js
+│ ├── utils/ # 工具函数
+│ │ ├── logger.js
+│ │ ├── response.js
+│ │ └── validator.js
+│ ├── config/ # 配置文件
+│ │ ├── database.js
+│ │ ├── redis.js
+│ │ └── index.js
+│ ├── routes/ # 路由定义
+│ │ ├── userRoutes.js
+│ │ ├── index.js
+│ │ └── api.js
+│ ├── jobs/ 或 workers/ # 定时任务/后台任务
+│ │ └── emailWorker.js
+│ ├── events/ 或 subscribers/ # 事件监听
+│ │ └── userEvents.js
+│ └── app.js # 应用入口
+├── tests/ # 测试文件
+│ ├── unit/
+│ ├── integration/
+│ └── e2e/
+├── migrations/ # 数据库迁移
+├── seeds/ # 种子数据
+├── docs/ # 文档
+├── .env # 环境变量
+├── package.json
+└── README.md
+```
+
+::: tip 📊 从图解中你能看到什么?
+**分层逻辑**:
+
+```
+┌─────────────────────────────────────────┐
+│ Controller 层(控制器层) │ ← 接待员:接收请求,返回响应
+│ - 接收 HTTP 请求 │
+│ - 参数校验、权限检查 │
+│ - 调用 Service │
+│ - 格式化响应 │
+├─────────────────────────────────────────┤
+│ Service 层(业务逻辑层) │ ← 厨师:处理核心业务
+│ - 业务逻辑编排 │
+│ - 事务管理 │
+│ - 调用 Repository │
+│ - 跨模块协调 │
+├─────────────────────────────────────────┤
+│ Repository 层(数据访问层) │ ← 仓管员:管理数据存取
+│ - 数据库操作 │
+│ - ORM 封装 │
+│ - 查询构建 │
+├─────────────────────────────────────────┤
+│ Model 层(数据模型层) │ ← 菜谱标准:定义数据结构
+│ - 实体定义(Entity) │
+│ - 类型定义 │
+│ - 业务规则验证 │
+└─────────────────────────────────────────┘
+```
+
+**依赖方向**:
+```
+Controller → Service → Repository → Model
+ ↓
+ Middleware / Utils
+```
+
+上层依赖下层,下层不依赖上层。Model 是核心,所有层都可能依赖它。
+:::
+
+### 2.2 各层职责详解
+
+#### Controller 层:请求的"接待员"
+
+Controller 是系统的"门面",负责接收 HTTP 请求并返回响应。
+
+**职责**:
+- 接收和解析请求参数
+- 调用相应的 Service 处理业务
+- 格式化响应数据
+- 处理 HTTP 相关逻辑(状态码、Header 等)
+
+**不应该做的事**:
+- 直接操作数据库
+- 编写复杂业务逻辑
+- 处理事务
+
+::: details 📝 Controller 代码示例(Node.js/Express)
+```javascript
+// controllers/userController.js
+const userService = require('../services/userService')
+const { success, error } = require('../utils/response')
+
+class UserController {
+ // 获取用户列表
+ async list(req, res) {
+ try {
+ const { page = 1, limit = 10 } = req.query
+ const users = await userService.getUsers({ page, limit })
+ return success(res, users)
+ } catch (err) {
+ return error(res, err.message, 500)
+ }
+ }
+
+ // 获取单个用户
+ async getById(req, res) {
+ try {
+ const { id } = req.params
+ const user = await userService.getUserById(id)
+ if (!user) {
+ return error(res, 'User not found', 404)
+ }
+ return success(res, user)
+ } catch (err) {
+ return error(res, err.message, 500)
+ }
+ }
+
+ // 创建用户
+ async create(req, res) {
+ try {
+ const userData = req.body
+ const newUser = await userService.createUser(userData)
+ return success(res, newUser, 201)
+ } catch (err) {
+ return error(res, err.message, 400)
+ }
+ }
+}
+
+module.exports = new UserController()
+```
+:::
+
+#### Service 层:业务的"厨师"
+
+Service 是系统的"大脑",包含核心业务逻辑。
+
+**职责**:
+- 实现业务规则和流程
+- 协调多个 Repository 完成复杂操作
+- 管理事务
+- 数据转换和计算
+
+**不应该做的事**:
+- 直接处理 HTTP 请求/响应
+- 直接操作数据库(通过 Repository)
+
+::: details 📝 Service 代码示例
+```javascript
+// services/userService.js
+const userRepository = require('../repositories/userRepository')
+const orderRepository = require('../repositories/orderRepository')
+const emailService = require('./emailService')
+const { hashPassword } = require('../utils/crypto')
+
+class UserService {
+ // 获取用户列表
+ async getUsers({ page, limit }) {
+ const offset = (page - 1) * limit
+ const [users, total] = await Promise.all([
+ userRepository.findAll({ limit, offset }),
+ userRepository.count()
+ ])
+
+ return {
+ data: users,
+ pagination: {
+ page,
+ limit,
+ total,
+ totalPages: Math.ceil(total / limit)
+ }
+ }
+ }
+
+ // 获取用户详情(包含订单信息)
+ async getUserById(id) {
+ const user = await userRepository.findById(id)
+ if (!user) return null
+
+ // 获取用户订单统计
+ const orderStats = await orderRepository.getStatsByUserId(id)
+
+ return {
+ ...user,
+ orderStats
+ }
+ }
+
+ // 创建用户(包含事务和邮件通知)
+ async createUser(userData) {
+ // 检查邮箱是否已存在
+ const existingUser = await userRepository.findByEmail(userData.email)
+ if (existingUser) {
+ throw new Error('Email already exists')
+ }
+
+ // 密码加密
+ const hashedPassword = await hashPassword(userData.password)
+
+ // 创建用户
+ const newUser = await userRepository.create({
+ ...userData,
+ password: hashedPassword
+ })
+
+ // 发送欢迎邮件(异步,不阻塞)
+ emailService.sendWelcomeEmail(newUser.email).catch(console.error)
+
+ return newUser
+ }
+}
+
+module.exports = new UserService()
+```
+:::
+
+#### Repository 层:数据的"仓管员"
+
+Repository 负责所有与数据存储相关的操作。
+
+**职责**:
+- 数据库的增删改查
+- ORM 映射
+- 查询优化
+
+**不应该做的事**:
+- 包含业务逻辑
+- 处理事务(由 Service 控制)
+
+::: details 📝 Repository 代码示例
+```javascript
+// repositories/userRepository.js
+const { User } = require('../models')
+
+class UserRepository {
+ // 查询所有用户
+ async findAll({ limit, offset }) {
+ return await User.findAll({
+ limit,
+ offset,
+ attributes: { exclude: ['password'] } // 不返回密码
+ })
+ }
+
+ // 根据 ID 查询
+ async findById(id) {
+ return await User.findByPk(id, {
+ attributes: { exclude: ['password'] }
+ })
+ }
+
+ // 根据邮箱查询
+ async findByEmail(email) {
+ return await User.findOne({ where: { email } })
+ }
+
+ // 创建用户
+ async create(data) {
+ return await User.create(data)
+ }
+
+ // 更新用户
+ async update(id, data) {
+ const user = await User.findByPk(id)
+ if (!user) return null
+ return await user.update(data)
+ }
+
+ // 删除用户
+ async delete(id) {
+ const user = await User.findByPk(id)
+ if (!user) return null
+ await user.destroy()
+ return true
+ }
+
+ // 统计用户数量
+ async count() {
+ return await User.count()
+ }
+}
+
+module.exports = new UserRepository()
+```
+:::
+
+#### Model 层:数据的"定义"
+
+Model 定义数据结构和业务规则。
+
+::: details 📝 Model 代码示例(Sequelize)
+```javascript
+// models/user.js
+const { DataTypes } = require('sequelize')
+const { sequelize } = require('../config/database')
+
+const User = sequelize.define('User', {
+ id: {
+ type: DataTypes.UUID,
+ defaultValue: DataTypes.UUIDV4,
+ primaryKey: true
+ },
+ name: {
+ type: DataTypes.STRING(100),
+ allowNull: false,
+ validate: {
+ len: [2, 100]
+ }
+ },
+ email: {
+ type: DataTypes.STRING(255),
+ allowNull: false,
+ unique: true,
+ validate: {
+ isEmail: true
+ }
+ },
+ password: {
+ type: DataTypes.STRING(255),
+ allowNull: false
+ },
+ status: {
+ type: DataTypes.ENUM('active', 'inactive', 'banned'),
+ defaultValue: 'active'
+ }
+}, {
+ tableName: 'users',
+ timestamps: true, // 自动添加 createdAt 和 updatedAt
+ indexes: [
+ { fields: ['email'] },
+ { fields: ['status'] }
+ ]
+})
+
+module.exports = User
+```
+:::
+
+---
+
+## 3. 其他重要目录
+
+### 3.1 `middlewares/` 中间件
+
+中间件是请求处理流程中的"过滤器"。
+
+```
+middlewares/
+├── auth.js # 认证中间件
+├── errorHandler.js # 错误处理
+├── validator.js # 参数校验
+├── rateLimiter.js # 限流
+├── logger.js # 请求日志
+└── cors.js # 跨域处理
+```
+
+::: details 📝 中间件示例
+```javascript
+// middlewares/auth.js
+const jwt = require('jsonwebtoken')
+
+const authMiddleware = (req, res, next) => {
+ const token = req.headers.authorization?.split(' ')[1]
+
+ if (!token) {
+ return res.status(401).json({ message: 'No token provided' })
+ }
+
+ try {
+ const decoded = jwt.verify(token, process.env.JWT_SECRET)
+ req.user = decoded
+ next()
+ } catch (err) {
+ return res.status(401).json({ message: 'Invalid token' })
+ }
+}
+
+module.exports = authMiddleware
+```
+:::
+
+### 3.2 `routes/` 路由
+
+集中管理所有 API 路由。
+
+```javascript
+// routes/userRoutes.js
+const express = require('express')
+const router = express.Router()
+const userController = require('../controllers/userController')
+const authMiddleware = require('../middlewares/auth')
+
+// 公开路由
+router.get('/', userController.list)
+router.get('/:id', userController.getById)
+
+// 需要认证的路由
+router.post('/', authMiddleware, userController.create)
+router.put('/:id', authMiddleware, userController.update)
+router.delete('/:id', authMiddleware, userController.delete)
+
+module.exports = router
+```
+
+```javascript
+// routes/index.js
+const express = require('express')
+const router = express.Router()
+
+router.use('/users', require('./userRoutes'))
+router.use('/orders', require('./orderRoutes'))
+router.use('/products', require('./productRoutes'))
+
+module.exports = router
+```
+
+### 3.3 `config/` 配置
+
+集中管理所有配置,支持多环境。
+
+```javascript
+// config/index.js
+const env = process.env.NODE_ENV || 'development'
+
+const configs = {
+ development: {
+ port: 3000,
+ database: {
+ host: 'localhost',
+ port: 5432,
+ name: 'myapp_dev'
+ },
+ redis: {
+ host: 'localhost',
+ port: 6379
+ }
+ },
+ production: {
+ port: process.env.PORT || 80,
+ database: {
+ host: process.env.DB_HOST,
+ port: process.env.DB_PORT,
+ name: process.env.DB_NAME
+ }
+ }
+}
+
+module.exports = configs[env]
+```
+
+### 3.4 `utils/` 工具
+
+```
+utils/
+├── logger.js # 日志工具
+├── response.js # 响应封装
+├── crypto.js # 加密解密
+├── date.js # 日期处理
+└── validator.js # 验证工具
+```
+
+---
+
+## 4. 按功能组织(Feature-based)
+
+对于中大型项目,可以采用按功能组织的方式:
+
+```
+src/
+├── features/
+│ ├── users/
+│ │ ├── users.controller.js
+│ │ ├── users.service.js
+│ │ ├── users.repository.js
+│ │ ├── users.model.js
+│ │ ├── users.routes.js
+│ │ ├── users.validator.js
+│ │ └── index.js # 统一导出
+│ ├── orders/
+│ │ ├── orders.controller.js
+│ │ ├── orders.service.js
+│ │ └── ...
+│ └── products/
+│ ├── products.controller.js
+│ └── ...
+├── shared/ # 共享资源
+│ ├── middlewares/
+│ ├── utils/
+│ └── config/
+└── app.js
+```
+
+**优点**:
+- 高内聚,一个功能的所有代码在一起
+- 便于团队协作,不同人负责不同 feature
+- 易于删除或重构
+
+---
+
+## 5. 知名开源项目的架构参考
+
+### 5.1 Express.js 官方示例
+
+```
+express-example/
+├── bin/ # 启动脚本
+├── public/ # 静态资源
+├── routes/ # 路由
+├── views/ # 视图模板
+├── app.js # 应用配置
+└── package.json
+```
+
+**特点**:简单直接,适合小型项目。
+
+### 5.2 NestJS(企业级 Node.js 框架)
+
+```
+nestjs-project/
+├── src/
+│ ├── modules/ # 功能模块
+│ │ ├── users/
+│ │ │ ├── users.controller.ts
+│ │ │ ├── users.service.ts
+│ │ │ ├── users.module.ts
+│ │ │ └── dto/
+│ │ └── orders/
+│ ├── common/ # 共享模块
+│ ├── config/ # 配置
+│ └── main.ts # 入口
+```
+
+**特点**:
+- 强制模块化结构
+- 内置依赖注入
+- 适合大型项目
+
+### 5.3 Django(Python)
+
+```
+django-project/
+├── project_name/ # 项目配置
+├── apps/
+│ ├── users/ # 用户应用
+│ │ ├── models.py
+│ │ ├── views.py
+│ │ ├── serializers.py
+│ │ └── urls.py
+│ └── orders/ # 订单应用
+├── templates/
+├── static/
+└── manage.py
+```
+
+**特点**:
+- 约定优于配置
+- MTV(Model-Template-View)模式
+- 应用可复用
+
+### 5.4 Spring Boot(Java)
+
+```
+spring-boot-project/
+├── src/main/java/
+│ └── com/example/
+│ ├── controller/
+│ ├── service/
+│ ├── repository/
+│ ├── entity/
+│ ├── dto/
+│ ├── config/
+│ └── Application.java
+├── src/main/resources/
+│ ├── application.yml
+│ └── mapper/
+└── src/test/
+```
+
+**特点**:
+- 严格的分层架构
+- 注解驱动开发
+- 强大的生态
+
+---
+
+## 6. 架构设计原则与检查清单
+
+### 6.1 核心原则
+
+| 原则 | 说明 | 实践建议 |
+|------|------|----------|
+| **单一职责** | 一个模块只做一件事 | Controller 只处理 HTTP,Service 只处理业务 |
+| **依赖倒置** | 依赖抽象而非具体实现 | 使用接口/抽象类 |
+| **开闭原则** | 对扩展开放,对修改关闭 | 新增功能不修改原有代码 |
+| **DRY** | 不要重复自己 | 提取公共逻辑到 utils 或基类 |
+| **KISS** | 保持简单 | 不要过度设计 |
+
+### 6.2 检查清单
+
+**分层检查**:
+- [ ] Controller 是否只处理 HTTP 相关逻辑?
+- [ ] Service 是否包含核心业务逻辑?
+- [ ] Repository 是否只负责数据访问?
+- [ ] 层与层之间是否通过明确的接口交互?
+
+**代码质量**:
+- [ ] 是否有统一的错误处理机制?
+- [ ] 是否使用环境变量管理配置?
+- [ ] 是否有日志记录?
+- [ ] 是否编写了单元测试?
+
+**安全**:
+- [ ] 敏感配置是否放入环境变量?
+- [ ] 是否有输入验证?
+- [ ] 是否有认证和授权?
+- [ ] 密码是否加密存储?
+
+---
+
+## 7. 总结
+
+::: tip 💡 核心思想
+好的后端架构应该像一家组织良好的餐厅:
+
+- **分工明确**:每个角色知道自己的职责
+- **流程清晰**:数据像流水一样在各层之间传递
+- **易于扩展**:新增功能不会破坏现有结构
+- **便于测试**:各层可以独立测试
+
+**记住这几点**:
+1. **分层是手段,不是目的**:不要为了分层而分层
+2. **按功能组织**:中大型项目推荐 Feature-based
+3. **统一约定**:命名、结构、错误处理保持一致
+4. **持续重构**:定期审视架构,及时调整
+
+**最终目标**:让代码像整理好的车间一样,想找什么立刻能找到,新功能容易添加,旧代码容易维护。
+:::
+
+---
+
+## 参考资源
+
+- [NestJS 文档](https://docs.nestjs.com/)
+- [Express 最佳实践](https://expressjs.com/en/advanced/best-practice-security.html)
+- [Bulletproof Node.js](https://github.com/santiq/bulletproof-nodejs)
+- [Clean Architecture](https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html)
diff --git a/docs/zh-cn/appendix/4-server-and-backend/file-storage.md b/docs/zh-cn/appendix/4-server-and-backend/file-storage.md
index d2181a8..9507669 100644
--- a/docs/zh-cn/appendix/4-server-and-backend/file-storage.md
+++ b/docs/zh-cn/appendix/4-server-and-backend/file-storage.md
@@ -1,3 +1,162 @@
# 文件存储与对象存储
-> 待实现
+::: tip 前言
+**用户上传了一张头像,你把它存在服务器的 `/uploads` 目录下——然后服务器磁盘满了,或者你加了第二台服务器,用户发现头像时有时无。** 文件存储看似简单,但在分布式环境下却是一个需要认真对待的架构问题。对象存储就是互联网时代解决这个问题的标准答案。
+:::
+
+**这篇文章会带你学什么?**
+
+学完这章后,你将获得:
+
+- **存储类型认知**:理解块存储、文件存储、对象存储的区别和适用场景
+- **对象存储核心概念**:掌握 Bucket、Object、Key、Pre-signed URL 等核心概念
+- **上传方案设计**:学会客户端直传 vs 服务端中转的方案选型
+- **CDN 加速原理**:理解 CDN 如何加速静态资源的全球分发
+- **最佳实践**:掌握文件命名、权限控制、生命周期管理等实战技巧
+
+| 章节 | 内容 | 核心概念 |
+|-----|------|---------|
+| **第 1 章** | 存储类型对比 | 块存储、文件存储、对象存储 |
+| **第 2 章** | 对象存储核心概念 | Bucket、Object、Key、元数据 |
+| **第 3 章** | 文件上传方案 | 客户端直传、Pre-signed URL |
+| **第 4 章** | CDN 加速 | 边缘节点、缓存策略、回源 |
+| **第 5 章** | 最佳实践 | 命名规范、权限、生命周期 |
+
+---
+
+## 0. 全景图:为什么不能把文件存在服务器本地?
+
+刚开始做项目时,把用户上传的文件存在服务器本地目录是最直觉的做法。但随着项目发展,你会遇到一系列问题:
+
+- **磁盘空间有限**:服务器磁盘总会满,扩容麻烦
+- **多服务器不共享**:负载均衡后,用户请求可能打到不同服务器,文件找不到
+- **没有备份**:服务器挂了,文件就丢了
+- **没有 CDN**:全球用户访问同一台服务器,速度慢
+
+::: tip 对象存储的核心价值
+对象存储(如 AWS S3、阿里云 OSS)解决了所有这些问题:**容量无限、全球可访问、自动备份、天然支持 CDN**。它已经成为互联网应用存储文件的事实标准。
+:::
+
+---
+
+## 1. 存储类型对比:块、文件、对象
+
+计算机世界有三种主要的存储方式,它们解决不同层次的问题。
+
+
+
+| 维度 | 块存储 | 文件存储 | 对象存储 |
+|------|--------|---------|---------|
+| 数据单位 | 固定大小的块 | 文件 + 目录 | 对象(Key-Value) |
+| 访问协议 | iSCSI/FC | NFS/SMB | HTTP REST API |
+| 性能 | 最高(毫秒级) | 中等 | 较低(但够用) |
+| 扩展性 | 有限 | 中等 | 近乎无限 |
+| 成本 | 最高 | 中等 | 最低 |
+| 典型场景 | 数据库 | 共享文件 | 图片/视频/备份 |
+
+::: tip 简单记忆
+- **块存储**像硬盘——给数据库用
+- **文件存储**像网络共享文件夹——给多台服务器共享配置用
+- **对象存储**像网盘——给用户上传的图片、视频用
+:::
+
+---
+
+## 2. 对象存储核心概念
+
+对象存储的数据模型非常简单:**Bucket(桶)** 是容器,**Object(对象)** 是文件,每个对象通过唯一的 **Key(键)** 来标识。
+
+```
+my-app-bucket/ ← Bucket(桶)
+├── avatars/user-123.jpg ← Object Key
+├── avatars/user-456.png ← Object Key
+├── reports/2024/q1-report.pdf ← Object Key("目录"只是 Key 的前缀)
+└── uploads/temp/file.zip ← Object Key
+```
+
+| 概念 | 说明 | 示例 |
+|------|------|------|
+| Bucket | 存储容器,全局唯一命名 | `my-app-prod`、`company-assets` |
+| Object | 存储的文件本体 + 元数据 | 一张图片、一个 PDF |
+| Key | 对象的唯一标识符 | `avatars/user-123.jpg` |
+| 元数据 | 对象的附加信息 | Content-Type、自定义标签 |
+| ACL | 访问控制列表 | public-read、private |
+| Pre-signed URL | 临时授权访问链接 | 有效期 15 分钟的上传/下载链接 |
+
+::: tip 对象存储没有真正的"目录"
+`avatars/user-123.jpg` 中的 `avatars/` 不是目录,只是 Key 的前缀。对象存储是扁平结构,所有对象在同一层级。控制台显示的"文件夹"只是按前缀分组的视觉效果。
+:::
+
+---
+
+## 3. 文件上传方案:谁来传文件?
+
+文件上传有两种主流方案:服务端中转和客户端直传。对于大多数场景,**客户端直传**是更优的选择。
+
+
+
+::: tip 客户端直传的优势
+1. **节省服务器带宽**:文件不经过你的服务器,直接到 OSS
+2. **避免超时**:大文件上传不会触发 Nginx/网关的超时限制
+3. **降低服务器负载**:服务器只需要签发凭证,不需要处理文件流
+4. **支持断点续传**:OSS 原生支持分片上传,前端可以实现断点续传
+
+实现步骤:前端请求后端获取 Pre-signed URL → 前端用这个 URL 直接上传到 OSS → OSS 回调通知后端
+:::
+
+---
+
+## 4. CDN 加速:让全球用户都快
+
+当你的用户遍布全球时,从单一源站下载文件会很慢。CDN(Content Delivery Network)通过在全球部署边缘节点,将文件缓存到离用户最近的节点,大幅降低访问延迟。
+
+
+
+| CDN 概念 | 说明 |
+|---------|------|
+| 边缘节点 | 分布在全球各地的缓存服务器 |
+| 回源 | 边缘节点没有缓存时,向源站请求文件 |
+| 缓存命中率 | 请求被边缘节点直接响应的比例,越高越好 |
+| TTL | 缓存有效期,过期后需要重新回源 |
+| 缓存刷新 | 主动清除边缘节点的缓存,让新文件生效 |
+
+::: tip CDN 最佳实践
+- **文件名加 hash**:`logo.a3f2b1.png` 而不是 `logo.png`,这样更新文件时不需要刷新缓存
+- **设置合理的 TTL**:静态资源(JS/CSS/图片)设长 TTL(1年),HTML 设短 TTL(5分钟)
+- **开启 Gzip/Brotli 压缩**:文本类资源压缩后体积减少 60-80%
+:::
+
+---
+
+## 5. 最佳实践
+
+| 实践 | 说明 | 示例 |
+|------|------|------|
+| Key 命名规范 | 用有意义的前缀组织文件 | `{type}/{date}/{uuid}.{ext}` |
+| 避免热点 Key | 不要用递增数字开头 | 用 UUID 或 hash 前缀 |
+| 权限最小化 | Bucket 默认 private | 只对需要公开的文件设置 public-read |
+| 生命周期规则 | 自动清理过期文件 | 临时文件 7 天后自动删除 |
+| 跨域配置 | 前端直传需要配置 CORS | 允许你的域名 PUT/POST |
+| 服务端加密 | 敏感文件开启 SSE | SSE-S3 或 SSE-KMS |
+
+---
+
+## 总结
+
+文件存储是每个 Web 应用都会遇到的基础问题。对象存储以其无限容量、低成本、高可用的特性,成为了互联网应用的标准选择。
+
+回顾本章的关键要点:
+
+1. **三种存储类型**:块存储给数据库、文件存储给共享、对象存储给用户文件
+2. **对象存储模型**:Bucket + Key + Object,扁平结构,HTTP API 访问
+3. **客户端直传**:Pre-signed URL 方案,文件不经过服务器,高效省资源
+4. **CDN 加速**:边缘节点缓存 + 文件名 hash,让全球用户都快
+5. **安全与管理**:权限最小化、生命周期规则、服务端加密
+
+## 延伸阅读
+
+- [AWS S3 开发者指南](https://docs.aws.amazon.com/s3/) - 对象存储的标杆文档
+- [阿里云 OSS 最佳实践](https://help.aliyun.com/document_detail/31853.html) - 国内最常用的对象存储
+- [MinIO 文档](https://min.io/docs/minio/linux/index.html) - 开源的 S3 兼容对象存储
+- [Cloudflare R2](https://developers.cloudflare.com/r2/) - 零出口费用的对象存储
+- [Pre-signed URL 详解](https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-presigned-url.html) - 客户端直传的核心机制
diff --git a/docs/zh-cn/appendix/4-server-and-backend/rate-limiting-backpressure.md b/docs/zh-cn/appendix/4-server-and-backend/rate-limiting-backpressure.md
index 25b3ea5..e11cbc4 100644
--- a/docs/zh-cn/appendix/4-server-and-backend/rate-limiting-backpressure.md
+++ b/docs/zh-cn/appendix/4-server-and-backend/rate-limiting-backpressure.md
@@ -1,3 +1,131 @@
# 限流与背压控制
-> 待实现
+::: tip 前言
+**双十一零点,几亿用户同时涌入——服务器扛得住吗?** 任何系统都有处理能力的上限。当请求量超过系统承载能力时,如果不加控制,结果就是所有人都用不了。限流和背压就是保护系统不被"压垮"的两道防线。
+:::
+
+**这篇文章会带你学什么?**
+
+学完这章后,你将获得:
+
+- **限流必要性**:理解为什么需要主动拒绝部分请求来保护系统
+- **限流算法**:掌握令牌桶、漏桶、滑动窗口三种核心算法的原理和差异
+- **背压机制**:理解当上游速度超过下游时的处理策略
+- **多层限流**:了解从客户端到网关到服务的多层限流架构
+- **实战能力**:知道在什么场景下选择什么限流策略
+
+| 章节 | 内容 | 核心概念 |
+|-----|------|---------|
+| **第 1 章** | 为什么需要限流 | 雪崩效应、服务保护 |
+| **第 2 章** | 限流算法 | 令牌桶、漏桶、滑动窗口 |
+| **第 3 章** | 背压控制 | 缓冲区、丢弃策略、弹性扩容 |
+| **第 4 章** | 多层限流架构 | 客户端、网关、服务端 |
+| **第 5 章** | 实战与选型 | Nginx、Redis、Sentinel |
+
+---
+
+## 0. 全景图:为什么要"拒绝"用户?
+
+这听起来很反直觉——我们不是应该服务好每一个用户吗?但现实是:**不拒绝一部分请求,所有请求都会失败**。
+
+想象一个只能坐 100 人的餐厅,突然涌进来 1000 人。如果不限流,结果不是 1000 人都能吃上饭,而是厨房崩溃、服务员瘫痪,1000 人谁都吃不上。正确的做法是在门口排队限流,让 100 人先进去,其余人等候。
+
+::: tip 限流的核心目标
+- **保护系统**:防止过载导致服务完全不可用
+- **公平分配**:确保已接受的请求能正常处理
+- **优雅降级**:被限流的请求收到明确的 429 状态码,而不是超时或 500 错误
+:::
+
+---
+
+## 1. 限流算法:三种经典方案
+
+限流的核心问题是:**在单位时间内,最多允许多少个请求通过?** 不同的算法在精确度、突发流量处理、实现复杂度上各有取舍。
+
+
+
+| 算法 | 原理 | 突发流量 | 精确度 | 实现复杂度 |
+|------|------|---------|--------|-----------|
+| 令牌桶 | 固定速率放令牌,请求消耗令牌 | 允许(桶中有存量) | 高 | 中 |
+| 漏桶 | 请求排队,固定速率处理 | 不允许(完全平滑) | 高 | 中 |
+| 滑动窗口 | 统计窗口内请求数 | 部分允许 | 较高 | 低 |
+| 固定窗口 | 按时间窗口计数 | 边界处可能突发 | 低 | 最低 |
+
+::: tip 选哪个算法?
+- **API 限流**:令牌桶最常用,允许合理的突发流量
+- **流量整形**:漏桶适合需要恒定输出速率的场景
+- **简单计数**:滑动窗口实现简单,适合大多数 Web 应用
+:::
+
+---
+
+## 2. 背压控制:当上游比下游快
+
+限流解决的是"外部请求太多"的问题,而**背压(Backpressure)**解决的是"内部组件速度不匹配"的问题。
+
+当生产者产生数据的速度持续超过消费者处理数据的速度时,中间的缓冲区会不断膨胀,最终导致内存溢出或数据丢失。背压机制就是让消费者能够"反向通知"生产者减速。
+
+
+
+::: tip 背压的四种策略
+1. **丢弃(Drop)**:缓冲区满时丢弃新数据或旧数据,适合实时性要求高但允许丢失的场景
+2. **阻塞(Block)**:让生产者暂停,等消费者处理完再继续,适合数据不能丢失的场景
+3. **采样(Sample)**:只处理部分数据,适合高频数据流
+4. **弹性扩容(Scale)**:动态增加消费者数量,适合云原生环境
+:::
+
+---
+
+## 3. 多层限流架构
+
+生产环境中,限流不是在某一个点做就够了,而是需要**多层防护**,每一层解决不同粒度的问题。
+
+| 层级 | 位置 | 限流粒度 | 工具 |
+|------|------|---------|------|
+| 客户端 | 前端/App | 按钮防抖、请求节流 | lodash.throttle、debounce |
+| CDN/WAF | 边缘节点 | IP 级别、地域级别 | Cloudflare Rate Limiting |
+| API 网关 | 入口网关 | 路由级别、用户级别 | Nginx limit_req、Kong |
+| 服务端 | 应用内部 | 接口级别、资源级别 | Sentinel、Resilience4j |
+| 数据库 | 存储层 | 连接数、QPS | 连接池配置、慢查询熔断 |
+
+::: tip 限流的 HTTP 规范
+被限流的请求应该返回 `429 Too Many Requests` 状态码,并在响应头中包含:
+- `Retry-After`: 建议客户端多久后重试(秒数或日期)
+- `X-RateLimit-Limit`: 限流上限
+- `X-RateLimit-Remaining`: 剩余配额
+- `X-RateLimit-Reset`: 配额重置时间
+:::
+
+---
+
+## 4. 实战选型
+
+| 场景 | 推荐方案 | 说明 |
+|------|---------|------|
+| Nginx 入口限流 | `limit_req_zone` | 基于漏桶算法,配置简单 |
+| 分布式限流 | Redis + Lua 脚本 | 令牌桶或滑动窗口,多实例共享计数 |
+| Java 微服务 | Sentinel / Resilience4j | 支持熔断、降级、热点限流 |
+| Node.js API | express-rate-limit | 简单易用,支持 Redis 存储 |
+| Go 服务 | golang.org/x/time/rate | 标准库令牌桶实现 |
+
+---
+
+## 总结
+
+限流和背压是保护系统稳定性的两道关键防线。限流控制外部流量的涌入速度,背压协调内部组件的处理速度。
+
+回顾本章的关键要点:
+
+1. **限流的必要性**:不拒绝部分请求,所有请求都会失败
+2. **三种核心算法**:令牌桶(允许突发)、漏桶(完全平滑)、滑动窗口(简单精确)
+3. **背压机制**:丢弃、阻塞、采样、扩容四种策略
+4. **多层防护**:从客户端到数据库,每层解决不同粒度的问题
+5. **429 规范**:被限流时返回标准状态码和限流头信息
+
+## 延伸阅读
+
+- [Stripe 的限流实践](https://stripe.com/blog/rate-limiters) - 支付系统的限流设计
+- [Nginx limit_req 文档](https://nginx.org/en/docs/http/ngx_http_limit_req_module.html) - Nginx 限流模块
+- [Alibaba Sentinel](https://sentinelguard.io/) - 面向分布式服务的流量控制组件
+- [Resilience4j](https://resilience4j.readme.io/) - Java 轻量级容错库
+- [Token Bucket 算法详解](https://en.wikipedia.org/wiki/Token_bucket) - 令牌桶算法的数学原理
diff --git a/docs/zh-cn/appendix/4-server-and-backend/request-journey.md b/docs/zh-cn/appendix/4-server-and-backend/request-journey.md
index 5e4d9f2..54c4397 100644
--- a/docs/zh-cn/appendix/4-server-and-backend/request-journey.md
+++ b/docs/zh-cn/appendix/4-server-and-backend/request-journey.md
@@ -1,3 +1,295 @@
# 一个请求的完整旅程
-> 待实现
+::: tip 前言
+**当你在浏览器里输入一个网址按下回车,到页面显示出来,中间到底发生了什么?** 这个问题是面试经典题,更是理解整个 Web 架构的钥匙。搞懂这条链路,你就能理解前端、后端、网络、数据库是怎么协作的。
+:::
+
+**这篇文章会带你学什么?**
+
+学完这章后,你将获得:
+
+- **全链路视角**:理解一个 HTTP 请求从发出到返回的完整过程
+- **各层职责认知**:DNS、TCP、负载均衡、Web 服务器、应用服务器、数据库各自做什么
+- **问题定位能力**:请求慢或失败时,知道从哪一层开始排查
+- **性能优化思路**:每一层都有优化空间,知道优化点在哪里
+
+| 章节 | 内容 | 核心概念 |
+|-----|------|---------|
+| **第 1 章** | 浏览器发起请求 | DNS 解析、TCP 连接、HTTP 请求 |
+| **第 2 章** | 网络传输 | 路由、CDN、负载均衡 |
+| **第 3 章** | 服务器处理 | Web 服务器、应用逻辑、数据库查询 |
+| **第 4 章** | 响应返回 | 序列化、压缩、渲染 |
+| **第 5 章** | 全链路优化 | 缓存、连接复用、异步处理 |
+
+---
+
+## 0. 全景图:一个请求经历了什么?
+
+用一个比喻来理解:你在网上下单买书,这个过程和 HTTP 请求惊人地相似。
+
+| 请求阶段 | 买书类比 | 技术对应 |
+|---------|---------|---------|
+| 输入网址 | 你说"我要去某某书店" | 浏览器解析 URL |
+| DNS 解析 | 查地图找到书店地址 | 域名 → IP 地址 |
+| TCP 连接 | 走到书店门口,推门进去 | 三次握手建立连接 |
+| 发送请求 | 告诉店员"我要《xxx》这本书" | HTTP 请求报文 |
+| 服务器处理 | 店员去仓库找书、查库存、算价格 | 应用逻辑 + 数据库查询 |
+| 返回响应 | 店员把书递给你 | HTTP 响应报文 |
+| 浏览器渲染 | 你打开书开始阅读 | HTML/CSS/JS 解析渲染 |
+
+
+
+---
+
+## 1. 浏览器发起请求
+
+### 1.1 URL 解析
+
+当你输入 `https://api.example.com/books?id=123` 时,浏览器会把它拆解成几个部分:
+
+| 部分 | 值 | 含义 |
+|-----|-----|------|
+| 协议 | `https` | 用加密方式通信 |
+| 域名 | `api.example.com` | 服务器的"名字" |
+| 路径 | `/books` | 要访问的资源 |
+| 查询参数 | `id=123` | 附加条件 |
+
+### 1.2 DNS 解析:域名 → IP 地址
+
+计算机不认识域名,只认识 IP 地址(如 `93.184.216.34`)。DNS 就是互联网的"电话簿"。
+
+```
+浏览器缓存 → 系统缓存 → 路由器缓存 → ISP DNS → 根域名服务器
+ ↓ 命中就直接用,不命中就往下查
+```
+
+::: tip DNS 缓存的意义
+如果每次请求都从根域名服务器查起,全球互联网会被 DNS 查询压垮。所以每一层都有缓存,大部分请求在浏览器或系统层就能解析完成。
+:::
+
+### 1.3 TCP 三次握手
+
+找到 IP 地址后,浏览器需要和服务器"建立连接"。TCP 用三次握手确保双方都准备好了:
+
+```
+客户端 → 服务器:你好,我想连接(SYN)
+服务器 → 客户端:好的,我准备好了(SYN + ACK)
+客户端 → 服务器:收到,开始通信(ACK)
+```
+
+如果是 HTTPS,还需要额外的 TLS 握手来协商加密方式。
+
+### 1.4 发送 HTTP 请求
+
+连接建立后,浏览器发送 HTTP 请求报文:
+
+```http
+GET /books?id=123 HTTP/1.1
+Host: api.example.com
+Accept: application/json
+Authorization: Bearer eyJhbGci...
+User-Agent: Chrome/120.0
+```
+
+| 组成部分 | 内容 |
+|---------|------|
+| 请求行 | 方法(GET)+ 路径 + 协议版本 |
+| 请求头 | 元信息:身份认证、期望的数据格式等 |
+| 请求体 | POST/PUT 请求才有,携带要提交的数据 |
+
+---
+
+## 2. 网络传输:请求在路上
+
+### 2.1 路由转发
+
+请求离开你的电脑后,会经过多个路由器的转发,就像快递经过多个中转站:
+
+```
+你的电脑 → 家庭路由器 → 运营商网络 → 骨干网 → 目标机房
+```
+
+每个路由器根据 IP 地址决定"下一跳"往哪里转发。可以用 `traceroute` 命令查看请求经过了哪些节点。
+
+### 2.2 CDN 加速
+
+如果目标网站使用了 CDN(内容分发网络),请求可能不需要到达源服务器:
+
+| 场景 | 走向 |
+|-----|------|
+| 请求静态资源(图片、CSS、JS) | CDN 边缘节点直接返回 |
+| 请求动态数据(API) | 穿透 CDN,到达源服务器 |
+
+CDN 的本质是"把内容提前放到离用户最近的地方"。
+
+### 2.3 负载均衡
+
+大型网站不会只有一台服务器。负载均衡器负责把请求分配到多台服务器上:
+
+```
+用户请求 → 负载均衡器 → 服务器 A(30% 流量)
+ → 服务器 B(30% 流量)
+ → 服务器 C(40% 流量)
+```
+
+常见的分配策略:
+
+| 策略 | 原理 | 适用场景 |
+|-----|------|---------|
+| 轮询 | 依次分配 | 服务器配置相同 |
+| 加权轮询 | 按权重分配 | 服务器配置不同 |
+| IP 哈希 | 同一用户固定到同一台 | 需要会话保持 |
+| 最少连接 | 分给当前连接最少的 | 请求处理时间差异大 |
+
+---
+
+## 3. 服务器处理:厨房里发生了什么
+
+请求到达服务器后,会经过多层处理。
+
+### 3.1 Web 服务器(Nginx / Apache)
+
+第一个接收请求的通常是 Web 服务器,它负责:
+
+| 职责 | 说明 |
+|-----|------|
+| 静态文件服务 | 直接返回 HTML、CSS、JS、图片 |
+| 反向代理 | 把 API 请求转发给后端应用 |
+| SSL 终止 | 处理 HTTPS 加密解密 |
+| 请求过滤 | 拦截恶意请求、限流 |
+
+### 3.2 应用服务器处理
+
+Web 服务器把请求转发给应用服务器(Node.js、Spring、Django 等),处理流程:
+
+```
+请求进入 → 中间件链 → 路由匹配 → 控制器 → 服务层 → 数据访问层
+```
+
+**中间件**做的事情:
+
+1. 解析请求体(JSON、表单数据)
+2. 验证身份(检查 Token)
+3. 检查权限(这个用户能访问这个接口吗?)
+4. 记录日志(谁在什么时候访问了什么)
+
+### 3.3 数据库查询
+
+大部分请求最终都要和数据库打交道:
+
+```
+应用代码:SELECT * FROM books WHERE id = 123
+ ↓
+数据库引擎:解析 SQL → 查询优化 → 执行计划 → 读取数据
+ ↓
+返回结果:{ id: 123, title: "xxx", price: 59.9 }
+```
+
+::: tip 数据库是最常见的性能瓶颈
+网络传输通常是毫秒级,应用逻辑也很快,但一个没有索引的数据库查询可能要几秒甚至几十秒。所以"慢请求"大概率是数据库查询慢。
+:::
+
+---
+
+## 4. 响应返回:数据的归途
+
+### 4.1 构造 HTTP 响应
+
+服务器处理完后,构造响应报文:
+
+```http
+HTTP/1.1 200 OK
+Content-Type: application/json
+Content-Encoding: gzip
+Cache-Control: max-age=3600
+
+{"id": 123, "title": "xxx", "price": 59.9}
+```
+
+| 组成部分 | 内容 |
+|---------|------|
+| 状态行 | 协议版本 + 状态码(200 成功、404 未找到、500 服务器错误) |
+| 响应头 | 数据格式、缓存策略、压缩方式等 |
+| 响应体 | 实际的数据内容(JSON、HTML 等) |
+
+### 4.2 数据压缩
+
+服务器通常会用 gzip 或 brotli 压缩响应体,减少传输量:
+
+| 压缩算法 | 压缩率 | 速度 |
+|---------|--------|------|
+| gzip | 约 70% | 快 |
+| brotli | 约 80% | 较慢但压缩更好 |
+
+一个 100KB 的 JSON,压缩后可能只有 20-30KB。
+
+### 4.3 浏览器渲染
+
+浏览器收到响应后:
+
+1. **解析 HTML** → 构建 DOM 树
+2. **解析 CSS** → 构建样式树
+3. **合并** → 生成渲染树
+4. **布局** → 计算每个元素的位置和大小
+5. **绘制** → 把像素画到屏幕上
+
+
+
+---
+
+## 5. 全链路优化:每一层都能更快
+
+### 5.1 各层优化手段
+
+| 层级 | 优化手段 | 效果 |
+|-----|---------|------|
+| DNS | DNS 预解析、使用快速 DNS 服务 | 减少 DNS 查询时间 |
+| 网络 | CDN、HTTP/2、连接复用 | 减少传输延迟 |
+| 服务器 | 缓存(Redis)、异步处理 | 减少处理时间 |
+| 数据库 | 索引、查询优化、读写分离 | 减少查询时间 |
+| 前端 | 懒加载、代码分割、资源压缩 | 减少渲染时间 |
+
+### 5.2 缓存:最有效的优化
+
+缓存存在于请求链路的每一层:
+
+```
+浏览器缓存 → CDN 缓存 → 反向代理缓存 → 应用缓存(Redis)→ 数据库缓存
+```
+
+::: tip 缓存的本质
+用空间换时间。把计算过的结果存起来,下次直接用,不用重新算。缓存命中率每提高 10%,系统性能可能提升数倍。
+:::
+
+### 5.3 请求失败时的排查思路
+
+| 现象 | 可能的问题层 | 排查方法 |
+|-----|------------|---------|
+| 完全无响应 | DNS / 网络 | ping、nslookup |
+| 连接超时 | 网络 / 服务器宕机 | telnet、curl |
+| 返回 4xx | 客户端请求有误 | 检查 URL、参数、Token |
+| 返回 5xx | 服务器内部错误 | 查看服务器日志 |
+| 响应很慢 | 数据库 / 应用逻辑 | 查看慢查询日志、APM 工具 |
+
+---
+
+## 6. 总结
+
+一个 HTTP 请求的完整旅程:
+
+1. **浏览器**:解析 URL → DNS 查询 → TCP 连接 → 发送请求
+2. **网络**:路由转发 → CDN 判断 → 负载均衡分发
+3. **服务器**:Web 服务器接收 → 中间件处理 → 业务逻辑 → 数据库查询
+4. **返回**:构造响应 → 压缩 → 网络传输 → 浏览器渲染
+
+::: tip 理解全链路的价值
+当你能在脑中画出请求的完整链路时,遇到任何问题都能快速定位到是哪一层出了问题。这是从"初级开发"到"能独立排查问题"的关键跨越。
+:::
+
+---
+
+## 延伸阅读
+
+- [HTTP 权威指南](https://developer.mozilla.org/zh-CN/docs/Web/HTTP) — MDN 的 HTTP 文档
+- [High Performance Browser Networking](https://hpbn.co/) — 浏览器网络性能优化
+- [What happens when...](https://github.com/alex/what-happens-when) — 经典的"输入 URL 后发生了什么"详解
diff --git a/docs/zh-cn/appendix/4-server-and-backend/search-engines.md b/docs/zh-cn/appendix/4-server-and-backend/search-engines.md
index 8d440b9..b289856 100644
--- a/docs/zh-cn/appendix/4-server-and-backend/search-engines.md
+++ b/docs/zh-cn/appendix/4-server-and-backend/search-engines.md
@@ -1,3 +1,153 @@
# 搜索引擎原理
-> 待实现
+::: tip 前言
+**你在淘宝搜"红色连衣裙",0.1 秒内从几十亿商品中找到了最相关的结果——这背后是怎么做到的?** 搜索引擎是互联网最核心的基础设施之一,从 Google 到电商站内搜索,它的核心原理都是一样的:倒排索引 + 相关性排序。
+:::
+
+**这篇文章会带你学什么?**
+
+学完这章后,你将获得:
+
+- **倒排索引**:理解搜索引擎最核心的数据结构
+- **分词技术**:了解中文分词的挑战和常见方案
+- **相关性排序**:掌握 TF-IDF 和 BM25 的基本原理
+- **Elasticsearch**:了解最流行的搜索引擎的架构和使用场景
+- **搜索优化**:掌握同义词、纠错、高亮等实用搜索功能
+
+| 章节 | 内容 | 核心概念 |
+|-----|------|---------|
+| **第 1 章** | 倒排索引 | 正排索引 vs 倒排索引 |
+| **第 2 章** | 分词与分析 | 中文分词、停用词、词干提取 |
+| **第 3 章** | 相关性排序 | TF-IDF、BM25 |
+| **第 4 章** | Elasticsearch | 分布式架构、分片、副本 |
+| **第 5 章** | 搜索优化 | 同义词、纠错、自动补全 |
+
+---
+
+## 0. 全景图:搜索的本质是什么?
+
+搜索的本质是一个**信息检索(Information Retrieval)**问题:给定一个查询,从海量文档中找到最相关的结果,并按相关性排序返回。
+
+这个过程分为两个阶段:
+
+- **索引阶段(离线)**:提前把所有文档处理好,建立高效的查找结构
+- **查询阶段(在线)**:用户输入关键词时,快速找到匹配的文档并排序
+
+::: tip 为什么不能用数据库 LIKE 查询?
+`SELECT * FROM products WHERE name LIKE '%红色连衣裙%'` 看起来能搜索,但它需要**全表扫描**——逐行检查每条记录。当数据量达到百万级时,这种查询会慢到不可用。倒排索引把这个 O(n) 的操作变成了 O(1) 的查找。
+:::
+
+---
+
+## 1. 倒排索引:搜索引擎的"心脏"
+
+传统数据库用的是**正排索引**:从文档 ID 找到文档内容。而搜索引擎用的是**倒排索引**:从关键词找到包含它的文档列表。
+
+
+
+| 索引类型 | 方向 | 查找方式 | 适用场景 |
+|---------|------|---------|---------|
+| 正排索引 | 文档 → 内容 | 知道 ID,查内容 | 数据库主键查询 |
+| 倒排索引 | 关键词 → 文档列表 | 知道关键词,查文档 | 全文搜索 |
+
+::: tip 倒排索引的构建过程
+1. **文档收集**:获取所有需要被搜索的文档
+2. **分词(Tokenization)**:将文档拆分为一个个词语
+3. **建立映射**:记录每个词语出现在哪些文档中(以及出现位置、频率等)
+4. **持久化存储**:将索引写入磁盘,支持快速查找
+:::
+
+---
+
+## 2. 分词与文本分析
+
+分词是搜索引擎的第一步,也是中文搜索的最大挑战。英文天然以空格分词,但中文没有分隔符——"乒乓球拍卖了"可以分成"乒乓球/拍卖/了"或"乒乓/球拍/卖/了"。
+
+| 分词方式 | 说明 | 示例 |
+|---------|------|------|
+| 标准分词 | 按空格和标点切分(英文) | "hello world" → ["hello", "world"] |
+| 中文分词 | 基于词典或模型切分 | "搜索引擎" → ["搜索", "引擎"] |
+| N-gram | 按固定长度滑动窗口切分 | "搜索" → ["搜索", "索引"] |
+| 自定义词典 | 添加业务专有词汇 | "iPhone16ProMax" 作为一个词 |
+
+::: tip 文本分析管道
+分词只是文本分析的一步,完整的管道包括:
+1. **字符过滤**:去除 HTML 标签、特殊字符
+2. **分词**:将文本拆分为词语(Token)
+3. **停用词过滤**:去除"的"、"了"、"是"等无意义的高频词
+4. **同义词扩展**:将"手机"扩展为"手机、电话、移动电话"
+5. **词干提取**:将 "running" 还原为 "run"(英文)
+:::
+
+---
+
+## 3. 相关性排序:哪个结果最"相关"?
+
+找到匹配的文档只是第一步,更重要的是**排序**——把最相关的结果排在最前面。
+
+| 算法 | 原理 | 特点 |
+|------|------|------|
+| TF-IDF | 词频(TF) × 逆文档频率(IDF) | 经典算法,简单有效 |
+| BM25 | TF-IDF 的改进版,加入文档长度归一化 | Elasticsearch 默认算法 |
+| 向量检索 | 将文档和查询转为向量,计算余弦相似度 | 支持语义搜索 |
+
+::: tip TF-IDF 直觉理解
+- **TF(词频)**:一个词在文档中出现越多次,这个文档越可能与该词相关
+- **IDF(逆文档频率)**:一个词在越少的文档中出现,它的区分度越高
+- "的"在所有文档中都出现(IDF 低),所以搜索"的"没有意义
+- "Elasticsearch"只在少数文档中出现(IDF 高),搜索它能精确定位
+:::
+
+---
+
+## 4. Elasticsearch:最流行的搜索引擎
+
+Elasticsearch 是目前最流行的开源搜索引擎,基于 Apache Lucene 构建,提供分布式、RESTful API 的全文搜索能力。
+
+| 概念 | 说明 |
+|------|------|
+| Index | 类似数据库的"表",存储同类文档 |
+| Document | 一条记录,JSON 格式 |
+| Shard | 分片,将索引拆分到多个节点 |
+| Replica | 副本,提供高可用和读扩展 |
+| Mapping | 字段类型定义,类似数据库 Schema |
+| Analyzer | 文本分析器,定义分词规则 |
+
+::: tip ES vs 数据库
+Elasticsearch 不是用来替代数据库的,而是作为搜索层与数据库配合使用。典型架构:数据写入数据库 → 同步到 ES → 搜索请求走 ES → 详情请求走数据库。
+:::
+
+---
+
+## 5. 搜索优化:让搜索更"聪明"
+
+| 优化手段 | 说明 | 效果 |
+|---------|------|------|
+| 同义词 | "手机"也能搜到"电话" | 提高召回率 |
+| 拼写纠错 | "iphoen" 自动纠正为 "iphone" | 容错性 |
+| 自动补全 | 输入"苹"提示"苹果手机" | 提升体验 |
+| 高亮 | 搜索结果中标红匹配词 | 直观展示 |
+| 权重调整 | 标题匹配权重 > 内容匹配 | 提高精确度 |
+| 过滤与聚合 | 按价格区间、品牌筛选 | 缩小范围 |
+
+---
+
+## 总结
+
+搜索引擎是互联网应用的核心基础设施。理解倒排索引、分词、相关性排序这三个核心概念,就掌握了搜索引擎的本质。
+
+回顾本章的关键要点:
+
+1. **倒排索引**:从关键词到文档的反向映射,是搜索引擎的核心数据结构
+2. **分词是基础**:中文分词是搜索质量的关键,需要选择合适的分词器
+3. **BM25 排序**:基于词频和文档频率的相关性评分,是 ES 的默认算法
+4. **ES 架构**:分片 + 副本实现分布式和高可用
+5. **搜索优化**:同义词、纠错、补全让搜索更智能
+
+## 延伸阅读
+
+- [Elasticsearch 官方文档](https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html) - 最权威的 ES 参考
+- [Elasticsearch 权威指南](https://www.elastic.co/guide/cn/elasticsearch/guide/current/index.html) - 中文入门指南
+- [Apache Lucene](https://lucene.apache.org/) - ES 底层的搜索引擎库
+- [MeiliSearch](https://www.meilisearch.com/) - 轻量级搜索引擎,适合中小项目
+- [Typesense](https://typesense.org/) - 开源的即时搜索引擎
diff --git a/docs/zh-cn/appendix/index.md b/docs/zh-cn/appendix/index.md
index fdf4e6d..4c7b8be 100644
--- a/docs/zh-cn/appendix/index.md
+++ b/docs/zh-cn/appendix/index.md
@@ -49,9 +49,14 @@
description="从汇编到高级语言,理解编程语言的演进与分类"
/>
+