榜单持久化
榜单持久化的基本流程是这样的:
-
创建表
-
持久化Redis数据到数据库
-
清理Redis数据
现在,创建表的动作已经完成,接下来就轮到Redis数据的持久化了。持久化的步骤如下:
-
读取Redis数据
-
判断数据是否存在
-
不存在,直接结束
-
存在,则继续
-
-
保存数据到数据库
不过,Redis的数据结构如图:
其KEY中包含一个上赛季对应的日期,因此要读取Redis数据,我们必须先得到上赛季的日期。
另外,我们采用了水平分表的策略,每一个赛季都是一个独立表。那么在写数据到数据库时,必须先知道表名称。
综上,最终持久化的业务流程如图:
动态表名
持久化的流程中存在一个问题,我们的数据库持久化采用的是MybatisPlus来实现的。而MybatisPlus读取表名的方式是通过实体类上的@Table
注解,而注解往往是写死的:
那我们该如何让MybatisPlus在执行的时候改变数据写入的表名称呢?
MybatisPlus中提供了一个动态表名的插件:
https://baomidou.com/pages/2a45ff/#dynamictablenameinnerinterceptor
插件的部分源码如下:
可见表名称动态获取就是依赖于tableNameHandlerMapping中的具体的TableNameHandler,这个Map如图:
这个Map的key是旧的表名称,value是TableNameHandler,就是表的名称处理器,用于根据旧名称获取新名称。
TableNameHandler的源码如下:
public interface TableNameHandler {/*** 生成动态表名** @param sql 当前执行 SQL* @param tableName 表名* @return String*/String dynamicTableName(String sql, String tableName);
}
OK,因此我们要做的事情就很简单了,定义DynamicTableNameInnterInterceptor
,向其中添加一个TableNameHandler
,将points_board
这个表名,替换为points_board_赛季id
的名称。
不过,新的问题来了,这个插件中的TableNameHandler该如何获取赛季对应的表名称呢?
计算表名的方式是获取获取上赛季时间,查询数据库中上赛季信息,得到上赛季id。然后拼接得到表名。
当我们批量的写数据到数据库时,如果每次插入都计算一次表名,那性能也太差了。因此,我们肯定是希望一次计算,在TableNameHandler中可以随时获取。
那么该如何实现呢?
2.4.1.2.传递表名
一旦我们计算完表名,以某种方式传递给插件中的TableNameHandler,那么就无需重复计算表名了。
不过,问题来了:要知道动态表名称插件,以及TableNameHandler,都是由MybatisPlus内部调用的。我们无法传递参数。
那么该如何传递表名称呢?
虽然无法传参,但是从计算表名,到动态表名插件执行,调用TableNameHandler,都是在一个线程内完成的。要在一个线程内实现数据共享,该用什么呢?
大家应该很容易想到,就是ThreadLocal.
我们可以在定时任务中计算完动态表名后,将表名存入ThreadLocal,然后在插件中从ThreadLocal中读取即可:
我们在tj-learning
的com.tianji.learning.utils
包下定义一个传递表名称的工具:
package com.tianji.learning.utils;public class TableInfoContext {private static final ThreadLocal<String> TL = new ThreadLocal<>();public static void setInfo(String info) {TL.set(info);}public static String getInfo() {return TL.get();}public static void remove() {TL.remove();}
}
然后在tj-learning
模块下定义一个配置类,用于定义DynamicTableNameInnterInterceptor
插件:
package com.tianji.learning.config;import com.baomidou.mybatisplus.extension.plugins.handler.TableNameHandler;
import com.baomidou.mybatisplus.extension.plugins.inner.DynamicTableNameInnerInterceptor;
import com.tianji.learning.utils.TableInfoContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import java.util.HashMap;
import java.util.Map;@Configuration
public class MybatisConfiguration {@Beanpublic DynamicTableNameInnerInterceptor dynamicTableNameInnerInterceptor() {// 准备一个Map,用于存储TableNameHandlerMap<String, TableNameHandler> map = new HashMap<>(1);// 存入一个TableNameHandler,用来替换points_board表名称// 替换方式,就是从TableInfoContext中读取保存好的动态表名map.put("points_board", (sql, tableName) -> TableInfoContext.getInfo() == null ? tableName : TableInfoContext.getInfo());return new DynamicTableNameInnerInterceptor(map);}
}
插件虽然定义好了,但是该如何继承到MybatisPlus中呢?
在天机学堂项目中的tj-common模块中,已经实现了MybatisPlus的自动装配,并且定义了很多的MP插件。如果我们在自己的项目中重新定义MP配置,就会导致tj-common中的插件失效。
所以,我们应该修改tj-common
中的MP配置,将DynamicTableNameInnerInterceptor
配置进去。找到tj-common
模块下的MybatisConfig
配置:
动态表名已经准备就绪,接下来我们就可以去定义定时任务,实现榜单持久化了。
在tj-learning
模块的com.tianji.learning.handler.PointsBoardPersistentHandler
中添加一个定时任务:
@XxlJob("savePointsBoard2DB")
public void savePointsBoard2DB(){// 1.获取上月时间LocalDateTime time = LocalDateTime.now().minusMonths(1);// 2.计算动态表名// 2.1.查询赛季信息Integer season = seasonService.querySeasonByTime(time);// 2.2.将表名存入ThreadLocalTableInfoContext.setInfo(POINTS_BOARD_TABLE_PREFIX + season);// 3.查询榜单数据// 3.1.拼接KEYString key = RedisConstants.POINTS_BOARD_KEY_PREFIX + time.format(DateUtils.POINTS_BOARD_SUFFIX_FORMATTER);// 3.2.查询数据int pageNo = 1;int pageSize = 1000;while (true) {List<PointsBoard> boardList = pointsBoardService.queryCurrentBoardList(key, pageNo, pageSize);if (CollUtils.isEmpty(boardList)) {break;}// 4.持久化到数据库// 4.1.把排名信息写入idboardList.forEach(b -> {b.setId(b.getRank().longValue());b.setRank(null);});// 4.2.持久化pointsBoardService.saveBatch(boardList);// 5.翻页pageNo++;}// 任务结束,移除动态表名TableInfoContext.remove();
}
XXL-JOB任务分片
刚才定义的定时持久化任务,通过while死循环,不停的查询数据,直到把所有数据都持久化为止。这样如果数据量达到数百万,交给一个任务执行器来处理会耗费非常多时间。
因此,将来肯定会将学习服务多实例部署,这样就会有多个执行器并行执行。但是,如果交给多个任务执行器,大家执行相同代码,都从第1页逐页处理数据,又会出现重复处理的情况。
怎么办?
这就要用到任务分片的方案了。
怎样才能确保任务不重复呢?我们可以参考扑克牌发牌的原理:
要想知道每一个执行器执行哪些页数据,只要弄清楚两个关键参数即可:
因此,现在的关键就是获取两个数据:
-
逐一给每个人发牌
-
发完一圈后,再回头给第一个人发
-
重复上述动作,直到牌发完为止
最终,每个执行器处理的数据页情况:
-
执行器1:处理第1、4、7、10、13、...页数据
-
执行器2:处理第2、5、8、11、14、...页数据
-
执行器3:处理第3、6、9、12、15、...页数据
-
起始页码:pageNo
-
下一页的跨度:step
-
起始页码:执行器编号是多少,起始页码就是多少
-
页跨度:执行器有几个,跨度就是多少。也就是说你要跳过别人读取过的页码
-
执行器编号
-
执行器数量
@XxlJob("savePointsBoard2DB") public void savePointsBoard2DB(){// 1.获取上月时间LocalDateTime time = LocalDateTime.now().minusMonths(1);// 2.计算动态表名// 2.1.查询赛季信息Integer season = seasonService.querySeasonByTime(time);// 2.2.存入ThreadLocalTableInfoContext.setInfo(POINTS_BOARD_TABLE_PREFIX + season);// 3.查询榜单数据// 3.1.拼接KEYString key = RedisConstants.POINTS_BOARD_KEY_PREFIX + time.format(DateUtils.POINTS_BOARD_SUFFIX_FORMATTER);// 3.2.查询数据int index = XxlJobHelper.getShardIndex();int total = XxlJobHelper.getShardTotal();int pageNo = index + 1; // 起始页,就是分片序号+1int pageSize = 10;while (true) {List<PointsBoard> boardList = pointsBoardService.queryCurrentBoardList(key, pageNo, pageSize);if (CollUtils.isEmpty(boardList)) {break;}// 4.持久化到数据库// 4.1.把排名信息写入idboardList.forEach(b -> {b.setId(b.getRank().longValue());b.setRank(null);});// 4.2.持久化pointsBoardService.saveBatch(boardList);// 5.翻页,跳过N个页,N就是分片数量pageNo+=total;}TableInfoContext.remove(); }
清理Redis缓存任务
当任务持久化以后,我们还要清理Redis中的上赛季的榜单数据,避免过多的内存占用。
在
tj-learning
模块的com.tianji.learning.handler.PointsBoardPersistentHandler
中添加一个定时任务:package com.tianji.learning.handler;import com.tianji.common.utils.CollUtils; import com.tianji.common.utils.DateUtils; import com.tianji.learning.constants.RedisConstants; import com.tianji.learning.domain.po.PointsBoard; import com.tianji.learning.service.IPointsBoardSeasonService; import com.tianji.learning.service.IPointsBoardService; import com.tianji.learning.utils.TableInfoContext; import com.xxl.job.core.context.XxlJobHelper; import com.xxl.job.core.handler.annotation.XxlJob; import lombok.RequiredArgsConstructor; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Component;import java.time.LocalDateTime; import java.util.List;import static com.tianji.learning.constants.LearningConstants.POINTS_BOARD_TABLE_PREFIX;@Component @RequiredArgsConstructor public class PointsBoardPersistentHandler {private final IPointsBoardSeasonService seasonService;private final IPointsBoardService pointsBoardService;private final StringRedisTemplate redisTemplate;// ... 略@XxlJob("clearPointsBoardFromRedis")public void clearPointsBoardFromRedis(){// 1.获取上月时间LocalDateTime time = LocalDateTime.now().minusMonths(1);// 2.计算keyString key = RedisConstants.POINTS_BOARD_KEY_PREFIX + time.format(DateUtils.POINTS_BOARD_SUFFIX_FORMATTER);// 3.删除redisTemplate.unlink(key);} }
任务链
现在,所有任务都已经定义完毕。接下来就给配置任务调度了。
我们最终期望的任务执行顺序是这样的
要想让任务A、B依次执行,其实就是配置任务B作为任务A的子任务。因此,我们按照下面方式配置:
-
创建历史榜单表(10)的子任务是持久化榜单数据任务(12)
-
持久化榜单数据任务(12)的子任务是清理Redis中的历史榜单(13)
也就是说:10的子任务是12, 12的子任务是13
相关文章:
榜单持久化
榜单持久化的基本流程是这样的: 创建表 持久化Redis数据到数据库 清理Redis数据 现在,创建表的动作已经完成,接下来就轮到Redis数据的持久化了。持久化的步骤如下: 读取Redis数据 判断数据是否存在 不存在,直接结束…...
璞华ChatBI闪耀2025数博会:对话式数据分析引领数智化转型新范式
4月17日至19日,2025中国(武汉)数字经济产业博览会在武汉盛大举办,璞华集团携自主研发的“ChatBI自然语言问答式数据分析平台”惊艳亮相。以 "通过对话让数据说话" 为主题,璞华集团在 A3-T8 展位构建了沉浸式…...
力扣DAY63-67 | 热100 | 二分:搜索插入位置、搜索二维矩阵、排序数组查找元素、搜索旋转排序数组、搜索最小值
前言 简单、中等 √ 二分法思路很简单,但是判断边界太麻烦了!难道真的要去背模板吗 搜索插入位置 我的题解 循环条件左不超过右,目标大于中间值(向下取整)时,左中1,小于,右中-1&…...
leetcode-哈希表
哈希表 127. 单词接龙 题目 字典 wordList 中从单词 beginWord 到 endWord 的 转换序列 是一个按下述规格形成的序列 beginWord -> s(1) -> s(2) -> ... -> s(k): 每一对相邻的单词只差一个字母。 对于 1 < i < k 时,每个 s(i) 都在…...
信息技术有限公司项目管理手册
这篇文档是信息技术有限公司的项目管理指导手册,对软件公司项目管理者具有重要价值,主要体现在以下几个方面: 管理全面规范 涵盖内容广:从项目的整体管理到各个具体领域,如范围管理、进度管理、成本管理等&…...
TFTP服务调试
在tftpboot目录下进行sudo minicom 启动内核时 问题:程序启动卡在Loading阶段 原因:tftp协议的问题 、或者网卡配置的问题 解决:1.检查网线是否插好 多试几次 2.检查tftp服务是否正常 在minicom中调试ping pc机的ip地址 2.进入boot调…...
date-picker组件的shortcuts为什么不能配置在vue的data的return中
在 Vue 中,shortcuts 是一个选项,通常用于配置像 date-picker 这样的组件的日期快捷方式。这里有一些原因解释为什么 shortcuts 不应该配置在 data 的 return 中,而是应该配置在 data 的外部(例如,直接作为组件的一个属…...
迭代器模式:统一数据遍历方式的设计模式
迭代器模式:统一数据遍历方式的设计模式 一、模式核心:将数据遍历逻辑与数据结构解耦 在软件开发中,不同的数据结构(如数组、链表、集合)有不同的遍历方式。如果客户端直接依赖这些数据结构的内部实现来遍历元素&…...
RocketMQ 核心架构速览
欢迎光临小站:致橡树 文章现有讲述比较简单,后续逐渐丰富各部分内容。 Apache RocketMQ 作为阿里巴巴开源的一款分布式消息中间件,凭借其高吞吐、低延迟、高可用等特性,成为金融级稳定性场景的首选解决方案。本文将深入剖析 Roc…...
kafka安装、spark安装
kafka简介 Kafka就是一个分布式的用于消息存储的消息队列。 kafka角色 Kafka中存储的消息,被消费后不会被删除,可以被重复消费,消息会保留多长,由kafka自己去配置。默认7天删除。背后的管理工作由zookeeper来管理。 kafka安装 …...
迅为RK3562开发板ARM四核A53核心板多种系统适配全开源
迅为RK3562开发板ARM四核A53核心板多种系统适配全开源 RK3562开发板(2GB内存16GB存储)...
用交换机连接两台电脑,电脑A读取/写电脑B的数据
1、第一步,打开控制面板中的网络和共享中心,如下图配置,电脑A和电脑B均要配置; 注意:要保证电脑A和电脑B在同一子网掩码下,不同的IP地址; 2、在电脑上同时按‘CommandR’,在弹出的输…...
线程入门3
synchronized修饰方法 synchronized可以修饰代码块(在线程入门2中有例子),也可以修饰普通方法和静态方法。 修饰普通方法 修饰普通方法简化写法: 修饰静态方法 修饰静态方法简化写法: 注意:利用synchronized上锁,锁的…...
【C++】AVL树
目录 一、AVL树的引入 二、AVL树 🍔AVL树的概念 🍟AVL树节点的定义 🌮AVL树的插入 🥪AVL树的旋转 三、AVL树的验证 四、结语 一、AVL树的引入 🌟我们知道 map/multimap/set/multiset 这几个容器的共同点是&#…...
Java大师成长计划之第1天:Java编程基础入门
📢 友情提示: 本文由银河易创AI(https://ai.eaigx.com)平台gpt-4o-mini模型辅助创作完成,旨在提供灵感参考与技术分享,文中关键数据、代码与结论建议通过官方渠道验证。 欢迎来到“Java大师成长计划”系列文…...
Java线程中断机制详解
中断机制是Java中一种协作式的线程停止方式,它提供了一种优雅的线程间通信机制,用于请求另一个线程停止当前工作。 中断机制的核心概念 中断标志位(Interrupt Status) 每个线程都有一个boolean类型的中断状态标志(native方法控制)…...
gem5-gpu教程06 回归测试
gem5-gpu包括gem5风格的回归测试,以避免常见错误,并在变更集之间保持模拟系统性能的一致性。如果你想为gem5-gpu做出贡献,你必须确保你的更改通过了包含的回归测试。 回归测试是一种软件测试类型,其主要目的是确保新代码的更改没有对现有功能造成影响。在软件开发过程中,当…...
查询Hologres或postgresql中的数据
因Hologres使用postgresql的语法.所以两者查询一样. 方案1: import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.util.ArrayList; import java.util.List;/*** 一个使用简单连接池管理PostgreSQL连接的工具类。*/ publi…...
C# 文件读取
文件读取是指使用 C# 程序从计算机文件系统中获取文件内容的过程。将存储在磁盘上的文件内容加载到内存中,供程序处理。主要类型有:文本文件读取(如 .txt, .csv, .json, .xml);二进制文件读取(如 .jpg, .pn…...
On the Biology of a Large Language Model——Claude团队的模型理解文章【论文阅读笔记】其一CLT与LLM知识推理
这个学习笔记,是在精读Anthropic的博客 On the Biology of a Large Language Model 的过程中留下的笔记。 由于原文非常长,我会分2-3 个博客来写。 作者的思路 作者对常用的LLM特征解读工具 SAE/Transcoder 进行了优化,增加了跨层连接的能力…...
Postman忘记密码访问官网总是无响应
1.Header Editor插件下载 百度网盘下载: 链接:https://pan.baidu.com/s/1EV6cY7TYQVgPjip3v-vhfQ 提取码:yyds 2.插件配置 下载规则url:https://azurezeng.github.io/static/HE-GoogleRedirect.json 、U(向上)、L(向左)和 R(向右)组成的 48 字符描…...
深度学习中的黑暗角落:梯度消失与梯度爆炸问题解析
📌 友情提示: 本文内容由银河易创AI(https://ai.eaigx.com)创作平台的gpt-4o-mini模型生成,旨在提供技术参考与灵感启发。文中观点或代码示例需结合实际情况验证,建议读者通过官方文档或实践进一步确认其准…...
【数字图像处理】机器视觉(1)
判别相对应的点 1. 图像灰度化 2. 局部特征 3. 仿射不变性特征 图像变化的类型 【1】几何变化:旋转、相似(旋转 各向相同的尺度缩放)、仿射(非各向相同的尺度缩放) 【2】灰度变化:仿射灰度变化 角点 角…...
# 构建和训练一个简单的CBOW词嵌入模型
构建和训练一个简单的CBOW词嵌入模型 在自然语言处理(NLP)领域,词嵌入是一种将词汇映射到连续向量空间的技术,这些向量能够捕捉词汇之间的语义关系。在这篇文章中,我们将构建和训练一个简单的Continuous Bag of Words…...
Ubuntu20.04下GraspNet复现流程中的问题
pytorchcudacudnn的版本问题相对于GraspNet来说至关重要!!!至关重要!!!至关重要!!!(重要的事情说三边) 我的显卡是3070 那么首先说结论 使用30系…...
【ROS2】机器人操作系统安装到Ubuntu简介
主要参考: https://book.guyuehome.com/ROS2/1.系统架构/1.3_ROS2安装方法/ 官方文档:https://docs.ros.org/en/humble/Installation.html 虚拟机与ubuntu系统安装 略,见参考文档 ubutun换国内源,略 1. 设置本地语言 确保您有…...
从0到1掌握机器学习核心概念:用Python亲手构建你的第一个AI模型(超多代码+可视化)
🧠 一、开始 真正动手实现一个完整的AI项目!从数据预处理、特征工程、模型训练,到评估与调优,一步步还原你在动画视频中看到的所有核心知识点。 📦 二、环境准备 建议使用 Python 3.8,推荐工具࿱…...
Java面试题汇总
1王二哥 https://javabetter.cn/sidebar/sanfene/redis.html#_10-redis-%E6%8C%81%E4%B9%85%E5%8C%96%E6%96%B9%E5%BC%8F%E6%9C%89%E5%93%AA%E4%BA%9B-%E6%9C%89%E4%BB%80%E4%B9%88%E5%8C%BA%E5%88%AB 2.小林 https://www.xiaolincoding.com/redis/data_struct/command.html#…...
Ollama API 应用指南
1. 基础信息 默认地址: http://localhost:11434/api数据格式: application/json支持方法: POST(主要)、GET(部分接口) 2. 模型管理 API (1) 列出本地模型 端点: GET /api/tags功能: 获取已下载的模型列表。示例:curl http://lo…...
React SSR + Redux 导致的 Hydration 报错踩坑记录与修复方案
一条“Hydration failed”的错误,让我损失了半天时间 背景 我在用 Next.js App Router Redux 开发一个任务管理应用,一切顺利,直到打开了 SSR(服务端渲染),突然看到这个令人头皮发麻的报错: …...
【论文精读】Reformer:高效Transformer如何突破长序列处理瓶颈?
目录 一、引言:当Transformer遇到长序列瓶颈二、核心技术解析:从暴力计算到智能优化1. 局部敏感哈希注意力(LSH Attention):用“聚类筛选”替代“全量计算”关键步骤:数学优化: 2. 可逆残差网络…...
iOS18 MSSBrowse闪退
iOS18 MSSBrowse闪退 问题方案结果 问题 最近升级了电脑系统(15.4.1),并且也升级了xcode(16.3)开发工具。之后打包公司很早之前开发的项目。 上线之后发现在苹果手机系统18以上,出现了闪退问题。 涉及到的是第三方MSSBrowse,在选择图片放大的…...
create_function()漏洞利用
什么是 create_function() create_function() 是 PHP 早期提供的一个用来创建匿名函数的函数: $func create_function($a,$b, return $a $b;); echo $func(1, 2); // 输出 3 第一个参数是函数的参数列表(字符串形式),第二个参…...
leetcode-数组
数组 31. 下一个排列 题目 整数数组的一个 排列 就是将其所有成员以序列或线性顺序排列。 例如,arr [1,2,3] ,以下这些都可以视作 arr 的排列:[1,2,3]、[1,3,2]、[3,1,2]、[2,3,1] 。 整数数组的 下一个排列 是指其整数的下一个字典序更大…...
Tailwind CSS 实战:基于 Kooboo 构建个人博客页面
在现代 web 开发中,Tailwind CSS 作为一款实用优先的 CSS 框架,能让开发者迅速搭建出具有良好视觉效果的页面;Kooboo 则是一个强大的快速开发平台,提供了便捷的页面管理和数据处理功能。本文将详细介绍如何结合 Tailwind CSS 和 K…...
C#学习1_认识项目/程序结构
一、C#项目文件的构成 1.新建一个项目 2.运行项目 3.认识文件 1)解决方案(Solution):组织多个项目的容器 抽象理解:餐厅 解决方案.sln文件,点击即可进入VS编辑 2)项目(…...
边缘计算在工业自动化中的应用:开启智能制造新时代
在工业4.0的浪潮中,智能制造成为推动工业发展的核心驱动力。随着物联网(IoT)技术的广泛应用,工业设备之间的互联互通变得越来越紧密,但这也带来了数据处理和传输的挑战。边缘计算作为一种新兴技术,通过将计…...
《MySQL:MySQL表的内外连接》
表的连接分为内连接和外连接。 内连接 内连接实际上就是利用where子句对两种表形成的笛卡尔积进行筛选,之前的文章中所用的查询都是内连接,也是开发中使用的最多的连接查询。 select 字段 from 表1 inner join 表2 on 连接条件 and 其他条件࿱…...
人工智能催化民航业变革:五大应用案例
航空业正在经历一场前所未有的技术革命,人工智能正成为变革的主要催化剂。从停机坪到航站楼,从维修机库到客户服务中心,人工智能正在从根本上重塑航空公司的运营和服务方式。这种转变并非仅仅停留在理论上——全球主要航空公司已从人工智能投…...
机器视觉中有哪些常见的光学辅助元件及其作用?
在机器视觉领域,光学元件如透镜、反射镜和棱镜扮演着至关重要的角色。它们不仅是高精度图像捕获的基础,也是提升机器视觉系统性能的关键。深入了解这些光学元件的功能和应用,可以帮助我们更好地掌握机器视觉技术的精髓。 透镜:精…...
Stream API 对两个 List 进行去重操作
在 Java 8 及以上版本中,可以使用 Lambda 表达式和 Stream API 对两个 List 进行去重操作。以下是几种常见的去重场景及对应的 Lambda 表达式实现方式: 1. 合并两个 List 并去重 List<String> list1 Arrays.asList("A", "B"…...
lerna 8.x 详细教程
全局安装 lerna npm install lerna -g初始化项目 mkdir lerna-cli-do cd lerna-cli-do npm init -y初始化项目 lerna init --packages="packages/*"lerna create 创建子项目 lerna create core lerna create util...
ROS第十二梯:ros-noetic和Anaconda联合使用
1) 概述 ros-noetic默认Python版本是Python2.7,但在使用过程中,通常需要明确调用python3进行编译。 Anaconda: 支持创建独立的python2/3环境,避免系统库冲突; 方便安装ROS依赖的科学计算库(如Numpy,Pandas)和机器学习框架; 核心目标:在anaconda环…...
网络原理 - 5(TCP - 2 - 三次握手与四次挥手)
目录 3. 连接管理 建立连接 - 三次挥手 三次握手的意义 断开连接 - 四次挥手 握手和挥手的相似和不同之处 连接管理过程中涉及到的 TCP 状态转换 完! 3. 连接管理 连接管理分为建立连接 和 断开连接~(important 重点!) 建…...
【开源】STM32HAL库移植Arduino OneWire库驱动DS18B20和MAX31850
项目开源链接 github主页https://github.com/snqx-lqh本项目github地址https://github.com/snqx-lqh/STM32F103C8T6HalDemo作者 VXQinghua-Li7 📖 欢迎交流 如果开源的代码对你有帮助,希望可以帮我点个赞👍和收藏 项目说明 最近在做一个项目…...
【maven-7.1】POM文件中的属性管理:提升构建灵活性与可维护性
在Maven项目中,POM (Project Object Model) 文件是核心配置文件,而属性管理则是POM中一个强大但常被低估的特性。良好的属性管理可以显著提升项目的可维护性、减少重复配置,并使构建过程更加灵活。本文将深入探讨Maven中的属性管理机制。 1.…...
DC-2寻找Flag1、2、3、4、5,wpscan爆破、git提权
一、信息收集 1、主机探测 arp-scan -l 探测同网段2、端口扫描 nmap -sS -sV 192.168.66.136 80/tcp open http Apache httpd 2.4.10 ((Debian)) 7744/tcp open ssh OpenSSH 6.7p1 Debian 5deb8u7 (protocol 2.0)这里是扫描出来两个端口,80和ssh&…...
数据结构手撕--【栈和队列】
目录 1、栈 2、队列 1、栈 先进后出(都在栈顶进行操作) 使用数组结构比使用链式结构更优,因为数组在尾上插入数据的代价更小。并且采用动态长度的数组来表示。 定义结构体 #include <stdio.h> #include <stdlib.h> #include &l…...
八大排序——选择排序/堆排序
八大排序——选择排序/堆排序 目录 一、选择排序 二、堆排序 2.1 大顶堆(升序) 2.1.1 步骤 2.1.2 代码实现 2.2 小顶堆(降序) 一、选择排序 每一趟从待排序序列中找到其最小值,然后和待排序序列的第一个值进行交换&am…...