- 博客(108)
- 收藏
- 关注
原创 函数栈帧的创建与销毁
我们在编程的过程中经常会听见函数栈帧这个词汇,那到底什么是函数栈帧呢?接下来就为大家解答一下,我们都知道,一个函数的创建是需要去开辟空间的,而且是在栈区上面开辟的空间(静态函数除外),而这个开辟空间的行为,我们就可以去称之为函数栈帧的创建,当然,他也不仅仅只是单纯的去开辟空间,还伴随着一些其他的行为,后面我们会介绍到。当我们调用完一个函数完毕以后,就会去释放掉申请的空间,这个过程也就称之为函数栈帧的销毁。函数开辟空间是用来干什么呢?
2025-04-04 23:27:21
1081
原创 C++之设计模式
设计模式是前辈们对代码开发经验的总结,是解决特定问题的⼀系列套路它不是语法规定,而是⼀套⽤来提高代码可复用性、可维护性、可读性、稳健性以及安全性的解决⽅案。设计模式的六大原则单⼀职责原则(Single Responsibility Principle)(1)类的职责应该单一,一个⽅法只做⼀件事。职责划分清晰明了,每次改动到最小单位的方法或类。(2)使用建议:两个完全不⼀样的功能不应该放⼀个类中,⼀个类中应该是⼀组相关性很高的函数、数据的封装。
2024-12-31 00:22:55
740
原创 C/C++不定参数
在C++中,我们就可以使用template来定义一个可变模版参数,最终通过可变模版参数来解决问题,其实他也是运用的递归的原理,递归的去对每一个参数进行调用,我们在这儿定义一个空的xprintf的作用就在于最后递归调用过去为空时就会发生一些问题,所以我们在这儿就定义一个空的调用,调用到最后打印一个换行符就可以了。当然,上面这一段代码是针对于某个特定的类型来说的,如果我们需要打印的是字符串的话,就需要使用到我们的vasprintf函数。它的作用是初始化一个。类型的变量和可变参数的最后一个固定参数的地址。
2024-12-28 15:16:09
1126
1
原创 自主HTTP服务器实现
HTTP(Hyper Text Transfer Protocol)协议又叫做超文本传输协议,是一个简单的请求-响应协议,HTTP通常运行在TCP之上。CGI(Common Gateway Interface,通用网关接口)是一种重要的互联网技术,可以让一个客户端,从网页浏览器向执行在网络服务器上的程序请求数据。CGI描述了服务器和请求处理程序之间传输数据的一种标准。
2024-02-28 14:30:51
845
原创 高并发内存池项目
目录项目简介什么是内存池池化技术内存池内存池主要解决的问题定长内存池的设计高并发内存池的整体框架设计thread cachethread cache的整体设计thread cache哈希桶的对齐规则threadcacheTLS无锁访问central cachecentralcache整体设计central cache 结构设计central cache核心实现page cachepage 整体设计page cache结构设计page cache 中获取一个非空span申请内存过程联调threadcache回
2024-02-05 12:00:21
1069
原创 MySQL视图特性
视图的数据变化会影响到基表,基表的数据变化也会影响到视图。并且在数据库对应的目录下,会增加一个对应的xxx.frm文件,但并没有与之对应的xxx.ibd文件,这也证明了视图和基表使用的是同一份数据。当我们要查询每个员工及其对应的部门名称时,需要使用员工表和部门表进行多表查询,并筛选出员工的部门号等于部门的部门号的记录。下面用员工表和部门表作为测试表,员工表中的ename代表的是员工的姓名,deptno代表的是员工所在部门的部门号。部门表中的dname代表的是部门名,deptno代表的是部门的部门号。
2024-01-03 23:19:44
706
1
原创 MySQL事务管理
其中隔离级别越严格,安全性越高,但数据库的并发性能也就越低,往往需要在两者之间找一个平衡点;不可重复读的重点是修改和删除:同样的条件,你读取过的数据,再次读取出来发现值不一样了;幻读的重点在于新增:同样的条件,第1次和第2次读出来的记录数不一样;说明: mysql 默认的隔离级别是可重复读,一般情况下不要修改;上面的例子可以看出,事务也有长短事务这样的概念。事务间互相影响,指的是事务在并行执行的时候,即都没有commit的时候,影响会比较大。隔离级别脏读不可重复读幻读加锁读。
2023-12-31 00:09:53
906
原创 MySQL索引
所谓的操作系统与磁盘IO的基本交互为4KB,其实是指内核缓冲区与磁盘之间是以4 KB进行数据交互的,而MySQL与磁盘之间并不是直接进行交互的,所以MySQL与磁盘之间交付的基本单位是16KB指的是MySQL与内核缓冲区交互的基本单位是16KB,只不过在说的时候更关注的是MySQL和磁盘之间的关系,所以直接说的是MySQL与磁盘交互的基本单位是16KB,相当于忽略了中间的内核缓冲区。它有着更高的IO场景,所以,为了提高基本的IO效率, MySQL 进行IO的基本单位是 16KB。
2023-12-25 23:14:36
175
1
原创 MySQL内外连接
内连接实际上就是利用where子句对两种表形成的笛卡儿积进行筛选,我们前面学习的查询都是内连接,也是在开发过程中使用的最多的连接查询。题目要求学生没有成绩也要讲个人信息显示出来,我们就可以使用左外连接,当左边表和右边表没有匹配时,也会显示左边表的数据。对stu表和exam表联合查询,把所有的成绩都显示出来,即使这个成绩没有学生与它对应,也要显示出来。为了方便进行演示,我们创建两张表,一张学生表,一张成绩表并插入数据。右外连接跟左外连接的道理一样,即使这个学生没有成绩也要将他显示出来。
2023-12-23 22:27:34
215
原创 MySQL复合查询
然后将上述查询作为子查询,在查询员工表时在where子句中使用in关键字,判断员工的工作岗位是子查询得到的若干岗位中的一个,如果是则符合筛选条件,由于要求筛选出来的员工不包含10号部门的,因此还需要在where子句中指明筛选条件为部门号不等于10。先查询30号部门员工的工资,在查询时最好对结果进行去重,因为30号部门的某些员工的工资可能是相同的,然后将上述查询作为子查询,在查询员工表时在where子句中使用all关键字,判断员工的工资是否高于子查询得到的所有工资,如果是则符合筛选条件。
2023-12-22 23:53:27
169
原创 MySQL内置函数
rand函数用于生成0.0到1.0的随机浮点数,如果想要生成0到100的随机数,可以用生成的随机浮点数乘以100,然后再以某种取整方式进行取整。有如下成绩表,要求显示exam_result表中的信息,显示格式:“XXX的语文是XXX分,数学XXX分,英语XXX分”。strcmp函数用于逐字符按照ASCII码比较两个字符串的大小,两个字符串大小相等返回0,前者大返回1,后者大返回-1。substring函数用于从字符串的指定位置开始,向后截取指定个数的字符。
2023-12-21 09:41:59
94
原创 MySQL表的约束
真正约束字段的是数据类型,但是数据类型约束很单一,需要有一些额外的约束,更好的保证数据的合法性,从业务逻辑角度保证数据的正确性。比如有一个字段是email,要求是唯一的。表的约束很多,这里主要介绍如下几个: null/not null,default, comment, zerofill,primary,key,auto_increment,unique key。
2023-12-18 10:47:57
141
原创 MySQL数据类型
MySQL本身是不支持bool类型的,当把一个数据设置成bool类型时,数据库会自动将其转换成tinyint(1)的数据类型,其实这个就是变相的bool类型,因为tinyint(1)只有1和0两种取值,可以分别对应bool类型的true和false。该设定只是提供了若干个选项的值,最终一个单元格中,实际只存储了其中一个值;在MySQL中,整型可以指定是有符号的和无符号的,默认是有符号的,可以通过UNSIGNED来说明某个字段是无符号的,接下来我们来看一下无符号类型tinyint测试。
2023-12-15 13:12:39
129
原创 MySQL表的操作
在项目实际开发中,经常修改某个表的结构,比如字段名字,字段大小,字段类型,表的字符集类型,表的存储引擎等等。我们还有需求,添加字段,删除字段等等。这时我们就需要修改表。若不使用可选参数进行指定,则新增列在表的最后。在修改现有表时,要确保新增列与现有列不会产生冲突或重复。我们在user1表中添加一列用来保存用户电话号码。示例:需要将user1修改表名为employee。MySQL 数据库表中添加列,可以使用。示例1:修改name,将其长度改成60;示例:比如我们要删除password列;
2023-12-11 11:18:30
199
原创 MySQL库的操作
表恢复之前需要先选中一个数据库,表明需要将表恢复到哪一个数据库中,为了防止恢复出来的表与该数据库中已有的表的表名重复,一般在恢复表时会选择创建一个空的数据库,然后在该数据库中进行表的恢复。使用不同的校验规则操作数据库中的数据可能会得到不同的结果,比如utf8_general_ci校验规则在比对数据时是不区分大小写的,而utf8_bin校验规则在对比数据时则是区分大小写的。在对数据库当中的数据进行增删查改时,不可避免的需要进行数据的比对,因为在对数据做增删查改之前,都需要先通过比对的方式找到目标数据。
2023-12-11 09:27:03
478
1
原创 MySQL数据库基础
数据库是按照数据结构来组织、存储和管理数据的仓库,是一个长期存储在计算机内的、有组织的、可共享的、统一管理的大量数据的集合。存储数据用文件就可以了,为什么还要弄个数据库?文件的安全性问题:数据误操作以后无法进行回滚。回滚(Rollback)指的是程序或数据处理错误,将程序或数据恢复到上一次正确状态的行为;文件不利于数据查询和管理:没有将存储的数据以某种数据结构组织起来;文件不利于存储海量数据:数据的控制需要由用户自己来完成;文件在程序中控制不方便:数据量越大用户的操控成本就越高。
2023-12-10 10:38:41
108
原创 Epoll服务器(ET工作模式)
如果我们传输的单纯是一个字符串,直接发送到网络中就可以了,但是如果是一些结构化的数据,比如实现一个计算器,他会存在左操作数,右操作数,操作符等,如果一个一个进行发送,就需要一个一个进行接收,此时服务端还需要纠结这些数据如何组合,所以我们可以将这些结构化数据打包。未来我们除了要添加_listensock以外,还需要需要添加大量的sock,所以我们的AddConnection函数就需要就需要将读回调,写回调,异常回调全部考虑在内,在进行_listensock添加时将写回调,异常回调设置为空即可;
2023-12-09 15:09:08
147
原创 I/O多路转接之select/poll/epoll
虽然当前的select服务器是一个单进程的服务器,但它却可以同时为多个客户端提供服务,根本原因就是因为select函数调用后会告知select服务器是哪个客户端对应的连接事件就绪了,此时select服务器就可以读取对应客户端发来的数据,读取完后又会调用select函数等待某个客户端连接的读事件就绪。此时如果select监视的文件描述符上有事件就绪,那么select函数的返回值就是大于0的,如果select监视的文件描述符上没有事件就绪,那么select的返回值就是等于0的。
2023-12-01 10:56:33
171
1
原创 Linux之高级IO
进行异步IO需要调用一些异步IO的接口,异步IO接口调用后会立马返回,因为异步IO不需要你进行“等”和“拷贝”的操作,这两个动作都由操作系统来完成,你要做的只是发起IO,当IO完成后操作系统会通知应用程序,因此进行异步IO的进程或线程并不参与IO的所有细节。当我们输入数据以后,此时read函数就会检测到底层的数据已经就绪了,就会将缓冲区中的数据拷贝到我们的buffer数组中,并且将读取到的数据输出到显示器上面,最后我们就看到了我们输入的字符串。
2023-11-27 10:46:03
1320
原创 DNS/ICMP协议、NAT技术
域名是用来识别主机名称和主机所属的组织机构的一种分层结构的名称,例如www.baidu.com。com:一级域名,表示这是一个工商企业域名。同级的还有.net(网络提供商)和.org(开源组织或非盈利组织)等。baidu:二级域名,一般对应的就是公司名。www:只是一种习惯用法,之前人们在使用域名时,往往命名成类似于ftp.xxx.xxx/www.xxx.xxx这样的格式,来表示主机支持的协议。应用层的作用:负责应用程序间沟通,完成一系列业务处理所需服务。
2023-11-25 16:31:37
298
原创 数据链路层-以太网协议
所以在同一个网段内,我们需要通过IP地址得到对方的MAC地址,这就叫做ARP协议。在进行局域网通信时,就算只知道对方的IP地址,而不知道对方的MAC地址,也可以以广播的方式将数据发送到局域网当中,此时局域网当中的主机也能够在IP层比对目的IP地址与自己是否相符,来判断收到的这个数据是否是发送给自己的。在IP层中,不仅仅源端主机会进行数据的分片,数据在路由的过程中也会进行分片,因为不同的网络MTU可能是不一样的,如果传输路径上的某个网络MTU要比源端主机上的MTU小,数据在路由的过程中就可能会产生分片。
2023-11-24 17:28:11
645
原创 网络层协议-IP协议
分片就是将一个比较大的报文,拆成多个小的,满足条件的报文,分片的行为是网络层做的,同样,组装的行为也是对端网络层做的,对于TCP/UDP,将数据传输给下层以后,他其实并不关心下层是怎么将数据发送的(我将一个完整的数据发送给你,就必须传输回来的数据也是完整的,至于怎么实现,就是网络层的事情)。双方进行网络间通信,不仅仅是需要将数据发送出去的,还需要将数据向上交付,我们知道TCP/UDP发送给网络层是一个完整的数据,那么我们在进行数据向上交付的时候,也需要一个完整的数据,这就需要我们对分片的报文进行组装了。
2023-11-23 15:23:00
198
原创 传输层协议-TCP协议
比如此时有两个人小花和小红,两个人在面对面进行交流,对方说话两个人都能听见,但是两个人相隔50米以后,此时再说话,对方也就无法听见了,这也就造成消息的不可靠性,其实本质上就是距离变长了,因此,要进行设备间的通信,就必须引入可靠性,如果要进行通信的各个设备相隔千里,,传输数据时出现错误的概率也会大大增高,此时要保证传输到对端的数据无误。网好的时候重传的时间可以设置的短一点,网卡的时候重传的时间可以设置的长一点,也就是说超时重传设置的等待时间一定是上下浮动的,因此这个时间不可能是固定的某个值。
2023-11-19 14:42:34
213
原创 传输层协议-UDP协议
应用层中的每一个网络进程都会绑定一个端口,对于客户端进程来说,端口是操作系统动态进行分配的,而服务端就需要我们显示的绑定端口,UDP就是通过报头当中的目的端口号来找到对应的应用层进程的。如果UDP中不存在接收缓冲区,上层在接收数据是就需要及时的将UDP读取到的报文给读取上去,否则就会出现上一个报文还没有被读取,下一个报文已经来了,此时刚从底层获取的报文就会被丢弃。需要注意的是,UDP协议报头当中的UDP最大长度是16位的,因此一个UDP报文的最大长度是64K(包含UDP报头的大小)。
2023-11-14 21:19:25
253
原创 HTTPS协议
数据指纹(数据摘要),其基本原理是利用单向散列函数(Hash函数)对信息进行运算,生成一串固定长度的数据摘要。数据指纹并不是一种加密机制,但可以用来判断数据有没有被篡改;摘要常见方法:MDS、SHA1、SHA256、SHA512等,算法把无限的映射成有限,因此可能会有碰撞(两个不同的信息,算出相同的摘要,但是概率非常低);摘要特征:和加密算法的区别是,摘要严格意义上说不是加密,因为没有解密,只不过从摘要很难反推原信息,通常用来进行数据对比。
2023-11-12 15:47:46
133
原创 HTTP协议
HTTP(Hyper Text Transfer Protocol)协议又叫做超文本传输协议,是一个简单的请求-响应协议,HTTP通常运行在TCP之上。
2023-11-10 09:59:28
140
原创 Linux认识协议
上面服务端代码包含了许多细节类的问题,因为我们需要进行结构化数据的传输,所以我们的服务端接收数据的过程是将序列化数据反序列化,因为我们服务端是要进行计算的,我们的网络计算器底层是以TCP来实现的,就存在字节流->结构化的转换问题,就像我们在读取数据的过程中,此时单纯的recv已经不能满足我们的需求,所以我们在接下来定制协议的过程,就需要考虑数据完整性的问题。因此客户端最好把这些结构化的数据打包后统一发送到网络当中,此时服务端每次从网络当中获取到的就是一个完整的请求数据,客户端常见的“打包”方式有以下两种。
2023-11-06 16:51:46
262
原创 网络编程套接字(二)
我们知道,子进程创建成功以后,父子进程共享一个文件描述符表,但是父进程创建子进程后,由于进程间独立性,父子进程之间并不会相互影响,所以,父进程文件描述符的变化并不会影响子进程,就像匿名管道一样,父进程先调用pipe函数得到两个文件描述符,一个是管道读端的文件描述符,一个是管道写端的文件描述符,此时父进程创建出来的子进程就会继承这两个文件描述符,之后父子进程一个关闭管道的读端,另一个关闭管道的写端,这时父子进程文件描述符表的变化是不会相互影响的,此后父子进程就可以通过这个管道进行单向通信了。
2023-11-03 22:36:44
298
原创 网络编程套接字(一)
户端运行之后提示我们进行输入,当我们在客户端输入数据后,客户端将数据发送给服务端,此时服务端再将收到的数据打印输出,这时我们在服务端的窗口也看到我们输入的内容。对于同一台主机上,数据存储的方式一样,所以无论是大端存储还是小端存储,并不会出现问题,但是涉及到网络传输以后,在多台机器之间进行数据传输,可能一台机器存储方式为大端存储,另一台机器的存储方式为小端存储,在进行数据传输以后原本大端存储的是数据会被按小端方式识别出来,而原本小端存储的是数据会被按大端方式识别出来,导致数据识别出现错误;
2023-10-31 15:27:49
132
原创 Linux网络基础
此时局域网1内的数据要发送到局域网2时,路由器接收到局域网1发送的数据以后,会先对以太网的报头进行解包,将剩下的数据交付给网络层,此时网络层在进行一系列的操作以后,再将数据向下交付给链路层,此时数据就会添加令牌环相应的报头信息,然后再将信息发送至局域网2,此时该数据就能够在令牌环网当中传输了。我们有了这样的约定后,当甲计算机向乙计算机发送类似于{1, 0x1234}的数据时,乙计算机识别到code的值是1,于是就知道了甲计算机是让自己将data的值存储进数据库,这是一种纯软件的约定方案。
2023-10-29 10:09:29
345
原创 Linux之线程池
并且我们会发现这3个线程在处理时会呈现出一定的顺序性,因为主线程是每秒push一个任务,这3个线程只会有一个线程获取到该任务,其他线程都会在等待队列中进行等待,当该线程处理完任务后就会因为任务队列为空而排到等待队列的最后,当主线程再次push一个任务后会唤醒等待队列首部的一个线程,这个线程处理完任务后又会排到等待队列的最后,因此这3个线程在处理任务时会呈现出一定的顺序性。:指的就是一个类只能创建一个对象,该模式可以保证系统中该类只有一个实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享。
2023-10-27 16:27:42
808
1
原创 Linux信号量
我们可以让生产者不停的进行生产,而消费者每隔一秒进行消费,此时由于生产者生产的很快,运行代码后一瞬间生产者就将环形队列打满了,此时生产者想要再进行生产,但空间资源已经为0了,于是生产者只能在space_sem的等待队列下进行阻塞等待,直到由消费者消费完一个数据后对space_sem进行了V操作,生产者才会被唤醒进而继续进行生产。当执行流在申请信号量时,可能此时信号量的值为0,也就是说信号量描述的临界资源已经全部被申请了,此时该执行流就应该在该信号量的等待队列当中进行等待,直到有信号量被释放时再被唤醒。
2023-10-24 16:04:11
126
原创 Linux生产者消费者模型
生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消费者不找生产者要数据,而是直接从阻塞队列里取,阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力。对应到生产者消费者模型中,函数传参实际上就是生产者生产的过程,而执行函数体实际上就是消费者消费的过程,但生产者只负责生产数据,消费者只负责消费数据,在消费者消费期间生产者可以同时进行生产,因此生产者消费者模型本质是一种松耦合。我们仍然让生产者生产的快,消费者消费的慢。
2023-10-19 15:44:40
195
原创 C++之IO流
在C语言中,我们若是想要将一个整型变量的数据转化为字符串格式,有以下两种方法:1、使用itoa函数进行转化。int a = 10;2、使用sprintf函数进行转化。int a = 10;虽然itoa函数和sprintf函数都能完成转化,但是在两个函数在转化时,都需要先给出保存结果的空间,而空间的大小是不太好界定的,除此之外,转化格式不匹配时,可能还会得到错误的结果甚至程序崩溃。在C++中,我们可以使用stringstream类对象来避开此问题。
2023-10-17 15:00:58
264
原创 C++之类型转换
而使用dynamic_cast进行向下转型则是安全的,如果父类的指针(或引用)指向的是子类对象那么dynamic_cast会转换成功,但如果父类的指针(或引用)指向的是父类对象那么dynamic_cast会转换失败并返回一个空指针。:隐式类型转换只能是在相近的类型之间进行,比如int与double之间他们的数据类型相似,如果是int与int*就不可以,因为他们一个是指针一个是整形,就需要我们显示的进行转换。dynamic_cast用于将一个父类对象的指针/引用转换为子类对象的指针或引用(动态转换)
2023-10-16 11:22:36
114
原创 特殊类设计
C++98中构造函数私有化,派生类中调不到基类的构造函数,则无法继承,因为子类的构造函数被调用时,必须调用父类的构造函数初始化父类的那一部分成员,但父类的私有成员在子类当中是不可见的,所以在创建子类对象时子类无法调用父类的构造函数对父类的成员进行初始化,因此该类被继承后子类无法创建出对象。但是我们不能将构造函数设置为私有,也不能用=delete的方式将拷贝构造函数删除,因为CreateObj函数当中创建的是局部对象,返回局部对象的过程中势必需要调用拷贝构造函数。单例模式有两种实现方式,分别是。
2023-10-16 09:42:21
89
原创 C++之智能指针
什么是内存泄漏内存泄漏指因为疏忽或错误造成程序未能释放已经不再使用的内存的情况。内存泄漏并不是指内存在物理上的消失,而是应用程序分配某段内存后,因为设计错误,失去了对该段内存的控制,因而造成了内存的浪费。内存泄漏的危害长期运行的程序出现内存泄漏,影响很大,如操作系统、后台服务等等,出现内存泄漏会导致响应越来越慢,最终卡死。
2023-10-15 10:24:00
150
原创 C++11之包装器
绑定时第一个参数传入函数指针这个可调用对象,但后续传入的要绑定的参数列表依次是placeholders::_1和placeholders::_2,表示后续调用新生成的可调用对象时,传入的第一个参数传给placeholders::_1,传入的第二个参数传给placeholders::_2。此时绑定后生成的新的可调用对象的传参方式,和原来没有绑定的可调用对象是一样的,所以说这是一个无意义的绑定。它可以接受一个可调用对象,生成一个新的可调用对象来“适应”原对象的参数列表,C++中的bind本质是一个函数模板。
2023-10-14 09:55:17
111
原创 C++11之线程库
在C++11之前,涉及到多线程问题,都是和平台相关的,比如windows和linux下各有自己的接口,这使得代码的可移植性比较差。C++11中最重要的特性就是对线程进行支持了,使得C++在并行编程时不需要依赖第三方库,而且在原子操作中还引入了原子类的概念。
2023-10-12 15:03:15
222
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人