用十年自学编程 (1998)

Hacker News Top 新闻

摘要

Peter Norvig的一篇经典文章,认为成为编程专家需要大约十年的刻意练习,并批评了快速学习类书籍。

暂无内容
查看原文
查看缓存全文

缓存时间: 2026/07/29 03:51

# 用十年自学编程 来源:https://www.norvig.com/21-days.html ## 为什么每个人都这么急于求成? 走进任何一家书店,你都会看到如何在 24 小时内自学 Java 的书籍,以及无数类似的变体,承诺在几天或几小时内教会你 C、SQL、Ruby、算法等。亚马逊的高级搜索[标题:teach, yourself, hours, 自 2000 年起](http://www.amazon.com/gp/search/ref=sr_adv_b/?search-alias=stripbooks&unfiltered=1&field-keywords=&field-author=&field-title=teach+yourself+hours&field-isbn=&field-publisher=&node=&field-p_n_condition-type=&field-feature_browse-bin=&field-subject=&field-language=&field-dateop=After&field-datemod=&field-dateyear=2000&sort=relevanceexprank&Adv-Srch-Books-Submit.x=16&Adv-Srch-Books-Submit.y=5) 找到了 512 本这样的书。前 10 名中,有 9 本是编程类书籍(另一本关于簿记)。如果搜索词改为“learn”或“days”,结果也类似。 结论是:要么人们急于学习编程,要么编程比任何其他东西都不可思议地容易学。Felleisen 等人在其著作《如何设计程序》中提到了这一趋势,他们说:“糟糕的编程很容易。*白痴*也能在*21 天*内学会,即使他们是*傻瓜*。”Abstruse Goose 漫画也对此有自己的[解读](http://abstrusegoose.com/249)。让我们分析一下像《24 小时自学 C++》这样的书名可能意味着什么: - **自学:** 在 24 小时内,你不会有时间编写几个有意义的程序,并从成功和失败中学习。你不会有时间与有经验的程序员合作,理解在 C++ 环境中工作是什么感觉。简而言之,你不会有时间学到多少东西。所以这本书只能谈皮毛,而非深入理解。正如亚历山大·蒲柏所说,一知半解是危险的事。 - **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 年才开始创作世界级音乐。另一个例子,披头士乐队似乎是在 1964 年凭借一系列冠军单曲和登上 Ed Sullivan 秀而突然爆红。但他们从 1957 年起就在利物浦和汉堡的小俱乐部里演奏,虽然早期就有大众吸引力,但他们的第一次重大评论成功*Sgt. Peppers*是在 1967 年发行的。 Malcolm Gladwell 普及了这一观点,尽管他注重的是 10,000 小时而非 10 年。Henri Cartier-Bresson(1908-2004)有另一种标准:“你最初的一万张照片是最差的。”(他没有预料到数字相机让某些人能在一周内达到这个数量。)真正的专长可能需要一生:塞缪尔·约翰逊(1709-1784)说:“任何领域的卓越只有通过一生的努力才能达到;不能以更低的价格买到。”乔叟(1340-1400)抱怨:“生命如此短暂,技艺如此难学。”希波克拉底(约公元前 400 年)的名言“Ars longa, vita brevis”是更长的引文的一部分:“Ars longa, vita brevis, occasio praeceps, experimentum periculosum, iudicium difficile”,英文译为“生命短暂,技艺长久,机会转瞬即逝,实验充满风险,判断困难”。 当然,没有哪个数字是最终答案:假设所有技能(例如编程、国际象棋、跳棋、音乐演奏)都需要完全相同的时间掌握,或者所有人都会花完全相同的时间,这似乎不合理。正如 K. Anders Ericsson 教授所说:“在大多数领域,即使是最有天赋的人也需要惊人的时间才能达到最高水平的表演。10,000 小时这个数字只是让你意识到,我们说的是每周 10 到 20 小时,持续数年,而即使是那些有些人认为最有天赋的人也需要这个时间才能达到最高水平。” ## 所以你想成为一名程序员 这是我给编程成功的配方: - **对编程产生兴趣**,并因为乐趣而去做一些。确保它持续足够有趣,让你愿意投入十年/10,000 小时。 - **编程**。最好的学习方式是[做中学](http://www.engines4ed.org/hyperbook/nodes/NODE-120-pg.html)。更技术地说,“在给定领域中,个人的最大表演水平不会自动随着广泛的经验而达到,即使是高度经验的个体也可以通过刻意努力来提高表演水平。”(第 366 页),并且“最有效的学习需要一个定义明确的任务,为特定个体设置适当的难度级别,提供信息性反馈,以及重复和纠正错误的机会。”(第 20-21 页)。这本书《日常生活中的认知实践:思维、数学与文化》是这一观点的有趣参考。 - **与其他程序员交流**;阅读他人的程序。这比任何书或培训课程都重要。 - 如果你愿意,可以在**大学**(或研究生院)投入四年。这会让你获得一些需要学历的工作机会,并让你对这个领域有更深入的理解,但如果你不喜欢学校,你也可以(通过一定程度的投入)靠自己或在工作中学到类似的经验。无论如何,仅靠书本学习是不够的。“计算机科学教育不能使任何人成为专家程序员,就像研究画笔和颜料不能使任何人成为专家画家一样。”Eric Raymond 说,他是《新黑客词典》的作者。我曾雇佣过的最好的程序员之一只有高中学历;他制作了一些[很棒的](http://www.xemacs.org/) [软件](http://www.mozilla.org/),拥有自己的[新闻组](http://groups.google.com/groups?q=alt.fan.jwz&meta=site%3Dgroups),并通过股票期权赚够了钱,买下了自己的[夜总会](http://en.wikipedia.org/wiki/DNA_Lounge)。 - **与其他程序员一起做项目**。在某些项目中做最好的程序员;在其他项目中做最差的。当你最好时,你测试自己领导项目的能力,并用你的愿景激励他人。当你最差时,你学习大师们做什么,以及他们不喜欢做什么(因为他们让你替他们做)。 - **在他人之后**处理项目。理解别人写的程序。看看在原程序员不在时,理解和修复它需要什么。思考如何设计你的程序,以便后来维护它的人更容易。 - 学习至少**六种编程语言**。包括一种强调类抽象的语言(如 Java 或 C++),一种强调函数式抽象的语言(如 Lisp 或 ML 或 Haskell),一种支持语法抽象的语言(如 Lisp),一种支持声明式规范的语言(如 Prolog 或 C++ 模板),以及一种强调并行的语言(如 Clojure 或 Go)。 - 记住“计算机科学”里有个“**计算机**”。知道你的计算机执行一条指令、从内存取一个字(有缓存未命中和没有)、从磁盘连续读字、以及寻道到磁盘新位置分别需要多长时间。(答案在此。[此处](https://www.norvig.com/21-days.html#answers)) - 参与一个语言的**标准化**工作。可能是 ANSI C++ 委员会,或者是决定你所在团队的编码风格是 2 个还是 4 个空格的缩进。无论哪种方式,你都会了解别人喜欢语言中的什么,他们的感受有多深,甚至可能了解一点点他们为什么有那种感受。 - 明智地**尽快退出**语言标准化工作。在所有这些之后,仅仅通过书本学习能走多远值得怀疑。在我第一个孩子出生前,我读了所有“如何做”的书,但仍然觉得自己像个无知的初学者。30 个月后,当我第二个孩子即将出生时,我是否回头去翻书复习?不。相反,我依靠我个人的经验,事实证明这对我来说比专家写的成千上万页书更有用和更令人安心。 Fred Brooks 在他的文章《没有银弹》中提出了寻找优秀软件设计师的三部分计划: 1. 尽早系统性地识别顶级设计师。 2. 指派一位职业导师负责培养候选人,并精心维护职业档案。 3. 为成长中的设计师提供互相交流与激励的机会。 这假设有些人已经具备了成为优秀设计师所需的品质;工作就是恰当地引导他们前进。Alan Perlis 更简洁地表达了:“每个人都可以被教去雕刻:米开朗基罗却需要被教如何不去雕刻。伟大的程序员也是如此。”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. --- ## 答案 典型 PC 上各种操作的大致时间: 执行典型指令:1/1,000,000,000 秒 = 1 纳秒 从 L1 缓存取数据:0.5 纳秒 分支预测失败:5 纳秒 从 L2 缓存取数据:7 纳秒 互斥锁加锁/解锁:25 纳秒 从主存取数据:100 纳秒 在 1Gbps 网络上发送 2K 字节:20,000 纳秒 从内存顺序读取 1MB:250,000 纳秒 从新磁盘位置取数据(寻道):8,000,000 纳秒 从磁盘顺序读取 1MB:20,000,000 纳秒 从美国到欧洲往返发送数据包:150 毫秒 = 150,000,000 纳秒 --- ## 附录:语言选择 有几个人问应该先学哪种编程语言。没有唯一答案,但考虑以下几点: - **用你朋友的选择。** 当被问到“我应该用哪种操作系统,Windows、Unix 还是 Mac?”我的答案通常是:“用你朋友用的那个。”从朋友那里学习的好处将抵消操作系统或编程语言之间的任何内在差异。也要考虑你未来的朋友:你将继续参与的程序员社区。你选择的语言有庞大且增长中的社区,还是小而垂死的?有书籍、网站和在线论坛可以获取答案吗?你喜欢那些论坛里的人吗? - **保持简单。** 像 C++ 和 Java 这样的编程语言是为大型团队的专业开发而设计的,这些开发人员关心代码的运行效率。因此,这些语言有为此设计的复杂部分。你关心的是学习编程。你不需要那种复杂性。你想要一种为单个新手程序员设计、易于学习和记忆的语言。 - **玩着学。** 你更喜欢哪种方式学钢琴:正常的交互方式,每次按键就能听到音符;还是“批处理”模式,只有在弹完整首曲子后才能听到音符?显然,交互模式让钢琴学习更容易,编程也一样。坚持使用带有交互模式的语言,并使用它。 根据这些标准,我推荐的第一门编程语言是 **Python** 或 **Scheme**。另一个选择是 JavaScript,不是因为它是为初学者完美设计的,而是因为有大量的在线教程,比如 Khan Academy 的教程。但你的情况可能不同,还有其他好的选择。如果你的年龄还是个位数,你可能更喜欢 Alice 或 Squeak。

相似文章

以理论构建的视角阅读编程

Hacker News Top

本文推荐 Peter Naur 的著作《编程即理论构建》,主张编程的本质在于构建和传达对软件的心理模型,而不仅仅是编写代码。

编程作为理论构建(1985)

Lobsters Hottest

这篇彼得·诺尔(Peter Naur)于1985年发表的论文指出,编程本质上是一种理论构建活动,程序员需要深入理解问题领域,而不仅仅是生成代码。

编程猿 (Code Hale, 2012) [视频]

Hacker News Top

文章解释了软件应该设计得符合人类认知系统,特别是快速直觉和慢速注意过程,以提高效果和用户体验。

老实说,我现在确实认为AI将在几年内掌握编程

Reddit r/singularity

一位程序员反思了AI在编码方面的快速进步,指出像Claude这样的模型现在在系统架构和重构等高级任务上表现出色,并预测AI将在几年内掌握编程,当前的限制只是暂时的驾驭问题。