目录
2576 字
13 分钟
技术黑话词典:从「在我机器上是好的」到「这是个特性」

一场事故复盘会,有人说了句「这是个概率性问题」,会议就散了。

这句话的信息量是零,但它的效率是满分。它听起来像一个技术判断,实际是一个社交动作——意思是「我还没查清楚,但如果继续追下去,今天下不了班」。

技术黑话不是骗子的话术,它是长期在压力下形成的语言压缩。压缩的代价很直接:信息丢了,责任也模糊了。下面这份词典,每一条都试着把这层压缩解开,看看底下藏着什么。

一、甩锅类:把问题推给一个不可证伪的对象#

「在我机器上是好的」#

翻译:代码没问题,是你的环境有问题——而且我不打算查是哪里不一样。

这句话最气人的地方在于,它经常是对的。环境差异是真实存在的技术问题,只是没人愿意为它负责。常见的根因就那几个:

  • lockfile 没提交,或者别人跑了 npm install 而不是 npm ci,传递依赖每次解析出不同版本;
  • PATH 里躺着两份 Node,终端里是 v22,IDE 里是 v18;
  • 环境变量只在 .env 里有,CI 上压根没配,于是连的是另一个数据库;
  • 文件系统大小写:macOS 的 APFS 默认大小写不敏感,import './Button' 在本地能过,到了 Linux 上因为真实文件叫 button.tsx 而报错;
  • 本地时区、本地 glibc 版本、本地装了某个全局工具。

止血方式也早就有了,只是需要有人愿意做:lockfile 进仓库、CI 用 npm ci、运行时版本写进 .nvmrcmise.toml、配置从代码里赶出去(12-Factor 的第三条)。这套东西的收益不是「少吵几次架」,而是让「在我机器上是好的」这句话变得没有意义

「你重启一下试试」#

这是整份词典里最诚实的一句——它承认自己不知道原因,但它知道一个几乎总有效的操作。

重启不是玄学,重启是状态重置。它有效,说明问题出在进程的累积状态里。候选者:内存泄漏、连接池或文件描述符泄漏(未 close 的 socket 最终撞上 EMFILE)、全局单例里越攒越多的对象、缓存里的脏数据、某个未捕获的 Promise rejection 让一处状态机永久卡死。

所以「重启一下好了」应该被当成线索而不是结论。一个服务如果每周都需要重启,它已经在用泄漏速度告诉你它病在哪了。

「这是缓存问题」#

缓存是最容易被栽赃的组件:它确实经常是原因,而且清它的成本看起来很低。

但「缓存问题」不是诊断,是猜测。想验证,成本也不高:

Terminal window
curl -sI https://example.com/api/posts \
-H 'Cache-Control: no-cache' \
| grep -iE 'age|x-cache|cache-control|etag'

Age 很大说明命中的是旧副本,X-Cache: HIT 说明前面真有一层缓存在拦。

而真正的缓存问题,形态基本只有三种,清缓存一个都治不了

  1. 缓存键漏了维度——多租户场景下 key 里只有资源 id 没有租户 id,于是 A 的数据被返回给了 B。这是事故,不是性能问题。
  2. 失效策略错——写入时忘了让缓存失效,或者 TTL 长得离谱,用户改完资料刷新十次还是旧的。
  3. 缓存击穿——大批 key 同时过期,流量瞬间打穿到数据库,把数据库也带走。

二、状态描述类:把 bug 说成设计#

「这是个特性,不是 bug」#

这句话有一半时候是真的,而它成真的机制有个名字:Hyrum 定律——当你的接口有了足够多的用户,你对其所有可观察行为的依赖都不再是偶然,而是契约的一部分。

一个真实形态的例子:某接口在列表为空时返回 null 而不是 []。下游五百个服务老老实实写了 if (res == null) { ... }。三年后你想修这个「显然的 bug」,代价是发大版本、写迁移指南、挨个通知调用方。兼容性成本已经超过了正确性收益,于是 bug 就地转正,领取了「特性」的编制。

这句黑话在多数场合是自我解嘲,但它的技术内核是硬的:正确性不是免费的,它要和兼容性竞价。

「预期行为」#

上一句的正式版本,通常出现在 issue tracker 的关闭理由里,和 WONTFIX 的区别只在于礼貌程度。

三、偶现类:把不确定性当成不可知#

「偶现」「概率性问题」#

翻译:我复现不出来,而且我怀疑复现需要条件。

这类问题的根因几乎总在这几类里:竞态(多线程/多协程读写共享状态没有同步)、时序依赖(隐含假设某个网络请求会先返回)、未初始化或已释放的资源、GC 时机、时钟。

它们的共同点值得单独拎出来说:代码不是「有时候错」,而是代码对执行顺序有隐含假设,而这个假设不总是成立

所以正确的做法不是反复尝试「复现」,而是把不确定性变成可观测性:

Terminal window
# Go:竞态检测器,专治「本地跑一万次都没事」
go test -race -count=10000 ./...
# Node:把未捕获的 Promise 拒绝变成崩溃,而不是静默
node --unhandled-rejections=strict app.js

加日志时带上 request id 和协程/线程 id,把顺序记下来。概率性 bug 只要样本足够,一定会复现——它缺的只是样本量,不是运气。

「线上没复现出来」#

翻译:生产和我们能碰的环境不一样。

真正的差异通常不在代码,而在数据:生产有几亿行、有真实并发、有三年前那次迁移留下的空字段。本地拿一张十行的 users 表测出来的「没问题」,不能说明任何事。

缩短差距的办法是具体的:生产数据脱敏后灌进预发、做流量回放、用 feature flag 灰度而不是一把梭全量。

四、稳定性类:把放大器当成修复#

「加个重试就好了」#

这条是整篇词典里最危险的一句。

重试真正能治的只有一类问题:瞬时故障——网络抖动、单个副本重启、被限流。超出这三类,重试都在帮倒忙:

  • 下游如果是因为过载而超时,重试等于继续加压。一次故障就是这样被放大成全站故障的,它有专门的名字:retry storm
  • 操作如果不幂等,重试就变成了重复扣款、重复发券、重复建单。

一条能上线的重试,至少要凑齐五个条件:有上限、有指数退避、有抖动(否则所有客户端会在同一毫秒一起重试,形成同步尖峰)、只对可重试的错误码重试(400/404 重试毫无意义)、配熔断。写操作还必须带幂等键。

// 退避 + 抖动 + 上限 + 熔断,一个都不能少
const base = 100, cap = 5000, maxAttempts = 5;
async function retryable(fn, attempt = 1) {
try {
return await fn();
} catch (err) {
if (attempt >= maxAttempts || !isTransient(err)) throw err;
const exp = Math.min(cap, base * 2 ** (attempt - 1));
// full jitter:在 [0, exp] 里随机,避免重试风暴
await sleep(Math.random() * exp);
return retryable(fn, attempt + 1);
}
}

少任何一个条件,这段代码都是一颗定时炸弹。

「先这样,后面再优化」#

翻译:没有 ticket 的重构,等于永不重构。

这句不只是笑话。临时方案有个致命特性:它会变成事实标准,然后被依赖,然后按 Hyrum 定律变得不可移除。于是「后面再优化」这句话的诚意是可以被验证的——有没有开 issue、有没有写进本季度的待办、有没有设一个真的会响的提醒。三者全无,那就是「永不」。

五、AI 时代的新黑话#

旧黑话还没退休,新的一批已经上岗了。

「模型幻觉」#

「幻觉」是个正儿八经的学术词,现在被用成了万能背锅词。但真实的失败模式至少有四种,对症下药完全不同

你看到的现象真实原因该做的事
答了但完全是编的知识不在模型里上 RAG,把资料检索进上下文
资料给它了还是答错检索到的片段不对调分块策略、加重排
格式/字段总是错指令遵循失败结构化输出、约束解码
同一问题答案飘忽采样随机性降温度、自洽性投票

把四类都叫「幻觉」,约等于把 404500、超时统称为「网络不好」——听着像结论,实际是放弃了。

「是提示词的问题」#

先确认你要的信息到底在不在上下文里。 提示词调得再漂亮,也变不出没给它的事实。绝大多数被归为「提示词问题」的故障,翻到最后都是上下文里根本没有那一条。

「这个 case 模型没学过」#

多数时候,它是学过,但你的调用方式让它没机会答对。

黑话的自我修养#

黑话不是罪。它是团队的速记:说「在我机器上是好的」比说「我怀疑是 lockfile 未提交导致的传递依赖漂移」快十倍。

问题出在信息量的差距。前者让人停下,后者让人继续

所以给一条能落地的建议:黑话可以说,但后面跟一句提问方向。

  • 「这是缓存问题。」——讨论结束了。
  • 「这是缓存问题吗?我看下 X-Cache 是不是 HIT。」——讨论开始了。

复盘会上最贵的成本从来不是故障本身,而是「偶现」「概率性」这类词把复盘提前按停。无责复盘(blameless postmortem)的核心原则是追机制不追人,但这一切有个前提:这个机制得先被说出来

参考来源#

技术黑话词典:从「在我机器上是好的」到「这是个特性」
https://www.hehonglei.cn/posts/tech-jargon-dictionary/
作者
Honglei He
发布于
2026-09-20
许可协议
CC BY-NC-SA 4.0