源代码的学习【原文地址:http://www.programfan.com/blog/article.asp?id=17982】
1. 画出整个程序的流程图,理解整个程序流程的思想。画流程图的方式更让人很直接 的理解程序的整体流程,而不会被代码所干扰,让程序员总体上把握整个程序。
2. 对流程各节点(函数或过程)的理解。流程的每一节点是构成整个流程的不可缺少的部份。
3. 再把流程和流程各节点串起来理解整个程序,可能的话最好写出读书笔记。
4. 如果想深刻的学习到源代码的精髓所在,请写一个相近的程序进行操练。当你理解了这个程序并不表明你掌握了这个程序,只有在你操练一个相近的程序时,你才知道你到底理解了多少,掌握了多少。
其实源代码的学习这是一个从整体到不断细化的过程,是一个极为繁琐的过程同时也是一个不断认清事物本原的过程。
很多程序员(包括我自己)在相当长的时间内,过份注重程序代码的细节部份,而忽略了程序的有机整体,这不能不说是一种悲哀。
特别是软件大工业时代的现在,由于项目的庞大,整个项目被人为的分割成七零八落的几个独立小块 (这就更须要有人对整个项目的统领),程序员在这几个小块中各自为战,堕落自己的思维,限制在狭小的空间中还自得其乐。整个一井底之蛙。
但是我们也要看到,现在有越来越多的程序员潜意识里明白了这个缺陷,正在不断的改进。
其实我真正想说的是,大凡世事纷繁复杂,但道理却殊途同归,这才是万法归一的理解。
By [zbkid] at 22:41:36 | Comments[0] | 31 views
软件开发入门学习的个人看法 [2005-1-21]
沙鸥 (wego@163.com)
踏实
偶然在网上看到《由C#风潮想起的-给初学编程者的忠告》一文. 其中一个角度:避免“浮躁”,倡导“踏实”的学习方法,我是很认同的,但总觉该文作者标题“-给初学编程者的忠告”太大,所以在其文列出的一些具体的“操作方法”上我认为可以探讨,如同自己在某次公司总结会上就《软件开发,我们积累的是什么?》为题跟同事聊了半个多小时后,其中一个同事提到希望我能继续把这个题目细化,就刚入行的他们具体该如何发展有更“具操作性”的指引,当时我是跟他们说这只是我在这一行呆了5年多的体会,谈“指引”还太远,只是可以提出来大家思考、讨论。
不要过度贬低编码
不要真的认为"不少大师级的计算机技术研究者是不懂编程的",做软件开发编码是最最基础的东西,只有踏踏实实的掌握好这个基础你才有办法往上走,不管做分析做设计做项目管理你都需要能清楚东西是如何实现的?可不可以实现?否则肯定出现大量的:"设计是设计,编码是编码","产品都是代码人员从头到尾实现的","究竟需花多少时间,难度有多大,开发人员说了算","质量/成本/进度全是黑匣子"...现象,如果你是做编码那编码就更重要了.所以对于有志从事这个行业(软件开发)的个人来说,必须先从"重视编码"开始.过了这一关才能去考虑做系统分析,做项目管理...
软件开发的各个环节是相辅相承的,分析有分析的重要,设计有设计的重要,编码有编码的重要,测试实施也各有其地位,任何一个环节搞不好就如同我们熟悉的木桶理论,"最薄弱的一个环节制约着其总容量".
既然编码重要,那该如何学编码?
专心学好一门语言
算算自己用过的语言也不少(括弧里为使用该语言写的比较有代表性的东东),C(dos版的图像/图标编辑工具,96年的《电脑报》有介绍),C++(可自定义方块形状的方块游戏,被收录于99年《软件》杂志的附送光盘上),汇编(DOS汉字系统,97年底完成),PB(学校自动排课/排考模块,98年),ASP(一套web版的企业信息系统,99年),VB(企业信息系统的核心组件,99年),delphi(工作流平台,组件式GIS系统等),Java(Delphi Client + J2EE Server协同实现),.Net(规则引擎),PHH...
看起来好象也不少,回过头来想想自己真正认真学过的语言只有一个,就是“C”, Dos年代的TC2.0,用它写了大量的小程序,比较系统的了解了编程是怎么一回事,记得那个时候看到什么软件都要琢磨它是如何实现的?如果让我来实现该如何做?也模仿了不少东西,虽然多是很表面的模仿但对自己编程思维的锻炼很有好处.后来用其它语言基本上都只是翻翻帮助,然后找找其Demo代码来看看,很快就可进入状态.
语言都是差不多的,重要的是“编码的思想”,具备了该思想语言就只是工具了,用什么工具实现都差不多,该思想的形成是需要“磨练”的,就是“专心使用一门语言”来磨练(甚至需要有“咬文嚼字的孔已己作风”),然后可“一理通百理通”,不然你只是浮于表面的去学再多的语言都没有.都不能拿来做真正的开发.都不能了解“编码”的内涵.
如在今年招聘面试的时候看到太多写着什么语言都精通(或熟练)的毕业生,我惯用的方法是给他(她)一张纸一支笔,让他(她)用自己最了解的语言写一个算阶乘的函数,这个问题你一看肯定说很简单,好,接着我会往下问,可以有多少种方法来实现:循环,递归…还有吗?你能写出多少种来?(代码基本结构模式的考察).代码质量如何? 有没有考虑错误处理(太多人写的代码会进入死循环比如输入的是负数) ? int的上限是多少,用long? 如果输入值比较大,算得出结果吗,该如何去实现可以计算很大数的该函数?...看着他(她)写出来的代码一个个问题的问就得了,不管你用什么语言,不管你“精通”多少种语言,我只问这些用什么语言来解决问题都需要的基础的东西, 就是“编码的思想”.
在学专一门语言的基础上新东西当然要跟,不然在这个行业你是很难“混下去”的,但有这“学专一门”的前提后,你跟起来就轻松了,而不用总是得“追”~
在“专”一门语言的过程中为解决问题你会发现“算法”很重要,这就是接下来要说的“基础”了.
基础很重要
面试的时候我一般都会问,基础知识学得如何? 一般重点问的是:《数据结构》, 《编译原理》, 《数据库原理》的内容.至于《由》文提到的:《汇编语言》,《 Windows 程序设计》我是不会问的.这些是可以进一步学习的东西,但对现在的开发来说不是必须的.《软件工程》我向来不问,教材理论跟实际差得太远了~
《数据结构》很重要,不懂数据结构很多编码就是“蛮干”,而且往往把“简单问题复杂化”,甚至复杂到不可能解决.认真学习《数据结构》并多做尝试用你熟悉的语言去实现里面的算法,你会发觉“世界真奇妙”~不要认为你不会去开发“编程语言”不需要学习《编译原理》, 《编译原理》里面包含了太多开发软件的“奇妙”的思想案例,认真体会你肯定会被其解决问题的方法折服,从中你能体会到很多东西,对以后做软件(不管是设计还是编码等)大有帮助,里面有很多现存的方法可用在你的项目中,而这些跟《数据结构》是互为补充的.在这些基础上接下来《设计模式》一书你也一定得看看.
很多应用都离不开数据库,最终总得找个地方来“操纵,存储,分析数据”,关于范式,关于锁,关于SQL,关于笛卡儿那一套你总得了解了解,不然无法入手,这就需要好好学习《数据库原理》了.单纯知道几条SQL语句是远远不够的,如何保证数据的完整性,安全性?如何提高效率等等都需要这些基础的支持~
当然英文也是基础,看英文资料确实重要,不单是书,还有网络上的大量资料,论坛…看的时候别害怕就是了,毕竟都是受过高等教育的,英语也学了那么多年起码都有点底吧,配合这两个工具:《金山词霸》及Google.com,不懂的单词“即指即译”,但很多名词或基础知识不是靠单词解释能清楚的,配合搜索引擎查查相关资料看看,记住一点,看到不懂的东西多看几遍,默记一小会,日积月累你能看懂的东西就多了。
兴趣
最后该说说的就是兴趣问题,如果你能对它真正感兴趣(如果要从事软件开发又没兴趣的话赶紧先培养兴趣去^_^),对看技术资料就想别人看武侠小说看球赛一样的话,再配合上面提到的几点(踏实, 先专后广, 基础扎实)相信在这一行多少是可以做点东西出来的~~
By [zbkid] at 8:20:45 | Comments[0] | 38 views
成为软件高手的几个忌讳 [2005-1-20]
主 题: 成为软件高手的几个忌讳
作 者: 阿荣 (进士)
所属论坛: 灌水乐园
本帖分数: 0
回复次数: 34
发表时间: 2004-7-19 21:13:18
正文内容:
1) 不会英语:CS源于美国,重量级的文档都是英文的。不会英语,那么你只能忍受拙劣的翻译和大延迟的文档(翻译出来的文档几乎都是很久以前出版的东西)。
2) 急于求成:什么都没学习就开始编程是最大的忌讳。写C++程序语法都能错,数据结构连线性表都不知道,数据库不知道关系模型,TCP编程不知道socket,还是先坐下来学习几年再说(如果说工作急需,我只能说:早干嘛去了)
3) 过于好问:勤学好问是一种很好的品质,但是如果把勤学丢了,只留下好问,就是一个恶劣的素质了。事无巨细都去请教别人,一则会让人厌烦,二则由于没有系统学习过程,也是不可能学习好的。
4) 只会艳羡别人和说别人不该拿那么多钱,而自己却收入微薄:老实说,绝大多数情况下,收入的高低和你的水平是有正相关系的。不是否认有关系的存在,但是绝对不会10个人中9个人有关系而独独你没有。少抱怨一些多学习一些,提升自己才是最重要的。
5) 过于不求甚解和过于求甚解。了解为什么是很重要的,但是要学习的东西很多,如果什么都弄明白,那么估计头发白了还没有找到所有答案。当然如果什么都不想细致了解,那么只能去做蓝领了。
6) 过分崇拜他人:我想信很多人都是很厉害的,值得大家崇拜,但是如果过于崇拜,把他们的话当成圣经就没有必要了。你需要突破他们,而不是崇拜他们。
7) 不想吃苦:IT业高收入和高竞争是联系在一起的。没有付出永远别想进步。
By [zbkid] at 11:32:51 | Comments[0] | 36 views
论程序设计方法 [2005-1-19]
论程序设计方法
作者:杨老师
如果你是初学者----------------请不要阅读;
但有志成为中高级程序员--------请务必阅读;
如果你是中级程序员------------请务必阅读;
如果你高级程序员--------------请批评指正。
本文是我在“软件工程师班”开学第一节课的讲义,和“计算机软件设计发展”讲座上的内容整理而成。写作本文的目的是引导学生从更高的层次来看待程序设计方法,为将来成为高级程序员而做好理论准备。
一、计算机硬件环境对软件设计方法的限制
计算机的发明到现在已经60年了,计算机程序设计方法也伴随着计算机硬件技术的提高而不断发展。硬件环境对软件设计既有严重的制约作用,也有积极的推动作用。
在我的大学母校(此处删除6个字),数学系的一些老师,有幸成为了我国第一代的计算机DIY一族。呵呵,不要以为是组装PC机呦,他们组装的可是小型机。一人多高铁皮柜大小的主机,加上纸带机(后期改进为读卡机),组装好后,除了供学校自己的科研使用外,还在全国各地销售了十几台。当时(七十年代)一台的售价是10几万元人民币,如果换算到今天,相当于价值大约为100多万元,非常高档的小型计算机了。下面大家猜猜,这么高档的计算机,它的内存是多少那?(都把嘴闭好了,我要公布答案了)—— 4K。
一块50公分见方的内存板,
插入到主机箱中,好了------ 1K;
再插一块内存板,好了------ 2K;
再插一块内存板,好了------ 3K;
再插一块内存板,好了------ 4K;
再......不行了,插不起了,太贵了!这就是当时的环境。这样的环境下,用什么写程序那?当然只有机器码了。先用汇编写,然后翻阅手册手工改写为机器码,然后打卡或穿纸带,输入运行。可以想象,在当时的条件下,什么叫好的程序那?什么叫优秀的程序那?—— 技巧!
程序设计的最初始阶段,是讲究技巧的年代。如何能节省一个字节,如何能提高程序运行的效率,这些都是要严肃考虑的问题。而所谓的程序的易读性,程序的可维护性根本不在考虑范围之内。
今天,35岁以上的学习过计算机的朋友可能都使用过一种个人计算机——APPLE-II(中国也生产过这种计算机的类似产品“中华学习机”)。主频1M,内存48K(扩展后,最多可达到64K)。我就是使用这样的计算机长大的 :)。当年,类似的个人计算机产品,还有PC1500,Layser310等。这种计算机上已经固化了 BASIC 语言,当然只是为学习使用。要想开发出真正的商业程序,则必须使用汇编,否则的话,程序就比蜗牛还要慢了。于是,程序设计中对于技巧的运用,是至关重要的了。
题外话1:
比尔盖茨是 BASIC 的忠实拥护和推动者。当年,他在没有调式环境的状况下,用汇编语言写出了一款仅有 4K 大小的 BASIC 解释器,且一次通过。确实另人佩服。(不象现在微软出品的程序,动辄几十兆。)这也许就是比尔对 BASIC 情有独忠的原因,每当微软推出(临摹)一个新技术,则他会立刻在 BASIC 中提供支持。
题外话2:
在 APPLE-II 上有一款游戏软件“警察抓小偷”,当年熬夜玩游戏,乐趣无穷。后来这款游戏被移植到了PC上,咳~~~根本没有办法玩,因为小偷还没跑就被警察抓到了。硬件的速度提升,另我无法再回味以前的时光了。
二、结构化程序设计
随着计算机的价格不断下降,硬件环境不断改善,运行速度不断提升。程序越写越大,功能越来越强,讲究技巧的程序设计方法已经不能适应需求了。记得是哪本书上讲过,一个软件的开发成本是由:程序设计 30% 和程序维护 70% 构成。这是书上给出的一个理论值,但实际上,从我十几年的工作经验中,我得到的体会是:程序设计占 10%,而维护要占 90%。也许我说的还是太保守了,维护的成本还应该再提高。下面这个程序,提供了两种设计方案,大家看看哪个更好一些那?
题目:对一个数组中的100个元素,从小到大排序并显示输出。(BASIC)
方法1:冒泡法排序,同时输出。
FOR I=1 TO 100
FOR J=I+1 TO 100
IF A[I] > A[J] THEN T=A[J]: A[J]=A[I]: A[I]=T
NEXT J
? A[I]
NEXT I
方法2:冒泡法排序,然后再输出。 FOR I=1 TO 100
FOR J=I+1 TO 100
IF A[I] > A[J] THEN T=A[J]: A[J]=A[I]: A[I]=T
NEXT
NEXT
FOR I=1 TO 100
? A[I]
NEXT
显然,“方法1”比“方法2”的效率要高,运行的更快。但是,从现在的程序设计角度来看,“方法2”更高级。原因很简单:(1)功能模块分割清晰——易读;(2)也是最重要的——易维护。程序在设计阶段的时候,就要考虑以后的维护问题。比如现在是实现了在屏幕上的输出,也许将来某一天,你要修改程序,输出到打印机上、输出到绘图仪上;也许将来某一天,你学习了一个新的高级的排序方法,由“冒泡法”改进为“快速排序”、“堆排序”。那么在“方法2”的基础上进行修改,是不是就更简单了,更容易了?!这种把功能模块分离的程序设计方法,就叫“结构化程序设计”。
三、对程序设计中技巧使用的思考
我可以肯定,大家在开始学习程序设计的时候,一定都做过这样一个题目:求100以内的素数。老师在黑板上,眉飞色舞地写出了第一个程序:(C程序)
方法1: for(i=1; i<100; i++)
{
for(j=2; j< i; j++)
if(i%j == 0) break;
if(j >= i) printf("%d,", i);
}
然后,老师开始批判这个程序“这个叫什么呀?太慢了!因为我们都知道大偶数不可能是素数了,因此,要排除掉!” 于是,意尤未尽地写出了第二个程序:
方法2: printf("2,");
for(i=3; i<100; i+=2)
{
for(j=2; j< i; j++)
if(i%j == 0) break;
if(j >= i) printf("%d,", i);
}
老师说:“看!我们只改动了一点点,程序运行的速度就提高了一倍多”。然后运用诱导式教学法继续提问“程序的效率,还能再提高吗?能!”,得意地写出第三个程序:
方法3: printf("2,");
for(i=3; i<100; i+=2) ''不考虑大偶数
{
for(j=3; j< i/2; j+=2) ''不考虑用偶数去测试,而且只验算到一半就足够了
if(i%j == 0) break;
if(j >= i) printf("%d,", i);
}
“大家看,我们又只改动了一点点,运行速度又提高了一倍多。可以了吗?不可以!我们还能再提高”。于是又高傲地写出了第四个程序:
方法4: printf("2,");
for(i=3; i<100; i+=2)
{
int k = sqrt(i);
for(j=3; j<= k; j+=2)
if(i%j == 0) break;
if(j >= k ) printf("%d", i);
}
然后,开始证明为什么我们判断素数的时候,只需要验算到平方根就足够了:
假设p是合数,那么令:p=a*b。反正法:由于我们已经判断了p的平方根以内的整数都不能被p整除,于是 a>SQRT(p)。基于同样的理由 b>SQRT(p)。于是 p = a * b > SQRT(p) * SQRT(p) = p 得出矛盾, 命题得正。
的确,“方法4”的确比“方法1”的运行速度要提高了好几倍,甚至好几十倍。但我们仔细分析测试看看。
(1)“程序4”到底比“程序1”快了多少那?我在某台计算机上进行测试(P4,1.5G)得到的速度对比表:
计算范围
100 1000 10000 100000
速度差 0.00秒 0.01秒 0.18秒 15秒
(2) 在10万以上,才会看出一些差别。而这种差别根本就不够底偿程序设计阶段的付出。如果计算的范围再大,那么不管是“方法1”,还是“方法4”都不是好的算法。(计算素数的另外一个比较优秀的算法叫“漏筛法”)
(3)写出“方法1”,只要具有小学四年级的数学水平就够了,而“方法4”则需要初中三年级的水平并且还要具备一些“数论”的知识。
(4)从维护性看,如果你写的程序需要另外一个程序员来维护,或者若干时间以后,你重新来阅读这段程序,那么就会对这个程序产生很多疑问:这个求平方根是干什么用的?其实,就这个题目来说,使用到“方法3”就已经足够了。
总结发言:
I. 计算机的价格每年下降一半,而运算速度每年提高一倍”,因此我们应该把速度提高的任务交给硬件实现。
II. 从易读性、维护性出发,程序员只负责按定义给出软件实现。算法的问题是数学家解决的。
题外话:
多年以来,人们一直在寻找动态图象(影视)的存储和回放的算法,但效果都不理想。直到有人发现,原来在200多年前的数学家早就帮我们解决了这个问题——傅立叶(Fourier)级数展开。因此我要说,优秀的算法不是我们程序员要考虑的问题,我们的任务只要按照数学家给出的算法翻译为计算机程序语言而已。(这句话恐怕要遭到大多数程序员抛出的板砖袭击)再比如,计算一元多次方程解的问题。我们使用的就是牛顿的迭代算法。不要怪我瞧不起你,你能发明这个方法的话,那就是当代的牛顿了。
四、程序的易读性与书写方法
程序是否容易阅读和维护,与怎么书写有很大的关系。说实在的,C语言中为了方便程序员书写,允许使用++,--,<<,&&,?......这些运算符号。但很多人经常乱用,以为自己写的程序多么简洁,效率多高。其实,当你分行书写的话则更加容易阅读和维护,效率也不会降低,因为编译程序早就帮你优化为最快捷的代码了。先看一个简单的例子:
计算一个整数乘 255(C语言)
方法1:a *= 255;
方法2:因为移位运算比乘法运算要快很多倍,因此a*255的运算书写为:
a =(a<<8)-a; //a*255 = a*256 - a = (a<<8) - a
方法1的书写非常简单,直截了当,显然更容易维护。而方法2的书写运用了移位的技巧,不容易阅读,但效率最高。是不是真的是这样那?把这两个程序编译为汇编代码看看。原来无论是方法1还是方法2,它们的汇编代码都是一样的:
mov ecx, eax
shl eax, 8
sub eax, ecx
也就是说,你认为非常技巧的书写方法,其实编译器的优化功能早就帮你想到了。那么方法2的方式就很值得批判了。下面是几个有关C语言书写方面的重要原则:
尽量表达愿义,多加注释;
变量名称和函数名称,要使用有意义的符号,并且遵守“匈牙利命名法”;
不要为俭省内存,使一个变量在一个模块中表达多个含义。
在某个模块中,前半部分用i表示计数器,由于后半部分不再使用计数器了,于是又用i来保存某个中间的结果。等你维护这段程序的时候,保证你肯定会犯傻的。
在使用条件表达式的时候,不要混合书写运算表达式;
经常有人在书写for循环的时候,使用这样的方式: for(int a=1,s=0; a<=100 && (s+=a); a++);
天呀,这样写是不会提高程序运行效率的,尤其是当运算表达式复杂的时候,就更不容易阅读了,还是把运算写到for的循环体中吧。 int s = 0;
for(int a=1; a<=100; a++)
s += a; //计算1+2+...+100 这不很好吗?!
再比如,if(a=b)这个写法在语法上是允许的,但不要使用。要使用也要if(0!=(a=b))这样的方式。 还有值得一提的是慎用“,”(逗号运算符)。
不要连续使用++,--,<<,*,& .....这样的运算符号。
a = b++-(--c<<1+e&0x0f>>1); //这个人有病。出这个题目考试的老师,也有病。
常量要写在条件表达式的左边;
if(5 == a) 这是正确的写法,这样书写可以避免勿输入而导致的 if(a=5)这样的错误。
避免程序中{ }的嵌套层次太深;
最多4层。如果必须大于4层,那么写成调用子函数或宏的方式。
尽量多地使用断言;
当你在书写程序的过程中,凭你的智慧,你一定是知道:程序运行到我正书写的这行代码的时候某个变量一定是某个值。好啦,那么不要忧郁,马上加上一句代码:ASSERT(nnn == xxx);。将来在调式维护这段代码的时候,你会得到无限美妙的回报。
书写需要“成对匹配”使用的代码的时候,在写使用代码之前,就先把结束写出来;
file.Open(...); //当要打开文件的时候 char *lp=new char [100]; //当要申请内存的时候
...... //先不要写这段代码 ...... //先不要写这段代码
file.Close(); //马上写关闭 delete [] lp; //马上写释放
xxx.Loack(); //当某个对象需要锁定的时候 for(....)
...... //先不要写这段代码 { //写大括号的时候
xxx.Unlock(); //马上写解锁 } //马上写大括号结束
和这个道理相同,在C++的类中,如果需要申请内存,那么先在构造函数中给出 lp=NULL;然后马上在析构函数中书写 if(lp) delete []lp;
可以适当地使用goto;
在结构化程序设计中,goto 是被排斥的。但是,如果适当地使用 goto 不但不影响斜率,而且还能提高程序的可读性。
题目:合并2个文件到一个新文件中。(不要挑我的毛病呀~~~~~,我使用的是类C的方式书写的。)
方法1:
FILE *f1,*f2,*f3;
if(Open(f1)成功)
{
if(Open(f2)成功)
{
if(Open(f3)成功)
{
...... //这里是真正干活的地方
Close(f1);
Close(f2);
Close(f3);
}
else //f3不成功
{
Close(f1);
Close(f2);
......
}
}
else //f2不成功
{
Close(f1);
......
}
}
else //f1不成功
{
......
}
==========================================================
方法2:FILE *f1=NULL,*f2=NULL,*f3=NULL;
if(Open(f1)不成功) goto err;
if(Open(f2)不成功) goto err;
if(Open(f3)不成功) goto err;
...... //这里是真正干活的地方
err:
if(f3) Close(f3);
if(f2) Close(f2);
if(f1) Close(f1);
方法1是最最标准的结构化设计,好吗?不好!尤其是当{ }的层次比较深的时候,估计你寻找真正干活的代码的地方都找不到。而使用方法2的程序,不但程序容易读,而且没有{ } 的深度。在C++中,又提供了异常try/catch的设计结构,而异常的结构则比 goto 的结构更好、更完善了。
五、面向对象的程序设计
随着程序的设计的复杂性增加,结构化程序设计方法又不够用了。不够用的根本原因是“代码重用”的时候不方便。面向对象的方法诞生了,它通过继承来实现比较完善的代码重用功能。很多学生在应聘工作,面试的时候,常被问及一个问题“你来谈谈什么是面向对象的程序设计”,学生无言,回来问我,这个问题应该怎么回答。我告诉他,你只要说一句话就够了“面向对象程序设计是对数据的封装;范式(模板)的程序设计是对算法的封装。”后来再有学生遇到了这个问题,只简单的一句对答,对方就对这个学生就刮目相看了(学生后来自豪地告诉我的)。为什么那?因为只有经过彻底的体会和实践才能提炼出这个精华。
面向对象的设计方法和思想,其实早在70年代初就已经被提出来了。其目的就是:强制程序必须通过函数的方式来操纵数据。这样实现了数据的封装,就避免了以前设计方法中的,任何代码都可以随便操作数据而因起的BUG,而查找修改这个BUG是非常困难的。那么你可以说,即使我不使用面向对象,当我想访问某个数据的时候,我就通过调用函数访问不就可以了吗?是的,的确可以,但并不是强制的。人都有惰性,当我想对 i 加1的时候,干吗非要调用函数呀?算了,直接i++多省事呀。呵呵,正式由于这个懒惰,当程序出BUG的时候,可就不好捉啦。而面向对象是强制性的,从编译阶段就解决了你懒惰的问题。
巧合的是,面向对象的思想,其实和我们的日常生活中处理问题是吻合的。举例来说,我打算丢掉一个茶杯,怎么扔那?太简单了,拿起茶杯,走到垃圾桶,扔!注意分析这个过程,我们是先选一个“对象”------茶杯,然后向这个对象施加一个动作——扔。每个对象所能施加在它上面的动作是有一定限制的:茶杯,可以被扔,可以被砸,可以用来喝水,可以敲它发出声音......;一张纸,可以被写字,可以撕,可以烧......。也就是说,一旦确定了一个对象,则方法也就跟着确定了。我们的日常生活就是如此。但是,大家回想一下我们程序设计和对计算机的操作,却不是这样的。拿DOS的操作来说,我要删除一个文件,方法是在DOS提示符下:c:> del 文件名<回车>。注意看这个过程,动作在前(del),对象在后(文件名),和面向对象的方法正好顺序相反。那么只是一个顺序的问题,会带来什么影响那?呵呵,大家一定看到过这个现象:File not found. “啊~~~,我错了,我错了,文件名敲错了一个字母”,于是重新输入:c:> del 文件名2<回车>。不幸又发生了,计算机报告:File read only. 哈哈,痛苦吧:)。所以DOS的操作其实是违反我们日常生活中的习惯的(当然,以前谁也没有提出过异议),而现在由于使用了面向对象的设计,那么这些问题,就在编译的时候解决了,而不是在运行的时候。obj.fun(),对于这条语句,无论是对象,还是函数,如果你输入有问题,那么都会在编译的时候报告出来,方便你修改,而不是在执行的时候出错,害的你到处去捉虫子。
同时,面向对象又能解决代码重用的问题——继承。我以前写了一个“狗”的类,属性有(变量):有毛、4条腿、有翘着的尾巴(耷拉着尾巴的那是狼)、鼻子很灵敏、喜欢吃肉骨头......方法有(函数):能跑、能闻、汪汪叫......如果它去抓耗子,人家叫它“多管闲事”。好了,狗这个类写好了。但在我实际的生活中,我家养的这条狗和我以前写的这个“狗类”非常相似,只有一点点的不同,就是我的这条狗,它是:卷毛而且长长的,鼻子小,嘴小......。于是,我派生一个新的类型,叫“哈巴狗类”在“狗类”的基础上,加上新的特性。好了,程序写完了,并且是重用了以前的正确的代码——这就是面向对象程序设计的好处。我的成功只是站在了巨人的肩膀上。当然,如果你使用VC的话,重用最多的代码就是MFC的类库。
六、组件(COM)程序设计
有了面向对象程序设计方法,就彻底解决了代码重用的问题了吗?答案是:否!硬件越来越快,越来越小了,软件的规模却也越来越大了,集体合作越来越重要,代码重用又出现的新的问题。
我用C++写的类,不能被BASIC重用——不能夸语言;
你要干什么,想重用我的代码?不行,这样你就看见了我的设计思想——只能在源程序级别重用,不能在二进制级别(可执行代码及)重用;
我耗尽毕生的精力,写了一个包罗万象的类库,但没有人用。因为他们说:你这个太大了,我的程序只有1K,你却给我一个 10000MB 的库——MFC 的尴尬;
太好了,我终于找到了程序中的一个BUG,已经修改完成,而且是只改动了一个字节。接下来我要重新向我的用户分发新的版本,我的用户有......10万个——升级的非鲁棒性,不是我分发累死了,就是用户重新安装累死了。(鲁棒:robust。意为强壮性的,平顺的,顺滑的.....鬼知道是哪个不懂计算机的人翻译的这个词汇。)
我想写一个集大成的软件,这个软件的功能是我中有你,你中有我。既能实现文字编辑,又能实现电子表格计算,又能实现自动翻译,还能画图,还能实现数据库检索,还可以看电影.....只要用了我的这个软件,想要什么就有什么,我要强占整个软件的市场------OLE实现的重用功能,只要学会了COM,这些都不是问题了;
用户甲要求我的软件窗口上下分割,用户乙要求我的软件窗口左右分割......我需要在我的软件基础上,派生出100个类型,可怎么办呀?将来怎么维护呀?------在脚本的支持下,实现同一程序的的灵活配置而重用,问题迎刃而解了;
我是个老板,你知道我有多痛苦吗?我手下的员工向我提出加工资的要求,我不得不答应呀。因为如果这个员工跳槽了,他的代码要维护起来有多难!!!——现在好啦,我要求员工统统用组件写模块,想加工资?门都没有,威胁我要走?那你走吧,这个月的工资也不发了。反正用组件写的代码,我可以很容易地进行包容和聚合实现维护。(老板的福音,程序员的悲哀);
还有好多那,现在想不起来了......
COM程序设计方法,就是解决以上问题的一个方式。有很多朋友觉得COM非常复杂难懂,不想学习了。你一定学习过程序设计的最基本的方法(非结构化设计:汇编、gwBasic......),然后,你又学习了结构化程序设计(C、Pascal......),然后,你又努力学习并熟练掌握了面向对象的程序设计方法(C++、Delphi、Java......),那么不要怕,要有信心去学习组件程序设计,它只是一个设计方法和思想,并且是目前较高级的方法,如果不掌握,就太可惜了。
学习了结构化程序设计,你就会“藐视”那些不遵守结构化设计思想而写出的代码;
学习了面向对象设计,你就会“嘲笑”那些为找BUG而晕头转向的程序员;
同样,学习了组件程序设计,你就会站在更高的层次看待程序设计。
七、结束语
写程序的目的是什么?养家糊口、兴趣使然、我的事业......这些都对。但我要强调的是:写程序的目的是为了修改程序。在这个观点上,那么写注释、写文档、选择语言、选择结构......都是为这个服务的。本文从软件设计方法的进化角度来反复阐述这个观点,希望爱好者能有所体会和思考。
文中所讨论的技术和观点,适合于大多数情况下的程序设计,而对于特殊的应用的(驱动开发,嵌入式开发,网络通讯,实时视频......),这些领域中,由于硬件环境的限制和极限效率的要求,有些观点就不合适了,需要具体情况具体分析。另外就是对于程序设计的初学者,可以先不考虑这么多问题,以掌握基本技巧方法和思想为要。
欢迎大家批评指正。文中一些调侃的部分,也请勿对号入坐^_^。
[align=left][size=1][color=#cccccc][Edit on 2005-1-23 16:48:56 By zbkid][/color][/size][/align]
By [zbkid] at 16:59:57 | Comments[0] | 36 views
对编程初学者的忠告 [2005-1-15]
作为一名自考生,我觉得除了考过每一门课外,还有一些理念需要学习:
我始终认为,对一个初学者来说,IT界的技术风潮是不可以追赶的,而且也没有能力去追赶。我时常看见自己的DDMM们把课本扔了,去卖些价格不菲的诸如C#, VB.Net这样的大部头,这让我感到非常痛心。而许多搞不清指针是咋回事的BBS站友眉飞色舞的讨论C#里面可以不用指针等等则让我觉得好笑。C#就象当年的ASP一样,“忽如一夜春风来,千树万树梨花开”,结果许多学校的信息学院成了“Web学院”。96,97级的不少大学生都去做Web了。当然我没有任何歧视某一行业的意识。我只是觉得如果他们把追赶这些时髦技术的时间多花一点在基础的课程上应该是可以走得更远的。
几个误区
初学者对C#风潮的追赶其实也只是学习过程中经常遇到的几个误区之一。我将用一些实际的例子来说明这些现象,你可以按部就班的看看自己是不是属于其中的一种或者几种:
认为计算机技术等于编程技术:
有些人即使没有这个想法,在潜意识中也有这样的冲动。让我奇怪的是,许多信息学院的学生也有这样的念头。认为计算机专业就是编程专业,与编程无关的,或者不太相关的课程他统统都不管,极端的学生只要书上没带“编程”两个字他就不看。
其实编程只是计算机技术应用过程中一种复杂性最低的劳动,这就是为什么IT业最底层的人是程序员(CODER)。计算机技术包括了多媒体,计算机网络,人工智能,模式识别,管理信息系统等等这些方面。编程工作只是在这些具体技术在理论研究或者工程实践的过程中表达算法的过程。编程的人不一定对计算机技术的了解就一定很高。而一个有趣的现象是,不少大师级的计算机技术研究者是不懂编程的。网上的炒作和现实中良好的工作待遇把编程这种劳动神秘化了。其实每一个程序员心里都明白,自己这些东西,学的时候并不比其它专业难,所以自然也不会高档到哪里去。
咬文嚼字的孔已己作风:
我见过一本女生的《计算机网络原理》教材,这个女生象小学生一样在书上划满了横杠杠,笔记做得满满的,打印出来一定比教材还厚。我不明白的是,象计算机网络原理这样的课程有必要做笔记?我们的应试教育的确害了不少学生,在上《原理》这一类课程的时候许多学生象学《马列原理》一样逐字背诵记忆。这乃是我见过的最愚蠢的行为。所谓《原理》,即是需要掌握它为什么这样做,学习why,而不是how(怎样做)。极端认真的学生背下以太网的网线最大长度,数据帧的长度,每个字段的意义,IP报头的格式等等,但是忘了路由的原则,忘了TCP/IP协议设计的宗旨。总之许多人花了大量的时间把书背得滚瓜烂熟却等于什么也没学。
在学习编程的时候这些学生也是这样,他们确切的记得C++语法的各个细节。看完了C++教程后看《Thinking in C++》(确实是好书),《Inside C++》,《C++ reference》,this C++, that C++……,然后是网上各种各样的关于C++语法的奇闻逸事,然后发现自己又忘了C++的一些语法,最后回头继续恶补…。有个师弟就跟我说:“C++太难了,学了这里忘了那里,学了继承忘了模板。”我的回答道:“你不去学就容易了”。我并没有教坏他,只是告诉他,死抠C++的语法就和孔已己炫耀茴香豆的茴字有几种写法一样毫无意义。你根本不需要对的C++语法太关心,动手编程就是了,有不记得的地方一查MSDN就立马搞定。我有个结论就是,实际的开发过程中对程序语法的了解是最微不足道的知识。这是为什么我在为同学用Basic(我以前从没有学过它)写一个小程序的时候,只花了半个小时看了看语法,然后再用半个小时完成了程序,而一个小时后我又完全忘记了Basic的所有关键字。
不顾基础,盲目追赶时髦技术:
终于点到题目上来了。大多数的人都希望自己的东西能够马上跑起来,变成钱。这种想法对一个已经进入职业领域的程序员或者项目经理来说是合理的,而且IT技术进步是如此的快,不跟进就是失业。但是对于初学者来说(尤其是时间充裕的大中专在校生),这种想法是另人费解的。一个并未进入到行业竞争中来的初学者最大的资本便是他有足够的时间沉下心来学习基础性的东西,学习why而不是how。时髦的技术往往容易掌握,而且越来越容易掌握,这是商业利益的驱使,为了最大化的降低软件开发的成本。但在IT领域内的现实就是这样,越容易掌握的东西,学习的人越多,而且淘汰得越快。每一次新的技术出来,都有许多初学者跟进,这些初学者由于缺乏必要的基础而使得自己在跟进的过程中花费大量的时间,而等他学会了,这种技术也快淘汰了。基础的课程,比方数据结构,*作系统原理等等虽然不能让你立马就实现一个linux(这是许多人嘲笑理论课程无用的原因),但它们能够显著的减少你在学习新技术时学习曲线的坡度。而且对于许多关键的技术(比方Win32 SDK程序的设计,DDK的编程)来说甚至是不可或缺的。
如果你是学生,或者如果你有充足的时间。我建议你仔细的掌握下面的知识。我的建议是针对那些希望在IT技术上有所成就的初学者。同时我还列出了一些书目,这些书应该都还可以在书店买到。说实在的,我在读其他人的文章时最大的心愿就是希望作者列出一个书单。
大学英语-不要觉得好笑。我极力推荐这门课程是因为没有专业文档的阅读能力是不可想象的。中文的翻译往往在猴年马月才会出来,而现在的许多出版社干脆就直接把E文印刷上去。学习的方法是强迫自己看原版的教材,开始会看不懂,用多了自然熟练。吃得苦下得狠心绝对是任何行业都需要的品质。
计算机体系结构和汇编语言-关于体系结构的书遍地都是,而且也大同小异,倒是汇编有一本非常好的书。《80x86汇编语言程序设计教程》(清华大学出版社,黑色封面,杨季文著)。你需要着重学习386后保护模式的程序设计。否则你在学习现代操作系统底层的一些东西的时候会觉得是在看天书。
计算机操作系统原理-我们的开发总是在特定的操作系统上进行,如果不是,只有一种可能:你在自己实现一个操作系统。无论如何,操作系统原理是必读的。这就象我们为一个芯片制作外围设备时,芯片基本的工作时序是必需了解的。这一类书也很多,我没有发现哪一本书非常出众。只是觉得在看完了这些书后如果有空就应该看看《Inside Windows 2000》(微软出版社,我看的是E文版的,中文的书名想必是Windows 2000技术内幕之类吧)。
数据结构和算法-这门课程能够决定一个人程序设计水平的高低,是一门核心课程。我首选的是清华版的(朱战立,刘天时)。很多人喜欢买C++版的,但我觉得没有必要。C++的语法让算法实现过程变得复杂多了,而且许多老师喜欢用模块这一东西让算法变得更复杂。倒是在学完了C版的书以后再来浏览一下C++的版的书是最好的。
软件工程-这门课程是越到后来就越发现它的重要,虽然刚开始看时就象看马哲一样不知所云。我的建议是看《实用软件工程》(黄色,清华)。不要花太多的时间去记条条框框,看不懂就跳过去。在每次自己完成了一个软件设计任务(不管是练习还是工作)以后再来回顾回顾,每次都会有收获。
Windows程序设计-《北京大学出版社,Petzold著》我建议任何企图设计Windows程序的人在学习VC以前仔细的学完它。而且前面的那本《Inside Windows 2000》也最好放到这本书的后面读。在这本书中,没有C++,没有GUI,没有控件。有的就是如何用原始的C语言来完成Windows程序设计。在学完了它以后,你才会发现VC其实是很容易学的。千万不要在没有看完这本书以前提前学习VC,你最好碰都不要碰。我知道的许多名校甚至都已经用它作为教材进行授课。可见其重要。
上面的几门课程我认为是必学的重要课程(如果你想做Windows程序员)。
对于其它的课程有这样简单的选择方法:如果你是计算机系的,请学好你所有的专业基础课。如果不是,请参照计算机系的课程表。如果你发现自己看一本书时无法看下去了,请翻到书的最后,看看它的参考文献,找到它们并学习它们,再回头看这本书。如果一本书的书名中带有“原理”两个字,你一定不要去记忆它其中的细节,你应该以一天至少50页的速度掌握其要领。尽可能多的在计算机上实践一种理论或者算法。
你还可以在CSDN上阅读到许多书评。这些书评能够帮助你决定读什么样的书。
日三省乎己
每天读的书太多,容易让人迷失方向。一定要在每天晚上想想自己学了些什么,还有些什么相关的东西需要掌握,自己对什么最感兴趣,在一本书上花的时间太长还是不够等等。同时也应该多想想未来最有可能出现的应用,这样能够让你不是追赶技术潮流而是引领技术潮流。同时,努力使用现在已经掌握的技术和理论去制作具有一定新意的东西。坚持这样做能够让你真正成为一个软件“研发者”而不仅仅是一个CODER。
把最多的时间花在学习上
这是对初学者最后的忠告。把每个星期玩SC或者CS的时间压缩到最少,不玩它们是最好的。同时,如果你的ASP技术已经能够来钱,甚至有公司请你兼职的话,这就证明你的天份能够保证你在努力的学习之后取得更好的收益,你应该去做更复杂的东西。眼光放长远一些,这无论是对谁都是适用的。
[Edit on 2005-1-15 0:09:23 By zbkid]
By [zbkid] at 0:07:07 | Comments[0] | 41 views
程序宝典:C++学习感想 [2005-1-14]
【简 介】
很多新手特别容易会对自己所学习的东东产生疑惑、迷茫。觉得自己学这个东西,花了这么多时间有没有用,会不会过时?这种思想很普遍。
在一些论坛上经常会看到一些各语言的优劣比较,知道自己所学语言的优劣也好,但是如果一味停留在这个层面就没有用了。任何语言都只是工具而已。重要的是使用工具的人!就我个人的经验来讲,真正处于业界搞开发的人都愿意使用成熟的、为自己所熟知的技术来完成工作。而新手都喜欢用一些比较新的技术来做开发,而且喜欢追求新奇(从界面很容易看出来,花花绿绿的界面多半出自新手)。其实,安于用一些效率可能低下、扩展性和维护性差的方法来解决问题并不是开发人员的错。他们只是在完成工作而已。但是作为一个真正有上进心的开发人员,我们应该使用更优雅和高效的编程技术,这才是我们逐渐变成编程“大牛”的好习惯。老是停留在原地,很容易被淘汰的。在软件开发这个行当,尤其如此。无论是对学生,还是一线开发人员,我觉得都不应该产生“书读够了”的感叹!我有时候喜欢将以前看过的书翻出来再看,每次总能体会到一些新东西。有关C++语言的书籍更是如此,而且我觉得我所起的题目不是很好。为什么?因为我觉得学习语言还只是新手跨入软件开发“地狱”的第一步,单单学习语言本身是远远不够的,还要学习相关的程序库(C++当然首选是先学习C++标准程序库)、相关的平台技术(如.NET),说得更远一点,还要锻炼对目标问题的分析、归纳能力等等。工作之前,技术路线自己作主,工作之后,绝大多数程序员将被公司技术路线左右。所以,趁现在还有时间,可以学一些自己感兴趣的。如果想搞软件开发,特别是电力系统软件的开发,学好C++不会令我们失望。当我们进入C++的前门,然后经过一段黑暗之路,再从后门出来到达光明顶后,我们会体味到“一览众山小”的感觉。
推荐书籍:
《编程高手箴言》---------- 梁肇新(用过超级解霸的都应该知道吧,^_^)写的第一本书,其中有几章还是值得一读的。在这本书中,梁告诉我们,学东西要耐心,要耐得住“寂寞”,走自己的路,让别人去“说”吧!
最近比较忙,原来打算紧扣主题讲讲一些具体的C++语言的细节的,但还是抽不出大段的时间了。所以,现在只能再漫谈一些关于C++的故事了。
C++源于C语言,还记得很久以前学习C语言的时光(那是一段快乐而充实的时光),可是现在学习C++,并不是在C的基础上加上了类而已,如果这样认为,我们是耍不好C++的。因此,C++绝不是C的升级或扩充,我们应该把C++当作一门新语言来学习(C++之父Bjarne Stroustrup语)。
写程序首先希望是程序能正确执行,其次是效率能够被接受,再次就是易于维护。C++是一个难学易用的语言。C++提供了太多可选择的东西,而且使用使用C++来写程序可以有四种思考模式:基于过程、基于对象、面向对象和泛型。我们使用一种语言来写程序,并不意味着就是使用语言本身,换句话说,我们更多的时候是使用程序库在写程序。比如MFC、STL、ATL、VCL等等。其中要使用C++来写出结构优美、性能卓越、代码简洁、易于维护的代码,首推C++标准程序库。STL对效率做了严格的要求,而且使用STL写出来的程序简洁美观(前段时间我特意贴了一个要求对若干整数进行排序的帖子,其实目的就是用来展示STL的简洁优雅)。一旦习惯使用泛型思维来考虑问题,我们能够充分体会到模板带来的美!对于数值计算来说,C++标准程序库可以充分满足现代化服务和商业计算对数据、信息的即时回应的要求。
我觉得学好一门语言最重要的就是实践。也就是多“写”!“工程经验之积累”对已具有一段开发时间的程序员而言,非常重要!只有在不断的积累中,我们才能渐渐体会到C++语言中的一些背后的东西。对于这点,没有大量程序代码写作经验的菜鸟,也可以借助《Effective C++》先攒一些经验值。《Effective C++》是一本好书!。Meyers的书绝对值得一读,Meyers可以说当今C++社群中数一数二的技术专家。
推荐网站:www.royaloo.com
C++提供了操作符new来在堆上分配内存,操作符delete来释放内存。有些情况下,我们需要对内存的分配和释放进行更好的控制。许多程序创建和释放一些重要类的大量的对象,如tree nodes,linked lists links,points,lines,messages,etc.使用通用的内存分配器如new和delete来进行这些对象的分配和释放有时将支配程序的运行时间和内存需求。
两方面的因素:通用内存分配操作的运行和空间的耗费以及不同对象大小引起的内存碎片。类使用定制的内存分配器将加快模拟器、编译器和类似程序的执行速度。
例外一种需要更好的内存控制的情况是:需要在有限资源的情况下长时间不间断运行的程序。实时系统经常需要用最少的耗费来获取有保证的可预期的内存。这也就导致了更好的内存控制的需要。一般来说,这些程序都避免使用动态的内存分配,而使用特殊目的的内存分配器来管理有限资源。
此外,还有一些情况下由于硬件或系统的要求,需要将对象放在指定的内存位置。这也需要进行定制的内存管理(通过重载new来加以实现)。
在C++ Release 2.0中,为了满足以上需求,内存管理机制做了相应的修改。主要是引进了operator new [] 和 operator delete []。
new操作符的作用范围(Scope for operator new Functions)
操作符(Operator) 范围(Scope)
::operator new Global
class-name::operator new Class
operator new的第一个参数必须是类型size_t(在STDDEF.H中定义的类型),返回类型
为void *。
当分配内建(built-in)类型的对象、未包含用户自定义的new操作符函数的类对象、任何类型的数组时,使用全局new操作符函数。当在类中自定义new操作符时,分配该类对象的内存时,调用该类的new操作符。如下:
#include
#include
class Blanks
{
public:
Blanks(){}
void *operator new( size_t stAllocateBlock, char chInit );
};
void *Blanks::operator new( size_t stAllocateBlock, char chInit )
{
void *pvTemp = malloc( stAllocateBlock );
if( pvTemp != 0 )
memset( pvTemp, chInit, stAllocateBlock );
return pvTemp;
}
int main()
{
Blanks *a5 = new( 0xa5 ) Blanks;//创建对象Blanks,并且初试化为0xa5
return a5 != 0;
}
new操作符可以重载,而delete却不行。因为等到需要释放的时候,我们所能得到的就是一个指针。而且该指针可能不是原先的对象类型指针(有可能进行了类型转换)。实际上,当使用new获得一个指向一片内存的指针时,在该片内存前有一个指示器(indicator),记录实际分配的内存数量。当调用delete时,可以获知需要释放的内存大小。数组的释放(Deallocating Arrays):
void f( )
{
X* p1 = new X[10];
//...
delete [] X;
}
为什么不使用delete [10] X;来释放内存?Bjarne Stroustrup称这种做法容易导致错
误,而将记录元素个数的任务放在delete的实现中了。
至于为什么C++中未内建垃圾收集器(Garbage Collection)的原因,看《C++语言的设计和演化》(En) Bjarne Stroustrup 机械工业出版社(俗称:D&E)可以得到答案。
此外,C++标准库中提供了一种智能型指针auto_ptr,这种指针可以帮助我们防止“被异常抛出时发生资源泄漏”。但是缺点是该智能型指针不能指向数组,因为其内部释放内存是通过delete而非delete [] 来进行的。所以,只能使用其来指向一个单个对象。
模板部分是C++中比较难的部分,也是C++的魅力所在。以下文字是我以前看过的,具体出处不清楚了。今天稍微整理了一下,作为模板介绍的一个单元。
By [zbkid] at 21:44:59 | Comments[0] | 36 views
[转]写给想当程序员的朋友 -- 一个还不太老的程序员的体会 [2004-12-28]
写给想当程序员的朋友 -- 一个还不太老的程序员的体会
--------------------------------------------------------------------------------
作者:风化
软件以程序员为本 - -《程序员》
谨以此文献给所有想当程序员的朋友
(一) 文章由来及个人经历
我是一名计算机专业的本科毕业生,毕业已经1年多了。毕业后从事的是软件编程工作,经常有其他专业的朋友想从事软件编程工作,向我请教如何,因为我自觉涉行不深,不敢信口开河,无奈朋友信任,我不得不郑重考虑一下这个问题了,来帮助朋友选择和回报朋友的信任。
这也就是此文的由来。
还是先谈谈我个人的经历吧。(是不是有点俗套,但我觉得了解我的经历,有助于理解我话的含义;我一向认为不了解古龙的生活经历的,不会真正读懂古龙的作品和古龙笔下的英雄的)我本科就读于南方一所著名的高校(因为自己的不成气,愧谈母校名谓),学的就是计算机专业。上本科时,几乎没有认真的听完一门专业课程,上课看报纸睡大觉,下课看录像看小说看球赛,临考抱佛脚,每次考试和课程设计都是蒙混过关。(于之相对是,我选修的工商管理和经济贸易方面的课到是听得不亦乐乎,考的分数颇高,也许这才是我的真正兴趣所在。)
总而言之,大学是混过来了,对专业的理解和掌握程度,应该没有达到毕业要求的合格水平。(也很后悔,但是有什么用呢,当时不知道珍惜;如果上天再给我一次机会的话,我一定会抓住,多看点美国大片少看点港片;现在,重回校园是我的一大理想)但是大学的学习使我有了一个简单的知识框架(总算学费没白交),我对一个朋友这样形容过我的这个知识框架,“它不是钢筋铸的,是稻草扎的”,哈哈哈,不要笑,真的,我敢说很多本科毕业的朋友的本专业的知识框架也只不过是“稻草扎的”。直到现在,我一直觉得自己的基础知识还是很薄弱,一直想抓点时间,把基础书本好好的温习一下。(此项任务正在计划和实施中)
毕业后,分配到某研究所工作。当领导让我选择自己以后的工作方向时,我毫不犹豫的选择了软件(也不知道到底是对还是错,但我决不后悔)。此研究所主要是以硬件为核心搞通信控制设备的研发生产;软件是辅助,所以也不受什么重视,很多搞软件的人都跳槽走了,留下来的大都是一些已经废掉和行将废掉的“伪/萎”程序员(名副其实的“软件人员”)。在这里感觉不到什么高紧张和高技术程度的研究和开发;软件开发的技术含量极低,以致于大部分人只有半年的学习和开发经验,以后都是这些知识和经验的重复利用。(我问过其他到研究所工作的同学,他们说都一样,呜呼,我们的国防科研开发呀)对于软件的开发,领导的意志和老掉牙的经验在新课题的技术采用和开发中起了决定性作用,没有明确的需求,没有明确的开发计划和进度,大家在一天一天一周一周的浪费着宝贵的时间,最后开发出来的东西修来改去,直至它变成垃圾。 我越来越认识到一点,要么象那些废人一样废掉,要么自己去努力寻求出路,反正别指望从工作中得到什么高明的经验了(教训倒也许有)。期间发生了一些感情上的纠纷,严重的影响了学习计划和效果,直到现在浮躁的心仍然有些浮躁。
期间,我读了一些书,看了一些文章,编过一些小例程,搞了一些没有什么技术含量的开发工作,也和一些前辈和高手们谈过聊过。 我一直在思考几个问题;如何学习软件开发?如何搞软件开发,国外的软件开发到底其秘诀在何处?为何我们的软件业一直在低水平徘徊?我们难道真的离了Microsoft就活不了?我们的程序员到底在浪费时间干些什么?软件开发到底是如何分类的?我们如何走自己的民族软件之路?
我想了很久,一些想通了,一些还在想。但我知道有一点是肯定的,那就是我们一定要靠我们自己走出自己的软件之路!跟在别人屁股后面永远受制于人!
好了,关于经历和牢骚就先写这些吧,该进入我们的正题了。
(二) 你适合当程序员吗,你知道编程序是怎么回事吗?
1、 程序员意味着要编程序。(如果你仅仅想得到一份高薪水的工作,喝喝咖啡就等老板发薪水,我奉劝你还是另找一份更合适的工作,譬如练摊,真的,兄弟,这份工作不适合你)
2、你是学文的还是学理的,编程序也许需要浪漫,但更需要逻辑和严谨。(说坦白点就是,在你没有找到乐趣以前,它很枯燥)
3、你有对新技术追求的热情吗?你有刨根问底的探索精神吗?(热情绝对是最重要的!你仔细思考一下自己的性格适合当程序员吗?)
4、当程序员决不是什么好差事,时刻需要学习,需要思考。(直到你成为那个可以引导别人去学习和思考的人,你才可以偷偷的嘿嘿笑,又一群傻蛋)
5、程序员的未来很迷茫。(但我认为关键看你自己!我希望你是一个有追求的人,不仅仅是混碗饭吃。因为真正的乐趣在于创造;如果你能改变软件业的历史,那才是英雄;不想成为Bill Gates,不想成为Dennis Ritchie和 Bjarne Stroustrup,我会说你没有追求。有个关于程序员未来的笑话,也许你还没听过,你该听一听,摘抄如下:
一个程序员对自己的未来很迷茫,于是去问上帝。
“万能的上帝呀,请你告诉我,我的未来会怎样?”
上帝说“我的孩子,你去问Lippman,他现在领导的程序员的队伍可能是地球上最大的”
于是他去问Lippman。
Lippman说“程序员的未来就是驾驭程序员”
这个程序员对这个未来不满意,于是他又去问上帝。
“万能的上帝呀,请你告诉我,我的未来会怎样?”
上帝说“我的孩子,你去问Gates,他现在所拥有的财产可能是地球上最多的”
于是他去问Gates。
Gates说“程序员的未来就是榨取程序员”
这个程序员对这个未来不满意,于是他又去问上帝。
“万能的上帝呀,请你告诉我,我的未来会怎样?”
上帝说“我的孩子,你去问侯捷,他写的计算机书的读者可能是地球上最多的”
于是他去问侯捷。
侯捷说“程序员的未来就是诱惑程序员”
这个程序员对这个未来不满意,于是他又去问上帝。
“万能的上帝呀,请你告诉我,我的未来会怎样?”
上帝摇摇头“唉,我的孩子,你还是别当程序员了”)
6、当程序员还是很有乐趣的。(当你学到新知识时,当你有新的思想见解时,当你有新的产品问世时,和知己探讨你的成果时…我问你,觉得这些是乐趣吗?)
7、当程序员不易也不难。(世间事有难易乎?为之…;不为…。你有决心和信心吗?)
8、你真的要当程序员?是你自己的想法?
9、你舍得花钱买书吗?(读好书绝对是学习编程的最佳捷径。你一定会说,现在电脑书籍真T.M.D贵,没法子,谁让知识和技术在人家的脑袋,在人家的书里呢;等你写书时可以把价格定低一点,记着还有好多没钱但想买书的兄弟很困难呀。要舍得买书,买好书,不好的的书不如不读,其害大于其益,关于买什么书,你可以问高手或看候捷的书评;准备一个小本子记录你想买的书的名字,逛书店时看看,如果好就买下,记住要读,别光买不看。) 10、我告诉你,程序就是:任何有目的的、预想好的动作序列,它是一种软件。
11、编程序就是编写程序。
12、你想好了吗?(如果你想好了还是决定要当程序员,可以继续往下读;否则,你可以继续寻找别的出路了。)
(三) 一个程序员应该具备的基础知识和概念
1、计算机是有什么组成的,CPU是什么东西,其工作原理是什么。(对于这些以及下面将要提到的概念我不会告诉你什么答案,你可以看相应的教材,关于教材我会在下一部分详述,记住理解最重要!)
2、机器语言和微指令集的概念。
3、程序的概念。
4、汇编语言是低级语言但不是机器语言。
5、高级语言主要有那些?(C,C++,Basic,Pascal,Fortran,C#,Java等等;如果你是中国软件业的英雄,你也写一门语言,最好不用英语) 6、编译程序和解释程序的概念和其原理。(编译器是高手和专家编写的)
7、HTML、XML等是标识性语言。
8、Prolog是人工智能语言。
9、操作系统OS的概念和原理。(Windows98,Windows2000,Windows NT,UNIX,Linux,等等都是OS,还有一些实时OS,嵌入OS,编这些的绝对是高手)
10、Windows编程说白了就是Windows API的调用。(中国的程序员很多只是会编windows程序,用的是VB,我的建议是这些程序员顶多只是低级编码员,我称其是coder)
11、VC++、VB、BC、BCB、Delphi、VF等都只是编程的工具和环境,不是编程语言。
12、面向结构的设计概念。
13、面向对象的概念。(好好理解,兄弟,这个东西还是很重要的)
14、软件工程的概念和原理。(如果你想当老总就需要好好研究了,系统分析员比编码员要高一个等级,薪水也高哟)
15、数据库的概念。(要熟悉一些著名的数据库系统和语言的名字,如Orcle,SQL,DB2,DyBase等)
16、了解网络概念。
17、了解多媒体概念。
18、熟悉和掌握数据结构和基本算法。
19、是不是要求太高了,别着急慢慢来,进步在不知不觉之中。(一旦开始学习,一个月以后你就会有一个基本的概念;两个月以后你就会感觉自己有了全面的基础知识;当你知道编程序是怎么回事时,说明你已经入门了。也有很多人编了很多年程序还没有入门呢,你不会希望自己步其后尘吧。要有信心和耐心。沉不住气怎么能成大事?!)
(四) 教材推荐
――-推荐的教材主要还是针对概念来的,最好选用名校的教学用书。
1、《计算机组成原理》(熟悉)
2、《数据结构》(掌握)
3、《操作系统》(了解->熟悉)
4、《The C language》(掌握)
5、《编译原理》(了解原理)
6、《汇编语言》(了解)
7、《计算机网络》(了解)
8、《软件工程》(了解)
9、《关系数据库》(熟悉)
10、《The C++Languege 》(掌握)
11、《面向对象设计》(掌握;结合C++学习)
(五)一些经验和体会
1、真正的程序员用C++;(一位专家说的)
2、动手去编程序;
3、动脑去思考;
4、要有良好的编程风格;
5、读书,读好书,尽量读原版书!(我反复强调这一点,读书要有选择,坚持读好书,名家出的经典书,不要浪费实践在一些粗制滥造的书上面;坚持博览群书)
6、有自己的学习计划;
7、总结自己的经验教训;(准备一个笔记本,记录错误和心得)
8、不要怕学新东西;
9、要有软件工程的思想;
10、善于发现问题,然后去寻找答案;
11、向高手请教;(要虚心直到你成为高手)
12、和同行交流;(不善于交流肯定不行)
13、懂得软件的实质,不要被千变万化的表象所迷惑;
14、真正要学习用的是编程语言和方法,不是什么库,什么类,什么工具;(学用那些什么库都比较简单,但光会这些库,我觉得还远远不够)
15、学习wiodows编程主要是学习windows OS和win32 API;
16、有空了解一下嵌入式开发;
17、有空了解一下PDA软件开发;
18、了解一下.NET框架和C#语言,也许它是你新的衣食父母;
19、要有耐心,不要作浮躁的人; 20、对程序加注释,并保留你的老程序;
21、学到的东西越多,了解的越多,你就越接近专家;
22、有空去逛逛CSDN,那里有你很多知己;
23、要有信心成为一个优秀的程序;
(六)一些好书的推荐
1、《The C Programming language》 (Keinighan & Dennis Ritchie 1988)
2、《The C++ Programming Languague》(Bjarne Stroustrup 1997)
3、《Inside The C++ Object Model》 (lippmans)
4、《Effective C++》 (同上)
5、《More Effective C++》 (同上)
6、《Exceptional c++》
7、《C++面向对象高效编程》
8、《设计模式》
9、《Thinking In C++》
10、《The Standard C++ Bible》(一般推荐)
11、《The Art of Computer Programming 》
12、《Programming Windows》 (Charles Petzold)
13、《VC++5.0技术内幕》
14、《MFC 深入浅出》
15、《软件需求》
16、《Advanced Windows》
17、《C++ primer》
18、《win32程序员参考手册》
19、《用TCP/IP进行网际互连》
20、《COM 本质论》
(七)学习计划
――-这个学习计划是我个人定的,也共享给大家参考一下,共同进步吧。 1、《计算机组成原理》
2、《操作系统》
3、《数据结构》
4、《汇编语言》
5、《 C 》
6、《 C++ 》
7、《VC 技术内幕》
8、《Programming Windows》
9、《深入浅出MFC》
10、《Advanced Windows》
11、《Inside The C++ Object Model》
12、《Thinking in C++》
13、《Effective C++》
14、数据库
15、网络
16、嵌入式OS和编程
17、硬件单片机
18、.NET和C#
19、软件工程
20、UNIX和Linux
(八)后记
一年来浪费了大量的时间去摸索,去思考,走了很多的弯路,直到现在我还觉得自己是个编程的门外汉。我把我的一些体会和想法说出来(当然,很多都不一定正确,欢迎大家指正和讨论),也许对一些想加入程序员行列的朋友有一些建议和帮助。希望能帮助这些朋友顺利走上编程之路,成为高手。
如果真能如此,我也就很高兴了。欢迎有兴趣的朋友给我发E_mail(sjpsky@163.net);我这个人有两大业余爱好,其一就是读武侠小说,其二就是结交英雄侠士。
后记:此文我用analyster的名字登录,发表在“csdn-程序人生”上了,有很多网友看了,回了,还收到几个网友发来邮件,和我探讨,我很感谢大家对我的信任和鼓励。
我要说明的就是我的这篇小文,主要是想给“一些想成为程序员”的朋友一些建议,帮他们寻找一条自我培训的捷径,(其实世界上没有什么捷径的,我觉得一切都在于悟性,师傅领进门,修行在个人,譬如我就修行不够)少象我一样作大量的无用功。还有,主要就是一个程序员应该具备的基本功(个人看法),有人称其为“内功”,我觉得很对。没有扎实的基本功,我们如何能够做到游刃有余的编写高质量高性能的优秀程序呢?
让我们共同努力,振兴我们的民族软件业!