自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(197)
  • 资源 (1)
  • 问答 (1)
  • 收藏
  • 关注

原创 【持续更新中】Q&AGroup1

函数指针就是指向函数的指针变量。每个函数都有一个入口地址,该入口地址就是函数指针所指向的地址。f = &func;函数指针的应用场景:回调callback,我们调用别人提供的 API函数应用程序编程接口称为Call;如果别人的库里面调用我们的函数,就叫Callback野指针:就是指针指向的位置是不可知的(随机的、不正确的、没有明确限制的)产生原因:释放内存后指针不及时置空,依然指向原来的内存,那么可能出现非法访问的错误。初始化置NULL申请内存后判空指针释放后置NULL。

2023-08-27 11:26:13 961

原创 【项目构建】04:动态库与静态库制作

与静态库不同的是,动态链接库必须与程序同时部署,还要保证程序能正常加载得到的库文件。由于静态库的特点,在编译时已经将库中的代码编译到二进制文件中,当编译完成后,该库文件可以删除,并且程序可以直接运行,由于动态库的特点,若只在编译时使用的动态库,而运行时没有指定动态库位置,则程序将无法正常运行,静态链接库:会将库中的代码编译到二进制文件中,当程序编译完成后,该库文件可以删除,文件目录结构如下,将第三方动态库动态载入,编译自己的项目,文件目录结构如下,将第三方静态库动态载入,编译自己的项目,

2024-04-29 07:06:12 1152

原创 【数据库连接池】04:连接池空闲连接回收

多余的连接如果超过指定的时间,还没有再次被使用到,就需要将连接进行回收,从而节省服务器资源,启动一个定时线程,定时扫描超过maxIdleTime的空闲连接,进行多余连接的回收操作。在初始化连接池时,添加刷新Connection连接的alivetime。在消费者生产Connection连接时,刷新连接的alivetime。在消费者使用完毕,归还数据库连接时,需要刷新连接的alivetime。

2023-11-28 09:14:25 1434

原创 【数据库连接池】03:连接池消费者操作

shared_ptr构造函数第2个参数自动接收一个删除器(函数对象),直接使用lambda表达式创建一个删除器,并将其传入构造函数中。操作来归还连接,而是可以使用智能指针(智能指针出作用域会自动析构、进而释放Connection)还需要对智能指针重定义析构函数,在析构时不要将数据库连接释放掉,而是将连接归还到数据库连接池中,在外部使用完数据库连接后,可以不需要考虑再提供类似。ConnectionPool连接池需要向外部提供。接口,以便外部获取可用的空闲数据库连接,

2023-11-28 09:13:16 542

原创 【数据库连接池】02:连接池生产者操作

对于普通成员方法的调用依赖于对象,如果要将其设计成为一个线程函数,就必须将this指针所需要的对象绑定到该方法上(线程函数都是C接口,不支持面向对象),在创建生产者线程connProducer时,需要传入一个线程函数produceConnTask,使用绑定器为当前对象的成员方法produceConnTask,绑定一个当前对象,将线程函数写成类的成员函数,最大的好处是可以非常方便的访问当前对象的成员变量,produceConnTask具体的执行逻辑,创建一个生产者线程,作为数据库连接的生产者,

2023-11-28 09:12:03 489

原创 【数据库连接池】01:连接池初始化

连接池不需要创建多个,所以可以通过单例模式来设计数据库连接池类,但是服务器肯定是多线程的,肯定会有多个线程都来获取连接池的单例,所以还需要保证数据库连接池的线程安全问题,CommonConnectionPool类设计:需要通过单例模式实现,并保证数据库连接池的线程安全问题(线程安全的单例),在整个系统中数据库连接池对象出现一次即可,有数据库连接需求时,从同一个数据库连接池中获取。封装Connection类,在该类内调用mysql提供的接口实现对数据库的增删改查,

2023-11-28 09:10:22 889

原创 【设计模式】03:单例模式

项目全局范围内,某个类的实例有且仅有一个,通过这个实例向其他模块提供数据的全局访问,这种模式就叫单例模式。单例模式的典型应用就是任务队列。使用单例模式来替代全局变量(对全局变量进行管理),直接使用全局变量会破坏类的封装(全局变量随意读写),通过单例模式的类提供的成员函数进行访问。单例模式缺点:扩展困难:单例模式中没有抽象层,因此扩展困难,不适用于变化的对象:如果同类型的对象总是要在不同的用例场景发生变化,单例就会引起数据错误,不能保存状态。

2023-11-27 17:12:32 1163

原创 【项目构建】03:CMakeList项目构建

cmake可以使用set命令为自定义的变量进行赋值操作,默认为字符串类型,源文件指定编译C++版本标准指定输出路径指定# 指定C++编译版本# 指定HOME路径# 指定源文件路径# 指定可执行文件输出路径宏功能执行cmake命令后的参数目录执行cmake命令的目录当前处理的CMakeLists.txt所在的路径target 编译目录定义目标二进制可执行文件的存放位置定义目标链接库文件的存放位置PROJECT指令定义的项目名称。

2023-11-27 11:37:56 1286

原创 【项目构建】05:makefile编写练习

编写makefile文件来编译带头文件的程序,

2023-11-26 09:50:05 450

原创 【项目构建】02:makefile项目构建

make是一个命令工具,makefile是一个文件,make执行的时候需要读取makefile文件中的规则(makefile规则需要自己写),makefile定义一系列的规则来指定哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于更复杂的功能操作,由于静态库的特点,在编译时已经将库中的代码编译到二进制文件中,当编译完成后,该库文件可以删除,并且程序可以直接运行,由于动态库的特点,若只在编译时使用的动态库,而运行时没有指定动态库位置,则程序将无法正常运行,

2023-11-26 09:47:44 949

原创 堆与栈的区别

注:关于堆上内存空间的分配过程,首先应该知道操作系统有一个记录空闲内存地址的链表,当系统收到程序的申请时,会遍历该链表,寻找第一个空间大于所申请空间的堆节点,然后将该节点从空闲节点链表中删除,并将该节点的空间分配给程序。调整时先在左右儿子节点中找最小的,如果父节点不大于这个最小的子节点说明不需要调整了,反之将最小的子节点换到父节点的位置。重复进行下沉操作,以满足堆的条件。思路是每次都把堆顶的元素和堆尾的元素交换,然后把除了堆尾的那个元素组成的堆进行堆化(就是把堆顶的元素进行下沉),不断重复直至堆为空为止。

2023-09-13 09:27:45 1882

转载 NULL与nullptr的区别

在这段代码中,我们对函数func进行可重载,参数分别是void*类型和int类型,但是运行结果却与我们使用NULL的初衷是相违背的,因为我们本来是想用NULL来代替空指针,但是在将NULL输入到函数中时,它却选择了int形参这个函数版本,所以是有问题的,这就是用NULL代替空指针在C++程序中的二义性。可见,在C++中,NULL实际上是0.因为C++中不能把void*类型的指针隐式转换成其他类型的指针,所以为了结果空指针的表示问题,C++引入了0来表示空指针,这样就有了上述代码中的NULL宏定义。

2023-08-29 08:38:05 283

原创 多态/虚函数/虚函数表

如果每个父类都有虚函数,那么每个父类都会有一个虚函数表,子类对象会包含每个父类的虚函数表指针,因此子类对象会有多个虚函数表指针,每个指针指向相应的虚函数表。如果某个父类没有虚函数,那么子类对象就不会包含该父类的虚函数表指针,只会包含其他父类的虚函数表指针和成员变量。多态性:多态必须存在虚函数,没有虚函数绝不可能存在多态,并且只有调用虚函数时才有存在多态性的可能,当某个类中存在至少一个虚函数的时候,在编译期间编译器就会为类A生成一个虚函数表。虚函数表指针(virtual table ptr),

2023-08-27 22:46:51 298

原创 事件回调机制实现

使用C++编写回调函数时,一种常见的场景是使用函数指针作为回调机制。事件回调的基本概念是,在某个特定事件发生时,系统会调用预先定义好的函数(即回调函数)来处理该事件。以下是两种常见的回调函数实现方式:回调函数有两种实现方式,函数指针回调与函数对象回调,通过函数指针或函数对象实现回调函数时,可以根据需要传递参数,并在回调函数中执行相应的逻辑。程序在事件发生时采取相应的动作,而不必等待事件的完成。回调函数通常作为参数传递给触发事件的函数。在C++中,回调函数通常通过。,从而实现灵活的回调机制。

2023-08-27 11:04:21 1123

原创 VMVareC++开发环境快速配置

做Linux下的C/C++开发,gcc和g++肯定是必备的,这个命令将会安装一系列软件包,包括gcc,g++,和make。为了长期方便并且舒适使用该虚拟机,首先需要对虚拟机的ip进行配置,否则一段时间后再登录虚拟机ip地址可能会发生变化,其实gdb自从8.3版本之后就已经默认支持了彩色显示,并且默认已经启用了,所以查看地址、文件名等符号时都是彩色的。为了方便使用xshell或者vscode连接虚拟机,进行远程开发需要安装ssh服务,并开放相应的端口号,等可执行文件,运行这里的gdb,代码高亮便默认启用了。

2023-08-26 09:39:00 3911

原创 【Qt学习】08:文件读写操作

在使用QDataStream的时候代码很方便,但使用了QTextStream时却有所不同,使用QDataStream写入的时候,实际上会在要写入的内容前面,额外添加一个这段内容的长度值。操作这种文件需要使用QTextStream类,QTextStream和QDataStream的使用类似,只不过它是操作纯文本文件的。QDataStream既能够存取 C++ 基本类型,也可以存取复杂的数据类型,例如自定义的类(实际上QDataStream对于类的存储,是将复杂的类分割为很多基本单元实现的)。

2023-08-26 09:16:45 323

原创 【Qt学习】07:绘图与绘图设备

QPicture是可以记录和重现QPainter命令的绘图设备,QPicture将QPainter的命令序列化到一个IO设备,保存为一个平台独立的文件格式,这种格式有时候会是元文件meta- files。Qt的这种格式是二进制的,不同于某些本地的元文件Qt的pictures文件没有内容上的限制,只要是能够被QPainter绘制的元素,不论是字体还是pixmap,或者是变换都可以保存进一个picture中。可以将QPainter理解成画笔,QPaintDevice理解成使用画笔的地方,比如纸张、屏幕等;

2023-08-26 09:14:57 328

原创 【Qt学习】06:事件与事件过滤器

该函数接受一个QObject *类型的参数,eventFilter()函数是QObject的一个成员函数,因此任意QObject都可以作为事件过滤器(如果没有重写eventFilter()函数,这个事件过滤器是没有任何作用的,默认什么都不会过滤)。event()函数并不直接处理事件,而是将这些事件对象按照它们不同的类型,分发给不同的事件处理器event handler(event()函数主要用于事件的分发)。该函数为任意线程的任意对象的任意事件调用,因此不存在事件过滤器的线程的问题。

2023-08-26 09:11:08 1718

原创 【Qt学习】05:自定义封装界面类

/方式1//方式2 listi < 4;

2023-08-26 09:07:33 1481

原创 【Qt学习】04:QDialog

对话框分为模态对话框和非模态对话框,模态对话框,会阻塞同一应用程序中其它窗口的输入。模态对话框很常见,比如“打开文件”功能。你可以尝试一下记事本的打开文件,当打开文件对话框出现时,我们是不能对除此对话框之外的窗口部分进行操作的。非模态对话框相反,例如查找对话框,我们可以在显示着查找对话框的同时,继续对记事本的内容进行编辑。使用实现应用程序级别的模态对话框使用实现窗口级别的模态对话框使用实现非模态对话框。

2023-08-26 09:01:30 2125

原创 【Qt学习】03:QMainWindow

QMainWindow是一个为用户提供主窗口程序的类,包含一个菜单栏menu bar、多个工具栏tool bars、多个锚接部件dock widgets、一个状态栏status bar及一个中心部件central widget,是许多应用程序的基础,如文本编辑器、图片编辑器等。

2023-08-26 09:00:13 158

原创 【Qt学习】02:信号和槽机制

使用connect可使用系统提供的信号和槽,但Qt的信号槽机制并不仅仅是使用系统提供那部分,其还允许开发者设计自己的信号和槽,发送者和接收者都需要是QObject的子类(槽函数是全局函数、Lambda 表达式等无需接收者的时候除外);自定义信号signal返回值是 void,只需要声明不需要实现,可以有参数(发生重载)槽函数是普通的成员函数,需要声明也需要实现,会受到 public、private、protected 的影响(早期必须写到public slots作用域下)

2023-08-26 08:58:40 366

原创 【QT学习】01:helloqt

在析构过程中它会调用子对象列表中每一个对象的析构函数,也就是说 quit 此时就被析构了。作为父组件的 window 和作为子组件的 quit 都是QObject的子类(事实上,它们都是QWidget的子类,而QWidget是QObject的子类)。因此这段代码在超出作用域时,会先调用 quit 的析构函数,将其从父对象 window 的子对象列表中删除,然后才会再调用 window 的析构函数。这里析构顺序就出现了问题,在上面的代码中作为父对象的 window 会首先被析构,因为它是最后一个创建的对象。

2023-08-03 17:13:30 508

原创 【项目构建】01:代码编译链接与执行的过程

预处理Preprocessing:将.cpp文件转化为.i文件,预处理器把所有include的文件包括递归包含的文件内容,都展开到输出文件,并展开了所有的宏定义。编译Compilation:将.cpp/.h文件转换成.s文件,编译的过程将预处理的文件进行一系列的词法分析、语法分析、语义分析及优化成相应的汇编代码。这一步中一般会进行优化,比如去除没有用到的类的声明、循环语句的优化等。汇编Assemble:将.s文件转化为.o文件,

2023-08-01 11:33:15 340

原创 认清现实重新理解游戏的本质

游戏会成为我们工作和学习拖延的帮凶,游戏对我最大的危害就是拖延,玩了几十年游戏的人生注定不会过的那么精彩,因为所有的精彩都留在了虚拟的游戏世界(游戏开发商服务器数据库里的一条数据)游戏一直麻痹着我的神经,让我一次次假期变得拖延,让我一次次工作变得拖延,人生也被分为了游戏和现实两个部分,花大量时间在游戏中,最终带来的恶果让我过上注定平庸的一生,

2023-07-29 22:46:00 733

原创 【设计模式】02:面向对象设计原则

关于这个原理的应用其实也很常见,比如在 Qt 中,所有窗口类型的类的构造函数都有一个 QWidget* 类型的参数(QWidget 类是所有窗口的基类),通过这个参数指定当前窗口的父对象。虽然参数是窗口类的基类类型,但是我们在给其指定实参的大多数时候,指定的都是子类的对象,其实也就是相当于使用子类类型替换掉了它们的父类类型。该原则是程序设计的一种理想模式,在很多情况下无法做到完全的封闭,因此需要在这些位置创建抽象类来隔离以后发生的这些同类变化(多态的应用,创建新的子类并重写父类虚函数,用以更新处理动作)。

2023-07-20 16:44:07 181

原创 【设计模式】01:类间关系

类之间的关系强弱顺序:继承(泛化) > 组合 > 聚合 > 关联 > 依赖(使用最强的关系描述即可)关联和聚合的区别主要在于语义上:关联的两个对象之间一般是平等的,聚合则一般是不平等的。聚合和组合的区别则在语义和实现上都有差别:组合的两个对象之间生命周期有很大关联,被组合的对象在组合对象创建的同时或者创建之后创建在组合对象销毁之前销毁,聚合则无需考虑这些事情。一般被组合对象不能脱离组合对象独立存在,而且也只能属于一个组合对象,聚合则不一样,被聚合的对象可以属于多个聚合对象。

2023-07-20 16:37:21 362

原创 【CPP11新特征】02:可调用对象与lambda表达式

声明符也可以包含类型修饰,从而也能由基本数据类型构造出复合类型,可以使用 using别名声明来定义类型的别名。在定义基础类型时,通过 using 和 typedef 的语法格式发现二者的使用没有太大区别,其不同在于定义函数指针//使用typedef定义函数指针 其中func为函数指针 int为其返回类型 using func = int(*)(int , double);//使用using定义函数指针 其中func为函数指针 int为其返回类型。

2023-04-26 17:21:06 913 2

原创 URL信息截取与linux文件目录遍历

利用格式化输入sscanf函数实现主要功能:将参数str的字符串根据参数format字符串来转换并格式化数据,转换后的结果存于对应的参数中,指定长度指定字符为止包含指定字符集指定字符集为止举例:从中分别获取传输协议、网站域名、端口等信息。

2023-04-25 20:44:38 804

原创 fastCGI快速上手

fastCGI是什么?:运行在服务器端的代码, 帮助服务器处理客户端提交的动态请求fastCGI作用:帮助服务器处理客户端提交的动态请求,fastCGI如何使用?fastCGI如何获取数据?nginx解析客户端发送的http请求然后转发# 分析出客户端请求对应的指令 -- /test# nginx转发出去给fastcgi程序fastcgi_pass 地址:端口;//nginx对http请求解析得到的环境变量fastcgi如何接收数据?spawn-fcgi与fastcgi是父子进程关系,

2023-04-14 15:43:14 2174

原创 HTTP协议

客户端(浏览器)发送给服务器的数据格式,请求分为四部分: 请求行, 请求头, 空行, 请求数据。服务器给客户端发送的数据,四部分: 状态行, 消息报头, 空行, 响应正文。客户端会将数据提交给服务器。

2023-04-13 22:16:44 684

原创 Nginx快速上手

Nginx作为web服务器:# 部署静态网页1. 制作出来, 并且部署到对应的资源目录中2. 根据客户端的请求, 在服务器端添加对应的 location处理指令 - nginx.conf3. 重新加载nginx.conf配置文件客户端请求的url: http://xxxx.com/hello/login.html- 去掉协议: http- 去掉域名/IP:- 去掉端口- 去掉尾部的文件名Nginx作为反向代理服务器:1. 找到反向代理服务器 的配置文件: nginx.conf。

2023-04-13 20:55:56 639

原创 Redis快速上手

两种模式同时开启, 如果要进行数据恢复, 如何选择?key: 必须是字符串 - “hello”List类型:存储多个string字符串的。aof和rdb能不能同时打开?aof和rdb能不能同时关闭?List类型 - 存储多个字符串。String类型:字符串。SortedSet类型。value: 可选的。

2023-04-11 11:51:27 663

原创 分布式文件系统FastDFS

fastDFS是c语言编写的一款开源的分布式文件系统(余庆淘宝架构师)。为互联网量身定制,充分考虑了冗余备份、负载均衡、线性扩容等机制,注重高可用、高性能等指标。可以很容易搭建一套高性能的文件服务器集群提供文件上传、下载等服务。图床、网盘冗余备份: 纵向扩容线性扩容: 横向扩容fastDFS框架中的三个角色具体说明追踪器Tracker - 管理者(守护进程)管理存储节点存储节点 - storage(守护进程)存储节点是有多个的客户端 - 开发者编写的程序(非守护进程)

2023-04-10 15:23:39 1026

原创 内存对齐总结

计算机系统对基本类型数据在内存中存放的位置有限制,它们会要求这些数据的首地址的值是某个数k(通常它为4或8)的倍数,这就是所谓的内存对齐。在结构体中,编译器为结构体的每个成员按其自然边界(alignment)分配空间,各个成员按照它们被声明的顺序在内存中顺序存储,第一个成员的地址和整个结构体的地址相同。看下面程序,理论上占10byte,age占4byte,weightheight各占8字节,那么将它们放到一个结构体中应该占30byte;但是实际上得到的结果是32byte,这就是内存对齐所导致的。

2023-04-09 19:37:07 653

原创 【CPP11新特征】01:概述

要解决的问题是:可能调用了库函数、或者一个目标文件中调用了另外一个文件中的库函数,需要通过链接器建立对应的关系,使程序能够正常的执行。编译的过程将预处理的文件进行一系列的词法分析、语法分析、语义分析及优化成相应的汇编代码。答:strlen的时间复杂度为O(n),而string.length的时间复杂度为O(1),string类中存储着length的大小,strlen为遍历方式。答:理解为调用的是类对象str1的函数,而str2作为参数传入函数中,str1是一个this指针(this对象是str1)

2023-04-09 12:28:39 543

原创 multiple definition of ‘xxx‘ first defined here错误记录

a.cpp和b.cpp先分别被编译为.o格式的目标文件,两个目标文件再被链接器链接起来,这当中a.cpp和b.cpp分别进行了一次include,相当于global.h中的代码重复出现了一次。在C++中const修饰的变量,在编译的时候如果前面有 extern 和取地址符 & 时,会为变量分配存储空间是为了兼容C语言,但是在C++中,用const修饰的变量就真的无法修改它的值,可以说是常亮。extern修饰的变量具有外部链接属性,可以实现全局变量的属性,与const结合就可以实现全局和只读变量的目的,

2023-04-08 17:48:16 10115 1

原创 一个的错误的演化

C程序中的问题的本质:在于定义了char *str但是没有为其分配内存空间,添加上一行calloc操作为其分配内存空间:char * str;int num;len ++;} //获取num的长度 int i = len - 1;num /= 10;i --;return 0;C++程序中的问题也是相同的string str;没有进行初始化,直接使用str[i]去引用string中的某个字符导致访问非法内存访问。

2023-04-03 00:51:19 455

原创 【Linux系统与网络编程】18:并发模型

相较于多进程IO,多线程共享进程空间,线程的通信变得简单、成本低、但是需要考虑线程安全的问题(互斥、锁实现)注:客户端保证在断开之前会发送完整的数据,且客户端一定会调用。

2023-03-30 20:45:44 866

原创 【Linux系统与网络编程】17:IO多路复用

push的速度特别快,而pop弹出有一个标准IO的系统调用输出过程(比较消耗时间),导致输出的每一个线程执行进度不是按照预期顺序进行的。:多线程,创建一个线程进行用户数据的接收,另外再创建一个线程进行sleep睡眠等待,接收数据的线程来通知睡眠线程。注:select的出现具有跨时代的意义,其将原先并发的机制由多线程、多进程的形式改为单个进程就可以实现并发管理。补充:死锁是指两个或两个以上的进程/线程因为进程推进顺序不当、或者资源数量受限,而导致的互相等待的情况。运行结果,文件的输出是没有顺序的输出,

2023-03-30 11:14:23 610

【免费下载】HBase分布式数据库实验

HBase分布式NoSQL数据库实验 1.HBase基础 HBase伪分布式部署 HBase Shell接口操作 HBase Web UI管理 2.HBase数据管理 HBase DDL操作 HBase DML操作 练习1:HBase Shell操作 练习2:HBase Shell数据操作 案例:CMS数据表设计 3.HBase集群管理 创建和使用自动化脚本Shell HBase用户权限管理 4.HBase编程开发 Java API命名空间操作 Java API表操作 编程实现数据操作功能 编程应用过滤器

2022-04-15

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

TA关注的人

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