当前位置: 首页 > news >正文

设计模式之抽象工厂模式--创建一系列相关对象的艺术(简单工厂、工厂方法、到抽象工厂的进化过程,类图NS图)

目录

  • 概述
    • 概念
    • 适用场景
    • 结构
    • 类图
  • 衍化过程
    • 业务需求
    • 基本的数据访问程序
    • 工厂方法实现数据访问程序
    • 抽象工厂实现数据访问程序
    • 简单工厂改进抽象工厂
    • 使用反射+抽象工厂
    • 反射+配置文件
    • 衍化过程总结
  • 常见问题
  • 总结

概述

概念

    抽象工厂模式是一种创建型设计模式,它提供了一种将相关对象组合在一起创建的方式,而无需指定具体类。该模式通过定义一个抽象工厂接口来创建一系列相关或依赖的对象,而不是直接实例化具体类。这种方式使得系统更加灵活,易于扩展和维护。

适用场景

抽象工厂模式适用于以下情况:

当一个系统需要独立于其产品的创建、组合和表示时;
当一个系统需要由多个系列的产品中的一个进行配置时;
当强调一系列相关产品对象的创建和一起使用时;
当提供一个产品类库,而只想显示它们的接口而不是实现时。

结构

抽象工厂模式包含以下几个角色:

抽象工厂(Abstract Factory):声明了创建一系列产品对象的接口。
具体工厂(Concrete Factory):实现了抽象工厂接口,具体工厂负责创建具体的产品对象。
抽象产品(Abstract Product):声明了具体产品的接口。
具体产品(Concrete Product):实现了抽象产品接口,具体产品是由具体工厂创建的。

类图

在这里插入图片描述

衍化过程

业务需求

    假设有一个简单的应用程序,它使用了 SQL Server 数据库来存储数据。现在需要将数据库更换为 Access 数据库,同时保持应用程序的功能不变。

基本的数据访问程序

在这里插入图片描述
客户端直接和qlserverUser耦合
在这里插入图片描述

//SqlServer
public class SqlServerUser {//新增用户public void insert(User user){System.out.println("在SQlServer中给USER表添加一条数据");}//获取用户信息public User getUser(int id){System.out.println("在SQlServer中根据用户id得到USER表中的一条记录");return null;}
}//user表
public class User {private int _id;public int getid(){return this._id;}public void setId(int value){this._id=value;}private String _name;public String getname(){return this._name;}public void setname(String value){this._name=value;}
}//客户端
public class Client {public static void main(String[] args) {User user=new User();SqlServerUser su=new SqlServerUser();su.insert(user);su.getUser(1);}
}

    在这段客户端代码中,可以看到SqlServerUser su=new SqlServerUser();使su这个对象被框死在了SqlServerUser上。
    现在要做的就是解除客户端和SqlServerUser 的耦合(简答说就是客户端不再依赖SqlServerUser ,那么更换其他的数据库管理系统就不会影响应用程序了)

工厂方法实现数据访问程序

    解除客户端和SqlServerUser对象的耦合,就是把 new SqlServerUser()封装起来,这点上想到使用工厂方法封装new SqlServerUser()过程。
在这里插入图片描述
在这里插入图片描述

抽出两个接口

//工厂接口
interface IFactory {public IUser  creatUserDB();}
//数据库接口
public interface IUser {public void insert(User user);public User getUser(int id);
}//SqlServerUser ,用于访问SqlServer的User 
public class SqlServerUser implements IUser {//新增用户@Overridepublic void insert(User user) {System.out.println("在SQlServer中给USER表添加一条数据");}public User getUser(int id){System.out.println("在SQlServer中根据用户id得到USER表中的一条记录");return null;}
}
//SqlServerFactory 实例化SqlServerUser
public class SqlServerFactory implements IFactory {@Overridepublic IUser creatUser() {return new SqlServerUser();}
}//客户端
public static void main(String[] args) {Ifactory factory=new SqlServerFactory();User user=new User();IUser iu = factory.creatUser();iu.insert(user);iu.getUser(1);}

    再来看客户端声明IUser接口的对象iu,事先并不知道要访问哪个数据库,却可以在运行时完成工作,这就是业务逻辑和数据访问的解耦(也就是客户端不再依赖SqlServerUser,如果需要更换AccessUser,只需要创建一个AccessFactory,由AccessFactory封装创建AccessUser对象的过程。)
    现在又有了新的问题:
    数据库里如果不是只有一个User表呢,该怎么办?

抽象工厂实现数据访问程序

    现在需要增加一个Department表,SqlServer和Access分别操作这个Department表,
    再抽出一个IDepartment的接口,两个工厂了分别增加创建SqlserverDepartment和AccessDepartment的方法

在这里插入图片描述
在这里插入图片描述
工厂里两个方法,可以有不同的实现,可以理解为两个不同的系列

//工厂接口
public interface IFactory {public IUser creatUserDB();public IDepartment createDepartment();
}
//客户端
public class Client {public static void main(String[] args) {//需要对两个表操作,客户端只认识两个表,不认识Access和SQLServerUser user = new User();Department department = new Department();//需要用哪个DBMS就实例化哪个工厂IFactory factory = new SqlServerFactory();//实例化数据库交给对应的工厂IUser iu = factory.creatUserDB();//user表里插入,读取操作iu.getUser(1);iu.insert(user);IDepartment idept=factory.createDepartment();//department表里插入,读取操作idept.getDepartment(2);idept.insert(department);}
}

    再分析一下需求,我们是要读写User表和Department表,IUser和IDepartment里有对应的方法,也就是干活的是这两个接口的实现类,SqlServerUser、AccessUser;以及SqlServerDepartment、AccessDepartment,那谁负责生产这些实现类的对象呢,那就看谁的返回对象是IUser和IDepartment,当然是工厂,SqlServerFactory和AccessFactory.

  • 抽象工厂的优势现在体现出来了:
    1、易于交换产品系列
    由于具体工厂类,例如Factory factory=new AccessFactory0,
    在一个应用中只需要在初始化的时候出现一次,这就使得改变一个应用的具体工厂变得非常容易,它只需要改变具体工厂即可使用不同的产品配置。
    我们的设计不能去防止需求的更改,那么我们的理想便是让改动变得最小
    2、它让具体的创建实例过程与客户端分离(这点工厂方法也做到了)
    客户端是通过它们的抽象接口操纵实例,产品的具体类名也被具体工厂的实现分离,不会出现在客户代码中。事实上客户端所认识的只有User和Department,至于它是用SQL Server来实现还是Access来实现就不知道了。”

  • 但是仍然存在的问题:
    1、业务扩充
    要增加项目表Project,至少要增加三个类,IProject、.SqlserverProject、AccessProject,.还需要更改IFactory、SqlserverFactory和AccessFactory才可以完全实现。(对应两个表的两个dbms,两个生产dbms的工厂,还有两个接口)
    2、客户端如果多个,改动就很多
    有很多地方使用IUesr或Department,而这样的设计,其实在每一个类的开始都需要声明Factory factory=new SqlserverFactory0,如果有100个调用数据库访问的类,就要更改l00次Factory factory=new AccessFactory()这样的代码

简单工厂改进抽象工厂

    抽象工厂客户端耦合太多
    去掉工厂,创建对象交给DateAccess
在这里插入图片描述
在这里插入图片描述

//DataAccess 负责创建具体数据库对象
public class public class DataAccess {private static String db="Sqlserver";//可换成Access//创建用户对象工厂public static IUser createUser(){IUser result=null;switch (db){case "Sqlserver":result=new SqlServerUser();break;case "Access":result=new AccessUser();break;}return result;}//创建部门对象工厂public static  IDepartment createDepartment(){IDepartment result=null;switch (db){case "Sqlserver":result=new SqlServerDepartment();break;case "Access":result=new AccessDepartment();break;}return result;}}
{private static String db="Sqlserver";//可换成Access//创建用户对象工厂public static IUser createUser(){IUser result=null;switch (db){case "Sqlserver":result=new SqlServerUser();break;case "Access":result=new AccessUser();break;}return result;}//创建部门对象工厂public static  IDepartment createDepartment(){IDepartment result=null;switch (db){case "Sqlserver":result=new SqlServerDepartment();break;case "Access":result=new AccessDepartment();break;}return result;}}//客户端
public class Client {public static void main(String[] args) {//需要对两个表操作,客户端只认识两个表,不认识Access和SQLServerUser user = new User();Department department = new Department();//实例化数据库交给DataAccessIUser iu = DataAccess.createUser();//user表里插入,读取操作iu.getUser(1);iu.insert(user);IDepartment idept=DataAccess.createDepartment();//department表里插入,读取操作idept.getDepartment(2);idept.insert(department);}
}

问题:
    如果需要增加Oracle数据库访问,抽象工厂只增加一个OracleFactory工厂类就可以了,现在就需要在DataAccess类中每个方法的swicth中加case
改进:
    不在程序里写明‘如果是Sqlserver就去实例化SQL Server数据库相关类,如果是Access就去实例化Access相关类’这样的语句,而是根据字符串db的值去某个地方找应该要实例化的类是哪一个。这样就不用switch case了

使用反射+抽象工厂

类图只改变DataAccess就可以
在这里插入图片描述
在这里插入图片描述

public class DataAccess {private static String assemblyName="designpatterns.abstractfactory.reflaxAbstractFactoryAccess.DB.";private static String db="SqlServer";//数据库名称,可替换为Access//创建用户对象工厂public static IUser createUser(){return (IUser)getInstance(assemblyName+db+"User");}//创建部门对象工厂public static IDepartment createDepartment(){return (IDepartment) getInstance(assemblyName+db+"Department");}private static  Object getInstance(String className){Object result=null;try {result=Class.forName(className).getDeclaredConstructor().newInstance();}catch(InvocationTargetException e){e.printStackTrace();}catch(NoSuchMethodException e){e.printStackTrace();}catch(InstantiationException e){e.printStackTrace();}catch(IllegalAccessException e){e.printStackTrace();}catch(ClassNotFoundException e){e.printStackTrace();}return result;}}

    对象可以根据类路径动态创建了,但是在更换数据库访问时,还是需要去改程序(改db这个字符串的值)重编译,如果可以不改程序,那才是真正地符合开放-封闭原则。

反射+配置文件

相对于只用反射,属性db(数据库名)动态获取了
在这里插入图片描述

public class DataAccess {private static String assemblyName="designpatterns.abstractfactory.profileReflaxAbstractFactoryAccess.DB.";public static String getDb() throws IOException {String result="";Properties properties=new Properties();properties.load(new FileInputStream("E:\\tgb\\training program\\java\\myProject\\src\\main\\java\\designpatterns\\abstractfactory\\profileReflaxAbstractFactoryAccess\\db.properties"));result=properties.getProperty("db");return result;}//创建用户对象工厂public static IUser createUser() throws IOException, ClassNotFoundException, InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {String db=getDb();return (IUser)getInstance(assemblyName+db+"User");}
//反射获取对象public static  IDepartment createDepartment() throws IOException, ClassNotFoundException, InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {String db=getDb();return (IDepartment) getInstance(assemblyName+db+"Department");}private static  Object getInstance(String className) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {Object result=null;result=Class.forName(className).getDeclaredConstructor().newInstance();     return result;}}

进步:
    如果更换数据库,无须重新编译代码,只需要改配置文件就可以。
    所有在用简单工厂的地方,都可以考虑用反射技术来去除switch或if,解除分支判断带来的耦合。”
    反射技术可以很好地解决switch 或者if分支难以应对变化,难以维护和扩展的诟病。

衍化过程总结

    在上面的示例中,业务需求是通过数据库连接来执行查询操作。一开始,使用了简单的数据访问方式,直接在应用程序中编写了连接和查询数据库的代码。

    随着业务的发展,需要将数据库从 SQL Server 更换为 Access。为了实现这个数据库更换的需求,采用了工厂方法模式。通过引入抽象产品(IUser)和具体产品(SqlServerUser和AccessUser),抽象工厂(IFactory)和具体工厂(SqlServerFactory和AccessFactory)将数据库连接的创建和使用进行了解耦,使得代码更加灵活和可扩展。

    然后,需要增加一个部门表,让两个数据库去访问,为了应对这种变化,引入了抽象工厂模式。通过在具体工厂(SqlServerFactory和AccessFactory)中增加一个creatDepartment方法,解决了创建SqlServerDepartment和AccessDepartment的问题。
后面又为了更加灵活,介绍了用简单工厂来改进抽象工厂,以及使用反射和配置文件,真正实现三高。

    每次的变化都是为了应对业务需求的不断变化。最初的简单数据访问方式可能适应了当时的需求,但随着业务的发展和技术环境的变化,需要更灵活、可扩展的解决方案。工厂方法和抽象工厂模式提供了一种可扩展的设计,使得我们能够快速适应业务变化,并以相对低的开销进行数据库类型的切换。

常见问题

什么是一系列相关或依赖的对象?
    一系列相关或相互依赖的对象指的是一组具有共同特征或者相互之间存在某种关联关系的对象集合。这些对象通常有着相似或者相互关联的功能、属性或行为。
如何判断这些对象是一系列相关或相互依赖的呢?

  • 共同特征:这些对象具有共同的特征或者属性。例如,它们可能都实现了同一个接口或者继承了同一个抽象类,并拥有类似的方法或属性。

  • 相互关联:这些对象之间存在某种关联关系,彼此之间相互依赖。例如,它们可能是一种逻辑上或功能上相关的对象,需要协同工作以完成某个复杂的任务。

  • 执行步骤:这些对象在特定的操作过程中需要按照一定的顺序或流程进行调用。它们可能是按照特定的顺序被创建、初始化、配置或者销毁的。

  • 统一管理:这些对象可能需要由同一个抽象工厂来创建和管理。抽象工厂可以提供一种统一的方式来创建这些对象,确保它们之间的协调性和一致性。

    总之,一系列相关或相互依赖的对象在抽象工厂模式中是作为一个整体出现的,它们具有共同特征、相互关联,需要按照一定顺序进行操作,并由同一个抽象工厂进行创建和管理。这样可以更好地实现对象之间的协作和组织。
举个栗子
在这里插入图片描述

    比如有一个一个汽车制造厂,可以使用抽象工厂模式来创建一系列相关或相互依赖的对象。

    假设汽车制造厂需要生产不同类型的汽车,如轿车(Sedan)和SUV(Sport Utility Vehicle)。每种类型的汽车由多个部件构成,包括引擎(Engine)、底盘(Chassis)和车身(Body)等。

在这个例子中,可以定义以下抽象类和接口:

  • CarFactory(抽象工厂):定义了用于创建汽车部件的方法。
  • Engine(抽象产品):定义了引擎的功能。
  • Chassis(抽象产品):定义了底盘的功能。
  • Body(抽象产品):定义了车身的功能。

具体的类可以包括:

  • SedanCarFactory(具体工厂):实现了CarFactory接口,并负责创建轿车相关的部件。

  • SedanEngine(具体产品):实现了Engine接口,提供了轿车引擎的具体功能。

  • SedanChassis(具体产品):实现了Chassis接口,提供了轿车底盘的具体功能。

  • SedanBody(具体产品):实现了Body接口,提供了轿车车身的具体功能。

  • SuvCarFactory(具体工厂):实现了CarFactory接口,并负责创建SUV相关的部件。

  • SuvEngine(具体产品):实现了Engine接口,提供了SUV引擎的具体功能。

  • SuvChassis(具体产品):实现了Chassis接口,提供了SUV底盘的具体功能。

  • SuvBody(具体产品):实现了Body接口,提供了SUV车身的具体功能。

    在这个例子中,抽象工厂模式将一系列相关或相互依赖的对象(引擎、底盘和车身)组合到具体的工厂中(轿车工厂和SUV工厂)。每个具体工厂负责创建特定类型汽车所需的部件,并保证这些部件之间的协调性和一致性。

    例如,当需要生产一辆轿车时,可以使用SedanCarFactory创建引擎、底盘和车身。而当需要生产一辆SUV时,可以使用SuvCarFactory创建相应的部件。

    通过使用抽象工厂模式,汽车制造厂可以轻松扩展以生产不同类型的汽车,而无需修改现有代码。同时,不同类型的汽车部件之间的依赖关系也得到了良好的管理和维护,提高了系统的可维护性和可扩展性。

总结

    抽象工厂模式通过引入抽象工厂接口,使得客户端代码与具体产品的实现解耦。它提供了一种简单的方式来创建一系列相关的产品对象,而无需关心具体的实现细节。通过选择不同的具体工厂,可以轻松地切换不同的产品系列,以满足不同的需求。抽象工厂模式在大型系统中非常有用,它能够提高代码的可维护性、可扩展性和可测试性。

相关文章:

设计模式之抽象工厂模式--创建一系列相关对象的艺术(简单工厂、工厂方法、到抽象工厂的进化过程,类图NS图)

目录 概述概念适用场景结构类图 衍化过程业务需求基本的数据访问程序工厂方法实现数据访问程序抽象工厂实现数据访问程序简单工厂改进抽象工厂使用反射抽象工厂反射配置文件衍化过程总结 常见问题总结 概述 概念 抽象工厂模式是一种创建型设计模式,它提供了一种将相…...

大数据-玩转数据-Flink SQL编程实战 (热门商品TOP N)

一、需求描述 每隔30min 统计最近 1hour的热门商品 top3, 并把统计的结果写入到mysql中。 二、需求分析 1.统计每个商品的点击量, 开窗2.分组窗口分组3.over窗口 三、需求实现 3.1、创建数据源示例 input/UserBehavior.csv 543462,1715,1464116,pv,1511658000 662867,22…...

python中实现定时任务的几种方案

目录 while True: sleep()Timeloop库threading.Timersched模块schedule模块APScheduler框架Celery框架数据流工具Apache Airflow概述Airflow 核心概念Airflow 的架构 总结以下几种方案实现定时任务,可根据不同需求去使用不同方案。 while True: sleep() 利用whil…...

AcWing算法提高课-5.6.1同余方程

宣传一下 算法提高课整理 CSDN个人主页:更好的阅读体验 原题链接 题目描述 求关于 x x x 的同余方程 a x ≡ 1 ( m o d b ) ax ≡ 1 \pmod b ax≡1(modb) 的最小正整数解。 输入格式 输入只有一行,包含两个正整数 a , b a,b a,b,用一…...

Docker Tutorial

什么是Docker 为每个应用提供完全隔离的运行环境 Dockerfile, Image,Container Image: 相当于虚拟机的快照(snapshot)里面包含了我们需要部署的应用程序以及替它所关联的所有库。通过image,我们可以创建很…...

平面图—简单应用

平面图:若一个图𝐺能画在平面𝑆上,且使𝐺的边仅在端点处相交,则称图𝐺为可嵌入平面𝑆,𝐺称为可平面图,简称为平面图。 欧拉公式:设有…...

安装JDK(Java SE Development Kit)超详细教程

文章时间 : 2023-10-04 1. 下载地址 直接去下载地址:https://www.oracle.com/java/technologies/downloads/ (需要翻墙,不想翻墙或者不想注册oracel账号的,直接去我的阿里云盘) 阿里云盘:http…...

KUKA机器人通过3点法设置工作台基坐标系的具体方法

KUKA机器人通过3点法设置工作台基坐标系的具体方法 具体方法和步骤可参考以下内容: 进入主菜单界面,依次选择“投入运行”—“测量”—基坐标,选择“3点法”, 在系统弹出的基坐标编辑界面,给基座标编号为3,命名为table1,然后单击“继续”按钮,进行下一步操作, 在弹出的…...

以太网的MAC层

以太网的MAC层 一、硬件地址 ​ 局域网中,硬件地址又称物理地址或MAC地址(因为用在MAC帧),它是局域网上每一台计算机中固化在适配器的ROM中的地址。 ​ 关于地址问题,有这样的定义:“名字指出我们所要寻…...

Hadoop启动后jps发现没有DateNode解决办法

多次使用 Hadoop namenode -format 格式化节点后DateNode丢失 找到hadoop配置文件core-site.xml查找tmp路径 进入该路径,使用rm -rf data删除data文件 再次使用Hadoop namenode -format 格式化后jps后出现DateNode节点...

VUE3照本宣科——应用实例API与setup

VUE3照本宣科——应用实例API与setup 前言一、应用实例API1.createApp()2.app.use()3.app.mount() 二、setup 前言 👨‍💻👨‍🌾📝记录学习成果,以便温故而知新 “VUE3照本宣科”是指照着中文官网和菜鸟教…...

json/js对象的key有什么区别?

1.对于JS对象来说 一个js对象如果是这样的 obj {"0": "小明","0name": "小明明", "": 18,"¥": "哈哈"," ": "爱好广泛" }对于js对象来说,有时候key是不…...

极大似然估计概念的理解——统计学习方法

目录 1.最大似然估计的概念的理解1 2.最大似然估计的概念的理解2 3.最大似然估计的概念的理解3 4.例子 1.最大似然估计的概念的理解1 最大似然估计是一种概率论在统计学上的概念,是参数估计的一种方法。给定观测数据来评估模型参数。也就是模型已知,参…...

python模拟表格任意输入位置

在表格里输入数值,要任意位置,我找到了好方法: input输入 1. 行 2. 列输入:1 excel每行输入文字input输入位置 3.2 表示输入位置在:3行个列是要实现一个类似于 Excel 表格的输入功能,并且希望能够指定输入…...

如何限制文件只能通过USB打印机打印,限制打印次数和时限并且无法在打印前查看或编辑内容

在今天这个高度信息化的时代,文档打印已经成为日常工作中不可或缺的一部分。然而,这也带来了诸多安全风险,如文档被篡改、知识产权被侵犯以及信息泄露等。为了解决这些问题,只印应运而生。作为一款独特的软件工具,只印…...

车牌文本检测与识别:License Plate Recognition Based On Multi-Angle View Model

论文作者:Dat Tran-Anh,Khanh Linh Tran,Hoai-Nam Vu 作者单位:Thuyloi University;Posts and Telecommunications Institute of Technology 论文链接:http://arxiv.org/abs/2309.12972v1 内容简介: 1)方向&#x…...

Blender中的4种视图着色模式

Blender中有四种主要的视图着色模式:线框、实体、Look Dev和渲染。它们的主要区别如下: - 线框模式只显示物体的边缘(线框),可以让您看到场景中的所有物体,也可以调整线框的颜色和背景的颜色。 - 实…...

Flutter项目安装到Android手机一直显示在assembledebug

问题 Flutter项目安装到Android手机一直显示在assembledebug 原因 网络不好,gradle依赖下载不下来 解决方案 修改如下的文件 gradle-wrapper.properties 使用腾讯提供的gradle镜像下载 distributionUrlhttps://mirrors.cloud.tencent.com/gradle/gradle-7.5…...

数据挖掘实验(二)数据预处理【等深分箱与等宽分箱】

一、分箱平滑的原理 (1)分箱方法 在分箱前,一定要先排序数据,再将它们分到等深(等宽)的箱中。 常见的有两种分箱方法:等深分箱和等宽分箱。 等深分箱:按记录数进行分箱&#xff0…...

Vue2 第一次学习

本章为超级浓缩版,文章过于短,方便复习使用哦~ 文章目录 1. 简单引入 vue.js2. 指令2.1 事件绑定指令 v-on (简写 )2.2 内容渲染指令2.3 双向绑定指令 v-model2.4 属性绑定指令 v-bind (简写 : )2.5 条件渲染指令2.6 循环指令 v-for 3. vue 其他知识3.1 侦听器 watch3.2 计算属…...

tiny模式基本原理整合

【Tiny模式】的基本构成 M【首头在首位】 U【/】 V【HTTP/】 Host H【真实ip】 XH \r回车 \n换行 \t制表 \ 空格 一个基本的模式构成 [method] [uri] [version]\r\nHost: [host]\r\n[method] [uri] [version]\r\nHost: [host]\r\n 检测顺序 http M H XH 有些地区 XH H M 我这边…...

使用聚氨酯密封件的好处?

聚氨酯密封件因其优异的耐用性、灵活性和广泛的应用范围而在各个行业中广受欢迎。在本文中,我们将探讨使用聚氨酯密封件的优点,阐明其在许多不同领域广泛使用背后的原因。 1、高性能: 聚氨酯密封件具有出色的性能特征,使其成为各…...

DevEco Studio如何安装中文插件

首先 官网下载中文插件 由于DevEco是基于IntelliJ IDEA Community的,所有Compatibility选择“IntelliJ IDEA Community”,然后下载一个对应最新的就ok了。 最后打开Plugins页面,点击右上角齿轮 -> Install Plugin from Disk…。选择下载的…...

10.2 校招 实习 内推 面经

绿泡*泡: neituijunsir 交流裙 ,内推/实习/校招汇总表格 1、校招 | 国家电网 国网信通产业集团2024届校园招聘! 校招 | 国家电网 国网信通产业集团2024届校园招聘! 2、校招 | 海信集团2024届全球校园招聘正式启动&#xff01…...

Golang 语言学习 01 包含如何快速学习一门新语言

Golang方向 区块链 go服务器端 (后台流量支撑程序) 支撑主站后台流量(排序,推荐,搜索等),提供负载均衡,cache,容错,按条件分流,统计运行指标 (qps, latenc…...

整理了197个经典SOTA模型,涵盖图像分类、目标检测、推荐系统等13个方向

今天来帮大家回顾一下计算机视觉、自然语言处理等热门研究领域的197个经典SOTA模型,涵盖了图像分类、图像生成、文本分类、强化学习、目标检测、推荐系统、语音识别等13个细分方向。建议大家收藏了慢慢看,下一篇顶会的idea这就来了~ 由于整理的SOTA模型…...

10.4 小任务

目录 QT实现TCP服务器客户端搭建的代码&#xff0c;现象 TCP服务器 .h文件 .cpp文件 现象 TCP客户端 .h文件 .cpp文件 现象 QT实现TCP服务器客户端搭建的代码&#xff0c;现象 TCP服务器 .h文件 #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #includ…...

AJAX--Express速成

一、基本概念 1、AJAX(Asynchronous JavaScript And XML)&#xff0c;即为异步的JavaScript 和 XML。 2、异步的JavaScript 它可以异步地向服务器发送请求&#xff0c;在等待响应的过程中&#xff0c;不会阻塞当前页面。浏览器可以做自己的事情。直到成功获取响应后&#xf…...

开题报告 PPT 应该怎么做

开题报告 PPT 应该怎么做 1、报告时首先汇报自己的姓名、单位、专业和导师。 2、研究背景&#xff08;2-3张幻灯片&#xff09; 简要阐明所选题目的研究目的及意义。 研究的目的&#xff0c;即研究应达到的目标&#xff0c;通过研究的背景加以说明&#xff08;即你为什么要…...

JavaScript系列从入门到精通系列第十四篇:JavaScript中函数的简介以及函数的声明方式以及函数的调用

文章目录 一&#xff1a;函数的简介 1&#xff1a;概念和简介 2&#xff1a;创建一个函数对象 3&#xff1a;调用函数对象 4&#xff1a;函数对象的普通功能 5&#xff1a;使用函数声明来创建一个函数对象 6&#xff1a;使用函数声明创建一个匿名函数 一&#xff1a;函…...

月夜影院/怎么样优化网站seo

求素数只需要到i*i<x for(int i2; i*i<x i) 1、素数&#xff0c;所以没有1&#xff0c;从2开始。 2、一个数如果不是素数&#xff0c;最大的因子该是小于等于x/2&#xff0c;在大根本没法除。 3、进一步确定到根号x&#xff0c;一个数如果不是素数&#xff0c;意味着一定…...

乌鲁木齐人才网/搜索引擎优化的技巧

计算机操作系统期末考试题目及答案(选择题)答案绝对正确广药师姐一、单项选择题(本大题共20小题&#xff0c;每小题2分&#xff0c;共40分)。1位示图方法可用于()A、盘空间的管理B盘的驱动调度C、文件目录的查找D页式虚拟存贮管理中的页面调度凡是有盘空间三个字就选2.下列关于…...

东莞市手机网站建设/2345浏览器网站进入

一&#xff1a;什么是Ajax? Ajax&#xff1a;异步的JavaScript和XML&#xff0c;用于完成网页局部刷新功能&#xff08;修改少量数据只用局部刷新&#xff0c;不用再整个网页重新加载&#xff09;&#xff1b; XML的作用&#xff1a;1.是用于数据传输&#xff0c;但现在都在使…...

长沙公积金网站怎么做异动/关键词的选取原则

HBase之Rowkey设计总结及易观方舟实战篇 代立冬 2018-06-02 21:52:46 3466 收藏 10 最后发布:2018-06-02 21:52:46首发:2018-06-02 21:52:46分类专栏&#xff1a; --------【HBase优化】 ●HBase 大数据实战系列 版权声明&#xff1a;本文为博主原创文章&#xff0c;遵循…...

网站开发所得税/爱战网官网

题目链接 链接&#xff1a;https://leetcode.com/problems/max-sum-of-rectangle-no-larger-than-k/description/ 题解&代码 1、暴力枚举所有的情况&#xff0c;时间复杂度O(n^2*m^2)&#xff0c;实际耗时759 ms class Solution { public:int maxSumSubmatrix(vector<ve…...

在哪里找做网站的/网站建设情况

浙江省赛补 IMagic Points 比赛时&#xff0c;我还在一直纠结&#xff0c;5 3这条线为啥不行&#xff0c;结果下来才知道题目不能有重复点没有说&#xff0c;然后fdf说应该是2 7或者 2 5那条线&#xff0c;我也只能通过画图连猜想了。。。 #include <cstdio> #include &l…...