最后
四轮技术面+一轮hr面结束,学习到了不少,面试也是一个学习检测自己的过程,面试前大概复习了 一周的时间,把以前的代码看了一下,字节跳动比较注重算法,面试前刷了下leetcode和剑指offer, 也刷了些在牛客网上的面经。大概就说这些了,写代码去了~
祝大家都能收获大厂offer~
篇幅有限,仅展示部分内容
function handleRefresh() {
// 在此处编写处理下拉刷新的逻辑
// 当用户下拉到一定程度时,触发刷新数据的操作
}
// 监听滚动事件
window.addEventListener(‘scroll’, () => {
const scrollHeight = document.documentElement.scrollHeight; // 页面总高度
const scrollTop = document.documentElement.scrollTop; // 滚动条距离顶部的高度
const clientHeight = document.documentElement.clientHeight; // 可视区域高度
if (scrollTop + clientHeight >= scrollHeight) {
handleLoadMore(); // 到达页面底部,执行上拉加载
}
});
// 监听触摸事件
let startY; // 记录触摸起始位置
window.addEventListener(‘touchstart’, (e) => {
startY = e.touches[0].pageY; // 记录触摸开始位置
});
window.addEventListener(‘touchmove’, (e) => {
const moveY = e.touches[0].pageY; // 当前触摸位置与起始位置的偏移量
const distance = moveY - startY; // 移动距离
if (distance > 0 && document.documentElement.scrollTop === 0) {
e.preventDefault(); // 阻止页面滚动
handleRefresh(); // 下拉到一定程度,执行下拉刷新
}
});
## 27.说说你对 useReducer 的理解?
理解:
1.`useReducer` 是 React 提供的一个 Hook,用于实现状态管理和状态更新,它的作用类似于类组件中的 `this.setState` 方法。通过 `useReducer`,可以将组件的状态逻辑抽离出来,以更清晰、可维护的方式管理组件的状态。
2.使用 `useReducer` 需要提供两个参数:reducer 函数和初始状态。其中,reducer 函数接收当前状态和动作(action),并返回新的 状态。
3.`useReducer` 返回的数组包含当前状态和 dispatch 方法,通过解构赋值可以分别获取它们
useReducer的好处:
1.当状态逻辑较复杂时,可以将其拆分为多个 case,每个 case 只关注自己的逻辑,使代码更易于理解和维护。
2.`useReducer` 还可以结合 `Context` API 实现全局状态管理,或者与其他 Hook 如 `useEffect`、`useContext` 等搭配使用,实现更强大的功能。
## 28.谈谈你对BFC的理解?
1. **BFC,或者块级格式上下文(Block Formatting Context),是CSS中的一个重要概念,用于控制和规范块级元素在布局中的表现。理解BFC对于解决布局问题和处理元素之间的相互影响非常有帮助。**
**BFC是一种重要的CSS布局概念,用于控制块级元素的布局和相互关系。了解BFC如何创建以及它的特性和作用可以帮助开发者更好地控制页面布局,解决一些常见的布局问题。**
1. **创建条件**:BFC是在以下情况下创建的:
* 根元素(HTML根元素)。
* 浮动元素(`float`属性不为`none`)。
* 绝对定位元素(`position`属性为`absolute`或`fixed`)。
* 行内块元素(`display`属性为`inline-block`)。
* 表格单元格元素(`display`属性为`table-cell`)。
* `overflow`属性不为`visible`的元素。
2. **特性和作用**:BFC具有以下特性和作用:
* 内部的块级盒子会在垂直方向上一个接一个地排列。
* BFC内部的元素不会与浮动元素重叠。
* BFC可以包含浮动元素,将浮动元素的边界框包含在内。
* BFC内部的元素会忽略浮动元素,不会与浮动元素重叠。
* BFC内部的元素不会溢出其容器,它们会在容器内重新布局,不会影响外部元素的位置。
3. **应用场景**:BFC的理解对于解决以下一些常见的布局问题非常有用:
* 清除浮动:将包含浮动元素的父元素创建为BFC,以清除浮动。
* 防止外边距合并:在两个垂直外边距发生合并时,将一个元素包含在BFC中,以防止合并。
* 自适应两栏布局:实现两栏布局时,将左侧栏创建为BFC,以防止右侧栏覆盖。
* 防止元素溢出:将包含溢出元素的容器创建为BFC,以确保不会影响其他元素的布局。
## 29.我们应该在什么场景下使用 useMemo 和 useCallback?
`useMemo` 和 `useCallback` 都是 React 提供的 Hook,它们都可以用于优化函数组件的性能。
`useMemo` 的作用是对函数的计算结果进行缓存,只有在依赖项发生变化时才会重新计算
当一个组件中渲染内容需要根据一些复杂的计算结果得出,这个计算过程可能会非常耗时,就可以考虑使用 `useMemo` 来缓存计算结果,避免不必要的重复计算,并且能够有效地提高渲染性能。
`useCallback` 的作用是对函数进行缓存,只有依赖项发生变化时才会创建新的函数。
当一个组件中传递给子组件的回调函数需要大量计算,或者是传递给子组件的回调函数会引起子组件的重复渲染时,就可以使用 `useCallback` 来缓存回调函数。
## 30.为什么 useState 返回的是数组而不是对象?
在 React 中,`useState` 是一个用于在函数组件中声明状态的钩子函数。它的返回值是一个长度固定为 2 的数组,而不是一个对象,这是由设计选择所决定的。
使用数组来表示状态,是因为它具有以下优势:
1. 简单直观:将状态以数组的形式进行管理,可以更容易地理解和使用。
2. 顺序保持一致:使用 `useState` 声明多个状态时,它们的顺序和声明的顺序是完全一致的。你可以根据索引访问和更新每个状态,而不需要命名或记住状态的特定名称。
3. 无需每次指定键:当更新状态时,不需要像使用对象那样指定键。只要调用 `useState` 返回的第二个元素(通常命名为 `setXXX`)即可。
## 31.虚拟DOM一定更快吗?
虚拟 DOM 本身并不一定比直接操作真实 DOM 更快。它的性能优势主要体现在以下几个方面:
1. 高效的批量更新:虚拟 DOM 可以将多次状态变更批量处理,并通过算法进行优化,最终只更新真实 DOM 中需要变更的部分。这种批量更新的方式可以有效减少对真实 DOM 的频繁操作,提高性能。
2. 减少重绘和回流:虚拟 DOM 会通过 diff 算法,比较新旧虚拟 DOM 树的差异,并最小化对真实 DOM 的修改。通过最小化修改操作,可以减少浏览器的重绘(repaint)和回流(reflow)操作,从而提升性能。
3. 跨平台能力:虚拟 DOM 是一个抽象层,可以使得 React 这样的框架同时运行在多个平台上,如浏览器、移动端等。它可以将用户界面渲染为虚拟 DOM,然后再根据具体平台的特性将其转化为真实的 UI。
尽管虚拟 DOM 可以提供性能上的优势,但并不意味着它一定比直接操作真实 DOM 更快。在某些简单场景下,直接操作真实 DOM 可能更加高效。而且虚拟 DOM 本身也会引入一定的开销,比如虚拟 DOM 的生成和 diff 算法的计算等。
## 32.React中,能否直接将 props 的值复制给 state?
在 React 中,可以把 `props` 直接赋值给 `state`,但这样不一定是一个好的做法,因为 `props` 和 `state` 有不同的含义和用途。
`props` 表示从父组件传递给子组件的属性,主要用于组件之间传递数据。而 `state` 则表示组件自身的状态,主要用于保存交互状态或控制组件行为。
虽然 `props` 和 `state` 的数据形式相同,但它们存在本质的区别:
1. `props` 是从父组件传递下来的,子组件不能修改。而 `state` 是组件自己管理的,可以通过 setState() 方法进行修改。
2. `props` 可以用于组件之间传递数据,而 `state` 主要用于保存组件内部的交互状态。
因此,直接将 `props` 复制给 `state` 忽略了组件自身状态的更新和控制,容易导致数据不一致或不可控的情况。在一些特殊场景下,可以将 `props` 赋值给 `state`,但需要认真考虑并仔细分析其影响和后果。
## 33.什么是高阶组件?
高阶组件(Higher-Order Component,简称 HOC)是一个函数,它接收一个组件作为参数,并返回一个新的组件。这个新的组件可以对原组件进行扩展或增强,例如添加一些通用的逻辑、状态、行为等。
高阶组件本质上是一个装饰器模式,通过把通用逻辑从组件中抽离出来,实现代码复用和组件的解耦。高阶组件可以用于很多场景,例如添加权限控制、添加数据逻辑、动态渲染等等。
在 React 中,高阶组件主要通过以下方式实现:
1. 属性代理:通过 props 将新的属性传递给被包裹的组件。
2. 反向继承:通过继承被包裹的组件,可以覆盖或增加它的生命周期方法和渲染函数。
使用高阶组件可以有效避免代码冗余和逻辑耦合,提高代码的可维护性和重用性。但需要注意,过度使用高阶组件可能会导致组件层级过深、代码难以理解等问题,因此需要根据具体场景进行评估和使用。
## 34. React.PureComponent 和 React.Component 有什么区别?
1.React.PureComponent`和`React.Component会浅比较组件的 props 和 state 的变化,如果相同则不会重新渲染组件。而 `React.Component` 每次更新都会重新渲染组件。
2.`React.PureComponent` 会帮助我们优化组件性能,避免不必要的组件重渲染,从而提升应用的性能和用户体验
3.`React.PureComponent` 的浅比较只检查对象引用是否相等,不会检查对象内部属性的变化,如果使用不当可能会导致错误或不可预期的结果。
4.`React.PureComponent`,因为每次渲染都会生成新的对象,无法享受到性能优化的好处。
**目录**
[1.清除浮动的几种方式,各自的优缺点,推荐使用哪种?](#1.%E6%B8%85%E9%99%A4%E6%B5%AE%E5%8A%A8%E7%9A%84%E5%87%A0%E7%A7%8D%E6%96%B9%E5%BC%8F%EF%BC%8C%E5%90%84%E8%87%AA%E7%9A%84%E4%BC%98%E7%BC%BA%E7%82%B9%EF%BC%8C%E6%8E%A8%E8%8D%90%E4%BD%BF%E7%94%A8%E5%93%AA%E7%A7%8D%EF%BC%9F)
[2.Sass、LESS区别是什么?大家为什么要使用他们?](#2.Sass%E3%80%81LESS%E5%8C%BA%E5%88%AB%E6%98%AF%E4%BB%80%E4%B9%88%EF%BC%9F%E5%A4%A7%E5%AE%B6%E4%B8%BA%E4%BB%80%E4%B9%88%E8%A6%81%E4%BD%BF%E7%94%A8%E4%BB%96%E4%BB%AC%EF%BC%9F)
[3.说说React生命周期有哪些不同的阶段?每个阶段对应的方法是?(2)](#3.%E8%AF%B4%E8%AF%B4React%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F%E6%9C%89%E5%93%AA%E4%BA%9B%E4%B8%8D%E5%90%8C%E7%9A%84%E9%98%B6%E6%AE%B5%EF%BC%9F%E6%AF%8F%E4%B8%AA%E9%98%B6%E6%AE%B5%E5%AF%B9%E5%BA%94%E7%9A%84%E6%96%B9%E6%B3%95%E6%98%AF%EF%BC%9F%EF%BC%882%EF%BC%89)
[4.说说React中setState执行机制?](#4.%E8%AF%B4%E8%AF%B4React%E4%B8%ADsetState%E6%89%A7%E8%A1%8C%E6%9C%BA%E5%88%B6%EF%BC%9F)
[5.如果需要手动写动画,你认为最小时间间隔是多久,为什么?](#5.%E5%A6%82%E6%9E%9C%E9%9C%80%E8%A6%81%E6%89%8B%E5%8A%A8%E5%86%99%E5%8A%A8%E7%94%BB%EF%BC%8C%E4%BD%A0%E8%AE%A4%E4%B8%BA%E6%9C%80%E5%B0%8F%E6%97%B6%E9%97%B4%E9%97%B4%E9%9A%94%E6%98%AF%E5%A4%9A%E4%B9%85%EF%BC%8C%E4%B8%BA%E4%BB%80%E4%B9%88%EF%BC%9F)
[6.React组件之间如何通信?(4)](#6.React%E7%BB%84%E4%BB%B6%E4%B9%8B%E9%97%B4%E5%A6%82%E4%BD%95%E9%80%9A%E4%BF%A1%EF%BC%9F%EF%BC%884%EF%BC%89)
[7.说说你对受控组件和非受控组件的理解?应用场景?\*//\*\*](#7.%E8%AF%B4%E8%AF%B4%E4%BD%A0%E5%AF%B9%E5%8F%97%E6%8E%A7%E7%BB%84%E4%BB%B6%E5%92%8C%E9%9D%9E%E5%8F%97%E6%8E%A7%E7%BB%84%E4%BB%B6%E7%9A%84%E7%90%86%E8%A7%A3%EF%BC%9F%E5%BA%94%E7%94%A8%E5%9C%BA%E6%99%AF%EF%BC%9F*%2F%2F**)
[8.说说你对fiber架构的理解?解决了什么问题?(2)](#8.%E8%AF%B4%E8%AF%B4%E4%BD%A0%E5%AF%B9fiber%E6%9E%B6%E6%9E%84%E7%9A%84%E7%90%86%E8%A7%A3%EF%BC%9F%E8%A7%A3%E5%86%B3%E4%BA%86%E4%BB%80%E4%B9%88%E9%97%AE%E9%A2%98%EF%BC%9F%EF%BC%882%EF%BC%89)
[9.说说react diff的原理是什么?(2)](#9.%E8%AF%B4%E8%AF%B4react%20diff%E7%9A%84%E5%8E%9F%E7%90%86%E6%98%AF%E4%BB%80%E4%B9%88%EF%BC%9F%EF%BC%882%EF%BC%89)
[10.说说你对redux中间件的理解?常用的中间件有哪些?实现原理?(2)](#10.%E8%AF%B4%E8%AF%B4%E4%BD%A0%E5%AF%B9redux%E4%B8%AD%E9%97%B4%E4%BB%B6%E7%9A%84%E7%90%86%E8%A7%A3%EF%BC%9F%E5%B8%B8%E7%94%A8%E7%9A%84%E4%B8%AD%E9%97%B4%E4%BB%B6%E6%9C%89%E5%93%AA%E4%BA%9B%EF%BC%9F%E5%AE%9E%E7%8E%B0%E5%8E%9F%E7%90%86%EF%BC%9F%EF%BC%882%EF%BC%89)
[11.路由原理 history 和 hash 两种路由方式的特点?](#11.%E8%B7%AF%E7%94%B1%E5%8E%9F%E7%90%86%20history%20%E5%92%8C%20hash%20%E4%B8%A4%E7%A7%8D%E8%B7%AF%E7%94%B1%E6%96%B9%E5%BC%8F%E7%9A%84%E7%89%B9%E7%82%B9%EF%BC%9F)
[12.什么是强缓存和协商缓存?(2)](#12.%E4%BB%80%E4%B9%88%E6%98%AF%E5%BC%BA%E7%BC%93%E5%AD%98%E5%92%8C%E5%8D%8F%E5%95%86%E7%BC%93%E5%AD%98%EF%BC%9F%EF%BC%882%EF%B