Java架构师之路九、设计模式:常见的设计模式,如单例模式、工厂模式、策略模式、桥接模式等
目录
常见的设计模式:
单例模式:
工厂模式:
策略模式:
桥接模式:
责任链模式:
Java架构师之路八、安全技术:Web安全、网络安全、系统安全、数据安全等-CSDN博客
Java架构师之路十、框架和工具:Spring Framework、Spring Boot、Spring Cloud、MyBatis、Hibernate、Dubbo、Zookeeper、Redis等-CSDN博客
常见的设计模式:
在 Java 中,设计模式是软件开发中常用的解决方案模板,可以帮助开发者解决特定的设计问题并提高代码的可重用性、可维护性和灵活性。Java 中常见的设计模式包括创建型模式、结构型模式、行为型模式以及其他模式,其中还包括责任链模式。
-
创建型模式:
- 工厂模式(Factory Pattern):定义一个创建对象的接口,但让子类决定实例化哪个类。
- 单例模式(Singleton Pattern):确保一个类只有一个实例,并提供一个全局访问点。
- 建造者模式(Builder Pattern):将一个复杂对象的构建过程与其表示分离,使相同的构建过程可以创建不同的表示。
-
结构型模式:
- 适配器模式(Adapter Pattern):将一个类的接口转换成客户希望的另一个接口,使原本由于接口不兼容而不能在一起工作的类可以一起工作。
- 装饰器模式(Decorator Pattern):动态地给一个对象添加一些额外的职责,而不影响从这个类派生的其他对象。
- 代理模式(Proxy Pattern):为其他对象提供一种代理以控制对这个对象的访问。
-
行为型模式:
- 观察者模式(Observer Pattern):定义对象间的一对多依赖关系,使得当一个对象改变状态时,所有依赖它的对象都会得到通知并自动更新。
- 策略模式(Strategy Pattern):定义一系列算法,将每个算法封装起来,并使它们可以互相替换。
- 模板方法模式(Template Method Pattern):定义算法的框架,由子类实现具体步骤。
- 责任链模式(Chain of Responsibility Pattern):为请求创建一个接收者对象的链,并沿着这条链传递请求,直到有对象处理请求为止。
-
其他模式:
- 享元模式(Flyweight Pattern):通过共享技术来有效支持大量细粒度对象的复用。
- 备忘录模式(Memento Pattern):在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。
这些设计模式在 Java 开发中有着广泛的应用,合理运用设计模式可以提高软件的质量和可维护性,降低系统的耦合度,使代码更加清晰易懂。责任链模式特别适用于处理请求的场景,可以灵活地组织处理者链条,实现请求与处理者的解耦,提高代码的灵活性和可扩展性。
单例模式:
单例模式是一种创建型设计模式,保证一个类只有一个实例,并提供一个全局访问点。在实际应用中,有些对象只需要一个实例,例如线程池、缓存、对话框、注册表设置等。单例模式可以确保系统中某个类只有一个实例,避免了重复创建对象,节省了系统资源,并且方便对该实例的控制和管理。
在 Java 中,单例模式通常有几种实现方式:
-
懒汉式:
- 延迟加载,在第一次使用时创建实例。
- 线程安全需要考虑,可以通过 synchronized 加锁,或者使用双重检查锁定(Double-Checked Locking)。
- 可能会存在性能问题,因为每次获取实例都需要进行同步操作。
-
饿汉式:
- 类加载时即创建实例。
- 线程安全,但可能会浪费内存。
-
静态内部类:
- 利用类加载机制保证线程安全且延迟加载。
- 通过静态内部类持有外部类的实例,当外部类被加载时静态内部类并不会被加载和初始化。
-
枚举:
- 最简洁、安全的实现方式,由 JVM 保证只会实例化一次。
- 防止反射和序列化攻击。
实现单例模式时需要考虑线程安全性、延迟加载、性能等因素。在选择实现方式时,可以根据具体需求和场景来决定使用哪种方式。单例模式在很多框架和库中都有广泛应用,如 Spring 框架中的 Bean 默认就是单例模式,保证了在应用中只有一个 Bean 实例存在。
总的来说,单例模式是一种常见且重要的设计模式,合理使用可以提高代码的效率和可维护性,但也需要注意避免滥用单例模式导致的问题,如增加代码耦合度、隐藏依赖关系等。
懒汉式单例模式:
在懒汉式单例模式中,实例在需要的时候才被创建。
实现步骤:
- 将构造函数设置为私有,防止外部直接实例化该类。
- 提供一个静态方法获取实例,在方法内部判断实例是否为空,为空则创建实例,否则直接返回实例。
Java 代码示例:
public class LazySingleton {private static LazySingleton instance;private LazySingleton() {// 私有构造函数}public static LazySingleton getInstance() {if (instance == null) {instance = new LazySingleton();}return instance;}
}
示例代码说明:
LazySingleton
类中的构造函数是私有的,外部无法直接实例化。getInstance()
方法是获取实例的静态方法,通过判断instance
是否为空来决定是否创建实例。
测试代码:
public class Main {public static void main(String[] args) {LazySingleton singleton1 = LazySingleton.getInstance();LazySingleton singleton2 = LazySingleton.getInstance();System.out.println(singleton1 == singleton2); // 输出 true,说明是同一个实例}
}
示例说明:
- 在上面的示例中,通过调用
LazySingleton.getInstance()
方法两次获取实例,得到的两个实例是相同的,因为单例模式确保了只有一个实例存在。 - 这种懒汉式单例模式虽然简单,但在多线程环境下存在线程安全问题,可能会创建多个实例。可以通过加锁或使用双重检查锁定等方式来解决线程安全性问题。
工厂模式:
工厂模式是一种创建型设计模式,它提供一种封装对象创建过程的方式。工厂模式通过定义一个共同的接口来创建对象,但具体的实现由子类决定。这样可以将对象的创建与使用代码解耦,提高代码的灵活性和可维护性。
工厂模式常见的几种变体包括简单工厂模式、工厂方法模式和抽象工厂模式。
下面分别详细介绍这三种工厂模式的实现方式,并给出相应的代码示例:
1. 简单工厂模式(Simple Factory Pattern):
简单工厂模式通过一个工厂类负责创建多个不同类型的对象。
实现步骤:
- 创建一个共同的接口或抽象类,用于描述所要创建的对象。
- 创建具体的实现类,实现共同的接口或抽象类。
- 创建一个简单工厂类,负责根据参数的不同返回不同的具体对象。
Java 代码示例:
// 共同的接口
public interface Product {void operation();
}// 具体的实现类
public class ConcreteProductA implements Product {@Overridepublic void operation() {System.out.println("ConcreteProductA operation");}
}public class ConcreteProductB implements Product {@Overridepublic void operation() {System.out.println("ConcreteProductB operation");}
}// 简单工厂类
public class SimpleFactory {public static Product createProduct(String type) {if (type.equals("A")) {return new ConcreteProductA();} else if (type.equals("B")) {return new ConcreteProductB();}return null;}
}
示例代码说明:
Product
是一个共同的接口,描述了所要创建的对象应具有的行为。ConcreteProductA
和ConcreteProductB
是具体的实现类,实现了Product
接口。SimpleFactory
是简单工厂类,根据参数的不同返回不同的具体对象。
测试代码:
public class Main {public static void main(String[] args) {Product productA = SimpleFactory.createProduct("A");productA.operation(); // 输出 "ConcreteProductA operation"Product productB = SimpleFactory.createProduct("B");productB.operation(); // 输出 "ConcreteProductB operation"}
}
2. 工厂方法模式(Factory Method Pattern):
工厂方法模式将对象的创建延迟到子类,每个子类负责创建一个具体的对象。
实现步骤:
- 创建一个抽象工厂类,声明一个抽象的工厂方法。
- 创建具体的工厂类,实现抽象工厂类中的工厂方法,每个具体工厂类负责创建一个具体的对象。
- 创建一个共同的接口或抽象类,用于描述所要创建的对象。
- 创建具体的实现类,实现共同的接口或抽象类。
Java 代码示例:
// 共同的接口
public interface Product {void operation();
}// 具体的实现类
public class ConcreteProductA implements Product {@Overridepublic void operation() {System.out.println("ConcreteProductA operation");}
}public class ConcreteProductB implements Product {@Overridepublic void operation() {System.out.println("ConcreteProductB operation");}
}// 抽象工厂类
public abstract class Factory {public abstract Product createProduct();
}// 具体的工厂类
public class ConcreteFactoryA extends Factory {@Overridepublic Product createProduct() {return new ConcreteProductA();}
}public class ConcreteFactoryB extends Factory {@Overridepublic Product createProduct() {return new ConcreteProductB();}
}
示例代码说明:
Product
是一个共同的接口,描述了所要创建的对象应具有的行为。ConcreteProductA
和ConcreteProductB
是具体的实现类,实现了Product
接口。Factory
是抽象工厂类,声明了一个抽象的工厂方法createProduct()
。ConcreteFactoryA
和ConcreteFactoryB
是具体的工厂类,分别负责创建ConcreteProductA
和ConcreteProductB
对象。
测试代码:
public class Main {public static void main(String[] args) {Factory factoryA = new ConcreteFactoryA();Product productA = factoryA.createProduct();productA.operation(); // 输出 "ConcreteProductA operation"Factory factoryB = new ConcreteFactoryB();Product productB = factoryB.createProduct();productB.operation(); // 输出 "ConcreteProductB operation"}
}
3. 抽象工厂模式(Abstract Factory Pattern):
抽象工厂模式提供一个接口,用于创建一系列相关或相互依赖的对象。
实现步骤:
- 创建一组共同的接口,用于描述所要创建的对象。
- 创建多个具体的实现类,实现共同的接口。
- 创建一个抽象工厂类,声明创建一组对象的抽象方法。
- 创建具体的工厂类,实现抽象工厂类中的抽象方法,负责创建一组相关的对象。
Java 代码示例:
// 共同的接口
public interface ProductA {void operationA();
}public interface ProductB {void operationB();
}// 具体的实现类
public class ConcreteProductA1 implements ProductA {@Overridepublic void operationA() {System.out.println("ConcreteProductA1 operationA");}
}public class ConcreteProductA2 implements ProductA {@Overridepublic void operationA() {System.out.println("ConcreteProductA2 operationA");}
}public class ConcreteProductB1 implements ProductB {@Overridepublic void operationB() {System.out.println("ConcreteProductB1 operationB");}
}public class ConcreteProductB2 implements ProductB {@Overridepublic void operationB() {System.out.println("ConcreteProductB2 operationB");}
}// 抽象工厂类
public interface AbstractFactory {ProductA createProductA();ProductB createProductB();
}// 具体的工厂类
public class ConcreteFactory1 implements AbstractFactory {@Overridepublic ProductA createProductA() {return new ConcreteProductA1();}@Overridepublic ProductB createProductB() {return new ConcreteProductB1();}
}public class ConcreteFactory2 implements AbstractFactory {@Overridepublic ProductA createProductA() {return new ConcreteProductA2();}@Overridepublic ProductB createProductB() {return new ConcreteProductB2();}
}
示例代码说明:
ProductA
和ProductB
是一组共同的接口,描述了所要创建的对象应具有的行为。ConcreteProductA1
、ConcreteProductA2
、ConcreteProductB1
和ConcreteProductB2
是具体的实现类,分别实现ProductA
和ProductB
接口。AbstractFactory
是抽象工厂类,声明了创建一组对象的抽象方法createProductA()
和createProductB()
。ConcreteFactory1
和ConcreteFactory2
是具体的工厂类,分别负责创建一组相关的对象。
测试代码:
public class Main {public static void main(String[] args) {AbstractFactory factory1 = new ConcreteFactory1();ProductA productA1 = factory1.createProductA();productA1.operationA(); // 输出 "ConcreteProductA1 operationA"ProductB productB1 = factory1.createProductB();productB1.operationB(); // 输出 "ConcreteProductB1 operationB"AbstractFactory factory2 = new ConcreteFactory2();ProductA productA2 = factory2.createProductA();productA2.operationA(); // 输出 "ConcreteProductA2 operationA"ProductB productB2 = factory2.createProductB();productB2.operationB(); // 输出 "ConcreteProductB2 operationB"}
}
工厂模式通过封装对象的创建过程,将对象的具体类型与使用代码解耦,提供了一种灵活的方式来创建对象。它能够隐藏对象的创建细节,简化了客户端的代码,并且方便扩展和维护。工厂模式在实际应用中经常被使用,例如在 Java 中,Spring 框架的 BeanFactory 就是一个工厂模式的实现。
策略模式:
策略模式(Strategy Pattern)是一种行为型设计模式,它定义了一系列算法,并将每个算法封装在独立的类中,使得它们可以互相替换。策略模式使得算法可以独立于使用它的客户端而变化。
在策略模式中,有三个核心角色:
- 上下文(Context):上下文是客户端与策略模式之间的接口,它负责调用具体的策略对象来完成任务。
- 策略(Strategy):策略是定义了一组相同行为的接口或抽象类,它代表了一种算法或行为。
- 具体策略(Concrete Strategy):具体策略是策略接口的实现类,它实现了具体的算法或行为。
策略模式的优点包括:
- 提高代码的可扩展性:由于策略模式将算法封装在独立的类中,因此可以很容易地添加新的策略类来扩展系统的功能。
- 提供了一定程度的灵活性:客户端可以根据需要选择不同的策略来完成特定的任务,而不需要修改客户端的代码。
- 使代码易于理解和维护:策略模式将不同的算法分离开来,使得每个算法都具有清晰的目的和职责,使代码更加可读和易于维护。
下面是一个简单的策略模式的示例,以计算商品折扣价格为例:
// 策略接口
public interface DiscountStrategy {double applyDiscount(double price);
}// 具体策略类
public class NoDiscountStrategy implements DiscountStrategy {@Overridepublic double applyDiscount(double price) {return price;}
}public class FixedDiscountStrategy implements DiscountStrategy {private double discountAmount;public FixedDiscountStrategy(double discountAmount) {this.discountAmount = discountAmount;}@Overridepublic double applyDiscount(double price) {return price - discountAmount;}
}public class PercentageDiscountStrategy implements DiscountStrategy {private double discountPercentage;public PercentageDiscountStrategy(double discountPercentage) {this.discountPercentage = discountPercentage;}@Overridepublic double applyDiscount(double price) {return price * (1 - discountPercentage);}
}// 上下文类
public class Product {private String name;private double price;private DiscountStrategy discountStrategy;public Product(String name, double price, DiscountStrategy discountStrategy) {this.name = name;this.price = price;this.discountStrategy = discountStrategy;}public double getPriceAfterDiscount() {return discountStrategy.applyDiscount(price);}
}// 客户端代码
public class Main {public static void main(String[] args) {Product product1 = new Product("Product 1", 100.0, new NoDiscountStrategy());System.out.println("Price: " + product1.getPriceAfterDiscount()); // 输出 "Price: 100.0"Product product2 = new Product("Product 2", 100.0, new FixedDiscountStrategy(20.0));System.out.println("Price: " + product2.getPriceAfterDiscount()); // 输出 "Price: 80.0"Product product3 = new Product("Product 3", 100.0, new PercentageDiscountStrategy(0.25));System.out.println("Price: " + product3.getPriceAfterDiscount()); // 输出 "Price: 75.0"}
}
在上述示例中,策略模式通过定义 DiscountStrategy
接口和具体的策略类 NoDiscountStrategy
、FixedDiscountStrategy
和 PercentageDiscountStrategy
来实现不同的折扣算法。Product
类作为上下文类,它包含一个折扣策略对象,并通过调用 applyDiscount()
方法来计算最终的折扣价格。
通过使用策略模式,客户端可以根据具体的需求选择不同的折扣策略,而无需修改上下文类的代码。这样一来,当需要添加新的折扣策略时,只需要创建新的具体策略类并实现 DiscountStrategy
接口即可,而不会对原有的代码造成影响。这提高了代码的可扩展性和灵活性。
桥接模式:
桥接模式(Bridge Pattern)是一种结构型设计模式,它将抽象部分与实现部分分离,使它们可以独立变化而互不影响。桥接模式通过组合的方式,将抽象和实现解耦,从而可以在两者之间建立一座桥梁,使它们可以独立地进行变化和扩展。
在桥接模式中,有四个核心角色:
- 抽象类(Abstraction):定义了抽象部分的接口,维护一个指向实现类的引用。
- 具体实现类(Concrete Implementation):实现了实现部分的接口,并具体实现了其方法。
- 实现类接口(Implementation):定义了实现部分的接口,供具体实现类实现。
- 具体抽象类(Concrete Abstraction):继承自抽象类,实现了抽象部分的具体功能。
桥接模式的优点包括:
- 解耦抽象和实现:桥接模式通过将抽象部分和实现部分分离,使得它们可以独立变化,互不影响。
- 扩展性强:由于抽象部分和实现部分可以独立变化,因此很容易添加新的抽象类或实现类,扩展系统的功能。
- 隐藏实现细节:桥接模式可以隐藏实现部分的细节,使客户端只需要关注抽象部分即可。
下面是一个简单的桥接模式的示例,以形状和颜色为例:
// 颜色接口
public interface Color {void applyColor();
}// 红色类
public class RedColor implements Color {@Overridepublic void applyColor() {System.out.println("Applying red color");}
}// 蓝色类
public class BlueColor implements Color {@Overridepublic void applyColor() {System.out.println("Applying blue color");}
}// 形状抽象类
public abstract class Shape {protected Color color;public Shape(Color color) {this.color = color;}public abstract void applyColor();
}// 圆形类
public class Circle extends Shape {public Circle(Color color) {super(color);}@Overridepublic void applyColor() {System.out.print("Circle filled with ");color.applyColor();}
}// 正方形类
public class Square extends Shape {public Square(Color color) {super(color);}@Overridepublic void applyColor() {System.out.print("Square filled with ");color.applyColor();}
}// 客户端代码
public class Main {public static void main(String[] args) {Shape redCircle = new Circle(new RedColor());redCircle.applyColor(); // 输出 "Circle filled with Applying red color"Shape blueSquare = new Square(new BlueColor());blueSquare.applyColor(); // 输出 "Square filled with Applying blue color"}
}
在上述示例中,桥接模式通过将形状类和颜色类分离,使它们可以独立变化。Shape
是抽象类,它包含一个颜色对象,并定义了一个抽象方法 applyColor()
。Circle
和 Square
是具体抽象类,它们继承自 Shape
,并实现了 applyColor()
方法来应用颜色。
通过使用桥接模式,客户端可以选择不同的颜色来填充不同的形状,而不需要修改形状类的代码。这样一来,当需要添加新的形状或颜色时,只需要创建新的具体抽象类并传入相应的颜色对象即可,而不会对原有的代码造成影响。桥接模式提高了代码的灵活性和可扩展性。
责任链模式:
责任链模式(Chain of Responsibility Pattern)是一种行为设计模式,用于解耦发送者和接收者之间的关系。在责任链模式中,多个对象(处理者)依次处理请求,直到其中一个对象能够处理该请求为止。这些对象被串成一条链,请求沿着链传递,直到有一个处理者处理它为止。
责任链模式通常包括以下几个角色:
- 抽象处理者(Handler):定义一个处理请求的接口,通常包括一个处理请求的方法和一个设置下一个处理者的方法。
- 具体处理者(ConcreteHandler):实现抽象处理者接口,在处理请求时可以决定是否自己处理,或者将请求传递给下一个处理者。
- 客户端(Client):创建责任链,并向链头的处理者发送请求。
责任链模式的优点包括:
- 解耦发送者和接收者:发送者不需要知道具体的接收者,只需将请求发送给第一个处理者即可。
- 灵活性增强:可以动态地修改责任链中的处理者顺序或增加新的处理者,而不需要修改客户端代码。
- 可以动态地指定处理者:每个处理者都有机会处理请求,客户端可以根据需要灵活地指定处理者的顺序。
然而,责任链模式也存在一些缺点,包括:
- 请求可能未被处理:如果责任链没有正确配置或者最终没有处理请求的处理者,请求可能会被漏掉。
- 性能问题:请求需要沿着责任链传递,可能导致一定的性能损失,特别是在责任链较长时。
总的来说,责任链模式适合于多个对象可以处理同一请求,且客户端不需要明确指定处理者的情况下使用。通过合理设计责任链,可以更好地管理和处理请求,提高系统的灵活性和可扩展性。
假设我们有一个在线商城系统,当用户下单购买商品时,订单需要经过一系列的处理流程来验证和处理。这时候可以使用责任链模式来处理订单。
首先,我们定义一个抽象处理者(Handler)接口,其中包含处理请求的方法和设置下一个处理者的方法。
public interface OrderHandler {void handleOrder(Order order);void setNextHandler(OrderHandler handler);
}
然后,我们创建具体的处理者类,实现抽象处理者接口,并在处理请求时决定是否自己处理或者将请求传递给下一个处理者。
public class StockHandler implements OrderHandler {private OrderHandler nextHandler;public void handleOrder(Order order) {if (order.getStock() >= order.getQuantity()) {System.out.println("库存充足,可以继续处理订单。");// 处理订单逻辑...} else {System.out.println("库存不足,无法处理订单,将请求传递给下一个处理者。");passToNextHandler(order);}}public void setNextHandler(OrderHandler handler) {this.nextHandler = handler;}private void passToNextHandler(Order order) {if (nextHandler != null) {nextHandler.handleOrder(order);} else {System.out.println("没有合适的处理者,请求无法处理。");}}
}public class PaymentHandler implements OrderHandler {private OrderHandler nextHandler;public void handleOrder(Order order) {if (order.isPaymentValid()) {System.out.println("支付有效,可以继续处理订单。");// 处理订单逻辑...} else {System.out.println("支付无效,无法处理订单,将请求传递给下一个处理者。");passToNextHandler(order);}}public void setNextHandler(OrderHandler handler) {this.nextHandler = handler;}private void passToNextHandler(Order order) {if (nextHandler != null) {nextHandler.handleOrder(order);} else {System.out.println("没有合适的处理者,请求无法处理。");}}
}
最后,我们创建客户端代码,创建责任链,并向链头的处理者发送订单请求。
public class Client {public static void main(String[] args) {OrderHandler stockHandler = new StockHandler();OrderHandler paymentHandler = new PaymentHandler();stockHandler.setNextHandler(paymentHandler);Order order = new Order("ABC123", 10, 100.0);stockHandler.handleOrder(order);}
}
在上述例子中,订单首先会经过库存处理者(StockHandler),如果库存充足,则订单被处理;否则,请求会被传递给支付处理者(PaymentHandler),再次进行处理。如果没有合适的处理者,请求将无法被处理。
通过使用责任链模式,订单处理过程被解耦,每个处理者只需要关注自己的处理逻辑,增加新的处理者或者调整处理者的顺序也变得灵活和简单。
相关文章:

Java架构师之路九、设计模式:常见的设计模式,如单例模式、工厂模式、策略模式、桥接模式等
目录 常见的设计模式: 单例模式: 工厂模式: 策略模式: 桥接模式: 责任链模式: Java架构师之路八、安全技术:Web安全、网络安全、系统安全、数据安全等-CSDN博客Java架构师之路十、框架和工…...

【OpenAI官方课程】第三课:ChatGPT文本总结Summarizing
欢迎来到ChatGPT 开发人员提示工程课程(ChatGPT Prompt Engineering for Developers)!本课程将教您如何通过OpenAI API有效地利用大型语言模型(LLM)来创建强大的应用程序。 本课程由OpenAI 的Isa Fulford和 DeepLearn…...

跨越千年医学对话:用AI技术解锁中医古籍知识,构建能够精准问答的智能语言模型,成就专业级古籍解读助手(LLAMA)
介绍:首先在 Ziya-LLaMA-13B-V1基线模型的基础上加入中医教材、中医各类网站数据等语料库,训练出一个具有中医知识理解力的预训练语言模型(pre-trained model),之后在此基础上通过海量的中医古籍指令对话数据及通用指令…...

初识表及什么是数据表
一、了解表 1.1.概述 表是处理数据和建立关系型数据库及应用程序的基本单元,是构成数据库的基本元素之一,是数据库中数据组织并储存的单元,所有的数据都能以表格的形式组织,目的是可读性强。 1.2.表结构简述 一个表中包括行和列…...

使用Docker部署DataX3.0+DataX-Web
1、准备基础镜像,开通所需端口 先查看3306和9527端口是否开放,如果未开放先在防火墙添加 firewall-cmd --zonepublic --add-port3306/tcp --permanent firewall-cmd --zonepublic --add-port9527/tcp --permanent firewall-cmd --reload systemctl sto…...

庖丁解牛-二叉树的遍历
庖丁解牛-二叉树的遍历 〇、前言 01 文章内容 一般提到二叉树的遍历,我们是在说 前序遍历、中序遍历、后序遍历和层序遍历 或者说三序遍历层序遍历,毕竟三序和层序的遍历逻辑相差比较大下面讨论三序遍历的递归方法、非递归方法和非递归迭代的统一方法然…...

一文了解LM317T的引脚介绍、参数解读
LM317T是一种线性稳压器件,它具有稳定输出电压的特性。LM317T可以通过调整其输出电阻来确保输出电压的稳定性,因此被广泛应用于各种电子设备中。 LM317T引脚图介绍 LM317T共有3个引脚,分别是: 输入引脚(输入电压V_in&…...

【2024.02.22】定时执行专家 V7.0 发布 - TimingExecutor V7.0 Release - 龙年春节重大更新版本
目录 ▉ 新版本 V7.0 下载地址 ▉ V7.0 新功能 ▼2024-02-21 V7.0 - 更新日志▼ ▉ V7.0 新UI设计 ▉ 新版本 V7.0 下载地址 BoomWorks软件的最新版本-CSDN博客文章浏览阅读10w次,点赞9次,收藏41次。▉定时执行专家—毫秒精度、专业级的定时任务执行…...

☀️将大华摄像头画面接入Unity 【1】配置硬件和初始化摄像头
一、硬件准备 目前的设想是后期采用网口供电的形式把画面传出来,所以这边我除了大华摄像头还准备了POE供电交换机,为了方便索性都用大华的了,然后全都连接电脑主机即可。 二、软件准备 这边初始化摄像头需要用到大华的Configtool软件&#…...

直流电流电压变送器4-20mA 10V信号隔离转换模拟量精度变送器
品牌:泰华仪表 型号:TB-IP(U)XX 产地:中国大陆 省份:安徽省 地市:宿州市 颜色分类:4-20mA转4-20mA,4-20mA转0-10V,4-20mA转0-20mA,4-20mA转0-5V,0-20mA转0-20mA,0-20mA转4-20mA,0-20mA转0-10V,0-20mA转…...

1.1 计算机网络的概念、功能、组成和分类
文章目录 1.1 计算机网络的概念、功能、组成和分类(一)计算机网络的概念(二)计算机网络的功能(三)计算机网络的组成1.组成部分2.工作方式3.功能组成 (四)计算机网络的分类 总结 1.1 …...

排序算法整理
排序种类排序特性代码背景 基于插入的排序直接插入排序原理代码 折半查找排序2路查找排序希尔排序(shell) 缩小增量排序原理代码 基于交换的排序冒泡排序原理代码 快速排序(重要!)原理我的思考 代码 基于选择的排序(简单)选择排序…...

ONLYOFFICE 桌面应用程序 v8.0 发布:全新 RTL 界面、本地主题、Moodle 集成等你期待的功能来了!
目录 📘 前言 📟 一、什么是 ONLYOFFICE 桌面编辑器? 📟 二、ONLYOFFICE 8.0版本新增了那些特别的实用模块? 2.1. 可填写的 PDF 表单 2.2. 双向文本 2.3. 电子表格中的新增功能 单变量求解:…...

c语言---数组(超级详细)
数组 一.数组的概念二. 一维数组的创建和初始化2.1数组的创建2.2数组的初始化错误的初始化 2.3 数组的类型 三. 一维数组的使用3.1数组的下标3.2数组元素的打印3.2数组元素的输入 四. 一维数组在内存中的存储五. 二维数组的创建5.1二维数组的概念5.2如何创建二维数组 六.二维数…...

神经网络权重初始化
诸神缄默不语-个人CSDN博文目录 (如果只想看代码,请直接跳到“方法”一节,开头我介绍我的常用方法,后面介绍具体的各种方案) 神经网络通过多层神经元相互连接构成,而这些连接的强度就是通过权重ÿ…...

代码随想录训练营第三十九天|62.不同路径63. 不同路径 II
62.不同路径 1确定dp数组(dp table)以及下标的含义 从(0,0)出发到(i,j)有 dp[i][j]种路径 2确定递推公式 dp[i][j]dp[i-1][j]dp[i][j-1] 3dp数组如何初始化 for(int i0;i<m…...

学习大数据所需的java基础(5)
文章目录 集合框架Collection接口迭代器迭代器基本使用迭代器底层原理并发修改异常 数据结构栈队列数组链表 List接口底层源码分析 LinkList集合LinkedList底层成员解释说明LinkedList中get方法的源码分析LinkedList中add方法的源码分析 增强for增强for的介绍以及基本使用发2.使…...

Python 光速入门课程
首先说一下,为啥小编在即PHP和Golang之后,为啥又要整Python,那是因为小编最近又拿起了 " 阿里天池 " 的东西,所以小编又不得不捡起来大概五年前学习的Python,本篇文章主要讲的是最基础版本,所以比…...

解决vite打包出现 “default“ is not exported by “node_modules/...问题
项目场景: vue3tsvite项目打包 问题描述 // codemirror 编辑器的相关资源 import Codemirror from codemirror;error during build: RollupError: "default" is not exported by "node_modules/vue/dist/vue.runtime.esm-bundler.js", impor…...

c语言strtok的使用
strtok函数的作用为以指定字符分割字符串,含有两个参数,第一个函数为待分割的字符串或者空指针NULL,第二个参数为分割字符集。 对一个字符串首次使用strtok时第一个参数应该是待分割字符串,strtok以指定字符完成第一次分割后&…...

hash,以及数据结构——map容器
1.hash是什么? 定义:hash,一般翻译做散列、杂凑,或音译为哈希,是把任意长度的输入(又叫做预映射pre-image)通过散列算法变换成固定长度的输出, 该输出就是散列值。这种转换是一种压缩映射&…...

AIoT网关 人工智能物联网网关
AIoT(人工智能物联网)作为新一代技术的代表,正以前所未有的速度改变着我们的生活方式。在这个智能时代,AIoT网关的重要性日益凸显。它不仅是连接智能设备和应用的关键,同时也是实现智能化家居、智慧城市和工业自动化的必备技术。 一…...

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的鸟类识别系统(Python+PySide6界面+训练代码)
摘要:本文详细阐述了一个利用深度学习进行鸟类识别的系统,该系统集成了最新的YOLOv8算法,并与YOLOv7、YOLOv6、YOLOv5等先前版本进行了性能比较。该系统能够在图像、视频、实时视频流和批量文件中精确地识别和分类鸟类。文中不仅深入讲解了YO…...

核密度分析
一.算法介绍 核密度估计(Kernel Density Estimation)是一种用于估计数据分布的非参数统计方法。它可以用于多种目的和应用,包括: 数据可视化:核密度估计可以用来绘制平滑的密度曲线或热力图,从而直观地表…...

先进语言模型带来的变革与潜力
用户可以通过询问或交互方式与GPT-4这样的先进语言模型互动,开启通往知识宝库的大门,即时访问人类历史积累的知识、经验与智慧。像GPT-4这样的先进语言模型,能够将人类历史上积累的海量知识和经验整合并加以利用。通过深度学习和大规模数据训…...

重铸安卓荣光——上传图片组件
痛点: 公司打算做安卓软件,最近在研究安卓,打算先绘制样式 研究发现安卓并不像前端有那么多组件库,甚至有些基础的组件都需要自己实现,记录一下自己实现的组件 成品展示 一个上传图片的组件 可以选择拍照或者从相册中…...

Bert基础(四)--解码器(上)
1 理解解码器 假设我们想把英语句子I am good(原句)翻译成法语句子Je vais bien(目标句)。首先,将原句I am good送入编码器,使编码器学习原句,并计算特征值。在前文中,我们学习了编…...

Visual Studio快捷键记录
日常使用Visual Studio进行开发,记录一下常用的快捷键: 复制:CtrlC剪切:CtrlX粘贴:CtrlV删除:CtrlL撤销:CtrlZ反撤销:CtrlY查找:CtrlF/CtrlI替换:CtrlH框式选…...

分享84个Html个人模板,总有一款适合您
分享84个Html个人模板,总有一款适合您 84个Html个人模板下载链接:https://pan.baidu.com/s/1GXUZlKPzmHvxtO0sm3gHLg?pwd8888 提取码:8888 Python采集代码下载链接:采集代码.zip - 蓝奏云 学习知识费力气,收集…...

vue使用.sync和update实现父组件与子组件数据绑定的案例
在 Vue 中,.sync 是一个用于实现双向数据绑定的特殊修饰符。它允许父组件通过一种简洁的方式向子组件传递一个 prop,并在子组件中修改这个 prop 的值,然后将修改后的值反馈回父组件,实现双向数据绑定。 使用 .sync 修饰符的基本语…...