编程大师访谈录01----查尔斯.西蒙尼

查尔斯.西蒙尼:

在某些情况下,如果你倒着做事情,之前显得很复杂的问题突然之间会变得非常简单。例如,解析前向引用(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

时间: 2024-11-18 01:07:42

编程大师访谈录01----查尔斯.西蒙尼的相关文章

[小北De编程手记] : Lesson 01 - Selenium For C# 之 环境搭建

在我看来一个自动化测试平台的构建,是一种很好的了解开发语言,单元测试框架,自动化测试驱动,设计模式等等等的途径.因此,在下选择了自动化测试的这个话题来和大家分享一下本人关于软件开发和自动化测试的认识.刚刚开通了博客,就从最基础的开始吧,算是写给初学者的编程手记,也算是给对自动化完全不了解的小伙伴开个头.时间允许的话会坚持更新下去... ... 后续的文章计划会谈到一些企业级自动化测试平台的构建(但愿有时间完成哈~~). 关于自动化测试的框架,网上有很多相关的对比,在这里我我就不评论和对比了.本人

[小北De编程手记] Lesson 01 - AutoFramework构建 之 从一个简单的Demo聊起

写在最前面 这个系列的主旨是要跟大家分享一下关于自动化测试框架的构建的一些心得.这几年,做了一些自动化测试框架以及团队的构建的工作.过程中遇到了很多这样的同学,他们在学习了某一门语言和一些自动化测试的类库或者工具之后,打算进一步的提高.我想这个系列也许会帮助到你,我们一起从各个维度来看一看自动化测试框架的一些最佳实践.本人能力有限,如果有什么不正确的的地方还各位大牛指正. 聊聊自动化测试的初心 在开始具体的技术和理论之前,我们先来思考一下自动化测试的目的是什么?我简单的罗列了几点: 替代手工测试

2018 校招在线编程 20题-01

1. 最大乘积(拼多多) 输入 3 4 1 2 输出 24 解题思路: 定义五个数,一个最大,一个次大,一个第三大,一个最小,一个次小.只要找到这五个数,问题就解决了.因为最大乘积只可能是最大*(次大*第三大) 或者是 最大*(最小*次小).时间复杂度O(n),空间复杂度O(1).PS:这道题输入有问题,题目给的样例是直接给了一组数,而此时用例先给了一个数的个数n,然后再给了一组数. 1 #include<bits/stdc++.h> 2 using namespace std; 3 4 in

Scala编程问题集(01)

By 高焕堂 洞庭国际智能硬件检测基地 Q-01: 如何使用Scala的Singleton机制来表达Class-level的数据. Answer: 在面向对象编程(OOP,Object-Oriented Programming)概念里,属性(Attribute)和函数(Function)都分为两个不同级别(Level).例如,厦门的科技谷(厦门)公司的大数据平台上,定义了数百个航空公司的类(Class),包括:东方航空公司(ChinaEasternAirlines).南方航空公司(ChinaEa

《一站式学习C编程》笔记01

1.程序的基本概念 程序由一系列指令组成,通常包括以下几类:输入,输出,基本运算,测试和分支,循环. 高级语言用语句编写程序,语句是计算机指令的抽象表示. 高级语言编程的优点:用C语言编程更容易,写出来的代码更紧凑,可读性更强,出错也容易改正,并且具有平台无关性(一种平台,就是一种体系结构,就是一种指令集,就是一种机器语言) 编译执行的过程:source code → compiler → exe cutable → loader → result 解释执行的过程:source code → i

[编程题] 交错01串 网易2018

如果一个01串任意两个相邻位置的字符都是不一样的,我们就叫这个01串为交错01串.例如: "1","10101","0101010"都是交错01串.小易现在有一个01串s,小易想找出一个最长的连续子串,并且这个子串是一个交错01串.小易需要你帮帮忙求出最长的这样的子串的长度是多少. 输入描述: 输入包括字符串s,s的长度length(1 ≤ length ≤ 50),字符串中只包含'0'和'1' 输出描述: 输出一个整数,表示最长的满足要求的子串

并发编程大师系列之:Synchronized的类锁和对象锁

说到并发编程,感觉跟大多数人一样,谈之色变,说它简单把,其实很有内容,说难吧,用起来也挺容易,最近我硬着头皮,决心要把并发编程好好的搞一遍.以前,面试的时候,面试官问,并发编程会吗?嗯,接触过,就加一个synchronized关键字就好了,面试官微笑着说,嗯好.特喵的现在感觉来说,这俩low逼.本来写了几行的软文,但感觉在技术文章里面体现,有失风度,明明可以靠文采吃饭,而我却非要靠技术,任性!上代码! 1.对象锁概念: java的所有对象都含有1个互斥锁,这个锁由JVM自动获取和释放.线程进入s

精通 VC++ 实效编程280例 - 01 窗口[转]

窗口是屏幕上的一个矩形区域.窗口分为3种:重叠窗口.弹出窗口和子窗口.每个窗口都有由系统绘制的“非客户区”和应用程序绘制的“客户区”.在 MFC 中,CWnd 类为各种窗口提供了基类. 1 通过 HWND 获得 CWnd 指针 通过 HWND 获得 Cwnd 指针可以调用 Cwnd::FromHandle 函数. 1 2 3 4 5 6 7 8 void CDemoDlg::OnButton1() {     HWND hWnd = GetSafeHwnd();  //获得当前窗口的句柄    

spark SQL编程动手实战-01

首先创建SparkContext上下文: 接着引入隐身转换,用于把RDD转成SchemaRDD: 接下来定义一个case class 来用于描述和存储SQL表中的每一行数据: 接下来要加载数据,这里的测试数据是user.txt文件: 我们创建好use.txt增加内容并上传到hdfs中: web控制台查询: hdfs命令查询: 加载数据: 验证数据是否加载成功: 注册成为user的table: 此刻user还是一个MappedRDD: 执行age 大于13 小于19的SQL查询: 此刻的teena