AI → Full-Stack
365 天全栈成长 · PHASE 1 · WEEK 1 · 复盘日

Day 7 - 复盘日:把 Week 1 的六天连成一张图

今日时长:3 小时(默写 60 min + code review 60 min + 补漏 60 min)· 今天不学新内容。复盘日的唯一任务是:把学过的东西从「看懂了」变成「说得出、写得出」· 产出:一张全景图 + 默写答卷 + 一次代码 review
⚠️ 复盘日的规矩

不许翻前六天的讲义。先凭记忆写,写完再对照订正。订正的地方用红色或加粗标出来——那些就是你真正的知识缺口,下周会再考。

如果某一题完全写不出来,不要跳过。写下「我不会」,然后去看讲义,再用自己的话重写一遍。

🗺️ 第一件事:画出「一个 HTTP 请求的一生」(约 40 min)

这是本周最重要的产出。把六天学的东西,串成一条线。

任务

在 src/07-week1-review/request-lifecycle.md 里,用文字或 mermaid 画出下面这个过程,每一步标注它对应 Day 几学的内容:

场景

一个德国用户在浏览器输入 https://www.supergood-tech.de/de/day/1/,回车。你的 Node 服务器上发生了什么?

要覆盖这些环节(顺序你自己排):

  • 浏览器发出的那段文本长什么样
  • TCP 连接建立后,谁通知了 event loop
  • event loop 在哪个 phase 取出这个事件
  • 你的 handler 在哪个线程上跑
  • handler 里 await 数据库时,主线程去干嘛了
  • 如果 handler 里有 2 秒 CPU 计算,会发生什么,该怎么办
  • 响应体 100MB 时,该怎么写出去
  • 想吃满 4 核,该用什么
  • 响应报文长什么样,必须有哪几个 header

写完之后自查:这九个环节你标出了几个 Day?

参考答案的对应关系(不是完整答案,只是给你对一下 Day 编号):

环节对应
请求报文格式、状态码、headerDay 6
libuv 通知 → poll phase 取出Day 2
handler 在主线程跑,await 时让出Day 1
CPU 计算卡住全场 → worker_threadsDay 5
大响应体用流,别拼字符串Day 3
吃满多核 → cluster 多进程Day 4
为什么这张图值 40 分钟

面试官问「你了解 Node 吗」,背 API 的人说「我用过 Express」;能画这张图的人,直接进入下一轮。

更重要的是:这张图在 C#、Java、Go 里结构完全一样,只有第 3、4 步不同(它们用线程池,不用 event loop)。你画的是「后端服务器」,不是「Node 服务器」。

✍️ 第二件事:六张概念卡默写(约 60 min)

写在 src/07-week1-review/concept-cards.md。每张卡片必须包含三部分:通用定义(不绑定语言)、Node 里的样子、其他语言里的样子。

卡片 1:并发模型(Day 1)

  • 并发和并行的区别,用一句话
  • 三种并发模型各自的取舍(多线程 / 事件循环 / 协程)
  • 为什么说 Node 的模型适合 I/O 密集,不适合 CPU 密集

卡片 2:事件循环(Day 2)

  • 六个 phase 的顺序,以及你只需要记住的三站是哪三站
  • nextTick 和 microtask 在什么时候清场,它们属于 phase 吗
  • setTimeout(fn, 0) 和 setImmediate(fn),顶层调用时谁先?I/O 回调里调用时谁先?为什么不一样

卡片 3:流与背压(Day 3)

  • 为什么 2GB 文件不能用 readFileSync
  • 背压是什么,write() 返回 false 时该做什么
  • 字节和字符的区别,一个中文字在 UTF-8 里几个字节

卡片 4:进程模型(Day 4)

  • 进程和线程的区别(内存、沟通、崩溃影响三个维度)
  • exec / execFile / spawn / fork 各自的场景,以及两颗炸弹是什么
  • cluster 多个进程共享同一个端口的原理

卡片 5:线程与共享内存(Day 5)

  • worker_threads 和 cluster 的三个区别
  • 拷贝 / 转移 / 共享三种传数据方式,各自什么时候用
  • 什么是竞态条件,Atomics 在防什么
  • 决策表至少 5 行:什么时候用 worker / cluster / child_process / 什么都不用

卡片 6:HTTP(Day 6)

  • 请求报文的四个部分,那个空行的作用
  • 五类状态码,401 和 403 的区别
  • 幂等的定义,以及它和客户端重试的关系
  • Content-Length 和 chunked 的区别

🔍 第三件事:给自己这周的代码做一次 review(约 40 min)

打开你这周写的所有代码(src/01- 到 src/06-),用「别人写的代码」的眼光看一遍。把发现写在 src/07-week1-review/code-review.md。

Review 清单(逐条检查)

检查项为什么重要对应 Day
有没有地方用了 readFileSync 读可能很大的文件内存炸弹Day 3
有没有 body += chunk 这种攒字符串的写法,且没有大小上限上传攻击面Day 3 / 6
有没有创建了 worker / child_process 但忘了 terminate / kill进程不退出Day 4 / 5
有没有在主线程做超过 100ms 的同步计算卡住所有请求Day 1 / 5
错误有没有被吞掉(空的 catch、没监听 error 事件)问题被藏起来全部
用 exec 的地方,命令里有没有拼接外部输入shell 注入Day 4
Content-Length 有没有用 .length 而不是 Buffer.byteLength中文截断Day 6
变量名和函数名,一周后的你看得懂吗可维护性—

产出要求

每发现一个问题,写成这个格式:

## 文件:src/03-streams-buffer/ex2.ts 第 18 行
**问题:** 用 readFileSync 读了一个可能 2GB 的文件
**后果:** 内存会被吃光,进程崩溃
**改法:** 改成 createReadStream + pipeline
**我当时为什么这么写:** 只想着能跑通,没想文件会变大

最后一行最重要。记录当时的想法,才能发现自己的思维盲区。

如果一个问题都没发现,那说明 review 得不够仔细——再看一遍,特别看错误处理和资源释放。

📊 第四件事:补对照表 + 自测 20 题(约 40 min)

4.1 补跨语言对照表

打开 roadmap.md,找到顶部的「后端概念跨语言对照表」。这周学到的东西,至少补三行:

  • 运行时与并发模型 行 —— 补一句你自己的理解(Day 1 / 5)
  • 流式 I/O 行 —— 补一句(Day 3)
  • 新增一行 HTTP 服务器 —— 填 Node / C# / Java / Python / Go(Day 6 讲义里有)

要求:补的内容必须是你亲手验证过的,不是抄讲义。抄的东西记不住。

4.2 自测 20 题(闭卷,写在 src/07-week1-review/self-test.md)

基础题(每题 1 分)

  1. 并发和并行的区别是什么?
  2. event loop 的六个 phase,哪三个最重要?
  3. process.nextTick 和 Promise.then,谁先执行?
  4. 为什么递归调用 process.nextTick 会饿死 event loop?
  5. Buffer 和 String 的区别是什么?
  6. write() 返回 false 意味着什么?你该做什么?
  7. pipe() 和 pipeline() 的区别?该用哪个?
  8. 进程和线程,在「内存」这个维度上有什么区别?
  9. exec 的 maxBuffer 是什么?超了会怎样?
  10. cluster 的多个 worker 怎么能监听同一个端口?

理解题(每题 2 分)

  1. 为什么说 worker_threads 不是 cluster 的升级版?
  2. postMessage 的「转移」和「共享」有什么区别?各自什么时候用?
  3. 什么是竞态条件?用一个具体例子说明。
  4. HTTP 请求报文的四个部分是什么?那个空行为什么必须有?
  5. 401 和 403 的区别?
  6. 为什么表单校验失败不该返回 500?
  7. 什么是幂等?POST 和 PUT 哪个幂等?
  8. 什么时候必须用 chunked 而不是 Content-Length?

综合题(每题 5 分)

  1. 场景题:你的 API 有一个 /report 接口,要生成一个 PDF,耗时约 3 秒(纯 CPU)。上线后用户反馈「点了报表,整个网站都卡住了」。用这周学的知识完整解释原因,并给出两个不同层次的解决方案。
  2. 场景题:你的 API 有一个 /export 接口,要导出一个 2GB 的 CSV。目前的实现是先在内存里拼好字符串再返回。说出至少三个问题,并给出改法。改完之后,响应头会有什么变化?

评分:满分 36。低于 25 分,下周开始前先把错题对应的那天重看一遍。

🎯 Week 1 结算与 Week 2 预告

这周你从「不知道」到「能讲清楚」的东西

Day主题核心收获
1并发模型一个服务员怎么招呼一千桌客人
2event loop他的巡场路线和清场顺序
3Stream / Buffer2GB 的菜怎么端才不砸锅
4进程模型一个人不够时怎么开分店
5worker_threads店里加操作台,以及什么时候不该加
6HTTP客人递的那张纸条长什么样
一句话总结 Week 1

你现在知道一个后端服务器从「接到字节」到「发出字节」的完整链路,以及每一环可能出什么事。

这是所有后端知识的地基。接下来学的东西(框架、数据库、缓存、部署)都是盖在这上面的。

Week 2 预告(Day 8–14):服务端 TypeScript + HTTP 语义深入

  • TypeScript 在服务端真正有用的部分:泛型、discriminated union 与类型收窄(你的水平测试 G2 题)、unknown vs any
  • 用 zod 做运行时校验——为什么「类型」和「校验」是两件不同的事
  • HTTP 语义深入:幂等、内容协商、缓存头
  • 统一错误格式 RFC 9457 problem+json 正式落地
  • 产出:把 Day 6 的裸 http API 加上 zod 校验和统一错误体

提交今天的产出

git add -A
git commit -m "docs: week 1 review"

✅ 复盘日自检

  • 画出了「一个 HTTP 请求的一生」,九个环节都标了 Day 编号
  • 六张概念卡全部默写完,每张都有「通用定义 + Node + 其他语言」三部分
  • 对本周代码做了 review,至少找出 3 个问题并写清了改法和当时的想法
  • roadmap 对照表补了至少 3 行,内容是自己验证过的
  • 自测 20 题做完并打分,低于 25 分的部分已经安排重看
  • 今天的产出已经 commit