从决定转IT那天到现在,已经四年了,一路上经历了许多的坎坷,困难,直到现在终于略有收获,找到了一份满意的工作。期间走过许多弯路,吃了很多亏,也有很多反思和感悟。
决定转行的那天是2014年10月7日,距离那年的考研还有81天。原本打算考体育专业的我,和家人以及老师做了一些分析以后,决定转行考软件工程。但是那个时候我根本不知道自己面对的是什么,从没学过高数,只有一点点少得可怜的c语言基础(计算机三级的水平),不知道数据结构为何物,更不知道软件工程是个什么,甚至计算机科学和软件工程的区别都不知道,但是我当时知道的是,我喜欢写程序,也希望能把一辈子的经历用在软件开发上,无论前面的路多么难,我都想试试。
第二天,我买了高数的课本和线性代数的课本,开始了自学高数的道路。艰难异常,花了整整一个多月的时间我自学完了一元函数积分学,又花了半个月的时间看完了线性代数的前三章内容,政治在考前借同学的复习资料看了一周多,英语也看了不到一周左右的时间(前两个月有在背单词)。这个时候只有四天就要考研了,专业课还没有开始预习,不过那年的主要目的是去试水,看看体形,以及看看自己究竟有没有能力读软件工程。四天的时间,从基本的线性表开始,看完了链表,堆栈,队列,并且用c++实现 了部分内容以后,我就上了考场。第一天还好,虽然自己很烂,政治大题基本不怎么会写,但是还是挺过来了,但是第二天上午就尴尬了。课本上那点东西根本不足以应付考研数学这个庞然大物,大题根本看不懂题目,选择题蒙了一下,填空题把选择题的选项抄上了,大题只写了三步洛必达法则(我当时能记得的也只有洛必达法则了),非常尴尬的熬过了三个小时。下午专业课的感觉还是不错的,至少写上来了一半的内容,剩下的题目我也把题偷偷抄在了准考证后面,准本回去以后重新看看,然后来年再战。当年的考研成绩是数学11分(多优秀的成绩)英语政治都是四十几,专业课88分。看到专业课成绩我知道自己应该可以,于是决定再战一年,但是大四的下学期一堆乱七八糟的事,加上毕业论文,学车,毕业,一直到了六月份我才开始安心的复习。报了新东方的考研政治班和数学的网课,一路跟下来,发现自己的数学依然很烂,平时最多考到110分,最低大约80左右。不过这个分数对我来说已经足够了,因为我对自己的专业课、政治还有英语比较有信心。考研结束以后,我看了政治的选择题答案和英语的答案解析以后,知道自己的英语政治肯定没问题了(政治选择题估分40)。但是数学,很糟心,因为2015年那场考研数学应该是有史以来最难的一次,我全程处于懵逼状态,除了自己学的确实很扎实的线性代数能做对大半意外,高数又一次把我虐了,自己估分53分,专业课因为调整了大纲,加了一章内容(图),而我恰恰没复习,所以最后20分的题目我基本就是不会,最后给自己估分110~120之间。当时做出的结论就是,数学单科能过,我就能过(SDU的数学单科线75分)。
成绩出来以后,果然数学挂了,59。于是又参加了调剂,被调剂到CDUT,那一刻其实一直很感激我的导师把我收了,否则我可能真的永远离开IT了。开学以后,学习也算比较努力,但是因为研一上学期拼命过度,第二年频频跑医院,根本没有多余的能力去学习。不过好在成绩不算太烂。
研究生期间主要还是在自学,从入学的第一天我就在找自己的兴趣点和研究方向,并且在不断的学一些自己认为比较重要的知识。其实我走了很多弯路,但是这些弯路给了我很多教训。比如我在学习双目视觉的三维重建的时候,不甘心于仅仅恢复深度图,于是凭空想象了很多方法,结果都不行,后来才知道,很多相关的算法都很成熟了,自己还以为在改变世界。所以从研二下学期开始就把学习的重点从课本转变为了论文。那是第一次知道论文的重要性。关于技术方面,我觉得最有必要学习的就是汇编语言和Win32编程。把很多底层的东西搞懂以后,再学习高层的东西会有更好的理解。
我自学编程的经历其实是在本科的时候。c++的基本语法必须要好好学,我推荐一本书《c++高级编程 第二版》红色的,这本书真的特别棒,对我的帮助很大。其实学编程真的没有什么太多的技巧,语法只能靠多练,很多底层的东西要靠自己理解,并且多查资料。好多人害怕接触底层,拒绝深入,觉得语法会了就可以。但是不搞懂底层的内容,很多时候会出现理解的偏差,并且底层原理可以帮助自己记忆一点语法(比如指针,指针是我觉得c++最好用的工具,没有之一)。另外一本书是《Windows程序设计 第五版》这本书我找不到正版资源,从某宝买的打印版,内容特别好,有兴趣了解win32编程的小伙伴可以参考。JAVA的学习书籍我没有看过,因为我发现慕课网是一个很好的课程平台,上面的JAVA课程免费,而且比较全面,虽然很多东西不是最新的技术,但是入门和打基础是足够了。个人不太建议把python作为学习的重点,虽然大家都说python各种好,各种流行,各种火爆,但是它对于计算机模型的理解基本没有什么帮助,踏踏实实的把c作为入门语言真的是最好的选择。有人说c好难,简单的东西大家都能学会,学会了有什么竞争力。人人都会的技术就不叫技术了不是。学会了编程语言,就该上手数据结构了。个人推荐《数据结构 算法于应用 c++语言描述》代码示例很清晰明了,习题非常经典有趣,很值得学习。当然,无论什么语言,都需要学习数据结构,并且从头到尾实现一遍。不要告诉我有list,array,hashmap这些东西可以直接用。如果需要自定义部分功能怎么办?到头来还是要自己写。并且,把那些很好的工具当作黑盒来用,我会觉得不踏实,因为不搞懂原理我会不知道该在什么地方使用。如果有兴趣了解算法的相关内容,有两本书可以参考,一本是《Algorithms》这本书是用JAVA语言描述的,可以作为数据结构的补充本,英文原版有点小贵,我在亚马逊买的99刀。淘宝好像有中文版。另一本就是经典的《算法导论》用的是伪代码,后者较前者内容丰富,难度大一点。
很多人在犹豫或者考虑要不要造轮子。我的想法是,在时间允许的情况下,用尽全力的造轮子。即使轮子很差,至少你会更好的体会到经典框架或者代码的魅力以及精华,并且提升自己的代码能力。很多东西不自己动手实践一遍根本不知道其精华所在。比如我把KFC电玩上校里面的小游戏写了一半(小朋友可能都不知道那是个啥)自己尝试过用Win32最基本的setpixel函数写了一个三维投影的程序(OpenGL最基本的功能)。虽然这些东西没什么意义,但是真的可以锻炼自己的代码能力。
三年的研究生生涯拿到了学业三一二等奖学金(每年一个)并且在今年的秋招遇到了一个我认为比较赏识我的老板,老板人真的很好,亲自进行技术面。终于,我拿到了offer,薪水虽然在班里只能排中等,但是也让我狂喜了好多天,毕竟如果我没有读这个研究生,我可能只能做一个健身教练(健身教练这份工作也很不错,但是我不太喜欢和人打交道)。虽然这份工作要与我学习了一年多的SLAM告别,但是我可以学到更多新知识,并且,SLAM可以作为我的兴趣点,关注一辈子。而且,有了研一的经历以后,我找工作的第一要求就是不加班(拒绝996,拒绝995)。毕竟活着才是硬道理,而且,没有自己的时间,也没有机会提升自己。
曾经我一直以为自己是因为在计算机方面有天赋,所以才会取得比较快的进步。但是回想起来,发现自己仅仅是因为兴趣,比别人更努力了一点罢了。能力这个东西真的是需要用时间去打磨的,即使智商超群, 没有长时间的训练和思考,也无法取得很高的成就。研究生期间有很多遗憾,没有一篇高质量的论文,没有找到SLAM方向的工作,没有早一点找到一个领路人。所以,还是希望更多人能尽可能的避免这些坑吧:
1. 多看论文,多看博客,多参加学术论坛,多向高手请教,不要以为自己在改变世界,因为这个世界上的大牛真的太多太多了。
2. 好好学英语,主要是专业英语,因为好的文章都是英语的,无论是国内还是国外的学者,因为SCI大多数就是英语文献,排斥英文文献将直接限制自己的眼界和能力。
3. 多练编程,我认识很多本科生以及研究生,连二叉树都不能独立完成。如果没有编程能力,除非你有很强的数学能力,否则公司凭什么要你呢。
4. 提升数学能力,数学让我在考研的时候吃了很大的亏,所以我也是在研究生阶段花了很多时间补数学。其实工程上用的数学很多时候可能不需要很强的计算能力,因为计算机的计算能力肯定是比人强的,但是要把公式概念理解透彻,至少做到在paper中看到一堆公式,能够知道这些公式是怎么得到了,如何去推导,如何去实现。否则就会错过这篇文章的精华部分。一篇论文里面的内容(或者部分内容)只有自己动手实现一遍才能知道其真伪(国内学术造假这种事真的不想吐槽了),并且完全理解透彻。
5. 要有输出,多写开源代码和博客,这样可以把自己的学习经历分享出来,也可以让自己把自己觉得理解的最正确的内容记录下来(毕竟别人要看的,太垃圾了自己都不好意思拿出来吧)。很多时候自己还是太懒了,不想整理,而且在CSDN上打公式好麻烦……多分享,对自己和别人都是一种提升。
6. 不要局限在某一种语言上,语言只是工具,算法才是核心,数学才是王道。我中途有过转JAVA和python的经历,有了c++的基础,学习新语言很快,而且有汇编基础,对很多模型的理解也会比较快,所以不要总是纠结于选择什么语言,学好了算法,多去写程序,明智的老板不会卡你的。
7. 如果准备考研,一定要去好学校!否则那些国企大公司连简历都不会多看一眼,如果没有顶会顶刊,好的独角兽公司依然不会多看一眼,如果学校不好,多在牛客网上练编程,这是弯道超车的最好方法,因为公司也不知道那些笔试做的好的人究竟是真的强还是仅仅就会那几个题,然后参加现场面试现场笔试的宣讲会,能力强自然会有好工作。我的同班同学今年拿到了32W的年薪,还是能力决定一切。