[前端高频面试] 2023年初级、中级面试题解

单纯为了自己面试方便,整理一些高频面试题,2023希望每个前端小伙伴找到心仪的工作!!

目录

「自我介绍(仅供参考)」

「HTML、CSS相关」

 » H5有哪些新特性?

 » 浏览器渲染机制、重排、重绘

» 简述CSS盒模型

» 如何让盒子水平垂直居中

» 如何实现一个三角形?

» CSS样式优先级

» display:none 和 visibility: hidden 的区别?

» 什么是BFC?BFC布局规则是什么?如何创建BFC?

» cookies、localStorage、sessionStorage的区别?

「JS」

» 什么是闭包?

» 作用域、作用域链、变量提升、函数提升分别是什么?

» JS有哪些数据类型?typeof、instanceof、类型转换

» 原型和原型链

» 继承(含ES6)、多种继承方式

» this指向、new关键字

» bind、call、apply的区别?

» JS 的设计模式?

» 深拷贝和浅拷贝

» TS 和 JS 有什么区别,优点和缺点

» 什么是事件冒泡、事件捕获、事件委托机制?

» 普通事件和事件绑定有什么区别?

» EventLoop(线程机制)

» 防抖和节流

» 函数柯里化

「ES6」

» var 、 const、 let 的区别?

» Promise的理解

» Promise.all 和 Promise.race

» 箭头函数和普通函数的区别?

» map 和 forEach 的区别?

「Ajax API模块」

» ajax同源策略的理解,如何解决跨域?

» HTTP状态码有哪些?

» get 和 post 的区别?

» HTTP 和 HTTPS 的区别?

» 浏览器从输入url到渲染页面,发生了什么?

» 输入url 后 http请求的完整过程是什么?

「Vue2和Vue3」

» vue2 和 vue3的区别?

» vue2相比vue3有什么缺点?

» vue3有哪些新特性吗?它们带来什么影响

» vue2 数据双向绑定原理

» v-model的实现以及实现原理?

» MVVM开发模式的理解?

» vue组件通信有哪几种方式?

» 的作用是什么?或者vue切换页面如何保存状态?

» vuex有哪几种属性?

» vue-router路由实现原理是什么?有什么不同

» $route 和 $router的区别?

» vue中key 的作用是什么?

» 虚拟DOM和真实DOM的区别?

» computed 、watch 、methods的区别?

» 组件中的data为什么是一个函数?

» v-if 和 v-show的区别?

» vue数据变化视图不更新如何解决?

» 父子组件生命周期渲染顺序?

「前端性能优化」

» 前端性能优化的几种方式

» Vue首屏渲染优化有哪些?

» CDN加速静态资源是什么?

「前端工程化」

» express 和 koa 有什么区别?

» webpack配置

» 前端为什么要进行打包和构建?

» webpack的基本功能有哪些?

» 常见的Webpack Loader?解决什么问题

» Loader 和 Plugin 的不同?

» 有哪些常见的 Plugin插件?解决什么问题的?

» Vite 和 Webpack区别?

» 为什么Vite 比 webpack速度快?

「职业技能规划、人事面试」

» 你的职业规划是什么?

» 为什么从上一家公司离职?

» 前端是如何学习的?

» 项目中有遇到什么难题?

» 还有什么想问的?

「自我介绍(仅供参考)」

注意: 别紧张,目光注视面试官,不要有小动作,自信!!自信!!自信!!

面试官您好,我叫XXX,目前从事前端开发工作已经有X年,我上家公司是一个外包公司做别人的项目的,主要从事H5页面,后台管理系统和小程序等项目开发,其中H5和PC端是一套做保险相关业务的,在做H5的时候遇到过一个bug就是做微信分享SKD签名无效,请求的后台数据也返回了,后端就反映不是自己的问题,但反复排查发现是后端返回的签名和公众号配置的签名不一致,导致签名无效,分享失败...我呢平常喜欢逛一些技术社区丰富自己的技术,像知乎,掘金之类,并且自己也独立开发了个人博客网站,记录自己的工作总结和学习心得。 我的性格比较温和,跟同事朋友相处时比较外向,在工作中代码开发时我喜欢全心全意的投入,对于工作我也抱着认真负责的态度。面试官,以上是我的介绍,谢谢。

「HTML、CSS相关」

 » H5有哪些新特性?

  • 语义化标签: main、header、nav、article、section、aside、footer 
语义化指的就是合理正确的使用语义化标签来创建页面结构,如:
header、nav、footer,从标签上就能看出这个标签的作用,而不是滥用div
语义化的优点:
代码结构清晰,易于阅读、利于开发和维护
方便其他设备解析(如屏幕阅读器)根据语义渲染网页
有利于搜索引擎优化(SEO),搜索引擎爬虫会根据不同的标签来赋予不同的权重

 » 浏览器渲染机制、重排、重绘

网页生成过程:

  • HTMl被HTML解析器解析成DOM树
  • css被css解析器解析成CSSOM树
  • 结合DOM树和CSSOM树,生成一颗渲染树(Render Tree)
  • 生成布局(flow),将所有渲染树的所有节点进行平面合成
  • 将布局绘制(paint)在屏幕上

重排(也叫回流):当改变DOM元素位置和大小时,浏览器需要重新计算元素的几何属性,将其安放在接界面的正确位置,这个过程叫做重排

触发:

  1. 添加或者删除DOM元素
  2. 元素位置改变、元素尺寸改变、内容改变
  3. 浏览器窗口尺寸改变

重绘: 当一个元素的外观发生改变,但布局没有发生变化,重新绘制外观的过程

触发: 改变元素的 color、 background、box-shadow等属性

总结:重排一定会引起重绘,重绘不一定会引起重排,重排的性能消耗比重绘大

如何避免性能影响?

  1. css避免使用table布局,避免设置多层内联样式
  2. 避免频繁操作DOM,对于大量插入DOM操作,建议使用文档片段;用js修改样式,最好不要直接写样式,而是通过class来修改样式

» 简述CSS盒模型

  • 标准盒子(内容盒子):无论设置margin、padding、border,都不会影响内容区的宽高,但会影响盒子实际占的宽高  box-sizing:content-box
  • IE盒模型(边框盒子): width指的是加上margin、padding、border总宽高,内容被挤小
    box-sizing:border-box

» 如何让盒子水平垂直居中

  1. 绝对定位方法: top、bottom、left、right设置为0, margin:auto
  2. 绝对定位方法:top:50%;left:50%; margin-left: 宽度的一半; margin-top:高度的一半
  3. 绝对定位方法:不确定div的宽度和高度,利用transform: translate(-50%,-50%)
  4. flex弹性盒布局:父:display:flex; 垂直居中-align-items:center; 水平居中-justify-content:center

» 如何实现一个三角形?

.box {
    width: 0;
    height: 0;
    line-height: 0;
    font-size: 0;
    border: 50px solid transparent;
    border-left-color: pink;
}
想要哪个方向的三角设置哪个方向的边框颜色

» CSS样式优先级

!important(无穷大)  > 行内样式(1000) > id选择器(100) > 类选择器(10)、属性选择器、伪类选择器  > 标签选择器、元素选择器(1) > 继承或 *通配符选择器(0)

  1. id选择器 ( # myid)
  2. 类选择器( .box )    属性选择器 (a[resl = 'external'])  伪类选择器 (a:hover, li:nth-child())
  3. 标签选择器 (p,div,h1-h6)       伪元素选择器 (p::after    p::before)

» display:none 和 visibility: hidden 的区别?

共同点: 都用来隐藏元素

不同点:

  • display:none; 隐藏元素不占据任何空间,会导致重排和重绘
  • visibility:hidden; 隐藏元素的时候还会占据空间,只是内容不可见,只会导致重绘
  • display:none; 非继承属性,子孙节点的消失是因为渲染树消失造成的,通过修改子孙节点属性无法显示
  • visibility:hidden; 继承属性,子孙节点的消失是由于继承了hidden,通过设置visibility:visible;可以让子孙节点显示

» 去除浮动的几种方式?(问可顺带答出BFC)

浮动的元素会脱离文档流,什么叫脱离文档流,举个栗子: 有一天你和你老板说:世界那么大,你想去看看,那之后你老板就管不了你了。脱离文档流也同理,一个元素一旦浮动,就会脱离文档流,那父元素也就管不了他了,布局就会往前推进, 父元素就会出现 高度塌陷 的问题。

  1. 将父级设置成浮动,float:left 缺点:父级设置浮动了,那爷爷不也受影响了,又得解决爷爷的高度塌陷问题,无限套娃
  2. 给父级设置定位absolute, 缺点:也会脱离文档流,影响布局
  3. 给父级设置overflow:hidden,缺点:文本过长,且包含英文时,会出现英文文本被隐藏
  4. 给父级设置对应的高度,缺点:浮动元素定高还好,如果不定高的情况就不灵活了
  5. 末尾增加空的div,设置clear:both,缺点:增加了一个div标签
  6. 给父级添加伪元素进行clear, ::after,伪元素不会被当作dom标签渲染出来(目前最优解)

» 什么是BFC?BFC布局规则是什么?如何创建BFC?

BFC是块级格式化上下文,是CSS布局的一个概念,是一个环境,里边的元素布局不会影响到外面的元素布局

布局规则(原理):

A.内部的box会在垂直方向,一个接一个的放置

B.box垂直方向的距离由margin决定,属于同一个BFC的两个box 的margin会发生重叠

C.BFC的区域不会与float元素box重叠

D.BFC是一个独立的容器,里边的子元素不会影响外边的元素

E.计算BFC高度的时候,浮动元素也会参与计算

哪些元素会生成BFC?

  • 根元素
  •  float属性为left 和 right
  • position为absolute和fixed
  • overflow不为 visible,为auto、scroll、hidden
  • display为inline-block, table-cell, flex, inline-flex

» cookies、localStorage、sessionStorage的区别?

  • 数据生命周期: 
    • cookie:可以设置失效时间,默认浏览器关闭失效
    • local:本地持久化存储,除非手动删除否则永久保存
    • session:仅在当前页有效,浏览器关闭或者页面关闭就会被清除
  • 存放数据大小:
    • cookie:数据不能超过4k,主要用于保存登录信息,比如登录某个网站看到“记住密码”,通过往cookie存入一段辨识用户的数据来实现的
    • local、session:虽然也有存储大小限制,但比cookie大很多,一般在5M或更大
  • http请求
    • cookie每次请求都会携带http头中,如果使用cookie保存过多数据会带来性能问题;
    • local、session在浏览器中保存,不参与和服务器的通信
  • 作用域不同
    • sessionStorage:不在不同的浏览器窗口中共享,即使在同一个页面
    • localStorage和cookie:在所有同源窗口中都是共享的;只要浏览器不关闭,数据仍然在

  从安全性来说,因为每次http请求都会携带cookie,这样浪费了带宽,所以cookie尽可能少用,此外cookie需要指定作用域,不能跨域调用,限制很多;local和session可以用来在页面传递参数,session可以保存一些临时的数据,防止用户刷新页面丢失一些参数

「JS」

» 什么是闭包?

通俗一点就是打通了一条函数外部访问函数内部作用域的通道,正常情况下函数外部是访问不到函数内部作用域变量的

如何判断闭包: 函数嵌套函数、内部函数被return、内部函数调用外层函数的局部变量

优点: 隔离作用域,不造成全局污染

缺点: 导致函数变量一直保留在内存中,过多的闭包会导致内存泄露(任何对象不需要它后仍然还在)

闭包的主要作用: 延伸变量的作用范围

适用场景: 封装组件、for循环和定时器结合、节流和防抖也会用到

vue中出现内存泄露的情况: 

  1. 全局变量引起的内存泄露
  2. 监听事件没有解绑,在页面销毁的时候,顺便解绑,释放内存,原则不用的东西及时归还
  3. echarts页面切换的时候,还保留在内存中,导致浏览器卡顿

» 作用域、作用域链、变量提升、函数提升分别是什么?

作用域: js识别变量的范围,包括全局作用域(任何地方都可访问的变量)、局部作用域(只在函数内部定义的变量范围)、块级作用域(ES6用const、let定义的变量都认为是块级作用域中的变量)

作用域链: 从当前作用域开始一层一层向上寻找某一个变量,直到找到全局作用域还是没找到,就放弃!这查找的过程,就是作用域链

变量提升: 使用var关键字定义的变量,只提变量,不提赋值

函数提升: 使用function声明的函数,只提函数,不调用函数

» JS有哪些数据类型?typeof、instanceof、类型转换

js属于弱类型语言(支持隐式转换)

数据类型: String、Number、Boolean、Null、undefined、Object(function,array--堆内存)、symbol(ES10BigInt--栈内存)

typeof: 基本数据类型除了null返回Object,其他都返回对应的类型; 引用数据类型除了函数其他都返回Object

instanceof: 判断该对象是谁的实例

null表示空对象,undefined表示已在作用域中声明但未赋值的变量

» 原型和原型链

原型: js中万物皆对象,每一个对象都有自己的属性,js中如何让多个对象共用一个或多个方法呢?原型的出现就是为了解决这个问题,每一个对象都有一个与他关联的原型对象,每次获取对象属性都是一次查找过程,在对象的自有属性中找不到就会去查找它的原型对象

原型链: 原型连成一条链,当我们访问一个对象的属性时,如果这个对象内部没有这个属性,我们就会去它的原型对象中查找这个属性,这个原型对象又会有自己的原型,于是这样一直向上查找,直到找到Object为null的时候,这个查找的过程就是原型链

总结: 

  1. 原型存在的意义就是组成原型链
  2. 原型链存在的意义就是继承:访问对象属性时,在对象本身找不到,就会按原型链一层一层找,说白了就是一个对象可以访问其他对象的属性
  3. 继承存在的意义就是属性共享:好处:1.代码重用2.可扩展,不同对象可以继承相同的属性,也可以定义只属于自己的属性

» 继承(含ES6)、多种继承方式

  • 原型链继承 – 重写prototype
  • 构造函数继承 – Parent.call(this)
  • 组合继承 – 重写prototype + Parent.call(this)
  • 原型式继承 – Object.create(Parent),不添加额外的属性和方法
  • 寄生式继承 – Object.create(Parent),添加额外的属性和方法
  • 寄生组合式继承 – Object.create(Parent) + Parent.call(this)
  • ES6类的继承 – extends + super(props)
  • 原型链继承口述:写个父类、子类,子类的原型为父类的实例,子类.prototype = new 父类,修正子类原型为子类本身, 子类.prototype.constructor = 子类, new 子类即可调用父类方法,构造函数继承,写个父类、子类,在子类中父类.call(this)即可实现

» this指向、new关键字

  • 构造器函数调用:this指向new创建的新对象
  • 箭头函数不绑定this: 捕获在上下文的this,在哪里定义指向谁
  • 全局函数中,this指向的是window
  • 普通函数this,谁调用指向谁

     new操作符干了什么?

  1. 内存中创建一个新对象
  2. this指向这个新对象
  3. 执行构造函数里边代码添加属性
  4. 返回新对象(所以构造函数里不用return)

» bind、call、apply的区别?

  • 都可以改变函数内部this指向
  • call、apply可以调用函数,bind不会调用函数
  • call和apply传递的参数不一样,call传递参数列表,apply传递的是数组形式

» JS 的设计模式?

  1. JS的设计模式有很多,我知道的有单例模式、工厂模式、观察者模式
  2. 单例模式:保证一个类只有一个实例,比如:window对象、document对象、vuex的store
  3. 工厂模式:将逻辑封装在一个函数中,根据不同的输入返回不同的实例,用来创建同一类对象
  4. 观察者模式:定义了对象间一种一对多的依赖关系,当目标对象的状态发生改变的时候,所有依赖它的对象都会得到通知

» 深拷贝和浅拷贝

浅拷贝: 只拷贝最外层对象,更深层次的对象只拷贝引用地址,而且改变一个对象属性值,另一个对象属性也会发生改变,即互相影响; 用ES6的 Object.assign({}, {})浅拷贝进行对象合并,ES6扩展运算符

深拷贝: 拷贝最里层的数据,利用递归函数;即改变一个对象属性,另一个对象属性值不会发生改变,可以通过JSON.parse(JSON.stringify(对象))的方式实现深拷贝,缺点 不可拷贝 undefined、function、RegExp类型的数据

» TS 和 JS 有什么区别,优点和缺点

TS是JS的超集,可以在ts中使用原生的 js 语法; JS是一种脚本语言,用于创建动态网页

TS是强类型语言,支持静态和动态类型; JS是动态弱类型语言

TS可以在编译期间发现错误; JS只能在运行时发现错误

TS不允许改变变量的数据类型; JS变量可以被赋予不同类型的值

TS优点:

1. 提供了静态类型检查,可以在编译时捕获一些常见的错误

2.包含了更多类型信息和注释,便于阅读和理解

3.提供更好的代码提示和自动补全功能,可以提高开发效率

JS的优点:

1. 直接在浏览器中运行,不需要编译成其他语言

2.具有广泛的应用和强大的生态系统,有大量的库和工具

3.可以快速迭代开发,适合小型项目

» 什么是事件冒泡、事件捕获、事件委托机制?

事件冒泡:子元素事件的触发会影响到父元素事件;从内而外,关闭事件冒泡: e.stopPropagation()

事件捕获:父元素的事件会影响到子元素的事件;从外而内,阻止默认行为:e.preventDefault()

事件委托:某个事件本来是自己干,但自己不做交给别人来干,利用冒泡处理子元素的事件

提高性能: 如当有很多li同时需要注册事件时,如果使用传统方法来注册事件的话,就需要给每一个li注册事件,但如果使用事件委托,只需要将事件委托给父元素即可

» 普通事件和事件绑定有什么区别?

普通事件的onclick只支持单个事件,而且会被其他onclick事件覆盖;且不可以取消

事件绑定addEventListener可以添加多个事件,也不会被覆盖,绑定后可用removeEventListener取消

» EventLoop(线程机制)

js一大特点就是单线程,也就是说,同一个时间只能做一件事

单线程就意味着,所有任务都需要排队,前一个任务结束,后一个任务才会执行,如果前一个任务耗时很长,后一个任务不得不等着; 于是所有任务分为两种同步任务和异步任务,异步队列又分为宏任务和微任务队列,宏任务执行时间长,所以微任务优先于宏任务; 

微任务: .then、async、await、.catch、.finally

宏任务: setImmediate、setTimeout、setInterval、ajax请求、读取文件、DOM事件

执行顺序: 同步——promise、process.nextTick——微任务——宏任务

同步任务: 代码一行行执行,前面代码没有执行完.后面代码就不会执行,代码阻塞

如: 烧水做饭,必须等水开10分钟之后,再去切菜、炒菜(强调执行的顺序)

异步任务: 当前代码没有执行完,可以执行后面代码

如:烧水的同时,利用10分钟切菜、炒菜(不按顺序执行,解决代码阻塞,提升代码执行效率和性能)

» 防抖和节流

防抖(debounce): 一定时间连续触发,只在最后执行一次,比如:搜索事件,用户在不断的输入值时,用防抖来节约请求资源,只有最后一次回车才能返回结果; 用户按钮的点击事件,为了防止多次重复提交也会使用防抖,减少请求次数,节约请求资源,不消耗性能

如: 坐公交,司机需要等最后一个人上车才能关门,每上一个人,司机就会多等待几秒在关门

节流(throttle): 一段时间内只执行一次; 如:页面滚动事件,是否滑到底部自动加载更多;csdn写文章,边写边保存

如: 一个水龙头在滴水,可能一次会滴很多,但我们希望500ms滴一滴,保持这个频率;希望函数在一个可以接受的频率重复调用

防抖(简单版本):
function debounce(fn, delay) {
    let timer = null
    clearTimeout(timer); 清除上次定时器,然后重新延迟
    timer = setTimeout(function () {
        fn()
    }, delay) 
}

» 函数柯里化

将多个参数的函数改为一个参数的函数




  
  
  函数柯里化-经典面试题


  


  // 通过typeofTest生成: 
  // 动态传入判断的类型
    const typeofTest = function (type) {
      function isUndefined(thing) {
        return typeof thing === type
      }
      return isUndefined
    }
    // 简化版:
    const typeofTest1 = type => thing => typeof thing === type

    const isString = typeofTest('string')
    console.log(isString('1111'))

「ES6」

新增symbol类型 表示独一无二的值,用来定义独一无二的对象属性名;
const/let 都是用来声明变量,不可重复声明,具有块级作用域。存在暂时性死区,也就是不存在变量提升。(const一般用于声明常量);
变量的解构赋值(包含数组、对象、字符串、数字及布尔值,函数参数),剩余运算符(...rest);
模板字符串(${data});
扩展运算符(数组、对象);;
箭头函数;
Set和Map数据结构;
Proxy/Reflect;
Promise;
async函数;
Class;
Module语法(import/export),解决命名冲突,提高复用性,提高代码可维护性

» var 、 const、 let 的区别?

  • var声明的变量可以重复声明,let和const重复声明会报错
  • var声明的变量不赋值是undefined,let和const声明变量不赋值报错
  • var定义的变量没有块级作用域的概念,全局变量,let和const有块级作用域,局部变量
  • const定义的常量不能修改值,引用类型可以修改; 
  • var 声明的变量会成为 window对象的属性,let 和 const不会
  • let和const存在暂时性死区,如果在声明变量之前使用该变量就会报错;
  • 定义对象、函数、用const; 计算的一些变量用let

» Promise的理解

  • promise是ES6提出的异步编程解决方案,可以避免层层嵌套的回调函数(回调地狱)。ES6规定promise是一个构造函数,需要通过new关键字来生成一个promise实例对象
  • promise对象有三种状态, pending(等待)、fulfilled(成功)、rejected(失败),一个Promise对象初始化的状态是pending,调用 resolve 后将Promise 的状态扭转为 fulfilled, 调用 reject 后将Promise状态扭转为 rejected, 这两种扭转一旦发生就不能改变到其他状态!!
  • promise 通过then获取异步数据的,resolve将异步数据传出来
  • async 返回的是promise对象,await直接获取resolve传递出来的异步数据
async function fun1() {
          let data = await fun2()
          console.log(data) //then中执行的代码
      }
      async function fun2() {
          console.log(200) // 同步
          return 100
      }
      fun1()     // 200 100
      
   // 1、3、5、8、2、6、7、4
        console.log(1)
        async function async1() {
            await async2()
            console.log(2)
        }
        async function async2() {
            console.log(3)
        }
        async1()
        setTimeout(() => console.log(4),0)
        new Promise(resolve => {
            console.log(5)
            resolve()
        }).then(function() {
            console.log(6)
        }).then(function() {
            console.log(7)
        })
        console.log(8)

» Promise.all 和 Promise.race

promise.all可以将多个promise实例包装成一个新的promise实例。同时,成功和失败的返回值是不同的,成功的时候返回一个数组,失败的时候返回最先被reject失败状态的值。

promise.race 就是赛跑的意思,哪个结果获取的最快,就返回哪个结果,不管结果本身是成功还是失败状态

  • Promise.all 可以比作接力跑,必须都成功才能胜利
  • Promise.race可以比作短跑,谁跑的快谁就胜利

» 箭头函数和普通函数的区别?

     定义参数:如果只有一个参数可以不写括号,函数体只有返回值可以不写return

      this指向不同: 普通函数this谁调用指向谁,箭头函数this在哪里定义,this就指向谁      

» map 和 forEach 的区别?

共同点: 都是用来做循环的; 每次循环都支持三个参数,当前项、索引、原数组; 函数this都指向window

不同点: 1.forEach没有返回值; 2. map有返回值可以return,返回一个新数组

「Ajax API模块」

» ajax同源策略的理解,如何解决跨域?

同源策略是浏览器的一种安全机制,防止他人恶意攻击网站,如果协议、域名、端口号有一个不同就会产生跨域(及域名和ip地址访问);跨域请求产生时,请求是发出去了,也是有响应的,仅仅是浏览器同源策略,认为不安全拦截了结果,不将数据传递给前端使用

img、link、script标签允许跨域加载

如何解决跨域:

  1. jsonp(利用script标签没有跨域限制的漏洞实现,缺点:只支持get请求)
  2. CORS跨域资源共享(设置Access-Control-Allow-Origin:指定可访问资源的域名)
  3. 代理(前端代理和nginx后端反向代理)config文件中配置proxy
  4. postMessage:h5新增API用于多窗口消息,页面嵌套iframe消息传递,通过onmessage监听传递的数据
  5. websocket:H5的持久化协议,实现了浏览器与服务器的全双工通信
  6. 各种嵌套iframe的方式,不常用

» HTTP状态码有哪些?

  • 1xx——临时响应,请求已经发送,继续处理
  • 2xx——请求成功
  • 3xx——重定向,完成请求必须进行更进一步的操作
  • 4xx——客户端错误,请求的语法错误或请求无法实现
  • 5xx——服务器错误,服务器处理请求时内部发生错误

» get 和 post 的区别?

  1. get参数通过url传递,post放在Request body中
  2. get参数暴露在url上不安全,不能用来传递敏感信息
  3. get请求在url中传递的参数是有长度限制的(基本上是2KB),post没有
  4. get请求在浏览器回退不会再次请求,post会再次提交请求
  5. get请求会被浏览器主动缓存,post不会除非手动设置
  6. get请求参数会被完整保留在浏览器历史记录里,post参数不会
  7. get一般用于查询信息,post一般用于提交某种信息进行修改操作

» HTTP 和 HTTPS 的区别?

  1. http是不安全的,https是安全的
  2. http标准端口是80,而https标准端口是443
  3. 在 OSI 网络模型中,http工作于应用层, 而https 的安全传输机制工作在传输层
  4. http 无法加密, 而 https 对传输的数据进行加密
  5. http 无需证书, 而 https需要CA机构WoSign的颁发的SSL证书

» 浏览器从输入url到渲染页面,发生了什么?

三个方面:
网络篇:
        构建请求
            查找强缓存
            DNS解析
            建立TCP连接(三次握手)
            发送HTTp请求(网络请求后网络响应)
浏览器解析篇:
         解析html构建DOM树
            解析css构建CSS树,样式计算
            生成布局树(Layout Tree)
浏览器渲染篇:
        建立图层树(Layer Tree)
        生成绘制列表
        生成图块并栅格化
        显示器显示内容
        最后断开连接:TCP 四次挥手
        (浏览器会将各层的信息发送给GPU,GPU会将各层合成,显示在屏幕上)

» 输入url 后 http请求的完整过程是什么?

建立TCP连接——发送请求行——发送请求头——(到达服务器)发送状态行——发送响应头——发送响应数据——断开TCP连接

「Vue2和Vue3」

» vue2 和 vue3的区别?

  1. 响应式原理:vue2响应式原理是Object.defineProperty(), vue3响应式原理基础是proxy
  2. 生命周期钩子名称: vue3前面加了 on
  3. Composition API(组合式API): vue2是选项API,一个代码逻辑拆分在不同的位置,导致可读性很差, vue3组合式API,逻辑复用,增强代码可读性
  4. 对于TS的支持: vue3更好的拥抱TS
  5. 根节点: vue2支持一个根节点, vue3支持多个根节点
  6. 新的内置组件
  7. diff算法

» vue2相比vue3有什么缺点?

  • 性能问题: vue2采用的是双向数据绑定和脏检查的方式,对于大型应用或复杂组件来说,性能可能会受影响
  • 大量代码: vue2需要引入大量的代码来支持其功能,使得包体积很大
  • 逻辑复用: vue2对逻辑复用支持不是很友好
  • ts支持不佳: vue2对于ts支持比较弱

» vue3有哪些新特性吗?它们带来什么影响

  • 性能提升 更小巧、更快速 支持自定义渲染器 支持摇树优化:一种在打包时去除无用代码的优化手段 支持Fragments和跨组件渲染
  • API变动 模板语法99%保持不变 原生支持基于class的组件,并且无需借助任何编译及各种stage阶段的特性 在设计时也考虑TypeScript的类型推断特性 重写虚拟DOM可以期待更多的编译时提示来减少运行时的开销 优化插槽生成可以单独渲染父组件和子组件 静态树提升降低渲染成本 基于Proxy的观察者机制节省内存开销
  • 不兼容IE11 检测机制更加全面、精准、高效,更具可调试式的响应跟踪

» vue2 数据双向绑定原理

核心主要通过数据劫持结合发布者-订阅者模式来实现的。

通过Object.defineproperty()来劫持各个属性的getter和setter,在数据变动的时候发布给订阅者,触发相应的监听回调渲染视图,缺点就是没办法监听到数组的变化, vue3的proxy可以直接监听对象和数组的变化,并且有多达13种拦截方法

» v-model的实现以及实现原理?

本质上就是一个语法糖,可以看成是value+input方法的语法糖。可以通过model属性的prop和event属性来进行自定义。原生的model会根据标签的不同生成不同的事件和属性。

  • text和textarea元素使用value属性和input事件
  • checkbox和radio元素使用checked属性和change事件
  • select字段将value作为prop将change作为事件

» MVVM开发模式的理解?

MVVM是Model-View-ViewModel的缩写,Model代表数据模型,View代表ui组件,ViewModel代表桥梁,当数据发生变化的时候,视图也发生变化,当视图发生变化的时候,数据也会跟着同步变化

» vue组件通信有哪几种方式?

  • 父传子: 子props接收,通过ref属性给子组件设置一个名字,父通过$refs组件名来获取子组件,子通过$parent来获取父
  • 子传父: $emit $on
  • 兄弟组件: EventBus事件总线,vue3移除了$on/$off等方法,不在使用eventBus,用mitt.js替换(用于任意组件通信)
  • 跨级组件通信: $attr / $listeners , Provide / inject
    如果业务逻辑复杂,很多组件之间需要处理共同的数据,这个时候采用上面的方法不利于项目维护,可以使用vuex数据状态管理仓库,将共同的数据抽离出来,作为一个全局的变量来管理,然后各个组件就可以对这个公共的数据进行读写操作,这样达到了解藕的目的

» 的作用是什么?或者vue切换页面如何保存状态?

内置组件,一般结合路由和动态组件,实现组件缓存,一般用在用户频繁点击的地方

keep-alive提供include、exclude属性,两者都支持正则表达式和字符串

include: 只要匹配的组件就会被缓存

exclude: 任何匹配的组件都不会被缓存,优先级高

keep-alive对应两个钩子函数: activated 组件渲染后调用; deactivated组件销毁后调用

例如: 有一个列表页和详情页,用户一直来回高频率切换两个页面,一直在进行挂载销毁挂载销毁,消耗资源,可以使用keep-alive进行缓存,这样来回切换的时候直接从缓存里渲染,而不是重新渲染

» vuex有哪几种属性?

  • state: 默认的初始状态
  • getters: 有点类似vue.js中计算属性
  • mutations: 唯一更改state状态的方法,且必须是同步函数
  • actions: 提交mutations,通过store.commit(),而不是直接更改状态,包含任何异步操作,store.dispatch()
  • modules: 当state很复杂臃肿的时候,可以分模块,每个模块拥有自己的state,mutations,actions

实现流程:

  1. 在vue组件里面,通过dispatch来触发actions提交修改数据的操作。
  2. 然后再通过actions的commit来触发mutations来修改数据。
  3. mutations接收到commit的请求,就会自动通过Mutate来修改state(数据中心里面的数据状态)里面的数据。
  4. 最后由store触发每一个调用它的组件的更新

» vue-router路由实现原理是什么?有什么不同

路由本质上就是建立URL和页面之间的映射关系,路由实现原理的核心之一就是“更新视图但不重新请求页面”,目前实现路由主要两种方式:1.url中的hash  2.H5中的history

不同点: 

  1. hash路由地址上有#, history没有
  2. 回车刷新的时候hash会加载对应的页面,history会报错404,需要后台的配置
  3. history有历史记录,h5新增了pushState和replaceState修改历史记录,并不会立刻发送请求
  4. hash兼容性好,history针对高级浏览器
  5. hash不会重新加载页面,单页面应用必备

» $route 和 $router的区别?

$router: 为路由实例,是全局路由对象,包含路由跳转方法,钩子函数等,$router.push() $router.go(1)

$route: 路由信息对象|| 跳转的路由对象,包括:name,params,path,query,hash,fullPath,matched参数

» vue中key 的作用是什么?

key的作用主要是为了高效的更新虚拟DOM

好比给你起名字,如果没有名字,渲染列表是不是从0-100得重新渲染,如果你有名字的情况下,刚好你名字对应的数据变动了,然后根据名字直接找到这个值修改就好,就不需要重新渲染了

» 虚拟DOM和真实DOM的区别?

  • 虚拟dom 不会进行排版和重绘操作
  • 虚拟dom 就是把真实dom 转换为 js代码
  • 虚拟dom 进行频繁修改,然后一次性比较并修改真实dom 中需要改的部分,最后并在真实DOM中进行排版与重绘,减少过多dom节点排版与重绘损耗

» computed 、watch 、methods的区别?

  实际得到的数据不能直接在页面中展示,需要做一些处理,就使用computed

  • watch应用场景
    • 一个数据影响多个数据
    • 支持异步
    • 不支持缓存,数据改变会直接触发相应的操作
  • computed适用场景:
    • 一个数据被多个数据影响,上来就执行
    • 不支持异步
    • 有缓存,只有依赖的数据发生变化,才会重新进行计算
    • 和data里边属性名不能相同
  • methods:
    • 上来就执行一次,只要页面重新渲染就会执行
    • 必须有一定触发条件(点击事件)
    • 不需要缓存可以使用methods

» 组件中的data为什么是一个函数?

一个组件被复用多次的话,也会创建多个实例,本质上,这些实例用的是同一个构造函数,如果data是对象的话,对象是引用类型,会影响到所有的实例,为了保证组件不同的实例之间data不冲突,data必须是一个函数,data是闭包,函数被return,对象在栈中存的都是地址,函数的作用就是属性私有化,保证组件修改自身不会影响到其他复用组件

» v-if 和 v-show的区别?

v-if 直接创建和销毁DOM让元素显示和隐藏

v-show 通过css属性 display:none来控制显示和隐藏

如果频繁切换,使用v-show; 反之v-if, v-if消耗性能

» vue数据变化视图不更新如何解决?

在created中操作DOM报错,在这个时候vue实例没有挂载,获取不到DOM,可以使用this.$nextTick(()=>{})回调函数获取DOM

» 父子组件生命周期渲染顺序?

加载渲染过程: 父beforeCreate、父created、父beforeMount、子beforeCreate、子created、子beforeMount、子mounted、父mounted

子组件更新过程: 父beforeUpdate、子beforeUpdate、子updated、父updated

父组件销毁过程:父beforeDestory、子beforeDestory、子destoryed、父destoryed

常用的生命周期: created获取数据, mounted操作Dom, beforeDestory销毁实例防止内存泄露

「前端性能优化」

» 前端性能优化的几种方式

1. 浏览器缓存
2. 防抖、节流
3. 资源懒加载、预加载
4.开启Nginx gzip压缩
三个方面来说明前端性能优化
一: webapck优化与开启gzip压缩
    1.babel-loader用 include 或 exclude 来帮我们避免不必要的转译,不转译node_moudules中的js文件
    其次在缓存当前转译的js文件,设置loader: 'babel-loader?cacheDirectory=true'
    2.文件采用按需加载等等
    3.具体的做法非常简单,只需要你在你的 request headers 中加上这么一句:
    accept-encoding:gzip
    4.图片优化,采用svg图片或者字体图标
    5.浏览器缓存机制,它又分为强缓存和协商缓存
二:本地存储——从 Cookie 到 Web Storage、IndexedDB
    说明一下SessionStorage和localStorage还有cookie的区别和优缺点
三:代码优化
    1.事件代理
    2.事件的节流和防抖
    3.页面的回流和重绘
    4.EventLoop事件循环机制
    5.代码优化等等

» Vue首屏渲染优化有哪些?

  • 图片压缩/懒加载
  • 禁止生成 .map 文件
  • 路由懒加载
  • cdn 引入公共库
  • 开启 GZIP 压缩
  • 渲染优化,尽量减少重绘和重排

» CDN加速静态资源是什么?

首先呢您肯定在京东自营买过东西,在京东买东西基本隔天就能到货,这是为什么呢?

细心的话就会发现京东发货地址离我们很近,那是因为京东将商品放在八大仓库里,我们从京东买东西会从就近的仓库发货,这样就省去了物流时间,基本第二天就能送到,速度很快

那当我们访问网络时,我在北京访问一个网络,站点服务器在上海,这个时候访问速度是不是会变慢,那怎么才能向京东买东西一样快速到货,就用到了CDN

CDN就是你的网站缓存,而CDN节点相当于京东八大仓库,把网站内容存到了CDN节点,然后每个请求网站的用户就近获取网站数据,大大减短了长距离传输和网络拥堵的情况下的访问速度

「前端工程化」

» express 和 koa 有什么区别?

1. 语法区别

  • express 异步使用回调
  • koa1 异步使用generator + yeild
  • koa2 异步使用 async / await

2. 中间件区别

  • express 本身无洋葱模型,需要引入插件,不支持 context
  • koa 采用洋葱模型,进行顺序执行,出去反向执行,支持 context 传递数据

3. 集成度区别

  • express 内置了很多中间件,集成度高,使用省心
  • koa 轻量简洁,容易定制

» webpack配置

module.exports={
    entry: {},
    output: {},
    plugins:[],
    module: [ rules: [{}] ]
}

» 前端为什么要进行打包和构建?

代码层面: 

  • 体积更小(Tree-shaking、压缩、合并),加载更快
  • 编译高级语言和语法(TS、ES6、模块化、scss)
  • 兼容性和错误检查(polifill、postcss、eslint)

研发流程方面:

  • 统一、高效的开发环境
  • 统一的构建流程和产出标准
  • 集成公司构建规范(提测、上线)

» webpack的基本功能有哪些?

  1. 代码转换:TS编译成JS、SCSS编译成css
  2. 文件优化:压缩js、css、html代码,压缩合并图片等
  3. 代码分割:提取多个页面公共代码,提取首屏不需要执行部分代码让其异步加载
  4. 模块合并:在采用模块化的项目有很多模块和文件,需要构建功能把模块分类合并成一个文件
  5. 自动刷新:监听本地代码的变化,自动构建,刷新浏览器
  6. 代码校验:提到仓库前检验代码是否规范,以及单元测试是否通过
  7. 自动发布:更新完代码之后自动构建出线上发布代码

» 常见的Webpack Loader?解决什么问题

  • file-loader: 把文件输出到一个文件中,在代码中通过相对url引用输出的文件
  • url-loader: 在文件很小的情况下以base64的方式把文件内容注入到代码中
  • source-map-loader: 方便断点调试
  • image-loader: 加载并压缩图片
  • babel-loader: 把ES6/ES7转换为ES5
  • scc-loader: 加载css,支持模块化、压缩、文件导入等
  • style-loader: 把css注入到js中,通过DOM操作加载CSS
  • eslint-loader: 通过Eslint检查代码

» Loader 和 Plugin 的不同?

不同的作用:

  • Loader: 直译加载器,webpack原生只能解析js文件,如果想将其他文件一起打包,就要用到loader,所以loader的作用就是让webpack拥有加载和解析非js文件的能力
  • Plugin: 直译插件,拓展webpack的功能,让webpack更具灵活性

不同的用法:

  • Loader 在module.rules中配置的,也就是他作为模块的解析而存在。类型为数组,每一项都是一个Object,里边描述对于什么类型的文件使用加载什么loader
  • Plugin 在plugins中单独配置。类型为数组,每一项是一个plugin实例,参数都通过构造函数传入

» 有哪些常见的 Plugin插件?解决什么问题的?

  • html-webpack-plugin:简化 HTML 文件创建 (依赖于 html-loader)
  • uglifyjs-webpack-plugin:压缩js文件
  • clean-webpack-plugin:目录清除
  • commons-chunk-plugin:提取公共代码
  • define-plugin:定义环境变量

» Vite 和 Webpack区别?

  1. 构建原理: webpack是一个静态模块打包器,通过对项目的js、css、图片等文件进行分析,生成对应的静态资源,并且可以通过一些插件和加载器来实现各种功能; Vite则是基于浏览器原生ES模块解析的构建工具
  2. 打包速度: Vite打包速度非常快,webpack相对慢些
  3. 配置难度: webpack配置难度复杂,因为需要通过各种插件和加载器实现各种功能; Vite配置简单,可以根据不同的开发场景自动配置相应的环境变量和配置选项
  4. 插件和加载器: webpack有大量的插件和加载器可以使用,可以实现各种复杂的构建场景,例如:代码分割、按需加载、css预处理器; Vite的插件和加载器相对较少
  5. Vite是按需加载: webpack是全部加载,在热更新方面,当改动一个模块后,Vite需要浏览器重新请求该模块即可; webpack需要把该模块相关的依赖全部编译一次, vite效率更高
  6. webpack是先打包再启动开发服务器:Vite是直接启动开发服务器,然后按需加载依赖文件,由于Vite在启动的时候不需要打包文件,也就意味着不用像webpack那样分析模块的依赖、不需要编译,因此速度非常快。这种按需动态编译的方式,极大缩减了编译时间。

» 为什么Vite 比 webpack速度快?

  1. webpack会先打包,然后启动开发服务器,请求服务器时给予打包结果; Vite是直接启动服务器,实时编译
  2. Vite在启动时不需要打包,不需要分析模块的依赖,不需要编译,所以速度非常快
  3. Vite是在请求哪个模块在对哪个模块进行按需加载,极大缩减了编译时间
  4. 在热更新(HMR)方面,当改动一个模块,仅需浏览器重新请求该模块即可,webpack需要把相关依赖重新加载编译一次
  5. 当需要打包到生产环境时,Vite使用rollup进行打包,因此,Vite 的主要优势在开发阶段, Vite利用的是ES module,因此在代码中不可以使用CommonJS

「职业技能规划、人事面试」

» 你的职业规划是什么?

一专多精

» 为什么从上一家公司离职?

我一般回答主要两个原因: 1、想学更多的东西 2、老生常谈当然薪资呗

» 前端是如何学习的?

面试官问怎么学习前端,这种问题一般考察: 学习能力

一开始学习前端,主要靠视频和书籍,主要是总结很多知识点,但发现学习过程中理论大于实操,所以自己把知识点总结后开始找项目实操,这样一步步成长起来的,平时在工作中也会碰到很多问题,一般都是自己查找原因并和同事一起来交流,然后自己会总结一些学习文档,方便日后查看和积攒经验,所以我感觉我的学习都是实操加总结

» 项目中有遇到什么难题?

可以说由于之前的业务相对常规,没有遇到太大的困难,但是也比较期待在今后的工作中遇到一些难题,因为这样才能让我成长; 也可以说些自己项目遇到了什么难题bug

» 还有什么想问的?

一般问技术团队的规模

  • 技术团队有几个人
  • 几个前端、几个后端
  • 高级、中级、初级分别有多少人

然后就是技术栈

  • 目前使用什么技术栈
  • 将来打算使用什么技术栈
  • 自己是否可以决定未来技术栈的走向

然后是自己在团队中的角色

  • 负责什么工作
  • 对于项目的决策度

问清楚工资什么时候发,公积金的缴纳比例,有没有涨薪和晋升的机会,有没有普调,在几月调薪,能不能提前通过试用期.....

最后祝大家,都能找到满意的工作,升职加薪,一个个成为富婆!!

你可能感兴趣的:(Vue3,Vue2,javascript,面试,职场和发展,vue.js,前端)