本科的课程回顾

Writely上的原文连接:
http://www.writely.com/View.aspx?docid=ajgpqkpbjrwz_bbj68w6npnrm3
http://www.writely.com/View.aspx?docid=ajgpqkpbjrwz_0cgcdhr(这篇是Stack写的)

————————————————————————————–

 

本科课程总结
Saki @ 2006-06-04

 
前言
本文尝试对本科的专业课程进行总结,希望能有所帮助——请原谅因为能力所限没有包含数学方面的课程(代数、离散、概率、可计算理论),偏硬件方面的课程(数字逻辑、微机原理、计算机组织与结构),还有就是没上过的课程,希望有人能补全这些东西。
上过的课方面,没有总结的是操作系统和数据库概论,这两门课是实在是掌握的太少,不足以给出什么建议(其实其它有些学的也不行,不过这两个比较明显,连废话都废不出来,呵呵)。
每门课介绍包含三部分内容,包括课程概述——对课程内容、实习和考试概要介绍;建议——这门课学习中的一些建议;补充——不在课程内容中但在本科阶段值得了解内容。三部分并不(也不可能)完全分离,比如课程概述中如果必要也会有一些建议。
因为我上课并不多,所以可能大部分建议的内容都是以自学为前提的。如果是关于上课的建议,我唯一体会的是对于用ppt(不用抄笔记)的课程应该预习,否则上课很难跟上老师的思路。另外对于很多课程去上课是有好处,而对于绝大多数课程自学也是足够的了。
文中所建议的书目大部分是我读过的,如果是没读过的推荐一般都会注明。
04级之后课程应该是有了一些调整(包括专业划分的时间),因为并不了解大部分课程如今的情况,所以还是按照02级的课程情况来叙述的。如果有任何不合时宜的东西尽可以指出来,我会努力做相应的调整。

 

计算概论
课程概述:课程是分两部分,首先是关于计算机(科学)的历史;然后是编程的基础——基于C语言。
这里首先可以肯定的是对于一个计算机专业的学生了解计算机历史是重要的。不过同样不值得怀疑的是计算机历史也还是历史,所以对于大部分大一新生这和单纯的历史是没有区别甚至是更加难以理解的。如果只是背诵的话,就很应该怀疑这里所花费精力的价值了(现在02级的,谁还记得大一计算概论期中考试时的内容呢?)假若能在大二下或者大三上有一门概括计算机历史(理论、软硬件等等)的课程那还是很好的。
编程基础是重要的,一直被很强调的是良好的编程风格的养成。我以为在这里最重要的是兴趣的培养,没有兴趣时做很多事是很痛苦的——不过现在大一还有次选专业的机会,所以还好一些。建议是如果对编程不感兴趣、不喜欢编程、讨厌编程的人,如果选择计算机专业还是要想清楚,因为虽然不能否定计算机理论科学的重要性,但是在我们系本科学习还是有大量的编程实践的。
不含任何贬低的说,C语言不是一门称职的入门语言——虽然它很cool,让不了解冯•诺依曼结构的学生把C语言当作入门语言来学实在有点险恶的意味,比如:不知道内存时指针这种东西常常带来太大的挫败感。如果间接导致在这里就养成对内容死记硬背的习惯,实在不是一件好事。假如你不是志在出国,尽量以学懂而不是高分为目的不失为一个好的建议,当然前提是我们系的保研形式一如既往的好。
期末包含需要写一个大程序,(就当时的水平来讲)有点复杂度。
期末考试,完全不记得了。
建议:虽然在课程中不大可能了解计算机历史,但是在今后一定应该在点滴中积累对计算机历史的认识,这个建议不限于这门课程的范围。Google是到06年初为止完成这个任务最好的工具。
如果有编程的基础(大概学过C、Pascal、QB之类的东东——规范的说法是学过一种命令式语言,写过千八百行程序),那么只是很保留地建议尝试从C++入手,不过这更是一门庞杂的语言了,对于面向对象思想的入门这几乎是主流中最差的选择了。我读过的书中推荐的C++入门读物是《Essential C++》——也并不太好。强烈不建议一开始就看大部头比如Thinking in C++、TCLP。
在没有明确的了解其意义的情况下,不建议在这门课里学习诸如MFC、VCL之类的界面Framework,把同样的精力放在STL中也许是更好的做法。对于大一学生,我认为一个结构优美、概念清晰的程序远比一个漂亮界面下的杂碎代码(我大一写的就是这种杂碎,当时我分不清CString和string的差别)值得欣赏得多。
补充:假如没有课程的限制,或者说不必要以C系语言开始实践。从很炫的角度,可以考虑从SICP(Structure and Interpretation of Computer Programs)这本书引入。Scheme作为一个混杂了命令式语言特性的Lisp方言,因为足够高的抽象程度(隐藏了很多底层细节)很适合初学者。而通过学习书中关于寄存器机器一章也可以对冯•诺依曼结构有一个大概的认识。
出于私心的角度,也推荐把Python作为一门入门语言(替换历史悠久的Pascal)。Python在一定程度上可以带来简单引发的兴趣。不过Python虽然不像C那么杂散,里面的语法糖对于newbie可能也太多了一点,加之教材稀缺。所以只是出于私心顺便一提。

程序设计实习
 课程概述:非典,这门课我上的不超过5节,所以关于课程内容可能所谈泛泛。
02级时大概的课程内容包括介绍了一些Win32编程、Windows APIs以及相关概念、面向对象的一些基本概念、用C++编写面向对象程序。课程包含比较多的编程实习。02级的实习比较有意义的包括使用Windows API写deltree;高精度计算程序;用基于一个简单压缩算法RLE实现压缩解压程序;写一个MyString类(面向对象封装)。
我印象里这门课讲得内容有点散乱,感觉郭炜熟悉什么就都讲了一些,像Win32编程之类的东西好像不怎么适合在这门课上讲的。现在这门课好像分了几个老师开,不知道具体情况是怎样的。不过从课程名来考虑,如果说计算概论给大家一个编程的感觉,程序设计实习实际上是尽可能地让你熟练地运用代码来描述自己的思想。所以建议尽早地能熟练编程(需要进行一定量实践),毕竟大学4年,如果去掉最后一年在1/3的地方熟练这么个基本功并不嫌早。
考试内容记不确凿,印象里有好多C++语法糖。
建议:这门课会包含一些比较重的实习(相对于当时的平均能力)——比如02级的压缩解压程序,而且大一下开始一般人也没了刚上大学时从高中继承来的认真态度(总体来说大学4年肯定是一年不如一年的),加上检查抄袭不很严格(相对与数据结构)。综上Ctrl-C,V别人程序的情况可能多一些。建议的原则是“明确自己的能力,尽可能的抄袭对自己提高性价比不合理的实习”,以下不再讨论关于Ctrl-C,V的问题了。
如果想系统学习C++(从中也可以了解面向对象的基本概念),建议阅读的书籍可在以下3本中择之:《Thinking in C++》(Vol1+Vol2)、《C++ Primer》、《The C++ Programming Language》。个人推荐TCPL。
如果想学Win32编程,建议阅读《Windows程序设计》——在此之前请确认清楚Win32编程的含义。出于但不限于了解Windows APIs的目的,学会使用MSDN是十分必要的。
如果想学MFC编程,保留性地建议按顺序阅读《Windows程序设计(上册)》的大部分章节、《深入浅出MFC》——在此之前请一定确认清楚MFC编程的含义。强烈不建议阅读《VC++技术内幕》,这本书更像一本包罗的条目参考,我怀疑初学者从这本书中总结出体系的可能性。
补充:如果自学能力很强,而且上这门课的主要目的在于学习C++语言,那么诚恳地建议在此之前了解Java——在此我无意做语言之争,如果有人很诚恳地想争执一下,那么建议去CSDN讨论区发表标题为“XX语言是垃圾”的帖子。
对于了解面向对象思想,Smalltalk可能是更好的起点——C++/Java/C#等等面向对象和命令式的hybrid语言可能会给初学者带来困扰,遗憾的是国内没有介绍Smalltalk的教材(在06年初china-pub上以Smalltalk作为关键字搜索结果为空,而且在可预见的将来这种情况不会改变),所以这只是极为参考性的建议(如果你在大学第一年中就可以通过阅读英文文献来学习一门没有接触过的编程范式的语言,那么我表示我的敬意)。

数据结构
课程概述:ms这门课现在也是好几个老师教了,不很清楚,所以我还按02级也就是张铭教的情况来讨论。
首先我一直没弄清楚这门课是数据结构还是编程实习,另外个人也很不喜欢这种很多功课的课程——表示出教师一种不信任的态度。不过可以肯定的是如果你在这门课后还没有对编程存在畏难情绪的话,那么就需要更加努力了。
关于这门课的重要性,我想说的是,个人认为算法和数据结构的重要性(至少在国内)被过分的强调了,原因可能是国内通过速成班培养出来的“程序员”很多——而且很可能只有对程序员来说算法和数据结构才是唯一重要的事。“程序=数据结构+算法”可能是被误读的一句话,“程序=数据结构+算法”只是从一个视角上看待程序而已。算法和数据结构很重要,但是还没重要到是唯一重要东西的地步。
实习,花哨的界面(特别是Win32出来的界面)对你自己的提高没什么用。
考试,其实这门课有点危言耸听的感觉,现实是好好付出,收获都不错(不过我怀疑区分度)。
建议:首先明确计算机工程师和计算机科学家的区别——区别并不代表某种比另一种很伟大,其次明确自己的理想,这将有助于你明晰算法和数据结构(其实更主要的是数学)对自己的重要程度,由此也可以知道自己应该如何学习这门课(或者说这方面的知识)。
无论如何应该熟练掌握所有的常用数据结构。
不会背诵所有常见(不常见)算法(比如快速排序)的实现细节是可以原谅的事情,某种程度上也是我们需要库的原因。但是知道所有常见算法的代价、适用等等特征,并且拥有快速搜索到它实现细节的能力是绝对必要的。
补充:虽然课程中的学期可能没有时间,但是强烈建议在今后通读《Introduction to Algorithms》,这本书将是一个深入的起点。其中学会证明一个算法的正确和分析算法的代价是非常必要的。
如果你发现自己的数学能力不足以帮助你完成算法代价的分析,那么可以使自己得到安慰的是,我相信国内这是很大多数的情况。
另外在你确定自己的能力之前,不要尝试阅读TAOCP。

编译原理
课程概述:孙家肃老师的课,讲课可能有点平淡。知识方面的建议觉得Stack后面讲编译实习的时候说的很清楚了,我就不在这里废话了。
提一下的是这门课的考试,从02年的试题上看考试只不过是把平时机器做的事让人来做一遍。各种词法语法分析的算法本质上是复杂的,但是记住并按步骤执行是很简单的。结论是这门课的考试(至少在02年)是很简单的。
建议:至少通读Dragon Book课程相关的章节。具体的看编译实习那部分吧
补充:也是看编译实习那部分吧,废话,呵呵

计算机网络概论
课程概述:首先概述了网络包括网络的分类、7层参考模型,而后自底向上讲述了计算机网络的协议栈,包括物理层、链路层(MAC层)、网络层——不包括传输层(含)以上的内容。
物理层的内容可能只是比较泛泛的了解,毕竟这部分更靠近通讯,也要了解是因为出于结合部。
除此之外的各层的,内容主要都是以算法和协议为主。建议深刻认识分层中每层的意义和目的。这样有助于理解每个算法和协议的意义和目的,使知识成为系统。毕竟这种本科生的课程就是一个概貌的认识,如果能系统化的话,对以后的深入很有帮助。
期末有一个实习,02级是在一个模拟器上实现802.3或802.11(实际上那个模拟器根本没用,如果不是起了反作用的话)。
考试,知识点很多很碎,而且没有更多的重点和非重点,几乎对于每个知识点出大题和小题的可能性都是差不多的。建议是早动手准备。
建议:强烈建议通读《计算机网络(第4版)》所有课程相关的章节。Tanenbaum的牛书,绝对是深入浅出,面面俱到、脉络清晰,也不难读,非常适合初学来对全局进行微浅的把握。(有趣的是Tanebaum和Silberschatz分别是《现代操作系统》和《操作系统概念》的作者)对于这本课程基本上是不在需要其他的参考书了。但如果确实存在难以理解的问题,那么沿着书里最后章节的阅读书目和参考文献检索,相信会有帮助。
补充:强烈建议通读《计算机网络(第4版)》全书。课程中不讲述的传输层、应用层同样非常重要,都是不可不看的内容。另外最后一部分关于网络安全,包括密码学的入门和一些常见的网络安全协议,可以帮助对信息安全有一个初步的认识。
鉴于TCP/IP的重要性,如果想详细了解之,推荐的书目包括《用TCP/IP进行网络互联》和《TCP/IP详解》,这里全部只建议阅读Vol1。而两本书的Vol2都是涉及实现TCP/IP的内容,可以根据自己的需要选择。两套书比较,个人推荐的是《用TCP/IP进行网络互联》。

面向对象技术引论
课程概述:因为麻志毅出国做访问学者(好像),所以是黄罡代课讲的一学期。02级的课程中分team做一个完整project(自由命题),而且花了很多课时让每个team在课上阐述自己的想法——不过这个只限于当年的情况不具备任何代表意义。
理论上讲这门课的主要内容应该包括OO的基本概念和OO的设计方法。
实际上OO除去概念外,其余的部分是很偏重实践的(OOAD),所以如果能通过一个项目来体会OO的感觉是很好的,但是在一门课里同时包含理论和实践怕是课时不够了。所以大概应该有一门OO实习的课程来补充。
考试可能要侧重概念,如果不建立在理解的基础上那就只能背了。
建议:因为任何一门讲述面向对象语言的书籍都会花费一些章节的阐述对象的基本概念相关的内容。所以对象的基本概念,实际上这门课只是起一个将概念系统化的作用。建议是在这门课之前已经(最好是熟练)掌握一门面向对象语言,如果没有做到这一点,请认真考虑是否选修这门课。
关于UML的入门读物,被广泛建议但是我没有读过的书是《UML Distilled》,不过这本书的中文版是我所看到过的遭受最猛烈抨击的译版(值得反思的是这本书是徐家福先生翻译的)——也是我还没读过这本书的原因。建议是如果想看的话先借来翻一翻以确定翻译的质量,另外如果不介意看电子版的话直接看电子版就可以了(截至第三版还没有影印版)。《UML用户指南》和《UML参考手册》并不是很好的教程但是作为参考资料备在手边是值得的,如果出于通过读这本书来学习UML的目的那么更推荐前者。
关于OOAD,建议以《UML和模式应用(第二版)》作为入门基础,这本书靠后的章节涉及到一些设计模式的概念,我在补充会讨论关于模式的内容。《统一开发过程》第二部分的章节详细阐述了UP中面向对象开发各个阶段的核心工作流,然而这本原书即被评价为艰涩——实际上很像一本手册,译本更甚之,所以只建议在有一点分析设计经验之后来读,或者作为上一本书的明细来参考。
关于UML工具,不介意使用日货的话(不过也有人说是中日合作的),推荐JUDE Community(https://www.esm.jp/jude-web/index.html),一个小巧但功能齐全的UML工具,而且到06年初为止还有免费的版本。
补充:强烈建议实践一个面向对象项目——最少也要完成需求、分析、设计三个步骤。
无论出于什么动机(学习、跟风)都强烈推荐阅读《设计模式:可复用面向对象软件的基础》。对于读这本书的建议是把握这本书的核心思想,而不是陷于对各种模式的记诵。个人观点是通过这本书足以了解Design Pattern的根本意图了,以后对于Pattern的学习都是为了解决特定的问题,所以并不特别建议与之配合的读物了。不过假如你发现很难理解这本书,那么下面两本书可能是有帮助的,《Head First Design Pattern》、《Design Patterns Explained》。

程序设计语言概论
 课程概述:从前是梅老板的课,不过到02级已经换成焦文品讲了,于是选这门课的价值就只在于课本身的价值了。
课程内容牵扯程序设计语言的所有方面,词法语法分析(编译原理中讲过,所以这里就只是泛泛谈之)、变量、语句、过程抽象、数据抽象、各种语言范型等等。这里内容广杂又相互牵扯,如果能在整体上宏观上有一个认识是很不错的。
02级期中交一篇论文,期末闭卷但考前告诉题目。
建议:虽然很多人反复说“语言只是工具”之类的话,而且这句话非常之对,但其实掌握多种编程语言应该是个基本功(说上面话的人如果不会多种语言的话,那么说这样的话大概是源于自卑)。我认为值得了解(不一定深入)的语言包括:Fortran、C(一个子集)、C++、Java、C#(尤其2.0/3.0)、Ruby(或Python)、Perl、Lisp(或某种方言)、Prolog(或XLST?)。
《Concepts of Programming Languages (5th Edition)》并不深入地介绍了语言的各个方面,很适合这门课。其中第二章依照时间先后介绍了十几种语言,很值得阅读。很可能与这本书类似(从目录来看,我没读过)的书有《Programming Languages: Concepts and Constructs,2e》、《Programming Languages:Principles and Practice》等等,从中择一读之应该也是好的选择——可以根据你的需要和Amazon的书评来选择。
补充:《程序设计语言——实践之路》比上述书籍更深入一些探讨了上述话题。但是也许不值得在这门课中投入如此多的精力来看这本书。
考察一门语言的具体实现也许是很值得的,如果要这么做,建议是选择一门简单语言入手——开源实现、语法简单、实现低效(意味着易理解,没有很多匪夷所思的优化)。

软件工程
课程概述:对软件工程做概貌性的阐述。主要内容包括过程简述、结构化方法、OO方法、CMM简述。
对学生来说软件工程过于抽象,大部分内容都是很有道理,但是不知道为什么有道理。这也和我们系的知识结构有关系。软件工程称之为工程,我们系缺乏系统工程相关课程的介绍。实际上将计算机科学和软件工程分列也许是更好的做法。
粗略掌握过程的知识是很必要的,但如果不是与(研究)工作紧密相关的话,背诵12207标准几乎没有任何意义。瀑布模型、迭代模型都是知识的结晶。
OO方法如果选修了OO的课程应该已经有一定掌握了。结构化方法,客观的说已经过时了,不过作为一种经典方法论来研究还有很高的价值,同时也有助于我们对于OO的认识。
CMM了解一下吧,记不住是正常的。
考试,06年为止,也只有结构化方法可能出大题;前面的概念其实大可不必背得很辛苦(这时候分数对大部分人都不重要了吧)。
建议:到大四上课,估计一般人也就没心思了,而且这种课对于大部分人都是临时背诵然后就忘记了,所以看教材就差不多够了。
保留性地建议阅读《软件工程——实践者的研究方法》作为参考。这也是一本大而全的教材,不过个人对其评价是远不如《计算机网络》和《数据库系统概念》的。可能也是软件工程知识远不如计算机网络成系统的,想在一本书中了解其全貌就不免有太泛泛之嫌,感觉整本书的脉络组织不好,甚至有点没有脉络的感觉。另外其中花了很多章节来阐述结构化方法,却仍然很难从中了解抽象的方法的含义,那么随着时间的推进,这部分就有点意义模糊了。
补充:将RUP作为一个实例,可能有助于这门课的学习,《RUP导论(第三版)》是一本短小精悍的读物,对掌握软件过程、软件开发模型、方法论的知识会有一定的帮助。更深入的了解,则尝试性地推荐阅读《统一软件过程》全书(OO课程只涉及核心工作流的章节),和OO课中的评价一样——手册一样的书,读起来会很艰涩。
想系统了解CMM的知识,推荐阅读《软件过程管理》。问题在于你能记住多少,把握体系应该是重要的。
出于时髦(05年前后)地推荐阅读敏捷开发的一些读物,可以把《敏捷软件开发:原则、模式与实践》第一部分的章节、《解析极限编程——拥抱变化》等书作为入门读物从中择而读之。(也会有助于编程实践)