Rust输出到命令行输出到命令行主要可以使用println!()和print!() 1. 这两个都有!是因为他们并非是函数,而是宏,具体我们以后再介绍,普通函数是不需要加!的 2. 两者的区别是是否会在行尾加一个换行符 3. 具体使用方法和C语言的printf很像,但是是用{}作为占位符 4. 并且会自动识别和填充参数,字符也可以写在{}中 5. 也可以使用数字指定参数的位置 6. 转义字符是相同的,只有{或者}是需要对应的写两遍
例如
12345678fn main(){ let a = 12; let b = 24; println!("a is {}", a); println!("a is {a}"); println!("b is {1}, a is {0}", a, b); println!...
Rust语言介绍和猜数字游戏的实现Rust语言是一种系统编程语言,核心强调安全性、并发性以及高性能,由类似于C/C++的底层控制能力,性能也非常接近,Rust有一些特性
所有权系统,这个可以自动管理内存,无需垃圾回收器,保证数据的安全
零成本抽象,高层抽象不会带来运行时的开销,运行时的效率会很高
线程安全,在编译阶段就能防止数据竞争的问题
强类型语言,类型转换非常严格,提升代码的可靠性
cargo管理工具非常好用,简化项目的管理和依赖管理
cargo是什么cargo是rust的官方管理构建工具,一来可以创建项目、构建项目、运行项目,二来可以管理整个项目依赖的第三方库,cargo基本上涵盖了所有的第三方库,可以在www.crate.io中查看
一些常用的方法如下
1234567cargo new project_name # 创建rust项目cargo build # 构建项目生成可执行文件cargo run # 构建并允许项目cargo add lib_name # 添加最新版本依赖cargo remove lib_name # 删除依赖cargo update [...
ABA问题是并发编程中一个经典的问题,尤其在使用无锁数据结构时容易发生。它源于变量值经历了”A→B→A”的变化序列,导致程序逻辑误判状态未改变。以下是详细解析:
ABA问题的定义当某个线程执行CAS(Compare-and-Swap)操作时:
线程1读取共享变量的值为A
线程2将值修改为B,随后又改回A
线程1再次检查时发现值仍是A,认为未被修改,继续执行操作
此时程序逻辑可能因中间状态变化而出现错误。
典型案例(链表删除场景)假设一个无锁链表结构:
12345struct Node { int value; Node* next;};Node* head; // 全局头指针
线程1操作:
读取当前头节点指针old_head = head(地址0x1000,值A)
准备将头指针更新为new_head = old_head->next
线程2操作:
删除头节点0x1000,释放内存
新建节点0x2000(值B),插入链表头部
再次删除0x2000,分配新节点0x1000(值C,但地址与旧节点相同)插入头部
结果:线程...
深入理解无锁队列与C++原子操作引言在多线程编程中,传统的锁机制(如互斥锁)虽然能保证线程安全,但存在性能瓶颈和死锁风险。无锁(Lock-Free)数据结构通过原子操作实现线程安全,能显著提升高并发场景下的性能。本文将详解如何使用C++原子变量实现无锁队列。
原子操作基础什么是原子操作?原子操作是不可分割的最小操作单元,要么完全执行,要么完全不执行。C++11通过<atomic>头文件提供原子类型:
123#include <atomic>std::atomic<int> counter(0);
内存顺序(Memory Order)指定原子操作的内存可见性顺序,常用选项:
memory_order_relaxed:无顺序保证
memory_order_acquire:加载操作,保证之后的内存访问不会重排到前面
memory_order_release:存储操作,保证之前的内存访问不会重排到后面
memory_order_seq_cst(默认):严格顺序一致性
12counter.store(42, std::memory_order_r...
深入解析C++中的静态多态与动态多态多态的本质与价值多态(Polymorphism)作为面向对象编程的三大核心特性之一,是构建灵活、可扩展软件系统的关键所在。在C++中,多态的实现主要分为静态多态(Static Polymorphism)和动态多态(Dynamic Polymorphism)两种形式,它们以不同的方式实现了”一个接口,多种实现”的核心思想。
多态的核心意义
提高代码复用性
增强系统扩展性
降低模块耦合度
实现接口与实现的分离
静态多态:编译时的魔法实现方式函数重载123456class Calculator {public: int add(int a, int b) { return a + b; } double add(double a, double b) { return a + b; } string add(const string& a, const string& b) { return a + b; }};
运算符重载12345...
HTTP3.0:QUIC协议详解QUIC是什么QUIC,读作“Quick”,顾名思义就是“快得飞起”。它是Google在2012年推出的一种基于UDP的新型传输协议。UDP大家应该都知道,那个不讲究顺序、不管丢包、不负责重传的“放养型”协议。QUIC就像是给UDP装上了加速器,再加上TCP的一些可靠性,摇身一变成为了一个又快又可靠的传输协议
QUIC为什么这么快QUIC有以下的特点
连接建立快:一见钟情型协议传统的TCP握手需要三次来回(俗称“三次握手”),还得再加个TLS握手才能加密,整个过程就像是在相亲时反复确认“你是谁?”、“你确定是你吗?”、“好吧,那我们开始吧”。而QUIC直接跳过这些繁琐步骤,用一个握手搞定连接和加密,利用缓存,显著减少连接建立时间
拥抱UDP:轻装上阵TCP虽然可靠,但它太重了,总要考虑丢包、顺序、重传等问题。而QUIC基于UDP,轻量级、不啰嗦,改善拥塞控制,拥塞控制从内核空间到用户空间
多路复用:一条路走到黑HTTP/2的多路复用功能是在同一个连接里可以传输多个流(stream)。但TCP有个问题,一旦某个流出问题(比如丢包),整个...
从1.0到3.0的性能革命HTTP/1.0(1996)
短连接模式:每次请求需新建TCP连接,如同每次点餐都要重新排队
基础功能框架:GET/POST/HEAD方法、状态码、首部字段奠定标准
性能痛点:加载含10张图片的网页需建立11次连接(1个HTML+10个图片)
123# 典型HTTP/1.0请求示例GET /index.html HTTP/1.0User-Agent: Mozilla/5.0
HTTP/1.1(1999)
长连接机制:Connection: keep-alive 实现TCP连接复用
管道化传输:允许连续发送多个请求(但响应必须按序返回)
关键创新:
Host头支持虚拟主机
分块传输编码
缓存控制机制
队头阻塞问题:如同高速公路上的抛锚车辆,前一个未完成的请求会阻塞后续所有请求
HTTP/2(2015)
二进制分帧层:将消息分解为独立帧传输
多路复用技术:在单个连接上并行交错传输多个请求/响应
头部压缩:HPACK算法减少重复头部数据
服务器推送:主动推送CSS/JS等依赖资...
C++ CRTP 详解:奇异递归模板模式的原理与应用在 C++ 编程中,模板不仅仅用于泛型编程,还可以发挥出“元编程”的威力。CRTP,即“奇异递归模板模式”,正是一种利用模板实现静态多态和代码复用的设计模式。本文将从原理、示例、优缺点以及新标准对其的改进等多个角度详细讲解 CRTP。
CRTP 简介CRTP 的英文全称为 _Curiously Recurring Template Pattern_,顾名思义,就是让一个类在继承时将自身作为模板参数传给其基类。例如:
123456789101112131415161718192021// 基类模板template <typename Derived>class Base {public: // 调用派生类的成员函数 implementation() void interface() { static_cast<Derived*>(this)->implementation(); } // 如果派生类没有重写,基类可以提供一个默认实现...