【字节日常实习-前端凉经】
- 一轮 电话面
- 二轮 视频面
博主人生中第一次面试竟然是字节跳动,真是蚍蜉撼树哈哈。当时无心插柳随手投了一个,没想到对方不在意我的非科班身份,给了我面试机会。
坐标杭州,背景是双985非科班硕士,除了肯加班一无是处。
一共三轮面试,博主水平太差,在第二轮就凉凉了。在这里感谢字节给我的面试体验,我会继续努力的。总结一下两轮面试,供大家参考。
一轮 电话面
面试官上来先说大概十几分钟,最后被我扯到了20分钟。
1. 做过什么项目?
生而为非科班,我很抱歉,只有一些和前端无关的算法项目和自己写的一个蹩脚的博客系统(重点还在node.js上…)
2.为什么选择前端?
3. 计算机基础怎么学的?
博主耿直地把计算机网络、数据结构与算法、操作系统挨个讲了一下。操作系统的确没有系统学过,不该讲的。编译原理么…
4. 讲一下计算机网络的分层结构
我说我看过《自顶向下》,面试官就问了这个问题。
5. 快速排序大概讲一下?
我说我数据结构是刷LeetCode为主,所以面试官问了这个问题,这个不难。接下来又进一步问了快速排序pivot
如何选择(优化)。没有看过《算法导论》的我,很抱歉…不会。面试完补了一下,可以参考这篇博文。
算法真是博大精深…我以为我会手写快排就行了,太天真…
总的来说,第一轮面试官是有看过我简历(知道我是非计算机专业的),针对性的提了一些比较友好的问题,感谢这位優しいの面试官。
二轮 视频面
收到第二轮面试邀请,点开链接看到牛客网的房间啊,哦吼完蛋。我意识到自己应该是过不了这一轮的了。盛传字节上来两道hard,以我这种一道medium都可能要做40+min,hard看运气AC的水平,肯定是要凉的。不过最终只有一道medium … 面试官几次提示我,最后还是没写好,这只能怪自己算法不扎实了。
1. 获取一个DOM树中,div节点的个数
面试官一上来,先BAN掉了document
的方法,说那样直接一步就出来了(其实我不知道怎么一步就出来了),然后我就懵逼了,因为DOM操作我记得document的方法…
后来面试官善意提醒我,DOM是什么数据结构?我回答是树。可惜当时太紧张了连递归都忘了用了,面试官引导我用深度遍历,还允许我用伪代码…
事后在网上也没搜索到原题答案,我就自己写了一个,有错误的地方请大佬指教。
<div id="app">
<div>
<div>重整旗鼓</div>
<div class='fighting'>
<div>再接再厉</div>
</div>
</div>
<div>冲冲冲</div>
</div>
<script>
function getDivNumbers(node){
let cnt = 0;
if(node==null || !node.hasChildNodes()) return 0
for(n of node.childNodes){
if(n.nodeType === 1){
cnt ++;
cnt += getDivNumbers(n)
}
}
return cnt
}
const node = document.getElementById("app")
console.log(getDivNumbers(node))
</script>
2. 三数之和
Leetcode原题!可惜我没刷过
看到题目的时候,我的脑海里闪现过,之前好像做过一个两数之和(easy)。
然后…就没有然后了。三数之和跟两数之和根本就不是一个东西…
我上来先说,这道题O(n3)的方法是可以的(废话)…
然后我想到了先排序,面试官提醒我可以用双指针,可惜太紧张了只听懂了一半,最后磕磕绊绊也没A出来… 牛客网的代码区风格和leetcode也不太一样,上来就飘红…很搞心态hhh
耻辱地贴上官方解答…
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
int n = nums.size();
sort(nums.begin(), nums.end());
vector<vector<int>> ans;
// 枚举 a
for (int first = 0; first < n; ++first) {
// 需要和上一次枚举的数不相同
if (first > 0 && nums[first] == nums[first - 1]) {
continue;
}
// c 对应的指针初始指向数组的最右端
int third = n - 1;
int target = -nums[first];
// 枚举 b
for (int second = first + 1; second < n; ++second) {
// 需要和上一次枚举的数不相同
if (second > first + 1 && nums[second] == nums[second - 1]) {
continue;
}
// 需要保证 b 的指针在 c 的指针的左侧
while (second < third && nums[second] + nums[third] > target) {
--third;
}
// 如果指针重合,随着 b 后续的增加
// 就不会有满足 a+b+c=0 并且 b<c 的 c 了,可以退出循环
if (second == third) {
break;
}
if (nums[second] + nums[third] == target) {
ans.push_back({ nums[first], nums[second], nums[third]});
}
}
}
return ans;
}
};
其实这是道挺经典的面试题,之前做了很多的每日一题,但竟然连这么经典的题目都没做过,刷题的选择上是有问题的… 以后还是不刷每日一题了,先把经典的面试题搞清楚…
3. promise和异步
这道题考察的是promise的执行逻辑和同步/异步。
- 首先promise构造函数执行,1会打印出来,然后promise变成resolved状态,接着输出2。后面然后reject()其实是没用的,因为promise状态确定后就不会改变;
- 然后setTimeout执行,但里面的回调是异步任务,所以5不会立马打印;
- 然后promise的then()和catch()函数被绑定上,但此时里面的回调不会执行;
- 然后最后的同步过程4被打印出来。
- 然后promise的回调函数(微任务)先于setTimeout(宏任务)被执行。
最后答案应该是:
1 2 4 3 6 5
4. 并发和并行/进程和线程
5. 说一说RSA加密… 这个我真的不会
6. defineProperty和proxy的区别。
只用过defineProperty。。。可以参考下这篇博客
7. new Function 的原理。
我回答的也不是很完善,可以参考下这篇博文
8. 浏览器的event loop 和 node环境下的event loop。
浏览器的event loop我知道,node的…支支吾吾就说了和"浏览器差不多"… 可以参考下这篇博客 宏任务和微任务。
9. TCP和UDP的区别。
感觉这是我唯一回答的还算可以的题…
10. 左边固定,右边自适应的布局。
简化版的圣杯 / 双飞翼。
** 11.移动端做过吗?rem适配原理是什么?**
第二面还是很看计算机基础和对JS的理解的,凉了也是理所应当。 作为一个已经研二的非科班,现在心情就像一个文科生报了理科高考,眼看着高考前夕… 唉,加油吧。
与其苟延残喘,不如纵情燃烧吧,有一天总会发芽…