面试题复盘和总结+深入学习

913 阅读19分钟

前言

经过这段时间的面试,在刷面试题时发现面试题类的文章要么就是一些简单的回答,要么就是长篇大论;为了方便大家,也为了方便自己,从而写出了这篇文章。
此篇文章通过站在面试官的角度来问你问题,答案分为两个部分普通版深入版

普通版:用于面试时回答
深入版:都是引用的链接,用于深入学习
最好看深入版链接的文章进行学习,这样有自己的理解,也更好在面试的时候作答

文章灵感来源于HearLing大佬的文章:化身面试官出 30+Vue 面试题,超级干货(附答案)|牛气冲天新年征文
在此感谢大佬

------ 废话不多说,咋们开始 ------

你先做个自我介绍吧 。。。 在你自我介绍的时候呢,我就看看你做过的项目,技术栈什么的。
先来个简单点的,顺便想下接下来该问那些技术栈

HTML/CSS 篇

垂直水平居中有哪些方法

答案

普通版
  • position:负margin
    position: absolute;
    
    // 负margin
    top: 50%;
    left: 50%;
    margin-top: -高度的一半;
    margin-left: -宽度的一半;
    
    // calc,与上同理
    top: calc(50% - 50px);
    left: calc(50% - 50px);
    
    // transform
    transform: translate(-50%, -50%);
    
  • flex布局:
    justify-content: center;
    align-items: center;
    

不错,不错,问下能否能熟练的运用

未知宽度和高度图片,在一个 200px*200px 的 DIV 里面,需要水平垂直居中自适应显示

答案

.imgDiv {
    width: 200px;
    height: 200px;
    display: flex;
    justify-content: center;
    align-items: center;
}
.imgDiv img {
    width: auto;
    height: auto;
    max-width: 100%;
    max-height: 100%;
}

emmmmm,看来蛮熟练的,来个难点的

浏览器的回流与重绘知道吗?知道的话说一下

答案

普通版
  • 回流 (Reflow):当Render Tree中部分或全部元素的尺寸、结构、或某些属性发生改变时,浏览器重新渲染部分或全部文档的过程称为回流。
  • 重绘 (Repaint):当页面中元素样式的改变并不影响它在文档流中的位置时,浏览器会将新样式赋予给元素并重新绘制它,这个过程称为重绘。
  • 一句话:回流必将引起重绘,重绘不一定会引起回流。
  • 性能影响:回流比重绘的代价要更高;有时即使仅仅回流一个单一的元素,它的父元素以及任何跟随它的元素也会产生回流。
Tips

在回答的时候最好加上如何避免,如果回答的时候没有回答如何避免,那么面试官可能会问如何避免


看到简历上面有ES6的技术栈,问一下

ES6/ES7 篇

ES6 的新特性有了解吗?用到了那些?

答案

普通版
  • letconst
  • 箭头函数、展开运算符 ...
  • class
  • Symbol
  • Promiseasync/await
  • SetMap
  • 数组的扩展

好家伙,说了这么多,有的问了

你刚才说到了 Let、const,那么他们什么区别呢?又和 var 有什么区别呢?

答案

普通版
  • var:存在变量提升,可以重复声明,全局变量属于顶层对象
  • let、cosnt:不存在变量提升,不可以重复声明,块级作用域
  • let 可以修改值; const 不能修改值(引用类型仅保证地址不被修改)
  • 在代码块内,使用let、const命令声明变量之前,该变量都是不可用的
Tips
  • 面试中,面试官可能会接着问你暂时性死区

这都难不倒你,问下你Promise这方面的,看你如何回答

Promise、async/await 说一说

答案

普通版
  • Promise:有等待态(Pending)、执行态(Fulfilled)和拒绝态(Rejected),一旦 promiseresolvedrejected,不能再迁移至其他任何状态。有 Promise.allPromise.race 两个方法
  • Promise.all:接收一个 promise 数组。当数组中所有的 promise 的状态都达到resolved 的时候,Promise.all 的状态就会变成 resolved,如果任意一个状态变成了 rejected,那么状态就会变成rejected,可以解决并行的问题。
  • Promise.race:接收一个 promise 数组。,哪个先执行完,race 就直接执行完,并从 then 中取值。
  • async:是 Generator 函数的语法糖,用于申明一个function 是异步的,返回的是一个 promise 对象
  • await:是一个表达式,这个表达式的计算结果是 promise 对象或者其它值,如果等待的是 promise 对象,它会阻塞后面的代码,等着 promise 对象resolve,然后得到 resolve 的值,作为表达式的运算结果。
Tips
  • 面试中,面试官可能会接着问你Promise的值穿透
  • 这里建议大伙尝试手写实现Promise

说的挺详细的,看来有点功底呀,继续

使用箭头函数应注意什么?

答案

普通版
  • 用了箭头函数,this 就不是指向 window,而是父级(指向是可变的)
  • 不能够使用 arguments 对象
  • 不能用作构造函数,这就是说不能够使用 new 命令,否则会抛出一个错误
  • 不可以使用 yield 命令,因此箭头函数不能用作 Generator 函数

ForEach 和 Map 有什么区别,是否会改变原数组

答案

普通版
  • forEach 方法不会返回执行结果, 而是 undefined
  • map 方法会得到一个新的数组并返回
  • 如果值是引用类型的话就会改变

class 说一说

答案

普通版
  • class 是一个语法糖,其底层还是通过 构造函数 去创建的。所以它的绝大部分功能,ES5都可以做到。新的 class 写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。
  • class可以通过 extends 关键字实现继承
  • super:有两种用法,一种是 super 方法,super 方法只能出现在 constructor 方法中;另外一种是 super 对象,一般出现在子类覆盖父类的方法中。

可以呀,看来ES6方面是难不倒你了;看看其余的咋样

JavaScript 篇

JS 执行机制知道吗?说一下

答案

普通版
  • js代码分为同步任务和异步任务
  • 同步任务会进入主线程,异步任务会进入Event Table(事件表),当事件表中的异步任务完成后会在Event Queue(事件队列)中注册回调函数
  • 主线程任务全部完成后,才会完成Event Queue中的任务
  • js解析器会不断地重复检查主线程执行栈是否为空,然后重复第3步,这就是Event Loop(事件循环)
  • 异步任务之宏任务:宏任务有 scriptsetTimeoutsetIntervalI/O 操作
  • 异步任务之微任务:宏任务一般为 ajaxPromise.thenprocess.nextTick
  • Event Loop
    1. 1、整体 script 作为第一个宏任务进入主线程
    2. 2、遇到的宏任添加进宏任务列表
    3. 3、遇到的微任务添加进微任务列表
    4. 4、执行完之后,取出微任务队列中的所有任务依次执行
    5. 5、如果微任务执行过程中产生了新的微任务,则继续执行微任务,直到微任务的队列为空
    6. 6、循环,循环以上 1 - 5

new 一个函数发生了什么

答案

普通版
  1. 创造一个全新的对象
  2. 链接到原型: obj.__proto__ = Con.prototype
  3. 绑定 this
  4. 返回新对象(如果构造函数有自己 retrun 时,则返回该值)

this 说一说呗

答案

普通版
  • 在函数中,可以引用运行环境中的变量。因此就需要一个机制来让我们可以在函数体内部获取当前的运行环境,这便是 this;它是一个对象,产生与函数有关,与执行环境绑定
  • this 绑定规则:默认绑定、隐式绑定、硬绑定、new绑定
    1. 默认绑定:在不能应用其它绑定规则时使用的默认规则,通常是独立函数调用
    2. 隐式绑定:函数的调用是在某个对象上触发的,即调用位置上存在上下文对象。典型的形式为 XXX.fun()
    3. 硬绑定:通过call,apply,bind的方式,显式的指定this所指向的对象
    4. new绑定:看 new 一个函数发生了什么

闭包说一说

答案

普通版
  • 闭包是 JS 函数作用域的副产品,闭包可以让一个函数访问并操作其声明时的作用域中的变量和函数,并且,即使声明时的作用域消失了,也可以调用
  • 《JavaScript高级程序设计》:闭包是指有权访问另一个函数作用域中的变量的函数
  • 《JavaScript权威指南》:从技术的角度讲,所有的JavaScript函数都是闭包:它们都是对象,它们都关联到作用域链。
  • 《你不知道的JavaScript》:当函数可以记住并访问所在的词法作用域时,就产生了闭包,即使函数是在当前词法作用域之外执行。
  • 使用闭包会让函数中的变量保存在内存中,如果滥用闭包会造成性能影响,如果在IE中会导致内存泄露

call、apply、bind 说一说吧

答案

普通版
  • 它们都是用于改变 this的指向
  • 共同点:三个方法的第一个参数,都是this。如果使用的时候不关心 this 是谁的话,可以直接设置为 null
  • callapply 的区别:
    1. 1、apply 是第2个参数,这个参数是一个数组:传给函数参数都写在数组中。
    2. 2、call 从第2~n的参数都是传给fun的。
  • call/applybind的区别:
    1. 1、call/apply 改变了函数的 this 上下文后,马上执行该函数,返回的是调用函数的返回值
    2. 2、bind 改变了 this 上下文后,返回改变了上下文后的函数,不执行该函数

什么是防抖?什么是节流?

答案

普通版
  • 防抖 (debounce):
    1. 理解说明:在函数多次频繁触发时,函数执行一次后,只有大于设定的执行周期后才会执行第二次
    2. 使用场景:页面滚动(scroll)、DOM 元素的拖拽(mousemove)、抢购点击(click)、播放事件算进度信息
  • 节流 (throttle):
    1. 理解说明:在函数频繁触发是,在规定之间以内,只让最后一次生效
    2. 使用场景:搜索框实时联想(keyup/input)、按钮点击太快,多次请求(登录、发短信)、窗口调整(resize)

数组如何去重和扁平化

答案

普通版
  • 数组去重:
    1. 1、ES6的 new Set() 配合 from 或者 展开运算符 ...
    2. 2、利用 filter 配合 indexOf
    3. 3、双循环去重
  • 扁平化:
    1. 1、递归
    2. 2、利用 toString 把数组变成以逗号分隔的字符串,然后遍历数组把每一项再变回原来的类型
    3. 3、flat(depth) 方法,默认值为1,不管多少层则可以用 Infinity 关键字作为参数

深拷贝和浅拷贝区别和实现

答案

普通版
  • 浅拷贝:重新在堆中创建内存,拷贝前后对象的基本数据类型互不影响,但拷贝前后对象的引用类型因共享同一块内存,会相互影响。
  • 深拷贝:从堆内存中开辟一个新的区域存放新对象,对对象中的子对象进行递归拷贝,拷贝前后的两个对象互不影响。
  • 浅拷贝实现:
    1. 1、Object.assign()
    2. 2、展开运算符 ...
    3. 3、数组的 concat()
    4. 4、数组的 slice()
  • 深拷贝实现:

    1、利用 JSON.parse(JSON.stringify())方法,但是不能识别 undefinedsymbolfunctionRegExp 引用类型会变成空对象,拷贝 Date 引用类型会变成字符串

    2、递归实现


看来基础掌握得非常好,在问下VUE

VUE 篇

说下 VUE 的生命周期

答案

普通版
生命周期
发生了什么
beforeCreate 创建前。在当前阶段 datamethodscomputed、以及 watch 上的数据和方法都不能被访问
created 创建后。当前阶段已经完成了数据观测,也就是可以使用数据,更改数据,在这里更改数据不会触发 updated 函数。可以做一些初始数据的获取,在当前阶段无法与 Dom 进行交互,如果非要想,可以通过 vm.$nextTick 来访问。推荐在在这个周期中调用异步请求
beforeMount 挂载前。在这之前 template 模板已导入渲染函数编译。而当前阶段虚拟Dom已经创建完成,即将开始渲染。在此时也可以对数据进行更改,不会触发 updated
mounted 挂载后。在当前阶段,真实的Dom挂载完毕数据完成双向绑定可以访问到Dom节点,使用$refs属性对Dom进行操作
beforeUpdate 更新前。也就是响应式数据发生更新,虚拟dom重新渲染之前被触发,你可以在当前阶段进行更改数据,不会造成重渲染
updated 更新后。当前阶段组件Dom已完成更新。要注意的是避免在此期间更改数据,因为这可能会导致无限循环的更新
beforeDestroy 销毁前。在当前阶段实例完全可以被使用,我们可以在这时进行善后收尾工作,比如清除计时器
destroyed 销毁后。这个时候只剩下了dom空壳。组件已被拆解,数据绑定被卸除,监听被移出,子实例也统统被销毁
  • 使用 keep-alive 会出现两个生命周期:
    1. activited:组件被激活前
    2. deactivated:组件被销毁时调用
  • 组件生命周期调用顺序: 调用顺序都是先父后子,渲染完成的顺序是先子后父。
  • 组件的销毁调用顺序: 先父后子,销毁完成的顺序是先子后父

说下 VUE 响应式数据/双向绑定原理

答案

普通版
  • vue2.x :响核心就是 Object.defineProperty()
    1. 1、 initData 初始化用户传入的参数
    2. 2、 Observe (观察者)观察 propsstate,遍历 propsstate,对每个属性创建独立的监听器( watcher )
    3. 3、使用 defineProperty 重写每个属性的 setter/getter(defineReactive)getter 做依赖收集,setter 派发更新。整体来说是一个 数据劫持 + 发布-订阅者模式。
  • vue3.x : 改用 ProxyReflect 替代 Object.defineProperty() 可以原生监听数组,可以监听对象属性的添加和删除,不需要深度遍历监听

说下 VUE 路由模式

答案

普通版
  • hash模式:响核心就是 Object.defineProperty()
    1. 1、 # 号后面 hash 值的变化,不会导致浏览器向服务器发出请求,浏览器不发出请求,就不会刷新页面
    2. 2、 通过监听 hashchange 事件可以知道 hash 发生了哪些变化,然后根据 hash 变化来实现更新页面部分内容的操作
  • history 模式: history 模式的实现,主要是 HTML5 标准发布的两个 pushStatereplaceState API,这两个 API 可以在改变 url时,不会发送请求。通过监听 url 变化来实现更新页面部分内容的操作
  • 两者的区别:
    1. 1、hash 可以支持低版本浏览器和 IE
    2. 2、hash 模式有“#”,history 模式没有

说下 VUE 中的 v-if 和 v-show 的区别

答案

普通版
  • v-for: 操作的是样式(display),切换当前DOM的显示和隐藏,适用于需要非常频繁切换条件的场景
  • v-if: 当条件不成立时,不会渲染DOM元素,适用于不需要频繁切换条件的场景

使用 VUE 中的 v-for 时为什么要用 key

答案

普通版
  • 为了快速的找到新节点对应的旧节点, key 是给每一个 vnode 唯一的 id, 可以依靠 key,更准确、更快的拿到 oldVnode 中对应的 vnode 节点,如果不使用 key 时也可以运行,但是会报 warning

说说 VUE 中 VUEX

答案

普通版

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式,VUEX有5个核心属性

    5个核心属性分别为:
  • state:状态中心
  • getters:获取状态
  • mutations:更改状态
  • actions: 异步更改状态
  • modules:将state分成多个modules,便于管理

说下 VUE 如何优化

答案

普通版
  • 1、路由懒加载
  • 2、图片懒加载
  • 3、区分 v-showv-if 使用场景
  • 4、区分 v-forv-if 不要一起使用
  • 5、区分 v-for 避免使用 index 作为 key
  • 6、提取公共样式
  • 7、第三方插件按需加载
  • 8、computedwatch 区分使用场景

写简历建议

写项目经验的时候,记得写上项目用了那些技术点,写你所掌握的,方便面试官问你;不然面试官就会自己想面试题问了。写上去的技术点一定要掌握,设计的知识点也最好非常熟悉,因为面试会在你回答的时候,从你回答的一些答案当中挑出技术点去回答。
如果你有很多的好项目经验,可以都写上去,不要想着简历最好不要超过两张纸

面试建议

1、在去面试前,记得去查面试公司的相关信息,到公司后,在本子上写上该公司的信息(名称、地址)、什么时间面试的、公司给你的第一感觉如何
2、面试时,回答面试题时要回答详细点,加上自己的理解;不要一直让自己处于被问的状态,最好抓住你抓掌握的点,去跟面试官讨论,或者有些你不是很清楚的去问面试官;
3、面试后记得把没有回答上的面试题或者回答得不是很深的面试题记上本子上,并写上面试上所了解的公司信息
4、在去下一家公司面试的路上开始查找记录的面试题并进行深度的理解,并思考这家公司是否符合自己的心里预期,好方便后面的选择
5、晚上到家后,对整天的面试进行复盘,如言行举止、面试时回答是否回答得体

个人面试笔记模板

微信图片_20210408110138.png

进阶篇链接

个人收藏的面试题链接

感谢

如果有错误或者不严谨的地方,烦请给予指正,十分感谢。如果喜欢或者有所启发,欢迎点赞,对作者也是一种鼓励。