结果
二面卒
一面
- vue的响应式原理
- 简述下vdom diff 算法,它是深度还是广度?--没答好
- vue与san的区别?
- vue3为什么可以多个根节点?
- 解释下原形链,es6 class与Function创建类的区别--没答好
- 性能优化手段
console.log([1, 2, 3, 4].map(parseInt))输出什么?[1, NaN, NaN, NaN]- 等同于 parseInt(1,0) ,parseInt(2,1),parseInt(3,2),parseInt(4,3)
- 第二个参数为0时等同于10进制
- promise settimeout顺序题,解释下js 事件执行过程
- 端与js通信过程
- websocket 与 轮巡 的区别
css相关
- BFC是什么?如何触发BFC
- overflow:hidden
- 浮动元素
- position值 absolute、fixed
- display:inline-block、table-cell、flex或者inline-flex
- 如何实现响应式布局
编程
- 写一个eventBus,加once, 需要再对比其他写的好的代码。
class EventBus {
constructor() {
this.eventHandler = {};
}
on(name, fn) {
if (!this.eventHandler[name]) {
this.eventHandler[name] = [];
}
this.eventHandler[name].push(fn);
}
emit(name, ...args) {
const fns = this.eventHandler[name];
if (fns && fns.length) {
fns.forEach(fn => {
fn(...args);
});
}
}
off(name, fn) {
const fns = this.eventHandler[name];
if (!fns || !fns.length) {
return;
}
if (!fn) {
this.eventHandler[name] = [];
} else {
for (let i = 0; i < fns.length; i++) {
if (fn === fns[i]) {
fns.splice(i, 1);
}
}
}
}
// 绑定事件,执行回调,回调执行完将事件清除掉
once(name, cb) {
let off = this.off.bind(this);
const callback = function (...args) {
cb(...args);
off(name, callback);
}
this.on(name, callback);
}
}
const bus = new EventBus();
bus.on('name1', function () {
console.log('name11');
});
bus.on('name1', function () {
console.log('name12');
});
bus.on('name2', function (a, b) {
console.log('name2');
});
bus.once('name3', function (a, b) {
console.log('name3');
});
bus.emit('name1');
bus.emit('name2');
bus.emit('name3');
- 两数之和
直接用hash来存储了,还有一种写法是排序,双指针?
function findTarget(nums, target) {
let hash = {};
for (let i = 0; i < nums.length; i++) {
hash[nums[i]] = i;
}
for (let i = 0; i < nums.length; i++) {
const val = nums[i];
const val2 = target - val;
if (val2 in hash) {
return [i, hash[val2]];
}
}
return [];
}
复盘
需要复习总结的知识点:
- vdom diff算法温习
15张图,20分钟吃透Diff算法核心原理,我说的!!!写的很棒
理解了上面的diff算法,就能理解为什么用index做key有问题了,因为插入元素后,前后的key不变,直接命中updateChildren中的第一种newS,oldS相同的情况,有会走到patchVode逻辑,而如果用唯一key的话,会判断出来是不同的节点,走到newE、oldE逻辑,判断出后面的节点情况。
- vue3响应式
- vue3为什么可以多根节点?
- 因为template会被编译成vdom树,而这个树是单根节点的,所以vue2只支持单根节点
- 创建了Fragment元素,将所有内容都挂在到这个下面,path时判断如果是Fragment类型,则直接取对应的children进行循环path 源码
- vue和san区别
-
es6 class与Function区别
- 类内部的所有方法(除去constructor)都是默认定义在原型上的,是不可枚举的,es5的function可以枚举
- class 没有提升的效果,只有定义后才能使用,这个跟Function定义不一样
- 继承的this区别:class子类需要通过调用super继承父类的this,否则会报错,但是es5的时候继承,是把父类的属性以及方法赋值到子类构造函数的this上,这个应该是区别最大的。
-
性能优化手段
- 加载阶段:
- 减少网络请求:js异步请求,css内敛
- 减少网络传输大小:压缩css、js等
- 图片:小图片换成base64、使用字体图标、webp格式,图片懒加载,图片放在cdn上
- 换成http2:多路复用、头部压缩,只开启一条tcp链接,减少了tcp连接创建时间,并且增加了一个二进制分桢层,来并行传输。http2
- 交互阶段:从浏览器渲染原理考虑,需要减少重绘和重排。
- 频繁操作dom时使用documentFragment,在它上面完成所有的操作,再放回页面中
- 避免同步布局,不要在操作dom之后立马查询dom的属性,这样会导致同步布局,因为正常的流程是js一个task,之后样式重新布局会到另一个task中,如果立刻读取的话,需要马上布局,造成同步布局,影响性能。
- 能用css实现的动画用css:通过 CSS 实现一些变形、渐变、动画等特效,这是由 CSS 触发的,并且是在合成线程上执行的,这个过程称为合成。因为它不会触发重排或者重绘,而且合成操作本身的速度就非常快,所以执行合成是效率最高的方式。可以将有动画的元素添加will-change属性,是 告诉渲染引擎需要将该元素单独生成一个图层。
- 有动画的元素开启绝对定位开启一个新的层级
- 利用节流和防抖
- 减少js请求时间,可以分批执行或者web worker执行复杂计算
- 加载阶段:
-
一个页面如何实现同时兼容H5和pc页面的
- 媒体查询
- rem:屏幕分成100份,font-size根据屏幕大小动态的设置成clientWidth/100,元素的大小就是元素占屏幕的百分比*100,pc的话会有一个最大值限制
- vh、vw:相当于简化了上面的html根节点的font-size设置,可以直接用xx vw
- flex、grid布局
-
websocket 与 轮巡 的区别
总结
一面虽然有没答出来的,但大部分答的还可以,所以通过了。
二面
-
认为项目中比较有挑战的事情,如何解决?
我说了我认为有挑战的事情,她不太认同,也许是我表达的问题,没将里面的核心问题表达出来。需要复盘。
-
听说过web component吗?熟悉吗?它的优势是什么?
前端时间听掘金开发者大会,一个大佬讲他们做的跨平台的组件库,哈,用上了,ppt传送门
-
webAssembly听过吗?它的优势是什么?为什么比其他的快?
为啥快这个没了解,没答出来
像是考广度?问的很杂。
- webpack、rollup、vite三者的区别?vite原理?--木有大号
- 你的优势是什么?
css相关
- position属性解释下
- css盒模型解释下,内敛元素的width、height生效吗?设置margin和padding呢?
- 块级元素可以设置width,height,margin和padding属性.
- 行内元素设置宽高无效,但是水平方向的padding-left,padding-right,margin-left,margin- right都产生边距效果,但竖直方向的padding-top,padding-bottom,margin-top,margin-bottom却不会产生边距效果.
- 了解css层级吗?哪些属性会触发新开一个层级?css 渲染层最好了解下
内心os:竟然问这么细的css问题,没想到,显然有的没答好,老菜鸟难过😫
编程
-
写一个快排的算法,并且调试出来
写了有点久,调试也比较慢,估计是这个写的不太好,跟挂有很大关系,孩子们,给挑挑刺吧,写的确实不够优雅,面试官说可以不用index的写法,构造left和right的数组。
function swap(arr, i, j) {
let tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
function quickSort(arr, left, right) {
if (left >= right) {
return;
}
// 随机选取一个枢纽元,放到最后一个位置
const pivotIndex = Math.round(Math.random() * (right - left + 1) + left);
const pivot = arr[pivotIndex];
swap(arr, pivotIndex, right);
let i = left;
let j = right - 1;
while (i <= j) {
while (arr[i] < pivot && i < right) {
i++;
}
while (arr[j] > pivot && j >= left) {
j--;
}
if (i < j) {
swap(arr, i, j);
}
}
swap(arr, right, i);
quickSort(arr, left, i - 1);
quickSort(arr, i + 1, right);
}
const arr = [3, 1, 2, 5, 4];
quickSort(arr, 0, arr.length - 1)
console.log(arr)
// 构造left与right数组:选取枢纽元,然后遍历数组,将小于枢纽元的放到left数组,大于枢纽元的放到right数组,然后递归求解
function quickSort2(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 [...quickSort2(left), pivot, ...quickSort2(right)]
}
const arr1 = [3, 1, 2, 5, 4];
quickSort2(arr1, 0, arr1.length - 1)
复盘
-
核心问题:编程写法以及调试偏慢
-
css层叠上下文概念、图层?
-
如何形成层叠上下文
- 文档根元素
- position属性的值不为static且z-index值不为auto
- opacity属性值小于1
- flex/grid布局且z-index不为auto
- will-change值设定任意属性,且值为非初始化值
- transform不为none
- filter不为none
-
如果处于同一层级,按照css层叠顺序来
-
如果处于不同的层叠上下文,则按照顶层元素的z-index判断。
-
层叠上下文和图层不是一个概念 层叠上下文 渲染图层 复合图层(硬件加速)区别与联系,某些特殊的渲染层会被提升为复合成层(Compositing Layers),复合图层拥有单独的 GraphicsLayer,而其他不是复合图层的渲染层,则跟随第一个拥有 GraphicsLayer 的父层。
-
如何开启复合图层
- 3d转换 translate3d、translateZ
- video、canvas、iframe
- will-change
- filter
- 等等
-
-
浏览器渲染层复习
-
vite原理复习
手写vite b站传送门
-
webassembly
- WebAssembly 完全入门:了解 wasm 的前世今身
- 是浏览器原生支持的能力了
- 可以使用c、c++、rust、python、java编写程序,编译成wasm格式的文件,在浏览器运行。
- 用途:一些桌面端的应用,例如之前用c++写的可应用到浏览器运行了,例如autoCAD等软件
- 为什么快?zhuanlan.zhihu.com/p/25773367 有点多
- 文件抓取阶段,WebAssembly 比 JavaScript 抓取文件更快。即使 JavaScript 进行了压缩,WebAssembly 文件的体积也比 JavaScript 更小;
- 解析阶段,WebAssembly 的解码时间比 JavaScript 的解析时间更短;
- 编译和优化阶段,WebAssembly 更具优势,因为 WebAssembly 的代码更接近机器码,而 JavaScript 要先通过服务器端进行代码优化。
-
项目有挑战的地方
总结
二面一开始就感觉不顺利,中间有答的好的,有答的不好的,过程中就感觉跟面试官气场不合,挂掉的最终原因应该跟最后快排写的不好有关。