Java八种常见的设计模式
一、单例模式
单例模式是(Singleton Pattern)Java中最常用的设计模式之一,它保证一个类仅有一个实例,并提供一个全局访问点。
实现单例模式的核心是将类的构造方法私有化,以防止外部直接通过构造函数创建实例。同时,类内部需要提供一个静态方法或变量来获取该类的唯一实例。单例模式分为饿汉式单例(立即加载)和懒汉式单例(延迟加载)。
饿汉式单例:线程安全
public class Singleton1 {/*** 在类的内部可以访问私有结构,所以可以在类的内部产生实例化对象*/private static Singleton1 instance = new Singleton1();/*** private 声明构造*/private Singleton1() {}/*** 返回对象实例*/public static Singleton1 getInstance() {return instance;}
}
懒汉式单例:
当多个线程并发执行 getInstance 方法时,懒汉式会存在线程安全问题,所以用到了 synchronized 来实现线程的同步,当一个线程获得锁的时候其他线程就只能在外等待其执行完毕。而饿汉式则不存在线程安全的问题。
public class Singleton2 {/*线程不安全*/
// // 指向自己实例的私有静态引用
// private static Singleton2 singleton2;
//
// // 私有的构造方法
// private Singleton2(){}
//
// // 以自己实例为返回值的静态的公有方法,静态工厂方法
// public static Singleton2 getSingleton2(){
// // 被动创建,在真正需要使用时才去创建
// if (singleton2 == null) {
// singleton2 = new Singleton2();
// }
// return singleton2;
// }/*** 声明变量*/private static volatile Singleton2 singleton = null;/*** 私有构造方法*/private Singleton2() {}/*** 提供对外方法* @return*/public static Singleton2 getInstance() {// 还未实例化if (singleton == null) {synchronized (Singleton2.class) {if (singleton == null) {singleton = new Singleton2();}}}return singleton;}
}
JDK 中的应用:
- java.lang.Runtime.getRuntime()
- java.util.logging.Logger
Spring 中的应用:Spring 的 Bean 默认是单例模式。可以通过 @Scope("prototype") 将其改为多例。
二、工厂模式
根据需求,在用于不同的场景下,创建不同的对象。
public interface Sender {void Send();
}public class MailSender implements Sender{@Overridepublic void Send() {System.out.println("This is mail sender...");}
}public class SmsSender implements Sender{@Overridepublic void Send() {System.out.println("This is sms sender...");}
}public class FactoryPattern {public static void main(String[] args) {Sender sender = produce("mail");sender.Send();}public static Sender produce(String str) {if ("mail".equals(str)) {return new MailSender();} else if ("sms".equals(str)) {return new SmsSender();} else {System.out.println("输入错误...");return null;}}
}
在此基础上,若存在多个分支判断条件,很容易出现传递的字符串出错,则不能正确创建对象,因此可以多封装一个类,用来将分支判断替换为每个方法,降低耦合,这种模式是多个工厂方法模式,是提供多个工厂方法,分别创建对象。
public interface Sender {void Send();
}public class MailSender implements Sender{@Overridepublic void Send() {System.out.println("This is mail sender...");}
}public class SmsSender implements Sender{@Overridepublic void Send() {System.out.println("This is sms sender...");}
}public class SendFactory {public Sender produceMail() {return new MailSender();}public Sender produceSms() {return new SmsSender();}
}public class FactoryPattern {public static void main(String[] args) {SendFactory factory = new SendFactory();Sender sender = factory.produceMail();sender.Send();}
}
JDK 中的应用:
- java.util.Calendar.getInstance()
- javax.xml.parsers.DocumentBuilderFactory.newInstance()
Spring 中的应用:
- BeanFactory 和 ApplicationContext 都是工厂模式的体现。
三、建造者模式
建造者模式用于创建复杂对象,就是将复杂对象的创建过程拆分成多个简单对象的创建过程,并将这些简单对象组合起来构建出复杂对象。
角色组成:
- 产品类(Product):表示被创建的复杂对象。它通常包含多个部分或者组成,并由具体的建造者逐步构建而成。 Meal
- 抽象建造者类(Builder):定义了建造复杂对象所需要的各个部分的创建方法。它通常包括多个构建方法和一个返回产品的方法。 MealBuilder
- 具体建造者类(ConcreteBuilder):实现Builder接口,并提供各个部分或者组成的构建方法。 BeefBurgerMealBuilder、ChickenMealBuilder、ShrimpMealBuilder
- 指挥者类(Director):负责控制建造者的构建顺序,指挥建造者如何构建复杂对象。MealDirector
/*** @Author: EstellaQ* @Date: 2025/4/17 15:43* @Description: 产品类**/
@Data
public class Meal {//汉堡包private String burger;//薯条private String fries;//饮料private String drink;}/*** @Author: EstellaQ* @Date: 2025/4/17 15:44* @Description: 建造者接口**/
public interface MealBuilder {Meal meal=new Meal();//构建汉堡public void buildBurger();//构建薯条public void buildFries();//构建饮料public void buildDrink();public default Meal getMeal(){return meal;}
}/*** @Author: EstellaQ* @Date: 2025/4/17 15:46* @Description: 牛肉套餐建造者**/
public class BeefBurgerMealBuilder implements MealBuilder{@Overridepublic void buildBurger() {meal.setBurger("牛肉汉堡");}@Overridepublic void buildFries() {meal.setFries("大份薯条");}@Overridepublic void buildDrink() {meal.setDrink("中杯可乐");}
}/*** @Author: EstellaQ* @Date: 2025/4/17 15:46* @Description: 鸡肉套餐建造者**/
public class ChickenMealBuilder implements MealBuilder{@Overridepublic void buildBurger() {meal.setBurger("鸡肉汉堡");}@Overridepublic void buildFries() {meal.setFries("中份薯条");}@Overridepublic void buildDrink() {meal.setDrink("大杯果汁");}
}/*** @Author: EstellaQ* @Date: 2025/4/17 15:46* @Description: 虾肉套餐建造者**/
public class ShrimpMealBuilder implements MealBuilder{@Overridepublic void buildBurger() {meal.setBurger("虾肉汉堡");}@Overridepublic void buildFries() {meal.setFries("小份薯条");}@Overridepublic void buildDrink() {meal.setDrink("大杯芬达");}
}/*** @Author: EstellaQ* @Date: 2025/4/17 15:50* @Description: 指挥者**/
public class MealDirector {private MealBuilder mealBuilder;public void setMealBuilder(MealBuilder mealBuilder){this.mealBuilder=mealBuilder;}public Meal getMeal(){return mealBuilder.getMeal();}//制作套餐public void constructMeal(){mealBuilder.buildBurger();mealBuilder.buildFries();mealBuilder.buildDrink();}
}public class BuilderPattern {public static void main(String[] args) {//创建指导者MealDirector director=new MealDirector();//执导建造牛肉套餐director.setMealBuilder(new BeefBurgerMealBuilder());director.constructMeal();Meal meal = director.getMeal();System.out.println("牛肉套餐:"+meal.toString());//鸡肉套餐director.setMealBuilder(new ChickenMealBuilder());director.constructMeal();Meal meal2 = director.getMeal();System.out.println("鸡肉套餐:"+meal2.toString());//虾肉套餐director.setMealBuilder(new ShrimpMealBuilder());director.constructMeal();Meal meal3 = director.getMeal();System.out.println("虾肉套餐:"+meal3.toString());}
}
JDK 中的应用:
- StringBuilder
- Stream.Builder
Spring 中的应用:
- UriComponentsBuilder 用于构建 URI。
四、 适配器模式
它允许将不兼容的对象转换成可兼容的接口。主要目的是解决在不改变现有代码的情况下,使不兼容的接口之间能够正常工作,通过创建一个中间转换的适配器来将一个对象转换成我们所需要的接口。
角色组成
- 目标接口(target):需要适配的标准接口。
- 源对象(source):需要被适配的不兼容对象。
- 适配器对象(adapter):充当中间转换角色,该对象将源对象转换成目标接口。
/*** @Author: EstellaQ* @Date: 2025/4/17 16:20* @Description: 目标接口**/
public interface Target {/*** 翻译* @param source 母语* @param target 要翻译成的语种* @param words 内容*/void translate(String source,String target,String words);
}/*** @Author: EstellaQ* @Date: 2025/4/17 16:20* @Description: 源对象**/
public class Translator {//英——》汉public void translateInZh(String words){if("hello world!".equals(words)){System.out.println("翻译成中文:”你好世界!“");}}//汉——》英public void translateInEn(String words){if("你好世界!".equals(words)){System.out.println("Translate in English:”hello world!“");}}
}/*** @Author: EstellaQ* @Date: 2025/4/17 16:21* @Description: 类适配器:通过多重继承目标接口和被适配者类方式来实现适配**/
public class ClassAdapter extends Translator implements Target{@Overridepublic void translate(String source, String target, String words) {if("中文".equals(source) && "英文".equals(target)) {//汉--》英this.translateInEn(words);} else {//英--》汉this.translateInZh(words);}}
}public class AdapterPattern {public static void main(String[] args) {//创建一个类适配器对象ClassAdapter adapter=new ClassAdapter();adapter.translate("中文", "英文", "你好世界!");adapter.translate("英语","中文","hello world!");}
}
五、 装饰器模式
装饰器模式在不改变原始类的基础上,动态累积扩展其功能。原始对象和装饰类对象都要实现原始对象的接口。
/*** @Author: EstellaQ* @Date: 2025/4/17 16:55* @Description: 原始对象的接口**/
public interface ICoffee {void makeCoffee();
}/*** @Author: EstellaQ* @Date: 2025/4/17 16:56* @Description: 原始对象**/
public class OriginalCoffee implements ICoffee{@Overridepublic void makeCoffee() {System.out.print("原味咖啡 ");}
}/*** @Author: EstellaQ* @Date: 2025/4/17 16:56* @Description: 装饰器基类**/
public abstract class CoffeeDecorator implements ICoffee{private ICoffee coffee;public CoffeeDecorator(ICoffee coffee){this.coffee=coffee;}@Overridepublic void makeCoffee() {coffee.makeCoffee();}
}/*** @Author: EstellaQ* @Date: 2025/4/17 16:58* @Description: 加奶的装饰**/
public class MilkDecorator extends CoffeeDecorator{public MilkDecorator(ICoffee coffee) {super(coffee);}@Overridepublic void makeCoffee() {super.makeCoffee();addMilk();}private void addMilk(){System.out.print("加奶 ");}
}/*** @Author: EstellaQ* @Date: 2025/4/17 16:58* @Description: 加糖的装饰**/
public class SugarDecorator extends CoffeeDecorator{public SugarDecorator(ICoffee coffee) {super(coffee);}@Overridepublic void makeCoffee() {super.makeCoffee();addSugar();}private void addSugar(){System.out.print("加糖 ");}
}/*** @Author: EstellaQ* @Date: 2025/4/17 17:00* @Description: 装饰器模式测试**/
public class DecoratorPattern {public static void main(String[] args) {//原味咖啡ICoffee coffee=new OriginalCoffee();coffee.makeCoffee();System.out.println("");//加奶的咖啡coffee=new MilkDecorator(coffee);coffee.makeCoffee();System.out.println("");//先加奶后加糖的咖啡coffee=new SugarDecorator(coffee);coffee.makeCoffee();}
}
JDK 中的应用:
- java.io.BufferedInputStream 和 java.io.BufferedOutputStream
Spring 中的应用:
- BeanPostProcessor 用于动态修改 Bean 的行为。
六、 代理模式
代理模式的结构比较简单,主要是通过定义一个继承抽象主题的代理来包含真实主题,从而实现对真实主题的访问,下面来分析其基本结构。
角色组成:
- 抽象主题(Subject)类(业务接口类):通过接口或抽象类声明真实主题和代理对象实现的业务方法,服务端需要实现该方法。
- 真实主题(Real Subject)类(业务实现类):实现了抽象主题中的具体业务,是代理对象所代表的真实对象,是最终要引用的对象。
- 代理(Proxy)类:提供了与真实主题相同的接口,其内部含有对真实主题的引用,它可以访问、控制或扩展真实主题的功能。
静态代理
静态代理服务于单个接口,我们来考虑实际工程中的一个例子,现在已经有业务代码实现一个增删功能,原有的业务代码由于仍有大量程序无法改变,现在新增需求,即以后每执行一个方法输出一个日志。
/*** @Author: EstellaQ* @Date: 2025/4/17 17:38* @Description: 业务接口**/
public interface DateService {void add();void del();
}/*** @Author: EstellaQ* @Date: 2025/4/17 17:39* @Description: 委托类**/
public class DateServiceImplA implements DateService{@Overridepublic void add() {System.out.println("成功添加!");}@Overridepublic void del() {System.out.println("成功删除!");}
}/*** @Author: EstellaQ* @Date: 2025/4/17 17:40* @Description: 代理类**/
public class DateServiceProxy implements DateService{DateServiceImplA server = new DateServiceImplA();@Overridepublic void add() {server.add();System.out.println("程序执行add方法,记录日志.");}@Overridepublic void del() {server.del();System.out.println("程序执行del方法,记录日志.");}
}/*** @Author: EstellaQ* @Date: 2025/4/17 17:39* @Description: 代理模式测试**/
public class ProxyPattern {public static void main(String[] args) {DateService service = new DateServiceProxy();service.add();service.del();}
}
动态代理
动态代理可以帮助我们仅仅在需要的时候再创建代理类,减少资源浪费,此外由于动态代理是一个模板的形式,也可以减少程序的代码量,例如在静态代码示例中,我们在每个方法中加入System.out.println("程序执行***方法,记录日志.");,当业务方法非常多时,我们也得为每个业务方法加上记录日志的语句,而动态代理中将方法统一管理,无论几个业务方法都只需要一条记录语句即可实现,具体请看代码。
/*** @Author: EstellaQ* @Date: 2025/4/17 17:48* @Description: 动态代理的代理类**/
public class ProxyInvocationHandler implements InvocationHandler {private DateService service;public ProxyInvocationHandler(DateService service) {this.service = service;}public Object getDateServiceProxy() {return Proxy.newProxyInstance(this.getClass().getClassLoader(), service.getClass().getInterfaces(), this);}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {var result = method.invoke(service, args); // 让service调用方法,方法返回值System.out.println(proxy.getClass().getName() + "代理类执行" + method.getName() + "方法,返回" + result + ",记录日志!");return result;}
}/*** @Author: EstellaQ* @Date: 2025/4/17 17:39* @Description: 代理模式测试**/
public class ProxyPattern {public static void main(String[] args) {
//静态代理
// DateService service = new DateServiceProxy();
// service.add();
// service.del();
//动态代理DateService serviceA = new DateServiceImplA();DateService serviceProxy = (DateService) new ProxyInvocationHandler(serviceA).getDateServiceProxy();serviceProxy.add();serviceProxy.del();}
}
七、 策略模式
该模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使用算法的客户。策略模式属于对象行为模式,它通过对算法进行封装,把使用算法的责任和算法的实现分割开来,并委派给不同的对象对这些算法进行管理。 我认为跟工厂模式的思想很相似
角色组成:
抽象策略(Strategy)类
具体策略(Concrete Strategy)类
环境(Context)类
/*** @Author: EstellaQ* @Date: 2025/4/17 18:04* @Description: 抽象算法的策略类,定义所有支持的算法的公共接口**/
public interface Strategy {/*** 算法方法*/public void AlgorithmInterface();
}/*** @Author: EstellaQ* @Date: 2025/4/17 18:04* @Description: 策略实现类A**/
public class ConcreteStrategyA implements Strategy{@Overridepublic void AlgorithmInterface() {System.out.println("算法A的实现");}
}/*** @Author: EstellaQ* @Date: 2025/4/17 18:04* @Description: 策略实现类B**/
public class ConcreteStrategyB implements Strategy{@Overridepublic void AlgorithmInterface() {System.out.println("算法B的实现");}
}/*** @Author: EstellaQ* @Date: 2025/4/17 18:04* @Description: 策略实现类C**/
public class ConcreteStrategyC implements Strategy{@Overridepublic void AlgorithmInterface() {System.out.println("算法C的实现");}
}/*** @Author: EstellaQ* @Date: 2025/4/17 18:06* @Description: 上下文,维护一个对策略类对象的引用**/
public class Context {private Strategy strategy;public Context(Strategy strategy) {this.strategy = strategy;}public void contextInterface(){strategy.AlgorithmInterface();}
}/*** @Author: EstellaQ* @Date: 2025/4/17 18:03* @Description: 策略模式的测试类**/
public class StrategyPattern {public static void main(String[] args) {Context context;context = new Context(new ConcreteStrategyA());context.contextInterface();context = new Context(new ConcreteStrategyB());context.contextInterface();context = new Context(new ConcreteStrategyC());context.contextInterface();}
}
JDK 中的应用:
- java.util.Comparator 是典型的策略模式。
Spring 中的应用:
- 事务管理(TransactionManager),支持编程式和声明式事务。
八、 观察者模式
观察者模式是一种行为型设计模式,它定义了一种一对多的依赖关系,当一个对象的状态发生改变时,其所有依赖者都会收到通知并自动更新。
角色组成:
- 主题(Subject):也称为被观察者或可观察者,它是具有状态的对象,并维护着一个观察者列表。主题提供了添加、删除和通知观察者的方法。
- 观察者(Observer):观察者是接收主题通知的对象。观察者需要实现一个更新方法,当收到主题的通知时,调用该方法进行更新操作。
- 具体主题(Concrete Subject):具体主题是主题的具体实现类。它维护着观察者列表,并在状态发生改变时通知观察者。
- 具体观察者(Concrete Observer):具体观察者是观察者的具体实现类。它实现了更新方法,定义了在收到主题通知时需要执行的具体操作。
/*** @Author: EstellaQ* @Date: 2025/4/17 18:42* @Description: 主题类,被观察者**/
public class Subject {private List<Observer> observers = new ArrayList<Observer>();private int state;public int getState() {return state;}public void setState(int state) {this.state = state;notifyAllObservers();}public void attach(Observer observer){observers.add(observer);}public void notifyAllObservers(){for (Observer observer : observers) {observer.update();}}
}/*** @Author: EstellaQ* @Date: 2025/4/17 18:43* @Description: 被通知者的抽象类**/
public abstract class Observer {protected Subject subject;public abstract void update();}/*** @Author: EstellaQ* @Date: 2025/4/17 18:46* @Description: 被通知者的实现类**/
public class BinaryObserver extends Observer{public BinaryObserver(Subject subject){this.subject = subject;this.subject.attach(this);}@Overridepublic void update() {System.out.println( "Binary String: "+ Integer.toBinaryString( subject.getState() ) );}
}/*** @Author: EstellaQ* @Date: 2025/4/17 18:46* @Description: 被通知者的实现类**/
public class OctalObserver extends Observer{public OctalObserver(Subject subject){this.subject = subject;this.subject.attach(this);}@Overridepublic void update() {System.out.println( "Octal String: "+ Integer.toOctalString( subject.getState() ) );}
}/*** @Author: EstellaQ* @Date: 2025/4/17 18:46* @Description: 被通知者的实现类**/
public class HexaObserver extends Observer{public HexaObserver(Subject subject){this.subject = subject;this.subject.attach(this);}@Overridepublic void update() {System.out.println( "Hex String: "+ Integer.toHexString( subject.getState() ) );}
}/*** @Author: EstellaQ* @Date: 2025/4/17 18:48* @Description: 观察者模式测试**/
public class ObserverPattern {public static void main(String[] args) {Subject subject = new Subject();new HexaObserver(subject);new OctalObserver(subject);new BinaryObserver(subject);System.out.println("First state change: 15");subject.setState(15);System.out.println("Second state change: 10");subject.setState(10);}
}
JDK 中的应用:
- java.util.Observer 和 java.util.Observable
- javax.swing.event.ChangeListener
Spring 中的应用:
- ApplicationEvent 和 ApplicationListener 是典型实现。
相关文章:
Java八种常见的设计模式
一、单例模式 单例模式是(Singleton Pattern)Java中最常用的设计模式之一,它保证一个类仅有一个实例,并提供一个全局访问点。 实现单例模式的核心是将类的构造方法私有化,以防止外部直接通过构造函数创建实例。同时&am…...
数据结构实验7.2:二叉树的基本运算
文章目录 一,实验目的二,问题描述三,基本要求四,实验操作五,示例代码六,运行效果 一,实验目的 深入理解树与二叉树的基本概念,包括节点、度、层次、深度等,清晰区分二叉…...
Go-zero框架修改模版进行handler统一响应封装
使用go-zero快速生成接口的时候,发现还是有一些情况不太好处理,比如说,想要自定义响应封装等等。 最开始第一版写api文件的时候,写法是这样的。 type LoginRequest {UserName string json:"userName"Password string …...
AI专题(一)----NLP2SQL探索以及解决方案
前面写了很多编码、算法、底层计算机原理等相关的技术专题,由于工作方向调整的缘故,今天开始切入AI人工智能相关介绍。本来按照规划,应该先从大模型的原理开始介绍会比较合适,但是计划赶不上变化,前面通用大模型的工作…...
深入理解 React Hooks:简化状态管理与副作用处理
在现代前端开发中,React 已经成为了最受欢迎的 JavaScript 库之一。随着 React 16.8 的发布,React Hooks 的引入彻底改变了开发者编写组件的方式。Hooks 提供了一种更简洁、更直观的方式来管理组件的状态和副作用,使得函数组件能够拥有类组件…...
Spring Boot 实现防盗链
在 Spring Boot 项目中实现防盗链可以通过多种方式,下面为你介绍两种常见的实现方法,分别是基于请求头 Referer 和基于令牌(Token)的防盗链。 基于请求头 Referer 的防盗链 这种方法通过检查请求头中的 Referer 字段,…...
Java 动态代理实现
Java 动态代理实现 一、JDK动态代理二、CGLIB动态代理三、动态代理的应用场景四、JDK代理与CGLIB代理比较 动态代理是Java中一种强大的技术,它允许在运行时创建代理对象,用于拦截对目标对象的方法调用。 一、JDK动态代理 JDK动态代理是Java标准库提供的代…...
2025年4月通信科技领域周报(4.07-4.13):6G技术加速落地 卫星通信网络迎来组网高潮
2025年4月通信科技领域周报(4.07-4.13):6G技术加速落地 卫星通信网络迎来组网高潮 目录 2025年4月通信科技领域周报(4.07-4.13):6G技术加速落地 卫星通信网络迎来组网高潮一、本周热点回顾1. 华为发布全球首…...
《手环表带保养全攻略:材质、清洁与化学品避坑指南》
系列文章目录 文章目录 系列文章目录前言一、表带材质特性与专属养护方案二、清洁剂使用红黑榜三、家庭清洁实验:化学反应警示录四、保养实践方法论总结 前言 手环作为现代生活的智能伴侣,表带材质选择丰富多样。从柔软亲肤的皮质到耐用耐磨的金属&…...
人脸扫描黑科技:多相机人脸扫描设备,打造你的专属数字分身
随着科技的迅猛发展,人脸扫描这个词已经并不陌生,通过人脸扫描设备制作超写实人脸可以为影视制作打造逼真角色、提升游戏沉浸感,还能助力教育机构等领域生产数字人以丰富教学资源,还在安防、身份识别等领域发挥关键作用࿰…...
基于Python的中国象棋小游戏的设计与实现
基于Python的中国象棋小游戏的设计与实现 第一章 绪论1.1 研究背景1.2 研究意义 第二章 需求分析2.1 需求分析2.1.1核心功能需求2.1.2 用户体验需求2.1.3 衍生功能需求 2.2 可行性分析2.2.1 技术可行性2.2.2 经济可行性2.2.3 市场可行性2.2.4 法律与合规性 第三章 概要设计3.1 …...
简单好用的在线工具
用AI写了一些在线工具,简介好用,推荐给大家,欢迎大家使用并提议意见。 网址:https://www.bittygarden.com/ 目前已有以下功能: MD5SM3SHAUnicode 编码Unicode 解码Base32 编码Base32 解码Base64 编码Base64 解码URL …...
JAVA设计模式——(1)适配器模式
JAVA设计模式——(1)适配器模式 目的理解实现优势 目的 将一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法一起工作的两个类能够在一起工作。 理解 可以想象成一个国标的插头,结果插座是德标的&…...
外卖市场规模巨大,是宽广赛道?京东CEO发言
大家好,我是小悟。 在竞争激烈的外卖市场中,京东作为新入局者,正以独特的战略视角和坚定的决心,重新定义外卖行业的竞争格局。 近日,京东集团CEO许冉在接受采访时表示:“外卖行业本就是一个宽广的赛道&am…...
Flutter PIP 插件 ---- iOS Video Call 自定义PIP WINDOW渲染内容
简介 画中画(Picture in Picture, PiP)是一项允许用户在使用其他应用时继续观看视频内容的功能。本文将详细介绍如何在 iOS 应用中实现 PiP 功能,包括自定义内容渲染和控制系统控件的显示。 效果展示 功能特性 已完成功能 ✅ 基础 PiP 接口实现(设置…...
TensorFlow 实现 Mixture Density Network (MDN) 的完整说明
本文档详细解释了一段使用 TensorFlow 构建和训练混合密度网络(Mixture Density Network, MDN)的代码,涵盖数据生成、模型构建、自定义损失函数与预测可视化等各个环节。 1. 导入库与设置超参数 import numpy as np import tensorflow as t…...
xml+html 概述
1.什么是xml xml 是可扩展标记语言的缩写: Extensible Markup Language。 <root><h1> text 1</h1> </root> web 应用开发,需要配置 web.xml,就是个典型的 xml文件 <web-app><servlet><servlet-name&…...
混合精度训练中的算力浪费分析:FP16/FP8/BF16的隐藏成本
在大模型训练场景中,混合精度训练已成为降低显存占用的标准方案。然而,通过NVIDIA Nsight Compute深度剖析发现,精度转换的隐藏成本可能使理论算力利用率下降40%以上。本文基于真实硬件测试数据,揭示不同精度格式的计算陷阱。…...
Python语法系列博客 · 第5期[特殊字符] 模块与包的导入:构建更大的程序结构
上一期小练习解答(第4期回顾) ✅ 练习1:判断偶数函数 def is_even(num):return num % 2 0print(is_even(4)) # True print(is_even(5)) # False✅ 练习2:求平均值 def avg(*scores):return sum(scores) / len(scores)print(…...
Sleuth+Zipkin 服务链路追踪
微服务架构中,为了更好追踪服务之间调用,实现时间分析,性能瓶颈分析,故障排查,因此有必要搭建链路追踪。下面简单介绍下实现的过程。 一.引入依赖 <!-- 链路追踪 zipkin已经集成有sleuth,不需要再单独…...
意志力的源头——AMCC(前部中扣带皮层)
AMCC(前部中扣带皮层)在面对痛苦需要坚持的事情时会被激活。它的存在能够使人类个体在面临困难的事、本能感到不愿意的麻烦事情时,能够自愿地去做这些事——这些事必须是局部痛苦或宏观的痛苦,即微小的痛苦micro-sucks。 AMCC更多…...
[Jenkins]pnpm install ‘pnpm‘ 不是内部或外部命令,也不是可运行的程序或批处理文件。
这个错误提示再次说明:你的系统(CMD 或 Jenkins 环境)找不到 pnpm 命令的位置。虽然你可能已经用 npm install -g pnpm 安装过,但系统不知道它装在哪里,也就无法执行 pnpm 命令。 ✅ 快速解决方法:直接用完…...
Java从入门到“放弃”(精通)之旅——数组的定义与使用⑥
Java从入门到“放弃”(精通)之旅🚀——数组⑥ 前言——什么是数组? 数组:可以看成是相同类型元素的一个集合,在内存中是一段连续的空间。比如现实中的车库,在java中,包含6个整形类…...
部署rocketmq集群
容器化部署RocketMQ5.3.1集群 背景: 生产环境单机的MQ不具有高可用,所以我们应该部署成集群模式,这里给大家部署一个双主双从异步复制的Broker集群 一、安装docker yum install -y docker systemctl enable docker --now # 单机部署参考: https://www.cnblogs.com/hsyw/p/1…...
如何对docker镜像存在的gosu安全漏洞进行修复——筑梦之路
这里以mysql的官方镜像为例进行说明,主要流程为: 1. 分析镜像存在的安全漏洞具体是什么 2. 根据分析结果有针对性地进行修复处理 3. 基于当前镜像进行修复安全漏洞并复核验证 # 镜像地址mysql:8.0.42 安全漏洞现状分析 dockerhub网站上获取该镜像的…...
Ubuntu 安装WPS Office
文章目录 Ubuntu 安装WPS Office下载安装文件安装WPS问题1.下载缺失字体文件2.安装缺失字体 Ubuntu 安装WPS Office 下载安装文件 需要到 WPS官网 下载最新软件,比如wps-office_12.1.0.17900_amd64.deb 安装WPS 执行命令进行安装 sudo dpkg -i wps-office_12.1…...
基于springboot的老年医疗保健系统
博主介绍:java高级开发,从事互联网行业六年,熟悉各种主流语言,精通java、python、php、爬虫、web开发,已经做了六年的毕业设计程序开发,开发过上千套毕业设计程序,没有什么华丽的语言࿰…...
使用Ollama本地运行deepseek模型
Ollama 是一个用于管理 AI 模型的工具 下载 Ollama Ollama 选择版本 下载模型 安装好后,下载模型 选择模型 选择模型大小,复制对应命令(越大越聪明,但是内存要求越高) 打开控制台运行命令,第一次运行会自动…...
网络编程 - 3
目录 UDP 连接拓展(业务逻辑) 词典服务器实现 完 UDP 连接拓展(业务逻辑) 我们上一篇文章实现了一个回显服务器,在服务端中业务方法 process 中,只是单纯的将客户端输入的东西 return 了一下࿰…...
rebase和merge的区别
目录 1. 合并机制与提交历史 2. 冲突处理方式 3. 历史追溯与团队协作 4. 推荐实践 5. 撤销难度 git rebase和git merge是Git中两种不同的分支合并策略,核心区别在于提交历史的处理方式:merge保留原始分支结构并生成合并提交&am…...
