写这篇所谓的面经,不是要炫耀我怎么样拿到了offer,相反我这学期面的几家公司都挂了。只是作为一个大二菜鸟,总结一下自己找实习的经历,等大三的时候就能更有把握。
我前后一共投了这几家公司:豆瓣、阿里、腾讯、网易、搜狐、豌豆荚。其中网易太久没有处理我的简历,我不耐烦就取消申请了;搜狐本来进入安排面试阶段却突然显示简历未通过,之后找了个学姐帮内推可能因为时间太晚了也没有消息(对搜狐不是很上心,因为之前听学长说团队的成员去搜狐很容易,当时简历都写的很随便,内推也懒得找了)。其余几家都获得了笔试、面试机会。
一、简历书写
网上有很多教你怎么写简历的,我也看过一些,不同技术职位的简历还会有不同之处,我这里只说下我对写简历的一些经验。
简历一般是你获得笔试、面试机会的敲门砖,虽然不需要在上面花太多精力显示你自己很牛逼(这些在面试的时候会慢慢考你),但是准备一份好的简历依然很重要,对之后的面试也有帮助(虽然有些公司面试的时候不一定拿着你的简历问,大多数还是会按简历上写的东西来问你,特别是项目相关)。
说下简历大致格式与注意点:
1.一般学校是211/985,专业也比较对口(比如我是计算机专业),是获得公司垂青的第一步,因此简历的开头一般要把教育背景写清楚(并不是说大公司只要名校专业对口的学生,而是在那么多简历中,这样的学生更容易脱颖而出。当然走内推的话就不是那么重要了);
2.然后就是个人技能。我当时写的时候纠结了很久,因为自己好像对很多技术都有涉猎,但不深入,所以写的很蛋疼。个人感觉作为Android程序员,应该掌握的技能包括:熟练Java、熟悉基本数据结构及相关算法、熟悉Android控件的使用、了解设计模式、掌握一门数据库语言、对网络编程(http、tcp/ip等)有了解。当然这些只是基本要求,能够自定义控件、了解Android进程/线程通信模型、Binder机制这些更高级的技能与底层原理,会有更多加分。我因为能称得上熟练的太少,写了很多都是『了解』,有些也并不是Android方面的内容,甚至把自己熟悉的开源库也作为技能写上去了......(事实证明,会用开源库几乎是最Low的技能,虽然看起来可以很快的做出东西来,但是大公司不会招一个只会用开源库的人。他们更希望你是一个基础扎实、了解更多技术原理的人,相关经验不一定要很多,毕竟一个学生最多就3、4年经验,在一家大公司诸多牛人面前不算什么。但是基础扎实,学什么都会快很多,比起一些所谓经验丰富但是基础不扎实的人,更有前途。后者只能在一些小公司做螺丝钉。)
3.实践经历也是很重要的一项。加入了什么技术团队、做过什么职位、曾经的比赛/实习经历、做过什么项目/产品,都是很大的加分项。虽然对一个学生并不要求那么多项目经验,但你有别人没有的经验就是一大优势,而一些小公司、创业公司也更看重这些经历,他们更需要能够快速做出东西的人。这里最好写下自己做过大一点的项目(项目持续了较长时间,功能较复杂的),而且即使代码是多人合作写的,自己也能说出自己干了什么工作,并且能把整个项目讲清楚。个人感觉写几个小项目,不如写一个收获很大的大项目,在面试的时候也可以由此讲更多给面试官听。如果是上线产品,尽量把下载链接放上去,让人家能够看到产品;
4.自我评价。这一块感觉是很鸡肋的,但是大多数简历上还是都写了。我觉得不要吹牛,正常的评价几句就行了,没几个人会看这里的;
5.加分项。一般包括自己的技术博客、个人主页、github地址。对一些真正的大牛来说,这些都是真正体现实力的东西,如果有几篇写的很深入的博客、有star的开源库,肯定大大加分。这些就看平时积累了,在平时看书、做项目之余,还该多写点东西、造点轮子。
二、笔试
豆瓣:我首先做了豆瓣的线上笔试,也是最有特色的。印象中全部是开放式问答题,应该是没有要写代码的题,全都是Android相关的。我当时有点小看这些题了,时间安排的不好,在一道自己较熟悉的题上大谈特谈,结果其他题时间就不太够答的不太好。还有是可以当场搜的,豆瓣也没有说这个问题,当然时间有限一般也搜不了多少。
大多还是基础题,但是可以引申下去很多东西。我印象比较深的是这两个题:
1.什么是OOM?它的产生原因是什么,应该怎么检查和避免?(这个问题我当时答了很多,但是都是从Android中具体的一些例子说,不知道有多少是答到点的。其实这个问题可以深入到很底层,说到C/C++层的内存管理上去,不过一般讲到Java虚拟机垃圾回收应该够了)
2.Android进程通信有哪些方法?(一深入下去又到Binder了)
虽然感觉答的不够好,但是基本还是答上了。而且因为有学长内推,自我感觉应该能有面试机会,但是最终就没音讯了,之前说即使挂了也会有通知,这点让我觉得挺不爽。不过今年团队的人基本都没过豆瓣笔试,有点诡异。
阿里:阿里我错过了内推的机会,因为觉得自己技术不够迟迟不敢找人内推。事后想起来还是应该找次内推,先体验一把电面积累经验,而且之后看起来走内推比网申通过的概率还是更大,当然这并不是说内推要求低。
阿里的笔试题基本都是数据结构、算法、C/C++、操作系统相关,而且各个技术岗位用一套题,对我这个数据结构没学完、操作系统、C++没学过的人来说还是很有难度,当时蒙了很多。但是最后还是通过了。听说阿里不刷简历是因为借笔试来刷,之前简历不行的人可能笔试就比较难过,总之团队的人只要参加了笔试都通过了。
腾讯:腾讯的笔试题类型、难度都和阿里差不多,不同之处在于前者线上笔试时要求打开摄像头、并且限制你从笔试页面离开的次数,算是对作弊有更好的监督。当然结果也还是和阿里一样,蒙着就过了。
豌豆荚:豌豆荚因为走的内推,直接到面试,不过面试中途有笔试,之后再说。
三、面试
腾讯:这是我最早参加的面试,面试地点在璞玉酒店。当时去的时候相当紧张,看周围都是比我大很多的哥哥姐姐,貌似就只有我一个大二的来面试。到了现场签到了之后,就被指定去一个房间,面试官已经等在那里了。
一进去还没做自我介绍,面试官就冷冷的给我递上纸笔,让『写一个C语言的交换字符串的函数』。按说这个东西真的很简单,但是我确实太紧张一点准备都没有,完全没想到会一进来就写代码,还是用我很久没写过的C。我就拿起笔想了下:简单但会不会有陷阱、用指针还是字符数组、能不能用异或运算而不用临时变量来做交换。这真的是因为太没准备,很简单的代码我纠结了很久才写好,拿给他看还被质疑『是这样吗』。这里我也没处理好,检查了一遍没发现什么问题,但是没敢问他哪里有问题。告诫大家如果某个问题没答对一定要问问面试官哪里有问题,也许是他没理解你的意思,也许他是故意质疑你,无论你到底有没有答对,一定要给人家一个反馈,表现出你在思考,你要是被质疑了就吓傻了闷在那里不知所措,肯定是会被鄙视的。自信一点很重要。
然后他就换了个问题开始问,之后就是一连串的问题,主要都是考察C/C++、算法数据结构、操作系统(这个因为我还没有上过相关课程,问得不多,我也没怎么答上),问了我一个TCP发送一个包的过程,我一下没反应过来又大脑空白了,他就默认我对网络编程几乎没有了解。Android、Java一个问题也没问,只是让我把做过的app拿来看一下(就看了一眼)以及问下Android的学习方法。基本都是问在了我最不熟悉的领域。很快就问完了技术问题,就问我有没有什么问题要问他。我就按照网上教的,让他给我一点学习建议,他大概就说了『要把基础打好,把数据结构、C语言这些学好』。这样基本就知道挂了,当作是积累了第一次经验。
腾讯的这次面试获得的收获就是面试的时候的确有可能出现面试官不是你所求职的那个领域的,比如我这个面试官显然不是做Android/Java的,专业不对口的面试还是有可能出现的。这个时候不一定要你精通各个领域,做Android的不一定要把后台也写的很溜,但是基础知识都是相通的,比如C/C++、数据结构、操作系统、网络,这些也是所有技术面试都是会重点考察的。虽然我不觉得把这些相关的问题都答上来就很牛逼(毕竟可以靠刷题,而很多这些知识在实际做项目中也许并不比你熟练某一平台的开发更有用),但这些不能回答的好也是自己的问题,这样一遇到不对口的面试官,他又不问你Android,只能问这些,你还答不好那只能挂了。
阿里:阿里的面试是一天面完,也就是过了一面马上开始第二面。不像腾讯每个面试官在单独的房间等你,阿里的面试官都是在一个会议厅里面坐着等你,场面相对比较嘈杂,不过也不容易紧张了。
面我的面试官是个看起来挺和蔼的中年大叔,可惜没能看到他的花名是什么。这次终于是从自我介绍开始,我也按部就班的把自己的学校专业、团队、Android经验简单的告诉了他,然后他就对着简历开始问我问题。相比腾讯的面试官,他更能聊也更善于引导,有些问题我没答上来他会试着提醒我某个点,所以这次面试也就比腾讯那次持续的时间长,大概一共花了45分钟。
先是问了Java基础的,比如hashCode( )、equals( )区别;finally、finalize( )、final区别;wait( )、Thread.sleep( )区别......涉及多线程的我没答好,其余的还将就。
提到finalize( )时他就顺便问了下我对垃圾回收有没有了解,我刚好那段时间看了一些有关GC、内存管理的文章,就跟他讲了一下:GC有哪几种、老生代新生代、Mark/Sweep是怎么样一个过程。自我感觉大致的还是讲清楚了,只是他对这方面也没什么研究,只是问了我这些事看了别人的分析还是自己研究源码,我感觉不是做JVM相关研究源码有点没必要,通过别人的文章了解GC的原理对一般的Android程序员来说足够了。
然后又开始问算法,问了冒泡、快排是怎么个过程,时间复杂度怎样,然后问冒泡为什么比快排更快,归并排序是怎么个过程。我再次吃了数据结构的亏,稍微深入一点的都没答上。
接着他根据我的简历问了我上过面向对象的课程吗,我说实际是自己自学了一些有关设计模式的东西,就开始问设计模式。设计模式是问得最久的,大概前后一共15分钟,当然很多时间都是他在跟我聊:他先让我讲几个熟悉的设计模式,我就讲了单例、观察者、工厂、builder。然后让我手写个单例,我就先写了个最简单的懒汉模式,他问我有什么问题我就说多线程调用第一次会null(这个还是很清楚的,写懒汉模式就是为了详细讲解),解决方法可以用方法同步,他又说这样最简单但是不好是吧,然后跟我讲为什么不好,我当然知道就说最好的方式是用双重加锁检查的方式去写,他又让我写出来,我一时忘了怎么写就跟他说了,这还是让他挺不满意的,觉得我好像一个单例模式都写不好一样(个人感觉一定要求我写出双重加锁的有点钻牛角,我并非不知道这种情况,如果实际中要写肯定会搜到写法,因为我目前没写过这种单例模式所以实在不熟,当然我用单例模式时是很清楚要怎么用的才没用到双重加锁)。接着问了观察者,让我举个例子,我就举了OnClickListener和EventBus,他又展开问了很多,这之后就是他聊的很多。
最后到了Android相关的,给他看了下写的app,他大致了解了下一些效果的实现(都是简单的属性动画和ViewPager),然后就根据我简历上写的开始问自定义View相关的,这里又问了很多,原本以为会问的结果都没问,再次反映了准备不充分、血洗不全面的悲痛......之后就基本结束了。
阿里面试中两个值得思考的点:
1.重写onDraw( )时有哪些要注意的点?
2.onMeasure( )中做了哪些工作?
豌豆荚:豌豆荚是一个华科的学长电面的,做完自我介绍之后就开始问项目,是三次面试中问项目最多的。问了我产品最主要的功能点在哪里,难点在哪里。我说动画,他就问我有没有解决过动画在低端设备上的卡顿问题,我暂时没遇到过就说没有,听他那边的反应大概是觉得我too young这个问题都没遇到过。然后问我最复杂的一个界面、一个View是怎么写的,我就跟他讲了那个根据滑动距离来控制滑动header还是下方ListView的界面,讲到了事件处理相关的,以及我是怎么自定义布局去做这个复杂的东西,中间被他质疑了几次,我没答的很好,怪自己因为过去太久对怎么写的这个也不熟悉了。不过感觉在面试中尽量还是少讲某个东西的具体写法,稍微复杂一点的一时半会人家不看你代码也不能理解你讲的,想要只通过语言讲清楚某个能体现你技术的点不容易,当面的话结合demo可能好一点。
然后又问到了自定义View,这次是问到了invalidate( )里面做了什么,我只看过一部分代码,只好说自己源码看得不多不清楚。之后问了数据结构,然后就让我上一个网站做题,做完了他再打电话过来。
题目大概就是计算一个连续序列里最小子序列和,我之前做过最大子序列和,这个也类似。用动态规划的思想,从第一个出现的负数开始设为min,每加一个数都去和min比较,如果更小则重新赋值,然后处理全部是正数的情况。最终时间复杂度为O(n)。这个倒是完全正确的写出来了。之后打电话问了我下实现,确认正确后就挂了电话,面试到此结束。
感觉豌豆荚这种小公司会更看重项目经历,而大公司则更希望你对基础、底层知识了解透彻,所以代码写的多项目做的多的去小公司更有优势,而学霸可能更受大公司青睐(我也听说有不少人靠刷题过了面试,当然代码能力怎么样就不知道了)。
豌豆荚面试中问的两个需要思考的问题:
1.invalidate( )做了什么?
2.final关键字有些什么用法?(这个真心平时没注意,然而它确实有更多用法由此也可以展开很多内容)
三、总结
经历了这次找实习后,自我感觉有太多东西要学习要完善,所以豌豆荚没过之后就也不想继续找了,太花时间,还是静下来继续学习为好。
回想起来自己最近几个月看书、研究做的太少,主要都在做app,但最终并没有因为项目经历给自己加分,反而忽略了很多其他的技术点,比如每次问到数据结构都要吃亏。项目还是要认真做,不过不能整天就写代码,一定要抽出时间来看书、打好基础,也要有时间去研究一些底层的东西或者自己感兴趣的技术点。之前看了某个大神的总结,他白天做公共的开源项目,晚上做自己的项目,最终效率相当好。每天除了做团队的项目外,能够有几个小时专注在自己的github造轮子上也是一件幸福的事情,我也要开始尝试这种工作模式。
去公司实习,最主要的目的是要获得一个学习的机会,使自己获得提升,而对于我来说,这次的求职经历已经让我发现了自己的不足,也给了我新的学习方向。之前感觉自己写代码越来越没有动力,因为做的工作太多都是重复性的机械工作。这种时候就应该跳出来想想到底是哪里的问题:是功能加的太多?还是自己的结构设计的不好、扩展性太差?一个程序员一定不能只追求实现某个牛逼的功能或者效果,必须不断的审视自己的代码是否足够优雅,不断的重构,长久坚持下去一定能写出真正好的代码。另外就是在做项目之余还要保持自己对技术的热情,如果所做的项目需要用到的技术点恰好就是自己很感兴趣的,那最好,可以每天都专注的去研究这个点去实现。但遇到项目中没有那么多感兴趣的点的时候,有些工作虽然做的不舒服还是要逼自己花一段时间专注的做完,然后就有时间去看自己感兴趣的技术点,这样才不会因为项目枯燥而产生厌倦的情绪。
暂时想到这么多,等下次再把最近了解的Android/Java技术点写一篇文章整理下。