自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 C++ | 实现mysql连接池

利用单利模式获取连接池实例,支持高并发,为每个连接记录存活时间,当连接总量大于最大连接数时会将时间过长的连接断开,当池子没有连接时会利用生产者线程进行生产Connpool *Connpool::instance = nullptr;//获得池子Connpool *Connpool::GetInstance(){ if (instance == nullptr) { std::lock_guard<std::mutex> lock(instance_mute

2022-04-24 17:34:23 1854

原创 C++ | function和bind

可调用对象可调用对象的定义:(满足一个即可)是一个函数指针是一个具有operator()成员函数的类对象(就是仿函数)是一个可被转换为函数指针的类对象是一个类成员(函数)指针关于一个可被转换为函数指针的类对象的举例:struct Bar{ using fr_t = void(*) (void);//返回值为空参数为空的函数指针类型定义为fr_t static void func(void) { //... } operator fr_t(void) { return f

2022-04-17 19:02:14 668

原创 C++并发 | std::future原理

只是了解future可以异步返回一个函数的返回值,和std::packaged_task一起使用,但是不了解其中原理,上网看了一些资料做个总结^^std::future 可以用来获取异步任务的结果,因此可以把它当成一种简单的线程间同步的手段.通过用packaged_task和目标任务和参数打包形成的packaged_task类,我的理解是里面重载了()运算符,使对象成为可调用的仿函数,struct st{ int val; void operator()(int x) { val = x;

2022-04-05 18:07:37 1340 1

原创 C++并发编程 | 实现通用线程池

此线程池采用了半同步半异步,而且实现了任意任务的传入,不限制参数和返回值,用到了std::packaged_task和future,利用lambda 表达式作为统一调用.SynbQueue为同步队列,在此类中添加要执行的任务ThreadPoll负责创建线程池并且没有任务时阻塞,当有任务添加时,将其唤醒并执行,大致模型为第一层为同步服务层,处理来自上层的任务请求,上层的任务请求是并发的,并不会马上处理,而是将这些任务放到一个同步队列中,等待处理。第二层为同步队列,来自上层的任务都会加到队列中等待处理

2022-04-05 17:18:39 878

原创 C++ | 对象池结合单例模式

思想就是一个对象只能有一个池子,用对象从池子里面取,每个池子有一个管理者来管理所对应的池子,取对象从管理者这里申请template<class _Ty>class ObjectPoll{private: enum { PollSize = 4 };protected: struct _Node { _Node* next; }; _Node* front; _Node* rear; void ReFull() { int total = sizeof(

2022-03-27 14:09:56 788

原创 mysql |

四大排名函数:一、ROW_NUMBER()Row_number() 在排名是序号 连续 不重复,即使遇到表中的两个一样的数值亦是如此1 2 3 4 5二、rank()Rank() 函数会把要求排序的值相同的归为一组且每组序号一样,排序不会连续执行1 2 2 4 4 6三、dense_rank()Dense_rank() 排序是连续的,也会把相同的值分为一组且每组排序号一样1 2 2 3 3 4 4四、ntile()Ntile(group_num) 将所有记录分成group_num个组,每组

2022-03-13 00:00:23 936

原创 c++ | 函数调用时栈使用情况分析(汇编)

int main(){ int a = 1; int b = 2; int c = sum(a , b); int d = 2; return 0;}sum调用前此时ebp:012FF98C ,esp:012FF890将b的值入栈,a的值入栈执行call。执行call的时候,先把下一条指令的地址入栈,再跳转。对于每一次push操作,%esp储存的地址会-1sum栈中:将ebp的值将入栈,还没入,此时ebp的值为0x012FF98C,esp为0x012FF884.

2022-03-12 17:55:02 837

原创 mysql | imit offset

offset X是跳过X个数据,limit Y是选取Y个数据limit X,Y 中X表示跳过X个数据,读取Y个数据

2022-03-11 23:57:51 571

原创 mysql | snull,ifnull,nullif

isnull(expr) 的用法: 如expr 为null,那么isnull() 的返回值为 1,否则返回值为 0。 mysql> select isnull(1+1); -> 0 mysql> select isnull(1/0); -> 1 使用= 的null 值对比通常是错误的。isnull() 函数同 is null比较操作符具有一些相同的特性。请参见有关is null 的说明。IFNULL(expr1,expr2)的用法:假如expr1 不为 NULL,则 IFNUL

2022-03-11 23:56:07 118

转载 linux | 从内核文件系统看文件读写过程

虚拟文件系统一个操作系统可以支持多种底层不同的文件系统(比如NTFS, FAT, ext3, ext4),为了给内核和用户进程提供统一的文件系统视图,Linux在用户进程和底层文件系统之间加入了一个抽象层,即虚拟文件系统(Virtual File System, VFS),进程所有的文件操作都通过VFS,由VFS来适配各种底层不同的文件系统,完成实际的文件操作。通俗的说,VFS就是定义了一个通用文件系统的接口层和适配层,一方面为用户进程提供了一组统一的访问文件,目录和其他对象的统一方法,另一方面又要和不

2022-03-08 00:06:42 297

原创 算法 | KMP算法

核心:主串不能回退,一直遍历当子串没有重复的时候子串回退到头部有重复的时候回退到最后一个重复位置如果发生失配,从失配位置向前看,看字串是否存在两个真子串一个顶头一个顶尾匹配到c的时候匹配失败,按照普通方式是子串回到起始位置,主串到上次开始匹配位置的下一个位置,也就是b,但是这样的话在匹配失败的位置c的前面等于发生"错位",这样错位一直到,这时候其实也是错位,但是刚好错位还跟第一次匹配错误位置前两个对应上了,由于并不知道第一次匹配错误的位置是否等于子串的下一个位置,所以需要比较一下b是否和a相等

2022-02-27 18:15:00 84

原创 vector | resize和reserve在底层上的差异

今天通过源码大概分析了一遍resize的流程,不是特别详细,只是了解了大致过程,简单来说就是当申请的尺寸大于当前的容量,会进行_Resize_reallocate,流程我大概总结了一下,就是先按照新容量进行空间的申请返回新的地址_Newvec,将_Appended_first置为新的地址+旧size*sizeof(class)在_Appended_first将额外新的对象进行构建,这样_Appended_first之上的几个对象空间用来存储以前就有对象然后在_Newvec进行拷贝构造,(以前就有

2022-02-26 18:42:11 182

原创 C++ | 虚继承和内存结构

虚继承和虚函数是完全无相关的两个概念。虚继承是解决C++多重继承问题的一种手段,从不同途径继承来的同一基类,会在子类中存在多份拷贝。这将存在两个问题:其一,浪费存储空间;第二,存在二义性问题,通常可以将派生类对象的地址赋值给基类对象,实现的具体方式是,将基类指针指向继承类(继承类有基类的拷贝)中的基类对象的地址,但是多重继承可能存在一个基类的多份拷贝,这就出现了二义性。虚继承可以解决多种继承前面提到的两个问题:虚继承底层实现原理与编译器相关,一般通过虚基类指针和虚基类表实现,每个虚继承的子类都有一个虚

2022-02-25 21:51:26 190

原创 排序 | 堆排序

思路:void adjustheap(int* ar,int start,int end){ int tmp = ar[start]; int i = start; int j = 2 * start + 1;//左孩子 while (j <= end) { if (j<end && ar[j + 1]>ar[j]) { j += 1; } if (ar[j] > tmp)//本来是要把tmp放到这个位置的,可是他如果小于他的孩子

2022-02-23 22:47:26 119

原创 排序 | 归并排序(递归和迭代)

利用分治的思想,将问题不断地划分为相同但是规模更小的问题,利用相同的解法解小问题,最终大问题得以解决一一合并完之后每一个元素个数为2的数组有序,然后两个两个的合并,四个四个的合并…直到最大容量,排序完成递归版void copy(int* src, int* dest, int left, int right){ for (left; left <= right; ++left) { dest[left] = src[left]; }}void merge(int* src, i

2022-02-20 22:24:30 497

原创 C++ | 实例化和具体化

实例化是将利用模板产生对象:Pair<string, string> ii; // 隐式 实例化对象template class Pair<int, double>; //显式实例化对象具体化是模板的细分,就是更加具体一些,但还是个模板template<class _Ty, class _Dx = default_Deletor<_Ty>>class my_share_ptr{};template<class _Ty, cl

2022-02-20 22:18:33 448

原创 排序 | 快速排序

思想每一次划分,使左边均小于基准,右边均大于,但是无序,然后再将左右边各划分一次,这样划分下去,直到分解数组大小为1,划分停止,此时已经有序.划分函数快排中划分函数时必不可少的,他的作用是确定一个基准,然后以此基准进行划分,划分的方式有很多种,最常用的是双指针在边界处进行遍历,右指针找小于基准的,左指针找大于基准的,然后交换,直到左右指针重合,再把基准放到最终指针位置,这样基准的左边均小,右边均大了.双指针指向最左和最右的划分函数int Partition(int* ar, int left, i

2022-02-17 16:55:48 373

原创 计算机网络 | 链路层

链路层和arp

2022-02-16 23:31:16 1335

原创 C++ | 智能指针

RAII资源的获取即初始化资源的使用经历三个步骤获取资源使用资源销毁资源引入智能指针的目的使用裸指针的缺点:难以区分是单个对象还是一个数组使用完无法判断是否应该销毁指针没有办法分辨一个指针处于悬挂状态难以保证在所有路径中只有一次的销毁指针操作智能指针所干的事就是当对象不再需要时就自动执行清理auto_ptr代码template<class _Ty>class my_auto_ptr{ bool _Owns; _Ty* _Ptr;public: ex

2022-02-15 22:55:07 261

原创 C/C++ | 内存模型的比较

今天看到一篇内容,讲的是new和malloc区别,虽然是老生常谈,但是这篇文章给我一个新的认知我们都知道在C++中,内存分为五个区:堆、栈、自由存储区、全局/静态存储区和常量存储区。在C中,分为代码区,全局初始化数据区/静态数据区...

2022-02-15 14:31:55 496

原创 C++ | 用C语言实现多态和一些思考

一些思考

2022-02-13 21:30:02 355

原创 算法 | 递归和分治

概念分治策略:是将规模比较大的问题可分割成规模较小的相同问题。问题不变,规模变小。这自然导致递归过程的产生。分治与递归像一对孪生兄弟,经常同时应用在算法设计之中,并由此产生许多高效算法。递归:若一个函数直接地或间接地调用自己,则称这个函数是递归的函数。(简单地描述为“自己调用自己”)。典型例子:求阶乘int fac(int n){ if(n==1) return 1; return fac(n-1)*n;}int main(){ fac(4);}当求4的阶乘时,进入函数,不满足i

2022-02-13 20:19:18 783

原创 MySQL | 基本命令

1. 操作数据库创建数据库CREAT DATABASE [IF NOT EXISTS] name []的意思是可带可不带删除数据库 DROP DATABASE [IF EXISTS] name使用数据库use name查看数据库show DATABASE2. 字段的属性ZEROFILL:用0填充的,不足的位数用0来填充Auto_InCrement:自增的,默认自动+1,通常用来设计主键,可自己设置起始值和一次增加的长度:当前表设置步长(AUTO_INCREMENT=100) : 只影响

2022-02-13 14:30:06 414

原创 Linux | 五种io模型以及比较

同步阻塞io默认情况下所有的socket都是阻塞的.在这个IO模型中,用户空间的应用程序执行一个系统调用(recvform),这会导致应用程序阻塞,什么也不干,直到数据准备好,并且将数据从内核复制到用户进程,最后进程再处理数据同步非阻塞同步非阻塞就是 “每隔一会儿瞄一眼进度条” 的轮询(polling)方式,设备是以非阻塞的形式打开的,意味着 IO 操作不会立即完成,read 操作可能会返回一个错误代码在网络IO时候,非阻塞IO也会进行recvform系统调用,检查数据是否准备好,与阻塞IO不一

2022-02-13 10:42:21 411

原创 C++ | 多态和对虚函数理解和详解

编译时多态,早期绑定(编联)在编译时期就能确定调用关系,通过函数的重载和运算符的重载来实现的。运行时多态运行时的多态性是指在程序执行前,无法根据函数名和参数来确定该调用哪一个函数,必须在程序执行过程中,根据执行的具体情况来动态地确定。它是通过类继承关系public和虚函数来实现的。目的也是建立一种通用的程序。通用性是程序追求的主要目标之一。虚函数虚函数是一个类的成员函数,定义格式如下class Animal{private: char name[20];public: Animal(c

2022-02-12 20:47:26 452

原创 Linux | 系统调用

什么是系统调用是操作系统提供给用户程序调用的一组“特殊”接口。用户程序可以通过这组“特殊”接口来获得操作系统内核提供的服务,比如用户可以通过文件系统相关的调用请求系统打开文件、关闭文件或读写文件,可以通过时钟相关的系统调用获得系统时间或设置系统时间等。注意内核函数和系统调用的关系,内核函数在内核实现,满足一些内核编程的要求。系统调用是一层用户进入内核的接口,它本身并非内核函数,进入内核后,不同的系统调用会找到对应到各自的内核函数.系统调用、用户编程接口(API)、系统命令的辨析用户编程接口其实是一个

2022-02-11 19:44:43 252

原创 Linux | 文件类型说明

Linux 下所有的东西都可以看做文件,Linux 将文件分为以下几种类型:◼ 普通文件 ‘-’◼ 目录文件 ‘d’◼ 管道文件 ‘p’◼ 链接文件 ‘l’◼ 设备文件(块设备 ’b’ 、字符设备 ‘c’)◼ 套接字文件 ‘s’Linux 上不以文件的扩展名区别文件类型,而是在文件属性中有一列专门记录文件类型。文件权限◼ r 读权限 值: 4◼ w 写权限 值: 2◼ x 执行权限 值: 1◼ - 无权限 值: 0修改文件权限 chmod3.1 文字设定法u 表属主 g 同组

2022-02-11 19:22:24 401

原创 Linux | 常用命令

基础命令pwd显示当前位置的绝对路径cd切换目录,绝对路径和相对路径都可以ls显示目录中的文件man查看帮助手册,命令,系统调用,库函数等信息touch,mkdir前者创建普通文件,后者创建目录文件rm,rmdir删除文件和目录,非空目录要用rm -r namecp拷贝文件,目录加上-r...

2022-02-11 19:08:56 433

转载 C | 浅析malloc实现

malloc底层实现原理,较浅

2022-02-11 18:46:04 119

原创 C++ | 模板相关

清晰概念类模板和模板类类模板表示是一个模板,可以用此模板产生其他模板类模板类是由模板而产生的类函数模板和模板函数模板函数重点是模板,表示他是一个模板,用来产生模板函数模板函数就是用模板刻出来的函数运行机制1.编译器会对函数模板进行两次编译(在声明的地方对模板代码本身进行编译;在调用的地方再对参数替换后的代码进行编译。)2.编译器在对函数模板编译时与调用的次数无关,与调用时参数类型有关...

2022-02-11 18:14:24 157

原创 C++ | 继承详解

继承机制先构建基类对象再构建派生对象,基类对象时派生对象的一个成员,保护类型可以被继承(无论什么继承方式),但私有类型不能如果在派生对象中定义一个基类对象,那么这个对象中会有隐藏基类对象和自己定义的基类对象.在派生类o中定义一个基类对象a,无论a是共有还是私有还是保护,a中的保护和私有类型派生类o均无法访问.保护属性在外部无法访问,和私有的区别在继承的时候,派生类可以访问保护类型函数和变量和父类重名时,会优先选择子类,可以通过作用域访问父类同名成员.友元不具有继承性.//通过作用域访问

2022-02-11 17:34:32 149

原创 C++ | const和指针引用的混淆点

const的意思是所修饰的变量不能被修改const char* s = "woshishabi";const和指针 const char* s = "woshishabi"; int a = 10; const int b = 20; b = a;//err a = b;//ok int* p = &a; const int* p1 = &a; const int* const p2 = &a; a = 11; *p1 = 12;//err *p2 = 1

2022-02-09 21:49:07 378

原创 C++ | 引用

概念引用可以看作变量的别名,就是给变量起一个"小名",比如张三,我们给他起了一个外号叫贼娃子,我们打贼娃子打的就是张三.其实底层就是指针.使用任何类型的变量都可以引用,但是引用类型却不能引用,在定义int&& p=i;会失败 ,引用一旦被初始化就不能改变指向, int b = 0; int d = 10; int& c = b; c = d;//b改为10 int&& p = b;//err, int&& p = c;//err,

2022-02-09 21:07:16 276

原创 C++ | C和C++区别

输入和输出c++:cin,coutc:printf,scanf引用引用可以看作是变量的别名,在引用上的修改可以直接修改到原变量.inline函数(内联函数)在C++中,为了解决一些频繁调用的小函数大量消耗栈空间(栈内存)的问题,特别的引入了inline 修饰符,表示为内联函数。内联函数的处理方式是在函数的调用点直接代码展开。在计算机系统下,假如频繁的调用就会造成较大的时间开销。内联函数的引入减少了函数调用过程中开栈和清栈的开销。函数的重载模板函数动态内存上的区别..

2022-02-09 20:23:09 460

原创 C语言 | 堆与栈的区别

管理方式:栈由系统自动管理;堆由程序员控制,使用方便,但易产生内存泄露。生长方向:栈向低地址扩展(即”向下生长”),是连续的内存区域;堆向高地址扩展(即”向上生长”),是不连续的内存区域。这是由于堆区管理系统用链表来存储空闲内存地址,自然不连续,而链表从低地址向高地址遍历。空间大小:栈顶地址和栈的最大容量由系统预先规定(通常默认1M或10M);堆的大小则受限于计算机系统中有效的虚拟内存,32位Linux系统中堆内存可达2.9G空间。存储内容:栈在函数调用时,首先压入是函数实参,然后主调函数中下条指令.

2022-01-22 21:01:47 171

原创 C语言 | 文件操作和易错点

文件操作文件在操作系统中以页块大小来存储,不论多少字节 起始是4k,超4k变为8kfile是一个文件操作结构体,当需要对文件进行操作时,需要定义一个文件操作指针打开文件打开文件函数原型:FILE* fopen ( const char * filename, const char * mode );filename:路径,如果没有文件夹会报错mode:读写方式int main(){ FILE* fp=fopen("d:\\fxl.txt","w");}读写文件fprinf

2022-01-22 20:54:16 371

原创 C语言 | 联合体

联合体和结构体的区别结构体每个变量有自己独立的空间联合体则共用空间定义辨析union ip{ int ip; char a; char b; char c; char d; };//a,b,c,d始终占ip的第一个字节,即指向同一块空间union ip{ int ip; struct { char a; char b; char c; char d; };//亚

2022-01-22 20:51:01 77

原创 C语言 | 结构体

结构体定义辨析变量为结构体时,用结构体内的变量用".",比如student.num为结构体指针时用->字节对齐1)结构体变量的首地址,必须是MIN(“结构体最大基本数据类型成员所占字节数”,指定对齐方式}大小的整数倍。2)结构体每个成员相对于结构体首地址的偏移量,都是 MIN{基本数据类型成员,指定对齐方式)大小的整数倍。3)结构体的总大小,为MIN{结构体“最最大基本数据类型成员所占字节数”(将嵌套结构体里的基本类型也算上,得出最大基本数据类型成员所占字节数),指定对齐方式}大小

2022-01-22 20:46:58 347

原创 C语言 | 指针和数组

指针和一维数组数组名是数组首元素地址(sizeof除外)int main() { int ar[8] = { 12,34,56,78 }; char* br[4];//定义了四个char类型指针 int(*cr)[8]=&ar;//指向数组的指针 cr=&ar; cr+1=cr+sizeof(ar) *cr+1=ar+1=ar+sizeof(*ar); printf("%d,%d,%d", sizeof(ar), sizeof(br), sizeof(*cr));

2022-01-22 20:39:21 146

原创 C语言 | 指针和函数

函数指针指向函数的指针 和普通指针相同,指向的空间必须和指针类型相同当函数指针作为一个函数的参数时,就像数组作为参数一样,(int* arr)传入的是arr.函数的类型:返回类型+形参列表int add(int x,int y){ return x+y; }typedef int (*pfun)(int, int);int mian(){ int (*pfun)(int,int);//代表申请了一个指针 但是这个pfun指针还未指向 int (*pfun)(int,

2022-01-22 20:33:25 218

空空如也

空空如也

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

TA关注的人

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