一篇写给前端的精选面试题,中大厂面试重复率高到爆!!!

写在前面

针对前端环境恶劣,很多人在前端面试的时候都直接去找相关公司的面经,或者没有真正新一点各个厂里常用面试题,现在小编给大家整理好了,前端面试无非就是那些,面试题更别谈新旧,只不过很多公司常用框架来说,面试内容也各不相同,那么vue和react作为经常出现的老大哥,各位工作上的小娇妻,应该都很熟悉,基本掌握这俩个钥匙那么就算成功了一小半。

毕竟还有算法,手写题之类的出现,不知道各位遇没遇见去公司面试,进门就是七八张纸全是手写题的情况,就很离谱,但因为坑位确实是少,哪怕你知道他是坑,也得往下跳

目录合集

面试题整理

React.js 面试真题

★★★ React 事件绑定原理

/*
一、react 并没有使用原生的浏览器事件,而是在基于 Virtual DOM 的基础上实现
了合成事件。
二、react 合成事件主要分为以下三个过程:
1、事件注册
document 上注册、存储事件回调。
2、事件合成
事件触发后,会执行一下过程:
(1)进入统一的事件分发函数 dispatchEvent;
(2)找到触发事件的 ReactDOMComponent;
(3)开始事件的合成;
—— 根据当前事件类型生成指定的合成对象
—— 封装原生事件和冒泡机制
—— 查找当前元素以及他所有父级
—— 在 listenerBank 根据 key 值查找事件回调并合成到 event(合成事
件结束)
3、批处理
批量处理合成事件内的回调函数
*/

★★★ React 中的 setState 缺点是什么呢

setState 执行的时候可以简单的认为,隶属于原生 js 执行的空间,那么就是属于
同步,被 react 处理过的空间属于异步,这其实也是一种性能的优化,如果多次使用 setState
修改值,那么在异步中会先进行合并,再进行渲染,降低了操作 dom 的次数

★★★ React 组件通信如何实现

/*
react 本身:
(1)props——父组件向子组件通过 props 传参
(2)实例方法——在父组件中可以用 refs 引用子组件,之后就可以调用子
组件的实例方法了
(3)回调函数——用于子组件向父组件通信,子组件调用 props 传递过来的
方法
(4)状态提升——两个子组件可以通过父组件定义的参数进行传参
(5)Context 上下文——一般用作全局主题
(6)Render Props——渲染的细节由父组件控制
状态管理:
(1) mobx/redux/dva——通过在 view 中触发 action,改变 state,进而
改变其他组件的 view
*/

★★★ 类组件和函数组件的区别

/* (1)语法上:函数组件是一个函数,返回一个 jsx 元素,而类组件是用 es6
语法糖 class 定义,继承 component 这个类
(2)类组件中可以通过 state 进行状态管理,而在函数组件中不能使用
setState(),在 react16.8 以后,函数组件可以通过 hooks 中的 useState 来模拟类组件
中的状态管理;
(3)类组件中有一系列的生命周期钩子函数,在函数组件中也需要借助 hooks
来使用生命周期函数;
(4)类组件能够捕获**最新**的值(永远保持一致),这是因为当实例的 props
属性发生修改时,class 组件能够直接通过 this 捕获到组件最新的 props;而函数式组件是
捕获**渲染**所使用的值,已经因为 javascript**闭包**的特性,之前的 props 参数保存
在内存之中,无法从外部进行修改。
*/

★★★★ 虚拟 DOM 的优劣如何?实现原理?

/* 虚拟 dom 是用 js 模拟一颗 dom 树,放在浏览器内存中,相当于在 js 和真实 dom 中
加了一个缓存,利用 dom diff 算法避免了没有必要的 dom 操作,从而提高性能。
优点:
(1)虚拟 DOM 具有批处理和高效的 Diff 算法,最终表现在 DOM 上的修改只是变更
的部分,可以保证非常高效的渲染,优化性能;
(2)虚拟 DOM 不会立马进行排版与重绘操作,对虚拟 DOM 进行频繁修改,最后一
次性比较并修改真实 DOM 中需要改的部分;
(3)虚拟 DOM 有效降低大面积真实 DOM 的重绘与排版,因为最终与真实 DOM 比
较差异,可以只渲染局部;
缺点:
(1)首次渲染大量 DOM 时,由于多了一层虚拟 DOM 的计算,会比 innerHTML 插入
慢;
React 组件的渲染过程:
(1)使用 JSX 编写 React 组件后所有的 JSX 代码会通过 Babel 转化为
React.createElement 执行;
(2)createElement 函数对 key 和 ref 等特殊的 props 进行处理,并获取
defaultProps 对默认 props 进行赋值,并且对传入的子节点进行处理,最终构造成一个
ReactElement 对象(所谓的虚拟 DOM)。
(3)ReactDOM.render 将生成好的虚拟 DOM 渲染到指定容器上,其中采用了批处
理、事务等机制并且对特定浏览器进行了性能优化,最终转换为真实 DOM。
虚拟 DOM 的组成——ReactElementelement 对象结构:
(1)type:元素的类型,可以是原生 html 类型(字符串),或者自定义组件(函
数或 class)
(2)key:组件的唯一标识,用于 Diff 算法,下面会详细介绍
(3)ref:用于访问原生 dom 节点
(4)props:传入组件的 props,chidren 是 props 中的一个属性,它存储了当前
组件的孩子节点,可以是数组(多个孩子节点)或对象(只有一个孩子节点)
(5)owner:当前正在构建的 Component 所属的 Component
(6)self:(非生产环境)指定当前位于哪个组件实例
(7)_source:(非生产环境)指定调试代码来自的文件(fileName)和代码行数
(lineNumber)
*/

★★★★ 新出来两个钩子函数?和砍掉的 will 系列 有啥区别?

// react16 中废弃了三个钩子
componentWillMount // 组件将要挂载的钩子
componentWillReceiveProps // 组件将要接收一个新的参数时的钩子
componentWillUpdate // 组件将要更新的钩子
// 新增了方法
getDerivedStateFromProps // 静态方法
getSnapshotBeforeUpdate
/* 在 16.8版本以后,react将 diff运算改进为 Fiber,这样的话当我们调用 setState
方法进行更新的时候,在 reconciler 层中 js 运算会按照节点为单位拆分成一个个小的工
作单元,在 render 前可能会中断或恢复,就有可能导致在 render 前这些生命周期在进行一
次更新时存在多次执行的情况,此时如果我们在里面使用 ref 操作 dom 的话,就会造成页面
频繁重绘,影响性能。
所以废弃了这几个 will 系列的勾子,增加了 getDerivedStateFromProps 这个静
态方法,这样的话我们就不能在其中使用 this.refs 以及 this 上的方法了;
getSnapshotBeforeUpdate 这个方法已经到了 commit 阶段,只会执行一次,给想读取 dom
的用户一些空间。
*/

★★★★ 当调用`setState`时,React `render` 是如何工作的?

Answer
调用 setState()

检查上下文环境生成更新时间相关参数并判定事件优先级(fiber,currenttime,
expirationtime 等…)

根据优先级相关参数判断更新模式是 sync(同步更新)或是 batched(批量处理)

加入执行更新事件的队列,生成事件队列的链表结构

根据链表顺序执行更新
setState 既是同步的,也是异步的。同步异步取决于 setState 运行时的上下文。
且 setState 只在合成事件和钩子函数中是“异步”的,在原生 DOM 事件和
setTimeout 中都是同步的
render 如何工作
 React 在 props 或 state 发生改变时,会调用 React 的 render 方法,创建一颗不
同的树
 React 需要基于这两颗不同的树之间的差别来判断如何有效的更新 UI
 diff 算法,将两颗树完全比较更新的算法从 O(n^3^),优化成 O(n);

同层节点之间相互比较,不会跨节点比较

不同类型的节点,产生不同的树结构
设置 key 来指定节点在不同的渲染下保持稳定

★★★★ 什么是 immutable?为什么要使用它?

Answer
immutable 是一种持久化数据。一旦被创建就不会被修改。修改 immutable 对 象的时候返回新的 immutable。但是原数据不会改变。
在 Rudux 中因为深拷贝对性能的消耗太大了(用到了递归,逐层拷贝每个节 点)。 但当你使用 immutable 数据的时候:只会拷贝你改变的节点,从而达 到了节省性能。 总结:immutable 的不可变性让纯函数更强大,每次都返回 新的 immutable 的特性让程序员可以对其进行链式操作,用起来更方便。
因为在 react 中,react 的生命周期中的 setState()之后的 shouldComponentUpdate()阶段默认返回 true,所以会造成本组件和子组件的 多余的 render,重新生成 virtual dom,并进行 virtual dom diff,所以解决办法
是我们在本组件或者子组件中的 shouldComponentUpdate()函数中比较,当不 需要 render 时,不 render。
当 state 中的值是对象时,我们必须使用深拷贝和深比较!如果不进行深拷贝后再 setState,会造成 this.state 和 nextState 指向同一个引 用,所以 shouldComponentUpdate()返回值一定是 false,造成 state 值改了, 而组件未渲染(这里不管 shouldComponentUpdate 中使用的是深比较还是浅 比较)。所以必须深拷贝。
如果不在 shouldComponentUpdate 中进行深比较,会造成即使 state 中的对 象值没有改变,因为是不同的对象,而在 shouldComponentUpdate 返回 true, 造成不必要的渲染。
所以只能是深拷贝和深比较。

★★★★ React 复用组件的状态和增强功能的方法

Answer

 ①render props 模式

 创建 Mouse 组件,在组件中提供复用的状态逻辑代码

 将要复用的状态作为 props.render(state) 方法的参数,暴露到组件外部

 使用 props.render() 的返回值作为要渲染的内容

// 子组件
class Mouse extends React.Component{
// mouse 本组件的数据
state={
x:0,
y:0
}
// mouse 本组件的方法
handleMouse=(e)=>{
this.setState({
x:e.clientX,
y:e.clientY
})
}
componentDidMount(){
window.addEventListener('mousemove',this.handleMouse)
};
render(){
// 在这里用 props 接收从父传过来的 render 函数,再把 state 数据作为实参传
递出去
// 其实渲染的就是从父传过来的 UI 结构,只是公用了 Mouse 组件的数据和方法
return this.props.render(this.state)
}
}
// 父组件
class App extends React.Component{
render(){
return(<div>
<h1>app 组件:{this.props.name}</h1>
{/* 在使用 mouse 组件时,给 mouse 传递一个值(父传子),
只不过这里的 props 是函数,这个函数将要用形参接受从 mouse 组件传递过来
的实参(state 数据) */}
<Mouse render={(mouse)=>{
return (<div>
<h5>我用的是 Mouse 的 state 和方法:X 坐标{mouse.x}-Y 坐标
{mouse.y}</h5>
</div>)
}} />
</div>)
}
}

 ②高阶组件 HOC

const EnhancedComponent = withHOC(WrappedComponent)
// 高阶组件内部创建的类组件:
class Mouse extends React.Component {
render() {
return <WrappedComponent {...this.state} />
}
}

 ③hooks:自定义 hook

// 自定义 hook
function useFriendStatus(friendID) {
const [isOnline, setIsOnline] = useState(null);
// ...
return isOnline;
}
// 使用
function FriendStatus(props) {
const isOnline = useFriendStatus(props.friend.id);
if (isOnline === null) {
return 'Loading...';
}
return isOnline ? 'Online' : 'Offline';
}

4、webpack 的构建流程是什么?从读取配置到输出文件这个过 程尽量说全

Webpack 的运行流程是一个串行的过程,从启动到结束会依次执行以下流程:

1. 初始化参数:从配置文件和 Shell 语句中读取与合并参数,得出最终的参 数;

2. 开始编译:用上一步得到的参数初始化 Compiler 对象,加载所有配置的 插件,执行对象的 run 方法开始执行编译;

3. 确定入口:根据配置中的 entry 找出所有的入口文件;

4. 编译模块:从入口文件出发,调用所有配置的 Loader 对模块进行翻译, 再找出该模块依赖的模块,再递归本步骤直到所有入口依赖的文件都经过 了本步骤的处理;

5. 完成模块编译:在经过第 4 步使用 Loader 翻译完所有模块后,得到了每 个模块被翻译后的最终内容以及它们之间的依赖关系;6. 输出资源:根据入口和模块之间的依赖关系,组装成一个个包含多个模块 的 Chunk,再把每个 Chunk 转换成一个单独的文件加入到输出列表, 这步是可以修改输出内容的最后机会;

7. 输出完成:在确定好输出内容后,根据配置确定输出的路径和文件名,把 文件内容写入到文件系统。

在以上过程中,Webpack 会在特定的时间点广播出特定的事件,插件在监听到 感兴趣的事件后会执行特定的逻辑,并且插件可以调用 Webpack 提供的 API 改变 Webpack 的运行结果。

5、如何利用 webpack 来优化前端性能?(提高性能和体验)

用 webpack 优化前端性能是指优化 webpack 的输出结果,让打包的最终结果在 浏览器运行快速高效。

 压缩代码。删除多余的代码、注释、简化代码的写法等等方式。可以利用 webpack 的 UglifyJsPlugin 和 ParallelUglifyPlugin 来压缩 JS 文件, 利用 cssnano(css-loader?minimize)来压缩 css

 利用 CDN 加速。在构建过程中,将引用的静态资源路径修改为 CDN 上 对应的路径。可以利用 webpack 对于 output 参数和各 loader 的 publicPath 参数来修改资源路径

 删除死代码(Tree Shaking)。将代码中永远不会走到的片段删除掉。可以通过在启动 webpack 时追加参数--optimize-minimize 来实现

 提取公共代码。

6、npm 打包时需要注意哪些?如何利用 webpack 来更好的构建?

Npm 是目前最大的 JavaScript 模块仓库,里面有来自全世界开发者上传的可复 用模块。你可能只是 JS 模块的使用者,但是有些情况你也会去选择上传自己开 发的模块。 关于 NPM 模块上传的方法可以去官网上进行学习,这里只讲解如 何利用 webpack 来构建。

NPM 模块需要注意以下问题:

1. 要支持 CommonJS 模块化规范,所以要求打包后的最后结果也遵守该规 则。

2. Npm 模块使用者的环境是不确定的,很有可能并不支持 ES6,所以打包的最后结果应该是采用 ES5 编写的。并且如果 ES5 是经过转换的,请最好连同 SourceMap 一同上传。

3. Npm 包大小应该是尽量小(有些仓库会限制包大小)

4. 发布的模块不能将依赖的模块也一同打包,应该让用户选择性的去自行安装。这样可以避免模块应用者再次打包时出现底层模块被重复打包的情况。

5. UI 组件类的模块应该将依赖的其它资源文件,例如.css 文件也需要包含在发布的模块里。

基于以上需要注意的问题,我们可以对于 webpack 配置做以下扩展和优化:

1. CommonJS 模块化规范的解决方案: 设置 output.libraryTarget='commonjs2'使输出的代码符合 CommonJS2 模块 化规范,以供给其它模块导入使用

2. 输出 ES5 代码的解决方案:使用 babel-loader 把 ES6 代码转换成 ES5 的 代码。再通过开启 devtool: 'source-map'输出 SourceMap 以发布调试。

3. Npm 包大小尽量小的解决方案:Babel 在把 ES6 代码转换成 ES5 代码 时会注入一些辅助函数,最终导致每个输出的文件中都包含这段辅助函数的代码,造成了代码的冗余。解决方法是修改.babelrc 文件,为其加入

transform-runtime 插件

4. 不能将依赖模块打包到 NPM 模块中的解决方案:使用 externals 配置项 来告诉 webpack 哪些模块不需要打包

写在最后

面试题整理了很多所以展示部分,觉得有帮助就用,尽管前端环境确实一直在淘汰人,但是我们也要报团取暖,加油,对面试题感兴趣可【点击此处】最后希望各位能找到满意的工作

 

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

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

相关文章

L2-024. 部落-PAT团体程序设计天梯赛GPLT(tarjan缩点)

题解&#xff1a; 可能有人在多个圈子&#xff0c;那么这几个圈子合并为一个部落&#xff0c;一个做法就是将圈子转化为有向图&#xff0c;最后求出的缩点就是部落个数。再查询是否在一个缩点当中。 #include<bits/stdc.h> #pragma GCC optimize("Ofast") #d…

BackTrader 中文文档(十二)

原文&#xff1a;www.backtrader.com/ Visual Chart 原文&#xff1a;www.backtrader.com/docu/live/vc/vc/ 与 Visual Chart 的集成支持两者&#xff1a; 实时数据提供 实时交易 Visual Chart是完整的交易解决方案&#xff1a; 在单个平台上集成图表、数据源和经纪功能 更多…

【在线OJ系统】自定义注解实现自增ID的无感插入

实现思路 首先自定义参数注解&#xff0c;然后根据AOP思想&#xff0c;找到该注解作用的切点&#xff0c;也就是mapper层对于mapper层的接口在执行前都会执行该aop操作&#xff1a;获取到对于的方法对象&#xff0c;根据方法对象获取参数列表&#xff0c;根据参数列表判断某个…

时序分解 | Matlab实现WOA-VMD鲸鱼算法WOA优化VMD变分模态分解

时序分解 | Matlab实现WOA-VMD鲸鱼算法WOA优化VMD变分模态分解 目录 时序分解 | Matlab实现WOA-VMD鲸鱼算法WOA优化VMD变分模态分解效果一览基本介绍程序设计参考资料 效果一览 基本介绍 Matlab实现WOA-VMD鲸鱼算法WOA优化VMD变分模态分解&#xff08;完整源码和数据) 1.利用鲸…

Semaphore信号量源码解读与使用

&#x1f3f7;️个人主页&#xff1a;牵着猫散步的鼠鼠 &#x1f3f7;️系列专栏&#xff1a;Java全栈-专栏 &#x1f3f7;️个人学习笔记&#xff0c;若有缺误&#xff0c;欢迎评论区指正 目录 1. 前言 2. 什么是Semaphore&#xff1f; 3. Semaphore源码解读 3.1 acquire…

Linux系统的引导过程与服务控制

目录 一、Linux操作系统引导过程 二、Linux系统服务控制 系统初始化进程 三、运行级别切换 *运行级别及切换 Linux系统的运行级别 四、优化开机自动加载服务 五、修复MBR扇区故障 一、Linux操作系统引导过程 主要步骤 开机自检&#xff1a; 检测硬件设备&#…

C++从入门到精通——const与取地址重载

const与取地址重载 前言一、const正常用法const成员函数问题const对象可以调用非const成员函数吗非const对象可以调用const成员函数吗const成员函数内可以调用其它的非const成员函数吗非const成员函数内可以调用其它的const成员函数吗总结 二、取地址及const取地址操作符重载概…

小米汽车SU7隐藏款曝光!新配色和透明车身亮了 coreldraw教程入门零基础 coreldraw下载 coreldraw2024

刘强东说&#xff0c;论营销&#xff0c;没有任何人能比得过小米。 小米SU7发布会24小时&#xff0c;下定量就超过了蔚来汽车2023年四季度的交付量。 ▲雷军发布的小米SU7 24小时订单量 小米SU7发布会后五天&#xff0c;雷军在北京亦庄工厂亲自交付了第一批创世版本小米SU7&a…

黑马点评(四) -- 分布式锁

1 . 分布式锁基本原理和实现方式对比 分布式锁&#xff1a;满足分布式系统或集群模式下多进程可见并且互斥的锁。 分布式锁的核心思想就是让大家都使用同一把锁&#xff0c;只要大家使用的是同一把锁&#xff0c;那么我们就能锁住线程&#xff0c;不让线程进行&#xff0c;让…

gpt4.0人工智能网页版

在最新的AI基准测试中&#xff0c;OpenAI几天前刚刚发布的GPT-4-Turbo-2024-04-09版本&#xff0c;大幅超越了Claude3 Opus&#xff0c;重新夺回了全球第一的AI王座。 GPT-4-Turbo-2024-04-09版本是目前国内外最强的大模型&#xff0c;官网需要20美元每月才能使用&#xff0c;…

【UE5.1】使用MySQL and MariaDB Integration插件——(3)表格形式显示数据

在上一篇&#xff08;【UE5.1】使用MySQL and MariaDB Integration插件——&#xff08;2&#xff09;查询&#xff09;基础上继续实现以表格形式显示查询到的数据的功能 效果 步骤 1. 在“WBP_Query”中将多行文本框替换未网格面板控件&#xff0c;该控件可以用表格形式布局…

Pytest测试用例中的mark用法(包含代码示例与使用场景详解)

在软件开发中&#xff0c;测试是确保代码质量和功能稳定性的重要环节。Python作为一门流行的编程语言&#xff0c;拥有丰富的测试工具和框架&#xff0c;其中pytest是其中之一。pytest提供了丰富的功能来简化测试用例的编写&#xff0c;其中的mark功能允许我们对测试用例进行标…

理解思维链Chain of Thought(CoT)

Chain of Thought&#xff08;CoT&#xff09;&#xff0c;即“思维链”&#xff0c;是人工智能领域中的一个概念&#xff0c;特别是在自然语言处理和推理任务中。它指的是一种推理过程&#xff0c;其中模型在生成最终答案之前&#xff0c;先逐步推导出一系列的中间步骤或子目标…

【日常记录】【CSS】SASS循环的使用

文章目录 1、引言2、安装3、举例4、参考链接 1、引言 目前在任何项目框架中&#xff0c;都会有css 预处理器&#xff0c;目前一般使用 sass、less 这俩其中之一&#xff0c;它可以简化css的书写 Sass 是一款强化 CSS 的辅助工具&#xff0c;它在 CSS 语法的基础上增加了变量 (v…

推动企业档案数字化转型的措施

推动企业档案数字化转型的措施有以下几点&#xff1a; 1. 制定数字化转型战略&#xff1a;企业应该制定明确的数字化转型战略&#xff0c;明确企业数字化转型的目标、步骤和时间表&#xff0c;并将档案数字化转型作为其中的重要内容。 2. 投资数字化技术&#xff1a;企业应该投…

代码随想录:二叉树5(层序遍历全解)

目录 102.二叉树的层序遍历 107.二叉树的层序遍历II 199.二叉树的右视图 637.二叉树的层平均值 429.N叉树的层序遍历 501.在每个树行中找最大值 116.填充每个节点的下一个右侧节点指针 117.填充每个节点的下一个右侧节点指针II 104.二叉树的最大深度 111.二叉树的最大…

UE5 HLSL 详细学习笔记

这里的POSITION是变量Position的语义&#xff0c;告诉寄存器&#xff0c;此变量的保存位置&#xff0c;通常语义用于着色器的输入和输出&#xff0c;以冒号“&#xff1a;”的方式进一步说明此变量&#xff0c;COLOR也类似 还有什么语义呢&#xff1f; HLSL核心函数&#xff1a…

CAN的底层驱动

框架图 拆解链路模型 CAN子系统 can_controller Core 包含协议控制器和接收/发送移位寄存器。它可处理所有 ISO 11898-1: 2015 协议功能,并支持 11 位和 29 位标识符。

【数据结构】树与森林(树的存储结构、森林与二叉树的转化、树与森林的遍历)

目录 树和森林树的存储结构一、树的双亲表示法&#xff1a;二、树的孩子表示法方法一&#xff1a;定长结点的多重链表方法二&#xff1a;不定长结点的多重链表方法三&#xff1a;孩子单链表表示法 三、树的二叉链表(孩子-兄弟)存储表示法 森林与二叉树的转换树和森林的遍历先根…

Java中的容器

Java中的容器主要包括以下几类&#xff1a; Collection接口及其子接口/实现类&#xff1a; List 接口及其实现类&#xff1a; ArrayList&#xff1a;基于动态数组实现的列表&#xff0c;支持随机访问&#xff0c;插入和删除元素可能导致大量元素移动。LinkedList&#xff1a;基…
最新文章