自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 还搞不懂 UDP和TCP?一篇文章帮你搞定

UDP特点无连接不可靠面向数据报报文格式· 源端口:这个字段占据 UDP 报文头的前 16 位,通常包含发送数据报的应用程序所使用的 UDP 端口。接收端的应用程序利用这个字段的值作为发送响应的目的地址。这个字段是可选的,所以发送端的应用程序不一定会把自己的端口号写入该字段中。如果不写入端口号,则把这个字段设置为 0。这样,接收端的应用程序就不能发送响应了。目的端口:接收端计算机上 UDP 软件使用的端口,占据 16 位。长度:该字段占据 16 位,表示 UDP 数据报长度,包含 UD

2020-06-09 23:39:23 1558 1

转载 Redis 如何保证数据库和缓存双写一致性

redis

2022-08-09 10:28:33 432

原创 C++ 异常捕获详解

为什么存在异常处理在程序运行时常会碰到一些错误,例如除数为 0、年龄为负数、数组下标越界等,这些运行时错误如果放任不管,系统就会执行默认的操作,终止程序运行,也就是我们常说的程序崩溃(Crash)。C++ 提供了异常(Exception)机制,让我们能够捕获运行时错误,给程序一次“起死回生”的机会,或者至少告诉用户发生了什么再终止程序。而 C++ 异常处理机制就可以让我们捕获并处理这些错误,然后我们可以让程序沿着一条不会出错的路径继续执行,或者不得不结束程序,但在结束前可以做一些必要的工作,例如将内存中

2021-04-28 17:40:27 9498 1

原创 C++ 内联函数浅析

概念C++中的函数是一个可以重复使用的代码块,CPU 会根据顺序一条一条地挨个执行其中的代码。CPU 在执行主调函数代码时如果遇到了被调函数,主调函数就会暂停,CPU 转而执行被调函数的代码;被调函数执行完毕后再返回到主调函数,主调函数根据刚才的状态继续往下执行。一个 C/C++ 程序的执行过程可以认为是多个函数之间的相互调用过程,它们形成了一个或简单或复杂的调用链条,这个链条的起点是 main(),终点也是 main()。当 main() 调用完了所有的函数,它会返回一个值(例如return 0;)来

2021-04-28 10:42:07 196

原创 C++抽象类浅析

抽象类如果在一个虚函数的后面写上 =0 ,则这个函数为纯虚函数。而包含纯虚函数的类叫做抽象类(也叫接口类)。特点包含纯虚函数的类称为抽象类(Abstract Class)。之所以说它抽象,是因为它无法实例化,也就是无法创建对象。原因很明显,纯虚函数没有函数体,不是完整的函数,无法调用,也无法为其分配内存空间。抽象类通常是作为基类,让派生类去实现纯虚函数。派生类必须实现(重写)纯虚函数才能被实例化。class Car //这就是一个抽象类{ public: virtual void Dr

2021-04-27 13:19:26 311

原创 Java数组的创建、java中new和C++中new的不同点

一维数组type(要创建的数组类型)[ ] 数组名 = new type [length(数组长度)]int[] arr1 = new int[10];String[] arr2 = new String[2];也可以在创建时直接赋值int[] arr1 = {1,2,3,4,5,6};int[] arr1 = new int[]{1,2,3,4,5,6};二维数组type(要创建的数组类型)[ ][ ] 数组名 = new type [length(行长度)] [len

2021-04-19 13:28:22 183

原创 C++ 四大类型转换

类型转换为什么C++需要四种类型转换C风格的转换格式很简单,但是有不少缺点的:隐式类型转化有些情况下可能会出问题:比如数据精度丢失显式类型转换将所有情况混合在一起,代码不够清晰因此 C++ 提出了自己的类型转化风格,注意因为 C++ 要兼容C语言,所以 C++ 中还可以使用C语言的转化风格标准C++为了加强类型转换的可视性,引入了四种命名的强制类型转换操作符:- static_cast、reinterpret_cast、const_cast、dynamic_cast1.static_ca

2021-04-14 14:21:41 203

转载 浅析堆、栈、数据段、代码段、BSS的作用

动态区域(栈、堆)、静态存储区(数据段和程序段)堆(new、malloc出来的空间)类成员变量存放在堆区,所有类的实例和数组都是在堆上分配内存的,堆内存由存活和死亡的对象,空闲碎片区组成,对象所占的堆内存是由自动内存管理系统回收;堆允许程序在运行时动态地申请某个大小的内存。一般由程序员分配释放,若程序员不释放,则可能会引起内存泄漏。栈(定义局部、临时变量时系统自动分配空间)由编译器自动分配释放,存放函数的参数值,局部变量等值。其操作方式类似于数据结构中的栈。数据段: 由三部分

2021-04-14 14:15:25 617

原创 C语言实现银行家算法

#define _CRT_SECURE_NO_WARNINGS#include<stdio.h>#include<malloc.h>#include<string.h>#include<windows.h>void Init(int **arr,int row, int col) //赋值{ //int*...

2021-04-14 10:53:29 381

原创 Linux下 &、&&、|、||、>、>>的区别

1. & 表示将任务放后台运行log.text & // 把log.text放在后台运行2. && 表示当上一条命令执行成功时,才会执行下一条命令(如果上一条命令未执行成功,下一条命令则不会进行)cd XX/ && vi test.c //进入XX目录后创建test.c3. | 管道符(将上一条命令的输出当作下一条命令的输入参数)ps -aux | grep xxx // 在ps打印出的

2021-04-14 10:52:42 1095

原创 C++ 回调函数浅析

简述能来了解回调函数,说明电脑前的你必定对指针有了比较深入的见解了吧,我们知道函数的参数有很多,整形、浮点、指针、对象等等。每一个函数其实都有属于它自己的地址(函数指针就指向函数的地址),当需要调用的时候其实也是在访问它的地址,而指针既然能作为函数参数,那么函数的地址当然也可以作为函数参数。举个例子:#include<iostream>#include<string>using namespace std;typedef void(*callback)(string);

2021-04-02 17:40:34 238

原创 Linux 下的多路转接/复用技术和四种典型的高级IO介绍

多路转接/复用概念多路复用是指以同一传输媒质(线路)承载多路信号进行通信的方式。各路信号在送往传输媒质以前,需按一定的规则进行调制,以利于各路已调信号在媒质中传输,并不致混淆,从而在传到对方时使信号具有足够能量,且可用反调制的方法加以区分、恢复成原信号。作用:用于针对大量描述符进行 IO 就绪事件的集中监控,让我们的进程能够针对就绪的描述符进行操作,避免了对没有就绪的描述符进行操作而导致的阻塞,同时也避免了对大量没有就绪的描述符进行操作而带来的效率低下。四种典序的IO模型1.阻塞IO发起

2020-08-16 22:56:06 383

原创 MySQL的基本操作指令及常见数据类型

数据库概念数据库是“按照数据结构来组织、存储和管理数据的仓库”。是一个长期存储在计算机内的、有组织的、可共享的、统一管理的大量数据的集合。数据库是以一定方式储存在一起、能与多个用户共享、具有尽可能小的冗余度、与应用程序彼此独立的数据集合,可视为电子化的文件柜——存储电子文件的处所,用户可以对文件中的数据进行新增、查询、更新、删除等操作。数据库和文件存储的区别文件系统面向某一应用程序,共享性差,冗余度大,数据独立性差,记录内有结构,整体无结构,由应用程序自己控制。数据库系统面向现实世界,共享性高

2020-08-15 21:20:35 615

原创 滑动窗口算法总结

算法目的该算法展示了如何将嵌套for循环在少数问题中转换为单个for循环,从而减少了时间的复杂性。应用滑动窗口技术:我们使用线性循环计算n个项中前k个元素的总和,并将总和存储在变量window_sum中。然后,我们将在阵列上线性滑动直至达到最终并同时追踪最大和。要获得k个元素块的当前总和,只需从前一个块中减去第一个元素并添加当前块的最后一个元素即可。 下面的表示将清楚说明窗口如何在阵列上滑动。这是我们计算从索引0开始的初始窗口总和的初始阶段。在这个阶段,窗口和为6.现在,我们将maximum_s

2020-08-12 18:55:00 9407 1

原创 并查集原理、代码、例题演示

并查集原理在一些应用问题中,需要将n个不同的元素划分成一些不相交的集合。开始时,每个元素自成一个单元素集合,然后按一定的规律将归于同一组元素的集合合并。在此过程中要反复用到查询某一个元素归属于那个集合的运算。适合于描述这类问题的抽象数据类型称为并查集(union-findset)比如:某公司今年校招全国总共招生10人,西安招4人,成都招3人,武汉招3人,10个人来自不同的学校,起先互不相识,每个学生都是一个独立的小团体,现给这些学生进行编号:{0, 1, 2, 3,4, 5, 6, 7, 8, 9}

2020-08-07 22:44:14 176 1

原创 协程实现网络服务器

1. 协程介绍2. 函数介绍3. 项目代码

2020-07-30 13:42:01 571

原创 C++ 单例模式/类型转换/特殊类设计

单例模式概念常用的一种典型的设计模式,单例模式的方法创建的类在当前进程中只有一个实例,一份资源只能被申请加载一次。实现饿汉模式:在资源的程序还在初始化的时候就会加载,保证后面能够直接进行使用。(不涉及线程安全问题 )优:使用的过程流畅缺:可能会加载很多不需要的资源,导致程序初始化缓慢懒汉模式: 资源在使用的过程中发现还没加载则申请加载。(游戏中常用且涉及线程安全)优:程序初始化快缺:使用过程中衔接不流程,并且在第一次运行某个模块时会比较缓慢,因为此时正在加载相应的资源总结对比一下饿

2020-07-25 00:02:41 273

原创 C++ 内存泄漏和智能指针介绍

智能指针为什么要使用智能指针因为 C++ 不像 Java 一样具有垃圾回收机制(gc),但是又需要释放内存,防止内存泄漏。智能指针的作用是管理一个指针,主要用于防止内存写了,因为智能指针就是一个类,当超出了类的作用域是,类会自动调用析构函数,析构函数会自动释放资源。所以智能指针的作用原理就是在函数结束时自动释放内存空间,不需要手动释放内存空间。1.auto_ptrauto_ptr 的大概流程就是使用该指针去代替原生指针管理空间,而后将原生指针置空,这样在 auto_ptr 的生命周期到了以后会去调

2020-07-23 23:27:43 369

原创 C++ 中的线程库和 lamber 表达式

lambeda表达式语法格式lambda表达式书写格式:[capture-list] (parameters) mutable -> return-type { statement }1.lambda表达式各部分说明[capture-list] : 捕捉列表,该列表总是出现在lambda函数的开始位置,编译器根据 [] 来判断接下来的代码是否为 lambda 函数,捕捉列表能够捕捉上下文中的变量供 lambda 函数使用。(parameters):参数列表。与普通函数的参数列表一致,如果不

2020-07-22 22:47:40 560

原创 网络基础总结 (TCP/IP模型及常见协议解析)

OSI 七层参考模型应用层表示层会话层传输层网络层数据链路层物理层后来因模型太过繁琐被压缩成了 TCP/IP 五层参考模型。TCP/IP 五层参考模型应用层负责应用程序之间的沟通;是七层模型中最靠近用户的一层,为用户提供应用接口,也为用户直接提供各种网络服务。包含的协议有:HTTP、DNS、HTTPS、FTP、SNMP、DHCP、TELNET、TFTP等。传输层负责应用程序之间的数据传输;是通信子网和资源子网的接口和桥梁,主要向用户提供可靠的端到端的差错和流量控制,保证

2020-07-12 19:48:19 2184

原创 哈希 (hash) 闭散列和开散列的存储方式以及对应哈希冲突的解决办法

哈希的概念顺序结构以及平衡树中,元素关键码与其存储位置之间没有对应的关系,因此在查找一个元素时,必须要经过关键码的多次比较。顺序查找时间复杂度为 O(N),平衡树中为树的高度,即O(LogN),搜索的效率取决于搜索过程中元素的比较次数。我们理想的搜索方法:可以不经过任何比较,一次直接从表中得到要搜索的元素。 如果构造一种存储结构,通过某种函数 (hashFunc) 使元素的存储位置与它的关键码之间能够建立一一映射的关系,那么在查找时通过该函数可以很快找到该元素。当向该结构中:插入元素根据待插入元

2020-07-11 22:37:55 1316

原创 Hash 位图和布隆过滤器的原理的使用解析

位图这里借用鹅厂一道经典的面试题来开头:如果给你 40 亿的不重复的无符号乱序排列的整数,再给你一个无符号整数,如何快速判断这个数是否在这 40 亿个整数中?首先我们先算一算存储 40 亿个数所需要的空间大小,unsigned 是 4 个字节,也就是 40 亿 * 4 = 160 亿的字节,2 ^ 30 = 1G, 算下来接近 15G,这个代价未免也太大了,所以我们需要一个更加稳妥的方式去解决它。这里我们就用到了 hash 位图。原理一个字节是 8 个 bit,所以我们可以开足够大小的 bi

2020-07-07 23:17:20 573

原创 C++ 中 map 和 set 的用法以及概念解析/含 map中operator[] 的用法

键值对用来表示具有一一对应关系的一种结构,该结构中一般只包含两个成员变量<key,value>,key代表键值,value表示与key对应的信息。比如:现在要建立一个英汉互译的字典,那该字典中必然有英文单词与其对应的中文含义,而且,英文单词与其中文含义是一一对应的关系,即通过该应该单词,在词典中就可以找到与其对应的中文含义。SGI-STL中关于键值对的定义template <class T1, class T2>struct pair{ typedef T1 fir

2020-07-02 11:11:23 808

原创 红黑树的插入(map、set的底层实现)

红黑树红黑树,是一种二叉搜索树,但在每个结点上增加一个存储位表示结点的颜色,可以是Red或Black。 通过对任何一条从根到叶子的路径上各个结点着色方式的限制,红黑树确保没有一条路径会比其他路径长出俩倍,因而是接近平衡的。性质每个结点不是红色就是黑色根节点必是黑色的 (重点)如果一个节点是红色的,则它的两个孩子结点是黑色的,即没有连续的红节点 (重点)对于每个结点,从该结点到其所有后代叶结点的简单路径上,均包含相同数目的黑色结点 (重点)每个叶子结点都是黑色的(此处的叶子结点指的是空

2020-06-30 14:44:38 199

原创 AVL 树的插入以及简单代码实现

AVL 树概念AVL树是最先发明的自二叉搜索树。因为一旦二叉搜索树插入的数据接近有序,那么则会退化成为一颗单支叶树,相当于一个链表,查找效率低下。但在AVL树中任何节点的两个子树的高度最大差别为1,所以它也被称为高度平衡树。严格保证了树的高度,大大提高了查找的效率,但是增加和删除可能需要通过一次或多次旋转来重新平衡这个树。特点本身首先是一棵二叉搜索树。它的左右子树都是 AVL 树带有平衡条件:每个结点的左右子树的高度之差的绝对值(平衡因子)最多为1。如果一棵二叉搜索树是高度平衡的,它就是AV

2020-06-28 23:46:47 745

原创 一篇文带你搞懂搜索二叉树的原理和实现

二叉搜索树概念二叉搜索树又称二叉排序树,它或者是一棵空树,或者是具有以下性质的二叉树:若它的左子树不为空,则左子树上所有节点的值都小于根节点的值若它的右子树不为空,则右子树上所有节点的值都大于根节点的值它的左右子树也分别为二叉搜索树1.二叉搜索树的查找2.二叉树的插入a. 树为空,则直接插入b. 树不空,按二叉搜索树性质查找插入位置,插入新节点3.二叉搜索树的删除首先查找元素是否在二叉搜索树中,如果不存在,则返回, 否则要删除的结点可能分下面四种情况:a. 要删除的结点

2020-06-16 23:19:43 913 2

原创 C++ 多态详解(含重载、覆盖(重写)、隐藏(重定义)的对比)

多态概念也就是多种形态,具体就是当要去完成某个行为时,不同的对象完成时会产生出不同的状态。多态的构成条件多态是在不同继承关系的类对象,去调用同一函数,产生了不同的行为。比如 Student 继承了 Person。Person 对象买票全价,Student对象买票半价。那么在继承中要构成多态还有两个必备条件:必须通过基类的指针或者引用调用虚函数被调用的函数必须是虚函数,且派生类必须对基类的虚函数进行重写虚函数的重写(覆盖)派生类中有一个跟基类完全相同的虚函数(即派生类虚函数与基类虚函数的

2020-06-07 23:03:23 289

原创 C++普通继承和虚继承详解

继承继承概念所谓的继承就是一个类继承了另一个类的属性和方法,这个新的类包含了上一个类的属性和方法,被称为子类或者派生类,被继承的类称为父类或者基类。继承特点子类拥有父类的所有属性和方法(除了构造函数和析构函数)。子类可以拥有父类没有的属性和方法。子类是一种特殊的父类,可以用子类来代替父类。子类对象可以当做父类对象使用。继承格式class 派生类类名: 继承方式 基类名{成员变量和成员函数的声明}继承方式: public protected privat

2020-06-07 22:18:46 3228 1

原创 Linux下模拟 TCP 套接字编程

TCP套接字编程步骤客户端创建套接字绑定地址信息(不推荐,因为系统会帮你绑定,这样能预防端口冲突)向客户端发送连接请求发送/接收数据关闭套接字服务端创建套接字绑定地址信息(客户端必须自己绑定,系统不会帮你)将套接字设为监听状。此状态下一旦接收到连接请求,就会创建一个新的 socket 并放入未完成连接队列里面去,等到连接建立完成,就会将它再次转到已完成连接队列里去。(若未完成连接队列已满则新的连接请求会被丢弃,直到腾出空间才再次建立连接)获取新连接。从已完成连接队列中取出一个套接

2020-06-03 23:43:40 639 2

原创 C++ 模拟实现 vector

#define _CRT_SECURE_NO_WARNINGS#include<iostream>#include<vector>#include<list>#include<assert.h>using namespace std;namespace My_Vector{ template<class T> class vector { public: typedef T* iterator; typedef co

2020-05-27 22:43:17 214

原创 Linux下 模拟 UDP套接字编程

套接字(socket)概念套接字(socket)是一个抽象层,应用程序可以通过它发送或接收数据,可对其进行像对文件一样的打开、读写和关闭等操作。套接字允许应用程序将I/O插入到网络中,并与网络中的其他应用程序进行通信。网络套接字是IP地址与端口的组合。通信的实质两个主机之间的通信,可以认为是两个进程的通信,也可以认为其实是两个socket 套接字之间的通信。通信五元组源 IP 地址源端口号目的 IP 地址目的端口号传输层协议(通过通信五元组就能够标识一条通信道路)流程图示套

2020-05-27 12:24:50 419

原创 C 语言库函数 memset 为什么只能初始化为0的原因详解

这是因为 memset 是根据字节来初始化的举个例子int main(){ int a[10]; //memset(a, 0, sizeof(int)*10); //memset(a, 1, sizeof(int)*10); memset(a, 2, sizeof(int)*10); for (auto e : a) cout << e << " "; cout << endl;}这里实际上是这样的//因为一个 int 是四个字节,所以 m

2020-05-20 20:37:09 1688 2

原创 C++ 模拟日期类的实现

#define _CRT_SECURE_NO_WARNINGS#include<iostream>using namespace std;class Date { //友元函数 friend ostream& operator<<(ostream& out, const Date& d); friend istream& operator>>(istream& in, Date& d);private:

2020-05-19 20:17:26 297

原创 Linux下信号量概念解析及简单代码演示

信号量概念用于实现进程、线程间的同步和互斥关系(主要用来实现同步),本质上是由一个计数器和一个 pcb 等待队列构成。同步通过自身的计数器堆资源数目进行计数,并通过计数判断进程、线程是否满足访问临界资源的条件,若满足则进行访问,若不满足则阻塞等待直到被唤醒。互斥只需要保证计数器的计数不大于 1 即可保证一个资源在同一时间内只被一个进程、线程所访问。(<= 0 都进等待队列)函数功能接口1. 定义信号量 sem_t sem; 2. 初始化信号量 int sem_ini

2020-05-17 18:41:50 415

原创 Linux下线程的单例模式和简单代码演示

单例模式概念常用的一种典型的设计模式,单例模式的方法创建的类在当前进程中只有一个实例,一份资源只能被申请加载一次。实现饿汉模式:在资源的程序还在初始化的时候就会加载,保证后面能够直接进行使用。(不涉及线程安全问题 )优:使用的过程流畅缺:可能会加载很多不需要的资源,导致程序初始化缓慢懒汉模式: 资源在使用的过程中发现还没加载则申请加载。(游戏中常用且涉及线程安全)优:程序初始化快缺:使用过程中衔接不流程,并且在第一次运行某个模块时会比较缓慢,因为此时正在加载相应的资源需注意的问题

2020-05-16 23:13:29 144

原创 Linux下线程池概念详解以及代码演示

线程池概念多个线程的组合,但是总数量不会超出池子的限制。是多执行流并发/并行处理,每当任务到来都会从池子里取出一个空闲的线程去进行处理。产生原因线程若是不限制数量的创建,在峰值的压力下,线程创建过多,会导致系统资源耗尽,所以创建线程池来约束线程数量。处理一个线程的总时间(T) = 创建线程的时间(T1) + 任务的处理时间(T2) + 销毁线程的时间(T3) , 若是 T2/T 所占比不够高的话会造成大量的时间浪费,所以创建线程池来统一创建和销毁线程,节约了时间成本,提高了效率。构成

2020-05-16 21:42:09 248

原创 C++ 模拟 string 的实现

#define _CRT_SECURE_NO_WARNINGS#include<iostream>#include<assert.h>#include<string>using namespace std; namespace MyString{ class string { public: friend ostream& operator<< (ostream& out, const string& s);

2020-05-12 23:10:15 172

原创 C++ 中 string 的常用用法和 迭代器详解

string的常用用法#include<iostream>#include<string>using namespace std;void String1(){ 1. 字符串的初始化和拷贝构造 string s1("hello"); //初始化s1 string s2 = s1; //拷贝构造s2 string s3(s2, 2); // 从...

2020-05-03 20:07:54 1608

原创 Linux 下同步与互斥、死锁的概念及其操作详解、生产者消费者模型代码演示

同步概念通过同一时间内访问的唯一性保证临界资源访问的安全性。互斥的实现通过 互斥锁/互斥量 来实现。互斥锁本身是一个只有 0/1 的计数器,描述了一个临界资源当前的访问状态。所有的执行流在访问临界资源前都必须判断当前的临界资源是否允许访问。如不允许访问则执行流等待,否则可以访问临界资源,但是在访问期间需要将临界资源的访问状态改为不可访问状态,防止其他的外来访问干扰。函数接口 #...

2020-04-28 17:43:13 258

原创 Linux 下多线程的概念及其具体操作

多线程目的多了实现多任务处理方式。多任务处理多创建几个进程,能够串行化的完成多个任务;以前我们说一个进程就是一个 pcb ,是操作系统对一个运行中程序的描述。而现在我们说的线程其实是进程中的一条执行流,该执行流在 Linux 下通过 pcb 实现,因此实际上线程就是一个 pcb, 然而 pcb 却代表一个进程,并且 Linux 下的 pcb 共用一个虚拟地址空间,相较于传统 pcb 更加...

2020-04-28 13:29:14 171

空空如也

空空如也

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

TA关注的人

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