TYUT设计模式精华版
七大原则
-
单一职责原则 职责要单一不能将太多的职责放在一个类中
-
开闭原则 软件实体对扩展是开放的,但对修改是关闭的
-
里氏代换原则 一个可以接受基类对象的地方必然可以接受子类
-
依赖倒转原则 要针对抽象层编程,而不要针对具体类编程
-
接口隔离原则 使用多个专门的接口来取代一个统一的接口
-
合成复用原则 复用功能时,优先使用组合和聚合关联关系,尽量不要使用继承
-
迪米特法则 一个软件实体对其他软件实体的应用越少越好,或者两个类不必彼此直接通信,就不应当发生直接的相互作用,而是通过引入一个第三者发生间接交互。
设计模式
定义:设计模式是一套被反复使用被多数人知晓的经过分类编目的,代码设计经验的总结。
基本要素:模式名称,问题,目的,解决方案,效果实例代码,和相关设计模式。
创建型模式
工厂模式
简单工厂模式
定义:定义了一个类,用这个类来封装实例化对象的类
问题:类的创建依赖工厂类,如果想要扩展新的类,就必需对工厂类进行修改
解决方法:增加新的功能,去增加新的工厂类就可以,使用工厂方法模式
工厂方法模式
定义了一个创建对象的抽象方法,由子类决定要实例化的类。工厂方法模式将对象的实例化推迟到子类。
解决了工厂模式问题,如果想要,只需要再增加一个实现类,就行。
问题:如果我要A产品,只能去找到生成A产品的工厂才能去得到,无法达到用户说出那个产品的需求,工厂自会安排的效果
解决方法:
把工厂类抽象为接口,根据用户的需求,即对应的产品,去找到对应的参数,这就是简单工厂模式
抽象工厂模式
角色:
AbstractFactory 抽象工厂
WindowsFactory 等具体工厂
Text,Button 抽象产品
WindowsText等具体产品
如果代码需要与多个不同系列的相关产品交互, 但是由于无法提前获取相关信息, 或者出于对未来扩展性的考虑, 你不希望代码基于产品的具体类进行构建, 在这种情况下, 你可以使用抽象工厂。
抽象工厂为你提供了一个接口, 可用于创建每个系列产品的对象。 只要代码通过该接口创建对象, 那么你就不会生成与应用程序已生成的产品类型不一致的产品。
如果你有一个基于一组抽象方法的类, 且其主要功能因此变得不明确, 那么在这种情况下可以考虑使用抽象工厂模式。
在设计良好的程序中, 每个类仅负责一件事。 如果一个类与多种类型产品交互, 就可以考虑将工厂方法抽取到独立的工厂类或具备完整功能的抽象工厂类中。
建造者模式
定义:该模式允许将复杂的对象构建步骤与表示方式相分离,通过指定复杂对象的类型和内容就可以构建他们
角色:
抽象建造者类 Builder
public abstract class ComputerBuilder {
protected Computer computer=new Computer();public abstract void buildType();public abstract void buildRam();
public abstract void buildHdd();
public abstract void buildCpu();
public abstract Computer getComputer(); }
具体建造者类 ConcreteBuilder
public class ConcreteBuilder extends ComputerBuilder{
@Override
public void buildType(){computer.setType("Desktop");}
@Override
public void buildRam() {computer.setRam("16GB");}@Override
public void buildHdd() {computer.setHdd("2TB");}@Overridepublic void buildCpu() {computer.setCpu("Desktop cpu 11th gen");
} @Override
public Computer getComputer() {return computer;} }
产品角色 Product
public class Computer {
private String type;
private String ram;
private String hdd;
private String cpu;
public String getType() { return type; }
public String getRam() { return ram; }
public String getHdd() { return hdd; }
public String getCpu() { return cpu; }
public void setType(String type) { this.type = type; }
public void setRam(String ram) { this.ram = ram; }
public void setHdd(String hdd) { this.hdd = hdd; }
public void setCpu(String cpu) { this.cpu = cpu; } }
指挥者类 Director
public class ComputerAssembleDirector {private ComputerBuilder computerBuilder;public ComputerAssembleDirector(ComputerBuilder computerBuilder) {this.computerBuilder = computerBuilder;}public Computer assemble(){computerBuilder.buildType();computerBuilder.buildRam();computerBuilder.buildHdd();computerBuilder.buildCpu();return computerBuilder.getComputer();}
}
类图:
优点:
-
客户端不必知道产品内部细节,本身与本身创建过程解耦, 相同的创建过程创建不同的产品对象。
-
具体建造者互相独立,与其他建造者无关,使用不同的建造者得到不同的对象
-
符合开闭原则
-
精细的控制产品的创建过程
缺点:
该模式所创建的产品一般具有较多的共同点,产品之间如果差异性很大则,不适合使用该模式。
原型模式
定义:原型模式用原型实例创建对象的种类,并且通过复制这些原型创建新的对象。
工作原理:将一个对象通过请求原型对象传给那个要发动创建的对象,该对象通过请求原型对象复制原型来创建的过程。
角色:
抽象原型类
具体原型类
浅克隆
浅克隆中,被复制对象的所有普通成员变量都具有与原来对象相同的值,而所有对象对其他对象的引用仍然指向原来的对象,也就是只考虑当前对象,不考虑成员对象,浅克隆时要使用Object的Clone接口
这就是浅克隆的核心
public class Many implements Cloneable{public Object clone() {try {return super.clone();} catch (CloneNotSupportedException e) {throw null;}}
}
深克隆
深克隆顾名思义,这两个对象是完全不同的对象,对其他对象的引用也会改变
深克隆 不会用Clone()接口,而是使用序列化传输,进行流的转换。
public class Many implements Serializable {public Object deppClone() throws IOException, ClassNotFoundException {//对象写入流中ByteArrayOutputStream outputStream = new ByteArrayOutputStream();ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);objectOutputStream.writeObject(this);// 对象从流中取出ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray());ObjectInputStream objectInputStream = new ObjectInputStream(inputStream);return objectInputStream.readObject();}
}
优点 :
-
对象比较复杂时,该模式简化对象的创建过程,提高效率
-
动态增加和减少产品类
-
简化的创建结构,无需用专门的工厂类去创建
-
深克隆的对象保持对象当前的状态,以便需要的时候使用
缺点:
-
需要为每个类配备一个克隆方法,没有创建的类简单,但是对于已经创建的类去改造比较麻烦,所以违反了开闭原则
单例模式
定义:确保一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,提供全局访问的方法。
要点:
-
一个类只有一个实例
-
必须自行创建这个实例
-
必须自行向整个系统提供这个实例
饿汉式单例
public class Many {private static final Many many=new Many();private Many(){}public static Many getInstance(){return many;}
}
懒汉式单例
同步化机制,处理多线程环境
public class Many {private static Many instance=null;private Many(){};synchronized public static Many getInstance(){return (instance==null)?instance=new Many():instance;}双重检查 synchronized+instance==null 确保只有一个单例生成
}
结构型模式
适配器模式
定义:将一个类的接口转换成用户希望的另一个接口,原本不兼容的类可以一起工作,无需修改现有事物的内部。
角色:
Target 目标抽象类 抽象类或接口,具体类
Adapter 适配器类 适配类可以调用另一个接口,对Adapter 和Target进行适配,是适配器的核心。类适配器中实现Target接口并继承Adaptee达到效果。 java只能单一继承,对象适配器中 继承Target并关联Adapptee达到效果
Adaptee(适配者类) 被适配的角色,定义了一个已经存在的接口,并且需要适配。
类适配器
对象适配器
对象适配器与类适配器类主要的区别就是adapter的区别
public class Adapter implements Target {private Adaptee adaptee;@Overridepublic void request() {adaptee.specificRequest();}
}
优点:
-
将目标类和适配器类解耦,引入适配器类,而不用去修改原有代码
-
增加了类的透明性和复用性,具体实现封装在适配器类,对客户端透明,且提高了复用性
-
灵活性和扩展性都非常好,符合开闭原则
缺点:
桥接模式
定义:抽象部分与他的实现部分分离,使他们都可以独立的变化。
桥接模式存在一条连接两个继承等级的桥
角色:
-
Abstraction (抽象类)
-
RefinedAbstraction(扩充抽象类)
-
Implementor(实现类接口)
-
ConcreteImplementor(具体实现类)
优点:
-
分离抽象化及其实现
-
是比多继承方案更好的方案
-
提高了系统的可扩展性
-
实现细节对客户透明,可以对用户隐藏实现细节,用户在使用时不需要关心实现,在抽象层通过聚合关联关系完成封装和对象的封装。
缺点:
-
桥接模式的引入会增加系统的理解和设计难度,由于聚合
关联关系是建立在抽象层,需要针对抽象进行设计
-
需要正确识别出系统中两个独立变化的维度,因此其使用范围有一定的局限性。
组合模式
定义:
组合多个对象形成树形结构以表示部分-整体的结构层次,组合模式分为单个对象(叶子对象)和组合对象(即容器对象)
核心:
引入一个抽象类,他即是叶子对象的父类,也是容器对象的父类
类图:
角色:
Component(抽象构件) 接口/抽象类 定义所有子类的共有行为的申明和实现
Leaf叶子节点,表示叶子节点对象,叶子节点没有子节点,只是实现抽象构件中的部分行为
Composite(容器构件) 表示容器节点对象,包含子节点,其子节点可以是叶子节点也可是容器节点,提供一个集合去存放子节点,实现了在抽象构件中定义的行为,访问和管理子构件的行为
就像文件夹中可以存放文件夹也可以存放文件。
安全组合模式,透明组合模式
安全组合模式
由此就可以看出组合模式的具体实现,可以观察到这部分实现容器构件的一些特殊的方法,在抽象构件,叶子节点中都没有出现,因为这些方法在他们这里出现也没有意义没有任何东西,反而是不够安全的,运行阶段调用这些方法反而是空的,所以上个类图展现的模式是不安全的,叫透明组合模式,改进后的叫安全组合模式。
透明组合模式类图
安全组合模式类图
优点:
-
可以清楚的定义分层次的复杂对象,表示全部或部分层次
-
客户端调用时不必关心自己处理的是单个对象或者组合结构
-
叶子对象可以被组合成更复杂的结构,容器对象也可以被组合,可以形成更加复杂的树形结构
缺点:
-
设计变得抽象,对象的业务规则如果复杂挑战性比较da
-
增加新构件有可能会出现一些问题,很难对容器中的构件类型进行限制。
装饰模式
定义:
动态地给一个对象增加一些额外的职责,就增加对象来说,装饰模式比生成子类更为灵活
类图:
角色:
Commponent(抽象构件) 定义对象的接口,可以给这些对象动态的增加职责,抽象装饰类和具体构件的共同父类,一致处理未被装饰的对象和装饰之后的对象
public abstract class Commponent { abstract void operation(); }
ConcreteComonent(具体构件) 具体构件实现了抽象构件中申明的方法,装饰器可以动态的添加功能
public class ConncreteCommpent extends Commponent{
@Override void operation() { System.out.println("operation"); } }
Decorator(抽象装饰类) 用于添加职责,具体职责在子类中实现。
public class Decorator {private Commponent commponent;
public Decorator(Commponent commponent) { this.commponent = commponent; }
public void operation(){ commponent.operation(); } }
ConcereDecorator(具体装饰类) 具体添加职责的类
public class ConncreteDecorator extends Decorator{
public ConncreteDecorator(Commponent commponent) { super(commponent); }@Override public void operation() { super.operation(); addBehavior(); // 增加功能 }public void addBehavior(){ System.out.println("addBehavior"); } }
优点:
-
该模式与继承都是扩展对象的功能,不过该模式更加灵活
-
动态方式扩展对象的功能
-
具体装饰类与被装饰类之间的排列组合创造出不同的装饰器
-
具体构件类与具体装饰类可以独立变化,使用时再进行组合,符合开闭原则
缺点:
透明装饰模式
透明装饰模式就是你的定义了一个具体构件你可去放入任何的装饰器,而不是一对一的关系,是一对多
半透明装饰模式
半透明装饰模式与透明装饰模式相反,我这个具体构件只能由这一类的装饰器来执行,其他装饰器不可以。
外观模式
引入一个外观角色来简化客户端与子系统之间的操作,为复杂的子系统调用提供一个统一的接口,使子系统与客户端的耦合度降低。
划分若干子系统,降低系统复杂性,体现单一职责原则
引入外观类,降低系统复杂度,降低客户端与系统的耦合度,体现迪米特原则
类图:
角色:
Facade外观角色
在外观角色中可以知道相关子系统的功能和责任,在正常情况下他会接受上面发来的请求去转发给子系统来处理。
SubSystem子系统角色
-
每个子系统可以是单独的类或者类的集合,实现子系统的功能
-
每个子系统都可以被直接调用,处理由外观类的请求
上述描述的缺点中提到了如果要增加新的子系统,需要修改外观类,违背了开闭原则,所以再加一层抽象外观类就解决了。
享元模式
当系统中存在大量的相同或者相似对象,该模式通过共享技术实现相同或者相似细粒度的对象复用,节约了内存空间。提供享元池存储已经创造好的对象,并且通过享元工厂类提供享元对象
定义:运用共享技术有效支持大量细粒度对象的复用,要求能够共享的对象必须是细粒度对象,所以又称轻量级模式
享元模式一般结合工厂类模式使用
类图:
角色:
具体享元类 ConcreteFlyweight
抽象享元类 Flyweight
非共享具体享元类 UnsharedConcreteFlyWeight
享元工厂类 FlyweightFactory
代理模式
定义:给摸一个对象提供一个代理,并由代理对象控制原对象的引用
类图:
角色:
抽象主题角色 Subject
声明了真实主题和代理主题得共同接口,任何使用真实主题得场景都可以使用代理主题,客户端需要针对抽象主题进行编程
public abstract class Subject { public abstract void request(); }
Proxy代理主题角色
其内部包含了对真实主题得引用,可以在任何时候操作真实主题对象,在代理主题角色中提供了一个与真实主题相同得接口,以便在任何时候去替代真实主题角色。
public class Proxy extends Subject{
private RealSubject realSubject=new RealSubject();
public void before(){ System.out.println("Ready to send"); }
@Override public void request() { before(); realSubject.request(); after(); }
public void after(){ System.out.println("send success"); } }
RealSubject 真实主题角色
定义了代理角色所代表得真实对象,再该对象中体现了真实得业务操作,客户端也可以通过代理主题角色去调用真实主题角色得方法
public class RealSubject extends Subject{@Override
public void request() { System.out.println("send RealSubject"); } }
静态代理
刚才类图中展示得代码就是静态代理,就是在编译之前已经决定好的。
是由程序员创建或特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class 文件就已经存在了。它需要为每个被代理的类都创建一个代理类,代理类和被代理类实现相同的接口或者继承相同的抽象类。
动态代理
由于使用静态代理模式去解决这类问题,真实主题对象事先已经存在,作为其内部得属性,这样有可能会导致其类得数量增加,所以出现了动态代理模式。
是在程序运行时,运用反射机制动态地创建代理对象。代理类并不是在代码编译阶段就确定好的,而是在运行时根据需要动态生成字节码并加载到 JVM 中。
public interface Star { void sing(); void dance(); }
public class BigStar implements Star {
具体对象 public void sing(){ System.out.println("sing"); }
public void dance(){ System.out.println("dance"); } }
动态代理类
public class ProxyUtil {public static Star getStar(BigStar bigStar){Star star = (Star) Proxy.newProxyInstance(ProxyUtil.class.getClassLoader(),new Class[]{Star.class},new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {if(method.getName().equals("sing")){System.out.println("before sing");method.invoke(bigStar,args);System.out.println("after sing");}else{System.out.println("before dance");method.invoke(bigStar,args);System.out.println("after dance");}return null;}});return star;}
}
优点:
缺点:
-
增加了代理对象,有些类型得代理模式会导致请求速度变慢
-
代理模式有得实现非常复杂
行为型模式
命令模式
定义:将一个请求封装成一个对象,从而使我们可用不同的请求对客户进行参数化,他将请求发送者与请求接受者解耦,请求发送者通过命令对象来间接引用接收者,可以在不修改源码的情况下将相同的发送者对应不同的接收者,也可以将多个命令组成一个宏命令(执行多个命令),还可以在命令类中提供用来撤销申请的方法
类图:
角色:
Command 抽象命令类
接口或者抽象类,声明执行请求的方法,(调用请求接收者的相关操作)
public abstract class Command {
abstract void execute();}
ConcreteCommand 具体命令类
实现了抽象命令的方法,绑定接收者对象的动作
public class ConcreteCommand extends Command{
private Reciver reciver=new Reciver();@Override void execute()
{ reciver.action(); } }
Invoker 调用者
请求的发送者,命令对象来执行请求
public class invoker {private Command command;
public invoker(Command command){ this.command = command; }
public void setCommand(Command command) { this.command = command; }
public void action(){ command.execute(); } }
Receiver 接收者
接收请求,执行动作
public class Reciver { public void action(){ System.out.println("command received!"); } }
优点:
-
降低系统耦合度,使请求者与接收者之间不存在之间引用,不需要交互,两者之间是多对多的关系。
-
新的命令可以很容易加入到系统中,即增加新的具体命令类,满足开闭原则
缺点:
使用命令模式可能会导致系统中存在过多的命令类,可以设置一个宏命令来解决
宏命令模式与命令模式普通版的区别在于新增了一个特殊的类
public class MarcoCommand extends Command{
private List<Command> commands = new ArrayList<>();
public void add(Command command){ commands.add(command); }
@Override void execute() { commands.forEach(Command::execute); } }
迭代器模式
对聚合对象进行遍历,引入迭代器可以将数据的遍历功能从聚合对象分离出来,聚合对象只负责存储数据,遍历数据需要迭代器完成,符合单一职责要求、
定义:提供一种方法来访问聚合对象,不用保留对象的内部表示
角色:
Itearor 抽象迭代器
定义了访问和遍历元素的接口
public interface TVIterator {
void next();
void previous();boolean isFirst();
boolean isLast();
void setChannel(int i);Object currentChannel(); }
ConcreteItearor 具体迭代器
实现了抽象迭代器的接口,完成聚合对象的遍历,并且跟踪其当前位置
public class ConcreteCommand extends Command{private Reciver reciver=new Reciver();@Overridevoid execute() {reciver.action();}
}
Aggregate 抽象聚合类
存储对象,并创建相应迭代器的接口,创建一个迭代器的对象的方法
public interface TV { TVIterator createIterator(); }
ConcreteAggregate 具体聚合类
实现了相应迭代器的接口,实现了聚合类中的创建迭代器的方法
public class HomeTv implements TV{
Object[] objects={"sumsung","xiaomi","huawei"};@Overridepublic TVIterator createIterator() { return new TVIteratorImpl(objects); } }
优点:
支持以不同的方式遍历聚合对象
简化聚合类,在原有的对象中不需要在自行遍历的方法
在同一个聚合上可以有多个遍历
增加新的聚合类和迭代器类都很方便,满足开闭原则
缺点:
观察者模式
一个对象的改变可能会导致一个或多个其他与之存在依赖关系的对象。
定义:
定义对象一对多依赖关系,每当一个对象状态发生更新时,其相关依赖对象都得到通知,并自动更新
别名:
发布订阅模式,模型视图模式,源监听器模式,从属者模式
类图:
角色:
Subject 目标
public abstract class Subject {
protected List<Observer> list=new ArrayList<>();
public abstract void attach(Observer observer);public abstract void detach(Observer observer);
public abstract void notify1(Observer observer); }
c 具体目标
public class ConcreteSubject extends Subject{@Override
public void attach(Observer observer)
{ list.add(observer); }@Overridepublic void detach(Observer observer){ list.remove(observer); }@Override
public void notify1()
{ list.forEach(Observer::update); } }
Observer观察者
public interface Observer { public void update(); }
ConcreteObserver 具体观察者
public class ConcreteObserver implements Observer{
@Override
public void update() { System.out.println("收到通知"); } }
优点:
实现表示层和数据逻辑层得分离,并定义稳定的消息 更新传递机制,抽象了更新接口
观察者模式支持广播通信,观察目标会像所有注册的观察者发送通知,简化了设计难度
符合开闭原则
缺点:
状态模式
解决系统中复杂对象的状态转换以及不同状态下行为的封装问题。当系统中某个对象存在多个状态,这些状态之间可以进行转换,而且对象在不同状态下行为不相同时可以使用状态模式。
状态模式将一个对象的状态从该对象分离出来,使其状态灵活变化
定义:
允许一个对象在其内部状态时,去改变他的行为,对象看起来似乎修改了他的类
类图:
角色:
Context 环境类
public class Context {
private State state;
public Context(State state){/** 实例化状态 */ this.state = state; }
/**切换状态 * */ public void setState(State state) { this.state = state; }public void request() { state.handle(); } }
State 抽象状态类
public abstract class State { public abstract void handle(); }
ConcreteState具体状态类
public class ConcreteStateA extends State{
@Overridepublic void handle() { System.out.println("ConcreteStateA"); } }
简单状态模式和可切换状态的状态模式
两者之间的区别就是状态是否改变,简单状态模式,在实例化的时候就确定了状态,无法更改
可切换的状态,可以调用方法切换状态,不是一成不变的
优点:
封装了转换规则,无需使用过长的语句来判断状态的转换和转移,提高了代码的可维护性
枚举可能状态,在枚举状态之前需要确定状态种类
将所有与某个状态的行为放到一个类中,可以方便新增增加新的状态,只需要改变对象的状态
允许状态逻辑与状态对象合为一体
缺点:
策略模式
策略模式用于算法的自由切换和扩展,解决某一个问题的算法簇,允许用户随意选择一个。
策略模式实现了算法定义和算法使用的分离,通过继承和多态的机制实现对算法族的使用和管理
完成任务时可以有不同的策略,可以选择不同的策略来完成任务
Context (环境类)
public class Context {private Strategy strategy; /**切换策略,或者注入策略 * */
public void setStrategy(Strategy strategy) { this.strategy = strategy; }public void algorithm() { strategy.algorithm(); } }
Stragey 策略类
public abstract class Strategy { abstract void algorithm(); }
具体策略类 ConcreteStragey
public class ConncreteStragetyA extends Strategy{@Override void algorithm() { System.out.println("策略A"); } }
与状态模式的区别
从他们两者的基本类图看出来很相似大差不差,首先我个人理解的一点是状态模式不断切换状态,方法的结果会随之改变,但是你的策略模式无论采用什么策略最后的目的都是一致的,本身两种模式是为了解决不同问题设计的。
相关文章:
TYUT设计模式精华版
七大原则 单一职责原则 职责要单一不能将太多的职责放在一个类中 开闭原则 软件实体对扩展是开放的,但对修改是关闭的 里氏代换原则 一个可以接受基类对象的地方必然可以接受子类 依赖倒转原则 要针对抽象层编程,而不要针对具体类编程 接口隔离原则 …...
责任链模式
07-责任链模式 1 导读 1.1 定义 包含了一些命令对象和一系列处理对象。每个处理对象决定它能处理哪些命令对象,它也知道如何将它不能处理的命令对象传递给该链中的下一个处理对象。 该模式还描述了往该处理链的末尾添加新的处理对象的方法。 精简定义:为…...
2024.11.29(单链表)
思维导图 声明文件 #ifndef __LINKLIST_H__ #define __LINKLIST_H__#include <myhead.h>typedef char datatype; //数据元素类型 //定义节点类型 typedef struct Node {union{int len; //头节点数据域datatype data; //普通节点数据域};struct Node *next; //指针域…...
用Python做数据分析环境搭建及工具使用(Jupyter)
目录 一、Anaconda下载、安装 二、Jupyter 打开 三、Jupyter 常用快捷键 3.1 创建控制台 3.2 命令行模式下的快捷键 3.3 运行模式下快捷键 3.4 代码模式和笔记模式 3.5 编写Python代码 一、Anaconda下载、安装 【最新最全】Anaconda安装python环境_anaconda配置python…...
洛谷P1443 马的遍历
简单的bfs 题目链接 P1443 马的遍历 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 题目描述 有一个 nm 的棋盘,在某个点(x,y) 上有一个马,要求你计算出马到达棋盘上任意一个点最少要走几步。 输入格式 输入只有一行四个整数,分别为 n…...
实现一个Vue自定义指令
在 Vue 中,自定义指令允许你为 DOM 元素添加特定的行为或功能。下面是一个实现 Vue 自定义指令的简单示例,展示了如何创建一个指令,使得元素在鼠标悬停时改变背景色。 1. 创建自定义指令 在 Vue 2.x 中,你可以在 Vue.directive …...
【已解决】git push需要输入用户名和密码问题
解决方法: 1)查看使用的clone方式: git remote -v 2)若为HTTPS,删除原clone方式: git remote rm origin 3)添加新的clone方式: git remote add origin gitgithub.com:zludon/git_test.git …...
什么是内存对齐?为什么需要内存对齐?
1. 什么是内存对齐 内存对齐是指将数据存储在内存中时,按照一定的规则让数据排列在规定的地址上。具体来说,每个成员变量会按照其自身所占用的字节数对齐,内存首地址为对齐周期的倍数,而对齐周期指的是数据类型的大小。例如&…...
数据库操作、锁特性
1. DML、DDL和DQL是数据库操作语言的三种主要类型 1.1 DML(Data Manipulation Language)数据操纵语言 DML是用于检索、插入、更新和删除数据库中数据的SQL语句。 主要的DML语句包括: SELECT:用于查询数据库中的数据。 INSERT&a…...
xiaolin coding 图解网络笔记——TCP篇
1. TCP 头格式有哪些? 序列号:在建立连接时由计算机生成的随机数作为其初始值,通过 SYN 包传给接收端主机,每发送一次数据,就【累加】一次该【数据字节数】的大小。用来解决网络包乱序问题。 确认应答号:指…...
基于大数据python 豆果美食推荐数据可视化系统(源码+LW+部署讲解+数据库+ppt)
!!!!!!!!! 很对人不知道选题怎么选 不清楚自己适合做哪块内容 都可以免费来问我 避免后期給自己答辩找麻烦 增加难度(部分学校只有一次答辩机会 没弄好就延迟…...
ElasticSearch通过es-head插件安装可视化及相关问题
1.es-head下载地址 GitHub - mobz/elasticsearch-head: A web front end for an elastic search cluster 2.启动 建议使用vscode启动,并安装好node.js环境 npm installnpm run start 通过http://localhost:9100就可以看到本地添加的es库 3.相关问题 3.1跨域问…...
JVM系列之OOM观测准备
OOM, 全称 “Out Of Memory”,即内存用完的意思。JVM 因为没有足够的内存来为对象分配空间并且垃圾回收器也已经没有空间可回收时(可分配内存大于需要分配的内存), 就会抛出 java.lang.OutOfMemoryError。在实际的生产应用中,一旦…...
基于Java Springboot Vue3图书管理系统
一、作品包含 源码数据库设计文档万字全套环境和工具资源部署教程 二、项目技术 前端技术:Html、Css、Js、Vue3、Element-ui 数据库:MySQL 后端技术:Java、Spring Boot、MyBatis 三、运行环境 开发工具:IDEA 数据库&#x…...
解析生成对抗网络(GAN):原理与应用
目录 一、引言 二、生成对抗网络原理 (一)基本架构 (二)训练过程 三、生成对抗网络的应用 (一)图像生成 无条件图像生成: (二)数据增强 (三ÿ…...
torch.maximum函数介绍
torch.maximum 函数介绍 定义:torch.maximum(input, other) 返回两个张量的逐元素最大值。 输入参数: input: 张量,表示第一个输入。other: 张量或标量,表示第二个输入。若为张量,其形状需要能与 input 广播。输出&a…...
Git | 理解团队合作中Git分支的合并操作
合并操作 团队合作中Git分支的合并操作分支合并过程1.创建feature/A分支的过程2. 创建分支feature/A-COPY3.合并分支查看代码是否改变 团队合作中Git分支的合并操作 需求 假设团队项目中的主分支是main,团队成员A基于主分支main创建了feature/A,而我又在团队成员A创…...
源代码定制编译:构建理想的库 以curl为例
文章目录 源代码curl开发环境下载地址制定理想的库初级进阶如何知道选项名称交叉编译交叉编译工具链配置编译环境设置目标架构库和头文件路径编译代码 源代码 我们在日常中会接触到比较多第三方库,比如 网络库相关: libevent、mongoose、curl图形界面&…...
服务熔断-熔断器设计
文章目录 服务为什么需要熔断熔断器设计思想熔断器代码实现 服务为什么需要熔断 对于服务端采用的保护机制为服务限流。 对于服务调用端是否存在保护机制? 假如要发布一个服务 B,而服务 B 又依赖服务 C,当一个服务 A 来调用服务 B 时&#x…...
生产环境中:Flume 与 Prometheus 集成
在生产环境中,将 Apache Flume 与 Prometheus 集成的过程,需要借助 JMX Exporter 或 HTTP Exporter 来将 Flume 的监控数据转换为 Prometheus 格式。以下是详细的实现方法,连同原理和原因进行逐步解释,让刚接触的初学者也能完成集…...
深度解析MySQL的刷脏机制
前言 今天天气挺好,看大家对MySQL系列这么感兴趣,继续来聊聊MySQL,在MySQL的InnoDB中Buffer Pool和LSN关系紧密相连,尤其在脏页管理和刷新过程中起着至关重要的作用。理解LSN如何同Buffer Pool协同工作,有助于深入掌握 MySQL 的写入优化机制及数据一致性保证。 Buffer P…...
Java NIO 全面详解:初学者入门指南
除了前一篇文章讲的传统的 java.io 模块,Java 还提供了更现代化、更高效的非阻塞 IO 模块,即 java.nio(New IO)。java.nio 引入了面向缓冲区(Buffer)的数据处理方式,以及多路复用器(…...
优化 Conda 下载速度:详细的代理配置和网络管理策略
优化 Conda 下载速度:详细的代理配置和网络管理策略 为了彻底解决使用 Conda 下载 PyTorch 时遇到的速度问题,并确保下载过程稳定可靠,这需要一个详细、综合的技术方案。让我们更深入地分析问题原因,然后详尽地解释采取的解决策略…...
蓝牙MCU单片机8k高回报率无线应用
随着高端无线产品性能大幅提升,相比常规蓝牙133Hz回报率,8kHz回报率作为市场最高标准,每秒上传8000个数据包。以鼠标为例,位置每秒更新8000次,刷新率较常规蓝牙提升了60倍,超低延迟、极速响应,已…...
Java抛出自定义运行运行
1.重新生成异常的.java文件 Empty:空 Exception:异常 加起来就是 空指针异常的文件 2.打上extends 运行的异常(异常的类型) 3.点击ctrlo,选着这两个快捷重写 4.在需要抛出异常的地方写上:th…...
JVM 性能调优 -- JVM常用调优工具【jps、jstack、jmap、jstats 命令】
前言: 前面我们分析怎么去预估系统资源,怎么去设置 JVM 参数以及怎么去看 GC 日志,本篇我们分享一些常用的 JVM 调优工具,我们在进行 JVM 调优的时候,通常需要借助一些工具来对系统的进行相关分析,从而确定…...
python+django自动化部署日志采用WebSocket前端实时展示
一、开发环境搭建和配置 # channels是一个用于在Django中实现WebSocket、HTTP/2和其他异步协议的库。 pip install channels#channels-redis是一个用于在Django Channels中使用Redis作为后台存储的库。它可以用于处理#WebSocket连接的持久化和消息传递。 pip install channels…...
【Flink-scala】DataStream编程模型之窗口计算-触发器-驱逐器
DataStream API编程模型 1.【Flink-Scala】DataStream编程模型之数据源、数据转换、数据输出 2.【Flink-scala】DataStream编程模型之 窗口的划分-时间概念-窗口计算程序 文章目录 DataStream API编程模型前言1.触发器1.1 代码示例 2.驱逐器2.1 代码示例 总结 前言 本小节我想…...
毕昇入门学习
schemas.py 概述 这段代码主要定义了一系列基于 Pydantic 的数据模型(BaseModel),用于数据验证和序列化,通常用于构建 API(如使用 FastAPI)。这些模型涵盖了用户认证、聊天消息、知识库管理、模型配置等多…...
实时数据开发|Flink实现数据输出--DataSinks操作
哇哦,又是快乐周五!今天主管又又又请我们喝奶茶了,是乐乐茶的草莓新品。甜甜的草莓配上糯叽叽的麻薯,喝完好满足。这应该不是什么加班信号吧哈哈哈,不加不加周五要回家。 前几天被不同的bug缠身,今天终于正…...
详解网络代理模式:规则、全局与直连的应用与配置
“详解网络代理模式:规则、全局与直连的应用与配置” 当然,为了提供更深入的理解,让我们对每种代理模式进行更详尽的探讨,包括它们的内部工作机制、具体使用场景以及在实际应用中的优势和局限。 规则模式(Rule-based…...
Nacos部署和使用(服务注册与发现、配置中心)
1. docker部署nacos 参考: docker安装nacos-CSDN博客 2.注册中心原理 在微服务远程调用的过程中,包括两个角色: 服务提供者:提供接口供其它微服务访问,比如 A-service服务消费者:调用其它微服务提供的…...
医学机器学习:数据预处理、超参数调优与模型比较的实用分析
摘要 本文介绍了医学中的机器学习,重点阐述了数据预处理、超参数调优和模型比较的技术。在数据预处理方面,包括数据收集与整理、处理缺失值、特征工程等内容,以确保数据质量和可用性。超参数调优对模型性能至关重要,介绍了多种调…...
【大数据学习 | Spark-SQL】关于RDD、DataFrame、Dataset对象
1. 概念: RDD: 弹性分布式数据集; DataFrame: DataFrame是一种以RDD为基础的分布式数据集,类似于传统数据库中的二维表格。带有schema元信息,即DataFrame所表示的二维表数据集的每一列都带有名称和类型…...
流媒体中ES流、PS流 、TS流怎么理解
在流媒体的领域中,ES流、PS流和TS流是视频和音频数据的不同封装格式。它们通常用于传输、存储和播放多媒体内容。让我们分别了解一下它们的定义和用途。 1. ES流(Elementary Stream) ES流(基本流)是最基本的视频或音…...
阿里云ECS服务器磁盘空间不足的几个文件
查看磁盘空间命令: df -h /mnt 清零 echo >nohup.out 磁盘空间不足的文件列表: 一、nohup.out:来自"nohup java -jar service.jar &"命令产生的文件,位置在服务jar所在目录 二、access.log:位于…...
pip 安装指定镜像源
pip 安装指定镜像源 使用 pip 安装时,可以通过指定镜像源来加速安装速度,尤其在网络状况不佳或需要访问国内镜像源的情况下。 常见的国内镜像源 清华大学: https://pypi.tuna.tsinghua.edu.cn/simple 阿里云: https://mirrors.aliyun.com/pypi/simple …...
java全栈day10--后端Web基础(基础知识)
引言:只要能通过浏览器访问的网站全是B/S架构,其中最常用的服务器就是Tomcat 在浏览器与服务器交互的时候采用的协议是HTTP协议 一、Tomcat服务器 1.1介绍 官网地址:Apache Tomcat - Welcome! 1.2基本使用(网上有安装教程,建议…...
GPT(Generative Pre-trained Transformer) 和 Transformer的比较
GPT(Generative Pre-trained Transformer) 和 Transformer 的比较 flyfish 1. Transformer 是一种模型架构 Transformer 是一种通用的神经网络架构,由 Vaswani 等人在论文 “Attention Is All You Need”(2017)中提…...
大数据营销
大数据营销是一个热门的大数据应用。对于多数企业而言,大数据营销的主要价值源于以下几个方面。 市场预测与决策分析支持 数据对市场预测及决策分析的支持,早就在数据分析与数据挖掘盛行的年代被提出过。沃尔玛著名的“啤酒与尿布”案例就是那个时候的杰…...
数据字典的实现与应用 —— 提高系统灵活性与维护效率的关键
目录 前言1. 数据字典的基本概念1.1 什么是数据字典1.2 数据字典的主要特点 2. 数据字典的优势2.1 提高代码复用性2.2 提升系统的灵活性2.3 方便非技术人员管理2.4 减少错误概率 3. 数据字典在若依中的实现3.1 若依框架简介3.2 数据字典的结构设计 4. 若依框架中数据字典的配置…...
Scrapy管道设置和数据保存
1.1 介绍部分: 文字提到常用的Web框架有Django和Flask,接下来将学习一个全球范围内流行的爬虫框架Scrapy。 1.2 内容部分: Scrapy的概念、作用和工作流程 Scrapy的入门使用 Scrapy构造并发送请求 Scrapy模拟登陆 Scrapy管道的使用 Scrapy中…...
Jenkins的使用
文章目录 一、Jenkins是什么\有什么用\与GitLab的对比二、Jenkins的安装与配置Jenkins的安装方式在Linux上安装Jenkins:在Windows上安装Jenkins:配置Jenkins: (可选)配置启动用户为root(一定要是root吗??…...
计算机基础 原码反码补码问题
整数的二进制的表示形式:其实有三种 原码:直接根据数值写出的二进制序列就是原码 反码:原码的符号位不变,其他位按位取反就是反码 补码:反码1,就是补码 负数:-1 以补码形式存放在内存 写出 -1…...
ORB-SLAM2 ----- LocalMapping::SearchInNeighbors()
文章目录 一、函数意义二、函数讲解三、函数代码四、本函数使用的匹配方法ORBmatcher::Fuse()1. 函数讲解2. 函数代码 四、总结 一、函数意义 本函数是用于地图点融合的函数,前面的函数生成了新的地图点,但这些地图点可能在前面的关键帧中已经生成过了&a…...
游戏引擎学习第27天
仓库:https://gitee.com/mrxiao_com/2d_game 欢迎 项目的开始是从零开始构建一款完整的游戏,完全不依赖任何库或引擎。这样做有两个主要原因:首先,因为这非常有趣;其次,因为它非常具有教育意义。了解游戏开发的低层次…...
【超全总结】深度学习分割模型的损失函数类别及应用场景
《------往期经典推荐------》 一、AI应用软件开发实战专栏【链接】 项目名称项目名称1.【人脸识别与管理系统开发】2.【车牌识别与自动收费管理系统开发】3.【手势识别系统开发】4.【人脸面部活体检测系统开发】5.【图片风格快速迁移软件开发】6.【人脸表表情识别系统】7.【…...
基于HTML和CSS的校园网页设计与实现
摘要 随着计算机、互联网与通信技术的进步,Internet在人们的学习、工作和生活中的地位也变得越来越高,校园网站已经成为学校与学生,学生与学生之间交流沟通的重要平台,对同学了解学校内发生的各种事情起到了重要的作用。学校网站…...
深度学习基础02_损失函数BP算法(上)
目录 一、损失函数 1、线性回归损失函数 1.MAE损失 2.MSE损失 3.SmoothL1Loss 2、多分类损失函数--CrossEntropyLoss 3、二分类损失函数--BCELoss 4、总结 二、BP算法 1、前向传播 1.输入层(Input Layer)到隐藏层(Hidden Layer) 2.隐藏层(Hidden Layer)到输出层(Ou…...
Flutter:列表分页,上拉加载下拉刷新,在GetBuilder模板使用方式
GetBuilder模板使用方式参考上一节 本篇主要代码记录如何使用上拉加载下拉刷新, 接口请求和商品组件的代码不包括在内 pubspec.yaml装包 cupertino_icons: ^1.0.8# 分页 上拉加载,下拉刷新pull_to_refresh_flutter3: 2.0.2商品列表:controlle…...