本文转载自中文译者 郭晓刚 发布的同名文章,所译作品是由 Peter Norvig 创作的 Teach Yourself Programming in Ten Years,此版本译文得到原作者许可。原作者版权所有,转载需注明出处。本文对原译文在版式上略作修正。

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

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

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% 是计算机书籍。

结论是,要么是人们非常急于学会计算机,要么就是不知道为什么计算机惊人地简单,比任何东西都容易学会。没有一本书是要在几天里教会人们欣赏贝多芬或者量子物理学,甚至怎样给狗打扮。

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

  • 学会

在 3 天时间里,你不够时间写一些有意义的程序,并从它们的失败与成功中学习。你不够时间跟一些有经验的程序员一起工作,你不会知道在那样的环境中是什么滋味。简而言之,没有足够的时间让你学到很多东西。所以这些书谈论的只是表面上的精通,而非深入的理解。如 Alexander Pope(译注:英国诗人、作家,1688-1744)所言,一知半解是危险的(a little learning is a dangerous thing)。

  • Pascal

在 3 天时间里你可以学会 Pascal 的语法(如果你已经会一门类似的语言),但你无法学到多少如何运用这些语法。简而言之,如果你是,比如说一个 Basic 程序员,你可以学会用 Pascal 语法写出 Basic 风格的程序,但你学不到 Pascal 真正的优点(和缺点)。那关键在哪里?Alan Perlis(译注:ACM 第一任主席,图灵奖得主,1922-1990)曾经说过:“如果一门语言不能影响你对编程的想法,那它就不值得去学”。另一种观点是,有时候你不得不学一点 Pascal(更可能是 Visual Basic 和 JavaScript 之类)的皮毛,因为你需要接触现有的工具,用来完成特定的任务。但此时你不是在学习如何编程,你是在学习如何完成任务。

  • 3 天

不幸的是,这是不够的,正如下一节所言。

十年编程无师自通

一些研究者(Hayes、Bloom)的研究表明,在许多领域,都需要大约 10 年时间才能培养出专业技能,包括国际象棋、作曲、绘画、钢琴、游泳、网球,以及神经心理学和拓扑学的研究。似乎并不存在真正的捷径:即使是莫扎特,他 4 岁就显露出音乐天才,在他写出世界级的音乐之前仍然用了超过 13 年时间。再看另一种音乐类型的代表--披头士,他们似乎是在 1964 年的 Ed Sullivan 节目中突然冒头的。但其实他们从 1957 年就开始表演了,即使他们很早就显示出了巨大的吸引力,他们第一次真正的成功之作 Sgt. Peppers 也要到 1967 年才发行。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(《新黑客字典》)的作者如是说。我曾经雇用过的最优秀的程序员之一仅有高中学历;但他创造出了许多伟大的软件,甚至有讨论他本人的新闻组,而且股票期权让他达到我无法企及的富有程度(译注:指 Jamie Zawinski,XEmacs 和 Netscape Navigator 的作者)。
  • 跟别的程序员一起完成项目。在一些项目中成为最好的程序员;在其他一些项目中当最差的一个。当你是最好的程序员时,你要测试自己领导项目的能力,并通过你的洞见鼓舞其他人。当你是最差的时候,你学习高手们在做些什么,以及他们不喜欢做什么(因为他们让你帮他们做那些事)。
  • 接手别的程序员完成项目。用心理解别人编写的程序。看看在没有最初的程序员在场的时候理解和修改程序需要些什么。想一想怎样设计你的程序才能让别人接手维护你的程序时更容易一些。
  • 学会至少半打编程语言。包括一门支持类抽象(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 个月内发生真正的变化。

参考文献

Bloom, Benjamin (ed.) Developing Talent in Young People, Ballantine, 1985.

Brooks, Fred, No Silver Bullets, IEEE Computer, vol. 20, no. 4, 1987, p. 10-19.

Hayes, John R., Complete Problem Solver, Lawrence Erlbaum, 1989.

Lave, Jean, Cognition in Practice: Mind, Mathematics, and Culture in Everyday Life, Cambridge University Press, 1988.