10年自学编程

10年自学编程

Teach Yourself Programming in Ten Years

By Peter Norvig (真*大神,不认识的可以自行“Google”)

原文链接:http://norvig.com/21-days.html

为什么大家都很心急?

如果你走进书店,你就会看到这样的书:Java自学一日通或者C、SQL、Ruby、算法自学三月通。如果去Amazon搜索title: teach, youself, hours, since: 2000,你会发现512本书。前10本书中,有9本是编程书籍,还有一个本是关于书籍管理的。如果把自学替换成学习,小时换成天,会得到类似的结果。

结论是:要么人们很急切的想要学习编程,要么学习编程比学习其他技能更加容易。《How to design programs》的作者们“认可”了这个说法,书中提到:“差劲的编程很简单,傻子都能在21天内学会编程,即使他们是傻子”。Abtruse Goose的搞笑漫画持类似观点

21天学会C++

我们来分析一下:24小时自学C++:

  • 自学:24小时,你没有时间写出一些有用的程序,并且从这些项目中吸取经验教训。你也没有时间与一个有经验的C++程序员一起工作并且理解真实的C++开发环境。长话短说,你没有时间学很多东西。所以这个本书只能给你一种假的熟悉感,而不是深入理解。就像Alexander Pope说的:学一点点是很危险的!
  • C++:24小时的时间,你可能可以学一点C++的语法(如果你之前接触过其他编程语言),但是你不能学到很多关于如何使用这个语言的内容。总之,假设你是一个Basic程序员,你可能会学会用Basic的模式写C++,但是你不会理解C++实际的长度和弊端。如果这样的话,为什么还要学呢?Alan Perlis 说过:“一个计算机语言如果不能影响你思考编程的方式,那么这个语言不值得学习”。还有一个可能的观点是,为了完成一个需要与其他语言交互的任务,你需要学一点点C++(或是 JavaScript 或 Processing)。但是你并没有学习如何编程,而是学习完成一个那个任务。
  • 24小时:时间不够!下个小节说明

10年自学编程

研究表明(Researchers (Bloom (1985), Bryan & Harter (1899), Hayes (1989), Simmon & Chase (1973))):在大多数领域达到专家水平需要大约10年时间,这些领域包括但不完全:象棋、作曲、网球、钢琴、绘画、游泳等等。而成功的关键在于刻意练习:不是无意义的重复,而是永远做一些有挑战的事情,并且做得过程中和完成后分析经验教训。然后,需要不断重复这个过程!在成为专家的路上似乎没有捷径:即使是莫扎特也不例外。他4岁就是个音乐奇才了,他仍然花了13年才做出了世界级别的音乐。披头士乐队也是如此,1964年他们在Ed Sullivan秀登台并且带来了一连串的经典歌曲,可是他们从1957年开始就在利物浦和汉堡的小酒吧里演出了,而他们的传奇专辑《Sgt.Peppers》在1967年才问世。

Malcolm Gladwell让这个观点更加流行了,尽管他在说中提到的是1万小时而不是10年。Henri Cartier-Bresson (1908-2004) 提到过:“你的前1万张照片是你最差的作品!”(不过在他的时代还没数码相机,现在人们可以在一周实现1万张了)。真正的专业水准需要一生的时间:Samuel Johnson (1709-1784) 说:“在任何领域获得杰出成就的价格都是一生的努力,没有更便宜的价格了”。Chaucer (1340-1400) 抱怨到:“生之有限,学也无涯”。K. Anders Ericsson教授提到::“在大多数领域中,即使是最有才华的人也需要多少时间才能达到最高水平的表现,这一点很了不起。 1万小时的数字只是让你觉得我们在谈论的是每周 10 到 20 小时,有些人认为这些是最有天赋的人仍然需要达到最高水平。”

所以,你想要成为一个程序员?

下面我列出成为成功程序员的要素:

  • 兴趣。确保自己对编程有足够的兴趣,因为这样你才愿意话10年或者1万小时编程
  • 程序。做好的学习就是实践。从技术角度说,你在某个领域达到的最好程度不一定会随着经验提高,但是通过刻意练习,即使你已经很厉害了,你还是可以获得提高。最有效的学习需要一个明确的、难度合适的任务,同时需要其他人的反馈以及重复和纠错的机会。Cognition in Practice: Mind, Mathematics, and Culture in Everyday Life在这方面很有帮助。
  • 交流。与其他程序员交流,阅读别人的程序。这一点比任何书籍和课程都重要。
  • 如果你愿意,去大学或者研究生院学习4年。这样你有就会获得一些需要学历的工作,同时你会更加深刻的理解计算机科学。但是如果你不想上学,你也可以通过自学或者工作经验弥补。不论哪种情况,只靠读书是不够的。《The New Hacker’s Dictionary》的作者 Eric Raymond说:“计算机科学教育不可能让每一个学生都成为专家级程序员,就像你不能通过学习画笔和颜料成为一个画家一样”。我(Peter)雇佣过最好的程序员之一只有高中学历,但是他做出了很多出色的软件,他有自己的新闻组,他甚至得到了足够多的股权去买一个夜店
  • 与其他程序员一起做项目。在一些项目里你是最好的;而另一些里面你是最差的。当你是最好的程序员,你可以测试你的领导能力;当你是最差的,你可以跟那些大师学习,学习他们希望做的和他们不希望做的(因为他们会让你做。。)
  • 追随其他程序员的项目。理解别人写的程序。学会如何理解和修复一个出问题的程序,思考自己的项目怎么写可以让后来的人维护起来更方便,
  • 至少学6个计算机语言。包括一个强调类型抽象的(比如C++,Java),一个强调函数式抽象的(比如Lisp、ML、Haskel),一个支持语法抽象的(比如Lisp),一个支持声明式说明的(比如Prolog或者C++模板),和一个强调并行的(小编:我觉得这里作者可能想说的是并发而不是并行)(比如Clojure或者Go)
  • 记住:计算机科学里面有一个“计算机”。知道你的计算机需要多长时间执行一个指令、从内存读取一个词(有缓存或者没有缓存的情况)、从硬盘读取一个词或者在硬盘寻址。答案在最后一小节 <-
  • 参与一个语言的标准化。可以是ANSI C++委员会,或者是你自己的编码风格是2个还是4个空格。无论哪种方式,你会学习那些东西是其他人喜欢的,以及为什么人们喜欢。
  • 能够感知什么时候放弃语言标准化。

说了这么多,我们开始质疑仅仅通过阅读书籍你可以走多远?在我第一个孩子出生以前,我读了各种“如何做”的书,却还是觉得自己是个菜鸟。30个月后,当我的第二个孩子要出生的时候,我回去看那些书了吗?没有!相反,我依靠我的第一个孩子的经验,事实也证明这些经验比那些“专家”给出的建议更有用。

Fred Brooks在他的文章《No Silver Bullet》发现了一个找到好的软件设计者的3步走计划:

  1. 尽早系统化地识别顶级设计师
  2. 指定一个职业导师
  3. 提供与其他设计师交流的机会

这假设有些人已经具备成为伟大设计师所需的素质; 工作是引导他们前进。 Alan Perlis 更简洁地说:“每个人都可以学会雕刻:米开朗基罗必须学会如何不雕刻。伟大的程序员也是如此”。 玻璃市说,伟人有一些超越他们训练的内在品质。 但是,在没有质量从何而来? 是天生的吗? 还是他们通过勤奋来发展它? 正如 Auguste Gusteau(《料理鼠王》中的虚构厨师)所说,“任何人都可以做饭,但只有无所畏惧的人才是伟大的。” 我认为它更像是愿意将一个人一生的大部分时间用于深思熟虑的实践。 但也许无所畏惧是总结这一点的一种方式。 或者,正如 Gusteau 的评论家 Anton Ego 所说:“不是每个人都能成为伟大的艺术家,但伟大的艺术家可以来自任何地方。”

所以去买那本 Java/Ruby/Javascript/PHP 书吧; 你可能会从中得到一些用处。 但是你不会在 24 小时或 21 天内改变你的生活,或者你作为程序员的真正整体专业知识。努力工作以在 24 个月内持续改进怎么样?好吧,现在开始你的旅程把。。。

答案

任务 时间(纳秒)
执行一条指令 1
L1缓存读取 0.5
分支预测错误 5
L2缓存读取 7
互斥锁操作 25
内存读取 100
在1Gbps网络发送2kb数据 20000
从内存顺序读取1MB数据 250000
从本地磁盘读取一个新的位置(seek) 8毫秒
从本地磁盘顺序读取1MB数据 20 毫秒
在美国和欧洲之间传递数据 150 毫秒

附录:语言选择

很多人问过:第一个计算机语言应该学什么?没有固定的答案,但是考虑如下三点:

  • 选你朋友用的。当被问到:“我该用那个操作系统,Wondows,Unix还是MacOS?” 的时候,我的回答通常是:用你周围朋友用的。您从朋友那里学到的优势将抵消操作系统之间或编程语言之间的任何内在差异。 还要考虑你未来的朋友:如果你继续下去,你将成为其中一员的程序员社区。 你选择的语言有一个庞大的成长社区还是一个正在消亡的小社区? 是否有书籍、网站和在线论坛可以获取答案? 你喜欢那些论坛里的人吗?
  • 把事情简单化。 C++ 和 Java 等编程语言是为由关心代码运行时效率的经验丰富的程序员组成的大型团队而设计的。 因此,这些语言具有为这些情况设计的复杂部分。 你关心的是学习编程。 你不需要那种复杂性。 您需要一种设计为易于单个新程序员学习和记忆的语言。
  • 玩。 您更愿意以哪种方式学习弹钢琴:正常的交互式方式,即您在敲击琴键后立即听到每个音符,或“批处理”模式,在这种方式中,您仅在完成一首歌曲后才听到音符 ? 显然,交互模式使钢琴学习和编程更容易。 坚持一种具有交互模式的语言并使用它。

鉴于这些标准,我对第一种编程语言的建议是 Python 或 Scheme。 另一个选择是 Javascript,不是因为它非常适合初学者,而是因为它的在线教程太多了,例如可汗学院的教程。 但是您的情况可能会有所不同,还有其他不错的选择。 如果您的年龄是个位数,您可能更喜欢 Alice 或 Squeak 或 Blockly(年龄较大的学习者可能也喜欢这些)。重要的是你选择并开始编程。

欢迎关注 泛程序员 获得更多编程知识: