计算机科班出身有优势吗?答案自然是肯定的。
先讲语言:大学本科期间唯一一门语言必修课是C语言。其他的语言统统都是选修或自学。用的当然不是谭浩强的教材。考试是机试:程序输入过测试点,和leetcode等方式是一样的。很多同学觉得很残忍,一个小错误可能就导致考试不及格。老师讲过一个故事,说他和北大的老师讨论,北大老师说:怎么可以这样呢?明明程序大多数都写对了,怎么能一分不给呢?老师说:这就是工科和理科的区别吧。你不能说火箭大多数都对了,只是错了一颗螺丝钉。那就是一分不给啊。说白了语言就是一门工具,举一反三的家伙,多数科班教育都不会把语言特性作为育人的重点。
离散数学:离散数学算是计算机基础数学。主要包括集合论、图论、数理逻辑等。图论算是比较贴近实际工作的部分,毕竟有很多图算法。集合论貌似是最远的,但却是一切的基础,如笛卡尔积的概念,我最早一直不知道有什么用,直到学数据库,上来就说join(广义的,而不是只指自然连接)操作就是笛卡尔积,顿时恍然大悟。数理逻辑包括命题逻辑、谓词逻辑等等,在人工智能领域是用得着逻辑推理的。
算法:我校的算法课程不是一般意义上的讲具体算法,而是讲的算法的一些种类、思想、理论。比如讲divide and conquer,讲概率算法、随机算法(很多人是分不清这两者的)。讲快排在什么情况下最慢,讲通过随机算法(随机快排)来减少最坏情况出现的概率,讲快排和插排切换使用加快排序。概率算法,比如hyperloglog,布隆过滤器都是通过牺牲精度换取巨大的性能提升。所以算法课的价值和刷算法题是不一样的。讲真,除了少数情况,多数算法都有成熟的库实现,并不需要你裸写一个。应用的时候,你知道有什么样的算法,用什么样的思想能解决问题,比你会裸写出来重要100倍。
形式语言自动机:乔姆斯基文法类型。大家都爱用正则表达式,但是正则表达式所对应的正则文法到底能做到什么?是万能的吗?如果不知道,有的根本实现不了的功能就还可能在绞尽脑汁想怎么写个正则表达式。比如正则表达式能解决括号配对的问题(左右括号一样多)吗?对不起,不行,要上下文无关文法才可以。又如,我见过有同事面对一堆的状态纯手撸代码的情况,逻辑不是这儿有漏洞就是那儿有,一直搞不定bug。其实,纸上画一个有限状态机,状态转移图一画,逻辑就理清楚了。
数据库原理:3NF,4NF,BCNF有什么区别?对不起,我也不记得,但是我知道有这个东西,需要的时候我可以去查。一般来讲,一个数据库系统3NF是需要的吧?也有为了性能需要一些冗余的情况,但就必须要注意好数据一致性问题。我是见过什么范式都不满足的数据库系统(当然,1NF还是有的。。。),维护起来一团糟。
编译原理:嗷,这个可能是很不接地气的一门课了。高级语言满天飞的今天,有多少人还需要编译原理或者汇编这样的知识啊?但我们学校的编译课,可是硬生生要求大家实现一个PL0文法(Pascal文法子集)(和C0文法穿插着来,防止学弟学妹直接抄上一届学长的作业,也是用(sang)心(xin)良(bing)苦(kuang))的编译器,要想拿优还要实现一些基本的编译优化。这种知识,多数情况下是用不着的。但是当你的代码面对性能问题的时候,你会发现有时候面向编译器的代码优化有时候能更好的提高性能。有时候写框架,需要用到代码生成,那么这时候懂编译原理也能有所裨益。
接下来是考研必考的三门专业课:
计算机组成原理和操作系统:这两个放在一起说,是因为他们有很多互相交叉的部分。考研面试常问问题:从你按下电源键到登录到底发生了什么?计算机存储的层次结构?硬盘、内存、cpu cache之间的关系、缓存、交换。这些对代码的优化还是很有好处的。举个例子:大数据领域常用的消息中间件Kafka,数据都是落在磁盘上的,但是却提供了超高的读写性能。其原因就是强制使用顺序读写,充分利用了操作系统Page Cache,这种思想和实现,没有扎实的计算机基本功是做不到的。操作系统的调度算法可以在写“大数据”任务的调度算法时有所参考。了解double,int等数据的存储方式,可以避免计算时不必要的精度损失(比如大数加小数)和提高性能(比如用位移代替乘除法)。又比如为什么有时候存储时有的框架看似多存了几个字节反而性能好了?这多半是用了对齐,提高了cpu cache的命中率。这些有都是需要计算机基础知识的。
还有一点是避免闹笑话:某本Spark书,将ListenerBus理解为Listener 公共汽车,还觉得“巧妙”:
但凡学过计算机组成原理的都应该知道,bus在这里应该是“总线”的意思(计算机里一堆总线,很多这个概念的提及)。强行抖一波机灵,说是公共汽车,到站就下车,实在是贻笑大方。
网络:网络也是个设计非常巧妙的东西。滑动窗口机制、慢启动快重传,都是在消息传递的时候非常有借鉴意义的设计。前段时间排查一个错误,涉及到socket的问题,我就强烈怀疑是和滑动窗口机制有关,遗憾的是,由于时间和精力关系,没有进一步跟下去,但能往这个方向想,就本身是需要有这方面的基础知识的。
当然,科班的这些优势都不是绝对的,只是平均上讲会有一些优势。毕竟这些东西都不是壁垒。我认为程序员是一个入门容易精通困难的职业。其实很多职业都有这样的特性吧。