Skip to content
小 K. 同学

小 K. 同学

Author

1. 组件通信方式

组件的通信方式分为两大类,一类是 父子组件通信,另一类是 任何关系类型组件通信(父子、兄弟、非兄弟)

Vue 组件

  1. 父子组件的通信方式:

    • 父 → 子:通过给子组件添加 自定义属性,比如:<List :list="list"/>,list 是父组件给子组件传递的数据。子获取父的数据,在子组件中使用 props 属性获取

    • 子 → 父:在子组件通过 emit 触发自定义方法,在父组件监听此方法并实现对应的处理函数,比如:父组件中有 <List @delete="deleteHandler"/> 组件,deleteHandler 就是在父组件中的声明的处理函数,在子组件中通过 this.$emit('delete', 数据)(vue3 composition-api 中直接使用 emit 函数,不再使用 this),从而调用父组件的方法,并把数据传递到父组件

    • props 是只读属性,不可以被修改,所有被修改都会失效且报警告

  2. 任何关系类型组件通信(父子、兄弟、非兄弟)方式:

    • EventBus稍微大一点的系统不推荐):使用方法是创建一个新的 Vue 实例,需要通信的组件都引入该 Vue 实例,传递数据的组件使用 event.$emit('名称',参数) 发送数据,接收数据的组件使用 event.$on('名称',方法) 接收数据

    • VueX(Pinia):集中管理项目公共数据,Vuex 的状态存储是响应式的,当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。不能直接改变 store 中的状态。改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation

    • $root / $parent / $children不推荐):通过拿到 根组件/父组件/子组件 的实例,然后直接去操作获取数据或调用该组件的方法

EventBus 的优缺点:

  • 优点:解决了多层组件之间繁琐的事件传播,使用原理十分简单,代码量少。适合业务简单,组件传递数据较少的项目,大型项目业务复杂的还是尽量使用 VueX(Pinia)

  • 缺点:vue 是单页应用,如果你在某一个页面刷新了之后,与之相关的 EventBus 会被移除,这样就导致业务走不下去。同时如果页面中有反复操作的业务,EventBus 在监听的时候就会触发很多次,需要好好处理 EventBus 在项目中的关系。在 vue 页面销毁时,同时移除 EventBus 事件监听,否则容易造成内存泄漏

React 组件

  1. 父子组件:

    • 父 → 子:通过 props 自定义属性传递给子组件

    • 子 → 父:

      • 通过父组件 props 自定义方法,在子组件中调用对应的方法,然后通过参数传递给父组件
      • 在父组件定义 ref,传递给子组件(子组件是函数组件就需要 ref 转发来实现了),在子组件实现方法,父组件直接通过 ref 实例调用子组件的方法获取数据
  2. 兄弟组件:

    若两个组件共用一个父组件,那么我们可以考虑把它们的共享数据提升保存在它们的父组件中,并定义对应的方法来触发数据变更,并将数据及更新方法分别传递给两个兄弟子组件即可

  3. 任何关系类型的组件:

    • Context 上下文:当某些数据全局或部分全局共享时,而且可能是某节点跟它很深的一个组件才会共享时,就可以考虑在这个节点上声明一个上下文共享数据(否则用 props 一层一层往下传就特别复杂)。通过 React.createContext(defaultValue) 来创建上下文数据

    • Redux:全局状态管理库,任何一个组件都可使用其中存储的数据,并通过固定的 dispatch 方法去更新数据 → 使用详情可见

2. 浏览器输入 URL 发生了什么?

关键点

DNS 解析、TCP 握手、HTTP 缓存、重定向、服务器状态码、渲染引擎和 JS 引擎互斥、渲染过程、浏览器进程、网路进程、渲染进程

整个过程大概分为如下六步:

  1. DNS 域名解析(获取服务器 ip 地址)

    • (针对域名)按顺序检索浏览器 DNS 缓存、操作系统 DNS 缓存、系统 hosts 文件、本地配置的首选 DNS 服务器

    • 若直接访问的是 ip 地址,则会跳过 DNS 域名解析

  2. 建立 TCP 连接

    • 为了确保客户端与服务端能准确地传输数据,TCP 协议采用了 三次握手 策略(确保双方均有发送与接收数据的能力):发送端首先发送一个带 SYN(synchronize)标志 的数据包给接收方,接收方收到后,回传一个带有 SYN/ACK(acknowledegment)标志 的数据包以示传达确认信息。最后发送方再回传一个带 ACK标志 的数据包,代表握手结束

    • 而且可以引申(🫥)更多知识点:TCP与UDP三次握手🤝四次挥手🙋‍♂️的过程... (比如:TCP 协议灵魂之问

  3. 发起 HTTP 请求

    • 在浏览器地址栏输入某域名实际上是默认的 GET 请求,获取对应的资源文件

    • 引申(🫥),比如:1. http 请求头 originhostreferer 三者有什么区别,为什么要设定这三个字段;2. 强缓存协商缓存

  4. 接受响应结果

    • 响应结果一般为 html 文件

    • 引申(🫥):http 状态码有哪些,分别代表什么含义?

  5. 浏览器解析 HTML

    • 浏览器按顺序解析 html 文件,构建 DOM Tree,在解析到外部的 css 和 js 文件时,向服务器发起请求下载资源。若是下载 css 文件不会阻塞 DOM Tree 的构建,并构建 CSS Tree,但在下载 js 文件和执行它时会阻塞 DOM Tree 的构建

    • DOM TreeCSS Tree 构建完毕后,浏览器引擎会将它们结合形成 渲染树(🌲)(渲染树中包含可视节点的样式信息,如 head 元素,属性为 display: none; 等不会出现在渲染树中)

    Notice

    注意这个过程是逐步完成的,比如:有时网络环境比较差时,我们会看到整个页面是一行一行加载出来的。因为它是解析完一部分内容就显示一部分内容,同时,可能还在通过网络下载其余的内容

  6. 浏览器布局渲染

    • 布局(Layout):通过计算得到每个渲染对象在可视区域中的具体位置信息(大小和位置),这是一个递归的过程

    • 绘制(Paint):将计算好的每个像素点信息绘制在屏幕上

    • 在页面显示的过程中会多次进行 Reflow(重排)Repaint(重绘) 操作,而 Reflow 的成本比 Repaint 的成本高得多的多。因为 Repaint 只是将某个部分进行重新绘制而不用改变页面的布局(比如元素背景颜色或字体颜色的改变);而当更改的元素属性影响到页面布局的情况时,就会触发 Reflow(比如某个元素 display 属性由 block 变为 none)

    • 引申(🫥):如何减少 Reflow 和 Repaint?

3. 说一说 BFC

关键点

块级格式化上下文、独立的渲染区域、不会影响边界以外的元素、形成 BFC 条件、float、position、overflow、display

  1. BFC:(Block Formatting Context) 块级格式化上下文,它是 Web 页面一块独立的渲染区域,内部元素有一套自己的渲染规则

  2. BFC 规则:

    • 内部盒子会在垂直方向,一个接一个地放置
    • 内部盒子垂直方向的距离由 margin 决定,属于同一个 BFC 的两个相邻盒子的 margin 会发生 重叠
    • 内部盒子(block / inline-block)的左外边距与包含块的左边界相接触(从左到右排列时),即使浮动元素也是如此
    • BFC 的区域不会与 float box 重叠
    • 计算 BFC 的高度时,浮动子元素也参与计算
    • BFC 就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素,反之亦然
  3. BFC 形成条件:

    • 根元素,web 页面的 html 元素
    • float 设置成 leftright
    • positionabsolutefixed
    • overflowautoscrollhidden(非visible
    • displayflexinline-blocktable-celltable-captiontableinline-tableinline-flexgridinline-grid

4. 怎么理解 MVVM?

MVVM:就是 Model-View-ViewModel

  • Model:模型层,负责处理业务逻辑以及和服务器端进行交互
  • View:视图层:负责将数据模型转化为 UI 展示出来,可以简单的理解为 HTML 页面
  • ViewModel:视图模型层,用来连接 Model 和 View,是 Model 和 View 之间的通信桥梁

5. 怎么理解组件化?

一句话来说就是把图形、非图形的各种逻辑均抽象为一个统一的概念(组件)来实现开发的模式

组件化的优势:

  1. 降低整个系统的耦合度,可以替换不同的组件快速完成需求,类似搭积木的方式

  2. 方便调试,我们一般会基于单一职责原则来封装组件,所以在排查问题时能够快速定位

  3. 提高可维护性,因为都是复用的组件,所以对组件代码的优化将会使系统整体进行升级

6. SPA(单页应用)的理解

SPA(single-page application):它是一种网络应用程序或网站的模型,它通过动态重写当前页面来与用户交互

SPA 不会因为用户的操作而进行页面的重载,取而代之的是利用路由机制来实现 HTML 的替换、UI 交互等功能

优点:

  • 用户体验好,(内部页面跳转)加载速度快
  • 对服务器压力相对较小
  • 前后端职责分离,架构清晰

缺点:

  • 初次加载相对耗时较长,需要加载整个系统的 JS、CSS 等资源(可按需加载)
  • SEO 弱势

DANGER

This is split line =================

11. webpack 与 rollup 的区别?webpack5 与 webpack4?

打包工具对比 🔗

12. composition-api 与 hooks 的异同点?

react 对 hook 的定义是:

它可以让你在不编写 class 的情况下,让你在函数组件里 “钩入” React state 及生命周期等特性的函数

vue 的 composition-api(我们也可称为 Vue Hooks),它受到了 React Hooks 的启发,但也有些不同,规避了一些 react 的问题

在 hook 思想出来之前,针对业务上的逻辑复用功能:vue 采用 mixins 方案,react 采用 render props高阶组件 的方案处理

  • mixins 与组件之前是隐式依赖,可能会产生冲突(比如我们定义的方法名、数据名重名的情况)
  • 高阶组件和 render props 容易导致组件嵌套层次过深,增大复杂度和维护成本

不同点:

  1. React Hooks 是基于 链表 实现的,不能在循环内部、条件语句中或嵌套函数里调用 Hooks;Vue Hooks 定义在 setup 函数中,由于它数据的响应式是基于 Proxy 实现的,只要更改数据就会触发对应的依赖函数执行更新操作,所以避开了 react 可能遇到的性能问题

  2. 代码执行时机:React hooks 在组件每次渲染时都会运行;Vue Hooks 定义在 setup() 函数中,它会早于 beforeCreatecreated 生命周期函数,且仅执行一次

  3. React 使用 useState Hook 来声明数据,传入一个参数作为数据初始值(只会在初次运行这个函数时使用这个值进行初始化);Vue 中使用 refreactive 这两个函数来定义数据

13. vue 中的 jsx 与 react 的 jsx 区别?

vue 组件使用 jsx 需要使用插件进行编译,react 组件中是默认支持的

vue template 与 react jsx 的区别:

vue 中提供一系列指令帮助我们构建页面

14. 说说 XSS 攻击与防范?

XSS 攻击(Cross-Site Scripting,跨站脚本攻击),它是页面中被注入了恶意的代码

一般,XSS 攻击有下列注入方式:

  • 在 HTML 中内嵌的文本中,恶意内容以 script 标签形成注入
  • 在内联的 JavaScript 中,拼接的数据突破了原本的限制(字符串,变量,方法名等)
  • 在标签属性中,恶意内容包含引号,从而突破属性值的限制,注入其他属性或者标签
  • 在标签的 href、src 等属性中,包含 javascript: 等可执行代码
  • 在 onload、onerror、onclick 等事件中,注入不受控制代码
  • 在 style 属性和标签中,包含类似 background-image:url("javascript:..."); 的代码(新版本浏览器已经可以防范)
  • 在 style 属性和标签中,包含类似 expression(...) 的 CSS 表达式代码(新版本浏览器已经可以防范)

防范手段(可能并不全面):

  • 输入过滤,这也仅限于明确类型的用户输入,比如 数字URL邮箱 等内容进行必要的过滤处理

  • 输入长度限制,虽不能完全防止,但可以增加 XSS 攻击的难度

  • 做纯前端渲染,将数据与代码分隔开,对 HTML 做充分 转义(输出 HTML 时进行)

  • 纯前端渲染方案中,尽量采用 .innerText.textContent.setAttribute 等 API,避免使用 .innerHTML.outerHTML.document.write() 等 API;在 vue/react 框架中,避免使用 v-html/dangerouslySetInnerHTML 功能;注意关注 DOM 内联事件或 <a> 标签的 href 属性,js 的 eval()setTimeout()setImmediate()setInterval() 等 API 均能将 字符串 作为代码直接执行

15. DNS 劫持

域名解析需要由专门的域名解析服务器来完成,DNS 就是进行域名解析的服务器(Domain Name SystemDomain Name Service

在网络中,机器之间是通过 ip 地址互相访问与通信的,但是为了便于记忆,就可以为每个 ip 配置对应的 域名,然后我们直接通过访问域名的方式,由浏览器去进行 DNS 解析获取到对应的 ip 地址,达到访问目标的目的(这也是常规八股文 浏览器输入 URL 发生了什么 🔗 的第一步 DNS 域名解析 做的事情)

DNS 劫持 又称为 域名劫持,它是指通过某些手段获得某些域名的解析控制权,在你访问某个域名时,给你返回错误的 ip 地址,结果就是网址无法访问或者假网址(比如攻击者搭建一个跟原网址 长得一样 的页面,你在这个网站的一切操作,比如登录的账号、密码等信息,可能都被其记录并发送到攻击者手里了)。DNS 劫持 并不是说 黑掉了 对方的网站,而是一种 冒名顶替无响应 的攻击方式

DNS 劫持方法:

  • 利用 DNS 劫持进行 DDoS 攻击 🔗

    由于在 DNS 缓存未命中的情况下,会向 DNS 服务器发起递归查询,拿到映射结果后逐级缓存。假如在此过程中攻击者已知我们的 IP 地址,且攻击者拥有足够数量的 肉鸡,反复的进行如上操作,那么我们就会受到来自于 DNS 服务器的响应信息 DDoS 攻击(结果就是 我们的网络被拖垮至发生中断

  • DNS 缓存感染

    攻击者使用 DNS 请求,将数据放入一个具有漏洞的的 DNS 服务器的缓存当中,我们在进行 DNS 访问时拿到这些污染的缓存信息,从而将我们正常的域名访问 导向访问攻击者设置的钓鱼 🎣 网站,或通过其他伪造手段获取用户账号密码信息等的攻击手段

  • DNS 信息劫持

    假设攻击者如果通过监听客户端和 DNS 服务器的对话,在 DNS 服务器之前将虚假的响应交给用户,从而 欺骗客户端去访问恶意的网站

  • DNS 重定向

    攻击者将 DNS 名称查询重定向到恶意 DNS 服务器上,被劫持 域名的解析就完全在攻击者的控制之下

  • ARP 欺骗

    ARP 攻击就是通过伪造 IP 地址和 MAC 地址实现 ARP 欺骗,能够在网络中产生大量的 ARP 通信量使网络阻塞,造成网络中断 或 中间人攻击

  • 本机劫持

    本机的计算机系统被木马或流氓软件感染后,DNS 缓存被修改导致域名访问异常。本机 DNS 劫持方式包括 hosts 文件篡改本机 DNS 劫持SPI 链注入BHO 插件 等方式

防止 DNS 劫持方法(网络层):

  • 准备多个域名,可能出现一个被攻击的情况下,能够有其他域名可以正常访问

  • 手动修改路由器 首选DNS备用DNS IP

    • 地址栏输入 192.168.0.1 / 192.168.1.1 登录进入路由器管理界面
    • DHCP服务器—DHCP 服务中,填写 主选DNS服务器 为更可靠的 114.114.114.114 地址,备用DNS服务器8.8.8.8
    • 隔段时间重新设置路由器登录密码

16. 说说 cors 跨站脚本攻击防范?

CORS:跨域资源共享(Cross-origin resource sharing),它使用额外的 HTTP 头来告诉浏览器让运行在一个 origin (domain) 上的 Web 应用被准许访问来自不同源服务器上的指定的资源

cors 将请求分为两种:

  • 简单请求(simple request)
  • 非简单请求(preflight request),会首先发送一个 OPTIONS 预检请求

简单请求 需要满足以下条件:

  • 请求的方法只能是 GET, POST, HEAD 的一种
  • 请求的 header 的只能是 AcceptAccept-Language, Content-LanguageContent-Type 这些字段,不能超出这些字段
  • Content-Type 字段,只能是以下值:
    • text/plain
    • multipart/form-data
    • application/x-www-form-urlencoded

除此之外,均是非简单请求

非简单请求,先发出预检请求,检查当前请求是否符合服务器的 cors 配置,如果符合,则再发出真正的请求;不符合则直接返回跨域

如果预检请求通过了,在一定时间内重复请求是不用再次发起预检请求

17. 说说 CSRF 跨站请求伪造防范?

18. devOps(如 jenkins 等)

19. 测试框架(jest)

20. 说一说 qiankun 的路由匹配原理

MIT