《黑客与画家》——读书笔记
这是一本相见恨晚的书,尤其对于我这种去创业圈里滚了一圈回来的普通大学生而言,对里面作者的一些观点有着强烈的共鸣。
————————————————————————————————————————————————————————————————
“你现在拿在手里的,是一本非常重要、也非常独特的书。”这是书的最开始的一句话,随着酣畅淋漓的把这本书读完,我更加觉得这是本“极具意义,富有启发性”的业界巨作,堪称经典。虽然有些地方有冗余,但是并不影响这本书的质量。
书的作者首先是个很厉害的人,除去title“创业教父”以外,学历也高:哈佛大学计算机博士,开发了第一个非桌面应用,成为了现在的雅虎商店,之后又创办了举世闻名的创业孵化YC公司。他就是保罗·格雷厄姆(Paul Graham)。也他个人的成功,YC的成功,YC项目的成功,都足以让人信服他的创业哲学:1.搭建原型2.上线运营3.收集反馈4.调整产品5.成长壮大。这本书基本上都是作者自己的一些有意思的想法,大篇幅都可以作为“创业经”来学习,然而极富浪漫色彩的语言背后,是作者高屋建瓴的思想,和致力于推动世界向前发展的野心。
本书先是重申黑客的概念,“黑客”既可以指很巧妙或很便捷的解决方法,也可以指比较笨拙、不那么优雅的解决方法。这个词被发明时是完全正面的,如果要完成一个hack,就必然包含着高度的革新、独树一帜的风格、精湛的技艺。最能干的人会自豪地称自己为黑客。黑客是“伟大”的,不是“龌蹉”的。黑客不服从管教,具有叛逆精神。黑客是有精神追求的。自由软件基金会创始人理查德·斯托尔曼说:“出于兴趣而解决某个难题,不管它有没有用,这就是黑客。”黑客行为必须包含三个特点:好玩、高智商、探索精神。只有其行为同时满足这三个标准,才能被称为“黑客”。另一方面,它们也构成了黑客的价值观,黑客追求的就是这三种价值,而不是实用性或金钱。黑客有时会入侵计算机系统但主要目的并不是侵犯别人的利益,而是改进现状、探索未知。“黑客”有着自己的价值观,六条伦理:
(1) 使用计算机以及所有有助于了解这个世界本质的事物都不应受到任何限制。任何事情都应该亲手尝试。 (2) 信息应该全部免费。 (3) 不信任权威,提倡去中心化。 (4) 判断一名黑客的水平应该看他的技术能力,而不是看他的学历、年龄或地位等其他标准。 (5) 你可以用计算机创造美和艺术。 (6) 计算机使生活更美好。根据这六条“黑客伦理”,黑客价值观的核心原则可以概括成这样几点:分享、开放、民主、计算机的自由使用、进步。
之后讲述了黑客的成长过程。作者将黑客和画家作比,通俗易懂的语言,阐明了作为一个黑客应该具备的素质。让公众了解,黑客并不神秘,更不是技术怪人。黑客只是怀有一门特殊手艺、有创造天赋的普通人。而且编程是一种艺术创作,黑客就是艺术家,开发软件与画家作画、雕塑家雕刻、建筑师设计房屋并没有本质不同。
书呆子受欺负所以有着怪异的性格,影响到了以后。AI的正确含义是如何凭空创造出问题。由于现阶段体制人们无法考核你的工作,甚至误解你的工作。所谓“试玉要烧三日满,辨才要待七年期”作者说了现在教育制度和黑客的成长曲线不符。而企业也不允许黑客继续做自己喜欢的事情,现有的考核标准不能考核一个程序员是否优秀。大学和实验室强迫黑客成为科学家,企业强迫黑客成为工程师。
编程语言首要的特性应该是允许动态扩展(malleable)。编程语言是用来帮助思考程序的,而不是用来表达你已经想好的程序。它应该是一支铅笔,而不是一支钢笔。
但是当你排斥设计差异的时候,你不仅将失败的可能性排除在外,也将获得高利润的可能性排除在外。这对大公司来说不是问题,因为生产特别优秀的产品不是它们的获胜手段。大公司只要做到不太烂,就能赢。
真正竞争软件设计的战场是新兴领域的市场,这里还没有人建立过防御工事。只要你能做出大胆的设计,由一个人或一批人同时负责设计和实现产品,你就能在这里战胜大公司。微软公司自己一开始就是这样走向成功的,苹果公司和惠普公司也是如此。我觉得几乎所有的创业公司都是这样取得成功的。
黑客的出发点是原创,最终得到一个优美的结果;而科学家的出发点是别人优美的结果,最终得到原创性。
如果你预先承认规格设计是不完美的,在编程的时候,就可以根据需要当场修改规格,最终会有一个更好的结果。过早优化(premature optimization)是一件危险的事情。我认为,我们应该对“过早设计”(premature design)也抱有同样的担忧,不要太早决定一个程序应该怎么做。坚持一丝不苟,就能取得优秀的成果。因为那些看不见的细节累加起来,就变得可见了。
如果黑客只是一个负责实现领导意志的技术工人,职责就是根据规格说明书写出代码,那么他其实与一个挖水沟的工人是一样的,从这头挖到那头,仅此而已。但是,如果黑客是一个创作者,他从事的就不是机械性的工作,他必须具备灵感。
作者又给出了团队开发合作的建议,不能过于“合”,不能多人一起开发小块的代码。黑客应该时刻考虑到用户的人性需要,尽可能的“换位思考”,这样才能做出伟大的产品。“程序写出来是给人看的,附带能在机器上运行。”
要有自己的观点和思想,并且主动给但是不要随意的发表观点,避免给自己带来麻烦,要找信得过的人讨论,让想法变得更有意义。优秀作品往往来自于其他人忽视的想法,而最被忽视的想法就是那些被禁止的思想观点。
不管是哪一个原因,看来存在一个很清晰的关联关系:智力越高的人,越愿意去思考那些惊世骇俗的思想观点。这不仅仅因为聪明人本身很积极地寻找传统观念的漏洞,还因为传统观念对他们的束缚力很小,很容易摆脱。从他们的衣着上你就可以看出这一点:不受传统观念束缚的人,往往也不会穿流行的衣服。
作者阐述了个人认为的看法:版权保护一定程度上阻止了新技术的诞生。并阐明了软件从桌面转移到服务器的趋势。“太麻烦,不如死”。“你的电脑”这个概念正慢慢成为过去时,取而代之的是“你的数据”。你应该可以从任何电脑上获取你的数据。(我要学会和服务器连接,而不是在本地编一些小程序)这本书发表到现在也有一段时间了,我们惊喜的发现,作者的憧憬有一部分已经是现在的情况了。这也足以说明,作者的观点是高屋建瓴的,经得起时间的考验。
软件的边际成本很小,所以只要有可能,就采用 “价格歧视”的定价方法,也就是针对不同的客户给出不同的报价,使得利润最大化.
互联网软件的目标客户应该是个人和小企业。这些客户决策比较灵活,又需要低成本的新技术,所以他们更愿意尝试新事物。大公司付出的高价之中,很大一部分是商家为了让大公司买下这个商品而付出的费用。这就是为什么公司内部的局域网软件明明不可取、但是还会继续存在并且不断发展的一个原因。这样的软件更昂贵,但是你对这个难题就是无能为力。所以,最好的安排就是把个人和小企业客户放在第一位。其他的客户该来的时候就会来。
开发互联网软件的创业公司会把与创业有关的每一件事做到极致。只用更少的人、更少的钱,就可以把软件写出来,并且开始运作。你必须打破常规、快速行动,循规蹈矩不可能成功。你完全能够在只有三个人的情况下让产品开始运营,你们唯一的办公场所就是一间公寓,里面放着一台连着ISP的服务器。
创业公司的压力很大,不幸的是,这一点在互联网软件业也发挥到了极致。互联网软件永远没有收工的那一天,如果你愿意,可以一直干下去,每天忙上16个小时。而且,你能够做到这一点,意味着竞争者也能做到这一点,所以长时间工作变成了一种必需,不得不如此。因为你能做到,所以你必须做到。“孩子们的创业经”,创业一定要自己动手设计和开发
从经济学观点看,你可以把创业想象成一个压缩过程,你的所有工作年份被压缩成了短短几年。你不再是低强度地工作四十年,而是以极限强度工作四年。在高技术领域,这种压缩的回报尤其丰厚,工作效率越高,额外报酬就越高。在不受打扰的情况下,程序员能创造很大的价值。如果自己能够高效率的工作,那么创业能给你带来巨大的财富。财富才是你的目标,金钱不是。金钱是财富的一种简便的表达方式。财富是能被创造出来的,创造财富的就是手艺工人。程序员坐在电脑前就能创造财富。优秀软件本身就是一件有价值的东西。
如果你去工作,你创造的财富应该至少要是你的薪水。因为大的组织规模下,个人努力会被平均化,所以把大的组织架构划分为小的组织架构是比较合理的。能够有更高效的生产力。
创业公司要成功,你必须有他人难以复制的技术或者模式。创业公司不像能经受打击的黑熊,也不像有盔甲保护的螃蟹,而是像蚊子一样,不带有任何防御,就是为了达到一个目的而活着。蚊子唯一的防御就是,作为一个物种,它们的数量极多,但是作为个体,却极难生存。创业公司如同蚊子,往往只有两种结局,要么赢得一切,要么彻底消失。你通常不知道自己会是哪一个结局,只有等到最后一刻才会明了。保险的做法就是在早期卖掉自己的创业公司,放弃未来发展壮大(但风险也随之增大)的机会,只求数量较少但是更有把握的回报。思考:把公司“当孩子养还是当猪养”。买卖的艺术上,大多数时候,促成买方掏钱的最好办法不是让买家看到有获利的可能,而是让他们感到失去机会的恐惧。对于买家来说,最强的收购动机就是看到竞争对手可能收购你。
VC真正在意的只是你拥有的用户数量。创业公司也应该把用户数量当做指标。不要想着一次性把产品做的多好,而是尽快拿出1.0版,然后根据用户的反映而不是自己的猜测进行软件优化。当我们讨论“收入分配不公平”时,我们还要问问收入从何而来,收入背后的财富到底是谁生产出来的。如果收入完全根据个人创造的财富数量而分配,那么结果可能是不平均的,但是很难说是不公平的。
技术无法使其变得更便宜的唯一东西,就是品牌。这正是为什么我们现在越来越多地听到品牌的原因。富人与穷人之间生活差异的鸿沟正在缩小,品牌是这种差距的遗留物。当今社会贫富差距在缩小,但是作者认为现代社会的收入差距扩大反而是一种健康的信号。技术使得生产率的差异加速扩大,如果这种扩大没有反映在收入上面,只有三种可能的解释:(a)技术革新停顿了;(b)那些创造大部分财富的人停止工作了;(c)创造财富的人没有获得报酬。
作者还介绍了借助统计学原理(贝叶斯方法),一些规律用算法和代码来过滤垃圾邮件。(这一部分作者可能很骄傲于自己的方法,但是我没怎么看懂,也没有兴趣了解)
美感是第一道关卡,丑陋的数学在世界上无法生存。——GH.哈代,《一个数学家的道歉》。“品味”相当重要。(1)好设计是简单的设计。(2)好设计是解决主要问题的设计。(3)好设计是启发性的设计。每个人看到《蒙娜丽莎》都有自己的理解。“一千个读者有一千个哈姆雷特”。在软件业中,这条原则意味着,你应该为用户提供一些基本模块,使得他们可以随心所欲自由组合,就像玩乐高积木那样。(4)好设计通常是有点趣味性的设计。(5)好设计是艰苦的设计。并非所有的痛苦都是有益的。世界上有有益的痛苦,也有无益的痛苦。你需要的是咬牙向前沖刺的痛苦,而不是脚被钉子扎破的痛苦。 “越是简单的音调越需要艰苦的练习”练习的作用也许是训练你把刻意为之的事情变成一种自觉的行为。(6)好设计是对称的设计。自然界的对称大量存在,这就说明了对称的重要性。、对称有两种:重复性对称和递归性对称。递归性对称就是指子元素的重复,比如树叶上叶脉的纹路。(7)好设计是模仿大自然的设计。模仿与剽窃并不相同。写实的目的不是为了给生活留下一模一样的记录,而是为你的思想提供一个咀嚼点:你的眼睛看着某样东西,你的手就代表你的思想, 画出一些比较有意思的内容。(8)好设计是一种再设计。很少有人一次就把事情做对。专家的做法是先完成一个早期原型,然后提出修改计划,最后把早期原型扔掉。(9)好设计是能够复制的设计。把事情做对比原创更重要。等到你逐渐对一件事产生热情的时候,就不会满足于模仿了。你的品味就进入了第二阶段,开始自觉地进行原创。(10)好设计常常是奇特的设计。“奇特”这个特点是无法培育的。但是你最后发展出来的风格是自然而然形成的。唯一达到“奇特”的方法,就是追求做出好作品,完成之后再回过头看。(11)好设计是成批出现的。互相激励比天赋更重要。(12)好设计常常是大胆的设计。如果你想做出伟大的新成果,那就不能对常识与真理不相吻合之处视而不见,反而应该特别注意才对。优秀作品的秘块就是:非常严格的品味,再加上实现这种品味的能力。
高级语言使得程序更具有可移植性。编译器不是高级语言唯一的实现方法,另一种方法是使用解释器,它的作用是实时地将代码解释为相应的机器语言,然后一行行运行。相比之下,编译器则是先将整个程序全部翻译成机器语言,然后再运行。
我们一直被教育编程应该面向对象,然而作者却有着自己的看法。有好有坏。 任何一种编程语言都可以分成两大组成部分:基本运算符的集合(扮演公理的角色)以及除运算符以外的其他部分(原则上,这个部分可以用基本运算符表达出来)。基本运算符是一种语言能否长期存在的最重要因素。慎重选择公理还不够,还必须控制它的规模。那些内核最小、最干净的编程语言才会存在于进化的主干上。一种语言的内核设计得越小、越干净,它的生命力就越顽强。浪费可以分成好的浪费和坏的浪费好的浪费,即用更多的钱得到更简单的设计。正确提高效率的做法应该是将语言的语义与语言的实现予以分离。在语义上不需要同时存在列表和字符串,单单列表就够了。而在实现上做好编译器优化,使它在必要时把字符串作为连续字节的形式处理。
语言设计时,对实现方式少作限制还会使得程序具备更大的灵活性。未来,并行计算。性能分析器将变得越来越重要。应用软件运行速度提升的关键在于有一个好的性能分析器帮助指导程序开发。现在,两个观点:(1)一百年后的编程语言在理论上今天就能设计出来;(2)如果今天真能设计出这样一种语言,很可能现在就适合编程,并且能够产生更好的结果。如果我们把这两个观点联系起来,那就得出了一些有趣的可能性。
从Python和Java入手,因为它们比较容易学。想当高级一点的黑客,还应该学习C和Perl。前者用来对付Unix系统,后者用来系统管理和开发CGI脚本。最后,真正非常严肃地把黑客作为人生目标的人,应该考虑学习Lisp:Lisp很值得学习。你掌握它以后,会感到它给你带来的极大启发。这会大大提高你的编程水平,使你成为一个更好的程序员。尽管在实际工作中极少会用到Lisp。
大公司可以互相模仿,但是创业公司就不行。我觉得很多人没有意识到这一点,尤其是一些创业者。Lisp语言的好处不在于它有一些狂热爱好者才明白的优点,而只在于它是目前最强大的编程语言。它没有得到广泛使用的原因就是因为编程语言不仅仅是技术,也是一种习惯性思维,非常难于改变。
经理:(a)对技术一无所知;(b)对技术有强烈的个人观点。作者用程序员时常的矛盾对立面产品经理来调侃,再次说明不同的编程语言之间有着很大的差异。Lisp和Fortran代表了编程语言发展的两大方向。前者的基础是数学,后者的基础是硬件架构。
Lisp之所以独特,因为它诞生的时候就包含了9种新思想。其中一些我们今天已经习以为常,另一些则刚刚在其他高级语言中出现,至今还有2种是Lisp独有的。
(1) 条件结构(即if-then-else结构)。现在大家都觉得这是理所当然的,但是Fortran I就没有这个结构,它只有基于底层机器指令的goto结构。
(2) 函数也是一种数据类型。在Lisp语言中,函数与整数或字符串一样,也属于数据类型的一种。它有自己的字面表示形式(literal representation),能够存储在变量中,也能当作参数传递。一种数据类型应该有的功能,它都有。
(3) 递归。Lisp是第一种支持递归函数的高级语言^。
(4) 变量的动态类型。在Lisp语言中,所有变量实际上都是指针,所指向的值有类型之分,而变量本身没有。复制变量就相当于复制指针,而不是复制它们指向的数据。
(5) 垃圾回收机制。
(6) 程序由表达式组成。Lisp程序是一些表达式树的集合,每个表达式都返回一个值。这与Fortran和大多数后来的语言都截然不同,它们的程序由表达式和语句组成。
(7) 符号类型。符号实际上是一种指针,指向存储在散列表中的字符串。所以,比较两个符号是否相等,只要看它们的指针是否一样就行了,不用逐个字符地比较。
(8) 代码使用符号和常量组成的树形表示法。
(9) 无论什么时候,整个语言都是可用的。Lisp并不真正区分读取期、编译期和运行期。你可以在读取期编译或运行代码,也可以在编译期读取或运行代码,还可以在运行期读取或者编译代码。
「如果你不想让经理发现你正在使用Lisp编程,你可以告诉他你用的是XML。」(哈哈哈哈哈)说Lisp语言古怪倒不是因为它的语法很古怪,而是因为它根本没有语法,程序直接以解析树(parse tree)的形式表达出来。在其他语言中,这种形式只是经过解析在后台产生,但是Lisp直接采用它作为表达形式。它由列表构成,而列表则是Lisp的基本数据结构。
使用一种不常用的技术也有代价:你的程序可能无法很好地与使用其他语言写的程序协同工作;你可能找不到很多函数库;你可能不容易雇到程序员。当然随大流也要付出代价。
衡量语言的编程能力的最简单方法可能就是看代码数量。所谓高级语言,就是能够提供更强大抽象能力的语言,因此,语言的编程能力越强大,写出来的程序就越短(当然不是指字符数量,而是指独立的语法单位)。(这本书一直提到《人月神话》啊,看看看)
第一,不同语言的编程能力不一样。第二,大多数经理故意忽视第一点。你把这两点事实结合起来,其实就得到了赚钱的诀窍。
如果你想解决一个困难的问题,关键不是你使用的语言是否强大,而是好几个因素同时发挥作用:(a)使用一种强大的语言;(b)为这个难题写一个事实上的解释器;或者(c)你自己变成这个难题的人肉编译器。
这种实践不仅很普遍,而且已经制度化了。举例来说,在面向对象编程的世界中,我们大量听到“模式”(pattern)当我在自己的程序中发现用到了模式,我觉得这就表明某个地方出错了。(作者在文章中质疑了pattern)
靠谱的新语言,可以从各方各面来提高效率:脚本语言、免费、简洁、可编程性、一次性、丰富多样的函数库……
简洁性最重要的方面就是要使得语言更抽象。为了达到这一点,首先你设计的必须是高级语言,然后把它设计得越抽象越好。简洁性是静态类型语言的力所不及之处。“整洁”的意思是设计得很清楚,内核由数量不多的运算符构成,这些运算符易于理解,每一个都有很完整的独立用途。“混乱”的意思是它允许黑客以自己的方式使用。所谓一次性程序,就是指为了完成某些很简单的临时性任务而在很短时间内写出来的程序。开发大型程序的另一个方法就是从一次性程序开始,然后不断地改进。这种方法比较不会让人望而生畏,程序在不断的开发之中逐渐进步。如果你想设计一种适合开发大型项目的编程语言,就必须使得这种语言也适合开发一次性程序,因为大型项目就是从一次性程序演变而来的。很容易装备不仅仅指很容易安装或者已经安装,还指很容易与使用者互动。一种有命令行界面、可以实时反馈的语言就具有互动性。
所以,编程时提高代码运行速度的关键是使用好的性能分析器(profiler),它自动告诉程序员每个部分的性能,而不是非要等到程序员手动运行后才能知道, 性能分析器甚至有可能自动找出不合理的算法。没有必要每个函数的每个参数类型都声明清楚,你只需要在瓶颈处声明清楚参数类型就可以了。
越来越多的程序主要不是受限于计算机的运算速度,而是受限于I/O的速度。加快I/O速度将是很值得做的一件事。编程语言也能起到作用比如采用简洁、快速、格式化输出的函数,比如采用缓存和持久化对象。用户关心的是反应时间,但是软件的另一种效率正在变得越来越重要,那就是每个处理器能够同时支持的用户数量。 编程语言在这方面也能发挥作用,对线程的良好支持将使得所有用户共享同一个内存堆。持久化对象和语言内核级别的延迟加载支持也有助于减少内存需求。
当然一种编程语言要想变得流行,最后一关就是要经受住时间的考验。 为了写出优秀软件,你必须同时具备两种互相冲突的信念。一方面,你要像初生牛犊一样,对自己的能力信心万丈;另一方面,你又要像历经沧桑的老人一样,对自己的能力抱着怀疑态度。在你的大脑中,有一个声音说“千难万险只等闲”,还有一个声音却说“早岁哪知世事艰”。不能停滞不前,要时刻保持怀疑
用户是一把双刃剑。他们推动语言的发展,但也使得你不敢对语言进行大规模改造。所以,一开始的时候要精心选择用户,避免使用者过快增长。
梦寐以求的编程语言(就是新的语言):
这种语言干净简练,具有最高层次的抽象和互动性,容易装备,只用很少的代码就解决常见的问题。不管是什么程序,你真正要写的代码几乎都与你自己的特定设置有关,其他具有普遍性的问题都有现成的函数库可以调用。
这种语言的句法短到令人生疑。
这种语言的抽象程度很高,使得你可以快速写出一个程序的原型。
这种语言有大量优秀的范例可供学习,而且非常符合直觉,你只需花几分钟阅读范例就能领会应该如何使用此种语言。你偶尔才需要查阅操作手册,它本身很薄,里面关于限定条件和例外情况的警告寥寥无几。
这种语言的内核很小,但很强大。各个函数库高度独立,而且和内核一样经过精心设计,它们都能很好地协同工作。语言的每个部分就像精密照相机的各种零件一样完美契合,不需要为了兼容性问题放弃或者保留某些功能。所有函数库的源码都很容易得到。这种语言能够很轻松地与操作系统和用其他语言开发的应用裎序对话。
这种语言以层的方式构建。较高的抽象层透明地构建在较低的抽象层之上。如果需要的话,你可以直接使用较低的抽象层。
除了一些绝对必要隐藏的东西,这种语言的所有细节对使用者都是透明的。它提供的抽象能力只是为了方便你的开发,而不是为了强迫你按照它的方式行事。事实上,它鼓励你参与它的设计,给你提供与语言创造者平等的权力。你能够对它的任何部分加以改变,甚至包括它的语法。它尽可能让你自己定义的部分与它本身定义的部分处于同等地位。这种梦幻般的编程语言不仅开放源码,更开放自身的设计。
设计与研究的区别看来就在于,前者追求“好”(good),后者追求“新”(new)。优秀的设计不一定很“新”,但必须是“好”的;优秀的研究不一定很“好”,但必须是“新”的。只有应用“新”的创意和理论,才会诞生超越前人的最佳设计;只有解决那些值得解决的难题(也就是“好”的难题),才会诞生最佳研究。做“用户需要的设计”,而不是“用户要求的设计”。需求和要求不同。
关注用户,并且以用户为中心。这里的“用户”并不是指所有普罗大众。指目标用户。如果目标用户群体涵盖了设计师本人,那么最有可能诞生优秀设计。为了做出优秀的设计,你必须贴近用户,始终寸步不离,永远站在用户的角度调整自己的构想。在软件领域,贴近用户的设计思想被归纳为“弱即是强”(Worse is Better)模式。那就是如果你正在设计某种新东西,就应该尽快拿出原型,听取用户的意见。
与之对照,还有另一种软件设计思想,也许可以被称为“万福玛丽亚”模式。它的观点是你应该等到完整的成品出来以后再一下子隆重地推向市场,就像圣母玛丽亚降临一样,哪怕整个过程漫长得像橄揽球运动员长途奔袭、达阵得分也没有关系。它会让你自毁前程。另外士气是设计的关键因素。坚信自己能成功。先做出原型,再逐步加工做出成品,这种方式有利于鼓舞士气,因为它使得你随时都可以看到工作的成效。
——————————————————————————————————————————————————————————
感谢你能看到最后,附上YC《如何创业》课程的粗糙笔记:
http://www.cnblogs.com/jisijie/p/5030661.html