React18原理: 渲染与更新时的重点关注事项
概述
- react 在渲染过程中要做很多事情,所以不可能直接通过初始元素直接渲染
- 还需要一个东西,就是虚拟节点,暂不涉及React Fiber的概念,将vDom树和Fiber 树统称为虚拟节点
- 有了初始元素后,React 就会根据初始元素和其他可以生成虚拟节点的东西生成虚拟节点
- React一定是通过虚拟节点来进行渲染的
常用节点类型
- 除了初始元素能生成虚拟节点以外,还有哪些可能生成虚拟节点?总共有多少节点类型?
1. Dom节点 (ReactDomComponent)
- 此dom非彼dom, 这里的dom指的是虚拟dom节点,当初始化元素的type属性为字符串的时候
- React 就会创建虚拟dom节点,例如,前面使用 jsx 直接书写的
const B = <div></div>
- 它的属性就是div, 可以打印出来
{ type: 'div' }
2. 组件节点 (ReactComposite)
- class组件和函数式组件
- type 有两类:class App 或 f Test() 这种举例
3. 文本节点 (ReactTextNode)
- 直接书写字符串或数字,React 会创建为文本节点
- 比如,我们可以直接用 ReactDOM.render 方法直接渲染字符串或数字
import ReactDOM from 'react-dom/client';const root = ReactDOM.createRoot(document.getElementById('root'));// root.render('一头猪') // 创建文本节点 root.render(1111); // 创建文本节点
4. 空节点(ReactEmpty)
- 我们平时写 React 代码的时候,经常会写三目表达式
{this.state.xxx ? <App/> : false}
- 用来进行条件渲染,只知道为 false 就不会渲染,到底是怎么一回事?
- 其实,遇到字面量 null, false, true, undefined 在 React 中均会被创建一个空节点
- 在渲染过程中,如果遇到空节点,那么它将什么都不会做
import ReactDOM from 'react-dom/client'const root = ReactDOM.createRoot(document.getElementById('root')); // root.render(flase); // 创建空节点 // root.render(true); // 创建空节点 root.render(null) root.render(undefined) // 创建空节点
5. 数组节点(ReactArrayNode)
- 不是渲染数组本身,当React遇到数组时,会创建数组节点,但是不会直接进行渲染
- 而是将数组里的每一项按出来,根据不同节点类型去做相应的事情
- 所以,数组里的每一项只能是这里提到的五个节点类型
渲染过程
- 通过 document.createElement 创建的元素就是真实的dom
- React 的工作是通过初始元素或可以生成虚拟节点的东西生成虚拟节点然后针对不同的节点类型去做不同的事情最终生成真实dom挂载到页面上
- 渲染原理
- 初始元素和可以生成虚拟节点的东西
- 虚拟节点:根据不同的节点去做不同的事情
- 挂载到界面(UI)
首次渲染阶段
-
React 会根据初始元素先生成虚拟节点,然后做了一系列操作后最终渲染成真实的UI
-
根据不同的虚拟节点来看它到底做了些什么处理?
-
1 )初始元素-dom节点
- 对于初始元素的 type 属性为字符串时,React会通过 document.createElement 来创建真实DOM
- 因为,初始元素的 type 为字符串,所以直接会根据 type 属性创建不同的真实DOM
- 创建完真实DOM后立即设置该真实dom的所有属性,比如,直接在jsx中可以直接书写的 className, style 等都会作用到真实dom上
// jsx 语法: React初始元素 const B = <div class='wrapper' style={{color: 'red'}}><p className='text'>123</p> </div>
- 当然 html 结构肯定不止一层,所以,在设置完属性后React会根据children属性进行递归遍历
- 根据不同的 节点类型 去做不同的事情,同样的,如果 children 是初始元素,创建真实dom、设置属性
- 然后检查是否有子元素,重复次步骤,移植到最后一个元素位置,遇到其他节点类型会做以下事情
-
2 )初始元素-组件节点
- 如果初始元素的 type 属性是一个 class 类 或 function 函数时
- 那么会创建一个组件节点,所以,针对类或函数组件, 它的处理是不同的
- 函数组件
- 对于函数组件会直接调用函数,将函数的返回值进行递归处理
- 看看是什么节点类型,然后去做对应的事情,所以一定要返回能生成虚拟节点的东西
- 最终生成一棵vDOM树
- 类组件
- 对于类组件而言,会相对麻烦一些
- a. 首先创建类的实例(调用constructor)
- b. 调用生命周期方法 static getDerivedStateFromProps
- c. 调用生命周期方法 render, 根据返回值递归处理,跟函数组件处理返回值一样,最终生成一棵 vDom树
- d. 将该组件的生命周期方法 componentDidMount 加入到执行队列中等待真实dom挂载到页面后执行
- 注意
- 前面说了 render 是一个递归处理,所以如果一个组件存在 父子关系的时候
- 那么肯定要等子组件渲染完
- 父组件才能走出 render, 所以,子组件的 componentDidMount 一定是比父组件
- 先入队列的,肯定先运行
- 对于类组件而言,会相对麻烦一些
-
3 )文本节点
- 针对文本节点,会直接通过 document.createTextNode 创建真实的文本节点
-
4 )空节点
- 如果生成的是 空节点,那么它将什么都不会做
-
5 )数组节点
- 就像前面提到的一样,React不会直接渲染数组,而是将里面的每一项拿出来遍历
- 根据不同的节点类型去做不同的事,直到递归处理完数组里的每一项 (这里流一个问题,为何数组里要写 key)
-
注意,嵌套组件渲染时的大致执行顺序
- 先执行父组件的 constructor, getDerivedStateFromProps, render
- 再执行子组件的 constructor, getDerivedStateFromProps, render, componentDidMount
- 最后执行父组件的 componentDidMount
更新与卸载
- 挂载完成后组件进入活跃状态,等待数据的更新进行重新渲染
- 那么到底有几种场景会触发更新?整个过程又是怎么样的,有哪些需要注意的地方?
组件更新(setState)
- 最常见的,我们经常用 setState 来重新设置组件的状态进行重新渲染
- 使用setState只会更新调用此方法的类。不会涉及到兄弟节点以及父级节点
- 影响范围仅仅是自己的子节点,步骤如下:
- 1 ) 运行当前类组件的生命周期静态方法static getDerivedStateFromProps,根据返回值合并当前组件的状态
- 2 ) 运行当前类组件的生命周期方法shouldComponentUpdate,如果该方法返回的false,直接终止更新流程
- 3 ) 运行当前类组件的生命周期方法render,得到一个新的vDom树,进入新旧两棵树的对比更新
- 4 ) 将当前类组件的生命周期方法 getSnapshotBeforeUpdate 加入执行队列,等待将来执行
- 5 ) 将当前类组件的生命周期方法 componentDidUpdate 加入执行队列,等待将来执行
- 6 ) 重新生成vDom树
- 7 ) 执行队列,此队列存放的是更新过程涉及到原本存在的类组件的 生命周期 方法 getSnapshotBeforeUpdate
- 8 ) 根据vDom树更新真实DOM
- 9 ) 执行队列,此队列存放的是更新过程涉及到原本存在的类组件的 生命周期 方法 componentDidUpdate
- 10 ) 执行队列,此队列存放的是更新过程中所有卸载的类组件的 生命周期方法 compoentWillUnmount
根节点更新(ReactDOM.createRoot().render)
- 在ReactDOM的新版本中,已经不是直接使用 ReactDOM.render 进行更新了
- 而是通过 createRoot (要控制的DOM区域)的返回值来调用 render
import React from 'react'; import ReactDOM from 'react-dom/client'; import'./index.css'; import App from'./App';const root = ReactDOM.createRoot(document.getElementById('root'); root.render(<App/> );
对比更新过程(diff)
- 知道了两个更新的场景以及会运行哪些生命周期方法后,我们来看一下具体的过程到底是怎么样的。
- 所谓对比更新就是将新vDom树跟之前首次渲染过程中保存的老vDom树对比发现差异然后去做一系列操作的过程。
- 那么问题来了,如果我们在一个类组件中重新渲染了,React怎么知道在产生的新树中它的层级呢?
- 难道是给vDom树全部挂上一个不同的标识来遍历寻找更新的哪个组件吗?
- 当然不是,我们都知道React的diff算法将之前的复杂度0(n^3)降为了0(n)
- 它做了以下几个假设:
- 1.假设此次更新的节点层级不会发生移动(直接找到旧树中的位置进行对比)
- 2.兄弟节点之间通过key进行唯一标识
- 3.如果新旧的节点类型不相同,那么它认为就是一个新的结构
- 比如之前是初始元素div现在变成了初始元素 span那么它会认为整个结构全部变了,
- 无论嵌套了多深也会全部丢弃重新创建
key的作用
-
如果列表里面有初始元素,并且没有给初始元素添加 key那么它会警告
- Warning: Each child in a list should have a unique “key” prop. 。
-
那么 key值到底是干嘛用的呢?
- 其实key的作用非常简单,仅仅是为了通过旧节点
- 寻找对应的新节点进行对比提高节点的复用率
-
现在来举个例子,假如现在有五个兄弟节点更新后变成了四个节点
-
未添加key
- 添加了key
找到对比目标-节点类型一致
- 经过假设和一系列的操作找到了需要对比的目标
- 如果发现节点类型一致,那么它会根据不同的节点类型做不同的事情
- 初始元素-DOM节点
- 如果是DOM节点,React会直接重用之前的真实DOM
- 将这次变化的属性记录下来,等待将来完成更新
- 然后遍历其子节点进行递归对比更新
- 初始元素-组件节点
- 函数组件
- 如果是函数组件,React仅仅是重新调用函数拿到新的vDom树,然后递归进行对比更新
- 类组件
- 针对类组件,React也会重用之前的实例对象。后续步骤如下:
- 1.运行生命周期静态方法static getDerivedStateFromProps。将返回值合并当前状态
- 2.运行生命周期方法shouldComponentUpdate,如果该方法返回false,终止当前流程
- 3.运行生命周期方法render,得到新的vDom树,进行新旧两棵树的递归对比更新
- 4.将生命周期方法getSnapshotBeforeUpdate加入到队列等待执行
- 5.将生命周期方法componentDidUpdate加入到队列等待执行
3.文本节点
- 对于文本节点,同样的React也会重用之前的真实文本节点。
- 将新的文本记录下来,等待将来统一更新(设置nodeValue)
4.空节点
- 如果节点的类型都是空节点,那么React啥都不会做
5.数组节点
- 首次挂载提到的,数组节点不会直接渲染
- 在更新阶段也一样,遍历每一项,进行对比更新,然后去做不同的事
找到对比目标-节点类型不一致
- 如果找到了对比目标,但是发现节点类型不一致了,这时候类型变了,那么你的子节点肯定也都不一样了
- 就算一万个子节点,并且他们都是没有变化的,只有最外层的父节点的节点类型变了
- 照样会全部进行卸载重新创建,与其去一个个递归查看子节点,不如直接全部卸载重新创建
import'./App.css'; import React from 'react';function Count(props) {console.log('Count')return <h1>{props. count}</h1> }class App extends React. Component {constructor() {super()this.state={arr:[1,2,3]}this.update =this.update.bind(this)}update() {this.setState({arr: [1,2,3,4]})}render() {console.log('父亲render执行')return (<div><button onClick={this.update}>点我更新</button>{ this.state.arr.map((count) => <Count key={count} count={count} />) }</div>)} } export default App;
- 这个例子,初始化的时候,Count组件被初始化3次
- 而点击更新的时候,Count组件更新了4次
- 这是因为它是函数式组件,更新时,仅仅是重新调用函数,拿到新的vDOM树
- 在react内部加了key,可以复用的是底层的vDom的树,而非这个函数式组件
- 函数式组件,每次渲染,都会重新执行这个函数,这里要分清两者的区别
未找到对比目标
- 如果未找到对比的目标,跟 节点类型 不一致的做法类似,
- 那么对于多出的节点进行挂载流程,对于旧节点进行卸载直接弃用
- 如果其包含子节点进行递归卸载,对于初始类组件节点会多一个步骤,那就是运行生命周期方法componentWillUnmount。
- 注意:
- 尽量保持结构的稳定性,如果未添加key的情况下
- 兄弟节点更新位置前后错位一个那么后续全部的比较都会错位导致找不到对比目标从而进行卸载新建流程,对性能大打折扣
总结
- 对于首次挂载阶段
- 需要了解React的渲染流程
- 通过书写的初始元素和一些其他可以生成虚拟节点的东西来生成虚拟节点
- 然后针对不同的节点类型去做不同的事情,最终将真实DOM挂载到页面上
- 然后执行渲染期间加入到队列的一些生命周期,然后组件进入到活跃状态
- 对于更新卸载阶段
- 需要注意的是有几个更新的场景,以及key的作用到底是什么,有或没有会产生多大的影响
- 还有一些小细节,比如条件渲染时,不要去破坏结构,尽量使用空节点来保持前后结构顺序的统一
- 重点是新旧两棵树的对比更新流程
- 找到目标,节点类型一致时针对不同的节点类型会做哪些事,类型不一致时会去卸载整个旧节点
- 无论有多少子节点,都会全部递归进行卸载
相关文章:
React18原理: 渲染与更新时的重点关注事项
概述 react 在渲染过程中要做很多事情,所以不可能直接通过初始元素直接渲染还需要一个东西,就是虚拟节点,暂不涉及React Fiber的概念,将vDom树和Fiber 树统称为虚拟节点有了初始元素后,React 就会根据初始元素和其他可…...
嵌入式I2C 信号线为何加上拉电阻(图文并茂)
IIC 是一个两线串行通信总线,包含一个 SCL 信号和 SDA 信号,SCL 是时钟信号,从主设备发出,SDA 是数据信号,是一个双向的,设备发送数据和接收数据都是通过 SDA 信号。 在设计 IIC 信号电路的时候我们会在 SC…...
Vite 5.0 正式发布
11 月 16 日,Vite 5.0 正式发布,这是 Vite 道路上的又一个重要里程碑!Vite 现在使用 Rollup 4,这已经代表了构建性能的大幅提升。此外,还有一些新的选项可以改善开发服务器性能。 Vite 4 发布于近一年前,它…...
嵌入式STM32 单片机 GPIO 的工作原理详解
STM32的 GPIO 介绍 GPIO 是通用输入/输出端口的简称,是 STM32 可控制的引脚。GPIO 的引脚与外部硬件设备连接,可实现与外部通讯、控制外部硬件或者采集外部硬件数据的功能。 以 STM32F103ZET6 芯片为例子,该芯片共有 144 脚芯片,…...
系统调用的概念
在嵌入式开发、操作系统开发以及一般的系统编程中,系统调用是一个核心概念。它允许用户空间程序请求内核执行某些操作,如打开文件、读写数据、创建进程等。这些操作通常需要特殊的权限或访问硬件资源,因此不能直接在用户模式下执行。 系统调…...
【无标题】Matlab 之axes函数——创建笛卡尔坐标区
**基本用法:**axes 在当前图窗中创建默认的笛卡尔坐标区,并将其设置为当前坐标区。 应用场景1:在图窗中放置两个 Axes 对象,并为每个对象添加一个绘图。 要求1:指定第一个 Axes 对象的位置,使其左下角位于…...
2.12:C语言测试题
1.段错误:申请堆区内存未返回,str指向NULL 2.段错误:局部变量,本函数结束,p也释放 3.越界访问,可能正常输出hello,可能报错 4.可能段错误,释放后,str未指向NULL&#x…...
【Linux】yum软件包管理器
目录 Linux 软件包管理器 yum 什么是软件包 Linux安装软件 查看软件包 关于rzsz Linux卸载软件 查看yum源 扩展yum源下载 Linux开发工具 vim编辑器 上述vim三种模式之间的切换总结: 命令模式下,一些命令: vim配置 Linux 软件包管理…...
「优选算法刷题」:寻找旋转排序数组中的最小值
一、题目 已知一个长度为 n 的数组,预先按照升序排列,经由 1 到 n 次 旋转 后,得到输入数组。例如,原数组 nums [0,1,2,4,5,6,7] 在变化后可能得到: 若旋转 4 次,则可以得到 [4,5,6,7,0,1,2]若旋转 7 次…...
MySQL 基础入门指南:从安装到基本操作
一、简介 MySQL 是一种流行的开源关系型数据库管理系统,被广泛用于各种规模和类型的应用程序中。如果您对 MySQL 还不熟悉,本文将为您提供一个基础的入门指南,从安装到基本操作。 1.1 安装 MySQL 首先,您需要下载并安装 MySQL。…...
嵌入式Qt Qt Creator安装与工程介绍
一.Qt概述 什么是Qt:Qt是一个跨平台的C图形用户界面应用程序框架。它为应用程序开发者提供建立图形界面所需的所有功能。它是完全面向对象的,很容易扩展,并且允许真正的组件编程。 二.Qt Creator下载安装 下载地址:Index of /a…...
Windows 系统盘(C盘)爆红如何清理、如何增加C盘空间
1、简介 Windows系统中,系统和保留占用太多的空间,一旦系统盘分配空间较少,使用一段时间后,备份文件、临时文件、系统更新记录等都会在占用系统盘较大空间,导致系统盘空间不够使用,会造成应用运行卡顿。如何…...
【JavaEE Spring】Spring 原理
Spring 原理 1. Bean的作⽤域1.1 概念1.2 Bean的作⽤域 2. Bean的⽣命周期 1. Bean的作⽤域 1.1 概念 在Spring IoC&DI阶段, 我们学习了Spring是如何帮助我们管理对象的. 通过 Controller , Service , Repository , Component , Configuration ,Bean 来声明Bean对象。通…...
【Crypto | CTF】RSA打法
天命:我发现题题不一样,已知跟求知的需求都不一样 题目一:已知 p q E ,计算T,最后求D 已知两个质数p q 和 公钥E ,通过p和q计算出欧拉函数T,最后求私钥D 【密码学 | CTF】BUUCTF RSA-CSDN…...
红衣大叔讲AI:从OpenAI发布首个视频大模型Sora,谈2024年视觉大模型的十大趋势
OpenAI宣布推出全新的生成式人工智能模型“Sora”。据了解,通过文本指令,Sora可以直接输出长达60秒的视频,并且包含高度细致的背景、复杂的多角度镜头,以及富有情感的多个角色。 OpenAI发布首个视频大模型Sora,一句话生…...
java远程连接Linux执行命令的三种方式
java远程连接Linux执行命令的三种方式 1. 使用JDK自带的RunTime类和Process类实现2. ganymed-ssh2 实现3. jsch实现4. 完整代码:执行shell命令下载和上传文件 1. 使用JDK自带的RunTime类和Process类实现 public static void main(String[] args){Process proc Run…...
JavaScript- let var const区别
let 允许你声明⼀个作⽤域被限制在块级中的变量、语句或者表达式 let 绑定不受变量提升的约束,这意味着 let 声明不会被提升到当前 该变量处于从块开始到初始化处理的“暂存死区” function example() {let x 10;if (true) {let x 20;console.log(x); // Outpu…...
指针的经典笔试题
经典的指针试题,让你彻底理解指针 前言 之前对于指针做了一个详解,现在来看一些关于指针的经典面试题。 再次说一下数组名 数组名通常表示的都是首元素的地址,但是有两个意外,1.sizeof(数组名)这里数组名…...
书生浦语大模型实战营-课程笔记(1)
模型应用过程,大致还是了解的。和之前实习做CV项目的时候比起来,多了智能体这个环节。智能体是个啥? 类似上张图,智能体不太清楚。感觉是偏应用而不是模型的东西? 数据集类型很多,有文本/图片/视频。所以…...
磁盘database数据恢复: ddrescue,dd和Android 设备的数据拷贝
ddrescue和dd 区别: GNU ddrescue 不是 dd 的衍生物,也与 dd 没有任何关系 除了两者都可用于将数据从一台设备复制到另一台设备。 关键的区别在于 ddrescue 使用复杂的算法来复制 来自故障驱动器的数据,尽可能少地造成额外的损坏。ddrescue…...
SpringMVC-入门
1.概念 SpringMVC是一种软件架构思想,把软件按照模型(Model)、视图(View)、控制器(Controller)这三层来划分。Model:指的是工程中JavaBean,用来处理数据View:指的是工程中的html、jsp等页面,用来展示给用户数据Control…...
需要学习的知识点清单
div 4 div 3 F :拓扑排序 G : 组合数学 D : 结构体排序 div 2 div 12...
杂谈--spconv导出中onnx的扩展阅读
Onnx 使用 Onnx 介绍 Onnx (Open Neural Network Exchange) 的本质是一种 Protobuf 格式文件,通常看到的 .onnx 文件其实就是通过 Protobuf 序列化储存的文件。onnx-ml.proto 通过 protoc (Protobuf 提供的编译程序) 编译得到 onnx-ml.pb.h 和 onnx-ml.pb.cc 或 on…...
嵌入式培训机构四个月实训课程笔记(完整版)-Linux ARM驱动编程第二天-arm ads下的start.S分析(物联技术666)
链接:https://pan.baidu.com/s/1E4x2TX_9SYhxM9sWfnehMg?pwd1688 提取码:1688 ; ; NAME: 2440INIT.S ; DESC: C start up codes ; Configure memory, ISR ,stacks ; Initialize C-variables ; 完全注释 ; HISTORY: ; 2002.02.25:kwtark: ver 0.…...
STL之list容器的介绍与模拟实现+适配器
STL之list容器的介绍与模拟实现适配器 1. list的介绍2. list容器的使用2.1 list的定义2.2 list iterator的使用2.3 list capacity2.4 list element access2.5 list modifiers2.6 list的迭代器失效 3. list的模拟实现3.1 架构搭建3.2 迭代器3.2.1 正向迭代器3.2.2反向迭代器适配…...
Leetcode With Golang 二叉树 part1
这一部分主要来梳理二叉树题目最简单最基础的部分,包括遍历,一些简单题目。 一、Leecode 144 - 二叉树的前序遍历 https://leetcode.cn/problems/binary-tree-preorder-traversal/description/ 二叉树的遍历是入门。我们需要在程序一开始就创建一个空…...
tcp 中使用的定时器
定时器的使用场景主要有两种。 (1)周期性任务 这是定时器最常用的一种场景,比如 tcp 中的 keepalive 定时器,起到 tcp 连接的两端保活的作用,周期性发送数据包,如果对端回复报文,说明对端还活着…...
黑马Java——IO流
一、IO流的概述 IO流:存储和读取数据的解决方案 IO流和File是息息相关的 1、IO流的分类 1.1、纯文本文件 word、Excel不是纯文本文件 而txt或者md文件是纯文本文件 2、小结 二、IO流的体系结构 三、字节流 1、FileOutputStream(字节输出流ÿ…...
re:从0开始的CSS学习之路 11. 盒子垂直布局
1. 盒子的垂直布局的注意 若两个“相邻”垂直摆放的盒子,上面盒子的下外边距与下面盒子的上外边距会发生重叠,称为外边距合并 若合并后,外边距会选择重叠外边距的较大值 若两个盒子具有父子关系,则两个盒子的上外边距会发生重叠&…...
Kindling-OriginX 如何集成 DeepFlow 的数据增强网络故障的解释力
DeepFlow 是基于 eBPF 的可观测性开源项目,旨在为复杂的云基础设施及云原生应用提供深度可观测性。DeepFlow 基于 eBPF 采集了精细的链路追踪数据和网络、应用性能指标,其在网络路径上的全链路覆盖能力和丰富的 TCP 性能指标能够为专业用户和网络领域专家…...
轻松掌握Jenkins执行远程window的Jmeter接口脚本
Windows环境:10.1.2.78 新建与配置节点 【系统管理】—【管理节点】—【新建节点】输入节点名称,勾选“dumb slave”,点击ok 按如上配置: 说明: Name:定义slave的唯一名称标识,可以是任意字…...
UI文件原理
使用UI文件创建界面很轻松很便捷,他的原理就是每次我们保存UI文件的时候,QtCreator就自动帮我们将UI文件翻译成C的图形界面创建代码。可以通过以下步骤查看代码 到工程编译目录,一般就是工程同级目录下会生成另一个编译目录,会找到…...
OS设备管理
设备管理 操作系统作为系统资源的管理者,其提供的功能有:处理机管理、存储器管理、文件管理、设备管理。其中前三个管理都是在计算机的主机内部管理其相对应的硬件。 I/O设备 I/O即输入/输出。I/O设备即可以将数据输入到计算机,或者可以接收…...
Matlab绘图经典代码大全:条形图、极坐标图、玫瑰图、填充图、饼状图、三维网格云图、等高线图、透视图、消隐图、投影图、三维曲线图、函数图、彗星图
学会 MATLAB 中的绘图命令对初学者来说具有重要意义,主要体现在以下几个方面: 1. 数据可视化。绘图命令是 MATLAB 中最基本也是最重要的功能之一,它可以帮助初学者将数据可视化,更直观地理解数据的分布、变化规律和趋势。通过绘制图表,可以快速了解数据的特征,从而为后续…...
姿态传感器MPU6050模块之陀螺仪、加速度计、磁力计
MEMS技术 微机电系统(MEMS, Micro-Electro-Mechanical System),也叫做微电子机械系统、微系统、微机械等,指尺寸在几毫米乃至更小的高科技装置。微机电系统其内部结构一般在微米甚至纳米量级,是一个独立的智能系统。 微…...
MySQL 基础知识(一)之数据库和 SQL 概述
目录 1 数据库相关概念 2 数据库的结构 3 SQL 概要 4 SQL 的基本书写规则 1 数据库相关概念 数据库是将大量的数据保存起来,通过计算机加工而成的可以进行高效访问的数据集合数据库管理系统(DBMS)是用来管理数据库的计算机系统…...
挑战杯 wifi指纹室内定位系统
简介 今天来介绍一下室内定位相关的原理以及实现方法; WIFI全称WirelessFidelity,在中文里又称作“行动热点”,是Wi-Fi联盟制造商的商标做为产品的品牌认证,是一个创建于IEEE 802.11标准的无线局域网技术。基于两套系统的密切相关ÿ…...
Midjourney提示词风格调试测评
在Midjourney中提示词及风格参数的变化无疑会对最终的作品产生影响,那影响具体有多大?今天我我们将通过一个示例进行探究。 示例提示词: 计算机代码海洋中的黄色折纸船(图像下方)风格参考:金色长发的女人,…...
Codeforces Round 926 (Div. 2)(A~C)
A. Sasha and the Beautiful Array 分析:说实话,打比赛的时候看到这题没多想,过了一下样例发现将数组排序一下就行,交了就过了。刚刚写题解反应过来,a2-a1a3-a2.....an-a(n-1) an - a1,所以最后结果只取决…...
Godot 游戏引擎个人评价和2024年规划(无代码)
文章目录 前言Godot C# .net core 开发简单评价Godot相关网址可行性 Godot(GDScirpt) Vs CocosGodot VS UnityUnity 的裁员Unity的股票Unity的历史遗留问题:Mono和.net core.net core的开发者,微软 个人的独立游戏Steam平台分成说明独立游戏的选题美术风…...
Win11关闭Windows Defender实时保护,暂时关闭和永久关闭方法 | Win10怎么永久关闭Windows Defender实时保护
文章目录 1. 按2. 暂时关闭Windows Defender实时保护3. 永久关闭实时保护 1. 按 开启Windows Defender实时保护有时候会导致系统变得异常卡顿,严重影响系统的流畅度,并且由于会有几率错误拦截和查杀我们的正常操作,所以还会导致我们的程序无…...
C# CAD2016 宗地生成界址点,界址点编号及排序
1 、界址点起点位置C# CAD2016 多边形顶点按方向重新排序 2、 界址点顺时针逆时针走向 C# CAD2016 判断多边形的方向正时针或逆时针旋转 3、块文件插入 //已知块文件名称 GXGLQTC //块文件需要插入的坐标点 scaledPoint// 插入块到当前图纸中的指定位置ObjectId newBlockId;B…...
[ai笔记7] google浏览器ai学习提效定制优化+常用插件推荐
欢迎来到文思源想的ai空间,这是技术老兵重学ai以及成长思考的第7篇分享! 工欲善其事必先利其器,为了ai学习的效能提升,放假期间对google浏览器做了一次系统整改,添加了一些配置和插件,这里既有一些显示、主…...
联想thinkpad-E450双系统升级记
早期笔记本联想thinkpad-E450双系统 大约16年花4000多大洋,买了一台thinkpad-E450屏幕是16寸本,有AMD独立显卡,i5cpu,4G内存。 . 后来加了一个同型号4G内存组成双通道, . 加了一个三星固态500G, . 换了一个…...
Mysql运维篇(四) Xtarbackup--备份与恢复练习
一路走来,所有遇到的人,帮助过我的、伤害过我的都是朋友,没有一个是敌人。如有侵权,请留言,我及时删除! 前言 xtrabackup是Percona公司CTO Vadim参与开发的一款基于InnoDB的在线热备工具,具有…...
vue3 封装一个通用echarts组件
实现这个组件需要引入echarts和vue-echarts插件,使用vue-echarts是因为它帮我们封装了一些很常用的功能,比如监听页面resize后重新渲染功能,本次组件只使用到了autoresize配置,其它可以根据官方文档按需选配 https://github.com/…...
安装 Windows Server 2003
1.镜像安装 镜像安装:Windows Server 2003 2.安装过程(直接以图的形式呈现) 按Enter(继续),继续后F8继续 直接Enter安装 下一步 秘钥:GM34K-RCRKY-CRY4R-TMCMW-DMDHM 等待安装成功即可...
在STM32中使用DMA进行SD卡读写操作的实现方法
在STM32中,使用DMA进行SD卡的读写操作可以提高数据传输的速度和效率。下面是在STM32中使用DMA进行SD卡读写操作的实现方法: ✅作者简介:热爱科研的嵌入式开发者,修心和技术同步精进 ❤欢迎关注我的知乎:对error视而不见…...
StringBuilder/StringBuffer类(Java)
StringBuilder/StringBuffer类 当对字符串进行修改的时候,使用 StringBuffer / StringBuilder 类更方便。和 String 类不同的是,StringBuffer 和 StringBuilder 类的对象能够被多次的修改,并且不产生新的未使用对象。方法类似 public class…...
SQL的1999语法
目录 交叉连接 实现交叉连接 自然连接 实现自然连接(实际上就是内连接) ON和USING 使用自然连接时要求两张表的字段名称相同,但是如果不相同或者两张表中有两组字段是重名,这时就要利用 ON 子句指定关联条件,利用 USING 子句…...