首页 > 其他分享 >前端面试必修--面试八股文(根据本人面试经验总结,持续更新)

前端面试必修--面试八股文(根据本人面试经验总结,持续更新)

时间:2024-07-16 21:03:16浏览次数:10  
标签:必修 浏览器 请求 -- 认证 面试 缓存 使用 客户端

前端八股

目录

掘金大佬总结的八股文,里面有各个板块的链接:

前端铜九铁十面试必备八股文——HTML&CSS - 掘金 (juejin.cn)

下面是我自己总结的内容,内容可能不全,主要是为了应付面试:

webpack和vite之间的区别

优点:
  • webpack由于其丰富的功能和扩展性,适合于大型、复杂的项目。而vite凭借其轻量和速度,更适合于中小型项目和快速原型开发。
  • 更快的冷启动:Vite 借助了浏览器对 ESM 规范的支持,采取了与 Webpack 完全不同的 unbundle 机制
  • 更快的热更新:Vite 采用 unbundle 机制,所以 dev server 在监听到文件发生变化以后,只需要通过连接通知浏览器去重新加载变化的文件,剩下的工作就交给浏览器去做了。
  • Vite相比于Webpack而言,没有打包的过程,而是直接启动了一个开发服务器devServer。Vite劫持浏览器的HTTP请求,在后端进行相应的处理将项目中使用的文件通过简单的分解与整合,然后再返回给浏览器(整个过程没有对文件进行打包编译)。所以编译速度很快。
缺点:
  • 开发环境下首屏加载变慢:由于 unbundle 机制,Vite 首屏期间需要额外做其它工作。不过首屏性能差只发生在 dev server 启动以后第一次加载页面时发生。之后再 reload 页面时,首屏性能会好很多。原因是 dev server 会将之前已经完成转换的内容缓存起来
  • 开发环境下懒加载变慢:跟首屏加载变慢的原因一样。Vite 在懒加载方面的性能也比 Webpack 差。由于 unbundle 机制,动态加载的文件,需要做 resolve、load、transform、parse 操作,并且还有大量的 http 请求,导致懒加载性能也受到影响。
  • webpack支持的更广。由于 Vite 基于ES Module,所以代码中不可以使用CommonJs;webpack更多的关注兼容性, 而Vite 关注浏览器端的开发体验。Vite目前生态还不如 Webpack。

1、前端工程化解决的问题

1.为什么需要前端工程化?

前端技术发展更新快,一些大型前端项目需要更系统化、更规范化的去组织开发工作;以此来提高对项目的开发效率,减少维护成本。

  1. 统一的开发规范 => 提高代码质量,减少维护成本
  2. 统一的文件组织结构 => 清新美观的目录结构,便于定位问题
  3. 统一的的模块依赖 => 相同依赖直接复用,不需要每次新建项目都copy
  4. 统一的工具配置 => 相同配置直接复用,发布、打包、上传等工作自动化
  5. 统一的基础代码 => 相同代码直接复用,不需要每次新建项目都copy

2.前端工程化解决的问题:

传统的前端开发方式存在一些问题,为了提升整体开发效率并降低代码维护成本;我们需要实现前端开发工程化,它能解决如下问题:

1、 传统语言和语法在各端的兼容性不好;

例如,现在的项目通常都是用es6+或者ts去开发;而一些政企项目中客户(特别是国企的客户)还在用一些老电脑,使用的IE8、IE9、IE10等老的浏览器版本不兼容es6+的执行,需要转换为es5甚至es3到浏览器去执行;

2、 一些项目无法使用模块化/组件化;

例如,以前做的一个数据可视化项目中有大量图表组件;这些图表组件的代码量和数量很多,全部一次加载浏览器速度很慢。所以需要考虑图表组件的按需加载,那就需要webpack这样的工具来配合做图表的模块化和组件化。

3、 重复机械式的工作/重复造轮子;

工程化时,我们可以将重复代码提取成公用的模块或者库供所有人使用,避免重复造轮子;

4、 没有代码风格统一、质量保证

在开发中如果没有统一的代码书写规范,那么会造成项目开发的混乱,会在项目中遗留很多隐性的BUG,也会导致后期项目维护成本升高。所以我们通常使用eslint、csslint等工具来检查代码书写规范。

5、 前后端分离开发过程中,依赖后端服务支持导致效率低下

现在的项目开发中,为了提升效率和项目解耦通常采用了前后端分离的方式;但是前端开发和后端开发是同时进行,大概率情况下前端所需后端接口不能及时提供;所以我们需要使用mock等工具自己去模拟接口。

2.前端工程化流程

创建项目 => 编码 => 预览/测试 => 提交 => 部署

2.1 创建项目

在项目开发初期,我们可以实用工具自动创建一些脚手架、模板、通用等文件;还能够创建项目结构、创建特定类型文件,例如:

  • 创建vue项目:vue-cli
  • 创建react项目:create-react-app
  • 自定义nodejs cli应用:根据自己需求实现的工具,可以自定义创建项目、生成项目描述文件等。

2.2 编码

在正式堆代码的时候,可能会有多人协同开发的场景;这时候需要我们制定编码规范来约束开发人员的编码风格,并使用工具来代替人为约定。除此之外,还可以使用一些自动化工具来替我们自动构建、自动编译打包。

  • 格式化代码:prettier
  • 校验代码风格:eslint、stylelint
  • 编译/构建/打包/模块化:grunt、gulp、fis3、webpack、babel

2.3 预览/测试

在开发本地调试的时候,我们可以使用一些工具来模拟服务器场景并实现热更新、热加载;即代码修改后自动编译构建,浏览器根据变化自动刷新同时还要方便我们查看源码。

  • 本地服务:WebServer / Mock
  • 热加载/热更新:Live Reloading / HMR
  • 源码映射:Source Map

2.4 提交

  • Git Hooks:可在提交前进行代码质量和风格的检查
  • Lint-staged
  • 持续集成

2.5 部署

  • 自动化部署:CI/CD
  • 自动化集成:Jenkins 可以调用执行脚本,集成自动化构建、打包、部署等

常见请求头

User-Agent:标识客户端使用的浏览器和操作系统信息。可以通过$_SERVER['HTTP_USER_AGENT']获取。

Accept:指定客户端能够处理的内容类型,即可接受的媒体类型。可以通过$_SERVER['HTTP_ACCEPT']获取。

Content-Type:指定请求体中的数据格式类型。常见的取值有application/json、application/x-www-form-urlencoded等。可以通过$_SERVER['CONTENT_TYPE']获取。

Authorization:用于进行身份验证的凭证信息。常见的取值有Bearer Token、Basic Authentication等。可以通过$_SERVER['HTTP_AUTHORIZATION']获取。

Cookie:包含来自客户端的Cookie信息。可以通过$_SERVER['HTTP_COOKIE']获取。

Referer:指示当前请求是从哪个URL页面发起的。可以通过$_SERVER['HTTP_REFERER']获取。

Host:指定服务器的域名或IP地址。可以通过$_SERVER['HTTP_HOST']获取。

X-Requested-With:指示请求是否由Ajax发起的。通常在Ajax请求中会设置该头部字段,取值为"XMLHttpRequest"。可以通过$_SERVER['HTTP_X_REQUESTED_WITH']获取。

Content-Length:指定请求体的长度。可以通过$_SERVER['CONTENT_LENGTH']获取。

Cache-Control:控制缓存行为的指令。用于指定客户端和代理服务器如何缓存响应。可以通过$_SERVER['HTTP_CACHE_CONTROL']获取。


前端用户验证方案

HTTP 基本认证

在 HTTP 中,基本认证方案(Basic Access Authentication)是允许 HTTP 用户代理(通常指的就是网页浏览器)在请求时,通过用户提供用户名和密码的方式,实现对用户身份的验证。

基本认证中,最关键的是四个要素:

  1. uid:用户的 ID,也就是我们常说的用户名
  2. password:密码
  3. realm:领域,其实就是指当前认证的保护范围

在进行基本认证的过程中,HTTP 的请求头字段会包含 Authorization 字段,Authorization: Basic <用户凭证>,该用户凭证是 用户名密码 的组合而成的 Base64 编码

Session-Cookie 认证

Session-Cookie 认证是利用服务端的 Session(会话)和浏览器(客户端)的 Cookie 来实现的前后端通信认证模式。

由于 HTTP 请求时是无状态的,服务端正常情况下无法得知请求发送者的身份,这个时候我们如果要记录状态,就需要在服务端创建 Session 会话,将相同客户端的请求都维护在各自的会话记录中,每当请求到达服务端时,先校验请求中的用户标识是否存在于 Session 中,如果有则表示已经认证成功,否则表示认证失败。

Cookie 主要用于以下三个方面:

  • 会话状态管理(如用户登录状态、购物车、游戏分数或其他需要记录的信息)
  • 个性化设置(如用户自定义设置、主题等)
  • 浏览器行为追踪(如跟踪分析用户行为等)
Token 认证

随着 Restful API、微服务的兴起,基于 Token 的认证现在已经越来越普遍。Token 和 Session-Cookie 认证方式中的 Session ID 不同,并非只是一个标识符。Token 一般会包含 用户的相关信息,通过验证 Token 不仅可以完成身份校验,还可以获取预设的信息。像 Twitter、微信、QQ、Github 等公有 API 都是基于这种方式进行认证的,一些开发框架如 OpenStack、Kubernetes 内部 API 调用也是基于 Token 的认证。

JWT 认证

JWT(JSON Web Token)是 Auth0 提出的通过对 JSON 进行加密签名来实现授权验证的方案,就是登录成功后将相关信息组成 JSON 对象,然后对这个对象进行某种方式的加密,返回给客户端,客户端在下次请求时带上这个 Token,服务端再收到请求时校验 token 合法性,其实也就是在校验请求的合法性。

单点登录

单点登录(Single Sign-on)又称 SSO,是指在多系统应用群中登录单个系统,便可在其他所有系统中得到授权而无需再次登录。

传统的 All-in-one 型应用的认证系统和业务系统集合在一起的,当用户认证通过时,将用户信息存入 Session 中。其他业务只需要从业务中通过对应会话身份凭证取到用户信息进行相关业务处理即可。

传统的 Session 是将用户信息存入内存,维护一个哈希表。每次请求携带会话身份凭证 SessionID(Tomcat 中是 JSESSIONID)到服务端,根据此 SessionID 查找到对应的用户信息。

利用 Redis 等内存数据库进行用户信息的存储,自定义 Token 生成规则将用户信息写入 Redis 中。这样将用户信息的存储和业务系统进行拆分,使系统更加健壮,更易于扩展。新增系统只需要从 SSO 中获取相关的认证即可进行横向的业务扩展。而且 Redis 本身的性质也易于进行 集群化 的部署。

LDAP 认证登录

LDAP 的全称是 Lightweight Directory Access Protocol,即轻量目录访问协议,是一个开放、广泛被使用的工业标准(IEFT、RFC)。企业级软件也通常具备 *支持 LDAP- 的功能,比如 Jira、Confluence、OpenVPN 等,企业也经常采用 LDAP 服务器来作为企业的认证源和数据源。但是大家比较常见的误区是,可以使用 LDAP 来实现 SSO。我们可以先分析以下它的主要功能点或场景。

信任登录

信任登录是指所有不需要用户主动参与的登录,例如建立在私有设备与用户之间的绑定关系,凭证就是私有设备的信息,此时不需要用户再提供额外的凭证。信任登录又指用第三方比较成熟的用户库来校验凭证,并登录当前访问的网站。

  1. 登录服务 *信任业务系统- 的凭证校验结果
  2. 登录服务 *信任第三方登录系统- 的凭证校验结果,前提是必须又本站点的账号体系下的账号与第三方账号的一对一绑定关系,现在流行的授权方式也属于这个模式。

目前比较常见的第三方信任登录帐号如:QQ 号淘宝帐号、支付宝帐号、微博帐号等。

信任登录的好处是可以利用第三方庞大的用户群来推广、营销网站,同时减少用户的注册、登录时间。


git相关

修改一个 git commit 的提交信息时:
  • 修改当前分支最新 commit 的提交信息
  • 修改当前分支某历史 commit 的提交信息
  • 修改当前分支第一个 commit 的提交信息
解决方式

我们以表格的形式描述如上三种场景下的解决方式:

修改 commit 提交信息场景操作命令
修改最新 commit 的提交信息git commit --amend
修改某历史 commit 的提交信息git rebase -i father_commitId
修改第一个 commit 的提交信息git rebase -i --root
merge冲突

1.git state查看冲突信息

2.打开冲突文件,会新增分割线标识

3.编辑冲突文件内容,决定要保留的内容,然后删掉三行分割线

4.git addgit commit

如何中断一次merge

git merge --abort


事件循环

【【前端八股文】事件循环-宏任务和微任务-哔哩哔哩】 https://b23.tv/S1tIVC5

【宏任务微任务笔试题-哔哩哔哩】 https://b23.tv/Crkq2Oq

1.同步代码

2.微任务异步

3.宏任务异步
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


事件捕获和事件冒泡

在这里插入图片描述

事件冒泡将从一个子元素开始,在 DOM 树上传播,直到最上面的父元素事件被处理。

事件捕获是指当一个事件被触发时,它会从最外层的元素开始,然后逐级向内传播,直到最内层的元素。在这个过程中,事件会经过每一个元素,直到它到达最内层的元素。

区别:

在事件冒泡中,事件处理程序会按照它们被注册的顺序执行,也就是说,先注册的事件处理程序会先执行。相反,在事件捕获中,事件处理程序会按照它们被注册的相反顺序执行,也就是说,后注册的事件处理程序会先执行。

如何组织事件传播:

我们可以使用 stopPropagation() 方法来避免这种行为,它将阻止事件沿着 DOM 树向上或向下进一步传播。


防抖节流

防抖

在这里插入图片描述

应用场景:

搜索框搜索输入

文本编辑器实时保存

代码实现思路:

利用定时器:设定一个函数,触发这个函数的时候如果上一个定时器没有结束,则清楚这个计时器重新触发,如果结束了,就再触发一次。

在这里插入图片描述

节流

在这里插入图片描述

应用场景:

高频事件 例如 快速点击、鼠标滑动、resize事件、scroll事件

下拉加载

视屏播放记录时间

代码实现思路

利用定时器:如果上个定时器没有结束,则直接return回去,如果为空了就设定新的定时器

在这里插入图片描述


原型和原型链

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

实例的__proto__属性指向构造函数的原型对象

在这里插入图片描述

原型对象本身也是个对象及也拥有__proto__属性,所以当在当前原型对象中查找不到的话,会往上查找原型对象的原型对象,一层一层链式调用,知道查找到顶部null

总结:

在这里插入图片描述


vue响应式原理

vue2响应式原理:

Vue在组件和实例初始化的时候,会将data里的数据进行数据劫持(object.definepropety)对数据做处理)。被劫持过后的数据会有两个属性:一个叫getter,一个叫setter。

getter是使用数据的时候触发,setter是在修改数据的时候触发,修改数据的时候触发setter,同时也触发了底层的watcher监听,通知dom修改刷新。

ps:getter 方法用于获取数据属性的值,而 setter 方法用于在数据属性的值发生改变时执行响应的操作,例如更新视图(view)。

vue3响应式原理:

用proxy代替Object.defineproperty实现响应。

defineProperty监听的是属性,而proxy监听的是整个对象。

ps:在Vue2中,数据响应式主要借助Object.defineProperty()来实现,存在的缺陷是无法操作数据的增加和删除,在Vue3中,数据响应式主要借助proxy和Reffect配合实现,可以做到实现数据的增删改查。


什么是函数柯里化

指的是将一个多参数的函数拆分成一系列函数,每个拆分后的函数都只接受一个参数。


vue2 options Api与vue3 composition Api对比

vue2 options:我们会在一个vue文件中methods,computed,watch,data中等等定义属性和方法,共同处理页面逻辑。

缺点: 一个功能往往需要在不同的vue配置项中定义属性和方法,比较分散,项目小还好,清晰明了,但是项目大了后,一个methods中可能包含20多个方法你往往分不清哪个方法对应着哪个功能

vue3 Composition API :我们的代码是根据逻辑功能来组织的,一个功能所定义的所有api会放在一起(更加的高内聚,低耦合),这样做,即时项目很大,功能很多,我们都能快速的定位到这个功能所用到的所有API,而不像vue2 Options API 中一个功能所用到的API都是分散的,需要改动功能,到处找API的过程是很费劲的


watch与computed使用场景

  • watch的使用场景:一个数据影响多个数据,需要在数据变化时执行异步操作或者开销较大的操作时使用。

    例如:搜索数据

  • computed:一个数据受多个数据影响,处理复杂的逻辑或多个属性影响一个属性的变化时使用。

    例如:购物车商品结算的时候


v-if和v-show的使用场景

1、v-if

此元素进入页面后,此元素只会显示或隐藏不会被再次改变显示状态,此时用v-if更加合适,如请求后台接口通过后台数据控制某块内容是否显示或隐藏,且这个数据在当前页不会被修改

2、v-show

此元素进入页面后,此元素会频繁的改变显示状态,此时用v-show更加合适,如页面中有一个toggle按钮,点击按钮来控制某块区域的显示隐藏


vue2.x与vue3.x生命周期对比

在这里插入图片描述


vue生命周期哪一步发请求

推荐加载 created 钩子函数中调用异步请求,因为在 created 钩子函数中调用异步请求有以下优点:

1.此时组件实例已经创建完成,可以安全地访问数据和方法。

2.能更快获取到服务端数据,减少页面loading时间。

为什么不能在beforeCreate的时候发送请求:

因为在beforeCreate的时候,datapropsmethods 等都不可用


ref与reactive的区别

  • 数据类型:ref用于包装基本数据类型(如数字、字符串),而reactive用于包装对象。
  • 访问数据:使用ref时,需要通过.value来访问数据,而reactive则允许直接访问属性。
  • 数据的包装:ref返回一个包装对象,而reactive返回一个包装后的对象。
  • 使用 ref 定义单个响应式数据,使用 reactive 定义包含多个属性的响应式对象。
  • Vue 的响应式系统是基于代理的,reactive 可以对整个对象进行代理,使得 Vue 可以更高效地追踪和优化响应式数据的变化。而 ref 是通过 getter 和 setter 实现的,对于复杂的状态管理,reactive 的性能更优。

什么是跨域,出现原因及解决方法

跨域是什么意思?

首先一个url是由:协议、域名、端口 三部分组成。(一般端口默认80)

当一个请求url的协议域名端口三者之间的任意一个与当前页面url不同即为跨域

跨域产生原因?

出于浏览器的同源策略限制。

同源策略是一个重要的安全策略,它用于限制一个的文档或者它加载的脚本如何能与另一个源的资源进行交互。

非同源会出现的限制:

  • 无法读取非同源网页的cookie、localstorage等
  • 无法接触非同源网页的DOM和js对象
  • 无法向非同源地址发送Ajax请求
解决方法

nginx反向代理解决跨域(前端常用)

正向代理:

a–>b访问不了,可以找个中间的服务器c, 先访问c再从c到b,类似曲线救国。
明确访问的目的地,但是用户不知道中间的代理服务器。(忽略中间服务器)

反向代理:a--> c <--b

a明确访问c代理服务器,但是不知道c的内容从哪里来,c反向从别的地方拿来数据。(忽略的是目标地址)

CORS解决跨域(也就是添加响应头解决跨域)

通过jsonp解决跨域(老方法)

实现原理:通常为了减轻web服务器的负载,我们把js、css、图片等静态资源分离到另一台独立域名的服务器上,在html页面中再通过相应的标签从不同域名下加载静态资源,而被浏览器允许。


什么是浏览器缓存/缓存策略

当我们访问一个网站时,会加载各种资源,如 HTML文档、JS、CSS、图片等。浏览器会将一些不经常变的资源保存在本地,这样下次访问相同网站时,就直接从本地加载资源,并不通过请求服务器,这就是浏览器缓存。

浏览器缓存策略分为两种:强缓存协商缓存,并且缓存策略都是通过设置 HTTP Header 来实现的。

强缓存
不会向服务器发送请求,直接从缓存中读取资源,强缓存可以通过设置两种 HTTP Header 实现。

协商缓存
协商缓存就是强制缓存失效后,浏览器携带缓存标识向服务器发起请求,由服务器根据缓存标识决定是否使用缓存的过程。


async/await是什么

async 和 await 是ES8提出的基于Promise解决异步的最终方案,让异步代码像同步代码一样 async 是函数的修饰符,返回一个promise 对象,结果由 async 修饰的函数返回值决定。 await 必须写在 async 中,await 右侧表达式一般为 promise 对象,一般返回 promise 成功的值。如果 await 的 promise 失败,则会抛出异常,需要使用 try…catch 捕获。

如果 await 返回失败的 promise,一定要用 try…catch 接收吗?如果有多个 await怎么才能不阻塞主进程代码的执行?能不能用 Promise.all ?

答:

在 JavaScript 中,如果 await 返回一个失败的 promise,推荐使用 try...catch 语句来处理错误,这样可以确保代码的健壮性并且能够优雅地处理异常情况。

对于多个 await 调用,如果希望它们并行执行而不是顺序执行,从而避免阻塞主进程,可以使用 Promise.all 来并行处理多个异步操作。这样做可以显著提高性能,尤其是当这些操作互不依赖时。


什么是轮询

如果页面上有一份数据需要持续刷新,我们要轮询等待页面完成这个数据处理,此使怎么做?

轮询是一种定期发送请求以检查某个状态或获取数据的技术。在页面上实现轮询,可以使用 setInterval 函数,每 n 秒检查一次


cookie 和 session 之间有什么不同?使用 session 的时候需要用到 cookie 吗

cookie:存储在客户端浏览器中的小数据文件,可以跨会话存在,通常用于保存用户偏好、登录状态等信息。cookie 可以设置过期时间。

session:存储在服务器端的一种会话机制,用户访问网站时生成的唯一会话标识(session ID)保存在 cookie 中。session 数据保存在服务器端,浏览器关闭后 session 也会失效。


cookie、sessionStorage 和 localStorage 之间的区别

三者都是存储在客户端

sessionStorage:在客户端读取数据,页面刷新后数据仍然存在,但关闭浏览器或标签页后数据就会消失。

localStorage:持久化存储数据,除非通过 JavaScript 删除,否则数据会一直存在,即使关闭浏览器也不会消失

Cookie:主要是用来在服务端读取的,它可以用来追踪用户或维护用户的状态等。每次HTTP请求时,Cookie都会被发送到服务器。

  • Cookie:适合存储需要在客户端和服务器之间传递的少量数据,尤其是需要持久化的小型数据,如会话ID。
  • LocalStorage:适合存储大量、持久化、非敏感的数据,主要用于客户端持久存储。
  • SessionStorage:适合存储会话范围内的临时数据,数据只在当前会话有效。

localstorage和localforage的区别

  • LocalForage 的操作是异步的,而localstorage的操作是同步的,LocalForage不会阻塞主线程。它使用 Promise 或回调来处理异步操作,这在处理大数据量时有显著优势。
  • LocalForage 可以存储比 LocalStorage 更多的数据。
  • LocalForage 支持存储各种 JavaScript 数据类型,包括对象、数组、二进制数据等;LocalStorage 只能存储字符串类型的数据,其他数据类型需要转换为字符串。

怎么判断一个数据类型是null

用三等运算符直接和null比较

value === null;    //true or false


为什么要用状态管理库,主要解决了什么问题,和本地缓存的区别

为什么要用状态管理库?
多组件的状态共享问题: 当多个组件需要访问和修改相同的数据时,我们需要在组件之间传递 props或者使用事件总线。应用就会变得难以维护和调试。

多组件状态同步问题: 当一个组件修改了状态,其他组件可能无法立即得知该变化。

状态变更的追踪问题: 无法追踪到状态的变化是由何处引起的,使得调试和维护变得困难。
————————————————

vuex/pinia存储在内存,vuex/pinia会随着页面的重启刷新一起重置状态,localstorage(本地存储)则以文件的方式存储在本地,永久保存;


typeof null/function

typeof null 返回 'object',而 typeof function 返回 'function'


什么是vuex

Vuex 是一个状态管理库,对标vue3中的pinia。

它采用集中式存储管理应用的所有组件的状态。

什么时候使用?

一般用于中大型 web 单页应用中对应用的状态进行管理,vuex 更多地用于解决跨组件通信以及作为数据中心集中式存储数据。

1多个组件依赖于同一状态。
2.来自不同组件的行为需要变更同—状态。

怎么使用?

在main.js引入store,注入。

vuex有哪几种属性?
State、 Getter、Mutation 、Action、 Module

state:存放公共数据的地方。
getter:获取根据业务场景处理返回的数据。
mutations:唯一修改state的方法,修改过程是同步的。
action:异步处理,通过分发操作触发mutation。
module:将store模块分割,减少代码臃肿。


vuex与pinia的区别

Vuex 是 Vue.js 官方提供的状态管理库,而 Pinia 是基于 Vue 3 且使用 TypeScript 编写的轻量级的状态管理库。

Vuex 在使用时需要在 Vue.js 应用中显式地安装,而 Pinia 则不需要显示安装。

Vuex 使用全局 store 存储状态,而 Pinia 使用本地store,这意味着在使用多个获取数据的单独实例时,每个实例都有自己的存储空间。

Vuex 提供了更为完整、复杂的接口和功能集,包括管理多个模块、插件等;而 Pinia 则更加简单,只提供了片段式组装 store 等核心需求。

Vuex 对比 Pinia 经过长时间稳定运行,并且文档和社区支持完善。而 Pinia虽然较新,但侧重于 TypeSciprt 风格的开发方式,在未来可能会提供更好的维护性和易读性


为什么要用lerna

1.统一管理依赖并抽离相同依赖,避免依赖冲突和重复安装。

2允许在同一个存储库中开发多个包,集中管理多个包的代码。

3.可以帮助我们同时运行多个子包的脚本命令,我们可以使用Lerna来运行所有子包的测试。


promise.all()与promise.race()的实际应用

promise.all():

  • 登录时验证用户名和密码同时是否有效。
  • 从不同 API 下载多个资源,只有当所有资源都下载完成后才执行下一步操作。

promise.race():

  • 点击按钮发请求,当后端的接口超过一定时间,假设超过三秒,没有返回结果,我们就提示用户请求超时

总结:

  • Promise.all接收的是数组,得到的结果也是数组,并且一一对应,也可以理解为Promise.all照顾跑的最慢的,最慢的跑完才结束。
  • Promise.race接收的也是数组,不过,得到的却是数组中跑的最快的那个,当最快的一跑完就立马结束。

TS泛型

指在定义函数、接口或类的时候,不预先指定具体的类型,而在使用的时候再指定类型的一种特性。 使用<T>代表类型的变量,T只是约定用法,可以任意指定。

泛型无法知道具体的类型,所以无法操作它的属性和方法


watch和watchEffect的区别

  • 执行时机:watchEffect是立即执行的,在页面加载时会主动执行一次,来收集依赖;而watch是惰性地执行副作用,它不会立即执行,但可以配置 immediate,使其主动触发。
  • 参数不同:watchEffect只需要传递一个回调函数,不需要传递侦听的数据,它会在页面加载时主动执行一次,来收集依赖;而watch至少要有两个参数(第三个参数是配置项),第一个参数是侦听的数据,第二个参数是回调函数。
  • 结果不同:watchEffect获取不到更改前的值;而watch可以同时获取更改前和更改后的值。

https的加密过程

  1. 客户端向服务端发送请求,并包含自身的公钥和其他相关信息。
  2. 服务端收到请求后,验证客户端的身份信息,并生成一对公钥和私钥。
  3. 服务端将公钥发送给客户端,并使用私钥对之前发送的信息进行加密,然后将加密后的信息发送给客户端。
  4. 客户端使用服务端的公钥对接收到的信息进行解密,得到服务端的私钥。
  5. 客户端使用服务端的私钥对自身公钥进行加密,然后将加密后的信息发送给服务端。
  6. 服务端使用自身的私钥对接收到的信息进行解密,得到客户端的公钥。

动态添加路由

1.通过当前获取的权限,从总菜单中筛选出与当前权限匹配的菜单。

2.定义添加路由函数,接收菜单对象和路由对象两个值。

3.遍历检查当前遍历到的主菜单是否有子菜单,如果有则递归调用自己,最后自底而上通过addRoute来动态添加路由。


TS中any的作用

为编程阶段还不清楚类型的变量指定一个类型。 这些值可能来自于动态的内容,比如来自用户输入或第三方代码库。 这种情况下,我们不希望类型检查器对这些值进行检查而是直接让它们通过编译阶段的检查。


箭头函数特点

1.没有this、super、arguments,因为没有this,故无法用call、bind、apply绑定this。

2.不能使用new调用。

3.没有原型。


this指向

在这里插入图片描述
在这里插入图片描述

方式一为隐式

方式二为显示

在这里插入图片描述

面试题:
在这里插入图片描述


const与Object.freeze()的区别:

const:

  • const定义的变量值无法改变,但是const定义的数组、对象中的值是可以被改变的。

Object.freeze():

  • 返回一个不可变对象。这就意味着我们不能添加,删除或更改对象的任何属性。
  • Object.freeze()仅能冻结对象的当前层级属性,换而言之,如果对象的某个属性本身也是一个对象,那么这个内部对象并不会被Object.freeze()冻结

hash和history的原理以及区别

一、实现原理

hash 原理
hash 通过监听浏览器 onhashchange 事件变化,查找对应路由应用。通过改变 location.hash 改变页面路由。
history 原理
利用 html5 的history Interface 中新增的 pushState() 和 replaceState() 方法,改变页面路径。
history Interface 是浏览器历史记录栈提供的接口,可通过 back、forward、go 等,可以读取历览器历史记录栈的信息,pushState、repalceState 还可以对浏览器历史记录栈进行修改。

hash 与 history 区别对比:

hashhistory
有 # 号没有 # 号
能够兼容到IE8只能兼容到IE10
实际的url之前使用哈希字符,这部分url不会发送到服务器,不需要在服务器层面上进行任何处理每访问一个页面都需要服务器进行路由匹配生成 html 文件再发送响应给浏览器,消耗服务器大量资源
刷新不会存在 404 问题浏览器直接访问嵌套路由时,会报 404 问题。
不需要服务器任何配置需要在服务器配置一个回调路由

如何脱离文档流,影响是什么

  • 元素设置position,并且position的值为fixed或absolute;
  • 元素添加浮动float,并且float的值不为none;
  1. 不占据原有空间:这使得其他元素表现得如同该元素不存在。
  2. 可自由定位:元素可以放置在页面上几乎任何位置,便于创建浮动效果或覆盖层。
  3. 可能影响布局响应性:固定位置可能导致在不同设备或窗口大小下布局问题。
  4. 影响层叠顺序:通过z-index控制元素在视觉上的堆叠。

null和undefined

在JavaScript中,null表示一个空对象指针,用于表示变量未引用任何对象。而undefined表示一个未定义的值,用于表示变量声明但未初始化,或者对象属性不存在。
解答思路:从内存的角度来说,null和undefined在内存中的表示是不同的。当一个变量被赋值为null时,实际上是将这个变量指向了一个空的对象指针,内存中会分配空间来存储这个指针。而当一个变量的值为undefined时,表示这个变量并没有被赋值,内存中并不会分配空间来存储undefined的值。


性能优化

首屏优化

在这里插入图片描述
在这里插入图片描述
收益大:

  • 打包工具压缩、不用第三方库(自定义功能)、减少代码体积(重构、嵌套)
  • 异步加载:体积比较大但是不是马上需要的功能且与首屏渲染没什么关系。例如图片压缩功能,用到了个很大的第三方库,但是这个功能只在上传图片的时候打开页面进行上传并且勾选需要压缩的时候使用,这个时候就可以异步加载这个功能。
  • 版本更新:现在打包工具是支持tree-shaking的(按需引入,只打包用到的模块):项目中项目引用的库比较老,不支持tree-shaking,一一排查项目中的老版本库,将其升级为支持tree-shaking的新版本库,大大减小了打包体积,加快了首屏渲染。
  • 去除大的base64体积:图片等资源会转变成base64存放在js或者css中,所以大的图片等资源不要转成base64。

收益小:

  • 数据接口并行
  • 滚动按需渲染页面dom
  • loading、骨架屏、先让屏幕不白,减少用户焦虑

常见状态码

2XX 成功

200 ok(请求成功)
204 no content (请求成功,但是没有结果返回)
206 partial content (客户端请求一部分资源,服务端成功响应,返回一范围资源)

3XX 重定向

301 move permanently (永久性重定向)
302 found (临时性重定向)
303 see other (示由于请求对应的资源存在着另一个 URI,应使用 GET
方法定向获取请求的资源)
304 not modified (表示在客户端采用带条件的访问某资源时,服务端找到了资源,但是这个请求的条件不符合。跟重定向无关)
307 temporary redirect (跟302一个意思)

4XX 客户端错误

400 bad request (请求报文存在语法错误)
401 unauthorized (需要认证(第一次返回)或者认证失败(第二次返回))
403 forbidden (请求被服务器拒绝了)
404 not found (服务器上无法找到请求的资源)

5XX 服务器错误

500 internal server error (服务端执行请求时发生了错误)
503 service unavailable (服务器正在超负载或者停机维护,无法处理请求)


vue3销毁前能做什么

  • 清除定时器和取消订阅:在组件中使用了定时器或订阅外部事件时,需要在组件销毁前将其清除或取消,以防止内存泄漏。
  • 取消异步请求:如果组件中有未完成的异步请求,可以在销毁前取消这些请求,以避免请求结果返回后更新已销毁的组件。
  • 解绑事件监听器:如果组件中有添加了事件监听器,如 addEventListener,需要在销毁前将其移除,以防止事件回调函数继续执行。
  • 清除计时器和动画:如果组件中使用了计时器或动画效果,需要在销毁前将其清除,以避免无效的计时器继续执行或动画效果导致的性能问题。
  • 取消订阅全局状态:如果组件订阅了全局状态管理工具(如 Vuex),需要在销毁前取消对状态的订阅,以避免无效的状态更新。
  • 清理其他资源:根据具体情况,可能还需要执行其他清理操作,如关闭数据库连接、释放内存等。

标签:必修,浏览器,请求,--,认证,面试,缓存,使用,客户端
From: https://blog.csdn.net/qq_74099184/article/details/140330014

相关文章

  • 机器学习评价指标之决策曲线
    决策曲线是一种用于评估和比较不同分类模型性能的工具,它可以帮助研究人员和数据分析者理解模型在不同阈值设置下的收益和风险。以下是一些关于分类模型决策曲线的详细信息:决策曲线的构成:阈值(Threshold):分类模型通常会输出一个概率分数,表示样本属于正类的概率。阈值是用于将概......
  • 前端面试必修--面试算法题(附带字节跳动真题pdf)
    面试算法题目录简单53.最大子数组和-力扣(LeetCode)415.字符串相加-力扣(LeetCode)206.反转链表-力扣(LeetCode)1.两数之和-力扣(LeetCode)572.另一棵树的子树-力扣(LeetCode)1410.HTML实体解析器-力扣(LeetCode)69.x的平方根-力扣(LeetCode)26.删除有序数组中......
  • 7月16日JavaSE学习笔记
    方法(函数、过程)语法返回值类型方法名(参数列表){方法体}返回值类型:该方法必须返回的一个这个类型的对象当方法不需要返回值时,返回值类型就定义为voidpublicstaticintmax(inta,intb){intmax=a>b?a:b;//方法名和变量名不会冲突//return返回......
  • Linux 【disk】磁盘管理
    Linux磁盘管理好坏直接关系到整个系统的性能问题。Linux磁盘管理常用三个命令为df、du和fdiskdf:diskfree:列出文件系统的整体磁盘使用量du:diskused:检查磁盘空间使用量fdisk:用于磁盘分区磁盘管理磁盘分区-->格式化(获得文件系统)-->挂载磁盘的分类:SCSI硬盘......
  • Linux 【systemctl 】服务管理器
    1.start/stop#启动一个服务并在后台运行它systemctlstart[service]#停止当前正在运行的服务systemctlstop[service]#停止正在运行的服务,然后重新启动它systemctlrestart[service]#-------------------------------#示例:开启sshd服务systemctlstartsshd#示例:......
  • MySQL【表完整性约束】
    约束条件说明primarykey(PK)标识该字段为该表的主键,唯一性,不为空;UNIQUE+NOTNULLforeignkey(FK)标识该字段为该表的外键,实现表与表之间的关联null标识是否允许为空,默认为NULL。notnull标识该字段不能为空,可以修改。uniquekey(UK)标识该字段的值是唯一的......
  • 虚拟机网络配置最佳实践
    一、虚拟网卡配置1.1设置虚拟网卡点击VMwareNetworkAdapterVMnet8设置虚拟网卡注意要点:1.设置静态IP,地址为:192.168.2.1002.设置子网掩码(默认):255.255.255.03.设置默认网关:192.168.2.1(重要!!!这里要跟下面虚拟机网络设置中的NAT设置中的网关IP一致)2.3DHCP设置......
  • MySQL【源码安装安装 mysql】
    1.当前目录:修改属主属组cd/usr/local/mysqlchown-Rmysql.mysql.2.初始化数据库:mysql/bin/mysqld./bin/mysqld--initialize--user=mysql--basedir=/usr/local/mysql--datadir=/usr/local/mysql/data/#拿到随机密码:#[Note]Atemporarypasswordisgeneratedf......
  • 从ThreadLocal底层源码一直聊到内存泄漏,干货满满!!
    小强最近在疯狂补习高并发的相关知识,但是在学到threadLocal时有点力不从心了,尤其是threadLocal的底层架构和如何导致内存泄漏,今天我们帮小强一把!!把这一块彻底聊清楚!!!文章目录1.threadLocal的前世今生1.为什么要使用threadLocal2.threadLocal和Synchonized的比较3.使用场......
  • java入门---作用域
    作用域:作用域是指在程序中定义变量的区域,该变量在该区域内可被访问。1、关于作用域的两种查询在JavaScript中编译器会用两种查询方式进行查询一种是LHS查询;一种是RHS查询;俩个查询的含义是,当变量出现赋值操作在左侧时进行LHS查询,出现在右侧时进行RHS查询。详细的讲就是R......