程序员成长之道

黄小非译注:本文作者Peter Norvig目前任职于Google,其职位是研究主管(Directorof  Research). Peter Norvig是享誉世界的计算机科学家和人工智能专家。他是 AAAI    ACM 的会员,是业界内经典书籍《ArtificialIntelligence: A Modern Approach | 人工智能:一种现代方法》的作者之一。在加入Google之前,他曾经是NASA(美国航空航天局)计算科学部门的主要负责人,并在南加州大学以及伯克利大学任教。以下为译文。

你们着什么急?

  随意步入一家书店,满目都是《7天搞定Java编程》这种速成书目,同样的书籍还包括Visual BasicWindow系统、Internet互联网等等,它们都承诺在几天,甚至几小时之内就让你能够学会相关技术。我在亚马逊网站上做了如下的条件检索:

pubdate: after1992 and title: days and

(title: learn ortitle: teach yourself)

出版日期:1992年以后,题目关键字:学会或者自学

  然后得到了248条搜索结果。头78条都是计算机类书籍(第79条记录是《30天学会孟加拉语》)。我将关键字换成了小时,不出意外地搜索到了253条记录,其中头77条记录是计算机书籍,第78条的搜索记录是《24小时语法和样式自学手册》。在总共搜索到的头200条记录中,有96%计算机书籍。

  从上面的搜索结果可以看出来,要么就是人们对计算机技术的学习如饥似渴,要么就是计算机技术实在太简单,不费吹灰之力就能学会。相比于计算机技术书籍的如此速成,在其他领域的书籍里,你却很难找到诸如:三天学会贝多芬,或者五天搞定量子力学,这种速成教材,甚至连《狗狗喂养手册》这种宠物指南,都鲜有几天搞定的说法。Felleisen et al.在他们的著作《如何设计程序》一书中明确指出了这种速成的趋势,并评论到:垃圾的编程技术当然非常容易,傻子都能在21天之内学会,哪怕他天生就是个白痴。

  让我们来仔细看看《3天学会C++》这种速成教材实际上意味着什么:

·        学会:3天时间里你几乎没有时间去写任何有意义的程序,就更不要谈什么从编程中获得经验和教训这种事情了。你也不可能有时间和有经验的程序员一起工作和交流,也不会体验到在真正的C++环境下工作是什么感觉。长话短说吧,你就是没时间,也学不到什么。所以这种书籍最多也就让你有个粗浅的印象,但是绝对不可能有深入的理解。就像亚历山大教皇说的那样,浅尝辄止是很危险的

·        C++: 如果你有其他编程语言的基础,那3 天之内你也许可以学到C++的一些语法,但即使是这样,你还是无法了解如何使用该语言编程。简言之,如果你之前是一个Basic程序员,那么经过3天的学习,你会成为一个能使用C++语法编写Basic风格程序的程序员,不过这样是没法发挥出C++语言本身的优势的(说句不好听的,你连怎么犯C++典型错误都不会)。仅仅知道一点语法意味着什么呢?Allan Perlis曾经说过:一个无法改变你思维方式的编程语言是不值得学习的。;另一种可能性是,你可以只学一点点C++知识(类似的,或者一点点 JavaScript,或者一点点Flex Script),然后就可以利用现有的工具制作应用接口,完成特定的编程任务了。但是这样的行为并不意味着你编程了,你只是会使用这个工具完成任务而已。

·        3天:很不幸,3天是远远不够的,往下看你就知道了。

peter norvig

  研究人员(Bloom (1985) Bryan & Harter (1899,见文后参考书目)Hayes (1989)Simmon & Chase (1973,见文后参考书目) 的一系列调查研究显示,在各个领域内,要想获得专业级别的水平,大约需要10年时间的努力。参与此项调查的领域包括:国际象棋,作曲,发报,绘画,钢琴演奏,游泳,网球等。科学家们从神经心理学和拓扑学的角度对这些领域进行研究,并得出结论。若要在某一领域内达到专家级的水平,其关键在于审慎地重复也就是说,并非是机械地,一遍又一遍地练习,而是要不断地挑战自我,试图超越自身当前的水平,通过不断的尝试挑战,并在尝试的过程中和尝试之后对自身的表现进行分析和总结,吸取经验,纠正之前犯过的各种错误。把这一审慎的过程不断重复,才能取得成功。

  所谓的捷径是不存在的,即使对于莫扎特这种天才来说,也没有捷径可走,尽管4岁就开始作曲,可是他也花了13年的时间,才真正地写出了世界级的作品。再举一个例子,甲壳虫乐队(The Beatles,他们似乎在1964年凭借一系列热门单曲和其在艾德沙利文秀(The Ed Sullivan show)上的演出一炮而红,但是你也许不知道,他们早在1957年就在利物浦和汉堡两地进行小规模演出了,而在此之前的非正式演出更是不计其数。甲壳虫乐队的主要成名曲《Sgt. Peppers》,则是1967年才发行的。Malcolm Gladwell公布了他对柏林音乐学院所作的一项研究的报告,该研究对比了一个班里的学习成绩为上、中下三个档次的学生,并逐一询问他们进行音乐练习的时间。

  这三个档次中的所有人,大约都是在5岁的时候开始练习音乐的,一开始的时候大家练习音乐的时间都差不多,大约一周23小时。但是到了八岁左右,大家的区别就开始体现了。后来成为班里最好的那一部分学生开始比别的学生练习得更多,大概每周69小时,12岁的时候每周8小时,14岁的时候每周16时,往后则越来越多,直到20岁左右,他们每周练习音乐的时间已经超过30小时了。在20岁的年纪,那些精英级别的演奏家们都有累计超过10000小时的音乐练习时间。相比之下,仅有部分优等生能达到8000小时的累计练习时间,而那些音乐教师级别的学生,他们的累计练习时间只有4000小时左右。

  所以,也许这个让你能达到专业等级的神奇时间应该是10000小时,而不是10年。(HenriCartier-Bresson (1908-2004)说过,(作为摄影师),你所拍摄的头10000张照片都是垃圾,但即使是垃圾作品,他拍一张照片也要花接近一小时。)Samuel Johnson(1709-1784)认为这个时间应该更长:在任何一个领域要想做到极好,势必穷尽一生的精力,否则根本无法企及。” Chaucer (1340-1400)也发出过生命如此短暂,技能如此高深的感叹。Hippocrates (c. 400BC)因写下了如下的句子而被人称颂:“ars longa, vitabrevis”,该句是来自于一个更长的引用:”Ars longa, vita brevis, occasio praeceps, experimentumpericulosum, iudicium difficile”, 这段话翻译成英语就是:生命很短暂,但是技艺却很高深,机遇转瞬即逝,探索难以捉摸,抉择困难重重。这段话是用拉丁文写的。在拉丁文里,ars可以翻译为技艺或者艺术,但是在古希腊文里,ars只能做技能的意思,而没有艺术的意思。

你想当程序员么?

  下面是我列举的程序员成功食谱

·        沉醉于编程,编程是为了兴趣。保持这种充满兴趣的感觉,以便于你能将其投入到你的10/10000小时的编程时间中。

·        程序. 最好的学习方式是在实践中学习。更技术一些地说:一个人在某个专业领域方面能够达到最高水平,并不是因为这个人经验增长了以后而自动获得的,而是这个人为了进步所做出了专门的努力之后产生的结果。(p. 366)最有效的学习包括如下几个要素:明确并且难度适当的任务,适应学习者个人情况,及时的信息反馈,有重新开始和改正错误的机会)(p. 20-21) Cognition inPractice: Mind, Mathematics, and Culture in Everyday Life》这本书提供了上述有趣的观点

·        同其他程序员交流,多阅读其他人写的程序。这些远比你看书或者上培训班重要

·        如果你愿意的话,就选择去读一个计算机科学专业吧(当然你还可以去念这个专业的研究生)。如果你能做到这点,那么你就有机会找到一些需要计算机学位认证的工作,也会让你对这个行业有更深的理解。不过,如果你不是上学的料,那么你可以(当然需要有足够的毅力)靠自己学习,或者通过工作来积累经验。无论你采用哪种途径,光依靠书本是远远不够的。如果说仅仅靠学习油画和调色技术无法创造出顶尖的画家的话,那么光学习计算机科学课程更不能造就顶尖的程序员。Eric Raymond这样说过,他著有《新黑客字典》一书。我所聘用过的最好的程序员仅仅只有高中文凭; 他写了很多伟大的软件,他有他自己的新闻组,并且通过股权赚够了钱,还开了家属于自己的夜店。(作者说的这个人是Jamie Zawinski,他是网景浏览器(Netscape)的早期开发这者之一,也是开源项目MozillaXEmacs的主要贡献者,他开了一家叫做DNA_lounge的夜店,位于旧金山的SoMa——译者注)

·        与其他程序员一起做项目。在某些项目中要尽量做到最好,在某些项目中却别做那么好。当你是最好的时候,你的领导能力就会得到锻炼,并激发你高瞻远瞩的视野。当你做得不好的时候,你就能知道你的领导怎么做事,以及他们不喜欢哪些事(因为领导总是把那些他们不爱做的杂事丢给他们认为不得力的人去做)

·        尝试跟随其他程序员一起做项目。尝试去理解其他人所写的代码。看看如果你无法找到代码的作者本人的情况下,理解和修正他写的代码需要花费什么样的代价。同时也思考,如何规划你自己的程序代码,让它们更容易被其他人理解和维护。

·        至少学习半打编程语言。包括一种支持类抽象的语言(例如Java或者 C++),一种支持函数抽象的语言(例如Lisp或者ML,一种支持语法抽象的语言(例如Lisp,一种支持声明式编程的语言(例如Prolog或者 C++模板),一种支持协同程序的语言(例如Icon或者Scheme,一种支持平行并发编程的语言(例如Sial

·        牢记计算机科学中包含着计算机这个词。了解计算机需要花多长的时间执行一条指令,花多长时间从内存中获取一个字(word)(包括缓存命中和不命中两种情况),如果连续从磁盘中获取数据,时间消耗如何?以及需要花多少时间才能再磁盘上定位一个新的位置?

·        尽量参与语言的标准化过程。往大了说,你可以试着加入ANSI C++委员会这样的专业组织,往小了讲,你也可以从自己的代码规范入手,限定代码缩进是需要2个空格宽还是4个空格宽。无论采用哪种方式,你都需要了解其他人对于语言的喜好,以及他们的喜好的程度,甚至你要知道他们为什么产生这样的喜好的原因。

·        有良好的意识,能尽快适应语言标准化的成果。

  要掌握上面所说的所有内容,光靠看书学习应该是很难做到的。当我的第一个孩子出生的时候,我几乎阅读了市面上所有的《如何》指南书籍,但是我读完了以后还是觉得自己是个菜鸟。30个月以后,我的第二个孩子快出生时,我难道还要做一个书虫么?不!相反,我此时更依赖我的个人经验,这些经验相比于那些上千页的书籍,则更加有效和让我放心。

Fred Brooks所著的著名的论文《No SilverBullets没有银弹》里向我们揭示了发现和培养软件设计人才的三步骤:

1.   有组织地辨认顶尖的软件设计人才,越早越好

2.   安排一个职业导师,为其职业前景指点迷津,并谨慎对待自己的职业履历

3.   为成长中的设计师们提供机会,让他们能够互相激发促进。

  即使一部分人已经具备了成为优秀软件设计人员的潜质,也需要经历工作的慢慢琢磨,方可展现才华。Alan Perlis说得更加直接:任何人都可以被成一个雕塑匠,但米开朗基罗则被如何不要成为一个雕塑匠,因为他要做的是雕塑大师,。这个道理放到编程大师身上同样管用。”Perlis认为,伟大的软件开发人员都有一种内在的特质,这种特质往往比他们所接受的训练更重要。但是这些特质是从哪里来的呢?是与生俱来的?还是通过后天勤奋而来?正如Auguste Gusteau(动画电影《料理鼠王》里的幻象大厨)所说,谁都能做饭,但只有那些无所畏惧的人才能成为大厨!我很情愿地说,将你生命中的大部分时间花在审慎地练习和提高上,这很重要!但是无所畏惧的精神,才是将促使这些练习成果凝聚成形的途径。或者,就像是《料理鼠王》里那个与Gusteau对的刻薄的美食评论家Anton Ego说的那样:不是任何人都能成为伟大的艺术家,不过,伟大的艺术家在成名前可能是任何人。

  所以尽管去书店大买Java/Ruby/Javascript/PHP书籍吧;你也许会发现他们真的挺管用。但是这样做不会改变你的人生,也不会让你在整体经验上有什么提高。24小时,几天,几周,做一个真正的程序员?光靠读书可读不出来。你尝试过连续24个月不懈努力提高自己么?呵呵,如果你做到了,好吧,那么你开始上路了……

 

下载方式:https://pan.quark.cn/s/a4b39357ea24 布线问题(分支限界算法)是计算机科学和电子工程领域中一个广为人知的议题,它主要探讨如何在印刷电路板上定位两个节点间最短的连接路径。 在这一议题中,电路板被构建为一个包含 n×m 个方格的矩阵,每个方格能够被界定为可通行或不可通行,其核心任务是定位从初始点到最终点的最短路径。 分支限界算法是处理布线问题的一种常用策略。 该算法与回溯法有相似之处,但存在差异,分支限界法仅需获取满足约束条件的一个最优路径,并按照广度优先或最小成本优先的原则来探索解空间树。 树 T 被构建为子集树或排列树,在探索过程中,每个节点仅被赋予一次成为扩展节点的机会,且会一次性生成其全部子节点。 针对布线问题的解决,队列式分支限界法可以被采用。 从起始位置 a 出发,将其设定为首个扩展节点,并将与该扩展节点相邻且可通行的方格加入至活跃节点队列中,将这些方格标记为 1,即从起始方格 a 到这些方格的距离为 1。 随后,从活跃节点队列中提取队首节点作为下一个扩展节点,并将与当前扩展节点相邻且未标记的方格标记为 2,随后将这些方格存入活跃节点队列。 这一过程将持续进行,直至算法探测到目标方格 b 或活跃节点队列为空。 在实现上述算法时,必须定义一个类 Position 来表征电路板上方格的位置,其成员 row 和 col 分别指示方格所在的行和列。 在方格位置上,布线能够沿右、下、左、上四个方向展开。 这四个方向的移动分别被记为 0、1、2、3。 下述表格中,offset[i].row 和 offset[i].col(i=0,1,2,3)分别提供了沿这四个方向前进 1 步相对于当前方格的相对位移。 在 Java 编程语言中,可以使用二维数组...
源码来自:https://pan.quark.cn/s/a4b39357ea24 在VC++开发过程中,对话框(CDialog)作为典型的用户界面组件,承担着与用户进行信息交互的重要角色。 在VS2008SP1的开发环境中,常常需要满足为对话框配置个性化背景图片的需求,以此来优化用户的操作体验。 本案例将系统性地阐述在CDialog框架下如何达成这一功能。 首先,需要在资源设计工具中构建一个新的对话框资源。 具体操作是在Visual Studio平台中,进入资源视图(Resource View)界面,定位到对话框(Dialog)分支,通过右键选择“插入对话框”(Insert Dialog)选项。 完成对话框内控件的布局设计后,对对话框资源进行保存。 随后,将着手进行背景图片的载入工作。 通常有两种主要的技术路径:1. **运用位图控件(CStatic)**:在对话框界面中嵌入一个CStatic控件,并将其属性设置为BST_OWNERDRAW,从而具备自主控制绘制过程的权限。 在对话框的类定义中,需要重写OnPaint()函数,负责调用图片资源并借助CDC对象将其渲染到对话框表面。 此外,必须合理处理WM_CTLCOLORSTATIC消息,确保背景图片的展示不会受到其他界面元素的干扰。 ```cppvoid CMyDialog::OnPaint(){ CPaintDC dc(this); // 生成设备上下文对象 CBitmap bitmap; bitmap.LoadBitmap(IDC_BITMAP_BACKGROUND); // 获取背景图片资源 CDC memDC; memDC.CreateCompatibleDC(&dc); CBitmap* pOldBitmap = m...
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值