告别内存泄漏:你的Rust语言30天征服计划

欢迎踏上Rust学习之旅!


第一周:奠定基础 (Week 1: Laying the Foundation)

第1天:环境搭建与 “Hello, World!”

  • 核心概念: 安装Rust工具链 (rustup),它包含了编译器rustc和包管理器Cargo。Cargo是你的好朋友,用于创建项目、构建、测试和管理依赖。

  • 代码示例: main.rs 文件内容

    // main函数是每个可执行Rust程序的入口点
    fn main() {// println! 是一个宏,用于将文本打印到控制台println!("Hello, world!");
    }
    
  • 编程练习:

    1. 访问 rustup.rs 并按照说明安装Rust。

    2. 打开终端,运行 cargo new hello_rust 创建一个新项目。

    3. 进入 hello_rust/src/main.rs 文件,修改打印内容为你自己的问候语。

    4. 在项目根目录运行 cargo run,看到输出。

第2天:变量、可变性与数据类型初探

  • 核心概念: Rust中的变量默认是不可变的(immutable)。使用mut关键字可以使其变为可变的。Rust是静态类型语言,但编译器通常可以推断出你想要的类型。

  • 代码示例:

    fn main() {// 默认不可变let x = 5;println!("The value of x is: {}", x);// x = 6; // <-- 这行会编译错误!// 使用 mut 关键字使其可变let mut y = 10;println!("The initial value of y is: {}", y);y = 20;println!("The new value of y is: {}", y);
    }
    
  • 编程练习: 创建一个程序,声明一个不可变变量spaces并赋值为一个字符串。再声明一个同名的可变变量,记录字符串的长度。这种“遮蔽”(Shadowing)是允许的。

第3天:标量数据类型 (Scalar Types)

  • 核心概念: 了解Rust的四种基本标量类型:整数、浮点数、布尔值和字符。

  • 代码示例:

    fn main() {// 整数 (Integer)let apples: i32 = 5; // 带类型标注let bananas = 10u64; // 带类型后缀// 浮点数 (Floating-Point)let pi: f64 = 3.14159;// 布尔值 (Boolean)let is_rust_fun: bool = true;// 字符 (Character) - 使用单引号let heart_eyed_cat = '😻';println!("Apples: {}, Bananas: {}, Pi: {}", apples, bananas, pi);println!("Is Rust fun? {}, Look: {}", is_rust_fun, heart_eyed_cat);
    }
    
  • 编程练习: 编写一个程序,进行一些基本的数学运算,比如整数加法和浮点数除法,并将结果打印出来。

第4天:函数 (Functions)

  • 核心概念: 使用fn关键字定义函数。函数可以有参数和返回值。表达式的最后一个值若不带分号,则会作为函数的返回值。

  • 代码示例:

    fn main() {let sum = add_five(10);println!("10 + 5 = {}", sum);
    }// 定义一个函数,接收一个 i32 参数,返回一个 i32
    fn add_five(x: i32) -> i32 {x + 5 // 这是一个表达式,它的值将作为函数的返回值
    }
    
  • 编程练习: 编写一个名为celsius_to_fahrenheit的函数,它接收一个f64类型的摄氏温度作为参数,返回转换后的华氏温度(公式:F=Ctimes1.8+32)。在main函数中调用它并打印结果。

第5天:控制流 (Control Flow)

  • 核心概念: 学习if-else表达式和三种循环:loop, while, for

  • 代码示例:

    fn main() {let number = 6;if number % 4 == 0 {println!("number is divisible by 4");} else if number % 3 == 0 {println!("number is divisible by 3");} else {println!("number is not divisible by 4 or 3");}// for 循环for i in 1..=5 { // `..=` 表示包含5println!("Looping: {}", i);}
    }
    
  • 编程练习: 使用loop循环,在循环体中将一个计数器加一,当计数器达到10时,使用break关键字并从循环中返回计数器的两倍值。

第6天:复合类型:元组(Tuple)和数组(Array)

  • 核心概念: 元组是固定长度、可包含多种类型的集合。数组是固定长度、所有元素必须是相同类型的集合。

  • 代码示例:

    fn main() {// 元组 (Tuple)let user_info: (&str, i32, bool) = ("Alice", 30, true);// 解构元组let (name, age, _is_active) = user_info;println!("User: {}, Age: {}", name, age);// 通过索引访问println!("First element: {}", user_info.0);// 数组 (Array)let months: [&str; 3] = ["January", "February", "March"];println!("The first month is: {}", months[0]);
    }
    
  • 编程练习: 创建一个元组来存储一个HTTP状态(状态码u16,消息&str),例如(200, "OK")。然后创建一个包含5个浮点数的数组,计算并打印它们的平均值。

第7天:所有权 (Ownership)

  • 核心概念: 内存由“所有者”管理。当所有者离开作用域,值被清理。值只能有一个所有者。赋值操作会发生“移动”(Move)。

  • 代码示例:

    fn main() {// s1 拥有一个 Stringlet s1 = String::from("hello");// s1 的所有权被“移动”到 s2let s2 = s1;// println!("s1 is {}", s1); // <-- 这行会编译错误!因为 s1 不再拥有数据println!("s2 is {}", s2); // s2 现在是所有者,可以被使用
    }
    
  • 编程练习: 创建一个String类型的变量s1。将其赋值给s2。然后尝试打印s1,仔细阅读并理解编译器关于“值被移动”(value moved)的错误信息。


第二周:深入所有权与结构化数据

第8天:引用 (References) 与借用 (Borrowing)

  • 核心概念: 如果不想转移所有权,可以创建值的“引用”,这被称为“借用”。引用默认不可变。&mut创建可变引用。

  • 代码示例:

    fn main() {let s1 = String::from("hello");// calculate_length 函数“借用”了 s1,而不是获取所有权let len = calculate_length(&s1);// 因为 s1 的所有权没有被移动,所以在这里仍然可以访问它println!("The length of '{}' is {}.", s1, len);
    }fn calculate_length(s: &String) -> usize {s.len()
    } // s 在这里离开作用域,但因为它不拥有所引用的数据,所以什么也不会发生
    
  • 编程练习: 重写第7天的练习。创建一个计算String长度的函数,该函数接收String的引用&String作为参数。在main函数中调用此函数后,验证原来的String变量仍然可用。

第9天:切片 (Slices)

  • 核心概念: 切片允许你引用集合中一部分连续的元素序列,它本身不持有所有权。

  • 代码示例:

    fn main() {let sentence = String::from("hello world");let hello = &sentence[0..5]; // or &sentence[..5]let world = &sentence[6..11]; // or &sentence[6..]println!("First word: {}, Second word: {}", hello, world);
    }
    
  • 编程练习: 编写一个函数,它接收一个字符串切片&str,并返回它找到的第一个单词的切片。提示:通过遍历字符串中的字节来寻找空格。

第10天:结构体 (Structs)

  • 核心概念: 使用struct关键字创建自定义的复合数据类型。

  • 代码示例:

    // 定义一个结构体
    struct Rectangle {width: u32,height: u32,
    }fn main() {// 创建一个 Rectangle 实例let rect1 = Rectangle {width: 30,height: 50,};println!("The area of the rectangle is {} square pixels.",rect1.width * rect1.height);
    }
    
  • 编程练习: 定义一个User结构体,包含username (String)、email (String) 和 active (bool) 字段。在main函数中,创建一个User实例并打印其email

第11天:结构体上的方法 (Methods on Structs)

  • 核心概念: 使用impl块为结构体定义方法。方法的第一个参数通常是&self&mut selfself

  • 代码示例:

    struct Rectangle {width: u32,height: u32,
    }// 为 Rectangle 实现方法
    impl Rectangle {// `&self` 是 `self: &Rectangle` 的缩写fn area(&self) -> u32 {self.width * self.height}
    }fn main() {let rect1 = Rectangle { width: 30, height: 50 };// 使用点号调用方法println!("The area is {}", rect1.area());
    }
    
  • 编程练习: 为第10天的User结构体实现一个deactivate方法,它接收一个&mut self,将active字段设置为false

第12天:枚举 (Enums) 与模式匹配 (Pattern Matching)

  • 核心概念: enum允许你定义一个可以枚举出不同可能值的类型。match控制流运算符必须穷尽所有可能性。

  • 代码示例:

    enum Message {Quit,Move { x: i32, y: i32 },Write(String),ChangeColor(i32, i32, i32),
    }fn process_message(msg: Message) {match msg {Message::Quit => println!("Quit"),Message::Move { x, y } => println!("Move to x: {}, y: {}", x, y),Message::Write(text) => println!("Text message: {}", text),Message::ChangeColor(r, g, b) => println!("Change color to R:{}, G:{}, B:{}", r, g, b),}
    }fn main() {process_message(Message::Write(String::from("hello")));process_message(Message::Quit);
    }
    
  • 编程练习: 创建一个TrafficLight枚举,包含RedYellowGreen三个变体。编写一个函数,接收一个TrafficLight枚举,使用match返回每种灯需要等待的时间(u8类型)。

第13天:Option 枚举

  • 核心概念: Option<T>用于处理可能为空的值,避免了null带来的问题。它有两个变体:Some(T)None

  • 代码示例:

    fn find_division_result(numerator: f64, denominator: f64) -> Option<f64> {if denominator == 0.0 {None} else {Some(numerator / denominator)}
    }fn main() {let result1 = find_division_result(10.0, 2.0);let result2 = find_division_result(10.0, 0.0);match result1 {Some(value) => println!("Result 1: {}", value),None => println!("Result 1: Cannot divide by zero"),}// if let 是 match 的一种简写形式if let Some(value) = result2 {println!("Result 2: {}", value);} else {println!("Result 2: Cannot divide by zero");}
    }
    
  • 编程练习: 编写一个函数,接收一个整数数组的切片,如果切片不为空,则返回Some包含第一个元素的值,否则返回None。在main函数中使用match来处理这个Option结果。

第14天:包、Crate和模块 (Packages, Crates, and Modules)

  • 核心概念: 使用moduse来组织代码,将代码分割到不同文件和模块中。

  • 代码示例:

    // 文件结构:
    // ├── src
    // │   ├── main.rs
    // │   └── front_of_house.rs// src/main.rs
    mod front_of_house; // 声明 front_of_house 模块,Rust会查找 front_of_house.rs// 使用 use 关键字将 hosting 引入作用域
    use front_of_house::hosting;fn main() {hosting::add_to_waitlist();
    }// src/front_of_house.rs
    // 模块默认是私有的,需要用 pub 关键字使其公开
    pub mod hosting {pub fn add_to_waitlist() {println!("Added to waitlist!");}
    }
    
  • 编程练习: 将第11天的User结构体及其impl块移动到一个名为models.rs的独立文件中。然后在main.rs中通过mod models;use models::User;来使用它。


第三周:集合、错误处理与泛型

第15天:Vector (动态数组)

  • 核心概念: Vec<T>是一种可增长的、存储在堆上的集合类型。

  • 代码示例:

    fn main() {// 创建一个可变的 vectorlet mut v: Vec<i32> = Vec::new();// 添加元素v.push(5);v.push(6);v.push(7);// 访问元素(安全的方式)match v.get(2) {Some(third) => println!("The third element is {}", third),None => println!("There is no third element."),}// 遍历 vectorfor i in &v {println!("{}", i);}
    }
    
  • 编程练习: 创建一个Vec<i32>,向其中添加数字1到5。然后遍历这个vector,将每个元素乘以2,并将结果存储在一个新的vector中。

第16天:字符串 (String)

  • 核心概念: &str是字符串切片,String是堆上分配、可变的字符串。

  • 代码示例:

    fn main() {let mut s = String::from("foo");s.push_str("bar");println!("{}", s); // "foobar"let s1 = String::from("Hello, ");let s2 = String::from("world!");// + 操作符会获取 s1 的所有权let s3 = s1 + &s2; println!("{}", s3);// println!("{}", s1); // s1 在这里不再有效
    }
    
  • 编程练习: 创建一个空的String,然后使用push_str()push()方法向其中添加文本和字符,最后将其与其他&str拼接成一句话并打印。

第17天:哈希表 (Hash Maps)

  • 核心概念: HashMap<K, V>用于存储键值对。

  • 代码示例:

    use std::collections::HashMap;fn main() {let mut scores = HashMap::new();scores.insert(String::from("Blue"), 10);scores.insert(String::from("Yellow"), 50);let team_name = String::from("Blue");// get 方法返回一个 Option<&V>let score = scores.get(&team_name).copied().unwrap_or(0);println!("Blue team score: {}", score);// 遍历for (key, value) in &scores {println!("{}: {}", key, value);}
    }
    
  • 编程练习: 创建一个HashMap来统计一段文本中每个单词出现的次数。

第18天:错误处理与Result

  • 核心概念: Result<T, E>用于处理可能失败的操作。?运算符可以简化错误传播。

  • 代码示例:

    use std::fs::File;
    use std::io::Read;// 函数返回一个 Result
    fn read_username_from_file() -> Result<String, std::io::Error> {let mut f = File::open("hello.txt")?; // `?` 如果是 Err,则直接返回 Errlet mut s = String::new();f.read_to_string(&mut s)?; // `?` 如果是 Err,则直接返回 ErrOk(s) // 如果成功,则返回 Ok(s)
    }fn main() {match read_username_from_file() {Ok(username) => println!("Username: {}", username),Err(e) => println!("Error reading file: {}", e),}
    }
    
  • 编程练习: 编写一个safe_divide函数,接收两个f64参数。如果除数为零,则返回一个Err包含描述错误的字符串;否则返回Ok包含除法结果。在main中调用它并使用match处理Result

第19天:泛型 (Generics)

  • 核心概念: 泛型是具体类型或其他属性的抽象替代,用于减少代码重复。

  • 代码示例:

    // 泛型结构体
    struct Point<T> {x: T,y: T,
    }// 泛型函数
    fn print_point<T: std::fmt::Display>(p: &Point<T>) {println!("Point is at ({}, {})", p.x, p.y);
    }fn main() {let integer_point = Point { x: 5, y: 10 };let float_point = Point { x: 1.0, y: 4.0 };print_point(&integer_point);print_point(&float_point);
    }
    
  • 编程练习: 创建一个泛型函数largest<T: PartialOrd>(list: &[T]) -> &T,它可以找到任何实现了PartialOrd trait(即可比较大小)的类型的切片中的最大元素。

第20天:Trait (特性)

  • 核心概念: Trait类似于接口,定义了某种类型必须提供的方法签名。

  • 代码示例:

    // 定义一个 Trait
    pub trait Summary {fn summarize(&self) -> String;
    }pub struct Tweet {pub username: String,pub content: String,
    }// 为 Tweet 类型实现 Summary Trait
    impl Summary for Tweet {fn summarize(&self) -> String {format!("{}: {}", self.username, self.content)}
    }fn main() {let tweet = Tweet {username: String::from("horse_ebooks"),content: String::from("of course, as you probably already know, people"),};println!("1 new tweet: {}", tweet.summarize());
    }
    
  • 编程练习: 定义一个名为CanSpeak的trait,它有一个speak(&self) -> String方法。为你之前创建的User结构体和新创建的Cat结构体实现这个trait。

第21天:生命周期 (Lifetimes)

  • 核心概念: 生命周期是编译器用来确保所有借用都有效的范围。大多数情况编译器可自动推断,复杂时需手动标注。

  • 代码示例:

    // 'a 是生命周期参数
    // 它告诉 Rust,返回的引用的生命周期与 x 和 y 中较短的那个生命周期相关联
    fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {if x.len() > y.len() {x} else {y}
    }fn main() {let string1 = String::from("long string is long");let result;{let string2 = String::from("xyz");// result 的生命周期被限制在 string2 的生命周期内result = longest(string1.as_str(), string2.as_str());println!("The longest string is {}", result);}// println!("The longest string is {}", result); // <-- 这里会报错,因为 string2 和 result 都已失效
    }
    
  • 编程练习: 编写一个结构体ImportantExcerpt<'a>,它包含一个字段part,类型为&'a str。验证你不能创建一个比它所引用的字符串活得更长的ImportantExcerpt实例。


第四周:高级特性与并发

第22天:闭包 (Closures)

  • 核心概念: 闭包是可以捕获其环境的匿名函数。

  • 代码示例:

    fn main() {let x = 4;// 这个闭包捕获了环境中的 xlet equal_to_x = |z| z == x;let y = 4;assert!(equal_to_x(y));let v1 = vec![1, 2, 3];// map 方法接收一个闭包作为参数let v2: Vec<_> = v1.iter().map(|x| x + 1).collect();println!("v2: {:?}", v2); // v2: [2, 3, 4]
    }
    
  • 编程练习: 使用find方法和一个闭包,在一个Vec<i32>中查找第一个大于10的数字。

第23天:迭代器 (Iterators)

  • 核心概念: 迭代器是处理元素序列的一种懒惰(lazy)且高效的方式。

  • 代码示例:

    fn main() {let v1 = vec![1, 2, 3, 4, 5];let iterator = v1.iter(); // 创建迭代器// 迭代器是懒惰的,需要消耗它们才能做事let total: i32 = iterator.sum(); // sum() 会消耗迭代器println!("Sum: {}", total);// 链式调用let v2: Vec<i32> = vec![1, 2, 3];let v3: Vec<_> = v2.iter().map(|x| x * 2).filter(|&x| x > 4).collect();println!("v3: {:?}", v3); // v3: [6]
    }
    
  • 编程练习: 创建一个从1到100的数字vector。使用迭代器、filtermap链式调用,找出所有能被3整除的数,将它们平方,然后使用sum计算总和。

第24天:智能指针 (Box, Rc, RefCell)

  • 核心概念: Box<T>在堆上分配值;Rc<T>允许多个所有者;RefCell<T>在运行时检查借用规则。

  • 代码示例: (Box 用于递归类型)

    // 使用 Box 来创建递归的 Cons List 类型
    enum List {Cons(i32, Box<List>),Nil,
    }
    use List::{Cons, Nil};fn main() {// (1, (2, (3, Nil)))let list = Cons(1, Box::new(Cons(2, Box::new(Cons(3, Box::new(Nil))))));
    }
    
  • 编程练习: 使用Rc<T>来创建一个允许多个列表共享同一个尾部(另一个列表)的数据结构。

第25天:并发:线程 (Threads)

  • 核心概念: 使用thread::spawn创建新线程。move关键字常用于闭包中,以转移所有权。

  • 代码示例:

    use std::thread;
    use std::time::Duration;fn main() {let handle = thread::spawn(|| {for i in 1..10 {println!("hi number {} from the spawned thread!", i);thread::sleep(Duration::from_millis(1));}});for i in 1..5 {println!("hi number {} from the main thread!", i);thread::sleep(Duration::from_millis(1));}// 等待子线程结束handle.join().unwrap();
    }
    
  • 编程练习: 创建一个新线程,它持有一个Vec的所有权并打印其中的元素。在主线程中尝试访问这个Vec,观察编译错误。

第26天:并发:消息传递 (Message Passing)

  • 核心概念: 使用通道(Channel)在线程间安全地传递消息,避免共享内存。

  • 代码示例:

    use std::sync::mpsc; // multiple producer, single consumer
    use std::thread;fn main() {let (tx, rx) = mpsc::channel();thread::spawn(move || {let val = String::from("hi");tx.send(val).unwrap();// println!("val is {}", val); // val 的所有权已经转移,这里会报错});let received = rx.recv().unwrap();println!("Got: {}", received);
    }
    
  • 编程练习: 创建一个通道。在一个子线程中,发送多条消息(比如数字1到5)。在主线程中,使用for循环来接收并打印所有消息。

第27天:并发:共享状态 (MutexArc)

  • 核心概念: Mutex<T>提供互斥访问。Arc<T>是线程安全的引用计数指针,允许多个线程拥有同一个值的引用。

  • 代码示例:

    use std::sync::{Arc, Mutex};
    use std::thread;fn main() {// 使用 Arc 来允许多个所有者,Mutex 来保证一次只有一个线程能修改值let counter = Arc::new(Mutex::new(0));let mut handles = vec![];for _ in 0..10 {let counter = Arc::clone(&counter);let handle = thread::spawn(move || {// lock() 会阻塞当前线程,直到可以获取锁let mut num = counter.lock().unwrap();*num += 1;}); // 锁在这里被释放handles.push(handle);}for handle in handles {handle.join().unwrap();}println!("Result: {}", *counter.lock().unwrap()); // 最终结果是 10
    }
    
  • 编程练习: 重做以上练习,但这次每个线程将计数器增加2而不是1。验证最终结果是20。

第28天:Cargo进阶与生态系统

  • 核心概念: 通过在Cargo.toml中添加依赖来使用crates.io上的第三方库。

  • 代码示例:

    // 1. 在 Cargo.toml 文件中添加:
    // [dependencies]
    // serde = { version = "1.0", features = ["derive"] }
    // serde_json = "1.0"// 2. 在 main.rs 中使用:
    use serde::{Serialize, Deserialize};#[derive(Serialize, Deserialize, Debug)]
    struct Point {x: i32,y: i32,
    }fn main() {let point = Point { x: 1, y: 2 };// 序列化为 JSON 字符串let serialized = serde_json::to_string(&point).unwrap();println!("serialized = {}", serialized);// 反序列化let deserialized: Point = serde_json::from_str(&serialized).unwrap();println!("deserialized = {:?}", deserialized);
    }
    
  • 编程练习: 在你的项目中添加一个流行的第三方库,比如rand,用它来生成一个随机数并打印出来。

第29天:unsafe Rust

  • 核心概念: unsafe关键字让你绕过编译器的某些安全检查,用于与非Rust代码交互、或进行编译器无法理解的底层优化等。

  • 代码示例: (请谨慎使用)

    fn main() {let mut num = 5;// 创建裸指针let r1 = &num as *const i32;let r2 = &mut num as *mut i32;// 解引用裸指针必须在 unsafe 块中进行unsafe {println!("r1 is: {}", *r1);*r2 = 10; // 修改数据println!("r2 now points to: {}", *r2);}
    }
    
  • 编程练习: (仅为理解)编写一个unsafe块,创建一个指向整数的裸指针,并解引用它来读取值。思考在哪些情况下这个操作可能导致未定义行为。

第30天:下一步与项目构思

  • 核心概念: 回顾所学,总结Rust的核心优势。探索生态系统,如异步编程(async/await)、WebAssembly、嵌入式等。

  • 代码示例: (异步代码 async/await 概念)

    // 需要添加 tokio 依赖: `tokio = { version = "1", features = ["full"] }`#[tokio::main]async fn main() {println!("Hello");// .await 表示等待异步操作完成,但不会阻塞整个线程let result = fetch_data_from_db().await;println!("Data fetched: {}", result);}async fn fetch_data_from_db() -> String {// 模拟一个耗时的数据库查询tokio::time::sleep(tokio::time::Duration::from_secs(2)).await;"Some data from database".to_string()}
    
  • 编程练习: 为自己构思一个小的结业项目。例如:一个简单的命令行待办事项应用、一个TCP端口扫描器、一个简单的Web服务器。写下项目的功能需求和你计划使用的crates,然后开始动手吧!


祝您学习愉快,编程顺利!欢迎来到Rust的世界!

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

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

相关文章

乱删文件,电脑不能开机,怎么办

相信不少朋友在清理电脑、释放空间时&#xff0c;都做过一件“后悔一整年”的事——乱删系统文件。本来只是想让电脑快点、干净点&#xff0c;结果第二天一开机&#xff1a;黑屏了、蓝屏了、无限重启了&#xff0c;甚至连桌面都见不到了&#xff01;很多用户在删文件时&#xf…

ICODE SLIX2有密钥保护的物流跟踪、图书馆管理ISO15693标签读写Delphi源码

本示例使用设备&#xff1a;https://item.taobao.com/item.htm?spma21dvs.23580594.0.0.6781645eXF3tm5&ftt&id959258149468 一、密钥认证 procedure TForm1.Button21Click(Sender: TObject); varctrlword:byte;passwordid:byte; //密钥类型status:byte; //存…

核环境特种机器人设备的抗辐照芯片选型方案

摘要&#xff1a;核能作为国家能源安全的重要组成部分&#xff0c;对工业自动化设备的稳定性和可靠性提出了极高的要求。机器人设备在涉核环境下的日常巡检、设备维护、应急响应等任务中发挥着不可替代的作用。然而&#xff0c;涉核环境&#xff0c;尤其是高能粒子的辐照效应&a…

Linux权限系统完全指南:从本质到安全实践

一、权限的本质&#xff1a;Linux安全的核心逻辑在Linux的多用户环境中&#xff0c;权限系统通过三个关键维度实现资源隔离&#xff1a;用户标识 (UID)&#xff1a;系统通过数字ID识别用户&#xff0c;root用户的UID固定为0组标识 (GID)&#xff1a;用户组机制实现批量权限管理…

养老院跌倒漏报率↓78%!陌讯多模态算法在智慧照护中的边缘计算优化

​摘要​​&#xff1a; 针对养老场景中复杂光照与遮挡导致的跌倒漏报问题&#xff0c;陌讯视觉算法通过多模态融合与边缘计算优化&#xff0c;实测显示在RK3588 NPU硬件上实现​​mAP0.5达89.3%​​&#xff0c;较基线模型提升28.5%&#xff0c;功耗降低至7.2W。本文解析其动态…

老年护理实训室建设方案:打造安全、规范、高效的实践教学核心平台

在老龄化社会加速发展的背景下&#xff0c;培养高素质、技能过硬的老年护理专业人才迫在眉睫。一个设计科学、功能完备的老年护理实训室&#xff0c;正是院校提升实践教学质量&#xff0c;对接行业需求的核心平台。本方案旨在构建一个安全、规范、高效的现代化实训环境。点击获…

OpenCv中的 KNN 算法实现手写数字的识别

目录 一.案例&#xff1a;手写数字的识别 1.安装opencv-python库 2.将大图分割成10050个小图&#xff0c;每份对应一个手写数字样品 3.训练集和测试集 4.为训练集和测试集准备结果标签 5.模型训练与预测 6.计算准确率 7.完整代码实现 一.案例&#xff1a;手写数字的识别…

TCP/IP 传输层详解

TCP/IP 传输层详解 传输层&#xff08;Transport Layer&#xff09;是 TCP/IP 模型的第四层&#xff08;对应 OSI 模型的传输层&#xff09;&#xff0c;核心功能是实现 端到端&#xff08;进程到进程&#xff09;的可靠通信。主要协议包括&#xff1a; TCP&#xff08;传输控制…

深度学习笔记:Overview

本文根据吴恩达老师的深度学习课程整理而来&#xff0c;在此表示感知。 文章目录1.课程笔记2.编程作业1.课程笔记 1&#xff09;深度学习笔记&#xff08;1&#xff09;&#xff1a;神经网络基础 2&#xff09;深度学习笔记&#xff08;2&#xff09;&#xff1a;浅层神经网络…

LLM之RAG理论(十八)| ChatGPT DeepResearch 深度研究功能全面技术分析报告

一、背景与行业环境1.1 DeepResearch 的诞生与战略意义ChatGPT DeepResearch&#xff08;深度研究&#xff09;是 OpenAI 于 2025 年 2 月 3 日正式发布的全新 AI 智能体产品&#xff0c;是继 o3-mini 模型发布后&#xff0c;OpenAI 在 AI 研究领域的又一重大突破。这一功能的推…

数据库学习--------数据库日志类型及其与事务特性的关系

在数据库系统中&#xff0c;日志是保证数据可靠性和一致性的重要组成部分&#xff0c;尤其与事务的特性紧密相连。无论是事务的原子性、一致性&#xff0c;还是持久性&#xff0c;都离不开日志的支持。数据库日志&#xff08;Database Log&#xff09;是数据库系统记录自身操作…

如何在 Ubuntu 24.04 或 22.04 LTS 上安装 OpenShot 视频编辑器

OpenShot 视频编辑器是一款轻量级工具,不需要高性能硬件即可编辑视频。它最初是一个爱好项目,后来成为一款拥有简单干净用户界面的流行免费编辑工具。这款直观的视频编辑器可以剪辑影片,并添加额外的视频和音频素材。最终,您可以将作品导出为您选择的格式。本教程将向您展示…

SpringMVC核心原理与实战指南

什么是MVC&#xff1f; MVC英文是Model View Controller&#xff0c;是模型(model)&#xff0d;视图(view)&#xff0d;控制器(controller)的缩写&#xff0c;一种软件设计规范。 MVC是用一种业务逻辑、数据、界面显示分离的方法&#xff0c;将业务逻辑聚集到一个部件里面&am…

【JavaEE】(7) 网络原理 TCP/IP 协议

一、应用层 应用层是程序员最关心的一层&#xff0c;需要自定义数据传输的格式&#xff0c;即前&#xff08;客户端&#xff09;后&#xff08;服务器&#xff09;端交互的接口&#xff0c;然后调用传输层的 socket api 来实现网络通信。 自定义数据传输的协议&#xff0c;主要…

深入理解 Slab / Buddy 分配器与 MMU 映射机制

&#x1f4d6; 推荐阅读&#xff1a;《Yocto项目实战教程:高效定制嵌入式Linux系统》 &#x1f3a5; 更多学习视频请关注 B 站&#xff1a;嵌入式Jerry 深入理解 Slab / Buddy 分配器与 MMU 映射机制 在现代 Linux 内核中&#xff0c;物理内存的管理和虚拟地址的映射是系统性能…

Layui核心语法快速入门指南

Layui 基本语法学习指南 Layui 是一个经典的模块化前端框架&#xff0c;以其轻量易用、组件丰富著称。以下是 Layui 的核心语法结构和使用方法&#xff1a; 一、模块加载机制&#xff08;核心基础&#xff09; // 标准模块加载语法 layui.use([module1, module2], function()…

基于百度 iframe 框架与语音解析服务的数字人交互系统实现

在智能化交互场景中,数字人作为人机交互的重要载体,其语音交互能力与指令响应效率直接影响用户体验。本文将详细介绍如何基于百度提供的 iframe 框架与语音解析服务,实现数字人语音播报、文字展示及指令响应的完整业务流程,涵盖从插件初始化到实时语音交互的全链路实现逻辑…

高防服务器租用的优势有哪些?

高防服务器具有着强大的防护能力&#xff0c;可以帮助企业抵御各种网络攻击&#xff0c;其中包括大规模的DDOS攻击&#xff0c;高防服务器中还有着防火墙、流量清洗和负载均衡等多种安全技术&#xff0c;能够保证业务持续稳定的运行&#xff0c;降低了企业整体的损失和安全风险…

7.28 进制交换|迭代器模式|map|子集按位或|带参递归

lc701.二叉搜索树插入void dfs不行TreeNode* dfs&#xff0c;带接受参数处理的dfs当为空的时候&#xff0c;就可以添加插入if (!root){return new TreeNode(val);}插入位置root->left insertIntoBST(root->left, val);class Solution {public:TreeNode* insertIntoBST(T…