用十年时间自学编程

  

  走进任何一家书店,你会看到《怎样在24小时内学会 Java》以及在几天或几小时内学会 C、SQL、Ruby、算法等等这种书。在亚马逊上对【关键词:“教学”、“自学”、“小时”,时间段:2000年以后】做一次高级检索,然后找到了 512 本这样的书。在前十名中,9本都是编程书(另外一本关于记账的)。把“自学”换成“学习”,或者“小时”换成“天”,可以得到类似的结果。

  一个结论就是,要么人们急于学习编程,要么觉得“编程”这件事比学习其他东西简单很多。Felleisen 等人在他们书中《怎样设计程序》对这一趋势表示赞同,并且他们表示“糟糕的编程是简单的,白痴也能在 21天内学会,即便他们是傻瓜”。漫画 Abtruse Goose 中也表达出类似的观点。

  让我们分析一下“24小时内学会 C++”这样的标题可能意味这什么:

  自学:在24小时里,你将没有时间去写几个重要的程序,也就无法从成功和失败中得到经验和教训。你将没有时间与一个有经验的程序员合作,并理解在 C++ 环境中 C++ 到底是什么。总而言之,你将没有时间学习很多东西。所以书中内容只能讨论一些肤浅的内容,而不是深刻理解。正如 Alexander Pope 所说,学习一丢丢是很危险的。

  C++:在24小时里你可能学习到一些 C++ 的语法(如果你之前知道另一门其他编程语言),但你无法学习到如何使用这门语言的知识。简而言之,如果你是一个 Basic 程序员,你可能学习到使用 C++ 的语法、Basic 的代码风格去写程序,但是你无法学习到 C++ 真正的好与坏。那有什么意义呢?Alan Perlis 曾经说过:“一门语言如果不能改变你对思考编程的方式,那么它是不值得学的”。一个可能的意义会是,你需要学习一点点的 C++ (或者更可能是其他的东西,比如 JavaScript 或 Processing)因为你需要面对现有的工具去完成一个特定的任务。但是你这不是学习如何学习编程,而是在学习如何完成任务。

  24小时内:不幸的是,这远远是不够的,正如下一章所要讲的内容。

  研究人员(Bloom (1995), Bryan&Harter(1899), Hayes(1989), Simmon&Chase(1973))已经表明,在任何一个广泛的领域,包括国际象棋、音乐创作、电报操作、绘画、钢琴演奏、游泳、网球,以及神经心理学和拓扑学的研究,都需要花费10年的时间去发展专业知识,关键在于深思熟虑地实践,不是一次又一次地做,你需要用一个超出自己能力的任务挑战自己,尝试它,在做了之后分析你的表现,纠正错误,然后再重复重复再重复。似乎没有真正的捷径,就连4岁的音乐天才莫扎特,也花费了 13 多年才开始创作世界级的音乐。在另一个流派,Beatles 乐队(一个摇滚乐队)似乎以一系列的“热门第一”和在1964年的埃德·沙利文秀上亮相而崭露头角。但他们自1957年就已经在Liverpool and Hamburg的小俱乐部效力,虽然他们在很早就有大众的吸引力,但他们的第一个重大的成功是发行与1967年的 《Sgt. Peppers》。

  Malcolm Gladwell 推广了这个想法,虽然他专注于 10000 小时而不是 10 年。Henri Cartier-Bresson(1908-2004)提出了另一个衡量标准:“你的前10000照片是你拍摄的照片中最差的”(他没想到,有了数码相机,一些人一周就能达到这个标准)。真正的专业知识可能需要花费一生的时间:Samuel Johnson (1709-1784)说“在任何一个 department,excellence 只能通过一生的努力来实现;这不是在低价时买东西”。Chaucer (1340-1400)抱怨道“生命如此短暂,艺术如此长久”。Hippocrates(约公元前400年)以摘录“ars longa, vita brevis”而闻名,这是对“Ars longa, vita brevis, occasio praeceps, experimentum periculosum, iudicium difficile”的引用,翻译一下就是“人生很短,艺术永存,机会转瞬即逝,实验背信弃义,判断困难”。当然,没有一个数字可以作为最终的答案:假定所有技能(比如编程、下棋、跳棋、音乐)需要完全相同的很多时间掌握似乎是不太合理的,所有人花费同样的时间也不合理。正如 Prof. K. Anders Ericsson 所说“在大多数领域,即便是最有才华的人,他们需要花费多少时间去达到一个最高水平,这点非常值得注意”。10000小时这个数字只是让你感觉一下我们正在讨论的 10 到 20 小时一个星期,有人争辩说,那些天赋很高人依旧需要达到最高的水平。

  以下是我一些编程成功的秘诀

  对编程感兴趣,因为它有趣。确保它足够有趣,这样你才能乐意投入10年/10000小时的时间。

  编程。最好的学习方式是在实践中学习。更严格地说,“个人在某一特定领域的最高表现水平不是随着经验的扩展自动得到的,但是最高表现水平可以通过有经验的的人的深思熟虑的努力来增加。”(第366页),“最有效的学习需要一个明确定义的任务、对适当的个体有一定的难度、有信息反馈、以及重复和纠正错误的机会(第20-21页)”。这本书《实践中的认知:日常生活中的思维、数学和文化》是这一观点有趣的参考。

  与其他程序员交流;阅读其他程序。这比任何书籍和培训课程都重要。

  如果你愿意,可以在大学里呆四年(或者在研究生院多呆四年)。这会获得一些需要证书的工作,也会让你对这个领域有更深的了解,但如果你不喜欢上学,你可以(带着一些奉献的精神)在自己身上或工作中得到类似的经验。无论如何,光靠书本学习是不够的。“计算机科学教育不能让每个人成为专家级程序员,正如学习刷子和颜料不能让人成为专业画家一样”,Eric Raymond 说,一个“New Hacker's Dictionary” 的作者。我雇佣过的最好的程序员之一只有高中学历;他制作了很多很棒的软件,有自己的新闻组,然后赚够了足够的股票期权买了一家属于他自己的夜总会。

  与其他程序员一起做项目。在某些项目中做最好的程序员;在某些项目中是最差的程序员。当你是最好的时候,你得到了一次领导项目的能力的测试,并用你的愿景激励别人。当你是最差的时候,你能知道 masters 在做什么,也能够知道他们不喜欢做什么(因为他们会让你帮他们做)。

  做其他程序员之后的项目。理解别人写的程序。看看当原来程序员不在测时候,需要什么东西理解它和修复 bug。思考如何设计你的程序,让那些在你之后的人更容易维护它们。

  学习至少 6 种编程语言。包括一种强调类抽象(比如 Java、C++),强调函数抽象(比如 Lisp、ML、Haskell),支持句法抽象(比如 Lisp),支持声明性规范(比如 Prolog、C++模版),强调并行性(比如 Clojure、Go)。

  记住“计算机科学”有一个“计算机”这个词。了解计算机执行一条指令、从内存中读取一个字(有无缓存丢失)、在磁盘里读取连续字以及查找磁盘上新位置所需的时间。

  参与语言化标准内容。它可能是 ANSI C++ 委员会,或者它可以决定你本地编码风格是两个空格还是四个空格的缩进。不管是哪种方式,你都可以了解到其他人对一种语言的喜好,他们的感受有多深,甚至可以了解一点他们为什么会有这样的感受。

  尽可能快地对语言化标准内容有一个良好地感觉,然后做别的事情。

  考虑到这些,仅仅通过书本学习你能走多远是值得质疑的。在我第一个孩子出生前,我读了所有关于“怎样xxx”的书,仍然感觉自己是个无知的初学者。30 个月后,当我的第二个孩子出生的时候,我有没有回到书本上复习?没有,相反,我把时间花费在个人经验上,这比专家们写的几千页书更有用,更让我放心。

  Fred Brooks 在他的文章《No Silver Bullet》提出了一个有三部分组成的用于寻找优秀软件设计师的计划:

  尽可能系统地确定顶级设计师。

  指派一个职业导师负责有潜力的人的发展并认真保存职业档案。

  为成长的设计师互动和相互激励的提供机会。

  这假定了这些人已经具备了成为一个优秀设计师所必须的素质,工作就是适当地哄他们。Alan Perlis 说得更简洁:“每个人被教去雕塑:米开朗基罗被教去如何不雕塑,优秀的程序员也是如此”。Perlis 说,优秀的球员有一些内在的品质超越训练。但是这些品质从何而来?是天生的吗?或者他们通过勤奋发展起来的?正如 Augeste Gusteau(一个虚构《料理鼠王》的厨师)所说,“每个人都会做饭,但是只有无畏的人才是杰出的。”我认为这更像是一个人乐意把一生的大部分时间去做深思熟虑的实践中。但也许无畏是一种总结。或者,正如 Gusteau 的评论家——Anton Ego 说:“不是每个人都能成为伟大的艺术家,但是一个伟大的艺术家可以来自任何地方”。

  所以去买那本 Java/Ruby/JavaScript/PHP 书,你可能会从中得到一些用处。但是你无法在24小时或21年内改变你的生活,也不会改变作为程序员的专业编程技能。不如在 24 个月里好好努力提升自己?很好,你开始有进展了......

  原文链接:http://norvig.com/21-days.html

  作者:Peter Norvig,如需转载,请联系作者。

  举报/反馈