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

消息队列(3) -封装数据库的操作

前言

上一篇博客我们写了, 关于交换机, 队列,绑定, 写入数据库的一些建库建表的操作 这一篇博客中,我们将建库建表操作,封装一下实现层一个类来供上层服务的调用 , 并在写完该类之后, 测试代码是否完整

实现封装

在写完上述的接口类 与 xml 后, 我们想要 创建一个类 ,来调用 接口类中的各种方法 , 并对数据库完成一些操作

创建DataBaseManager 类

在这个类中, 我们 需要完成对数据库的建库建表操作 , 并封装 一些关于表的增删查改方法(这里说一下, 因为我们使用的数据库是SQLite 是一个文件, 所以当调用建表操作的时候就自动建库了)
实现的方法

  1. init()初始化, 该方法内如果没有表的存在就去创建表
  2. checkDB,检查数据库文件是否存在
  3. createtable 创建表
  4. default 创建一个默认的交换机插入进去
  5. delete数据库文件的删除
  6. 剩下的就是封装 队列 交换机 绑定的方法了

对于各种方法的介绍, 都写进代码里面了 ,自行阅读即可

package com.example.demo.mqServer.dataCenter;import com.example.demo.MqApplication;
import com.example.demo.mqServer.core.Binding;
import com.example.demo.mqServer.core.Exchange;
import com.example.demo.mqServer.core.ExchangeType;
import com.example.demo.mqServer.core.MSGQueue;
import com.example.demo.mqServer.mapper.MateMapper;import java.io.File;
import java.util.List;public class DataBaseManager {private MateMapper mateMapper;// 针对数据库进行初始化public void init() {// 手动获取matemapper 对象mateMapper = MqApplication.context.getBean(MateMapper.class);// 手动的获取到 MetaMapperif (!checkDBExists()) {//如果数据库不存在,就进行建表操作// 先创建一个data目录File dataDir = new File("./data");dataDir.mkdirs();createTable();// 插入默认数据createDefaultData();System.out.println("[DataBaseManager] 数据库初始化完成!");} else {// 数据库已经存在了, 啥都不必做即可System.out.println("[DataBaseManager] 数据库已经存在!");}}// 删除数据库,  及删除文件 也删除目录 public void deleteDB() {File file = new File("./data/meta.db");boolean ret = file.delete();if (ret) {System.out.println("[DataBaseManager] 删除数据库文件成功!");} else {System.out.println("[DataBaseManager] 删除数据库文件失败!");}File dataDir = new File("./data");// 使用 delete 删除目录的时候, 需要保证目录是空的.ret = dataDir.delete();if (ret) {System.out.println("[DataBaseManager] 删除数据库目录成功!");} else {System.out.println("[DataBaseManager] 删除数据库目录失败!");}}// 检查是否存在meta.db 文件private boolean checkDBExists() {File file = new File("./data/meta.db");return file.exists();}// 这个方法用来建表.// 建库操作并不需要手动执行. (不需要手动创建 meta.db 文件)// 首次执行这里的数据库操作的时候, 就会自动的创建出 meta.db 文件来 (MyBatis 帮我们完成的)private void createTable() {mateMapper.createExchangeTable();mateMapper.createQueueTable();mateMapper.createBindingTable();System.out.println("[DataBaseManager] 创建表完成!");}// 给数据库表中, 添加默认的数据.// 此处主要是添加一个默认的交换机.// RabbitMQ 里有一个这样的设定: 带有一个 匿名 的交换机, 类型是 DIRECT.private void createDefaultData() {// 先构建一个交换机Exchange exchange = new Exchange();exchange.setName("");exchange.setType(ExchangeType.direct);exchange.setDurable(true);exchange.setAutoDelete(false);mateMapper.insertExchange(exchange);System.out.println("[DataBaseManager] 创建初始数据完成!");}public void insertExchange(Exchange exchange){mateMapper.insertExchange(exchange);}public List<Exchange> selectAllExchanges(){return mateMapper.selectAllExchanges();}public void deleteExchange(String exchangeName){mateMapper.deleteExchange(exchangeName);}public void insertQueue(MSGQueue queue){mateMapper.insertQueue(queue);}public List<MSGQueue> selectAllQueues(){return mateMapper.selectAllQueues();}public void deleteQueue(String queueName){mateMapper.deleteQueue(queueName);}public void insertBinding(Binding binding){mateMapper.insertBinding(binding);}public List<Binding> selectAllBindings(){return mateMapper.selectAllBindings();}public void deleteBinding(Binding binding){mateMapper.deleteBinding(binding);}
}

另一种获取Bean对象的方式

对DataBaseManager 类的 解释, 我们知道 想要 获取 Bean对象 一般情况下 我们使用的 @Autowired注解, 但是这个类 我们想要手动 来操作, 使用@Autowired 就在一开始就存入了 , 所以我们教大家另一种 获取Bean对象的方式

步骤1: 找到启动类 , 在启动类中添加一个静态成员
public static ConfigurableApplicationContext context;
步骤2: 使用context 等于 run方法结果
步骤3: 在DataBaseManager 中使用 context 来实现对象装配
mateMapper = MqApplication.context.getBean(MateMapper.class);

package com.example.demo;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;@SpringBootApplication
public class MqApplication {// 在启动类创建一个静态成员, 用来手动的获取bean对象public static ConfigurableApplicationContext context;public static void main(String[] args) {context = SpringApplication.run(MqApplication.class, args);}}

对数据库进行单元测试

但我们,每写完一个模块的时候, 我们就应该对该模块就行单元测试 ,
接下来我们对数据库进行单元测试
单元测试是在想要测试的类中点击Generate , 会出现一个Test ,点击Test
在这里插入图片描述
在这里插入图片描述
这个Test(安装Junit的插件-这里就不介绍了) , 然后选择你想要测试的方法,点击OK
在这里插入图片描述
会在Test包中生成对应的类 , 在这个类中加上@SpringBootTest 注解 ,就可以正常使用了
在这里插入图片描述
测试代码如下

package com.example.demo.mqServer.dataCenter;import com.example.demo.MqApplication;
import com.example.demo.mqServer.core.Binding;
import com.example.demo.mqServer.core.Exchange;
import com.example.demo.mqServer.core.ExchangeType;
import com.example.demo.mqServer.core.MSGQueue;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.test.context.SpringBootTest;import java.util.List;import static org.junit.jupiter.api.Assertions.*;
@SpringBootTest
class DataBaseManagerTest {private DataBaseManager dataBaseManager = new DataBaseManager();// 接下来下面这里需要编写多个 方法 . 每个方法都是一个/一组单元测试用例.// 还需要做一个准备工作. 需要写两个方法, 分别用于进行 "准备工作" 和 "收尾工作"// 使用这个方法, 来执行准备工作. 每个用例执行前, 都要调用这个方法.@BeforeEachpublic void setUp() {// 由于在 init 中, 需要通过 context 对象拿到 metaMapper 实例的.// 所以就需要先把 context 对象给搞出来.MqApplication.context = SpringApplication.run(MqApplication.class);dataBaseManager.init();}// 使用这个方法, 来执行收尾工作. 每个用例执行后, 都要调用这个方法.@AfterEachpublic void tearDown() {// 这里要进行的操作, 就是把数据库给清空~~ (把数据库文件, meta.db 直接删了就行了)// 注意, 此处不能直接就删除, 而需要先关闭上述 context 对象!!// 此处的 context 对象, 持有了 MetaMapper 的实例, MetaMapper 实例又打开了 meta.db 数据库文件.// 如果 meta.db 被别人打开了, 此时的删除文件操作是不会成功的 (Windows 系统的限制, Linux 则没这个问题).// 另一方面, 获取 context 操作, 会占用 8080 端口. 此处的 close 也是释放 8080.MqApplication.context.close();dataBaseManager.deleteDB();}@Testpublic void testInitTable() {// 由于 init 方法, 已经在上面 setUp 中调用过了. 直接在测试用例代码中, 检查当前的数据库状态即可.// 直接从数据库中查询. 看数据是否符合预期.// 查交换机表, 里面应该有一个数据(匿名的 exchange); 查队列表, 没有数据; 查绑定表, 没有数据.List<Exchange> exchangeList = dataBaseManager.selectAllExchanges();List<MSGQueue> queueList = dataBaseManager.selectAllQueues();List<Binding> bindingList = dataBaseManager.selectAllBindings();// 直接打印结果, 通过肉眼来检查结果, 固然也可以. 但是不优雅, 不方便.// 更好的办法是使用断言.// System.out.println(exchangeList.size());// assertEquals 判定结果是不是相等.// 注意这俩参数的顺序. 虽然比较相等, 谁在前谁在后, 无所谓.// 但是 assertEquals 的形参, 第一个形参叫做 expected (预期的), 第二个形参叫做 actual (实际的)Assertions.assertEquals(1, exchangeList.size());Assertions.assertEquals("", exchangeList.get(0).getName());Assertions.assertEquals(ExchangeType.direct, exchangeList.get(0).getType());Assertions.assertEquals(0, queueList.size());Assertions.assertEquals(0, bindingList.size());}private Exchange createExchange(String name){Exchange exchange = new Exchange();exchange.setName(name);exchange.setAutoDelete(false);exchange.setDurable(true);exchange.setType(ExchangeType.fanout);exchange.setArguments("aaa",1);exchange.setArguments("bbb",2);return exchange;}@Testpublic void insertExchange() {Exchange exchange =createExchange("testExchange");dataBaseManager.insertExchange(exchange);// 插入完毕之后, 查询结果List<Exchange> exchangeList = dataBaseManager.selectAllExchanges();Assertions.assertEquals(2, exchangeList.size());Exchange newExchange = exchangeList.get(1);Assertions.assertEquals("testExchange", newExchange.getName());Assertions.assertEquals(ExchangeType.fanout, newExchange.getType());Assertions.assertEquals(false, newExchange.isAutoDelete());Assertions.assertEquals(true, newExchange.isDurable());Assertions.assertEquals(1, newExchange.getArguments("aaa"));Assertions.assertEquals(2, newExchange.getArguments("bbb"));System.out.println("insertExchange测试成功");}@Testpublic void testDeleteExchange() {// 先构造一个交换机, 插入数据库; 然后再按照名字删除即可!Exchange exchange =createExchange("testExchange");dataBaseManager.insertExchange(exchange);List<Exchange> exchangeList = dataBaseManager.selectAllExchanges();Assertions.assertEquals(2, exchangeList.size());Assertions.assertEquals("testExchange", exchangeList.get(1).getName());// 进行删除操作dataBaseManager.deleteExchange("testExchange");// 再次查询exchangeList = dataBaseManager.selectAllExchanges();Assertions.assertEquals(1, exchangeList.size());Assertions.assertEquals("", exchangeList.get(0).getName());System.out.println("testDeleteExchange测试成功");}private MSGQueue createTestQueue(String queueName) {MSGQueue queue = new MSGQueue();queue.setName(queueName);queue.setDurable(true);queue.setAutoDelete(false);queue.setExclusive(false);queue.setArguments("aaa", 1);queue.setArguments("bbb", 2);return queue;}@Testpublic void testInsertQueue() {MSGQueue queue = createTestQueue("testQueue");dataBaseManager.insertQueue(queue);List<MSGQueue> queueList = dataBaseManager.selectAllQueues();Assertions.assertEquals(1, queueList.size());MSGQueue newQueue = queueList.get(0);Assertions.assertEquals("testQueue", newQueue.getName());Assertions.assertEquals(true, newQueue.isDurable());Assertions.assertEquals(false, newQueue.isAutoDelete());Assertions.assertEquals(false, newQueue.isExclusive());Assertions.assertEquals(1, newQueue.getArguments("aaa"));Assertions.assertEquals(2, newQueue.getArguments("bbb"));System.out.println("testInsertQueue测试成功");}@Testpublic void testDeleteQueue() {MSGQueue queue = createTestQueue("testQueue");dataBaseManager.insertQueue(queue);List<MSGQueue> queueList = dataBaseManager.selectAllQueues();Assertions.assertEquals(1, queueList.size());// 进行删除dataBaseManager.deleteQueue("testQueue");queueList = dataBaseManager.selectAllQueues();Assertions.assertEquals(0, queueList.size());System.out.println("testDeleteQueue测试成功");}private Binding createTestBinding(String exchangeName, String queueName) {Binding binding = new Binding();binding.setExchangeName(exchangeName);binding.setMsgQueueName(queueName);binding.setBindingKey("testBindingKey");return binding;}@Testpublic void testInsertBinding() {Binding binding = createTestBinding("testExchange", "testQueue");dataBaseManager.insertBinding(binding);List<Binding> bindingList = dataBaseManager.selectAllBindings();Assertions.assertEquals(1, bindingList.size());Assertions.assertEquals("testExchange", bindingList.get(0).getExchangeName());Assertions.assertEquals("testQueue", bindingList.get(0).getMsgQueueName());Assertions.assertEquals("testBindingKey", bindingList.get(0).getBindingKey());System.out.println("testInsertBinding测试成功");}@Testpublic void testDeleteBinding() {Binding binding = createTestBinding("testExchange", "testQueue");dataBaseManager.insertBinding(binding);List<Binding> bindingList = dataBaseManager.selectAllBindings();Assertions.assertEquals(1, bindingList.size());// 删除Binding toDeleteBinding = createTestBinding("testExchange", "testQueue");dataBaseManager.deleteBinding(toDeleteBinding);bindingList = dataBaseManager.selectAllBindings();Assertions.assertEquals(0, bindingList.size());System.out.println("testDeleteBinding测试成功");}
}

相关文章:

消息队列(3) -封装数据库的操作

前言 上一篇博客我们写了, 关于交换机, 队列,绑定, 写入数据库的一些建库建表的操作 这一篇博客中,我们将建库建表操作,封装一下实现层一个类来供上层服务的调用 , 并在写完该类之后, 测试代码是否完整 实现封装 在写完上述的接口类 与 xml 后, 我们想要 创建一个类 ,来调用…...

PostgreSQL中根据时间段范围查询数据,如19:29:10到20:29:10范围内的数据,排除年月日

数据格式如下 问题描述 我的SQL语句条件是 WHERE (TO_CHAR(cti.binder_gen_time, YYYY-MM-DD HH:mm:ss) > 19:29:10 AND TO_CHAR(cti.binder_gen_time, YYYY-MM-DD HH:mm:ss) < 20:29:10)为什么我数据的时间是2023-07-20 17:58:29也能被查出来&#xff1f; 问题解决…...

【二分+贪心】CF1665 C

Problem - C - Codeforces 题意&#xff1a; 思路&#xff1a; 一开始想太简单wa6了 只想到先感染大的分量&#xff0c;然后最后把最大的分量剩下的染色 但是可能会有别的分量更大&#xff08;因为最后给最大的染色之后可能不再是最大的&#xff09; 可以用堆维护&#xf…...

【Wamp】安装 | 局域网内设备访问

安装教程&#xff1a; https://wampserver.site/article/1.html 下载 https://www.wampserver.com/en/ 安装路径上不能有中文 安装好之后图标呈绿色 放入网页文件 将网页文件放置于wamp文件夹的www子文件夹 例如&#xff1a;\Wamp\program\www 修改http端口 WAMP服务器…...

【golang】类型推断和变量重声明

类型推断是一种编程语言在编译期自动解释表达式类型的能力。 1.Go语言的类型推断可以带来哪些好处&#xff1f; 在写代码时&#xff0c;我们通过使用Go语言的类型推断会节省敲击次数&#xff0c;而节省下来的键盘敲击次数几乎可以忽略不记。但它真正的好处&#xff0c;往往会…...

“算法详解”系列第3卷贪心算法和动态规划出版

“算法详解”系列图书共有4卷&#xff0c;目前1到3卷已经出版。最新出版的是第3卷—贪心算法和动态规划。 算法详解 卷3 贪心算法和动态规划 “算法详解”系列图书共有4卷&#xff0c;本书是第3卷—贪心算法和动态规划。其中贪心算法主要包括调度、最小生成树、集群、哈夫曼编…...

CSS前端开发指南:创造精美的用户界面

简介&#xff1a; 《CSS前端开发指南&#xff1a;创造精美的用户界面》是一本旨在帮助读者掌握CSS技术&#xff0c;实现令人惊叹的前端用户界面的实用指南。无论您是初学者还是有经验的开发者&#xff0c;本书都将为您提供全面的知识和实用技巧&#xff0c;帮助您创建引人注目…...

代数学与理论物理中常见的群

代数学与理论物理中常见的群 代数学与理论物理中常见的群 四阶群 六阶群 对称群 二维转动群 三维转动群 三维正交群 群 O3群...

解析xml文件,获取需要的数据并写入txt文件中

_ 话不多说&#xff01;直接上代码&#xff01;_ 1、XmlUtil.java xml解析工具类 public class XmlUtil {private static String dicName "";private static String dicValue "";// 用于存储需要的数据private static List<Map<String, Str…...

JavaScript基础 第三天

1.for循环 2.数组的基本使用和操作 3.数组排序 一.for循环 ① 语法&#xff1a;把声明起始值&#xff0c;循环条件&#xff0c;变量值写到一起&#xff0c;让人一目了然 for(变量起始值;终止条件;变量变化量) {// 循环体 }举例&#xff1a; for (let i 0; i < 100; i)…...

2.Redis部署到Windows服务器

1.下载安装包 Redis官网没有提供Windows的安装包&#xff0c;可以去gitHub或者网上去下载Redis的Windows安装包。 2.Redis部署到服务器 将Redis整个文件夹放到服务器的指令目录&#xff0c;然后进行修改Redis的配置文件 redis.windows.conf&#xff0c;修改里面的配置项 1.b…...

【修正-高斯拉普拉斯滤波器-用于平滑和去噪】基于修正高斯滤波拉普拉斯地震到达时间自动检测研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…...

Go语言基础: 有参函数Func、Map、Strings详细案例教程

目录标题 一、Variadic Functions1.Syntax2.Examples and understanding how variadic functions work3.Slice arguments vs Variadic arguments 仅改变可变参数4.Gotcha 二、Map1.Create a Map2.Retrieving value for a key from a map3.Checking if a key exists4.Iterate ov…...

JDBC连接数据库如何实现你会吗???

1.首先建立一个maven项目。。。详细过程来了哇 还没有安装maven的童鞋可以看这里&#xff1a;maven的下载安装与配置环境变量&#xff01;&#xff01;&#xff01;&#xff08;全网最详细&#xff09;_明天更新的博客-CSDN博客 有很多小伙伴就有疑问啦&#xff0c;难道我直接…...

C#与C++交互(2)——ANSI、UTF8、Unicode文本编码

【前言】 我们知道计算机上只会存储二进制的数据&#xff0c;无论文本、图片、音频、视频等&#xff0c;当我们将其保存在计算机上时&#xff0c;都会被转成二进制的。我们打开查看的时候&#xff0c;二进制数据又被转成我们看得懂的信息。如何将计算机上的二进制数据转为我们…...

SQLSTATE[42000]: this is incompatible with sql_mode=only_full_group_by in

执行 SELECT *FROM test WHERE id>1 GROUP BY name having AVG(age)>10 ORDER BY id desc limit 1 提示错误 Fatal error: Uncaught PDOException: SQLSTATE[42000]: Syntax error or access violation: 1055 Expression #1 of SELECT list is not in GROUP BY clause…...

企业权限管理(五)-订单分页

订单分页查询 PageHelper介绍 PageHelper是国内非常优秀的一款开源的mybatis分页插件&#xff0c;它支持基本主流与常用的数据库&#xff0c;例如mysql、oracle、mariaDB、DB2、SQLite、Hsqldb等。 PageHelper使用 集成 引入分页插件有下面2种方式&#xff0c;推荐使用 Maven …...

Blender如何给fbx模型添加材质贴图并导出带有材质贴图的模型

推荐&#xff1a;使用 NSDT场景编辑器快速助你搭建可二次编辑的3D应用场景 此教程适合新手用户&#xff0c;专业人士直接可直接绕路。 本教程中介绍了利用Blender建模软件&#xff0c;只需要简单几步就可以为模型添加材质贴&#xff0c;图&#xff0c;并且导出带有材质的模型文…...

MySQL不走索引的情况分析

未建立索引 当数据表没有设计相关索引时&#xff0c;查询会扫描全表。 create table test_temp (test_id int auto_incrementprimary key,field_1 varchar(20) null,field_2 varchar(20) null,field_3 bigint null,create_date date null );expl…...

安装ubuntu22.04系统,配置国内源以及ssh远程登录

一、安装ubuntu22.04系统 原文连接&#xff1a;Ubuntu操作系统22.04版本安装教程-VMware虚拟机_wx63f86e949a470的技术博客_51CTO博客 1.点击界面左侧的开启此虚拟机&#xff0c;即可进入Ubuntu操作系统安装界面&#xff0c;点击​​Try or Install Ubuntu ​​即可开始安装 …...

docker详细操作--未完待续

docker介绍 docker官网: Docker&#xff1a;加速容器应用程序开发 harbor官网&#xff1a;Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台&#xff0c;用于将应用程序及其依赖项&#xff08;如库、运行时环…...

基于FPGA的PID算法学习———实现PID比例控制算法

基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容&#xff1a;参考网站&#xff1a; PID算法控制 PID即&#xff1a;Proportional&#xff08;比例&#xff09;、Integral&#xff08;积分&…...

VB.net复制Ntag213卡写入UID

本示例使用的发卡器&#xff1a;https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...

如何在看板中体现优先级变化

在看板中有效体现优先级变化的关键措施包括&#xff1a;采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中&#xff0c;设置任务排序规则尤其重要&#xff0c;因为它让看板视觉上直观地体…...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)

可以使用Sqliteviz这个网站免费编写sql语句&#xff0c;它能够让用户直接在浏览器内练习SQL的语法&#xff0c;不需要安装任何软件。 链接如下&#xff1a; sqliteviz 注意&#xff1a; 在转写SQL语法时&#xff0c;关键字之间有一个特定的顺序&#xff0c;这个顺序会影响到…...

什么是Ansible Jinja2

理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具&#xff0c;可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板&#xff0c;允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板&#xff0c;并通…...

深入浅出Diffusion模型:从原理到实践的全方位教程

I. 引言&#xff1a;生成式AI的黎明 – Diffusion模型是什么&#xff1f; 近年来&#xff0c;生成式人工智能&#xff08;Generative AI&#xff09;领域取得了爆炸性的进展&#xff0c;模型能够根据简单的文本提示创作出逼真的图像、连贯的文本&#xff0c;乃至更多令人惊叹的…...

VisualXML全新升级 | 新增数据库编辑功能

VisualXML是一个功能强大的网络总线设计工具&#xff0c;专注于简化汽车电子系统中复杂的网络数据设计操作。它支持多种主流总线网络格式的数据编辑&#xff08;如DBC、LDF、ARXML、HEX等&#xff09;&#xff0c;并能够基于Excel表格的方式生成和转换多种数据库文件。由此&…...

CTF show 数学不及格

拿到题目先查一下壳&#xff0c;看一下信息 发现是一个ELF文件&#xff0c;64位的 ​ 用IDA Pro 64 打开这个文件 ​ 然后点击F5进行伪代码转换 可以看到有五个if判断&#xff0c;第一个argc ! 5这个判断并没有起太大作用&#xff0c;主要是下面四个if判断 ​ 根据题目…...

前端工具库lodash与lodash-es区别详解

lodash 和 lodash-es 是同一工具库的两个不同版本&#xff0c;核心功能完全一致&#xff0c;主要区别在于模块化格式和优化方式&#xff0c;适合不同的开发环境。以下是详细对比&#xff1a; 1. 模块化格式 lodash 使用 CommonJS 模块格式&#xff08;require/module.exports&a…...