自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 AVL树(平衡二叉树)详解 | C/C++实现

删除节点 X 之后,R4的平衡因子变为 -2,R4 左旋;插入一个节点会导致节点所在的子树高度加1,但是旋转会让新节点所在子树减1,所以AVL树插入一个节点最多只需要两次旋转就可以了。删除一个节点会导致节点所在子树减1,旋转又会让节点所在的子树减1,所以最坏的时候需要O(logN)次旋转。当从根节点至待删除节点的父节点平衡因子交替为 -1 和 +1,删除该节点一旦触发旋转就需要logn次旋转。在BST树的基础上引入了平衡因子的概念,要求任意一个节点的左右子树高度差不超过1。

2023-03-16 16:26:35 631 1

原创 红黑树详解(C/C++实现)

本文对红黑树进行详细的介绍,分析了红黑树的删除插入操作以及详细的代码实现,最后介绍了红黑树与AVL树的区别

2023-03-12 17:48:55 781 2

原创 FastDFS分布式文件系统

分布式文件系统FastDFS

2022-11-24 21:57:26 1075

原创 图床项目架构与设计

分布式文件服务系统

2022-11-24 21:54:22 935

原创 关于排序算法

排序算法

2022-10-19 19:31:06 188

原创 muduo

muduo

2022-10-14 14:39:52 763

原创 基于muduo的集群聊天服务器

基于muduo与nginx实现集群聊天服务器

2022-10-08 23:03:04 968

原创 多路IO转接服务器

多路I/O转接服务器多路IO转接服务器也叫做多任务IO服务器。该类服务器实现的主旨思想是,不再由应用程序自己监视客户端连接,取而代之由内核替应用程序监视文件selectint select(int nfds, fd_set * readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);//委托内核监控该文件描述符对应的读,写或者错误事件的发生.//nfds: 告诉内核要监控文件描述符的范围,一般取值为最大的文件

2021-11-29 20:15:02 800

原创 高并发服务器

高并发服务器第一种方案: 使用多进程, 可以让父进程接受新连接, 让子进程处理与客户端通信思路: 让父进程accept接受新连接, 然后fork子进程, 让子进程处理通信, 子进程处理完成后退出, 父进程使用SIGCHLD信号回收子进程第二种方案: 使用多线程, 让主线程接受新连接, 让子线程处理与客户端通信; 使用多线程要将线程设置为分离属性, 让线程在退出之后自己回收资源如何不使用多进程或者多线程完成多个客户端的连接请求将accept和read函数设置为非阻塞, 调用fcntl函数可以将文件描

2021-11-29 13:18:44 2668

原创 锁、条件变量、信号量

线程同步互斥锁#include<stdio.h>#include<stdlib.h>#include<string.h>#include<sys/types.h>#include<unistd.h>#include<pthread.h>#include<time.h>//定义一把锁pthread_mutex_t mutex;void *mythread1(void* args){ whil

2021-11-25 15:43:56 710 2

原创 守护进程和线程

守护进程和线程守护进程Daemon(精灵)进程,是Linux中的后台服务进程,通常独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件。一般采用以d结尾的名字,如vsftpdLinux后台的一些系统服务进程,没有控制终端,不能直接和用户交互。不受用户登录、注销的影响,一直在运行着,他们都是守护进程。如:预读入缓输出机制的实现;ftp服务器;nfs服务器等进程组和会话ps ajx查看进程组ID和会话ID进程组进程组是一个或者多个进程的集合,每个进程都属于一个进程组,引入进程组是为了简化

2021-11-25 14:53:47 703

原创 关于信号的一些东西

信号信号的机制进程A给进程B发送信号,进程B收到信号之前执行自己的代码,收到信号后,不管执行到程序的什么位置,都要暂停运行,去处理信号,处理完毕后再继续执行。与硬件中断类似——异步模式。但信号是软件层面上实现的中断,早期常被称为“软中断”每个进程收到的所有信号,都是由内核负责发送的信号的状态产生按键产生,如:Ctrl+c、Ctrl+z、Ctrl+\系统调用产生,如:kill、raise、abort软件条件产生,如:定时器alarm硬件异常产生,如:非法访问内存(段错误)、除0(浮点数

2021-11-25 14:52:33 130

原创 进程间通信

进程间通信Linux环境下,进程地址空间相互独立,每个进程各自有不同的用户地址空间。任何一个进程的全局变量在另一个进程中都看不到,所以进程和进程之间不能相互访问,要交换数据必须通过内核,在内核中开辟一块缓冲区,进程1把数据从用户空间拷到内核缓冲区,进程2再从内核缓冲区把数据读走,内核提供的这种机制称为进程间通信IPC管道管道是一种最基本的IPC机制,也称匿名管道,应用于有血缘关系的进程之间,完成数据传递管道的本质是一块内核缓冲区 ,内部使用环形队列实现由两个文件描述符引用,一个表示读端,一个

2021-11-24 22:48:53 123

原创 关于进程控制

进程控制创建进程fork//创建子进程pid_t fork(void);//成功:父进程返回子进程的PID,子进程返回0;失败:返回-1,设置errno值父子进程谁先抢到CPU时间片谁先执行父子进程间不能共享全局变量,虽然打印出来的地址一样,因为是虚拟地址如果父子进程只是对全局变量做读操作,则父子进程在内存中只有一份,属于共享如果父子进程中的任何一个进程对该变量做修改操作,会在内存中拷贝一个副本,然后在这个副本上进行修改,修改完成以后映射回去#include<stdio.

2021-11-24 22:47:36 251

原创 文件和目录

文件和目录stat/lstat//获取文件属性int stat(const char *pathname, struct stat *buf);int lstat(const char *pathname, struct stat *buf);//成功返回0,失败返回-1struct stat { dev_t st_dev; //文件的设备编号 ino_t st_ino; //节点 mode_t st_mode; //文件的类型和存取的权限 nlink_t s

2021-11-24 11:56:59 94

原创 文件I/O

文件I/O文件描述符对于内核,所有打开的文件都通过文件描述符引用文件描述符是一个非负整数,当打开一个现有文件或新建一个文件时,内核向进程返回一个文件描述符文件描述符0与进程的标准输入关联STDIN_FILENO文件描述符1与标准输出关联STDOUT_FILENO文件描述符2与标准错误关联STDERR_FILENOopen//打开或创建一个文件#include<fcntl.h>int open(const char* pathname,int flags);int op

2021-11-24 11:56:19 710

原创 高性能服务器程序框架

高性能服务器程序框架服务器模型C/S模型TCP/IP协议在设计和实现上并没有客户端和服务器的概念,在通信过程中所有机器都是对等的C/S(客户端/服务器)模型:所有客户都通过访问服务器来获取所需的资源适合资源相对集中的场合,并且其实现较为简单服务器是通信的中心,当访问量过大时,可能所有的客户都将得到很慢的响应P2P模型P2P(Peer to Peer,点对点)模型摒弃了以服务器为中心的格局,让网络上所有主机重新回归到对等的地位P2P模型使得每台机器在消耗服务的同时也给别人提供服务,这样

2021-11-23 13:12:01 748

原创 Linux服务器程序规范

Linux服务器程序规范日志Linux系统日志服务器的调试和维护都需要一个专业的日志系统Linux提供一个守护进程syslogd来处理系统日志现在的Linux系统上使用的都是其升级版rsyslogdrsyslogd守护进程既可以接受用户进程输出的日志,又能接收内核日志用户进程通过调用syslog函数生成系统日志,该函数将日志输出到一个UNIX本地域socket类型(AF_UNIX)的文件/dev/log中。rsyslogd则监听该文件以获取用户进程的输出内核日志在老系统上是通过守护进程rkl

2021-11-22 20:59:41 831

原创 可执行文件的装载与进程

可执行文件的装载与进程进程虚拟地址空间程序是一个静态的概念,是一些预先编译好的指令和数据集合的一个文件进程是一个动态的概念,是程序运行时的一个过程C语言指针大小的位数与虚拟空间的位数相同#include<stdio.h>int main(){ int a = 10; int* p = &a; printf("%ld\n",sizeof(p));//8 可得出64位平台下指针位64位,即8字节 return 0;}程序在运行时处于操作系

2021-11-22 14:43:57 994 1

原创 Linux网络编程基础API

Linux网络编程基础APIsocket地址APIsocket地址:一个IP地址和端口对(ip,port),唯一表示了使用TCP通信的一端字节序大小端字节序32位机的CPU累计器一次能装载(至少)4字节,即一个整数。这4个字节在内存中的排列顺序将影响其被累加器装载成的整数的值大端字节序(MSB):一个整数的高位字节(2331bit)存储在内存低地址处,低位字节(07bit)存储在内存高地址处小端字节序(LSB):一个整数的高位字节(2331bit)存储在内存高地址处,低位字节(07bi

2021-11-21 20:54:35 2420 1

原创 高级IO函数

高级I/O函数pipe函数//创建一个管道,实现进程间通信#include<unistd.h>int pipe(int fd[2]);//成功时返回0并将一对打开的文件描述符值填入其参数指向的数组。失败返回-1并设置errno//fd[0]只能用于从管道读取数据//fd[1]只能用于往管道写入数据//实现双向通信需要使用两个管道//默认情况下这一对文件描述符时阻塞的。如果用read系统调用读取一个空的管道,read将被阻塞,直到管道中有数据可读//如果用write系统调

2021-11-21 20:52:42 1818

原创 静态链接的一些东西

静态链接//a.c#include"b.h"extern int shared;int main(){ int a = 100; swap(&a,&shared);}//b.c#include"b.h"int shared = 1;void swap(int* a,int* b){ *a ^= *b ^= *a ^= *b;}//gcc -c a.c b.c//得到a.o b.o//如何将a.o和b.o链接在一起形成一个可执行文件

2021-11-19 11:55:24 593

原创 目标文件里有什么

2021-11-17 22:34:11 58

原创 编译和链接

2021-11-16 20:14:09 50

原创 GoWeb

GoWebGoWeb应用原理[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jKcRfp9k-1623597877761)(C:\Users\51936\AppData\Roaming\Typora\typora-user-images\image-20210411115121803.png)]创建一个web应用在终端执行命令在目录中右键→在命令提示符中打开执行 go build main.go 命令;然后在当前目录中就会生成一个 main.exe 的二进制可执行

2021-06-13 23:24:58 228

原创 面向对象程序设计OOP

面向对象程序设计OOPOPP概述核心思想数据抽象:将类的接口和实现分离继承:定义相似的类型并对其相似关系建模动态绑定:在一定程度上忽略相似类型的区别,以统一的方式使用其对象继承通过继承联系在一起的类构成一种层次关系,通常在层次关系的根部有一个基类,其他类则直接或间接地从基类继承而来,这些继承得到的类称为派生类,基类定义在层次关系中所有类共同拥有的成员,而每个派生类定义各自持有的成员某些函数,基类希望其派生类各自定义适合自身的版本,此时基类就将这些函数声明成虚函数允许派生类显式注

2021-06-13 23:22:43 168

原创 重载运算与类型转换

重载运算与类型转换基本概念重载的运算符是具有特殊名字的函数,operator运算符号返回类型、参数列表、函数体如果一个运算符函数是成员函数,则其第一个运算对象绑定到隐式的this指针上,因此成员运算符函数的(显式)参数数量比运算符的运算对象总数少一个运算符函数或者是类的成员,或者至少含有一个类类型的参数//int operator+(int,int);//不能为int重定义内置运算符不能被重载的运算符:: .* . ?:直接调用一个重载的运算符函

2021-06-11 12:07:04 322 2

原创 C++动态内存

动态内存动态分配的对象的生存期与其在哪创建无关,只有当显式地被释放时,对象才会被销毁动态内存和智能指针new:在动态内存中为对象分配空间并返回一个指向该对象的指针delete接受一个动态对象的指针,销毁该对象,并释放与之关联的内存shared_ptr类为模板,当创建一个智能指针时,必须提供额外的信息——指针可以指向的类型允许多个指针指向同一个对象shared_ptr<string>p1;//可以指向stringshared_ptr<list<int&gt

2021-06-07 22:28:57 130 4

原创 C++关联容器

关联容器关联容器中的元素是按关键字保存和访问的,顺序容器中的元素按其在容器中的位置顺序保存和访问的map与multimap定义在头文件map中,set与multiset定义在头文件set中,无序容器定义在头文件unordered_map和unordered_set中关联容器的迭代器都是双向的关联容器概述定义关联容器每个关联容器都定义了一个默认构造函数,其创建一个指定类型的空容器map<string,size_t>word_count;//空容器//列表初始化set&lt

2021-06-07 14:27:19 84 1

原创 C++泛型算法

泛型算法大多数算法都定义在头文件algorithm,标准库在在头文件numeric中定义一组数值泛型算法一般算法并不直接操作容器,而是遍历由两个迭代器指定的一个元素范围操作(输入范围)初识泛型算法只读算法只读取其输入范围内的元素,不改变元素findaccumulate包含在numeric中equal用于确定两个序列是否保存相同的值int sum = accumulate(vec.cbegin(),vec.cend(),0);//前两个参数指出了需要求和的元素的范围,第三个参数是和

2021-06-06 16:24:09 100

原创 C++顺序容器

顺序容器vector可变大小数组。支持快速随机访问。在尾部之外的位置插入或删除元素可能很慢deque双端队列。支持快速随机访问。在头尾位置插入/删除速度很快list双向链表。只支持双向顺序访问。在list中任何位置进行插入/删除操作速度都很快forword_list单向链表。只支持单向顺序访问。在链表任何位置进行插入/删除操作速度都很快array固定数组大小。支持快速随机访问。不能添加或删除元素string与vector相似的容器,但专门用于保存字符

2021-06-02 12:39:07 140 1

原创 C++IO库

IO库IO类iostream头文件istream、wistream从流读取数据ostream、wostream向流写入数据iostream、wiostream读写流fstream头文件ifstream、wistream从文件读取数据ofstream、wofstream向文件写入数据fstream、wfstream读写文件sstream头文件istringstream、wistringstream从string读取数据ostringstream、wostrings

2021-06-01 20:22:34 85

原创 C++函数

函数参数传递数组形参void print(const int*);void print(const int[]);void print(const *int[10]);//等价数组引用形参void print(int (&arr)[10]){ for(auto elem : arr) cout<<elem<<endl;}int i=0,j[2]={0,1};int k[10]={0,1,2,3,4,5,6,7,8,9};//

2021-05-31 16:50:48 107

原创 异常处理语句

语句范围for语句for(declaration:expression) statementvector<int>v={0,1,2,3,4,5,6};for(auto &r :v)//对于v中的每一个元素 R *= 2;//将v中每个元素的值乘2try语句块和异常处理C++中异常处理throw表达式,异常检测部分使用throw表达式表示其遇到了无法处理的问题。throw引发了异常try语句块,异常处理部分使用try语句块处理异常,try语句块以关键

2021-05-31 14:15:57 522

原创 字符串、向量和数组

字符串、向量和数组标准库类型string可变长的字符序列包含string头文件定义和初始化string对象string s1;//默认初始化,s1是一个空串string s2(s1);string s2 = s1;//s2是s1的副本string s3("value");string s3="value";string s4(n,'c');//把s4初始化为由连续n个字符c组成的串直接初始化与拷贝初始化使用**=**:拷贝初始化,编译器将等号右侧的初始值拷贝到新创

2021-05-31 13:36:03 90

原创 变量和基本类型

C++为静态类型语言,在编译阶段检查类型编译器负责检查数据类型是否支持要执行的运算,如果不支持,编译器将报错变量和基本类型基本内置类型算术类型空类型算术类型整型(包括字符和布尔类型)浮点型类型转换将非布尔类型的算术值赋给布尔类型时,初始值为0结果为false,否则结果为true将布尔类型赋给非布尔类型时,初始值为false结果为0,否则结果为1赋给带符号类型一个超出其表示范围的值时,结果为未定义,程序可能继续工作、崩溃、或产生垃圾数据变量初始化int a=.

2021-05-30 23:23:58 72

原创 Go运算符

Go运算符算术运算符对数值型变量进行运算package mainimport( "fmt")func main(){ // /的使用 //如果运算的数都是整数,那么除后去掉小数部分,保留整数部分 fmt.Println(10/4)//2 var n1 float32 = 10/4 //n1为2 fmt.Println(n1) //如果希望保留小数部分,需要有浮点数参与运算 var n2 float32 = 10.0/4 fmt.Println(n2) // %

2021-05-28 20:53:12 136

原创 Go文件操作

Go文件操作文件是数据源(保存数据的地方)的一种输入流与输出流文件在程序中是以流的形式来操作的流:数据在数据源(文件)和程序(内存)之间经历的路径输入流:数据从数据源(文件)到程序(内存)的路径输出流:数据从程序(内存)到数据源(文件)的路径os.File封装所有文件操作,File是一个结构体常用文件操作和方法打开与关闭文件func Open(name string)(file *File,err error)Open打开一个文件用于读取,如果操作成功,返回的文件对象的方

2021-05-28 20:52:05 51

原创 Go数组与切片

Go数组与切片数组package mainimport( "fmt")func main(){ //数组的定义 /* var 数组名 [数组大小]数据类型 */ var intArr [3]int //定义完数组后,数组的各个元素都有默认值0 fmt.Println(intArr)//[0 0 0] //数组的地址可以通过数组名来获取&intArr //数组第一个元素的地址就是数组的首地址 //数组的各个元素的地址间隔是由数组类型决定 //初始化数组 var

2021-05-28 20:51:23 40

原创 Go面向对象三大特性

Go面向对象三大特性三大特性之一:封装把抽象出的字段和对字段的操作封装在一起,数据被保护在内部,程序的其他包只有通过授权的操作(方法)才能对字段进行操作封装好处隐藏实现细节对数据进行验证,保证安全合理体现封装对结构体中的属性进行封装通过方法,包实现封装封装实现将结构体、字段的首字母小写给结构体所在包提供一个工厂模式的函数,首字母大写提供一个首字母大写的Set方法,用于对属性判断并赋值func (var 结构体类型名)SetXXX(参数列表)(

2021-05-28 20:50:47 122

空空如也

空空如也

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

TA关注的人

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