继上次宇宙条面试之后, 笔者备受打击, 决定闭关一段时间好好修炼自己的功力, 所以暂时将简历隐藏, 然鹅突然收到来自阿里巴巴的面试邀约, 怀着忐忑的心里开始了阿里的面试之旅.
电话初探
被告知简历通过评审之后的三天后收到一个来自上海的电话, 我怀着半信半疑的心态接通了电话(害怕是办信用卡的). 对面是个小哥哥, 简单介绍了下自己是阿里的, 询问我有没有时间, 做个简单地电话初面, 看看是否合适在发起后续流程进行正式面试. 当时正在上班的我一口答应, 并且快速冲到了走廊. 出来的我就感觉有点后悔, 因为门外那叫一个冷, 我没有穿上我一千块的保暖大衣, 又不好意思说回去工位穿衣服, 所以全程都在哆嗦中度过.
一开始让我做了个简单的自我介绍, 问我现在在哪里工作, 为什么要离职, 目前手头上跟的什么项目什么的. 然后让我挑一个最近正在做的项目, 聊聊技术栈. 我找了一个我负责构建的项目, 然后从项目背景, 人员分配, 技术栈说起, 巴拉巴拉说了大概四五分钟. 紧接着小哥哥问我为什么选择这个技术栈, 我又巴拉巴拉说完后就说感觉我挺合适, 给我发起正式面试流程. 我一听, 那个激动恨不得立马发起流程! 然后小哥哥问我有什么问题要问他的, 由于外面实在太冷了, 所以我就问了一个问题, 能介绍下您所在部门的业务吗? 这一问可不得了, 面试小哥哥从自己的部门, 再到前景, 再到工作内容给我介绍的明明白白, 说北京有岗位, 但是会先去杭州工作半年到一年时间, 最后说会在一周内联系我进行面试. 由于太冷了, 我就没有再问问题, 就这么愉快地结束了!
这一步没什么问题, 只要放开了和面试官聊就行了, 把你想知道的都问清楚, 把他想知道的尽量都告诉他, 先给对方一个好的印象, 至少让别人感觉你是积极向上的而不是死气沉沉混机会的.
一轮技术面
由于一面告诉面试官我和他不在同一座城市, 而且目前在职无法去现场面试, 他很爽快地答应了可以进行视频面试. 大概过了三天的时间, 又收到来自这位小哥哥的电话, 具体是想和我安排面试时间, 我问了下晚上是否可以, 小哥哥爽快答应, 此时我已经了解到阿里晚上也是正常工作时间, 这和我目前一样. 我们相互约定了时间, 互换心声, 相约不见不散! 到了约定时间我会想起小哥哥说会给我进行视频面试, 我一来懵逼, 既然是视频面试莫非是 QQ 视频, 微信视频? 还在疑惑的我被手机铃声打断, 我一看还是熟悉的号码, 还是熟悉的感觉, 果然是那位可爱的小哥哥. 小哥哥问我准备好了没, 准备开始面试了! 纳尼? 小哥哥竟然是我的面试官, 我一直以为他是 HR 小哥哥呢, 还没待我询问清楚, 他说会发一条链接到我的邮箱. 可能是安排的人比较多, 一时间找不到我的邮箱了, 就说你先来个自我介绍, 此时的我心灰意冷, 不是才认识的嘛, 都已经这么熟悉了还需要自我介绍? 是不是早已经忘记人家了? 当我还在伤心的时候, 我发现时间已经过了三秒钟了, 于是我开始重新介绍我自己, 这次的自我介绍相比之前的要更加详细, 主要是个人的基本情况, 工作能力和未来规划三个方面讲的, 自我介绍完后小哥哥说到挺有想法的小伙子, 我给你发了链接到邮箱里面, 你去看看. 说时迟那时快, 我用了两秒钟就等进了邮箱打开了链接, 我的英俊容貌立马出现在电脑屏幕上, 我也看到了面试小哥哥! 哇, 简直和我一样英俊, 潇洒. 管不了那么多了, 我已经准备好面试了.
突然我的头像缩小了, 屏幕上面出现了熟悉的文本框, 是的, 你没猜错, 现场编码! 第一道题是考察正则匹配的, 题目如下:
特定语法匹配替换
说明: 匹配字符串中形如 =g 文字文字 = 的语法, 并将相应部分转化为对应的标签文字文字
示例:
- transform('=g1.18 进入开发 ='); // <g>1.18 进入开发</g>
- transform('=g1.23 联调(-1)=,=g1.25 发布(+1)=');// <g>1.23 联调(-1)</g>,<g>1.25 发布(+1)</g>
- transform('1.25 发布'); // 1.25 发布
这道题不难, 但是需要考虑没有匹配到的情况该如何处理, 也就是最后一个示例的情况. 大概花了一分钟搞定, 然后满意地告诉小哥哥做好了. 他看了我的结果后立马出了第二道题:
合并数组中相邻且重复的元素
说明: 请实现一个函数 merge, 传入一个数组, 合并数组中[相邻且重复] 的元素.
示例:
- merge([3,2,2,4,5,5,6,2,1]); // 输出[3,2,4,5,6,2,1]
- merge([3,2,3]); // 输出[3,2,3]
- merge([2,2,3]); // 输出[2,3]
拿到这道题我觉得很简单, 于是就开始了正常的排序, 去重. 下面是我的第一次尝试
- function merge(arr) {
- if (!Array.isArray(arr) || arr.length == 0) return [];
- arr.sort();
- var ret = [arr[0]];
- for (var i = 0, j = i + 1; j <arr.length; j++) {
- if (arr[i] != arr[j]) {
- ret.push(arr[j]);
- i = j;
- }
- }
- return ret;
- }
小哥哥说可以调试, 我打开了控制台, 以最快的速度粘贴了我的代码后发现结果不对呀, 怎么搞的? 才发现是因为顺序改变了, 不能进行排序. 再次我的第二次尝试
- function merge(arr) {
- if (!Array.isArray(arr) || arr.length == 0) return [];
- var ret = {};
- for (var i = 0; i < arr.length; i++) {
- ret[arr[i]] = i;
- }
- return Object.keys(ret);
- }
我发现这样确实可以去重, 奈何顺序也跟着改变了, 这该如何是好呢? 这时小哥哥发话了, 这道题很难吗? 我立马回了句不难, 我不应该排序的, 然后他说根本不需要排序可以使用 ES6 的语法. 纳尼? 这道题不是考察算法而是考察 ES6 语法, 打死我我也不信, 这明明是算法... 就在这零点零一秒的时间里, 我的任督二脉突然被打通, 我没在抱怨了, 而是以最快地速度进行了我的第三次尝试
- function merge(arr) {
- if (!Array.isArray(arr) || arr.length == 0) return [];
- var ret = [];
- for (var i = 0; i < arr.length; i++) {
- if (ret.indexOf(arr[i]) == i) {
- ret.push(arr[i]);
- }
- }
- return ret;
- }
还没写完, 小哥哥就同步到我的想法了, 对嘛! 这就是我想要的答案, 你考虑那么复杂干嘛? 其实还可以一句代码搞定:
- [...new Set(arr)];
- // or
- Array.from(new Set(arr));
这里是对 ES6 自带 API 的考察, 然后顺势给我同步出第三道题
函数组合运行
说明: 实现一个方法, 可将多个函数方法按从左到右的方式组合运行.
如 composeFunctions(fn1,fn2,fn3,fn4)等价于 fn4(fn3(fn2(fn1)). 示例:
- const add = x => x + 1;
- const multiply = (x, y) => x * y;
- const multiplyAdd = composeFunctions(multiply, add);
- multiplyAdd(3, 4) // 返回 13
初一看以为是函数的柯里化, 细看又不是, 于是开始了我的尝试套路
- function composeFunctions() {
- var args = Array.prototype.slice.apply(arguments);
- return function() {
- if (args.length == 1) {
- return args[0].apply(this, Array.prototype.slice.apply(arguments));
- }
- return composeFunctions(...args.slice(1))(args[0].apply(this, Array.prototype.slice.apply(arguments)));
- }
- }
以上是我的第一次尝试, 当时我因为传错了参数, 也就是最后 return composeFunctions 那句传错了参数调试死活出不来, 我感觉我的思路没错呀, 为什么结果不对呢, 正打算打开 debug 工具调试, 小哥哥开口说话了, 问我这个题目很难吗? 我当然说不难了, 这辈子都不会觉得难的. 然后他开始帮我分析, 他说这个题怎么能返回一个函数呢? 我...emm? 我说对, 不应该返回函数, 此时他里面意识到有问题就说是返回一个函数哈, 我...emm? 此时我已无法用言语表达我的尴尬之情. 他问我那问题出在哪里? 我说我感觉写的没问题, 但是死活出不来, 然后我看他在阅读我的代码, 然后说了句好的, 我们直接开始面试吧! 本来有四个题, 我觉得你做三个就可以了!
前戏大概花了十五分钟左右, 然后直奔主题.
第一个问题是老生常谈的居中问题, 如何用 CSS 来实现水平垂直居中. 我用了六种实现方案, 其中最后一种是基于 vertical-align 配合文字基准线来实现的, 有兴趣的小伙伴可以自行找下该方案.
第二个问题是 Promise 的用法以及实现原理.
第三个问题是前端存储方式, 以及它们之间的优缺点.
第四个问题是移动端页面适配解决方案, 我的回答是淘宝的 flexible.JS 来做屏幕适配, 然后面试官询问了它的实现原理, 以及浏览器中几种长度单位 (rem,em,px) 的特点和区别, 很可惜这块我答得不是很好, 没有完全理清物理像素和逻辑像素的区别, 面试官小哥哥也告诉我了解一个框架的实现原理比用一个框架更有意思, 不是么?
第五个问题是 React,vue 之间的区别和实现原理, 另外问了下 React 中 Fibber 是什么? 我只知道 Fibber 是调度, 可以提升 react 渲染的效率, 然鹅不太清楚具体的实现原理.
第六个问题是 JS 的 Event Loop.
第七个问题是三次握手和四次挥手.
最后问了我最近最有成就感的项目, 并介绍下项目的技术方案, 哪些地方让你特有成就感, 还有遇到的困难是什么, 如何解决的?
最最后面试官对我进行了一个评价, 说我知道的还挺多就是表达不是很流畅, 让我今后要多注意, 我连声达到好好好! 紧接着就说先聊到这里, 有什么问题需要了解的吗? 我问了两个问题, 第一个是他们对人才的定义, 想要招个什么样的人? 小哥哥微微一笑, 说道这个问题太大了, 立马反问给我, 让我给人才下个定义, 其实我就是想知道我今天的表现如何所以才提了这个问题, 所以我就巴拉巴拉说了我的人才观, 随后他也像我阐述了他的观点. 紧接着我就问第二个问题, 面试结果什么时候能知道? 他说最迟一周, 后来我发现这是所有面试官的一个套路, 只要问道肯定就会说一周之内给结果. 最后就愉快地结束了今天的面试, 总体来说还是比较轻松的.
二轮技术面
一面面完大概过了四天左右收到了来自杭州的电话, 告诉我一面通过了约个时间进行二面, 并且和二面面试官互加了微信. 后来我才发现, 二面面试官就是当初某 boss 上面跟我聊天的大佬, 技术专家级别! 我怀着忐忑的心情等待接受二面的摧残, 因为二面是部门负责人面.
面试终究还是来了, 看到来自杭州的电话迫不及待地接通, 听说话的口音感觉面试官很奈斯, 瞬间就没有了压力. 首先让我做了下自我介绍, 接着就开始正式的面试环节.
自我介绍中粗略地介绍了我目前做的业务, 面试官让我挑一个最熟悉的跟他聊聊, 具体从技术方案, 遇到的问题, 解决情况来阐述. 前十来分钟基本上就是按照我的项目来进行的, 一切都很顺利. 紧接着问了几个 ts 相关的问题, 就说今天的面试先这样, 问我有没有问题要问! 我一览懵逼, 因为整个面试过程都很顺利聊得也很开心, 突然结束是不是自我感觉良好, 他人感觉不好呢? 虽然有一系列疑问, 但是我只问了一个问题, 就是当天在公司干活时遇到的一个问题, 他先是笑了一下然后问了下我是如何解决的, 我巴拉巴拉说完后, 他提出自己的见解. 说非常欣赏我的处事方法, 第一次被面试官夸赞的感觉简直受宠若惊! 然后告诉我如果是他他会如何解决, 大佬果然是大佬, 我默默地叹息道! 随后就结束了二面.
三面 boss 面
二面结束后又是漫长的等待, 等了十来天时间还没联系我, 我觉得应该是跪了吧. 由于我加有一面, 二面的面试官, 所以就试探性地问了下二面面试官我的情况, 他说你通过了, 不过 boss 最近比较忙没有时间面试, 所以就拖了这么久, 再耐心等等! 知道结果的我受宠若惊, 决心要好好准备.
距离二面结束两周后终于有一个杭州的电话打进来, 果然是阿里的 HR, 跟我约了周末进行视频终面. 并告诉我 boss 很忙一定不要失约.
终面的前一晚 HR 小姐姐打来电话说需要调整面试时间, 因为 boss 临时有个会议, 于是向后延了五天时间.
面试的时间是工作日, 我请了假回到家中, 虽说前两面都很顺利, 但是第三面还是很紧张. 三面使用的是阿里的内部会议系统, 到达指定时间后我连接上去没有任何回应, 打电话给 HR 小姐姐始终占线, 瞬间心里感到更加紧张, 五分钟后对方接了进来. 我看到一共有两个人, 一个是传说中的 boss(男), 另外一个 (女) 没有猜到是什么岗位. 简单地询问后就直扑主题.
首先让我做个自我介绍, 介绍完后问我在京东做什么? 我当时脑子是懵逼的, 我就说我在做什么, 做什么? 两句话介绍完后, boss 接着问, 你所说的 XXX 产品是个啥? 真是一波未平一波又起, 我的脑子已经一片空白了, 简单地介绍了产品后, boss 抬头看了下我说, 我没有问题了, 又看了下另一位面试官问到, 你还有什么问题吗? 另外一位面试官就问我离职的原因是什么? 我说想去更好的平台工作. 紧接着说我的求职意向是北京, 但是他们是在杭州, 我说 HR 告诉我北京有岗, 面试官答到要先来杭州工作半年到一年才能去北京, 我说没有问题! 然后就问我还有什么问题吗?
我提了三个问题, 第一个仍然是想知道他们对人才的定义, 得到的答案是问题太大了, 换个问题吧. 第二个问题是前端的发展路线, 从 Ajax 到 node, 再到数据驱动, 下一个会是什么呢? 在一旁看手机的 boss 抬头看了看我说道, 不好意思我不是搞前端的, 你换个问题! 我说出了我的第三个问题: 结果什么时候能出来? 得到的答复是一周内, 然后就说今天先这样, 后面有消息会有电话通知. 一脸懵逼进来, 一脸懵逼出去, 就这样结束了三面.
由于是请假所以面完后直奔公司继续工作, 刚坐下就收到了来自阿里巴巴的邮件通知, 以为顺利通过, 结果一看我的简历直接被推到了蚂蚁金服! 说明 CBU 流程已经结束, 我的简历得到了释放, 也就意味了面试跪了. 很是失落, 于是截了个图发给了我的一面面试官, 他说帮我问问 boss 怎么回事. 很快告诉我未通过的原因是项目的复杂度有点问题. 并不断安慰我说很正常, 面试通过率很低, 让我不要灰心, 面试是很看运气的. 另外告诉我一面和二面面试官都觉得好可惜, 但是没有办法. 让我试试其他的部门, 再次感谢非常可爱的面试官小哥哥, 全程对我的帮助! 虽然很是失落, 但是面试之后的总结还是必不可少的.
面试总结
相比其他的企业, 我发现此次面试阿里过程中被问到的问题还不算很难, 阿里更看重的是基础, 而不仅仅停留在会使用的阶段. 所以平时要多看看优秀开源项目, 多看看基础的内容, 多了解底层的实现原理.
对于 boss 面问到的问题, 我总结了一下其实这两个问题都很大. 首先第一个问题, 你在做什么? 其实潜台词就是问你都做了什么项目, 此时正确的做法是介绍自己参与的项目, 所在项目的角色, 然后详细讲解你参与项目的技术方案, 开发过程中遇到的问题以及如何去解决这些问题, 将主动权完全交给你, 你可以自由发挥把面试官带到你的思路中. 其实面试官更关心的是你解决问题的过程, 而不是像我一样两句话搞定. 第二个问题就是要详细介绍自己的产品, 产品和其他竞品的优势在哪里? 以及你贡献的内容和目前取得了什么样的成就等等. 这种开放性的问题说好答也好答, 说不好答也不好答, 完全看自己的语言组织能力.
阿里一直以来都是我心中想去的公司, 在中国的互联网公司中也是名列前茅. 所以不是随随便便就能进入的, 要想成功进入阿里除了过硬的技术基础外, 还需要有良好的表达能力, 处事能力等软实力. 一次失败不算什么, 认真总结, 在下一次遇到同样的问题而不至于用同样错误的方法去处理才是最重要的. 就和农药里面的程咬金一样, 反正你打不死我, 不服就来打我呀!
来源: https://juejin.im/post/5c90f573e51d450a7d7dfc75