自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 Linux管道——进程间通信(匿名管道、命名管道)

为了让每个进程都能通过这个地址进入通信的大门,假设他对应的文件名是a,进程1打开a的时候,拿到一个fd,file,inode,操作系统判断这个文件类型,知道是命名管道文件,会给他分配一块内存,这时候你操作这个文件的时候,数据是写到内存里的,同理,这时候进程2也打开这个文件,也拿到一个fd,file,inode。不同的进程,要用同一个匿名管道进行通信,则需要进程拥有该管道的读写两端的文件描述符,所以匿名管道只让能具有亲缘关系的进程进行进程间通信,且父进程需要先创建匿名管道,再创建子进程。

2023-01-08 09:41:35 1441 1

原创 高并发内存池项目

​ 本项目是实现一个高并发的内存池,它的原型是Google的一个开源项目tcmalloc,tcmalloc全称Thread-Caching Malloc,即线程缓存的malloc,实现了高效的多线程内存管理,用于替代系统的内存分配相关的函数(malloc、free)。​ 本项目是模拟tcmalloc最核心的简化框架,实现一个简易的高并发内存池,目的是学习tcmalloc的精华,与博主先前模拟实现STL库来学习STL容器的方式类似。​ 这个项目会用到C/C++、数据结构(链表、哈希桶)、操作系统内存管理

2023-01-08 09:31:44 1255 2

原创 Linux制作和使用动静态库

静态库与动态库本质都是一堆目标文件(xxx.o)的集合,库的文件当中并不包含主函数而只是包含了大量的方法以供调用。将程序编写成库提供给第三方使用,这样做的好处是不会造成源码泄漏,而且调用者不用关心内部实现。

2022-12-28 14:53:17 577

原创 Linux文件操作(基础IO)

在C、C++、Python等语言中存在对文件操作的接口,通过这些接口我们可以创建文件,并实现文件内容的写入和读取,本文将介绍Linux下我们是如何进行文件操作的,并且深入底层的解析文件操作的原理。

2022-12-27 09:08:17 852

原创 【Linux】进程控制(进程创建、进程终止、进程等待、进程替换)

如果子进程已经退出,调用 wait / waitpid 时,wait / waitpid 会立即返回,并且释放资源,获得子进程退出信息。如果在任意时刻调用 wait / waitpid,子进程存在且正常运行,则进程可能阻塞。如果不存在该子进程,则立即出错返回。我们创建子进程的目的:if else 让子进程指向父进程代码的一部分!如何让子进程执行一个全新的程序?进程不变,仅仅替换当前进程的 代码 和 数据 的技术叫做进程的程序替换思考什么是进程替换?

2022-12-25 08:56:26 1681 1

原创 C++(第十六篇):红黑树 - Red Black Tree(介绍、模拟实现插入)

红黑树,是一种平衡二叉搜索树,但在每个结点上增加一个存储位表示结点的颜色,可以是 Red 或 Black。通过对任何一条从根到叶子的路径上各个结点着色方式的限制,红黑树确保没有一条路径会比其他路径长出2倍(最长路径最多是最短路径的2倍),因而是接近平衡的。

2022-12-24 09:50:36 278 1

原创 C++(第十五篇):AVLTree - 平衡二叉搜索树(介绍、实现)

二叉搜索树的插入和删除操作都必须先查找,查找效率代表了二叉搜索树中各个操作的效率。但是二叉搜索树有其自身的缺陷,假如往树中插入的元素有序或者接近有序,二叉搜索树就会退化成单支树,时间复杂度为O(N),因此 map、set 等关联式容器的底层结构是对二叉树进行了平衡处理,即采用平衡二叉搜索树来实现。最优情况下,有 n 个结点的二叉搜索树为完全二叉树,查找效率为:O(log2Nlog_2Nlog2​N)最差情况下,有 n 个结点的二叉搜索树退化为单支树,查找效率为:O(N)

2022-12-21 09:20:45 281 1

原创 C++(第十四篇):set和map(介绍、应用、pair)

序列式容器,比如:vector、list、deque、forward_list(C++11)等,其底层为线性序列的数据结构,里面存储的是元素本身。那什么是关联式容器?它与序列式容器有什么区别?关联式容器也是用来存储数据的,与序列式容器不同的是,其里面存储的是 结构的键值对,在数据检索时比序列式容器效率更高。根据应用场景的不同,STL总共实现了两种不同结构的关联式容器:「树型结构」与「哈希结构」。

2022-12-20 10:26:28 493 2

原创 C++(第十三篇):二叉搜索树(二叉树进阶、二叉搜索树的结构、应用及模拟实现)

普通的二叉树单纯用来存储数据意义不大,不如用数组和链表。普通数组和链表,面对一些需要频繁查找、插入、删除的场景,也很麻烦。普通数组/链表:暴力查找,O(N)排序数组:二分查找,O(log2N)所以这里引入了[二叉搜索树]。二叉搜索树的查找,根据「二叉搜索树性质」来找某节点二叉搜索树的插入,先根据「二叉搜索树性质」来查找适合插入的空位置,必须要保存新节点的父节点,并判断新节点是左孩子还是右孩子,然后再插入新节点。(不允许冗余)二叉搜索树的删除,先根据「二叉搜索树性质」来查找。

2022-12-16 09:36:39 395 1

原创 C++(第十二篇):多态(虚函数、抽象类、虚函数表、虚表指针、多继承下的多态)

多态是在继承关系中不同的类对象,去调用同一函数,产生了不同的行为。比如 Student 继承了 Person。Person 对象买票全价,Student 对象买票半价。在继承中要构成多态构成多态的函数必须是虚函数,且派生类必须对基类的虚函数进行重写(覆盖)。必须通过基类的指针或者引用调用虚函数,通过父类的对象调用只会调用父类成员,不会构成多态。满足上述条件后,基类的指针指向基类对象则调用基类的虚函数,指向派生类对象则调用派生类的虚函数。构成多态,指向谁就调用谁的虚函数,跟对象有关。

2022-12-15 08:55:29 740 2

原创 C++(第十一篇):继承(基类与派生类、菱形继承和菱形虚拟继承问题)

面向对象程序设计中最重要的一个概念是继承。继承允许我们依据另一个类来定义一个类,这使得创建和维护一个应用程序变得更容易。这样做,也达到了重用代码功能和提高执行效率的效果。当创建一个类时,不需要重新编写新的数据成员和成员函数,只需指定新建的类去继承一个已有的类即可。这个已有的类称为基类(父类),新建的类称为派生类(子类)。很多人说 C++ 语法复杂,其实多继承就是一个体现。有了多继承,就存在菱形继承,有了菱形继承就有菱形虚拟继承,底层实现就很复杂。所以一般不建议设计出菱形继承。否则在复杂度及性能上都有问题。

2022-12-11 09:48:43 1203

原创 Linux进程地址空间(虚拟地址和物理地址的映射、页表)

在学习 C/C++ 的时候,我们知道内存会分为几个区域:栈区、堆区、全局/静态区、代码区、字符常量区 …这只是语言层面的理解,是远远不够的,如下空间布局图,请问这是物理内存吗?—— 不是,是进程地址空间。两点结论:进程地址空间不是物理内存!进程地址空间,会在进程的整个 [生命周期] 内一直存在,直到进程退出!这也就解释了为什么全局/静态变量的生命周期是整个程序,因为全局/静态变量是随着进程一直存在的。验证地址空间的基本排布?进程地址空间究竟是什么?地址空间和物理内存之间的关系?

2022-10-17 20:37:53 2141

原创 Linux环境变量和命令行参数

命令行参数可以让同一个命令,通过带上不同的选项,表现出不同的功能和作用。这就是命令行参数的意义。我们平常在 VS 中写代码,都知道程序是从 main 函数开始执行,那是谁调用的 main 函数呢?编程者写的 main 函数被函数调用的,这个函数定义在 VS 安装目录的某个 .c 文件中(VS 的版本不同,存放的位置也不同),它会执行一些初始化操作,如从内核中获取命令行参数和环境变量值、初始化全局变量、初始化 IO 等等所需各项准备之后,为调用函数做好了准备。(⭐)

2022-10-16 18:52:48 1226 4

原创 C++(第十篇):容器适配器、优先级队列和仿函数(stack、queue、priority_queue、dequeue)

stack 是一种「容器适配器」,专门用在具有 LIFO (后进先出) 操作的上下文环境中,其中元素仅从容器的一端插入和提取。队列是一种「容器适配器」(container adapter),专门用于在 FIFO (先进先出) 操作的上下文环境中,其中从容器一端插入元素,另一端提取元素。

2022-10-13 19:27:03 468

原创 Linux进程概念(冯诺依曼体系结构、操作系统、进程的状态)

这里的存储器指的是内存。不考虑缓存情况,CPU 能且只能对内存进行读写,不能访问外设(输入或输出设备)。冯诺依曼规定了硬件层面上的数据的流向。在数据层面上,CPU 不和外设打交道,外设只和存储器打交道(可以将存储器理解为是 CPU 和所有外设的缓存)。(而在硬件层面上,外设是可以直接给 CPU 发中断)外设要输入或输出数据只能写入内存或从内存中读出。补充:CPU和寄存器、高速缓存,以及主存之间的关系。

2022-10-12 20:14:49 464

原创 【Linux】Linux 基础开发工具(yum、vim、gcc/g++、gdb、make/makefile、git)

yum的使用,介绍使用vim的三种模式和命令,如何在linux下进行代码调试

2022-10-11 14:30:32 2011

原创 C++(第九篇):list容器(介绍、使用、模拟实现、迭代器相关问题讲解、list和vector的对比)

list是序列式容器,可以在序列中的任意位置进行常数时间 O(1) 的插入和删除操作,以及双向迭代。list的底层是「带头双向循环链表」结构,双向链表中每个元素存储在不同且不相关的独立节点中,在节点中通过指针指向其前一个元素和后一个元素。list与非常相似:主要区别在于是单链表,因此只能向前迭代,让其更简单高效。与其他的序列式容器相比 (array,vector,deque),list 在容器内任意位置进行插入、删除、移动元素方面的执行效率通常表现更好。

2022-10-07 21:21:25 438 3

原创 【Linux】vim常用命令(多行注释、字符替换,命令模式、底行模式常用命令)

vi / vim 的区别简单点来说,它们都是多模式编辑器,不同的是 vim 是 vi 的升级版本,它不仅兼容 vi 的所有指令,而且还有一些新的特性在里面。如果上一次编辑时异常退出了,就会产生这样的警告,这是因为异常退出导致.swp文件没有删除,当进入vim时遇到这样的警告,按"d"将.swp文件删除即可。首先将光标移动至要进行替换的行,按":“进入底行模式,键入s/,后面跟要被替换的字符,再键入”/“,后面跟替换后的字符,最后面再跟一个”/"。因为它是所有 Linux 环境下自带的。

2022-10-03 00:04:42 6800 1

原创 【Linux】Shell运行原理及Linux权限

目录的可执行权限是表示你是否可以进入目录。如果目录没有 -x 权限,则无法对目录执行任何命令,甚至无法 cd 进入目录,即使目录仍然有 -r 读权限(这个地方很容易犯错,认为有读权限就可以进入目录读取目录下的文件)(想要读和写目录里的文件,首先得有进入目录的权限)(比如要去银行仓库取钱,你得先有进入银行仓库的权限)而如果目录具有 -x 权限,但没有 -r 权限,则用户可以执行命令,可以 cd 进入目录。但由于没有目录的读权限,所以在目录下,即使可以执行 ls 命令,但仍然没有权限读出目录下的文档。

2022-10-02 11:08:42 586 1

原创 【Linux】Linux的基本指令(Linux入门、用户的创建和切换)

Linux是一款企业级后台操作系统,命令行方式交互,开源。搭建自己得Linux服务器:博主是直接买的腾讯云轻量级服务器,CentOS7.6。

2022-09-30 12:24:28 1968 1

原创 C++(第八篇):vector类容器(介绍、使用、模拟实现及迭代器失效问题)

vector 是表示可变大小数组的序列容器。就像数组一样,vector 也采用的连续存储空间来存储元素。也就是意味着可以采用下标对 vector 的元素进行访问,和数组一样高效。但是又不像数组,它的大小是可以动态改变的,而且它的大小会被容器自动处理。本质讲,vector 使用动态分配数组来存储它的元素。当新元素插入时候,这个数组需要被重新分配大小为了增加存储空间。其做法是,分配一个新的数组,然后将全部元素移到这个数组。...

2022-08-15 17:10:21 1040 5

原创 C++(第七篇):string 容器(介绍、使用、深浅拷贝、模拟实现、写时拷贝)

前言​ 在C语言中,字符串是以’\0’结尾的一些字符的集合。为了操作方便,C语言中还提供了一些控制字符串的函数例如strcpy,strcmp,strcat等等。但是这些函数与字符串是分离开的,并不符合C++封装的特性。于是C++中由单独产生了一个string类。...

2022-08-14 09:28:07 863 3

原创 【C++】string类练习题(字符串相乘、替换空格、把字符串转换成整数、字符串相加、反转字符串、字符串中的第一个唯一字符、字符串最后一个单词的长度、验证回文串、反转字符串中的单词)

字符串最后一个单词的长度_牛客题霸_牛客网 (nowcoder.com)描述计算字符串最后一个单词的长度,单词以空格隔开,字符串长度小于5000。(注:字符串末尾不以空格为结尾)输入一行,代表要计算的字符串,非空,长度小于5000。输出一个整数,表示输入字符串最后一个单词的长度。示例1输入:hello nowcoder输出:8说明:最后一个单词为nowcoder,长度为8string a;}......

2022-08-13 20:09:31 1877 1

原创 C++(第六篇):模板详解(函数模板、类模板、非类型模板参数、模板特化、模板分离编译问题及一些题目)

模板是C++支持参数化多态的工具,使用模板可以使用户为类或者函数声明一种一般模式,使得类中的某些数据成员或者成员函数的参数、返回值取得任意类型。使用模板的目的就是能够让程序员编写与类型无关的代码。比如编写了一个交换两个整型int 类型的swap函数,这个函数就只能实现int 型,对double,字符这些类型无法实现,要实现这些类型的交换就要重新编写另一个swap函数。使用模板的目的就是要让这程序的实现与类型无关,比如一个swap模板函数,即可以实现int 型,又可以实现double型的交换。...

2022-08-08 16:39:49 2020 4

原创 C++(第五篇):动态内存管理(C/C++内存分布、new / delete的使用及其底层原理、operator new / operator delete函数、内存泄漏)

一. C/C++内存分布二. C语言中动态内存管理方式2.1 malloc/calloc/realloc和free三. C++动态内存管理3.1 概念3.2 new和delete操作自定义类型四. operator new与operator delete函数4.1 概念4.2 operator new与operator delete的类专属重载(了解)五. new和delete的实现原理(🌟)5.1 内置类型5.2 自定义类型六. 定位new表达式(placement-new)..

2022-08-04 16:32:21 1618 14

原创 【C语言】详解栈和队列(定义、销毁、数据的操作)

栈:是一种特殊的线性表,其**只允许在表尾进行插入和删除元素操作**。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。

2022-08-04 16:04:44 1771 3

原创 C++(第四篇):C++的类和对象(下 —— 再谈构造函数、static成员、成员初始化、友元、内部类)

我们可以认为,初始化列表位置才是真正的,对成员变量进行初始化(定义)的地方,构造函数体中只是对成员变量进行赋值 =,不是初始化(定义),构造函数体执行完,对象就创建成功了。初始化较函数体赋值是更正规的初始化成员变量,当对象创建(定义)时,便是成员变量定义的时候,有些成员变量必须在定义的时候进行初始化,而这就是初始化列表的价值。构造函数的初始化列表可以认为是成员变量定义初始化的地方。使用:以一个冒号开始,接着是一个以逗号分隔的数据成员列表,每个"成员变量"后面跟一个放在括号中的初始值或表达式【注意】这些成员

2022-08-02 15:58:35 2038 4

原创 【C语言】带头双向循环链表(list)详解(定义、增、删、查、改)

带头双向循环链表,有一个数据域和两个指针域,一个是前驱指针,指向其前一个节点;一个是后继指针,指向其后一个节点//定义双向链表的节点typedefintDLTDateType;//定义数据类型typedefstructDLT_Node{...

2022-08-02 15:31:32 3327

原创 C++(第三篇):C++的类和对象(中 —— 万字详解:六个默认成员函数,编译器的优化问题,日期类的实现)

默认成员函数功能常用写法编译器默认生成的构造函数完成成员变量的初始化对内置类型(基本类型)成员变量不处理,对自定义类型成员变量会去调用它的默认构造函数(不用传参的构造函数)进行初始化。析构函数完成成员变量的资源清理(delete、free)~Date()对内置类型成员不处理,因为没有资源需要清理。对自定义类型成员,会调用它的析构函数拷贝构造函数同类对象定义时的初始化Date(constDate&d),参数是本类类型对象按内存存储按字节序完成浅拷贝,对内置类型会完成浅拷贝,而。......

2022-08-01 09:13:17 1798

原创 【C语言】链表详解(无头单向非循环)

学习链表之前,先让我们来思考一个问题为什么有了顺序表,还需要有链表这样的数据结构呢?顺序表存在的一些问题顺序表在中间/头部的插入删除,要挪动很多数据,时间复杂度为O(N),效率太低了。增容需要申请新空间,拷贝数据,释放旧空间。会有不小的消耗。增容一般是一次增长2倍,势必会有一定的空间浪费。例如当前容量为100,满了以后增容到200,我们再继续插入了5个数据,后面没有数据插入了,那么就浪费了95个数据空间。为了更好的解决上述问题,引入了链表。...

2022-07-29 16:03:45 1881 6

原创 C++(第二篇):C++的类和对象(上)

本文内容一. 面向过程和面向对象初步认识二. 类的引入三. 类的定义四. 类的访问限定符及封装访问限定符封装五. 类的作用域六. 类的实例化七. 类对象模型类对象的大小计算结构体内存对齐规则八. this指针this指针的特性...

2022-07-29 14:48:17 1672 4

原创 C++(第一篇):C++基础入门知识(函数重载、引用、内联函数...)

定义命名空间,需要使用到namespace关键字,后面跟命名空间的名字,然后**接一对{}**即可,{}中即为命名空间的成员。namespace关键字定义的是一个域,用来解决C语言命名冲突的问题。//1.普通的命名空间namespaceN1//N1为命名空间的名称//命名空间中的内容,既可以定义变量,也可以定义函数inta;{}//2.命名空间可以嵌套{inta;intb;{intC;intd;}}注。...

2022-07-29 14:32:36 1780

原创 【C语言】详解顺序表(SeqList)

线性表(linearlist)是n个具有相同特性的数据元素的有限序列。顺序表、链表、栈、队列、字符串…线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物理上存储时,通常以数组和链式结构的形式存储。顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。可动态增长的数组,要求数据是连续存储的缺陷给小了不够用,给大了可能浪费,非常不实用//定长数组intsize;200。...............

2022-07-27 15:01:13 3410 5

原创 剑指Offer 07 重建二叉树 -- 从中序与后序遍历序列构造二叉树

输入某二叉树的前序遍历和中序遍历的结果,请构建该二叉树并返回其根节点。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。首先要知道遍历后的数组都有什么样的特点根据上面的理论知识可以清楚本题的解题策略,就是以前序数组的第一个元素【根节点】为切割点,先切中序数组,根据中序数组,反过来在切前序数组。一层一层切下去,每次前序数组的第一个元素就是节点元素。前序遍历的第一个元素就是他的头节点。知道了头节点,我们可以在中序遍历中找到头节点的位置index。通过index。root->left。同理。...

2022-07-27 08:57:46 1517

原创 【C语言】程序环境和预处理

本文的主要内容是对我们在写完代码之后,编译执行过程的详细说明。因此也会引出在编译之前进行的处理 —— 预处理命令的说明。

2022-07-19 12:12:48 3090 3

原创 【C语言】文件的处理与操作

文件是当今计算机系统不可或缺的部分。文件用于储存程序、文档、数据、书信、表格、图形、照片、视频和许多其他种类的信息。作为程序员,必须会编写创建文件和从文件读写数据的程序。文件(file)通常是在磁盘或固态硬盘上的一段已命名的存储区。对我们而言,stdio.h就是一个文件的名称,该文件中包含一些有用的信息。然而,对操作系统而言,文件更复杂一些。例如,大型文件会被分开储存,或者包含一些额外的数据,方便操作系统确定文件的种类。程序文件数据文件文件名一个文件要有一个唯一的文件标识,以便用户识别和引用。...

2022-07-18 15:05:58 4491

原创 【C语言】动态内存管理(malloc、calloc、realloc,柔性数组)

我们已经掌握的内存开辟方式有:但是上述的开辟空间的方式有两个特点:空间开辟大小是固定的。数组在申明的时候,必须指定数组的长度,它所需要的内存在编译时分配。但是对于空间的需求,不仅仅是上述的情况。有时候我们需要的空间大小在程序运行的时候才能知道,那数组的编译时开辟空间的方式就不能满足了。也就是说当我们在定义变量时并不知道会使用多少的内存,这时候就需要进行动态内存开辟!上述两种开辟内存方法一个在栈上开辟,一个在堆上开辟。在C语言或内置的库中有能够进行动态内存开辟的库函数。参数表示需要开辟的内存的字节数。

2022-07-13 18:30:39 3773 5

原创 【C语言】自定义类型的介绍(结构体,枚举,联合体,位段)

在C语言当中,除了我们常用的几个基本的数据类型之外,还有一种类型叫自定义类型。比如:我们要描述一个学生。这个学生有姓名,性别,年龄,身高等。单独用基本的数据类型是不能完全描述的。这个时候就要使用我们自定义的类型来进行描述。自定义的类型有结构体,枚举和联合体。C语言 数组允许定义可存储相同类型数据项的变量,结构是C语言编程中另一种用户自定义的可用的数据类型,它允许存储不同类型的数据项。结构体是一些值的集合,这些值被称为成员变量,每一个成员变量可以有不同的类型。结构体的声明与定义其中是自定义结构体类型,..

2022-07-12 15:18:49 3356 3

原创 【C语言】字符串和内存函数介绍及模拟实现

本文内容:strlen,strcpy,strncpy,strcat,strncat,strcmp,strncmp,strstr,strtok,strerror,memcpy,memmove,memcmp

2022-07-07 22:12:03 3434 9

原创 【C语言】八种排序(希尔排序、堆排序、快速排序、归并、计数排序....)

本文内容:递归实现快速排序和迭代实现快速排序,递归实现和迭代实现归并排序,冒泡排序,插入排序,希尔排序,选择排序,堆排序,计数排序

2022-06-25 16:32:55 3866 5

机器学习与数据挖掘的实验报告,包含多种模型分析实验代码和数据分析结果

机器学习与数据挖掘的实验报告,包含逻辑回归分析、贝叶斯分类器模型,决策树和随即森林在心脏病数据分析中的应用。包括实验代码和结果分析。

2023-01-12

高并发内存池项目原始代码,开源项目

高并发内存池,模仿tcmalloc的最核心的框架。包含基数树优化等内容。

2023-01-12

空空如也

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

TA关注的人

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