计算机专业的“万金油”知识? | 青山随笔

今天有位学弟 @Vash 问了我一个问题:

雨峰学长好!学弟最近比较迷茫,有一件事情想请教😁

现在前端框架越更新越多,更替也比较快,虽然有些框架可以快速入门,但是无疑当框架过时了以后,也付出了时间成本。在高速发展的年代,对于2020年毕业的我们,也不能预知未来,倒也不是为了功利性地哪个火就学哪个,我还是希望以后在工作中,多利用本科期间学到的东西。所以请问学长,您建议学习哪些类似数据结构、算法这种以后肯定多少会用到的“万金油”知识呢?十分感谢😊

能被咨询这样的问题我很开心,这种信任感对我来说是无价的。这个问题对于学计算机专业的同学们来说很有代表性,也是我曾经的困惑,直至今日也仍在探索这个问题的答案。我从我个人的经验出发,对他的问题做了回答。

以下是回答。

-–

首先我想说,你的文字表达能力很好,能把问题的背景以及自己想获取的答案描述的很清楚,作为一名程序员,你已经有一个很好的起点啦。

你的这个认知也很到位。我相信你如果和同届2020年毕业的同学们交流这个问题,他们中不少人应该是并不知道你在说什么,甚至对这个问题不感兴趣。总的来说,建议在本科期间尽可能学习好关键课程的知识,并积极锻炼自己的通用能力。

那么具体什么是“关键课程”和“通用能力”呢?

-–

先说关键课程。你绝对听过一种他人给你的建议,就是说大学中的所有课都很有用,都要好好学。我要说的是,你应该识别出哪些课对你来说是重要的,哪些课不是,然后把你额外的精力用在学好那些重要的课上。当然,如果一个人自认为没有这种识别的能力,那最好还是老老实实把所有的课都学好,以免把这个建议当做不好好学习难课的理由。

对于不同的人来说,关键课程是不一样的。比如对于要出国留学的同学来说,要拼GPA,所以所有课的成绩都很重要,哪怕一门通识选修;对于要考研的同学来说,也许是高数、线代、英语、数据结构等。听你这意思,你是想本科毕业后就工作,我特别支持。对于要找工作的同学来说,我建议尽可能学好计算机网络、操作系统、软件工程、面向对象编程、数据结构、数据库原理这些课。至少这些课的知识对我来说,都非常需要,而且后悔在学校期间没能学的更好。我会介绍一下为什么这些课对我的工作来说很有用,以便给你一个直观的感受。毕竟,在校期间的一个最为常见的问题就是“这门课在将来有什么用?”。注意,这些课的重要程度排序只是对我的工作来说的,并不能代表所有后端工程师,或者程序员们的工作。

顺带一提,对于有志于从事前端的同学,我感觉前端对框架的依赖可能会更大一些,所以这些课程的重要性也许会适度减小。比如,我前段时间接触了一下前端的React框架,真的是刷新了我的认知,原来前端已经是一个非常复杂的世界了,而不是我印象中的HTML+CSS+JS构成的前端页面。对React、Vue这些前端框架来说,学习确实是需要成本的。

如果是想做iOS、Android客户端开发的话,我不是很了解,感觉他们前后端都干。如果是有志于从事人工智能、机器学习、算法这类高端方向的话,那数据结构、概率论、线性代数、算法等课程的重要性肯定是要排在前面的了。咱们接着说这些课。

-–

计算机网络。我在工作中经常接触TCP/UDP、路由转发规则这些内容,常常有一种“这触及到了我的知识盲区”的感觉。有时候遇到BUG进行调试,如果相应的基础知识不够,就真的只能是随缘调试,因为基础知识不够到位(无法缩小故障根源的范围),调试技能也不够熟练(无法有效地锁定故障原因)。在我的todo-list上一直有一项,就是读一遍《TCP/IP详解》卷一,我计划在2018年把这事干了。

操作系统。我有种感觉,就是操作系统这门课的知识,是一个普通程序员(白色)能够成为稀有程序员(蓝色)的关键知识。从两个方面来说,第一是操作系统这门课给你介绍的是软件底层的事情。对于大学里的课来说,软件系统的最底层,是《计算机组成原理》这门课,因为组成原理告诉了你软件的指令究竟是怎么转换为硬件的电路的。不过这对日常的软件系统来说又太底层了,所以《操作系统》是我们绝大多数人的底层。

我印象中主要是两块知识,进程线程还有内存管理。举个例子,我日常使用的编程语言是Golang,也就是Go语言。这门语言有一个重要特性“协程”,是一种更加轻量级的线程。如果在上学的时候就把进程线程这些事学的很清楚了,是不是上手这种高级编程语言的高级特性就更加轻松呢?(两个“高级”的含义不一样)。不过很惭愧的说,我也没法回答这个问题,因为操作系统我学的比较一般。

我们组最近在研究一个叫做“Kubernetes”的技术,简称k8s。k8s是一种分布式技术,我听说一种说法,就是分布式技术很多内容的基础,都是操作系统课程的知识。虽然我还没特别体会到这一点,但我先把这种看法分享给你。

软件工程不用多说,我的工作是软件开发,所以每天都在软件工程中度过。软件工程知识对于个人来说可能不是很重要,但是对于一个软件开发团体来说就非常重要。因为这些知识和对知识的实践能够区分开“软件作坊”和“软件工程”。我推荐一本《构建执法——现代软件工程》给你看看,你看这本书的话可能会觉得一头雾水,我当初看的时候也是这个感觉,书里面的很多东西,是得的等你真正接触实际的软件开发工作后,才能有更加切身的体会。不过提前看看总归是没什么坏处。另外记住,如果有人对你说类似这样的话:“大学学的软件工程课没什么用,在工作里一点也用不到”,不用理睬,这种话毫无道理可言。

面向对象编程、数据结构和数据库原理我就合并到一起说吧。面向对象编程,肯定是躲不开的,不管你将来用什么语言工作。好好理解OOP(面向对象编程)中的那些概念,比如接口等等,反正工作了以后还得补这些课。数据结构和数据库原理呢,比如说数据结构,当你学过时间复杂度分析后,你可能会发现在工程代码里把几个for循环嵌套在一起是个危险的动作,因为没准就产生了一段时间复杂度为O(n^?)的代码。数据库原理的话,比如如果你学过范式,你在设计数据库表的时候,就至少不会设计出连1NF(第一范式)都不满足的表,比如把”姓名,学号“作为一个单独的列名。

给你举了一些例子,总之希望你能感受到这些课的知识对于实际工作都是有用的,而且还不是什么高端的工作,就是我这种普普通通的后端开发工作。另外再补充一点。对于这些关键课程,你学好他们的标准,绝对不是仅仅在这门课的期末考试里拿一个高分。你对自己的要求要更高一些,你要去看该课程公认的经典教材,而不仅仅是学校发的课本;你要用很多课余时间,去仔细地看教材,理解知识并和其他人交流。如果有机会的话,用练习题或实际的项目机会把知识实践起来。推荐关键词:网易云课堂计算机专业课程体系。那是一个知识的宝库,而且对所有人开放。

-–

再说说通用能力。为什么说在大学尽可能积累通用能力呢?

比如编程能力就是一种通用能力。编程能力是和编程语言无关的,看的是你怎么分析问题、拆分问题、处理问题。拆分问题对我来说就是把大需求转换为小函数,处理问题就是写具体的代码。编程语言是一种很神奇的东西,你既可以高效而优雅地解决一个问题,也可以粗糙而不负责任地解决一个问题。有一种说法是,如果想成为一个合格的程序员,应该在本科期间积累两万行代码,你可以评估一下自己的代码量。

还有一些通用能力,或者说通用的软技能,在上大学期间也尽可能锻炼一下,比如与人相处的能力、沟通和表达能力(鼓励你写博客),多读书、多出游,积累见识。因为这些能力在工作后就很难有心情培养了,你也许现在还不信这个事,到时候你如果发现我说的不对的话可以回来拍我。

毕业之前多了解这个行业。如果将来你要进入互联网行业,你不仅需要了解工作的技能,你还需要了解你所处的行业。推荐一本《浪潮之巅》,基本把IT行业给你讲明白了,具体的介绍可以看我以前的文章。

下面这句话我很认同,再啰嗦一次:多了解自己和这个世界的关系,比如我是一个怎样的人?我所处的社会是一个怎样的社会?多点信心,少点戾气。多了解自己愿意全情全意投入的事物,比如自己将来工作了,工作很忙碌,但在工作之余,自己的生活还有没有一个支点和重心?哪怕只是一个简单的爱好。另外就是谈谈恋爱,在爱与被爱中令心智变得成熟。大学是最好的婚恋场所,用心感受这句话。i

俗话说经济基础决定上层建筑,这些“关键课程”和“通用能力”就是你的经济基础,那些框架啥的,如果地基打得好,学起来都很快的。我认为呢,优秀的互联网公司,所需要的应届生是一个优秀而有发展潜力的人,而不是一个马上就能熟练地用框架写出一堆业务代码的人。