Rust并发编程实践:10分钟入门系统级编程
目录
学前一问:Rust为何而出现?
摘要
引言
正文解析:
一、Rust中的并发编程基础
1.1 线程
1.2 协程
二、Rust并发编程的高级特性
2.1 通道
2.2 原子操作
2.3 锁
三、实例展示:优化并发编程性能
1. 并行计算
2. 异步IO
3. 数据并行
四、并发编程的挑战与最佳实践
结论:
参考文献:
学前一问:Rust为何而出现?
Rust是一门现代的系统编程语言,它的设计目标是提供安全性、并发性和高性能。Rust的出现是为了解决其他编程语言在这些方面存在的一些问题和挑战。下面是一些导致Rust出现的主要原因:
内存安全问题:传统的系统编程语言(如C和C++)给程序员提供了灵活性和低级控制能力,但也容易导致内存安全问题,如空指针引用、缓冲区溢出和数据竞争。这些问题可能导致程序崩溃、安全漏洞甚至恶意攻击。Rust通过引入所有权、借用和生命周期的概念,以及静态内存管理和线程安全性的保证,解决了这些问题,使得编写安全、可靠的系统级代码更加容易。
并发编程挑战:随着计算机系统的发展,多核处理器和并发编程变得越来越普遍。然而,传统的并发编程在处理共享数据和线程同步时存在困难,如数据竞争、死锁和饥饿等问题。Rust通过引入所有权和借用的概念,以及内置的线程安全性保证,使得编写并发程序更加安全和简单。
性能要求:系统级编程通常需要高性能和低级别的控制能力。然而,一些高级语言在性能方面存在一些限制,如垃圾回收开销、运行时开销等。Rust通过在编译时执行内存管理、零成本抽象和强大的优化能力,提供了与C/C++相媲美的性能,同时保持了高级语言的安全性和开发效率。
综上,Rust的出现是为了解决传统系统编程语言的安全性、并发性和性能方面的问题。它致力于成为一门现代化、安全性保证的系统编程语言,适用于各种应用领域,包括操作系统、嵌入式系统、网络服务和大规模分布式系统等。
摘要
Rust作为一门现代的系统级编程语言,提供了强大的并发编程能力。本文将介绍Rust中的并发编程概念,包括线程、协程和通道等核心概念,以及Rust提供的丰富的并发原语和工具。通过实例展示,我们将深入探讨如何在Rust中实现高效的并发编程,以提升程序的性能和响应速度。
引言
在当今多核处理器和分布式系统的时代,充分利用计算资源和实现高性能的并发编程成为了软件开发中的重要课题。Rust作为一门内存安全且具有高性能的编程语言,为开发者提供了丰富的并发编程工具和原语。通过正确地使用Rust的并发编程特性,我们能够编写出高效、安全且易于维护的并发代码。
正文解析:
一、Rust中的并发编程基础
1.1 线程
Rust通过标准库提供了对线程的支持,使得开发者能够创建和管理多线程程序。本节将介绍如何创建线程、线程间的通信和共享数据的安全性问题。
在Rust中,你可以使用标准库提供的std::thread
模块来创建和管理线程。要创建一个新线程,你可以使用std::thread::spawn
函数,并传递一个闭包作为新线程的入口点。下面是一个简单的例子:
use std::thread;fn main() {// 创建一个新线程let handle = thread::spawn(|| {// 在新线程中运行的代码println!("Hello from the new thread!");});// 在主线程中继续执行其他操作// 等待新线程结束handle.join().expect("Failed to join the thread");
}
在这个例子中,我们创建了一个新线程,并在闭包中输出一条消息。主线程继续执行其他操作,然后使用handle.join()
等待新线程结束。
线程间的通信可以使用消息传递或共享内存的方式实现。Rust提供了多种线程间通信的方式,包括通道(channel)和原子类型等。通过这些机制,你可以在多个线程之间安全地传递数据。
当多个线程同时访问和修改共享数据时,需要考虑线程安全性的问题。Rust通过所有权和借用系统来保证线程安全性。使用互斥锁(mutex)和原子类型,你可以在多个线程之间安全地共享数据。
1.2 协程
Rust的协程由async/await语法支持,通过异步编程模型实现轻量级的并发。我们将探讨Rust中的异步编程模型以及如何编写高效的异步代码。
Rust的协程(coroutine)通过异步编程模型来实现,并且使用async/await
语法进行编写。异步编程允许你在单个线程上同时执行多个任务,从而实现轻量级的并发。
在Rust中,协程的主要概念是Future
和async/await
。Future
是一个表示异步操作结果的类型,而async/await
则是用于编写异步代码的语法糖。
下面是一个简单的示例,展示了如何使用async/await
来编写异步函数:
async fn hello() {println!("Hello from the async function!");
}#[tokio::main]
async fn main() {// 调用异步函数hello().await;println!("Async code execution completed.");
}
在这个例子中,我们定义了一个异步函数hello
,并在main
函数中使用await
关键字来等待异步函数执行完成。
Rust的异步编程模型主要依赖于第三方库,如tokio
或async-std
。这些库提供了异步运行时和其他异步相关的工具,使得编写高效的异步代码变得简单。
二、Rust并发编程的高级特性
2.1 通道
Rust的标准库提供了多种实现并发通信的通道类型,如mpsc(多生产者单消费者)和spmc(单生产者多消费者)。我们将详细介绍这些通道的使用方法和适用场景。
在Rust中,标准库提供了两种通道类型:多生产者单消费者(MPSC)和单生产者多消费者(SPMC)。MPSC通道允许多个线程作为生产者,但只能有一个线程作为消费者。生产者可以通过通道发送消息,而消费者可以从通道接收消息。下面是一个简单的示例:
use std::sync::mpsc;
use std::thread;fn main() {// 创建一个MPSC通道let (sender, receiver) = mpsc::channel();// 创建多个生产者线程for i in 0..5 {let sender = sender.clone();thread::spawn(move || {sender.send(i).expect("Failed to send message");});}// 主线程作为消费者接收消息for _ in 0..5 {let received = receiver.recv().expect("Failed to receive message");println!("Received: {}", received);}
}
在这个例子中,我们创建了一个MPSC通道,并使用sender.clone()
克隆了发送端,每个生产者线程都持有一个发送端的克隆。每个线程通过send
方法发送一个数字,主线程作为消费者通过recv
方法接收消息并打印。
SPMC通道允许一个线程作为生产者,但可以有多个线程作为消费者。生产者可以通过通道发送消息,而消费者可以同时从通道接收消息。使用SPMC通道的示例与MPSC通道类似,只需将mpsc::channel()
替换为spmc::channel()
。
通道是一种有效的线程间通信机制,适用于生产者-消费者场景。MPSC通道适用于多个线程向单个消费者发送消息的情况,而SPMC通道适用于单个生产者向多个消费者发送消息的情况。
2.2 原子操作
Rust的原子操作类型提供了一种线程安全的方式来进行并发访问和修改共享数据。我们将讨论原子操作的使用方法和注意事项。
Rust的原子操作类型提供了线程安全的方式来进行并发访问和修改共享数据。原子操作是基于硬件提供的原子指令,可以确保操作的原子性,避免数据竞争。
标准库提供了一些原子操作类型,如AtomicBool
、AtomicI32
、AtomicUsize
等。这些类型具有原子性,可以被多个线程同时访问和修改。
下面是一个使用AtomicUsize
的简单示例:
use std::sync::atomic::{AtomicUsize, Ordering};
use std::thread;fn main() {// 创建一个原子计数器let counter = AtomicUsize::new(0);// 创建多个线程对计数器进行增加操作let mut handles = vec![];for _ in 0..5 {let counter = counter.clone();let handle = thread::spawn(move || {counter.fetch_add(1, Ordering::SeqCst);});handles.push(handle);}// 等待所有线程结束for handle in handles {handle.join().expect("Failed to join thread");}// 输出最终计数器的值println!("Counter: {}", counter.load(Ordering::SeqCst));
}
在这个例子中,我们创建了一个AtomicUsize
类型的原子计数器,并使用fetch_add
方法在多个线程中增加计数器的值。最后,我们使用load
方法获取计数器的最终值并打印。
使用原子操作类型可以有效地进行共享数据的并发访问和修改,避免了数据竞争和不一致的问题。
2.3 锁
Rust的Mutex和RwLock类型提供了对共享数据的安全访问机制。我们将介绍如何正确使用锁来保证多线程代码的正确性和性能。
Rust的Mutex和RwLock类型提供了对共享数据的安全访问机制。Mutex(互斥锁)允许一次只有一个线程访问数据,而RwLock(读写锁)允许多个线程同时读取数据,但只允许一个线程写入数据。
下面是一个使用Mutex
和RwLock
的简单示例:
use std::sync::{Mutex, RwLock};
use std::thread;fn main() {// 使用Mutex进行共享数据的访问let shared_data = Mutex::new(0);// 创建多个线程修改共享数据let mut handles = vec![];for _ in 0..5 {let shared_data = shared_data.clone();let handle = thread::spawn(move || {let mut data = shared_data.lock().unwrap();*data += 1;});handles.push(handle);}// 等待所有线程结束for handle in handles {handle.join().expect("Failed to join thread");}// 输出最终共享数据的值println!("Shared data: {}", *shared_data.lock().unwrap());// 使用RwLock进行共享数据的访问let shared_data = RwLock::new(0);// 创建多个线程读取共享数据let mut handles = vec![];for _ in 0..5 {let shared_data = shared_data.clone();let handle = thread::spawn(move || {let data = shared_data.read().unwrap();println!("Shared data: {}", *data);});handles.push(handle);}// 创建一个线程写入共享数据let handle = thread::spawn(move || {let mut data = shared_data.write().unwrap();*data = 42;});handles.push(handle);// 等待所有线程结束for handle in handles {handle.join().expect("Failed to join thread");}
}
在这个例子中,我们首先使用Mutex
创建了一个共享数据,并在多个线程中通过lock
方法获取互斥锁来修改数据。最后,我们使用lock
方法获取互斥锁来输出最终共享数据的值。
然后,我们使用RwLock
创建了另一个共享数据,并在多个线程中通过read
方法获取读取锁来并发读取数据。同时,我们创建了一个线程使用write
方法获取写入锁来修改数据。注意,RwLock
的写入操作是互斥的,因此在写入时会阻塞其他线程的读取。
使用锁是一种保证多线程代码正确性和安全性的常见方式。通过合理地使用Mutex
和RwLock
,你可以确保共享数据的访问顺序和一致性,避免数据竞争和不一致的问题。
三、实例展示:优化并发编程性能
通过实例展示,将深入探讨如何在Rust中优化并发编程性能。具体包括以下内容:
1. 并行计算
将演示如何使用Rust的并发编程特性来加速计算密集型任务,从而充分利用多核处理器的计算能力。
use std::sync::mpsc;
use std::thread;fn compute(data: Vec<i32>) -> i32 {// 这里是计算密集型任务的代码let result = data.iter().sum();result
}fn main() {let data = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];let num_threads = 4;let chunk_size = data.len() / num_threads;let (sender, receiver) = mpsc::channel();for i in 0..num_threads {let chunk = data[i * chunk_size..(i + 1) * chunk_size].to_vec();let sender = sender.clone();thread::spawn(move || {let result = compute(chunk);sender.send(result).unwrap();});}drop(sender);let final_result: i32 = receiver.iter().sum();println!("Final result: {}", final_result);
}
上述代码通过将数据集划分为多个块,并在不同的线程中计算每个块的部分结果。最后,通过通道将部分结果发送回主线程,并计算最终结果。
2. 异步IO
将展示如何使用Rust的异步编程模型来优化IO密集型任务,提高程序的响应速度和吞吐量。
use std::fs::File;
use std::io::{self, BufRead, BufReader};async fn process_line(line: String) {// 这里是处理每行数据的代码println!("Processing line: {}", line);
}async fn process_file(filename: &str) -> io::Result<()> {let file = File::open(filename)?;let reader = BufReader::new(file);let mut lines = reader.lines();while let Some(line) = lines.next_line().await? {process_line(line).await;}Ok(())
}#[tokio::main]
async fn main() -> io::Result<()> {let filename = "data.txt";process_file(filename).await?;Ok(())
}
上述代码使用异步IO模型处理文件的每一行数据。通过异步方式逐行读取文件,并在异步任务中处理每一行的数据。这样可以充分利用IO等待时间,提高程序的响应速度和吞吐量。
3. 数据并行
通过数据并行的方式,可以将大数据集划分为多个任务并行处理,提高程序的处理效率。我们将介绍如何在Rust中实现数据并行,并讨论其优缺点。
use rayon::prelude::*;fn process_data(data: &mut [i32]) {// 这里是每个数据块的处理代码data.iter_mut().for_each(|x| *x *= 2);
}fn main() {let mut data = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];let chunk_size = 4;data.par_chunks_mut(chunk_size).for_each(|chunk| {process_data(chunk);});println!("Processed data: {:?}", data);
}
上述代码使用Rayon库实现数据的并行处理。通过将数据集划分为多个块,并使用par_chunks_mut
方法并行地处理每个块的数据,从而提高程序的处理效率。
四、并发编程的挑战与最佳实践
并发编程不仅带来了性能提升,也引入了一些挑战和难点。本节将讨论在Rust中进行并发编程时可能遇到的问题,并提供一些最佳实践和解决方案。主要包括以下内容:
-
**共享数据的安全性:**在并发编程中,多个线程同时访问和修改共享数据可能导致数据竞争和并发安全问题。为了确保共享数据的安全性,可以使用互斥锁(Mutex)或读写锁(RwLock)来保护共享数据的访问。通过正确使用锁机制,可以避免多个线程同时修改数据,保证数据的一致性和正确性。
-
**死锁和饥饿:**死锁是指多个线程因为互相等待对方释放资源而无法继续执行的情况。饥饿是指某个线程由于其他线程的资源占用导致无法获得所需资源而无法执行的情况。为了避免死锁和饥饿,需要合理设计锁的获取和释放顺序,并避免线程之间出现循环依赖的资源获取关系。此外,可以使用超时机制或者避免使用过多的锁来提高程序的吞吐量和响应性能。
-
**调度器优化:**Rust的调度器对并发程序的性能起着重要作用。调度器决定了线程如何分配和利用系统资源。为了优化调度器的性能,可以考虑以下几点:合理设置线程的数量,避免创建过多的线程导致资源争用;使用线程池来重用线程,减少线程创建和销毁的开销;合理设置任务的调度策略,根据任务的特点选择合适的并发度和调度算法;使用异步编程模型来提高程序的并发性能,减少线程的上下文切换开销。
-
**错误处理和线程间通信:**并发编程中的错误处理和线程间通信也是需要考虑的重要方面。在处理错误时,可以使用Result和Option等类型来传递和处理错误信息。在线程间通信时,可以使用通道(Channel)或消息传递机制来实现线程之间的数据交换和同步。合理处理错误和进行有效的线程间通信可以提高程序的可靠性和性能。
-
**测试和调试:**并发程序的测试和调试是挑战性的任务。为了确保并发程序的正确性,可以使用各种测试工具和技术,如单元测试、集成测试、模拟器等。此外,可以使用调试工具来分析并发程序的执行过程,定位问题和性能瓶颈。
结论:
Rust提供了丰富的并发编程原语和工具,使得开发者能够轻松编写高效的并发代码。通过正确地使用Rust的并发编程特性,我们能够提升程序的性能和响应速度,并充分利用计算资源。然而,并发编程也带来了一些挑战,需要开发者谨慎处理共享数据的安全性和避免常见的并发问题。通过学习并实践本文介绍的并发编程概念和最佳实践,我们可以在Rust中编写出高效、安全且易于维护的并发代码。
参考文献:
[1] Rust Documentation: Concurrency -Fearless Concurrency - The Rust Programming Language
[2] The Rustonomicon: Fearless Concurrency -Introduction - The Rustonomicon
[3] “Concurrency in Rust” by Aaron Turon -Aaron Turon’s tech blog · Aaron Turon
相关文章:
Rust并发编程实践:10分钟入门系统级编程
目录 学前一问:Rust为何而出现? 摘要 引言 正文解析: 一、Rust中的并发编程基础 1.1 线程 1.2 协程 二、Rust并发编程的高级特性 2.1 通道 2.2 原子操作 2.3 锁 三、实例展示:优化并发编程性能 1. 并行计算 2. 异步…...
Linux 命令大全完整版(06)
2. 系统设置命令 pwunconv 功能说明:关闭用户的投影密码。语法:pwunconv补充说明:执行 pwunconv 指令可以关闭用户投影密码,它会把密码从 shadow 文件内,重回存到 passwd 文件里。 rdate(receive date) 功能说明&a…...
VSCode 中设置 Git 忽略仅因时间戳修改导致的文件变更【使用deepseek生成的一篇文章】
在 VSCode 中设置 Git 忽略仅因时间戳修改导致的文件变更,可通过以下步骤实现: 确认是否为纯时间戳修改 首先确认文件的修改是否仅涉及时间戳,使用终端运行: git diff -- <file>若输出为空但 Git 仍提示修改,可…...
echarts找不到了?echarts社区最新地址
前言:在之前使用echarts的时候,还可以通过上边的导航栏找到echarts社区,但是如今的echarts变更之后,就找不到echarts社区了。 ✨✨✨这里是秋刀鱼不做梦的BLOG ✨✨✨想要了解更多内容可以访问我的主页秋刀鱼不做梦-CSDN博客 如今…...
Git-速查
Git 安装 Git 之后,你可以… 配置全局用户信息(推荐) 全局设置,创建本地仓库时默认分支名称为 main(你需要什么名称就该什么名称)【推荐配置为 main 】 git config --global init.defaultBranch main全…...
AxiosError: Network Error
不知怎么的,项目还在开发阶段,之前还好好的,玩儿了两天再一打开发现页面无法显示数据了,报错如下: 我以为是后端出问题了,但是后端控制台无报错,又用postman测试了一下,可以获取到数…...
ImGui 学习笔记(三)—— 隐藏主窗口窗口关闭检测
ImGui 的主窗口是平台窗口,默认是可见的,这会影响视觉效果。那么怎么隐藏 ImGui 的主窗口呢? 这很简单,但是需要针对后端做一些修改。 本文仅介绍在 glfwopengl3 和 win32dx11 两种实现上如何修改。 在 win32dx11 实现上&#…...
周末总结(2024/02/22)
工作 人际关系核心实践: 要学会随时回应别人的善意,执行时间控制在5分钟以内 坚持每天早会打招呼 遇到接不住的话题时拉低自己,抬高别人(无阴阳气息) 朋友圈点赞控制在5min以内,职场社交不要放在5min以外 职场的人际关系在面对利…...
SOME/IP--协议英文原文讲解11
前言 SOME/IP协议越来越多的用于汽车电子行业中,关于协议详细完全的中文资料却没有,所以我将结合工作经验并对照英文原版协议做一系列的文章。基本分三大块: 1. SOME/IP协议讲解 2. SOME/IP-SD协议讲解 3. python/C举例调试讲解 4.2.6 Er…...
Spring Boot 概要(官网文档解读)
Spring Boot 概述 Spring Boot 是一个高效构建 Spring 生产级应用的脚手架工具,它简化了基于 Spring 框架的开发过程。 Spring Boot 也是一个“构件组装门户”,何为构件组装门户呢?所谓的“构件组装门户”指的是一个对外提供的Web平台&#x…...
图像处理篇---图像处理中常见参数
文章目录 前言一、分贝(dB)的原理1.公式 二、峰值信噪比(PSNR, Peak Signal-to-Noise Ratio)1.用途2.公式3.示例 三、信噪比(SNR, Signal-to-Noise Ratio)1.用途2.公式3.示例 四、动态范围(Dyna…...
Win11更新系统c盘爆满处理
1.打开磁盘管理 2.右击c盘选择属性,进行磁盘管理,选择详细信息。 3.选择以前安装的文件删除即可释放c盘空间。...
C++关键字之mutable
1.介绍 在C中,mutable是一个关键字,用于修饰类的成员变量。它的主要作用是允许在常量成员函数或常量对象中修改被标记为mutable的成员变量。通常情况下,常量成员函数不能修改类的成员变量,但有些情况下,某些成员变量的…...
vue3 采用xlsx库实现本地上传excel文件,前端解析为Json数据
需求:本地上传excel 文件,但需要对excel 文件的内容进行解析,然后展示出来 1. 安装依赖 首先,确保安装了 xlsx 库: bash复制 npm install xlsx 2. 创建 Vue 组件 创建一个 Vue 组件(如 ExcelUpload.v…...
【Linux系统】—— 冯诺依曼体系结构与操作系统初理解
【Linux系统】—— 冯诺依曼体系结构与操作系统初理解 1 冯诺依曼体系结构1.1 基本概念理解1.2 CPU只和内存打交道1.3 为什么冯诺依曼是这种结构1.4 理解数据流动 2 操作系统2.1 什么是操作系统2.2 设计OS的目的2.3 操作系统小知识点2.4 如何理解"管理"2.5 系统调用和…...
易语言模拟真人鼠标轨迹算法 - 防止游戏检测
一.简介 鼠标轨迹算法是一种模拟人类鼠标操作的程序,它能够模拟出自然而真实的鼠标移动路径。 鼠标轨迹算法的底层实现采用C/C语言,原因在于C/C提供了高性能的执行能力和直接访问操作系统底层资源的能力。 鼠标轨迹算法具有以下优势: 模拟…...
PHP旅游门票预订系统小程序源码
🌍 旅游门票预订系统:一站式畅游新体验,开启您的梦幻旅程 🌟 一款基于ThinkPHPUniapp精心雕琢的旅游门票预订系统,正翘首以待,为您揭开便捷、高效、全面的旅游预订新篇章!它超越了传统预订平台…...
侯捷 C++ 课程学习笔记:内存管理的每一层面
目录 一、C 应用程序的内存管理架构 二、C 内存原语 三、内存管理的实际应用 四、学习心得 一、C 应用程序的内存管理架构 C 应用程序的内存管理架构可以分为多个层次,从应用程序到操作系统 API,每一层都提供了不同的内存管理功能。 架构图…...
Python开发Django面试题及参考答案
目录 Django 的请求生命周期是怎样的? Django 的 MTV 架构中的各个组件分别是什么? Django 的 URL 路由是如何工作的? Django 的视图函数和视图类有什么区别? Django 的模板系统是如何渲染 HTML 的? Django 的 ORM 是如何工作的? Django 的中间件是什么?它的作用是…...
前端js进阶,ES6语法,包详细
进阶ES6 作用域的概念加深对js理解 let、const申明的变量,在花括号中会生成块作用域,而var就不会生成块作用域 作用域链本质上就是底层的变量查找机制 作用域链查找的规则是:优先查找当前作用域先把的变量,再依次逐级找父级作用域直到全局…...
【三十四周】文献阅读:DeepPose: 通过深度神经网络实现人类姿态估计
目录 摘要AbstractDeepPose: 通过深度神经网络实现人类姿态估计研究背景创新点方法论归一化网络结构级联细化流程 代码实践局限性实验结果总结 摘要 人体姿态估计旨在通过图像定位人体关节,是计算机视觉领域的核心问题之一。传统方法多基于局部检测与图模型&#x…...
将 Vue 项目打包后部署到 Spring Boot 项目中的全面指南
将 Vue 项目打包后部署到 Spring Boot 项目中的全面指南 在现代 Web 开发中,前后端分离架构已经成为主流。然而,在某些场景下,我们可能需要将前端项目(如 Vue)与后端项目(如 Spring Boot)集成部…...
Linux 权限系统和软件安装(二):深入理解 Linux 权限系统
在 Linux 的世界里,权限系统犹如一位忠诚的卫士,严密守护着系统中的文件与目录,确保只有具备相应权限的用户才能进行操作。与其他一些操作系统不同,Linux 并不依据文件后缀名来标识文件的操作权限,而是构建了一套独特且…...
计算机网络常考大题
运输层的主要功能 运输层为应用进程之间提供端到端的逻辑通信。 运输层还要对收到的报文进行差错检测。 运输层需要有两种不同的运输协议,即面向连接的 TCP 和无连接的 UDP 传输控制协议 TCP 概述 TCP 是面向连接的运输层协议。 每一条 TCP 连接只能有两个端点…...
百度首页上线 DeepSeek 入口,免费使用
大家好,我是小悟。 百度首页正式上线了 DeepSeek 入口,这一重磅消息瞬间在技术圈掀起了惊涛骇浪,各大平台都被刷爆了屏。 百度这次可太给力了,PC 端开放仅 1 小时,就有超千万人涌入体验。这速度,简直比火…...
《跟李沐学 AI》AlexNet论文逐段精读学习心得 | PyTorch 深度学习实战
前一篇文章,使用 AlexNet 实现图片分类 | PyTorch 深度学习实战 本系列文章 GitHub Repo: https://github.com/hailiang-wang/pytorch-get-started 本篇文章内容来自于学习 9年后重读深度学习奠基作之一:AlexNet【下】【论文精读】】的心得。 《跟李沐…...
Linux搭建Nginx直播流媒体服务RTMP/RTSP转Http-flv视频浏览器在线播放/Vue/Java/ffmpeg
参考文章: https://blog.csdn.net/whatareyouding/article/details/144317654 https://www.cnblogs.com/Gredae/p/18362900 https://www.cnblogs.com/kn-zheng/p/17422707.html https://blog.51cto.com/u_16099344/10281495 https://www.tulingxueyuan.cn/tlzx/jsp…...
Node.js高频面试题精选及参考答案
目录 什么是 Node.js?它的主要特点有哪些? Node.js 的事件驱动和非阻塞 I/O 模型是如何工作的? 为什么 Node.js 适合处理高并发场景? Node.js 与传统后端语言(如 Java、Python)相比,有哪些优势和劣势? 简述 Node.js 的运行原理,包括 V8 引擎的作用。 什么是 Nod…...
公开整理-最新中国城市统计NJExcel+PDF版本(1985-2024年)
数据简介:《中国城市统计NJ》从1985年开始,本NJ内容共分四个部分:第一部分是全国城市行政区划,列有不同区域、不同级别的城市分布情况;第二、三部分分别是地级以上城市统计资料和县级城市统计资料,具体包括人口、劳动力及土地资源、综合经济、工业、交通…...
ModuleNotFoundError: No module named ‘xgboost‘
问题: --------------------------------------------------------------------------- ModuleNotFoundError Traceback (most recent call last) Cell In[1], line 64 import pickle5 from sklearn.metrics import mean_squared_error, r2_…...
应用层协议HTTP
应用层协议HTTP 引言 应用层协议是程序员自己制定的,但是良好的协议是保证网络通信的基础,前代的计算工程师已经帮助我们制定了一些很好用的应用层协议,http(hybertext transfer protocol)(超文本传输协议)就是其中之一。 http协议是客户端…...
常见的“锁”有哪些?
悲观锁 悲观锁认为在并发环境中,数据随时可能被其他线程修改,因此在访问数据之前会先加锁,以防止其他线程对数据进行修改。常见的悲观锁实现有: 1.互斥锁 原理:互斥锁是一种最基本的锁类型,同一时间只允…...
PAT 甲级 1091 Acute Stroke
一开始只是简单的递归(bfs),导致最后两个没法通过(爆栈了) //最后两个案例没有通过,只是最简单的bfs暴力算法 #include<cstdio> using namespace std; int v[62][1288][130]{0}; int find(int i,int…...
flowable适配达梦数据库
文章目录 适配相关问题无法从数据库产品名称“DM DBMS”中推断数据库类型分析解决 构建ibatis SqlSessionFactory时出错:inStream参数为null分析解决 liquibase相关问题问题一:不支持的数据库 Error executing SQL call current_schema: 无法解析的成员访…...
Git入门:数据模型 to 底层原理
版本控制系统(VCS)是软件开发中不可或缺的工具,而Git作为现代版本控制的事实标准,其底层设计远比表面命令更加优雅。本文将从数据模型的角度,揭示Git的核心工作原理。 Git的核心概念 1. 快照(Snapshot&am…...
Bootstrap Blazor UI 中 <Table> 组件 <TableColumn> 使用备忘01:EF Core 外码处理
应用场景:将外码转换为对应的文本进行显示、编辑。 例如,有一个【用户】表,其中有一个【用户类型ID】字段;另有一个【用户类型】表,包含【ID】、【名称】等字段。现在要求在 <Table> 组件显示列表中,…...
Redis过期数据处理
Redis缓存过期后数据还能恢复吗? Redis缓存过期后,数据通常会被删除,但可以通过以下几种方法尝试恢复数据: 1. 数据备份恢复 RDB 持久化恢复:Redis 提供了 RDB(Redis Database Backup)持久化…...
零基础学C/C++160——字符串
题目描述 给定两个由小写字母组成的字符串A和B,判断B中的字符是否全部在A中出现。 输入 输入为多组测试数据。 输入数据只有一行,包含2个字符串A和B,每个字符串后面有一个#字符标记(#不属于A或B),其中B…...
Spring Boot+Vue项目从零入手
Spring BootVue项目从零入手 一、前期准备 在搭建spring bootvue项目前,我们首先要准备好开发环境,所需相关环境和软件如下: 1、node.js 检测安装成功的方法:node -v 2、vue 检测安装成功的方法:vue -V 3、Visu…...
Linux 命令大全完整版(13)
5.文件管理命令 patch 功能说明:修补文件。语 法:patch [-bceEflnNRstTuvZ][-B <备份字首字符串>][-d <工作目录>][-D <标示符号>][-F <监别列数>][-g <控制数值>][-i <修补文件>][-o <输出文件>][-p &l…...
MySQL面试学习
MySQL 1.事务 事务的4大特性 事务4大特性:原子性、一致性、隔离性、持久性 原⼦性: 事务是最⼩的执⾏单位,不允许分割。事务的原⼦性确保动作要么全部完成,要么全不执行一致性: 执⾏事务前后,数据保持⼀…...
CentOS中shell脚本对多台机器执行下载安装
1.建立免密ssh连接 详情见这篇: CentOS建立ssh免密连接(含流程剖析)-CSDN博客 2.脚本编写 我这里只是简单写了个demo进行演示,如果服务器很多可以先暂存成文件再逐行读取host进行连接并执行命令 用node1去ssh连接node2和node…...
【Java】多线程和高并发编程(四):阻塞队列(上)基础概念、ArrayBlockingQueue
文章目录 四、阻塞队列1、基础概念1.1 生产者消费者概念1.2 JUC阻塞队列的存取方法 2、ArrayBlockingQueue2.1 ArrayBlockingQueue的基本使用2.2 生产者方法实现原理2.2.1 ArrayBlockingQueue的常见属性2.2.2 add方法实现2.2.3 offer方法实现2.2.4 offer(time,unit)方法2.2.5 p…...
C语言多人聊天室 ---chat(客户端聊天)
head.h #ifndef __HEAD_H #define __HEAD_H// 常用头文件 #include <stdio.h> #include <stdlib.h> #include <string.h>// 网络编程涉及的头文件 #include <sys/socket.h> #include <netinet/in.h> #include <netinet/ip.h>#include <…...
设计模式教程:命令模式(Command Pattern)
1. 什么是命令模式? 命令模式(Command Pattern)是一种行为型设计模式。它将请求封装成一个对象,从而使你能够用不同的请求、队列和日志请求以及支持可撤销操作。 简单来说,命令模式通过把请求封装成对象的方式解耦了…...
【华三】STP的角色选举(一文讲透)
【华三】STP的角色选举 一、引言二、STP基础概念扫盲三、根桥选举过程详解四、根端口选举过程详解五、指定端口选举过程详解六、阻塞端口七、总结与配置建议七、附录**1. BPDU字段结构图(文字描述)****2. 华三STP常用命令速查表** 文章总结 一、引言 在…...
Trae+Qt+MSVC环境配置
Trae Trae是字节跳动基于VSCode推出的AI集成开发环境(IDE),是一款专为中文开发者深度定制的智能编程工具。其目标是通过AI技术实现从“Copilot”到“Autopilot”的编程模式演进。 类似这样的IDE比如Windsurf、Cursor,都是基于VS…...
SpringSecurity初始化的本质
一、对SpringSecurity初始化的几个疑问 通过前面第一次请求访问的分析我们明白了一个请求就来后的具体处理流程 对于一个请求到来后会通过FilterChainProxy来匹配一个对应的过滤器链来处理该请求。那么这里我们就有几个疑惑。 FilterChainProxy什么时候创建的?过滤器链和对应的…...
3D Gaussian Splatting(3DGS)的核心原理
3D Gaussian Splatting(3DGS)的核心原理 1. 基本概念 3D Gaussian Splatting(3DGS) 是一种基于 高斯分布的点云表示与渲染技术,核心思想是将三维场景建模为一系列 可学习的高斯分布,每个高斯分布具有以下…...
Transformers快速入门-学习笔记
一、自然语言处理 NLP 是借助计算机技术研究人类语言的科学自然语言处理发展史 一、不懂语法怎么理解语言 依靠语言学家人工总结文法规则 Chomsky Formal Languages 难点:上下文有关文法 规则增多,存在矛盾 二、只要看得足够多,就能处理语言…...