前言
面试日期为 5月20日 19 : 00
又到了我跟滴滴某金融部门battle的时间了, 这次挑了如此特殊的日期来面试,是有特殊道理滴。
PS :为什么520这天,我原来定的521,后来调日期了,我没妹子你也别想带妹子出去玩!这回面的资深前端岗位,但愿面试官轻点蹂躏我😘😘😘😘。
自我介绍
首先上来面试官先说了一下他的情况,这另我刮目相看,然后就是我的show time了,
介绍个人信息,亮点以及项目经历之后,面试就算正式开始了。
PS :这里通过自己的话术将面试官的注意力吸引到项目优化方向,经过5分钟的自我介绍,面试官也对我刮目相看,没想到我能逼逼这么多。
简历相关
问 :你印象最深的项目是哪个?难点是什么?是怎么解决的?
PS :第一轮的过招,让我感觉面试官不简单,我要谨慎,所以没怎么吹,真的,没怎么吹。
Git
问 : git rebase
git rebase 都是用于分支合并
git rebase 会先找到两个分支的第一个共同的 commit 祖先记录,然后将提取当前分支这之后的所有 commit 记录,然后将这个 commit 记录添加到目标分支的最新提交后面。经过这个合并后,两个分支合并后的 commit 记录就变为了线性的记录了。
PS :上来一道送分题,嗯~ 不愧是资深前端岗,这波是试探,嗯,没错,一定是试探。
输出题
问 : 原型继承
function F() {}
Object.prototype.a = function() {
console.log('a')
}
Function.prototype.b = function() {
console.log('b')
}
const f = new F()
f.a()
f.b()
// 我的答案
undefined
b
后经过面试官引导,得出一下答案
a
undefined
//正确答案
a
Uncaught TypeError: f.b is not a function
解析:
f并不是Function的实例,因为它本来就不是构造函数,调用的是Function原型链上的相关属性和方法,只能访问到Object原型链。所以f.a()输出a,而f.b()就报错了。F是个构造函数,而F是构造函数Function的一个实例。因为F instanceof Object === true,F instanceof Function === true,由此可以得出结论:F是Object和Function两个的实例,即 F 能访问到a, 也能访问到b。所以F.a()输出 a ,F.b()输出b。
PS :这里我有点紧张,自己对原型链的理解还是不够透彻的,还是害怕继续追问这方面的问题,毕竟资前端岗,要谨慎,表害怕。
问 : 变量提升
var name = 'World';
(function() {
if (typeof name === 'undefined') {
var name = 'Jack'
console.log('Goodbay ' + name)
} else {
console.log('Hello ' + name)
}
})()
输出结果:Goodbye Jack
//在 JavaScript中, Function 和 var 都会被提升(变量提升),所以上面的代码就相当于
var name = 'World!';
(function () {
var name;
if (typeof name === 'undefined') {
name = 'Jack';
console.log('Goodbye ' + name);
} else {
console.log('Hello ' + name);
}
})();
PS :我都没解释,直接把第二段代码写出来了,让面试官自己看去。出这题是瞧不起我面试的嘛!!!!
问 : 异步&事件循环
async function async1() {
console.log('A')
await async2()
consolo.log('B')
}
async function async2() {
console.log('C')
}
console.log('D')
setTimeout(function() {
console.log('E')
})
async1()
new Promise(function(resolve) {
console.log('F')
}).then(function() {
console.log('G')
})
console.log('H')
//输出顺序如下
//D
//A
//C
//F
//H
//B
//undefined
//E
代码执行过程如下:
- 开头定义了
async1和async2两个函数,但是并未执行,执行 script 中的代码,所以打印出D; - 遇到定时器
setTimeout,它是一个宏任务,将其加入到宏任务队列; - 之后执行函数
async1,首先打印出A; - 遇到
await,执行async2,打印出C,并阻断后面代码的执行,将后面的代码加入到微任务队列; - 然后跳出
async1和async2,遇到Promise,打印出F; - 遇到
resolve,将其加入到微任务队列,然后执行后面的script代码,打印出H; - 之后就该执行微任务队列了,首先打印出
B,然后打印出undefined; - 执行完微任务队列,就开始执行宏任务队列中的定时器,打印出
E。
PS: 有惊无险,基本上这里答的自己也算满意,但是我心里却我慌了,明明答不上来最可怕,怎么感觉面试官要给我来个大的。
手写题
利用递归,遍历出二叉树深度
面试官先问了我有没有刷题,我说没有,然后就问了这个递归。
function tree(root) {
if (!root) return 0
let leftChildRoot = tree(root.leftChildRoot)
let rightChildRoot = tree(root.rightChildRoot)
return Math.max(leftChildRoot,rightChildRoot)
}
//代码并不完善,但是面试官听我说完大概流程就停止让我写了。
PS :此题必拿下,这么轻松的答出来,我也是对自己更加的满意,总而言之,看来这次面试胜负已分了,我稳了面试官你是不是没招了~~ 起飞了哈哈哈 这就是大的吗?
Componsition API
问 : 了解 Componsition API 吗?
在 Vue2 中,代码是 Options API 风格的,也就是通过填充 (option) data、methods、computed 等属性来完成一个 Vue 组件。这种风格使得 Vue 容易上手,同时也造成了几个问题:
- 由于
Options API不够灵活的开发方式,使得Vue开发缺乏优雅的方法来在组件间共用代码。 Vue组件过于依赖this上下文,TypeScript在Vue2中很不好用。
于是在 Vue3 中,舍弃了 Options API ,转而投向 Composition API。Composition API本质上是将 Options API 背后的机制暴露给用户直接使用,这样用户就拥有了更多的灵活性,也使得 Vue3 更适合于 TypeScript 结合。
问: Composition API 与React Hook很像,区别是什么?
我没用过 React Hook 但是我能说下 Composition API的一些特点
- 声明在
setup函数内,一次组件实例化只调用一次setup Compositon API的调用不需要顾虑调用顺序,也可以在循环、条件、嵌套函数中使用- 响应式系统自动实现了依赖收集,进而组件的部分的性能优化由Vue内部自己完成,使得组件性能得到提升。
PS :最开始面试官问的时候,我没听清,后来面试官说是 Vue的,我有了字节面试时因没听清而丢题的经验,让面试官把单词打出来了,有惊无险。
工程化的理解
问:你对前端工程化的理解
PS :这里就大概的理解了,反正手写和代码输出都出来了,问题也答的比较满意,这里我自己说的也比较放松。
反问
原话
麻烦您了,今天时间赶的还520,也没陪女朋友出去玩,真是抱歉了呢~
心里
哥哥 520你不陪女朋友,你女朋友不会生气吧?
哥哥 520你跟我视频,你女朋友不会打我吧?
我只会心疼哥哥~~
PS :真实情况肯定不能问的不能这么直白,但是我肯定暗示了。
总结
面试大概小一小时,越面越开心,越唠越开心,我虽然没掌握节奏,但是这面试官太上道了,接下来几轮,还这强度我不稳了嗷,全是送分题。
重铸滴滴荣光,我辈义不容辞!!!!
首战告捷!!!!
之前让滴滴面试官虐的 ,现在我找回了面子的同时找回了场子, 滴滴的面试官们是不会善罢甘休的,那么他们会在下一轮怎么应对呢?
偷摸说一句,我做梦笑醒了~