Spark RPC 学习总结
前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站:https://www.captainai.net/dongkelun
前言
本文从API层面学习总结Spark RPC,暂不涉及源码分析。
Spark 通信历史
最开始: Akka
Spark 1.3: 开始引入Netty,为了解决大块数据(如Shuffle)的传输问题
Spark 1.6:支持配置使用 Akka 或者 Netty。
Spark 2:完全废弃Akka,全部使用Netty
Akka 是一个用 Scala 编写的库,用于简化编写容错的、高可伸缩性的 Java 和 Scala 的 Actor 模型应用。
Spark 借鉴Akka 通过 Netty 实现了类似的简约版的Actor 模型
废弃Akka的原因
https://issues.apache.org/jira/plugins/servlet/mobile#issue/SPARK-5293
主要原因是解决用户的Spark Application中akka版本和Spark内置的akka版本冲突的问题。比如,用户开发的Spark Application中用到了Spray框架,Spray依赖的akka版本跟Spark的不一致就会导致冲突:
- 很多Spark用户也使用Akka,但是由于Akka不同版本之间无法互相通信,这就要求用户必须使用跟Spark完全一样的Akka版本,导致用户无法升级Akka。
- Spark的Akka配置是针对Spark自身来调优的,可能跟用户自己代码中的Akka配置冲突。
- Spark用的Akka特性很少,这部分特性很容易自己实现。同时,这部分代码量相比Akka来说少很多,debug比较容易。如果遇到什么bug,也可以自己马上fix,不需要等Akka上游发布新版本。而且,Spark升级Akka本身又因为第一点会强制要求用户升级他们使用的Akka,对于某些用户来说是不现实的。
参考:https://www.zhihu.com/question/61638635
RpcEnv
Rpc环境,RpcEndpoint
需要在 RpcEnv
中注册一个名称来接收消息。
先看源码中是如何创建 RpcEnv
val securityMgr = new SecurityManager(conf)val rpcEnv = RpcEnv.create(SYSTEM_NAME, host, port, conf, securityMgr)def create(name: String,host: String,port: Int,conf: SparkConf,securityManager: SecurityManager,clientMode: Boolean = false): RpcEnv = {create(name, host, host, port, conf, securityManager, 0, clientMode)}def create(name: String,bindAddress: String,advertiseAddress: String,port: Int,conf: SparkConf,securityManager: SecurityManager,numUsableCores: Int,clientMode: Boolean): RpcEnv = {val config = RpcEnvConfig(conf, name, bindAddress, advertiseAddress, port, securityManager,numUsableCores, clientMode)new NettyRpcEnvFactory().create(config)}
本次测试用的代码
def createRpcEnv(conf: SparkConf,name: String,port: Int,clientMode: Boolean = false): RpcEnv = {val config = RpcEnvConfig(conf, name, "localhost", "localhost", port,new SecurityManager(conf), 0, clientMode)new NettyRpcEnvFactory().create(config)}
clientMode: 是否客户端模式,默认false,默认会启动一个 NettyServer,具体在 TransportServer.init 中实现,可参考上篇文章。如果设置为true,则不启动服务,只作为一个客户端。
port: 为0时,会随机绑定一个端口号,这一点是Netty本身实现的,如果非0,则按照指定的端口绑定,但是要求端口号范围为[1024,65536),如果端口已占用,则尝试端口号+1,默认重试16次,可以通过配置 spark.port.maxRetries 修改最大重试次数 。
RpcEndpoint
很多都是RpcEndpoint的子类,如:Master
、Worker
、ClientEndpoint
、DriverEndpoint
、CoarseGrainedExecutorBackend
、YarnCoarseGrainedExecutorBackend
、YarnDriverEndpoint
、YarnSchedulerEndpoint
等。
RpcEndpoint
的生命周期:constructor -> onStart -> receive* -> onStop 。也就是首先会调用 onStart 方法。
RpcEndpoint
首先必须通过调用 rpcEnv
.setupEndpoint
才能使用
setupEndpoint
使用名称注册 RpcEndpoint
并返回其 RpcEndpointRef
def setupEndpoint(name: String, endpoint: RpcEndpoint): RpcEndpointRef
RpcEndpointRef
RpcEndpointRef
:远程 RpcEndpoint
的引用。RpcEndpointRef
是线程安全的
有两种方法可以返回RpcEndpointRef
一个是上面提到的setupEndpoint
,另外一个则是 setupEndpointRef
/*** Retrieve the [[RpcEndpointRef]] represented by `uri` asynchronously.*/def asyncSetupEndpointRefByURI(uri: String): Future[RpcEndpointRef]/*** Retrieve the [[RpcEndpointRef]] represented by `uri`. This is a blocking action.*/def setupEndpointRefByURI(uri: String): RpcEndpointRef = {defaultLookupTimeout.awaitResult(asyncSetupEndpointRefByURI(uri))}/*** Retrieve the [[RpcEndpointRef]] represented by `address` and `endpointName`.* This is a blocking action.*/def setupEndpointRef(address: RpcAddress, endpointName: String): RpcEndpointRef = {setupEndpointRefByURI(RpcEndpointAddress(address, endpointName).toString)}
setupEndpoint
返回的是本地 RpcEndpoint
的引用,主要作用是使用名称注册
setupEndpointRef
根据远程地址和名称返回 RpcEndpoint
的引用。例如:
// Worer 中返回 Master 的引用
val masterEndpoint = rpcEnv.setupEndpointRef(masterAddress, Master.ENDPOINT_NAME)
// CoarseGrainedExecutorBackend 中获取 Driver 的引用
driver = fetcher.setupEndpointRefByURI(arguments.driverUrl)
rpcEnv.asyncSetupEndpointRefByURI(driverUrl)
方法调用
- rpcEnv.setupEndpoint : 调用 rpcEndpoint.onStart
- rpcEndpointRef.send(没有返回值) : 调用 rpcEndpoint.receive
- rpcEndpointRef.ask*(有返回值): 调用 rpcEndpoint.receiveAndReply (rpcEndpointRef.ask* 最终都是在 NettyRpcEnv.askAbortable中实现)
- rpcEnv.stop(rpcEndpointRef) : 调用 rpcEndpoint.onStop
测试代码
完整代码:https://gitee.com/dongkelun/java-learning/tree/master/scala-learning/src/main/scala/org/apache/spark/rpc
本地测试
package org.apache.spark.rpcimport org.apache.spark.{SparkConf, SparkEnv}
import org.scalatest.concurrent.Eventually.{eventually, interval, timeout}import scala.concurrent.duration._object RpcLocalTest extends RpcParent {def main(args: Array[String]): Unit = {val conf = new SparkConf()val env = createRpcEnv(conf, "local", 8000)@volatile var message: String = nullval rpcEndpointRef = env.setupEndpoint("send-locally", new RpcEndpoint {override val rpcEnv = envoverride def onStart(): Unit = {println("start hello endpoint")}override def receive = {case msg: String =>println(msg)message = msg}})rpcEndpointRef.send("hello")eventually(timeout(5.seconds), interval(10.milliseconds)) {assert("hello" == message)}if (env != null) {env.shutdown()}SparkEnv.set(null)}
}
远程测试
RpcRemoteServer
package org.apache.spark.rpcimport org.apache.spark.SparkConfimport java.util.concurrent.CountDownLatchobject RpcRemoteServer extends RpcParent {def main(args: Array[String]): Unit = {val shutdownLatch = new CountDownLatch(1)val env = createRpcEnv(new SparkConf(), "local", 8000)println(s"地址:${env.address}")env.setupEndpoint("ask-remotely", new RpcEndpoint {override val rpcEnv = envoverride def onStart(): Unit = {println("onStart 被调用")}override def receiveAndReply(context: RpcCallContext): PartialFunction[Any, Unit] = {case msg: String =>context.reply(msg)}})shutdownLatch.await()}
}
RpcRemoteTest
package org.apache.spark.rpcimport org.apache.spark.SparkConfimport java.util.concurrent.CountDownLatchobject RpcRemoteTest extends RpcParent {def main(args: Array[String]): Unit = {val shutdownLatch = new CountDownLatch(1)val anotherEnv = createRpcEnv(new SparkConf(), "remote-client", 0, clientMode = true)println(s"地址:${anotherEnv.address}")val rpcEndpointRef = anotherEnv.setupEndpointRef(new RpcAddress("localhost", 8000), "ask-remotely")val reply = rpcEndpointRef.askSync[String]("hello Remote")println(reply)shutdownLatch.await()}
}
这里需要注意
RpcRemoteServer
中RpcEndpoint
的名称为 ask-remotely ,我们在RpcRemoteTest
中不仅需要对应的IP、端口号,而且名称也一定要对应准确。
更多测试
完整代码:https://gitee.com/dongkelun/java-learning/blob/master/scala-learning/src/test/scala/org/apache/spark/rpc/RpcEnvSuite.scala
如测试 onStart 和 onStop
test("onStart and onStop") {val stopLatch = new CountDownLatch(1)val calledMethods = mutable.ArrayBuffer[String]()val endpoint = new RpcEndpoint {override val rpcEnv = envoverride def onStart(): Unit = {println("onStart 被调用")calledMethods += "start"}override def receive: PartialFunction[Any, Unit] = {case msg: String =>}override def onStop(): Unit = {println("onStop 被调用")calledMethods += "stop"
// stopLatch.countDown()}}println("调用setupEndpoint前")val rpcEndpointRef = env.setupEndpoint("start-stop-test", endpoint)println("调用setupEndpoint后")println("调用stop前")env.stop(rpcEndpointRef)println("调用stop后")stopLatch.await(10, TimeUnit.SECONDS)assert(List("start", "stop") === calledMethods)}
总结
- 首先用
RpcEnv
.create
创建RpcEnv
,这里底层会通过 Netty 创建一个 Server, 绑定对应的端口,这里也可以只使用客户端模式不创建 Server - 然后具体通信的实体类是在
RpcEndpoint
中实现,比如Master
、Worker
等都是RpcEndpoint
,RpcEndpoint
首先必须通过调用rpcEnv
.setupEndpoint
才能使用。 RpcEndpoint
的方法调用都是通过它对应引用RpcEndpointRef
实现,rpcEnv
.setupEndpoint
会返回本地引用,setupEndpointRef
根据远程地址和名称返回远程RpcEndpoint
的引用,注意这里名称一定要对应准确。RpcEndpoint
的方法调用顺序onStart
->receive*
->onStop
,其中onStart
做一些初始化的准备,setupEndpoint
会触发onStart
方法;receive
方法没有返回值,receiveAndReply
方法有返回值,分别通过rpcEndpointRef
.send
和rpcEndpointRef
.ask*
触发,ask方法分同步调用和异步调用;而onStop
则处理服务停止后的操作,通过rpcEnv
.stop
触发。
相关文章:
Spark RPC 学习总结
前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站:https://www.captainai.net/dongkelun 前言 本文从API层面学习总结Spark RPC,暂不涉及源码分析。 Spark 通信历史 最开始: …...
JAVA安全—JWT攻防Swagger自动化Druid泄露
前言 依旧是Java安全的内容,今天主要是讲JWT这个东西,JWT之前讲过了,是Java中特有的身份校验机制,原理我就不再多说了,主要是看看它的安全问题,至于Swagger和Druid顺便讲一下。 Druid泄露 Druid是阿里巴…...
深度学习核函数
一、核函数的基本概念 核函数在机器学习中具有重要应用价值,常用于支持向量机(SVM)等算法中。 核函数是面试中经常被考到的知识点,对于找工作和实际数据转换都有重要作用。 二、数据建模与核函数的作用 数据越多,可…...
【神经网络基础】
目录 一、神经网络的构成 1.1什么是神经网络? 1.2 激活函数 1.2.1 Sigmoid 1.2.2 Tanh 1.2.3 ReLU 1.2.4 softmax 1.2.5 其他激活函数 1.2.6 选择激活函数 1.3 参数初始化 1.4 模型构建 二、损失函数 2.1 分类问题 2.1.1多分类(多分类交叉…...
一些面试常见问题及其回答参考
1、请你自我介绍一下你自己? 回答提示:一般人回答这个问题过于平常,只说姓名、年龄、爱好、工作经验,这些在简历上都有。其实,企业最希望知道的是求职者能否胜任工作,包括:最强的技能、最深入研…...
[JavaScript] 深入理解流程控制结构
文章目录 1. **if-else 语句**基本语法:示例:扩展:else if 2. **switch-case 语句**基本语法:示例:注意事项: 3. **for 循环**基本语法:示例:扩展:for-in 和 for-of 4. *…...
Mysql常见问题处理集锦
Mysql常见问题处理集锦 root用户密码忘记,重置的操作(windows上的操作)MySQL报错:ERROR 1118 (42000): Row size too large. 或者 Row size too large (> 8126).场景:报错原因解决办法 详解行大小限制示例:内容来源于网…...
高级java每日一道面试题-2025年01月19日-框架篇[Mybatis篇]-MyBatis 中见过什么设计模式 ?
如果有遗漏,评论区告诉我进行补充 面试官: MyBatis 中见过什么设计模式 ? 我回答: 1. 工厂模式(Factory Pattern) 定义:工厂模式是一种创建型模式,它提供了一种创建对象的最佳方式,将对象创建过程抽象化ÿ…...
C++,设计模式,【目录篇】
文章目录 1. 简介2. 设计模式的分类2.1 创建型模式(Creational Patterns):2.2 结构型模式(Structural Patterns):2.3 行为型模式(Behavioral Patterns): 3. 使用设计模式…...
C/C++内存管理(超详解)
目录 1.C/C内存分布 2.C语言动态内存管理 2.1 malloc 2.2 free 2.3 calloc 2.4 realloc 3.C动态内存管理 3.1new/delete操作内置类型 3.2new/delete操作自定义类型 3.3operator new与operator delete函数 3.4定位new表达式(placement-new) 1.C/C内存分布 内存中是如…...
【前端】用OSS增强Hexo的搜索功能
文章目录 前言配置 _config.fluid.yml云端实时更新 local-search.xml解决 OSS.Bucket 的跨域问题 前言 原文地址:https://blog.dwj601.cn/FrontEnd/Hexo/hexo-enhance-local-search-with-oss/ 考虑到某著名云服务商提供的云服务器在两年的 99 计划后续费价格高达四…...
智慧校园平台中的信息处理与技术应用
随着信息技术的迅速发展,智慧校园平台已经成为现代教育领域的重要组成部分。智慧校园平台不仅能够提高教学效率,还能够改善学生的学习体验,以及优化学校的管理流程。为了实现这些目标,信息处理技术在智慧校园平台的应用中扮演了至…...
Spring MVC(一)
RestController RestController 是由 Controller 和 ResponseBody 两个注解构成的。 Spring 启动的时候会扫描所有包含 Controller 或者 RestController 注解的类,创建出对外的接口,这样外界就可以从这里与服务器实现交互,如果没有这个注解…...
【王树森搜索引擎技术】概要01:搜索引擎的基本概念
1. 基本名词 query:查询词SUG:搜索建议文档:搜索结果标签/筛选项 文档单列曝光 文档双列曝光 2. 曝光与点击 曝光:用户在搜索结果页上看到文档,就算曝光文档点击:在曝光后,用户点击文档&…...
imbinarize函数用法详解与示例
一、函数概述 众所周知,im2bw函数可以将灰度图像转换为二值图像。但MATLAB中还有一个imbinarize函数可以将灰度图像转换为二值图像。imbinarize函数是MATLAB图像处理工具箱中用于将灰度图像或体数据二值化的工具。它可以通过全局或自适应阈值方法将灰度图像转换为二…...
ThinkPHP 8的一对多关联
【图书介绍】《ThinkPHP 8高效构建Web应用》-CSDN博客 《2025新书 ThinkPHP 8高效构建Web应用 编程与应用开发丛书 夏磊 清华大学出版社教材书籍 9787302678236 ThinkPHP 8高效构建Web应用》【摘要 书评 试读】- 京东图书 使用VS Code开发ThinkPHP项目-CSDN博客 编程与应用开…...
医工交叉合作信息汇总,第三期名单分享,近期需要联合申请基金以及课题合作的老师/同学重点关注一下!|合作信息·25-01-17
小罗碎碎念 之前出过两期医工交叉领域合作信息的汇总推送,最近一直没顾上这事,现在重新捡起来,并且把需求向所有的粉丝公开,直接在后台回复“合作信息”就可以获取表格。 截至目前为止,共收集了92条合作信息…...
深度学习中的张量 - 使用PyTorch进行广播和元素级操作
深度学习中的张量 - 使用PyTorch进行广播和元素级操作 元素级是什么意思? 元素级操作在神经网络编程中与张量的使用非常常见。让我们从一个元素级操作的定义开始这次讨论。 一个_元素级_操作是在两个张量之间进行的操作,它作用于各自张量中的相应元素…...
浅谈云计算20 | OpenStack管理模块(下)
OpenStack管理模块(下) 五、存储管理5.1 存储管理概述 5.2 架构设计5.2.1 Cinder块存储架构5.2.2 Swift对象存储架构 六、网络管理6.1 网络管理概述6.2 架构解析6.2.1 Neutron网络服务架构6.2.2 网络拓扑架构 6.3 原理与流程6.3.1 网络创建原理6.3.2 网络…...
GitLab集成Jira
GitLab与Jira集成的两种方式 GitLab 提供了两种 Jira 集成,即Jira议题集成和Jira开发面板集成,可以配置一个或者两个都配置。 具体集成步骤可以参考官方文档Jira 议题集成(极狐GitLab文档)和Jira 开发面板集成(极狐G…...
如何用selenium来链接并打开比特浏览器进行自动化操作(1)
前言 本文是该专栏的第76篇,后面会持续分享python爬虫干货知识,记得关注。 本文,笔者将基于“比特浏览器”,通过selenium来实现链接并打开比特浏览器,进行相关的“自动化”操作。 值得一提的是,在本专栏之前,笔者有详细介绍过“使用selenium或者pyppeteer(puppeteer)…...
Docker私有仓库管理工具Registry
Docker私有仓库管理工具Registry 1 介绍 Registry是私有Docker仓库管理工具,Registry没有可视化管理页面和完备的管理策略。可借助Harbor、docker-registry-browser完成可视化和管理。Harbor是由VMware开发的企业级Docker registry服务。docker-registry-browser是…...
《Hands_On_LLM》8.1 语义搜索和 RAG 概述(Semantic Search and RAG)
说明 接下来的这三篇文章是《On Large Language Models》的第8章:语义搜索和检索增强生成(Retrieval-Augmented Generation)的翻译。 概述 搜索是最早被业界广泛采用的语言模型应用之一。在开创性论文《BERT:用于语言理解的深度…...
C++实现设计模式---迭代器模式 (Iterator)
迭代器模式 (Iterator) 迭代器模式 是一种行为型设计模式,它提供了一种方法,顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示。 意图 提供一种方法,可以顺序访问一个容器对象中的元素,而无需暴露其…...
skywalking的使用
面试常问的面试题: 你们的服务监控怎么做的? 其实就可以回答skywalking,skywalking是一个开源的分布式追踪与性能监视平台,特别适用于微服务架构、云原生环境以及基于容器(如Docker、Kubernetes)的应用部…...
【C语言系列】深入理解指针(1)
前言 总所周知,C语言中指针部分是非常重要的,这一件我们会介绍指针相关的内容,当然后续我还会出大概4篇与指针相关的文章,来深入的讲解C语言指针部分,希望能够帮助到指针部分薄弱或者根本不会的程序员们,后…...
医院挂号就诊系统设计与实现(代码+数据库+LW)
摘 要 传统办法管理信息首先需要花费的时间比较多,其次数据出错率比较高,而且对错误的数据进行更改也比较困难,最后,检索数据费事费力。因此,在计算机上安装医院挂号就诊系统软件来发挥其高效地信息处理的作用&#…...
Mysql 主从复制原理及其工作过程,配置一主两从实验
主从原理:MySQL 主从同步是一种数据库复制技术,它通过将主服务器上的数据更改复制到一个或多个从服务器,实现数据的自动同步。 主从同步的核心原理是将主服务器上的二进制日志复制到从服务器,并在从服务器上执行这些日志中的操作…...
verilog笔记1
1. 阻塞赋值 阻塞赋值,顾名思义即在一个 always 块中,后面的语句会受到前语句的影响,具体来说就是在同一个always 中,一条阻塞赋值语句如果没有执行结束,那么该语句后面的语句就不能被执行,即被“阻塞”。也…...
人工智能之数学基础:线性代数中的线性相关和线性无关
本文重点 在线性代数的广阔领域中,线性相关与线性无关是两个核心概念,它们对于理解向量空间、矩阵运算、线性方程组以及人工智能等问题具有至关重要的作用。 定义与直观理解 当存在一组不全为0的数x1,x2,...,xn使得上式成立的时候,那么此时我们可以说向量组a1,a2...,an…...
Flask简介与安装以及实现一个糕点店的简单流程
目录 1. Flask简介 1.1 Flask的核心特点 1.2 Flask的基本结构 1.3 Flask的常见用法 1.3.1 创建Flask应用 1.3.2 路由和视图函数 1.3.3 动态URL参数 1.3.4 使用模板 1.4 Flask的优点 1.5 总结 2. Flask 环境创建 2.1 创建虚拟环境 2.2 激活虚拟环境 1.3 安装Flask…...
Ubuntu22.04安装paddle GPU版本
文章目录 确立版本安装CUDA与CUDNN安装paddle 确立版本 查看官网信息,确立服务版本:https://www.paddlepaddle.org.cn/documentation/docs/zh/2.6/install/pip/linux-pip.html 安装CUDA与CUDNN 通过nvidia-smi查看当前显卡驱动版本: 通过…...
读《SQL经典实例》学数据库(系列一)
目录 友情提醒第一章、数据库简述1.1)数据库简述1.2)常见的数据库软件1.3)MySQL数据库安装 第二章、SQL语句分类2.1)操作数据仓库/数据表:DDL2.1.1)创建数据仓库/数据表2.1.2)删除数据仓库/数据表2.1.3&…...
Android系统开发(一):AOSP 架构全解析:开源拥抱安卓未来
引言 当我们手握智能手机,流畅地滑动屏幕、切换应用、欣赏动画时,背后其实藏着一套庞大且精密的开源系统——Android AOSP(Android Open Source Project)。这套系统不仅是所有安卓设备的根基,也是系统开发者的终极 pl…...
git系列之revert回滚
1. Git 使用cherry-pick“摘樱桃” step 1: 本地切到远程分支,对齐要对齐的base分支,举例子 localmap git pull git reset --hard localmap 对应的commit idstep 2: 执行cherry-pick命令 git cherry-pick abc123这样就会将远程…...
【统计的思想】假设检验(一)
假设检验是统计学里的重要方法,同时也是一种“在理想与现实之间观察求索”的测试活动。假设检验从概率的角度去考察理想与现实之间的关系,籍此来缓解测试可信性问题。 我们先来看一个例子。民航旅客服务系统,简称PSS系统,有一种业…...
Linux 管道操作
Linux 管道操作 在 Linux 中,管道(Pipe)是一个非常强大且常用的功能,它允许将一个命令的输出直接传递给另一个命令作为输入,从而能够高效地处理和分析数据。管道在多个命令之间建立数据流,减少了文件的读写…...
Rust 数据类型详解
一、标量类型(Scalar Types) 标量类型代表一个单独的值。Rust 中有四大基本标量类型:整数(integer)、浮点数(floating-point number)、布尔(boolean)和字符(…...
(十四)WebGL纹理坐标初识
纹理坐标是 WebGL 中将 2D 图像(纹理)应用到 3D 物体表面的重要概念。在 WebGL 中,纹理坐标通常使用一个二维坐标系,称为 uv 坐标,它们决定了纹理图像如何映射到几何体上。理解纹理坐标的核心就是明白它们如何将二维纹…...
青少年CTF练习平台 EasyMD5解题思路
题目 EasyMD5 PHP弱类型/弱等于的判断 翻译 上传之后网页提示:Not a PDF! angry!!! get out from my page 修改文件后缀为pdf 再次上传,答案出来了 s878926199a s155964671a 成功获取flag...
二叉搜索树(TreeMapTreeSet)
文章目录 1.概念2.二叉搜索树的底层代码实现(1)首先构建二叉树(2)实现插入功能;(3)实现查找(4)删除(重点) 3.TreeMap 1.概念 TreeMap&TreeSet都是有序的集合都是基于二叉搜索树来实现的 二叉搜索树:是一种特殊的二叉树 若左子…...
鸿蒙动态路由实现方案
背景 随着CSDN 鸿蒙APP 业务功能的增加,以及为了与iOS、Android 端统一页面跳转路由,以及动态下发路由链接,路由重定向等功能。鸿蒙动态路由方案的实现迫在眉睫。 实现方案 鸿蒙版本动态路由的实现原理,类似于 iOS与Android的实…...
matlab实现一个雷达信号处理的程序,涉及到对原始图像的模拟、加权、加噪以及通过迭代算法对图像进行恢复和优化处理
clc clear close all load scene3.mat %加载原始图像,自己设计 设计为一个300*400的矩阵 300是距离向长度,400是方位向长度 Map_ori = scene3; [M,N_K] = size(Map_ori);figure imagesc(scene3) v = 100; %机载速度,单位m/s bandwidth = 30*1e6; …...
设置 Git 默认推送不需要输入账号和密码【Ubuntu、SSH】
如何设置 Git 默认推送不需要输入账号和密码 在使用 Git 管理代码时,许多开发者会遇到每次推送(push)或拉取(fetch)代码时都需要输入 GitHub 或 GitLab 等远程仓库的账号和密码的情况。虽然设置了用户名和电子邮件信息…...
【深度学习】Pytorch:导入导出模型参数
PyTorch 是深度学习领域中广泛使用的框架,熟练掌握其模型参数的管理对于模型训练、推理以及部署非常重要。本文将全面讲解 PyTorch 中关于模型参数的操作,包括如何导出、导入以及如何下载模型参数。 什么是模型参数 模型参数是指深度学习模型中需要通过…...
ABP - 缓存模块(1)
ABP - 缓存模块(1) 1. 与 .NET Core 缓存的关系和差异2. Abp 缓存的使用2.1 常规使用2.2 非字符串类型的 Key2.3 批量操作 3. 额外功能 1. 与 .NET Core 缓存的关系和差异 ABP 框架中的缓存系统核心包是 Volo.Abp.Caching ,而对于分布式缓存…...
【unity进阶篇】unity如何实现跨平台及unity最优最小包体打包方式(.NET、Mono和IL2CPP知识介绍)
考虑到每个人基础可能不一样,且并不是所有人都有同时做2D、3D开发的需求,所以我把 【零基础入门unity游戏开发】 分为成了C#篇、unity通用篇、unity3D篇、unity2D篇。 【C#篇】:主要讲解C#的基础语法,包括变量、数据类型、运算符、…...
5-1 创建和打包AXI Interface IP
创建和打包AXI Interface IP的前流程和后流程 step 1 : 选择类型 1: 将当前的工程打包成IP 2: 将当前的BD工程打包成IP 3: 将指定的源码打包成IP 4: 创建一个新的AXI 接口IP 其中3和4是比较常用的,本次…...
【C++】如何从源代码编译红色警戒2地图编辑器
【C】如何从源代码编译红色警戒2地图编辑器 操作视频视频中的代码不需要下载三方库,已经包含三方库。 一、运行效果:二、源代码来源及编程语言:三、环境搭建:安装红警2安装VS2022下载代码,源代码其实不太多,…...
HRNet,Deep High-Resolution Representation Learning for Visual Recognition解读
论文、代码和ppt地址:HRNet。代码地址: hrnet 本文通过paper解读和代码实例以及onnx模型的分析,来说明hrnet模型。 摘要——高分辨率表征对于诸如人体姿态估计、语义分割和目标检测等对位置敏感的视觉问题至关重要。现有的最先进框架首先通过一个子网&…...