- 博客(125)
- 收藏
- 关注
原创 [项目]云备份项目
云备份系统搭建云备份服务器与客⼾端,客⼾端程序运⾏在客⼾机上⾃动将指定⽬录下的⽂件备份到服务器,并且能够⽀持浏览器查看与下载,其中下载⽀持断点续传功能,并且服务器端对备份的⽂件 进⾏热点管理,将⻓时间⽆访问⽂件进⾏压缩存储。centos7.6/vim、g++、gdb、makefile 以及 windows10/vs2017http 客⼾端/服务器搭建, json 序列化,⽂件压缩,热点管理,断点续传,线程池, 读写锁,单例模式。
2025-08-11 01:52:02
403
原创 MySQL内置函数
在显示评论信息时,如果只想显示评论的日期而不显示评论的时间,可以在查询sendtime字段时,通过date函数截取sendtime的日期部分进行显示。对于多字节字符来说,不同编码中一个字符所占的字节个数是不同的,比如utf8中一个字符占用3个字节,而gbk中一个字符占用2个字节。现有如下成绩表,要求以“XXX的语文是XX分,数学是XX分,英语是XX分”的格式显示成绩表中的信息。需要注意的是,向下取整本质是向负无穷方向取整,因此负数向下取整后得到的是第一个小于等于该数的整数。
2025-07-30 00:13:29
646
原创 MySQL表的增删查改
在select的column列表中添加表达式查询,查询的表达式为语文、数学和英语成绩之和,为了方便观察可以将表达式对应的列指定别名为“总分”,在where子句中指明筛选条件为三科成绩之和小于200。需要注意的是,MySQL中不支持+=这种复合赋值运算符,此外,这里在查看更新后的数据时不能查看总成绩倒数前三的3位同学,因为之前总成绩倒数前三的3位同学,数学成绩加上30分后可能就不再是倒数前三了。
2025-07-28 18:04:53
1450
原创 MySQL表的约束
创建客户表的时候,将客户编号设置成主键并且可以将其设置成自增长字段,然后给姓名设置not null属性,将邮箱设置成唯一键,将性别设置成enum类型并仅提供男女性别选项,此外,题目虽然没有对身份证做要求,但正常来说身份证也应该保证唯一性,最好也设置成唯一键。查看表中插入的数据可以看到,表当中有重复的IP地址,也有重复的端口号,但是不会出现IP和端口均重复的,这就是复合主键的作用,复合主键可以有多个相同的key值但是必须保证有一个key值是唯一的。
2025-07-26 18:34:07
1126
原创 MySQL的数据类型
此外,由于MySQL在保存值时会进行四舍五入,因此实际可插入float(4,2)的范围为-99.994~99.994,如果插入的数据不在该范围内,那么插入数据时就会产生报错。无符号float类型的取值范围,实际就是把对应有符号float类型中的负数部分拿走了,因此float(4,2)的取值范围为0~99.99,实际可插入的范围是0~99.994。向表中插入一条记录,记录中指定id和a的值均为10,插入记录后查看表会发现a的值显示的十六进制的10(mysql的版本不同可能bit类型的呈现方式不一样)。
2025-07-25 17:03:49
1070
原创 MySQL表的基本操作
原本应该是三个文件,还有一个.frm(表结构),由于未使用的是MySQL 8.0 及之后的版本,默认使用 InnoDB 存储引擎,并且将表结构元数据存储在。新增列SQL中的after表示将该列新增到哪一列之后,如果想要将新增的列放到第一列,可以将after及其之后的SQL换成not null first。修改表的过程中可能会影响到表中的数据,为了演示这个过程,我们在修改表之前先在user表中插入两条数据。本篇博客讲的是表的DDL操作,也就是操作表结构的SQL语句。将user表的表名改成employee。
2025-07-24 15:51:46
592
原创 MySQL数据库基础
也就是说,MySQL服务器本质是一个网络服务器,我们使用mysql命令连接MySQL服务器时,本质就是MySQL客户端在向MySQL服务器发起连接请求,连接建立成功后MySQL客户端就会将用户输入的SQL语句发送给MySQL服务器,之后MySQL服务器就会根据SQL语句对数据进行对应的操作。存储引擎就是数据库管理系统如何存储数据、如何为存储的数据建立索引、如何更新数据、如何查询数据等技术的实现方法,MySQL中的存储引擎是插件式的存储引擎,它可以支持多种存储引擎。
2025-07-23 14:36:26
675
原创 [项目] 高并发内存池(C++)
1.池化技术所谓“池化技术”,就是程序先向系统申请过量的资源,然后⾃⼰管理,以备不时之需。之所以要申 请过量的资源,是因为每次申请该资源都有较⼤的开销,不如提前申请好了,这样使⽤时就会变得⾮ 常快捷,⼤⼤提⾼程序运⾏效率。在计算机中,有很多使⽤“池”这种技术的地⽅,除了内存池,还有连接池、线程池、对象池等。以 服务器上的线程池为例,它的主要思想是:先启动若⼲数量的线程,让它们处于睡眠状态,当接收到 客⼾端的请求时,唤醒池中某个睡眠的线程,让它来处理客⼾端的请求,当处理完这个请求,线程⼜进⼊睡眠状态。
2025-07-21 21:15:43
1277
原创 I/O多路转接 —— epoll
其中文件描述符0、1、2是默认打开的,分别对应的是标准输入、标准输出和标准错误,3号文件描述符对应的是服务器创建的epoll模型,4号文件描述符对应的是监听套接字,5号和6号文件描述符对应的分别是正在访问服务器的两个客户端。在epoll中,对于每一个事件都会有一个对应的epitem结构体,红黑树和就绪队列当中的节点分别是基于epitem结构中的rbn成员和rdllink成员的,epitem结构当中的成员ffd记录的是指定的文件描述符值,event成员记录的就是该文件描述符对应的事件。
2025-07-17 14:36:07
912
原创 I/O多路转接 —— select, poll
当我们借助telnet工具向select服务器发起连接请求后,select函数就会立马检测到监听套接字的读事件就绪,此时select函数便会成功返回,并将我们设置的提示语句进行打印输出,因为当前程序并没有对就绪事件进行处理,此后每次select函数一调用就会检测到读事件就绪并成功返回,因此会看到屏幕不断打印输出提示语句。此时如果select监视的文件描述符上有事件就绪,那么select函数的返回值就是大于0的,如果select监视的文件描述符上没有事件就绪,那么select的返回值就是等于0的。
2025-07-15 13:51:47
899
原创 五种IO模型
因此在以非阻塞方式读取数据时,如果调用read函数时得到的返回值是-1,此时还需要通过错误码进一步进行判断,如果错误码的值是EAGAIN或EWOULDBLOCK,说明本次调用read函数出错是因为底层数据还没有就绪,因此后续还应该继续调用read函数进行轮询检测数据是否就绪,当数据继续时再进行数据的读取。阻塞IO和非阻塞IO的区别在于,阻塞IO当数据没有就绪时,后续检测数据是否就绪的工作是由操作系统发起的,而非阻塞IO当数据没有就绪时,后续检测数据是否就绪的工作是由用户发起的。
2025-07-12 18:03:38
747
原创 TCP相关实验
现在我们让telnet退出,就相当于客户端向服务器发起了连接断开请求,但此时服务器端并没有调用close函数关闭对应的文件描述符,所以当telnet退出后,客户端维护的连接的状态会变为FIN_WAIT_2,而服务器维护的连接的状态会变为CLOSE_WAIT。当面试官让你用UDP实现可靠传输时,你一定要立马想到TCP协议,因为TCP协议就是当前比较完善的保证可靠性的协议,面试官让你用UDP这个不可靠的协议来实现可靠传输,无非就是让你在应用层来实现可靠性,此时就可以参考TCP协议保证可靠性的各种机制。
2025-07-06 08:35:44
803
原创 传输层协议——TCP协议
例如图中的1001-2000的数据包如果在传输过程中丢包了,此时虽然2001-5000的数据都被对方收到了,此时对方发来的确认序号也只能是1001,当发送端补发了1001-2000的数据包后,对方发来的确认序号就会变为5001,此时发送缓冲区当中1001-5000的数据也会立马被归置到滑动窗口的左侧。TCP建立连接,数据通信,断开连接,一定会发送TCP报文,TCP发送的报文一定是各种类型的,不同的类型,决定了服务端要做不同的动作,接收方如何得知,报头的类型各自是什么呢?
2025-06-30 18:21:52
1192
原创 传输层协议——UDP协议
而socket接口往下的传输层实际就是由操作系统管理的,因此UDP是属于内核当中的,是操作系统本身协议栈自带的,其代码不是由上层用户编写的,UDP的所有功能都是由操作系统完成,因此网络也是操作系统的一部分。UDP就是通过报头当中的目的端口号来找到对应的应用层进程的。需要注意的是,UDP协议报头当中的UDP最大长度是16位的,因此一个UDP报文的最大长度是64K(包含UDP报头的大小)。报文在网络中进行路由转发时,并不是每一个报文选择的路由路径都是一样的,因此报文发送的顺序和接收的顺序可能是不同的。
2025-06-26 12:44:54
1047
原创 应用层协议——HTTP协议
HTTP(yperText Transfer Protocol)协议又称超文本协议,是一个简单的请求-响应协议,HTTP通常运行在TCP之上URL叫做统一资源定位符,也就是外面平常上网所看到的网址,是因特网的万维网服务程序上用于指定信息位置的表示方法一个完整的URL大致由以下几部分构成:协议方案名http://协议方案名称,表示请求时需要使用的协议,通常使用的是HTTP协议或安全协议HTTPS。HTTPS是以安全为目标的HTTP通道,在HTTP的基础上通过传输加密和身份认证保证了传输过程的安全性。
2025-06-13 12:26:16
846
原创 C++ IO流
使用itoa函数进行转化。int a = 10;//将整型的a转化为十进制字符数字存储在字符串arr当中使用sprintf函数进行转化。int a = 10;//将整型的a转化为字符串格式存储在字符串arr当中虽然itoa函数和sprintf函数都能完成转化,但是在两个函数在转化时,都需要先给出保存结果的空间,而空间的大小是不太好界定的,除此之外,转化格式不匹配时,可能还会得到错误的结果甚至程序崩溃。在C++中,我们可以使用stringstream类对象来避开此问题。
2025-05-18 10:41:57
881
1
原创 Linux任务管理与守护进程
每当有一个用户登录Linux时,系统就会创建一个会话(session)任何进程都可以被设置为前台进程,只要前台进程被干掉系统会自动的将bash放到前台变成前台进程我下面写了一个死循环,创建一个文件 test.cc 测试它被干掉之后bash进程是否会自动顶替它可以看到在a.out运行期间不管我们输入多少次指令都是没有响应的,原因就是此时的前台进程已经不是bash了,当我们使用ctrl + c。
2025-05-16 19:10:59
770
原创 STL,智能指针和线程安全&&自选锁&&读者写者问题
不是.原因是, STL 的设计初衷是将性能挖掘到极致, 而一旦涉及到加锁保证线程安全, 会对性能造成巨大的影响. 而且对于不同的容器, 加锁方式的不同, 性能可能也不同(例如hash表的锁表和锁桶). 因此 STL 默认不是线程安全. 如果需要在多线程环境下使用, 往往需要调用者自行保证线程安全.
2025-05-14 14:25:40
618
原创 unordered_map和unordered_set的介绍和使用
方式一: 指定key和value的类型构造一个空容器。//构造一个key为int类型,value为double类型的空容器方式二: 拷贝构造某同类型容器的复制品。//拷贝构造同类型容器um1的复制品方式三: 使用迭代器拷贝构造某一段内容。//使用迭代器区间构造方式一: 构造一个某类型的空容器。//构造int类型的空容器方式二: 拷贝构造某同类型容器的复制品。//拷贝构造同类型容器us1的复制品方式三: 使用迭代器拷贝构造某一段内容。//构造string对象某段区间的复制品。
2025-05-14 12:15:50
917
原创 网络编程套接字(一)
如果一台主机上的数据要传输到另一台主机,那么就应该作为该数据传输时的。但仅仅知道目的IP地址是不够的,当对端主机收到该数据后,对端主机还需要对该主机做出响应,因此对端主机也需要发送数据给该主机,此时对端主机就必须知道。因此一个传输的数据当中应该涵盖其和,目的IP地址表明该数据传输的目的地,源IP地址作为对端主机响应时的目的IP地址。在数据进行传输之前,会先完成数据的封装,其中在网络层封装的IP报头当中就涵盖了源IP地址和目的IP地址。
2025-05-05 11:55:42
964
9
原创 线程池&&单例模式
单例模式是一种 "经典的, 常用的, 常考的" 设计模式.IT行业这么火, 涌入的人很多. 俗话说林子大了啥鸟都有. 大佬和菜鸡们两极分化的越来越严重. 为了让菜鸡们不太拖大佬的后腿, 于是大佬们针对一些经典的常见的场景, 给定了一些对应的解决方案, 这个就是 设计模式。
2025-04-26 22:24:05
1282
原创 哈希的应用 ——> 布隆过滤器
我们在使用新闻客户端看新闻时,它会给我们不停地推荐新的内容,它每次推荐时要去重,去掉 那些已经看过的内容。问题来了,新闻客户端推荐系统如何实现推送去重的?用服务器记录了用 户看过的所有历史记录,当推荐系统推荐新闻时会从每个用户的历史记录里进行筛选,过滤掉那 些已经存在的记录。如何快速查找呢?
2025-04-25 11:39:06
839
原创 【STL】bitset(位图) 的介绍,使用,模拟实现
给40亿个不重复的无符号整数,没排过序。给一个无符号整数,如何快速判断一个数是否在这40亿个数中?将这一堆数进行排序,然后通过二分查找的方法判断该数是否在这一堆数中。将这一堆数插入到unordered_set容器中,然后调用find函数判断该数是否在这一堆数中。单从方法上来看,这两种方法都是可以,而且效率也不错,第一种方法的时间复杂度是O (NlogN) ,第二种方法的时间复杂度是O(N)。但问题是这里有40亿个数,若是我们要将这些数全部加载到内存当中,那么将会占用16G的空间,空间消耗是很大的。
2025-04-24 23:21:36
970
原创 C++11 线程库
由于thread提供了移动赋值函数,因此当后续需要让该线程对象与线程函数关联时,可以以带参的方式创建一个匿名对象,然后调用移动赋值将该匿名对象关联线程的状态转移给该线程对象。线程函数的参数是以值拷贝的方式拷贝到线程栈空间中的,就算线程函数的参数为引用类型,在线程函数中修改后也不会影响到外部实参,因为其实际引用的是线程栈中的拷贝,而不是外部实参。当线程函数的参数类型为引用类型时,如果要想线程函数形参引用的是外部传入的实参,而不是线程栈空间中的拷贝,那么在传入实参时需要借助ref函数保持对实参的引用。
2025-04-23 21:45:53
984
原创 Linux 生产者消费者模型
生产者和消费者彼此之间不直接通讯,而通过这个容器来通讯,所以,这个容器就相当于一个缓冲区,平衡了生产者和消费者的处理能力,这个容器实际上就是用来给生产者和消费者解耦的。
2025-04-20 14:57:56
1046
原创 Linux 线程互斥
对一个全局变量进行多线程并发 -- / ++ 操作是否是安全的?运行结果显然不符合我们的预期,因为其中出现了剩余票数为负数的情况。为什么无法获得预期结果?--ticket为什么--ticket操作不是一个原子操作?-- 操作并不是原子操作,而是对应三条汇编指令:loadupdatestore我们取出--tickets的汇编代码既然--
2025-04-18 23:52:17
1080
原创 Linux 多线程
1. 如果thread线程通过return返回,retval所指向的单元里存放的是thread线程函数的返回值。2. 如果thread线程被别的线程调用pthread_cancel异常终止掉,retval所指向的单元里存放的是常数PTHREAD_CANCELED。3. 如果thread线程是自己调用pthread_exit终止的,retval所指向的单元存放的是传给pthread_exit的参数。4. 如果对thread线程的终止状态不感兴趣,可以传NULL给retval参数。用grep。
2025-04-10 21:52:51
1120
1
原创 Linux 进程信号
其中1~31号信号是普通信号,34~64号信号是实时信号,普通信号和实时信号各自都有31个,每个信号都有一个编号和一个宏定义名称,这些宏定义可以在/usr/include/x86_64-linux-gnu/bits/signum-generic.h 中找到,例如其中有定义: #define SIGINT 2信号是如何记录的?实际上,当一个进程接收到某种信号后,该信号是被记录在该进程的进程控制块当中的。
2025-04-04 17:06:28
1398
10
原创 system V 消息队列&&信息量(了解)
msgget函数创建消息队列创建消息队列也需要使用ftok函数生成一个key值,这个key值作为msgget函数的第一个参数。msgget函数的第二个参数,与创建共享内存时使用的shmget函数的第三个参数相同。消息队列创建成功时,msgget函数返回的一个有效的消息队列标识符(用户层标识符),否则,返回-1,错误原因存于error中。shmget有设置大小的参数,而msgget没有消息队列的释放msgctl函数释放消息队列。
2025-03-26 16:50:42
1000
原创 Linux 进程间通信
进程间通信简称IPC(Interprocess communication),进程间通信就是在不同的进程之间的传播或交换信息管道是Unix中最古老的进程间通信的形式。我们把从一个进程连接到另一个进程的一个数据流称为一个“管道”例如:统计我们当前使用云服务器上的登录用户个数其中who命令和wc命令都是两个程序,当它们运行起来后就变成了两个进程,who进程通过标准输出将数据打到 “管道” 当中,wc进程再通过标准输入从 ”管道“ 当中读取数据,至此便完成了数据的传输,进而完成数据的进一步加工处理。
2025-03-25 23:41:00
945
原创 Linux 动静态库
完成头文件展开,去掉注释,宏替换,条件编译等,最后形成xxx.i文件完成词法分析,语法分析,语义分析,符号汇总等,最终形成xxx.s文件将汇编指令转换成二进制指令,最终形成xxx.o文件将生成的各个xxx.o文件链接例如:用 a.c b.c c.c d.c 以及main.c形成可执行文件,我们需要先得到这些文件的目标文件(二进制文件)a.o b.o c.o d.o 以及main.o,然后将这些目标文件链接起来,最后形成一个可执行文件。
2025-03-11 13:07:59
953
2
原创 Linux 软硬链接
与软连接不同的是,当硬链接的源文件被删除,硬链接文件依旧能正常执行,只是文件的硬链接数减少了一个,因为此时该文件的文件名少了一个,所谓的建立硬链接,本质就是在特定目录的数据块中新增文件名和指向文件名的inode编号的映射关系。命令我们可以看到,硬链接文件的inode编号和源文件是相同的,并且硬链接文件大小与源文件大小也是相同的,特别注意的是,当创建了一个硬链接文件后,该硬链接文件和源文件的硬链接数(引用计数)都变成了2。1. 软连接是一个独立的文件,有独立的inode,而硬链接没有独立的inode。
2025-03-07 21:43:56
815
1
原创 LInux 文件系统
线性存储介质理解文件系统,首先我们必须将磁盘想象成一个线性的存储介质,例如磁带,当磁带被卷起来时,其就像磁盘一样是圆形的,当我们将磁带拉直后,它就是线性的抽象理解磁盘从逻辑结构来看,磁盘是线性的,所以为了更好的理解磁盘,我们将磁盘理解成一个数组所以我们可以根据下标28888反推回它在线性结构的那个区域,然后进行访问一个磁盘有5个盘片,每个盘面有2w给扇区每个盘面50个磁道,每个磁道400个扇区1.确定在那一面28888 / 20000 = 1面(从第0面开始),它在第一面2.在哪一个扇区。
2025-03-06 22:41:52
1065
原创 C++的类型转换
由于编译器认为const修饰的变量是不会被修改的,因此会将const修饰的变量存放到寄存器当中保存,当需要读取const变量是就会直接从寄存器中进行读取,而我们修改的实际上是内存中变量 a的值,因此打印出来的是修改之前变量a的值。上述代码中,如果传入fun函数的是子类对象的地址,那么在转换后pb1和pb2都会有对应的地址,但如果传入func函数的是父类对象的地址,那么pb1会有对应的地址,而pb2则会返回一个空指针。向上转换是语法天然支持的,不需要进行转换,而向下转换是语法不支持的,需要进行强制类型转换。
2025-03-02 22:53:13
1006
1
原创 Linux基础IO
当fopen以写入的方式打开一个文件时,若文件不存在,则会自动在当前路径创建该文件,那么这里所说的当前路径指的是什么呢?例如,我们在test_2_26目录下运行可执行程序myproc,那么该可执行程序创建的log.txt文件会出现在test_2_26目录下这里是否能说明的“当前路径”是指当前可执行程序所处的路径这时我们删除刚才可执行程序生成的log.txt先删除测试一下:回退到上级目录,在上级目录下运行该可执行程序。
2025-03-01 21:21:53
725
1
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人