90天古法编程计划 - 每日详细
这是 90天古法编程计划 的执行手册。主文章聊思路,这篇是每天干什么、怎么验证。
每个项目结束时:代码能跑 + valgrind 无泄漏 + 写一篇博客。
阶段一:用 C 造小工具(Day 1-30)
Week 1:内存透视器(memory_probe)
输入一个值,打印它在内存里的真实样子。
| Day | 里程碑 | 验证标准 |
|---|---|---|
| 1 | 打印整数的二进制表示 | ./memprobe int 42 → 00101010 |
| 2 | 十六进制 + 有符号/无符号 + 负数补码 | ./memprobe int -1 → FF / -1 |
| 3 | 打印浮点数的 IEEE 754 位序列 | ./memprobe float 0.1 → 打印 32 位 |
| 4 | 打印 struct 的内存布局(偏移、padding) | 定义 struct,看到每个字段的偏移和填充字节 |
| 5 | 打印变量地址 + 指针指向的内容 | 输入一个指针,看到地址和指向的值 |
| 6 | 检测大小端 + 检查 malloc 数据的内存 | 程序报告 big/little endian |
| 7 | 整理代码 + 写博客 | “我造了一个内存透视器” |
自然学到的:二进制/补码、IEEE 754、指针、struct 布局、大小端、malloc/free、valgrind。
Week 2:字符串引擎(str_engine)
C 没有好用的字符串类型,自己造一个。
| Day | 里程碑 | 验证标准 |
|---|---|---|
| 8 | 定义 String 结构体(char* + length),实现 create/free | 创建字符串,打印,释放,valgrind 零泄漏 |
| 9 | 拼接(concat)+ 比较(compare) | concat("hello ", "world") → "hello world" |
| 10 | 查找子串(find) | find("hello world", "world") → 位置 6 |
| 11 | 分割(split)+ 连接(join) | split("a,b,c", ",") → 三个字符串 |
| 12 | 动态字符串数组(push/pop/get) | push 100 个字符串,全部可访问 |
| 13 | 替换(replace)+ 去空格(trim) | replace("foo bar", "foo", "baz") → "baz bar" |
| 14 | 整理代码 + 写博客 | “C 语言手写字符串引擎” |
自然学到的:动态数组、malloc/free、指针运算、内存泄漏检测。这是从"复制粘贴"到"自己写"的转折周。
Week 3:mini-grep
造一个文本搜索工具。
| Day | 里程碑 | 验证标准 |
|---|---|---|
| 15 | 读取文件并逐行打印 | ./minigrep "" file.txt → 打印所有行 |
| 16 | 精确匹配搜索,打印匹配行 | ./minigrep "error" log.txt → 只有含 error 的行 |
| 17 | 行号 + 颜色高亮匹配 | 匹配的文本有颜色,行首有行号 |
| 18 | 简单正则(.*^$) | ./minigrep "^Error" log.txt → 以 Error 开头的行 |
| 19 | 多文件搜索 + 递归目录 | ./minigrep "TODO" ./src/ → 搜索整个目录 |
| 20 | -v 反转 / -i 忽略大小写 / -c 计数 | 三个 flag 都正常工作 |
| 21 | 整理代码 + 写博客 | “我造了一个 mini-grep” |
自然学到的:文件 I/O、字符串匹配、命令行解析、递归。
Week 4:CSV 数据刀(csv_knife)
造一个 CSV 读取/筛选/排序/导出工具。用 Week 2 的字符串引擎。
| Day | 里程碑 | 验证标准 |
|---|---|---|
| 22 | 解析 CSV(处理引号、逗号、换行) | 读取真实 CSV,打印成表格 |
| 23 | 按列选择(--select name,age) | 只显示指定列 |
| 24 | 按条件筛选(--where age>18) | 只显示符合条件的行 |
| 25 | 按列排序(--sort age) | 按指定列排序,升降序可选 |
| 26 | 导出 CSV | 导出的文件 Excel 能打开 |
| 27 | 错误处理(坏 CSV、缺列) | 不崩溃,友好报错 |
| 28 | 回顾四周代码,重构 | 代码更清晰,功能不变 |
| 29 | 写阶段一总结博客 | “30天,4个小工具” |
| 30 | 发布总结 | — |
自然学到的:解析、排序算法(手写快排)、函数指针(比较器)、错误处理、重构。
阶段二:系统级编程(Day 31-60)
Week 5:mini-shell
造一个能跑真实命令的 shell。
| Day | 里程碑 | 验证标准 |
|---|---|---|
| 31 | 读取输入,解析命令+参数,execvp 执行 | 输入 ls -la 正常执行 |
| 32 | fork 子进程执行,父进程等待 | 命令执行完 shell 继续 |
| 33 | 管道 | | ls | grep .c 正常工作 |
| 34 | 重定向 > < >> | ls > out.txt 写入文件 |
| 35 | 后台执行 & | sleep 10 & 后 shell 立即返回 |
| 36 | 内建命令 cd / exit / history | cd 能切换目录,history 显示历史 |
| 37 | 整理代码 + 写博客 | “我造了一个 mini-shell” |
自然学到的:fork/exec/wait、管道、文件描述符、信号。FreeRTOS 的任务调度概念直接迁移,但 fork 和虚拟内存是 RTOS 没有的。
Week 6:HTTP 服务器(tiny_httpd)
造一个浏览器能访问的 Web 服务器。
| Day | 里程碑 | 验证标准 |
|---|---|---|
| 38 | TCP socket:bind/listen/accept | nc localhost 8080 能连上 |
| 39 | 读取并解析 HTTP 请求(method/path/headers) | 打印浏览器发送的请求内容 |
| 40 | 根据 URL 返回静态 HTML 文件 | 浏览器看到页面 |
| 41 | 处理不同内容类型(HTML/CSS/JS/图片) | CSS 和 JS 正常加载 |
| 42 | 404 处理 + 错误响应 | 错误 URL 返回 404 页面 |
| 43 | 路由 + query string 解析 | /?name=foo 能取到参数 |
| 44 | 整理代码 + 写博客 | “从 socket 到 HTTP 服务器” |
自然学到的:socket、TCP、HTTP 协议、MIME 类型、URL 解析。嵌入式几乎没碰过的领域。
Week 7:迷你数据库(tiny_db)
造一个持久化 KV 存储。
| Day | 里程碑 | 验证标准 |
|---|---|---|
| 45 | 定义存储格式,写一个 key-value 到文件 | 写入后文件有数据 |
| 46 | SET 和 GET 命令 | SET name hello / GET name → hello |
| 47 | 持久化:启动时加载文件 | 重启程序,数据还在 |
| 48 | DELETE + 列出所有 key | 删除后 GET 返回空,LIST 显示剩余 |
| 49 | 加哈希索引加速查找 | 1000 条数据 GET < 1ms |
| 50 | 加 B+ 树索引支持范围查询 | RANGE a m 返回 a-m 之间的 key |
| 51 | 整理代码 + 写博客 | “我造了一个迷你数据库” |
自然学到的:文件 I/O、哈希表、B+ 树、持久化。B+ 树不是提前学的,是发现"范围查询太慢"后自然需要的。
Week 8:多线程爬虫(web_crawler)
造一个多线程网页爬虫。
| Day | 里程碑 | 验证标准 |
|---|---|---|
| 52 | HTTP GET 下载一个网页(复用 Week 6 知识) | 下载并保存 HTML |
| 53 | 解析 HTML,提取 <a href> 链接 | 打印页面所有链接 |
| 54 | URL 队列(复用 Week 2 动态数组) | URL 入队出队正确 |
| 55 | pthread 多线程,worker 从队列取 URL 并下载 | 3 个线程并发下载 3 个页面 |
| 56 | 互斥锁保护队列 + 已访问 URL 集合 | 无重复下载,无竞争崩溃 |
| 57 | 深度限制 + 域名过滤 | 只爬同域名,到指定深度停止 |
| 58 | 写 Makefile 构建所有代码 | make 一键编译 |
| 59 | 写单元测试(字符串引擎、队列、URL 集合) | make test 全部通过 |
| 60 | 写阶段二总结博客 | “60天,我造了 shell/服务器/数据库/爬虫” |
自然学到的:pthread、互斥锁、条件变量、生产者-消费者模型、哈希集合、Makefile、单元测试。FreeRTOS 的生产者-消费者模型直接迁移到 pthread。
阶段三:全栈项目(Day 61-90)
Week 9-10:从零写 Web 应用
切换到 JS/TS,禁止 React/Vue/Express。
项目选 URL 短链服务或 Todo 应用。
| Day | 里程碑 | 验证标准 |
|---|---|---|
| 61 | Node.js HTTP 服务器(不用 Express) | curl localhost:3000 有响应 |
| 62 | URL 路由(解析 method + path) | 不同路径返回不同响应 |
| 63 | 创建短链(生成 code,存内存) | POST 创建,返回短码 |
| 64 | 重定向(GET /:code → 302) | 浏览器访问短链能跳转 |
| 65 | 持久化(JSON 文件或 SQLite) | 重启数据不丢 |
| 66 | 前端页面(HTML + CSS + 原生 JS) | 表单能创建短链 |
| 67 | 中期复盘 + 博客 | “Web 应用第一周” |
| 68 | 点击统计 | 统计页显示每个短链的点击数 |
| 69 | 输入验证 + 错误处理 | 非法输入友好报错 |
| 70 | 简单认证(token) | 只有授权用户能创建 |
| 71 | 安全检查(XSS、注入) | 存储的 URL 不含恶意脚本 |
| 72 | API 文档 | 别人能照文档用你的 API |
| 73 | 部署(Dockerfile 或 systemd) | 服务在后台运行 |
| 74 | 项目完成 + 博客 | “从零手写了一个 Web 应用” |
Week 11:调试与性能
| Day | 里程碑 | 验证标准 |
|---|---|---|
| 75 | Chrome DevTools 断点调试 | 设断点,查变量 |
| 76 | 结构化日志(请求/响应) | 日志有用且可读 |
| 77 | 性能分析,找瓶颈 | 找出最慢的操作 |
| 78 | 优化(缓存/查询优化) | 基准测试显示提升 |
| 79 | 内存泄漏检查 | 长时间运行内存不增长 |
| 80 | 负载测试 | 能处理 100 并发请求 |
| 81 | 博客 | “调试和优化实战” |
Week 12:重构与总结
| Day | 里程碑 | 验证标准 |
|---|---|---|
| 82 | 代码审查,列出所有问题 | 5+ 条发现 |
| 83 | 根据审查重构 | 测试仍通过,代码更清晰 |
| 84 | 补充测试(单元+集成) | 覆盖率 > 70% |
| 85 | README + API 文档 + 架构说明 | 别人能看懂你的项目 |
| 86 | LeetCode 中等题(不看答案) | 30 分钟内解出 |
| 87 | LeetCode 中等题 x2(计时) | 各 20 分钟内 |
| 88 | 回顾90天代码和笔记 | 成长轨迹文档 |
| 89 | 写终极总结博客 | 发布 |
| 90 | 庆祝 | — |
终极总结:90天前后自评对比 + 3个认知突破 + 不足和改进 + GitHub 链接 + 对古法编程和 AI 辅助编程关系的新理解。
自评体系
每周末给自己打分(1-10),记录在博客里:
| 维度 | 说明 |
|---|---|
| 完成度 | 这周的工具跑起来了吗? |
| 理解度 | 能给别人讲明白吗? |
| 代码质量 | 结构、命名、错误处理 |
| 独立性 | 有多少是真正独立完成的 |
| 投入度 | 实际投入 vs 计划时间 |
目标:到 Day 90,每个维度都 7 分以上。
中断恢复
- 中断1-2天:正常继续,博客说明
- 中断3-7天:本周项目顺延
- 中断超过1周:花1天复习上周代码,然后继续
- 中断超过2周:从当前阶段 Week 1 重新开始
不追求完美连续,追求真实完成。
返回 90天古法编程计划