题目
-
浏览器点击300ms延时是因为什么?现在还有吗?怎么解决的?点击穿透
-
node的事件循环和浏览器事件循环区别?
-
event loop:检查是否有异步IO或者计时器,有的话进入事件循环
-
事件循环:六个阶段,一圈代表一次轮询,一个tick
-
timers:计时器(setTimeout、setInterval的回调函数),如果定时器到时间了,则会被调用执行。
-
pending callback: 执行某些系统操作的回调,例如TCP错误类型
-
idle prepare:系统内部使用
-
poll:轮询阶段,执行与IO相关的几乎任何回调(除去定时器和setImmediate的回调),例如文件读取,http请求
- 如果队列有回调函数,依次执行回调
- 如果没有,则阻塞在这里,直到有新的回调出现
- 如果这时候有poll出现新的回调,则立即执行。
- 如果check队列有setImmediate回调,则继续向下走check队列
- 如果有设定的timers,并且timers时间到达了,则event loop将绕回timers阶段执行timers
- 如果同时有setImmediate和setTimeout,则从按照顺序poll->check->timeout依次执行
-
check:setImmediate的回调,这个回调是直接进入到这个队列中的
-
close callbacks:一些关闭的回调函数 socket.on('close');
-
-
经过分析发现,基本会阻塞在poll阶段等待执行,但如果有setImmediate或者setTimeout则会停止等待,继续走流程。
- 微任务:
- 不属于事件循环,执行时机是每执行一个宏任务前都会检查微任务队列是否有微任务,有的话执行,这一点跟浏览器事件循环还比较一致,而且如果微任务执行过程中插入新的微任务,是会在本次微任务队列中直接执行,而不是等到下一次循环。
- nextTick优先级大于promise优先级
- 和浏览器事件循环
- 不同点
- 浏览器就是一个微任务队列和一个宏任务队列
- 宏任务队列没有分出来那么多过程,而是一个队列
- 相同点:
- 执行一个宏任务前将微任务的所有回调先执行完,nodejs不会等完整的tick而是一个宏任务之后就检查微任务。
- 不同点
- cookie和sesstionId区别,单点登录的区别,前端方面实现从A网站到B网站,如何不重新登录?前端做了哪些事情?
- cookie是存储在浏览器的,session是存储在服务器的
- 单点登录(SSO)看这一篇就够了
-
包含SSO
-
纯前端登录,cookie设置到localstorage,创建一个iframe,给另一个域名发送cookie,另一个html监听事件,收到事件后将cookie写入localStorage中。
-
- 面试官:什么是单点登录?如何实现?
缺点:
- csrf(跨站请求伪造)
- http referer
- 随机token
- 分布式session(增加一个单独的redies服务器)
JWT登录方案?
- 和cookie-session区别?cookie-session需要服务端存储。JWT是后端生成token,可以解析出来用户名。
- 缺点
-
token安全性,token窃取,能被解析出来,需要搭配https
-
性能
-
失效时间:redis失效时间存在token里
-
单点登录镇楼图
-
- ts中let、const实现的区别?
- 使用 let 声明的变量是只需要推导至这个值从属的类型即可。
- 而 const 声明的原始类型变量直接一步到位收窄到最精确的字面量类型,但对象类型变量仍可变(但同样会要求其属性值类型保持一致)。
let被推断为string
const直接被推断为精确的字面量类型,但是如下如果是一个const对象,因为属性还是可以被修改的,所以还是被推断为string类型
-
网络五层模型,http1 2 3区别
-
技术选型思路?
-
事件捕获和冒泡的区别?有没有哪些事件是不支持冒泡的?
- 分别是微软和网景提出的两种事件模型,捕获是从外到里,冒泡是从里到外,addEventListener第三个参数useCapture可以改变事件执行时机。默认是false,冒泡阶段执行,true的话改为捕获阶段执行。
- 阻止冒泡有2种方式:
- e.stopPropagation:阻止了事件往上冒泡,但不阻止事件本身(默认事件)
- 返回false:不仅阻止了事件往上冒泡,而且阻止了事件本身(默认事件)
- 不支持冒泡的事件
- scroll 事件
- scroll 事件不会冒泡,这个带来的影响就是,当我们去做事件委托的时候,其它的大部分事件可以在冒泡阶段的时候完成委托,而 scroll 事件必须在捕获阶段完成委托。
- scroll 事件无法取消( 没有冒泡的基本都没法取消 ),scroll 回调中的 preventDefault 和 stopPropagation 都是无效的。
- focus、blue事件:也是无法冒泡,无法取消的
- Media 事件:由媒介(比如视频、图像和音频)触发的事件,都不冒泡,简单举例:
- onpause 当媒介被用户或程序暂停时运行的脚本
- onplay 当媒介已就绪可以开始播放时运行的脚本
- onplaying 当媒介已开始播放时运行的脚本
- onsuspend 在媒介数据完全加载之前不论何种原因终止取回媒介数据时运行
- mouseleave 和 mouseenter:同样不会冒泡,当这种不冒泡的特性发生在鼠标事件的时候,显得额外的符合直觉
- scroll 事件
- 你真的理解 事件冒泡 和 事件捕获 吗?
- JavaScript 中那些不会冒泡的事件
-
0.1 + 0.2 不等于 0.3的原因?
后端问为什么前端数值精度会丢失? 解决方法:
- 转换为整数
- 使用BigInt
-
promise 坑人题,😄,终究还是答错了
new Promise((res,rej)=>{
console.log(1);
res(2);
console.log(3)
throw Error('abc')
}).catch((err)=>{
console.log('123')
}).then((res)=>{
console.log(res)
})
console.log('333')
可以看看上面题的输出顺序是什么?这里有个坑,resolve后再throw还会reject吗?就是被这个点给迷惑住了,我在想executor执行的时候是捕获了异常的,所以肯定是走到了reject中,但是,reject执行的时候是会判断当前promise的状态是不是pending,如果是pending才会变化,否则是不会执行的。
1 3 33 2
解答:
来吧,上规范,promisesaplus.com/, 还是说人话,直接中文吧。 【译】 Promises/A+ 规范
这道题还是答错了,之前以为promise掌握的不错了,一做题还是崩啊,所以这知识真是越学发现自己不会的越多。
- ts补充以下泛型
function a(o,key) {
return o[key]
}
- vue中v-if v-show区别
- vue中computed与watched区别
编程题
- 给一个多维数组,先展开成一维数组,再去重,再排序,如果自己写出排序加分
function flatten(arr, depth = Infinity) {
return arr.reduce((acc, cur) => {
return acc.concat(Array.isArray(cur) && depth > 0 ? flatten(cur, depth - 1) : [cur])
}, []);
}
// 排序写了快排
function quickSort(arr) {
if (!arr.length) {
return [];
}
const len = arr.length;
// 随机选取一个枢纽元,放到最后一个位置
const pivotIndex = Math.round(Math.random() * (len - 1));
const pivot = arr[pivotIndex];
swap(arr, pivotIndex, len - 1);
const left = [];
const right = [];
for (let i = 0; i < len - 1; i++) {
if (arr[i] < pivot) {
left.push(arr[i]);
} else {
right.push(arr[i]);
}
}
return [...quickSort(left), pivot, ...quickSort(right)]
}
- 写一个深克隆,考虑函数和null
function deepCopy(obj) {
const map = new Map();
const clone = (obj) => {
if (!obj || typeof obj !== 'object') {
return;
}
if (map.has(obj)) {
return map.get(obj);
}
let result = Array.isArray(obj) ? [] : {};
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
const val = obj[key];
if (typeof val === 'object') {
result[key] = deepCopy(val);
} else {
result[key] = obj[key];
}
}
}
map.set(obj, result);
return result;
}
return clone(obj);
}
其他
-
vue中keep-alive组件原理?
- 本质是把组件移动到隐藏的容器中,触发deActivate api,而激活是把组件从隐藏容器中搬运回原来的容器,触发active事件
- 组件的状态不变
- 多出来deactivated和actived生命周期,beforeDestory和destoryed不会再被触发,因为不会被真正的销毁。
-
vue中teleport组件:用来将组件dom移动到指定的位置,通常用于modal,实现就是渲染时将其挂载到to的下面。
-
eslint
- npm init @eslint/config : 创建规则文件
- npx mrm lint-staged:安装提交hooks 钩子,执行eslint命令
总结
- 如果是常见面试题的,自己掌握的回答的就比较好
- 我觉得日常看技术文章的分别就区分出来了,有些确实是跟你之前很多年的积累有关,即使突击,它也是能面出来的,所以以后要养成看技术文章的习惯
- 很多知识点是你认为你懂了,其实一问又被难住了,其实没有真正掌握,所以学习的方法还是得总结才能内化成自己的知识,否则非常容易忘记。没有真正理解的知识点过段时间就会忘,即使你当时懂了,如果长时间不用,也是会忘的。学习还是需要总结+实践才行。