当前位置: 首页 > news >正文

Rust-10-数据类型

Rust 标准库中包含一系列被称为 集合(collections)的非常有用的数据结构。大部分其他数据类型都代表一个特定的值,不过集合可以包含多个值。不同于内建的数组和元组类型,这些集合指向的数据是储存在堆上的,这意味着数据的数量不必在编译时就已知,并且还可以随着程序的运行增长或缩小。每种集合都有着不同功能和成本,而根据当前情况选择合适的集合,这是一项应当逐渐掌握的技能。在这一章里,我们将详细的了解三个在 Rust 程序中被广泛使用的集合:
• vector 允许我们一个挨着一个地储存一系列数量可变的值
• 字符串(string)是字符的集合。我们之前见过 String 类型,不过在本章我们将深入了解。
• 哈希 map(hash map)允许我们将值与一个特定的键(key)相关联。这是一个叫做 map 的更通用的数据结构的特定实现。

Sequences: Vec, VecDeque, LinkedList
Maps: HashMap, BTreeMap
Sets: HashSet, BTreeSet
Misc: BinaryHeap

一、vector

vector 允许我们在一个单独的数据结构中储存多于一个的值,它在内存中彼此相邻地排列所有的值。vector 只能储存相同类型的值。类似java中的ArrayList结构。

1.1 创建

 let v:Vec<i32> = Vec::new();

vector 是用泛型实现的,Vec 是一个由标准库提供的类型,它可以存放任何类型,而当 Vec 存放某个特定类型时,那个类型位于尖括号中。
通常,我们会用初始值来创建一个 Vec 而 Rust 会推断出储存值的类型,所以很少会需要这些类型注解。为了方便 Rust 提供了 vec! 宏,这个宏会根据我们提供的值来创建一个新的vector。

let v = vec![1,2,3];

1.2 更新

使用push方法

//如果想要能够改变它的值,必须使用 mut 关键字使其可变。
let mut v = Vec::new();
v.push(1);
v.push(2);

1.3 读取

有两种方法引用 vector 中储存的值:通过索引或使用 get 方法。

fn main() {let v = vec![1,2,3,4,5];let third = &v[2];println!("third is {}",third);let third = v.get(2);match third {Some(third) => println!("The third element is {third}"),None => println!("There is no third element."),}
}

这里有几个细节需要注意。我们使用索引值 2 来获取第三个元素,因为索引是从数字 0 开始的。使用 & 和 [] 会得到一个索引位置元素的引用。当使用索引作为参数调用 get 方法时,会得到一个可以用于 match 的 Option<&T> 。
使用[] 访问vector时当引用一个不存在的元素时 Rust 会造成panic。这个方法更适合当程序认为尝试访问超过 vector 结尾的元素是一个严重错误的情况,这时应该使程序崩溃。
当 get 方法被传递了一个数组外的索引时,它不会造成panic而会返回None。当偶尔出现超过vector 范围的访问属于正常情况的时候可以考虑使用它。接着你的代码可以有处理Some(&element) 或 None 的逻辑。
一旦程序获取了一个有效的引用,借用检查器将会执行所有权和借用规则来确保 vector 内容的这个引用和任何其他引用保持有效。回忆一下不能在相同作用域中同时存在可变和不可变引用的规则。当我们获取了 vector 的第一个元素的不可变引用并尝试在 vector 末尾增加一个元素的时候,如果尝试在函数的后面引用这个元素是行不通的:

fn main() {let mut v = vec![1, 2, 3, 4, 5];let first = &v[0];v.push(6);println!("The first element is: {first}");
}
error[E0502]: cannot borrow `v` as mutable because it is also borrowed as immutable--> src\main.rs:232:5|
231 |     let first = &v[0];|                  - immutable borrow occurs here
232 |     v.push(6);|     ^^^^^^^^^ mutable borrow occurs here
233 |     println!("The first element is: {first}");|                                     ------- immutable borrow later used here

看起来应该能够运行:为什么第一个元素的引用会关心 vector 结尾的变化?不能这么做的原因是由于 vector 的工作方式:在 vector 的结尾增加新元素时,在没有足够空间将所有元素依次相邻存放的情况下,可能会要求分配新内存并将老的元素拷贝到新的空间中。这时,第一个元素的引用就指向了被释放的内存。借用规则阻止程序陷入这种状况。

1.4 遍历 vector 中的元素

如果想要依次访问 vector 中的每一个元素,我们可以遍历其所有的元素而无需通过索引一次一个的访问。

fn main() {let mut v = vec![1, 2, 3, 4, 5];for i in &v {println!("{i}")}
}

我们也可以遍历可变 vector 的每一个元素的可变引用以便能改变它们。

fn main() {let mut v = vec![1, 2, 3, 4, 5];for i in &mut v {*i +=10;}
}

1.5 使用枚举来储存多种类型

vector 只能储存相同类型的值。这是很不方便的;绝对会有需要储存一系列不同类型的值的用例。幸运的是,枚举的成员都被定义为相同的枚举类型,所以当需要在 vector 中储存不同类型值时,我们可以定义并使用一个枚举

enum SpreadsheetCell {Int(i32),Float(f64),Text(String),
}
let row = vec![SpreadsheetCell::Int(3),SpreadsheetCell::Text(String::from("blue")),SpreadsheetCell::Float(10.12),];

Rust 在编译时就必须准确的知道 vector 中类型的原因在于它需要知道储存每个元素到底需要多少内存。第二个好处是可以准确的知道这个 vector 中允许什么类型。如果 Rust 允许vector 存放任意类型,那么当对 vector 元素执行操作时一个或多个类型的值就有可能会造成
错误。
如果在编写程序时不能确切无遗地知道运行时会储存进 vector 的所有类型,枚举技术就行不通了。相反,你可以使用 trait 对象,这个后面再说
vector文档

1.6 丢弃 vector 时也会丢弃其所有元素

类似于任何其他的 struct ,vector 在其离开作用域时会被释放,当 vector 被丢弃时,所有其内容也会被丢弃,这意味着这里它包含的数据将被清理。借用检查器确保了任何 vector 中内容的引用仅在 vector 本身有效时才可用。

二、string

字符串就是作为字节的集合外加一些方法实现的,当这些字节被解释为文本时,这些方法提供了实用的功能。在这一部分,我们会讲到 String 中那些任何集合类型都有的操作,比如创建、更新和读取。索引 String 是很复杂的,由于人和计算机理解 String 数据方式的不同。

2.1 什么是字符串

Rust 的核心语言中只有一种字符串类型:字符串 slice str ,它通常以被借用的形式出现,&str 。字符串 slices:它们是一些对储存在别处的 UTF-8 编码字符串数据的引用。举例来说,由于字符串字面值被储存在程序的二进制输出中,因此字符串字面值也是字符串 slices。
字符串(String )类型由 Rust 标准库提供,而不是编入核心语言,它是一种可增长、可变、可拥有、UTF-8 编码的字符串类型。而且 String 和 字符串 slices 都是UTF-8 编码的。

2.2 新建

很多 Vec 可用的操作在 String 中同样可用,事实上 String 被实现为一个带有一些额外保证、限制和功能的字节 vector 的封装。

let mut s = String::new();
let str = "hello".to_string();
let str = String::from("hello world");

因为字符串应用广泛,这里有很多不同的用于字符串的通用 API 可供选择。其中一些可能看起来多余,不过都有其用武之地!在上面例子中,String::from 和 .to_string 最终做了完全相同的工作,所以如何选择就是代码风格与可读性的问题了。

2.3 更新

String 的大小可以增加,其内容也可以改变,就像可以放入更多数据来改变 Vec 的内容一样。另外,可以方便的使用 + 运算符或 format! 宏来拼接 String 值。

使用 push_str 和 push 附加字符串
可以通过 push_str 方法来附加字符串 slice,从而使 String 变长。
push 方法被定义为获取一个单独的字符作为参数,并附加到 String 中。

    let mut str = "hello".to_string();str.push_str(" world");

使用+拼接字符串其实使用的add函数 fn add(self, s: &str) -> String {

 let s1 = String::from("Hello, ");let s2 = String::from("world!");let s3 = s1 + &s2; // 注意 s1 被移动了,不能继续使用

s2 使用了 & ,意味着我们使用第二个字符串的 引用 与第一个字符串相加。这是因为add 函数的 s 参数:只能将 &str 和 String 相加,不能将两个 String 值相加。之所以能够在 add 调用中使用 &s2 是因为 &String 可以被 强转(coerced)成 &str 。当add 函数被调用时,Rust 使用了一个被称为 Deref 强制转换(deref coercion)的技术,你可以将其理解为它把 &s2 变成了 &s2[…] 。
其次,可以发现签名中 add 获取了 self 的所有权,因为 self 没有 使用 & 。这意味着 s1 的所有权将被移动到 add 调用中,之后就不再有效。所以虽然 let s3 = s1 +&s2; 看起来就像它会复制两个字符串并创建一个新的字符串,而实际上这个语句会获取 s1 的所有权,附加上从 s2 中拷贝的内容,并返回结果的所有权。换句话说,它看起来好像生成了很多拷贝,不过实际上并没有:这个实现比拷贝要更高效。

如果想要级联多个字符串,+ 的行为就显得笨重了,对于更为复杂的字符串链接,可以使用 format! 宏

 let s1 = String::from("aaaaaa");let s2 = String::from("bbbbbb");let s3 = String::from("cccccc");let s = format!("{s1}-{s2}-{s3}");

format! 与 println! 的工作原理相同,不过不同于将输出打印到屏幕上,它返回一个带有结果内容的 String 。这个版本就好理解的多,宏
format! 生成的代码使用引用所以不会获取任何参数的所有权。

2.4 索引字符串

在很多语言中,通过索引来引用字符串中的单独字符是有效且常见的操作。然而在 Rust 中,如果你尝试使用索引语法访问 String 的一部分,会出现一个错误。

fn main() {let s1 = String::from("hello");let h = s1[0];
}
error[E0277]: the type `String` cannot be indexed by `{integer}`--> src\main.rs:232:13|
232 |     let h = s1[0];|             ^^^^^ `String` cannot be indexed by `{integer}`|= help: the trait `Index<{integer}>` is not implemented for `String`= help: the following other types implement trait `Index<Idx>`:<String as Index<RangeFull>><String as Index<std::ops::Range<usize>>><String as Index<RangeFrom<usize>>><String as Index<RangeTo<usize>>><String as Index<RangeInclusive<usize>>><String as Index<RangeToInclusive<usize>>>

从上错误所知Rust 的字符串不支持索引。
那为什么呢
String 是一个 Vec<u8> 的封装。如果对于这个let hello = String::from("Hola");在这里,len 的值是 4,这意味着储存字符串 “Hola” 的 Vec 的长度是四个字节:这里每一个字母的 UTF-8 编码都占用一个字节。如果有其它语言的编码,那么它的长度可能是不能确认的。比如对于let hello = String::from("Здравствуйте");这样的在rust里面不是12个字节,而是24个。这是使用 UTF-8编码 “Здравствуйте” 所需要的字节数,这是因为每个 Unicode 标量值需要两个字节存储。因此一个字符串字节值的索引并不总是对应一个有效的 Unicode 标量值。

let hello = String::from("Здравствуйте");
let s = &hello[0];

当使用 UTF-8 编码时,(西里尔字母的 Ze)З 的第一个字节是 208 ,第二个是 151 ,所以 s 实际上应该是 208 ,不过 208 自身并不是一个有效的字母。返回 208 可不是一个请求字符串第一个字母的人所希望看到的,不过它是Rust 在字节索引 0 位置所能提供的唯一数据。用户通常不会想要一个字节值被返回。即使这个字符串只有拉丁字母,如果 &“hello”[0] 是返回字节值的有效代码,它也会返回 104 而不是 h 。为了避免返回意外的值并造成不能立刻发现的 bug,Rust 根本不会编译这些代码,并在开发过程中及早杜绝了误会的发生。

Rust 提供了多种不同的方式来解释计算机储存的原始字符串数据,这样程序就可以选择它需要的表现方式,而无所谓是何种人类语言。
最后一个 Rust 不允许使用索引获取 String 字符的原因是,索引操作预期总是需要常数时间(O(1))。但是对于 String 不可能保证这样的性能,因为 Rust 必须从开头到索引位置遍历来确定有多少有效的字符。

2.5 字符串 slice

索引字符串不是一个好方案,因为字符串索引应该返回的类型是不明确的:字节值、字符、字形簇或者字符串 slice。因此,如果你真的希望使用索引创建字符串 slice 时,Rust 会要求你更明确一些。为了更明确索引并表明你需要一个字符串 slice,相比使用 [] 和单个值的索引,可以使用 [] 和一个 range来创建含特定字节的字符串 slice

let hello = "Здравствуйте";
let s = &hello[0..4];

这里,s 会是一个 &str ,它包含字符串的头四个字节。这些字母都是两个字节长的,所以这意味着 s 将会是 “Зд”。
如果获取 &hello[0…1] 会发生什么呢?答案是:Rust 在运行时会 panic,就跟访问 vector中的无效索引时一样

2.6 遍历字符串

操作字符串每一部分的最好的方法是明确表示需要字符还是字节。对于单独的 Unicode 标量值使用 chars 方法。对 “Зд” 调用 chars 方法会将其分开并返回两个 char 类型的值,接着就可以遍历其结果来访问每一个元素了

for c in "Зд".chars() {println!("{c}");
}

另外 bytes 方法返回每一个原始字节

for b in "Зд".bytes() {println!("{b}");
}

Rust 选择了以准确的方式处理 String 数据作为所有 Rust 程序的默认行为,这意味着程序员们必须更多的思考如何预先处理 UTF-8 数据。这种权衡取舍相比其他语言更多的暴露出了字符串的复杂性,不过也使你在开发周期后期免于处理涉及非 ASCII 字符的错误。

三、hashmap

哈希 map(hash map)。HashMap<K, V> 类型储存了一个键类型K 对应一个值类型 V 的映射。它通过一个 哈希函数(hashingfunction)来实现映射,决定如何将键和值放入内存中。

3.1 新建

可以使用 new 创建一个空的 HashMap ,并使用 insert 增加元素。

fn main() {use std::collections::HashMap;let mut scores = HashMap::new();scores.insert(String::from("Blue"), 10);scores.insert(String::from("Yellow"), 50);
}

3.2 访问

使用 get 方法进行访问。

    use std::collections::HashMap;let mut scores = HashMap::new();scores.insert(String::from("Blue"), 10);scores.insert(String::from("Yellow"), 50);let color_name = String::from("Blue");let score = scores.get(&color_name).copied().unwrap_or(0);

get 方法返回 Option<&V> ,如果某个键在哈希 map 中没有对应的值,get 会返回 None 。程序中通过调用 copied 方法来获取一个
Option 而不是 Option<&i32> ,接着调用 unwrap_or 在 scores 中没有该键所对应的项时将其设置为零。可以使用与 vector 类似的方式来遍历哈希 map 中的每一个键值对

    use std::collections::HashMap;let mut scores = HashMap::new();scores.insert(String::from("Blue"), 10);scores.insert(String::from("Yellow"), 50);for (k,v) in &scores {println!("{k}:{v}")}

3.3 哈希 map 和所有权

对于像 i32 这样的实现了 Copy trait 的类型,其值可以拷贝进哈希 map。对于像 String 这样拥有所有权的值,其值将被移动而哈希 map 会成为这些值的所有者

 use std::collections::HashMap;let field_name = String::from("Favorite");let field_value = String::from("Java");let mut map = HashMap::new();map.insert(field_name, field_value);// 这里 field_name 和 field_value 不再有效,// 尝试使用它们看看会出现什么编译错误

当 insert 调用将 field_name 和 field_value 移动到哈希 map 中后,将不能使用这两个绑定。

3.4 更新哈希 map

尽管键值对的数量是可以增长的,每个唯一的键只能同时关联一个值

  • 覆盖直接insert相同key的数据进去就行
  • 只在没有键的时候插入使用api map.entry(String::from("Favorite")).or_insert("Rust");
  • 根据旧值更新一个值
 use std::collections::HashMap;let text = "hello world wonderful world";let mut map = HashMap::new();for word in text.split_whitespace() {let count = map.entry(word).or_insert(0);*count += 1;}println!("{:?}", map);

3.5 删除键

在Rust中,可以使用remove方法从HashMap中删除一个键值对。

use std::collections::HashMap;fn main() {let mut map: HashMap<String, i32> = HashMap::new();map.insert("one".to_string(), 1);map.insert("two".to_string(), 2);map.insert("three".to_string(), 3);println!("Before removing: {:?}", map);map.remove("two");println!("After removing: {:?}", map);
}

3.6 哈希函数

HashMap 默认使用一种叫做 SipHash 的哈希函数,它可以抵御涉及哈希表(hash table) 的拒绝服务(Denial of Service, DoS)攻击。然而这并不是可用的最快的算法,不过为了更高的安全性值得付出一些性能的代价。如果性能监测显示此哈希函数非常慢,以致于你无法接受,你可以指定一个不同的 hasher 来切换为其它函数。hasher 是一个实现了 BuildHasher trait的类型。crates.io也提供了一些好用的第三方库。
要使用自定义哈希函数,需要实现std::hash::Hasher trait

use std::collections::HashMap;
use std::hash::{BuildHasher, Hasher};struct MyHasher {hash: u64,
}impl Hasher for MyHasher {fn write(&mut self, bytes: &[u8]) {for byte in bytes {self.hash = self.hash.wrapping_mul(31).wrapping_add(*byte as u64);}}fn finish(&self) -> u64 {self.hash}
}fn main() {let mut map: HashMap<String, i32, BuildHasherDefault<MyHasher>> = HashMap::default();map.insert("one".to_string(), 1);map.insert("two".to_string(), 2);map.insert("three".to_string(), 3);println!("Before removing: {:?}", map);map.remove("two");println!("After removing: {:?}", map);
}

相关文章:

Rust-10-数据类型

Rust 标准库中包含一系列被称为 集合&#xff08;collections&#xff09;的非常有用的数据结构。大部分其他数据类型都代表一个特定的值&#xff0c;不过集合可以包含多个值。不同于内建的数组和元组类型&#xff0c;这些集合指向的数据是储存在堆上的&#xff0c;这意味着数据…...

C#面:PDB是什么东西? 在调试中它应该放在哪里

C# PDB&#xff08;Program Database&#xff09;是一种用于存储调试信息的文件格式。它包含了源代码文件、符号表和其他调试相关的信息&#xff0c;可以帮助开发人员在调试过程中定位和解决问题 在调试中&#xff0c;PDB文件应该与编译生成的可执行文件&#xff08;如DLL或EX…...

C#--使用CMake构建C++程序调用示例

1.C代码 // example.cpp#include <iostream>extern "C" {__declspec(dllexport) void PrintMessage() {std::cout << "Hello from C!" << std::endl;} }2.CMakeLists.txt文件&#xff0c;用于使用CMake构建C库&#xff1a; # CMakeLis…...

三十七篇:大数据架构革命:Lambda与Kappa的深度剖析

大数据架构革命:Lambda与Kappa的深度剖析 1. 引言 在这个数据驱动的时代,我们面临着前所未有的挑战和机遇。随着数据量的爆炸性增长,传统的数据处理方法已无法满足现代业务的需求。大数据处理不仅涉及数据量的增加,还包括数据类型的多样化、数据来源的广泛性以及对实时数据…...

Vue3【十五】标签的Ref属性

Vue3【十五】标签的Ref属性 标签的ref属性 用于注册模板引用 用在dom标签上&#xff0c;获取的是dom节点 用在组件上&#xff0c;获取的是组件实例对象 案例截图 目录结构 代码 app.vue <template><div class"app"><h1 ref"title2">你…...

Java实现数据结构——顺序表

目录 一、前言 二、实现 2.1 增 2.2 删 2.3 查 2.4 改 2.5 销毁顺序表 三、Arraylist 3.1 构造方法 3.2 常用操作 3.3 ArrayList遍历 四、 ArrayList具体使用 4.1 杨辉三角 4.2 简单洗牌算法 一、前言 笔者在以前的文章中实现过顺序表 本文在理论上不会有太详细…...

线程知识点总结

Java线程是Java并发编程中的核心概念之一&#xff0c;它允许程序同时执行多个任务。以下是关于Java线程的一些关键知识点总结&#xff1a; 1. 线程的创建与启动 继承Thread类&#xff1a;创建一个新的类继承Thread类&#xff0c;并重写其run()方法。通过创建该类的实例并调用st…...

计算机网络:数据链路层 - 扩展的以太网

计算机网络&#xff1a;数据链路层 - 扩展的以太网 集线器交换机自学习算法单点故障 集线器 这是以前常见的总线型以太网&#xff0c;他最初使用粗铜轴电缆作为传输媒体&#xff0c;后来演进到使用价格相对便宜的细铜轴电缆。 后来&#xff0c;以太网发展出来了一种使用大规模…...

视频修复工具,模糊视频变清晰!

老旧视频画面效果差&#xff0c;视频效果模糊。我们经常找不到一个好的工具来让视频更清晰&#xff0c;并把它变成高清画质。相信很多网友都会有这个需求&#xff0c;尤其是视频剪辑行业的网友&#xff0c;经常会遇到这个问题。今天给大家分享一个可以把模糊视频修复清晰的工具…...

协程库——面试问题

1 同步、异步 1.1 同步 代码顺序执行&#xff0c;完全由用户控制. 同步阻塞 等待可读、可写的时候阻塞&#xff0c;不让出cpu。读、写之后&#xff0c;下面的代码才能执行、 同步非阻塞 等待可读、可写时&#xff0c;不会阻塞cpu&#xff0c;返回失败&#xff0c;设置错误码为…...

数据结构与算法题目集(中文)6-2顺序表操作集

题目地址 https://pintia.cn/problem-sets/15/exam/problems/type/6?problemSetProblemId725&page0 注意审题&#xff0c;返回false的时候不要返回ERROR&#xff0c;否则答案错误&#xff0c;机器规则是死的。 位置一般指数组下标&#xff0c;位序一般指数组下标1。但是思…...

8086 汇编笔记(十二):int 指令 端口 直接定址表

一、int 指令 int 指令的格式为:int n&#xff0c;n 为中断类型码&#xff0c;它的功能是引发中断过程 CPU 执行 intn 指令&#xff0c;相当于引发一个n号中断的中断过程&#xff0c;执行过程如下&#xff1a; (1) 取中断类型码 n; (2) 标志寄存器入栈&#xff0c;IF0&…...

揭开FFT时域加窗的奥秘

FFT – Spectral Leakage 假设用于ADC输出数据分析的采样点数为N&#xff0c;而采样率为Fs&#xff0c;那我们就知道&#xff0c;这种情况下的FFT频谱分辨率为δf&#xff0c;那么δfFs/N。如果此时我们给ADC输入一个待测量的单频Fin&#xff0c;如果此时Fin除以δf不是整数&a…...

【AI基础】第二步:安装AI运行环境

开局一张图&#xff1a; ​ 接下来按照从下往上的顺序来安装部署。 规则1 注意每个层级的安装版本&#xff0c;上层的版本由下层版本决定 比如CUDA的版本&#xff0c;需要看显卡安装了什么版本的驱动&#xff0c;然后CUDA的版本不能高于这个驱动的版本。 这个比较好理解&…...

【MySQL】聊聊唯一索引是如何加锁的

首先我们要明确&#xff0c;加锁的对象是索引&#xff0c;加锁的基本单位是next-key lock&#xff0c;由记录锁和间隙锁组成。next-key是前开后闭区间&#xff0c;间隙锁是前开后开区间。根据不同的查询条件next-key 可能会退化成记录锁或间隙锁。 在能使用记录锁或者间隙锁就…...

k8s-CCE使用node节点使用VIP--hostNetworkhostPort

CCE使用node节点使用VIP 背景:想在节点上使用VIP,将nodeport服务做到高可用。启动VIP后发现访问失败 部署 ! Configuration File for keepalived global_defs { router_id master-node }vrrp_instance VI_1 {state BACKUPinterface eth0mcast_src_ip 10.1.0.60virtual_rou…...

18、关于优化中央企业资产评估管理有关事项的通知

一、加强重大资产评估项目管理 (一)中央企业应当对资产评估项目实施分类管理,综合考虑评估目的、评估标的资产规模、评估标的特点等因素,合理确定本集团重大资产评估项目划分标准,原则上,企业对外并购股权项目应纳入重大资产评估项目。中央企业应当研究制定重大资产评估…...

AI大模型日报#0610:港大等1bit大模型“解决AI能源需求”、谷歌开源TimesFM时序预测模型

导读&#xff1a;AI大模型日报&#xff0c;爬虫LLM自动生成&#xff0c;一文览尽每日AI大模型要点资讯&#xff01;目前采用“文心一言”&#xff08;ERNIE 4.0&#xff09;、“零一万物”&#xff08;Yi-Large&#xff09;生成了今日要点以及每条资讯的摘要。欢迎阅读&#xf…...

速盾:图片cdn加速 免费

随着互联网的快速发展&#xff0c;图片在网页设计和内容传播中起着重要的作用。然而&#xff0c;随着网站访问量的增加和图片文件大小的增加&#xff0c;图片加载速度可能会成为一个问题。为了解决这个问题&#xff0c;许多网站使用图片CDN加速服务。 CDN&#xff08;Content …...

贪心算法例子

贪心算法概述 贪心算法是一种在每一步选择中都做出局部最优选择的算法,以期望通过一系列局部最优选择达到全局最优。贪心算法在许多优化问题中表现良好,特别是在某些特定类型的问题中能够保证找到最优解。 活动选择问题(Activity Selection Problem)背包问题(贪心解法)霍…...

vivado HW_ILA_DATA、HW_PROBE

HW_ILA_DATA 描述 硬件ILA数据对象是ILA调试核心上捕获的数据的存储库 编程到当前硬件设备上。upload_hw_ila_data命令 在从ila调试移动捕获的数据的过程中创建hw_ila_data对象 核心&#xff0c;hw_ila&#xff0c;在物理FPGA上&#xff0c;hw_device。 read_hw_ila_data命令还…...

refault distance算法的一点理解

这个算法看了好几次了&#xff0c;都没太理解&#xff0c;今天记录一下&#xff0c;加深一下印象。 引用某个博客对这个算法的介绍 一次访问page cache称为fault&#xff0c;第二次访问该页面称为refault。page cache页面第一次被踢出LRU链表并回收(eviction)的时刻称为E&#…...

软件安全技术【太原理工大学】

没有划重点&#xff0c;只说了一句课后题和实验中的内容都可能会出。 2022考试题型&#xff1a;选择20个20分&#xff0c;填空10个10分&#xff0c;名词解释4个20分&#xff0c;简答6个30分&#xff0c;分析与论述2个20分&#xff0c;没找到历年题。 如此看来&#xff0c;这门考…...

异常(Exception)

异常是什么 异常就是程序在进行时的不正常行为&#xff0c;就像之前数组时会遇到空指针异常&#xff08;NullPointerException&#xff09;&#xff0c;数组越界异常&#xff08;ArrayIndexOutOfBoundsException&#xff09;等等。 在java中异常由类来表示。 异常的分类 异常…...

一文者懂LLaMA 2(原理、模型、训练)

引言 LLaMA&#xff08;Large Language Model Meta AI&#xff09;是Meta&#xff08;前身为Facebook&#xff09;开发的自然语言处理模型家族之一&#xff0c;LLaMA 2作为其最新版本&#xff0c;展示了在语言理解和生成方面的显著进步。本文将详细解读LLaMA 2的基本原理、模型…...

MySQL 存储函数及调用

1.mysql 存储函数及调用 在MySQL中&#xff0c;存储函数&#xff08;Stored Function&#xff09;是一种在数据库中定义的特殊类型的函数&#xff0c;它可以从一个或多个参数返回一个值。存储函数在数据库层面上封装了复杂的SQL逻辑&#xff0c;使得在应用程序中调用时更加简单…...

设计模式七大原则-单一职责原则SingleResponsibility

七大原则是在设计“设计模式”的时候需要用到的原则&#xff0c;它们的存在是为了保证设计模式达到以下几种目的&#xff1a; 1.代码重用性 2.可读性 3.可拓展性 4.可靠性&#xff08;增加新的功能后&#xff0c;对原来的功能没有影响&#xff09; 5.使程序呈现高内聚、低耦合的…...

msfconsole利用Windows server2008cve-2019-0708漏洞入侵

一、环境搭建 Windows系列cve-2019-0708漏洞存在于Windows系统的Remote Desktop Services&#xff08;远程桌面服务&#xff09;&#xff08;端口3389&#xff09;中&#xff0c;未经身份验证的攻击者可以通过发送特殊构造的数据包触发漏洞&#xff0c;可能导致远程无需用户验…...

Reinforcement Learning学习(三)

前言 最近在学习Mujoco环境,学习了一些官方的Tutorials以及开源的Demo,对SB3库的强化学习标准库有了一定的了解,尝试搭建了自己的环境,基于UR5E机械臂,进行了一个避障的任务,同时尝试接入了图像大模型API,做了一些有趣的应用,参考资料如下: https://mujoco.readthedo…...

hw meta10 adb back up DCIM

1. centos install adb 2. HW enable devlepment mode & enalbe adb debug 3. add shell root/zt/adb-sync python3 ./adb-sync --reverse /sdcard/DCIM/Camera /root/zt/meta10...

西宁商城网站建设公司/seo推广是什么意思

第三卷 第十二章 年龄和性别预测 为了构建一个能够识别照片中人物年龄和性别的系统,我们将使用 Adience 数据集。我们训练两个模型,一个用于年龄识别,另一个用于性别识别。此外,我们还必须依靠更高级的计算机视觉算法,例如面部标志和面部对齐来帮助我们进行预处理 我们在分…...

网站备案怎么办/竞价外包代运营公司

SpringBoot开启https 生成证书 首先新建一个文件&#xff0c;一定要提前新建&#xff0c;要不然会报错&#xff08;回来补坑&#xff0c;后续的操作发现是不新建也可以&#xff0c;我也搞不明白了&#xff0c;都试试吧&#xff09; 我是在D盘新建了zhengshu文件夹&#xff0c…...

沈阳网站制作教学/房地产销售技巧和话术

这是我为简单线性回归创建的代码。这是密码&#xff0c;我有几个问题&#xff0c;我正在寻找答案。如何从X和Y中检测和删除异常值也许一个代码示例会有所帮助&#xff1f;您对模型部分的培训和评估质量有何看法&#xff1f;正确的交叉验证&#xff1f;列车试验装置&#xff1f;…...

计算机专业做网站的开题报告/百度网络小说排行榜

使用如下SQL语句: SET IDENTITY_INSERT IdentityTable ON INSERT IdentityTable(TheIdentity, TheValue) VALUES (3, First Row) SET IDENTITY_INSERT IdentityTable OFF 上面的一语句,一次只能操作一张表,必须完成一张表的操作之后才能操作另一张表. 如果插入的ID值比当前表中…...

电脑网站建设/百度域名注册官网

位置问题&#xff1a; 在bootstrap中用 datetimepicker 时默认是在输入框下面弹出的&#xff0c; 但是遇到输入框在屏幕最下面时&#xff0c;日期选择框会有一部分在屏幕下面&#xff0c;显示不了&#xff0c;因此需要能够从上面弹出。 可以在初始化时&#xff1a; $(.form_dat…...

阿里百秀wordpress/太原关键词排名推广

GetLastInputInfo是Windows中获取键盘和鼠标空闲时间的API1.调用函数GetLastInputInfo()以后, 结构成员lpi.dwTime 中的值并非上次输入事件发生以后的毫秒数。而是上次输入事件发生时的系统运行时间。相当于上次输入事件发生时执行了lpi.dwTime::GetTickCount()。::GetTickCoun…...