1.编程本质论     选择自 leezy_2000 的 Blog  
关键字   编程 本质 
出处    
 
 编程本质论by leezy_2000 这几年各种新的技术井喷一样的涌现出来。身处这样一个时代的我们,难免就有一种拔剑四顾,心下茫然的感觉。在某一方面的做到精专已属不易,全才似不可能,那么究竟又该何去何从?这篇文章目的是探讨编程过程中一些本质的东西,已期对大家的学习有所帮助。 个人以为,从编程这一职业诞生开始一直至今,其本质就没有改变过。对概念的抽象对逻辑的描述始终都是编程过程中最核心的东西。 程序为解决某一问题而存在。而问题可拆分成某些概念和逻辑关系。而结构化程序设计和面向对象程序设计不过是对概念和逻辑进行表达的不同方式。而程序中逻辑关系的复杂程度随程序的规模而增加。 程序的本质不是各种技巧。就算你把Effective C++,More Effective C++中的每一条款都应用到了你的C++程序中,如果没有对逻辑关系的良好组织,你的程序也可能糟不可言。可能高耦合低内聚,可能不可扩充―――。 上面这段文字提到了四个概念,他们分别是:问题、概念、逻辑和技巧。 我来举个例子来说明这四个概念都代表些什么。 现在假设我们需要根据已知的一个文件名产生一个临时文件名。如果输入为prog.dat,mydir,hello.,oops.tmp,end.dat那么相应的输出为prog.dat=>prog.tmpmydir=> mydir.tmphello.=>hello.tmpoops.tmp=>oops.xxxend.dat=>end.tmp(这里使用了The C++ Standard Library中第11章的例子) 什么都不做的程序是不存在的,程序总要解决客观世界中的某些问题。这里的问题就是要为一个已知的文件名产生相应的临时文件名。 解决这个问题时涉及的概念主要有两个:字符串和扩展名。扩展名可以用字符串进行表示。 解决这个问题的逻辑之一可用下面的伪代码来表述: if(输入文件名没有扩展名){    用输入文件名、'.'号和"tmp"生成临时文件名;}else {    得到输入文件名的扩展名;        if(扩展名为空)    {        用输入文件名和"tmp"生成临时文件名;    }    else if(扩展名为"tmp")    {        把"tmp"替换为"xxx";    }    else    {        把文件名'.'以后的部分替换为"tmp";    }}当然你还可以有其他的实现逻辑,而这种逻辑总是可以独立于语言、操作系统的。 至于你是用C++标准库、还是MFC的Cstring类或者.net中的相应类或者不依靠类库自己用某种语言来表述这种逻辑那就是技巧。 上面虽然是个小例子,但我认为完成任何程序:从上层应用直到底层驱动,都会涉及到这四个概念,。 上面所说编程时必须的四个要素中,我个人认为逻辑和概念是编程中更本质的东西,直接的原因是他们在更大的程度上决定着程序的质量。不要忘了评价软件质量的几个指标:健壮性、可重用性、易扩充性、容错性等。 而这些指标并不是你选择了某个语言或者某个框架他们就达到了。而要通过对解决的问题的逻辑进行提炼和精化才可能达到。不要说这是系统分析的责任,程序每一部分都有自己要解决的问题,怎么可能每一部分程序质量的保证都是系统分析的责任。 此外当你要把原来用软件实现的功能换做用硬件来实现的时候,这点就分外的明显--软件其实就是一组逻辑关系。 但眼下主流意识形态似乎并不认同这点,各种招聘广告可为明证。下面是一个招聘软件工程师的广告:1. BS degree or above in computer science. 
2. At least 2 years of driver development experience. 
3. Experience in C, C++, windows SDK/DDK or Linux system development. 
4. Familiar with computer networking or telecommunication 802.3, 802.11, TCP/IP protocol is a plus. 
5. Familiar with embedded system design. 
6. Familiar with Bluetooth is a plus. 如果把编程与磨刀砍柴做类比的化,那么当某个人熟悉某种语言、某个框架、某个IDE、某个协议某个开发包的时候我们可以认为这个人拥有一把较锋利的柴刀。但这和这个人最终擅不擅长砍柴并没有必然的关系。夫欲善其事,必先利其器。但利其器了未必就会善其事。所以说上面的广告一定程度上相当于想找一个会砍柴的人,但看人的时候却更注重他有没有一把锋利的刀子。(更可悲的是挣扎在生存边缘的我们,纵然不愿却也不得不迎合这种要求) 未避免矫枉过正,这里要强调一点,不是说基本技能不重要,没有对语言、框架、IDE的一定认识,根本就产生不了有用的程序。但当我们执迷于对不同语言、框架、IDE的优缺点进行比较的时候,不要忘了他们并不对程序的健壮性、可重用性、易扩充性、容错性等最终衡量程序优劣的诸多方面起决定作用。起决定作用的是你对概念的定义方式和对各种复杂逻辑关系的描述方式。 语言是什么?语言是逻辑的载体和描述的工具。当你试图表述逻辑关系的时候大多语言应该是满足这一要求的,要不然他早被淘汰了。框架是什么?框架是对逻辑和概念的一种封装。框架把某一领域通用的概念和逻辑封装起来,进而使程序员不必做一些重复性的工作。而实际上对这个领域的这些通用概念并不只有这么一种表述方式,也就是说并不只有一种逻辑表述。你选择某个框架的同时也就意味这你从n种方式中选择了一种,舍弃了其他。没有那个框架是完美的,选择的同时自然也就继承了这种不完美。所以善用他们,他们很重要,但不会再重要了。 当我意识到这点时,我发现虽然编程许久,但在对逻辑表述方面的能力却没有寸进,因为把90%以上的时间都投在了技巧的提升上了。Jeffrey Richter和Matt Pietrek两位堪称Windows编程界中的技巧大师。可我现在敢说即使你把《Windows核心编程》、《Programming Server-Side Application for Micorsoft Windows 2000》还有MSDN杂志的Under the Hood专栏倒背如流,你可能还是写不出高质量的程序。这些东西是必须的,但远不是全部。 林锐写过一本《高质量C++/C编程指南》,此书在网上流传甚广,我想原因有二:一是此书对C/C++语言中的容易造成模糊的地方进行了详细说明(真的很有用);二是林锐笔法不错。但也正因其流传甚广,我觉得在这里必须指出,此书严重的文不对题。按照书中所说那些就能设计出高质量的C/C++程序么?那些都是编程所需要的技巧,不过是告诉你怎么能磨出一把锋利的刀而已。如果读过此书的人都把这些技巧和高质量的程序相等价,那么学习时恐怕就难免会误入歧途了。 这个题目太大,我是姑妄言之。这里不过是刚刚开始一种探讨而远非结论。欢迎大家一起讨论,还望诸君有以教我!

解决方案 »

  1.   

    2.也谈编程本质     选择自 johnnyxia 的 Blog  
    关键字   Programming, C++,编程 
    出处    
     
     也谈编程本质
    by johnnyxia最近在网上看到leezy_2000的一篇文章,《编程本质》,读了之后颇有感触。有些观点,我非常赞同,但是,有些我却有不同的看法。觉得在文章之后的讨论区不能一吐为快,另外,也早有许多相关的想法想表达,所以就干脆打开Word,敲下了这篇文章。希望能和leezy_2000,以及其他的程序员朋友一同分享。 leezy_2000把程序设计归结为四大要素:问题、概念、逻辑和技巧,并且举了一个例子加以说明。问题是程序的目的,概念是在解决问题时用到的抽象事物(或者说是术语),逻辑是描述如何解决问题的,技巧等同于实现,使用何种计算机语言或框架等。这四大要素其实是程序设计的四个步骤,分析、抽象、概要设计、实现。从程序开发的过程上来说,的确如此。 但是,作者把程序的本质归结为概念和逻辑,我并不赞同。我倒是有些赞同cppTrier的观点,“编程的本质是问题模型到编程语言的映射”。但是这样描述的话,程序员变成了翻译员,抹杀了程序员的创造性。所以我觉得编程的本质更应该是以编程语言的思想描述、解决现实问题。Thinking in Programming Language。 关于语言和框架,leezy_2000的描述非常的经典。“语言是逻辑的载体和描述工具,框架是对逻辑和概念的一种封装”。使用不同的语言解决相同的问题,他们的逻辑是不同的。一个极端的例子是Prolog语言,这是我见到过的最奇怪的一种语言,但是用它来解决一些离散数学的问题却很方便。如果同样的问题让一个Prolog程序员和一个C++程序员来解决,他们的逻辑显然是不同的。大师说“语言磨砺了我们的思维方式,也决定了我们的思考范围”,就是这个道理(感谢weihere的引用,有时间我要去读读《The C++ Programming Language》)。每一种语言都有它内在的一种描述问题的思想和方法。 作为一个程序员,对于所使用的语言应该有一个全面、深刻的认识,掌握它的思想,学会用它来思考和解决问题。这也是Bruce Eckel在他的系列书籍Thinking in  Java,Thinking in C++所提倡的。 那么如何掌握语言的思想呢?看看Bruce的书就行了吗?那样只能学到一些皮毛。你必须实践,写上几千,几万行代码。只有在水里才能学会游泳。一本好书只能帮助我们缩短学习的过程,它不能代替实践。我不能想象一个人如果从来没有写过面向对象的程序,他是如何理解UML之类的东西的;更不能想象一个初学C++或是Java的程序员是如何通过读读《Design Pattern》就能掌握设计模式的。 计算机是一门实践的学科。当我们在讨论编程的本质时候,决不能忘记实践是重要的。本质固然重要,如果少了实践,就会变得形而上学。即使是微软的高级副总裁,Rick Rashid,仍然每年坚持编写大约50 000行代码。他认为,用最新的技术编程可以使他保持对计算机最前沿的技术的敏感。(摘自李开复《给中国学生的一封信》)。而在我的周围,一些只带几个程序员的小官,就以编程为耻,他认为象他这样的官(也叫项目经理)写程序,太丢份。真让人汗颜! 我们是程序工人(Coder)还是软件设计师(Designer)?在回答这个问题之前,我们首先要明白,什么是设计?设计是工程上的概念,设计的结果是一组文档,制造团队可以依据这份文档,准确的构建出产品。源代码是满足这一要求的惟一的软件设计文档。和一般工程不同的是,根据源代码构建产品的成本非常低廉,它无须什么工人,计算机可以代劳。现在流行的看法,似乎只有画UML图才是设计,而使用设计模式编码的设计倒不算设计。这其实是本末倒置了,UML图只能算是辅助设计文档,真正的设计文档是源代码。因此,我们都是软件设计师,我们是在设计软件,而不是构建软件。(这一观点出自于Jack Reeves的《源代码就是设计》,《敏捷软件开发-原则、模式与实践》附录D) 设计软件不是凭空的,你总是要以某一种编程语言来设计。和语言无关的设计,只能算是概要设计,只能做到一定的程度。要做详细设计必须和某一种语言相关。 以上只是我的一家之言,希望能给其他的初学程序设计的程序员一些帮助。
      

  2.   

    3. BY 猛禽  大大。偶转载没经过同意 可以吧 ^_^效颦篇:编程本质论--------------------------------------------------------------------------------
    原创作者:raptor
    转载需经作者同意
    最后修改时间:2004-12-30 先有leezy_2000兄的大作《编程本质论》,接着是johnnyxia兄的《也谈编程本质》,在CSDN上引发了一场关于编程本质问题的热烈讨论。当时我也在QQ上和FrameSniper兄就这个问题聊了几句,当时就想写这么一篇效颦文章来凑个热闹,只是因为没想到那篇BCBX的文章写了这么久,加上过了个年,于是耽搁了,现在过了两三个月了,再来旧话重提,恐有马后炮的嫌疑。
    “效颦”的典故出自《庄子·天运》,曰:故西施病心而颦其里,其里之丑人见之而美之,归亦捧心而颦其里。其里之富人见之,坚闭门而不出;贫人见之,挈妻子而去之走。彼知颦美而不知颦之所以美。
    正如我对FS兄所说的观点:虽然我们在软件业摸爬滚打了这么些年头,但软件的本质对于我们来说,与盲人面前的大象没有区别。每个人看到的都是其中很小的一个方面,所有说出来的看法都是片面的,我也不例外。然而每个人将自已从不同角度得到的看法说出来,也许就能让我们对软件的本质有更全面的了解。这就是我为什么明知是在 “效颦”而仍要为之的原因之一(另一个原因当然是因为我也是“不知颦之所以美”)。
     
    在研究“编程本质”前,当然首先要研究一下什么是“本质”,金山词霸对“本质”一词的解释有三个:
    1、  事物中常在的不变的形体
    2、  事物的根本性质
    3、  哲学名词。某类事物区别于其它事物的基本特质
    首先,软件应该说是没有什么具体的形体的,至于哲学,太高深了,非我辈所能妄言,所以我想研究的是:什么是“编程的根本性质”?
    然后再来看看“编程”是一个什么概念?顾名思义,所谓“编程”就是编写程序,就是Coding,然而这只是一个狭义的概念。按照program一词的正式解释是:设计、编写、测试程序。也就是Development,即“开发”。
    现在可以明确所谓“编程本质”就是“软件开发的根本性质”。
     
    leezy_2000兄认为编程有四大要素:问题、概念、逻辑和技巧,并且认为其本质为:概念和逻辑。
    而johnnyxia兄则认为编程的本质是Thinking in Programming Language。
    此外在两篇文章的评论中还有很多其它的观点,有些还非常的独特,比如itpunk兄的:“编程的本质就是出卖劳动力换取一日三餐。”(窃以为“出卖劳动力”不太准确,所有的工作都是如此,不独编程,换成“出卖代码”会更好些),这里不一一列举(BTW:我认为看CSDN上的文章,最好把所有评论看完,因为这对文章最好的补充)。
    我的观点是,他们说的都是正确的,但这不能算是“软件开发的根本性质”。
     
    先来看leezy_2000兄的观点:首先这种划分四大要素的分法就非常的主观,因为每个人从不同的角度来看,都可能有不同的分法。比如三个要素:问题,解题思路(借用toomore兄的说法)及实现----个人更倾向于这种看法。或者还有人能分出五个要素来。既然它不是不变的,又谈何“根本性质”?
    另外,所谓“要素”即“必要的元素”,意味着它们中的任何一项都是不可或缺的,如果硬要说其中包含着所谓的“本质”,那么所有的部分都是同等重要的,这个“本质”必须包含所有的要素,何故厚此薄彼?
    leezy_2000兄强调概念和逻辑是基于软件的质量属性:健壮性、可重用性、易扩充性、容错性(其实这就是健壮性)而言的。而事实上软件的质量属性远不止这几个,按《软件需求》第11章中的说法可以分成两类:对用户最重要的属性和对开发者最重要的属性。而这两类分别包括:有效性,高效性,灵活性,完整性,互操作性,可靠性,健壮性,可用性(以上为用户方面),可维护性,可移植性,可重用性,可测试性(以上为开发者方面)。而且就这些属性来说,很多也是互相制约的,只能是根据实际情况取舍,并非如leezy_2000兄所言的,只要对“逻辑进行提炼和精化”就能达到。
    至于软件可以用硬件替代,不过是证明软件中包含逻辑,并不能证明逻辑就是软件的本质,而且还恰恰证否了这一点:套用前面的哲学说法来说,它们就不能算是软件“区别于其它事务的基本特质”了。
    不可否认现在重视工具与技巧有些过度,沉迷于技术细节固然不是一种好的做法,在这一点上,我很支持leezy_2000兄对林锐的书的看法,正如《老子·五十七章》所说:“人多技巧,奇物滋起”。但我还是支持cppTrier兄的观点:不可矫枉过正(虽然leezy_2000兄在文中提到这不是他的目的,但事实上他的文章却得到这样的效果),相当部分的初学者其实都很盲目,很容易从一个极端走向另一个极端。技巧仍然是一个必不可少的要素。而且从某种角度上说,即使是像模式之类的也是一种技巧。
    johnnyxia兄和cppTrier兄的观点比较一致,也很有道理,而且从狭义上说,Thinking in Programming Language就是Coding的本质(考虑到概念的完整性,这个Programming Language其实还应该包括Platform,在具体开发时,即使同样是用C++语言,面对Windows和Linux下不同的API,这个Thinking多少也是有些不同的),所有Coding的过程都有这个“根本性质”,因为Coding一定是在一个确定的平台下用一种确定的开发语言来进行,“语言磨砺了我们思维的方式,也决定了我们思考的范围。”大师就是大师。
    然而对于“软件开发”来说,这个“本质”还是不够根本。拿现在异军突起的MDA来说,MDA提出了PIM(Platform Independent Model)和PSM(Platform Specific Model)的概念,将设计过程分为两个阶段。Thinking in Programming Language只是PSM阶段的工作,至于PIM阶段,则是一个更高层次的抽象。所以说Tinking in Programming Language也不能说是“软件开发的根本性质”。
    不过我非常赞成Coding即Design的观点,MDA的PSM即证明了这一点,设计PSM的过程其实就是对Coding的改进,在PSM的代码自动生成技术实现后,PSM就成为软件的实现阶段了。Coding也是软件开发的重要组成部分,鄙视Coding的所谓项目经理才是最应该被鄙视的。 
     
    那么什么才是“软件开发的根本性质”?我来说说我的看法吧(奏乐),软件开发的根本性质就是:通过Coding解决问题!(怎么都晕倒了?)
    废话,这的确是一句废话。因为这是谁都知道的事。
    然而这也是一句实话,真理有时候就是这么朴素。
    首先,有软件就有Code,即使是MDA被完美地实现了,PSM可以直接生成代码了,也还可以认为PSM是一种图形化的Code,就如同工业上PLC所用的编程语言----梯形图,就是一种典型的图形化Code。
    其次,软件的目的就是解决问题,不能解决问题的软件根本就是废物。
    前面说过,我们都是在盲人摸象,然而摸不出象并不表示象就不存在。对于软件开发的问题,在具体的观点上,各人有各人的看法,但仍然还是存在普遍真理的,这就是邓公的经典论断“不管黑猫白猫,抓得到老鼠就是好猫”,不论是什么软件理论或技术,只要是对解决问题有益的,就是好东东。
    所以不论是概念逻辑分析,还是Thinking in Programming Language,只要有助于你的软件开发工作,那你就应该采纳。从解决问题的角度上说,所以用于解决问题的方法都可以看作技巧,不论是Coding的技巧,还是设计模式,OO,UML……对于解决不同的问题,它们肯定会有不同的侧重,没有哪个是绝对的重要,还是应该以一种平等的观点来看待这些要素的。过于强调其中的某些方面实在有误导之嫌,必然导致别人陷入像pbzjh兄那样的困境。正如toomore兄所言:“手中有了一把榔头,看什么都是钉子”,这样的人还是很多,片面地强调某些方面则必然导致他们放下这把榔头,拿起的不过是另一把榔头。所以我认为还是应该强调它们的重要性是同等的,要根据实际情况处理,如toomore兄所说(BTW:toomore兄的例子都很经典啊):“我记得中央体育台的中国象棋节目的张强大师有一次讲到,高手下棋从来是根据具体的局面情况来制订策略,而许多低手下棋总喜欢把棋走成某几种固定的形状而不顾具体局势如何。”
    基于解决问题这一个目的,对于软件公司的招聘要求也就好理解了,因为他们要的是能够为他们解决具体问题的人,而不是一些只会空谈的人。我们做技术的常常容易犯自以为是的毛病(我也一样),总认为那些开公司的什么都不懂,其实不懂的恰恰是我们,因为经营公司与开发软件是完全不同的两回事。作为公司来说,特别是目前国内的这些小软件公司,最重要的是以最快的速度开发出为用户解决问题的软件,不管你有多么强的逻辑分析能力,如果没有实用的技巧,它是不可能等你去慢慢学习的。至于大公司,如微软之类,它有足够的资源去培养人才,所以它对技巧并不重视。打个简单比方:一个普通的镖局招人,肯定是要有一定外家功夫的人,至于像段誉未学六脉神剑时那样,即使他有很强的内功,镖局也不会要的,因为不能打;但对于大的武林门派来说,要收门徒的话,却一般会挑选有潜质的人,而不在乎他能不能打。(BTW:就像从来没有哪个镖局能发展成为知名武林门派一样,我感觉国内现有的软件公司也不太可能在有限的时间里发展成为国际知名软件公司)
    如果一定要在软件开发的过程中找一个重点的话,我认为是“问题”。只有在正确地定义了问题以后,后面的解决思路和实现才有意义,如果是对一个问题作了错误的定义,即使后面提出了正确的解决思路和实现,那也是对错误问题的解决。这也许就是为什么Karl.E.Weigers凭一本不到200页的薄薄小书《软件需求》而获JOLT大奖的原因。
    我本来就是个狂妄的人,所以也就没有什么假装谦虚的客套话,大家有板砖就尽管扔过来吧。^_^
     
    [Mental Studio]猛禽 
    2004-2-15
      

  3.   

    多些这类的文章,Delphi论坛的才能上层次。支持一下!
      

  4.   

    回复人: reallike(爱翔) ( ) 信誉:100  2005-01-11 12:34:00  得分: 0  
     
     
       我的呢?我还有一篇呢……
      
     
    -----------------------------
    你的地址打不开!!!我就没贴了你自己贴上来吧。。哈
      

  5.   

    貌似偶介里blog上不去鸟,只能在这里灌水了ToT
      

  6.   

    听猛禽说blog停电了  来这里灌水好了
      

  7.   

    一日不博,比便秘还难受ToTPS,在我还没有知道什么叫“编程”之前,偶还不配论“本质”。
      

  8.   

    那么什么才是“软件开发的根本性质”?我来说说我的看法吧(奏乐),软件开发的根本性质就是:通过Coding解决问题!Coding基本是解决问题的最后阶段了,自然而然不能成为软件开发的根本性质;相当部分的初学者其实都很盲目,很容易从一个极端走向另一个极端。技巧仍然是一个必不可少的要素。
    非常之赞同,软件开发的本质的论述也许简单,我们可以比喻成1+1=2这样的例子,但是,如果想要学会1+1=2,或者是知道为什么这样的话,需要用其它的手段,软件的本质不是凭空存在的,如果脱离了其它的辅助性的,他自然而然的成了空中阁楼。但是,所以,在此点上比较赞同ohnnyxia。
      

  9.   

    To  firetoucher(风焱) 
      哈哈~永远不要进食,自然而然不回发生便秘了
      

  10.   

    子曰:学而不思则怠,思而不学则罔。
    学习ing +思考ing
      

  11.   

    2  ihihonline(小小-努力~-IEWS088430) 
    KICK~~~
      

  12.   

    LEEZY-2000的不错,其他的都是P话,有个鸟的意思!