react 组件应用
文章目录
- react 组件
- react 中组件 hook 函数应用
- useMemo
- 技术细节(useMemo 钩子函数和 useCallback 钩子函数)
- 小结(依赖性数组应用)
react 组件
-
函数式组件实例及应用场景
- 实例:
- 以下是一个简单的函数式组件,用于显示一个欢迎消息。
import React from 'react'; const WelcomeMessage = (props) => {return <h1>Welcome, {props.name}!</h1>; }; export default WelcomeMessage;
- 这个组件接收一个名为
name
的属性(props
),并在h1
标签中显示欢迎消息。它可以在其他组件中被这样使用:
import React from 'react'; import WelcomeMessage from './WelcomeMessage'; const App = () => {return (<div><WelcomeMessage name="John" /></div>); }; export default App;
- 应用场景:
- 展示型组件:函数式组件非常适合用于展示型组件,这些组件主要用于将数据以某种形式展示给用户,没有复杂的内部状态或生命周期方法。例如,一个简单的文章列表组件,它接收文章数据作为属性,然后将每篇文章的标题、作者等信息展示出来。
- 无状态逻辑组件:当组件不需要维护自己的状态,只是简单地根据传入的属性进行渲染时,函数式组件是很好的选择。像上面的欢迎消息组件,它只是根据传入的名字属性来显示消息,没有自己的内部状态。
- 作为纯函数:函数式组件就像纯函数一样,对于相同的输入(属性),总是返回相同的输出(渲染结果)。这使得它们在性能优化方面具有优势,因为React可以更容易地判断组件是否需要重新渲染。例如,在一个数据可视化组件中,只要传入的数据(属性)没有变化,组件就不需要重新渲染。
- 实例:
-
类组件实例及应用场景
- 实例:
- 下面是一个简单的类组件,用于实现一个计数器。
import React, { Component } from 'react'; class Counter extends Component {constructor(props) {super(props);this.state = {count: 0};}increment() {this.setState((prevState) => ({count: prevState.count + 1}));}render() {return (<div><p>Count: {this.state.count}</p><button onClick={() => this.increment()}>Increment</button></div>);} } export default Counter;
- 这个类组件有一个内部状态
count
,初始值为0。有一个increment
方法用于增加计数,在render
方法中,它展示当前的计数,并提供一个按钮,点击按钮会调用increment
方法来更新状态,从而重新渲染组件显示新的计数。
- 应用场景:
- 有状态组件:类组件适合需要维护内部状态的场景。例如,在一个表单组件中,需要跟踪用户输入的各个字段的值,这些值就是组件的内部状态。像一个登录表单,需要记录用户输入的用户名和密码,并且可能还需要验证输入是否符合要求,这时候类组件的状态管理就很有用。
- 复杂的生命周期管理:当组件需要在挂载、更新或卸载等不同生命周期阶段执行特定操作时,类组件是更好的选择。例如,在组件挂载时获取数据,在组件更新时根据新的数据重新计算某些值,在组件卸载时清理资源(如取消网络请求、清除定时器等)。比如,一个地图组件,在挂载时需要初始化地图,在更新时可能需要更新地图上的标记位置,在卸载时需要释放地图相关的资源,使用类组件可以更好地利用生命周期方法来实现这些功能。
- 与第三方库集成:如果需要在组件中集成第三方库,并且这些库需要与组件的生命周期进行交互,类组件会更方便。例如,在使用一些动画库时,可能需要在组件挂载时启动动画,在组件卸载时停止动画,通过类组件的生命周期方法可以很好地控制这些操作。
- 实例:
react 中组件 hook 函数应用
-
React组件传值
- 父组件向子组件传值(Props)
- 实例:
- 首先创建一个父组件
ParentComponent
和一个子组件ChildComponent
。
import React from 'react'; import ChildComponent from './ChildComponent'; const ParentComponent = () => {const message = "Hello from Parent";return (<div><ChildComponent passedMessage={message} /></div>); }; export default ParentComponent;
- 子组件接收
passedMessage
属性并显示它。
import React from 'react'; const ChildComponent = (props) => {return (<div><p>{props.passedMessage}</p></div>); }; export default ChildComponent;
- 首先创建一个父组件
- 解释:在父组件中,定义了一个变量
message
,然后将这个变量作为属性passedMessage
传递给子组件ChildComponent
。在子组件中,通过props.passedMessage
来访问这个传递过来的值,并将其渲染在p
标签中。
- 实例:
- 子组件向父组件传值(回调函数)
- 实例:
- 父组件定义一个函数来接收子组件传递的值。
import React from 'react'; import ChildComponentWithCallback from './ChildComponentWithCallback'; const ParentComponentWithCallback = () => {const handleChildValue = (valueFromChild) => {console.log("Received value from child: ", valueFromChild);};return (<div><ChildComponentWithCallback sendValueToParent={handleChildValue} /></div>); }; export default ParentComponentWithCallback;
- 子组件调用父组件传递过来的函数来传递值。
import React from 'react'; const ChildComponentWithCallback = (props) => {const valueToSend = "Value from Child";const sendValue = () => {props.sendValueToParent(valueToSend);};return (<div><button onClick={sendValue}>Send Value to Parent</button></div>); }; export default ChildComponentWithCallback;
- 解释:在父组件中,
handleChildValue
函数用于接收子组件传递的值。这个函数作为属性sendValueToParent
传递给子组件。在子组件中,当按钮被点击时,sendValue
函数被调用,它会调用props.sendValueToParent
并将valueToSend
作为参数传递,这样就实现了子组件向父组件传值。
- 实例:
- 父组件向子组件传值(Props)
-
Hook函数应用实例
- useState Hook
- 实例:
- 用于在函数式组件中添加状态。
import React, { useState } from 'react'; const CounterHook = () => {const [count, setCount] = useState(0);const increment = () => {setCount(count + 1);};return (<div><p>Count: {count}</p><button onClick={increment}>Increment</button></div>); }; export default CounterHook;
- 解释:
useState
是一个Hook函数,它返回一个数组,数组的第一个元素是状态变量(count
),第二个元素是用于更新这个状态变量的函数(setCount
)。初始状态值为0。当按钮被点击时,increment
函数被调用,它使用setCount
来更新count
的值,从而导致组件重新渲染并显示新的计数。
- 实例:
- useEffect Hook
- 实例:
- 用于在组件挂载、更新或卸载时执行副作用操作,如获取数据、订阅事件等。
import React, { useState, useEffect } from 'react'; const DataFetchingComponent = () => {const [data, setData] = useState([]);useEffect(() => {const fetchData = async () => {const response = await fetch('https://example.com/api/data');const jsonData = await response.json();setData(jsonData);};fetchData();}, []);return (<div>{data.map((item) => (<p key={item.id}>{item.name}</p>))}</div>); }; export default DataFetchingComponent;
- 解释:
useEffect
接受一个函数作为参数。在这个例子中,函数内部定义了一个异步函数fetchData
来从API获取数据。获取到数据后,使用setData
来更新状态。第二个参数[]
表示这个useEffect
只在组件挂载时执行一次。如果省略这个参数,useEffect
会在组件每次更新时都执行。如果想在某些特定状态变化时执行useEffect
,可以将这些状态变量放在数组中,例如[count]
,这样当count
状态改变时,useEffect
就会执行。
- 实例:
- useContext Hook
- 实例:
- 用于在组件树中共享数据,避免了层层传递属性的麻烦。
- 首先创建一个上下文(Context)。
import React from 'react'; const MyContext = React.createContext();
- 然后在一个父组件中提供这个上下文的值。
import React from 'react'; import MyContext from './MyContext'; import ChildComponentUsingContext from './ChildComponentUsingContext'; const ParentComponentWithContext = () => {const sharedValue = "This is a shared value";return (<MyContext.Provider value={sharedValue}><ChildComponentUsingContext /></MyContext.Provider>); }; export default ParentComponentWithContext;
- 最后在子组件中使用
useContext
来获取这个共享的值。
import React, { useContext } from 'react'; import MyContext from './MyContext'; const ChildComponentUsingContext = () => {const sharedValue = useContext(MyContext);return (<div><p>{sharedValue}</p></div>); }; export default ChildComponentUsingContext;
- 解释:
React.createContext
创建了一个上下文对象。在ParentComponentWithContext
中,通过MyContext.Provider
来提供一个共享的值sharedValue
。在ChildComponentUsingContext
中,useContext(MyContext)
用于获取这个共享的值,并将其渲染在p
标签中。这样,无论组件层次有多深,只要在MyContext.Provider
的范围内,都可以方便地获取这个共享值。
- 实例:
- useState Hook
useMemo
-
基本概念
useMemo
是一个React Hook,它用于缓存计算结果。其主要目的是通过记忆(memorization)来避免在每次组件重新渲染时都进行昂贵的计算。这样可以优化性能,特别是当计算过程复杂或者依赖的数据频繁变化时。
-
语法和参数
- 语法:
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
- 第一个参数是一个函数,这个函数包含了需要进行记忆化的计算。例如,这个函数可能是对一个大型数组进行过滤、排序或者其他复杂的操作。
- 第二个参数是一个依赖项数组。这个数组中的元素是当它们发生变化时,
useMemo
才会重新运行第一个参数中的计算函数,以更新memoizedValue
。如果依赖项数组为空,那么计算函数只会在组件初次渲染时执行一次。
- 语法:
-
应用实例
- 避免重复计算
- 假设我们有一个组件,用于计算并显示一个非常大的斐波那契数列。斐波那契数列的计算是比较复杂的,而且如果没有优化,每次组件渲染都会重新计算整个数列。
import React, { useState, useMemo } from 'react'; const FibonacciCalculator = () => {const [n, setN] = useState(10);// 使用useMemo来缓存斐波那契数列的计算结果const fibonacciSequence = useMemo(() => {const sequence = [0, 1];for (let i = 2; i <= n; i++) {sequence.push(sequence[i - 1] + sequence[i - 2]);}return sequence;}, [n]);return (<div><inputtype="number"value={n}onChange={(e) => setN(Number(e.target.value))}/><p>斐波那契数列前{n}项: {fibonacciSequence.join(', ')}</p></div>); }; export default FibonacciCalculator;
- 解释:在这个组件中,
useMemo
用于缓存斐波那契数列的计算结果。当n
的值发生变化时(通过输入框改变n
的值),useMemo
会重新运行计算斐波那契数列的函数,因为n
是useMemo
的依赖项。如果n
没有变化,即使组件因为其他原因(比如父组件重新渲染)重新渲染,fibonacciSequence
的值也不会重新计算,而是直接使用之前缓存的值。
- 优化子组件渲染
- 考虑一个场景,父组件有一个状态值,这个状态值会导致父组件频繁重新渲染,但是子组件只有在特定数据变化时才需要重新渲染。
import React, { useState, useMemo } from 'react'; const ParentComponent = () => {const [count, setCount] = useState(0);const [data, setData] = useState([1, 2, 3]);// 假设这是一个复杂的计算,用于过滤数据const filteredData = useMemo(() => {return data.filter((item) => item > 1);}, [data]);return (<div><button onClick={() => setCount(count + 1)}>Increment Count (This causes Parent to re - render)</button><ChildComponent data={filteredData} /></div>); }; const ChildComponent = ({ data }) => {return (<div>{data.map((item) => (<p key={item}>{item}</p>))}</div>); }; export default ParentComponent;
- 解释:在
ParentComponent
中,count
状态的变化会导致父组件重新渲染。但是,通过useMemo
缓存了filteredData
的计算结果,只要data
没有变化,filteredData
就不会重新计算,传递给ChildComponent
的数据也不会改变。这样,即使父组件因为count
的变化重新渲染,ChildComponent
也不会重新渲染,除非data
发生变化,从而优化了子组件的渲染性能。
- 避免重复计算
技术细节(useMemo 钩子函数和 useCallback 钩子函数)
-
基本概念和用途
- useMemo:
- 主要用于缓存计算结果。它会记住一个函数的返回值,只有当依赖项发生变化时,才会重新计算这个返回值。这个返回值可以是任何类型的数据,比如一个复杂的计算结果、一个经过处理的数据数组等。
- 目的是避免在每次组件渲染时都进行昂贵的计算,以提高性能。
- useCallback:
- 用于缓存函数本身。它返回一个记忆化(memoized)的函数,只有当依赖项发生变化时,这个记忆化的函数才会重新创建。
- 通常用于在组件中传递回调函数,以避免在不必要的情况下重新创建函数,从而防止子组件因为接收到新的函数引用而重新渲染。
- useMemo:
-
语法对比
- useMemo:
- 语法:
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
- 第一个参数是一个返回需要缓存的值的函数,第二个参数是一个依赖项数组,用于确定何时重新计算这个值。
- 语法:
- useCallback:
- 语法:
const memoizedCallback = useCallback(() => doSomething(a, b), [a, b]);
- 第一个参数是需要缓存的函数本身,第二个参数同样是依赖项数组,用于决定何时重新创建这个函数。
- 语法:
- useMemo:
-
应用场景对比
- useMemo:
- 复杂计算的缓存:
- 例如,在一个数据可视化组件中,需要对大量的数据进行复杂的统计计算,如计算平均值、标准差等。
import React, { useState, useMemo } from 'react'; const DataVisualizationComponent = () => {const [data, setData] = useState([1, 2, 3, 4, 5]);// 计算平均值并缓存结果const average = useMemo(() => {const sum = data.reduce((acc, val) => acc + val, 0);return sum / data.length;}, [data]);return (<div><p>数据平均值: {average}</p></div>); }; export default DataVisualizationComponent;
- 解释:每次
data
发生变化时,useMemo
会重新计算平均值;如果data
不变,即使组件因为其他原因重新渲染,也会直接使用缓存的平均值,避免了重复计算。
- 避免数据处理的重复执行:
- 假设要对一个文本字符串进行复杂的格式化操作,如将一段包含HTML标签的文本转换为纯文本并进行单词计数。
import React, { useState, useMemo } from 'react'; const TextProcessingComponent = () => {const [text, setText] = useState("<p>Hello, World!</p>");// 缓存格式化后的文本和单词计数结果const [formattedText, wordCount] = useMemo(() => {const plainText = text.replace(/<[^>]*>/g, "");const words = plainText.split(" ").length;return [plainText, words];}, [text]);return (<div><p>格式化后的文本: {formattedText}</p><p>单词计数: {wordCount}</p></div>); }; export default TextProcessingComponent;
- 解释:
useMemo
确保只有当text
发生变化时,才会重新进行文本格式化和单词计数操作。
- 复杂计算的缓存:
- useCallback:
- 优化子组件渲染(传递回调函数):
- 考虑一个包含列表和删除按钮的组件,点击删除按钮会调用一个回调函数来删除列表中的某个元素。
import React, { useState, useCallback } from 'react'; const ParentListComponent = () => {const [list, setList] = useState([1, 2, 3]);// 记忆化删除函数const handleDelete = useCallback((index) => {const newList = [...list];newList.splice(index, 1);setList(newList);}, [list]);return (<div>{list.map((item, index) => (<ChildListItem key={item} item={item} onDelete={handleDelete(index)} />))}</div>); }; const ChildListItem = ({ item, onDelete }) => {return (<div><p>{item}</p><button onClick={onDelete}>删除</button></div>); }; export default ParentListComponent;
- 解释:
useCallback
用于缓存handleDelete
函数。只有当list
发生变化时,handleDelete
函数才会重新创建。这样,在ParentListComponent
重新渲染时,如果list
没有变化,传递给ChildListItem
的onDelete
函数引用不会改变,从而避免了ChildListItem
因为函数引用改变而不必要地重新渲染。
- 事件处理函数的优化:
- 例如,在一个游戏组件中有多个按钮,每个按钮都有自己的点击事件处理函数,这些函数可能会根据游戏状态(如得分、关卡等)进行一些操作。
import React, { useState, useCallback } from 'react'; const GameComponent = () => {const [score, setScore] = useState(0);const [level, setLevel] = useState(1);// 记忆化加分事件处理函数const handleAddScore = useCallback(() => {setScore(score + 10);}, [score]);// 记忆化升级事件处理函数const handleLevelUp = useCallback(() => {setLevel(level + 1);}, [level]);return (<div><button onClick={handleAddScore}>加分</button><button onClick={handleLevelUp}>升级</button></div>); }; export default GameComponent;
- 解释:
useCallback
确保每个事件处理函数只有在其依赖的游戏状态(score
或level
)发生变化时才会重新创建。这有助于在游戏状态更新时,只重新渲染与状态变化相关的部分,提高性能。
- 优化子组件渲染(传递回调函数):
- useMemo:
小结(依赖性数组应用)
-
理解依赖项数组的作用
- 在
useMemo
、useCallback
和其他类似的React钩子(如useEffect
)中,依赖项数组用于告诉React在哪些值发生变化时,需要重新执行相关的操作。例如,在useMemo
中,当依赖项数组中的元素变化时,会重新计算缓存的值;在useCallback
中,依赖项的变化会导致回调函数重新创建。
- 在
-
分析组件内部的逻辑和状态使用情况
- 数据读取与计算
- 识别使用的数据:仔细查看在计算或函数内部使用了哪些变量、状态(
state
)或属性(props
)。例如,在一个useMemo
钩子中,如果是计算一个购物车商品总价,并且总价是根据商品数量和单价来计算的,那么商品数量和单价就是依赖项。 - 考虑数据来源:如果数据来自组件的状态(通过
useState
定义)、父组件传递的属性(props
)或者其他外部数据源(如context
),这些都有可能是依赖项。例如,在一个展示用户信息的组件中,用户的姓名、年龄等属性是从父组件传递过来的,那么这些props
就应该在依赖项数组中,因为如果这些信息改变,组件的展示可能需要更新。
- 识别使用的数据:仔细查看在计算或函数内部使用了哪些变量、状态(
- 函数调用与副作用操作
- 检查函数内部调用的函数:如果在
useCallback
定义的函数内部调用了其他函数,并且这些函数的行为可能因为某些数据的变化而改变,那么这些数据对应的变量也可能是依赖项。例如,在一个表单提交的回调函数中,调用了一个验证表单数据的函数,而验证函数可能依赖于表单的某些字段,这些字段对应的变量就是依赖项。 - 副作用操作相关的数据:对于
useEffect
钩子,考虑在其中执行的副作用操作(如数据获取、订阅事件等)依赖于哪些数据。如果在组件挂载时通过fetch
获取数据,并且数据的URL是根据某个状态变量确定的,那么这个状态变量就是useEffect
的依赖项。
- 检查函数内部调用的函数:如果在
- 数据读取与计算
-
遵循最小化依赖原则
- 只包含真正会影响计算或操作的元素。例如,在一个简单的计数器组件中,有一个
increment
函数用于增加计数,一个doubleCount
函数(通过useMemo
缓存)用于计算计数的两倍。doubleCount
函数只依赖于计数变量,而不依赖于increment
函数,所以在useMemo
的依赖项数组中只需要包含计数变量。 - 避免包含不必要的元素,因为这可能导致过度重新计算或重新创建函数。如果不小心包含了一个不会影响操作的变量,那么每次这个变量变化时,都会触发不必要的重新计算或重新创建,降低性能。例如,在一个组件中,有一个用于显示当前日期的函数(通过
useMemo
缓存),这个函数只依赖于日期相关的状态,而不依赖于一个用于切换主题的变量,那么主题变量就不应该出现在useMemo
的依赖项数组中。
- 只包含真正会影响计算或操作的元素。例如,在一个简单的计数器组件中,有一个
-
动态依赖项的情况
- 有时候依赖项可能是动态生成的,例如,一个根据用户权限动态加载不同模块的组件。在这种情况下,可以考虑使用一个更高级的技术,如使用
useReducer
来管理状态,或者在useEffect
中动态地添加和移除事件监听器,并且根据具体情况更新依赖项数组。但是这种情况比较复杂,需要谨慎处理,因为不当的操作可能导致内存泄漏或其他性能问题。 - 如果依赖项是一个对象或数组,并且对象或数组的内容可能会改变而引用不变(例如,修改对象的属性而不是重新创建对象),React可能无法正确检测到变化。在这种情况下,可以考虑使用一些辅助函数,如
React.useMemo
来创建一个新的引用,或者使用Object.assign
或[...array]
等方式来创建新的对象或数组,并且将这些新的引用作为依赖项。
- 有时候依赖项可能是动态生成的,例如,一个根据用户权限动态加载不同模块的组件。在这种情况下,可以考虑使用一个更高级的技术,如使用
相关文章:
react 组件应用
文章目录 react 组件react 中组件 hook 函数应用useMemo技术细节(useMemo 钩子函数和 useCallback 钩子函数)小结(依赖性数组应用) react 组件 函数式组件实例及应用场景 实例: 以下是一个简单的函数式组件,用于显示一个欢迎消息。 import React from re…...
mysql 快速解决死锁方式
mysql 快速解决死锁方式 直接寻找并终止导致死锁的具体 SQL 语句是处理死锁的一种有效方法,特别是在高并发环境中。以下步骤和示例展示了如何通过识别、分析和终止长时间运行的 SQL 语句来解决死锁问题。 一、识别那个导致死锁的 SQL 语句 1. 使用 SHOW ENGINE I…...

RabbitMQ 篇-深入了解 RabbitMQ 安装以及 SpringAMQP 的基础使用(声明队列和交换机、发送接收消息、配置 JSON 消息转化器)
🔥博客主页: 【小扳_-CSDN博客】 ❤感谢大家点赞👍收藏⭐评论✍ 文章目录 1.0 RabbitMQ 初识 1.1 RabbitMQ 安装 2.0 数据隔离 2.1 用户管理 2.2 virtual host 虚拟主机 3.0 SpringAMQP 3.1 RabbitMQ 配置 3.2 发送消息 3.3 接收消息 3.4 Wor…...

在 WPF 中,绑定机制是如何工作的?WPF数据绑定机制解析
在WPF(Windows Presentation Foundation)中,数据绑定机制是其核心功能之一,广泛用于连接应用程序的UI(用户界面)和应用程序的业务逻辑层。数据绑定允许你将UI元素与数据源(如对象、集合或其他数…...
pwn学习笔记(12)--Chunk Extend and Overlapping
pwn学习笔记(12)–Chunk Extend and Overlapping chunk extend 是堆漏洞的一种常见利用手法,通过 extend 可以实现 chunk overlapping(块重叠) 的效果。这种利用方法需要以下的时机和条件: 程序中存在…...
java基础面试题六集合框架
目录 1. List,Set,Map是否继承自collection接口? 2. 说说List,Set,Map三者的区别 3. 写出list、map、set接口的实现类,并说出其特点 4. 常见集合类的区别和适用场景 5. 集合的父类是谁?哪些安全的? 6…...

2024年12月一区SCI-指数-三角优化算法ETO-附Matlab免费代码
引言 本期介绍了一种基于数学概念的元启发式优化算法,称为指数-三角优化算法Exponential-trigonometric optimization algorithm,ETO。该算法基于指数函数和三角函数的复杂组合,于2024年12月最新发表在中JCR1区、 中科院1区 SCI期刊Computer…...
设置服务器ssh连接超时时间
在Linux服务器上,您可以通过修改SSH服务器配置文件来设置SSH连接的超时时间。以下是设置SSH连接超时时间的一些步骤: 打开SSH服务器配置文件。这个文件通常是/etc/ssh/sshd_config。sudo nano /etc/ssh/sshd_config在配置文件中,您可以设置以…...

Dubbo分布式日志跟踪实现
前言 随着越来越多的应用逐渐微服务化后,分布式服务之间的RPC调用使得异常排查的难度骤增,最明显的一个问题,就是整个调用链路的日志不在一台机器上,往往定位问题就要花费大量时间。如何在一个分布式网络中把单次请求的整个调用日…...

EPSON机械手与第三方相机的校准功能设计By python
EPSON机械手与第三方相机的校准功能设计By python 使用Python来实现EPSON机械手与第三方相机的校准功能是一个复杂但可行的任务。这通常涉及以下几个步骤:硬件接口通信、图像处理、标定算法实现和控制逻辑编写。 1. 环境准备 首先,库 pip install numpy opencv-python pyse…...
探索 Java 23:新时代的编程利器
一、引言 随着技术的不断发展,Java 作为一种广泛应用的编程语言也在不断演进。Java 23 的推出带来了许多令人兴奋的新特性和改进,为开发者提供了更多的工具和功能,以应对日益复杂的软件开发挑战。本文将深入介绍 Java 23 的各个方面。 二、J…...
CSS3_3D变换(七)
1、CSS3_3D变换 1.1 3D空间与景深 3D空间:在父元素中将属性transform-style设置为preserve-3d开启3D空间,默认值为flat(开启2D空间); 景深:人眼与平面的距离,产生透视效果,使得效果…...

Mesh网格
Mesh(网格) 定义:Mesh 是一个包含顶点、三角形、顶点法线、UV坐标、颜色和骨骼权重等数据的对象。它定义了3D模型的几何形状。 功能: 顶点(Vertices):构成3D模型的点。 三角形(Triangles)&…...

LeetCode 509.斐波那契数
动态规划思想 五步骤: 1.确定dp[i]含义 2.递推公式 3.初始化 4.遍历顺序 5.打印dp数组 利用状态压缩,简化空间复杂度。在原代码中,dp 数组保存了所有状态,但实际上斐波那契数列的计算只需要前两个状态。因此,我们…...
SQL Server 数据太多如何优化
大家好,我是 V 哥。讲了很多数据库,有小伙伴说,SQL Server 也讲一讲啊,好吧,V 哥做个听话的门童,今天要聊一聊 SQL Server。 在 SQL Server 中,当数据量增大时,数据库的性能可能会受…...

关于word 页眉页脚的一些小问题
去掉页眉底纹: 对文档的段落边框和底纹进行设置,也是页眉横线怎么删除的一种解决方式,具体操作如下: 选中页眉中的横线文本; 点击【开始】选项卡,在【段落】组中点击【边框】按钮的下拉箭头; …...
【高等数学学习记录】连续函数的运算与初等函数的连续性
一、知识点 (一)连续函数的和、差、积、商的连续性 定理1 设函数 f ( x ) f(x) f(x) 和 g ( x ) g(x) g(x) 在点 x 0 x_0 x0 连续,则它们的和(差) f g f\pm g fg、积 f ⋅ g f\cdot g f⋅g 及商 f g \frac{f…...

【抖音直播间弹幕】protobuf协议分析
将Uint8Array变成 PushFrame格式,里面的payload就存放着弹幕消息 点进去就可以看到其定义的proto结构 headers是一个自定义类型 将测试数据保存一下,等下做对比 先将PushFrame的 payload 内容进行gzip解压 然后再解析为响应 可以看到里面有对应的消…...
Swift 开发教程系列 - 第11章:内存管理和 ARC(Automatic Reference Counting)
在 Swift 中,内存管理由 ARC(自动引用计数)机制自动处理。ARC 通过追踪和管理对象的引用计数来确保分配的内存得到有效释放。尽管 ARC 在大多数情况下能够高效地管理内存,但理解其工作原理仍然十分重要,因为不当的引用…...
C#中 layout的用法
在C#中,layout并不是一个直接用于C#语言本身的关键字或特性。然而,layout在与C#紧密相关的某些上下文中确实有其用途,特别是在涉及用户界面(UI)设计和数据展示时。以下是几个常见的与layout相关的用法场景:…...

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析
1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具,该工具基于TUN接口实现其功能,利用反向TCP/TLS连接建立一条隐蔽的通信信道,支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式,适应复杂网…...
Ubuntu系统下交叉编译openssl
一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机:Ubuntu 20.04.6 LTSHost:ARM32位交叉编译器:arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...
在四层代理中还原真实客户端ngx_stream_realip_module
一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡(如 HAProxy、AWS NLB、阿里 SLB)发起上游连接时,将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后,ngx_stream_realip_module 从中提取原始信息…...

Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

【VLNs篇】07:NavRL—在动态环境中学习安全飞行
项目内容论文标题NavRL: 在动态环境中学习安全飞行 (NavRL: Learning Safe Flight in Dynamic Environments)核心问题解决无人机在包含静态和动态障碍物的复杂环境中进行安全、高效自主导航的挑战,克服传统方法和现有强化学习方法的局限性。核心算法基于近端策略优化…...
怎么让Comfyui导出的图像不包含工作流信息,
为了数据安全,让Comfyui导出的图像不包含工作流信息,导出的图像就不会拖到comfyui中加载出来工作流。 ComfyUI的目录下node.py 直接移除 pnginfo(推荐) 在 save_images 方法中,删除或注释掉所有与 metadata …...
libfmt: 现代C++的格式化工具库介绍与酷炫功能
libfmt: 现代C的格式化工具库介绍与酷炫功能 libfmt 是一个开源的C格式化库,提供了高效、安全的文本格式化功能,是C20中引入的std::format的基础实现。它比传统的printf和iostream更安全、更灵活、性能更好。 基本介绍 主要特点 类型安全:…...
SpringAI实战:ChatModel智能对话全解
一、引言:Spring AI 与 Chat Model 的核心价值 🚀 在 Java 生态中集成大模型能力,Spring AI 提供了高效的解决方案 🤖。其中 Chat Model 作为核心交互组件,通过标准化接口简化了与大语言模型(LLM࿰…...
区块链技术概述
区块链技术是一种去中心化、分布式账本技术,通过密码学、共识机制和智能合约等核心组件,实现数据不可篡改、透明可追溯的系统。 一、核心技术 1. 去中心化 特点:数据存储在网络中的多个节点(计算机),而非…...
xmind转换为markdown
文章目录 解锁思维导图新姿势:将XMind转为结构化Markdown 一、认识Xmind结构二、核心转换流程详解1.解压XMind文件(ZIP处理)2.解析JSON数据结构3:递归转换树形结构4:Markdown层级生成逻辑 三、完整代码 解锁思维导图新…...