前端面试题详解整理106|大数减法,get,post,fps,定义一个组件查看网络请求,typescript,状态码301,302,403的含义,

124 阅读20分钟

11. 开发中如何查看网络请求

在开发中,可以通过多种方式查看网络请求,具体取决于所使用的开发工具和环境。以下是一些常用的方法:

  1. 浏览器开发者工具:现代浏览器都提供了内置的开发者工具,可以通过查看网络面板来监视和分析页面上的网络请求。常见的浏览器开发者工具包括 Chrome DevTools、Firefox 开发者工具、Safari 开发者工具等。

  2. 网络抓包工具:使用网络抓包工具可以捕获计算机上所有的网络数据包,进而分析 HTTP 请求和响应。常见的网络抓包工具包括 Wireshark、Fiddler、Charles 等。

  3. 代理工具:一些代理工具可以拦截浏览器和服务器之间的网络通信,允许开发者查看和修改请求和响应数据。常见的代理工具包括 Charles、Fiddler、Mitmproxy 等。

  4. 前端监控工具:一些前端监控工具可以实时监视网页的网络请求,并提供可视化的界面来展示请求的详细信息。常见的前端监控工具包括 Sentry、TrackJS、New Relic 等。

  5. 命令行工具:一些命令行工具可以通过命令行界面来查看网络请求,例如 cURL、HTTPie 等。

根据实际需求和个人偏好,选择适合自己的工具和方法来查看网络请求,有助于快速定位和解决开发过程中遇到的问题。

3. 项目开发中用过哪些 ts 特性

在项目开发中,使用 TypeScript(TS)时可以利用许多强大的特性来提高代码质量和开发效率。以下是一些常用的 TypeScript 特性:

  1. 静态类型检查:TypeScript 提供了静态类型检查,可以在编译时发现类型相关的错误,避免在运行时出现类型不匹配的问题。

  2. 类型注解:通过为变量、函数参数和返回值等添加类型注解,可以明确指定它们的类型,提高代码的可读性和可维护性。

  3. 接口和类型别名:可以使用接口和类型别名来定义自定义的数据类型,提高代码的抽象程度和可复用性。

  4. 泛型:TypeScript 支持泛型编程,允许编写可复用的代码,以适应不同类型的数据。

  5. 枚举:可以使用枚举类型来定义一组命名的常量,使代码更加清晰和易于理解。

  6. 可选属性和默认参数:可以在接口定义和函数参数中使用可选属性和默认参数,使代码更加灵活和健壮。

  7. 访问修饰符:可以使用 public、private 和 protected 等访问修饰符来控制类成员的可访问性,提高代码的安全性。

  8. 模块化:TypeScript 支持使用模块化的方式组织代码,可以使用 import 和 export 关键字导入和导出模块。

  9. 装饰器:可以使用装饰器来添加元数据和功能,例如日志、性能监控等,使代码更加灵活和可扩展。

  10. 类型推断:TypeScript 可以根据上下文推断变量和函数的类型,减少了手动添加类型注解的工作量。

这些特性使得 TypeScript 成为了在大型项目中开发的首选语言之一,能够提供更好的开发体验和代码质量。

3. 状态码 301/302/403 含义

  • 301 Moved Permanently (永久重定向):请求的资源已被永久移动到新位置,并且将来任何对该资源的引用都应该使用新的 URL。客户端应该自动向新的 URL 发起请求。这个响应状态码经常被搜索引擎用来更新它们的链接。

  • 302 Found (临时重定向):请求的资源临时移动到了新的 URL。客户端应该继续使用原有的 URL。这个响应状态码是 HTTP/1.0 中引入的,被认为存在一些问题。因此,HTTP/1.1 引入了 303 和 307 状态码来替代。

  • 403 Forbidden (禁止访问):服务器理解客户端的请求,但拒绝执行它。通常,这是由于服务器没有权限处理请求而导致的。这可能是由于服务器知道客户端是未经授权的或者没有权限访问请求的资源。

3. package.json 作用与常见字段含义

  1. package-lock.json 作用

package.json 是 Node.js 项目的配置文件,用于描述项目的元信息和依赖信息。其中常见字段的含义包括:

  1. name:项目的名称,必须是唯一的。
  2. version:项目的版本号,遵循语义化版本规范。
  3. description:项目的描述信息。
  4. main:指定项目的入口文件。
  5. scripts:定义一系列可执行的脚本命令,通常用于项目的构建、测试、运行等任务。
  6. dependencies:项目的生产依赖,指定项目运行时所依赖的包。
  7. devDependencies:项目的开发依赖,指定项目开发时所依赖的包。
  8. author:项目的作者信息。
  9. license:项目的许可证信息。

package-lock.json 是 npm 5+ 引入的锁定文件,用于记录项目依赖包的精确版本信息。它的作用包括:

  • 锁定项目依赖的精确版本,确保在不同的开发环境中安装的依赖版本一致。
  • 提供给其他开发者或构建系统使用,确保安装的依赖版本与开发者本地的一致。
  • 加速依赖安装过程,避免重复解析依赖树和下载依赖包。

总的来说,package-lock.json 的作用是确保项目依赖的一致性和稳定性,并提高依赖安装的效率。

3. node 模块解析机制

Node.js 模块解析机制是指 Node.js 在引入模块时如何查找模块文件并加载的过程。Node.js 的模块解析机制主要包括以下几个步骤:

  1. 核心模块(Built-in Modules):首先检查模块是否为 Node.js 的核心模块,核心模块是编译进 Node.js 可执行文件中的模块,可以直接通过模块名称引入,例如 require('fs')

  2. 文件模块:如果模块不是核心模块,Node.js 将按照一定的规则从文件系统中查找模块文件。具体步骤如下:

    • 根据模块标识(文件路径或模块名称)确定模块的绝对路径。
    • 如果模块标识是相对路径(以 ./../ 开头),则相对于当前文件的目录解析模块的绝对路径;如果模块标识是绝对路径(以 / 开头),则直接使用该路径。
    • 如果模块标识不包含文件后缀(如 .js.json.node),则按照一定的优先级依次尝试添加后缀查找对应的文件。
    • 如果模块标识指定的路径是一个目录,则按照一定的规则查找该目录下的 package.json 文件,并根据其中的 main 字段指定的文件名作为模块的入口文件。
    • 如果模块标识指定的路径是一个目录,且不存在 package.json 文件或者 main 字段未指定,则按照一定的规则查找该目录下的 index.jsindex.jsonindex.node 文件作为模块的入口文件。
  3. 模块缓存:Node.js 在加载模块后会将模块缓存起来,下次再次加载相同模块时会直接从缓存中获取,避免重复加载和解析模块,提高了性能。

这种模块解析机制使得 Node.js 能够方便地管理模块依赖,使得模块化开发更加灵活和高效。

5. FPS 帧率的概念 ❌

FPS 指的是 Frames Per Second,即每秒帧数。在视频、游戏和动画等场景中,FPS 表示每秒钟图像帧数的数量,也就是屏幕每秒更新的次数。

在视觉上,FPS 较高的情况下,动画和视频看起来会更加流畅、自然。一般来说,人眼可以感知到的最佳帧率是 60 FPS,但是在某些情况下,更高的帧率可能会提供更好的体验,特别是对于需要更高精度和更快响应的应用程序。

在网页开发中,通常会关注页面的渲染性能,其中 FPS 是一个重要的指标之一。如果页面的 FPS 较低,可能会导致页面动画卡顿、用户交互不流畅等问题。因此,优化页面性能以提高 FPS 是网页开发中常见的任务之一。

7. Vue 中如何定义一个组件(没搞懂这个问题的意思,只回答了 SFC

在 Vue 中,可以使用单文件组件 (SFC) 或者通过 JavaScript 对象的方式定义组件。

使用单文件组件 (SFC) 定义一个组件通常包括三个部分:模板 (template)、脚本 (script) 和样式 (style)。例如:

<template>
  <div>
    <h1>{{ title }}</h1>
    <p>{{ content }}</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      title: 'Hello World',
      content: 'This is a Vue component.'
    };
  }
};
</script>

<style>
h1 {
  color: blue;
}
p {
  font-size: 16px;
}
</style>

如果不使用单文件组件,也可以直接在 JavaScript 中定义组件。例如:

Vue.component('my-component', {
  template: `
    <div>
      <h1>{{ title }}</h1>
      <p>{{ content }}</p>
    </div>
  `,
  data() {
    return {
      title: 'Hello World',
      content: 'This is a Vue component.'
    };
  }
});

无论是哪种方式,定义的组件都可以在其他组件中通过标签的形式引用和使用。

8. 常用 Vue 指令

  1. Vue3 中的 setup 函数具有什么作用?

常用 Vue 指令有:

  1. v-bind:用于动态绑定 HTML 属性。
  2. v-model:用于在表单元素和 Vue 实例的数据之间双向绑定。
  3. v-if:根据表达式的值条件性地渲染元素。
  4. v-for:基于数组或对象的值循环渲染元素。
  5. v-on:用于监听 DOM 事件,并触发 Vue 实例中定义的方法。
  6. v-show:根据表达式的值条件性地显示或隐藏元素,通过改变 CSS 的 display 属性。
  7. v-text:更新元素的文本内容。
  8. v-html:更新元素的 HTML 内容,会导致 XSS 漏洞风险,谨慎使用。

Vue3 中的 setup 函数是 Composition API 的核心函数,具有以下作用:

  1. 设置组件的初始状态。
  2. 注册响应式数据。
  3. 注册计算属性(computed)。
  4. 注册监听器(watch)。
  5. 注册事件处理函数。
  6. 注册生命周期钩子。
  7. 返回组件的模板渲染所需的数据、方法等。

通过 setup 函数,可以更灵活地组织和管理组件的逻辑,使得组件的代码更加清晰易读,提高了代码的可维护性和可复用性。\

  1. 算法:大数减法

大数减法是指针对超过计算机存储位数限制的大整数进行减法运算。在实现大数减法时,一般会采用模拟手工计算的方法,从个位开始逐位相减,并考虑借位的情况。

以下是大数减法的基本步骤:

  1. 将两个大整数从个位开始对齐。
  2. 从最低位(个位)开始逐位相减,如果被减数小于减数,则需要向高位借位。
  3. 对于每一位的相减,如果被减数小于减数,则需要向高位借位。借位操作会影响到高位数字的减法结果。
  4. 最后得到的结果即为两个大整数的减法结果。

实现大数减法时,需要注意处理借位和进位的情况,以及处理结果中的前导零。

以下是一个示例的大数减法的实现(JavaScript):

function bigNumberSubtraction(num1, num2) {
    // 将字符串形式的大整数转换为数组,逆序存储
    let arr1 = num1.split('').reverse();
    let arr2 = num2.split('').reverse();
    let result = []; // 存储结果的数组
    let borrow = 0; // 借位初始化为0

    // 从个位开始逐位相减
    for (let i = 0; i < Math.max(arr1.length, arr2.length); i++) {
        // 将字符转换为数字,如果不存在则设为0
        let digit1 = parseInt(arr1[i]) || 0;
        let digit2 = parseInt(arr2[i]) || 0;
        
        // 减去借位
        digit1 -= borrow;
        
        // 如果被减数小于减数,则向高位借位
        if (digit1 < digit2) {
            digit1 += 10; // 借10
            borrow = 1; // 设置借位标志
        } else {
            borrow = 0; // 清除借位标志
        }

        // 计算当前位的减法结果并存入结果数组
        result.push(digit1 - digit2);
    }

    // 去除结果数组末尾的多余的0
    while (result.length > 1 && result[result.length - 1] === 0) {
        result.pop();
    }

    // 将结果数组逆序并转换为字符串形式的结果
    return result.reverse().join('');
}

// 示例
let num1 = '12345678901234567890';
let num2 = '9876543210123456789';
console.log(bigNumberSubtraction(num1, num2)); // 输出:11469135691111111101

这是一个简单的大数减法的实现,实际应用中可能还需要考虑更多的边界情况和优化。

  1. Github 仓库中的 qq 机器人项目做了什么

12. get 与 post 请求的区别

GET和POST是HTTP协议中最常见的两种请求方法,它们之间有以下几个区别:

  1. 参数传递方式

    • GET请求的参数是通过URL传递的,即参数会附加在URL的末尾,形成类似http://example.com/resource?key1=value1&key2=value2的形式。
    • POST请求的参数是通过HTTP请求体传递的,参数不会直接暴露在URL中,而是作为请求体的一部分发送给服务器。
  2. 数据大小限制

    • GET请求的数据大小受到URL长度的限制,因为URL的长度是有限制的,不同浏览器和服务器对URL长度的限制可能有所不同,一般来说在2KB到8KB之间。
    • POST请求的数据大小一般没有固定限制,但是受到服务器和客户端设置的最大请求体大小限制。
  3. 请求语义

    • GET请求用于向服务器请求获取资源,通常用于获取数据,例如获取网页、图片、文件等。
    • POST请求用于向服务器提交数据,通常用于提交表单数据、上传文件等操作。
  4. 数据安全性

    • GET请求的参数在URL中明文传输,因此不适合传输敏感信息,如密码等。
    • POST请求的参数在请求体中传输,相对于GET请求更安全,适合传输敏感信息。
  5. 缓存机制

    • GET请求可以被浏览器缓存,因为它的请求参数在URL中,浏览器可以根据URL来缓存响应结果。
    • POST请求默认情况下不会被浏览器缓存,因为POST请求的响应结果可能与请求参数有关,且不同的POST请求可能会产生不同的结果,因此不适合被缓存。

总的来说,GET请求适用于获取资源,参数传递简单,但安全性和数据大小有限制;POST请求适用于提交数据,参数传递安全,数据大小没有固定限制,但相对于GET请求会增加服务器的负载。

13. https 的加密过程(TLS 四次握手)

TLS(Transport Layer Security)协议是保证网络通信安全的一种协议,它的加密过程包括以下几个步骤:

  1. 客户端发送加密算法支持列表和随机数给服务器端

    • 客户端发送一个ClientHello消息给服务器端,该消息包含了客户端支持的加密算法列表、TLS版本信息和一个随机数。
    • 这个随机数将用于生成会话密钥,用于后续通信的对称加密。
  2. 服务器端确认加密算法并返回自己的公钥、数字证书和随机数给客户端

    • 服务器端接收到ClientHello消息后,从中选择一个加密算法,然后生成自己的随机数。
    • 服务器端返回一个ServerHello消息给客户端,该消息包含了服务器端选择的加密算法、数字证书和一个随机数。
  3. 客户端验证服务器的数字证书并生成会话密钥

    • 客户端收到服务器端的ServerHello消息后,首先验证服务器端的数字证书是否有效,包括验证证书的合法性、颁发机构的信任链等。
    • 如果验证通过,客户端使用服务器端的公钥加密一个会话密钥,并发送给服务器端。
  4. 服务器端接收会话密钥,使用自己的私钥解密,然后生成会话密钥

    • 服务器端收到客户端发送的加密的会话密钥后,使用自己的私钥解密得到会话密钥。
    • 接着,客户端和服务器端就使用这个会话密钥来进行后续的通信,包括对称加密、消息认证和完整性验证等。
  5. 客户端和服务器端交换加密通信

    • 客户端和服务器端使用之前协商好的加密算法和会话密钥进行通信,保证通信的机密性、完整性和可靠性。

这个过程称为TLS握手(Handshake),在完成握手之后,客户端和服务器端就可以安全地进行加密通信了。TLS握手过程中涉及到的加密算法、数字证书等信息,都是为了保证通信的安全性和可信度。

  1. TSL 加密过程是比较消耗性能的,对于 QQ 这样的大型应用,有没有什么好的方案可以优化

对于大型应用如 QQ,优化 TLS 加密过程的方式有以下几种:

  1. 使用更快的加密算法:选择更高效的加密算法可以提高 TLS 加密的速度。例如,替换 RSA 加密算法为 ECC(椭圆曲线加密算法)可以减少加密运算的复杂度,提高性能。

  2. 启用会话重用:TLS 会话重用可以减少重复的握手过程,降低加密过程的开销。通过在服务器端启用 TLS 会话重用,客户端可以在多次连接中重复使用相同的会话密钥,从而减少握手的次数。

  3. 使用硬件加速:利用专用的硬件加速模块(如 SSL 加速卡)可以提高 TLS 加密的性能。这些硬件模块具有专门优化的加密引擎,可以在硬件级别上执行加密和解密操作,比软件实现更快速。

  4. 优化 TLS 协议参数:调整 TLS 协议的参数和配置,例如增大密钥交换时的 Diffie-Hellman 参数长度、优化加密套件的选择等,可以提高 TLS 加密的效率和性能。

  5. 使用 CDN 和负载均衡:通过将 TLS 终端部署在 CDN 和负载均衡器等高性能设备上,可以分担加密过程的负载,提高整体的加密性能。

  6. 缓存公共密钥:为了减少密钥交换的计算开销,可以在客户端和服务器端缓存公共密钥。这样可以避免重复计算密钥交换过程中的复杂运算,提高握手速度。

综合使用这些优化方法,可以有效地提升大型应用中 TLS 加密过程的性能和效率,减少对系统资源的消耗,提升用户体验。

15. Web 安全:XSS 攻击与 SQL 注入

Web 安全中的两个常见威胁是 XSS(跨站脚本攻击)和 SQL 注入(SQL Injection)。

  1. XSS 攻击

    • XSS 攻击是指攻击者通过在 Web 页面中注入恶意脚本,从而在用户的浏览器中执行恶意代码的一种攻击方式。
    • 攻击者可以利用 XSS 攻击窃取用户的 Cookie、会话信息,甚至篡改页面内容,进行钓鱼等恶意行为。
    • XSS 攻击分为存储型 XSS、反射型 XSS 和 DOM 型 XSS 三种类型,分别对应着攻击者通过存储恶意代码、通过 URL 参数等传递恶意代码以及通过操作 DOM 对页面进行攻击。
  2. SQL 注入

    • SQL 注入是指攻击者通过在 Web 应用的输入参数中注入 SQL 代码,从而执行恶意的 SQL 查询,进而对数据库进行非法操作的一种攻击方式。
    • 攻击者可以通过 SQL 注入获取敏感数据、删除数据库中的数据,甚至完全控制整个数据库。
    • SQL 注入通常发生在 Web 应用中对用户输入数据没有进行充分过滤和验证的情况下,攻击者可以在输入框中输入恶意的 SQL 语句,然后执行。

为了防范 XSS 攻击和 SQL 注入等安全威胁,Web 开发者可以采取一些防御措施,例如:

  • 对用户输入数据进行合适的过滤和验证,避免恶意输入的注入。
  • 使用安全的编程语言和框架,并及时更新和修补安全漏洞。
  • 使用安全的密码存储方式,并定期更新密码。
  • 对敏感数据进行加密存储,确保数据的安全性。
  • 对于 XSS 攻击,可以采用输入转义、使用 Content Security Policy(CSP)等方式进行防御。
  • 对于 SQL 注入,可以使用参数化查询、ORM 框架等方式进行防御。

通过采取这些安全措施,可以有效地提高 Web 应用的安全性,防范各种潜在的安全威胁。\

16. Vue2 与 Vue3 响应式原理的区别

Vue2 和 Vue3 的响应式原理在实现上有一些区别:

  1. Proxy vs. Object.defineProperty:

    • Vue2 使用了 Object.defineProperty 来劫持对象的属性,从而实现响应式。这种方式存在一些限制,例如无法监听属性的添加和删除,需要在初始化时就定义好。
    • Vue3 则使用了 ES6 中的 Proxy 对象来代理对象,可以更灵活地监听对象的操作,包括属性的添加、删除和修改,以及数组的变化。这使得 Vue3 的响应式系统更加强大和灵活。
  2. 性能优化:

    • Vue3 的响应式系统相比 Vue2 更加高效。Vue3 在内部实现上进行了许多优化,如使用了懒代理、缓存了属性的代理等,提升了性能并减少了不必要的代理开销。
  3. Composition API:

    • Vue3 引入了 Composition API,它更加灵活和强大,可以更方便地组织和管理组件的逻辑代码。在 Composition API 中,可以使用 reactiveref 等函数来创建响应式数据,而不仅仅局限于组件实例上。
  4. Tree-Shaking:

    • Vue3 的模块系统和代码结构更加清晰,采用了 Tree-Shaking 技术,可以更好地消除未使用的代码,减小项目的体积。

总的来说,Vue3 的响应式原理相比 Vue2 更加先进和高效,使得 Vue3 在性能、灵活性和开发体验上都有了显著的提升。

今天最为酣畅淋漓的一场面试,几乎打穿了我的知识储备😭

#腾讯实习##前端实习#