自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(218)
  • 收藏
  • 关注

原创 Rust闭包详解

默认情况下,闭包会借用他捕获的环境中的变量,闭包可以使用这些变量,但是不能修改他们的所有权,此时闭包内部和外部的作用域都可以使用这个变量。:在闭包之前添加move关键字,闭包会获取他捕获的变量的所有权,此时,变量的所有权会转移到内部,外部作用域无法使用这些变量。闭包的生命周期与它们所捕获的变量的生命周期相关。Rust 的闭包是轻量级的,并且 Rust 的编译器会进行优化,使得闭包的调用接近于直接调用函数。闭包可以通过move关键字获取外部变量的所有权,或者通过借用的方式获取外部变量的引用。

2025-04-01 21:12:17 487 1

原创 Rust迭代器详解

我们也可以为自己的类型实现迭代器 iterator trait(可以理解为接口)只需要定义next方法即可,例如} else {Noneprintln!// 输出 1 到 5这里我们先不去管 impl 是什么,直接翻译的话是实例,适用于给结构体或者特性实现方法的一个关键字。

2025-04-01 20:45:48 762

原创 Rust函数、条件语句、循环

除此之外也可以给循环设定标签,也就是可以在多层循环时,内部只需要一个break,就能退出所有循环,同时还能带出返回值。这是rust非常重要的基础概念,我们可以认为函数体是由语句和表达式组成的。需要注意的是,表达式的返回值是 a + b,代表整个表达式的返回值,加上。函数名是蛇形风格,rust不在意函数的声明顺序,只需要有声明即可。for循环是和python很像的,类似于C++的范围for。这里的a是数组,iter表示迭代器,后面我们会详细讲。语句指的是执行某些操作并且没有返回值的步骤。

2025-03-23 20:10:25 412

原创 Rust基础语法

用bool表示,只能是true或者false,需要注意的是,这里相对于C/C++的限制更加严格,bool类型是无法和int类型进行隐式类型转换的。使用char表示,大小位4字节,主要是因为是使用Unicode编码的,可以支持中英日韩表情符号零宽度空格,这些都是有效字符。Rust是强类型语言,也就是说他对于变量的限制非常严格,但是具有自动判断变量类型的能力。我们可以认为这个a是一个变量,可以使用let重新绑定,但是在绑定之前是不允许被改变的。上面的a是不可变变量,因此任何形式的重新赋值都是不被允许的。

2025-03-21 11:12:37 497

原创 Rust语言介绍和猜数字游戏的实现

Rust语言是一种系统编程语言,核心强调安全性、并发性以及高性能,由类似于C/C++的底层控制能力,性能也非常接近,Rust有一些特性所有权系统,这个可以自动管理内存,无需垃圾回收器,保证数据的安全零成本抽象,高层抽象不会带来运行时的开销,运行时的效率会很高线程安全,在编译阶段就能防止数据竞争的问题强类型语言,类型转换非常严格,提升代码的可靠性cargo管理工具非常好用,简化项目的管理和依赖管理。

2025-03-19 21:15:17 665

原创 并发编程之ABA问题

ABA问题是并发编程中一个经典的问题,尤其在使用无锁数据结构时容易发生。它源于变量值经历了"A→B→A"的变化序列,导致程序逻辑误判状态未改变。以下是详细解析:当某个线程执行**CAS(Compare-and-Swap)**操作时:此时程序逻辑可能因中间状态变化而出现错误。假设一个无锁链表结构:线程1操作:线程2操作:结果:线程1执行时,发现仍是0x1000,误以为链表未变化,实际上:

2025-02-17 15:45:36 742

原创 深入理解无锁队列与C++原子操作

原子操作是不可分割的最小操作单元,要么完全执行,要么完全不执行。C++11通过<atomic>

2025-02-17 15:44:31 376

原创 C++多态:静态多态vs动态多态

多态(Polymorphism)作为面向对象编程的三大核心特性之一,是构建灵活、可扩展软件系统的关键所在。在C++中,多态的实现主要分为静态多态(Static Polymorphism)和动态多态(Dynamic Polymorphism)两种形式,它们以不同的方式实现了"一个接口,多种实现"的核心思想。在这一篇博客里我有详细介绍(

2025-02-12 17:49:57 831

原创 HTTP3.0:QUIC协议详解

QUIC就像是给UDP装上了加速器,再加上TCP的一些可靠性,摇身一变成为了一个又快又可靠的传输协议。传统的TCP握手需要三次来回(俗称“三次握手”),还得再加个TLS握手才能加密,整个过程就像是在相亲时反复确认“你是谁?而QUIC则完美解决了这个问题,每个流都是独立的,互不干扰。QUIC采用了类似TCP的拥塞控制机制,但它更灵活,可以根据网络状况动态调整传输速度,既能跑得快,又不会把网络“堵死”。理想和现实总是有一定的差距:虽然经过多年的推广的应用,但QUIC协议目前仍未达到大量普及的阶段,在。

2025-02-12 17:48:59 1095

原创 从HTTP1.0到HTTP3.0性能革命

简单介绍HTTP1.0到HTTP3.0的特点和发展

2025-02-12 17:47:35 768

原创 C++ CRTP:奇异递归模板模式的原理与应用

CRTP 的英文全称为,顾名思义,就是让一个类在继承时将自身作为模板参数传给其基类。// 基类模板public:// 调用派生类的成员函数 implementation()// 基类模板 template < typename Derived > class Base {public :// 调用派生类的成员函数 implementation() void interface() {} // 如果派生类没有重写,基类可以提供一个默认实现 void implementation() {

2025-02-07 11:03:29 1138

原创 git的理解与使用

一般来说master分支是最稳定的,也就是服务部署的分支,然后是dev开发分支,开发分支可以再继续细分到具体的某个人,如果开发只有你一个人来包揽也是可以的,类似的还有feature分支。master分支或者main分支为主分支,一般大型项目都不在主分支上,分支就像是分身一样,写不同部分的代码,最后合并就是完整的项目,因此我们也可以进行分支的创建、切换、合并。当我们使用add之后,代码就会被存储在暂存区,只有commit之后,也就是提交代码,整个代码才会被放入版本库,也就是上图的master文件夹中。

2025-01-24 17:16:47 1494

原创 Web3 简介

Web3 致力于构建一个去中心化、由用户主导的下一代互联网。在这个生机勃勃的领域中,广泛分布着各种类型的赛道,涵盖了去中心化金融( DeFi )、非同质化代币( NFT )、去中心化自治组织( DAO )、去中心化身份( DID )、社交金融( SocialFi )、游戏金融( GameFi )和基础设施等关键领域。每个赛道都孕育出了具有创新性和影响力的经典项目,从为用户提供金融自主权 的 DeFi 协议,到赋予数字创作独特身份的 NFT 市场,再到通过 DAO 促进群体决策的平台。

2025-01-24 15:55:49 753

原创 RabbitMQ的死信队列

对于RabbitMQ来说,死信队列是可以存储不能被正确消费的信息的,可以通过消费死信队列中的内容来分析可能出现的异常情况,可以用于改善和优化系统。死信(Dead Letter)是消息队列中的一种特殊消息,是指没有办法被正常消费或者处理的消息,例如消息过期、消息被拒绝、队列满了。消息的生存时间(Time-To-Live, TTL)超过了指定的时长,而消息仍未被消费,这样的消息会被转移到死信队列。AWS SQS 支持直接配置死信队列,开发者可以设置消息的最大重试次数,超出后消息会被自动转移到死信队列。

2025-01-24 15:40:25 890

原创 BTC密码学原理

区块链由一系列“区块”组成,每个区块包含一组交易记录,并且每个区块的哈希值都与前一个区块的哈希值相连接。如果有人尝试修改已确认的交易,必须重新计算该区块的哈希值,并且修改该区块后面的所有区块的哈希值。由于比特币的网络中有成千上万的节点在不断同步区块链,修改区块链的历史记录需要超过50%的算力,这几乎是不可行的。由于找到有效的哈希值需要消耗大量计算资源,攻击者需要获得超高的算力,成本极高,从而保障了比特币网络的安全性。在比特币的交易中,私钥用于签署交易,从而证明发起交易的用户是该比特币的所有者。

2024-12-09 12:58:12 1574 1

原创 现代C++HTTP框架cinatra

cinatra是一个基于C++20协程的高性能HTTP框架,它的目标是提供一个快速开发的C++ HTTP框架解决方案它不仅支持HTTP/1.1和1.0,还支持SSL和WebSocket,使得开发者可以轻松构建数据库访问服务器、文件上传下载服务器、实时消息推送服务器,甚至是MQTT服务器。

2024-11-16 11:01:58 462

原创 WebSocket协议介绍与C++实现

WebSocket协议建立在HTTP协议之上,首先通过一个HTTP请求来进行握手。一旦握手完成,客户端和服务器之间的连接会被“升级”到WebSocket协议,之后通信不再依赖HTTP,而是直接使用WebSocket协议。

2024-11-13 21:32:10 1248

原创 C++20协程详解

全网最详细协程讲解

2024-11-12 23:01:54 1198

原创 八大技术架构与演进2

比如,在一个电商系统中,可以将用户数据、订单数据、商品数据分别存储在不同的数据库中,以减少单库的负载。但是这种做法其实是增加了数据库的运维难度,这种其实也就叫做分布式数据库,逻辑上是一整个大的数据库,但是实际上却是由各个分开的数据库来组合实现的功能。在同一台服务器中,可以由很多个不同的镜像运行,他们之间是独立的,我们甚至可以粗暴的任务,一个docker容器就是一个简单的操作系统。我们可以将不同的业务分给不同的开发团队去维护,每个团队独立实现自己的微服务,互相之间的数据进行隔离。

2024-11-12 20:52:26 370

原创 八大技术架构与演进1

当应用服务器逐渐增多时,一台数据库服务器可能以及难以满足我们的需求了,但是这里最重要的问题是需要确保数据库服务器的一致性,因此我们采用的解决方案是使用主从服务器,将主数据库服务器用于写,其他的从属服务器用于读数据库服务器,当主数据库改变时,就需要同步到从属服务器中。另一种就是横向扩展,水平扩展,我们对软件架构进行调整,添加应用层的硬件,说人话就是再买一台服务器,采用负载均衡的方式来对用户进行分流,这种方案的优势就在于成本更低,也更方便提供,劣势就是给系统提供了更多的复杂性。

2024-11-10 17:36:46 717

原创 Linux文件描述符详解及其应用

系统会为进程分配一张文件描述符表(FD Table),其中每个打开的文件或资源都会占用一个文件描述符,进程通过文件描述符来读写、控制和管理这些资源。在编程中,可以通过重定向这些文件描述符来改变数据的输入和输出位置,例如将标准输出重定向到文件,或从文件而不是键盘读取输入。每当打开一个文件时,系统会返回一个文件描述符,后续对文件的所有操作(如读取、写入、关闭)都依赖这个文件描述符。每个进程在打开文件、套接字等资源时,操作系统会分配一个可用的文件描述符。文件描述符使文件的操作变得简单,能统一处理不同的资源。

2024-10-26 14:08:49 1661

原创 Linux下的线程同步与死锁避免

即,线程只有在能够获取所有资源时才会继续执行,否则会释放已经持有的资源,避免持有并等待的发生。为了避免这种情况,我们可以在申请资源之前,确保线程不占有其他资源,或者一次性申请所有所需资源。在某些情况下,我们可以通过将资源转换为可共享的资源来破坏互斥条件,从而避免死锁。是指存在一个线程循环等待链,每个线程都在等待下一个线程持有的资源。通过一次性申请资源,线程要么成功获取所有资源并继续执行,要么立即释放资源,减少持有并等待的风险。通过这种方式,线程不会无限期地等待资源,从而避免了死锁的发生。

2024-10-26 14:07:51 1205

原创 Linux环境C++多线程调试工具和内存泄漏工具介绍

幸运的是,Linux 提供了多种调试工具来帮助我们排查多线程相关的问题和内存泄漏。AddressSanitizer 是 GCC 和 Clang 编译器中的另一个强大的工具,用于检测内存错误,包括越界访问、堆栈溢出和内存泄漏。除了多线程问题,内存管理也是 C++ 程序中常见的挑战之一。执行该命令后,Valgrind 会跟踪程序的所有内存分配和释放情况,并在程序结束时给出详细的报告,指出泄漏的内存位置和大小。是一个用于跟踪程序执行时系统调用的工具,对于多线程程序,它可以帮助开发者检查线程相关的系统调用(例如。

2024-10-26 14:07:03 1158

原创 C++11中的同步互斥机制详解

std::mutex是 C++11 提供的最基本的互斥锁,用于保护共享资源,确保同一时刻只有一个线程能够访问该资源。它提供了lock()和unlock()两个基本方法,分别用于加锁和解锁。std::mutex是 C++11 提供的 RAII(资源获取即初始化)机制的封装类,用于自动管理mutex的生命周期。构造时加锁,析构时解锁,确保在函数作用域结束时自动释放锁,避免了手动管理锁的复杂性。是一个比更加灵活的锁管理类。与不同,延迟锁定:可以在对象创建时不锁定,而在需要时调用lock()。

2024-10-26 14:06:21 880

原创 C++中RAII详解

在这些场景中,RAII 的思想同样适用,即在构造时获取资源,在析构时释放资源。智能指针是 C++ 标准库中的一种 RAII 实现,它通过封装原始指针的分配与释放逻辑,帮助开发者自动管理内存。RAII 将资源管理的职责交给对象的构造函数和析构函数,使得开发者无需手动编写资源释放代码,大幅减少代码量和潜在的错误。使用 RAII 管理锁的生命周期,在函数结束或异常时自动释放锁,从而避免死锁或忘记解锁的问题。智能指针的使用减少了手动管理内存的复杂性,并且在异常情况下也能自动释放内存,避免了内存泄漏。

2024-10-26 14:05:18 1160

原创 Linux中exec系列函数与fork函数

函数是进程管理中的两个重要组成部分。它们在创建和执行进程时扮演着关键角色,理解它们的工作原理及相互关系对于系统编程至关重要。后,当前进程(父进程)会被复制一份,生成一个新的进程(子进程)。一起使用,以便创建新的进程并在其中执行新程序。系列函数用于在当前进程的上下文中执行新的程序。在 Linux 和其他 Unix-like 操作系统中,后,当前进程的代码和数据将被新程序替换。是用于创建新进程的系统调用。

2024-10-21 12:33:23 714

原创 C++智能指针对比与总结

C++的智能指针是RAII的一种应用 自动管理动态内存的工具 可以避免显示的内存释放 减少内存泄漏和为定义行为的可能性 C++标准库提供了三种主要的智能指针 unique_ptr shared_ptr weak_ptr。这个智能指针是共享对象的所有权的 是使用引用计数来维护同一个对象 当最后一个shared_ptr被销毁时 对象才会被释放。这是一种弱引用 主要是和shared_ptr配合使用的 他不影响对象的引用计数 也就说他并不会独立拥有对象本身。

2024-10-21 12:30:03 249

原创 C++服务端的配置文件库介绍

Boost.PropertyTree 是 Boost 库的一部分,用于处理层次结构的属性数据,如 XML、JSON 和 INI 文件。jsoncpp 是一个用于解析和生成 JSON 格式数据的库。JSON 格式通常用于现代应用程序的配置文件,因其可读性强且易于使用。在 C++ 项目中,灵活地读取用户配置是提升软件可用性的重要部分。本文将介绍几种常见的 C++ 配置库,包括它们的原理和使用方法。它通过逐行解析文本文件,识别键值对和节(section),便于简单的配置管理。

2024-10-19 11:22:39 958

原创 C++STL库全详解

因此他的迭代器需要维护的信息也很多 但是我们要知道这其中的数据单元是什么 其实还是元素本体 需要有 指向当前元素的指针(找到元素的基本单位) 指向整个指针数组的指针(用来找具体在哪一个缓冲区的指针)指向具体缓冲区的指针(表示当前元素所在的缓冲区)对于对象的构造和析构在空间的申请和释放是分开的 有些对象的构造不需要构造函数 有些对象析构不需要析构函数 将这两个过程分开就能提高程序的性能了 前提是我们需要通过类型萃取来获取类型是否调用 可以通过迭代器来获取 这部分也是比较复杂的。

2024-10-18 18:57:07 1463

原创 常见开源组件的详解

代理函数(stub):是负责客户端和服务器之间的通信 主要是为远程服务调用提供的一个本地接口 把远程调用的过程隐藏起来 他的内部处理功能就是序列化与反序列化 错误处理 返回结果 这种代理函数也支持多种编程语言 让不同语言的服务也能够通信。它遵循“Django 管理后台”的理念,提供了一个完备的后台管理界面,开发者可以快速上手并生成高效的 Web 应用。学过HTTP协议的错误处理都知道 这个玩意的错误机制是不太好的 客户端要根据状态码的不同处理不同的错误情况。

2024-10-13 20:03:13 986

原创 C++多态常见问题

重写指的是在继承关系中子类重新定义继承来的虚函数 重写的函数名\参数列表\返回值类型必须和父类一致 被继承的函数必须是虚函数 可以指定父类显示调用基类的被重写函数 属于动态多态 通过重写子类中的虚函数表实现。重载指的是在同一个作用域中 函数名相同 但参数列表不同 包括类型\个数\顺序 的函数 返回值不同不算重载 属于静态多态 底层原理是在编译时形成不同的函数名 链接时区分链接。重定义指的是在继承关系中 子类重新定义继承来的非虚函数 父类的函数被隐藏 可以使用域作用限定符来访问父类中的同名函数。

2024-10-08 16:53:16 297

原创 C++重载(Overloading)、重写(Overriding)、重定义(Hiding)的对比与区别

重定义指的是派生类中的函数与基类中的同名函数没有完全相同的签名(例如参数列表不同),但基类中的函数并不是虚函数。在这种情况下,派生类中的函数隐藏了基类中的同名函数,即使通过基类指针也无法访问被隐藏的基类函数。函数名相同,但基类的函数不是虚函数。可以参数列表不同,但即便相同,仍会隐藏基类的函数。基类函数被隐藏后,使用基类指针调用时只会访问派生类的版本。重定义可能会导致意外的行为,因此需要注意。public:public:在这个例子中,Child类中的print()函数隐藏了。

2024-10-08 10:16:49 1452

原创 C++继承与组合详解与对比

继承是一种用于创建新类的机制,允许新类(子类)从已有类(基类)继承属性和方法。继承形成了类与类之间的“是一个”关系(is-a relationship)。public:class Dog : public Animal { // Dog 继承自 Animalpublic:在上述代码中,Dog类继承自Animal类,Dog类可以访问Animal类的方法。组合是一种通过将对象嵌套到另一个对象中的方式来实现代码复用。它形成了“有一个”关系(has-a relationship)。

2024-10-04 12:32:29 658

原创 C++异步操作实现线程池

他的一个重要的特性就是能够阻塞当前的线程,一直到异步操作完成,从而确保在获取结果的时候,异步工作线程的任务是完成的。当我们在进行多线程中使用异步任务时,std::future是用来帮我们在需要的时候获取任务执行的结果。这是将一个函数封装起来,也可以返回一个封装对象,来获取他保存的这个函数的执行结果。其实就是设置,在获取结果时,才会进行传参调用,deferred本身是推迟的意思。,是如果有结果的话,直接获取结果,没有的话也是会阻塞等待。在我们调用获取结果之后,才显示正在计算,执行异步任务,

2024-10-03 11:26:35 946

原创 C++引用指针大对比

特性引用指针是否需要初始化必须在声明时初始化可以声明后再初始化是否能为空不能可以为空 (nullptr是否可重新绑定不能,绑定后不能更改可以重新指向不同的对象访问方式直接使用需要使用解引用是否可指向不同对象否是内存占用不占用额外内存占用内存,存储对象地址能否指向数组不能用于遍历数组可以用于数组遍历。

2024-10-03 09:52:55 1009

原创 C++常引用详解

是C++中的一种引用类型,它允许你通过引用访问某个变量,但不允许通过该引用修改变量的值。(rvalue)是一个临时值,通常不能通过变量的名字访问,它仅存在于表达式的计算过程中。是一个右值(临时对象),如果没有常引用,临时对象会在语句结束后销毁。:常引用的一个重要特性是它可以绑定到临时对象(右值),并延长该临时对象的生命周期。简单来说,右值就是临时、短暂的值,通常用于表达式的中间结果或临时对象,不具有持久性。当一个函数返回一个较大的对象时,可以通过常引用返回,避免返回值的拷贝。

2024-10-03 09:45:49 953

原创 C++类型强转详解const_cast,reinterpret_cast,static_cast与dynamic_cast

需要注意的是,这种类型转换是在编译时进行转换,并且不会进行运行时类型检查(RTTI),因此他从子类转父类是安全的,从父类向子类是不安全的,不安全就类似于强制转换。是最不安全的类型转换操作符,通常用于在不相关类型之间进行转换,或者将指针和整数类型之间进行转换。这种方式虽然简单,但缺乏明确性(可读性也一般般)和安全性,编译器不会检查转换的有效性。在 C++ 中,类型转换是一个常见的需求。)之外,C++ 提供了更安全、可读性更强的类型转换操作符,包括。本文将详细介绍这些操作符的用法,并对比它们之间的区别。

2024-10-02 17:47:30 966

原创 GTest测试框架介绍

GTest是谷歌发布的一个跨平台的单元测试框架,主要是为了在不同平台上编写的C++单元测试而生成的。测试中可以有多个测试套件,可以包含一组单元测试,不是很好理解,可以认为这是一个测试环境。测试程序中可以有很多测试套件,对应着全局,每一个测试套件中可以有多个单元测试。这其实就是我们用户自己定义的一个测试环境,是一个全局的测试环境类。如果局部需要设置全局的环境,就需要使用之前的全局的继承。在用例测试中,每一次单元测试都是单独进行的,互不影响。提供了丰富的断言,致命和非致命的判断,参数化。

2024-10-01 16:28:39 1044

原创 SQLite数据库介绍

SQLite是一个本地化的数据库,不需要客户端服务端什么的配置,主打就是轻量化方便化。他也不是一个独立的进程,而是可以根据应用程序的需求,可以进行静态或者动态的连接。第三个参数是flag是可以设置文件的打开方式,提供下面的宏可以选择。需要注意的是 在SQLite中一个数据库对应了一个数据库文件。而且他是直接存储在磁盘文件的,提供了简单易用的API接口。第一个参数是文件名,第二个参数是传入一个句柄指针的地址。如果是其他值的话就代表着有问题,需要查找对应的宏来看到。这是一个执行语句的操作函数。

2024-09-30 19:32:06 910

原创 基于muduo库实现protobuf协议的通信详解

而在这个类中,我们可以看到onMessage和send,其实就是针对protobuf处理的方法,也就是收到消息之后被调用的方法。在之前我们单纯使用muduo实现的时候,并没有考虑到tcp粘包之类的问题,只是进行一个返回。可以看到这里消息回调函数,这里面用的是ProtoBufCodec的onMessage函数。在具体看这个onMessage处理函数之前,我们先看这个协议的结构是什么样的。我们可以先大致学习一下这里是怎么实现的,然后仿照使用一下。有了这样的协议之后,就可以解决粘包问题。业务操作逻辑是这样的。

2024-09-30 14:28:36 528

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除