黑客与画家(Hackers and Painters)

Table of Contents

1

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

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

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

2 黑客伦理

  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).

3 术语解析

Blub困境(Bulb Paradox):程序员的思想往往会受到自己正在使用的语言的束缚,不相信存在更强大的语言。

格林斯潘第十定律(Greenspun’s Tenth Rule):任何C或Fortran程序复杂到一定程度之后,都会包含一个临时开发的,只有一半功能的,不完全符合规范,到处都是bug的,运行速度很慢的Common Lisp实现。

“奥卡姆剃刀”原则(Occam’s Razzor):简单的解释就是较好的解释。

帕金森定律(Parkinson’s Law):完成一项任务所需要的资源会不断扩展,直到把这种资源消耗光为止。

4 为什么书呆子不受欢迎

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

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

5 黑客与画家

优美的软件并不总是论文的合适题材。首先,科学研究必须具有原创性。写过博士论文的人都知道,确保自己在开垦新领地的方法,就是去找那些没有人要土地。其次,科学研究必须是能够产生大量成果的,而那些不成熟的,障碍重重的领域最容易写出许多篇论文,因为你可以写那些为了完成工作、你不得不克服的障碍。但是创造优美的东西往往不是从头做起,而是在现有成果的基础上做一些小小的调整,或者将已有的观点用比较新的方式组合起来。这种类型的工作很难用研究性的论文表达出来。

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

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

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

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

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

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

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

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

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

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

6 不能说的话

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

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

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

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

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

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

7 良好的坏习惯

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

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

8 另一条路

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

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

由于互联网软件的程序员非常辛苦,所以会使得经济优势根本性地从大公司向创业公司转移。互联网公司软件要求的那种工作强度和付出,只有当公司是其本人所有时,程序员才愿意提供。软件公司可以雇到能干的人,让他们去感轻松的事情,也可以雇到不能干的人,让他们去干艰苦的事情,但是无法雇到非常能干的人,让他们去干非常艰苦的事情。因为互联网软件的创业不需要太多的资本,所以大公司可以与创业公司竞争的优势就所剩无几了。

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

9 如何创造财富

如果你想致富,应该怎么做?我认为最好的办法就是自己创业,或者加入创业公司。从经济学观点看,你可以把创业想象成为一个压缩过程,你的所有工作年份被压缩成了短短几年。

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

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

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

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

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

创业是有一些潜规则的,其中一条就是很多事情由不得你。比如,你无法决定到底付出多少。你只想更勤奋工作2到3倍,从而得到相应的回报。但是,真正创业以后,你的竞争对手决定了你到底有多辛苦,而他们做出的决定都是一样的:你能吃多少苦,我们就能吃多少苦。此外,创业公司不像能经受打击的黑熊,也不像有盔甲保护的螃蟹,而是像蚊子一样,不带有任何防御,就是为了达到一个目的而活着。蚊子唯一的防御就是,作为一个物种,他们的数量极多,但是作为个体,却极难生存。

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

10 关注贫富分化

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

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

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

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

11 设计者的品味

  • 好设计是简单设计。这样强调简单似乎有点奇怪。有人会说,简单就是事物本来的样子,装饰反而意味着更多的工作。但是当人们自己从事创造性工作的时候,好像就会忘了保持简单这个原则。当你被迫把东西做得很简单时,你就被迫直接面对真正的问题。当你不能用表面的装饰交差时,你就不得不做好真正本质的部分。
  • 好设计是永不过时的设计。以永不过时作为目标是一种帮助自己找到最佳答案的方法:如果你不愿别人的答案取代你的答案,你就只好自己做出最佳答案。以永不过时作为目标也是一种避开时代风潮的影响的方法。如果一件东西长盛不衰,那么它的吸引力一定来自本身的魅力,而不是来自风潮的影响。说来奇怪,如果你自己希望自己的作品对未来的人们有吸引力,方法之一就是让你的作品对上几代有吸引力。我们很难猜测未来是什么样子,但是可以肯定,未来的人们不会在乎今天流行的风潮。
  • 好的设计是启发性的设计。在软件业中,这条原则意味着,你应该为用户提供一些基本模块,使得他们可以随心所欲自由组合,就像玩乐高积木那样。
  • 好设计通常是有点趣味性的设计。好的设计并非一定要有趣,但是很难想象完全无趣的设计会是好的设计。
  • 好设计是艰苦的设计。困难的问题需要艰巨的付出才能解决,高难度的数学证明需要结构非常精细的解决方法(它们往往做起来很有趣),工程学也是如此。并非所有的痛苦都是有益的。世界上有有益的痛苦,也有无益的痛苦。你需要的是咬牙向前冲刺的痛苦,而不是脚被钉子扎破的痛苦。解决难题的痛苦对设计是有好处,但是对付挑剔的客户的痛苦或者对付质量低劣的建材的痛苦就是另外一回事了。
  • 好设计是看似容易的设计。科学和工程学的一些最重大的发现在形式上往往很简单,会使得你觉得自己也想到过。可是,如果它真的那么简单,为什么发现人不是你呢?在大多数领域,看上去很容易的事情,背后都需要大量的练习。练习的作用也许是训练你把刻意为之的事情变成一种自觉的行为。人们有时会说自己有了“状态”,我的理解是,他们这时可以控制自己的脊髓。脊髓是更本能的反应,面对难题时,它能释放你的直觉。
  • 好设计是对称的设计。对称也许只是简洁性的一种表现,但是它十分重要,值得单独列出一点。自然界的对称大量存在,这就说明了对称的重要性。对称的危险在于它也可以用来取代思考,在大量使用重复的时候这种危险性更大。
  • 好设计是模仿大自然的设计。我不是说模仿着大自然这种行为本身有多么好,而是说大自然在长期的烟花基本解决了很多设计问题。所以如果你的设计与大自然很解决,那么它基本上不会很差。
  • 好设计是一种再设计。很少有人一次就把事情做对。专家的做法是先完成一个早期原型,然后提出修改计划,最后把早期原型扔掉。扔掉早期原型是需要信心的,你必须有本事看出什么地方还可以改进。
  • 好设计是能够复制的设计。我们对待复制的态度经常是一个否定之否定的过程。刚入门的新手不知不觉地模仿他人,逐渐熟练之后才开始创作原创性作品。最后他会意识到,把事情作对比原创更重要。我想,最伟大的大师最终会达到一种超脱自我的境界。他们一心想找到正确答案,如果别人已经回答出了一部分,那就没理由不拿来用。他们足够自信地使用他人的成果,完全不用担心因此丧失个人的特点。
  • 好设计常常是奇特的设计。前文提到的好设计的大多数特点都是可以培育出来的,但是我觉得“奇特”这个特点是无法培育的。你最多就是在它开始显现是不要把它扼杀掉。
  • 好设计是成批出现的。推动人才成批涌现的最大因素就是,让有天赋的人聚在一起,共同解决某个难题。互相激励比天赋更加重要。达芬奇之所以成为达芬奇,主要原因不仅仅是他的天赋,更重要的是他生活在当时的佛罗伦萨,而不是米兰。在历史的任何时刻都有一些热点项目,一些团体在这些项目上做出伟大的成绩。如果你远离这些中心,几乎不可能单靠自己就取得伟大成就。某种程度上,你个人最多可以对趋势产生一定的影响,但是你不可能决定趋势,实际上是趋势决定了你。
  • 好设计常常是大胆的设计。今天的实验性错误就是明天的新理论。如果你想做出伟大的新成果,那就不能对常识与真理不相吻合之处视而不见,反而应该特别注意才对。实际上,我觉得发现丑陋的东西比你想象出在一个优美的东西更容易。大多数人做出优美的成果的人好像只是为了修正他们眼中丑陋的东西。伟大的成果的出现常常来源于某人看到一样东西湖,心想我能做得比这更好。单单是无法容忍丑陋东西还不够,只有对这个领域非常熟悉,你才可能发现哪些地方可以动手改进。你必须锻炼自己。只有在成为某个领域的专家之后,你才会听到心里有一个细微的声音说:“这样解决太糟糕了!一定有更好的选择。”不要忽视这种声音,要培育它们。优秀作品的秘诀就是:非常严格的品味,在加上实现这种品味的能力。

12 编程语言解析

可能因为想炫耀自己见多识广,某些黑客会告诉你所有高级语言基本相似。“所有编程语言我都用过。”某个看上去饱经风霜又酷的黑客往酒吧里一坐,“你用什么语言并不重要,重要的是你对问题是否有正确的理解。代码以外的东西才是关键。”这当然是一派胡言。各种语言简直天差地别。

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

13 一百年后的编程语言

我认为,基本运算符是一种语言能否长期存在的最重要因素。其他因素都不是决定性的。这有点像买房子的时候你应该先考虑地理位置。别的地方将来出问题都有办法弥补,但是地理位置是没法变的。

我已经预测了,一旦未来硬件的性能大幅提高将会发生什么事。新增加的运算能力都会被糟蹋掉。但是浪费可以分为好的浪费和坏的浪费。我感兴趣的是好的浪费,即用更多的钱得到更简单的设计。所以问题就变成了如何才能充分利用新硬件更强大的性能最有利地“浪费”他们。

Lisp语言的黑客很早就明白数据结构灵活性的价值。我们写程序的第一版时,往往会把所有事情都用列表的形式处理。所以,这些最初版本可能效率低下得惊人,你必须努力克制自己才能忍住不手动优化它们,这就好像吃牛排的时候必须努力克制自己才能不去想牛排是从哪里来的一样,至少对我来说是这样的。

一百年后的程序员最需要的编程语言就是可以让你毫不费力地写出程序第一版的编程语言,哪怕它的效率低下得惊人(至少按我们今天的眼光来看是如此)。他们会说,他们想要的就是很容易上手的编程语言。效率低下的软件并不等于很烂的软件。一种让程序员做无用功的语言才真正称得上烂。浪费程序员的时间而不是浪费机器的时间才是真正的无效率。随着计算机速度越来越快,这会变得越来越明显。

另一种消耗硬件性能的方法就是,在应用软件和硬件之间设置很多的软件层。这也是我们已经看到的一种趋势,许多新兴的语言就被编译成字节码。比尔伍兹曾经对我说,根据经验判断,每增加一个解释层,软件的运行速度就会慢一个数量级。但是,多余的软件层可以让编程灵活起来。

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

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

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

14 拒绝平庸

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

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

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

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

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

15 书呆子的复仇

你不能让那些衣冠楚楚,西装革履的家伙替你做技术决策。潜在的并购方有没有对我们使用Lisp语言感到很难受呢?稍微有一点吧,但是如果我们不使用Lisp,我们就根本写不出现在的软件,也就不会有人想收购我们。他们眼中不正常的事情恰恰就是使得这一切发生的原因所在。

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

16 梦寐以求的编程语言

黑客的看法其实比语言设计者的更重要。编程语言不是数学定理,而是一种工具,为了便于使用,它们才被设计出来。所以,设计编程语言的时候必须考虑到人类的长处和短处,就像设计鞋子的时候必须符合人类的脚型。如果鞋子穿上去不舒服,无论它的外形多么优美,多么像一件艺术品,你也只能把它当做一双坏鞋。

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

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

开发大型程序的另外一种方法就是从一次性程序开始,然后不断地改进。这种方法比较不会让人望而生畏,程序在不断的开发之中逐渐进步。一般来说,使用这种方法开发程序,一开始用什么编程语言,就会一直用到最后,也因为除非有外部政治因素的干预,程序员很少会中途更换编程语言。所以,我们就有了一个看似矛盾的结论:如果你想设计一种适合开发大型程序的编程语言,就必须是的这种语言也适合开发一次性程序,因为大型项目就是从一次性程序演变而来的。

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

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

用户是一把双刃剑。他们推动语言的发展,但也使得你不敢对语言进行大规模改造。所以,一开始的时候要精心选择用户,避免使用者过快增长。发展用户就像一种优化过程,明智的做法就是放慢速度。

17 梦寐以求的编程语言总结

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

这种语言干净简练,具有最高层次的抽象和互动性,而且很容易装备,可以只用很少的代码就解决常见的问题。不管是什么程序,你真正要写的代码几乎都与你自己的特定设置有关,其他具有普遍性的问题都有现成的函数库可以调用。

这种语言的句法短到令人生疑。你输入的命令中,没有任何一个字母是多余的,甚至用到Shift键的机会也很少。

这种语言的抽象程度很高,使得你可以快速写出一个程序原型。然后,等到你开始优化的时候,它还提供一个真正出色的性能分析器,告诉你应该重点关注什么地方。你能让多重循环快得难以置信,并且在需要的地方还能直接嵌入字节码。

这种语言有大量优秀的范例可供学习,而且非常符合直觉,你只需要花几分钟阅读范例就能领会到应该如何使用此种语言。你偶尔才需要查阅操作手册,它本身很薄,里面关于限定条件和例外情况的警告寥寥无几。

这种语言而内核很小,但很强大。各个函数库高度独立,而且和内核一样经过精心设计,它们都能很好地协同工作。语言的每个部分就想精密照相机的各种零件一样完美契合,不需要为了兼容性问题放弃或者保留某些功能。所有函数库的源码都很容易得到。这种语言能够很轻松地与操作系统和用其他语言开发的应用程序对话。

这种语言以层的方式构建。较高的抽象层透明底构建在较低的抽象层之上。如果需要的话,你可以直接使用较低的抽象层。

这种语言的所有细节对使用者都是透明的,除了一些绝对必要隐藏的东西。它提供的抽象能力只是为了方便你的开发,而不是为了强迫你按照它的方式行事。事实上,它鼓励你参与它的设计,给你提供与语言创造者平等的权力。你能够对它的任何部分加以改变,甚至包括它的语法。它尽可能让你自己定义的部分与它本身定义的部分处于同等地位。这种梦幻般的编程语言不仅开放源码,更开放自身的设计。

18 设计与研究

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

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

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

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

19 自己感想

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

—END

comments powered by Disqus