- 博客(90)
- 收藏
- 关注
原创 【CMake】初识CMake
CMake是一个跨平台的构建工具,它通过读取CMakeLists.txt配置文件生成各平台的构建文件(如Makefile或VS工程文件),再由这些文件完成最终编译。CMake的核心作用是作为"构建文件生成器",解决不同操作系统和编译器间构建规则不统一的问题。 安装CMake后,用户只需维护一套CMakeLists.txt即可实现多平台构建。示例演示了如何用CMake构建一个简单的hello world工程:首先设置最低版本要求,定义项目名称,然后通过add_executable生成可执行
2025-10-24 21:38:23
645
原创 【C++】异步操作
在 C++ 中,异步操作是指程序在执行一个操作时,不需要等待该操作完成就可以继续执行后续代码,从而提高程序的并发性能和响应性。std::async下面就逐一介绍一下。
2025-10-24 21:34:05
831
1
原创 【C++】并发支持库
C++11 thread库提供了跨平台的线程封装,支持面向对象编程和移动语义。thread类提供多种构造函数,最常用的是传入可调用对象和参数的形式。线程对象不支持拷贝,但可通过移动构造/赋值传递。join()用于主线程等待子线程结束。this_thread命名空间提供线程相关全局函数,如get_id()获取线程ID、yield()让出执行权、sleep_for()阻塞指定时长、sleep_until()阻塞到特定时间点。这些函数配合chrono库的时间类型,实现了灵活的线程控制能力。
2025-10-13 09:38:09
305
原创 Json & Jsoncpp
JSON是一种轻量级的数据交换格式,具有简洁易读、跨平台兼容等特点。本文介绍了JSON的基本概念、核心特点及数据结构,并重点讲解了C++中处理JSON的开源库Jsoncpp。Jsoncpp通过Json::Value类作为核心容器,支持JSON数据的解析、生成和操作。文章详细说明了Jsoncpp的序列化(StreamWriter)和反序列化(CharReader)接口的使用方法,并提供了示例代码展示如何实现JSON数据的读写操作。这些内容为C++开发者处理JSON数据提供了实用的技术参考。
2025-08-02 22:18:52
814
原创 【Linux网络】网络编程基础
对于一个基于 TCP 的网络通信过程,用户首先要建立 TCP 连接,连接建立成功后就可以收到来自其他主机的数据,此时就要对数据的格式进行处理,比如对数据进行解密,最后将解密的数据进行业务处理。:就像两个人在电话中说话要使用双方都能听懂的语言,比如中文,并且要遵循一定的语言规范,有正确的语序、词汇用法等,这对应于协议中规定的数据格式和结构。整个打电话的过程就像网络通信中的协议,通过遵循这些类似语法、语义、时序的规则,双方才能顺利沟通,就像网络中的设备通过协议来实现数据的正确传输和理解。
2025-02-23 23:56:54
912
1
原创 【Git】多人协作
目前,我们的仓库中只有一个master主分支,但在实际的项目开发中,在任何情况下其实都是不允许直接在master分支上修改代码的,这是为了保证主分支的稳定。这时,Windows用户已经修养得差不多,可以继续进行自己的开发工作,那么他首先要获取到你帮他开发的内容,然后接着你的代码继续开发。最后不要忘记,虽然我们是在分支上进行多人协作开发,但最终的目的是要将开发后的代码合并到 master上去,让我们的项目运行最新的代码。并且推送各自的分支时,并没有任何冲突,两个用户互不影响,用起来很舒服!
2025-02-23 23:56:19
864
原创 【Git】远程操作
向潜在用户、贡献者等介绍项目的目标、功能、适用场景,以及它所解决的具体问题,突出项目独特之处和为用户带来的好处,让他人快速理解项目核心价值,高质量的概述还能吸引更多人试用项目、在开源社区建立信誉。
2025-02-23 23:55:46
1187
原创 【Linux】Linux线程互斥与同步(接口篇)
在多线程编程里,读写锁是一种特殊的锁机制,它把对共享资源的访问分成读操作和写操作。允许多个线程同时进行读操作,但写操作是独占的,即同一时间只能有一个线程进行写操作,并且写操作进行时不允许其他线程进行读操作。
2025-02-23 23:55:12
1101
原创 【Linux】线程的其他概念(理论篇)
在 C++ 的标准模板库(STL)里,大部分容器并非线程安全的。主要是为了避免在单线程环境中因线程安全机制带来不必要的开销。线程安全机制(像加锁操作)会影响性能,若在所有操作中都默认加入,会让单线程程序变慢。因此,STL 把线程安全的控制权交给了开发者。死锁是指在一组进程中的各个进程均占有不会释放的资源,但因互相申请被其他进程所站用不会释放的资源而处于的一种永久等待状态。智能指针的线程安全特性因类型而异,并且即使某些操作是线程安全的,对其所管理对象的访问通常也需要额外的同步措施。
2025-02-23 23:54:49
846
原创 【Git】分支管理
分支在实际中有什么用呢?假设你准备开发一个新功能,但是需要两周才能完成,第一周你写了50%的代码,如果立刻提交,由于代码还没写完,不完整的代码库会导致别人不能干活了。如果等代码全部写完再一次提交,又存在丢失每天进度的巨大风险。现在有了分支,就不用怕了。你创建了一个属于你自己的分支,别人看不到,还继续在原来的分支上正常工作,而你在自己的分支上干活,想提交就提交,直到开发完毕后,再一次性合并到原来的分支上,这样,既安全,又不影响别人工作。并且Git无论创建、切换和删除分支,Git在1秒钟之内就能完成!
2025-02-20 15:41:51
1121
原创 【Linux】线程概念及控制
线程(Thread)是计算机程序执行的最小单元,是进程(Process)中的一个实体。线程是操作系统调度的基本单位,它与进程共享进程的资源(如内存地址空间、打开的文件描述符等),但可以独立执行任务。一切进程至少都有一个执行线程线程在进程内部运行,本质是在进程地址空间内运行在Linux系统中,在CPU眼中,看到的PCB都要比传统的进程更加轻量化透过进程虚拟地址空间,可以看到进程的大部分资源,将进程资源合理分配给每个执行流,就形成了线程执行流。
2025-02-20 15:41:24
949
原创 【Linux】信号概念
你在网上买了很多件商品,再等待不同商品快递的到来。但即便快递没有到来,你也知道快递来临时,你该怎么处理快递。也就是你能“识别快递”当快递员到了你楼下,你也收到快递到来的通知,但是你正在打游戏,需5min之后才能去取快递。那么在在这5min之内,你并没有下去去取快递,但是你是知道有快递到来了。也就是取快递的行为并不是一定要立即执行,可以理解成“在合适的时候去取”。在收到通知,再到你拿到快递期间,是有一个时间窗口的,在这段时间,你并没有拿到快递,但是你知道有一个快递已经来了。
2025-02-19 12:27:16
841
原创 【Git】初识Git & 基础操作
掌握 Git 企业级应用,深刻理解Git操作过程与操作原理,理解工作区,暂存区,版本库的含义掌握 Git 版本管理,自由进行版本回退、撤销、修改等Git操作方式与背后操作原理掌握 Git 分支管理,从分支创建,切换,合并,删除的整个生命周期,灵活进行各种场景下的分管理,学习常见分支管理策略掌握 Git 远程仓库与本地仓库,结合版本管理与分支管理,做到基于分支级的个人级开发理解分布式版本控制系统,学习远程仓库与本地仓库的交互操作,掌握多人协作开发模式。
2025-02-19 12:26:23
1092
原创 【Linux】进程间通信
进程间通信(Inter - Process Communication,IPC)的目的:数据共享多个进程可能需要访问和处理相同的数据。例如,在一个数据库管理系统中,有一个负责写入数据的进程和多个负责读取数据的进程。它们之间需要进行通信来共享数据库中的记录。通过进程间通信机制,这些进程可以协调对数据的访问,确保数据的一致性和完整性。再比如,在一个多任务的科学计算环境中,不同的进程可能负责计算一个大型数据集的不同部分。当各个部分的计算结果完成后,需要通过进程间通信将这些结果汇总起来,以得到最终的完整结果。
2025-01-24 18:22:47
1094
原创 动静态库的理解
在程序启动时,操作系统的加载器会根据程序中记录的动态库信息,在系统默认的库路径或者通过环境变量指定的路径中查找所需动态库。经过这样的链接过程,静态库中的代码就成为了可执行程序的一部分,使得可执行程序在运行时可以直接调用静态库中的函数和使用其中的变量,而不需要像动态库那样在运行时再去加载库文件。如果动态库和静态库在同一路径下,使用 gcc 命令,默认链接的是动态库,如果要指定使用静态库编译,那么需要在 gcc 后面带。不同的库可能提供不同的功能,通过指定库的名称,编译器可以准确地将程序与所需的库进行链接。
2025-01-23 20:02:36
1178
原创 【Linux】基础IO
在C语言中,如果我们想对一个文件来进行操作,需要以下几个步骤:打开文件对文件进行 IO 操作关闭文件我们知道,文件一般是存放在磁盘中的,我们在电脑上对文件进行访问,都先得打开,文件是通过执行代码的方式完成修改(比如我们使用文本编辑器或WPS等软件来对文件进行修改,但是这些软件也是由一行行代码所编写出来的),所以可以得出一个结论,文件是被进程打开的。而一个进程可以打开多个文件,这也说明了在一定时间段内,系统中存在多个进程也可能同时存在更多的被打开的文件。
2025-01-23 20:00:10
1138
原创 【Linux】进程控制
在操作系统中,进程程序替换(Process Replacement)是指使用一个新的程序替换当前进程的执行代码,而进程的 PID 保持不变。进程程序替换的一个常见场景是,父进程(例如 Shell)创建一个子进程,子进程在创建后立即执行 exec,将自己替换为另一个程序(如执行用户输入的命令)。进程退出码(或称退出状态码)是进程在结束时向操作系统返回的一个整数值,用于表示进程的终止状态。当父进程有多个子进程时,可以使用 waitpid 指定一个特定的子进程,便于控制进程的管理和资源的回收。
2025-01-22 22:06:10
770
原创 【Linux】环境变量
直接赋值即可,比如 VAR=“value”。在 shell 函数中,可以通过 local 关键字来限定变量为函数级别的本地变量。
2025-01-21 22:31:22
1094
原创 【Linux】进程地址空间
进程地址空间是指操作系统为每个进程提供的一个虚拟内存区域。在 Linux 等现代操作系统中,进程的地址空间是独立的,即每个进程有自己独立的地址空间,不会直接与其他进程的地址空间重叠或冲突。这种设计保证了进程之间的隔离性和安全性。进程地址空间的主要组成部分文本段(Text Segment)包含程序的可执行代码,即编译后的指令集。这是只读的,以防止进程修改自身的指令集。多个进程可以共享同一个可执行文件的代码段,比如系统库、公共的程序代码等。数据段(Data Segment)
2025-01-20 20:31:59
855
原创 【Linux】进程概念
进程的概念课本概念:程序的一个执行示例,正在执行的程序等。内核观点:担当分配系统资源(CPU时间,内存)的实体。操作系统是怎么进行进程管理的呢一、先描述进程创建与撤销•创建• 当有新的程序需要运行或者系统进行初始化时,操作系统就开始了进程的创建工作。就像盖房子一样,首先要为这个“进程房子”规划出一块合适的“土地”,也就是分配内存空间。然后,还要为这个进程建立一个详细的“档案”,即初始化进程控制块(PCB)
2025-01-20 20:31:33
1054
原创 【数据结构】哈希
桶的个数是一定的,随着元素的不断插入,每个桶中元素的个数不断增多,极端情况下,可能会导致一个桶中链表节点非常多,会影响的哈希表的性能,因此在一定条件下需要对哈希表进行增容,那该条件怎么确认呢?一种支持删除的方法:将布隆过滤器中的每个比特位扩展成一个小的计数器,插入元素时给k个计数器(k个哈希函数计算出的哈希地址)加一,删除元素时,给k个计数器减一,通过多占用几倍存储空间的代价来增加删除操作。布隆过滤器的思想是将一个元素用多个哈希函数映射到一个位图中,因此被映射到的位置的比特位一定为1。
2024-12-09 09:21:22
967
原创 【算法】模拟
列的话我们并不好确定,所以只能将每列都开跟这个字符串的长度一样,这样就能确保每行都有足够的空间放入字符。后面就将字符串中的每个字符按规定放入矩阵中即可。这四个字符的时候,我们要去看看每一个字符对应的前驱字符,有没有青蛙叫出来。可以证明,在给定的约束条件下,答案总是存在的。这道题如果直接纯模拟的话,时间复杂度和空间复杂度都会比较高,首先我们需要创建一个矩阵,该矩阵的行比较好确定,就是题目给的。在《英雄联盟》的世界中,有一个叫 “提莫” 的英雄。,它表示不同青蛙发出的蛙鸣声(字符串 “croak” )的组合。
2024-12-09 09:20:40
969
原创 【算法】位运算
1. 基础位运算2. 给一个数,确定它的二进制表示中第 x 位是 0 还是 13. 将一个数二进制表示的第 x 位修改成 14. 将一个数二进制表示的第 x 位修改成 05. 提取一个数二进制表示中最右侧的 16. 干掉一个数二进制表示中最右侧的 17. 异或(^)运算符定律191. 位1的个数338. 比特位计数461. 汉明距离136. 只出现一次的数字260. 只出现一次的数字 III在这里就讲解一下260. 只出现一次的数字 III其他的大家看完以上定理都能做。给你一个整数数组。
2024-12-09 09:19:50
765
原创 【算法】前缀和
⼆维前缀和的简单应用题,关键就是我们在填写结果矩阵的时候,要找到原矩阵对应区域的「左上角」以及「右下角」的坐标(推荐大家画图),我在。的时间复杂度内完成该题。因此,我们仅需用一个哈希表,一边求当前位置的前缀和,一边记录第一次出现该前缀和的位置。从中心下标的定义可知,除中心下标的元素外,该元素左边的「前缀和」等于该元素右边的「后缀和」。因此,我们仅需用一个哈希表,一边求当前位置的前缀和,一边存下之前每⼀种前缀和出现的次数。因此,我们仅需用一个哈希表,一边求当前位置的前缀和,边存下之前每一种前缀和出现的次数。
2024-12-09 09:18:07
1064
原创 【C++】智能指针
内存泄漏指因为疏忽或错误造成程序未能释放已经不再使用的内存的情况。内存泄漏并不是指内存在物理上的消失,而是应用程序分配某段内存后,因为设计错误,失去了对该段内存的控制,因而造成了内存的浪费。
2024-12-08 10:37:59
1170
原创 【C++】异常
实际使用中很多公司都会自定义自己的异常体系进行规范的异常管理,因为一个项目中如果大家随意抛异常,那么外层的调用者基本就没办法玩了,所以实际中都会定义一套继承的规范体系。这样大家抛出的都是继承的派生类对象,捕获一个基类就可以了。// 服务器开发中通常使用的异常继承体系public:, _id(id){}protected:int _id;public:{}
2024-12-08 10:37:11
949
原创 【数据结构】二叉搜索树(C++实现)
学习二叉搜索树是为了学习C++容器中map和set做铺垫,通过对二叉搜索树的特性了解,有助于更好的理解map和set的特性,因为map容器是一个模型,而set是一个K(key)模型,它们的实现原理都是一样的。所以,为了减少本文的代码量,我在模拟实现的过程中,会只实现K(key)模型。但两个模型的总体实现代码我会放在最后供大家审阅。在这里给大家解释一下KV模型与KK模型:K模型即只有key作为关键码,结构中只需要存储Key即可,关键码即为需要搜索到的值。给一个单词word,判断该单词是否拼写正确。
2024-12-08 10:31:20
1063
原创 【C++】C++的IO流
在C语言中,如果想要将一个整型变量的数据转化为字符串格式,如何去做?使用itoa()函数使用sprintf()函数但是两个函数在转化时,都得需要先给出保存结果的空间,那空间要给多大呢,就不太好界定,而且转化格式不匹配时,可能还会得到错误的结果甚至程序崩溃。在C++中,可以使用stringstream类对象来避开此问题。**在程序中如果想使用stringstream,必须要包含头文件。和。
2024-10-24 13:07:39
741
原创 【C++】C++的类型转换
这里出现这样的结果,原因是在编译时,编译器进行了一些优化,因为 i 定义时是const属性,所以编译器可能将它的值放到了寄存器中进行缓存,使用该值的时候直接是去到寄存器中去拿的,所以即使i的值被修改了,运行结果依旧是原来的值。在运行时进行类型检查,确保类型转换的合法性。关键字可以告诉编译器不要对别修饰的变量进行这些优化,确保每次读取该变量时都从内存中获取最新的值,而不是使用可能被缓存的旧值。进行向下转型,而实际上基类指针并不指向所需的派生类对象,可能会导致访问非法内存或产生不可预测的结果。
2024-10-24 13:07:14
864
原创 【C++】特殊类的设计
使用设计模式的目的:为了代码可重用性、让代码更容易被他人理解、保证代码可靠性。设计模式使代码编写真正工程化;设计模式是软件工程的基石脉络,如同大厦的结构一样。
2024-10-24 13:06:49
793
原创 【数据结构】红黑树(C++实现)
红黑树,是一种二叉搜索树,但在每个结点上增加一个存储位表示结点的颜色,可以是Red或Black。通过对任何一条从根到叶子的路径上各个结点着色方式的限制,红黑树确保没有一条路径会比其他路径长出俩倍,因而是接近平衡的。每个节点不是红色就是黑色根节点是黑色的如果一个节点是红色的,则它的两个孩子节点必须是黑色的(换句话说,就是没有连续的红色节点)对于每个结点,从该结点到其所有后代叶结点的简单路径上,均 包含相同数目的黑色结点(换句话说,就是每条路径都包含相同数量的黑色节点。
2024-10-13 19:47:33
1408
1
原创 【数据结构】AVL树(C++实现)
二叉搜索树虽可以缩短查找的效率,但如果数据有序或接近有序二叉搜索树将退化为单支树,查找元素相当于在顺序表中搜索元素,效率低下。当向二叉搜索树中插入新结点后,如果能保证每个结点的左右子树高度之差的绝对值不超过1(需要对树中的结点进行调整),即可降低树的高度,从而减少平均搜索长度。它的左右子树都是AVL树左右子树高度之差(简称平衡因子)的绝对值不超过1(-1/0/1)如果一棵二叉搜索树是高度平衡的,它就是AVL树。如果它有n个结点,其高度可保持在Olog2nO(log_2 n)Olog。
2024-10-13 19:43:26
844
原创 【C++】模拟实现list
模拟实现不是为了写得和库里面一样好。而是为了更好的了解底层,从而能够更熟练的使用这些类,同时也能学习大佬们的代码风格。有序性:列表中的元素是按照一定顺序排列的。可变性:可以对列表中的元素进行添加、修改、删除等操作。允许重复元素:列表中可以包含相同的元素。
2024-10-13 19:42:11
675
原创 【C++11】lambda & 包装器 & bind 绑定
在C++98中,如果想要对一个数据集合中的元素进行排序,可以使用std::sort方法。intmain()//默认按照小于比较,排出来结果是升序//如果需要降序,需要改变元素的比较规则return0;//名字//价格//评价{}intmain()vector<Goods>v={{"苹果",2.1,5},{"香蕉",3,4},{"橙子",2.2,3},{"菠萝",1.5,4}};
2024-10-07 23:22:35
1040
原创 【C++11】可变模板参数
中的每个参数的,只能通过展开参数包的方式来获取参数包中的每个参数,这是使用可变模版参数的一个主要特点,也是最大的难点,即如何展开可变模版参数。可变参数模板是 C++11 引入的一种模板特性,允许定义可以接收任意数量参数的模板,广泛应用于函数和类的设计中,以实现灵活和通用的代码结构。,你可以提供构造元素所需的参数,容器会直接在内部空间中构造该对象,避免了先创建对象再将其复制到容器的过程。这样方式获取可变参数,所以我们的用一些奇招来一一获取参数包的值。
2024-10-07 23:21:02
1081
原创 【C++11】右值引用 & 万能引用 & 完美转发
换句话说,左值是可以放在赋值运算符左侧的变量或对象,它们可以存储到内存中,并且有明确的内存地址,可以通过引用来操作。设计这个特性的原因是:移动语义是将右值的资源窃取过来,如果右值引用没有左值属性的话,是无法交换的,因为是左值,所以它的资源才能被改变(交换)。的主要应用场景是在实现泛型函数时,尤其是当一个函数希望将其收到的参数转发给另一个函数,而不改变参数的左值或右值特性时。右值引用,用于绑定右值的引用类型,允许对右值进行修改和资源的移动操作。右值引用的典型用途是实现移动语义,以提高程序效率。
2024-10-05 22:16:20
1267
原创 【C++11】C++11的新语法
在C++98中auto是一个存储类型的说明符,表明变量是局部自动存储类型,但是局部域中定义局部的变量默认就是自动存储类型,所以auto就没什么价值了。这样要求必须进行显示初始化,让编译器将定义对象的类型设置为初始化值的类型。C++11扩大了用大括号括起的列表(初始化列表)的使用范围,使其可用于所有的内置类型和用户自定义的类型,如果我们再细细去看会发现基本每个容器中都增加了一些C++11的方法,但是其实很多都是用得比较少的。一般是作为构造函数的参数,C++11对STL中的不少容器就增加。这样便能成功编译了。
2024-10-05 22:15:50
686
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅