十年内自学编程
彼得·诺维格
为什么大家都这么着急?
走进任何一家书店,您将看到如何在24小时内教会自己Java,以及提供在几天或几小时内教授C、SQL、Ruby、算法等的无休止的变体。亚马逊高级搜索[标题:教学,你自己,小时,自2000年以来,发现512这样的书。在前十名中,有九本是编程书(另一本是关于簿记的)。类似的结果来自于将“自学”改为“学习”,或将“小时”替换为“天”。
结论是,要么人们急于学习编程,要么编程比其他任何东西都容易得多。费莱森等人在他们的“如何设计程序”(How To Design Program)一书中,他们表示:“糟糕的编程很容易,白痴可以在21天内学会它,即使他们是假人。”这位狂暴的鹅漫画也有自己的想法。
让我们分析24小时内自学C++这样的标题可能意味着什么:
自学:在24小时内,你就没有时间写几个重要的程序,从你的成功和失败中吸取教训。您将没有时间与有经验的程序员一起工作,并了解在C++环境中生活是什么感觉。总之,你没有时间学到很多东西。因此,这本书只能谈论一种肤浅的熟悉,而不是一种深刻的理解。正如亚历山大·波普所说,一点点学习是一件危险的事情。
C++:在24小时内,您可能可以学习C++的一些语法(如果您已经知道另一种语言),但您无法了解如何使用该语言。简单地说,如果你是一个基本程序员,你可以学习用C++语法以Basic的方式编写程序,但是你不能知道C++实际上是好的(和坏的)什么。那有什么意义?AlanPerlis曾经说过:“一种不影响你对编程的思考方式的语言是不值得知道的”。一个可能的问题是,您必须学习一点C++(或者更可能的是,类似JavaScript或处理的东西),因为您需要与现有工具接口来完成特定的任务。但是你不是在学习如何编程,而是在学习如何完成这个任务。
在24小时内:不幸的是,这还不够,正如下一节所示。
十年内自学编程
研究人员(Bloom(1985)、Bryan&Harter(1899年)、Hayes(1989)、Simmon&Chase(1973))已经证明,在包括国际象棋、音乐创作、电报运算、绘画、钢琴演奏、游泳、网球以及神经心理学和拓扑学研究在内的任何广泛领域,都需要十年的时间才能发展出专门知识。关键在于深思熟虑的练习:不只是一次又一次地去做,而是用一项超出你目前能力范围的任务来挑战自己,尝试它,分析你在做的时候和之后的表现,并纠正任何错误。那就重复一遍。再重复一遍。似乎没有真正的捷径:即使是莫扎特,他在4岁时是一个音乐天才,花了13年才开始创作世界级的音乐。在另一种类型中,披头士乐队似乎以一连串的#1热门和1964年的埃德·沙利文秀出现在现场。但从1957年起,他们就一直在利物浦和汉堡打小俱乐部,虽然他们很早就有了很大的吸引力,但他们的第一个重大成功,佩珀斯中士,在1967年被释放了。
马尔科姆·格拉德威尔(Malcolm Gladwell)推广了这一理念,尽管他专注于1万小时,而不是10年。HenriCartier-Bresson(1908-2004)有另一个指标:“你的前10,000张照片是你最差的。”(他没有预料到,使用数码相机,一些人可以在一周内达到这一目标。)真正的专业知识可能需要一生的时间:塞缪尔·约翰逊(1709-1784)说:“任何部门的卓越都只能靠一生的劳动才能实现;不能以较低的价格购买。”乔叟(1340-1400)抱怨道:“莱夫太短了,手艺太长了。”Hippocrates(公元前400年)以摘录“Ars Longa,vita brevis”而闻名,这是较长的引语“Ars Longa,vita brevis,ocus o precep,实验性的周膜,艰难的分枝”的一部分,在英语中,它表现为“生命短,工艺长,机会短暂,实验变化无常,判断困难”。当然,没有一个数字是最终的答案:似乎不合理地假定所有技能(例如编程、下棋、跳棋和音乐演奏)都需要完全相同的时间来掌握,也不认为所有人都需要完全相同的时间。正如K·安德斯·爱立信(K.Anders Ericsson)教授所言,“在大多数领域,即便是最有才华的人,也需要多少时间才能达到最高水平。1万小时的时间让你感觉到,我们所说的每周10到20个小时,有些人会认为,那些天生最有天赋的人仍然需要达到最高水平。”
所以你想成为一名程序员
下面是我编程成功的秘诀:
对编程感兴趣,并做一些,因为它是有趣的。一定要保持足够的乐趣,这样你就会愿意投入你的10年/10,000小时。
节目。最好的学习方式是边做边学。更严格地说,“在某一领域,个人的最高业绩水平并不是随着经验的扩展而自动达到的,但即使是经验丰富的个人,也可以通过刻意改进而提高业绩水平。”(第366页)和“最有效的学习需要一个明确的任务,适当的难度水平,为特定的个人,信息反馈,并有机会重复和纠正错误。”(第20-21页)“实践中的认知:日常生活中的思想、数学和文化”是这一观点的有趣参考。
与其他程序员交谈;阅读其他程序。这比任何书籍或培训课程都更重要。
如果你愿意,在一所大学(或更多的研究生院)待四年。这会让你获得一些需要资格证书的工作,也会让你对这个领域有更深入的了解,但如果你不喜欢上学,你可以(用一些奉献精神)独自或在工作中获得类似的经验。无论如何,光靠书本学习是不够的。“计算机科学教育不能使任何人成为专业程序员,就像研究画笔和颜料可以使人成为专业画家一样”,“新黑客词典”的作者埃里克·雷蒙德说。我雇过的最好的程序员之一只有高中学位,他制作了很多很棒的软件,有自己的新闻组,并且有足够的股票期权来购买自己的夜总会。
与其他程序员一起完成项目。在某些项目中做最好的程序员;在其他项目上做最差的程序员。当你是最好的,你可以测试你的能力来领导一个项目,并用你的远见激励别人。当你是最坏的时候,你学会了主人做什么,你学会了他们不喜欢做什么(因为他们让你为他们做)。
工作项目后,其他程序员。理解别人写的程序。看看当原来的程序员不在的时候,需要什么才能理解和修复它。想一想如何设计你的程序,让那些在你之后维护它们的人更容易。
至少学习六种编程语言。包括一种强调类抽象的语言(比如Java或C++)、一种强调函数抽象(比如Lisp、ML或Haskell)、一种支持语法抽象(比如Lisp)、一种支持声明性规范(比如Prolog或C++模板)、一种强调并行性(比如Clojure或Go)。
记住,在“计算机科学”中有一个“计算机”。知道您的计算机执行指令、从内存中获取一个单词(是否有缓存丢失)、从磁盘中读取连续单词以及寻找磁盘上的新位置需要多长时间。(答案在这里)
参与语言标准化工作。它可能是ANSI C++委员会,也可能是决定您的本地编码风格将有2或4个空间缩进水平。不管是哪种方式,你都可以了解到其他人在一种语言中喜欢什么,他们有多深,也许还有一点是关于为什么他们会这样想的。
有良好的判断力,尽快摆脱语言标准化的努力。
考虑到所有这些,仅仅通过书本学习,你能走多远是值得怀疑的。在我的第一个孩子出生之前,我读了所有的书,仍然觉得自己是一个无知的新手。30个月后,当我的第二个孩子即将出生时,我是否又回到书本上复习了一下?没有。相反,我依靠的是我个人的经验,这比专家们写的几千页更有用,也更让我放心。
弗雷德·布鲁克斯(FredBrooks)在他的文章“没有银弹”中指出了一个寻找优秀软件设计师的三部分计划:
系统地尽早确定顶级设计师。
指派一位职业导师负责前景的发展,并仔细保存一份职业档案。
为不断成长的设计师提供互动和相互激励的机会。
这假设有些人已经具备了成为一名伟大设计师所必需的素质,其工作就是恰当地引导他们坚持下去。艾伦·佩利斯(AlanPerlis)更简洁地说:“每个人都可以学会雕刻:米开朗基罗(Michelangelo)必须学会如何不去做,伟大的程序员也是如此。”佩利斯说,伟大的球员有一些超越他们训练的内在素质。但是质量是从哪里来的呢?是天生的吗?或者他们是通过勤奋来发展的呢?正如奥古斯特·古斯托(Ratatouille中虚构的厨师)所言:“任何人都能做饭,但只有无畏的人才能做得很好。”我认为它更多的是愿意把一个人一生中的大部分时间花在深思熟虑的实践上。但也许无畏是总结这一点的一种方式。或者,正如古斯托的批评家安东·伊戈所说:“不是每个人都能成为伟大的艺术家,但伟大的艺术家可以来自任何地方。”
因此,继续购买Java/Ruby/Javascript/PHP书籍;您可能会从中得到一些使用。但你不会在24小时或21天内改变你的生活,也不会改变你作为程序员的真正专业知识。在过去的24个月里,努力工作,不断提高,怎么样?现在你开始有进展了..。
参考文献
布卢姆,本杰明(编辑)“发展青年人才”,巴兰汀,1985年。
布鲁克斯,弗雷德,没有银子弹,IEEE计算机第20卷,第4期,1987年,第10-19页。
Bryan,W.L.&Harter,N.“电报语言研究:习惯层次的习得”,“心理学评论”,1899年,8,345-375。
海斯,约翰R.,完全问题解决者劳伦斯厄尔鲍姆,1989年。
放大图片作者:William G.&Simon,Herbert A.“象棋中的知觉”,“认知心理学”,1973,4,55-81。
“实践中的认知:日常生活中的思想、数学和文化”,剑桥大学出版社,1988年。
答案
典型PC上各种操作的大致时间:
执行典型指令1/1,000,000,000秒=1纳塞克
从L1高速缓存存储器0.5纳塞克中提取
支路误判5纳秒
从L2高速缓存存储器7纳塞克中提取
互斥锁/解锁25纳塞克
从主存100纳塞克中提取
在1Gbps网络上发送2K字节20,000纳秒
从内存250,000纳塞克中顺序读取1MB
从新磁盘位置(查找)获取8,000,000纳塞克
从磁盘按顺序读取1MB 20,000,000纳塞克
将数据包US发送到欧洲,返回150毫秒=150,000,000纳塞克
附录:语言选择
有几个人问他们应该先学哪种编程语言。没有一个答案,但请考虑以下几点:
利用你的朋友。当被问到“我应该使用什么操作系统,Windows,Unix还是Mac?”时,我的回答通常是:“使用任何你的朋友使用的操作系统。”你从朋友那里学到的优势将抵消操作系统之间或编程语言之间的任何内在差异。还要考虑你未来的朋友:如果你继续的话,你会成为程序员社区的一部分。你所选择的语言是有一个庞大的成长社区,还是一个正在消亡的小群体?有没有书籍,网站和在线论坛可以得到答案?你喜欢那些论坛上的人吗?
保持简单。编程语言(如C++和Java)是为专业开发而设计的,由大量经验丰富的程序员组成,他们关心代码的运行时效率。因此,这些语言具有为这些情况设计的复杂部分。你关心的是学习编程。你不需要那种并发症。你想要一种语言,它被设计成一个简单易学的语言,并被一个新的程序员记住。
玩。你更愿意学习弹钢琴的哪一种方式:普通的,交互式的,在你一按下键就听到每个音符的方式,还是“分批”模式,只有在你唱完整首歌之后才能听到音符?显然,交互模式使钢琴和编程更容易学习。坚持一种互动的语言,并使用它。
考虑到这些标准,我对第一种编程语言的建议将是Python或Scheme。另一个选择是Javascript,并不是因为它为初学者设计得非常好,而是因为它有很多在线教程,比如Khan Academy的教程。但你的情况可能会有所不同,还有其他好的选择。如果你的年龄是个位数,你可能更喜欢爱丽丝、斯奎克或布洛克里(年长的学习者也会喜欢这些)。重要的是你选择并开始。
附录:书籍和其他资源
有几个人问他们应该从哪些书籍和网页中学习。我再说一遍,“光靠书本学习是不够的”,但我可以推荐以下几点:
方案:计算机程序的结构和解释(Abelson&Sussman)可能是计算机科学的最佳入门,它确实教授编程作为理解计算机科学的一种方式。你可以在这本书上看到讲座的在线视频,也可以在网上看到完整的文本。这本书具有挑战性,并将淘汰出一些可能通过另一种方法获得成功的人。
方案:如何设计程序(Felleisen等人)是关于如何以优雅和实用的方式实际设计程序的最好的书籍之一。
Python:PythonProgramming:IntrotoCS(Zelle)是使用Python的一个很好的介绍。
Python:几个在线教程可以在Python.org上找到。
奥兹:计算机编程的概念、技术和模型(VanRoy&Haridi)被一些人视为现代阿贝尔森和苏斯曼的继承者。它是一个关于编程的伟大思想的旅行,涵盖的范围比Abelson&Sussman更广泛,而且可能更容易阅读和跟踪。它使用的一种语言,Oz,并不广为人知,但作为学习其他语言的基础。
注记
T.Capey指出,亚马逊上的完整问题解决方案页面现在有“21天内教你自己孟加拉语”和“教你自己语法和风格”的书,在“为这个项目购物的顾客也在购买这些物品”部分下。我想看那本书的人中有很大一部分是从这一页来的。感谢罗斯·科恩帮助希波克拉底。