- 博客(66)
- 收藏
- 关注
原创 Linux高级IO流详解
本文详细介绍了Linux中的高级IO流技术,包括非阻塞IO、异步IO、内存映射文件、零拷贝、事件驱动IO和IO多路复用。每种技术都有其独特的应用场景和优点。通过这些高级IO技术,开发者可以编写出高效、响应迅速的应用程序。在实际开发中,选择合适的IO模型和技术对于提高应用程序的性能至关重要。希望本文提供的详细解释和C++代码示例能够帮助读者更好地理解和应用Linux高级IO流。
2024-07-15 20:56:08
618
原创 Linux的线程
在计算机科学和软件工程中,多线程编程是一项关键技能,尤其在当今多核处理器和高并发应用程序的背景下显得尤为重要。本文将全面探讨Linux环境下的线程编程,涵盖基本概念、线程创建与管理、线程同步、性能优化以及实际应用,通过详细的C++示例代码帮助读者深入理解并掌握这一技术。
2024-07-15 16:59:31
387
原创 Linux 多进程编程详解
通过在同一程序中运行多个独立的进程,可以实现并发处理,充分利用多核处理器的优势,提高程序的运行效率。本文将详细介绍Linux多进程的基本概念、创建方法、进程间通信、同步机制以及实际应用,配以C++示例代码,帮助读者深入理解和掌握多进程编程技术。fork()会创建一个子进程,该子进程是父进程的副本,继承了父进程的所有资源和上下文。进程间通信(IPC)是多进程编程中的重要部分,用于在独立的进程之间传递数据和信息。fork()返回两次,一次在父进程中返回子进程的PID,一次在子进程中返回0。
2024-07-15 15:30:44
340
原创 如何在Ubuntu20上离线安装joern(包括sbt和scala)
在Ubuntu 20上离线安装Joern,由于Joern通常需要通过互联网从其官方源或GitHub等地方下载,但在离线环境中,我们需要通过一些额外的步骤来准备和安装。(本人水平有限,希望得到大家的指正)我们首先要做的就是需要安装sbt和scala(前提是得有java的环境,java配置的步骤几乎和这两个相同)
2024-06-30 15:22:42
1003
2
原创 sbt的依赖管理逻辑
我们首先来了解一下依赖项的概念,依赖项(Dependency)通常指的是具体的软件包、库或模块,它是构建或运行一个软件项目所需的外部资源。在某种程度上,依赖项可以看作是依赖关系的实现,因为它们实际上是项目中需要的外部资源。例如:以下是一个简单的Java项目,使用 Maven 来管理依赖项。假设你想要在你的 Java 项目中使用 Google 的 Gson 库,这个库可以帮助你处理 JSON 数据。但是在这之前,你需要创建一个 Maven 项目,然后在 pom.xml 文件中添加 Gson 作为依赖项。
2024-06-07 16:54:17
679
原创 gdb和makefile的讲解
工程是需要被清理的,像clean这种,没有被第一个目标文件直接或间接关联,那么它后面所定义的命令将不会被自动执行,不过,我们可以显示要make执行。一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作。,一般来说,大多数的IDE都有这个命令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。那么make是如何工作的呢?
2024-03-22 15:17:55
931
2
原创 vim编辑器和gcc/g++编辑器的使用讲解
我们的C程序中,并没有定义“printf”的函数实现,且在预编译中包含的“stdio.h”中也只有该函数的声明,而没有定义函数的实现,那么,是在哪里实“printf”函数的呢?静态库是指编译链接时**,把库文件的代码全部加入到可执行文件中,因此生成的文件比较大**,但在运行时也就不再需要库文件了。控制屏幕光标的移动,字符、字或行的删除,移动复制某区段及进入Insert mode下,或者到 last line mode。vim是Linux的编写代码的工具,是一种多模式的编辑器。
2024-03-22 09:38:06
1228
原创 shell的介绍以及Linux权限的讲解
1目录的可执行权限是表示你可否在目录下执行命令。2如果目录没有-x权限,则无法对目录执行任何命令,甚至无法cd 进入目录, 即使目录有-r 读权限(这个地方很容易犯错,认为有读权限就可以进入目录读取目录下的文件)3 而如果目录具有-x权限,但没有-r权限,则用户可以执行命令,可以cd进入目录。但由于没有目录的读权限,所以在目录下,即使可以执行ls命令,但仍然没有权限读出目录下的文档。
2024-03-20 19:40:59
1192
2
原创 Linux的基本指令讲解
cp指令用于复制文件或目录,如同时指定两个以上的文件或目录,且最后的目的地是一个已经存在的目录,则它会把前面指定的所有文件或目录复制到此目录中。其实Linux和windows系统一样,他们的文件系统都是一个多叉树,每个节点到根目录的路径有且仅有一条,磁盘上的文件和目录被组成一棵目录树,每个节点都是目录或文件。,是临时的,不占据磁盘的资源,他起到了传到数据的作用,入口时head,出口就是tail。如果下面创建的message的目录的绝对路径上有目录不存在,那么将先创建不存在的目录。
2024-03-19 19:58:18
1119
原创 Linux的背景介绍
随着 Linux 的不断发展,它也逐渐受到了企业和政府的关注。他们发现了 Linux 的安全性、稳定性和可靠性,并开始将其用于商业和政府应用。现在,Linux 已经成为了一个全球性的操作系统,广泛应用于各种电脑、服务器和移动设备上。它不仅是个人用户的首选,也是企业和政府的主要选Linux 的诞生可以追溯到 1991 年。当时,芬兰的软件工程师 Linus Torvalds 正在寻找一个代替 MINIX(一个小型的 Unix 操作系统)的操作系统。他决定重新编写代码,创建了 Linux。
2024-03-18 21:22:25
1094
2
原创 特殊类设计以及C++中的类型转换
如果单例对象构造十分耗时或者占用很多资源,比如加载插件啊, 初始化网络连接啊,读取文件啊等等,而有可能该对象程序运行时不会用到,那么也要在程序一开始就进行初始化,就会导致程序启动时非常的缓慢。就比如说:如果单例1和单例2同时创建,那么饿汉模式就无法控制顺序了,并且如果当单例对象过大时,main函数前就要申请资源,占用了资源,程序的启动就会变慢。,如果非强制类型转换不可,则应限制强制转换值的作用域,以减少发生错误的机会。
2024-03-13 20:08:08
1145
4
原创 智能指针的讲解
内存泄漏指因为疏忽或错误造成程序未能释放已经不再使用的内存的情况。内存泄漏并不是指内存在物理上的消失,而是应用程序分配某段内存后,因为设计错误,失去了对该段内存的控制,因而造成了内存的浪费。那么内存泄漏对于程序又会有什么样的危害呢?如果说这只是一个小小的代码段,它的影响其实不大,但是如果是在像操作系统这样的程序中发生内存泄漏那危害还是蛮大的长期运行的程序出现内存泄漏,影响很大,如操作系统、后台服务等等,出现内存泄漏会导致响应越来越慢,最终卡死。
2024-03-13 16:22:32
1017
1
原创 异常的讲解
其实异常的规范很多人都不会用的,实际使用中很多公司都会自定义自己的异常体系进行规范的异常管理,因为一个项目中如果大家随意抛异常,那么外层的调用者基本就没办法使用了,所以实际中都会定义一套继承的规范体系。这样大家抛出的都是继承的派生类对象,捕获一个基类就可以了// 服务器开发中通常使用的异常继承体系public:,_id(id){}protected:int _id;
2024-03-12 17:08:11
1123
4
原创 C++11的简单介绍(下)
在C++11之前,涉及到多线程问题,都是和平台相关的,比如windows和linux下各有自己的接口,这使得代码的可移植性比较差。C++11中最重要的特性就是对线程进行支持了,使得C++在并行编程时不需要依赖第三方库,而且在原子操作中还引入了原子类的概念。要使用标准库中的线程,必须包含< thread >头文件。kw=thread线程是操作系统中的一个概念,线程对象可以关联一个线程,用来控制线程以及获取线程的状态。当创建一个线程对象后,没有提供线程函数,该对象实际没有对应任何线程。
2024-03-10 20:32:35
1263
13
原创 C++11的简单介绍(上)
在2003年C++标准委员会曾经提交了一份技术勘误表(简称TC1),使得C++03这个名字已经取代了C++98称为C++11之前的最新C++标准名称。不过由于C++03(TC1)主要是对C++98标准中的漏洞进行修复,语言的核心部分则没有改动,因此人们习惯性的把两个标准合并称为C++98/03标准。从C++0x到C++11,C++标准10年磨一剑,第二个真正意义上的标准珊珊来迟。相比于C++98/03,C++11则带来了数量可观的变化,其中包含了约140个新特性,以及对C++03标准中约600个缺陷的修正。
2024-03-10 17:53:56
897
原创 哈希图的应用
这个题目我们就用一个哈希函数进行切割,将这个100g的log file分成若干个小的文件,然后再对依次对这些小文件进行处理,使用map统计每个小文件里每个ip出现的次数,然后提取出每个map中的出现次数最多的ip,和其他小文件的出现次数最多的比较,选出最大的一个ip。1往做移动j位后取反,就只有第j位为0,其他位置都为1,与上第i个位置,第j个位置无论是0还是1都会置为0,其他位置是0就变为0,是1还是1。如果要删除某个位置,就要将它置零,所以第i个位置的整形与上1往左边移动j位后取反的结果,
2024-03-07 16:20:37
1143
16
原创 哈希的简单介绍
unordered_map是存储<key, value>键值对的关联式容器,其允许通过keys快速的索引到与其对应的value。在unordered_map中,键值通常用于惟一地标识元素,而映射值是一个对象,其内容与此键关联。键和映射值的类型可能不同。在内部,unordered_map没有对<kye, value>按照任何特定的顺序排序, 为了能在常数范围内找到key所对应的value,unordered_map将相同哈希值的键值对放在相同的桶中。
2024-03-05 14:03:36
1380
12
原创 用红黑树封装实现map和set
对红黑树类型中的迭代器类型进行typedef时,可以看到我们在typedef后面加了typename,typename的作用就是告诉编译器后面的东西是一个类型,你先不要编译他,等到模板实例化为真正类型后,你再去取他里面的内嵌类型iterator。,只有模板实例化之后,它里面的内嵌类型我们才可以取到,所以如果你不加typename,有可能取的不是类型,因为静态变量或函数都是可以通过类+域访问符进行访问的,所以如果你要取模板里面的类型,那就必须在模板前面加typename,告诉编译器你取的是类型。
2024-03-05 09:58:00
1005
4
原创 红黑树的简单介绍
根据上面的红黑树的性质和我们之前学习的AVL树的知识的铺垫,我们就可以很快的将红黑树的基本框架搭起来:与AVL树的平衡因子不同,红黑树除了节点外还要枚举节点的颜色我们将黑色和红色先进行枚举// 红黑树节点的定义{}// 节点的左孩子// 节点的右孩子// 节点的双亲(红黑树需要旋转,为了实现简单给出该字段)// 节点的值域// 节点的颜色大家可以看到我们在节点的颜色的初始化时的时候给了缺省参数是红色,这是为什么呢?大家可以想一想,
2024-03-04 20:23:39
951
46
原创 AVL 树
AVL树是一种特殊的二叉搜索树,它具有高度的平衡,所以为了在插入过程中的各个节点的平衡因子的更新,我们在定义AVL树的节点结构的同时要带上一个节点的双亲结点parent{}// 该节点的左孩子// 该节点的右孩子// 该节点的双亲T _data;int _bf;// 该节点的平衡因子。
2024-03-01 19:25:26
1035
18
原创 map和set的简单介绍
map是关联容器,它按照特定的次序(按照key来比较)存储由键值key和值value组合而成的元素。在map中,键值key通常用于排序和惟一地标识元素,而值value中存储与此键值key关联的内容。键值key和值value的类型可能不同,并且在map的内部,key与value通过成员类型value_type绑定在一起,为其取别名称为pair:在内部,map中的元素总是按照键值key进行比较排序的。
2024-02-29 16:19:09
1379
7
原创 二叉搜索树在线OJ题讲解
本题是根据前序和中序来构造二叉树,我们知道前序的第一个节点就是二叉树的根节点,而中序中根节点左边的就是左子树,右边为右子树,然后再遍历前序第二个节点,再次带入中序,前序的“根节点”能够将中序分为两个区间,分为区间后我们再递归两个区间。如果root的左孩子节点或者root的右孩子节点不为空的话,就要把root的左孩子节点的val用括号括起来,就算左孩子为空这个括号也不能省略。就比如节点2他的右孩子节点是空的,所以那个括号就要省略,4和3的两个括号都省略,就可以得到最后的结果了。
2024-02-28 22:00:53
1121
5
原创 二叉树进阶之二叉搜索树
当删除节点既有左孩子又有右孩子的时候我们面对的问题就是他被删除后他的两个孩子节点怎么办,这个时候我们就有两种解决的办法,一个是找一个左子树的最大节点,另一种办法就是找右子树的最小节点来替代这个被删除的节点的值,这种情况不同于上面两种情况,我们叫做替代删除。其实插入的节点到最终都是一个叶子节点,所以二叉搜索树的插入还是很简单的,就比如我要插入0和16,最终都是成为这棵树的新的叶子节点。下图中打x叉的就不是二叉搜索树,因为第三层的5小于他的父节点10,打勾的就是二叉搜索树,它满足了二叉搜索树的所有条件。
2024-02-27 20:36:53
939
8
原创 多态的讲解
多态是在不同继承关系的类对象,去调用同一函数,产生了不同的行为。比如Student继承了Person。Person对象买票全价,Student对象买票半价。必须通过基类的指针或者引用调用虚函数被调用的函数必须是虚函数,且派生类必须对基类的虚函数进行重写如果是对象直接调用的话就不会构成多态,上图中的虚函数覆盖就是我们所说的虚函数重写,其实覆盖是底层实现上的理解,而重写是语义上的理解,我们在后面也会对其讲解注意:重载是函数名相同参数不同。
2024-02-26 20:32:52
846
24
原创 C++中的继承
继承(inheritance)机制是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特性的基础上进行扩展,增加功能,这样产生新的类,称派生类。继承呈现了面向对象程序设计的层次结构,体现了由简单到复杂的认知过程。以前我们接触的复用都是函数复用,继承是类设计层次的复用。
2024-02-04 17:57:40
1361
25
原创 模板讲解之进阶
一个程序(项目)由若干个源文件共同实现,而每个源文件单独编译生成目标文件,最后将所有目标文件链接起来形成单一的可执行文件的过程称为分离编译模式。【优点】模板复用了代码,节省资源,更快的迭代开发,C++的标准模板库(STL)因此而产生增强了代码的灵活性【缺陷】模板会导致代码膨胀问题,也会导致编译时间变长出现模板编译错误时,错误信息非常凌乱,不易定位错误。
2024-02-02 16:08:07
1281
15
原创 stack和queue及优先级队列和适配器(包括deque)的介绍
stack是一种容器适配器,专门用在具有后进先出操作的上下文环境中,其删除只能从容器的一端进行元素的插入与提取操作。stack是作为容器适配器被实现的,容器适配器即是对特定类封装作为其底层的容器,并提供一组特定的成员函数来访问其元素,将特定类作为其底层的,元素特定容器的尾部(即栈顶)被压入和弹出。stack的底层容器可以是任何标准的容器类模板或者一些其他特定的容器类,这些容器类应该支持以下操作:empty:判空操作back:获取尾部元素操作push_back:尾部插入元素操作。
2024-02-02 12:38:01
1352
31
原创 list的介绍及其模拟实现
list是可以在常数范围内在任意位置进行插入和删除的序列式容器,并且该容器可以前后双向迭代。list的底层是双向链表结构,双向链表中每个元素存储在互不相关的独立节点中,在节点中通过指针指向其前一个元素和后一个元素。list与forward_list非常相似:最主要的不同在于forward_list是单链表,只能朝前迭代,已让其更简单高效。与其他的序列式容器相比(array,vector,deque),list通常在任意位置进行插入、移除元素的执行效率更好。
2024-01-25 20:56:05
1355
29
原创 vector的模拟实现
上一篇我们对vector一些常用的函数进行了讲解,本篇博客我们就对vector进行模拟实现,以便于我们更好地了解vector的使用以及对一些常见bug的认识有了string类的模拟实现,vector的模拟实现我们上手起来就简单一点了:首先为了和库里面的vector混淆视听,放入自己命名的空间里,并且根据vector的源码分析我们得出了三个成员变量:分别是:其实他们实质上都是指针,位置大概是这样的,遵循左闭右开的规则这样一个简单的框架就构造出来了:template是模板初阶我们学习过的,里面的T
2024-01-22 18:09:04
1181
19
原创 vector讲解
vector是表示可变大小数组的序列容器。就像数组一样,vector也采用的连续存储空间来存储元素。也就是意味着可以采用下标对vector的元素进行访问,和数组一样高效。但是又不像数组,它的大小是可以动态改变的,而且它的大小会被容器自动处理。本质讲,vector使用动态分配数组来存储它的元素。当新元素插入时候,这个数组需要被重新分配大小为了增加存储空间。其做法是,分配一个新的数组,然后将全部元素移到这个数组。
2024-01-21 10:05:43
1212
38
原创 string类的模拟实现
上一篇博客我们对string类函数进行了讲解,今天我们就对string类进行模拟实现,以便于大家更加深入地了解string类函数的应用然后就是我们将string类的类的成员进行定义:string类实际就是字符串,它的几个成员有capacity(容量),size(字符拆串当前字符个数),str(字符串的指针)
2024-01-20 09:39:30
1162
30
原创 string类的函数讲解
至于容量为什么是15,这就是底层实现的原因了,一些编译器是基于1.5倍的扩容,比如我们的vscode,而linux的终端里是以2倍的扩容,其实不必太过于纠结这一点,我们只需要了解到这一点即可。这里要引出的是 reverse_iterator 其实这里的rbegin已经不在字符串的第一个位置了二者是有区别的,并且,这里的指针也是++,不然怎么会叫做反向迭代器呢?我们这里的size和lenth的作用是一样的,只是在后期的语言发展中为了适应需要,例如,如果是一个二叉树,用lenth合适吗,所以就引出了size。
2023-12-26 19:36:42
1663
51
原创 C++内存管理和模板初阶
new的原理调用operator new函数申请空间在申请的空间上执行构造函数,完成对象的构造delete的原理在空间上执行析构函数,完成对象中资源的清理工作调用operator delete函数释放对象的空间new T[N]的原理调用operator new[]函数,在operator new[]中实际调用operator new函数完成N个对象空间的申请在申请的空间上执行N次构造函数delete[]的原理在释放的对象空间上执行N次析构函数,完成N个对象中资源的清理。
2023-12-23 18:16:24
1822
23
原创 类和对象(下篇)
在之前的学习中我们知道,在创建一个对象时,我们的编译器就会自动调用构造函数将对象初始化,给对象中各个成员变量一个合适的初始值。例如:虽然上述构造函数调用之后,对象中已经有了一个初始值,但是不能将其称为对对象中成员变量的初始化,构造函数体中的语句只能将其称为赋初值,而不能称作初始化。因为初始化只能初始化一次,而构造函数体内可以多次赋值。所以C++就引入了初始化列表的概念:初始化列表的形式如下:以一个冒号开始,接着是一个以逗号分隔的数据成员列表,每个"成员变量"后面跟一个放在括号中的初始值或表达式。废
2023-12-22 18:52:10
2876
45
原创 类和对象(中篇)
4. 编译器生成的默认拷贝构造函数已经可以完成字节序的值拷贝了,还需要自己显式实现吗?当然像日期类这样的类是没必要的。那么下面的类呢?验证一下试试?请看代码:
2023-12-20 20:39:05
2828
45
原创 类和对象(上篇)
类的形式如下:这里的 classname 就是你要定义的类名class 就是定义类的关键字{}里面就是类的主题部分// 类体:由成员函数和成员变量组成// 一定要注意后面的分号类体中内容称为类的成员;类中的变量称为类的属性或成员变量;类中的函数称为类的方法或者成员函数。声明和定义全部放在类体中,需注意:成员函数如果在类中定义,编译器可能会将其当成内联函数处理。其实咱们可以尽量地使用第二种成员变量命名规则的建议:首先我们放上一段代码这里的形参和成员变量都长一样,就会有点僵硬。
2023-12-18 19:50:07
1683
52
原创 C++入门
我们来看一下命名空间的定义:定义命名空间,需要使用到namespace关键字,后面跟命名空间的名字,然后接一对{}即可,{}中即为命名空间的成员。例如:这里的myspace就是咱们自己定义的命名空间,里面的rand就可以正常使用了// 命名空间中可以定义变量/函数/类型int val;这里注意:命名空间可以嵌套使用:我们在命名空间N1中嵌套了N2int a;int b;int c;int d;
2023-12-10 21:59:08
723
60
原创 几种排序的实现
当a[end]大于此前i下标的元素的值时,将其调整,将end位置的值移动到end后面一个位置,同时end–,如果是小于的,那就直接跳出循环,就代表了前面的所有值都是升序的。就是,第一次摸牌我们把它放在第一张,第二次就和第一张比较,比它大就放在他的后面,否则就放在他的前面,摸第三张的时候先和后面大的一张牌开始比较,依次向前。我们将小于中间位置的值的放在左边,大于的放在右边,然后再对左边进行一样的划分,右边也是,用递归实现即可。我们将第二个元素开始向后遍历,i=1,令end=i-1,并且保存a[i]的值。
2023-12-09 17:31:00
601
42
原创 二叉树在线OJ
然后递归newnode的左子树根节点,*(count)++(count传的是地址,所以记得解引用),随后递归右子树根节点即可,最后返回newnode,就是二叉树的根节点。当两个子树都不为空时判断两个子树的根节点是否相等,不相等直接返回false,然后递归左子树和右子树的根节点。当数组的首元素为#或者“\0”,即二叉树没有根节点,为空树,直接接返回。当左子树的根节点和右子树的根节点不相等时只返回false。左子树和右子树相同,左子树的左子树后右子树的右子树相同。同时左子树的子树和右子树的子树也要同时递归。
2023-12-03 16:49:15
797
52
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人