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