- 博客(39)
- 收藏
- 关注
原创 Linux项目 | 基于HTTP的自主web服务器
文章目录概览所谓的HTTP,本质就是把服务器上的文件资源想方设法的发送回给浏览器。web服务器要做的两件事:1、从http请求中提取出要访问什么资源2、找到资源且判定资源是否合法,合法情况下打开,打开之后读取,读取之后发送回去,发送完关闭。要面对的问题:1、HTTP协议本身的解析问题2、HTTP资源的返回问题概览httpserver.hpp 服务器、端口相关设置sock.hpp 对套接字的封装,满足基本通信要求Protocol.hpp 专门处理协议细节util.hpp 与逻辑业
2021-09-20 17:59:43 389
原创 网路基础Ⅲ(网络层 | 数据链路层)
文章目录网络层IP分片总结HTTP解决:构建与解析request && response ->recieve && sendTCP解决:可靠性,效率,什么时候发送,发多少,怎么发。IP:端到端(主机A到B之间)、点到点(主机A到下一跳路由器),将数据经过路径选择,送达到对方主机的过程。网络层在复杂的网络环境中确定一个合适的路径。路由查找的基本过程:是先找到目的网络,再找到目的主机。找到目标主机所在的局域网,然后在局域网内部进行报文转发,找到目标主机。
2021-09-13 19:36:36 842
原创 C++项目 | 高并发内存池
池化技术:线程池、内存池、连接池内存池解决的问题:1、提高申请和释放内存的效率 2、解决内存碎片内存碎片:频繁申请、释放小块内存,可能会导致内存碎片。分为两种场景:内碎片,外碎片(通常)高并发内存池:对比malloc在多线程并发场景下申请内存的性能,减少锁竞争——让每个线程都有一个自己独立的内存池。内存池需要考虑以下的问题:内存碎片问题。性能问题。多核多线程环境下,锁竞争问题一、高并发内存池的组成threadCache(解决锁竞争)就是一个哈希映射的内存桶(自由链表),th.
2021-09-08 11:21:33 709
原创 网络基础Ⅱ(应用层 | 运输层)
文章目录一、应用层一、应用层我们之前所写的程序都是在应用层。协议是一种 “约定”。如果我们要传输一些"结构化的数据"怎么办呢?网络版计算器
2021-07-03 19:36:16 826 1
原创 网络版计算器
Server.hpp#ifndef __SERVER_HPP__#define __SERVER_HPP__#include <iostream>#include <unistd.h>#include <stdlib.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>..
2021-05-27 18:49:14 249
原创 TCP 网络程序
!TCP 网络程序TCP是一种网络协议。UDP是无连接的,而TCP是面向连接的。所以客户端想和服务器通信的第一件事情不再是发数据,而是先建立连接;同时,TCP的接口调用要多一些。接口// 开始监听socket (TCP, 服务器)int listen(int socket, int backlog);// 接收请求,服务器等待客户端连接,一般是阻塞态int accept(int socket, struct sockaddr* address,socklen_t* address_len)
2021-05-21 14:33:24 270
原创 UDP 网络程序
!UDP 网络程序接口从网络中接收数据,把收到数据在本地打印出来,再经拼凑,返回给客户端,完成一个简单的echo server。效果 ↓// UDP专用,发送数据到指定的IP地址和端口int sendto(int sockfd, const void * msg, int len, unsigned int flags, const struct sockaddr * dst_addr, int addrlen);// UDP专用,接收数据,返回数据远端的IP地址和端口int recvfr
2021-05-21 14:14:40 213 4
原创 网络编程套接字
文章目录一、套接字IP地址和端口号套接字网络通信二、网络字节序三、TCP协议与UDP协议(简要)TCPUDP四、一、套接字IP地址和端口号IP地址主要负责的是把数据从一台主机硬件传送到另一台主机硬件,它标识的是操作系统或者是服务器本身的唯一性。当我们把数据送到目标主机时,只是把数据送到了这台机器,这台机器上有许多运行的软件服务,那么此时该数据包该给哪个软件呢?因此,网络通信中,除了要用IP地址确认目标主机以外,还要通过某种方式去标定该主机上的特定的一个进程!把标定进程的方式叫做端口号。在前
2021-05-20 19:36:06 292
原创 网络基础Ⅰ(协议 | 传输流程 | 数据包封装和分用)
文章目录网络层状体系结构和系统的对应关系一、网络发展历程二、协议协议分层OSI七层模型TCP/IP五层模型三、网络传输基本流程1、数据包封装和分用2、同一个网段内两台主机的文件传输3、跨网段的主机文件传输网络层状体系结构和系统的对应关系网络是操作系统的一部分,与操作系统有关系。在系统的各个硬件内部会有“线”相连,进行数据的传输。网络和体系结构的差别就是“线”变长了。而计算机网络本质是解决:当“线”变长后,怎么把数据从一个机器交付给另一个机器的问题。1、“转发”:要经过若干个线路,路由器转发2
2021-05-08 23:58:44 2067 2
原创 线程池、读者写者模型
文章目录线程池总结线程池优点:处理任务的线程数目是稳定的,服务器不会受到大面积任务到来时而造成的冲击,进而导致宕机。线程池维护着多个线程,等待着监督管理者分配可并发执行的任务,避免了在处理短时间任务时创建与销毁线程的代价。显然,server也是一个线程或进程,后端的一批,相当于一组线程。用任务队列把它们连起来。sever收到任务,把任务放进任务队列,任务队列后端指派任务给池中的线程。线程池能够预先创建一批线程,进而提高处理业务的效率。线程池存在的价值:1、有任务,立刻就有线程进行服务,省掉
2021-04-28 21:28:13 206 2
原创 POSIX信号量(基于环形队列的生产消费模型)
文章目录前言POSIX信号量是什么?信号量的意义?怎么用?基于环形队列的生产消费模型总结前言POSIX信号量是什么?信号量(也叫信号灯),本质是一个在描述临界资源中,有效资源个数的计数器。如果把临界区划分成多个块儿,那么多个线程可以同时进入临界区访问不同的块。之前的锁,是我们认为临界资源只有一块。信号量可以保证让多个线程同时进入临界区,访问临界资源的不同块。申请信号量,把计数器--叫做P操作;释放信号量,计数器++叫做V操作。要保证所有的线程都得看到信号量,所以信号量本身就是临界资
2021-04-27 12:31:34 574 3
原创 互斥与同步(基于阻塞队列的生产消费模型)
文章目录互斥总结互斥所有的线程数据是共享的。被多个执行流访问的公共资源叫做临界资源,访问临界资源是以线程/执行流的方式去访问的,把每个线程内访问临界资源的那部分代码叫做临界区。不一定所有的共享资源都会被所有线程访问,比如main只被一个执行流访问。互斥:任何时刻,互斥保证有且只有一个执行流进入临界区,访问临界资源,通常对临界资源起保护作用。原子性:不会被任何调度机制打断的操作,该操作只有两态,要么完成,要么未完成。多个线程并发的操作共享变量,会带来一些问题:比如我们假设有ticket =
2021-04-26 23:26:34 736 2
原创 关于线程(概念| 优缺点| 创建| 异常| 操作)
Linux 多线程背景线程的概念线程的优缺点优点缺点Linux中线程的基本操作LWP(系统角度)线程ID(用户角度)线程异常线程用途进程与线程总结背景在创建一个进程时,操作系统做了以下的工作:1、创建一个进程所需要的各种数据结构(pcb、地址空间、页表、与文件的关系,父子关系等等)2、开辟物理内存,把硬盘上的代码和数据加载到物理内存中。3、把虚拟地址空间和物理内存通过页表建立映射关系。所以,创建一个进程就是一个执行流从无到有的过程。在这个过程中,我们申请了很多资源,创建了很多东西。当CPU调度
2021-04-21 20:09:26 635 1
原创 进程信号(信号产生 | 信号保存 | 信号处理 | 阻塞 未决 递达)
文章目录一、信号概念信号处理常见的方式二、总结信号是事件发生的一种通知机制,即便是信号没有发生,进程也知道怎么处理。信号也算是通信。那它与通信有什么区别?通信是以传输数据为目的,信号本质是想要把事件通知给进程。一、信号概念我们来看个例子,这是一个死循环。#include<stdio.h>int main(){while(1){ while(1) { printf("i am running \n"); sleep(1); } return 0;}当一个
2021-04-12 21:07:21 825
原创 进程间通信(匿名管道 | 命名管道 | 共享内存)
进程通信的目的数据传输:一个进程需要将它的数据发送给另一个进程资源共享:多个进程之间共享同样的资源。通知事件:一个进程需要向另一个或一组进程发送消息,通知它(它们)发生了某种事件(如进程终止时要通知父进程)。进程控制:有些进程希望完全控制另一个进程的执行(如Debug进程),此时控制进程希望能够拦截另一个进程所有的陷入和异常,并能够及时知道它状态的改变。进程是具有独立性的(进程的代码和数据与另外一个进程的代码和数据是没有关系的)。可是,要通信,就意味着两个进程要进行数据交互,那么数据便有可能
2021-04-05 15:53:20 1241 3
原创 基础IO(文件描述符 | 重定向 | 文件系统 | inode | 软硬链接)
文章目录复习C文件IO一、系统文件IO接口介绍二、文件描述符fd文件描述符的分配规则重定向使用 dup2 系统调用三、理解文件系统inode复习C文件IO文件的读写#include<stdio.h>#include<string.h>int main(){ // 写 FILE *wfp = fopen("myfile.txt", "w"); if (!wfp){ printf("fopen error!\n"); } const char *str =
2021-03-29 18:02:35 555 1
原创 进程控制(进程创建与终止 | 进程等待 | 程序替换)
文章目录一、进程创建1. fork函数2. fork创建进程3. 写时拷贝二、进程终止1. 进程退出有三种情况2. 常见进程终止方法三、进程等待背景(必要性)1. 进程等待的方法(1)wait在之前的学习中,我们至少应该明确进程的概念:是一些数据结构(PCB+地址空间+页表)+ 代码和数据这样的一个集合。一、进程创建1. fork函数初识进程时,我们对fork也有过一些简单的了解。#include<unistd.h> //头文件 pid_t fork() fork返回值
2021-03-21 19:19:27 662
原创 进程地址空间(虚拟地址 | 物理内存)
文章目录前言一、简单理解地址空间二、虚拟地址现象解释三、三个问题搞懂地址空间1. 什么是地址空间?2. 为什么要有地址空间?3. 地址空间是如何工作的?四、一些补充前言在之前的学习中,我们只学习了图中的下半部分(用户空间),当时还并未涉及到操作系统。我们写一段代码来验证一下这张图。#include<stdio.h>#include<stdlib.h>int g_val = 100; //初始化int g_unval; //未初始化int main(int ar
2021-03-17 23:54:10 5025 6
原创 进程优先级及环境变量(是的,main函数是有三个参数~)
文章目录一、进程优先级1. 了解优先级2. 进程优先级3. 查看系统进程优先级4. PRI和NI5. 独立、竞争、并行、并发二、环境变量1. PATH2. 常见环境变量:查看环境变量方法关于环境变量的清晰认知3. 使用语言如何操纵环境变量?4.通过系统调用获取或设置环境变量5. 环境变量的全局性一、进程优先级1. 了解优先级(1)区分优先级和权限:优先级:是使用某种“事物”的先后顺序。权限:能不能使用某种“事物”。(2)优先级的存在目的:在被管理对象很多的时候,优先级起到仲裁的作用。2.
2021-03-16 22:18:53 1729 6
原创 关于进程(PCB | 父进程 | 子进程 | fork深层探讨 |僵尸进程与孤儿进程)
文章目录一、进程与PCB1. 进程的概念:2. 什么是PCBtask_structtask_ struct内容分类4. 查看进程5. 进程概念的加深二、父进程与子进程1. 通过系统调用获取进程标示符2. 进程的创建 - fork3. fork的深层探讨(关键)(1)如何理解进程创建?(2)如何深刻理解fork为什么会有两个返回值?(3)fork父子进程执行顺序、代码和数据复制问题?三、进程的状态一、进程与PCB1. 进程的概念:在一个程序运行之前,要先加载进内存中,称之为,进程。2. 什么是PC.
2021-03-14 18:15:59 4363 9
原创 详解冯诺依曼体系结构与操作系统
计算机体系结构本文主要从两个方面来详细介绍计算机体系结构:1.冯诺依曼体系结构(硬件)2.操作系统(软件)文章目录计算机体系结构前言一、深入理解冯诺依曼体系结构1. 简要背景介绍2. 五大部件介绍3. 细节解释4. 举例理解冯诺依曼机中数据走向二、全面认识操作系统1. 操作系统的概念2. 计算机系统 比对 银行系统3. 深入认识“管理”:4. 库函数和系统调用接口5. 操作系统存在的目的6. 操作系统与Shell总结前言硬件——深入理解冯诺依曼体系结构软件——全面认识操作系统一、深
2021-03-13 18:41:54 5985 5
原创 C++动态内存分配——new和delete背后深层的秘密
尽管C语言内存管理方式在C++中仍可以继续使用,但有些地方依然无能为力且使用起来比较麻烦,因此C++又提出了自己的内存管理方式:通过new和delete操作符进行动态内存管理。1. new/delete操作内置类型申请和释放单个元素的空间,使用new和delete操作符,申请和释放连续的空间,使用new[]和delete[]2. new/delete操作内置类型在申请自定义类型的空间时,new会调用构造函数,delete会调用析构函数,而malloc与free不会。3. operator ne
2021-03-12 19:28:12 300
原创 运算符重载及其应用——日期类的实现(完整版)
首先,我们先来了解什么是运算符重载?为什么要引入运算符重载?C++为了增强代码的可读性引入了运算符重载,使自定义类型可以像内置类型一样去用运算符。运算符重载是具有特殊函数名的函数,也具有其返回值类型,函数名字以及参数列表,其返回值类型与参数列表与普通的函数类似。函数原型:返回值类型 operator需要重载的操作符(参数列表)注意事项如下:1、 不能通过连接其他符号来创建新的操作符:比如operator@2、重载操作符必须有一个类类型或者枚举类型的操作数3、用于内置类型的操作符,其
2021-03-06 21:46:10 963
原创 引用(C++入门)
文章目录一、引用的概念二、引用的特性三、常引用四、使用场景(作用)五、引用和指针的区别一、引用的概念引用不是新定义一个变量,而是给已存在变量取了一个别名,编译器不会为引用变量开辟内存空间,它和它引用的变量共用同一块内存空间。类型& 引用变量名(对象名) = 引用实体;注意:引用类型必须和引用实体是同种类型的。void TestRef(){ int a = 10; int& ra = a;//<====定义引用类型 printf("%p\n", &a);
2021-02-10 20:22:21 137
原创 为什么C++支持函数重载,而C语言不支持?
首先,什么是函数重载?函数重载:是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,这些同名函数的形参列表(参数个数 或 类型 或 顺序)必须不同,常用来处理实现功能类似数据类型不同的问题int add(int a, int b){ return a + b;}double add(double a,double b){ return a + b;}因此,以上两个函数即为典型的函数重载。int add(int a, int b){ return a+b;
2021-02-03 23:28:34 248
原创 【数据结构】最全排序汇总 | 考研
本文主要内容1. 排序及其相关概念的介绍2. 常见排序及其算法实现3. 排序算法复杂度及稳定性分析提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档目录本文主要内容前言一、排序及其相关概念的介绍二、常见排序及其算法实现1.引入库2.读入数据总结前言提示:这里可以添加本文要记录的大概内容:例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。一、排序及其相关概念的介绍排序:使一串记录,按照其中的某个或
2021-02-03 02:49:18 1952 8
原创 Leetcode — 40. 最小的k个数(剑指Offer|用建堆来实现)
题目描述:输入整数数组 arr ,找出其中最小的 k 个数。题目链接算法描述:提示:这里可以添加要学的内容例如:1、 搭建 Java 开发环境2、 掌握 Java 基本语法3、 掌握条件语句4、 掌握循环语句代码实现:提示:这里可以添加计划学习的时间例如:1、 周一至周五晚上 7 点—晚上9点2、 周六上午 9 点-上午 11 点3、 周日下午 3 点-下午 6 点优点分析:提示:这里统计学习计划的总量例如:1、 技术笔记 2 遍2、CSDN 技术博客 3 篇
2021-01-21 19:20:46 415 1
原创 Leetcode — 用栈实现队列&用队列实现栈 (C语言)
一、用栈实现队列:题目描述:请你仅使用两个栈实现先入先出队列。队列应当支持一般队列的支持的所有操作(push、pop、peek、empty):实现 MyQueue 类:void push(int x) 将元素 x 推到队列的末尾int pop() 从队列的开头移除并返回元素int peek() 返回队列开头的元素boolean empty() 如果队列为空,返回 true ;否则,返回 false说明:你只能使用标准的栈操作 —— 也就是只有 push to top, peek/pop
2021-01-21 00:34:24 337
原创 Leetcode — 147.对链表进行插入排序
题目描述:对链表进行插入排序。题目链接算法描述:插入排序算法:1.插入排序是迭代的,每次只移动一个元素,直到所有元素可以形成一个有序的输出列表。2.每次迭代中,插入排序只从输入数据中移除一个待排序的元素,找到它在序列中适当的位置,并将其插入。3.重复直到所有输入数据插入完为止举例说明:思路分析:1.:将待排序链表的头拿出,作为新链表的头,然后依次把剩余的结点插入到以这个头为头的新链表中。2.确定插入位置:从前往后遍历,为当前要插入的结点找到正确的插入位置即可。第一种情况:
2021-01-16 00:42:10 185
原创 C语言程序环境和预处理
C语言程序环境和预处理内容包括:程序的翻译环境和执行环境、预处理标识符#和##、预处理指令、宏和函数的比较、命令行定义、条件编译和文件包含。文章目录C语言程序环境和预处理前言一、程序的翻译环境和执行环境二、使用步骤1.引入库2.读入数据二、使用步骤总结前言本文内容主要对我们在写完代码之后,编译执行过程的详细说明。因此也会引出在编译之前进行的处理 —— 预处理命令的说明提示:以下是本篇文章正文内容,下面案例可供参考一、程序的翻译环境和执行环境示例:pandas 是基于NumPy 的一种
2020-11-22 23:33:08 634 2
原创 文件操作 - C语言
C语言文件操作什么是文件?磁盘上的文件一般都叫文件。而在程序设计中,我们一般说的文件有两种:(1) 程序文件:源程序文件(后缀为.c),目标文件(windows环境后缀为.obj),可执行程序(windows环境后缀为.exe)。(2) 数据文件:文件的内容不一定是程序,而是程序运行时读写的数据,比如程序运行需要从中读取数据的文件,或者输出内容的文件,文本文件(后缀为.txt)等。这里,我们主要讨论的文件类型是数据文件。在以前的学习中,我们所处理数据的输入输出都是以终端为对象的,即从终端
2020-11-15 23:32:50 234
原创 关于动态内存分配
为什么存在动态内存分配?我们之前掌握的内存开辟方式是在栈区开辟的:int val = 20;//在栈空间上开辟四个字节char arr[10] = {0};//在栈空间上开辟10个字节的连续空间栈区内存开辟的特点:大小固定数组在声明的时候,必须指定数组的长度,并且它所需要的内存在编译时分配。所谓动态内存分配,就是指在程序在执行的过程中,动态地分配或者回收存储空间的分配内存的方法。动态内存分配不需要像数组等静态内存分配方法那样预先的分配存储空间,而是由系统根据程序的需要即时分配,且分配的
2020-11-02 23:28:15 615
原创 详解自定义类型(结构体+位段+枚举+联合)
结构体结构是一些值的集合,这些值被称为成员变量,结构的每个成员可以是不同类型的变量。1. 结构体类型的声明及变量的定义和初始化struct tag{ //成员}/*变量*/ ;例如:struct Stu { char name[20];//名字 int age;//年龄 char sex[5];//性别 };s1, s2;//直接在这儿通过struct student创建了两个变量s1,s2,它们是全局变量int main(){ //单独创建的
2020-11-01 16:09:38 462 1
原创 总结字符函数、字符串函数及内存操作函数
一、字符与字符串字符类型是C语言中的主要数据类型之一。字符变量并不是把该字符本身放到内存单元中,而是将该字符对应的ASCII码值放入变量的存储单元中,所以char的本质可以理解为一个大小为1的整型。字符变量的创建:char c = 'a';C语言中字符类型的变量中不能存放汉字,因为只有1个字节大小。特殊的字符 - 转义字符常用的转义字符转义字符释义\n换行\t水平制表符\v垂直制表符\a警告字符,蜂鸣\?在书写连续多个问号时使用,防止他
2020-10-28 21:07:53 418
原创 数据在内存中的存储
什么是内存? 在计算机的组成结构中,有一个很重要的部分,就是存储器。存储器是用来存储程序和数据的部件,对于计算机来说,有了存储器,才有记忆功能,才能正常工作。存储器的种类很多,按其用途可分为主存储器和辅助存储器,主存储器又称内存储器,简称内存。内存,被分为一个一个的内存单元。一个内存单元我们通常规定放一个字节。数据类型的详细介绍数据类型分为:内置类型和自定类型数据类型的意义:(1) 使用这个类型开辟内存空间的大小(2) 决定了我们如何看待内存空间的视角类型的基本归类:1.整型家族:char s
2020-09-27 00:28:19 584 1
原创 【C语言】扫雷
创建头文件和相应的.c文件其中,game.h用于写入所有要包含的头文件,要声明的宏常量及要使用的函数声明。#include<stdio.h>#include<stdlib.h>#include<time.h>#define ROW 9#define COL 9#define ROWS ROW+2#define COLS COL+2//初始化void InitBoard(char board[ROWS][COLS],int row,int col);
2020-09-10 23:14:31 329
原创 【C语言】三子棋练习
首先,在编程之前,要创建头文件和相应的.c文件其中,game.h文件用于写入所有要用的头文件,实现三子棋游戏的所有函数的声明和宏常量的定义。#include<stdio.h>#include<stdlib.h>#include<time.h>#define ROW 3#define COL 3void InitBoard(char board[ROW][COL], int row, int col); //棋盘的初始化void print_board(c
2020-09-06 22:21:28 187
原创 【C语言】求两个数最大公约数
方法一:直接求解#include<stdio.h>int main(){ int a = 0, b = 0; int min = 0; scanf("%d%d", &a, &b); if (a > b) { min = b; } else min = a; int i = 0; for (i = min; i < 1; i--) { if (a%i == 0 && b%i == 0) { break;
2020-08-20 21:44:55 276 2
原创 【C语言】将三个数按从大到小输出
#include<stdio.h>void swap(int *pa, int *pb){ int ret = 0; ret = *pa; *pa = *pb; *pb = ret;}int main(){ int a = 0; int b = 0; int c = 0; scanf("%d%d%d", &a, &b, &c); if (a < b) { swap(&a, &b); } if (a < c)
2020-08-20 21:39:47 291
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人