怒肝1.3w 字给学姐讲明白计算机专业大学四年到底该学什么?
为了保证这篇文章后续能够继续完善,我已近将其同步到了我的 Github:https://github.com/Snailclimb/cs-guide (无价值不分享。欢迎扩散,让更多学姐看到。有帮助就点个 star 鼓励一下 🤟)
网上已经有挺多关于“计算机专业大学四年到底应该学什么?”相关的文章了。不过,既然学姐问了我这个问题,我还是想再从我的角度来给她回答一下。安排!
另外,这篇文章中我不光会推荐你学习什么,还会推荐对应的比较好的学习资料给你。
这篇文章前前后后花了两个月时间写完,光是完善和修改就花了一周。即使,我尽量控制不说废话,但是这篇文章的字数也还是超过了 1w 字 ,不过都是干货!相信,不论是在校大学生还是已经工作几年的小伙伴都应该能够从中有所收获。如果有帮助点个赞/再看鼓励一下就好!
另外, 这篇文章也要感谢我哈工大的一位朋友小明,毕竟自己离开学校已有 1 年多,没有他的鼎力帮助,就没有这篇文章。
下面这张图是周末的时候在窗台边写这篇文章的时候拍的。
首先,在学习编程之前,我觉得什么编程语言、数据结构、算法、操作系统这些都要统统一边去。作为计算机专业的学生一定要首先养成下面几个程序员必备的好习惯。
程序员必备的好习惯
使用 Google 搜索而不是百度。如果你实在访问不了 Google 的话,替换成 Bing 也行。 经常逛一些比较不错的博客论坛比如国内的掘金、博客园、CSDN,学有余力的小伙伴还可以去 GitHub、码云上找一些开源项目,用来训练自己的开发能力。 多关注一些你的领域的一些大牛在干嘛,多关注一些优质原创博主的博客。举个例子:Java 领域的话,你可以多关注一下我的 Github:https://github.com/Snailclimb[1] ,上面有很多干货。 编程不只是要看,更要动手,这是一个特别需要实践的专业。各个高校在编程课上可能会介绍自己校内的 oj(online judge),题库式的网站,可以做一些编程题目,还可以在线评测。一般适合初学者的简单的 OJ 校内都会提供,如果没有的话,可以去校外找一些开放的简单的 OJ 来刷题。 不要因为刚开始学习编程的不容易,而打击自己的学习兴趣和欲望。加油!奥利给!
我把我知道的一些程序员必备的好习惯毫无保留地都整理在了这个仓库:https://github.com/Snailclimb/programmer-advancement [2] ,强烈推荐大家看看,同时也期待你的完善补充!
然后,就是编程语言了!
编程语言
几乎所有的大学刚入学第一年就会开设一门编程语言课,一般是 C 语言偏多。
不论你的学校是否开设了 C 语言这门课,我建议大家最好还是学一下 C 语言。拿我从事的 Java 后端开发来说,很多 Java 从业者单纯觉把 Java 学好就完全足够了,并不需要再学习像 C、C++这种稍微更难一点的编程语言。我觉得对于刚能写好 CRUD 的 Java 程序员来说确实是这样的,但是对于想要成为比较顶尖的 Java 程序员来说肯定是不行的。很多开源项目都调用了 C 语言库,所以, 作为 Java 程序员,不需要你 C 编码能力多强,至少能够看懂 C 代码。
刚开始学习一门编程语言的时候,大部分人都挺吃力的。有时候一个环境搭建就折腾大半天。我记得,我那时候刚开始学,很多非常非常简单的控制台程序都写不出来。不过,随着后面学习的慢慢深入,我慢慢发现自己的编程思维和能力在变得越来越好。
在这里我想鼓舞一下初入计算机编程的各位小伙伴:万事开头难,你见过的所有大佬都是从懵懵懂懂的阶段摸爬滚打过来的。 当你在 C 语言课上看着前面的老师在编译器中飞快地输入着代码,自己却连编译器都配置不好的时候,心中难免会有失落,但这决非放弃的理由,只要坚持住,解决了一个又一个的难题,你也会成为曾经心中的大佬。
如果想要看视频提前学习或者上课没学好 C 语言的话,推荐去 B 站搜索 C 语言郝斌。这个老师的课程很不错,非常适合拿来作为初学者学习 C 语言的教程。并且,视频中老师还会给你分享一些他自己的编程学习心得。
另外,如果你觉得谭浩强 老师的 《C 语言程序设计》 这本书比较难理解的话,可以看一下 《啊哈 C 语言!》,这本书非常通俗易懂,非常适合之前没有学习过编程的新手。
还有开设 C++课程的高校也比较多。初学者学习 C++的教材可以使用《C++ Primer》,熟练掌握基础语法后,为了进一步提高自己的编程开发能力,还可以读一读《C++ Primer Plus》和《Effective C++》。
实际上,大一初学编程的小伙伴在刚开始学编程语言的时候都会很吃力,以上推荐教材的正确使用方法有两个要点:
结合课上老师所讲和书上所讲,在实际应用中去感悟“为什么” 把教材当成工具书、参考书,而非“教程”,结合参考书和网上搜索资源,来解决在实际编程中遇到的问题
计算机基础课
计算机基础的话,就是我们平时常提到的老四件:1.数据结构、2.算法、3.计算机网络、4.操作系统。
要我说的话,这四门课是程序员最最最需要好好学的东西!另外,虽然四者都很重要,但是数据结构和算法相比于计算机网络和操作系统要更加重要一些!
这四大件也就是我们常说的程序员内功修炼最重要的一部分内容!
“直接用框架不就好了么?为啥还要学习这些东西呢?” 这句话是很多初学编程的小伙伴最疑惑的问题。
简单给大家聊聊为什么这四大件这么重要吧!
地基稳固才能走的长远 :这大件可以说是程序员未来发展的地基,你掌握的程度决定了你的地基打的有多深。工作不久之后,你就会发现你想要成为一位优秀的程序员,而不是 API 调用者/低级 Bug 制造者,这些东西都是必备的! 技术更新换代快 :我们前几年可能还在用 Spring 基于传统的 XML 开发,现在几乎大家都会用 Spring Boot 这个开发利器来提升开发速度,再比如几年前我们使用消息队列可能还在用 ActiveMQ,到今天几乎都没有人用它了,现在比较常用的就是 Rocket MQ、Kafka 。技术更新换代这么快的今天,你是无法把每一个框架/工具都学习一边的,底层技术就是你快速上手他们的瑞士军刀。 懂得底层技术的人更有竞争力 :现在的程序员这么多,你如何能和别人拉开差距?单纯就靠使用框架的能力么?这些随便从培训班抽一个人可能都会做的工作无法成为你的核心竞争力。
数据结构
关于数据结构,我想说的是,它是这四大件中最简单、最基础的一个。离开了数据结构,几乎任何的程序都会失效,所以在讨论数据结构的时候,常常要把算法也连带着说一说。
要单纯地掌握常见的数据结构,就如同拆解一个个精妙的仪器件一样有趣和简单。正因为数据结构这个东西在程序中的作用,和仪器部件特别相像,不同的数据结构有着不同的特性,因此要想学好数据结构,图解是必备武器!
在数据结构的学习中,强烈建议跟着名校的网课学习,这些课程都经过多次打磨,配套练习丰富,非常适合初学者。比如中国大学 MOOC 上的武汉大学开设的《数据结构》课程。
辅以教材参考书,强推《大话数据结构》,光看封面你就知道这本书的风格了,图解学数据结构?选这本,没错的!
当用图解理清了各种数据结构的原理和特性之后,还要在代码中多加练习,熟能生巧。
编程是一个冒出一个问题,解决一个问题的有趣过程。
当有一个变量在脑海中出现的时候,要先思考该变量的作用是什么,以什么数据结构存储这个变量,还要考虑在代码中如何实现。比如说栈,在 C 语言中可以用数组辅以栈顶指针来实现;在 Java 中可以直接调用 Stack 类来实现。只要你编程,就要用到数据结构,编的程序越复杂,用到的数据结构就可能越多,可以说它几乎没有什么难点,重点是熟能生巧。
算法
算法课常常和数据结构课放在一起,在有些高校中,会存在“数据结构与算法”和“算法设计与分析”这样的两门课。
前者可能相对简单,介绍的是常用的数据结构和基础的算法;后者就相对较难,讲的是算法相关的概念,以及稍微比较复杂的算法思维和算法分析。前者侧重的是基础逻辑算法的应用,后者侧重的是运用算法思想到实际问题中。
举个例子,我们常用的排序算法就属于前者的课程内容,一个排序问题可以有多种算法解决方案,不同方案有不同的优劣,也就有不同的应用场景,学习一题多解也可以加强编程熟练度。而贪心思想属于后者的课程内容,比如说经典的活动选择问题:
设 S={1,2,...,n}是 n 个活动的集合,各个活动的集合,各个活动使用同一个资源,资源在同一时间只能为一个活动使用。现已知 n 个活动的开始时间 si 和 fi,设所有活动的最早开始时间和最晚结束时间都在资源可供利用的时间内,并规定若活动 i 和活动 j 满足 fi≤sj(或 fj≤si),则称他们是兼容的。现求:最大活动集合,该活动集合内的所有活动都是兼容的。
该问题的解决思想使用了贪心思想,贪心策略为:每次都选 fi 最小,即结束时间最早的活动(在满足兼容的情况下)。以此贪心策略进行选取活动集合,可以满足结果为最优解(不唯一),该解法的最优性可以用优化子结构来证明。以上这些,对于初学者来说可能听起来云山雾绕,但这都是算法设计与分析课上的内容。
分治思想、贪心思想、动态规划这三大算法在实际应用起来非常灵活,常常让人摸不到头脑。我给大家的建议是:
多多联系图解的方式,先接触算法的思想。不管多复杂的算法,结合了图解,总能对其有一个清晰的认识。 多多联系实例,研究算法在问题中的应用。对算法有一个清晰的认识后,到了实际问题中还是不容易应用算法想出解题思路,需要大家勤动脑,勤动手,多做题,感悟算法在问题中的应用。 多多看博客、热门笔记,听听前辈们的总结,争取做到举一反三。前辈们的笔记都是非常不错的学习资源,如 网上一些热门的开放的 OJ 也是大家训练算法的好资源哦~,比如leetcode[3]
另外,如果你刷 Leetcode 的话,你会发现很多算法题都是通过动态规划的方式来解决的,因此你务必要琢磨透动态规划算法的思想。
再附上一些算法领域的经典学习参考书(对于初学者,推荐程度从左向右……):
下面这两篇文章都非常不错,一定要好好看一下:
《硬核的算法学习书籍+资源推荐》[4] 。 如何刷 Leetcode?[5]
计算机网络
计算机网络是一门系统性比较强的计算机专业课,各大名校的计算机网络课程打磨的应该都比较成熟。
要想学好计算机网络,首先要了解的就是 OSI 七层模型或 TCP/IP 五层模型,即应用层(应用层、表示层、会话层)、传输层、网络层、数据链路层、物理层。
Data to Drag关于这门课,首先强烈推荐参考书是机械工业出版社的《计算机网络——自顶向下方法》。该书目录清晰,按照 TCP/IP 五层模型逐层讲解,对每层涉及的技术都展开了详细讨论,基本上高校里开设的课程的教学大纲就是这本书的目录了。
如果你觉得上面这本书看着比较枯燥的话,我强烈推荐+安利你看看下面这两本非常有趣的网络相关的书籍:
《图解 HTTP》[6] :讲漫画一样的讲 HTTP,很有意思,不会觉得枯燥,大概也涵盖也 HTTP 常见的知识点。因为篇幅问题,内容可能不太全面。不过,如果不是专门做网络方向研究的小伙伴想研究 HTTP 相关知识的话,读这本书的话应该来说就差不多了。 《网络是怎样连接的》[7] :从在浏览器中输入网址开始,一路追踪了到显示出网页内容为止的整个过程,以图配文,讲解了网络的全貌,并重点介绍了实际的网络设备和软件是如何工作的。
如果说学习计算机网络要围绕的 TCP/IP 五层模型逐层展开学习的话,那么针对每层的学习,就要以协议为单位了。一言以蔽之,我们学习计算机网络需要的协议有:
应用层协议 HTTP 协议(超文本传输协议,网页浏览常用的协议) DHCP 协议(动态主机配置) DNS 系统原理(域名系统) FTP 协议(文件传输协议) 电子邮件协议等(SMTP、POP3、IMAP) P2P 架构 传输层协议 报文段结构 RDT(可靠数据传输协议) 报文段结构 可靠数据传输 流量控制 拥塞控制 TCP 协议 UDP 协议 网络层协议 IP 协议(TCP/IP 协议的基础,分为 IPv4 和 IPv6) ARP 协议(地址解析协议,用于解析 IP 地址和 MAC 地址之间的映射) ICMP 协议(控制报文协议,用于发送控制消息) NAT 协议(网络地址转换协议) RIP 协议、OSPF 协议、BGP 协议(路由选择协议) 链路层 差错检测技术 多路访问协议(信道复用技术) CSMA/CD 协议 MAC 协议 以太网技术 物理层(对计算机专业的小伙伴来说,在课程要求中,物理层的内容可能相对不那么重要)
操作系统
操作系统也是一门比较重要的学科。为何这样说呢?
操作系统中的很多思想、很多经典的算法,你都可以在我们日常开发使用的各种工具或者框架中找到它们的影子。
比如说我们开发的系统使用的缓存(比如 Redis)和操作系统的高速缓存就很像。CPU 中的高速缓存有很多种,不过大部分都是为了解决 CPU 处理速度和内存处理速度不对等的问题。我们还可以把内存可以看作外存的高速缓存,程序运行的时候我们把外存的数据复制到内存,由于内存的处理速度远远高于外存,这样提高了处理速度。同样地,我们使用的 Redis 缓存就是为了解决程序处理速度和访问常规关系型数据库速度不对等的问题。
高速缓存一般会按照局部性原理(2-8 原则)根据相应的淘汰算法保证缓存中的数据是经常会被访问的。我们平常使用的 Redis 缓存很多时候也会按照 2-8 原则去做,很多淘汰算法都和操作系统中的类似。
既说了 2-8 原则,那就不得不提命中率了,这是所有缓存概念都通用的。简单来说也就是你要访问的数据有多少能直接在缓存中直接找到。命中率高的话,一般表明你的缓存设计比较合理,系统处理速度也相对较快。
总结来说,我觉得学好操作系统能够提高自己思考的深度以及对技术的理解力。
操作系统内容比较多,如果说你单纯是为了应付面试的话,你可以看我之前总结的一篇文章:https://snailclimb.gitee.io/javaguide/#/docs/operating-system/basis[8] 。
这篇文章的目录如下,涵盖了操作系统一些比较常见的问题。
如果你要系统地学习操作系统的话,最硬核最权威的书籍是**《操作系统导论》** 。你可以再配套一个 《深入理解计算机系统》 加深你对计算机系统本质的认识,美滋滋!
如果你比较喜欢动手,对于理论知识比较抵触的话,我推荐你看看《30 天自制操作系统》,这本书会手把手教你编写一个操作系统。
计算机专业课
本章设计的课程并不是说专业课,只是说相比于上面的四大件,专业性更强,主要包括面向对象程序设计、形式语言与自动机、机器学习、数据库系统、编译原理。
面向对象程序设计
面向对象程序设计(OOP)是程序员编程的核心思想,如果以后走软件开发路线,OOP 是必须要精通的。OOP 给程序员提供了一种思维模式,将现实生活中的事务抽象成为“对象”,面向对象进行程序设计。
举个例子,OOP 中有三大要素——类、继承、多态(也有封装、继抽象、继承、多态四大要素)。如果把杯子抽象成为类的话,那么咖啡杯、茶杯、马克杯等等都属于对杯子的继承,在该继承中,被继承者——杯子,被称为父类,继承者——咖啡杯、茶杯、马克杯,被称为子类。子类继承父类,即父类有的子类一定有(除父类私有),而子类有的父类不一定有。而多态的概念是在继承之中的,在继承中,子类拥有父类的方法,都是杯子,那么就都能装水。而不同的杯子可以定制自己的方法,即重载父类“装水”的方法——装咖啡、装茶水等。
OOP 中还有六大原则:
单一责任原则(Single Responsibility Principle) :一个类尽量只负责一种事务的抽象,功能尽量单一,降低耦合。 开放-封闭原则(Open-Closed Principle) :在类的设计中,要尽量保证“对扩展性的开放,对修改的封闭”。 Liskov 替换原则(Liskov Substitution Principle) :Liskov 规则严格规定,“子类型必须能够替换其基类型,派生类必须能够通过其基类的接口使用,客户端无需了解二者之间的差异。” 接口聚合原则(Interface Segregation Principle) :该原则要求,不能强迫客户端依赖于它们不需要的接口,只提供必需的接口。“大”接口尽量分割为若干个”小“接口,不同的接口向不同的客户端提供服务,客户端只访问自己需要的接口。 依赖转置原则(Dependency Inversion Principle) :抽象的模块不应该依赖于具体的模块,具体应依赖于抽象。 最少知识原则(Least Knowledge Principle) :一个类对其他类的内部实现,知道的越少越好,如果一定要和不太相干的类通信,尽量使用第三者作为转达。
可能有很多小伙伴在学完了 OOP,编了两三年程序也没完全弄清楚这六大原则。其实他们无处不在,这里我尽量举例子来形象地说明这六大原则。
假设杯子分为咖啡杯和牛奶杯:
单一责任原则要求,不应该有一种杯子既能装咖啡又能装面包,如果可以的话,那么当客户需要一个装面包的容器时,被提供了一只杯子,这样当装面包的容器发生变化时,就波及到了杯子功能的实现,耦合度较高不利于维护。 开放封闭原则要求,杯子现在可能很简单,但最好支持将来的拓展,如加入量度、加入杯盖等。但请不要再做修改,咖啡杯就是咖啡杯,如果需要改造出一个茶杯,请新继承一个茶杯,而不要在已有的咖啡杯上修改。 Liskov 替换原则要求,顾客在买杯子的时候,只需要说”我要买杯子,装咖啡用“,就可以提供咖啡杯给该顾客,满足顾客的所有需求。 接口聚合原则要求,不应该有一种杯子既能装咖啡又能装牛奶,如果顾客需要装咖啡的杯子,请不要提供给他”咖啡牛奶杯“,装牛奶的功能是他不需要的。 依赖转置原则要求,咖啡杯的设计一定要依赖”杯子具有盛装液体“的功能,而非杯子能装液体依赖于咖啡杯的设计。这一原则和”面向过程程序设计“思想恰恰相反。 最少知识原则,嗯...用杯子举例就不太恰当了,就拿企业里各个部门之间运作举例吧,两个不相关部门之间不要直接通信,如果要通信的话,用第三个部门统筹安排,降低耦合度,提高效率。
关于 OOP 大的概况,我只能用三大特性和六大原则来概括,真要学习起来,OOP 中的每一个细节都值得深入讨论。OOP 早在上世纪八十年代就开始流行,作为提高程序设计生产力的重要思想,一直沿用到现在。C++和 Java 是现在比较主流的 OOP 编程语言,也是高校中 OOP 课程的主力教学语言。如果接触的第一门语言的是 C 语言的话,也不用太过抵触,虽然 C 语言是面向过程程序设计,接触过这种稍稍比较原始的编程思想,再学习 OOP 的话,会有更不一样的感觉。
形式语言与自动机
“计算机专业大学四年到底应该学什么?”,我想很多人在这个问题下的回答不会包括这门课——形式语言与自动机。
这门课包括两个部分:
形式语言。 自动机。
形式语言更像是计算机专业的数学课,它研究的是严格的语法规则下,语义的表示。基于形式语言课程的后续课程其实也不算多,编译原理、自然语言处理等专业课程可能会用到形式语言的知识,但形式语言带给学生的更偏向于一种思想,在给定条件下对问题的定义能力和抽象能力。
自动机是算法的一种。自动机可以理解为一台在给定状态下、给定输入得到确定的输出(集)的机器,核心是状态 × 输入 →{状态}的映射。他也是代表着一类思想。自动机思想在算法中的应用常常被看作是传统算法,由于他的思路非常简单,运行效率高,在一些特定的场景下有着高效地运用。但自动机的缺点在于其定义非常复杂,正因为此,适用面也比较窄。
总的来说,形式语言跟正则表达式还有点关系,自动机的学习过程更像是解一道道的智力题,这门课应该还算比较有趣的一门课。
如果你要学习这门课的话,可以去中国大学 Mooc 看看哈工大的形式语言与自动机理论这门课。
机器学习
机器学习这门课不一定每个高校都开设,有的高校可能开设的是领域性更强的深度学习,有的高校可能把机器学习当作选修课开设,但在现在的人工智能技术横行的 IT 行业中,要掌握 AI 技术,机器学习属于一门很好的入门专业课(并不是通识课)。
机器学习中涉及了大量的概率论的知识,需要扎实的概率论基础,还夹杂着一些不简单的线性代数知识。 机器学习的工作是在研究一种算法,在某些任务中,利用一些经验,研究该算法的性能。任务的种类大体可以分为分类问题和回归问题。 分类问题,就是在给定已知条件的情况下,决定该情况属于哪一类,比如经典的航班预测问题,给定某一班航班的信息,预测该航班是否可能会晚点。而回归问题是在给定已知条件的情况下,计算该情况的回归值,在航班预测问题中,可能并不是预测是否晚点(二分类问题),而是预测该航班的到达时间(相比于基准时间的晚点时间或早到时间),这就是回归问题。
机器学习中比较简单的算法有决策树、多项式拟合、逻辑回归等,相对较难的算法有支持向量机(SVM)算法、EM 算法等,就不一一列举了。机器学习在一些算法上可以看作是数值分析课程和概率论的延伸,因此在学习机器学习之前,一定要打好扎实的数值分析基础,学好概率论,顺便别把大一学的线性代数都忘光了。
在学习的过程中,除了跟着老师在课堂上的逐步讲解和推导,课下还可以结合着 B 站上的 “白板机器学习” 来看,推导非常详细,小哥哥也非常耐心。
参考书的话,这里有两本推荐的书,一本是“西瓜书”——周志华的《机器学习》。 西瓜书中的案例场景围绕着“种西瓜”展开,比较能带动读者兴趣,但是该书涉及符号较多,读者最好有一定的代数能力素养,可以尽快适应该书的符号表达和公式推导。该书比较适合慢慢研读,内容在机器学习领域不算深,一点点啃会有不小的收获。另一本书是李航的《统计学习方法》, 该书不仅适合计算机专业的学生,也适合数理统计专业的学生,书中每章都围绕着一个个经典算法展开,推导过程详细,篇幅也不长,但内容相对西瓜书来说比较枯燥,适合作为工具书来读,需要学习某个算法的时候,去该书上找那一章节,快速读完,不懂的话可以多读几遍。
数据库系统
数据库系统这门课在程序员的职业规划中也是非常重要的一门课,甚至有些信息管理的专业的也要开设这门课。说这门课重要,是因为对于程序员的发展来说,一方面关系数据库系统、SQL 语言以及数据库的三段设计(概念设计、逻辑设计和物理设计)都是开发数据库应用程序的必备技能,通常在数据库应用开发岗位的面试中,数据库的设计是面试官青睐的考点,如何能根据需求分析并设计出完善的数据库系统,是程序员的必备技能,设计好了完善的数据库系统之后,再用 SQL 语言等工具对其进行实现,那么这些其实就是个人的编码能力了。另一方面,数据库中的查询处理、查询优化、并发控制、事务管理、日志管理等内容,都是数据库中稍微进阶一点的技能,对于一些对岗位要求比较高的,这些技术同样要求熟练掌握。 对一些查询优化的等数据库底层实现的内容,也是新型数据库开发的前置基础技能,对于一些研究型人才来说,也是非常重要的。
数据库系统与其他计算机专业课一样,知识体系非常清晰,而且他有一个非常突出的特点,就是实际与理论相结合。SQL 语言,数据库设计等,这些都属于实践应用部分,而对于一些范式定义,两段锁协议并发控制等,这些就偏向于理论多一些。要想学好数据库系统,建议大家:
在课程的前期阶段,熟练掌握 SQL 语言的应用,同时不要忘了训练关系代数的应用能力。 关系代数虽然在数据库的实现上作用较小,但在学习阶段,结合关系代数和 SQL 语言学习,可以更加有体系地理清 SQL 语言各个子句之间的逻辑关系,有助于 SQL 语言的学习和记忆。关系代数的学习更像是建立一种思维,这种思维到了数据库底层实现学习环节也是非常有用的。 在课程的中期阶段,熟练掌握 ER 图的应用,并强化数据库设计中的理论部分。 ER 图的熟练应用可以更加轻松地设计出关系数据库模式,而理论部分同样不能忽视,设计理论的运用决定了数据库的正确性和健壮性。 而在课程的后期阶段,主要就是以理论居多,而且这些理论并不容易能找到配套的实验练习。这里再次强调,凡是理论知识的学习,尽量要结合图解的方式。
教材的话,强烈推荐《数据库系统概念》(机械工业出版社),这本书涵盖了数据库系统的全套概念,知识体系清晰,是学习数据库系统非常经典的教材!不是参考书!
参考书的话,可以看一看《深入浅出 MySQL:数据库开发、优化与管理维护》,该书非常适合 MySQL 开发的从业者,完全可以作为 MySQL 学习的参考书,相比《数据库系统概念》来说,该书更加倾向于基于 MySQL 技术的全套开发,一共分为基础篇、开发篇、优化篇、管理维护篇和架构篇。
编译原理
编译原理相比于前面介绍的专业课,地位显得不那么重要了。编译原理的重要性主要体现在:
底层语言、引擎或高级语言的开发,如 MySQL,Java 等 操作系统或嵌入式系统的开发 词法、语法、语义的思想,以及自动机思想
编译原理的重要前置课程就是形式语言与自动机,自动机的思想在词法分析当中有着重要应用,学习了这门课后,应该就会发现许多场景下,自动机算法的妙用了。
总的来说,这门课对于各位程序员的职业发展来说,相对不那么重要,但是从难度上来说,学习这门课可以对编程思想有一个较好的巩固。学习资源的话,除了课堂上的幻灯片课件以外,还可以把《编译原理》(机械工业出版社)这本书作为参考书,用以辅助自己学不懂的地方(大家口中的龙书,想要啃下来还是有一定难度的)。
通用课
通用课的部分我想分为两大部分来介绍,主要就是数学和英语,一般在大一和大二两学年就可以全部修完,大二大三逐渐接触专业课。通用课作为许多高中生升入大学的第一门课,算是高中阶段到本科阶段的一个过渡,从职业生涯重要性上来说,远不及专业课重要,但是在本科阶段的学习生活规划中,有着非常重要的地位。由于通用课的课程多,学分重,占据了本科阶段绩点的主要部分,影响到学生在前两年的专业排名,也影响到大三结束时的推免资格分配,也就是保研。而从升学角度来看,对于攻读研究生和博士生的小伙伴来说,数学和英语这两大基础课,还是十分有用的。
数学
微积分(高等数学)
微积分,即传说中的高数,成为了无数新大一心中的痛。但好在,大学的课程考核没那么严格,期末想要拿高分,也不至于像高中那样刷题刷的那么狠。微积分对于计算机专业学生的重要性,主要体现在计算机图形学中的函数变换,机器学习中的梯度算法,信号处理等领域。
微积分的知识体系包括微分和积分两部分,一般会先学微分,再学积分,也有的学校把高数分为两个学期。微分就是高中的导数的升级版,对于大一萌新来说还算比较友好。积分恰好是微分的逆运算,思想上对大一萌新来说比较新,一时半会可能接受不了。不过这门课所有的高校都有开设,而且大部分的名校都有配套的网课,教材也都打磨的非常出色,结合网课和教材的“啃书”学习模式,这门课一定不会落下。
线性代数(高等代数)
线性代数的思维模式就更加复杂了一些,它定义了一个全新的数学世界,所有的符号、定理都是全新的,唯一能尝试的去理解的方式,大概就是用几何的方式去理解线性代数了。由于线性代数和几何学有着密不可分的关系,比如空间变换的理论支撑就是线性代数,因此,网上有着各种“可视化学习线性代数”的学习资源,帮助理解线性代数的意义,有助于公式的记忆。
概率论与数理统计
对于计算机专业的小伙伴来说,这门课可能是概率论更有用一点,而非数理统计。可能某些学校只开设概率论课程,也可能数理统计也教,但仅仅是皮毛。概率论的学习路线和微积分相似,就是一个个公式辅以实例,不像线性代数那么抽象,比较贴近生活。在现在的就业形势下,概率论与数理统计专业的学生,应该是数学专业最好就业的了,他们通常到岗位上会做一些数据分析的工作,因此,这门课程确实是数据分析的重要前置课程,概率论在机器学习中的重要性也就不言而喻了。
离散数学(集合论、图论、近世代数等)
离散数学是计算机专业的专属数学,但实际上对于本科毕业找工作的小伙伴来说,离散数学还并没有发挥它的巨大作用。离散数学的作用主要在在图研究等领域,理论性极强,需要读研深造的小伙伴尽可能地扎实掌握。
英语
英语算是大学里面比较灵活的一项技能了,有的人会说,“英语学的越好,对个人发展越有利”,此话说的没错,但是对于一些有着明确发展目标的小伙伴,可能英语技能并不在他们的技能清单内。接下来的这些话只针对计算机专业的小伙伴们哦。
英语课在大学本科一般只有前两年开设,小伙伴们可以记住,想用英语课来提升自己的英语水平的,可以打消这个念头了。 英语水平的提高全靠自己平时的积累和练习,以及有针对性的刷题。
英语的大学四六级一定要过。 这是必备技能,绝大部分就业岗位都要看四六级水平的,最起码要通过的。四级比高中英语稍微难一些,一般的小伙伴可能会卡在六级上,六级需要针对性的训练一下,因为大学期间能接触英语的实在太少了,每学期一门英语课是不足以保持自己的英语水平的。对于一些来自于偏远地区,高中英语基础薄弱的,考四六级会更加吃力。建议考前集中训练一下历年真题,辅以背一下高频词汇,四六级通过只需要 425 分,这个分数线还是比较容易达到的。稍微好一点的小伙伴可能冲一下 500 分,要是能考到 600 分的话,那是非常不错的水平了,算是简历上比较有亮点的一项。
英语的雅思托福考试只限于想要出国的小伙伴,以及应聘岗位对英语能力有特殊要求的。雅思托福考试裸考不容易通过,花钱去比较靠谱的校外补课班应该是一个比较好的选择。
对于计算机专业的小伙伴来说,英语能力还是比较重要的,虽然应聘的时候不会因为没有雅思托福成绩卡人,但是你起码要能够:
熟练使用英文界面的软件、系统等 对于外网的一些博客、bug 解决方案等,阅读无压力 熟练阅读英文文献 具备一定的英文论文的撰写能力
毕竟计算机语言就是字符语言,听说读写中最起码要满足读写这两项不过分吧。
Q&A
1.感觉学校教的都联系不到实际,我本科毕业真的能找到工作吗?
就笔者所就读的高校来说,我是相信它的培养方案是有能力培养出具有就业能力的本科毕业生的。我相信很多名校的培养方案也都不会差。如果你就读的学校不是那么出色,并且质疑自己学校的培养能力的话,建议你多到名校的网课上取取经。如果你是就读于国内名校的话,请相信的自己专业的培养方案,下限不会低。
另外,如果你的学校比较差的话,大学期间一定要尽全力让自己的简历更好看,你可以出去实习、参加一些含金量比较高的比赛、跟着老师做一些项目。
2.学校里需要参加一些社团、学生会之类的吗?
笔者只参加过社团,并未参加过学生会。对于这个问题,我结合我所接触的人来简单回答一下。针对不同的发展定位,可以选择自己投入社团、学生会的精力。比如,你是一个技术宅,那么我想你就算加入了社团之类的团体,也收获不到自己想要的能力,其实就没有参加的必要了。如果你是一个学生干部,或者擅长和人打交道,也许毕业之后从事产品经理之类的工作,那么在学生会的经历应该是蛮锻炼你的能力的。是否要选择参加团体活动,投入多少精力,完全取决你对自己的定位如何,请把你自己放到合适的环境下培养,不必人云亦云。
3.在大学里一定要参加竞赛比赛吗?
竞赛比赛对于学生的好处有,得奖了的话可能会获得保研加分、丰富个人简历,在应聘中拿到不错的印象分。保研加分具体涉及到的竞赛需要咨询所在学院,并非所有竞赛获奖都能加分的。
那么竞赛比赛有没有坏处呢?也会有一点吧,就是指那些能力并不算强,但仍然把大量时间花在了打比赛这上面,这其实并不是坏处,这对个人能力仍有提高,坏处指的是因为打竞赛耽误了专业课的学习。这样一来,基础也没扎实,突出能力也没训练出来,捡了芝麻丢了西瓜,就不好了。
总的来说,打竞赛利大于弊,不要低估的自己的能力而排斥参加竞赛,也不要高估自己的能力过分痴迷竞赛。
以上是我针对本科计算机专业各个课程的倾力解读,如有不妥,请多加指正!
参考资料
https://github.com/Snailclimb: https://github.com/Snailclimb
[2]
https://github.com/Snailclimb/programmer-advancement : https://github.com/Snailclimb/programmer-advancement
[3]
leetcode: https://leetcode-cn.com/
[4]
《硬核的算法学习书籍+资源推荐》: docs/dataStructures-algorithms/算法学习资源推荐.md
[5]
如何刷 Leetcode?: https://www.zhihu.com/question/31092580/answer/1534887374
[6]
《图解 HTTP》: https://book.douban.com/subject/25863515/
[7]
《网络是怎样连接的》: https://book.douban.com/subject/26941639/
[8]
https://snailclimb.gitee.io/javaguide/#/docs/operating-system/basis: https://snailclimb.gitee.io/javaguide/#/docs/operating-system/basis