首先我想说的是,人各有志,不是每一个计算机专业出生的人以后都会去“编程”的,以前和我同寝室的同学,现在在编程的人只有两个,另外的六个有的去当公务员了,有的去类似银行、法院这样的地方做计算机维护什么的,还有一个改行了,现在在做“信贷”。所以你完全有别的选择,如果对编程没有兴趣,建议你还是去干点别的,因为没兴趣的话你坚持不下去的,就算硬着头皮去学,永远也只能跟在别人后面跑,很痛苦的。另外,考研其实是个不错的选择,只可惜要考“政治”和“英语”,不然我也去考了。:)
如果你是一名本科在校生的话,下面的文章就是为你写的;如果你刚刚开始工作不久,也希望下面的内容能对你有所帮助。。。。。。
一。关于计算机本科大学四年的各种必修课
我首先想说的是,并不是每一门必修课都是有用的,而且确实如此。
1。“显然没用”的课是:“大学物理”,这门课你只要做到能有60分就行了。“大学物理”我们是大一学的,由于高中带来的惯性,我学得很认真,可是现在回头来看,它是最没用的一门课,一点用都没有,当然,也许某某会说这是个“素质”问题,当然,如果你这么想的话也行,但是我觉得如果你不是对它十分的感兴趣的话,还是别在这上面花太多的时间,时间宝贵呀。
2。“更显然没用”的如:“XX革命史”、“XX品德”我也就不废话了。
3。“十分有用”的,它们是:“程序设计”、“数据结构”、“操作系统原理”。这三门课,我觉得是整个大学四年最有用的三门课了,而且是直接的有用。“程序设计”,在我们的课表上全称叫做“C++程序设计”,其实就是教会你使用一门高级语言,重要性不言而喻;而且学到后面,比如在学“编译原理”的时候,讲到各种词法分析方法时它就会用C++(我看的那本书用的是C++)来写一些例子,再接着讲,也就是说“程序设计”这门课同时也是用来学习后面很多的课程的工具。“数据结构”可以说是“编程整件事”要使用到的核心技术之一,必须要很好的理解、完全掌握这门课。“操作系统原理”包括了很多东西,都应该很好的掌握,比如“进程和线程”的基础知识如果你掌握的不好,那你以后编“多线程”程序的时候就会碰到很多麻烦;而且,只有理解了操作系统,才有可能编好应用软件,道理很简单,所用的应用软件都必须运行在操作系统之上,都必须调用它的功能。
对于这三门课,最好不要看国人写的教材。“操作系统原理”建议看《操作系统:设计与实现》(第二版),作者Anderw S.Tanenbaum等。此书中译本分上下两册,上册为原理,下册为Minix操作系统的源代码,上册必看,下册根据各人情况有选择的读一些也是好的。“数据结构”建议看《数据结构——C++语言描述》,作者William Ford等,但是裘宗燕的一本《数据结构——C++与面向对象的途径》也还行,如果你们学校用它做教材的话,那你勉强看看也就凑合了。至于“程序设计”,书太多了,《The C++ Programming Language》、《C++ Prime》、《Thinking In C++》、《Thinking In Java》都是好书。另外,说到这里,不得不提到一个问题:以前经常看到有人争论一个问题,就是C++、Java、(现在又多了一门C#)这三种语言到底哪种好?我们应该学习哪一种?这其实是一个无聊的争论,因为它们的80%都是相同的,所以你用“用来争论的这点时间”已经可以在“掌握它们其中之一”的前提下学完另外的两种了,等你精通了这三门语言后,也就不屑于这种争论了,语言本身只是表现思想的一种手段罢了,它们是何等的容易学习!
4。“有用”的课。这些课,不能算是“直接的有用”,也就是说,它们的很多内容你过几年也许就忘得差不多了,竟然也不会影响你当前的工作。但是,它们是铺垫,是基石。对于这些课,我们的态度应该是,注重基本概念,做到“弄清楚大致的框架”就可以了,但可以忽略不必要的细节(但也许考试的时候会考到一些细节,那你就自己看着办了)。。这些课是:“微机系统与汇编语言”、“计算机组成原理”、“计算机网络”、“软件工程”、“数据库原理”、“计算机接口原理”、“编译原理”、“计算方法”、“离散数学”。“汇编”还是有用的,它是你理解和学习“计算机组成原理”和“计算机接口原理”的钥匙。“计算机组成原理”和“计算机接口原理”其实是给你讲一遍计算机的硬件结构,比如CPU内部是怎么回事,它是怎么计算和缓存的,DMA传输方式是怎么样的等等,弄清楚(或者说曾经弄清楚过,毕竟它们的很多东西你以后会慢慢忘记的)这些东西心里会感觉比较有底。“计算机网络”感觉上和实际的网络编程联系不大,也是为你解释了一些原理性的东西,看了心理比较有底:)。另外“数据库原理”除了讲一些原理以外,一般还会教你SQL语法,其中最难的是各种“查询”语法了,但是到了实际用的时候你会发现,这些是不必要的,一般的“复杂查询语句”都有工具可以自动生成的,不用你自己写的,所以对此你不必担心。“软件工程”其实作为一个本科生来说是不可能很好的理解它的,它必须要有很多实践经验以后,才能体会其中的一些道理,而且国内的“软件工程”教材一般都比较“教条主义”,建议浏览一遍即可,知道个大概,了解一下大型软件的开发流程是怎么样的,就可以了(并且也是需要的),至于其中的诸多概念,重在理解,能理解多少就理解多少,千万不要去“背”,没有用的。“计算方法”这门课现在可以说是实用价值剧减,因为基本上所有的算法都有现成的程序库可以调用的,所以大概了解一下就行了,真到要自己开发算法的时候,不管你当时学得再好,肯定还要回过头来看这些书的,因为这之间你根本不曾使用过它们,早忘记了。至于“编译原理”有人认为它很重要,我认为做个了解,大致上知道是怎么回事就行了,因为你不太可能会去开发一个编译器,但是在实际中用到的机会也是有的,比如我有一次编程时就需要用到“编译原理”的知识来做一个“词法分析程序”,用来处理用户输入的函数表达式,再调用几个库函数来做定积分,但总的来说“编译原理”只对很有限的一部分程序的编写起到了实际的作用,所以,先了解一下,等到用时,再来细看。“离散数学”是前面提到的“数据结构”的理论基础,如果“离散数学”学得好,理解“数据结构”会更容易些,所以还是花点时间看看吧。
推荐一本书:《编译原理及实践》,作者Kenneth C.Louden,此书附录中有一份Tiny语言编译器的源代码,对照着前面的理论来看就不会像清华版的《编译原理》那样不知所云(我们当时用的就是这本教材,后来我去买了Kenneth C.Louden的《编译原理及实践》来看,很多问题才豁然开朗)。
另外,我想说的是,“软件工程学”其实现在才处在一个初级的发展阶段,CMM、XP等等的理论打得不可开交,各说各的理,几乎达到了互相对骂的程度。作为一个初学者,特别是“实践经验缺乏”的初学者,我建议你对各种理论多了解,注意我指的是“了解”,不是去“背”其中的条条框框,当你了解了大多数现在的主流软件工程思想以后,就会形成你自己的比较客观的思想了,当然还需要结合一些实践的经验,这是以后的事了。至于看哪些书,太多太多了,自己去找吧。
5。“不太有用”的。其实说这些课“不太有用”已经是客气的了,它们其中的一些其实就是“没用”。这些课是:“自动控制原理”、“通信原理”、“电路原理”、“数字电路原理”、“模拟电路原理”、“复变函数与积分变换”、“线性代数”、“概率论与数理统计”、“高等数学”。其中,“自动控制原理”和“通信原理”我感觉和实际的编程相差得实在是太远了,我学过它们可是现在全忘了,也不影响我现在的任何东西。“电路原理”、“数字电路原理”、“模拟电路原理”这三门课讲起来也是计算机学科的基础课,我只觉得“数字电路原理”对于理解比如“计算机组成原理”和“计算机接口原理”这样的课还有一些帮助,但是另两门课,我实在发现不了它们到底有用在哪里,比如“模拟电路原理”主要是教你“三极管的内部构造”之类的东西,如果你觉得这也属于“必须要掌握的东西”的话,那我也无话可说。另外,“复变函数与积分变换”是“数字图象处理”(这是一门研究生课程)的基础,如果以后想到Adobe去工作的人,还是应该趁早学好它们,但是除此以外,好像也是别无他用。“线性代数”、“概率论与数理统计”和“高等数学”我倒觉得是属于所谓的“素质”了,这些东西不懂好像就说不过去了,但是要懂到什么程度,各人自己看了。另,“高等数学”也是“复变函数与积分变换”的基础。
6。英语。这门课很特殊,很有用,总之一句话,现在学好了以后绝对不会后悔。:)
二。关于课外的学习
首先我想说的是,如果有志以后成为“优秀的程序员”的人,应该从大学就开始自己的“课外自学”了,这是很必要的,否则你会一开始就落在别人后面。另外,不要以为“所有的基础课都学得十分的好了”就可以“用比别人短得多的时间来学会各种实际的编程技术”。
(还有,我想说明的是,我只了解Windows编程,Linux我不懂。所以你以后如果立志于Linux领域的,我下面的文章对你不会有多少帮助)
1。主线。
作为“主线学习”。我建议这样进行:首先看这两本书:《Windows 程序设计》(第五版),作者Charles Petzold;《Windows 核心编程》(第四版) ,作者Jeffrey Richter;毫无疑问,此两本书必看!否则你永远也不可能成为一个专业的、高级的程序员(我指Windows程序员)。另,看《Windows 核心编程》以前需要有“操作系统原理”的基础。同时,如果学的是C++(在目前,C++在中国仍然是使用最广泛的编程语言),只看看你们的教材是肯定不够的,除了上面说的《The C++ Programming Language》等书(挑一本看就够了)以外,还应该看看《Effective C++ 中文版》,作者Scott Meyers。接下来,我建议你不要去学MFC了,它已经过时了,而且确实不太好用,我回想起当年学MFC的情景,总是觉得付出和得到不成正比。这时候可以去学“.NET”编程了,先学一下C#的语法(Tom Archer的《C#技术内幕》还算不错),你会发现它极容易,可以飞速的看完,因为你已经有了很好的C++基础了。然后再找一本比较全面介绍“.NET”的书看起,现在的话,我觉得《.NET 程序设计技术内幕》是个不错的选择,作者Jeff Prosise。我这里不是说学“.NET”就看这两本书就OK了,但是作为一个“学生”,能看到这里就不错了(当然你要是觉得还不够的话可以去看看Jeffrey Richter的《Applied Microsoft.NET Framework Programming》)。还有,在学习各种编程技术期间编一些自己的小程序是必不可少的,不然的话,你会学什么忘什么。最后,再有时间的话,学一学“设计模式”(它其实很重要的,而且慢慢的你会觉得它越来越重要),书蛮多,《设计模式》值得推荐(作者Erich Gramma等),它是“设计模式”类书籍的宗师,很不错的书,“设计模式”也是要一些实践经验作铺垫的,因此你可能不能完全的理解它。
2。支线。
作为支线,也就是说我觉得它们相对次要些。并且学习它们可以不分先后次序,但是,我还是建议先看完上面说的前三本书(《Windows 程序设计》、《Windows 核心编程》、《Effective C++ 中文版》)以后再来学下面的东西。
“Java”。。把“Java”作为支线一定会引起很多人的不满,或者说是愤慨,当然,你也可以把它作为主线来学,用来替代上面说的“.NET”。可是根据我自己的体会,“.NET”拥有更多的优势,如果你不同意我的观点,当然可以去学“Java”,没问题。但是作为一个“初学者”,我还是建议你两样都学一下,这样自己才能有比较,才能为自己的将来选择一条更适合自己的“技术路线”。另外,时间还是多的(主线中才提到了六本书),而且,我这里说的“学Java”只建议你看一本书:《Thinking in Java》,这本书可以说是入门的绝佳选择,至于以后怎么继续学习“Java”,可以去看看蔡学庸在CSDN上的专栏文章,里面讲得很详细了。
“网络编程”。。这个东西我想很多人都是比较向往的。我建议如果想做到对网络编程“比较精通”的话,应该去看看《Windows 网络编程技术》(第二版),作者Anthony Jones。这本书和上面讲的《Windows 程序设计》属于同一个技术层次,都是用“Windows API”直接编程,学这类东西的好处是能使你不仅“知其然”而且“知其所以然”。但是,如果立志要学“Java”的,也可以跳过这本书,直接看《Java Network Programming》,是O'Reilly的书,作者我忘记了。至于“.NET”方面,我还没发现专门讲网络编程讲得特别好的书,自己去找找吧。(其实一般的“.NET”书籍中已经有大量关于网络编程的内容了)
“COM”。。“以前的学习方法”是先看《深度探索C++ 对象模型》,作者Stanley B.Lippman;再看《COM 本质论》(作者Don Box)的前面两章,然后看《COM 原理与应用》(作者潘爱民),再回过头来看《COM 本质论》的后面部分。《COM 本质论》的前面两章讲得极好,它用最能让人理解的方式讲述了“什么是COM”,但这本书的后面部分比较晦涩,如果没有一点实际的“COM程序编写经验”,就很难理解了,所以我提到这里要插进来看一看潘爱民的《COM 原理与应用》。但是,这里有一个问题,《COM 原理与应用》里的应用部分使用的是MFC和ATL(抱歉我又提到了这些过时的东西,我只是对它们太熟悉了),我前面曾建议大家不要去学MFC了,于是产生了矛盾,请恕我无知,在当前的情况下,我不太能肯定要怎么学习“COM”才是最有效的,这里我确实不能给大家“更新的方法”了。但是现在随着“.NET”的推进,“COM”的生存空间似乎是越来越小了,因此“到底要把COM学到什么程度”也几乎成了“到时候看情况再说”的问题了。但是,我觉得无论如何了解一下“COM的基本思想”还是能带来莫大的好处,它太经典了!也就是我上面说的《COM 本质论》的前面两章。
“DDK”。。所谓“DDK”就是“设备驱动程序”,这属于一个相对冷僻的方面,但事实是“正因为它冷僻,所以这方面的技术人员的收入还是不错的”,但是“DDK”的知识对你学习别的很多东西(比如“.NET”、“Java”)都不会带来任何的帮助,它比较独立。所以我的建议是“在你还没有能力确定以后自己的专攻方向时,不要去学它”,因为它实在也不太好学。我对它只是略知一二,所以也只能说到这里就作罢了。不过可以给你推荐一本书:《Programming Microsoft Windows Driver Model》,(作者Walter Oney)。
好了好了,再下面就绝对要超出“初学者”的范畴了。其实学到这里,再加上你已经积累了一定的实际经验了,那下面再要学些什么,路要怎么走,就一定会有自己独立的想法了。我就不再废话了。
三。几个初学者要注意的问题
1。无论在学基础课的时候,还是在学实际的编程的时候,都是重在理解,千万不要死记硬背。比如上面说的“软件工程”就是最好的例子。有一次,我碰到两个人正在讨论MFC,“甲”说:“我觉得MFC真是复杂,这么多的类和方法,根本不知道怎么去学。”这时“乙”表示他也有同感,但是已经找到了学习的方法,于是“乙”很诚恳的对“甲”说:“其实有时候还是要背一些东西的,你可以去买一本中文版的MFC类库手册,天天背,天天记,慢慢的就好了。”。我当时从旁边走过,打了一个冷颤。。对于MFC这种东西,除了理解还要多用,很多东西自然就记住了,当然这么多的类和函数还是没能记住它们的确切名字和用法,但是别着急,你已经知道了有哪些类和方法大概是存在的,所以真到用的时候再到“MSDN”里去找呗,怕什么呢。
2。我前面提到了《Windows 程序设计》和《Windows 核心编程》这两本书是必看的,它们都是在介绍基于“Win32 SDK” 平台(或者说是接口)的编程,也就是用“Windows API”直接编程,这是一种十分底层的Windows编程方法。就今天来说,学习“Win32 SDK”编程的意义更大的在于“使你能够更彻底的理解基于它们之上的、包装得更好的、更易于使用和效率更高的各种技术,以便能更好的使用它们”,比如“MFC”、“.NET”等等。如果你一定要在实际的开发中也直接用“Windows API”来编程,无疑是自讨苦吃。因此,我们要鼓励使用各种开发效率更高的工具,当然,理解“Win32 SDK” 平台的编程能在你使用这些高级工具的时候给你带来巨大的好处。“网络编程”也是同理,我上面提到的那本《Windows 网络编程技术》也是基于Winsock(它是Win32 SDK的一部分)的书,实际编程的时候,你也许不太会直接去用它。
3。实践很重要。这个道理是很明显的,比如C++的语法,如果你不去用它的话,就算你当初能把整本书都背下来,到了大四的时候肯定也忘得差不多了。用的过程其实就是熟悉的过程,在用的时候可能会发现自己某一个细节怎么又想不起来了,没关系,正常的,再拿来书翻开看看,如此反复几次也就记住了。
4。坚持很重要。这里有一个前提,就是“你是真的对编程很有兴趣”,如果确实如此,那不用说你也会去不断的学习的。但如果不是这样,那就很糟糕了,就像我开头的时候提到的那个人,他就是“实在对编程没兴趣呀”,所以一直工作的很辛苦,感到身心疲惫,还总是落在别人后面,现在终于不得以该行去作“信贷”了。
5。关于“高级程序员”考试。这个考试其实是名不副实的,他分上午场和下午场,上午考一些基础概念,也就是上面提到的那些本科课程中比较重要的几门课,考试难度和形式都和你们的期末考试差不多,下午考编程,其实就和你们的“程序设计”期末考试最后的几道编程题差不多。一句话,考的是很理论的东西,死读书的人一般都能通过的:)。如果你了解到你以后要去应聘的公司对这张证书比较看重的话,那就花一些时间去复习一下以前的课程,去拿一张证书,像我的两个去当公务员的同学居然也都通过了这个考试。但是如果这张证书不是你就业的前提的话,我建议你不要在这上面花时间了,因为它太简单了,对提高你的实际水平没有帮助的。当然这只是我的个人观点,没有蔑视这项考试的意思。
6。也许你的志向是当一个“技术总监”,或是“XX主管”之类的,也就是所谓的“不写代码的人”,当然,很多人都这么想。但是,请记住,这些人其实都有着很好的实际编程经验,如果没有这段经历和积累,他们根本就到达不了现在的境界,也不能服众。所以,趁早多学一些“技术”是很必要的。
7。最后我想提醒各位,虽然至此你可能已经觉得自己“学识满腹”了,但是千万不要以为自己懂的多了,就开始自以为是,开始看不起别人了。我曾经有幸听过“钱能”老师的课,他给我印象最深的一句话就是:“你越学就应该越是觉得自己无知啊,怎么这么多东西自己都不懂呢?所以要谦虚啊,要谦虚啊,千万不能学了一点点东西就自认为了不起了。”(这是他在课堂上的原话。。。)