<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>工程实践 on 方糖猫Blog</title>
    <link>https://ftmao.com/blog/tags/%E5%B7%A5%E7%A8%8B%E5%AE%9E%E8%B7%B5/</link>
    <description>AI 视频、AI Agent 与工程实践笔记</description>
    <generator>Hugo</generator>
    <language>zh-CN</language>
    <lastBuildDate>Sun, 08 Oct 2023 10:40:00 +0800</lastBuildDate><atom:link href="https://ftmao.com/blog/tags/%E5%B7%A5%E7%A8%8B%E5%AE%9E%E8%B7%B5/index.xml" rel="self" type="application/rss+xml" /><item>
      <title>《思考，快与慢》笔记：给大脑的偏差清单打个包</title>
      <link>https://ftmao.com/blog/bookstore/thinking-fast-and-slow-book-notes/</link>
      <pubDate>Sun, 08 Oct 2023 10:40:00 +0800</pubDate>
      <guid>https://ftmao.com/blog/bookstore/thinking-fast-and-slow-book-notes/</guid>
      <description>&lt;h1 id=&#34;思考快与慢笔记给大脑的偏差清单打个包&#34;&gt;《思考，快与慢》笔记：给大脑的偏差清单打个包&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;Daniel Kahneman 的《思考，快与慢》（Thinking, Fast and Slow，2011）严格说不是一本&amp;quot;方法论&amp;quot;书——它更像一份&lt;strong&gt;人类认知系统的 bug 报告合集&lt;/strong&gt;。Kahneman 是心理学家，却拿了 2002 年诺贝尔经济学奖（领奖时他的老搭档 Amos Tversky 已过世），因为这本书背后的研究直接掀了&amp;quot;理性人&amp;quot;假设的桌子。&lt;/p&gt;
&lt;p&gt;作为工程师，我读这本书的姿势很功利：把大脑当一套系统，书里每个偏差就是一条已知的、可复现的 bug。bug 修不掉（进化写死的），但可以打监控、加护栏、写进 checklist。这篇笔记就是这个思路的产物——&lt;strong&gt;不是书摘，是一份偏差清单的打包分发&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;全书五百多页，我把它拆成三块：双系统模型（bug 的运行时环境）、十大核心偏差（bug 本体）、工程落地（怎么在日常工作中绕开它们）。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id=&#34;一全景系统-1-和系统-2-的分工&#34;&gt;一、全景：系统 1 和系统 2 的分工&lt;/h2&gt;
&lt;p&gt;Kahneman 把思考拆成两个&amp;quot;系统&amp;quot;——注意，这是两个&lt;strong&gt;虚构的代理人&lt;/strong&gt;，是为了描述方便，大脑里没有真的两个模块，别当真去找解剖位置：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;系统 1（快思考）&lt;/strong&gt;：自动、并行、不费力气。认人脸、读母语、听到&amp;quot;2+2&amp;quot;立刻想到 4、躲开飞过来的东西。它 7×24 小时在线，关不掉。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;系统 2（慢思考）&lt;/strong&gt;：需要集中注意力、按规则运算。算 17×24、填报税表、在人群中找一个穿红衣服的人。它很懒，能不启动就不启动，启动了还会带来瞳孔放大、心跳变化这些生理代价。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;关键设定是：&lt;strong&gt;系统 2 默认信任系统 1 给出的答案，只在&amp;quot;感觉不对劲&amp;quot;时才介入审查&lt;/strong&gt;。而&amp;quot;感觉不对劲&amp;quot;本身也是系统 1 判断的——这就是整个偏差体系的入口。&lt;/p&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;flowchart TB
    IN[&amp;#34;外部问题 / 决策场景&amp;#34;] --&amp;gt; S1[&amp;#34;系统 1&amp;lt;br/&amp;gt;直觉、联想、自动激活&amp;lt;br/&amp;gt;快、省力、永不休息&amp;#34;]
    S1 --&amp;gt;|&amp;#34;给出直觉答案&amp;#34;| GATE{&amp;#34;系统 2 审查&amp;lt;br/&amp;gt;懒、容量有限、默认放行&amp;#34;}
    GATE --&amp;gt;|&amp;#34;看起来没毛病&amp;lt;br/&amp;gt;(大多数情况)&amp;#34;| OUT1[&amp;#34;直接采纳直觉答案&amp;#34;]
    GATE --&amp;gt;|&amp;#34;感觉不对劲&amp;lt;br/&amp;gt;或任务明确要求计算&amp;#34;| S2[&amp;#34;系统 2 接管&amp;lt;br/&amp;gt;规则运算、逻辑核查&amp;#34;]
    S2 --&amp;gt; OUT2[&amp;#34;审慎结论&amp;#34;]
    S1 -.-&amp;gt;|&amp;#34;出错路径 ①&amp;lt;br/&amp;gt;直觉本身有系统性偏差&amp;lt;br/&amp;gt;(锚定/可得性/代表性...)&amp;#34;| OUT1
    S2 -.-&amp;gt;|&amp;#34;出错路径 ②&amp;lt;br/&amp;gt;系统 2 太累/太懒&amp;lt;br/&amp;gt;放弃审查或草率放行&amp;#34;| OUT1&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;p&gt;系统 2 到底有多懒？书里最著名的一道测试题是&amp;quot;球拍和球&amp;quot;（Cognitive Reflection Test 的首题）：球拍和球一共 1.10 美元，球拍比球贵 1 美元，球多少钱？超过一半的哈佛、MIT、普林斯顿学生脱口而出 0.10 美元——正确答案是 0.05 美元（验算：0.05 + 1.05 = 1.10）。题目不难，难的是系统 2 愿不愿意起来验算一遍。这就是&amp;quot;认知懒惰&amp;quot;的常态：&lt;strong&gt;直觉答案先到，系统 2 看都不看就放行了&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;这张图解释了为什么&amp;quot;我知道有偏差&amp;quot;并不能让我免于偏差：&lt;strong&gt;知道偏差是系统 2 的知识，而犯偏差是系统 1 的操作&lt;/strong&gt;。书读完了，系统 1 一行代码都没改。所以对抗偏差的正解不是&amp;quot;以后注意点&amp;quot;，而是改造流程和环境，让偏差在触发前就被拦下——这一点贯穿本篇后面的所有落地建议。&lt;/p&gt;
&lt;p&gt;还有一个对工程师很实际的推论：系统 2 的容量是有限的，而且会被消耗。注意力被占满时（赶 deadline、半夜 oncall、连续开会），人会&lt;strong&gt;更多地依赖系统 1&lt;/strong&gt;——也就是说，你越累、越忙，越容易被偏差带走，而你偏偏在这些时刻做的决策往往代价最高。重要的方案评审别排在周五下午，重要的估算别在半夜拍，这不是养生建议，是认知带宽管理。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;感悟&lt;/strong&gt;：这套分工跟我们写系统一模一样——一个热路径（系统 1）处理 99% 的请求，追求低延迟；一个冷路径（系统 2）处理疑难 case，追求正确性但贵。所有的问题都出在&lt;strong&gt;流量分配策略&lt;/strong&gt;上：本该走冷路径的请求被热路径直接应答了。性能优化的思路反过来用，就是认知纠偏的思路。&lt;/p&gt;
&lt;p&gt;类比再推进一步：给热路径加监控告警（哪些决策类型历史上误判率高）、给高风险请求做强制路由（评审清单、双人复核）、给冷路径预留容量（重要决策安排在认知带宽充足的时间）——这三件事在认知工程和系统工程里是逐条对应的。后面第五节的三条落地实践，其实就是这套类比的展开。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;二偏差拆解上直觉是怎么编故事的&#34;&gt;二、偏差拆解（上）：直觉是怎么编故事的&lt;/h2&gt;
&lt;p&gt;这一节五个偏差，共同点是：系统 1 在&lt;strong&gt;回答问题时偷偷换了题目&lt;/strong&gt;。你问它一个难的问题，它答一个容易的相关问题，然后把答案交差——Kahneman 称之为&amp;quot;替代问题&amp;quot;（substitution）。&amp;ldquo;这只股票值得买吗&amp;quot;被换成&amp;quot;我喜欢这家公司吗&amp;rdquo;；&amp;ldquo;这个候选人能胜任吗&amp;quot;被换成&amp;quot;他面试表现好吗&amp;rdquo;。配套还有一条更底层的设定，缩写叫 &lt;strong&gt;WYSIATI&lt;/strong&gt;（What You See Is All There Is，所见即全部）：系统 1 只用&lt;strong&gt;当前可得的信息&lt;/strong&gt;编故事，从不主动追问&amp;quot;我不知道的那部分有多大&amp;quot;。理解这两句话，下面每个偏差都只是它们的实例化。&lt;/p&gt;
&lt;h3 id=&#34;21-锚定效应anchoring&#34;&gt;2.1 锚定效应（Anchoring）&lt;/h3&gt;
&lt;p&gt;先给你一个无关的数字，再让你估计另一个数字，你的估计会被那个无关数字拖着走。经典实验（Tversky &amp;amp; Kahneman，1974）：让被试转一个被动过手脚的轮盘，只会停在 10 或 65，然后问&amp;quot;非洲国家在联合国中占比多少？&amp;quot;。转到 10 的组平均估 25%，转到 65 的组平均估 45%。一个明摆着随机的轮盘数字，把专业估计拖偏了 20 个百分点。&lt;/p&gt;
&lt;p&gt;机制有两层：一是系统 1 会做&amp;quot;锚定调整&amp;quot;，从锚出发往下调，但&lt;strong&gt;总是调得不够&lt;/strong&gt;；二是锚会激活与之一致的联想——听到 65，你的大脑会自动搜索&amp;quot;非洲国家占比可能很高&amp;quot;的证据。&lt;/p&gt;
&lt;p&gt;锚定最阴险的地方在于它不需要锚&amp;quot;合理&amp;quot;。书里还提过类似的实验变体：即便是明说&amp;quot;这个数字是随机转出来的&amp;quot;，被试照样被锚住。系统 1 对接收到的数字一视同仁地激活联想，理性与否是系统 2 的事，而系统 2 经常缺席。&lt;/p&gt;
&lt;p&gt;工程里最鲜活的例子就是排期谈判：第一个说出口的工期数字就是锚。老板说&amp;quot;这个两周能搞定吧&amp;quot;，你后面所有的挣扎都只是在 2 周基础上&amp;quot;调整&amp;quot;，而不是从任务本身出发估算。反制手段也简单：&lt;strong&gt;别让对方先开口&lt;/strong&gt;。谈判前先自己做完独立估算，写下来，再去听别人的数字——锚一旦先进了你的脑子，再拔就难了。&lt;/p&gt;
&lt;h3 id=&#34;22-可得性偏差availability&#34;&gt;2.2 可得性偏差（Availability）&lt;/h3&gt;
&lt;p&gt;判断一件事的发生频率或概率时，系统 1 用的启发法是&amp;quot;&lt;strong&gt;我能多快想起例子来&lt;/strong&gt;&amp;quot;。想得起 = 常见。问题在于记忆的提取难度和真实频率并不相关——媒体大量报道的事件（空难、恐怖袭击）会被高估，平淡的、不报道的（车祸、普通疾病）会被低估。&lt;/p&gt;
&lt;p&gt;书里还有个微妙的版本：让被试列举自己&amp;quot;果断&amp;quot;的例子，列 6 条的组觉得自己挺果断，列 12 条的组反而觉得自己不果断——因为列到后面想不出来了，&amp;ldquo;想不出来&amp;quot;这个体验本身成了证据。&lt;strong&gt;系统 1 用的不是例子的内容，是提取例子的流畅感。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;技术选型是这个偏差的重灾区。&amp;ldquo;XX 数据库最近总看到翻车帖&amp;quot;和&amp;quot;XX 数据库真实故障率&amp;rdquo;，是两件完全不同的事，但评审会上站出来发言的人，手里举的永远是前者。写翻车复盘文章的公司是少数，沉默的大多数不构成&amp;quot;可得&amp;quot;的记忆。反制手段就一句话：&lt;strong&gt;查数据，别查记忆&lt;/strong&gt;——选型前先问&amp;quot;有没有统计口径的对比&amp;rdquo;，没有就承认自己在凭印象下注。&lt;/p&gt;
&lt;h3 id=&#34;23-代表性偏差representativeness与基础概率忽视&#34;&gt;2.3 代表性偏差（Representativeness）与基础概率忽视&lt;/h3&gt;
&lt;p&gt;系统 1 判断&amp;quot;A 属于类别 B 的概率&amp;quot;靠的是&amp;quot;像不像&amp;quot;，而不是统计学意义上的概率。像 = 概率高。这直接导致两个连环错误：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;基础概率忽视（Base Rate Neglect）&lt;/strong&gt;：给一段人物描述&amp;quot;害羞、细致、爱整洁、喜欢条理&amp;quot;，问这人是图书管理员还是农民？绝大多数人说图书管理员——完全无视美国农民数量是图书管理员的几十倍。描述再&amp;quot;像&amp;quot;，也架不住基数差几个数量级。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;合取谬误（Conjunction Fallacy）&lt;/strong&gt;，就是著名的 Linda 问题（Tversky &amp;amp; Kahneman，1983）：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Linda，31 岁，单身，性格直率，非常聪明。大学主修哲学，在校期间深切关注歧视与社会公正问题，还参加过反核示威。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;问：哪个更可能？① Linda 是银行柜员；② Linda 是银行柜员，并且是女权运动的活跃分子。绝大多数被试选 ②。但 ② 是 ① 的&lt;strong&gt;子集&lt;/strong&gt;——&amp;ldquo;柜员且女权&amp;quot;的概率不可能大于&amp;quot;柜员&amp;rdquo;。细节越丰富、故事越&amp;quot;像&amp;quot;，系统 1 就越觉得可信，哪怕逻辑上概率在变低。&lt;/p&gt;
&lt;p&gt;这个实验当时遭到了不少学界的反弹，后续研究者换着花样验证——把选项写成&amp;quot;① 柜员且女权；② 柜员（无论是不是女权）&amp;quot;，照样有人选错；找统计系的研究生来做，正确率也只是从惨不忍睹变成勉强及格。Kahneman 在书里的总结很到位：这不是知识问题，是直觉系统对&amp;quot;生动叙事&amp;quot;的偏好压过了逻辑规则。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;感悟&lt;/strong&gt;：合取谬误在工程里的化身是&amp;quot;事故报告写得越详细越显得可信&amp;quot;。一个把因果链讲得丝丝入扣的事后分析，往往比一个诚实的&amp;quot;我们也不确定&amp;quot;更能说服人——而前者恰恰更可能是编的。详细的叙事 ≠ 高概率，这是评审任何复盘材料时该挂在墙上的话。&lt;/p&gt;
&lt;p&gt;基础概率忽视在工程里还有个日常版：监控告警响了，&amp;ldquo;看起来像数据库连接池耗尽&amp;rdquo;，于是直接去查连接池——但这类症状的历史分布里，七成其实是上游流量突增。&amp;ldquo;像不像&amp;quot;是最贵的诊断方式，先查历史分布（这类告警八成是什么引起的）再动手，平均能省一半的定位时间。&lt;/p&gt;
&lt;h3 id=&#34;24-回归均值regression-to-the-mean&#34;&gt;2.4 回归均值（Regression to the Mean）&lt;/h3&gt;
&lt;p&gt;这是全书里我觉得最反直觉、也最容易被误用的一条。Kahneman 自己的故事：他给以色列空军飞行教官讲课，说奖励比惩罚更能促进行为改善。一位教官反驳：&amp;ldquo;你说反了。学员飞得特别好的时候我夸他，下次准飞得差；飞得砸的时候我骂他，下次准飞得好。骂就是比夸管用。&amp;rdquo;&lt;/p&gt;
&lt;p&gt;真相是：飞行表现围绕一个均值随机波动，&lt;strong&gt;一次超水平发挥之后，下一次大概率回落；一次砸锅之后，下一次大概率回升&lt;/strong&gt;——跟骂不骂没关系。教官观察到的是纯粹的回归均值，却归因给了自己的奖惩。这个案例的杀伤力在于：那位教官有一辈子的&amp;quot;数据&amp;rdquo;，每一架次都&amp;quot;验证&amp;quot;了他的结论，而他错得彻头彻尾。&lt;/p&gt;
&lt;p&gt;工作里的翻版比比皆是：团队某次线上事故后狠抓一波流程，下个季度事故果然少了——是流程见效，还是事故本来就在均值附近波动？不做对照，你永远分不清。同样的结构还有：给绩效最差的团队派帮扶专家，下季度他们&amp;quot;果然&amp;quot;好转了；球员上了《体育画报》封面后表现下滑（著名的&amp;quot;封面魔咒&amp;quot;），其实不过是巅峰表现之后的自然回落。&lt;strong&gt;凡是&amp;quot;极端值 + 干预 + 好转&amp;quot;的叙事，先按回归均值打折，再谈干预效果。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;这一条之所以重要，是因为它专门腐蚀&amp;quot;经验&amp;quot;。那位飞行教官不是不聪明，他是被真实数据骗的——数据不会说话，解释才说话，而系统 1 永远优先提供&amp;quot;我的干预有效&amp;quot;这个解释。对抗它的唯一办法是流程化的：干预前后设对照、看更长的窗口、或者干脆承认小样本上什么也证明不了。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;三偏差拆解下人是怎么做选择的&#34;&gt;三、偏差拆解（下）：人是怎么做选择的&lt;/h2&gt;
&lt;p&gt;这一节五个偏差，发生在&amp;quot;权衡收益与损失、预测未来、回看过去&amp;quot;的场景里。如果说上一节的偏差是&amp;quot;系统 1 答错题&amp;quot;，这一节的偏差就是&amp;quot;系统 1 在计价时动了手脚&amp;quot;——同样一笔钱、同一段时间、同一个结果，换了个位置（我的/不是我的、得到的/失去的、事前/事后），大脑给出的估值完全不同。&lt;/p&gt;
&lt;h3 id=&#34;31-损失厌恶与前景理论prospect-theory&#34;&gt;3.1 损失厌恶与前景理论（Prospect Theory）&lt;/h3&gt;
&lt;p&gt;这是 Kahneman 和 Tversky 1979 年提出的理论，也是整本书的学术内核。核心就一句话：&lt;strong&gt;损失带来的痛苦，大约是等量收益带来的快乐的两倍&lt;/strong&gt;（损失厌恶系数约 2:1，不少实验测出来在 1.5-2.5 之间）。&lt;/p&gt;
&lt;p&gt;经典赌局实验：抛硬币，正面你赢 150 美元，反面你输 100 美元，玩不玩？期望收益是 +25 美元，纯理性该玩——但绝大多数人拒绝。要让多数人愿意上桌，赢的金额得加到 200 美元左右，即&lt;strong&gt;潜在收益得约两倍于潜在损失，赌注才显得&amp;quot;公平&amp;quot;&lt;/strong&gt;。&lt;/p&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;flowchart LR
    subgraph 传统期望效用
        A[&amp;#34;输赢按金额线性计价&amp;lt;br/&amp;gt;100 元 = 100 元&amp;#34;] --&amp;gt; AR[&amp;#34;理性人:&amp;lt;br/&amp;gt;+25 期望就该玩&amp;#34;]
    end
    subgraph 前景理论
        B[&amp;#34;价值函数:&amp;lt;br/&amp;gt;参照点以上凹(怕失去)&amp;lt;br/&amp;gt;参照点以下凸且更陡&amp;#34;] --&amp;gt; BR[&amp;#34;损失 -100 的痛感&amp;lt;br/&amp;gt;≈ 收益 +200 的快感&amp;lt;br/&amp;gt;(损失厌恶 ≈ 2:1)&amp;#34;]
    end
    A --&amp;gt; C[&amp;#34;关键修正:&amp;lt;br/&amp;gt;人评估的是&amp;#39;相对参照点的得失&amp;#39;&amp;lt;br/&amp;gt;不是绝对财富&amp;#34;]
    B --&amp;gt; C&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;p&gt;前景理论还有一个推论经常被人忽略：&lt;strong&gt;得失是相对&amp;quot;参照点&amp;quot;说的，而参照点是可以被话术移动的&lt;/strong&gt;。&amp;ldquo;你这单能省 500&amp;quot;和&amp;quot;你再不下单就亏 500&amp;quot;是同一笔钱，后者杀伤力大得多——因为后者把参照点设在了&amp;quot;已拥有&amp;rdquo;。&lt;/p&gt;
&lt;p&gt;损失厌恶在日常工程决策里最常见的表现是&amp;quot;不敢动&amp;quot;：明知某个服务该下线、某段代码该重写，但&amp;quot;动它有风险、出问题算我的&amp;quot;的损失感，永远压过&amp;quot;改完长期受益&amp;quot;的收益感——哪怕后者期望值为正。这时候有个好用的思维工具：&lt;strong&gt;把决策翻译成&amp;quot;如果今天从零开始，我还会选现状吗？&amp;quot;&lt;/strong&gt; 不会，就说明你在为损失厌恶付费，不是在为理性付费。&lt;/p&gt;
&lt;h3 id=&#34;32-禀赋效应endowment-effect&#34;&gt;3.2 禀赋效应（Endowment Effect）&lt;/h3&gt;
&lt;p&gt;一旦某样东西被算作&amp;quot;我的&amp;quot;，放弃它的痛苦立刻按损失计价。经典实验（Kahneman, Knetsch &amp;amp; Thaler，1990）：随机把马克杯发给一半被试，然后让有杯子的人报价卖、没杯子的人报价买。按理性假设两边的估价应该接近，结果&lt;strong&gt;卖家的要价中位数大约是买家出价的两倍&lt;/strong&gt;。杯子还是同一个杯子，&amp;ldquo;拥有&amp;quot;这个动作让它的价值翻倍了。&lt;/p&gt;
&lt;p&gt;工程里的禀赋效应：自己写的代码、自己选的技术栈、自己定的方案。Code review 里的本能防御、重构旧系统时的心疼，都是同一个机制——你把&amp;quot;我的产出&amp;quot;从收益账本挪进了损失账本。有个很实用的小练习：评审自己的方案前，先假设作者是隔壁组一个你不熟的人，再看一遍。很多&amp;quot;绝不能改&amp;quot;的设计，换了个署名就变成了&amp;quot;这也能忍？&amp;quot;。&lt;/p&gt;
&lt;p&gt;附带一提，禀赋效应也是谈判和协作的润滑剂原理的反面：让别人先在方案里&amp;quot;留下指纹&amp;rdquo;（采纳他的一个命名、沿用他的一段接口），他对整个方案的敌意会显著下降——方案有一部分变成&amp;quot;他的&amp;quot;了。这不是操纵，是承认人的计价方式本来如此。&lt;/p&gt;
&lt;h3 id=&#34;33-规划谬误planning-fallacy&#34;&gt;3.3 规划谬误（Planning Fallacy）&lt;/h3&gt;
&lt;p&gt;Kahneman 自曝的案例，堪称全书最诚实的一段。多年前他参与一个团队，为以色列教育部门设计一门判断与决策课程并编写配套教材。开工时团队内部估算：&lt;strong&gt;大约 2 年完工&lt;/strong&gt;（估计在 1.5 到 2.5 年之间）。Kahneman 突然想起该问一句&amp;quot;别的团队做同类课程花了多久&amp;quot;，于是问了课程专家——答案是：&lt;strong&gt;类似项目从未有低于 7 年的，大约 40% 的团队最终直接放弃，完成的也普遍用了 7 到 10 年&lt;/strong&gt;。而且没人认为他们这个团队比那些失败的团队强。&lt;/p&gt;
&lt;p&gt;然后呢？团队知道后，照样按原计划干了下去。&lt;strong&gt;最终这个项目用了 8 年才完成&lt;/strong&gt;，而那时教材已经没什么使用价值了。&lt;/p&gt;
&lt;p&gt;规划谬误的结构很清晰：估算时只盯着&amp;quot;我这个项目的内部情况&amp;quot;（内部视角），拒绝看&amp;quot;同类项目的历史分布&amp;quot;（外部视角）。对策 Kahneman 也给了，叫&lt;strong&gt;参照类预测（Reference Class Forecasting）&lt;/strong&gt;：先找同类项目的历史数据定基准，再根据本项目的特殊性做微调。&lt;/p&gt;
&lt;p&gt;这个方法后来被正式用于英国的大型基建项目评估——伦敦奥运、高铁项目的预算审批都被要求引入参照类数据，因为公共工程的超支史实在过于壮观。书里没细讲，但结论是一致的：&lt;strong&gt;任何&amp;quot;这次不一样&amp;quot;的信念，都应该先接受历史分布的拷问。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;顺便说一句，这个案例里还有个细节特别真实：团队听完&amp;quot;同类项目都 7 年起、四成烂尾&amp;quot;之后，没有一个人提议重新评估要不要继续干。&lt;strong&gt;信息被接收了，但没有被采纳&lt;/strong&gt;——知道和行动之间，隔着一整本这本书。&lt;/p&gt;
&lt;h3 id=&#34;34-后见之明偏差hindsight-bias&#34;&gt;3.4 后见之明偏差（Hindsight Bias）&lt;/h3&gt;
&lt;p&gt;事情发生之后，人会觉得&amp;quot;我早就知道会这样&amp;quot;。这不是装，是真实的记忆扭曲——知道结果后，大脑会重构之前的记忆，让结果显得不可避免。Kahneman 的说法很刻薄：这会让我们&lt;strong&gt;对决策质量的评估完全错位&lt;/strong&gt;——评价一个决定不看决策时的信息和过程，只看结果好不好（结果论，outcome bias 的近亲）。&lt;/p&gt;
&lt;p&gt;工程上的重灾区就是事故复盘。&amp;ldquo;这么明显的问题当初怎么没发现？&amp;quot;——因为当初它有几百个同样&amp;quot;明显&amp;quot;的候选问题，只是别的没炸。不复盘当时的已知信息分布，复盘就退化成甩锅大会。&lt;/p&gt;
&lt;p&gt;后见之明还有个副作用经常被忽视：它让&lt;strong&gt;后来者无法从事故里真正学习&lt;/strong&gt;。如果记忆里事故是&amp;quot;显而易见且本该避免的&amp;rdquo;，那学到的东西只有一句&amp;quot;下次仔细点&amp;quot;——等于没学。只有把记忆还原回&amp;quot;当时看起来模棱两可&amp;quot;的状态，才能问出有价值的问题：当时缺的是什么信号？这个信号下次怎么提前暴露？&lt;/p&gt;
&lt;h3 id=&#34;35-过度自信optimistic-overconfidence&#34;&gt;3.5 过度自信（Optimistic Overconfidence）&lt;/h3&gt;
&lt;p&gt;顺带一条：规划谬误的深层燃料是过度自信。Kahneman 在书里说，如果让他选一个&amp;quot;最该被消除的偏差&amp;quot;，他选过度自信。专家的预测准确率经常接近掷硬币，但自信程度一点不打折——&lt;strong&gt;知道得越多，编的故事越连贯，故事越连贯，越自信&lt;/strong&gt;；而故事的连贯性和真实性之间，没有半毛钱关系。&lt;/p&gt;
&lt;p&gt;书里有个压得住场的实证：Tetlock 对二百多位政治、经济专家的长期追踪研究（历时约二十年，收集了几万个预测）发现，专家对各自领域长期走向的预测准确率只比随机略好——用 Kahneman 转述的话说，&amp;ldquo;掷飞镖的黑猩猩&amp;quot;就能和他们打个平手，而预测越自信的专家往往错得越离谱。专家的自信不是准确率的信号，只是叙事流畅度的信号。&lt;/p&gt;
&lt;p&gt;工程版的过度自信在容量预估和故障域判断上最常见：&amp;ldquo;这个量级肯定扛得住&amp;quot;&amp;ldquo;问题肯定出在 XX 层&amp;rdquo;。给自己立的一个规矩是：&lt;strong&gt;任何&amp;quot;肯定&amp;rdquo;，都必须配一个打脸条件&lt;/strong&gt;——&amp;ldquo;肯定扛得住，除非单实例 QPS 超过 X&amp;rdquo;。写不出打脸条件的自信，就是系统 1 在编故事。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;四偏差速查表&#34;&gt;四、偏差速查表&lt;/h2&gt;
&lt;p&gt;把上面的内容压成一张表，适合打印出来贴在工位上。用这张表的姿势是&amp;quot;对号入座&amp;rdquo;：做哪类决策之前，先扫一眼对应的行——它不是知识清单，是触发器清单。&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;偏差&lt;/th&gt;
					&lt;th&gt;一句话机制&lt;/th&gt;
					&lt;th&gt;高频翻车场景&lt;/th&gt;
					&lt;th&gt;一句话对策&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;锚定效应&lt;/td&gt;
					&lt;td&gt;先出现的数字拖走后续估计&lt;/td&gt;
					&lt;td&gt;排期谈判、报价、性能指标对齐&lt;/td&gt;
					&lt;td&gt;自己先备好独立估算，别让对方先开口&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;可得性偏差&lt;/td&gt;
					&lt;td&gt;想得起 = 发生得多&lt;/td&gt;
					&lt;td&gt;风险评估、技术选型（&amp;ldquo;最近老看到 XX 翻车&amp;rdquo;）&lt;/td&gt;
					&lt;td&gt;查数据，别查记忆&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;代表性偏差&lt;/td&gt;
					&lt;td&gt;像 = 概率高&lt;/td&gt;
					&lt;td&gt;根据&amp;quot;画像&amp;quot;判断候选人/问题归属&lt;/td&gt;
					&lt;td&gt;强制问一句：基数是多少？&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;合取谬误&lt;/td&gt;
					&lt;td&gt;故事越细越信&lt;/td&gt;
					&lt;td&gt;事故归因、需求评审里的&amp;quot;完整用户故事&amp;quot;&lt;/td&gt;
					&lt;td&gt;细节越丰富的因果链越要警惕&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;基础概率忽视&lt;/td&gt;
					&lt;td&gt;忽略先验分布&lt;/td&gt;
					&lt;td&gt;招聘、故障定位、A/B 结果解读&lt;/td&gt;
					&lt;td&gt;先报 base rate，再谈个案特征&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;损失厌恶&lt;/td&gt;
					&lt;td&gt;亏的痛感 ≈ 赚的快感 ×2&lt;/td&gt;
					&lt;td&gt;不敢下线下线功能、沉没成本追加投入&lt;/td&gt;
					&lt;td&gt;把决策翻译成&amp;quot;从零开始还选它吗&amp;quot;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;禀赋效应&lt;/td&gt;
					&lt;td&gt;是我的就值钱&lt;/td&gt;
					&lt;td&gt;护着自己的代码/方案不放&lt;/td&gt;
					&lt;td&gt;评审时假设作者是别人&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;规划谬误&lt;/td&gt;
					&lt;td&gt;只看内部视角估工期&lt;/td&gt;
					&lt;td&gt;一切项目排期&lt;/td&gt;
					&lt;td&gt;参照类预测：同类项目花了多久？&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;后见之明&lt;/td&gt;
					&lt;td&gt;出事后觉得早有预兆&lt;/td&gt;
					&lt;td&gt;事故复盘、绩效评估&lt;/td&gt;
					&lt;td&gt;复盘只评估决策时的信息与过程&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;回归均值&lt;/td&gt;
					&lt;td&gt;极端值之后自然回落&lt;/td&gt;
					&lt;td&gt;绩效&amp;quot;干预见效&amp;quot;、骂完就进步&lt;/td&gt;
					&lt;td&gt;看长期分布，别看单次起伏&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;过度自信&lt;/td&gt;
					&lt;td&gt;故事顺 = 把握大&lt;/td&gt;
					&lt;td&gt;专家拍脑袋、容量预估&lt;/td&gt;
					&lt;td&gt;给结论配一个置信区间和打脸条件&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id=&#34;五落到工程实践给流程打护栏&#34;&gt;五、落到工程实践：给流程打护栏&lt;/h2&gt;
&lt;p&gt;前面说了，知道偏差 ≠ 免于偏差。真正有用的是把对策&lt;strong&gt;外置到流程里&lt;/strong&gt;，让系统 1 没机会上场。我自己在用/在推的有三条：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;① 评审清单（Review Checklist）前置。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;设计评审和技术方案评审最容易中代表性偏差和合取谬误——一份写得漂亮的方案天然显得靠谱。我们的做法是在评审 checklist 里加几条&amp;quot;反直觉&amp;quot;项：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;这个方案的 base rate 是什么？同类方案/同类系统的失败率有多高？&lt;/li&gt;
&lt;li&gt;方案里最乐观的假设是哪一条？它错了的话，代价是什么？&lt;/li&gt;
&lt;li&gt;细节最丰富的因果链，有没有可能是编的？（合取谬误检查）&lt;/li&gt;
&lt;li&gt;这份方案如果是竞争对手写的，我的评价会一样吗？（禀赋效应检查）&lt;/li&gt;
&lt;li&gt;拍板之前，有没有哪个该咨询的人还没被咨询过？（WYSIATI 检查）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;清单的价值不在于发现问题，在于&lt;strong&gt;强制系统 2 开机&lt;/strong&gt;。还有个执行细节：这几条必须由&amp;quot;方案作者以外的人&amp;quot;来问——让作者自查偏差，等于让系统 1 审查系统 1。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;② 估算加参照类缓冲。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;排期时强制走两步：先报&amp;quot;内部视角&amp;quot;的估算（拆任务、加总），再报&amp;quot;外部视角&amp;quot;的基准（过去五个类似项目实际花了多久，平均超期多少）。两个数摆在一起，最终排期取外部视角为锚、内部视角做微调。&lt;/p&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;flowchart LR
    T[&amp;#34;新任务排期&amp;#34;] --&amp;gt; V1[&amp;#34;内部视角&amp;lt;br/&amp;gt;拆任务、加总工时&amp;lt;br/&amp;gt;(系统 1 主场的乐观估计)&amp;#34;]
    T --&amp;gt; V2[&amp;#34;外部视角&amp;lt;br/&amp;gt;同类项目历史实际耗时&amp;lt;br/&amp;gt;平均超期率&amp;#34;]
    V1 --&amp;gt; CMP{&amp;#34;对照&amp;lt;br/&amp;gt;差多少? 为什么?&amp;#34;}
    V2 --&amp;gt; CMP
    CMP --&amp;gt; F[&amp;#34;最终排期&amp;lt;br/&amp;gt;以外部视角为锚&amp;lt;br/&amp;gt;内部视角做微调&amp;#34;]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;p&gt;实操里我们组的内部估算平均比实际乐观 40% 左右——这个 40% 本身就是参照类数据，是规划谬误的量化。&lt;strong&gt;缓冲不是拍脑袋乘 1.5，是用自己团队的历史超期率算出来的。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;③ 复盘去后见之明。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;事故复盘立一条规矩：所有&amp;quot;当初怎么没发现 XX&amp;quot;的讨论，必须补充回答&amp;quot;当时已知的、和 XX 同样可疑但没出事的问题有哪些&amp;quot;。这一条直接掐灭后见之明——它把记忆拉回到决策时点的不确定性里。复盘材料里禁止出现&amp;quot;显而易见&amp;quot;&amp;ldquo;早就应该&amp;quot;这类词，除非能证明当时的信息足以支撑这个判断。评价决策质量看过程，不看结果；运气好的烂决策要批，运气差的好决策要认。&lt;/p&gt;
&lt;p&gt;执行这条规矩时有个实操细节：复盘会上先让参与者各自&lt;strong&gt;写下&lt;/strong&gt;&amp;ldquo;事发前自己真实的判断是什么&amp;rdquo;，再开始讨论。不写下来，讨论开始五分钟后，所有人的记忆就会收敛到&amp;quot;我当时就觉得要出事&amp;rdquo;——后见之明是即时生效的，写得慢一步就来不及了。&lt;/p&gt;
&lt;p&gt;这三条有一个共同的形态，值得点破：&lt;strong&gt;它们都是&amp;quot;把关键动作提前到偏差生效之前&amp;quot;&lt;/strong&gt;。checklist 在方案动笔前立好，独立估算在听到别人的锚之前写完，真实判断在结果揭晓之前记下。纠偏的正确时机永远是事前，因为事后的你已经不是当时的你了。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;六思考与感悟&#34;&gt;六、思考与感悟&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;偏差是特性，不是缺陷。&lt;/strong&gt; 系统 1 的启发法在进化环境里是高效近似，是 modern world 的统计结构让这批近似失效了。所以别抱着&amp;quot;消灭偏差&amp;quot;的心态读这本书，那不现实；正确的心态是像对待第三方库的已知 issue 一样：&lt;strong&gt;文档里写清楚 workaround，关键路径上绕开&lt;/strong&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;个人层面的纠偏收益很低，组织层面的纠偏收益很高。&lt;/strong&gt; Kahneman 自己说过，他研究了一辈子偏差，自己该犯照犯。但流程不会犯——checklist、参照类估算、复盘规矩这些东西不需要意志力，它们是把纠偏成本从每次决策转移到了一次性的流程设计上。这跟&amp;quot;与其教育用户别点钓鱼链接，不如默认开二次验证&amp;quot;是同一个工程哲学。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;这本书改变了我读数据的方式。&lt;/strong&gt; 以前看到&amp;quot;上季度事故下降 30%&amp;ldquo;会觉得干得漂亮，现在第一反应是问：基线方差多大？是不是回归均值？是不是定义改了？不是抬杠，是损失厌恶的镜像——&lt;strong&gt;好消息也需要通过同样严格的审查&lt;/strong&gt;，而系统 1 天生只审查坏消息。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;警惕&amp;quot;偏差列表&amp;quot;本身成为新的锚。&lt;/strong&gt; 带着偏差清单看世界，容易看谁都像偏差——别人不同意我，一定是他锚定了/禀赋效应了。这本身就是一种可得性偏差。清单是用来审自己的决策流程的，不是用来给别人贴标签的。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;这本书的最佳读法是&amp;quot;隔几年重读一遍&amp;rdquo;。&lt;/strong&gt; 第一遍读案例，觉得新鲜；工作几年后再读，每个案例都能对上自己踩过的坑——排期乐观、复盘甩锅、护着自己的方案不放，一个不落。它不像技术书会过时，因为书里写的这套&amp;quot;硬件&amp;quot;几十万年内都不会升级。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id=&#34;本篇小结&#34;&gt;本篇小结&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;双系统模型是全书的地基：系统 1 快而偏、系统 2 懒而贵，偏差的本质是&lt;strong&gt;该走系统 2 的决策被系统 1 截胡了&lt;/strong&gt;；&lt;/li&gt;
&lt;li&gt;十大核心偏差按场景分两类：判断类（锚定、可得性、代表性、合取谬误、基础概率忽视、回归均值）和选择类（损失厌恶与前景理论、禀赋效应、规划谬误、后见之明），速查表见第四节；&lt;/li&gt;
&lt;li&gt;关键史实案例：Linda 问题证明故事细节能压倒概率逻辑；轮盘实验证明无关数字能拖走估计；飞行教官证明&amp;quot;骂比夸有效&amp;quot;是回归均值的错觉；编教材的 2 年变 8 年证明内部视角系统性乐观；赌局实验测出损失厌恶约 2:1；&lt;/li&gt;
&lt;li&gt;落地三件事：评审清单强制系统 2 开机、估算用参照类预测加缓冲、复盘用&amp;quot;当时的已知信息&amp;quot;去后见之明；&lt;/li&gt;
&lt;li&gt;一句收尾：知道所有偏差依然会被骗，所以&lt;strong&gt;把纠偏写进流程，别写进愿望&lt;/strong&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这本书值得放在手边常翻。技术书教你怎么让系统不犯错，这本书教你承认：&lt;strong&gt;决策系统里最不稳定的那个组件，一直是你自己&lt;/strong&gt;。&lt;/p&gt;
</description>
    </item>
    <item>
      <title>《程序员修炼之道》读书笔记：把五种逻辑能力焊进日常工程动作</title>
      <link>https://ftmao.com/blog/bookstore/pragmatic-programmer-notes/</link>
      <pubDate>Mon, 05 Sep 2022 16:00:00 +0800</pubDate>
      <guid>https://ftmao.com/blog/bookstore/pragmatic-programmer-notes/</guid>
      <description>&lt;h1 id=&#34;程序员修炼之道读书笔记把五种逻辑能力焊进日常工程动作&#34;&gt;《程序员修炼之道》读书笔记：把五种逻辑能力焊进日常工程动作&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;逻辑思维书单合读笔记的收官篇。前两篇：《&lt;a href=&#34;https://ftmao.com/blog/blog/bookstore/asking-questions-pyramid-principle-book-notes/&#34;&gt;〈学会提问〉与〈金字塔原理〉&lt;/a&gt;》（想清楚 + 说明白）、《&lt;a href=&#34;https://ftmao.com/blog/blog/bookstore/how-to-solve-it-thinking-in-systems-notes/&#34;&gt;〈怎样解题〉与〈系统之美〉&lt;/a&gt;》（解点状问题 + 看系统结构）；总纲见《&lt;a href=&#34;https://ftmao.com/blog/blog/posts/programmer-logical-thinking-training/&#34;&gt;程序员逻辑思维训练手册&lt;/a&gt;》。&lt;br&gt;
《程序员修炼之道》（The Pragmatic Programmer）在这个书单里位置特殊：前四本书练的是「脑」，这本书练的是「手」——&lt;strong&gt;它把抽象的思维能力，翻译成 DRY、正交性、曳光弹这样一条一条可以当天就用起来的工程纪律。&lt;/strong&gt;&lt;br&gt;
这篇笔记不按原书章节抄，按训练手册里的五种能力重新归类。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;flowchart TD
    BOOK[&amp;#34;《程序员修炼之道》&amp;lt;br/&amp;gt;几十条 tips 散在十章里&amp;#34;] --&amp;gt; A[&amp;#34;概念清晰&amp;lt;br/&amp;gt;DRY / 命名 / 需求之坑&amp;#34;]
    BOOK --&amp;gt; B[&amp;#34;推理链条&amp;lt;br/&amp;gt;橡皮鸭调试 / 不要假定要证明&amp;lt;br/&amp;gt;拒绝巧合式编程&amp;#34;]
    BOOK --&amp;gt; C[&amp;#34;抽象分层&amp;lt;br/&amp;gt;正交性 / 得墨忒耳法则&amp;lt;br/&amp;gt;解耦与时间耦合&amp;#34;]
    BOOK --&amp;gt; D[&amp;#34;边界意识&amp;lt;br/&amp;gt;契约式设计 / 断言&amp;lt;br/&amp;gt;防御式编程 / 资源有始有终&amp;#34;]
    BOOK --&amp;gt; E[&amp;#34;因果辨析&amp;lt;br/&amp;gt;曳光弹与原型 / 估算&amp;lt;br/&amp;gt;重构的时机&amp;#34;]
    style BOOK fill:#e8f4e8&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;hr&gt;
&lt;h2 id=&#34;能力一-概念清晰dry-的本质不是别复制粘贴&#34;&gt;能力一 概念清晰：DRY 的本质不是「别复制粘贴」&lt;/h2&gt;
&lt;p&gt;书中被引用最多也误解最深的一条是 DRY（Don&amp;rsquo;t Repeat Yourself）。它说的不是「代码别重复」，而是——&lt;strong&gt;每一个知识点，在系统中必须有唯一、权威、无歧义的表示&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;踩坑故事 #1（三处复制的校验逻辑，一次资损）&lt;/strong&gt;：订单金额的校验规则（起购金额、优惠券叠加上限）在三个服务里各写了一份。规则调整时改了两处漏了第三处，一个边缘渠道绕过了叠加上限，被羊毛党薅了一晚上。复盘时发现三份代码&lt;strong&gt;长得并不一样&lt;/strong&gt;——不是复制粘贴，是同一个「知识」被各自实现了三遍。DRY 管的就是这个：校验规则收敛成一份配置 + 一个共享库，三处引用。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;踩坑故事 #2（需求之坑：做了用户「说要的」，不是「要的」）&lt;/strong&gt;：运营说「要一个导出全量订单的按钮」。我们做了，导出 800 万行 Excel，系统卡死，运营崩溃。追问之下，真实需求是「每周一看上周各渠道的退款率」——一张定时推送的报表就能解决。书中的原话值得抄在墙上：&lt;strong&gt;「需求很少躺在表面上，它们深埋在层层假设、误解和政治之下。」&lt;/strong&gt;「我们要 X」这个陈述本身，就是需要被挖掘的假设。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;实践清单：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; 评审时先问：这个「需求」背后要解决的问题是什么？（至少往下挖一层）&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; 同一个规则/知识在系统里有几处表示？超过一处就要收敛&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; 名字说得出准确含义吗？说不清含义的命名（&lt;code&gt;data&lt;/code&gt;、&lt;code&gt;temp&lt;/code&gt;、&lt;code&gt;handle&lt;/code&gt;）是概念没清晰的信号&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id=&#34;能力二-推理链条调试的哲学与巧合式编程&#34;&gt;能力二 推理链条：调试的哲学与「巧合式编程」&lt;/h2&gt;
&lt;p&gt;书里调试章节只有两条核心纪律：&lt;strong&gt;「不要恐慌」&lt;strong&gt;和&lt;/strong&gt;「不要假定，要证明」（Don&amp;rsquo;t Assume It — Prove It）&lt;/strong&gt;。配合著名的橡皮鸭调试法（把问题逐行讲给一只鸭子听，讲着讲着自己就找到了答案），构成一套完整的 debug 心法——和波利亚的四步法互为表里。&lt;/p&gt;
&lt;p&gt;它给一种常见病起了名字：&lt;strong&gt;巧合式编程（Programming by Coincidence）&lt;/strong&gt;——代码能跑，但你不知道为什么能跑；改了一行，测试过了，至于为什么过，不知道。这种代码的每次成功运行都是运气贷的款，利率很高。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;踩坑故事 #3（「能跑就行」的代码，凌晨随机爆炸）&lt;/strong&gt;：接过一段遗留代码：发送消息后 sleep 500ms 再查状态，「因为不 sleep 偶尔查不到」。没人知道 500ms 是怎么来的——它就是巧合式编程的活标本：把「碰巧没失败」当成了「正确」。大促流量上来，下游延迟抖动到 600ms，状态查询大面积误判，凌晨两点报警群爆炸。根因是消息状态要轮询或回调确认，sleep 是用运气对抗时延。&lt;strong&gt;凡是「不知道为什么能跑」的代码，上线前必须弄懂，或者重写。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;踩坑故事 #4（橡皮鸭的实战版）&lt;/strong&gt;：一个诡异的并发 bug 查了两天，最后是在给同事复述问题的时候自己发现的——讲到「这个计数器只在这里加……」突然意识到「不对，还有一个地方也加」。语言化会强迫推理补全所有跳步。&lt;strong&gt;讲不出来 = 没想完整&lt;/strong&gt;，这是橡皮鸭有效的底层原因。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;实践清单：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; 修复前能一句话说清根因吗？说不清就还没找到&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; 代码里有没有「不知道为什么能跑」的部分？找出来，弄懂或重写&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; 卡住超过 30 分钟？找人（或 AI）把问题从头讲一遍&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; 修复后问：这个 bug 依赖的「巧合」还有哪些？（同类巧合一起清掉）&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id=&#34;能力三-抽象分层正交性改-a-不坏-b的工程学&#34;&gt;能力三 抽象分层：正交性，「改 A 不坏 B」的工程学&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;正交性&lt;/strong&gt;：两个组件，改一个不影响另一个，就叫正交。这是全书对「分层」最硬核的定义——不是画几张架构图，是「改动的爆炸半径有多小」。&lt;/p&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;flowchart LR
    subgraph BAD[&amp;#34;非正交：牵一发动全身&amp;#34;]
        A1[&amp;#34;业务逻辑&amp;#34;] --- A2[&amp;#34;日志组件&amp;#34;]
        A2 --- A3[&amp;#34;配置格式&amp;#34;]
        A3 --- A1
        A1 -.-&amp;gt;|&amp;#34;改日志库版本&amp;lt;br/&amp;gt;业务发布受阻&amp;#34;| X1[&amp;#34;爆炸半径: 全系统&amp;#34;]
    end
    subgraph GOOD[&amp;#34;正交：各改各的&amp;#34;]
        B1[&amp;#34;业务逻辑&amp;#34;] --&amp;gt; B4[&amp;#34;稳定接口&amp;#34;]
        B2[&amp;#34;日志组件&amp;#34;] --&amp;gt; B4
        B3[&amp;#34;配置&amp;#34;] --&amp;gt; B4
        B4 -.-&amp;gt;|&amp;#34;改动被接口吸收&amp;#34;| X2[&amp;#34;爆炸半径: 单组件&amp;#34;]
    end
    style GOOD fill:#e8f4e8&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;p&gt;配套的两条：&lt;strong&gt;得墨忒耳法则&lt;/strong&gt;（只跟直接朋友说话，别 &lt;code&gt;a.getB().getC().doSomething()&lt;/code&gt; 层层穿透）和&lt;strong&gt;时间耦合&lt;/strong&gt;（A 必须发生在 B 之前？那顺序本身就是依赖，要显式化或消除）。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;踩坑故事 #5（升级日志库，阻塞了业务发版）&lt;/strong&gt;：安全部门要求全公司升级某个日志组件版本。我们的业务代码里直接 import 了它的十几个类，牵一发动全身，业务迭代被迫停了一周。有防腐层的团队半天就升完了。&lt;strong&gt;依赖第三方时永远隔一层自己的接口&lt;/strong&gt;——这是正交性最朴素的形式，也是最常被偷懒跳过的一层。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;实践清单：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; 问每个改动：它的爆炸半径到哪里？（能答上来，说明边界是清楚的）&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; 代码里有没有 &lt;code&gt;a.b.c.d()&lt;/code&gt; 式穿透调用？有就收口&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; 有没有「必须先调 X 再调 Y」的隐性顺序？显式化（状态机/工作流）或消除&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; 第三方依赖隔了自己的接口层吗？&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id=&#34;能力四-边界意识契约断言与防御式编程&#34;&gt;能力四 边界意识：契约、断言与防御式编程&lt;/h2&gt;
&lt;p&gt;书中的边界三板斧：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;契约式设计&lt;/strong&gt;：每个方法声明「调用前你必须保证什么（前置条件），我保证返回什么（后置条件），过程中什么不会变（不变式）」&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;断言&lt;/strong&gt;：「不可能发生」的情况就用断言挡住——&lt;strong&gt;它不可能发生的意思是，如果发生了，一定是 bug，要让系统立刻响铃&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;资源有始有终&lt;/strong&gt;：谁分配谁释放，成对出现&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;踩坑故事 #6（「不可能为空」的字段，空了）&lt;/strong&gt;：订单下游默认「支付成功的订单必有支付流水号」，没做校验。一次支付渠道故障，回调丢了流水号但状态是「成功」，空流水号一路穿透到对账任务，对账差异报警在三天后才被人注意到。如果入口有一条断言，事故时长是三分钟。&lt;strong&gt;「不可能」三个字是边界意识最危险的敌人——线上专治各种不可能。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;踩坑故事 #7（资源泄漏：谁打开的连接没还）&lt;/strong&gt;：压测时连接数缓慢上涨，八小时后服务假死。定位到一个异常分支里 &lt;code&gt;connection.close()&lt;/code&gt; 被跳过——正常路径成对，异常路径裸奔。教训和书中的完全一致：&lt;strong&gt;资源的分配与释放要在同一个视野里可见&lt;/strong&gt;（try-with-resources / defer / RAII），跨函数传递所有权的设计，十个里有九个会漏。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;实践清单：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; 关键方法的契约写得出来吗？（前置/后置/不变式各一句）&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; 「不可能发生」的假设有没有断言守着？&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; 外部输入（用户、上游、回调）全部按「不可信」校验了吗？&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; 资源的打开和关闭在同一个代码块视野内吗？&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id=&#34;能力五-因果辨析曳光弹估算与重构的时机&#34;&gt;能力五 因果辨析：曳光弹、估算与重构的时机&lt;/h2&gt;
&lt;p&gt;这一组 tips 回答的是「决策」问题——怎么在信息不足时往前推进：&lt;/p&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;flowchart TD
    subgraph TRACER[&amp;#34;曳光弹 Tracer Bullets&amp;#34;]
        T1[&amp;#34;端到端打通一条最薄链路&amp;lt;br/&amp;gt;登录→下单→支付 各只实现 5%&amp;#34;] --&amp;gt; T2[&amp;#34;架构/集成/部署&amp;lt;br/&amp;gt;风险第一时间暴露&amp;#34;]
        T2 --&amp;gt; T3[&amp;#34;之后每一枪&amp;lt;br/&amp;gt;都沿着弹道修正&amp;#34;]
    end
    subgraph PROTO[&amp;#34;原型 Prototype&amp;#34;]
        P1[&amp;#34;用纸板/脚本验证&amp;lt;br/&amp;gt;某个具体问题&amp;#34;] --&amp;gt; P2[&amp;#34;验证完就扔掉&amp;lt;br/&amp;gt;代码使命是学习&amp;#34;]
    end
    Q[&amp;#34;面对一个新系统&amp;#34;] --&amp;gt; TRACER
    Q --&amp;gt; PROTO
    style TRACER fill:#e8f4e8&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;p&gt;&lt;strong&gt;曳光弹 vs 原型&lt;/strong&gt;是书中最精妙的区分：原型是「用后即弃的实验」，回答局部问题；曳光弹是「会一直发光的骨架」，端到端打通整条链路，让集成风险第一天就暴露。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;踩坑故事 #8（三个月大设计，集成第一天就崩）&lt;/strong&gt;：早年一个项目，前两个月各模块分头开发，接口全靠文档约定。联调第一天：认证方式对不上、时间格式两套、错误码语义相反——三个月的工期，联调吃掉一个月。后来所有新项目第一周的硬指标改成：&lt;strong&gt;端到端曳光弹必须打通&lt;/strong&gt;（登录→一个空接口→落库→前端显示一个 hello），哪怕薄如蝉翼。集成风险从「最后一个月的惊喜」变成「第一周的日常」。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;估算&lt;/strong&gt;一节也值得单独记：估算前先问「精度要求是什么」——「两周左右」和「14 个工作日」是两种承诺；估算要带上依据（「参照上次的 X 项目」），否则就是报数字占卜。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;实践清单：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; 新项目第一周：曳光弹打通了吗？（端到端，再薄也算）&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; 验证性代码标记「原型」了吗？原型有没有被当成产品上线？（常见事故）&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; 估算带依据和精度范围了吗？&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; 重构是「顺手做」（童子军军规：离开时比来时干净）还是攒成了「重构专项」？后者通常永远不会排期&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id=&#34;收官五本书拼起来是一张完整的图&#34;&gt;收官：五本书拼起来是一张完整的图&lt;/h2&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;flowchart LR
    A[&amp;#34;《学会提问》&amp;lt;br/&amp;gt;结论要过安检&amp;#34;] --&amp;gt; THINK[&amp;#34;想清楚&amp;#34;]
    B[&amp;#34;《金字塔原理》&amp;lt;br/&amp;gt;结论站塔尖&amp;#34;] --&amp;gt; SAY[&amp;#34;说明白&amp;#34;]
    C[&amp;#34;《怎样解题》&amp;lt;br/&amp;gt;四步解题法&amp;#34;] --&amp;gt; SOLVE[&amp;#34;解得掉&amp;#34;]
    D[&amp;#34;《系统之美》&amp;lt;br/&amp;gt;找结构不找人&amp;#34;] --&amp;gt; SOLVE
    E[&amp;#34;《程序员修炼之道》&amp;lt;br/&amp;gt;工程纪律清单&amp;#34;] --&amp;gt; DO[&amp;#34;落得下去&amp;#34;]
    THINK --&amp;gt; DO
    SAY --&amp;gt; DO
    SOLVE --&amp;gt; DO
    style E fill:#e8f4e8&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;思考与感悟之一&lt;/strong&gt;：这本书出版二十多年，具体技术在书中已经老（CVS、CORBA），纪律一条没过时。这印证了训练手册里那句判断——框架三个月过期，思维能力跟你三十年。&lt;strong&gt;读老书读「不变的部分」，是技术人对抗知识折旧的最优策略。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;思考与感悟之二&lt;/strong&gt;：全书的隐藏主线是「责任感」——对自己的代码负责（不妥协于巧合式编程）、对后来者负责（DRY、正交）、对用户负责（挖掘真需求）。所谓「修炼」，练的不是绝技，是&lt;strong&gt;把每一条朴素的纪律在 deadline 压力下依然执行到位&lt;/strong&gt;。知道和做到之间，隔着的不是天赋，是一百次「这次就算了」的拒绝。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;思考与感悟之三（系列收尾）&lt;/strong&gt;：五本书读下来，它们的交集惊人地小，合力惊人地大：学会提问管「别信错」，金字塔管「别说不清」，波利亚管「别卡住」，系统之美管「别复发」，修炼之道管「别妥协」。逻辑思维不是一个器官，是一套工具箱——&lt;strong&gt;工具箱的意义不在于拥有，在于每个场景知道伸手拿哪一件。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id=&#34;附落地清单贴工位版--全书精选&#34;&gt;附：落地清单（贴工位版 · 全书精选）&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; 这个知识在系统里有几处表示？（DRY）&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; 代码能跑，但我说得清为什么吗？（拒绝巧合式编程）&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; 这次改动的爆炸半径到哪？（正交性）&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; 「不可能发生」的假设有断言守着吗？（契约）&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; 资源的打开和关闭在同一视野内吗？（有始有终）&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; 新项目第一周打通曳光弹了吗？（端到端骨架）&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; 原型代码被当成产品上线了吗？（用后即弃）&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; 今天离开代码时，比来时干净一点了吗？（童子军军规）&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
  </channel>
</rss>
