The Missing Semester总结
Published on
Table of Contents
最近发现一个有意思的MIT课The Missing Semester of Your CS Education. 它把那些一直靠自学的工程基本功系统讲了一遍:shell、版本控制、调试与性能分析、测试与 CI、打包部署、安全习惯、数据处理。
这些内容以前基本都是遇到问题就搜一条命令,能跑就行。短期确实快,但长期会暴露两个问题:一是知识不成体系(不知道哪些是必修、哪些是坑、哪些应该自动化);二是习惯不稳定(换台机器/换个项目就又从头踩坑)。
主要内容 Link to this section
这门课的主要内容,这篇文章内容主要来自课程仓库:
把 shell 当语言:用管道把程序拼起来,理解权限、重定向、引用这些高频坑位。
让终端可持续:tmux 管会话,SSH 管远程,dotfiles 管可复现;把环境变成可迁移资产。
把编辑器当平台:LSP/调试/任务编排一体化;Vim 模式提升文本操作带宽。
把 AI 当工具链一部分:先写清目标与约束,再让 AI 出 plan/patch;最后用 lint/test 作为裁判。
把调试变成证据链:日志 → 交互调试 → 跟踪/性能分析 → 复现与回放(rr/逆向调试)。
把质量写进流程:格式化、测试、覆盖率、CI、预提交钩子,把靠自觉变成默认正确。
把交付当工程:打包、版本、容器、部署与监控,决定代码能否被别人正确使用。
Shell——从命令行到脚本 Link to this section
课程从 shell 开始——目标是少量命令搞定日常导航/管道拼装,并写出不容易翻车的 shell 脚本。
Shell 基础与语言 Link to this section
命令行要当作管道语言,而不是敲命令。
- PATH 与导航:查看路径、当前目录、跳转目录、提示符信息。
echo $PATH
which echo
pwd
cd /tmp && pwd
ls -lh- 管道与重定向:串联程序、覆盖/追加输出、重定向错误、指定输入。
journalctl | grep sshd | head -50 > ssh.log
cmd > out.txt
cmd >> out.txt
cmd 2> err.log
cmd < input.txt- 权限、可执行位与
sudo重定向陷阱(非常常见且容易踩):- 可执行位决定能否
./script:
- 可执行位决定能否
chmod +x semester
./semester./scriptvssh script:前者需要可执行位 + 会读取 shebang;后者显式用解释器执行(可执行位不关键)。重定向是 shell 做的,不是命令做的:
sudo echo 3 > brightness失败是因为>打开文件发生在sudo之外。
# 错误示例(> 由当前 shell 打开文件)
sudo echo 3 > brightness
# 正确示例:让以 root 身份运行的程序去打开文件echo 3 | sudo tee brightness >/dev/null- 常用查找/搜索:递归查找文件、正则搜索、处理 NUL 分隔。
find . -name '*.py' -type f
rg pattern
grep -R pattern .
xargs -0 echo- 引号与转义:单引号、双引号、反斜杠示例。
echo "$PATH"
echo '$PATH'
echo "quote \"inside\""历史与命令发现:
history | grep、Ctrl+R/fzf 反向搜索;HISTCONTROL=ignorespace避免敏感信息入历史;-help/man/tldr/which/type。兼容与 shebang:
#!/usr/bin/env bash优先于硬编码路径;区分交互/登录 shell,按需在.bashrc/.profile/.zshrc条件加载。
Bash 脚本与脚本质量 Link to this section
脚本不仅要能跑,更要稳健。以下示例和守则可直接拿去作为模板。
- 基本构造:变量、条件、循环、函数、退出码、短路、命令/进程替换、globbing、shebang。
#!/usr/bin/env bash
mcd(){ mkdir -p "$1"; cd "$1"; }
for f in "$@"; do
if ! grep -q foobar "$f"; then
echo "# foobar" >> "$f"
fi
done
echo "Last status: $?"
echo "Args: $@ (count: $#)"- 稳健脚本的必踩坑与护栏(面向只看总结就能写不翻车的脚本):
source script.shvs./script.sh:source在当前 shell 执行,能修改当前环境(如cd、定义函数);./script.sh会启动子进程,修改不会回到父 shell。- 参数展开:
"$@":保持每个参数的边界(几乎总是你想要的)。"$*":把所有参数拼成一个字符串(在需要把参数当成一句话时才用)。
- 避免
for f in $(ls …):会被空格/换行打爆;用 glob 或find -print0 | xargs -0。 - 推荐模板(按需使用,避免把错误静默吞掉):
#!/usr/bin/env bash
set -euo pipefail
IFS=$'\n\t'
cleanup() { rm -rf "${tmpdir:-}"; }
trap cleanup EXIT
tmpdir="$(mktemp -d)"
# ... your code ...- 质量与帮助:静态检查与文档。
shellcheck script.sh
man find
tldr tar现代 Shell 工具 Link to this section
这些现代工具主要用来提升导航、搜索与展示效率。
- 快速搜索/导航/显示。
rg todo
fd src
fzf
bat README.md
zoxide query src
eza -lah组合技巧:
ripgrep | fzf交互筛选;fd -x批量操作;z快速跳目录(依赖 zoxide)。其他常用:
tree、ranger/nnn浏览目录;fasd/autojump按频率+近期跳转。
到这里,手工步骤基本能压缩成一条命令或脚本。下一步:把终端变成稳定工作台(进程/会话/远程连接/配置管理),解决断线就崩。
命令行环境 Link to this section
这一节关注进程/会话/远程连接的管理,让 shell 成为可持续的工作场所。
作业控制与信号 Link to this section
- 前后台、暂停、信号管理。
sleep 1000 &
jobs
kill -STOP %1
fg %1
nohup long-task &
disown %1
kill -TERM %1
kill -KILL %1终端复用(tmux) Link to this section
- 基本操作:会话/窗口/面板。
tmux new -s work
tmux ls
tmux a -t work
# tmux 内:<C-b> c 新窗口;<C-b> n/p 切换;<C-b> " / % 分屏;<C-b> z 放大;<C-b> [ 滚动;<C-b> d 分离SSH 与远程 Link to this section
- 密钥、配置、转发、复制;控制连接与跳板。
ssh-keygen -t ed25519 -C "email"
cat ~/.ssh/config
# Host example
# HostName example.com
# User ubuntu
# IdentityFile ~/.ssh/id_ed25519
# ProxyJump bastion
# ControlMaster auto
# ControlPersist 10m
ssh -L 8000:localhost:8000 host
ssh -R 9000:localhost:9000 host
ssh -A host cmd
# agent forwarding
ssh-copy-id user@host
scp file host:/tmp/
rsync -av --progress src/ host:/srv/app/Dotfiles 与定制 Link to this section
目标:配置可复现、可迁移。
- 别名、函数、提示符存放与条件加载。
echo "alias ll='ls -lh'" >> ~/.bashrc
echo "alias gs='git status'" >> ~/.bashrc
echo "alias mv='mv -i'" >> ~/.bashrc- 推荐实践:
- 把 dotfiles 放在单独目录(如
)并纳入版本控制;用安装脚本/Makefile/justfile 批量创建软链接到/dotfiles/.bashrc,,/.gitconfig/.vimrc,,/.ssh/config/.tmux.conf等。 - 做跨机器差异:用条件判断(uname/hostname/$SHELL)或include 本地私有文件(例如
~/.gitconfig_local),避免把 token、主机地址等敏感信息直接提交到公共仓库。 - 让登录/交互 shell 行为一致:在
.profile/.bash_profile中按需source ~/.bashrc;避免重复追加 PATH。
- 把 dotfiles 放在单独目录(如
AI Shell 与终端 Link to this section
- 使用 Warp、Zummoner 或类
llm-zsh-plugin的补全/代理工具时注意审查与隐私。
Shell 环境 Link to this section
- 启动文件与环境变量。
echo 'export EDITOR=vim' >> ~/.bashrc
source ~/.bashrc- 兼容性:在
.profile/.bash_profile里引用.bashrc以确保登录/非登录一致;避免在 PATH 中重复。
终端稳定后,瓶颈常转移到写代码本身:编辑器、跳转、重构、调试、AI 协作。下面把这些工具当成一条流水线来组织。
开发环境与AI工具 Link to this section
这一节把编辑器、调试器、AI 助手与容器环境串成工作流,让工具彼此协作。
编辑器与 LSP Link to this section
启用 LSP、跳转/悬停/重构、远程开发(VSCode/JetBrains/Zed)。
调试与测试集成:使用内置调试器、终端复用、任务/launch 配置。
协作:Live Share/多编辑器协作模式(与agentic IDE/协作编辑的趋势一致)。
定制/插件:管理插件(Vim 插件管理器、VS Code 扩展),配置快捷键、snippets、格式化/诊断集成,理解操作+对象语法(动作+移动)与宏/寄存器/标记。
高效文本编辑与 Vim 模式 Link to this section
- 移动/操作/文本对象/宏/搜索替换。
:%s/old/new/gc- 启用 shell/Readline/IDE 的 Vim 模式(根据工具设置)。
AI 编程助手 Link to this section
Claude Code、Copilot、Cursor、CodeWhisperer:从补全到 coding agents;根据付费/本地模型权衡隐私与算力。
最佳实践:给出目标、上下文、约束;让 AI 先出 plan 再要代码;审查安全/性能/许可证;生成后用 lint/test 验证。
常见坑:AI 的70% 问题(能完成大半,但最后一段最贵);不要把不理解的 patch 直接合入;遇到调试螺旋就回到最小复现/日志/二分。
工具集成:MCP/工具调用能把 IDE、代码搜索、Issue/PR、CI 等接入上下文,但要明确权限边界与数据外发策略。
Devcontainer 与非编辑器工具 Link to this section
- 容器化开发环境。
devcontainer up # 取决于工具
docker-compose up # devcontainer 组合- 静态/安全分析。
semgrep -f p/ci- 其他工具:代码搜索(ripgrep/LiveGrep)、结构化查找(comby)、安全扫描(trivy 针对容器镜像)。
编辑/搜索/AI 到位后,下一个卡点通常是定位:为什么坏了、慢了、占内存。调试与 profiling 的核心是把直觉变成证据。
调试与性能分析 Link to this section
调试就是观测-假设-验证的循环。本节整理从日志到系统调用、从 CPU 到内存的工具链。
调试方法 Link to this section
- 日志与系统日志。
journalctl -u myservice | tail
log show --predicate 'process == "myapp"' --last 1h
logger "hello"
dmesg | tail交互调试与记录回放 Link to this section
- gdb/lldb 基本命令。
gdb --args ./app arg1
# gdb 内:run, break main, next, step, bt, frame, print var, layout src语言调试器:
pdb/ipdb(Python)、pwndbg 提升 gdb 体验。record-and-replay / reverse debugging(如 rr)。
rr record ./app
rr replay系统调用与低层跟踪 Link to this section
strace -e trace=network -f curl https://example.com
dtruss ls -l- 网络抓包:
tcpdump -i eth0 port 443,Wireshark 图形分析。
静态分析与 AI 调试 Link to this section
- 结合 lint/类型检查;AI 用于解释日志但需验证。
pyflakes app.py
mypy app.py
semgrep -f p/ci性能分析与监控 Link to this section
time cmd
hyperfine 'fd src' 'find . -name src'
python -m cProfile script.py
kernprof -l script.py && python -m line_profiler script.py.lprof
perf stat ls >/dev/null
perf record ./app && perf report
top
htop
iostat 1
iotop- 浏览器端分析:使用 Chrome/Firefox devtools 的性能/网络/内存分析器。
内存与泄漏 Link to this section
valgrind --leak-check=full ./app
python -m memory_profiler script.py能定位问题只是第一步,更重要的是别让它再发生:把格式化、lint、测试和 CI 变成默认流程,而不是上线前祈祷。
质量与CI Link to this section
质量保证应从本地格式化、lint 一路贯穿到 CI。下面这份清单可以当作基础设施 checklist。
格式化与 Lint Link to this section
black src/
eslint .- 结合 AI remediation:让 AI 提建议/改 patch,但以 formatter/linter 的输出作为唯一真相。
测试 Link to this section
pytestfuzz/性质测试(Hypothesis/QuickCheck/fast-check、AFL/libFuzzer/cargo-fuzz/go-fuzz),CI 中跑短任务,定时跑长 fuzz。
AI 测试生成:适合补齐回归与边界,但要把断言建立在可验证的不变量上。
覆盖率 Link to this section
coverage run -m pytest
coverage html构建与任务编排 Link to this section
paper.pdf: paper.tex plot-data.png
pdflatex paper.tex
plot-%.png: %.dat plot.py
./plot.py -i $*.dat -o $@just testMake/.PHONY:为
clean等伪目标加.PHONY,利用依赖图做增量构建;语言自带 runner(npm scripts/cargo)按需取舍。预提交自动化:
pre-commit配置格式化/安全检查,阻止带问题的提交。依赖与版本:语义化版本号,锁文件 vs vendoring;apt/pip/npm/conda/cargo 等包管理器差异与固定版本。
CI Link to this section
GitHub Actions 工作流、缓存、并行、质量门禁(lint/测试/覆盖率)。
示例片段:
name: ci
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with: {python-version: '3.x'}
- run: pip install -r requirements.txt
- run: pytest质量门禁自动跑起来后,下一步就是交付:让别人能在本地、CI、服务器上,用同一种方式跑起代码。
打包与交付 Link to this section
当代码要被他人使用时,交付方式决定体验。本节覆盖打包、版本、容器与部署。
打包与环境 Link to this section
python -m build
uv venv- 环境与包管理:
pipx、pip-compile/uv pip compile、hatch、Nodenvm、Rustrustup,按语言选择隔离方式。
发布与版本 Link to this section
语义化版本、变更日志、签名/校验。
发布流水线:预发布 tag,CI 生成制品并签名/校验;区分 prod/staging 渠道。
容器化与可复现 Link to this section
docker build -t app:latest .
docker-compose up- Nix/flakes 等可复现工具;Docker 多阶段构建、非 root 镜像。
部署 Link to this section
- systemd 示例:
[Unit]
Description=My App
After=network.target
[Service]
ExecStart=/usr/bin/myapp
Restart=always
[Install]
WantedBy=multi-user.target配置 DNS、反向代理/证书(nginx/Caddy/Traefik + ACME/certbot)、健康检查/回滚;监控与 UptimeRobot。
其他进程管理:launchd(macOS)、supervisord、pm2(Node)。
打包/发布/回滚都离不开可追溯的历史。Git 不只是备份工具,更像工程协作的时间机器:定位、还原、审计、协作,很多痛苦会瞬间消失。
版本控制 Link to this section
Git 是协作与历史的核心。理解数据模型,再学命令,效率最高。
数据模型与基础 Link to this section
- blob/tree/commit、内容寻址、引用、暂存区;
git log –graph –decorate理解 DAG;暂存区 vs 工作区。
日常与现代 porcelain Link to this section
git status
git add file
git diff
git commit -m "message"
git switch -c feature
git merge main
git rebase main
git fetch
git pull
git push
git restore file
git reset --soft HEAD^
git revert <commit>- 断头提交与恢复:
git reflog找回丢失引用,git restore –staged/–worktree清理工作区。
进阶 Link to this section
git worktree add ../feat feat
git clean -fd
# 谨慎
git rebase -i HEAD~3
gh pr create
# GitHub CLI 示例
git add -p
git stash
git bisect start
git mergetool能熟练地在时间线上移动之后,工程效率的上限往往不再取决于命令熟练度,而取决于意图表达:文档、PR 描述、沟通方式,以及在 AI 参与时的边界与透明度。
文档、协作与 AI 礼仪 Link to this section
代码之外的沟通、协作与 AI 礼仪,同样是工程实践的一部分。
文档与沟通 Link to this section
README 结构、注释与提交信息(说明做了什么+为什么)。
提交信息格式:
<type>: <summary>;正文描述动机/风险;引用 Issue/PR。
社区协作 Link to this section
- Issues/PR 规范,小步提交,描述风险与测试,遵循模板。
AI 礼仪 Link to this section
- 标注 AI 辅助,审查输出,避免敏感数据。
接下来三节是课程页面暂未覆盖、但工程里经常用到的补齐项:数据处理、安全与杂项工具。来自往期资料,依旧很实用。
数据处理和管道思维 Link to this section
数据处理不仅是命令列表,更是方法论:先缩小、再结构化、最后统计/可视化。
方法论 Link to this section
先把数据变小:优先在数据源附近过滤(例如
ssh host ‘journalctl | …’),再传回本地处理。先结构化再统计:抽取字段(
sed/awk/jq)→ 排序/去重/计数(sort | uniq -c)→ 再做聚合/可视化。让管道可复用:每一步都能单独运行/检查;中间结果用
tee或重定向落盘,避免反复拉取远程数据。
文本处理与正则 Link to this section
sed -E 's/.*Disconnected from (invalid |authenticating )?user (.*) [^ ]+ port [0-9]+( \[preauth\])?$/\2/'
awk -F, '{print $2}' file.csv其他工具:
jq处理 JSON,pup解析 HTML,column -t对齐表格,perl one-liners。Vim 宏/ Python/ R 作为多行转换与统计工具;pandas/ggplot2 用于表格与可视化。
正则陷阱:贪婪 vs 非贪婪、捕获组复用(
\1/\2);perl -pe支持.*?。xargs 与 NUL:
find . -print0 | xargs -0 cmd避免空格/换行问题;grep -n、sed -n ‘1,10p’快速定位。CLI 统计/绘图:
paste -sd+ | bc -l,R –no-echo -e ‘summary(scan(“stdin”))’,gnuplot -p快速柱状图。
管道组合 Link to this section
sort | uniq -c | sort -nr
cut -d',' -f2 file.csv
paste file1 file2
join -t, file1 file2
tee out.txt | head
diff <(ls foo) <(ls bar)- 组合技巧:用
find -print0 | xargs -0处理特殊字符;grep -n显示行号,sed -n ‘1,10p’分段查看。
二进制与远程 Link to this section
hexdump -C file.bin | head
strings file.bin | head
ssh host 'journalctl | grep sshd' | less
ffmpeg ... | convert ... | gzip | ssh host 'gzip -d | feh -' # 管道同样适用于二进制安全习惯 Link to this section
安全是一套习惯与工具的组合:理解原理、配置好基础设施、养成默认安全的行为。
基础与密码学 Link to this section
- 熵、哈希、KDF(PBKDF2/scrypt/Argon2)、对称/非对称加密、密钥分发。
实践 Link to this section
密码管理器、2FA(TOTP/U2F)、全盘加密、私密通信、SSH 安全(禁用密码登录、管理私钥)。
安全习惯:最小权限、及时更新、不要在聊天/代码中泄露密钥;浏览器隔离(Multi-Account Containers)、广告/脚本阻断(uBlock)。
密码与钓鱼:长随机密码+管理器;警惕钓鱼域名/Token 泄露;硬件密钥优先。
Potpourri Link to this section
这里收纳了系统、生产力和云相关的杂项,适合按需查阅。
系统与生产力 Link to this section
- 键位映射、systemd service、FUSE、备份策略(增量/异地/校验)。
工具与环境 Link to this section
常见 CLI 模式、窗口管理器/VPN、Hammerspoon、启动介质制作。
APIs:
curl/jq访问 REST,OAuth token 管理,IFTTT 将服务事件串联。计划任务:
cron/systemd 定时任务。
虚拟化与云 Link to this section
Docker/Vagrant/VM/云的差异与取舍;Notebook 编程。
GPU/集群任务:自动排队与提交脚本,减少人工操作(对应 ML 工作流建议)。
Markdown/GitHub:Markdown 基础语法;GitHub 作为 git 托管与协作(Issues/PR/Actions),不要与 git 本身混淆。
常见问题 Link to this section
工具优先级:优先练习键盘快捷与少用鼠标;精通编辑器;自动化/简化重复任务;Git 协作。
Bash vs Python:bash 适合短小脚本和流水线,大型/复杂脚本用 Python/Ruby 等可复用库的语言;bash 容易被空格/引号坑,缺少模块化。
系统包管理 vs 语言包管理:
- 系统管理器(apt 等)版本稳定、可有二进制包;语言管理器(pip 等)更新快、依赖隔离更好。
- 避免混用同一包;推荐语言管理器+虚拟环境。
- 示例:
python -m venv .venv
source .venv/bin/activate
pip install requests- 包分发路径
/bin/lib等:PATH 中常见位置:/bin必要命令;/sbin系统命令;/usr/bin非必要命令;/usr/local/bin本地编译;/lib系统库;/opt可选软件;/etc系统配置;/var日志/缓存。- 使用
which/type查找:
echo $PATH
which pythonDocker vs VM:容器共享宿主内核,启动轻量但隔离弱且需兼容内核;VM 启动完整 OS 栈,隔离强但资源开销大;在 macOS 上跑 Docker 仍需隐藏的 Linux VM。
OS 选择与差异:滚动发行(如 Arch)新但偶有不稳定;LTS(Debian/Ubuntu)稳但更新慢;macOS 界面好但与 Linux 有差异;FreeBSD 文档好但兼容性差;Windows 仅在特定需求时使用。
浏览器/插件:uBlock Origin(阻止第三方请求,推荐 medium/hard mode)、Stylus(自定义 CSS)、Full Page Screen Capture、Multi-Account Containers(隔离 Cookie)、密码管理器扩展(防钓鱼域名)、Vimium 键盘导航。
2FA 与安全习惯:开启 2FA,优先 U2F 硬件密钥(YubiKey);SMS 2FA 有风险但胜过无;结合密码管理器使用。
ML 工作流与数据管理:为实验记录 JSON/CSV 元数据,用 shell 工具筛选聚合;自动化提交/排队 GPU 任务,减少人工干预。