前端面试题—面试题整理(3)

一 面试题汇总(Boss直聘分享-武汉中地云申)

  1. 单点登录
  2. vuex
  3. vue的生命周期有哪些,data里面的数据初始化是在哪个阶段
  4. vue双向数据绑定的原理
  5. 闭包
  6. https为什么比http更安全
  7. 为什么data属性是一个函数而不是一个对象
  8. ts熟悉吗
  9. axios封装过没
  10. 封装过哪些组件
  11. vue的自定义指令用过没

二 面试题解答(仅供参考)

2.1 单点登录

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
单点登录(Single Sign-On,SSO)是一种身份认证的解决方案,允许用户只需一次登录,
即可访问多个相关的系统或服务。在单点登录系统中,用户只需通过一次认证,
便可获取到访问多个系统的访问权限,无需为每个系统单独进行认证登录。

单点登录的基本原理如下:

1-认证中心(Authentication Center,Auth Center):

单点登录系统中会存在一个认证中心,负责用户的身份认证和授权操作。
当用户首次访问系统时,系统会将用户重定向到认证中心进行认证。

2-认证过程:

用户在认证中心输入用户名和密码进行登录认证。
认证中心验证用户的身份,并生成一个认证凭证(Token)。
认证中心将认证凭证返回给用户的浏览器。

3-凭证传递:

用户的浏览器将认证凭证保存在本地,通常存储在 Cookie 或者 Local Storage 中。
用户访问其他系统时,系统会检查用户的凭证是否有效。

4-授权:

如果凭证有效,系统将向认证中心发送请求,获取用户的授权信息。
认证中心返回用户的授权信息给系统,系统根据授权信息确定用户是否有权访问系统资源。

5-单点注销:

用户在任意一个系统注销登录时,系统会通知认证中心,认证中心会将用户在所有系统的登录状态注销,实现单点注销。

通过单点登录系统,用户可以方便地在多个系统之间进行切换,提高了用户体验和管理效率。
常见的单点登录协议包括 SAML(Security Assertion Markup Language)、
OAuth(Open Authorization)、OpenID Connect 等。
这些协议都是用来在不同系统之间安全地传递用户身份和授权信息的标准化协议

2.2 vuex

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。
它允许您在一个中心化的状态存储管理应用的所有组件的状态,并以可预测的方式进行状态的修改。

Vuex 的核心概念包括:

1-State(状态):

State 即应用程序中需要共享的数据状态,存储在 Vuex 的状态树中。
在组件中访问 State 可以通过 this.$store.state 来获取。

2-Mutations(突变):

Mutations 是一种同步函数,用于修改 State 中的数据。
每个 Mutation 都有一个字符串类型的事件类型(type)和一个处理函数(handler),通过 commit 方法来触发 Mutation。
Mutations 的处理函数接收两个参数:state(当前状态)和 payload(额外参数)。

3-Actions(动作):
Actions 类似于 Mutations,但是 Actions 支持异步操作。
Actions 用于提交 Mutations,而不是直接变更状态。
Actions 是一个包含多个 Action 函数的对象,通过 dispatch 方法来触发 Action。

4-Getters(获取器):

Getters 类似于计算属性,用于从 State 中派生出一些状态,类似于 State 的计算属性。
Getters 接收 state 作为参数,并返回一个值。

5-Modules(模块):

Modules 允许将 Store 拆分为多个独立的模块,每个模块都有自己的 State、Mutations、Actions、Getters 等。
模块内部的状态修改遵循相同的流程,但是被限制在模块的作用域内。

Vuex 的工作流程大致如下:

1.组件通过提交 Mutations 或者分发 Actions 来修改 State。
2.Mutations 或者 Actions 中的处理函数会修改 State 中的数据。
3.修改后的数据会通过 Vue.js 的响应式机制自动更新到相关联的组件中,从而实现视图的更新。

通过使用 Vuex,您可以更好地组织和管理应用程序的状态,并提供了一种可预测的状态管理方案,
使得应用程序的状态变化更易于跟踪和调试。

2.3 vue的生命周期有哪些,data里面的数据初始化是在哪个阶段

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Vue 组件的生命周期包括创建阶段、更新阶段和销毁阶段。常见的生命周期钩子函数如下:

1-创建阶段(Initialization):

1.1-beforeCreate: 在实例初始化之后,数据观测(data observer)和event/watcher事件配置之前被调用。
1.2-created: 在实例创建完成后被立即调用。在这一阶段,实例已完成以下的配置:
数据观测 (data observer),属性和方法的运算,watch/event 事件回调。
1.3-beforeMount: 在挂载开始之前被调用:相关的 render 函数首次被调用。

2-更新阶段(Updating):

2.1-beforeUpdate: 数据更新时调用,发生在虚拟 DOM 重新渲染和打补丁之前。
2.2-updated: 由于数据更改导致的虚拟 DOM 重新渲染和打补丁后调用。

3-销毁阶段(Destruction):

3.1-beforeDestroy: 在实例销毁之前调用。在这一阶段,实例仍然完全可用。
3.2-destroyed: 实例销毁后调用。在这一阶段,实例的所有指令已经解绑,
所有的事件监听器已经移除,所有的子实例也已经被销毁。

在 created 阶段,Vue 实例已经被创建,但尚未挂载到 DOM 中。此时 data 中的数据已经初始化,
但还没有进行模板渲染,也就是说 data 中的数据已经可以在 Vue 实例中使用了,
但尚未在页面上显示。因此,data 中的数据初始化是在 Vue 实例的 created 阶段。

2.4 vue双向数据绑定的原理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Vue 的双向数据绑定是其核心特性之一,它使得视图层和数据层能够保持同步,
即当数据发生变化时,视图会自动更新;同时,当用户在视图中进行操作时,数据也会相应地更新。
Vue 的双向数据绑定主要基于以下两个原理:

1-数据劫持和响应式:
Vue 使用了 Object.defineProperty()方法或Proxy 对象来劫持数据的getter和setter,
从而实现了对数据的响应式监测。

1.1-Getter:当访问数据时,Vue能够捕捉到对数据的读取操作,并建立依赖关系,将Watcher对象添加到订阅者列表中。
1.2-Setter:当修改数据时,Vue 能够捕捉到对数据的修改操作,并通知订阅者进行更新,从而实现数据和视图的同步。

2-虚拟 DOM 和数据绑定:
Vue 使用虚拟 DOM 来描述视图层的状态,并通过模板语法将视图与数据进行绑定。

2.1-模板语法:Vue 提供了一套模板语法,
通过指令(如 v-model、v-bind、v-on 等)将数据绑定到视图上,实现了视图和数据的双向绑定。
2.2-虚拟 DOM:当数据发生变化时,Vue 会生成新的虚拟 DOM 树,
并通过 diff 算法比较新旧虚拟 DOM 树的差异,最终只更新发生变化的部分,从而实现了高效的视图更新。

综上所述,Vue 的双向数据绑定是基于数据劫持和响应式、虚拟 DOM 和模板语法等技术实现的
。通过监听数据的变化并更新视图,以及通过模板语法将视图和数据进行绑定,
Vue 实现了数据和视图之间的自动同步,从而提高了开发效率和用户体验。

2.5 闭包

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
闭包(Closure)是指函数和其周围的引用环境(词法环境)的组合。
在 JavaScript 中,函数可以访问其外部作用域中的变量,
即使在函数定义之后,当函数在其他地方被调用时仍然可以访问这些变量。这种函数和其词法环境的组合就称为闭包。

闭包的特点包括:

1.访问外部作用域的变量:
内部函数可以访问外部函数中定义的变量,即使外部函数已经执行结束。

2.变量保持活动状态:
由于内部函数保留了对外部作用域中变量的引用,
因此这些变量在外部函数执行完毕后仍然可以保持活动状态,不会被垃圾回收机制回收。

3.实现数据隐藏:
闭包可以实现一种类似于私有变量的效果,将一些变量封装在函数内部,
不暴露给外部,从而实现数据隐藏和封装。

4-延长变量的生命周期:
闭包可以延长变量的生命周期,使得函数执行结束后变量仍然可以被访问和使用。

闭包在 JavaScript 中有广泛的应用,常见的应用场景包括:

1.封装私有变量:通过闭包可以创建私有变量和方法,从而实现信息隐藏和封装。
2.实现模块化:通过闭包可以创建模块化的代码结构,将变量和函数封装在闭包中,从而避免全局命名空间污染。
3.保存状态:通过闭包可以保存函数执行时的上下文状态,实现一些状态的持久化。
4.回调函数:闭包常用于实现回调函数,将一个函数作为参数传递给另一个函数,并在内部函数中访问外部函数的变量。
5.循环中的异步操作:在循环中使用闭包可以解决 JavaScript 异步操作中的作用域问题。

尽管闭包在 JavaScript 中有很多有用的应用场景,但在不合理使用的情况下,
闭包也可能导致内存泄漏和性能问题。因此,在使用闭包时需要注意合理使用,避免滥用

2.6 https为什么比http更安全

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
HTTPS 比 HTTP 更安全的主要原因有以下几点:

1-加密通信:
HTTPS 使用 SSL/TLS 协议对通信内容进行加密传输,使得传输过程中的数据无法被中间人窃听和篡改。
这意味着即使通信被拦截,攻击者也无法获取到实际的数据内容。

2-身份验证:
HTTPS 能够对服务器和客户端进行身份验证,确保通信双方的身份合法。
通过数字证书,客户端能够验证服务器的身份,确保通信的安全性和可信度。

3-数据完整性:
HTTPS 使用消息摘要算法(如 MD5、SHA-1、SHA-256 等)对数据进行摘要计算,
然后将摘要信息与传输过程中的数据进行比对,以验证数据的完整性。这样可以确保数据在传输过程中没有被篡改。

4-信任链:
HTTPS 使用数字证书来验证服务器的身份,并建立信任链来确保证书的可信度。
客户端内置了一组受信任的证书颁发机构(CA,Certificate Authority),
可以根据证书的颁发机构来验证服务器的身份是否合法。

5-安全性标识:
浏览器会在地址栏显示安全锁图标,以及网站的 HTTPS 标识,
告知用户当前网站正在使用安全连接,从而提升用户的信任度和安全意识。

综上所述,HTTPS 使用了加密通信、身份验证、数据完整性和信任链等多种安全机制,
相比起 HTTP,能够有效防止数据窃听、篡改和劫持等安全威胁,提高了通信的安全性和可信度,
因此更为安全。在今天的互联网环境中,采用 HTTPS 是保护用户隐私和数据安全的基本要求之一。

2.7 为什么data属性是一个函数而不是一个对象

1
2
3
4
5
6
7
8
9
10
在 Vue.js 组件中,data 属性通常被定义为一个函数,而不是一个对象,主要有以下两个原因:

1-数据隔离:
使用函数形式定义data属性可以实现数据的隔离,每个组件实例都会调用一次该函数,返回一个新的数据对象。
这样可以确保每个组件实例都拥有独立的数据副本,避免了不同组件之间数据的共享和污染。

2-组件复用:
函数形式定义 data 属性可以更好地支持组件的复用,
每次实例化组件时都会调用一次data函数,返回独立的数据对象。
这样即使在多个地方复用同一个组件,也能够保证数据的独立性,避免了组件之间数据的冲突。

2.8 ts熟悉吗

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
TypeScript 是 JavaScript 的一个超集,为JavaScript添加了静态类型检查、
面向对象编程的特性和其他一些新特性,使得 JavaScript 代码更加可维护、
可读性更高,并提供了更好的开发工具支持。

我了解 TypeScript 的一些基本概念和特性,包括:

1-静态类型检查:
TypeScript 提供了静态类型检查的功能,可以在编译时发现潜在的类型错误,提高了代码的健壮性和可维护性。
通过类型注解和类型推断,可以为变量、函数参数、函数返回值等添加类型信息。

2-面向对象编程:
TypeScript 支持面向对象编程的特性,包括类、继承、接口、抽象类等。
可以使用类来组织代码结构,通过继承和接口实现代码复用和模块化。

3-泛型:
TypeScript 支持泛型编程,可以在函数、类、接口等中使用泛型来增加代码的灵活性和复用性,
使得代码更加通用和可扩展。

4-装饰器:
TypeScript 支持装饰器(Decorator)语法,
可以通过装饰器为类和类的成员添加元数据和行为,实现代码的解耦和扩展。

5-枚举:
TypeScript 提供了枚举(Enum)类型,可以定义一组命名的常量值,提高了代码的可读性和可维护性。

6-命名空间:
TypeScript 支持命名空间(Namespace)来组织代码,可以避免全局命名冲突,提高了代码的模块化和可维护性。

7-编译工具:
TypeScript 提供了一个强大的编译工具(tsc),可以将 TypeScript 代码编译成 JavaScript 代码,可以在开发过程中使用各种开发工具和框架进行开发。

总之,TypeScript 是一种增强版的 JavaScript,通过添加静态类型检查和其他一些新特性,
使得 JavaScript 代码更加健壮、可维护和可读性更高。

2.9 axios封装过没

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
对于大型项目或者长期维护的项目,通常会对 axios 进行封装以便于统一管理和处理网络请求,
提高开发效率和代码可维护性。axios 的封装一般包括以下几个方面:

1-统一配置:
封装 axios 实例时,可以设置统一的默认配置,例如设置基础 URL、请求超时时间、请求拦截器、响应拦截器等。

2-请求拦截器:
在请求发送之前,可以通过请求拦截器进行一些全局性的处理,例如添加请求头、对请求参数进行处理等。

3-响应拦截器:
在接收到响应数据之后,可以通过响应拦截器进行一些全局性的处理,例如对响应数据进行统一处理、错误处理等。

4-错误处理:
封装 axios 实例时,可以对响应数据进行统一的错误处理,
例如对不同的 HTTP 状态码进行不同的处理、对网络异常进行处理等。

5-取消重复请求:
对于可能会发起重复请求的场景,可以使用 axios 的取消请求功能,防止出现重复请求的情况。

6-封装公共方法:
封装一些公共的请求方法,例如 get、post、put、delete 等,使得在项目中可以统一调用这些方法进行网络请求。

7-模块化封装:
将 axios 的封装进行模块化,按照业务模块或者 API 接口进行划分,方便管理和维护。

2.10 封装过哪些组件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
我已经封装过许多不同类型的组件,涵盖了前端开发中常见的各种场景和需求。
以下是我封装过的一些常见组件类型:

1-UI 组件库组件:

按钮(Button)
表单输入框(Input)
下拉菜单(Dropdown)
弹窗(Modal)
标签页(Tabs)
表格(Table)
图表(Chart)
图片轮播(Carousel)
图片预览(ImageViewer)
图标(Icon)
进度条(Progress)

2-布局组件:

栅格布局(Grid)
列表布局(List)
卡片布局(Card)
折叠面板(Collapse)
分割线(Divider)
面包屑(Breadcrumb)

3-功能性组件:

懒加载组件(Lazy Load)
无限滚动组件(Infinite Scroll)
回到顶部组件(Back to Top)
下拉刷新组件(Pull to Refresh)
加载动画组件(Loading)

4-数据展示组件:

时间线(Timeline)
日历(Calendar)
标签(Tag)
树形菜单(Tree)
面包屑(Breadcrumb)

5-交互式组件:

拖拽排序组件(Drag and Drop)
拖拽上传组件(Drag and Drop Upload)
可编辑表格组件(Editable Table)
可排序表格组件(Sortable Table)

6-响应式组件:

响应式导航栏(Responsive Navbar)
响应式布局容器(Responsive Layout Container)

以上仅是一些常见的组件类型,实际上我在项目中根据具体需求还封装了许多其他类型的组件。
组件的封装旨在提高代码的可重用性、可维护性和可扩展性,同时也有助于团队合作和项目的开发效率。

2.11 vue的自定义指令用过没

1
2
3
4
5
6
7
8
Vue 的自定义指令允许开发者根据自己的需求定义全局或局部的指令,
并在模板中通过指令的方式来实现一些特定的行为。

自定义指令可以用于实现一些与 DOM 直接交互的功能,例如:

1-事件监听:监听 DOM 事件并触发相应的逻辑。
2-DOM 操作:直接操作 DOM 元素的属性、样式、内容等。
3-数据绑定:根据数据的变化更新 DOM 的状态。

三 参考

  • ChatGPT3.5