数学家?计算机科学家?黑客?

概述

黑客与画家的共同之处,在于他们都是创作者。

我一直不喜欢“计算机科学”(Computer Science)这个词,主要原因是根本不存在这种东西。计算机科学就像一个大杂烩,由于某些历史意外,很多不相干的领域被强行拼装在一起。

  • 这个学科的一端是纯粹的数学家,他们自称“计算机科学家”,只是为了得到国防部研究局(DARPA)的项目资助。
  • 中间部分是计算机科学家,研究各种专门性的题目,比如网络数据的路由算法。
  • 另一端则是黑客,只想写出有趣的软件,对于他们来说,计算机只是一种表达的媒介,就像建筑师手里的混凝土,或者画家手里的颜料。

有时,黑客做的事情被称为“软件工程”(Software Engineering),但是这个词也是误导的。与其说优秀的软件设计师是工程师(Engineer),不如说是建筑师(Architect)。

也许有一天,“计算机科学”会分裂成几个独立的部分。这可能是一件好事,如果我本人的领域——黑客——能够独立出来,那就更好了。

黑客?论文?

数学家看来并不在乎自己搞的是计算机还是数学。他们很高兴来到这个新地方,然后就开始埋头证明新的定理,与数学系的数学家干的事情完全一样。不一会儿,他们可能就忘了办公楼外的牌子上写的是“计算机科学系”。

但是对于黑客,“计算机科学”这个标签是一个麻烦。如果黑客的工作被称为科学,这会让他们感到自己应该做得像搞科学一样。所以,大学和实验室里的黑客,就不去做那些真正想做的事情(设计优美的软件),而是觉得自己应该写一些研究性的论文。

要是黑客写论文,最好的情况下,写出来的也只是一些补充性的描述,不会具有太大的实际价值。黑客先开发了一个很酷的软件,然后就写一篇论文,介绍这个软件。论文变成了软件成果的展示,这种结合是错误的,常常会产生问题。为了配合论文研究性的主题,你很容易就把工作重点从开发优美的软件转移为开发一些丑陋的东西。

创造优美事物的方式往往不是从头做起,而是在现有成果的基础上做一些小小的调整,或者将已有的观点用比较新的方式组合起来。这种类型的工作很难用研究性的论文表达。

那么,为什么大学和实验室还把论文数量作为考核黑客工作的指标呢?这种事情其实在日常生活中普遍存在。比如,我们使用简单的标准化测试考核学生的学术能力倾向(Scholastic Aptitude);再比如,我们使用代码的行数考核程序员的工作效率。这样的考核容易实施,而容易实施的考核总是首先被采用。

学习分享可知,如果没有任何目标考核、时间限制,并且按照自己的兴趣、方法、节奏来学习,那么可以得到纯粹的学习之乐

黑客真正想做的是设计优美的软件,考核这种工作是非常困难的。你本人需要有良好的设计感,才能去考核别人的设计是否良好。但是,你觉得你有“良好的设计感”,与你实际是否具有,不存在相关关系,甚至可能存在负相关。

唯一有效的外部考核就是时间。经过岁月的洗礼,优美的东西生存发展的机会更大,丑陋的东西往往会被淘汰。不幸的是,这种考核需要的时间可能比一个人的生命还要长。塞缪尔·约翰逊说过,人们对一个作家的评价,需要100年才能达成一致。你必须先等他的那些有影响力的朋友都死了,然后再等他的追随者都死了,才能对他有一个公正的评价。

肤浅意味着遗忘,深刻意味着记忆。——佚名

创作者?科学家?

人们无法考核你的工作,甚至误解你的工作,都不是最糟的事。更大的危险是你自己也会误解自己的工作。

黑客搞懂“计算理论”(Computation Theory)的必要性,与画家搞懂颜料化学成分的必要性差不多大。一般来说,在理论上,你需要知道如何计算时间和空间复杂度(Time and Space Complexity);如果你要写一个解析器,可能还需要知道状态机(State Machine)的概念;除此以外,并不需要知道特别多的理论。这些可比画家必须记住的颜料成分少很多。

我发现,黑客新想法的最佳来源,并非那些名字里有“计算机”三个字的理论领域,而是来自于其他创作领域。与其到“计算理论”领域寻找创意,你还不如在绘画中寻找创意。

书上说,调试(Debugging)是最后的步骤,用来纠正打字的错误和疏忽。可是我的工作方法看上去却像编程就是在调试。如果我那时看到其他创作领域,比如绘画或者建筑,我就会想到,自己的方法其实有一个正式的名称——打草稿。我现在认为,大学里教给我的编程方法都是错的。你把整个程序想清楚的时间点,应该是在编写代码的同时,而不是在编写代码之前,这与作家、画家和建筑师的做法完全一样。

创作者不同于科学家,明白这一点有很多好处。除了不用为静态类型烦恼以外,还可以免去另一个折磨科学家的难题,那就是“对数学家的妒忌”。科学界的每一个人,暗地里都相信数学家比自己聪明。我觉得,数学家自己也相信这一点。最后的结果就是科学家往往会把自己的工作尽可能弄得看上去像数学。对于物理学这样的领域,这可能不会有太大不良影响。但是,你越往自然科学的方向发展,它就越成为一个严重的问题。

一页写满了数学公式的纸真是令人印象深刻啊(小窍门:用希腊字母表示变量名会令人印象更深刻)。因此,你就受到巨大的诱惑,去解决那些能够用数学公式处理的问题,而不是去解决真正重要的问题。如果黑客认识到自己与其他创作者——比如作家和画家——是一类人,这种诱惑对他就不起作用。作家和画家没有“对数学家的妒忌”,他们认为自己在从事与数学完全不相关的事情。我认为,黑客也是如此。

黑客?企业?

如果大学和实验室不允许黑客做他们想做的事情,那么适合黑客的地方可能就是企业。不幸的是,大多数企业也不允许黑客做他们想做的事情。大学和实验室强迫黑客成为科学家,企业强迫黑客成为工程师。

直到最近我才发现这一点。雅虎收购Viaweb的时候,他们问我想做什么。我对商业活动从来都没有太大兴趣,就回答说我想继续做黑客。等我来到雅虎以后,发现在他们看来,“黑客”的工作就是用软件实现某个功能,而不是设计软件。在那里,程序员被当作技工,职责就是将产品经理的“构想”(如果这个词是这么用的话)翻译成代码。

这似乎是大公司的普遍情况。大公司这样安排的原因是为了减少结果的标准差。

如果某一天你想要去赚大钱,那么记住上面这一点,因为这是创业公司能够成功的原因之一。大公司为了避免设计上的灾难,选择了减少设计结果的标准差。但是当你排斥差异的时候,你不仅将失败的可能性排除在外,也将获得高利润的可能性排除在外。所以,如果你的竞争优势是在软件设计方面,并且你的对手是一家大公司,它大到由一群产品经理来设计软件,那么你的对手将永远无法赶上你。不过说实话,这样的机会不容易找到。

真正竞争软件设计的战场是新兴领域的市场,这里还没有人建立过防御工事。只要你能做出大胆的设计,由一个人或一批人同时负责设计和实现产品,你就能在这里战胜大公司。微软公司自己一开始就是这样走向成功的,苹果公司和惠普公司也是如此。我觉得几乎所有的创业公司都是这样取得成功的。

所以,开发优秀软件的方法之一就是自己创业。但是,这样做会遇到两个问题。一个问题是自己开公司的话,必须处理许许多多与开发软件完全无关的事情;另一个问题是赚钱的软件往往不是好玩的软件,两者的重叠度不髙。

设计编程语言是很好玩的事情,事实上,微软的第一个产品就是一种编程语言。1975年,MITS公司发布了Altair 8800型计算机,比尔·盖茨意识到为它开发软件是有利可图的,他写了一个BASIC语言解释器,卖给了MITS。这就是微软公司的第一个产品,当时比尔·盖茨还是哈佛大学二年级在校生。但是,如今没有人会出钱买编程语言。

游戏引擎的起源中,Romero用BASIC语言来制作游戏,之后转向IBM-PC、C语言

Linus和Linux中,Linus用BASIC语言来编写程序,之后转向UNIX、C语言

液晶显示器的发展历程中,Intel的CPU是386,Microsoft的操作系统是DOS

黑客如何才能做自己喜欢的事情?我认为这个问题的解决方法是一个几乎所有创作者都知道的方法——找一份养家糊口的“白天工作”(Day Job)。这个词是从音乐家身上来的,他们晚上表演音乐,所以白天可以找一份其他工作。更一般地说,“白天工作”的意思是,你有一份为了赚钱的工作,还有一份为了爱好的工作。

当我说,黑客解决生计问题的方法是找一份“白天工作”,然后在其余时间开发优美的软件,我并没有说这是一个新方法。开源软件界的黑客早就这样做了。我想说的其实是,开源软件的这种工作模式可能就是正确的模式,因为它已经被其他领域的创作者都验证过了。

我们面试程序员的时候,主要关注的事情就是业余时间他们写了什么软件。因为如果你不爱一件事,你不可能把它做得真正优秀,要是你很热爱编程,你就不可避免地会开发你自己的项目。微软不鼓励雇员为开源项目做贡献,甚至业余时间也不行。但是,如此之多的一流黑客都在从事开源项目,所以这个政策主要的效果,可能就是使得微软公司很难雇到一流的程序员。

Quake和计算机图形学中,计算机图形学的泰斗级人物Abrash,在Gates(Microsoft)、Carmack(id Software)之间选择了后者

黑客?编程?

因为黑客更像创作者,而不是科学家,所以要了解黑客,不应该在科学家身上寻找启示,而是应该观察其他类型的创作者。那么,从画家身上,我们还能借鉴到什么对黑客的启示呢?

有一件事情是可以借鉴的(至少可以确认),那就是应该如何学习编程。画家学习绘画的方法主要是动手去画,黑客学习编程的方法也理应如此。大多数黑客不是通过大学课程学会编程的,他们从实践中学习,13岁时就自己动手写程序了。即使上了大学,黑客学习编程依然主要通过自己写程序。

黑客通过实践学习编程,这又是一个标志,说明黑客与科学家的区别有多大。

  • 科学家研究的基础都是现有的很完美的成果,在这个意义上,他们的第一步只是在复制别人已经做过的工作。最后,他们才会从某一个点开始,进行自己的原创性工作。
  • 黑客就不一样,从一开始做的就是原创性工作,根本没有他人完美的成果可以依靠。

创作者另一个学习的途径是通过范例。对画家来说,博物馆就是美术技巧的图书馆。几百年来,临摹大师的作品一直是传统美术教育的一部分,因为临摹迫使你仔细观察一幅画是如何完成的。

同样地,黑客可以通过观看优秀的程序学会编程,不是看它们的执行结果,而是看它们的源代码。开源运动最鲜为人知的优点之一,就是使得学习编程变得更容易了。我学编程的时候,不得不主要依靠教材上的范例。那时可以搞到的源码,主要来自于UNIX,但是就连UNIX也不是开源的,大部分阅读UNIX源码的人都是通过约翰·莱昂斯那本书的非法影印本。该书虽然是1977年写的,但是在1996年之前都不被允许公开出版。

关于向没有技术背景的人解释UNIX,可参见Linus和Linux

普通黑客与优秀黑客的所有区别之中,会不会“换位思考”可能是最重要的单个因素。有些黑客很聪明,但是完全以自我为中心,根本不会设身处地为用户考虑。这样的人很难设计出优秀软件,因为他们不从用户的角度看待问题。

判断一个人是否具备“换位思考”的能力有一个好方法,那就是看他怎样向没有技术背景的人解释技术问题。我们认识这样一些人,他们在其他方面非常聪明,但是把问题解释清楚的能力却惊人低下。如果聚会上,外行人问他们“什么是编程语言”,他们会这样回答:“哦,高级语言就是编译器的输入代码,用来产生目标码。”高级语言?编译器?目标码?……如果对方不知道什么是编程语言,那么他显然也不会知道这些概念。

软件的部分功能就是解释自身。为了写出优秀软件,你必须假定用户对你的软件基本上一无所知。你要明白,用户第一次使用你的软件的时候,不会预先做好功课,他们没有任何准备就开始用了,所以软件的使用方式最好能符合用户的直觉,别指望用户去读使用手册。在这方面,我见过的最佳系统是1984年原始的Macintosh电脑。它做到了那时别的软件都做不到的事情——它真的能用。

使用Go语言实现GUI应用中,Macintosh引入了GUI,之后是Windows、UNIX

源代码也应该可以自己解释自己。如果我只能让别人记住一句关于编程的名言,那么这句名言就是《计算机程序的结构与解释》一书的卷首语:

程序写出来是给人看的,附带能在机器上运行