一站式指导:在Neo4j与PostgreSQL间实现高效数据同步
作者:后端小肥肠
🍇 我写过的文章中的相关代码放到了gitee,地址:xfc-fdw-cloud: 公共解决方案
🍊 有疑问可私信或评论区联系我。
🥑 创作不易未经允许严禁转载。
姊妹篇:
数据同步的艺术:探索PostgreSQL和Redis的一致性策略_postgresql redis 同步-CSDN博客
【Neo4j系列】简化Neo4j数据库操作:一个基础工具类的开发之旅_neo4j js-CSDN博客【Neo4j系列】Neo4j概念简介及整合SpringBoot_neo4j springboot-CSDN博客
【Neo4j系列】Neo4j之CQL语句和函数介绍_neo4j cql-CSDN博客
目录
1. 引言
2. Neo4j与PostgreSQL的基础知识
2.1. Neo4j基本概念与架构
2.2. PostgreSQL基本概念与架构
2.3. 数据处理上的不同与互补
3. 数据同步方案设计
3.1. Neo4j与PostgresSQL对比说明
3.2. 数据同步技术方案设计
3.2.1 全量同步
3.2.2. 增量同步
4. 技术实现
4.1. PostgresSQL表结构设计
4.2. Neo4j 数据模型设计
4.3. 全量同步代码
4.4. 增量同步代码
5. 结论
1. 引言
在当今数字化时代,数据已成为企业的核心资产。随着业务的不断扩展和技术的快速发展,企业常常需要同时运用多种数据库系统来满足不同的业务需求。在这种背景下,Neo4j作为领先的图数据库,以其高效的关系数据处理能力而备受青睐;而PostgreSQL作为功能强大的关系型数据库,则以其稳定性和可扩展性而闻名。然而,如何在这两种截然不同的数据库系统之间实现高效、可靠的数据同步,成为了许多企业面临的一大挑战。
本文旨在为读者提供一个全面的指南,详细阐述如何在Neo4j和PostgreSQL之间构建高效的数据同步机制。我们将深入探讨数据同步的重要性,分析两种数据库系统的特点,并提供从策略设计到技术实现的完整解决方案。无论您是数据库管理员、系统架构师,还是对数据集成感兴趣的技术爱好者,本文都将为您提供宝贵的见解和实用的技巧。
通过阅读本文,您将了解到:
- PostgresSQL、Neo4j基本概念简介
- 如何设计一个既满足业务需求又技术可行的同步策略
- 实现数据同步的具体技术步骤和最佳实践
- 如何应对同步过程中可能遇到的挑战,并进行性能优化
让我们开始这段探索数据同步世界的旅程,一同揭示Neo4j和PostgreSQL协同工作的无限可能!
2. Neo4j与PostgreSQL的基础知识
2.1. Neo4j基本概念与架构
Neo4j 是一种高性能的图数据库,它使用图结构存储复杂的网络关系,以节点、关系和属性的形式存储和查询数据。Neo4j的主要特点包括:
- 图存储模型:相对于传统的关系数据库,Neo4j直接在图中存储实体之间的关系,能够快速通过关系遍历相关节点。
- Cypher查询语言:专为图数据设计的声明式语言,使得编写查询直观并易于理解。
- 强调关系:Neo4j认为关系是首要的,不仅仅是节点的附属品,这使得关系查询非常高效。
- ACID事务:支持全事务性的操作,保证数据的一致性和完整性。
2.2. PostgreSQL基本概念与架构
PostgreSQL 是一种功能强大的开源关系型数据库系统,以其稳定性、可扩展性和丰富的特性集而著名。其核心特点包括:
- SQL兼容:遵循SQL标准,支持复杂的查询和多种数据类型。
- 扩展性:支持自定义类型、函数和插件,用户可以根据需要扩展数据库功能。
- MVCC(多版本并发控制):提供高级别的并发性和性能,同时保持读写操作的一致性。
- 高可靠性:支持点对点复制和热备份,确保数据安全和高可用。
2.3. 数据处理上的不同与互补
Neo4j和PostgreSQL在数据处理上有本质的不同,这些差异为它们在特定应用场景中的互补提供了基础:
- 处理复杂关系:Neo4j在处理高度连接的数据和深层关系网络方面具有优势,适合社交网络分析、推荐系统等场景。而PostgreSQL在处理大规模的结构化数据和事务性要求高的应用中更为有效。
- 查询性能:对于深度连接查询和图遍历,Neo4j表现出色;而PostgreSQL在执行大规模聚合查询和多表连接时更具优势。
- 数据完整性与安全:PostgreSQL提供广泛的数据完整性和安全特性,这在需要严格数据验证和法规遵从的业务中非常重要。Neo4j也提供事务支持,但以不同方式实现。
通过理解这些基本概念和架构的不同,可以更好地设计出符合特定业务需求的数据同步策略,有效地利用两种数据库系统的优势。
3. 数据同步方案设计
3.1. Neo4j与PostgresSQL对比说明
在我们开始讨论如何同步Neo4j和PostgreSQL之间的数据之前,先来看看它们在数据模型上的异同。为了方便理解,我把两者对应的概念列成了一个表格:
关系型数据库(PostgresSQL) | Neo4j |
---|---|
表 | 图 |
行 | 节点 |
列 | 属性 |
约束 | 关系 |
这张表看起来很简单,但如果我们深入分析,每一行其实都揭示了两种数据库背后完全不同的思维方式。
1. 表 vs 图
在PostgreSQL里,数据是存储在表格中的,每张表有固定的结构和字段,比如用户表可能包含用户ID、姓名、邮箱等信息。
Neo4j则完全不同,它把数据存储在图里。图中包含的是节点和关系,比如一个用户是另一用户的朋友就可以通过节点(用户)和关系(朋友)轻松表达。
简单理解:
- 表是二维的,一行行数据排列得整整齐齐。
- 图是网络状的,数据之间的连接是它的核心。
2. 行 vs 节点
PostgreSQL中的每一行表示一条具体的记录,比如某个用户的详细信息。
而在Neo4j中,这种记录会被表达成一个节点,节点可以理解为图里的一个点,每个点都有属于它自己的属性。
举个例子:
PostgreSQL的用户表中,一行记录可能是:{id: 1, name: '张三', email: 'zhangsan@example.com'}
到了Neo4j里,这一行会变成一个用户节点:(id: 1, name: '张三', email: 'zhangsan@example.com')
3. 列 vs 属性
在PostgreSQL中,表的每一列都是字段,比如姓名、邮箱这些。
而在Neo4j中,节点或关系都有属性,这些属性其实就是PostgreSQL里的列。
换句话说: 列就是属性,属性就是列。同步时,只需要确保列名和属性名一致,就能一一对应。
4. 约束 vs 关系
这一点是PostgreSQL和Neo4j最根本的差异。
PostgreSQL中的约束,比如外键,用来表示两张表之间的关联关系。
而在Neo4j里,关系本身就是一等公民,图数据库的设计核心就在于节点之间的关系。
例如:
在PostgreSQL中,如果你有用户表和好友关系表:
- 用户表存用户信息。
- 好友关系表存两个用户的ID,表示谁和谁是好友。
在Neo4j中,你不需要分成两张表,因为好友关系可以直接存在于图中:
(张三)-[:朋友]->(李四)
关系甚至可以有属性,比如加好友的时间、关系强度等,这一点是图数据库的天然优势。
通过这几个对应关系,我们可以看出PostgreSQL更注重结构化的数据存储,而Neo4j更适合表现复杂的数据关系。在设计数据同步方案时,我们的目标就是把PostgreSQL里的表、行、列和约束,巧妙地转换成Neo4j里的图、节点、属性和关系,为下一步的全量同步和增量同步打好基础。简单点说,这就是把二维的表,变成更立体的图,顺便让数据之间的关系更加直观。
3.2. 数据同步技术方案设计
在Neo4j与PostgreSQL之间实现数据同步,通常有两种方式:全量同步和增量同步。全量同步通常用于初次数据迁移,而增量同步适用于实时或近实时的增量更新。增量同步和全量同步实现的方式很多,本章仅仅基于Java实现展开。
3.2.1 全量同步
全量同步是一种将PostgreSQL中的所有数据一次性迁移到Neo4j的方式,适用于初次数据迁移或定期的全量刷新。
实现步骤:
-
数据抽取:
- 使用Java通过JDBC从PostgreSQL数据库中抽取数据。
- 根据PostgreSQL的表结构,将每一行数据映射为Neo4j中的一个节点,每个列映射为节点的属性。
-
数据转换:
- 在数据抽取后,进行格式转换,将PostgreSQL的行数据转换为符合Neo4j图数据库结构的数据模型。
- 为每个数据项(如节点、关系)生成唯一标识,以保证在Neo4j中的一致性和准确性。
-
批量插入:
- 使用Neo4j的批量插入功能,通过Cypher语句将转换后的数据批量写入Neo4j数据库。
- 在插入过程中,采用事务管理来提高插入效率,确保数据一致性。
-
数据验证:
- 全量同步完成后,进行数据校验,确保PostgreSQL与Neo4j之间的数据一致性,检查是否有数据遗漏或错误。
3.2.2. 增量同步
增量同步是一种实时或周期性同步数据变更的方式,适用于数据更新频繁、需要实时反映变动的场景。
实现步骤:
-
数据变更捕获:利用PostgreSQL的WAL日志(Write-Ahead Logging)机制来捕获数据的增量变更。
-
消息队列传输:
- 将捕获到的增量变更数据通过消息队列(如RabbitMQ)传输到Neo4j的同步系统。
- 每个消息中包含了变更的操作类型(如插入、更新、删除)以及相关数据。
-
数据应用:
- 在Neo4j中,根据消息的内容执行相应的Cypher查询,更新图数据库中的数据。
- 通过Java程序处理从RabbitMQ接收到的增量数据,动态更新Neo4j中的节点和关系。
-
容错处理与监控:
- 设计增量同步的容错机制,确保在增量同步过程中不会丢失数据或发生重复同步。
4. 技术实现
4.1. PostgresSQL表结构设计
在本节PG库到Neo4j数据库同步技术实践中,我设计了4张数据表,分别是教师表(xfc_teacher)、学生表(xfc_student)、班级表(xfc_class)、班级和老师关联中间表(xfc_brid_teacher_and_class)。其表关系如下:
4.2. Neo4j 数据模型设计
根据提供的关系型数据库表结构,我们设计了如下的 Neo4j 图数据库数据模型:
节点(Nodes):
-
Teacher (老师节点)
- 属性:
id
(老师的唯一标识)name
(老师名字)subject
(老师教授的科目)
- 说明: 表示每位老师的基本信息。
- 属性:
-
Class (班级节点)
- 属性:
id
(班级的唯一标识)name
(班级名称)
- 说明: 表示每个班级的基本信息。
- 属性:
-
Student (学生节点)
- 属性:
id
(学生的唯一标识)name
(学生名字)age
(学生年龄)
- 说明: 表示每位学生的基本信息。
- 属性:
关系(Relationships):
-
TEACHES (教授)
- 起点节点类型:
Teacher
- 终点节点类型:
Class
- 属性: 无
- 说明: 表示某位老师教授某个班级的关系。
- 起点节点类型:
-
HAS_STUDENT (包含学生)
- 起点节点类型:
Class
- 终点节点类型:
Student
- 属性: 无
- 说明: 表示某个班级包含某位学生的关系。
- 起点节点类型:
示意模型
- 老师和班级:
(:Teacher {id: "T1", name: "张老师", subject: "数学"})-[:TEACHES]->(:Class {id: "C1", name: "一年级"})
- 班级和学生:
(:Class {id: "C1", name: "一年级"})-[:HAS_STUDENT]->(:Student {id: "S1", name: "李明", age: 12})
对应的 PostgreSQL 数据表和 Neo4j 模型的映射
PostgreSQL 表 | Neo4j 节点或关系 | 属性映射 |
---|---|---|
xfc_teacher | Teacher 节点 | id , name , subject |
xfc_class | Class 节点 | id , name |
xfc_student | Student 节点 | id , name , age |
xfc_brid_teacher_and_class | TEACHES 关系 | teacher_id -> id , class_id -> id |
xfc_student.class_id (外键) | HAS_STUDENT 关系 | class_id -> id |
通过这种图模型设计,我们将关系型数据库中的结构化表格数据转换为更直观的图数据结构,为后续的数据同步和分析奠定基础。
4.3. 全量同步代码
代码我都放到git仓库了,需要的自己去取。xfc-fdw-cloud: 公共解决方案
1. 全量同步接口:
2. 全量同步方法:
3. 多源事务管理配置类:
@Configuration
public class TransactionConfig {@Autowiredprivate DataSource dataSource;@Autowiredprivate Driver neo4jDriver;@Bean("postgresTransactionManager")public PlatformTransactionManager postgresTransactionManager() {return new DataSourceTransactionManager(dataSource);}@Bean("neo4jTransactionManager")public PlatformTransactionManager neo4jTransactionManager() {return new Neo4jTransactionManager(neo4jDriver);}@Bean("transactionManager")public PlatformTransactionManager chainedTransactionManager(@Qualifier("postgresTransactionManager") PlatformTransactionManager postgresTransactionManager,@Qualifier("neo4jTransactionManager") PlatformTransactionManager neo4jTransactionManager) {return new ChainedTransactionManager(postgresTransactionManager,neo4jTransactionManager);}
}
这段代码是一个Spring配置类,通过定义多个事务管理器(分别用于PostgreSQL和Neo4j)以及一个链式事务管理器(ChainedTransactionManager
),实现对多数据源的分布式事务管理,确保事务在多个数据库之间的一致性和原子性。
我就不讲解了,很简单。
4.4. 增量同步代码
1. 编写ChangeLogProcessor
代码太长了,我这里就不粘贴了,只粘贴主干代码,要看全都代码可以去仓库。
public void processChangeLog(String changeLog) {try {String operation = extractOperation(changeLog);String table = extractTable(changeLog);String id = extractId(changeLog);log.debug("Processing change: operation={}, table={}, id={}", operation, table, id);switch (table) {case "public.xfc_teacher":processTeacherChange(operation, id, changeLog);break;case "public.xfc_class":processClassChange(operation, id, changeLog);break;case "public.xfc_student":processStudentChange(operation, id, changeLog);break;case "public.xfc_brid_teacher_and_class":processTeacherClassRelation(operation, changeLog);break;default:log.warn("未知的表操作: {}", table);}} catch (Exception e) {log.error("处理变更日志时发生错误: {}", changeLog, e);}}
processChangeLog 函数是一个变更日志处理器,主要功能是接收并处理 PostgreSQL 数据库的变更日志(比如插入、更新、删除操作),然后将这些变更同步到 Neo4j 图数据库中
2. 编写DatabaseChangeService
public class DatabaseChangeService {private final JdbcTemplate jdbcTemplate;private final ChangeLogProcessor changeLogProcessor;private static final String SLOT_NAME = "neo4j_replication_slot";private static final long POLL_INTERVAL = 1000; // 1秒private static final int MAX_RETRIES = 3;private volatile boolean running = true;@PostConstructpublic void startListening() {new Thread(this::initializeReplicationSlot, "ReplicationListener").start();}private void initializeReplicationSlot() {try {if (!isSlotExists(SLOT_NAME)) {createReplicationSlot(SLOT_NAME);log.info("Created new replication slot: {}", SLOT_NAME);} else {log.info("Using existing replication slot: {}", SLOT_NAME);}listenToReplicationSlot();} catch (Exception e) {log.error("初始化复制槽时发生错误", e);}}private boolean isSlotExists(String slotName) {String query = "SELECT COUNT(*) FROM pg_replication_slots WHERE slot_name = ?";Integer count = jdbcTemplate.queryForObject(query, Integer.class, slotName);return count != null && count > 0;}private void createReplicationSlot(String slotName) {String query = "SELECT pg_create_logical_replication_slot(?, 'test_decoding')";jdbcTemplate.update(query, slotName);}public void listenToReplicationSlot() {String query = "SELECT data FROM pg_logical_slot_get_changes(?, NULL, NULL)";int retryCount = 0;while (running) {try {List<String> changes = jdbcTemplate.queryForList(query, String.class, SLOT_NAME);for (String change : changes) {try {changeLogProcessor.processChangeLog(change);} catch (Exception e) {log.error("处理变更时发生错误: {}", change, e);}}retryCount = 0; // 重置重试计数Thread.sleep(POLL_INTERVAL);} catch (InterruptedException e) {log.info("复制监听器被中断");Thread.currentThread().interrupt();break;} catch (Exception e) {log.error("监听复制槽时发生错误", e);retryCount++;if (retryCount >= MAX_RETRIES) {log.error("达到最大重试次数,停止监听");break;}try {Thread.sleep(POLL_INTERVAL * retryCount); // 指数退避} catch (InterruptedException ie) {Thread.currentThread().interrupt();break;}}}}public void stop() {running = false;}
}
DatabaseChangeService 是一个数据库变更监听服务,它通过 PostgreSQL 的逻辑复制功能(使用复制槽 replication slot)来捕获数据库的变更事件(如插入、更新、删除),当检测到变更时,会通过 ChangeLogProcessor 处理这些变更并将其同步到 Neo4j 图数据库中,从而实现 PostgreSQL 到 Neo4j 的实时数据同步。这个服务在启动时会自动创建并监听复制槽,并通过循环轮询的方式持续获取变更日志,同时包含了错误处理和重试机制以确保同步的可靠性。
5. 结论
本文详细介绍了如何在 Neo4j 与 PostgreSQL 两种数据库之间实现高效数据同步,从基础概念到全量与增量同步的实现策略,结合具体代码与实践案例,为开发者提供了全面的指导。通过充分利用 Neo4j 的关系处理优势与 PostgreSQL 的结构化数据支持,这种同步机制能够满足复杂业务需求,为数据整合和分析提供坚实基础。希望本文能为技术从业者提供清晰的思路,助力多数据库协作的实现与优化。
相关文章:
一站式指导:在Neo4j与PostgreSQL间实现高效数据同步
作者:后端小肥肠 🍇 我写过的文章中的相关代码放到了gitee,地址:xfc-fdw-cloud: 公共解决方案 🍊 有疑问可私信或评论区联系我。 🥑 创作不易未经允许严禁转载。 姊妹篇: 数据同步的艺术&#…...
linux-安全-iptables防火墙基础笔记
目录 一、 iptables链结构 五链 二、 iptables表结构 四表 三、 匹配流程 四、 语法 五、 匹配 1. 通用匹配 2. 隐含匹配 3. 显示匹配 六、 SNAT 七、 DNAT 八、 规则备份及还原 1. 备份 2. 还原 这篇将讲解iptables防火墙的基础知识 一、 iptables链结构 规则…...
Redis——主从复制原理
Redis的主从复制原理是其高可用性和分布式读取能力的重要基础。以下是Redis主从复制原理的详细解释: 一、主从复制的基本概念 Redis的主从复制是一种数据复制和备份的方式,它允许一个主节点(Master)将其所有的数据同步到一个或多…...
vue2 虚拟DOM 和 真实DOM (概念、作用、Diff 算法)
虚拟 DOM 和 真实DOM(概念、作用、Diff 算法) 1.1 概念 真实 DOM(Document Object Model):是浏览器中用于表示文档结构的树形结构。 <h2>你好</h2>虚拟DOM:用 JavaScript 对象来模拟真实 DOM…...
王道考研编程题总结
我还在完善中,边复习边完善(这个只是根据我自身总结的) 一、 线性表 1. 结构体 #define MaxSize 40 typedef struct{ElemType data[MaxSize];int length; }SqList 2. 编程题 1. 删除最小值 题意 :从顺序表中删除…...
手机租赁系统开发全攻略 创新服务助力企业智能转型
内容概要 在当今数字化飞速发展的时代,“手机租赁系统开发”正逐渐成为企业智能转型的必然选择。这一过程并不简单,但关键流程的解析将帮助企业理清思路。首先,了解需求和目标是基础,之后制定详细计划和流程图,让整件…...
git回退到某个版本git checkout和git reset命令的区别
文章目录 1. git checkout <commit>2. git reset --hard <commit>两者的区别总结推荐使用场景* 在使用 Git 回退到某个版本时, git checkout <commit> 和 git reset --hard <commit> 是两种常见的方式,但它们的用途和影响有很…...
如何使用Spring Boot进行Web开发?
Spring Boot 是一个基于 Java 的框架,它简化了新 Spring 应用的初始设置和开发过程。使用 Spring Boot 进行 Web 开发可以让你快速创建独立的、生产级别的基于 Spring 的应用。下面是使用 Spring Boot 进行 Web 开发的基本步骤: 文章目录 1. 环境准备2. …...
error=‘null‘], commandType=io.lettuce.core.RedisPublisher$SubscriptionCommand]
问题 查看java应用启动日志输出下面错误: errornull], commandTypeio.lettuce.core.RedisPublisher$SubscriptionCommand] Completing command LatencyMeteredCommand [typeINFO, outputStatusOutput [output# Server redis_version:4.0.14 redis_git_sha1:000…...
AI PC处理器ARM架构-引入NPU和大模型
AI PC处理器架构变化:ARM低功耗、引入NPU和大模型 AI进化加速端侧落地,新一轮浪潮蓄势待发(2024)”。ARM(Advanced RISC Machine)架构和x86架构是两种主要的处理器架构,它们在设计理念、应用场景和性能特点等方面有显著的差异。 ARM架构是一…...
python之opencv库Haar级联分类器检测人脸--‘haarcascade_frontalface_default.xml‘
python之opencv库Haar级联分类器检测人脸–‘haarcascade_frontalface_default.xml’ opencv库: 它由 Intel 公司发起并参与开发,其初衷是为了提供高效的计算机视觉算法实现。随着计算机视觉领域的发展,OpenCV不断更新和完善,吸引…...
「Mac畅玩鸿蒙与硬件37」UI互动应用篇14 - 随机颜色变化器
本篇将带你实现一个随机颜色变化器应用。用户点击“随机颜色”按钮后,界面背景会随机变化为淡色系颜色,同时显示当前的颜色代码,页面还会展示一只猫咪图片作为装饰,提升趣味性。 关键词 UI互动应用随机颜色生成状态管理用户交互…...
确定 POST 请求中的数据字段
在使用 requests 进行 HTTP 请求时,data 和 params 是两种常见的参数,用于传递不同类型的数据。以下是它们的作用和区别: 1. data 的作用 用于 POST 请求的主体。通常传递表单数据或 JSON 数据。在 HTTP 请求中,data 中的内容会…...
Linux - DNS服务器
六、DNS服务器 1、简介 DNS(Domain Name System)是互联网上的一项服务,它作为将域名和IP地址相互映射的一个分布式 数据库,能够使人更方便的访问互联网。 DNS系统使用的是网络的查询,那么自然需要有监听的port。DNS使…...
探究 SpringBoot 结合 MVC 高校办公室行政事务管理系统的设计与应用实现
摘 要 身处网络时代,随着网络系统体系发展的不断成熟和完善,人们的生活也随之发生了很大的变化,人们在追求较高物质生活的同时,也在想着如何使自身的精神内涵得到提升,而读书就是人们获得精神享受非常重要的途径。为了…...
蓝桥杯-扫雷
这题不难,就是麻烦一点,这里暴力求解了直接 题目链接: 扫雷 AC代码: import java.util.Scanner; // 1:无需package // 2: 类名必须Main, 不可修改public class Main {public static void main(String[] args) {Scanner scan ne…...
Hive高可用配置
在hive的商用上没有集群一说,而且它本身也不是数据库,只是hadoop的数据sql化工具,但是hive可以配置高可用,通常业内对元数据服务会开5个,而HS2服务开3个,来保证hive服务的高可用 配置方式也很简单…...
探索AI新世界!热门工具与学习资源免费获取
抖知书老师推荐: 人工智能技术的迅速发展让人们既充满期待又有些迷茫。有人担忧被AI技术取代,有人却积极拥抱这场科技浪潮。无论你处于哪种心态,人工智能已经深入到我们生活的方方面面。如果你希望轻松掌握最新的AI工具与动态,…...
MAUI APP开发蓝牙协议的经验分享:与跳绳设备对接
在开发MAUI应用程序时,蓝牙协议的应用是一个重要的环节,尤其是在需要与外部设备如智能跳绳进行数据交换的场景中。以下是我在开发过程中的一些经验和心得,希望能为你的项目提供帮助。 1. 蓝牙协议基础 蓝牙协议是无线通信的一种标准&#x…...
常见Linux命令(详解)
文章目录 常见Linux命令文件目录类命令pwd 打印当前目录的绝对路径ls 列出目录内容cd 切换路径mkdir 建立目录rmdir 删除目录touch 创建空文件cp 复制文件或目录rm 移除文件或者目录mv 移动文件与目录或重命名cat 查看文件内容more 文件分屏查看器less 分屏显示文件内容head 显…...
LeetCode763. 划分字母区间(2024冬季每日一题 23)
给你一个字符串 s 。我们要把这个字符串划分为尽可能多的片段,同一字母最多出现在一个片段中。 注意,划分结果需要满足:将所有划分结果按顺序连接,得到的字符串仍然是 s 。 返回一个表示每个字符串片段的长度的列表。 示例 1&a…...
【k8s 深入学习之 event 聚合】event count累记聚合(采用 Patch),Message 聚合形成聚合 event(采用Create)
参考 15.深入k8s:Event事件处理及其源码分析 - luozhiyun - 博客园event 模块总览 EventRecorder:是事件生成者,k8s组件通过调用它的方法来生成事件;EventBroadcaster:事件广播器,负责消费EventRecorder产生的事件,然后分发给broadcasterWatcher;broadcasterWatcher:用…...
Java--数组的定义与使用
1.数组的基本概念 1.1为什么用数组 在程序设计中,每一个数据总是对应一个变量.当数据量越大,就需要更多的变量来存储.我们将相同类型的数据存储到一个集合中,就可以更方便我们对数据进行访问,同时可以减少不断定义变量.这个集合就叫做数组 1.2数组的定义 数组是一种基本的数…...
tcpdump抓包wireshark分析
背景 分析特定协议的数据包,如 HTTP、DNS、TCP、UDP 等,诊断网络问题,例如连接故障、延迟和数据包丢失。 大概过程 1.安装tcpdump yum update yum install tcpdump2.抓包,从当前时间起,一小时后停止,…...
qtcanpool 知 09:测试框架
文章目录 前言不满改进优化后语 前言 很久以前,作者写的代码都没有测试用例,最多就是写个 demo 验证一下,毕竟不是专业出身,也没经过大公司的洗礼。 后来,参与到一些项目才知道有专门的测试,而且开发也要测…...
使用Apache HttpClient发起一个GET HTTP请求
Apache HttpClient 是一个强大且灵活的Java库,用于处理HTTP请求。 它提供了广泛的功能,包括对不同HTTP方法的支持、连接管理、Cookie处理等。 无论是与RESTful API交互、下载网页内容还是自动化网页任务,Apache HttpClient 都能通过其简洁而…...
C++ STL 容器系列(三)list —— 编程世界的万能胶,数据结构中的百变精灵
STL系列学习参考: C STL系列__zwy的博客-CSDN博客https://blog.csdn.net/bite_zwy/category_12838593.html 学习C STL的三个境界,会用,明理,能扩展,STL中的所有容器都遵循这个规律,下面我们就按照这三个境…...
【前端学习笔记】TypeScript学习
1.什么是TypeScript TypeScript(简称 TS)是微软公司开发的一种基于 JavaScript (简称 JS)语言的编程语言。TypeScript 可以看成是 JavaScript 的超集(superset),添加了类型系统和编译时类型检查…...
qt三大调试方法总结(printf\qDebug\qCDebug)
文章目录 1 传统方法2 qDebug传统方法扩展1 控制输出扩展2 日志格式扩展3 日志保存扩展4 源码定义护展5 开源扩展3 qCDebug方法扩展1 控制扩展2 格式化扩展3 保存日志扩展4 源码定义参考1 传统方法 #include<stdio.h> printf(“xboard hello printf”) 2 qDebug传统方法…...
耶鲁大学公开课《心理学导论》学习笔记:第 1 课 - 导论
概述 作为一个程序员,或者说,我们不管做什么行业,都可以或多或少的学习一些心理学 我们在生活工作中,其实都会有意无意的接触一些心理学原理,例如,【番茄工作法】、【内在动机与外在激励】 这里选择的是&…...
Android ConstraintLayout 约束布局的使用手册
目录 前言 一、ConstraintLayout基本介绍 二、ConstraintLayout使用步骤 1、引入库 2、基本使用,实现按钮居中。相对于父布局的约束。 3、A Button 居中展示,B Button展示在A Button正下方(距离A 46dp)。相对于兄弟控件的约束…...
STM32F030单片机AD采集应用总结
最近在设计一款产品的AD时,采集到的电压老是比输入电压0.2V左右,电路如图所示 查阅资料得知,STM32f030 的输入阻抗应小于 50K。于是将电阻改为 39K/10K,但情况依旧。随后,干脆将电阻值改为 3.9K/1K,虽有一定…...
Web开发基础学习——通过React示例学习模态对话框
Web开发基础学习系列文章目录 第一章 基础知识学习之通过React组件学习模态对话框 文章目录 Web开发基础学习系列文章目录前言一、创建新的 React 应用二、 创建模态对话框组件三、修改 App.js四、 添加样式五、启动应用六、访问应用总结 前言 模态对话框(Modal D…...
实例分割详解
实例分割详解 引言 实例分割是计算机视觉领域的一项复杂任务,它要求模型能够识别图像中不同类别的对象,并对每个单独的对象进行像素级别的分类。与语义分割不同的是,实例分割不仅要区分不同的类别,还要识别同一类别中的不同个体…...
Flink四大基石之State(状态) 的使用详解
目录 一、有状态计算与无状态计算 (一)概念差异 (二)应用场景 二、有状态计算中的状态分类 (一)托管状态(Managed State)与原生状态(Raw State) 两者的…...
vue深入理解输入框字符限制的优化设计
文章目录 深入理解输入框字符限制的优化设计背景与挑战输入框限制的重要性常见需求 多种实现方法解析方法一:基于实时过滤的字符限制方法二:借助正则验证方法三:提交时二次校验 性能优化无障碍设计延伸场景与最佳实践1. 多语言国际化支持2. 动…...
MySQL的子查询
SQL语句中嵌套select语句,嵌套查询 案例: select * from t1 where column1 (select column1 from t2); 补: 1.子查询外部的语句可以是insert/update/delete/select的任何一个 2.位置也可以在where/from/select之后 类型: 1.标量子查询…...
Kubernetes架构原则和对象设计
云原生学习路线导航页(持续更新中) 快捷链接 Kubernetes常见问题解答 本文从 Google Borg系统的架构设计开始,深入讲解Kubernetes架构及组件的基本原理 1.什么是云计算 1.1.传统行业应用 假设有10台服务器,两个应用。小规模管…...
npm : 无法加载文件 D:\nodejs\npm.ps1,因为在此系统上禁止运行脚本
要以管理员身份打开PowerShell,请按照以下步骤操作: 在Windows搜索框中查找PowerShell: 在任务栏上,点击左下角的Windows徽标(或按Win S键)以打开搜索框。输入“PowerShell”以查找PowerShell应用程序。右…...
Linux CentOS
阿里云开源镜像下载链接 https://mirrors.aliyun.com/centos/7/isos/x86_64/ VMware 安装 CentOS7 自定义 下一步 选择稍后安装操作系统 选择 输入 查看物理机CPU内核数量 CtrlShiftEsc 总数不超过物理机内核数量 推荐内存 自选 推荐 推荐 默认 拆分成多个 默认 自定义硬件…...
如何用注册机破解Reflexive游戏
相信有许多小朋友(像我以前一样)已经迫不及待地准备准备对浩瀚的、像三星堆一般的Reflexive游戏合集进行考古挖掘工作了。不巧的是,打开游戏之后发现常常提示要付费才能解锁完整版。 一、下载注册机与破解文件 首先,在我的永硕网…...
【算法day7】字符串:反转与替换
题目引用 反转字符串反转字符串II替换数字 1.反转字符串 编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。 不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。 示例 1&am…...
基于Linux C++多线程服务器 + Qt上位机开发 + STM32 + 8266WIFI的智慧无人超市
前言 针对传统超市购物车结账排队时间长、付款效率低的问题,提出了一种更符合现代社会人们购物方式-基于RFID的自助收银系统。习惯了快节奏生活的人们都会选择自助收银机结账,理由显而易见:自助收银机结账很方便,几乎不用排队&am…...
继电器测试的培训和学习资源有哪些推荐?
继电器是电气控制设备中常见的一种元件,用于实现电路的开关控制和保护功能。对于从事电气相关工作的人员来说,掌握继电器的测试技能是非常重要的。以下是一些推荐的继电器测试培训和学习资源: 1. 在线课程:许多在线学习平台提供了…...
学习日志020---qt信号与槽
作业 import sysfrom PySide6.QtWidgets import QApplication, QWidget,QPushButton,QLineEditfrom Form import Ui_Form from second import Ui_second from PySide6.QtCore import Qtclass MyWidget(QWidget,Ui_Form):def __init__(self):super().__init__()self.setupUi(se…...
小迪安全笔记 第四十四天 sql盲注 实战利用sql盲注 进行漏洞的利用
sql盲注的分类 什么是盲注 就是我们什么也不知道的情况下进行的注入 前边的注入 都是简单的注入 我们猜测 数据类型 之后 可以直接 union 去查 这种情况多用于 数据库增删查改中的 查 bool盲注也用于查 这个的情况的就是我们前边都试了 没有用 就需要…...
AMEYA360:上海永铭电子全新高压牛角型铝电解电容IDC3系列,助力AI服务器电源高效运转
随着数据中心和云计算的高速发展,AI服务器的能效要求日益提高。如何在有限空间内实现更高的功率密度和稳定的电源管理,成为AI服务器电源设计的一大挑战。永铭推出全新高压牛角型铝电解电容IDC3系列,以大容量、小尺寸的创新特性,为…...
SpringBoot Web 开发请求参数
SpringBoot Web 开发请求参数 简单的 web 请求: @RestController public class HelloController {@RequestMapping("sayHello")public String sayHello(){System.out.println("Hello World");return "hello world";} }获取请求参数 简单参数…...
力扣92.反转链表Ⅱ
题目描述 题目链接92. 反转链表 II 给你单链表的头指针 head 和两个整数 left 和 right ,其中 left < right 。请你反转从位置 left 到位置 right 的链表节点,返回 反转后的链表 。 示例 1: 输入:head [1,2,3,4,5], left …...
网络安全、Web安全、渗透测试之笔经面经总结(一)
本篇文章总结涉及以下几个方面: 一:对称加密非对称加密? 对称加密:加解密用同一密钥,密钥维护复杂n(n-1)/2,不适合互联网传输密钥,加解密效率高。应用于加密数据。 非…...