五种编程活动与被打断的代价 — 你的时间去了哪
这一章讲三件事: 「写代码」这个词掩盖了五种认知上完全不同的活;打断为什么值一刻钟; 以及三种把伤害压到最低的自救办法。 它把全书的方法按「活动」重新装箱:方法没错,但要看你此刻在干哪种活。
1. 全景:五种活动,三种记忆
来自一套研究「符号系统」(编程语言这 类表达思想的体系)的框架,它把语言对大脑的影响拆成一个个评估侧面,每个侧面叫维度(dimension,可以理解成体检项);这套框架通称符号认知维度,提出者是 Green、Blackwell 与 Petre,第 13 章还会遇到它。它把程序设计分成五种活动1。每种活动压的记忆不同,所以对症的辅助手段也不同:
| 活动 | 在干什么 | 压哪套记忆 | 对症的辅助 |
|---|---|---|---|
| 搜索 | 找特定信息:改哪、调用在哪 | 短时记忆——要记着「我在找什么、找过哪了」 | 笔记:把搜索状态写下来 |
| 理解 | 弄懂不熟悉的代码 | 工作记忆——全程靠推理 | 建模型、重构(第 04~06 章全套) |
| 转写 | 方案已定,照方写码 | 长时记忆——语法要信手拈来 | 抽认卡、自动化(第 03、11 章) |
| 递增 | 加新功能:搜索+理解+转写 | 三种全压 | 注释和重构 |
| 探索 | 用代码试想法,边写边想 | 三种全压,工作记忆最重 | 随手记设计方向 |
两个实务推论。**其一:**递增任务(最常见的「加个功能」)对新手最难,因为五种里它一下压三种记忆——给新人分任务时尽量拆开:先纯搜索、再纯理解、最后才转写3。**其二:**调试不在五单里,因为它是五种活动的叠加——先搜索、再理解、再探索、最后转写修复4。
2. 打断的价目表
打断贵,但贵多少,有数5:
- 20 世纪 90 年代 van Solingen 的观察:程序员经常被打断,每次持续 15~20 分钟;大约两成工作时间用于应付干扰;
- 帕宁(Parnin)的 85 人、10000 次会话记录:程序员平均每天只有两小时不被打扰;微软的调查里,62% 的程序员认为被打断后找回状态「相当不易」;
- 找回状态的代价:约一刻钟;如果打断发生在改方法改到一半,只有 10% 的人能一分钟内回来。
脑成像补了个细节:中川团队测出程序理解的认知负荷峰值出现在任务中段——理解活动存在预热(先热身、搭模型的阶段)期和冷却期,最难的部分在两者之间6。这意味着打断落在任务中段时,拆掉的是最贵的部分。
3. 主走查:一次五分钟的打断,大脑里丢了什么
场景:你在修一个 bug,改到第三版,手机进来一个五分钟的电话(人物与代码为演示场景,认知机制全部有出处)7。逐层盘点丢掉了什么:
打断前你手里有什么:
短时记忆:「变量 retryCount 现在是 3,下一版要验证边界」 ← 30 秒内蒸发
工作记忆:这个 bug 的心智模型——「应该是超时后没重置
计数器,所以第二次请求带上了旧票据」(搭了半小时)
前瞻记忆:「改完这里,还要把单元测试里的假数据删掉」
电话 5 分钟(聊的是晚饭):
打断后盘点:
① 短时记忆:已清空。「retryCount 是几?」——没了,
只能重读代码。这一项丢得最少。
② 心智模型:还在,但开始渗漏。你隐约记得「和重置有关」,
却想不起「为什么怀疑重置」——模型没有错,是支撑它的
证据链断了,你得回去重看两处代码重建证据。
③ 前瞻记忆:全灭。「删假数据」这件事连「存在过」都不记得了。
那一刻钟(第 2 节的实测数)花在哪:不是反应慢,
是 ①重读代码恢复中间值 + ②重看证据链焊接模型 + ③查 diff
找回「本来还要干嘛」——三件事各自都要几分钟。(diff,
即版本工具里「改动前后对照」的视图。)
程序员们其实早就自发发明了对策,帕宁记录了其中一种:路障提醒——打断前故意在代码里塞几 个随机字符,让编译必然报错;回来时错误消息像路障一样把你拦在原地,想忘都忘不了8。下面这节把这类土办法升级成三件正经工具。
4. 三件自救工具
工具一:把心智模型存出去。理解活动靠心智模型(第 07 章),那就在模型最新鲜的时刻把它写进注释——不只是「这段干什么」,更包括为什么这么做、排除了哪些方案。书里引了奥斯特霍特(Ousterhout)的话:注释的意义就是「获取存在于编写者脑海里但没有体现在代码中的信息」9。自己的注释首先是给「被打断后的自己」看的——代码即文档派常反驳说注释没用,但代码恰恰写不出「我为什么放弃了方案 B」这部分。若打断可以推迟,优先推迟:Slack 消息可以晾着,响铃的电话晾不了10。
工具二:喂饱前瞻性记忆。除了程序性和陈述性记忆,还有第三种——前瞻性记忆:记住「将来要做某事」的记忆,计划全靠它。「改完记得删假数据」就存在这里。它的常见容器是 TODO 注释——容器有多不可靠?GitHub 上含「TODO」的代码超过 1.36 亿条,大多「待而不办」11。改进方向:要么给提醒挂上触发点(有研究者做过给 TODO 设有效期的插件),要么退回路障提醒这类「物理外挂」12。
**工具三:子目标标记。**动手前把任务拆成显式的几步,写下来。书里用文本拆解任务演示——作者自己的写法是把每步写成注释,逐个补齐:
# parse text ← 第 1 步:拆开文本
# receive parse tree ← 第 2 步:拿到分析树
# filter the parse tree ← 第 3 步:筛选
# flatten tree back into text format
有研究(马古利厄克斯)证实:提供子目标时,程序员真的会用它们规划解法14。子目标的三重用途:规划 时是路线图;被打断时是「我做到第几步了」的定位器;做完后注释就地转正成文档。
5. 干扰本身能不能治
三件工具都是「被打断之后」,但打断的时机可以管理。贝利(Bailey)的对照实验:50 位被试做主要任务,一组的无关信息(突发新闻、股价)在任务中途插入,另一组在任务完成后才给——中途组花时更久、感受更难更烦更焦虑;2006 年的后续研究里,被打断者的错误率是两倍15。
结论:同样的干扰,挪到任务间隙发生,伤害大幅下降。于是有了 FlowLight:一盏按打字速度、鼠标活动判断「你是否在状态」的桌灯,专注时亮红(别来烦我),闲时变绿。449 位程序员、12 个国家的现场研究:干扰减少 46%,不少人实验结束后继续用16——成本一盏灯,收益半个下午。
顺带回答一个常见反驳:「我不是被打断,我是主动多任务。」研究不站这边:一心多用只在各任务都自动化后成立(第 11 章),读难文章时想把音乐调小、停车入位前想关收音机,都是大脑在报「坑位不足」17。数字上:边读边聊天的学生多花约 50% 时间;重度社交网络用户学习时长不短、成绩更低,而且自我感觉效率很高;2008 年的对照实验里,一边干活一边在线聊天的人自我评价良好,同伴给他们的评分却低得多18。多任务最危险的部位是「自我感觉」。
6. 作者的判断与证据
**有实验撑着的:**打断频率与代价(van Solingen;帕宁 85 人记录;微软调查);预热期(中川,fNIRS);错误率翻倍(贝利 2001/2006);FlowLight 46%(祖格尔,449 人现场研究);多任务三连(Fox;克尔希纳;2008 对照)。
作者的发挥,要分开看:「把设计方向写进注释」是作者的一贯主张,她自己的步骤注释实例是自我报告;主走查的盘点是把书里分散的机制(30 秒蒸发、模型、前瞻记忆)拼到一个场景上——场景是编的,机制各有出处。
**书的坦白:**FlowLight 靠交互数据推测专注度,只是「通俗地讲」在判断状态;子目标研究的结论也只到「会使用」为止,收益没有测过数。
7. 边界与局限
- 五种活动的边界在真实工作里是糊的:一次提交常常五种活动揉在一起,分类是分析工具,不是时刻表;
- 一刻钟、46%、两倍这些数字各有各的样本(85人会话、449人、50被试),相互间不能换算,引用时要 带各自的口径;
- FlowLight 的 46% 来自自愿参加的现场研究——愿意挂灯的人本身就可能更在意专注,效果有自我选择的水分;
- 「打断后一刻钟」测的是恢复到能写代码,不是恢复到打断前的思路质量——深处的模型缺口可能几天后才暴露。
8. 可带走的
- 干活前先自报家门:这会儿是搜索、理解还是转写?——活动不同,该请的工具不同;
- 给新人拆任务按活动切:先纯搜索、再纯理解,最后才递增;
- 离开工位前 30 秒,把心智模型和「下一步」写进注释或便签——这是给自己买的保险;
- 「下一步要做的琐事」别信脑子,TODO 要么带触发点,要么用路障提醒;
- 大任务开工前先把子目标写成注释,打断回来靠它定位;
- 能推迟的干扰就推迟:把「马上回」改成「攒到任务间隙一起回」;
- 团队装一盏 FlowLight(或任何状态灯),一盏灯顶半条制度;
- 别信自己「可以一心多用」的感觉——那个感觉恰恰是被研究证伪的部分。
9. 原文地图
| 主题 | 原书章 | 原文位置 |
|---|---|---|
| 五种活动框架 | 11.1 程序设计包括不同的编程活动 | text/65-ch11-01-11-1.txt:5(搜「5种编程活动」) |
| 各活动压的记忆 | 11.1 程序设计包括不同的编程活动 | text/65-ch11-01-11-1.txt:15(搜「搜索活动会影响短时记忆」) · text/65-ch11-01-11-1.txt:27(搜「显著影响工作记忆」) · text/65-ch11-01-11-1.txt:33(搜「转写活动主要影响长时记忆」) |
| 递增与探索 | 11.1 程序设计包括不同的编程活动 | text/65-ch11-01-11-1.txt:39(搜「混合性」) · text/65-ch11-01-11-1.txt:53(搜「尤其明显」) |
| 调试=五种结合 | 11.1 程序设计包括不同的编程活动 | text/65-ch11-01-11-1.txt:59(搜「5种编程活动的结合」) |
| 打断频率 | 11.2 受到干扰的程序员 | text/66-ch11-02-11-2.txt:7(搜「15~20分钟」) · text/66-ch11-02-11-2.txt:9(搜「62%」) |
| 预热期 | 11.2 受到干扰的程序员 | text/66-ch11-02-11-2.txt:17(搜「认知负荷最高」) · text/66-ch11-02-11-2.txt:19(搜「预热期」) |
| 一刻钟与路障提醒 | 11.2 受到干扰的程序员 | text/66-ch11-02-11-2.txt:23(搜「一刻钟」) · text/66-ch11-02-11-2.txt:25(搜「路障提醒」) |
| 保存心智模型 | 11.2 受到干扰的程序员 | text/66-ch11-02-11-2.txt:39(搜「没有体现在代码中」) · text/66-ch11-02-11-2.txt:41(搜「重中之重」) · text/66-ch11-02-11-2.txt:43(搜「推迟法」) |
| 前瞻性记忆与 TODO | 11.2 受到干扰的程序员 | text/66-ch11-02-11-2.txt:49(搜「前瞻性记忆」) · text/66-ch11-02-11-2.txt:51(搜「1.36亿」) · text/66-ch11-02-11-2.txt:57(搜「attachables」) |
| 子目标标记 | 11.2 受到干扰的程序员 | text/66-ch11-02-11-2.txt:61(搜「 子目标标记法」) · text/66-ch11-02-11-2.txt:71(搜「parse text」) · text/66-ch11-02-11-2.txt:76(搜「Margulieux」) |
| Bailey 实验 | 11.2 受到干扰的程序员 | text/66-ch11-02-11-2.txt:88(搜「50位被试者」) · text/66-ch11-02-11-2.txt:92(搜「两倍」) |
| FlowLight | 11.2 受到干扰的程序员 | text/66-ch11-02-11-2.txt:98(搜「449位程序员」) |
| 多任务研究 | 11.2 受到干扰的程序员 | text/66-ch11-02-11-2.txt:108(搜「自主阶段」) · text/66-ch11-02-11-2.txt:114(搜「50%」) · text/66-ch11-02-11-2.txt:116(搜「Facebook」) · text/66-ch11-02-11-2.txt:88(搜「对照实验」) |