书名:黑客与画家(10万册纪念版)
作者:保罗·格雷厄姆
译者:阮一峰
一、概要
《黑客与画家》是互联网从业者的必读书之一。这是一本讲黑客(优秀程序员)的书,可以从三个维度去看这本书:第一是“黑客精神”和“创造者思维”;第二是“财富创造”;第三是“开拓未来”。本书通俗易懂,虽然此书已经出版了很多年了,但其中思想至今还还很流行甚至超前,强烈建议程序员或IT相关人员阅读。
二、关于作者
有“创业教父”之称的哈佛大学计算机博士保罗·格雷厄姆。
保罗·格雷厄姆和罗伯特·莫里斯(是一个非常聪明的黑客,曾经在1988年编写了历史上第一个蠕虫病毒——莫里斯蠕虫。)开发了Viaweb产品,这是第一个通过互联网使用的软件。1998年被雅虎收购,并改名为Yahoo Store。
作者保罗·格雷厄姆最大的成就是创立了YC,它既是一个创业公司的孵化器,也是一个教导员,还是一个与投资人联系的中介。YC是全球唯一一个可以实现规模化的创业加速器。YC来源于Lisp语言的Y Combinator,这是一个编程术语,意思是创造其他函数的函数。YC在每年的1月和6月举办两次训练营,每次为期3个月。他们从中挑出20个项目。每个项目将得到1.1万美元的启动资金,外加每个项目成员3 000美元的生活津贴,交换条件是YC将拿走该项目5%的股份5。如果项目成功,5%的股份将非常值钱。
三、摘记
◆ 赞誉
>> 《黑客与画家》是互联网从业者的必读书之一。十几年前作者关于未来、关于创业、关于专业技术领域的很多前瞻性观点都已成真。现在读,依然能获得思考问题的方向和思路。
——姬十三 果壳创始人、CEO
◆ 推荐序 “黑客精神”过时了吗?答案是永远不会
>> 在保罗的观念里,以及在YC和奇绩创坛的实践观察中,我们发现,黑客精神的真谛是动手去创造性地解决问题。
>> 只有通过好的设计,技术才能源源不断地满足需求。
◆ 保罗·格雷厄姆其人其事
>> 保罗·格雷厄姆有一套完整的创业哲学,他的创业公式是:
(1)搭建原型;
(2)上线运营(别管bug);
(3)收集反馈;
(4)调整产品;
(5)成长壮大。
>> 他认为一定要特别关注用户需要什么,这样才有办法将一个坏项目转变成好项目。
>> “许多伟大的公司,一开始的时候做的都是与后来业务完全不同的事情。
>> “Make something people want”(制造用户需要的东西)
>> 小团队更容易成功,创始人总数最好不要超过三个。其中一个原因是,创始人越多,股权越不容易平等分配,容易造成内耗。
>> “以前创业很昂贵,你不得不找到投资人才能创业。而现在,唯一的门槛就是勇气。”
◆ 精装版译者序 向着未来而生
>> 德国哲学家马丁·海德格尔(Martin Heidegger)说过一句著名的话:人应该“向死而生”。意思是人面对死亡,才会停止那些无谓琐碎的关注和困扰,体会到什么是重要的事情,从而达到真正的存在。
>> 我觉得格雷厄姆的哲学是“向着未来而生”
>> 如果这种预测是正确的,就意味着未来20年里,政府的力量将缩小,个人和小团体将崛起,成为推动社会前进的主要力量。
>> 只要把握大趋势,技术就会把个人送到难以想象的高度。
>> 你要做的就是“活在未来,然后造出现在还没有的部分”(Live in the future, then build what's missing)。
◆ 平装版译者序
>> hack的本义是“砍(木头)”
>> hacker,也就是黑客。
>> “出于兴趣而解决某个难题,不管它有没有用,这就是黑客。”
>> 根据理查德·斯托曼的说法,黑客行为必须包含三个特点:好玩、高智商、探索精神。只有其行为同时满足这三个标准,才能被称为“黑客”。另外,它们也构成了黑客的价值观,黑客追求的就是这三种价值,而不是实用性或金钱。
>> “黑客伦理”的一个必然推论就是,黑客不服从管教,具有叛逆精神。
>> 真正的黑客致力于改变世界,让世界运转得更好。
>> 在本书中,“黑客”就是指最优秀的程序员,而不是入侵计算机系统的人。
◆ 前言
>> 没有一个编程语言的设计者会相信“不同的语言各有千秋”这种文绉绉的客套话。
◆ 第一部分 黑客如何成长及看待世界
◆ 1 为什么书呆子不受欢迎
>> “书呆子”的目标具有两重性。他们毫无疑问想让自己受欢迎,但是他们更愿意让自己聪明。
>> 文艺复兴时期的代表人物阿尔伯蒂有一句名言:“任何一种艺术,不管是否重要,如果你想要在该领域出类拔萃,就必须全身心投入。”
>>“受欢迎”的英语单词是popular,这个词还有另一个意思,即“大众化的,多数人的”,
>> 事实上,大多数“会画”的人,本身就很喜欢画画,将许多时间投入其中,这就是他们擅长画画的原因。
>> 书呆子被教导追求正确答案,而受欢迎的小孩被教导要讨人喜欢。
>> 在一个人产生良知之前,折磨就是一种娱乐。
>> 没有什么比一个共同的敌人更能使得人们团结起来了。
>> 你在其他地方有所得,就会在这个地方有所失。
>> 不过,成年人很清楚不用在乎别人怎么想
>> 就像任何一场战争,胜利方也是要付出代价的。
>> 青少年都不喜欢孤独一人
◆ 2 黑客与画家
>> 黑客与画家的共同之处,在于他们都是创作者。与作曲家、建筑师和作家一样,黑客和画家都试图创作出优秀的作品。他们本质上都不是在做研究,虽然在创作过程中,他们可能会发现一些新技术(那样当然更好)。
>> 建筑学和工程学之间的界限并不是很分明,但就是存在区别。这表现在“做什么”和“怎么做”:建筑师决定做什么,工程师想出怎么做。
>> 在英语中,“建筑师”(architect)和“架构师”(architect)是同一个词,所以这里用的是双关语,意思是优秀程序员不仅负责建造,还负责架构。
>> 当然,“做什么”和“怎么做”不应该分得太开。如果你决定做一件事,却不知道怎么做,你就是在自找麻烦。
>> 创造优美事物的方式往往不是从头做起,而是在现有成果的基础上做一些小小的调整,或者将已有的观点用比较新的方式组合起来。这种类型的工作很难用研究性的论文表达。
>> 黑客搞懂“计算理论”(theory of computation)的必要性,与画家搞懂颜料化学成分的必要性差不多大。
>> 你需要知道如何计算“时间复杂度”和“空间复杂度”(time and space complexity);如果你要写一个解析器,可能还需要知道状态机(state machine)的概念;除此以外,并不需要知道特别多的理论。
>> 你把整个程序想清楚的时间点,应该是在编写代码时,而不是在编写代码之前,这与作家、画家和建筑师的做法完全一样。
>> 编程语言首要的特性应该是允许动态扩展。
>> 静态类型是某些计算机语言的一个特性,指编译时对变量类型进行严格检查,典型代表是C、C++和Java。在这一类语言中,在声明变量时,必须指定类型,而且以后不能再改变。
>> 大学和实验室强迫黑客成为科学家,企业强迫黑客成为工程师。
>> 开发优秀软件的方法之一就是自己创业。
>> 事实上,微软的第一个产品就是一种编程语言
>> 如果你想赚钱,你可能不得不去干那些很麻烦很令人讨厌的事情,因为这些事情没人愿意义务来干。
>> 黑客如何才能做自己喜欢的事情?我认为这个问题的解决方法是一个几乎所有创作者都知道的方法:找一份养家糊口的“白天工作”(day job)。这个词是从音乐家身上来的,他们晚上表演音乐,所以白天可以找一份其他工作。更一般地说,“白天工作”的意思是,你有一份为了赚钱的工作,还有一份为了爱好的工作。
>> 我说黑客解决生计问题的方法是找一份“白天工作”,然后在其余时间开发优美的软件,不过我并没有说这是一个新方法。开源软件界的黑客早就这样做了。我想说的其实是,开源软件的这种工作模式可能就是正确的模式,因为它已经被其他领域的创作者验证过了。
>> 如此之多的一流黑客都在从事开源项目
>> 某幅作品如果有特别出色之处,你往往能够在更早的作品中发现一个小规模的初期版本
>> 也许对于黑客来说,采取像画家这样的做法很有好处:应该定期地从头开始,而不要长年累月地在一个项目上不断工作,并且试图把所有的最新想法都以修订版的形式包括进去。
>> 黑客就不一样,从一开始做的就是原创性工作,根本没有他人完美的成果可以依靠。
>> 黑客的出发点是原创,最终得到一个优美的结果;而科学家的出发点是别人优美的结果,最终得到原创性。
>> 绘画还有一个值得借鉴的地方:一幅画是逐步完成的。通常一开始是一张草图,然后再逐步填入细节。但是,它又不单纯是一个填入细节的过程。有时,原先的构想看来是错的,你就必须动手修改。无数古代油画放在X光下检视,就能看出修改痕迹,四肢的位置被移动过,或者脸部的表情经过了调整。
>> 眼下想必每个人都知道,过早优化是一件危险的事情。我认为,我们应该对“过早设计”也抱有同样的担忧,不要太早决定一个程序应该怎么做。
>> 坚持一丝不苟,就能取得优秀的成果,因为那些看不见的细节累加起来,就变得可见了。
>> 对于编程,这实际上意味着你可以把bug留到以后解决。
>> 正确的合作方法是将项目分割成严格定义的模块,每一个模块由一个人明确负责。模块与模块之间的接口经过精心设计,如果可能的话,最好把文档说明写得像编程语言规范那样清晰。
>> 了解别人对于事情的看法,并不代表你为他的利益服务。在某些情况下,比如在打仗的时候,了解对手正是为了打击对手12。
>> 举例来说,几乎所有最伟大的绘画作品都是画人的,因为人类总是对自身感兴趣。
>> 普通黑客与优秀黑客的所有区别之中,会不会“换位思考”可能是最重要的单个因素。
>> 判断一个人是否具备“换位思考”的能力有一个好方法,那就是看他怎样向没有技术背景的人解释技术问题。
>> 程序必须写得能够供人们阅读,偶尔供计算机执行。
◆ 3 不能说的话
不能说的话:
(1)真话,触怒他人的言论;
(2)时空差异:将当代观念与不同时期的古代观念diff一下,看下是否能说;
(3)道貌岸然:找那些一本正经的卫道者,看看他们到底在捍卫什么。
(4)机制:去观察禁忌是如何产生的。
观察不能说的话,有如下好处:
>> 优秀作品往往来自其他人忽视的想法,而最容易被忽视的想法就是那些被禁止的思想观点。
>> 一个好的科学家,并不仅仅是避开传统观点,还要努力打破传统观点。科学家就是要自找麻烦。
怎么做:
发现了不能说的话,最好守口如瓶,但心里无所不想。如果一定要你说,好的回答是“我还没想好”。
>> 你不要直接攻击某个标签,而要攻击它的“元标签”。所谓“元标签”,就是对某个标签的抽象描述。如果人们开始讨论元标签,那么原来的标签反而不会受到注意了。
永远质疑:
>> 如果自己就是潮水的一部分,怎么能看见潮流的方向呢?你只能永远保持质疑:什么话是我不能说的?为什么?
◆ 第二部分 黑客如何工作及影响世界
◆ 4 良好的坏习惯
>> 黑客是不服从管教的
>> 只有深入了解当前的技术,黑客才能构想下一代技术。
>> 1977年,IBM公司内部肯定有一些部门正在开发下一代计算机。他们没有料到的是,真正的下一代计算机不是诞生于IBM实验室,而是由两个与他们完全不相干的长头发年轻人在旧金山的一间车库里开发出来的。这两个年轻人,一个是史蒂夫·乔布斯,另一个是史蒂夫·沃兹尼亚克
>> 1977年,苹果公司推出的Apple II计算机是世界上第一台个人计算机。
>> 最新的版权法设置了前所未有的障碍,禁止外部人员了解专有技术的内部细节,从而也就禁止了外部人员经由这个途径获得新构想。
>> 如果我们不可以研究当前的技术,不能思考如何改进它,那么我们怎样才能开发出新技术呢?
>> 具有讽刺意味的是,这种局面正是黑客自己造成的。
>> 对于适当的不服从管教保持宽容,这不会有太大的坏处,反而很有利于造就美国的国家优势,它使得美国不仅能吸引聪明人,还能吸引那些很自负的人。黑客永远是自负的。
◆ 5 另一条路
>> 我们的软件Viaweb是最受欢迎的网上商店生成器,用户超过2万人。
◆◆ 下一个潮流?
>> 互联网软件运行在服务器上,用户界面就是网页。对于普通用户来说,这种新型软件将更容易、更便宜、更机动、更可靠,通常也比桌面软件更强大。
>> 所以,大多数时候,你不需要一台全功能的计算机(即本身可以运行软件的计算机),你所需要的设备只要有键盘、屏幕和浏览器就够了,可能还有无线网卡。
>> 有些公司生产轻量级的消费类电子产品,它们意识到“服务才赚钱”以后,往往就会把在线服务与硬件捆绑在一起卖。这个模式效果不好,第一个原因是,消费类电子产品和在线服务是两种类型的业务,需要两种不同的公司来做;第二个原因是,消费者不喜欢硬件和服务捆绑在一起收费。
◆◆ 用户的胜利
>> 互联网应用程序能够同时被多人使用,所以非常适合团队协作性的工作。
>> 安全问题的关键是不要有漏洞,而不是任何设计上的决策。
◆◆ 软件的发布
>> 常见的桌面软件可能一年发布一到两个新版本,而我们在Viaweb经常是一天发布三到五个版本。
>> 对于互联网软件来说,大部分的变化是细微和渐进的,所以引入bug的机会比较小。
>> 互联网软件的发布规则是:它运行不了,你就无法发布;一旦它能运行了,你就可以立刻发布。
>> “版本”这个概念不适用于互联网软件。
◆◆ 软件bug
>> 早一点发现bug就不容易形成复合式bug,也就是互相影响的两个bug。
>> 在软件中,复合式bug是最难发现的bug
>> 复合式bug有一个子类型:两个bug是互相弥补的,好比“负负得正”,软件反而能正常运行。这种bug可能才是最难发现的bug。当你修正了其中的一个bug,另一个bug才会暴露出来。这时你会觉得刚才修正错了,因为那是你最后修改的地方,你就怀疑自己在那里做错了,但是你其实是对的。
◆◆ 客户支持
>> Viaweb不是这样。我们的客户支持是免费的,因为我们希望知道用户的反应。如果他们使用时遇到困难,我们希望立刻知道,这样就能再现错误,从而解决问题并发布新版本。
>> 我们的政策是当场修复bug,这改变了客服人员与黑客之间的关系。
◆◆ 全身心投入
>> 构思这种东西有一个特点,那就是它会导致更多的构思。
>> 将一个构思束之高阁,不仅意味着延迟它的实现,还意味着延迟所有在实现过程中激发的构思。
>> 大公司的做法不是立刻实现新功能,而是先为新功能做一个计划。
>> 我们有改进的想法,但是如果我们想到应该怎么改进,就已经把它实现了。
◆◆ 逆向的《人月神话》
>> 当项目进度落后时,光靠增加人力到该项目中,并不会加快进度,反而有可能使进度更加延后。
◆◆ 关注用户
>> 基准测试(benchmark test)指的是先设置一个基本的数据环境,测试应用程序的表现,然后把这个表现当作“基准”(benchmark),用来比较其他情况下应用程序的表现。
◆◆ 金钱问题
>> 20世纪90年代早期,我读过一篇文章,它称应该让用户像订报纸那样按照使用时间长短订购软件的使用权。第一眼看上去,这种说法好像很滑稽,但是后来我意识到这个观点是对的,因为它反映了软件开发的现实:软件开发不是静态的,而是一个持续不断的动态过程。
>> 互联网软件是一个很理想的收入来源。你每个季度的销售额不是从零开始,而是拥有一个持续的现金流。因为互联网软件每时每刻都可以升级,所以你不用担心做错什么事。事实上,你不可能真的做错什么事,因为如果用户痛恨你对软件的修改,你马上就会知道。你也不会有坏账的烦恼,如果谁不付钱,你就停止对他的服务。此外,你也不可能遇到盗版问题。
>> 我觉得,软件公司明白这个道理,所以故意对某些盗版行为睁一只眼闭一只眼。
>> 由于互联网软件无法盗版,所以软件公司必须想出其他策略推广软件。
>> 软件公司有时会采用分销模式,让ISP分销互联网软件。这样做很不好。服务器必须在你自己的控制之中,因为你需要不断改进硬件和软件。如果你放弃对服务器的直接控制,就放弃了互联网软件的大部分优势。
◆◆ 目标客户
>> 不少公司很想知道,什么事情可以外包,什么事情不可以外包。一个可能的答案是,公司内部所有不直接感受到竞争压力的部门都应该外包出去,让它们暴露在竞争压力之下。
◆◆ 桌面电脑
>> 在那个时候,VisiCalc太先进了,人们为了能够使用这个软件,纷纷去购买苹果计算机。
>> 桌面电脑开始成为主流,因为许多创业公司为它写软件。
>> 现在,创业公司有更多的理由选择互联网软件创业,因为开发桌面软件越来越乏味了。如果你现在开发桌面软件,就不得不接受微软公司的授权条款,调用它的API,为它那个bug百出的操作系统伤透脑筋。历尽了千辛万苦,你最终写出了一个大受欢迎的软件,这时你可能会发现,你所做的一切其实只是在为微软公司做市场调查。
◆◆ 微软公司
>> 微软的成功就是利用了IBM的疏忽。
>> 优秀的开源浏览器最大的优点则是会推动HTTP和HTML继续向前发展
◆◆ 创业公司
>> 你必须打破常规、快速行动,循规蹈矩不可能成功。
>> 互联网软件永远没有收工的那一天,如果你愿意,可以一直干下去,每天忙上16个小时。
>> “帕金森定律”成为官僚主义的代名词,有一条就是“因为你必须做到,所以你能够做到”。
>> 本文作者称“因为你能够做到,所以你必须做到”是逆向的帕金森定律。
>> 桌面软件迫使用户变成系统管理员,互联网软件则迫使程序员变成系统管理员:用户的压力变小了,程序员的压力变大了。这未必是坏事。
◆◆ 勉强够用的网页
>> 有一件事可能会打消你通过互联网软件创业的念头,那就是网页作为用户界面,功能实在是太弱了。我承认,这确实是一个问题。我们真的想改造HTML语言和HTTP协议,对许多地方进行加强。不过必须指出,目前阶段的网页刚好能满足需要。
>> 对于相当一部分使用者来说,打开浏览器就能使用软件本身
>> 相比之下,互联网软件不需要做任何关于安装的假设,只要能上网的地方,它就能运行。
◆◆ 为什么不尝试一下
>> 首先,管理企业其实很简单,只要记住两点就可以了:做出用户喜欢的产品,保证开支小于收入。只要做到这两点,你就会超过大多数创业公司。随着事业的发展,你自己就能琢磨出来其他的诀窍。
>> 比较软件的标准应该是看对手的软件将来会有什么功能,而不是现在有什么功能。
>> 如果你不打算自己动手设计和开发,那就不要创业。
>> 微软公司的恐怖之处在于,它大到可以开发任何软件,就像一座能够行走的大山。
>> 不要被微软吓到。你能做到它做不到的事情,正如它能做到你做不到的事情一样。
◆ 6 如何创造财富
>> 如果你想致富,应该怎么做?我认为最好的办法就是自己创业,或者加入创业公司。
>> 创业公司其实就是解决了某个技术难题的小公司。
◆◆ 一个命题
>> 从经济学观点看,你可以把创业想象成一个压缩过程,你的所有工作年份被压缩成了短短几年。你不再是低强度地工作40年,而是以极限强度工作4年。在高技术领域,这种压缩的回报尤其丰厚,工作效率越高,额外报酬就越高。
>> 往往只有在创业公司里,你才能得到一种宝贵的工作环境,就叫作“不受干扰”。
>> 这里的假设是,如果每个员工按照他创造的财富获得报酬,那么整个公司的利润将最大化。
>> 我没有说放大因子不多不少正好是36,但肯定是大于10的,在个别情况下甚至高达100。
>> 这里有一个守恒定律:如果你想赚100万美元,就不得不忍受相当于100万美元的痛苦。
◆◆ 运气的成分
>> 但微软公司碰巧是历史上最大商业错误之一——DOS操作系统的授权协议——的受益者。
>> 如果IBM按照常理要求独家购买微软的产品,不许微软向第三方提供,微软也只能乖乖地签字。
>> 如果IBM没有犯下这个错误,微软依然会是一家成功的公司,但是不会膨胀得这么大这么快。
>> 致富的方法有许多种,本文只谈论其中的一种,也就是通过创造有价值的东西在市场上得到回报,从而致富。
>> 通过创造有价值的东西而致富,这种方法的优势不仅仅在于它是合法的(许多其他方法如今都是不合法的),还在于它更简单,你只需要做出别人需要的东西就可以了。
◆◆ 金钱不等于财富
>> 即使你没有钱,你也能拥有财富。
>> 财富才是你的目标,金钱不是。
>> 如果财富真的这么重要,为什么大家都把挣钱挂在嘴边呢?部分原因是,金钱是财富的一种简便的表达方式:金钱有点像流动的财富,两者往往可以互相转化。
>> 使用“挣钱”这个词会不利于理解如何才能挣钱。
>> 金钱就是交换媒介,它必须数量稀少,并且便于携带。
>> 交换媒介的优点是,它使得交易可以进行下去。缺点是,它往往模糊了交易的实质。人们觉得做生意就是为了挣钱,但是金钱其实只是一种媒介,让大家可以更方便地获得自己想要的东西。大多数生意的目的是创造财富,做出人们真正需要的东西。
>> 我这里指的只是一种特定的技术层面上的“财富”——人们用金钱和你交换的东西。
>> 对于自己感兴趣的东西,你会觉得它们很有价值,但是它们恰恰最不可能与他人眼中有价值的东西发生重合。
◆◆ 大饼谬论
>> 但是大多数情况下,世界上可供交换的财富不是一个恒定不变的量。人类历史上的财富一直在不停地增长和毁灭(总体上看是净增长)。
>> 假设你拥有一辆老爷车,你可以不去管它,在家中悠闲度日,也可以自己动手把它修葺一新。这样做的话,你就创造了财富。世界上因为多了一辆修葺一新的车,财富就变得更多了一点
◆◆ 手工艺人
>> 最可能明白财富能被创造出来的人就是那些善于制作东西的人,也就是手工艺人。
>> 随着工业化时代的来临,手工艺人越来越少。目前还存在的最大的手工艺人群体就是程序员。
>> 我们这个世界,你向下沉沦或者向上奋进都取决于你自己,不能把原因推给外界。
>> 创造出来的财富不一定非要通过出售实现价值。
◆◆ 工作是什么
>> 公司一切行为的目的都是盈利,从而生存下去。创造财富是大多数公司盈利的手段。
>> 我们说,财富就意味着人们需要的东西,那么把商品送到顾客手中也是人们需要的。许许多多不生产物质商品的公司都是在如此创造财富。几乎所有情况下,公司的存在目的就是满足人们的某种需要。
>> 真正重要的是做出人们需要的东西,而不是加入某个公司。
◆◆ 更努力地工作
>> 真正的问题实际上在于公司无法测量你的贡献。
>> 销售员是一个例外。他们产生的收入很容易测量,他们的薪水往往是销售额的一个百分比。如果一个销售员想更努力地工作,他马上就可以这样做,并且自动按比例得到更多的报酬。
>> 除了销售员以外,还有一个职位,大公司可以雇到顶级人才,那就是高级的管理职位。
>> 你想更努力地工作,但是你的工作与其他许多人的工作混杂在一起,这样就产生了问题。在大公司中,个人的表现无法单独测量,公司里其他人会拖累你。
◆◆ 可测量性和可放大性
>> 要致富,你需要两样东西:可测量性和可放大性。你的职位产生的业绩应该是可测量的,否则你做得再多,也不会得到更多的报酬。此外,你还必须有可放大性,也就是说你做出的决定能够产生巨大的效应。
>> CEO也是一种同时具备可测量性和可放大性的工作。公司的表现就是CEO的表现,所以它具备可测量性;CEO的决策决定了整个公司的方向,所以它具备可放大性。
>> 我认为,任何一个通过自身努力而致富的个人,在他身上应该都能同时发现可测量性和可放大性。我能想到的例子就有CEO、电影明星、基金经理和专业运动员。
◆◆ 小团队 = 可测量性
>> 你最好找出色的人合作,因为他们的工作和你的一起平均计算。
>> 乔布斯曾经说过,创业的成败取决于最早加入公司的那10个人。我基本同意这个观点,虽然我觉得真正决定成败的其实只是前5人。小团队的优势不在于它本身的小,而在于你可以选择成员。我们不需要小村庄的那种“小”,而需要全明星第一阵容的那种“小”。
>> 所以,在不考虑其他因素的情况下,对一个非常能干的人来说,待在大公司里可能是一件很糟的事情,因为他的表现被其他不能干的人拖累了。
>> 一个非常能干而且在乎回报的人,通常在同类人组成的小团队中会有更出色的表现,自己也会感到更满意。
◆◆ 高科技 = 可放大性
>> 什么是技术?技术就是某种手段,就是我们做事的方式。如果你发现了一种做事的新方式,它的经济价值就取决于有多少人使用这种新方式。技术就是钓鱼的鱼竿,而不是那条鱼。这就是创业公司与餐馆或理发店的区别。餐馆煎鸡蛋,理发店剪头发,每次只能为一个顾客提供服务,但是如果你解决了一个热门的技术难题,别人都会使用你的解决方案。这就是可放大性。
>> 回顾历史,大多数因为创造财富而发财的人是通过开发新技术而实现的。
>> 17世纪,荷兰人掌握了造船术和航海知识,那也是当时的高科技,因此荷兰人主宰了欧洲前往远东的航线。
>> 大公司开发出来的新技术只出现在那些需要大规模资本投入的领域,比如微处理器、电厂和大型民用飞机等,因为在这些领域内创业公司没有能力与之竞争。
>> 生物科技类和软件类的创业公司很显然都是解决高难度技术问题的。
>> 沃尔玛也是如此,它的创始人山姆·沃顿(Sam Walton)并不是因为经营零售业而致富,而是因为设计出了一种新型商店。
>> 选择公司要解决什么问题应该以问题的难度作为指引,而且此后的各种决策都应该以此为原则。Viaweb的一条经验法则就是“更上一层楼”。
>> 在实际操作中,这就意味着我们故意选择那些很困难的技术问题。
>> 风险投资人(Venture Capitalist,VC)知道这个道理,并为它起了一个名字——进入壁垒。如果你有一个新点子,你去找风险投资人,问他是否投资,他首先就会问你几个问题,其中之一就是其他人复制你的模式是否很困难。
>> 设置“进入壁垒”的方法之一就是申请专利。
>> 费罗·法恩斯沃斯,电视机的发明者,可是没有人知道他,因为他的公司没有从电视机上面赚到钱。赚到钱的公司是RCA,发明电视机给法恩斯沃斯带来的结果就是一场长达10年的专利诉讼。
>> 总的来说,这也是很好的处事原则。如果你有两个选择,就选较难的那个。
◆◆ 潜规则
>> 但创业是有一些潜规则的,其中一条就是很多事情由不得你。真正创业以后,你的竞争对手决定了你到底要有多辛苦
>> 另一条潜规则是,创业的付出与回报虽然总体上是成比例的,但是在个体上是不成比例的。
◆◆ 用户数量
>> 我认为,如果你的公司有机会被收购,那将是不错的选择。管理一家公司与创立一家公司是不同的两件事。当情况基本稳定下来以后,不妨让大公司来接手。
>> 潜在的买家会尽可能地拖延收购。收购这件事最难的地方就是让买方真正拿出钱。大多数时候,促成买方掏钱的最好办法不是让买家看到有获利的可能,而是让他们感到失去机会的恐惧。对于买家来说,最强的收购动机就是让他们看到竞争对手可能收购你,我们发现这会使得CEO们连夜行动。次强的动机则是让他们担心如果现在不收购你,你的高速成长将使得未来的收购耗资巨大,甚至你本身可能变成他们的一个竞争对手。
>> 在这两种收购动机中,归根结底的因素都是用户数量。你以为买家在收购前会做很多研究,搞清楚你的公司到底值多少钱,其实根本不是这么回事,他们真正在意的只是你拥有的用户数量。
>> 事实上,买家假定用户知道谁有最好的技术。
>> 你开办创业公司不是单纯地为了解决问题,而是为了解决那些用户关心的问题。
>> 尽快拿出1.0版,然后根据用户的反映而不是自己的猜测优化软件。
>> 你必须时刻牢记的最基本的原则就是,创造人们需要的东西,也就是创造财富。
>> 如果你想通过创造财富致富,那么你必须知道人们需要什么。
◆◆ 财富和权力
>> 资产阶级在历史上首先出现在意大利北部和荷兰,这可能不是偶然,因为那里没有强大的中央政府。这两个地区是那时最富裕的地方,后来变成了文艺复兴向外扩散的两大中心。
>> 没有财富的激励,技术革新就会逐渐停顿。
>> 缓慢工作的后果并不仅仅是延迟了技术革新,而且很可能会扼杀技术革新。
>> 要鼓励大家去创业,只要懂得藏富于民,国家就会变得强大。让“书呆子”保住他们的血汗钱,你就会无敌于天下。
◆ 7 关注贫富分化
>> 有没有可能,在现代社会中,收入差距拉大实际上是一种健康的信号?
◆◆ 财富的老爹模式
>> 金钱只是用来交易财富的一种手段,财富才是有价值的东西,我们购买的商品和服务都属于财富。
>> 如果你想要更多的财富,自己生产就可以了。
>> 每个人的技能不同,导致收入不同,这才是贫富分化的主要原因
>> “奥卡姆剃刀原理”所说,简单的解释就是最好的解释。
>> 一个人的工作具有多少价值不是由政府决定的,而是由市场决定的。
>> 但是在现实中,财富是用工作成果衡量的
◆◆ 偷窃
>> 不管是战争还是政治斗争,本质上都属于偷窃。
>> 在控制程度更高的社会,统治者和官僚阶层用税收代替直接充公。但是,根本的一点并没有变,那就是致富的方法不是创造财富,而是以统治者的强权进行搜刮掠夺。
>> 在中世纪,中产阶级其实是一个独立的团体。封建社会只有两个阶级:贵族与农奴(为贵族服务的人)。中产阶级是一个新的第三类团体,他们出现在城镇中,以制造业和贸易为生。
>> 事实上,他们创造出来的东西使得人类的物质生活变得更富有。他们只能这样做,否则不会有人付钱给他们的。
◆◆ 技术的杠杆效应
>> 技术应该会引起收入差距的扩大,但是似乎能缩小其他差距。
>> 现在,由于技术的发展,富人的生活与普通人的差距缩小了。
>> 现在不是这样了,石英表被发明出来了,一块普通的石英表反而比几十万美元的名牌机械表走时更准。
>> 一块普通的石英表,每天的误差大约是0.5秒。
>> 富人最喜欢的就是那些方便易用的产品。
>> 如今,确实有很多人非常有钱,完全不必再去工作,他们之所以还在工作,不是因为感到社会压力,而是因为无所事事使人感到孤独和消沉。
>> 今天的人们多多少少还是有一些互相隔离的趋势,但主要是因为教育层次的差别,而不是财富的差别。
>> 无论在物质上,还是在社会地位上,技术好像都缩小了富人与穷人之间的差距,而不是让这种差距扩大了。
>> 如果参观雅虎、英特尔或思科公司,你会看到每个人都穿着差不多的衣服,有着同样的办公室(或者小隔间)、同样的家具,彼此直呼对方的名字,不加任何头衔或敬语。
>> 技术在加大收入差距的同时,缩小了大部分其他差距。
◆◆ 公理的不同意见
>> 这种收入差距只是因为前者的技能比后者的要值钱得多。
>> 如果得不到报酬,人们是否愿意创造财富?唯一的可能就是,工作必须能提供乐趣。会有人愿意免费写一个操作系统,但是他们不愿意免费为你安装、提供电话支持、进行客户培训等。即使是最先进的高科技公司,也有至少90%的工作没有乐趣、令人生厌。
>> 总的来说,你要避免的是绝对贫穷,而不是相对贫穷。如果必须在这两种社会之间做选择,根据目前的证据,我选择个人相对贫穷但是整体上更富裕的社会。
◆ 8 防止垃圾邮件的一种方法
>> 如果你与奴隶比赛,你也会变成一个奴隶。
>> 我对贝叶斯方法寄予厚望,因为它的过滤能力可以随着垃圾邮件一起进化。
◆ 9 设计者的品味
>> 所谓“品味没有好坏之分”的公理也就顿时见鬼去了。
>> 众多不同学科对“美”的认识有着惊人的相似度。
>> 好设计是简单的设计。
>> 好设计是永不过时的设计。
>> 如果解决方法是丑陋的,那就肯定还有更好的解决方法,只是还没有发现而已。
>> 以永不过时作为目标是一种帮助自己找到最佳答案的方法:如果你不愿别人的答案取代你的答案,你就只好自己给出最佳答案。
>> “风潮”这个词,从字面上就可以看出,它就像一阵风似的,随着时间经常改变。
>> 如果你希望自己的作品对未来的人们有吸引力,方法之一就是让你的作品对上几代人有吸引力
>> 好设计是解决主要问题的设计。
>> 幽默感是强壮的一种表现,始终拥有幽默感就代表你对厄运一笑了之,而丧失幽默感则表示你被厄运深深伤到。
>> 好的设计并非一定要有趣,但是很难想象完全无趣的设计会是好的设计。
>> 如果你工作得不艰苦,你可能正在浪费时间。
>> 在绘画上,肖像画通常占据最高地位。
>> 人们常常觉得野生动物非常优美,原因就是它们的生活非常艰苦,在外形上不可能有多余的部分了。
>> 好设计是对称的设计。
>> 对称有两种:重复性对称和递归性对称。
>> 在软件中,能用递归解决的问题通常代表已经找到了最佳解法。
>> 对称的危险在于它可以用来取代思考,在大量使用重复的时候,这种危险性更大。
>> 好设计是能够复制的设计。
>> 爱因斯坦并不想让相对论变得很奇特,他只想找出真理,是真理本身显得很奇特。
>> 达·芬奇之所以成为达·芬奇,主要原因不仅仅是他的天赋,更重要的是他生活在当时的佛罗伦萨,而不是米兰。
>> 单单是无法容忍丑陋的东西还不够,只有对这个领域非常熟悉,你才可能发现哪些地方可以动手改进。
◆ 第三部分 黑客的工具和设计方法
◆ 10 编程语言解析
机器语言:所有机器都有一张操作命令清单,这种操作命令的总和就是计算机的机器语言。
汇编语言:命令清单还是一样的,就是每个命令换了一个更人性化的名字。机器语言的加法命令是11001101,这可能就是计算机内部的加法表达方式,但是在汇编语言中,这条命令就改成了add。
◆◆ 高级语言
>> 所谓“编译器”,本身就是一个程序,作用是将以简便方式书写的程序(就像上面这一行命令)转变为硬件可以理解的语言。
>> 高级语言还有一个优点,它使得程序更具有可移植性。不同计算机的机器语言都不是完全相同的,所以你无法将为某一种机型写的机器语言程序放到另一种机型上运行,只有彻底重写才能实现。但是,如果你的程序是用高级语言写的,你只需要重写编译器就可以了。
>> 编译器不是高级语言唯一的实现方法,另一种方法是使用解释器,它的作用是实时地将代码解释为相应的机器语言,然后一行行运行。相比之下,编译器则是先将整个程序全部翻译成机器语言,然后再运行。
◆◆ 开放源码
>> 编译器处理的高级语言代码又叫作源码。它经过翻译以后产生的机器码就叫作目标码。顾客购买市场上的商业软件时得到的往往只是目标码
◆◆ 语言的战争
>> 程序员的时间要比计算机的时间昂贵得多,后者已经变得很便宜了
>> 只有少数最关键的部分可能还会用到汇编语言
>> 事实介于这两个极端之间。语言之间确实有差别,但是很难确定地说哪一种语言是最好的。这个领域依然还在快速发展。
◆◆ 抽象性
>> 如果你非常关注运行速度,那么最好使用接近机器的语言。
>> 使用越高级的语言,越不容易被攻击。最常见的几种入侵计算机的手法都是利用了C语言的某些特点。当你在C语言中为输入的内容分配出一片内存(也叫“缓存”)时,它会被分配在当前运行代码的返回地址旁边。所谓“返回地址”指的是一块特定内存,当前代码运行完毕以后,就要运行这块内存中包含的代码。也就是说,它实际上是计算机下一步要做的事情。假定有人打算入侵你的计算机,他们猜出你会为某种输入分配256字节的缓存,于是他们就提交多于256字节的内容,目的是覆盖旁边的“返回地址”。那么,当前代码运行完毕之后,程序的控制权就交给了他们指定的内存地址。这个地址通常是缓存的首地址,缓存中是入侵者事前编好的机器码。于是,入侵者的程序就运行在你的计算机上了。如果使用更抽象的高级语言,上面的事情是不可能发生的。但是,在C语言中,一旦接受用户输入的时候你没有检查输入长度,就创造出了一个安全漏洞。利用这种漏洞的攻击行为就被称为“缓冲区溢出攻击”。在这种攻击中,还有其他方法可以控制计算机,但是覆盖返回地址是最经典的一种。
◆◆ 安全带还是手铐
>> 在静态类型语言中,写代码时必须知道每个变量的类型。而在动态类型语言中,随便什么时候,你都可以把变量设为任意类型的值。
◆ 11 一百年后的编程语言
>> 很难预测一百年后的人类生活,只有少数几件事是可以确定的。那时,汽车将具备低空飞行能力,城市规划的法规将放宽,大楼可以造到几百层,大街上一天到晚看不见太阳,女性个个都学过防身术。
>> 一百年后,人们使用什么语言开发软件?
>> 为什么这个问题值得思考?原因不是我们最终会用上这些语言,而是幸运的话,我们从现在开始就能用上这些语言。
>> 之所以要问这个问题,不是为了一百年后让后人感叹我们曾经如此英明,而是为了找到进化的主干。它会启发我们去选择那些靠近主干的语言,这样对当前的编程最有利。
>> 无论何时,选择进化的主干可能都是最佳方案。
>> 这有点像买房子的时候你应该先考虑地理位置。别的地方将来出问题都有办法弥补,但是地理位置是没法变的。
>> 发现冗余的代码会导致更多冗余的代码
>> 如果其他条件不变,现在被认为运行速度慢(即运行效率不高)的语言将来会有更大的发展空间。
>> 我已经预测了一旦未来硬件性能大幅提高将会发生什么事:新增加的运算能力都会被糟蹋掉。
>> 我们应该有意识地问自己,什么时候可以放弃一些性能,换来一点点便利性的提高。
>> 正确做法应该是将语言的语义与语言的实现予以分离。
>> 一百年后的程序员最需要的编程语言就是可以让你毫不费力地写出程序第一版的编程语言,哪怕它的效率低下得惊人(至少按我们今天的眼光来看是如此)
>> 如果我们想要减少语言内核中基本公理的数目,不妨把眼光放得远一点
>> 另一种消耗硬件性能的方法就是,在应用软件与硬件之间设置很多的软件层。这也是我们已经看到的一种趋势,许多新兴的语言就被编译成字节码
>> 每增加一个解释层,软件的运行速度就会慢一个数量级。但是,多余的软件层可以让编程灵活起来。
>> 某些使用面向对象编程开发出来的软件确实具有可重用性,但是这不是因为它使用了面向对象编程,而是因为它的开发方法是自下而上的。
>> 面向对象编程使得你有办法对面条式代码进行可持续性开发。通过不断地打补丁,它让你将软件一步步做大。大公司总是倾向于采用这样的方式开发软件。我预计一百年后也是如此。
>> 既然是谈论未来,最好谈谈并行计算
>> 除了某些特定的应用软件,一百年后并行计算不会很流行。如果应用软件真的大量使用并行计算,那就属于过早优化了。
>> 一百年后强大的硬件只会使得语言数目变得更多。
>> 性能分析器
>> 静态类型语言看来无法真正支持宏(在我看来,一种语言不支持宏,那就不值得使用了)。
>> 新语言更多地以开源项目的形式出现,而不是以研究性项目的形式出现。这是语言的一种发展趋势。另一种发展趋势是,新语言的设计者更多的是本身就需要使用它们的应用软件作者,而不是编译器作者
>> 采用程序长度作为它耗费的工作量的近似指标是一个很有用的技巧。
>> 观古而知今
>> 在学习开车的时候,一个需要记住的原则就是要把车开直,不是通过将车身对齐画在地上的分隔线,而是通过瞄准远处的某个点。
◆ 12 拒绝平庸
>> 把软件放在服务器端,使用普通的网页作为用户界面。
>> Viaweb是第一个互联网应用程序。
◆◆ 秘密武器
>> Lisp语言确实可以使你成为更好的程序员
>> 选择使用哪一种技术的时候,你不能考虑别人的做法,只能考虑什么样的技术能最好地完成工作。
>> Lisp语言真的非常适合快速开发软件
>> 因为Lisp是一种抽象层次非常高的语言,所以就不需要非常庞大的开发团队,这会降低成本。
>> 在竞争中,你的对手无法理解你的技术优势,这可是再宝贵不过了。
◆◆ Blub困境
>> Lisp语言到底好在什么地方?如果它真的这么好,为什么没有得到广泛使用呢?这种问题听起来有点像绕口令,但是实际上回答起来很简单。Lisp语言的好处不在于它有一些狂热爱好者才明白的优点,而只在于它是目前最强大的编程语言。它没有得到广泛使用就是因为编程语言不仅仅是技术,也是一种习惯性思维,非常难于改变。
>> 徒手用机器语言写出整个程序是一件很蠢的事。
>> 如果你有好几种语言可以选择,在不考虑其他因素的情况下,你不选择最强大的那种语言就是一件很蠢的事。
>> 总的来看,对于应用程序来说,还是应该选择总体最强大、效率也在可接受范围内的编程语言
假设有一种Blub语言。它的抽象程度正好落在编程能力曲线的中点。这位程序员看低层次语言,觉得Blub语言强大,但看高层次语言,觉得可能差不多,因此觉得Blub语言够用了,就不会考虑高层次语言了。
>> 唯一洞悉所有语言优劣的人必然是懂得最强大的那种语言的人。
>> Lisp的宏是独一无二的。信不信由你,Lisp宏的作用与括号有关。Lisp语言的设计者大量使用括号并不是为了标新立异。
>> 它们是Lisp与其他语言存在巨大差异的外在表现。
>> Lisp代码由Lisp数据对象构成。其他语言的源代码一般由字符组成,字符串是主要数据类型之一,但是Lisp语言不完全是这样。经过解析器处理之后,Lisp代码就变成了你可以遍历的数据结构。
>> 如果你理解编译器的工作原理,那么事实是,与其说Lisp有一种很奇特的语法,还不如说它根本没有语法。一般的源代码程序经过编译器解析会生成解析树。Lisp的奇特之处就在于,你完全可以写出程序,控制这种解析树,进行任意的存取操作。Lisp的这种程序就叫作宏,它可以用来生成其他程序。
◆◆ 创业公司的合气道
>> 合气道(Aikido)是一种日本的武术,主要特点是“以柔克刚”“借劲使力”“不主动攻击”。
>> 编程语言的特点之一就是它会使得大多数使用它的人满足于现状,不想改用其他语言。
>> 编程语言的发展通常比CPU的发展落后一二十年。
>> 精简指令集计算机(Reduced Instruction Set Computer,RISC)是CPU的一种架构,对指令数目和寻址方式都做了精简,使其实现更容易,执行速度更快,编译器的效率更高。
>> 技术的变化速度通常是很快的,但是编程语言不一样,与其说它是技术,还不如说是程序员的思考模式。
>> 闭包是20世纪60年代Lisp语言引入的功能,现在的接受程度还很低。
◆ 13 书呆子的复仇
>> Java语言之父詹姆斯·高斯林在第一份《Java白皮书》中说得很清楚,之所以要设计Java,就是想解决C++的一些弱点。
>> 认为所有语言都一样的看法的缺点是自欺欺人
>> 另一些人则认为Ruby语言是取代Python的最佳选择。
>> 当你按照Java、Perl、Python和Ruby这样的顺序观察这些语言,你会发现一个有趣的结果。如果你是一个Lisp黑客,你就看得出来,排在越后面的语言越像Lisp。
>> 编程语言现在的发展不过刚刚赶上1958年时Lisp语言的水平。
◆◆ 朝着数学的方法发展
>> 1958年,约翰·麦卡锡第一个提出了Lisp语言。
>> 1958年的计算机的运算能力还不如今天的电子表,而体积却大得像冰箱
>> 他想用更简洁的方式定义图灵机。
>> Lisp比图灵机表达起来更简洁。
>> Steve Russell,做出了Lisp解释器,也是历史上第一个计算机游戏的作者,1962年他写了《太空大战》
>> 由此也就得出了20世纪50年代的编程语言到现在还没有过时的原因。简单说,因为这种语言本质上不是一种技术,而是数学。数学是不会过时的。
>> Lisp和Fortran代表了编程语言发展的两大方向。前者的基础是数学,后者的基础是硬件架构。从那时起,这两大方向一直在互相靠拢。
◆◆ 为什么Lisp语言很特别
>> Lisp语言诞生的时候就包含了9种新思想
>> (1) 条件结构
>> (2) 函数也是一种数据类型。
>> (3) 递归。Lisp是第一种支持递归函数的高级语言。3
>> (4) 变量的动态类型。
>> 所有变量实际上都是指针
>> (5) 垃圾回收机制。
>> (6) 程序由表达式组成。Lisp程序是一些表达式树的集合,每个表达式都返回一个值。这与Fortran和大多数后来的语言截然不同,它们的程序由表达式和语句组成。
>> (7) 符号类型。符号实际上是一种指针,指向存储在散列表中的字符串。所以,比较两个符号是否相等,只要看它们的指针是否一样就行了,不用逐个字符地比较。
>> (8) 代码使用符号和常量组成的树形表示法。
>> (9) 无论什么时候,整个语言都是可用的。Lisp并不真正区分读取期、编译期和运行期。你可以在读取期编译或运行代码,也可以在编译期读取或运行代码,还可以在运行期读取或者编译代码。
>> 说Lisp语言古怪倒不是因为它的语法很古怪,而是因为它根本没有语法,程序直接以解析树的形式表达出来。
>> 它由列表构成,而列表则是Lisp的基本数据结构。
◆ 语言优势真正体现的地方
>> Lisp的最大优势体现在编程任务的另一端,就是在激烈竞争的条件下开发那些解决困难问题的复杂程序。ITA软件公司为Orbitz旅行社开发的飞机票价搜索程序就是一个很好的例子。
>> ITA的软件核心是一个20万行的Common Lisp程序,它的搜索能力比竞争对手高出许多个数量级。
◆◆ 向心力
>> 使用一种不常见的语言会出现的问题我想到了三个:你的程序可能无法很好地与使用其他语言写的程序协同工作;你可能找不到很多函数库;你可能不容易雇到程序员。
>> 为什么像Perl和Python这样的新语言会流行起来。它们之所以流行,不是因为人们使用它们开发Windows应用程序,而是因为人们在服务器上使用它们。
>> 如果你创业的话,千万不要为了取悦风险投资商或潜在并购方而设计你的产品,让用户感到满意才是你的设计方向。只要赢得用户,其他事情就会接踵而来。如果没有用户,谁会关心你选择的“正统”技术是多么令人放心。
◆◆ 随大流的代价
>> 衡量语言的编程能力的最简单方法可能就是看代码数量。所谓高级语言,就是能够提供更强大的抽象能力的语言,从某种意义上,就像能够提供更大的砖头,所以砌墙的时候用到的砖头数量就变少了。因此,语言的编程能力越强大,写出来的程序就越短
>> 强大的编程语言如何让你写出更短的程序?一个技巧就是(在语言允许的前提下)使用“自下而上”的编程方法。你不是用基础语言开发应用程序,而是在基础语言之上先构建一种你自己的语言,然后再用后者开发应用程序,这样写出来的代码会比直接用基础语言开发出来的短得多。
>> “1行Lisp代码相当于20行C代码”
◆◆ 一个诀窍
>> 在大型组织内部,有一个专门的术语描述这种跟随大多数人的选择的做法,叫作“业界最佳实践”。
◆◆ 附录:编程能力
>> 闭包(即一个函数,通过它可以引用由包含这个函数的代码所定义的变量
>> “格林斯潘第十定律”:任何C或Fortran程序复杂到一定程度之后,都会包含一个临时开发的、只有一半功能的、不完全符合规格的、到处都是bug的、运行速度很慢的Common Lisp实现。
>> 如果你想解决一个困难的问题,关键不是你使用的语言是否强大,而是好几个因素同时发挥作用:(a)使用一种强大的语言;(b)为这个难题写一个事实上的解释器;(c)你自己变成这个难题的人肉编译器。
>> 举例来说,在面向对象编程的世界中,我们大量听到“模式”(pattern)这个词,我觉得那些模式就是现实中的因素(c),也就是人肉编译器。
>> 彼得·诺维格发现,总共23种设计模式之中,有16种在Lisp语言中“本身就提供,或者被大大简化”。
◆ 14 梦寐以求的编程语言
>> 当且仅当黑客喜欢一种语言时,这种语言才能成为合格的编程语言
◆◆ 流行的秘诀
>> 语言流行,专家级黑客的看法是最重要的因素。
◆◆ 外部因素
>> 编程语言总是与它们依附的系统联系在一起的。
>> 编程语言还需要有一本介绍它的书。这本书应该不厚,文笔流畅,而且包含大量优秀的范例。布莱恩·柯尼汉1和丹尼斯·里奇合写的《C程序设计语言》(C Programming Language)就是这方面的典范。眼下,我大概还能再加一句,这一类书之中必须有一本由O’Reilly公司出版发行。这正在变成是否能吸引黑客的前提条件了。
◆◆ 简洁
>> 假定你的语言已经能够满足上面三项条件(一种免费的实现,一本相关图书,以及语言所依附的计算机系统),那么还需要做什么才能使得黑客喜欢上你的语言?
黑客欣赏的一个特点就是简洁。
>> 简洁性是静态类型语言力所不及之处。不考虑其他因素,没人愿意在程序的头部写上一大堆声明语句。只要计算机可以自己推断出来的事情,都应该让计算机自己去推断。
◆◆ 可编程性
>> 黑客喜欢破解,而破解就意味着深入内部,揣测原始设计者的意图。
>> 对于制造工具的人来说,总是会有用户以违背你本意的方式使用你的工具。
>> 一种真正优秀的编程语言应该既整洁又混乱。“整洁”的意思是设计得很清楚, 内核由数量不多的运算符构成,这些运算符易于理解,每一个都有很完整的独立用途。“混乱”的意思是它允许黑客以自己的方式使用。
◆◆ 一次性程序
>> 很容易装备不仅仅指很容易安装或者已经安装,还指很容易与使用者互动。一种有命令行界面、可以实时反馈的语言就具有互动性,那些必须先编译后使用的语言就不具备互动性。
◆◆ 函数库
>> 我认为,未来50年中,编程语言的进步很大一部分与函数库有关。
>> 优秀函数库的重要性将超过语言本身。某种语言到底是静态类型还是动态类型,是面向对象编程还是函数式编程,这些都不如函数库重要。
◆◆ 效率
>> 编程时提高代码运行速度的关键是使用好的性能分析器
>> 好的性能分析器对程序的帮助可能大于编译器的作用。
>> 越来越多的程序主要不是受限于计算机的运算速度,而是受限于I/O速度。加快I/O速度将是很值得做的一件事。在这方面,编程语言也能起到作用,有些措施是显而易见的,比如采用简洁、快速、格式化输出的函数,还有些措施则需要深层次的结构变化,比如采用缓存和持久化对象。
>> 帕金森定律4被证明与摩尔定律一样颠扑不破。软件不断膨胀,消耗光所有可以得到的资源。
>> 帕金森定律的一种原始表达形式是“工作总是到最后一刻才会完成”,后来引申到计算机领域就变成了“数据总是会填满所有空间”,更一般性的总结则是“对一种资源的需求总是会消耗光这种资源的所有供应”。
>> 在一些应用程序中,处理器的运算能力是瓶颈,那么最重要的优化对象就是软件的运行速度。但是,一般情况下内存才是瓶颈,你能够同时支持的用户数量取决于用户数据所消耗的内存。编程语言在这方面也能发挥作用,对线程的良好支持将使得所有用户共享同一个内存堆。持久化对象和语言内核级别的延迟加载支持也有助于减少内存需求。
◆◆ 时间
>> 我有一个朋友,在他的客户第一次提出某种需求时,他很少理会,因为他知道人们有时候会想要自己并不真正需要的东西。为了避免浪费时间,只有当客户第三次或第四次提出同样的需求时,他才认真对待。
>> 所以,发明新事物的人必须有耐心,要长年累月不断地做市场推广,直到人们开始接受这种发明。
>> 人们真正注意到你的时候,不是第一眼看到你站在那里,而是发现过了这么久你居然还在那里。
>> 新技术被市场接纳的方式有两种,一种是自然成长式,另一种是大爆炸式。
>> 最终来看,自然成长式会比大爆炸式产生更好的技术,能为创始人带来更多的财富。如果你研究一下目前的主流技术,就会发现大部分是源于自然成长式。
◆◆ 再设计
>> 为了写出优秀软件,你必须同时具备两种互相冲突的信念。一方面,你要像初生牛犊一样,对自己的能力信心万丈;另一方面,你又要像历经沧桑的老人一样,对自己的能力抱着怀疑态度。在你的大脑中,有一个声音说“千难万险只等闲”,还有一个声音却说“早岁那知世事艰”。
>> 这里的难点在于你要意识到,实际上这两种信念并不矛盾。你的乐观主义和怀疑倾向分别针对两个不同的对象。你必须对解决难题的可能性保持乐观,同时对当前解法的合理性保持怀疑。
>> 如果用户数量庞大,修改语言带来的痛苦就将持续很长时间。
>> 一种可能的解决方法是,将软件内部的接口设计成垂直接口而不是水平接口。这意味着软件内部的模块是一个个垂直堆积起来的抽象层,层与层之间的接口完全由其中的一层控制。如果较高的一层使用了较低的一层定义的语言,那么接口就由较低的一层控制;如果较低的一层从属于较高的一层,那么接口就由较高的一层控制。
◆◆ 梦寐以求的编程语言
>> 让我们试着描述黑客心目中梦寐以求的语言来为以上内容做个小结。这种语言干净简练,具有最高层次的抽象和互动性,而且很容易装备,可以只用很少的代码就解决常见的问题。不管是什么程序,你真正要写的代码几乎都与你自己的特定设置有关,其他具有普遍性的问题都有现成的函数库可以调用。
>> 这种语言的抽象程度很高,使得你可以快速写出一个程序的原型。然后,等到你开始优化的时候,它还提供一个真正出色的性能分析器,告诉你应该重点关注什么地方。
◆ 15 设计与研究
>> 可是,让用户满意并不等于迎合用户的一切要求。用户不了解所有可能的选择,也经常弄错自己真正想要的东西。做一个好的设计师就像做一个好医生一样。你不能头痛医头,脚痛医脚。病人告诉你症状,你必须找出他生病的真正原因,然后针对病因进行治疗。
>> 除非设定目标用户,否则一种设计的好坏根本无从谈起。
>> 如果你觉得自己在为傻瓜设计产品,那么很可能不仅无法设计出优秀产品,而且就连傻瓜也不喜欢你的设计。
>> 举例来说,不考虑其他因素,肖像画就是比风景画更能引发观众的兴趣。文艺复兴时期的经典绘画作品都是画人的,这并非巧合。
>> 不管你喜不喜欢,编程语言也是以人为本的。
>> 人类似乎不善于处理精细的工作,所以最好还是交给计算机处理。
>> 评价一种语言的优劣,不能简单地看最后的程序是否表达得很漂亮,而要看程序从无到有的那条完成路径是否很漂亮。
>> 有时候,更少的功能(弱)反而是更好的选择(强),因为这会使得软件的可用性提高。
>> 与之对照,还有另一种软件设计思想,也许可以被称为“万福玛丽亚”模式。它不要求尽快拿出原型,然后再逐步优化,它的观点是你应该等到完整的成品出来以后再一下子隆重地推向市场,就像圣母玛丽亚降临一样
>> 在互联网泡沫时期,无数创业公司因为相信了这种模式而自毁前程。
>> 以绘画为例,你真正应该采用的方法是快速地用几根线画出一个大致准确的轮廓,然后再逐步地加工草稿。
>> 大多数艺术领域,原型使用的材料与成品的材料一般来说是不一样的。印刷活字先画在纸上,然后才做成铅字。雕塑先用石蜡创作,然后才用青铜浇铸。地毯图案先用墨水画出纸型,然后才织成地毯。建筑物先做出木模型,然后才做成石头建筑
>> 为什么15世纪油画首次亮相会引起轰动并很快流行起来?原因就是油彩使得画家可以在原型上直接画出最后的样子。你可以按照自己的想法画出初稿,但是它并不对你构成限制。接下来你可以逐步加上细节,甚至对初稿做出重大修改,直到最后完成。
>> 软件开发也可以这样做。原型并不只是模型,不等于将来一定要另起炉灶,你完全能够在原型的基础上直接做出最后的成品。
>> 先做出原型,再逐步加工做出成品,这种方式有利于鼓舞士气,因为它使得你随时都可以看到工作的成效。在开发软件的时候,我有一条规则:任何时候,代码都必须能够运行。如果你正在写的代码一个小时之后就可以看到运行结果,这好比让你看到不远处就是唾手可得的奖励,你因此会受到激励和鼓舞。
>> 画家之间甚至流传着一句谚语:“画作永远没有完工的一天,你只是不再画下去而已。”
◆ 术语表
>> Algorithm 算法:完成任务的方法。
>> ASP/Application Service Provider 应用服务提供商:这种软件公司允许用户通过网络使用存放在服务器上的软件
>> Bayesian 贝叶斯定理:一种统计推断的方法,又称贝叶斯算法。
>> Bit Manipulation 位操作
>> Block-Structured 块结构:某些语言支持的子区域结构。有了这种语法,就可以实现结构化编程,而不是简单地一条条按顺序执行命令。
>> Blub Paradox Blub困境:程序员的思想往往会受到自己正在使用的语言的束缚,不相信还存在更强大的语言。
>> Brooks's Hypothesis 布鲁克斯假说:程序员一天写出的代码行数是一个常量,与他使用什么语言无关。
>> Buffer 缓冲区:一个内存区域,用来保存程序需要的输入数据,或者将程序的输出数据累积起来,到一定数量后再输出。
>> Collocated 托管:通常指放在ISP处。
>> Common Gateway Interface Script CGI脚本/通用网关接口脚本:当网络服务器需要进行某种运算(比如数据库搜索)而不是直接传输现有文件时所运行的一种程序。
>> Common Lisp:Lisp语言的一种流行的方言,20世纪80年代由一个委员会设计。
>> Complexity 复杂度
>> CPU/Central Processing Unit 中央处理器
>> Crash 崩溃:
>> Cruft 冗余
>> Cycle 周期:执行一个机器指令的最少时间。
>> C语言:一种简洁优美的计算机语言,由丹尼斯·里奇(Dennis Ritchie)在20世纪70年代初设计。广泛用于操作系统和路由器的编程。
>> Data Structure 数据结构
>> Deprecated 废弃
>> Embedded Language 嵌入式语言
>> Field 字段
>> Freeware 自由软件:自由传播的软件。
>> Garbage Collection 垃圾回收
>> Glue Program 胶水程序:在应用程序之间整理或者转移数据的程序。
>> Hack 破解:一种破坏规则的解决方法
>> Hacker 黑客:解释一,优秀程序员;解释二,侵入他人电脑的人。
>> Heuristic 启发
>> High-Level Programming Language 高级编程语言:比机器语言抽象得多的语言。
>> HTML/HyperText Markup Language 超文本标记语言:用来撰写网页的一套书写法。
>> HTTP/HyperText Transfer Protocol 超文本传输协议:网络服务器与浏览器之间的通信协议。
>> I/O 输入(Input)和输出(Output)
>> Indented 缩进
>> Infinite Loop 无限循环
>> Instrument 记录仪
>> Interpreter 解释器
>> 而是每次读入一行代码,然后执行相应的机器语言命令,之后再去读下一行代码。
>> IT/Information Technology 信息技术
>> Larval Startup 雏形创业公司:
>> Legacy Software 历史遗留软件
>> 现状。
Lexical Closure 闭包:一个函数,通过它可以引用由包含这个函数的代码所定义的变量。
>> Linux:Unix操作系统的一个开源版本。
>> Lisp:一种编程语言的分支,由约翰·麦卡锡(John McCarthy)在20世纪50年代末的研究成果衍生而来。它的两种最著名的方言是Common Iisp和Scheme。如今的开源编程语言越来越多地借鉴Lisp的设计。
>> Machine Instruction 机器指令
>> Macro 宏:一个能够生成其他程序的程序。要在不同语言中实现这一点,就意味着不同语言的宏差异很大,一种语言的宏可能比另一种语言的宏强大得多。
>> Metacircular 元循环:当一种语言的解释器用这种语言本身开发时,就会出现这种情况。
>> Moore's Law 摩尔定律:摩尔定律的正式版本是指,一块芯片上的晶体管数量每2年就会翻一番。但是,大多数人提到这个术语时,指的却是处理器的运算速度每18个月就会翻一番。
>> Object Code 目标码:编译器产生的机器语言。
>> Occam's Razor “奥卡姆剃刀”原则:简单的解释就是较好的解释。
>> Open Source Software 开源软件:源代码可以被任何人自由传播和修改的软件,前提条件往往是修改后的软件源代码也必须保持自由状态。
>> Optimization 优化:调整程序,使得它的效率更高。
>> Orthogonal 正交的:彼此独立、能够以多种方式组合在一起的一组东西。
>> OS/Operating System 操作系统
>> Parkinson's Law 帕金森定律:完成一项任务所需要的资源会不断扩展,直至把这种资源消耗光为止。
>> Parser Tree 解析树:解析器读取源码后生成的数据结构。它是将源码翻译成机器语言的第一步。
>> Patch 补丁
>> PDA/Personal Digital Assistant 个人数字助理:一种可以随身携带的小型计算机。
>> Pipe 管道:将操作系统的各种命令连接起来的一种方式,使得一个命令的输出变成另一个命令的输入。
>> Pointer Arithmetic 指针运算
>> Polynomial 多项式的
>> Portable 可移植性
>> 高级语言程序比机器语言程序更具备可移植性,因为前者的代码(几乎)与硬件无关。
>> Portal 门户:网站。
>> Premature Design 过早设计:过早决定一个程序的行为。
>> Premature Optimization 过早优化:还没有写完程序,你就开始考虑它的性能问题。
>> Profiler 性能分析器
>> Pseudocode 伪代码
>> Python:一种由吉多·范罗苏姆(Guido van Rossum)开发的开源编程语言。带有强烈的面向对象风格,被爱好者看作是Perl语言的一种较为简洁的替代品。
>> QA/Quality Assurance 质量保证
>> RAID/Redundant Array of Independent Disks 独立磁盘冗余阵列
>> Recursive 递归
>> Regular Expression 正则表达式:一种分解字符串的模式,就像筛子一样从字符串中取出想要的部分。
>> Risc/Reduced Instruction Set Computer 精简指令集计算机
>> Socket 套接字:Unix操作系统的一种内部渠道,不同计算机的进程通过它可以在网络上交换信息。
>> Software Engineer 软件工程师:程序员的一种正式名称。
>> SSH/Secure Shell 安全外壳:可以安全连接远程计算机的一种程序。
>> SSL/Secure Sockets Layer 安全套接字层
>> State Machine 状态机
>> Subroutine 子程序
>> Subset 子集
>> Turing Machine 图灵机:一种完全虚构的计算机,作用是证明计算理论。由于所有计算机的程序都可以被转换成图灵机程序,所以在这个意义上,你不可能做出比图灵机更强大的计算机。但是没有人能保证这一点,因为“计算机”这个词并没有被正式定义过。
Turing-Complete 图灵完备:如果一种编程语言写出的所有程序都能被转换成图灵机程序,并且反之也成立,那么这种编程语言就是图灵完备的。所有当代编程语言都是图灵完备的,这意味着(在理论上)它们的功能都是一样强大的。图灵完备又称图灵等价(Turing-Equivalent)。
>> UDP/User Datagram Protocol 用户数据报协议:一种网络传播信息的协议。
>> UI/User Interface:用户界面。
>> Uptime 正常运行时间
>> 它的另一个意思一指某台计算机从上次宕机到现在的时间长度。
>> URL/Uniform Resource Locator 统一资源定位符:网页的地址。
>> VC/Venture Capitalist 风险投资人
>> XML/Extensible Markup Language 可扩展标记语言
◆ 贝叶斯推断与过滤垃圾邮件
(详细如何过滤垃圾邮件,见该书籍对应章节)
◆◆ 什么是贝叶斯推断
>> 贝叶斯推断是一种统计学方法,用来估计统计量的某种性质。它是贝叶斯定理的应用。
◆◆ 贝叶斯定理
>> 要理解贝叶斯推断,必须先理解贝叶斯定理。后者实际上就是计算“条件概率”的公式。
>> 所谓条件概率,就是指在事件B发生的情况下,事件A发生的概率,用P(A|B)来表示。
由
得
>> 这就是条件概率的计算公式。
◆◆ 全概率公式
>> 这就是全概率公式
>> 条件概率的另一种写法
◆◆ 贝叶斯推断的含义
>> 对条件概率公式进行变形,可以得到如下形式:
>> 我们把P(A)称为“先验概率”,即在B事件发生之前,我们对A事件发生概率的一个判断。P(A|B)称为“后验概率”,即在B事件发生之后,我们对A事件发生概率的重新评估。P(B|A)/P(B)称为“可能性函数”,这是一个调整因子,使得预估概率更接近真实概率。
>> 条件概率可以理解成下面的式子:
后验概率=先验概率×调整因子
>> 这就是贝叶斯推断的含义。
◆◆ 【例子】假阳性问题
>> 现有一个病人的检验结果为阳性,请问他确实得病的可能性有多大?
>> 即阳性结果完全不足以说明病人得病。为什么会这样?为什么这种检验的准确率高达99%,但是可信度却不到2%?答案与它的误报率太高有关。
◆◆ 联合概率的计算
>> 所谓联合概率,就是指在多个事件发生的情况下,另一个事件发生的概率有多大。
>> 这就是联合概率的计算公式(不明白,这如何推导的)
◆◆ 最终的计算公式
>> 一封邮件是不是垃圾邮件,就用这个式子进行计算。
四、其他
>> 亚历克西斯·奥哈尼安(Alexis Ohanian,论坛网站Reddit的联合创始人)和山姆·阿尔特曼[Sam Altman,Loopt联合创始人,后来担任了YC的掌门人,并与埃隆·马斯克(Elon Musk)联合创立了OpenAI
>> 陆奇创建了YC中国(后更名为奇绩创坛)
>> 1946年,第一台电子计算机ENIAC在美国诞生
>> 唐氏综合征(Down's Syndrome,多了一条21号染色体)是一种先天性疾病,主要指幼儿的智力和体格发育迟缓,特征为低智商、身材矮小、表情呆滞。
>> 约翰·纳什(John Nash,1928—2015),美国著名数学家,因其对博弈论的突出贡献而获得1994年的诺贝尔经济学奖。纳什从小性格孤僻,不合群,读大学期间以行为古怪而闻名,30岁时就患上了严重的精神分裂症。电影《美丽心灵》讲述的就是他的故事。
>> 今天,说地球围绕太阳运转真是再平常不过了,如果换在17世纪的欧洲,这么说就大难临头了。伽利略说了这样的话,结果遭到了宗教法庭的审判。
>> 伽利略因为宣传日心说而遭到教廷的审判,这件事讽刺的地方在于,他只是在宣传哥白尼的观点,而后者却安然无恙。
>> 2001年“9·11”事件以后,美国通过了《爱国者法案》,以遏制恐怖主义为目的大大扩大了警察机关的权限。
>> 经济学里有一条拉弗曲线,认为随着税率的上升,税收收入会先增加后减少。
>> IBM在推出个人计算机时,懒得自己开发操作系统,就与微软公司签了一个很大方的授权协议,将微软的DOS作为默认操作系统,每卖出一台计算机,微软都可以拿到提成,并且还可以把DOS授权给其他公司使用。这份授权协议的结果无疑让IBM感到非常吃惊。
>> 苹果公司的iPhone手机已于2007年6月上市。
>> Altair 指的是MITS公司在1975年推出的Altair 8800微型计算机,CPU为Intel 8080。它是第一批微型计算机中最成功的产品,被认为是最早的个人计算机。
>> Edward Roberts(1941—2010),美国工程师。1970年创立MITS公司,1975年设计出了历史性的产品——微型计算机Altair 8800,开创了个人计算机的时代,后来被称为“个人计算机之父”。
>> 当时,哈佛大学二年级的学生比尔·盖茨就是因为看到了这篇报道,才决定和保罗·艾伦一起为Altair开发Basic语言的解释器,并于1975年7月成立微软公司,可以说这篇报道直接促成了微软公司的成立。
>> 古希腊数学家埃拉托色尼(Eratosthenes,公元前276—前195)通过测量不同地点建筑物的阴影长度,估算出了地球周长。他的结果只比正确值小了约2%。
>> SETI@home是一个寻找地球以外智慧生命的科学实验,由加州大学伯克利分校发起并主持。它使用射电望远镜监听太空中的无线电信号,然后用计算机进行数据分析,如果发现有些信号不可能自然产生,就可以证明外星文明的存在。
end