01 设计模式-创造型模式-工厂模式

  • 工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一,它提供了一种创建对象的方式,使得创建对象的过程与使用对象的过程分离。

  • 工厂模式提供了一种创建对象的方式,而无需指定要创建的具体类。

  • 通过使用工厂模式,可以将对象的创建逻辑封装在一个工厂类中,而不是在客户端代码中直接实例化对象,这样可以提高代码的可维护性和可扩展性。

设计模式,最近持续更新中,如需要请关注

如果你觉得我分享的内容或者我的努力对你有帮助,或者你只是想表达对我的支持和鼓励,请考虑给我点赞、评论、收藏。您的鼓励是我前进的动力,让我感到非常感激。

文章目录

  • 1 概要
  • 2 实现
  • 3 Demo代码
  • 4 开发案例
    • 4.1 算法执行服务里,不同的任务数据来源不同,执行脚本类型不同,结果处理不同,使用工厂模式
    • 4.2 网络还原时,不同的采集数据,解析处理方式不同

1 概要

意图
定义一个创建对象的接口,让其子类决定实例化哪一个具体的类。工厂模式使对象的创建过程延迟到子类。

主要解决
接口选择的问题。

何时使用
当我们需要在不同条件下创建不同实例时。

如何解决
通过让子类实现工厂接口,返回一个抽象的产品。

关键代码
对象的创建过程在子类中实现。

应用实例

  1. 汽车制造:你需要一辆汽车,只需从工厂提货,而不需要关心汽车的制造过程及其内部实现。
  2. Hibernate:更换数据库时,只需更改方言(Dialect)和数据库驱动(Driver),即可实现对不同数据库的切换。

优点

  1. 调用者只需要知道对象的名称即可创建对象。
  2. 扩展性高,如果需要增加新产品,只需扩展一个工厂类即可。
  3. 屏蔽了产品的具体实现,调用者只关心产品的接口。

缺点
每次增加一个产品时,都需要增加一个具体类和对应的工厂,使系统中类的数量成倍增加,增加了系统的复杂度和具体类的依赖。

使用场景

  1. 日志记录:日志可能记录到本地硬盘、系统事件、远程服务器等,用户可以选择记录日志的位置。
  2. 数据库访问:当用户不知道最终系统使用哪种数据库,或者数据库可能变化时。
  3. 连接服务器的框架设计:需要支持 “POP3”、“IMAP”、“HTTP” 三种协议,可以将这三种协议作为产品类,共同实现一个接口。
  4. 在算法执行服务中,每个任务需要处理的数据来源不同,根据数据类型创建对应的数据出来handle类,不用关心handle里的内部处理逻辑

注意事项
工厂模式适用于生成复杂对象的场景。如果对象较为简单,通过 new 即可完成创建,则不必使用工厂模式。使用工厂模式会引入一个工厂类,增加系统复杂度。

结构
工厂模式包含以下几个主要角色:

  • 抽象产品(Abstract Product):定义了产品的共同接口或抽象类。它可以是具体产品类的父类或接口,规定了产品对象的共同方法。
  • 具体产品(Concrete Product):实现了抽象产品接口,定义了具体产品的特定行为和属性。
  • 抽象工厂(Abstract Factory):声明了创建产品的抽象方法,可以是接口或抽象类。它可以有多个方法用于创建不同类型的产品。
  • 具体工厂(Concrete Factory):实现了抽象工厂接口,负责实际创建具体产品的对象。

2 实现

我们将创建一个 Shape 接口和实现 Shape 接口的实体类。下一步是定义工厂类 ShapeFactory。

FactoryPatternDemo 类使用 ShapeFactory 来获取 Shape 对象。它将向 ShapeFactory 传递信息(CIRCLE / RECTANGLE / SQUARE),以便获取它所需对象的类型。
请添加图片描述

3 Demo代码

在这里插入图片描述
Shape

/**
 * 公共接口
 */
public interface Shape {
    void draw();
}

Circle

/**
 * 圆形,形状的实现类
 */
public class Circle implements Shape {

    @Override
    public void draw() {
        System.out.println("Inside Circle::draw() method.");
    }
}

Rectangle

/**
 * 矩形,形状的实现类
 */
public class Rectangle implements Shape {

    @Override
    public void draw() {
        System.out.println("Inside Rectangle::draw() method.");
    }
}

Square

/**
 * 方形,形状的实现类
 */
public class Square implements Shape {

    @Override
    public void draw() {
        System.out.println("Inside Square::draw() method.");
    }
}

ShapeFactory

/**
 * 形状工厂类【根据不同的参数创建对应的实例】
 */
public class ShapeFactory {

    //使用 getShape 方法获取形状类型的对象
    public Shape getShape(String shapeType) {
        if (shapeType == null) {
            return null;
        }
        if (shapeType.equalsIgnoreCase("CIRCLE")) {
            return new Circle();
        } else if (shapeType.equalsIgnoreCase("RECTANGLE")) {
            return new Rectangle();
        } else if (shapeType.equalsIgnoreCase("SQUARE")) {
            return new Square();
        }
        return null;
    }
}

FactoryPatternDemo

/**
 *    总结:用来根据不同的参数创建对象
 */
public class FactoryPatternDemo {

    public static void main(String[] args) {
        ShapeFactory shapeFactory = new ShapeFactory();

        //获取 Circle 的对象,并调用它的 draw 方法
        Shape shape1 = shapeFactory.getShape("CIRCLE");
        //调用 Circle 的 draw 方法
        shape1.draw();

        //获取 Rectangle 的对象,并调用它的 draw 方法
        Shape shape2 = shapeFactory.getShape("RECTANGLE");
        //调用 Rectangle 的 draw 方法
        shape2.draw();

        //获取 Square 的对象,并调用它的 draw 方法
        Shape shape3 = shapeFactory.getShape("SQUARE");
        //调用 Square 的 draw 方法
        shape3.draw();
    }
}

效果
在这里插入图片描述

4 开发案例

4.1 算法执行服务里,不同的任务数据来源不同,执行脚本类型不同,结果处理不同,使用工厂模式

请添加图片描述
说明:

  • TaskAbstractFactory命名成抽象工厂,可以创建出来DataSetHandle工厂,ScriptExecuteHandle工厂,ResultHandle工厂,但是实现时,时间关系,简化成简单工厂模式。
  • 工厂返回的对象,每次都是新创建出来的,因为这些handle每次创建初始化的参数是不同的,和下面的第二个案例有所不同

在这里插入图片描述

工厂类

/**
 * 任务抽象工厂类,创建各种处理类
 * @since 2023 -10-08 16:13
 */
public class TaskAbstractFactory {
    private static final Logger LOGGER = LoggerFactory.getLogger(TaskAbstractFactory.class);

    /**
     * Gets script execute handle.
     *
     * @param scriptParam the script param
     * @param algoId the algo id
     * @return the script execute handle
     */
    public static ScriptExecuteHandle getScriptExecuteHandle(ScriptParam scriptParam, String algoId) {
        if (Constants.ScriptType.PYTHON.equals(scriptParam.getScriptType()) || Constants.ScriptType.PYTHON3.equals(
            scriptParam.getScriptType())) {
            return new PythonScriptExecuteHandle(scriptParam);
        } else {
            LOGGER.error("The algorithm type is not supported. algoId: {} ,scriptType: {} ", algoId,
                scriptParam.getScriptType());
            throw new CommonServiceException(AIModelError.ALGO_TYPE_NOT_SUPPORTED);
        }
    }

    /**
     * Gets data set handle list.
     *
     * @param dataSets the data sets
     * @return the data set handle list
     */
    public static List<DataSetHandle> getDataSetHandleList(List<InputDataSource> dataSets) {
        ArrayList<DataSetHandle> dataSetHandleList = new ArrayList<>(10);
        for (InputDataSource inputDataSource : dataSets) {
            dataSetHandleList.add(getDataSetHandle(inputDataSource));
        }
        return dataSetHandleList;
    }

    /**
     * Gets data set handle.
     *
     * @param inputDataSource the input data source
     * @return the data set handle
     */
    public static DataSetHandle getDataSetHandle(InputDataSource inputDataSource) {
        if (Constants.DataSourceType.MINIO_FILE.equalsIgnoreCase(inputDataSource.getDatatype())) {
            DataSetHandle dataSetHandle = new S3DataSetHandle(inputDataSource.getDataSourceInfo(),
                inputDataSource.getDataSourceConfig());
            // 进行数据源校验
            dataSetHandle.checkDataSource();
            return dataSetHandle;
        } else if (Constants.DataSourceType.HDFS_FILE.equalsIgnoreCase(inputDataSource.getDatatype())) {
            DataSetHandle dataSetHandle = new HdfsDataSetHandle(inputDataSource.getDataSourceInfo(),
                inputDataSource.getDataSourceConfig());
            // 进行数据源校验
            dataSetHandle.checkDataSource();
            return dataSetHandle;
        } else {
            LOGGER.error("The data source type is not supported. datatype: {} ", inputDataSource.getDatatype());
            throw new CommonServiceException(AIModelError.DATA_TYPE_NOT_SUPPORTED);
        }
    }

    /**
     * Gets result handle.
     *
     * @param calculateParam the calculate param
     * @param scriptParam the script param
     * @return the result handle
     */
    public static ResultHandle getResultHandle(CalculateParam calculateParam, ScriptParam scriptParam) {
        // 【预留】 设置结果集存放的数据源。目前所有的算法都有数据集,取数据集的第一个数据源作为结果上传的数据源
        OutputDataSource outputDataSource = getOutDataSource(calculateParam.getDataSets().get(0));

        if (Constants.CustomizedAlgoId.POTENTIAL_GUEST_ALGO_ID.equals(calculateParam.getAlgoId())) {
            // 定制化的处理方式,需要走特有的处理方式。此类算法,只能提前预置后
            return new PotentialGuestResultHandle(scriptParam, outputDataSource);
        } else {
            // 任务结果走默认处理方式,此类算法可以通过算法管理界面可以添加
            return new ResultHandle(scriptParam, outputDataSource);
        }
    }

    private static OutputDataSource getOutDataSource(InputDataSource inputDataSource) {
        return new OutputDataSource(inputDataSource.getDatatype(), inputDataSource.getDataSourceConfig());
    }

}

使用

    public TaskEntity(TaskInfo taskInfo, CalculateParam calculateParam, String algoPackDir, String localFileDir) {
        this.scriptParam = getScriptParam(calculateParam, algoPackDir, localFileDir);
        this.taskInfo = taskInfo;
        this.shellParamHandle = TaskAbstractFactory.getScriptExecuteHandle(scriptParam, calculateParam.getAlgoId());
        this.dataSetHandleList = TaskAbstractFactory.getDataSetHandleList(calculateParam.getDataSets());
        this.resultHandle = TaskAbstractFactory.getResultHandle(calculateParam, scriptParam);
    }

其他说明
设计是工厂创建实例的是子类,返回的是父类。多态的体现。同事父类有默认方法,子类是对父类的扩展, 或者重写。如下:
DataSetHandle

/**
 * 数据集处理父类
 * @since 2023 -09-15 15:35
 */
public abstract class DataSetHandle {
    private static final Logger LOGGER = LoggerFactory.getLogger(DataSetHandle.class);

    /**
     * The Data source info.
     */
    protected String dataSourceInfo;

    /**
     * The Data source config.
     */
    protected String dataSourceConfig;

    /**
     * Instantiates a new Data set handle.
     *
     * @param dataSourceInfo the data source info
     * @param dataSourceConfig the data source config
     */
    public DataSetHandle(String dataSourceInfo, String dataSourceConfig) {
        this.dataSourceInfo = dataSourceInfo;
        this.dataSourceConfig = dataSourceConfig;
    }

    /**
     * Check data source.
     */
    public void checkDataSource() {
        // 对参数的json格式进行校验
        if (!MyStringUtil.checkJson(dataSourceInfo)) {
            LOGGER.error("dataSourceInfo json format error.");
            throw new CommonServiceException(AIModelError.PARAM_ERROR, "dataSourceInfo json format error.");
        }

        if (StringUtils.isNotEmpty(dataSourceConfig) && !MyStringUtil.checkJson(dataSourceConfig)) {
            LOGGER.error("dataSourceConfig json format error.");
            throw new CommonServiceException(AIModelError.PARAM_ERROR, "dataSourceConfig json format error.");
        }
    }

    /**
     * Handle data.
     *
     * @param taskId the task id
     * @param localFileDir the local file dir
     */
    public abstract void handleData(String taskId, String localFileDir);

}

S3DataSetHandle

/**
 * S3或者minio类型的数据集处理类
 * @since 2023 -09-15 15:35
 */
public class S3DataSetHandle extends DataSetHandle {
    private static final Logger LOGGER = LoggerFactory.getLogger(S3DataSetHandle.class);

    /**
     * Instantiates a new S 3 data set handle.
     *
     * @param dataSourceInfo the data source info
     * @param dataSourceConfig the data source config
     */
    public S3DataSetHandle(String dataSourceInfo, String dataSourceConfig) {
        super(dataSourceInfo, dataSourceConfig);
    }

    /**
     * Check data source.
     */
    @Override
    public void checkDataSource() {
        // 1 父类进行参数json格式的校验
        super.checkDataSource();
        // 2 具体子类,进行特性校验
        List<S3DataSourceInfo> s3DataSourceList = JSON.parseArray(dataSourceInfo, S3DataSourceInfo.class);
        for (S3DataSourceInfo s3DataSource : s3DataSourceList) {
            // 目前S3,仅支持zip文件
            if (!Constants.FileType.ZIP.equalsIgnoreCase(s3DataSource.getFileType())) {
                LOGGER.error("The file type is not supported. fileType:{}", s3DataSource.getFileType());
                throw new CommonServiceException(AIModelError.PARAM_ERROR,
                    "The file type is not supported. fileType: " + s3DataSource.getFileType());
            }
            if (StringUtils.isEmpty(s3DataSource.getFileId()) || StringUtils.isEmpty(s3DataSource.getStoreDirName())) {
                LOGGER.error("fileId and storeDirName cannot be empty.");
                throw new CommonServiceException(AIModelError.PARAM_ERROR, "fileId and storeDirName cannot be empty.");
            }
        }
    }

    /**
     * Handle data.
     *
     * @param taskId the task id
     * @param localFileDir the local file dir
     */
    @Override
    public void handleData(String taskId, String localFileDir) {
        // 1 获取配置
        S3DataSourceConfig s3DataSourceConfig = JSON.parseObject(dataSourceConfig, S3DataSourceConfig.class);
        // 2 初始化S3客户端
        S3ClientUtils s3ClientUtils = S3ClientUtils.getInstance(s3DataSourceConfig);
        for (S3DataSourceInfo s3DataSourceInfo : JSON.parseArray(dataSourceInfo, S3DataSourceInfo.class)) {
            InputStream s3InputStream = null;
            try {
                // 3 获取数据流
                s3InputStream = s3ClientUtils.download(s3DataSourceConfig.getBucketName(),
                    s3DataSourceInfo.getFileId());
                // 4 将文件保存在本地磁盘
                saveFileToLocal(s3InputStream, s3DataSourceInfo, taskId, localFileDir + taskId);
            } finally {
                MyIOUtils.closeInputStream(s3InputStream);
            }
        }
    }
}

4.2 网络还原时,不同的采集数据,解析处理方式不同

说明:

  • 创建对象由spring类管理,创建出来的对象是单例的,这个案例1有所不同,案例1,每个类初始化的参数不同。这个案例对象初始化方式一样,只是处理逻辑不同。
  • 在vimpim对象是,因为参数不同所有每次都需要new

工厂类:

/**
 * The type Ods process factory.
 *
 * @since 2024 -06-11 10:54
 */
@Slf4j
@Service
public class OdsProcessFactory {

    private static final List<VimPimModelDto> VIM_PIM_MODEL_V2_LIST = new ArrayList<>();
    private static final String VIM_PIM_MODEL_V2_FILE_PATH = "2.json";
    private static final List<String> VIM_PIM_MODEL_V2_WHITE_LIST = Arrays.asList();
    private static final List<VimPimModelDto> VIM_PIM_MODEL_V3_LIST = new ArrayList<>();
    private static final String VIM_PIM_MODEL_V3_FILE_PATH = "3.json";
    private static final List<String> VIM_PIM_MODEL_V3_WHITE_LIST = Arrays.asList();

    /**
     * The Data source.
     */
    @Resource(name = "gauss")
    DataSource dataSource;

    @Autowired
    private VimPimRepository vimPimRepository;

    @Autowired
    private VnfMaeCnDataProcessDomainService vnfMaeCnDataProcessDomainService;

    @Autowired
    private VnflocLcmDataProcessDomainService vnflocLcmDataProcessDomainService;

    static {
        // 初始化模型数据
        initModel(VIM_PIM_MODEL_V2_FILE_PATH, VIM_PIM_MODEL_V2_WHITE_LIST, VIM_PIM_MODEL_V2_LIST);
        initModel(VIM_PIM_MODEL_V3_FILE_PATH, VIM_PIM_MODEL_V3_WHITE_LIST, VIM_PIM_MODEL_V3_LIST);
    }

    private static void initModel(String vimPimModelFilePath, List<String> vimPimModelWhiteList,
        List<VimPimModelDto> vimPimModelList) {
    }

    /**
     * Gets ods process service.
     *
     * @param taskDto the task dto
     * @param dataFormat the data format
     * @return the ods process service
     */
    public DataProcessDomainService getOdsProcessService(CollectionTaskDto taskDto, int dataFormat) {
        if (OdsParseConstants.OdsDataFormat.VNF_MAECN == dataFormat
            || OdsParseConstants.OdsDataFormat.NIC_DSP == dataFormat) {
            return vnfMaeCnDataProcessDomainService;
        } else if (OdsParseConstants.OdsDataFormat.VIM_OV2 == dataFormat
            || OdsParseConstants.OdsDataFormat.PIM_OV2 == dataFormat) {
            return getVimPimDataProcessV2DomainService();
        } else if (OdsParseConstants.OdsDataFormat.VIM_OV3 == dataFormat
            || OdsParseConstants.OdsDataFormat.PIM_OV3 == dataFormat) {
            return getVimPimDataProcessV3DomainService();
        } else if (OdsParseConstants.OdsDataFormat.VNFLOC_LCM == dataFormat) {
            return vnflocLcmDataProcessDomainService;
        } else {
            // 采集来的数据格式不支持
            log.warn("Incorrect data dataFormat. taskId:{}, tasksSn:{}, dataFormat:{} ", taskDto.getTaskId(),
                taskDto.getTaskSn(), dataFormat);
        }
        return null;
    }

    public VimPimDataProcessV2DomainService getVimPimDataProcessV2DomainService() {
        return new VimPimDataProcessV2DomainService(VIM_PIM_MODEL_V2_LIST, dataSource, vimPimRepository);
    }

    public VimPimDataProcessV3DomainService getVimPimDataProcessV3DomainService() {
        return new VimPimDataProcessV3DomainService(VIM_PIM_MODEL_V3_LIST, dataSource, vimPimRepository);
    }
}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/895256.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SpringBoot框架下的汽车票在线预订系统

4系统概要设计 4.1概述 本系统采用B/S结构(Browser/Server,浏览器/服务器结构)和基于Web服务两种模式&#xff0c;是一个适用于Internet环境下的模型结构。只要用户能连上Internet,便可以在任何时间、任何地点使用。系统工作原理图如图4-1所示&#xff1a; 图4-1系统工作原理…

基于单片机的家用无线火灾报警系统的设计

1 总体设计 本设计家用无线火灾报警系统利用单片机控制技术、传感器检测技术、GSM通信技术展开设计&#xff0c;如图2.1所示为本次系统设计的主体框图&#xff0c;系统包括单片机主控模块、温度检测模块、烟雾检测模块、按键模块、GSM通信模块、液晶显示模块、蜂鸣器报警模块。…

汽车票预订系统:SpringBoot框架的优势

6系统测试 6.1概念和意义 测试的定义&#xff1a;程序测试是为了发现错误而执行程序的过程。测试(Testing)的任务与目的可以描述为&#xff1a; 目的&#xff1a;发现程序的错误&#xff1b; 任务&#xff1a;通过在计算机上执行程序&#xff0c;暴露程序中潜在的错误。 另一个…

UE5 使用Animation Budget Allocator优化角色动画性能

Animation Budget Allocator是UE内置插件&#xff0c;通过锁定动画系统所占CPU的预算&#xff0c;在到达预算计算量时对动画进行限制与优化。 开启Animation Budget Allocator需要让蒙皮Mesh使用特定的组件&#xff0c;并进行一些编辑器设置即可开启。 1.开启Animation Budget…

地球链EACO怎么和房车旅游等行业结合起来加速全球发展?

地球链EACO怎么和房车旅游等行业结合起来加速全球发展&#xff1f; 将地球链&#xff08;EACO&#xff09;与房车,旅游&#xff0c;汽车等行业结合以加速全球发展&#xff0c;可以通过以下策略&#xff1a; 智能合约与租赁平台 去中心化租赁市场&#xff1a;建立一个基于EACO的…

PCL 点云配准 基于目标对称的ICP算法(精配准)

目录 一、概述 1.1原理 1.2实现步骤 1.3应用场景 二、代码实现 2.1关键函数 2.1.1计算点云的法线 2.1.2基于对称误差估计的ICP配准 2.1.3可视化 2.2完整代码 三、实现效果 PCL点云算法汇总及实战案例汇总的目录地址链接&#xff1a; PCL点云算法与项目实战案例汇总…

【火山引擎】调用火山大模型的方法 | SDK安装 | 配置 | 客户端初始化 | 设置

豆包 (Doubao) 是字节跳动研发的大规模预训练语言模型。 目录 1 安装 2 配置访问凭证 3 客户端初始化 4 设置地域和访问域名 5 设置超时/重试次数 1 安装 通过pip安装PYTHON SDK。 pip install volcengine-python-sdk[ark] 2 配置访问凭证 获取 API Key 访问凭证具体步…

理工科考研想考计算机,湖南大学、重大、哈工大威海、山东大学,该如何选择?

C哥专业提供——计软考研院校选择分析专业课备考指南规划 计算机对理工科同学来说&#xff0c;还是性价比很高的&#xff0c;具有很大的优势&#xff01; 一、就业前景广阔 高需求行业 在当今数字化时代&#xff0c;计算机技术几乎渗透到了各个领域&#xff0c;无论是互联网…

YOLO11 目标检测 | 自动标注 | 预标注 | 标签格式转换 | 手动校正标签

本文分享使用YOLO11进行目标检测时&#xff0c;实现模型推理预标注、自动标注、标签格式转换、以及使用Labelme手动校正标签等功能。 目录 1、预训练权重 2、生成预标注 3、分析YOLO11的目标检测格式 4、分析Labelme标注工具的格式 5、生成json标注文件 6、手动校正标签 …

SQL Server-导入和导出excel数据-注意事项

环境&#xff1a; win10&#xff0c;SQL Server 2008 R2 之前写过的放在这里&#xff1a; SqlServer_陆沙的博客-CSDN博客 https://blog.csdn.net/pxy7896/category_12704205.html 最近重启ASP.NET项目&#xff0c;在使用sql server导出和导入数据时遇到一些问题&#xff0c;特…

Qt键盘按下事件和定时器事件及事件的接收和忽略

定时器事件 //设置多少毫秒调用一次 1s1000timerId this->startTimer(1000);timerId2 this->startTimer(500);void MyWidget::timerEvent(QTimerEvent* t) {static int sec 0;//通过判断当前ID来实现不同定时器的调用时间if(t->timerId() this->timerId){//隔一…

AtCoder Beginner Contest 375 A-E 题解

我的老师让我先做最后再交&#xff0c;看正确率&#xff08;即以OI赛制打abc&#xff09; 所以我用的小号&#xff08;… …&#xff09; C 卡了老半天才出来&#xff0c;我把题读错了 难度&#xff1a; A. Seats 题意 给你一个字符串 S S S&#xff0c;仅包含 . 和 #&…

kubernets(二)

集群操作 查看集群信息 kubectl get查看各组件信息 格式&#xff1a;kubectl get 资源类型 【资源名】 【选项】 events #查看集群中的所有日志信息 -o wide # 显示资源详细信息&#xff0c;包括节点、地址... -o yaml/json #将当前资源对象输出至 yaml/json 格式文…

2024.10.20 进制转换 删除根节点为x的整个子树

进制转换 十进制转换为任意进制 #include <stdio.h> int main(){char res [32] {0};int num;int index;scanf("%d %d",&num,&index);char table[] "0123456789ABCDEF";int i 0;if(num0) res[0] 0;else if(num!0){while(num>0){res[i…

Java重修笔记 UDP 网络通信

UDP 网络通信原理 1. 类 DatagramSocket 和 DatagramPacket [数据包/数据报] 实现了基于 UDP协议网络程序。 2. UDP 数据报通过数据报套接字 DatagramSocket 发送和接收&#xff0c;系统不保证UDP数据报一定能够安全送到目的地&#xff0c;也不能确定什么时候可以抵达&#…

【机器学习】决策树算法

目录 一、决策树算法的基本原理 二、决策树算法的关键概念 三、决策树算法的应用场景 四、决策树算法的优化策略 五、代码实现 代码解释&#xff1a; 在机器学习领域&#xff0c;决策树算法是一种简单直观且易于理解的分类和回归方法。它通过学习数据特征和决策规则&#…

电力系统IEC-101报文主要常用详解

文章目录 1️⃣ IEC-1011.1 前言1.2 101规约简述1.3 固定帧格式1.4 可变帧格式1.5 ASDU1.5.1 常见类型标识1.5.2 常见结构限定词1.5.3 常见传送原因1.5.4 信息体地址 1.6 常用功能报文1.6.1 初始化链路报文1.6.2 总召报文1.6.3 复位进程1.8.4 对时1.8.4.1时钟读取1.8.4.2时钟写…

R语言医学数据分析实践-R编程环境的搭建

【图书推荐】《R语言医学数据分析实践》-CSDN博客 《R语言医学数据分析实践 李丹 宋立桓 蔡伟祺 清华大学出版社9787302673484》【摘要 书评 试读】- 京东图书 (jd.com) R语言编程_夏天又到了的博客-CSDN博客 R语言对编程环境的要求不高&#xff0c;可以在多种操作系统平台上…

数据结构——顺序表的基本操作

前言 介绍 &#x1f343;数据结构专区&#xff1a;数据结构 参考 该部分知识参考于《数据结构&#xff08;C语言版 第2版&#xff09;》24~28页 补充 此处的顺序表创建是课本中采用了定义方法为SqList Q来创建&#xff0c;并没有使用顺序表指针的方法&#xff0c;具体两个…

【Linux系列】查询nginx相关的进程

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…