C++ 与 Go、Rust、C#:基于实践场景的语言特性对比
目录
编辑
一、语法特性对比
1.1 变量声明与数据类型
1.2 函数与控制流
1.3 面向对象特性
二、性能表现对比编辑
2.1 基准测试数据
在计算密集型任务(如 10⁷ 次加法运算)中:
在内存分配测试(10⁵ 次对象创建)中:
对于并发请求测试(模拟 1000 个并发请求):
2.2 内存管理机制
三、应用场景分析
3.1 行业分布图
3.2 典型项目案例
四、代码实践对比
4.1 并发编程示例
4.2 内存管理示例
五、学习与职业发展
5.1 学习资源推荐
5.2 职业发展趋势
六、总结
一、语法特性对比
对比维度 | C++ | Go | Rust | C# | ||
---|---|---|---|---|---|---|
变量声明 | int x; | var x int | let x: i32; | int x; | ||
函数定义 | int add(int a, int b) { return a + b; } | func add(a, b int) int { return a + b } | fn add(a: i32, b: i32) -> i32 { a + b } | int add(int a, int b) { return a + b; } | ||
类与对象 | class MyClass { int data; }; | 无类,结构体 + 方法 | struct MyStruct { data: i32 }; impl MyStruct { fn new() -> MyStruct { MyStruct { data: 0 } } } | class MyClass { public int Data; } | ||
并发语法 | 手动线程、锁 | go func() { /* code */ }() | `std::thread::spawn( | { /* code */ })` | Task.Run(() => { /* code */ }); |
1.1 变量声明与数据类型
C++ 作为老牌编程语言,变量声明方式多样,既可以使用传统的 int num;
方式,也支持 auto
类型推导,例如 auto it = vec.begin();
。C++ 拥有丰富的数据类型,包括基本数据类型、结构体、类,还支持复杂的自定义类型,并且存在隐式类型转换,但这也可能导致一些潜在的类型错误。
Go 语言的变量声明简洁明了,采用静态类型推导,如 var num int
或者更简洁的 num := 10
。Go 语言的类型系统简洁,基本数据类型有整型、浮点型、字符串等,还提供了切片(slice
)、映射(map
)等实用的数据结构,方便开发者进行数据处理。
Rust 的变量声明需要显式指定类型,如 let num: i32 = 5;
,可变变量则需要使用 mut
关键字,例如 let mut num = 10;
。Rust 的类型系统严格,旨在从编译阶段就避免类型相关的错误,其提供的 Vec
、HashMap
等数据结构,在安全性和性能上都有出色表现。
C# 的变量声明与 C++ 类似,如 int num;
,同时也支持 var
进行类型推导,例如 var list = new List<int>();
。C# 不仅支持基础数据类型和自定义类型,还提供了丰富的泛型类型和匿名类型,方便开发者编写灵活、高效的代码。
1.2 函数与控制流
C++ 支持函数重载和模板函数,开发者可以根据不同的参数类型或数量定义多个同名函数,提高代码的复用性。在控制流方面,C++ 拥有 if
、switch
、for
、while
等常见的控制语句,满足各种逻辑判断和循环需求 。
Go 语言没有函数重载,但支持多返回值,例如 func divide(a, b int) (int, error) { if b == 0 { return 0, fmt.Errorf("division by zero") } return a / b, nil }
。在控制流上,Go 语言的 for
循环功能强大,可以替代 while
循环,并且 Go 语言没有传统的 switch
语句,而是通过 switch
表达式实现类似功能 。
Rust 语言的函数支持模式匹配,这在处理多种不同情况时非常方便,可以替代传统的 switch
语句。Rust 还拥有丰富的闭包和高阶函数特性,使得函数式编程风格在 Rust 中也能很好地实现,例如 let add = |x, y| x + y;
。
C# 语言拥有简洁的 Lambda 表达式和强大的 LINQ(语言集成查询),极大地简化了数据查询和处理操作。在异常处理方面,C# 拥有更规范的机制,通过 try-catch-finally
语句块,能够有效地捕获和处理程序运行过程中出现的异常 。
1.3 面向对象特性
C++ 是一种完全面向对象的编程语言,支持继承、多态和虚函数等特性,并且还支持多重继承。C++ 中的类拥有构造函数和析构函数,用于对象的初始化和资源释放,例如:
class Animal {
public:Animal() { std::cout << "Animal created" << std::endl; }virtual ~Animal() { std::cout << "Animal destroyed" << std::endl; }virtual void speak() { std::cout << "Animal makes a sound" << std::endl; }
};class Dog : public Animal {
public:Dog() { std::cout << "Dog created" << std::endl; }~Dog() { std::cout << "Dog destroyed" << std::endl; }void speak() override { std::cout << "Dog barks" << std::endl; }
};
Go 语言没有传统意义上的类和继承,而是通过结构体嵌入来实现类似继承的功能,并且 Go 语言的接口是隐式实现的,只要结构体实现了接口的方法,就可以被视为实现了该接口。Go 语言没有构造函数和析构函数,而是通过初始化函数和资源清理函数来完成相关操作 。
Rust 语言通过 trait
来实现接口功能,结构体可以实现一个或多个 trait
。Rust 采用结构体组合的方式来替代传统的继承,使得代码更加灵活和可复用。在 Rust 中,Drop
trait 类似于析构函数,用于在对象生命周期结束时释放资源 。
C# 语言支持单继承和接口,类的属性和索引器使得对象的访问更加方便和规范。C# 还支持事件驱动编程,通过定义事件和事件处理程序,能够实现对象之间的交互和响应,例如在 Windows 应用开发中广泛应用 。
二、性能表现对比
2.1 基准测试数据
在计算密集型任务(如 10⁷ 次加法运算)中:
C++ 的性能表现出色,平均耗时约 12ms 。这得益于 C++ 对底层硬件的直接操作能力和高效的代码优化机制。Go 语言在该测试中耗时约 25ms ,虽然相比 C++ 稍慢,但 Go 的并发性能优势在其他场景下更为突出。Rust 的表现与 C++ 接近,平均耗时 13ms ,凭借其严谨的类型系统和高效的编译优化,在计算任务中能发挥出强大的性能 。C# 在计算密集型任务中耗时约 30ms ,尽管 C# 经过不断优化,但由于其运行时环境和垃圾回收机制等因素,在纯计算性能上略逊于前三者 。
在内存分配测试(10⁵ 次对象创建)中:
C++ 手动管理内存,能够精确控制内存分配和释放,平均耗时 85ms 。然而,手动内存管理也增加了开发者出错的风险。Go 语言的自动垃圾回收机制虽然方便,但在大量对象创建时会产生一定的性能开销,平均耗时 150ms 。Rust 的所有权系统在编译期进行严格检查,确保内存安全的同时,性能也较为出色,平均耗时 90ms 。C# 的垃圾回收机制在内存分配测试中耗时 180ms ,相对较慢,不过在实际应用中,其垃圾回收的优化和后台处理机制可以减少对应用性能的影响 。
对于并发请求测试(模拟 1000 个并发请求):
Go 语言展现出强大的优势,平均耗时仅 220ms 。Go 的 goroutine 和 channel 机制使得并发编程变得简单高效,能够轻松处理大量并发任务。C++ 在处理并发请求时需要手动管理线程和锁,平均耗时 450ms ,虽然可以通过优化线程池等方式提高性能,但开发难度相对较高。Rust 在并发场景下的表现也不错,平均耗时 380ms ,其线程和通道机制结合所有权系统,在保证并发安全的同时,实现了较好的性能 。C# 通过 Task 并行库处理并发请求,平均耗时 500ms ,随着.NET 框架的不断升级,C# 的并发性能也在逐步提升 。
2.2 内存管理机制
语言 | 性能特点 | 内存管理方式 |
---|---|---|
C++ | 手动内存管理,性能极致;多线程需手动同步 | 手动分配释放(new /delete ),可使用智能指针 |
Go | 自动 GC,适合高并发;性能略逊于 C++,胜在效率 | 自动垃圾回收 |
Rust | 无 GC,性能接近 C++;编译期保证内存安全 | 所有权系统,编译期检查 |
C# | JIT 编译,性能依赖优化;自动 GC,开发效率高 | 自动垃圾回收,可实现 IDisposable 接口释放非托管资源 |
C++ 的内存管理主要依赖手动操作,开发者需要使用 new
操作符分配内存,使用 delete
操作符释放内存。为了避免内存泄漏和悬空指针等问题,开发者也可以使用智能指针,如 std::unique_ptr
、std::shared_ptr
等。智能指针通过自动管理内存的生命周期,大大减少了手动内存管理的风险,但也会带来一定的性能开销 。
Go 语言采用自动垃圾回收(GC)机制,开发者无需手动释放内存,Go 的 GC 采用标记 - 清除算法,能够自动检测不再使用的对象并回收其占用的内存。这种方式极大地减轻了开发者的负担,但在某些对实时性要求极高的场景下,GC 的暂停时间可能会对应用性能产生影响 。
Rust 的内存管理基于所有权系统,在编译期就对内存进行严格检查,确保每个值在任一时刻都有且只有一个所有者,当所有者离开作用域时,值会被自动释放。这种机制从根本上避免了内存泄漏和数据竞争等问题,同时也保证了程序的高性能 。
C# 的内存管理同样依赖自动垃圾回收,.NET 运行时会自动管理对象的生命周期。C# 还提供了析构函数和终结器机制,开发者可以在对象被回收前执行一些清理操作。此外,C# 的垃圾回收机制会根据对象的生命周期和使用频率,将对象分配到不同的代(Generation)中,进行分代式垃圾回收,提高回收效率 。
三、应用场景分析
3.1 行业分布图
从应用领域的分布来看,C++ 在游戏开发领域占据主导地位,约占 35% 的市场份额 。众多知名游戏引擎,如 Unreal Engine 都采用 C++ 开发,C++ 的高性能和对底层硬件的直接控制能力,使其能够满足游戏对图形渲染、物理模拟等方面的高要求 。
Go 语言在云原生领域表现突出,约占 25% 的市场份额 。Kubernetes、Docker 等云原生领域的核心项目都大量使用 Go 语言开发。Go 语言的高并发处理能力、简洁的语法以及良好的跨平台性,使其成为云原生开发的首选语言 。
Rust 在系统安全和底层开发领域崭露头角,约占 15% 的市场份额 。Firefox 浏览器的部分组件、区块链项目 Solana 等都采用 Rust 开发。Rust 的内存安全特性和高性能,使其在对安全性和稳定性要求极高的系统级开发中具有独特优势 。
C# 在企业级开发和游戏开发(通过 Unity 引擎)领域广泛应用,约占 25% 的市场份额 。ASP.NET Core 框架用于构建企业级 Web 应用,C# 与.NET 框架的紧密结合,提供了丰富的类库和开发工具,能够快速构建稳定、可靠的企业级应用 。在游戏开发方面,Unity 引擎使用 C# 作为主要开发语言,吸引了大量游戏开发者 。
3.2 典型项目案例
语言 | 典型应用场景 | 代表项目 |
---|---|---|
C++ | 游戏引擎、操作系统、嵌入式 | Unreal Engine、Linux 内核 |
Go | 云原生、微服务、网络编程 | Kubernetes、Docker |
Rust | 系统级开发、区块链、安全软件 | Firefox、Solana |
C# | 企业级 Web、Unity 游戏、桌面应用 | ASP.NET Core、Unity 游戏 |
Unreal Engine 是全球知名的 3D 游戏引擎,采用 C++ 开发。C++ 的高性能和对图形硬件的直接访问能力,使得 Unreal Engine 能够实现逼真的图形渲染效果和复杂的物理模拟。同时,C++ 的面向对象特性和丰富的库支持,方便开发者进行游戏逻辑的开发和扩展 。
Kubernetes 是一个开源的容器编排平台,主要使用 Go 语言开发。Go 语言的高并发处理能力使得 Kubernetes 能够轻松管理大规模的容器集群,实现容器的自动化部署、扩展和管理。Go 语言的简洁语法和良好的代码可读性,也有助于团队协作开发和项目维护 。
Firefox 浏览器的部分组件采用 Rust 开发,尤其是涉及安全和性能关键的模块。Rust 的内存安全特性能够有效避免浏览器因内存泄漏和安全漏洞而导致的崩溃和安全风险。同时,Rust 的高性能也有助于提升浏览器的响应速度和运行效率 。
ASP.NET Core 是微软推出的开源跨平台 Web 应用框架,使用 C# 开发。C# 与.NET 框架的结合,提供了丰富的功能和工具,如依赖注入、中间件、身份验证等,能够快速构建企业级 Web 应用。C# 的面向对象特性和 LINQ 等现代语言特性,也提高了开发效率和代码质量 。
四、代码实践对比
4.1 并发编程示例
在 C++ 中进行多线程计算,需要手动创建和管理线程,并且要注意线程同步和数据共享问题。以下是一个简单的 C++ 多线程计算示例:
#include <iostream>
#include <thread>
#include <vector>void calculate(int& result) {for (int i = 0; i < 1000000; ++i) {result += i;}
}int main() {int sum = 0;std::vector<std::thread> threads;for (int i = 0; i < 4; ++i) {threads.push_back(std::thread(calculate, std::ref(sum)));}for (auto& th : threads) {th.join();}std::cout << "Sum: " << sum << std::endl;return 0;
}
我们创建了 4 个线程同时进行计算,并通过 std::ref
传递引用,确保多个线程操作的是同一个变量。最后使用 join
方法等待所有线程完成计算。
Go 语言的并发编程非常简洁,通过 goroutine
和 channel
实现高效的并发处理。下面是一个 Go 语言的 goroutine 并发求和示例:
package main
import ("fmt"
)func calculate(result chan int) {s := 0for i := 0; i < 1000000; i++ {s += i}result <- s
}func main() {result := make(chan int, 4)for i := 0; i < 4; i++ {go calculate(result)}sum := 0for i := 0; i < 4; i++ {sum += <-result}close(result)fmt.Println("Sum:", sum)
}
我们通过 go
关键字启动 4 个 goroutine
进行计算,每个 goroutine
计算完成后将结果通过 channel
发送出去。主程序从 channel
中接收结果并进行累加,最后关闭 channel
。
Rust 语言的并发编程通过线程和通道实现,并且结合所有权系统保证并发安全。下面是一个 Rust 线程池并发处理的示例:
use std::sync::{Arc, Mutex};
use std::thread;
use std::collections::VecDeque;
use std::sync::mpsc::{channel, Receiver, Sender};struct ThreadPool {tasks: Arc<Mutex<VecDeque<Box<dyn FnOnce() + Send>>>>,sender: Sender<()>
}impl ThreadPool {fn new(size: usize) -> ThreadPool {let (sender, receiver): (Sender<()>, Receiver<()>) = channel();let tasks = Arc::new(Mutex::new(VecDeque::new()));for _ in 0..size {let tasks_clone = Arc::clone(&tasks);let receiver_clone = receiver.clone();thread::spawn(move || {loop {let task = {let mut guard = tasks_clone.lock().unwrap();guard.pop_front()};match task {Some(task) => task(),None => {match receiver_clone.recv() {Ok(_) => (),Err(_) => break,}}}}});}ThreadPool { tasks, sender }}fn submit<F>(&self, task: F) where F: FnOnce() + Send + 'static {let mut guard = self.tasks.lock().unwrap();guard.push_back(Box::new(task));}fn shutdown(&self) {drop(self.sender);}
}fn main() {let pool = ThreadPool::new(4);let sum = Arc::new(Mutex::new(0));for _ in 0..4 {let sum_clone = Arc::clone(&sum);pool.submit(move || {let mut s = 0;for i in 0..1000000 {s += i;}let mut guard = sum_clone.lock().unwrap();*guard += s;});}pool.shutdown();let result = *sum.lock().unwrap();println!("Sum: {}", result);
}
我们创建了一个线程池,通过 submit
方法提交任务,线程池中的线程从任务队列中获取任务并执行。主程序通过共享变量和互斥锁实现结果的累加,最后关闭线程池 。
C# 通过 Task 并行库进行并发编程,简化了多线程编程的复杂性。下面是一个 C# Task 并行库求和的示例:
using System;
using System.Threading.Tasks;class Program
{static int sum = 0;static void Calculate(){for (int i = 0; i < 1000000; i++){sum += i;}}static void Main(){Task[] tasks = new Task[4];for (int i = 0; i < 4; i++){tasks[i] = Task.Run(Calculate);}Task.WaitAll(tasks);Console.WriteLine("Sum: " + sum);}
}
我们通过 Task.Run
方法启动 4 个任务进行计算,Task.WaitAll
方法等待所有任务完成后输出结果 。
4.2 内存管理示例
在 C++ 中,动态内存分配通过 new
和 delete
操作符实现。下面是一个简单的 C++ 动态内存分配示例:
#include <iostream>
using namespace std;int main() {int* ptr = new int; // 分配一个int类型的内存空间*ptr = 10;cout << "Value: " << *ptr << endl;delete ptr; // 释放内存return 0;
}
在处理数组时,则需要使用 new[]
和 delete[]
,如:
#include <iostream>
using namespace std;int main() {int* arr = new int[5]; // 分配包含5个int的数组空间for (int i = 0; i < 5; i++) {arr[i] = i;}for (int i = 0; i < 5; i++) {cout << arr[i] << " ";}delete[] arr; // 释放数组内存return 0;
}
不过手动管理内存容易出现内存泄漏(忘记 delete
)、悬空指针(delete
后继续使用指针)等问题。为解决这些问题,C++ 引入智能指针,如 std::unique_ptr
(独占所有权)和 std::shared_ptr
(共享所有权) :
#include <iostream>
#include <memory>int main() {std::unique_ptr<int> uPtr(new int(20)); // 独占所有权的智能指针std::cout << "Value: " << *uPtr << endl;// 离开作用域时,uPtr自动释放内存std::shared_ptr<int> sPtr1(new int(30)); // 共享所有权的智能指针std::shared_ptr<int> sPtr2 = sPtr1; // 多个指针共享同一内存std::cout << "Value: " << *sPtr2 << endl;// 当所有共享指针超出作用域,内存自动释放return 0;
}
Go 语言采用自动垃圾回收机制,开发者无需手动释放内存。以下是 Go 语言中切片(动态数组)的内存管理示例 :
package main
import "fmt"func main() {slice := make([]int, 0, 5) // 创建一个初始长度为0,容量为5的切片for i := 0; i < 5; i++ {slice = append(slice, i) // 向切片添加元素,容量不足时自动扩容}fmt.Println(slice)// 当slice变量离开作用域,其占用的内存由垃圾回收器自动回收
}
在 Go 语言中,即使频繁创建和销毁大量对象,开发者也无需担心内存泄漏问题,Go 的垃圾回收器会在后台自动运行,定期扫描不再使用的对象并回收内存。
Rust 的内存管理基于所有权系统,在编译期就确保内存安全。以下是 Rust 中字符串的所有权转移示例:
fn main() {let s1 = String::from("hello"); // s1拥有"hello"字符串的所有权let s2 = s1; // s1的所有权转移到s2,此时s1不再有效// println!("{}", s1); // 这行会导致编译错误,因为s1已失去所有权println!("{}", s2);
}
当函数传递参数时,也遵循所有权规则:
fn take_ownership(s: String) {println!("Received string: {}", s);// s离开作用域时,其占用的内存自动释放
}fn main() {let s = String::from("world");take_ownership(s);// 这里s已无效,因为所有权已转移到take_ownership函数中
}
如果想要在函数传递中不转移所有权,可以使用引用(&
) :
fn borrow_string(s: &String) {println!("Borrowed string: {}", s);// 引用不会转移所有权,s在函数结束后依然有效
}fn main() {let s = String::from("rust");borrow_string(&s);println!("Original string: {}", s);
}
C# 的内存管理依赖自动垃圾回收机制。以下是 C# 中对象创建和垃圾回收的示例:
using System;class MyClass {~MyClass() {Console.WriteLine("对象被回收");}
}class Program {static void Main() {MyClass obj = new MyClass();obj = null; // 使对象失去引用,等待垃圾回收GC.Collect(); // 手动触发垃圾回收(通常无需手动触发)}
}
C# 的垃圾回收器会自动监测对象的引用情况,当一个对象不再被任何变量引用时,它将被标记为可回收,并在适当的时候由垃圾回收器回收内存。此外,C# 还提供了 IDisposable
接口,用于在对象不再使用时及时释放非托管资源,如文件句柄、数据库连接等 :
using System;
using System.IO;class Program {static void Main() {using (FileStream fs = new FileStream("test.txt", FileMode.Create)) {// 在using块内,fs对象有效byte[] data = System.Text.Encoding.UTF8.GetBytes("Hello, C#");fs.Write(data, 0, data.Length);} // 离开using块,fs对象自动调用Dispose方法释放资源}
}
五、学习与职业发展
维度 | C++ | Go | Rust | C# |
---|---|---|---|---|
学习曲线 | 陡峭 | 平缓 | 极陡峭 | 中等 |
学习难点 | 模板、内存管理 | goroutine、channel | 所有权、生命周期 | LINQ、.NET 框架 |
就业方向 | 游戏、系统、嵌入式 | 云原生、网络 | 系统安全、底层 | 企业级、游戏 |
薪资水平(参考) | 高 | 较高 | 高 | 较高 |
5.1 学习资源推荐
对于想要学习 Go 语言的 C++ 选手,官方文档(Documentation - The Go Programming Language )是最权威的学习资料,涵盖了语法、标准库、工具链等详细内容。经典书籍《Go 语言圣经》对 Go 语言的特性和应用进行了深入讲解,适合系统学习。在线课程方面,Udemy 上的《The Complete Go Bootcamp》课程通过大量实践案例,帮助学习者快速掌握 Go 语言开发技能。
Rust 语言的官方文档(The Rust Programming Language - The Rust Programming Language )同样是学习的首选,其交互式的学习方式能让开发者边学边实践。《Rust 程序设计语言》是 Rust 学习的经典书籍,从基础语法到高级特性都有详细阐述。《Rust By Example》则提供了丰富的代码示例,便于学习者理解和掌握 Rust 的各种概念和用法。
C# 语言的官方文档(C# 指南 - .NET 托管语言 | Microsoft Learn )内容全面,不仅有语法介绍,还包含大量的应用场景示例。《C# 高级编程》是 C# 学习的必备书籍,深入讲解了 C# 的高级特性和.NET 框架的使用。Pluralsight 上的 C# 系列课程,由微软官方专家授课,对 C# 的最新特性和企业级应用开发有深入的讲解。
5.2 职业发展趋势
从职业发展角度看,掌握 C++ 的开发者可以在游戏开发领域深耕,如成为游戏引擎开发工程师、游戏客户端开发工程师等。随着元宇宙概念的兴起,对 C++ 高性能图形开发和底层优化的需求持续增长。
Go 语言开发者在云原生领域有广阔的发展空间,可从事云原生架构师、DevOps 工程师等职位。各大互联网公司和云计算厂商对 Go 语言人才的需求日益增加,尤其是在分布式系统、微服务架构和容器编排等方面。
Rust 开发者在系统安全、区块链、底层开发等领域备受青睐。可以成为系统安全专家、区块链开发工程师等职位,负责开发高性能、高安全性的系统和应用。随着对软件安全性要求的不断提高,Rust 语言人才的市场需求也在逐步上升。
C# 开发者在企业级应用开发和游戏开发领域有稳定的职业发展路径。可以成为.NET 企业开发工程师,负责构建企业级 Web 应用、桌面应用等;也可以通过 Unity 引擎,成为游戏开发工程师,参与手机游戏、PC 游戏等的开发。
六、总结
C++ 作为一门强大的系统级编程语言,拥有深厚的技术积累和广泛的应用场景。而 Go、Rust 和 C# 各自在不同领域展现出独特的优势。Go 语言在云原生和高并发领域表现卓越,语法简洁,开发效率高;Rust 以其内存安全和高性能,在系统级开发和安全领域占据一席之地;C# 则在企业级应用和游戏开发方面拥有强大的生态支持,其中C++ 选手在选择学习新语言时,可根据自身兴趣和职业规划进行决策。若希望进入云原生和 DevOps 领域,Go 语言是不错的选择;若对系统安全和底层开发感兴趣,Rust 语言更值得深入学习;若专注于企业级应用开发或 Unity 游戏开发,C# 语言则是理想之选。无论选择哪门语言,都能在原有 C++ 基础上进一步拓展技术视野,提升自身竞争力 。
相关文章:
C++ 与 Go、Rust、C#:基于实践场景的语言特性对比
目录 编辑 一、语法特性对比 1.1 变量声明与数据类型 1.2 函数与控制流 1.3 面向对象特性 二、性能表现对比编辑 2.1 基准测试数据 在计算密集型任务(如 10⁷ 次加法运算)中: 在内存分配测试(10⁵ 次对象创建…...
RDB和AOF的区别
Redis提供两种主要的持久化机制:RDB(Redis Database)和AOF(Append Only File),它们在数据持久化方式、性能影响及恢复策略上各有特点。以下是两者的对比分析及使用建议: RDB(快照持久…...
因子分析基础指南:原理、步骤与地球化学数据分析应用解析
前言 在看深度学习成矿预测以及地球化学数据分析的文献的时候很多引言部分的内容会提到一些老的技术,正所谓:知其然知其所以然。所以我把关于一些老技术的基础铺垫的内容作为:研究生基础指南部分进行记录。 这部分讲述的是因子分析…...
采用AI神经网络降噪算法的通信语音降噪(ENC)模组性能测试和应用
采用AI降噪的语言通话环境抑制模组性能效果测试 随着AI时代来临.通话设备的环境噪音抑制也进入AI降噪算法时代. AI神经网络降噪技术是一款革命性的语音处理技术,他突破了传统单麦克风和双麦克风降噪的局限性,利用采集的各种日常环境中的噪音样本进行训练学习.让降噪…...
面试题 - Kafka、RabbitMQ、RocketMQ如何选型?
在当今的高并发、大数据时代,系统架构的复杂性呈指数级增长。你是否曾遇到过这样的问题:用户订单提交后,系统响应缓慢甚至卡顿?或者在业务高峰期,消息积压导致系统崩溃? 这些问题的背后,往往隐…...
【落羽的落羽 C++】stack和queue、deque、priority_queue、仿函数
文章目录 一、stack和queue1. 概述2. 使用3. 模拟实现 二、deque三、priority_queue1. 概述和使用2. 模拟实现 四、仿函数 一、stack和queue 1. 概述 我们之前学习的vector和list,以及下面要认识的deque,都属于STL的容器(containers&#x…...
Golang 空结构体特性与用法
文章目录 1.简介2.核心特性2.1 零内存占用2.2 值比较语义2.3 类型隔离2.4 值地址 3.作用3.1 实现集合(Set)3.2 不发送数据的信道3.3 无状态方法接收者3.4 作为 context 的 value 的 key 4.小结参考文献 1.简介 在 Go 语言中,空结构体是一个不…...
企业对数据集成工具的需求及 ETL 工具工作原理详解
当下,数据已然成为企业运营发展过程中的关键生产要素,其重要性不言而喻。 海量的数据分散在企业的各类系统、平台以及不同的业务部门之中,企业要充分挖掘这些数据背后所蕴含的巨大价值,实现数据驱动的精准决策,数据集…...
基于HTTP头部字段的SQL注入:SQLi-labs第17-20关
前置知识:HTTP头部介绍 HTTP(超文本传输协议)头部(Headers)是客户端和服务器在通信时传递的元数据,用于控制请求和响应的行为、传递附加信息或定义内容类型等。它们分为请求头(Request Headers&…...
Megatron系列——流水线并行
内容总结自:bilibili zomi 视频大模型流水线并行 注:这里PipeDream 1F1B对应时PP,Interleaved 1F1B对应的是VPP 1、朴素流水线并行 备注: (1)红色三个圈都为空泡时间,GPU没有做任何计算 &am…...
Android HttpAPI通信问题(待解决)
使用ClearTextTraffic是Android中一项重要的网络设置,它控制了应用程序是否允许在不使用HTTPS加密的情况下访问网络。在默认情况下,usescleartexttraffic的值为true,这意味着应用程序可以通过普通的HTTP协议进行网络通信。然而,这…...
WebFlux vs WebMVC vs Servlet 对比
WebFlux vs WebMVC vs Servlet 技术对比 WebFlux、WebMVC 和 Servlet 是 Java Web 开发中三种不同的技术架构,它们在编程模型、并发模型和适用场景上有显著区别。以下是它们的核心对比: 核心区别总览 特性ServletSpring WebMVCSpring WebFlux编程模型…...
Spring MVC参数传递
本内容采用最新SpringBoot3框架版本,视频观看地址:B站视频播放 1. Postman基础 Postman是一个接口测试工具,Postman相当于一个客户端,可以模拟用户发起的各类HTTP请求,将请求数据发送至服务端,获取对应的响应结果。 2. Spring MVC相关注解 3. Spring MVC参数传递 Spri…...
Spring MVC 和 Spring Boot 是如何访问静态资源的?
Spring MVC 和 Spring Boot 在配置静态资源访问方面有所不同,Spring Boot 提供了更便捷的自动配置。 一、Spring Boot 如何配置静态资源访问 (推荐方式) Spring Boot 遵循“约定优于配置”的原则,对静态资源的访问提供了非常方便的自动配置。 默认静态…...
如何应对网站被爬虫和采集?综合防护策略与实用方案
在互联网时代,网站内容被恶意爬虫或采集工具窃取已成为常见问题。这不仅侵犯原创权益,还可能影响网站性能和SEO排名。以下是结合技术、策略与法律的综合解决方案,帮助网站构建有效防护体系。 一、技术防护:阻断爬虫的“技术防线”…...
MySQL 分页查询优化
目录 前言1. LIMIT offset, count 的性能陷阱:为什么它慢?😩2. 优化策略一:基于排序字段的“跳跃式”查询 (Seek Method) 🚀3. 优化策略二:利用子查询优化 OFFSET 扫描 (ID Subquery)4. 基础优化࿱…...
我用Deepseek + 亮数据爬虫神器 1小时做出輿情分析器
我用Deepseek 亮数据爬虫神器 1小时做出輿情分析器 一、前言二、Web Scraper API 实战(1)选择对应的URL(2)点击进入对应url界面(3)API结果实例和爬取结果展示(4)用户直接使用post请…...
langchain4j中使用milvus向量数据库做RAG增加索引
安装milvus向量数据库 官方网址 https://milvus.io/zh 使用docker安装milvus mkdir -p /data/docker/milvus cd /data/docker/milvus wget https://raw.githubusercontent.com/milvus-io/milvus/master/scripts/standalone_embed.sh#在docker中启动milvus sh standalone_emb…...
【开源工具】深度解析:基于PyQt6的Windows时间校时同步工具开发全攻略
🕒 【开源工具】深度解析:基于PyQt6的Windows时间校时同步工具开发全攻略 🌈 个人主页:创客白泽 - CSDN博客 🔥 系列专栏:🐍《Python开源项目实战》 💡 热爱不止于代码,热…...
开源 RPA 工具深度解析与官网指引
开源 RPA 工具深度解析与官网指引 摘要 :本文深入解析了多款开源 RPA 工具,涵盖 TagUI、Aibote、Taskt 等,分别介绍了它们的核心功能,并提供了各工具的官网链接,方便读者进一步了解与使用,同时给出了基于不…...
【免杀】C2免杀技术(一)VS设置
一、概述 编译器生成的二进制文件特征(代码结构、元数据、指纹)可能被杀软的静态或动态检测规则匹配。Visual Studio 的构建设置(特别是运行库、编译器优化、链接方式等)会直接影响最终生成的二进制文件的结构、行为特征和依赖关…...
OpenHarmony 开源鸿蒙南向开发——linux下使用make交叉编译第三方库——nettle库
准备工作 请依照这篇文章搭建环境 OpenHarmony 开源鸿蒙南向开发——linux下使用make交叉编译第三方库——环境配置_openharmony交叉编译-CSDN博客 编译依赖 相关依赖有 gmp-6.3.0 请依照这篇文章编译 OpenHarmony 开源鸿蒙南向开发——linux下使用make交叉编译第三方库…...
Kotlin与Ktor构建Android后端API
以下是一个使用 Kotlin 和 Ktor 构建 Android 后端 API 的详细示例,包含常见功能实现: 1. 项目搭建 (build.gradle.kts) plugins {applicationkotlin("jvm") version "1.9.0"id("io.ktor.plugin") version "2.3.4"id("org.je…...
网页jupyter如何显示jpipvenv虚拟环境
今天使用社区版pycharm编辑.ipynb文件时,发现pycharm编辑.ipynb文件需要订阅。但是发现pipvenv虚拟环境解释器在jupyter中只有一个Python3:ipykernel版本,没有venv和conda的虚拟环境。因此在网上搜寻资料,作为备份记录。 以windows为例 假设目…...
学习黑客5 分钟深入浅出理解Windows System Configuration
5 分钟深入浅出理解Windows System Configuration ⚙️ 大家好!今天我们将探索Windows系统配置——这是Windows操作系统的核心控制中心,决定了系统如何启动、运行和管理各种功能。无论你是计算机初学者,还是在TryHackMe等平台上学习网络安全…...
Spyglass:跨时钟域同步方案
相关阅读 Spyglasshttps://blog.csdn.net/weixin_45791458/category_12828934.html?spm1001.2014.3001.5482 Spyglass可以用于检测设计中的跨时钟域相关问题,确保电路中添加了适当的同步机制,以避免此类问题的发生,例如: 与亚稳…...
Ubuntu虚拟机文件系统扩容
1. 删除所有的虚拟机快照。 2. 选择扩展 将最大大小调整为你所需的大小 3. 进入虚拟机,输入命令: sudo apt install gparted sudo gparted 4. 选择磁盘,右键根分区,选择Resize/Move,调整大小。 5. 调整所需分区大…...
Window、CentOs、Ubuntu 安装 docker
Window 版本 网址:https://www.docker.com/ 下载 下载完成后,双击安装就可以了 Centos 版本 卸载 Docker (可选) yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-log…...
mac M2下虚拟机CentOS 8 安装上安装 Berkeley DB
问题:直接在centos8 yum安装db4-devel失败,只能手工安装 进入home目录,下载 wget http://download.oracle.com/berkeley-db/db-4.6.21.tar.gz 解压 tar -zxvf db-4.6.21.tar.gz 切到cd db-4.6.21的build_unix下 cd db-4.6.21 cd build_…...
Python文字转语音TTS库示例(edge-tts)
1. 安装 pip install edge-tts2. 命令行使用 # 生成语音文件 # -f:要转换语音的文本文件,例如一个txt文件 # --text:指明要保存的mp3的文本 # --write-media:指明保存的mp3文件路径 # --write-subtitles:指定输出字幕…...
lua入门语法,包含安装,注释,变量,循环等
文章目录 LUA入门什么是lualua安装入门lua的使用方式注释定义变量lua中的数据类型流程控制ifelsewhile语法:for 函数表模块 LUA入门 什么是lua 一种脚本语言,设计的目的是为了能够在一些应用程序提供灵活的扩展功能和定制功能。 lua安装 有linux版本…...
【文心智能体】使用文心一言来给智能体设计一段稳定调用工作流的提示词
🌹欢迎来到《小5讲堂》🌹 🌹这是《文心智能体》系列文章,每篇文章将以博主理解的角度展开讲解。🌹 🌹温馨提示:博主能力有限,理解水平有限,若有不对之处望指正࿰…...
TWASandGWAS中GBS filtering and GWAS(1)
F:\文章代码\TWASandGWAS\GBS filtering and GWAS README.TXT 请检查幻灯片“Vitamaize_update_Gorelab_Ames_GBS_filtering_20191122.pptx”中关于阿姆斯(Ames)ID处理流程的详细信息。 文件夹“Ames_ID_processing”包含了用于处理阿姆斯ID的文件和R…...
Linux电源管理(五),发热管理(thermal),温度控制
更多linux系统电源管理相关的内容请看:Linux电源管理、功耗管理 和 发热管理 (CPUFreq、CPUIdle、RPM、thermal、睡眠 和 唤醒)-CSDN博客 本文主要基于linux-5.4.18版本的内核代码进行分析。 1 简介 1.1 硬件知识 CPU等芯片在工作时会产生大量热量,…...
【C++11】异常
前言 上文我们学习到了C11中类的新功能【C11】类的新功能-CSDN博客 本文我们来学习C下一个新语法:异常 1.异常的概念 异常的处理机制允许程序在运行时就出现的问题进行相应的处理。异常可以使得我们将问题的发现和问题的解决分开,程序的一部分负…...
C#WPF里不能出现滚动条的原因
使用下面这段代码,就不能出现滚动条: <mdix:DrawerHost.LeftDrawerContent><Grid Width="260" Background="{StaticResource MaterialDesign.Brush.Primary}"><Grid.RowDefinitions><RowDefinition Height="auto"/>&l…...
安装Hadoop并运行WordCount程序
一、安装 Java Hadoop 依赖 Java,首先需要安装 Java 开发工具包(JDK)。以 Ubuntu 为例: bash sudo apt update sudo apt install openjdk-8-jdk安装后,设置环境变量: bash echo export JAVA_HOME/usr/li…...
从零搭建AI工作站:Gemma3大模型本地部署+WebUI配置全套方案
文章目录 前言1. 安装Ollama2.Gemma3模型安装与运行3. 安装Open WebUI图形化界面3.1 Open WebUI安装运行3.2 添加模型3.3 多模态测试 4. 安装内网穿透工具5. 配置固定公网地址总结 前言 如今各家的AI大模型厮杀得如火如荼,每天都有新的突破。今天我要给大家安利一款…...
《数字人技术实现路径深度剖析与研究报告》
《数字人技术实现路径深度剖析与研究报告》 一、引言 1.1 研究背景与意义 近年来,随着人工智能、虚拟现实、计算机图形学等技术的飞速发展,数字人技术应运而生并取得了显著进展。数字人作为一种新兴的技术应用,正逐步渗透到各个领域,成为推动行业创新发展的重要力量。从最…...
《棒球百科》MLB棒球公益课·棒球1号位
MLB(美国职业棒球大联盟)的棒球公益课通过推广棒球运动、普及体育教育,对全球多个地区产生了多层次的影响: 1. 体育文化推广 非传统棒球地区的普及:在棒球基础较弱的地区(如中国、欧洲部分国家)…...
Android 中 Handler (创建时)内存泄漏问题及解决方案
一、Handler 内存泄漏核心原理 真题 1:分析 Handler 内存泄漏场景 题目描述: 在 Activity 中使用非静态内部类 Handler 发送延迟消息,旋转屏幕后 Activity 无法释放,分析原因并给出解决方案。 内存泄漏链路分析: 引…...
linux-驱动开发之设备树详解(RK平台为例)
前言 Linux3.x以后的版本才引入了设备树,设备树用于描述一个硬件平台的板级细节。 在早些的linux内核,这些“硬件平台的板级细节”保存在linux内核目录“/arch”, 以ARM为例“硬件平台的板级细节”保存在“/arch/arm/plat-xxx”和“/arch/ar…...
【现代深度学习技术】注意力机制05:多头注意力
【作者主页】Francek Chen 【专栏介绍】 ⌈ ⌈ ⌈PyTorch深度学习 ⌋ ⌋ ⌋ 深度学习 (DL, Deep Learning) 特指基于深层神经网络模型和方法的机器学习。它是在统计机器学习、人工神经网络等算法模型基础上,结合当代大数据和大算力的发展而发展出来的。深度学习最重…...
RDD的五大特征
1. 由多个分区(Partitions)组成 特性:RDD 是分区的集合,每个分区在集群的不同节点上存储。分区是数据并行处理的基本单位。作用:分区使 RDD 能够在集群中并行计算,提高处理效率。 2. 有一个计算每个分区的…...
键盘RGB矩阵与LED指示灯(理论部分)
键盘RGB矩阵与LED指示灯(理论部分) 一、LED指示灯基础 在键盘世界里,LED指示灯不仅仅是装饰,它们还能提供丰富的状态信息。QMK固件提供了读取HID规范中定义的5种LED状态的方法: Num Lock(数字锁定)Caps Lock(大写锁定)Scroll Lock(滚动锁定)Compose(组合键)Desp…...
HTTP方法和状态码(Status Code)
HTTP方法 HTTP方法(也称HTTP动词)主要用于定义对资源的操作类型。根据HTTP/1.1规范(RFC 7231)以及后续扩展,常用的HTTP方法有以下几种: GET:请求获取指定资源的表示形式。POST:向指…...
【sqlmap需要掌握的参数】
sqlmap需要掌握的参数 目标-u 指定URL 用于get请求-l 用于post请求- r 用于post请求指定数据库/表/字段 -D/-T/-C 脱库获得数据库获取用户获取表获取列获取字段获取字段类型获取值 其他 目标 -u 指定URL 用于get请求 -u URL, --urlURL 目标URL 只使用于get命令中 -l 用于pos…...
用 AltSnap 解锁 Windows 窗口管理的“魔法”
你有没有遇到过这样的场景:电脑屏幕上堆满了窗口,想快速调整它们的大小和位置,却只能拖来拖去,费时又费力?或者你是个多任务狂魔,喜欢一边写代码、一边看文档、一边刷视频,却发现 Windows 自带的…...
高并发内存池(三):TLS无锁访问以及Central Cache结构设计
目录 前言: 一,thread cache线程局部存储的实现 问题引入 概念说明 基本使用 thread cache TLS的实现 二,Central Cache整体的结构框架 大致结构 span结构 span结构的实现 三,Central Cache大致结构的实现 单例模式 thr…...
数据治理域——数据治理体系建设
摘要 本文主要介绍了数据治理系统的建设。数据治理对企业至关重要,其动因包括应对数据爆炸增长、提升内部管理效率、支撑复杂业务需求、加强风险防控与合规管理以及实现数字化转型战略。其核心目的是提升数据质量、统一数据标准、优化数据资产管理、支撑业务发展和…...