DataX实战:从MongoDB到MySQL的数据迁移--修改源码并测试打包
在现代数据驱动的业务环境中,数据迁移和集成是常见的需求。DataX,作为阿里云开源的数据集成工具,提供了强大的数据同步能力,支持多种数据源和目标端。本文将介绍如何使用DataX将数据从MongoDB迁移到MySQL。
环境准备
-
安装MongoDB:首先,我们需要安装MongoDB。通过创建repo文件并配置yum源,我们可以轻松地通过yum安装MongoDB。此外,还需要修改MongoDB的配置文件以允许远程连接,并启动MongoDB服务。
-
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数据到MySQL。通过编写适当的JSON配置文件,我们可以灵活地处理各种复杂的数据迁移任务。这不仅提高了DataX的可用性,也为我们的数据同步工作提供了更多的可能。
相关文章:

DataX实战:从MongoDB到MySQL的数据迁移--修改源码并测试打包
在现代数据驱动的业务环境中,数据迁移和集成是常见的需求。DataX,作为阿里云开源的数据集成工具,提供了强大的数据同步能力,支持多种数据源和目标端。本文将介绍如何使用DataX将数据从MongoDB迁移到MySQL。 环境准备 安装MongoDB…...

Axure设计之表格列冻结(动态面板+中继器)
在Web端产品设计中,复杂的表格展示是常见需求,尤其当表格包含大量列时,如何在有限的屏幕空间内优雅地展示所有信息成为了一个挑战。用户通常需要滚动查看隐藏列,但关键信息列(如ID、操作按钮等)在滚动时保持…...

WPF DataGrid 动态修改某一个单元格的样式
WPF DataGrid 动态修改某一个单元格的样式 <DataGrid Name"main_datagrid_display" Width"1267" Height"193" Grid.Column"1"ItemsSource"{Binding DataGridModels}"><DataGrid.Columns><!--ElementStyle 设…...
如何安装部署kafka
安装和部署Apache Kafka需要以下几个步骤,包括下载 Kafka、配置 ZooKeeper(或者使用 Kafka 自带的 Kafka Raft 模式替代 ZooKeeper),以及启动 Kafka 服务。以下是一个但基于 Linux 的典型安装流程,可以根据需要改装到其…...

Centos7-rpm包管理器方式安装MySQL 5.7.25
前言 本文用于学习通过Mysql压缩包在centos7中安装和配置的过程以及过程中碰到的Bug解决。 Mysql安装包下载和上传 MySQL :: Download MySQL Community Server (Archived Versions)https://downloads.mysql.com/archives/community/访问Mysql官方下载站,选择对应的…...
Project Online 协作版部署方案
目录 前言 第一部分:为什么选择Project Online? 一、核心优势 二、适用场景 第二部分:部署前的准备工作 一、需求分析 二、账户和权限管理 三、培训与支持 第三部分:Project Online 的核心功能 一、项目创建与管理 二、资源管理 三、团队协作 四、风险管理 五…...

小米 13 Ultra机型工程固件 资源预览与刷写说明 步骤解析
小米 13 Ultra机型---机型代码为ishtar 。工程固件可以辅助修复格机或者全檫除分区后的基带修复。可以用于修复TEE损坏。以及一些分区的底层修复。此款固件也可以为更换UFS后的底包。 通过博文了解 1💝💝💝-----此机型工程固件的资源刷写注意事项 2💝💝💝-----此…...
Goweb预防XSS攻击
XSS攻击示例 假设您有一个简单的Web应用程序,其中包含一个用户输入表单,用户可以在其中输入他们的名字,然后这个名字会被显示在页面上。攻击者可以在表单中输入恶意的JavaScript代码,如,如果应用程序没有对这个输入进…...
ICM20948 DMP代码详解(36)
接前一篇文章:ICM20948 DMP代码详解(35) 上一回讲到了icm20948_sensor_setup() ---> inv_icm20948_initialize_auxiliary函数 ---> inv_icm20948_set_slave_compass_id函数,本回开始,就对于inv_icm20948_set_sla…...
【框架】Spring、SpringBoot和SpringCloud区别
Spring Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器(框架) IoC(Inversion of Control,控制反转)是一种设计思想,它主要用于降低软件系统中不同模块之间的耦合度,提高代码的可维护…...
计算机网络各层有哪些协议?
计算机网络的各层协议知识总结 一、物理层 没有涉及到比较重要的协议,但是有一个比较重要的技术----非对称数字用户线(ADSL) 二、数据链路层 1、点对点协议(PPP----point to point protocol,用户计算机与ISP进行通信…...

Diffusion Model Stable Diffusion(笔记)
参考资料: 文章目录 DDPM架构模型如何拥有产生逼真图片的能力Denoise模型功能Denoise模型如何训练考虑进文字 文生图流程(Stable Diffusion) DDPM架构 模型如何拥有产生逼真图片的能力 Denoise模型功能 通过Denoise将一个噪音图一步步生成为目标图像 Denoise实际…...
如何创建模板提示prompt
定义模型 from langchain_ollama import ChatOllamallm ChatOllama(base_url"http://ip:11434",model"qwen2",temperature0,tool_choice"auto" )什么是提示模板? 它的目的是根据不同的输入动态生成特定格式的文本,以便…...

C语言 | Leetcode C语言题解之第423题从英文中重建数字
题目: 题解: char * originalDigits(char * s) {int lenstrlen(s);int arr[26]{0},num[10]{0},cot0;for(int i 0; i < len; i)arr[s[i] - a];num[0] arr[z-a];num[2] arr[w-a];num[4] arr[u-a];num[6] arr[x-a];num[8] arr[g-a];num[1] arr[o…...

Jboss CVE-2017-12149 靶场攻略
漏洞简述 该漏洞为 Java反序列化错误类型,存在于 Jboss 的 HttpInvoker 组件中的 ReadOnlyAccessFilter过滤器中。该过滤器在没有进⾏任何安全检查的情况下尝试将来⾃客户端的数据流进⾏反序列化,从⽽导 致了漏洞 漏洞范围 JBoss 5.x/6.x 环境搭建 …...
ROS2 中令人困惑的rclpy.shutdown()
在使用rclpy(Robot Operating System (ROS) 2的Python客户端库)时,rclpy.spin()和rclpy.shutdown()是两个非常重要的函数,它们各自承担着不同的角色。 rclpy.spin() rclpy.spin()函数通常被用于启动一个节点的主循环。在这个循环…...
PHP纯离线搭建(php 8.1.7)
要离线从零安装 PHP 8.1.7,需要准备好 PHP 的源代码以及所有相关的依赖包。以下是步骤: 步骤概览 在联网系统上下载 PHP 8.1.7 源代码和所有依赖包。 将这些文件传输到离线系统。 安装所需的依赖包。 编译并安装 PHP 8.1.7。 配置 PHP 和 Web 服务器。 …...
【iOS】push和pop、present和dismiss
目录 前言push和poppushpop present和dismisspresentdismiss实现模态对话框代码示例 区别总结 前言 push 和 present 是两种用于导航和切换视图控制器(ViewController)的常用方法,push与present都可以推出新的界面,present与dismi…...

基于51单片机的两路电压检测(ADC0808)
目录 一、主要功能 二、硬件资源 三、程序编程 四、实现现象 一、主要功能 基于51单片机,通过ADC0808获取两路电压,通过LCD1602显示 二、硬件资源 基于KEIL5编写C代码,PROTEUS8.15进行仿真,全部资源在页尾,提供…...

JavaScript ---案例(统计字符出现次数)
统计字符出现次数 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widthdevice-w…...
Symbol、Set 与 Map:新数据结构探秘
Symbol、Set 与 Map:新数据结构探秘 引言 ECMAScript 6 (ES6) 引入了三种强大的数据结构:Symbol、Set 与 Map,它们解决了 JavaScript 开发中的特定痛点,为我们提供了更多工具来处理复杂的数据操作。 Symbol:唯一标识…...

【航天远景 MapMatrix 精品教程】08 Pix4d空三成果导入MapMatrix
【航天远景 MapMatrix 精品教程】08 Pix4d空三成果导入MapMatrix 文章目录 【航天远景 MapMatrix 精品教程】08 Pix4d空三成果导入MapMatrix一、资料准备1.去畸变影像2.相机文件3.外方位元素二、创建工程1.新建工程2.导入照片3.编辑相机文件4.编辑外方位元素文件,导入外方位元…...

Kettle 远程mysql 表导入到 hadoop hive
kettle 远程mysql 表导入到 hadoop hive (教学用 ) 文章目录 kettle 远程mysql 表导入到 hadoop hive创建 对象 执行 SQL 语句 -mysql 导出 CSV格式CSV 文件远程上传到 HDFS运行 SSH 命令远程登录 run SSH 并执行 hadoop fs -put 建表和加载数据总结 创…...

mapbox高阶,PMTiles介绍,MBTiles、PMTiles对比,加载PMTiles文件
👨⚕️ 主页: gis分享者 👨⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨⚕️ 收录于专栏:mapbox 从入门到精通 文章目录 一、🍀前言1.1 ☘️mapboxgl.Map 地图对象1.2 ☘️mapboxgl.Map style属性1.3 ☘️Fill面图层样式1.4 ☘️PMTiles介绍1.5…...

[Protobuf] 快速上手:安全高效的序列化指南
标题:[Protobuf] (1)快速上手 水墨不写bug 文章目录 一、什么是protobuf?二、protobuf的特点三、使用protobuf的过程?1、定义消息格式(.proto文件)(1)指定语法版本(2)package 声明符 2、使用protoc编译器生成代码&…...
汽车售后诊断数据流详细分析
一、引言 随着汽车电子化程度的不断提升,电控系统已成为车辆运行的核心支撑。据罗兰贝格 2025 年智能汽车白皮书数据显示,中央计算 区域控制架构(Zonal EEA)的普及率已突破 58%,推动整车线束成本下降 41%12。与此同时…...
微信小程序页面嵌套web-view点击系统导航返回时进行弹窗处理
实现效果:微信小程序页面嵌套web-view点击系统导航返回时进行弹窗处理 首先在web-view里是不可实现的(据我了解下来) 参考小程序文档:page-container 大致逻辑: 1、page-container可实现页面离开前拦截 2、由于web-vie…...

王树森推荐系统公开课 排序06:粗排模型
shared bottom 表示神经网络被所有特征共享。精排模型主要开销在神经网络,神经网络很大且很复杂。 每做一次推荐,用户塔只做一次推理。物品塔存放入向量数据库。 后期融合模型常用于召回,前期融合模型常用于精排。 物品塔短时间内比较稳…...

【Node.js】部署与运维
个人主页:Guiat 归属专栏:node.js 文章目录 1. Node.js 部署概述1.1 部署的核心要素1.2 Node.js 部署架构全景 2. 传统服务器部署2.1 Linux 服务器环境准备系统更新与基础软件安装创建应用用户 2.2 应用部署脚本2.3 环境变量管理2.4 Nginx 反向代理配置2…...
Java面试实战:从Spring到大数据的全栈挑战
Java面试实战:从Spring到大数据的全栈挑战 在某家知名互联网大厂,严肃的面试官正在面试一位名叫谢飞机的程序员。谢飞机以其搞笑的回答和对Java技术栈的独特见解而闻名。 第一轮:Spring与微服务的探索 面试官:“请你谈谈Spring…...