前端面试题 - 计算机网络与浏览器相关

系列文章目录

vue常见面试题总结

html+css 面试题总结附答案

初级前端面试题总结(html, css, js, ajax,http)

js基础面试题整理(包含ES5,ES6)



一、网络协议相关

1. 从浏览器地址栏输入url到显示页面的步骤

  1. 浏览器解析输入的 URL,提取出其中的协议、域名和路径等信息。
  2. 浏览器向 DNS 服务器发送请求,DNS服务器通过多层查询将该域名解析为对应的IP地址,然后将请求发送到该IP地址上,与服务器建立连接和交换数据。(寻找哪台机器上有你需要的资源,根据域名找IP)
  3. 浏览器与服务器建立 TCP 连接。
  4. 浏览器向服务器发送 HTTP 请求,包含请求头和请求体。
  5. 服务器接收并处理请求,并返回响应数据,包含状态码、响应头和响应体。
  6. 浏览器接收到响应数据,解析响应头和响应体,并根据状态码判断是否成功。
  7. 如果响应成功,浏览器解析渲染页面 -》浏览器便开始下载网页,HTML,CSS,JS文件后依次渲染
  8. 连接结束,断开TCP连接 四次挥手

详细可参考:超详细讲解页面加载过程

2. HTTP请求的完整过程

  1. 建立TCP连接:HTTP协议基于TCP协议,因此需要先建立TCP连接。在建立TCP连接中,需要进行 “三次握手” ,即客户端向服务器发送一个连接请求报文,服务器接收到请求报文后回复一个连接确认报文,客户端再向服务器发送一个确认报文,确认连接已建立。
  2. 发送请求报文:TCP连接建立后,客户端像服务器发送HTTP请求报文。请求报文通常包括请求行(包括请求方法、请求URL、HTTP协议版本)、请求头和请求体(对于POST等需要提交数据的请求)。
  3. 服务器处理请求:服务器收到请求报文后,根据请求行中的URL和请求头中的各种信息进行处理,生成响应报文。
  4. 发送响应报文:服务器生成响应报文后,向客户端发送HTTP响应报文。响应报文通常包括响应行(HTTP协议版本、状态码和状态描述)、响应头和响应体。
  5. 关闭TCP连接:HTTP协议采用“短连接”方式,即每个HTTP请求和响应都需要建立和关闭一个TCP连接。当服务器发送完响应报文后,会关闭TCP连接,客户端收到响应后也会关闭TCP连接。

3. 三次握手,说明每次握手都发送什么信息?四次挥手

三次握手是TCP协议用于建立可靠连接的过程,具体过程如下:

  1. 客户端向服务器发送一个 SYN(synchronize同步)报文。其中随机生成一个初始序列号,表示客户端准备发送数据。
  2. 服务器接收到SYN报文后,回复一个 SYN ACK(同步确认)报文,表示我收到了。其中确认号为客户端的序列号+1,同时随机生成一个初始序列号,表示服务器准备接收数据。
  3. 客户端接收到SYN ACK报文后,向服务器发送一个 ACK(确认)报文,表示我知道了,握手结束。其中确认号为服务器的序列号+1,表示客户端准备发送数据。服务器接收到ACK报文后,连接建立成功,双方开始进行数据传输。

直白理解:

(客户端:hello,你是server么?服务端:hello,我是server,你是client么 客户端:yes,我是client 建立成功之后,接下来就是正式传输数据。)

三次握手的目的是为了确保客户端和服务器之间的通信是可靠的,同时也可以防止已经失效的连接请求报文段再次传到服务器,导致错误。

四次挥手:即终止TCP连接,就是指断开一个TCP连接时,需要客户端和服务端总共发送4个包以确认连接的断开。

直白理解:

(主动方:我已经关闭了向你那边的主动通道了,只能被动接收了 被动方:收到通道关闭的信息 被动方:那我也告诉你,我这边向你的主动通道也关闭了 主动方:最后收到数据,之后双方无法通信)

可参考:一文搞懂TCP的三次握手和四次挥手

TCP三次握手、四次挥手时序图

4. TCP三次握手,握手是根据ip和端口来握手的吗?

是的。
在TCP三次握手过程中,交换IP地址和端口号信息的具体步骤如下:

  1. 客户端向服务器发送一个SYN包,其中包含客户端的IP地址和端口号信息。
  2. 服务器接收到SYN包后,向客户端回复一个SYN-ACK包,其中包含服务器的IP地址和端口号信息。
  3. 客户端再向服务器发送一个ACK包,确认建立连接,并携带客户端的IP地址和端口号信息。
    通过这样的交互过程,客户端和服务器就可以互相了解对方的IP地址和端口号信息,从而建立一条可靠的数据传输通道。

5. 那为什么要三次握手呢?两次不行吗?

为了确认双方的 接收能力发送能力 都正常。

如果是用两次握手,则会出现下面这种情况:
如客户端发出连接请求,但因连接请求报文丢失而未收到确认,于是客户端再重传一次连接请求。后来收到了确认,建立了连接。数据传输完毕后,就释放了连接,此时客户端共发出了两个连接请求报文段。
其中第一个丢失,第二个到达了服务端,但是第一个丢失的报文段只是在某些网络节点长时间滞留了,延误到连接释放以后的某个时间才到达服务端,此时服务端误以为客户端又发出一次新的连接请求,于是就向客户端发出确认报文段,同意建立连接,不采用三次握手;只要服务端发出确认,就建立新的连接了。此时客户端忽略服务端发来的确认,也不发送数据,则服务端一直等待客户端发送数据,浪费了资源。

6. http的文本传输和流传输?使用场景

HTTP协议有两种主要数据传输方式:文本传输流传输

  1. 文本传输:这种方式数据作为文本字符串发送,因此易于阅读、解析和处理。同时,这种方式具有一定的可读性,便于诊断错误。主要应用场景是传输小型文本数据,例如通过POST方法提交表单数据。由于文本类型数据通常较小,因此使用文本传更方便和高效。

  2. 流传输:这种方式将数据以2进制流的方式传输,允许客户端和服务器在数据传输过程中即时处理。这一特性对于处理大型文件、下载,二进制图像、视频音频等需求非常实用,在数据体积大、网络环境不稳定且延迟高的情况下表现尤佳。使用流传输可以使数据更快地到达接收方,同时减少网络上的数据传输时间和额外开销。

使用场景:
如果需要传输的数量比较小或需要直接查看或审查数据,则文本传输可能比较合适。相反,如果数据规模较大或者需要自动处理梳理而无详细检查数据,则流传输可能更适宜。

7. HTTP请求报文都有什么组成?

主要由三个部分组成:请求行、请求头和请求体。具体如下:

请求行:包含请求方法URIHTTP协议版本。例如:GET /index.html HTTP/1.1。
请求头(Header): 包含了客户端向服务器发送的附加信息,例如浏览器类型、字符编码、认证信息等。请求头以键值对的形式存在,多个键值对之间以换行符分隔。例如:Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7。
请求体(Body): 存放请求参数,即浏览器向服务器传输数据的实体部分。常用于POST方法提交请求时,发送表单数据、JSON数据等类型的数据。

需要注意的是,并不是所有的HTTP请求都必须带有请求体,像GET请求通常不需要发送请求体。

在这里插入图片描述

为什么 HTTP 报文中要存在 “空行”?
因为 HTTP 协议并没有规定报头部分的键值对有多少个。空行就相当于是 “报头的结束标记”, 或者是 “报头和正文之间的分隔符”。
HTTP 在传输层依赖 TCP 协议, TCP 是面向字节流的. 如果没有这个空行, 就会出现 “粘包问题”

8. HTTP协议各版本的区别

HTTP协议的版本历经多次更新迭代,主要包括 HTTP/1.0HTTP/1.1HTTP/2等版本,它们之间的主要区别如下:

1)HTTP/1.0:

  1. 浏览器与服务器只保持短连接,浏览器的每次请求都需要与服务器建立一个TCP连接,都要经过三次握手,四次挥手。
  2. 由于浏览器必须等待响应完成才能发起下一个请求,造成 “队头阻塞”
    如果某请求一直不到达,那么下一个请求就一直不发送。(高延迟–带来页面加载速度的降低)

2)HTTP/1.1:目前使用最广泛的版本

  1. 支持长连接,通过keep-alive保持HTTP连接不断开,避免重复建立TCP连接。
  2. 管道化传输,通过长连接实现一个TCP连接中同时处理多个HTTP请求;服务器会按照请求的顺序去返回响应的内容,无法存在并行响应。(http请求返回顺序按照服务器响应速度来排序,这里也会引入promise.then 和 async await 来控制接口请求顺序)
  3. 新增了一些请求方法,新增了一些请求头和响应头(如下)
  4. 支持断点续传, 新增 Range 和 Content-Range 头表示请求和响应的部分内容
  5. 加入缓存处理(响应头新字段Expires、Cache-Control)
  6. 增加了Host字段;为了支持多虚拟主机的场景,使用同一个IP地址上可以托管多个域名,访问的都是同一个服务器,从而满足HTTP协议发展所需要的更高级的特性。
  7. 并且添加了其他请求方法:put、delete、options…

缺点:

  1. 队头阻塞
  2. 无状态通信模型(巨大的HTTP头部),也就是服务器端不保存客户端请求的任何状态信息。这样会造成一些需求频繁交互的应用程序难以实现,需要通过其他机制来保证状态的一致性等。
  3. 明文传输–不安全
  4. 不支持服务端推送

3)HTTP/2.0:

  1. 采用二进制格式而非文本格式
  2. 多路复用,在同一个TCP连接上同时传输多条消息;每个请求和响应都被分配了唯一的标识符,称为“流(Stream)”,这样每条信息就可以独立地在网络上传输。
  3. 使用 HPACK 算法报头压缩,降低开销。
  4. 服务器推送,支持服务器主动将相关资源预测性地推送给客户端,以减少后续的请求和延迟。(例如 HTML、CSS、JavaScript、图像和视频等文件)

4)HTTP3.0

是 HTTP/3 中的底层支撑协议,该协议基于 UDP,又取了 TCP 中的精华,实现了即快又可靠的协议。

  1. 运输层由TCP改成使用UDP传输
  2. 队头堵塞问题的解决更为彻底
  3. 切换网络时的连接保持:基于TCP的协议,由于切换网络之后,IP会改变,因而之前的连接不可能继续保持。而基于UDP的QUIC协议,则可以内建与TCP中不同的连接标识方法,从而在网络完成切换之后,恢复之前与服务器的连接
  4. 升级新的压缩算法

9. HTTP状态码的含义

区分状态码
1××开头 - 信息性状态码,表示HTTP请求已被接收,需要进一步处理。
2××开头 - 成功状态码,表示请求已成功处理完成。
3××开头 - 重定向状态码,表示请求需要进一步的操作以完成。
4××开头 - 客户端错误状态码,表示请求包含错误或无法完成。
5××开头 - 服务器错误状态码,表示服务器无法完成有效的请求。

常见状态码
200 - 请求成功,从客户端发送给服务器的请求被正常处理并返回

301 - 表示被请求的资源已经被永久移动到新的URI(永久重定向)
302 - 表示被请求的资源已经被临时移动到新的URI(临时重定向)
304 - 表示服务器资源未被修改;通常是在客户端发出了一个条件请求,服务器通过比较资源的修改时间来确定资源是否已被修改

400 - 服务器不理解请求,请求报文中存在语法错误
401 - 请求需要身份验证
403 - 服务器拒绝请求(访问权限出现问题)
404 - 被请求的资源不存在
405 - 不允许的HTTP请求方法,意味着正在使用的HTTP请求方法不被服务器允许

500 - 服务器内部错误,无法完成请求
503 - 服务器当前无法处理请求,一般是因为过载或维护

关于返回403 Forbidden错误的原因

一开始我以为返回403 Forbidden错误的原因可能与浏览器向DNS服务器发送请求,解析域名返回ip地址,是ip地址不符合访问导致的,于是去寻找答案,了解到解析出的IP地址实际是服务器的IP地址,跟我们计算机上的ipv4无关。下文就是返回403 原因的解释。

返回403 Forbidden错误的原因通常不是DNS解析返回的IP地址与访问不匹配。实际上,当您尝试访问一个网站时,浏览器会首先从 DNS服务器 获取该域名对应的IP地址,并将其用于与服务器建立连接和交换数据。如果域名解析成功且找到了正确的IP地址(服务器地址),但仍然返回403 Forbidden错误,则表示服务端可能禁止了您的访问。
403 Forbidden错误通常是由服务器的访问控制规则、文件权限设置、安全策略等问题引起的。例如,服务器可能禁止您访问某个特定的目录或文件,或者拒绝来自您当前IP地址或浏览器的请求。在这种情况下,您可以通过联系网站管理员或升级您的访问权限来解决此问题。

10. HTTP与HTTPS的区别

先说一下什么是HTTP??HTTP是基于TCP/IP的关于数据如何在万维网中如何通信的协议。

1. 安全性:HTTPS 基于SSL/TLS 协议的 HTTP 协议,通过在传输层加密数据可以提供更高的安全性。相反,HTTP 不提供任何安全保障,明文传输容易被窃听。
2. 加密方式: HTTPS 通过 SSL/TLS 协议使用非对称加密(公钥加密)和对称加密(私钥加密)的结合方式来保护数据。HTTP 传输的数据都是明文的。
3. 连接方式:HTTPS 连接需要经过握手认证,浏览器与服务器之间需要进行一系列的握手和协商才能建立连接,建立连接后收发数据都会加密。而 HTTP 连接是随时可以断开、随时可以建立的。
4. 端口:HTTP 使用 80 端口,HTTPS使用 443 端口。
5. 费用:HTTPS 协议需要到CA申请证书,一般免费证书较少,因而需要一定费用。

综上所述,HTTPS 提供了更高的安全性,适合传输敏感信息的数据,如银行卡信息、用户密码等。而 HTTP 则适合一些不需要保密的信息传输,如浏览某些公开网站,获取新闻资讯等。

11. 介绍一下DNS (DNS 协议是什么?)

DNS服务器通过多层查询将解析域名为IP地址

域名劫持:是指在劫持的网络范围内拦截域名解析的请求,分析请求的域名,把审查范围以外的请求放行,否则返回假的IP地址或者什么都不做使请求失去响应,其效果就是对特定的网络不能访问访问的是假网址


二、浏览器相关

1. 浏览器渲染机制

详细请点击 浏览器渲染机制
浏览器渲染 — 渲染过程讲的很详细 — 很适合学习

1)处理 HTML 并构建 DOM 树。
2)处理 CSS 构建 CSSOM 树(样式树)。
3)将 DOMCSSOM 合并成一个 渲染树
4)计算渲染树中每个节点位置。这个过程会发生回流和重绘。
5)调用 CPU 绘制,合成图层,显示在屏幕上

第4步和第5步是最耗时的部分,这两步合起来,就是我们通常所说的渲染

注意:

1)浏览器工作流程:构建DOM -> 构建CSSOM -> 构建渲染树 -> 布局 -> 绘制。
2)CSSOM会阻塞渲染,只有当CSSOM构建完毕后才会进入下一个阶段构建渲染树。
3)通常情况下DOM和CSSOM是并行构建的,但是当浏览器遇到一个script标签时,DOM构建将暂停,直至脚本完成执行。因为JavaScript可以修改DOM,导致后续HTML资源白白加载,所以需要等DOM构建完毕后再执行JS。
4)如果你想首屏渲染的越快,就越不应该在首屏就加载 JS 文件,建议将 script 标签放在 body 标签底部。

在这里插入图片描述

2. 浏览器在渲染时的两种现象

重排重绘,重排也叫也叫回流。

重排:当 DOM 结构发生变化或者元素样式发生改变时,浏览器需要重新计算元素的几何属性并重新布局,这个过程比较消耗性能。
重绘:指元素的外观样式发生变化(比如改变 color 就叫称为重绘),但是布局没有变,此时浏览器只需要重新绘制元素就可以了,比重排消耗的性能小一些。

重排必定会发生重绘,重绘不一定会引发重排。重排所需的成本比重绘高的多,改变深层次的节点很可能导致父节点的一系列重排

3. 渲染页面时常见哪些不良现象?

由于浏览器的渲染机制不同,在渲染页面时会出现两种常见的不良现象 — 白屏问题FOUS(无样式内容闪烁)

FOUC:由于浏览器渲染机制(比如firefox),在CSS加载之前,先呈现了HTML,就会导致展示出无样式内容,然后样式突然呈现的现象;
白屏:有些浏览器渲染机制(比如chrome)要先构建DOM树和CSSOM树,构建完成后再进行渲染,如果CSS部分放在HTML尾部,由于CSS未加载完成,浏览器迟迟未渲染,从而导致白屏;也可能是把js文件放在头部,脚本会阻塞后面内容的呈现,出现白屏问题。

4. 简单请求和复杂请求

简单请求和复杂请求是指在发送跨域请求时,根据请求方式头部信息等因素区分的两种请求类型。
简单请求:使用常见的GET、POST、HEAD方式中的一种,不包含自定义头部字段,且请求方法不会对服务器状态产生影响。这种请求不需要预检请求(OPTIONS),直接发出即可。
复杂请求:使用常见的请求方式(如PUT、DELETE)或者包含自定义头部字段,且请求方法可能对服务器状态产生影响。这种请求需要向发送预检请求(OPTIONS),已确认服务器是否允许真正的请求。预检请求成功后才能发出真正的请求。

5. get和post的区别

  1. 针对数据操作的类型不同。GET对数据进行查询,POST主要对数据进行增删改!简单说,GET是只读,POST是写。

  2. 参数大小不同。GET请求在URL中传送的参数是有长度的限制,一般在2000个字符;而POST没有限制(GET请求参数的限制是来源与浏览器或web服务器限制了url的长度)

  3. 安全性不同。 GET参数通过URL传递,会暴露,不安全;POST放在Request Body中,相对更安全

  4. 浏览器回退表现不同。 GET在浏览器回退时是无害的,而POST会再次提交请求

  5. 浏览器对请求地址的处理不同 。GET请求地址会被浏览器主动缓存,而POST不会,除非手动设置

  6. 浏览器对响应的处理不同 。GET请求参数会被完整的保留在浏览器历史记录里,而POST中的参数不会被保留

6. 什么叫跨域?什么叫同源策略?

所谓同源策略是浏览器的一种安全机制,来限制不同源的网站不能通信。同源就是域名、协议、端口一
致。
域名、协议、端口有一个不一致就会导致跨域。

7. 如何解决跨域问题?

最初做项目的时候,使用的是 jsonp,但存在一些问题,使用 get 请求不安全,携带数据较小,后来通过了解和学习发现使用 proxy 代理使用比较方便–在开发中使用 proxy,在服务器上使用 nginx 代理,这样开发过程中彼此都方便,效率也高;现在 h5 新特性还有 windows.postMessage()

1)JSONP
ajax 请求受同源策略影响,不允许进行跨域请求,而 script 标签 src 属性中的链接却可以访问跨域的 js 脚本,利用这个特性,服务端不再返回 JSON 格式的数据,而是 返回一段调用某个函数的 js 代码,在 src 中进行了调用,这样实现了跨域。

步骤:

  1. 去创建一个 script
  2. script 的 src 属性设置接口地址
  3. 接口参数,必须要带一个自定义函数名,要不然后台无法返回数据
  4. 通过定义函数名去接受返回的数据
//动态创建 script
var script = document.createElement('script');

// 设置回调函数
function getData(data) {
    
    
    console.log(data);
}

//设置 script 的 src 属性,并设置请求地址
script.src = 'http://localhost:3000/?callback=getData';

// 让 script 生效
document.body.appendChild(script);

缺点:
JSON 只支持 get,因为 script 标签只能使用 get 请求; JSONP 需要后端配合返回指定格式的数据。

2)CORS

使用额外的 HTTP 头来告诉 浏览器 让运行在一个 origin 上的Web应用被准许访问来自不同源服务器上的指定的资源。服务器设置对CORS的支持原理:服务器设置 Access-Control-Allow-Origin HTTP响应头之后,浏览器将会允许跨域请求。

推荐原因
这种方案对于前端来说没有什么工作量,工作量基本都在后端这里。
只要第一次配好了,之后不管有多少接口和项目复用就可以了,一劳永逸的解决了跨域问题,而且不管是开发环境还是正式环境都能方便的使用。
但总有后端觉得麻烦不想这么搞,那纯前端也是有解决方案的。

3)proxy代理 + Nginx

nginx是一款极其强大的web服务器,其优点就是轻量级、启动快、高并发。
跨域问题的产生是因为浏览器的同源政策造成的,但是服务器与服务器之间的数据交换是没有这个限制。

dev 开发模式下可以下使用 webpackproxy 使用也是很方便,参照 proxy配置文档 就会使用了。但这种方法在生产环境是不能使用的。在生产环境中需要使用 nginx 进行反向代理。不管是 proxy 和 nginx 的原理都是一样的,通过搭建一个中转服务器来转发请求规避跨域的问题。

可以通过 vue.config.js 中的 devServer.proxy 选项来配置。新增以下代码

module.exports = defineConfig({
    
    
{
    
    
  devServer: {
    
     //devServer 的意思其实就是通过 webpack 帮你在本地起一个 node 服务器
    proxy: {
    
    
      '/api': {
    
     // '/api'是代理标识,用于告诉node,url前面是 /api 的就是使用代理的
        target: 'http://dnny.net', // 请求的目标地址,一般是指后台服务器地址
        changeOrigin: true, //是否跨域(换源)
        pathRewrite: {
    
     //pathRewrite作用是把实际Request Url中 '/api' 用 ""代替
          '^/api': '' 
        }
      },
      '/foo': {
    
    
        target: '<other_url>'
      }
    }
  }
}
})

假如需要请求的接口url是’http://dnny.net/info’,代理配置成功后,可以在浏览器的开发者工具中发现请求的接口url却是http://localhost:8080/api/info,但实际的请求是http://dnny.net/info。

因为代理服务器会做以下转发:
http://localhost:8080/api/info => http://dnny.net/api/info => http://dnny.net/info

可参考:前端使用proxy解决跨域问题

8. 介绍一下HTTP缓存策略 (强缓存和协商缓存)

HTTP缓存策略缓存的是已经请求过的HTTP资源,包括HTML、CSS、JavaScript文件、图片等。当浏览器第一次请求某个资源时,服务器会返回资源的内容以及相关的缓存控制参数(如缓存过期时间缓存标识符等)。浏览器在接收到这些信息后,会根据缓存策略来判断是否需要缓存该资源,并将其保存到本地缓存中。当下次请求同一个资源时,浏览器可以直接从本地缓存中获取该资源,而无需再向服务器发送请求,从而提高了页面加载速度和用户体验。

浏览器缓存的特点:

  • 浏览器每次发起请求,都会先在浏览器缓存中查找该请求的结果以及缓存标识
  • 浏览器每次拿到返回的请求结果都会将该结果和缓存标识存入浏览器缓存中

根据是否需要向服务器重新发起HTTP请求将缓存过程分为两个部分,分别是强缓存协商缓存

  1. 强缓存:使用强缓存策略时,如果缓存资源在过期时间内,是的话直接从本地缓存中读取资源,不与服务器进行通信。常见的缓存控制字段有Expires和Cache-Control。
  2. 协商缓存:如果强缓存失效后,客户端将向服务器发出请求,进行协商缓存。浏览器携带上一次请求返回的响应头中的 缓存标识 向服务器发起请求(如ETag、Last-Modified等),由服务器判断资源是否更新。如果资源没有更新,则返回状态码 304 Not Modified,告诉浏览器可以使用本地缓存;否则返回新的资源内容。强缓存优先级高于协商缓存,但是协商缓存可以更加灵活地控制缓存的有效性。
  3. 离线缓存:离线缓存可以使网站在没有网络连接的情况下仍然可以访问,他通过将网站的资源存储在本地缓存中,供客户端在没有网络连接时使用。离线缓存需要使用Service Worker来实现。

9. 什么叫内存泄漏?知道哪些会导致内存泄漏?

在javaScript中,内存泄漏指的是程序分配的内存空间因为某些原因而无法被垃圾回收机制正确的释放。这通常是由于代码中持续引用着不需要的对象或者变量,或者存在未及时清除的定时器或者事件监听器等情况所致。如果内存泄漏问题长期存在,会导致浏览器卡顿或者崩溃,影响用户体验。

其他内存泄漏:

  1. 闭包:内部函数引用外部函数作用域的局部变量。

  2. 没有清理定时器或事件监听器:如果定时器或事件监听器没有被正确清理,则会一直占用内存,导致内存泄漏。

  3. 互相引用:如果两个对象相互引用,但是没有其他地方引用它们,那么它们就不能被垃圾收集器回收,导致内存泄漏。

  4. 大量 DOM 元素:如果在页面上创建大量的 DOM 元素,且这些元素没有被正确清理和销毁,可能会导致内存泄漏。

10. 浏览器垃圾回收机制

JavaScript 的垃圾回收机制是自动垃圾回收,它的主要工作就是定期扫描内存中的对象并清除不再使用的对象所占用的内存空间,以避免内存泄漏和浪费。

具体来说,JavaScript 引擎会在变量不再有用时(即没有被任何其他变量或函数引用)将其标记为“可回收”对象。然后,垃圾回收器会定期扫描内存,找到这些可回收对象,并释放他们所占的内存空间。垃圾回收器采用的算法包括标记-清除算法引用计数算法分代回收算法等。

需要注意的是,垃圾回收器只能回收动态分配内存,而不能处理静态分配内存,例如全局变量和闭包等。因此,在编写 JavaScript 代码时,我们应该尽可能避免创建过多的全局变量和闭包,同时及时处理掉不再使用的变量和对象,以便垃圾回收器能够更好的完成垃圾回收工作。

可参考:简单了解 JavaScript 垃圾回收机制
深入理解JavaScript——垃圾回收机制

11. 什么是v8引擎,它的回收机制是什么呢?

先了解下什么是v8引擎。
V8是一种开源的JavaScript引擎,由Google公司开发。它负责将JavaScript代码编译和执行为机器码,并在浏览器(例如Chrome)中高效地运行JavaScript应用程序。

V8引擎垃圾回收机制
V8引擎使用标记-清除算法分代回收策略来实现垃圾回收。

标记-清除算法中,V8会对堆内存中的所有活动对象进行标记,然后清除那些没有被标记的非活动对象

而在分代回收策略中,V8会将堆内存分为新生代老生代两部分,新生代中的对象生命周期短暂,容量只有1~8M;因此采用基于Scavenge算法的标记-复制方式;新生代内存回收频率很高,速度也很快,但是空间利用率很低,因为有一半的内存空间处于"闲置"状态。老生代中的对象寿命较长,因此采用基于Mark-Sweep算法Mark-Compact算法的混合方式进行回收。前者标记并清除非活跃对象,后者在清除之后进行空间整理(到一边),这样空间就大了。通过这些技术,V8可以高效地回收不再使用的内存,从而提高程序性能和稳定性。

新生代垃圾回收(副垃圾回收器):
【Scavenge算法】

在这里插入图片描述

  • 把新生代空间对半划分为两个区域,一半是对象区域(from),一半是空闲区域 (to)
  • 新的对象会首先被分配到对象(from)空间,当对象区域快写满时,就需要执行一次垃圾清理操作。
  • 当进行垃圾回收的时候,先将 from 空间中的 存活的对象 复制空闲(to)空间进行保存,对未存活的对象空间进行回收。
  • 复制完成后, from 空间和 to 空间进行调换,to 空间会变成新的 from 空间,原来的 from 空间则变成 to 空间。这样就完成了垃圾对象的回收操作,同时这种角色调换的操作能让新生代中的这两块区域无限重复使用下去。

老生代垃圾回收(主垃圾回收器):

为了执行效率,一般新生区的空间会设置的比较小,所以JavaScript引擎采用了 对象晋升策略(两次垃圾回收依然存活的对象,会被放到老生区中)

老生代区的对象包括新生代区“晋升”的对象和一些大的对象。因此老生代区中的对象有两个特点:对象占用空间大,对象存活时间长

【垃圾回收过程:标记 - 清除 - 整理(Mark-Sweep算法 和 Mark-Compact算法)】

原理:

  • 递归遍历这组根元素,标记垃圾数据。
  • Mark-Sweep算法 标记活跃对象并清除非活跃对象。
  • Mark-Compact算法 清除标记后产生大量不连续内存,需要进行空间整理(到一边),这样空间就大了。

总结 - 新生代 VS 老生代

1.新生代垃圾回收是临时分配的内存,存活时间短;老生代垃圾回收是常驻内存,存活时间长
2.新生代垃圾回收由副垃圾回收器负责;老生代垃圾回收由主垃圾回收器负责
3.新生代采用 Scavenge 算法;老生代采用「标记-清除-整理」算法
1)Scavenge 算法:将空间分为两半,一半是 from 空间,一半是 to 空间。新加入的对象会放在 from 空间,当空间快满时,执行垃圾清理;再角色调换,再当调换完后的 from 空间快蛮时,再执行垃圾清理,如此反复。
2)标记-清理-整理:此为两个算法,「标记-清理」算法和 「标记-整理」算法
标记-清理:标记活动对象,清除非活跃对象
标记-整理:清理完内存后,会产生不连续的内存空间,为节省空间,整理算法会将内存排序到一处空间,空间就变大了

可参考:V8内存管理及垃圾回收机制
深入理解JavaScript——垃圾回收机制

12. cookie和session 的区别

  1. cookie数据存放在客户的浏览器上,session数据放在服务器上。
  2. cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗
    考虑到安全应当使用session。
  3. session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能
    考虑到减轻服务器性能方面,应当使用COOKIE。
  4. 单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。
  5. 所以个人建议:

将登陆信息等重要信息存放为 session
其他信息如果需要保留,可以放在 cookie 中

13. cookie、sessionStorage和localStorage的区别和使用场景

相同点:

  • 存储在客户端

不同点:

1)与服务器交互

  • cookie 是网站为了标示用户身份而储存在用户本地终端上的数据(通常经过加密)

  • cookie 始终会在同源 http 请求头中携带(即使不需要),在浏览器和服务器间来回传递

  • sessionStorage 和 localStorage 不会自动把数据发给服务器,仅在本地保存

    2)存储大小

  • cookie 数据根据不同浏览器限制,大小一般不能超过 4k

  • sessionStorage 和 localStorage 虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大

    3)有效时间

  • localStorage 存储持久数据,浏览器关闭后数据不丢失除非主动删除数据

  • sessionStorage 数据在当前浏览器窗口关闭后自动删除

  • cookie 设置的cookie过期时间之前一直有效,与浏览器是否关闭无关

应用场景:

  • 标记用户与跟踪用户行为的情况,推荐使用 cookie
  • 适合长期保存在本地的数据(令牌),推荐使用 localStorage
  • 敏感账号一次性登录,推荐使用 sessionStorage

14. 浏览器常见的攻击方式,存在的原因、防御的方法?

攻击方式:XSS跨站脚本攻击(Cross Site Scripting)、 CSRF跨站请求伪造( Cross-site request forgery )

XSS(跨站脚本攻击)是一种代码注入攻击。攻击者在目标网站上注入恶意代码,当用户登陆网站时就会执行这些恶意代码,这些脚本可以读取 Cookie、SessionID,或者其它敏感的网站信息。比如在 (url 中输入、在评论框中输入),向你的页面注入脚本(可能是 js、hmtl 代码块等)。

存在的原因:

浏览器为了在安全和自由之间找到一个平衡点。支持了页面中的引用第三方资源和 跨域资源共享(CORS),这样做带来了很多安全问题,其中最典型的就是 XSS 攻击。

危害:

1.监听用户行为:可以使用“addEventListener”接口来监听键盘事件
2. 修改 DOM: 以通过修改 DOM 伪造假的登录窗口,用来欺骗用户输入用户名和密码等信息

CSRF(跨站请求伪造:攻击者诱导用户进入第三方网站,在第三方网站中,向被攻击网站发送跨站请求。利用用户在被攻击网站已经获取的注册凭证,绕过后台的用户验证,达到冒充用户对被攻击的网站执行某项操作的目的。例如转账、修改密码等。而且CSRF 攻击并不需要将恶意代码注入用户的页面,仅仅是利用服务器的漏洞和用户的登录状态来实施攻击

存在的原因:

利用了web中用户身份验证的一个漏洞:简单的身份验证只能保证请求发自某个用户的浏览器,却不能保证请求本身是用户自愿发出的。

XSS避免方式:

  1. 前端对用户输入的数据进行过滤或转码,后端同样也需要对用户提交的数据进行严格的验证和过滤。
  2. 在cookie中设置HttpOnly属性后,js脚本将无法读取到cookie信息

CSRF避免方式:

  1. 使用token验证,确保请求来自登录站点。token 验证的 CSRF 防御机制是公认最合适的方案
  2. 请求头中的referer 验证,验证页面来源。此种方法成本最低,但是并不能保证 100% 有效,因为服务器并不是什么时候都能取到 Referer,而且低版本的浏览器存在伪造 Referer 的风险。
  3. 禁止以 GET 形式提交数据,只允许 POST 请求,因为 GET 请求可被缓存、预取,并被表单历史纪录保留。

15. CSRF 和 XSS 的区别

区别一:

  • CSRF :需要用户先登录网站 A ,获取 cookie
  • XSS :不需要登录。

区别二:(原理的区别)

  • CSRF :是利用网站 A 本身的漏洞,去请求网站 Aapi
  • XSS :是向网站 A 注入 JS 代码,然后执行 JS 里的代码,篡改网站 A 的内容。

区别三:攻击的目标不同

  • CSRF 攻击的目标是应用程序
  • XSS 攻击的目标是用户

本质上讲,XSS 是代码注入问题,CSRF 是 HTTP 问题。 XSS 是内容没有过滤导致浏览器将攻击者的输入当代码执行。CSRF 则是因为浏览器在发送 HTTP 请求时候自动带上 cookie,而一般网站的 session 都存在 cookie里面(Token验证可以避免)。

可参考:
XSS 攻击和 CSRF 攻击各自的原理是什么?两者又有什么区别?以及如何防范?
XSS攻击与CSRF攻击

16. 对虚拟DOM的理解和优缺点?

虚拟DOM的实现原理与优缺点

理解

虚拟 DOM 就是为了解决浏览器性能问题而被设计出来的
它是将整个页面抽象为一个 JavaScript 对象树(虚拟DOM),当状态变更的时候,重新构造一棵新的对象树。然后用新的树和旧的树进行比较,记录两棵树差异把所记录的差异应用到真正的 dom 树上,视图就更新了。利用DOM diff算法减少不必要的DOM操作和页面重绘,提高性能和用户体验。

虚拟DOM也可以方便实现组件化开发,使得前端代码更具可维护性和可复用性。

优点

1)快速渲染:虚拟 DOM 可以直接操作 JavaScript 对象,无需访问真实浏览器的 DOM。
2)减少不必要的 DOM操作:虚拟 DOM 通过 diff 算法比较前后两个状态的差别,只更新需要改变的部分,减少大量不必要的 DOM 操作,提升性能。
3)跨平台:虚拟 DOM 不依赖具体的浏览器实现,可以在不同的平台上使用,例如服务器渲染,移动端开发等。
4)提高开发效率:虚拟 DOM 可以简化组件的编写和维护,开发效率提高。

缺点

1)需要额外的内存开销:虚拟 DOM 需要创建一颗以 JavaScript 对象表示的虚拟 DOM 树,在一些场景下可能会占用过多的内存。
2)性能瓶颈:虚拟 DOM 在一些复杂场景下可能会导致性能瓶颈,例如大量的列表渲染、频繁的样式变化等。

17. 操作虚拟DOM真的比真实DOM方便吗?

很多人说虚拟dom操作回避原生dom更快,也不全面。比如,首次渲染或者所有节点都需要进行更新的时候,这个时候采用虚拟dom会比直接操作原生dom多一层构建虚拟dom的动作,会占用更多的内存以及延长渲染时间。
总之,

  • 虚拟DOM不一定会比操作原生DOM更快。
  • 虚拟DOM的优势在于节点进行改动的时候尽量减少开销。
  • 我们用vue等框架的本质是提升开发效率,让我们的注意力更集中于数据;我们使用框架做出的一切行为,都会被框架转化为对原生dom的操作。

可参考:虚拟dom比真实dom还快吗?90%回答掉坑里了


三、Ajax相关

1. 什么是ajax?

Ajax是全称是Asynchronous JavaScript and XML,即异步JavaScript和xml,用于在Web页面中实现异步数据交互,实现页面局部刷新

2. ajax原理??(创建ajax过程??)

1)创建一个XMLHttpRequest对象,用于向服务器发送请求和接收响应。
2)设置XHR对象的callback函数,该函数会在服务器响应返回后被调用。
3)使用XHR对象发送请求,并传递必要的参数(如请求的URL、请求类型、请求头、请求体等)
4)callback函数中处理服务器响应,通常是解析响应数据并更新网页内容。

以下是一个使用jQuery的Ajax示例代码:

$.ajax({
    
    
  url: "example.com/data",
  type: "GET",
  dataType: "json",
  success: function(data) {
    
    
    // 处理响应数据
  },
  error: function(jqXHR, textStatus, errorThrown) {
    
    
    // 处理请求错误
  }
});
// 该代码会向"example.com/data"发送一个GET请求,请求数据类型为JSON。
// 当服务器响应成功返回时,success函数会被调用,可以在该函数中处理响应数据。
// 如果请求出现错误,error函数会被调用,可以在该函数中处理错误情况。

总结一句话就是:
创建一个XHR对象,并发送异步请求,接着监听服务器响应结果,并把它渲染在页面上

3. ajax优缺点?

优点:

  1. 提升用户体验:可以在不刷新整个页面的情况下更新部分内容(局部内容更新),可以更快、更流畅的浏览网页
  2. 减少服务器负载:由于ajax只更新部分内容,因此可以减少服务器的负载和带宽消耗,提高网站性能和可扩展性
  3. 支持异步通信:支持异步通信,可以在后台向服务器发送请求,不打断用户的操作
  4. 界面和应用相分离(ajax将界面和应用分离也就是数据与呈现相分离)

缺点:

  1. 对搜索引擎不友好:由于ajax动态更新页面内容,搜索引擎可能无法索引所有内容,影响网站SEO效果。
  2. 安全问题: 由于ajax可以向服务器发送异步请求,可能会导致跨站点脚本攻击(XXS)和跨站点请求伪造(CSRF)等安全性问题。
  3. 对浏览器兼容性要求高:不同浏览器对ajax的支持程度不同,需要编写兼容多种浏览器的代码。
  4. 可维护性差:由于ajax将数据和处理逻辑分散在多个文件中,代码结构复杂,可维护性较差。
  5. 难以调试:由于ajax是异步通信,调试时可能需要使用特殊工具和技术,难度较大。

持续更新中。。。

猜你喜欢

转载自blog.csdn.net/weixin_45811256/article/details/129692811