保罗格雷厄姆,美国程序员、危险投资家、博客作者和技能作家。他以Lisp方面的工作而闻名,也是最早的Web运用Viaweb的创办者之一,后来被雅虎以美金5千万余元收购,成为Yahoo Store,后共同创办了具有影响力的创业加速器和种子资本公司Y Combinator。

在保罗眼里,黑客是创作者,是互联网之子,拥有一颗不安分的心,虽然经常被视为书呆子,却以自己的尽力,为互联网新世界奠基。毫无疑问,咱们日子于其间的世界,现已且必将持续被黑客深刻地改动,因而,了解黑客,咱们也会更了解这个世界

黑客精神在咱们这个时代主要经过数字化、软件和代码开发来完结。黑客一开始其实仅仅以软件为主,后来延伸到硬件,并逐渐拓展到其他创新范畴。人类前史现已进入了数字化时代,这一时代是前史的长河,是人道的延伸,是势不行当的长时刻趋势。

《黑客与画家》这本书自上市以来影响了许多互联网人,被其思维影响的人不行胜数,至今畅销了15万册。一本好的书,其间的思维是永不过期的。

来源 | 黑客与画家(10万册纪念版)

作者 | [美]保罗格雷厄姆(Paul Graham)

译者:阮一峰


挑选编程言语进化的骨干

我以为,编程言语就像生物物种相同,存在一个进化的头绪,许许多多分支终究都会成为进化的死胡同。这种现象现已发生了。Cobol言语从前盛行一时,可是现在看来没有任何后续言语继承它的思维。 它就像尼安德特人相同,进化之路现已走到了止境。

我预言Java也会如此。有人写信说:“你怎样能说Java不会成功呢?它现已成功了。”我觉得这要看你的成功标准是什么。假如标准是相关书本的出书量,或许是信任学会Java就能找到工作的大学生数量,那么Java的确现已成功了。当我说Java不会成功时,我的意思是它和Cobol相同,进化之路现已走到了止境。

这仅仅我的猜想,未必正确。这里的重点不是看衰Java,而是提出编程言语存在一个进化的头绪,然后引导读者思考,在整个进化过程中,某一种言语的位置究竟在哪里?之所以要问这个问题,不是为了一百年后让后人感叹咱们从前如此英明,而是为了找到进化的骨干。它会启发咱们去挑选那些接近骨干的言语,这样对当时的编程最有利。

不论何时,挑选进化的骨干或许都是最佳方案。 要是你不幸选错了,变成了一个尼安德特人,那就太糟了。你的对手克鲁马努人时不时就会来攻打你,把你的食物悉数偷走。

这便是我想找出一百年后的编程言语的原因。我不愿意押错赌注。

编程言语的聚合

编程言语的进化与生物学进化仍是有差异的,由于不同分支的言语会发生聚合。比方,Fortran分支看来正在与Algol的继承者聚合。理论上,不同的生物物种也或许发生聚合,可是或许性很低,所以大约从来没有真实呈现过。

编程言语之所以或许呈现聚合,一个原因是它的概率空间比较小,另一个原因是它的突变不是随机的。言语的规划者们总是有意识地借鉴其他言语的规划思维。

关于言语规划者来说,认清编程言语的进化途径特别有用,由于这样就能够照着姿态规划言语了。 这时,认清进化的骨干就不只要助于识别现存的优异言语,还能够把它当作规划言语的攻略。

挑选内核最小、最洁净的编程言语

任何一种编程言语都能够分红两大组成部分:根本运算符的调集(扮演正义的人物)以及除运算符以外的其他部分(原则上,这个部分能够用根本运算符表达出来)。

我以为,根本运算符是一种言语能否长时刻存在的最重要要素。 其他要素都不是决定性的。这有点像买房子的时分你应该先考虑地理位置。别的当地将来出问题都有办法弥补,可是地理位置是无法变的。

稳重挑选正义还不够,还有必要控制它的规划。 数学家总是觉得正义越少越好,我觉得他们说到了点子上。

你细心审视一种言语的内核,考虑哪些部分能够被摒弃,这至少也是一种很有用的训练。在长时刻的职业生涯中,我发现冗余的代码会导致更多冗余的代码,不只软件如此,而且像我这样性格懒散的人,我发现在床底下和房间的角落里这个命题也建立,一件废物会发生更多的废物。

我的判别是,那些内核最小、最洁净的编程言语才会存在于进化的骨干上。 一种言语的内核规划得越小、越洁净,它的生命力就越顽强。

当然,猜想一百年后人们运用什么编程言语,这自身便是一个很大的假定。或许一百年后人类现已不编程了,或许直接告诉计算机想做什么,计算机就会自动完结。

不过,到现在为止,计算机智能并没有获得太大开展。我猜想一百年后,人们仍是运用与现在差不多的程序指挥计算机。或许有一些咱们今日需要编程处理的问题,那时现已不需要编程了,可是我想,那时还会存在许多与今日相同的编程任务。

你或许以为只要那些自以为是的人才会去预言一百年后的技能。可是,请不要忘记,软件开展的前史现已走过了50年。在这50年中,编程言语的进化其实是十分缓慢的,因而展望一百年后的言语并不是虚无缥缈的主意。

编程言语进化缓慢的原因在于它们并不是真实的技能。言语仅仅一种书写法,而程序则是一种严厉契合规矩的描绘,以书面方法记录计算机应该怎么处理你的问题。所以,编程言语的进化速度更像数学符号的进化速度,而不像真实的技能(比方交通或通信技能)的进化速度。数学符号的进化是缓慢的突变式变化,而不是真实技能的那种跳跃式开展。

不论一百年后的计算机是什么姿态,咱们根本上能够判定它们的运转速度一定会快得多。假如摩尔定律依然建立,一百年后计算机的运转速度将是现在的74乘以10的18次方倍(准确地说是73786976294838206464倍)。真是让人难以幻想。不过实际上更现实的猜测并不是速度会进步这么多,而是摩尔定律终究将不建立。不论是什么东西,假如每18个月就增长一倍,那么最终很或许会到达极限。但那时的计算机比现在快得多大约是毫无疑问的。即便最终仅仅略微快了100万倍,也将实质性地改动编程的根本规矩。假如其他条件不变,现在被以为运转速度慢的言语(即运转的功率不高)将来会有更大的开展空间。

那时,依然会有对运转速度要求很高的运用程序。咱们期望计算机处理的有些问题其实是计算机自身引起的。比方,计算机处理视频的速度取决于生成这些视频的另一台计算机。此外,还有一些问题自身就要求无限快的处理才干,比方图画烘托、加密/解密、模拟运算等。

既然在现实中一些运用程序自身的功率较低,而另一些运用程序会耗尽硬件供给的所有运算才干,那么有了更快速的计算机就意味着编程言语不得不敷衍更多的极点情况,涵盖更大规模的功率要求。 咱们现已看到这种情况发生了。要是以几十年前的标准衡量,有一些运用新言语开发的热门运用程序对硬件资源的糟蹋十分惊人。

不只编程言语有这种现象,这实际上是一种遍及的前史趋势。跟着技能的开展,每一代人都在做上一代人觉得很糟蹋的工作。30年前的人要是看到咱们今日如此随意地运用长途电话,一定会感到震惊。100年前的人要是看到一个普通的包裹居然也能享用一天内从波士顿发件、途经孟菲斯、抵达纽约的待遇,恐怕就要更震惊了。

论“糟蹋”

我现已猜测了,一旦未来硬件的功能大幅进步将会发生什么事。新添加的运算才干都会被糟蹋掉。

在我学习编程的时代,计算机仍是稀罕玩意儿。我记住其时运用的微机类型是TRS-80,它的内存只要4K,为了把BASIC程序装入内存,我不得不把源码中的空格悉数删除。我一想到那些极点低功率的软件、不断重复某些愚笨的运算、把硬件的计算才干悉数占用,就感到无法忍受。可是,我的这种反应是错的,我就像某个出身贫寒的穷孩子,一听到要花钱就舍不得,即便把钱用在重要场合(比方去医院治病)都觉得很难承受。

某些糟蹋的确令人厌恶。比方有人就很讨厌SUV(运动型多用途车),即便它选用可再生的清洁动力也改动不了观念,由于SUV来自一个令人厌恶的主意(怎么使得小货车看上去更有男子汉气魄)。可是,并非所有的糟蹋都是坏的。 既然现在的电信基础设施现已如此发达,再掐着时刻打长途电话就有点锱铢必较了。假如有满足的资源,你能够将长途电话和本地电话视为同一件事,全部会变得更轻松。

糟蹋能够分红好的糟蹋和坏的糟蹋。 我感兴趣的是好的糟蹋,即用更多的钱得到更简略的规划。所以,问题就变成了怎么才干充分利用新硬件更强壮的功能最有利地“糟蹋”它们?

对速度的追求是人类内心深处根深柢固的愿望。当你看着计算机这个小玩意儿,就会情不自禁地期望程序运转得越快越好,真的要下一番功夫才干把这种愿望抑制住。规划编程言语的时分,咱们应该有意识地问自己,什么时分能够抛弃一些功能,换来一点点便利性的进步。

正确的做法

许多数据结构存在的原因都与计算机的速度有关。比方,今日的许多言语都一起有字符串和列表。从语义上看,字符串或多或少能够了解成列表的一个子集,其间的每一个元素都是字符。那么,为什么还需要把字符串单列为一种数据类型呢?完全能够不这么做。字符串仅仅为了进步功率才存在的。可是,这种以加快运转速度为意图、却使得编程言语的语义大大复杂的行为,很不行取。编程言语设置字符串似乎便是一个过早优化的比方。

假如咱们把一种言语的内核幻想为一些根本正义的调集,那么仅仅为了进步功率就往内核添加剩余的正义,却没有带来表达才干的提高,这必定是一件很糟的事。 没错,功率是很重要,可是我以为修正言语规划并不是进步功率的正确办法。

正确做法应该是将言语的语义与言语的完结予以分离。 在语义上不需要一起存在列表和字符串,单单列表就够了。而在完结上做好编译器优化,使它在必要时把字符串作为连续字节的方法处理。

关于大多数程序,速度不是最关键的要素,所以你一般不需要操心考虑这种硬件层面上的微观管理。跟着计算机速度越来越快,这一点现已越发显着了。

功率低下≠烂

言语规划时,对完结方法少作约束还会使得程序具备更大的灵敏性。言语的标准发生变化不仅仅无法防止的,也是合理的。经过编译器的处理,依照从前标准开发的软件就会照常运转,这就供给了灵敏性。

essay(论文)这个词来自法语的动词essayer,意思是“试试看”。从这个原始含义来说,论文便是你写一篇文章,试着搞清楚某件事。软件也是如此。我觉得一些最好的软件就像论文相同,也便是说,当作者真实开始动手写这些软件的时分,他们其实不知道最终会写出什么结果。

Lisp言语的黑客早就明白数据结构灵敏性的价值。咱们写程序的第一版时,往往会把所有工作都用列表的方法处理。所以,这些最初版别或许功率低下得惊人,你有必要尽力抑制自己才干忍住不动手优化它们,这就如同吃牛排的时分有必要尽力抑制自己才干不去想牛排是从哪里来的相同,至少对我来说是这样的。

一百年后的程序员最需要的编程言语便是能够让你毫不费力地写出程序第一版的编程言语,哪怕它的功率低下得惊人(至少按咱们今日的眼光来看是如此)。他们会说,他们想要的便是很容易上手的编程言语。

功率低下的软件并不等于很烂的软件。 一种让程序员做无用功的言语才真实称得上很烂。糟蹋程序员的时刻而不是糟蹋机器的时刻才是真实的无功率。跟着计算机速度越来越快,这会变得越来越显着。

能否抛弃根本数据类型?

我觉得,抛弃字符串类型现已是咱们能够承受的主意了。Arc言语现已这样做了,看上去效果不错。从前用正则表达式很难描绘的一些操作,现在用回归函数能够表达得很简略。

这种数据结构的扁平化趋势会怎样开展?我极点尽力地幻想各种或许,得到的结果乃至令我自己都吓了一跳。比方,数组会不会消失?毕竟数组仅仅散列表的一个子集,其特色便是数组的键悉数都是整数向量。进一步说,散列表自身会不会被列表替代呢?

还有比这更惊人的预言。在逻辑上其实不需要对整数设置单独的表示法,由于能够把它们也看作列表,整数n能够用一个n元素的列表表示。这照样能完结数学运算,仅仅功率低得让人无法忍受。

编程言语会开展到抛弃根本数据类型之一的整数这一步吗? 我这样问并不是真的要你严肃思考这个问题,更多的是期望翻开你对未来的思路。我仅仅提出一种设想的情况:假如一股不行抵抗的力量遇到了一个不行移动的物体,会发生什么事。详细就本文而言:一种功率低得不行幻想的言语遇到了功能强壮得不行幻想的硬件,会发生什么事。 我看不出抛弃整数类型有什么不妥。未来相当漫长。假如咱们想要削减言语内核中根本正义的数目,无妨把眼光放得远一点,想一想假如时刻变量t趋向无限会怎样样。一百年是一个很好的参考方针,假如你觉得某个主意在一百年后依然或许是难以令人承受,那么或许一千年后它也依然难以令人承受。

让我说清楚,我的意思不是说所有的整数运算都用列表来完结,而是说言语的内核(不涉及任何编译器的完结)能够这样界说。在现实中,任何进行数学运算的程序或许都是以二进制方法表示数字,可是这归于编译器的优化,而不归于言语内核语义的一部分。

另一种消耗硬件功能的办法便是,在运用软件与硬件之间设置许多的软件层。这也是咱们现已看到的一种趋势,许多新兴的言语就被编译成字节码。比尔伍兹从前对我说,根据经验判别,每添加一个解说层,软件的运转速度就会慢一个数量级。可是,剩余的软件层能够让编程灵敏起来。

Arc言语最初的版别便是一个极点的比方,它的层许多,运转速度十分慢,可是的确带来了相应的好处。Arc是一个典型的“元循环”解说器,在CommonLisp的基础上开发,很像约翰麦卡锡在他经典的Lisp论文中界说的eval函数。Arc解说器总共只要几百行代码,所以很便于了解和修正。咱们选用的Common Lisp版别是CLisp,它自身是在另一个字节码解说器的基础上开发的。所以,咱们总共有两层解说器,最上面那层功率低下得惊人,可是言语自身是能用的。我供认仅仅勉强可用,可是的确能用。

运用多层方法开发

即便是运用程序,运用多层方法开发也是一种很强壮的技巧。自下而上的编程办法意味着要把软件分红好几层,每一层都能够充任它上面那一层的开发言语。这种办法往往会发生更小、更灵敏的程序。它也是通往软件圣杯——可重用性——的最佳道路。从界说上看,言语便是能够重用的。在编程言语的协助下,你的运用程序越是选用这种多层方法开发,它的可重用性就越好。

可重用性这个概念多多少少与20世纪80时代鼓起的面向对象编程有些关联。不论怎样寻觅依据,也不或许把这两件事完全分隔。某些运用面向对象编程开发出来的软件的确具有可重用性,但这不是由于它运用了面向对象编程,而是由于它的开发办法是自下而上的。以函数库为例,它们具有可重用性,是由于它们归于言语的一部分,而不是由于它们选用面向对象或许其他编程办法。

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

谈谈并行计算

既然是谈论未来,最好谈谈并行计算,由于看上去并行计算如同便是为未来而存在的。不论怎样想,并行计算似乎都是未来日子的一部分。

它会在未来完结吗?曩昔二十年,人们都在说并行计算立刻就会来临。可是,到现在为止,它对编程实践并没有太大影响。这是真的吗?芯片规划师现已不得不把它考虑在内,为多CPU计算机开发系统软件的程序员也是如此。

可是,真实的问题在于,并行计算究竟能到达哪个抽象层次?一百年后它就会影响到开发运用软件的程序员吗?或许,它还仅仅编译器作者需要考虑的工作,在运用软件的代码中根本就无处寻觅?

一种或许是,大多数能够用到并行计算的场合,人们都会抛弃运用并行计算。虽然我总的猜测是未来的软件会挥霍掉大部分新增的硬件功能,可是并行计算是一个特例。我估量跟着硬件功能得到惊人的提高,假如你明确地说想要并行计算,那么必定能够得到它,可是一般情况下你不会用到它。 这意味着,除了一些特殊的运用程序,一百年后的并行计算不会是那种大规划的并行计算。我意料,关于普通程序员来说,全部更像对进程进行复制,然后让多个进程在后台并行运转。

这是编程进行到很后期才要做的工作,归于对程序的优化,类似于你想开发一种特定的数据结构来替代现有的数据结构。程序的第一个版别一般会疏忽并行计算供给的各种好处,就如同编程开始时会疏忽某种特定的数据结构给你带来的好处相同。

除了某些特定的运用软件,一百年后,并行计算不会很盛行。假如运用软件真的许多运用并行计算,这就归于过早优化了。

一百年后的言语数目

一百年后会有多少种编程言语?从最近来看,呈现了许多的新言语。硬件功能进步是一个原因,这就允许程序员根据运用意图在运转速度和编程便利性之间做出不同的取舍。假如这便是未来的趋势,那么一百年后强壮的硬件只会使得言语数目变得更多。

可是,另一方面,一百年后的常用言语或许只要很少几种。 部分原因是基于我的乐观主义,我信任在未来,假如你的著作的确很超卓,你或许挑选的是一种开发起来很便利的言语。运用这种言语写出来的软件第一版的运转速度很慢,只要对编译器进行优化设置后运转速度才会提高。既然我抱有这种乐观主义,那么我还要做一个预言。有些言语能够到达机器的最高功率,另一些言语的功率则慢到刚刚能够运转而已,两者之间存在巨大的距离。我预言一百年后,这段距离之间的各个点上都会有对应的编程言语存在。

由于这段距离正在变得越来越大,所以功能剖析器将变得越来越重要。现在,功能剖析并没有受到重视。许多人如同依然信任,程序运转速度提高的关键在于开发出能够生成更快速代码的编译器。代码功率与机器功能的距离正在不断加大,咱们将会越来越清楚地看到,运用软件运转速度提高的关键在于有一个好的功能剖析器协助指导程序开发。

我说将来或许只要很少几种常用言语,但没有把用于特定范畴的“小众言语”算进去。我觉得,这些嵌入式言语的主意很不错,一定会蓬勃开展。可是我判别这些“小众言语”会被规划成相当薄的一层,使得用户能够一眼看出在底下作为基础的通用型言语,这样就削减了学习时刻,降低了运用本钱。

谁来规划这些未来的言语?曩昔10年最激动人心的趋势之一便是开源言语的崛起,比方Perl、Python和Ruby。言语规划现已被黑客接管。到现在为止这样究竟是好是坏还看不清楚,可是开展势头令人鼓舞。比方,Perl就有一些绝妙的创新。不过,它也包含了一些很糟糕的主意。关于一种充溢进取心、斗胆探究的言语来说,这也是很正常的事。以它现在这种变化的速率,大约只要天主才知道一百年后Perl会变成什么样。

有一句俗话说,假如你自己做不到,那就去当教师。这在言语规划范畴不建立,我知道的一些最超卓的黑客就在当教授。可是,当教师的人的确有许多工作不能做。研讨性职位给黑客带来了一些约束。在任何学术范畴,都有一些标题是能够做的,另一些标题是不能够做的。不幸的是,这两类题意图差异一般取决于它们写成论文后看上去是不是很深邃,而不是取决于它们对软件业的开展是否重要。最极点的比方或许便是文学,文学研讨者的任何效果几乎对文学创作者都毫无影响。

虽然科学范畴的情况要稍好一点,可是研讨者能够做的标题与能够对规划优异言语有所协助的标题之间的交集小得令人沮丧。比方,研讨变量类型的论文如同多得无穷无尽,虽然事实上静态类型言语看来无法真实支持宏(在我看来,一种言语不支持宏,那就不值得运用了)。

新言语更多地以开源项意图方法呈现,而不是以研讨性项意图方法呈现。这是言语的一种开展趋势。另一种开展趋势是,新言语的规划者更多的是自身就需要运用它们的运用软件作者,而不是编译器作者。 这似乎是好的趋势,我等待它持续坚持下去。

摆脱思维定式

一百年后的物理学根本上不或许猜测。可是计算机言语不相同,现在就动手规划一种一百年后能够招引运用者的新言语,这在理论上似乎是或许的。

规划新言语的办法之一便是直接写下你想写的程序,不论编译器是否存在,也不论有没有支持它的硬件。 这便是假定存在无限的资源供你分配。不论是今日仍是一百年后,这样的假定如同都是有道理的。

你应该写什么程序?随意什么,只要能让你最省力地写出来就行。可是要注意,这有必要是在你的思维没有被当时运用的编程言语影响的情况下。 这种影响无处不在,有必要很尽力才干克服。你或许觉得,关于人类这样懒散的生物,喜爱用最省力的方法写程序是再天然不过的工作。可是事实上,咱们的思维或许往往会受限于某种现存的言语,只选用在这种言语看来更简略的方法,它对咱们思维的束缚效果会大得令人震惊。新言语有必要靠你自己去发现,不能依托那些让你天然而然就沉下去的思维定势。

把程序写得简洁

选用程序的长度作为它消耗工作量的近似方针是个很有用的技巧。这里的程序长度当然不是指字符的数量,而是指各种句法元素的总长度,根本上便是整个解析树的大小。或许不能说最短的程序便是写起来最省力的程序,可是当你专心想把程序写得简洁而不是松松垮垮时,你就更接近省力这个方针,你的日子也会变得好过得多。所以,规划言语的正确做法就变成了,看着一段程序,然后问自己是不是能把它写得更短一点?

实际上,用幻想出来的一种一百年后的言语来写程序,这件工作的可靠程度,取决于你对言语内核的估量是否满足正确。 惯例的排序,你现在就能够写出来。可是,想要猜测一百年后的言语运用什么函数库就很难了。很或许许多函数库针对的范畴现在还根本不存在。比方,假如SETI@home方案成功,咱们就需要与外星人联络的函数库了。当然,假如外星人的文明高度发达,现已到了用XML格式交换信息的境地,那就不需要新的函数库了。

另一个极点是,我觉得今日你就能规划出一百年后的言语内核。 事实上,在有些人看来,大部分言语内核在1958年就现已规划出来了。

今日的你愿意运用100年后的言语吗?

假现在日就能运用一百年后的编程言语,咱们会用它编程吗?观古而知今。假如1960年就能运用今日的编程言语,那时的人们会用它们吗?

在某些方面,回答是否定的。今日的编程言语依靠的硬件在1960年并不存在。比方,Python这样的言语,正确的缩进在编写时很重要,可是1960年的计算机没有显示器,只要打印机终端,所以编写起来就不会很顺畅。

可是,假如把这些要素排除在外(你能够假定,咱们只在纸上编程),20世纪60时代的程序员会喜爱用现在的言语编程吗?

我想他们会的。某些缺少幻想力、深受早期编程言语思维影响的人或许会觉得不或许。(没有指针运算,怎么复制数据?没有goto句子,怎么完结流程图?)可是我想,那时最聪明的程序员一定能轻松地运用今日的大多数言语,假定他们能得到的话。

假如咱们现在就能拥有一百年后的编程言语,那就至少能用来写出优异的伪码。 咱们会用它开发软件吗?由于一百年后的编程言语需要为某些运用程序生成快速代码,所以很或许它生成的代码能够在咱们的硬件上运转,速度也还能够承受。相比一百年后的用户,咱们或许不得不对这种言语做更多的优化,可是总的来看,它应该依然会为咱们带来净收益。

现在就测验去写吧!

现在,咱们的两个观念便是: (1)一百年后的编程言语在理论上今日就能规划出来;(2)假现在日真能规划出这样一种言语,很或许现在就适合编程,而且能够发生更好的结果。 假如咱们把这两个观念联络起来,那就得出了一些风趣的或许性。为什么不现在就动手测验写出一百年后的编程言语呢?

当你规划言语的时分,心里牢牢记住这个方针是有好处的。学习开车的时分,一个需要记住的原则便是要把车开直,不是经过将车身对齐画在地上的分隔线,而是经过瞄准远处的某个点。即便你的方针只在几米开外,这样做也是正确的。我以为,规划编程言语时,咱们也应该这样做。

引荐阅览

论程序员思维的重要性

《黑客与画家(10万册纪念版)》

[美]保罗格雷厄姆(Paul Graham) |著

阮一峰 | 译

有效的思考方法,才是你最强壮的兵器,透过黑客与画家的视角,与聪明的脑筋对话,了解为何聪明人和咱们想得不相同

硅谷创业教父保罗格雷厄姆畅销近20年的思维经典,豆瓣图书TOP250,超越4万人想读

奇绩创坛创始人兼CEO陆奇作序引荐,王小川、吴声、罗振宇、姬十三、蒋涛、采铜、成甲、阳志平、林恒毅、冯大辉、池建强、方军、李卓桓、高庆一联合引荐