自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 2021-08-31

构造链表的结构体(数据、指针)struct node{ int data; // 数据 node* next; // 指针};使用new运算符为节点分配内存node* p = new node;编写创建列表函数,参数为链表的长度(从用户cin输入读入),返回值为创建的列表的头指针node* create(int len){ node *p, *pre, *head; // 临时指针,指向前驱节点,头指针 head = new node; // 为头指针分配内存

2021-08-31 23:17:23 232

原创 解决VScode调试时报错GDB failed with message

调试报错界面信息如下原因及解决办法原因:代码路径中存在中文名,导致出现这样的问题解决办法:修改代码路径的中文名为英文路径即可正常调试情况

2021-05-01 09:59:39 7307 8

转载 valgrind检测的5种内存泄漏情况详解

摘要:valgrind是linux下用于调试程序和查找内存泄露的常用工具。valgrind会报告5种内存泄露,“definitely lost”, “indirectly lost”, “possibly lost”, “still reachable”, and “suppressed”。笔者于工作闲暇之余对这5种(其实是4种,有一种没研究出结果)内存泄露的出现原因及区别进行了研究,撰此文以记之。官方解释及分析:摘自http://valgrind.org/docs/manual/faq.html#f

2021-04-30 12:53:15 6349 1

转载 Tomcat详细简介

转载链接:lhttps://blog.csdn.net/u014231646/article/details/79482195一、概念Tomcat 服务器是一个开源的轻量级Web应用服务器,在中小型系统和并发量小的场合下被普遍使用,是开发和调试Servlet、JSP 程序的首选。二、原理Tomcat结构图:Tomcat主要组件:服务器Server,服务Service,连接器Connector、容器Container。连接器Connector和容器Container是Tomcat的核心。一个Co

2021-04-18 14:08:57 297

原创 Linux如何查看某个进程打开的文件数

lsof指令lsof [选项] 文件/进程名/进程ID项目Value-c显示指定的进程名所打开的文件-p显示指定的进程号所有打开的文件-i通过监听指定的协议、端口和主机等信息,显示符合条件的进程信息-u显示指定用户使用的文件-U显示所有socket文件通过lsof命令结合管道查看某个特定进程打开的文件数[root@xinogte ~]# lsof -p 1278 | wc -l19...

2021-04-08 14:58:02 2717

原创 单Reactor和主从Reactor模式介绍

单Reactor模式单Reactor需要响应连接和读写事件,单线程处理任务较多单Reactor连接和读写事件放在一块处理,会互相影响,而且本身读写事件是一个比较耗时的操作,当一个读写事件处理事件太长,那么势必会影响下一个连接事件的处理,影响用户连接,这是个非常不友好的事情,很影响体验。主从Reactor模式1.主从Reactor将会使用两个Reactor,主Reactor响应连接事件,从Reactor响应读写事件2.主Reactor的selector只关注连接事件,接受到一个连接之后,将通道注

2021-04-02 15:41:54 452

转载 编写项目的过程中使用do{ } while(0)的好处

在阅读项目源码的过程中,发现原发大量使用do{} while (0)觉得挺奇怪,不知道为什么这么写,网上找了一下发现原因有如下使用do{ } while(0)的好处1.替代{},实现局部作用域.在一些C的实现里也可以用2.避免使用goto语句,用break做跳出当你执行一段代码到一半,想跳过剩下的一半的时候,如果你正处于do while循环中,则能用break达到这个目的。如下伪代码:do{ 我执行 我执行。。 我再执行。。。 if (有什么条件满足了我) { 呀,我

2021-03-28 13:49:24 169

原创 关于epoll_wait的个人理解的一些记忆

该篇博客类似做笔记的行为,记录自己关于学习IO多路复用过程中的一些个人理解,不喜勿喷,谢谢!!~epoll采用的模式为边沿触发非阻塞I/O水平/边沿触发:指的是epoll_wait()的触发行为阻塞/非阻塞I/O:指的是文件描述符的读写(read)行为使用水平触发非阻塞I/O:如果客户端发送10字节,服务端每次只能读5字节,水平触发就会导致缓冲区不断堆积。如果客户端发送5000字节,这5000字节首部有一个50字节长度的标识,服务器每次读取50字节,可以通过判断标识来决定后面的要不要,如果是水平触

2021-03-27 11:00:15 2888

转载 TCP“流和UDP的“保护消息边界“

概述在socket网络程序中,TCP和UDP分别是面向连接和非面向连接的。因此TCP的socket编程,收发两端(客户端和服务器端)都要有一一成对的socket,因此,发送端为了将多个发往接收端的包,更有效的发到对方,使用了优化方法(Nagle算法),将多次间隔较小且数据量小的数据,合并成一个大的数据块,然后进行封包。这样,接收端,就难于分辨出来了,必须提供科学的拆包机制。对于UDP,不会使用块的合并优化算法,这样,实际上目前认为,是由于UDP支持的是一对多的模式,所以接收端的skbuff(套接字缓冲

2021-03-25 07:59:05 390

原创 Recator模式的一些概念记录

Reactor模式的基本概念Reactor模式是事件驱动模型,有一个或多个并发输入源,有一个Service Handler,有多个Request Handlers;这个Service Handler会同步的将输入的请求(Event)多路复用的分发给相应的Request Handler。从结构上,这有点类似生产者消费者模式,即有一个或多个生产者将事件放入一个队列中,而一个或多个消费者主动的从这个队列中提取事件来处理;而Reactor模式则并没有队列来做缓冲,每当一个Event输入到Service Handl

2021-03-22 13:06:13 271

转载 零拷贝的概念详解

传统IO在开始谈零拷贝之前,首先要对传统的IO方式有一个概念。基于传统的IO方式,底层实际上通过调用read()和write()来实现。通过read()把数据从硬盘读取到内核缓冲区,再复制到用户缓冲区;然后再通过write()写入到socket缓冲区,最后写入网卡设备。整个过程发生了4次用户态和内核态的上下文切换和4次拷贝,具体流程如下:用户进程通过read()方法向操作系统发起调用,此时上下文从用户态转向内核态DMA控制器把数据从硬盘中拷贝到读缓冲区CPU把读缓冲区数据拷贝到应用缓冲区,

2021-03-21 11:25:37 1129

转载 构造函数为什么不能是虚函数?

从存储空间角度虚函数对应一个vtable,这大家都知道,可是这个vtable其实是存储在对象的内存空间的。问题出来了,如果构造函数是虚的,就需要通过 vtable来调用,可是对象还没有实例化,也就是内存空间还没有,无法找到vtable,所以构造函数不能是虚函数。从使用角度虚函数主要用于在信息不全的情况下,能使重载的函数得到对应的调用。构造函数本身就是要初始化实例,那使用虚函数也没有实际意义呀。所以构造函数没有必要是虚函数。从实现上看vbtl在构造函数调用后才建立,因而构造函数不可能成为..

2021-03-20 20:49:01 403

原创 C++之override关键字

概念在成员函数声明或定义中, override 确保该函数为虚函数并覆写来自基类的虚函数。使用位置在函数调用运算符之后,函数体或纯虚函数标识 “= 0” 之前。不使用override关键字的效果#include <iostream>using namespace std;class Base{public: virtual void foo() { cout << "Base::foo" << endl; } virtual void go

2021-03-17 08:45:19 769 1

原创 冒泡排序算法

什么是冒泡排序冒泡排序(Bubble Sort),是一种计算机科学领域的较简单的排序算法。它重复地走访过要排序的元素列,依次比较两个相邻的元素,如果顺序(如从大到小、首字母从Z到A)错误就把他们交换过来。走访元素的工作是重复地进行直到没有相邻元素需要交换,也就是说该元素列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端(升序或降序排列),就如同碳酸饮料中二氧化碳的气泡最终会上浮到顶端一样,故名“冒泡排序”。原始的冒泡排序是稳定的,由于该排序算法的每一轮都要遍历一遍所有的元

2021-03-16 21:50:53 155

原创 TCP通信粘包问题分析和解决方法

粘包问题分类一种是粘在一起的包都是完整的数据包,一种是粘在一起的包有不完整的包。并非所有的粘包现象都需要处理,若传输的数据为不带结构的连续流数据(如文件传输),则不必把粘连的包分开(简称分包)。但在实际工程应用中,传输的数据一般为带结构的数据,这时就需要做分包处理。在处理定长结构数据的粘包问题时,分包算法比较简单;在处理不定长结构数据的粘包问题时,分包算法就比较复杂。特别是粘在一起的包有不完整的包的粘包情况,由于一包数据内容被分在了两个连续的接收包中,处理起来难度较大。实际工程应用中应尽量避免出现

2021-03-16 21:24:21 340 2

原创 map底层使用红黑树实验的原因

1、红黑树红黑树是一种二叉查找树,但在每个节点增加一个存储位表示节点的颜色,可以是红或黑(非红即黑)。通过对任何一条从根到叶子的路径上各个节点着色的方式的限制,红黑树确保没有条路径会比其它路径长出两倍,因此,红黑树是—种弱平衡二叉树,相对于要求严格的AVL树来说,它的旋转次数少,所以对于搜索,插入,删除操作较多的情况下,通常使用红黑树。性质1.每个节点非红即黑2.根节点是黑的3.每个叶节点(叶节点即树尾端NULL指针或NULL节点)都是黑的4.如果一个节点是红色的,则它的子节点必须是黑色的。5

2021-03-15 14:51:23 285

原创 关于个人科研中使用Psychtoolbox制作刺激界面的原理解释及代码说明

闪烁刺激原理Psychtoolbox通过双缓存技术,在windows后台创建多个Flip缓存区域,将需要表现的闪烁刺激以纹理的形式在后台缓存区。然后通过VBL垂直回扫信号捕捉到显示屏刷新的时间,在刺激开始时将刺激纹理按每帧(通过Screen(‘Flip’,win,ifi)函数)一个编写好的缓存纹理的顺序呈现,以达到刺激界面的时间戳上的精确呈现效果。matlab相关代码说明通过0-1编码技术,实现显示器屏幕刷新速度/(0-1编码个数)=刺激频率的目的。将0/1分别表示不同的“颜色”,例如显示器刷新频率

2021-03-15 10:26:02 2373

原创 gdb调试常见指令总结

gdb调试常见指令前提:调试的程序编译时需要使用 -g命令 **1. 启动gdb** start -- 只执行一步 n -- next s -- step(单步) -- 可以进入到函数体内部 c - continue -- 直接停在断点的位置 **2. 查看代码:** l -- list l 10(函数名) l filename:行号(函数名) **3. 设置断点:** 设置当前文件断点:

2021-03-14 13:07:13 418

原创 sizeof 运算所得的值是在编译时还是运行时确定?

《C语言程序设计》中对sizeof的描述:C语言提供了一个编译时(compile-time) 一元运算符 sizeof,它可以用来计算任一对象的长度。 表达式sizeof 对象以及sizeof(类型名)将返回一个整型值,它等于指定对象或类型占用的存储空间字节数。依据上述描述,可以得出结论sizeof的值是在编译时确定的,而非运行期确定。如一下举例代码:// 需在C99标准的编译器下编译, ANSI C (即C89)下编译不通过#include <stdio.h>#include &lt

2021-03-13 21:16:03 4948 2

原创 linux中统计某一目录下文件的代码的总行数

代码如下:find . -name "*.cpp"|xargs cat|grep -v ^$|wc -lfind . -name "*.h"|xargs cat|grep -v ^$|wc -l执行效果

2021-03-02 21:02:59 561

原创 GET和POST的区别总结

概括GET方式请求:浏览器会把httpheader和data并发送出去,服务器响应200(返回数据)POST方式请求:浏览器先发送 header,服务器响应100 continue,浏览器再发送data,服务器响应200ok(返回数据)区别get参数通过ur传递,post放在 request body中。ge请求在u中传递的参数是有长度限制的,而pos没有。get比post更不安全,因为参数直接暴露在u中,所以不能用来传递敏感信息。(实际上两者都不是安全的,因为都可以被抓包捕获)get请

2021-02-24 19:45:54 178

原创 操作系统中的结构体对齐、字节对齐

1、原因平台原因(移植原因):不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛岀硬件异常。性能原因:数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问。2、规则数据成员对齐规则:结构(stru或联合 union的数据成员,第一个数据成员放在 offset0的地方,以后每个数据成员的对齐按照# pragma pack指定的数值和这个数据成员自身长

2021-02-24 09:11:32 363

原创 算法刷题时使用if else if与连续if if语句的区别

使用if else输出结果为1#include <iostream>using namespace std;int main () { int a1=1, a2=2, a3=3, a4=4; if (a1 == 1) cout << a1; else if (a2 == 2) cout << a2; else if (a3 == 3) cout << a3; else if (a4 == 4) cout <<

2021-02-14 11:31:58 1072 2

原创 如何屏蔽SIGPIPE信号

#include <stdlib.h>#include <sys/signal.h>//默认读写一个关闭的socket会触发sigpipe信号 该信号的默认操作是关闭进程 这明显是我们不想要的//所以我们需要重新设置sigpipe的信号回调操作函数 比如忽略操作等 使得我们可以防止调用它的默认操作 //信号的处理是异步操作 也就是说 在这一条语句以后继续往下执行中如果碰到信号依旧会调用信号的回调处理函数//处理sigpipe信号void handle_for_s

2021-02-10 13:08:18 1713

原创 for(;;)与while(true)的区别

死循环的有两种写法for(; ;);while(true); // while(1)两者有何区别,为何在源码中多以for(; ;)形式居多?对两条语句分别进行编译结果如下:// 编译前while(1);//编译后mov eax, 1test eax, eaxje foo+23hjmp foo+18h// 编译前for(; ;);// 编译后jmp foo+23h通过对两者分别编译后对比,for(; ;)语句不仅指令少、不占用寄存器,还没有跳转判断指令,比while(1)

2021-02-10 10:02:47 340

原创 C++源文件从文本到可执行文件经历的过程

对于C++源文件,从文本到可执行文件般需要四个过程预处理阶段:对源代码文件中文件包含关系(头文件)、预编译语句(宏定义)进行分析和替换,生成预编译文件。编译阶段:将经过预处理后的预编译文件转换成特定汇编代码,生成汇编文件汇编阶段:将编译阶段生成的汇编文件转化成机器码,生成可重定位目标文件链接阶段:将多个目标文件及所需要的库连接成最终的可执行目标文件...

2021-02-07 22:35:36 210

原创 C++左值引用与右值引用概念

右值引用是C++11中引入的新特性,它实现了转移语义和精确传递。它的主要目的有两个方面:1、消除两个对象交互时不必要的对象拷贝,节省运算存储资源,提高效率。2、能够更简洁明确地定义泛型函数左值和右值的概念左值:能对表达式取地址、或具名对象变量。一般指表达式结束后依然存在的持久对象。右值:不能对表达式取地址,或匿名对象。一般指表达式结束就不再存在的临时对象。右值引用和左值引用的区别:1.左值可以寻址,而右值不可以。2.左值可以被赋值,右值不可以被赋值,可以用来给左值赋值。3.左值可变右值不.

2021-02-07 22:30:05 102

原创 STL知识点 | 迭代器的作用、有指针为何还要迭代器、迭代器是如何删除元素的

迭代器iterator(迭代器)模式又称 Cursor(游标)模式,用于提供-种方法顺序访问一个聚合对象中各个元素,而又不需暴露该对象的内部表示。或者这样说可能更容易理解:iterator模式是运用于聚合对象的—种模式,通过运用该模式,使得我们可以在不知道对象内部表示的凊况下,按照一定顺序(由 iterator提供的方法)访问聚合对象中的各个元素。由于 Iterator模式的以上特性:与聚合对象耦合,在一定程度上限制了它的广泛运用,一般仅用于底层聚合支持类,如STL的list、 vector、 s.

2021-02-07 07:36:55 408 1

原创 Linux知识点 | select和epoll的区别、原理、性能、限制

说一说select原理select相关调用函数void FD_ZERO(fd_set *set); // 将set清空为0void FD_CLR(int fd, fd_set *set); // 将fd从set中清除出去void FD_SET(int fd, fd_set *set); // 将fd设置到set中去int FD_ISSET(int fd, fd_set *set); // 判断fd是否在集合中select在使用前,先将需要监控的描述符对应的bi位置1,然

2021-02-06 08:51:45 1436

原创 STL知识点 | map和set的区别与实现

map和set的定义:map和set都是C++的关联容器,其底层实现都是红黑树(RB-Tree)。由于map和set所开放的各种操作接口,RB-tree也都提供了,所以几乎所有的map和set的操作行为,都只是转调RB-tree的操作行为。map和set的区别:(1)map中的元素是 key-value(关键字值)对:关键字起到索引的作用,值则表示与索引相关联的数据;Set与之相对就是关键字的简单集合,set中每个元素只包含一个关鍵字。(2)set的迭代器是 const的,不允许修改元素的值;ma.

2021-02-05 09:38:42 277

原创 数组中未出现的最小正整数

问题描述:给你一个未排序的整数数组 nums ,请你找出其中没有出现的最小的正整数。要求 :解决方案实现时间复杂度为 O(n) 并且只使用常数级别额外空间。本地编译器运行代码如下:#include<iostream>using namespace std;void swap(int* arr, int i, int j) { int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp;}int main() { int a.

2021-02-05 08:35:01 784

原创 C++知识点 | 虚函数与多态的实现

虚函数的实现:在有虚函数的类中,类的最开始部分是一个虚函数表的指针,这个指针指向一个虚函数表,表中放了虚函数的地址,实际的虚函数在代码段(.text)中。当子类继承了父类的时候也会继承其虚函数表,当子类重写父类中虚函数时候,会将其继承到的虚函数表中的地址替换为重新写的函数地址。使用了虚函数,会增加访问内存开销,降低效率。多态的实现:多态的实现主要分为静态多态和动态多态,静态多态主要是重载,在编译的时候就已经确定;动态多态是用虚函数机制实现的,在运行期间动态绑定。举个例子:一个父类类型的指针指向一个子.

2021-02-05 08:11:32 277

原创 C++知识点 | 静态函数与虚函数、重载与重写的区别

静态函数和虚函数的区别静态函数在编译的时候就已经确定运行时机,虚函数在运行的时候动态绑定。虚函数因为用了虚函数表机制,调用的时候会增加一次内存开销重载与重写的区别重载:两个函数名相同,但是参数列表不同(个数,类型),返回值类型没有要求,在同一作用域中重写:子类继承了父类,父类中的函数是虚函数,在子类中重新定义了这个虚函数,这种情况是重写...

2021-02-05 08:05:19 477

原创 C++经典面试题 | 析构函数与虚函数

为什么析构函数必须是虚函数?为什么C++默认的析构函数不是虚函数?参考回答:将可能会被继承的父类的析构函数设置为虚函数,可以保证当我们new一个子类,然后使用父类指针或引用指向该子类对象,释放父类指针时可以释放掉子类的空间,防止内存泄漏。C++默认的析构函数不是虚函数是因为虚函数需要额外的虚函数表和虚表指针,占用额外的内存。而对于不会被继承的类来说,其析构函数如果是虚函数,就会浪费内存。因此C++默认的析构函数不是虚函数,而是只有当需要当作父类时,设置为虚函数。...

2021-02-05 08:00:54 271

原创 Linux下Web性能压力测试工具之WebBench

WebBenchan安装wget http://www.ha97.com/code/webbench-1.5.tar.gztar zxvf webbench-1.5.tar.gzcd webbench-1.5makemake installWebBench使用webbench -c 1000 -t 60 http://192.168.80.157/phpinfo.php// webbench -c 并发数 -t 运行测试时间 URLApache测试实例结果并发数为300时root

2021-02-04 08:37:07 360

原创 C++四种智能指针详解

四种智能指针:shared_ptr,unique_ptr,weak_ptr,auto_ptrC++里面的四个智能指针:shared_ptr,unique_ptr,weak_ptr,auto_ptr其中前三个是c++11支持,并且最后一个已经被11弃用。智能指针的使用智能指针主要用于管理在堆上分配的内存,它将普通的指针封装为一个栈对象。当栈对象的生存周期结束后,会在析构函数中释放掉申请的内存,从而防止内存泄漏。C++11中最常用的智能指针类型为 shared_ptr它采用引用计数的方法,记录当前内存资源

2021-02-04 08:35:08 1378

原创 C++面试经典题 | 指针和引用、指针和数组的区别

说一下指针和引用的区别指针是变量,这个变量存放的是所指内容的地址。引用是别名,与所引用变量占用同一内存空间使用 sizeof看一个指针的大小是4,而引用则是被引用对象的大指针可以被初始化为NULL,而引用必须被初始化且必须是一个已有对象的引用作为参数传递时,指针需要被解引用才可以对对象进行操作,而直接对引用的修改都会改变引用所指向的对象可以有 const指针,但是没有 const引用指针在使用中可以指向其它对象,但是引用只能是一个对象的引用,不能被改变指针可以有多级指针(*p),而引用只有一

2021-02-03 09:05:30 356

原创 C++面试经典题 | C++中四种强制类型转换

说一说C++中的四个cast转换C++中四种类型转换是:static cast, dynamic cast, const cast, reinterpret castconst cast用于将cons变量转为非 conststatic cast用于各种隐式转换,比如非cons转onst,wod转指针等 static cast能用于多态向上转化,如果向下转能成功但是不安全,结果未知dynamic cast用于动态类型转换。只能用于含有虚函数的类,用于类层次间的向上和向下转化。只能转指针或引用。

2021-02-03 08:58:24 643 5

原创 C++面试经典题 | static关键字的作用

说一下static关键字的作用全局静态变量在全局变量前加上关键字 static,全局变量就定义成一个全局静态变量静态存储区,在整个程序运行期间一直初始化:未经初始化的全局静态变量会被自动初始化为0(自动对象的值是任意的,除非他被显式初始化)作用域:全局静态变量在声明他的文件之外是不可见的,准确地说是从定义之处开始,到文件结尾局部静态变量在局部变量之前加上关键字 static,局部变量就成为一个局部静态变量。内存中的位置:静态存储区初始化:末经初始化的全局静态变量会被自动初始化为0(自动对象的值

2021-02-03 08:51:57 2237 4

原创 new/delete和malloc/free的区别联系

1.先来谈谈new和delete在C++中堆内存的分配和释放是通过new和delete来操作的,它们和C语言的malloc和free有什么区别呢?(1)new的底层也是通过malloc来开辟内存的new比malloc多一项功能,就是开辟完内存,还可以进行初始化操作如下:int *p = new int(10);上面是new的基本操作,10代表堆上开辟的整形内存的初始值;如果是自定义类类型的话,如下:Test *p = new Test(); // Tset是一个实现定义好的类这个语句不

2021-02-02 08:20:36 1246 2

空空如也

空空如也

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

TA关注的人

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