当前位置: 首页 > news >正文

【从0实现React18】 (五) 初探react mount流程 完成核心递归流程

更新流程的目的:

  • 生成wip fiberNode树
  • 标记副作用flags

更新流程的步骤:

  • 递:beginWork
  • 归:completeWork

在 上一节 ,我们探讨了 React 应用在首次渲染或后续更新时的整体更新流程。在 Reconciler 工作流程中,beginWorkcompleteWork 两个方法起到了关键作用。beginWork 负责构建表示更新的 Fiber 树,而 completeWork 则将这个 Fiber 树映射到实际的 DOM 结构上。接下来,我们将深入实现这两个方法。

  1. 开发环境打印日志

首先,在开发环境下增加 DEV 标识,以便在开发环境中方便地打印日志:

pnpm i -D -w @rollup/plugin-replace

安装完成后,在 scripts/rollup/utils.js 中引入:

 // scripts/rollup/utils.js  // ...  import replace from  '@rollup/plugin-replace' ;  // ...   export  function  getBaseRollupPlugins ( { alias = { __DEV__: true }, typescript = {} } = {} ) {  return [ replace (alias), cjs (), ts (typescript)]; } 

这样我们就可以在开发环境中打印日志了。

  1. 实现 beginWork

对于如下结构的reactElement:

<A><B/>
<A/>

当进入A的beginWork时,通过对比B的current fiberNode 与B的reactElement,生成对应wip fiberNode


beginWork 函数在向下遍历阶段执行,根据 Fiber 节点的类型(HostRootHostComponentHostText)分发任务给不同的处理函数,处理具体节点类型的更新逻辑:

export const beginWork = (wip: FiberNode) => {switch (wip.tag) {case HostRoot:return updateHostRoot(wip)case HostComponent:return updateHostComponent(wip)case HostText:return nulldefault:if (__DEV__) {console.warn('beginWork为实现的类型', wip)}break}
}
  1. HostRoot

    /** 处理根节点的更新,包括协调处理根节点的属性 以及子节点的更新逻辑 */
    function updateHostRoot(wip: FiberNode) {const baseState = wip.memoizedStateconst updateQueue = wip.updateQueue as UpdateQueue<Element>const pending = updateQueue.shared.pendingupdateQueue.shared.pending = null // 清空更新链表// 1.计算状态的最新值const { memoizedState } = processUpdateQueue(baseState, pending) // 计算待更新状态的最新值wip.memoizedState = memoizedState // 更新协调后的状态最新值// 2. 创造子fiberNodeconst nextChildren = wip.memoizedState // 获取 children 属性reconcileChildren(wip, nextChildren) // 处理根节点的子节点,可能会递归调用其他协调函数;// 返回经过协调后的新的子节点链表return wip.child
    }
    
    • 表示根节点,即应用的最顶层节点;
    • 调用 updateHostRoot 函数,处理根节点的更新,包括协调处理根节点的属性以及子节点的更新逻辑;
    • 调用 reconcileChildren 函数,处理根节点的子节点,可能会递归调用其他协调函数;
    • 返回 workInProgress.child 表示经过协调后的新的子节点链表;
  1. HostComponent

    function updateHostComponent(wip: FiberNode) {const nextProps = wip.pendingProps//  创造子fiberNodeconst nextChildren = nextProps.children // 获取Dom的children属性reconcileChildren(wip, nextChildren) // 处理原生 DOM 元素的子节点更新,可能会递归调用其他协调函数;return wip.child
    }
    
    • 表示原生 DOM 元素节点,例如 <div><span> 等;
    • 调用 updateHostComponent 函数,处理原生 DOM 元素节点的更新,负责协调处理属性和子节点的更新逻辑;
    • 调用 reconcileChildren 函数,处理原生 DOM 元素的子节点更新;
    • 返回 workInProgress.child 表示经过协调后的新的子节点链表;
  1. HostText

    • 表示文本节点,即 DOM 中的文本内容,例如 <p>123</p> 中的 123
    • 调用 updateHostText 函数,协调处理文本节点的内容更新;
    • 返回 null 表示已经是叶子节点,没有子节点了;

其中 reconcileChildren 函数的作用是,通过对比子节点的 current FiberNode 与 子节点的 ReactElement,来生成子节点对应的 workInProgress FiberNode。(current 是与视图中真实 UI 对应的 Fiber 树,workInProgress 是触发更新后正在 Reconciler 中计算的 Fiber 树。)

function reconcileChildren(wip: FiberNode, children?: ReactElementType) {const current = wip.alternateif (current !== null) {// updatewip.child = reconcileChildFibers(wip, current?.child, children)} else {// mountwip.child = mountChildFibers(wip, null, children)}
}

reconcileChildren 函数中调用了 reconcileChildFibersmountChildFibers 两个函数,它们分别负责处理更新阶段和首次渲染阶段的子节点协调。

reconcileChildFibers:

  • reconcileChildFibers 函数作用于组件的更新阶段,即当组件已经存在于 DOM 中,需要进行更新时。
  • 主要任务是协调处理当前组件实例的子节点,对比之前的子节点(current)和新的子节点(workInProgress)之间的变化。
  • 根据子节点的类型和 key 进行对比,决定是复用、更新、插入还是删除子节点,最终形成新的子节点链表。

mountChildFibers:

  • mountChildFibers 函数作用于组件的首次渲染阶段,即当组件第一次被渲染到 DOM 中时。
  • 主要任务是协调处理首次渲染时组件实例的子节点。
  • 但此时是首次渲染,没有之前的子节点,所以主要是创建新的子节点链表。
 // packages/react-reconciler/src/childFiber.ts
/** 实现生成子节点fiber 以及标记Flags的过程 */import { ReactElementType } from 'shared/ReactTypes'
import { FiberNode, createFiberFromElement } from './fiber'
import { REACT_ELEMENT_TYPE } from 'shared/ReactSymbols'
import { HostText } from './workTags'
import { Placement } from './fiberFlags'function ChildrenReconciler(shouldTrackEffects: boolean) {/** 处理单个 Element 节点的情况对比 currentFiber 与 ReactElement生成 workInProgress FiberNode */function reconcileSingleElement(returnFiber: FiberNode,currentFiber: FiberNode | null,element: ReactElementType) {// 根据element创建fiberconst fiber = createFiberFromElement(element)fiber.return = returnFiberreturn fiber}/** 处理文本节点的情况对比 currentFiber 与 ReactElement生成 workInProgress FiberNode */function reconcileSingleTextNode(returnFiber: FiberNode,currentFiber: FiberNode | null,content: string | number) {const fiber = new FiberNode(HostText, { content }, null)fiber.return = returnFiberreturn fiber}/** 为 Fiber 节点添加更新 flags */function placeSingleChild(fiber: FiberNode) {// 优化策略,首屏渲染且追踪副作用时,才添加更新 flagsif (shouldTrackEffects && fiber.alternate === null) {fiber.flags |= Placement}return fiber}// 闭包,根据 shouldTrackSideEffects 返回不同 reconcileChildFibers 的实现return function reconcileChildFibers(returnFiber: FiberNode,currentFiber: FiberNode | null,newChild?: ReactElementType) {// 判断当前fiber的类型// 1. 单个 Element 节点if (typeof newChild === 'object' && newChild !== null) {switch (newChild.$$typeof) {case REACT_ELEMENT_TYPE:return placeSingleChild(reconcileSingleElement(returnFiber, currentFiber, newChild))default:if (__DEV__) {console.warn('未实现的reconcile类型', newChild)}break}}// TODO 2. 多个 Element 节点 ul > li*3// 3. HostText 节点if (typeof newChild === 'string' || typeof newChild === 'number') {return placeSingleChild(reconcileSingleTextNode(returnFiber, currentFiber, newChild))}// 4. 其他if (__DEV__) {console.warn('未实现的reconcile类型', newChild)}return null}
}/** 处理更新阶段的子节点协调,组件的更新阶段中,追踪副作用*/
export const reconcileChildFibers = ChildrenReconciler(true)
/** 处理首次渲染阶段的子节点协调,首屏渲染阶段中不追踪副作用,只对根节点执行一次 DOM 插入操作*/
export const mountChildFibers = ChildrenReconciler(false)
// packages/react-reconciler/src/fiber.ts
// .../** 根据element创建fiber并返回 */
export function createFiberFromElement(element: ReactElementType) {const { type, key, props } = elementlet fiberTag: WorkTag = FunctionComponentif (typeof type === 'string') {// <div/>  type: 'div'fiberTag = HostComponent} else if (typeof type !== 'function' && __DEV__) {console.warn('未定义的type类型', element)}// 创建 fiber 节点const fiber = new FiberNode(fiberTag, props, key)fiber.type = typereturn fiber
}

beginWork性能优化策略

考虑如下结构的reacetElement:

<div><p>练习时长</p><span>两年半</span>
</div>

理论上mount流程完毕后包含的flags:

  • 两年半 Placement
  • Span Placement
  • 练习时长 Placement
  • P Placement
  • Div Placement

相比执行5次Placement,我们可以构建好离屏DOM后,对div执行1次Placement操作

  1. 实现 completeWork

需要解决的问题:

  • 对于 Host 类型 fiberNode: 构建离屏Dom树
  • 标记 Update flag (TODO)

completeWork 函数在向上遍历阶段执行,根据 Fiber 节点的类型(HostRootHostComponentHostText 等)构建 DOM 节点,收集更新 flags,并根据更新 flags 执行不同的 DOM 操作:

  • HostComponent:

    • 表示原生 DOM 元素节点;
    • 构建 DOM 节点,并调用 appendAllChildren 函数将 DOM 插入到 DOM 树中;
    • 收集更新 flags,并根据更新 flags 执行不同的 DOM 操作,例如插入新节点、更新节点属性、删除节点等;
  • HostText:

    • 表示文本节点;
    • 构建 DOM 节点,并将 DOM 插入到 DOM 树中;
    • 收集更新 flags,根据 flags 的值,更新文本节点的内容;
  • HostRoot:

    • 表示根节点;
    • 会执行一些与根节点相关的最终操作,例如处理根节点的属性,确保整个应用更新完毕;
export const completeWork = (wip: FiberNode) => {const newProps = wip.pendingPropsconst current = wip.alternateswitch (wip.tag) {case HostComponent:if (current !== null && wip.stateNode) {//update} else {// mount  构建离屏的 Dom 树// 1. 构建 Domconst instance = createInstance(wip.type, newProps)// 2. 将Dom插入到Dom树中appendAllChildren(instance, wip)wip.stateNode = instance}bubbleProperties(wip)return nullcase HostText:if (current !== null && wip.stateNode) {//update} else {// mount// 1. 构建 Domconst instance = createTextInstance(newProps.content)wip.stateNode = instance}bubbleProperties(wip)return nullcase HostRoot:bubbleProperties(wip)return nulldefault:if (__DEV__) {console.warn('completeWork未实现的类型', wip)}break}
}

其中,appendAllChildren 函数负责递归地将组件的子节点添加到指定的 parent 中,它通过深度优先遍历 workInProgress 的子节点链表,处理每个子节点的类型。先处理当前节点的所有子节点,再处理兄弟节点。

如果它是原生 DOM 元素节点或文本节点,则将其添加到父节点中;如果是其他类型的组件节点并且有子节点,则递归处理其子节点。

 // packages/react-reconciler/src/completeWork.ts
// ...
function appendAllChildren(parent: FiberNode, wip: FiberNode) {let node = wip.child// 递归插入while (node !== null) {if (node?.tag === HostComponent || node?.tag === HostText) {appendInitialChild(parent, node?.stateNode)} else if (node.child !== null) {node.child.return = nodenode = node.childcontinue}// 终止条件if (node === wip) {return}// 子节点结束,开始处理兄弟节点while (node.sibling === null) {// 1.当前节点无兄弟节点if (node.return === null || node.return === wip) {return}node = node?.return}// 2.当前节点有兄弟节点node.sibling.return = node.returnnode = node.sibling}
}

completeWork 性能优化策略

flags分布在不同fiberNode中,如何快速他们?

  • 利用completeWork向上遍历(归)的流程,将子fiberNode的flags冒泡到父fiberNode

创建 bubbleProperties 函,负责在 completeWork 函数向上遍历的过程中,通过向上冒泡子节点的 flags,将所有更新 flags 收集到根节点。主要包含以下步骤:

  • 从当前需要冒泡属性的 Fiber 节点开始,检查是否有需要冒泡的属性。
  • 如果当前节点有需要冒泡的属性,将这些属性冒泡到父节点的 subtreeFlags 或其他适当的属性中。
  • 递归调用 bubbleProperties 函数,处理父节点,将属性继续冒泡到更上层的祖先节点,直至达到根节点。
 // packages/react-reconciler/src/completeWork.ts
// .../** 收集更新 flags,将子 FiberNode 的 flags 冒泡到父 FiberNode 上 */
function bubbleProperties(wip: FiberNode) {let subtreeFlags = NoFlagslet child = wip.childwhile (child !== null) {subtreeFlags |= child.subtreeFlagssubtreeFlags |= child.flagschild.return = wipchild = child.sibling}wip.subtreeFlags |= subtreeFlags
}
  1. 位运算简介

flags 是 React 中很重要的一环,具体作用是通过二进制在每个 Fiber 节点保存其本身与子节点的 flags。在保存与处理 flags 时,使用了一些二进制运算符,我们来复习一下:

1. | 运算

| 运算的两个位都为 0 时,结果才为 0:

  • 1 | 1 = 1
  • 1 | 0 = 1
  • 0 | 0 = 0

React 利用了 | 运算符的特性来存储 flags,如:

const NoFlags = /*            */ 0b0000000;
const PerformedWork = /*      */ 0b0000001;
const Placement = /*          */ 0b0000010;
const Update = /*             */ 0b0000100;
const ChildDeletion = /*      */ 0b0001000;const flags = Placement | Update; //此时 flags = 0b0000110

2. & 运算

& 运算的两个位都为 1 时,结果才为 1:

  • 1 & 1 = 1
  • 1 & 0 = 0
  • 0 & 0 = 0

React 中会用一个 flags & 某一个 flag,来判断 flags 中是否包含某一个 flag,如:

const flags = Placement | Update; //此时 flags = 0b0000110Boolean(flags & Placement); // true, 说明 flags 中包含 Placement
Boolean(flags & ChildDeletion); // false, 说明 flags 中不包含 ChildDeletion

3. ~ 运算

运算符会把每一位取反,0 变 1,1 变 0:

  • ~1 = 0
  • ~0 = 1

在 React 中,~ 运算符同样是常用操作,如:

let flags = Placement | Update; //此时 flags = 0b0000110flags &= ~Placement; //此时 flags = 0b0000100

通过 ~ 运算符与 & 运算符的结合,从 flags 中删除了 Placement 这个 flag。


至此,我们就实现了 React 协调阶段中的 beginWorkcompleteWork 函数,生成了一棵表示更新的 Fiber 树,并收集了树中节点的更新 flags,下一节我们将根据这些 flags 执行对应的 DOM 操作。

借鉴链接: https://juejin.cn/post/7347911786802511924

相关文章:

【从0实现React18】 (五) 初探react mount流程 完成核心递归流程

更新流程的目的&#xff1a; 生成wip fiberNode树标记副作用flags 更新流程的步骤&#xff1a; 递&#xff1a;beginWork归&#xff1a;completeWork 在 上一节 &#xff0c;我们探讨了 React 应用在首次渲染或后续更新时的整体更新流程。在 Reconciler 工作流程中&#xff…...

0-30 VDC 稳压电源,电流控制 0.002-3 A

怎么运行的 首先&#xff0c;有一个次级绕组额定值为 24 V/3 A 的降压电源变压器&#xff0c;连接在电路输入点的引脚 1 和 2 上。&#xff08;电源输出的质量将直接影响与变压器的质量成正比&#xff09;。变压器次级绕组的交流电压经四个二极管D1-D4组成的电桥整流。桥输出端…...

HTML5+CSS3+JS小实例:图片九宫格

实例:图片九宫格 技术栈:HTML+CSS+JS 效果: 源码: 【HTML】 <!DOCTYPE html> <html lang="zh-CN"> <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1…...

湘潭大学软件工程数据库总结

文章目录 前言试卷结构给学弟学妹的一些参考自己的一些总结 前言 自己可能很早很早之前就准备复习了&#xff0c;但是感觉还是没有学到要点&#xff0c;主要还是没啥紧迫的压力&#xff0c;我们是三月份开学&#xff0c;那时候实验室有朋友挺认真开始学习数据库了&#xff0c;…...

Codeforces Testing Round 1 B. Right Triangles 题解 组合数学

Right Triangles 题目描述 You are given a n m nm nm field consisting only of periods (‘.’) and asterisks (‘*’). Your task is to count all right triangles with two sides parallel to the square sides, whose vertices are in the centers of ‘*’-cells. …...

怎样将word默认Microsoft Office,而不是WPS

设置——>应用——>默认应用——>选择"word"——>将doc和docx都选择Microsoft Word即可...

C语言之进程的学习2

Env环境变量&#xff08;操作系统的全局变量&#xff09;...

web使用cordova打包Andriod

一.安装Gradel 1.下载地址 Gradle Distributions 2.配置环境 3.测试是否安装成功 在cmd gradle -v 二.创建vite项目 npm init vitelatest npm install vite build 三.创建cordova项目 1.全局安装cordova npm install -g cordova 2. 创建项目 cordova create cordova-app c…...

内卷情况下,工程师也应该了解的项目管理

简介&#xff1a;大家好&#xff0c;我是程序员枫哥&#xff0c;&#x1f31f;一线互联网的IT民工、&#x1f4dd;资深面试官、&#x1f339;Java跳槽网创始人。拥有多年一线研发经验&#xff0c;曾就职过科大讯飞、美团网、平安等公司。在上海有自己小伙伴组建的副业团队&…...

【解锁未来:深入了解机器学习的核心技术与实际应用】

解锁未来&#xff1a;深入了解机器学习的核心技术与实际应用 &#x1f48e;1.引言&#x1f48e;1.1 什么是机器学习&#xff1f; &#x1f48e;2 机器学习的分类&#x1f48e;3 常用的机器学习算法&#x1f48e;3.1 线性回归&#xff08;Linear Regression&#xff09;&#x1…...

1-3.文本数据建模流程范例

文章最前&#xff1a; 我是Octopus&#xff0c;这个名字来源于我的中文名–章鱼&#xff1b;我热爱编程、热爱算法、热爱开源。所有源码在我的个人github &#xff1b;这博客是记录我学习的点点滴滴&#xff0c;如果您对 Python、Java、AI、算法有兴趣&#xff0c;可以关注我的…...

【FFmpeg】avformat_alloc_output_context2函数

【FFmpeg】avformat_alloc_output_context2函数 1.avformat_alloc_output_context21.1 初始化AVFormatContext&#xff08;avformat_alloc_context&#xff09;1.2 格式猜测&#xff08;av_guess_format&#xff09;1.2.1 遍历可用的fmt&#xff08;av_muxer_iterate&#xff0…...

Flask 缓存和信号

Flask-Caching Flask-Caching 是 Flask 的一个扩展&#xff0c;它为 Flask 应用提供了缓存支持。缓存是一种优化技术&#xff0c;可以存储那些费时且不经常改变的运算结果&#xff0c;从而加快应用的响应速度。 一、初始化配置 安装 Flask-Caching 扩展&#xff1a; pip3 i…...

基于weixin小程序农场驿站系统的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;农场资讯管理&#xff0c;用户管理&#xff0c;卖家管理&#xff0c;用户分享管理&#xff0c;分享类型管理&#xff0c;商品信息管理&#xff0c;商品类型管理 开发系统&#xff1a;Windows 架构模式…...

JAVA将List转成Tree树形结构数据和深度优先遍历

引言&#xff1a; 在日常开发中&#xff0c;我们经常会遇到需要将数据库中返回的数据转成树形结构的数据返回&#xff0c;或者需要对转为树结构后的数据绑定层级关系再返回&#xff0c;比如需要统计当前节点下有多少个节点等&#xff0c;因此我们需要封装一个ListToTree的工具类…...

设计模式——开闭、单一职责及里氏替换原则

设计原则是指导软件设计和开发的一系列原则&#xff0c;它们帮助开发者创建出易于维护、扩展和理解的代码。以下是你提到的几个关键设计原则的简要说明&#xff1a; 开闭原则&#xff08;Open/Closed Principle, OCP&#xff09;&#xff1a; 开闭原则由Bertrand Meyer提出&am…...

代码随想录算法训练营第59天:动态[1]

代码随想录算法训练营第59天&#xff1a;动态 两个字符串的删除操作 力扣题目链接(opens new window) 给定两个单词 word1 和 word2&#xff0c;找到使得 word1 和 word2 相同所需的最小步数&#xff0c;每步可以删除任意一个字符串中的一个字符。 示例&#xff1a; 输入: …...

jvm性能监控常用工具

在java的/bin目录下有许多java自带的工具。 我们常用的有 基础工具 jar:创建和管理jar文件 java&#xff1a;java运行工具&#xff0c;用于运行class文件或jar文件 javac&#xff1a;java的编译器 javadoc&#xff1a;java的API文档生成工具 性能监控和故障处理 jps jstat…...

ISP IC/FPGA设计-第一部分-SC130GS摄像头分析-IIC通信(1)

1.摄像头模组 SC130GS通过一个引脚&#xff08;SPI_I2C_MODE&#xff09;选择使用IIC或SPI配置接口&#xff0c;通过查看摄像头模组的原理图&#xff0c;可知是使用IIC接口&#xff1b; 通过手册可知IIC设备地址通过一个引脚控制&#xff0c;查看摄像头模组的原理图&#xff…...

HTTP协议头中X-Forwarded-For是能做什么?

X-Forwarded-For和相关几个头部的理解 $remote_addr 是nginx与客户端进行TCP连接过程中&#xff0c;获得的客户端真实地址. Remote Address 无法伪造&#xff0c;因为建立 TCP 连接需要三次握手&#xff0c;如果伪造了源 IP&#xff0c;无法建立 TCP 连接&#xff0c;更不会有后…...

Linux高并发服务器开发(八)Socket和TCP

文章目录 1 IPV4套接字结构体2 TCP客户端函数 3 TCP服务器流程函数代码粘包 4 三次握手5 四次挥手6 滑动窗口 1 IPV4套接字结构体 2 TCP客户端 特点&#xff1a;出错重传 每次发送数据对方都会回ACK&#xff0c;可靠 tcp是打电话的模型&#xff0c;建立连接 使用连接 关闭连接…...

力扣第220题“存在重复元素 III”

在本篇文章中&#xff0c;我们将详细解读力扣第220题“存在重复元素 III”。通过学习本篇文章&#xff0c;读者将掌握如何使用桶排序和滑动窗口来解决这一问题&#xff0c;并了解相关的复杂度分析和模拟面试问答。每种方法都将配以详细的解释&#xff0c;以便于理解。 问题描述…...

Qt实战项目——贪吃蛇

一、项目介绍 本项目是一个使用Qt框架开发的经典贪吃蛇游戏&#xff0c;旨在通过简单易懂的游戏机制和精美的用户界面&#xff0c;为玩家提供娱乐和编程学习的机会。 游戏展示 二、主要功能 2.1 游戏界面 游戏主要是由三个界面构成&#xff0c;分别是游戏大厅、难度选择和游戏…...

Windows 10,11 Server 2022 Install Docker-Desktop

docker 前言 Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的 Linux或Windows 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。 docker-compose Compose 是用于定义和运行…...

C++中的RAII(资源获取即初始化)原则

C中的RAII&#xff08;Resource Acquisition Is Initialization&#xff0c;资源获取即初始化&#xff09;原则是一种管理资源、避免资源泄漏的惯用法。RAII是C之父Bjarne Stroustrup提出的设计理念&#xff0c;其核心思想是将资源的获取&#xff08;如动态内存分配、文件句柄、…...

【机器学习】Whisper:开源语音转文本(speech-to-text)大模型实战

目录 一、引言 二、Whisper 模型原理 2.1 模型架构 2.2 语音处理 2.3 文本处理 三、Whisper 模型实战 3.1 环境安装 3.2 模型下载 3.3 模型推理 3.4 完整代码 3.5 模型部署 四、总结 一、引言 上一篇对​​​​​​​ChatTTS文本转语音模型原理和实战进行了讲解&a…...

ubuntu22.04 编译安装openssl C++ library

#--------------------------------------------------------------------------- # openssl C library # https://www.openssl.org/source/index.html #--------------------------------------------------------------------------- cd /opt/download # 下载openssl-3.0.13…...

百度Agent初体验(制作步骤+感想)

现在AI Agent很火&#xff0c;最近注册了一个百度Agent体验了一下&#xff0c;并做了个小实验&#xff0c;拿它和零一万物&#xff08;Yi Large&#xff09;和文心一言&#xff08;ERNIE-4.0-8K-latest&#xff09;阅读了相同的一篇网页资讯&#xff0c;输出资讯摘要&#xff0…...

7-491 3名同学5门课程成绩,输出最好成绩及所在的行和列(二维数组作为函数的参数)

编程:数组存储3名同学5门课程成绩 输出最好成绩及所在的行和列 要求&#xff1a;将输入、查找和打印的功能编写成函数 并将二维数组通过指针参数传递的方式由主函数传递到子函数中 输入格式: 每行输入一个同学的5门课的成绩&#xff0c;每个成绩之间空一格&#xff0c;见输入…...

OpenCloudOS开源的操作系统

OpenCloudOS 是一款开源的操作系统&#xff0c;致力于提供高性能、稳定和安全的操作系统环境&#xff0c;以满足现代计算和应用程序的需求。它结合了现代操作系统设计的最新技术和实践&#xff0c;为开发者和企业提供了一个强大的平台。本文将详细介绍 OpenCloudOS 的背景、特性…...

排序题目:多数元素 II

文章目录 题目标题和出处难度题目描述要求示例数据范围进阶 前言解法一思路和算法代码复杂度分析 解法二思路和算法代码复杂度分析 解法三思路和算法代码复杂度分析 题目 标题和出处 标题&#xff1a;多数元素 II 出处&#xff1a;229. 多数元素 II 难度 3 级 题目描述 …...

<电力行业> - 《第1课:电力行业的五大四小》

1 什么是电力行业的五大四小&#xff1f; 我们常说的电力行业的五大四小&#xff0c;指的是电力行业有实力的公司&#xff0c;分为&#xff1a;较强梯队的五大集团、较弱梯队的四小豪门。 五个实力雄厚的集团&#xff0c;分别是&#xff1a; 中国华能集团公司中国大唐集团公…...

数据库定义语言(DDL)

数据库定义语言&#xff08;DDL&#xff09; 一、数据库操作 1、 查询所有的数据库 SHOW DATABASES;效果截图&#xff1a; 2、使用指定的数据库 use 2403 2403javaee;效果截图&#xff1a; 3、创建数据库 CREATE DATABASE 2404javaee;效果截图&#xff1a; 4、删除数据…...

mybatis实现多表查询

mybatis高级查询【掌握】 1、准备工作 【1】包结构 创建java项目&#xff0c;导入jar包和log4j日志配置文件以及连接数据库的配置文件&#xff1b; 【2】导入SQL脚本 运行资料中的sql脚本&#xff1a;mybatis.sql 【3】创建实体来包&#xff0c;导入资料中的pojo 【4】User…...

数据结构:队列详解 c++信息学奥赛基础知识讲解

目录 一、队列概念 二、队列容器 三、队列操作 四、代码实操 五、队列遍历 六、案例实操 题目描述&#xff1a; 输入格式&#xff1a; 输出格式&#xff1a; 输入样例&#xff1a; 输出样例&#xff1a; 详细代码&#xff1a; 一、队列概念 队列是一种特殊的线性…...

硬件开发笔记(二十三):贴片电阻的类别、封装介绍,AD21导入贴片电阻原理图封装库3D模型

若该文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/140110514 长沙红胖子Qt&#xff08;长沙创微智科&#xff09;博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV…...

Kafka基本原理详解

&#xff08;一&#xff09;概念理解 Apache Kafka是一种开源的分布式流处理平台&#xff0c;专为高性能、高吞吐量的实时数据处理而设计。它最初由LinkedIn公司开发&#xff0c;旨在解决其网站活动中产生的大量实时数据处理和传输问题&#xff0c;后来于2011年开源&#xff0…...

【Unity】RPG2D龙城纷争(七)关卡编辑器之剧情编辑

更新日期:2024年7月1日。 项目源码:第五章发布(正式开始游戏逻辑的章节) 索引 简介一、剧情编辑1.对话数据集2.对话触发方式3.选择对话角色4.设置对话到关卡5.通关条件简介 严格来说,剧情编辑不在关卡编辑器界面中完成,只不过它仍然属于关卡编辑的范畴。 在我们的设想中…...

uniapp启动页面鉴权页面闪烁问题

在使用uni-app开发app 打包完成后如果没有token&#xff0c;那么就在onLaunch生命周期里面判断用户是否登录并跳转至登录页。 但是在app中页面会先进入首页然后再跳转至登录页&#xff0c;十分影响体验。 处理方法&#xff1a; 使用plus.navigator.closeSplashscreen() 官网…...

全志H616交叉编译工具链的安装与使用

交叉编译的概念 1. 什么是交叉编译&#xff1f; 交叉编译是指在一个平台上生成可以在另一个平台上运行的可执行代码。例如&#xff0c;在Ubuntu Linux上编写代码&#xff0c;并编译生成可在Orange Pi Zero2上运行的可执行文件。这个过程是通过使用一个专门的交叉编译工具链来…...

深入解析Java和Go语言中String与byte数组的转换原理

1.Java String与byte[]互相转换存在的问题 java中&#xff0c;按照byte[] 》string 》byte[]的流程转换后&#xff0c;byte数据与最初的byte不一致。 多说无益&#xff0c;上代码&#xff0c;本地macos机器执行&#xff0c;统一使用的UTF-8编码。 import java.nio.charset.S…...

什么是strcmp函数

目录 开头1.什么是strcmp函数2.strcmp函数里的内部结构3.strcmp函数的实际运用(这里只列举其一)脑筋急转弯 结尾 开头 大家好&#xff0c;我叫这是我58。今天&#xff0c;我们要来认识一下C语言中的strcmp函数。 1.什么是strcmp函数 strcmp函数来自于C语言中的头文件<str…...

Follow Carl To Grow|【LeetCode】491.递增子序列,46.全排列,47.全排列 II

【LeetCode】491.递增子序列 题意&#xff1a;给你一个整数数组 nums &#xff0c;找出并返回所有该数组中不同的递增子序列&#xff0c;递增子序列中 至少有两个元素 。你可以按 任意顺序 返回答案。 数组中可能含有重复元素&#xff0c;如出现两个整数相等&#xff0c;也可以…...

pytorch nn.Embedding 用法和原理

nn.Embedding 是 PyTorch 中的一个模块&#xff0c;用于将离散的输入&#xff08;通常是词或子词的索引&#xff09;映射到连续的向量空间。它在自然语言处理和其他需要处理离散输入的任务中非常常用。以下是 nn.Embedding 的用法和原理。 用法 初始化 nn.Embedding nn.Embed…...

Python中常用的有7种值(数据)的类型及type()语句的用法

目录 0.Python中常用的有7种值&#xff08;数据&#xff09;的类型Python中的数据类型主要有&#xff1a;Number&#xff08;数字&#xff09;、Boolean&#xff08;布尔&#xff09;、String&#xff08;字符串&#xff09;、List&#xff08;列表&#xff09;、Tuple&#xf…...

某配送平台未授权访问和弱口令(附赠nuclei默认密码验证脚本)

找到一个某src的子站&#xff0c;通过信息收集插件&#xff0c;发现ZABBIX-监控系统&#xff0c;可以日一下 使用谷歌搜索历史漏洞&#xff1a;zabbix漏洞 通过目录扫描扫描到后台&#xff0c;谷歌搜索一下有没有默认弱口令 成功进去了&#xff0c;挖洞就是这么简单 搜索文章还…...

01.总览

目录 简介Course 1: Natural Language Processing with Classification and Vector SpaceWeek 1: Sentiment Analysis with Logistic RegressionWeek 2: Sentiment Analysis with Nave BayesWeek 3: Vector Space ModelsWeek 4: Machine Translation and Document Search Cours…...

Linux换源

前言 安装完Linux系统&#xff0c;尽量更换源以提高安装软件的速度。 步骤 备份原始源列表sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak修改sources.list sudo vim /etc/apt/sources.list将内容替换成对应的源 **PS&#xff1a;清华源地址&#xff1a;https:…...

【高考志愿】 化学工程与技术

目录 一、专业概述 二、就业前景 三、就业方向 四、报考注意 五、专业发展与深造 六、化学工程与技术专业排名 七、总结 一、专业概述 化学工程与技术专业&#xff0c;这是一门深具挑战与机遇的综合性学科。它融合了工程技术的实用性和化学原理的严谨性&#xff0c;为毕…...

2024上半年网络与数据安全法规政策、国标、报告合集

事关大局&#xff0c;我国数据安全立法体系已基本形成并逐步细化。数据基础制度建设事关国家发展和安全大局&#xff0c;数据安全治理贯穿构建数据基础制度体系全过程。随着我国数字经济建设进程加快&#xff0c;数据安全立法实现由点到面、由面到体加速构建&#xff0c;目前已…...

【高考志愿】光学工程

目录 一、专业概述 二、专业特点 三、研究和就业方向 3.1 研究方向 3.2 就业方向 四、光学工程专业排名 高考志愿选择光学工程专业无疑是一项既具深度又富挑战性的明智之举。这个古老而充满魅力的专业&#xff0c;正逐渐崭露其在现代社会中的重要性与独特魅力。 一、专业…...

【机器学习】在【Pycharm】中的应用:【线性回归模型】进行【房价预测】

专栏&#xff1a;机器学习笔记 pycharm专业版免费激活教程见资源&#xff0c;私信我给你发 python相关库的安装&#xff1a;pandas,numpy,matplotlib&#xff0c;statsmodels 1. 引言 线性回归&#xff08;Linear Regression&#xff09;是一种常见的统计方法和机器学习算法&a…...

ai智能电销机器人系统稳不稳,效果好不好

智能ai电销机器人好不好用&#xff1f;智能AI电销机器人系统现如今已经不是一个新名词了&#xff0c;在人工智能这个新趋势的风潮下&#xff0c;一些企业已经在电销部门引入了智能AI机器人系统。我一起来看看ai智能电销机器人系统稳不稳。 1.数据有效 通常我们需要收集潜在用…...

【计算机网络】网络层(作业)

【一】 1、某主机的 IP 地址为 166.199.99.96/19。若该主机向其所在网络发送广播 IP 数据报&#xff0c; 则目的地址可以是&#xff08;D&#xff09;。 A. 166.199.99.255B. 166.199.96.255C. 166.199.96.0D. 166.199.127.255 解析&#xff1a; 166.199.99.96/19166.199.0…...

系统安全与应用

目录 1. 系统账户清理 2. 密码安全性控制 2.1 密码复杂性 2.2 密码时限 3 命令历史查看限制 4. 终端自动注销 5. su权限以及sudo提权 5.1 su权限 5.2 sudo提权 6. 限制更改GRUB引导 7. 网络端口扫描 那天不知道为什么&#xff0c;心血来潮看了一下passwd配置文件&am…...

ArcGIS中将测绘数据投影坐标(平面坐标)转地理坐标(球面经纬度坐标)

目录 前言1.测绘数据预览1.1 确定带号1.2 为什么是对Y轴分带&#xff0c;而不是对X轴分带&#xff1f; 2 测绘数据转shp2.1 添加数据2.2 显示XY数据2.3 添加经纬度字段2.4 计算经纬度 3.shp数据重投影4.总结 前言 最近在刚好在做一个小功能&#xff0c;将测绘数据转为经纬度坐标…...

秦PLUS与轩逸分别领跑新能源与燃油车销量榜?盖世终端销量数据

在2024年4月的国内新能源乘用车销量排行榜中,轿车市场呈现出激烈的竞争态势。秦PLUS以惊人的45,428辆销量稳坐榜首,海鸥紧随其后,销量达到28,391辆,驱逐舰05则以19,996辆的销量位列第三。汉、五菱宏光MINI、五菱缤果等车型也表现不俗,分别占据销量榜的第四至第六位。而在S…...

荣威“D家族”首款SUV车型D5XDMH即将正式上市!

2024年5月10日,荣威DMH技术品牌大会,在上海举行。在大会上,荣威汽车官方正式公布了荣威D5X DMH将于5月20日正式上市。该款车在不久前的北京车展上正式开启了预售,其预售价格区间为11.98万元至14.68万元。在外观尺寸上,荣威D5X DMH的长宽高分别为4700mm、1890mm和1664mm,轴…...

华为鸿蒙智行五一假期全系车型大定破11000台

随着五一假期的结束,华为智选车业务鸿蒙智行公布了整个假期的“销售成绩单”:5月1日-5 月5 日全系车型大定突破11000 台。在假期的前四天,也就是5月1日-4日,鸿蒙智行全系车型大定突破 8600 台,意味着 5月5日一天内新增了超过2400台的大定订单。根据此前公布的数据,鸿蒙智行…...

Sylvester矩阵、子结式、辗转相除法的三者关系(第二部分)

【三者的关系】 首先&#xff0c;辗转相除法可以通过Sylvester矩阵进行&#xff0c;过程如下&#xff08;以 m 8 、 l 7 m 8、l 7 m8、l7为例子&#xff09;。 首先调整矩阵中 a a a系数到最后面几行&#xff0c;如下所示&#xff1a; S ( a 8 a 7 a 6 a 5 a 4 a 3 a 2 …...

磁带存储:“不老的传说”依然在继续

现在是一个数据指数增长的时代&#xff0c;根据IDC数据预测&#xff0c;2025年全世界将产生175ZB的数据。 这里面大部分数据是不需要存储的&#xff0c;在2025预计每年需要存储11ZB的数据。换算个容易理解的说法&#xff0c;1ZB是10^18Bytes, 相当于要写5556万块容量18TB的硬盘…...

笔记90:C++中sort函数的使用

函数原型&#xff1a;sort ( iterator beg , iterator end , _Pred ) a a 参数介绍&#xff1a; beg&#xff1a;起始迭代器end&#xff1a;终止迭代器Pred&#xff1a;谓词&#xff08;如果不给&#xff0c;默认使用 less<int>() 作为谓词&#xff0c;排序方式为从小到大…...