设计模式
本文主要介绍设计模式的主要设计原则和常用设计模式。
一、UML画图
1.类图
2.时序图
二、设计模式原则
1.单一职责原则
就是一个方法、一个类只做一件事;
2.开闭原则
就是软件的设计应该对拓展开放,对修改关闭,这在java中体现最明显的就是访问控制修饰符;
3.里式替换原则
就是在设计父子关系时,就是如果能用子类,则一定也能用父类替代;
4.接口隔离
每个接口的设计要高内聚,低耦合;
5.迪特米原则
这个也叫最小知道原则,就是设计一个类的时候,要保证这个对象知道的最小;
6.依赖倒置原则
主要是为了解决类之间的耦合性,这个在spring中体现的很详细,就是类间的依赖通过接口来实现;
三、常用设计模式
设计模式分为三种类型,共23种:
创建型模式:单例模式、抽象工厂模式、建造者模式、工厂模式、原型模式。
结构型模式:适配器模式、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式。
行为型模式:模版方法模式、命令模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式、状态模式、策略模式、责任链模式、访问者模式。
创建型模式
1.原型模式(singleton)
1) 概述
解决问题:在系统中其实只需要该类的一个对象,为避免频繁创建和销毁其他对象,只给该类一个单例对象供使用;解决方法:给该类一个全局静态变量来保存单例,只提供一个共有方法来获取该实例,不提供构造方法来实例化对象;使用场景:1.只需要一个全局实例的,比如说生产全局UUID的生成器;
2) 具体说明
普通模式:重点注意由于只有一个实例化对象,所以实例变量是静态成员变量;再就是构造方法要是private修饰,排除new方法创建新的对象;还有就是创建实例对象的方法要是public static,这样才能通过类名直接创建;
饿汉式:就是创建一个静态常量作为实例,这样类一加载就完成了实例对象的初始化操作;劣势也很明显,就是没法懒加载,但后面没有用到该单例时候也被加载进来的了;
懒汉式:就是在调用getInstance()方法时才实例出单例对象,并且之前创建单例模式的方法都没有考虑到并发情况,当同时进入到getInstance()创建实例时候,没有办法保证只创建一个实例,所以动用synchronized和volatile关键字来保证方法的调用并发执行;
双重检验式:在创建单例之前判断单例是否存在,再进入加锁阶段,和懒汉式有区别的是加锁阶段后还会再次判断是否单例存在,这是生产环境常用的模式。
IoDH方式:就是通过内部静态类的方式来避免懒汉式类加载的时候就创建了实例的问题;
3) 代码实现
/*** @author yangnk* @desc* @date 2023/08/13 16:46**/
public class Singleton {//volatile 保障可见性private volatile static Singleton singleton;//private构造方法,无法通过new来实例化对象private Singleton() { }public static Singleton getSingleton() {if (singleton == null) {//用synchronized加锁,只允许并发情况下进行一个实例化操作synchronized (Singleton.class) {//需要再次判断singletonTest == null,避免指令重排导致初始化和分配内存失序if (singleton == null) {singleton = new Singleton();}}}return singleton;}public static void main(String[] args) {for (int i = 0; i < 3; i++) {Singleton singleton = Singleton.getSingleton();System.out.println("singletonTest.hashCode() = " + singleton.hashCode());}}
}
4) 总结
优点:1、只有一个对象在内存中,不用占用过多堆内存;2、只有一个实例,可以严格控制访问控制;缺点:1、违法类设计模式的单一指责的原则,一个实例就能做好所有的事?肯定不行;
2.工厂模式(factory)
1) 概述
解决问题:将产品实例的创建过程封装在工厂类中实现,将产品的声明和创建分离开来,提供统一的接口来创建不同的产品实例,解决需要创建多种继承同一接口的产品;解决方法:每个产品实现同一抽象产品类,每个工厂类实现同一抽象工厂类,通过多态特性实现不同的产品由不同的产品工厂类来实现;使用场景:工厂设计模式在各大框架中是运用最多的,在自己之前写过的代码中,日志记录也用到了这种设计模式,他可以拓展其他记录日志的方式;再通过反射和配置的形式,可以做到不需要修改代码就能实现不同记录日志的功能;
2) 具体说明
**主要角色:**
抽象工厂类:声明了一组用于创建产品对象的方法,每个方法对应一种产品类型。抽象工厂可以是接口或抽象类。
具体工厂类:生产具体产品的类,实现了抽象工厂类;
抽象产品类:是具体产品类的父类,封装了具体产品的方法;
具体产品类:实现具体方法,实现了抽象产品类;
几种不同的工厂模式:
简单工厂模式:工厂方法的思路是通过工厂类来创建相应的实体对象,简单工厂的逻辑是具体产品类实现抽象或接口产品类的方法,外部想要使用该产品需要通过工厂类来获取,该类工厂模式通过判定来生产相应的具体产品类;
抽象工厂模式:当碰到所需生产的具体产品太多的时候,它只需要实现相应的具体产品类,但是在工厂类中,他是需要修改代码来实现的,这就违背了设计模式修改闭合的原则,所以借鉴产品类有抽象或接口的思路,工厂类也有相应的抽象类或接口,如果新增了具体产品,就新增相应产品工厂类。
3) 代码实现
4) 总结
优势:1、向用户隐藏了产品生产的逻辑,符合Java良好封装性的特征;2、如果想要再加新的产品类,不需要修改其他代码,只需要实现他们的接口就好了;劣势:1、如果产品很多那就很麻烦了,所以工厂模式不太适合产品超过5个的设计;
3.原型模式(prototype)
1) 概述
模式定义:允许通过拷贝原始对象的属性创建一个相同的对象,而不需要关注这个对象怎么创建的。
解决问题:不需要关注怎么创建一个新的对象。
解决方案:在Java中年通过实clone()方法,在Spring中通过声明bean为Prototype类型来实现。
应用场景:通过Java中的clone方法可以根据模板对象克隆一个原型对象,这就是原型模式的应用。在使用原型模式的时候要着重关注浅克隆还是深克隆。比较适合创建一个实例化比较复杂的时候,比如创建网络链接或数据库连接; 原型创建的对象一般会缓存起来,在运行时在缓存中获取即可。
2) 具体说明
原型的设计模式在于系统中有一个原型实例,之后在需要只需要**复制**他的副本就好了。原型设计模式最初由原型抽象类和原形实现类组成,其中最关键的在于要实现原型副本的拷贝,在Java中这是很容易实现的,直接重写clone方法就好了,但这个要注意Java里的深复制和浅复制,如果成员变量有对象的话,需要实现通过流来实现深复制。之后原型进化出另外一个组件,是原型管理器,其将原型保存到一个map中,等到其他类需要的话,再从这个map中拷贝。
3) 代码实现
4) 总结
优势:提高实例化对象的性能,不需要关注构造函数和初始化的过程,一般创建好的原型对象会放在缓存中,后续直接从缓存中获取对象即可 。劣势:如果类的成员变量引用比较深的话,那样clone起来就比较麻烦了;参考资料:深度分析:java设计模式中的原型模式,看完就没有说不懂的:https://segmentfault.com/a/1190000023831083
4.构建者模式(Builder)
1) 概述
- 解决问题:当实例化一个对象的时,需要配置多个参数,并且参数的组合类型还非常多的情况,可以考虑使用使用构建者模式。
- 解决方案:通过Builder统一给需要的对象来进行构建。
- 应用场景:应用于一个实例需要通过配置 多个参数才能构建,并且这样的参数搭配有很多种,这种情况可以将产品本身和产品的创建解耦,产品的创建就交给builder来实现,实践中一般构造函数中的参数超过4个就可以考虑使用构建者模式了;
2) 具体说明
构建者模式讲的是这样一件事,就是如果一个实例有很多类组件或属性共同组成,而且没有固定套路,这样的的组合有很多种,所以就需要一种套餐的形式去构建,就像kfc套餐一样,汉堡和饮料作为套餐,具体类别你可以再选择;
构建者模式有三大组件,包括builder接口类、builder实现类还有director。他们的逻辑关系是这样的,builder实现类负责组合各类产品,最合成一个套餐,这个套餐其实在他的接口中就已经制定好了,而director就负责构建这样一个套餐;
3) 代码实现
简单构建者模式的实现:
public class Computer {private final String cpu;//必须private final String ram;//必须private final int usbCount;//可选private final String keyboard;//可选private final String display;//可选private Computer(Builder builder){this.cpu=builder.cpu;this.ram=builder.ram;this.usbCount=builder.usbCount;this.keyboard=builder.keyboard;this.display=builder.display;}public static class Builder{private String cpu;//必须private String ram;//必须private int usbCount;//可选private String keyboard;//可选private String display;//可选public Builder(String cup,String ram){this.cpu=cup;this.ram=ram;}public Builder setUsbCount(int usbCount) {this.usbCount = usbCount;return this;}public Builder setKeyboard(String keyboard) {this.keyboard = keyboard;return this;}public Builder setDisplay(String display) {this.display = display;return this;}public Computer build(){return new Computer(this);}}
}
4) 总结
优势:针对很多参数组成的实例,将对象的构建和使用分离,能够非常灵活的构建一个对象;
劣势:1.他有一定的局限性,就是builder的实例是同一个类别的,或者说他是实现同一个接口的;2.使用构建者模式进行对象创建适合参数比较多得情况,参数较少不建议使用;
参考资料:秒懂设计模式之建造者模式(Builder pattern) shusheng007:https://zhuanlan.zhihu.com/p/58093669
结构性模式
5.适配器模式(adapter)
1) 概述
解决问题:已有的对象和需要的对象无法直接对接,需要通过适配器来进行中转适配。
解决方案:适配器继承或者依赖适配者,在适配器中实现需要提供的功能;
使用场景:适配器类的使用场景还是很广的, 在SpringMVC中就有广泛的使用,比如Handler和HandlerAdapter的关系;
2) 具体说明
主要角色:
- 适配器接口类:规定适配器需要实现的接口方法;
- 适配器类:为目标类实现功能匹配的类;
- 适配者接口类:目标类,原始还未适配的类的接口;
- 适配者类:目标类的实现类;
适配器模式是利用一个适配器类来将接口无法适配的类对接起来。常用组件是一个适配器类和一个适配器接口类外加一个适配者类,适配者类上面可以有个是适配者类接口,要做的就是外部通过适配器就能够直接调用适配者的方法,具体实现是适配器类实现适配接口类的方法,适配器类接口种定义了外部需要的接口,适配器类可以继承适配者,这样就能从其身上继承他的方法,另一种方式是组合适配者对象引用。总的来说,适配器模式的关键在于实现他的适配器接口类,继承适配者类。他的UML类图如下所示:
3) 代码实现
4) 总结
优势:1、可以通过一个适配器适配多个适配者,这样可以弥补前期设计没有考虑周全的问题;
劣势: 加了中间一层适配器类转发,导致代码关系变复杂了;
一文彻底弄懂适配器模式(Adapter Pattern):https://segmentfault.com/a/1190000040524953
6.装饰者模式(decorator)
1) 概述
解决问题:在不改变目标类的前提下拓展功能。
解决方案:通过将目标类包装在修饰器内,在能够实现目标类的功能同时,修饰器类也能拓展其他功能;
应用场景:装饰者设计模式在Java IO中运用的十分普遍,为什么在IO中引用普遍呢?在于IO为了兼顾不同应用场景和需求有太多不同类型的IO流了,所以利用修饰者模式的话,只需要在基础IO流上进行功能补充就好了;
2) 具体说明
主要组件:
构建接口:目标类的接口类,定义目标类需要实现的功能;
具体构建类:构建接口的具体实现;
修饰器接口:持有对构建类的引用,并实现了构建接口的方法,能够统一对外提供目标类的方法;
具体修饰器类:实现了修饰器接口,作为修饰器具体实现类还会新增其他功能;
修饰者模式又称为包装器模式,出现的原因在于有在基础类上进行增加功能的需求,如果直接修改当然违背了对修改闭合的原则,所以就想出了在原本的类上新增特性的修饰者类。实现该种模式的逻辑是:原始的被目标类实现对应的接口,修饰者也实现这个接口,当然这不是真正的修饰者类,其真正的修饰者类继承了修饰者接口,将其补充功能在真正的修饰者类中实现。
3) 代码实现
4) 总结
优势:1、修饰者是类似于继承的一种增强其他类的一种方式,但是他更灵活,要增加什么功能可以自己增加;2、通过配置和运行时动态生成的方式,可以让他变得更灵活;
劣势:变复杂了;
7.门面模式(facade)
1) 概述
解决问题:访问系统中存在多个子系统,访问起来非常复杂;解决方案:为客户端提供一个统一的门面类型,之后只需要访问门面即可访问子系统中方法;使用场景:Spring的日志框架中用到了,slf4j统一了丰富多样的日志实现;
2) 具体说明
主要角色:
门面类:通过门面统一向外界提供服务;
子系统接口:规定子系统需要实现的逻辑;
子系统类:实现子系统接口,实现各自的业务逻辑;
门面模式又称外观模式,用以解决在多个外部系统要和多个内部系统进行通信,可能存在非常多的联系,提升系统交互的复杂度,通过引入门面统一负责和外部系统的通信,减少系统的复杂程度;在门面模式中存在门面和子系统两个角色。
3) 代码实现
4) 总结
优点:1.化繁为简,将对多个不同的子系统访问转换为会单个门面的访问;缺点:1.违反了开闭原则,组件间相互依赖,修改子系统会涉及修改门面 ;
8.代理模式(proxy)
1) 概述
解决问题:通过代理类来实现对委托类的操作,可以出现在委托类无法获得或者不便获得,也可以用以增强对委托类的操作;
解决方案:JDK和Spring源码中有很多实现;
2) 具体说明
主要角色:
委托者接口:定义目标类需要实现的方法;
委托者实现:具体实现委托类中的方法;
代理者:代理类中有委托类的引用,在代理类中也需要实现委托类的方法,所以可以执行委托类的本身的方法外,除此之外还能够在该方法前后进行增加;
代理模式有3个组件,包括:委托者接口、委托者还有代理者,他们的关系是:定义一个委托者接口,委托者和代理者都要实现他的方法,在代理类中还需要创建委托者的对象引用,这样在对委托者类方法进行重写时候可以直接调用。动态代理的UML类图:
代理模式经常用在(1)委托类不想被直接调用,可以通过调用他的代理类来实现,像房产中介一样;(2)还有一种情况是可以增强委托类的能力,像Java中的动态代理,这中在spring aop中应用广泛;
3) 代码实现
4) 总结
优势:降低调用者和被调用者的耦合关系,怎么说呢?就是被调用者想要拓展新功能,可以在代理类中实践,不需要在自身类中进行修改,符合设计模式的开闭原则;
劣势:1对于JDK的动态代理,他需要委托类有接口,通过CgLib来动态代理,可以不需要;
行为型模式
9.责任链模式(chain of responsibility)
1) 概述
解决问题:一条处理链中的每个角色都能够处理请求,避免请求方和相应方的耦合关系,沿着这条处理链处理请求,直到最后处理得到结果。使用场景:Spring的Filter中使用了责任链,这个适合于可以进行一系列链式处理的场景;
2) 具体说明
对于处理流程是线性的比较合适,每个handler中包含目前节点需要处理的业务,也包括下一个节点的引用。
3) 代码实现
4) 总结
10.观察者模式(Observer)
1) 概述
2) 具体说明
观察者模式又称订阅发布模式,所以他适合发布订阅的场景,当目标对象有事件发生,就会通知观察者。
3) 代码实现
4) 总结
四、代码实现
GitHub:https://github.com/yangnk/MyComputerScience/tree/07f4ea1e6c06437ba5fa552a288e67a1adae3cf9/src/main/java/designPattern
TODO
- 需要完善已经写的设计模式;
- 需要补充新的还未加上的设计模式;
参考资料
类图、时序图怎么画:https://design-patterns.readthedocs.io/zh_CN/latest/read_uml.html#id2
设计模式gitbook上的一本书,讲的很好:https://gof.quanke.name
菜鸟教程上的教程:http://www.runoob.com/design-pattern/design-pattern-tutorial.html
本文由博客一文多发平台 OpenWrite 发布!
相关文章:

设计模式
本文主要介绍设计模式的主要设计原则和常用设计模式。 一、UML画图 1.类图 2.时序图 二、设计模式原则 1.单一职责原则 就是一个方法、一个类只做一件事; 2.开闭原则 就是软件的设计应该对拓展开放,对修改关闭,这在java中体现最明显的就…...

用gdal库读取tif影像并填充边缘,并根据窗口大小滑动裁剪裁剪(包含gdal转PIL)
相关文章 PIL,OPENCV之间的转换关系_pil cvtcolor(image)_番茄就要炒鸡蛋的博客-CSDN博客 python GDAL和PIL图像转换_gdal.readasarray和pil_llc的足迹的博客-CSDN博客 一、原始数据 二、分别读取数据 1、gdal读取的array 2、pil读取的array 三、 gdal转pil image …...

sqlserver数据库导出到mysql
爱到分才显珍贵,很多人都不懂珍惜拥有,只到失去才看到,其实那最熟悉的才最珍贵的。 这里只介绍一种方式,有很多的方式。 1.使用Navicat 安装 下载 2.工具 数据传输 3.选择源和目标 然后开始 4.最好导入前备份一下库...

【抓包工具】whistle抓包工具分享
一、使用场景 抓包请求转发 二、基础篇 官网:http://wproxy.org/whistle/ github: https://github.com/avwo/whistle 简介: whistle(读音[ˈwɪsəl],拼音[wēisǒu])基于Node实现的跨平台web调试代理工具,类似的工具有Window…...

docker可视化工具Portainer
1:Portainer简介 Portainer是一个docker可视化管理工具,可以非常方便地管理docker镜像容器。官网地址:https://www.portainer.io/ 注:现在Portainer有BE(收费)和CE(免费)版本,安装的…...

售后服务管理系统哪家好?云部署的售后服务软件有什么优势?
如今,越来越多的企业开始利用数字化系统来监控他们建造、操作或维护的高科技设备的技术属性。然而,仍然有很多公司依赖于孤立的低技术解决方案,比如使用Excel电子表格和手动流程来管理工作。当然,对于一家公司来说,寻找…...

laravel-admin之 解决上传图片不显示 $form->image(‘image‘); 及 $grid->column(‘image‘);
参考 https://blog.csdn.net/u013164285/article/details/106017464 $grid->column(‘image’)->image(‘http://wuyan.cn’, 100, 100); // //设置服务器和宽高 图片上传的域名 上传的图片不显示 在 这里设置了图片的上传路径 在这里设置 域名 就可以回显图片...

运营商三要素 API:构建安全高效的身份验证系统
当今数字化的世界中,身份验证是各行各业中至关重要的一环。为了保护用户的隐私和数据安全,企业需要寻求一种既安全可靠又高效便捷的身份验证方式。运营商三要素 API 应运而生,为构建安全高效的身份验证系统提供了有力的解决方案。 运营商三要…...

使用 BERT 进行文本分类 (01/3)
摄影:Max Chen on Unsplash 一、说明 这是使用 BERT 语言模型的一系列文本分类演示的第一部分。以文本的分类作为例,演示它们的调用过程。 二、什么是伯特? BERT 代表 来自变压器的双向编码器表示。 首先,转换器是一种深度学习模…...

layui第三方组件cron的使用
1. 首先上代码 <!DOCTYPE html> <html><head><meta charset"utf-8" /><title>cron表达式生成</title><meta name"renderer" content"webkit" /><meta http-equiv"X-UA-Compatible" con…...

Linux 信号的基本概念
信号的基本概念 1. 信号的概念 信号是Linux系统响应某些条件产生的一些事件。接收到信号的进程会相应地采取一些行动。 2. 信号的生成 信号是由于某些错误条件而生成的,如内存段冲突、浮点处理器错误或非法指令等。信号的生成其实就是一种软件层次的中断&#x…...

神经网络基础-神经网络补充概念-31-参数与超参数
概念 参数(Parameters): 参数是模型内部学习的变量,它们通过训练过程自动调整以最小化损失函数。在神经网络中,参数通常是连接权重(weights)和偏置(biases),…...

C# Linq源码分析之Take (二)
概要 本文主要分析Linq中Take带Range参数的重载方法的源码。对于其中的一些关于Range或序列的新概念,不再赘述,请参看C# Linq源码分析之Take (一) 源码分析 基于Range参数的Take重载方法,主要分成两部分实现&#x…...

FPGA控制RGB灯WS2812B
文章目录 FPGA控制RGB灯WS2812B1、简介1.1水一水1.2程序完成目标1.3项目工程结构 2、代码3、仿真代码4、结果展示 FPGA控制RGB灯WS2812B 1、简介 1.1水一水 最近在学习WS2812B手册,是一个简单的协议编写,做的时间也算是比较久,相对做出了一…...

【Linux】【驱动】应用层和驱动层传输数据
【Linux】【驱动】应用层和驱动层传输数据 绪论1.如果我在应用层使用系统0 对设备节点进行打开,关闭,读写等操作会发生什么呢? 2 我们的应用层和内核层是不能直接进行数据传输的3 驱动部分的代码4 应用代码5 编译以及运行代码 绪论 Linux一切皆文件! 文…...

【第二阶段】kotlin函数引用
针对上篇传入函数参数我们也可以重新定义一个函数,然后在main中调用时传入函数对象 lambda属于函数类型的对象,需要把普通函数变成函数类型的对象(函数引用),使用“::” /*** You can edit, ru…...

sip网络号角喇叭 sip音柱 POE供电广播音箱 ip网络防水对讲终端 sip网络功放
SV-7042TP网络号角喇叭 一、描述 SV-7042TP是我司的一款SIP网络号角喇叭,具有10/100M以太网接口,内置有一个高品质扬声器,将网络音源通过自带的功放和喇叭输出播放,可达到功率30W。SV-7042TP作为SIP系统的播放终端,可…...

【网络】传输层——TCP(滑动窗口流量控制拥塞控制延迟应答捎带应答)
🐱作者:一只大喵咪1201 🐱专栏:《网络》 🔥格言:你只管努力,剩下的交给时间! 上篇文章对TCP可靠性机制讲解了一部分,这篇文章接着继续讲解。 🎨滑动窗口 在…...

Electron教程_编程入门自学教程_菜鸟教程-免费教程分享
教程简介 Electron是一个是使用JavaScript,HTML和CSS构建跨平台的桌面应用程序框架。 Electron 通过将 Chromium 和 Node.js 合并到同一个运行时环境中,并将其打包为 Mac,Windows 和 Linux 系统下的应用来实现这一目的。 Electron入门教程 …...

LVS负载均衡DR(直接路由)模式
在LVS(Linux Virtual Server)负载均衡中的DR(Direct Routing)模式下,数据包的流向如下: 客户端发送请求到负载均衡器(LVS)的虚拟IP(VIP)。负载均衡器&#x…...

14 anaconda+pycharm环境管理以及源管理
文章目录 环境管理博主使用的环境环境设置conda常用指令pycharm与环境的连接(新2023版本后)设置国内镜像(源管理)常用操作 环境管理 博主使用的环境 Anaconda3-2023.03-Windows-x86_64 pycharm-professional-2023.2 环境设置 …...

【C语言程序设计】C语言基本数据类型与表达式(思考题)
思考题 1、C语言的主要特点有哪些? ①简单紧凑、灵活方便,②是结构化的语言,③运算符丰富,④是一种高效的语言,⑤可直接对硬件进行操作,⑥具有较好的可移植性。 高效性:C语言是一种高级编程语言…...

Linux 网络发包流程
哈喽大家好,我是咸鱼 之前咸鱼在《Linux 网络收包流程》一文中介绍了 Linux 是如何实现网络接收数据包的 简单回顾一下: 数据到达网卡之后,网卡通过 DMA 将数据放到内存分配好的一块 ring buffer 中,然后触发硬中断CPU 收到硬中…...

Python web实战之Django的AJAX支持详解
关键词:Web开发、Django、AJAX、前端交互、动态网页 今天和大家分享Django的AJAX支持。AJAX可实现在网页上动态加载内容、无刷新更新数据的需求。 1. AJAX简介 AJAX(Asynchronous JavaScript and XML)是一种在网页上实现异步通信的技术。通过…...

spring boot实现实体类参数自定义校验
安装依赖项 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId></dependency>1、新建实体类 Data public class UserEntity {private String name;private Integer age;…...

网络安全威胁与防御策略
第一章:引言 随着数字化时代的快速发展,网络已经成为人们生活和工作中不可或缺的一部分。然而,网络的广泛应用也引发了一系列严峻的网络安全威胁。恶意软件、网络攻击、数据泄露等问题层出不穷,给个人和企业带来了巨大的风险。本文…...

C++:哈希表——模拟散列表
模拟散列表 维护一个集合,支持如下几种操作: 1.“I x”,插入一个数x 2.“Q x”,询问数x是否在集合中出现过 现在要进行N次操作,对于每个询问操作输出对应的结果 输入格式 第一行包含整数N,表示操作数量 …...

项目配置中心介绍
目录 什么是配置中心 为什么要有配置中心 配置中心的做法(读取和通知) 配置中心优点: 常用的配置中心中间件 什么是配置中心 配置中心就是用来管理项目当中所有配置的系统,也是微服务系统当中不可或缺的一部分。项目的配置文件不放到本地…...

14-案例:购物车
综合案例-购物车 需求说明: 1. 渲染功能 v-if/v-else v-for :class 2. 删除功能 点击传参 filter过滤覆盖原数组 3. 修改个数 点击传参 find找对象 4. 全选反选 计算属性computed 完整写法 get/set 5. 统计 选中的 总价 和 数量 计算属性conputed reduce条件求和 6. 持久化到本…...

上海市青少年算法2023年2月月赛(丙组)
上海市青少年算法2023年2月月赛(丙组)T1 格式改写 题目描述 给定一个仅由拉丁字符组成字符序列,需要改写一些字符的大小写,使得序列全部变成大写或全部变成小写,请统计最少修改多少个字符才能完成这项任务。 输入格式 一个字符序列:保证仅由拉丁字符构成 输出格式 单个整…...