黑客与画家(Hackers and Painters)

Table of Contents

1. 前言和序

Paul Graham有一套完整的创业哲学,他的创业公式是:

  1. 搭建原型
  2. 上线运营(别管bug)
  3. 收集反馈
  4. 调整产品
  5. 成长壮大

首先他鼓励创业公司快速发布产品,因为这样可以尽早知道一个创意是否可行。其次他认为一定要特别关心用户需要什么,这样才有办法将一个坏项目转变成为好项目。此外比起那些令人较好的创意,Graham更加看重创始人的素质。他说:”我们一开始就认识到,创始人本身比他的创意更重要。”他还认为,小团队更加容易成功,创始成员总数不要超过三个人。其中一个原因是,创始人越多,股权越不容易平等均分,容易造成内耗。

黑客伦理:

  1. 使用计算机以及所有有助于了解这个世界本质的事物都不应该受到任何限制。任何事情都应该亲手尝试。(Access to computers and anything that might teach you something about the way the world works – should be unlimited and total. Always yield to the Hands-On Imperative)
  2. 信息应该完全免费。(All information should be free).
  3. 不信任权威,提倡去中心化。(Mistrust Authority – Promote Decentralization).
  4. 判断一名黑客的水平应该看他的技术能力,而不是看他的学历、年龄或者地位等其他标准。(Hackers should be judged by their hacking, not bogus criteria such as degrees, age, race, or position).
  5. 你可以用计算机创造美和艺术。(You can create art and beauty on a computer).
  6. 计算机使生活更美好。(Computers can change your life for the better).

术语解析:

  1. Blub困境(Bulb Paradox):程序员的思想往往会受到自己正在使用的语言的束缚,不相信存在更强大的语言。
  2. 格林斯潘第十定律(Greenspun’s Tenth Rule):任何C或Fortran程序复杂到一定程度之后,都会包含一个临时开发的,只有一半功能的,不完全符合规范,到处都是bug的,运行速度很慢的Common Lisp实现。
  3. “奥卡姆剃刀”原则(Occam’s Razzor):简单的解释就是较好的解释。
  4. 帕金森定律(Parkinson’s Law):完成一项任务所需要的资源会不断扩展,直到把这种资源消耗光为止。

2. 为什么书呆子不受欢迎

但是我认为,孩子们欺负书呆子的主要原因也与追求“受欢迎”的心理有关。怎样才能让自己更受欢迎?个人魅力只是很小的一个方面,你应该更多考虑如何结盟。秘诀就是不停地设法使自己与其他受欢迎的人变得关系更密切。没有比什么一个共同的敌人更能使得人们团结起来了。这就好比一个政客,他想让选民忘记槽糕的国内局势,方法就是为国家找出一个敌人,哪怕敌人并不真的存在,他也可以创造一个出来。

回到过去,我会像13岁的我提供一些建议,主要告诉他要昂起头看世界。我在那个年纪根本不知道这一点,而我身边的世界又虚假的像奶油夹心蛋糕一样。不仅是学校,整个小镇都很虚假,不像真实的世界。那么人们为什么还要搬到郊区去住?为了培养下一代!难道难怪郊区生活是如此的乏味和贫瘠,整个镇子就像一个巨大的幼儿园,所有的一切都是为了教育下一代而有意识的造出来的。

在我生长的这个地方,感觉整个世界就是这么大,你根本没有别的地方可去,没有别的事情可以做。这一点都不令人意外,郊区就是故意这样设计的,与外部世界隔离,不让儿童沾染到外界有害的东西。至于学校,不过是这个虚假环境中关住牲口的围栏。表面上学校的使命是教育儿童,事实上学校的真正目的是把儿童都关在一个地方,以便大人白天可以腾出手来把事情做完。我对这一点没有意见,在一个高度工业化的社会,对孩子不加管束,让他们四处乱跑无疑是场灾难。让我困扰的事,不是把孩子关在监狱里,而是(a)不告诉他们这一点,并且(b)把这监狱的大部分交给犯人来管理。孩子们被送进来,花6年时间,记住一些毫无意义的事实,还要身处在一群四肢发达的小巨人管理的世界。而那些巨人们只知道追逐一个椭圆形棕色的球,好像这是全世界最天经地义的事情。这简直就像一场超现实的鸡尾酒化妆晚会,如果孩子畏缩不前,瑟瑟发抖,他们就会被视为怪人。

过去的社会中,青少年扮演一个积极的角色。工业化时代到来之前,青少年都是某种形式的学徒,不是在某个作坊,就是在某个农庄,甚至在某军舰上。他们不会被扔到一旁,创造自己的小社会,他们是成年人社会的低级成员。以前的青少年似乎更尊敬成年人,因为成年人都是看得见的专家,会传授他们所要学习的技能。如今的大多数青年,对他们的家长在遥远的办公室所从事的工作几乎一无所知。他们看不到学校作业与未来走向社会后从事的工作有何联系?如果青少年更尊重成年人,那么成年人也会更接受青少年。经过几年的训练,学徒就能担当重大的责任,即使是那些刚招收进来的学徒,也能用来送信或打扫操场。如今的成年人根本不接受青少年,一般来说他们都是在办公室工作,所以就在上班的路上,顺路把孩子送到学校去关着,这有点像他们周末外出度假时,把狗送到寄养的地方。

如果存在对于真正能力的外部测试,待在等级关系的底层也不会那么痛苦。球队的新人并不会怨恨老队员的球技,他们希望有一天自己也能如此,所以很高兴有机会向老队员求教。老队员可能也会因此产生一种传帮带的光荣感(noblesse oblige)。最重要的是老队员的地位是通过他们本身出色的能力获得的,而不是通过排挤他人获得的。宫廷中的等级关系就完全是另外一回事了。这种类型的团体贬低了每一个成员的人格,底层成员对上层成员毫无敬意,而上层成员也没有传帮带的光荣感。这里的一切就是杀与被杀。

哪怕你什么也改变不了,但是仅仅是理解自己的处境,也能使得痛苦减轻一些。书呆子并不是失败者。他们只是在玩一个不同的游戏,一个更接近真实世界状况的游戏。成年人明白这一点。成功的成年人,几乎都声称自己在高中属于书呆子。对于书呆子来说,意识到学校并非全部的人生,也是很重要的事情。学校是一个很奇怪的、人为设计出来的体系,一般像是无菌室,一半像是野蛮洪荒之地。它就像人生一样,里面无所不包,但是又不事物的真实样子。它只是一个暂时的过程,只要你向前看,你就能超越它,那学你还是身处其中。

3. 黑客与画家

要是黑客写论文,最好的情况下,写出来的也只是一些补充性的描述,不会具有太大的实际价值。黑客先开发了一个很酷的软件,然后就写一篇论文,介绍这个软件。论文变成了软件成果的展示。这种结合是错误的,常常会产生问题。为了配合论文研究性的主题,你很容易就把工作重点从开发优美的软件转移为开发一些丑陋的东西。优美的软件并不总是论文的合适题材。首先,科学研究必须具有原创性。写过博士论文的人都知道,确保自己在开垦新领地的方法,就是去找那些没有人要土地。其次,科学研究必须是能够产生大量成果的,而那些不成熟的,障碍重重的领域最容易写出许多篇论文,因为你可以写那些为了完成工作、你不得不克服的障碍。没有什么比一个错误的前提更容易产生大量待解决的问题。人工智能(AI)领域的大部分情况,都符合这条“如何凭空创造出问题”的规律。你假定使用一系列的谓词逻辑(predicate logic)表达式,再加上代表抽象概念的参数,就能表达人类的知识,那么,你就可以写出许许多多的论文,解释如何完成这项工作。创造优美的东西往往不是从头做起,而是在现有成果的基础上做一些小小的调整,或者将已有的观点用比较新的方式组合起来。这种类型的工作很难用研究性的论文表达出来。

黑客搞懂“计算理论”(theory of computation)的必要性,与画家搞懂颜料化学成分的必要性差不多。一般来说,在理论上,你需要知道如何计算“时间复杂度”和”空间复杂度“(time and space complexity);如果你要写一个解析器,可能好需要知道状态机(state machine)的概念;除此之外,并不需要知道特别多的理论。这些可比画家必须记住的颜料成分少很多。我发现,黑客新想法的最佳来源,并非那些名字里有“计算机”三个字的理论领域,而是来自于其他创造领域。与其到“计算理论”领域寻找创意,你还不如在绘画中寻找创意。

萨缪尔约翰逊在他编辑的《莎士比亚戏剧集》的前言中写道:“他(莎士比亚)的影响远远超过他的时代,时间就是对他文学成就的检验。不管他的作品从那时的暗语,风俗,政治局势之中得到过怎样的优势,这些优势都已经消失多年了。他在每一幕戏剧中,通过模拟那时的生活所产生的每一个欢乐的主题或悲伤的动机,都已经趋于平淡,不再是戏剧的亮点。贵族的宠爱和对手的竞争都不再产生效果;朋友和敌人都走进了坟墓;他的作品再也不是支持一方,打击一方的舆论工具;它们既不能产生虚名,也不会带来恶意的攻击。人们阅读这些作品只有一个理由,那就是欣赏作品本身。因此,只有人们真正欣赏它们,会发出赞美…”

创造者不同于科学家,明白这一点有很多好处。除了不用为静态类型烦恼以外,还可以免去另一个折磨科学家的难题,那就是“对数学家的嫉妒”。科学界的每一个人,暗地里都相信数学家比自己聪明,我觉得数学家自己也相信这一点。最后的结果就是,科学家往往会把自己的工作尽可能弄弄得看上去像数学。对物理物理这样的领域,这可能不会有太大不良影响。但是,你越往自然科学的方向发展,它就越可能成为一个严重的问题。一页写满了数学公式的纸真是令人印象深刻呀。(小窍门:用希腊字母表示变量会令人印象更深刻)因此,你就受到巨大的诱惑,去解决那那些能够用数学公式处理的问题,而不是去解决真正重要的问题。如果黑客认识到自己与其他创作者,比如作家和画家,是你一类人,这种诱惑对他就不起作用。作家和画家没有对数学家的嫉妒,他们认为自己在从事与数学完全不相关的事情。我认为,黑客也是如此。

如果某一天你想要去赚大钱,那么请记住这一点,因为这是创业公司能够成功的原因之一。大公司为了避免设计上的灾难,选择了减少设计结果的标准差。但是当你排斥差异的时候,你不仅将失败的可能性排除在外,也将获得高利润的可能性排除在外。这对大公司来说不是问题,因为生产特别优秀的产品不是它们的获胜手段。大公司只要做大不太烂,就能赢。

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

创业的另外一个问题是赚钱的软件往往不是好玩的软件,两者的重叠度不高。如果你想赚钱,你可能不得不去干那些很麻烦很讨厌的事情,因为这些事情没有人愿意义务来干。此外,所有软件创作者都面临这个问题。价格是由供给和需求共同决定的。好玩的软件的需求量,比不上解决客户麻烦问题的软件需求量。开发编程语言的收入,比不上把某些公司老掉牙的数据库连接上服务器的收入。

因为黑客更像创作者,而不是科学家。所以要了解黑客,不应该在科学家身上寻找启示,而是也能够该观察其他类型的创作者。那么,从画家身上,我们还能借鉴到什么对黑客的启示呢?(ps:后面部分非常精彩)

1.画家的作品都会保留下来,你观察这些作品,就能看出他们是怎么一步步通过实践学习绘画的。如果你把一个画家的作品按照时间顺序排列,就会发现每幅画所用的技巧,都是建立在上一幅作品学到的东西至上。某幅作品如果有特别出色之处,你往往能够在更早的作品上发现一个小规模的初期版本。我想大多数创作者都是这样学习和工作的,作家和建筑师似乎都是如此。也许对于黑客来说,采取像画家这样的做法很有好处:应该定期地从头开始,而不要长年累月地在一个项目上不断地工作,并且试图把所有的最新想法都以修订版的形式包含进去。

2.创作者另一个学习的退经就是通过范例。对画家来说,博物馆就是美术技巧的图书馆。几百年来,临摹大师的作品一直都是传统美术教育的一部分,因为临摹迫使你仔细观察每一幅画是如何完成的。同样黑客可以通过观看优秀的程序学会编程。不是看它们的执行结果,而是看它们的源代码。开源运动最鲜为人知的优点之一,就是式的学习编程变得更加容易了。

3.还有一个可以借鉴的绘画的地方:一幅画是逐步完成的。通常一开始就是一张草图,然后再逐步填入细节。但是,它又不单纯是一个填入细节的过程。有时,原先的构想看来是错的,你就必须动手修改。无数古代油画放在X光下检视,就能看出修改痕迹,四肢的位置被移动过,或者脸部的表情经过了调整。绘画的这个创作过程就值得学习。我认为黑客也应该这样工作。你不能现盼望有一个完美的规格设计,然后再动手编程,这样想是不现实的。如果你预先承认规格设计是不完美的,在编程的时候,就可以根据需要当场修改规格,最终会有一个更好的结果。

4.用绘画的例子作为参考,不仅能够教会我们如何管理自己的工作,还能教会我们如何与他人一起工作。历史上许多伟大的艺术品都是多人一起合作的结果。就我所知,当多个画家共同创作一幅作品时,每个人画的部分都是不一样的。通常来说,大师负责画主要人物,助手们负责画次要人物和背景。但是,你肯定找不到某个部分是两个人一起画的。我认为,这也是多人共同开发一个软件的正确模式。需要合作,但是不要“合”得过头。如果一个代码块由三四个人共同开发,就没有人真正“拥有”这块代码。最终它就会变得像一个公共杂物间,没人管理,又脏又乱,到处堆满了冗余代码。正确的合作方式是将项目分割成严格定义的模块,每一个模块由一个人明确负责。模块与模块之间的接口经过精心设计,如果可能的话,最好把文档说明写得像编程语言规范那样清晰。

5.就像绘画作品一样,大多数软件是为人类用户准备的。所以黑客必须像画家一样,时刻考虑到用户的人性需要,这样才能做出伟大的产品。你必须能够站在用户的角度思考问题,也就是说你必须学会“换位思考”。但是“换位思考”并不意味着你要做自我牺牲。实际上,这是完全不同的两回事。了解别人对于事情的看法,并不代表你为他的利益服务。判断一个人是否具备“换位思考”的能力有一个好方法,那就是看他怎样向没有技术背景的人解释技术问题。

坚持一丝不苟,就能取得优秀的成果。因为那些看不见的细节累加起来,就变得可见了。当人们从达芬奇的《女性肖像》前面走过的时候,他们的注意力往往立刻就被它吸引住了,那时他们甚至还没有看到说明的标签牌,没有意识到这是达芬奇的作品。所有那些看不见的细节合并在一起,就使得这样东西产生了惊人的效果,仿佛上千个细微的声音都以同一个音调在歌唱。同样的,优秀的软件也要求对美的狂热追求。如果你查看优秀软件的内部,就会发现那些预料中没有人会看见的部分也是优美的。我对待代码的认真程度远远超过我对待其他事情,如果我以这种态度对待日常生活的每一件事,那么我就够资格找心理医生开处方药了。看到代码前面的缩进乱七八糟,或者看到丑陋的变量名,都会把我逼疯的。

为了做出优秀的工作,你必须把这种心理周期考虑在内。只有这样,你才能根据不同的事情找出不同的应对方法。你有一辆手动变速的汽车,你把它开上山,有时不得不松开离合器,防止汽车熄火。同样,暂时放手也有时能防止热心熄火。对于画家和黑客这样的创造者,有些工作需要投入巨大的热情,另一些则是不需要很操心的日常琐事。在你厌倦的时候再去做那些比较容易的工作,这是个不错的主意。

4. 不能说的话

历史的常态似乎就是,任何一个年代的人们都会对一些荒谬的东西深信不疑。他们的信念还很坚定,只要有人稍微表示了一点怀疑,就会惹来大麻烦。我们这个时代是否有所不同?只要读过一点历史,你就知道答案几乎确定无疑,就是“没有不同”。即使有那么一丝微小的可能,有史以来第一次,我们这个时代的所有信念都是正确的,那也是出于惊人的巧合,而不是因为我们真找到了正确的方向。

有时候,别人会对你说:“要根据社会需要,改造自己的思想(well-adjusted)。”这种说法隐含的意思似乎是,如果你不认同社会,那么肯定是你自己的问题。你同意这种说法吗?事实上,它不仅不对,而且还会让历史倒退。如果你真的相信了他,凡是不认同社会之处,你连想都不敢想,马上就放弃自己的观点,那才会真正出问题。

如今,当然也有这样的标签,从万金油式的“不适当”(inappropriate),到可怕的“制造分裂”(divisive),不胜枚举。好在不管是哪个年代,分辨这样的标签应该是比较容易的。你只要看看人们怎么称呼那些自己不赞成,但是又不算错的观点就行了。当一个政治家说自己的对手是错的,这是直截了当的批评。但是,如果他不谈论对错,却使用“制造分裂”,或者“对种族问题不敏感”这样的标签攻击对手,那么我们就应该多加注意了。

我们可以自以为是的相信,当代人比古代人更聪明,更高尚。但是,了解的历史越多,就越明白事实并非如此。古人与我们是一样的人,他们既不是更勇敢,也不是更野蛮,而是像我们一样通情达理的普通人。不管他们产生怎样的想法,都是正常人产生的想法。

我猜想,道德禁忌的最大制造者是那些权力斗争中略占上风的一方。你会发现,这一方有实例推行禁忌,同时又软弱到需要禁忌保护自己的利益。大多数的斗争,不管它们实际争的是什么,都会以思想斗争的形式表现出来。思想斗争更容易获取支持者,不管哪一方获胜,他们所代表的思想也就被认为获得了胜利,仿佛上帝通过选择胜利的一方表示了自己的倾向。我并不是想说斗争从来就与思想无关,而是要强调,不管实际上是否有思想斗争,斗争都是会以思想斗争的形式表现出来。

所以,如果你要寻找不能说的话,可以观察流行的产生方式,试着预测它会禁止哪些话。哪一个团体势力强大,却又精神高度紧张?这种团体喜欢压制什么样的思想观点?近来有没有什么社会斗争?失败的一方是哪一方?受到他们牵连的是什么样的思想观点?如果一个先锋人物,要挣脱当前的流行(比如上一代人的观点)脱颖而出,他会支持什么样的思想观点?随大流的人对什么样的思想观点抱有恐惧心?

在科学领域,质疑他人的结论和公认的假设是尤其重要的一件事情,会提供巨大的科学创造的优势。科学家(至少是优秀的可科学家)做事的方式,准确地说,就是寻找传统观点中无法自圆其说的地方,然后试着拆开那里,看个究竟,瞧瞧里面到底出了什么问题。新的理论就是这样产生的。换而言之,一个好的科学家,并不仅仅是避开传统观点,还要努力打破传统观点。科学家就是要自找麻烦。这应该是任何学者的研究方式,但是科学家似乎特别愿意一探究竟。做一个异端是有回报的,不仅是在科学领域,在任何有竞争的地方,只要你能看到别人看不到或者是不敢看的东西,你就有很大的优势。训练自己去想那些不能想的事情,你获得的好处会超过所得到的想法本身。

一旦发现“不能说的话”,下一步怎么办?我的建议就是别说,至少也要挑选合适的场合再说,只打那些值得打的仗。你要明白,自由思考比畅所欲言更重要。如果你感到一定要跟那些人辩个明白,决不咽下这口气,一定要把话说清楚,结果很可能是从此你再无法自由理性地思考了。我认为这样做不可取,更好的做法是在思想和言论之间划一条明确的界线。在心里无所不想,但是不一定要说出来。我就鼓励自己在心里默默地思考那些最无法无天的想法。你的思想是一个地下组织,绝不要把那里发生的事情一股脑地说给外人听。“格斗俱乐部”的第一条规则,就是不要提到格斗俱乐部。

“守口如瓶”的真正缺点在于,你从此无法享受讨论带来的好处了。讨论一个观点会产生更多的观点,不讨论就什么观点也没有。所以,如果可能的话,你最好找一些信得过的知己,只与他们畅所欲言,无所不谈。这样不仅可以获得新观点,还可以用来选择朋友。能够一起谈论“异端邪说”并且不会因此气急败坏的人,就是你最应该认识的朋友。

狂热分子试图引诱你说出来真心话,但是你可以不回答。如果他们不放手,一定要你回答“到底是赞成还是反对我们”,你不妨以不变应万变:“我既不反对也不赞成”。不过,更好的回答是“我还没有想好”。哈佛大学校长拉里萨默尔(Larry Summer)被逼表态时,就是这么说的。他后来解释“别想在我身上做石蕊实验。“人们喜欢讨论的许多问题实际上是很复杂的,马上说出你的想法对你并没有任何好处。

如果你的数学不好,那么你自己会知道,因为考试的时候你得不出正确答案。但是,如果你的思想很保守,你自己不会知道,而且你很可能还会持有相反的看法。请记住,所谓流行(传统观念也是一种流行),本质上就是自己看不见自己的样子,否则就不会有流行了。那些被流行抓住的人,流行就不再是流行,而是应该要做的正确的事情。只有保持一定的距离,才能观察到人们观念的变化,发现流行(也就是人们自以为正确的事情)到底是什么。时间就是一种产生距离的简单方法,实际上新的流行让旧的流行更容易被观察到。因为对比之下,旧的流行就会显得很荒唐,从钟摆波动的一端望去,上一个周期的端点就显得特别遥远。

不过,想要摆脱你自己的时代的流行,需要一点自觉。没有了时间所产生的距离,不得不自己创造距离。你不要成为你不要让自己成为人群的一份子,而要尽可能的远离人群,观察正在发生的事情,特别注意那些被压制的思想观点。各种各样的标签可能是外部线索的最大来源,帮助你发现这个时代流行的是什么。如果一个命题是错的,这就是它所能得到的最坏评价,足够批判它了,根本不用再加上任何其他标签。但是,如果一个命题不是错的,却被加上各种标签,进行压制和批判,那就有问题。因为只要不是错的观点,就不应该被压制的讨论。所以当你看到有些话被攻击为出自XX分子或XX主义,这就是明确的信号,表明背后有问题。不管在1630年还是在2030年,都是如此。当你听到有人在用这样的标签,就要问为什么。

如果你想要清晰地思考,就必须远离人群。但是走得越远,你的处境就会越困难吗,受到的阻力也会越大,因为你没有迎合社会习俗,而是一步步地与它背道而驰。小时候,每个人都会鼓励你不断地成长,变成一个心智成熟,不要再耍小孩子脾气的人。但是很少有人鼓励你继续成长,变成一个怀疑和抵制社会错误潮流的人。如果自己就是潮水的一部分,怎么能看见潮流的方向呢?你只能永远保持质疑。问自己,什么话是我不能说的?为什么?

5. 良好的坏习惯

信不信由你,“黑”的这两个意思也是相关的。丑陋的做法与聪明的做法存在一个共同点,那就是不符合常规。你用胶带把包裹绑在自行车上,那是不合常规的丑陋做法;你提出充满想象力的概念,推翻欧几里德(Eculidean space),那是不符合常规的聪明做法。从”丑陋“到”聪明“,他们之间存在一种连续性渐变。

你能想象今天的美国总统也这么说吗?这些开国元勋就像直率的老祖母,用自己的言辞让他们的那些不自信的继承者感到了惭愧。他们提醒我们不要忘记自己从何而来,提醒我们,正是那些不服从管教的人们,才是美国财富与力量的源泉。

6. 另一条路

互联网软件的发布规则是:它运行不不了,你就无法发布。一旦它能运行了,你就可以立刻发布。这些行业的老手会想:你说的好听!软件运行不了,就不发布,但是如果你已经对外承诺了明确的发布日期,到时却没有准备好,怎么办?这个问题听起来有道理,但是事实上,你不会对互联网软件做出这样的承诺,因为它根本就没有”版本“这个概念。你的软件是连续性渐变的,某些更新也许比较重大,但是”版本“这个概念不适用于互联网软件。

解决新代码的bug,要比解决历史遗留代码的bug容易。在自己刚刚写好的代码中,找出bug往往会比较快。有时,你只要看到出错提示,就知道问题出在哪里,甚至都不用看源码,因为潜意识中你已经在担心那个地方可能会出错。如果你要解决的bug出自于6个月前写好的代码,那么就麻烦了,就要大费周章了。那时,你对代码也已经不熟悉了,就更可能采用危险的方式解决问题,甚至引入更多的bug。这观点也是引申自特雷弗-布莱克威尔(Trevor Blackwell)的话,他说:“随着软件规模的增大,开发成本指数式上升,这可能是因为修正旧bug的原因。如果bug都能被快速发现,成本的上升形态就能基本保持线性。”

如果软件的新版本要等到一年后才能发布,我就会把大部分新构思束之高阁,至少过上一段时间再来考虑。但是,构思这种东西有一个特点,那就是它会导致更多的构思。你有没有注意过,坐下来写东西的时候,一般的构思是写作时产生的?软件也是这样。实现某个构思,会带来更多的构思。所以,将一个构思束之高阁,不仅意味着延迟它的实现,还意味着延迟所有在实现过程中激发的构思。事实上,将一个构思束之高阁,甚至会限制新构思的产生。因为你看一眼堆放在一边、还没有实现的构思,就会想”我已经为下一个版本准备了很多新东西要实现了“,你就懒得再思考更多的新功能了。

如果要说有什么缺点,就是由于开发人员比较少,每个程序员都必须承担一点儿系统管理的责任。当你在服务器上发布软件时,必须有人监控服务器,但是由于人员太少,监控员只能由开发人员兼任。Viaweb有许多系统组件,变动非常频繁,导致应用软件和系统软件之间的界限很难区分。硬性指定一条界限将限制我们的开发。所以,虽然我们总是安慰自己,公司运营很快就能走上正轨,一两个月后就能平稳发展,那时就可以雇一个专职的系统管理员让他专门负责维护服务器,但是这个愿望一直没有实现。

有钱的客户倾向于更贵的选择,即使便宜的选择更符合他们的需要,他们也不会买。这种现象普遍存在。原因就是,那些索要高价的人,将更多的钱投入推销。Viaweb不采用这种做法。互联网咨询公司从我们手里抢走了几个高端商家,他们说服这些商家,让他们相信更好的选择就是,花50万美元,将网上商店开在自己的服务器上。结果是意料之中的,当圣诞节购物高峰来临时,服务器的负载陡然上升,这些商家一个接一个的发现,他们的选择并不是那么正确。Viaweb的系统远比大多数商家自己搭建的系统更高级更先进,但是我们付不起高额的宣传费,无法让他们明白这一点。我们的宣传费每月只有300美元,无法派遣一个衣冠楚楚,言之凿凿的团队到客户公司做演示。有段时间我们构思了一种新类型的服务名叫“Viaweb黄金版”。它比我们普通类型的服务贵10倍,但是功能一模一样,唯一的区别就是有专门穿的西装面对面把它卖给你。我们从未把这个构思付诸实践,但是我很肯定,要是真推出的话,一定会有商家购买。

大公司付出的高价之中,很大一部分是商家为了让大公司买下这个商品而付出的费用。如果国防部花1000美元买一个马桶座圈,部分原因是要让国防部买下它本身就需要花很多钱。这就是为什么公司内部的局域网软件明明不可取,但是还会继续存在并且不断发展的一个原因。这样的软件更昂贵,但是你对这个难题就是无能为力。所以最好的安排就是把个人和小企业客户放在第1位,其他的客户该来的时候就会来。

由于个人经历的关系,特雷弗布莱克威尔对这一点的认识可能比其他任何人都深刻。他写道:“我会进一步说,由于互联网软件的程序员非常辛苦,所以会使得经济优势根本性地从大公司向创业公司转移。互联网公司软件要求的那种工作强度和付出,只有当公司是其本人所有时,程序员才愿意提供。软件公司可以雇到能干的人,让他们去感轻松的事情,也可以雇到不能干的人,让他们去干艰苦的事情,但是无法雇到非常能干的人,让他们去干非常艰苦的事情。因为互联网软件的创业不需要太多的资本,所以大公司可以与创业公司竞争的优势就所剩无几了。”

管理企业其实非常简单,只要记住两点就可以了:做出用户喜欢的产品,保证开支小于收入。只要做到这两点,你就会超过大多数创业公司。随着事业的发展,你就自己琢磨出来其他的诀窍。刚开始的时候,你可能入不敷出,但是只要亏损不持续太久,你就不会有事。如果初期阶段缺少资金,这至少有助于你养成勤俭节约的习惯。开支越小,就越不会超支。至于如何做出用户喜欢的产品,下面是一些通用规则。从制造简洁的产品开始着手,首先保证你自己愿意使用。然后迅速做出1.0版,并且不断地加以改进,整个过程中密切倾听用户的反馈。用户总是对的,但是不同的用户要求不一样。地段的用户要求简化操作和清晰易懂,高端的用户要求你增加新功能。软件最大的好处就是让一切变得简单。但是,做到这一点的方法是正确设置默认值,而不是限制用户选择。如果竞争对手的产品很糟糕,你也不要自鸣得意。比较软件的标准应该是看对手的软件将来会有什么功能,而不是现在有什么功能。无论何时,都要使用自己的软件。

7. 如何创造财富

如果你想致富,应该怎么做?我认为最好的办法就是自己创业,或者加入创业公司。从经济学观点看,你可以把创业想象成为一个压缩过程,你的所有工作年份被压缩成了短短几年。你不再是低强度的工作40年,而是以及高强度工作4年。在高科技领域,这种压缩的回报尤其丰厚,工作效率越高,额外报酬就越高。

那些大公司的执行官看到创业公司员工的生产率是本公司员工的20或30倍,自然很想知道怎样才能让自己的手下也这样拼命工作。答案很简单,付钱就行了。许多大公司的内部,平均主义泛滥。如果采用自由市场制度那样的机制,你的公司就可以变成一个很有效率的地方。这里的假设是,如果每个员工按照他创造的财富获得报酬,那么整个公司的利润将最大化。

财富才是你的目标,金钱不是。但是如果财富真的那么重要,为什么大家都把挣钱挂在嘴边呢?部分原因是,金钱是财富的一种简便的表达方式:金钱有点像流动的财富,两者往往可以互相转换。但是,他们确实不是同样的东西,除非你打算伪造货币,否则使用“挣钱”这个词会不利于你理解如何才能挣钱。

我只是借此表达我的观点,就是说如果你想创造财富,那么你应该抱着特别怀疑的态度,去思考那些着眼于你自己感兴趣的东西的商业计划。对于自己感兴趣的东西,你会觉得他们很有价值,但是他们恰恰最不可能与他人眼中有价值的东西发生重合。

谈到财富总额的时候,财富经常被形容为一个大饼。政治家说:“你无法把饼做得更大。“小时候我就对这点深信不疑:如果富人拿走了所有的钱,那么其他人就变得更穷了。许多成年人至今都是类似的看法的信徒。如果你打算创业,那么不管你是否意识到了,你都是在着手推翻这个大饼谬论(如果带着这个大饼理论创业的话,你将充满愧疚感)。在大多数情况下,世界上可供交换的财富并不是一个恒定不变的量。人类历史上的财富一直在不断地增长和毁灭(总体上看是净增长)。比如你拥有一辆老爷车,你可以不去管它,在家中悠闲度日,也可以自己动手把他修葺一新。这样做的话,你就创造了财富。注意,金钱不是财富,而只是我们用来转移财富所有权的东西。

一个大学毕业生总是想”我要找一份工作“,别人也是这么对他说的,好像变成某个组织的成员是一件多么重要的事情。更加直接的表达方式应该是”你需要去做一些人们需要的东西“。即使不加入公司,你也能做到。公司不过是一群人在一起工作,共同做出人们需要的东西。真正重要的是做出人们需要的东西,而不是加入某个公司。对于大多数人来说,最好的选择可能是为某个现存的公司打工。但是理解这种行为的真正含义对你没有任何坏处。工作就是在一个组织中,与许多人共同合作,做出某种人们需要的东西。

大公司会使得每个员工的贡献平均化,这是一个问题。我觉得大公司的最大困扰就是无法准确测量每个员工的贡献。大多数时候它只是瞎猜。在大公司中,你只要一般性地努力工作,就能得到意料之中的薪水。你不能明显无能或者是懒散,但是谁也没觉得你会把全部精力投入工作。但是,现实是你在工作中投入的精力越多,就越能产生规模效应。真正的问题实际上在于公司无法测量你的贡献。你想更努力地工作,但是你的工作与其他许多人的工作混杂在一起,这样就产生了问题。在大公司中,个人的表现无法单独测量,公司里其他人会拖累你。

要致富,你需要两样东西:可测量性和可放大性(你做出的决定能够产生巨大的效应)。单单具备可测量性是不够的,比如血汗工厂的工人报酬就是按照计件机制计算的,这是一个只有可测量性,没有可放大性的例子。就算你无法测量每个员工的贡献,但是你可以得到近似值,那就是测量小团队的贡献。整家公司产生的收入是可测量的,如果公司只有一个员工,那么就可以准确知道他的贡献了。所以公司越小,你就越能准确估计每个人的贡献。创业公司通过发明新技术盈利,所以具备可放大性。

选择公司要解决什么问题应该以问题的难度作为指引,而且此后的各种决策都应该以此为原则。Viaweb的一个经验法则就是“更上一层楼”。在实际操作中,这就意味着我们故意选择那些很困难的技术问题。假定软件有两个候选的新功能,他们创造的商业价值完全相同,那么我们总是选择较困难的哪个功能。不是因为这个功能能带来更多的收入,而是因为它比较难。我们很乐于迫使那些又大又慢的竞争对手跟着我们一起走进沼泽地。创业公司就像游击队一样,喜欢选择不易生存的深山老林作为根据地,政府的正规军无法追到那种地方。

创业是有一些潜规则的,其中一条就是很多事情由不得你。比如,你无法决定到底付出多少。你只想更勤奋工作2到3倍,从而得到相应的回报。但是,真正创业以后,你的竞争对手决定了你到底有多辛苦,而他们做出的决定都是一样的:你能吃多少苦,我们就能吃多少苦。另一条潜规则是创业的付出与回报,虽然总体上是成比例的,但是在个体上是不成比例的。我在前面说过,对于个人来说,付出与回报之间存在很随机的放大因子,你努力30倍,最后得到的回报在现实中并不是30倍,而是0~1000倍之间的一个随机数。假定所有创业者,都努力30倍,最后他们得到的总体平均回报是30倍,但中位数却是0。此外,创业公司不像能经受打击的黑熊,也不像有盔甲保护的螃蟹,而是像蚊子一样,不带有任何防御,就是为了达到一个目的而活着。蚊子唯一的防御就是,作为一个物种,他们的数量极多,但是作为个体,却极难生存。

那么怎样才能把公司卖掉呢?基本上不管是否想出售公司,你要做的事情都是一样的(比如多赚钱)但是,被收购本身就是一门学问,我们在Viaweb上花了很多时间研究它。潜在的买家会尽可能的拖延收购,收购这件事情最难的地方就是让买方真正拿出钱,大多数时候促成买方掏钱的最好办法,不是让买家看到有获利的可能,而是让他们感到失去机会的恐惧。对买家来说,最强的收购动机就是看到竞争对手可能收购你,我们发现这会使得CEO们连夜行动。次强的动机则是让他们担心,如果现在不买你,你的高速成长将使得未来的收购耗资巨大,甚至你本身可能变成他们的一个竞争对手。在这两种收购动机中,归根结底的因素都是用户数量。你以为买家在收货前会做很多研究,搞清楚你的公司到底值多少钱,其实根本不是这么回事儿。他们真正在意的只是你拥有的用户数量。事实上,买家假定用户知道谁有最好的技术。听上去很蠢,但是用户是你证明自己创造了财富的唯一证据,财富就是人们需要的东西,如果没有人使用你的软件,可能不是因为你的推广活动很失败,而是因为你没有做出人们想要的东西。风险投资商有一张清单,上面写满了各种表示不应该收购的危险信号。排在榜首的信号中有一个,就是公司由技术顽童掌控,只想解决有趣的技术问题,不考虑用户的需要。你开办创业公司不是单纯的为了解决问题,而是为了解决那些用户关心的问题。

你开办创业公司不是单纯地为了解决问题,而是为了解决那些用户关心的问题。所以,我认为你应该和买家一样,也把用户数量当做一个测试指标。像优化软件一样优化公司,用户数量就是判断公司表现好坏的指标。做过软件优化的人都知道,优化难点就是如何测试系统的表现。如果凭空猜测软件最慢的哪一部分以及怎样让它快起来,那估计百分百会猜错。你必须时刻牢记的最基本的原则就是,创造人们需要的东西,也就是创造财富。如果你想通过创造财富使得自己致富,那么你必须知道人么需要什么。

8. 关注贫富分化

我认为有三个原因使得我们对赚钱另眼相看。第一,我们从小被误导对财富的看法;第二,历史上积累财富的方式大多名声不好;第三,担心收入差距拉大将对社会产生不利影响。(作者后面对于三点分别进行讨论了)。

由于孩子们接触到钱的方式就是这样,他们往往会误解财富,把财富与钱混为一谈。他们认为财富的总量是不变的,某个权威负责分配财富,没有意识到财富是创造出来的。此外,他们认为,勤奋工作本身就是值得的,如果勤奋工作却没有得到很多报酬就会感到不公平。但是在现实中,财富使用工作成果衡量的,而不是用它花费的成本衡量的。

巴尔扎克说过:”每一笔巨大财富的背后,都隐藏着罪行。“这句话被广泛引用,但是他其实说的是另一个意思,如果巨大财富没有明显来源的话,那可能就是来源于精心安排的犯罪活动。巴尔扎克很清楚,你不用偷窃也可以发财。起码他自己就是这样做的,他写出很受欢迎的小说,从而赚到了钱。

技术无法使其变得更便宜的唯一东西,就是品牌。这正是为什么我们现在越来越多的听到品牌的原因。富人与穷人之间生活差异的鸿沟正在缩小,品牌是这种差距的遗留物。但是,品牌只是商品的标签,即使买不起名牌,至少你还可以买普通牌子,这总比根本无法消费这一种商品要好得多。1900年,只要你有一辆马车你就是富人,根本没人问你买车的牌子,没有马车的人就是穷人,只能挤公共交通或者步行。今天即使最穷的美国人也有自己的汽车,那么厂商只好通过广告训练我们识别品牌,以便我们能够识别哪些汽车特别昂贵。

我想提出一种相反的观点:现代社会的收入差距扩大是一种健康的信号。技术使得生产率的差异加速扩大,如果这种扩大没有反映在收入上面,只有三种可能的解释:1.技术革新停顿了。2.那些创造大部分财富的人停止工作了。3.创造财富的人没有获得报酬。一个社会需要有富人,这主要不是因为你需要富人的支出创造就业机会,而是因为它们在致富过程做出的事情。我在这里谈的不是财富从富人流向穷人的那种扩散效应(trickle-down effect),也不是说如果你让亨利福特致富,他就会在下一场宴会雇用你当服务员,而是说如果你让他致富,他就会造出一台拖拉机,使你不再需要使用马匹耕田了。

9. 设计者的品味

好设计是简单设计。这样强调简单似乎有点奇怪。有人会说,简单就是事物本来的样子,装饰反而意味着更多的工作。但是当人们自己从事创造性工作的时候,好像就会忘了保持简单这个原则。当你被迫把东西做得很简单时,你就被迫直接面对真正的问题。当你不能用表面的装饰交差时,你就不得不做好真正本质的部分。

好设计是永不过时的设计。以永不过时作为目标是一种帮助自己找到最佳答案的方法:如果你不愿别人的答案取代你的答案,你就只好自己做出最佳答案。以永不过时作为目标也是一种避开时代风潮的影响的方法。如果一件东西长盛不衰,那么它的吸引力一定来自本身的魅力,而不是来自风潮的影响。说来奇怪,如果你自己希望自己的作品对未来的人们有吸引力,方法之一就是让你的作品对上几代有吸引力。我们很难猜测未来是什么样子,但是可以肯定,未来的人们不会在乎今天流行的风潮。所以,如果你的作品对今天的人们以及1500年的人都有吸引力,那么它极有可能也会吸引2500年的人。

好的设计是启发性的设计。在建筑学和设计学中,这条原则意味着,一幢建筑或一个物品应该允许你按自己的愿望来使用。举例来说,一幢好的建筑物应该可以充当平台,让你想怎么布置就可以怎么布置,过上自己想过的家庭生活,而不是使得你像执行程序一样,只能过上建筑师为你安排的生活。在软件业中,这条原则意味着,你应该为用户提供一些基本模块,使得他们可以随心所欲自由组合,就像玩乐高积木那样。在数学中这条原则意味着,一个可以成为许多新工作基础的证明,要优于一个难度很高,但无助于未来学科发展的证明。科学领域中,总体上可以把引用次数看作他人启发性大小的粗略指标。

好设计通常是有点趣味性的设计。好的设计并非一定要有趣,但是很难想象完全无趣的设计会是好的设计。我想,这是因为幽默一定程度上反映了力量。幽默感是强壮的一种表现,始终拥有幽默感就代表你对厄运一笑了之,而丧失幽默感则表示你被厄运深深伤到。

好设计是艰苦的设计。困难的问题需要艰巨的付出才能解决,高难度的数学证明需要结构非常精细的解决方法(它们往往做起来很有趣),工程学也是如此。并非所有的痛苦都是有益的。世界上有有益的痛苦,也有无益的痛苦。你需要的是咬牙向前冲刺的痛苦,而不是脚被钉子扎破的痛苦。解决难题的痛苦对设计是有好处,但是对付挑剔的客户的痛苦或者对付质量低劣的建材的痛苦就是另外一回事了。在绘画上,肖像画通常占据最高地位。这不是偶然的,原因不仅是面部肖像比其他题材更能打动人,还因为我们太擅长观察脸,所以肖像画家不得不加倍努力,才能达到我们的要求。如果画的是树,树枝画偏了5度,也不会有人发现。但是,如果你把别人的眼睛画偏了5度,人们一眼就能看出来。

德国包豪斯(Bauhaus)学派的设计师采纳了美国建筑师路易斯沙利文(Louis Sullivan)的观点“功能决定形式”(form follows function),但是他们实际上的理解是“功能应当决定形式”。真实情况是,如果开发“功能”非常艰难,那么“形式”将不得不全部由“功能”决定,因为没有多余的精力再来单独开发“形式”了。人们常常觉得野生动物非常优美,原因就是他们的生活非常艰苦,在外形上不可能有多余的部分了。

好设计是看似容易的设计。科学和工程学的一些最重大的发现在形式上往往很简单,会使得你觉得自己也想到过。可是,如果它真的那么简单,为什么发现人不是你呢?在大多数领域,看上去很容易的事情,背后都需要大量的练习。练习的作用也许是训练你把刻意为之的事情变成一种自觉的行为。人们有时会说自己有了“状态”,我的理解是,他们这时可以控制自己的脊髓。脊髓是更本能的反应,面对难题时,它能释放你的直觉。

好设计是对称的设计。对称也许只是简洁性的一种表现,但是它十分重要,值得单独列出一点。自然界的对称大量存在,这就说明了对称的重要性。对称的危险在于它也可以用来取代思考,在大量使用重复的时候这种危险性更大。

好设计是模仿大自然的设计。我不是说模仿着大自然这种行为本身有多么好,而是说大自然在长期的演化基本解决了很多设计问题。所以如果你的设计与大自然很解决,那么它基本上不会很差。

好设计是一种再设计。很少有人一次就把事情做对。专家的做法是先完成一个早期原型,然后提出修改计划,最后把早期原型扔掉。扔掉早期原型是需要信心的,你必须有本事看出什么地方还可以改进。犯错误是很正常的事情,你不要把犯错看成灾难,要勇于承认,勇于改正。达芬奇实际上重新发明了素描这种艺术形式,把它当作一种探索更多可能的方式。开源软件因为公开承认自己会有bug,反而使得代码的bug比较少。

好设计是能够复制的设计。我们对待复制的态度经常是一个否定之否定的过程。刚入门的新手不知不觉地模仿他人,逐渐熟练之后才开始创作原创性作品。最后他会意识到,把事情作对比原创更重要。我想,最伟大的大师最终会达到一种超脱自我的境界。他们一心想找到正确答案,如果别人已经回答出了一部分,那就没理由不拿来用。他们足够自信地使用他人的成果,完全不用担心因此丧失个人的特点。

好设计常常是奇特的设计。前文提到的好设计的大多数特点都是可以培育出来的,但是我觉得“奇特”这个特点是无法培育的。你最多就是在它开始显现是不要把它扼杀掉。

好设计是成批出现的。推动人才成批涌现的最大因素就是,让有天赋的人聚在一起,共同解决某个难题。互相激励比天赋更加重要。达芬奇之所以成为达芬奇,主要原因不仅仅是他的天赋,更重要的是他生活在当时的佛罗伦萨,而不是米兰。在历史的任何时刻都有一些热点项目,一些团体在这些项目上做出伟大的成绩。如果你远离这些中心,几乎不可能单靠自己就取得伟大成就。某种程度上,你个人最多可以对趋势产生一定的影响,但是你不可能决定趋势,实际上是趋势决定了你。

好设计常常是大胆的设计。今天的实验性错误就是明天的新理论。如果你想做出伟大的新成果,那就不能对常识与真理不相吻合之处视而不见,反而应该特别注意才对。实际上,我觉得发现丑陋的东西比你想象出在一个优美的东西更容易。大多数人做出优美的成果的人好像只是为了修正他们眼中丑陋的东西。伟大的成果的出现常常来源于某人看到一样东西湖,心想我能做得比这更好。单单是无法容忍丑陋东西还不够,只有对这个领域非常熟悉,你才可能发现哪些地方可以动手改进。你必须锻炼自己。只有在成为某个领域的专家之后,你才会听到心里有一个细微的声音说:“这样解决太糟糕了!一定有更好的选择。”不要忽视这种声音,要培育它们。优秀作品的秘诀就是:非常严格的品味,在加上实现这种品味的能力。

10. 编程语言解析

那么应该使用哪一种语言?嗯,关于这个问题,现在有很多争论。部分原因是,如果你长期使用某种语言,你就会按照这种语言的思维模式进行思考。所以,后来当你遇到其他任何一种有重大差异的语言,即使那种语言本身没有任何不对的地方,你也会觉得他极其难用。缺乏经验的程序员对于各种语言优缺点的判断常常被这种心态误导。

可能因为想炫耀自己见多识广,某些黑客会告诉你所有高级语言基本相似。“所有编程语言我都用过。”某个看上去饱经风霜又酷的黑客往酒吧里一坐,“你用什么语言并不重要,重要的是你对问题是否有正确的理解。代码以外的东西才是关键。”这当然是一派胡言。各种语言简直天差地别。比如Fortran I和最新版的Perl就是两种完全不同的语言,而早期版的Perl和最新版的Perl之间的差别也大得惊人。但是,那个夸夸其谈的黑客可能真的相信自己的这番话,的确有可能使用所有不同的语言写出了与原始的Pascal语言写的差不多的程序。如果你吃过麦当劳,就会知道全世界各地的麦当劳的味道都几乎一样。

如果高层级语言比汇编语言更有利于编程,你也许会认为语言的层次越高越好。一般情况下确实如此,但不是绝对的。编程语言可以变得很抽象,完全脱离硬件,但也有可能走错了方向。比如,我觉得Prolog语言就有这个问题。它的抽象能力强得不可思议,但是只能用来解决2%的问题,其余时间你苦思冥想,运用这些抽象能力写出来的程序实际上就是Pascal语言的程序。

另一个你会用到低层次语言的原因就是效率问题。如果你非常关注运行速度,那么最好使用接近机器的语言。大多数操作系统都是用C语言编写的,这并非偶然。不过,硬件的运行速度越来越快了,所以使用C这样的低层次语言开发应用程序的必要性正在不断减少,但是大家似乎还是要求操作系统越快越好。

11. 一百年后的编程语言

这只是我的猜测,未必正确.这里的重点不是看衰Java,而是提出编程语言存在一个进化的脉络,从而引导读者思考,在整个进化过程中,某一种语言的位置到底在哪里?之所以要问这个问题,不是为了1000年后让后人感叹,我们曾经如此英明,而是为了找到进化的主干。它会启发我们去选择那些靠近主干的语言,这样对当前的编程最有利。

任何一种编程语言都可以分为两大组成部分,基本运算符的集合(扮演公理)的角色,以及除运算符以外的其他部分(原则上,这个部分可以用基本运算符表达出来)。我认为,基本运算符是一种语言能否长期存在的最重要因素。其他因素都不是决定性的。这有点像买房子的时候你应该先考虑地理位置。别的地方将来出问题都有办法弥补,但是地理位置是没法变的。慎重选择公理还不够,还必须控制它的规模,数学家总觉得公理越少越好,我觉得他们说到了点子上。你仔细审视一种语言的内核,考虑哪些部分可以被摒弃,这至少也是一种很有用的训练。在长期的职业生涯中,我发现冗余的代码会导致更多冗余的代码,不仅软件如此,而且像我这样性格懒散的人,我发现在床底下和房间角落里这个命题也成立,一件垃圾会产生更多的垃圾。我的判断是,那些内核最小最干净的编程语言,才会存在于进化的主干上。一种语言的内核设计的越小,越干净,它的生命力就越顽强。

我已经预测了,一旦未来硬件的性能大幅提高将会发生什么事。新增加的运算能力都会被糟蹋掉。但是浪费可以分为好的浪费和坏的浪费。我感兴趣的是好的浪费,即用更多的钱得到更简单的设计。所以问题就变成了如何才能充分利用新硬件更强大的性能最有利地“浪费”他们。对于速度的追求是人类内心深处根深蒂固的欲望。当你看着计算机这个小玩意儿,就会不由自主的希望程序运行的越快越好,真的要下一番功夫才能把这种欲望克制住。设计编程语言的时候,我们应该有意识地问自己,什么时候可以放弃一些性能,换来一点点便利性的提高。

Lisp语言的黑客很早就明白数据结构灵活性的价值。我们写程序的第一版时,往往会把所有事情都用列表的形式处理。所以,这些最初版本可能效率低下得惊人,你必须努力克制自己才能忍住不手动优化它们,这就好像吃牛排的时候必须努力克制自己才能不去想牛排是从哪里来的一样,至少对我来说是这样的。一百年后的程序员最需要的编程语言就是可以让你毫不费力地写出程序第一版的编程语言,哪怕它的效率低下得惊人(至少按我们今天的眼光来看是如此)。他们会说,他们想要的就是很容易上手的编程语言。效率低下的软件并不等于很烂的软件。一种让程序员做无用功的语言才真正称得上烂。浪费程序员的时间而不是浪费机器的时间才是真正的无效率。随着计算机速度越来越快,这会变得越来越明显。

另一种消耗硬件性能的方法就是,在应用软件和硬件之间设置很多的软件层。这也是我们已经看到的一种趋势,许多新兴的语言就被编译成字节码。比尔伍兹曾经对我说,根据经验判断,每增加一个解释层,软件的运行速度就会慢一个数量级。但是,多余的软件层可以让编程灵活起来。即便是应用程序,使用多层形式开发也是一种很强大的技巧。自下而上的编程方法意味着要把软件分成好几层,每一层都可以充当它上面那一层的开发语言。这种方法往往会产生更小更灵活的程序,它也是通往软件圣杯-可重用性(reusability)-的最佳路线。从定义上看,语言就是可以重用的。在编程语言的帮助下,你的应用程序越是采用这种多层形式开发,它的可重用性就越好。

顺便说一句,我不认为面向对象编程将来会消亡。我觉得,除了某些特定的领域,这种编程方法其实没有为优秀程序员带来很多好处,但是它对大公司有不可抗拒的吸引力。面向对象编程使得你有办法面对面条式代码进行可持续性开发。通过不断地打补丁,它让你将对软件一步步做大。大公司总是倾向于采用这样的方式开发软件。我预计一百年后也是如此。

设计新语言的方法之一就是直接写下你想写的程序,不管编译器是否存在,也不管有没有支持它的硬件。这就是假设存在无限的资源供你支配。不管是今天还是一百年后,这样的假设好像都是有道理的。你应该写什么程序?随便什么,只要能让你最省力地写出来就行。但是要注意,这必须是在你的思维没有被当前使用的编程语言影响的情况下。这种影响无处不在,必须很努力才能克服。你也许觉得,对于人类这样的懒惰的生物,喜欢用最省力的方式写程序是再自然不过的事情了。但是事实上,我们的思想往往可能会受限于某种现存的语言,只采用在这种语言看来更简单的形式,它对我们思想的束缚作用会大得令人震惊。新语言必须靠你自己去发现,不能依靠那些让你自然而然就沉下去的思维定势。

当你设计编程语言的时候,心里牢牢记住这个目标是有好处的。学习开车的时候,一个需要记住的原则就是要把车开直,不是通过将车身对其画在地上的分隔线,而是通过瞄准远处的某个点。即使你的目标只在几米开外,这样做也是正确的。我认为,设计编程语言时,我们也应该这样做。

12. 拒绝平庸

大公司可以互相模仿,但是创业公司就不行。我觉得很多人没有意识到这一点,尤其是一些创业者。大公司每年平均成长大约10%.所以,如果你掌管一家大公司,只要每件事都做到大公司的平均水准,你就能得到大公司的平均结果,也就是每年成长大约10%.如果你掌管创业公司,当然也可以这样。你把每件事都做到平均水平,就能得到平均结果。问题在于,小公司的平均结果就意味着关门倒闭。创业公司的生存率远低于50%.所以,如果你掌管创业公司,最好做一些独特的事情,否则就会有麻烦。

Lisp没有得到广泛使用的原因就是因为编程语言不仅仅是技术,也是一种习惯性思维,非常难于改变。我先从一个争议极大的命题开始讲起:编程语言的编程能力有差异。Perl4如何?与Perl5相比,它不支持闭包。所以,大多数Perl的黑客都认为Perl5比Perl4强大。如果你同意这一点,就意味着你也认为一种高级语言可以比另一种高级语言强大。因此,必然能够接着推导出,除了某些特殊情况,你就是应该使用目前最强大的语言。

如果从图灵等价(Turing-Equivalent)的角度来看,所有语言都是一样强大的,但是这对于程序员没有意义。(没有人想为图灵机编程。)程序员关心的那种强大也许很难正式定义,但是有一个办法可以解释,那就是有一些功能在语言是内置的,但是在另外一种语言中需要修改解释器才能够做到,那么前者就比后者更强大。

唯一洞悉所有语言优势的人必然是懂得最强大的那种语言的人(这大概就是Eric Raymod所说的Lisp语言使你成为一个更好的程序员的意思。)由于Blub困境的存在,你无法信任其他人的意见:他们都满足于自己碰巧用熟了的那种语言,他们的编程思想都被那种语言主宰了。

如果你为创业公司公告做,那么这里有一个评估竞争对手的妙招-关注他们的招聘职位。他们网站上的其他内容无非是一些陈腐的照片和夸夸其谈的文字,但是招聘职位却不得不写得很明确,反映出他们到底想干什么,否则就会引来一大批不合适的求职者。

13. 书呆子的复仇

当你按照Java, Perl, Python,Ruby这样的顺序观察这些语言,你会发现一个有趣的结果。至少,如果你是一个Lisp黑客,你就看得出来,排在越后面的语言越像Lisp. Python语言模仿Lisp,甚至把许多Lisp的黑客认为属于设计错误的功能也一起模仿了。至于Ruby语言,如果回到1975年,你声称它是一种有着自己句法的Lisp方言,没有人会提出反对意见。编程语言现在的发展不过刚刚赶上1958年Lisp语言的水平。

让我告诉你原因。这是因为设计者本来没打算把Lisp设计成编程语言,至少不是我们现在意义上的编程语言。我们今天所说的编程语言,指的是用来告诉计算机怎么做的一种工具。麦卡锡最后确实有意开发这种意义上的编程语言,但是实际上它做出来的Lisp却是完全不同的一种东西,语言的基础是它的一种演算理论,他想用简洁的方式定义图灵机。正如他后来所说:

Lisp比图灵机表达起来更简洁,证明这一点的一种方法就是写一个类似的通用函数,证明他比图灵机的一般性描述更短,更易懂。这个类似的函数就是eval,它用来计算力所表达式的值。

编写eval函数需要发明一种表示法,能够把Lisp的函数表示成Lisp数据。设计这种书写法完全是为了满足论文写作的需要,(我)根本没有想过用它来编写Lisp程序并在计算机上运行。

由此也就得出了20世纪50年代的编程语言,到现在还没有过时的原因。简单说,因为这种语言本质上不是一种技术,而是数学。数学是不会过时的。你不应该把历史和语言与50年代的硬件联系在一起,而是应该把它与快速排序算法进行类比。这种排序是1960年提出的,至今仍然是最快的通用排序方法。

Fortran语言也是20世纪50年代出现的,并且一直使用至今。它代表了语言设计的一种完全不同的方向。Lisp语言是无意中从纯理论发展为编程语言的,而Fortran从一开始就是作为编程语言设计出来的。但是今天我们把Lisp看成高级语言,而把Fortran看成一种相当低层次的语言。Lisp和Fortran代表了编程语言发展的两大方向。前者的基础是数学,后者的基础是硬件架构。从那时起,这两大方向一直在互相靠拢。Lisp语言刚设计出来的时候就很强大,接下来的20年它提高了运行速度,而那些所谓的主流语言把更快的运行速度作为设计的出发点,然后再用40多年的时间一步步变得更强大。直到今天,最高级的主流语言也只是刚刚接近Lisp的水平。虽然已经很接近了,但还是没有Lisp那样强大。

Lisp语言的9种新思想:

  1. 条件结构
  2. 函数对象(闭包)
  3. 递归
  4. 动态类型变量
  5. 垃圾回收机制
  6. 程序由表达式组成
  7. 符号类型
  8. 代码使用符号和常量组成的树形表示法
  9. 不区分读取期-编译期-运行期

关于9书里面是这么解释的。无论什么时候,整个语言都是可用的,Lisp并不真正区分读取期编译期和运行期。你可以在读取期编译或运行代码,也可以在编译期读取或运行代码,还可以在运行期读取或编译代码。在读取及运行代码,使得用户可以重新调整Lisp的语法;在编译器运行代码,则是Lisp宏的工作基础;在运行期编译代码,使得Lisp可以在Emacs这样的程序中充当扩展语言。在运行期读取代码,使得程序之间可以使用S表达式通信。

你不能让那些衣冠楚楚,西装革履的家伙替你做技术决策。潜在的并购方有没有对我们使用Lisp语言感到很难受呢?稍微有一点吧,但是如果我们不使用Lisp,我们就根本写不出现在的软件,也就不会有人想收购我们。他们眼中不正常的事情恰恰就是使得这一切发生的原因所在。如果你创业的话,千万不要为了取悦风险投资商或潜在并购方而设计你的产品,让用户感到满意才是你的设计方向。只要赢得用户,其他事情就会接踵而来。如果没有用户,谁会关心你选择的“正统”技术是多么令人放心。

强大的编程语言如何让你写出更短的程序?一个技巧就是,在语言允许的前提下使用自下而上(bottom-up)的编程方法。你不是用基础语言开发应用程序,而是在基础语言之上先构件一种你自己的语言,然后再用后者开发应用程序。这样写出来的代码会比直接用基础语言开发出来的短的多。实际上大多数压缩算法也是这样运作的。自下而上的编程往往也便于修改,因为许多时候你自己添加的中间层根本不需要变化,你只需要修改前端逻辑就可以了。

由于选择了不当的编程语言而导致项目失败的可能性,是你的经理不愿意考虑的问题。事实上大部分的经理都这样。因为你知道,总的来说,你的经理其实不关心公司是否真的能获得成功,他真正关心的是不承担决策失败的责任。所以对他个人来说,最安全的做法就是跟随大多数人的选择。在大型组织内部,有一个专门的属于描述这种跟随大多数人的选择的做法,叫做“业界最佳实践”。这个词出现的原因其实就是为了让你的经理可以推卸责任。既然我选择的是“业界最佳实践”,如果不成功,项目失败了,那么你也无法指责我,因为做出选择的人不是我,而是整个“业界”。我认为这个词原来是指某种会计方法,大致意思就是不要采用很奇怪的处理方法。在会计方法中,这可能是一个好主意。“尖端”和“核算”这两个次听上去就不适合放在一起。但是如果你把这个标准引入技术决策,你就要开始出错了。技术本来就应该尖端的。正如伊拉恩加内特所说,编程语言的所谓“业界最佳实践”,实际上不会让你变成最佳,只会让你变得很平常。

如果你想解决一个困难的问题,关键不是你使用的语言是否强大,而是好几个因素同时发挥作用:(a)使用一种强大的编程语言; (b)为这个难题写一个事实上的解释器; 或者(c)你自己变成这个难题的人肉编译器。这种实践不仅很普遍,而且已经制度化了。举例来说,在那些面向对象编程的世界中,我们听到“模式”(pattern)这个词,我觉得那些“模式”就是现实中的因素(c)也就是人肉编译器。当我在自己的程序中发现用到了模式,我觉得这就表明某个地方出错了。程序的形式应该仅仅反映它所要解决的问题。代码中其他任何外加的形式都是一个信号,(至少对我来说)表明我对问题的抽象还不够深,也经常提醒我,自己正在手工完成的事情,本应该写代码通过宏的扩展自动实现。

14. 梦寐以求的编程语言

黑客的看法其实比语言设计者的更重要。编程语言不是数学定理,而是一种工具,为了便于使用,它们才被设计出来。所以,设计编程语言的时候必须考虑到人类的长处和短处,就像设计鞋子的时候必须符合人类的脚型。如果鞋子穿上去不舒服,无论它的外形多么优美,多么像一件艺术品,你也只能把它当做一双坏鞋。大多数程序员也许无法分辨语言的好坏。但是,这不代表优秀的编程语言会被埋没,专家级黑客一眼就能认出他们,并且会拿来使用。虽然他们人数很少,但就是这样一小群人写出了人类所有优秀软件。他们有着巨大的影响力,他们使用什么语言,其他程序员往往就会跟着使用。老实说,很多时候这种影响力更像是一种命令,对于其他程序员来说,专家级黑客就像自己的老板或导师,他们说哪种语言好用,自己就会乖乖的跟进。

简洁性最重要的方面就是要使得语言更抽象。为了达到这一点,首先你设计的必须是高级语言,然后把它设计的越抽象越好。语言设计者应该总是看着代码,问自己能不能使用更少的语法单位把它表达出来。如果你有办法让许多不同的程序都能更简短地表达出来,那么这很可能意味着你发现了一种很有用的新抽象方法。

一种真正优秀的编程语言应该既整洁有混乱。“整洁”的意思是设计得很清楚,内核由数量不多的运算符构成,这些运算符易于理解,每一个都有很完整的独立用途。“混乱”的意思是它允许黑客以自己的方式使用。C语言就是这样的例子,早期的Lisp语言也是如此。真正的黑客语言总是稍微带一点放纵不羁、不服管教的个性。

为了吸引黑客,一种语言必须善于完成黑客想要完成的各种任务。这意味着它必须很适合开发一次性程序。这一点可能出乎很多人的意料。我有一种预感,最优秀的那些大型程序就是这样发展起来的,而不是像胡佛水坝那样从一开始就作为大型工程来设计。一下子从无到有做出一个大型项目是件很恐怖的事情,当人们接受一个巨型项目是很容易被他搞得一蹶不振。最后要么是线项目陷入僵局,要么是做出来一个规模小性能差的东西。你想造一片闹市,却只做出一家商场;你想建一个罗马,却只造出一个巴西利亚;你想发明C语言,却只开发出Ada。开发大型程序的另外一种方法就是从一次性程序开始,然后不断地改进。这种方法比较不会让人望而生畏,程序在不断的开发之中逐渐进步。一般来说,使用这种方法开发程序,一开始用什么编程语言,就会一直用到最后,也因为除非有外部政治因素的干预,程序员很少会中途更换编程语言。所以,我们就有了一个看似矛盾的结论:如果你想设计一种适合开发大型程序的编程语言,就必须是的这种语言也适合开发一次性程序,因为大型项目就是从一次性程序演变而来的。

人们在使用非常高级的语言(比如Lisp)时,经常抱怨很难知道哪个部分对性能的影响比较大。可能确实如此,如果你使用一种非常抽象的语言,这也许是无法避免的。不管怎么样,我认为一个好的性能分析器会解决这个问题,虽然这方面还有很长的路要走,但是未来你可以快速知道程序每个部分的时间开销。但是语言设计者喜欢提高编译器速度,认为这是对自己技术水平的考验,而最多只把性能分析器当做一个附送给使用者的赠品。但是在现实中,一个好的性能分析器对程序的帮助可以大于编译器的作用。

发明新事物的人必须有耐心,要常年常年累月不断地做市场推广,直到人们开始接受这种发明。不过,好消息是,简单重复同一个信息局能解决这个问题。你只需要不停地重复同一句话,最终人们将会开始倾听。人们开始注意到你的时候,不是第一眼看到你站在这里,而是发现过来这么久你居然还在这里。

一般来说,车库里的创业者会嫉妒大爆炸式的创业公司,后者的主导人物个个光彩照人,自信非凡,深受风险资本商的追捧。他们什么都买得起,在公关公司配合产品推出的宣传活动中,他们自己也附带成为成为了明星人物。自然成长式的创业者坐在自家车库里,觉得自己又穷又可怜。但是我想他们不必难过,最终来看,自然成长式会比大爆炸式产生更好的技术,能为创始人带来更多的财富。如果你研究一下目前的主流技术,就会发现大部分都是源于自然成长式。这种模式不仅存在于商业公司,还存在于科研活动中。Multics操作系统和Ada语言是大爆炸式项目,现在都已经销声匿迹了,而他们的继承者Unix和C语言则是自然成长式项目。

用户是一把双刃剑。他们推动语言的发展,但也使得你不敢对语言进行大规模改造。所以,一开始的时候要精心选择用户,避免使用者过快增长。发展用户就像一种优化过程,明智的做法就是放慢速度。一般情况下用户比较少,意味着你任何时候都可以加大修改的力度。这时对语言规则做出改变就像是绷带,当你感到痛苦的一瞬间痛苦就成为回忆。如果用户数量庞大,修改语言带来的痛苦就将持续很长时间。大家都知道,让一个委员会负责设计语言是非常糟糕的主意。委员会只会做出恶劣的设计。但是我觉得委员会最大的问题在于它们妨碍了再设计(redesign)。在委员会的主持下修改语言是件麻烦的事情,没有人愿意自讨苦吃。而且即使大多数成员不喜欢某种做法,委员会最后的决定往往还是维持现状。就算委员会只有两个人,还是会妨碍再设计,典型例子就是软件内部的各个接口由不同的人负责。这时除非两个人都同意改变接口,否则接口就无法改变。因此现实中,尽管软件功能越来越强大,内部接口却往往一成不变,成为整个系统拖后腿的部分。

让我们试着描述黑客心目中梦寐以求的语言来为以上内容做一个小节。

  1. 这种语言干净简练,具有最高层次的抽象和互动性,而且很容易装备,可以只用很少的代码就解决常见的问题。不管是什么程序,你真正要写的代码几乎都与你自己的特定设置有关,其他具有普遍性的问题都有现成的函数库可以调用。
  2. 这种语言的句法短到令人生疑。你输入的命令中,没有任何一个字母是多余的,甚至用到Shift键的机会也很少。
  3. 这种语言的抽象程度很高,使得你可以快速写出一个程序原型。然后,等到你开始优化的时候,它还提供一个真正出色的性能分析器,告诉你应该重点关注什么地方。你能让多重循环快得难以置信,并且在需要的地方还能直接嵌入字节码。
  4. 这种语言有大量优秀的范例可供学习,而且非常符合直觉,你只需要花几分钟阅读范例就能领会到应该如何使用此种语言。你偶尔才需要查阅操作手册,它本身很薄,里面关于限定条件和例外情况的警告寥寥无几。
  5. 这种语言而内核很小,但很强大。各个函数库高度独立,而且和内核一样经过精心设计,它们都能很好地协同工作。语言的每个部分就想精密照相机的各种零件一样完美契合,不需要为了兼容性问题放弃或者保留某些功能。所有函数库的源码都很容易得到。这种语言能够很轻松地与操作系统和用其他语言开发的应用程序对话。
  6. 这种语言以层的方式构建。较高的抽象层透明底构建在较低的抽象层之上。如果需要的话,你可以直接使用较低的抽象层。
  7. 这种语言的所有细节对使用者都是透明的,除了一些绝对必要隐藏的东西。它提供的抽象能力只是为了方便你的开发,而不是为了强迫你按照它的方式行事。事实上,它鼓励你参与它的设计,给你提供与语言创造者平等的权力。你能够对它的任何部分加以改变,甚至包括它的语法。它尽可能让你自己定义的部分与它本身定义的部分处于同等地位。这种梦幻般的编程语言不仅开放源码,更开放自身的设计。

15. 设计与研究

设计与研究最大的不同在于你会更多地考虑用户。设计的时候,一开始总是问:我为谁设计?他们需要什么?优秀的建筑师不会先设计,然后强迫用户接受,而是先研究最终用户需求,然后最初用户需要的设计。注意,我说的是“用户需要的设计”,而不是“用户要求的设计”。让用户满意并不等于迎合用户的一切要求。用户不了解所有可能的选择,也经常弄错自己真正想要的东西。大多数优秀设计都是这样产生的,它们关注用户,并且以用户为中心。

我说设计必须考虑用户的需求,这里的“用户”并不是指所有普罗大众。事实上,你可以选择任何想要的目标用户。如果目标用户群体涵盖了设计师本人,那么最有可能诞生优秀设计。如果目标用户与你本人差别很大,你往往会假定目标用户的需求比你本人的需求更简单,而不是更复杂。但是低估用户(即使出于善意)一般来说总是会让设计师出错。如果你觉得自己在为傻子设计产品,那么很可能不仅无法设计出优秀产品,而且就连傻瓜也不喜欢你的设计。

怎样理解编程语言?你不要把它看成那些已经完成的程序的表达方式,而应该把它理解成促成程序从无到有的一种媒介。所以,评价一种语言的优劣不能简单地看最后的程序是否表达得很漂亮,而要看程序从无到有的那条完成路径是否很漂亮。(我觉得作者这句话说得非常好,而且也能看得出作者非常了解程序和计算机对于人类的作用。)

怎样理解编程语言?你不要把它看成那些已经完成的程序的表达方式,而应该把它理解成促成程序从无到有的一种媒介。这里的意思是说,成品的材料和开发时使用的材料其实是不一样的。搞艺术的人都知道,这两个阶段往往需要不同的媒介,比如大理石是一种非常良好耐用的材料,很适合用于最后的成品。但是它极其缺乏弹性和灵活性,所以不适合在构思阶段用来做模型。

最后写出来的程序就像已经完成了数学证明一样,是一颗经过精心修剪的树木,上面杂乱滋生的树杈都已经被剪去。所以评价一种语言的优劣不能简单的看最后的程序是否表达得漂亮,还要看程序从无到有的那条完成路径是否漂亮。某种设计使得最后的程序非常漂亮,但是不一定同时具有具备漂亮的编程过程。比如,我写过一些宏,他们的作用是自动生成另一些宏,他们看上去非常精美优雅,就像一粒粒精细的宝石。但是,开发过程非常丑陋,我就是连续好几个小时不停的试错,而且老实说,至今仍然无法确定他们是否100%正确。

我们常常采用错误的方法评价编程语言,只看一眼最后完成的程序就作出判断。同一个软件由两种不同语言开发的版本,你发现其中一个版本比另一个版本短得多,于是非常自信的认为前者的编程语言比后者更好。但是,如果你从艺术创作的角度思考这个问题,就不太可能这样评价编程语言了。因为你不想最后只剩下一种像大理石那样漂亮,又像大理石那样难用的编程语言。

在软件领域,贴近用户的设计思想被归纳为“弱即是强”(Worse is Better)模式。这个模式实际上包含了几种不同的思想,所以至今人们还在争论它是否真的成立。但是,其中有一点是正确的,那就是如果你正在设计某种新东西,就应该尽快拿出原型,听取用户的意见。先做出原型,再逐步加工做成成品,这种方式有利于鼓舞士气,因为它使得你随时都可以看到工作的成就。士气是设计的关键因素。令我吃惊的是,大家很少提到这一点。我的一位美术启蒙老师告诉我:如果你觉得画某样东西很乏味,那么你画出来的东西就真的很乏味。

16. 旅途终点

每章都是作者一篇散文,视角独特,涉及的方面也非常广泛。从在学校的书呆子为什么不收欢迎,到书呆子走出学校如何致富以及如何创业,关注社会问题比如贫富分化以及强调黑客的本质,最后也谈到了计算机编程方面包括编程语言和设计。很多问题因为自己经历过所以没有发言权说是否正确,但是作者的话却给予我们相当多的启示。这些启示或许对于自己以后在人生发展道路选择,或者是对于计算机编程和设计方面权衡和决定,都应该会有非常大的作用。书后面说这本书”将迫使你重新思考计算机编程的本质“,我觉得这本书的目的达到了。当我把书中的一些段落摘抄完之后,感觉作者已经成功地按照他的逻辑指引带我重新思考了一次计算机编程的本质。谢谢Paul Graham以及《黑客与画家》的译者阮一峰。