<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>文章 · Hugox</title>
    <link>http://localhost:1313/posts/</link>
    <description>按写作时间排列的全部记录。</description>
    <generator>Hugo</generator>
    <language>zh-CN</language>
      <lastBuildDate>Wed, 22 Jul 2026 17:10:00 &#43;0800</lastBuildDate>
      <atom:link href="http://localhost:1313/posts/index.xml" rel="self" type="application/rss+xml" />
      <item>
        <title>缓慢工作的形状：在持续变化的世界里保留注意力</title>
        <link>http://localhost:1313/posts/the-shape-of-slow-work/</link>
        <pubDate>Wed, 22 Jul 2026 17:10:00 &#43;0800</pubDate>
        <guid isPermaLink="true">http://localhost:1313/posts/the-shape-of-slow-work/</guid>
        <description>&lt;p&gt;我们很容易把速度理解成一种单一能力：更快地回复消息，更快地完成任务，更快地把想法变成可见的结果。然而，真正决定一项工作能否长期存在的，往往不是最初完成得有多快，而是在变化不断发生之后，它是否仍然清楚、可靠，并且允许后来的人继续前进。&lt;/p&gt;&#xA;&lt;p&gt;缓慢工作并不意味着拖延，也不意味着拒绝效率。它是一种对注意力的主动安排：在需要判断的地方停下来，在可以复用的地方建立结构，在结果尚不确定的时候保留修正的空间。它关心的不只是今天完成了什么，也关心明天是否还能理解今天的决定。&lt;/p&gt;&#xA;&lt;h2 id=&#34;速度并不是时间的反义词&#34;&gt;速度并不是时间的反义词&lt;/h2&gt;&#xA;&lt;p&gt;一件事情看起来完成了，不代表它真正结束了。仓促写下的代码可能在上线后变成长期维护成本；没有说明背景的文档可能在半年后制造新的误解；为了赶进度而跳过的验证，往往只是在把检查工作推迟到更昂贵的阶段。&lt;/p&gt;&#xA;&lt;p&gt;因此，衡量速度不能只看交付时刻，还要看一个结果从产生到稳定所经历的完整周期。如果一项工作需要反复返工、解释和补救，那么最初节省的时间通常只是暂时借来的。&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;真正的快，不是比别人更早离开起点，而是更少走进那些必须原路返回的岔路。&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;这并不要求每个决定都经过漫长讨论。恰恰相反，好的节奏来自对决定类型的区分：容易撤销的决定可以迅速行动，难以撤销的决定则需要更多证据。&lt;/p&gt;&#xA;&lt;table&gt;&#xA;&#x9;&lt;thead&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;th&gt;决定类型&lt;/th&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;th&gt;撤销成本&lt;/th&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;th&gt;合适的做法&lt;/th&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&lt;/thead&gt;&#xA;&#x9;&lt;tbody&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;修改局部文案&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;很低&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;直接尝试并观察&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;调整页面布局&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;较低&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;用真实内容验证&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;改变数据结构&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;较高&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;设计迁移与回滚&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;发布公共接口&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;很高&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;明确约束并记录原因&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;p&gt;当注意力与风险匹配时，团队既不会在小事上无限争论，也不会在重要边界上草率行事。&lt;/p&gt;&#xA;&lt;h2 id=&#34;注意力是一种有限资源&#34;&gt;注意力是一种有限资源&lt;/h2&gt;&#xA;&lt;p&gt;一天中的时间看似均匀，注意力却不是。连续两个小时的完整思考，与被消息切成十二段的两个小时，并不具有相同价值。很多复杂问题需要我们先在头脑中建立一个模型，然后才能判断某个局部变化会带来什么影响。每一次打断，都可能让这个模型部分坍塌。&lt;/p&gt;&#xA;&lt;p&gt;这也是为什么“随时在线”并不等于高效协作。即时沟通适合处理真正紧急、需要快速同步的信息，但如果所有问题都进入同一条即时通道，重要工作就会被迫与每一个提示音竞争。&lt;/p&gt;&#xA;&lt;h3 id=&#34;给不同工作分配不同容器&#34;&gt;给不同工作分配不同容器&lt;/h3&gt;&#xA;&lt;p&gt;一种简单的做法，是根据工作所需的认知状态来安排环境：&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;深度工作需要连续时间、明确目标和尽量少的入口。&lt;/li&gt;&#xA;&lt;li&gt;协作讨论需要共享上下文，以及可以被追踪的结论。&lt;/li&gt;&#xA;&lt;li&gt;日常处理适合集中完成，避免它们不断侵入主要任务。&lt;/li&gt;&#xA;&lt;li&gt;探索性工作需要允许失败，不应过早承诺确定结果。&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;容器不是严格的时间表，而是一种边界。它告诉我们当前正在做什么，也提醒其他事情暂时不进入这里。&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;上午：完成需要连续推理的核心工作&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;中午：处理邮件、评论和短任务&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;下午：协作、评审与验证&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;结束前：记录进展和下一步入口&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这样的安排看起来并不激进，却能减少每天重新寻找状态的次数。&lt;/p&gt;&#xA;&lt;h2 id=&#34;清晰比聪明更容易延续&#34;&gt;清晰比聪明更容易延续&lt;/h2&gt;&#xA;&lt;p&gt;我们常常欣赏精巧的解决方案，因为它们展示了作者的能力。但一套需要反复解释才能使用的方案，很难在时间中保持稳定。真正耐久的系统通常没有那么戏剧化：命名与行为一致，边界可以被识别，失败发生时能够找到原因。&lt;/p&gt;&#xA;&lt;p&gt;清晰不是把所有复杂性抹平。有些领域本身就复杂，例如支付状态、权限继承、分布式一致性。好的设计会让这些必要的复杂性显露出来，同时尽量减少与问题无关的意外复杂性。&lt;/p&gt;&#xA;&lt;p&gt;下面是一段普通的配置。它没有追求技巧，但每项设置都表达了明确意图：&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-toml&#34; data-lang=&#34;toml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;pagination&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;pagerSize&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;8&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;params&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;description&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;记录技术、阅读与日常观察。&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;dateFormat&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;2006 年 1 月 2 日&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;taxonomies&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;tag&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;tags&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;读者不需要猜测分页大小从哪里来，也不需要寻找隐藏在模板中的日期规则。透明的配置减少了理解系统时必须记住的例外。&lt;/p&gt;&#xA;&lt;h3 id=&#34;注释应当解释原因&#34;&gt;注释应当解释原因&lt;/h3&gt;&#xA;&lt;p&gt;如果一段注释只是把代码换一种语言重复，它很快就会变成噪音。更有价值的注释会保存无法从当前实现中直接推导出来的背景，例如为什么不能采用看似更简单的方案，或者某项约束来自哪个外部系统。&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// 使用 UTC 保存发布时间，避免部署地区变化后文章顺序发生漂移。&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;publishedAt&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;time&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Now&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;().&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;UTC&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这里重要的不是“调用了 &lt;code&gt;UTC&lt;/code&gt;”，代码已经表达了这一点。重要的是顺序稳定这一约束，它会帮助后来的人避免无意中恢复旧问题。&lt;/p&gt;&#xA;&lt;h2 id=&#34;维护不是创造的对立面&#34;&gt;维护不是创造的对立面&lt;/h2&gt;&#xA;&lt;p&gt;“新功能”容易被看见，“维护”则经常被描述成不得不做的后续工作。但对使用者来说，两者并没有清晰边界。页面是否快速、升级是否安全、数据能否保留、错误是否能够恢复，这些都构成产品本身。&lt;/p&gt;&#xA;&lt;p&gt;维护工作的价值常常体现在没有发生的事情上：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;一次迁移没有造成停机；&lt;/li&gt;&#xA;&lt;li&gt;一个错误在影响用户前被监控发现；&lt;/li&gt;&#xA;&lt;li&gt;一段旧代码被删除后，后续修改不再需要考虑双重路径；&lt;/li&gt;&#xA;&lt;li&gt;构建时间缩短，让修复能够更快抵达生产环境；&lt;/li&gt;&#xA;&lt;li&gt;文档保存了关键决定，使团队不必重复同一场讨论。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;因为这些结果缺少戏剧性，我们需要用更具体的语言描述它们。与其说“重构存储层”，不如说“让数据库迁移可以在不中断写入的情况下完成”。后者指出了用户和系统真正得到的能力。&lt;/p&gt;&#xA;&lt;h2 id=&#34;写作是整理判断的工具&#34;&gt;写作是整理判断的工具&lt;/h2&gt;&#xA;&lt;p&gt;写作不只是传播已经形成的观点。很多时候，观点是在写作过程中才真正形成的。一个模糊想法留在脑海里时，可以依靠直觉连接许多未说明的部分；一旦写到纸面上，缺失的前提、跳跃的推论和含混的词语就会暴露出来。&lt;/p&gt;&#xA;&lt;p&gt;因此，写作也是一种低成本的设计验证。它迫使我们回答：&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;我试图解决的究竟是什么问题？&lt;/li&gt;&#xA;&lt;li&gt;哪些事实是已知的，哪些只是推测？&lt;/li&gt;&#xA;&lt;li&gt;这个方案依赖哪些条件？&lt;/li&gt;&#xA;&lt;li&gt;如果结果不符合预期，如何撤销或修正？&lt;/li&gt;&#xA;&lt;li&gt;谁会受到这个决定的影响？&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;这些问题适用于文章，也适用于软件、流程和产品决策。&lt;/p&gt;&#xA;&lt;h3 id=&#34;文档应该保存决定而不是复制现状&#34;&gt;文档应该保存决定，而不是复制现状&lt;/h3&gt;&#xA;&lt;p&gt;现状可以从代码、配置和运行结果中读取，决定背后的理由却很容易消失。一份耐久的文档不必很长，但应当让未来的读者知道某个边界为何存在。&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;决定：RSS 输出完整文章正文。&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;原因：读者应当能够在订阅器中完成阅读，不必跳转网页。&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;影响：订阅文件体积会增加，图片和代码块需要保持有效的 HTML 表达。&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;当约束发生变化时，这段记录也提供了重新评估的起点，而不是把旧选择变成无法质疑的传统。&lt;/p&gt;&#xA;&lt;h2 id=&#34;删除是一种重要的设计能力&#34;&gt;删除是一种重要的设计能力&lt;/h2&gt;&#xA;&lt;p&gt;增加功能会扩大系统能够做的事情，删除则减少系统必须同时解释的状态。每移除一条无用分支，测试、部署、文档和维护者就少考虑一种可能性。&lt;/p&gt;&#xA;&lt;p&gt;然而，安全删除比简单增加更需要证据。一个看似无人使用的入口，可能仍被外部脚本调用；一项已经关闭的功能，可能仍留下持久化数据；一个旧配置项，可能被用户当作稳定契约。&lt;/p&gt;&#xA;&lt;p&gt;删除前可以做一份简短检查：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;搜索仓库中的直接和间接引用；&lt;/li&gt;&#xA;&lt;li&gt;检查生产环境是否仍有真实使用；&lt;/li&gt;&#xA;&lt;li&gt;确认旧数据是否需要迁移；&lt;/li&gt;&#xA;&lt;li&gt;告知外部使用者变化范围；&lt;/li&gt;&#xA;&lt;li&gt;同时删除过期测试和文档；&lt;/li&gt;&#xA;&lt;li&gt;部署后观察关键指标。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;删除不是清理冲动，而是对系统边界的重新确认。&lt;/p&gt;&#xA;&lt;h2 id=&#34;性能需要明确预算&#34;&gt;性能需要明确预算&lt;/h2&gt;&#xA;&lt;p&gt;如果没有具体标准，“足够快”会变成不断变化的主观判断。性能预算的作用，是把偏好变成可验证的约束。它不一定适用于所有项目，但应该与产品场景相匹配。&lt;/p&gt;&#xA;&lt;p&gt;对于一个以阅读为主的静态站点，可以采用这样的预算：&lt;/p&gt;&#xA;&lt;table&gt;&#xA;&#x9;&lt;thead&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;th&gt;指标&lt;/th&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;th style=&#34;text-align: right&#34;&gt;建议预算&lt;/th&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&lt;/thead&gt;&#xA;&#x9;&lt;tbody&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;初始 HTML&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td style=&#34;text-align: right&#34;&gt;压缩后小于 30 KB&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;关键 CSS&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td style=&#34;text-align: right&#34;&gt;压缩后小于 20 KB&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;JavaScript&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td style=&#34;text-align: right&#34;&gt;非必要时保持 0 KB&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;首屏最大图片&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td style=&#34;text-align: right&#34;&gt;小于 250 KB&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;500 篇文章构建时间&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td style=&#34;text-align: right&#34;&gt;小于 2 秒&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;p&gt;预算并不意味着超过一字节就失败。它提供的是讨论基础：如果一个新能力需要额外成本，我们可以判断它是否值得，而不是在上线后才偶然发现代价。&lt;/p&gt;&#xA;&lt;h2 id=&#34;留出可以回来的入口&#34;&gt;留出可以回来的入口&lt;/h2&gt;&#xA;&lt;p&gt;长时间工作最困难的部分，往往不是继续，而是重新开始。昨天结束时没有留下线索，今天就需要再次阅读大量上下文，才能找回当时正在形成的判断。&lt;/p&gt;&#xA;&lt;p&gt;一个好的结束动作非常简单：记录已经确认的事实、当前未解决的问题，以及下一步最小可执行动作。例如：&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-markdown&#34; data-lang=&#34;markdown&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;gu&#34;&gt;## 当前状态&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;-&lt;/span&gt; 已确认数据读取没有错误&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;-&lt;/span&gt; 问题只出现在移动端布局&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;-&lt;/span&gt; 可能与 42rem 断点有关&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;gu&#34;&gt;## 下一步&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;在 375px 宽度下检查文章列表的日期布局。&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这份记录不是正式报告，而是留给未来自己的路标。它减少了重新进入工作所需的启动成本，也让协作者能够接续而不是从头猜测。&lt;/p&gt;&#xA;&lt;h2 id=&#34;长期主义是一系列短期动作&#34;&gt;长期主义是一系列短期动作&lt;/h2&gt;&#xA;&lt;p&gt;长期主义听起来像一种宏大立场，但它真正存在于日常细节里：是否为重要决定写下一句原因，是否在功能稳定后删除临时开关，是否愿意在上线前完成最后一次验证，是否给后来的人留下可以理解的命名。&lt;/p&gt;&#xA;&lt;p&gt;这些动作单独看都很小。它们不会立刻制造巨大的差异，却会持续改变系统未来的可修改性。一年之后，项目是变得越来越沉重，还是仍然允许人们从容地做出改变，往往取决于这些不显眼的选择。&lt;/p&gt;&#xA;&lt;p&gt;我们不需要预测所有未来，也不可能一次设计出永远正确的结构。更实际的目标，是让错误能够被发现，让决定能够被解释，让变化能够被撤销，让注意力能够回到真正重要的问题上。&lt;/p&gt;&#xA;&lt;p&gt;缓慢工作的价值最终不在于慢，而在于它保留了判断。它让速度不必以混乱为代价，让创造与维护不再彼此对立，也让我们完成的东西在离开当下之后，仍然拥有继续生长的可能。&lt;/p&gt;&#xA;</description>
      </item>
      <item>
        <title>The Quiet Work of Building Software That Lasts</title>
        <link>http://localhost:1313/posts/the-quiet-work-of-building-software/</link>
        <pubDate>Wed, 22 Jul 2026 16:40:00 &#43;0800</pubDate>
        <guid isPermaLink="true">http://localhost:1313/posts/the-quiet-work-of-building-software/</guid>
        <description>&lt;p&gt;Most software does not fail because its authors lacked intelligence. It fails because the system gradually became harder to understand than the organization could afford. A shortcut became a convention, a temporary exception became a permanent interface, and a useful abstraction accumulated responsibilities until nobody could explain where its boundaries ended.&lt;/p&gt;&#xA;&lt;p&gt;The difficult part of building software is therefore not invention alone. It is preserving clarity while requirements, teams, and operating conditions continue to change. This work is quiet. It rarely produces dramatic screenshots, but it determines whether a project remains useful after the excitement of its first release has passed.&lt;/p&gt;&#xA;&lt;h2 id=&#34;clarity-is-an-operational-feature&#34;&gt;Clarity is an operational feature&lt;/h2&gt;&#xA;&lt;p&gt;We often discuss clarity as if it were a preference for elegant code. In practice, clarity affects response time, reliability, and cost. When an incident occurs, the team must form an accurate model of the system before it can act safely. Every ambiguous name, hidden dependency, and surprising side effect increases the time required to build that model.&lt;/p&gt;&#xA;&lt;p&gt;A clear system does not need to be simple in every dimension. Some domains are genuinely complicated. The goal is to make essential complexity visible and accidental complexity removable. A payment system may need careful state transitions, but it should not also require its operators to remember that a function named &lt;code&gt;refresh&lt;/code&gt; silently writes to three databases.&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;Good maintenance begins when the code says what it does, the documentation says why it exists, and the production system behaves like both.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;This standard changes how we review code. Instead of asking only whether a patch works, we can ask a more durable set of questions:&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;Can a reader identify the inputs, outputs, and side effects?&lt;/li&gt;&#xA;&lt;li&gt;Does the change introduce a new concept that the existing model cannot express?&lt;/li&gt;&#xA;&lt;li&gt;Is failure visible at the boundary where it can be handled?&lt;/li&gt;&#xA;&lt;li&gt;Will the next person know which behavior is intentional?&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;These questions do not eliminate defects. They reduce the amount of interpretation required when defects inevitably appear.&lt;/p&gt;&#xA;&lt;h2 id=&#34;small-changes-are-easier-to-trust&#34;&gt;Small changes are easier to trust&lt;/h2&gt;&#xA;&lt;p&gt;Large rewrites are attractive because they promise a clean boundary between the frustrating present and an orderly future. That boundary rarely exists. The old system contains years of discovered behavior, including behavior that was never documented but still matters to someone. A rewrite starts with less visible complexity, not necessarily less actual complexity.&lt;/p&gt;&#xA;&lt;p&gt;Small changes provide a different advantage: they preserve feedback. A narrow patch can be reviewed against a narrow claim. It can be deployed independently, observed in production, and reverted without disturbing unrelated work. If the result is wrong, the lesson arrives before the team has built five more decisions on top of it.&lt;/p&gt;&#xA;&lt;p&gt;Consider a function that has begun to mix validation, persistence, and notification:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;func&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Publish&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ctx&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;context&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Context&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;post&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Post&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;error&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&#x9;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;post&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Validate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;nil&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&#x9;&#x9;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;fmt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Errorf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;validate post: %w&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&#x9;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&#x9;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;repository&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Save&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ctx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;post&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;nil&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&#x9;&#x9;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;fmt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Errorf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;save post: %w&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&#x9;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&#x9;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;notifier&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Send&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ctx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;post&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;It may eventually need a queue, retries, idempotency, and an audit log. Adding all of those at once would make the transition difficult to reason about. A smaller first step might only make the notification boundary explicit and record failures. That change creates evidence for the next decision instead of predicting every future requirement.&lt;/p&gt;&#xA;&lt;h3 id=&#34;the-value-of-reversible-decisions&#34;&gt;The value of reversible decisions&lt;/h3&gt;&#xA;&lt;p&gt;Not every decision deserves the same ceremony. A local variable name is easy to change. A public URL, persisted schema, or external protocol is expensive to change. Good teams spend their attention according to reversibility.&lt;/p&gt;&#xA;&lt;table&gt;&#xA;&#x9;&lt;thead&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;th&gt;Decision&lt;/th&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;th&gt;Cost to reverse&lt;/th&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;th&gt;Useful response&lt;/th&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&lt;/thead&gt;&#xA;&#x9;&lt;tbody&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;Internal helper name&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;Low&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;Choose clearly and continue&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;Page layout detail&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;Low to medium&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;Test with real content&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;Database representation&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;High&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;Model migration and rollback&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;Public API contract&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;Very high&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;Document invariants and versioning&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;p&gt;This approach avoids two common failures. The first is endless debate over details that can be corrected in minutes. The second is casual treatment of interfaces that will constrain the project for years.&lt;/p&gt;&#xA;&lt;h2 id=&#34;maintenance-is-product-development&#34;&gt;Maintenance is product development&lt;/h2&gt;&#xA;&lt;p&gt;Maintenance is often described as the work that happens after product development. That distinction is misleading. Users experience the complete behavior of a system: its speed, consistency, recovery, compatibility, and ability to preserve their data. Improving those properties is product work, even when the release notes contain no new feature names.&lt;/p&gt;&#xA;&lt;p&gt;A maintenance task has product value when it removes friction or reduces risk. Examples include:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;replacing an unreliable background job with an observable queue;&lt;/li&gt;&#xA;&lt;li&gt;deleting a configuration option that no longer changes behavior;&lt;/li&gt;&#xA;&lt;li&gt;improving an error message so a user can recover without support;&lt;/li&gt;&#xA;&lt;li&gt;reducing build time so fixes reach production sooner;&lt;/li&gt;&#xA;&lt;li&gt;documenting a data-retention rule before it becomes an incident.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;The challenge is that preventive work competes poorly in planning meetings. A visible feature can be demonstrated immediately, while the value of a safer migration appears as an incident that never happens. Teams need a vocabulary for this value. Instead of saying “clean up the database layer,” describe the concrete operational result: “allow schema changes without stopping writes.”&lt;/p&gt;&#xA;&lt;h2 id=&#34;documentation-should-preserve-decisions&#34;&gt;Documentation should preserve decisions&lt;/h2&gt;&#xA;&lt;p&gt;Documentation decays when it merely repeats code. A list of function parameters can often be generated, and generated facts should be generated. Human-written documentation is most valuable when it records context that cannot be reconstructed from the current implementation.&lt;/p&gt;&#xA;&lt;p&gt;Useful documentation answers questions such as:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;What problem made this component necessary?&lt;/li&gt;&#xA;&lt;li&gt;Which alternatives were considered and rejected?&lt;/li&gt;&#xA;&lt;li&gt;What must remain true during a migration?&lt;/li&gt;&#xA;&lt;li&gt;Which failure modes are acceptable?&lt;/li&gt;&#xA;&lt;li&gt;Who depends on this behavior outside the repository?&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;An architectural decision can be short and still be durable:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Decision: store publication timestamps in UTC.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Reason: authors and readers may be in different time zones, while ordering&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;must remain stable across deployments.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Consequence: convert to local time only at presentation boundaries.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The important detail is not the format. It is the preservation of intent. Without the reason, a future developer may “simplify” the code by storing local timestamps and unknowingly restore the original bug.&lt;/p&gt;&#xA;&lt;h2 id=&#34;observability-begins-with-questions&#34;&gt;Observability begins with questions&lt;/h2&gt;&#xA;&lt;p&gt;Collecting more telemetry does not automatically make a system observable. A dashboard with hundreds of charts can still leave operators unable to answer a basic question: are users completing the action they came to perform?&lt;/p&gt;&#xA;&lt;p&gt;Start with questions, then collect the evidence needed to answer them:&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;Is the service accepting work?&lt;/li&gt;&#xA;&lt;li&gt;Is accepted work completing successfully?&lt;/li&gt;&#xA;&lt;li&gt;Where is time being spent?&lt;/li&gt;&#xA;&lt;li&gt;Which users or inputs are affected by failure?&lt;/li&gt;&#xA;&lt;li&gt;Did the latest deployment change any of these answers?&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;This sequence usually produces a small set of service-level metrics, structured events, and traces around important boundaries. It also reveals where logging is merely decorative. A message like &lt;code&gt;operation failed&lt;/code&gt; consumes storage but carries no diagnostic value unless it identifies the operation, relevant state, and underlying cause.&lt;/p&gt;&#xA;&lt;h3 id=&#34;design-errors-for-recovery&#34;&gt;Design errors for recovery&lt;/h3&gt;&#xA;&lt;p&gt;Errors are part of an interface. Internally, they should preserve enough context for diagnosis. Externally, they should tell the caller what can happen next. These needs are related but not identical.&lt;/p&gt;&#xA;&lt;p&gt;For example, a storage timeout may need a request identifier and dependency name in the logs. The user may only need to know that their draft remains safe and that retrying is appropriate. Exposing internal detail to the user is not transparency; it is transferring diagnostic work to someone without the tools to perform it.&lt;/p&gt;&#xA;&lt;h2 id=&#34;performance-work-needs-a-budget&#34;&gt;Performance work needs a budget&lt;/h2&gt;&#xA;&lt;p&gt;Performance improvements are easiest to evaluate when the project defines an explicit budget. Without one, “fast” becomes a moving adjective and optimization becomes a collection of local opinions.&lt;/p&gt;&#xA;&lt;p&gt;A small content site might choose budgets like these:&lt;/p&gt;&#xA;&lt;table&gt;&#xA;&#x9;&lt;thead&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;th&gt;Measure&lt;/th&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;th style=&#34;text-align: right&#34;&gt;Budget&lt;/th&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&lt;/thead&gt;&#xA;&#x9;&lt;tbody&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;Initial HTML&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td style=&#34;text-align: right&#34;&gt;Under 30 KB compressed&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;Critical CSS&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td style=&#34;text-align: right&#34;&gt;Under 20 KB compressed&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;JavaScript&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td style=&#34;text-align: right&#34;&gt;0 KB unless interaction requires it&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;Largest image&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td style=&#34;text-align: right&#34;&gt;Under 250 KB&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;Server build&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td style=&#34;text-align: right&#34;&gt;Under 2 seconds for 500 posts&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;p&gt;Budgets are not universal laws. They are constraints chosen for a particular product. Their value is that they turn a vague preference into a testable decision. When a feature exceeds the budget, the team can discuss whether its value justifies the cost instead of discovering the cost accidentally after launch.&lt;/p&gt;&#xA;&lt;h2 id=&#34;deletion-is-a-design-skill&#34;&gt;Deletion is a design skill&lt;/h2&gt;&#xA;&lt;p&gt;Removing code is one of the highest-leverage forms of maintenance. Every deleted branch eliminates a state that tests, operators, and future developers no longer need to consider. Yet deletion requires more care than addition because old behavior may have invisible consumers.&lt;/p&gt;&#xA;&lt;p&gt;Safe deletion starts with evidence:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;search for internal references;&lt;/li&gt;&#xA;&lt;li&gt;inspect production usage where possible;&lt;/li&gt;&#xA;&lt;li&gt;identify persisted data using the old representation;&lt;/li&gt;&#xA;&lt;li&gt;announce changes to external consumers;&lt;/li&gt;&#xA;&lt;li&gt;remove the behavior and its tests together;&lt;/li&gt;&#xA;&lt;li&gt;observe the system after deployment.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;Feature flags deserve particular attention. A temporary flag creates at least two versions of the product. Once a rollout is complete, leaving the flag in place preserves both versions in the code even if only one is used. The cleanup task is part of the feature, not optional work for a quieter quarter.&lt;/p&gt;&#xA;&lt;h2 id=&#34;a-sustainable-pace-is-technical-infrastructure&#34;&gt;A sustainable pace is technical infrastructure&lt;/h2&gt;&#xA;&lt;p&gt;Software quality depends on attention, and attention is finite. Teams working under constant urgency make narrower observations, rely more heavily on familiar solutions, and postpone verification. Over time, the system reflects those conditions through duplicated logic, incomplete migrations, and alerts that everyone learns to ignore.&lt;/p&gt;&#xA;&lt;p&gt;A sustainable pace does not mean avoiding deadlines or difficult periods. It means allowing recovery and protecting enough uninterrupted time for careful work. Review quality, incident response, and architectural judgment all decline when every task arrives as an emergency.&lt;/p&gt;&#xA;&lt;p&gt;This is not separate from engineering practice. It is part of the environment in which engineering decisions are made. A team cannot compensate indefinitely for an unstable process by asking individuals to be more disciplined.&lt;/p&gt;&#xA;&lt;h2 id=&#34;what-lasting-software-feels-like&#34;&gt;What lasting software feels like&lt;/h2&gt;&#xA;&lt;p&gt;Software that lasts is not frozen. It changes without losing its shape. New contributors can locate important behavior. Operators can understand failures before guessing at remedies. Users can trust that an upgrade will preserve their work. Old features can be removed without archaeology becoming the dominant engineering activity.&lt;/p&gt;&#xA;&lt;p&gt;None of this requires perfect foresight. It requires habits that keep correction affordable:&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;Prefer explicit boundaries over clever shortcuts.&lt;/li&gt;&#xA;&lt;li&gt;Make the smallest change that can produce useful evidence.&lt;/li&gt;&#xA;&lt;li&gt;Record why expensive decisions were made.&lt;/li&gt;&#xA;&lt;li&gt;Treat maintenance outcomes as user-facing value.&lt;/li&gt;&#xA;&lt;li&gt;Delete obsolete paths once their replacement is proven.&lt;/li&gt;&#xA;&lt;li&gt;Protect the attention needed to verify important work.&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;The result may look modest from the outside. That is often the point. Reliable systems make difficult work appear ordinary. Their strongest qualities emerge not in a launch demonstration, but months later, when a new requirement arrives and the team can meet it without first untangling everything that came before.&lt;/p&gt;&#xA;</description>
      </item>
      <item>
        <title>从一张白纸开始写作</title>
        <link>http://localhost:1313/posts/first-note/</link>
        <pubDate>Wed, 22 Jul 2026 10:30:00 &#43;0800</pubDate>
        <guid isPermaLink="true">http://localhost:1313/posts/first-note/</guid>
        <description>&lt;p&gt;极简不是把所有东西删掉，而是让留下来的部分各自承担明确的工作。这个主题没有 JavaScript，页面只由 HTML、CSS 和一套中文阅读字体构成。&lt;/p&gt;&#xA;&lt;h2 id=&#34;阅读是一种节奏&#34;&gt;阅读是一种节奏&lt;/h2&gt;&#xA;&lt;p&gt;中文正文需要比拉丁文字更舒展的行距。标题负责停顿，段落负责向前，元信息则安静地退到视线之外。主题将正文宽度控制在适合持续阅读的范围，同时让手机屏幕保持自然的边距。&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;好的排版不会抢走文字的声音，它只是让声音抵达得更清楚。&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;文章可以使用常见的 Markdown 元素：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;无序列表用来并列记录&lt;/li&gt;&#xA;&lt;li&gt;有序列表用来表达步骤&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;行内代码&lt;/code&gt; 用来标明命令或变量&lt;/li&gt;&#xA;&lt;li&gt;链接可以指向 &lt;a href=&#34;https://gohugo.io/&#34;&gt;Hugo 官方文档&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;构建时完成代码高亮&#34;&gt;构建时完成代码高亮&lt;/h2&gt;&#xA;&lt;p&gt;Hugo 内置 Chroma。高亮结果直接写入静态 HTML，不需要浏览器下载脚本。&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;package main&#xA;&#xA;import &amp;#34;fmt&amp;#34;&#xA;&#xA;func main() {&#xA;&#x9;fmt.Println(&amp;#34;纸短，路长。&amp;#34;)&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;表格与长内容&#34;&gt;表格与长内容&lt;/h2&gt;&#xA;&lt;p&gt;较窄的屏幕会让表格自然横向滚动，不会撑破正文布局。&lt;/p&gt;&#xA;&lt;table&gt;&#xA;&#x9;&lt;thead&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;th&gt;原则&lt;/th&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;th&gt;实现方式&lt;/th&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;th&gt;运行时依赖&lt;/th&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&lt;/thead&gt;&#xA;&#x9;&lt;tbody&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;内容优先&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;语义化模板与克制排版&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;无&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;自动深色&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;&lt;code&gt;prefers-color-scheme&lt;/code&gt;&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;无&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;代码高亮&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;Hugo Chroma&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;无&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;hr&gt;&#xA;&lt;h2 id=&#34;图片&#34;&gt;图片&lt;/h2&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://img.moxao.workers.dev/pengchangg/piclist/master/20260617/20260617090910181.webp&#34; alt=&#34;图片&#34; title=&#34;这是标题&#34;&gt;&lt;/p&gt;&#xA;&lt;hr&gt;&#xA;&lt;p&gt;这篇文章可以在填入真实内容后删除。创建下一篇文章时，运行：&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;hugo new content posts/my-note.md&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
      </item>
  </channel>
</rss>
