用十年来学编程 — Peter Norvig

March 30th, 2010

为什么每个人都急不可耐?

走进任何一家书店,你会看见《Teach Yourself Java in 7 Days》(7天Java无师自通)的旁边是一长排看不到尽头的类似书籍,它们要教会你Visual Basic、Windows、Internet等等,而只需要几天甚至几小时。我在Amazon.com上进行了如下搜索:

pubdate: after 1992 and title: days and (title: learn or title: teach yourself)
出版日期:1992年后 and 书名:天 and (书名:学会 or 书名:无师自通)

我一共得到了248个搜索结果。前面的78个是计算机书籍(第79个是《Learn Bengali in 30 days》,30天学会孟加拉语)。我把关键词“days”换成“hours”,得到了非常相似的结果:这次有253本书,头77本是计算机书籍,第78本是《Teach Yourself Grammar and Style in 24 Hours》(24小时学会文法和文体)。头200本书中,有96%是计算机书籍。
结论是,要么是人们非常急于学会计算机,要么就是不知道为什么计算机惊人地简单,比任何东西都容易学会。没有一本书是要在几天里教会人们欣赏贝多芬或者量子物理学,甚至怎样给狗打扮。在《How to Design Programs》这本书里说“Bad programming is easy. Idiots can learn it in 21 days, even if they are dummies.” (坏的程序是很容易的,就算他们是哑巴,白痴都可以在21天内学会。)

让我们来分析一下像《Learn C++ in Three Days》(3天学会C++)这样的题目到底是什么意思:

  • 学会:在3天时间里,你不够时间写一些有意义的程序,并从它们的失败与成功中学习。你不够时间跟一些有经验的程序员一起工作,你不会知道在C++那样的环境中是什么滋味。简而言之,没有足够的时间让你学到很多东西。所以这些书谈论的只是表面上的精通,而非深入的理解。如Alexander Pope(英国诗人、作家,1688-1744)所言,一知半解是危险的(a little learning is a dangerous thing)。
  • C++:在3天时间里你可以学会C++的语法(如果你已经会一门类似的语言),但你无法学到多少如何运用这些语法。简而言之,如果你是,比如说一个Basic程序员,你可以学会用C++语法写出Basic风格的程序,但你学不到C++真正的优点(和缺点)。那关键在哪里?Alan Perlis(ACM第一任主席,图灵奖得主,1922-1990)曾经说过:“如果一门语言不能影响你对编程的想法,那它就不值得去学”。另一种观点是,有时候你不得不学一点C++(更可能是javascript和Flash Flex之类)的皮毛,因为你需要接触现有的工具,用来完成特定的任务。但此时你不是在学习如何编程,你是在学习如何完成任务。
  • 3天:不幸的是,这是不够的,正如下一节所言。
  • 10年学编程

    一些研究者(Bloom (1985), Bryan & Harter (1899), Hayes (1989), Simmon & Chase (1973))的研究表明,在许多领域,都需要大约10年时间才能培养出专业技能,包括国际象棋、作曲、绘画、钢琴、游泳、网球,以及神经心理学和拓扑学的研究。似乎并不存在真正的捷径:即使是莫扎特,他4岁就显露出音乐天才,在他写出世界级的音乐之前仍然用了超过13年时间。再看另一种音乐类型的披头士,他们似乎是在1964年的Ed Sullivan节目中突然冒头的。但其实他们从1957年就开始表演了,即使他们很早就显示出了巨大的吸引力,他们第一次真正的成功Sgt. Peppers也要到1967年才发行。Malcolm Gladwell研究报告称,把在伯林音乐学院学生一个班的学生按水平分成高中低,然后问他们对音乐练习花了多少工夫:

    在这三个小组中的每一个人基本上都是从相同的时间开始练习的(在五岁的时候)。在开始的几年里,每个人都是每周练习2-3个小时。但是在八岁的时候,练习的强度开始显现差异。在这个班中水平最牛的人开始比别人练习得更多:在九岁的时候每周练习6个小时,十二岁的时候,每周8个小时,十四岁的时候每周16个小时,并在成长过程中练习得越来越多,到20岁的时候,其每周练习可超过30个小时。到了20岁,这些优秀者在其生命中练习音乐总共超过 10,000小时。与之对比,其它人只平均有8,000小时,而未来只能留校当老师的人仅仅是4,000小时。

    所以,这也许需要10,000小时,并不是十年,但这是一个magic number。Samuel Johnson(英国诗人)认为10年还是不够的:“任何领域的卓越成就都只能通过一生的努力来获得;稍低一点的代价也换不来。”(Excellence in any department can be attained only by the labor of a lifetime; it is not to be purchased at a lesser price.) 乔叟(Chaucer,英国诗人,1340-1400)也抱怨说:“生命如此短暂,掌握技艺却要如此长久。”(the lyf so short, the craft so long to lerne.)

    下面是我在编程这个行当里获得成功的处方:

  • 对编程感兴趣,因为乐趣而去编程。确定始终都能保持足够的乐趣,以致你能够将10年时间投入其中。
  • 跟其他程序员交谈;阅读其他程序。这比任何书籍或训练课程都更重要。
  • 编程。最好的学习是从实践中学习。用更加技术性的语言来讲,“个体在特定领域最高水平的表现不是作为长期的经验的结果而自动获得的,但即使是非常富有经验的个体也可以通过刻意的努力而提高其表现水平。”(p. 366),而且“最有效的学习要求为特定个体制定适当难度的任务,有意义的反馈,以及重复及改正错误的机会。”(p. 20-21)《Cognition in Practice: Mind, Mathematics, and Culture in Everyday Life》(在实践中认知:心智、数学和日常生活的文化)是关于这个观点的一本有趣的参考书。
  • 如果你愿意,在大学里花上4年时间(或者再花几年读研究生)。这能让你获得一些工作的入门资格,还能让你对此领域有更深入的理解,但如果你不喜欢进学校,(作出一点牺牲)你在工作中也同样能获得类似的经验。在任何情况下,单从书本上学习都是不够的。“计算机科学的教育不会让任何人成为内行的程序员,正如研究画笔和颜料不会让任何人成为内行的画家”, Eric Raymond,《The New Hacker’s Dictionary》(新黑客字典)的作者如是说。我曾经雇用过的最优秀的程序员之一仅有高中学历;但他创造出了许多伟大的软件(XEmacs, Mozilla),甚至有讨论他本人的新闻组,而且股票期权让他达到我无法企及的富有程度(译注:指Jamie Zawinski,Xemacs和Netscape的作者)。
  • 跟别的程序员一起完成项目。在一些项目中成为最好的程序员;在其他一些项目中当最差的一个。当你是最好的程序员时,你要测试自己领导项目的能力,并通过你的洞见鼓舞其他人。当你是最差的时候,你学习高手们在做些什么,以及他们不喜欢做什么(因为他们让你帮他们做那些事)。
  • 接手别的程序员完成项目。用心理解别人编写的程序。看看在没有最初的程序员在场的时候理解和修改程序需要些什么。想一想怎样设计你的程序才能让别人接手维护你的程序时更容易一些。
  • 学会至少半打编程语言。包括一门支持类抽象(class abstraction)的语言(如Java或C++),一门支持函数抽象(functional abstraction)的语言(如Lisp或ML),一门支持句法抽象(syntactic abstraction)的语言(如Lisp),一门支持说明性规约(declarative specification)的语言(如Prolog或C++模版),一门支持协程(coroutine)的语言(如Icon或Scheme),以及一门支持并行处理(parallelism)的语言(如Sisal)。
  • 记住在“计算机科学”这个词组里包含“计算机”这个词。了解你的计算机执行一条指令要多长时间,从内存中取一个word要多长时间(包括缓存命中和未命中的情况),从磁盘上读取连续的数据要多长时间,定位到磁盘上的新位置又要多长时间。(答案在这里
  • 尝试参与到一项语言标准化工作中。可以是ANSI C++委员会,也可以是决定自己团队的编码风格到底采用2个空格的缩进还是4个。不论是哪一种,你都可以学到在这门语言中到底人们喜欢些什么,他们有多喜欢,甚至有可能稍微了解为什么他们会有这样的感觉。
  • 拥有尽快从语言标准化工作中抽身的良好判断力。
  • 抱着这些想法,我很怀疑从书上到底能学到多少东西。在我第一个孩子出生前,我读完了所有“怎样……”的书,却仍然感到自己是个茫无头绪的新手。30个月后,我第二个孩子出生的时候,我重新拿起那些书来复习了吗?不。相反,我依靠我自己的经验,结果比专家写的几千页东西更有用更靠得住。

    Fred Brooks在他的短文《No Silver Bullets》(没有银弹)中确立了如何发现杰出的软件设计者的三步规划:

  • 尽早系统地识别出最好的设计者群体。
  • 指派一个事业上的导师负责有潜质的对象的发展,小心地帮他保持职业生涯的履历。
  • 让成长中的设计师们有机会互相影响,互相激励。
  • 这实际上是假定了有些人本身就具有成为杰出设计师的必要潜质;要做的只是引导他们前进。Alan Perlis说得更简洁:“每个人都可以被教授如何雕塑;而对米开朗基罗来说,能教给他的倒是怎样能够不去雕塑。杰出的程序员也一样”。

    所以尽管去买那些Java书;你很可能会从中找到些用处。但你的生活,或者你作为程序员的真正的专业技术,并不会因此在24小时、24天甚至24个月内发生真正的变化。

    英文原文:Teach Yourself Programming in Ten Years
    via:酷壳

    最华丽的冒险是与你相守

    January 13th, 2010


    这个成人童话在电影的前十分钟就似行板如歌般地铺展开来。老爷爷Carl与老奶奶Ellie小时候都是爱做探险梦的孩子,在一栋废弃的老屋里偶然相识。当时还只有那么一丁儿点大的奶奶跟同样只有那么一丁儿点大爷爷分享自己梦寐以求的探险目的地——那本她手工精心制作的”My Adventure Book”上贴着一张瀑布的图片。这个名叫“paradise fall”的瀑布传说在南美,正如其名,有着似乎只有天堂才能堪比的美。于是“去南美找天堂瀑”在两个娃心中仿佛成了今后人生的头等大事。说的容易,可南美到底是啥地方呢?“南美,大概就和美国差不多,只不过在南面吧。” 果然是小孩子呢。

    可忽儿间人就长大了,当年的两个小毛孩后来相爱结婚,搬进了最初偶遇时的那栋屋子。探险当然还是放不下的梦,于是她成了主题公园里南美景区的向导,而他则在离她不远的地方卖着气球。南美那个如仙境般的瀑布依然是魂牵梦萦的所在,于是两人开始有的没的往“天堂瀑基金”里存钱,期待着攒够旅费的那一天。可生活偏偏充满意外,今天汽车得换新轮胎,明天手臂受伤需要医治,“天堂瀑基金”总是在存满前被挪作他用。生活也有不随人愿的时候,如此想要孩子的两人却无法体会作他人父母的幸福。好在还有彼此,好在还能每日一起看浮云变幻夕阳斜下,还能并排坐在紧挨着的沙发上,只是执手,哪怕不语。年华就这样哗哗地在领带花纹、云朵形状和晚霞成色的日日更迭中流走,等回过神来的时候,两人都已经满头白发。

    他突然意识到,一辈子都快过完了,还没能和她去南美。于是下了决心,买了机票,准备在例行看夕阳的时候给她个惊喜,而此时的她却再也爬不上那个他们一同赏了几十年日落的山丘了。我上面罗罗嗦嗦的一大段,在电影里不过短短几分钟。这几分钟里没有一句台词,有的只是一个个再平凡不过的生活场景依次以柔和的暖色调呈现。有些地方的处理很含蓄,只是轻轻一点,没有说破,以至于最后画面上出现葬礼上老爷爷哀伤的身影时,坐在我旁边一个约摸还未上学的小女孩疑惑地问妈妈:“What happened?” 也是,这几分钟里包含的那么多细小又深沉的甜蜜与哀伤,小孩子如何明白得了。而看得懂的人,哪怕只是略懂如我,此时早已泪流满面。

    而之后那些在南美丛林乱石间的历险奇遇反倒不是我真正关心的了。尽管Russell胖嘟嘟的亚洲小孩脸让人很想捏一把,尽管神奇大鸟Kevin花里胡哨的外表很喜感,尽管那只一看就不像反派的金毛猎犬Dug也很讨人喜欢,却也无法掩盖这部分故事剧本的相对单薄。幸好Pixar在动画技术上做得很有诚意,我也倒看得津津有味。我迫切想知道的是Carl和Ellie的爱情童话最后会怎样收尾,Carl能否按照约定把房子安在瀑布边?做到了又怎样?他会释然吗?还是长久的心愿一了,反倒像失去信仰一样没了方向?

    Carl独自拖着渐行渐沉的屋子一步一步最终到达瀑布边的那一刻被处理得异常平淡,丝毫不见Disney惯用的个人英雄主义式渲染。他的脸上见不到梦想实现的欣喜,除了疲惫外似乎还有些怅然若失。他走进这座飞过了半个地球终于安然落地的房子,迎接他的是一屋狼藉。老人扶起夫妻俩曾经并排而坐的沙发,坐在自己的位子上,窗外就是梦寐以求的瀑布美景。一切就这么结束了?可为何目的地已到,而心结却好像仍未解开?Carl找出Ellie小时候珍爱的那本”My Adventure Book”,过了一辈子的时间,这本探险日志终于来到了它本该来的地方,可日志的主人却已不在。老人的手抚过日志的一页页,最终停在写着“Things I am going to do”的那页。那是儿时Ellie的稚嫩笔迹,那时帅气如假小子的她曾扬言要将余下的日志全用来记录在南美的探险奇遇。 Carl抚过那行字的手似乎透着愧疚,也许就是因为与自己在生活的琐碎中蹉跎一生,才使得这本日志的后半永远无法被填满吧。

    而之后Carl所翻见的,却出乎他也出乎了我的意料。原来这本日志的后半并非空白,而是被Ellie贴上了一页页的照片。当这些电影最开头出现过的生活片段以一个个凝固的瞬间重现时,我再次像傻瓜一样流泪到不能自己。

    而这次,我并非唏嘘两人天人永隔,而是被Ellie那份深沉的爱所打动。在最后的照片上,已经成为老奶奶的Ellie坐在窗边,屋外的暖阳在她的侧脸上投下柔和的光影。我在想,爱上一个人究竟有怎样强大的力量,能让曾经那个留着爆炸头,大大咧咧,一刻不安生的假小子成为现在这个容颜安详平和,满脸洋溢着幸福和满足的老人。其实她早就悟出来了吧:如果说去旅行去冒险是为了遇见不曾见过的美妙景色,经历不曾想过的充实人生,那么与你的相遇相守就是我能想到的最华丽的冒险。 也许正是因为如此,她才能在日志的最后一页留下那句 “Thanks for the adventures.”

    很多人把Up的关键词定为“梦想”, 而在我看来这个故事的关键词应该是“牵绊”。在我看的众多日剧日影里,这个词常被用来形容一种类似缘分又类似感情纠葛的人间关系,总之就是因为某个事物或机缘,使两个人不再只是在时间和空间里各自作 random walk的两个点,而是走上了联系在一起的人生轨迹。在Carl看来,维系着他和Ellie之间牵绊的是一起去南美的约定以及那座他们一同生活过的屋子。所以他才那么不顾一切地要守护这座屋子和那个约定,仿佛要是屋子毁了或到达瀑布的约定没能实现,他和Ellie之间的牵绊也就断了。而Ellie却比Carl早一步明白,原来当感情足够强烈它本身成了两人牵绊最有力的维系,至于屋子或去南美的约定反到变得可有可无。所以她才能将探险的梦想释然放下,成为那个坐在自家窗边有着幸福侧颜的老人。

    好在在Ellie的留言和照片的点拨下,Carl也明白了他和Ellie之间的牵绊远比他想象中的要永恒,所以他才能毅然决然地清空这座他曾经视作珍宝的屋子,所以他才能在最终屋子渐渐飘远直到消失在云层中时,只是淡淡地说一句“It’s just a house.” 屋子没有了又怎样,约定没有达成又怎样,有了那些共同生活的美好记忆,其实两人一直都在一起。而Pixar到底还是爱童话的,最后的最后,屋子悠悠荡荡地还是飘落在了瀑布旁,就如两人当年的约定一样。只是此时,这已经不重要了。

    看Up的我二十出头,和儿时的Ellie一样,有着一颗梦想到处游走的心。我曾很多次背起包离开家,去到很远的地方。我也爬上过很高的山,穿越过无际的森林,看见过令人屏息的悬崖峡谷。我曾跟朋友说,无法想象能有什么可以让我放弃到处流浪的自由。而现在我想,自己之所以会这么认为,也许是因为还没有遇见真正美好的感情。有一天,有一个与我有着深刻牵绊的人出现在我的生活里,我也会像后来的Ellie一样,心甘情愿地慢慢飘落下来,在那个人身边落地生根,与那个人一起长成两棵并肩的树。然后哪儿也不去了,就这么看着云朵和星辰在两人头顶的那小片天空日日变幻。就像Carl和Ellie那样,正因为是与你一起,那再小再琐碎的生活,都是华丽的冒险。

    Quicksand years 09

    December 31st, 2009


    记得去年的今天,在日志上写下了惠特曼的诗句QuicksandYears,鼓励自己在新的一年里更加坚强、执着。
    在这九局下半的一年,去年的寒假,就给自己计划了在这一年要完成的任务:完成实习公司项目EP-Project;完成托业考试;找到满意的工作,改变生活。一年中,我带着这颗还算坚强的心,考虑着这些事情,完成的还算顺利。
    3-5月的时间,多半用在了实习项目之上。三月的一晚,第一个Linux驱动设备程序调试成功的喜悦,至今还记得。那晚之后,我知道这个项目一定能够完成了。项目产品于9月底投入市场,至今为止任然有问题从测试过程和用户使用过程中发现,不得不引起反思。认识到要想开发出所谓的“精品”是多么不容易的事情。好在问题都有解决的方法,解决问题过程中的收获也许不比开发过程中的小,心里也就多是满足了。随着项目的进展,学术论文也顺利发表并有幸得老师推荐在学院的学术年会上获奖。
    项目之余的时间,心思多放在托业考试的准备上。寒假时基本把考试的语法部分记忆了,3-5月每天听1个小时左右的BBC英语材料,以及5月底考试强化训练,让我取得了还算满意的成绩。不过,依然清晰的记得,在5.31考试的最后15分钟,心情的紧张和思路的慌乱,给这场考试留下了遗憾。让我意识到,自己心智的软弱。
    6月中去北京参加Redhat的实习笔试,考试结果不理想,没有争取到暑期实习的机会。这次经历,让我认识到在嵌入式软件求职之路上自己需要的一些改变,不免身心疲惫。还好有北京挚友和弟弟的细心关怀和鼓励,让这次旅行多了些快乐的回忆,少了些犹豫。也正是由于这次失败的尝试,让我决心去申请国防科技大学高级体系结构和嵌入式系统暑期学校,7.15-8.15一边学习课程一边公司实习的辛苦,让我进步很快。
    9.21的怀着坦诚的心写了一封信,此后开始了正式求职。“找工作是一个逐步认识自己的过程”-现在想想找工作的经历,觉得这句话着实正确。认识自己,在我而言是这个过程中最大的收获和体会。看看自己在求职之初所列出的目标公司列表,自己多半都有去尝试。期间的每一次尝试,不论失败或者成功,都让我更加的认识自己。期间家人和她的鼓励,让我坚定了很多,始终保持着该有的自信。10.26走出了一步
    一年之间,有很多应尽的责任没有做到。想起这些,让我心痛。想告诉我的家人,告诉她,告诉我的朋友们,未来我会做好。

    11.31我开心的认识到,我的人生逐渐的完整。认识到上天给我的最为珍贵的礼物,是那么的美丽。

    2010年我要完成的3件事情:
    1.用心的爱
    2.更加健康快乐
    3.理解工作和生活

    雪中的思念

    December 26th, 2009

    我生命的纸页,留着你美丽的图案。我的心不再孤单。谢谢你。

    beagleboard

    December 22nd, 2009

    BeagleBoard.org 是由志愿者建立的开源组织,意在开发出开源的、功能强大的、嵌入式硬件设备。目前BeagleBoard.org的作品是BeagleBoard。Bealgle Board 是一款基于TI OMAP 3530 处理器的嵌入式开发板。[ OMAP 3530处理器的亮点是 ARM Cortex-A8 和 TMS320C64x+ DSP 的双核架构,目前Palm Pre & Motorola Droid & Nokia N900 用的是这款处理器。]BealgleBoard成本低廉,很适合学习如何建立 Linux 和小型系统。对于为自己设计项目的爱好者,为课程创建项目的学校,以及设计低成本装置或瘦客户机的专业人员,它都是合适的选择。

    BeagleBoard.org社区的网站上,以及形成了比较完善的软件、硬件的开发社区。每天互联网上也有很多新的应用文章[比如这一篇:在 BeagleBoard上引导Linux],邮件列表更新。

    国内已经出现了BeagleBoard的类似开发板,例如[RealtimeDSP的miniEVM]和[英倍特的DevKit8000]。目前国内也有很多的开发者从事OMAP平台的开发工作,在LInuxForum上就看到了一些开发者的讨论。我近期对这个板子也做了几周的调查咯,估计不久就会出手购入了^

    相关链接:
    1. Linuxforum的DJBean大整理的:关于OMAP处理器的资源列表

    2. 两位来自瑞士的Android爱好者的技术博客:
    Using Android in Industrial Automation 他们目前在进行着一个很有意思的项目:Spectrum analyzer

    3. 我收集的:关于BeagleBoard开发的资料链接 — 列表不定期更新哦^

    4.一份很有价值的技术报告:Using Android in Industrial Automation