面试题大纲(未完待续......)-程序员宅基地

技术标签: 面试  面试题总结大全  

面试题大全

提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加


文章目录


React相关面试题

1、说说你对react的理解?有哪些特性?

React,用于构建用户界面的 JavaScript 库,提供了 UI 层面的解决方案
遵循组件设计模式、声明式编程范式和函数式编程概念,以使前端应用程序更高效
使用虚拟DOM来有效地操作DOM,遵循从高阶组件到低阶组件的单向数据流
帮助我们将界面成了各个独立的小块,每一个块就是组件,这些组件之间可以组合、嵌套,构成整体页面
react 类组件使用一个名为 render() 的方法或者函数组件return,接收输入的数据并返回需要展示的内容

特性
JSX语法、单向数据绑定、虚拟DOM、声明式编程、Component

2、说说Real diff算法是怎么运作的

主要分为3层:tree层、component层、element层

Tree层:tree层对DOM节点的跨层级移动的操作忽略不计,只对相同层级的DOM节点进行比较(即同一个父节点下的所有子节点),一旦发现节点不存在,直接删除掉该节点以及之下的所有子节点
Component层: 遇到同一类型的组件遵循 tree diff,进行层级对比
遇到不同类型的组件,直接将这个不同的组件判断为脏组件,并替换该组件和之下所有的子节点
在同一类型的两个组件中,当知道这个组件的虚拟dom没有任何变化,就可以手动使用shouldComponentUpdate()来判断组件是否需要进行diff,进一步的提升了diff效率和性能
Element层:对同一层级的元素节点进行比较,有三种情况:

  • 面对全新的节点时,执行插入操作
  • 面对多余的节点时,执行删除操作
  • 面对换位的节点时,执行移动操作

3、说说React生命周期有哪些不同的阶段?每个阶段对应的方法是?

挂载阶段:
constructor() 在 React 组件挂载之前,会调用它的构造函数。
componentWillMount: 在调用 render 方法之前调用,并且在初始挂载及后续更新时都会被调用。
componentDidMount(): 在组件挂载后(插入DOM 树中)立即调用

更新运行阶段:
componentWillReceiveProps: 在接受父组件改变后的props需要重新渲染组件时用到的比较多,外部组件传递频繁的时候会导致效率比较低
shouldComponentUpdate():用于控制组件重新渲染的生命周期,state发生变化,组件会进入重新渲染的流程,在这里return false可以阻止组件的更新
render(): render() 方法是 class 组件中唯一必须实现的方法。
componentWillUpdate():shouldComponentUpdate返回true以后,组件进入重新渲染完成之前进入这个函数。
componentDidUpdate(): 每次state改变并重新渲染页面后都会进入这个生命周期

卸载或销毁阶段
componentWillUnmount (): 在此处完成组件的卸载和数据的销毁

4、说说你对React中虚拟dom的理解?

虚拟DOM是一棵以JavaScript对象作为基础的树,每一个节点可以将其称为VNode,用对象属性来描述节点,实际上它是一层对真实DOM的抽象,最终可以通过渲染操作使这棵树映射到真实环境上,简单来说Virtual DOM就是一个Js对象,是更加轻量级的对DOM的描述,用以表示整个文档。

Virtual DOM是一种编程概念,在这个概念里,UI以一种理想化的,或者说虚拟的表现形式被保存于内存中,并通过如ReactDOM等类库使之与真实的DOM同步,这一过程叫做协调。这种方式赋予了React声明式的API,您告诉React希望让UI是什么状态,React就确保DOM匹配该状态,这样可以从属性操作、事件处理和手动DOM更新这些在构建应用程序时必要的操作中解放出来。
与其将Virtual DOM视为一种技术,不如说它是一种模式,人们提到它时经常是要表达不同的东西。在React的世界里,术语Virtual
DOM通常与React元素关联在一起,因为它们都是代表了用户界面的对象,而React也使用一个名为fibers的内部对象来存放组件树的附加信息,上述二者也被认为是React中Virtual
DOM 实现的一部分。

5、说说你对react hook的理解?

React Hook是React 16.8版本引入的新特性,它可以让我们在函数组件中使用state和其他React特性,而不需要使用类组件。
使用Hook可以使代码更简洁、易于理解和维护。
常用的Hook包括useState、useEffect、useContext等,它们可以帮助我们处理组件状态、副作用和全局数据等问题。

6、React组件之间如何通信?

react组件之间可以通过props、context、事件总线等方式进行通信

Props:父组件可以通过props向子组件传递数据和方法,子组件可以通过props接收并使用这些数据和方法。

Context:Context可以让我们在组件树中传递数据,而不需要手动地一层层地传递props。使用Context需要创建一个Context对象,然后通过Provider组件向下传递数据,子组件可以通过Consumer组件或useContext Hook来获取数据。

事件总线:事件总线是一种发布-订阅模式,可以让不同组件之间进行通信。我们可以使用第三方库如EventEmitter3或自己实现一个事件总线。

7、说说你对受控组件和非受控组件的理解?应用场景?

受控组件
由React控制的输入表单元素而改变其值的方式。
比如,给表单元素input绑定一个onChange事件,当input状态发生变化时就会触发onChange事件,从而更新组件的state。

非受控组件
表单数据由DOM本身处理。即不受setState()的控制,与传统的HTML表单输入相似,input输入值即显示最新值。
在非受控组件中,可以使用一个ref来从DOM获得表单值。

8、说说Connect组件的原理是什么?

Connect组件是一个高阶组件,它可以将Redux store中的state和action creator作为props传递给被包裹的组件。Connect组件通过订阅Redux store的变化,来更新被包裹组件的props,从而实现组件与Redux store的连接。Connect组件的原理是使用了React的Context和高阶组件的特性,通过Provider和Consumer组件将Redux store传递给被包裹组件,并使用Redux的subscribe方法订阅store的变化,从而更新被包裹组件的props。

9.说说react 中jsx语法糖的本质?

JSX语法糖是一种JavaScript语法扩展,
它可以让我们在JavaScript代码中编写类似HTML的标记,从而更方便地描述UI组件的结构和样式。
JSX语法糖本质上是一种语法糖,它会被转换为React.createElement函数调用,从而创建React元素。
JSX语法糖的优点是可以提高代码的可读性和可维护性,缺点是需要学习一些新的语法和规则。

10.说说你对redux中间件的理解?常用的中间件有哪些?实现原理?

redux中间件是一种机制,它可以在Redux action被发起之后,到达reducer之前,对action进行拦截、处理和转换。中间件可以用于处理异步操作、日志记录、错误处理、路由跳转等场景

常用的中间件包括thunk、saga、logger等
thunk中间件可以让我们在action creator中返回一个函数,从而处理异步操作;
saga中间件可以让我们使用Generator函数来处理异步操作和复杂的业务逻辑;
logger中间件可以让我们记录Redux action的日志,从而方便调试和排查问题。

中间件的实现原理是基于Redux的applyMiddleware函数和函数式编程的思想。applyMiddleware函数接收一个或多个中间件作为参数,返回一个enhancer函数,该函数接收createStore函数作为参数,返回一个增强版的createStore函数。增强版的createStore函数可以在dispatch action之前,对action进行拦截、处理和转换,然后再将处理后的action传递给下一个中间件或reducer。中间件的处理过程是通过函数柯里化和compose函数来实现的,这样可以让多个中间件按照顺序依次执行,并且让每个中间件只需要关注自己的逻辑,从而提高代码的可读性和可维护性。

11.说说AMD、CMD、commonJS模块化规范的区别?

AMD、CMD、commonJS都是JavaScript模块化规范,它们的主要区别在于模块定义和加载方式的不同。

AMD(Asynchronous Module Definition)规范是由RequireJS提出的,它采用异步方式加载模块,可以在页面加载时并行加载多个模块,从而提高页面加载速度。AMD规范的模块定义方式是通过define函数来定义,可以指定模块的依赖关系和导出内容。

CMD(Common Module Definition)规范是由SeaJS提出 的,它采用同步方式加载模块,可以在需要时按需加载模块,从而提高页面响应速度。CMD规范的模块定义方式是通过define函数来定义,可以指定模块的依赖关系和导出内容。

CommonJS规范是由Node.js提出的,它采用同步方式加载模块,可以在服务器端使用。CommonJS规范的模块定义方式是通过module.exports和require函数来定义和加载模块,可以实现模块的复用和封装。

总的来说,AMD和CMD适用于浏览器端的模块化开发,CommonJS适用于服务器端的模块化开发。AMD和CMD的主要区别在于模块的加载方式,AMD采用异步方式加载模块,CMD采用同步方式加载模块。而CommonJS的模块定义和加载方式与AMD和CMD有所不同,它采用module.exports和require函数来定义和加载模块。

12.说说package.json中版本号的规则?

版本的格式 major、minor、patch 主版本号、次版本号、修补版本号
patch:修复bug,兼容老版本
minor:新增功能,兼容老版本
major:新的架构调整,不兼容老版本

  • 依赖版本号规则
    这三个依赖分别使用了三个符号来表明依赖的版本范围。语义化版本范围规定:
    *:升级到最新版本
    ^:升级次版本号和修订号
    ~:只升级修订号
    举个例子:
    1. 必须匹配某个版本
      如:1.1.2,表示必须依赖1.1.2版

    2. >version
      必须大于某个版本
      如:>1.1.2,表示必须大于1.1.2版

    3. >=version
      可大于或等于某个版本
      如:>=1.1.2,表示可以等于1.1.2,也可以大于1.1.2版本

    4. <version
      必须小于某个版本
      如:<1.1.2,表示必须小于1.1.2版本

    5. <=version
      可以小于或等于某个版本
      如:<=1.1.2,表示可以等于1.1.2,也可以小于1.1.2版本

    6. ~version
      大概匹配某个版本

      如果minor版本号指定了,那么minor版本号不变,而patch版本号任意

      如果minor和patch版本号未指定,那么minor和patch版本号任意

      如:~1.1.2,表示>=1.1.2<1.2.0,可以是1.1.2,1.1.3,1.1.4,…,1.1.n

      如:~1.1,表示>=1.1.0 <1.2.0,可以是同上

      如:~1,表示>=1.0.0<2.0.0,可以是1.0.0,1.0.1,1.0.2,…,1.0.n,1.1.n,1.2.n,…,1.n.n

    7. ^version
      兼容某个版本
      版本号中最左边的非0数字的右侧可以任意
      如果缺少某个版本号,则这个版本号的位置可以任意
      如:^1.1.2 ,表示>=1.1.2
      <2.0.0,可以是1.1.2,1.1.3,…,1.1.n,1.2.n,…,1.n.n
      如:^0.2.3 ,表示>=0.2.3 <0.3.0,可以是0.2.3,0.2.4,…,0.2.n
      如:^0.0,表示 >=0.0.0 <0.1.0,可以是0.0.0,0.0.1,…,0.0.n

    8. x-range
      x的位置表示任意版本
      如:1.2.x,表示可以1.2.0,1.2.1,…,1.2.n

    9. *-range
      任意版本,""也表示任意版本
      如:*,表示>=0.0.0的任意版本

    10. version1 - version2
      大于等于version1,小于等于version2
      如:1.1.2 - 1.3.1,表示包括1.1.2和1.3.1以及他们件的任意版本

    11. range1 || range2
      满足range1或者满足range2,可以多个范围
      如:=2.3.1 =2.5.2 ️.0.0,表示满足这3个范围的版本都可以

13.说说React jsx转换成真实DOM的过程?

14.说说你对@reduxjs/toolkit的理解?和react-redux有什么区别?

reduxjs/toolkit: Redux 官方强烈推荐,开箱即用的一个高效的 Redux 开发工具集。它旨在成为标准的 Redux逻辑开发模式,使用 Redux Toolkit 都可以优化你的代码,使其更可维护

react-redux:react官方推出的redux绑定库,react-redux将所有组件分为两大类:UI组件和容器组件,其中所有容器组件包裹着UI组件,构成父子关系。容器组件负责和redux交互,里面使用redux API函数,UI组件负责页面渲染,不使用任何redux API。容器组件会给UI组件传递redux中保存对的状态和操作状态的方法

15.React render方法的原理,在什么时候会触发?

React的render方法是用于将React元素渲染为真实DOM节点的方法。当组件的props或state发生变化时,React会调用render方法重新渲染组件,并将新的React元素与旧的React元素进行比较,从而更新真实DOM节点。如果新旧两个React元素相同,那么React不会重新渲染组件,从而提高性能

render方法的触发时机包括:
组件挂载时:当组件第一次被渲染到页面上时,React会调用render方法生成React元素,并将其转换为真实DOM节点。

组件更新时:当组件的props或state发生变化时,React会调用render方法重新渲染组件,并将新的React元素与旧的React元素进行比较,从而更新真实DOM节点。

强制更新时:当组件调用forceUpdate方法时,React会忽略shouldComponentUpdate方法的返回值,强制调用render方法重新渲染组件。

总的来说,React的render方法是用于将React元素渲染为真实DOM节点的方法,它会在组件挂载、更新和强制更新时被调用。通过比较新旧两个React元素的差异,React可以高效地更新页面,从而提高性能。

16.React性能优化的手段有哪些?

1.避免使用内联函数。每次render渲染时,都会创建一个新的函数实例,应该在组件内部创建一个函数,讲事件绑定到函数,这样每次调用render时,就不会创建单独的函数实例。
2.使用react fragement 避免额外标记。用户创建新组件时,每个组件应具有单个父标签,父级不能有两个标签。所以顶部要有一个公共标签,所以经常在组件顶部添加额外标签div,这个div标签充当父标签意外,没有其他作用,这个时候可以使用fragement,它不会向组件引入任何的额外标记,但是可以作为父级标签。
3.使用immutable。在react中使用immutablr能够带来性能优化,主要体现在减少渲染的次数,为了避免重复渲染,会在shouldComponentUpdate()中做对比,当返回true,执行render方法。immutable通过is方法完成对比。
4.懒加载组件。从工程方面考虑,webpack存在代码拆分的能力,可以为应用创建多个包,并在运行时动态加载,减少初始包的大小, 在react中使用Suspense,lazy组件
5.事件绑定方式,从性能考虑,在render方法中使用bind和箭头函数,都会生成新的方法实例,在constructer中欧给使用bind和箭头函数,性能提高
6.服务端渲染,可以使用户更快的看到显然成功的页面,服务端渲染可以起一个node服务,可以使用express。koa等,调用react的renderToString方法,将跟组件渲染成字符串,再输出到相应中
7.组件拆分,合理使用hooks

17. 如何通过原生js实现一个节流函数和防抖函数,写出核心代码,不是简单的思路?

节流(throttle)和防抖(debounce)是两种常用的浏览器事件处理方法。

相同点:

都是为了减少事件触发频率,优化性能。
不同点:

节流是指在一段时间内最多触发一次事件,节流算法会在特定的时间间隔内判断是否触发事件;
防抖是指在一段时间内只要有事件触发,就重新计算时间,直到这段时间内没有事件触发,才真正的执行事件;
节流适用于持续的触发,防抖适用于短时间内的大量触发。

节流核心代码

function fn(a){
    
		canRun = true
		return function(){
    
			If(!canRun){
    
				return
			}
			canRun = false
			setTimeout(()=>{
    
				a.apply(this)
				canRun = true
			},1000)
		}	
	}

防抖核心代码

function fn(a){
    
	canRun = null
	return function(){
    
		clearTimeout(canRun)
		canRun = setTimeout(()=>{
    
			a.apply(this,arguments)
		},1000)	
	}
}

18.说说你对koa中洋葱模型的理解

Koa的洋葱模型是以next()函数为分割点,先由外到内执行Request的逻辑,然后再由内到外执行Response的逻辑,这里的request的逻辑,我们可以理解为是next之前的内容,response的逻辑是next函数之后的内容,也可以说每一个中间件都有两次处理时机洋葱模型的核心原理主要是借助compose方法

19.说说如何借助webpack来优化前端性能

Webpack是一个模块打包工具,它可以将多个模块打包成一个或多个文件,从而减少页面的请求次数和文件大小,提高页面的加载速度和性能。

Webpack可以通过以下几种方式来优化前端性能
代码分割:Webpack可以将代码分割成多个小块,从而实现按需加载和并行加载,减少页面的加载时间和文件大小。

Tree Shaking:Webpack可以通过静态分析的方式,删除未使用的代码,从而减少文件大小和加载时间。

按需加载:Webpack可以根据需要动态加载模块,从而减少页面的加载时间和文件大小。

缓存优化:Webpack可以通过文件名哈希和chunk哈希等方式,实现文件的缓存和更新,从而减少页面的请求次数和文件大小。

压缩优化:Webpack可以通过UglifyJS等工具,对代码进行压缩和混淆,从而减少文件大小和加载时间。

图片优化:Webpack可以通过url-loader和image-webpack-loader等插件,对图片进行压缩和优化,从而减少文件大小和加载时间。

代码分析:Webpack可以通过webpack-bundle-analyzer等工具,对打包后的文件进行分析和优化,从而提高打包效率和性能。

总的来说,Webpack是一个强大的模块打包工具,它可以通过代码分割、Tree
Shaking、按需加载、缓存优化、压缩优化、图片优化和代码分析等方式,优化前端性能,提高页面的加载速度和性能。

20. 说说React中setState执行机制?

  • 一个组件的显示形态可以由数据状态和外部参数所决定,而数据状态就是state, 当需要修改里面的值的状态需要通过调用setState来改变,从而达到更新组件内部数据的作用
  • setState第一个参数可以是一个对象,或者是一个函数,而第二个参数是一个回调函数,用于可以实时的获取到更新之后的数据
  • 在使用setState更新数据的时候,setState的更新类型分成:同步更新,异步更新
  • 在组件生命周期或React合成事件中,setState是异步
  • 在setTimeout或者原生dom事件中,setState是同步
  • 对同一个值进行多次 setState, setState 的批量更新策略会对其进行覆盖,取最后一次的执行结果

21.说说react的事件机制

React 的事件机制其实使用了 事件委托 的方式,React 在内部自己实现了浏览器中对应事件的合成事件,web 浏览器中,浏览器在生成虚拟 dom 树的时候,解析出的合成事件挂载到 document 上 (native 中不是很了解),部分事件仍然在 dom 元素上,事件的实现是插件的机制,方便后续拓展事件

22.说说你对fiber架构的理解?解决了什么问题?

  • 理解?
    在 react16 没有正式公布之前,业界的人员觉得此次的 react16 就叫作 Fiber,足以说明 Fiber 的重要性。fiber 在英文中意为纤维,此处意为比线程还细的单位。Facebook 取名 Fiber 的意思是为了描述一个比线程更小单位的渲染机制 用一句话来描述我所理解的 Fiber 架构:
    新的 Fiber 架构改变了以前 react 同步的组件渲染机制,使原来同步渲染的组件如今能够异步化,可中途中断渲染,执行更高优先级的任务,用户体验更好。

  • 解决什么样的问题?
    Fiber 的引入主要是为了解决在网页里面用户和网页应用进行交互的问题:github 在 react16
    以前的版本中,组建的渲染是同步的动做,若是组件包含不少层子组件,渲染时间比较长,在组件渲染的过程当中又没法被打断,会致使这期间用户没法与网页进行交互。
    全部的任务都是按照前后顺序,没有优先级可言,这样就会致使优先级比较高的任务没法优先被执行。

23.什么是强缓存和协商缓存

1. 浏览器缓存(Brower Caching):

是浏览器对之前请求过的文件进行缓存,以便下一次访问时重复使用,节省带宽,提高访问速度,降低服务器压力 HTTP
1.0协议中的。简而言之,就是告诉浏览器在约定的这个时间前,可以直接从缓存中获取资源而无需跑到服务器去获取。 http缓存机制主要在http响应头中设定,响应头中相关字段为Expires、Cache-Control、Last-Modified、Etag

2.强缓存:

浏览器不会像服务器发送任何请求,直接从本地缓存中读取文件并返回Status Code: 200 OK

3.协商缓存

协商缓存: 向服务器发送请求,服务器会根据这个请求的request
header的一些参数来判断是否命中协商缓存,如果命中,则返回304状态码并带上新的response
header通知浏览器从缓存中读取资源;

24.如何使用css实现一个三角形 transparent

  • 使用 border 绘制三角形
    使用 border 实现三角形利用了高宽为零的容器及透明的 border 实现。
    给一个高宽为零的容器设置不同颜色的 border
div {
    
  width: 0px;
  height: 0px;
  margin: auto;
}
.normal {
    
  border-top: 50px solid yellowgreen;
  border-bottom: 50px solid deeppink;
  border-left: 50px solid bisque;
  border-right: 50px solid chocolate;
}

<div class='normal'></div>

让任何三边的边框的颜色为 transparent,可以得到各种角度的三角形:

.top {
    
  border: 50px solid transparent;
  border-bottom: 50px solid deeppink;
}

.left {
    
  border: 50px solid transparent;
  border-right: 50px solid deeppink;
}

.bottom {
    
  border: 50px solid transparent;
  border-top: 50px solid deeppink;
}

.right {
    
  border: 50px solid transparent;
  border-bottom: 50px solid deeppink;
}

<div class='top'></div> 
<div class='left'></div>
<div class='bottom'></div>
<div class='right'></div>

在这里插入图片描述

  • 使用 linear-gradient 绘制三角形
    我们可以使用线性渐变 linear-gradient 实现三角形。它的原理也非常简单,我们实现一个 45° 的渐变:

在这里插入图片描述
让它的颜色从渐变色变为两种固定的颜色:

div {
    
  width: 100px;
  height: 100px;
  background: linear-gradient(45deg, deeppink, deeppink 50%, yellowgreen 50%, yellowgreen 100%);
}

在这里插入图片描述

再让其中一个颜色透明即可:

div {
    
        width: 100px;
        height: 100px;
        background: linear-gradient(45deg,  rgb(255, 20, 147) 50%, rgba(154, 205, 50,0) 50%);
    }

在这里插入图片描述

  • 使用 clip-path 绘制三角形
    clip-path CSS 属性可以创建一个只有元素的部分区域可以显示的剪切区域。区域内的部分显示,区域外的隐藏。剪切区域是被引用内嵌的 URL 定义的路径或者外部 SVG 的路径。

也就是说,使用 clip-path 可以将一个容器裁剪成任何我们想要的样子。

通过 3 个坐标点,实现一个多边形,多余的空间则会被裁减掉,代码也非常简单:

div {
    
        width: 100px;
        height: 100px;
        background: deeppink;
        clip-path: polygon(0 0, 100% 0, 0 100%, 0 0);
    }

在这里插入图片描述

  • 利用字符绘制三角形
    这一种有些独特,就是使用字符表示三角形。
    下面列出一些三角形形状的字符的十进制 Unicode 表示码。

◄ : &#9664;
► : &#9654;
▼ : &#9660;
▲ : &#9650;
⊿ : &#8895;
△ : &#9651;

<div>&#9660; </div>
div {
    
    font-size: 100px;
    color: deeppink;
}

在这里插入图片描述

25.说说webpack中常见的loader?解决了什么问题?

style-loader: 将css添加到DOM的内联样式标签style里

css-loader :允许将css文件通过require的方式引入,并返回css代码

less-loader: 处理less

sass-loader: 处理sass

postcss-loader: 用postcss来处理CSS

autoprefixer-loader: 处理CSS3属性前缀,已被弃用,建议直接使用postcss

file-loader: 分发文件到output目录并返回相对路径

url-loader: 和file-loader类似,但是当文件小于设定的limit时可以返回一个Data Url

html-minify-loader: 压缩HTML

babel-loader :用babel来转换ES6文件到ES

26.Vue中自定义指令的理解,应用场景有哪些

在 Vue 中,自定义指令可以让你在模板中使用 v-directiveName 这样的语法来调用自己定义的指令。自定义指令可以用来操作DOM 元素,给元素绑定事件监听器,或者进行其他自定义操作。
要定义一个自定义指令,可以使用 Vue.directive 函数来注册一个指令。该函数接受两个参数,第一个参数是指令的名称,第二个参数是一个对象,用来定义指令的行为。

应用场景
表单防止重复提交
图片懒加载
一键Copy的功能
防抖

27.大文件如何做断点续传

点续传是一种文件传输技术,可以在文件传输过程中断开连接后自动恢复传输。对于大文件的传输,断点续传技术可以提高传输的可靠性和效率。

下面是一些实现断点续传的方法:

  • HTTP Range 请求
    HTTP Range 请求是一种用于请求部分数据的 HTTP 请求,可以用于实现断点续传。在 HTTP Range 请求中,客户端可以指定请求数据的范围,服务器只返回指定范围内的数据。通过多次发送 HTTP Range 请求,可以实现大文件的断点续传。
  • 文件分片
    文件分片是一种将大文件分成多个小文件的方法,每个小文件可以独立传输。通过将大文件分成多个小文件,可以实现断点续传和多线程传输,从而提高传输的效率和可靠性。
  • 断点续传协议 断点续传协议是一种专门用于文件传输的协议,例如 BitTorrent
    协议。在断点续传协议中,文件被分成多个小块,每个小块可以独立传输,从而实现断点续传和多线程传输。

总之,实现断点续传需要根据具体情况选择合适的方法和技术,例如 HTTP Range 请求、文件分片和断点续传协议等。在实际开发中,需要考虑文件传输的可靠性、效率和安全性等因素,从而选择合适的断点续传方案。

28.原生js如何实现上拉加载下拉刷新

下拉刷新

首先,在页面顶部添加一个下拉刷新的区域,然后监听touchstart、touchmove和touchend等事件。当用户在下拉刷新区域内进行下拉操作时,触发touchmove事件,并判断下拉的距离是否超过一定阈值。如果超过阈值,则触发下拉刷新操作,更新数据并重新渲染页面。

上拉加载

上拉加载的实现方式与下拉刷新类似,也是通过监听滚动事件,并判断滚动到底部时触发相应的操作。

29.说说设备像素、css像素、设备独立像素、dpr、ppi之间的区别

  • 设备像素(Device Pixel) 设备像素是显示器或者移动设备屏幕上最小的物理像素点,也称为物理像素(Physical Pixel)。设备像素的大小是固定的,它们的数量决定了显示器或移动设备屏幕的分辨率。例如,一个 1920x1080 的显示器就有 1920x1080 个设备像素。
  • CSS 像素(CSS Pixel) CSS像素是浏览器中用于渲染页面的基本单位,也称为逻辑像素(Logical Pixel)。CSS 像素的大小是可变的,它们的数量由 CSS 样式表中的像素大小来决定。例如,使用一个 100 像素的 CSS 尺寸,就会在屏幕上显示出 100 个 CSS 像素。
  • 设备独立像素(Device Independent Pixel)设备独立像素是一个抽象的单位,它与设备的分辨率和大小无关,用于在不同分辨率和大小的设备上显示相同大小的内容。设备独立像素的大小是固定的,通常被定义为 1/96 英寸,也称为点(Point)或密度无关像素(Device Independent Pixel)。在 iOS 设备上,设备独立像素也被称为逻辑像素(Logical Pixel)。
  • 设备像素比(Device Pixel Ratio,DPR) 设备像素比是设备像素和设备独立像素之间的比率,用于描述屏幕分辨率和屏幕大小之间的关系。例如,一个设备像素比为 2
    的屏幕,表示每个设备独立像素由 2 个设备像素组成,即每个设备独立像素的大小是 2x2 个设备像素。
  • 像素密度(Pixels PerInch,PPI) 像素密度是显示器或移动设备屏幕上每英寸显示的像素数量,也称为屏幕密度(Screen Density)。像素密度越高,屏幕显示的内容就越清晰和细腻。在移动设备上,像素密度通常使用 PPI 来描述,而在打印机上通常使用DPI(Dots Per Inch)来描述。

总之,设备像素、CSS像素、设备独立像素、设备像素比和像素密度之间存在着一定的区别和联系,了解它们之间的关系可以帮助我们更好地理解屏幕分辨率和显示效果等概念。

30.谈谈你对BFC的理解

简单的理解:BFC就是一个块级容器,它会隔离外部,让盒子里面的元素不影响外面的元素,也就是在搭建页面的时候,不影响外面的布局。

1、可以利用BFC解决两个相邻元素的上下margin重叠问题;

2、可以利用BFC解决高度塌陷问题;

3、可以利用BFC实现多栏布局(两栏、三栏、圣杯、双飞翼等)。

31.说说TCP为什么需要三次握手和四次握手

TCP需要进行三次握手来建立连接,主要是为了保证数据传输的可靠性安全性
具体原因如下:

  • 防止已失效的连接请求报文段重复发送造成服务端的错误处理。
  • 防止客户端发送的连接请求报文段在网络中长时间滞留,等待服务端响应,从而浪费网络资源。
  • 防止服务端发送的连接应答报文段在网络中长时间滞留,导致客户端无法及时确认连接状态。
  • 确认双方的接收能力和发送能力正常,确保连接的可靠性和稳定性。

TCP需要进行四次握手来关闭连接,主要是为了确保数据传输的完整性可靠性
具体原因如下:

  • 防止已失效的数据报文段在连接关闭后重复传输。 确保客户端和服务端都接收到了对方的关闭请求。
  • 确认双方的接收能力和发送能力正常,确保连接的可靠性和稳定性。 防止服务端重复发送数据,导致客户端接收到重复数据。

32.react新出来两个钩子函数是什么?和删掉的will系列有什么区别?

新生命周期中新增了两个钩子,分别为getDerivedStateFromProps(从props中得到衍生的state)和getSnapshotBeforeUpdate。

  • 区别
    1、componentWillMount中可能需要做的事(一些数据初始化的操作就应该放在这个钩子中处理),constructor与componentDidMount也能做,甚至做的更好,此方法被废弃。
    2、componentWillReceiveProps实际行为与命名并不相符,由于不稳定性已由getDerivedStateFromProps代替;
    3、而componentWillUpdate同等理由被getSnapshotBeforeUpdate代替

33.最少说出三种前端清除浮动的方法

  • 使用空元素清除浮动:在浮动元素后面添加一个空的标签,设置clear属性为both,从而清除浮动。

  • 使用overflow属性清除浮动:将浮动元素的父容器设置overflow属性为auto或hidden,从而清除浮动。

  • 使用伪元素清除浮动:在浮动元素后面添加一个伪元素,设置clear属性为both,从而清除浮动。

34.说说你对git rebase 和git merge的理解?区别?

35.在使用redux过程中,如何防止定义的action-type的常量重复?

  • ES6引入了一种新的原始数据类型Symbol,表示独一无二的值。

  • Symbol函数前不能使用new命令,否则会报错。这是因为生成的Symbol是一个原始类型的值,不是对象

  • Symbol函数可以接受一个字符串作为参数,表示对Symbol实例的描述,主要是为了在控制台显示,或者转为字符串时,比较容易区分。

36.调和阶段setState干了什么

  • 代码中调用 setState 函数之后,React 会将传入的参数对象与组件当前的状态合并,然后触发所谓的调和过程(Reconciliation)。
  • 经过调和过程,React 会以相对高效的方式根据新的状态构建 React 元素树并且着手重新渲染整个 UI 界面;
  • React 得到元素树之后,React 会自动计算出新的树与老树的节点差异,然后根据差异对界面进行最小化重渲染;
  • 在差异计算算法中,React 能够相对精确地知道哪些位置发生了改变以及应该如何改变,这就保证了按需更新,而不是全部重新渲染。

37.props和state相同点和不同点?render方法在哪些情况下会执行

相同点:

都是用于管理组件的数据和状态。
都可以触发组件的重新渲染。
都是React组件的内部状态,外部无法直接访问和修改。

不同点:

  • 数据来源不同
    props通常是由父组件传递给子组件的,
    state通常是组件内部自己维护的。
  • 可修改性不同
    props是只读的,不能在组件内部直接修改,
    state是可读写的,可以在组件内部修改。
  • 更新方式不同
    props的更新通常是由父组件触发的,
    state的更新通常是由组件自身触发的。

render方法在哪些情况下会执行?

  • 组件第一次挂载时会执行render方法。 组件的props或state发生变化时会执行render方法。
  • 父组件重新渲染时,子组件也会重新渲染,因此render方法也会执行。
  • 强制更新组件时,render方法也会执行。
  • 总之,render方法是React组件中非常重要的一个方法,它用于根据当前组件的props和state生成对应的UI。在组件的生命周期中,render方法会在多个时机被执行,以保证组件的渲染和更新。

38.React的props.children使用map函数来遍历会收到异常显示,为什么?应该如何遍历

  • 在React中,使用map函数来遍历props.children时,可能会收到异常显示。这是因为props.children不一定是数组类型,有可能是字符串、数字、布尔值、null或undefined等非数组类型,如果尝试对非数组类型使用map函数来遍历,就会出现异常。
  • 为了遍历props.children,可以使用React.Children.map函数来遍历。React.Children.map函数可以遍历props.children,并对每个子元素执行指定的回调函数

该函数的语法如下:
React.Children.map(children, function[(thisArg)])
其中,children是要遍历的子元素,function是要执行的回调函数,thisArg是可选的回调函数中的this对象。

39.谈谈你对immutable.js的理解

Immutable.js是一个非常有价值的JavaScript库,它提供了一组不可变数据结构和操作方法,可以用于管理和操作不可变的数据,避免因可变数据引起的问题,同时也可以方便地进行数据缓存、函数式编程等操作。但是,由于Immutable.js的学习曲线较陡峭,开发者在使用时需要花费一些时间去理解和掌握。

Immutable.js的主要应用场景包括:

React应用:由于React中推崇不可变数据的概念,因此Immutable.js可以作为React应用的数据管理工具,避免因可变数据引起的问题。
数据缓存:由于Immutable.js中的数据结构是不可变的,因此可以方便地进行数据缓存,避免重复计算和数据传递。
函数式编程:由于Immutable.js中的操作方法都是纯函数,因此可以方便地进行函数式编程和函数组合。

40.redux本来是同步的,为什么它能执行异步代码?实现原理是什么?中间件的实现原理是什么

  • Redux本来是同步的,但是在实际应用中,经常需要处理异步数据流,例如网络请求、定时器等,因此Redux提供了一些方便的方式来处理异步数据流,例如使用中间件、使用异步Action等。

  • 实现原理:

    • 使用中间件:Redux中间件是一个函数,它可以对Redux的dispatch方法进行增强,从而实现一些额外的功能,例如异步操作、打印日志、错误处理等。使用中间件可以方便地处理异步操作,例如使用thunk中间件来处理异步Action。
      使用异步Action:Redux中的Action本质上是一个JavaScript对象,它描述了应用中发生的事件,例如用户点击按钮、网络请求返回等。但是,Redux并没有限制Action必须是同步的,因此可以使用异步Action来处理异步数据流。异步Action可以返回一个函数,该函数可以在内部执行异步操作,然后再通过dispatch方法来触发真正的Action。
  • 中间件的实现原理:

    • 中间件是一个函数,它接收Redux Store的dispatch方法和getState方法作为参数,并返回一个函数,该函数可以接收一个next参数,表示下一个中间件或者Redux
      Store的dispatch方法。中间件的实现原理如下: 中间件函数接收dispatch和getState方法作为参数,返回一个函数。
      返回的函数接收next参数,表示下一个中间件或者Redux Store的dispatch方法。
      返回的函数内部定义一个新的dispatch方法,它可以在原始的dispatch方法前后执行一些额外的逻辑,例如打印日志、处理错误等。
      返回的函数最终返回next(action)或者dispatch(action),表示将action传递给下一个中间件或者Redux
      Store的dispatch方法。

总之,Redux提供了一些方便的方式来处理异步数据流,例如使用中间件、使用异步Action等。中间件是实现这些功能的关键,它可以对Redux的dispatch方法进行增强,从而实现一些额外的功能,例如异步操作、打印日志、错误处理等。

41.redux中同步action与异步action最大的区别是什么

  • Redux中同步Action和异步Action最大的区别是:
  • 同步Action是一个简单的JavaScript对象,用于描述应用中发生的同步事件,
  • 而异步Action是一个函数,它可以执行异步操作,例如网络请求、定时器等,并返回一个Promise对象或者另一个函数来描述异步操作的结果。
  • 具体来说,同步Action和异步Action的区别主要体现在以下几个方面:
  • 数据结构
    • 同步Action是一个简单的JavaScript对象,它包含一个type字段和一些payload数据,用于描述应用中发生的同步事件;
    • 异步Action是一个函数,它可以执行异步操作,并返回一个Promise对象或者另一个函数,用于描述异步操作的结果。
  • 执行时机
    • 同步Action是在dispatch方法调用时直接执行的,
    • 而异步Action是在dispatch方法调用后异步执行的,例如网络请求、定时器等。
  • 数据流处理
    • 同步Action直接将payload数据传递给Reducer函数,用于更新Store中的状态;
    • 异步Action需要先执行异步操作,然后在异步操作完成后再将payload数据传递给Reducer函数,用于更新Store中的状态。
  • 处理方式
    • 同步Action通常是直接在Reducer函数中处理的,
    • 而异步Action通常需要使用中间件来处理,例如使用redux-thunk中间件来处理异步Action。

总之,同步Action和异步Action在Redux中具有不同的作用和处理方式。同步Action用于描述应用中发生的同步事件,而异步Action用于执行异步操作,并在操作完成后更新应用的状态。开发者在使用Redux时,需要根据不同的场景选择使用同步Action或异步Action,以便更好地管理和控制数据流。

42.redux-saga和redux-thunk的区别与使用场景

redux-saga和redux-thunk都是Redux中常用的中间件,用于处理异步操作和副作用。

它们的区别和使用场景主要包括以下几点:

工作原理

redux-thunk是Redux官方提供的中间件,它通过在action中使用函数来处理异步操作。当dispatch一个函数类型的action时,redux-thunk会将这个函数执行,并将dispatch和getState作为参数传递给这个函数,从而实现异步操作。
redux-saga是一个基于Generator函数的中间件,它通过在saga文件中编写Generator函数来处理异步操作。saga文件包含了一系列的Generator函数,每个Generator函数可以监听一个或多个action,并在监听到相应的action时执行相应的操作。

处理异步操作的能力

redux-thunk只能处理简单的异步操作,例如发送AJAX请求等。当异步操作比较复杂时,redux-thunk的代码可能会变得非常冗长。
redux-saga具有更强大的异步操作处理能力,它可以处理复杂的异步操作,例如异步的流程控制、错误处理、取消操作等。使用redux-saga可以将异步操作的逻辑与组件的逻辑分离开来,使代码更加清晰易于维护。

使用场景

  • redux-thunk适用于处理简单的异步操作,例如发送AJAX请求、获取数据等。当异步操作比较复杂时,redux-thunk的代码可能会变得非常冗长,不易于维护。
  • redux-saga适用于处理复杂的异步操作,例如流程控制、错误处理、取消操作等。使用redux-saga可以将异步操作的逻辑与组件的逻辑分离开来,使代码更加清晰易于维护。

总的来说,redux-thunk和redux-saga都是Redux中常用的中间件,用于处理异步操作和副作用。它们的区别在于工作原理、处理异步操作的能力和使用场景。使用redux-thunk适合处理简单的异步操作,而使用redux-saga适合处理复杂的异步操作。

43.CDN的特点及意义

  • CDN的功能特点
    (1)节省骨干网带宽,减少带宽需求量;
    (2)提供服务器端加速,解决由于用户访问量大造成的服务器过载问题;
    (3)服务商能使用Web Cache技术在本地缓存用户访问过的Web页面和对象,实现相同对象的访问无须占用主干的出口带宽,并提高用户访问因特网页面的相应时间的需求;
    (4)能克服网站分布不均的问题,并且能降低网站自身建设和维护成本;
    (5)降低“通信风暴”的影响,提高网络访问的稳定性

  • 意义
    使用CDN可以获取一些好处,无论它们是公有CDN还是提供静态内容的私有CDN,你的里程可能会有所不同,具体取决于通过CDN传递的流量以及你产生的流量。

44.为什么for循环比forEach性能高

  • 作用域链
    JavaScript中,每个函数都有一个作用域链,当访问变量时,JavaScript引擎会沿着作用域链逐层查找,直到找到该变量为止。
    forEach方法中的回调函数是一个闭包,会在每次循环迭代中创建一个新的作用域,从而影响性能。

  • 函数调用
    forEach方法中的回调函数会对每个元素都执行一次,这意味着会进行多次函数调用。
    for循环中的代码只需要在循环内部执行一次,从而减少了函数调用的次数,提高了性能。

  • 长度计算
    forEach方法中,需要通过数组的length属性计算需要迭代的次数。
    而在for循环中,可以通过将数组的length属性存储在一个变量中来避免重复计算`,从而提高性能。

综上所述,for循环比forEach性能高的原因主要是因为for循环避免了闭包、函数调用和重复计算长度等问题。但是,在使用for循环时,需要注意避免出现死循环和无限循环的情况,以避免造成性能问题。

45.谈谈你是如何做移动端适配的

46.移动端1像素的解决方案

47.弹性盒中的缩放机制是怎样的

48.说说redux的实现原理是什么,写出核心代码

原理

  • 将应用的状态统一放到 state 中,由 store 来管理 state。
  • reducer 的作用是 返回一个新的 state 去更新 store 中对用的 state。
  • 按 redux 的原则,uI层每一次状态的改变都应通过 action 去触发,action 传入对应的 reducer 中,reducer 返回一个新的 state更新 store 中存放的 state ,这样就完成了一次状态的更新
  • subscribe 是为 store 订阅监听函数,这些订阅后的监听函数是在每一次 dipatch 发起后依次执行
  • 可以添加中间件对提交的 dispateh 进行重写

核心API

  • createstore 创建仓库,接受 reducer 作为参数
  • bindActionCreator 绑定 store.dispatch 和 action 的关系
  • combineReducers 合多个 reducers
  • applyMiddleware 洋葱模型的中间件,介于 dispatch 和 action 之间,重写 dispatch
  • compose 整合多个中间件

48.为什么react元素有一个$$type属性

目的是为了防止 xss 攻击。因为 ynbol 无法被序列化,所以 React 可以通过有没有 Stypeof 属性来断出当前的 element 对象是以数据库来的还是自己生成的。如果没有 $stypeof 这个属性,reat 会拒绝处理该元素

从设计上来说,React 元素是一个普通的对象。
对于优化编译器,在worker之间传递UI元素或者将JSX与React包解耦是有用的。
但是,如果服务器侧有一个允许用户存储任意JSON对象的漏洞,而客户端代码期待一个字符串,这可能会成为一个问题:React 0.13很容易受到XSS攻击。这种攻击取决于现有的服务器漏洞。 在React 0.14版本,它的修复方法是对每一个React元素使用Symbol来进行标记。 不能把Symbol放在JSON中,因此,即使服务器具有安全漏洞并返回JSON而不是文本,该JSON也不能包含Symbol.for(‘react.element’)。
React将检查元素的typeof属性,如果typeof属性丢失或无效,将拒绝处理该元素

49.说说你对事件循环event loop的理解

javascript是单线程脚本语言,代码自上而下执行,代码在执行时会被压入执行栈(stack)中,
当遇到setTimeout时会将setTimeout函数交给Web API来维护,
异步任务(比如:setTimeout)执行完成后会将对应的回调函数推入事件队列(event queue)中,
当执行栈中任务全部执行完成之后浏览器会读取任务队列,把对应的回调函数再压入执行栈中,然后循环执行
这就是所谓的EventLoop。

50.前端跨域的解决方案

51.数组常用方法及作用,至少15个

JavaScript中数组是一种非常常用的数据结构,提供了丰富的方法来操作和处理数组元素。以下是15个常用的数组方法及其作用:
push():向数组末尾添加一个或多个元素,并返回新的数组长度。 pop():从数组末尾移除并返回一个元素。
unshift():向数组开头添加一个或多个元素,并返回新的数组长度。 shift():从数组开头移除并返回一个元素。
slice():返回一个数组的一部分,不会改变原数组。 splice():向或从数组中添加或移除元素,会改变原数组。
concat():将两个或多个数组合并成一个新数组,不会改变原数组。 join():将数组中的所有元素转换为字符串,并连接在一起。
reverse():将数组中的元素顺序颠倒,会改变原数组。 sort():将数组中的元素按照指定的顺序排序,会改变原数组。
indexOf():返回数组中某个元素的索引,如果不存在则返回-1。
lastIndexOf():返回数组中某个元素最后出现的位置的索引,如果不存在则返回-1。
map():对数组中的每个元素进行操作,并返回一个新的数组。 filter():从数组中筛选出符合条件的元素,并返回一个新的数组。
reduce():将数组中的元素累加或合并成一个值,并返回该值。
需要注意的是,数组的方法有些会改变原数组,有些则会返回新的数组或其他值,使用时需要根据实际情况选择适合的方法。

52. 说说你对vue中mixin的理解

在Vue中,Mixin是一种混入模式,用于组件之间的代码复用和逻辑抽象。Mixin可以定义一些可复用的选项、组件、方法等,然后将其混入到组件中使用,以实现代码的复用和共享。
具体来说,Mixin的作用如下:
实现代码复用:Mixin可以将多个组件中的相同代码抽象成一个Mixin,然后将Mixin混入到这些组件中,以实现代码的复用和共享。
提高代码可维护性:Mixin可以将组件中的公共逻辑抽象出来,使得组件的代码更加简洁、清晰,提高了代码的可维护性。
功能扩展:Mixin可以通过添加新的选项、组件、方法等,扩展组件的功能。

53.for…in循环和for…of循环的区别

54.Js数据类型判断都有哪几种方式?至少说出5种?它们的区别是什么

55.说说你对Object.defineProperty()的理解

56.从浏览器地址栏输入url到显示页面的步骤

57.介绍一下你对浏览器内核的理解

58.如果需要手动写动画,你认为最小时间间隔是多久,为什么

59.SPA(单页应用)首屏加载速度慢怎么解决

60.bind、call、apply 区别?如何实现一个bind

61.VUE路由的原理

62.说说你对keep-alive的理解

63.什么是响应式设计?响应式设计的基本原理是什么?如何做

64.说说react router有几种模式?实现原理

65.说JavaScript中的数据类型?存储上的差别

66.说说Real DOM和Virtual DOM的区别?优缺点?

1.虚拟dom不会进行排版与重绘操作,虚拟dom是把js代码转为真实dom
2.真实dom频繁回流与重绘效率非常低
3.虚拟dom可以跨平台操作而真实dom是与浏览器绑定的

优缺点

  • 真实 DOM 的优势
    易用
  • 缺点
    效率低,解析速度慢,内存占用量过高
    性能差:频繁操作真实 DOM,易于导致重绘与回流
  • 虚拟 DOM 的优势
    简单方便:如果使用手动操作真实 DOM 来完成页面,繁琐又容易出错,在大规模应用下维护起来也很困难
    性能方面:使用 Virtual DOM,能够有效避免真实 DOM 数频繁更新,减少多次引起重绘与回流,提高性能
    跨平台:React 借助虚拟 DOM,带来了跨平台的能力,一套代码多端运行
    缺点
    在一些性能要求极高的应用中虚拟 DOM 无法进行针对性的极致优化
    首次渲染大量 DOM 时,由于多了一层虚拟 DOM 的计算,速度比正常稍慢

68.说说React中setState和replaceState的区别?

70.说说react diff的原理是什么?

71.说说javascript内存泄漏的几种情况?

  • 循环引用 :当两个或多个对象之间存在相互引用,并且没有被其他对象引用,就会发生循环引用,从而导致内存泄漏。这种情况可以通过在对象之间断开引用来避免。
function createObject() {
    
  var obj1 = {
    };
  var obj2 = {
    };
  obj1.ref = obj2;
  obj2.ref = obj1;
  return obj1;
}
var myObj = createObject();
// 这里无法回收 myObj 和 myObj.ref 所占用的内存空间,导致内存泄漏
  • 定时器未清除 :在JavaScript中使用setInterval()或setTimeout()函数时,必须确保在不需要它们时清除这些定时器。
var count = 0;
function incrementCount() {
    
  count++;
  console.log(count);
  setTimeout(incrementCount, 1000);
}
incrementCount();
// 这里没有清除计时器,导致计时器持续运行,占用内存空间,导致内存泄漏

有清除计时器,导致计时器持续运行,占用内存空间,导致内存泄漏

  • DOM元素未正确删除 :在使用JavaScript操作DOM元素时,必须确保在不需要它们时正确删除它们。
var element = document.getElementById("myElement");
element.addEventListener("click", function() {
    
  // do something
});
// 这里没有正确删除DOM元素,导致元素无法被垃圾回收器清理,从而导致内存泄漏
  • 全局变量未清除 :在JavaScript中,如果定义了全局变量,它们将一直存在于内存中,直到页面关闭。如果不需要全局变量,请确保在使用后将其删除或赋值为null。
var globalVariable = "some data";
// 这里定义了全局变量,如果不再需要使用它,请将其删除或赋值为 null
  • 闭包未正确使用 :在JavaScript中,闭包可以让函数访问其定义时的作用域,但如果未正确使用闭包,也可能导致内存泄漏。在使用闭包时,请确保只保留必要的引用,并在不需要时删除它们。
function createFunction() {
    
  var data = "some data";
  return function() {
    
    console.log(data);
  };
}
var myFunc = createFunction();
// 这里保留了函数的引用,导致闭包内的 data 变量无法被垃圾回收器清理,从而导致内存泄漏
  • 事件未正确解绑 :在JavaScript中,如果注册了事件监听器却没有正确解绑,就会导致内存泄漏。例如,当一个DOM元素被删除时,它仍然会保留对事件监听器的引用,如果没有解绑,事件监听器将无法被垃圾回收。
var element = document.getElementById("myElement");
element.addEventListener("click", handleClick);
function handleClick() {
    
  // do something
}
// 这里没有正确解绑事件监听器,导致元素无法被垃圾回收器清理,从而导致内存泄漏
  • 大量数据未及时清理 :在处理大量数据时,如果不及时清理无用的数据,就会导致内存泄漏。
var data = [];
for (var i = 0; i < 10000; i++) {
    
  data.push(i);
}
  • 使用了第三方库或框架 :在使用第三方库或框架时,需要确保它们没有内存泄漏问题。如果使用了存在内存泄漏问题的库或框架,就会导致整个应用程序出现内存泄漏问题。
// 使用第三方库或框架时,需要确保它们没有内存泄漏问题
// 例如,在 React 应用中,如果没有正确使用 componentWillUnmount(),就可能导致组件无法被垃圾回收器清理,从而导致内存泄漏
class MyComponent extends React.Component {
    
  componentDidMount() {
    
    this.interval = setInterval(() => {
    
      // do something
    }, 1000);
  }
  componentWillUnmount() {
    
    clearInterval(this.interval);
  }
  render() {
    
    return <div>My Component</div>;
  }
}

72.说说React生命周期中有哪些坑?如何避免?

73.React合成事件的原理?

74.说说你对webSocket的理解?

75.什么是垂直外边距合并?说说合并后的几种情况?

76.useEffect的依赖为引用类型如何处理?

77.知道react里面的createPortal么,说说其使用场景?

78.Provider和connect的底层原理实现,写出其核心代码?

79.你了解vue的diff算法吗?说说看?

80.如何优化webpack打包速度?

81.说说对React Hooks的理解?解决了什么问题?

82.说说你对promise的了解?

83.Vue组件之间的通信方式都有哪些?

84.说说你对栈、队列的理解?应用场景?

85.什么是闭包,应用场景是什么?

86.说说你对useEffect的理解,可以模拟哪些生命周期?

模拟componentDidMount
第二个参数为空数组,可以模拟compomentDidMount
模拟componentDidUpdate
没有第二个参数代表监听所有属性的更新
监听多个属性的变化需要将属性作为数组传入第二个参数。
模拟componentWillUnmount
通常,组件卸载时需要清除 effect 创建的诸如订阅或计时器 ID 等资源

87.说说react中onClick绑定后的工作原理?

react中的事件都是合成事件,不是把每一个dom的事件绑定在dom上,而是把事件统一绑定到document中,触发时通过事件冒泡到document进行触发合成事件,因为是合成事件,所以我们无法去使用e.stopPropagation去阻止,而是使用e.preventDefault去阻止。

88.说说webpack中代码分割如何实现?

Webpack 实现代码分割的主要方法是
使用动态导入语法(Dynamic Import Syntax)
或者
配置 optimization.splitChunks。

动态导入语法

Webpack 2 提供了 import() 函数来实现动态导入模块。这个函数会返回一个 Promise 对象,可以用于异步加载模块。在 Webpack 中,可以将动态导入语法用于实现代码分割。

例如,我们可以将应用程序中不同路由中的组件拆分为单独的代码块:

// 路由配置
const routes = {
    
  '/home': () => import('./Home'),
  '/about': () => import('./About'),
  '/contact': () => import('./Contact')
};

// 路由实现
function router() {
    
  const path = getCurrentPath();
  const route = routes[path];
  if (route) {
    
    // 异步加载路由所需的代码块
    route().then(module => {
    
      // 渲染路由组件
      module.default.render();
    });
  }
}

在这个例子中,当用户访问 /home 路由时,Web 程序会异步加载 ./Home 模块。如果用户访问 /about 或 /contact 路由,也会按照同样的方式异步加载相应的代码块。

optimization.splitChunks 配置

webpack4 及以上版本可以使用 optimization.splitChunks 配置项,自动地将公共的代码块提取到单独的文件中。这样可以避免重复打包相同的代码块,从而减小文件大小和加载时间。

例如,在 webpack.config.js 中配置 optimization.splitChunks:

module.exports = {
    
  // ...
  optimization: {
    
    splitChunks: {
    
      chunks: 'all',
      minSize: 30000,
      maxSize: 0,
      minChunks: 1,
      maxAsyncRequests: 5,
      maxInitialRequests: 3,
      automaticNameDelimiter: '~',
      name: true,
      cacheGroups: {
    
        vendors: {
    
          test: /[\\/]node_modules[\\/]/,
          priority: -10
        },
        default: {
    
          minChunks: 2,
          priority: -20,
          reuseExistingChunk: true
        }
      }
    }
  }
};

这个配置会自动将公共代码块分离出来,并生成一个名为 vendors~main.js 的文件。在 HTML 文件中使用这个文件即可实现代码分割:

<script src="vendors~main.js"></script>
<script src="main.js"></script>

89. React合成事件的原理?

	事件注册,事件触发
	React中模拟冒泡和捕获

原理:收集的事件放在dispatchQueue数组中,而冒泡和捕获的区别在于执行时机和顺序,那么我们只需要对数组按照不同顺序循环执行即可

总结:首先会在fiber节点进入render阶段的complete阶段时,将事件监听绑定在root上。然后调用ensureListeningTo进行事件绑定,生成事件合成对象、收集事件、触发真正的事件。

94.Vuex的实现原理是什么,写出其实现的核心代码?

TS相关面试题

1.interface和type的区别?

interface只能定义对象数据结构类型。 type侧重于直接定义类型 type 还可以给一个或多个类型起一个新名称(当变量用)
type当然也能定义对象类型

type 和 interface 相同点
相同1:type 和 interface都支持扩展
type 和 interface 不同点
区别1: type 可以为基本类型,联合类型 或 元组 甚至any等等 赋值定义别名,interface 明显办不到
区别2: interface 定义重名了会合并属性,type 办不到(会报错提醒 重复定义)

2.ts修饰符有哪些?

1、public:公有,在类里面、子类、类外面都可以访问
2、protected:保护类型,在雷里面、子类里面可以访问,在类外部不能访问
3、private:私有,在类里面可以访问,子类、类外边不能访问
属性如果不加修饰符默认是公有(public)

3.静态属性和静态方法的区别?

4.泛型的理解以及应用场景?

5.never类型和void类型的区别?

void
  表示没有任何类型
可以用到void 有以下几种情况

函数没写return
只写了 return, 没有具体的返回值
return 的是 undefined
never
  表示永远不会有值的一种类型,任何类型都不能赋值给 never 类型的变量

6.TS中函数的理解?

TS 里可以自定义传入参数的类型以及函数返回的类型。 TS 函数还可以设置可选参数。如果不设置可选参数,那么所有定义的参数都要传入。
对于函数返回类型,可以设置多个类型。但是要注意的是 undefined 是所有类型的大哥,如果 void 或者不声明返回类型,则返回
undefined。 ES 6 的特性,可以给函数加默认参数值。 要注意的是设置了默认值后就不需要设置类型了,因为 TS 可以做类型推断。
arguments 是如下结构,注意:不是数组,是对象,只是长得像数组。 TS 的重载和 Java
的差不多,就是可以对调用同一个函数的时候传入不同的参数。但是重载的函数参数数目应该要是一样的。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/zc_123_/article/details/130697122

智能推荐

LightOJ - 1067 Combinations(快速幂+逆元)_快速幂求逆元 在线oj-程序员宅基地

文章浏览阅读484次。DescriptionGiven n differentobjects, you want to take k of them. How many ways to can do it? For example, saythere are 4 items; you want to take 2 of them. So, you can do it 6 ways. Take 1, _快速幂求逆元 在线oj

Fairseq学习日记:注定麻烦的旅程_final_lr_scale-程序员宅基地

文章浏览阅读6.6k次,点赞10次,收藏23次。现在开头:Fairseq是一个正在快速迭代的产品,而且是开源的!这不是表扬,这意味着三件事情:1.他没有文档!所有框架代码都没有任何注释,包括函数docstring都没有2.他没有经过有效测试,估计是抢时间吧!即使是官网Readme里的例子也是无法跑起来的!3.他是一个框架,而且是一个非常不Pythonic的框架,充斥着inline/包装器/莫名其妙的语法。虽然这三点决定他真的对不住Facebook的金字招牌,但是作为一个学习者,总要把他运行起来,那么开始这场针对 FaceBOOK派“全_final_lr_scale

[Linux][Busybox]分享你不知道Top 命令参数_busybox top-程序员宅基地

文章浏览阅读5.1k次。目录摘要:基本操作与命令介绍:进入top后交互一点点新的操作Author: Keivn.Xu [email protected]摘要: 玩过Linux一定使用过busybox top命令,但下面的操作方法,你不一定有见过。基本操作与命令介绍:console:/ $ busybox top -help top: invalid optio..._busybox top

rssi参数获取_信号强度(RSSI)知识整理-程序员宅基地

文章浏览阅读1.6k次。为什么无线信号(RSSI)是负值答:其实归根到底为什么接收的无线信号是负值,这样子是不是容易理解多了。因为无线信号多为mW级别,所以对它进行了极化,转化为dBm而已,不表示信号是负的。1mW就是0dBm,小于1mW就是负数的dBm数。弄清信号强度的定义就行了:RSSI(接收信号强度)Received Signal Strength IndicatorRss=10logP,只需将接受到的信号功率P代..._c#获取低功耗设备的rssi信号强度

后端服务的雪崩效应及解决思路_接口超时时间过长导致雪崩效应-程序员宅基地

文章浏览阅读204次。1.RPC与本地调用的区别RPC远程调用,一般是跨平台、采用http协议,因为http协议底层使用socket技术,只要你的语言支持socket技术,就可以相互进行通讯。比如:java语言开发的接口,使用http协议,如此以来C#语言可以调用。本地调用:只支持java语言与java语言开发,使用虚拟机和虚拟机之间的通讯,RMI。2.雪崩效应产生的原因默认情况下只有一个线程池维护所有的服务接口,如果大量的请求访问同一个接口,达到tomcat线程池默认极限,可能会导致其他服务无法访问。3.雪_接口超时时间过长导致雪崩效应

linux操作redis_linux 连接redis-程序员宅基地

文章浏览阅读2.7w次,点赞4次,收藏35次。redis常用命令_linux 连接redis

随便推点

keil迁移到cubeIDE_cubeide生成代码 keil打开-程序员宅基地

文章浏览阅读2.7k次。以stm32f105rct6为例子,keil迁移到cubeIDE_cubeide生成代码 keil打开

语音处理:Python实现dBFS刻度和采样值相互转换_dbfs 频域-程序员宅基地

文章浏览阅读781次。以对数域常用的dBFS刻度为例,支持主流音频信号位深:整型16/24/32位和浮点32位,编写Python实现对数域和采样值单位互换功能_dbfs 频域

SOD(显著性目标检测)数据集_sod数据集-程序员宅基地

文章浏览阅读4k次,点赞5次,收藏29次。显著性目标检测常用十种数据集:SOD,提取码:f7uqDUT-OMRON,提取码:wqpnMSRA-B,提取码:rfrbSOC,提取码:d5b9SED2,提取码:q4iaHKU-IS,提取码:2f1iPASCAL-S,提取码:naaxDUTS,提取码:a5w7THUR-15K,提取码:ptk9ECSSD..._sod数据集

线程基础:多任务处理(18)——MESI协议以及带来的问题:伪共享-程序员宅基地

文章浏览阅读3.9k次,点赞10次,收藏17次。本文和后续文章将着眼CPU的工作原理阐述伪共享的解决方法和volatile关键字的应用。

Google Earth Engine (GEE) ——代码编辑器_gee怎么新建代码文件-程序员宅基地

文章浏览阅读1.7k次。问题 在线代码编辑器的主要功能是什么? 在学习 GEE 的过程中,我可以去哪里寻求帮助? 如何搜索和导入数据集? 如何创建、共享和保存脚本? 目标 了解代码编辑器中可用的工具 加载图像集合并将其过滤为相关图像 使用几何工具创建研究区域 代码编辑器概述GEE 有一个称为代码编辑器的集成开发环境 (IDE)。代码编辑器有许多功能可以帮助我们在本教程中更轻松地在这种环境中进行编程。有关详尽说明,请参阅GEE 用户指南..._gee怎么新建代码文件

关于 Eclipse 使用 Maven 打包,每次都需要下载 jar 包的问题_maven打包每次都要下载依赖-程序员宅基地

文章浏览阅读6.2k次。在是Eclipse开发的时候,使用Maven打包每次都需要联网下载jar包。第一次需要下载这个可以理解。但是每次都需要下载,就有点问题了...重点是,所用的网络不能访问Maven的私服,所以每次打包都断开网络。这样很麻烦,找资料发现勾选下图中的 Offline(离线) 就可以解决问题了。注意:当你需要下载其他的依赖时,就需要把这个勾去掉,不然连接不上仓库哦。..._maven打包每次都要下载依赖