Rust语言学习
Rust语言学习
- 通用编程概念
- 所有权
- 所有权
- 引用和借用
- slice
- struct(结构体)
- 定义并实例化一个结构体
- 使用结构体
- 方法语法
- 枚举 enums
- 定义枚举
- match控制流运算符
- if let 简单控制流
- 使用包、Crate和模块管理不断增长的项目(模块系统)
- 包和crate
- 定义模块来控制作用域与私有性
- 路径用于引用模块树中的项
- 使用use关键字将名称引入作用域
- 将模块分割进不同文件
- 常用集合
- vrctor<T>
- 使用字符串存储utf-8编码的文本
- 哈希map存储键值对
- 错误处理
- panic!与不可恢复的错误
- Rusult 与可恢复的错误
- 泛型、trait、生命周期
- 泛型数据类型
- trait :定义共享的行为
- 生命周期和引用有效性
- 测试
- 编写测试
通用编程概念
- let定义一个不可变的值,需要可变则 加mut;
- 使用const 声明常量,常量不仅是不可变的,它们始终是不可变的。常量只能设置为常量表达式,而不能设置为函数调用的结果或只能在运行时计算的任何其他值。
- 遮蔽,使用let对关键字进行阴影处理,例如let x = 5; let x = x + 1 ;
- 静态类型,Rust是一种静态类型的语言,必须在编译器知道所有变量的类型;
- 标量类型:整数、浮点数、布尔值、字符
- 复合类型:元组、数组
- 元组: 将多种类型的多个值组合为一个复合类型的一般方法。元组的长度是固定的:声明后,它们就无法增长或缩小。例如:let tup = (500, 6.4, 1); let (x, y, z) = tup;
- 数组:数组具有固定长度,例如:let a = [1, 2, 3, 4, 5]; let a: [i32; 5] = [1, 2, 3, 4, 5];
- 函数:蛇形大小写作为函数和变量名的常规样式。在蛇形情况下,所有字母均为小写,并在下划线之间使用单独的单词。
- 功能实体包含语句和表达式
- 语句:语句不返回值;如:let a= 5;
- 表达式:**{ let x=3; x+1 }**表达式不包括结尾分号。如果在表达式的末尾添加分号,则将其变成一条语句,然后该语句将不返回值。
- 具有返回值的函数:函数的返回值与函数主体块中最终表达式的值同义。您可以通过使用return关键字并指定一个值从函数中提前返回,但是大多数函数隐式返回最后一个表达式。例如:fn five() -> i32 { 5 }
- if bool { } else if bool {} else {}:if的条件不加() ,结果可赋值给变量
- 循环重复 :loop、while、for
- loop { // 逻辑 } :Rust提供了另一种更可靠的突破循环的方法。您可以将break关键字放在循环中,以告知程序何时停止执行循环;
let mut counter = 0;let result = loop {counter += 1;if counter == 10 {break counter * 2;}};
- while bool表达式 {}
```javascriptlet mut a = 0;let aa = [1,2,2,3,4];while a<aa.len() {println!("{}",aa[a]);a = a+2;}
```
所有权
所有权
- 所有权规则
- Rust中的每个值都有一个称为其所有者的变量。
- 值在任一时刻有且只有一个所有者。
- 当所有者(变量)离开作用域,该值将被删除。
- 所有权的存在为了管理堆数据
- String 类型存储在堆上,当离开作用域时,Rust会调用一个特殊函数,这个函数叫drop 放置释放内存的代码。
- Rust 永远也不会自动创建数据据的“深拷贝”,
- 变量与数据的交互方式:
- 移动 let s1 = s2; (主要是存储在堆里的数据,如果作为参数传入到新的函数中,之后不可使用,参考其下代码二)
- 克隆 clone()
- 只在栈上的拷贝 (区分上述的移动和拷贝)。Rust 有一个叫做 Copy trait 的特殊注解,。如果一个类型拥有 Copy trait,一个旧的变量在将其赋值给其他变量后仍然可用。
- 所有整数类型,比如 u32。
- 布尔类型,bool,它的值是 true 和 false。
- 所有浮点数类型,比如 f64。
- 字符类型,char。
- 元组,当且仅当其包含的类型也都是 Copy 的时候。比如,(i32, i32) 是 Copy 的,但 (i32, String) 就不是。
- 返回值也可以转移所有权
- 转移返回值的所有权(变量的所有权总是遵循相同的模式:将值赋给另一个变量时移动它。当持有堆中数据值的变量离开作用域时,其值将通过 drop 被清理掉,除非数据被移动为另一个变量所有。)
- 返回参数的所有权 (引用)
//代码二
fn main() {//s值移入到函数中 之后不在有效let s = String ::from("hello");takes_ownership(s);//返回值转移所有权let s2 = String::from("abc");let s3 = takes_and_give_back(s2);println!("s3:{}",s3);//转移返回值的所有权let s1 = String::from("word");let (s2, len) = calculate_length(s1);println!("s2:The length of '{}' is {}.", s2, len);let x =5; //x是copy的,所以后面可继续使用makes_copy(x);
}
fn takes_ownership(some_string:String){println!("{}",some_string);
}
fn makes_copy(some_integer:i32){println!("{}",some_integer);
}
fn takes_and_give_back(str:String) -> String {str
}
fn calculate_length(s: String) -> (String, usize) {let length = s.len(); // len() 返回字符串的长度(s, length)
}
引用和借用
- 引用就是符号&。 允许使用所有权但不获取所有权。
- 我们将获取引用作为函数参数称为借用。
- 正如变量默认是不可变的,引用也一样。(默认)不允许修改引用的值。
- 可变引用:&mut
- 在特定作用域中的特定数据中只能有一个可变引用,好处是可以在编译时就避免数据竞争,可以通过大括号创建一个新的作用域,以允许拥有多个可变引用,只是不能同时拥有。
- 引用的规则:在任意给定时间,要么只能有一个可变引用,要么只能有多个不可变引用。 引用必须总是有效的。
slice
- 允许引用集合中一段连续的元素序列,而不引用整个集合。
- 没有所有权的数据类型。
- 引用 &string[1…2] ; &string[…1]; &string[1…];(部分 或起止末尾的引用)。
- 所有权、借用和slice让rust在编译时确保内存安全。
struct(结构体)
自定义数据类型,允许命名和包装多个相关的值,形成一个有意义的组合。
定义并实例化一个结构体
- 变量与字段同名的字段初始化简写语法。
- 可使用结构体更新语法从其他实例创建实例。
- (元组结构体):使用没有命名字段的元组结构体来创建不同的类型。
- (类单元结构体):没有任何字段的结构体(因为它们类似于 (),即unit 类型。类单元结构体常常在你想要在某个类型上实现 trait 但不需要在类型中存储数据的时候发挥作用)。
- 结构体数据的所有权,(如果结构体存储被其对象拥有数据的引用,需要用上生命周期(lifetimes))
使用结构体
- {} 中加入 :? 指示符告诉 println! 我们想要使用叫做 Debug 的输出格式。Debug 是一个 trait,它允许我们以一种对开发者有帮助的方式打印结构体,以便当我们调试代码时能看到它的值。(参考代码如下)
- #[derive(Debug)] 注解
let user = User {user_name: String::from("yyn"),age: 18,live: true};println!("user:{:#?}",user);#[derive(Debug)]
struct User{user_name:String,age:u16,live:bool,
}
方法语法
- 方法和函数类型 使用fn关键字,可以拥有参数和返回值 ,不同点:在结构体的上下文中被定义(或枚举或trait对象的上下文),并且第一个参数总是self,代表调用该方法的结构体实例。
- 自动引用和解引用: 方法调用时rust中少数几个拥有这种行为的地方:当使用 object.something() 调用方法时,Rust 会自动为 object 添加 &、&mut 或 * 以便使 object 与方法签名匹配。
- 方法有一个明确的接收者———— self 的类型。在给出接收者和方法名的前提下,Rust 可以明确地计算出方法是仅仅读取(&self),做出修改(&mut self)或者是获取所有权(self)。事实上,Rust 对方法接收者的隐式借用让所有权在实践中更友好。
- 关联函数(不以self作为参数的函数):impl的另一个有用的功能,它们与结构体相关联,他们仍然是函数,而不是方法,因为它们并不作用于一个结构体的实例,例如:String::from
- 每个结构体都允许拥有多个impl块。
- 结构体不是创建自定义类型的唯一方法,还有枚举。
fn main(){let mut r = Rectangle{width:20,height:20};r.setHeight(300);println!("r.area:{}",r.area());let square = Rectangle::square(300);println!("square:{}",square.height);
}#[derive(Debug)]
struct Rectangle {width:u32,height:u32,
}impl Rectangle{fn square(size:u32)-> Rectangle{return Rectangle{ width:size,height:size};}fn setHeight(&mut self,height:u32){self.height = height;}fn area(&self) -> u32{self.height* self.width}
}
枚举 enums
定义枚举
- 可以将任意类型的数据放入到枚举成员中。例如:字符串、数字类型、或者结构体,还可以是另一个枚举。
- 结构体和枚举还有另一个相似点:使用impl来为结构体定义方法那样,也可以在枚举上定义方法。
- Option枚举:为了拥有一个可能为空的值,你必须要显式的将其放入对应类型的 Option 中。接着,当使用这个值时,必须明确的处理值为空的情况。只要一个值不是 Option 类型,你就 可以 安全的认定它的值不为空。这是 Rust 的一个经过深思熟虑的设计决策,来限制空值的泛滥以增加 Rust 代码的安全性。
- match 表达式就是这么一个处理枚举的控制流结构:它会根据枚举的成员运行不同的代码,这些代码可以使用匹配到的值中的数据。
match控制流运算符
- 允许我们将一个值与一系列的模式相比较,并根据相匹配的模式执行相应代码。
- ** _ 通配符** :会匹配所有的值,通过将其放在其他分支之后,_将会匹配所有之前没有指定的可能的值。
- match 在只关心 一个 情况的场景中可能就有点啰嗦了。为此 Rust 提供了if let。
if let 简单控制流
- if let 获取通过等号分隔一个模式和一个表达式,失去match强制要求的穷尽性检查。
- if let 包含一个else 。else块中代码与match表达式中的_分支块中的代码相同。
#[derive(Debug)]
enum IpAddKind{V4,V6(String)
}
#[derive(Debug)]
struct IpAddr{kind :IpAddKind,address:String,
}fn main(){//使用结构体和枚举定义数据let home = IpAddr{kind:IpAddKind::V4,address:String::from("127.0.0.1")};let loopback = IpAddr{kind:IpAddKind::V6(String::from("::1")),address:String::from("::1")};//使用matchlet b = value_in_ip_add_kind(home.kind);println!("v4:{}",b);let a = value_in_ip_add_kind(loopback.kind);println!("v6:{}",a);//Option<T>//let five = Some(5);//let six = plus_one(five);//let none = plus_one(None);//if let 使用let some_and_value = Some(4);if let Some(3) = some_and_value{println!("three");} else {println!("qita");}
}fn value_in_ip_add_kind(ip_add_kind:IpAddKind) -> u8 {match ip_add_kind{IpAddKind::V4 => 1,IpAddKind::V6(str)=>{println!("str:{}",str);return 2},}
}
fn plus_one(x:Option<i32>) -> Option<i32>{match x {None => None,Some(i) => Some(i+1)}
}
使用包、Crate和模块管理不断增长的项目(模块系统)
一个包可以包含多个二进制crate项和一个可选的crate库。伴随着包的增长,你可以将包中的部分代码提取出来做成独立的crate,这些crate则作为外部依赖项。
作用域
模块系统:
1、包(Packages): Cargo 的一个功能,它允许你构建、测试和分享 crate。
2、Crates :一个模块的树形结构,它形成了库或二进制项目。
3、模块(Modules)和 use: 允许你控制作用域和路径的私有性。
4、路径(path):一个命名例如结构体、函数或模块等项的方式
cargo new --lib 模块名
Rust 提供了将包分成多个 crate,将 crate 分成模块,以及通过指定绝对或相对路径从一个模块引用另一个模块中定义的项的方式。你可以通过使用 use 语句将路径引入作用域,这样在多次使用时可以使用更短的路径。模块定义的代码默认是私有的,不过可以选择增加 pub 关键字使其定义变为公有。
包和crate
- Cargo 遵循的一个约定:src/main.rs 就是一个与包同名的二进制 crate 的 crate 根。Cargo 知道如果包目录中包含 src/lib.rs,则包带有与其同名的库 crate,且 src/lib.rs 是 crate 根。Cargo提供了工作区间这一功能。
- crate 是一个二进制项或者库。crate root 是一个源文件,Rust 编译器以它为起始点,并构成你的 crate 的根模块.
- 包(package) 是提供一系列功能的一个或者多个 crate。一个包会包含有一个 Cargo.toml 文件,阐述如何去构建这些 crate。
- 包中所包含的内容由几条规则来确立。一个包中至多 只能 包含一个库 crate(library crate);包中可以包含任意多个二进制 crate(binary crate);包中至少包含一个 crate,无论是库的还是二进制的。
- 如果一个包同时含有 src/main.rs 和 src/lib.rs,则它有两个 crate:一个库(main)和一个二进制项,且名字都与包相同。通过将文件放在 src/bin 目录下,一个包可以拥有多个二进制 crate:每个 src/bin 下的文件都会被编译成一个独立的二进制 crate。
- cargo new name创建一个可执行工程 src/main.rs
- cargo new --lib name 创建一个库工程 src/lib.rs
定义模块来控制作用域与私有性
- paths(允许你命名项的路径);use(将路径引入作用域);pub(使项变为公有);as,外部包,glob运算符;
- 模块让我们可以将一个 crate 中的代码进行分组,以提高可读性与重用性。模块还可以控制项的 私有性,即项是可以被外部代码使用的(public),还是作为一个内部实现的内容,不能被外部代码使用(private)。
- ** 定义一个模块**:是以 mod 关键字为起始,然后指定模块的名字,并且用花括号包围模块的主体。在模块内,我们还可以定义其他的模块。模块还可以保存一些定义的其他项,比如结构体、枚举、常量、特性、或者函数。
路径用于引用模块树中的项
- 路径分为绝对路径和相对路径:绝对路径(absolute path)从 crate 根开始,以 crate 名或者字面值 crate 开头。相对路径(relative path)从当前模块开始,以 self、super 或当前模块的标识符开头。
- 绝对路径和相对路径都后跟一个或多个由双冒号(::)分割的标识符。
- 模块还定义了Rust的私有性边界,Rust默认所有项都是私有的,父模块中的项不能使用子模块中的私有项,但是子模块中的项可以使用父模块中的项。
- 使用pub关键字创建公共项,使子模块的内部部分暴露给上级模块。
- 使用super起始的相对路径。
- 使用pub 可以设计公有的结构体和枚举,我们还可以决定每个结构体的字段是否公有。
- 如果结构体中具有私有字段,我们需要提供公共的关联函数来构造结构体的实例。
- 与结构体相反**,如果把枚举设置为公有,它的成员都将变为公有。**
使用use关键字将名称引入作用域
- 使用use关键字将路径一次性引入作用域,然后调用该路径的项。
- 使用use 将两个同名类型引入同一个作用域这个问题还有另一个解决办法 使用as关键字指定一个新的本地名或者别名。 例如:use std::fmt::Result; use std::io::Result as IoResult;
- 使用 pub use 重导出名称,将项引入作用域,并同时使其可供其他代码引入自己的作用域。
- 使用外部包 Cargo.toml 加入 [dependence] rand=“0.5.5” ,加入一行use起始的包名。
- crates.io 上有很多 Rust 社区成员发布的包,将其引入你自己的项目都需要一道相同的步骤:在 Cargo.toml 列出它们并通过 use 将其中定义的项引入项目包的作用域中。 例如:[dependencies] rand = “0.5.5”
- 嵌套路径来消除大量的use行。 例如:use std::{cmp::Ordering,io}
- 通过glob运算符将所有的公有定义引入作用域 ** *,glob运算符 **,glob运算符经常用于测试模块tests中,后面讲解。
将模块分割进不同文件
- mod *** 后使用分号,而不是代码块,这将告诉Rust在另一个与模块同名的文件中加载模块的内容。
常用集合
vrctor
- 新建
- let v:Vec = Vec::new();
- let v = vec![1,2,3];
- 更新 push
- 读取 索引语法(&v[下标]) 或者 get()(返回一个Option<&T>)
- (执行所有权和借用规则)不能在相同作用域中同时存在可变和不可变引用的规则
- 遍历 **for i in & (mut) v {} **
- 更多参考文档
使用字符串存储utf-8编码的文本
- Rust 的核心语言中只有一种字符串类型:str,字符串 slice,它通常以被借用的形式出现,&str;
- 创建字符串 String::new(); String::from(“abc”); “abc”.to_string();
- 更新字符串push_str();push(); 使用+运算符 (let s3 = s1 + &s2; // 注意 s1 被移动了,不能继续使用)或format! 宏拼接字符串
- 索引字符串 s1[0]
- slice 字符串
- for c in “字符串”.chars(){}
哈希map存储键值对
- 新建 HashMap::new(); HashMap<,> 可以使用下划线占位,而 Rust 能够根据 数据的类型推断出 HashMap 所包含的类型。
- insert(插入、覆盖) get(获取) entry(是否存中)
错误处理
panic!与不可恢复的错误
- Rust 有 panic!宏。当执行这个宏时,程序会打印出一个错误信息,展开并清理栈数据,然后接着退出。
- 当出现 panic 时,程序默认会开始 展开((unwinding),这意味着 Rust 会回溯栈并清理它遇到的每一个函数的数据,不过这个回溯并清理的过程有很多工作。另一种选择是直接 终止(abort),这会不清理数据就退出程序。**panic 时通过在 Cargo.toml 的 [profile] 部分增加 panic = ‘abort’,可以由展开切换为终止。例如,如果你想要在release模式中 panic 时直接终止 [profile.release] panic = ‘abort’ **
- RUST_BACKTRACE 环境变量来得到一个 backtrace ** RUST_BACKTRACE=1 cargo run**
Rusult 与可恢复的错误
- Result<T,E>
- 失败时panic的简写:unwrap(unwrap 会为我们调用 panic!)和expect( 输出失败信息)
- 传播错误:当编写一个其实现会调用一些可能会失败的操作的函数时,除了在这个函数中处理错误外,还可以选择让调用者知道这个错误并决定该如何处理。
- 传播错误的简写:?运算符
泛型、trait、生命周期
泛型数据类型
- Rust 通过在编译时进行泛型代码的 单态化(monomorphization)来保证效率。单态化是一个通过填充编译时使用的具体类型,将通用代码转换为特定代码的过程。
trait :定义共享的行为
- trait 告诉 Rust 编译器某个特定类型拥有可能与其他类型共享的功能。可以通过 trait 以一种抽象的方式定义共享的行为。可以使用 trait bounds 指定泛型是任何拥有特定行为的类型。**注意:trait 类似于其他语言中的常被称为 接口(interfaces)的功能,虽然有一些不同。 **
- trait 定义是一种将方法签名组合起来的方法,目的是定义一个实现某些目的所必需的行为的集合。
- 例如:pub trait Summary { fn summarize(&self) -> String; }; 实现 使用 impl trait名称 for 目标{fn… }
- 实现 trait 时需要注意的一个限制是,只有当 trait 或者要实现 trait 的类型位于 crate 的本地作用域时,才能为该类型实现 trait。
- 但是不能为外部类型实现外部 trait
- trait中的方法可有默认实现。
- trait作为参数: fn 方法名(item: impl trait名){ … }
- trait bound 语法糖 fn 方法名 <T : trait名>( item:T){ … }
- 在<T : trait名> 还可使用 + 或者使用 where fn some_function<T, U>(t: T, u: U) -> i32 where T: Display + Clone, U: Clone + Debug { … }
- 也可在返回值中使用 impl Trait语法 ,返回一个只是指定了需要实现的 trait 的类型的能力在闭包和迭代器场景十分的有用
- 通过使用带有 trait bound 的泛型参数的 impl 块,可以有条件地只为那些实现了特定 trait 的类型实现方法。
生命周期和引用有效性
- Rust 中的每一个引用都有其 生命周期(lifetime),也就是引用保持有效的作用域。
- 生命周期避免了悬垂引用。它会导致程序引用了非预期引用的数据。
- 生命周期注解语法
- &i32 // 引用
- &'a i32 // 带有显式生命周期的引用
- &'a mut i32 // 带有显式生命周期的可变引用
- 泛型生命周期
- 当从函数返回一个引用,返回值的生命周期参数需要与一个参数的生命周期参数相匹配。如果返回的引用 没有 指向任何一个参数,那么唯一的可能就是它指向一个函数内部创建的值,它将会是一个悬垂引用,因为它将会在函数结束时离开作用域。
- 生命周期语法是用于将函数的多个参数与其返回值的生命周期进行关联的。一旦他们形成了某种关联,Rust 就有了足够的信息来允许内存安全的操作并阻止会产生悬垂指针亦或是违反内存安全的行为。
- 结构体定义中的生命周期注解
- 我们将定义包含引用的结构体,不过这需要为结构体定义中的每一个引用添加生命周期注解。
- 被编码进 Rust 引用分析的模式被称为 **生命周期省略规则 **
- 第一条规则是每一个是引用的参数都有它自己的生命周期参数。换句话说就是,有一个引用参数的函数有一个生命周期参数:fn foo<'a>(x: &'a i32),有两个引用参数的函数有两个不同的生命周期参数,fn foo<'a, 'b>(x: &'a i32, y: &'b i32),依此类推。
- 第二条规则是如果只有一个输入生命周期参数,那么它被赋予所有输出生命周期参数:fn foo<'a>(x: &'a i32) -> &'a i32。
- 第三条规则是如果方法有多个输入生命周期参数并且其中一个参数是 &self 或 &mut self,说明是个对象的方法(method) ,那么所有输出生命周期参数被赋予 self 的生命周期。第三条规则使得方法更容易读写,因为只需更少的符号。
- **静态生命周期 **
- ** 'static **,其生命周期能够存活于整个程序期间。
测试
编写测试
- #[test]注解 方法上使用
- assert_eq!宏 相等 assert_ne! 不相等
- 使用 assert! 宏来检查结果
- assert!、assert_eq! 和 assert_ne! 宏传递一个可选的失败信息参数,可以在测试失败时将自定义失败信息一同打印出来
- 使用 #[should_panic] 检查 panic ,检查方法打印值是否相同
- 将 Result<T, E> 用于测试作为返回值
相关文章:
Rust语言学习
Rust语言学习 通用编程概念所有权所有权引用和借用slice struct(结构体)定义并实例化一个结构体使用结构体方法语法 枚举 enums定义枚举match控制流运算符if let 简单控制流 使用包、Crate和模块管理不断增长的项目(模块系统)包和crate定义模块来控制作用…...
wordPress WooCommerce 本地文件包含漏洞复现(CVE-2025-1661)(附脚本)
免责申明: 本文所描述的漏洞及其复现步骤仅供网络安全研究与教育目的使用。任何人不得将本文提供的信息用于非法目的或未经授权的系统测试。作者不对任何由于使用本文信息而导致的直接或间接损害承担责任。如涉及侵权,请及时与我们联系,我们将尽快处理并删除相关内容。 0x0…...
【CSS文字渐变动画】
CSS文字渐变动画 HTML代码CSS代码效果图 HTML代码 <div class"title"><h1>今天是春分</h1><p>正是春天到来的日子,花都开了,小鸟也飞回来了,大山也绿了起来,空气也有点嫩嫩的气息了</p>…...
2021-06-15 C逆序存入数组的元素
缘由编程,逆序存入数组的元素_编程语言-CSDN问答 #define N 7 main() { static int a[N]{12,9,16,5,7,2,l},k,s; for(k0;k<N;k) Printf("%4d",a[k]);for (k0;k<N/2; k) {sa[k]; a[k]a[N-1-k]; a[N-1-k]s; } for (k0;k<N;k) Printf("%4…...
Qt 控件概述 QLabel
目录 QLabel显示类控件 label如何做到与窗口同步变化 边框 Frame QLabel显示类控件 textFormat :设置文件格式 Pixmap :标签图片 label如何做到与窗口同步变化 Qt中对应用户的操作 : 事件和信号 拖拽窗口大小就会触发…...
k8s服务中userspace,iptables,和ipvs的比较
在 Kubernetes 中,kube-proxy 是负责实现服务负载均衡的组件。它支持三种代理模式:userspace、iptables 和 ipvs。这三种模式在性能、功能和复杂性上有所不同。以下是它们的详细比较: 1. Userspace 模式 Userspace 是 Kubernetes 最早支持的…...
Vue 渲染 LaTeX 公式 Markdown 库
🌟 前言 欢迎来到我的技术小宇宙!🌌 这里不仅是我记录技术点滴的后花园,也是我分享学习心得和项目经验的乐园。📚 无论你是技术小白还是资深大牛,这里总有一些内容能触动你的好奇心。🔍 &#x…...
KMP-子串匹配算法-关键点理解
1.理解next[]数组的使用与来历 2.求解next[]数组 一、kmp算法的原理 首先观察暴力解法:假设主串为:abdxxabc,模式串为abxxabd。 暴力解法,就是对主串每个字符作为第一个字符,开始和模式串比较。 比如:从…...
网络原理之网络层、数据链路层
1. 网络层 1.1 IP协议 1.1.1 基本概念 主机: 配有IP地址,但是不进⾏路由控制的设备路由器: 即配有IP地址,⼜能进⾏路由控制节点: 主机和路由器的统称 1.1.2 协议头格式 说明: 4位版本号(version): 指定IP协议的版本,对于IPv4来说,就是4,对于IPv6来说,就是6 4位头…...
ssh 多重验证的好处:降低密钥长度,动态密码
ssh 多重验证的好处: 多重验证:可能要比单纯提高密钥长度,或密码的长度更好,可以获得更好的保证服务器安全的效果。降低密钥长度:可以提高 CPU运行时的有效速度,特别是在传输大文件、或传输低比特率视频时…...
版本控制器Git ,Gitee如何连接Linux Gitee和Github区别
📖 示例场景 假设你和朋友在开发一个「在线笔记网站」,代码需要频繁修改和协作: 只用本地文件管理 每次修改后手动复制文件,命名为 v1.html、v2.html 问题:无法追踪具体改动内容;多人修改易冲突࿱…...
网站测速:提升用户体验的关键
在互联网飞速发展的今天,网站已成为企业展示形象、提供服务以及用户获取信息的重要平台。而网站的速度,如同高速公路的路况,直接影响着用户的访问体验和满意度。因此,网站测速成为了网站运营和维护中不可或缺的关键环节。 网站速…...
【动态规划篇】91. 解码方法
91. 解码方法 题目链接: 91. 解码方法 题目叙述: 一条包含字母 A-Z 的消息通过以下映射进行了 编码 : “1” -> ‘A’ “2” -> ‘B’ … “25” -> ‘Y’ “26” -> ‘Z’ 然而,在解码已编码的消息时,你…...
Python高级——类的知识
一、知识梳理: 二、货币场景搭建: 1)代码展示: class RMB:count 0def __init__(self,yuan0,jiao0,fen0):self.__yuan yuanself.__jiao jiaoself.__fen fenRMB.count 1def __add__(self, other):temp RMB()temp.__yuan se…...
Python 编程题 第十一节:选择排序、插入排序、删除字符、目标移动、尾部的0
选择排序 假定第一个为最小的为已排序序列,与后面的比较,找到未排序序列中最小的后,交换位置,获得最小元素,依次往后 lst[1,14,25,31,21,13,6,8,14,9,7] def selection_sort(lst):for i in range(len(lst)):min_inde…...
resnet与densenet的比较
一、 ResNet(残差网络)和 DenseNet(密集连接网络) ResNet(残差网络)和 DenseNet(密集连接网络)都是深度学习中非常经典的卷积神经网络架构,它们在图像分类、目标检测等诸…...
Linux 运维工作中,掌握一系列基础命令与积累丰富经验至关重要
基础命令 文件与目录操作 ls:用于查看目录内容。例如ls -l能以长格式显示文件和目录的详细信息,ls -a则可显示包括隐藏文件在内的所有文件。cd:用于切换工作目录。像cd /home/user可切换到/home/user目录,cd ..能返回上一级目录…...
【算法day16】电话号码的字母组合
电话号码的字母组合 给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。 给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。 https://leetcode.cn/problems/letter-combinations…...
软件工程之软件验证计划Software Verification Plan
个人主页:云纳星辰怀自在 座右铭:“所谓坚持,就是觉得还有希望!” 本文为基于ISO26262软件验证计划模板,仅供参考。 软件验证计划,包括: 1. 软件需求验证计划 2. 软件架构设计验证计划 3. 软件单…...
软考系统架构设计师之计算机组成与体系结构笔记
一、计算机硬件组成 1. 冯诺依曼结构与哈佛结构 冯诺依曼结构:以存储器为中心,指令和数据统一存储,通过总线连接运算器、控制器、输入输出设备。其核心思想是“存储程序控制”,但存在存储器访问瓶颈问题。哈佛结构:指…...
「JavaScript深入」Socket.IO:基于 WebSocket 的实时通信库
Socket.IO Socket.IO 的核心特性Socket.IO 的架构解析Socket.IO 的工作流程Socket.IO 示例:使用 Node.js 搭建实时聊天服务器1. 安装 Socket.IO2. 服务器端代码(Node.js)3. 客户端代码(HTML JavaScript)4. 房间功能 高…...
redis分布式锁实现Redisson+redlock中watch dog是如何判断当前线程是否持有锁进行续租的呢?
在 Redis 中,Watch Dog(看门狗)机制主要用于实现分布式锁的自动续期(如 Redisson 的 RedLock 实现)。其核心目的是确保当业务逻辑执行时间超过锁的初始过期时间(leaseTime)时,锁不会…...
Spring Cloud之负载均衡之LoadBalance
目录 负载均衡 问题 步骤 现象 什么是负载均衡? 负载均衡的一些实现 服务端负载均衡 客户端负载均衡 使用Spring Cloud LoadBalance实现负载均衡 负载均衡策略 编辑 编辑LoadBalancer原理 服务部署 准备环境和数据 服务构建打包 启动服务 上传J…...
一份1000元机器人开发资金计划表
一、硬件采购(约850元) 类别项目数量单价(元)总价(元)说明主控板Arduino Uno R3120~5050入门首选,开源生态完善,适合学习基础控制逻辑。传感器HC-SR04超声波模块21020用于避障或测距…...
分布式任务调度
今天我们讲讲分布式定时任务调度—ElasticJob。 一、概述 1、什么是分布式任务调度 我们可以思考⼀下下⾯业务场景的解决⽅案: 某电商平台需要每天上午10点,下午3点,晚上8点发放⼀批优惠券 某银⾏系统需要在信⽤卡到期还款⽇的前三天进⾏短信提醒 某…...
嵌入式面经(2)——央企篇
前文得知我只投央企,不投国企,有面试的央企大致有三类:感兴趣的同学可以和我私聊 军工央企相关(航空航天,兵器兵工) 制造央企相关(三桶油,装备制造) 金融运维相关(信通集团,国有银行) 接下来我将对我有的面试中询问的面经进行总结 一.军工央企相关(航空航天,…...
第7章 类与面向对象
6-1 二维平面上的点操作(Python3) 题目描述 设计一个表示二维平面上点的类 Point。该类应该包含以下功能: 两个私有属性 _x 和 _y,分别表示点的横坐标和纵坐标。 一个构造函数 __init__,用于初始化点的坐标。 一个…...
架构设计的灵魂交响曲:系统设计各维度的深度解析与实战指南
引言: 系统设计的背景与重要性 在快速变化的技术环境中,数字化转型成为企业生存与发展的核心驱动力。系统设计能力不仅是技术团队的核心竞争力,也是推动业务创新和提升整体效率的关键因素。根据Gartner的研究,超过70%的数字化转型项目未能实…...
[贪心算法]买卖股票的最佳时机 买卖股票的最佳时机Ⅱ K次取反后最大化的数组和 按身高排序 优势洗牌(田忌赛马)
1.买卖股票的最佳时机 暴力解法就是两层循环,找出两个差值最大的即可。 优化:在找最小的时候不用每次都循环一遍,只要在i向后走的时候,每次记录一下最小的值即可 class Solution { public:int maxProfit(vector<int>& p…...
【 <二> 丹方改良:Spring 时代的 JavaWeb】之 Spring MVC 的核心组件:DispatcherServlet 的工作原理
<前文回顾> 点击此处查看 合集 https://blog.csdn.net/foyodesigner/category_12907601.html?fromshareblogcolumn&sharetypeblogcolumn&sharerId12907601&sharereferPC&sharesourceFoyoDesigner&sharefromfrom_link <今日更新> 一、Dispat…...
