设计模式(一)
1、适配器模式
(1)概述
- 适配器中有一个适配器包装类Adapter,其包装的对象为适配者Adaptee,适配器作用就是将客户端请求转化为调用适配者中的接口;
- 当调用适配器中的方法时,适配器内部会调用适配者类的方法,这个调用对客户端是透明,实现了不同接口之间由于不兼容的类,可以相互调用;
(2)对象适配器
- Target(目标抽象类):可以是一个抽象类或接口,该类为客户端所需要的接口;
- Adapter(适配器类):Adapter可以调用另外一个接口,对Target和Adaptee进行适配,Target通过Adapter可以调用Adaptee中的业务逻辑,对客户端是透明的;
- Adaptee(适配者类):定义了一个已经存在的接口,适配者类一般是一个具体的类,包含了客户需要调用的业务方法;
- Adapter和Adaptee是关联关系;
//适配器
public class Adapter implements Target{private MySQLConnect mySQLConnect;//适配者对象public Adapter(MySQLConnect mySQLConnect){this.mySQLConnect=mySQLConnect;}@Overridepublic void connect() {mySQLConnect.mysqlConnect();}
}
public interface Target {public void connect();
}
//适配者
public class MySQLConnect {public void mysqlConnect(){System.out.println("数据库链接配置");}
}
//测试
public class Main {public static void main(String[] args) {Target target=new Adapter(new MySQLConnect());target.connect();}
}
(3)类适配器
- 适配器和适配者之间的关系为继承;
- 适配器实现了Target接口,继承了Adapteee类;
- 当Target不是接口,而是抽象类,则无法使用类适配器,当Adaptee类被final修饰,也不能使用类适配器;
//适配器类,其他代码和上一样
public class Adapter extends MySQLConnect implements Target{@Overridepublic void connect() {mysqlConnect();}
}
(3)缺省适配器
- ServiceInterface(适配者接口):为一个接口,实现大量方法;
- AbstractServiceClass(缺省适配器类):实现了适配者接口中所有方法,使用空方法形式;
- ConcreteServiceClass(业务类):为缺省适配器的子类,在没有适配器之前,该类需要实现ServiceInterface中所有方法,引入适配器类后,只需要继承适配器类,实现对应的方法即可;
public interface ServiceInterface {public void print();public void eat();public void smell();
}
public class AbstractService implements ServiceInterface{//缺省适配器@Overridepublic void print() { }@Overridepublic void eat() { }@Overridepublic void smell() { }
}
public class ConcreteService extends AbstractService{@Overridepublic void print() {//重写打印接口System.out.println("打印");}
}
(4)总结
优点:
- 目标类和适配者类解耦,通过引入一个适配器类来重用现有的适配者类,无序修改原有代码结构;
- 增加了类的透明性和复用性,将业务代码封装在适配者类中,对于用户是透明的,同时适配者类可以被多个不同系统调用
- 灵活性和扩展性好,通过配置文件切换适配器类,可以在原有基础上添加新的适配器类,符合开闭原则;
缺点:
- 类适配器中只能适配一个适配者类,java不能多继承;
- 对象适配器,在适配器重置换适配者类比较麻烦,需要先创建一个适配者类的子类,重写需要置换的方法,然后再将适配器适配到这个子类;
使用场景:
- 系统需要使用已有的接口,而这些接口不符合系统需求,甚至没有源代码;
- 想创建一个可以重复使用的类,用于一些彼此之间没有太大关联的一些类,包括一些可能在将来引进的类一起工作;
2、工厂方法模式
(1)概述
- 工厂方法定义一个创建对象的接口,让实现该接口的子类取实例化对象。
- 工厂方法将对象的实例化延迟到其子类创建;
(2)角色
- Product(抽象产品):定义产品接口(某个类型产品),是工厂方法模式中,所有创建对象的公共父类;
- ConcreteProduct(具体产品):实现抽象产品的接口,即某种类型的具体产品,与一个具体工厂一一对应;
- Factory(抽象工厂):创建对象工厂的接口,声明工厂方法(Factory Method),用于返回一个产品,所有创建对象的工厂类都需要实现该接口;
- ConcreteFactory(具体工厂):实现抽象工厂的工厂方法,返回一个具体的产品;
(3)实现
public interface Factory {public Product create();
}
public class MySQLFactory implements Factory{@Overridepublic Product create() {return new MySQLProduct();}
}
public abstract class Factory {//抽象工厂public void connect(){//对客户端隐藏调用具体产品的方法Product product = this.create();product.connect();}public abstract Product create();
}
public class MySQLFactory extends Factory{//具体工厂@Overridepublic Product create() {return new MySQLProduct();}
}
public class Main {public static void main(String[] args) {Factory factory=new MySQLFactory();//可以通过配置文件配置,进行工厂方法切换factory.connect();}
}
(4)总结
优点
- 客户端只需要知道创建对象的工厂方法,工厂方法隐藏具体具体对象被实例化的细节,客户端无需关系对象如何创建,甚至无需关心对象的具体类名;
- 当需要加入一个新的对象产品时,无需修改原系统,只需要新增一个具体对象类和对应的工厂类即可;
缺点:
- 每新增一个产品,就需要新增对应的产品类和工厂类,增加系统复杂度,同时由更多类需要被系统加载,会给系统带来一些而外的开销;
- 引入抽象层,增加系统抽象性和可理解性;
使用场景:
- 客户端不知道他所需要的类;
- 抽象工厂类通过子类创建对象;
3、抽象工厂模式
(1)概述
- 产品等级结构:即产品的继承结构,一个抽象产品,多个相同的产品继承该抽象产品,一个抽象产品与其子类构成一个产品等级结构。如:电视机为抽象类,则海尔电视机,华普电视机,创维电视机为其子类,共同构成一个产品等级结构;
- 产品族:产品族是由同一个工厂产生的,位于不同产品等级结构的一组产品;
- 一个工厂负责生产一个产品族(即下图颜色相同的);
- 抽象工厂会提供一个创建一系列相关或相互依赖的对象的接口,而无需指定他们的具体实现类;
(2)角色
- AbstractFactory(抽象工厂):声明一些列创建产品族的方法,每一个方法对应一个产品;
- ConcreteFactory(具体工厂):实现抽象工厂中的方法,用于创建一组具体产品,这些具体产品构成一个产品族,位于一个产品等级结构中;
- AbstractProduct(抽象产品):为每种产品生成一种接口,在抽象产品中声明了产品所具有的业务方法;
- ConcreteProduct(具体产品):他定义具体工厂生成的产品对象,实现抽象产品接口中声明的业务方法;
(3)实现
public interface AbstractFactory {//抽象工厂public AbstractProductA createProductA();public AbstractProductB createProductB();
}
public class ConcreteProduct1 implements AbstractFactory{//具体工厂1@Overridepublic AbstractProductA createProductA() {return new ProductA1();}@Overridepublic AbstractProductB createProductB() {return new ProductB1();}
}
public class ConcreteProduct2 implements AbstractFactory{//具体工厂2@Overridepublic AbstractProductA createProductA() {return new ProductA2();}@Overridepublic AbstractProductB createProductB() {return new ProductB2();}
}
public interface AbstractProductA {//抽象产品Apublic void printA();
}
public class ProductA1 implements AbstractProductA{//具体产品A--1@Overridepublic void printA() {System.out.println("产品A类--型号1类型");}
}
public class ProductA2 implements AbstractProductA{//具体产品A---2@Overridepublic void printA() {System.out.println("产品A类--型号2类型");}
}
public interface AbstractProductB {//抽象产品Bpublic void printB();
}
public class ProductB1 implements AbstractProductB{//具体产品B--1@Overridepublic void printB() {System.out.println("产品B类--型号1类型");}
}
public class ProductB2 implements AbstractProductB{//具体产品B--2@Overridepublic void printB() {System.out.println("产品B类--型号2类型");}
}
public class Main {//测试类public static void main(String[] args) {System.out.println("工厂1生成对应1号类型的产品族");AbstractFactory factory1=new ConcreteProduct1();factory1.createProductA().printA();factory1.createProductB().printB();System.out.println("工厂2生成对应的2号类型的产品族");AbstractFactory factory2=new ConcreteProduct2();factory2.createProductA().printA();factory2.createProductB().printB();}
}
(4)总结
优点:
- 客户端不需要知道产品如何创建,如果需要切换产品,更换一个具体工厂即可;
- 增加新的产品族十分方便,无需修改原系统,符合开闭原则;
缺点:
- 添加一个产品等级结构系列时,需要从修改原有系统中的所有工厂方法,不符合开闭原则;
使用场景:
- 一个系统不依赖对象的创建,组合,客户端无需知道对象如何创建;
- 系统中有多个产品族,每次只使用一个产品族;
- 同一个产品族中的产品将在一起使用,同一个产品族的产品可以没有任何关系,但必须是有一总共同约束;
4、装饰器模式
(1)概述
- 装饰模式可以在不改变原有对象的模式下,增加额外行为;
- 可以动态给对象增加一些职责;
(2)角色
- Component(抽象组件):他是具体组件和装饰组件的父类,声明了具体组件实现的业务方法,为客户端提供以一致方式处理装饰前以及装饰后的组件;
- ConcreteComponent(具体组件):Component的子类,用于定义具体的组件方法,装饰器类可以给他增加额外职责;
- Decorator(抽象装饰类):Component子类,用于给具体组件添加新的职责,他维护一个指向抽象组件的应用,通过该应用可以调用装饰之前的组件,并通过起子类扩展职责;
- ConcreteDecorator(具体装饰类):抽象装饰类的子类,负责向具体组件添加新的职责;
(3)实现
public interface Component {//抽象组件public void operation();
}
public class ConcreteComponent implements Component{//具体组件@Overridepublic void operation() {System.out.println("组件操作");}
}
public class Decorator implements Component{//抽象装饰器private Component component;public Decorator(Component component){this.component=component;}@Overridepublic void operation() {component.operation();}
}
public class ConcreteDecoratorA extends Decorator{//具体装饰类public ConcreteDecoratorA(Component component) {super(component);}@Overridepublic void operation() {super.operation();addState();}public void addState(){System.out.println("添加机器状态");}
}
public class ConcreteDecoratorB extends Decorator {//具体装饰类public ConcreteDecoratorB(Component component) {super(component);}@Overridepublic void operation() {super.operation();addMoney();}public void addMoney(){System.out.println("加钱,买更多机器投入操作");}
}
public class Main {//main方法public static void main(String[] args) {Component component=new ConcreteComponent();System.out.println("装饰器A-----------");Decorator decorator=new ConcreteDecoratorA(component);decorator.operation();System.out.println("装饰器B---------------");decorator=new ConcreteDecoratorB(component);decorator.operation();}
}
(4)总结
优点:
- 装饰器比继承更加灵活,不会导致类个数急剧增加;
- 可以动态的扩展一个对象功能,通过配置类可以在运行时选择不同的配置类,从而实现不同行为;
- 可以对一个对象装饰多次,采用不同1装饰类可以组装出多个不同的行为;
- 具体的组件类和装饰类可以独立添加,可以根据需要添加新的构建类和组件类,符合开闭原则;
缺点:
- 会产生大量的小对象,这些小对象随着不断累积,会消耗大量内存;
- 对于排错,需要多级查找;
使用场景:
- 在不影响其他对象的情况下,动态,透明的给一个对象添加职责;
- 系统中存在大量独立的类,不可以使用装饰器模式,否则会产生大量的子类;
5、建造者模式
(1)概述
- 将一个复杂对象的构建与他的表示分离,使得同样构建过程可以创建不同的表示;
- 不同的具体建造者定义不同的创建过程,且具体的建造者相互独立,增加新的建造者非常方便;
(2)角色
- Builder(抽象建造者):他为建造复杂对象的各个部件定义接口,在接口中声明方法中,一类是buildProductX方法,用于构建各个组件,另外一类为getProduct()方法,用于获取构建后的对象;既可以是接口,也可以是抽象类;
- Concretebuilder(具体建造者):实现Builder接口,实现各个构造组件的方法,并实现返回一个对象的方法;
- Product(产品):具体的构建对象,包含多个组件,由ConcreteBuilder装配;
- Director(指挥者):定义一个construct()方法,复杂组件装配的顺序,返回构造好的对象,一般该类与客户端进行交互;内部维护一个Builder类;
- 复杂对象:包含多个属性的对象;
(3)实现
@Data
public class Product {//产品类private String A;private String B;
}
public abstract class Builder {//建造者抽象类protected Product product=new Product();public abstract void buildPathA(String value);public abstract void buildPathB(String value);public Product getProduct(){return this.product;}
}
public class ConcreteBuilder extends Builder{//具体建造类@Overridepublic void buildPathA(String value) {product.setA(value);}@Overridepublic void buildPathB(String value) {product.setB(value);}
}
public class Director {//指挥者类private Builder builder;public Director(Builder builder){this.builder=builder;}public Product construct(String A,String B){builder.buildPathA(A);builder.buildPathB(B);return builder.getProduct();}
}
public class Main {public static void main(String[] args) {Builder builder=new ConcreteBuilder();Product product=new Director(builder).construct("属性A","属性B");System.out.println(product.getA());System.out.println(product.getB());}
}
(4)总结
优点:
- 在建造者模式中,客户端不必直到内部如何构建,将产品本身与产品构建之间解耦,使得相同的构建过程可以构建不同的产品;
- 每一个构建者相对独立,客户端可以很方便的添加新的构造者,同时增加新的构造者,不用修改原有的代码符合开闭原则;
缺点:
- 产品之间相差过大,各个组成部分由较大差异,不适合使用该模式;
- 产品的组件变化复杂,需要定义过多的构造类来实现这种变化,导致系统过于庞大;
使用场景:
- 需要生成复杂对象,这些对象通常包含多个属性;
- 对象之间的属性相互依赖,且由一定的顺序性;
- 隔离复杂对象的创建和使用,使得相同的创建过程可以构建出不同的对象;
6、组合模式
(1)概述
- 组合多个对象成为树形结构,对于叶子对象和容器对象的操作都具有一致性;
- 当调用容器对象的某一个方法时,将会遍历整个树,寻找包含这个方法的成员变量,使用递归对整个树结构进行调用;
- 叶子对象:没有字节点;
- 容器对象:包含多个叶子对象和多个容器对象;
(2)角色
- Component(抽象构件):为叶子构件和容器构件声明了接口,定义了其子类共有的行为方法;
- Leaf(叶子构件):实现了Component接口中的行为方法,没有子节点;
- Composite(容器构件):该节点有子节点,子节点可以是容器节点,也可以是叶子节点。有一个列表属性,用于存储子节点,实现了Component接口定义的行为方法,该方法可以递归调用子节点的业务方法;同时包含管理子构建的方法;
(3)实现
public abstract class Component {//抽象组件public abstract void add(Component component);//添加构建public abstract void remove(Component component);//删除构建public abstract List<Component> getChild();//获取子类public abstract void print();//输出文件
}
public class OssLeaf extends Component{//叶子组件private String name;public OssLeaf(String name){this.name=name;}@Overridepublic void add(Component component) {System.out.println("异常处理");}@Overridepublic void remove(Component component) {System.out.println("异常处理");}@Overridepublic List<Component> getChild() {return null;}@Overridepublic void print() {System.out.println("输出"+name+"文件");}
}
public class TxtLeaf extends Component{//叶子组件private String name;public TxtLeaf(String name){this.name=name;}@Overridepublic void add(Component component) {System.out.println("异常处理");}@Overridepublic void remove(Component component) {System.out.println("异常处理");}@Overridepublic List<Component> getChild() {return null;}@Overridepublic void print() {System.out.println("输出"+name+"文件类型");}
}
public class Composite extends Component{//容器组件//记录该组件的子组件(叶子组件、容器组件)private List<Component> componentList=new ArrayList<>();private String name;public Composite(String name){this.name=name;}@Overridepublic void add(Component component) {componentList.add(component);}@Overridepublic void remove(Component component) {componentList.remove(component);}@Overridepublic List<Component> getChild() {return componentList;}@Overridepublic void print() {System.out.println("输出"+name+"类型的文件,输出如下:");//调用子类的方法for (Component component : componentList) {component.print();}}
}
public class Main {//测试方法public static void main(String[] args) {OssLeaf ossLeaf1=new OssLeaf("图片");OssLeaf ossLeaf2=new OssLeaf("视频");TxtLeaf txtLeaf=new TxtLeaf("txt");TxtLeaf txtLeaf1=new TxtLeaf("docx");TxtLeaf txtLeaf2=new TxtLeaf("pptx");Composite composite1=new Composite("oss类型文件");composite1.add(ossLeaf1);composite1.add(ossLeaf2);composite1.print();Composite composite2=new Composite("文本类型文件");composite2.add(txtLeaf);composite2.add(txtLeaf1);composite2.add(txtLeaf2);composite2.print();}
}
(4)总结
优点:
- 在新增新的叶子组件或容器组件时,无需修改原有代码,符合开闭原则;
- 忽略客户端层次差异,方便对整个层次进行控制;
缺点:新增新的组件时,难以对组件的类型进行控制;
使用场景:
- 需要处理一个树型结构;
- 系统中可以分离出叶子组件和容器组件,类型不固定,需要增加一些新的类型;
- 整体和部分具有层次结构,需要处理忽略他们的层次差,使用客户端一致调用这些业务方法;
7、观察者模式
(1)概述
- 定义一种一堆多的关系,使得每当一个对象发生改变时,会通知其关联对象并自动更新;
- 发生改变的对象为观察目标,而被通知的对象为观察者,这些观察者之间没有任何联系;
(2)角色
- Subject(目标):被观察的对象,在目标中定义了一个观察者对象集合,提供删除,添加观察者的方法,同时定义了通知方法notify,可以是接口,抽象类或具体类;
- ConcreteSubject(具体目标):Subject的子类,他包含发生改变的数据,当该数据发生改变时,会通知集合中的观察者,同时还实现目标类中的抽象业务方法;(无需扩展目标类,该类可以省略)
- Observer(抽象观察者):观察者对改变做出响应,一般为接口,声明update方法;
- ConcreteObserver(具体观察者):实现抽象观察者中的update方法,同时维护一个ConcreteSubject对象的应用,存储具体观察者有关状态,该状态需要与目标对象状态一致;
(3)实现
public abstract class Subject {//抽象目标public List<Observer> observerList=new ArrayList<>();//观察者集合public void add(Observer observer){//添加观察者observerList.add(observer);}public void delete(Observer observer){//删除观察者observerList.remove(observer);}public abstract void notifyObserver(String name);}
public class ConcreteSubject extends Subject{//具体目标类@Overridepublic void notifyObserver(String name) {//通知每一个观察者处理errorfor (Observer observer : observerList) {if (!((ConcreteObserver) observer).getName().equals(name)){observer.dealError();}}}
}
public interface Observer {//抽象观察者public void dealError();//在发生error时触发public void error(Subject subject);
}
public class ConcreteObserver implements Observer{//具体观察者private String name;public ConcreteObserver(String name){this.name=name;}public String getName(){return this.name;}//处理错误@Overridepublic void dealError() {System.out.println(name+"来处理error了");}//发生错误@Overridepublic void error(Subject subject) {System.out.println(name+"发生error,都来处理error");subject.notifyObserver(name);}
}
public class Main {public static void main(String[] args) {Subject subject=new ConcreteSubject();Observer observer1=new ConcreteObserver("A");Observer observer2=new ConcreteObserver("B");Observer observer3=new ConcreteObserver("C");subject.add(observer1);subject.add(observer2);subject.add(observer3);observer1.error(subject);}
}
(4)总结
优点:
- 观察者适合广播通信,目标对象发生改变时,会通知所有订阅目标的观察者;
- 添加具体观察者,无需修改原有代码,每一个观察者之间无任何联系,符合开闭原则;
缺点:
- 目标类如果有过多的观察者,通知时会耗费大量时间;
- 观察者和目标之间存在循环依赖,通知时,会导致死循环;
- 观察者无法直到观察对象是如何变化的,只能直到该对象发生了变化;
使用场景:
- 一个对象发生改变会影响多个对象,而这些对象之间相互无任何联系;
- 链式触发,如A影响B,B影响C,。。。;
8、责任链模式
(1)概述
避免请求发送者和接收者耦合在一起,让多个对象都可以接收请求,将这些对象合成一条链,并且沿着这条链传递请求,直到有对象处理该请求为止;
(2)角色
- Handler(抽象处理者):定义了一个处理请求的接口,不同的处理者对每一个请求的处理方式不同,因此定义抽象处理者。每一个处理者的下一个还是处理者,在抽象类中定义一个处理者对象,用于对下一个处理者的调用;
- ConcreteHandler(具体处理者):抽象处理者的实现类,实现具体的请求处理方法,处理请求之前需要先判断是否有权限处理,有则处理,否则将请求转发给下一个处理者;
(3)实现
@Data
public abstract class Handler {protected Handler handler;//下一个处理者protected String name;//姓名public Handler(String name){this.name=name;}//处理请求逻辑方法public abstract void processorHandler(int money);
}
public class ConcreteHandlerA extends Handler{public ConcreteHandlerA(String name){super(name);}@Override//可以审批5000元以下public void processorHandler(int money) {if (money<=5000){System.out.println(name+"进行审批,审批通过");}else {System.out.println(name+"无法审批金额,流转下一个审批者");handler.processorHandler(money);}}
}
public class ConcreteHandlerB extends Handler{public ConcreteHandlerB(String name){super(name);}@Override//可以审批5000-20000public void processorHandler(int money) {if (money>5000&&money<=20000){System.out.println(name+"进行审批,审批通过");}else {System.out.println(name+"无法审批金额,流转下一个审批者");handler.processorHandler(money);}}
}
public class ConcreteHandlerC extends Handler{public ConcreteHandlerC(String name){super(name);}@Override//可以审批20000以上public void processorHandler(int money) {if (money>20000){System.out.println(name+"进行审批,审批通过");}else {System.out.println(name+"无法审批金额,流转下一个审批者");handler.processorHandler(money);}}
}
public class Main {public static void main(String[] args) {Handler handlerA=new ConcreteHandlerA("主管");Handler handlerB=new ConcreteHandlerB("经理");Handler handlerC=new ConcreteHandlerC("董事长");//设置下一个处理者handlerA.setHandler(handlerB);handlerB.setHandler(handlerC);handlerA.processorHandler(30000);}
}
(4)总结
优点:
- 发送者和接收者都没有对方的信息,只知道请求会被处理,降低系统耦合度;
- 职责链的处理更加灵活,可以动态增加和删除处理者,来改变处理一个请求的职责;
- 增加一个新的请求者无需修改原有代码,只需添加新连接即可,符合开闭原则;
缺点:
- 请求没有明确接收者,可能导致请求走完职责链也并未被处理;
- 请求处理需要多个对象进行处理,系统性能将受一定的影响;
- 创建的连接不当,可能会造成系统死循环;
使用场景:
- 多个对象处理一个请求,请求需要等到运行时才能确定哪一个处理者处理;
- 不明确处理者对象,向多个对象提交一个请求;
- 指定一组对象进行处理,客户端可以动态添加处理对象,并且可以改变顺序;
相关文章:

设计模式(一)
1、适配器模式 (1)概述 适配器中有一个适配器包装类Adapter,其包装的对象为适配者Adaptee,适配器作用就是将客户端请求转化为调用适配者中的接口;当调用适配器中的方法时,适配器内部会调用适配者类的方法…...

Prometheus关于微服务的监控
在微服务架构下随着服务越来越多,定位问题也变得越来越复杂,因此监控服务的运行状态以及针对异常状态及时的发出告警也成为微服务治理不可或缺的一环。服务的监控主要有日志监控、调用链路监控、指标监控等几种类型方式,其中指标监控在整个微服务监控中比重最高,也是实际生…...

CSS实现白天/夜晚模式切换
目录 功能介绍 示例 原理 代码 优化 总结 功能介绍 在网页设计和用户体验中,模式切换功能是一种常见的需求。模式切换可以为用户提供不同的界面外观和布局方案,以适应其个人偏好或特定环境。在这篇博客中,我们将探索如何使用纯CSS实现一…...

selenium实现输入数字字母验证码
思路 1. 登录url 2. 获取验证码坐标 3. 根据桌标截图验证码 4. 对验证码进行识别 5. 自动输入验证码 测试代码 import os import time from io import BytesIO from PIL import Image from selenium import webdriver from selenium.webdriver.common.by import By impo…...

Docker的运用
文章目录 一、 Docker介绍二、Docker常用命令三、Docker 部署微服务项目四、Docker 使用场景五、Docker模拟场景5.1 模拟部署Nacos5.2 模拟部署Mongodb5.3 模拟部署RabbitMQ 一、 Docker介绍 Docker是一种开源软件平台,用于在不同的操作系统(如Windows、…...

在项目中快速搭建机器学习的流程
在软件开发领域,机器学习框架发挥着关键作用,为开发人员提供强大的人工智能工具、库和算法,以有效地利用机器学习的潜力。从本质上讲,机器学习使计算机能够从数据中学习并做出预测或决策,而无需明确编程。 机器学习框…...

计网-All
路由器的功能与路由表的查看_路由器路由表_傻傻小猪哈哈的博客-CSDN博客路由基础-直连路由、静态路由与动态路由的概念_MikeVane-bb的博客-CSDN博客路由器的功能与路由表的查看_路由器路由表_傻傻小猪哈哈的博客-CSDN博客 直连路由就是路由器直接连了一个网段,他就…...

Rabbitmq的Federation Exchange
(broker 北京 ) , (broker 深圳 ) 彼此之间相距甚远,网络延迟是一个不得不面对的问题。有一个在北京的业务(Client 北京 ) 需要连接 (broker 北京 ) ,向其中的交换器 exchangeA 发送消息,此时的网络延迟很小,(C…...

AIGC - 生成模型
AIGC - 生成模型 0. 前言1. 生成模型2. 生成模型与判别模型的区别2.1 模型对比2.2 条件生成模型2.3 生成模型的发展2.4 生成模型与人工智能 3. 生成模型示例3.1 简单示例3.2 生成模型框架 4. 表示学习5. 生成模型与概率论6. 生成模型分类小结 0. 前言 生成式人工智能 (Generat…...

如何优雅地创建一个自定义的Spring Boot Starter
优雅永不过时,希望看完本文,你会觉得starter如此优雅! Spring Boot Starter是一种简化Spring Boot应用开发的机制,它可以通过引入一些预定义的依赖和配置,让我们快速地集成某些功能模块,而无需繁琐地编写代…...

Hbase--技术文档--单机docker基础安装(非高可用)
环境准备-docker 配置Linux服务器华为云耀云服务器之docker安装,以及环境变量安装 java (虚拟机一样适用)_docker配置java环境变量_一单成的博客-CSDN博客 说明: 本文章安装方式为学习使用的单体hbase项目。主要是学习ÿ…...

React 生命周期新旧对比
前言 React16.4版本之后使用了新的生命周期,它使用了一些新的生命周期钩子(getDerivedStateFromProps、getSnapshotBeforeUpdate),并且即将废弃老版的3个生命周期钩子(componentWillMount、componentWillReceiveProps…...

云计算存储类型
一、共享存储模式 NAS: ①一种专门用于存储和共享文件的设备,它通过网络连接到计算机或其他设备, 提供了一个中心化的存储解决方案 ②存储网络使用IP网络 ,数据存储共享基于文件 ③本质上为:NFS和CIFS文件共享服务器 ④提供的不是一个磁盘块…...

javacv基础03-调用本机摄像头并截图保存到本地磁盘
基于基础02 的基础上对视频进行取帧保存 代码如下: package com.example.javacvstudy;/*** 本地摄像头截图*/import org.bytedeco.javacv.CanvasFrame; import org.bytedeco.javacv.FrameGrabber; import org.bytedeco.javacv.OpenCVFrameConverter; import org.b…...

Python读取Windows注册表的实战代码
大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…...

macOS 安装 Homebrew 详细过程
文章目录 macOS 安装 Homebrew 详细过程Homebrew 简介Homebrew 安装过程设置环境变量安装 Homebrew安装完成后续设置(重要)设置环境变量homebrew 镜像源设置macOS 安装 Homebrew 详细过程 本文讲解了如何使用中科大源安装 Homebrew 的安装过程,文章里面的所有步骤都是必要的,需…...

数据结构之树型结构
相关概念树的表示二叉树二叉树性质二叉树储存 实现一颗二叉树创建遍历(前中后序)获取树中节点个数获取叶子节点个数获取第k层节点个数获取二叉树高度检测值为value元素是否存在层序遍历(需要队列来实现)判断是否为完全二叉树&…...

指针进阶详解
个人主页:点我进入主页 专栏分类:C语言初阶 C语言程序设计————KTV C语言小游戏 C语言进阶 欢迎大家点赞,评论,收藏。 一起努力,一起奔赴大厂。 目录 1.字符指针 2.指针数组 3.数组指针 4.数组传…...

QGIS 如何添加天地图
相信很多小伙伴在 QGIS 里面添加天地图的时候一定感觉很困惑,按照官网的操作申请 Key 之后,添加相对应的服务地址之后看不到地图或者地图不正常显示,今天我们就来解决这个问题 以下所有操作基于 QGIS 3.22 版本 申请 Key 1. 添加天地图的第一步需要申请 Key,首先要注册天…...

PHP8内置函数中的数学函数-PHP8知识详解
php8中提供了大量的内置函数,以便程序员直接使用常见的内置函数包括数学函数、变量函数、字符串函数、时间和日期函数等。今天介绍内置函数中的数学函数。 本文讲到了数学函数中的随机数函数rand()、舍去法取整函数floor()、向上取整函数 ceil()、对浮点数进行四舍…...

云计算企业私有云平台建设方案PPT
导读:原文《云计算企业私有云平台建设方案PPT》(获取来源见文尾),本文精选其中精华及架构部分,逻辑清晰、内容完整,为快速形成售前方案提供参考。 喜欢文章,您可以点赞评论转发本文,…...

ORA-01174: DB_FILES be compatible RAC rolling fashion complete outage
How to change the DB_FILES parameter in RAC (Doc ID 1636681.1)编辑To Bottom In this Document Goal Solution APPLIES TO: Oracle Database - Enterprise Edition - Version 10.1.0.2 and later Oracle Database Cloud Schema Service - Version N/A and later Oracle…...

线性代数(五) 线性空间
前言 《线性代数(三) 线性方程组&向量空间》我通过解线性方程组的方式去理解线性空间。此章从另一个角度去理解 空间是什么 大家较熟悉的:平面直角坐标系是最常见的二维空间 空间由无穷多个坐标点组成 每个坐标点就是一个向量 反过来,也可说&…...

kafka--技术文档--spring-boot集成基础简单使用
阿丹: 查阅了很多资料了解到,使用了spring-boot中整合的kafka的使用是被封装好的。也就是说这些使用其实和在linux中的使用kafka代码的使用其实没有太大关系。但是逻辑是一样的。这点要注意! 使用spring-boot整合kafka 1、导入依赖 核心配…...

【核磁共振成像】部分傅里叶重建
目录 一、部分傅里叶重建二、部分傅里叶重建算法2.1 填零2.2 零差处理 一、部分傅里叶重建 在部分傅里叶采集中,数据并不是绕K空间中心对称收集的,而是K空间的一半是完全填充的,另一半只收集了一小部分数据。 部分傅里叶采集所依据的原理…...

React中的flushSync与Vue中的nextTick的比较
React中的flushSync与Vue中的nextTick是两种用于处理异步更新的机制。它们在React和Vue这两个流行的前端框架中起着重要的作用。 首先,让我们来看看flushSync。在React中,当需要更新UI时,React会将更新操作放入一个队列中,然后异…...

golang设置国内镜像源
以windows为例, 在cmd 窗口中执行下列语句 go env -w GO111MODULEon go env -w GOPROXYhttps://goproxy.io,direct 或者 1.运行 go env -w GO111MODULEon //开启mod 运行 go env -w GOPROXYhttps://goproxy.cn,direct //设置代理 执…...

linux切换到root没有conda环境
这个错是因为 没有将anaconda添加到环境变量 export PATH"/home/tao/anaconda3/bin:$PATH"然后 source ~/.bashrc或者写入 nano ~/.bashrc在文件的末尾添加以下行 export PATH"/home/tao/anaconda3/bin:$PATH"再 source ~/.bashrc就可以了...

数据库——redis介绍
文章目录 redis是什么?分布式缓存常见的技术选型方案有哪些?说一下 Redis 和 Memcached 的区别和共同点? redis是什么? 简单来说 Redis 就是一个使用 C 语言开发的数据库,不过与传统数据库不同的是 Redis 的数据是存在…...

从C语言到C++_34(C++11_下)可变参数+ lambda+function+bind+笔试题
目录 1. 可变参数模板 1.1 展开参数包 1.1.1 递归函数方式展开 1.1.2 逗号表达式展开 1.2 emplace相关接口 2. lambda表达式(匿名函数) 2.1 C11之前函数的缺陷 2.2 lambda表达式语法 2.3 函数对象与lambda表达式 3. 包装器 3.1 function包装器…...