协作翻译
原文:Teach Yourself Programming in Ten Years
链接:http://norvig.com/21-days.html
译者:Tocy, lnovonl, AlfredCheung, 边城, 无若
走进任意一家书店,你会看到如何在24小时内自学 Java,以及在几天或几小时内教授 C、SQL、Ruby、算法等无穷无尽的书籍变种。亚马逊高级搜索以下关键词[title: teach, yourself, hours, since: 2000,会发现有512本这样的书。在前十名中,有九本是编程书籍(另一本是关于记账的)。类似的结果来自于将 "teach yourself"替换为"learn"或将"hours"替换为"days"。
结论是,要么人们都急于学习编程,要么编程在某种程度上比其他任何东西都更容易学习。Felleisen 等人在他们的“How to Design Programs”一书中对此趋势表示赞同,“糟糕的编程很容易。即使是傻瓜,人们也可以在21天内学会它。”Abtruse Goose 漫画对此也有他们的理解。
我们来分析一下诸如24小时自学 C++ 这样的标题意味着什么:
自学:24小时不足以写一些有意义的程序,更不用说从中汲取经验或者教训。这个时间也不足以跟有经验的程序员一起工作并理解处于 C++ 的环境是一种怎样的感受。简单地说,就是因为时间不足,学不到多少东西。因此,这种书只会谈及肤浅的表面,不会带来深刻的理解。正如 Alexander Pope 所说,学点皮毛是件很危险的事情。
C++:24小时内你可能会学到一些 C++ 语法(如果你已经会其它语言的话),但是不能学到如何应用这门语言。简而言之,如果你是一名 Basic 程序员,你可以学会用 C++ 语法以 Basic 风格编写程序,但你不会了解 C++ 为什么好(或坏)。所以这有什么意义呢?Alan Perlis 曾说:“如果一门语言不能引发你对编程的思考,就不值得去学。”一个可能的观点是,你必须学一点 C++(或者更可能是像 JavaScript 或 Processing 的语言),因为你可能需要与现有工具进行交互以完成某项特定的任务。但是这样一来,你学的不是如何编程,而是如何完成任务。
24小时: 很不幸,这是远远不够的,下面我们将详述。
研究员 (Bloom (1985), Bryan & Harter (1899), Hayes (1989), Simmon & Chase (1973)) 已经证实,在包括国际象棋、音乐制作、电报操作、绘画、钢琴表演、游泳、羽毛球、神经心理学以及拓扑研究在内的各种领域中构建专业知识体系需要大约十年的时间。
关键是审慎的实践:不仅仅是一次又一次地重复,而是用一项超出你现有能力的任务来挑战自己,尝试它,分析你在执行它时的表现,并纠正任何错误。然后重复一遍再重复一遍。似乎没有真正的捷径:即使莫扎特4岁时是一位音乐神童,他在开始制作世界级音乐之前还花了13年时间。
在另一时代中,甲壳虫乐队似乎在一系列#1热门歌曲和1964年的 Ed Sullivan 现场秀中亮相。但自1957年以来他们一直在利物浦和 Hamburg 小型俱乐部演唱,虽然他们有早期粉丝,但他们的第一次重大成功,Sgt. Peppers,于1967年发布。
马尔科姆·格拉德维尔推广了这一思想,尽管他更关注10,000个小时而不是10年。
亨利·卡蒂埃-布列松则有其他的标准:“最糟糕的是你前10,000张照片”(他没想到数码相机的出现致使某些人在一周之内就能达成目标)。
“真正的专业知识需要你用一生来了解”,塞缪尔·约翰逊说到,“任何学科的卓越成就依靠毕生劳作,靠金钱买不来。”
乔叟则抱怨道:“生之有崖,学而无涯。”
希波克拉底因这条摘要 "ars longa, vita brevis"而著名,这是引文“Ars longa, vita brevis, occasio praeceps, experimentum periculosum, iudicium difficile”的一部分,在英语中则说 "Life is short, [the] craft long, opportunity fleeting, experiment treacherous, judgment difficult."(译者注:生命短暂,技艺长远,机会易逝,实验诡谲,判断困难的意思,希波克拉底用拉丁文写的)
当然,答案不唯一:假设所有技能(例如:编程,下象棋,玩跳棋还有演奏音乐)都需要完全相同的时间掌握那是不合理的,并非所有人都花费相同时间。像安德斯·爱立信教授所言,“在大多数领域中,才华横溢者也需时间成就不朽伟业。10,000这个数给我们每周仅工作10至20个小时,有些人辩称大天才还需要达到最高水准。”
这是我在编程方面获得成功的秘诀:
对编程感兴趣,因为它很有趣而完成一些编程工作。确保它能对你保持足够的兴趣,以便你愿意在未来投入十年/10,000小时。
编码。最好的学习方式是边学边做。更具技术性地描述下,“特定领域中个人的最高绩效水平并不是作为增加经验的功能而自动实现的,但即使是经验丰富的个体因刻意努力改进是可以提高绩效水平的。”(p. 366)和“最有效的学习需要一个定义明确的任务,对特定的个体有适当的难度级别、信息反馈,以及重复和纠正错误的机会。” (第20-21页)“实践中的认知:日常生活中的思想,数学和文化”(Cognition in Practice)一书中是对这一观点的一个有趣的引用。
跟其他程序员交谈,或阅读其他人的程序。这比其他任何书籍或课程都管用。
如果对学校有兴趣,你可以读4年大学(或再读几年研究生)。这样你就可以找那些有学历门槛的工作,而且学校可以让你对这个领域有更深的认识。当然,如果你不喜欢学校,那么也可以通过自学或工作来达到相同的效果。无论如何,单单看书肯定是不够的。“单凭计算机课无法让一个人变成一个编程专家,就像单纯研究刷子和颜料无法造就一个画家一样。”《新黑客字典》的作者 Eric Raymond 这样说。我曾经有个员工,虽然只有高中学历,但非常厉害,写了很多很棒的软件,还有自己的新闻组,甚至还靠股票期权买下了自己的夜总会。
跟其他程序员一起做项目。在一些项目里,你可能是最牛的;在另一些项目里,你可能是最弱的。在那些你最牛的项目里,你可以训练你的领导能力,用你的眼界来激发大家。在那些你最弱的项目里,你可以学学那些大牛是怎么做的,也可以学学那些大牛不想做的东西(因为大牛让你替他们做)
接手其他程序员的项目。理解其他人写的程序。看看理解和修复其他人的程序会有多难。这样你就可以想想怎么优化自己的设计,可以让别人接手时简单一些,再简单一些。
至少要学那么六七门编程语言。其中至少要有一门是强调类抽象的(比如 Java 和 C++),一门是强调函数抽象的(比如 Lisp、ML 或 Haskell),一门是支持语法抽象的(比如 Lisp),一门是支持声明式规范的(比如 Prolog 和 C++ 模板),一门是强调并行性的(比如 Clojure 和 Go)。
记住,“计算机科学”中是有一个“计算机”的。你得知道你的计算机执行一条指令需要多久,从内存取一个词需要多久(缓存命中要多久,不命中要多久),从磁盘读连续的字要多久,磁盘寻道要多久。
加入到语言的标准化过程中。大到加入 ANSI C++ 委员会,小到确定你们公司里是用2个空格缩进还是4个空格缩进。通过这些过程,你可以了解其他人对语言里某些东西的喜好,这种喜好到底有多深刻,甚至为什么有这种喜好。
还要有尽快从语言标准化工作中抽身而出的决断力。
考虑到所有这些问题,你可以通过书本学习到多少。在我的第一个孩子出生之前,我读了所有的 How To 书籍,仍然感觉像一个无知的新手。30个月后,当我的第二个孩子到来时,我是否还要回到书本上进行复习?不。相反,我依靠我的个人经验,结果证明,与专家撰写的数千页相比,这对我来说更有用,更让人放心。
弗雷德布鲁克斯在他的文章 No Silver Bullet 中确定了一个由三部分组成的计划来寻找优秀的软件设计师:
尽早系统地识别顶级设计师。
指派一名职业导师负责潜在客户的发展并谨慎地保留工作档案。
为成长中的设计师提供互动和互相激励的机会。
这里假设有些人已经拥有成为优秀设计师所需的品质;任务就是要循循善诱之。Alan Perlis 的表达更简洁:“每个人都可以被教导雕琢:米开朗基罗必须被教导如何不被雕琢。伟大的程序员也是如此”。
Perlis 说过,伟人的内在品质超越了他们的训练。但其品质来自哪里?它是天生的吗?或者他们是通过勤奋来形成的?正如 Auguste Gusteau(Ratatouille中虚构的厨师)所说,“任何人都可以烹饪,但只有无所畏惧者才能做得很好。”我更多地想到将一个人的大部分时间投入到审慎的实践中的意愿。但也许无畏是对其总结的一种方式。或者,正如 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. "关于电报语言的研究:习惯等级的养成. 心理学评论, 1899, 8, 345-375
Hayes, John R., Complete Problem Solver Lawrence Erlbaum, 1989.
Chase, William G. & Simon, Herbert A. "Perception in Chess"(国际象棋中的洞察力) 认知心理学, 1973, 4, 55-81.
Lave, Jean, 实践中的认知学:日常生活中的心灵、数学以及文化, 剑桥大学出版社, 1988.
典型PC上不同操作的大致耗时:
许多人问初学编程选什么语言好。这没有固定的答案,但有几点供参考:
利用朋友。当被问及我该使用哪个操作系统,Windows、Unix 还是 Mac 的时候,我总会回答:你朋友用什么你就用什么。这样好处是从你朋友处学到的将抵消操作系统上或是编程语言中的内在差别。想下未来吧老兄:假设你继续下去成为了程序员社区的一份子。你所选择的的语言是社区庞大快速增长还是用户渺渺接近消亡?能否从书籍、网站或是论坛得到答案?你喜欢论坛上的人吗?
保持简洁。诸如 C++ 和 Java 之类的编程语言由经验丰富的大型程序员团队专业开发而来,他们会关心代码运行时的效率。显然这些语言为该状况设计了繁琐的部分。你只需要关注学习编程,不需要这么复杂。你需要一种易于新程序员学习和记忆的语言。
如何对待。你更喜欢怎样学弹钢琴:常态的交互式,按下按键听到声音?或是批量模式,弹完整首后听到声音?无疑,交互式模式使得学习弹钢琴更容易,同样使得学习编程更容易。坚持用交互式学习一门语言并且应用它。
鉴于这些标准,我对第一种编程语言的推荐是Python或Scheme。另一个选择是Javascript,不是因为它非常适合初学者,而是因为它有很多的在线教程,比如Khan学院的教程。但是你的情况可能会有所不同,还有其他好的选择。如果你的年龄是一位数,你可能更偏爱Alice、Squeak或Blockly(年龄较大的学习者也可能喜欢这些语言)。重要的是你选择了并已在路上。
有几个人已问过他们应该学习哪些书籍和网页。我再说一遍“仅靠看书学习是不够的”,但我可以推荐以下内容:
Scheme:《计算机程序的结构和转译》(Abelson & Sussman)可能是计算机科学的最佳入门书籍,它确实将编程作为理解计算机科学的一种方法。你可以查看本书相关讲座的在线视频以及完整的在线文字版。这本书颇具挑战性,并将淘汰一些可能通过另一种方法取得成功的人。
Scheme:《如何设计程序》(Felleisen等人)是关于如何以优雅和函数式的方式真实地设计程序的最佳书籍之一。
Python: Python编程:CS简介 (Zelle)是对Python用法的不错的介绍。
Python: 一些在线教程可以在Python.org上找到。
Oz: 计算机编程的概念、技术及模型(Van Roy & Haridi) 被一些人视为Abelson&Sussman的现代继承者。这是一个关于编程的重要思想之旅,涵盖了比Abelson和Sussman更广泛的范围,同时可能更容易阅读和遵循。它使用一种语言——Oz,这种语言并不广为人知,但却是学习其他语言的基础。<
开源中国征稿开始啦!
开源中国 www.oschina.net 是目前备受关注、具有强大影响力的开源技术社区,拥有超过 200 万的开源技术精英。我们传播开源的理念,推广开源项目,为 IT 开发者提供一个发现、使用、并交流开源技术的平台。
现在我们开始对外征稿啦!如果你有优秀的技术文章想要分享,热点的行业资讯需要报道等等,欢迎联系开源中国进行投稿。投稿详情及联系方式请参见:我要投稿
GitHub Dashboard 重构放弃使用 jQuery
大变样,Chrome 新一代 Material Design UI 来袭