阿里前端 暑期实习 笔试+六面经历
lz是美帝的留学生,一开始是EE专业,大二下学期才转到cs,简历上毛都没有所以秋招的时候,美帝这里一家面试都没收到。。
最后开始投国内的暑期实习,然后也陆陆续续收到了一些面试。阿里算是流程长的了,二月中旬投的一直面到现在,最后还是用别的offer去催才加快了速度,不过面试的体验还是非常好的~
然后由于流程很长了,具体的问题都记不太清楚了,就给大家讲一下大体的经历吧。
一面:简历面?
可能是简历面来着?我也不太清楚。
总之先问了一些项目的问题,比较细
- 记得问到了项目里怎么保证安全(jwt)
- 问到了项目的难点
- 问到了在项目中的角色(leader)
- 整体来说讲得比较细,要求你的项目有东西可以说
然后问了一些基础
- ES6有哪些新的feature(说到了weakmap和weakset)
- 那你讲一下weakmap和weakset是什么
- 然后引申到了js的gc和内存泄漏
- 然后继续引申到了闭包
- 别的记不太清了,总之就是顺着你说的追问下去
笔试
lz是通过牛客内推的,不知道为啥还要写笔试。。
然后笔试四道题,两个小时,说是unit test加分,typescript加分。
lz先是花了一小时AC了三道题 + unit test(chai,mocha,nyc三件套)
最后一道题,剩下的一个小时都花上面了也没做出来。。结束后想了想,我的思路应该是对的,但就是想得太复杂了。第二天我又花了一个半小时,AC了,然后把code和test一起发给了面试官,他说很好。
就是这道题,不知道有没有人做过
/**
* 平铺节点数组转嵌套树
* 说明:将一个包含深度信息的节点数组转换成一棵树,要求只能遍历一次该数组
* 输入值:TreeNode数组 TreeNode为包含title, depth(正整数,深度不限)字段的Object
* 输出值:组装好的嵌套树,子节点挂载在对应父节点的children字段上
*/
/*
举例 (title字段仅为便于理解,实际无固定规则)
输入:[
{ title: '1', depth: 1 },
{ title: '1-1', depth: 2 },
{ title: '1-1-1', depth: 3 },
{ title: '1-1-2', depth: 3 },
{ title: '1-2', depth: 2 },
{ title: '2', depth: 1 },
{ title: '2-1', depth: 2 },
]
输出:[
{
"title": "1",
"depth": 1,
"children": [
{
"title": "1-1",
"depth": 2,
"children": [
{
"title": "1-1-1",
"depth": 3
},
{
"title": "1-1-2",
"depth": 3
}
]
},
{
"title": "1-2",
"depth": 2
}
]
},
{
"title": "2",
"depth": 1,
"children": [
{
"title": "2-1",
"depth": 2
}
]
}
]
*/
然后是我个人的解法。用递归。可以解决任意顺序的input。
function arrayToTree(arr) {
const ans = [];
// iteration over all objects
for (let obj of arr) {
// get key name
let keyName = "";
for (let key in obj) {
if (key !== "depth") {
keyName = key;
break;
}
}
// use recursion to parse object
let level = obj[keyName];
// console.log(ans, obj);
arrayToTreeHelper(ans, obj, keyName, level);
}
return ans;
}
function arrayToTreeHelper(ans, obj, keyName, level) {
// base case, append to ans
if (level.length === 1) {
// find where to insert
let pos = 0;
let currentTitle = "";
// get "title" of object already in ans
for (let key in ans[pos]) {
if (key !== "depth" && key !== "children") {
currentTitle = ans[pos][key];
break;
}
}
while (pos < ans.length && obj[keyName] >= currentTitle) {
// if encounter temporary object created before
if (obj[keyName] === currentTitle) {
ans[pos] = { children: ans[pos].children, ...obj };
return;
}
// keep comparing key
pos++;
for (let key in ans[pos]) {
if (key !== "depth" && key !== "children") {
currentTitle = ans[pos][key];
break;
}
}
}
// insert obj to pos
ans.splice(pos, 0, obj);
return;
}
// recursively find position to insert
const currentLevel = parseInt(level.charAt(0)) - 1;
// if ans[currentLevel] does not exist yet
if (ans[currentLevel] === null || ans[currentLevel] === undefined) {
// assign a temporary object
ans[currentLevel] = { children: [] };
ans[currentLevel][keyName] = obj[keyName].slice(
0,
obj[keyName].length - level.length + 1
);
}
// console.log(ans, currentLevel);
if (ans[currentLevel].hasOwnProperty("children")) {
arrayToTreeHelper(ans[currentLevel].children, obj, keyName, level.slice(2));
} else {
const children = [];
ans[currentLevel]["children"] = children;
arrayToTreeHelper(children, obj, keyName, level.slice(2));
}
}
二面
二面先是讲了下项目,然后也是问得很细。
因为我们前端用react,就问怎么做SEO。
我说打算用prerender.io做(还没开始做,但是看了眼),他就问prerender.io的原理,这个确实没有去仔细看。。然后二面我记得就这一点有瑕疵,别的回答得都ok。
后来去看了才知道,原来是个中间件。
三面
三面也还是讲了点项目和基础,然后还有怎么设计关系型数据库等等。
具体的记不太清了,总之问得没有一面二面那么细。
我以为这是技术面的最后一面了,没想到面完才知道,我还没有面过总监面。。
四面:总监面(P9大佬)
面对P9大佬的时候还是很慌的..然后面的内容依旧还是一些项目的细节,再加上一个设计的题目。
问我如果pdd的app要增加一个游戏的功能,并且提供排行榜要怎么做。
我说大体上把游戏分成一个独立的模块,留一个接口来接收购物页面法的物品信息,然后根据那个信息,使用简单工厂或者抽象工厂模式创建实例,然后在新的页面打开。
不知道有没有更好的设计方案。。
五面:交叉面
五面很短,大概只有20min。
因为我前面面过太多了,能问的不多,所以很快就结束了。
大致上问了怎么区分登录和未登录的用户,以及提供不同的功能(jwt)
然后问了项目的定位,以及怎么处理流量大了以后的问题。我说是设计数据库(MongoDB)的时候,就是按照存储大量数据的目的设计的,除此以外还有负载均衡的技术等等。
hr面
hr小姐姐人很nice。问了我学校以及转专业的问题,还有一些对于未来的规划。
总结
总结下来就是,为啥我一个实习岗位也有这么多面试啊。。而且我还是内推的,结果连笔试都写了。。
而且阿里的流程真的好长啊,别的公司offer早就下来了,阿里还在面。。然后还问我鹅厂面到哪里了。我说鹅厂hr面结束了,于是他们似乎给我加快了一些速度,说是很多他们看好的人都跑去鹅厂了。。
(然后我鹅厂hr面后就再也没有了消息2333)
#阿里巴巴##实习##面经##前端工程师#