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

React 设计模式:实用指南

在这里插入图片描述
React 提供了众多出色的特性以及丰富的设计模式,用于简化开发流程。开发者能够借助 React 组件设计模式,降低开发时间以及编码的工作量。此外,这些模式让 React 开发者能够构建出成果更显著、性能更优越的各类应用程序。

本文将会为您介绍五个基础的 React 组件设计模式,并提供实例来协助您优化您的 React 应用。

文章目录

    • 1. 高阶组件(HOC)模式
    • 2. Provider 模式
    • 3. 容器/表现模式
    • 4. 复合模式
    • 5. Hooks 模式

1. 高阶组件(HOC)模式

随着您的应用规模逐步扩大,可能会出现需要在多个组件之间共享相同组件逻辑的情况。而这正是 HOC 模式所能为您实现的。
HOC 是一个纯粹的 JavaScript 函数,它以一个组件作为参数,并在注入或者添加额外的数据和功能之后,返回另一个组件。从本质上讲,它充当了一个 JavaScript 装饰器函数。HOCs 的基本理念与 React 的特性相符,也就是倾向于组合而非继承。

例如,设想一个我们需要对多个应用组件进行统一风格化的场景。我们能够通过实现一个 HOC ,来避免在本地反复构建样式对象,该 HOC 会将样式应用于传入的组件。

import React from 'react';// HOC
function decoratedComponent(WrappedComponent) {return props => {const style = { padding: '5px', margin: '2px' };return <WrappedComponent style={style} {...props} />;};
}const Button = ({ style }) => <button style={{ ...style, color: 'yellow' }}>这是一个按钮。</button>;
const Text = ({ style }) => <p style={style}>这是文本。</p>;const DecoratedButton = decoratedComponent(Button);
const DecoratedText = decoratedComponent(Text);function App() {return (<><DecoratedButton /><DecoratedText /></>);
}export default App;

在上述代码示例中,我们已经对Button 和Text 组件进行了修改,分别生成了DecoratedButton 和DecoratedText。现在这两个组件都继承了由高阶组件(HOC)decoratedComponent 添加的样式。由于Button 组件已经有一个名为style 的prop,HOC 将覆盖它并附加新的prop。

优点

  • 集中维护:有助于在单一位置维护可重用功能。
  • 代码清晰:通过将所有逻辑整合到一个部分来保持代码的清晰,并实现关注点分离。
  • 减少错误:通过避免代码重复,减少整个应用中意外错误的可能性。

缺点

  • Props 名称冲突:有时会导致props 名称冲突,使得调试和扩展应用更具挑战性,特别是当组合许多共享相同prop 名称的 HOC 时。

2. Provider 模式

在复杂的 React 应用中,经常会出现如何使数据对多个组件可访问的挑战。虽然可以使用props 来传递数据,但在所有组件中访问props 值可能会变得繁琐,导致props 钻取(prop drilling)。

Provider 模式
利用 React Context API,以及在某些情况下使用 Redux,为这一挑战提供了解决方案。这种模式允许开发者将数据存储在中心区域,称为 React 上下文对象或 Redux 存储,消除了props 钻取的需要。

使用 React-Redux 实现 Provider 模式
React-Redux 在应用的顶层使用 Provider 模式,为所有组件提供对 Redux 存储的访问权限。以下代码示例展示了如何设置它。

import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import store from './store';
import App from './App';const rootElement = document.getElementById('root');
ReactDOM.render(<Provider store={store}><App /></Provider>,rootElement
);

使用 React Context 的 Provider 模式
在 Redux 可能过于复杂的情况下,可以使用 React 的Context API。例如,如果一个 App 组件有一个数据集需要被深层组件树中的 List、PageHeader 和 Text 组件访问,Context API 可以绕过 props 钻取。

以下代码示例说明了如何创建和提供上下文。

import React, { createContext } from 'react';
import SideMenu from './SideMenu';
import Page from './Page';const DataContext = createContext();function App() {const data = {list: ['项目1', '项目2', '项目3'],text: '你好世界',header: 'WriterGate'}; // 在这里定义你的数据结构。return (<DataContext.Provider value={data}><SideMenu/><Page/></DataContext.Provider>);
}

使用 Context 数据
组件可以使用useContext 钩子访问数据,它允许读取和写入上下文对象中的数据。

以下代码示例供参考。

import React, { useContext } from 'react';const SideMenu = () => <List/>
const Page = () => <div><PageHeader/><Content/></div>function List() {const data = useContext(DataContext);return <span>{data.list}</span>;
}function Text() {const data = useContext(DataContext);return <h1>{data.text}</h1>;
}function PageHeader() {const data = useContext(DataContext);return <div>{data.header}</div>;
}const Content = () => {const data = useContext(DataContext);return <div><Text/></div>;
}

优点

  • 允许将数据发送到多个组件,无需通过组件层次结构。
  • 减少了重构代码时出现不可预见错误的可能性。
  • 消除了 props-drilling,这是一种反模式。
  • 简化了保持某种形式的全局状态,因为组件可以访问它。

缺点

  • 过度使用 Provider 模式可能会导致性能问题,特别是当向多个组件传递不断变化的变量时。然而,在较小的应用中,这不会是一个大问题。

3. 容器/表现模式

React 中的容器/表现模式提供了一种实现关注点分离的方法,有效地将视图与应用逻辑分开。理想情况下,我们需要通过将这个过程分成两部分来实现关注点分离。

表现组件
这些组件专注于如何向用户展示数据。它们通过props 接收数据,并负责以视觉上令人愉悦的方式呈现它,通常带有样式,而不修改数据。

考虑以下示例,它显示了从 API 获取的食物图片。为了实现这一点,我们实现了一个函数组件,该组件通过props 接收数据并相应地呈现它。

import React from "react";export default function FoodImages({ foods }) {return foods.map((food, i) => <img src={food} key={i} alt="食物" />);
}

在这个代码示例中,FoodImages 组件充当表现组件。表现组件保持无状态,除非它们需要 React 状态来渲染 UI。接收到的数据不会被修改。相反,它是从相应的容器组件中检索的。

容器组件
这些组件专注于决定向用户展示什么数据。它们的主要角色是将数据传递给表现组件。容器组件通常不渲染除了与它们的数据相关联的表现组件之外的其他组件。容器组件通常没有任何样式,因为它们的责任在于管理状态和生命周期方法,而不是渲染。

以下代码示例是一个容器组件,它从外部 API 获取图片并将它们传递给表现组件(FoodImages)。

import React from "react";
import FoodImages from "./FoodImages";export default class FoodImagesContainer extends React.Component {constructor() {super();this.state = {foods: []};}componentDidMount() {fetch("http://localhost:4200/api/food/images/random/6").then(res => res.json()).then(({ message }) => this.setState({ foods: message }));}render() {return <FoodImages foods={this.state.foods} />;}
}

优点

  • 实现了关注点分离。
  • 表现组件高度可重用。
  • 由于表现组件不改变应用逻辑,它们的外表可以在不了解源代码的情况下进行修改。
  • 测试表现组件是直接的,因为这些组件根据提供的数据进行渲染。

缺点

  • 容器/表现模式下,无状态函数组件需要被重写为类组件。

4. 复合模式

复合组件是 React 组件模式中的高级模式,它允许构建功能以协作完成任务。它允许许多相互依赖的组件共享状态和处理逻辑,同时协同工作。
这种模式为父组件与其子组件之间的通信提供了一个富有表现力和多功能的 API。此外,它允许父组件隐式地与其子组件共享状态。复合组件模式可以使用 Context API 或 React.cloneElement API 来实现。
以下代码示例展示了如何使用 Context API 实现复合组件模式。

import React, { useState, useContext } from "react";const SelectContext = React.createContext();const Select = ({ children }) => {const [activeOption, setActiveOption] = useState(null);return (<SelectContext.Provider value={{ activeOption, setActiveOption }}>{children}</SelectContext.Provider>);
};const Option = ({ value, children }) => {const context = useContext(SelectContext);if (!context) {throw new Error("Option必须在Select组件内使用。");}const { activeOption, setActiveOption } = context;return (<divstyle={activeOption === value ? { backgroundColor: "black" } : { backgroundColor: "white" }}onClick={() => setActiveOption(value)}><p>{children}</p></div>);
};// 将"Option"作为"Select"的静态属性附加。
Select.Option = Option;export default function App() {return (<Select><Select.Option value="john">John</Select.Option><Select.Option value="bella">Bella</Select.Option></Select>);
}

在上面的示例中,select 组件是一个复合组件。它由多个共享状态和行为的组件组成。我们使用「Select.Option」 =「Option」将「Option」和「Select」组件链接起来。现在,导入「Select」组件会自动包含「Option」组件。

优点

  • 复合组件维护其内部状态,这些状态在子组件之间共享。因此,在使用复合组件时无需显式管理状态。
  • 无需手动导入子组件。

缺点

  • 使用「React.Children.map」传递值时,组件堆叠受到限制。只有父组件的直接子组件才能访问 props。
  • 如果现有的 prop 与提供给「React.cloneElement」方法的 props 同名,可能会出现命名冲突。

5. Hooks 模式

React Hooks API 在 React 16.8 中引入,从根本上改变了我们处理 React 组件设计的方式。Hooks 是为了解决 React 开发者遇到的常见问题而开发的。它们通过允许函数组件访问状态、生命周期方法、上下文和 refs 等特性,彻底改变了我们编写 React 组件的方式,这些特性以前是类组件独有的。

useState
useState 钩子使得函数组件能够添加状态。它返回一个包含两个元素的数组:当前状态值和允许你更新它的函数。

import React, { useState } from "react";function ToggleButton() {const [isToggled, setIsToggled] = useState(false);const toggle = () => {setIsToggled(!isToggled);};return (<div><p>切换状态:{isToggled ? "ON" : "OFF"}</p><button onClick={toggle}>{isToggled ? "关闭" : "开启"}</button></div>);
}export default ToggleButton;

useEffect
useEffect 钩子便于在函数组件中执行副作用。它类似于类组件中的「componentDidMount」、「componentDidUpdate」和「componentWillUnmount」的组合。

import React, { useState, useEffect } from "react";function Example() {const [data, setData] = useState(null);useEffect(() => {const fetchData = async () => {try {const response = await fetch("https://jsonplaceholder.typicode.com/posts");const jsonData = await response.json();setData(jsonData);} catch (error) {console.error("获取数据错误:", error);}};fetchData();}, []);return (<div>{data ? (<div><h2>数据获取成功!</h2><ul>{data.map((item, index) => (<li key={index}>{JSON.stringify(item)}</li>))}</ul></div>) : (<p>正在加载数据...</p>)}</div>);
}export default Example;

useRef

useRef 返回一个可变的 ref 对象,其 current 属性被初始化为传递的参数。这个对象在整个组件的生命周期内持续存在。

import React, { useRef } from "react";function InputWithFocusButton() {const inputRef = useRef(null);const focusInput = () => {inputRef.current.focus();};return (<div><input ref={inputRef} type="text" /><button onClick={focusInput}>聚焦输入</button></div>);
}export default InputWithFocusButton;

优点

  • 组织代码,使其整洁清晰,不像生命周期方法那样。
  • 克服了维护挑战,利用热重载和压缩问题。
  • 允许在不编写类的情况下利用状态和其他 React 功能。
  • 促进了跨组件重用有状态逻辑,减少代码重复。
  • 减少了错误的可能性,并使用简单函数实现组合。

缺点

  • 需要遵守特定规则,尽管没有 linter 插件很难识别规则违规。
  • 需要实践才能有效使用某些钩子(例如,useEffect)。
  • 需要小心避免不当使用(例如,useCallback,useMemo)。

相关文章:

React 设计模式:实用指南

React 提供了众多出色的特性以及丰富的设计模式&#xff0c;用于简化开发流程。开发者能够借助 React 组件设计模式&#xff0c;降低开发时间以及编码的工作量。此外&#xff0c;这些模式让 React 开发者能够构建出成果更显著、性能更优越的各类应用程序。 本文将会为您介绍五…...

在rtthread中,scons构建时,它是怎么知道是从rtconfig.h找宏定义,而不是从其他头文件找?

在rtthread源码中&#xff0c;每一个bsp芯片板级目录下都有一个 SConstruct scons构建脚本的入口&#xff0c; 在这里把rtthread tools/目录下的所有模块都添加到了系统路径中&#xff1a; 在tools下所有模块中&#xff0c;最重要的是building.py模块&#xff0c;在此脚本里面…...

寒假2.6--SQL注入之布尔盲注

知识点 原理&#xff1a;通过发送不同的SQL查询来观察应用程序的响应&#xff0c;进而判断查询的真假&#xff0c;并逐步推断出有用的信息 适用情况&#xff1a;一个界面存在注入&#xff0c;但是没有显示位&#xff0c;没有SQL语句执行错误信息&#xff0c;通常用于在无法直接…...

嵌入式面试题 C/C++常见面试题整理_7

一.什么函数不能声明为虚函数? 常见的不能声明为虚函数的有:普通函数(非成员函数):静态成员函数;内联成员函数;构造函数;友元函数。 1.为什么C不支持普通函数为虚函数?普通函数(非成员函数)只能被overload&#xff0c;不能被override&#xff0c;声明为虚函数也没有什么意思…...

说一下 Tcp 粘包是怎么产生的?

TCP 粘包是什么&#xff1f; TCP 粘包&#xff08;TCP Packet Merging&#xff09; 是指多个小的数据包在 TCP 传输过程中被合并在一起&#xff0c;接收方读取时无法正确分辨数据边界&#xff0c;导致数据解析错误。 TCP 是流式协议&#xff0c;没有数据包的概念&#xff0c;…...

基于STM32设计的仓库环境监测与预警系统

目录 项目开发背景设计实现的功能项目硬件模块组成设计思路系统功能总结使用的模块的技术详情介绍总结 1. 项目开发背景 随着工业化和现代化的进程&#xff0c;尤其是在制造业、食品业、医药业等行业&#xff0c;仓库环境的监控和管理成为了至关重要的一环。尤其是在存储易腐…...

在uniapp中修改打包路径

在uniapp中修改打包路径&#xff0c;主要涉及到对manifest.json文件的编辑。以下是详细的步骤&#xff1a; 1. 确定当前uniapp项目的打包配置位置 uniapp项目的打包配置通常位于项目的根目录下的manifest.json文件中。这个文件包含了项目的全局配置信息&#xff0c;包括应用的…...

Kali Linux 渗透测试环境配置(Metasploit + Burp Suite)

一、Kali Linux 系统准备 首先&#xff0c;确保你已经成功安装了 Kali Linux 系统。可以从官方网站下载镜像文件&#xff0c;并通过 U 盘引导安装等常规方式完成系统部署。建议使用最新稳定版本&#xff0c;以获取最新的软件包支持和安全更新。 安装完成后&#xff0c;登录系…...

Oracle 变更redo log文件位置

更改Oracle数据库的Redo log文件位置&#xff0c;可以按照以下步骤操作。 1.查询当前Redo log文件信息 select * from v$log; select * from v$logfile;通过查询结果可知Redo log文件放在/oradata/redofile 目录下。 2.拷贝redo log文件到新的位置/Data/redolog $cd /orada…...

力扣题库第495题目解析

文章目录 1.题目再现2.思路分析&&示例说明2.1第一个示例2.2第二个示例 3.代码解释 1.题目再现 这个题目的名字叫做提莫攻击&#xff0c;如果是玩游戏的小伙伴对于这个场景就很熟悉了&#xff1b; 这个实际上是说&#xff1a;已知的条件会给我们一个数组&#xff0c;在…...

Milvus 存储设计揭秘:从数据写入到 Segment 管理的全链路解析

作为一款云原生向量数据库&#xff0c;Milvus 的高效查询性能有赖于其独特的存储架构设计。然而&#xff0c;在实际使用过程中&#xff0c;许多社区用户常常会遇到以下问题&#xff1a; 为什么频繁调用 flush 后&#xff0c;查询速度会变慢&#xff1f; 数据删除后&#xff0c;…...

单片机通讯中的时序图:初学者的入门指南

一、什么是时序图&#xff1f; 在单片机的世界里&#xff0c;时序图是一种非常重要的工具&#xff0c;它用于描述信号在时间上的变化规律。简单来说&#xff0c;时序图就像是信号的“时间线”&#xff0c;它展示了各个信号线在不同时间点上的电平状态。通过时序图&#xff0c;我…...

ASP.NET Core JWT

目录 Session的缺点 JWT&#xff08;Json Web Token&#xff09; 优点&#xff1a; 登录流程 JWT的基本使用 生成JWT 解码JWT 用JwtSecurityTokenHandler对JWT解码 注意 Session的缺点 对于分布式集群环境&#xff0c;Session数据保存在服务器内存中就不合适了&#…...

Linux基础命令之Nginx中的rewrite功能(重新)

一、什么是Rewrite Rewrite也称URL Rewrite&#xff0c;即URL重写&#xff0c;就是把传入Web的请求重定向到其他URL的过程。 1. URL Rewrite最常见的应用是URL伪静态化&#xff0c;是将动态页面显示为静态页面方式的一种技术。比如http://www.123.com/news/index.php?id123 使…...

4 前端前置技术(上):AJAX技术、Axios技术(前端发送请求)

文章目录 前言一、Ajax技术&#xff08;从服务端获取数据&#xff0c;发送各种请求&#xff09;0 接口文档管理&#xff1a;使用apipost等接口测试软件创建接口便于前端后端分离测试1 基本概念2 原生Ajax使用示例&#xff08;几年前的早期用法&#xff09; 二、 Axios技术(对原…...

三星手机为何不大力扩展中国市场?

三星在中国市场的手机销量长期低迷&#xff0c;主要原因可以归结为以下几点&#xff0c;这也解释了为什么三星可能没有大力扩展中国市场的计划&#xff1a; 1. 市场竞争激烈 中国市场已经被华为、OPPO、vivo、小米和苹果等品牌牢牢占据&#xff0c;这些品牌在产品设计、本地化…...

Linux在x86环境下制作ARM镜像包

在x86环境下制作ARM镜像包&#xff08;如qemu.docker&#xff09;&#xff0c;可以通过QEMU和Docker的结合来实现。以下是详细的步骤&#xff1a; 安装QEMU-user-static QEMU-user-static是一个静态编译的QEMU二进制文件&#xff0c;用于在非目标架构上运行目标架构的二进制文…...

【算法篇】贪心算法

目录 贪心算法 贪心算法实际应用 一&#xff0c;零钱找回问题 二&#xff0c;活动选择问题 三&#xff0c;分数背包问题 将数组和减半的最小操作次数 最大数 贪心算法 贪心算法&#xff0c;是一种在每一步选择中都采取当前状态下的最优策略&#xff0c;期望得到全局最优…...

硬件电路基础

目录 1. 电学基础 1.1 原子 1.2 电压 1.3 电流 1.电流方向&#xff1a; 正极->负极,正电荷定向移动方向为电流方向&#xff0c;与电子定向移动方向相反。 2.电荷&#xff08;这里表示负电荷&#xff09;运动方向&#xff1a; 与电流方向相反 1.4 测电压的时候 2. 地线…...

iOS 音频录制、播放与格式转换

iOS 音频录制、播放与格式转换:基于 AVFoundation 和 FFmpegKit 的实现 在 iOS 开发中,音频处理是一个非常常见的需求,比如录音、播放音频、音频格式转换等。本文将详细解读一段基于 AVFoundation 和 FFmpegKit 的代码,展示如何实现音频录制、播放以及 PCM 和 AAC 格式之间…...

探索前端框架的未来:Svelte 的崛起

引言 在前端开发的世界里&#xff0c;框架更新换代的速度仿佛光速。从 jQuery 到 Angular&#xff0c;再到如今大热的 React 和 Vue&#xff0c;开发者们不断追逐更轻量、更快、更易于维护的框架。如今&#xff0c;Svelte 正悄然崛起&#xff0c;并引发了关于前端框架未来的热烈…...

Gitea+Gridea 创建个人博客

历史文档存档&#xff0c;该方法目前已经无法使用&#xff0c;部署方法可供参考 Gitea部分 1.关于Gitea Gitea 是一个面向开源及私有软件项目的托管平台&#xff0c;是全球最大的代码托管平台之一。它采用 Git 分布式版本控制系统&#xff0c;为开发者提供了代码托管、版本控…...

DeepSeek-V3:开源多模态大模型的突破与未来

目录 引言 一、DeepSeek-V3 的概述 1.1 什么是 DeepSeek-V3&#xff1f; 1.2 DeepSeek-V3 的定位 二、DeepSeek-V3 的核心特性 2.1 多模态能力 2.2 开源与可扩展性 2.3 高性能与高效训练 2.4 多语言支持 2.5 安全与伦理 三、DeepSeek-V3 的技术架构 3.1 模型架构 3…...

通过制作docker镜像的方式在阿里云部署前端后台服务

前端Dockerfile文件的内容&#xff1a; FROM nginx:版本&#xff0c;如果不指定&#xff0c;默认是latest COPY dist/ /usr/share/nginx/html/dist COPY nginx.conf /etc/nginx/nginx.conf EXPOSE 端口 前端sh脚本文件内容&#xff1a; appName项目名 tar -xvf dist.tar …...

无界构建微前端?NO!NO!NO!多系统融合思路!

文章目录 微前端理解1、微前端概念2、微前端特性3、微前端方案a、iframeb、qiankun --> 使用比较复杂 --> 自己写对vite的插件c、micro-app --> 京东开发 --> 对vite支持更拉跨d、EMP 方案--> 必须使用 webpack5 --> 很多人感觉不是微前端 --> 去中心化方…...

Linux(CentOS)安装 Nginx

CentOS版本&#xff1a;CentOS 7 Nginx版本&#xff1a;1.24.0 两种安装方式&#xff1a; 一、通过 yum 安装&#xff0c;最简单&#xff0c;一键安装&#xff0c;全程无忧。 二、通过编译源码包安装&#xff0c;需具备配置相关操作。 最后附&#xff1a;设置 Nginx 服务开…...

【提示词工程】探索大语言模型的参数设置:优化提示词交互的技巧

在与大语言模型(Large Language Model, LLM)进行交互时,提示词的设计和参数设置直接影响生成内容的质量和效果。无论是通过 API 调用还是直接使用模型,掌握模型的参数配置方法都至关重要。本文将为您详细解析常见的参数设置及其应用场景,帮助您更高效地利用大语言模型。 …...

GNN多任务预测模型实现(二):将EXCEL数据转换为图数据

目录 一. 引言 二. 加载和检查数据 三. 提取特征和标签 四. 标准化特征 五. 构建节点索引 六. 构建边及其特征 七. 总结 八. 结语 一. 引言 在图神经网络&#xff08;Graph Neural Networks, GNNs&#xff09;的多任务学习场景中&#xff0c;数据预处理是至关重要的一…...

.net的一些知识点6

1.写个Lazy<T>的单例模式 public class SingleInstance{private static readonly Lazy<SingleInstance> instance new Lazy<SingleInstance>(() > new SingleInstance());private SingleInstance(){}public static SingleInstance Instace > instance…...

Java 线程池:7参数配置、4拒绝策略与执行流程详解

1. 为什么需要线程池&#xff1f; 在 Java 并发编程中&#xff0c;线程的创建和销毁是一项昂贵的操作。频繁地创建和销毁线程会带来较高的系统开销&#xff0c;甚至可能因线程数过多而导致 OOM&#xff08;OutOfMemoryError&#xff09; 或 CPU 过载。 线程池&#xff08;Thre…...

SQL带外注入

SQL 带外注入&#xff08;Out-of-Band SQL Injection, OOB SQLi&#xff09; 是 SQL 注入的一种特殊类型&#xff0c;主要用于以下情况&#xff1a; 数据库没有直接返回错误信息&#xff08;比如被防火墙拦截了&#xff09;。无法使用常规注入手法&#xff08;如 UNION、错误信…...

MySQL知识点总结(一)

1.SQL分类 数据定义&#xff08;DDL&#xff09;:创/改/删/名/清&#xff08;cadrt&#xff09; 数据库对象&#xff1a;表/视图/存储/函数/触发器/事件 数据操作&#xff08;DML&#xff09;&#xff1a;增/删/改/查&#xff08;idus&#xff09; 操作数据库对象 数据控制&…...

【报错解决】MySQL报错:sql_mode=only_full_group_by

文章目录 报错信息 DataGrip 报错还原Navicat 报错还原 报错原因解决方案 查看当前 sql mode方案一&#xff1a;临时解决方案二&#xff1a;永久解决方案三&#xff1a;使用 any_value() 或 group_concat()方案四&#xff1a;调整实现思路&#xff0c;避开 GROUP BY 使用 我…...

【华为OD机考】华为OD笔试真题解析(1)--AI处理器组合

一、题目描述 某公司研发了一款高性能AI处理器&#xff0c;每台物理设备具备8颗AI处理器&#xff0c;编号分别为0、1、2、3、4、5、6、7。 编号0~3的处理器处于同一链路中&#xff0c;编号4~7的处理器处于另外一个链路中&#xff0c;不同链路中的处理器不能通信&#xff0c;如…...

【redis】缓存设计规范

本文是 Redis 键值设计的 14 个核心规范与最佳实践&#xff0c;按重要程度分层说明&#xff1a; 一、通用数据类型选择 这里我们先给出常规的选择路径图。 以下是对每个步骤的分析&#xff1a; 是否需要排序&#xff1f;&#xff1a; zset&#xff08;有序集合&#xff09;用…...

Node.js 实现简单爬虫

介绍 爬虫是一种按照一定的规则&#xff0c;自动地抓取万维网信息的程序或者脚本。 本文将使用 Nodejs 编写一个简单的爬虫脚本&#xff0c;爬取一个美食网站&#xff0c;获取菜品的标题和图片链接&#xff0c;并以表格的形式输出。 准备工作 1、初始化项目 首先&#xff0…...

一次奇怪的空指针问题分析:事务、死锁与隐式回滚

最近我们在排查一个诡异的 空指针异常&#xff0c;整个分析过程可以说是跌宕起伏&#xff0c;最终的结论也颇具隐蔽性。今天就把这个问题分享出来&#xff0c;希望对大家有所帮助。 问题现象 在系统中&#xff0c;我们有 单据 B&#xff0c;它通过一个 关联 ID 字段与 上级单…...

数据结构-基础

1、概念&#xff1a; 程序 数据结构 算法 2、程序的好坏 可读性&#xff0c;稳定性&#xff0c;扩展性&#xff0c;时间复杂度&#xff0c;空间复杂度。 3、数据结构 是指存储、组织数据的方式&#xff0c;以便高效地进行访问和修改。通过选择适当的数据结构&#xff0c; 能…...

问题大集04-浏览器阻止从 本地 发起的跨域请求,因为服务器的响应头 Access-Control-Allow-Origin 设置为通配符 *

1、问题 localhost/:1 Access to XMLHttpRequest at xxx&#xff08;请求&#xff09; from origin http://localhost:xxx&#xff08;本地&#xff09; has been blocked by CORS policy: The value of the Access-Control-Allow-Origin header in the response must not be t…...

音频进阶学习十二——Z变换一(Z变换、收敛域、性质与定理)

文章目录 前言一、Z变换1.Z变换的作用2.Z变换公式3.Z的状态表示1&#xff09; r 1 r1 r12&#xff09; 0 < r < 1 0<r<1 0<r<13&#xff09; r > 1 r>1 r>1 4.关于Z的解释 二、收敛域1.收敛域的定义2.收敛域的表示方式3.ROC的分析1&#xff09;当 …...

leetcode——组合总和(回溯算法详细讲解)

在面试或刷题过程中&#xff0c;回溯算法是一个绕不开的核心算法之一。今天&#xff0c;我们来详细解析 LeetCode 39「组合总和」 问题&#xff0c;并用 Java 回溯 剪枝优化 来高效解决它&#xff01;这篇文章不仅适合初学者&#xff0c;也适合希望提高回溯算法的朋友们。 给你…...

说一下JVM管理的常见参数

Java虚拟机&#xff08;JVM&#xff09;有许多常见参数&#xff0c;用于控制其行为和性能。以下是一些常见的JVM参数及其说明&#xff1a; 1. 内存管理参数 -Xms<size> START 设置初始堆内存大小。例如&#xff0c;-Xms512m表示初始堆大小为512MB。 -Xmx<size>…...

leetcode_47全排列II

1. 题意 给一个含有重复数字的数组&#xff0c;求不重复的排列。 2. 题解 将数组进行排序&#xff0c;当回溯发生的时候&#xff0c;找到下个不重复的元素即可。 class Solution { public:void genPerm(std::vector<std::vector<int>> &ans, std::vector&l…...

pytest-xdist 进行多进程并发测试!

在软件开发过程中&#xff0c;测试是确保代码质量和可靠性的关键步骤。随着项目规模的扩大和复杂性的增加&#xff0c;测试用例的执行效率变得尤为重要。为了加速测试过程&#xff0c;特别是对于一些可以并行执行的测试用 例&#xff0c;pytest-xdist 提供了一种强大的工具&…...

【CPP】CPP经典面试题

文章目录 引言1. C 基础1.1 C 中的 const 关键字1.2 C 中的 static 关键字 2. 内存管理2.1 C 中的 new 和 delete2.2 内存泄漏 3. 面向对象编程3.1 继承和多态3.2 多重继承 4. 模板和泛型编程4.1 函数模板4.2 类模板 5. STL 和标准库5.1 容器5.2 迭代器 6. 高级特性6.1 移动语义…...

STM32的HAL库开发---通用定时器(TIMER)---定时器脉冲计数

一、脉冲计数实验原理 1、 外部时钟模式1&#xff1a;核心为蓝色部分的时基单元&#xff0c;时基单元的时钟源可以来自四种&#xff0c;分别是内部时钟PCLK、外部时钟模式1&#xff0c;外部时钟模式2、内部定时器触发&#xff08;级联&#xff09;。而脉冲计数就是使用外部时钟…...

在C#中,Array,List,ArrayList,Dictionary,Hashtable,SortList,Stack的区别

Array Array你可以理解为是所有数组的大哥 普通数组 : 特点是长度固定, 只能存储相同类型的数据 static void Main(string[] args){//声明int[] ints;string[] strings;People[] peoples;//默认值 //int 类型是 0//string 类型是 nullint[] ints1 { 1, 2, 3 };string[] …...

Ollama 部署本地大语言模型

一、下载安装ollama 1.百度 ollama Ollama 2.点击下载 可以复制下载链接&#xff0c;使用下载器下载。 3.双击安装 默认安装目录&#xff1a;C:\Users\用户名\AppData\Local\Programs\Ollama 二、更改模型下载目录 0.默认下载目录 (跳过) 之前没下载过模型&#xff0c;不…...

sql批量更新和删除语句

1.更新一条数据 update om_sellorder set SOSTATUS2 where id 283d3eb87b134e1c993b70b018406285 2.更新多个数据为某一个特点值 string ID context.Request["ID"]; //需要替换‘,’逗号&#xff0c;不然识别不出ID数据这里注意 ‘ID’ 是一个逗号&#xff08;&a…...

探索从传统检索增强生成(RAG)到缓存增强生成(CAG)的转变

在人工智能快速发展的当下&#xff0c;大型语言模型&#xff08;LLMs&#xff09;已成为众多应用的核心技术。检索增强生成&#xff08;RAG&#xff09;&#xff08;RAG 系统从 POC 到生产应用&#xff1a;全面解析与实践指南&#xff09;和缓存增强生成&#xff08;CAG&#x…...