主流的“对象转换工具”使用示例大全以及性能的对比

news2024/10/1 5:25:16

目录

前言

源码地址

代码示例

引入依赖

先定两个实体用于转换

定义一个接口让所有转换器都集成

Apache BeanUtils

BeanCopier

bean-mapping

bean-mapping-asm

Dozer

自己写get/set

JMapper

json2json

MapStruct(推荐)

ModelMapper

OriKa

Spring BeanUtils

测试代码

测试结果绘制成图

总结


前言

本文章分别测试的对象转换工具为:

MapStructJMapperModelMapperDozerOriKaBeanCopier自己写get/set

json2jsonApache BeanUtilsSpring BeanUtilsbean-mappingbean-mapping-asm

源码地址

lasse-vo2dto: 测试市面上常用的实体转换工具的性能

代码示例

引入依赖

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>

        <!-- Apache BeanUtils Begin -->
        <dependency>
            <groupId>commons-beanutils</groupId>
            <artifactId>commons-beanutils</artifactId>
            <version>1.9.4</version>
        </dependency>
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency>
            <groupId>commons-collections</groupId>
            <artifactId>commons-collections</artifactId>
            <version>3.2.2</version>
        </dependency>
        <!-- Apache BeanUtils End -->

        <!-- https://mvnrepository.com/artifact/com.github.houbb/bean-mapping-core -->
        <dependency>
            <groupId>com.github.houbb</groupId>
            <artifactId>bean-mapping-core</artifactId>
            <version>0.2.6</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/com.github.houbb/bean-mapping-asm -->
        <dependency>
            <groupId>com.github.houbb</groupId>
            <artifactId>bean-mapping-asm</artifactId>
            <version>0.2.6</version>
        </dependency>

        <!-- MapStruct begin -->
        <!-- https://mvnrepository.com/artifact/org.mapstruct/mapstruct -->
        <dependency>
            <groupId>org.mapstruct</groupId>
            <artifactId>mapstruct</artifactId>
            <version>1.4.2.Final</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.mapstruct/mapstruct-processor -->
        <dependency>
            <groupId>org.mapstruct</groupId>
            <artifactId>mapstruct-processor</artifactId>
            <version>1.4.2.Final</version>
        </dependency>
        <!-- MapStruct end -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.78</version>
        </dependency>

        <dependency>
            <groupId>ma.glasnost.orika</groupId>
            <artifactId>orika-core</artifactId>
            <version>1.4.6</version>
        </dependency>

        <!--Dozer -->
        <dependency>
            <groupId>net.sf.dozer</groupId>
            <artifactId>dozer-spring</artifactId>
            <version>5.5.1</version>
        </dependency>
        <dependency>
            <groupId>net.sf.dozer</groupId>
            <artifactId>dozer</artifactId>
            <version>5.5.1</version>
        </dependency>

        <dependency>
            <groupId>org.modelmapper</groupId>
            <artifactId>modelmapper</artifactId>
            <version>1.1.0</version>
        </dependency>

        <dependency>
            <groupId>com.googlecode.jmapper-framework</groupId>
            <artifactId>jmapper-core</artifactId>
            <version>1.6.1.CR2</version>
        </dependency>

        <!-- http://modelmapper.org/getting-started/-->
        <dependency>
            <groupId>org.modelmapper</groupId>
            <artifactId>modelmapper</artifactId>
            <version>2.3.0</version>
        </dependency>

    </dependencies>

先定两个实体用于转换

public class UserVO {
    /**
     * 自增ID
     */
    private Long id;

    /**
     * 用户ID
     */
    private String userId;

    /**
     * 用户昵称
     */
    private String userNickName;

    /**
     * 注册时间
     */
    private Date createTime;
    //get/set/toString等方法省略。。。
}
/**
 * 用户DTO
 */
public class UserDTO {

    /**
     * 用户ID
     */
    private String userId;

    /**
     * 用户昵称
     */
    private String userNickName;

    /**
     * 注册时间
     */
    private Date createTime;
//get/set/toString等方法省略。。。
}

定义一个接口让所有转换器都集成

/**
 * 对象装配器接口
 */
public interface IAssembler<SOURCE, TARGET> {

    TARGET sourceToTarget(SOURCE var);

}

Apache BeanUtils

@Component
public class ApacheCopyPropertiesAssembler implements IAssembler<UserVO, UserDTO> {
    @Override
    public UserDTO sourceToTarget(UserVO var) {
        UserDTO userDTO = new UserDTO();
        try {
            BeanUtils.copyProperties(userDTO, var);
        } catch (IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
        }
        return userDTO;
    }
}

BeanCopier

@Component
public class BeanCopierAssembler implements IAssembler<UserVO, UserDTO> {
    @Override
    public UserDTO sourceToTarget(UserVO var) {
        UserDTO userDTO = new UserDTO();
        BeanCopier beanCopier = BeanCopier.create(var.getClass(), userDTO.getClass(), false);
        beanCopier.copy(var, userDTO, null);
        return userDTO;
    }
}

bean-mapping

@Component
public class BeanMappingAssembler implements IAssembler<UserVO, UserDTO> {
    @Override
    public UserDTO sourceToTarget(UserVO var) {
        UserDTO userDTO = new UserDTO();
        BeanUtil.copyProperties(var, userDTO);
        return userDTO;
    }
}

bean-mapping-asm

@Component
public class BeanMappingASMAssembler implements IAssembler<UserVO, UserDTO> {
    @Override
    public UserDTO sourceToTarget(UserVO var) {
        UserDTO userDTO = new UserDTO();
        AsmBeanUtil.copyProperties(var, userDTO);
        return userDTO;
    }
}

Dozer

@Component
public class DozerAssembler implements IAssembler<UserVO, UserDTO> {

    private static DozerBeanMapper mapper = new DozerBeanMapper();

    @Override
    public UserDTO sourceToTarget(UserVO var) {
        return mapper.map(var, UserDTO.class);
    }
}

自己写get/set

@Component("getSetAssembler")
public class GetSetAssembler implements IAssembler<UserVO, UserDTO> {
    @Override
    public UserDTO sourceToTarget(UserVO var) {
        UserDTO userDTO = new UserDTO();
        userDTO.setUserId(var.getUserId());
        userDTO.setUserNickName(var.getUserNickName());
        userDTO.setCreateTime(var.getCreateTime());
        return userDTO;
    }
}

JMapper

@Component("jMapperAssembler")
public class JMapperAssembler implements IAssembler<UserVO, UserDTO> {

    @Override
    public UserDTO sourceToTarget(UserVO var) {
        JMapper<UserDTO, UserVO> jMapper = new JMapper<>(UserDTO.class, UserVO.class, new JMapperAPI()
                .add(JMapperAPI.mappedClass(UserDTO.class)
                        .add(JMapperAPI.attribute("userId")
                                .value("userId"))
                        .add(JMapperAPI.attribute("userNickName")
                                .value("userNickName"))
                        .add(JMapperAPI.attribute("createTime")
                                .value("createTime"))
                ));

        return jMapper.getDestination(var);
    }

}

json2json

@Component
public class Json2JsonAssembler implements IAssembler<UserVO, UserDTO> {
    @Override
    public UserDTO sourceToTarget(UserVO var) {
        String strJson = JSON.toJSONString(var);
        return JSON.parseObject(strJson, UserDTO.class);
    }
}

MapStruct(推荐)

@MapperConfig
public interface IMapping<SOURCE, TARGET> {

    /**
     * 映射同名属性
     */
    @Mapping(target = "createTime", dateFormat = "yyyy-MM-dd HH:mm:ss")
    TARGET sourceToTarget(SOURCE var1);

    /**
     * 反向,映射同名属性
     */
    @InheritInverseConfiguration(name = "sourceToTarget")
    SOURCE targetToSource(TARGET var1);

    /**
     * 映射同名属性,集合形式
     */
    @InheritConfiguration(name = "sourceToTarget")
    List<TARGET> sourceToTarget(List<SOURCE> var1);

    /**
     * 反向,映射同名属性,集合形式
     */
    @InheritConfiguration(name = "targetToSource")
    List<SOURCE> targetToSource(List<TARGET> var1);

    /**
     * 映射同名属性,集合流形式
     */
    List<TARGET> sourceToTarget(Stream<SOURCE> stream);

    /**
     * 反向,映射同名属性,集合流形式
     */
    List<SOURCE> targetToSource(Stream<TARGET> stream);

}
@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE, unmappedSourcePolicy = ReportingPolicy.IGNORE)
public interface UserDTOMapping extends IMapping<UserVO, UserDTO> {
    /** 用于测试的单例 */
    IMapping<UserVO, UserDTO> INSTANCE = Mappers.getMapper(UserDTOMapping.class);

    @Mapping(target = "userId", source = "userId")
    @Mapping(target = "createTime", dateFormat = "yyyy-MM-dd HH:mm:ss")
    @Override
    UserDTO sourceToTarget(UserVO var1);

    @Mapping(target = "userId", source = "userId")
    @Mapping(target = "createTime", dateFormat = "yyyy-MM-dd HH:mm:ss")
    @Override
    UserVO targetToSource(UserDTO var1);
}
@Component
public class MapStructAssembler implements IAssembler<UserVO, UserDTO> {

    @Resource
    private IMapping<UserVO, UserDTO> userDTOMapping;

    @Override
    public UserDTO sourceToTarget(UserVO var) {
        return userDTOMapping.sourceToTarget(var);
    }

}

ModelMapper

@Component
public class ModelMapperAssembler implements IAssembler<UserVO, UserDTO> {

    private static ModelMapper modelMapper = new ModelMapper();

    static {
        modelMapper.addMappings(new PropertyMap<UserVO, UserDTO>() {
            @Override
            protected void configure() {
                // 属性值不一样可以自己操作
                map().setUserId(source.getUserId());
            }
        });
    }

    @Override
    public UserDTO sourceToTarget(UserVO var) {
        return modelMapper.map(var, UserDTO.class);
    }

}

OriKa

@Component
public class OrikaAssembler implements IAssembler<UserVO, UserDTO> {

    /**
     * 构造一个MapperFactory
     */
    private static MapperFactory mapperFactory = new DefaultMapperFactory.Builder().build();

    static {
        mapperFactory.classMap(UserDTO.class, UserVO.class)
                .field("userId", "userId")  // 字段不一致时可以指定
                .byDefault()
                .register();
    }

    @Override
    public UserDTO sourceToTarget(UserVO var) {
        return mapperFactory.getMapperFacade().map(var, UserDTO.class);
    }

}

Spring BeanUtils

@Component
public class SpringCopyPropertiesAssembler implements IAssembler<UserVO, UserDTO> {
    @Override
    public UserDTO sourceToTarget(UserVO var) {
        UserDTO userDTO = new UserDTO();
        BeanUtils.copyProperties(var, userDTO);
        return userDTO;
    }
}

测试代码

@RunWith(SpringRunner.class)
@SpringBootTest
public class ApiTest {

    private Logger logger = LoggerFactory.getLogger(ApiTest.class);

    @Resource(name = "apacheCopyPropertiesAssembler")
    private IAssembler<UserVO, UserDTO> apacheCopyPropertiesAssembler;
    @Resource(name = "beanCopierAssembler")
    private IAssembler<UserVO, UserDTO> beanCopierAssembler;
    @Resource(name = "beanMappingAssembler")
    private IAssembler<UserVO, UserDTO> beanMappingAssembler;
    @Resource(name = "beanMappingASMAssembler")
    private IAssembler<UserVO, UserDTO> beanMappingASMAssembler;
    @Resource(name = "getSetAssembler")
    private IAssembler<UserVO, UserDTO> getSetAssembler;
    @Resource(name = "mapStructAssembler")
    private IAssembler<UserVO, UserDTO> mapStructAssembler;
    @Resource(name = "springCopyPropertiesAssembler")
    private IAssembler<UserVO, UserDTO> springCopyPropertiesAssembler;
    @Resource(name = "orikaAssembler")
    private IAssembler<UserVO, UserDTO> orikaAssembler;
    @Resource(name = "dozerAssembler")
    private IAssembler<UserVO, UserDTO> dozerAssembler;
    @Resource(name = "modelMapperAssembler")
    private IAssembler<UserVO, UserDTO> modelMapperAssembler;
    @Resource(name = "jMapperAssembler")
    private IAssembler<UserVO, UserDTO> jMapperAssembler;
    @Resource(name = "json2JsonAssembler")
    private IAssembler<UserVO, UserDTO> json2JsonAssembler;

    private Long cycleIndex=100000L;
    private UserVO userVO = new UserVO();

    @Test
    public void all(){
        System.out.println("各跑"+cycleIndex+"次");
        test_apacheCopyPropertiesAssembler();
        test_beanCopierAssembler();
        test_beanMappingAssembler();
        test_beanMappingASMAssembler();
        test_getSetAssembler();
        test_mapStructAssembler();
        test_springCopyPropertiesAssembler();
        test_orikaAssembler();
        test_dozerAssembler();
        test_modelMapperAssembler();
        test_jMapperAssembler();
        test_json2JsonAssembler();
    }

    @Before
    public void initData() {
        userVO.setId(1001L);
        userVO.setUserId("007");
        userVO.setUserNickName("lasse");
        userVO.setCreateTime(new Date());
    }

    @Test
    public void test_apacheCopyPropertiesAssembler() {
        long start = System.currentTimeMillis();
        for (int i = 0; i < cycleIndex; i++) {
            UserDTO userDTO = apacheCopyPropertiesAssembler.sourceToTarget(userVO);
        }
        System.out.println("apacheCopyPropertiesAssembler方法耗时:" + (System.currentTimeMillis() - start) + "ms");
        // 方法耗时:2050ms
    }

    @Test
    public void test_beanCopierAssembler() {
        long start = System.currentTimeMillis();
        for (int i = 0; i < cycleIndex; i++) {
            UserDTO userDTO = beanCopierAssembler.sourceToTarget(userVO);
        }
        System.out.println("beanCopierAssembler方法耗时:" + (System.currentTimeMillis() - start) + "ms");
        // 方法耗时:53ms
    }

    @Test
    public void test_beanMappingAssembler() {
        long start = System.currentTimeMillis();
        for (int i = 0; i < cycleIndex; i++) {
            UserDTO userDTO = beanMappingAssembler.sourceToTarget(userVO);
        }
        System.out.println("beanMappingAssembler方法耗时:" + (System.currentTimeMillis() - start) + "ms");
        // 方法耗时:162ms
    }

    @Test
    public void test_beanMappingASMAssembler() {
        long start = System.currentTimeMillis();
        for (int i = 0; i < cycleIndex; i++) {
            UserDTO userDTO = beanMappingASMAssembler.sourceToTarget(userVO);
        }
        System.out.println("beanMappingASMAssembler方法耗时:" + (System.currentTimeMillis() - start) + "ms");
        // 方法耗时:90ms
    }

    // 方法耗时:3ms
    @Test
    public void test_getSetAssembler() {
        long start = System.currentTimeMillis();
        for (int i = 0; i < cycleIndex; i++) {
            UserDTO userDTO = getSetAssembler.sourceToTarget(userVO);
        }
        System.out.println("getSetAssembler方法耗时:" + (System.currentTimeMillis() - start) + "ms");
    }

    @Test
    public void test_mapStructAssembler() {
        long start = System.currentTimeMillis();
        for (int i = 0; i < cycleIndex; i++) {
            UserDTO userDTO = mapStructAssembler.sourceToTarget(userVO);
        }
        System.out.println("mapStructAssembler方法耗时:" + (System.currentTimeMillis() - start) + "ms");
        // 方法耗时:4ms
    }

    @Test
    public void test_springCopyPropertiesAssembler() {
        long start = System.currentTimeMillis();
        for (int i = 0; i < cycleIndex; i++) {
            UserDTO userDTO = springCopyPropertiesAssembler.sourceToTarget(userVO);
        }
        System.out.println("springCopyPropertiesAssembler方法耗时:" + (System.currentTimeMillis() - start) + "ms");
        // 方法耗时:64ms
    }

    @Test
    public void test_orikaAssembler() {
        long start = System.currentTimeMillis();
        for (int i = 0; i < cycleIndex; i++) {
            UserDTO userDTO = orikaAssembler.sourceToTarget(userVO);
        }
        System.out.println("orikaAssembler方法耗时:" + (System.currentTimeMillis() - start) + "ms");
    }

    @Test
    public void test_dozerAssembler() {
        long start = System.currentTimeMillis();
        for (int i = 0; i < cycleIndex; i++) {
            UserDTO userDTO = dozerAssembler.sourceToTarget(userVO);
        }
        System.out.println("dozerAssembler方法耗时:" + (System.currentTimeMillis() - start) + "ms");
    }

    @Test
    public void test_modelMapperAssembler() {
        long start = System.currentTimeMillis();
        for (int i = 0; i < cycleIndex; i++) {
            UserDTO userDTO = modelMapperAssembler.sourceToTarget(userVO);
        }
        System.out.println("modelMapperAssembler方法耗时:" + (System.currentTimeMillis() - start) + "ms");
    }

    @Test
    public void test_jMapperAssembler() {
        long start = System.currentTimeMillis();
        for (int i = 0; i <cycleIndex; i++) {
            UserDTO userDTO = jMapperAssembler.sourceToTarget(userVO);
        }
        System.out.println("jMapperAssembler方法耗时:" + (System.currentTimeMillis() - start) + "ms");
    }

    @Test
    public void test_json2JsonAssembler() {
        long start = System.currentTimeMillis();
        for (int i = 0; i < cycleIndex; i++) {
            UserDTO userDTO = json2JsonAssembler.sourceToTarget(userVO);
        }
        System.out.println("json2JsonAssembler方法耗时:" + (System.currentTimeMillis() - start) + "ms");
    }

}

测试结果绘制成图

用于对象属性转换有12种,接下来我们分别测试这12种属性转换操作分别在一百次、一千次、一万次、十万次、一百万次时候的性能时间对比。

总结

  • BeanUtils.copyProperties 是大家代码里最常出现的工具类,但只要你不把它用错成 Apache 包下的,而是使用 Spring 提供的,就基本还不会对性能造成多大影响。
  • 但如果说性能更好,可替代手动get、set的,还是 MapStruct 更好用,因为它本身就是在编译期生成get、set代码,和我们写get、set一样。
  • 其他一些组件包主要基于 AOPASMCGlib,的技术手段实现的,所以也会有相应的性能损耗

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

使用Vue实现数据可视化大屏功能(二)

引入数据大屏相关组件 用Datav插件做大屏可视化的组件&#xff0c;官网地址 http://datav.jiaminghi.com/ &#xff0c;整个组件库都是基于Vue React版本实现&#xff0c;主要用于构建大屏数据可视化页面&#xff0c;具有很多种类的组件可以使用。其安装方式如下。 npm instal…

WebRTC中的NAT穿透

NAT简介 我们知道&#xff0c;WebRTC会按照内网、P2P、中转的顺序来尝试连接。在大部分的情况下&#xff0c;实际是使用P2P或者中转的。这里P2P的场景主要使用的技术就是NAT穿透。 我们先简单了解下NAT。NAT在真实网络中是常见的&#xff0c;它的出现一是为了解决ipv4地址不够…

2.1操作系统-进程管理:进程的同步与互斥、信号量与PV操作、PV操作与互斥模型、PV操作与同步模型

2.1操作系统-进程管理&#xff1a;进程的同步与互斥、信号量与PV操作、PV操作与互斥模型、PV操作与同步模型进程的同步与互斥PV操作PV操作与互斥模型PV操作与同步模型进程的同步与互斥 进程是动态的&#xff0c;有一些动态变迁的过程&#xff0c;进程在计算机中是可以同时存在…

JavaEE简单示例——Spring框架的简单介绍

简单介绍&#xff1a; 在我们之前创建的Java项目中&#xff0c;会发现我们的各种类&#xff0c;接口文件和配置文件都放在了一起&#xff0c;虽然我们也做了一些包管理去管理我们的这些文件&#xff0c;但是对于我们来说&#xff0c;这些操作还是太繁琐了&#xff0c;尤其是当…

Spark-RDD创建、并行分区

集合&#xff08;内存&#xff09;中创建 RDD 外部存储&#xff08;文件&#xff09;创建 RDD 并行与分区 分区的设定 集合&#xff08;内存&#xff09;中创建 RDD 从集合中创建 RDD&#xff0c;Spark 主要提供了两个方法&#xff1a;parallelize 和 makeRDD&#xff0c;从…

【源码解析】SpringBoot缓存之@Cacheable的快速入门和源码解析

快速入门 启动类上添加注解EnableCaching在方法上添加注解Cacheable。 OverrideCacheable(cacheNames "value", key "#code_#dictKey")public String getValue(String code, Integer dictKey) {return baseMapper.getValue(code, dictKey);}OverrideCac…

数据结构和算法学习记录——线性表之单链表(上)-初始单链表及其头插函数(顺序表缺陷、单链表优点、链表打印)

单链表的概念单链表是一种链式存取的数据结构&#xff0c;链表中的数据是以结点来表示的。每个结点的构成&#xff1a;元素(数据元素的映象) 指针(指示后继元素存储位置)。元素就是存储数据的存储单元&#xff0c;指针就是连接每个结点的地址数据。以“结点的序列”表示的线性…

Kubernetes Service简介

Service 之前我们了解了Pod的基本用法&#xff0c;我们也了解到Pod的生命是有限的&#xff0c;死亡过后不会复活了。我们后面学习到的RC和Deployment可以用来动态的创建和销毁Pod。尽管每个Pod都有自己的IP地址&#xff0c;但是如果Pod重新启动了的话那么他的IP很有可能也就变…

cocos2dx+lua学习笔记:事件派发器CCEventDispatcher

前言 本篇在讲什么 cocos2dx内关于事件监听和派发的调度器EventDispatcher相关内容 本篇适合什么 适合初学Cocos2dx的小白 适合想要学习EventDispatcher的新手 本篇需要什么 对Lua语法有简单认知 对C语法有简单认知 对Cocos2dx有简单认知 Cocos2dx-Lua的开发环境 依…

【Spring事物三千问】DataSource的设计和常用实现——Hikari、Druid

javax.sql.DataSource javax.sql.DataSource 是 jdk 提供的接口&#xff0c;各个连接池厂商 和 Spring 都对 DataSource 进行了设计和实现。 javax.sql.DataSource 是连接到物理数据源的工厂接口。它是 java.sql.DriverManager 功能的替代者&#xff0c;是获取数据库连接的首选…

H5视频付费点播打赏影视系统程序全开源运营版,含完整的前后台+数据库

源码介绍&#xff1a; 这是一个非常棒的精品代码&#xff0c;之前官方网站售价可是超过2w的。我拿过来了简单测试了一下&#xff0c;完美。好久没有遇到这么好的代码了&#xff0c;特此整理了一份完整的搭建教程并分享一下。 thinkphp开发&#xff0c;前后端分离设计&#xf…

Vue3做出B站【bilibili】 Vue3+TypeScript+ant-design-vue【快速入门一篇文章精通系列(一)前端项目案例】

本项目分为二部分 1、后台管理系统&#xff08;用户管理&#xff0c;角色管理&#xff0c;视频管理等&#xff09; 2、客户端&#xff08;登录注册、发布视频&#xff09; Vue3做出B站【bilibili】 Vue3TypeScriptant-design-vue【快速入门一篇文章精通系列&#xff08;一&…

ASEMI高压MOS管20N60参数,20N60尺寸,20N60体积

编辑-Z ASEMI高压MOS管20N60参数&#xff1a; 型号&#xff1a;20N60 漏极-源极电压&#xff08;VDS&#xff09;&#xff1a;600V 栅源电压&#xff08;VGS&#xff09;&#xff1a;30V 漏极电流&#xff08;ID&#xff09;&#xff1a;20A 功耗&#xff08;PD&#xff…

项目最后一刻发生范围变更该怎么处理?

不管是项目需求发生了变化&#xff0c;还是第一轮可交付成果没有完全达到预期&#xff0c;在项目范围定义的初始阶段之后可能发生变化的原因有很多。当这种情况发生时&#xff0c;你需要准备好一个计划来处理最后一刻的范围变更和调整。 什么是范围变更&#xff1f; 范围变更是…

浪潮 KaiwuDB x 山东重工 | 打造离散制造业 IIoT 标杆解决方案

近日&#xff0c;浪潮 KaiwuDB 携手山东重工集团有限公司&#xff08;以下简称&#xff1a;山东重工&#xff09;重磅发布“离散制造业 IIoT 解决方案”。该 IIoT 方案以 KaiwuDB 就地运算专利技术为底座&#xff0c;搭建了”多快优智”的“13N”方案体系&#xff0c;目前已率先…

南京、西安集成电路企业和高校分布一览(附产业链主要厂商及高校名录)

前言 3月2日&#xff0c;国务院副总理刘鹤在北京调研集成电路企业发展&#xff0c;并主持召开座谈会。刘鹤指出&#xff0c;集成电路是现代化产业体系的核心枢纽&#xff0c;关系国家安全和中国式现代化进程。他表示&#xff0c;我国已形成较完整的集成电路产业链&#xff0c;也…

视频理解论文串讲——学习笔记

文章目录DeepVideoTwo-StreamBeyond-short-SmippetsConvolutional FusionTSNC3DI3DNon-localR&#xff08;21&#xff09;DSlowFastTimesformer本文是对视频理解领域论文串讲的笔记记录。 一篇相关综述&#xff1a;Yi Zhu, Xinyu Li, Chunhui Liu, Mohammadreza Zolfaghari, Yu…

【YOLO】YOLOv8训练自定义数据集

1. 运行环境 windows11 和 Ubuntu20.04&#xff08;建议使用 Linux 系统&#xff09; 首先切换到自己建立的虚拟环境安装 pytorch torch 1.12.0cu116&#xff08;根据自身设备而定&#xff09; torchvision 0.13.0cu116&#xff08;根据自身设备而定&…

详解JAVA枚举类

目录 1.概述 2.常用API 2.1.清单 2.2.代码示例 2.2.1.ordinal 2.2.2.compareTo 2.2.3.toString 2.2.4.valueOf 2.2.5.values 3.成员变量和带参构造 1.概述 枚举变量指的是变量的取值只在一个有限的集合内&#xff0c;如性别、星期几、颜色等。从JDK5开始&#xff0…

超详细CentOS7 NAT模式(有图形化界面)网络配置

在此附上CentOS7&#xff08;有可视化界面版&#xff09;安装教程 超详细VMware CentOS7&#xff08;有可视化界面版&#xff09;安装教程 打开VMware—>点击编辑---->选择虚拟网络编辑器 打开虚拟网络编辑器后如下图所示&#xff1a; 从下图中我们看到最下面子网IP为…