慢一点工作,给判断留些时间
一些关于工作节奏、维护和写作的笔记:什么时候该快,什么时候值得停一下。
AI 摘要
文章认为“慢一点”并非拖延,而是把时间留给高撤销成本、需长期维护的判断。通过保护注意力、追求清晰、记录决定、验证删除、设定性能预算并留下续作入口,可减少返工与解释成本,让成果更可靠、可撤销,也便于他人接手和长期演进。
谈到工作速度,我们通常会想到回复和交付用了多久,想法是否很快落地。但工作完成后还可能需要修改、交接和维护。到了那一步,最初省下的时间未必还有多大意义,结果是否可靠、别人能否接着做会更重要。
我所说的缓慢工作不是拖延,也不是故意降低效率,而是把注意力留给需要判断的地方。可复用的内容要整理清楚,结果尚未确定时也要保留修改的余地。除了完成今天的工作,还要让明天的人看得懂当时为什么这样做。
速度并不是时间的反义词 #
一件事看起来完成了,后面的工作却未必结束。匆忙写下的代码上线后可能一直需要维护,缺少背景的文档会让人半年后重新猜测,为了赶进度跳过的验证也只是被推迟到更难处理的时候。
如果一项工作后来不断返工,还需要反复解释和补救,最初省下的时间很快就会被用掉。提前确认方向可以减少这类返工,但没有必要让每个决定都经过长时间讨论。容易撤销的决定可以直接试,改动代价高的决定则应先多找些证据。
| 决定类型 | 撤销成本 | 合适的做法 |
|---|---|---|
| 修改局部文案 | 很低 | 直接尝试并观察 |
| 调整页面布局 | 较低 | 用真实内容验证 |
| 改变数据结构 | 较高 | 设计迁移与回滚 |
| 发布公共接口 | 很高 | 明确约束并记录原因 |
这样分配时间,可以少在小事上打转,遇到重要边界时也不至于太仓促。
注意力是一种有限资源 #
钟表上的每个小时都一样,人的注意力却不是。连续思考两个小时,和被消息切成十二段的两个小时,做不了同样的事。处理复杂问题时,我们得先在脑中拼出大致的模型,才看得出局部改动会影响哪里。一被打断,这个刚搭起来的东西就可能散掉一部分。
所以,“随时在线”不一定带来更好的协作。即时消息适合紧急问题和快速同步,可一旦所有事情都挤进同一条通道,需要专心做的工作就得和每个提示音抢时间。
给不同工作分配不同容器 #
我试过按照工作所需的状态来安排环境。需要连续思考的任务,要有明确目标,并尽量减少其他入口。协作讨论则要共享上下文,把结论留在可以追踪的地方。邮件和短任务可以集中处理,以免不断打断主要工作;探索性工作还应允许失败,不必过早承诺确定结果。
这种分法不是精确到分钟的时间表,只用来确定现在先做什么,以及哪些事情可以晚点处理。
上午:完成需要连续推理的核心工作
中午:处理邮件、评论和短任务
下午:协作、评审与验证
结束前:记录进展和下一步入口
安排本身很普通,作用只是少让自己反复找回状态。
清晰比聪明更容易延续 #
精巧的方案很容易让人眼前一亮,但如果每次使用都要作者在旁边解释,过一阵子就会变得难以维护。能用得久的系统往往很普通:命名对得上行为,边界看得见,出了错也有地方可查。
清晰也不是假装问题很简单。支付状态、权限继承、分布式一致性本来就复杂,设计要做的是把这些复杂之处摆出来,别再添上与问题无关的麻烦。
下面这段配置没什么技巧,每项设置的意思倒是很清楚:
[pagination]
pagerSize = 8
[params]
description = "记录技术、阅读与日常观察。"
dateFormat = "2006 年 1 月 2 日"
[taxonomies]
tag = "tags"
读者不用猜分页大小从哪里来,也不用到模板里翻找日期规则。配置写得明白,理解系统时就能少记几个例外。
注释应当解释原因 #
注释如果只是把代码换成自然语言再说一遍,很快就成了噪音。值得留下的是代码本身看不出来的背景,比如为什么没用那个看起来更简单的方案,或者某项约束究竟来自哪里。
// 使用 UTC 保存发布时间,避免部署地区变化后文章顺序发生漂移。
publishedAt := time.Now().UTC()
代码已经写明调用了 UTC,不用再解释。注释留下的是“文章顺序必须稳定”这个约束,免得后来的人改回旧写法,又碰到同一个问题。
维护不是创造的对立面 #
新功能容易被看见,维护则常被当作收尾,但使用者只会感受到页面是否够快、升级会不会出问题、数据是否还在,以及出错后能不能恢复。这些都是产品的一部分。
维护工作可能让迁移在没有停机的情况下完成,也可能让监控在错误影响用户之前发现问题。删除旧代码后,后续修改不用再照顾双重路径;缩短构建时间,可以让修复更快进入生产环境。文档如果保存了关键决定,团队也不用重复同一场讨论。
这些结果不太显眼,因此描述工作时需要说清具体变化。“让数据库迁移可以在不中断写入的情况下完成”,就比“重构存储层”更容易判断实际效果。
写作是整理判断的工具 #
写作不只用来传播已经想好的观点。有些想法在脑中显得完整,是因为直觉补上了缺口。真正写下来以后,缺失的前提、跳过的推论和含糊的用词才会显出来,观点也会在修改中逐渐成形。
因此,写作可以用来做成本很低的设计验证。它会迫使人说明自己究竟要解决什么问题,区分已知事实与推测,并写清方案依赖的条件。还要考虑结果不符合预期时如何撤销或修正,以及谁会受到决定的影响。这些问题不仅出现在文章里,做软件、定流程和讨论产品时也绕不开。
文档应该保存决定,而不是复制现状 #
代码、配置和运行结果可以说明现在是什么样,却未必告诉我们为什么变成这样。文档不用很长,能让以后读到它的人知道某条边界为什么存在,就已经有用。
决定:RSS 输出完整文章正文。
原因:读者应当能够在订阅器中完成阅读,不必跳转网页。
影响:订阅文件体积会增加,图片和代码块需要保持有效的 HTML 表达。
以后约束变了,也可以从这段记录开始重新判断,不必因为“不知道当初为什么这么做”就一直保留旧选择。
删代码前先找证据 #
增加功能会让系统能做的事变多,删除无用分支则会减少测试、部署和文档需要照顾的状态,维护者也能少记一条路径。
但删除不能只凭“看起来没人用了”。某个入口可能仍被外部脚本调用,已经关闭的功能也可能留下持久化数据,旧配置项还可能被用户当作稳定契约。动手前应搜索仓库中的直接和间接引用,检查生产环境是否仍有真实使用,并确认旧数据是否需要迁移。外部使用者需要提前知道变化范围,过期测试和文档要与功能一起删除,部署后还要观察关键指标。
经过这些检查,删除才算明确了系统以后不再承担哪些行为,而不只是一次顺手清理。
性能需要明确预算 #
没有具体标准时,“足够快”很容易随着讨论对象变化。性能预算把这种偏好写成可以检查的约束,但没必要到处套用,数字也得符合产品的实际场景。
一个以阅读为主的静态站点,比如可以先定下这样的预算:
| 指标 | 建议预算 |
|---|---|
| 初始 HTML | 压缩后小于 30 KB |
| 关键 CSS | 压缩后小于 20 KB |
| JavaScript | 非必要时保持 0 KB |
| 首屏最大图片 | 小于 250 KB |
| 500 篇文章构建时间 | 小于 2 秒 |
这不表示多出一个字节就算失败。预算只是给讨论一个参照:新功能会增加成本时,可以提前判断值不值得,而不是上线以后才偶然发现代价。
留出可以回来的入口 #
一项工作拉得很长,麻烦的常常是第二天怎么重新开始。如果昨天收工时什么线索都没留,今天只好重读一遍上下文,慢慢找回当时想到哪里了。
收工前可以记下已经确认的事实、还没解决的问题,再写一句最小的下一步。例如:
## 当前状态
- 已确认数据读取没有错误
- 问题只出现在移动端布局
- 可能与 42rem 断点有关
## 下一步
在 375px 宽度下检查文章列表的日期布局。
这不是正式报告,只是给明天的自己留个入口。协作者看到后也知道从哪里接着做,不用从头猜。
这些小事要过一阵子才看得见 #
实际工作中,需要长期维护的往往是一些具体选择。重要决定要留下原因,功能稳定后应删除临时开关,上线前完成必要的验证,命名时也要考虑以后读代码的人。这些事情短期内未必能看出影响,但一年以后,项目是否仍然容易修改,常常与它们有关。
没有人能预先看见所有变化,也不可能一次设计出永远正确的结构。比较实际的做法,是让错误容易被发现,保存决定的来由,并尽量保留撤销改动的办法。这里所说的“慢”不是拖长工期,而是在容易匆忙做决定的地方多留一点时间。这样做可能让眼前的进度稍慢,却能减少后来的返工,也方便其他人继续完成这项工作。