我从去年年初开始在美团当校招面试官,参加了 17 届春招和 18 届秋招两届面试,总共就面试了五十多个人。本来我也就是刚开始学着当面试官,不该妄谈经验,但是因为最近换了一份工作,未来几年都不会再有国内互联网公司的校招经验了,所以不如趁热分享一下,省得知识过期。本文是个人体会,而且经验不多,读者姑妄听之就好,不必太认真。
这篇文章主要针对的是徘徊在 offer 线上下的同学,因为作为面试中的初试官,也在这部分同学上花心思比较多,如何保证通过的质量、如何保证面试的公平性等等,明显能通过的同学反而不用花太多心思,offer 的定级交给复试官就好。文章中会用校招圈子的通用标准来描述 offer 等级:批发价、SP、SSP。更高的等级(例如阿里星)就不讨论了,拿到 SSP 的候选人我都没见过几个。
开始之前也必须声明一下, 面试是一件随机性很大的事情(PS:之前听过一个准备华为面试的讲座分享,讲座上就提到过很多大公司就像华为一样都有专门的面试团队。另外建议大家在面试一个公司的时候了解一下这个公司到底是不是适合自己、了解一下这个公司的价值观。最好不要海投!!!) 。看学生的帖子经常会说某个公司的面试是什么样的,但是其实面试的标准每个人都不同,面试官会用自己的方法去评估一个人在不同维度上的分数。在实际操作中,公司很难通过培训等手段统一整个公司的面试标准。一个组、或者是公司派往一个城市的面试团队之间倒是有可能通过不断磨合来统一标准。反过来说,整个互联网圈子由于人员流动太快,公司之间的面试体系差异倒是不大,一个面试官可能今年在百度,明年在阿里,他会用同样的体系去评估候选人,然后根据公司的标准去选择录取线。
在面试的时候,面试团队会尽量统一标准。不同的团队由于负责人的偏好可能会有不同的倾向、比如有的团队会看重潜力、看重学习能力,另外一个团队则看重基础知识,要求录取的同学基础必须扎实。因为标准不同,一个公司派往一个城市的两个团队可能会给一个同学给出不同的结果。所以我认为,在后端技术面试体系(而不是招聘流程)的角度谈公司意义不大。最近几年校招同学在论坛上对面试官的评价和讨论越来越多,面试官出言不慎很容易给公司惹事,因此公司往往要求面试官少给学生反馈。我看到很多同学面试几场下来,只知道面试官问了什么问题,却对面试官如何从这些问题中勾勒出一个候选人的知识结构毫无概念,也不知道自己再哪些方面有缺陷,希望本文能给你提供一个不一样的视角,学会从面试官的角度思考如何提问,如何评估候选人的水平。
获取面试机会,也就是投递简历,通常就是三种渠道:内推、网申和霸面。
各个公司都会给内推多一点机会,有的承诺不需要笔试,有的不承诺但是通过机会也比网申大一些,总之尽量找人内推。但是内推也不是一定能得到面试机会,通过 HR 筛简历之后可能面试官还要筛一次简历(或者是各个组自己从简历池里挑人,有的简历一直到最后都没被挑走)。
网申一般需要笔试,笔试通过还需要 HR 筛选才能见到面试官。笔试现在都是网上答题,客观题就不说了,主观题(例如写代码)一般除了系统跑测试用例之外还会有面试官人工判卷。如果是算法题,面试官会判断是否最优解,如果不是最优解,即使测试用例都通过了也会扣几分。笔试的标准一般不会太高,能写出来就行,没有最优解也能拿到面试机会。
不同公司的笔试时间难免会冲突,只能做一个,这时候选你喜欢的公司做就行了。互联网行业的校招中优秀学生的话语权很大,只要简历够好,不参加笔试也有可能得到面试机会。
面试的当天按时到场就可以了,实在不能来可以提前问问 HR 能否改个时间面试。放鸽子确实不礼貌,不过 HR 通常也会打电话问一下原因。如果是觉得肯定通过不了,我倒觉得不妨试试,参加面试实战绝对是提高最快的方法。
如果没有得到面试机会,去现场霸面也是可以的。提前一点到,把简历交给 HR,然后等通知。由于面试当天一般会有爽约的学生,所以也会有闲着的面试官,如果是接受霸面的公司,HR 会收集简历给面试官看一下,觉得简历不错的通常会得到面试机会,而且不会因为是霸面就提高通过标准。
另外,几轮面试官之间会传递一些信息,例如哪方面很好,哪方面有欠缺,哪方面没问之类的。所以也不要纠结为什么某轮面试官问的方向有点奇怪,这都是为了更全面的评估候选人。
在校园招聘中,后端可以说是要求最宽的职位了。你如果去面试 iOS,肯定要做过 App,如果去面试前端,肯定要写过 JS,如果要面试算法,肯定要做过机器学习。但是面试后端,却不一定要做过后端。在实际面试中,我们遇到过各种专业的同学,通信、自动化已经算是关联性较高的了,化工、机械之类的工科也不少,很多同学都完全没有接触过后端开发,但是拿到了后端 offer。
在面试中,我会按照三个方面去考察:
一个企业无论按照什么样的标准去招软件工程师,手写代码都是基本的能力。尤其是校招的时候,应届生的项目经验不多,手写代码的重要性就更高了。但是代码题一般不会太难,像手写红黑树这种难度的题一般不会出现。
考虑到面试时间通常都是半小时到一小时之间,手写代码的时间也不会超过 20 分钟,按照这个时间去卡,就是默写常见算法(查找、排序等等)或者简单一些,但是需要现场思考的代码,一般是 LeetCode 上的 medium 或者 easy 难度,如果 easy 难度的题都做不出来,面试官心里真的要打问号了。
除了手写代码之外,可能会有一个不需要写代码的算法题,考察对数据结构的理解和分解问题的思路,这个的难度会大一些,也没办法估算范围,只能平时多思考了。
计算机基础通常指的就是考研的四门课,计组一般不会有人问,但是如果没学好计组的话操作系统、数据库之类的题可能会理解不深。另外三门课也都是计算机和软件学生应该具备的基础知识。
数据结构的水平可能在算法题里体现出来,如果直接问的话一般不会问太难。有可能问链表和数组的区别这种热身题,也可能出二叉树前中后序遍历这种简单的动手题。
计算机网络可以考察的内容主要集中在 TCP/IP 协议上。还可能问 DNS、七层模型之类的问题。网络这门课很多同学偏向于死记硬背,对原理性的东西掌握不足,面试的时候一般会先问是什么,然后问为什么,能把协议设计的原理讲明白才算是合格。
操作系统主要是问进程线程模型,进程间通信,内存模型,pv 操作之类的。和计算机网络类似,这门课也有很多同学死记硬背,面试的时候一般会结合编程问,例如问 Java 中的进程线程实现之类的问题。来考察是背下来的还是真的理解。
前面说面试后端可以没做过后端,但是如果做过后端的话绝对是加分项,也容易成为面试的主战场。对于面试官来说,最需要的一个就是自己非常熟悉,候选人也下过功夫的领域,这样才能提出有足够深度的问题,考察出候选人的学习能力。这部分因为不是每个人都要掌握的,所以一般是结合简历上的项目经历问,简历上写做过什么才会问什么,千万不要在简历上写自己没做过和只是打了一下酱油的项目。
我认为属于后端的领域包括:编程语言和框架(例如 Java 语言和 Java Web 框架)、数据库、HTTP、中间件、分布式系统、系统设计和解决实际问题的能力。这里语言用 Java 做例子。
Java 语言在语法方面可以考察的不多,很多面试官喜欢问 Java 类库的实现,比如哈希表就是一个很常见的题,可以问 HashTable, HashMap 的区别,如果需要并发的话怎么办,ConcurrentHashMap 的实现原理,HashMap 在 JDK 不同版本的演进,何时从链表换成红黑树等等。如果要在简历上写熟悉 Java 的话,最好把常用的数据结构代码都读一下。此外,多线程、垃圾回收也是非常常见的问题,多看面经的都知道,不再赘述。
Java Web 大家熟悉的一般是 SSH,如果有 Spring MVC, MyBatis, SpringBoot 的知识也很好。这套技术栈面试官一般都很熟悉,候选人的水平是简单的照着视频做过一遍开发,还是深入了解过框架的原理,甚至自己试着仿制和修改过框架,都很容易考察出来。
数据库主要指的是 MySQL 这样的关系型数据库。大家在学校里一般都学过数据库原理,比如索引的数据结构、三范式。在实践中一般也做过索引优化,选一两个例子问原理,还可以考察对数据结构的理解。
HTTP 对于做过网站的同学应该都熟悉,尤其是有的同学简历上还写熟悉 RESTful,可以问的问题都很多,比如 GET POST 的区别可以很容易的看出学习的深度。另外 Session 和 Cookie 也是非常好的考察点,是照着视频搭的网站还是自己研究过,研究的多深一问就明白了。在我的经验中,只有一半做过 Web 的候选人知道 Session 是依赖 Cookie 实现的。
中间件和分布式系统一般是实习过的同学才会问到。应届生可能理解不会太深,但是还是有很明显的区分度。例如 Redis 很多人都会写到简历上,有的同学只是会调接口,有的同学知道接口后面是怎么实现的,还有的同学不但知道实现,还思考过原理,能讲出来为什么要这么做。
系统设计是很好的题目,聊起来轻松,就是有些费时间,不管候选人的水平怎么样都能花掉 10 到 20 分钟。有时候前面能问的很深入,就没有时间做系统设计,也有简历太简单,没什么可问的,就问两个系统设计凑够时间。我出系统设计题一般是描述一个简单的系统,如果是业务系统,让候选人写出数据库表就可以了,如果是性能要求比较高的系统,可能会涉及到对中间件的使用和 sharding。系统设计中可以考察的点就多了,能否考虑到一致性、幂等、冗余、横向扩展、未来需求、搜索、统计等等的需求都可以体现出来。
最后可能还会注意到项目中一些比较难的问题,让候选人复述当时是怎么做的,如果问题很通用的话,还可以增加条件,让问题变得更复杂,现场思考解决方案。这些都是很难提前准备的,但是如果解决问题的时候做过足够多的调研和思考,在面试的时候都能反映出来。
在上述的知识范围中,如何确定一个候选人是否通过、和给什么等级的 offer 呢?我相信每个公司都为确立标准和统一标准费尽了心思。但是最后落到面试官手里的并不是一个包罗万象的打分表,而是前后几轮面试官在沟通一个个候选人的评价时形成的感觉。
在标准的确立上,有的 leader 会非常看重候选人的学习能力,只要表现出来很强的学习能力,就算基础知识很差也可以。还有的 leader 要求基础必须好,就算很聪明,对计算机基础没有足够的了解也不行。如果想多收 offer,而不是碰运气捡一两个 offer 的话,最好能把自己的短板都补齐,在所有的领域都做到有基础,然后有突出的优点。
手写代码是最最基本的要求,面试软件工程师不写代码肯定是不行的,但是不同的面试官也有不同的要求。有些公司的面试会让候选人手写二分查找,冒泡排序之类的,作为正在找工作的应届生,很多人都会把常见的查找和排序算法背下来,所以考察效果一般。
面试官一般都有自己得题库,我也是会准备几道题,上来会先写一个单向链表空间复杂度 O(1) 的翻转,这道题应该说足够简单,从我的经验看,80% 的人都能写出来,写不出来的话如果还有时间可能会再出一道简单的题,两道题都写不出来就可以找题目杀时间了。第一道题写出来就会再出一道稍微难一些的题,如果两道题都能写出来,代码就算合格了。第二道题一般有很多种解法,也有一些扩展问题,如果思路很清晰,能直接找到最好的解法,扩展问题也回答的很好,在代码部分就算是表现优秀。如果思路不是很清楚,但是经过提示之后想到了方法,这轮只能算是勉强过关。
一般的后端面试,写代码都不会出很难的题,一来时间有限,太难就没办法问别的了。二来比较难的算法题,思路都十分的精巧,面试的时候能做出来的人,大部分都是刷题的时候做过,而不是水平高到能在几分钟之内想出来。其实在后端开发中,只要对常见的数据结构理解充分,能够灵活应用就够了。
计算机基础知识的三个方面,学计算机的同学通常都了解的不错,跨专业的同学在这方面可能会适当放宽,但是也不能一无所知。一般数据结构是必须掌握的,操作系统和网络如果没学过可以不了解。
举一个例子:TCP 建立和断开连接的过程候选人一般都能写出来。写出来之后我会问,为什么 TCP 断开连接要比建立连接多一次操作?这个问题听起来很傻,但是不是所有人都能答出来。如果这个问题回答不出来,可以说 TCP 的知识只是死记硬背的,根本不理解。还有一个知识点是 2MSL,知道这个时间是怎么推算出来的,差不多就是所有候选人中的前 30% 了。
除了手写代码和计算机基础,剩下的方面都是可选项,很多硕士应届生,研究生期间和导师做某个方向的研究,从来没写过后端应用,那只要基础知识很扎实,研究做的也不错就可以了。还有一些同学正好相反,基础知识比较差,但是动手能力很强,自己做过许多东西,这类就要求关于项目的问题回答的很好,表现出很强的自学能力才能通过。
项目的问题我举个例子,如果一个同学做过微信公众号的支付部分,那我会让他画一下微信支付的流程图,然后问从微信的角度考虑,设计流程时,如何防止用户篡改价格,如何防止重复支付,如果网络连接断开了,怎么获取支付结果,如何防止重放攻击等等。真的做过项目的同学,至少流程图是能画出来的,但是这远远不够。能够从微信支付的流程中学到支付 API 的设计思路,并且在自己设计 API 的时候能够用上,才算是学习能力强的候选人。
代码、计算机基础、后端这三个方面都合格,或者某一方面有缺陷,但是有优势能补上的同学就能拿到批发价的 offer 了。批发价的范围很广,从刚刚及格,到能力相当全面但是没有突出亮点的同学都会拿到批发价。
SP 根据不同公司的情况差别就很大了,有的公司求贤若渴、品牌不够或者批发价给的低,都有可能导致 SP 比较水。我在美团的时候见到的 SP 很少,很多在 BAT 拿到 SP 的同学在我们这里都没拿到。通常来说拿到 SP 的同学都有一两个大公司的实习经历,并且对自己实习时的工作非常熟悉。
关于实习,我看到有很多同学说实习没有用,其实并不一定。实习很看公司,如果是去小科技公司改页面或者做做 CRUD,给什么任务就做什么任务,对公司的框架、技术体系、业务运转都一片模糊的话,实习的作用确实不大。但是如果有在一二线互联网公司中,深度参与到项目中的实习经历,可以在项目这部分远远超过在校园里自己做练手小项目的同学。
要想从实习经历中表现出很强的学习能力,实习的时候一定要积极,不光交给你的任务要完成,还要努力了解整个系统的架构,最好还要知道架构设计的原因,在了解原因的时候还会触及到业务背景。实习是一次很全面的考验,勤奋的同学可能会努力干活,但是没有足够的好奇心和自我驱动力很难了解到面试官想问的那些问题。
对于没有实习的同学,也不是没有办法,比如参加竞赛。ACM 自然最好,没有参加 ACM 的也可以参加一些比较偏向动手的比赛,我印象很深的是有一个同学参加阿里中间件竞赛,虽然没进决赛,但是讲初赛的几轮改进已经表现出很好的学习能力,在 Java、操作系统、数据结构方面都有明显的进步过程。另外还有一个同学参加微软的创业大赛做了一个 App,比一般同学练手做的 App 完成度高很多。另外,如果有兴趣,自己钻研一些开源系统也是很好的加分项,比如有些同学精读 Linux 源码,面试官问不出极限,肯定会给很高的评价。
在面试的时候,因为要考察候选人的学习能力和自我驱动力,所以难免对计算机专业的同学的要求更高,对研究生的标准比本科生更高。同理,工作之后再考研的同学,我们也会有更高的要求,如果研究生期间只是沿着工作时的老路做些类似的系统,连技术栈都没有换,那工作经历对候选人肯定是减分项。同样在社招时,我们对候选人参加工作的时间也会有一些考虑,对于工作八九年还在做初级工作的工程师,也会考虑他是否学习能力不足。
这篇文章写了这么多知识点,但是大部分都是在校园里会学到的内容,我也不觉得应届毕业生拿到一份年薪 20 万的 offer 是多么难的事情,至少相比其他行业 8-10k 的 offer 来说难度没有高很多。对于非计算机专业的同学,要想拿到 offer 一般都提前两三年开始准备,并且付出了很多的努力。参加三四个月的培训拿到 offer 的例子,不是没有,但是真的很少。互联网公司的面试一般超过两个小时,我不认为培训的时候教的那些技巧能够骗过面试官,所以想去一线公司的同学,最好还是早点准备,把基础学扎实了,再实实在在的做几个项目。
感谢阅读到这里的同学,祝大家都能拿到满意的 offer~
我是@程序员柠檬橙 关注我,学习更多编程知识!
微信搜「后端技术学堂」回复 「1024」 获取编程学习资源,若有帮助,请点赞转发支持一下~
点击下方「了解更多」下载学习资源