此次字节的一面仍是比较简单的,和通常公司的一面差不太多,基本你们只要多复习复习JS的基础和ES6,其实都差很少可以答出来。接下来记下具体此次的面试和流程,但愿能对XDM有所帮助html
此次是在牛客网上的面试房间面试的,有的面试官会使用腾讯会议面试,有的面试官会使用电话面试,因此碰到在牛客网上面试的状况的话,能够尽可能多准备准备算法相关的一些东西,由于常常会有题目须要你手打代码,而后面试官询问思路前端
首先是面试官让你自我介绍,介绍完以后开始问CSS方面的知识,这部分问的少,居中对齐有哪几个方案,position居中对齐的方案解释下原理,这两个问题回答完就直接JS部分了。CSS部分复习比较普遍繁琐,尽可能仍是在平常使用中累积经验面试
这部分首先是事件循环题,是一个老生常谈的题目了,我没记下原题,这里贴一个相似的题目,当时出的是只有五个打印的题目,这个题目只要注意在微任务中Promise、settimeout的执行顺序,遇到await会当即执行表达式,而后把表达式后面的代码放到微任务队列里,让出执行栈让同步代码先执行就好了算法
async function async1() {
console.log('async1 start');
await async2();
console.log('async1 end');
}
async function async2() {
console.log('async2');
}
console.log('script start');
setTimeout(function() {
console.log('setTimeout');
}, 0)
async1();
new Promise(function(resolve) {
console.log('promise1');
resolve();
}).then(function() {
console.log('promise2');
});
console.log('script end');
/** * script start * async1 start * async2 * promise1 * script end * async1 end * promise2 * setTimeout */
复制代码
紧接着的是手写的题目,要求手写call函数和Promise函数(这个其实没有让我去写,只是说了下实现的思路,后面的Redux简单实现也是只要求说了思路),注意如下写的东西并非当时写的代码redux
Function.prototype.myCall = function(context) {
context = context || window;
context.func = this;
const params = [...arguments].slice(1);
const result = context.func(...params);
return result;
}
function MyPromise(executor) {
var self = this;
this.status = 'pending';
this.value = undefined;
this.reason = undefined;
this.onResolvedCallbacks = [];
this.onRejectedCallbacks = [];
function resolve(value) {
if (self.status === 'pending') {
self.status = 'resolve';
self.value = value;
self.onResolvedCallbacks.map((fn) => {
fn();
})
}
}
function reject(reason) {
if (self.status === 'pending') {
self.status = 'rejected';
self.reason = reason;
self.onRejectedCallbacks.map((fn) => {
fn();
})
}
}
try {
executor(resolve, reject);
} catch (err) {
reject(err)
}
}
MyPromise.prototype.then = function (infulfilled, inrejected) {
var self = this;
if (this.status === 'resolve') {
infulfilled(this.value)
}
if (this.status === 'rejected') {
inrejected(this.reason)
}
if (this.status === 'pending') {
this.onResolvedCallbacks.push(function () {
infulfilled(self.value)
});
this.onRejectedCallbacks.push(function () {
inrejected(self.reason)
});
}
};
复制代码
Promise部分完以后,面试官问知道拍平吗?拍平能说出有哪几种方案,我说了简单的好比toString+split的方案,递归的方案,还有Array.prototype.flat能够作到这一点,而后这里面试官说但愿我能手写一个flat函数,要求传数组进去可以返回拍平后的数组数组
// 错误示范
// 这个是当时我写的,num并未起做用,而后面试官就让我回答后续的问题了
function flat(arr, num){
let res = [];
if(num > 0){
arr.map(item => {
if(Array.isArray(item)){
res = [...res, flat(item, num - 1)]
} else {
res.push(item)
}
})
}else {
res = arr
}
return res;
}
console.log(flat([1,2,3,[1,2, [3,4], 5], 6], 1))
复制代码
紧接着面试官询问了我了解哪些状态码,我说完以后他取出304状态码问这个状态码是何时会看到的,这个地方其实就是问你对缓存的了解,问完后就进入了React的部分promise
首先简单问了React中diff的原理,key的做用,而后问了生命周期都有哪些,让我按本身的记忆说一遍,由于后面我用的是hooks,因此生命周期我只说了六七个,而后问了我,this.setState是同步的仍是异步的,这里是一个小陷阱,由于this.setState在一些时候是同步的,一些时候是异步的,这个你们能够本身去了解一下在监听事件、绑定事件、生命周期中的this.setState表现。而后问了我this.setState为何不能用在render里,这里也是一点小陷阱,由于事实上不是不能用,而是尽可能谨慎,this.setState会触发从新render,你能够为其设置限制条件等控制他的从新渲染。为何hooks不能用在if-else里面,这个其实我没有太清楚,因此说了很差意思不太清楚。值得一提的是,大厂的面试官不会由于你不懂而改变对你的态度,始终都会是比较温和的面试态度,因此这点对于面试者仍是比较舒服的,不会出现面完心态大崩的状况啦。而后问了我懂不懂redux的简单的实现,正好这个我有写过一个简单的实现,而后就边地打了几行,边讲具体的代码和设计思路,具体代码在下方缓存
export default function createStore(reducer){
let state = null;
const listeners = [];
const getState = () => state
const dispatch = (action) => {
state = reducer(state, action)
listeners.forEach(listener => listener())
}
const subscribe = (listener) => listeners.push(listener)
// 这里初始化dispatch的缘由是在这以前,state是为null的
dispatch({});
return {
dispatch,
subscribe,
getState,
}
}
复制代码
最后面试官还问了我graphql的意义是什么,这个是由于个人简历上是有说用过graphql的,因此问了用这个的缘由,这里我答得是和Restful的一些差异,这个的话你们能够没用过的话就能够不用复习,不用担忧面试官会问出除你简历所写以外的技术(昂除非是很基础的好比CSS、html),最后是让我问问题,我询问了该前端团队所选用的技术栈是怎样的,也是gql + apollo那一套加中间层,具体的没有详细问,但愿个人面经可以对你们的面试有所帮助markdown