自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 详解数据结构线性表 c++实现

线性表是一种非常基础且重要的数据结构,它是具有相同数据类型的 n(n≥0)个数据元素的有限序列。这里的 “有限” 意味着元素的数量是确定的,“序列” 则表示元素之间存在着顺序关系。

2025-04-04 12:31:00 653

原创 详解红黑树 c++实现

红黑树是一种高效的自平衡二叉查找树,通过特定规则和操作确保平衡,从而保证各项操作的时间复杂度为O(log n)。

2025-04-02 15:38:29 583

原创 详细介绍平衡二叉树 c++实现

(AVL树)是一种,由Adelson-Velsky和Landis于1962年提出。其核心目标是,从而避免普通二叉搜索树(BST)在插入有序数据时退化为链表的性能问题。每个节点的AVL树要求所有节点的平衡因子绝对值。若某个节点的平衡因子超出范围,则触发以恢复平衡。AVL树也是二叉搜索树,插入搜索删除都是一样的,只是每次操作完后检查一次是否失衡![[平衡二叉树旋转规则.jpg]]

2025-03-31 14:23:27 556

原创 详解数据结构之树、二叉树、二叉搜索树详解 C++实现

树是n ( n>=0 )个结点的有限集。n=0时称为空树。图中的G H I J为叶子节点,B C D E F为分支结点也叫做内部结点,整颗树的度为3因为节点D的度为3。

2025-03-30 16:03:08 988

原创 详解c++中万能引用、完美转发、类型推导

值继续看这章之前建议先了解右值的概念,可以看右详细介绍右值。

2025-03-28 14:04:45 796

原创 详解c++中的可调用对象,std::function、Lambda表达式、std::bind等

可调用对象用处广泛,比如在使用一些基于范围的模板函数时(如 sort()、all_of()、find_if() 等),常常需要我们传入一个可调用对象,以指明我们需要对范围中的每个元素进行怎样的处理。又比如,在处理一些回调函数、触发函数时,也常常会使用可调用对象。()等。上面演示了最简单的可调用对象。

2025-03-27 21:06:31 989

原创 详解c++的类型转换,static_cast、dynamic_cast、const_cast、reinterpret_cast运算符

c中变量的数据类型可以强制转换为其他数据类型。但由于这种C风格的类型转换可能会出现一些问题,即过于松散的情况和因此 C++ 提出了更加规范、严格的类型转换,添加了四个类型转换运算符,进而更好的控制类型转换过程。

2025-03-27 17:37:32 615

原创 详细讲解c++中线程类thread的实现,stl源码讲解之thread

本节我们来详细介绍一下c++中的线程类thread,在讲解的过程中会用到大量模板的知识,可以去看是一个 SFINAE(Substitution Failure Is Not An Error)技巧,用于禁止使用thread对象作为可调用对象来构造新的thread对象。

2025-03-26 21:49:59 756

原创 c++手撕协程库,实现生成器与自定义可等待对象

Context定义了我们用到的14个寄存器,而swap_context函数就是我们代码层面用来调用汇编的接口,这个函数只有声明没有定义,在连接阶段会将汇编代码与当前的声明合并,详细的c++编译过程可以看。协程是用户态的线程,它需要由程序来进行调度,如上下文切换与调度设计都需要程序来设计,并且协程运行在单个线程中,这就成就了线程的低成本,简单讲协程就是一种可以被挂起与恢复的特殊函数。你可以简单的理解为就是一个函数名,冒号后面是函数的运行逻辑,我们分为两部分保存于恢复之间用换行分隔,

2025-03-25 17:29:37 917

原创 详解c++20的协程,自定义可等待对象,生成器详解

自定义可等待对象需要满足特定的接口要求,主要涉及和这三个成员函数。:用于判断是否可以立即恢复协程的执行。若返回true,协程会马上恢复;若返回false,协程就会被挂起。:在协程挂起时调用,这里可以执行异步操作。在示例中,使用一个新线程来模拟异步操作,操作完成后恢复协程。:在协程恢复执行时调用,返回异步操作的结果。return 42;});// 输出: 42return 0;

2025-03-24 23:18:15 1196

原创 详细解释计算机系统中的大小端

在计算机系统中,对于跨越多字节对象都被存储为连续的字节序列,对象的地址为所使用字节中最小的地址,例如,假设一个类型为int的变量x的地址为0x100,也就是说,地址表达式&x的值为0x100。那么,(假设数据类型int为32位表示)x的4个字节将被存储在内存的0x100、0x101、0x102和0x103位置。这种排列方式有两种,某些机器选择在内存中按照从最低有效字节到最高有效字节的顺序存储对象,而另一些机器则按照从最高有效字节到最低有效字节的顺序存储。在最前面的方式,称为。在最前面的方式,称为。

2025-03-22 21:47:28 164

原创 Amdahl 定律

a表示我们提升部分初始耗时比例,k是我们的提升倍率,通过这个公式我们可以轻松的得知对每一部分的提醒,对整个系统带来的影响是多少。

2025-03-22 21:46:41 231

原创 计算机时钟周期

是描述硬件操作时序的基本概念,它决定了计算机各部件协调工作的节奏,CPU内部时钟振荡器产生的周期性脉冲信号就是时钟周期,是计算机系统的最小时间单位。在计算机系统中cou运行命令的时间是按时间周期来算的,比如运行最基本的加分运算可能需要1周期完成,对于同架构的cpu这个周期是一样的,不过实际运行时间不同,这是因为不同处理的主频不一样导致一时钟周期需要的时间也不一样。拿苹果的m1芯片举例,它的主频是3.2GHz,时钟周期是3.2 * 10的9次方分之1,所以一时钟周期是31纳秒。

2025-03-22 21:45:47 228

原创 简述计算机系统中的抽象,进程、线程、虚拟内存与文件抽象

计算机系统中的一个重大主题就是提供不同层次的抽象表示,来隐藏实际实现的复杂性。在处理器里,指令集架构提供了对实际处理器硬件的抽象。使用这个抽象,机器代码程序表现得就好像运行在一个一次只执行一条指令的处理器上。底层的硬件远比抽象描述的要复杂精细,它并行地执行多条指令,但又总是与那个简单有序的模型保持一致。

2025-03-22 12:47:51 706

原创 详解计算机储存系统,局部性原理,高速缓存与寄存器的作用

根据机械原理,较大的存储设备要比较小的存储设备运行得慢,而快速设备的造价远高于同类的低速设备。比如说,一个典型系统上的磁盘驱动器可能比主存大1000倍,但是对处理器而言,从磁盘驱动器上读取一个字的时间开销要比从主存中读取的开销大1000万倍。针对这个原因,计算机系统中的储存结构被设计成了多层,根据访问速度来排列,最顶层的访问速度最快相应的造假也更高储存容量更少,低层的造价便宜容量大,访问速度也更低,这样设计的主要原因是上一层的存储器作为低一层存储器的缓存,这种设计有效的原因是使用了。

2025-03-21 19:49:51 778

原创 c++简单实现redis

本节我们一步一步实现redis的基本数据类型,redis的数据类型讲解可以看核心redis类的实现我们通过这个类来控制整个redis系统,这是一个单例类,commandTypes是各个设计命令对应的类型,比如set对应string,hset对应hash,redis这个成员变量是所有的键值对,这个函数继承了一个单例模板类,我们通过you hao,它只对外开放一个command接口,参数和返回值都是一个字符串,下面是具体实现。

2025-03-20 20:26:41 1067

原创 c++实现单例模板类

上面就是我们单例模板类的全部类,很简单的实现GetInstance函数用来获得实例,如果你是c++11以下的版本,你可以需要额外做一下线程安全,因为在c++11之前static是不保证线程安全的,我们delete掉了移动构造和移动赋值函数,确保类的唯一形,我们还将构造与析构函数设置成为了protected,这确保了在代码中我们无法构造单例类。今天我们来实现一个懒汉式的单例模板类,我们只需要继承这个类就可以实现单例,懒汉式是在第一次被使用时才进行初始化,这叫做延迟初始化。

2025-03-20 17:09:54 163

原创 Linux中的epoll简单使用案例

允许一个进程或线程同时监控多个网络 sockets 的状态。它通过单个系统调用(select)来检查多个 sockets 是否有数据可读、可写或是否有异常。Linux 提供了多种 I/O 复用技术,包括上面提到的 select、以及 poll、epoll。

2025-03-17 22:12:43 605

原创 Linux网络编程,创建api的使用方式

本节将详细介绍Linux网络编程,主要包括套接字的作用,Linux的模型epoll,在网络编程中,就像是网络世界的。每一个联网的应用程序,为了能够互发消息,都会使用到这样一个端口。这个端口允许数据从一个程序流向另一个程序。简而言之,套接字是应用程序用来在网络上交流的桥梁。而允许一个进程或线程同时监控多个网络 sockets 的状态。它通过单个系统调用(select)来检查多个 sockets 是否有数据可读、可写或是否有异常。

2025-03-17 20:16:48 770

原创 简答介绍Redis的基本使用

Redis是一款高性能的key-value数据库,Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用,同时还提供list,set,zset,hash等数据结构的存储。Redis支持数据的备份,即master-slave模式的数据备份,并且Redis的所有操作都是原子性的,同时Redis还支持对几个操作全并后的原子性执行。Redis的操作相当简单,我们可以使用redis-cli工具在命令行连接redis,对于redis的命令相当简单,详看下面的介绍。

2025-03-16 19:13:20 596

原创 详解c++的编译过程,如何从源文件到可执行文件到

本节详细介绍c++的编译过程,c++从代码到可执行文件有四个阶段:我们可以使用这一命令进行预处理,预处理后的文件还是文本文件可以打开查看以.i为结尾这一阶段主要处理以井号#开头的代码,比如, , ,对代码进行一个初步的处理,并且会把所有注释删除,通过#include将头文件的实际内容放入当前文件中,主要有两种格式 或 ,对于尖括号的格式,编译器会在默认的头文件搜索路径(通常是标准库头文件所在的系统目录)中查找指定的头文件。例如像、这样的标准库头文件,通常使用尖括号来引用,对于双引号格式,编译器会优先在当

2025-03-16 15:40:53 1192

原创 c++详解模板泛型编程,详解类模板的实现为什么不能放在cpp文件

泛型编程是一种编程范式,它允许程序员编写与类型无关的代码,从而在编译期确定具体的类型。我们通过模板编写一个函数可以让编译器,自动生成对应类型的实现,这大大减少了重复代码的出现,还提高了代码的可维护性和可扩展性,很重要的一点是模板有特性。

2025-03-15 22:37:58 850

原创 c++异常处理简单介绍 try catch throw三者的作用

c++中通过try catch throw这三个关键字处理异常,我们为什么要处理异常呢,为什么要用专门的异常处理来处理异常呢,这是本文将要解决的几个问题,我们会一一解答疑惑,异常处理的主要作用是,让我们的程序更健壮,当遇到不可预测的问题时可以做出处理,而不是直接崩溃,当发送错误时可以让程序执行备选方案,如果不得不接受程序时可以提前做一些必要的工作,如将内存中的数据写入文件、关闭打开的文件、释放动态分配的内存空间等。

2025-03-15 17:03:21 284 1

原创 c++详解移动语义,右值引用与move函数的作用,noexcept关键字在移动构造与移动赋值运算符中的重要性

这是c++ 11新添加的特性,设计的目的是为了避免不必要的拷贝开销,通过提升性能,它可以在不拷贝的情况下移动大型资源,它所做的就是将现有资源的所有权交给其他对象,而传统的拷贝需要进行一次内存分配这是很大的开销,移动语义相较于拷贝性能提升相当明显,移动后的源对象处于,即保证可安全析构和重新赋值,但具体成员值由实现决定(可能为空、残留值等)。继续访问其值前必须先重置状态。

2025-03-14 19:27:20 449

原创 c++智能指针详解,如何防止循环引用

智能指针是c++ 11标准,添加的用于管理内存资源的类,通过智能指针我们可以,轻松的对内存进行分配与释放,这使得我们不再需要,为手动管理内存的繁琐而烦恼了,主要有三个智能指针,分别是unique_ptrshared_ptrweak_ptr,我们下面一一介绍我们先来看看智能指针的基本使用上面这一部分代码,如果没有智能指针是不可以出现~Test析构的,而使用了智能指针后当func1函数退出时,我们创建的资源就自动被释放了,这就是智能指针的魅力,利用RAII思想完美实现资源的管理,真的非常方便且高效。

2025-03-13 22:06:04 1038

原创 详解c++中的const关键字

c++中const关键字可以实现将一个变量或者函数,限定为只读不可进行修改的功能,它的作用是很大的,const可以避免程序员在代码中意外修改某些本应保持恒定的值,并且它还可以限定指针或引用,使其无法通过它们修改所指向的对象,通过const,可以增强代码的安全性和可读性,明确标识出不应被修改的部分,同时编译器会强制检查这些约束。下面再仔细讲讲,const在c++的各种应用。

2025-03-13 19:18:04 388

原创 C++基础内存管理讲解,如何避免常见的内存问题,堆栈内存讲解

内存管理是c++变成中很重要的一环,这是编写高效可靠c++的必要条件,这也是c++与其他高级语言最大的区别,其他的语言都提供了高级的gc机制,而c++没有这就难住了很大一部分人了,对于高手来说这是高效程序的关键,对于菜鸟这就是噩梦啊,经常出现的野指针,忘记delete的内存严重影响了运行与开发效率。

2025-03-12 22:58:21 626

原创 详解C++中的抽象类与虚函数表的实现

我们创建了两个派生类,通过输出可以看到a1和a2都输出了自己的名字,而a1调用test输出的是基类test的函数,实现这种现象是因为c++中的虚函数表,虚函数表是一个存储虚函数指针的数组,每个类(含虚函数的类)会生成一个虚函数表,每个对象在内存中会通过一个隐式的。具体情况我们看下面的测试。目前基类使用非虚的析构函数,我们运行后会发现只输出了Base destructor,这肯定是不行的我们的派生类没有运行析构,会导致严重的内存泄露。下面我们来使用一下Abstract这个基类。指向它所属类的虚函数表。

2025-03-11 18:51:52 299

原创 CMake构建cpp代码的实践

是一个跨平台的构建系统生成器,它通过高级的配置文件()生成底层构建工具所需的文件(如 Make的Makefile他的主要作用就是组织cpp代码,生成make的Makefile文件用于编译,它支持多平台(Linux、Windows、macOS)和多编译器(GCC、Clang、MinGW)我们的测试代码是cpp的,下面是我们的目录结构。

2025-03-11 17:15:29 369

原创 Docker 如何创建自己的镜像(多阶段构建) Dockerfile文件的使用

本教程教大家如何使用Dockerfile文件创建自己的镜像,我们使用一个简短的go代码作为演示,它的作用是开启一个http端口,下面是我们的go代码。我们使用多阶段构建的形式来制作镜像,这种方式的好处是使程序运行在一个更稳定的环境中,还可以大大减少镜像的大小,接下来我们逐行解析。输出如上就表示运行成功了,下面我们开始讲解如何使用docker制作一个容器来运行这个代码。拿到代码后要先确保电脑安装了go的环境,如果有我们运行下面的命令,先来运行一下看看效果。

2025-03-10 23:24:44 279

原创 详解Qt信号与槽机制,讲解底层实现

connect的作用是链接信号与槽,连接后Qt 将发送者对象、信号索引、接收者对象、槽函数索引、连接类型等信息存储在一个全局的 **连接列表** 中,还会进行参数校验,槽的参数可以比信号少,在使用时信号与槽支持基本的隐式类型转换(例如 `int` 可隐式转为 `double`),但是不正常自定义的隐式转换,最后通过 `QMetaMethod::methodIndex()` 获取信号和槽在元对象中的唯一索引。若发送者与接收者同线程,使用**直接连接**;否则使用**队列连接**。下面我们帮演示边讲解原理。

2025-03-10 15:45:27 291

原创 c++通过RAII思想实现go的defer

RAII是想是c++之父提出的一种自动管理生命周期的思想,使用局部变量来管理动态分配的内容,它充分的利用了C++语言局部对象自动销毁的特性来控制资源的生命周期。go语言中的defer就是这种实现,提前定义一个函数,当作用域结束的时候自动执行,今天我们就来实现这个小功能。上面的功能就实现了最基本的defer功能,在构造时确定函数,析构时执行我们给它的函数,下面测试代码。输出是5511 11完美实现。

2025-03-09 22:14:31 189

原创 Apisix教程 安装与使用,并与consul结合实现服务发现,负载均衡限流,统一鉴权(超级详细)

在微服务中网关是很重要的操作,肩负了统一鉴权、熔断限流、负载均衡等责任,网关是非常重要的一部分,本篇我们就来介绍一款高性能网关Apisix,这个网关的主要特点有三个,1.全动态能力,你不需要重启就可以更改网关的各种配置(conf.yaml这个无法热加载),2.使用nginx内置变量做为路由的匹配条件,可以自定义匹配函数来过滤请求,3.支持与众多的工具与平台集成使用,并且有优化的ui界面下面我们开始安装与配置。

2025-03-09 18:10:37 1079

原创 git教程,git的基本使用(超级详细)

git是程序员不可或缺的工具,它可以轻松的实现版本控制与保存代码,这可以让我们在出现bug或不消息误删内容时,可以快速回溯到没有问题的代码,希望大家在发送这样的事情前就用起来,博主之前就是因为误删核心代码,又没有用git导致耽误一个星期重写,从那开始我所有的项目都使用了git。

2025-03-07 16:10:35 432

原创 Docker教程2 运行MySQL容器,详细讲解run命令

如果我们没有指定版本默认下载最新的,我们可以使用`docker images`命令来查看下载的所有镜像,镜像下载完成后就想要运行了,运行前先创建几个目录,用于将宿主机的目录挂载到容器内部。第一个是hub官方维护的镜像,我们一般就使用这个,如果有特殊需求后面还有各个团队维护的不同版本,点进去可以查看详细的介绍,再点击tags可以查看所有版本,我们可以选择自己想要的版本。`-p`用来设置端口映射,冒号前面的是主机的端口,后面的是容器的端口,这个表示将主机的3306端口映射到容器的3306。

2025-03-06 21:54:06 332

原创 Docker教程1 从下载安装配置到运行第一个容器(超级详细)

docker是现在经常使用的一个东西,它可以很方便的启动中间件,配置运行环境,是非常值得学习的一个工具。

2025-03-05 22:08:46 210

原创 c++ 手撕线程池

我们先说最基本的workerThread函数,每个线程内部运行的都是它,其内部定义了一个function<void()>用于运行用户提交的任务,一个死循环保证线程不会自己退出,使用条件变量加智能锁实现了线程安全与无任务时让线程阻塞以免浪费资源,cv.wait的作用是当条件不满足时阻塞当前线程并且释放锁,当被唤醒时会重新判断条件,如果为true重新加锁并恢复线程运行,这时候我们将队列内部的任务取出一个在当前线程运行,这里花括号的作用是限制锁的作用域,减少锁的持有时间,避免执行用户任务时持有锁。

2025-03-04 16:49:57 280

原创 C++实现工厂模式和注册宏

ProductCreator是我们的映射类型,我们将构造和赋值函数都禁用,默认构造函数设置为私有的这样设置一个单例类,registerClass函数用来注册类,使用时想要一个类的类型参数是类名字符串,内部将一个闭包放入映射中,在创建时就会调用这个闭包来生成类,这里为什么要返回一个short我们后面讲,create很简单传入一个类名,他就会返回对应的类实例,没有就返回空指针。我们并没有实现运行时这一关键点,我们实现的这个必须在编译时就确定的,不能在运行时根据用户的输入或配置文件来决定加载和使用哪些类。

2025-02-13 13:33:28 359 1

原创 手撕shared_ptr 共享指针

今天让我们来手撕c++的共享指针shared_ptr,共享指针的是通过引用计算和RAII思想来实现的,当我们将指针赋值给其他shared ptr时内部有一个计数变量会加1,当shared ptr触发析构时这个计数就会减1,当计数为0时就会自动的释放管理的资源

2025-02-11 23:21:05 491

原创 vtk加载stl模型文件并在qml中显示

负责呈现数据到场景中通过关联vtkPolyDataMapper决定显示内容,还可以设置模型的颜色与透明度,接着我们使用vtkCellCenters计算每个三角面片单元的中心,并且选择第一个中心存储到ViewCenter,作为actor的原点与摄像机的焦点,最后将vtkActor加入vtkRenderer渲染器。vtkSTLReader STL文件读取器,用于读取缩放好的 STL 文件,vtkPolyDataMapper几何数据映射器,将几何数据转换为可渲染的图元,vtkActor场景中的可视对象。

2025-02-08 17:50:39 385

空空如也

空空如也

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

TA关注的人

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