React 揭秘:从新手到高手的进阶之路
目录
React:前端开发新宠
React 初相识
什么是 React
React 的核心特性
1.组件化开发
2.虚拟 DOM 与 Diff 算法
单向数据流
搭建 React 开发环境
环境准备
创建 React 项目
项目结构解析
React 基础语法与核心概念
JSX 语法
基本语法规则
属性与表达式
注意事项
React 组件
函数式组件
类组件
组件通信
状态管理(State)
状态的定义与初始化
状态更新
函数式组件中的状态(Hooks)
React:前端开发新宠
在当今的前端开发领域,React 已然成为了一颗耀眼的明星,备受开发者们的青睐。它由 Facebook 开发并开源,自诞生以来,便以其独特的理念和强大的功能,迅速改变了前端开发的格局 ,成为构建现代用户界面的首选工具之一。无论是大型企业级应用,还是小型创业项目,React 都展现出了卓越的适应性和强大的生命力。那么,React 究竟有何魅力,能让众多开发者为之倾心呢?接下来,就让我们一同深入探索 React 的世界,揭开它神秘的面纱。
React 初相识
什么是 React
React 是一个用于构建用户界面的 JavaScript 库,它采用了一种声明式的编程风格,让开发者可以用简洁直观的方式描述用户界面的结构和行为。React 的核心思想是将用户界面拆分成一个个独立的、可复用的组件,每个组件都有自己的状态和逻辑,通过组合这些组件来构建复杂的应用程序 。它由 Facebook 开发并开源,如今已经成为了前端开发领域中最受欢迎和广泛使用的库之一。
React 的核心特性
1.组件化开发
在 React 中,组件是构建用户界面的基本单元,就像是搭建积木一样,我们可以将一个个小的组件组合起来,构建出复杂的页面。以一个简单的按钮组件为例,我们可以这样定义:
import React from 'react';// 定义一个Button组件
const Button = (props) => {return <button onClick={props.onClick}>{props.label}</button>;
};export default Button;
在上述代码中,我们定义了一个名为 Button 的函数组件,它接受两个属性:onClick和label。onClick是按钮的点击事件处理函数,label是按钮上显示的文本。通过这种方式,我们将按钮的功能和样式封装在了一个组件中,在其他地方使用这个按钮时,只需要传入相应的属性即可。
组件化开发的优势在于:
1.代码复用:减少重复代码,提高开发效率。比如,我们在多个页面中都需要使用一个按钮,只需要定义一次Button组件,然后在不同的页面中引入即可。
2.易于维护:每个组件都有自己独立的逻辑和状态,当某个组件出现问题时,我们可以快速定位和修复,而不会影响到其他组件。
3.可扩展性:随着应用程序的不断发展,我们可以方便地添加新的组件,或者对现有组件进行修改和扩展。
2.虚拟 DOM 与 Diff 算法
虚拟 DOM(Virtual DOM)是 React 的另一个重要特性。在传统的前端开发中,当数据发生变化时,我们需要直接操作真实的 DOM,这会导致浏览器频繁地重新渲染页面,从而影响性能。而 React 引入了虚拟 DOM 的概念,它在内存中维护一个与真实 DOM 对应的虚拟树,当数据发生变化时,React 会先计算虚拟 DOM 的差异,然后再将这些差异一次性更新到真实 DOM 上,从而大大减少了对真实 DOM 的直接操作,提高了应用的性能。
Diff 算法是 React 用于计算虚拟 DOM 差异的算法。它的核心思想是通过对比新旧虚拟 DOM 树,找出最小的变化集,然后只更新这些变化的部分。下面是一个简单的例子,展示了 Diff 算法的工作原理:
import React, { useState } from'react';const List = () => {const [items, setItems] = useState([1, 2, 3]);const addItem = () => {setItems([...items, items.length + 1]);};return (<div><ul>{items.map(item => (<li key={item}>{item}</li>))}</ul><button onClick={addItem}>添加项目</button></div>);
};export default List;
在上述代码中,我们定义了一个List组件,它包含一个列表和一个按钮。当点击按钮时,会向列表中添加一个新的项目。在这个过程中,React 会使用 Diff 算法来计算虚拟 DOM 的差异,只更新新增的列表项,而不会重新渲染整个列表,从而提高了页面的渲染效率。
单向数据流
单向数据流是 React 的数据管理方式。在 React 中,数据从父组件流向子组件,子组件只能接收父组件传递过来的数据,而不能直接修改这些数据。如果子组件需要修改数据,需要通过回调函数通知父组件,由父组件来更新数据,然后再将新的数据传递给子组件。这种数据流动方式使得数据的流向更加清晰,易于调试和维护。
以下是一个父子组件数据传递的示例:
import React, { useState } from'react';// 子组件
const Child = ({ count, increment }) => {return (<div><p>计数: {count}</p><button onClick={increment}>增加计数</button></div>);
};// 父组件
const Parent = () => {const [count, setCount] = useState(0);const incrementCount = () => {setCount(count + 1);};return (<div><Child count={count} increment={incrementCount} /></div>);
};export default Parent;
在上述代码中,Parent组件通过count和incrementCount两个属性将数据和回调函数传递给Child组件。Child组件可以通过count属性读取数据,通过increment回调函数通知父组件更新数据。这种单向数据流的设计使得组件之间的依赖关系更加明确,降低了组件之间的耦合度。
搭建 React 开发环境
环境准备
在开始 React 开发之前,我们需要确保开发环境中安装了 Node.js 和 npm(Node Package Manager)。Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行时,它允许我们在服务器端运行 JavaScript 代码 。npm 是 Node.js 的包管理器,用于安装和管理项目所需的依赖包。
你可以通过以下步骤安装 Node.js 和 npm:
1.下载安装包:访问 Node.js 官方网站(Node.js — Run JavaScript Everywhere),根据你的操作系统下载对应的安装包。
2.安装 Node.js:运行下载的安装包,按照安装向导的提示完成安装。在安装过程中,npm 会自动被安装。
3.验证安装:打开命令行工具,输入node -v和npm -v,如果显示出版本号,则说明安装成功。例如:
$ node -v
v18.12.1
$ npm -v
8.19.2
Node.js 和 npm 对于 React 开发至关重要。Node.js 提供了运行 React 应用所需的 JavaScript 环境,而 npm 则用于安装 React 及其相关的依赖包,如 React Router、Redux 等。通过 npm,我们可以轻松地管理项目的依赖关系,确保项目在不同环境中能够稳定运行。
创建 React 项目
为了快速创建一个 React 项目,我们可以使用 Create React App,它是一个官方提供的脚手架工具,用于快速搭建 React 应用的基础架构。
使用 Create React App 创建新项目的步骤如下:
1.打开命令行工具:在你希望创建项目的目录下,打开命令行工具(如 Windows 下的命令提示符或 PowerShell,Mac 下的终端)。
2.运行创建项目命令:输入以下命令来创建一个名为my - react - app的项目(你可以将my - react - app替换为你想要的项目名称):
npx create-react-app my-react-app
npx是 npm 5.2 及以上版本自带的命令,用于运行 npm 包中的可执行文件。这里,它会自动下载并运行create - react - app,创建一个新的 React 项目。
3. 等待项目创建完成:命令执行后,create - react - app会自动下载并安装项目所需的依赖包,这个过程可能需要一些时间,具体取决于你的网络速度。
4. 进入项目目录:项目创建完成后,进入项目目录:
cd my-react-app
5.启动项目:在项目目录下,运行以下命令启动开发服务器:
npm start
执行npm start后,开发服务器会启动,并自动打开浏览器,访问http://localhost:3000,你将看到一个默认的 React 应用界面,这表明你的 React 项目已经成功创建并运行。
项目结构解析
当我们使用 Create React App 创建一个 React 项目后,项目的目录结构如下:
my-react-app
├── node_modules
├── public
│ ├── favicon.ico
│ ├── index.html
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── robots.txt
├── src
│ ├── App.css
│ ├── App.js
│ ├── App.test.js
│ ├── index.css
│ ├── index.js
│ ├── logo.svg
│ ├── reportWebVitals.js
│ └── setupTests.js
├── .gitignore
├── package-lock.json
├── package.json
└── README.md
下面我们来详细解释各文件和文件夹的作用:
- node_modules:该目录包含了项目的所有依赖包,由 npm 自动管理。在项目中,我们一般不需要手动修改这个目录。
- public:该目录存放静态资源,如 HTML 文件、图标等。其中,index.html是 React 应用的入口 HTML 文件,它提供了一个基本的 HTML 结构,React 应用最终会被渲染到这个文件中的root节点上。favicon.ico是网站的图标,manifest.json用于配置渐进式 Web 应用(PWA)的相关信息,robots.txt用于控制搜索引擎爬虫的行为。
- src:这是我们开发的主要目录,存放所有的 React 组件、样式和其他资源。其中,index.js是项目的入口文件,它负责渲染 React 应用的根组件到index.html中的root节点上。App.js是应用的主要组件,通常包含应用的主要逻辑和布局。App.css用于定义App.js组件的样式。index.css是全局样式文件。App.test.js用于编写App.js组件的测试用例,reportWebVitals.js用于报告应用的性能指标,setupTests.js用于配置测试环境。
- .gitignore:该文件用于指定哪些文件和目录不需要被 Git 版本控制系统追踪,例如node_modules目录通常会被忽略,以避免将庞大的依赖包上传到版本库中。
- package.json:这是项目的配置文件,包含了项目的元数据、依赖包信息、脚本命令等。例如,我们可以在scripts字段中定义各种脚本命令,如start用于启动开发服务器,build用于打包生产环境代码等。dependencies字段列出了项目运行时所依赖的包,devDependencies字段列出了项目开发时所依赖的包。
- package - lock.json:该文件用于锁定依赖包的版本,确保在不同环境中安装的依赖包版本一致,避免因版本差异导致的兼容性问题。
- README.md:这是项目的说明文档,用于记录项目的基本信息、使用方法、安装步骤等,方便其他开发者了解和使用项目。
React 基础语法与核心概念
JSX 语法
基本语法规则
JSX(JavaScript XML)是一种 JavaScript 的语法扩展,它允许我们在 JavaScript 代码中直接编写类似 HTML 的代码。React 使用 JSX 来描述用户界面,它可以很好地描述 UI 应该呈现出的交互本质形式,并且能和 JavaScript 完美融合。例如:
const element = <h1>Hello, React!</h1>;
在上述代码中,我们使用 JSX 创建了一个<h1>元素,它看起来就像普通的 HTML 标签,但实际上它是一个 JavaScript 表达式。在编译时,JSX 会被转换为React.createElement函数调用,上述代码等价于:
const element = React.createElement('h1', null, 'Hello, React!');
这种转换使得我们可以在 JavaScript 中更直观地构建用户界面,同时利用 JavaScript 的强大功能来动态生成和操作 UI。
属性与表达式
在 JSX 中,我们可以像在 HTML 中一样设置元素的属性。例如,为<img>标签设置src和alt属性:
const imgUrl = 'https://example.com/image.jpg';
const imgAlt = '示例图片';const imageElement = <img src={imgUrl} alt={imgAlt} />;
注意,当属性值是一个 JavaScript 表达式时,我们需要使用大括号{}将其包裹起来。这里的src={imgUrl}和alt={imgAlt},imgUrl和imgAlt都是 JavaScript 变量,它们的值会在运行时被计算并赋值给相应的属性。
除了属性,我们还可以在 JSX 中使用 JavaScript 表达式来动态生成内容。例如,使用三元运算符根据条件渲染不同的内容:
const isLoggedIn = true;const greetingElement = (<div>{isLoggedIn ? <p>欢迎回来!</p> : <p>请登录。</p>}</div>
);
在上述代码中,根据isLoggedIn的值,greetingElement会渲染不同的<p>元素。
注意事项
使用 JSX 时,有一些语法要求需要注意:
1.必须有一个根元素:JSX 中所有的元素必须包含在一个外层元素中,例如<div>、<section>等。如果不需要实际的 DOM 元素包裹,可以使用空标签<></>(也称为 React Fragment)。例如:
// 正确,使用div作为根元素
const validElement1 = (<div><p>段落1</p><p>段落2</p></div>
);// 正确,使用React Fragment作为根元素
const validElement2 = (<><p>段落1</p><p>段落2</p></>
);// 错误,没有根元素
const invalidElement = (<p>段落1</p><p>段落2</p>
);
2.标签必须闭合:在 JSX 中,所有标签都必须正确闭合,无论是单标签(如<img>、<input>)还是双标签(如<div></div>、<p></p>)。例如:
// 正确,单标签闭合
const validSingleTag = <input type="text" />;// 错误,单标签未闭合
const invalidSingleTag = <input type="text">;// 正确,双标签闭合
const validDoubleTag = <div><p>内容</p></div>;// 错误,双标签未闭合
const invalidDoubleTag = <div><p>内容</p>;
3.区分大小写:JSX 中标签和属性名是区分大小写的。一般来说,HTML 标签使用小写字母,而自定义组件使用大写字母开头。例如:
// 正确,HTML标签小写
const htmlElement = <div>这是一个div</div>;// 错误,HTML标签大写
const wrongHtmlElement = <DIV>这是错误的</DIV>;// 定义一个自定义组件
const MyComponent = () => {return <p>这是一个自定义组件</p>;
};// 正确,自定义组件大写
const customElement = <MyComponent />;// 错误,自定义组件小写
const wrongCustomElement = <myComponent />;
React 组件
函数式组件
函数式组件是定义 React 组件的一种简洁方式,它是一个普通的 JavaScript 函数,接收props(属性)作为参数,并返回一个 React 元素。例如,我们定义一个简单的函数式组件Welcome:
import React from'react';// 定义一个函数式组件
const Welcome = (props) => {return <p>欢迎,{props.name}!</p>;
};export default Welcome;
在上述代码中,Welcome组件接收一个props对象,其中包含name属性。组件通过props.name获取传入的名字,并渲染在<p>标签中。
使用函数式组件时,我们可以通过属性传递数据。例如,在另一个组件中使用Welcome组件:
import React from'react';
import Welcome from './Welcome';const App = () => {return (<div><Welcome name="张三" /></div>);
};export default App;
在App组件中,我们将name属性设置为"张三",并传递给Welcome组件,Welcome组件会显示"欢迎,张三!"。
类组件
类组件是基于 ES6 类的方式定义的 React 组件,它具有自己的状态(state)和生命周期方法。类组件需要继承React.Component类,并实现render方法来返回组件的 UI。下面是一个简单的类组件示例,实现一个计数器功能:
import React, { Component } from'react';class Counter extends Component {constructor(props) {super(props);// 初始化状态this.state = {count: 0};}// 定义一个方法用于更新状态increment = () => {this.setState({count: this.state.count + 1});};render() {return (<div><p>计数: {this.state.count}</p><button onClick={this.increment}>增加计数</button></div>);}
}export default Counter;
在上述代码中:
1.constructor方法是类的构造函数,用于初始化组件的状态和绑定方法。通过super(props)调用父类的构造函数,确保this.props正确初始化。
2.this.state用于定义组件的状态,这里初始化count为 0。
3.increment方法使用setState方法来更新状态,setState会触发组件的重新渲染,从而更新 UI。
4.render方法返回组件的 UI,展示当前的计数和一个按钮,点击按钮会调用increment方法增加计数。
组件通信
1.父子组件通信:在 React 中,父子组件通信是通过属性(props)来实现的。父组件可以将数据和方法通过 props 传递给子组件。例如:
import React, { useState } from'react';// 子组件
const Child = ({ count, increment }) => {return (<div><p>计数: {count}</p><button onClick={increment}>增加计数</button></div>);
};// 父组件
const Parent = () => {const [count, setCount] = useState(0);const incrementCount = () => {setCount(count + 1);};return (<div><Child count={count} increment={incrementCount} /></div>);
};export default Parent;
在上述代码中,Parent组件通过count属性将当前的计数值传递给Child组件,通过increment属性将incrementCount方法传递给Child组件。Child组件可以通过props.count读取计数值,通过props.increment调用父组件的方法来更新计数。
2.兄弟组件通信:兄弟组件之间不能直接通信,通常需要通过它们的共同父组件作为中介来实现通信。例如,有两个兄弟组件ComponentA和ComponentB,它们的父组件ParentComponent可以管理共享的状态,并将状态和更新状态的方法传递给两个子组件。以下是一个简单的示例:
import React, { useState } from'react';// 组件A
const ComponentA = ({ count, increment }) => {return (<div><p>组件A: {count}</p><button onClick={increment}>组件A增加计数</button></div>);
};// 组件B
const ComponentB = ({ count, increment }) => {return (<div><p>组件B: {count}</p><button onClick={increment}>组件B增加计数</button></div>);
};// 父组件
const ParentComponent = () => {const [count, setCount] = useState(0);const incrementCount = () => {setCount(count + 1);};return (<div><ComponentA count={count} increment={incrementCount} /><ComponentB count={count} increment={incrementCount} /></div>);
};export default ParentComponent;
在这个示例中,ParentComponent管理着count状态,并将count和incrementCount方法传递给ComponentA和ComponentB。当ComponentA或ComponentB中的按钮被点击时,都会调用incrementCount方法,从而更新共享的count状态,两个组件的 UI 也会相应更新。
状态管理(State)
状态的定义与初始化
在 React 类组件中,状态(state)是一个包含组件数据的 JavaScript 对象。状态的变化会触发组件的重新渲染,从而更新用户界面。通常在组件的构造函数中初始化状态。例如,我们创建一个简单的Toggle组件,用于切换一个开关的状态:
import React, { Component } from'react';class Toggle extends Component {constructor(props) {super(props);// 初始化状态,isOn为false表示开关关闭this.state = {isOn: false};}render() {return (<div><button>{this.state.isOn? '关闭' : '打开'}</button></div>);}
}export default Toggle;
在上述代码中,Toggle组件的state包含一个isOn属性,初始值为false。在render方法中,根据isOn的值来显示按钮上的文本。
状态更新
要更新组件的状态,我们使用setState方法。setState方法接受一个新的状态对象,并将其合并到当前状态中。React 会在状态更新后自动重新渲染组件。继续上面的Toggle组件示例,我们添加点击按钮切换状态的功能:
import React, { Component } from'react';class Toggle extends Component {constructor(props) {super(props);this.state = {isOn: false};// 绑定this,确保handleClick方法中的this指向组件实例this.handleClick = this.handleClick.bind(this);}handleClick() {// 使用setState更新状态this.setState((prevState) => ({isOn:!prevState.isOn}));}render() {return (<div><button onClick={this.handleClick}>{this.state.isOn? '关闭' : '打开'}</button></div>);}
}export default Toggle;
在上述代码中:
1.handleClick方法中使用setState来更新isOn状态。这里使用了函数形式的setState,它接受一个函数参数,该函数的参数prevState是上一个状态,返回值是新的状态。这样可以确保在状态更新依赖于前一个状态时,能得到正确的结果。
2.在constructor中,通过this.handleClick = this.handleClick.bind(this);将handleClick方法的this绑定到组件实例,因为在 React 中,事件处理函数中的this默认是未定义的,需要手动绑定。
需要注意的是,setState是异步的,React 可能会将多个setState调用合并为单个更新,以提高性能。因此,不要依赖于setState调用后立即获取最新的状态值。例如:
// 错误的做法,无法保证获取到最新的count值
this.setState({ count: this.state.count + 1 });
console.log(this.state.count); // 正确的做法,使用回调函数获取更新后的状态
this.setState({ count: this.state.count + 1 }, () => {console.log(this.state.count);
});
函数式组件中的状态(Hooks)
在 React 16.8 及以上版本中,函数式组件可以使用 Hooks 来管理状态。useState是一个常用的 Hook,它允许我们在函数式组件中添加状态。例如,我们将上面的Toggle组件用函数式组件和useState实现:
import React, { useState } from'react';const Toggle = () => {// 使用useState定义状态,isOn初始值为falseconst [isOn, setIsOn] = useState(false);const handleClick = () => {// 使用setIsOn更新状态setIsOn(!isOn);};return (<div><button onClick={handleClick}>{isOn? '关闭' : '打开'}</button></div>);
};export default Toggle;
在上述代码中:
1.const [isOn, setIsOn] = useState(false);使用useState定义了一个状态变量isOn,初始值为false,并返回一个更新状态的函数setIsOn。
2.handleClick函数中通过setIsOn(!isOn)来更新isOn状态。
3.与类组件中的setState不同,useState的更新函数setIsOn不会自动合并新的状态,而是直接替换旧的状态。如果需要合并状态,可以使用展开运算符(...)。例如:
const [obj, setObj] = useState({ key1: 'value1' });const updateObj = () => {setObj({...obj,key2: 'value2'});
};
相关文章:
React 揭秘:从新手到高手的进阶之路
目录 React:前端开发新宠 React 初相识 什么是 React React 的核心特性 1.组件化开发 2.虚拟 DOM 与 Diff 算法 单向数据流 搭建 React 开发环境 环境准备 创建 React 项目 项目结构解析 React 基础语法与核心概念 JSX 语法 基本语法规则…...
JAVA的内存图理解
目录 一、方法区1、类常量池2、静态常量池3、方法区过程 二、栈三、堆1、字符常量池2、堆内存图的绘制 java中内存可以分为 方法区、 堆、 栈、 程序计数器、 本地方法栈,其中比较中重要的是方法区、堆、栈。 一、方法区 1.方法区(Method Area&…...
k8s存储介绍(六)StorangeClass
一、Kubernetes 存储类(StorageClass)详解 1. 什么是 StorageClass? 在 Kubernetes 中,StorageClass(存储类)是一种用于动态创建 PersistentVolume(PV)的资源对象。它允许管理员根…...
SourceMap原理
点击查看原文 1 webpack中使用 详见 js的模块化-webpack打包示例 2 webpack的配置 const { resolve } require(path)module.exports {mode: development,devtool: source-map,entry: ./src/index.js,output: {path: resolve(__dirname, dist),filename: "bundle.js&q…...
硬件基础--14_电功率
电功率 电功率:指电流在单位时间内做的功(表示用电器消耗电能快慢的一个物理量)。 单位:瓦特(W),简称瓦。 公式:PUI(U为电压,单位为V,i为电流,单位为A,P为电功率,单位为W)。 单位换算:进位为1000ÿ…...
练习题:110
目录 Python题目 题目 题目分析 需求理解 关键知识点 实现思路分析 代码实现 代码解释 函数定义: 计算值的总和: 测试函数: 运行思路 结束语 Python题目 题目 定义一个函数,接受一个字典作为参数,返回字…...
Promise使用
Promise 是 JavaScript 中用于处理异步操作的一种对象,它代表了一个异步操作的最终完成(或失败)及其结果值。Promise 有三种状态: 1. pending(进行中):初始状态,既不是成功也不是失…...
心理咨询法律咨询预约咨询微信小程序系统源码独立部署
预约咨询微信小程序:基于ThinkPHPUniapp的全场景解决方案与SEO深度优化指南 在心理健康、医疗问诊、法律咨询等领域线上化需求激增的背景下,预约咨询微信小程序凭借其灵活部署、多场景适配与隐私安全保障,成为机构与从业者提升服务效率的核心…...
JavaFX基础- Button 的基本使用
说明 本文记录一下对Button的基本使用,包括但不限于 样式的设置,事件的监听等。 按钮样式的设置 方式一 : Java代码的方式 // 创建一个按钮Button button new Button("按钮");// 设置按钮的位置button.setLayoutX(50);button.set…...
Golang使用 ip2region 查询IP的地区信息
利用 ip2region 进行 IP 地址定位 import ("fmt""log""github.com/lionsoul2014/ip2region/binding/golang/xdb" )func main() {ip : "213.118.179.98"dbPath : ".\\cmd\\ip\\ip2region.xdb"// 1、初始化查询器//searcher,…...
阿里云数据学习20250327
课堂链接:阿里云培训中心 (aliyun.com) 一、课堂问题 (一)课时3 1.支持字符集的含义是什么...
RAG - 五大文档切分策略深度解析
文章目录 切分策略1. 固定大小分割(Fixed-Size Chunking)2. 滑动窗口分割(Sliding Window Chunking)3. 自然语言单元分割(Sentence/Paragraph Segmentation)4. 语义感知分割(Semantic-Aware Seg…...
软件测试之接口测试
🍅 点击文末小卡片 ,免费获取软件测试全套资料,资料在手,涨薪更快 接口测试定义 接口是前后端沟通的桥梁,是数据传输的通道,包括外部接口、内部接口。内部接口又包括:上层服务与下层服务接口ÿ…...
synchronized锁与lock锁的区别
引言 在学习多线程时,当时为了解决线程并发问题,曾有两种锁,一种是synchronized同步块,同步方法,一种就是Lock锁,那么这两种锁之间有什么区别?谁更好用呢? synchronized 同步方法…...
Open HarmonyOS 5.0 分布式软总线子系统 (DSoftBus) 详细设计与运行分析报告
1. HarmonyOS 5.0 与分布式软总线 (DSoftBus) 概述 1.1 HarmonyOS 5.0 架构概览 HarmonyOS 5.0,又称鸿蒙星河版,标志着操作系统架构的重大演进,其核心在于转向自研的微内核系统 1。此版本摒弃了先前版本中兼容安卓的双框架模式,全…...
蓝桥杯备考:多米诺骨牌
这道题要求上下方格子和之差要最小,其实就是算每个上下格子的差求和的最小值 这道题其实是动态规划01背包问题 我们直接按步骤做吧 step1:定义状态表示f[i][j]表示从1到i个编号的差值里选出刚好j个数的最小操作次数 step2:推导状态转移方程 如图这就是我们的状态…...
C++:allocator类(动态数组续)
1.为什么需要 allocator? 在 C 中,动态内存管理通常通过 new 和 delete 完成: int* p new int; // 分配内存 构造对象 delete p; // 析构对象 释放内存 但 new 和 delete 有两个问题: 耦合性:将内…...
Go语言手动内存对齐的四大场景与实践指南
Go语言手动内存对齐的四大场景与实践指南 引言:Go的内存对齐机制 Go语言通过编译器自动处理内存对齐问题,开发者通常无需关心底层细节。然而,在特定场景下,手动干预内存对齐是避免程序崩溃或数据错乱的必要操作。本文将深入探讨G…...
libva基础
Libva(Lib Video Acceleration)是一个开源的库,实现了 **VA-API**(Video Acceleration API),旨在为视频处理提供跨平台的硬件加速支持。 1、核心功能与作用 硬件加速抽象层:Libva 作为中间层&…...
如何在 AI 搜索引擎(GEO)霸屏曝光,快速提升知名度?
虽然大多数人仍然使用 Google 来寻找答案,但正在发生快速转变。ChatGPT、Copilot、Perplexity 和 DeepSeek 等 LLM 已成为主流。这主要是因为每个都有自己的免费和公共版本,并且总是有重大的质量改进。 许多人每天都使用这些工具来提问和搜索互联网&…...
Java入门知识总结——章节(二)
ps:本章主要讲数组、二维数组、变量 一、数组 数组是一个数据容器,可用来存储一批同类型的数据 🔑:注意 类也可以是一个类的数组 public class Main {public static class Student {String name;int age; // 移除 unsignedint…...
Python 序列构成的数组(元组不仅仅是不可变的列表)
元组不仅仅是不可变的列表 有些 Python 入门教程把元组称为“不可变列表”,然而这并没有完全概括 元组的特点。除了用作不可变的列表,它还可以用于没有字段名的记 录。鉴于后者常常被忽略,我们先来看看元组作为记录的功用。 元组和记录 元…...
OJ题:移动零
双指针法 c 语言实现 void moveZeroes(int* nums, int numsSize) {int dest,cur; //创建临时指针和目标指针destcur0;//出初始化while(cur<numsSize)//遍历{if(nums[cur]!0){swap(&nums[cur],&nums[dest]);cur;dest;}else{cur;}}} 思路是建立两个指针࿰…...
wait函数等待多个子进程
父进程等待多个子进程时可以使用 wait() 函数,但有一些要点需要注意,下面为你详细介绍相关内容。 可以使用 wait() 函数等待多个子进程的原理 wait() 函数会让调用它的父进程暂停执行,直到它的某个子进程结束,然后返回结束子进程…...
数据湖的数据存储与管理策略:构建高效的数据管理框架
数据湖的数据存储与管理策略:构建高效的数据管理框架 在大数据时代,数据湖作为存储和管理海量数据的关键技术,已经成为众多企业数字化转型的重要组成部分。数据湖的核心优势在于其能够支持结构化、半结构化和非结构化数据的存储,然而,随着数据量的增加和复杂度的提升,如…...
Linux进程管理之进程的概念、进程列表和详细的查看、进程各状态的含义
进程的概念 进程是程序执行的实例,在Linux中,每个进程都有一个唯一的PID(进程ID)。 查看当前系统中有哪些进程 在Linux系统中,查看当前运行的进程可以使用几个常用命令: ps - 显示当前进程的快照。常用选…...
3万字长文详解Android AIDL 接口设计
目录 第一章:AIDL 概述 1.1 什么是 AIDL?定义与核心作用 1.2 AIDL 的典型使用场景 第二章:AIDL 语法规则 2.1 支持的数据类型:从基础到高级 2.2 接口声明:写好通信的 “剧本” 2.3 方向标记:数据流向的 “交通灯” 第三章:AIDL 文件编写 3.1 创建 AIDL 文件:从…...
HFSS 使用入门
资源 下载资源: https://download.csdn.net/download/wangjun_huster/90547193 下载破解: https://download.csdn.net/download/wangjun_huster/90547551 安装 https://www.bilibili.com/list/ml3403866295?oid925751664&bvidBV1CT4y1u7LB 入门…...
精心整理-2024最新网络安全-信息安全全套资料(学习路线、教程笔记、工具软件、面试文档).zip
2024最新网络安全-信息安全全套资料(学习路线、教程笔记、工具软件、面试文档),视频教程文档资料共55GB。 一、网络安全-信息安全学习路线 0、网络安全-信息安全思维导图.jpg 1、网络安全大师课 V2024.pdf 2、网络安全行业白皮书.pdf 3、网络…...
RAG基建之PDF解析的“流水线”魔法之旅
将PDF文件和扫描图像等非结构化文档转换为结构化或半结构化格式是人工智能的关键部分。然而,由于PDF的复杂性和PDF解析任务的复杂性,这一过程显得神秘莫测。 在RAG(Retrieval-Augmented Generation)基建之PDF解析的“魔法”与“陷阱”中,我们介绍了PDF解析的主要任务,对现…...
leetcode刷题日记——跳跃游戏
[ 题目描述 ]: [ 思路 ]: 题目要求在给出的每次可移动最大步数中选择一个移动步数,如果有一种选择能达到终点就返回true,如果没有一种选择能够达到终点就返回false因为每次给出的最大步数不同,步数越大,…...
Scala 数组
Scala 数组 引言 Scala 作为一门多范式编程语言,融合了面向对象和函数式编程的特点。数组是编程语言中非常基础和常见的数据结构,在 Scala 中也不例外。本文将详细介绍 Scala 中的数组,包括其定义、操作以及在实际开发中的应用。 Scala 数…...
基于华为设备技术的端口类型详解
以下是基于华为设备技术网页的端口类型详解(截至2025年3月): 一、Access端口 定义:仅允许单个VLAN通过,用于连接终端设备(如PC、打印机) 处理流程: 接收帧:未带标签…...
使用 Go 和 Gin 实现高可用负载均衡代理服务器
前言 在现代分布式系统中,负载均衡是保障服务高可用性和性能的核心技术。本文将基于 Go 语言和 Gin 框架实现一个支持动态路由、健康检查、会话保持等特性的企业级负载均衡代理服务器,并提供完整的压力测试方案和优化建议。 通过本方案实现的负载均衡代理具备以下优势: 单…...
零基础驯服GitHub Pages
各位互联网流浪汉、赛博吉普赛人、以及不小心点进来的产品经理们!今天我们要用程序员的方式搞点大事情——不写代码、不买服务器、不氪金,免费拥有一个能吹牛的个人网站!准备好你的键盘和表情包收藏夹,我们的奇幻漂流开始了&#…...
OpenBMC:BmcWeb 生效路由5 优化trie
OpenBMC:BmcWeb 生效路由4 将路由添加到Trie中-CSDN博客 在url被添加到trie中后,validate的最后一步是优化trie void validate() {for (std::unique_ptr<BaseRule>& rule : allRules){if (rule){std::unique_ptr<BaseRule> upgraded = rule->upgrade();if…...
买卖股票的最佳时机(121)
121. 买卖股票的最佳时机 - 力扣(LeetCode) 解法: class Solution { public:int maxProfit(vector<int>& prices) {int cur_min prices[0];int max_profit 0;for (int i 1; i < prices.size(); i) {if (prices[i] > cur…...
强大的AI网站推荐(第四集)—— Gamma
网站:Gamma 号称:展示创意的新媒介 博主评价:快速展示创意,重点是展示,在几秒钟内快速生成幻灯片、网站、文档等内容 推荐指数:🌟🌟🌟🌟🌟&#x…...
Business Trip and Business Travel
Business Trip and Business Travel References Background I would like to introduce the background. Dave is going on a business trip, but he’s very busy, so he needs Leo’s help to buy the plane ticket. Panda is an agent of China Eastern /ˈiːstərn/ Airl…...
为pip设置国内镜像源
pip设置国内镜像源 在Python中使用pip安装软件包时,通常我们会遇到网络问题,尤其是在中国大陆地区。为了解决这个问题我们可以使用一些国内提供的镜像源。下面以清华大学的镜像源为例进行使用说明。 方法一:临时使用 在命令行中࿰…...
MySQL查询成本计算
对于如上SQL,只是因为查询字段不同,最终执行时选择的索引就不同,那么MySQL是如何决定选择使用哪个索引呢? 答案是MySQL会进行成本计算,对于各个场景查询进行成本预估,最终选择最优。 我们可以使用trace工具…...
使用 rsync 进行服务器文件同步与优化
使用 Rsync 工具在两台 Linux 服务器之间同步文件 Rsync 是一种高效的文件同步工具,它可以在本地或远程服务器之间同步文件和目录。Rsync 通过仅传输文件的变化部分来减少数据传输量,因此特别适合用于定期备份或同步大量数据。本文将详细介绍如何将 A 服…...
java面向对象从入门到入土
面向对象进阶 (写程序的套路) 面向:拿,找 对象:能干活的东西 面向对象编程:拿东西过来做对应的事情 (写程序的套路) 面向:拿,找 对象:能干活的东西 面向对象编程:拿东西过来做对应的事情 重点学习:学习已有对象并使用,学习如何自己设计对象并使用 设计对…...
Redis设计与实现-哨兵
哨兵模式 1、启动并初始化sentinel1.1 初始化服务器1.2 使用Sentinel代码1.3 初始化sentinel状态1.4 初始化sentinel状态的master属性1.5 创建连向主服务器的网络连接 2、获取主服务器信息3、获取从服务器的信息4、向主从服务器发送信息5、接受主从服务器的频道信息6、检测主观…...
vscode 打开工程 看不到文件目录
vscode 打开工程 看不到文件目录 View->Explorer 快捷键:CtrlShiftE...
[c++项目]基于微服务的聊天室服务端测试
项目概述 本测试报告针对基于C实现的微服务架构聊天室服务端进行全面测试。系统主要包含以下微服务: 用户认证服务(Auth Service)消息处理服务(Message Service)在线状态服务(Presence Service࿰…...
Java面试黄金宝典16
1. 各种排序算法的时间复杂度和空间复杂度 冒泡排序 定义: 冒泡排序是一种简单的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来。走访数列的工作是重复地进行直到没有再需要交换,…...
pytorch中dataloader自定义数据集
前言 在深度学习中我们需要使用自己的数据集做训练,因此需要将自定义的数据和标签加载到pytorch里面的dataloader里,也就是自实现一个dataloader。 数据集处理 以花卉识别项目为例,我们分别做出图片的训练集和测试集,训练集的标…...
LabVIEW 燃气轮机气路故障诊断
在船用燃气轮机气路故障诊断领域,LabVIEW 软件以其独特的功能和优势,成为构建高效、精准诊断系统的关键技术支撑。它全面覆盖硬件在环仿真平台的各个环节,从硬件连接、数据交互到系统功能实现,都发挥着不可替代的作用,…...
[项目]基于FreeRTOS的STM32四轴飞行器: 十六.激光测距定高功能
基于FreeRTOS的STM32四轴飞行器: 十六.激光测距定高功能 一.芯片介绍二.配置CubeMX三.激光测距芯片驱动编写四.定高PID的计算五.定高PID作用到电机上 一.芯片介绍 激光测高芯片在飞控板下侧: 原理图如下: 型号为:VL53LX1,为国产…...