深入MapReduce——计算模型设计
引入
通过引入篇,我们可以总结,MapReduce针对海量数据计算核心痛点的解法如下:
- 统一编程模型,降低用户使用门槛
- 分而治之,利用了并行处理提高计算效率
- 移动计算,减少硬件瓶颈的限制
优秀的设计,总会借鉴使用到前人总结的精华。
在MapReduce设计中,就有很多经典的设计模式的影子:
- 责任链模式,让每个组件发挥自己的作用,串联起来完成一个完整的分布式应用程序的执行。
- 模板方法模式,在责任链的基础上,又用了模板的形式来定义数据处理的基本流程架构。
- 策略模式,在模板方法的基础上,提供灵活的具体业务实现方式。
下面我们就深入了解一下,MapReduce这个所谓的通用计算模型,到底是如何设计落地的。
MapReduce计算模型设计
首先,我们要知道,任何通用的计算模型,本质都可以划分为输入->计算->输出三个模块。既然说MapReduce是一个通用的计算模型,那我们就来看看它是怎么设计实现的。
核心设计思路
我们先从核心设计思路方面入手,MapReduce的编程模型中的核心计算模块设计很简单,正如其名,分为Map和Reduce两个部分:
- Map负责“分”,即把复杂的任务分解为若干个“简单的任务”来并行处理。可以进行拆分的前提是这些小任务可以并行计算,彼此间几乎没有依赖关系。
- Reduce负责“合”,即对map阶段的结果进行全局汇总。
可以看到,这个计算模块的设计非常简单,下面我们看下在代码层面,它是如何基于这个核心思路,去提供输入,计算,输出的能力给用户的。
编程组件设计
在代码层面,MapReduce结合了分布式场景的特殊性,针对这三个模块对外提供了5个可编程组件,分别是InputFormat、Mapper、Partitioner、Reducer和OutputFormat。
下面我们分别介绍一下:
InputFormat
- 数据读取与分片:因为MapReduce是构建在HDFS上的,那要计算的数据肯定是以一个个Block块的形式,分散存储在不同的DataNode里。InputFormat 组件负责从各种数据源读取数据,并将数据切分成合适的分片(split),从而实现在多个计算节点上并行处理。例如,在处理大规模的文本数据时,InputFormat 可以按行或按固定大小对数据进行分片,使得每个 Mapper 任务可以独立处理一个数据分片,实现数据的并行读取和处理。
- 数据格式适配:不同的数据源可能有不同的数据格式,如文本格式、二进制格式、数据库记录格式等。InputFormat 能够将各种不同格式的数据转换为 MapReduce 可以处理的键值对形式,为后续的处理提供统一的输入格式。
InputFormat主要用于描述输入数据的格式,核心就是以下两件事:
- 数据切分:按照某个策略将输入数据切分成若干个split,以便确定Map Task个数以及对应的split。
- 为Mapper提供输入数据:给定某个split,通过创建读取数据的工具(RecordReader)来将其解析成一个个 key-value 对。
这种设计有点类似工厂方法,主要有以下好处:
- 解耦数据划分和读取过程:
通过这种设计,将输入数据的划分(InputFormat的职责)和具体的数据读取(RecordReader的职责)两个过程分开。这样可以让开发者独立地修改和扩展这两个部分。
例如,如果要支持一种新的数据格式,只需要创建一个新的InputFormat子类和对应的RecordReader,而不会影响到其他部分的代码。- 提高可维护性和可扩展性:
这种设计使得MapReduce框架能够方便地支持多种输入数据格式。对于不同的数据来源和格式,只需要实现相应的InputFormat和RecordReader组合。
比如,对于数据库数据、日志文件、二进制文件等不同类型的数据,都可以通过自定义的InputFormat和RecordReader来实现数据的有效处理。- 支持数据局部性优化:
InputFormat在划分数据分片时,可以考虑数据的存储位置等因素,使得RecordReader读取数据时能够更好地利用数据局部性。
例如,将在同一物理存储位置的数据划分到一个分片,这样可以减少数据传输开销,提高MapReduce的整体性能。其中文件切分算法在v1和v2版本有所区别:
- v1:splitSize = max{minSize, min{goalSize, blockSize}}
- v2:splitSize = max{minSize, min{maxSize, blockSize}}
新版本用 maxSize 替换了 goalSize ,可以更直接地对 splitSize 的上限进行严格控制。
例如,在处理一些对单个Map任务处理数据量上限有严格要求的场景(如资源有限的小型集群或者对任务响应时间敏感的场景),能够明确设置 maxSize ,避免出现因 goalSize 计算复杂而导致输入分片过大的情况。
在InputSplit切分方案确定后,会确定每个InputSplit的元数据信息。这通常由四部分组成:<file, start, length, hosts>,分别表示InputSplit所在的文件、起始位置、长度以及所在的host(节点)列表。
其中,前三项很容易确定,难点在于host列表的选择方法。
FileInputFormat设计了一个简单有效的启发式算法,核心就是尽量选择本地节点。
其实现主要考虑以下几点:
- 性能提升。通过尽量选择本地和机架本地的节点,可以尽可能减少网络带宽带来的瓶颈,如果能走本地,更是可以完全利用本地磁盘IO,避免网络传输带来的延迟。
- 资源优化利用。考虑节点的资源状况进行host选择,可以尽可能平衡各个节点的负载,并有效提升集群的吞吐能力。
- 增强容错。尽可能的选择本地,避免网络传输,能很好的降低数据丢失风险,并提高故障恢复效率。
Mapper
- 并行数据处理:Mapper 是 MapReduce 中实现并行计算的核心组件。对于大规模的数据处理任务,将数据分片后,每个 Mapper 任务在不同的计算节点上独立地对数据分片进行处理,实现了数据的并行处理,大大提高了处理效率。例如,在进行文本数据的词频统计时,每个 Mapper 可以对自己负责的数据分片中的文本进行单词拆分和初步计数。
- 数据转换与过滤:Mapper 可以对输入数据进行各种转换和过滤操作,将原始数据转换为更适合后续处理的中间表示形式。比如,可以在 Mapper 中对数据进行清洗、格式转换、提取关键信息等操作,为后续的聚合和分析做准备。
Partitioner
- 数据分区与分发:在分布式计算中,Mapper 任务的输出需要按照一定的规则分配到不同的 Reducer 任务中进行处理。Partitioner 组件负责根据键的特征将 Mapper 的输出数据划分到不同的分区,确保具有相同或相关键的数据能够被发送到同一个 Reducer 任务中,以便进行有效的聚合和处理。例如,在对大规模用户数据按用户 ID 进行统计分析时,Partitioner 可以根据用户 ID 的哈希值将数据分配到不同的 Reducer,使得同一用户的数据能够在同一个 Reducer 中进行处理。
- 负载均衡:通过合理的分区策略,Partitioner 可以实现数据在 Reducer 任务之间的均衡分配,避免某些 Reducer 任务处理的数据量过大,而其他 Reducer 任务闲置的情况,从而充分利用集群资源,提高整个系统的性能和效率。
Partitioner的作用是对Mapper产生的中间结果进行分区,以便将同一分组的数据交给同一个Reducer处理,它直接影响Reduce阶段的负载均衡。
MapReduce提供了两个Partitioner实现:HashPartitioner和TotalOrderPartitioner。
- HashPartitioner是默认实现,它是基于哈希值的分片方法实现的。
- TotalOrderPartitioner提供了一种基于区间的分片方法,通常用在数据全排序中。
关于全排序,通常容易想到的是归并排序,主要是利用二分去提升效率,其与一些简单的排序算法如插入,冒泡,选择相比,核心就在于没有浪费比较行为。
但由于作业只能有一个ReduceTask,因而Reduce阶段会成为作业的瓶颈。为了提高全局排序的性能和扩展性, MapReduce提供了TotalOrderPartitioner。它能够按照大小将数据分成若干个区间(分片),并保证后一个区间的所有数据均大于前一个区间数据。
TotalOrderPartitioner的全排序的步骤如下:
- 数据采样。
在Client端通过采样获取分片的分割点。(Hadoop自带了几个采样算法,IntercalSampler、RandomSampler、SplitSampler等。)- Map阶段。
本阶段涉及两个组件,分别是Mapper和Partitioner。其中,Mapper可选用不同的Mapper实现类,如IdentityMapper,直接将输入数据输出,但Partitioner必须选TotalOrderPartitioner,它将步骤1中获取的分割点保存到trie树(前缀树,字典树)中以便快速定位任意一个记录所在的区间,这样,每个MapTask产生R(Reduce Task个数)个区间,且区间之间有序。- Reduce阶段。
每个Reducer对分配到的区间数据进行局部排序,最终得到全排序数据。从以上步骤可以看出,基于TotalOrderPartitioner全排序的效率跟key分布规律和采样算法有直接关系;key值分布越均匀且采样越具有代表性,则Reduce Task负载越均衡,全排序效率越高。
TotalOrderPartitioner有两个典型的应用实例:TeraSort和HBase批量数据导入。
- TeraSort是Hadoop自带的一个应用程序实例。它曾在TB级数据排序基准评估中赢得第一名,而TotalOrderPartitioner正是从该实例中提炼出来的。
- HBase是一个构建在Hadoop之上的NoSQL数据仓库。它以Region为单位划分数据,Region内部数据有序(按key排序),Region之间也有序。一个MapReduce全排序作业的R个输出文件正好可对应HBase的R个Region。
Reducer
- 数据聚合与合并:Reducer 主要用于对 Mapper 输出的经过分区和排序的数据进行聚合和合并操作。在许多分布式计算场景中,需要对数据进行汇总、统计、合并等操作,Reducer 能够将具有相同键的值进行合并和计算,得到最终的结果。如在词频统计中,Reducer 将各个 Mapper 输出的相同单词的计数进行累加,得到最终的单词出现频率。
- 复杂数据分析:对于一些需要全局视角或多轮处理的复杂数据分析任务,Reducer 可以在收到所有相关数据后进行综合处理。例如,在计算数据的平均值、中位数,或者进行数据的关联和整合等操作时,Reducer 可以根据具体的业务逻辑对数据进行进一步的分析和处理,得到最终的分析结果。
OutputFormat
- 数据存储与持久化:在 MapReduce 任务完成后,需要将最终的计算结果存储到合适的位置,以便后续的查询和使用。OutputFormat 组件负责将 Reducer 的输出数据按照指定的格式和存储方式进行存储,如将结果存储为文本文件、二进制文件、数据库表等。
- 结果格式定制:不同的应用场景可能对结果的输出格式有不同的要求,OutputFormat 允许用户根据实际需求定制输出结果的格式和内容,或者按照特定的文件结构和数据组织方式进行存储,方便与其他系统或工具进行集成和交互。
任务架构设计
用户通过借助前面MapReduce提供的编程组件,实现了业务逻辑以后,会将程序打包提交到Hadoop集群中,这里就涉及如何去调度执行任务。
如下图所示,是MRv1的架构设计(MRv2,也就是Yarn,可以看后面深入Yarn篇的内容)
我们来介绍一下里面的涉及的核心模块:
Client
用户编写的MapReduce程序通过Client提交到JobTracker端;同时,用户可通过Client提供的一些接口查看作业运行状态。
在Hadoop内部用Job(任务)表示MapReduce程序。一个MapReduce程序可对应若干个Job,而每个作业会被分解成若干个 Map/Reduce Task。
JobTracker
JobTracker主要负责资源监控和作业调度。
JobTracker监控所有TaskTracker与作业的健康状况,一旦发现失败情况后,其会将相应的任务转移到其他节点;同时,JobTracker会跟踪任务的执行进度、资源使用量等信息,并将这些信息告诉任务调度器,而调度器会在资源出现空闲时,选择合适的任务使用这些资源。
TaskTracker
TaskTracker会周期性地通过Heartbeat(心跳),将本节点上资源的使用情况和任务的运行进度汇报给JobTracker,同时接收JobTracker发送过来的命令并执行相应的操作(如启动新任务、杀死任务等)。
TaskTracker使用slot来等量划分本节点上的资源量。
slot是MapReduce针对CPU、内存等计算资源的一个抽象,它代表集群中计算节点上的一个基本资源分配单位。
其设计的核心目的,是为了控制同时运行的任务数量,并有效地管理和分配集群的计算资源,避免资源过度使用或闲置。
一个Task获取到一个slot后才有机会运行,而Hadoop调度器的作用就是将各个TaskTracker上的空闲slot分配给Task使用。slot分为Map slot和Reduce slot两种,分别供Map Task和Reduce Task使用。TaskTracker通过slot数目(可配置参数)限定Task的并发度。
Task
Task分为Map Task和Reduce Task两种,均由TaskTracker启动。
从深入HDFS篇章,我们知道HDFS会以固定大小的block为基本单位存储数据,而对于MapReduce而言,其处理单位是Split。这是一个逻辑概念,它只包含一些元数据信息,比如数据起始位置、数据长度、数据所在节点等。它的划分方法完全由用户自己决定。但需要注意的是,split的多少决定了Map Task的数目,因为每个split会交由一个Map Task处理。
任务调度流程
MapReduce任务的调度流程如下:
Job提交
- 客户端配置与提交:用户编写实现了
Mapper
和Reducer
接口的 Java 程序,设置作业的各项参数,如输入输出路径、Mapper 和 Reducer 类等。接着,客户端调用JobClient
类将作业提交给 JobTracker。 - 作业检查:在提交作业前,客户端会检查作业的输入输出路径是否合法等,同时计算输入数据的分片信息。
Job初始化
- JobTracker 接收作业:JobTracker 接收到客户端提交的作业后,为作业分配一个唯一的作业 ID,创建一个
JobInProgress
对象来跟踪该作业的执行进度。 - 资源和任务初始化:JobTracker 会将作业相关信息(如作业配置、输入分片信息等)存储在 HDFS 上,同时为作业的 Map 和 Reduce 任务分配资源。
Job分配
- Map 任务分配:JobTracker 根据输入数据的分片情况,将 Map 任务分配给 TaskTracker。一般会尽量将 Map 任务分配到存储有对应输入分片数据的节点上,以实现数据的本地化处理,减少数据传输开销。
- Reduce 任务分配:JobTracker 会根据作业配置中指定的 Reduce 任务数量,将 Reduce 任务分配给合适的 TaskTracker。Reduce 任务的分配没有数据本地化的要求。
Map 阶段
- TaskTracker 接收任务:TaskTracker 从 JobTracker 接收分配的 Map 任务后,为该任务启动一个新的 Java 进程。
- 数据读取:该 Java 进程从 HDFS 读取对应的输入分片数据,将其解析成键值对形式,作为
Mapper
的输入。 - Map 函数执行:
Mapper
对输入的键值对执行用户自定义的map
方法,生成一系列中间键值对。这些中间键值对会先被写入到内存缓冲区。 - 溢写磁盘:当内存缓冲区达到一定阈值(默认 80%)时,会触发溢写操作。在溢写过程中,数据会按照键进行分区和排序(默认使用哈希分区),并将排序后的结果写入本地磁盘。如果配置了 Combiner,还会在溢写前对相同键的值进行局部合并。
- 多次溢写合并:如果在 Map 处理过程中发生了多次溢写,最终会将这些溢写文件合并成一个大的分区且排序好的文件。
Shuffle 阶段
- 数据复制:Reduce 任务启动后,会从各个 Map 任务所在的 TaskTracker 上复制属于自己分区的数据。
- 归并排序:Reduce 任务将复制过来的数据进行归并排序,确保相同键的值相邻排列。这个过程会将来自不同 Map 任务的相同分区的数据合并在一起。
Reduce 阶段
- TaskTracker 接收并执行:TaskTracker 从 JobTracker 接收分配的 Reduce 任务后,为其启动一个新的 Java 进程。
- Reduce 函数执行:
Reducer
对排序好的数据执行用户自定义的reduce
方法,对相同键的值进行聚合处理,生成最终的输出结果。 - 结果输出:
Reducer
将处理后的结果写入到 HDFS 等指定的输出存储系统中。
Job完成清理
- 状态更新:当所有的 Map 任务和 Reduce 任务都成功完成后,JobTracker 将作业的状态标记为成功完成。
- 资源清理:JobTracker 会清理作业运行过程中产生的临时文件和其他相关资源。同时,TaskTracker 也会清理本地磁盘上的中间数据文件。
总结
今天梳理了MapReduce这个通用计算模型的总体设计落地思路,后面我们基于源码去进一步深入它是如何实现的。
相关文章:
深入MapReduce——计算模型设计
引入 通过引入篇,我们可以总结,MapReduce针对海量数据计算核心痛点的解法如下: 统一编程模型,降低用户使用门槛分而治之,利用了并行处理提高计算效率移动计算,减少硬件瓶颈的限制 优秀的设计,…...
在Spring Boot中使用SeeEmitter类实现EventStream流式编程将实时事件推送至客户端
😄 19年之后由于某些原因断更了三年,23年重新扬帆起航,推出更多优质博文,希望大家多多支持~ 🌷 古之立大事者,不惟有超世之才,亦必有坚忍不拔之志 🎐 个人CSND主页——Mi…...
Qt实践:一个简单的丝滑侧滑栏实现
Qt实践:一个简单的丝滑侧滑栏实现 笔者前段时间突然看到了侧滑栏,觉得这个抽屉式的侧滑栏非常的有趣,打算这里首先尝试实现一个简单的丝滑侧滑栏。 首先是上效果图 (C,GIF帧率砍到毛都不剩了) QProperty…...
基于ESP32-IDF驱动GPIO输出控制LED
基于ESP32-IDF驱动GPIO输出控制LED 文章目录 基于ESP32-IDF驱动GPIO输出控制LED一、点亮LED3.1 LED电路3.2 配置GPIO函数gpio_config()原型和头文件3.3 设置GPIO引脚电平状态函数gpio_set_level()原型和头文件3.4 代码实现并编译烧录 一、点亮LED 3.1 LED电路 可以看到&#x…...
OpenCV文字绘制支持中文显示
OpenCV版本:4.4 IDE:VS2019 功能描述 OpenCV绘制文本的函数putText()不支持中文的显示,网上很多方法推荐的都是使用FreeType来支持,FreeType是什么呢?FreeType的官网上有介绍 FreeType官网 https://www.freetype.or…...
jenkins-k8s pod方式动态生成slave节点
一. 简述: 使用 Jenkins 和 Kubernetes (k8s) 动态生成 Slave 节点是一种高效且灵活的方式来管理 CI/CD 流水线。通过这种方式,Jenkins 可以根据需要在 Kubernetes 集群中创建和销毁 Pod 来执行任务,从而充分利用集群资源并实现更好的隔离性…...
消息队列篇--基础篇(消息队列特点,应用场景、点对点和发布订阅工作模式,RabbmitMQ和Kafka代码示例等)
1、消息队列的介绍 消息(Message)是指在应用之间传送的数据,消息可以非常简单,比如只包含文本字符串,也可以更复杂,可能包含嵌入对象。 消息队列(Message Queue,简称MQ)…...
Jetpack架构组件学习——使用Glance实现桌面小组件
基本使用 1.添加依赖 添加Glance依赖: // For AppWidgets supportimplementation "androidx.glance:glance-appwidget:1.1.0"// For interop APIs with Material 3implementation "androidx.glance:glance-material3:1.1.0"// For interop APIs with Mater…...
go读取excel游戏配置
1.背景 游戏服务器,配置数据一般采用csv/excel来作为载体,这种方式,策划同学配置方便,服务器解析也方便。在jforgame框架里,我们使用以下的excel配置格式。 然后可以非常方便的进行数据检索,例如ÿ…...
Linux系统下速通stm32的clion开发环境配置
陆陆续续搞这个已经很久了。 因为自己新电脑是linux系统无法使用keil,一开始想使用vscode里的eide但感觉不太好用;后面想直接使用cudeide但又不想妥协,想趁着这个机会把linux上的其他单片机开发配置也搞明白;而且非常想搞懂cmake…...
快慢指针及原理证明(swift实现)
目录 链表快慢指针一、快慢指针基本介绍二、快慢指针之找特殊节点1.删除链表的倒数第k个结点题目描述解题思路 2.链表的中间节点题目描述解题思路 三、快慢指针之环形问题1.判断环形链表题目描述解题思路 2.判断环形链表并返回入环节点题目描述解题思路 3.变种——判断快乐数题…...
web前端3--css
注意(本文一切代码一律是在vscode中书写) 1、书写位置 1、行内样式 //<标签名 style"样式声明"> <p style"color: red;">666</p> 2、内嵌样式 1、style标签 里面写css代码 css与html之间分离 2、css属性:值…...
一文大白话讲清楚webpack基本使用——5——babel的配置和使用
文章目录 一文大白话讲清楚webpack基本使用——5——babel的配置和使用1. 建议按文章顺序从头看,一看到底,豁然开朗2. babel-loader的配置和使用2.1 针对ES6的babel-loader2.2 针对typescript的babel-loader2.3 babel配置文件 一文大白话讲清楚webpack基…...
Python自动化运维:一键掌控服务器的高效之道
《Python OpenCV从菜鸟到高手》带你进入图像处理与计算机视觉的大门! 解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 在互联网和云计算高速发展的今天,服务器数量的指数增长使得手动运维和管理变得异常繁琐。Python凭借其强大的可读性和丰富的生态系统,成为…...
基于quartz,刷新定时器的cron表达式
文章目录 前言基于quartz,刷新定时器的cron表达式1. 先看一下测试效果2. 实现代码 前言 如果您觉得有用的话,记得给博主点个赞,评论,收藏一键三连啊,写作不易啊^ _ ^。 而且听说点赞的人每天的运气都不会太差&…...
HTML常用属性
HTML标签的常见属性包括许多不同的功能,可以为元素提供附加信息或控制元素的行为。以下是一些常见的属性及其解释: 1. src 描述:src(source)属性指定一个资源的路径,通常用于图像、音频、视频等标签。常见…...
在 Babylon.js 中使用 Gizmo:交互式 3D 操作工具
在 3D 应用程序中,交互式操作对象(如平移、旋转、缩放)是一个常见的需求。Babylon.js 提供了一个强大的工具——Gizmo,用于在 3D 场景中实现这些功能。本文将介绍如何在 Babylon.js 中使用 Gizmo,并展示如何通过代码实…...
蓝桥杯练习日常|递归-进制转换
蓝桥云课760数的计算 一、递归 题目: 我的解题代码: #include <iostream> using namespace std; int sum0; int main() {// 请在此输入您的代码int n;cin>>n;int fun(int n);fun(n); cout<<sum<<\n;return 0; } // void fu…...
LabVIEW滤波器选择与参数设置
在信号处理应用中,滤波器是去除噪声、提取目标信号的重要工具。LabVIEW 提供多种类型的滤波器(如低通、高通、带通、带阻),用户需要根据采样频率、信号特性和应用需求合理选择滤波器类型及参数设置。本文以 采样率 100kHz…...
【c语言日寄】Vs调试——新手向
【作者主页】siy2333 【专栏介绍】⌈c语言日寄⌋:这是一个专注于C语言刷题的专栏,精选题目,搭配详细题解、拓展算法。从基础语法到复杂算法,题目涉及的知识点全面覆盖,助力你系统提升。无论你是初学者,还是…...
C#中的Timers.Timer使用用法及常见报错
System.Timers.Timer 是一个基于服务器的计时器,它可以在应用程序中定期触发事件。这个计时器特别适合用于多线程环境,并且不应该与用户界面(UI)直接交互。在 ASP.NET 中,通常使用 System.Timers.Timer 来处理周期性的任务。 主要使用步骤&am…...
chrome小插件:长图片等分切割
前置条件: 安装有chrome谷歌浏览器的电脑 使用步骤: 1.打开chrome扩展插件 2.点击管理扩展程序 3.加载已解压的扩展程序 4.选择对应文件夹 5.成功后会出现一个扩展小程序 6.点击对应小程序 7.选择图片进行切割,切割完成后会自动保存 代码…...
mysql数据被误删的恢复方案
文章目录 一、使用备份恢复二、使用二进制日志(Binary Log)三、使用InnoDB表空间恢复四、使用第三方工具预防措施 数据误删是一个严重的数据库管理问题,但通过合理的备份策略和使用适当的恢复工具,可以有效地减少数据丢失的风险…...
K8S-Pod资源清单的编写,资源的增删改查,镜像的下载策略
1. Pod资源清单的编写 1.1 Pod运行单个容器的资源清单 ##创建工作目录 mkdir -p /root/manifests/pods && cd /root/manifests/pods vim 01-nginx.yaml ##指定api版本 apiVersion: v1 ##指定资源类型 kind: Pod ##指定元数据 metadata:##指定名称name: myweb ##用户…...
Unity Line Renderer Component入门
Overview Line Renderer 组件是 Unity 中用于绘制连续线段的工具。它通过在三维空间中的两个或两个以上的点的数组,并在每个点之间绘制一条直线。可以绘制从简单的直线到复杂的螺旋线等各种图形。 1. 连续性和独立线条 连续性:Line Renderer 绘制的线条…...
计算机工程:解锁未来科技之门!
计算机工程与应用是一个充满无限可能性的领域。随着科技的迅猛发展,计算机技术已经深深渗透到我们生活的方方面面,从医疗、金融到教育,无一不在彰显着计算机工程的巨大魅力和潜力。 在医疗行业,计算机技术的应用尤为突出。比如&a…...
翻译:How do I reset my FPGA?
文章目录 背景翻译:How do I reset my FPGA?1、Understanding the flip-flop reset behavior2、Reset methodology3、Use appropriate resets to maximize utilization4、Many options5、About the author 背景 在写博客《复位信号的同步与释放(同步复…...
在Unity中使用大模型进行离线语音识别
文章目录 1、Vosk下载下载vosk-untiy-asr下载模型在项目中使用语音转文字音频转文字2、whisper下载下载unity项目下载模型在unity中使用1、Vosk 下载 下载vosk-untiy-asr Github链接:https://github.com/alphacep/vosk-unity-asr 进不去Github的可以用网盘 夸克网盘链接:h…...
SpringBoot+Vue使用Echarts
前言 在vue项目中使用echarts,本次演示是使用vue2 1 前端准备 echarts官网: https://echarts.apache.org/zh/index.html 官网提供了基本的使用说明和大量的图表 1.1 下载echarts 执行命令 npm install echarts 直接这样执行很可能会失败,…...
【QT】-explicit关键字
explicit explicit 是一个 C 关键字,用于修饰构造函数。它的作用是防止构造函数进行隐式转换。 为什么需要 explicit? 在没有 explicit 的情况下,构造函数可以用于隐式类型转换。这意味着,如果你有一个接受某种类型的参数的构造…...
docker: Device or resource busy
(base) [rootbddx-vr-gpu-bcc2 /]#rm -rf /ssd1/docker/overlay2/8d96a51e3fb78e434fcf2b085e952adcc82bfe37485d427e1e017361a277326d/ rm: cannot remove ‘/ssd1/docker/overlay2/8d96a51e3fb78e434fcf2b085e952adcc82bfe37485d427e1e017361a277326d/merged’: Device or re…...
Vue - toRefs() 和 toRef() 的使用
一、toRefs() 在 Vue 3 中,toRefs()可以将响应式对象的属性转换为可响应的 refs。主要用于在解构响应式对象时,保持属性的响应性。 1. 导入 toRefs 函数 import { toRefs } from vue;2. 将响应式对象的属性转换为 ref const state reactive({count: 0,message:…...
(2024,MLLM,Healthcare,综述)多模态学习是否已在医疗保健领域实现通用智能?
Has Multimodal Learning Delivered Universal Intelligence in Healthcare? A Comprehensive Survey 目录 0. 摘要 1. 简介 5. MLLM 5.1 模态编码器与跨模态适配器 5.1.1 图像编码器 (Image Encoder) 5.1.2 语言模型 (Language Model) 5.1.3 跨模态适配器 (Cross-moda…...
css命名规范——BEM
目录 引言 BEM是什么? 块Block 元素Element 修饰语Modifier BEM解决了哪些问题? 在流行框架的组件中使用 BEM 格式 实战 认识设计图 如何使用当前的css规范正确命名? 引言 css样式类命名难、太难了,难于上青天,这个和js变量命名还不一样。看看项目中五花八门的样…...
使用PHP函数 “is_object“ 检查变量是否为对象类型
在PHP中,变量可以保存不同类型的值,包括整数、字符串、数组、布尔值等等。其中,对象是一种特殊的数据类型,用于封装数据和方法。在处理PHP代码中,我们经常需要检查一个变量是否为对象类型,以便进行相应的处…...
Golang:使用DuckDB查询Parquet文件数据
本文介绍DuckDB查询Parquet文件的典型应用场景,掌握DuckDB会让你的产品分析能力更强,相反系统运营成本相对较低。为了示例完整,我也提供了如何使用Python导出MongoDB数据。 Apache Parquet文件格式在存储和传输大型数据集方面变得非常流行。最…...
Moretl FileSync增量文件采集工具
永久免费: <下载> <使用说明> 我们希望Moretl FileSync是一款通用性很好的文件日志采集工具,解决工厂环境下,通过共享目录采集文件,SMB协议存在的安全性,兼容性的问题. 同时,我们发现工厂设备日志一般为增量,为方便MES,QMS等后端系统直接使用数据,我们推出了增量采…...
消息队列篇--原理篇--Pulsar(Namespace,BookKeeper,类似Kafka甚至更好的消息队列)
Apache Pulusar是一个分布式、多租户、高性能的发布/订阅(Pub/Sub)消息系统,最初由Yahoo开发并开源。它结合了Kafka和传统消息队列的优点,提供高吞吐量、低延迟、强一致性和可扩展的消息传递能力,适用于大规模分布式系…...
linux 扩容
tmpfs tmpfs 82M 0 82M 0% /run/user/1002 tmpfs tmpfs 82M 0 82M 0% /run/user/0 [输入命令]# fdisk -lu Disk /dev/vda: 40 GiB, 42949672960 bytes, 83886080 sectors Units: sectors of 1 * 512 512 bytes Sector size (logi…...
数据表中的数据查询
文章目录 一、概述二、简单查询1.列出表中所有字段2.“*”符号表示所有字段3.查询指定字段数据4.DISTINCT查询 三、IN查询四、BETWEEN ADN查询1.符合范围的数据记录查询2.不符合范围的数据记录查询 五、LIKE模糊查询六、对查询结果排序七、简单分组查询1.统计数量2.统计计算平均…...
深入了解 Java split() 方法:分割字符串的利器
Java 提供的 split() 方法是 String 类中一个常用的工具,它可以将一个字符串根据指定的分隔符切割成多个子字符串,并以字符串数组的形式返回。这个方法常用于字符串的处理、数据解析等场景。本文将详细介绍 Java 中 split() 方法的使用方式,并…...
Ubuntu 安装 docker 配置环境及其常用命令
Docker 安装与配置指南 本文介绍如何在 Ubuntu 系统上安装 Docker,解决权限问题,配置 Docker Compose,代理端口转发,容器内部代理问题等并进行相关的优化设置。参考官方文档:Docker 官方安装指南 一、安装 Docker 1…...
Android Studio安装配置
一、注意事项 想做安卓app和开发板通信,踩了大坑,Android 开发不是下载了就能直接开发的,对于新手需要注意的如下: 1、Android Studio版本,根据自己的Android Studio版本对应决定了你所兼容的AGP(Android…...
leetcode 面试经典 150 题:有效的括号
链接有效的括号题序号20题型字符串解法栈难度简单熟练度✅✅✅ 题目 给定一个只包括 ‘(’,‘)’,‘{’,‘}’,‘[’,‘]’ 的字符串 s ,判断字符串是否有效。 有效字符串需满足: 左括号必须…...
C语言 指针_野指针 指针运算
野指针: 概念:野指针就是指针指向的位置是不可知的(随机的、不正确的、没有明确限制的) 指针非法访问: int main() {int* p;//p没有初始化,就意味着没有明确的指向//一个局部变量不初始化,放…...
【HarmonyOS之旅】基于ArkTS开发(二) -> UI开发之常见布局
目录 1 -> 自适应布局 1.1 -> 线性布局 1.1.1 -> 线性布局的排列 1.1.2 -> 自适应拉伸 1.1.3 -> 自适应缩放 1.1.4 -> 定位能力 1.1.5 -> 自适应延伸 1.2 -> 层叠布局 1.2.1 -> 对齐方式 1.2.2 -> Z序控制 1.3 -> 弹性布局 1.3.1…...
java基础学习——jdbc基础知识详细介绍
引言 数据的存储 我们在开发 java 程序时,数据都是存储在内存中的,属于临时存储,当程序停止或重启时,内存中的数据就会丢失,我们为了解决数据的长期存储问题,有以下解决方案: 通过 IO流书记&…...
第十五届蓝桥杯大赛软件赛省赛C/C++ 大学 B 组
第十五届的题目在规定时间内做出了前5道,还有2道找时间再磨一磨。现在把做的一些思路总结如下: 题1:握手问题 问题描述 小蓝组织了一场算法交流会议,总共有 50人参加了本次会议。在会议上,大家进行了握手交流。按照惯例…...
基于JAVA的微信点餐小程序设计与实现(LW+源码+讲解)
专注于大学生项目实战开发,讲解,毕业答疑辅导,欢迎高校老师/同行前辈交流合作✌。 技术范围:SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容:…...
2K320Hz显示器哪个好?
2K320Hz显示器哪个好?320Hz这种高刷新率的显示器确实很少见,那究竟哪个牌子哪个型号更适合你呢? 1.HKC G27H4Pro - 2K320Hz显示器哪个好 外观设计 - HKC G27H4Pro 2K320Hz显示器 三面微边框超震撼:采用三面微边框设计࿰…...