24种设计模式之行为型模式(下)-Java版

软件设计模式是前辈们代码设计经验的总结,可以反复使用。设计模式共分为3大类,创建者模式(6种)、结构型模式(7种)、行为型模式(11种),一共24种设计模式,软件设计一般需要满足7大基本原则。下面通过5章的学习一起来看看设计模式的魅力吧。

行为模式(11种):本质是描述类与对象协助完成单个对象无法完成的任务,以及怎么分配职责。

包括:模板方法、策略、命令、责任链、状态、观察者、中介者模式、迭代器、访问者、备忘录、解释器。

目录

1.中介者模式

2.迭代器模式

3.访问者模式

4.备忘录模式

5.解释器模式


1.中介者模式

定义:中介者模式又称为调停模式,定义一个中介角色来封装一系列对象的交互操作,使得原有对象之间耦合度减小。

中介者模式包含以下角色:

01.抽象中介者:中介者接口,提供同事对象注册与转发同事对象的抽象方法。

02.具体中介者:协调各个同事之间的关系。

03.抽象同事类:定义同事类的接口,保存中介者对象,提供同事对象交互的抽象方法。

04.具体同事类:抽象同事类的实现者。

中介者模式的优缺点及使用场景:

优点:松散耦合、集中控制。

缺点:同事类比较多的情况下,中介者的职责将变得复杂而庞大。

使用场景:系统中对象存在复杂的引用关系,系统结构混乱且难以理解。

下面通过一个租房的案例学习一下中介者模式,房主和租客是同事类,中介就是中介类。

1.首先定义一个抽象同事类,包含房主与租客的名字,以及中介对象。

/*** @author nuist__NJUPT* @ClassName Person* @description: 抽象同事类* @date 2024年02月03日*/
public abstract class Person {protected String name ;protected Mediator mediator ;public Person(String name, Mediator mediator) {this.name = name;this.mediator = mediator;}
}

2.然后定义一个抽象的中介对象,用于和房主以及租客进行沟通。

/*** @author nuist__NJUPT* @ClassName Mediator* @description: 抽象中介者类* @date 2024年02月03日*/
public abstract class Mediator {public abstract void contact(String message, Person person) ;
}

3.定义具体的同事角色类,即租客类与房主类,需要获取信息并与中介进行沟通。

/*** @author nuist__NJUPT* @ClassName HouseOwner* @description: 具体的同事角色类* @date 2024年02月03日*/
public class HouseOwner extends Person {public HouseOwner(String name, Mediator mediator) {super(name, mediator);}// 和中介进行沟通public void contact(String message){mediator.contact(message, this);}// 获取信息public void getMessage(String message){System.out.println("房东" + name + "获取到的信息:" + message);}
}

/*** @author nuist__NJUPT* @ClassName Tenant* @description: 具体同事角色类* @date 2024年02月03日*/
public class Tenant extends Person {public Tenant(String name, Mediator mediator) {super(name, mediator);}// 和中介进行沟通public void contact(String message){mediator.contact(message, this);}// 获取信息public void getMessage(String message){System.out.println("租房者" + name + "获取到的信息:" + message);}}

4.定义具体的中介类,用于和房主以及租客进行沟通。

/*** @author nuist__NJUPT* @ClassName MediatorStructure* @description: 具体的中介者类* @date 2024年02月03日*/
public class MediatorStructure extends Mediator {// 聚合同事角色类:房主和租客private HouseOwner houseOwner ;private Tenant tenant ;public HouseOwner getHouseOwner() {return houseOwner;}public void setHouseOwner(HouseOwner houseOwner) {this.houseOwner = houseOwner;}public Tenant getTenant() {return tenant;}public void setTenant(Tenant tenant) {this.tenant = tenant;}// 和中介沟通public void contact(String message, Person person){if(person == houseOwner){tenant.getMessage(message);}else if(person == tenant){houseOwner.getMessage(message);}}}

5.最后创建测试类:创建中介,创建房主与租客,使中介知道该房主与租客,最后通过中介进行沟通。

/*** @author nuist__NJUPT* @ClassName Client* @description: 客户端测试类* @date 2024年02月03日*/
public class Client {public static void main(String[] args) {// 创建中介对象MediatorStructure mediatorStructure = new MediatorStructure() ;// 创建房主与租客对象HouseOwner houseOwner = new HouseOwner("肥婆", mediatorStructure) ;Tenant tenant = new Tenant("小王", mediatorStructure) ;// 中介需要知道具体的房主与租客mediatorStructure.setHouseOwner(houseOwner);mediatorStructure.setTenant(tenant);// 通过中介完成房主与租客进行沟通tenant.contact("请问有单间可以出租吗?");houseOwner.contact("有的...");}
}

2.迭代器模式

定义:提供一个对象来访问聚合对象中的一系列数据,而不暴露聚合对象的内部表示。

迭代器模式主要包含如下角色:
01.抽象聚合角色:定义元素操作以及迭代器对象的接口。

02.具体聚合角色:实现抽象聚合角色,返回一个具体的迭代器对象。

03.抽象迭代器角色:定义访问和遍历聚合元素的接口,包含next()等方法。

04.具体迭代器角色:实现抽象迭代器类并重写相应的抽象方法遍历与访问聚合元素。

迭代器模式的优缺点及使用场景:

优点:支持以不同方式遍历一个聚合对象,简化了聚合类的设计,满足开闭原则。

缺点:增加了类的数目,在一定程度上增加了系统的复杂度。

使用场景:遍历聚合对象,提供统一接口,不暴露内部实现细节。在java的集合中使用了迭代器模式,使用迭代器可以遍历集合元素。

下面定义一个存储学生对象的容器对象,将遍历该容器的功能交给迭代器实现。

1.定义一个学生对象,包含姓名合编号。


/*** @author nuist__NJUPT* @ClassName Student* @description: 学生对象* @date 2024年02月03日*/
public class Student {private String name ;private String number ;public String getName() {return name;}public void setName(String name) {this.name = name;}public String getNumber() {return number;}public void setNumber(String number) {this.number = number;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", number='" + number + '\'' +'}';}public Student(String name, String number) {this.name = name;this.number = number;}public Student() {}
}

2.定义聚合接口及其实现类,用于用于添加/删除学生对象以及获取迭代器对象。

/*** @author nuist__NJUPT* @InterfaceName StudentAggregate* @description: 抽象聚合角色* @date 2024年02月03日*/
public interface StudentAggregate {// 添加学生void addStudent(Student student) ;// 删除学生void removeStudent(Student student) ;// 获取迭代器对象StudentIterator getStudentIterator() ;
}

import java.util.ArrayList;
import java.util.List;/*** @author nuist__NJUPT* @ClassName StudentAggregateImpl* @description: 具体聚合角色* @date 2024年02月03日*/
public class StudentAggregateImpl implements  StudentAggregate {private List<Student> list = new ArrayList<Student>() ;public void addStudent(Student student) {list.add(student) ;}public void removeStudent(Student student) {list.remove(student) ;}public StudentIterator getStudentIterator() {return new StudentIteratorImpl(list);}
}

3.定义迭代器接口及其实现类,用于遍历迭代器元素。

/*** @author nuist__NJUPT* @InterfaceName StudentIterator* @description: 抽象迭代器角色接口* @date 2024年02月03日*/
public interface StudentIterator {// 判断是否还有元素boolean hasNext() ;// 获取下一个元素Student next() ;}
import java.util.List;/*** @author nuist__NJUPT* @ClassName StudentIteratorImpl* @description: 具体迭代器角色* @date 2024年02月03日*/
public class StudentIteratorImpl implements StudentIterator {List<Student> list ;private int position = 0 ;public StudentIteratorImpl(List<Student> list) {this.list = list;}public boolean hasNext() {return position < list.size() ;}public Student next() {return list.get(position++);}
}

4.定义客户端测试类,通过向聚合对象添加学生对象,通过获取迭代器对象,遍历元素。


/*** @author nuist__NJUPT* @ClassName Client* @description: 客户端测试类* @date 2024年02月03日*/
public class Client {public static void main(String[] args) {// 创建聚合对象StudentAggregate studentAggregate = new StudentAggregateImpl() ;// 添加学生对象studentAggregate.addStudent(new Student("张三", "1"));studentAggregate.addStudent(new Student("王五", "2"));studentAggregate.addStudent(new Student("李四", "3"));// 获取迭代器对象StudentIterator iterator = studentAggregate.getStudentIterator();// 通过迭代器对象遍历while (iterator.hasNext()){System.out.println(iterator.next().toString());}}}
3.访问者模式

定义:封装一些作用于某种数据结构的各种操作,在不改变数据结构的前提下定义作用于这些元素的新操作。

访问者模式包含以下角色:

01.抽象访问者角色:定义了对每个元素的访问行为。

02.具体访问者角色:定义了对每个元素类访问时所产生的具体行为。

03.抽象元素角色:定义一个接收访问者的方法。

04.具体元素角色:定义一个接收方法的具体实现。
05.对象结构:定义对象结构,包含一组元素及其迭代方式,供访问者访问。

访问者模式的优缺点及使用场景:

优点:扩展性好,复用性好,通过访问者来分离无关行为。

缺点:违背依赖倒转原则,访问者是依赖具体而不是依赖抽象。
使用场景:对象结构相对稳定,但是操作算法经常变化。

下面通过给宠物喂食的案例学习一下访问者模式。其中各个类对应的角色如下:

抽象访问者角色:给宠物喂食的人

具体访问者角色:主人、其它人

抽象元素角色:动物角色

具体元素角色:宠物狗、宠物猫

结构对象角色:主人家

1.首先定义一个抽象元素角色,定义由访问者访问的方法。

/*** @author nuist__NJUPT* @InterfaceName Animal* @description: 抽象元素角色类* @date 2024年02月04日*/
public interface Animal {// 接受访问者访问void accept(Person person) ;}

2.定义两个具体元素角色,实现抽象元素角色接口,并重写相应的接口方法。


/*** @author nuist__NJUPT* @ClassName Dog* @description: 具体元素角色* @date 2024年02月04日*/
public class Dog implements Animal{public void accept(Person person) {person.feedDog(this);System.out.println("好吃,汪汪汪...");}
}

/*** @author nuist__NJUPT* @ClassName Cat* @description: 具体元素角色类* @date 2024年02月04日*/
public class Cat implements Animal{public void accept(Person person) {person.feedCat(this);System.out.println("好吃,喵喵喵...");}
}

3.定义抽象访问者类,类中定义访问方法。


/*** @author nuist__NJUPT* @InterfaceName Person* @description: 抽象访问者角色* @date 2024年02月04日*/
public interface Person {// 给猫喂食void feedCat(Cat cat) ;// 给狗喂食void feedDog(Dog dog) ;}

4.定义具体访问者类,并实现抽象访问者接口,重写接口方法。


/*** @author nuist__NJUPT* @ClassName Owner* @description: 具体访问者* @date 2024年02月04日*/
public class Owner implements Person {public void feedCat(Cat cat) {System.out.println("主人喂宠物猫");}public void feedDog(Dog dog) {System.out.println("主人喂宠物狗");}
}
/*** @author nuist__NJUPT* @ClassName Someone* @description: 具体访问者* @date 2024年02月04日*/
public class Someone implements Person {public void feedCat(Cat cat) {System.out.println("其它人喂宠物猫");}public void feedDog(Dog dog) {System.out.println("其它人喂宠物狗");}}

5.定义对象结构类,用于添加元素,并为访问者类提供访问对象的方法。

import java.util.ArrayList;
import java.util.List;/*** @author nuist__NJUPT* @ClassName Home* @description: 对象结构类* @date 2024年02月04日*/
public class Home {// 定义一个集合对象,用来存储元素对象List<Animal> animals = new ArrayList<Animal>() ;// 添加元素public void addAnimal(Animal animal){animals.add(animal) ;}// 提供访问者访问元素对象的方法public void action(Person person){for(Animal animal : animals){animal.accept(person);}}}

6.定义客户端测试类,验证访问者模式。


/*** @author nuist__NJUPT* @ClassName Client* @description: 客户端测试类* @date 2024年02月04日*/
public class Client {public static void main(String[] args) {// 创建结构对象Home home = new Home() ;// 添加元素对象home.addAnimal(new Dog());home.addAnimal(new Cat());// 创建访问者对象Owner owner = new Owner() ;// 结构对象提供访问者对象访问相应的元素home.action(owner);}
}
4.备忘录模式

定义:备忘录模式又称为快照模式,在不破坏封装性的前提下,捕获一个对象的内部状态,并在外部保存这个对象的内部状态,当需要使用到的时候可以快速恢复到保存的状态。

备忘录模式的主要角色如下:
01.发起人角色:记录当前时刻的内部状态信息,提供创建备忘录记录和恢复备忘录记录的功能。

02.备忘录角色:存储发起人的内部状态信息,在需要的时候将这个状态传递给发起人。

03.管理者角色:对备忘录进行管理,提供保存与获取备忘录的功能,不能更改备忘录内部细节。

备忘录模式的优缺点及使用场景:
优点:提供了状态恢复机制,实现了内部状态的封装,也符合单一职责原则。

缺点:资源多的情况下,资源消耗大。

使用场景:需要保存与恢复数据,提供一个可以回滚的场景。

备忘录模式有黑箱备忘录和白箱备忘录模式,白箱备忘录模式是破坏封装性的,即备忘录管理者能构修改备忘录内部的细节。

下面通过一个游戏案例学习备忘录模式,一个游戏角色有生命力、攻击力、防御力等数据,在打boss前和打boss后一定会不一样,玩家在跟boss决斗不理想的情况下允许恢复到之前的状态。

1.首先先一下白箱备忘录模式,定义一个游戏角色,即发起人对象。


/*** @author nuist__NJUPT* @ClassName GameRole* @description: 游戏角色类-发起人对象* @date 2024年02月04日*/
public class GameRole {// 攻击力private int vit ;// 防御力private int def ;// 生命力private int atk ;// 初始化内部状态public void initState(){this.vit = 100 ;this.def = 100 ;this.atk = 100 ;}// 战斗public void fight(){this.vit = 0 ;this.atk = 0 ;this.def = 0 ;}// 保存角色状态功能public RoleStateMemento saveState(){return new RoleStateMemento(vit, def, atk) ;}// 恢复角色状态public void recoveryState(RoleStateMemento roleStateMemento){// 将备忘录中存储的对象状态赋值到当前对象this.vit = roleStateMemento.getVit() ;this.def = roleStateMemento.getDef() ;this.atk = roleStateMemento.getAtk() ;}// 展示状态功能public void stateDisplay(){System.out.println("角色生命力:" + vit);System.out.println("角色攻击力" + atk);System.out.println("角色防御力" + def);}public int getVit() {return vit;}public void setVit(int vit) {this.vit = vit;}public int getDef() {return def;}public void setDef(int def) {this.def = def;}public int getAtk() {return atk;}public void setAtk(int atk) {this.atk = atk;}
}

2.定义备忘录角色,用于保存发起人角色的状态。

/*** @author nuist__NJUPT* @ClassName RoleStateMemento* @description: 备忘录角色类* @date 2024年02月04日*/
public class RoleStateMemento {// 攻击力private int vit ;// 防御力private int def ;// 生命力private int atk ;public RoleStateMemento(int vit, int def, int atk) {this.vit = vit;this.def = def;this.atk = atk;}public RoleStateMemento() {}public int getVit() {return vit;}public void setVit(int vit) {this.vit = vit;}public int getDef() {return def;}public void setDef(int def) {this.def = def;}public int getAtk() {return atk;}public void setAtk(int atk) {this.atk = atk;}
}

3.定义管理者角色,用于管理备忘录,备忘录提供宽接口,即提供具体备忘录实现类给管理者管理

/*** @author nuist__NJUPT* @ClassName RoleStateCaretaker* @description: 管理者类* @date 2024年02月04日*/
public class RoleStateCaretaker {// 声明备忘录类对象private RoleStateMemento roleStateMemento ;public RoleStateMemento getRoleStateMemento() {return roleStateMemento;}public void setRoleStateMemento(RoleStateMemento roleStateMemento) {this.roleStateMemento = roleStateMemento;}}

4.最后,定义测试类,测试白箱备忘录模式。

/*** @author nuist__NJUPT* @ClassName Client* @description: 客户端测试类-白箱备忘录模式* @date 2024年02月04日*/
public class Client {public static void main(String[] args) {System.out.println("-----------------大战Boss前-------------------") ;// 创建发起人角色GameRole gameRole = new GameRole() ;gameRole.initState();gameRole.stateDisplay();// 创建备忘录管理者管理备忘录RoleStateCaretaker roleStateCaretaker = new RoleStateCaretaker() ;roleStateCaretaker.setRoleStateMemento(gameRole.saveState());System.out.println("-----------------大战Boss后-------------------") ;// 战斗gameRole.fight();gameRole.stateDisplay();System.out.println("-----------------恢复到之前的状态-------------------") ;gameRole.recoveryState(roleStateCaretaker.getRoleStateMemento());gameRole.stateDisplay();}
}

还是这个案例,下面我们看一下黑箱备忘录模式,该模式是将备忘录实现类放到发起人角色类的内部,通过提供一个抽象接口给管理者管理。

1.定义发起人类对象,在发起人对象内部定义备忘录类对象。

/*** @author nuist__NJUPT* @ClassName GameRole* @description: 将备忘录角色类定义在发起者角色类的内部* @date 2024年02月04日*/
public class GameRole {// 攻击力private int vit ;// 防御力private int def ;// 生命力private int atk ;// 初始化内部状态public void initState(){this.vit = 100 ;this.def = 100 ;this.atk = 100 ;}// 战斗public void fight(){this.vit = 0 ;this.atk = 0 ;this.def = 0 ;}// 保存角色状态功能public Memento saveState(){return new RoleStateMemento(vit, def, atk) ;}// 恢复角色状态public void recoveryState(Memento memento){RoleStateMemento roleStateMemento = (RoleStateMemento) memento;// 将备忘录中存储的对象状态赋值到当前对象this.vit = roleStateMemento.getVit() ;this.def = roleStateMemento.getDef() ;this.atk = roleStateMemento.getAtk() ;}// 展示状态功能public void stateDisplay(){System.out.println("角色生命力:" + vit);System.out.println("角色攻击力" + atk);System.out.println("角色防御力" + def);}public int getVit() {return vit;}public void setVit(int vit) {this.vit = vit;}public int getDef() {return def;}public void setDef(int def) {this.def = def;}public int getAtk() {return atk;}public void setAtk(int atk) {this.atk = atk;}public class RoleStateMemento implements  Memento{// 攻击力private int vit ;// 防御力private int def ;// 生命力private int atk ;public RoleStateMemento(int vit, int def, int atk) {this.vit = vit;this.def = def;this.atk = atk;}public RoleStateMemento() {}public int getVit() {return vit;}public void setVit(int vit) {this.vit = vit;}public int getDef() {return def;}public void setDef(int def) {this.def = def;}public int getAtk() {return atk;}public void setAtk(int atk) {this.atk = atk;}}
}

2.对外提供一个备忘录抽象接口由管理者管理。

/*** @author nuist__NJUPT* @InterfaceName Memento* @description: 备忘录接口-对外提供窄接口* @date 2024年02月04日*/
public interface Memento {}

3.声明管理者类管理备忘录对象。


/*** @author nuist__NJUPT* @ClassName RoleStateCaretaker* @description: 管理者类-只管理备忘录的接口抽象,不管理具体内部实现类细节* @date 2024年02月04日*/
public class RoleStateCaretaker {// 声明备忘录类对象private Memento memento ;public Memento getMemento() {return memento;}public void setMemento(Memento memento) {this.memento = memento;}
}

4.定义客户端测试类,测试黑盒备忘录模式。

/*** @author nuist__NJUPT* @ClassName Client* @description: 客户端测试类-黑箱备忘录模式* @date 2024年02月04日*/public class Client {public static void main(String[] args) {System.out.println("-----------------大战Boss前-------------------") ;// 创建发起人角色GameRole gameRole = new GameRole() ;gameRole.initState();gameRole.stateDisplay();// 创建备忘录管理者管理备忘录RoleStateCaretaker roleStateCaretaker = new RoleStateCaretaker() ;roleStateCaretaker.setMemento(gameRole.saveState());System.out.println("-----------------大战Boss后-------------------") ;// 战斗gameRole.fight();gameRole.stateDisplay();System.out.println("-----------------恢复到之前的状态-------------------") ;gameRole.recoveryState(roleStateCaretaker.getMemento());gameRole.stateDisplay();}
}
5.解释器模式

定义:给定一个语言,定义它的文法表示,并定义一个解释器,这个解释器使用该标识来解释语言中的句子。

解释器模式包含以下角色:

01.抽象表达式角色:定义解释器接口,约定解释器的解释操作。

02.终结符表达式角色:抽象表达式的子类,用来实现文法中与终结符相关的操作。

03.非终结符表达式角色:抽象表达式的子类,用来实现文法中与非终结符相关的操作。

04.环境角色:通常包含各个解释器需要的数据或是公共的功能。

05.客户端:将需要分析的句子或者表达式转换成使用解释器对象描述的抽象语法树。

解释器模式的优缺点及使用场景:

优点:易于改变与扩展文。

缺点:对于复杂的文法难以维护。
使用场景:当语言的文法较为简单,且执行效率不是关键问题的时候。

通过实现用于加减法的案例来学习解释器模式,具体如下:

1.首先定义抽象表达式类,定义解释器接口。


/*** @author nuist__NJUPT* @ClassName AbstractExpression* @description: 抽象表达式角色* @date 2024年02月04日*/
public abstract class AbstractExpression {public abstract int intercept(Context context) ;}

2.定义三个具体表达式角色,是抽象表达式的子类。

/*** @author nuist__NJUPT* @ClassName Plus* @description: 加法表达式角色* @date 2024年02月04日*/
public class Plus extends AbstractExpression {// +号左边的表达式private AbstractExpression left ;// +号右边的表达式private AbstractExpression right ;public Plus(AbstractExpression left, AbstractExpression right) {this.left = left;this.right = right;}public int intercept(Context context) {// 将左边表达式的结果与右边表达式的结果进行相加return left.intercept(context) + right.intercept(context);}@Overridepublic String toString() {return "Plus{" +"left=" + left +", right=" + right +'}';}
}

/*** @author nuist__NJUPT* @ClassName Minus* @description: 减法表达式类* @date 2024年02月04日*/
public class Minus extends AbstractExpression {// -号左边的表达式private AbstractExpression left ;// -号右边的表达式private AbstractExpression right ;public Minus(AbstractExpression left, AbstractExpression right) {this.left = left;this.right = right;}public int intercept(Context context) {// 将左边表达式的结果与右边表达式的结果进行相减return left.intercept(context) - right.intercept(context);}@Overridepublic String toString() {return "Plus{" +"left=" + left +", right=" + right +'}';}
}
/*** @author nuist__NJUPT* @ClassName Variable* @description: TODO* @date 2024年02月04日*/
public class Variable extends AbstractExpression {// 声明存储变量名的成员变量private String name ;public Variable(String name){this.name = name ;}public int intercept(Context context) {// 直接返回变量的值return context.getValue(this);}@Overridepublic String toString() {return "Variable{" +"name='" + name + '\'' +'}';}
}

3.定义环境角色,用于对变量进行操作。


import java.util.HashMap;
import java.util.Map;/*** @author nuist__NJUPT* @ClassName Context* @description: 环境角色类* @date 2024年02月04日*/
public class Context {// 定义一个Map集合用来存储变量及其对应的值private Map<Variable,Integer> map = new HashMap<Variable, Integer>() ;// 添加变量的功能public void assign(Variable variable, Integer value){map.put(variable, value) ;}// 根据变量获取相应的值public int getValue(Variable variable){return map.get(variable) ;}}

4.最后定义测试类,测试解释器模式。

/*** @author nuist__NJUPT* @ClassName Client* @description: 客户端测试类* @date 2024年02月04日*/
public class Client {public static void main(String[] args) {// 创建环境对象Context context = new Context() ;// 创建多个变量Variable a = new Variable("a") ;Variable b = new Variable("b") ;Variable c = new Variable("c") ;Variable d = new Variable("d") ;// 将变量存储到环境中context.assign(a,1);context.assign(b,2);context.assign(c,3);context.assign(d,4);// 获取抽象语法树AbstractExpression abstractExpression = new Minus(a, new Plus(new Minus(b, c), d));// 解释int intercept = abstractExpression.intercept(context);System.out.println(intercept);}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/668816.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

大端和小端模式介绍

介绍 “大端”和“小端”通常指的是字节序&#xff08;Byte Order&#xff09;的两种类型&#xff0c;也被称为端序&#xff08;Endianness&#xff09;。在多字节的数据类型&#xff08;如整数&#xff09;中&#xff0c;字节可以以不同的顺序存储&#xff0c;这影响了计算机…

风行智能电视G32Y 强制刷机升级方法,附刷机升级数据MstarUpgrade.bin

升级步骤&#xff1a; 1、下载刷机数据&#xff0c;如是压缩包&#xff0c;需要先解压&#xff0c;然后将刷机bin格式的文件重命名为MstarUpgrade.bin 2、将此文件放到U盘根目录 &#xff08;U盘格式FAT32&#xff0c;单分区&#xff0c;建议4G的优盘刷机成功率高&#xff09;…

JD京东商品详情数据获取API测试示例

item_get 获得JD商品详情item_search 按关键字搜索商品item_search_img 按图搜索京东商品&#xff08;拍立淘&#xff09;item_search_shop 获得店铺的所有商品item_history_price 获取商品历史价格信息item_recommend 获取推荐商品列表buyer_order_list 获取购买到的商品订单列…

彻底学会系列:一、机器学习之线性回归(一)

1.基本概念(basic concept) 线性回归&#xff1a; 有监督学习的一种算法。主要关注多个因变量和一个目标变量之间的关系。 因变量&#xff1a; 影响目标变量的因素&#xff1a; X 1 , X 2 . . . X_1, X_2... X1​,X2​... &#xff0c;连续值或离散值。 目标变量&#xff1a; …

JAVA毕业设计126—基于Java+Springboot+Vue的二手交易商城管理系统(源代码+数据库)

毕设所有选题&#xff1a; https://blog.csdn.net/2303_76227485/article/details/131104075 基于JavaSpringbootVue的二手交易商城管理系统(源代码数据库)126 一、系统介绍 本项目前后端分离&#xff0c;本系统分为管理员、用户两种角色 1、用户&#xff1a; 注册、登录、…

docker更换镜像源

添加的镜像源 {"registry-mirrors": ["https://registry.cn-hangzhou.aliyuncs.com", "https://reg-mirror.qiniu.com/", "https://docker.mirrors.ustc.edu.cn"] }docker更换镜像源之后一定要重启守卫 systemctl daemon-reloaddock…

【Ubuntu】安装hbase

前提 需要安装java 安装 HBase 下载并解压 HBase 安装包&#xff1a; wget https://dlcdn.apache.org/hbase/2.5.7/hbase-2.5.7-bin.tar.gz tar -zxvf hbase-2.5.7-bin.tar.gz配置 HBase 环境变量&#xff1a; export HBASE_HOME/path/to/hbase-2.5.7 export PATH$PATH:$H…

ESP32QRCodeReader库使用,ESP32-CAM识别二维码并向自写接口发出请求确认身份。

#include <Arduino.h> #include <WiFi.h> #include <HTTPClient.h> #include <ESP32QRCodeReader.h>#define WIFI_SSID "username" #define WIFI_PASSWORD "password" // 连接电脑主机的IP地址的8088端口 #define WEBHOOK_URL &qu…

docker-学习-5

docker-学习第五天 docker-学习第五天1. 昨天的练习回顾1.1. 练习11.2. 练习2 2. 命令2.1. 看镜像的详细信息 3. Dockerfile指令3.1. 常见的指令3.2. ENTRYPOINT和CMD的区别3.3. RUN中的set指令 4. 镜像的原理4.1. 为什么 Docker 镜像要采用这种分层结构呢&#xff1f;4.2. doc…

JavaScript ATM取款机

①&#xff1a;循环的时候&#xff0c;需要反复提示输入框&#xff0c;所以提示框写到循环里面 ②&#xff1a;退出的条件是用户输入了 4&#xff0c;如果是4&#xff0c;则结束循环&#xff0c;不在弹窗 ③&#xff1a;提前准备一个金额预先存储一个数额 ④&#xff1a;取钱…

Servlet服务器端的小程序

文章目录 Servlet概述快速入门Servlet 中方法的生命周期Servlet 的体系结构GenericServletHttpServlet Servlet 3.0以后Servlet 相关配置 案例Servlet xml配置web.xmlMyServlet Servlet 注解配置 Servlet 概述 Servlet applet 运行在服务器端的小程序&#xff0c;Servlet 就是…

挑战杯 python+opencv+机器学习车牌识别

0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 基于机器学习的车牌识别系统 &#x1f947;学长这里给一个题目综合评分(每项满分5分) 难度系数&#xff1a;4分工作量&#xff1a;4分创新点&#xff1a;3分 该项目较为新颖&#xff0c;适…

【MySQL】在 Centos7 环境安装 MySQL -- 详细完整教程

说明&#xff1a; 安装与卸载中&#xff0c;用户全部切换成为 root&#xff0c;一旦安装&#xff0c;普通用户就能使用。 一、卸载内置环境 1、卸载不要的环境 [rootVM-8-5-centos ~]$ ps ajx | grep mariadb # 先检查是否有mariadb存在 13134 14844 14843 13134 pts/0 14843…

NLP_Bag-Of-Words(词袋模型)

文章目录 词袋模型用词袋模型计算文本相似度1.构建实验语料库2.给句子分词3.创建词汇表4.生成词袋表示5.计算余弦相似度6.可视化余弦相似度 词袋模型小结 词袋模型 词袋模型是一种简单的文本表示方法&#xff0c;也是自然语言处理的一个经典模型。它将文本中的词看作一个个独立…

Java Collection 集合体系的使用

Java Collection 集合体系的使用 package com.zhong.collection;import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.HashSet;public class CollectionDemo {public static void main(String[] args) {// ArrayList 有序 可…

C语言贪吃蛇详解

个人简介&#xff1a;双非大二学生 个人博客&#xff1a;Monodye 今日鸡汤&#xff1a;人生就像一盒巧克力&#xff0c;你永远不知道下一块是什么味的 C语言基础刷题&#xff1a;牛客网在线编程_语法篇_基础语法 (nowcoder.com) 一.贪吃蛇游戏背景 贪吃蛇是久负盛名的游戏&…

###C语言程序设计-----C语言学习(9)#函数基础

前言&#xff1a;感谢您的关注哦&#xff0c;我会持续更新编程相关知识&#xff0c;愿您在这里有所收获。如果有任何问题&#xff0c;欢迎沟通交流&#xff01;期待与您在学习编程的道路上共同进步。 一. 基础知识的学习 1.函数的定义 函数是一个完成特定工作的独立程序模块&…

GPT-1, GPT-2, GPT-3, GPT-3.5, GPT-4论文内容解读

目录 1 ChatGPT概述1.1 what is chatGPT1.2 How does ChatGPT work1.3 The applications of ChatGPT1.3 The limitations of ChatGPT 2 算法原理2.1 GPT-12.1.1 Unsupervised pre-training2.1.2 Supervised fine-tuning2.1.3 语料2.1.4 分析 2.2 GPT-22.3 GPT-32.4 InstructGPT…

如何使用MCSM搭建我的世界Java版服务器并实现远程联机游戏

文章目录 1. 安装JAVA2. MCSManager安装3.局域网访问MCSM4.创建我的世界服务器5.局域网联机测试6.安装cpolar内网穿透7. 配置公网访问地址8.远程联机测试9. 配置固定远程联机端口地址9.1 保留一个固定tcp地址9.2 配置固定公网TCP地址9.3 使用固定公网地址远程联机 本教程主要介…

面试题:SpringBoot 在打包部署的时候打包成 jar 和 war 有什么不同?

文章目录 前言jar包和war包的区别一、打包成jar二、打包成war包形式 前言 首先给大家来讲一个我们遇到的一个奇怪的问题: 我的一个springboot项目&#xff0c;用mvn install打包成jar&#xff0c;换一台有jdk的机器就直接可以用java -jar 项目名.jar的方式运行&#xff0c;没…