Spark 的 Shuffle 机制:原理与源码详解
Apache Spark 是一个分布式数据处理框架,专为大规模数据分析设计。其核心操作之一是 Shuffle,这是一个关键但复杂的机制,用于在某些操作期间在集群中重新分配数据。理解 Shuffle 需要深入探讨其目的、机制和实现,既包括概念层面,也包括源代码层面。本解释将详细、逐步且通俗易懂,即使是非专业人士也能清晰理解,同时提供技术深度以确保准确性。
目录
- 什么是 Shuffle,为什么需要它?
- Shuffle 的高层工作流程
- Shuffle 的详细步骤与原理
- 步骤 1:触发 Shuffle
- 步骤 2:Map 阶段(写入 Shuffle 数据)
- 步骤 3:Shuffle 数据传输
- 步骤 4:Reduce 阶段(读取 Shuffle 数据)
- 底层原理与优化
- 源代码解析
- 常见问题与缓解措施
- 结论
1. 什么是 Shuffle,为什么需要它?
概念概述
在 Spark 中,数据以分布式方式在集群的多个节点(计算机)上处理。每个节点处理数据的子集,称为 分区(Partition)。Spark 的操作分为两类:
- 窄变换(Narrow Transformations)(如 map、filter):这些操作在单个分区上执行,无需数据在节点之间移动。
- 宽变换(Wide Transformations)(如 groupBy 、join、reduceByKey):这些操作需要跨分区重新分配数据,因为一个分区的输出可能依赖于其他分区的数据。
Shuffle 是在宽变换期间重新分配数据的过程。它确保相关数据(例如,groupBy 中具有相同键的所有记录)被分组到同一节点上,以便进一步处理。
为什么需要 Shuffle?
想象你在按城市对学生进行分组(groupBy 操作)。如果学生记录分散在不同的节点上,Spark 需要移动这些记录,以便同一城市的所有学生记录都集中在同一节点上。这种数据移动就是 Shuffle。没有 Shuffle,像分组、连接或跨分区聚合数据的操作将无法实现。
Shuffle 的挑战
- 性能开销:Shuffle 涉及磁盘 I/O、网络 I/O 以及序列化/反序列化,是 Spark 中最昂贵的操作之一。
- 复杂性:在分布式系统中管理数据移动需要仔细协调。
2. Shuffle 的高层工作流程
在高层,Shuffle 可分为两个阶段:
- Map 阶段:输入数据的每个分区由一个“映射器(Mapper)”任务处理,该任务按键分组数据并将其写入磁盘,格式适合重新分配。
- Reduce 阶段:“归约器(Reducer)”任务从所有映射器中获取分组数据,合并数据并生成最终输出。
这类似于 MapReduce 范式,其中:
- 映射器 通过按键分区数据来准备数据。
- 归约器 聚合或处理分区后的数据。
Shuffle 位于这两个阶段之间,负责集群中的数据传输。
3. Shuffle 的详细步骤与原理
让我们将 Shuffle 过程分解为细致的步骤,解释每个阶段的原理和机制。我们将以 groupByKey
操作为例进行说明,因为它是一个典型的触发 Shuffle 的操作。
步骤 1:触发 Shuffle
发生什么:调用一个宽变换(例如 groupByKey),需要跨分区重新分配数据。
原理:
- Spark 的执行模型基于 弹性分布式数据集(RDD) 或 数据集/数据框(Dataset/DataFrame),这些是分成多个分区的逻辑数据集合。
- 当调用宽变换时,Spark 的查询规划器(通过 DataFrame 的 Catalyst 优化器 或 RDD 的血缘关系)检测到数据依赖跨越分区边界。
- 这会在 Spark 的有向无环图(DAG)调度器中触发一个 阶段边界(Stage Boundary)。为 Shuffle 操作创建一个新的阶段。
示例:
val rdd = sc.parallelize(Seq(("A", 1), ("B", 2), ("A", 3), ("B", 4)))
val grouped = rdd.groupByKey()
这里,groupByKey 要求将键为“A”的所有记录放在一个分区,键为“B”的所有记录放在另一个分区。这种重新分配就是 Shuffle。
源码分析:
在 Spark 的 DAGScheduler(类 org.apache.spark.scheduler.DAGScheduler)中,submitJob 方法分析 RDD 血缘关系并识别 Shuffle 依赖:
def submitJob[T](rdd: RDD[T],func: (TaskContext, Iterator[T]) => _,partitions: Seq[Int],callSite: CallSite,resultHandler: (Int, U) => Unit,properties: Properties): JobId = {// 检测 Shuffle 依赖并在需要时创建新阶段
}
当检测到 Shuffle 依赖(通过 ShuffleDependency)时,会创建一个新的 ShuffleMapStage。
步骤 2:Map 阶段(写入 Shuffle 数据)
发生什么:每个映射器任务处理其分区,按键分组数据,并将结果写入磁盘,格式优化用于 Shuffle。
原理:
- 按键分区:Spark 使用 分区器(Partitioner)(如 HashPartitioner 或 RangePartitioner)来确定每个键属于哪个归约器分区。对于 HashPartitioner ,分区计算为:分区=hash(键)mod 分区数
- 缓冲与溢写:为避免将所有数据加载到内存,Spark 在内存中缓冲数据,并在缓冲区超过阈值(由 spark.shuffle.memoryFraction 控制)时溢写到磁盘。
- 序列化:数据被序列化以减少内存和网络开销。
- 磁盘写入:每个映射器将其输出写入本地磁盘,生成称为 Shuffle 文件 的文件,按归约器分区组织。
详细机制:
- 映射器任务执行:
- 输入 RDD 的每个分区由一个映射器任务处理。
- 对于每条记录,映射器应用变换(例如,为 groupByKey 提取键)。
- 键被哈希,记录被分配到归约器分区。
- 外部 Shuffle 服务:
- Spark 使用 ExternalAppendOnlyMap 或 ExternalSorter 管理内存中的数据。这些数据结构缓冲键值对,并在内存不足时溢写到磁盘。
- 溢写文件是临时的,存储在本地磁盘目录(通过 spark.local.dir 配置)。
- Shuffle 文件创建:
- 为每个归约器分区,映射器创建单独的文件或文件段。
- 这些文件以包含元数据的格式写入(例如,每个归约器分区的偏移量)。
示例:
对于 RDD Seq(("A", 1), ("B", 2), ("A", 3), ("B", 4)),假设有两个归约器分区:
- 映射器 1 处理 ("A", 1), ("B", 2):
- 键“A”哈希到分区 0。
- 键“B”哈希到分区 1。
- 写入两个文件:分区 0 的文件(("A", 1))和分区 1 的文件(("B", 2))。
- 映射器 2 处理("A", 3), ("B", 4):
- 同样,写入分区 0(("A", 3))和分区 1(("B", 4))。
源码分析:
ShuffleMapTask(类 org.apache.spark.scheduler.ShuffleMapTask)协调 Map 阶段。关键逻辑在 runTask 中:
override def runTask(context: TaskContext): MapStatus = {// 反序列化 RDD 分区val deserializer = serializer.get()val rddIter = rdd.iterator(partition, context)// 使用 ShuffleWriter 写入 Shuffle 数据val writer = shuffleBlockResolver.getWriter(dep.shuffleId, partition.index, context)writer.write(rddIter.map(x => (dep.partitioner.getPartition(x._1), x)))writer.stop(success = true).get
}
ShuffleWriter(如 SortShuffleWriter)处理分区和磁盘写入。
步骤 3:Shuffle 数据传输
发生什么:归约器任务通过网络从所有映射器中获取 Shuffle 文件。
原理:
- 块管理器(BlockManager):Spark 的 BlockManager 负责管理数据块(包括 Shuffle 文件)。每个节点运行一个 BlockManager,为其他节点提供 Shuffle 文件。
- 外部 Shuffle 服务:为将 Shuffle 文件服务与执行器生命周期解耦,Spark 使用外部 Shuffle 服务(一个独立进程)来提供 Shuffle 文件。这在动态分配场景中尤为有用。
- 网络传输:归约器使用 HTTP 或基于 Netty 的传输从映射器节点获取 Shuffle 文件。文件以 块(Block) 的形式获取,Spark 通过流水线和压缩(由 spark.shuffle.compress 控制)优化这一过程。
详细机制:
- 归约器请求:
- 每个归约器任务需要从所有映射器任务中获取其分配分区的数据。
- 归约器查询 MapOutputTracker(驱动程序的一个组件)以获取其分区的 Shuffle 文件位置。
- 数据获取:
- 归约器使用 BlockManager 从映射器节点获取块。
- 如果启用了外部 Shuffle 服务,则由其提供文件;否则,由映射器的执行器提供。
- 合并:
- 在获取数据时,归约器将来自多个映射器的流合并为单个流以进行处理。
- Spark 可能使用 基于排序的 Shuffle(按键排序数据)或 基于哈希的 Shuffle(按键分组而不排序),具体取决于操作。
示例:
对于分区 0(键“A”):
- 归约器 0 从映射器 1 获取分区 0 的 Shuffle 文件(("A", 1)),从映射器 2 获取分区 0 的文件(("A", 3))。
- 数据合并为单个流:(("A", 1), ("A", 3)。
源码分析:
BlockTransferService(如 NettyBlockTransferService)处理数据获取:
def fetchBlocks(host: String,port: Int,execId: String,blockIds: Array[String],listener: BlockFetchingListener): Unit = {// 启动 Shuffle 块的网络传输
}
MapOutputTracker(类 org.apache.spark.MapOutputTracker)提供 Shuffle 文件位置的元数据。
步骤 4:Reduce 阶段(读取 Shuffle 数据)
发生什么:归约器任务处理获取的数据以生成最终输出。
原理:
- 聚合:对于像 groupByKey 这样的操作,归约器将给定键的所有值分组。对于 reduceByKey,它应用归约函数来组合值。
- 内存管理:归约器在内存中缓冲数据,并在需要时溢写到磁盘,类似于映射器。
- 输出:归约器将最终输出写入新的 RDD 分区或 DataFrame,供后续操作使用。
详细机制:
- 数据处理:
- 归约器迭代获取的数据,按需分组或聚合。
- 对于 groupByKey,它为每个键创建值列表(例如,
("A", [1, 3])
)。
- 溢写管理:
- 如果数据超过内存限制,Spark 使用 ExternalSorter 溢写到磁盘。
- 输出写入:
- 最终输出写入新分区,根据存储级别(例如
MEMORY_AND_DISK
)存储在内存或磁盘中。
- 最终输出写入新分区,根据存储级别(例如
示例:
对于 groupByKey:
- 归约器 0 处理
("A", 1), ("A", 3)
,生成("A", [1, 3])
。 - 归约器 1 处理
("B", 2), ("B", 4)
,生成("B", [2, 4])
。
源码分析:
ResultTask(类 org.apache.spark.scheduler.ResultTask)或 ShuffleMapTask 中的归约器逻辑处理数据:
override def runTask(context: TaskContext): U = {val iter = dep.rdd.iterator(partition, context)func(context, iter)
}
4. 底层原理与优化
关键原理
- 确定性分区:分区器确保具有相同键的所有记录到达同一归约器,以实现正确的分组或聚合。
- 容错性:Shuffle 文件存储在磁盘上,因此如果节点失败,Spark 可以重新计算或重新获取数据。
- 本地化:Spark 尝试在数据所在节点上运行任务,以减少网络传输。
优化
- 合并 Shuffle 文件:
- Spark 通过合并文件(由 spark.shuffle.consolidateFiles 启用)减少打开的文件句柄数量,而不是为每个映射器-归约器对创建单独文件。
- 基于排序的 Shuffle:
- 在 Spark 1.2 中引入,基于排序的 Shuffle 按键排序数据,相比基于哈希的 Shuffle 减少内存使用。
- 由 spark.shuffle.manager 控制(默认设置为 sort)。
- 压缩:
- Shuffle 数据被压缩以减少磁盘和网络 I/O(由 spark.shuffle.compress 和 spark.shuffle.spill.compress 启用)。
- 外部 Shuffle 服务:
- 通过独立于执行器提供 Shuffle 文件,提高可靠性。
- Tungsten:
- Spark 的 Tungsten 引擎通过使用堆外内存和高效序列化(在 DataFrame/DataSet API 中使用)优化 Shuffle 期间的内存使用。
5. 源代码解析
让我们深入探讨 Spark 源代码(基于 Spark 3.x)的关键类和方法,以理解 Shuffle 的实现。代码主要用 Scala 编写,位于 org.apache.spark
包中。
关键类
-
ShuffleDependency(org.apache.spark.ShuffleDependency):
- 表示 RDD 之间的 Shuffle 依赖。
- 包含分区器和 Shuffle ID。
class ShuffleDependency[K, V, C](@transient val rdd: RDD[_ <: Product2[K, V]],val partitioner: Partitioner,val serializer: Serializer = SparkEnv.get.serializer,val keyOrdering: Option[Ordering[K]] = None,val aggregator: Option[Aggregator[K, V, C]] = None,val mapSideCombine: Boolean = false)extends Dependency[Product2[K, V]] {// Shuffle 的元数据 }
-
ShuffleMapTask(org.apache.spark.scheduler.ShuffleMapTask):
- 执行 Map 阶段,写入 Shuffle 数据。
- 使用
ShuffleWriter
分区和写入数据。
-
SortShuffleWriter(org.apache.spark.shuffle.sort.SortShuffleWriter):
- 实现基于排序的 Shuffle,按键排序数据并写入磁盘。
def write(records: Iterator[Product2[K, V]]): Unit = {val sorter = new ExternalSorter[K, V, _](context, dep.aggregator, None, dep.keyOrdering, serializer)sorter.insertAll(records)// 将排序后的数据写入 Shuffle 文件 }
-
BlockManager(org.apache.spark.storage.BlockManager):
- 管理 Shuffle 文件并将其提供给归约器。
- 使用 DiskBlockManager 进行磁盘存储,BlockTransferService 进行网络传输。
-
MapOutputTracker(org.apache.spark.MapOutputTracker):
- 跟踪集群中 Shuffle 文件的位置。
def getMapSizesByExecutorId(shuffleId: Int, reduceId: Int): Seq[(BlockManagerId, Long)] = {// 返回归约器的 Shuffle 文件位置和大小 }
代码中的工作流程
- 阶段创建:
- DAGScheduler.submitMissingTasks 为 Map 阶段创建 ShuffleMapTask 实例。
- Map 阶段:
- ShuffleMapTask.runTask 调用 SortShuffleWriter.write 分区并写入数据。
- 数据获取:
- 归约器使用 BlockManager.getRemoteBytes 获取 Shuffle 块。
- Reduce 阶段:
- ResultTask 或归约器逻辑处理获取的数据。
6. 常见问题与缓解措施
问题
- 性能瓶颈:
- 过多的磁盘 I/O 或网络传输可能减慢 Shuffle。
- 缓解措施:增加内存(spark.memory.fraction),启用压缩,或使用更多分区以并行化。
- 数据倾斜:
- 如果某些键的数据显著较多,某些归约器可能成为瓶颈。
- 缓解措施:使用加盐(为键添加随机前缀)或自定义分区器。
- 溢写到磁盘:
- 如果内存不足,Spark 会溢写到磁盘,增加 I/O。
- 缓解措施:增加执行器内存或调整
spark.shuffle.memoryFraction
。
调优参数
spark.shuffle.compress
:为 Shuffle 文件启用压缩。spark.shuffle.spill.compress
:为溢写数据启用压缩。spark.shuffle.consolidateFiles
:减少 Shuffle 文件数量。spark.shuffle.partitions
:设置归约器分区数(默认值为 200)。
7. 结论
Spark 的 Shuffle 是分布式数据处理中宽变换的关键机制。通过跨分区重新分配数据,它确保像 groupBy
、join
和 reduceByKey
这样的操作能够正确执行。该过程包括 Map 阶段(写入分区数据)、数据传输阶段(通过网络获取数据)和 Reduce 阶段(处理数据)。在代码层面,类如 ShuffleMapTask
、SortShuffleWriter
和 BlockManager
协调这一复杂操作。
对于初学者,可以将 Shuffle 想象为一个大规模的排序和配送系统:数据按键排序,包装成箱子(Shuffle 文件),通过网络运送,并由归约器拆箱以生成最终结果。尽管 Shuffle 资源密集,但 Spark 的优化(如基于排序的 Shuffle、压缩、外部 Shuffle 服务)使其高效且可扩展。
相关文章:
Spark 的 Shuffle 机制:原理与源码详解
Apache Spark 是一个分布式数据处理框架,专为大规模数据分析设计。其核心操作之一是 Shuffle,这是一个关键但复杂的机制,用于在某些操作期间在集群中重新分配数据。理解 Shuffle 需要深入探讨其目的、机制和实现,既包括概念层面&a…...
IdeaVim配置指南
一、什么是 IdeaVim? IdeaVim 是 JetBrains 系列 IDE(如 IntelliJ IDEA, WebStorm, PyCharm 等)中的一个插件,让你在 IDE 里使用 Vim 的按键习惯,大大提升效率。 安装方法: 在 IDE 中打开 设置(Settings) →…...
[监控看板]Grafana+Prometheus+Exporter监控疑难排查
采用GrafanaPrometheusExporter监控MySQL时发现经常数据不即时同步,本示例也是本地搭建采用。 Prometheus面板 1,Detected a time difference of 11h 47m 22.337s between your browser and the server. You may see unexpected time-shifted query res…...
P56-P60 统一委托,关联游戏UI,UI动画,延迟血条
这一部分首先把复杂的每个属性委托全部换成了简洁可复用的委托,之后重新修改了UI蓝图,然后在新增了一个与之前表格关联的动画与血条延迟下降的蓝图 OverlayAuraWidgetController.h // Fill out your copyright notice in the Description page of Project Settings. #pragma …...
智能修复大模型生成的 JSON 字符串:Python 实现与优化
在使用大语言模型(LLM)生成 JSON 格式数据时,常因模型输出不完整、语法错误或格式不规范导致 JSON 解析失败。本文介绍如何通过 json_repair 库实现对 LLM 生成 JSON 字符串的自动修复,并改进原始提取函数以提升容错能力。 一、LLM 生成 JSON 的常见问题 LLM 输出的 JSON …...
【PPT制作利器】DeepSeek + Kimi生成一个初始的PPT文件
如何基于DeepSeek Kimi进行PPT制作 步骤: Step1:基于DeepSeek生成文本,提问 Step2基于生成的文本,用Kimi中PPT助手一键生成PPT 进行PPT渲染-自动渲染 可选择更改模版 生成PPT在桌面 介绍的比较详细,就是这个PPT模版…...
华为设备端口隔离
端口隔离的理论与配置指南 一、端口隔离的理论 基本概念 端口隔离(Port Isolation)是一种在交换机上实现的安全功能,用于限制同一VLAN内指定端口间的二层通信。被隔离的端口之间无法直接通信,但可通过上行端口访问公共资源&#…...
YOLO12改进-C3K2模块改进-引入离散余弦变换DCT 减少噪声提取图像的细节、边缘和纹理等微观特征
离散余弦变换(Discrete Cosine Transform, DCT)由 Nasir Ahmed 于 1974 年提出,最初是为了优化数据压缩。其核心思想是将信号从空间域转换为频率域,从而实现冗余信息的压缩。DCT 在图像和视频处理领域应用广泛,例如 JP…...
基于大模型的自然临产阴道分娩全流程预测与方案研究报告
目录 一、引言 1.1 研究背景与目的 1.2 研究意义 1.3 国内外研究现状 二、大模型技术原理与应用概述 2.1 大模型基本原理 2.2 在医疗领域的应用现状 2.3 用于分娩预测的优势 三、术前预测与准备方案 3.1 产妇身体状况评估指标 3.2 大模型预测流程与方法 3.3 基于预…...
用 Tailwind CSS 优化你的 Vue 3 项目! ! !
Vue 3 的响应式魅力 TailwindCSS 的原子级美学 前端开发的舒适巅峰! 在现代前端开发中,组件驱动 原子化 CSS 正在成为新的标准。如果你已经在使用 Vue 3,那不妨试试 Tailwind CSS —— 一个强大的原子化 CSS 框架,它能让你几乎…...
PostgreSQL数据库的array类型
PostgreSQL数据库相比其它数据库,有很多独有的字段类型。 比如array类型,以下表的pay_by_quarter与schedule两个字段便是array类型,即数组类型。 CREATE TABLE sal_emp (name text,pay_by_quarter integer[],schedule t…...
融智学视角集大成范式革命:文理工三类AI与网络大数据的赋能
融智学视角下的“集大成”范式革命:AI与大数据的终极赋能 一、化繁为简的工具革命:AI与大数据的三重解构 信息压缩的数学本质 Kolmogorov复杂度极限突破: K_AI(x)min_p∈P_NN ℓ(p)λ⋅dist(U(p),x) (神经网络程序p的描述长度语…...
【2025】Visio 2024安装教程保姆级一键安装教程(附安装包)
前言 大家好!最近很多朋友在问我关于Visio 2024的安装问题,尤其是对于那些需要制作专业流程图和组织结构图的小伙伴来说,这款软件简直是必不可少的办公神器!今天就给大家带来这篇超详细保姆级的Visio 2024安装教程,不…...
C++【继承】
继承 1.继承1.1 继承的概念1.2继承的定义1.2.1定义格式1.2.2继承基类成员访问方式的变化 1.3继承模板 2.基类和派生类之间的转换 1.继承 1.1 继承的概念 继承(inheritance)机制是面向对象程序设计使代码可以复用的最重要的手段,它允许我们在保持原有类特性的基础上…...
理解字、半字与字节 | 从 CPU 架构到编程实践的数据类型解析
注:本文为 “字、半字、字节” 相关文章合辑。 略作重排,未全校。 如有内容异常,请看原文。 理解计算机体系结构中的字、半字与字节 在计算机科学中,理解“字 (Word)”、“半字 (Half-Word)”和“字节 (Byte)”等基本数据单元的…...
VMware搭建ubuntu保姆级教程
目录 VMware Ubuntu 虚拟机配置指南 创建虚拟机 下载 Ubuntu ISO 新建虚拟机 网络配置(双网卡模式) 共享文件夹设置 SSH 远程访问配置 VMware Ubuntu 虚拟机配置指南 创建虚拟机 下载 Ubuntu ISO 【可添加我获取】 官网:Get Ubunt…...
内容社区系统开发文档
1 系统分析 1.1 项目背景 1.2 需求分析 2 系统设计 2.1 系统功能设计 2.2 数据库设计 2.2.1 数据库需求分析 2.2.2 数据库概念结构设计 2.2.3 数据库逻辑结构设计 2.2.4 数据库物理结构设计 2.2.5 数据库视图设计 2.2.6 函数设计 2.2.7 存储过程设计 2.2.8 触发器…...
Ubuntu开放端口
在 Ubuntu 中,我们可以使用 ufw (Uncomplicated Firewall) 来管理防火墙。以下是打开 80 和 8090 端口的步骤: 首先检查防火墙状态 sudo ufw status 如果防火墙没有启用,先启用它: sudo ufw enable 允许 80 端口(…...
PyTorch 与 TensorFlow 中基于自定义层的 DNN 实现对比
深度学习双雄对决:PyTorch vs TensorFlow 自定义层大比拼 目录 深度学习双雄对决:PyTorch vs TensorFlow 自定义层大比拼一、TensorFlow 实现 DNN1. 核心逻辑 二、PyTorch 实现自定义层1. 核心逻辑 三、关键差异对比四、总结 一、TensorFlow 实现 DNN 1…...
质量员考试案例题有哪些常见考点?
质量员考试案例题常见考点如下: 施工质量控制 施工工艺与工序:如混凝土浇筑时的振捣时间、方法,若振捣不充分会导致混凝土出现蜂窝、麻面等质量问题。 施工环境:例如在高温天气下进行砌筑作业,未对砌块进行适当处理或…...
Axure疑难杂症:深度理解与认识“事件”“动作”(玩转交互)
亲爱的小伙伴,在您浏览之前,烦请关注一下,在此深表感谢! Axure产品经理精品视频课已登录CSDN可点击学习https://edu.csdn.net/course/detail/40420 课程主题:深度理解与认识“事件”“动作” 主要内容:事件、动作定义、本质、辩证关系、执行顺序 应用场景:原型交互 …...
【AI知识库云研发部署】RAGFlow + DeepSeek
gpu 安装screen:yum install screen 配置ollama: 下载官方安装脚本并执行: curl -fsSL https://ollama.com/install.sh | sh 通过screen后台运行ollama:screen -S ollama 在screen会话中启动服务: export OLLA…...
HTML07:表格标签
表格 基本结构 单元格行列跨行跨列 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>表格学习</title><style>td {text-align: center;vertical-align: middle;}</style> </he…...
【专家库】Kuntal Chowdhury
昆塔尔乔杜里 Kuntal Chowdhury 是 NVIDIA 的 6G 开发者关系经理和技术布道师。他致力于推动与 NVIDIA 平台和工具的开发者和早期采用者生态系统的联系,以促进 6G 研究社区的蓬勃发展。在此之前,他是 BlueFusion, Inc. 的创始人,这是一家创新…...
IAA-Net:一种实孔径扫描雷达迭代自适应角超分辨成像方法——论文阅读
IAA-Net:一种实孔径扫描雷达迭代自适应角超分辨成像方法 1. 论文的研究目标与实际意义1.1 研究目标1.2 实际问题与产业意义2. 论文的创新方法、公式与优势2.1 方法框架与核心步骤2.2 核心公式与推导2.2.1 回波模型与目标函数2.2.2 正则化加权矩阵设计2.2.3 迭代更新公式2.2.4 …...
[论文阅读]MCP Guardian: A Security-First Layer for Safeguarding MCP-Based AI System
MCP Guardian: A Security-First Layer for Safeguarding MCP-Based AI System http://arxiv.org/abs/2504.12757 推出了 MCP Guardian,这是一个框架,通过身份验证、速率限制、日志记录、跟踪和 Web 应用程序防火墙 (WAF) 扫描来…...
提示词工程:通向AGI时代的人机交互艺术
引言:从基础到精通的提示词学习之旅 欢迎来到 "AGI时代核心技能" 系列课程的第二模块——提示词工程。在这个模块中,我们将系统性地探索如何通过精心设计的提示词,释放大型语言模型的全部潜力,实现高效、精…...
地级市-机器人、人工智能等未来产业水平(2009-2023年)-社科数据
地级市-机器人、人工智能等未来产业水平(2009-2023年)-社科数据https://download.csdn.net/download/paofuluolijiang/90623814 https://download.csdn.net/download/paofuluolijiang/90623814 此数据集统计了2009-2023年全国地级市在机器人、人工智能等…...
神经网络中之多类别分类:从基础到高级应用
神经网络中之多类别分类:从基础到高级应用 摘要 在机器学习领域,多类别分类是解决复杂问题的关键技术之一。本文深入探讨了神经网络在多类别分类中的应用,从基础的二元分类扩展到一对多和一对一分类方法。我们详细介绍了 softmax 函数的原理…...
破解工业3D可视化困局,HOOPS Visualize助力高效跨平台协作与交互!
一、当前3D可视化面临的痛点 (1)性能瓶颈 现有的许多3D可视化工具在处理大型复杂模型时往往力不从心。例如在航空航天、汽车制造等高端制造业,动辄涉及数以亿计的三角面片和海量的纹理细节。这些超大规模的模型在渲染时常常出现卡顿、延迟&…...
感知器准则感知器神经元模型——等价
不同的东西,很多刊物有误。但两者等价。 感知器神经元模型的误差反馈学习 y y y:期望值 y ^ \hat{y} y^:实际输出值 权重更新公式为: w i ← w i η ( y − y ^ ) x i w_i \leftarrow w_i \eta(y - \hat{y})x_i wi←wi…...
Qt学习Day0:Qt简介
0. 关于Qt Qt是C的实践课,之前在C中学习的语法可以有具体的应用场景。Qt的代码量很大,不要死记硬背,学会查询文档的能力更加重要。 建议提升一下相关单词的储备量: 1. Qt是什么? Qt是一个基于C语言的图形用户界面&a…...
JAVA设计模式——(十二)原型模式(Prototype Pattern)
JAVA设计模式——(十二)原型模式(Prototype Pattern) 介绍理解实现Email类测试 应用 介绍 用原型实例指定创建对象的种类,并且通过复制原型已有的对象用于创建新的对象。 理解 原型实例便是我们需要复制的类的实例&…...
C++命名空间
什么是命名空间 命名空间是一种用来避免命名冲突的机制,它可以将一段代码的名称隔离开,使其与其他代码的名称不冲突 简单来说,就是编译器检测到相同的名称的函数,变量,或者其他的相同名称的东西,也许会有疑问,怎么能出现相同的名称的变量呢.这就是C引入的…...
Hello Robot 推出Stretch 3移动操作机器人 提升开源与可用性
Stretch 3机器人是Hello Robot推出的新一代移动操作机器人,专注于提升开源开发与实际应用能力。它结合了先进的设计理念和工程技术,旨在为家庭任务和辅助技术提供智能化解决方案。通过优化硬件性能和软件兼容性,这款机器人不仅增强了灵活性&a…...
[Linux_69] 数据链路层 | Mac帧格式 | 局域网转发 | MTU MSS
目录 0.引入 1.以太网帧格式 2.重谈局域网转发的原理(基于协议) 小结 3.认识MTU 3.1MTU对IP协议的影响 3.2MTU对UDP协议的影响 3.3MTU对于TCP协议的影响 0.引入 在去年的这篇文章中,我们有对网络进行过一个概述[Linux#47][网络] 网络协议 | TCP/IP模型 | 以…...
I2C总线驱动开发:MPU6050应用
引言 I2C(Inter-Integrated Circuit)总线作为嵌入式系统中广泛使用的通信协议,在传感器、外设控制等领域扮演着重要角色。本文将深入探讨I2C总线的工作原理、Exynos4412平台裸机驱动实现、Linux内核中的I2C子系统架构,并以MPU605…...
15.命令模式:思考与解读
原文地址:命令模式:思考与解读 更多内容请关注:深入思考与解读设计模式 引言 在软件开发中,尤其是当系统涉及多个请求、操作或任务时,你是否遇到过这样的情况:每个操作都有自己的执行逻辑,且这些操作可能…...
2025年软件工程与数据挖掘国际会议(SEDM 2025)
2025 International Conference on Software Engineering and Data Mining 一、大会信息 会议简称:SEDM 2025 大会地点:中国太原 收录检索:提交Ei Compendex,CPCI,CNKI,Google Scholar等 二、会议简介 2025年软件开发与数据挖掘国际会议于…...
博客系统测试报告
文章目录 目录1. 项目背景2. 项目简介3. 测试工具4. 测试用例5. 功能测试6. 性能测试7. 弱网测试8. 自动化测试9. bug简述10. 测试结论 目录 项目背景项目简介测试工具测试用例功能测试性能测试弱网测试自动化测试bug简述测试结论 1. 项目背景 为了将平时自己写的笔记、知识…...
window 显示驱动开发-线程同步和 TDR
下图显示了 Windows 显示驱动程序模型 (WDDM) 中显示微型端口驱动程序的线程同步的工作原理 如果发生硬件超时,则会启动 超时检测和恢复 (TDR) 进程。 GPU 计划程序调用驱动程序的 DxgkDdiResetFromTimeout 函数,这将重置 GPU。 DxgkDdiResetFromTimeou…...
GEC6818蜂鸣器驱动开发
相关知识:Linux设备驱动开发 insmod 编译好的.ko文件后再运行beep_app.c编译完成的可执行文件即可使板子蜂鸣。 beep_drv.c: #include <linux/module.h> //包含了加载模块时需要使用的大量符号和函数声明 #include <linux/kernel.h> //包含了printk内…...
WPF MVVM入门系列教程(五、命令和用户输入)
🧭 WPF MVVM入门系列教程 一、MVVM模式介绍二、依赖属性三、数据绑定四、ViewModel五、命令和用户输入六、ViewModel案例演示 WPF中的命令模型 在WPF中,我们可以使用事件来响应鼠标和键盘动作。 但使用事件会具备一定的局限性,例如&#x…...
基于Jetson Nano与PyTorch的无人机实时目标跟踪系统搭建指南
引言:边缘计算赋能智能监控 在AIoT时代,将深度学习模型部署到嵌入式设备已成为行业刚需。本文将手把手指导读者在NVIDIA Jetson Nano(4GB版本)开发板上,构建基于YOLOv5SORT算法的实时目标跟踪系统,集成无人…...
创建简易个人关系图谱(Neo4j )
1. 启动 Neo4j 并进入 Neo4j Browser 确保 Neo4j 已启动,访问: http://localhost:7474/2. 创建人物节点(Person) (1) 创建 Alice CREATE (alice:Person {name: "Alice", age: 28, gender: "Female"}) RETUR…...
JavaScript 到命令和控制 (C2) 服务器恶意软件分析及防御
攻击始于一个经过混淆的JavaScript文件,该文件从开源服务中获取编码字符串以执行PowerShell脚本。然后,该脚本从一个IP地址和一个URL缩短器下载一个JPG图像和一个文本文件,这两个文件都包含使用隐写术嵌入的恶意MZ DOS可执行文件。这些有效载荷一旦执行,就会部署Stealer恶意…...
[原创](现代Delphi 12指南):[macOS 64bit App开发]: 如何自动打开“安全性与隐私“控制面板?
[作者] 常用网名: 猪头三 出生日期: 1981.XX.XX 企鹅交流: 643439947 个人网站: 80x86汇编小站 编程生涯: 2001年~至今[共24年] 职业生涯: 22年 开发语言: C/C++、80x86ASM、Object Pascal、Objective-C、C#、R、Python、PHP、Perl、 开发工具: Visual Studio、Delphi、XCode、…...
springboot微服务连接nacos超时
问题现象 java应用启动失败,查看日志,发现是连接Nacos超时,获取不到配置,导致dubbo注册失败,错误日志如下: 2025-05-01 14:50:08.973 ERROR [TW-172.29.245.61-9063-3] [com.alibaba.nacos.common.utils.…...
react-transition-group 在 React 18 及以上版本中的兼容性问题
出现问题 在React19中下载react-transition-group(4.4.5),正常导入使用: 出现下述报错: 报错原因 React18开始,已废弃findDOMNode ,而 react-transition-group 的 4.4.5 版本仍然使用了 findD…...
day17 天池新闻数据KMeans、DBSCAN 与层次聚类的对比
在数据分析中,聚类是一种常见的无监督学习方法,用于将数据划分为不同的组或簇。本文将通过news数据集(news.csv),使用 KMeans、DBSCAN 和层次聚类三种方法进行聚类分析,并对比它们的性能。 数据来源于天池 …...