自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 高级IO模型

文章目录高级IO一、高阶IO重要概念1、同步通信 vs 异步通信2、阻塞 vs 非阻塞二、五种IO模型1、阻塞IO2、非阻塞IO3、信号驱动IO4、多路转接IO5、异步IO重点学习:多路转接IO一、select模型1、select函数2、socket就绪条件3、select的特点4、select缺点二、poll 模型1、poll函数2、socket就绪条件3、poll的优点&&缺点三、epoll模型1、epoll函数2、epoll的使用过程3、epoll的优点(和 select 的缺点对应)

2021-08-19 16:57:01 390 2

原创 网络:传输层协议:TCP&&UDP

文章目录UDP1.UDP特点2.UDP协议段格式3.UDP的缓冲区4.UDP使用注意事项5.基于UDP的应用层协议TCP1.TCP特点2.TCP协议段格式3.TCP的三种机制(1)确认应答(ACK)机制(2)超时重传机制(3)连接管理机制4.TCP传输的两种状态(1)TIME_WAIT状态(2)CLOSE_WAIT 状态5.滑动窗口6.流量控制7.拥塞控制UDP1.UDP特点传输层协议属于传输层协议;无连接知道对端的IP和端口号就直接进行传输, 不需要建立连接;不可靠传输没有确认机制, 没

2021-06-09 09:35:50 387 2

原创 网络编程:HTTP:长短链接

长短链接文章名字虽然叫HTTP:长短链接,但HTTP本身是无状态,无连接的,长短连接属于通信细节,由传输层TCP协议负责建立。HTTP分为长连接和短连接,其实本质上是TCP连接。TCP连接是一个双向的通道,它可以保持一段时间不关闭,因此TCP连接才有真正的长连接和短连接的说法。在互联网发展早期,一个网页中只包含文本,甚至没有图片,在传输数据时使用短链接便足够,但如今在一个网页中包含多种“元素“,如:文本,图片,视频,音频,各种链接等等;使用短链接效率大大不足支持数据的传输。现如今我们平时用的基本上

2021-06-07 12:34:09 569

原创 图解HTTPS加密过程

文章目录HTTPHTTPS概念即组成SSL/TSL概念SSL/TSL的运作流程对称加密 / 非对称加密HTTPS密钥协商HTTPS中间人攻击劫持问题远端服务器身份认证问题中间信息被篡改问题HTTPhttps在我之前的博客中已经有所讲解。敬请移步Linux:了解HTTP协议HTTPS概念即组成HTTPS (全称:Hyper Text Transfer Protocol over SecureSocket Layer),是以安全为目标的 HTTP 通道,在HTTP的基础上通过传输加密和身份认证保证了传

2021-06-02 22:49:27 935 5

原创 Linux:了解HTTP协议

文章目录HTTP && HTTPS协议1.概念2.其他相关概念(1)认识url(2)urlencode和urldecode3.HTTP协议格式(1)HTTP请求(2)HTTP相应4.HTTP的方法5.HTTP的状态码6.HTTP常见Header7.代码实现简单的HTTP服务器HTTP && HTTPS协议1.概念HTTP:是互联网上应用最为广泛的一种网络协议,是一个客户端和服务器端请求和应答的标准(TCP),用于从WWW服务器传输超文本到本地浏览器的传输协议,它可以使浏

2021-05-31 17:19:54 277 2

原创 详谈HTTP协议中的cookie与session功能

文章目录cookie&&session1.概念(1)**cookie是一种储存在用户本地终端上的数据**(2)**session在网络应用中,称为“会话控制”**2.图解cookie运作流程3.图cookie++session运作流程cookie&&session相信大家都有过在网页上登录某一账号的经历,比如CSDN、知乎、B站等等;在一次登陆过后,即使关掉浏览器,在下一次访问该网页时,上次登陆过的账号会自动登录。我们知道,http协议本身是无连接、无状态的;它是由TC

2021-05-31 16:03:12 478 3

原创 c++:继承

继承1.继承的概念继承(inheritance)机制是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特性的基础上进行扩展,增加功能,这样产生新的类,称派生类。继承呈现了面向对象程序设计的层次结构,体现了由简单到复杂的过程。从类设计出发,避免重复定义数据以及方法,进行类角度的复用//下面我们看到Person是父类,也称作基类。Student是子类,也称作派生类。class Person{public: void Print() { cout << "n

2021-05-19 20:42:45 257 8

原创 二叉树的遍历:迭代实现

二叉树的遍历:迭代实现二叉树有两种遍历方式:递归实现以及迭代实现,递归实现相信大家已经非常熟悉,今天为大家介绍二叉树的迭代实现以及其代码实现;迭代遍历的好处我们都知道,递归调用的函数是存在中“栈”中的,但是栈的容量并不大;在进行递归实现时,如果构造的二叉树过大,容易栈溢出;但是在使用迭代实现时,是将所遍历的节点存在已经开好的空间中,这个空间开在“堆”上,堆的容量可以认为是无限大的,便不存在溢出的问题。迭代遍历代码实现前序遍历前序遍历:根节点->左孩子->右孩子;思路:定义一个当

2021-05-17 10:58:47 396 7

原创 c++:二叉搜索树BinarySortTree

文章目录二叉搜索树BinarySortTree1.二叉搜索树概念2.二叉搜索树操作(1)查找(2)插入节点(3)删除节点3.二叉搜索树的代码实现(1)功能实现(2)测试二叉搜索树BinarySortTree1.二叉搜索树概念二叉搜索树又称二叉排序树,它或者是一棵空树,或者是具有以下性质的二叉树:若它的左子树不为空,则左子树上所有节点的值都小于根节点的值若它的右子树不为空,则右子树上所有节点的值都大于根节点的值它的左右子树也分别为二叉搜索树如图所示二叉搜索树最大的功能便是搜索;一般来讲它比顺

2021-05-13 14:38:28 264 4

原创 linux:网络:socket套接字

文章目录套接字socket相关概念1.源IP地址和目的IP地址2.端口号 port3."端口号" 和 "进程ID"4.源端口号和目的端口号5.套接字的本质6.TCP协议7.认识UDP协议8.网络字节序9.socket编程接口10.sockaddr结构简单的UDP网络程序1.服务器端(接收消息)2.用户端发送消息3.运行截图套接字socket加粗样式在正式接触网络编程套接字之前,需要先认识几个基本概念。1.源IP地址和目的IP地址2.端口号port3.“端口号” 和 "进程ID"4.源端口号和目

2021-05-12 22:36:39 237 5

原创 linux:线程 POSIX信号量&&线程池

文章目录POSIX信号量1.POSIX信号量的系统调用函数(1)初始化信号量(2)销毁信号量(3)等待信号量(4)发布信号量2.基于环形队列的生产消费模型(1)生产快&&消费慢(1)生产慢&&消费快线程池1.什么是线程池2.使用场景3.线程池简单代码实现POSIX信号量POSIX信号量和SystemV信号量作用相同,都是用于同步操作,达到无冲突的访问共享资源目的。 但POSIX可以用于线程间同步。1.POSIX信号量的系统调用函数头文件:#include<sem

2021-04-27 12:40:55 205 1

原创 linux:线程&&多线程 初见

线程1. Linux线程概念线程是在进程中独立运行的子任务,可以理解为一个“轻量级进程”,一个进程内可以有多个线程,这些线程使用同一个PCB。1.在一个程序里的一个执行路线就叫做线程(thread)。更准确的定义是:线程是“一个进程内部的控制序列”。2.一切进程至少都有一个执行线程。3.线程在进程内部运行,本质是在进程地址空间内运行。4.在Linux系统中,在CPU眼中,看到的PCB都要比传统的进程更加轻量化。5.透过进程虚拟地址空间,可以看到进程的大部分资源,将进程资源合理分配给每个执行流,

2021-04-24 16:14:29 147

原创 OJ.evalRPN逆波兰表达式

来自某扣的OJ小练习根据 逆波兰表示法,求表达式的值。有效的算符包括 +、-、*、/ 。每个运算对象可以是整数,也可以是另一个逆波兰表达式。说明:整数除法只保留整数部分。给定逆波兰表达式总是有效的。换句话说,表达式总会得出有效数值且不存在除数为 0 的情况。解决方法:建立一个栈,遇到数字便入栈,遇到运算符便运算,使栈顶数据作为右值,栈顶的前一个值作为左值,运算之后的结果继续入栈,最终返回栈中唯一数据,即栈顶即可。int evalRPN(vector<string>& t

2021-04-16 16:13:28 179

原创 linux学习:信号初识

文章目录信号信号列表查看信号的产生1.终端按键产生信号2.调用系统函数向进程发信号3.由软件条件产生信号4.硬件异常产生信号信号捕捉初识简单的信号捕捉模拟代码实现阻塞信号1.信号相关概念2.在内核中的表示3.sigset_t4.信号集操作函数5.模拟实现捕捉信号(自定义捕捉)1.定义2.信号的捕捉(1)信号捕捉在内核中的实现(2) sigactionvolatile信号信号的概念:信号是进程之间事件异步通知的一种方式,属于软中断信号列表查看用kill -l命令可以察看系统定义的信号列表编号34以上

2021-04-15 22:22:12 212

原创 c++:stl中list的模拟实现

list1、list的介绍及使用list是可以在常数范围内在任意位置进行插入和删除的序列式容器,并且该容器可以前后双向迭代。list的底层是带头双向链表结构,双向链表中每个元素存储在互不相关的独立节点中,在节点中通过指针指向其前一个元素和后一个元素。list与forward_list非常相似:最主要的不同在于forward_list是单链表,只能朝前迭代,已让其更简单高效。与其他的序列式容器相比(array,vector,deque),list通常在任意位置进行插入、移除元素的执行效率更好。与

2021-04-14 10:43:46 165

原创 进程间通信:共享内存

共享内存共享内存是最快的IPC形式共享内存就是允许两个不相关的进程访问同一个虚拟内存。共享内存是在两个正在运行的进程之间共享和传递数据的一种非常有效的方式。共享内存函数1.int shmget(key_t key,int shmsz,int shmflg);Shmget()函数分配一块新的共享内存。Shmsz指明共享内存的大小,以字节为单位,shmflg的设置与信号量的semget()函数中的参数semflg类似。如果shmget()函数调用成功则返回共享内存的ID;否则返回-1.2.void

2021-04-10 13:03:43 255 1

原创 C++:vector的模拟实现

vector的介绍与特点vector是表示可变大小数组的序列容器。vector采用的连续存储空间来存储元素。也就是意味着可以采用下标对vector的元素进行访问,和数组一样高效。但是又不像数组,它的大小是可以动态改变的,而且它的大小会被容器自动处理。vector使用动态分配数组来存储它的元素。当新元素插入时候,这个数组需要被重新分配大小为了增加存储空间。其做法是,分配一个新的数组,然后将全部元素移到这个数组。每当一个新的元素加入到容器的时候,vector并不会每次都重新分配大小。vector分配空

2021-04-09 10:01:23 867 1

原创 linux进程间通信:匿名管道&&命名管道

linux进程间通信:匿名管道&&命名管道什么是管道管道是Unix中最古老的进程间通信的形式。我们把从一个进程连接到另一个进程的一个数据流称为一个“管道”1.匿名管道#include <unistd.h>功能:创建一无名管道原型int pipe(int fd[2]);参数:fd:文件描述符数组,其中fd[0]表示读端, fd[1]表示写端返回值:成功返回0,失败返回错误代码(1)匿名管道的代码实现以及分析:管道的四个重要结论1.当实际读取时,如果读取条件

2021-04-07 22:54:48 221 2

原创 深浅拷贝与string类

深浅拷贝深拷贝的就是多层拷贝对象或数组中的数据,浅拷贝的话就是拷贝一层数据1、浅拷贝浅拷贝就是只是把另一个变量的值拿过来;int main(){ test::string s1("hello world!"); test::string s2(s1); s2[0] = 'x'; cout << s1.c_str() << endl; cout << s2.c_str() << endl;}如图&&代码:实现浅拷贝;先s

2021-04-01 21:43:59 907 1

原创 c++中string关于 系统调用接口 的常见操作

c++中string关于 系统调用接口 的常见操作1.插入字符串insert和+=的运算符重载是string的常见插入方式;一般不推荐使用insert,在头插与中间插入时需要移动数据,效率不高;insert常见用法:int main(){ //不推荐使用insert,在头插与中间插入时需要移动数据,效率不高 //insert的常见操作 string s1("1234"); s1.insert(s1.begin(), '0');//在s1的begin(即索引为0)处

2021-03-27 16:00:34 469 2

原创 计算三角形面积-----c语言

此处用到正余弦定理;先用三边求出某一角的余弦值,由cosAcosA+sinAsinA=1可求得sinA的值,然后由三角形面积公式求出;源代码如下:int main(){ float a, b, c, cosA, sinA;//a,b,c分别为三角形三边长,d为三角形中a边所对角 的 cos值,e为sin值。 printf("请输入三角形三边的长度:"); scanf_s("%f%f%f", &a, &b, &c);//输入三角形三边的长度 cos

2021-03-27 13:45:33 663

原创 c++中string类

string了解string是表示字符串的字符串类该类的接口与常规容器的接口基本相同,再添加了一些专门用来操作string的常规操作。比特科技string在底层实际是:basic_string模板类的别名,typedef basic_string<char, char_traits, allocator>string;不能操作多字节或者变长字符的序列。在使用string类时,必须包含#include头文件以及using namespace std;string常用接口说明1

2021-03-22 22:13:57 962 2

原创 日期计算器:C++日期类的实现(赋值运算符重载实现)以及赋值运算符重载

日期类具体功能1、获取每个月的天数2、判断两个日期是否同一天3、判断两个日期的先后4、某日期在某天后的日期5、某日期在某天前的日期6、日期减日期所得天数赋值运算符C++为了增强代码的可读性引入了运算符重载,运算符重载是具有特殊函数名的函数,也具有其返回值类型,函数名字以及参数列表,其返回值类型与参数列表与普通的函数类似。在C语言中,我们如果要实现两个数字相加,则需要定义一个函数,函数名为Add()或者有些取名不规范叫做Jia()或其他名字,并不是人人一眼都能看懂;但是c++中的赋值运算符重

2021-02-05 16:07:21 1338 4

原创 C++基础知识(命名空间、输入&输出、缺省函数、函数重载)

命名空间1、为什么使用命名空间在C/C++中,变量、函数和类都是大量存在的,这些变量、函数和类的名称将都存在于全局作用域中,可能会导致很多冲突。使用命名空间的目的是对标识符的名称进行本地化,以避免命名冲突或名字污染,namespace关键字的出现就是针对这种问题的。2、命名空间定义定义命名空间,需要使用到namespace关键字,后面跟命名空间的名字,然后接一对{}即可,{}中即为命名空间的成员。namespace cpp{ int a = 3; int b = 5;//全局变量,放到命名

2021-01-31 17:23:39 144

原创 二叉树的前序、中序、后序遍历以及节点个数返回(C语言实现)

二叉树建立#pragma once#include<stdio.h>#include<stdlib.h>#include<assert.h>typedef int DataT;//建立二叉树节点的结构体typedef struct BinaryTreeNode{ DataT val; struct BinaryTreeNode* right; struct BinaryTreeNode* left;}BinaryTreeNode;//前序遍历

2021-01-31 16:18:07 403 2

原创 常见的几种排序(插入排序、希尔排序、选择排序、冒泡排序、快速排序、归并排序)

void Swap(int* p, int* q){ int tmp = *q; *q = *p; *p = tmp;}//三数取中int GetMidIndex(int* a, int begin, int end){ int mid = (begin + end) / 2; if (a[begin] < a[mid]) { if (a[mid] < a[end]) return mid; else if (a[begin] > a[end])

2021-01-27 17:37:40 1532 5

原创 OJ.对链表进行插入排序

链表中的插入排序插排的逻辑无需多说,直接上代码:typedef struct ListNode ListNode;struct ListNode* insertionSortList(struct ListNode* head){ if(head==NULL||head->next==NULL) return head; //新链表头节点为sorthead ListNode* sorthead=head; ListNode* cur=head->n

2021-01-24 12:14:19 232

原创 OJ.删除排序链表中的重复元素 II

给定一个排序链表,删除所有含有重复数字的节点,只保留原始链表中 没有重复出现 的数字。思路定义一个fast节点,一个cur节点,两个节点同时从head出发,val相同时,cur不动,fast向后走,直到与cur的val不相同,定义一个prev前驱节点保存cur的前一个节点;然后删除prev与fast之间的所有节点,然后继续迭代;附上代码:struct ListNode* deleteDuplicates(struct ListNode* head){ //如果链表为空或只有一个结点,直接

2021-01-24 12:10:49 136

原创 OJ、用栈实现队列&用队列实现栈

用栈实现队列typedef int DataT;typedef struct Stack{ int* a; int top;//栈顶下标 int capacity;//目标容量}Stack;//初始化void StackInit(Stack* pst){ assert(pst); pst->a = (int *)malloc(sizeof(DataT)*4); pst->top = 0; pst->capacity = 4;}//销毁void Stac

2021-01-16 20:32:42 145

原创 双向带头链表的增删查改

双向带头链表的增删查改双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。一般我们都构造双向循环链表。#define _CRT_SECURE_NO_WARNINGS 1#include<stdio.h>#include<assert.h>#include<stdlib.h>typedef int DataType;//双向链表的建立t

2021-01-06 15:17:14 83

原创 数组中数字出现的次数

一个整型数组 nums 里除两个数字之外,其他数字都出现了两次。请写程序找出这两个只出现一次的数字。#define _CRT_SECURE_NO_WARNINGS#include <stdio.h>#include <stdlib.h>#include <string.h>//异或int ContinuousXor(int* arr, int sz){ int ret = 0; for (int i = 0; i < sz; i++) { r

2020-12-29 16:36:04 221 1

原创 斐波那契数列

用递归和迭代两种方法://迭代算法int Fib(int num){ int a = 0, b = 1; int c = 0; for (int i = 1; i < num; i++) { c = a + b; a = b; b = c; } return c;}//递归算法int Fib(int num){ //斐波那契数列前两项都为1 if(num=1||num=2) { return 1; } if(num>=3) {

2020-12-29 15:10:29 161

原创 OJ.删除链表指定节点

给定单向链表的头指针和一个要删除的节点的值,定义一个函数删除该节点。返回删除后的链表的头节点。示例 1:输入: head = [4,5,1,9], val = 5输出: [4,1,9]解释: 给定你链表中值为 5 的第二个节点,那么在调用了你的函数之后,该链表应变为 4 -> 1 -> 9.思路:双指针。cur定义为要删除的节点,prev为cur之前的那个节点,cur从head一直往后走,找到要删除的节点后,使prev->next=cur->next,再释放cur。st

2020-12-29 14:18:52 207 1

原创 OJ.判断链表是否为回文结构

思路:先找到链表的中间节点,然后将链表从中间节点之后的后半段反转;然后将前半段与后半段逐一进行比较。//链表的建立struct ListNode {int val;struct ListNode *next;};bool isPalindrome(struct ListNode* head){//找到中间节点struct ListNodetwo=head,one=head;while(two&&two->next){one=one->next;tw

2020-12-17 17:09:09 145 2

原创 OJ.只出现一次的数字 III

给定一个整数数组 nums,其中恰好有两个元素只出现一次,其余所有元素均出现两次。 找出只出现一次的那两个元素.思路:将所有数异或之后;numN=两个目标数的异或(两个相同的数异或结果为0,0与任何数异或结果为那个数本身),找出异或之后newN位数为1的位(这一位上两个目标数必是一个为1,另一个为0),将数组中这一位为1的分为一组异或,为0的分为一组异或,便得到两个目标数。int* singleNumber(int* nums, int numsSize){int newN=0;//将所有数异或

2020-12-16 17:12:31 220 1

原创 九九乘法表以及更多

九九乘法表的打印附上源代码#include<stdio.h>int main(){int a, b, c;for (a = 1; a <= 9; a++){for (b = 1; b <= a; b++){c = a * b;printf("%d*%d=%d “, a, b, c);}printf(”\n");}}我们还可以给定一个值num,打印这个值的乘法表,用例为12#define _CRT_SECURE_NO_WARNINGS 1#i

2020-12-10 11:03:38 103

原创 计算1!+2!+3!+4!+5!+6!+......+20!

#define _CRT_SECURE_NO_WARNINGS 1#include<stdio.h>#include<stdio.h>int main(){int n; //循环控制变量scanf("%d", &n);unsigned long long i, m = 1;//累乘的初始值为1unsigned long long s = 0;//累加的初始值为0for (i = 1; i <= 20; i++){m = m * i;//累乘s .

2020-12-09 17:41:50 1345

原创 动态顺序表的增删查改

#pragma once#define _CRT_SECURE_NO_WARNINGS 1#include<stdio.h>#include<stdlib.h>#include<assert.h>typedef int SLDT;#define N 10typedef struct SL{SLDT a;SLDT size;//有效数据数量SLDT cap;//容量}SL;//初始化void SeqListInit(SL ps){ps-&g.

2020-12-07 17:54:41 103

原创 单身狗(异或算法)

#define _CRT_SECURE_NO_WARNINGS 1#include<stdio.h>#include<string.h>#include<stdlib.h>int main(){int n=0;int a[100] = { 1,1,2,2,3,3,4,4,5,6,6,7,7,8,8,9,9 };for (int i = 0; i < 99; i++){n = n ^ a[i];}printf("%d", n);return.

2020-12-04 16:53:36 312

原创 逆序输出字符串的两种方法

逆序输出字符串一#define _CRT_SECURE_NO_WARNINGS#include <stdio.h>#include <string.h>int main(){char a[100];scanf("%s", &a);int len = strlen(a);//获取字符串长度for (int i = len - 1; i >= 0; i–){//从尾到前遍历printf("%c", a[i]);}return 0;}二

2020-12-02 18:53:01 9644 2

空空如也

空空如也

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

TA关注的人

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