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

Rust基础学习-标准库

stand

栈和堆是我们Rust代码在运行时可以使用的内存部分。Rust是一种内存安全的编程语言。为了确保Rust是内存安全的,它引入了所有权、引用和借用等概念。要理解这些概念,我们必须首先了解如何在栈和堆中分配和释放内存。


栈可以被看作一堆书。当我们添加更多书时,我们把它们放在堆叠的顶部。当我们需要一本书时,我们从顶部拿一本。栈按顺序插入值。它获取它们并以相反的顺序移除值。

添加数据称为入栈,移除数据称为出栈。这种现象在编程中被称为后进先出(LIFO)。存储在栈上的数据在编译时必须具有固定大小。Rust默认为原始类型在栈上分配内存。

让我们通过一个示例来直观地展示如何在栈上分配和释放内存。

fn foo() {let y = 999;let z = 333;
}fn main() {let x = 111;foo();
}
  • 在上面的例子中,我们首先调用函数main()。 main() 函数有一个变量绑定 x。

  • 当 main() 执行时,我们将一个单独的 32 位整数(x)分配给堆栈帧。

AddressNameValue
0x111

在表中,Address列指的是RAM的内存地址。它从0开始,并且到你的计算机拥有多少RAM(字节数)为止。Name列指的是变量,Value列指的是变量的值。

当调用foo()时,将分配一个新的栈帧。foo()函数有两个变量绑定,y 和 z。

AddressNameValue
2z333
1y999
0x111
  • 实际上,计算机在现实中不会使用数字0、1和2来表示地址值。这些地址根据值的不同会相隔几个字节。
  • foo() 完成后,其堆栈帧将被释放。
AddressNameValue
0x111
  • 最后,main() 完成了,一切都消失了。Rust 自动在堆栈内外分配和释放内存。

与堆栈相反,大多数时候,我们需要将变量(内存)传递给不同的函数,并使它们的存活时间比单个函数的执行时间更长。这时候我们就可以使用堆了。
我们可以使用 Box<T> 类型在堆上分配内存。例如:

fn main() {let x = Box::new(100);let y = 222;println!("x = {}, y = {}", x, y);
}

x = 100, y = 222

AddressNameValue
1y222
0x???

和之前一样,我们在堆栈上分配两个变量 x 和 y。但是,当调用 Box::new() 时,x 的值会在堆上分配。因此,x 的实际值是指向堆的指针。这里使用????来表示;

AddressNameValue
5678100
1y222
0x→ 5678

在这里,变量 x 持有一个指向地址→ 5678 的指针,这是用于演示的任意地址。Heap 可以按任意顺序分配和释放。

因此它可能以不同的地址结束。

  • 当 x 被释放时,它首先释放在堆上分配的内存。
AddressNameValue
1y222
0x???

一旦main()完成,我们释放栈帧,所有东西都会被清空,释放所有内存。我们可以通过转移所有权使内存存活更久,堆可以比分配 Box 的函数存活更长时间。


栈和堆的区别

StackHeap
访问堆栈中的数据更快。访问堆中的数据速度较慢。
栈上内存管理可预测且简单堆上内存管理(任意大小)较为复杂。
Rust默认在栈上进行分配使用Box来分配堆内存。
函数的原始类型和局部变量在栈上分配动态大小的数据类型,如StringVecBox等,在堆上分配。

Vector

Vector 是一种动态(可调整大小)的数据结构,可以存储相同类型的元素列表。作为一种可调整大小的数据结构,vector可以在运行时增长和收缩。


创建Vector

let v = vec![1, 2, 3];
  • 使用 了vec!宏创建并初始化了一个vector,元素为1,2,3三个整数;
  • vec!宏通过给定的初始元素可以自动推断其类型,从而确定vector的类型为Vec<i32>;
  • 当然,我们也可以手动显式的指明类型,比如:
let v:Vec<u8> = vec![1,2,3];

打印输出vec中的元素,我们可以使用println!()宏并使用{:?}格式化;

fn main() {let v = vec![1, 2, 3, 4];println!("{:?}", v);
}

访问Vector元素

通过索引访问

vector中的每个元素都与一个唯一的数字序列相关联。这个数字被称为向量索引。我们可以使用向量索引访问向量的元素。假设我们有一个颜色向量。

let colors = vec!["blue","red","green"];

image-20240611104821264

我们可以使用它们对应的向量索引来访问单个矢量元素。例如:

colors[0] - 访问索引为 0 的元素(第一个元素)
colors[1] - 访问索引为 1 的元素(第二个元素)
colors[2] - 访问索引为 2 的元素(第三个元素)

fn main() {let colors = vec!["blue", "red", "green"];// method 1: access vector elements using vector indexprintln!("first color = {}", colors[0]);println!("second color = {}", colors[1]);println!("third color = {}", colors[2]);
}
通过get方法访问

还是之前的代码:

let colors = vec!["blue", "red", "green"];

我们可以使用 get() 方法访问该向量的元素。get() 方法不会直接返回向量元素,而是返回一个类型为Option<T>的枚举。结果要么是 Some(T),要么是 None

colors.get(0) - 返回索引为 0 的 Some 值
colors.get(1) - 返回索引为 1 的 Some 值
colors.get(2) - 返回索引为 2 的 Some 值

colors.get(3) will return None

fn main() {let colors = vec!["blue", "red", "green"];// method 2: access vector elements using get() method and vector indexprintln!("first color = {:?}", colors.get(0));println!("second color = {:?}", colors.get(1));println!("third color = {:?}", colors.get(2));
}

输出:

first color = Some(“blue”)
second color = Some(“red”)
third color = Some(“green”)


向Vector中添加元素

我们可以通过在Rust中创建可变向量来向向量添加值。 我们可以在将向量分配给变量之前使用mut关键字使其可变。 例如,

let mut v = vec![2,4,6,8,10];

使用push()方法添加元素;

fn main() {let mut number = vec![2, 4, 6, 8, 10];println!("{:?}:", number);number.push(12);number.push(14);println!("修改后的vector:{:?}", number);
}

移除Vector中的元素

我们可以通过将Vector变为可变,并使用remove()方法来从矢量中移除值。例如,

fn main() {let mut even_numbers = vec![2, 4, 6, 8, 10];println!("original vector = {:?}", even_numbers);// remove value from the vector in its second indexeven_numbers.remove(2);println!("changed vector = {:?}", even_numbers);
}

遍历Vector

可以使用for循环来遍历vector中的元素;

fn main() {let colors = vec!["blue", "red", "green"];let mut index = 0;for color in colors {println!("Index: {} -- Value: {}", index, color);index = index + 1;}
}

应优先选择 for 循环而不是 [] 运算符来访问向量元素,因为使用 [] 访问会产生运行时成本,需要进行越界检查。


使用vec::new()创建Vector

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

在这里,我们创建一个空的向量来保存 i32 类型的值。

  • Vec<i32> - 向量的类型,其中i32是向量中所有元素的数据类型
  • Vec::new() - 使用 new() 方法初始化一个空向量
fn main() {// vector creation with Vec::new() methodlet mut v: Vec<i32> = Vec::new();// push values to a mutable vectorv.push(10);v.push(20);println!("v = {:?}", v);
}

Rust String

Rust中的字符串是以UTF-8编码的Unicode字符序列。

例如,“Rust编程”是一个字符串,其中每个字符都是有效的Unicode字符。即“R”,“u”,“s”,“t”,“ ”等等。

使用String::from()创建字符串

let word = String::from("Hello, World!");

在这里,我们创建一个新的字符串并将其分配给word变量。我们还提供了"Hello, World!"的默认值。

字符串是在堆内存中分配的,并具有动态(可调整大小)的特性。因此,在编译时大小未知。

fn main() {// string creation using String::from() methodlet word = String::from("Hello, World!");println!("word = {}", word);
}

可变字符串

let mut word = String::from("cat");

由于使用了mut关键字,我们可以再次修改字符串

fn main() {let mut word = String::from("cat");println!("original string = {}", word);word.push_str(" dog");println!("changed string = {}", word);
}

original string = cat
changed string = cat dog


字符串切片

我们可以在Rust中对字符串进行切片,以引用字符串的一部分。字符串切片允许我们引用字符串的一部分。例如:

fn main() {let w = String::from("Hello Rust!");let slice = &w[0..5];println!("string = {}", w);println!("slice:{}", slice);
}

在这里,&word[0..5] 是对存储在变量 w 中的字符串进行切片的表示法,从起始索引 0(包括)到结束索引 5(不包括)。切片语法中的 &(和)表示这是一个字符串引用,而不是实际数据。

切片也用于访问存储在数组和向量中的数据的部分。


字符串中的迭代器

我们可以使用字符串类型的chars()方法来迭代字符串。例如,

fn main() {let str = String::from("Hello");for char in str.chars() {println!("{}",char);}
}

在这里,我们使用 chars() 方法迭代所有字符并打印每个字符。


当然,你也可以创建一个空字符串之后再使用push()方法添加元素;

fn main() {// create an empty stringlet mut word = String::new();println!("original string = {}", word);// append a string to the word variableword.push_str("Hello, World!");println!("changed string = {}", word);
}

Rust 中的 String 和 str 有什么区别?

在 Rust 中,我们可以将字符串分为两种类型:String 和 str。
String

  • 是一种在堆数据结构中分配内存的数据类型。
  • 具有固定的大小并且可以修改。
  • str
  • 是存储在内存中某处的字符串的视图。
  • 也称为字符串切片,只能使用指针如 &str 进行处理。

HashMap

Rust HashMap 数据结构允许我们以键-值对的方式存储数据。以下是 HashMap 的一些特点:

  • 每个值都与相应的键相关联。
  • 键是唯一的,而值可以重复。
  • 可以使用它们对应的键访问值。

使用

HashMap包含在了conllections标准库中,所以在使用之前需要先导入相关的库,

use std::collections::HashMap;
  • 使用new()方法创建一个HashMap;
let mut info:HashMap<i32,String> = HashMap::new();
  • 声明一个可变变量 info
  • HashMap<i32, String> - HashMap 的类型,其中键是 Integer,值是 String
  • HashMap::new() - 创建一个新的 HashMap

同样,也可以使用{:?}宏来打印HashMap的内容;

// import HashMap from Rust standard collections library
use std::collections::HashMap;fn main() {// create a new HashMaplet mut info: HashMap<i32, String> = HashMap::new();println!("HashMap = {:?}", info);
}

HashMap中的一些基本操作

1. 添加元素

使用insert()方法向Map中插入元素:

use std::collections::HashMap;fn main() {let mut fruits: HashMap<i32, String> = HashMap::new();// add key-value in a hashmapfruits.insert(1, String::from("Apple"));fruits.insert(2, String::from("Banana"));println!("fruits = {:?}", fruits);
}

注意,只有变量声明为mut才有可能向HashMap添加新的键值对。


2. 访问元素

可以使用get()方法访问HashMap中的元素;

use std::collections::HashMap;
fn main() {let mut mobile: HashMap<i32, String> = HashMap::new();mobile.insert(1, String::from("Apple"));mobile.insert(2, String::from("Xiaomi"));mobile.insert(3, String::from("Huawei"));let first_mobile = mobile.get(&1);let second_mobile = mobile.get(&2);let third_mobile = mobile.get(&3);let third_mobile = fruits.get(&4);println!("first  = {:?}", first_mobile);println!("second  = {:?}", second_mobile);println!("third  = {:?}", third_mobile);
}
  • get() 方法的输出是一个 Option 枚举,这意味着如果作为参数传递的键匹配,它将返回一些值;
  • 如果不匹配,则返回 None
  • 在上面的例子中,let third_mobile = fruits.get(&4) 返回 None,因为键 &4没有匹配到哈希映射中的任何内容。

3. 移除元素

可以使用remove()方法从HashMap中移除元素;

use std::collections::HashMap;fn main() {let mut fruits: HashMap<i32, String> = HashMap::new();// insert values in a hashmapfruits.insert(1, String::from("Apple"));fruits.insert(2, String::from("Banana"));println!("fruits before remove operation = {:?}", fruits);// remove value in a hashmapfruits.remove(&1);println!("fruits after remove operation = {:?}", fruits);
}

在这里,我们使用remove()方法从hashmap中删除键为1的元素。


4. 修改元素

我们可以使用insert()方法对使用了mut声明的可变HashMap进行再次修改;

use std::collections::HashMap;fn main() {let mut fruits: HashMap<i32, String> = HashMap::new();// insert values in a hashmapfruits.insert(1, String::from("Apple"));fruits.insert(2, String::from("Banana"));println!("Before update = {:?}", fruits);// change value of hashmap with key of 1fruits.insert(1, String::from("Mango"));println!("After update = {:?}", fruits);
}

一个个列举就到这了,下面是一些其他常用方法,请自己多练:

英文版看起更加协调和舒服,原汁原味就不翻译了。

MethodDescription
len()Returns the length of the HashMap.
contains_key()Checks if a value exists for the specified key.
iter()Returns an iterator over the entries of a HashMap.
values()Returns an iterator over the values of a HashMap.
keys()Returns an iterator over the keys of a HashMap.
clone()Creates and returns a copy of the HashMap.

HashSet

HashSet Rust 中实现了集合数据结构。就像集合一样,它允许我们存储没有重复的值。

同样,在使用之前,我们需要导入相对应的依赖:

use std::collections::HashSet;

我们使用use声明导入了HashSet模块。它应该位于程序顶部。现在,我们可以使用HashSet模块的new()方法来创建一个hashset

let mut color: HashSet<String> = HashSet::new();

let mut color - 声明一个可变变量 color
HashSet<String> - 哈希集的类型,其中值的类型为字符串
HashSet::new() - 创建一个新的哈希集

// import HashSet from Rust standard collections library
use std::collections::HashSet;fn main() {// create a new HashSetlet mut color: HashSet<String> = HashSet::new();println!("HashSet = {:?}", color);
}

基本操作

1. 添加元素

还是可以使用insert()方法来添加元素:

use std::collections::HashSet;fn main() {let mut colors: HashSet<&str> = HashSet::new();// insert values in a HashSetcolors.insert("Red");colors.insert("Yellow");colors.insert("Green");println!("colors = {:?}", colors);
}

colors = {“Green”, “Yellow”, “Red”}

在这里,输出的元素以不同的顺序显示。这是因为 hashset 不保证值的插入顺序,也就是无序的。


2.在Rust中检查HashSet中是否存在值

我们使用 contains() 方法来检查值是否存在于哈希集中。如果指定的元素存在于哈希集中,则该方法返回 true,否则返回 false。让我们看一个例子,

use std::collections::HashSet;fn main() {let mut colors: HashSet<&str> = HashSet::new();colors.insert("Red");colors.insert("Yellow");println!("colors = {:?}", colors);// check for a value in a HashSetif colors.contains("Red") {println!("We have the color \"Red\" in the HashSet.")}
}

colors = {“Red”, “Yellow”}
We have the color “Red” in the HashSet.

在上面的示例中,我们使用colors.contains("Red")作为 if 语句的条件。这里,元素 Red 存在于 hashset 中,所以条件为 true。因此,我们获得了期望的输出。


3. 移除元素

我们可以使用 remove() 方法从 hashset 中移除指定的元素。例如,

use std::collections::HashSet;fn main() {let mut colors: HashSet<&str> = HashSet::new();colors.insert("Red");colors.insert("Yellow");colors.insert("Green");println!("colors before remove operation = {:?}", colors);// remove value from a HashSetcolors.remove("Yellow");println!("colors after remove operation = {:?}", colors);
}

4. 使用for循环遍历
use std::collections::HashSet;fn main() {let mut colors: HashSet<&str> = HashSet::new();colors.insert("Red");colors.insert("Yellow");colors.insert("Green");// iterate over a hashsetfor color in colors {// print each value in the hashsetprintln!("{}", color);}
}

在这里,我们迭代名为colors的哈希集,并打印每个元素。


5.使用初始值值创建HashSet

我们还可以在创建时使用 from() 方法创建一个带有默认值的哈希集。例如,

use std::collections::HashSet;fn main() {// Create HashSet with default set of values using from() methodlet numbers = HashSet::from([2, 7, 8, 10]);println!("numbers = {:?}", numbers);
}

在这里,我们使用HashSet::from()方法创建一个带有默认值的哈希集,并将其打印到屏幕上。


6. 其他方法
MethodDescription
len()returns the length of a hashset
is_empty()checks if the hashset is empty
clear()removes all elements from the hashset
drain()returns all the elements as an iterator and clears the hashset

7.计算两个集合的并集

我们可以使用 union() 方法来查找两个集合的并集。例如,

use std::collections::HashSet;fn main() {let hashset1 = HashSet::from([2, 7, 8]);let hashset2 = HashSet::from([1, 2, 7]);// Union of hashsetslet result: HashSet<_> = hashset1.union(&hashset2).collect();println!("hashset1 = {:?}", hashset1);println!("hashset2 = {:?}", hashset2);println!("union = {:?}", result);
}

hashset1 = {7, 8, 2}
hashset2 = {2, 7, 1}
union = {2, 7, 8, 1}

union() 方法返回一个迭代器,因此我们使用了collect() 方法来获取实际结果。


8. 计算交集

我们可以使用 Intersection() 方法来查找两个集合之间的交集。例如,

use std::collections::HashSet;fn main() {let hashset1 = HashSet::from([2, 7, 8]);let hashset2 = HashSet::from([1, 2, 7]);// Intersection of hashsetslet result: HashSet<_> = hashset1.intersection(&hashset2).collect();println!("hashset1 = {:?}", hashset1);println!("hashset2 = {:?}", hashset2);println!("intersection = {:?}", result);
}

9.Difference()

我们可以使用 Difference() 方法来查找两个集合之间的差异。例如,

use std::collections::HashSet;fn main() {let hashset1 = HashSet::from([1, 2, 3, 4]);let hashset2 = HashSet::from([4, 3, 2]);// Difference between hashsetslet result: HashSet<_> = hashset1.difference(&hashset2).collect();println!("hashset1 = {:?}", hashset1);println!("hashset2 = {:?}", hashset2);println!("difference = {:?}", result);
}

我们可以使用 symmetric_difference() 方法来找到两个集合之间的对称差异。对称差异返回的是两个集合中各自独有的元素,而不包括两个集合共有的元素。

use std::collections::HashSet;fn main() {let hashset1 = HashSet::from([2, 7, 8]);let hashset2 = HashSet::from([1, 2, 7, 9]);// Symmetric difference of hashsetslet result: HashSet<_> = hashset1.symmetric_difference(&hashset2).collect();println!("hashset1 = {:?}", hashset1);println!("hashset2 = {:?}", hashset2);println!("symmetric difference = {:?}", result);
}

hashset1 = {8, 7, 2}
hashset2 = {2, 9, 1, 7}
symmetric difference = {8, 9, 1}

相关文章:

Rust基础学习-标准库

栈和堆是我们Rust代码在运行时可以使用的内存部分。Rust是一种内存安全的编程语言。为了确保Rust是内存安全的&#xff0c;它引入了所有权、引用和借用等概念。要理解这些概念&#xff0c;我们必须首先了解如何在栈和堆中分配和释放内存。 栈 栈可以被看作一堆书。当我们添加更…...

django连接达梦数据库

为了在Django中连接达梦数据库&#xff0c;你需要确保你有达梦的数据库驱动。Django默认支持的数据库有PostgreSQL, MySQL, SQLite, Oracle等&#xff0c;但不包括达梦数据库。不过&#xff0c;对于大多数数据库&#xff0c;Django的数据库API是通用的&#xff0c;你可以通过第…...

Python深度学习基于Tensorflow(17)基于Transformer的图像处理实例VIT和Swin-T

文章目录 VIT 模型搭建Swin-T 模型搭建参考 这里使用 VIT 和 Swin-T 在数据集 cifar10 上进行训练 VIT 模型搭建 导入需要的外部库 import numpy as np import tensorflow as tf import matplotlib.pyplot as plt import matplotlib.gridspec as gridspec这里我们接着使用 ci…...

树莓派4B_OpenCv学习笔记5:读取窗口鼠标状态坐标_TrackBar滑动条控件的使用

今日继续学习树莓派4B 4G&#xff1a;&#xff08;Raspberry Pi&#xff0c;简称RPi或RasPi&#xff09; 本人所用树莓派4B 装载的系统与版本如下: 版本可用命令 (lsb_release -a) 查询: Opencv 版本是4.5.1&#xff1a; 今日学习:读取窗口鼠标状态坐标_TrackBar滑动条控件的使…...

c、c#、c++嵌入式比较?

嵌入式系统是专门设计用于特定用途的计算机系统&#xff0c;通常用于控制、监视或执行特定任务。这些系统通常具有严格的资源限制&#xff0c;如内存、处理器速度和能耗。因此&#xff0c;在选择编程语言时&#xff0c;需要考虑到这些限制以及系统的特性。 对于嵌入式系统&…...

如何使用ai人工智能作诗?7个软件帮你快速作诗

如何使用ai人工智能作诗&#xff1f;7个软件帮你快速作诗 使用AI人工智能作诗是一种创新的写作方式&#xff0c;以下是一些可以帮助您快速作诗的AI人工智能软件&#xff1a; 1.AI创作云&#xff1a; 这是一个AI诗歌助手应用程序&#xff0c;可以根据您提供的主题或关键词生成…...

调用华为API实现语音合成

目录 1.作者介绍2.华为云语音合成2.1 语音合成介绍2.2 华为语音合成服务2.3 应用场景 3. 实验过程以及结果3.1 获取API密钥3.2 调用语音合成算法API3.3 实验代码3.4 运行结果 1.作者介绍 袁斌&#xff0c;男&#xff0c;西安工程大学电子信息学院&#xff0c;2023级研究生 研究…...

docker实战命令大全

文章目录 1 环境准备1.1 移除旧版本Docker1.2安装工具包1.3配置docker yum源 2 安装最新docker2.1 设置开机自启docker2.2配置加速器 3 实操-镜像3.1搜索镜像3.2下载镜像3.3查看镜像3.4 删除镜像 4 实操-容器4.1运行nginx容器4.2 查看容器4.3启动容器4.5关闭容器4.6查看容器日志…...

Java线程死锁

在Java中&#xff0c;线程死锁通常发生在两个或更多个线程相互等待对方释放资源的情况下。以下是一个简单的Java示例&#xff0c;展示了如何创建线程死锁&#xff1a; public class DeadlockDemo {// 定义两个资源private static Object resource1 new Object();private stat…...

virtual box安装invalid installation directory

问题原因 看官方文档Chapter 2. Installation Details 第2.1.2所示&#xff0c;安装目录需要满足两个条件&#xff1a; 一是&#xff1a;需要安装目录的所有父目录都要满足以下访问控制条件 Users S-1-5-32-545:(OI)(CI)(RX) Users S-1-5-32-545…...

概率分析和随机算法

目录 雇佣问题 概率分析 随机算法 生日悖论 随机算法 概率分析 球与箱子 总结 雇佣问题 有n个候选人面试&#xff0c;如果面试者比目前雇佣者的分数高&#xff0c;评价更好&#xff0c;那么就辞掉当前雇佣者&#xff0c;而去聘用面试者&#xff0c;否则继续面试新的候…...

15_2 Linux Shell基础

15_2 Linux Shell基础 文章目录 15_2 Linux Shell基础[toc]1. shell基本介绍1.1 什么是shell1.2 shell使用方式1.3 脚本的执行方式1.4 脚本练习 2. 变量的种类2.1 自定义变量2.2 环境变量&#xff0c;由系统提前定义好&#xff0c;使用时直接调用2.3 位置变量与预定变量2.4 变量…...

Catia装配体零件复制

先选中要复制的零件 然后选中复制到的父节点才可以。 否则 另外一种方法是多实例化...

实用小工具-python esmre库实现word查找

python esmre库实现word查找 前言&#xff1a; 在文本中匹配特定的字符串&#xff0c;一般可以用普通的字符串匹配算法&#xff0c;KMP算法&#xff1b; python中提供了一个库&#xff0c;esmre, 通过预先将字符串存到esm对象中&#xff0c;利用这些字符串从候选的字符串中进行…...

SSM框架整合,内嵌Tomcat。基于注解的方式集成

介绍&#xff1a; SSM相信大家都不陌生&#xff0c;在spring boot出现之前&#xff0c;SSM一直是Java在web开发中的老大哥。现在虽说有了spring boot能自动整合第三方框架了&#xff0c;但是现在市面上任然有很多老项目是基于SSM技术的。因此&#xff0c;能熟练掌握SSM进行开发…...

系统架构设计师【论文-2016年 试题4】: 论微服务架构及其应用(包括写作要点和经典范文)

论微服务架构及其应用&#xff08;2016年 试题4&#xff09; 近年来&#xff0c;随着互联网行业的迅猛发展&#xff0c;公司或组织业务的不断扩张&#xff0c;需求的快速变化以及用户量的不断增加&#xff0c;传统的单块(Monolithic)软件架构面临着越来越多的挑战&#xff0c;…...

面试题:String 、StringBuffer 、StringBuilder的区别

String、StringBuffer、和StringBuilder都是用于处理字符串的操作类&#xff0c;但它们之间存在一些关键性的差异&#xff1a; 1.不可变性与可变性&#xff1a; String&#xff1a;字符串常量&#xff0c;是不可变的。一旦创建&#xff0c;其内容就不能被改变。对字符串的任何…...

TLS指纹跟踪网络安全实践(C/C++代码实现)

TLS指纹识别是网络安全领域的重要技术&#xff0c;它涉及通过分析TLS握手过程中的信息来识别和验证通信实体的技术手段。TLS&#xff08;传输层安全&#xff09;协议是用于保护网络数据传输的一种加密协议&#xff0c;而TLS指纹则是该协议在实际应用中产生的独特标识&#xff0…...

小白学RAG:大模型 RAG 技术实践总结

节前&#xff0c;我们组织了一场算法岗技术&面试讨论会&#xff0c;邀请了一些互联网大厂朋友、今年参加社招和校招面试的同学。 针对大模型技术趋势、大模型落地项目经验分享、新手如何入门算法岗、该如何准备面试攻略、面试常考点等热门话题进行了深入的讨论。 汇总合集…...

Doris Connector 结合 Flink CDC 实现 MySQL 分库分表

1. 概述 在实际业务系统中为了解决单表数据量大带来的各种问题&#xff0c;我们通常采用分库分表的方式对库表进行拆分&#xff0c;以达到提高系统的吞吐量。 但是这样给后面数据分析带来了麻烦&#xff0c;这个时候我们通常试将业务数据库的分库分表同步到数据仓库时&#x…...

ModbusTCP、TCP/IP都走网线,一样吗?

在现代通信技术中&#xff0c;Modbus/TCP和TCP/IP协议是两种广泛应用于工业自动化和网络通信领域的协议。尽管它们都运行在网线上&#xff0c;但它们在设计、结构和应用场景上有着明显的区别。 Modbus/TCP协议是什么 Modbus/TCP是一种基于TCP/IP的应用层协议&#xff0c;它是Mo…...

网络学习(13)|Spring Boot中获取HTTP请求头(Header)内容的详细解析

文章目录 方法一&#xff1a;使用HttpServletRequest实现原理代码示例优点缺点适用场景 方法二&#xff1a;使用RequestContextHolder实现原理代码示例优点缺点适用场景 方法三&#xff1a;使用RequestHeader注解实现原理代码示例优点缺点适用场景 总结 在Spring Boot应用中&am…...

【漏洞复现】宏景eHR pos_dept_post SQL注入漏洞

0x01 产品简介 宏景eHR人力资源管理软件是一款人力资源管理与数字化应用相融合&#xff0c;满足动态化、协同化、流程化、战略化需求的软件。 0x02 漏洞概述 宏景eHR pos_dept_post 接囗处存在SQL注入漏洞,未经过身份认证的远程攻击者利用此漏洞执行任意SQL指令&#xff0c;…...

82. 删除排序链表中的重复元素 and II

链接直达&#xff1a; 保留重复元素 不保留重复元素 题目&#xff1a; 1: 给定一个已排序的链表的头 head &#xff0c; 删除所有重复的元素&#xff0c;使每个元素只出现一次 。返回 已排序的链表 。示例 1&#xff1a;输入&#xff1a;head [1,1,2] 输出&#xff1a;[1…...

C++ 判断目标文件是否被占用(独占)(附源码)

在IM软件中发起文件发送时,如果要发送的是某word文件,并且该word文件被office打开,则会提示文件正在被占用无法发送,如下所示: 那文件被占用到底是如何判断出来的呢?其实很简单,调用系统API函数CreateFile,打开该文件(OPEN_EXISTING),传入FILE_SHARE_READ共享读标记…...

计划任务 之 一次性的计划任务

计划任务 作用:定时自动完成特定的工作 计划任务的分类&#xff1a; &#xff08;1&#xff09;一次性的计划任务 例如下周三对系统的重要文件备份一次 &#xff08;2&#xff09;周期性重复计划任务 例如每天晚上12&#xff1a;00备份一次 一次性的任务计划&#xff1a…...

非比较排序之计数排序

目录 一、什么是计数排序 二、思路 三、代码实现 一、什么是计数排序 计数排序是一种非比较型的排序算法&#xff0c;它通过统计待排序数据中每个元素出现的次数&#xff0c;然后根据这个次数来进行排序。计数排序的具体步骤如下&#xff1a; 首先找出待排序数据中的最大值…...

Django路由与会话深度探索:静态、动态路由分发,以及Cookie与Session的奥秘

系列文章目录 Django入门全攻略&#xff1a;从零搭建你的第一个Web项目Django ORM入门指南&#xff1a;从概念到实践&#xff0c;掌握模型创建、迁移与视图操作Django ORM实战&#xff1a;模型字段与元选项配置&#xff0c;以及链式过滤与QF查询详解Django ORM深度游&#xff…...

第7章 用户输入和 while 循环

第7章 用户输入和 while 循环 7.1 函数 input()的工作原理7.1.1 编写清晰的程序7.1.2 使用 int()来获取数值输入7.1.3 求模运算符 7.2 while 循环简介7.2.1 使用 while 循环7.2.2 让用户选择何时退出7.2.3 使用标志7.2.4 使用 break 退出循环7.2.5 在循环中使用 continue7.2.6 …...

xshell远程无法链接上VM的centos7

1、现象如下&#xff0c; 2.1解决办法&#xff1a;查证后发现这个默认的设置为vmnet0 2.2解决办法&#xff1a;重启win10的虚拟机网卡&#xff08;先禁用再启用&#xff09; 3.参考文章&#xff1a;Xshell连接不上虚拟机centos7_centos7的nat模式可以ping通网络,但是用xshell连…...

种植园网站模板/免费b2b网站推广有哪些

以下学习内容摘录自boost官网 例1. 最简单的HelloWorld例程 #include <boost/python.hpp> // 预备导出的函数 char const* greet() {return "hello, world"; } // 注册PYTHON模块hello_ext BOOST_PYTHON_MODULE(hello_ext) {using namespace boost::python;  …...

网站主题 模板/下载百度安装

最近做了个项目&#xff0c;该项目可以方便查询全国地铁线路&#xff0c;地铁线路上模拟小车到站提醒&#xff0c;点击小车可触发相关事件&#xff0c;使用的有 百度地图查询地铁线路 &#xff0c;地铁图api&#xff0c;再结合vue-baidu-map 1.判断地铁线路图加载完成 //会有…...

好的文化网站模板下载/网站的seo 如何优化

修改COM口的端口号...

百度搜索不到网站/51网站统计

a3;b4.5;printf(%f%dn,a,b);编译时不给出出错信息&#xff0c;但运行结果将与原意不符。这种错误尤其需要注意。11.输入数据时&#xff0c;企图规定精度。scanf(%7.2f,a);这样做是不合法的&#xff0c;输入数据时不能规定精度。12.switch语句中漏写break语句。例如&#xff1a;…...

专业做消防工程师的正规网站/深圳网站关键词优化推广

2019独角兽企业重金招聘Python工程师标准>>> 以项目名为myTest,当前类名为test(其中package com.sun.app)&#xff0c;test.txt为test同目录下为例&#xff1a; 全路径&#xff1a; 1.当前类test.class文件的URI目录 URL url test.class.getResource("")…...

网站建设方案的重要性/国际新闻今天

题目看这里 一看求和就知道是要先用前缀和的 让后看到类似相等和不相等的条件&#xff0c;可以考虑并查集 当然这道题由于变量的值一定是0,1所以关系只有不等号也有反传递性&#xff0c;可以直接拆点来做 如果s[i]s[j]那么我们就将i,j所在的并查集合并&#xff0c;将i和j所在的…...