Java中常见的设计模式
Java中常见的设计模式
Java 中有 23 种经典设计模式,通常被分为三大类:创建型、结构型和行为型。每个设计模式都解决了不同类型的设计问题。以下是几种常见设计模式的总结,并附带了实际应用场景、示例代码和详细的注释说明。
一、创建型设计模式
这些设计模式关注对象的创建方式,避免在代码中直接创建对象。
1. 单例模式(Singleton Pattern)
-
定义:
单例模式确保一个类只有一个实例,并提供一个全局的访问点来获取该实例。 -
应用场景:
常用于配置类、数据库连接池、日志类等。 -
示例代码:
public class Singleton {// 1. 声明一个私有静态实例变量private static Singleton instance;// 2. 私有构造方法,防止外部创建多个实例private Singleton() {}// 3. 提供公共的静态方法,返回唯一实例public static Singleton getInstance() {if (instance == null) {synchronized (Singleton.class) { // 4. 双重检查锁定,确保线程安全if (instance == null) {instance = new Singleton(); // 5. 创建实例}}}return instance; // 6. 返回单例实例}
}
- 解释:
通过private构造器防止外部创建多个实例。
使用getInstance()方法获取唯一的实例,采用双重锁定来保证线程安全。
2. 工厂模式(Factory Pattern)
-
定义:
工厂模式提供一个创建对象的接口,但由子类决定实例化哪一个类。它让客户端无需知道具体的实现类,就可以创建出所需的对象。 -
应用场景:
用于创建对象的场景,尤其是类的实例化非常复杂或需要根据不同条件创建不同的对象时。 -
示例代码:
// 1. 定义产品接口
public interface Animal {void sound();
}// 2. 具体产品类:Dog
public class Dog implements Animal {public void sound() {System.out.println("Woof!");}
}// 3. 具体产品类:Cat
public class Cat implements Animal {public void sound() {System.out.println("Meow!");}
}// 4. 工厂类,负责创建产品实例
public class AnimalFactory {public Animal createAnimal(String type) {if ("dog".equalsIgnoreCase(type)) {return new Dog(); // 5. 创建Dog对象} else if ("cat".equalsIgnoreCase(type)) {return new Cat(); // 6. 创建Cat对象}return null; // 7. 返回null表示无法创建对象}
}// 8. 客户端代码
public class Client {public static void main(String[] args) {AnimalFactory factory = new AnimalFactory(); // 9. 创建工厂对象Animal dog = factory.createAnimal("dog"); // 10. 通过工厂创建Dog对象dog.sound(); // 11. 输出:Woof!Animal cat = factory.createAnimal("cat"); // 12. 通过工厂创建Cat对象cat.sound(); // 13. 输出:Meow!}
}
- 解释:
AnimalFactory负责根据参数创建不同的Animal类型对象,避免客户端直接依赖具体类。
3. 抽象工厂模式(Abstract Factory Pattern)
- 定义:
抽象工厂模式提供一个接口,用来创建一系列相关或相互依赖的对象,而无需指定具体的类。 - 应用场景:
需要创建一系列相关的对象,而无需指定具体类。
用于产品族的创建,确保一系列相关的对象符合某种约定。 - 示例代码:
// 1. 定义抽象产品接口:ProductA
public interface ProductA {void doSomething();
}// 2. 具体产品A1
public class ProductA1 implements ProductA {public void doSomething() {System.out.println("ProductA1 does something");}
}// 3. 具体产品A2
public class ProductA2 implements ProductA {public void doSomething() {System.out.println("ProductA2 does something");}
}// 4. 定义抽象产品接口:ProductB
public interface ProductB {void doSomethingElse();
}// 5. 具体产品B1
public class ProductB1 implements ProductB {public void doSomethingElse() {System.out.println("ProductB1 does something else");}
}// 6. 具体产品B2
public class ProductB2 implements ProductB {public void doSomethingElse() {System.out.println("ProductB2 does something else");}
}// 7. 定义抽象工厂接口
public interface AbstractFactory {ProductA createProductA();ProductB createProductB();
}// 8. 具体工厂A1
public class ConcreteFactoryA1 implements AbstractFactory {public ProductA createProductA() {return new ProductA1(); // 9. 返回ProductA1}public ProductB createProductB() {return new ProductB1(); // 10. 返回ProductB1}
}// 10. 具体工厂A2
public class ConcreteFactoryA2 implements AbstractFactory {public ProductA createProductA() {return new ProductA2(); // 11. 返回ProductA2}public ProductB createProductB() {return new ProductB2(); // 12. 返回ProductB2}
}// 13. 客户端代码
public class Client {public static void main(String[] args) {AbstractFactory factory = new ConcreteFactoryA1(); // 14. 使用工厂A1ProductA productA = factory.createProductA(); // 15. 创建ProductAproductA.doSomething(); // 16. 输出:ProductA1 does somethingProductB productB = factory.createProductB(); // 17. 创建ProductBproductB.doSomethingElse(); // 18. 输出:ProductB1 does something else}
}
- 解释:
AbstractFactory定义了两个产品的创建方法,具体工厂实现不同产品的创建。
ConcreteFactoryA1和ConcreteFactoryA2根据需要创建一系列产品。
tips: Java中工厂模式和抽象工厂模式的区别
二、结构型设计模式
这些设计模式主要关注类和对象的组合,帮助我们设计灵活、易于扩展和维护的系统。
4. 适配器模式(Adapter Pattern)
- 定义:
适配器模式通过将一个类的接口转换成客户端期望的另一个接口,使得原本由于接口不兼容而不能一起工作的类可以一起工作。 - 应用场景:
用于将一个类的接口转换为客户期望的另一个接口,常见于第三方库的集成时。 - 示例代码:
// 1. 目标接口
public interface Target {void request();
}// 2. 适配者类,已经存在的接口
public class Adaptee {public void specificRequest() {System.out.println("Specific request");}
}// 3. 适配器类,实现目标接口,并委托调用适配者的方法
public class Adapter implements Target {private Adaptee adaptee;public Adapter(Adaptee adaptee) {this.adaptee = adaptee; // 4. 构造方法,传入适配者}public void request() {adaptee.specificRequest(); // 5. 调用适配者的特定方法}
}// 6. 客户端代码
public class Client {public static void main(String[] args) {Adaptee adaptee = new Adaptee(); // 7. 创建适配者对象Target target = new Adapter(adaptee); // 8. 使用适配器target.request(); // 9. 输出:Specific request}
}
- 解释:
Target是客户期望的接口,Adaptee是已经存在的接口,通过Adapter类适配两者的差异。
5. 桥接模式(Bridge Pattern)
-
定义:
桥接模式通过将抽象部分和实现部分分离,使它们可以独立变化。它主要用于接口和实现的解耦。 -
应用场景:
用于将抽象部分与实现部分分离,使它们可以独立变化。常用于图形绘制、设备控制等场景。 -
示例代码:
// 1. 抽象类
public abstract class Shape {protected DrawingAPI drawingAPI; // 2. 依赖抽象的实现类public Shape(DrawingAPI drawingAPI) {this.drawingAPI = drawingAPI;}public abstract void draw(); // 3. 抽象方法
}// 4. 具体形状类:Circle
public class Circle extends Shape {private double x, y, radius;public Circle(double x, double y, double radius, DrawingAPI drawingAPI) {super(drawingAPI); // 5. 调用父类构造器,传入实现类this.x = x;this.y = y;this.radius = radius;}public void draw() {drawingAPI.drawCircle(x, y, radius); // 6. 委托给实现类}
}// 7. 抽象实现类
public interface DrawingAPI {void drawCircle(double x, double y, double radius); // 8. 绘制圆的方法
}// 9. 具体实现类:DrawingAPI1
public class DrawingAPI1 implements DrawingAPI {public void drawCircle(double x, double y, double radius) {System.out.println("Drawing Circle using DrawingAPI1 at (" + x + ", " + y + ") with radius " + radius);}
}// 10. 具体实现类:DrawingAPI2
public class DrawingAPI2 implements DrawingAPI {public void drawCircle(double x, double y, double radius) {System.out.println("Drawing Circle using DrawingAPI2 at (" + x + ", " + y + ") with radius " + radius);}
}// 11. 客户端代码
public class Client {public static void main(String[] args) {Shape shape1 = new Circle(1, 2, 3, new DrawingAPI1()); // 12. 使用API1shape1.draw(); // 13. 输出:Drawing Circle using DrawingAPI1 at (1, 2) with radius 3Shape shape2 = new Circle(4, 5, 6, new DrawingAPI2()); // 14. 使用API2shape2.draw(); // 15. 输出:Drawing Circle using DrawingAPI2 at (4, 5) with radius 6}
}
- 解释:
Shape类定义了抽象的draw()方法,依赖于DrawingAPI接口。
Circle类实现了具体的图形操作,将绘制行为委托给具体的实现类(DrawingAPI1或DrawingAPI2)。
三、行为型设计模式
6. 策略模式(Strategy Pattern)
-
定义:
策略模式定义了一系列算法,将每一个算法封装起来,并使它们可以互换。它让算法的变化独立于使用算法的客户。 -
应用场景:
策略模式用于定义一系列算法或策略,并允许在运行时切换策略。策略模式可以让你避免使用大量的 if-else 或 switch 语句来处理不同的行为。 -
示例代码:
假设你在开发一个支付系统,需要根据不同的支付方式(如支付宝、微信支付、信用卡支付)选择不同的支付策略。
// 策略接口,定义支付行为
interface PaymentStrategy {void pay(int amount);
}// 具体策略:支付宝支付
class AlipayPayment implements PaymentStrategy {@Overridepublic void pay(int amount) {System.out.println("Using Alipay to pay " + amount + " units.");}
}// 具体策略:微信支付
class WeChatPayment implements PaymentStrategy {@Overridepublic void pay(int amount) {System.out.println("Using WeChat to pay " + amount + " units.");}
}// 具体策略:信用卡支付
class CreditCardPayment implements PaymentStrategy {@Overridepublic void pay(int amount) {System.out.println("Using Credit Card to pay " + amount + " units.");}
}// 上下文类,持有一个策略对象
class PaymentContext {private PaymentStrategy paymentStrategy;// 设置支付策略public void setPaymentStrategy(PaymentStrategy paymentStrategy) {this.paymentStrategy = paymentStrategy;}// 执行支付public void executePayment(int amount) {paymentStrategy.pay(amount);}
}// 客户端代码
public class StrategyPatternExample {public static void main(String[] args) {// 创建上下文对象PaymentContext paymentContext = new PaymentContext();// 设置支付宝支付策略paymentContext.setPaymentStrategy(new AlipayPayment());paymentContext.executePayment(100); // 输出: Using Alipay to pay 100 units.// 设置微信支付策略paymentContext.setPaymentStrategy(new WeChatPayment());paymentContext.executePayment(200); // 输出: Using WeChat to pay 200 units.// 设置信用卡支付策略paymentContext.setPaymentStrategy(new CreditCardPayment());paymentContext.executePayment(300); // 输出: Using Credit Card to pay 300 units.}
}
- 解释:
- PaymentStrategy 是一个策略接口,定义了支付方法。
- AlipayPayment、WeChatPayment、CreditCardPayment 是具体的支付策略,分别实现了 PaymentStrategy 接口。
- PaymentContext 类持有一个支付策略对象,并在运行时动态改变使用的支付策略。
- 在客户端代码中,使用不同的支付策略(支付宝、微信、信用卡)来执行支付。
7. 观察者模式(Observer Pattern)
-
定义:
观察者模式定义了对象间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会自动更新。 -
应用场景:
观察者模式用于一对多的场景,一个对象的状态改变时,所有依赖于它的对象都会得到通知并自动更新。比如在实现事件监听机制时,常常使用观察者模式。 -
示例代码:
假设你在开发一个天气预报系统,当天气变化时,所有的观察者(如显示板、手机应用等)都需要得到通知并更新天气信息。
import java.util.ArrayList;
import java.util.List;// 观察者接口,定义更新方法
interface Observer {void update(String weather);
}// 具体观察者:显示板
class DisplayBoard implements Observer {@Overridepublic void update(String weather) {System.out.println("DisplayBoard updated with weather: " + weather);}
}// 具体观察者:手机应用
class MobileApp implements Observer {@Overridepublic void update(String weather) {System.out.println("MobileApp updated with weather: " + weather);}
}// 被观察者:天气数据
class WeatherData {private List<Observer> observers = new ArrayList<>();private String weather;// 添加观察者public void addObserver(Observer observer) {observers.add(observer);}// 移除观察者public void removeObserver(Observer observer) {observers.remove(observer);}// 设置天气信息并通知所有观察者public void setWeather(String weather) {this.weather = weather;notifyObservers();}// 通知所有观察者更新private void notifyObservers() {for (Observer observer : observers) {observer.update(weather);}}
}// 客户端代码
public class ObserverPatternExample {public static void main(String[] args) {WeatherData weatherData = new WeatherData();// 创建观察者DisplayBoard displayBoard = new DisplayBoard();MobileApp mobileApp = new MobileApp();// 添加观察者weatherData.addObserver(displayBoard);weatherData.addObserver(mobileApp);// 改变天气信息,通知所有观察者weatherData.setWeather("Sunny"); // 输出: DisplayBoard updated with weather: Sunny// 输出: MobileApp updated with weather: Sunny// 修改天气信息,观察者会自动更新weatherData.setWeather("Rainy"); // 输出: DisplayBoard updated with weather: Rainy// 输出: MobileApp updated with weather: Rainy}
}
- 解释:
- Observer 是观察者接口,定义了 update 方法来接收通知。
- DisplayBoard 和 MobileApp 是具体的观察者,分别实现了 Observer 接口。
- WeatherData 是被观察者,保存了观察者的列表,并在天气变化时通知所有观察者。
- 在客户端代码中,当天气信息发生变化时,所有已注册的观察者都会接收到更新通知。
8. 命令模式(Command Pattern)
- 定义:
命令模式将请求封装为对象,从而使用户可以通过不同的请求对客户端进行参数化。 - 应用场景:
命令模式将请求封装成对象,从而使你可以用不同的请求、队列和日志来参数化其他对象。它通常用于需要进行操作的场景,尤其是按钮点击、任务调度等。 - 示例代码:
假设你在设计一个遥控器系统,每个按钮上绑定不同的命令操作(如开灯、关灯)。
// 命令接口,定义执行操作的方法
interface Command {void execute();
}// 具体命令:开灯命令
class TurnOnLightCommand implements Command {private Light light;public TurnOnLightCommand(Light light) {this.light = light;}@Overridepublic void execute() {light.turnOn();}
}// 具体命令:关灯命令
class TurnOffLightCommand implements Command {private Light light;public TurnOffLightCommand(Light light) {this.light = light;}@Overridepublic void execute() {light.turnOff();}
}// 接收者类:灯
class Light {public void turnOn() {System.out.println("The light is on.");}public void turnOff() {System.out.println("The light is off.");}
}// 调用者类:遥控器
class RemoteControl {private Command command;public void setCommand(Command command) {this.command = command;}public void pressButton() {command.execute();}
}// 客户端代码
public class CommandPatternExample {public static void main(String[] args) {Light light = new Light();Command turnOn = new TurnOnLightCommand(light);Command turnOff = new TurnOffLightCommand(light);RemoteControl remoteControl = new RemoteControl();// 按下开灯按钮remoteControl.setCommand(turnOn);remoteControl.pressButton(); // 输出: The light is on.// 按下关灯按钮remoteControl.setCommand(turnOff);remoteControl.pressButton(); // 输出: The light is off.}
}
- 解释:
- Command 是命令接口,定义了 execute 方法来执行具体操作。
- TurnOnLightCommand 和 TurnOffLightCommand 是具体命令类,实现了 Command 接口,封装了开灯和关灯操作。
- Light 是接收者类,实际执行开关灯操作。
- RemoteControl 是调用者类,接收命令并调用命令的 execute 方法。
9. 状态模式(State Pattern)
-
定义:
状态模式允许一个对象在其内部状态发生改变时改变它的行为,看起来像是改变了其类。 -
应用场景:
状态之间的转换依赖于外部条件,常用于有限状态机(例如游戏中的状态机:开始、暂停、结束)。
10. 责任链模式(Chain of Responsibility Pattern)
-
定义:
责任链模式使得多个对象有机会处理请求,从而避免了请求的发送者和接收者之间的直接耦合。将请求沿着责任链传递,直到有一个对象处理它。 -
应用场景:
多个处理对象可能处理同一个请求时,比如日志过滤器、权限验证等。
11. 中介者模式(Mediator Pattern)
-
定义:
中介者模式通过定义一个中介对象来封装一组对象之间的交互,避免了对象间的直接引用,使得松耦合的设计变得更加容易。 -
应用场景:
多个类之间有复杂的交互时,使用中介者来集中管理这些交互,例如聊天室应用中的用户之间的消息传递。
12. 备忘录模式(Memento Pattern)
-
定义:
备忘录模式允许在不暴露对象实现细节的情况下保存和恢复对象的内部状态。 -
应用场景:
在需要保存对象历史状态的场景中,比如撤销操作、保存游戏进度等。
13. 模板方法模式(Template Method Pattern)
-
定义:
模板方法模式定义了一个操作中的算法的骨架,将一些步骤的实现延迟到子类中。子类可以在不改变算法结构的情况下重新定义该算法的某些特定步骤。 -
应用场景:
一些固定的操作流程和步骤,但某些步骤需要子类提供具体实现时。
14. 访问者模式(Visitor Pattern)
-
定义:
访问者模式将数据结构和操作分开,使得可以在不修改数据结构的情况下添加新的操作。 -
应用场景:
对多个类操作进行扩展,但不想修改类的实现时,常用于编译器、图形结构等。
四、总结
这些行为型设计模式能够让你灵活地处理对象之间的交互,特别是在复杂系统中,能够有效解耦和简化代码。
相关文章:
Java中常见的设计模式
Java中常见的设计模式 Java 中有 23 种经典设计模式,通常被分为三大类:创建型、结构型和行为型。每个设计模式都解决了不同类型的设计问题。以下是几种常见设计模式的总结,并附带了实际应用场景、示例代码和详细的注释说明。 一、创建型设计…...
nltk 是怎么和 Transformers(比如 BERT 模型)联动来处理文本的
🧠 一句话解释nltk: nltk 是一个用于自然语言处理(NLP)的 Python 库,功能包括分词、词性标注、命名实体识别、文本分类等。 全称是:Natural Language Toolkit(自然语言工具包) &…...
项目日志配置模板示例
1.新增application.properties配置 logging.configclasspath:logback-spring.xml spring.profiles.activedev 将项目部署到服务器时需要将dev修改为test后再进行打包部署 2.新增logback-spring.xml <?xml version"1.0" encoding"UTF-8"?> <…...
sql server统计小时数据中每日最大风速及风速对应的风向
客户提出一个需求,有历年逐小时的风速、风向资料,想获取历年最大的风速及风速对应的风向值,通过sql 怎么实现,这个统计,我认为主要考虑一个问题,就是数据重复性,所以我采用以下方法实现…...
【SQL】MySql常见的性能优化方式
MySQL性能优化的常用方式及对比说明 一、引言二、MySQL性能优化的常用方式及对比说明1. 索引优化1.1 合理创建索引1.2 覆盖索引1.3 索引下推 2. SQL语法优化2.1 避免低效操作2.2 分页优化2.3 JOIN优化 3. 配置与架构优化3.1 参数调优3.2 读写分离与分库…...
Prometheus实现负载均衡并将多个实例数据汇总到一个主Prometheus
一、Prometheus实现负载均衡策略原理 要实现 Prometheus 的负载均衡并将多个 Prometheus 实例的数据汇总到一个主 Prometheus 实例中,可以结合 Prometheus 联邦(Federation) 和 负载均衡器 来进行配置。 这种方法的核心是在主 Prometheus 实例…...
力扣 — — 最长公共子序列
力扣 — — 最长公共子序列 最长公共子序列 题源:1143. 最长公共子序列 - 力扣(LeetCode) 题目: 分析: 一道经典的题目:最长公共子序列(LCS) 题目大意:求两个字符串的最长公共序列。 算法&…...
通过AWS EKS 生成并部署容器化应用
今天给大家分享一个实战例子,如何在EKS上创建容器化应用并通过ALB来发布。先介绍一下几个基本概念: IAM, OpenID Connect (OIDC) 2014 年,AWS Identity and Access Management 增加了使用 OpenID Connect (OIDC) 的联合身份支持。此功能允许…...
GNSS静态数据处理
1 安装数据处理软件:仪器之星(InStar )和 Trimble Business Center 做完控制点静态后,我们需要下载GNSS数据,对静态数据进行处理。在处理之前需要将相关软件在自己电脑上安装好: 仪器之星(InS…...
NVIDIA H100 vs A100:新一代GPU架构性能对比分析
一、核心架构演进对比 Ampere架构(A100)采用台积电7nm工艺,集成540亿晶体管,配备6,912个CUDA核心和432个第三代Tensor Core,支持FP16、TF32和INT8精度计算。其显存子系统采用HBM2e技术,80GB版本带宽可…...
AI图像生成
要通过代码实现AI图像生成,可以使用深度学习框架如TensorFlow、PyTorch或GANs等技术。下面是一个简单的示例代码,演示如何使用GANs生成手写数字图像: import torch import torchvision import torchvision.transforms as transforms import …...
计算机考研一战上岸宁波大学经验分享
目录 话不多说先上分数 个人介绍 政治 英语二 数学二 408 复试 话不多说先上分数 初试排名15/65 复试79.81分,复试排名13/65 总成绩13/65,研招网招考50人 (均为公开数据,非泄露复试信息) 个人介绍 本人山东…...
泛微ECOLOGY9 记 数据展现集成 自定义开窗测试中对SQL 的IN语法转换存在BUG
背景 搭建流程时,需将明细表1中的合同字段 供明细表2中的合同开窗查询使用。 最终实现如下图: 选择 发票号时,自动带出明细表1中的采购合同号清单,然后在明细表2中开窗采购合同号时,只跳出明细表1中有的采购合同号&am…...
【Nginx】Nginx代理Tomcat配置及404问题解决
当Tomcat返回HTTP 404未找到错误时,可以通过以下两种方式设置跳转到指定地址: ① 在Tomcat应用内部配置错误页面跳转(直接修改Tomcat的Web应用配置) ② 在Nginx反向代理层拦截404错误并跳转(无需修改Tomcat,…...
【Vue】案例——To do list:
【Vue】案例——To do list: 一、案例介绍:二、效果展示(如图)三、主要功能:四、技术要点:补充:【Vue】Vue模板语法(点击可跳转)补充:【Vue】数据绑定(单双向)…...
JVM不同环境不同参数配置文件覆盖
背景 需要在启动Java服务并且参数不同的场景,例如端口号在yml中的配置是这样的: server:port: 9100 覆盖配置对应JVM参数: java -jar xxxx.jar -Dserver.port12306 [JVM其他参数] 这样12306就会覆盖掉9100端口的配置作为启动配置 IDE…...
游戏引擎学习第215天
总结并为今天做铺垫 今天的工作内容是解决调试系统中的一个小问题。昨天我们已经完成了大部分的调试系统工作,但还有一个小部分没有完全处理,那就是关于如何层次化组织数据的问题。我们遇到的一个问题是,演示代码中仍有一个尚未解决的部分&a…...
C语言--求n以内的素数(质数)
求n以内的素数,可以用试除法或者埃拉托斯特尼筛法(埃氏筛法) 输入:数字n 输出:n以内所有的素数 不管是哪个方法,都有一个数学结论可以减少循环次数: 如果有一个数不是质数,那么它至…...
多版本go冲突问题
今天执行go build时遇到一个报错: compile: version “go1.22.7 (Red Hat 1.22.7-1.moduleel8.10.0700fd5cfc7a)” does not match go tool version “go1.23.4” 结果一查 which -a go 发现 当前系统居然有四个不同的位置都安装了go 于是先看go version…...
Windows 10系统出现无法使用键鼠的问题
有一位系统之家的小伙伴在升级Windows 10系统电脑的时候,出现键盘鼠标不能正常工作打问题,其实,遇到这个问题,有时只需重新启动计算机或断开连接并重新连接鼠标或键盘可以提供帮助,如果没有,可以看看下面系…...
NFC 数据传输
前言 初次接触NFC协议,很多人都会感觉困惑,搜索相关资料,大多数都介绍协议的理论及应用领域,数据传输的内容却很少,但对与开发人员来说,除了理论知识外,数据传输也是非常重要环节,尤…...
基于Streamlit的智能创业计划生成器开发实践
一、应用概述 在数字经济时代,创业者亟需高效工具进行系统化的商业规划。本文介绍的智能创业计划生成器基于Streamlit框架构建,整合了财务建模、时间轴规划、智能文档生成等核心功能。该工具通过模块化设计实现了九大创业要素的系统化配置,显…...
蓝桥杯单片机刷题——按键控制距离显示精度
设计要求 驱动超声波传感器,启动距离测量功能,并将其结果显示到数码管上,距离数据单位为m。 按键“S4”定义为“切换”按键,通过此按键切换距离的显示精度(一位或两位小数)。切换顺序如图所示。 数码管显示格式如下图…...
c++拷贝构造函数(深浅拷贝)+运算符重载
1拷贝构造函数 1.1定义 只有一个形参,且该形参是对本类类型对象的引用(一般用const 修饰),在用已经存在的类类型对象穿件新对象是由编译器自动调用。(是一种特殊构造,即初始化一个一模一样的新对象&#…...
操作系统 3.5-内存换入-请求调页
案例分析内存换入 内存换入分析: 内存换入(Swapping)是指操作系统将不常使用的内存页从物理内存(RAM)移动到磁盘上的交换空间(Swap Space),以释放物理内存供其他进程使用。当需要访…...
stm32工程,拷贝到另一台电脑编译,错误提示头文件找不到cannot open source input file “core_cm4.h”
提示 cannot open source input file “core_cm4.h” ,找不到 [ core_cm4.h ] 这个头文件 . 于是我在原电脑工程文件里找也没有找到这个头文件 接下来查看原电脑keil的头文件引入配置,发现只引入了工程文件下的头文件, 那么core_cm4.h到底哪里来的? (到现在我也不清楚怎…...
使用platformio如何定位hard fault错误
这里写自定义目录标题 前言过程记录结语前言 hard fault是单片机开发过程中经常会遇到的问题,通常是内存溢出、野指针访问等导致,对于有经验的工程师,在代码改动不大的情况下,一般可以通过代码审查定位到问题原因,但也有很多情况下需要借助调试工具进行定位,像Keil就有比…...
全局异常处理器的基本使用
那使用全局异常处理器可以么? 是的,使用全局异常处理器是一个非常好的选择,因为它可以将异常处理逻辑集中化,避免在 Service 层或 Controller 层中重复编写异常处理代码。以下是使用全局异常处理器来处理添加用户时 username 唯一…...
python入门:简单介绍和python和pycharm软件安装/学习网址/pycharm设置(改成中文界面,主题,新建文件)
Python 目前是 AI 开发的首选语言 软件安装 python解释器 官网下载 Python |Python.org 勾选 Add python.exe to PATH 将python.exe添加到PATH 勾选这个选项会将Python的可执行文件路径添加到系统的环境变量PATH中。这样做的好处是,你可以在命令行中从任何位置直…...
众趣科技助力商家“以真示人”,让消费场景更真实透明
在当今的消费环境中,消费者权益保护问题日益凸显。无论是网购商品与实物不符、预定酒店民宿与图文描述差异大,还是游览景区遭遇“照骗”,这些问题不仅让消费者在消费和决策过程中倍感困扰,也让商家面临信任危机。 消费者在享受便…...
【Redis】string类型
目录 1、介绍2、底层实现【1】SDS【2】int编码【3】embstr编码【4】raw编码【5】embstr和raw的区别 3、常用指令【1】字符串基本操作:【2】批量操作【3】计数器【4】过期时间【5】不存在就插入 4、使用场景 1、介绍 string是redis中最简单的键值对形式,…...
EPLAN许可证更新教程
随着电气设计软件的不断更新和优化,确保您的EPLAN许可证始终是最新版本对于顺畅的项目管理至关重要。本文将为您提供一份详尽的EPLAN许可证更新教程,帮助您轻松完成更新操作,确保您的软件始终保持最佳状态。 一、为什么需要更新EPLAN许可证&…...
学习笔记五——Rust 控制流全解析
📚 目录 什么是控制流?Rust 有什么特别?if 表达式完整语法loop / while / for 三种循环写法match 表达式 _ 通配符深入解释if let 表达式用法与场景Option、Some、None 全面通俗讲解 "Tom" 和 "Tom".to_string() 有啥本…...
远程桌面协议(RDP)详解:原理、优势与局限和优化方案分享
文章目录 导言一. RDP的工作原理二. RDP的优势三. RDP的局限性四. RDP的优化与替代方案五. 内网穿透远程访问总结 导言 远程桌面协议(RDP)是一种微软开发的专有协议,允许用户通过网络连接到另一台计算机,并像操作本地计算机一样进行操作。它广泛应用于远…...
Linux 系统管理常用命令
以下是 Linux 系统管理常用命令 的详细介绍,涵盖 IP地址查看、端口管理、进程监控 等核心操作,并附上实际示例: 一、查看网卡 IP 地址 1. 使用 ip 命令 # 查看所有网络接口信息(包括 IP 地址) ip addr show# 查看特定…...
蓝桥杯篇---客观题
文章目录 前言 前言 本文简单介绍了蓝桥杯中客观题各个部分的知识点。 一、单片机相关 IAP15F2K61S2单片机的定时器0具有4种工作模式,当采用外部12MHz晶振时,定时器最大定时长度65535us。8051单片机的P0口,当使用外部存储器时它是一个传输低…...
RK3568 基于Gstreamer的多媒体调试记录
文章目录 1、环境介绍2、概念理清3、提前准备4、GStreamer编译5、GStreamer基础介绍6、视频播放初体验7、视频硬编码7.1、h2647.2、h265 8、视频硬解码8.1、解码视频并播放解码视频并播放带音频 1、环境介绍 硬件:飞凌ok3568-c开发板 软件:原厂rk356x …...
ZYNQ笔记(五):AXI GPIO 中断
版本:Vivado2020.2(Vitis) 任务:使用 AXI GPIO IP 核以中断方式实现按键 KEY 控制 LED 亮灭翻转(两个都在PL端) 目录 一、介绍 二、硬件设计 三、软件设计 四、效果 一、介绍 AXI GPIO 中断通常…...
C++23 多维下标运算符:探索 P2128R6 提案
文章目录 一、背景与动机二、语法与实现2.1 语法2.2 实现方式 三、应用场景3.1 多维数组3.2 自定义数据结构3.3 并行计算 四、性能影响4.1 编译时优化4.2 自定义数据结构的优化 五、总结 C23 引入了许多新特性,其中之一便是多维下标运算符(P2128R6&#…...
原理图设计准备:页面栅格模板应用设置
一、页面大小的设置 (1)单页原理图页面设置 首先,选中需要更改页面尺寸的那一页原理图,鼠标右键,选择“Schmatic Page Properties”选项,进行页面大小设置。 (2)对整个原理图页面设…...
LeeCode 409.最长回文串
给定一个包含大写字母和小写字母的字符串 s ,返回 通过这些字母构造成的 最长的 回文串 的长度。 在构造过程中,请注意 区分大小写 。比如 "Aa" 不能当做一个回文字符串。 示例 1: 输入:s "abccccdd" 输出:7 解释: 我们可以构造的…...
保护PCBA的不同方法:喷三防漆 vs 镀膜
PCBA(印刷电路板组件)的防护工艺中,喷三防漆和镀膜(如Parylene气相沉积)是两种常见技 术。它们在防护目的上类似,但在具体实现方式和应用场景上有显著差异。以下从外观、工艺、性 能、物理性质和成本五个…...
XILINX FPGA万兆光电口PXIE板卡设计
主要性能指标 1、 FPGA 型号: XC7K325-TFFG676-2 ; 2、 网络端口速率 : 10Gbps/1Gbps/2.5Gbps ; 3、 网络端口形式 : 3 路 SFP 万兆光电口 ; 4、 内存数量: 4Gb 4 ; 5、 内存带宽&…...
LangChain4j实战-Java AI应用开源框架之LangChain4j和Spring AI
今天这篇文章我来分享LangChain4j实战-Java AI应用开源框架之LangChain4j和Spring AI。 在贝恩聊架构AI专栏中通过学习如何使用Java相关AI应用开源框架,到后续开发企业级Java AI应用,将大型语言模型和AI工具集成到现有系统中。我们将重点介绍如何使用Sp…...
机器学习十大算法全解析机器学习,作为人工智能的基石,涵盖了众多高效的算法。今天,我们就来深入探讨其中的十大核心算法!
1️⃣ 线性回归:通过最小化误差的平方和来寻找最佳函数匹配。 2️⃣ 逻辑回归:用于分类问题,通过逻辑函数来预测事件发生的概率。 3️⃣ 决策树:基于特征选择和阈值来构建树形结构,用于分类和回归。 4️⃣ 朴素贝叶…...
day26图像处理OpenCV
文章目录 一、OpenCV1.介绍2.下载3.图像的表示4.图像的基本操作4.1图片读取或创建4.1.1读取4.1.2创建 4.2创建窗口4.3显示图片4.3.1设置读取的图片4.3.2设置显示多久4.3.3释放 4.4.保存图片4.5图片切片(剪裁)4.6图片大小调节 5.在图像中绘值5.1绘制直线5…...
怎么查询SQL Server AlwaysOn
1. SQL Server AlwaysOn 是什么? SQL Server AlwaysOn 是 Microsoft 提供的高可用性(High Availability, HA)和灾难恢复(Disaster Recovery, DR)解决方案,包含以下两个核心技术: 组件描述故障…...
10分钟做了一个投资回报计算器,欢迎大家使用
一、背景 今天突然想算一下1万本金,2%利率存2年情况下的投资回报收益情况,但是发现手上没有计算器,想着自己做一个网页简单实现一下,于是有了这个小工具(FutureValueCalculator——未来价值计算器)。 二、…...
报错:mount: unknown filesystem type ‘vfat’
服务器重启之后 进入 Ctrl D 界面 界面报错是 FAILED to mount /boot/efi 输入密码进去之后 (py38) [rootlocalhost data]# lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS sda 8:0 0 1.5T 0 disk ├─sda1 8:1 0 50M 0 part /bo…...
Java学习手册:面向对象编程核心概念
面向对象编程(OOP)是Java语言的核心编程范式,它强调通过对象之间的交互来实现程序功能。OOP的核心思想是将现实世界中的事物抽象为对象,通过对象的属性和行为来描述和操作这些事物。本文将深入探讨Java中面向对象编程的三大核心概…...