Teach Yourself Programming in Ten Years
Peter Norvig
Why is everyone in such a rush?
Walk into any bookstore, and you'll see how to Teach Yourself Java in 24 Hours alongside endless variations offering to teach C, SQL, Ruby, Algorithms, and so on in a few days or hours. The Amazon advanced search for [title: teach, yourself, hours, since: 2000 and found 512 such books. Of the top ten, nine are programming books (the other is about bookkeeping). Similar results come from replacing "teach yourself" with "learn" or "hours" with "days."
The conclusion is that either people are in a big rush to learn about programming, or that programming is somehow fabulously easier to learn than anything else. Felleisen et al. give a nod to this trend in their book How to Design Programs, when they say "Bad programming is easy. Idiots can learn it in 21 days, even if they are dummies." The Abtruse Goose comic also had their take.
Let's analyze what a title like Teach Yourself C++ in 24 Hours could mean:
Teach Yourself: In 24 hours you won't have time to write several significant programs, and learn from your successes and failures with them. You won't have time to work with an experienced programmer and understand what it is like to live in a C++ environment. In short, you won't have time to learn much. So the book can only be talking about a superficial familiarity, not a deep understanding. As Alexander Pope said, a little learning is a dangerous thing.
C++: In 24 hours you might be able to learn some of the syntax of C++ (if you already know another language), but you couldn't learn much about how to use the language. In short, if you were, say, a Basic programmer, you could learn to write programs in the style of Basic using C++ syntax, but you couldn't learn what C++ is actually good (and bad) for. So what's the point? Alan Perlis once said: "A language that doesn't affect the way you think about programming, is not worth knowing". One possible point is that you have to learn a tiny bit of C++ (or more likely, something like JavaScript or Processing) because you need to interface with an existing tool to accomplish a specific task. But then you're not learning how to program; you're learning to accomplish that task.
in 24 Hours: Unfortunately, this is not enough, as the next section shows.
Teach Yourself Programming in Ten Years
Researchers (Bloom (1985), Bryan & Harter (1899), Hayes (1989), Simmon & Chase (1973)) have shown it takes about ten years to develop expertise in any of a wide variety of areas, including chess playing, music composition, telegraph operation, painting, piano playing, swimming, tennis, and research in neuropsychology and topology. The key is deliberative practice: not just doing it again and again, but challenging yourself with a task that is just beyond your current ability, trying it, analyzing your performance while and after doing it, and correcting any mistakes. Then repeat. And repeat again. There appear to be no real shortcuts: even Mozart, who was a musical prodigy at age 4, took 13 more years before he began to produce world-class music. In another genre, the Beatles seemed to burst onto the scene with a string of #1 hits and an appearance on the Ed Sullivan show in 1964. But they had been playing small clubs in Liverpool and Hamburg since 1957, and while they had mass appeal early on, their first great critical success, Sgt. Peppers, was released in 1967.
Malcolm Gladwell has popularized the idea, although he concentrates on 10,000 hours, not 10 years. Henri Cartier-Bresson (1908-2004) had another metric: "Your first 10,000 photographs are your worst." (He didn't anticipate that with digital cameras, some people can reach that mark in a week.) True expertise may take a lifetime: Samuel Johnson (1709-1784) said "Excellence in any department can be attained only by the labor of a lifetime; it is not to be purchased at a lesser price." And Chaucer (1340-1400) complained "the lyf so short, the craft so long to lerne." Hippocrates (c. 400BC) is known for the excerpt "ars longa, vita brevis", which is part of the longer quotation "Ars longa, vita brevis, occasio praeceps, experimentum periculosum, iudicium difficile", which in English renders as "Life is short, [the] craft long, opportunity fleeting, experiment treacherous, judgment difficult." Of course, no single number can be the final answer: it doesn't seem reasonable to assume that all skills (e.g., programming, chess playing, checkers playing, and music playing) could all require exactly the same amount of time to master, nor that all people will take exactly the same amount of time. As Prof. K. Anders Ericssonputs it, "In most domains it's remarkable how much time even the most talented individuals need in order to reach the highest levels of performance. The 10,000 hour number just gives you a sense that we're talking years of 10 to 20 hours a week which those who some people would argue are the most innately talented individuals still need to get to the highest level."
So You Want to be a Programmer
Here's my recipe for programming success:
Get interested in programming, and do some because it is fun. Make sure that it keeps being enough fun so that you will be willing to put in your ten years/10,000 hours.
Program. The best kind of learning is learning by doing. To put it more technically, "the maximal level of performance for individuals in a given domain is not attained automatically as a function of extended experience, but the level of performance can be increased even by highly experienced individuals as a result of deliberate efforts to improve." (p. 366) and "the most effective learning requires a well-defined task with an appropriate difficulty level for the particular individual, informative feedback, and opportunities for repetition and corrections of errors." (p. 20-21) The book Cognition in Practice: Mind, Mathematics, and Culture in Everyday Life is an interesting reference for this viewpoint.
Talk with other programmers; read other programs. This is more important than any book or training course.
If you want, put in four years at a college (or more at a graduate school). This will give you access to some jobs that require credentials, and it will give you a deeper understanding of the field, but if you don't enjoy school, you can (with some dedication) get similar experience on your own or on the job. In any case, book learning alone won't be enough. "Computer science education cannot make anybody an expert programmer any more than studying brushes and pigment can make somebody an expert painter" says Eric Raymond, author of The New Hacker's Dictionary. One of the best programmers I ever hired had only a High School degree; he's produced a lot of great software, has his own news group, and made enough in stock options to buy his own nightclub.
Work on projects with other programmers. Be the best programmer on some projects; be the worst on some others. When you're the best, you get to test your abilities to lead a project, and to inspire others with your vision. When you're the worst, you learn what the masters do, and you learn what they don't like to do (because they make you do it for them).
Work on projects after other programmers. Understand a program written by someone else. See what it takes to understand and fix it when the original programmers are not around. Think about how to design your programs to make it easier for those who will maintain them after you.
Learn at least a half dozen programming languages. Include one language that emphasizes class abstractions (like Java or C++), one that emphasizes functional abstraction (like Lisp or ML or Haskell), one that supports syntactic abstraction (like Lisp), one that supports declarative specifications (like Prolog or C++ templates), and one that emphasizes parallelism (like Clojure or Go).
Remember that there is a "computer" in "computer science". Know how long it takes your computer to execute an instruction, fetch a word from memory (with and without a cache miss), read consecutive words from disk, and seek to a new location on disk. (Answers here.)
Get involved in a language standardization effort. It could be the ANSI C++ committee, or it could be deciding if your local coding style will have 2 or 4 space indentation levels. Either way, you learn about what other people like in a language, how deeply they feel so, and perhaps even a little about why they feel so.
Have the good sense to get off the language standardization effort as quickly as possible.
With all that in mind, its questionable how far you can get just by book learning. Before my first child was born, I read all the How To books, and still felt like a clueless novice. 30 Months later, when my second child was due, did I go back to the books for a refresher? No. Instead, I relied on my personal experience, which turned out to be far more useful and reassuring to me than the thousands of pages written by experts.
Fred Brooks, in his essay No Silver Bullet identified a three-part plan for finding great software designers:
Systematically identify top designers as early as possible.
Assign a career mentor to be responsible for the development of the prospect and carefully keep a career file.
Provide opportunities for growing designers to interact and stimulate each other.
This assumes that some people already have the qualities necessary for being a great designer; the job is to properly coax them along. Alan Perlis put it more succinctly: "Everyone can be taught to sculpt: Michelangelo would have had to be taught how not to. So it is with the great programmers". Perlis is saying that the greats have some internal quality that transcends their training. But where does the quality come from? Is it innate? Or do they develop it through diligence? As Auguste Gusteau (the fictional chef inRatatouille) puts it, "anyone can cook, but only the fearless can be great." I think of it more as willingness to devote a large portion of one's life to deliberative practice. But maybe fearless is a way to summarize that. Or, as Gusteau's critic, Anton Ego, says: "Not everyone can become a great artist, but a great artist can come from anywhere."
So go ahead and buy that Java/Ruby/Javascript/PHP book; you'll probably get some use out of it. But you won't change your life, or your real overall expertise as a programmer in 24 hours or 21 days. How about working hard to continually improve over 24 months? Well, now you're starting to get somewhere...
References
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.
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.
AnswersApproximate timing for various operations on a typical PC:
execute typical instruction1/1,000,000,000 sec = 1 nanosec
fetch from L1 cache memory0.5 nanosec
branch misprediction5 nanosec
fetch from L2 cache memory7 nanosec
Mutex lock/unlock25 nanosec
fetch from main memory100 nanosec
send 2K bytes over 1Gbps network20,000 nanosec
read 1MB sequentially from memory250,000 nanosec
fetch from new disk location (seek)8,000,000 nanosec
read 1MB sequentially from disk20,000,000 nanosec
send packet US to Europe and back150 milliseconds = 150,000,000 nanosec
Appendix: Language Choice
Several people have asked what programming language they should learn first. There is no one answer, but consider these points:
Use your friends. When asked "what operating system should I use, Windows, Unix, or Mac?", my answer is usually: "use whatever your friends use." The advantage you get from learning from your friends will offset any intrinsic difference between OS, or between programming languages. Also consider your future friends: the community of programmers that you will be a part of if you continue. Does your chosen language have a large growing community or a small dying one? Are there books, web sites, and online forums to get answers from? Do you like the people in those forums?
Keep it simple. Programming languages such as C++ and Java are designed for professional development by large teams of experienced programmers who are concerned about the run-time efficiency of their code. As a result, these languages have complicated parts designed for these circumstances. You're concerned with learning to program. You don't need that complication. You want a language that was designed to be easy to learn and remember by a single new programmer.
Play. Which way would you rather learn to play the piano: the normal, interactive way, in which you hear each note as soon as you hit a key, or "batch" mode, in which you only hear the notes after you finish a whole song? Clearly, interactive mode makes learning easier for the piano, and also for programming. Insist on a language with an interactive mode and use it.
Given these criteria, my recommendations for a first programming language would be Python or Scheme. Another choice is Javascript, not because it is perfectly well-designed for beginners, but because there are so many online tutorials for it, such as Khan Academy's tutorial. But your circumstances may vary, and there are other good choices. If your age is a single-digit, you might prefer Alice or Squeak or Blockly (older learners might also enjoy these). The important thing is that you choose and get started.
Appendix: Books and Other Resources
Several people have asked what books and web pages they should learn from. I repeat that "book learning alone won't be enough" but I can recommend the following:
Scheme: Structure and Interpretation of Computer Programs (Abelson & Sussman) is probably the best introduction to computer science, and it does teach programming as a way of understanding the computer science. You can see online videos of lectures on this book, as well as the complete text online. The book is challenging and will weed out some people who perhaps could be successful with another approach.
Scheme: How to Design Programs (Felleisen et al.) is one of the best books on how to actually design programs in an elegant and functional way.
Python: Python Programming: An Intro to CS (Zelle) is a good introduction using Python.
Python: Several online tutorials are available at Python.org.
Oz: Concepts, Techniques, and Models of Computer Programming (Van Roy & Haridi) is seen by some as the modern-day successor to Abelson & Sussman. It is a tour through the big ideas of programming, covering a wider range than Abelson & Sussman while being perhaps easier to read and follow. It uses a language, Oz, that is not widely known but serves as a basis for learning other languages.
翻译:
十年内自学编程
彼得·诺维格
为什么大家都这么着急?
走进任何一家书店,您将了解如何在 24 小时内自学 Java,同时在几天或几小时内提供无休止的变体来教授 C、SQL、Ruby、算法等。亚马逊高级搜索 [标题: 教, 你自己, 小时, 自: 2000 年以来, 并发现了 512 这样的书。前十名中,有九本是编程书籍(另一本是关于簿记的)。类似的结果来自将"自学"替换为"学习"或"小时"与"天"。
结论是,要么人们急于学习编程,要么编程比什么都容易学。Felleisen等人在《如何设计程序》一书中对这种趋势点头,当时他们说"糟糕的编程很容易。白痴可以在21天内学会,即使他们是假人。阿布特鲁斯鹅漫画也有他们采取。
让我们分析一下 24 小时内"C++"标题可能意味着什么:
教导自己:在24小时内,你将没有时间写几个重要的程序,并学习你的成功和失败与他们。您没有时间与经验丰富的程序员合作,并了解生活在一个良好的环境中C++。总之,你将没有时间学习太多。所以这本书只能说是肤浅的熟悉,不能是深刻的理解。正如亚历山大·波普说的,一点学习是危险的事情。
C++:在24小时内,你也许能够学习C++的一些语法(如果你已经知道另一种语言),但你不能学到很多如何使用的语言。简言之,如果你是一个基本程序员,你可以学会用C++语法编写基本风格的程序,但是你不能学习C++实际上是好(和坏)什么。那有什么意义呢?艾伦·佩利斯曾经说过:"一种不影响你编程方式的语言,不值得了解。一个可能的观点是,你必须学习一点点C++(或者更可能,像JavaScript或处理),因为你需要与现有的工具接口来完成一个特定的任务。但是,你并没有学习如何编程;你正在学习完成那个任务
在24小时:不幸的是,这是不够的,如下一节显示。
十年内自学编程
研究人员(Bloom(1985年)、布莱恩和哈特(1899年)、海耶斯(1989年)、西蒙和蔡斯(1973年))表明,在象棋、音乐创作、电报操作、绘画、钢琴演奏、游泳、网球以及神经心理学和拓扑学研究等许多领域,大约需要10年时间。关键是审议实践:不只是一次又一次地做,而是用一个超出你当前能力的任务来挑战自己,尝试一下,在做之后分析你的表现,并纠正任何错误。然后重复。再重复一遍似乎没有真正的捷径:即使是4岁时音乐神童的莫扎特,也花了13年时间才开始创作世界级的音乐。在另一种类型中,披头士乐队似乎以一连串的#1和1964年埃德·沙利文的时装秀而登上舞台。但是他们自1957年以来一直在利物浦和汉堡打小俱乐部,虽然他们很早就有大众的吸引力,但他们的第一次重大成功,佩珀斯中士,在1967年被释放。
马尔科姆·格拉德威尔已经推广了这个想法,尽管他专注于10,000小时,而不是10年。亨利·卡蒂埃-布雷森(1908-2004)还有另一个指标:"你的前10,000张照片是你们最差的。"(他没想到,使用数码相机,有些人可以在一个星期内达到这个目标。真正的专业知识可能需要一生的时间:塞缪尔·约翰逊(Samuel Johnson,1709-1784)说:"任何部门都只有一生的劳动才能取得卓越成就;它不应该以较低的价格购买。乔瑟 (1340 - 1400) 抱怨道: "莱夫这么短, 工艺这么久, 对勒恩来说。Hippocrates (c. 400BC) 以摘录 "ars longa, vita brevis" 而广为人知, 这是较长语录 "阿尔斯 · 朗加, 维塔 · 布雷维斯, 偶尔练习, 实验腹膜, 胆汁困难" 的一部分, 在英语中渲染为 "生命是短暂的, [the] 工艺长, 机会转瞬即逝, 实验背信弃义, 判断困难" 。当然,没有一个数字可以是最终的答案:似乎不合理地假设所有技能(如编程、棋牌、跳棋和音乐演奏)都需要完全相同的时间来掌握,也不认为所有人都需要完全相同的时间。正如安德斯·爱立信教授所说,"在大多数领域,即使是最有才华的个人也需要多少时间才能达到最高水平,这一点令人瞩目。10,000 小时的数字只是让您感觉到,我们谈论的是每周 10 到 20 小时,有些人会认为这些人是天生的天才人才,仍然需要达到最高水平。
所以你想成为一名程序员
以下是我的编程成功秘诀:
对编程感兴趣,并做一些,因为它很有趣。确保它一直足够有趣,这样你才愿意投入你的十年/10,000小时。
程序。最好的学习就是通过做学习。更技术上说,"给定领域中个人的最高绩效水平不是作为扩展经验的函数自动实现的,但即使经验丰富的个人,由于经过深思熟虑,可以提高绩效水平。罗夫。(第366)和"最有效的学习需要一个明确界定的任务,对于特定的个人,信息丰富的反馈,以及重复和纠正错误的机会,具有适当的难度级别。(第20-21号)《实践认知:日常生活中的思维、数学和文化》一书是这一观点的有趣参考。
与其他程序员交谈;阅读其他程序。这一点比任何书籍或培训课程都重要。
如果你想的话,在一所大学里工作四年(或者多在研究生院)。这将让您访问一些需要证书的工作,并让您更深入地了解该领域,但如果您不喜欢学校,您可以(有一些奉献精神)获得类似的经验,自己或工作。无论如何,单靠书本学习是不够的。《新黑客词典》的作者埃里克·雷蒙德(Eric Raymond)说:"计算机科学教育不能让任何人成为专家程序员,更不能让任何人成为专家程序员,更不能让任何人成为专家画家。我雇佣过的最好的程序员之一只有高中学位;他制作了很多伟大的软件, 有自己的新闻集团, 并做了足够的股票期权, 以购买自己的夜总会。
与其他程序员一起处理项目。成为某些项目的最佳程序员;是其他人最差的。当你是最好的,你可以测试你的能力,领导一个项目,并激励别人与你的远见。当你是最差的时候,你学习主人做什么,你学习他们不喜欢做什么(因为他们让你为他们做)。
在其他程序员之后处理项目。了解其他人编写的程序。看看当原始程序员不在的时候,需要什么来理解和修复它。考虑如何设计程序,使那些在您之后维护程序的人更容易。
学习至少六种编程语言。包括一种强调类抽象的语言(如Java或C++)、一种强调函数抽象的语言(如Lisp或ML或哈斯克尔)、一种支持句法抽象的语言(如Lisp)、一种支持声明性规范(如Prolog或C++模板)的语言,以及一种强调并行性的语言(如Cljure或 Go)。
请记住,"计算机科学"中存在"计算机"。了解计算机执行指令、从内存中获取单词(有和没有缓存错过)、从磁盘读取连续单词以及查找磁盘上的新位置需要多长时间。(答案在这里。
参与语言标准化工作。它可能是 ANSI C++,也可以决定您的本地编码风格是否具有 2 或 4 个空间缩进级别。无论哪种方式,你都了解别人喜欢的语言,他们感觉有多深,甚至一点点关于他们为什么这样的感觉。
有好感,尽快摆脱语言标准化工作。
想到这一切, 你只要通过书本学习能多远, 就值得怀疑了。在我的第一个孩子出生之前,我读了所有的《如何》一书,仍然觉得自己是一个无知的新手。30 个月后, 当我的第二个孩子到期时, 我回到书本上复习一下吗?不。相反,我依靠我个人的经验,事实证明,这比我有用和放心得多,比专家写的数千页。
弗雷德·布鲁克斯在他的论文《没有银弹》中确定了寻找伟大软件设计师的三部分计划:
尽早系统地确定顶级设计师。
指派一位职业导师负责潜在客户的发展,并仔细保存职业档案。
为成长的设计师提供互动和刺激的机会。
这假定有些人已经具备成为伟大设计师所需的素质;工作是正确地哄他们一起。艾伦·佩利斯说得更简洁:"每个人都可以被教导去雕刻:米开朗基罗必须被教导如何不雕刻。因此,这是与伟大的程序员"。佩利斯说,伟大的球员有一些超越他们训练的内部素质。但是质量从何而来呢?是天生的吗?还是他们通过勤奋来发展?正如奥古斯特·古斯托(拉塔图耶虚构的厨师)所说,"任何人都可以做饭,但只有无所畏惧的人才能是伟大的。我认为更多的是愿意把一生中的很大一部分用于审议实践。但也许无所畏惧是总结这一点的一种方式。或者,正如古斯托的批评家安东·埃戈所说:"不是每个人都能成为一个伟大的艺术家,但一个伟大的艺术家可以来自任何地方。
因此,继续购买 Java/Ruby/Javascript/PHP 书籍;你可能会从中得到一些利用。但你不会改变你的生活,或者你作为程序员在24小时或21天内真正的整体专业知识。努力在24个月内不断改进怎么样?现在你开始找个地方了...
引用
布鲁姆,本杰明(Ed.)培养年轻人的人才,巴兰廷,1985年。
布鲁克斯, 弗雷德, 没有银弹, IEEE 电脑, 第 20 卷, 第 4 号, 1987 年, 第 10 - 19 周。
布莱恩, W. l. – 哈特, N. "关于电报语言的研究: 获得习惯的层次。心理学评论, 1899, 8, 345-375
海斯,约翰R.,完全问题解决者劳伦斯·埃鲍姆,1989年。
蔡斯, 威廉 G. & 西蒙, 赫伯特 A. "国际象棋感知" 认知心理学, 1973 年, 4, 55 - 81 。
拉夫,让,实践认知:思维,数学和文化的日常生活,剑桥大学出版社,1988年。
答案
典型 PC 上各种操作的大致计时:
执行典型指令 1/1,000,000,000 秒 = 1 纳米秒从 L1 缓存内存 0。5 nanosec 分网预测错误 5 纳米秒从 L2 缓存存储器 7 nanosecMutex 锁 / 解锁 25 nanosecfetch 从主存储器 100 nanosecsend 2K 字节超过 1Gbps 网络 20,000 nanosecread 1MB 顺序从内存 250,000 从新的磁盘位置 (寻求) 8,000,000 nanosecread 1MB 顺序从磁盘 20,000,000 nanosec 发送数据包美国到欧洲和回 150 毫秒 = 150,000,000 nanosec
附录:语言选择
有几个人问他们应该先学什么编程语言。没有一个答案,但请考虑以下几点:
用你的朋友。当被问及"我应该使用什么操作系统,Windows,Unix,还是Mac?从朋友那里学习的好处将抵消操作系统之间或编程语言之间的任何内在差异。还要考虑你未来的朋友:如果你继续,你将成为其中一员的程序员社区。您选择的语言是有一个庞大的成长社区还是一个垂死的小社区?是否有书籍、网站和在线论坛可以获得答案?你喜欢那些论坛里的人吗?
保持简单。编程语言(C++ 和 Java)是由经验丰富的程序员团队为专业开发而设计的,他们关注代码的运行时效率。因此,这些语言具有专为这些情况设计的复杂部分。你关心的是学习编程。你不需要这种并发症。您想要一种由单个新程序员设计得易于学习和记忆的语言。
玩。你宁愿学习哪种方式弹钢琴:正常的互动方式,你一点击一个键,或"批"模式,你只听到音符后,你完成了一整首歌?显然,交互式模式使钢琴和编程的学习更加容易。坚持使用交互式模式的语言并使用它。
鉴于这些标准,我对第一种编程语言的建议将是Python或S方案。另一个选择是Javascript,不是因为它是为初学者设计得完美的,而是因为有这么多的在线教程,如Khan学院的教程。但是,你的情况可能会有所不同,还有其他不错的选择。如果你的年龄是一位数,你可能更喜欢爱丽丝或吱吱声或块(年龄较大的学习者也可能喜欢这些)。重要的是你选择并开始。
附录:书籍和其他资源
有几个人问他们应该从哪些书籍和网页中学习。我再说一遍, "单靠书学习是不够的", 但我可以推荐以下内容:
方案:计算机程序的结构和解释(Abelson & Sussman)可能是计算机科学的最佳介绍,它教编程作为理解计算机科学的一种方式。您可以在线查看有关本书的讲座视频,以及完整的文本。这本书很有挑战性,将一些人从另一种方法中去掉。
方案:如何设计程序(Felleisen等人)是有关如何以优雅和实用的方式实际设计程序的最佳书籍之一。
Python: Python 编程: 使用 Python 的 Cs 简介 (Zelle) 是一个很好的介绍。
Python:在一些在线教程Python.org。
奥兹: 计算机编程的概念、技术和模型 (范罗伊和哈里迪) 被一些人视为阿贝尔森和苏斯曼的现代接班人。这是一个通过编程的大想法之旅, 涵盖比亚伯森和苏斯曼更广泛的范围, 而也许更容易阅读和遵循。它使用一种语言,Oz,这是不广为人知,但作为学习其他语言的基础。<
笔记
T. Capey指出,亚马逊上的"完全问题解决者"页面现在有"在21天内自学孟加拉语"和"自学语法和风格"的书籍下"为这个项目购物的顾客也为这些物品购物"部分。我猜看那本书的人很多来自这个页面。感谢罗斯·科恩对希波克拉底的帮助。