查尔斯.西蒙尼:
在某些情况下,如果你倒着做事情,之前显得很复杂的问题突然之间会变得非常简单。例如,解析前向引用(forward reference)可能很难。要是倒着扫描,它们就变成了后向引用(backward reference),很容易解析。只要从新的角度看待程序,原本可能很难解决的问题也会变得容易解决。
什么是编程?人们对此一直各持己见。有人说它是科学,有人说它是艺术,还有人称之为技能或手艺。我认为这三方面兼而有之。我们喜欢说它蕴含大量艺术成分,但是我们都知道它里面更多的是科学。
孩子们在学校里学习数学,高中毕业时,他们会以为数学就是加法和乘法,甚或代数和微积分。其实,算术,即使简单如加法的运算,背后也有令人难以置信的科学理论作支持。
计算机编程背后也有大量科学理论作支持。例如,哥德尔定理的数学证明冗长而复杂,但是如果借用计算机科学的图灵定理,证明起来不费吹灰之力。信息理论和计算机科学其他领域对数学影响巨大,反之亦然。
编程包含有大量科学,同时,它也有点像手艺。实际上,在许多人看来,编程是一项复杂的技能,这跟工具制造很像,需要精雕细琢。我认为,只要将科学、艺术和技能这三者拿捏得恰到好处,你就能取得一些引人瞩目的成绩。
在我看来,编程显然有审美的一面,对用户界面而言,不仅设计中存在,甚至连外观也不例外。当你看到那些丑陋的屏幕时,程序员在艺术上的不足便一览无遗。在其他方面,计算机编程也堪称艺术,正如高能物理也可视作艺术一样。
审美也直接影响到其他程序员分析该程序并探究其编写方式,毋庸置疑。我觉得代码清单和计算机自身的美感一直让我陶醉其中。
“匈牙利命名法”:
命名规范其实是要让代码更易读。这套规范能够很好地控制程序中所有变量的命名。
要是分解一个程序,把它放进磨床,然后对碎片进行分类,你就会发现程序的大部分都是名字。写下“apples + oranges”,你会发现名字“apples”有6个字符,运算符“+”只有1个字符,名字“oranges”有7个字符,一共14个字符,只有一个字符即加号与运算有关。因此,对我来说,要起到作用或有所改进,合乎逻辑的做法就是尽力完善程序的主要部分,也就是名字。“匈牙利命名法”是一种根据变量的属性自动为其创建名字的命名方法。这跟人们把当裁缝(tailor)的叫做泰勒(Taylor)以及把当铁匠(blacksmith)的叫做史密斯(Smith)非常相似。
因此,面对一个具备某些属性的结构,不要随随便便地取个名字,然后让所有人去琢磨名字和属性之间有什么关联,你应该把属性本身用作结构的名字。这种方法有很多优点。首先,造个名字很容易,想到那些属性时,把它们写下来,名字自然就有了。第二,它很容易理解,因为当你读到某个变量时,从名字本身就能了解到与属性有关的大量信息。这些属性会越来越多,因此很难简明地描述它们。为此“匈牙利命名法”引入了一种缩写符号,以很小的空间就能展现具体属性。当然,这在不知情的人看来完全是一团乱麻,那个玩笑就是这么来的。
有些人认为,如果他们可以读出代码里的每个字,那么程序就是可读的。实际上,这种意义上的可读性并不可取。没有人会拿着代码清单,站到演讲台上大声朗读程序。关键在于理解。只是能阅读单词并发出音来,这毫无用处。当人们看到采用“匈牙利命名法”的代码清单时,他们发现这些词很难念,可能就会认为代码不是可读的。但实际上,由于名字和属性之间存在关联,它更容易理解,也更便于沟通。那些使用匈牙利命名法编程的人,即使在离开我的部门之后,仍会继续使用它。这种命名法已经打入苹果电脑、3Com及其他许多公司。
创建程序的整个过程(适用于所有程序的过程)
对编程而言,我认为我们应该知道自己想要做什么。如果不知道,那么有一个过程确实是解决各种问题的必经之路,那就是要弄清楚:我试图做什么?目标是什么?
打个比方,我想开发一个菜单驱动的文本编辑器,要求响应速度快,并且提供拼写检查器等。在开始真正编程之前,我需要先弄清楚最终产品。有时候,目标的选择取决于我都掌握了哪些技巧。以Bravo为例,这个程序是以算法为导引的。巴特勒·兰普森描述了两个很有意思的算法,于是我们试图围绕这些算法来编写这个编辑器,以充分利用这些算法。此外,J. 斯特罗彻·摩尔(J. Strother Moore),就是Boyer-Moore字符串查找算法的Moore,在文档编辑方面有几个很有意思的算法。于是我们决定:“嘿,这个编辑器要包含摩尔编辑算法、兰普森的屏幕更新算法还有两个缓存。”等到对目标有充分的把握之后,我才会开始真正的编程。我调整姿态,关上房门,并且大声宣布:“现在我要开始编程了。”
第一步:
编程的第一步是想象。就是要在脑海中对来龙去脉有极为清晰的把握。在这个初始阶段,我会使用纸和铅笔。我只是信手涂鸦,并不写代码。我也许会画些方框或箭头,但基本上只是涂鸦,因为真正的想法在我脑海里。我喜欢想象那些有待维护的结构,那些结构代表着我想编码的真实世界。
一旦这个结构考虑得相当严谨和明确,我便开始写代码。我会坐到终端前,或者换在以前的话,就会拿张白纸,开始写代码。这相当容易。我只要把头脑中的想法变换成代码写下来,我知道结果应该是什么样的。大部分代码会水到渠成,不过我维护的那些数据结构才是关键。我会先想好数据结构,并在整个编码过程中将它们牢记于心。
*******这是最重要的一步
最优算法的知识当属科学,结构的想象则是艺术。这些算法的细节,以及编写高效代码实现这些结构的转换,是编程像手艺活的一面。从技术上讲,这就是所谓维护结构的不变性。编写代码以维护不变性是相对简单的技艺,不过这需要非常用心并辅之以大量训练才能练就。
如何管理手下的程序员?
管理的最佳方法是言传身教,经常复审代码。我们一直坚持开展代码复审。
让多名程序员开发一个程序,开发速度不一定会更快:
编写同一个程序的人员越多,人均产出的实际代码量越少。结果,总的代码产出一开始会更多,之后实际上可能会减少。以两个人为例,也许单位时间只能多写百分之五十的代码。
顺便提一下,代码的效率还会随着开发同一个程序的人员数量的增加而有所降低。最高效的程序往往是一个人写的。唯一的问题是,它可能需要写上一辈子,而这显然是无法接受的。因此你需要找上三五十个,甚或好几百个人开发一个项目。
预估编写一个程序要用多长时间:
预估编写程序要花的时间难度很大。之所以难度很大,原因多种多样。这并不意味着我们就不用尽全力预估,因为预估时间可能用处很大,就像天气预报不仅有经济效益还有其他好处一样。
挑选合适的人并培养成优秀程序员,有不少套路可循。我们招揽有天分的员工。我不清楚他们何以有如此才华,我也不用去弄清楚。但是他们确实很有才。在此基础之上,环境可以起到很大作用。
进入公司第一天,程序员就会拿到几本书。其中一本是数学家乔治·波利亚写的《怎样解题》。(西蒙尼边说边从他办公桌旁的书柜里取出那本书,翻到某一页。)这两页很重要。这本书的其余内容就是基于这两页展开的。这就像一张问题求解的检查单。这是起飞前、起飞和着陆检查单。它不会教你如何飞行,但是如果不照做,即使你已经懂得怎么飞行,也有可能会坠机身亡。
求解问题时,我们遵循以下四个步骤:首先理解问题,然后拟定计划,接着执行计划,最后回顾整个过程。这样的书我们大概有四本,我觉得我们能使程序员比刚加入公司时变得更加优秀。
原文地址:https://www.cnblogs.com/lidongming/p/9698492.html