首页 > 技术交流 > 从开始到微信/支付宝/Airbnb/抖音Offer(二)

从开始到微信/支付宝/Airbnb/抖音Offer(二)

头像
viseator #面经#
编辑于 2020-06-02 20:26:55 APP内打开
赞 12 | 收藏 30 | 回复5 | 浏览7134

写在前面

首先原谅我用这样的标题来博得关注和点击,因为思前想后也只有我所拿到的Offer才最能在一定程度上代表能力,为我下面将要分享的内容作背书。

在最开始准备写这篇文章的时候只是想像往常那样放在我的博客上作为自己的回忆和总结,不太想去获得别人的关注;但另一个声音告诉我这些东西和之前的技术文章不太一样,这些经验和教训可能可以帮助到很多刚刚踏入校门的新人们,或多或少地产生一些价值。

既然决定了写这篇文章是为了创造价值,那么只有分享出来,让更多感兴趣的人看到才能创造更多的价值,这就是此时此刻你能看到这篇文章的原因。


由于文章的篇幅已经远超最初的预想,所以会拆成几篇分别在微信公众号VirMe发出(确实是公众号最适合创作与分享,还烦请关注),所有文章共用开头部分,特此说明。

个人介绍

笔者2016年高考考入华中科技大学计算机科学与技术专业,同年10月份加入学生技术团队联创团队Android组,后任组长。

2017年底(大二寒假)拿到今日头条(字节跳动)深圳研发中心Android开发实习生Offer,在深圳研发中心实习至2018年3月。

2018年4月加入新成立的今日头条武汉研发中心实习,2019年5月离职。

2019年春招拿到腾讯(微信)、蚂蚁金服(支付宝)、Airbnb的暑期实习Offer,2019年7月加入微信实习。

2019年秋招拿到字节跳动SSP(抖音)、微信***(转正)、猿辅导SP(斑马英语)校招Offer,最终选择留在微信,目前仍实习在职。

在我的大学四年中,有四年的Android开发经历,两年半的实习经历,有两款Google Play上架的应用,个人原创技术博客也收获了25w+的访问量,当然,最重要的是最后拿到了自己满意的Offer,也算是给大学生活画上一个比较完整的句号了。

文章目的

上面介绍的经历并不是为了显示我的经历有多牛逼,事实上在我认识的范围内我的经历还远远谈不上出彩。当我刚刚考入大学,进入我心仪的计算机专业时,觉得提升自己的技术、加入BAT这样的大厂就是我的目标,这也由此指引了我大学生活的方向。相信很多无论是不是刚入学的新生、也无论是不是计算机专业,都有着像我那时的想法。很幸运的是我在非典型的大学四年中找对了方向,也找到了方法,收获了很多的经验与教训,最终达到甚至稍稍超出了自己当初的立下那个目标。

现在回想起来,这很大程度上要归功于给我提出建议、给我指引的前辈们,没有前人的经验我们很难找到正确的方向与方法,以至于陷入无谓的迷茫与焦虑之中。当然在这过程中,也从自己的经历中认识到很多“假如我早点知道该多好”的问题。我所在的华中科技大***创团队(学生技术团队)有着近20年的历史积累,通过前辈的方法与经验的传承,近年就业的队员几乎是人手几家大厂SP Offer,我想这些方法与经验应该是行之有效的,也是值得与大家分享的。

我写这篇文章的目的也正是在此,一是为了总结自己的大学四年;二是给有着和我一样的目标的同学们一些参考和建议(包括对应届生比较实用的面经),希望可以给读到这篇文章你们一些帮助,希望你们也可以达到自己的目标或是在追求更高的目标的路上更进一步,也算是作出一些微小的贡献;三也是为了帮助大家更好地认识客户端开发这个现在普遍认识不足却有着极大缺口的方向,也是给我所在的联创团队微信团队打打广告。


虽然文章标题写的是客户端开发之路,但是文中80%以上的内容都是对于技术学习方向比较通用的内容;同时,本文主要面向毕业直接工作的同学,所以不会涉及到读研、出国相关的内容。

最后,本文表达的内容都是一些自己的看法,也仅代表个人的观点,受文笔和经验所限,表达不当之处敬请包涵,也恳请经验更加丰富的前辈多多指正。

正文

大学四年的经历很长,总归不是三言两语就能表达清楚的,每个人所处的阶段不同可能感兴趣的内容也不同,为了保证阅读体验,会主要分为三篇文章(非通用内容和一些书籍推荐等会后面另行发出):

  • 对刚进入大学、想要在未来从事开发工作的大一大二新生的一些建议:https://www.nowcoder.com/discuss/431452
  • 如何在大学阶段学习计算机并获得快速的技术成长
  • 关于实习;如何准备面试、在面试中展现自己以及最终的选择

本文是其中的第二篇,其他文章敬请关注公众号VirMe。

(二)过程——技术学习与个人成长

由于本文篇幅过长,层级也比较多,为了避免逻辑混乱和阅读困难,先在这里列出全文的大纲,大家可以先大致了解全文结构和内容。

最重要的一点:付出大量的时间

这是前文说过的团队要求在队时长的内在原因,也是在大学直至以后想要在一个领域取得进步和成就的核心点。这其实也是一句“正确的废话”,勤能补拙、奋发向上、量变引起质变的例子和大道理我们从小不知听过多少遍,但实际上,对很多人来说,这是一个典型的“道理我都懂,但就是做不到”的例子。

很多人都是靠着高中及其之前的勤奋与努力在高考中战胜了大部分的人考上现在的大学的,很多人也是听着“现在吃点苦,考上大学就轻松了”的所谓鼓励支撑自己度过了高中艰难的时光。

但大学有的只是自由,轻不轻松则完全取决于个人的目标。有人的地方就有着竞争,大学的学习中能体会到的竞争不像高中的分数排名那样直观与残酷,只要不挂科,我想大部分的情况下都不会有任何外部的压力。如果你的目标是顺利毕业,以我在华科的体会,课外的时间多到一天能打8个小时游戏的同时可以顺利毕业,确实这样的人也不在少数,不过人各有志,目标和行动匹配就好。但我相信点开这篇文章的你目标应该不在于此。

失去了高考这一明确的目标,外在的环境也不像高中那般竞争激烈,大学里也没人会管你勤奋与否,自由宽松的环境造成了很多人失去了前进的动力。很多人大一时还借着高中的惯性踌躇满志,买书籍做计划,希望在大学里大展身手,不出一年的时间发现自己好像不用那么努力也不会有什么问题,于是就开始把大把的时间花在了游戏上,最终与自己当初的目标相去甚远,毕业时泯然众人。可能在这里说得有些夸张,但我所见到很多人的情况确实如此。

所以为了在就业时激烈的竞争中可以取得优势,在这里必须强调付出时间的重要性,没有足够的时间的投入,下文将要说的一切方式方法都是空谈。同时,也希望大家能够明白,投入的时间越多,你能获得的优势就越大,可能比别人多投入200%的时间,你就能超越80%的人,但如果想成为最突出的那批人,你需要付出的时间会是别人的1000%或更多。千万不要相信所谓的“他这么厉害是因为天赋,是因为加入了团队”,以我所见到的,在最后获得了不错的Offer的人无一不是花费了大量的时间和努力的。

我在大一加入团队后,整个大一只因为班级聚会出过两次校门,印象深刻的是每天骑车背着十来斤的游戏本来回相距3公里团队与教学楼好几趟,进了大学后第一年反而瘦了十斤。大二实习后,除去每天朝十晚九的工作时间,回学校后也会再学习两三个小时,基本上都是一两点再回寝室睡觉,和保研的室友一学期也见不着几回面。

也是因为我相信我付出的时间远远超过大部分竞争者,在大三找工作的面试中才能有比较难得的自信,也让我敢厚着脸皮在这里写一些东西与大家分享。

当然也不是说大学生活的全部就应该是学习技术,我也因为对这些的投入牺牲了很多其他东西,这是我的选择,但大学中确实还有很多技术以外的事情值得我们去尝试,在最后再来谈这点。希望下面的内容可以对你的技术成长起到帮助。

应尽早知道的事情:方法与效率

既然想要获得技术成长就一定要付出时间,为什么有的人已经花费了很多时间但是没有相应的成长,不同人付出相同的时间能获得的技术成长是不是相同的呢?显然不是。因为真正获取到的东西=时间x效率,效率在很大程度上影响了最终的产出。

而对于计算机的学习来说,不同人之间效率的差距极大,有时候会有数倍之多,这就造成了花同样的时间,一些掌握方法、效率极高的人学到的知识/完成的项目会是其他人的数倍。尽早知道这些方法,意味着尽早积累优势,一些受用终身的东西可以帮助你在漫长的职业生涯中获得极大的回报。很多理念包括提升效率这点本身很多人工作多年后才能意识到,却是大学中团队mentor教会我的第一课,所以与前辈交流经验是很重要的。

在这里,我就将我和团队所受用的一些方法和理念分享给大家。

接受一手资料

刚进入团队的新人都会有着一个相同的第0期任务:配置上网环境(上Google,你懂的)、安装Linux与Linux下开发、使用hexo搭建博客。在第一次新人期的CodeReview时,我的mentor顺手就打开了Google,将我的语言设置成了英文:

团队一开始会告诉新人的是:尽可能使用Google,使用英文,阅读英文资料

熟悉英文环境

熟悉英文环境的理由很简单:绝大部分计算机领域的一手资料都是英文的,几乎所有经典的计算机书籍都是英文版翻译过来的;Android的官方文档近几年才开始支持中文(抛开翻译质量不谈,有更新的内容一定是先有英文版的),大部分常用开源库的文档只有英文版;更不用说一些新一些的技术了。如果为了方便和一开始的速度而不去熟悉英文环境,除了要面对参差不齐的翻译质量,到了只有英文资料提供的时候就会变得捉襟见肘,非常影响效率。一开始上手时可能会因为生疏导致阅读速度较低,但只要经过一段时间的适应后,阅读速度和能力都会有快速的成长,更可以开始体会很多翻译所完全丧失的原作者的机敏与幽默,会感到原版的内容读起来更加地流畅与易懂(例如英文版的计网-自顶向下和中文版简直是两本书)。

此外,为了与老外交流,比如去github提issue、去Stackoverflow提问与回答,英文也是到了一定阶段后不可或缺的技能,所以团队也要求代码的注释、git的commit message等也全部用英文。

不要担心你的英语水平不够阅读这些资料,Mentor原话是“你能考上大学的英语水平就足够了”,技术类的文章其实语言很直白,难度低很多,也完全不需要另外专门去学习,直接上手就是最快的办法,很多生词查几回就熟了。本人高考英语16年全国卷132分,从大一开始尽可能阅读英文后到了大二基本上适应了英文环境,之后基本上都是有英文原文绝不看翻译版。

使用Google

搜索资料与文章是我们除了看书以外学习技术和解决问题的另一大来源,在Google之前有统计的时候团队有学长统计过年搜索次数可达到1.2万次,而搜索结果的质量很大程度上就决定了我们能否找到正确的答案和接受的内容质量。但在英文搜索方面,百度确实做得远不如Google。

首先,百度的搜索结果是为中文优化的,所以即使你搜索的关键词是纯英文的,得到的结果也大部分会是中文的关联性不强的内容,而Google在设置为英文结果后则不会有这一问题,基本一搜一个准,在一些情况下Google也会展示部分高质量的中文内容。

其次,由于国外部分技术网站无法访问(包括Android的官方文档和间歇性失联的github),所以百度对这部分网站内容的索引很少,比较明显的是Google搜索各种类/接口/方法出现的前几条结果一定有官方的文档页面(也是最为推荐的了解类库的方式——阅读文档),而百度则是各种博客平台中质量参差不齐的文章(有些时间非常久远,也存在到处转载的重复文章):


左:Baidu 右:Google

虽然CSDN、简书上不乏高质量的博主和文章,奈何低质量的内容实在太多,需要花大量的时间甄别,而官方文档始终是最权威的资料来源,但很多所谓的Android开发者却从来没有打开过官方的文档和guide页面。

更不用说百度检索不到github的issue、Google issuetracker等这些非常实用的查问题的地方,对Stackoverflow这个几乎能找到所有常见问题的网站的检索能力也很弱,但很多问题确实只有在这些地方才能得到解答:




更为搞笑的是,国内还有网站钻起了Stackoverflow上都是英文内容、不便搜索的空子,直接爬取问题和回答再机翻出来,污染了搜索结果:




类似的例子数不胜数,就不再举例了。总的来说,熟练使用Google和英文环境,可以很大程度上提高信息的获取效率,更是对解决实际问题有着极大的帮助。

重视工具

这部分想讲的是要重视工具的使用以提高开发效率、节省开发时间。工具的含义很广,从我们使用的IDE、编辑器,到操作系统甚至是硬件设备,都是我们开发时会使用的东西。为什么要重视工具呢?因为工具带来的效率提升往往是最为直接的,举个简单的例子,假如你编译一次代码需要10分钟,学会使用make、ccache等工具后编译时间下降到了5分钟,一天编译十次,就节省了50分钟的编译时间,非常直接有效。

IDE与快捷键

那么可以从哪些方面入手呢?首先就是学会使用IDE和快捷键,像Android Studio这种IDE从接触Android开发起几乎是形影不离,其强大的功能如果不主动去学习很难了解全面。在我第一次见到mentor如何使用IDE的时候几乎目瞪口呆,各种跳转、重构、代码生成等让我意识到如果不学会这些操作,将会在低下的效率下浪费多少时间。所以非常有必要花上一些时间全面地了解你所使用的IDE的功能,方法也很简单,点开最上方的菜单,一个一个地了解、试验其每一个选项的作用并在以后的使用中加以运用,相信你一定会受益良多。

虽然写代码大部分的时间应该在思考而不是打字,但得心应手地使用IDE依然可以帮助我们流畅地编码,节约很多开发时间。

Linux

前面提到过团队新人的第0期任务之一就是安装Linux与Linux下开发,大部分人可能都听过Linux,但是从来没想过要主动去使用它,更别说作为主力操作系统日常使用。

我在大一刚入学的时候为了安装Linux(而且是团队推荐的比较激进的Arch Linux),整整用了两个礼拜,也是因为第一次尝试靠着官方的文档,在什么基础知识都没有的情况下摸索着安装,期间也不知推倒从来了多少次。也是这段经历驱使我后来写了篇如何安装Arch Linux的博客,意外收获了十几万的浏览量。当然像是Ubuntu这种更加大众的发行版的安装就不会有这么困难,基本上都是一键安装了。

从安装Linux后,我就基本上抛弃了windows,开始使用Linux作为主力操作系统进行后面的学习和开发,直到实习后转向macOS(真香)。事实证明,Linux是一个对开发者非常友好的操作系统,深入使用Linux可以带来很多好处,同时,熟悉Linux环境也是计算机专业毕业生必不可少的技能。

首先比较直观的,windows下比较头疼的开发环境配置问题在Linux里基本都是一行命令就能解决的,包管理器会帮你处理所有的依赖项和对应的配置,有着庞大的开发者群体,基本上碰到的系统/环境问题都可以很容易找到解决办法;字体渲染比windows好很多,看着舒服;不用像windows那样用ssh、git这种命令行工具都需要下载专门的客户端,Linux的命令行环境非常强大,利用shell编程,配合各种命令行工具,就可以非常方便的进行各种操作,在效率上会远高于windows下使用图形界面完成相同的操作;对于后台方向的同学来说,在Linux上部署服务、熟悉UNIX编程更是基础技能。

更重要的是,Linux继承自UNIX,几乎是伴随着操作系统的进化而来,有着完全开放的源码、架构和独特的设计哲学。它化繁为简,比起windows的黑盒来说更加透明、干净、简洁,从中你可以了解操作系统运行的每一部分:网络、内存管理、文件系统、进线程调度等。借由这实际且成熟的操作系统,可以帮助我们理解、学习相关知识,大学课程中知名的高质量实验如CS:APP(深入理解计算机系统)的lab、MIT 6.828的lab、南大的ics-pa等无一不是建立在Linux环境的基础上的。

与IDE类似,对于这种每天都要长时间接触、使用的工具,花上一些时间配置、熟悉所带来的效率提升是非常划算的。在安装完Linux后,我又在差不多两个月的时间里没事就折腾桌面环境、配置各种快捷键,当完全熟悉以后就发现自己再也回不去windows那死板的、毫无提升潜力的桌面环境了。

对于Android开发者,学习Linux的过程也就是对Android底层所依赖的Linux层面的学习过程,对Linux的理解越充分,对Android整体设计和与系统紧密关联的部分的认识就越充分。举个典型例子,Android的整套权限系统其实就是基于Linux的文件权限系统实现的,通过巧妙的用户和组的设置从内核层面保证了安全性,又避免了重复造轮子,非常简洁与优雅。

说了这么多,还是为了向大家推荐去尝试Linux,更希望可以将Linux作为自己的主力系统(macOS当然也行,但是还是有朋友在mac上装Linux用的……)。Linux远没有想象中的遥不可及和难以掌握,还是那个道理,虽然有学习成本,但其能带来的知识和效率上的收益会远远超出付出的成本。

再谈效率

程序员是非常注重效率的群体,很多人都对工具与开发环境有着执着的追求,在公司的大团队里一定会有人专门来研发工具和优化流程,提高所有人的开发效率。因为效率意味着在有限的时间成本中获得更大的收益,并且是改善的越早,累积的收益就会越大。

对个人来说也是如此,一旦当你发现有什么事情阻碍了你的学习/开发效率的时候,就应该意识到要去想办法改进;也要多关注、交流,了解可以使用什么工具或是方法来提高自己的效率。效率不是一切,但一旦你有了对效率的追求,就可以在成长的道路上不断提速。

基础知识的重要性及如何学习

在前文中已经非常多次强调了基础知识的重要性,基础知识主要指一些计算机科学中较为基础、通用的知识,包括被称为“四大基础”的计算机组成原理、算法与数据结构、操作系统、计算机网络和其他例如C语言、汇编、数据库、计算机体系结构、编译原理等。

可以发现这些都为计算机专业开设的课程,具体学校、学院会根据侧重不同开设数电、模电等偏底层的课程或是游戏开发、面向对象编程等上层课程,这部分课程可以根据兴趣选择深入程度,优先级会比前面这些通用的课程低一些。

在回答应该花多少精力学习基础知识时,我的回答通常是四个字“往死里学”。基础知识的重要性可以体现在以下几个方面:

基础知识决定了学习能力和深度

学习能力

整个计算机的知识体系其实很像计算机网络里面的分层模型,每一层都只关注这一层应该做的事情,在低一层提供的抽象的基础之上进行开发的同时为高一层提供抽象接口。计算机从最基本的硬件(数电/模电)开始,到计算机组成原理如何用电路组成基本的冯诺曼依体系计算机,到ISA指令集提供软硬件接口,到操作系统形成对硬件的管理和抽象,再到编译原理、汇编语言等打通高级语言与可执行程序间的鸿沟,最后到我们日常所接触的上层应用的开发。

以华科为例,教授这些知识的顺序通常会从高级语言层面、最容易理解的C语言开始,

因为学习语言不至于太过枯燥,也可以尽早培养最基本的编程能力。但是因为一开始所学的C语言已经是较为上层的知识,没有底层的知识背景,通常是很难学明白的。

就像是绝大多数人(包括我)在一上来就学习C语言的时候,会面对编译时的错误和运行时的SegmentFault等感到头疼,因为没有编译原理/编译器和操作系统的基础知识,我们只能选择查阅资料或者请教别人来直接找到解决的办法,而对其真正发生的原因一无所知;也会对类似于指针和地址的概念感到难以理解;更不用说理解堆上内存分配和函数栈帧这种概念了。

而对基础知识的学习,就是建立完整的知识体系、更加深入地理解计算机(程序)工作原理的过程。一旦学习了汇编语言,对C语言到汇编的对应关系有了了解以后,就能很容易地理解指针是以什么形式存在和被CPU所理解的,这个时候就会对C语言的认识更加深入与清晰。同时,汇编语言又会帮助你在后面的课程中理解操作系统的启动、编译的流程等等知识。

这是一个滚雪球的过程,对已有知识的充分理解,可以帮助你在能更加容易地学习新的知识的同时不断巩固和加深已有的知识,最终雪球越滚越快也会越来越大。计算机的学习曲线就是一条开始缓慢,而后不断提速直至达到一个人理解能力的极限的曲线,基础知识扎实的同学的学习速度和理解能力会远远超出基础知识不牢靠的同学,拉开越来越大的差距。

如图所示,可以认为学习能力=学到的技术能力/花费的精力,而大约50%的人由于没有对基础知识足够重视,一直会处于开始时很低的学习能力水平;有大约30%的人在学习完大学所有的课程后意识到基础知识对于学习的帮助,但毕业也意味着失去了最佳的学习基础知识的时机,毕业后很少会有大学中这么完整的时间沉下心来学习基础知识;同时有20%的人毕业时在基础知识上的积累已经越过了开始时增长较慢的过程,达到了较高的水平,这样的知识积累对毕业后的技术成长是非常重要的。

我在大学中的切身体会就是我把一批人远远地甩在了后面,而在我前面的人同样遥不可及。而这些走在最前面的人通常就是大学之前已经积累了很多计算机知识,入学时的学习能力已经甩开其他人一大截的人。在花同样的时间的前提下,在短期内他们的知识水平会一直比我们高,并且差距也会越来越大。

技术深度

更强的学习能力可以带来更深的技术深度,但基础知识对技术深度的影响还不止于此。

对于Android开发而言:

  • 技术深度一部分体现在对Android系统底层的理解上,理解了底层的运作才能对应用的行为有更全面的了解、解决一些应用层面很难理解的问题,才能根据底层的原理进行针对性的性能优化。而Android底层就是我们所熟悉的Linux,对于操作系统的认识在这里完全适用,另外,也需要有非常多的基础知识才能理解应用的运行时环境JVM,知道其是如何运行我们的应用代码并作出优化的。
  • 技术深度的另一部分可以体现在对软件架构的设计能力上,而操作系统、计算机网络、数据库系统等课程中的设计理念和原则都是非常经典和优秀的,对这些系统设计的学习可以潜移默化地提升我们的软件设计能力。当时读到Android系统源码中对于输入事件的处理代码时,突然发现这不就是组成原理中CPU流水线的设计吗,后来来微信以后也在代码中发现了类似的设计,这就是优秀设计的魅力。

这两点放在其他开发岗位也是大同小异,你所写的代码总会运行在底层所提供的环境之上,对于底层环境的理解需要的往往就是更多的基础知识,同时基础知识中经典的设计也可以有助于设计出更好的代码架构。这就是基础知识对于技术深度的重要性。

基础知识是面试时的重中之重

在我所经历的面试中,越是能力要求高的公司/岗位,对于基础知识的考察就越重视。很多人不能理解,基础知识大家都知道会考察,考察的问题也大同小异,为什么这些面试官还会不厌其烦地问这些问题?

对于每个刚从大学毕业、想从事开发岗的候选人来说,无论是否是所谓科班出身,通用的基础知识一定是衡量大学中对于计算机知识的掌握程度的最佳标准。一是所有人都会去学,不会出现刚好问到没接触过的方向的情况;二是对于基础知识的考察非常容易分辨真实水平,虽然面经网上一抓一大把,问题也就那么几个,但对于基础知识的掌握程度更多的靠的是前面所说的,不同知识间的相互印证和加深。同样一个问题,或许靠背诵准备好的“标准答案”可以说个大概,但只要面试官一旦再往下深入一步,或是提及相关的知识,就非常容易看出来到底是对这些知识有深入理解和关联还是只背过面经。

举个例子,“进程和线程的区别”是操作系统的一道非常经典的面试题,很多人都能轻松背出这个标准答案:“进程是操作系统资源分配的基本单位,而线程是任务调度和执行的基本单位”,但深入一步问“操作系统为进程分配了哪些资源?”,“操作系统为什么要进行线程调度,是如何进行的呢?”,这就不是大多数人能答得出来的了,更不用说面试官可以一步步深挖,直到知道面试者的认识极限。对如此庞大的知识体系的考察,决不是靠面经就能应付过去的。(百度搜了下这个问题排名第一的CSDN文章竟然是错的……)

为了提前对面试者的基础知识进行筛选和节省面试投入,现在各个大厂都会进行笔试进行考察,也非常流行进行交叉面试,让不是这个方向的面试官考察通用能力。事实证明,基础知识牢靠的面试者会非常容易得到面试官的好评,通过率也往往非常高,毕竟语言和具体的开发方向工作后都可以慢慢学习,唯独基础知识是必须在大学中才能学好的。明白了这一点,又怎会不去重视大学中基础知识的学习呢?

如何学习基础知识

花了这么大的篇幅介绍基础知识的重要性,还是想让大家从心里认同基础知识的价值,这是开始学习的第一步:弄清楚为什么要学,这样才不至于在这个过程中感到迷茫和动摇。下面就介绍一些我对于基础知识学习的经验。

关于学校开设的课程

前面说过,我们要学习的基础知识在大学中几乎都开设了对应的课程,那么是不是跟着学校教授的进度走就行了呢?答案是学校教授的基础知识对我们来说应该是远远不够的

首先大学目前开设的课程的学时远远不足,以华科为例,像是计算机操作系统这种核心课程的学时也只有64,这么短的时间内想要把操作系统弄清楚是很困难的,事实上做完MIT 6.828这种优秀的操作系统课程的实验所需要花的时间可能都不止64个小时。受限于学时的限制,老师也不得不省略一些较为深入的内容,而只能关注于把关键部分讲清楚,像是组成原理这种课程,课上所会教授的部分其实只有《计算机体系结构——量化研究方法》这本书内容的附录部分。而想要真正完整、全面地认识一门基础课程,光靠课堂上的这点时间是远远不够的。

其次,目前大学中开设课程所用的课本绝大部分还是国内自编的,非常不推荐从这些课本开始学习基础知识。第一还是由于课时所限,课本的相关内容也是经过选择的,并不能代表这一课程的全部内容;其次这些课本的年代也已经比较久远了,很多内容放在现在其实并不适用;最后还是因为这些课本本身不够权威,内容也没有经过广泛认可,很可能存在不正确的地方。刚开始学习一门课程时的第一印象很重要,否则错误的认识将会伴随后面的整个学习过程造成更多的错误认识。关于如何选择书籍,下节集中讲。

最后,学校开设课程的进度因为通识课的存在通常比较滞后,华科的操作系统和计算机网络等核心课程要等到大三才会开设,而这个时候通常已经到了马上要准备春招找实习的阶段了,所以对于就业的同学来说,提前学完这些核心课程是必须的。

因此,在大学的课堂上,我几乎都在自己阅读该课程对应的权威书籍,在课外的时间会选择另外一门基础知识同时来学,以提前积累一定量的基础知识,到了真正开设这门课的时候,通常还会再从头把书再看一遍,因为这时其他课程的知识一定可以帮助你重新认识很多知识点,也是为了准备课程的考试。

很多面试官也问过我,“你这么早出来实习,学校内的课程怎么办?”,其实这个问题就相当于说:“你不去上学校的这些基础课程,基础知识能保证吗?”。我的回答也很直接,我不去上课不代表不学,更不代表在基础知识方面花费的时间会比其他人少。事实上我在每一门专业课上花的时间会超过大部分的同学,在专业课上也是在零平时分的前提下平均分在90分左右(考试接近满分,老师不会为难你的平时分的)。这里不是鼓励大家翘课去实习,这么做的前提是你对自己学习基础知识的能力和投入有充分的保证,不然只能是得不偿失。

书籍选择

其实现在选择书籍已经很容易了,因为已经有很多书籍已经经历时间的考验,被大家所普遍认可,只要在知乎这种平台搜“XXX(课程名) 书籍”,高赞的回答取个交集基本就是候选的书了,但是这里还是要注意选择,因为很多书籍确实非常权威和全面,但是并不适合入门时阅读,比如C语言方面有人推荐《The C Programming Language》这本由C语言发明者和Unix宗师所著的书,但这本书并不面向初学者而编写。相比之下,更加适合的是《C Primer Plus》这种既权威,又为初学者考虑的书籍。千万不要为了追求所谓的“一步到位”而选择前者这种需要一定基础的书籍,这类书籍待到对其他方面的知识有了一定量的积累以后再来看,才会有较为透彻的理解、达到最佳的效果。

实在纠结不知道选哪本,那就都买来对照着看吧,反正学习基础知识,永远不嫌多。

同时,正如前文所介绍的,在有英文原版的情况下(机械工业出版社的黑皮书和人民邮电出版社都会出版对应的英文版,很良心),非常推荐看英文原版,上手以后无论是阅读质量和理解程度都会有一定提高,也是帮助自己熟悉英文环境。

我看的第一本原版书籍就是人民邮电出版社的《C Primer Plus : 英文版(第六版)》,当时是在刚进入大学时就看过这本书的中文版,后面开设C语言课程的时候又买了这本原版再看了一遍,确实帮助很大,如果一开始觉得英语能力不够的可以下个中文版的电子书对照着看,看完这一本以后基本上后面的英文书籍阅读就没什么障碍了。

具体的学习路线?

其实路线这个东西就因人而异了,每个人感兴趣的东西不同、学习习惯也不同,选择的路线只要能让自己能投入时间不断学习就行了,但是在这里还是强烈推荐一些书籍和计划:

  • 在大一上学期学完:
    • C语言:推荐《C Primer Plus》
    • 数据结构与算法初步:推荐《数据结构与算法分析——C语言描述》和人民邮电出版社的《算法(第4版)》(这本书虽然名字叫算法,讲的大部分还是和数据结构非常密切的,同时在Coursera上有普林斯顿配套的Algorithms课程,有详细的讲解)
    • 汇编语言:强烈推荐王爽的《汇编语言(第3版)》,深入浅出,配合附带的实验对学习汇编语言非常有帮助
  • 在学完上面的基础后强烈推荐在大一到大二上学期的时间内看完《深入理解计算机系统(原书第3版)》,也就是大名鼎鼎的CS:APP,这本书在知乎等平台备受推崇,书名看上去也非常高大上,容易让人误以为这是一本非常高阶的书。
    但事实上这书的英文名直译过来也就是“计算机系统:一个程序员的视角”,来源于CMU给大二学生开设的基础课"Introduction to Computer System(ICS)",是很多后续课程的前置课程,对能力背景的要求也仅有基本的C语言和汇编的知识(没有也不要紧,书里还会教……),所以最适合阅读的时机就是大一大二
    这本书的优点我在这里不再多说,“价值超过等重量黄金的无价资源宝库”这样的评价丝毫不会夸张,这是技术书里第一本能让我读起来感到非常“爽”的书,读完以后你会第一次认识到计算机到底是如何工作的,虽然不是非常深入细节,但是这样的宏观认识可以极大地帮助你后面深入的学习。
    在这里想说的是,这本书大多数人都听过,甚至都买来读过,但是真正能把它读完的人却很少,更不用说做完这本书精髓的11个Lab的人更是凤毛菱角(很惭愧我也没能做完)。首先因为这本书的体量很大(我买的原版足足有1000多页,拿着就像两块砖头),需要花大量的时间阅读,其次是其中有的章节在缺乏背景的情况下读起来确实会比较吃力(例如第四章处理器架构大部分人都会选择跳过去,不过这本书绝大部分内容已经写得非常通俗易懂了),劝退了不少人。其实我认为这书里的内容完全搞懂是不太可能的,因为它只是个Introduction,让你形成宏观概念,引入你深入学习,这本书的目的就达到了,所以对于不懂的地方大可先跳过,之后总会有一天反应过来原来如此的。
    而这本书的Lab是非常推荐在假期花上一整天的时间去做的,这几个Lab都是实验中非常难得的精品,在与知识深度结合的同时又不缺乏趣味性和挑战性(Bomb Lab拆炸弹、Attack Lab做攻击),就像是游戏一样。
    相信我,尽早看完这本书和做Lab,会让你受益匪浅。
  • 再往后就是几门经典课程了,有了CS:APP的积累,我觉得以什么顺序来学问题不是太大,大多数情况下也是几门一起学的,这些核心的课程除编译原理外建议在大二完成:
    • 计算机操作系统:《现代操作系统》、《操作系统设计与实现》、《操作系统:精髓与设计原理》、《操作系统概念》这几本书其实各有优劣、评价褒贬不一,我看的第一本是《现代操作系统》,其他几本都是翻过一下,可以根据自己的兴趣选择,大不了还是都看一遍……如果觉得还不够的话可以试试《Linux内核完全剖析》等偏应用的书籍。另外推荐MIT 6.828的配套实验和南大的ics-pa,都是非常精品的实验。
    • 计算机网络:推荐清华大学出版社的《计算机网络》和英文版的《计算机网络: 自顶向下方法》(这本书翻译实在太烂,中文版不推荐)。前者是自底向上的,可能一开始比较难理解,后面几章就好了。后者可以作为参考或者看的第二本书。另外,方向相关想要继续深入的同学后续可以看《TCP/IP详解》这套书。
    • 计算机组成原理:推荐也是神作的《计算机体系结构:量化研究方法》,这本书比较偏硬件,可以根据自己情况选择性读(我也没有读完)。
    • 编译原理:机械工业出版社《编译原理》,也就是久负盛名的“龙书”,有些学校把编译原理作为选修课,我觉得作为计算机专业本科的封顶课程,是非常有必要学习的。有的同学可能觉得,我又不从事编译器相关的工作,学编译原理有必要吗。其实编译器要解决的问题就是搭建用户语言与机器语言间的桥梁,也是一个将一种表示方式转换为另一种表示的通用问题,虽然编译器是特殊的,但其能解决的问题是通用的,它解决问题的方式和思路也是经典和优秀的,这些东西都值得我们学习。在微信实习的学长和我其实都用到了编译原理来解决一些问题,其实它离我们的日常开发并不遥远。
遇到问题

对于这些基础知识的学习过程并不轻松,时常会碰到不能理解的知识点,我的习惯是一般会先跳过这些点,有些是知识点的编排问题导致后面才会解释的概念提前出现,看到后面再回过头来自然就能理解了;另一些情况确实是书籍讲解的不够细致,比较直接的办法是直接搜索相关文章、博客、问题等帮助理解(有些专门针对于一个技术细节的文章讲得会比书中详细得多),麻烦一点的话就是找其他书的对应部分做参照,如果还没有找到答案,我觉得大概率这个问题其实并不重要,有时候过分关注于细节就是一种浪费。

一方面是不懂的地方可以暂时跳过,另一方面是如果一本书读完还觉得云里雾里,完全没了解到这门课程的内容,那么绝对不能就此罢休,可以换个课程学一段时间再回过头来再细读一遍,或者干脆就换本书继续学。还是前面所说的,基础知识值得我们“往死里学”。

基础知识之外

花了这么多的篇幅讲基础知识,那是不是把所有的学习时间全放在基础知识上就行了呢?虽然可以这样,但是纯粹的基础知识的学习有一个弊端是过于理论,除了几个精品的实验之外就几乎没有实践、编码的机会了,这样的学习过程会比较枯燥,不容易长期坚持如此。所谓实践出真知,总得来看纯粹的理论学习还是不利于自己对于知识的理解掌握与应用的。

另外,由于计算机的毕业生也越来越多,企业对毕业生的要求除了“基础知识扎实”之外也开始要求“有相关开发、项目经验优先”,对于想要拿到比较好的Offer的同学来说这更是必要条件。就像上一篇文章所讲的那样,大学中从零到掌握一个方向的内容都不太可能,公司里的开发岗位也通常也是按方向设置的,所以在大学中还是要深入一个方向,把这个方向做深做精会更有利于就业的同学。具体如何选择方向请见上一篇文章。

所以,清楚基础知识重要性的同时,还要协调好对自己方向相关内容的学习和实践。我大一的时候这两者所花费的时间大约是一比一,在团队的时间基本上都在做项目、写Android;上课和其他时间基本都会用来看书学基础。到大二大三如果有项目/实习的时候基本上大部分都会在开发上,周末或者晚上空下来的时候就会抓紧学基础,甚至一段时间没看基础的书就会有一种莫名的罪恶感……对我来说学习基础知识反而成了代码写累了的时候的一种消遣,能静下心来看书的时候不多,抱着享受的心态来学习的感觉是很不错的。

下面就介绍一些基础知识学习之外,应该重视的事情。

码量

我觉得大学里的计算机学习,除了基础知识之外,第二重要的就是码量。写代码是一个程序员基本得不能再基本的东西,对于初学者来说,码量的积累是非常重要的,这决定了在毕业时你能否成为一名合格甚至优秀的工程师。

看书学习是一个非常理论的过程,很多的东西只有在实际的编码中才能体会到,就算你把快速排序的算法描述看个几十遍以至于倒背如流,真正第一次写的时候十有***还是会出错,毕竟书本教会你的更多的还是理念和思想,而没有一本书会教你“如何把代码写出来”和“代码写出来出了问题该怎么解决”,而解决这两个问题,即提高工程能力的终极办法还是多写代码。

只有开始写代码的时候才会发现一些自己理解上的错误,因为计算机不会骗人,运行结果永远反应了实际的代码行为,当代码与自己的预期不符时,一定存在着自己的逻辑错误,这是很好的反馈与纠错的过程,把代码当成自己的老师,用自己的代码去验证自己的理解,是非常有效且正确的方法

所谓代码写得好,比较直观的,一方面是说写的代码不容易出错,另一方面则是出错时能很快的解决,这样的能力几乎就是和码量成正比的。代码写的越多,出的错误也越多,解决的问题也就越多,而解决问题的方法和避免问题的习惯就是在这样的过程中养成的。

所谓久病成医,当很多次解决一个问题或者一类的问题时,会引导我们去思考其中的原因,而直接暴露出来的问题往往是表层的,越是复杂和容易出现的问题往往有着更加深层次的原因,可能是架构设计的问题、可能是对系统行为理解不当、又或者是编码习惯问题,探寻并改进这些深层次问题的过程是可以对自己产生非常大的提升的。

举个例子,当你发现自己的类用起来总是很别扭,经常需要改动很多代码才能实现一个新的功能时、或是代码逻辑混乱,数据状态各种出错时,自然而然地就会去了解到面向对象设计的一些非常实用的理念和设计模式这一类专门解决这些设计问题的方法,并很快可以通过应用它们来改进自己的代码,从而达到对这些理论的理解。离开了代码和实际的场景,理解这些概念和抽象往往是非常困难的,这也是学习过程中经常会遇到的,只能通过不断编码和练习解决的问题

不同人在大学期间码量的差距也是极大的,记得我们学院书记曾对我们说过你们都应该给自己一个目标:“大学期间赚两万块钱,写两万行代码”,三年多下来给我的感觉是能赚到两万块钱的人比能写两万行代码的人还要多得多,而且能写到两万行以上代码的人往往赚得远远不止两万块了……(各种项目、外包、实习工资等),学院课程大部分人四年下来除去毕设会写的代码应该两万行不到,很多人毕设的工作量甚至也在一千行以内,而我了解了一下团队成员四年下来码量都会在十万行以上,这样巨大的差距直接导致了工程能力上的差异。

那么应该如何保证自己的码量呢,这里不建议刷LeetCode这种算法题来提高码量,算法能力不等于工程能力,其实积累码量的过程就是实践的过程,而在大学中这样的实践机会是很多的。

项目、外包与比赛

在学校里最能接触到的实践机会大多是项目、外包与比赛这三种,经常会有各种各样的渠道找上来的项目,或者直接一点的外包,也有很多的比赛的宣传。建议是把这些作为实践的契机,同时也要注意辨别,判断付出的时间和回报是否值得。

我大学中接到的第一个项目(除了团队的新人任务外),是在刚入学三个月的时候,学院的辅导员找到团队的学长和我,问要不要接一个公司的项目做。当时我是很诧异的,为什么会有人让刚入学三个月的新生来做这样的项目。不过当时我倒是没有什么犹豫,因为和当初犹豫要不要报名联创团队时一个学长点醒我的那句话一样“报名不要钱,你又不会亏,为什么不试试呢?”。其实这就是大学中做项目、外包这些事的优势:试错的成本出奇地低,假如没有完成或者对方不满意的话,我们也不用承担任何责任和损失,而从中获取到的项目经验和码量的积累是实实在在的。后面这个项目其实完成的质量远远达不到公司的要求,但是对方还是支付了我们5000块的报酬,这也是我大学里赚到的第一笔钱。

其实除了积累码量、赚一些钱外,项目经历对于工程岗的求职来说也是很大的加分项,我在大学中大大小小的项目做了有十几个,简历给面试官留下的第一印象还是很深刻的。

大学中的项目来源有几种:

  • 企业为了加强和学校的联系和合作(其实也就是希望吸引更多的毕业生到公司去工作),专门为学生设计的项目。这些项目可能是公司已经实现的东西,或者是比较边缘没有人力来支持的技术点,很少会有公司真正急需的东西来给到在校学生来做(这种一般直接外包了)。
    这类项目的技术要求最低,只要做的东西还过的去就会有一些报酬,一些比较重视的公司还会邀请你去参观公司,配备公司里的导师作交流等等。建议在大一大二时间比较宽裕,其他项目机会也比较少的情况下多接触这种项目,对上手做项目、开拓眼界等还是很有帮助的,也不用太考虑技术栈和自己方向是否匹配的问题,毕竟项目难度不会太大,了解一下其他技术也是很好的。
  • 自己想做/团队想一起做的项目。这类项目一般是自己或者团队里的其他人出于兴趣,想去实现某个东西,比如团队之前有做过微博的第三方客户端、520的表白墙、团队的BBS,甚至是为了Linux能够认证校园网而诞生的mentohust。
    这类项目其实是最推荐去做的,因为自己的项目不用受什么限制,可以实现很多自己的想法和尝试技术。但是这里要强调一定是自己感兴趣的,因为这种项目没有金钱的回报,也没有其他人的约束,能不能做下去全靠自己的兴趣,只有真正投入进去才能把这种项目做好。
    我大学中最引以为傲的项目就是学长拉我一起做的一个用于生成带字幕的Gif图表情包的APP“表情锅”(原型是一个网站,诞生了“为所欲为”等一系列表情包,学长和作者认识)。当时我们两个人开发了两三个月的时间,基本上所有的空闲时间都投入在上面了。当然收获也很多,技术上按自己的想法完全使用Kotlin来开发、深度使用RxJava、接触交叉编译等,学到了很多新东西;产品上把应用上架后收获了几十万的下载量,也得到了很多认可。大学中如果有机会去实现自己想做的一些事情,就大胆地尝试吧。
  • 自行申报的学院项目。在华科每年学院会有大学生创新项目的申报,这种建议是把上一条里面自己做的项目进行申报,可以报销一些经费什么的。
  • 外包项目。这个就水比较深了,来源的渠道各种各样,有各种朋友介绍的、老师联系的甚至还有寝室楼下贴小广告的……因为市场中的外包公司的报价会比较高,而给学生出的价钱就可以低很多,所以有些公司就会打起大学生的主意,甚至还有专门从外面接项目然后包给学生做的“二道贩子”。所以在遇到这种项目的时候首先要看看项目的甲方是否可靠;再就是做的东西是否对自己的技术成长有帮助,主要还是看技术栈是否符合自己的方向,毕竟这种项目一般就是要做完整的软件或是APP了,需要投入的精力还是很多的,如果不是自己想做的方向如果没做好那就连技术经验都积累不了了;最后还要衡量一下工作量和报酬的关系,接触到的比较靠谱的外包基本上一天不会低于500,如果发现对方不断增加工作或者不想付出应给的钱的话,还是果断退出为好,相同的时间做一些自己想做的项目对技术成长更有帮助,光是为了赚钱没必要。

最后就是比赛了,各种面向大学生的比赛还是非常推荐参加的,一般都是比较好的与他人合作、交流的机会,在技术上也可以有很多成长,像是hackday这种一天内开发项目的比赛,基本上一天能写到十几个小时、几千行的代码。也可以在参加一些比赛的时候顺便做一些自己想做的项目,我大二参加学校的手机应用设计比赛时就从团队拉了一个产品和设计,然后一个人肝了两周的时间写了个相机类的APP,最后拿到了冠军,后来这个应用也成为了我的第一个上架应用。

总的来说,大学里做项目、参加比赛的试错成本真的很低,关键是对自己的技术成长和视野有没有帮助,如果发现项目/比赛是个坑,也可以尽早跳出来。我完整做下来出结果的项目其实也不多,更多的是发现这事不靠谱就鸽了,只要多尝试,被坑多了也就明白了,总会有靠谱的项目的,而这个过程收获的是实实在在的实践经验和码量,这才是最重要的。

技术博客

团队成员必做的第0期任务里还有最后一点没有谈过,就是搭建自己的技术博客,为什么要有自己的技术博客呢?其实写博客更多的是给自己总结,其实和做笔记一个道理,把学习的一些东西做个记录和积累,一些比较难和有深度的东西,如果不及时地记录和总结,很有可能一段时间以后自己就忘了。

所以我博客里大部分内容还是实验的报告(在做完实验以后从头梳理了一遍实验的过程,加深印象和理解)、Android源码的分析(这些如果不记录下来,需要的时候再去翻源码效率太低了)和一些技术点的分析,如果能用文字把这些东西讲清楚,就说明是真的理解了。这些东西后来自己写代码想不起来的时候还会自己打开翻翻,到了面试前也会再拿来复习,好记性不如烂笔头的道理在技术学习上也一样适用。

另一方面,和做笔记不同的是,博客是公开的、可以被搜索到的,写博客不但是自己的积累,也是一种分享,很多自己分析源码的时候也搜不到相关的资料,这种原创的内容是可以为他人产生价值的。我之前也没想到自己重装5、6次以后写的Arch Linux安装教程后来会有十几万的访问量,也时常有人留言、发邮件表示感谢,会由衷地感到开心,这个时候才发现其实分享能带来的价值远远超乎我的想象。这几篇文章也算是一些更加大胆的尝试,希望能产生更多的价值。

最后,比较功利的角度,有原创的技术博客在简历上一定是加分项,因为会去总结技术、分享技术的人通常也会是热爱技术的,比较上心的面试官会提前看看博客,也是了解技术能力和热情的一个窗口,我在大二能面过头条很大原因就是博客上的文章得到了面试官的认可。

上架应用/上线项目

上架应用/上线项目其实代表的是真正可以被用户使用的项目,因为一个项目真正有人用才是有价值的,上线和上架意味着这是一个完整的产品,要进行迭代,对用户负责,这和课内做的项目或是一些企业给的项目还是有很大的区别的。因此自己做的项目还是要尽力保证质量,想办法上线运营并进行迭代,把项目做完善才能发挥它最大的价值。

心态

前文介绍了很多方法性质的东西,但经历过高三的同学应该都清楚,心态也是成长过程中需要重视的另一方面。

对技术保持敬畏心——切忌自我膨胀

学计算机会很容易让人产生成就感,解决一个bug、完成一个功能、实现一个trick,都会让人体验到很强的满足感,这样的反馈是很多人喜欢上编程的原因,但一些人会把这样的成就感变为自己的优越感,会刻意去吹捧一些自己完成了但是别人没完成的东西,在和别人比较后觉得自己掌握了很多东西已经足够了,从而固步自封,对技术浅尝辄止。

正如前面所说的,任何一个方向都不可能在四年内达到精通的水平,不对技术保持敬畏心有弊无利,因为盲目自大而止步不前更令人惋惜。

直面困难,保持耐心

一个比较有意思的事情是,计算机水平比较高的人脾气一般也会比较好,因为学计算机没有足够的耐性不太容易学好。

还是拿我大一入学装Arch Linux的经历来讲,因为显卡的原因,装完以后一直不正常,那些天每天强制重启电脑几十次,想了各种办法,换不同版本的包、调整配置,一旦调炸了又是几十分钟的重装过程,崩溃的时候真的会想砸电脑。最后折腾两个礼拜以后终于能开机使用了,但是外接显示器还是不正常,又是配置了一个礼拜,重装几次后搞定了。如果没有耐性和毅力,我想不可能能把Linux装好。

这其实更像是考验,经历过这样的过程更让人能体会到保持耐心、不轻言放弃的重要性。新人大多会遇到配置环境的种种问题、一个Bug解一天的情况,因为解决问题的方法与能力没有太多的积累,往往在开始会遇到比较大的困难,甚至觉得问题不可能解决从而放弃继续下去,其实这些都是非常正常的,每个人都会遇到的,而直面困难坚持下去才可能有后面的成长。

自信与勇气,大胆跨出第一步

自信不是自大,而是在碰到机会时勇敢尝试的信心。在大一刚入学的时候其实我对自己的自信是远远不够的,记得当时联创团队来招新的时候我看着***上的要求就几乎被劝退了,当时想的是自己什么都不会,团队招人要求又这么高,我肯定没机会。这样想法我后来在与学弟们的交流过程中其实听过很多很多次,很多人会觉得自己现在水平不够,想自己学一段时间后再报名,但是最好的机会往往就是这么被错过的。

万幸的是,当时到了报名的最后一天,我问了当时的班导师(大四学长),他的话我至今记忆犹新:“报名又不要钱,为什么不试试呢?你又不会亏。”。虽然比较直白,但是道理确实如此,我们没必要给自己设限,大学中做尝试的成本这么低,为何不试试呢?

后来的故事当时就觉得像做梦一样,面试出乎意料地顺利,自己在国庆假期学了整整一个礼拜的Java和Android最后以第一的成绩通过了熬测,如愿以偿加入了团队,才有了后面的故事。很多时候会想起当时如果因为胆怯没有报名团队,现在又会是什么样子呢?不敢多想,但是这让我在后面的大学生活中又做出了不少正确的决定。

大二上学期要结束时,偶然看到团队群里有学长发布的深圳头条急招客户端实习生的消息,当时其实对自己的技术水平并没有太多的把握,但还是抱着“试试肯定没错”的心态铁着头写了份简历推了过去,然后就被安排了人生的第一次面试,却也出乎意料地跟面试官格外聊得来(甚至聊到忘记做笔试),后面的Leader面感觉也非常好(至今还觉得是面试体验最好的一次),面完以后就觉得自己可能可以去实习了。然后在某一天的上午,在寝室床上收到了offer call,一如加***创时的梦幻,但是这次是实实在在的勇气换回来的。

有时候最困难的,就是跨出尝试的第一步。

技术之外的个人成长

这篇文章的前面部分讲的几乎都是关于技术的东西,虽然技术能力对于一名计算机专业的学生来说很重要,但个人成长包含的方面太多太多,技术并不能代表一切,更不能决定一切。

最显著的一点,到了真正去公司实习,走向工作岗位的时候,会发现开发的工作并不只是每天闷头写代码,而是需要花一大部分时间在与其他人的沟通上,与产品沟通需求、与设计沟通交互、与同事沟通方案,乃至大部分公司的绩效/晋升还需要进行沟通和答辩。

因此,沟通能力会在很大程度上影响一个人的发展,功利地说,面试中很大一部分也是在考察候选人的沟通能力,身边也有很多技术能力足够,但是因为面试沟通能力不足而没有通过的例子。所以有时候在团队里,比起闷头写代码,我更鼓励大家多聊天聚餐活动。

而沟通能力也只是个人成长这个庞大的话题中的很小一部分,这些所谓的“软素质”并不是通过一些方法或者经验就可以快速提升的,对这些内容我自己也正走在路上,所以也不再赘述了。在这里想表达的是千万不要把提升技术当成成长中唯一需要关注的事情,在大学里可以做的很多事情会比学习技术更加有意义。

我大学中绝大多数的时间都放在了技术上,除去大一参加了学生会、当了一年半班长之外,剩下的时间就是团队、公司和宿舍三点一线了,这样的大学生活我想不是大多数人所期待的,但回忆起大学中最值得开心的事情,并不是技术做得多好或拿了多少Offer,而是和队友们一起合作和成长的过程;也不是得到了多少荣誉或赚到了多少钱,而是靠着自己赚的钱带女朋友一起去了很多地方。真正的快乐,来自于技术为我们创造的价值。

最后的最后,还是要强调一下“身体是***的本钱”这句话,身体的健康是这一切的一切的前提,失去了健康意味着人生就此变换了方向,以前做的大部分努力都将付之一炬,这是绝大部分人所承受不起的。

知易行难,与君共勉。


这是全文的第二部分,介绍了如何在大学阶段学习计算机并获得快速的技术成长。在下一篇文章中,将主要介绍一些实习/工作相关的内容和面试的经验。
第一时间获取更新,敬请关注公众号VirMe:

如果以上的内容对你有所帮助,欢迎你把它分享给更多人,谢谢!

如果有任何想法、疑问、意见或是建议,欢迎在评论区留言交流。
---

今年的秋招也马上就要开始了,相对于春招,秋招的面试结果会真正决定毕业后的第一份工作以及最后的薪资水平,即使你已经拿到了心仪的实习Offer,也会需要参加其他公司的面试去拿到更好的评级/薪资来谈薪尽力提高转正后的薪资。

所以,无论你是已经有实习经历或者刚决定就业开始准备,都需要更加认真地对待秋招,除开自己方向的技术之外,算法是笔试/面试中必考的内容,我自己为了拿到更好的评级在大三寒假的时候就花了一个月的时间集中地看书、刷题。事实证明算法不仅是通过面试的基本门槛,较强的算法思维和能力非常容易赢得面试官的青睐,甚至于一些岗位现在不要求方向上的能力,只要基础扎实、算法过关,就能通过面试。

其实除了算法岗外的面试,算法的部分都比较套路,也有很多的技巧,这里推荐一下牛客推出的《算法笔面试真题精讲》(https://www.nowcoder.com/courses/cover/live/350?coupon=AL7ifZQ)视频课程,是《程序员代码面试指南:IT名企算法与数据结构题目最优解》这本书的作者、资深刷题大佬左程云亲自视频讲解,还有作业练习和专业答疑,里面所讲的套路与技巧已经足以应对算法岗之外的面试了(前提是你能坚持把这60小时的课程/练习全部完成)。通过上面的链接或是使用我的优惠码AL7ifZQ购买课程现在还可以有140元的优惠(虽然我觉得即使优惠完定价也有点高了,但是内容确实不错,比起后面收到的Offer来说这些付出完全是值得的)。

---
前文《从开始到微信/支付宝/Airbnb/抖音Offer——我的大学客户端开发学习之路(一)开始——步入大学生活》https://www.nowcoder.com/discuss/431452

未经本人授权,不能转载。

关于面经与面试方法的分享会在秋招开始前发出,感谢大家的关注与转发!


5条回帖

回帖
加载中...
话题 回帖

相关热帖

技术交流近期热帖

热门推荐