《Rust权威指南》学习笔记(五)
高级特性
1.在Rust中,unsafe是一种允许绕过Rust的安全性保证的机制,用于执行一些Rust默认情况下不允许的操作。unsafe存在的原因是:unsafe 允许执行某些可能被 Rust 的安全性检查阻止的操作,从而可以进行性能优化,如手动内存管理和优化特定的底层操作;在系统级编程中,通常需要直接操作硬件或底层资源,这些操作超出了 Rust 的安全模型的范围,unsafe 提供了一种方式来实现这些操作;在与不安全的代码库(例如 C 库)进行集成时,unsafe 使得可以调用这些库函数,虽然需要保证这些调用的安全性;允许开发者在受控的、已知的环境中使用不安全的操作,同时通过安全的 API 封装这些操作,确保整个程序的安全性。unsafe并没有关闭借用检查或停用其他安全检查,任何内存相关的错误必须留在unsafe块里,应尽量隔离unsafe代码,最好将其封装在安全的抽象里面,提供安全的API。unsafe块允许执行以下的操作:1解引用原始指针(裸指针):原始指针可以在其他地方创建但只能在unsafe块中使用,原始指针分为可变的*mut T和不可变的*const T(不可变意味着指针在解引用后不能直接对其赋值),此处*是类型名不是解引用,与引用不同,原始指针允许同时存在指向同个位置位置的可变指针来忽略借用规则,原始指针无法保证能指向合理的内存,且允许为null,原始指针不实现任何的自动清理。示例如下:
通过原始指针可以实现与C语言进行接口,构建借用检查器无法理解的安全抽象;2调用unsafe函数或方法:不安全的函数和方法调用是指在 Rust 中标记为 unsafe 的函数或方法,它们可能执行绕过 Rust 安全检查的操作,因此调用时必须在 unsafe 块中进行,以确保开发者意识到潜在风险并手动保证安全性。函数包含unsafe块代码并不意味着需要将整个函数标记为unsafe,将unsafe代码包裹在安全函数中是一个常见的抽象。如下图所示:
可以使用extern关键字调用其他语言的函数或从其他语言调用Rust函数,供其他语言调用的Rust函数需要在fn前面加上extern关键字,还要添加#[no_mangle]注解,避免Rust在编译时改变函数名称,如下图所示:
3访问或修改一个静态变量:在Rust中,静态变量(static变量)是具有'static生命周期的全局变量,这意味着它们在程序的整个运行期间都存在,静态变量可以在程序的任何地方访问,无论是主函数、子函数,还是多个线程之间。静态变量在程序的内存中占有固定位置,通常用于存储不变的数据或需要跨越多个函数或线程访问的数据。Rust中全局变量只能是静态变量,全局的数据还可以是常量const,他俩的区别是:const在编译时求值、不占用内存且总是不可变;static在运行时分配内存,具有'static生命周期,可用static mut使其可变。访问不可变静态变量是安全的,访问和修改可变静态变量是不安全的,不可变静态变量可以在程序的任何地方安全地访问,可变的静态变量 (static mut) 只能在unsafe块中访问。静态变量的名称通常使用全大写字母,如果静态变量的名称由多个单词组成,通常使用下划线_进行分隔。如下图所示:
4实现不安全的trait:当某个trait存在至少一个方法拥有编译器无法校验的不安全因素时,就称这个trait是不安全的,对于不安全的trait需在其前面加上unsafe声明,不安全的trait只能在unsafe块中实现,如下图所示:
2.Self和self的区别:在Rust中,Self代表当前类型,用于类型级别的操作,通常出现在实现构造函数、trait方法以及关联类型时,它表示与当前实现的类型相同的类型,可以在返回类型或关联类型中使用。例如,在impl块中,Self就等同于实现该impl块的具体类型。self则是方法的第一个参数,用于表示当前实例。它在实例方法中使用,用于访问和修改该实例的数据。根据需要,self可以通过值传递(self)、不可变引用(&self)、或可变引用(&mut 0self)的方式传递。
3.关联类型则是在trait中定义的一种占位符类型,具体类型由实现该trait的类型在实现过程中指定。如下图所示:
这种设计可以使trait的接口更简洁,因为使用者不需要在每次调用时都指定类型。关联类型尤其适用于涉及多个相关类型的trait,实现者可以为这些类型设置特定的关系,从而增强trait的表达力和易用性。泛型允许为不同类型多次实现同一个trait,如下图所示:
而关联类型在trait中占位且只能由具体实现者指定具体类型,因此在大多数情况下,一个关联类型只能为一个trait提供唯一的实现。
4.Rust中类型的三种变体(Variance):1协变(covariant):某类型只能用其“子类型”替代。例如,&'static T可以替代&'a T。这是因为'static生命周期比'a长,所以&'static T可以安全地用在需要&'a T的地方;2不变(invariant):类型必须严格提供指定的类型,不能有任何变动。例如,&mut T对于T来说是不变的,意味着必须严格匹配T的类型,不能使用其子类型或超类型;3逆变(contravariant):函数对参数的要求越低,参数可以发挥的作用越大。逆变指的是在某些上下文中,父类型可以替代子类型。逆变通常在函数参数中体现,如果一个函数能够接受一个更一般的类型作为参数,那么这个函数在子类中仍然有效。
5.可以在使用泛型参数时为泛型指定一个默认的具体类型,如标准库中Add定义,其中Rhs=Self表示默认的另一个操作数的类型与函数调用者类型相同:
这种技术通常用于运算符重载,可以在具体实现时不使用默认类型,而重新提供一个类型,如下图:
6.当结构体自身以及结构体实现的接口中都含有同名函数,默认调用的是结构体中的函数,想要调用接口中的函数,可使用下图中的方式:
其中&person指明了是哪个具体类型实现的接口中的函数,但如果这些函数中并没有传入&self,这样调用就会报错了,因为编译器无法知道该调用哪个类型对应的接口实现中的函数,此时可以使用完全限定语法来调用这些同名方法,格式为:<Type as Trait>::function(receiver_if_method,next_arg,…);,如下图所示:
7.可以使用supertrait来要求trait附带其它trait的功能,但需要被依赖的trait也被实现,否则会报错,那个被间接依赖的trait就是当前trait的supertrait,类似于其他语言中继承的概念,如下图所示:
8.可以使用type关键字创建类型别名,如下图所示:
有一个!的特殊类型,称为Never类型,他没有任何值,它在不返回值的函数中充当返回类,如无限循环、抛出错误、或其他导致函数退出的场景,不返回值的函数又称作发散函数。
9.孤儿规则(Orphan Rule)规定了一个trait可以被实现的前提是,trait或实现中的至少一个必须在当前crate中定义,以避免不同crate之间的冲突。但可以使用newtype模式在外部类型上实现外部trait,即利用元组结构体创建一个新的类型,如下图所示,fmt::Display和Vec<String>都是外部的:
Newtype模式通过封装现有类型创建新的类型,优点包括增加类型安全、封装数据、以及扩展功能。它通过定义一个包含现有类型的结构体来实现,这样可以控制对底层数据的访问,同时允许为新类型实现额外的功能或trait。动态大小(Dynamic Size)指的是在编译时无法确定大小的类型,这些类型的大小在程序运行时确定,而不是在编译时,如str类型。Sized trait是一个标记trait,用于指示某个类型的大小在编译时是已知的。默认情况下,Rust中的所有类型都实现了Sized trait,除非它们明确被声明为动态大小类型(DST)。T:?Sized是一个trait bound,用来表示T可以是定长的类型(Sized)或者不定长的类型(?Sized)。这通常用于泛型函数或结构体中,使得它们能够处理不定长类型。宽指针(FatPointer)是Rust中一种包含额外元数据的指针类型,用于引用不定长(?Sized)类型。宽指针不仅包含数据的内存地址,还包括额外的信息,如长度或虚表指针。常见的宽指针包括引用切片(&[T]或&str)和特征对象(&dynTrait)。对于切片,宽指针存储了指向数据的指针和长度;对于特征对象,宽指针存储了数据指针和指向虚表的指针,以便在运行时调用方法。
10.函数指针:可以将函数作为参数传递给其他函数,函数在传递过程中会被强制转换为fn类型,fn类型就是函数指针,如下图所示:
11.Rust中的宏主要分为两类:声明宏和过程宏。声明宏是最常见的一类宏,通过使用 macro_rules!进行定义。它们类似于函数,但操作的是代码而非数据,通常用于生成重复的代码模式。如下图:
过程宏允许通过编写函数来生成代码,它们比声明宏更为灵活和强大,能够进行复杂的代码生成和分析。过程宏可以分为三种类型:自定义派生宏允许为结构体或枚举自动生成代码,通常用于自动实现某些 trait,例如 Debug、Clone等。自定义派生宏通过 #[derive] 属性使用,例如#[derive(Debug)];属性宏允许将宏应用于函数、模块或其他 Rust 项目元素,以实现元编程。它们通过 #[attribute_name] 语法使用; 函数宏类似于声明宏,但它们的输入形式可以更复杂,函数宏可以接受括号内的任意输入,并生成对应的代码。
12.#[repr(transparent)] 是一个用于结构体的属性,它确保该结构体在内存中的布局与其单个字段的类型完全一致。这意味着在 FFI(Foreign Function Interface,外部函数接口)或与 C 语言交互时,Rust编译器不会对该结构体的布局进行任何调整,从而使其与字段的内存布局保持透明。repr(C)和repr(Rust)是Rust中用于控制数据结构内存布局的属性。repr(C)告诉编译器按C语言的内存布局规则排列结构体字段,使其在与C或其他语言的互操作中保持一致。这包括字段的顺序和对齐方式,确保Rust结构体在FFI中可以安全地传递和接收。而repr(Rust)是Rust的默认布局方式,编译器会根据优化的需要对字段进行排列,可能会重新排序字段以减少内存占用或提高访问速度,但这会导致布局不确定,因此不适合FFI。选择repr(C)提供了跨语言的兼容性,而repr(Rust)提供了在Rust内部更好的性能优化。repr(packed)用于紧凑排列结构体字段,忽略默认的内存对齐要求,减少结构体的内存占用,但可能导致未对齐的内存访问问题。repr(align(N)) 是 Rust 中的一个属性,用于将结构体的内存对齐设定为N字节,确保结构体在内存中的地址是 N 的倍数,有助于优化性能。下图示例展示了repr(C)和repr(Rust)的区别:
其他
1.Rust的编译过程始于源代码的解析和词法分析,编译器将源代码分解为标记(tokens),并构建抽象语法树(AST),这反映了代码的语法结构。接着,编译器进行语义分析,主要包括类型检查和借用检查,确保代码遵循Rust的严格类型系统和所有权规则。语义分析阶段还包括将AST转换为中间表示(HIR和MIR),以便进一步优化。在优化阶段,编译器对中间表示(MIR)执行各种优化,如常量折叠和循环展开,以提高代码效率。然后,编译器将优化后的MIR转换为LLVM的中间表示(LLVM IR),并利用LLVM的强大优化功能进一步改进代码,包括寄存器分配和指令合并等。最终,LLVM IR被编译为特定目标架构的机器码,这个阶段生成与硬件相关的二进制指令。编译过程的最后一步是链接,将不同的编译单元合并为最终的可执行文件或库文件。如果启用了增量编译,编译器会缓存中间结果以加快后续编译速度。整体上,Rust的编译过程通过严格的类型检查和多阶段优化,确保生成高效且安全的可执行代码。
2.不同于一些面向语句的编程语言,在Rust里,大多数控制结构(如if、match、loop等)都是表达式,这意味着它们可以返回一个值并直接用于赋值或作为其他表达式的一部分。分号表达式;返回值永远是自身的单元类型:(),分号表达式只有在块表达式的最后一行才会进行求值,其他时候只作为连接符存在。块表达式的值为块中最后一个表达式的值(块中最后一行不加;的表达式),块表达式只对其最后一行表达式进行求值。
3.在Rust中,编译期计算、常量函数和常量泛型是提高代码效率和灵活性的关键概念。它们允许在编译时执行计算,减少运行时开销,并使得代码在编译时就能确定许多值。这对性能至关重要,尤其是在系统编程和嵌入式编程中。常量函数(const fn)是可以在编译时执行的函数,与普通函数不同,const fn可以用于定义常量或在常量表达式中使用,编译器在编译过程中执行这些函数,并将其结果作为常量值嵌入到最终生成的代码中。例如:
const fn square(x: i32) -> i32 { x * x }
const SQUARE_OF_FIVE: i32 = square(5);
square就是一个常量函数,编译器在编译时就计算了SQUARE_OF_FIVE的值,并将其作为常量嵌入到程序中。常量函数还支持嵌套定义,如下图所示:
常量泛型是Rust提供的一种功能,允许在定义泛型类型或函数时使用常量值。通常情况下,泛型参数是类型参数,而常量泛型使得你可以使用整数或其他常量值作为泛型参数。例如:
struct Array<T, const N: usize> { elements: [T; N], }
fn main() {
let arr: Array<i32, 5> = Array { elements: [1, 2, 3, 4, 5] };
}
N是一个常量泛型参数,代表数组的长度。编译器在编译时会处理这个常量,并根据它生成相应的代码。这允许编译时确定数组的大小,而不需要运行时动态分配。
4.位置表达式是指那些能够表示数据的内存位置或地址的表达式,它们通常位于赋值操作的左侧,因为这些表达式可以被赋值,也就是能够“放置”一个值。位置表达式并不直接代表某个具体的值,而是代表某个可以存储值的内存位置。值表达式是指那些直接产生一个值的表达式,与位置表达式不同,值表达式表示的是某个具体的值,而不是一个可以存储值的内存位置。值表达式通常出现在右侧的表达式中,是表达式计算后的结果。常见的位置表达式包括:静态变量的初始化(如static mut LEVELS:u32=0;)、解引用表达式(如*rxpr)、数组索引表达式(形如expr[expr])、字段表达式(形如expr.field)、加上括号的位置表达式(形如(expr))。当位置表达式出现在值表达式的位置时就会发生copy或者所有权的转移。
5.[T]是一种抽象概念,用于描述元素的集合类型,而&[T]是实际使用中的借用类型,允许访问这组元素,切片在处理动态数组或需要获得部分数组的情况下非常有用。
6.NonNull<T>是Rust标准库中的一种指针类型,用于表示一个永远非空的原始指针。这种指针类型确保指针值永远不会是空指针,从而避免了空指针解引用带来的安全问题。但仍可能指向无效内存,因此通常需要在unsafe块中使用。
7.在Rust中,结构体分为具名结构体、元组结构体和单元结构体。具名结构体使用字段名称和类型进行定义,增强代码可读性,适合表示复杂数据结构。例如,struct Person { name: String, age: u32 }。元组结构体类似于元组定义,没有字段名,只有类型和顺序,用于简单封装或类型区分,适合无需复杂命名的简单结构,如struct Color(u8, u8, u8)。单元结构体不包含任何字段,不占用任何内存空间,类似于空元组(),通常用于类型标记或占位符,表示一种类型存在,例如struct Marker。这三种结构体形式满足不同需求,从复杂数据建模到简单类型标识,提供了灵活、多样的定义方式。
8.函数项类型和函数指针类型的主要区别在于语法表示、内存表示、自动转换、捕获环境和性能等方面。前者直接使用函数签名,是编译时确定的值,可以自动转换为后者,并能捕获闭包环境,通常更高效;后者使用fn关键字,是运行时确定的指针,不能自动转换为前者,也不能捕获环境,但可能有一些性能开销。因此,函数项类型更适合编译时确定的函数,函数指针类型更适合运行时确定的函数。
9.在Rust的结构体方法中,使用不同的参数类型会产生不同的效果。如果使用 self 作为参数,则意味着方法会获取结构体的所有权,并将其移动到方法内部,这意味着在方法调用之后,原始的结构体实例将不再可用。相反,如果使用 &self 作为参数,则方法只会借用结构体的引用,而不会获取其所有权,这样可以确保在方法调用之后,原始的结构体实例仍然可以使用。选择合适的参数类型取决于具体的使用场景,如果需要修改结构体的状态,应该使用 self,而如果只需要读取结构体的数据,则应该使用 &self。
相关文章:
《Rust权威指南》学习笔记(五)
高级特性 1.在Rust中,unsafe是一种允许绕过Rust的安全性保证的机制,用于执行一些Rust默认情况下不允许的操作。unsafe存在的原因是:unsafe 允许执行某些可能被 Rust 的安全性检查阻止的操作,从而可以进行性能优化,如手…...
数据库软考历年上午真题与答案解析(2018-2024)
本题考查计算机总线相关知识。 总线(Bus)是计算机各种功能部件之间传送信息的公共通信干线,它是由导线组成的传输线束。 根据总线连接设备范围的不同, 分为:1.片内总线:芯片内部的总线; 2.系统…...
HTML5 文件上传(File Upload)详解
HTML5 文件上传(File Upload)详解 HTML5 提供了强大的文件上传功能,允许用户通过网页选择文件并上传到服务器。以下是关于文件上传控件的详细说明。 1. 基本的文件上传控件 使用 <input> 标签的 type"file" 属性可以创建一…...
构建属于你的七牛云文件上传工具:Qiniu Uploader 详解(从 0 到 1 实现)
GitHub 仓库地址:https://github.com/hahala2333/qiniu-upload 📚 简介 在现代 Web 开发中,静态资源的上传和管理是不可避免的需求。为了简化将本地资源上传到七牛云存储的过程,我们构建了 Qiniu Uploader 工具。它具备灵活的配置…...
Spring Boot 项目中集成 Kafka-03
在 Spring Boot 项目中集成 Kafka 有多种方式,适应不同的应用场景和需求。以下将详细介绍几种常用的集成方法,包括: 使用 Spring Kafka (KafkaTemplate 和 KafkaListener)使用 Spring Cloud Stream 与 Kafka Binder使用 Spring for Apache K…...
如何在2025年创建一个网站:使用US Domain Center和WordPress的终极指南
在本指南中,我们将向你展示如何正确地使用US Domain Center和WordPress创建一个网站。无论你是要启动一个个人博客,还是一个在线商店,我们都会提供简单易懂的步骤指导。无需技术技能 — — 只需按照我们的简单步骤操作,你就能在今…...
LLM 训练中存储哪些矩阵:权重矩阵,梯度矩阵,优化器状态
LLM 训练中存储哪些矩阵 目录 LLM 训练中存储哪些矩阵深度学习中梯度和优化器是什么在 LLM 训练中通常会存储以下矩阵: 权重矩阵:这是模型的核心组成部分。例如在基于 Transformer 架构的 LLM 中,每一层的多头注意力机制和前馈神经网络都会有相应的权重矩阵。以 BERT 模型为…...
【JVM】总结篇之对象内存布局 执行引擎
文章目录 对象内存布局对象的实例化对象的内存布局对象的方问定位 执行引擎 对象内存布局 对象的实例化 new对象流程?(龙湖地产) 对象创建方法,对象的内存分配。(360安全) 1.判断对象对应的类是否加载、链…...
机器学习之正则化惩罚和K折交叉验证调整逻辑回归模型
机器学习之正则化惩罚和K折交叉验证调整逻辑回归模型 目录 机器学习之正则化惩罚和K折交叉验证调整逻辑回归模型1 过拟合和欠拟合1.1 过拟合1.2 欠拟合 2 正则化惩罚2.1 概念2.2 函数2.3 正则化种类 3 K折交叉验证3.1 概念3.2 图片理解3.3 函数导入3.4 参数理解 4 训练模型K折交…...
【图像处理】OpenCv + Python 实现 Photoshop 中的色彩平衡功能
前言 这是使用 python 和 OpenCv 实现的 Photoshop 中色彩平衡功能的代码,可以设置阴影,高光和中间调的色调参数来调整图片的色彩平衡。 参考文章二也有 python 版本的代码实现,虽然中间调的部分貌似没有实现,但是理论部分讲解还…...
基于vue框架的的校园快递管理系统x0xm0(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
系统程序文件列表 项目功能:学生,校园跑腿,快递代取,代取进度,评价信息 开题报告内容 基于Vue框架的校园快递管理系统开题报告 一、研究背景与意义 随着电子商务的蓬勃发展,校园快递业务急剧增长,成为校园生活中不可或缺的一部分。然而&a…...
【Vim Masterclass 笔记05】第 4 章:Vim 的帮助系统与同步练习(L14+L15+L16)
文章目录 Section 4:The Vim Help System(Vim 帮助系统)S04L14 Getting Help1 打开帮助系统2 退出帮助系统3 查看具体命令的帮助文档4 查看帮助文档中的主题5 帮助文档间的上翻、下翻6 关于 linewise7 查看光标所在术语名词的帮助文档8 关于退…...
智能体(Agent)如何具备自我决策能力的机理与实现方法
一、智能体自我决策能力的机理 从人工智能和控制理论的角度看,智能体能够“自我决策”的核心在于其 “感知–认知–行动” 的循环过程,以及在此过程中引入自主学习与自主优化的机制。经过优化与补充,智能体具备自我决策能力的机理可以分解为…...
Redis 数据库源码分析
Redis 数据库源码分析 我们都知道Redis是一个 <key,value> 的键值数据库,其实也就是一个 Map。如果让我来实现这样一个 Map,我肯定是用数组,当一个 key 来的时候,首先进行 hash 运算,接着对数据的 length 取余&…...
vue3 css实现文字输出带光标显示,文字输出完毕,光标消失的效果
Vue实现过程如下: <template><div ><p ref"dom_element" class"typing" :class"{over_fill: record_input_over}"></p></div> </template> <script setup> import {onMounted, ref} from…...
【Leetcode】731. 我的日程安排表 II
文章目录 题目思路代码复杂度分析时间复杂度空间复杂度 结果总结 题目 题目链接🔗 实现一个程序来存放你的日程安排。如果要添加的时间内不会导致三重预订时,则可以存储这个新的日程安排。 当三个日程安排有一些时间上的交叉时(例如三个日程…...
浅谈棋牌游戏开发流程四:核心业务逻辑(二)——房间匹配与对局流程
一、前言:让玩家轻松坐上“牌桌” 在上一篇文章中,我们深入探讨了用户系统与登录流程,了解了如何让“陌生人”转变为游戏中的“正式玩家”。接下来,我们将迈向游戏的核心环节——房间匹配与对局流程。这是玩家实际参与游戏、互动…...
大学生HTML5期末作业 Web前端网页制作 html5+css3+js html+css网页设计 美食 美食模版2个页面
大学生HTML5期末作业 Web前端网页制作 html5css3js htmlcss网页设计 美食 美食模版2个页面 网页作品代码简单,可使用任意HTML辑软件(如:Dreamweaver、HBuilder、Vscode 、Sublime 、Webstorm、Text 、Notepad 等任意html编辑软件进行运行及修…...
Java100道面试题
1.JVM内存结构 1. 方法区(Method Area) 方法区是JVM内存结构的一部分,用于存放类的相关信息,包括: 类的结构(字段、方法、常量池等)。字段和方法的描述,如名称、类型、访问修饰符…...
MySQL 日志简介
总览 MySQL Server 有以下⼏种⽇志,可以记录服务器正在发⽣的活动。 ⽇志类型⽇志信息 ⼀般查询⽇志 (General query log) 已建⽴的客⼾端连接和从客⼾端接收到的语句 错误⽇志 (Error log) mysqld在启动、运⾏或停⽌时遇到的问题 慢查询⽇志 (Slow query log) 执⾏…...
ubuntu清理磁盘
ubuntu清理磁盘脚本: #!/bin/bash#shell脚本用#作注释行,但是第一行的#!/bin/bash例外sudo apt-get clean sudo rm -rf /tmp/* sudo rm -rf /var/cache/*cd /var/log/ sudo du -h -d 1 rm -rf ./*cd ~/.cache sudo du -h -d 1 rm -rf ./*apt…...
鸿蒙APP之从开发到发布的一点心得
引言: 做鸿蒙开发大概有1年左右时间了,从最开始的看官方文档、看B站视频,到后来成功发布两款个人APP(房贷计算极简版、时简时钟 轻喷,谢谢)。简单描述一下里边遇到的坑以及一些经历吧。 学习鸿蒙开发 个…...
C++二十三种设计模式之享元模式
C二十三种设计模式之享元模式 一、组成二、特点三、目的四、缺点五、示例代码 一、组成 抽象享元类:声明操作方法。 具体享元类:使用内部数据和外部数据来实现操作方法。 享元管理者类:创建和管理具体享元对象。 二、特点 1、创建享元对象…...
基于Python的音乐播放器 毕业设计-附源码73733
摘 要 本项目基于Python开发了一款简单而功能强大的音乐播放器。通过该音乐播放器,用户可以轻松管理自己的音乐库,播放喜爱的音乐,并享受音乐带来的愉悦体验。 首先,我们使用Python语言结合相关库开发了这款音乐播放器。利用Tkin…...
基于32单片机的智能语音家居
一、主要功能介绍 以STM32F103C8T6单片机为控制核心,设计一款智能远程家电控制系统,该系统能实现如下功能: 1、可通过语音命令控制照明灯、空调、加热器、窗户及窗帘的开关; 2、可通过手机显示和控制照明灯、空调、窗户及窗帘的开…...
【C语言程序设计——入门】C语言入门与基础语法(头歌实践教学平台习题)【合集】
目录😋 ⚙️C语言环境配置:Windows配置C语言环境(超级详细) <第1关:程序改错> 任务描述 相关知识 1. 头文件的引用 2. 基本语法规则 编程要求 测试说明 通关代码 测试结果 <第2关:scanf 函数>…...
基于Springboot的知名作家交流系统
博主介绍:java高级开发,从事互联网行业多年,熟悉各种主流语言,精通java、python、php、爬虫、web开发,已经做了多年的设计程序开发,开发过上千套设计程序,没有什么华丽的语言,只有实…...
服务器数据恢复—离线盘数超过热备盘数导致raidz阵列崩溃的数据恢复
服务器数据恢复环境&故障: 一台配有32块硬盘的服务器在运行过程中突然崩溃不可用。经过初步检测,基本上确定服务器硬件不存在物理故障。管理员重启服务器后问题依旧。需要恢复该服务器中的数据。 服务器数据恢复环境: 1、将服务器中硬盘…...
conda安装及demo:SadTalker实现图片+音频生成高质量视频
1.安装conda 下载各个版本地址:https://repo.anaconda.com/archive/ win10版本: Anaconda3-2023.03-1-Windows-x86_64 linux版本: Anaconda3-2023.03-1-Linux-x86_64 Windows安装 环境变量 conda -V2.配置conda镜像源 安装pip conda…...
内蒙古水系详细很全shp格式arcgis软件无偏移坐标下载后内容测评
标题中的“内蒙古水系详细很全shp格式arcgis软件无偏移坐标”指的是一个地理信息系统(GIS)数据集,该数据集详细记录了内蒙古地区的水系信息,并以ESRI公司的标准矢量数据格式——Shapefile(.shp)进行存储。S…...
RK3588平台开发系列讲解(系统篇)Linux Kconfig的语法
文章目录 一、什么是Kconfig二、config模块三、menuconfig四、menu 和 endmenu五、choice 和 endchoice六、source七、depends on八、default九、help十、逻辑表达式沉淀、分享、成长,让自己和他人都能有所收获!😄 一、什么是Kconfig Kconfig的语法及代码结构非常简单。本博…...
c#使用SevenZipSharp实现压缩文件和目录
封装了一个类,方便使用SevenZipSharp,支持加入进度显示事件。 双重加密压缩工具范例: using SevenZip; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading.…...
【C++数据结构——查找】二叉排序树(头歌实践教学平台习题)【合集】
目录😋 任务描述 相关知识 1. 二叉排序树的基本概念 2. 二叉排序树节点结构体定义 3. 创建二叉排序树 4. 判断是否为二叉排序树 5. 递归查找关键字为 6 的结点并输出查找路径 6. 删除二叉排序树中的节点 测试说明 通关代码 测试结果 任务描述 本关任务&a…...
C# 服务生命周期:Singleton、Scoped、Transient
文章目录 1、概念:服务生命周期单例 (Singleton) :作用域 (Scoped) :瞬态 (Transient) : 2、对 Scoped 和 Transient 进一步辨析Scoped 生命周期Transient 生命周期选择哪种生命周期 1、概念:服务生命周期 单例 (Singleton) : 整个应用程序生命周期中只有一个实例被创建并共享…...
如何让用户在网页中填写PDF表格?
在网页中让用户直接填写PDF表格,可以大大简化填写、打印、扫描和提交表单的流程。通过使用复选框、按钮和列表等交互元素,PDF表格不仅让填写过程更高效,还能方便地在电脑或移动设备上访问和提交数据。 以下是在浏览器中显示可填写PDF表单的四…...
w140体育馆使用预约平台的设计与实现
🙊作者简介:多年一线开发工作经验,原创团队,分享技术代码帮助学生学习,独立完成自己的网站项目。 代码可以查看文章末尾⬇️联系方式获取,记得注明来意哦~🌹赠送计算机毕业设计600个选题excel文…...
Linux(Ubuntu)下ESP-IDF下载与安装完整流程(4)
接前一篇文章:Linux(Ubuntu)下ESP-IDF下载与安装完整流程(3) 本文主要看参考官网说明,如下: 快速入门 - ESP32-S3 - — ESP-IDF 编程指南 latest 文档 Linux 和 macOS 平台工具链的标准设置 - ESP32-S3 - — ESP-IDF 编程指南 latest 文档 前边几回讲解了第一步 —— …...
PDF预览插件
PDF预览插件 可用于当前页面弹窗形式查看,可增加一些自定义功能 pdf预览插件 代码块: pdfobject.js <div class="pdfwrap"><div class="item"><h3>笑场</h3><div class="tags"><p>李诞</p><i&…...
【微服务】2、网关
Spring Cloud微服务网关技术介绍 单体项目拆分微服务后的问题 服务地址问题:单体项目端口固定(如黑马商城为8080),拆分微服务后端口各异(如购物车808、商品8081、支付8086等)且可能变化,前端难…...
计算机网络--路由表的更新
一、方法 【计算机网络习题-RIP路由表更新-哔哩哔哩】 二、举个例子 例1 例2...
网络安全抓包
#知识点: 1、抓包技术应用意义 //有些应用或者目标是看不到的,这时候就要进行抓包 2、抓包技术应用对象 //app,小程序 3、抓包技术应用协议 //http,socket 4、抓包技术应用支持 5、封包技术应用意义 总结点:学会不同对象采用…...
字玩FontPlayer开发笔记8 Tauri2文件系统
字玩FontPlayer开发笔记8 Tauri2文件系统 字玩FontPlayer是笔者开源的一款字体设计工具,使用Vue3 ElementUI开发,源代码: github: https://github.com/HiToysMaker/fontplayer gitee: https://gitee.com/toysmaker/fontplayer 笔记 字玩目…...
http源码分析
一、HttpURLConnection http连接池源码分析 二、HttpClient 连接池,每个路由最大连接数 三、OkHttp okhttp的连接池与socket连接...
【vim】vim常用操作总结
vim常用操作总结 一,简介二,操作介绍2.1 命令模式2.1.1 删除(剪切)光标所在行2.1.2 复制2.1.3 粘贴2.1.4 跳到行末2.1.5 跳到行首2.1.6 撤销操作 2.2 视图模式2.3 命令模式2.4 编辑模式 三,总结 一,简介 在…...
【学Rust开发CAD】1 环境搭建
文章目录 一、搭建C/C编译环境二、安装Rust三、配置 PATH 环境变量四、验证安装结果五、安装编辑工具 一、搭建C/C编译环境 Rust 的编译工具依赖 C 语言的编译工具,这意味着你的电脑上至少已经存在一个 C 语言的编译环境。如果你使用的是 Linux 系统,往…...
RK3588开发笔记-spi接口调试
目录 前言 一、SPI接口简介 二、原理图连接 三、设备树配置 四、spi调试 五、spi应用软件接口 总结 前言 在嵌入式系统开发中,SPI(Serial Peripheral Interface)接口作为一种同步、全双工、多设备、多主机的通信协议,广泛应用于连接各种外围设备,如ADC、DAC、数据存…...
AlphaPi相关硬件驱动提取
初涉硬件编程,在咸鱼上搞了几块AlphaPi和microbit的板鼓捣了一下,alphapi生态不完善,网上又无任何文档,搞封闭,可玩性实在有限,但貌似相关扩展板是可以插microbit的,于是想把这些扩展版用microb…...
【Unity3D】Text文本文字掉落效果
相关技术:Text、TextMesh、Rigidbody(刚体)、BoxCollider(碰撞体)、TextGenerator、文本网格、文字网格 原理:使用UGUI Text获取其文字的每个字符网格坐标,转世界坐标生成对应的3D文本(TextMesh…...
MySQL内置函数详解
MySQL内置函数详解 1. 字符串函数 1.1 基本字符串处理 -- 字符串长度 SELECT LENGTH(Hello MySQL); -- 返回11-- 字符串大小写转换 SELECT LOWER(HELLO), UPPER(hello); -- 返回 hello, HELLO-- 字符串截取 SELECT SUBSTRING(MySQL Database, 1, 5); -- 返回 MySQL SELEC…...
【网络安全设备系列】9、WAF(Web应用防火墙)
0x00 定义: Web应用防火墙是通过执行一系列针对HTTP/HTTPS的安全策略来专门为Web应用提供保护的一种设备。 WAF需要部署在Web服务器的前面,串行接入,不仅在硬件性能上要求高,而且不能影响Web服务,所以HA功能、Bypass功能都是必…...