前言
第一次面大厂,面完之后,仿佛开启对大厂的憧憬之门,以前或许还会斟酌下大厂会不会卡学历,面完之后直接海投上压力~
书接下回:百度一和二面分享(今天刚刚面完二面,还来不及写......)
一、八股题(感兴趣可以自行查阅或者跳转)
1. token + jwt
2. 如何验证token有效
3. 闭包及其适用场景
4. 有哪些水平垂直居中方法(不知道具体宽高来实现)
看这 -> 当面试官问你使内容水平垂直居中的方式有哪些时,你可以回答出几种?
5. js类型判断
6. for in 和 for of
看这 -> 那些 for in 和 for of 以及遍历迭代踩过的坑
7. 事件循环
8. prommise 及其几个方法
看这 -> 一次性复习Promise上所有方法的实现原理
二、输出题
1. 闭包
js
function func() {
let i = 0
return () => {
i++
console.log(i)
}
}
const func1 = func()
const func2 = func()
func1()
func2()
func1()
func2()
func1 === func2
注意这里是创建俩个实例对象 func1 和 fuunc2,所以这俩个实例对象都会拥有自己单独的闭包,所以执行 func1() 、func2() 、func1() 、func2() 后各自的实例对象调用各自的闭包,所以打印结果为 1 1 2 2 ,那么最后执行的结果都为2,即 func1 和 fuunc2 的值是一样的,但都是对象有各自的引用地址,且 ===
除了判断值相对外还会判断地址是否相等,所以这里打印 false
2. 作用域和声明提升
js
var a = 2;
function AA() {
console.log(a);
var a = 1;
}
AA();
这也是一道很经典的题目了,主要考察 var
、let
、const
特性,var
变量的声明会被提升到当前作用域的顶部,虽然 var a = 1 在打印后面,但是var a
变量已经声明到函数作用域的顶部,已经声明但还没有赋值,所以打印的是 undefined
,如果 var a = 1 在打印前面则打印 2 ,那么这时候面试官就开始作妖了~
js
// 这时候又打印什么呢?
var a = 2;
function AA() {
console.log(a);
let a = 1;
}
AA();
var
变量具有声明提升,但是 let
并没有且具有块级作用域,所以此处打印会报错!
3. 事件循环
js
setTimeout(function() {
console.log(1)
}, 0);
new Promise(function(resolve) {
console.log(2);
for(var i = 0; i < 10000; i++) {
if (i === 9999) {
resolve();
}
}
console.log(3);
}).then(function() {
console.log(4);
});
console.log(5);
记住事件循环顺序:同步 -> 异步(微任务 -> 宏任务),所以结果就是 2 3 5 4 1
4. 原型继承
js
Function.prototype.a = () => alert(1)
Object.prototype.b = () => alert(2);
function A() {}
const a = new A();
a.a();
a.b();
a.b() 的结果是显示 2 这想必大家都很清楚,因为是直接在对象原型上挂方法,通过原型链逐层往上可以找到,但问题出现在 a.a() 要怎么判断呢?我们可以这么想,我们都知道 Function
上挂方法 a , 实例对象 function A() 是可以访问到的,即 A.a() 可以继承并显示 1 ,那么 function A() 的实例对象 a 可以访问吗?
我们都知道实例对象的隐式原型等于构造函数的显示原型,即 Function.prototype = obj.__proro__
按照这个依据我们就可以这么想:
Function.prototype = A.__proro__
,所以 function A() 可以继承到 a 方法A.prototype = a.__proro__
,这里 A 作为构造函数,但是 A 的 a 方法在隐式原型上__proro__
- 所以实例对象 a 并不能继承到 A 上的隐式原型方法,如果 A.prototype.a = () => alert(1) 则可以
所以这题 a.a() 会报错, a.b() 会显示 2
三、手写题
手写一个Promise.half
js
//Proimse.half = function(arr) {}
//有一半成功,就立即返回[res, res],低于一半,就返回null
function myHalf(promise){
return new Promise((resolve, reject)=>{
const res = [] // 储存每个promise状态
let n = 0 // 已经走完的次数
let ful = 0 // 状态成功的数量
let re = 0 // 状态失败的数量
for(let i = 0;i<promise.length;i++){
promise[i].then((res)=>{
res.push(promise[i])
ful = ful + 1 // 记录成功状态的个数
if(ful >= (promise.length)/2){
resolve(res) // 超过一一半直接返回存入成功状态的数组结果
}
}).catch((err)=>{
res.push(promise[i])
re = re + 1 // 记录失败状态的个数
if(re >= (promise.length)/2){
reject(null) // 超过一一半直接返回 null
}
}).finally(()=>{
n = n + 1
})
}
})
}
其实这道手写题就是 promise.allSettled
的变种题,promise.allSettled
用于处理一组 Promise 对象,并在所有 Promise 对象都已经 settled(fulfilled 或 rejected)之后返回一个新的 Promise,该 Promise 包含一个数组,数组中的每个元素都代表了原始 Promise 是否已经 fulfilled 或 rejected 以及对应的值或原因。
所以我们只需要把每个promise的状态给用一个数组记录下来,当某个状态超过一半时则返回对应结果,当时我写这题时也是一脸懵,因为也看了其他promise方法的手写但这个也确实浪费了很长时间,现在处于半挂不挂的状态也跟这手写题和后面算法有很大关系(确实也是因为这个写的太丐版了)。
如果对promise的其他方法手写感兴趣可以看看我朋友的这篇文章: 一次性复习Promise上所有方法的实现原理
四、算法题
输出二叉树的右试图
这道题目是力扣中等难度原题:199.二叉树的右试图
- 输入: [1,2,3,null,5,null,4]
- 输出: [1,3,4]
题目具体意思是从二叉树的右边看,从上往下输出看的第一个值,具体解题思路是按照中右左的前序遍历 或者层序遍历 来查找,可以使用深度优先递归遍历 或者广度优先层序遍历来进行查找。
方法一:DFS深度优先搜索
js
var rightSideView = function(root) {
if(!root) return []
let arr = []
dfs(root, 0, arr)
return arr
};
function dfs (root, step, res) {
if(root){
if(res.length === step){
res.push(root.val) // 当数组长度等于当前 深度 时, 把当前的值加入数组
}
dfs(root.right, step + 1, res) // 先从右边开始, 当右边没了, 再轮到左边
dfs(root.left, step + 1, res)
}
}
方法二:BFS广度优先搜索
js
var rightSideView = function(root) {
if(!root) return []
let queue = [root] // 队列 把树顶加入队列
let arr = [] // 用来存储每层最后个元素值
while(queue.length > 0){
let len = queue.length
while (len) {
let node = queue.shift() // 取出队列第一个元素
if(len === 1) arr.push(node.val) // 当是 当前一层的最后一个元素时,把值加入arr
if(node.left) queue.push(node.left) // 继续往队列添加元素
if(node.right) queue.push(node.right)
len--
}
}
return arr
};
这题说来惭愧,本人平常都是用python来写算法题目,因为字节的是在飞书的编译平台进行编写,也没有样例可以运行,本人这题只写对了7-8成,还有一些缩进命名等问题我没有仔细查看,就已经被面试官说停手了,因为面试的时间太长了。
我:😭😭
面试官:后面回去等通知😐😐
等了半个月的我既没有收到感谢信也没收到二面通知,大概率进鱼塘了吧......
🐭🐭下次继续努力~
顺带一提的是,算法题后来在力扣平台又成功跑了一遍,思路是对的,但有些地方需要改进。