自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 C++中重载和重写的区别

其函数名,参数列表,返回值类型,所有都必须同基类中被重写的函数一致。是指同一可访问区内被声明的几个具有不同参数列(参数的类型,个数,顺序不同)的同名函数,根据参数列表确定调用哪个函数,重载不关心函数返回类型。(3)virtual的区别:重写的基类函数必须要有virtual修饰,重载函数和被重载函数可以被virtual修饰,也可以没有。(2)参数区别:重写与被重写的函数参数列表一定相同,重载和被重载的函数参数列表一定不同。(1)范围区别:重写和被重写的函数在不同的类中,重载和被重载的函数在同一类中。

2024-04-01 14:25:05 281

原创 博客摘录「 【Linux】线程池」2023年10月14日

一种线程使用模式。线程过多会带来调度开销,进而影响缓存局部性和整体性能。而线程池维护着多个线程,等待着 监督管理者分配可并发执行的任务。这避免了在处理短时间任务时创建与销毁线程的代价。线程池不仅能够保证内核的充分利 用,还能防止过分调度。可用线程数量应该取决于可用的并发处理器、处理器内核、内存、网络sockets等的数量。我们去处理任务时,一个任务对应一个创建一个线程进行处理,效率是比较低的。我们可以预先创建一批线程,任务队列里没有任务的时候,每个线程都休眠,当队里中有任务的时候,就可以环形线程进行处理了。

2023-11-22 08:27:45 85

原创 算法(圆的定义和相关术语)

图中每一个顶点的度定义为以该项点为一个端点的边的数目。

2023-11-21 14:03:05 616

原创 c++菱形继承

可以看到ptr1和ptr2不知道自己压根不知道自己指向的是谁,这是一种切片,他们只管通过同样的方式先找到虚基表,然后通过虚基表中的偏移量找到A的位置,也可以说实际上D不用找A,但是B和C要找,因为不清楚B是切片的还是独立的,在D中找A直接通过切片的B寻找,但是独立的B要用自己的偏移量寻找。老师与学生都有人的特性,三者都是单独的类,如果在将学生类中的特性全写过一遍的话,造成代码的重复,老师类也一样,所以如果我们可以让两个后者继承人类的性质然后再加上自己私有的性质,就可以让代码复用。5实际尽量多去用组合。

2023-11-20 13:32:13 184

原创 动态规划c++

(英语:Dynamic programming,简称 DP),是一种在数学、管理科学、计算机科学、经济学和生物信息学中使用的,通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法。动态规划常常适用于有重叠子问题和最优子结构性质的问题。

2023-11-17 08:28:27 428

原创 const关键字c++

如果const位于星号*的左侧,则const就是用来修饰指针所指向的变量,即指针指向为常量;如果const位于星号*的右侧,const就是修饰指针本身,即指针本身是常量。通俗理解:左定值,右定向,const修饰不变量。

2023-11-15 18:58:37 385

原创 为什么要把析构函数定义为虚函数

原理:当delete父类的指针时,由于子类的析构函数与父类的析构函数构成多态,所以得先调动子类的析构函数;之所以再调动父类的析构函数,是因为delete的机制所引起,,delete父类指针所指的空间,要调用父类的析构函数。如果基类析构函数不是虚函数:基类指针指向子类对象,delete基类指针,调用基类析构函数,不会调用子类析构函数,造成内存泄露。如果基类析构函数是虚函数:当用一个基类的指针删除一个派生类的对象时,派生类的析构函数会被调用。虚析构函数 为了避免内存泄露,基类的析构函数一般都是虚函数。

2023-11-14 08:48:02 380

原创 为什么要把析构函数定义为虚函数

原理:当delete父类的指针时,由于子类的析构函数与父类的析构函数构成多态,所以得先调动子类的析构函数;之所以再调动父类的析构函数,是因为delete的机制所引起,,delete父类指针所指的空间,要调用父类的析构函数。如果基类析构函数不是虚函数:基类指针指向子类对象,delete基类指针,调用基类析构函数,不会调用子类析构函数,造成内存泄露。如果基类析构函数是虚函数:当用一个基类的指针删除一个派生类的对象时,派生类的析构函数会被调用。虚析构函数 为了避免内存泄露,基类的析构函数一般都是虚函数。

2023-11-13 18:38:02 81

原创 类的生命周期

编码阶段是 C++ 程序生命周期的起点,也是最重要的阶段,是后续阶段的基础,直接决定 了 C++ 程序的“生存质量, 最基本的要求是遵循语 言规范和设计文档,再高级一点的话,还有代码规范、注释规范、设计模式、编程惯用法, 等等。模板元编程: 它的核心思想是“类型运算”,操作的数据是编译时可见的“类型”,所以也比较特殊,代码只能由编译器执行,而不能被运行时 的 CPU 执行。更多的是以库的方式来使用.所以常用的范式是“过程 + 对象 + 泛型”,再加上少量的“函数式”,慎用“模板元”。可以用在C++11中。

2023-11-13 08:19:28 28

原创 malloc和new的区别

malloc的全称是memory allocation,中文叫动态内存分配,用于申请一块连续的指定大小的内存块区域以void*类型返回分配的内存区域地址,当无法知道内存具体位置的时候,想要绑定真正的内存空间,就需要用到动态的分配内存,且分配的大小就是程序要求的大小。(来源百度百科)new会先调用operator new函数,申请足够的内存,然后调用类型的构造函数,初始化成员变量,最后返回自定义类型指针。delete先调用析构函数,然后调用operator delete函数释放内存。

2023-11-11 13:24:36 223

原创 DFS与BFS优先搜索算法

DFS(深度优先搜索)是一种图遍历算法,它从一个起始点开始,一直往下走直到不能再走为止,然后返回到前一个节点,继续探索它的其他分支,直到找到目标节点为止。这种算法通常用于解决“遍历”问题,比如在树中查找所有的叶子节点。要理解DFS,也还可以想象自己在迷宫中寻找所有可行的路径1.首先,你会从起点开始,顺着一条路一直走,直到你走到一个死胡同2.再返回到前一个节点,继续探索其他分支在探索过程中,你可以使用栈来存储已经访问过的节点,以便后续回溯。在DFS中,你可以使用递归或栈来实现深度优先搜索。

2023-11-10 10:02:46 475

原创 右值引用C++

右值引用是 C++11 引入的与 Lambda 表达式齐名的重要特性之一。它的引入解决了 C++ 中大量的历史遗留问题, 消除了诸如 std::vector、std::string 之类的额外开销。先说一下一个看到的结论,引入右值引用,就是为了移动语义。移动语义就是为了减少拷贝。std::move就是将左值转为右值引用。这样就可以重载到移动构造函数了,移动构造函数将指针赋值一下就好了,不用深拷贝了,提高性能。

2023-11-09 14:50:36 124

原创 STL之Map(C++)

map 是具有唯一键值对的容器,通常使用红黑树实现。map 中的键值对是 key value 的形式,比如:每个身份证号对应一个人名(反过来不成立哦!),其中,身份证号就是 key,人名便是 value,是单项的关系,可以与 hash 作类比。使用 map 需要引入头文件,如下所示:定义形式如下所示:map<key_type, value_type>变量名注意:如果没有 using namespace std, map需要写成 std:map。

2023-10-28 11:24:01 320

原创 STL之deque(C++)

功能:双端数组,可以对头端进行插入删除操作。deuqe与vector区别:vector对于头部的插入删除效率低,数据量越大,效率越低;deque相对而言,对头部的插入删除速度比vector快;vector访问元素时的速度会比deque快,这和两者内部实现有关。deque内部工作原理:deque内部有个中控器,维护每段缓冲区的内容,缓冲区中存放真实数据;中控器维护的是每个缓冲区的地址,使得使用deque时像一片连续的内存空间。deque容器的迭代器也是支持随机访问的。

2023-10-26 18:27:20 99

原创 static关键字(C++)

在全局变量前,加上关键字static,该变量就被定义成为一个静态全局变量。我们先举一个全局变量和静态全局变量的例子,例如,在文件A中定义静态全局变量 i 和全局变量 j :也就是说,在声明全局的static变量时,static没有改变它的生存周期,也即存储位置(因为全局变量本来就存储在全局数据域),而是将变量的作用域限制在当前文件中。总:静态全局变量 i 有以下特点:静态变量都在全局数据区分配内存,包括后面将要提到的静态局部变量。对于一个完整的程序,在内存中的分布情况如下图:代码区全局数据区。

2023-10-25 14:12:55 95

原创 多态的实现原理

多态就是多种形态,C++的多态分为静态多态与动态多态。静态多态就是重载,因为在编译期决议确定,所以称为静态多态。在编译时就可以确定函数地址。动态多态就是通过继承重写基类的虚函数实现的多态,因为是在运行时决议确定,所以称为动态多态。运行时在虚函数表中寻找调用函数的地址。在基类的函数前加上virtual关键字,在派生类中重写该函数,运行时将会根据对象的实际类型来调用相应的函数。如果对象类型是子类,就调用子类的函数;

2023-10-24 20:42:54 173

原创 一文了解TCP/UDP

TCP作为面向连接的可靠传输协议,被广泛应用于各种场景,也是在面试时经常被提及的内容。学习了解TCP协议也是学习网络必不可少的一步,作者从个人的角度对TCP的一些知识进行了梳理,也是对学习的一个记录,有不对的地方也欢迎大家进行交流。因为TCP发送端和接收端的消息都需要被确认为什么不是两次?如果客户端发往服务端的SYN消息滞留在网络中,客户端发起重传SYN并建立连接,如果等到连接关闭时,此时之前滞留在网络中的SYN消息到达服务端,服务端回复,就默认建立连接,但是此时客户端已经断开连接了,造成连接资源的浪费。

2023-10-23 09:06:25 207

原创 一文带你了解UDP协议

UDP协议作为一种轻量级、无连接和不可靠的传输协议,在网络通信中具有广泛的应用。但需要注意的是,UDP协议不保证数据的可靠性和顺序性,因此在某些对数据完整性要求较高的场景中,可能需要使用TCP协议来确保数据的可靠传输。1. 实时音视频传输:由于UDP协议的低延迟和高效性,它广泛用于实时音视频传输,如音频会议、视频会议和流媒体服务等。2. 面向报文:UDP协议将应用程序传递给它的数据封装成独立的数据报进行传输,每个数据报都是独立的实体,不会进行拆分和重组。UDP协议在网络通信中具有广泛的应用。

2023-10-22 09:12:32 157

原创 HTTP 的长连接和短连接

在 HTTP/1.0 中,默认使用的是短连接。也就是说,浏览器和服务器每进行一次 HTTP 操作,就建立一次连接,但任务结束就中断连接。如果客户端浏览器访问的某个 HTML 或其他类型的 Web 页中包含有其他的 Web 资源,如JavaScript 文件、图像文件、CSS 文件等;当浏览器每遇到这样一个 Web 资源,就会建立一个 HTTP 会话。但从 HTTP/1.1 起,默认使用长连接,用以保持连接特性。

2023-10-21 11:34:23 142

原创 linux进度条小程序实现

C语言中字符分为两种:1.可显字符2.控制字符其中可显字符就是字符a这类的字符,控制字符就是\n这种控制字符。对于我们制作进度条,我们只需要关注两个控制字符:1.\r – 进行回车操作2.\n – 进行换行加回车操作说明: \n本身是换行字符,但是C语言本身将其解析成了换行加回车。

2023-10-20 09:47:59 99 1

原创 http服务器

http服务器。

2023-10-16 14:16:01 111 1

原创 基于C++实现五子棋

五子棋是我国古代传统的黑白棋种之一,黑白双方依次落子,任意一方在棋盘上形成横向、纵向、斜向的连续相同颜色的五颗棋子的一方为胜。

2023-10-15 20:54:39 2867 1

原创 线程池封装LINUX

一种线程使用模式。线程过多会带来调度开销,进而影响缓存局部性和整体性能。而线程池维护着多个线程,等待着 监督管理者分配可并发执行的任务。这避免了在处理短时间任务时创建与销毁线程的代价。线程池不仅能够保证内核的充分利 用,还能防止过分调度。可用线程数量应该取决于可用的并发处理器、处理器内核、内存、网络sockets等的数量。我们去处理任务时,一个任务对应一个创建一个线程进行处理,效率是比较低的。我们可以预先创建一批线程,任务队列里没有任务的时候,每个线程都休眠,当队里中有任务的时候,就可以环形线程进行处理了。

2023-10-14 15:43:12 45 1

原创 tcp socket 实现多线程服务端和客户端

【代码】tcp socket 实现多线程服务端和客户端。

2023-10-13 21:16:22 284

原创 tcp socket 多线程版服务器与客户端

以上就完成了一个tcp socket的多线程版服务器端 和客户端。

2023-10-13 21:08:41 59

原创 Day9编程题

(n为横向的格子数,m为竖向的格子数)从棋盘左上角出发沿着边缘线从左上角走到右下角,总共有多少种走法,要求不能走回头路, 即:只能往右和往下走,不能往左和往上走。

2023-10-13 14:35:30 24

原创 socket实现简单的网络聊天服务器和客户端(UDP)

在日常应用中有很多关于socket网络通信的例子,例如局域网内打游戏,使用浏览器看视频,用QQ软件聊天等。可以说socket是底层抽象给应用层所使用的一套接口。网络通信的传输方式有两种,一种是基于TCP(数据可靠传输),另一种是基于UDP(数据不可靠,一般用于实时视频传输)。

2023-10-10 17:14:17 1768 1

原创 Day5编程题

回文串”是一个正读和反读都一样的字符串,比如“level”或者“noon”等等就是回文串。花花非常喜欢这种拥有对称美的回文串,生日的时候她得到两个礼物分别是字符串A和字符串B。现在她非常好奇有没有办法将字符串B插入字符串A使产生的字符串是一个回文串。你接受花花的请求,帮助她寻找有多少种插入办法可以使新串是一个回文串。如果字符串B插入的位置不同就考虑为不一样的办法。例如:这里有4种把B插入A的办法:* 在A的第一个字母之前: "baba" 不是回文。

2023-10-10 16:41:58 25 1

原创 Day4编程题

A,B,C三个人是好朋友,每个人手里都有一些糖果,我们不知道他们每个人手上具体有多少个糖果,但是我们知道以下的信息:A - B, B - C, A + B, B + C. 这四个数值.每个字母代表每个人所拥有的糖果数.现在需要通过这四个数值计算出每个人手里有多少个糖果,即A,B,C。这里保证最多只有一组整数A,B,C满足所有题设条件。

2023-10-09 15:19:34 36 1

原创 【C语言】const修饰的指针(详解)

1. const int * p(int const * p) :const 放在*的左边,修饰的是*p,*p(指针指向的内容)不能被改变,p(指针变量本身)能被改变。2. int * const p :const 放在*的右边,修饰的是*p,*p(指针指向的内容)能被改变,p(指针变量本身)不能被改变。3. int const * const p (const int * const p),const 放在*的左边,修饰的是*p和p,*p(指针指向的内容)和p(指针变量本身)都不能被改变。

2023-10-08 19:37:30 33 1

原创 二叉树的层序遍历(广度优先)

广度优先搜索思路和算法我们可以用广度优先搜索解决这个问题。我们可以想到最朴素的方法是用一个二元组 (node, level) 来表示状态,它表示某个节点和它所在的层数,每个新进队列的节点的 level 值都是父亲节点的 level 值加一。最后根据每个点的 level 对点进行分类,分类的时候我们可以利用哈希表,维护一个以 level 为键,对应节点值组成的数组为值,广度优先搜索结束以后按键 level 从小到大取出所有值,组成答案返回即可。

2023-10-08 19:19:28 41 1

原创 倒置字符串

将一句话的单词进行倒置,标点不倒置。比如 I like beijing. 经过函数后变为:beijing. like I。

2023-10-07 21:15:29 17 1

原创 编程题删除公共字符

输入两个字符串,从第一字符串中删除第二个字符串中所有的字符。例如,输入”They are students.”和”aeiou”,则删除之后的第一个字符串变成”Thy r stdnts.”

2023-10-07 19:59:56 19 1

原创 编程题(组队竞赛)

【代码】编程题(组队竞赛)

2023-10-07 16:11:35 50 1

原创 七大排序算法(C++)

1.快速排序快速排序算法通过多次比较和交换来实现排序,其排序流程如下:1、首先设定一个分界值,通过该分界值将数组分成左右两部分。2、将大于或等于分界值的数据集中到数组右边,小于分界值的数据集中到数组的左边。此时,左边部分中各元素都小于分界值,而右边部分中各元素都大于或等于分界值。3、然后,左边和右边的数据可以独立排序。对于左侧的数组数据,又可以取一个分界值,将该部分数据分成左右两部分,同样在左边放置较小值,右边放置较大值。右侧的数组数据也可以做类似处理。

2023-10-04 20:51:27 64 1

原创 冒泡排序(C++)

对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。优化加入了判断最后一次是否交换的变量,如果没有交换就结束循环。如果第一个比第二个大,就交换他们两个。针对所有的元素重复以上的步骤,除了最后一个。

2023-10-02 20:02:38 31 1

原创 插入排序(C++)

插入排序的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。插入排序在实现上,通常采用in-place排序(即只需用到O(1)的额外空间的排序),因而在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。

2023-10-02 19:35:26 36 2

原创 快速排序C++实现

【代码】快速排序C++实现。

2023-10-02 15:15:01 217 2

原创 C++实现定长内存池

定长内存池是高并发的内存池的一部分。

2023-09-30 21:17:30 53 1

空空如也

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

TA关注的人

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