20240309-1-校招前端面试常见问题-前端框架及常用工具

校招前端面试常见问题【5】——前端框架及常用工具

在这里插入图片描述

React

Q:请简述一下虚拟 DOM 的概念?

基于 React 进行开发时所有的 DOM 构造都是通过虚拟 DOM 进行,每当数据变化时,React 都会重新构建整个 DOM 树,然后 React 将当前整个 DOM 树和上一次的 DOM 树进行对比,得到 DOM 结构的区别,然后仅仅将需要变化的部分进行实际的浏览器 DOM 更新。

React 在构建 DOM 的时候,是使用 javascript 的对象模拟 DOM 的,针对 js 的对象进行比较要比针对浏览器 DOM 进行比较的开销小很多。

Q:请简述一下 React 的生命周期?
Q:请简述一下 React Fiber 的概念?

在页面元素很多,且需要频繁刷新的场景下,React 15 会出现掉帧的现象。那么为什么会出现掉帧问题呢?其根本原因,是大量的同步计算任务阻塞了浏览器的 UI 渲染。默认情况下,JS 运算、页面布局和页面绘制都是运行在浏览器的主线程当中,他们之间是互斥的关系。如果 JS 运算持续占用主线程,页面就没法得到及时的更新。当我们调用 setState 更新页面的时候,React 会遍历应用的所有节点,计算出差异,然后再更新 UI。如果页面元素很多,整个过程占用的时机就可能超过 16 毫秒,就容易出现掉帧的现象。而原因就是 React 15 采用的是递归的方式遍历整颗组件树。

react16 将底层更新单元的数据结构改成了链表结构。以前的协调算法是递归调用,通过 react dom 树级关系构成的栈递归。而 fiber 是扁平化的链表的数据存储结构,通过 child 找第一个子节点,return 找父节点,sibling 找兄弟节点。遍历从递归改为循环。

这是 React 核心算法的一次大的更新,重写了 React 的 reconciliation 算法。reconciliation 算法是用来更新并且渲染 DOM 树的算法。以前 React 15.x 的版本使用的算法称为“stack reconciliation”,现在称为“fiber reconciler”。

fiber reconciler 主要的特点是可以把更新流程拆分成一个一个的小的单元进行更新,并且可以中断,转而去执行高优先级的任务或者浏览器的动画渲染等,等主线程空闲了再继续执行更新。

对于流畅度问题,我们很容易想到一个 api:requestldleCallback , 这个 api 可以在浏览器空闲的时候执行回调,我们把复杂的任务分片在浏览器空闲的时间执行,就不会影响浏览器的渲染等工作。这个就可以解决复杂任务长时间霸占主线程导致渲染延迟。

但是可能由于兼容性的考虑,react 团队放弃了这个 api,转而利用 requestAnimationFrame 和 MessageChannel pollyfill 了一个 requestIdleCallback

当前帧先执行浏览器的渲染等任务,如果当前帧还有空闲时间,则执行任务,直到当前帧的时间用完。如果当前帧已经没有空闲时间,就等到下一帧的空闲时间再去执行。

Q:React setState 的时机?

使用 setState 时不会直接更新数据,而是会直接将其挂到更新队列中。
更新的时机是:当前宏任务结束后,微任务开始前。

this.state = {
  a: 1,
}

// 这种情况只会+1,因为它相当于Object.assign(oldState, {count: XXX}, {count: XXX})
this.setState({ count: this.state.count + 1 })
this.setState({ count: this.state.count + 1 })

console.log(this.state.count) // 这时候会取到原来的state,也就是1

// 进行改造,这样就一定会+2了
this.setState((state, props) => {
  return { count: state.count + 1 }
})
this.setState((state, props) => {
  return { count: state.count + 1 }
})

Vue

Q:什么是 mvvm 模式?

M: 模型 => 数据,业务逻辑,验证逻辑,模型常常包含业务逻辑。
V: 视图 => 交互界面,是模型数据的可视化呈现,视图可能包含展示逻辑。
VM:视图和模型的中间人。

数据双向绑定:V 的变动直接反映在了 VM 上,M 的变化也直接反映在了 VM 上。

Q:请简述一下 vue 响应式数据的原理?

响应式数据的关键在于:data 如何更新 view,以及 view 如何更新 data。

1、view 更新 data 可以通过事件监听,比如 input 标签监听 ‘input’ 事件就可以实现了。

2、而 data 更新 view 的重点是如何知道数据变了。这时候我们就通过Object.defineProperty()对属性设置一个 set 函数,当数据改变了就会来触发这个函数,所以我们只要将一些需要更新的方法放在这里面就可以实现 data 更新 view 了。

Object.defineProperty 的具体用法:

Object.defineProperty(obj, prop, descriptor)
obj:要在其上定义属性的对象。
prop:要定义或修改的属性的名称。
descriptor:将被定义或修改的属性描述符。

descriptor 具有以下两种可选值:
get:给属性提供 getter 的方法,如果没有 getter 则为 undefined。当访问该属性时,该方法会被执行,方法执行时没有参数传入,但是会传入 this 对象。
set:给属性提供 setter 的方法,如果没有 setter 则为 undefined。当属性值修改时,触发执行该方法。该方法将接受唯一参数,即该属性新的参数值。

一个简单的响应式数据的例子:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>defineProperty</title>
  </head>
  <body>
    <div id="app">
      <input type="text" id="txt" />
      <p id="show"></p>
    </div>

    <script>
      let obj = {}

      Object.defineProperty(obj, 'txt', {
        get: function () {
          return obj
        },
        set: function (newValue) {
          document.getElementById('txt').value = newValue
          document.getElementById('show').innerHTML = newValue
        },
      })
      document.addEventListener('keyup', function (e) {
        obj.txt = e.target.value
      })
    </script>
  </body>
</html>
Q:请简述一下 Vue 的生命周期?
Q:请简述一下 Vue router 的原理?

Vue router 有两种模式:hash 模式和 history 模式,分别对应了两种原理:

hash 模式:

hash("#")符号的本来作用是加在 URL 指示网页中的位置,例如:
http://www.example.com/index.html#print

#本身以及它后面的字符称之为 hash 可通过 window.location.hash 属性读取。
hash 虽然出现在 url 中,但不会被包括在 http 请求中,对服务器端完全无用,因此,改变 hash 不会重新加载页面。

我们可以为 hash 的改变添加监听事件:
window.addEventListener("hashchange",funcRef,false)

每一次改变 hash,我们都会重新注入对应的组件,就可以来实现前端路由"更新视图但不重新请求页面"的功能了。

history 模式:

从HTML5开始,History interface提供了2个新的方法:pushState(),replaceState()使得我们可以对浏览器历史记录栈进行修改。

window.history.pushState(stateObject, title, URL)
window.history.replaceState(stateObject, title, URL)

stateObject: 当浏览器跳转到新状态时,触发popState事件,该事件将携带stateObject参数的副本
title: 所添加记录的标题
URL: 所添加记录的URL

我们可以为window.history的改变添加监听事件:
window.addEventListener("popstate",funcRef,false)

在监听事件中,重新注入对应的组件,就可以来实现前端路由"更新视图但不重新请求页面"的功能了。

用 HTML5 实现,单页路由的 url 就不会多出一个#,变得更加美观。但因为没有 # 号,所以当用户刷新页面之类的操作时,浏览器还是会给服务器发送请求,可能会造成404。

打包工具

Q:介绍一下 webpack?

webpack 是一个模块打包工具,在 webpack 中,一切文件都是模块,webpack 能做的就是将它们打包在一起。

webpack 在配置时主要有如下常用属性:

1、entry 以及 output:
入口起点(entry point)指示 webpack 应该使用哪个模块,来作为构建其内部依赖图的开始。进入入口起点后,webpack 会找出有哪些模块和库是入口起点(直接和间接)依赖的。

output 属性告诉 webpack 在哪里输出它所创建的 bundles,以及如何命名这些文件,默认值为 ./dist。基本上,整个应用程序结构,都会被编译到你指定的输出路径的文件夹中。你可以通过在配置中指定一个 output 字段,来配置这些处理过程。

const path = require('path')
module.exports = {
  entry: './path/to/my/entry/file.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'my-first-webpack.bundle.js',
  },
}

2、loader:
loader 让 webpack 能够去处理那些非 JavaScript 文件。loader 可以将所有类型的文件转换为 webpack 能够处理的有效模块,然后你就可以利用 webpack 的打包能力,对它们进行处理。
本质上,webpack loader 将所有类型的文件,转换为应用程序的依赖图(和最终的 bundle)可以直接引用的模块。

const path = require('path')
const config = {
  module: {
    rules: [{ test: /\.txt$/, use: 'raw-loader' }],
  },
}

3、plugins:
插件相比于 loader,可以用于执行范围更广的任务,比如压缩打包,优化等。想要使用一个插件,你只需要 require() 它,然后把它添加到 plugins 数组中。

const HtmlWebpackPlugin = require('html-webpack-plugin') // 通过 npm 安装
const webpack = require('webpack') // 用于访问内置插件
const config = {
  module: {
    rules: [{ test: /\.txt$/, use: 'raw-loader' }],
  },
  plugins: [new HtmlWebpackPlugin({ template: './src/index.html' })],
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/442355.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

selenium之PO设计模式

初识PO模式 PO&#xff08;PageObject&#xff09;是一种设计模式。简单来说就是把一些繁琐的定位方法、元素操作方式等封装到类中&#xff0c;通过类与类之间的调用完成特定操作。 PO被认为是自动化测试项目开发实践的最佳设计模式之一。 在学习PO模式前&#xff0c;可以先…

力扣日记3.8-【回溯算法篇】37. 解数独

力扣日记&#xff1a;【回溯算法篇】37. 解数独 日期&#xff1a;2023.3.8 参考&#xff1a;代码随想录、力扣 37. 解数独 题目描述 难度&#xff1a;困难 编写一个程序&#xff0c;通过填充空格来解决数独问题。 数独的解法需 遵循如下规则&#xff1a; 数字 1-9 在每一行只…

存货计价方式 比较-移动平均和批次计价

SAP常用的存货计价方式有 标准价格移动平均价格批次计价 标准价格常用于制造企业&#xff0c;今天的方案比较主要集中在销售型企业常用的移动平均价和批次计价 批次计价&#xff1a; 移动平均&#xff1a; 两种计价方式的Pros&Cons 比较 批次计价 移动平均优点 1…

基于单片机的水平角度仪系统设计

目 录 摘 要 I Abstract II 引 言 1 1控制系统设计 3 1.1系统方案设计 3 1.2系统工作原理 4 2硬件设计 6 2.1单片机 6 2.1.1单片机最小系统 6 2.1.2 STC89C52单片机的性能 7 2.2角度采集电路 8 2.2.1 ADXL345传感器的工作原理 9 2.2.2 ADXL345传感器倾角测量的原理 9 2.2.3 AD…

YOLOv8优化策略:特征融合篇 | GELAN(广义高效层聚合网络)结构来自YOLOv9

🚀🚀🚀本文改进:使用GELAN改进架构引入到YOLOv8 🚀🚀🚀YOLOv8改进专栏:http://t.csdnimg.cn/hGhVK 学姐带你学习YOLOv8,从入门到创新,轻轻松松搞定科研; 1.YOLOv9介绍 论文: 2402.13616.pdf (arxiv.org) 摘要: 如今的深度学习方法重点关注如何设计最合适…

用 ChatGPT 搭配 STAR 原则,准备英文面试超轻松

用 ChatGPT 搭配 STAR 原则&#xff0c;准备英文面试超轻松 ChatGPT 除了可以帮忙改简历&#xff0c;在你的求职历程中&#xff0c;ChatGPT 也可以帮忙练英文面试。在我们实测之后&#xff0c;发现 ChatGPT 在练习英文面试上&#xff0c;不仅能针对你的回答给予回馈&#xff0…

Docker下Jenkins打包java项目并部署

docker 构建Jenkins sudo docker run --namezen_haslett --userjenkins --privilegedtrue --volume/home/cyf/server/jenkins/jenkins_home:/var/jenkins_home -v /usr/lib/jvm/java-17-openjdk-amd64:/usr/lib/jvm/java-17-openjdk-amd64 -v /usr/lib/maven/apache-mav…

FFmpeg--AAC音频解码流程

文章目录 AAC 组成函数分析读aac帧写aac帧aac的head参数设置 运行结果 AAC 组成 AAC音频格式&#xff1a;是⼀种由MPEG-4标准定义的有损⾳频压缩格式 ADTS:是AAC音频的传输流格式 AAC音频文件的每一帧由ADTS Header和AAC Audio Data组成 每⼀帧的ADTS的头⽂件都包含了⾳频的采…

ArmSoM Rockchip系列产品 通用教程 之 GPIO 使用

1. GPIO简介​ GPIO&#xff0c;全称 General-Purpose Input/Output&#xff08;通用输入输出&#xff09;&#xff0c;是一种在计算机和嵌入式系统中常见的数字输入输出接口。它允许软件控制硬件的数字输入和输出&#xff0c;例如开关、传感器、LED灯等。GPIO通常由一个芯片或…

C++矢量运算与java矢量运算

矢量运算 概述&#xff1a; 矢量运算是一种基于向量的数学运算&#xff0c;它遵循特定的法则。以下是矢量运算的一些基本原理&#xff1a; 矢量加法&#xff1a;可以使用平行四边形法则或三角形法则来执行。当两个矢量相加时&#xff0c;可以将它们的起点放在同一个点上&…

【硬件设计】(更新中)以 UCC27710 为例设计栅极驱动器元件选型(资料摘抄)

还没更新完。。。。。。。 【仅作自学记录&#xff0c;不出于任何商业目的。如有侵权&#xff0c;请联系删除&#xff0c;谢谢&#xff01;】 本文摘抄翻译自&#xff1a; Bootstrap Network Analysis: Focusing on the Integrated Bootstrap Functionality (infineon.com)Boo…

[nlp入门论文精读] | Transformer

写在前面 最近工作从CV转向了NLP&#xff0c;于是空余时间便跟着哔哩哔哩李沐老师的视频学习。其实研一NLP课程讲论文的时候&#xff0c;我们小组就选择了经典的Attention和Bert&#xff0c;但还有很多细节并不完全理解&#xff0c;实际使用时也很困惑。 因此这个系列就来记…

【Android 内存优化】KOOM 快手开源框架线上内存监控方案-源码剖析

文章目录 前言OOMMonitorInitTask.INSTANCE.initOOMMonitor.INSTANCE.startLoopsuper.startLoopcall() LoopState.Terminate dumpAndAnalysisdumpstartAnalysisService回到startLoop方法总结 前言 这篇文章主要剖析KOOM的Java层源码设计逻辑。 使用篇请看上一篇: 【Android …

Kubesphere前端项目分析

1 KubeSphere console功能导图 模块&#xff1a; 命令行工具 (kubectl) 日志&#xff08;Logging&#xff09; 平台设置&#xff08;Platform Settings&#xff09; 服务组件&#xff08;Service Components&#xff09; 监控和警报&#xff08;Monitoring & Alerting&…

手写分布式配置中心(六)整合springboot(自动刷新)

对于springboot配置自动刷新&#xff0c;原理也很简单&#xff0c;就是在启动过程中用一个BeanPostProcessor去收集需要自动刷新的字段&#xff0c;然后在springboot启动后开启轮询任务即可。 不过需要对之前的代码再次做修改&#xff0c;因为springboot的配置注入value("…

pytest教程-15-多个fixture以及重命名

领取资料&#xff0c;咨询答疑&#xff0c;请➕wei: June__Go 上一小节我们学习了fixture的yield关键字&#xff0c;本小节我们讲解一下使用多个fixture的方法。 使用多个fixture 如果用例需要用到多个fixture的返回数据&#xff0c;fixture也可以return一个元组、list或字…

[嵌入式系统-37]:龙芯1B 开发学习套件 -7-MIPS指令集

目录 一、MIPS指令分类 二、常用指令详解 三、常用MIPS指令集及格式&#xff1a; 四、CPU内部的32个寄存器&#xff1a; 一、MIPS指令分类 MIPS&#xff08;Microprocessor without Interlocked Pipeline Stages&#xff09;指令集是一种广泛用于教学和嵌入式系统的指令集…

在线部署ubuntu20.04服务器,安装jdk、mysql、redis、nginx、minio、开机自启微服务jar包

一、服务器 1、查看服务器版本 查看服务器版本为20.04 lsb_release -a2、服务器信息 服务器初始账号密码 sxd / 123456 首先,更改自身密码都输入123456 sudo passwd 创建最高权限root账号&#xff0c;密码为 123456 su root 3、更新服务器源 1、更新源列表 sudo apt-g…

【golang】Windows与Linux交叉编译保姆级教程

【golang】Windows与Linux交叉编译 大家好 我是寸铁&#x1f44a; 总结了一篇【golang】Windows与Linux交叉编译的文章✨ 喜欢的小伙伴可以点点关注 &#x1f49d; 问题背景 今天寸铁想将Windows中的程序部到Linux下跑&#xff0c;我们知道在从Windows与Linux下要进行交叉编译…

11、Linux-安装和配置Redis

目录 第一步&#xff0c;传输文件和解压 第二步&#xff0c;安装gcc编译器 第三步&#xff0c;编译Redis 第四步&#xff0c;安装Redis服务 第五步&#xff0c;配置Redis ①开启后台启动 ②关闭保护模式&#xff08;关闭之后才可以远程连接Redis&#xff09; ③设置远程…