那些微小的编程技巧
文章摘要
Will Keleher 这篇短文的论点很简单:日常工程生产力里有相当可观的一部分,来自那些零碎的小知识块——知道某个语言特性存在;知道一个莫名其妙的 TCP 延迟多半和 Nagle 算法与 TCP_NODELAY 有关;知道从某个烂摊子里脱身的那句 git 咒语;知道一个用 sed 改写文件的小花招。
作者承认这在某种意义上是自明的:你知道的任何东西都由更小的知识片段构成,那些片段当然重要。但他想强调的是另一类东西——有些知识块特别有价值,而且几乎不需要任何前置心智基础设施。你完全不必懂 Python,也能用 python3 -m http.server 在当前目录起一个静态服务器,而这可能就让你的工作轻松了一点。
文章随后列举了一串这样的例子,涵盖终端、SQL、正则、JS 和 git:
ctrl + r搜命令历史大家都知道,但装上 fzf 就能变成模糊搜索;atuin 更进一步,用 SQLite 数据库替换 shell 历史;per-directory-history 让你在「当前目录跑过的命令」和「全部历史」之间切换;历史条数本身也是可配置的。- SQL 的
SELECT可以不带FROM,用来临时试一个数据库函数的行为,或者提醒自己三值逻辑到底怎么回事。 - PostgreSQL 和 MySQL 都支持
explain analyze,它会真的执行你要优化的查询并给出远多于explain的性能信息。 - 正则里的
\b(单词边界断言)让匹配词首词尾变得容易。 - 对指标取对数可以快速看出某个字段的量级分布——先算
Math.floor(Math.log10(count))得到桶号,再把桶号作为标签打点。 - 现代 JS 已经有
Array.flatMap、Object.entries和Promise.withResolvers。 - 在 Node 里创建一个
https.Agent并传给请求(fetch(url, {method, agent})),可以保持到外部资源的连接,对延迟影响可能很显著。 git log -S pattern(俗称 git pickaxe)列出所有添加或删除过某个字符串的提交,在老代码库里极其好用;git log -G pattern类似但也会显示该行被移动的情况。- 类似
cd -,git checkout -可以切回上一个 HEAD。 - 你多半不需要
find:很多 find 命令可以用**/*.md这样的 glob 替代,大多数 shell 开箱支持,bash 需要shopt -s globstar。 - 同理,多数人应该用 rg(ripgrep)而不是 grep / ack / ag。
- zsh 的高级补全默认是关着的,需要手动
autoload -Uz compinit并compinit(用 Homebrew 的话还要把 site-functions 加进 FPATH,写法是FPATH="$(brew --prefix)/share/zsh/site-functions:${FPATH}")。
文章的后半段其实才是重点。作者指出,在一家公司内部,更多的知识恰恰是这种「小而高杠杆」的颗粒:要排查某个问题该去看哪个数据源;某个领域谁最懂而且乐意帮忙;某个难点的好文档藏在哪;某个现象出现时意味着该手动扩容了;怎么滚动重启某个服务;哪个内部小工具让某类问题变得容易脚本化。他在上一家公司每天在 Slack 上给工程团队分享一个技巧,技术的和公司特定的都有,反馈相当好——即使十个里你知道九个,剩下那一个也可能帮你省下时间;而每天一个是刚好不会让人信息过载的剂量,偶尔还能激发有用的讨论。他建议资深工程师可以考虑做类似的事,并把这个做法的源头归给 Julia Evans 的博客,称她的写作完美体现了这篇文章的内核:小知识是有力量的、有趣的、可亲近的。
HN 评论精华
「AI 时代还有人手写代码吗」——本帖最大的一条支线。 behnamoh 借题发问:他所在的学术圈已经「基本没人自己写代码了」,一方面挺可惜,编程的乐趣被无休止的 agent 编排取代了;另一方面生产力提升太大,回不去了。他说自己当年学这些小技巧是有快乐的——nvim 的新用法、fish 的新快捷键、一个新的 vim 宏、bash 里单方括号和双方括号的区别——但现在这些好像全都无关紧要了。
回复呈现出一个相当分裂的图景。louthy 的反驳最有代表性:写了 41 年代码,他是「用代码思考」的,代码从大脑流经手指几乎不费力;把想法翻译成英文让 LLM 再翻译回代码比他自己写慢得多,而且一旦进入心流,最不需要的就是被提示循环打断。bigstrat2003 的理由更实际:LLM 出代码快,但他得逐行审查以确认正确,这花的时间和自己写差不多。catlifeonmars 说他在公司完全手写,同事几乎都不是,但他依然跟得上进度——不是炫耀,而是想指出在他的领域(绿地网络安全设备),写代码根本不是瓶颈。skydhash 描述了另一种分工:手写主要用于探索,其余时间大量花在读文档和思考上,而思考多半发生在离开电脑的时候。
acedTrex 提出了一个被忽略的角度:他确实不怎么亲手敲代码了,但他仍然整天在 shell 里穿梭做别的事,所以这些技巧每天都在用;他反过来问,真的有人只通过 LLM 和计算机交互吗,如果是真的那也太离谱了。这条正面回应了 monideas 那句「在 AI 时代这些几乎全都无关紧要,除了取对数那条」——bigfishrunning 的回敬很脆:「在 AI 时代用计算机也无关紧要了,你应该停止这么做。」
用 AI 学技巧的反向用法。 kccqzy 提出了本帖最有建设性的一条:与其让 AI 自主执行,不如退回到手动批准每条命令的模式——他最近做性能优化时,发现 Opus 用 perf 的方式是他闻所未闻的。给 AI 一个真实任务,认真读它用了什么命令,大概率能捡到一两个你不知道的技巧。teekert 附议,说这不会让他记住命令,但会让他知道什么是可能的。shinyoo 泼了冷水:恐怕大多数人最后只会机械地按「批准」,被 AI 的输出量和速度淹没时,没人有精力停下来看每一条的推理;而且 AI 接管了那些原本靠「做中学」积累技能的工作,我们内化技能的机会只会更少。noduerme 抱怨了一个具体的坏处:同一个模型同一天写的 CLI 脚本,参数风格都不统一,有时按等号切分,有时按空格和奇偶顺序配对。butterNaN 补充:有时候一个简单的 jq 就能解决的事,Opus 会做出疯狂的 shell 体操。
关于「分享技巧」这件事本身。 winternewt 指出了分享的尴尬:你知道的东西对你总是显得显而易见,很难判断别人到底不知道什么,分享大家都知道的东西又有显得傲慢的风险。happytoexplain 的反驳被顶得很高:不存在「所有人都知道的事」,东西太多了;哪怕一份很基础的清单,大概率也包含一件我不知道或忘了的事;他自己的实践知识大部分来自这类写作,而不是来自 RTFM(他确实也读手册)。他还说,我们不应该去验证那种「怕被当成有人格缺陷」的自我审查感。NegativeLatency 坦承作者那个「每天在 Slack 发一条」的做法会让他觉得烦,但他不会说出来以免显得像混蛋;blooalien 提出了折中方案——开一个可选的专门频道;saulpw 的回应很锋利:「把『被看作』去掉。烦躁是个线索,不是关于他们的,是关于你的。」
对内容本身的补充和异议。 VCFundedGenYer 认为标题应该改成「bash/zsh 命令行技巧」,因为这些和编程只有切线关系。wiredfool 指出用高级 glob 替代 find 有个坑:匹配上千个文件时很容易撞到参数展开上限,那时还是得回到 find。IsTom 直言 find 能做的远不止这些;laweijfmvo 承认 Unix「每个命令只做一件事」的哲学在 find 这里崩塌了,并推荐更友好的现代替代品 fd;deathanatos 给出了最好的解释——多数人没意识到 find 的第二组参数是一个表达式,是一门迷你 DSL,一旦理解了这一点,括号为什么要转义之类的问题就都自洽了,只是 -prune 和 -exec 这些带副作用的谓词确实让人困惑。kccqzy 不同意「从 ag 换到 rg」是无条件更好:rg 的 -g 用 glob 过滤文件,比 ag 的 -G(用正则)啰嗦得多,为此多敲很多字符只换来 0.1 秒。
读者自己的私货。 出现频率最高的是 zoxide(记住你去过的目录、替代 cd)和 atuin(把 shell 历史换成可搜索的 SQLite 库,还支持密钥过滤和跨机同步)。BeetleB 的玩法更进一步:按 Alt+J 把 zoxide 里所有目录按频率送进 fzf,选一个就跳过去,他已经几乎不打 cd 了。phforms 提出了一个很多人共鸣的问题:这些技巧的难点不是知道,而是养成使用它们的习惯——他早就知道 ctrl+r 甚至配好了 fzf 集成,却还是用了多年上下箭头,因为那是阻力最小的路径;他的解法是把这些东西按语言和工具分类写进一个自己知道去哪儿翻的文档目录。lelandbatey 的做法更硬核:为了从 git checkout 改用 git switch,他写了一段 bash 在自己手打 checkout 时报错并「训斥」他,同时又不影响脚本调用。reaperducer 提到上个世纪的人也有同样的问题,他们用套在键盘上的快捷键模板卡;今天最好的替代品就是把常用命令打印出来贴在显示器旁边。其他零散贡献包括:git log -S(多人独立提名)、rg --hidden -g '!*.lock' 跳过噪音、python3 -m json.tool 美化 API 响应、macOS 上的 pbcopy 把输出直接管到剪贴板、几乎没人知道的 script 命令(录制整个终端会话包括输出到文件),以及 O’Reilly 那本经久不衰的《Unix Power Tools》。