当前位置: 首页 > 面试经验 >

哈喽单车一面面经

优质
小牛编辑
107浏览
2023-03-28

哈喽单车一面面经

一、介绍一下 vue-router 相关的 api
二、说一下js的事件循环机制
    1. 所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)。
    2. 遇到异步任务, 进入Event Table并注册回调函数; 等到指定的事件完成时,Event Table会将这个回调函数移入Event Queue,如果是宏任务就加入宏任务队列,微任务加入微任务队列。
    3. 当栈中的代码执行完毕,执行栈(call stack)中的任务为空时,主线程会先检查micro-task(微任务)队列中是否有任务,如果有,就将micro-task(微任务)队列中的所有任务依次执行,直到micro-task(微任务)队列为空; 之后再检查macro-task(宏任务)队列中是否有任务,如果有,则取出第一个macro-task(宏任务)加入到执行栈中,之后再清空执行栈,检查micro-task(微任务)队列,以此循环,直到全部的任务都执行完成。
  • 三、setInterval有什么性能问题?

    定时器代码:

    setInterval(fn(), N); 复制代码

    上面这句代码的意思其实是fn()将会在 N 秒之后被推入任务队列

    所以,在 setInterval 被推入任务队列时,如果在它前面有很多任务或者某个任务等待时间较长比如网络请求等,那么这个定时器的执行时间和我们预定它执行的时间可能并不一致。

    考虑极端情况,假如定时器里面的代码需要进行大量的计算(耗费时间较长),或者是 DOM 操作。这样一来,花的时间就比较长,有可能前一次代码还没有执行完,后一次代码就被添加到队列了。也会到时定时器变得不准确,甚至出现同一时间执行两次的情况。

    最常见的出现的就是,当我们需要使用 ajax 轮询服务器是否有新数据时,必定会有一些人会使用 setInterval,然而无论网络状况如何,它都会去一遍又一遍的发送请求,最后的间隔时间可能和原定的时间有很大的出入。

    setInterval 有两个缺点:

    • 使用 setInterval 时,某些间隔会被跳过;
    • 可能多个定时器会连续执行;

    可以这么理解:每个 setTimeout 产生的任务会直接 push 到任务队列中;而 setInterval 在每次把任务 push 到任务队列前,都要进行一下判断(看上次的任务是否仍在队列中,如果有则不添加,没有则添加)。

    因而我们一般用 setTimeout 模拟 setInterval,来规避掉上面的缺点。

    具体实现如下:

    1.写一个 interval 方法

     
    					
    let timer = null
    function interval(func, wait){
    let interv = function() {
    func.call(null); timer=setTimeout(interv, wait); }; timer= setTimeout(interv, wait); }

    2.和 setInterval() 一样使用它

    interval(function() {}, 20);

    3.终止定时器

    if (timer) { window.clearSetTimeout(timer);
      timer = null;
    }

    四、重绘与回流有了解过吗,请简要说一下
    会引起元素位置变化的就会回流,窗口大小改变、字体大小改变、以及元素位置改变,都会引起周围的元素改变他们以前的位置;不会引起位置变化的,只是在以前的位置进行改变背景颜色等,只会重绘;每一次的回流都会将网页内容重新渲染,只是我们人眼感觉不到有任何变化,但是它确实是会清空页面的,再从页面的左上角的第一个像素点从左到右从上到下这样一点一点渲染,每次回流都会是这样的过程,只是感觉不到而已
    如何避免:
    css:
    • 避免使用table布局。
    • 尽可能在DOM树的最末端改变class。
    • 避免设置多层内联样式。
    • 将动画效果应用到position属性为absolute或fixed的元素上。
    • 避免使用CSS表达式(例如:calc())。
    JavaScript:
    • 避免频繁操作样式,最好一次性重写style属性,或者将样式列表定义为class并一次性更改class属性。
    • 避免频繁操作DOM,创建一个documentFragment,在它上面应用所有DOM操作,最后再把它添加到文档中。
    • 也可以先为元素设置display: none,操作结束后再把它显示出来。因为在display属性为none的元素上进行的DOM操作不会引发回流和重绘。
    • 避免频繁读取会引发回流/重绘的属性,如果确实需要多次使用,就用一个变量缓存起来。
    • 对具有复杂动画的元素使用绝对定位,使它脱离文档流,否则会引起父元素及后续元素频繁回流。

    五、说一下浏览器的渲染过程:

    渲染流程主要有4个步骤

    • 解析 HTML 生成DOM 树

    • 解析 CSS 样式生成 CSSOM 树,CSSOM 树与 DOM 树结合生成 Render tree

    • 布局 Render Tree 对每个节点进行布局处理,确定在屏幕上的位置

    • 绘制 Render Tree,遍历渲染树将每个节点绘制出来

    为了优化用户体验,渲染引擎不会等到 HTML 解析完才创建布局渲染树


    六、要实现一个盒子在页面上运动,怎样实现才能使动画性能最好:
    这里我们只需要了解 css 和 js 做动画的区别是什么:
    第一点

    从实现动画的复杂度来看,CSS 动画大多数都是补间动画,而 JS 动画是逐帧动画。当然这里我们不谈论实现的效果

    第二点

    编码的高效,采用 JS 去实现的动画,无论多简单的动画,都需要去控制整个过程,当然你可能会说可以采用一些库来解决这些问题,但是这些库的实际运行可能要比原生实现的效率要低的多

    第三点

    性能的高效,如果我们要操作一个元素向右移动,我们可能需要控制 dom.style.left 属性,每次来改变元素的位置几何属性的改变必然会引起回流,回流必然引起重绘,可想而知如果我们采用 JS 来实现动画,这个代价有多大,这会造成浏览器在不断的计算页面,从而导致浏览器内存堆积。同时由于 JavaScript 运行在浏览器的主线程中,主线程中还有其他的重要任务在运行,因而可能会受到干扰导致线程阻塞,从而丢帧

    而 CSS 的动画是运行在合成线程中的,不会阻塞主线程,并且在合成线程中完成的动作不会触发回流和重绘,当然还有一个重要的点:JS 动画运行在 CPU,而 CSS 动画运行在 GPU,总的来说, CSS动画的渲染成本小,并且它的执行效率高于 JavaScript 动画


    七:计算机网络中的三次握手和四次挥手都是啥意思:
    这个网上都有,不过前端把这些背住了也没啥用吧,简单知道下啥是三次握手就行了

    八:看到你的项目里用了 lazy-load,你知道内部的实现原理吗?
    B站有教手写 vue-lazyLoad 的,自己动手写一遍是最有帮助的,这是地址:【全网首发:更新完毕】Vue源码重写之『vue-lazyload』【高级程序设计】_哔哩哔哩_bilibili



    #前端实习生面试#
     类似资料: