将程序掌握在脑海中
2007年8月
一个优秀的程序员全神贯注地编写自己的代码时,可以像数学家思考问题一样将其掌握在脑海中。数学家不会像小学生那样在纸上演算来解答问题。他们更多地是在脑海中进行:他们试图充分理解一个问题空间,以便能够像在自己长大的房子里漫步一样,在其中自由穿梭。最好的编程也是如此。你将整个程序掌握在脑海中,并且可以随意操纵它。
这在项目开始时尤其有价值,因为最初最重要的是能够改变你正在做的事情。不仅仅是以不同的方式解决问题,而是改变你正在解决的问题。
你的代码是你对正在探索的问题的理解。因此,只有当你将代码放在脑海中时,你才能真正理解问题。
将程序放入脑海并不容易。如果你离开一个项目几个月,当你重新回到它时,可能需要几天才能真正理解它。即使你正在积极地处理一个程序,每天开始工作时也可能需要半个小时才能加载到你的脑海中。而且这还是在最好的情况下。在典型办公条件下工作的普通程序员永远不会进入这种模式。或者更戏剧性地说,在典型办公条件下工作的普通程序员永远无法真正理解他们正在解决的问题。
即使是最好的程序员也并非总是将他们正在处理的整个程序加载到脑海中。但是,你可以做一些事情来帮助自己:
- 避免分心。 分心对许多类型的工作都不利,但对编程尤其不利,因为程序员倾向于在他们可以处理的细节的极限下工作。
分心的危险不在于它持续的时间,而在于它扰乱你大脑的程度。程序员可以离开办公室去买一个三明治,而不会丢失脑海中的代码。但是,错误的干扰可能会在 30 秒内抹去你的大脑。
奇怪的是,有计划的分心可能比计划外的分心更糟糕。如果你知道一个小时后要开会,你甚至不会开始做一些困难的事情。
- 长时间工作。 由于每次开始处理程序时都有固定的成本,因此以几次长时间的工作比多次短时间的工作更有效率。当然,会有一个你因为疲倦而变得愚蠢的临界点。这因人而异。我听说过有人连续编程 36 个小时,但我最多只能坚持大约 18 个小时,而且我最擅长的是不超过 12 个小时的片段。
最佳状态不是你能身体上忍受的极限。分解项目既有成本也有好处。有时,当你休息后回到一个问题时,你会发现你的潜意识已经留下了一个答案在等你。
- 使用简洁的语言。 更强大的编程语言使程序更短。而且程序员似乎至少部分地用他们用来编写程序的语言来思考程序。语言越简洁,程序越短,就越容易加载并保存在你的脑海中。
你可以通过使用一种称为自下而上的编程风格来放大强大语言的效果,在这种风格中,你编写多层程序,较低的层充当较高层的编程语言。如果你做得对,你只需要将最顶层保存在你的脑海中。
-
不断重写你的程序。 重写程序通常会产生更简洁的设计。但即使没有,它也会有优势:你必须完全理解一个程序才能重写它,因此没有比这更好的方法来将一个程序加载到你的脑海中。
-
编写可重读的代码。 所有程序员都知道编写可读的代码是好的。但是你自己是最重要的读者。尤其是在开始时;原型是你与自己的对话。并且在为自己写作时,你有不同的优先级。如果你是为其他人写作,你可能不想使代码过于密集。如果像入门教科书一样将事物展开,则程序的某些部分可能最容易阅读。但是,如果你编写代码是为了使其易于重新加载到你的脑海中,那么最好选择简洁。
-
在小组中工作。 当你在脑海中操纵一个程序时,你的视野往往会在你拥有的代码的边缘停止。其他部分你不太了解,更重要的是,不能随意使用。因此,程序员的数量越少,项目就越能完全改变。如果只有一个程序员,就像一开始经常发生的那样,你可以进行全面的重新设计。
-
不要让多个人编辑同一段代码。 你永远无法像理解自己的代码那样理解别人的代码。无论你多么彻底地阅读过它,你都只是阅读过它,而不是编写过它。因此,如果一段代码是由多个作者编写的,那么他们中的任何一个人都无法像单个作者那样理解它。
当然,你不能安全地重新设计其他人正在处理的东西。不仅仅是你必须征得许可。你甚至不会让自己想到这样的事情。重新设计有多个作者的代码就像修改法律;重新设计你独自控制的代码就像看到一个模棱两可的图像的另一种解释。
如果你想让几个人参与一个项目,请将其分成几个组件,然后将每个组件分配给一个人。
- 从小处着手。 随着你对一个程序越来越熟悉,它就越容易保存在你的脑海中。一旦你确信自己已经完全探索过它们,你就可以开始将各个部分视为黑盒。但是,当你第一次开始处理一个项目时,你被迫看到一切。如果你从一个太大的问题开始,你可能永远无法完全理解它。因此,如果你需要编写一个大型复杂的程序,最好的开始方式可能不是为其编写规范,而是编写一个解决问题子集的原型。无论计划有什么优势,它们通常都被能够将程序保存在脑海中的优势所抵消。
令人惊讶的是,程序员经常会意外地击中所有八个要点。有人对一个新项目有一个想法,但由于它没有得到正式批准,他不得不在业余时间做——事实证明这更有成效,因为没有分心。在对新项目的热情驱动下,他连续工作了很多小时。因为最初只是一个实验,而不是“生产”语言,他使用了一种仅仅是“脚本”语言——事实上,这种语言要强大得多。他完全重写了该程序几次;这对于一个官方项目来说是不可辩解的,但这是一项爱的劳动,他希望它是完美的。并且由于除了他之外没有人会看到它,因此他省略了除自我提醒之外的任何注释。他被迫在一个小组中工作,因为他要么还没有告诉其他人这个想法,要么它看起来太没有希望了,以至于不允许其他人参与其中。即使有一个小组,他们也不可能有多个编辑同一代码的人,因为它变化太快了,不可能做到这一点。并且该项目从小处开始,因为该想法最初_很小_;他只是想尝试一些很酷的技巧。
更令人惊讶的是,许多官方批准的项目设法_将所有八件事都做错了_。事实上,如果你看看大多数组织编写软件的方式,就好像他们故意想做错事一样。从某种意义上说,他们是。自从有组织以来,组织的定义特征之一就是将个人视为可互换的零件。这对于更多可并行化的任务(例如打仗)非常有效。在历史上的大部分时间里,一支训练有素的职业士兵军队可以击败一支由个人战士组成的军队,无论他们多么勇敢。但是,拥有想法并不是很可并行化的。而这正是程序的本质:想法。
组织不喜欢依赖个人天才的想法,这不仅仅是事实,而是一种同义反复。这是组织定义的一部分,至少是我们当前对组织的理解。至少是我们当前对组织的理解。
也许我们可以定义一种新型的组织,它结合了个人的努力,而不需要他们是可互换的。可以说,市场就是这样一种组织形式,尽管将市场描述为退化的情况可能更准确——当组织不可能时,你默认得到的东西。
可能我们能做的最好的事情就是某种黑客行为,例如使组织的编程部分与其余部分的工作方式不同。也许最佳的解决方案是大型公司甚至不要尝试在内部开发想法,而只是购买它们。但是,无论解决方案如何,第一步都是意识到存在问题。在“软件公司”这个短语中存在矛盾。这两个词正在朝着相反的方向发展。大型组织中的任何优秀程序员都会与它发生冲突,因为组织旨在阻止程序员努力实现的目标。
优秀的程序员无论如何都能完成很多工作。但这通常需要几乎是对雇用他们的组织的反抗行为。如果更多的人理解程序员的行为是由他们所做的工作的需求所驱动的,也许会有所帮助。他们不是因为不负责任才长时间狂热地工作,在此期间他们会忽略所有其他义务,直接投入编程而不是先编写规范,并重写已经可以工作的代码。他们不是因为不友善才喜欢独自工作,或者对那些探头进来说你好的人咆哮。这种看似随机的令人讨厌的习惯有一个单一的解释:将程序保存在脑海中的力量。
无论理解这一点是否可以帮助大型组织,它肯定可以帮助他们的竞争对手。大公司最薄弱的一点是,他们不允许个人程序员做伟大的工作。因此,如果你是一家小型创业公司,这就是攻击它们的地方。承担必须在一个大脑中解决的那种问题。
感谢 Sam Altman、David Greenspan、Aaron Iba、Jessica Livingston、Robert Morris、Peter Norvig、Lisa Randall、Emmett Shear、Sergei Tsarev 和 Stephen Wolfram 阅读了本文的草稿。