程序员必读经典长文:用十年时间自学编程
考虑到一切,仅仅通过书本学习你能走多远是个值得怀疑的问题。
雷锋网 AI 科技评论按,相信很多做技术的同学都自学过,也看过「Teach Yourself Programming in Ten Years」这篇文章。虽然离初次发表已经好几年了,但所有试图自学编程的人都应该发自内心的同意它的说法(除去少数过时的具体技术部分)。直到今天,这篇经典的文章依然很有借鉴意义。以下是这篇文章的中文版。
为什么每个人都这么匆忙?
走进任何书店,你都会看到如何在 24 小时内自学 Java,同时你还可以看到很多在几天或几小时内学会 C、SQL、Ruby、算法等等的书籍。在亚马逊使用「title: teach, yourself, hours, since: 2000」进行高级搜索,我发现了 512 本这样的书。在排在前十名的书籍中,有九本是编程书籍,剩下一本是关于财务管理的。用「teach yourself」代替「learn」,或者用「day」代替「hours」产生的结果类似。
结论是,要么人们急于学习编程,要么编程比其他任何东西都更容易学习。Felleisen 等人在他们的书《How to Design Programs》中提到,「糟糕的编程很容易,即便是白痴都可以在 21 天内学会」时,请对这一观点表示赞同。
让我们来分析一下在 24 小时内学会 C++意味着什么:
自学:24 小时内,你将没有时间写几个重要的程序,并从成功和失败中吸取教训。你将没有时间和一个有经验的程序员一起工作,并理解在 C++环境中编程会是什么样子。简而言之,你将没有时间去学习多少东西。所以这本书只能说是肤浅的熟悉,而不是深刻的理解。正如 Alexander Pope 所说,只学会一点点点东西是危险的
C++:在 24 小时内,你也许能够学习 C++的一些语法(前提是你已经知道了另一种语言),但是你不能学到多少关于如何使用这门语言的知识。简而言之,如果你是一个基层的程序员,你可以学习用 C++语法编写 BASIC 程序,但是你不能学习到 C++真正的优缺点。那又有什么意义呢?Alan Perlis 曾经说过:「一种不影响你编程思维方式的语言,是不值得学习的。」有一种可能是,你必须学习一点 C++(或者是 JavaScript 之类的东西),因为你需要用现有的工具接口来完成特定的任务。但这种情况下,你不是在学习如何编程,而是在学习如何完成这项任务。
在 24 小时内:不幸的是,这根本不够,正如下面所说的那样。
用十年时间自学编程
很多研究人员发现,在各种领域要成为专家大约需要十年时间,这些领域包括国际象棋、音乐创作、电报、绘画、钢琴演奏、游泳、网球和科学研究、神经心理学和拓扑学等等。成功的关键是不断的实践:不只是一次又一次地做,而是每次都用一个超出你目前能力的任务挑战你自己,尝试去解决它,在做它的同时和之后分析你的表现,纠正错误,然后重复这个循环。人和事情都没有真正的捷径:即便对莫扎特来说也是如此。4 岁就被称为音乐天才的他,在开始创作世界级的音乐之前又花了 13 年时间来打磨自己。另一个例子是披头士乐队。披头士乐队似乎以一系列的热门歌曲和 1964 年在艾德沙利文秀上的亮相而一夜成名。但实际上自从 1957 年以来,他们一直在 Liverpool 和 Hamburg 的小酒吧里面演出,虽然很早以前他们就受到大众的欢迎,但他们第一次取得重大成功的专辑「Sgt. Peppers」是在 1967 年发布的。
Malcolm Gladwell 已经普及了这个想法,尽管他的观点是 10000 小时专注的努力,而不是 10 年。Henri Cartier-Bresson (1908-2004) 有一句名言:「你的前 10000 张照片是你最差的作品。」(他没有预料到使用数码相机,有些人可以在一周内就拍完 10000 张照片。)真正成为专家可能需要一辈子:Samuel Johnson(1709-1784)说:「成为任何领域的卓越人士都需要毕生的努力,投机取巧并不可行」。Chaucer (1340-1400) 抱怨说:「人生太短暂了,而知识是无穷的」。Hippocrates (约公元前 400 年) 因为那句名言「ars longa, vita brevis」而被人称颂,这句话的原文是「Ars longa, vita brevis, occasio praeceps, experimentum periculosum, iudicium difficile」,意思是「生命很短暂,但是技艺却很高深,机遇转瞬即逝,探索难以捉摸,抉择困难重重」。
当然,没有一个数字可以作为最终的答案,假定所有的技能(如编程、下棋、跳棋和音乐演奏)都需要完全相同的时间来掌握,或者所有人都需要完全相同的时间是不合理的。正如 K. Anders Ericsson 教授所说,「在大多数领域,即使是最有才华的人也需要很多时间才能达到最高水平,这是非常值得注意的。10000 小时这个数字让你感觉到,我们说的是一周 10 到 20 个小时。」
你想成为一名程序员
以下是我的编程秘诀:
对编程感兴趣,因为兴趣而编程。请保持足够的兴趣,以便你愿意投入你的 10 年或者 10000 小时。
编码。最好的学习方式是实践。更严格地说,「在特定领域中,一个人的最高水平不是由于经验的积累自动获得的,而是经过深思熟虑的改进,经验丰富的人也可以提高水平。」,「最有效的学习需要有一个明确的任务,对特定的人来说难度适中,还要有信息反馈以及重复试错和纠正错误的机会。」「Cognition in Practice: Mind, Mathematics, and Culture in Everyday Life」这本书正是这一观点的有趣参考。
与其他程序员交谈;阅读其他程序。这比任何书籍或培训课程都重要。
如果你愿意,可以在大学(或研究生院)呆四年。这将使你有机会获得一份需要证书的工作,让你对这个领域有更深的了解,但如果你不喜欢学校,你可以自学或在工作中获得类似的经验。无论如何,光靠书本知识是远远不够的。「The New Hacker's Dictionary」的作者 Eric Raymond 说:「计算机科学教育不能使任何人成为一个专业的程序员,就像学习刷子和颜料不可以使某人成为一个专业的画家一样。」我雇用过的最好的程序员之一只有高中学历,他开发了许多优秀的软件,拥有自己的团队,并且拥有足够买下一个夜店的股票期权。
与其他程序员一起做项目。在某些项目上你是最好的程序员,而在某些项目上你是最差的程序员。当你是最好的时候,你可以锻炼主导一个项目的能力,并用你的远见激励别人。当你是最坏的时候,你可以学习大师们做什么,观察他们不喜欢做什么(因为他们会让你为他们做自己不喜欢的事情)。
接手其他程序员的项目,理解别人写的程序。当原来的程序员不在时,学习需要怎样理解和修复程序。想想如何设计你的程序,让那些在你之后的人维护它们更容易些。
学习至少六种编程语言。包括一种强调类抽象的语言(如 Java 或 C++),它强调函数抽象的语言(如 Lisp 或 ML 或 Haskell),一种支持句法抽象的语言(如 Lisp),一种支持声明性规范的语言(如 Prolog 或 C++模板),一种强调并发性的语言(像 Clojure 或 Go)。
记住「computer science」中有一个「computer」。知道计算机执行一条指令、从内存中提取一个字符(有或没有缓存)、从磁盘中读取连续的字符以及在磁盘上寻找新的位置需要多长时间。
参与语言标准化工作。它可能是 ANSI C++委员会,也可以是决定你自己的本地编码风格是有 2 个或者 4 个空间缩进。无论哪种方式,你都可以了解到其他人对一种语言的喜好,他们的感受有多深,甚至可能了解他们的感受。
有很好的判断力,尽快适应语言的标准化
考虑到这一切,仅仅通过书本学习你能走多远是个值得怀疑的问题。在我的第一个孩子出生之前,我读完了所有的「How To」类型的书,但仍然觉得自己像个笨手笨脚的新手。30 个月后,当我的第二个孩子出生时,我重新学习了那些书本知识吗?不,相反,我依靠的是我的个人经验,这比专家们写的几千页书更有用,更让我放心。
Fred Brooks 在他的论文《No Silver Bullet》中指出了寻找优秀软件设计师的三个步骤:
尽早系统地发掘顶级程序员。
指派一名职业导师负责指导他,并谨慎对待履历。
为成长中的程序员提供相互交流和互相激励的机会。
这假设一些人已经具备成为一个伟大的程序师所必需的素质,那么你的工作就是适当地哄骗他们。Alan Perlis 的说法更加简洁:「每个人都可以学会雕刻,但 Michelangelo 必须学会如何不雕刻。对伟大的程序员来说也是如此。」Perlis 认为,伟人有一些超越训练的内在品质。但是这些品质是从哪里来的呢?是先天的吗?或者他们是通过勤奋养成的?正如 Auguste Gusteau 所说:「任何人都能学会做饭,但只有无畏的人才是伟大的。」我认为这更像是愿意将一生中大部分时间投入到某种实践中,但也许无畏是总结这一点的一种方式。或者,正如 Gusteau 的批评家 Anton Ego 所说:「不是每个人都能成为伟大的艺术家,但伟大的艺术家可以来自任何地方。」
所以继续购买 Java/Ruby /JavaScript /PHP 书籍吧,你可能会从中得到一些有用的东西。但是它们不会在 24 小时或 21 天内改变你的生活,也不会教会你作为一个程序员所需要的所有专业知识。何不努力工作,在接下来的 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.
Bryan, W.L. & Harter, N.《Studies on the telegraphic language: The acquisition of a hierarchy of habits》. Psychology Review, 1899, 8, 345-375
Hayes, John R.,《Complete Problem Solver》Lawrence Erlbaum, 1989.
Chase, William G. & Simon, Herbert A.《Perception in Chess》,Cognitive Psychology, 1973, 4, 55-81.
Lave, Jean,《Cognition in Practice: Mind, Mathematics, and Culture in Everyday Life》, Cambridge University Press, 1988.
前面问题的答