rust容器

标准库提供了常见的容器。包括向量 ( Vector )、映射( HashMap )、集合( HashSet )。

一、向量Vector

数组有一个缺点,就是它的长度在编译时就确定了,一旦确定就永不可更改。
向量是一个长度可变的数组。向量的存储在堆上,因此长度可变。

Rust在标准库中定义了结构体Vec用于表示向量。

(一)定义向量
一维向量
1.new()创建一个空向量
语法格式

let mut instance_name: Vec<T> = Vec::new();
例子
let v1: Vec<i32> = Vec::new(); // 创建类型为i32的空向量

2.vec!()宏创建向量
这种方式的创建方法类似于数组的语法。
它也有3种创建方式。
(1)创建空向量。需要指定类型。

let mut vec_marco: Vec<i32> = vec![];

(2)指定所有元素。可以省略类型。

let mut vec_marco = vec![1, 2, 3, 4, 5];

(3)指定初始值和长度。可以省略类型。

let mut vec_marco = vec![0; 5];     // 长度为5,元素初始化为0

注意,长度可以是变量,这点与数组不同。
例子

let len = 10;
let zero_vec = vec![0; len];

3.从数组创建向量

let arr = [1, 2, 3, 4, 5];
let v = arr.to_vec();

二维向量
1.使用new()创建空向量。需要指定类型。

let mut instance_name: Vec<Vec<T>> = Vec::new();
例子
let v1: Vec<Vec<i32>> = Vec::new();

2.使用vec!()宏创建向量
(1)创建空向量。需要指定类型。

let mut vec_marco: Vec<Vec<i32>> = vec![];

(2)指定所有元素。可以省略类型。

let mut vec_marco = vec![vec![1, 2, 3, 4, 5], ...];

(3)指定初始值和长度。可以省略类型。

let mut vec_marco = vec![vec![0; 5]; 10];
例子
let width = 4;
let height = 4;
let mut array = vec![vec![0; width]; height];

3.从二维数组创建二维向量
例如

let s = [
[0, 0, 1, 0, 0],
[0, 0, 1, 0, 0],
[0, 0, 1, 0, 0],
[0, 0, 1, 0, 0],
];
let s: Vec<_> = s.iter().map(|&e| e.to_vec()).collect();

(二)使用向量
1.获取长度
len()方法
例子

fn main() {let v = vec![1, 2, 3];println!("{}", v.len());let width = 4;let height = 4;let array = vec![vec![0; width]; height];println!("{} {}", array.len(), array[0].len());
}
运行结果如下
3
4 4

2.添加元素
使用push方法来追加单个元素
实例

fn main() {let mut vector = vec![1, 2, 4, 8];vector.push(16);vector.push(32);vector.push(64);println!("{:?}", vector);let mut arr: Vec<Vec<i32>> = Vec::new();arr.push(Vec::new());arr.push(vec![]);arr[0].push(1);println!("{:?}", arr);
}
运行结果:
[1, 2, 4, 8, 16, 32, 64]
[[1], []]

使用append方法用于将一个向量拼接到另一个向量的尾部
实例

fn main() {let mut v1: Vec<i32> = vec![1, 2, 4, 8];let mut v2: Vec<i32> = vec![16, 32, 64];v1.append(&mut v2);println!("{:?}", v1);
}
运行结果:
[1, 2, 4, 8, 16, 32, 64]

2.删除元素
使用remove()删除元素
remove() 方法移除并返回向量中指定的下标索引处的元素,将其后面的所有元素移到向左移动一位。

fn main() {let mut v = vec![10,20,30];v.remove(1);println!("{:?}",v);
}
运行结果如下
[10, 30]

clear
删除所有元素

let mut v = vec![10,20,30];
v.clear();
println!("{:?}",v);

3.获取元素
因为向量实现了Deref Target=[T],所以向量自动实现了切片的所有方法。
(1)使用get方法
get方法根据索引返回对元素或子切片的引用。
如果给定位置,则返回该位置上的元素的引用,如果越界则返回None。
如果给定范围,则返回对应于该范围的子切片,如果越界则返回None。
例子

let v = vec![10, 40, 30];
assert_eq!(Some(&40), v.get(1));
assert_eq!(Some(&[10, 40][..]), v.get(0..2));
assert_eq!(None, v.get(3));
assert_eq!(None, v.get(0..4));

(2)get_mut
get_mut方法根据索引返回对元素或子切片的可变引用
如果给定位置,则返回该位置上的元素的可变引用,如果越界则返回None。
如果给定范围,则返回对应于该范围的可变子切片,如果越界则返回None。
例子

let mut x = vec![0, 1, 2];
if let Some(elem) = x.get_mut(1) {*elem = 42;
}
assert_eq!(x, &[0, 42, 2]);

(3)使用[]
实例

fn main() {let v = vec![1, 2, 4, 8];println!("{}", v[1]);
}
运行结果:
2

二维向量

array[2][2] = 5;
println!("{:?}", array);

例子

use std::io;
fn main(){let width = 4;let height = 4;let mut array = vec![vec![0; width]; height];for i in 0..4 {let mut buf = String::from("");io::stdin().read_line(&mut buf).unwrap();array[i] = buf.split_whitespace().map(|s| s.parse().unwrap()).collect();}println!("{:?}", array);
}

4.遍历向量
(1)使用索引

fn main() {let v = vec![100, 32, 57];for i in 0..v.len() {println!("{}", v[i]);}
}

(2)使用向量的引用
实例

fn main() {let v = vec![100, 32, 57];for i in &v {println!("{}", i);}
}
运行结果:
100
32
57

实例

fn main() {let mut v = vec![100, 32, 57];for i in &mut v {*i += 50;}println!("{:?}", v);
}

(3)使用迭代器
iter()返回一个只读迭代器

for num in nums1.iter() {print!("{} ", num);
}
println!();

iter_mut()返回一个可写迭代器

let mut nums1 = [1; 5];
let mut i = 0;
for num in nums1.iter_mut() {*num = i;i += 1;
}
println!("{:?}", nums1);

into_iter()返回一个迭代器,但是转让所有权

let mut nums1 = [1; 5];
for num in nums1.into_iter() {print!("{} ", num);
}
println!();

for num in nums1.into_iter()
实际上等价于
for num in nums1

(4)使用迭代器的enumerate

let mut nums1 = [1; 5];
for (pos, v) in nums1.iter().enumerate() {println!("nums[{}]={}", pos, v);
}
println!("{:?}", nums1);
for (pos, v) in nums1.iter_mut().enumerate() {*v=pos;println!("nums[{}]={}", pos, v);
}
println!("{:?}", nums1);

二维向量
(1)使用索引

let mut v = vec![vec![1, 2, 3, 4, 5], vec![3, 9, 8]];
for i in 0..v.len() {for j in 0..v[i].len() {println!("{}", v[i][j]);}
}

(2)使用引用
例子

let s = [
[0, 0, 1, 0, 0],
[0, 0, 1, 0, 0],
[0, 0, 1, 0, 0],
[0, 0, 1, 0, 0],
];
let mut s: Vec<_> = s.iter().map(|&e| e.to_vec()).collect();
for row in &s{for col in row{print!("{} ", col);}println!();
}
for row in &mut s {for col in row {*col += 1;print!("{} ", col);}println!();
}

(3)使用向量的迭代器

let mut grid = [[0; 5]; 5];
for row in grid.iter() {for col in row.iter() {print!("{} ", col);}println!();
}
let mut i = 0;
for row in grid.iter_mut(){for col in row.iter_mut() {*col = i;i += 1;print!("{} ", col);}println!();
}

(4)使用迭代器的enumerate

let mut grid = [[0; 5]; 5];
for (i, row) in grid.iter().enumerate() {for (j, col) in row.iter().enumerate() {print!("{}", col);}println!()
}
for (i, row) in grid.iter_mut().enumerate() {for (j, col) in row.iter_mut().enumerate() {*col = 1;}
}

6.使用contains() 判断向量是否包含某个元素
如果值在向量中存在则返回 true ,否则返回 false 。

fn main() {let v = vec![10,20,30];if v.contains(&10) {println!("found 10");}println!("{:?}",v);
}
运行结果如下
found 10
[10, 20, 30]

7.逆转向量

reverse
适当地反转切片中元素的顺序。
例子
let mut v = [1, 2, 3];
v.reverse();
assert!(v == [3, 2, 1]);

二、映射HashMap

映射表(Map)在其他语言中广泛存在。其中应用最普遍的就是散列映射表(Hash Map)。
HashMap就是 键值对 的集合。映射表中不允许有重复的键,但允许不同的键有相同的值。

Rust语言定义了HashMap结构体来表示映射表。
HashMap结构体定义在std::collections模块中,使用之前需要导入std::collections模块。

(一)定义映射表
1.使用new创建空映射表
语法格式如下

let mut instance_name: HashMap<type1, type2> = HashMap::new();

实例

use std::collections::HashMap;
let mut map: HashMap<&str, i32> = HashMap::new();
let mut map = HashMap::new();//可以省略类型

2.可以从数组初始化HashMap
例子

use std::collections::HashMap;
let solar_distance = HashMap::from([
("Mercury", 0.4),
("Venus", 0.7),
("Earth", 1.0),
("Mars", 1.5),
]);

(二)使用映射表
1.使用len()获取键值对的个数
例子

use std::collections::HashMap;
fn main() {let mut stateCodes = HashMap::new();stateCodes.insert("name","简单教程");stateCodes.insert("site","https://www.twle.cn");println!("size of map is {}",stateCodes.len());
}
编译运行结果如下
size of map is 2

2.添加键值对
使用insert()方法用于插入或更新一个键值对
如果键已经存在,则更新为新的值,并则返回旧的值。
如果键不存在则执行插入操作并返回None 。

例子

fn main() {let mut map = HashMap::new();map.insert("color", "red");map.insert("size", "10 m^2");println!("{}", map.get("color").unwrap());
}
运行结果:
red

3.删除指定键值对
remove()用于从映射表中删除指定的键值对。
如果键值对存在则返回删除的键值对,返回的数据格式为 (&'a K, &'a V) 。
如果键值对不存在则返回None

例子

use std::collections::HashMap;
fn main() {let mut stateCodes = HashMap::new();stateCodes.insert("name","简单教程");stateCodes.insert("site","https://www.twle.cn");stateCodes.insert("slogn","简单教程,简单编程");println!("length of the hashmap {}",stateCodes.len());stateCodes.remove(&"site");println!("length of the hashmap after remove() {}",stateCodes.len());
}
编译运行结果如下
length of the hashmap 3
length of the hashmap after remove() 2

clear
清除map,删除所有键值对。
例子

use std::collections::HashMap;
let mut a = HashMap::new();
a.insert(1, "a");
a.clear();
assert!(a.is_empty());

4.根据键获取相应的值
使用get()方法获取键相应的值。
如果值不存在,则返回None 。
如果值存在,则返回值的一个引用。

例子

use std::collections::HashMap;
fn main() {let mut stateCodes = HashMap::new();stateCodes.insert("name","简单教程");stateCodes.insert("site","https://www.twle.cn");println!("size of map is {}",stateCodes.len());println!("{:?}",stateCodes);match stateCodes.get(&"name") {Some(value)=> {println!("Value for key name is {}",value);}None => {println!("nothing found");}}
}
编译运行结果如下
size of map is 2
{"name": "简单教程", "site": "https://www.twle.cn"}
Value for key name is简单教程

get_mut
实例

use std::collections::HashMap;
fn main() {let mut map = HashMap::new();map.insert(1, "a");if let Some(x) = map.get_mut(&1) {*x = "b";}
}

get_key_value
例子

use std::collections::HashMap;
let mut map = HashMap::new();
map.insert(1, "a");
assert_eq!(map.get_key_value(&1), Some((&1, &"a")));
assert_eq!(map.get_key_value(&2), None);

5.遍历映射表
(1)使用引用

for (book, review) in &book_reviews {println!("{book}: \"{review}\"");
}for (book, review) in &mut book_reviews {*review = 0;println!("{book}: \"{review}\"");
}

(2)使用迭代器
iter()方法会返回映射表中 键值对的引用组成的无序迭代器。
迭代器元素的类型为 (&'a K, &'a V) 。
实例

use std::collections::HashMap;
fn main() {let mut map = HashMap::new();map.insert("color", "red");map.insert("size", "10 m^2");for p in map.iter() {println!("{:?}", p);}
}
运行结果:
("color", "red")
("size", "10 m^2")
迭代元素是表示键值对的元组。

iter_mut
例子

use std::collections::HashMap;
let mut map = HashMap::from([
("a", 1),
("b", 2),
("c", 3),
]);
// 更新所有值
for (_, val) in map.iter_mut() {*val *= 2;
}

6.是否包含指定的键
contains_key()方法用于判断映射表中是否包含指定的键值对。
如果包含指定的键,那么会返回相应的值的引用,否则返回None 。

例子

use std::collections::HashMap;
fn main() {let mut stateCodes = HashMap::new();stateCodes.insert("name","简单教程");stateCodes.insert("site","https://www.twle.cn");stateCodes.insert("slogn","简单教程,简单编程");if stateCodes.contains_key(&"name") {println!("found key");}
}
编译运行结果如下
found key

7.entry
entry方法返回键值对
例子

use std::collections::HashMap;
let mut player_stats = HashMap::new();
fn random_stat_buff() -> u32 {42
}
player_stats.entry("health").or_insert(100);     // 没有就插入,有就跳过
player_stats.entry("defence").or_insert_with(random_stat_buff);     //没有就插入,有就跳过
let stat = player_stats.entry("attack").or_insert(100);     //没有就插入,返回值的引用
*stat += random_stat_buff();
player_stats.entry("mana").and_modify(|mana| *mana += 200).or_insert(100);     // 有就加200,没有就插入100
println!("{:?}", player_stats);

9.自定义键类型
派生Eq和Hash。 我们还必须导出PartialEq。
例子

use std::collections::HashMap;
#[derive(Hash, Eq, PartialEq, Debug)]
struct Viking {name: String,country: String,
}
impl Viking {/// 创建一个新的Viking。fn new(name: &str, country: &str) -> Viking {Viking { name: name.to_string(), country: country.to_string() }}
}
// 使用HashMap存储Viking的健康点。
let vikings = HashMap::from([
(Viking::new("Einar", "Norway"), 25),
(Viking::new("Olaf", "Denmark"), 24),
(Viking::new("Harald", "Iceland"), 12),
]);
// 使用派生的实现来打印Viking的状态。
for (viking, health) in &vikings {println!("{viking:?} has {health} hp");
}

10.其他
keys
返回一个迭代器,以任意顺序访问所有键。 迭代器元素类型为 &'a K。
例子

use std::collections::HashMap;
let map = HashMap::from([
("a", 1),
("b", 2),
("c", 3),
]);
for key in map.keys() {println!("{key}");
}

values
返回一个以任意顺序访问所有值的迭代器。 迭代器元素类型为 &'a V。
例子

use std::collections::HashMap;
let map = HashMap::from([
("a", 1),
("b", 2),
("c", 3),
]);
for val in map.values() {println!("{val}");
}

is_empty
如果map不包含任何元素,则返回true。
例子

use std::collections::HashMap;
let mut a = HashMap::new();
assert!(a.is_empty());
a.insert(1, "a");
assert!(!a.is_empty());

三、集合HashSet

HashSet是没有重复值的相同数据类型的值的集合。
Rust语言标准库std::collections中定义了结构体HashSet用于描述集合。

(一)定义集合
1.new()创建一个空集合
语法格式如下

let mut hash_set_name = HashSet::new();

2.可以从数组初始化HashSet:

use std::collections::HashSet;
let viking_names = HashSet::from(["Einar", "Olaf", "Harald"]);

(二)使用集合
1.获取集合的长度len()
len() 方法用于获取集合的长度,也就是集合中元素的个数。

范例

use std::collections::HashSet;
fn main() {let mut languages = HashSet::new();languages.insert("Python");languages.insert("Rust");languages.insert("Ruby");languages.insert("PHP");println!("size of the set is {}",languages.len());
}
编译运行结果如下
size of the set is 4

2.添加元素
insert() 用于插入一个值到集合中,如果集合中已经存在指定的值,则返回 false ,否则返回 true 。

例子

use std::collections::HashSet;
fn main() {let mut languages = HashSet::new();languages.insert("Python");languages.insert("Rust");languages.insert("Ruby");languages.insert("PHP");languages.insert("Rust"); // 插入失败但不会引发异常println!("{:?}",languages);
}
编译运行结果如下
{"Python", "PHP", "Rust", "Ruby"}

3.删除集合元素
remove() 方法用于从集合中删除指定的值。
删除之前如果值 value 存在于集合中则返回 true ,如果不存在则返回 false 。

例子

use std::collections::HashSet;
fn main() {let mut languages = HashSet::new();languages.insert("Python");languages.insert("Rust");languages.insert("Ruby");println!("length of the Hashset: {}",languages.len());languages.remove(&"Kannan");println!("length of the Hashset after remove() : {}",languages.len());
}
编译运行结果如下
length of the Hashset: 3
length of the Hashset after remove() : 3

clear
删除所有值。
例子

use std::collections::HashSet;
let mut v = HashSet::new();
v.insert(1);
v.clear();
assert!(v.is_empty());

4.获取元素
get() 方法用于获取集合中指定值的一个引用。
如果值 value 存在于集合中则返回集合中的相应值的一个引用,否则返回 None 。

例子

use std::collections::HashSet;
fn main() {let mut languages = HashSet::new();languages.insert("Python");languages.insert("Rust");languages.insert("Ruby");languages.insert("PHP");match languages.get(&"Rust"){Some(value)=>{println!("found {}",value);}None =>{println!("not found");}}println!("{:?}",languages);
}
编译运行结果如下
found Rust
{"Python", "Ruby", "PHP", "Rust"}

take
删除并返回集合中等于给定值的值 (如果有)。
该值可以是集合值类型的任何借用形式,但是借用形式上的Hash和Eq必须与值类型的那些匹配。
例子

use std::collections::HashSet;
let mut set = HashSet::from([1, 2, 3]);
assert_eq!(set.take(&2), Some(2));
assert_eq!(set.take(&2), None);

5.遍历集合
(1)使用引用

for book in &books {println!("{book}");
}

(2)使用迭代器
iter()方法用于返回集合中所有元素组成的无序迭代器。
迭代器元素的顺序是无序的,毫无规则的。而且每次调用iter() 返回的元素顺序都可能不一样。

例子

use std::collections::HashSet;
fn main() {let mut languages = HashSet::new();languages.insert("Python");languages.insert("Rust");languages.insert("Ruby");languages.insert("PHP");for language in languages.iter() {println!("{}",language);}
}
编译运行结果如下
PHP
Python
Rust
Ruby

6.判断集合是否包含某个值
contains() 方法用于判断集合是否包含指定的值。
如果值 value 存在于集合中则返回 true ,否则返回 false 。

例子

use std::collections::HashSet;
fn main() {let mut languages = HashSet::new();languages.insert("Python");languages.insert("Rust");languages.insert("Ruby");if languages.contains(&"Rust") {println!("found language");}
}
编译运行结果如下
found language

7.自定义类型
派生Eq和Hash。我们还必须导出PartialEq,这将在Eq中隐含在future中。

use std::collections::HashSet;
#[derive(Hash, Eq, PartialEq, Debug)]
struct Viking {name: String,power: usize,
}
let mut vikings = HashSet::new();
vikings.insert(Viking { name: "Einar".to_string(), power: 9 });
vikings.insert(Viking { name: "Einar".to_string(), power: 9 });
vikings.insert(Viking { name: "Olaf".to_string(), power: 4 });
vikings.insert(Viking { name: "Harald".to_string(), power: 8 });
for x in &vikings {println!("{x:?}");
}

8.其他
is_empty
如果集合不包含任何元素,则返回true。
例子

use std::collections::HashSet;
let mut v = HashSet::new();
assert!(v.is_empty());
v.insert(1);
assert!(!v.is_empty());

union
访问表示并集的值,即self或other中的所有值,没有重复项。
例子

use std::collections::HashSet;
let a = HashSet::from([1, 2, 3]);
let b = HashSet::from([4, 2, 3, 4]);
// 以任意顺序打印1、2、3、4。
for x in a.union(&b) {
println!("{x}");
}
let union: HashSet<_> = a.union(&b).collect();
assert_eq!(union, [1, 2, 3, 4].iter().collect());

intersection
访问表示相交的值,即self和other中的值。
当self和other中存在相等的元素时,生成的Intersection可能会引用其中一个。 如果T包含未通过其Eq实现进行比较的字段,并且可能在两组T的两个相等副本之间保持不同的值,则这可能是相关的。
例子

use std::collections::HashSet;
let a = HashSet::from([1, 2, 3]);
let b = HashSet::from([4, 2, 3, 4]);
// 以任意顺序打印2,3。
for x in a.intersection(&b) {
println!("{x}");
}
let intersection: HashSet<_> = a.intersection(&b).collect();
assert_eq!(intersection, [2, 3].iter().collect());

is_subset
如果集合是另一个集合的子集,则返回true,即other至少包含self中的所有值。
例子

use std::collections::HashSet;
let sup = HashSet::from([1, 2, 3]);
let mut set = HashSet::new();
assert_eq!(set.is_subset(&sup), true);
set.insert(2);
assert_eq!(set.is_subset(&sup), true);
set.insert(4);
assert_eq!(set.is_subset(&sup), false);

is_superset
如果集合是另一个集合的超集,则返回true,即self至少包含other中的所有值。
例子

use std::collections::HashSet;
let sub = HashSet::from([1, 2]);
let mut set = HashSet::new();
assert_eq!(set.is_superset(&sub), false);
set.insert(0);
set.insert(1);
assert_eq!(set.is_superset(&sub), false);
set.insert(2);
assert_eq!(set.is_superset(&sub), true);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/82434.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

路由器端口转发

什么是路由器端口转发 路由器端口转发是一种网络配置技术&#xff0c;用于将公共网络&#xff08;如互联网&#xff09;上的请求转发到私有网络中的特定设备或服务。它允许外部设备通过路由器访问内部网络中的设备或服务&#xff0c;实现网络上的通信和互动。 路由器端口转发…

计算机竞赛 深度学习 YOLO 实现车牌识别算法

文章目录 0 前言1 课题介绍2 算法简介2.1网络架构 3 数据准备4 模型训练5 实现效果5.1 图片识别效果5.2视频识别效果 6 部分关键代码7 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 基于yolov5的深度学习车牌识别系统实现 该项目较…

《YOLOv5/YOLOv7/YOLOv8最新改进大作战》专栏介绍 CSDN独家改进创新实战 专栏目录

&#x1f4a1;&#x1f4a1;&#x1f4a1;YOLOv5/YOLOv7/YOLOv8最新改进大作战&#xff0c;独家首发创新&#xff08;原创&#xff09;&#xff0c;持续更新&#xff0c;适用于Yolov5、Yolov7、Yolov8等各个Yolo系列&#xff0c;专栏文章提供每一步步骤和源码&#xff0c;轻松带…

Postman脚本——变量的设置和获取

设置变量 设置Collection环境变量 pm.collectionVariables.set("变量名", "变量值");设置Global环境变量 pm.globals.set("变量名", "变量值");设置Environment环境变量 // 设置环境变量 pm.environment.set("变量名", …

mybatis-plus根据指定条件批量更新

1.service实现类中 比如我这里只针对UserEntity&#xff0c;在UserServiceImpl下&#xff08;该实现类是继承了mybatis-plus的ServiceImpl的&#xff09;新增如下代码&#xff1a; public boolean updateBatchByQueryWrapper(Collection<UserEntity> entityList, Funct…

uniapp之uni-forms表单组件封装的双向数据绑定

前言 在uniapp中, 封装组件的props单向数据流更为严格, 不允许改变子组件的props属性, 所以记录下uniapp下的form表单的组件是如何封装的, 双向数据是如何绑定的. 版本: "dcloudio/uni-ui": "^1.4.27", "vue": "> 2.6.14 < 2.7&quo…

安卓毕业设计各种app项目,Android毕设设计,Android课程设计,毕业论文

作为一位从事软件开发多年的专业人士&#xff0c;您积累了丰富的经验和技能&#xff0c;解决了许多不同类型的问题。除了开发原创项目&#xff0c;您还愿意分享您的知识&#xff0c;指导实习生和在校生。这种乐于助人的行为对于行业的发展和新一代软件开发者的成长都起着积极的…

《优化接口设计的思路》系列:第三篇—留下用户调用接口的痕迹

系列文章导航 《优化接口设计的思路》系列&#xff1a;第一篇—接口参数的一些弯弯绕绕 《优化接口设计的思路》系列&#xff1a;第二篇—接口用户上下文的设计与实现 《优化接口设计的思路》系列&#xff1a;第三篇—留下用户调用接口的痕迹 前言 大家好&#xff01;我是sum…

阿里云交互式建模(PAI-DSW)训练并微调推理ChatGLM模型

参考内容为《轻量微调和推理ChatGLM模型实践》 点击“交互式建模&#xff08;DSW&#xff09;”&#xff0c;然后选择“创建实例” 写上实例名称&#xff0c;然后选择GPU规格&#xff0c;选择“ecs.gn6v-c8g1.2xlarge(8 vCPU&#xff0c;32GB)” 页面往下拉选择“pytorch:…

力扣刷题:寻找两个正序数组的中位数、最长回文子串

今日刷题又开始了 一、寻找两个正序数组的中位数 题目链接&#xff1a;https://leetcode.cn/problems/median-of-two-sorted-arrays/ 给定两个大小分别为 m 和 n 的正序&#xff08;从小到大&#xff09;数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。 算法…

常见的内网穿透工具有 ngrok/ localtunnel/ frp

1.内网穿透工具的工作原理 内网穿透工具的工作原理是通过在本地网络和公共网络之间建立一个通道&#xff0c;将公网流量转发到本地网络中的服务。这样&#xff0c;在没有公网 IP 或无法直接访问的情况下&#xff0c;用户可以通过公网访问本地网络中的服务。 2. 常见的内网穿透…

Leetcode162. 寻找峰值

力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 峰值元素是指其值严格大于左右相邻值的元素。 给你一个整数数组 nums&#xff0c;找到峰值元素并返回其索引。数组可能包含多个峰值&#xff0c;在这种情况下&#xff0c;返回 任何一个峰值 所在位置即…

Spring Boot 发送邮件

Spring Boot 发送邮件 准备工作引入依赖邮箱开启SMTP三方登录授权配置邮件服务器 发送邮件普通文本邮件复杂邮件 准备工作 引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-mail</artifactId&…

物理内存分配

目录 内核物理内存分配接口 内存分配行为&#xff08;物理上&#xff09; 内存分配的行为操作 内存 三个水位线 水线计算 水位线影响内存分配行为 内存分配核心__alloc_pages 释放页 1、内核物理内存分配接口 struct page *alloc_pages(gfp_t gfp, unsigned int ord…

Redis 三种特殊的数据类型 - Geospatial地理位置 - Hyperloglog基数统计的算法 - Bitmaps位图(位存储)

目录 Redis 三种特殊的数据类型&#xff1a; Geospatial&#xff1a;地理位置 Geospatial类型常用的命令&#xff1a; GEOADD&#xff1a;添加地理位置 GEOPOS&#xff1a;获取地理位置 GEODIST&#xff1a;返回两个给定位置之间的距离 GEORADIUS&#xff1a;以给定的经纬…

Window server 2008服务器,think-queue自动断开,宝塔redis爬坑记录

Window server 2008服务器,think-queue自动断开,宝塔redis爬坑记录 排查原因问题解决坑爹记录: 错误应用程序名称: redis-server.exe,版本: 0.0.0.0,时间戳: 0x5a604657 错误模块名称: redis-server.exe,版本: 0.0.0.0,时间戳: 0x5a604657 异常代码: 0xc0000005 错误偏…

Seata 源码篇之AT模式启动流程 - 上 - 02

Seata 源码篇之AT模式启动流程 - 02 自动配置两个关键点 初始化初始化TM初始化RM初始化TC 全局事务执行流程TM 发起全局事务GlobalTransactional 注解处理全局事务的开启 TM 和 RM 执行分支事务IntroductionDelegatingIntroductionInterceptorDelegatePerTargetObjectIntroduct…

java手写并查集算法应用拓展案例

Java手写并查集算法应用拓展案例 1. 并查集算法应用思路 并查集是一种用于处理不相交集合的数据结构&#xff0c;它支持合并&#xff08;union&#xff09;和查找&#xff08;find&#xff09;两种操作。并查集常用于解决集合合并、连通性问题等。 并查集算法的应用拓展案例主…

在华为云服务器上CentOS 7安装单机版Redis

https://redis.io/是官网地址。 点击右上角的Download。 可以进入https://redis.io/download/——Redis官网下载最新版的网址。 然后在https://redis.io/download/页面往下拉&#xff0c;点击下图超链接这里。 进入https://download.redis.io/releases/下载自己需要的安装…

【C语言】自定义类型:结构体【结构体内存具详细】,枚举,联合

目录 一、结构体 1.结构的声明 2.特殊的声明 3.结构的自引用 4.结构体变量的定义和初始化 5.结构体内存对齐&#xff08;重点来了&#xff09; 6.为什么会存在内存对齐 7.修改默认对齐数 8.结构体传参 二、位段 1.什么是位段 2.位段的内存分配 3.位段的跨平台问题…