【深入理解设计模式】 工厂设计模式

工厂设计模式
工厂设计模式是一种创建型设计模式,它提供了一种在不指定具体类的情况下创建对象的接口。在工厂设计模式中,我们定义一个创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
工厂设计模式的目的是:
- 封装对象创建的过程,使得用户不需要了解对象的实现细节。
- 扩展性良好,如果需要添加新的对象,只需添加一个新的子类即可。
- 遵循“开闭原则”,即对扩展开放,对修改封闭。
在java中,万物皆对象,这些对象都需要创建,如果创建的时候直接new该对象,就会对该对象耦合严重,假如我们要更换对象,所有new对象的地方都需要修改一遍,这显然违背了软件设计的开闭原则。如果我们使用工厂来生产对象,我们就只和工厂打交道就可以了,彻底和对象解耦,如果要更换对象,直接在工厂里更换该对象即可,达到了与对象解耦的目的;所以说,工厂模式最大的优点就是:解耦。
工厂模式的主要功能就是帮助我们实例化对象的,之所以名字中包含工厂模式四个字,是因为对象的实例化过程是通过工厂实现的,是用工厂代替new操作的。
这样做可以封装对象的实例化细节,尤其是对于实例化比较复杂或者对象的生命周期应该集中管理的情况。会给你系统带来更大的可扩展性和尽量少的修改量。
工厂模式有三种,分别是简单工厂模式,工厂方法模式,抽象工厂模式。三种模式从前到后越来越抽象,也更具有一般性。

简单工厂模式:
简单工厂模式并不属于23种设计模式,其更像是一种编程习惯。
简单工厂模式结构:
简单工厂包含如下角色:
- 抽象产品 :定义了产品的规范,描述了产品的主要特性和功能。
- 具体产品 :实现或者继承抽象产品的子类
- 具体工厂 :提供了创建产品的方法,调用者通过该方法来获取产品。
列举实现
抽象产品类:小米SU7
/*** @author OldGj 2024/02/20* @version v1.0* @apiNote 小米SU7抽象类*/
public abstract class XiaoMiSU7 {public void run(){System.out.println("百公里加速2.8");}public void stop(){System.out.println("黄色刹车盘");}// 获取配置public abstract String getDisposition();}
具体产品:低配版小米SU7
/*** @author OldGj 2024/02/20* @version v1.0* @apiNote 低配小米SU7*/
public class LowConfigurationSU7 extends XiaoMiSU7 {@Overridepublic String getDisposition() {return "低配小米SU7";}
}
具体产品:高配版小米SU7
/*** @author OldGj 2024/02/20* @version v1.0* @apiNote 高配小米SU7*/
public class HighConfigurationSU7 extends XiaoMiSU7{@Overridepublic String getDisposition() {return "高配小米SU7";}
}
具体工厂类:
/*** @author OldGj 2024/02/20* @version v1.0* @apiNote 小米SU7静态工厂*/
public class SimpleSU7Factory {/*** 根据不同配置生产小米SU7 静态方法,直接通过类名打点调用即可* @param type 不同配置* @return 不同配置的小米SU7*/public XiaoMiSU7 createXiaoMiSU7(String type) {XiaoMiSU7 xiaoMiSU7 = null;if ("high".equals(type)) {xiaoMiSU7 = new HighConfigurationSU7();} else if ("low".equals(type)) {xiaoMiSU7 = new LowConfigurationSU7();}return xiaoMiSU7;}
}
通过以上的简单工厂模式,我们在小米4S店类中,只需要使用SU7工厂类直接生产SU7即可,不需要再将4S店类与高配版SU7以及低配版SU7类之间进行耦合,达到了解耦的目的。
/*** @author OldGj 2024/02/20* @version v1.0* @apiNote 小米4S店*/
public class MI4S {/*** 订购小米SU7* @param type 订购类型(高配,低配)* @return (高配,低配)小米SU7*/public XiaoMiSU7 orderXiaoMiSU7(String type) {SimpleSU7Factory su7Factory = new SimpleSU7Factory();XiaoMiSU7 xiaoMiSU7 = su7Factory.createXiaoMiSU7(type);xiaoMiSU7.run();xiaoMiSU7.stop();return xiaoMiSU7;}
}
优缺点
优点:
封装了创建对象的过程,可以通过参数直接获取对象。把对象的创建和业务逻辑层分开,这样以后就避免了修改客户代码,如果要实现新产品直接修改工厂类,而不需要在原代码中修改,这样就降低了客户代码修改的可能性,更加容易扩展。
缺点:
增加新产品时还是需要修改工厂类的代码,违背了“开闭原则”。
扩展:静态工厂模式
我们可以将工厂中的创建产品的方法设置为工厂类的静态方法,这样我们在4S店中只需要通过工厂类名之间打点调用创建产品方法即可,无序去实例化工厂对象。
/*** @author OldGj 2024/02/20* @version v1.0* @apiNote 小米SU7静态工厂*/
public class SimpleSU7Factory {/*** 根据不同配置生产小米SU7 静态方法,直接通过类名打点调用即可* @param type 不同配置* @return 不同配置的小米SU7*/public static XiaoMiSU7 createXiaoMiSU7(String type) {XiaoMiSU7 xiaoMiSU7 = null;if ("high".equals(type)) {xiaoMiSU7 = new HighConfigurationSU7();} else if ("low".equals(type)) {xiaoMiSU7 = new LowConfigurationSU7();}return xiaoMiSU7;}
}
通过以上优缺点分析,我们发现简单工厂模式模式虽然把对象的创建和业务逻辑层分开,但是如果我们想要进行拓展,任然需要手动修改工厂方法中创建对象的逻辑,这显然也是不符合‘开闭原则’的,因此,我们可以使用简单工厂模式+配置文件的方式,解决这一问题。
可以通过工厂模式+配置文件的方式解除工厂对象和产品对象的耦合。在工厂类中加载配置文件中的全类名,并创建对象进行存储,客户端如果需要对象,直接进行获取即可。
第一步:定义配置文件
为了演示方便,我们使用properties文件作为配置文件,名称为bean.properties
american=com.tyut.pattern._01_creative_model.e02factor.config_factory.AmericanCoffee
latte=com.tyut.pattern._01_creative_model.e02factor.config_factory.LatteCoffee
ku=com.tyut.pattern._01_creative_model.e02factor.config_factory.KuCoffee
第二步:改进工厂类
/*** @author OldGj 2024/02/20* @version v1.0* @apiNote 简单咖啡工厂类 - 通过加载配置文件的方式,实现开闭原则,* 解除简单工厂类和具体产品类之间的耦合*/
public class CoffeeFactory {//定义一个map容器存储对象private static final Map<String, Coffee> map = new HashMap<>();/** 在静态代码块中加载配置文件并创建对象*/static {InputStream resource = CoffeeFactory.class.getClassLoader().getResourceAsStream("bean.properties");Properties properties = new Properties();try {properties.load(resource);Set<Object> keySet = properties.keySet();for (Object key : keySet) {String className = properties.getProperty((String) key);// 通过类的全限定路径创建类的反射(字节码)对象Class<?> clazz = Class.forName(className);// 通过反射对象调用类的无参构造实例化类Coffee coffee = (Coffee) clazz.newInstance();map.put((String) key, coffee);}} catch (Exception e) {throw new RuntimeException(e);}}//创建对象public static Coffee createCoffee(String type) {return map.get(type);}
}
静态成员变量用来存储创建的对象(键存储的是名称,值存储的是对应的对象),而读取配置文件以及创建对象写在静态代码块中,目的就是只需要执行一次。
通过以上代码改进工厂类,我们就可以通过读取配置文件中的配置,将需要的对象通过反射技术创建并加入容器中,在creat方法中,只需要通过参数获取容器中的对象并返回即可,这样就可以实现工厂类与具体产品类之间解耦,如果需要添加具体产品,只需要创建新增产品类并且在配置文件中加入新增产品的全限定路径即可,工厂类会在类加载阶段就将产品类创建并加入容器,无序修改工厂类,实现了“开闭原则”!
工厂方法模式
概念
定义一个用于创建对象的接口,让子类决定实例化哪个产品类对象。工厂方法使一个产品类的实例化延迟到其工厂的子类。
工厂方法模式结构
工厂方法模式的主要角色:
- 抽象工厂(Abstract Factory):提供了创建产品的接口,调用者通过它访问具体工厂的工厂方法来创建产品。
- 具体工厂(ConcreteFactory):主要是实现抽象工厂中的抽象方法,完成具体产品的创建。
- 抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能。
- 具体产品(ConcreteProduct):实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间一一对应。
列举实现
抽象产品:
抽象产品类:小米SU7
/*** @author OldGj 2024/02/20* @version v1.0* @apiNote 小米SU7抽象类*/
public abstract class XiaoMiSU7 {public void run(){System.out.println("百公里加速2.8");}public void stop(){System.out.println("黄色刹车盘");}// 获取配置public abstract String getDisposition();}
具体产品:低配版小米SU7
/*** @author OldGj 2024/02/20* @version v1.0* @apiNote 低配小米SU7*/
public class LowConfigurationSU7 extends XiaoMiSU7 {@Overridepublic String getDisposition() {return "低配小米SU7";}
}
具体产品:高配版小米SU7
/*** @author OldGj 2024/02/20* @version v1.0* @apiNote 高配小米SU7*/
public class HighConfigurationSU7 extends XiaoMiSU7{@Overridepublic String getDisposition() {return "高配小米SU7";}
}
抽象工厂类:
/*** @author OldGj 2024/02/20* @version v1.0* @apiNote 抽象工厂*/
public interface XiaoMiSU7Factory {XiaoMiSU7 createXiaoMiSU7();}
为每一个具体产品都创建一个与之对应的具体工厂用来创建具体产品实例。
具体工厂类:低配版SU7工厂
/*** @author OldGj 2024/02/20* @version v1.0* @apiNote 低配小米SU7工厂*/
public class LowXiaoMiSU7Factory implements XiaoMiSU7Factory {@Overridepublic XiaoMiSU7 createXiaoMiSU7() {return new LowConfigurationSU7();}
}
具体工厂类:高配版SU7工厂
/*** @author OldGj 2024/02/20* @version v1.0* @apiNote 高配小米SU7工厂*/
public class HighXiaoMiSU7Factory implements XiaoMiSU7Factory {@Overridepublic XiaoMiSU7 createXiaoMiSU7() {return new HighConfigurationSU7();}
}
小米4S店类:
/*** @author OldGj 2024/02/20* @version v1.0* @apiNote 小米4S店*/
public class MI4S {private XiaoMiSU7Factory factory;public void setFactory(XiaoMiSU7Factory factory) {this.factory = factory;}/*** 订购小米SU7** @return 小米SU7*/public XiaoMiSU7 orderXiaoMiSU7() {XiaoMiSU7 xiaoMiSU7 = factory.createXiaoMiSU7();xiaoMiSU7.run();xiaoMiSU7.stop();return xiaoMiSU7;}
}
工厂方法模式是简单工厂模式的进一步抽象。由于使用了多态性,工厂方法模式保持了简单工厂模式的优点,而且克服了它的缺点。
在小米4S店类中,我们只需声明一个抽象工厂类型的成员变量,并且调用其创建SU7方法即可,具体创建什么类型的SU7并不需要我们关心,只需要在客户端传入不同类型的工厂对象即可,通过这种工厂方法模式,我们将工厂类和具体产品类完全解耦(一个工厂只负责生产一种具体产品),并且如果我们还要拓展一个具体产品,如中配版SU7,我们只需创建新的具体产品类以及具体工厂类并让其实现其抽象即可,无序修改工厂类代码,符合“开闭原则”。
优缺点
优点:
- 用户只需要知道具体工厂的名称就可得到所要的产品,无须知道产品的具体创建过程;
- 在系统增加新的产品时只需要添加具体产品类和对应的具体工厂类,无须对原工厂进行任何修改,满足开闭原则;
缺点:
- 每增加一个产品就要增加一个具体产品类和一个对应的具体工厂类,这增加了系统的复杂度。
抽象工厂模式
前面介绍的工厂方法模式中考虑的是一类产品的生产,如畜牧场只养动物、电视机厂只生产电视机。
这些工厂只生产同种类产品,同种类产品称为同等级产品,也就是说:工厂方法模式只考虑生产同等级的产品,但是在现实生活中许多工厂是综合型的工厂,能生产多等级(种类) 的产品,如电器厂既生产电视机又生产洗衣机或空调,大学既有软件专业又有生物专业等。
抽象工厂模式将考虑多等级产品的生产,将同一个具体工厂所生产的位于不同等级的一组产品称为一个产品族。
产品族:位于不同产品等级结构中,功能相关的产品组成的家族。
概念
是一种为访问类提供一个创建一组相关或相互依赖对象的接口,且访问类无须指定所要产品的具体类就能得到同族的不同等级的产品的模式结构。
抽象工厂模式是工厂方法模式的升级版本,工厂方法模式只生产一个等级的产品,而抽象工厂模式可生产多个等级的产品。
抽象工厂模式结构
抽象工厂模式的主要角色如下:
- 抽象工厂(Abstract Factory):提供了创建产品的接口,它包含多个创建产品的方法,可以创建多个不同等级的产品。
- 具体工厂(Concrete Factory):主要是实现抽象工厂中的多个抽象方法,完成具体产品的创建。
- 抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能,抽象工厂模式有多个抽象产品。
- 具体产品(ConcreteProduct):实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间是多对一的关系。
列举实现
抽象产品类:咖啡类
/*** @author OldGj 2024/02/20* @version v1.0* @apiNote 抽象产品 - 咖啡*/
public abstract class Coffee {public abstract String getName();public void addSugar(){System.out.println("加糖");}public void addMilk(){System.out.println("加奶");}}
抽象产品类:甜品类
/*** @author OldGj 2024/02/20* @version v1.0* @apiNote 抽象产品 - 甜品*/
public abstract class Dessert {public abstract String getName();}
咖啡类和甜品类同属于甜点产品族中不同等级的产品。
具体产品类:
/*** @author OldGj 2024/02/20* @version v1.0* @apiNote 具体产品 - 拿铁咖啡*/
public class LatteCoffee extends Coffee{@Overridepublic String getName() {return "拿铁咖啡";}
}
/*** @author OldGj 2024/02/20* @version v1.0* @apiNote 具体产品 - 美式咖啡*/
public class AmericanCoffee extends Coffee {@Overridepublic String getName() {return "美式咖啡";}
}
/*** @author OldGj 2024/02/20* @version v1.0* @apiNote 具体产品 - 抹茶慕斯*/
public class MatchaMousse extends Dessert{@Overridepublic String getName() {return "抹茶慕斯";}
}
/*** @author OldGj 2024/02/20* @version v1.0* @apiNote 具体产品 - 提拉米苏*/
public class Tiramisu extends Dessert {@Overridepublic String getName() {return "提拉米苏";}
}
具体产品分别继承自各自产品等级的顶层抽象,并实现其抽象方法。
抽象工厂类:甜点产品族
/*** @author OldGj 2024/02/20* @version v1.0* @apiNote 抽象工厂 - 甜点接口*/
public interface DessertFactory {Dessert createDessert();Coffee createCoffee();
}
抽象工厂模式中,一个抽象工厂类中提供了多个同一产品族产品的生产方法。
例如:一个甜点类抽象工厂中,提供了生产咖啡方法和生产甜品方法。
具体工厂类:意大利风味甜点
/*** @author OldGj 2024/02/20* @version v1.0* @apiNote 具体工厂 - 意大利风味甜点*/
public class ItalyDessertFactory implements DessertFactory {@Overridepublic Dessert orderDessert() {return new Tiramisu();}@Overridepublic Coffee orderCoffee() {return new LatteCoffee();}
}
具体工厂类:美式风味甜点
/*** @author OldGj 2024/02/20* @version v1.0* @apiNote 具体工厂 - 美式风味甜点*/
public class AmericanDessertFactory implements DessertFactory {@Overridepublic Dessert orderDessert() {return new MatchaMousse();}@Overridepublic Coffee orderCoffee() {return new AmericanCoffee();}
}
如果要加同一个产品族的话,只需要再加一个对应的工厂类即可,不需要修改其他的类。
优缺点
优点:
当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。
缺点:
当产品族中需要增加一个新的产品时,所有的工厂类都需要进行修改。
"开闭原则"的倾斜性
"开闭原则”要求系统对拓展开放,对修改关闭,通过扩展达到增强其功能的目的。对于涉及到多个产品族与多个产品等级结构的系统,其功能增强包括两方面:
- 增加产品族:对于增加新的产品族,工厂方法模式很好的支持了“开闭原则”,对于新增加的产品族,只需要对应增加一个新的具体工厂即可,对已有代码无序做任何修改。
- 增加新的产品等级结构:对于增加新的产品等级结构,需要修改所有的工厂角色,包括抽象工厂类,在所有的工厂类中都需要增加生产新产品的方法,不能很好的支持“开闭原则”。
抽象工厂模式的这种性质称为“开闭原则”的倾斜性,抽象工厂模式以一种倾斜的方式支持增加新的产品,它为新产品族的增加提供方便,但不能为新的产品等级结构的增加提供方便。
抽象工厂模式总结
抽象工厂模式提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。抽象工厂模式又称为Kit模式,属于对象创建型模式。
抽象工厂模式是所有形式的工厂模式中最为抽象和最具一般性的一种形态。
抽象工厂模式的主要优点是隔离了具体类的生成,使得客户并不需要知道什么被创建,而且每次可以通过具体工厂类创建一个产品族中的多个对象,增加或者替换产品族比较方便,增加新的具体工厂和产品族很方便;主要缺点在于增加新的产品等级结构很复杂,需要修改抽象工厂和所有的具体工厂类,对“开闭原则”的支持呈现倾性。
使用场景
-
当需要创建的对象是一系列相互关联或相互依赖的产品族时,如电器工厂中的电视机、洗衣机、空调等。
-
系统中有多个产品族,但每次只使用其中的某一族产品。如有人只喜欢穿某一个品牌的衣服和鞋。
-
系统中提供了产品的类库,且所有产品的接口相同,客户端不依赖产品实例的创建细节和内部结构。
JDK中的工厂模式:
- Collection.iterator方法
Collection接口是抽象工厂类
ArrayList是具体的工厂类
Iterator接口是抽象商品类
ArrayList类中的Itr内部类是具体的商品类。
在具体的工厂类中iterator()方法创建具体的商品类的对象。
- DateForamt类中的getInstance()方法使用的是工厂模式;
- ,Calendar类中的getInstance()方法使用的是工厂模式;
相关文章:
【深入理解设计模式】 工厂设计模式
工厂设计模式 工厂设计模式是一种创建型设计模式,它提供了一种在不指定具体类的情况下创建对象的接口。在工厂设计模式中,我们定义一个创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。 工厂设计模式的目…...
Windows下搭建EFK实例
资源下载 elasticSearch :下载最新版本的就行 kibana filebeat:注意选择压缩包下载 更新elasticsearch.yml,默认端口9200: # Elasticsearch Configuration # # NOTE: Elasticsearch comes with reasonable defaults for most …...
工厂方法模式Factory Method
1.模式定义 定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method 使得一个类的实例化延迟到子类 2.使用场景 1.当你不知道改使用对象的确切类型的时候 2.当你希望为库或框架提供扩展其内部组件的方法时 主要优点: 1.将具体产品和创建…...
Vue的个人笔记
Vue学习小tips ctrl s ----> 运行 alt b <scrip> 链接 <script src"https://cdn.jsdelivr.net/npm/vue2.7.16/dist/vue.js"></script> 插值表达式 指令...
linux platform架构下I2C接口驱动开发
目录 概述 1 认识I2C协议 1.1 初识I2C 1.2 I2C物理层 1.3 I2C协议分析 1.3.1 Start、Stop、ACK 信号 1.3.2 I2C协议的操作流程 1.3.3 操作I2C注意的问题 2 linux platform驱动开发 2.1 更新设备树 2.1.1 添加驱动节点 2.1.2 编译.dts 2.1.3 更新板卡中的.dtb 2.2 …...
基于机器学习的青藏高原高寒沼泽湿地蒸散发插补研究_王秀英_2022
基于机器学习的青藏高原高寒沼泽湿地蒸散发插补研究_王秀英_2022 摘要关键词 1 材料和方法1.1 研究区概况与数据来源1.2 研究方法 2 结果和分析2.1 蒸散发通量观测数据缺省状况2.2 蒸散发与气象因子的相关性分析2.3 不同气象因子输入组合下各模型算法精度对比2.4 随机森林回归模…...
Failed at the node-sass@4.14.1 postinstall script.
问题描述 安装sass # "node-sass": "^4.9.0" npm i node-sass报错如下 npm ERR! code ELIFECYCLE npm ERR! errno 1 npm ERR! node-sass4.14.1 postinstall: node scripts/build.js npm ERR! Exit status 1 npm ERR! npm ERR! Failed at the node-sass4…...
【鸿蒙系统学习笔记】网络请求
一、介绍 资料来自官网:文档中心 网络管理模块主要提供以下功能: HTTP数据请求:通过HTTP发起一个数据请求。WebSocket连接:使用WebSocket建立服务器与客户端的双向连接。Socket连接:通过Socket进行数据传输。 日常…...
LabVIEW风力机智能叶片控制系统
LabVIEW风力机智能叶片控制系统 介绍了一种风力机智能叶片控制系统的开发。通过利用LabVIEW软件与CDS技术,该系统能够实时监测并调整风力机叶片的角度,优化风能转换效率。此项技术不仅提高了风力发电的稳定性和效率,而且为风力机的智能化管…...
HarmonyOS Stage模型 权限申请
配置声明权限 在module.json5配置文件中声明权限。不论是system_grant还是user_grant类型都需要声明权限,否则应用将无法获得授权。 {"module" : {// ..."requestPermissions":[{"name": "ohos.permission.DISCOVER_BLUETOOTH…...
标题:从预编译到链接:探索C/C++程序的翻译环境全貌
引言 在软件开发的世界里,我们通常会遇到两种不同的环境——翻译环境与运行环境。今天,我们将聚焦于前者,深入剖析C/C程序生命周期中至关重要的“翻译环境”,即从源代码到可执行文件这一过程中涉及的四个关键阶段:预编…...
深入理解单端模拟多路复用器DG406DW-E3 应用于高速数据采集、ATE系统和航空电子设备解决方案
DG406DW-E3是一款16通道单端模拟多路复用器设计用于将16个输入中的一个连接到公共端口由4位二进制地址确定的输出。应用包括高速数据采集、音频信号切换和路由、ATE系统和航空电子设备。高性能低功耗损耗使其成为电池供电和电池供电的理想选择远程仪器应用。采用44V硅栅CMOS工艺…...
Redis篇----第六篇
系列文章目录 文章目录 系列文章目录前言一、Redis 的持久化机制是什么?各自的优缺点?二、Redis 常见性能问题和解决方案:三、redis 过期键的删除策略?前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章…...
【LeetCode】509. 斐波那契数(简单)——代码随想录算法训练营Day38
题目链接:509. 斐波那契数 题目描述 斐波那契数 (通常用 F(n) 表示)形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始,后面的每一项数字都是前面两项数字的和。也就是: F(0) 0,F(1) 1 F(n) F(n -…...
[OpenGL教程05 ] glAccum() 函数对累积缓存设置
Accumulation Buffer:累积缓存 一、说明 openGL编程之所以困难,是因为它是三维图表示;简简单单加入一个Z轴,却使得几何遮挡、光线过度、运动随影等搞得尤其复杂。它的核心处理环节是像素缓存,本篇的积累缓存就是其一个…...
BeautifulSoup的使用与入门
1. 介绍 BeautifulSoup是用来从HTML、XML文档中提取数据的一个python库,安装如下: pip install beautifulsoup4 它支持多种解析器,包括python标准库、lxml HTML解析器、lxml XML解析器、html5lib等。结合稳定性和速度,这里推荐使用lxml HT…...
LLM之RAG实战(二十七)| 如何评估RAG系统
有没有想过今天的一些应用程序是如何看起来几乎神奇地智能的?这种魔力很大一部分来自于一种叫做RAG和LLM的东西。把RAG(Retrieval Augmented Generation)想象成人工智能世界里聪明的书呆子,它会挖掘大量信息,准确地找到…...
Linux Docker 关闭开机启动
说说自己为什么需要关闭自启动:Linux中安装Docker后,自启动会占用80和443端口,然后使用自己的SSL认证,导致自己Nginx配置的SSL认证失效,网站通过https打开显示不安全。 Docker是一个容器化平台,它可以让开…...
处理器管理补充——线程
传送门:操作系统——处理器管理http://t.csdnimg.cn/avaDO 1.1 线程的概念 回忆:[未引入线程前] 进程有两个基本属性:拥有资源的独立单位、处理器调度和分配的基本单位。 引入线程以后,线程将作为处理器调度和运行的基本单位&…...
RESTful 风格是指什么
RESTful(Representational State Transfer)是一种基于 HTTP 协议的软件架构风格,用于设计网络应用程序的接口。它的设计理念是利用 HTTP 协议中的方法(如 GET、POST、PUT、DELETE 等)来对资源进行 CRUD,使得…...
华为云AI开发平台ModelArts
华为云ModelArts:重塑AI开发流程的“智能引擎”与“创新加速器”! 在人工智能浪潮席卷全球的2025年,企业拥抱AI的意愿空前高涨,但技术门槛高、流程复杂、资源投入巨大的现实,却让许多创新构想止步于实验室。数据科学家…...
RocketMQ延迟消息机制
两种延迟消息 RocketMQ中提供了两种延迟消息机制 指定固定的延迟级别 通过在Message中设定一个MessageDelayLevel参数,对应18个预设的延迟级别指定时间点的延迟级别 通过在Message中设定一个DeliverTimeMS指定一个Long类型表示的具体时间点。到了时间点后…...
系统设计 --- MongoDB亿级数据查询优化策略
系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log,共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题,不能使用ELK只能使用…...
Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务
通过akshare库,获取股票数据,并生成TabPFN这个模型 可以识别、处理的格式,写一个完整的预处理示例,并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务,进行预测并输…...
2025盘古石杯决赛【手机取证】
前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来,实在找不到,希望有大佬教一下我。 还有就会议时间,我感觉不是图片时间,因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...
Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!
一、引言 在数据驱动的背景下,知识图谱凭借其高效的信息组织能力,正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合,探讨知识图谱开发的实现细节,帮助读者掌握该技术栈在实际项目中的落地方法。 …...
【HTML-16】深入理解HTML中的块元素与行内元素
HTML元素根据其显示特性可以分为两大类:块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...
uniapp中使用aixos 报错
问题: 在uniapp中使用aixos,运行后报如下错误: AxiosError: There is no suitable adapter to dispatch the request since : - adapter xhr is not supported by the environment - adapter http is not available in the build 解决方案&…...
【Android】Android 开发 ADB 常用指令
查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...
苹果AI眼镜:从“工具”到“社交姿态”的范式革命——重新定义AI交互入口的未来机会
在2025年的AI硬件浪潮中,苹果AI眼镜(Apple Glasses)正在引发一场关于“人机交互形态”的深度思考。它并非简单地替代AirPods或Apple Watch,而是开辟了一个全新的、日常可接受的AI入口。其核心价值不在于功能的堆叠,而在于如何通过形态设计打破社交壁垒,成为用户“全天佩戴…...
