大学四年的总结和回顾

0x00 前言

Wow,好久没用Markdown写文档了,着实有点不习惯是真的,最近一直忙着考研调剂、找工作、毕业设计等等杂事。一直在用 LATEX\LaTeX 撰写文档,突然转换成Markdown还真是不习惯呢。说实话最近确实迷上了 LATEX\LaTeX ,不因为别的,我就喜欢它排版文章出来的工整,这种工整是用其他工具所无法比拟的。

想总结一下大学这四年,得到了什么,失去了什么,犯过哪些错误,做过哪些正确的决定,站在上帝视角回顾一下这四年的生活。Every mistake is a wonderful revenue!

0x01

大学四年做过的最正确的决定当然是大一的时候在任老师的引荐下加入了他的实验室——那时候还叫“CIL(校企协同创新)实验室”——后来实验室因发展的需要和硬件方面的一个实验室合并,组成了一个大的实验室——智能装备实验室,然后就认识了很多学硬件学通信的通信。大一刚加入实验室的那会,每个新人都要选一个研究方向,当时没和硬件方面合并,实验室有3个大方向:C++, Java Web, Android,因为比较熟悉和喜欢C++,加入时,我选择了C++方向,加入后我才发现,原来C++方向的那个学长已经找到实习工作走了,我成为了唯一一个C++方向的,没有了学长的指引,整得我学习很迷茫。说来也奇怪,当时居然是一个学Java Web的学长来带我,他和我说,要去学一些框架,Java里面有Spring等等框架,C++也应该有这样的框架,他也不懂,让我自己去查查资料,学一些C++的框架。我想做Windows开发,然后查了很多资料,我只发现了一个问题,就是C++貌似并没有像Java中的Spring这样具有普适性的框架。而我所知道的可以称得上是框架的东西可能就只有微软出的MFC吧,而这个东西在网上也是褒贬不一。后来,查到了一些资料,可以用Visual Studio自带的spy++工具来分析一个程序用的什么“框架”,我分析了一下QQ,结果发现,分析出来的类名居然是腾讯公司内部实现的一个UI框架,显然这不是开源的。后来又去网上搜,迅雷公司开源了它的bolt界面引擎,学学这个?但这又太面向一家公司,我当时的想法就是试图在C++的世界里,找到一款像Spring这样的普适性的框架。现在看来这种想法完全是错误的,以至于我在上面走了很多弯路,也没有成功。这给了我一个教训:

不要让不同领域的人来指导你的学习和工作,尽管这个人所从事的领域可能和你相似,可能是他所从事领域内的大牛。例如,不要让学Java Web的来指导你学C++。

后来,我就很崩溃,不知道怎么学,不知道怎么深入,这是很令人难受的一段经历。后来得知,大家普遍都觉得使用C++来做Windows程序的界面UI,实在是太费劲了,很多人不乐意这么做,然后就有了electron这样的内部基于Chrome浏览器的桌面端程序框架,而且当时还得知了迅雷的bolt引擎内部是使用lua语言来进行一些必要的业务逻辑处理的。学一学lua?于是我又进行了一波大胆的尝试。学lua学了一段时间,一是感觉弱类型的脚本语言很难用,二是感觉对我的学习并没有什么实质上的帮助,我当时甚至都不知道lua语言主要面向什么,主要用来解决什么问题。人的记忆力总是有限的,现在看来,我对lua语言的唯一印象仿佛就只剩下它的数组是从1开始的。这让我得到了另一个教训:

第一,当你试图打开一个新的技术栈的时候,一定要先了解明白,你学这个是为了什么,主要是想解决什么样的问题或者业务需求。

第二,不要让你的新技术栈偏离你所学的重心太远!要不然就成了大而全,而你真正需要做的是在某一个方面,小而精!

后来又陆陆续续经历了一些挫折,我实验室的一学长,去了美团实习,在美团公司主要从事爬虫开发,说到爬虫,那时候的我有一个刻板印象就是Python不就是用来写爬虫的吗,这个刻板印象导致我在很长一段时间内认为Python就只是用来写爬虫的。恰逢当时我们学校的ACM的代码查询功能坏掉了,导致无法通过查询功能找到自己之前提交题目的代码,只能通过代码提交记录一页一页地找,直到找到某年某月某日你提交的代码。正好当时也跟着看了一点爬虫,于是我也打算学一学,然后做一个爬虫软件,帮我们实现这个一页一页找的功能,于是我又学了Python,当然只学会了怎么写爬虫,用最原始的字符串查找的方式找到你的名字,然后找到代码链接将代码爬取下来。然后我写了一个Python脚本用来实现这些功能,发布到我们班的QQ群里,让大家用,但是仿佛大家不是很懂Python环境的配置,以及执行脚本的过程。于是我又想干脆一不做二不休,写一个C++版的,编译成exe,这样大家点开就能用了,然后又学了libcurl库的使用,做了一个C++的爬虫软件,果然得到了大家的一直好评,尤其得到了想抄袭别人作业代码同学的一致好评。然后我就开始飘飘然了,大家都奉我为大神,学习进入了舒适区,就不愿继续往下,时间一久,人就开始忘记,然后Python也忘了个差不多了,只记得Python有2和3两个版本,而且貌似这两个版本在语法上还有略微的差别,其他的就都遗忘了个差不多的。又印证了那句话,人的记忆力总是有限的。总结一个教训:

褒则常然,贬则泰然。听到别人的褒扬时,千万不要飘飘然,使自己的学习进入舒适区,舒适区是很难让人跳出来的。要对知识充满敬畏,要看清与别人的差距,即便周围的人水平真的不如你,那你也要与社会上的竞争对手进行比较,要知道人外有人,山外有人。总有人在你喜欢的各方面都比你厉害。保持劲头,不断学习,这才是最重要的。否则现实版的“伤仲永”的例子就会不断在你身上上演,到最后的结果也只能是泯然众人矣。

后来,看到实验室一学长,弄了一个个人的博客网站,用来记录一些技术知识等,感觉还很不错。跟他讨教了一下,知道了WordPress这个东西,然后从国外的域名服务商处买了一个自己的域名,入手了一部最便宜的低配VPS服务器,开始了我的建站之旅,于是就有了www.shaoqunliu.com。WordPress是基于PHP的,为了能看懂WordPress的代码,并从中实现一点自定义的功能,于是我又学习了一下PHP。PHP这门语言很有特色,因为他不安全,很多学信息安全入门的人基本上都是从PHP执行SQL查询语句时的SQL注入漏洞开始的,我也是这么入门的,这着实很有意思。后来我了解到我们学校专门有一个社团叫网络安全协会,是专门从事网络安全方面的相关学习和研究的,然后认识了几个学网络安全的同学,在他们的带领下,我又走上了学习信息安全的道路,显然,这与我最初的想法C++方向已经相差甚远。在学习信息安全的过程中,我一直在玩CTF比赛,做了一些题。因为我们学校CTF网站上的题目都很简单,稍微学习之后,我就在那个平台上拿到了一个可观的名次,正是因为有了这个名次,网协的指导老师赵老师找到我,希望我可以加入他的网协,但是我以当前已经在CIL实验室学习为借口婉拒了他的邀请,现在想想这是一个错误的决定,我错失了一个可以认识更多朋友的机会,而且是一个很好的学习机会。得到的教训如下:

大学里可以加入多个社团或者实验室,给自己一个认识新朋友,开拓眼界,学习其他方面知识的机会,而不是仅仅拘泥于一个圈子。类比想象一下,在社会上其实也是这样的,不要仅局限于程序员这一个圈子,认识更多圈子里的人,想办法融入进去,开拓眼界,才会发现哇塞他们居然还能这么活着,居然还有这么优秀的人。毕竟中国是一个关系型的社会,在社会上,多一种谋生的手段,多交一些其他圈子里的朋友,才会让你有更好的发展。

当时有玩CTF,正好自己有一台VPS服务器, 想着在上面搭建一个DVWA渗透测试平台供大家玩。我就只有一台服务器,当时也还没了解到docker这种东西,我干脆就把DVWA和我的网站搭建在一块了,而且我在DVWA目录下,放了一个文件,说明了DVWA旁边就是我的网站,请大家渗透成功后,不要动我网站目录里面的东西,结果果然有人违反了约定,把我网站的网页目录全都给删了。这个事整得我很生气,我好心在我私人的VPS上搭建DVWA让大家学习渗透测试,DVWA本身就是个充满漏洞的平台,而且网上有大把的有关DVWA的渗透教程,但是还是没想到有人做了这种事,这个事整得我抑郁了好几天,幸亏我有定时备份WordPress的习惯,才没丢失我大部分的博客。从那之后我退出了他们的圈子,因为我不想和一些道德上说不过去的人在一个圈子里。

信息安全里有一个准则就是不要相信用户传送过来的数据,这本是在提醒开发者数据要在后端做进一步的检验,但是这同样适用于现实社会,不要假定对方道德品质高尚。

后来就到了大三,学校开设了一门课程叫Java框架编程,在学习这门课程的时候接触到了服务端开发的SSM三个框架,更深一步地理解了这几个框架。一开始学Java的时候,我就特别搞不懂,为什么要加入一个反射机制,我有必要通过这样的方式去调用一个类吗?我知道这个类叫什么名,直接调用不好吗?C++里面就没有这样的反射机制。这个问题在我初学Java的时候,确实很困扰我。直到更深一步地理解了Spring的底层原理,我才恍然大悟这个东西的用处居然这么大!

Knowledge is useless unless you know how to apply it.

知识在你发现它的实际用途之前往往是无用的。

在不知道这个东西实际用途之前,最好耐着性子把它学完,或许随着你学习的深入,你就慢慢发现了它的用途。一个东西的存在往往都是有价值的,只能说明你学的少而已。

话说当时在实验室还接了一个国家级大学生创新创业项目,虽然头顶着个国家级,但感觉依然很水,并没有什么含金量。但是有1万块钱的研究经费,所以就申请了,当然这些钱大部分都给了导师。这个项目本来是想基于C/S架构的,但是做到最后就成了B/S架构,完全成了一个Java Web的项目,本来想前端用C++做一个好看点的程序,但是并没有实现。项目在文档上耗时一年,实则耗时二三个月就开发完成了。话说我们学校的Java开发氛围很重,绝大多数学计科学软件的人,不是做前端就是做Java,当然这其中Java又包括Java Web和Android,少部分人去做了算法,极少部分人在搞C++在搞Windows编程这一块。不得不说,中国互联网的发达,确实也造就了这一切,没办法,我统计过,我们学校开设的有关Java的编程科目就有:Java语言程序设计、Java项目实训、Java Web程序设计、Java与数据库综合实训、Java框架编程技术、移动软件开发6门,而从事其他方向开发的,往往都只有1门,比如.Net程序设计,C++程序设计都是只有1门。Java比其他语言的课程比例在6:1。Java的应用确实广泛,而且学校愿意教这个,作为学生的我本身就在这样一个浓厚的氛围之内,慢慢地也把我熏陶到Java那去了。学Java的时候我就深刻地感觉到了一个问题,在这方面我与我们实验室之前一进入就学Java的同学已经落下了相当大的一段差距,这段差距又是难以弥补的。而且当时已经大三了,不得不提早作出人生的选择了,我感觉如果此时再不积极作出选择,未来等到毕业的时候,我会死得很惨。现在看来这是一个正确的决定:

无论做什么事,都要提早思考好未来,思考好后路,狡兔还有三窟呢,何况是我们人呢。

要说为未来做准备,我有一个女朋友啊,我要考虑2个人的未来。我曾经试图把我女朋友培养成一个优秀的程序员。但是我失败了,她也是学计算机专业的,只不过她的学校比我的差一点。我女朋友学习还不错,GPA非常高,经常因此拿他们学校的奖学金助学金什么的,各种奖学金非常多。反观我从来都没拿过我们学校的奖学金,不管是国家级的还是校级的一分钱都没有。这给我的感觉,她也应该是个学霸啊,而且她也是计算机专业的。我就开始建议她学一点真正的技术,而不是课本上的技术。我一开始建议她学Java,因为这个玩意,大中小型的公司往往都要,就业起来应该较为方便一点。但是我失败了,第一她的执行力比较低下,我让她看的一些技术书籍什么的,往往她看两眼就不乐意看了。第二她在这方面悟性不高,始终保持着高中的学习方法,这显然是行不通的,编程本身就要求你有很高的动手能力,纸上得来终觉浅,但是我女朋友就是不乐意动手敲代码,我曾经试图给她纠正,但就是纠正不过来,因为她动手敲的代码,一经编译错误百出,而且她本身不是很乐意去探索这些错误的起因和去调试这些错误。这给她的挫败感很强,导致她对编程这种工作失去兴趣,她不乐意去学编程。我也没有办法啊,从她身上,我总结出了,学习计算机科学应该注意的如下几点:

第一,纸上得来终觉浅,绝知此事要躬行。计算机科学,本身就是个需要大量动手实践的科目。唯有实践才能出真知。

第二,初学的时候可能挫败感较强,尤其是碰到很奇怪的错误调试不出来的时候,我女朋友有的时候就说,这段代码我明明是从书上原模原样复制下来的啊,为什么就运行不出来呢。抄也是有可能抄错的!必须自己动手,自己去调试,调试能力也很反应一个人的计算机科学素养。

第三,学习的时候要尽量抛开课本,尤其是学校里面用的课本,学习教学用的课本,往往比较老,理论可能没有发生变化,但实现方法和实现过程可能较过去有了较大的出入。要尽量抛开课本,课本唯一有用的往往就是目录,通过目录,列举一份学习的大纲,然后去搜索相关内容,最好去看一些英文的文档,一般的框架文档里面都会有sample,里面会列举一些场景,然后给出实例,个人感觉比较适合学习。

后来,我女朋友开始准备考研,以谋求一个更高的学历。而我这个时候也面临了人生的重大抉择。我这个时候恍然大悟了一个问题,就是我这大学的前三年,从来都没有认真地、深入地学习一门技术。这是我大学期间犯过的最大的错误,没有之一。我的学习成了大而全,而不是小而精。总结一下,我学过C++ Windows编程(只会写一个“带有窗口”的exe),学过Python(只会写一个最简单的爬虫),学过Lua(只记得Lua的数组是从1开始的),学过Java Web(能做一个小型的企业网站,但是涉及到大型的分布式系统,那我就是一无所知了),学过PHP和信息安全(只懂得一些比较落后的SQL注入和XSS手段,而这些手段往往还是较好防御的)。意识到这个问题之后我感觉我过得很惨,感觉走了很多弯路,虚度了许多时光。没办法,过去的光阴,一去不复返,我只能珍惜眼前了。周围深入学习某一个方向,而且不打算考研的同学们,已经开始准备春招,准备找工作了。做过很多项目,写过很多代码,但是就是没有一个可以拿得出手的项目,可以写在自己简历上的 项目。整得我很后悔大学的前几年,为了弥补这一切,我也打算考研。去一个新的学校,找一个新的环境,深入到某一方面的具体研究,真正实现小而精。这就是我当时打算考研的初衷。

一定不要忘记初心,努力学习,要做到小而精,而不是大而全,知识的广度固然重要,但知识的深度往往可以让你进入一个行业,进入一个圈子,决定你在这个圈子里面的等级和水平。所以学习一定不能大而全,什么都学,这世界上这么多东西,这么多学科门类,学得过来吗?况且人的记忆力往往是有限的,千万不要让你现在所学的东西,都是为了以后忘记的。

准备考研的日子是艰苦而又漫长的,首先就是学校的选择。我十分想去北京上学,因为在北京可以见识更大的世界,而且北京有很多互联网公司,日后研究生快读完的时候,找工作也相对方便,面试也都在一个城市内,就是房价贵点。而且我还想上个985大学,以消除日后面试的时候的学历歧视,虽然大家都说,金本科银硕士破铜烂铁读博士,但好歹也是个银的,况且到时候大不了不考虑那些限制第一学历的企业即可,想必也不会很多。经过一系列的比较,最终选择了北京某985高校,然后开始了我的考研生涯。因为选择的目标学校比较好,我也一直没和别人说我考的什么学校,经过大约半年的复习吧,终于到了考试的时间。考试那天,说不紧张也是假的,考完政治,我就很癫狂,因为我发现我背的那些大题貌似只考了一个,完了,剩下的大题我都不知道写啥好,于是我就抄材料,抄完材料,我连选择题的题干我都抄了,为的就是让他看上去像那么回事。考完政治中午回去之后,气得我,当时我发了个说说,我说政治这都考得啥啊,之前背的押题一个没写上,气人的是,当时还有个朋友给我评论“肖秀荣团队五道全中”,他全背上就全背上了吧,他还和我说。整得我下午考英语情绪就不是很好,但是幸运女神也稍微眷顾了我一下,英语的作文还是一个很简单很好写的素材,而且阅读做起来比较有感觉,很不错。第二天就是我最怕的数学考试,我这个人数学脑子不是很强,不是很能学会数学,尤其是看见数学公式头就大,而且还记不住这么多的公式。结果上场之后,概率论的大题说了个什么玩意服从指数分布,真是不巧,还就是忘了指数分布的公式,然后前面的大题也做得一塌糊涂,数学就给我整疯了,整得我下午专业课都有弃考的打算了,但是我一想,还是去吧,毕竟复习了这么长时间,而且还交了180块钱的报名费,不能浪费了不是。然后就这样,考完了所有的科目。第二天,我从网上搜到了网上的答案,然后凭借记忆,对比了一下,估了一下分,心想完了,彻底完了,国家线都过不了了。这时候,就得备灾啊,应对可能发生的灾难。玩了2天游戏,舒缓了一下身心和压力,然后就开始背一些面试题,准备一些算法编程题,开始准备找工作,多给自己留条后路。

备灾是必要的,也是必须的,人只有在不知道自己要干什么的时候才会迷茫。在一件事发生之后但不知道结果的时候,最好为自己备灾,如果干成了那自然是最好,如果干不成,也提前做好应对灾难的准备,争取不当死得最惨的那一个。

后来过了一些日子,考研的成绩出了,显然考得并不高,需要寻求调剂,找调剂的那段时间是最痛苦的,这也让我明白了为什么张雪峰老师说:“一旦你决定调剂,那你的命运将不再掌握在你的手中。”确实是这样的,很多学校一志愿可能报名的人数就不够它所需要招生的人数,所以会事先在官网发出预调剂通知,这个信息确实难找,我百度了一份211大学的名单,然后挨个点开其官网以及相关学院的网站,然后查询相关的调剂信息,以及去年的录取信息,看自己目前的情况是否有可能调剂到此,当时主要的目标是中国科学院大学,找了这个大学的很多所、学院作为参考,但是,大家都知道中科院好调,就导致了中科院调剂的人数爆炸,中科院深圳先进技术研究所,调剂报名人数近900人,而需要的人数只有60人,算过来是15:1,这个比例比很多985高校的一志愿报录比都高了,就导致我们这一年调剂的故事特别惨。而且调剂还有一个很不好的地方就在于,学校之间的复试专业课是不一样的,你根本没法复习,你目标调剂A校,A校复试数据库,可是A校拒了你的调剂申请B校给你发了复试通知,B校复试软件工程,你这就很惨,准备复试笔试的时间往往只有几天,几天是很难系统地学好一门功课的。所有学校唯一相通的地方貌似就只有复试英语口语和听力了,这仿佛是调剂考生唯一可以系统准备的科目了。而且还有个特别惨的事,就在于调剂的时候,你数一英一考了300分,对面一个数二英二的考了310分,这个时候,算总录取成绩的时候就特别惨,你居然和他是一个算法,但是数一英一考300分的难度和数二英二考310分的难度完全不一样好吧,而且各个学校的专业课命题难度也不一样,清华大学计算机考研的专业课题目和二本高校的计算机考研专业课题目难度完全不一样,完全都没有可比性的,可能二本高校的计算机专业课考140分的人去做清华计算机专业课只能得60分,但是调剂的时候,你们两个确实是站在同一起跑线上的,而且比较的就是你的初试成绩,明知道这样会产生不公平,这样的成绩之间是没有可比性的。这点华东师范大学做得就特别好,调剂复试完全抛开初试成绩,调剂复试得分成绩就是你的录取成绩,决定你是否最后调剂录取的总成绩和你的初试成绩完全无关,这是极好的,给予了所有人一个公平的竞争平台,但是其他的绝大多数学校并不是这样做的。

现实的社会中会存在很多不公平的因素,很多时候又是你无法改变的,坦诚面对,冷静分析才能针对你目前的现状选出最优解,有些时候,并不是人没有能力选出最优解,而是在特定的情况下,特定的压力下无法冷静地分析问题。遇到事深呼吸,冷静下来仔细考虑。

选了很多学校,最后中国地质大学(北京)为我发来了复试通知,好歹是个211,准备去复试,其复试笔试的科目是人工智能,这门科目我从未学过,也从未接触过,当时我看到复试通知和我要去复试的时间之间只有3天,我必须在3天之内速成一门我从来都没有学过的课程,而且令人害怕的是今年居然是计算机技术这个专业第一年复试笔试考人工智能这门课,连之前的考试真题都不可能找到,这让人真的崩溃,速成就速成吧,我一开始学这个东西,一开始的内容都是什么推理啊谓词啊之类的东西,跟我之前学过的离散数学这门课程有点像,我以为考试肯定会考这些谓词的化简之类的题目,结果去笔试的时候,拿到试卷我蒙了,居然全部都是简答题,而且都是概念题,一道计算题都没有,我都没背那些概念,当时我扫了一眼考场上的人,大约有50人参加这次考试,缺额10人,5个人里面要一个,看旁边的人都在认真作答,而我坐那发愣,我一想完了,怎么着也不能把我录进去。我就随便写,开局一句话剩下的全靠编。而且白天英语口语面试的时候,对面坐的全部都是外语学院的老师,问我第一个问题我听明白了也回答了,问我第二个问题,当时问题有点长,我都没听明白他说的啥,我就随口问了一句what?,然后对面那女老师对我挥挥手,示意我结束了让我出去叫下一个,也没再重复这个问题,也没让我继续回答,这显然就是凉了,彻底地凉了,无可替代地凉了。再加上复试笔试做得这么糟糕,我一想没戏了,感觉找下一家吧,从北京回来后,我又填报了华北电力大学(北京),然后也给我发来了复试通知,回来没几天,又要去北京,这次复试笔试内容是数据库原理,有了上一次的教训,我认真复习了这门课,而且背诵了相关概念,因为这门课我本科就学过,而且学得还不错,信心也大一点,准备几天,就又一次坐上了去北京的高铁,我还准备了一句I beg your pardon.作为英语口语面试时没听懂老师说啥用来替代what?的“高级句式”。到了北京,下了高铁坐地铁来到昌平区,刚出地铁站,就收到了一条短信,说中国地质大学(北京)为我发来了通知,让我去官网查看,然后我查看了,我原本以为是被拒的通知,点开之后居然是拟录取通知!太高兴了,然后我就这么稀里糊涂地考上了中国地质大学(北京)信息工程学院计算机技术专业大数据智能计算与数据挖掘技术方向的研究生。

有准备总比没准备好,哪怕能留给你准备的时间很短。临阵磨刀不快也光,老祖宗说的话,确实有道理。

0x02

想写一点对研究生期间的看法。首先我现在已经算是比较失败的了,可以这么说,上苍又给了我一个机会,让我去读3年的研究生,但是我这个普通211的研究生总是感觉不会太受人待见。很可惜考研没能上一所985高校,也算我人生中的一个遗憾吧。我现在在研究生这个链条中算是底层,想要被别人看得起就只能努力学习以证明自己。

首先呢得改掉自制力不强这个缺点,我之前去中国地质大学(北京)复试的时候,这个学校离清华大学只有一个街区的距离,我去清华看过,看过人家的自习室,我发现这帮人和我之间最大的差异就在这自律能力上,我的克制力不强,做事有的时候容易分心,这确实是刻不容缓需要改掉的一个毛病。

其次,要完成一些本科阶段没有完成的任务:

  • TOEFL要考到至少95分,最好105分

  • 努力地坚持地由浅入深地学一样东西,要小而精而不是大而全

  • 刷算法题,做ACM,LeetCode上每周的竞赛要能稳定到至少2000分以上

还有一点小小的展望:

我最大的梦想就是去美国,想在研究生阶段获得一个微软亚洲研究院或Google中国的实习机会,主要就是提高自身能力和英语水平吧,当然目前H1B抽签的概率比较低,而且貌似这个概率还会持续走低,希望能拿一个国外公司的offer,然后去抽一抽H1B,即便概率比较低。如果英语成绩进步较快的话,考虑研一这一年申请一下国外大学的研究生,研一申请不下来就算了吧,省得耽误太多未来。