上周五晚上在室友群里看到博仔收到了亚麻offer的消息,意味着一年前一起入学,住进同一个townhouse的“四兄弟”全部拿到了flag的实习offer,突然想写点东西来纪念一下过去整整一年的时间,那些大家相互激励相互扶持的日子。
我相信,对于每一个转cs的同学来说,入学第一年开始找暑假实习的过程都会是出国留学计划中最重要的一环,这篇文章将从我自己的角度出发,结合身边同学的经验,希望能够给在题海中挣扎的同学一点帮助。
一、转专业时间线
17年10月- 18年3月 0基础学java ,背题加硬刷 200道题
18年4月- 18年6月 入学 和室友一起刷50题
18年6月-18年8月 上算法班 200题
18年9月-18年10月 集中刷题500题
10月底拿offer
总体来说,我一共经历了这四个阶段
- 什么都不会,没有思路,花很久时间看懂讨论区的代码然后惊呼一声牛逼,模仿着写,写完了过几天也会忘记。
- 稍微对一些算法有一定了解,backtracking,二分法,dp等等,但是知识体系不完整。不知道自己欠缺点在哪里。
- 花大量题去完善知识体系,补充薄弱环节。
- 体系较完整后集中刷题,medium 难度可以秒,做过两遍的hard可以秒
二、打好基础
关于第一阶段相信每个同学在刷题的过程中都会或多或少经历类似的经历,之前看地里很多帖子还有很多学长学姐的经验都说,第一个阶段直接上leetcode没有什么问题,多模仿慢慢就磨出来了,但是以我个人的经验来看,这一步是完全没有收益而且浪费时间的,如果让我重新再来一遍,我肯定不会选择这样的路线,因为刚开始对数据结构和算法不熟悉的时候仅仅靠模仿和背代码是一点也起不到作用的,这一道题你背了stringbuilder的append方法,下一道题背了string.substring(),string.trim(),这样不知道坑有多大就去盲目填坑的行为真的效率低下。
所以我建议用这个办法来完全代替这第一个阶段:
假设你是零基础并且选择java,打好基础当然很重要,以我为例,我当时看了传智播客毕老师的java入门,真的是通俗易懂,很多抽象的基础概念都直接很清晰地讲了出来。
我看了英文版的《head first java 》前9章,这真的是一本神书,而且强烈推荐大家一定要看英文版,因为中文版的翻译有时候过于僵硬,不方便理解,我当时看这本书的感受就是,看了上一页脑海里刚想到一个问题,下一页就立马给出了脑海中这个问题的答案,全程一直在“卧槽?”,看完之后对java的一些基本特性更清晰了(尤其是jvm 这块)
最后一步我是去了地里找了很多小伙伴一块学ucb的神课cs61b(在这里想提一下公开课的选择,个人感觉mit和普林斯顿的算法课对0基础同学不是很友好,所以算法这一部分我个人不推荐这两门),cs61b这个课属于进阶版的java基础班(和cs61a是一个系列的,61a会讲一些基本java的语法),主要讲数据结构,不过这课load还是很重的,作业和pj都是精挑细选,经过岁月打磨出来的精品(我在网上找到了12年以后的每一个版本和一个05年的版本,老师只有中间的16年换了一次,其余都是一个老师,值得一提的是05年的时候老师头发还很茂密,你懂得)
我只看了前三分之二,做了两个homework和一个pj,感觉就已经进步很大了,能把这个课刷完的人一定前途无量。地里很多关于cs61b的帖子,大家可以去找微信群一块学,这样不懂的就可以一块讨论。
至于算法这一块,我并没有提前系统地学过,看过mit的算法课不过很快就放弃了,我不太明白为什么几乎所有算法课上来就都会先讲分治算法,这个算法我在不同版本的网课里看了至少5遍,每次都模棱两可,可能也正是因为这样慢慢磨,到最后来了scu上算法的时候才会那么容易明白很多算法原理,所以我给大家的建议不是上大学的网课,而是去找一个专门培训面试算法班的机构上一个网课,或者在youtube上面找专门讲解某一个算法的视频,在这里为了避嫌我不对算法培训机构做评价,如果感兴趣的同学可以私聊哈。
三、集中刷题找面经
打好基础后,就可以进入集中刷题的阶段了,这一阶段我给大家的建议是easy题10分钟做完,分析好时间空间复杂度,medium题15分钟,hard 25分钟争取做完,如果一道hard 10分钟一点思路都没有就不要继续死抠浪费时间了,因为如果在面试时候10分钟没有进展就基本上挂掉了。一天的刷题量我个人来说,开始每天可以到7-8题,每道题都认真做完,甚至可以多尝试几种办法,用多个数据结构,总之一个字,要做“精”。
到了后期题量和感觉上来了我最多一天达到过20题,不过那时候的大脑真的已经炸掉了。总的来说,刷题就是一个量变引起质变的过程,而且一道题只刷一遍肯定是不够的,我总体来说一共刷了400题,其中有100道左右用了不同方法刷了3-4遍,200道刷了两遍左右。
集中刷题之后,我们就可以有针对性地对某一个公司进行准备,这时候一亩三分地的面经板块就尤为重要,在这里各大公司的各类面经都有,而且很多都是近期的帖子。
四、准备面试
1. 投简历
这一部分写在简历已经写好的情况下,简历的问题在这里不会过多赘述,因为我在整个求职的过程中仅和身边同学参考的情况下,简历对于能否拿到面试的影响很小很小(名校满绩大神请忽略我 ),个人认为更多的影响在于两点:
(1)公司的招人计划
(2)先到先得
对于flag级别的公司,每年都会招大量的实习生,而且岗位在上一年的暑假就会放出来,加上大量的candidate,很可能会出现迅速满坑的状态,所以一定要早投,不要担心自己没有准备好,从投简历到面试通常需要一个月左右的时间,时间来得及。
我的情况是,9月15号开始两天之内找认识的前辈帮忙内推了fla三家,其中a家因为当时没有招实习生计划简历拒掉(当时身边认识的人全军覆没),l家因为晚投了两周简历拒(比我早投两周的同学都得到了hr的反馈,之后投的全军覆没),f家一周后收到hr邮件(f家战线还算比较长,陆陆续续一直到今年2月份还有收到offer 的),g家海投,没有找内推。
当然,漫漫找工季,单单指望flag是远远不够的,除了flag,我和室友们成立了投简历小组,这一点特别感谢博仔,很早很早就号召我们早投简历,三个人共享一个google doc,分别在不同的途径找投简历的链接,我主要是在linkedin上面找,在搜索栏输入2019 summer software develop engineer intern,每天都会有大大小小的公司的职位放出来,那时候每天刷题之余的放松途径就是投6-7封简历,每投出去一封,就好像是放出去一个信鸽,希望它能带回来好的消息。一周多的时间,投出了100多家公司,其中百分之60杳无音信,没有消息的公司名字现在几乎都已经忘了,其余的百分之30发来拒信,剩下百分之十发来oa意思一下(这里说意思一下的意思是很多公司是无脑发oa,甚至还没确定要不要招人也会先发个oa让你做着)。
2. 约面试
关于约面试的时间,我觉得用四个字形容就是:越早越好。有的同学会因为自己刷题不够而害怕,也会因为简历没有写好而不敢投,我觉得只要不是没刷够100题的情况,都是可以立刻投简历和约面试的,人有时候不逼自己一把,根本不会发现自己的潜力。而且那么多人都在投,晚一天都很有可能失去机会,我约的第一个面试是intuit,本来约的10月19号,后来提前到了12号,同期19号面的不错的同学也因为坑满了而没有拿到offer。g家当时约到了2周之后,其实在当时已经刷了大量题的情况下,最重要的不是去接触新题,而是尽量不在自己的易错点上犯错误。
3. mock interview
mock interview 是准备面试里最重要的一环,我建议在面试前至少进行找不同的人进行2-3次mock interview,因为在这个环节里我们可以直接发现自己在将来面试中会出现的一些错误,尤其是很多表达和分析代码的能力,平时写代码的时候我们是处在这样的模式下:
(1)leetcode 里看到题目和例子
(2)在leetcode里给出的固定函数接口下根据输入书写代码
(3)跑test case,提交代码以发现新的edge case
(4)修改代码以看到绿色accept
但是实际的面试中可能会是完全不一样的环境,界面是完全空白的写代码的区域,题目是面试官口头介绍或者是直接粘贴过来,句子可能会不好理解,例子也需要面试官给出,没有leetcode的函数接口,自己根据面试官的要求来书写函数框架,在书写代码前需要和面试官讲解思路,讨论edge case……. 1point3acres
这些不同之处会让一直在lc里写代码的同学非常不适应,再加上面试时可能会出现的各种情绪,mock 就显得尤为重要。
五、面试经验
在这一部分我不针对某个公司,而是希望以一个更general的角度来给一点面试的经验,我没有经历过onsite面试(想请求去google onsite被无情拒绝)面试的形式可能是电话面试也可能是电脑里的视频面试,面试内容就是算法题(个别公司会对除算法外的能力进行过多考察,如intuit的最终面是75分钟的项目和ood面试,在这里不过多讨论。
面试三要素
基于“面试官能给你最高的评价是:我想和这个面试者做同事” 和 我个人及身边同学的面试经验,我总结出三点面试原则:
1. keep talking
面试时要保持交流,面试官也是sde,把不工作的时间拿出来给你面试肯定是不希望对着一个哑巴说话的,为了体现你的态度,keep talking是最基本的礼仪,有同学会说写代码的时候没法保持keep talking,那也没关系,我们可以写完某一块代码,然后再给面试官解释这一部分代码的含义。
2. keep smiling
不管是视频面试还是电话面试,这一步都至关重要,视频面试的话,笑一笑可以给面试官一种很有亲和力的感觉,会让人感觉很容易交流。另外一点,之前看过一个ted演讲,里面讲的就是人不仅可以通过情绪来影响面部表情,反之亦然,笑一笑也会让自己心态更轻松,达到更好的状态(和深呼吸有点像)
3. keep communicating
这一点是我后来加上去的,结合自己和身边同学的例子,有时候我们由于过度紧张,尽管做到了前两步,还是没有达到很好的效果,最主要的原因还是太过于紧张,一直在自言自语而忽视了电话另一头的面试官,communication毕竟是两个人的事情,一个人一直说话而得不到反馈一定不是正常的交流,我在面一家很重要的公司时候,中间自己卡住了大概有将近十分钟,面试官稍微有一些不耐烦,就一直默默不说话,他越不说话我就越慌(我们通常可以根据面试官的反应来判断自己代码的正确性),又纠结了1分钟,我咬了咬牙,然后硬生生地把面试官“揪”回来,让他听我一步步再讲一次算法,每说一步找他要一点反馈,最后把题目讲完,后来的经验告诉我这样做对自己的信心也会有很大的提升,要时刻记住交流是两个人的事情。
面试过程
面试开始(1分钟到5分钟不等):自我介绍,面试官可能会让讲一下之前做过的项目或者一些基本的bq,这一部分就当练习口语和适应交流环境,不用太过紧张。
算法题目环节,这时候面试官会粘贴过来一小段题目要求,屏幕上刚刚出现这行字的时候是最让人紧张的,这时候一定要告诉自己放松放松,因为越紧张越容易读错题目,同时面试官会口头解释题目的含义,这时候有不明白的地方一定要立刻指出来,不要害怕面试官会不开心,“面试官有义务澄清好题目”,题目没给你说清楚是面试官的问题,一个case没听明白就让他再讲一个case,直到明白题意为止。
问题清楚之后,就要开始和面试官澄清一些edge case,比如输入为空或者一些不合法的情况,一般情况下面试官都不会刁难,而是说一句假设输入都合法。
澄清好各种情况之后,我的建议是在3句话以内讲述你的算法,比如“这道题我想用dfs,遍历一遍的同时记录什么什么,然后xxx来得到什么什么”,希望大家在准备面试的时候可以练习一下这个办法,这样精炼出来的3句话可以让面试官迅速明白你的思路,如果话太多又没有重点,面试官很难get到你的idea,从而影响交流。
3句话之后,听听面试官的反馈,如果思路正确他会表示满意,然后让你开始书写代码,也可能再问问你有没有别的办法,这都是一个好的兆头,说明你的办法被认可了,可以继续详细地解释你要用什么数据结构,描述一下算法的具体思路,这里最好充分利用你即将写code的地方,把每种case和对应的operation都列出来。 如果他对你三句话的算法不太满意,一般会说出你这个思路的问题,进而把你转向别的思路,也没有关系,谁也不能保证思路永远是对的。
感觉思路讲的差不多了,问一下:“Can I start to code?” 如果面试官对你的思路没有问题就会让你开始code(如果你思路错了他还让你写8成就是要坑你,这种情况几乎不会出现)然后就可以和他确认一下输入数据的格式,是直接写函数还是需要在一个class里面写,然后就按照之前和他澄清的各种case的情况开始写,如果有写comment的习惯最好,可以让代码更加清晰,记得每写完一部分向面试官解释一下这部分代码的目的。
如果面试的时候思路卡住了或者写代码的时候写不下去,我建议和面试官这样说:“我有一点想不出来这里是怎么回事了,可以给我2分钟的时间,让我在纸上捋一下思路吗?”面试时谁都会有紧张的情况,没有人会拒绝这样的请求。
写完代码之后面试官一般会让你口头跑一个test case(很少有让写main函数来run的,不过如果让这样的话public static void main这些关键词必须会),如果case 对了,code环节就算是结束了。然后分析一下时空复杂度,算法部分就算是完成了。
最后几分钟是对面试官提问的环节,这部分和面试结果影响不大(只要不触碰雷区,问自己的面试表现这类弱智问题),放松就好。
六、说点感言
我觉得我真的足够幸运,能有机会来到地理位置优越的scu,遇到身边这么多可爱的同学和给力的大佬室友们,后来遇到了帮我无私内推的哥哥姐姐们。
说到地理位置和环境因素,我想提到的一点是,其实我们每个个体也可以成为环境的一部分,从前我只是听说scu找工作环境好,身边同学找工氛围很浓厚,我的感受是到了9月份中旬,这种氛围是从我家里的三个人开始营造的,慢慢也吸引了周围的大家,后来每天大家讨论的话题都变成了你投了哪个哪个公司,你在做哪个哪个oa,什么时候电面这样。
在这里感谢一下刷题小组的同学们,大家每天在白板或者在twich上直播讲题,坚持了一个多月才有后来的结果(特别感谢鹏鹏帮我mock了5-6次,压中了一道高频)。从前我最担心的就是面试时不知道如何把思路讲出来,在这段时间的锻炼中也算慢慢变成了一个刷题老司机。
最后还要特别感谢我的三个室友,晨哥刚入学时给我讲解了很多算法,博仔,越越在后期抽出很多时间帮我mock(面试前一天晚上越越两道题全部压中),有点怀念那时候在家里白板上秒题的时光,记得有时候吃饭的时候讨论讨论着就放下筷子就拿着记号笔去白板上写思路了,如果没有室友们的帮助,我肯定不会这么顺利。四个FLAG 的offer也算是最好的结局。
最后送大家一句鸡汤:最后的结局总是好的,如果不是,说明还没到最后。
祝大家都能成功上岸,拿到自己心仪的offer!
ps 一张家里的全家福