2022 前端一场面试及答案整理
金三马上就要开始了,俗话说得好,知己知彼百战百胜,多准备总是没有错的。以面试的形式和大家一起学习、一起回顾我们的职场生涯。今天简单总结一下我个人去面试,包括我在面试别人时的经验。加油加加油!!!
目录
开头热场问题
1. 说一下工作中解决过比较困难的问题 或 说一下自己项目中比较有亮点的地方
2. 你了解浏览器的事件循环吗?
? ? 2.1 为什么 js 在浏览器中有事件循环的机制?
? ? 2.2 你了解事件循环当中的两种任务吗?
? ? 2.3 为什么要引入微任务的概念,只有宏任务可以吗?
? ? 2.4 你了解 Node.js 的事件循环吗?Node中的事件循环和浏览器的事件循环有什么区别?
? ? ? ? 2.5 这个时候理论问了这么多了,开始实践1
? ? ? ? 2.6 实践2
? ? ?2.7 实践3?
3. 事件的捕获和冒泡机制你了解多少?
? ? 3.1 基本概念
? ? 3.2? window.addEventListener 监听的是什么阶段的事件?? ? ? ? ?
? ? 3.3 平常有哪些场景用到了这些机制??
4.? 你工作中用过防抖和节流吗?
? ? 4.1 基本概念
? ? 4.2 分别适合用在什么场景?
? ? 4.3? 手写节流函数
5. 你了解 Promise 吗?平时用的多吗?
? ? 5.1 Promise.all( ) 你知道有什么特性吗?
? ? 5.2?如果其中一个 Promise 报错了怎么办?
? ? 5.3?如果有一个 Promise 报错了,那么其他的 Promise 还会执行吗?
? ? 5.4 手写一个?Promise.all(? )
? ? 5.5 Promise 在初始化的时候已经执行了,那么利用这个特性我们可以做点什么(扩展性问题)?
?6. 字节经典算法题---- 接雨水
开头热场问题
1. 说一下工作中解决过比较困难的问题 或 说一下自己项目中比较有亮点的地方
考察目的:面试官主要看一下我们解决问题的能力
解答:这个问题 主要是靠大家的工作积累,平时工作过程中可以养成一个良好的习惯,无论做什么需求的时候,都花点时间去记录一下,这样积累无论是一年,还是两年,或者五年都会积累很多也无需求,然后自己梳理一下,在面试的时候反馈给面试官,让面试官虎躯一震,offer马上到手~~~
2. 你了解浏览器的事件循环吗?
考察目的:以此问题作为一个突破口,深度挖掘你对整个概念的了解
2.1 为什么 js 在浏览器中有事件循环的机制?
解答:
① JS 是单线程的
② event loop
2.2 你了解事件循环当中的两种任务吗?
解答:
① 宏任务:整体代码块、setTimeOut、setInterval、I/O操作
② 微任务:new Promise().then()、mutationObserver(前端的回溯)
2.3 为什么要引入微任务的概念,只有宏任务可以吗?
解答:
宏任务:先进先出的原则
在 JS 的执行过程中 或者说在页面的渲染过程中,宏任务是按照先进先出的原则执行,我们并不能准确的控制 这些任务被推进任务队列里,但是我们这个时候如果出来一个非常高优先级的任务,这个时候该怎么办?如果我们只有宏任务,再往任务队列里面推一个,秉承着先进先出的原则,那么它肯定是最后一个执行的,所以要引入微任务;
了解到宏任务与微任务过后,我们来学习宏任务与微任务的执行顺序。
- 代码开始执行,创建一个全局调用栈,
script
作为宏任务执行 - 执行过程过同步任务立即执行,异步任务根据异步任务类型分别注册到微任务队列和宏任务队列
- 同步任务执行完毕,查看任务队列
- 若存在微任务,将微任务队列全部执行(包括执行微任务过程中产生的新微任务)
- 若无微任务,查看宏任务队列,执行第一个宏任务,宏任务执行完毕,查看微任务队列,重复上述操作,直至宏任务队列为空
2.4 你了解 Node.js 的事件循环吗?Node中的事件循环和浏览器的事件循环有什么区别?
解答:
Node宏任务的执行顺序:
① timers定时器:执行已经安排过的,setTimeout 和 setInterval 的回调函数;
②pending callback 待定回调:执行延迟到下一个循环迭代的I/O回调;
③idle,prepare:仅系统内部使用;
④poll:检索新的I/O事件,执行与I/O相关的回调
⑤check:执行setImmediate() 回调函数
⑥close callback:socket.on(‘close’, ( )=>{ })
微任务和宏任务在node的执行顺序:
首先大家要明白,Node中微任务和宏任务的执行顺序是和 node 的版本有关系的
Node V10 之前:
① 执行完上述一个阶段中的所有任务
② 执行 nextTick 队列里面的内容
③ 执行完微任务队列的内容
Node V10 之后:
和浏览器的行为统一了
2.5 这个时候理论问了这么多了,开始实践1
async function async1() {console.log("async1 start");await async2();console.log("async1 end");
}
async function async2() {console.log("async2");
}
console.log("script start");
setTimeout(() => {console.log("setTimeout");
}, 0);
async1();
new Promise((resolve) => {console.log("promise1");resolve();
}).then(() => {console.log("promise2");
});
console.log("script end");// 1. script start
// 2. async1 start
// 3. async2
// 4. promise1
// 5. script end
// 6. async1 end
// 7. promise2
// 8. setTimeout
2.6 实践2
这个就比较有难度了,如果真的不会,千万不要张嘴就来一句:“我不会”,这个时候我作为面试官的时候心里就在想:“我屮艸芔茻,这好尴尬”!娱乐一下开个玩笑,这个时候要尝试着说出自己的思路,即使是错的,你也要让面试官看到你的 进取、钻研精神!
console.log("start");
setTimeout(() => {console.log("children2");Promise.resolve().then(() => {console.log("children3");});
}, 0);new Promise((resolve, reject) => {console.log("children4");setTimeout(() => {console.log("children5");resolve("children6"); // 此处大坑}, 0);
}).then((res) => {console.log("children7");setTimeout(() => {console.log(res);}, 0);
});// 1. start
// 2. children4
/** 第一轮宏任务执行结束,尝试清空微任务队列,发现没有微任务,尝试执行下一轮宏任务 */
// 3. children2
/** 第二轮宏任务执行结束,尝试清空微任务队列, */
// 4. children3
// 5. children5
/** 第三轮宏任务执行结束,尝试清空微任务队列, */
// 6. children7
// 7. children6
2.7 实践3
到这一步,大家心里是不是在想:“面试官怎么抓着 事件循环不放了”,最后一道题
const p = () => {return new Promise((resolve, reject) => {const p1 = new Promise((resolve, reject) => {setTimeout(() => {resolve(1); // 这里 不会再输出了,因为 resolve(2) 已经把结果输出}, 0);resolve(2);});p1.then((res) => {console.log(res);});console.log(3);resolve(4);});
};
p().then((res) => {console.log(res);
});
console.log("end");// 1. 3
// 2. end
// 3. 2
// 4. 4
到此为止,事件循环结束!
3. 事件的捕获和冒泡机制你了解多少?
3.1 基本概念
以HTML为例:↓
捕获:从window → parent → child → son 到目标元素以后,转为冒泡
冒泡:目标元素 son→ child→ parent→window
3.2 window.addEventListener 监听的是什么阶段的事件?
// 冒泡阶段
window.addEventListener("click", () => {}); // 第三个参数默认为 false,为false 时,监听的为冒泡阶段// 捕获阶段
window.addEventListener("click", () => {}, true);
3.3 平常有哪些场景用到了这些机制?
3.3.1. 事件委托
<ul id="ul"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li></ul>const ul = document.querySelector("ul");ul.addEventListener("click", (e) => {const target = e.target;if (target.tagName.toLowerCase() === "li") {const liList = document.querySelectorAll("li");// 这里之所以会这么写,是因为 liList 并非是一个真正的 Array// 此时返回的是一个 nodeList,如果想使用 数组的 方法,需要改变thisconst index = Array.prototype.indexOf.call(liList, target);console.log(`内容:${target.innerHTML},索引:${index}`);}});
3.3.2 场景设计题
一个历史页面,上面有若干按钮的点击逻辑,每个按钮都有自己的 click 事件
新需求来了:给每一个访问的用户添加了一个属性,如果 banned = true,此用户点击页面上的任何按钮或元素,都不可响应原来的函数。而是直接 alert 提示,你被封禁了。
实现:采用 事件捕获 机制完成(当然实现的思路有三种,甚至更多,这里只说事件捕获)
/*** 场景设计题
????一个历史页面,上面有若干按钮的点击逻辑,每个按钮都有自己的 click 事件
? ? ?新需求来了:给每一个访问的用户添加了一个属性,如果 banned = true,此用户点击页面上的任何按钮或元素,都不可响应原来的函数。而是直接 alert 提示,你被封禁了。
*/window.addEventListener("click",(e) => {if (banned) {e.stopPropagation();}},true
);
4. 你工作中用过防抖和节流吗?
4.1 基本概念
防抖:持续触发事件的时候,一定时间段内,没有再触发事件,时间处理函数才会执行一次
节流:持续触发事件的时候,保证一段时间内只调用一次事件处理函数(固定时间)
4.2 分别适合用在什么场景?
防抖:input输入(巨量引擎)
节流:resize(屏幕大小改变)、scroll(滚动时) —> 一定要执行的,给一个固定间隔
4.3 手写节流函数
时间戳写法,第一次立即执行
// 时间戳写法,第一次立即执行
const throttle = (fn, interval) => {let last = 0;return () => {let now = Date.now();if (now - last >= interval) {fn.apply(this, arguments);}};
};
const handle = () => {console.log(Math.random());
};
const throttleHandle = throttle(handle, 3000);
throttleHandle();
throttleHandle();
定时器写法,第一次也需要延时 具体 时间以后再执行
// 定时器写法,第一次也会延时 具体的时间执行
const throttle = (fn, interval) => {let timer = null;return function () {let context = this;let args = arguments;if (!timer) {timer = setTimeout(() => {fn.apply(context, args);timer = null;}, interval);}};
};
const handle = () => {console.log(Math.random());
};
const throttleHandle = throttle(handle, 1000);
throttleHandle();
throttleHandle();
精确的实现一个节流函数,无论是第一次之后还是最后一次(避免最后一次执行还会再等具体时间之后再执行)
// 精确的实现一个节流函数,无论是第一次之后还是最后一次(避免最后一次执行还会再等具体时间之后再执行)
const throttle = (fn, delay) => {let timer = null;let startTime = Date.now();return function () {let curTime = null;let remainning = delay - (curTime - startTime);let context = this;let args = arguments;clearTimeout(timer);if (remainning <= 0) {fn.apply(context, args);startTime = Date.now();} else {timer = setTimeout(fn, remainning);}};
};
5. 你了解 Promise 吗?平时用的多吗?
5.1 Promise.all( ) 你知道有什么特性吗?
解答:Promise.all( ) 会接受一个 Promise 数组,数组里面可以是 Promise 也可以是一个常量或者其他;执行情况为:Promise 里面的所有 Promise 执行完成以后才会返回结果;
5.2如果其中一个 Promise 报错了怎么办?
解答:如果有一个报错了,那么整个 Promise.all( ),就会返回一个 catch
5.3如果有一个 Promise 报错了,那么其他的 Promise 还会执行吗?
解答:会的,因为 Promise 是在创建之初(实例化) 的时候已经执行了
5.4 手写一个Promise.all( )
面试官:“给你 三个 如下的 Promise ,调用你的Promise.all( )以后,看是否会在三秒以内返回对应的结果”
// 测试
const pro1 = new Promise((resolve, reject) => {setTimeout(() => {resolve("1");}, 1000);
});
const pro2 = new Promise((resolve, reject) => {setTimeout(() => {resolve("3");}, 2000);
});
const pro3 = new Promise((resolve, reject) => {setTimeout(() => {resolve("3");}, 3000);
});// 测试题
const PromiseAll = (promiseArray) => {};
如何实现?
考点1:Promise.all( ) 里面的参数有可能不是一个 Promise,如何处理?
考点2:Promise.all( ) 返回值的顺序,是你传入的 Promise 顺序,如何处理?
// 测试题
const PromiseAll = (promiseArray) => {return new Promise((resolve, reject) => {if (!Array.isArray(promiseArray)) {return reject(new Error("Type can only be array"));}const result = []; // promise 执行的结果集const promiseNums = promiseArray.length; // 当前循环次数let counter = 0; // 记录当前 promise 执行顺序,需要按照 传入的 promise 顺序返回for (let i = 0; i < promiseNums; i++) {Promise.resolve(promiseArray[i]).then((value) => {counter++;result.push(value);if (counter === promiseNums) {resolve(result);}}).catch((e) => reject(e));}});
};console.log(PromiseAll([pro1, pro2, pro3]).then((res) => {console.log(res);}).catch((e) => {console.log(e);})
);
5.5 Promise 在初始化的时候已经执行了,那么利用这个特性我们可以做点什么(扩展性问题)?
解答:可以利用 promise 的这个特性做缓存;
利用 装饰器 + Map结构,实现一个 Promise 的缓存;
const cacheMap = new Map();
const enableCache = (target, name, descriptor) => {const val = descriptor.value;descriptor.value = async (...args) => {const cacheKey = name + JSON.stringify(args);if (!cacheMap.get(cacheKey)) {const cacheValue = Promise.resolve(val.apply(this, args)).catch((_) => {cacheMap.set(cacheKey, null);});cacheMap.set(cacheKey, cacheValue);}return cacheMap.get(cacheKey);};return descriptor;
};
class PromiseClass {@enableCachestatic async getInfo() {}
}PromiseClass.getInfo(); // 第一次发送请求
PromiseClass.getInfo(); // 第二次以后就是缓存
PromiseClass.getInfo();
PromiseClass.getInfo();
6. 字节经典算法题---- 接雨水
题干:
给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
示例1:
输入 height = [0,1,0,2,1,0,1,3,2,1,2,1]
输出:6
解释:上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 单位的雨水(如上图,蓝色部分表示雨水)
示例2:
输入 height = [4,2,0,3,2,5]
输出:9
2022 前端一场面试及答案整理相关推荐
- 前端开发面试题及答案整理
前端开发面试题及答案整理 文章目录 一些开放性题目 position的值, relative和absolute分别是相对于谁进行定位的? 如何解决跨域问题 XML和JSON的区别? 谈谈你对webpa ...
- 2022前端秋招面试题总结 阿里 腾讯 字节 百度 网易 京东 小红书 快手面试记录
2022前端秋招面试题总结 阿里 腾讯 字节 百度 网易 京东 小红书 快手面试记录 等了百度三个月,终于发offer了,白菜价,92大佬们拒的薪资,我知足了. 排序挂了狠多,快手,蚂蚁,- 很绝望 ...
- Java 最常见的 10000+ 面试题及答案整理:持续更新
Java面试题以及答案整理[最新版]Java高级面试题大全(2021版),发现网上很多Java面试题都没有答案,所以花了很长时间搜集,本套Java面试题大全,汇总了大量经典的Java程序员面试题以及答 ...
- 【2022前端面试】CSS手写面试题汇总(加紧收藏)
[2022前端面试]CSS手写面试题汇总(加紧收藏) 更新时间:2022年3月3日 把答案一起写上,但是希望大家在看之前思考一下,如果有好的建议,跪求改正! 本文致力于建设前端面试题库,欢迎兄弟们投稿 ...
- 秋招如何抱佛脚?2022最新大厂Java面试真题合集(附权威答案)
2022秋招眼看着就要来了,但是离谱的是,很多同学最近才想起来还有秋招这回事,所以纷纷临时抱佛脚,问我有没有什么快速磨枪的方法, 我的回答是:有! 说起来,临阵磨枪没有比背八股文更靠谱的了,很多人对这 ...
- 金三银四如何抱佛脚?2022 最新大厂 Java 面试真题合集(附权威答案)
这些面试资料都是我通过各种渠道收集到的大厂面试真题,并附有最新的权威答案,绝不是网络上那些已经是几年前甚至十几年前的面试题所能媲美的,除面试题外还有我整理的一些经典 Java 学习电子书也都可以无偿分 ...
- 【2022前端面试】HTML面试题汇总(加紧收藏)
[2022前端面试]HTML面试题汇总(加紧收藏) 更新时间:2022年2月23日. 本文致力于建设前端面试题库,欢迎兄弟们投稿哈! 引言 没办法,逃不过.看了很多面经和总结,时过一年,再次更新本文, ...
- 【2022前端面试】CSS面试题汇总(加紧收藏)
[2022前端面试]CSS面试题汇总(加紧收藏) 更新时间:2022年3月2日. 本文致力于建设前端面试题库,欢迎兄弟们投稿哈! 大纲 CSS整体的在上次的篇幅上有了较大的变化,画一个思维导图及时更新 ...
- 前端面试知识点目录整理
前端面试知识点目录整理 基本功考察 1.关于Html 1.html语义化标签的理解.结构化的理解:能否写出简洁的html结构:SEO优化. 2.h5中新增的属性,如自定义属性data.类名classN ...
最新文章
- HTML-参考手册: URL 编码
- json对象数组按对象属性排序
- scikit-learn决策树算法类库使用小结及可视化方法
- python第一条入门程序_Python语言函数代码的执行流程
- Bash脚本报错:“/bin/bash^M: bad interpreter: No such file or directory”
- JavaScript高级之ECMASript 7、8 、9 、10 新特性
- 浅析laravel门面原理与实现
- Flyway 数据库脚本版本控制工具
- python新手如何编写一个猜数字小游戏
- Verilog初级教程(13)Verilog中的块语句
- TextToSpeech文本转语音,从开始说话到结束的监听
- 5.2 BP误差逆传播
- 积性函数是什么 超级明白的敷衍介绍
- 2021ICPC网络赛第一场【A Busiest Computing Nodes】【D Edge of Taixuan】
- 我被List中remove()方法的陷阱,坑惨了!
- /MD 与 /MT、/MTD与/MDD的区别
- C#中定义装箱和拆箱详解
- 高中计算机专业教师 教学计划,信息技术教师教学计划
- DisplayPort接口全总结
- 一文实现:在python中调用matlab程序,保姆级安装windows环境下的matlab.engine教程
热门文章
- 编译参数-Wl和rpath的理解
- 新装修的房子怎样知道含不含有甲醛?斐讯悟空M1告诉你
- python的self.boardx -= 5 什么意思_python小白求帮助
- 微信小游戏|unity搭建3D篮球小游戏场景
- “隔代教育的成功之道”-新浪教育专家宋少卫做客西单图书大厦
- Asp.net MVC WebApi Response AOP_se7en3_新浪博客
- android spinner,自定义字体大小颜色背景位置
- Windows Server 2012 R2 官方原版镜像
- 从wolai转移到Notion
- oracle 的lag,oracle分析函数lag