- 博客(113)
- 收藏
- 关注
原创 【MySQL】--- 数据类型
比如enum(‘男’,‘女’,‘保密’)中,‘男’ = 1,‘女’ = 2,‘保密’ = 3;set(‘羽毛球’,‘乒乓球’,‘篮球’,‘足球’) 中,‘羽毛球’ = 1,‘乒乓球’ = 2,‘篮球’ = 4,‘足球’ = 8。如果用字符串存储,一个选项就要占用好几个字节,未免太低效了,它们底层都使用数字来存储。字符串’a’,‘ab’,'abc’都插入成功了,而’abcd’超出了长度,插入失败。,其会根据精度的需要,调整占用的内存,确保可以精确保存这个精度的所有值!
2025-08-30 11:46:24
721
原创 【MySQL】--- 库表操作
此时在/var/lib/mysql下的db_1目录下,出现了三个文件:tb1.frm,tb1.ibd,db.opt这三个文件共同维护了tb1这张表。上述指令指定了一个名为bit_index 数据库,将其保存在路径~/test/bit_index.sql。主要作用:如果 没有这个数据库,就创建!此时系统就列出了支持的各种集合,比如。可以加这个选项,也可以不加!以上两种方式,都可以指定。
2025-08-19 17:57:57
787
原创 【基于个人博客系统】---测试报告
此次测试主要对个人博客系统的主要功能进行了测试,并用Selenium编写了测试脚本进行了自动化测试。1、个人博客系统还需对首页的个人信息栏部分进行优化,2、文章的数量要与用户发布的数量同步起来,3、在弹窗提示上也需要更详细些,为用户提供有用的弹窗信息,这样才能给用户提供一个良好的体验。
2025-08-14 15:26:46
953
原创 Linux网络:多路转接 epoll
在select中,就绪的事件通过一张位图返回,用户需要遍历整个位图所有元素,并判断该元素是否就绪,那么就会浪费大量的时间在未就绪的文件上。这是另一大优势,在select中,每次返回都会重置用户传入的位图,因此用户在每次轮询都要重新把文件描述符设置到select。数组,这个数组用于存储本次就绪的所有文件的epoll_event,为了防止越界,所以还要传入maxevents。时传入的,从它的events字段可以得知这个文件监听的事件,从data字段可以获取之前预设的其他信息,一般会预设。
2025-08-01 22:15:29
966
原创 Linux网络:多路转接 select
在刚才的代码中可以看出select的特性,每次循环都要重新设置所有的套接字。当select返回后要遍历所有的套接字,来判断哪个套接字可以进行读取了。所以select是一个比较麻烦的多路转接策略。而当select返回后,还要依据不同的套接字类型,来进行不同的事件处理。这也就是基本的多路转接使用流程事件循环事件派发事件处理。
2025-07-29 20:49:00
721
原创 Linux网络:IO模型
在网络通信中,进程需要频繁的与网络进行数据交互,这个过程会涉及到非常复杂的问题。如图,一个运行在操作系统上的进程,需要通过调用系统的接口,来完成数据的收发。操作系统再与互连网进行交互,完成真正的网络通信。这个过程中,进程全程只与操作系统交互,通过两个缓冲区来与内核交互。缓冲区的本质其实就是一块内存,用户和操作系统分别可以读写其中的数据,从而完成数据的流转。拷贝接收缓冲区recvfrom发送数据拷贝发送缓冲区而以上两个过程,从用户的角度其实就是读写数据Input与Output,简称IO。进程操作系统。
2025-07-27 11:43:34
886
原创 Linux网络:数据链路层-以太网协议
还是以刚才的例子为例,路由器D要将数据转发给同一局域网当中的主机B,前提是路由器D必须知道主机B的MAC地址,而现在路由器D只知道主机B的IP地址,因此路由器D现在需要向主机B发起ARP请求,然后等待主机B发送ARP应答得知主机B的MAC地址。从ARP的数据格式也可以看出,ARP是MAC帧协议的上层协议,ARP数据格式中的前3个字段和最后一个字段对应的就是以太网首部,但由于ARP数据包的长度不足46字节,因此ARP数据包在封装成为MAC帧时还需要补上18字节的填充字段。首先路由器D需要先构建ARP请求。
2025-07-24 20:45:07
937
原创 Linux网络:网络层-IP协议
需要注意的是,这里连接云服务器时的IP地址182.118.237.199,是云服务器的公网IP,由于我使用的是阿里云,因此这里的172.17.43.48是我这个云服务器在阿里内部的私网IP,可以看到这个IP正好在第二种私网IP范围内。而对于主机标识来讲,同一网段内主机的主机标识是不同的,不同网段内主机的主机标识是可以相同的。也就是说,IP地址中主机号为全0的代表的是当前局域网的网络号,IP地址中主机号为全1的代表的是广播地址,这两个IP地址都是不能作为主机的IP地址的。,最终由路由器D将数据交给主机C。
2025-07-23 17:02:37
803
原创 Linux网络:传输层-TCP协议
TCP全称为“传输控制协议(Transmission Control Protocol)”,协议是当今互联网当中使用,没有之一。TCP协议被广泛应用,其根本原因就是提供了详尽的可靠性保证,基于TCP的上层应用非常多,比如HTTP、HTTPS、FTP、SSH等,甚至MySQL底层使用的也是TCP。现代的计算机大部分都是基于冯诺依曼体系结构的。由于这几个硬件设备都是在一台机器上的,因此这里传输数据的“线”是很短的,传输数据时出现错误的概率也非常低。但如果要进行通信的各个设备相隔千里,那么连接各个设备的“线”就
2025-07-21 10:35:34
1070
原创 Linux网络:HTTPS协议
在HTTP协议中,所有的数据都采用明文的形式传输,这就会导致数据非常容易泄露,只要拿到HTTP报文,就可以窃取各种信息。基于HTTP协议,使用一定的加密措施,让HTTP内部的数据变为密文,就升级为了HTTPS协议,其中S表示Secure或者Safe,都是安全的意思。
2025-07-17 10:51:47
876
原创 Linux网络:http协议
HTTP(Hyper Text Transfer Protocol)协议又叫做超文本传输协议,是一个简单的请求-响应协议,HTTP通常运行在TCP之上。在编写网络通信代码时,我们可以自己进行协议的定制,但实际有很多优秀的工程师早就已经写出了许多非常成熟的应用层协议,其中最典型的就是HTTP协议。
2025-07-16 10:12:53
1018
原创 Linux网络:详解 序列化&反序列化
对象同理,先通过 root.getMemberNames()拿到所有的key,所有root[keys[j]]就是对象内的元素,这个元素同样有可能是标量,嵌套数组,嵌套对象,它们被统一为了Json::Value,直接递归print(root[keys[j]])。如果Json::Value内部存储的是对象,该函数用于获取一个Json::Value的所有key,并存储在Json::Value::Members中,Json::Value::Members是一个数组,可以直接通过下标访问。如何区分这三个区域?
2025-07-09 11:28:52
842
原创 Linux网络-网络协议 & 序列化/反序列化
当服务端调用accept函数获取到新连接并创建新线程后,该线程就需要为该客户端提供计算服务,此时该线程需要先读取客户端发来的计算请求,然后进行对应的计算操作,如果客户端发来的计算请求存在除0、模0、非法运算等问题,就将响应结构体当中的状态字段对应设置为1、2、3即可。比如现在要实现一个网络版的计算器,那么客户端每次给服务端发送的请求数据当中,就需要包括左操作数、右操作数以及对应需要进行的操作,此时客户端要发送的就不是一个简单的字符串,而是一组结构化的数据。将结构化的数据组合成一个字符串。
2025-07-08 16:34:21
864
1
原创 Linux网络-socket-接口总结
用于辨别这个结构体表示哪一个套接字。以上就是一个错误示例,因为不清楚代码的运行环境是大端还是小端,此时存入的数据22就有可能不是网络字节序,所以要先将22转为网络字节序,Linux为此提供了专门的接口。在不同主机内存中,字节数据分为大端字节序和小端字节序,假设一个大端主机和一个小端主机进行通信,此时就会发生错误,因为两别解析数据的方式不同,于是网络字节序出现了。当连接建立成功后,就可以开始收发消息了,TCP是面向字节流的,与UDP不同,TCP可以把sockfd文件描述符完全当作一个文件,完成消息的读写。
2025-07-07 09:03:30
837
原创 网络编程 套接字(TCP版)
TCP服务器在调用socket函数创建套接字时,参数设置如下:如果创建套接字后获得的文件描述符是小于0的,说明套接字创建失败,此时也就没必要进行后续操作了,直接终止程序即可。说明一下:绑定的步骤如下:绑定的实质:就是将打开的文件(sockfd)与网络(填充过网络信息的结构体)关联起来由于TCP服务器初始化时需要服务器的端口号,因此在服务器类当中需要引入端口号,当实例化服务器对象时就需要给传入一个端口号。而由于我当前使用的是云服务器,因此在绑定TCP服务器的IP地址时不需要绑定公网IP地址,直接绑定INAD
2025-07-06 08:57:59
1006
原创 网络编程 套接字(UDP版)
实际是因为早期有很多不同的实验室都在研究通信的方式,由于是不同的实验室,因此就出现了很多不同的通信方式,比如常见的有System V标准的通信方式和POSIX标准的通信方式。
2025-07-05 08:36:00
1031
原创 网络入门基础
所有的操作系统都必须支持。也就是说,虽然客户端和服务端可能使用的是不同种类的操作系统,但每个操作系统实现网络协议栈的方法包括各种细节都是一样的,
2025-07-03 21:10:56
878
原创 【项目设计】--- 高并发内存池设计(四)
在本文中,作者详细讨论了高并发内存池设计中处理大于256KB大块内存申请与释放的策略。对于大于256KB的内存申请,直接向page cache申请,若超过128页则向堆申请。RoundUp函数被修改以支持按页对齐。申请时,通过NewSpan函数获取指定页数的span,并在page cache中进行加锁操作以确保线程安全。释放时,通过对象的起始地址找到对应的span,并根据span的大小决定是归还给page cache还是直接释放给堆。page cache在回收span时会尝试合并相邻的span以减少内存碎片
2025-05-14 15:05:08
1115
1
原创 【项目设计】--- 高并发内存池设计(三)
由于在合并page cache当中的span时,需要通过页号找到其对应的span,而一个span是在被分配给central cache时,才建立的各个页号与span之间的映射关系,因此page cache当中的span也需要建立页号与span之间的映射关系。因此当我们申请k页的span时,如果是将n页的span切成了一个k页的span和一个n-k页的span,我们除了需要建立k页span中每个页与该span之间的映射关系之外,还需要建立剩下的n-k页的span与其首尾页之间的映射关系。
2025-05-06 22:43:44
680
原创 【项目设计】--- 高并发内存池设计(二)
现代很多的开发环境都是多核多线程,因此在申请内存的时,必然存在激烈的锁竞争问题。malloc本身其实已经很优秀了,但是在并发场景下可能会因为频繁的加锁和解锁导致效率有所降低,而该项目的原型tcmalloc实现的就是一种在多线程高并发场景下更胜一筹的内存池。在实现内存池时我们一般需要考虑到效率问题和内存碎片的问题,但对于高并发内存池来说,我们还需要考虑在多线程环境下的锁竞争问题。高并发内存池主要由以下三个部分构成:进一步说明:因此当线程要申请某一大小的内存块时,就需要经过某种计算得到对齐后的字节数,进而找到
2025-05-05 15:17:01
1099
原创 【项目设计】--- 高并发内存池设计(一)
本项目实现的是一个高并发的内存池,它的原型是Google的一个开源项目tcmalloc,tcmalloc全称Thread-Caching Malloc,即线程缓存的malloc,实现了高效的多线程内存管理,用于替换系统的内存分配相关函数malloc和free。tcmalloc的知名度也是非常高的,不少公司都在用它,比如Go语言就直接用它做了自己的内存分配器。该项目就是把tcmalloc中最核心的框架简化后拿出来,模拟实现出一个mini版的高并发内存池,目的就是学习tcmalloc的精华。
2025-04-21 11:03:19
686
原创 【Linux】 --- 线程池
我们将线程池进行了模板化,因此线程池当中存储的任务类型可以是任意的,但无论该任务是什么类型的,在该任务类当中都必须包含一个Run方法,当我们处理该类型的任务时只需调用该Run方法即可。此时线程池内的线程不断从任务队列拿出任务进行处理,而它们并不需要关心这些任务是哪来的,它们只需要拿到任务后执行对应的Run方法即可。主线程就负责不断向任务队列当中Push任务就行了,此后线程池当中的线程会从任务队列当中获取到这些任务并进行处理。线程池是一种线程使用模式。主函数:main.cc。
2025-03-29 15:39:23
1180
原创 【Linux】 --- 信号量
也就是说,当环形队列为空和满时,我们已经通过信号量保证了生产者和消费者的串行化过程。当执行流在申请信号量时,可能此时信号量的值为0,也就是说信号量描述的临界资源已经全部被申请了,此时该执行流就应该在该信号量的等待队列当中进行等待,直到有信号量被释放时再被唤醒。每个执行流在进入临界区之前都应该先申请信号量,申请成功,就有了操作特定的临界资源的权限,当操作完毕后就应该释放信号量。多个执行流为了访问临界资源会竞争式的申请信号量,因此信号量是会被多个执行流同时访问的,也就是说信号量本质也是临界资源。
2025-03-29 15:36:41
917
原创 【Linux】--- 基于阻塞队列:生产消费者模型
我们也可以当阻塞队列当中存储的数据大于队列容量的一半时,再唤醒消费者线程进行消费;当阻塞队列当中存储的数据小于队列容器的一半时,再唤醒生产者线程进行生产。
2025-03-28 09:40:15
1049
原创 【Linux】--- 线程互斥
既然–操作需要三个步骤才能完成,那么就有可能当thread1刚把tickets的值读进CPU就被切走了,也就是从CPU上剥离下来,假设此时thread1读取到的值就是1000,而当thread1被切走时,寄存器中的1000叫做thread1的上下文信息,因此需要被保存起来,之后thread1就被挂起了。临界区内的线程完全可能进行线程切换,但即便该线程被切走,其他线程也无法进入临界区进行资源访问,因为此时该线程是拿着锁被切走的,锁没有被释放也就意味着其他线程无法申请到锁,也就无法进入临界区进行资源访问了。
2025-03-24 20:44:13
888
原创 【Linux】--- 线程概念、线程控制
线程的标准概念:线程是进程中的的一个执行流,是CPU调度的基本单位!进程:进程是系统资源分配的基本单位!一切进程至少都有一个执行线程。线程在进程内部运行,本质是在进程地址空间内运行。关于进程需要明确的是,一个进程的创建实际上伴随着其进程控制块(task_struct)、进程地址空间(mm_struct)以及页表的创建,虚拟地址和物理地址就是通过页表建立映射的。每个进程都有自己独立的进程地址空间和独立的页表,也就意味着所有进程在运行时本身就具有独立性。关于线程。
2025-03-08 22:31:55
1144
原创 【Linux】--- 信号阻塞、信号捕捉
此处我们用(2) SIGINT做检测,先通过sigaddset(&set, 2)把set中的第二位变为1,随后通过sigprocmask(SIG_BLOCK, &set, nullptr)将set添加到block中,由于我们并不想知道旧的block是什么样,所以第三个参数设为nullptr。,指向信号的处理函数。如果时机合适,进程会检测pending表和block表,然后检测出已经接收到的信号,若该信号未被阻塞,执行对应信号的处理函数,并把pending中的该位变回0,表示该信号已经处理完了。
2025-02-17 20:33:06
951
原创 【Linux】--- 信号的概念、信号产生
再比如说我们之前的ctrl + C按键发送(2) SIGINT信号,本质也是硬件中断,当我们从键盘输入了数据后,键盘向CPU发出硬件中断,随后CPU去执行操作系统中的硬件中断程序,发现是用户按下了ctrl + C,于是操作系统向进程发送(2) SIGINT信号。以上就是Linux中的全部信号,它们分为两个区间:[1, 31] 和[34, 64],也就是说没有0,32,33这三个信号,虽然信号的最大编号为64,但实际上只有62个信号。经理收到这个信号后,会暂停当前的工作,转而去处理员工的请求。
2025-02-15 21:52:36
1178
原创 【Linux】--- 进程间的通信
进程间通信简称IPC(Interprocess communication),进程间通信就是在不同进程之间传播或交换信息。管道是Unix中最古老的进程间通信的形式,我们把从一个进程连接到另一个进程的数据流称为一个“管道”。例如,统计我们当前使用云服务器上的登录用户个数。其中,who命令和wc命令都是两个程序,当它们运行起来后就变成了两个进程,who进程通过标准输出将数据打到“管道”当中,wc进程再通过标准输入从“管道”当中读取数据,至此便完成了数据的传输,进而完成数据的进一步加工处理。
2025-02-11 22:07:02
815
原创 【Linux】--- 基础IO
该函数会返回一个FILE*的指针,C语言中,通过操作这个 FILE * 来控制文件的IO。当我们打开文件时,每个被使⽤的⽂件都在内存中开辟了⼀个相应的⽂件信息区,⽤来存放⽂件的相关信息。这些信息是保存在⼀个结构体变量中的。该结构体类型是由系统声明的,取名FILE。我们可以通过操纵这个FILE类型的结构体,来操控文件。大部分情况下,我们可以得到一个指向该结构体的指针FILE*,即文件指针,后续通过文件指针来操控文件。上图中,三个指针pf1,pf2,pf3,它们都指向了一个FILE类型的文件信息区。
2025-02-03 20:45:32
1435
原创 【Linux】--- 进程的等待与替换
例如,以下代码中同时创建了10个子进程,同时将子进程的pid放入到ids数组当中,并将这10个子进程退出时的退出码设置为该子进程pid在数组ids中的下标,之后父进程再使用waitpid函数指定等待这10个子进程。第一个参数是要执行程序的路径,第二个参数是一个指针数组,数组当中的内容表示你要如何执行这个程序,数组以NULL结尾,第三个参数是你自己设置的环境变量。第一个参数是要执行程序的路径,第二个参数是可变参数列表,表示你要如何执行这个程序,并以NULL结尾,第三个参数是你自己设置的环境变量。
2025-01-15 21:31:08
1290
原创 【Linux】--- Linux中进程的创建与终止
退出码都有对应的字符串含义,帮助用户确认执行失败的原因,而这些退出码具体代表什么含义是人为规定的,不同环境下相同的退出码的字符串含义可能不同。我们都知道main函数是代码的入口,但实际上main函数只是用户级别代码的入口,main函数也是被其他函数调用的,是间接性被操作系统所调用的。当子进程刚刚被创建时,子进程和父进程的数据和代码是共享的,即父子进程的代码和数据通过页表映射到物理内存的同一块空间。新进程为子进程,而原进程为父进程。3、为什么父进程返回的是子进程的pid,子进程返回的是0?
2025-01-15 11:58:11
980
原创 【Linux】--- 进程的概念
操作系统描述进程的时候就是PCB,PCB(process control block)在Linux中的PCB叫做:task_struct(task_struct就是PCB的一种)创建进程不仅仅是,把代码和数据加载到内存里,还要为进程创建task_struct所以:进程 = task_struct + 代码和数据根据:“先描述,再组织”①描述:task_struct在Linux内核中就是一种:结构体(里面包含着进程的相关信息)
2024-12-16 22:10:55
1368
原创 【Linux】--- 开发工具篇:yum、vim、gcc、g++、gdb、make、makefile
gdb是GNU开源组织发布的一个强大的UNIX下的程序调试工具,是命令行调试工具。一般来说,gdb主要完成如下四个功能:(1)启动程序,按照自定义要求随心所欲运行程序。(2)可让被调试的程序在指定的调试的断点处停住。(断点可以是条件表达式)(3)当程序被停住时,可以检查此时程序中所发生的事。(4)动态的改变程序的执行环境gcc 源文件 -o 目标文件 -g。
2024-10-30 21:39:34
1447
原创 【优选算法】--- 分治 快速排序
第一步:对数组排序,划分区间,【l,left】【left+1,right-1】【right,r】根据题目要求,我们需要把数组中的元素012按顺序排好。把 “ 1 ”当做key基准元素。采用:快排+三指针的解法。
2024-10-08 15:03:15
1271
原创 【优选算法】---分治 归并排序
(4)最后再一左一右利用双指针的算法,固定一个然后移动另外一个在:一左一右->这两个数组里面分别找逆序对的个数,最后加起来就是整个数组的逆序对个数。这里的重点和难点就在于:我们如何找到我们正在遍历的数组(是打乱排完序的)中当前元素的原始下标!(3)然后再在右半部分找逆序对的个数再排排序,(2)分别在左半部分找逆序对的个数,排完序。分治的思想:归并排序类似于二叉树的后序遍历。1、运用递归分别:处理左半部分、右半部分。这样的解法的时间复杂度:N*logN。但是这次我们要排的是:降序!但是有一点需要特别注意,
2024-10-07 22:55:28
902
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人