2023前端常见面试题大全

1. 什么是作用域?

变量 产生作用的区域就叫做作用域

2. 作用域的分类

全局作用域

局部作用域

3.局部作用域的分类

函数作用域

块级作用域

4.作用域链

作用域链的本质是变量查找机制

5.作用域链查找规则是什么?

a. 会优先查找自己的作用域

b. 自己的作用域查找不到的话会往上查找父级直到全局作用域

6.什么是垃圾回收机制

JS 中一种自动回收或释放内存的机制 简称 GC

7.垃圾回收机制有几种算法?

引用计数法:IE采用的引用计数算法, 定义“内存不再使用”的标准很简单,就是看一个对象是否有指向它的引用

如果这个值的被引用了一次,那么就记录次数1 , 如果减少一个引用就减1。 如果引用次数是0 ,则释放内存。但它却存在一个致命的问题:嵌套引用

标记清除法:就是从根部(在JS中就是全局对象)出发定时扫描内存中的对象。 凡是能从根部到达的对象,都是还需要使用的。

无法由根部出发触及到的对象被标记为不再使用,稍后进 行回收

8.什么是闭包?

就是有权访问另一个函数作用域中变量的函数

9.闭包的表现形式?

在一个函数内部创建另外一个函数

10.闭包有什么作用?

封闭数据,实现数据私有,防止数据被意外修改

11.闭包的弊端

容易导致内存泄露

12.什么是变量提升?

使用 var 声明的变量,会被提升到函数或全局作用域的顶部,这个现象叫做变量提升。

13.用哪个关键词会产生变量提升?

var会存在变量提升,let/const 声明的变量不存在变量提升

14.什么是构造函数

是一种特殊的函数,主要用来初始化对象 ,同时可以用构造函数来快速创建多个类似的对象。

15.构造函数创建对象的过程

  1. 创建新对象
  2. 构造函数this指向新对象
  3. 执行构造函数代码,修改this,添加新的属性
  4. 返回新对象

16.伪数组转真数组的方法

1.Array.from

2.Array.prototype.slice.call( )

3…展开运算符

17.什么是JavaScript 中的包装类型

JavaScript 中,基本类型是没有属性和方法的,但是为了便于操作基本类型的值,在调用基本类型的属性或方法时 JavaScript 会在后台地将基本类型的值转换为对象,这些对象就是包装类型

18. JavaScript有哪些数据类型,它们的区别?

JavaScript共有八种数据类型,分别是 Undefined、Null、Boolean、Number、String、Object、Symbol、BigInt

其中 SymbolBigInt 是 ES6 中新增的数据类型

Symbol 代表创建后独一无二且不可变的数据类型,它主要是为了解决可能出现的全局变量冲突的问题。

BigInt 是一种数字类型的数据,它可以表示任意精度格式的整数,使用 BigInt 可以安全地存储和操作大整数,即使这个数已经超出了 Number 能够表示的安全整数范围。

这些数据可以分为原始数据类型和引用数据类型:

栈:原始数据类型(Undefined、Null、Boolean、Number、String、Symbol 、BigInt

堆:引用数据类型(对象、数组和函数)

19.isNaN 和 Number.isNaN 函数的区别

重点在于判断 是不是NaN,而不是 数字

  1. 函数 isNaN 接收参数后,会尝试将这个参数转换为数值,任何不能被转换为数值的的值都会返回 true,因此非数字值传入也会返回 true ,会影响 NaN 的判断。
  2. 函数 Number.isNaN 只会判断 传入的数据 是不是 一个 NaN,并且不会帮你做类型转换。

20.对原型、原型链的理解

原型,也叫原型对象,构造函数的一个属性,名字是 prototype,它本身也是一个对象类型。在构造函数的原型所添加的成员可以被实例所共享。

原型链,指的基于原型继承的那些对象中,它们是通过 原型 prototype 将彼此联系在一起的,这个关系就叫做原型链。

21.原型链-查找规则

① 当访问一个对象的属性(包括方法)时,首先查找这个对象自身有没有该属性。
② 如果没有就查找它的原型(也就是 proto 指向的 prototype 原型对象)
③ 如果还没有就查找原型对象的原型(Object的原型对象)
④ 依此类推一直找到 Object 为止(null)
proto 对象原型的意义就在于为对象成员查找机制提供一个方向,或者说一条路线

22.什么是递归

函数内部自己调用自己, 这个函数就是递归函数,往往都需要添加终止递归的条件。

23.什么是深拷贝 什么是浅拷贝

  1. 浅拷贝只是针对引用类型数据中的属性做了一层复制,如果被拷贝的属性也是引用类型,那么这个属性只是复制了这个引用地址。

    做了浅拷贝的对象之间可能会相互影响

  2. 深拷贝是针对引用类型数据中的属性做无限层级的复制,不管属性是值类型还是引用类型,会完整复制一份。 其在堆内存中完全开辟了一块内存地址,并将原有的对象完全复制过来存放

    做了深拷贝的两个对象之间相互不会影响

  3. 除了 递归克隆对象、JSON.stringify 两种方式做的拷贝,其他方法全部都是浅拷贝

24.call、apply、bind的区别

  1. 他们三都可以修改 this 指向,
  2. call、apply 在修改 this 指向的同时也会调用原函数、bind 只会返回修改 this 指向后的函数
  3. callapply 接收参数的方式不一样,call 类似普通函数一样接收参数、apply 接收的参数必须都放在一个数组内。

25.什么是防抖和节流

  1. 所谓节流,就是在连续触发的行为中控制它在 n 秒中只执行一次 可以用在 轮播图点击效果 、 鼠标移动、页面尺寸缩放 resize、滚动条滚动 等场景
  2. 所谓防抖,在单位时间内,某个动作只能执行一次,如果在单位时间内多次触发,那么只有最后一次有效,可以用在 搜索框 业务中

二、Ajax面试题

26.HTTP 状态码

成功(2XX)

状态码原因短语说明
200OK表示从客户端发来的请求在服务器端被正确处理
201Created请求已经被实现,⽽且有⼀个新的资源已经依据请求的需要⽽建⽴
通常是在POST请求,或是某些PUT请求之后创建了内容, 进行的返回的响应
202Accepted请求服务器已接受,但是尚未处理,不保证完成请求
适合异步任务或者说需要处理时间比较长的请求,避免HTTP连接一直占用
204No content表示请求成功,但响应报⽂不含实体的主体部分
206Partial Content进⾏的是范围请求, 表示服务器已经成功处理了部分 GET 请求
响应头中会包含获取的内容范围 (常用于分段下载)

重定向(3XX)

状态码原因短语说明
301Moved Permanently永久性重定向,表示资源已被分配了新的 URL
比如,我们访问 http😕/www.baidu.com 会跳转到 https😕/www.baidu.com
302Move Temporarily临时性重定向,表示资源临时被分配了新的 URL, 支持搜索引擎优化
首页, 个人中心, 遇到了需要登录才能操作的内容, 重定向 到 登录页
303See Other对于POST请求,它表示请求已经被处理,客户端可以接着使用GET方法去请求Location里的URI。
304Not Modified自从上次请求后,请求的网页内容未修改过。
服务器返回此响应时,不会返回网页内容。(协商缓存)
307Temporary Redirect对于POST请求,表示请求还没有被处理,客户端应该向Location里的URI重新发起POST请求。
不对请求做额外处理, 正常发送请求, 请求location中的url地址

客户端错误(4XX)

状态码原因短语说明
400Bad Request请求报⽂存在语法错误((传参格式不正确)
401UnAuthorized权限认证未通过(没有权限)
403Forbidden表示对请求资源的访问被服务器拒绝
404Not Found表示在服务器上没有找到请求的资源
408Request Timeout客户端请求超时
409Confict请求的资源可能引起冲突

服务端错误(5XX)

状态码原因短语说明
500Internal Sever Error表示服务器端在执⾏请求时发⽣了错误
501Not Implemented请求超出服务器能⼒范围,例如服务器不⽀持当前请求所需要的某个功能,
或者请求是服务器不⽀持的某个⽅法
503Service Unavailable表明服务器暂时处于超负载或正在停机维护,⽆法处理请求
505Http Version Not Supported服务器不⽀持,或者拒绝⽀持在请求中使⽤的 HTTP 版本

27. DOM - 事件流与事件委托

2.1 事件流

事件流:又称为事件传播,是页面中接收事件的顺序。DOM2级事件规定的事件流包括了3个阶段:

  • 事件捕获阶段(capture phase)
  • 处于⽬标阶段(target phase)
  • 事件冒泡阶段(bubbling phase)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TUiMxAC2-1678461708343)(assets/1676540896648.png)]

事件捕获(Event Capturing)

事件开始由较为不具体的节点接收后,然后开始逐级向下传播到最具体的元素上。

事件捕获的最大作用在于:事件在到达预定⽬标之前就可以捕获到它。

如果仍以上面那段 HTML 代码为例,当点击按钮后,在事件捕获的过程中,document 对象会首先接收到这个 click 事件,然后再沿着 DOM 树依次向下,直到 <button>。具体顺序如下:

  1. document 对象
  2. html 元素
  3. body 元素
  4. button 元素

事件冒泡(Event Bubbling)

事件开始由最具体的元素(⽂档中嵌套层次最深的那个节点)接收到后,开始逐级向上传播到较为不具体的节点。

<html>
  
  <head> 
    <title>Document</title> 
  </head>
  
  <body> 
    <button>按钮</button> 
  </body> 
  
</html>

如果点击了上面页面代码中的 <button> 按钮,那么该 click 点击事件会沿着 DOM 树向上逐级传播,在途经的每个节点上都会发生,具体顺序如下:

  1. button 元素
  2. body 元素
  3. html 元素
  4. document 对象
2.2 事件委托

事件委托: 利用了事件冒泡的机制,在较上层位置的元素上添加一个事件监听函数,来管理该元素及其所有子孙元素上的某一类的所有事件。

示例

<ul id="list">
    <li>111</li>
    <li>222</li>
    <li>333</li>
    <li>444</li>
    <li>555</li>
</ul>

<script type="text/javascript">
    // ⽗元素 
    var list = document.getElementById('list');

    // 为⽗元素绑定事件,委托管理它的所有⼦元素li的点击事件 
    list.onclick = function (event) {
        var currentTarget = event.target;
        if (currentTarget.tagName.toLowerCase() === 'li') {
            alert(currentTarget.innerText)
        }
    }
</script>

适用场景:在绑定大量事件的时候,可以选择事件委托

优点

  • 事件委托可以减少事件注册数量,节省内存占⽤!
  • 当新增⼦元素时,⽆需再次做事件绑定,因此非常适合动态添加元素 (vue解析模板时, 会对新创建的元素, 额外进行绑定的)

28. Post 请求中 Content-Type 有哪几种类型?分别有什么特点?

主要有以下三种:

  • application/x-www-form-urlencoded: 原生的 form 表单提交数据,数据会进行编码,较少使用
  • multipart/form-data:可以上传键值对,也可以上传文件
  • application/json:以 JSON 字符串的格式传递,效率较高,经常使用

问:如何设置这三种数据类型?

  • urlencoded:使用 encodeURIComponent()
  • formData: 使用 new FormData()
  • json: 使用 JSON.stringify()

29 . FormData 对象是什么?有哪些 API?

FormData 是一个以 key/value 形式存储数据的对象,可以实现表单数据的序列化,包括普通的字符串、文件等,主要通过 Ajax 发送表单数据,可以进行二进制的文件进行上传文件

  • new FormData():创建一个新的 FormData 对象,
    • 参数为空时,创建一个空的 FormData 对象
    • 参数为 form 元素时,创建一个包含表单元素各项值的 FormData 对象,详情见示例
  • FormData.append(key, val):向 FormData 中添加新的属性值,FormData 对应的属性值存在也不会覆盖原值,而是新增一个值,如果属性不存在则新增一项属性值
  • FormData.set(key, val):给 FormData 设置属性值,如果FormData 对应的属性值存在则覆盖原值,否则新增一项属性值
  • FormData.get(key):返回在 FormData 对象中与给定键关联的第一个值
  • FormData.delete(key):从 FormData 对象里面删除一个键值对
  • FormData.keys(): 返回一个包含所有键的 iterator 对象
  • FormData.values(): 返回一个包含所有值的 iterator 对象
  • FormData.entries(): 返回一个包含所有键值对的 iterator 对象

30 . promise 有哪些常用的方法?作用分别是什么?

当我们在构造 Promise 的时候,构造函数内部的代码是立即执行的:

  • Promise.prototype.then():为 Promise 实例添加状态改变时的回调函数
    • .then() 的第一个参数为成功时的回调
    • .then() 的第二个参数为失败时的回调
    • 返回值为一个新的 promise
  • Promise.prototype.catch():用于指定发生错误时的回调函数
    • 作用与 .then(undefined, fn) 一样
    • 返回值为一个新的 promise
  • Promise.all(): 获取所有的成功结果,或最先失败的结果
    • 接收一个数组作为参数,如果数组项不是 promise 对象,则转换为 promise 对象
    • 返回值为一个新的 promise,promise 的状态可分为如下两种情况:
      • 所有 promise 对象 resolved 时,才 resolved
      • 只要有一个 promise 对象 rejected 时,就 resolved
  • Promise.race(): 获取最快的一个 promise 结果, 不论成功或失败
    • 接收一个数组作为参数,如果数组项不是 promise 对象,则转换为 promise 对象
    • 返回值为一个新的 promise,promise 的状态以传入数据的状态为准
      • 但凡有一个 promise 为 resolved,就 resolved
      • 但凡有一个 promise 为 rejected,就 rejected

31. 什么是链式调用?为什么能用链式调用?

链式调用:在调用对象上的某个方法之后,还可以接着调用其他方法,如 [1,2,3].map().filter().concat()axios({}).then().catch()

原因:方法的返回值是一个对象,对象上拥有某些方法,所以可以接着一直调用

promise 对象为什么可以链式调用

  1. Promise 对象的原型上有 then() 方法,可以被调用
  2. then()方法的返回值是一个新的 Promise 对象 ,状态是 pending
  3. 所以 Promise 最终可形成.then().then()..... 这种链式结构
  4. promise 的状态没有改变,不会执行 then 里面的代码

问题:如何实现一个 Person,可以满足以下的方式链式调用

person.setName('Jack').setAge(18).sayHi().sleep()

// 待实现代码
function Person() {
    this.name = '机器人1号'
    this.age = 100
}

// 待实现代码
Person.prototype.setName = function(name) {
  this.name = name
  return this
}

Person.prototype.setAge = function(age) {
  this.age = age
  return this
}

Person.prototype.sayHi = function() {
  console.log(`name: ${this.name} , age: ${this.age}`)
  return this
}

Person.prototype.sleep = function() {
  console.log('sleep')
  return this
}

const person = new Person()

person.setName('Jack').setAge(18).sayHi().sleep()

32 . 实现异步编程的方式有哪些?分别有哪些特点?

  • 回调函数
    • 写法:setTimeout(() => {}, 1000)ele.addEventListener('click', () => {})
    • 特点:将函数作为参数传入,并在特定的时机被调用,比较简单
    • 说明:多个回调函数嵌套的时候会造成回调函数地狱,耦合度太高,不利于维护
  • promise
    • 写法:promise.then(() => {...})
    • 特点:可以将嵌套的回调函数作为链式调用,可维护性增强
    • 说明:有时会造成多个 then 的链式调用,可能会造成代码的语义不够明确
  • async 异步函数
  • async 声明的异步函数,它的返回值会自动包装为promise
  • async声明的异步函数中可以使用await 来调用其他异步函数
  • 调用 await ,它会等待promise 执行出结果后将结果返回,可以通过变量接收结果
    • 写法:async function () { await asyncFn() }
    • 特点:将异步逻辑,转化为同步的顺序书写,更简洁,推荐使用
    • 说明:当函数内部执行到一个 await 语句的时候,如果语句返回一个 promise 对象,那么函数将会等待 promise 对象的状态变为 resolve 后再继续向下执行

33 . 浏览器的事件循环机制是什么?执行流程是怎样的?

JavaScript 在设计之初便是单线程,即指程序运行时,只有一个线程存在,同一时间只能做一件事,为了解决单线程运行阻塞问题,JavaScript 用到了计算机系统的一种运行机制,这种机制就叫做事件循环(Event Loop)

如果 JS 设置为多线程,一个线程进行了删除 DOM ,另一个添加 DOM,会导致很多数据和页面更新的问题

在 JavaScript 中,所有的任务都可以分为:

  • 同步任务:立即执行的任务,同步任务一般会直接进入到主线程中执行
  • 异步任务:异步执行的任务,比如ajax网络请求,setTimeout 定时函数等

微任务和宏任务在浏览器的执行顺序:

  • 执行一个宏任务
  • 执行完微任务队列
  • 重复上面的步骤…

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-n01k2jY8-1678461708344)(assets/1676434027852.png)]

微任务和宏任务的调度机制也被称作为事件循环机制 EventLoop

  • 宏任务 macrotask:
    • script (可以理解为外层同步代码)
    • setTimeout
    • setInterval
    • Ajax
    • 浏览器触发的 DOM 事件(如 click、resize)
    • postMessage
    • MessageChannel
  • 微任务 microTask:
    • promise.then
    • MutationObserver
    • queueMicrotask

在代码执行的过程中,同步任务会立即执行,异步任务会通过一些手段和过程才会拿到结果。所以在异步任务等待结果的同时,可先执行其后的同步任务。当异步任务有结果的时候,在回过头来执行异步任务

EvnentLoop执行的机制就是先执行同步代码,接着是微任务,然后是宏任务

三、git面试题

34. Git和其他代码管理版本控制系统有什么区别?

Git 和其他版本代码管理控制系统( 如 SVN 和 CVS )之间的主要区别在于它们的架构和工作方式。Git 是一个分布式版本控制系统,每个开发人员都可以拥有一个完整的代码库副本,并在需要时进行合并更改。

而 SVN 和 CVS 等传统的版本控制系统是基于中央服务器的,每个开发人员都从中央服务器检出代码,然后提交更改

35. Git的三个区域是什么?如何将代码从一个区域移动到另一个区域?

Git的三个区域是工作区、暂存区和本地仓库。可以通过git add将代码从工作区移动到暂存区,通过git commit将代码从暂存区移动到本地仓库

36. 如何将本地的代码推送到远程仓库?

可以通过git push将本地的代码推送到远程仓库。例如,可以使用git push origin master将本地的master分支推送到名为origin的远程仓库。

37. 如何从远程仓库拉取代码到本地?

可以通过git pull从远程仓库拉取代码到本地。例如,可以使用git pull origin master从名为origin的远程仓库的master分支拉取最新代码。

38.如何在Git中合并两个分支?

使用“git merge”命令合并两个分支。例如,要将名为“feature-branch”的分支合并到当前分支,请输入“git merge feature-branch”

39.如何在Git中解决冲突?

使用“git merge”命令合并分支时可能会发生冲突。要解决冲突,请手动编辑包含冲突的文件,然后使用“git add”“git commit”命令提交更改。

40.什么是 git flow

Git flow是一种Git分支模型,它为团队提供了一种规范化的开发流程,使得代码库更容易管理、维护和协作。它的核心思想是在代码库中维护两个主要的分支:

一个稳定的主分支(master),用于发布生产版本;另一个是开发分支(develop),用于开发新功能和修复错误。此外,git flow还定义了一些支持分支,如feature、

release、hotfix,它们有助于更好地管理和协作团队成员在不同的开发阶段中的工作。总之,Git flow提供了一种标准化的Git分支模型,使团队能够更

有效地协作和管理Git代码库。

四、CMS项目面试题

41. 什么是Axios拦截器?

Axios拦截器是Axios提供的一种机制,用于在请求和响应发送之前或之后执行某些操作,比如添加请求头、检查请求参数、处理响应数据等。

42.如何使用Axios拦截器?

使用Axios拦截器,需要通过Axios提供的interceptors属性来创建请求和响应拦截器

// 添加请求拦截器
axios.interceptors.request.use(function (config) {
  // 在发送请求之前做些什么
  config.headers.Authorization = localStorage.getItem('token')
  return config;
}, function (error) {
  // 对请求错误做些什么
  return Promise.reject(error);
});

// 添加响应拦截器
axios.interceptors.response.use(function (response) {
  // 对响应数据做点什么
  return response;
}, function (error) {
  // 对响应错误做点什么
  return Promise.reject(error);
});

43.如何在Axios拦截器中处理错误?

在Axios拦截器中处理错误,需要在拦截器的两个回调函数中来处理

  1. 第一个回调函数用来处理 业务状态码的错误
  2. 第二个回调函数用来处理 HTTP响应状态码的错误

44.简述前端JWT的作用及原理,并说明其优缺点。

JWT(JSON Web Token)是一种用于在网络应用中传递信息的安全方式。JWT实际上是一段加密的JSON数据,由三部分组成:头部(Header)、载荷(Payload)和签名(Signature)。

作用:
  1. 身份认证:JWT可以在用户登录后生成一个JWT,用于后续的身份认证,无需在每个请求中都携带身份信息。
  2. 授权:JWT中可以携带用户的授权信息,使得服务器端可以根据授权信息进行相应的操作,从而实现授权。
  3. 信息交换:JWT可以在不同的系统之间传递信息,比如OAuth2中的AccessToken。
优点:
  1. 无状态:JWT是一种无状态的认证方式,即服务器端不需要保存任何用户信息,使得应用可以更容易地扩展。
  2. 安全性高:由于JWT采用了加密算法,能够保证传输过程中的数据不被篡改和窃取。
  3. 跨平台:由于JWT是一种标准化的认证方式,因此可以在不同的平台上使用。
缺点:
  1. 信息冗余:由于JWT中包含了头部、载荷和签名三部分信息,因此可能会导致信息冗余。
  2. 容易被篡改:如果签名算法不够安全,就有可能被恶意攻击者篡改JWT中的信息。
  3. 无法撤销:由于JWT一旦颁发,就无法撤销,因此如果JWT泄露,就可能导致严重的安全问题。

45.前端web登录流程

前端web登录流程通常涉及以下几个步骤:

  1. 用户输入用户名和密码,并点击“登录”按钮。
  2. 前端代码将用户输入的用户名和密码发送到后端服务器。
  3. 后端服务器接收到前端发送的用户名和密码,并进行身份验证。通常,后端服务器会将用户名和密码与存储在数据库中的用户凭据进行比对,以验证用户身份。
  4. 如果后端服务器验证成功,则会向前端发送一个带有用户信息的令牌(通常是 JSON Web Token)。如果验证失败,则会向前端发送一个错误消息。
  5. 前端代码接收到令牌,并将其存储在浏览器的本地存储中(例如,使用localStorage或sessionStorage)。
  6. 以后,当用户进行需要身份验证的操作时,前端代码将令牌发送到后端服务器以验证用户身份。如果令牌有效,则后端服务器允许该操作。否则,后端服务器将返回一个错误消息。

总之,前端web登录流程可以归纳为:用户输入凭据 -> 前端发送凭据到后端 -> 后端验证凭据并发送令牌 -> 前端存储令牌并发送到后端以进行身份验证。

46.什么是iframe标签?

iframe标签是HTML中的一个标签,它允许将一个HTML文档嵌入到另一个HTML文档中。它可以用于在一个HTML页面中嵌入

其他网站或自己的HTML页面。iframe标签通过src属性指定要嵌入的HTML文档的URL。

47.iframe标签的缺点是什么?

iframe标签的主要缺点是它可能导致性能问题。由于iframe标签需要加载另一个HTML文档,因此它可能导致页面加载速度变

慢。另外,由于iframe标签可以显示其他网站的内容,因此它也可能导致安全问题。

48.XSS

XSS (Cross-Site Scripting),跨站脚本攻击

XSS(Cross-Site Scripting,跨站脚本攻击)是一种常见的网络安全漏洞,攻击者会利用该漏洞将恶意代码注入到一个网站的

页面中,然后当用户访问该页面时,恶意代码就会执行,攻击者就可以利用这种方式来窃取用户的敏感信息或者劫持用户的会

话。

这种攻击方式通常利用网站未过滤或过滤不严格的用户输入数据,比如输入框、URL参数等,攻击者会在这些数据中嵌入恶意

的脚本代码,当用户在网站上执行了这些脚本代码时,就会产生XSS攻击。

例如,攻击者可以在一个论坛的回复框中输入一段恶意的脚本代码,然后当其他用户在查看该回复时,就会执行这段脚本代

码,从而导致攻击者获取用户的Cookie等敏感信息

具体来说,网站可以采用以下几种方式来防止XSS攻击:

  1. 输入过滤: 网站可以对用户输入的数据进行过滤,比如只允许特定的字符集、限制输入长度等。
  2. 输出转义:网站可以对输出到页面上的数据进行转义,将特殊字符(如<, >, ", '等)转换成HTML实体,从而防止恶意代码的注入。
  3. 使用CSP(Content Security Policy):CSP是一种安全策略,它允许网站开发者指定哪些内容是可信的,哪些是不可信的,从而防止恶意代码的注入。
  4. 使用HTTP-only Cookie:HTTP-only Cookie是一种Cookie属性,它可以防止JavaScript脚本读取或修改Cookie内容,从而防止攻击者利用XSS攻击来盗取用户的Cookie。

总之,要防止XSS攻击,网站开发者需要充分了解XSS攻击的原理,并采取一系列的措施来确保网站的安全性

49.CSRF

CSRF(Cross Site Request Forgery),跨站请求伪造

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BZkWtsbm-1678461708345)(assets/ljaz32j59h.png)]

跨站请求伪造(Cross-Site Request Forgery,CSRF)是一种网络攻击方式,它通常会利用用户已经登录过的身份,来执行一

些恶意操作,比如删除账户、购买商品等。

攻击者会在一个恶意网站中构造一个请求,然后引诱用户在已登录的另一个网站上点击一个链接,这个链接会让用户在不知情

的情况下发送请求到目标网站,这时候目标网站会认为这个请求是合法的,因为它携带了用户已经登录的身份信息,从而执行

攻击者想要的操作。

例如,一个攻击者可以在一个恶意网站中构造一个请求,这个请求可以让用户在另一个网站上删除自己的账户,然后攻击者就

会通过这种方式来盗取用户的账户。

为了防止CSRF攻击,网站通常会采取一些防范措施,比如添加随机令牌、验证Referer头、验证请求的来源地址等。

50.ajax、axios、fetch的区别

(1)AJAX

Ajax 即“AsynchronousJavascriptAndXML”(异步 JavaScript 和 XML),是指一种创建交互式网页应用的开发技术。它是

一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。通过在后台与服务器进行少量数据交换,Ajax 可以使网页

实现异步更新。传统的网页(不使用 Ajax)如果需要更新内容,必须重载整个网页页面。其缺点如下:

  • 本身是针对MVC编程,不符合前端MVVM的浪潮
  • 基于原生XHR开发,XHR本身的架构不清晰
  • 不符合关注分离(Separation of Concerns)的原则
  • 配置和调用方式非常混乱,而且基于事件的异步模型不友好。
(2)Fetch

fetch号称是AJAX的替代品,是在ES6出现的,使用了ES6中的promise对象。Fetch是基于promise设计的。Fetch的代码结构比起ajax简单多。fetch不是ajax的进一步封装,而是原生js,没有使用XMLHttpRequest对象。

fetch的优点:

  • 语法简洁,更加语义化
  • 基于标准 Promise 实现,支持 async/await
  • 更加底层,提供的API丰富(request, response)
  • 脱离了XHR,是ES规范里新的实现方式

fetch的缺点:

  • fetch只对网络请求报错,对400,500都当做成功的请求,服务器返回 400,500 错误码时并不会 reject,只有网络错误这些导致请求不能完成时,fetch 才会被 reject。
  • fetch默认不会带cookie,需要添加配置项: fetch(url, {credentials: ‘include’})
  • fetch不支持abort,不支持超时控制,使用setTimeout及Promise.reject的实现的超时控制并不能阻止请求过程继续在后台运行,造成了流量的浪费
  • fetch没有办法原生监测请求的进度,而XHR可以
(3)Axios
  • Axios 是一种基于Promise封装的HTTP客户端,其特点如下:
  • 浏览器端发起XMLHttpRequests请求
  • node端发起http请求
  • 支持Promise API
  • 监听请求和返回
  • 对请求和返回进行转化
  • 取消请求
  • 自动转换json数据
  • 客户端支持抵御XSRF攻击

五、nodejs面试题

51.Node.js是什么?它的主要用途是什么?

Node.js是一个基于Chrome V8引擎的JavaScript运行时环境,它允许JavaScript在服务器端运行。Node.js的主要用途是编写服

务器端应用程序,但它也可以用于编写命令行工具、网络工具和桌面应用程序等。

52.Node.js中的包管理器是什么?它有什么作用?

Node.js中的包管理器是npmNode Package Manager)。它是一个用于安装、管理和分享Node.js模块的工具。npm允许你

通过命令行安装、卸载和更新模块,还可以搜索和分享你的模块。npm还可以自动解决依赖关系,并在安装时将所有需要的模

块下载到本地。它们可以提高数据处理的效率和安全性。

53.Node.js中的缓冲区是什么?它们的作用是什么?

答:缓冲区是Node.js中用于处理二进制数据的机制。缓冲区是一个固定大小的内存块,它可以存储任意类型的数据,包括

ASCII、UTF-8和16进制等。缓冲区可以用于处理文件、网络数据和其他I/O操作,它们可以提高数据处理的效率和安全性。

54.如何处理 Node.js 中的异步操作?

在 Node.js 中,异步操作通常通过回调函数来处理。当一个异步操作完成后,会调用回调函数,并将操作结果传递给回调函

数。开发人员可以在回调函数中处理异步操作的结果,例如输出结果、更新数据等。除了回调函数,Node.js 还提供了

PromiseAsync/Await 等方式来处理异步操作

55.什么是模块?如何创建和使用模块?

我们分为三大模块,分别是核心模块、自定义模块和第三方模块。

模块是指一个包含代码的文件或者文件夹。每个模块都拥有自己的作用域,可以通过 require 函数来加载模

块,并使用模块中的代码。可以通过 exportsmodule.exports 对象来向外暴露模块中的内容,其他模块可以通过 require

数来引用模块中的内容。

56.什么是webpack(必会)

webpack是一个打包模块化 javascript 的工具,在webpack里一切文件皆模块,通过loader转换文件,通过plugin注入钩子,最后输出由多个模块组合成的文件,webpack专注构建模块化项目

57.Webpack的优点是什么?(必会)

  1. 专注于处理模块化的项目,能做到开箱即用,一步到位
  2. 通过plugin扩展,完整好用又不失灵活
  3. 通过loaders扩展, 可以让webpack把所有类型的文件都解析打包
  4. 社区区庞大活跃,经常引入紧跟时代发展的新特性,能为大多数场景找到已有的开源扩展

58.webpack的构建流程是什么?从读取配置到输出文件这个过程尽量说全(必会)

​ Webpack 的运行流程是一个串行的过程,从启动到结束会依次执行以下流程:

​ 1. 初始化参数:从配置文件读取与合并参数,得出最终的参数

2. 开始编译:用上一步得到的参数初始化 Compiler 对象,加载所有配置的插件,开始执行编译
3. 确定入口:根据配置中的 entry 找出所有的入口文件
4. 编译模块:从入口文件出发,调用所有配置的 Loader 对模块进行翻译,再找出该模块依赖的模块,再递归本步骤直到所有入口依赖的文件都经过了本步骤的处理
5. 完成模块编译:在经过第4步使用 Loader 翻译完所有模块后,得到了每个模块被翻译后的最终内容以及它们之间的依赖关系
6. 输出资源:根据入口和模块之间的依赖关系,组装成一个个包含多个模块的 Chunk,再把每个 Chunk 转换成一个单独的文件加入到输出列表,这步是可以修改输出内容的最后机会
7. 输出完成:在确定好输出内容后,根据配置确定输出的路径和文件名,把文件内容写入到文件系统。

在以上过程中,Webpack 会在特定的时间点广播出特定的事件,插件在监听到感兴趣的事件后会执行特定的逻辑,并且插件可以调用 Webpack 提供的 API 改变 Webpack 的运行结果

59.说一下 Webpack 的热更新原理(必会)

​ webpack 的热更新又称热替换(Hot Module Replacement),缩写为 HMR。这个机制可以做到不用刷新浏览器而将新变更的模块替换掉旧的模块。

​ HMR的核心就是客户端从服务端拉去更新后的文件,准确的说是 chunk diff (chunk 需要更新的部分),实际上 WDS 与浏览器之间维护了一个 Websocket,当本地资源发生变化时,WDS 会向浏览器推送更新,并带上构建时的 hash,让客户端与上一次资源进行对比。客户端对比出差异后会向 WDS 发起 Ajax 请求来获取更改内容(文件列表、hash),这样客户端就可以再借助这些信息继续向 WDS 发起 jsonp 请求获取该chunk的增量更新。

​ 后续的部分(拿到增量更新之后如何处理?哪些状态该保留?哪些又需要更新?)由 HotModulePlugin 来完成,提供了相关 API 以供开发者针对自身场景进行处理,像react-hot-loader 和 vue-loader 都是借助这些 API 实现 HMR。

60.webpack与grunt、gulp的不同?(必会)

1) 三者之间的区别

​ 三者都是前端构建工具,grunt和gulp在早期比较流行,现在webpack相对来说比较主流,不过一些轻量化的任务还是会用gulp来处理,比如单独打包CSS文件等。

​ grunt和gulp是基于任务和流(Task、Stream)的。类似jQuery,找到一个(或一类)文件,对其做一系列链式操作,更新流上的数据, 整条链式操作构成了一个任务,多个任务就构成了整个web的构建流程。

​ webpack是基于入口的。webpack会自动地递归解析入口所需要加载的所有资源文件,然后用不同的Loader来处理不同的文件,用Plugin来扩展webpack功能。

2) 从构建思路来说

​ gulp和grunt需要开发者将整个前端构建过程拆分成多个Task,并合理控制所有Task的调用关系 webpack需要开发者找到入口,并需要清楚对于不同的资源应该使用什么Loader做何种解析和加工

3) 对于知识背景来说

​ gulp更像后端开发者的思路,需要对于整个流程了如指掌 webpack更倾向于前端开发者的思路

61.有哪些常见的Loader?他们是解决什么问题的?(必会)

1、 file-loader:把文件输出到一个文件夹中,在代码中通过相对 URL 去引用输出的文件

2、 url-loader:和 file-loader 类似,但是能在文件很小的情况下以 base64 的方式把文件内容注入到代码中去

3、 source-map-loader:加载额外的 Source Map 文件,以方便断点调试

4、 image-loader:加载并且压缩图片文件

5、 babel-loader:把 ES6 转换成 ES5

6、 css-loader:加载 CSS,支持模块化、压缩、文件导入等特性

7、 style-loader:把 CSS 代码注入到 JavaScript 中,通过 DOM 操作去加载 CSS。

8、 eslint-loader:通过 ESLint 检查 JavaScript 代码

62.Loader和Plugin的不同?(必会)

1) 不同的作用

​ Loader直译为"加载器"。Webpack将一切文件视为模块,但是webpack原生是只能解析js文件,如果想将其他文件也打包的话,就会用到loader。 所以Loader的作用是让webpack拥有了加载和解析非JavaScript文件的能力。

​ Plugin直译为"插件"。Plugin可以扩展webpack的功能,让webpack具有更多的灵活性。 在 Webpack 运行的生命周期中会广播出许多事件,Plugin 可以监听这些事件,在合适的时机通过 Webpack 提供的 API 改变输出结果。

2) 不同的用法

​ Loader在module.rules中配置,也就是说他作为模块的解析规则而存在。 类型为数组,每一项都是一个Object,里面描述了对于什么类型的文件(test),使用什么加载(loader)和使用的参数(options)

​ Plugin在plugins中单独配置。 类型为数组,每一项是一个plugin的实例,参数都通过构造函数传入。

63.重绘和回流(重排)

1. 回流(重排)

Render Tree渲染树)中部分或者全部元素的布局,尺寸大小,结构等发生改变时,浏览器就会重新渲染部分或全部文档的过程称为 回流

2. 重绘

页面中元素的颜色,字体,或其他外观属性改变时,浏览器需要重绘来更新外观(比如:color、background-color、outline等), 称为重绘。

重绘不一定引起回流(重排),而回流(重排)一定会引起重绘。

3. 会导致回流(重排)的操作:

1.1 页面的首次刷新
1.2 浏览器的窗口大小发生改变
1.3 元素的大小或位置发生改变
1.4 改变字体的大小
1.5 内容的变化(如:input框的输入,图片的大小)
1.6激活css伪类 (如::hover
1.7 脚本操作DOM(添加或者删除可见的DOM元素)
1.8 简单理解影响到布局了,就会有回流

在这里插入图片描述

64.什么是跨域?

跨域:指的是浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对 javascript 施加的安全限制

通俗的说就是协议 端口 主机 三者 不一致就会造成跨域

解决方案:

  1. 使用代理服务器:可以在本地搭建一个代理服务器,通过代理服务器转发请求,从而解决跨域问题。
  2. 使用 JSONP:JSONP 是一种跨域数据传输方式,可以通过动态插入 script 标签的方式实现跨域访问,JSONP是比较老的一种方案,只支持get请求,不支持post请求
  3. 使用 CORS:CORS 是一种跨域资源共享的方式,可以通过在服务器端配置 HTTP 头信息,让浏览器允许跨域访问。 它通过服务器增加一个特殊的Header[Access-Control-Allow-Origin]来告诉客户端跨域的限制
  4. 使用 WebSocket:WebSocket 是一种基于 TCP 的协议,可以实现双向通信,不存在跨域的限制。

六、vue面试题

65.什么是MVVM

MVVM,是Model-View-ViewModel的简写,是M-V-VM三部分组成。它本质上就是MVC 的改进版

Model(模型) : 表示应用程序中的数据模型,它代表着应用程序中的业务逻辑和状态。

View(视图): 表示应用程序中的用户界面。

ViewModel(视图模型) : 是一个桥梁,将模型和视图连接在一起,它提供了视图所需的数据和命令,并将用户的输入转换为模型的操作。

**MVVM采用双向数据绑定,view中数据变化将自动反映到viewmodel上,反之,model中数据变化也将会自动展示在页面上。**把ModelView关联起来的就是ViewModel。ViewModel负责把Model的数据同步到View显示出来,还负责把View的修改同步回Model。

MVVM核心思想,是关注model的变化,让MVVM框架利用自己的机制自动更新DOM,也就是所谓的数据-视图分离,数据不会影响视图

MVVM 就是将其中的View 的状态和行为抽象化,其中ViewModel将视图 UI 和业务逻辑分开,它可以取出 Model 的数据同时帮忙处理 View 中由于需要展示内容而涉及的业务逻辑。

66.vue的理解?

Vue.js 是一个渐进式JavaScript 框架,旨在通过尽可能简单的 API 实现响应式数据绑定组合的视图组件

Vue.js 的核心是数据驱动视图通过组件内特定的方法实现视图和模型的交互 。

Vue.js响应式系统可以在模型数据变化时,视图会自动更新。这意味着,我们可以在不手动操作 DOM 的情况下改变视图

Vue.js 还提供了许多其他功能,如组件系统、路由、状态管理等,可以帮助你构建复杂的单页应用。

总的来说,Vue.js 是一个轻量级的、易于使用的前端框架,可以帮助你快速构建响应式的 Web 应用。

67.说5个vue的指令

  1. v-bind:绑定属性
  2. v-ifv-show:条件渲染
  3. v-for: 列表渲染
  4. v-model:双向绑定
  5. v-html:解析html字符串
  6. v-on:绑定事件

68.vue 单页面应用

vue 是一个单页面应用 ,这个vue项目其实只会有一个 index.html 页面,它内容的切换本质都是通过切换div来实现模拟多页面的

SPA单页面应用(SinglePage Web Application,简称 SPA),指的是只有一个主页面的应用,一开始只需要加载一次jscss等相关资源,所有内容都包含在主页面上,对每一个功能模块组件化,单页面应用跳转,就是切换相关组件,仅仅刷新局部资源。(单页面应用指一个系统只加载一次资源,然后下面的操作交互、数据交互是通过router、ajax来进行,页面并没有刷新)

与传统的多页面应用相比,单页面应用具有许多优势,包括:

  • 快速响应:由于不需要重新加载页面,因此 SPA 应用可以快速响应用户的操作。
  • 减少服务器负载:由于大部分的处理都是在客户端进行的,因此 SPA 应用可以减少服务器的负载。
  • 更好的用户体验:由于 SPA 应用的页面切换非常流畅,因此它可以提供更好的用户体验。

然而,单页面应用也有一些缺点,包括:

  • 较难调试:由于 SPA 应用的代码都在客户端运行,因此调试可能会更加困难。
  • 首次加载耗时多:解决方法通过路由懒加载: 可以有效的分担首页所承担的加载压力,减少首页加载用时
  • SEO 难度较大: 由于所有的内容都在一个页面上动态替换显示,所以在 SEO 上其有着天然的弱势。 为了解决这个问题,可以使用服务端渲染(Server-Side Rendering,简称 SSR)技术,在服务器端渲染 SPA 应用的内容,使得爬虫可以正常抓取页面内容。

69.v-for和v-if为什么不能一起使用

vue2v-for优先级高于v-if,如果二者在同一级标签里面使用,每次都要先循环,再判断,消耗很多性能。

解决办法的话,可以在外层包装一个div,使用v-if做一次判断即可。Vue3解决了这个问题,将v-if的优先级调整为高于v-for了。

70.计算属性与watch的区别

computed是用来计算出来一个值的,这个值调用的时候不需要加括号,会根据依赖进行缓存,依赖不变,computed的值不会重新计算。

watch是来监听的,有2个选项

  1. immediate:表示是否要在第一次渲染的时候执行这个函数
  2. deep:如果我们监听一个对象,那么我们要看这个对象里面的属性是否变化,如果某个属性变化了,就去执行一个函数

71.vue组件中data为什么必须是一个函数

在 Vue.js 中,组件的 data 选项必须是一个函数,这是因为每个组件实例都应该有自己的状态,如果 data 不是一个函数,那么所有实例将共享同一个数据对象,这会导致组件之间的状态混乱

举个例子,假设你有一个组件 A 和组件 B,如果你把 data 写成这样:

data: {
  message: 'Hello'
}

那么组件 A 和组件 B 中的 message 都是同一个值,如果在组件 A 中修改了 message,那么组件 B 中的 message 也会改变。这显然不是你想要的结果。

因此,Vue.js 要求 data 选项必须是一个函数,这样每个组件实例都可以有自己的 data 对象。你可以这样写:

data: function () {
  return {
    message: 'Hello'
  }
}

这样就能保证每个组件实例都有自己的 data 对象,组件之间的状态就不会混乱了。

72.nextTick的理解

nextTick 是 Vue.js 中一个用来在下一个事件循环中调用回调函数的方法。( 就是你放在 $ nextTick 当中的操作不会立即执行,而是等数据更新、DOM更新完成之后再执行,这样我们拿到的肯定就是最新的了 )这个方法通常用在等待数据DOM 元素更新之后执行一些代码。也可以说在下一次DOM更新结束后执行其指定的回调

这句话扩展开来说,就是由于Vue中DOM更新是「异步执行」的,即修改数据时,视图不会立即更新,而是会监听数据变化,并缓存在同一事件循环中,等同一数据循环中的所有数据变化完成之后,再统一进行视图更新。经常我们会在还未更新的时候就使用了某个元素,这样是拿不到变更后的dom的,所以为了确保能够得到更新后的DOM,所以设置了nextTick()方法。在修改数据之后立即使用这个方法,获取更新后的DOM。简单概括,vue中的nextTick主要用于处理数据动态变化后,DOM还未及时更新的问题,用nextTick可以获取数据更新后最新dom的变化。

73.插槽

在 Vue.js 中,插槽(slot)是一种机制,可以在父组件的模板中定义一个占位符,然后在子组件中插入内容。这样,子组件就

可以在父组件的模板中渲染内容,使得子组件可以更灵活地与父组件进行交互。

  • 插槽的使用过程其实是抽取共性、预留不同
  • 我们会将共同的元素、内容依然在组件内进行封装
  • 同时会将不同的元素使用slot作为占位,让外部决定到底显示什么样的元素;

插槽有两种类型:

  • 具名插槽:具名插槽使用特定的名称来标识,子组件可以插入到特定的插槽中。
  • 不具名插槽:不具名插槽没有名称,子组件中的内容会插入到不具名插槽中。

74.路由模式

  • hash模式:
    • 浏览器中符号是“#”,#以及#后面的字符称之为 hash,又叫前端路由
    • window.location.hash 读取
    • hash 虽然在 URL 中,但不会向服务器发送请求
    • hash 改变会触发 hashchange 事件, 并根据hash值来修改页面内容
    • hash发生变化的url都会被浏览器记录下来,从而实现浏览器的前进后退。
  • history模式:
    • history 采用 了HTML5 History API
    • history 模式不仅可以在url里放参数,还可以将数据存放在一个特定的对象中
    • 它也有个问题:不怕前进,不怕后退,就怕刷新(如果服务器中没有相应的响应或资源,会分分钟刷出一个404来),因为刷新是实实在在地去请求服务器的。

75.说说vue的生命周期

vue组件生命周期:从创建销毁 的整个过程就是 – Vue实例的 生命周期

Vue中的生命周期本质上就是按顺序固定执行一个个的钩子函数,我们开发者可以在每个函数中写入特定代码来实现我们需要的功能例如我们常用的ajax请求通常就放在created或者mounted中

vue2的生命周期从分类上来看有如下几种情况:

  1. 组件创建挂载相关的钩子函数有
    1. beforeCreate
    2. created
    3. beforeMount
    4. mounted
  2. 组件更新相关的钩子函数有
    1. beforeUpdate
    2. updated
  3. 组件销毁相关的钩子函数有
    1. beforeDestroy
    2. destroyed

还有一个组件缓存激活相关的钩子函数是:activated和deactivated,这两个要配合keep-alive 缓存的组件一起使用

kee-alive 是 Vue 内置的一个组件,可以使被包含的组件保留状态,或避免重新渲染 。也就是所谓的组件缓存 keep-alive ,当它包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们

vue3总体来说什么周期执行顺序是一样的,不同点在于beforeCreate和created都被setup函数替代了

76.vue旧地复用策略

Vue会尽可能的就地(同层级,同位置),对比虚拟dom,复用旧dom结构,进行差异化更新,vue采用的是diff算法进行对比。它会先同层级根元素进行比较,如果根元素变化的话,就不考虑复用了,如果根元素没有变化,就会对比同级兄弟元素,默认按照下标进行对比复用,如果设置了key就会按照相同key的新旧元素进行对比复用,key必须是一个唯一不重复的字符串或者数值key的好处就是可以提高虚拟DOM对比的复用性能。

77.深度侦听在什么情况下使用?立即侦听什么情况下使用?

deep(深度侦听):默认情况下,侦听器无法侦听对象的属性值的变化,如果想实现这个效果,则需要添加deep配置为true

handler(固定方法触发):因为你要添加deep的配置,所以,侦听器的形式要变更为对象形式,只有对象才能添加其它的配置, 同时侦听函数必须为handler

immediate(立即侦听):如果需要默认一进页面就触发一次,添加immediate配置选项为true

78.前置路由守卫

全局前置路由守卫: 初始化的时候被调用每次 路由切换之前 被调用

路由跳转之前, 会触发的一个函数 叫前置路由守卫

语法:router.beforeEach((to, from, next) => {这里可以写路径的跳转判断/有无token值的情况分析})

作用 : 防止别人猜到网址的hash值后直接跳过登录就可以查看数据

里面的3个参数:

to : 到哪里去

from : 从哪里来

next : 放行函数 next():放行 , next(false):不放行

79.Vuex核心属性:

  • state:定义需要管理的数据
  • getters:state派生出来的数据,相当于state的计算属性
  • mutation:里面定义的是同步的更新数据方法,每个方法里都有两个参数,一个是state,一个是payload,通过store.commit调用
  • action:里面定义的是异步的方法,每个方法里面有两个参数,一个是store,一个是payload,通过store.dispatch调用,在actions里也可以提交mutation,通过store.commit
  • module:将vuex模块化,可以让每一个模块拥有自己的statemutationactiongetters,结构清晰,方便管理

80.Vue2优点和缺点讲解

优点

  • 轻量级的框架
  • 双向数据绑定
  • 组件化开发
  • 单页面路由
  • 学习成本低
  • 虚拟dom
  • 渐进式框架
  • 数据和结构的分离
  • 运行速度快
  • 插件化

缺点

  • 不支持IE8以下
  • 社区可能没有Angular和React那么丰富
  • Vue 不缺入门教程,可是很缺乏高阶教程与文档。同样的还有书籍
  • 因为是单页面应用,不利于seo优化
  • 初次加载时耗时多

81.在使用vuex时怎么实现数据的持久化

我们通常是将数据保存到本地存储中,当重新刷新页面后从本地存储中将之前的数据加载回来

保存到vuex中的state。这样就能实现vuex的数据持久化了

82.三次握手和四次挥手

三次握手是用于在俩台计算机之间建立网络连接, 确认双方的接收与发送能力是否正常 ,它包括三个步骤:

1.客户端向服务端发送连接请求

2.服务端向客户端发送确认消息,表明服务器已准备好接受连接

3.客户端向服务器发送确认消息,表明客户端已收到服务端的确认消息,并准备好开始数据传输

四次挥手是用于在俩台计算机之间终止网络连接,它包括以下四个步骤:

1.客户端向服务器发送断开连接请求

2.服务器向客户端发送确认消息,表明服务器已收到断开连接的请求。(服务端收到关闭请求的时候可能这个时候数据还没发送完,所以服务端会先回复一个确认报文,表示自己知道客户端想要关闭连接了,但需要等待数据传输完)

3.服务器向客户端发送断开连接的请求。(会主动发送FIN报文,告知客户端,服务端准备关闭连接了)

4.客户端向服务器发送确认消息,表明客户端已收到服务器的断开连接请求,稍后进行断开

扩展、 挥手为什么需要四次?

因为当服务端收到客户端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当服务端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉客户端,“你发的FIN报文我收到了”。只有等到我服务端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四次挥手。

补充、TCP和UDP的区别

TCPUDP都是传输层协议

TCP 是一种面向有连接的传输层协议,能够对自己提供的连接实施控制。适用于要求可靠传输的应用,例如文件传输。面向字节流,传输慢

UDP 是一种面向无连接的传输层协议,不会对自己提供的连接实施控制。适用于实时应用,例如:IP电话、视频会议、直播等。,以报文的方式传输,效率高

UDPTCP
是否连接无连接面向连接
是否可靠不可靠传输,不使用流量控制和拥塞控制可靠传输,使用流量控制和拥塞控制
连接对象个数一对一,一对多,多对一,多对多只能有俩个端点,一对一通信
传输方式面向报文面向字节流
首部开销开销小,仅8字节最小20字节,最大60字节

83.一个页面从输入 URL 到页面加载显示完成的过程

1、URL解析:地址栏输入地址,浏览器对输入内容进行解析,判断URL的合法性,和是否有可用缓存
2、DNS解析:域名解析系统(DNS)查找对应的IP地址
3、建立TCP连接(三次握手):浏览器向服务器发起TCP连接,与浏览器建立TCP三次握手
4、HTTP请求:浏览器将http请求数据发给服务器(客户端–>服务器)
5、HTTP响应:服务器处理收到的请求,返回响应结果至浏览器(服务器–>客户端)
6、关闭TCP连接(四次挥手):数据传输完成后,还要经过四次握手以终止连接
7、页面渲染:浏览器解析响应结果,进行页面渲染

84.vue双向数据绑定原理

比如说,当在输入框输入文字时,vue会检测到数据的变化,然后更新对应的视图。同样,如果你通过代码修改了数据,那么vue也会自动更新视图,其原理是通过数据劫持发布订阅模式实现的。

首先,Vue通过Object.defineProperty( )方法对数据进行劫持,监听数据的变化,并通过gettersetter方法对数据进行读写。
其次,Vue通过发布订阅模式,维护了一个订阅者数组,当数据发生变化时,Vue会通知所有订阅者进行更新。因此,当用户在页面上进行修改时,Vue也会自动更新对应的数据,并通知所有订阅者更新视图,同时当数据发生变化时,Vue也会更新对应的视图,通过这样的机制,Vue实现了双向数据绑定,使得数据和视图的变化可以互相影响

补充:订阅者是Vue中的一个概念,它是一个用于管理更新视图的对象,当数据发生变化时,Vue会通知所有的订阅者进行更新,在Vue中,每一个挂载到视图上的组件,或者每一个watcher,都可以被看成一个订阅者,他们订阅了某一个数据的变化,并等待数据发生变化时进行更新,订阅者是Vue实现双向数据绑定的关键组成部分,管理着数据和视图之间的关系,保证了数据的变化能够及时反应到视图上

vue双向数据绑定原理

是数据劫持加观察者模式实现的。 大致分成了以下两步:

  1. 通过 Object.defineProperty 劫持数据,收集依赖
  2. 当数据被访问或更新时,通知对应依赖去响应视图的变化 当 Vue 实例被创建时,它会在内部遍历所有数据并使用 Object.defineProperty() 函数为每个属性添加 getter 和 setter。这样,当数据被访问(get)或修改(set)时,Vue 就可以捕获数据并通知观察者(渲染页面)。

补充. 双向数据绑定原理之Vue3.0比vue2.0的优势有哪些?

vue2.0使用了 Object.defineProperty 的方法,首先它是无法检测到对象属性的新增或者删除,其次无法监听数组的变化,vue在实现数组的响应式时,它使用了一些hack, 把无法监听数组的情况通过重写数组的部分方法来实现响应式,这也只限制在数组的push/pop/shift/unshift/splice/sort/reverse七个方法, 其他数组方法及数组的使用则无法检测到 。

vue3.0 使用了proxy来代替Object.definePropertyproxy属性是ES6中新增的一个属性, proxy属性也是一个构造函数,他也可以通过new的方式创建这个函数, proxy直接代理的是整个对象而非对象属性,proxy的代理针对的是整个对象而不是像object.defineProperty针对某个属性, 只需要做一层代理就可以监听同级结构下的所有属性变化,。

85.页面优化:

  • v-if和v-for不能连用
  • 更多的情况下,使用v-if代替v-show
  • 要保证key值的唯一
  • 使用组件懒加载或者图片懒加载
  • 防抖和节流的使用
  • 模块按需导入
  • 打包优化
  • 使用cdn加载第三方模块
  • 缓存常用信息
  • 精灵图,base64

补充. v-if 和 v- show的区别

作用:都是可以实现元素的显示与隐藏

  1. v-show 频繁切换标签,用v-show css手段控制标签显示隐藏
  2. v-if 不频繁切换标签,用v-if,创建删除标签显示隐藏,惰性的,一开始为false的,不会创建标签,性能更好

补充、v-model的实现原理

Vue.js 中,v-model 指令是一种语法糖,它的作用是为表单元素绑定双向数据绑定v-model 指令的实现原理是基于计算属性和事件绑定。它会将表单元素的 value 属性绑定到一个计算属性上,并且在计算属性的 setter 中触发 input 事件来更新 Vue 实例中的数据。

补充、vue2中的filter过滤器

vue2有使用过滤器 vue3已舍弃使用

vue2过滤器的使用:用于一些常见的文本格式化 例如:日期格式化、数字大小写、单位转换、文本格式化等

过滤器的作用:可以在不改变原数据 只是对数据进行加工处理并返回过滤后的数据,再进行调用处理

过滤器分为全局过滤器和局部过滤器

过滤器只能应用在两个地方:双花括号插值v-bind表达式(后者从 2.1.0+ 开始支持)。例如

<!--在双花括号中使用 格式:{{值 | 过滤器的名称}}-->
<div>{{3 | addZero}}</div>
<!--在v-bind中使用 格式:v-bind:id="值 | 过滤器的名称"-->
<div v-bind:id="1 | addZero">11</div>

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一些可能在2023前端面试中常见的题目: 1. 请解释一下什么是前端开发,并列举一些前端开发常见任务和技术。 2. 请解释一下什么是响应式设计,以及如何实现一个响应式网页。 3. 请解释一下什么是跨域请求,以及如何解决跨域请求的问题。 4. 请解释一下什么是事件冒泡和事件捕获,并说明它们之间的区别。 5. 请解释一下什么是闭包,并举一个闭包的实际应用场景。 6. 请解释一下什么是异步编程,以及常见的异步编程方式有哪些。 7. 请解***释一下什么是单页应用(SPA),以及它的优缺点。 9. 请解释一下什么是模块化开发,以及常见的模块化开发方案有哪些。 10. 请解释一下什么是浏览器缓存,以及常见的浏览器缓存策略有哪些。 11. 请解释一下什么是性能优化,以及你在前端开发中常用的性能优化方法。 12. 请解释一下什么是前端安全,以及你在前端开发中常用的安全措施。 13. 请解释一下什么是渐进式增强和优雅降级,并说明它们之间的区别。 14. 请解释一下什么是响应式图片,并说明如何实现响应式图片加载。 15. 请解释一下什么是 SEO,以及你在前端开发中常用的 SEO 优化方法。 以上只是一些可能的题目,具体的面试题目还会根据公司和职位的要求而有所不同。建议你在准备面试时,综合考虑前端开发的基础知识、常用技术和最新趋势,以及与你申请的公司和职位相关的要求,进行有针对性的准备。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值