DataX实战:从MongoDB到MySQL的数据迁移--修改源码并测试打包

        在现代数据驱动的业务环境中,数据迁移和集成是常见的需求。DataX,作为阿里云开源的数据集成工具,提供了强大的数据同步能力,支持多种数据源和目标端。本文将介绍如何使用DataX将数据从MongoDB迁移到MySQL。

环境准备

  1. 安装MongoDB:首先,我们需要安装MongoDB。通过创建repo文件并配置yum源,我们可以轻松地通过yum安装MongoDB。此外,还需要修改MongoDB的配置文件以允许远程连接,并启动MongoDB服务。

  2. MongoDB可视化工具:为了方便数据操作,我们可以使用MongoDB可视化工具进行数据管理。

MongoDB在Linux系统中的安装与配置指南-CSDN博客

数据准备

创建表和添加测试数据

        在MongoDB中创建必要的表并添加测试数据。可以使用AIGC工具生成插入语句或使用Python代码进行数据导入。

数据如下:

6685758046e0fb0001dad8e8,340030000B47363438383733,8C780D32F900260383493808CC96,2024-07-04 00:00:00 055
6685758046e0fb0001dad8e9,340030000B47363438383733,8C79A06C39EE65FC81D828307124,2024-07-04 00:00:00 055
6685758046e0fb0001dad8ea,340030000B47363438383733,8C79A06C39EE632C2C12766ABC7D,2024-07-04 00:00:00 055
6685758046e0fb0001dad8eb,340030000B47363438383733,8C780D32381A65EEB9D6ACD107E7,2024-07-04 00:00:00 055
6685758046e0fb0001dad8ec,340030000B47363438383733,8C79A06C39EE65FC83D8242B91FC,2024-07-04 00:00:00 055
6685758046e0fb0001dadb53,180025000847363438383733,02818334223D7A,2024-07-04 00:00:00 125
6685758046e0fb0001dadb54,180025000847363438383733,8C7813B93818F058371851BB46ED,2024-07-04 00:00:00 125
6685758046e0fb0001dadb55,180025000847363438383733,A8001BAF809CEF25E00492C097AD,2024-07-04 00:00:00 125
6685758046e0fb0001dadb56,180025000847363438383733,8D78046A990C8E9DF09019F5FFD9,2024-07-04 00:00:00 125
6685758046e0fb0001dadb57,180025000847363438383733,02C18CB2F5ACA1,2024-07-04 00:00:00 125
6685758046e0fb0001dadb58,180025000847363438383733,200016303DA8AC,2024-07-04 00:00:00 125
6685758046e0fb0001dadb59,180025000847363438383733,02C18CB2F5ACA1,2024-07-04 00:00:00 125
6685758046e0fb0001dadb5a,180025000847363438383733,02C189B8C3FFB4,2024-07-04 00:00:00 125
6685758046e0fb0001dadb5b,180025000847363438383733,8D89805E584FE2AC38F4F65130D7,2024-07-04 00:00:00 125
6685758046e0fb0001dadb5c,180025000847363438383733,02A185BA442656,2024-07-04 00:00:00 125
6685758046e0fb0001dadb5d,180025000847363438383733,8D7805AF9909180C18041613AFAB,2024-07-04 00:00:00 125
6685758046e0fb0001dadb5e,180025000847363438383733,02E18D1AB8F754,2024-07-04 00:00:00 125
6685758046e0fb0001dadb5f,180025000847363438383733,02A184B1B5AC11,2024-07-04 00:00:00 125
6685758046e0fb0001dadb60,180025000847363438383733,80618193580D32DD1EC5D965CAAF,2024-07-04 00:00:00 125
6685758046e0fb0001dadb61,180025000847363438383733,A000019389C80030A40000B08473,2024-07-04 00:00:00 125
6685758046e0fb0001dadb62,180025000847363438383733,A8001235FF731F13FFF453FB3E9D,2024-07-04 00:00:00 125
6685758046e0fb0001dadb63,180025000847363438383733,A00015BDC2980030A400000C9499,2024-07-04 00:00:00 125
6685758046e0fb0001dadb64,180025000847363438383733,02A18639AEDAAD,2024-07-04 00:00:00 125
6685758046e0fb0001dadb65,180025000847363438383733,8D780E409908D120F0482094F4EF,2024-07-04 00:00:00 125
6685758046e0fb0001dadb66,180025000847363438383733,5D75021BAFC19A,2024-07-04 00:00:00 125
6685758046e0fb0001dadb67,180025000847363438383733,02C18930C484A8,2024-07-04 00:00:00 125
6685758046e0fb0001dadb68,180025000847363438383733,A00015BDFFD9F93B2004E186573A,2024-07-04 00:00:00 125

 示例:

db.yourCollectionName.insertOne({  "id": "6685758046e0fb0001dad8e8",  "serialNumber": "340030000B47363438383733",  "uniqueId": "8C780D32F900260383493808CC96",  "timestamp": "2024-07-04T00:00:00.055Z"  
})

数据导入方式

介绍了两种数据导入方式,一种是使用Python代码导入,另一种是通过命令行导入。

使用 python 代码导入

pip install pymongo==4.4

from pymongo import MongoClient# 创建MongoDB连接
client = MongoClient('hadoop13', 27017)# 选择数据库,如果不存在则会自动创建
db = client['demo']# 选择集合,如果不存在则会自动创建
collection = db['y_demo']# 插入数据
#rawDataContent,revTime,deviceCodewith open('测试数据','r') as file1:for line in file1:arr = line.split(',')print(arr)dict = {"rawDataContent": arr[2], "revTime": arr[3].rstrip('\n'), "deviceCode": arr[1]}print(dict)collection.insert_one(dict)

使用命令导入

如果不会 python,也可以通过命令导入:

mongoimport -h 127.0.0.1 -d demo -c y_demo --file "/home/y_demo.json" --jsonArray

json 数据在本文绑定资源可下载

DataX实战

真实需求

        将MongoDB中的一个表的三个字段导入到ClickHouse中,并在导入过程中将一个字段拆分为三个字段,同时增加三个新字段,变为 6 个字段。

解决方案

通过修改DataX的MongoDB reader源码来实现这一需求。

源码修改

详细介绍了如何使用IDEA打开DataX源码,修改maven配置,下载必要的jar包,并进行源码的修改和测试。

Datax - mongodb reader

DataX/mongodbreader/doc/mongodbreader.md at master · alibaba/DataX · GitHub

DataX案例:读取MongoDB的数据导入MySQL - 架构艺术 - 博客园 (cnblogs.com)

源码导入

环境准备

使用IntelliJ IDEA打开DataX源码。配置本地Maven,以加快依赖包的下载速度。

下载 jar 包的过程时间有点长,请耐心等待,本身是不大的,大约 20 多 M,但如果你拿到是含有编译过的 target 文件夹的源码,大约有 6G。

分析需求

阅读MongoDBReader的源码,理解其数据抽取和转换的机制。

首先同事已经通过 java 代码将 mongodb 的数据写入到了 ck 之中,想让你通过 datax 进行数据的抽取。同事的代码已经给了:

package com.lzhy.platform.service.impl;import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.HexUtil;
import com.lzhy.clickhouse.template.ClickHouseTemplate;
import com.lzhy.platform.entity.ParseData;
import com.lzhy.platform.model.pojo.CkAdsbParseData;
import com.lzhy.platform.model.pojo.CkAdsbRawData;
import com.lzhy.platform.model.pojo.DecodeSaveData;
import com.lzhy.platform.model.pojo.SendKafkaMessage;
import com.lzhy.platform.service.IWorkService;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.atomic.LongAdder;
import java.util.stream.Collectors;@Service("workService")
@Slf4j
@RequiredArgsConstructor
public class WorkServiceImpl implements IWorkService {private final ClickHouseTemplate<CkAdsbRawData> rawDataClickHouseTemplate;private final ClickHouseTemplate<CkAdsbParseData> ckAdsbParseDataClickHouseTemplate;public static final String PARSE_TABLE_NAME = "default.adsb_parse_temp_local";/*** 原始数据表名*/public static final String RAW_TABLE_NAME = "default.adsb_raw_data_local";/*** 原始数据计数器 统计消息个数*/private final LongAdder rawDataCount = new LongAdder();/*** 解析数据计数器 统计消息个数*/private final LongAdder parseDataCount = new LongAdder();/*** 原始数据临时存储*/@Getterprivate final List<CkAdsbRawData> rawDataList = new ArrayList<>(2000);/*** 解析数据临时存储*/@Getterprivate final List<CkAdsbParseData> ckParseDataList = new ArrayList<>(2000);@Overridepublic void start() {}@Overridepublic void saveRawDate(SendKafkaMessage sendKafkaMessage) {try {List<String> list = sendKafkaMessage.getRawDataValue();String deviceCode = sendKafkaMessage.getDeviceCode();long revTime = sendKafkaMessage.getRevTime();if (CollUtil.isEmpty(list) || Objects.isNull(deviceCode)) {return;}List<CkAdsbRawData> res = list.stream().filter(StringUtils::hasLength).map(raw -> {String[] split = raw.split(",");String rawContent = split[0];long time = Long.parseLong(split[1]);CkAdsbRawData ckAdsbRawData = new CkAdsbRawData();ckAdsbRawData.setIcao(getIcao(rawContent));ckAdsbRawData.setRevTime(LocalDateTimeUtil.of(time));ckAdsbRawData.setHandleTime(LocalDateTimeUtil.now());ckAdsbRawData.setDeviceCode(deviceCode);ckAdsbRawData.setMsgContent(rawContent);ckAdsbRawData.setMsgType(getDfType(rawContent));return ckAdsbRawData;}).collect(Collectors.toList());rawDataCount.increment();rawDataList.addAll(res);if (rawDataCount.longValue() % 15 == 0) {//存储log.info("原始数据存储。存储大小:{}", ckParseDataList.size());rawDataClickHouseTemplate.insertBath(RAW_TABLE_NAME, rawDataList);rawDataList.clear();rawDataCount.reset();}} catch (Exception e) {log.error("储存失败", e);}}@Overridepublic void saveParseDate(DecodeSaveData decodeSaveData) {if (Objects.isNull(decodeSaveData)) {return;}List<ParseData> parseDataList = decodeSaveData.getParseDataList();if (CollUtil.isEmpty(parseDataList)) {return;}List<CkAdsbParseData> res = parseDataList.stream().map(parseData -> {CkAdsbParseData ckAdsbParseData = new CkAdsbParseData();ckAdsbParseData.setIcao(Integer.parseInt(parseData.getIcao(), 16));ckAdsbParseData.setRevTime(LocalDateTimeUtil.of(parseData.getRevTime()));ckAdsbParseData.setDeviceCode(parseData.getDeviceCode());ckAdsbParseData.setType(parseData.getType());ckAdsbParseData.setRegNo(parseData.getRegNo());ckAdsbParseData.setCallsign(parseData.getCallsign());ckAdsbParseData.setCountry(parseData.getCountry());ckAdsbParseData.setCompany(parseData.getCompany());ckAdsbParseData.setLat(parseData.getLat());ckAdsbParseData.setLng(parseData.getLng());ckAdsbParseData.setAltitude(parseData.getAltitude());ckAdsbParseData.setHeading(parseData.getHeading());ckAdsbParseData.setSpeed(parseData.getSpeed());ckAdsbParseData.setPositionTime(parseData.getPositionTime().getTime());ckAdsbParseData.setSpeedTime(parseData.getSpeedTime() == null ? 0L : parseData.getSpeedTime().getTime());ckAdsbParseData.setVerSpeed(parseData.getVerSpeed());ckAdsbParseData.setVerSpeedType(parseData.getVerSpeedType());ckAdsbParseData.setHeight(parseData.getHeight());ckAdsbParseData.setHandleTime(LocalDateTime.now());ckAdsbParseData.setACode(parseData.getaCode());ckAdsbParseData.setIsOnGround(parseData.getIsOnGround());ckAdsbParseData.setSpi(parseData.getSpi());ckAdsbParseData.setEmergency(parseData.getEmergency());ckAdsbParseData.setAlert("");ckAdsbParseData.setRegNo(parseData.getRegNo());return ckAdsbParseData;}).collect(Collectors.toList());parseDataCount.increment();ckParseDataList.addAll(res);if (parseDataCount.longValue() % 20 == 0) {//存储try {log.info("解析数据存储。存储大小:{}", ckParseDataList.size());ckAdsbParseDataClickHouseTemplate.insertBath(PARSE_TABLE_NAME, ckParseDataList);} catch (Exception e) {log.error("存储失败", e);}ckParseDataList.clear();parseDataCount.reset();}}/*** 获取icao** @param rawContent* @return*/private int getIcao(String rawContent) {int dfType = getDfType(rawContent);if (dfType == 4 || dfType == 5) {return getShortIcao(HexUtil.decodeHex(rawContent));}String icaoStr = rawContent.substring(2, 8);return Integer.parseInt(icaoStr, 16);}private final long CRC24_INIT = 0x0;private final long CRC24_POLY = 0x1FFF409;/*** 获取 04 05 报文icao** @param abMessage* @return*/private int getShortIcao(byte[] abMessage) {long ulCRC = 0;ulCRC = CRC24_INIT;for (int i = 0; i < abMessage.length - 3; i++) {long tem = abMessage[i];tem = tem << 16;ulCRC = ulCRC ^ tem;for (int j = 0; j < 8; j++) {ulCRC = ulCRC << 1;if ((ulCRC & 0x1000000) != 0) {ulCRC = ulCRC ^ CRC24_POLY;}}}long last3Bits = abMessage[4] * 0x10000 + abMessage[5] * 0x100 + abMessage[6];String hex = HexUtil.toHex((ulCRC ^ last3Bits));hex = hex.length() > 6 ? hex.substring(hex.length() - 6) : hex;return Integer.parseUnsignedInt(hex, 16);}/*** 获取df类型** @param rawContent* @return*/private int getDfType(String rawContent) {String substring = rawContent.substring(0, 2);return Integer.parseInt(substring, 16) >> 3;}
}

因为人家代码中用到了 hutool 工具类,所以我们在源码的坐标中有添加该坐标:

<dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.16</version>
</dependency>

修改源码并测试打包

在修改完源码后,需要进行编译和打包。文章中提供了详细的编译命令和可能遇到的编译错误及其解决方案。

修改源码

所有字段全部写死

if (tempCol == null) {//continue; 这个不能直接continue会导致record到目的端错位String columnName = column.getString(KeyConstant.COLUMN_NAME);if ("icao".equals(columnName)){record.addColumn(new LongColumn(getIcao(item.getString("rawDataContent"))));}else if("msg_type".equals(columnName)){record.addColumn(new LongColumn(getDfType(item.getString("rawDataContent"))));}else if("handle_time".equals(columnName)){record.addColumn(new StringColumn(DateUtil.now()));}else{record.addColumn(new StringColumn(null));}
}
打包上传

代码编写完之后,需要编译,打包上传:

对datax的所有模块进行打包,时间比较长 30 分钟左右 【该命令会将 datax 中的所有插件全部打包】

mvn -U clean package assembly:assembly '-Dmaven.test.skip=true'

指定mongodbreader模块 以及 它所依赖的模块进行打包 【推荐使用,大约只运行 3 分钟左右】

mvn -U clean package -pl mongodbreader -am  assembly:assembly '-Dmaven.test.skip=true'

-p1 表示只打包对应的模块 -am 表示对应模块关联的模块也要打包编译。

编译报错

看到这个错误,是 java 环境变量的问题,这个问题非常难找,配置如下:

配置 CLASSPATH:

配置 JAVA_HOME:

配置 PATH 路径:

然后继续执行编译打包名命令,成功!

将idea中打的jar包上传到datax的mongodbreader下,替换原本的插件jar包

此时如果运行 job 任务,会报错,因为会提示缺 hutool 工具的 jar 包

hutool工具类jar包上传到datax的mongodbreader的libs目录下

出现这种错误

 DataX实战之MongoDB导入数据到mysql——打包jar包时出现Could not find goal assembly in plugin org.apache.maven.plugins_datax mongodbreader源码-CSDN博客

测试一下

在完成源码修改和打包后,需要在MySQL中创建相应的表,并编写DataX的JSON配置文件进行测试运行。

mysql建表
create table y_demo(device_code varchar(100),rev_time  varchar(100),msg_content  varchar(100),icao  varchar(100),msg_type  varchar(100),handle_time  varchar(100)
)

 

编写datax的json文件,并且测试运行

测试 json

{"job": {"content": [{"reader": {"name": "mongodbreader","parameter": {"address": ["bigdata01:27017"],"collectionName": "y_demo","column": [{"name":"deviceCode","type":"string"},{"name":"revTime","type":"string"},{"name":"rawDataContent","type":"string"},{"name":"icao","type":"string"},{"name":"msg_type","type":"string"},{"name":"handle_time","type":"string"}],"dbName": "demo",}},"writer": {"name": "mysqlwriter","parameter": {"column": ["device_code","rev_time","msg_content","icao","msg_type","handle_time"],"connection": [{"jdbcUrl": "jdbc:mysql://bigdata01:3306/sqoop","table": ["y_demo"]}],"password": "123456","username": "root","writeMode": "insert"}}}],"setting": {"speed": {"channel": "1"}}}
}
运行报错

添加 jar 包

运行 json 脚本,导入成功

mysql 中的数据如下

资料

Datax mongodbreader源码jar包 ,替换/opt/installs/datax/plugin/reader/mongodbreader/

自定义函数的jar包 /opt/installs/datax/plugin/reader/mongodbreader/libs

hutool工具类 /opt/installs/datax/plugin/reader/mongodbreader/libs

fastjson2 的 jar 包

通过网盘分享的文件:datax-mongo-1.0-SNAPSHOT.jar等4个文件

 视频讲解链接

通过修改DataX源码解决Mongodb导入数据到ClickHouse的问题_哔哩哔哩_bilibili

结语

        DataX提供了一个简单而有效的方法来迁移MongoDB数据到MySQL。通过编写适当的JSON配置文件,我们可以灵活地处理各种复杂的数据迁移任务。这不仅提高了DataX的可用性,也为我们的数据同步工作提供了更多的可能。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【亿美软通-注册/登录安全分析报告】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 暴力破解密码&#xff0c;造成用户信息泄露短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造成亏损无底洞…

ehcarts生成彩虹图,半圆饼图,蚊香图等

其实这三种图我都认为是一种图&#xff0c;都是饼图的变形&#xff0c;需求长这样子 我的效果图这样子 想要一模一样自己改改颜色就行了 我们先生成完整的蚊香图&#xff0c;众所周知&#xff0c;我们正常的饼图只是把seriesData配置一次&#xff0c;然后把数据全部塞进去&a…

9/24作业

1. 分文件编译 分什么要分文件编译&#xff1f; 防止主文件过大&#xff0c;不好修改&#xff0c;简化编译流程 1) 分那些文件 头文件&#xff1a;所有需要提前导入的库文件&#xff0c;函数声明 功能函数&#xff1a;所有功能函数的定义 主函数&#xff1a;main函数&…

【AI视频】Runway:Gen-2 图文生视频与运动模式详解

博客主页&#xff1a; [小ᶻZ࿆] 本文专栏: AI视频 | Runway 文章目录 &#x1f4af;前言&#x1f4af;仅图片生成视频方法一&#xff1a;通过Midjourney生成图片方法二&#xff1a;通过Runway预览生成图片注意点 &#x1f4af;图加文生成视频方式一&#xff1a;Midjourney…

中年被裁,记录下这段时间的心路历程,内含前端面试题和面经

前言 真正的转变都是痛苦且无声的。 大家好啊&#xff0c;好久不见&#xff0c;停更了一个月了&#xff0c;最近确实没时间更新我的公益服游戏&#xff0c;这段时间我经历了工作被裁员&#xff0c;学习复习&#xff0c;面试找工作&#xff0c;到最终找到工作。想把这段时间我的…

为什么 ECB 模式不安全

我们先来简单了解下 ECB 模式是如何工作的 ECB 模式不涉及链接模式&#xff0c;所以也就用不着初始化向量&#xff0c;那么相同的明文分组就会被加密成相同的密文分组&#xff0c;而且每个分组运算都是独立的&#xff0c;这也就意味着可以并行提高运算效率&#xff0c;但也正是…

电脑ip地址怎么换地区:操作步骤与利弊分析

在当今全球化的信息时代&#xff0c;人们经常需要访问不同地区的网络资源。然而&#xff0c;由于地理位置的限制&#xff0c;某些内容或服务可能只对特定地区的用户开放。这时&#xff0c;更换电脑IP地址的地区就成为了一个实用的解决方案。本文将详细介绍两种更换电脑IP地址地…

WebRTC关键技术及应用场景:EasyCVR视频汇聚平台高效低延迟视频监控解决方案

众所周知&#xff0c;WebRTC是一项开源的实时通信技术&#xff0c;它通过集成音频、视频和数据传输到Web浏览器中&#xff0c;使得实时通信变得简单且无需任何插件或第三方软件。WebRTC不仅是一个API&#xff0c;也是一系列关键技术和协议的集合&#xff0c;它的出现改变了传统…

羽毛球场馆预约系统,便捷管理预约

全国羽毛球运动的热度不断上升&#xff0c;在健身行业中掀起了一股羽毛球热潮。同时羽毛球运动的风靡&#xff0c;也吸引了不少人入局&#xff0c;各种大大小小的羽毛球馆不断出现&#xff0c;为大众的羽毛球喜好提供了场地。 随着互联网的发展&#xff0c;羽毛球馆也开始向线…

共享单车轨迹数据分析:以厦门市共享单车数据为例(六)

副标题&#xff1a;.基于POI数据的站点功能混合度探究——以厦门市为例 为了保证数据时间尺度上的一致性&#xff0c;我们从互联网上下载了2020年的POI数据&#xff0c;POI数据来源于高德地图 API平台,包括名称、大小类、地理坐标等。并将高德地图 POI数据的火星坐标 系 GCJ-0…

idea 创建多模块项目

一、新建项目&#xff0c;创建父工程 新建项目&#xff0c;选择 spring initializr 填写相关信息后提交 删除不相关的目录&#xff0c;如下 修改打包方式为 pom&#xff0c;在 pom.xml 文件中新增一行&#xff0c;如下 二、创建子模块 新增子模块 填写子模块信息&#x…

《机器学习》周志华-CH8(集成学习)

8.1个体与集成 集成学习(ensemble learning)通过构建并结合多个学习器来完成学习任务&#xff0c;有时也被称为多分类器系统&#xff0c;基于委员会的学习。 同质”集成“&#xff1a;只包含同种类型的个体学习器&#xff0c;同质集成中的个体学习器亦称“基学习器”&#xff0…

C# winforms 使用菜单和右键菜单

初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github&#xff1a;codetoys&#xff0c;所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的&#xff0c;可以在任何平台上使用。 源码指引&#xff1a;github源…

累加求和-C语言

1.问题&#xff1a; 计算123……100的和&#xff0c;要求分别用while、do while、for循环实现。 2.解答&#xff1a; 累加问题&#xff0c;先后将100个数相加。要重复进行100次加法运算&#xff0c;可以用循环结构来实现。重复执行循环体100次&#xff0c;每次加一个数。 3.代…

【C++掌中宝】C++ 中的空指针救世主——nullptr

文章目录 1. 什么是 NULL&#xff1f;2. NULL 在 C 和 C 中的区别3. C11 引入 nullptr 的原因4. nullptr 与 NULL 的区别5. nullptr 的应用场景6. 模拟 nullptr 的实现7. 总结结语 1. 什么是 NULL&#xff1f; 在 C 和 C 编程中&#xff0c;NULL 常用于表示空指针&#xff0c;…

如何修改音频的音量增益

一、前言 在开发音频相关的功能&#xff08;比如说语音通话、播放音乐&#xff09;时&#xff0c;经常会遇到音量太小的问题&#xff0c;这时候就需要我们对原始数据进行处理。本文将介绍如何通过修改原始音频数据来增加增益&#xff0c;本文包含如下内容&#xff1a; 1.音频数…

【Java】虚拟机(JVM)内存模型全解析

目录 一、运行时数据区域划分 版本的差异&#xff1a; 二、程序计数器 程序计数器主要作用 三、Java虚拟机 1. 虚拟机运行原理 2. 活动栈被弹出的方式 3. 虚拟机栈可能产生的错误 4. 虚拟机栈的大小 四、本地方法栈 五、堆 1. 堆区的组成&#xff1a;新生代老生代 …

速通LLaMA3:《The Llama 3 Herd of Models》全文解读

文章目录 概览论文开篇IntroductionGeneral OverviewPre-TrainingPre-Training DataModel ArchitectureInfrastructure, Scaling, and EfficiencyTraining Recipe Post-TrainingResultsVision ExperimentsSpeech Experiments⭐Related WorkConclusionLlama 3 模型中的数学原理1…

目标检测系列(一)什么是目标检测

目录 一、相关名词解释 二、目标检测算法 三、目标检测模型 四、目标检测应用 五、目标检测数据集 六、目标检测常用标注工具 一、相关名词解释 关于图像识别的计算机视觉四大类任务&#xff1a; 分类&#xff08;Classification&#xff09;&#xff1a;解决“是什么&…

【LLM开源项目】LLMs-微调框架-LLaMA-Factory入门指南v3.0

【#】SFT 训练 项目地址&#xff1a;https://llamafactory.readthedocs.io/zh-cn/latest/getting_started/sft.html 可以使用以下命令进行微调&#xff1a; llamafactory-cli train examples/train_lora/llama3_lora_sft.yamlexamples/train_lora/llama3_lora_sft.yaml 提供…