结束了为期三个多月的秋招,决定在学生生涯的最后阶段对自己的技术栈做一个整理,第一篇首先从硕士三年的学习规划谈起吧。
先做一个简单的自我介绍,博主本人就读于上海某高校计算机专业,科班出身。热爱存储与虚拟化技术,在相关领域有一定的技术积累,包括数据库、rocksdb存储引擎、文件系统、NVMe driver、虚拟化以及kernel by pass技术。在秋招中有幸获得阿里、腾讯、百度、Intel、网易互娱、金山云等公司的offer。
“凌一”是为自己将来入职阿里云起的花名(不过估计已经被占用了),其寓意一是指“会当凌绝顶,一览众山小”,告诉自己要不怕困难,努力向上攀爬,只有克服一切艰难,才能看到最美的景色;其二是指计算机中的“01”,让自己在工作学习中要站在计算机的角度来思考问题。在此希望能够为未来的同学介绍一些硕士期间的学习路线,希望大家能够有效利用三年的学习时间,积累自己的技术栈。
1. 确立目标
大家刚入学,首先要对自己未来三年后的规划有明确的目标。对于一般人来说(对于一些大神除外),无非主要关注两种选择,一是未来能够加入到喜欢的公司继续搬砖(工程型),另外一种是希望能够继续读博士,参与最前沿的科研,将来能够将自己的学术成果发表在顶会上(学术型)。只要大家能够确定自己的目标,制定相应的学习计划,坚持下去,就一定会有收获。当然,在自己刚入学还在迷茫时候,可以试着尝试先选定一个努力的目标,只有试了才知道自己适不适合。博主本人属于工程学术兼备型,硕士期间三篇paper,在工程上也有一定的自我实践。具体的学习规划后面将详细介绍。
2. 制定规划
在这不具体介绍每个专业的学习规划是什么,因为计算机方向实在太多了,对于每一个方向都要涉及到特别多的技术积累,在这是讲不清的,况且博主对其它方向也不是特别熟悉。在这里主要告诉大家,该如何摸索自己的学习规划,坦白的说,就是在这个方向上我如何学哪些东西,才能在将来秋招大队中显示出自己独特的地方。在此以博主自己的“存储”方向为例,来说明如何摸索。
基础知识
基础知识相当重要,主要是计算机相关的必须课,如语言相关、数据结构、操作系统、数据结构、计算机网络等。基本上对于所有的计算机方向来说,都离不开上述基础知识。虽然说把这些学好,貌似还做不了什么成就出来,但没有这些基础知识是万万不能的。然而,大多数同学对基础知识还有很大的误区,认为所从事的工作就是以语言划分为主的,本科加硕士七年时间,只要熟练掌握一门语言,例如Java,未来就能胜任一份工作,这是远远不够的。编程语言是计算机学科中最重要的一项基础知识,也是做其它事情的先前条件。就好像刚出生的小孩子一样,学会了走路说话,似乎还不能自己独立做一些事情,然而如果连说话走路都还没有达到的话,还说明还是需要很多的时间来成长的。其实编程语言是大二就应该熟练掌握的知识,而且至少需要会三种不同的编程语言。个人认为,语言只是基础,必须熟练掌握,没有哪个语言好,哪个语言不好。各类编程语言(C/C++、Java、Python、Shell、Golang等)都是相通的,不存在会不会的问题,团队需要什么,老板需要什么,大家就用什么,即使不熟悉的,看个两三天基本就应该可以上手工作了。
以存储方向为例,这是我遇到的各种编程语言的使用场景:
C:底层基本都是用C写的(例如文件系统、driver),C是我个人使用最多的语言。
C++:由于喜欢钻研数据库的源码,因此如果要自己动手修改MySQL内核、Rocksdb引擎等,都必须掌握C++。否则源码看不懂,自己改内核也无从下手。
Python:因为在论文中,博主经常会遇到一些算法方面的研究,因此在模拟各类不同的算法时,经常会选用Python最为测试语言。
Shell:由于经常操作Linux,对于一些经常使用的集成测试,都会手写shell脚本来完成。并且针对一些有规律的重复性操作,自己经常会写一些shell脚本来控制,大大提高了自己的工作效率。
Golang:由于在深圳某T公司实习的时候,项目需要优化Kafka的客户端,因此使用golang进行重构,虽然之前没接触过golang,但看了一天教程,基本第二天就直接开始用golang来coding了。
此外还有数据结构、操作系统等,此处不再多叙述,如果在基础知识方面还很欠缺的话,建议多花额外的时间补习。
必备工具
熟练掌握各类工具真的是事倍功半。最早的时候没有在这方面投入很多精力,导致失去了很多东西。因此建议大家在自己方向上的必备工具一定要花时间去学习,这是未来在效率上和别人竞争的神器。下面还是以我的专业"存储"方向为例,来说明工具的重要性。
在做存储相关的技术时,经常会遇到行一些奇葩的bug,例如I/O hang,segmentation fault等。此外,存储方面大部分的主要关注点是性能的提升,因此不同的类型的性能评估测试也是必备项。此外,对于经常写代码的同学来说,好的编辑器,例如vim,各种调试、测试工具都是必不可少的。
- fio: 大名鼎鼎的fio,用来直接评估裸盘以及文件系统的I/O性能。
- perf:可以用来生成火焰图分析程序中的热点函数以及CPU使用率等,直观的分析出程序中的瓶颈以及问题所在。
- cgroup:在做性能评估的时候,经常会遇到为了达到真实的使用场景,用于一些资源限制,系统资源分配管理的工具。
- gdb:Linux下编程,尤其是系统软件,都离不开gdb的调试。尤其经常遇到segmentation fault的时候。熟练的使用gdb决定了debug的速度。
- valgrind:程序检测工具,就算再严谨的人,难免会遇到一些疏忽的意向不到的错误,例如memory leak。因此,熟练使用这类工具能够保证代码的质量,提前解决一些意想不到的bug。
- vim:vim真的是特别强大的编辑器,尤其是在Linux环境下工作的同学,vim的常用配置方法以及各种快捷键都是必须要熟练掌握的技术。
此处不再一一介绍,主要是向大家说明工具的重要性。
提升阶段
在有了牢固的基础知识以及熟练掌握各类神器工具之后,后面需要开始进阶学习,并不断的动手提升自己。
首先是基本的进阶,就是一些常见的算法与编程。建议可以通过在各类编程平台上动手练习(例如leetcode),一是锻炼自己的算法思维以及语言的熟练度;其次是学习其它大神的写代码规范。如果能够坚持一到两年,每天至少一道题的话,会有很大的提高,这个过程是量变到质变的过程。
其次是阅读学习一些优秀项目的源码,如果能够将一个项目理解到一行行代码程序的话,才是真正的学习到其精华,并且能够加深对其的认识。例如,我们都学过操作系统,知道操作系统基本的线程管理、内存管理、I/O系统等。但都是理解在文件概念的层面,如果能够深入内核源码,去细细品味每一个子模块,每一个数据结构的话,对个人的技术来说是很大的提升。例如,在博主大四的时候,便开始阅读Linux内核文件系统与内存管理相关的源码。当然,当你第一次看这么庞大的项目的时候,一定是一脸懵逼,不知所云。所有人都会经历从不会到会再到精通的过程,没有人第一次看就能直接看懂的。我们要做的是,坚持不懈。在别人看电视剧的时候,我们在看源码,在别人玩游戏的时候,我们还在看源码,在别人逛淘宝的时候,我们还在看源码。所以当别人在最后抱怨太难放弃的时候,你基本已经上道了。
博主在硕士期间精读过多个优秀项目的源码,ext4、blobstore、Redis、Rocksdb、SPDK、DPDK等。
进阶学习
要想在相关领域内学习到最前沿的技术,个人认为有两个最佳的渠道。一是各类开源社区,二是各类计算机顶会的论文。
首先从开源社区谈起,虽然我国互联网的发展,越来越多的大公司开始倡导去IOE,因此随之而来的是各种开源项目的不断崛起。而且越来越多的企业开始使用开源软件作为底层服务软件,并且为了更够更加匹配公司的实际业务环境,越来越多优秀的开发者加入到开源社区当中来。因此,为了学习到这些新技术的发展方向,要时长关注各类社区的动向,最好能参入其中。首先,若想了解到更多的未来发展方向,可以订阅社区的mailing list,看社区中的大牛经常会提出什么讨论,新的patch等。其次,再不断的学习相关源码的时候,试着做一些优化,可以向社区提patch,来参与其中。对于大家来说,这个刚开始不容易上手,可以选择先从文档和注释做起,比如有一些文档写的不够全面、不够规范,或者有一些必要的地方缺少注释说明,这些都可以作为一个贡献去向社区提request。在逐渐的更加熟悉后,可以经常关注该项目的github issues,看是否有一些bug需要解决,可以尝试帮着社区解bug,其次也可以针对一些该项目缺少的功能,自己进行开发,向社区做贡献。这是一个很好的学习路径。
其次是各类计算机顶会。各大公司和名校的最新research都会发表在一些好的计算机会议上。要经常关注每年的会议,精读自己感兴趣领域的最新研究。例如,博主是学存储方向的,因此经常会关注一些系统和数据库方面的会议,例如FAST、OSDI、VLDB、USENIX ATC等。例如,经常阅读这些顶会的论文,你将会发现,如今LSM Tree、用户态软件栈、Open Channel SSD、RDMA、NVDIMM等,都是目前近几年无论在企业界还是学术界都特别关心的技术。通过阅读学习这些优秀的论文,一是能够学习到其中精妙的系统设计,二是能够学习到很多表达的技巧(包括presentation、做PPT、画各类图等),这些积累都是特别重要的财富。
其次,无论是参与到开源社区中,还是精读论文,都需要有一个良好的英语基础。无论是阅读、写作、还是听力和口语都是必不可少的。因此,每天留出额外的时间去学习英语是比不可少的。博主本人在这方面就有些缺失,因此目前仍在不断努力加强中。
4. 核心竞争力
确立了目标与学习计划是远远不够的,态度决定一切。最主要的还是脚踏实地,一步步地去学习。当然,学习的过程中难免会遇到很多困难,最主要的还是坚持不懈,勇敢的去战胜困难。要向优秀的人看齐,不要被外界的东西所打扰。例如,书还没看两页,就去打游戏了。刚配了一个环境,遇到点困难就放弃了,转身去看电视剧了。这样是万万不能的。
要有坚定的和果断的意志。以博主本人硕士期间的生活举例,通常周中晚上都是12点、1点睡觉,早上一般都是7点吃过早饭就坐在实验室了。中途从不玩手机、不打游戏、不看剧、不逛淘宝的。但是周末喜欢出去疯玩两天,周末除了特殊情况需要加班加点赶论文外,一般情况周末是不去实验室的。因此,可以做到劳逸结合。但个人非常喜欢技术,曾经,修改一个开源项目,自己琢磨到半夜,在遇到问题真的很难过,但在自己的坚持下,当新的功能可以完全跑起来的时候,半夜回去趟下都激动不已,难以入眠。
有疑问加站长微信联系(非本文作者)