自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 C++设计模式之中介者

用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。

2024-12-10 23:09:53 412

原创 C++设计模式之适配器

将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。要点总结Adapter模式主要应用于“希望复用一些现存的类,但是接口又与复用环境要求不一致的情况”,在遗留代码复用、类库迁移等方面非常有用。GoF23定义了两种Adapter模式的实现结构:对象适配器和类适配器。但类适配器采用多继承”的实现方式,一般不推荐使用。对象适配器采用”对象组合”的方式,更符合松耦合精神。

2024-12-04 22:56:23 503

原创 C++设计模式之代理模式

为其他对象提供一种代理以控制对这个对象的访问。以下是一个简单的 C++ 代理模式的例子,其中实现了一个图片加载的代理。

2024-12-04 22:22:47 595

原创 C++设计模式之外观模式

从客户程序的角度来看,Façade模式简化了整个组件系统的接口, 对于组件内部与外部客户程序来说,达到了一种“解耦”的效 果——内部子系统的任何变化不会影响到Façade接口的变化。下图中左边方案的问题在于组件的客户和组件中各种复杂的子系统有了过多的耦合,随着外部客户程序和各子系统的演化,这种过多的耦合面临很多变化的挑战。为子系统中的一组接口提供一个一致的界面, Facade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。如何将外部客户程序的演化和内部子系统的变化之间的依赖相互解耦?

2024-12-04 22:07:30 734

原创 C++设计模式之享元模式

运用共享技术有效地支持大量细粒度的对象。chatGPT给出的享元模式的例子以下是一个简单的 C++ 代码例子,演示了享元模式的实现。这个例子以文本编辑器中的字符格式化为场景。

2024-12-04 21:51:59 484

原创 C++设计模式之单例模式

保证一个类仅有一个实例,并提供一个访问它的全局访问点。在单例模式中使用双检查锁(DCL,Double-Checked Locking)时,可能会遇到一些问题,特别是在多线程环境下。在C++11之前的版本中,由于缺少内存栅栏(memory barrier)的支持,可能导致DCL失效,从而造成线程安全性问题。

2024-12-04 21:14:56 549

原创 C++设计模式之构造器

由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定。这个例子中的产品是简单的包含两个部分的字符串,实际应用中可以根据需求定义更复杂的产品结构。如何提供一种“封装机制”来隔离出“复杂对象的各个部分”的变化,从而保持系统中的“稳定构建算法”不随着需求改变而改变?通过调用建造者的方法,按照一定的构建流程组织建造者完成产品的构建。设计模式的目的是将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。,按照一定的构建流程构建了石头房子,并输出结果。

2024-11-29 14:05:11 866

原创 C++设计模式之抽象工厂

同时,由于需求的变化,往往存在更多系列对象的创建工作。如何绕过常规的对象创建方法(new),提供一种封装机制来避免客户程序和这种多系列具体对象创建工作的紧耦合?第二版:使用工厂方法,但是会遇到问题,使用的时候工厂之间有关联性,必须是同一系列的,比如都是oracle数据库的连接、命令、datareader等,不能是mysql的连接、orable的命令这种交叉使用。第三版:有关联性的创建行为放在一起,合成一个工厂,这就是抽象工厂Abstract Factory。第一版:不好的设计,绑定到具体的类。

2024-11-28 22:39:46 219

原创 C++设计模式之工厂模式和原型模式

定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method使一个类的实例化延迟到其子类。具体到上面的代码,用于创建对象的接口SplitterFactory,让子类(BinarySplitterFactory,TxtSplitterFactory等具体工厂)决定实例化哪一个类。在下列情况下可以使用Factory Method模式:• 当一个类不知道它所必须创建的对象的类的时候。• 当一个类希望由它的子类来指定它所创建的对象的时候。

2024-11-20 23:06:08 466

原创 设计模式之装饰模式

在某些情况下,我们可能会“过度地使用继承来扩展对象的功能”,由于继承为类型引入的静态特质,使得这种扩展方式缺乏灵活性;并且随着子类的增多(扩展功能的增多),各种子类的组合(扩展功能的组合)会导致更多子类的膨胀。第二个版本:把CryptoStream继承自Stream,直接对Stream进行加密,运行时绑定它的子类(FileStream,NetworkStream,MemoryStream)。考虑不同的流stream,有文件流,内存流,网络流等,需要对不同的流进行加密,缓冲。

2024-11-18 21:50:31 355

原创 设计模式之观察者模式

定义对象间的一种一对多的依赖关系,以便当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动刷新。这一模式中的关键对象是目标(subject)和观察者(observer)。一个目标可以有任意数目的依赖它的观察者。一旦目标的状态发生改变 , 所有的观察者都得到通知。作为对这个通知的响应,每个观察者都将查询目标以使其状态与目标的状态同步。这种交互也称为发布-订阅(puplish-subscribe)。目标是通知的发布者。它发出通知时并不需知道谁是它的观察者。可以有任意数目的观察者订阅并接收通知。

2024-11-18 21:33:12 654

原创 设计者模式之策略模式

在软件构建过程中,某些对象使用的算法可能多种多样,经常改变,如果将这些算法都写在对象中,将会使对象变得异常复杂;而且有时候支持不频繁使用的算法也是一个性能负担。如何在运行时根据需要透明地更改对象的算法,将对象和算法解耦?举例:不同国家税率的计算,新的需求是新增一个国家税率的计算。不好的做法:增加一个if else好的做法:定义一个新类(扩展),实现虚函数,以此来实现不同的税率计算。定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。本模式使得算法的变化可独立于使用它的客户。

2024-11-07 22:52:14 594

原创 设计模式之模块方法

模板与方法应该是最常使用的设计模式,在GOF(设计模式)中的定义:定义一个操作中的算法的骨架 ,而将一些步骤延迟到子类中。Template Method使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。

2024-11-04 22:08:38 667 1

原创 面向对象的设计原则

使用封装来创建对象之间的分界层,让设计者可以在分解层的一侧进行修改,而不会对另一侧产生不良的影响,从而实现层次间的松耦合。高层模块(稳定)不应该依赖于低层模块(变化),二者都应该依赖于抽象(稳定)。抽象(稳定)不应该依赖于实现细节(变化),实现细节应该依赖于抽象(稳定)。减少系统中的各部分的依赖关系,从而实现“高内聚”,“松耦合”的类型设计方式。而对象组合则只要求被组合的对象具有良好定义的接口,耦合度低。不将变量类型声明为某个特定的具体类,而是声明为某个接口。类模块应该是可扩展的,但是不可修改。

2024-11-03 22:37:58 240

原创 理解为什么要有C++设计模式

抽象:更高层次来讲,人们处理复杂性有一个通用的技术,即抽象。由于不能掌握全部的复杂对象,我们选择忽视它的非本质细节而去处理泛化和理想化了的对象模型。每一个模式描述了一个在我们周围不断重复的问题以及该问题的解决方案的核心,这样,就能一次有一次地使用该方案,而不必做重复劳动。分解:人们面对复杂性有一个常见的做法:即分而治之,将大问题分解为多个小问题,将复杂问题分解为多个简单问题。但是我们通过C++的特性多态来进行操作的话,我们的操作步骤和代码量会明显的减少;

2024-10-31 23:22:00 514

原创 不继承thread写线程

【代码】不继承thread写线程。

2024-08-09 20:47:07 155

原创 docker八大架构之应用服务集群架构

应用服务集群是指它可以创建多个应用层的服务器,并引入了负载均衡(如下图所示),应用以集群方式运作。

2024-05-13 10:47:54 373 1

原创 docker八大架构之应用数据分离架构

数据分离架构是指应用服务(应用层)和数据库服务(数据层)使用不同的服务器来进行操作,如下边的两个图所示。当访问到应用层后,如果需要获取数据会进行访问另一个服务器,从而避免在同一服务器进行操作,避免单机架构的缺点。

2024-05-12 22:44:27 268 2

原创 docker八大架构之单机架构

单机架构指的是应用服务和数据库服务公用同一台服务器。如下边两个图所示,当我们进行购物时,所有的物品信息和用户信息都是在同一个服务器下进行运行的,之所以称为单机架构就是因为它所有的操作是在同一台服务器上进行的。

2024-05-12 22:19:05 459 2

原创 docker是干嘛的?

它利用容器化技术,将应用程序及其依赖项打包到一个称为容器的可移植容器中。这使得应用程序能够在几乎任何环境中运行,而不受所运行的操作系统和硬件的限制。总之,Docker使得开发人员和运维团队能够更轻松地构建、交付和运行应用程序,同时提高了开发和部署的效率。便携性: 可以在不同的环境中轻松部署相同的应用程序,而不必担心环境差异导致的问题。版本控制: 可以轻松地创建、共享和管理容器镜像,确保开发、测试和生产环境的一致性。快速部署: 可以快速地启动和停止容器,从而加快应用程序的部署速度。

2024-05-12 22:18:09 920

原创 【MySQL】用户管理

如果我们只能使用root用户,这样存在安全隐患。这时,就需要使用MySQL的用户管理。

2023-12-23 21:22:33 1845 3

原创 【MySQL】视图

视图是一个虚拟的表,其内容由查询来进行定义。视图的数据变化会影响基表,基表的数据变化也会影响视图。如果我们频繁的进行表查询的时候,我们可以通过视图来进行查询,并且,修改视图后原表也会变化哦。注意,视图不是一个真正的表,但是我们可以使用和表一样的操作来查询它。注意,视图名不要和基表的名字相同。下边我们创建两个表,并插入数据。

2023-12-21 22:28:20 757 3

原创 【MySQL】表的内连和外连

内连接实际上就是利用where子句对两种表形成的笛卡儿积进行筛选,我们前面学习的查询都是内连接,也是在开发过程中使用的最多的连接查询。创建两个表并插入数据。

2023-12-07 20:30:02 521 3

原创 【MySQL】复合查询

单行子查询是指子查询只返回单列,单行数据;多行子查询是指返回单列多行数据,都是针对单列而言的,而多列子查询则是指查询返回多个列数据的子查询语句。在实际应用中,为了合并多个select的执行结果,可以使用集合操作符 union,union all。该操作符用于取得两个结果集的并集。当使用该操作符时,不会去掉结果集中的重复行。– 给自己的表起别名,因为要先做笛卡尔积,所以别名可以先识。自连接是指在同一张表连接查询。现有一个员工信息表emp。返回一行记录的子查询。

2023-12-07 20:16:28 279

原创 【MySQL】内置函数

思路是通过substring函数先将字符串中第一个字符截取出来,使用lcase进行处理之后,再与剩余的部分进行拼接。通常来讲在服务器中存储的密码是以这种加密方式存储的。向上取整函数的上,表示的是正无穷方向的上。向下取整同理,下指的是负无穷的方向。输出两分钟内新插入的数据。

2023-12-05 20:53:59 733 2

原创 【MySQL】聚合函数和分组(查找)

where是过滤表中数据的,而having是过滤分组数据的。在分组之前需要先通过where来拿到所要用到的数据。分组聚合主要使用的是 group by 和 having子句。分组聚合需要注意的是要先进行分组,然后再聚合。在select中使用group by 子句可以对指定列进行分组查询。3.SALGRADE:工资等级表。2.DEPT:部门表。

2023-12-05 16:59:21 218

原创 【MySQL】表的增删查改

desc 表名称。

2023-12-05 16:18:04 289 1

原创 【Linux】Linux网络总结图详解

简单来说,Cookie是用来保存个人信息的,它的保存方法有两种,分别为。

2023-11-01 11:29:36 3651 95

原创 【C++】设计模式之——建造者

建造者模式是一种对象创建型模式之一,用来隐藏复合对象的创建过程,它把复合对象的创建过程加以抽象,通过子类继承和重载的方式,动态地创建具有复合属性的对象。首先先大体了解一下,建造者模式是什么意思,它是怎么实现的?建造者模式主要用于构建复杂问题。

2023-10-03 21:54:30 1186 10

原创 【C++】类型转换

而使用dynamic_cast进行向下转型则是安全的,如果父类的指针(或引用)指向的是子类对象那么dynamic_cast会转换成功,但如果父类的指针(或引用)指向的是父类对象那么dynamic_cast会转换失败并返回一个空指针。上述代码中,如果传入func函数的是子类对象的地址,那么在转换后pb1和pb2都会有对应的地址,但如果传入func函数的是父类对象的地址,那么转换后pb1会有对应的地址,而pb2则是一个空指针。dynamic_cast用于将父类的指针(或引用)转换成子类的指针(或引用)。

2023-10-02 15:09:12 175

原创 【C++】单例

new和delete默认调用的是全局的operator new函数和operator delete函数,但如果一个类重载了专属的operator new函数和operator delete函数,那么new和delete就会调用这个专属的函数。将该类的构造函数设置为私有即可,因为子类的构造函数被调用时,必须调用父类的构造函数初始化父类的那一部分成员,但父类的私有成员在子类当中是不可见的,所以在创建子类对象时子类无法调用父类的构造函数对父类的成员进行初始化,因此该类被继承后子类无法创建出对象。

2023-10-02 09:43:13 196

原创 【C++】智能指针

上述程序是没有问题的,两个结点都能够正确释放。当智能指针对象的生命周期结束时,所有的智能指针默认都是以delete的方式将资源释放,这是不太合适的,因为智能指针并不是只管理以new方式申请到的内存空间,智能指针管理的也可能是以new[]的方式申请到的空间,或管理的是一个文件指针。需要注意的是,智能指针就是要模拟原生指针的行为,当我们将一个指针赋值给另一个指针时,目的就是让这两个指针指向同一块内存空间,所以这里本就应该进行浅拷贝,但单纯的浅拷贝又会导致空间被多次释放,因此根据解决智能指针拷贝问题方式的不同,

2023-10-01 18:34:49 226

原创 【C++】异常

实际中很多公司都会自定义自己的异常体系进行规范的异常管理。公司中的项目一般会进行模块划分,让不同的程序员或小组完成不同的模块,如果不对抛异常这件事进行规范,那么负责最外层捕获异常的程序员就非常难受了,因为他需要捕获大家抛出的各种类型的异常对象。因此实际中都会定义一套继承的规范体系,先定义一个最基础的异常类,所有人抛出的异常对象都必须是继承于该异常类的派生类对象,因为异常语法规定可以用基类捕获抛出的派生类对象,因此最外层就只需捕获基类就行了。

2023-10-01 14:09:44 184

原创 【C++】function包装器和bind包装器

function是一种函数包装器,也叫做适配器。它可以对可调用对象进行包装,C++中的function本质就是一个类模板。Ret:被包装的可调用对象的返回值Args:被包装可调用对象的形参类型包装示例function包装器可以对可调用对象进行包装,包括函数指针(函数名)、仿函数(函数对象)、lambda表达式、类的成员函数。//仿函数public:class Pluspublic:int main()//1.包装函数指针(函数名)//2.包装仿函数(函数对象)

2023-09-30 11:07:21 219 1

原创 【C++11】多线程

主线程创建新线程后,也可以调用detach进行将线程和主线程分离,分离后,新线程会到后台运行,其所有权和控制权将会交给C++运行库,此时,c++运行库会保证当线程退出时,其相关资源能够被正确回收。线程函数的参数是以值拷贝的方式拷贝到线程栈空间中的,就算线程函数的参数为引用类型,在线程函数中修改后也不会影响到外部实参,因为其实际引用的是线程栈中的拷贝,而不是外部实参。在没有对临界资源加锁的时候,由于是多个进程同时进行,这时,不能同步的,正确的完成我们的任务,此时我们就需要给临界资源进行加锁。

2023-09-29 22:12:08 1328

原创 【Linux】线程池

简单的来说,线程池的本质就是使用空间换取时间,例如一个程序本来就需要10个字节,但是它申请内存的时候申请了20个字节,为它以后使用,这样在下次使用的时候就不需要再次申请内存了,从而牺牲了空间节省了时间。线程池内逻辑实现,这里我们锁线程共享的变量放到构造器里头直接初始化,其中,我们还是用了队列来存线程数据,如果有线程进入,我们就会将其线程的操作方法放入队列中,当运行后,我们再将其取出。下面我们实现一个简单的线程池,线程池中提供了一个任务队列,以及若干个线程(多线程)。主函数,用于控制多线程。

2023-09-28 20:33:32 273

原创 【Linux】POSIX信号量

我们要先进性申请资源,后申请锁,因为如果先申请锁的画,如果这时的信号处于满的状态,那么此时我们的锁就会一直卡的,当其他线程进行申请时,就会一直处于堆积的状态。每个执行流进入临界区时,都会提前申请信号量,申请成功后就有了操作特定临界资源的权限,当操作完毕后,就会释放对应的信号量,同样,如果申请失败也会被挂起。当执行流就行申请信号量失败时,也就是说临界资源已经全部申请空了,此时该执行流就会在对应的信号量的等待队列中当中进行等待,直到有信号量被释放时再被唤醒。

2023-09-27 20:49:23 239

原创 【Linux】生产者和消费者模型

生产者和消费者彼此之间不直接通讯,而通过这个容器来通讯,所以生产者生产完数据之后不用等待消费者处理,直接将生产的数据放到这个容器当中,消费者也不用找生产者要数据,而是直接从这个容器里取数据,这个容器就相当于一个缓冲区,平衡了生产者和消费者的处理能力,这个容器实际上就是用来给生产者和消费者解耦的。其中,所有的生产者和消费者都会竞争式的申请锁,因此生产者和生产者、消费者和消费者、生产者和消费者之间都存在互斥关系。生产者和生产者、消费者和消费者、生产者和消费者,它们之间为什么会存在互斥关系?

2023-09-27 15:55:09 314

原创 【Linux】线程安全

其实在多线程中,几乎我们访问到的临界区和临界资源较多,所以我们通过多线程就可以很简单的构造这么一个环境。如下代码:此时我们相当如实现了主线程和新线程之间的通信,其中全局变量const称之为临界资源,因为他被多个执行流共享,而主线程中的printf和新线程中的const++称之为临界区,因为这些代码对临界资源进行了访问。当多个线程同时多一个临界资源进行访问修改的时候,那么此时就可能会导致不一致的问题,解决该问题的方案叫做互斥,互斥的作用就是保证任何时候只有一个执行流通过临界区进行对临界资源访问。我们可以自

2023-09-27 14:31:13 648

原创 【Linux】详细介绍Linux重入不可重入带例子

在Linux中,重入性指的是一个函数可以安全地在同时被多个线程或进程调用时正确地执行。不可重入性则表示一个函数在被并发调用时可能会导致不确定的行为或数据损坏。

2023-09-25 15:07:34 217 3

空空如也

空空如也

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

TA关注的人

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