【面试记录】新鲜出炉的某厂面试题

238 阅读9分钟

结果

二面卒

一面

  1. vue的响应式原理
  2. 简述下vdom diff 算法,它是深度还是广度?--没答好
  3. vue与san的区别?
  4. vue3为什么可以多个根节点?
  5. 解释下原形链,es6 class与Function创建类的区别--没答好
  6. 性能优化手段
  7. 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进制
  8. promise settimeout顺序题,解释下js 事件执行过程
  9. 端与js通信过程
  10. websocket 与 轮巡 的区别

css相关

  1. BFC是什么?如何触发BFC
    • overflow:hidden
    • 浮动元素
    • position值 absolute、fixed
    • display:inline-block、table-cell、flex或者inline-flex
  2. 如何实现响应式布局

编程

  1. 写一个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');
  1. 两数之和

直接用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算法温习

vdomdiff.png 15张图,20分钟吃透Diff算法核心原理,我说的!!!写的很棒

理解了上面的diff算法,就能理解为什么用index做key有问题了,因为插入元素后,前后的key不变,直接命中updateChildren中的第一种newS,oldS相同的情况,有会走到patchVode逻辑,而如果用唯一key的话,会判断出来是不同的节点,走到newE、oldE逻辑,判断出后面的节点情况。

san.png

  • 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 与 轮巡 的区别

总结

一面虽然有没答出来的,但大部分答的还可以,所以通过了。

二面

  1. 认为项目中比较有挑战的事情,如何解决?

    我说了我认为有挑战的事情,她不太认同,也许是我表达的问题,没将里面的核心问题表达出来。需要复盘。

  2. 听说过web component吗?熟悉吗?它的优势是什么?

    前端时间听掘金开发者大会,一个大佬讲他们做的跨平台的组件库,哈,用上了,ppt传送门

  3. webAssembly听过吗?它的优势是什么?为什么比其他的快?

    为啥快这个没了解,没答出来

像是考广度?问的很杂。

  1. webpack、rollup、vite三者的区别?vite原理?--木有大号
  2. 你的优势是什么?

css相关

  1. position属性解释下
  2. 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却不会产生边距效果.
  3. 了解css层级吗?哪些属性会触发新开一个层级?css 渲染层最好了解下

内心os:竟然问这么细的css问题,没想到,显然有的没答好,老菜鸟难过😫

编程

  1. 写一个快排的算法,并且调试出来

    写了有点久,调试也比较慢,估计是这个写的不太好,跟挂有很大关系,孩子们,给挑挑刺吧,写的确实不够优雅,面试官说可以不用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)

复盘

  1. 核心问题:编程写法以及调试偏慢

  2. css层叠上下文概念、图层?

  3. 浏览器渲染层复习

  4. vite原理复习 image.png 手写vite b站传送门

  5. 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 要先通过服务器端进行代码优化。
  6. 项目有挑战的地方

总结

二面一开始就感觉不顺利,中间有答的好的,有答的不好的,过程中就感觉跟面试官气场不合,挂掉的最终原因应该跟最后快排写的不好有关。