2022.4.28字节飞书一面
- 自我介绍
- 为什么会想选择前端这个方向
- 这个过程中通过哪些方式去学习前端
- 看过哪些方面的书
- 前端向后端发送请求,或者前端去请求一些静态资源的时候,在加载方面一般有什么优化的手段
- 缓存机制
- 在哪些不同的情况下,强缓存和协商缓存怎么选择
- 缓存策略的基本实现目标:
- 尽可能地命中本地缓存,减少请求、加快响应
- 后台资源更新可以及时获取 - 常用策略:
- 首先对资源使用哈希命名(结合 webpack 的 contenthash 等),让文件名基于文件内容命名,如果内容改变,文件名也会改变,这样浏览器会认为资源改变,而重新请求
- 对 html 资源使用协商缓存,总要与后台保持最新
- js、png、css 资源使用强缓存,尽量命中本地
- 如果 js、png、css 等资源更新,其对应文件命名也会改变,从而导致 html 对应的标签发生更新,导致 html 资源的更新,浏览器能够重新请求 html 文档,再基于新文档所引用的资源,判断对应的缓存是否存在,不存在的重新请求,存在的直接命中缓存
- 打包切割
- 服务端推送
- CDN的方式
- 缓存机制
- 浏览器渲染页面过程
- DOM树和CSS树,后面合成渲染树
- 后续稍微复杂些的渲染过程没答出来❎
- async和defer区别,如何选择,有没有什么更可靠的方式或最佳实现
- 放置位置
- 哪些会造成重绘和重排❎,有什么区别(答的不够清晰)
- JS的数据类型有哪些
- 判断数据类型(typeof的局限)
- Object.prototype.toString.call()
- instanceof
- instanceof和typeof的区别
- constructor
- Array.isArray
- 判断数据类型(typeof的局限)
- 改变作用域(改变this)
- call、apply、bind
- 三者区别
- new Fn()
- obj.xxx()
- call、apply、bind
- JS的继承方式
- 寄生组合式继承,实现过程
- typescript中const和readonly❎
- type和interface的区别和选择❎(ts就是给自己挖坑😭,之前没怎么看ts方面的面试题)
- axios的封装,取消重复请求
- 没有了解axios提供的api底层的实现❎
- 如何判断是同一个请求,或者怎么确定(也没答得很好)
- content-type起了什么作用
- 让服务器去识别这个内容的格式❎(这个其实不难,没答清楚)
- (项目)mini-vue实现了哪些模块
- v-for的key的作用(我擦,我以为他问的是编译模块实现用了什么key,听回放才听出来,哭了😭)❎
- reactivity的实现
- 深浅拷贝
- js原生方法
JSON.stringify
和JSON.parse
Object.assign
- 扩展运算符
- 实现一个深拷贝(满足数组对象即可)
- js原生方法
- 对象去重:给定一个对象数组,给定一个要过滤key数组,将包含相同key且value相同的子项过滤掉
js
let arr = [
{
id:1,
num:13
},
{
id:2,
num:22,
age:18
},
{
id:3,
num:13,
age:4
},
{
id:2,
num:64
}
]
// objArr = arr;
// keyArr = [‘id’,‘num’];
function objFilter(objArr, keyArr) {
let map = {};
return objArr.reduce((prev, cur) => {
let keys = Object.keys(cur).filter((item) => keyArr.includes(item));
let flag = true;
for (let key of keys) {
if (map[key] === undefined) {
map[key] = [cur[key]];
} else {
if (map[key].includes(cur[key])) {
flag = false;
break;
} else {
map[key].push(cur[key]);
}
}
}
if (flag) prev.push(cur);
return prev;
}, []);
}
// 去重结果:剩余前两项