使用 OpenRewrite 简化 Java 和 SpringBoot 迁移
大家好,这里是架构资源栈!点击上方关注,添加“星标”,一起学习大厂前沿架构!
移民的挑战
随着 Spring Boot 2.x 等旧版本即将到期且不再获得支持,迁移到较新版本对于安全性、兼容性和性能改进至关重要。但是,迁移过程面临着一些挑战:
1. 重大变更:主要版本升级通常会引入重大变更。例如,Spring Boot 3.x 需要Java 17并从 迁移javax.*
到jakarta.* packages
。
**2. 弃用的 API:**许多常用的 API 和模式已被弃用并需要替换。
**3. 手动更新:**传统迁移需要手动更新依赖项、重构代码和修复兼容性问题。
**4. 耗时:**大型代码库可能需要数周或数月才能迁移,从而增加项目成本和风险。
**5. 测试负担:**必须彻底测试每个更改以确保功能保持完好。
那么,我们如何才能简化和加速迁移过程呢?这就是 OpenRewrite 发挥作用的地方。
开放重写
OpenRewrite是一款开源的自动化代码重构工具,可帮助开发人员减少技术负担。它为框架迁移、安全修复和代码样式提供了预构建的重构方案,将工作量从几小时缩短到几分钟。
Gradle 和 Maven 插件可轻松将这些更改应用于存储库。OpenRewrite 社区最初专注于 Java,目前正在积极扩展对更多语言和框架的支持。
主要特点
- **自动重构:**自动更新代码语法、依赖关系和模式
- **基于配方:**使用声明性配方来定义转换规则
- **风格保存:**保留原始代码格式和注释
- **大规模变更:**可以一致地处理整个代码库
- **可扩展:**支持针对特定迁移需求的自定义配方
它是如何工作的?
-
OpenRewrite 修改代表源代码的无损语义树 (LST),并将它们转换回源代码。
-
您可以查看更改并根据需要提交。
-
修改是使用访问者进行的,访问者被分组到菜谱中。
-
配方可确保变化最小,并保持原始格式。
实践
在本文中,我将演示如何使用 OpenRewrite 将使用 Java 8、Spring Boot 2.x 和 JUnit 4 构建的简单 CRUD Spring Boot 应用程序迁移到 Java 21、Spring Boot 3.3 和 JUnit 5。
代码库
1)pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.14</version><relativePath/></parent><groupId>com.example</groupId><artifactId>demo</artifactId><version>0.0.1-SNAPSHOT</version><name>demo</name><description>Demo project for Spring Boot Migration</description><properties><java.version>1.8</java.version></properties><dependencies>// dependencies: starter web, data-jpa, etc</dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>
</project>
Enter fullscreen mode Exit fullscreen mode
2)UserController.java
@RestController
@RequestMapping("/api/users")
public class UserController {@Autowiredprivate UserRepository userRepository;@Autowiredprivate UserService userService;@RequestMapping(method = RequestMethod.GET)public List<User> getAllUsers() {return userRepository.findAll();}@RequestMapping(method = RequestMethod.POST)public ResponseEntity<?> createUser(@Valid @RequestBody User user) {User savedUser = userRepository.save(user);return ResponseEntity.ok().build();}@RequestMapping(value = "/{id}", method = RequestMethod.GET)public ResponseEntity<User> getUserById(@PathVariable("id") Long id) {User user = userRepository.findById(id).orElse(null);return user != null ? ResponseEntity.ok(user) : ResponseEntity.notFound().build();}@RequestMapping(value = "/username")public ResponseEntity<User> getUserByUsername(@RequestParam String username) {User user = userService.findByUsername(username);return user != null ? ResponseEntity.ok(user) : ResponseEntity.notFound().build();}}
Enter fullscreen mode Exit fullscreen mode
3)UserService.java
@Service
public class UserService {@Autowiredprivate UserRepository userRepository;public User findByUsername(String username) {return userRepository.findByUsernameNative(username);}
}
Enter fullscreen mode Exit fullscreen mode
4)UserRepository.java
@Repository
public interface UserRepository extends JpaRepository<User, Long> {@Query(value = "SELECT * FROM users WHERE username = ?1", nativeQuery = true)User findByUsernameNative(String username);}
Enter fullscreen mode Exit fullscreen mode
5)用户.java
import javax.persistence.*;
import javax.validation.constraints.NotNull;@Entity
@Table(name = "users")
public class User {@Id@GeneratedValue(strategy = GenerationType.AUTO)private Long id;@NotNull@Column(nullable = false)private String username;@Columnprivate String email;// setter, getter
}
Enter fullscreen mode Exit fullscreen mode
6)UserControllerTest.java
@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class UserControllerTest {@Autowiredprivate MockMvc mockMvc;@Autowiredprivate UserRepository userRepository;@Beforepublic void setup() {userRepository.deleteAll();}@Testpublic void testCreateUser() throws Exception {String userJson = "{"username":"testuser","email":"test@example.com"}";mockMvc.perform(MockMvcRequestBuilders.post("/api/users").contentType(MediaType.APPLICATION_JSON).content(userJson)).andExpect(MockMvcResultMatchers.status().isOk());}@Testpublic void testGetUser() throws Exception {User user = new User();user.setUsername("testuser");user.setEmail("test@example.com");userRepository.save(user);mockMvc.perform(MockMvcRequestBuilders.get("/api/users/" + user.getId())).andExpect(MockMvcResultMatchers.status().isOk()).andExpect(MockMvcResultMatchers.jsonPath("$.username").value("testuser"));}
}
Enter fullscreen mode Exit fullscreen mode
手动迁移
在使用 OpenRewrite 之前,让我们看看如果手动迁移到 Java 21 和 Spring Boot 3.3 会发生什么。
首先,更新pom.xml
<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.3.10</version><relativePath/>
</parent><properties><java.version>21</java.version>
</properties>
Enter fullscreen mode Exit fullscreen mode
接下来,使用 Maven 清理并构建项目:
mvn clean install
有几个编译错误
好的,让我们恢复更改并使用 OpenRewrite 进行迁移。
使用 OpenRewrite 进行迁移
添加 OpenRewrite 插件
在 中pom.xml
,添加 OpenRewrite Maven 插件。如果您使用的是 Gradle,则可以添加 Gradle 插件。
<build><plugins><plugin><groupId>org.openrewrite.maven</groupId><artifactId>rewrite-maven-plugin</artifactId><version>6.3.2</version></plugin></plugins>
</build>
Enter fullscreen mode Exit fullscreen mode
选择迁移方案
要发现所有可用的配方,您可以检查配方目录,其中列出了所有可用的配方,包括:Java、Spring Boot、Hibernate、Quarkus、Scala、.NET、Jenkins 等。
在这个展示中,我将使用三个配方:Java 8 到 21、Spring 2 到 3 和 JUnit 4 到 5。
让我们将食谱添加到 pom.xml 中;每个食谱都有自己的依赖项。
<plugin><groupId>org.openrewrite.maven</groupId><artifactId>rewrite-maven-plugin</artifactId><version>6.3.2</version><configuration><exportDatatables>true</exportDatatables><activeRecipes><recipe>org.openrewrite.java.migrate.UpgradeToJava21</recipe><recipe>org.openrewrite.java.spring.boot2.SpringBoot2JUnit4to5Migration</recipe><recipe>org.openrewrite.java.spring.boot3.UpgradeSpringBoot_3_3</recipe></activeRecipes></configuration><dependencies><dependency><groupId>org.openrewrite.recipe</groupId><artifactId>rewrite-migrate-java</artifactId><version>3.4.0</version></dependency><dependency><groupId>org.openrewrite.recipe</groupId><artifactId>rewrite-spring</artifactId><version>6.3.0</version></dependency></dependencies>
</plugin>
Enter fullscreen mode Exit fullscreen mode
现在,运行 Maven 来安装 OpenRewrite 插件及其配方:
mvn clean install
预览迁移
OpenRewrite 提供了一种dryRun
模式,允许开发人员在实际应用更改之前通过以下方式预览更改:
mvn rewrite:dryRun
您可以看到将用于实际迁移的更改。
应用迁移
现在,让我们进行迁移
mvn rewrite:run
使用您的 IDE 或差异检查工具来检查更改。
1.更新pom.xml:自动更新SpringBoot版本到3.3.10,Java版本到21,删除JUnit4。
2. 更新控制器:
从 迁移javax.*
到jakarta.* packages
,改为使用@GetMapping
,@PostMapping
用于专用注释。
3. 更新单元测试:
替换@Before
为@BeforeEach
,更新包名称
限制
在这个展示中,OpenRewrite 成功迁移到 Java 21 和 Spring Boot 3.3,但它仍然存在一些限制。
由于 OpenRewrite 依赖于预定义的配方,因此它支持许多常见框架,但并非全部。
例如,如果您需要将第三方库(如 Ehcache2)迁移到 Ehcache3(Spring 3.0 中不再支持),OpenRewrite 不提供内置配方。在这种情况下,您必须编写自定义配方或手动执行迁移。
如果您创建了自定义配方,请考虑将其贡献给 OpenRewrite 社区,以帮助其他进行类似迁移的人。
概括
OpenRewrite 通过以下方式显著简化了 Java 和 Spring Boot 迁移过程:
- 自动重复代码更改
- 减少迁移时间和精力
- 最大限度地减少人为错误
- 标准化迁移方法
虽然 OpenRewrite并不能消除测试和验证的需要,但它减少了迁移所需的手动工作量。这使开发人员可以专注于更复杂的迁移方面和业务逻辑更新。
参考
- https://docs.openrewrite.org/
- https://github.com/openrewrite
原文地址:https://mp.weixin.qq.com/s/c7HMXbTJdxYWj53tKdY3hA
相关文章:
使用 OpenRewrite 简化 Java 和 SpringBoot 迁移
大家好,这里是架构资源栈!点击上方关注,添加“星标”,一起学习大厂前沿架构! 移民的挑战 随着 Spring Boot 2.x 等旧版本即将到期且不再获得支持,迁移到较新版本对于安全性、兼容性和性能改进至关重要。但…...
电脑怎么设置锁屏密码 分享详细设置教程
电脑不仅仅是工作的工具,更是存储着大量个人信息和重要数据的私人空间。设置电脑锁屏密码是保护这些信息,免受未经授权访问的基本安全措施之一。那么,电脑怎么锁屏密码呢?下面便为大家介绍在一些不同操作系统中怎么设置电脑锁屏密…...
【Netty篇】Handler Pipeline 详解
目录 一、 Handler & Pipeline——流水线上的“特种部队”与“生产线”1、 ChannelHandler —— 流水线上的“特种兵”👮♂️2、 ChannelPipeline —— 生产线上的“接力赛跑”🏃♀️🏃♂️ 二、 代码实例1、 服务端代码示例2、 客…...
Postman实现接口测试(附项目实战)
Postman实现接口测试(附项目实战) Postman实现接口测试 掌握如何安装Postman 掌握Postman的基本用法 掌握全局变量与环境变量 掌握Postman断言和关联 掌握如何读取外部文件实现参数化 掌握如何使用Newman生成HTML测试报告 1.Postman介绍和安装 Postman是…...
从零上手GUI Guider学习LVGL——Button
视频教程请关注我b站:同学_好好学习,这里只是做相应的笔记文稿 从零上手GUI Guider学习LVGL——Buttton 前言: 首先我们为什么要学习LVGL设计工具呢? 1 降低开发难度 2 提高开发效率 所以我们需要学习一款合适的设计工具 在b站很少…...
软件工程知识体系全面梳理
一、软件工程概述 1. 软件工程基本概念 定义:应用系统化、规范化、可量化的方法开发、运行和维护软件的学科 目标:提高软件质量、降低开发成本、控制开发周期 三要素:方法、工具、过程 2. 软件生命周期 可行性分析 → 需求分析 → 设计 …...
操作教程|通过DataEase制作MaxKB系统数据大屏
MaxKB(Max Knowledge Brain)是一款强大易用的企业级AI助手,支持RAG检索增强生成、工作流编排、MCP工具调用能力,目前正在被广泛应用于智能客服、企业内部知识库、学术研究与教育等场景。MaxKB可以帮助用户快速搭建面向不同应用场景…...
关于webpack的知识点
一、什么是webpack?它的核心概念是什么? webpack是现代JavaScript应用程序的打包工具 它的核心概念包括: 入口输出loaderplugin(插件)模式模块依赖图 二、webPack与Grunt\Grulp有什么区别? 首先Grunt/Gulp是任务运行器,用来实现流…...
Linux系统中的 sudo 权限会导致环境变量失效。
标题为什么 sudo 会破坏 配置的环境变量? 权限切换:sudo 以 root 用户 身份执行命令,root 用户的环境变量和当前用户(user)的环境变量是隔离的。 环境变量丢失:nvm 依赖的 PATH、等环境变量是通过用户 She…...
目标分割模型优化自身参数都是梯度下降算法吗?
在计算机视觉的深度学习任务中,诸如 CNN、FCN、U-Net、DeepLab 系列模型已成为图像分类与图像分割任务的核心架构。它们在网络结构和任务上有所差异,但是否共享同一种优化机制?是否都使用梯度下降?优化过程中又有什么本质区别&…...
前端请求传参与后端匹配的接收方式Content-Type类型
文章目录 一、Content-Type简介二、Content-Type类型三、常⽤类型3.1. application/json:JSON数据格式3.2. application/x-www-form-urlencoded:普通表单格式(键值对)3.3. multipart/form-data:多部分表单格式…...
解决:VSCode C++ conan 安装第三方库后 头文件报错
文章目录 1 头文件include路径查找报错参考 1 头文件include路径查找报错 找到conan_toolchain.cmake中 INCLUDE_PATH list(PREPEND CMAKE_INCLUDE_PATH "/Users/hanliqiang/.conan2/p/b/fmte8c4f7a755477/p/include")生成C编译配置 CtrlShiftP 中选择C Edit Confi…...
(leetcode算法题)309. 买卖股票的最佳时机含冷冻期
按照题目要求,研究对象是最后一天结束后获得的最大利润 那么就可以把问题拆分成 第 1 天结束后获得的最大利润, 第 2 天结束后获得的最大利润, 第 i 天结束后获得的最大利润, 由于规则中强调不能同时参与多笔交易,…...
win10和win11系统修复工具各类故障解决
点赞关注一下哈: 在使用电脑时可能会遇到一些问题,通过上网查找解决方法费时费力,而有了这个小工具可以很方便的解决问题。有几十种解决方案,值得下载保存哦。 1、使用方法: 解压文件,双击文件夹内的exe文件…...
微硕WSP6949 MOS管在补水仪中的应用与市场分析
微硕WSP6949 MOS管在补水仪中的应用与市场分析 一、引言 补水仪作为一种常见的家用电器,其核心部件之一是驱动电路,而MOS管作为驱动电路中的关键元件,其性能直接影响到补水仪的运行效率和稳定性。微硕半导体推出的WSP6949 MOS管,…...
【通过Zadig给鼠标适配器安装驱动后,鼠标动不了,无法恢复的解决办法】
【通过Zadig给鼠标适配器安装驱动后,鼠标动不了,无法恢复的解决办法 问题产生缘由感谢这位大佬提供的解决办法解决办法 问题产生缘由 通过Zadig给鼠标适配器安装USB GAMING MOUSE这个驱动后,鼠标动不了,无法恢复(重启电脑,卸载鼠标驱动再重装也不可以), 不过还好,我用的是笔记…...
基本表单的实现即登录注册页面的实现
1.登录页面(opType.value0) 2.注册页面(opType.value1) 3.注意 el-form-item中的prop对应的是rules里面的key值 <el-form-itemlabel"邮箱"prop"email"label-width"100px"> </el-form-i…...
JVM 什么是逃逸分析?它有哪些优化手段?
JVM 逃逸分析 (Escape Analysis) 是一种编译器优化技术,主要由即时编译器 (JIT Compiler) 在运行时进行,用于分析对象的作用域,判断对象是否会逃逸出方法或线程。 什么是逃逸? 在 JVM 的上下文中,“逃逸” 指的是对象…...
Spring AI与通义千问的完美结合:构建智能对话应用
Spring AI是Spring生态系统中的新成员,它为开发人员提供了一套简单而强大的工具,用于集成各种AI大模型。本文将介绍如何使用Spring AI与阿里云通义千问大模型进行集成,构建智能对话应用,帮助你快速掌握AI应用开发的核心技能。 引言 随着人工智能技术的快速发展,越来越多的…...
CST仿真天线流程
基础操作指导 如何建模、设置边界条件、端口激励等。 材料属性设置、网格划分优化。 仿真参数配置(频域/时域仿真)。 常见仿真案例 天线设计(如微带天线、波导天线)。 微波器件(滤波器、功分器、耦合器࿰…...
Vue 组件化开发
引言 在当今的 Web 开发领域,构建一个功能丰富且用户体验良好的博客是许多开发者的目标。Vue.js 作为一款轻量级且高效的 JavaScript 框架,其组件化开发的特性为我们提供了一种优雅的解决方案。通过将博客拆分成多个独立的组件,我们可以提高…...
java + spring boot + mybatis 通过时间段进行查询
前端传来的只有日期内容,如:2025-04-17 需要在日期内容的基础上补充时间部分,代码示例: /*** 日志查询(分页查询)* param recordLogQueryDTO 查询参数对象* return 日志列表*/Overridepublic PageBean<…...
基于pycatia的CATIA自动化干涉检测系统开发全解析
引言 在智能制造时代,三维数模的干涉检测效率直接影响产品开发周期。本文基于Python的pycatia库,深入解析CATIA自动化干涉检测系统的开发要点与工业实践,结合达索系统最新技术趋势,为工程师提供一套高可靠性的二次开发方案。 一、…...
v-model进阶+ref+nextTick
一、v-model进阶 复习 v-model v-model: 双向数据绑定指令 数据 <-> 视图: 数据和视图相互影响, 因此被称为双向数据绑定指令 1> 数据变了, 视图也会跟着变 (数据驱动视图) 2> 视图变了, 数据也会跟着变 1. v-model 原理 v-model只是一个语法糖, 比较好用, …...
vscode+keil嵌入式软件开发全流程
vscodekeil嵌入式软件开发全流程 1 安装MinGW-w64 (1) MinGW-w64 是一个用于Windows操作系统的开发工具集,其包含了C语言编译器 GCC(GNU Compiler Collection),官网地址:https://www.mingw-w6…...
GitHub 从入门到精通完全指南(2025版)
以下是GitHub 从入门到精通完全指南,整合优质教程及官方文档,涵盖基础操作、协作开发、高级功能及实战技巧,助你快速掌握 GitHub 全流程。 一、GitHub 入门篇 1. 注册与配置 注册 GitHub 账号 访问 GitHub 官网,点击“Sign Up”填写邮箱、用户名、密码完成注册。建议绑定双…...
总结【过往部分项目经历一(计算机图形学方向)】
总结【过往部分项目经历】 1.蜂窝填充算法2.孔洞识别算法3.扫掠轮廓计算4.二维排料算法5.最大内接圆算法 1.蜂窝填充算法 介绍: 主要从二维六角网格基本算法出发,基于自定义数据结构和拓扑关系,从二维到三维进行拓展,六角网格->六棱柱-&g…...
Flask(补充内容)配置SSL 证书 实现 HTTPS 服务
没有加密的http服务,就像在裸泳,钻到水里便将你看个精光。数据在互联网上传输时,如果未经加密,随时可能被抓包软件抓住,里面的cookie、用户名、密码什么的,它会看得一清二楚,所以,只…...
js逆向分享
某验三代 这玩意大家应该都人手一份了,也没啥好分享的了,需要注意的是,一共五个请求,分别是: "https://apiv6.geetest.com/gettype.php “https://apiv6.geetest.com/get.php” “https://api.geevisit.com/a…...
【cocos creator 3.x】速通3d模型导入, 模型创建,阴影,材质使用,模型贴图绑定
1、右键创建平面,立方体 2、点击场景根节点,shadows勾选enabled3、点击灯光,shadow enabled勾选 4、点击模型,勾选接收阴影,投射阴影(按照需要勾选) 5、材质创建 6、选中节点,找…...
CentOS 中安装 vim
1. 使用 Yum 安装 Vim 如果您的系统可以正常访问互联网,并且已经配置好了正确的 Yum 源,可以直接运行以下命令安装 vim: sudo yum install vim -y 如果默认的 vim 包不可用,可以尝试安装增强版 vim-enhanced: sudo yu…...
安全可靠+操作简捷——安科瑞预付费电表的用户体验升级
安科瑞顾强 在现代化用电场景中,预付费模式凭借其高效性与便捷性,已成为商业、工业及住宅用电管理的优选方案。安科瑞电气推出的DDSY1352/DTSY1352系列预付费电能表,搭配智能管理平台,为用户提供从精准计量、智能控制到数据分析的…...
AI与物联网的深度融合:开启智能生活新时代
在当今数字化时代,人工智能(AI)和物联网(IoT)作为两大前沿技术,正在加速融合,为我们的生活和工作带来前所未有的变革。这种融合不仅提升了设备的智能化水平,还为各行各业带来了新的机…...
赛灵思 XCVU095-2FFVB2104E XilinxFPGA Virtex UltraScale
XCVU095-2FFVB2104I 是 Xilinx(现 AMD)Virtex UltraScale 系列中的高端 FPGA 器件,基于 20nm 工艺,提供卓越的逻辑密度和高速串行 I/O 能力,广泛应用于 400G 网络、ASIC 原型验证及大型数据中心互联 该器件集成 1 176…...
leetcode0212. 单词搜索 II - hard
1 题目:单词搜索 II 官方标定难度:难 给定一个 m x n 二维字符网格 board 和一个单词(字符串)列表 words, 返回所有二维网格上的单词 。 单词必须按照字母顺序,通过 相邻的单元格 内的字母构成ÿ…...
解决 VSCode 中 NVM 配置后无法识别 Node 和 NPM 的问题
在开发中,我们经常需要使用 Node.js 和 NPM 来管理 JavaScript 项目依赖,而 NVM(Node Version Manager)是开发者在本地环境中管理多个 Node.js 版本的得力工具。不过,有时候在 VSCode 中配置完 NVM 后,可能…...
67.评论日记
我的评论本身也就是一种回答 沈阳车展帖子灵异失踪,究竟是谁干的?_哔哩哔哩_bilibili 2025年4月17日17:32:10...
Vscode 插件开发
文章目录 1、使用vscode官方插件生成框架,下载脚手架2、使用脚手架初始化项目,这里我选择的是js3、生成的文件结构如下,重要的就是以下两个文件4、代码5、打包使用6、发布官网地址7、publisher ID undefined provided in the extension manif…...
数据结构(6)
实验步骤: 任务一: 编写算法实现带头结点单链表的就地逆置,即利用原带头结点单链表的结点空间把元素序列 a0,al,……,an-i 逆置为 an-1,……,al, a0 [程序参数设计] 定义了一个带头结点的单链表结构体,并提供了初始化、尾部插入、打印、就地…...
【ROS】恢复行为
【ROS】恢复行为 前言恢复行为(recovery_behavior)概述恢复行为的参数示例:recovery_behavior.yaml 配置文件参数说明与配置原则恢复行为模块的参数设置reset_recovery(重置行为:清除代价地图)参数冲突说明…...
HashMap中put方法的执行流程
在 Java 编程中,HashMap 是一种常用的集合类,它以键值对(Key-Value)的形式存储数据,它具有高效查找、插入和删除的优势。 一.HashMap底层数据结构 JDK 1.7:采用 数组 链表 的结构。JDK 1.8:优…...
基于深度学习并利用时间信息在X射线血管造影中进行冠状动脉血管分割|文献速递-深度学习医疗AI最新文献
Title 题目 Deep learning based coronary vessels segmentation in X-ray angiographyusing temporal information 基于深度学习并利用时间信息在X射线血管造影中进行冠状动脉血管分割 01 文献速递介绍 有创冠状动脉造影(ICA)在冠状动脉疾病&#…...
JVM详解(曼波脑图版)
(✪ω✪)ノ 好哒!曼波会用最可爱的比喻给小白同学讲解JVM,准备好开启奇妙旅程了吗?(๑˃̵ᴗ˂̵)و 📌 思维导图 ━━━━━━━━━━━━━━━━━━━ 🍎 JVM是什么?(苹果式比…...
深度理解指针之例题
文章目录 前言题目分析与讲解涉及知识点 前言 对指针有一定了解后,讲一下一道初学者的易错题 题目分析与讲解 先定义一个数组跟一个指针变量 然后把数组名赋值给指针变量————也就是把首地址传到pulPtr中 重点是分析这一句: *(pulPtr…...
Electricity Market Optimization(VI) - 机组组合问题的 GAMS 求解
根据之前的博客,我们考虑机组的启动成本只讨论考虑以下几种约束的机组组合问题: 功率平衡约束火电机组启停约束和爬坡约束备用容量约束 min ∑ t 1 T ( C t g e n C t u c C t curt ) s.t. C t g e n ∑ i ∈ [ G ] c i ( p i , t c ) C t u c …...
【Leetcode 每日一题】2176. 统计数组中相等且可以被整除的数对
问题背景 给你一个下标从 0 0 0 开始长度为 n n n 的整数数组 n u m s nums nums 和一个整数 k k k,请你返回满足 0 ≤ i < j < n 0 \le i < j < n 0≤i<j<n, n u m s [ i ] n u m s [ j ] nums[i] nums[j] nums[i]nums[j] 且…...
赛灵思 XCVU3P‑2FFVC1517I XilinxFPGA Virtex UltraScale+
XCVU3P‑2FFVC1517I AMD Xilinx Virtex UltraScale 系列中的高端 FPGA,基于 TSMC 16 nm FinFET 工艺及第三代 3D IC 堆栈互连技术(SSI),旨在为数据中心互连、高性能计算、网络加速和信号处理等苛刻应用提供领先的性能‑功耗比。…...
Rust 与 JavaScript 的 WebAssembly 互操作指南
1. Rust 中导入和导出 JS 函数 导入 JS 函数 Rust 代码中可以通过 extern 块导入 JavaScript 函数: #[link(wasm_import_module "mod")] // 指定 JS 模块名 extern { fn foo(); // 声明导入的 JS 函数 }如果没有指定 wasm_import_module,默…...
2025年特种设备安全管理 A 证考试全解析
对于想要获取特种设备安全管理 A 证的人员来说,了解考试的具体内容与形式是备考的关键。下面将为大家全面解析特种设备安全管理 A 证考试,助力大家顺利备考,成功取证。 特种设备安全管理 A 证考试内容丰富,涵盖多个重要领域。特种…...
TOA与AOA联合定位的高精度算法,三维、4个基站的情况,MATLAB例程,附完整代码
本代码实现了三维空间内目标的高精度定位,结合到达角(AOA) 和到达时间(TOA) 两种测量方法,通过4个基站的协同观测,利用最小二乘法解算目标位置。代码支持噪声模拟、误差分析及三维可视化,适用于无人机导航、室内定位等场景。订阅专栏后可获得完整代码 文章目录 运行结果…...