最全面试题

react

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

props:
props是一个从外部传进组件的参数,由于React具有单向数据流的特性,所以他的主要作用是从父组件向子组件中传递数据,它是不可改变的,如果想要改变它,只能通过外部组件传入新的props来重新渲染子组件,否则子组件的props和展示形式不会改变,props除了可以传字符串,数字,还可以传递对象,数组甚至是回调函数

state:
state主要作用是用于组件保存,控制及修改自己的状态,它只能在constructor中初始化,state是可以被改变的,state放改动的一些属性,比如点击选中,再点击取消,类似这种属性就放入带state中,注意:没有state的叫做无状态组件,多用props少用state,多写无状态组件,注意:修改state的值时,必须通过调用setState方法,当我们调用this.setState方法时,React会更新组件的数据状态,并且重新调用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的初始值

触发时机:
类组件调用用setState修改状态,从而执行render
函数组件通过useState的hook修改状态,函数通过useState这种形式更新数据,当数组的值不在发生变化就不会触发render

2. shouldComponentUpdate有什么作用?

ShouldComponentUpdate是React组件生命周期方法之一,用于控制组件是否进行重新渲染。
返回一个布尔值,表示组件是否应该重新渲染

方法的作用:
优化组件的性能。每当组件的props或state发生变化时,React都会重新渲染组件。
有时候,组件的props或state变化并不会影响到组件的输出,可以通过重写shouldComponentUpdate方法来避免不必要的重新渲染,从而提高性能。
根据组件的props和state的变化情况进行逻辑判断,返回一个布尔值来决定是否重新渲染组件。如果返回false,组件将不会进行重新渲染,而是直接使用之前的渲染结果

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

虚拟DOM(Virtual DOM)是React中的一个概念,它是一个轻量级的JavaScript对象,用于表示真实DOM的抽象层。
React使用虚拟DOM来提高性能和效率

关系:
diff算法是用于比较两个虚拟DOM树之间的差异,并确定需要更新的部分。它通过一种高效的算法来比较节点的类型、属性和子节点等信息,以确定需要更新或重新渲染的部分。
key属性是在虚拟DOM的渲染中用于标识唯一子元素的属性。在虚拟DOM的比较过程中,React使用key属性来追踪组件及其子元素的身份,以便更准确地确定哪些元素需要更新。使用合适的key可以帮助React在diff算法中更准确地确定元素的插入、移动和删除操作

工作原理:
当组件状态发生变化时,React会创建一个新的虚拟DOM树,表示组件在新状态下应该呈现的样子。
React将新的虚拟DOM树与之前的虚拟DOM树进行比较,找出两者之间的差异(即diff算法)。
根据差异,React会将需要更新的部分应用到真实DOM中,只更新发生变化的部分,而不是整个DOM树。

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

分别为getDerivedStateFromProps(从props中得到衍生的state)和getSnapshotBeforeUpdate。 

区别:

1、componentWillMount中可能需要做的事(一些数据初始化的操作就应该放在这个钩子中处理),constructor与componentDidMount也能做,甚至做的更好,此方法被废弃。

2、componentWillReceiveProps实际行为与命名并不相符,由于不稳定性已由getDerivedStateFromProps代替;

3、而componentWillUpdate同等理由被getSnapshotBeforeUpdate代替

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

使用map函数遍历props.children时,如果props.children只包含一个子节点,会收到一个异常显示,	在这种情况下,props.children将不是一个数组,而是一个单独的React元素。

两种方法:

1.使用React.Children.map:React提供了React.Children.map方法来遍历props.children,无论props.children是单个React元素还是多个React元素,都能正常工作。用法类似于Array.map,可以对每个子元素进行操作,返回一个新的数组

2.将props.children转换为数组:可以使用Array.from或展开运算符[...]将props.children转换为一个数组,然后再使用map函数进行遍历

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

1.父传子:在父组件的子组件标签上绑定一个自定义属性,通过属性值传递给子组件,子组件使用props接收

2.子传父:在父组件的子组件标签上绑定一个自定义函数,通过这个函数的回调函数获取到子组件传递给父组件的值

3.兄弟组件传值:找一个公用的父组件,进行父传子,子传服一系列操作

4.消息订阅发布:订阅者监听事件,并且做出反应,发布者发布消息,通过event方法获取道数据,当发布者修改数据后,监听者也可以及时获取最新数据

5.全局状态管理工具:借助redux全局状态管理工具进行通信,这种工具会维护一个全局状态中心store,并根据不同事件来产生新的状态

6.跨层级通讯:`Context` 设计⽬的是为了共享那些对于⼀个组件树⽽⾔是“全局”的数据,使用`context`提供了组件之间通讯的一种方式,可以共享数据,其他数据都能读取对应的数据

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

Redux本身是一个同步的状态管理库,通过中间件来支持执行异步代码。
Redux中间件允许开发者在派发(action dispatch)和到达reducer之间的过程中拦截和处理额外的逻辑。

	中间件的实现原理是基于Redux的洋葱模型(Onion Model)或管道模型(Pipeline Model)。
当一个action被派发时,会首先经过中间件链中的第一个中间件,然后通过next()函数传递给下一个中间件,直到达到最后一个中间件。
每个中间件都可以对action进行处理、修改、延迟或触发其他操作。处理完之后,action最终会到达reducer进行状态的更新。

	中间件可以在派发action和到达reducer之间执行一些异步操作,如发起网络请求、处理副作用、触发其他action等。
当中间件处理完异步操作后,可以再次派发一个新的action,或者不派发action而是将处理结果传递给下一个中间件。

	Redux中间件的实现原理主要基于函数柯里化和函数组合的概念。每个中间件都是一个接收store.dispatch和store.getState函数作为参数的函数,它返回一个接收next函数作为参数的函数。
这样就形成了一个中间件链,每个中间件都可以在执行自己的逻辑之前或之后调用next函数,将控制权传递给下一个中间件。

常见的Redux中间件如Redux Thunk、Redux Saga、Redux Observable等,它们都提供了不同的方式来处理异步操作。

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

同步:
同步action是一个简单的对象,描述了发生了什么类型的事件,并携带一些数据。
它会立即被派发给Redux的store,通过reducer更新应用的状态。
同步action的处理是立即执行的,不涉及任何异步操作。

异步:
异步action是一个函数,通常称为thunk函数。
异步action可以执行异步操作,例如发起网络请求、读取本地存储等。
它可以在异步操作完成后,再派发一个同步action,用于更新应用状态。
异步action的处理通常需要借助Redux中间件(如Redux Thunk、Redux Saga等)来支持。

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

	Redux-thunk是一个函数,允许在redux中派发函数类型的action 不仅仅是简单的对象,当派发一个函数类型的action时,redux-thunk会拦截该action并执行该函数,
可以在函数中执行异步操作,并在异步操作完成后手动派发一个同步的action来更新状态

	Redux-saga使用了generator函数来处理异步操作,它有单独的线程,在该线程中监听redux的action,并以声明的方式来处理异步操作,saga使用了类似于同步代码的写法,
实际上是通过yield关键字来暂停和恢复异步操作的

区别:

Redux:
相对比较简单,
适用于处理相对简单的异步请求或延迟操作,
可以直接派发函数类型的action,
但在处理复杂的异步流程时可能需要编写更多的样板代码

Redux-saga:
提供了更高级的抽象,
用于处理复杂的异步流程和副作用,
它可以处理各种异步操作,如网络请求 取消操作等 
提供了更灵活的控制流程和副作用管理的能力

应用场景:

Redux-thunk:
适用于简单的异步操作,如发起简单的网络请求、处理表单提交等。
它的学习曲线较低,适合小型项目或需要快速实现异步逻辑的场景。

Redux-saga:
用于复杂的异步流程,如处理多个相互依赖的请求、处理WebSocket连接、处理复杂的状态同步逻辑等。
它提供了更高级的控制流程和副作用管理的能力,适合大型项目或需要处理复杂异步逻辑的场景

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

1.统一管理:将所有的action-type常量集中管理,可以创建一个单独的文件或模块,用于定义和导出所有的action-type常量。这样可以确保所有的action-type常量都在同一个地方定义,避免重复定义。

2.命名空间:在定义action-type常量时,可以使用命名空间来避免重复。

3.唯一性检查:可以编写脚本或工具来检查所有的action-type常量,确保没有重复定义。可以通过遍历所有的定义文件,检查常量的唯一性,并给出警告或错误提示。

4.使用工具库:可以使用一些工具库来帮助管理和防止action-type常量的重复。例如,可以使用redux-actions库来自动生成action-type常量,它可以自动根据action的名称生成唯一的常量,并提供一些辅助函数来简化action的定义和处理。

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

@reduxjs/toolkit是Redux官方提供的一个工具集,旨在简化和优化Redux的使用方式 

区别:

react-redux:
react-redux是一个与React结合使用Redux的官方库。
提供了用于将Redux与React组件进行连接的connect函数和<Provider>组件。
react-redux帮助管理React组件与Redux之间的数据流动,使得Redux的状态可以在React组件中进行访问和更新。

@reduxjs/toolkit:
@reduxjs/toolkit是一个与Redux结合使用的工具集,用于简化和优化Redux的使用方式。
它提供了一些工具和API,帮助开发者更轻松地编写和组织Redux代码,减少样板代码的编写,并提供了一些约定和默认配置。

react-redux和@reduxjs/toolkit可以一起使用,@reduxjs/toolkit提供的简化和优化工具可以与react-redux的连接机制结合使用,进一步简化Redux在React应用中的使用和管理

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

原理:
	首次渲染:当组件被挂载到DOM时,React会调用组件的render方法,获取组件的输出内容。
render方法返回一个React元素(或者null),描述了组件应该如何在DOM中呈现。

	数据更新:当组件的props或state发生变化时,React会重新调用组件的render方法,获取组件新的输出内容。
React通过比较前一次渲染的输出和当前的输出,找出差异并更新DOM,从而实现局部更新,而不是重新渲染整个组件。

	虚拟DOM比较:在进行更新时,React使用虚拟DOM(Virtual DOM)进行比较,而不是直接操作真实DOM。
React会将新的虚拟DOM树与之前的虚拟DOM树进行比较,找出两者之间的差异。然后,React会将差异应用到真实DOM上,只更新发生变化的部分,从而提高性能和效率

触发:

1.组件首次渲染:当组件被挂载到DOM时,会调用组件的render方法进行首次渲染。
2.组件的props或state发生变化:当组件的props或state发生变化时,React会重新调用组件的render方法,获取新的输出内容,并进行DOM的更新。

javascript

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

	Immutable.js是一个JavaScript库,用于处理不可变(Immutable)数据结构。
它提供了一组不可变的数据类型,如List、Map、Set等,以及一些操作这些数据类型的方法。

Immutable.js的核心思想是不直接修改数据,而是通过创建新的不可变数据来实现数据的更新和变化

理解:

1.不可变性:Immutable.js的主要概念是不可变性,即数据一旦创建就不可更改。每次对Immutable.js数据进行修改,都会返回一个新的不可变数据,而不是直接修改原始数据。这种不可变性确保了数据的稳定性和可预测性,避免了一些常见的数据修改问题。

2.持久化数据结构:Immutable.js的数据结构是持久化的,意味着在对数据进行修改时,原始数据仍然保持不变。Immutable.js使用了结构共享(Structural Sharing)的技术,只有被修改的部分会被复制,共享部分则被共享在新数据和原始数据之间,从而节省了内存和性能。

3.纯函数式操作:Immutable.js提供了一组纯函数式的操作方法,用于对不可变数据进行增删改查等操作。这些操作方法返回新的不可变数据,而不会修改原始数据。通过使用这些操作方法,可以方便地进行数据的更新和变化,同时保持数据的不可变性。

4.性能优化:Immutable.js通过结构共享和持久化数据结构的特性,可以提供更好的性能。由于只有被修改的部分会被复制,而共享部分可以被多个数据共享,可以减少内存占用和提高性能。

5.引用相等性:Immutable.js使用引用相等性来判断两个不可变数据是否相等。如果两个不可变数据的引用相同,即它们是同一个对象,那么它们被认为是相等的。这可以简化相等性的判断,避免深度比较。

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

1.作用域链访问:for循环中的变量直接在当前作用域进行访问,而forEach方法中的回调函数会在一个新的作用域中执行。在forEach中访问外部变量时,需要通过作用域链进行查找,可能会导致性能上的一些开销

2.优化机制:for循环是一种基本的循环结构,JavaScript引擎在执行for循环时可以进行更多的优化和内联操作,以提高代码的执行效率。而forEach方法是一个高阶函数,它需要遍历数组并针对每个元素执行回调函数,这可能导致额外的函数调用和迭代开销。

3.可中断性:for循环可以通过break语句或return语句来提前终止循环,而forEach方法无法直接中断循环。这在某些情况下可以提高性能,因为可以避免对不必要的迭代进行操作

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

![]表示一个非空数组,而![] == ![]的结果是true,![] == []的结果是false

![]表示对一个非空数组进行逻辑非(取反)操作,根据JavaScript的规则,非空数组被视为真值(truthy value),对其取反后为false。
[]表示一个空数组,根据JavaScript的规则,空数组被视为真值(truthy value)。

1.![] == ![]比较的是两个false值,根据JavaScript的规则,两个false值是相等的,所以表达式的结果为true。因此,![] == ![]的结果应该是true。

2.![] == []比较的是一个false值和一个空数组,根据JavaScript的规则,不同类型的值进行相等比较时,会先进行类型转换。
在进行类型转换时,[]会被转换为字符串"",而false会被转换为数字0。因为""和0是不同的类型和值,所以表达式的结果是false

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

闭包是指一个函数内部定义的函数,并且函数内部可以访问外部函数的变量。
闭包包含两部分:内部函数和内部函数所在的环境(及外部函数的变量)

优点:
        1.保护数据:闭包可以将变量封装在内部函数中,只能通过内部函数访问,从而保护数据的安全性
        2.延长变量生命周期:闭包可以使得外部函数中的变量在外部函数执行完毕后仍然存在,从而延长了变量的生命周期
        3.实现私有化属性和方法:通过闭包可以模拟实现类似于类的私有属性和方法的功能

缺点:
        1.资源占用:闭包会占用更多的内存资源,因为闭包中的变量在外部函数执行完毕后仍然存在于内存中
        2.可能引发内存泄露:如果闭包中的变量长时间存在,并且被外部函数以外的其他对象引用,就可能导致内存泄漏问题
        3.难以理解和调试:闭包的嵌套结构和变量作用域较为复杂,可能会增加代码的理解和调试难度

应用场景:
        1.缓存:闭包可以用于实现缓存功能,将一些计算结果保存在闭包中,避免重复计算
        2.回调函数:闭包可以用于实现回调函数,将函数作为参数传递给其他函数,并在其它函数执行完毕后调用闭包函数
        3.封装:闭包可以用于实现模块化开发,将一些逻辑和数据封装在闭包中,提供给外部使用特定的接口

服务器

1. CDN的特点及意义?

CDN(Content Delivery Network)是一个分布式的网络架构,用于提供高效的内容分发服务

特点:
1.分布式部署:CDN采用分布式的服务器网络,将内容分发到离用户更近的边缘节点,减少网络延迟和提高访问速度。
2.缓存机制:CDN通过在边缘节点缓存静态内容,减轻源服务器的负载,提高响应速度。
3.高可用性:CDN具有高可用性,即使某个节点发生故障,其他节点仍然可以继续提供服务。
4.负载均衡:CDN可以根据用户的位置和网络状况,智能地选择最优的节点提供服务,实现负载均衡。

意义:
1.提高用户访问速度:CDN通过将内容分发到离用户更近的边缘节点,减少网络延迟,提高用户访问速度和体验。
2.减轻源服务器负载:CDN通过在边缘节点缓存静态内容,减轻源服务器的负载,提高源服务器的性能和可靠性。
3.改善网络传输效率:CDN可以优化网络传输路径,减少网络拥塞,并通过压缩和优化内容来减小传输的数据量。
4.提供高可用性和可靠性:CDN的分布式架构和负载均衡机制可以提供高可用性和可靠性,即使某个节点发生故障,其他节点仍然可以提供服务。
5.降低网络成本:通过使用CDN,可以减少网络传输流量,降低网络成本。

css

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

1.使用响应式布局:
使用CSS的媒体查询(Media Queries)来适配不同的设备和屏幕尺寸。

2.使用Viewport单位:
使用Viewport单位(如vw、vh)来代替传统的像素单位(px),以相对于视口的宽度或高度进行布局和尺寸计算

3.弹性布局:
使用Flexbox或Grid布局来实现弹性和自适应的页面布局。
这些布局方式可以根据屏幕尺寸和容器大小自动调整元素的位置和大小。

4.图片适配:
使用响应式图片或使用CSS的max-width属性来确保图片在不同屏幕尺寸下自适应。
可以使用srcset和sizes属性来提供不同尺寸和分辨率的图片资源。

5.使用移动端优化的CSS框架:
使用一些经过移动端优化的CSS框架,如Bootstrap、Ant Design Mobile等,可以提供一些移动端适配的组件和样式。

6.测试和调试:
使用模拟器、真机调试和响应式设计工具进行测试和调试,确保页面在各种设备和屏幕尺寸下的正常显示和交互。

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

1.使用CSS的border属性:
通过设置元素的border属性,将其宽度设置为1像素,配合缩放比例进行调整。
例如,可以使用border: 1px solid #000;来创建一个1像素的边框。结合媒体查询和缩放比例进行适配。

2.使用伪元素和缩放:
使用伪元素(::before或::after)来创建一个1像素的伪元素,并通过缩放来调整其显示。
可以使用transform: scaleY(0.5);来将伪元素的高度缩放为原来的一半。

3.使用特定的CSS库或工具:
有一些专门解决移动端1像素问题的CSS库或工具可供选择,如border.css、postcss-px-to-viewport等。
这些工具提供了更方便的解决方案,可以自动转换1像素的边框或线条。

4.使用SVG或Icon Font:
使用矢量图形(SVG)或Icon Font来绘制1像素的边框或线条。
矢量图形可以无损放大和缩小,保持清晰度。
Icon Font可以使用字体图标库中的1像素图标来绘制线条

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

弹性盒(Flexbox)布局是一种用于创建灵活的、自适应的页面布局的CSS布局模型。

在弹性盒中,缩放(flex shrink)机制用于控制弹性盒子内项目的缩小行为
在弹性盒中,每个项目都具有flex-shrink属性,用于确定项目在空间不足时是否要缩小以及缩小的比例。flex-shrink属性接受一个非负整数值,默认值为1。

工作原理:
1.弹性盒中的项目根据其flex-shrink属性值进行排序。较大的flex-shrink值的项目将优先缩小。
2.当弹性盒的容器空间不足以容纳所有项目时,浏览器会根据项目的flex-shrink属性值来决定各个项目的缩小比例。
3.缩小比例的计算是根据项目的flex-shrink属性值进行的。如果所有项目的flex-shrink值都相等,则它们将等比例缩小。如果某个项目的flex-shrink值为0,则该项目不会缩小,其他项目将按比例进行缩小

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值