主流的“对象转换工具”使用示例大全以及性能的对比
目录
前言
源码地址
代码示例
引入依赖
先定两个实体用于转换
定义一个接口让所有转换器都集成
Apache BeanUtils
BeanCopier
bean-mapping
bean-mapping-asm
Dozer
自己写get/set
JMapper
json2json
MapStruct(推荐)
ModelMapper
OriKa
Spring BeanUtils
测试代码
测试结果绘制成图
总结
前言
本文章分别测试的对象转换工具为:
MapStruct、JMapper、ModelMapper、Dozer、OriKa、BeanCopier、自己写get/set、
json2json、Apache BeanUtils、Spring BeanUtils、bean-mapping、bean-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> {@Overridepublic 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> {@Overridepublic 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> {@Overridepublic 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> {@Overridepublic 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();@Overridepublic UserDTO sourceToTarget(UserVO var) {return mapper.map(var, UserDTO.class);}
}
自己写get/set
@Component("getSetAssembler")
public class GetSetAssembler implements IAssembler<UserVO, UserDTO> {@Overridepublic 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> {@Overridepublic 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> {@Overridepublic 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")@OverrideUserDTO sourceToTarget(UserVO var1);@Mapping(target = "userId", source = "userId")@Mapping(target = "createTime", dateFormat = "yyyy-MM-dd HH:mm:ss")@OverrideUserVO targetToSource(UserDTO var1);
}
@Component
public class MapStructAssembler implements IAssembler<UserVO, UserDTO> {@Resourceprivate IMapping<UserVO, UserDTO> userDTOMapping;@Overridepublic 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>() {@Overrideprotected void configure() {// 属性值不一样可以自己操作map().setUserId(source.getUserId());}});}@Overridepublic 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();}@Overridepublic UserDTO sourceToTarget(UserVO var) {return mapperFactory.getMapperFacade().map(var, UserDTO.class);}}
Spring BeanUtils
@Component
public class SpringCopyPropertiesAssembler implements IAssembler<UserVO, UserDTO> {@Overridepublic 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();@Testpublic 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();}@Beforepublic void initData() {userVO.setId(1001L);userVO.setUserId("007");userVO.setUserNickName("lasse");userVO.setCreateTime(new Date());}@Testpublic 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}@Testpublic 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}@Testpublic 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}@Testpublic 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@Testpublic 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");}@Testpublic 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}@Testpublic 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}@Testpublic 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");}@Testpublic 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");}@Testpublic 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");}@Testpublic 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");}@Testpublic 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
一样。 - 其他一些组件包主要基于
AOP
、ASM
、CGlib
,的技术手段实现的,所以也会有相应的性能损耗
相关文章:

主流的“对象转换工具”使用示例大全以及性能的对比
目录 前言 源码地址 代码示例 引入依赖 先定两个实体用于转换 定义一个接口让所有转换器都集成 Apache BeanUtils BeanCopier bean-mapping bean-mapping-asm Dozer 自己写get/set JMapper json2json MapStruct(推荐) ModelMapper OriK…...

分享10个不错的C语言开源项目
今天跟大家分享10个重量级的C语言开源项目,C语言确实经得住考验: Redis:Redis是一个开源的高性能的键值对数据库。它以C语言编写,具有极高的性能和可靠性。 Nginx:Nginx是一个高性能的HTTP和反向代理服务器࿰…...
【阅读笔记】JavaScript设计模式与开发实践2--闭包与单例、策略模式
目录闭包与高阶函数Function 扩展函数柯里化函数单例模式透明的单例模式惰性单例策略模式策略模式发展策略模式实现闭包与高阶函数 Array.prototype.sort 接受一个函数当作参数,用户可以自行在该函数内指定排序方式 // 由小到大排序 let res [1, 4, 2].sort((a, …...

设计模式(二十)----行为型模式之责任链模式
1、概述 在现实生活中,常常会出现这样的事例:一个请求有多个对象可以处理,但每个对象的处理条件或权限不同。例如,公司员工请假,可批假的领导有部门负责人、副总经理、总经理等,但每个领导能批准的天数不同…...

数据持久化层--冷热分离
业务场景 有一个系统的主要功能是这样的:它会对接客户的邮件服务器,自动收取发到几个特定客服邮箱的邮件,每收到一封客服邮件,就自动生成一个工单。之后系统就会根据一些规则将工单分派给不同的客服专员处理。 这家媒体集团客户两年多产生了近2000万的工单,工单的操作记…...

Ubuntu16.04系统 VSCode中python开发插件的安装
VSCode中python开发插件的安装 1. python python插件提供了代码分析,高亮,规范化等很多基本功能 2. Python for vscode 3. Python Preview 实时可视化你的代码结果。如果你Leedcode等题时,可以安装这个插件。能为VSCode切换各种主题皮肤…...
buuctf-pwn write-ups (12)
文章目录buu093-wustctf2020_easyfastbuu094-ciscn_2019_es_1buu095-wdb2018_guessbuu096-gyctf_2020_some_thing_excetingbuu097-axb_2019_heapbuu098-oneshot_tjctf_2016buu099-护网杯_2018_gettingstartbuu100-wustctf2020_number_gamebuu101-zctf2016_note2buu093-wustctf2…...

Linux- 系统随你玩之--网络上的黑客帝国
文章目录1、前言2、TCPDump介绍2.1、问题来了: 所有用户都可以采用该命令吗?2.2、抓包原理2.3、特点2.3.1、参数化支持2.2.2、 TCP功能3、 服务器安装Tcpdump3.1、安装3.2、检查安装是否正常。4、tcpdump 命令4.1、常用功能选项4.2、输出内容5、实操5.1、…...

Python每日一练(20230312)
目录 1. 提示用户输入的简单菜单 ★ 2. 字母异位词分组 ★★ 3. 俄罗斯套娃信封问题 ★★★ 🌟 每日一练刷题专栏 C/C 每日一练 专栏 Python 每日一练 专栏 1. 提示用户输入的简单菜单 如果用户选择菜单选项1,提示用户输入1到10之间的整数&a…...

人生又有几个四年
机缘 不知不觉,已经来 csdn 创作四周年啦~ 我是在刚工作不到一年的时候接触 csdn 的,当时在学习 node,对 node 的文件相关的几个 api 总是搞混,本来还想着在传统的纸质笔记本上记一下,但是想想我大学记了好久的笔记本…...

第九章:Java集合
第九章:Java集合 9.1:Java集合框架概述 数组、集合都是对多个数据进行存储(内存层面,不涉及持久化)操作的结构,简称Java容器。 数组存储多个数据方面的特点 一旦初始化以后,其长度就确定了。数组一旦定义好ÿ…...

嵌入式学习笔记——STM32的USART通信概述
文章目录前言常用通信协议分类及其特征介绍通信协议通信协议分类1.同步异步通信2.全双工/半双工/单工3.现场总线/板级总线4. 串行/并行通信5. 有线通信、无线通信STM32通信协议的配置方式使用通信协议控制器实现使用IO口模拟的方式实现STM32串口通信概述什么是串口通信STM32F40…...

MySQL性能优化
MySQL性能调优 存储数据类型优化 尽量避免使用 NULL尽量使用可以的最小数据类型。但也要确保没有低估需要存储的范围整型比字符串操作代价更低使用 MySQL 内建的数据类型(比如date、time、datetime),比用字符串更快 基本数据类型 数字 整数…...

C语言/动态通讯录
本文使用了malloc、realloc、calloc等和内存开辟有关的函数。 文章目录 前言 二、头文件 三、主界面 四、通讯录功能函数 1.全代码 2.增加联系人 3.删除联系人 4.查找联系人 5.修改联系人 6.展示联系人 7.清空联系人 8.退出通讯录 总结 前言 为了使用通讯录时,可以…...

我用Compose做了一个地图轮子OmniMap
一、前言 半年前,我发布过一篇介绍:Compose里面如何使用地图,比如高德地图 的文章,原本是没有想造什么轮子的✍️ 闲来无事,有一天看到了评论区留言让我把源码地址分享出来,我感觉我太懒了,后来…...

STM32之SPI
SPISPI介绍SPI是串行外设接口(Serial Peripherallnterface)的缩写,是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,节约了芯片的管脚,同时为PCB的布局上节省空间,提供方便…...

02 深度学习环境搭建
1、查看对应版本关系 详细见:https://blog.csdn.net/qq_41946216/article/details/129476095?spm1001.2014.3001.5501此案例环境使用 CUDA 11.7、Pytouch1.12.1、Miniconda3_py38(含Python3.8) 2. 安装Anaconda 或 Miniconda 本案例重点一为Miniconda准 2.1 安…...

PHP导入大量CSV数据的方法分享
/** * @description 迭代器读取csv文件 * @param $strCsvPath * @return \Generator */ public static function readPathCsvFile($strCsvPath) { if ($handle = fopen($strCsvPath, r)) { while (!feof($handle)) { yield fgetcsv($handle); } …...

代码看不懂?ChatGPT 帮你解释,详细到爆!
偷个懒,用ChatGPT 帮我写段生物信息代码如果 ChatGPT 给出的的代码不太完善,如何请他一步步改好?网上看到一段代码,不知道是什么含义?输入 ChatGPT 帮我们解释下。生信宝典 1: 下面是一段 Linux 代码,请帮…...

【MyBatis】篇三.自定义映射resultMap和动态SQL
MyBatis整理 篇一.MyBatis环境搭建与增删改查 篇二.MyBatis查询与特殊SQL 篇三.自定义映射resultMap和动态SQL 篇四.MyBatis缓存和逆向工程 文章目录1、自定义映射P1:测试数据准备P2:字段和属性的映射关系P3:多对一的映射关系P4:一对多的映射关系2、动态SQL2.1 IF标签2.2 w…...
【Web 进阶篇】优雅的接口设计:统一响应、全局异常处理与参数校验
系列回顾: 在上一篇中,我们成功地为应用集成了数据库,并使用 Spring Data JPA 实现了基本的 CRUD API。我们的应用现在能“记忆”数据了!但是,如果你仔细审视那些 API,会发现它们还很“粗糙”:有…...

如何理解 IP 数据报中的 TTL?
目录 前言理解 前言 面试灵魂一问:说说对 IP 数据报中 TTL 的理解?我们都知道,IP 数据报由首部和数据两部分组成,首部又分为两部分:固定部分和可变部分,共占 20 字节,而即将讨论的 TTL 就位于首…...

学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2
每日一言 今天的每一份坚持,都是在为未来积攒底气。 案例:OLED显示一个A 这边观察到一个点,怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 : 如果代码里信号切换太快(比如 SDA 刚变,SCL 立刻变&#…...
Java线上CPU飙高问题排查全指南
一、引言 在Java应用的线上运行环境中,CPU飙高是一个常见且棘手的性能问题。当系统出现CPU飙高时,通常会导致应用响应缓慢,甚至服务不可用,严重影响用户体验和业务运行。因此,掌握一套科学有效的CPU飙高问题排查方法&…...

GruntJS-前端自动化任务运行器从入门到实战
Grunt 完全指南:从入门到实战 一、Grunt 是什么? Grunt是一个基于 Node.js 的前端自动化任务运行器,主要用于自动化执行项目开发中重复性高的任务,例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...

C# 表达式和运算符(求值顺序)
求值顺序 表达式可以由许多嵌套的子表达式构成。子表达式的求值顺序可以使表达式的最终值发生 变化。 例如,已知表达式3*52,依照子表达式的求值顺序,有两种可能的结果,如图9-3所示。 如果乘法先执行,结果是17。如果5…...
【LeetCode】3309. 连接二进制表示可形成的最大数值(递归|回溯|位运算)
LeetCode 3309. 连接二进制表示可形成的最大数值(中等) 题目描述解题思路Java代码 题目描述 题目链接:LeetCode 3309. 连接二进制表示可形成的最大数值(中等) 给你一个长度为 3 的整数数组 nums。 现以某种顺序 连接…...

解析奥地利 XARION激光超声检测系统:无膜光学麦克风 + 无耦合剂的技术协同优势及多元应用
在工业制造领域,无损检测(NDT)的精度与效率直接影响产品质量与生产安全。奥地利 XARION开发的激光超声精密检测系统,以非接触式光学麦克风技术为核心,打破传统检测瓶颈,为半导体、航空航天、汽车制造等行业提供了高灵敏…...

Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement
Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement 1. LAB环境2. L2公告策略2.1 部署Death Star2.2 访问服务2.3 部署L2公告策略2.4 服务宣告 3. 可视化 ARP 流量3.1 部署新服务3.2 准备可视化3.3 再次请求 4. 自动IPAM4.1 IPAM Pool4.2 …...
DiscuzX3.5发帖json api
参考文章:PHP实现独立Discuz站外发帖(直连操作数据库)_discuz 发帖api-CSDN博客 简单改造了一下,适配我自己的需求 有一个站点存在多个采集站,我想通过主站拿标题,采集站拿内容 使用到的sql如下 CREATE TABLE pre_forum_post_…...