Be a real hacker, 真正的软件设计

明白这一点对软件设计有重大影响。它意味着,编程语言首要的特性应该是允许动态扩展(malleable)。编程语言是用来帮助思考程序的,而不是用来表达你已经想好的程序。它应该是一支铅笔,而不是一支钢笔。

我们需要的是一种可以随意涂抹、擦擦改改的语言.

一般情况下,只有动态语言有这个特点, 所谓的动静态, 有一个最本质的特点,是不是允许修改后,可以马上起作用。这才是真正的关键,而不是所谓有强类型, 真正的区别是不是需要长时间编译出来,运行才可以看到效果。 运态语言,是可以马上看到效果的。 也有些语言即使编译出来也可以很快看到效果,go是也。 加上调试器的应用,写代码完全是没有压力, 语法层面再也不是问题,可以一股脑地把程序写出来, 依据调试反溃再一步一步地修正。 调试器的使用, 让这一切成为了可能。非函数式的编程语言,是通过内存数据的不断变换来实现计算和罗辑的, 所以可以看到程序的运行状态,是很重要的。

阅读别人的代码, 看懂所有的代码,再把他们拼起来运行, 这是我以前的思维方式。 这是我以前的思维方式,也是效能非常低下,而且思维成本很高的。 通过这种方式去阅读别人的代码是很痛苦的,如果别人的代码写得很烂,那真是地狱啊。 做treasurer,基本上里面所有的代码,我都是有记忆的, 快做完这个项目时, 精神上被压得不行不行了。 其实,那是一种错误的思维方式, 应该从机器的角度去思考,而不是做一个人肉编译器。 现在还是以这种方式做软件,被压得不行不行。 正确的方式,是从机器的角度去考虑, 通过机器的思维,去阅读程序,而不是一块一块的函数理解后,再从用人肉编译器,把它们编译出来,这样代码量上来后, 人的思维压力也在无限地增大, 如果是用机器的思维去理解, 再结合所有功能, 再扩展到代码层面,这样,就可以很快地理解了所有的代码块。 我一直呆在drupal里面, 其实,里面的功能代码基本己经写好了,我做的无非是使用它开放出来的元,来进行应用的订制。 一旦我切换到其他的方式写代码的时,很多功能需要自己写出来, 那时的压力就会突然增加,一直增加到思维的满负荷,直到崩溃。后面就应该好了, 学会正确的对待代码, 有机器做辅助编译器,只要专注于关键的部分就可以了。 再也不用做人肉编译器了。

现在阅读别人的代码,也是流流畅的。现在的web应用,其实都是比较简单, 无非是一些持久化的数据结构, 有一些业务, 再加上各种流程和验证。 这些流程本来就不多,通过机器辅助对它们进行编译, 很快就可以把他们给搞定了。 所以可以很快地对第三方系统进行验证,快速成为expert. 对别人的系统都是信手拈来。真是棒棒的!!!

web还是rails, 快速。

现在一般企业招的都是人肉编译器, php人肉编译器, python人肉编译器, c人肉编译器, C++人肉编译器等。


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

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

举例来说,我在大学受到的教育是,在上机编程之前,应该先在纸上把程序搞清楚。可我自己一直不是这样编程的,我喜欢直接坐在计算机前编程,而不是在纸上编程。更糟的是,我不是耐心地一步步写出整个程序,确保大体上是正确的,而是一股脑不管对错,先把代码堆上去,再慢慢修改。书上说,调试(debugging)是最后的步骤,用来纠正打字的错误和疏忽。可是我的工作方法看上去却像编程就是在调试。

很长一段时间内我都为此事沮丧,就像小学里老师教我怎么拿铅笔,我却总是学不会的那种感觉。如果我那时看到其他创作领域,比如绘画或者建筑,我就会想到,自己的方法其实有一个正式的名称:打草稿。我现在认为,大学里教给我的编程方法都是错的。你把整个程序想清楚的时间点,应该是在编写代码的同时,而不是在编写代码之前,这与作家、画家和建筑师的做法完全一样。

明白这一点对软件设计有重大影响。它意味着,编程语言首要的特性应该是允许动态扩展(malleable)。编程语言是用来帮助思考程序的,而不是用来表达你已经想好的程序。它应该是一支铅笔,而不是一支钢笔。如果大家都像学校教的那样编程,那么静态类型(static typing)是一个不错的概念。但是,我认识的黑客,没有一个人喜欢用静态类型语言编程。我们需要的是一种可以随意涂抹、擦擦改改的语言,我们不想正襟危坐,把一个盛满各种变量类型的茶杯,小心翼翼放在自己的膝盖上,为了与一丝不苟的编译器大婶交谈,努力地挑选词语,确保变量类型匹配,好让自己显得礼貌又周到。

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

一页写满了数学公式的纸真是令人印象深刻啊。(小窍门:用希腊字母表示变量名会令人印象更深刻。)因此,你就受到巨大的诱惑,去解决那些能够用数学公式处理的问题,而不是去解决真正重要的问题。

如果黑客认识到自己与其他创作者——比如作家和画家——是一类人,这种诱惑对他就不起作用。作家和画家没有“对数学的妒忌”,他们认为自己在从事与数学完全不相关的事情。我认为,黑客也是如此。


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

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

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

所以,如果你的竞争优势是在软件设计方面,并且你的对手是一家大公司,它大到由一群产品经理来设计软件,那么你的对手将永远无法赶上你。不过说实话,这样的机会不容易找到。你很难单单依靠软件设计就与大公司展开竞争。这就好比你很难攻入城堡与对手面对面地徒手搏斗。比如,就算写一个比微软的Word更好的文字处理软件不是难事,但是微软公司有自己的城堡,它的操作系统是垄断的,你根本无法对它构成威胁,它甚至都不会注意到你的存在。

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


所以,开发优秀软件的方法之一就是自己创业。但是,这样做会遇到两个问题。一个是自己开公司的话,必须处理许许多多与开发软件完全无关的事情。我创立Viaweb的时候,如果有四分之一时间可以用于开发,就感到很幸运了。我在其他四分之三时间所做的事情,从单调乏味到惊悚恐怖,无所不包。我来说一个比较,有一次董事会开到一半,我不得不离开去补牙。我记得坐在牙医诊所的椅子上,等着医生开动牙钻的那段时间,与刚才待在公司的时间相比,简直感觉像是在度假一样。

创业的另一个问题是赚钱的软件往往不是好玩的软件,两者的重叠度不高。 所有创作者都面临这个问题。价格是由供给和需求共同决定的。好玩的软件的需求量,比不上解决客户麻烦问题的软件的需求量。在小剧场里演出的酬劳,比不上穿着卡通大猩猩服装、在展览会上为厂商站台的酬劳。写小说的回报比不上写广告文案的回报。开发编程语言的收入,比不上把某些公司老掉牙的数据库连上服务器的收入。

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

几乎所有的创作者在职业生涯的早期都有一份“白天工作”。画家和作家尤其显著。如果幸运的话,你能找到一份与你的“真正工作”非常相关的“白天工作”。音乐家似乎常常是在唱片行工作。同样地,钻研某种编程语言或操作系统的黑客,很可能会得到一份使用这些工具的“白天工作”。

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


如果黑客只是一个负责实现领导意志的技术工人,职责就是根据规格说明书写出代码,那么他其实与一个挖水沟的工人是一样的,从这头挖到那头,仅此而已。但是,如果黑客是一个创作者,他从事的就不是机械性的工作,他必须具备灵感。 黑客就像画家,工作起来是有心理周期的。有时候,你有了一个令人兴奋的新项目,你会愿意为它一天工作16个小时。等过了这一阵,你又会觉得百无聊赖,对所有事情都提不起兴趣。

黑客就像画家,工作起来是有心理周期的。有时候,你有了一个令人兴奋的新项目,你会愿意为它一天工作16个小时。等过了这一阵,你又会觉得百无聊赖,对所有事情都提不起兴趣。

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

对于编程,这实际上意味着你可以把bug留到以后解决。消灭bug对我来说属于轻松的工作,只有在这个时候,编程才变得直接和机械,接近社会大众想象中的编程的样子。消灭bug的过程就像解一道数学题,已知许许多多的约束条件,你只要根据条件对方程求解就可以了。你的程序应该能产生x结果,但是却产生了y结果。哪里出错了?你知道自己最后肯定能解决这个问题,所以做起来就很轻松,就好像刷墙一样,接近于休闲了。


当多个画家共同创作一幅作品时,每个人画的部分都是不一样的。通常来说,大师负责画主要人物,助手们负责画次要人物和背景。但是,你肯定找不到某个部分是两个人一起画的。

我认为,这也是多人共同开发一个软件的正确模式。需要合作,但是不要“合”得过头。如果一个代码块由三四个人共同开发,就没有人真正“拥有”这块代码。最终,它就会变得像一个公用杂物间,没人管理,又脏又乱,到处堆满了冗余代码。正确的合作方法是将项目分割成严格定义的模块,每一个模块由一个人明确负责。模块与模块之间的接口经过精心设计,如果可能的话,最好把文档说明写得像编程语言规范那样清晰。