出现高频次面试题大全

面试题文本

面试不再紧张,会持续优化更新,记得点点关注,加个收藏!

前言

  面试不再紧张,记得点点关注,加个收藏。

React

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

不同点:
1.props不可以在组件内部修改,但state可以在组件内部修改
2.可以从父组件修改自组件的props,而不能从父组件修改自组件的state。
相同点:
1.props和state都是导出HTML的原始数据。
2.props和state都是确定性的,如果我们写的组件为同一props和state的组合。
3.生成了不同的输出,那我们肯定是哪里错了。
4.props和state都会触发渲染更新。
5.props和state都是纯JS对象(用typeof来判断,结果都是object)
6.可以从父组件得到初始值props和state的初始值
render在哪些情况下执行?
1、类组件调用setState修改状态时。
2、函数组件通过useState Hook修改状态时。
3、类组件重新渲染时。
4、函数组件重新渲染时。

2.shouldComponentUpdate有什么作用?

shouldComponentUpdate是React中的一个生命周期方法,用于控制组件是否需要重新渲染。它的作用是优化组件的性能,避免不必要的渲染,提高应用的性能。

当组件的state或props发生变化时,React会调用shouldComponentUpdate方法。在该方法中,你可以通过比较当前的state和props与下一个state和props来决定是否需要重新渲染组件。如果shouldComponentUpdate返回false,组件将不会进行重新渲染,从而节省了不必要的计算和渲染资源。

通常情况下,React会自动根据state和props的变化来判断是否重新渲染组件,但在某些情况下,你可能需要手动实现shouldComponentUpdate来进行更细粒度的控制。比如,当组件的props中包含大量数据或者嵌套层次很深时,可以通过shouldComponentUpdate来避免不必要的渲染。

3.说说React中的虚拟dom?在虚拟dom计算的时候diff和key之间有什么关系?

1、实际上它只是一层对真实DOM的抽象,以JavaScript对象作为基础的树,用对象的属性来描述节点,最终可以通过一系列操作时这棵树映射到真实环境上,创建虚拟DOM就是为了更好将虚拟的节点渲染到页面视图中,所以虚拟DOM对象的节点与真实DOM的属性一一照应.
2、通过JS模拟网页文档节点,生成JS对象树(虚拟DOM),然后再进行一步生成真实的DOM树,再绘制到屏幕。如果后面有内容发生改变,React会重新生成一棵全新的虚拟DOM树,再与前面的虚拟DOM树进行比对diff,把差异的部分打包成patch,再应用到真实DOM,然后渲染到屏幕浏览器。
在虚拟dom计算的时候diff和key之间有什么关系:
1、React需要同时维护两棵虚拟DOM树:一棵表示当前的DOM结构,另一棵在React状态变更将要重新渲染时生成。React通过比较这两棵树的差异,决定是否需要修改DOM结构,以及如何修改。这种算法称作Diff算法。
2、key 当同一层级的某个节点添加了对于其他同级节点唯一的key属性,当它在当前层级的位置发生了变化后。react diff算法通过新旧节点比较后,如果发现了key值相同的新旧节点,就会执行移动操作(然后依然按原策略深入节点内部的差异对比更新),而不会执行原策略的删除旧节点,创建新节点的操作。这无疑大大提高了React性能和渲染效率。

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

新出来的两个钩子函数:
1、getDerviedStateFromProps
作用:从props中获取衍生的state。
2、getSnapshotBeforeUpdate
作用:在组件更新前获取快照,一般结合componentDidUpdate使用, getSnapBeforeUpdate中返回值将作为第三参数传递给componentDidUpdate它和componentDidUpdate将render夹在中间,其实它的核心作用就是在render改变dom之前,记录更新前的dom信息传递给componentDidUpdate。
React新的生命周期去除的钩子函数?
1、componentWillMount
2、componentWillReceiveProps
3、componentWillUpdate
总结
1、componentWillMount中可能需要做的事(一些数据初始化的操作就应该放在这个钩子中处理),constructor与componentDidMount也能做,甚至做的更好,此方法被废弃。
2、componentWillReceiveProps实际行为与命名并不相符,由于不稳定性已由getDerivedStateFromProps代替;
3、而componentWillUpdate同等理由被getSnapshotBeforeUpdate代替。

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

1、当前组件没有子节点数据类型就是undefined.
2、有一个子节点数据类型就是object 。
3、有多个子节点的时候才会是array ,只有在多个节点的时候才可以直接调用map方法,react资深提供了一个react.children.map()方法,可以安全遍历子节点对象。

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

( 1)父传子组件通信
<1>在父组件的子组件标签上绑定一个属性,传递参数。
<2>子组件通过props方法来接收对应的参数,直接调用即可。
(2)子传父组件通信
<1>在父组件的子组件标签上绑定一个属性,传递一个函数。 <2>子组件通过props方法来接收对应的函数,直接调用即可。
(3)非父子组件通信
<1>中间人模式
<2>context状态树传参。

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

Render函数在react中有两种形式,在类组件中指的是render方法,在函数组件中,指的是函数组件本身,在render中我们会编写jsx,jsx通过babel编译后就会转化为我们熟悉的js格式,在render过程中,React将新调用的render函数返回的树与旧版本的树进行比较,决定如何更新DOM,然后进行diff比较,更新DOM树。
触发时机:
1、类组件调用setState修改状态时;
2、函数组件通过useState Hook修改状态时;
3、类组件重新渲染时;
4、函数组件重新渲染时;

8.说说React生命周期中有哪些坑?为什么要溢出will相关生命周期?

getDerivedStateFromProps 容易编写反模式代码,使受控组件和非受控组件区分模糊.
componentWillMount 在 react 中已被标记弃用,不推荐使用,主要的原因是因为新的异步架构会导致它被多次调用,所以网络请求以及事件绑定应该放到 componentDidMount 中componentWillReceiveProps 同样也被标记弃用,被 getDerivedStateFromProps 所取代,主要原因是性能问题。
shouldComponentUpdate 通过返回 true 或者 false 来确定是否需要触发新的渲染。主要用于性能优化。
为什么要溢出will相关声明周期?
filber的机制下,生命周期分为render和commit的阶段,render的时候是可以被打断的,重新渲染,终止的,当一个任务执行到一半被打断后,下一次染线程抢回主动权时,这个任务被重启的形式是“重复执行一遍整个任务”而非“接着上次执行到的那行代码往下走”。这就导致 render 阶段的生命周期都是有可能被重复执行的,而你会发现废弃的这三个都是在render的阶段执行的,废弃这三个也是为了给fiber铺路
2.componentWillReceiveProps 和 componentWillUpdate 里滥用 setState 导致重复染死循环的

Redux

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

Redux本身是一个同步的状态管理库,它通过纯粹的函数来处理状态的更新。然而,Redux通过中间件(middleware)的概念,可以支持执行异步代码并处理异步操作。
实现异步操作的常用中间件是redux-thunk和redux-saga。下面是它们的实现原理:
Redux Thunk:Redux Thunk中间件允许在Redux的action中返回一个函数而不仅仅是一个普通的action对象。当一个函数作为action被派发时,Redux Thunk会拦截该函数,并将dispatch和getState作为参数传递给该函数。这样,函数就可以在需要时异步执行,执行异步操作后再手动派发其他的action。
Redux Saga:Redux Saga中间件使用了ES6的Generator函数来处理异步操作。它在Redux的action中使用特定的语法(如takeLatest、takeEvery)来监听特定的action,并在满足条件时执行相应的异步操作。Saga函数可以通过yield关键字来暂停和恢复执行,并使用put来派发其他的action。

中间件的实现原理是基于Redux的dispatch函数的扩展。中间件可以在action被派发到reducer之前或之后进行一些额外的处理。它们通过重写或拦截dispatch函数来实现这个功能。当一个action被派发时,中间件可以在派发到reducer之前或之后执行一些自定义的逻辑,例如日志记录、异步操作、条件判断等。

中间件的实现原理可以简单概括为:创建一个函数来接收store的dispatch和getState,然后返回一个新的dispatch函数。这个新的dispatch函数会在派发action前后执行一些自定义的逻辑,然后将action传递给下一个中间件或最终的reducer。

通过使用中间件,Redux可以处理异步操作,并且能够在不改变原有的同步数据流的情况下扩展其功能。中间件允许开发者以一种非常灵活的方式来管理和处理异步操作。

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

1、使用redux-thunk的代码,当我们返回的是函数时,store会帮我们调用这个返回的函数,并且把dispatch暴露出来供我们使用。对于redux-thunk的整个流程来说,它是等异步任务执行完成之后,我们再去调用dispatch,然后去store去调用reduces。
2、使用了redux-saga的代码,当我们dispatch的action类型不在reducer中时,redux-saga的监听函数takeEvery就会监听到,等异步任务有结果就执行put方法,相当于dispatch,再一次触发dispatch。对于redux-saga的整个流程来说,它是等执行完action和reducer之后,判断reducer中有没有这个action。
区别:
1、redux-thunk和redux-saga处理异步任务的时机不一样 。
2、redux的action基础上,重新开辟了一个 async action的分支,单独处理异步任务。
3、saga 自己基本上完全弄了一套 asyc 的事件监听机制,代码量大大增加,从我自己的使用体验来看 redux-thunk 更简单,和 redux 本身联系地更紧密。

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

在Redux,防止定义的action type 常量重复的一种常见做法时使用一个单独文件或模块来集中管理这些常量,以确保唯一性。

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

1、React-redux是官方react UI绑定层,react允许React组件从redux存储中读取数据,并将操作分派到存储以更新的状态。提供了content,Provider等API,帮助我们连接react和redux,实现的逻辑会更加的严谨高效
2、@reduxjs/tookit是对redux的二次封装,开箱即用的一个高效的redux开发工具,使得创建store,更新store
区别:
1、reduxjs/tookit相对于react-redux来说比较方便,集成了redux-devtools-extension,不需要额外的配置,非常方便
2、reduxjs/tookit集成immutable-js的功能,不需要安装配置使用,提升了开发效率
3、reduxjs/tookit集成了redux-thunk的功能
4、reduxjs/tookit将types、actions、reducers放在一起组成了全新的slices,简化了我们的使用。

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

在 Redux 中,同步 action 和异步 action 的最大区别在于它们处理数据流的方式和返回值。
同步 action 是一个简单的 JavaScript 对象,它描述了一个动作的类型和携带的数据。当我们调用一个同步 action 时,它会立即发出并被 Redux store 接收并处理。同步 action 是通过 Redux store 的 dispatch 方法同步触发的,它会立即返回一个描述动作的对象。
异步 action 是一个函数,通常被称为 thunk 函数,它返回一个函数。当我们调用一个异步 action 时,它不会立即发出动作,而是在内部执行一些异步操作,比如发送网络请求或定时器等。这个异步操作完成后,它会再次调用 dispatch 方法来发出一个相应的同步 action。异步 action 可以在内部执行副作用,并根据异步操作的结果来发出一个或多个同步 action。
14.redux实现原理?

7.redux实现原理?

Redux的实现原理可以概括为以下几个步骤:

创建Store:通过调用createStore(reducer)函数创建一个store对象。reducer是一个纯函数,用于处理不同的action类型并返回新的状态。

初始化State:在创建store时,会调用reducer函数一次,以获取初始的应用程序状态。这个初始状态将成为store的默认状态。

触发Action:组件通过调用store.dispatch(action)方法来触发一个action。action是一个普通的JavaScript对象,描述了发生了什么操作。
调用Reducer:当dispatch方法被调用后,Redux会调用reducer函数,并传入当前的状态和action。reducer根据action的类型,对状态进行处理,并返回一个新的状态。
更新State:Redux接收到reducer返回的新状态后,会更新store中的状态。
通知订阅者:如果有通过store.subscribe(listener)方法注册的订阅者,Redux会通知它们状态发生了变化。
获取State:通过store.getState()方法可以获取当前的应用程序状态。
重要的是要理解Redux的核心思想是单向数据流。当组件触发一个action时,它只是描述了一个意图,而不直接修改状态。然后,reducer根据action的类型来处理这个意图,并返回一个新的状态。这种方式确保了状态的可控性和可预测性。
Redux还支持中间件(middleware),中间件可以在action被派发到reducer之前进行拦截和处理。这使得我们可以在Redux的工作流程中添加额外的逻辑,例如异步操作、日志记录等。

TS

TS抽象类的理解?

1.以abstract开头的类是抽象类。
2.抽象类和其他类区别不大,只是不能用来创建对象。
3.抽象类就是专门用来被继承的类。
4.抽象类中可以添加抽象方法抽象方法只能定义抽象类中,子类必须对抽象方法进行重写。

ts 命名空间理解?

  1. ts 命名空间内元素的导出和导入
    新建 student.ts,创建命名空间,导出接口、类、函数、变量。
    新建 index.ts ,调用从命名空间导入接口、类、函数、变量。
  2. ts 嵌套命名空间
    新建 student.ts ,创建嵌套命名空间。
    新建 index.ts ,调用嵌套命名空间定义的元素。
    在TypeScript中,命名空间是一种将代码组织为逻辑模块的方式。它可以用来避免全局命名冲突,并提供了一种逻辑上分组和组织代码的机制。
    通过使用命名空间,可以将相关的类、接口、函数和变量组织在一起。这样可以更好地管理代码,并提高代码的可维护性。命名空间可以嵌套,形成层级结构,使得代码的组织更加灵活。

    在TypeScript中,可以使用namespace关键字来定义命名空间。
    MyNamespace就是一个命名空间,包含了SomeInterface接口、SomeClass类和someFunction函数。通过使用export关键字,可以将命名空间中的内容导出,以便在其他地方使用。
    要在其他地方使用命名空间中的内容,可以使用namespaceName.content的方式进行访问。
    命名空间在编译后会被转换为相应的模块,因此在使用命名空间之前,需要确保已经配置好了模块系统,在编译时能够正确地处理命名空间的转换。

VUE

Html&Css

弹性盒子

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

1、弹性盒的项目设置flex-grow属性定义项目的放大比例,默认值为0,值越大,放大越厉害,且不支持负值;
2、而flex-shrink属性定义项目的缩小比列,默认值为1,数值越大,缩小越厉害,同样不支持负值;
3、flex-basis属性定义了在分配多余空间之前,项目占据的主轴空间,浏览器根据这个属性,计算主轴是否有多余空间。他的默认值为auto,也就是项目的本来大小。

项目代码

其它

1.谈谈你对immutable.js的理解?

1、Immutable.js就是react中用来做性能优化的.
2、在react中使用immutable可以减少页面的一些不必要的渲染,不需要像react中进行深度对比而进行渲染.
3、immutable可以直接快速的进行对比,完成渲染,提升了渲染的效率,降低了性能的消耗.
4、Immutable不可改变的,在计算机中,即指一旦创建,就不能再被更改的数据.
对 Immutable对象的任何修改或添加删除操作都会返回一个新的Immutable对象。
Immutable 实现的原理是 Persistent Data Structure(持久化数据结构):
1、用一种数据结构来保存数据。
2、当数据被修改时,会返回一个对象,但是新的对象会尽可能的利用之前的数据结构而不会对内存造成浪费。

2.CDN的特点及意义?

1、CDN 意为内容分发网络,是基于现有网络的智能虚拟网络,分布在世界各地的边缘服务器上。基本思路是避免互联网上可能影响数据传输速度和稳定性的瓶颈和环节,使内容传输更快更稳定。
2、CDN 表示将数据从原始服务器复制到其他服务器。当用户访问时,他们可以在复制了数据内容的服务器上进行访问。其目的是使用户能够更快更好地获取所需内容,解决网络拥塞情况,提高用户访问网站的响应速度。CDN 加速成本低,速度快,适合访问量比较大的网站。
特点:
1.本地缓存加速:提高了企业网站(尤其是包含大量图片和静态页面的网站)的访问速度,大大提高了上述网站的稳定性。
2.镜像服务:消除了不同运营商之间互联瓶颈带来的影响,实现了跨运营商的网络加速,保证了不同网络的用户都能获得良好的接入质量。
3.远程加速:远程访问用户根据DNS负载均衡技术智能自动选择缓存服务器,选择最快的缓存服务器加速远程访问。
4.带宽优化:自动生成服务器的远程镜像缓存服务器。远程用户访问时,可以从缓存服务器读取数据,减少远程访问的带宽,分担网络流量,减轻原WEB服务器的负载。
5.集群抗攻击:广泛分布的CDN 节点加上节点间的智能冗余机制,可以有效防止黑客入侵,降低各种D.D.o.S攻击对网站的影响,同时保证更好的服务质量。

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

1.遍历速度:for循环通常比forEach方法更快,因为for循环是通过索引迭代数组的元素,而forEach方法是使用回调函数迭代数组的每个元素。在for循环中,迭代过程是基于数组的索引,不需要额外的函数调用和上下文切换,因此更高效。而forEach方法每次迭代都会调用一次回调函数,这可能会导致一些额外的开销。
2.循环控制:使用for循环可以更灵活地控制循环过程,可以使用break和continue语句来中断循环或跳过某些迭代。而forEach方法没有提供类似的机制,在需要灵活控制循环流程的情况下,for循环更加适用。
3.兼容性:for循环是JavaScript的原生语法,几乎可以在所有的JavaScript环境中使用。而forEach方法是ES5新增的数组方法,相对较新,可能在一些旧版本的浏览器中不被支持。

尽管for循环通常比forEach方法更高效,但这并不意味着在所有情况下都应该优先选择for循环。对于简单的迭代操作,使用forEach方法可以提高代码的可读性和可维护性。而对于需要更高性能和更灵活控制的场景,可以考虑使用for循环。
需要注意的是,性能优化并不总是最重要的考虑因素,代码的可读性、可维护性和可扩展性同样重要。在实际开发中,应根据具体的需求和情况选择最适合的循环方式。

4.![] 1== ![],![] == [],结果是什么?为什么?

首先因为!要比 == 优先级高,所以先执行![ ],而光一个[]是true,所以![]=false,所以就是false == false,所以第一个=true。
第二个也是一样,那就是false==[],因为当有一个值是布尔值相比较会把另一个值变成数值。所以false==0,又因为0 == false,所以是false == false,所以第二个也是true。

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

闭包是指在一个函数内部定义的函数,并且该内部函数可以访问外部函数的变量。闭包通常用于在函数外部访问局部变量,或者在函数外部对局部变量进行持久化存储。
闭包的应用场景包括:
封装私有变量:通过闭包可以创建一个函数,该函数可以访问和修改外部函数中的私有变量,从而实现封装和隐藏变量。
延长变量的生命周期:当外部函数执行完毕后,内部函数仍然可以访问外部函数的变量,从而实现对变量的持久化存储。
实现函数的柯里化:通过闭包可以将一个函数转化为多个嵌套函数的形式,每个嵌套函数都接收部分参数,并返回一个新的函数,从而实现函数的柯里化。
实现回调函数:闭包可以用于创建回调函数,将一个函数作为参数传递给另一个函数,并在需要的时候调用该函数。

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

1、小数:0.5px,相信浏览器肯定是会慢慢支持的;目前而言,如果能用的话,可以hack一下;
2、阴影,border-img的方案不建议使用
3、背景图片和缩放可以在项目中配合使用,如单个线条使用缩放,四条框用背景图片模拟,额,如果要圆角的话,无能无力了
4、建议采用transform和伪类。

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

1.使用CSS缩放:通过使用transform和scale属性来对元素进行缩放,可以将1像素的线条放大到设备像素比的大小.
2.使用viewport单位:通过使用vw和vh单位来设置元素的大小,可以根据视口的大小来动态调整元素的像素大小。
3.使用JavaScript插件:可以使用一些专门处理1像素问题的JavaScript插件,比如border.js、1px.js等。这些插件可以根据设备的像素比来动态调整元素的大小,解决1像素问题。使用插件可以更方便地处理1像素问题,但需要引入额外的插件依赖。

8.你对Object.defineProperty()的理解?

Object.defineProperty() 是 JavaScript 中用于定义或修改对象属性的方法。它允许精确地控制属性的特性,包括数据值、可写性、可枚举性和可配置性等。
语法:
Object.defineProperty(obj, prop, descriptor)
var foo = ‘bar’;
obj:要定义属性的对象。
prop:要定义或修改的属性的名称。
descriptor:一个描述符对象,用来定义或修改属性的特性,包括 value(属性的值)、writable(可写性)、enumerable(可枚举性)和 configurable(可配置性)等。
通过使用Object.defineProperty(),我们可以实现以下操作:
定义新属性:我们可以使用该方法在对象上定义新的属性,并指定属性的名称、值和特性。
修改现有属性:如果对象已经存在某个属性,我们可以使用该方法修改属性的值或特性。
控制属性特性:我们可以通过设置属性的特性,例如可写性(writable)、可枚举性(enumerable)和可配置性(configurable),来限制对属性的访问和修改。
需要注意的是,使用Object.defineProperty()定义的属性默认是不可枚举的,这意味着在遍历对象属性时不会包含该属性。如果需要将属性设置为可枚举的,可以将enumerable特性设置为true。
总之,Object.defineProperty()提供了一种灵活的方式来定义和修改对象属性,使我们能够更好地控制属性的行为和特性。

9.找出数组【1,2,3,4,5,3,2,2,4,2,2,3,1,3,5】中出现次数最多的数,并统计出现多少次,编写一个函数?

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值