如何在大学期间学好计算机科学

来源:互联网 发布:数据录入员兼职2016 编辑:程序博客网 时间:2024/04/29 14:51

匆匆忙忙,大学的4年就这么快要结束了。想当初是个连编程语言都只是停留在听说过的懵懂少年,现在就马上要走入职场了(今年的出国申请运气真是法克!!)。

进入软件工程专业学习,可以说很偶然,但是却又圆了自己小时候当程序员(其实是Game Designer……)的小梦想。鉴于自己在这4年里还是挺努力的,对于Computer Science(以下就简称CS啦)的本科学习也稍微有点自己的心得,故想在毕业前跟大家分享分享。

以下主要讲讲自己的经历,夹杂着自己的看法,大家对于文体什么的就不要太介意了。

 

认识计算机科学

其实自己读的是软件工程(下面就简称SE好了),在分类上算是CS的一个小分支,并且主要偏重的是工程方面,可能还会带点管理在里面,所以科学味可能并不是太重。

无独有偶,自己大学前两年干得也的确都是些SE里的事:写写代码,编个网站,顶多有个小小的CVS的代码管理经验。这个时期可能学到的比较多的是如何较好的和人交流,项目开发中的文档的重要性等等。对于科学方向的内容探究的比较少,顶多就是数据结构算法这些有自己看过书。

然而自己在大二下学期一个偶然的机会加入了RoboCup实验室,开始接触人工智能方面的知识,使自己有机会更多的接触到一些CS方面的内容。所以大学的后两年,还是有幸接触到了一下CS里面的一些经典方向和问题。

当然我不是说在这里说SE里面就没有CS,只是我这里的侧重点不一样而已。

其实我觉得目前学CS的很多人可能连CS里面的方向到底具体怎么分,又应该具体如何一个学习法(具体来说就是一个学习路线问题)都不是很了解。自己很幸运的在大一的时候曾经听过一个微软MVP金戈大虾讲过一些关于计算机的学习问题,接下来讲讲从学习路线来讲讲CS。

 

程序设计语言

实际上我们在初学CS的时候,都会有一个入门过程,在这个时候我们会学习程序设计语言。语言是你进入CS一个基础阶段,因为通过语言,我们可以真实的体验程序的运行过程,有了程序,我们又可以体验到操作系统是如何运作,网络是怎么进行数据交流。而在目前国内的大学里,主流的可能都是C系的语言(C/C++,JAVA),对于脚本语言的关注还不够。C系语言有其自身的优势,同时语法上对于传统的程序员来说也比较熟悉,但是对于刚入门的初学者来说,关注的细节太多了。目前MIT就已经开始采用Python作为入学新生的教学语言,之前也曾经教过Scheme。这两门语言是Peter Norvig(AI经典教材AI: A modern approach的作者之一,也是目前Google研究所的主任),推荐的入门程序语言。

首先Python具有语法上的强制缩进要求并且简洁,对于初学者有很强的指导作用(相比大家都有看见没有缩进的代码那种头痛的经历)。而Scheme是Lisp的一个分支,里面包含了很多到目前为止都非常先进的程序语言思想,如垃圾回收,函数式编程,闭包,lambda表达式等等。并且语言本身的语法非常简洁,非常的极小主义。并且这两种语言都是脚本语言,使用REPL的过程较之于编译过程对于初学者来说从使用体验上来说也是比较好。

OK,有点扯远了。总之对于程序设计语言,其实学哪门还不是最不是最重要的,重要是我们使用这门语言去写程序,锻炼自己的程序思维。在这个阶段不能只停留在记得语法的阶段,还要知道各种语法的应用场景,还有语言自带的特性的利弊,当然这个过程也很漫长,需要自己去锻炼。

在这里可以推荐大家看看Peter Norvig写的《Teach Yourself Programming in Ten Years》这篇文章。

数据结构与算法

记得自己是在CS系某大牛的引领下开始看《算法导论》,从而掉进这个大坑的。(至今仍然没有读完,惭愧……)

刚开始学数据结构的时候,有点茫然,因为用到的地方不太多,虽然自己是有兴趣,但是老是感觉把握不到所学内容的核心。后来随着自己写的程序多了起来,有了点自己的心得体会,觉得这真是的博大精深的内容。

这门课也是CS的基础课程之一,每个学习计算机的人都应该对里面的基础内容熟记。数据结构的设计和使用是我们在编写程序的时候必须会碰到的问题,可能写写小程序用到的知识不会太多,但是当程序的规模增加,或者涉及的问题比较复杂的时候,肯定会要求我们去使用一些数据结构,这个时候我们最起码要知道哪些数据结构对于我们手上的问题来说能够较好的解决。

算法和数据结构就是两兄弟,每一个数据结构都会有伴随的算法复杂度,而且很多经典的算法都需要经典的数据结构来作为后面的基础,如堆排序。

我这么说可能有点范和空,但是当大家自己去编一个编译器,又或者写个文本搜索或者是文件压缩的程序甚至是内存分配的时候,就能够体会到这两者对于软件的重要性。

在这个过程中,我觉得很一个很好的学习方法就是遇到算法和数据结构都自己去实现一遍,而不是仅仅的把教材上面的代码给看懂。这个时候做些ACM题也是挺有用的。

 

离散数学

记得曾经在一篇文章里面看到过CS实际上可以说是应用数学的一个分支,其实我自己也蛮赞同这个观点。但是按照目前国内的数学教育来说,还很难达到这个高度。

说回整体,实际上CS对于数学的要求还是很高的,而其中离散数学应该是所有CS需要掌握的数学里面最最重要的一个分支。实际上我觉得离散数学就是对于CS最重要的数学分支的一个总体概括。我们可以在这门课里面学到很多相关数学的一些基础概念,让我们在以后的深入学习能够有一个大体的认识。比如说数论、图论、数理逻辑、计算理论等。

 

操作系统

说到大家最常用的操作系统了。这里不作太多的Unix/Linux、Windows孰优孰劣的评论,用我自己的经验来说的话,学习Linux,对于你理解操作系统肯定有很大的好处,无论你以后是不是用Linux来工作。

操作系统可能大家觉得学习来的用处不太大,主要是可能平时用到知识的场合比较少(主要是本科的范畴)。其实如果大家以后出来工作的话,就会发现操作系统对于整个软件设计是很重要的。就算在学校里,在接触分布式系统的时候,对于进程和线程的概念和调度这两个概念也必须十分的了解才能学好。记得在面百度的运维开发的时候就被问了个内存分配和CPU调度的问题。还有由于现在互联网的发展,提倡的云计算和移动开发,都需要对于操作系统有十分深入的了解才可以让自己在深入的时候游刃有余。

其实在操作系统主要也无非就是进程、内存、IO、文件系统这几块内容。在学习的时候,主要是需要大家自己去系统上多操作一下。如果有条件和能力的话,看看Linux/Minix的源码就更加好了,当然如果要看完那就有点难度太高了。

 

计算机体系与结构

这门课实际上是CS里面非常核心且重要且难学的一门课,但是我们竟然在大二就学了,恩,我们还是熬过来了……我感觉如果在大三大四学的话,会更好。

学习计算机,如果不知道一个计算机里面的结构,以及包含的指令集的作用的话,那我们其实错过了很多,对于我们理解计算机也是很缺失的。

计算机里面的CPU,我们需要学习他是如何通过一个数据通路来进行计算,一个CPU的执行周期又包含了哪些步骤,流水线是如何成倍的提高CPU的执行效率等等,这些都是关于计算机本身的核心话题啊!!而且在操作系统里面的内存管理和分层问题,这里会更加深入的探讨。

我觉得在学习这块的内容的时候,如果能够一个模拟的环境来让我们体会整个CPU的执行周期,这样可以让我们对于知识的了解更加的深入。

书的话,我推荐D. A. Patterson和J. L. Hennessy写的《Computer Organization and Design: The Hardware/Software Interface》,这本书非常深入且全面的讲解了体系结构里面的话题,不过阅读难度可能稍微大了点。

 

人工智能(AI)

其实是我自己把AI加进来的,但是从我自己的体验来说,学习人工智能对于加深CS的认识真的有很大的帮助,同时这个领域现在和很多其他的方向都有交集,基本上无论CS的哪个方向(貌似除了计算理论方向没有涉及)之外,其他的另外都会或多或少的涉及到AI。

首先AI实际上是个非常大的方向,所以和搜索和逻辑有关的话题你都可以说是AI。比如说DFS、BFS、A*这些基础的搜索,数理逻辑里面的命题和谓词逻辑,到后面的规划、机器学习、知识表示、机器人学、图像处理等等。

为什么说AI可以加深对于CS的认识?说说我自己的经历,首先在学习DFS、BFS以及A*、Min-Max这些搜索算法的时候,我们会用到之前算法和数据结构里面的知识。然后在学习命题和谓词逻辑以及规划、证明的时候,我们又会用到我们在离散数学里面学到的数理逻辑方面的知识。然后在学到机器学习的时候,我们又会利用到概率统计方面的来证明学习的有效性。

同时,学习AI还可以拓展自己在CS里面的视野,如果我们往后学习的话,会发现在涉及多智能体的问题的时候,我们需要用到经济领域常用的博弈论,有时候甚至会涉及一些运筹学。而面对机器人学的时候,我们又会需要用到自动化里面的控制理论来进行机器人的控制的计算。

而推荐书目的话,推荐看《Artificial Intelligence: A Modern Approach》,这本书从一个大整体的方向上来讲述了整个AI的内容,很高屋建瓴的感觉!

 

除了上面提到的核心课程之外,其实还有软件工程、编译原理与技术,太多了暂时就写这么多吧。

在学完上面这些基础课之后,根据自己的方向不同,会有计算机网络、数据库、图像处理、图形学等不同的选修课,不是说这些课就不重要,只是我觉得他们是在这些核心课程之上建筑起来的课程。

当然如果想要学习理论方面的CS的话,还有形式语言与自动化,计算理论,数理逻辑,程序语言,程序正确性证明等课程。

 

如何学CS以及推荐书目

其实上面就已经讲到了一些,所以下面主要讲讲怎么去驱动自己学习。

我觉得对于CS来说,他不像外界认识的那样,只要懂门语言就可以写代码,然后就可以了。其实CS是门很难的可能,并且随着现在时代的发展和知识的爆炸,我们会发现CS的内容越来越多,并且本身CS就是门跨数学和工程的专业,包含的内容和要求本身就很高。所以我觉得想要学好这个专业的话,很大一个因素是认清这个学科,并且找到驱动自己的那一个方向,这个方向不一定是CS里面的方向,也可以是编编应用,解决一下实际问题。

比如我自己,在大一的时候就尝试用C++编写过游戏(虽然是纯Text的),当然我自己对这方面是有兴趣,这样就驱动了我用C++去解决实际的问题,这同时也加深了我对于面向对象和里面的多态的认识。所以从我的角度来说,我比较鼓励兴趣和问题驱动的去学习CS。

同时我觉得在学习的同时,一定要学会关注当前计算机领域的动向和国外大学的一些研究现状。有时间上上CSDN或者国外的技术网站看看相关新闻,还有MIT或者Stanford一些lab的首页来看看他们的研究,又或者去网易公开课看看一些国外的课程,我觉得都可以拓充自己的视野,说不定还哪一天想到一些创业的Idea也不一定,哈哈。

 

接下来是推荐的书目了,这里讲讲我大学期间看过的一些书,如果是软件学院本身的教材的话我就不重复了。

C++:《C++ Primer》,一本教材足矣,基本包含了所以C++里面包含的话题。对于STL也有相当深入的讲解,当然如果要学STL和模板的话,光是这本还是不够,不过自己对于模板还不是太精通,就不推荐了。

C:《The C Programming Language》,C的作者写的C教材,通俗易懂,并且例子从易到难都有,比如字符串处理到后面的内存分配,可以在这本很薄的书里面发掘到很多经典的程序!

Scheme,计算机导论:《Structure and Interpretation of Computer Programs》,这本书许多大牛都推荐过,我还是要推荐。是MIT里面的本科入门课程的教材,在北大现在也有上这门课。这本书用Scheme作为载体,将整个CS里面的经典话题都基本讲了,并且例子非常好,生动!比如编译原理,函数式编程,逻辑编程,数值分析,垃圾回收等。

Common Lisp:《Practical Common Lisp》,很多通俗易懂的例子,而且作者一年学会Lisp,牛!

算法与数据结构:《算法导论》

离散数学:《离散数学及其应用》

操作系统:《现代操作系统》、《操作系统:设计与实现》,前者是教材,后者是同作者写的基于Minix来讲解的更加深入的一本书,对于想了解实现的同学有很大的帮助。

体系与结构:《Computer Organization and Design: The Hardware/Software Interface》

人工智能:《Artificial Intelligence: A Modern Approach》、《Artificial Intelligence: A New Synthesis》、《Artificial Intelligence: Structures and Strategies for Complex Problem Solving》,其中第二本是斯坦福的AI规划鼻祖写的,非常权威;第3本从一个很实际的角度讲解了AI,比前两本来的没那么抽象,并且后面有Prolog和Lisp实现AI里面的经典例子的章节,非常有用。

Linux:《Linux程序设计》、《Unix环境高级编程》、《Unix编程艺术》、《鸟哥的Linux私房菜》

计算机网络:《Computer Networking: A Top-Down Approach Featuring the Internet》、《Unix Network Programming Vol.1》,后者是已故的网络大牛W. R. Stevens写的,对于学习和编写网络程序都是必不可少的一本案头参考。

编译原理:《编译原理:技术与工具》,编译领域的龙书,第一版是用C作为载体,第二版是用的JAVA,看个人喜好了。

计算理论:《计算理论导引》,看离散数学后面不过瘾那就一定得找这本来看看。其实计算机那边上课好像还推荐了另外几本,不过我感觉看这本也很足够了。

数理逻辑:《应用逻辑》、《面向计算机科学的数理逻辑  系统建模与推理》,应用逻辑主要是后面的参考数目很牛,后者的话我觉得从一个很通俗易懂的角度来讲述了数理逻辑。

其他:《逻辑的引擎》、《编程人生  15位软件先驱访谈录》、《人月神话》

 

最后,我建议大家能够在大三大四的时候都出去实习,争取去到大公司里面拿到一些实际的工作经验,因为这是能够将我们自己的学到的理论知识运用到实际上的机会,并且能够知道业界发展的方向,和学到一些团队合作和项目管理方面的知识,这些都是在学校里面很难学到的。