----(转帖)----------------------------------------------------------------------
现在让我们开始我的正文吧。首先,我来完成这篇文章的第一个目标:介绍并评价当前主流技术。我指的今天的主流技术是:
*程序设计语言:C++/Delphi(本来应该是ObjectPascal,但为了简单,我就语言和工具混为一谈吧)/Java/C#(虽然他刚刚推出,但因为微软为之倾注了大量心血,一定会成为一种重要的开发语言)
*桌面应用程序框架:MFC/VCL
*企业应用程序框架:WindowsDNA/J2EE/.Net
*COM技术:我单独提出这项技术,是因为它无法简单的被视为语言、桌面应用程序框架或企业应用程序框架,它与这些都有关系。
2.1 程序设计语言
2.1.1 C++语言的演进
最初要从二进制代码和汇编说起,但那太遥远了。我们就从面向过程的语言说起吧(包括Basic/C/Fortran/Pascal)。这种面向过程的高级语言终于把计算机带入了寻常的应用领域。其中的C语言因为它的简单和灵活造就了Unix和Windows这样的伟大的软件。
面向对象的语言是计算机语言的一个合乎逻辑的进化,因为在没有过多的影响效率、简单性的前提下提供了一种更好的组织数据的方法,可使程序更容易理解,更容易管理——这一点可能会引出不同意见,但事实胜于雄辩,C++终于让C语言的领地越来越小,当今还活着的计算机语言或多或少的都具备面向对象的特征,所以这一点并不会引起太多困惑。C++的成功很大程度要归因于C,C++成为它今天的样子是合乎逻辑的产物。因为在面向过程的时代,C几乎已经统一天下了。今天著名的语言象Java/C#都从C借鉴了很多东西,C#本来的意思就是C++++。其实C++曾经很有理由统一面向对象程序设计语言的天下来着,但可惜的是,C++太复杂了。即使是一个熟练的程序员,要你很清楚的解释一些问题你也会很头痛。举几个还不是那么复杂的例子来说:
对=的重载/成员转换函数/拷贝构造函数/转化构造函数之间有什么区别和联系呢?
定义一个类成员函数private:virtualvoidMemFun()=0;是什么意义呢?
int(*(*x(int))[4])(double);是什么意思?
还有其他的特征,比如说可以用来制造一种新语言的typedef和宏(虽然宏不是C++的一部分,但它与C++的关系实在太密切了),让你一不小心就摔跤的内存问题(只要new和delete就可以了吗?有没有考虑一个对象存放在容器中的情况?)……诸如此类,C++是如此的复杂以至于要学会它就需要很长的时间,而且你会发现即使你用C++已经好几年了,你还会发现经常有新东西可学。你想解决一个应用领域的问题——比如说从数据库里面查询数据、更改数据那样的问题,可是你却需要首先为C++头痛一阵子才可以,是的,你精通C++,你可以很容易的回答我的问题,可是你有没有想过你付出了多大的代价呢?我不是想过分的谴责C++,我本人喜欢C++,我甚至建议一个认真的开发普通的应用系统的程序员也去学习一下C++,C++中的一些特性,比如说指针运算/模板/STL几乎让人爱不释手,宏可以用几个字符代替很多代码,对系统级的程序员来说,C++的地位是不可替代的,Java的虚拟机就是C++写的。C++还将继续存在而且有旺盛的生命力。
2.1.2 Java和C#
Java和C#相对于C++的不同最大的有两点:第一点是他们运行在一个虚拟环境之中,第二点是语法简单。对于开发人员而言,在语法和语言机制的角度可以把Java和C#视为同一种语言。C#更多的是个政治的产物而不是技术产物。如果不是Sun为难微软的话,我想微软不会费尽心力推出一个和Java差不多的C++++,记得Visual J++吗,记得WFC吗?看看那些东西就会知道微软为Java曾经倾注了多少心血。而且从更广泛的角度来说,两者也是非常相似的——C#和Java面对的是同样的问题,面向应用领域的问题:事务处理、远程访问、Webservice、Web页面发布、图形界面。那么在这一段中,我暂且用Java这个名字指代Java和C#两种语言——尽管两者在细节上确实有区别。Java是适合解决应用领域的问题的语言。最大的原因Java对于使用者来说非常简单。想想你学会并且能够使用Java需要多长时间,学会并且能够使用C++要多长时间。由于Java很大程度上屏蔽了内存管理问题,而且没有那么多为了微小的性能提升定义的特殊的内容(比如说,在Java里面没有virtual这个关键字,Java也不允许你直接在栈上创建对象,Java明确的区分bool和整型变量),他让你尽量一致的方式操作所有的东西,除了基本数据类型,所有的东西都是对象,你必须通过引用来操作他们;除了这些之外,Java还提供了丰富的类库帮助你解决应用问题——因为它是面向应用的语言,它为你提供了多线程标准、JDBC标准、GUI标准,而这些标准在C++中是不存在的,因为C++并不是直接面向解决应用问题的用户,有人试图在C++中加入这些内容,但并不成功,因为C++本身太复杂了,用这种复杂的语言来实现这种复杂的应用程序框架本身就是一件艰难的事情,稍后我们会提到这种尝试——COM技术。渐渐的,人们不会再用C++开发应用领域的软件,象MFC/QT/COM这一类的东西最终也将退出历史舞台。
2.1.3 Delphi
Delphi是从用C++开发应用系统转向用Java开发应用系统的一个中间产物。它比C++简单,简单的几乎象Java一样,因为它的简单,定义和使用丰富的类库成为可能,而且Delphi也这么做了,结果就是VCL和其他的组件库。而另一方面,它又比运行于虚拟环境的Java效率要高一些,这样在简单性和效率的平衡之中,Delphi找到了自己的生存空间。而且预计在未来的一段时间之内,这个生存空间将仍然是存在的。可以明显的看出,微软放弃了这个领域,他专注于两方面:系统语言C++和未来的Java(其实是.Net)。也许这对于Borland来说,是一件很幸运的事情。如果我能够给Borland提一些建议的话,那就是不要把Delphi弄得越来越复杂,如果那样,就是把自己的用户赶到了C++或Java的领地。在虚拟机没有最终占领所有的应用程序开发领域之前,Delphi和Delphi的用户仍然会生存得很好。
2.2 桌面应用程序框架
目前真正成功的桌面应用程序框架只有两个,一个是MFC,一个是VCL,还有一些其他的,但事实上并未进入应用领域。遗憾的是我对两个桌面应用程序框架都不精通。但这不妨碍我对他做出正确的评价。
2.2.1 MFC
MFC(还有曾经的OWL)是SDK编程的正常演化的结果,就象是C++是C的演化结果一样。MFC本身是一件了不起但不那么成功的作品,而且它过时了。这就是我的结论。MFC凝聚了很多天才的智慧——当然,OWL和VCL也一样,侯捷的《深入浅出MFC》把这些智慧摆在了我们的面前。但是这件东西用起来估计不会有人觉得很舒服,如果你一直在用Java、VB或者Delphi,再回过头来用MFC,不舒服的感觉会更加强烈。我不能够解释MFC为什么没有能够最终发展成和VCL一样简单好用的桌面程序框架,也许是微软没精力或者没动力,总之MFC就是那个样子了,而且也不会再有发展,它已经被抛弃了。我有时候想,也许基于C++这种复杂的语言开发MFC这样的东西本身就是错误的——可以开发这样的一个框架,但不应当要求使用它的人熟悉了整个框架之后才能够使用这个系统,但很显然,如果你不了解MFC的内部机制,是不太可能把它用好的,我不能解释清楚为什么会出现这种现象。
2.2.2 VCL
相比之下VCL要成功的得多。我相信很多使用VCL的人可能没有像MFC的用户研究MFC那样费劲的研究过VCL的内部机制。但这不妨碍他们开发出好用好看的应用程序,这就足够了,还有什么好说的呢?VCL给你提供了一种简单一致的机制,让你可以写出复杂的应用程序。在李维的Borland故事那篇文章中曾经说过,在Borland C++ 3.1推出之后Borland就有人提出开发类似C++ Builder一类的软件,后来竟未成行。是啊,如果C++ Builder是在那个时候出现的,今天的软件开发领域将会是怎么样的世界呢?真的不能想象。也许再过一段时间,这些都将不再重要。因为新生的语言如Java和C#都提供了类似于VCL的桌面应用程序框架。那个时候,加上Java和C#本身的简单性,如果他们的速度有足够块,连Delphi这种语言也要消失了,还有什么好争论的呢?只是对于今天的桌面程序开发人员来说,VCL确实是最好的选择。
2.3 企业应用程序框架
2.3.1 Windows DNA
Windows DNA的起源无从探究了。随着.Net的推出,事实上Windows DNA将成为历史的陈迹。Windows DNA虽然是几乎所有的企业应用程序开发人员都知道的一个名词,但我相信Windows DNA事实上应用的最广泛的是ASP而不是COM+。真正的COM开发有多少人真正的掌握了呢,更不要提COM+(我有必要解释一下:COM+是COM的执行环境,它提供了一系列如事务处理、安全等基础服务,让应用程序开发人员尽量少在基础架构设计上花精力)——当然我这里指的COM开发不是指VB下的COM开发,所以要这么说,是因为我觉得如果不能理解用C++进行COM开发,也就不能真正的理解COM技术。如果以一种技术没有被广泛理解和应用作为失败的标志,那么Windows DNA实际上是失败了,但这不是它本身的错,而是基于C++的COM技术的失败造成的。多层应用、系统开发角色分离的概念依然没有过时。
2.3.2 J2EE
J2EE是第一套成功的企业应用程序开发框架。因为它把事务处理、远程访问、安全这些概念带入了寻常百姓家。这种成功我认为要归因于Java的简单性。Java的简单,对于J2EE容器供应商来说一样重要。开发一个基于Java的应用服务器要比基于C++的更容易。而且由于Java的简单性,应用系统开发者出错的机会也会少一些,不会像C++的开发者那样受到那么多挫折。开发基于Java的企业应用系统的周期会更短,这恐怕是不容争辩的事实。不论如何,是J2EE让事务处理、远程访问、安全这些原来几乎都是用在金融系统中的概念也被一般的企业用户使用并从中获得利益。
2.3.3 .NET
.Net有什么好说的呢?其实,它不过是微软的J2EE。事务处理、安全、远程访问,这些概念在.Net中都找得到。更有力的说明是,微软也利用了.Net实现了一个PetStore。所以,.Net与J2EE几乎是可以完全对等的。但微软确实是一家值得尊敬的公司——我指从技术上,象Web form这种东西,我相信很多Web应用开发者都梦想过甚至自己实现过,但Sun却一直无动于衷,而且似乎Borland也没有为此作过太多努力,好像有过类似的东西,但肯定是不怎么成功——Borland已经很让人敬佩了,我们也许无法要求太多。
2.4 COM技术
COM应当是个更广泛的词汇,其实我觉得Axtive X、OLE、Auto mation、COM+都应当提及,因为如果你不理解COM,上面的东西你是无法理解的。而且,我只是想说明COM是一种即将消亡的技术,仅仅说说COM的复杂性和他的问题就够了,所以不会提及那些东西。为什么会出现COM技术?COM的根本目标是实现代码的对象化的二进制重用,进而实现软件的组件化、软件开发工作的分工。这要求他做到两点:第一,能够跨越不同的语言,第二,要跨越同一种语言的不同编译器。COM技术为这个目标付出了沉重的代价,尤其是为了跨越不同的编译器,以至于无论对于使用者而言还是开发者而言,他都是一个痛苦的技术。但幸运的事,这一切终归要结束了。
让我们从这个目的出发看看COM为什么会成为它现在的样子。其实COM不是什么新玩意,最初的DLL就是重用二进制代码的技术。DLL在C的年代可能还不错,但到了C++的年代就不行了。原因在于如果你在.h文件中改变了类定义(增加或者减少了成员变量),代码库用户的代码必须重新编译才可以,否则用户的代码会按你的旧类的结构为你的新类分配内存,这将产生什么后果可想而知。这就是为什么通过接口继承和通过接口操作对象成为COM的强制规范的原因,能够通过对象的方式组织代码是COM的重要努力。那么著名的IUnknown接口又是怎么回事呢?这是为了让使用不同编译器的C++开发人员能够共享劳动成果。
首先看QueryInterface,因为COM是基于接口的,那么一个类可能实现了几个接口,而对于用户来说,你又只能通过操作接口来操作类,这样你必须把类造型成某个特定的接口,使用Dynamic_cast吗?不行,因为这是编译器相关的,那么,就只好把它放在类的实现代码中了,这就是QueryInterface的由来。至于AddRef和Release,他们产生的第一个原因是delete这个操作要求一个类具有虚析构函数(否则的话,他的父类的析构函数将不会被调用),但不幸的是不同的编译器中析构函数在vtbl中的位置并不相同,这就是说你不能让用户直接调用delete,那么你的COM对象必须提供自己删除自己的方法;另外的原因在于一个COM对象可能作为几个接口在被用户同时使用,如果用户粗暴的删掉了某个接口,那么其他的接口也就不能用了,这样,只好要求用户在想用一个接口的时候通过AddRef通知COM对象“我要使用你了,你多了一个用户”,而在不用之后要调用Release告诉COM对象“我不用你了,你少了一个用户”,如果COM对象发现自己没有用户了,它就把自己删掉。
再看看诡异的HRESULT,这是跨语言和跨编译器的代价。其实,异常处理是物竞天择的结果——连一直用效率作标榜的C++都肯牺牲效率来实现这个try-catch,可见它的意义,但COM为了照顾那些低级的语言居然抛弃了这个特征——产生的结果就是HRESULT。我们可以看看他是多么愚蠢的东西。首先,我们要通过一个整数来传递错误信息,通过IErrorInfo来查找真正的错误描述,本来在现代语言中一个try-catch可以解决的问题,现在我们却需要让用户和开发者都走很多路才能解决,你怎么评价这个结果?其次,由于这个返回计算结果的位置被占用了,我们不得不用怪异的out参数来返回结果。想想一个简单的int add(intop1,intop2)在COM中竟然要变成HRESULT add(intop1,intop2,int* result),我不知道你对此作何感想。而且由于COM的方法无法返回一个对象而只能返回一个指针,为了完成一个简单的std::string GetName()这一类的操作,你要费多少周折——你需要先分配一块内存空间,然后在COM实现中把一个字符串拷贝到这个空间,用完了你要删掉这个空间,不知道你是否觉得这种工作很幸福,反正我觉得很痛苦。还有COM为了照顾那些解释性的语言,又加入了Automation技术,你有没有为此觉得痛苦?本来一个简单的方法调用,现在却需要传给你一个标志变量,然后让你根据这个标志变量去执行相应的操作。(这一点我现在仍然不明白,为什么解释性的语言需要通过这个方式来执行一个方法)。“我受够了,我觉得头痛”,你会说,是啊,我想所有的人都受够了,所有这些因素实际上是把COM技术变成了一头让人无法驾驭的怪兽。
人对复杂事物的掌控能力终究是有限的,C++本身已经够复杂了,COM的复杂性已经超出了我们大部分人的控制能力,你需要忍受种种痛苦得到的东西与你付出的代价相比是不是太不值得了?我们学习是为了解决问题,而现在我们却需要为了学习这件事情本身耗费太多的精力。这些痛苦的东西太多了,我在这里说到的,其实只是一小部分而已。计算机技术是为人类服务的,而不是少数人的游戏(我想COM技术可能是他的设计者和一部分技术作者的游戏),难道我们愿意成为计算机的奴隶吗?通过一种过于复杂的技术抛弃所有的人其实等于被所有的人抛弃,这么多年中选择J2EE的人我相信不乏高手,你是不是因为COM的过于复杂才选择J2EE的?因为它可以用简单的途径实现差不多的目标——软件的“二进制”重用、组件化、专业分工(容器开发商和应用开发商的分工)。事实上,你是被微软所抛弃的,同时,你也抛弃了微软。
现在让我们回来吧,我把你带进了COM的迷宫,现在让我把你领回来。再让我们看看COM到底想实现什么目标,其实很简单,不过是代码的二进制重用,也就是说你不必给别人源代码,而且你的组件可以象计算机硬件那样“即插即用”。我们回过头来看看Java,其实,这种二进制重用的困难是C++所带来的(这不是C++本身的错,而是静态编译的错),当Java出现的时候,很多问题已经不存在了。你不需要一个头文件,因为Java的字节码是自解释的,它说明了自己是什么样子的,可以做什么事情。不像C++那样需要一个头文件来解释这些事情;也不需要事先了解对象的内存结构,因为内存是在运行的时候才分配的。如果我们现在再回过头来解决COM要解决的问题,你会怎么做呢?首先你会不再选择C++这种语言来实现代码的“二进制”重用,其次,你会把所有的语言编译成同样的“二进制”代码(实际上,应当说是字节码),这显然是更聪明的做法,从前COM试图在源代码的级别抹平二进制层次的差异,这实际上是让人在做本来应当由机器做的事情,很愚蠢是吗?但他们一直做了那么多年,而且把这个痛苦带给了整个计算机世界——因为他们掌握着事实的标准,为了用户,为了利润,为了能够在Windows上运行,尽管你知道你在做着一个很不聪明的事情,但你还是做了。
COM技术为了照顾VB这个小兄弟和实现统一二进制世界的野心,实在浪费了太多的精力。首先,落后的东西的消亡是必然的,就象C、Pascal在应用领域的消亡一样,Basic一点一点的改良运动是不符合历史潮流的做法,先进的东西和落后的东西在一起,要么先进的东西被落后的东西拖住后腿,要么是同化落后的东西,显然我们更愿意看见后者,现在Basic终于被现代的计算机语言同化了。其次,统一二进制世界好像不是那么简单的事情,而且也没什么必要,微软的COM技术奋战了10年,现在也只有他自己和Borland支持,.Net终于放弃了这个野心。这一切终于要结束了。
过去J2EE高歌猛进地占领着应用开发的领地,COM在这种进攻面前多少显得苍白无力。现在微软终于也有了可以和J2EE一较长短的.NET,对于开发人员来讲,基于字节码的组件的二进制重用现在是天经地义的事情;你不用再为了能够以类方式发布组件做那么多乱七八糟的事情,因为现在所有的东西本来就是类了;实现软件开发的分工也很自然,你是专业人员,就用C#吧,你是应用开发人员,你喜欢用VB.Net,你就用吧,反正你们写的东西最终都被翻译成了一样的语言(其实我觉得这一点意义不大,因为一些不那么好用的语言被淘汰是正常的事情,C风格成为程序设计语言的主流风格,肯定是有它的原因的,语言的统一其实是大势所趋,就象中国人民都要说普通话一样,我觉得Java不支持多语言算不上缺点——本来就是一种很好看很好用的语言了,为什么要把简单问题复杂化呢?)。COM不会在短期内死去,因为我估计微软还不会马上用C#开发Office和Windows的图形界面部分,但我相信COM技术退出历史舞台的日子已经不远了,作为一般的开发人员,忘了这段不愉快的历史吧——你将不会在你的世界里直接和COM打交道。若干年以后,我想COM也许会成为一场笑话,用来讽刺那种野心过大、钻牛角尖的愚蠢的聪明人。
结论
说了很多,应该是有个结论的时候了。我似乎做了一件冒天下之大不韪的事情,因为我评价了主流技术,还要试图进行比较,好像某个名人说过:“C++ Builder也好,Visual C++也好,能在市场上立足,肯定都是有自己的过人之处的,而且一个人精通数种开发语言、数种开发工具是不可能的事情”,言下之意就是说你不要对这些东西妄加评论,但怎么可以不评论?好像高手都不屑于说哪种语言好、哪种语言坏,我不知道什么时候形成了这种风气。简单地说C++比Java好或者Java比C++好显然是愚蠢的行为,但如果让你用Java写驱动程序,用C++开发一个MIS系统是不是愚蠢的行为呢?显然更愚蠢。我想,作为一个独立的能思考的人,外界的东西对你而言总是有好有坏,而且你的生命有限,你还要享受你的生活,所以你必须做出选择。所以,起码评价这些东西对我自己而言是正确的——只要我有能力评价,那我就说出我的评价吧。
对于计算机语言来说,未来真正重要的语言只有三种C++、Java和C#。C++将更适合于专业的计算机公司编写图形界面系统(比如KDE)、虚拟机(比如Java虚拟机或者.Net运行环境)、杀毒软件或者其他的盒装软件(比如说Photoshop、Dreamweaver)这一类的东西。而且C++适合程序员做学习之用,能对C++有一定理解的程序员往往也应该能更深刻的理解Java、C#,这有助于编写更好的软件。如果是开发为客户定制的应用系统Java、C#是更好的选择。包括桌面应用和Web应用。
至于其他的语言比如VB.Net其实并没有太大的意义。Delphi在未来一段时间将继续存在,而且活得不错。最重要的原因在于,第一它有一套丰富的组件库,第二它效率相对算高的,第三它简单。如果虚拟机的执行效率赶不上Delphi,它就有存在的理由,但从过去的Visual J++来看,微软的虚拟机做得确实可以很好,加上.Net的组件库和C#的简单性并不差,所以从长远来看Delphi可能不那么乐观。
其实上面的比较也包含了桌面应用程序框架的比较。在现在来说VCL无疑最好的,MFC已经退出历史舞台。.Net中所带的桌面应用程序框架将最终统一桌面应用领域(但不包括微软和Borland这样的专业公司,因为他们要作出最好用而且效率最高的软件)。至于Java中所带的桌面应用程序框架,实在让人哭笑不得。这个结论的变数是.Net运行环境的执行效率。如果.Net中的虚拟机象Java的一样,那微软就倒霉了,它等于放弃了桌面应用开发工具领域,但根据微软在Visual J++上的成就和他推广.Net的背水一战的驾式,.Net在桌面领域失败的可能性不大(但不是没有,起码基于COM的技术在企业应用领域几乎可以说是全军覆没)。
在企业应用程序框架领域,最终只有J2EE和.Net可以决一雌雄。我没有提到CORBA,它也可以算是企业应用程序框架,但他的声势和J2EE或者.NET实在不能同日而语,而且最重要的是只有Borland一家大公司支持它(SUN、IBM、BEA、Borland支持J2EE,微软就不用说了),所以就不详细说他了。那么最终谁会赢呢?我想微软赢的可能性大一些。这样说可能让很多人不快,而且IBM的厉害也是有目共睹的。但这并不是纯技术问题,就象Windows NT蚕食Unix的领土那样,那时候微软也是孤军作战。J2EE的问题在于第一:混乱,第二,价高。我相信很多人都对这两点有过不快的经历。你知道写给Weblogic的应用程序不是很顺利地就可以移植到Websphere上的,反过来也一样。但.Net就不一样了,那是微软一个人的作品,根本不存在移植的问题。
如果J2EE阵营不想败在这一点上,有三个办法,第一种就是通过制定统一的标准彻底消灭移植问题,第二种是开发一种好用的部署工具(不能象JBuilder那么大、那么慢:),屏蔽不同的应用程序容器之间的区别,第三种,也是最不可能的,就是J2EE阵营有人能够一统天下。显然,这三种解决办法都不太现实。第二点价高,这是SUN、IBM、BEA、ORACLE传统,也是它们一直让微软的进攻屡屡得手的软肋。我一直不太能明白他们的西就为什么那么贵。这样想一想:微软的.Net SDK白送给你,BEA的Web logic一个CPU的License两万,如果你两种技术都会,如果你给客户的系统报价一样,你选哪种开发技术?这一点实在让人觉得无可奈何。J2EE有的东西,.Net也有(除了不能跨平台),技术上的细微差别在巨大的价格差异面前还有什么意义呢?当然,SUM、IBM这些大公司也不是等闲之辈。就象Windows NT没有消灭Unix一样,J2EE应当会像Windows NT和Unix的共存一样和.Net共存,只是我想.Net恐怕会占上风。
闲话
说完了该说的技术问题,说说闲话吧。有的话放在心里觉得不说出来不舒服,且让我一吐为快:)
给入门程序员的建议
不知道我在学计算机的时候是不是走了弯路。但我想如果让我重新开始学写程序的话,我会采用一些不同的办法。如果你也正在想成为一个程序员,这些也许会对你有帮助。我觉得可能大概要分几个阶段,第一个阶段应该是找一门简单的语言入门,比如Java或者C#都应该比较合适,选一本简单的带例子的书(最好不要太厚),按部就班的把书学完。这时候可能还有些懵懵懂懂,但没关系,可以开始做个小小的软件了,重要的事你要自己用那种语言的方式想思考,如果有项目做,当然更好。之后,你会觉得有点感觉了。如果你象我一样不是科班出身的,接下来应当补习一下计算机专业的课程,我觉得最重要的是数据结构——那些东西你可能永远都不会自己做,C++中有漂亮的STL,Java中也为你实现了大部分东西,但我觉得真的有必要学习那些内容,这会加强你用计算机语言思考问题的能力。在进一步,如果你的入门语言不是C++,那你可以补习一下C++,尽管你可能永远都不会用C++开发程序。C++在现在的计算机世界就象是普通话一样,而且它能让你很容易的理解其他语言中难以理解的问题。学完了C++,那你应当就已经不是一个初级程序员了,欢迎你进入计算机软件开发的世界。
印度的软件业
我记得好像在CSDN上看见过一篇文章,极力的鼓吹印度的软件业。而且我记得他好像说过一句很刻薄的话“我们公司那些B大的和T大的,一个一个特别牛,牛得看不见人……做起界面极尽奇迹淫巧之能事……”,诸如此类,总之认为程序员只有象印度的高中生那样乖乖的、懂得UML、会看Function Specification才算是真正的程序员。我当时觉得很不舒服。我想这个人应该不是B或T大的——哦,别误会,我也不是——但我觉得好像B大的T大的人没象他说的那样。而且我不明白为什么中国的软件业为什么一定要向印度看齐?作为一家公司,你想获取商业利润,学习印度无可厚非,你大可以找一大堆高中生培训成编程蓝领(我没有轻视高中生的意思,我相信有很多“高中生”在技术领域取得的成就是让我望尘莫及的),但你不应该因此就把有血有肉有个性的程序员扁得一钱不值。说实话,所谓的编程蓝领不过是工厂里面的装配工,如果有一天工厂里面换了自动化的设备,这些人就全成了废人!而你要知道并不是这些装配工发明了自动化机器。我想这种话用不着多说,子曰“过犹不及”,你可以喜欢变成蓝领,但不要把问题推向极端,把问题推向极端往往就会犯错误。我们中国可以在某种程度上学习印度,但好像我们更应该学习美国——只是我们现在没那么富裕——可是微软也不是从一开始就是这样一个伟大的帝国的,IBM也一样
--------------------------------------------------------------------------------
(看完了该帖,个人心中感慨万分,眺望未来,“大道至简”乃王者之道
现在让我们开始我的正文吧。首先,我来完成这篇文章的第一个目标:介绍并评价当前主流技术。我指的今天的主流技术是:
*程序设计语言:C++/Delphi(本来应该是ObjectPascal,但为了简单,我就语言和工具混为一谈吧)/Java/C#(虽然他刚刚推出,但因为微软为之倾注了大量心血,一定会成为一种重要的开发语言)
*桌面应用程序框架:MFC/VCL
*企业应用程序框架:WindowsDNA/J2EE/.Net
*COM技术:我单独提出这项技术,是因为它无法简单的被视为语言、桌面应用程序框架或企业应用程序框架,它与这些都有关系。
2.1 程序设计语言
2.1.1 C++语言的演进
最初要从二进制代码和汇编说起,但那太遥远了。我们就从面向过程的语言说起吧(包括Basic/C/Fortran/Pascal)。这种面向过程的高级语言终于把计算机带入了寻常的应用领域。其中的C语言因为它的简单和灵活造就了Unix和Windows这样的伟大的软件。
面向对象的语言是计算机语言的一个合乎逻辑的进化,因为在没有过多的影响效率、简单性的前提下提供了一种更好的组织数据的方法,可使程序更容易理解,更容易管理——这一点可能会引出不同意见,但事实胜于雄辩,C++终于让C语言的领地越来越小,当今还活着的计算机语言或多或少的都具备面向对象的特征,所以这一点并不会引起太多困惑。C++的成功很大程度要归因于C,C++成为它今天的样子是合乎逻辑的产物。因为在面向过程的时代,C几乎已经统一天下了。今天著名的语言象Java/C#都从C借鉴了很多东西,C#本来的意思就是C++++。其实C++曾经很有理由统一面向对象程序设计语言的天下来着,但可惜的是,C++太复杂了。即使是一个熟练的程序员,要你很清楚的解释一些问题你也会很头痛。举几个还不是那么复杂的例子来说:
对=的重载/成员转换函数/拷贝构造函数/转化构造函数之间有什么区别和联系呢?
定义一个类成员函数private:virtualvoidMemFun()=0;是什么意义呢?
int(*(*x(int))[4])(double);是什么意思?
还有其他的特征,比如说可以用来制造一种新语言的typedef和宏(虽然宏不是C++的一部分,但它与C++的关系实在太密切了),让你一不小心就摔跤的内存问题(只要new和delete就可以了吗?有没有考虑一个对象存放在容器中的情况?)……诸如此类,C++是如此的复杂以至于要学会它就需要很长的时间,而且你会发现即使你用C++已经好几年了,你还会发现经常有新东西可学。你想解决一个应用领域的问题——比如说从数据库里面查询数据、更改数据那样的问题,可是你却需要首先为C++头痛一阵子才可以,是的,你精通C++,你可以很容易的回答我的问题,可是你有没有想过你付出了多大的代价呢?我不是想过分的谴责C++,我本人喜欢C++,我甚至建议一个认真的开发普通的应用系统的程序员也去学习一下C++,C++中的一些特性,比如说指针运算/模板/STL几乎让人爱不释手,宏可以用几个字符代替很多代码,对系统级的程序员来说,C++的地位是不可替代的,Java的虚拟机就是C++写的。C++还将继续存在而且有旺盛的生命力。
2.1.2 Java和C#
Java和C#相对于C++的不同最大的有两点:第一点是他们运行在一个虚拟环境之中,第二点是语法简单。对于开发人员而言,在语法和语言机制的角度可以把Java和C#视为同一种语言。C#更多的是个政治的产物而不是技术产物。如果不是Sun为难微软的话,我想微软不会费尽心力推出一个和Java差不多的C++++,记得Visual J++吗,记得WFC吗?看看那些东西就会知道微软为Java曾经倾注了多少心血。而且从更广泛的角度来说,两者也是非常相似的——C#和Java面对的是同样的问题,面向应用领域的问题:事务处理、远程访问、Webservice、Web页面发布、图形界面。那么在这一段中,我暂且用Java这个名字指代Java和C#两种语言——尽管两者在细节上确实有区别。Java是适合解决应用领域的问题的语言。最大的原因Java对于使用者来说非常简单。想想你学会并且能够使用Java需要多长时间,学会并且能够使用C++要多长时间。由于Java很大程度上屏蔽了内存管理问题,而且没有那么多为了微小的性能提升定义的特殊的内容(比如说,在Java里面没有virtual这个关键字,Java也不允许你直接在栈上创建对象,Java明确的区分bool和整型变量),他让你尽量一致的方式操作所有的东西,除了基本数据类型,所有的东西都是对象,你必须通过引用来操作他们;除了这些之外,Java还提供了丰富的类库帮助你解决应用问题——因为它是面向应用的语言,它为你提供了多线程标准、JDBC标准、GUI标准,而这些标准在C++中是不存在的,因为C++并不是直接面向解决应用问题的用户,有人试图在C++中加入这些内容,但并不成功,因为C++本身太复杂了,用这种复杂的语言来实现这种复杂的应用程序框架本身就是一件艰难的事情,稍后我们会提到这种尝试——COM技术。渐渐的,人们不会再用C++开发应用领域的软件,象MFC/QT/COM这一类的东西最终也将退出历史舞台。
2.1.3 Delphi
Delphi是从用C++开发应用系统转向用Java开发应用系统的一个中间产物。它比C++简单,简单的几乎象Java一样,因为它的简单,定义和使用丰富的类库成为可能,而且Delphi也这么做了,结果就是VCL和其他的组件库。而另一方面,它又比运行于虚拟环境的Java效率要高一些,这样在简单性和效率的平衡之中,Delphi找到了自己的生存空间。而且预计在未来的一段时间之内,这个生存空间将仍然是存在的。可以明显的看出,微软放弃了这个领域,他专注于两方面:系统语言C++和未来的Java(其实是.Net)。也许这对于Borland来说,是一件很幸运的事情。如果我能够给Borland提一些建议的话,那就是不要把Delphi弄得越来越复杂,如果那样,就是把自己的用户赶到了C++或Java的领地。在虚拟机没有最终占领所有的应用程序开发领域之前,Delphi和Delphi的用户仍然会生存得很好。
2.2 桌面应用程序框架
目前真正成功的桌面应用程序框架只有两个,一个是MFC,一个是VCL,还有一些其他的,但事实上并未进入应用领域。遗憾的是我对两个桌面应用程序框架都不精通。但这不妨碍我对他做出正确的评价。
2.2.1 MFC
MFC(还有曾经的OWL)是SDK编程的正常演化的结果,就象是C++是C的演化结果一样。MFC本身是一件了不起但不那么成功的作品,而且它过时了。这就是我的结论。MFC凝聚了很多天才的智慧——当然,OWL和VCL也一样,侯捷的《深入浅出MFC》把这些智慧摆在了我们的面前。但是这件东西用起来估计不会有人觉得很舒服,如果你一直在用Java、VB或者Delphi,再回过头来用MFC,不舒服的感觉会更加强烈。我不能够解释MFC为什么没有能够最终发展成和VCL一样简单好用的桌面程序框架,也许是微软没精力或者没动力,总之MFC就是那个样子了,而且也不会再有发展,它已经被抛弃了。我有时候想,也许基于C++这种复杂的语言开发MFC这样的东西本身就是错误的——可以开发这样的一个框架,但不应当要求使用它的人熟悉了整个框架之后才能够使用这个系统,但很显然,如果你不了解MFC的内部机制,是不太可能把它用好的,我不能解释清楚为什么会出现这种现象。
2.2.2 VCL
相比之下VCL要成功的得多。我相信很多使用VCL的人可能没有像MFC的用户研究MFC那样费劲的研究过VCL的内部机制。但这不妨碍他们开发出好用好看的应用程序,这就足够了,还有什么好说的呢?VCL给你提供了一种简单一致的机制,让你可以写出复杂的应用程序。在李维的Borland故事那篇文章中曾经说过,在Borland C++ 3.1推出之后Borland就有人提出开发类似C++ Builder一类的软件,后来竟未成行。是啊,如果C++ Builder是在那个时候出现的,今天的软件开发领域将会是怎么样的世界呢?真的不能想象。也许再过一段时间,这些都将不再重要。因为新生的语言如Java和C#都提供了类似于VCL的桌面应用程序框架。那个时候,加上Java和C#本身的简单性,如果他们的速度有足够块,连Delphi这种语言也要消失了,还有什么好争论的呢?只是对于今天的桌面程序开发人员来说,VCL确实是最好的选择。
2.3 企业应用程序框架
2.3.1 Windows DNA
Windows DNA的起源无从探究了。随着.Net的推出,事实上Windows DNA将成为历史的陈迹。Windows DNA虽然是几乎所有的企业应用程序开发人员都知道的一个名词,但我相信Windows DNA事实上应用的最广泛的是ASP而不是COM+。真正的COM开发有多少人真正的掌握了呢,更不要提COM+(我有必要解释一下:COM+是COM的执行环境,它提供了一系列如事务处理、安全等基础服务,让应用程序开发人员尽量少在基础架构设计上花精力)——当然我这里指的COM开发不是指VB下的COM开发,所以要这么说,是因为我觉得如果不能理解用C++进行COM开发,也就不能真正的理解COM技术。如果以一种技术没有被广泛理解和应用作为失败的标志,那么Windows DNA实际上是失败了,但这不是它本身的错,而是基于C++的COM技术的失败造成的。多层应用、系统开发角色分离的概念依然没有过时。
2.3.2 J2EE
J2EE是第一套成功的企业应用程序开发框架。因为它把事务处理、远程访问、安全这些概念带入了寻常百姓家。这种成功我认为要归因于Java的简单性。Java的简单,对于J2EE容器供应商来说一样重要。开发一个基于Java的应用服务器要比基于C++的更容易。而且由于Java的简单性,应用系统开发者出错的机会也会少一些,不会像C++的开发者那样受到那么多挫折。开发基于Java的企业应用系统的周期会更短,这恐怕是不容争辩的事实。不论如何,是J2EE让事务处理、远程访问、安全这些原来几乎都是用在金融系统中的概念也被一般的企业用户使用并从中获得利益。
2.3.3 .NET
.Net有什么好说的呢?其实,它不过是微软的J2EE。事务处理、安全、远程访问,这些概念在.Net中都找得到。更有力的说明是,微软也利用了.Net实现了一个PetStore。所以,.Net与J2EE几乎是可以完全对等的。但微软确实是一家值得尊敬的公司——我指从技术上,象Web form这种东西,我相信很多Web应用开发者都梦想过甚至自己实现过,但Sun却一直无动于衷,而且似乎Borland也没有为此作过太多努力,好像有过类似的东西,但肯定是不怎么成功——Borland已经很让人敬佩了,我们也许无法要求太多。
2.4 COM技术
COM应当是个更广泛的词汇,其实我觉得Axtive X、OLE、Auto mation、COM+都应当提及,因为如果你不理解COM,上面的东西你是无法理解的。而且,我只是想说明COM是一种即将消亡的技术,仅仅说说COM的复杂性和他的问题就够了,所以不会提及那些东西。为什么会出现COM技术?COM的根本目标是实现代码的对象化的二进制重用,进而实现软件的组件化、软件开发工作的分工。这要求他做到两点:第一,能够跨越不同的语言,第二,要跨越同一种语言的不同编译器。COM技术为这个目标付出了沉重的代价,尤其是为了跨越不同的编译器,以至于无论对于使用者而言还是开发者而言,他都是一个痛苦的技术。但幸运的事,这一切终归要结束了。
让我们从这个目的出发看看COM为什么会成为它现在的样子。其实COM不是什么新玩意,最初的DLL就是重用二进制代码的技术。DLL在C的年代可能还不错,但到了C++的年代就不行了。原因在于如果你在.h文件中改变了类定义(增加或者减少了成员变量),代码库用户的代码必须重新编译才可以,否则用户的代码会按你的旧类的结构为你的新类分配内存,这将产生什么后果可想而知。这就是为什么通过接口继承和通过接口操作对象成为COM的强制规范的原因,能够通过对象的方式组织代码是COM的重要努力。那么著名的IUnknown接口又是怎么回事呢?这是为了让使用不同编译器的C++开发人员能够共享劳动成果。
首先看QueryInterface,因为COM是基于接口的,那么一个类可能实现了几个接口,而对于用户来说,你又只能通过操作接口来操作类,这样你必须把类造型成某个特定的接口,使用Dynamic_cast吗?不行,因为这是编译器相关的,那么,就只好把它放在类的实现代码中了,这就是QueryInterface的由来。至于AddRef和Release,他们产生的第一个原因是delete这个操作要求一个类具有虚析构函数(否则的话,他的父类的析构函数将不会被调用),但不幸的是不同的编译器中析构函数在vtbl中的位置并不相同,这就是说你不能让用户直接调用delete,那么你的COM对象必须提供自己删除自己的方法;另外的原因在于一个COM对象可能作为几个接口在被用户同时使用,如果用户粗暴的删掉了某个接口,那么其他的接口也就不能用了,这样,只好要求用户在想用一个接口的时候通过AddRef通知COM对象“我要使用你了,你多了一个用户”,而在不用之后要调用Release告诉COM对象“我不用你了,你少了一个用户”,如果COM对象发现自己没有用户了,它就把自己删掉。
再看看诡异的HRESULT,这是跨语言和跨编译器的代价。其实,异常处理是物竞天择的结果——连一直用效率作标榜的C++都肯牺牲效率来实现这个try-catch,可见它的意义,但COM为了照顾那些低级的语言居然抛弃了这个特征——产生的结果就是HRESULT。我们可以看看他是多么愚蠢的东西。首先,我们要通过一个整数来传递错误信息,通过IErrorInfo来查找真正的错误描述,本来在现代语言中一个try-catch可以解决的问题,现在我们却需要让用户和开发者都走很多路才能解决,你怎么评价这个结果?其次,由于这个返回计算结果的位置被占用了,我们不得不用怪异的out参数来返回结果。想想一个简单的int add(intop1,intop2)在COM中竟然要变成HRESULT add(intop1,intop2,int* result),我不知道你对此作何感想。而且由于COM的方法无法返回一个对象而只能返回一个指针,为了完成一个简单的std::string GetName()这一类的操作,你要费多少周折——你需要先分配一块内存空间,然后在COM实现中把一个字符串拷贝到这个空间,用完了你要删掉这个空间,不知道你是否觉得这种工作很幸福,反正我觉得很痛苦。还有COM为了照顾那些解释性的语言,又加入了Automation技术,你有没有为此觉得痛苦?本来一个简单的方法调用,现在却需要传给你一个标志变量,然后让你根据这个标志变量去执行相应的操作。(这一点我现在仍然不明白,为什么解释性的语言需要通过这个方式来执行一个方法)。“我受够了,我觉得头痛”,你会说,是啊,我想所有的人都受够了,所有这些因素实际上是把COM技术变成了一头让人无法驾驭的怪兽。
人对复杂事物的掌控能力终究是有限的,C++本身已经够复杂了,COM的复杂性已经超出了我们大部分人的控制能力,你需要忍受种种痛苦得到的东西与你付出的代价相比是不是太不值得了?我们学习是为了解决问题,而现在我们却需要为了学习这件事情本身耗费太多的精力。这些痛苦的东西太多了,我在这里说到的,其实只是一小部分而已。计算机技术是为人类服务的,而不是少数人的游戏(我想COM技术可能是他的设计者和一部分技术作者的游戏),难道我们愿意成为计算机的奴隶吗?通过一种过于复杂的技术抛弃所有的人其实等于被所有的人抛弃,这么多年中选择J2EE的人我相信不乏高手,你是不是因为COM的过于复杂才选择J2EE的?因为它可以用简单的途径实现差不多的目标——软件的“二进制”重用、组件化、专业分工(容器开发商和应用开发商的分工)。事实上,你是被微软所抛弃的,同时,你也抛弃了微软。
现在让我们回来吧,我把你带进了COM的迷宫,现在让我把你领回来。再让我们看看COM到底想实现什么目标,其实很简单,不过是代码的二进制重用,也就是说你不必给别人源代码,而且你的组件可以象计算机硬件那样“即插即用”。我们回过头来看看Java,其实,这种二进制重用的困难是C++所带来的(这不是C++本身的错,而是静态编译的错),当Java出现的时候,很多问题已经不存在了。你不需要一个头文件,因为Java的字节码是自解释的,它说明了自己是什么样子的,可以做什么事情。不像C++那样需要一个头文件来解释这些事情;也不需要事先了解对象的内存结构,因为内存是在运行的时候才分配的。如果我们现在再回过头来解决COM要解决的问题,你会怎么做呢?首先你会不再选择C++这种语言来实现代码的“二进制”重用,其次,你会把所有的语言编译成同样的“二进制”代码(实际上,应当说是字节码),这显然是更聪明的做法,从前COM试图在源代码的级别抹平二进制层次的差异,这实际上是让人在做本来应当由机器做的事情,很愚蠢是吗?但他们一直做了那么多年,而且把这个痛苦带给了整个计算机世界——因为他们掌握着事实的标准,为了用户,为了利润,为了能够在Windows上运行,尽管你知道你在做着一个很不聪明的事情,但你还是做了。
COM技术为了照顾VB这个小兄弟和实现统一二进制世界的野心,实在浪费了太多的精力。首先,落后的东西的消亡是必然的,就象C、Pascal在应用领域的消亡一样,Basic一点一点的改良运动是不符合历史潮流的做法,先进的东西和落后的东西在一起,要么先进的东西被落后的东西拖住后腿,要么是同化落后的东西,显然我们更愿意看见后者,现在Basic终于被现代的计算机语言同化了。其次,统一二进制世界好像不是那么简单的事情,而且也没什么必要,微软的COM技术奋战了10年,现在也只有他自己和Borland支持,.Net终于放弃了这个野心。这一切终于要结束了。
过去J2EE高歌猛进地占领着应用开发的领地,COM在这种进攻面前多少显得苍白无力。现在微软终于也有了可以和J2EE一较长短的.NET,对于开发人员来讲,基于字节码的组件的二进制重用现在是天经地义的事情;你不用再为了能够以类方式发布组件做那么多乱七八糟的事情,因为现在所有的东西本来就是类了;实现软件开发的分工也很自然,你是专业人员,就用C#吧,你是应用开发人员,你喜欢用VB.Net,你就用吧,反正你们写的东西最终都被翻译成了一样的语言(其实我觉得这一点意义不大,因为一些不那么好用的语言被淘汰是正常的事情,C风格成为程序设计语言的主流风格,肯定是有它的原因的,语言的统一其实是大势所趋,就象中国人民都要说普通话一样,我觉得Java不支持多语言算不上缺点——本来就是一种很好看很好用的语言了,为什么要把简单问题复杂化呢?)。COM不会在短期内死去,因为我估计微软还不会马上用C#开发Office和Windows的图形界面部分,但我相信COM技术退出历史舞台的日子已经不远了,作为一般的开发人员,忘了这段不愉快的历史吧——你将不会在你的世界里直接和COM打交道。若干年以后,我想COM也许会成为一场笑话,用来讽刺那种野心过大、钻牛角尖的愚蠢的聪明人。
结论
说了很多,应该是有个结论的时候了。我似乎做了一件冒天下之大不韪的事情,因为我评价了主流技术,还要试图进行比较,好像某个名人说过:“C++ Builder也好,Visual C++也好,能在市场上立足,肯定都是有自己的过人之处的,而且一个人精通数种开发语言、数种开发工具是不可能的事情”,言下之意就是说你不要对这些东西妄加评论,但怎么可以不评论?好像高手都不屑于说哪种语言好、哪种语言坏,我不知道什么时候形成了这种风气。简单地说C++比Java好或者Java比C++好显然是愚蠢的行为,但如果让你用Java写驱动程序,用C++开发一个MIS系统是不是愚蠢的行为呢?显然更愚蠢。我想,作为一个独立的能思考的人,外界的东西对你而言总是有好有坏,而且你的生命有限,你还要享受你的生活,所以你必须做出选择。所以,起码评价这些东西对我自己而言是正确的——只要我有能力评价,那我就说出我的评价吧。
对于计算机语言来说,未来真正重要的语言只有三种C++、Java和C#。C++将更适合于专业的计算机公司编写图形界面系统(比如KDE)、虚拟机(比如Java虚拟机或者.Net运行环境)、杀毒软件或者其他的盒装软件(比如说Photoshop、Dreamweaver)这一类的东西。而且C++适合程序员做学习之用,能对C++有一定理解的程序员往往也应该能更深刻的理解Java、C#,这有助于编写更好的软件。如果是开发为客户定制的应用系统Java、C#是更好的选择。包括桌面应用和Web应用。
至于其他的语言比如VB.Net其实并没有太大的意义。Delphi在未来一段时间将继续存在,而且活得不错。最重要的原因在于,第一它有一套丰富的组件库,第二它效率相对算高的,第三它简单。如果虚拟机的执行效率赶不上Delphi,它就有存在的理由,但从过去的Visual J++来看,微软的虚拟机做得确实可以很好,加上.Net的组件库和C#的简单性并不差,所以从长远来看Delphi可能不那么乐观。
其实上面的比较也包含了桌面应用程序框架的比较。在现在来说VCL无疑最好的,MFC已经退出历史舞台。.Net中所带的桌面应用程序框架将最终统一桌面应用领域(但不包括微软和Borland这样的专业公司,因为他们要作出最好用而且效率最高的软件)。至于Java中所带的桌面应用程序框架,实在让人哭笑不得。这个结论的变数是.Net运行环境的执行效率。如果.Net中的虚拟机象Java的一样,那微软就倒霉了,它等于放弃了桌面应用开发工具领域,但根据微软在Visual J++上的成就和他推广.Net的背水一战的驾式,.Net在桌面领域失败的可能性不大(但不是没有,起码基于COM的技术在企业应用领域几乎可以说是全军覆没)。
在企业应用程序框架领域,最终只有J2EE和.Net可以决一雌雄。我没有提到CORBA,它也可以算是企业应用程序框架,但他的声势和J2EE或者.NET实在不能同日而语,而且最重要的是只有Borland一家大公司支持它(SUN、IBM、BEA、Borland支持J2EE,微软就不用说了),所以就不详细说他了。那么最终谁会赢呢?我想微软赢的可能性大一些。这样说可能让很多人不快,而且IBM的厉害也是有目共睹的。但这并不是纯技术问题,就象Windows NT蚕食Unix的领土那样,那时候微软也是孤军作战。J2EE的问题在于第一:混乱,第二,价高。我相信很多人都对这两点有过不快的经历。你知道写给Weblogic的应用程序不是很顺利地就可以移植到Websphere上的,反过来也一样。但.Net就不一样了,那是微软一个人的作品,根本不存在移植的问题。
如果J2EE阵营不想败在这一点上,有三个办法,第一种就是通过制定统一的标准彻底消灭移植问题,第二种是开发一种好用的部署工具(不能象JBuilder那么大、那么慢:),屏蔽不同的应用程序容器之间的区别,第三种,也是最不可能的,就是J2EE阵营有人能够一统天下。显然,这三种解决办法都不太现实。第二点价高,这是SUN、IBM、BEA、ORACLE传统,也是它们一直让微软的进攻屡屡得手的软肋。我一直不太能明白他们的西就为什么那么贵。这样想一想:微软的.Net SDK白送给你,BEA的Web logic一个CPU的License两万,如果你两种技术都会,如果你给客户的系统报价一样,你选哪种开发技术?这一点实在让人觉得无可奈何。J2EE有的东西,.Net也有(除了不能跨平台),技术上的细微差别在巨大的价格差异面前还有什么意义呢?当然,SUM、IBM这些大公司也不是等闲之辈。就象Windows NT没有消灭Unix一样,J2EE应当会像Windows NT和Unix的共存一样和.Net共存,只是我想.Net恐怕会占上风。
闲话
说完了该说的技术问题,说说闲话吧。有的话放在心里觉得不说出来不舒服,且让我一吐为快:)
给入门程序员的建议
不知道我在学计算机的时候是不是走了弯路。但我想如果让我重新开始学写程序的话,我会采用一些不同的办法。如果你也正在想成为一个程序员,这些也许会对你有帮助。我觉得可能大概要分几个阶段,第一个阶段应该是找一门简单的语言入门,比如Java或者C#都应该比较合适,选一本简单的带例子的书(最好不要太厚),按部就班的把书学完。这时候可能还有些懵懵懂懂,但没关系,可以开始做个小小的软件了,重要的事你要自己用那种语言的方式想思考,如果有项目做,当然更好。之后,你会觉得有点感觉了。如果你象我一样不是科班出身的,接下来应当补习一下计算机专业的课程,我觉得最重要的是数据结构——那些东西你可能永远都不会自己做,C++中有漂亮的STL,Java中也为你实现了大部分东西,但我觉得真的有必要学习那些内容,这会加强你用计算机语言思考问题的能力。在进一步,如果你的入门语言不是C++,那你可以补习一下C++,尽管你可能永远都不会用C++开发程序。C++在现在的计算机世界就象是普通话一样,而且它能让你很容易的理解其他语言中难以理解的问题。学完了C++,那你应当就已经不是一个初级程序员了,欢迎你进入计算机软件开发的世界。
印度的软件业
我记得好像在CSDN上看见过一篇文章,极力的鼓吹印度的软件业。而且我记得他好像说过一句很刻薄的话“我们公司那些B大的和T大的,一个一个特别牛,牛得看不见人……做起界面极尽奇迹淫巧之能事……”,诸如此类,总之认为程序员只有象印度的高中生那样乖乖的、懂得UML、会看Function Specification才算是真正的程序员。我当时觉得很不舒服。我想这个人应该不是B或T大的——哦,别误会,我也不是——但我觉得好像B大的T大的人没象他说的那样。而且我不明白为什么中国的软件业为什么一定要向印度看齐?作为一家公司,你想获取商业利润,学习印度无可厚非,你大可以找一大堆高中生培训成编程蓝领(我没有轻视高中生的意思,我相信有很多“高中生”在技术领域取得的成就是让我望尘莫及的),但你不应该因此就把有血有肉有个性的程序员扁得一钱不值。说实话,所谓的编程蓝领不过是工厂里面的装配工,如果有一天工厂里面换了自动化的设备,这些人就全成了废人!而你要知道并不是这些装配工发明了自动化机器。我想这种话用不着多说,子曰“过犹不及”,你可以喜欢变成蓝领,但不要把问题推向极端,把问题推向极端往往就会犯错误。我们中国可以在某种程度上学习印度,但好像我们更应该学习美国——只是我们现在没那么富裕——可是微软也不是从一开始就是这样一个伟大的帝国的,IBM也一样
--------------------------------------------------------------------------------
(看完了该帖,个人心中感慨万分,眺望未来,“大道至简”乃王者之道