深入浅出RPC:选取适合自己的RPC

文章目录

  • 1、RPC概念&&背景
    • 1.1、RPC背景
  • 1.2、RPC是什么,什么时候需要用到?
  • 2、进程间的通信 - IPC与RPC
    • 2.1、什么是IPC
    • 2.2、IPC与RPC联系
  • 3、RPC的实现
    • 3.1、RPC实现的基本思路
    • 3.2、RPC实现的扩展方向
  • 4、RPC的选择


1、RPC概念&&背景

1.1、RPC背景

RPC远程调用的概念最早可以追溯到20世纪80年代,当时Sun Microsystems公司提出了一种名为ONC RPC(Open Network Computing Remote Procedure Call)的协议,用于在NFS(Network File System)中进行远程过程调用。此后,RPC成为了分布式系统中的一种重要通信方式,被广泛应用于各种分布式系统和应用中。

可以看出RPC这个概念已经超过四十年时间,但在今天仍然可以在各种论坛、技术网站上时常遇见“什么是 RPC?”、“如何评价某某 RPC 技术?”、“RPC 更好还是 REST 更好?”之类的问题,仍然“每天”都有新的不同形状的 RPC 轮子被发明制造出来。而对于快速发展的互联网技术,这无异是稀奇的。而这主要的原因主要还是很多论坛上的开发这对于RPC 本身解决什么问题、怎么解决这些问题、为什么要这样解决都或多或少存在认知模糊,接下来本文会一一介绍。

1.2、RPC是什么,什么时候需要用到?

RPC(Remote Procedure Call)是一种远程过程调用协议,它允许一个程序调用另一个程序中的函数或方法,而无需了解底层的网络细节。因此RPC的出现使得分布式系统中的各个组件之间的通信变得更加简单、高效和可靠。

并且RPC协议提供了更加丰富和灵活的功能,例如支持不同的序列化格式、支持异步调用、支持自定义的错误处理等等(如:gRPC、Apache Thrift、CORBA…等),而平常普通的http请求等就很难实现。因此在为了需要自定义上述的的功能,亦或者在分布式系统中需要进行组件的通信时,就需要rpc。(但是这里RPC底层的传输协议其实是可以用HTTP协议的,这种方式被称为HTTP-RPC或者HTTP-based RPC。在这种方式中,HTTP协议被用来传输RPC请求和响应数据。)

上述提到HTTP协议,其实也可以扩展一下,对于分布式中的通信除了常见RPC协议,能够更快的提高数据传输效率,对于常见的HTTP协议来说也有对应的架构,这种架构则是我们常说的restful。
rest(Representational State Transfer)是一种基于HTTP协议的架构风格,用于设计和构建分布式系统。它强调系统中的资源和状态的概念,并使用HTTP动词(GET、POST、PUT、DELETE等)对资源进行操作,并使用URI(Uniform Resource Identifier)标识资源的位置。它相对于RPC的特点更多为:

  • 基于HTTP协议: 使用HTTP协议进行通信,HTTP动词表示对资源的操作,URI表示资源的位置。
  • 资源和状态: 将系统中的所有内容抽象为资源,每个资源都有一个URI标识和一个状态。
  • 无状态: 每个请求都是独立的,不需要保存上下文信息。
  • 可缓存: 支持缓存机制,提高性能和可扩展性。
    因此rest的侧重点更多是灵活、易扩展、易缓存的场景。更多想了解的可以去看看凤凰架构中有对此更深的描述。

因此,在实现分布式系统中的通信时,想要提高网络传输效率使用专门的RPC协议会更加合适和可靠。但是而RPC具体是怎么能支持这些功能,还得从RPC的实现谈起。


2、进程间的通信 - IPC与RPC

在介绍RPC实现之前先来介绍下IPC,因为RPC在实现思想和背景上很多来自于IPC。

2.1、什么是IPC

IPC是一种在同一台计算机上的进程间通信方式,常见的IPC技术包括管道、消息队列、共享内存、信号量、套接字接口(Socket)等。IPC的主要作用是实现进程间数据的传输和共享,使得不同进程之间可以进行协调和互操作。

2.2、IPC与RPC联系

就如同开始强调的一样,rpc最初的目标只是为了让计算机能够跟调用本地方法一样去调用远程方法!! 在分布式系统中,不同组件之间可能需要进行本地进程间通信和远程过程调用,**这时就可以同时使用IPC和RPC来实现。**例如,在分布式系统中,一个组件可能需要调用另一个组件的本地函数或方法,这时可以使用IPC来实现本地进程间通信。而当两个组件位于不同的节点上时,就可以使用RPC来实现远程过程调用。此外,RPC的实现方式通常是基于网络协议和框架,而网络协议和框架中也使用了IPC的技术。例如,在TCP/IP协议中,就使用了IPC中的套接字(socket)技术来实现进程间通信。

这边要注意一个点在早先由于 Socket 是各个操作系统都有提供的标准接口,完全有可能把远程方法调用的通信细节隐藏在操作系统底层,从应用层面上看来可以做到远程调用与本地的进程间通信在编码上完全一致。但这这种透明的调用方法,容易造成滥用,而造成通信是无成本的假象,而导致了分布式系统下性能的下降。当然现在回来看通信是无成本的假象肯定是错的,毕竟分布式系统架构应是容错,一致性,高性能的trade off,而通信代价本就是性能中的一环。而在当时RPC这种观却是很盛行,对此Andrew Tanenbaum 教授曾发表了论文《A Critique of The Remote Procedure Call Paradigm》进行质疑,以及最终CM 和 Sun 院士Peter Deutsch、套接字接口发明者Bill Joy、Java 之父James Gosling等一众在 Sun Microsystems 工作的大佬们共同总结了现在分布式系统很著名的:通过网络进行分布式运算的八宗罪(8 Fallacies of Distributed Computing),有兴趣的可以去了解。

3、RPC的实现

3.1、RPC实现的基本思路

由上文可以知晓RPC的实现一开始是为了像本地方法那样调用远程方法,但是实际上远程调用中的 “远程” 的概念注定会有很多实现上的分歧,这也是本文的第二个内容,如何解决这些问题。
首先远程调用的大致链路其实都是大同小异的,大概如下图(图源来自论文Implementing Remote Procedure Calls):
在这里插入图片描述
由图可以分解出以下几个步骤:

  • 定义接口和数据类型: 首先需要定义接口和数据类型,包括接口方法名、参数类型、返回值类型等。这些定义通常使用IDL(Interface Definition Language)语言来描述,以便于不同语言之间的调用和序列化。
  • 生成代码: 根据接口和数据类型的定义,生成客户端和服务器端的代码。这些代码通常包括序列化和反序列化方法、网络传输方法等,以便于客户端和服务器端进行数据交换和通信。
  • 实现服务器端(被调用方): 在服务器端实现接口方法,根据客户端请求进行相应的处理,并将处理结果返回给客户端。服务器端还需要实现服务注册和发现、负载均衡、容错等机制,以提高系统的可用性和可靠性。
  • 实现客户端(调用方): 在客户端调用远程接口方法,将参数序列化并通过网络发送给服务器端,然后等待服务器端返回处理结果,并将结果反序列化后返回给调用方。客户端还需要实现服务发现和选择、负载均衡、重试等机制,以提高系统的可用性和可靠性。
  • 集成框架: 将生成的代码和实现的服务器端、客户端集成到RPC框架中,并提供相应的API和工具,以便于开发人员使用和集成。
  • 测试和优化: 对实现的RPC框架进行测试和优化,包括性能测试、功能测试、安全测试等,以确保系统的稳定性、可靠性和安全性。

3.2、RPC实现的扩展方向

除了上面几个基本步骤,不同的RPC通常会在下列三个方向,去进行自己扩展。

  • 如何表示数据 - 数据的序列化与反序列化的实现
  • 如何传递数据- 确定数据传输时所采用的格式与规则( Wire Protocol )
  • 如何统一方法调用- 确定请求端/接受端方法调用的方式

3.2.1 如何表示数据

对于如何表示数据的做法是将交互双方所涉及的数据转换为某种事先约定好的中立数据流格式来进行传输,将数据流转换回不同语言中对应的数据类型来进行使用,而这就是序列化协议的初衷,除此之外设计一个好的序列化协议还有以下几个作用:

  • 跨语言和跨平台: 在分布式系统中,不同计算机可能使用不同的编程语言和操作系统,因此需要一种通用的数据格式,以便于跨语言和跨平台进行数据传输和交互。序列化协议可以将数据转换为一种通用的格式,使得不同计算机之间可以正确地对数据进行编码和解码。
  • 数据压缩: 在网络传输过程中,数据的大小会影响网络带宽和传输速度,因此需要对数据进行压缩。序列化协议可以将数据压缩为更小的二进制格式,从而减少网络传输的数据量,提高网络传输效率。
  • 数据安全: 在网络传输过程中,数据可能会被篡改或窃取,因此需要对数据进行加密和解密。序列化协议可以将数据转换为二进制格式,并进行加密和解密操作,从而保证数据的安全性和完整性。
    数据可读性:在调试和排错过程中,需要查看网络传输的数据内容,以便于定位问题。序列化协议可以将数据转换为文本格式,使得数据更易于读取和理解。

也因此每种RPC都有其对应使用的序列化协议:

  • ONC RPC : External Data Representation (XDR)
  • gRPC: 使用Protocol Buffers作为默认的序列化协议,也支持JSON。
  • Java RMI : Java Remote Message Protocol(JRMP,也支持RMI-IIOP)
  • Web Service : XML Serialization
  • CORBA: 支持多种序列化协议,包括GIOP(General Inter-ORB Protocol)、IIOP(Internet Inter-ORB Protocol)、RMI-IIOP和TAO。
  • Apache Thrift: 支持多种序列化协议,包括二进制、压缩二进制、JSON、可扩展二进制和结构化数据格式(TJSON、TSV)。

3.2.2 如何传递数据
数据的传输并不是简单的约定好数据格式进行序列化反序列化就行,还需要考虑数据传输时需要的额外的信息譬如异常、超时、安全、认证、授权、事务,等等,都可能产生双方需要交换信息的需求,对这一类的行为则被称作Wire Protocol。而常见的Wire Protocol协议主要有:

  • 两端都是http endpoint可以直接HTTP
  • Java RMI 的Java Remote Message Protocol(JRMP,也支持RMI-IIOP)
  • CORBA 的Internet Inter ORB Protocol(IIOP,是 GIOP 协议在 IP 协议上的实现版本)
  • DDS 的Real Time Publish Subscribe Protocol(RTPS)
  • Web Service 的Simple Object Access Protocol(SOAP)
  • Wire Protoco通常是指应用层协议和传输层协议之间的协议。在OSI模型中,Wire Protocol可以被看作是第5层(会话层)和第6层(表示层)之间的协议。在TCP/IP协议栈中,Wire Protocol通常被认为是传输层协议和应用层协议之间的协议,例如HTTP、SMTP等应用层协议使用TCP或UDP作为传输层协议进行数据传输。
  • 而上面提到的序列化反序列化序列化和反序列化通常是在应用层协议中实现的,因为它们是将高级语言对象转换为字节流的过程,这些对象通常在应用程序中定义和使用。例如,在Java中,序列化和反序列化通常使用Java对象序列化(Java Object Serialization)API来实现。

3.2.3 如何统一方法调用

  • 在本地方法调用中方法调用并不是太大的问题,编译器或者解释器会根据语言规范,将调用的方法签名转换为进程空间中子过程入口位置的指针,但是远程调用可能则要考虑不同的语言,则在实现上需要考虑不同语言之间方法签名的差异。由于不同语言的方法调用方式和参数传递方式可能不同,因此在RPC中需要使用一种通用的方法来描述方法签名和参数列表,以便在客户端和服务器之间进行方法调用。

  • 通常情况下,RPC实现会使用一种IDL(Interface Description Language,接口定义语言)来描述方法签名和参数列表,以便在客户端和服务器之间进行交互。IDL通常使用一种中立的语言来描述接口,例如CORBA中使用的IDL语言。在IDL中,可以定义接口、方法、参数类型、返回类型等信息,以便在不同语言之间进行交互。

  • 在实际的RPC实现中,通常会使用代码生成工具来根据IDL文件自动生成客户端和服务器端的代码。这些生成的代码包含了方法调用的代码,以及将参数和返回值进行序列化和反序列化的代码,以便在不同语言之间进行方法调用。这样可以大大简化RPC实现的过程,同时也可以保证不同语言之间的方法调用是正确的。

值得一提的是IDL的实现有点类似寻找一个分布式id一样。如确定方法直接规定一个唯一的、在任何机器上都不重复的编号,调用的时候则不管这个方法签名是如何定义的,直接通过编号确定方法。而这个唯一但绝不重复的编码方案,这就是后来的UUID。

其他用于表示方法的协议还有:

  • Android 的Android Interface Definition Language(AIDL)
  • CORBA 的OMG Interface Definition Language(OMG IDL)
  • Web Service 的Web Service Description Language(WSDL)
  • JSON-RPC 的JSON Web Service Protocol(JSON-WSP)

因此其实RPC的很多实现思路都是可以从IPC上得到借鉴或启发,但是rpc随着发展早已不满足于简单的进行通信,早已还需要考量性能、通用等方面。

4、RPC的选择

经过的几十年的时间,rpc的发展并不是趋向一个统一的未来,因为随着多样化的需求、不断的技术发展和创建、以及需要跨语言和跨平台支持甚至包括生态的推动。现在的rpc已经成为一个百家争鸣之势如 RMI(Sun/Oracle)、Thrift(Facebook/Apache)、Dubbo(阿里巴巴/Apache)、gRPC(Google)、Motan1/2(新浪)、Finagle(Twitter)、brpc(百度/Apache)、.NET Remoting(微软)、Arvo(Hadoop)、JSON-RPC 2.0(公开规范,JSON-RPC 工作组)等等。

接下来会简单根据不同的场景建议选择不同的rpc框架并介绍其优缺点:

  • gRPC:
    • 优点: 高性能、低延迟、跨语言支持、多种通信协议、流式传输支持。
    • 适用场景: 大规模分布式系统、跨语言通信、需要高性能和低延迟的实时通信场景。
  • Dubbo:
    • 优点: 丰富的服务治理功能、高度可扩展、支持大规模分布式系统、灵活的扩展机制。
    • 适用场景: Java应用程序的分布式服务、需要服务治理功能的场景。
  • Apache Thrift:
    • 优点: 跨语言支持、多种序列化方式、代码生成工具、高效的数据传输。
    • 适用场景: 跨语言通信、大数据分析、需要高效数据传输的场景。
  • ZeroMQ:
    • 优点: 轻量级、快速、异步消息传递、支持多种通信模式。
    • 适用场景: 轻量级通信、需要快速和高效的消息传递的场景。
  • MQTT:
    • 优点: 轻量级、低功耗、支持发布-订阅模式。
    • 适用场景: 物联网应用、需要低功耗和轻量级通信的场景。
  • WebRTC:
    • 优点: 支持实时音视频通信、低延迟、Web浏览器原生支持。
    • 适用场景: 实时音视频通信、Web端的实时通信IM场景。

而大家平时搭建业务则一般就可以通过业务上所需要的通信特点进行去选择,例如如果是im场景下 WebRTC去提高通讯效率,如果是大型电商那种分布式系统的话可以使用gRPC,java则使用Dubbo,如果是搭建数据中心考虑跨语言则去选择Apache Thrift,当然如果最简单平常的也可以直接利用Springcloud中的Spring Cloud Netflix项目实现的多种组件,如Ribbon、Feign、Hystrix等,用于构建分布式系统中的服务通信和治理。

而想具体区分优缺点的则是可以从上面实现提到的序列化协议、传输协议实现入手:

  • gRPC:
    传输协议: 默认使用HTTP/2作为底层传输协议,HTTP/2支持多路复用、头部压缩和服务器推送等特性,可以提高性能和效率。
    序列化协议:默认使用Protocol Buffers(protobuf)作为序列化协议,protobuf是一种高效、紧凑的二进制序列化协议,适合高性能通信。

  • Dubbo:
    传输协议: Dubbo支持多种传输协议,包括dubbo、rmi、http、hessian、webservice等,可以根据需求选择合适的协议。
    序列化协议: Dubbo同样支持多种序列化协议,如hessian、json、protobuf等,可以根据需求选择合适的协议。

  • Apache Thrift:
    传输协议: Thrift支持多种传输协议,包括二进制、压缩、JSON、XML等,可以根据需求选择合适的协议。
    序列化协议: Thrift支持多种序列化协议,包括二进制、JSON、compact等,可以根据需求选择合适的协议。

  • ZeroMQ:
    传输协议: ZeroMQ是一种异步通信库,支持多种传输协议,如TCP、IPC、inproc等,可以根据需求选择合适的协议。
    序列化协议: ZeroMQ并不关心消息的格式和内容,用户可以自行定义消息的序列化方式。

  • WebRTC:
    传输协议: WebRTC是一种用于实时通信的开放式技术,通常使用UDP作为底层传输协议,可以实现较低的延迟和更好的实时性。
    序列化协议: WebRTC通常使用JSON或二进制格式来序列化和传输数据。

而这些使用的协议则会决定其底层存在的风险,并且在选择时也可以适当考虑是否社区还在维护,更新,生态是否完善等…

以下提供几个常见的rpc的地址:

  • grpc中文文档:https://doc.oschina.net/grpc
  • grpc官方文档:https://grpc.io/docs/
  • dubbo官方文档:https://cn.dubbo.apache.org/zh-cn/overview/home/
  • Apache Thrift官方文档:https://thrift.apache.org/
  • WebRTC官方文档:https://webrtc.org/?hl=zh-cn

如有不足,欢迎指正~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/231367.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【 AI 两步实现文本 转 语音】

基于hugging face 中 XTTS-v2 模型做文本转语音,此模型支持17种语言 1.登录hugging face 官网 https://huggingface.curated.co/ 或者 https://hf-mirror.com/models 找到models处下载XTTS-V2 如果你全程可以联网(/huggingface.co)直接步骤…

SpringBoot中使用@Async实现异步调用

SpringBoot中使用Async实现异步调用 什么是异步调用?异步调用对应的是同步调用,同步调用指程序按照定义顺序依次执行,每一行程序都必须等待上 一行程序执行完成之后才能执行;异步调用指程序在顺序执行时,不等待异步调用的语句返…

32位MCU极致性价比高速风筒方案特点--【其利天下技术】

近年来,伴随着人们消费升级及现代工业技术水平的提升,电吹风市场已经步入了绿色节能、高效多功能化的发展阶段。人们对电吹风的需求和要求都在不断增加。然而,传统电吹风采用交流电机,使用寿命有限,维护不方便&#xf…

数据可视化---双Y轴折线图比较

内容导航 类别内容导航机器学习机器学习算法应用场景与评价指标机器学习算法—分类机器学习算法—回归机器学习算法—聚类机器学习算法—异常检测机器学习算法—时间序列数据可视化数据可视化—折线图数据可视化—箱线图数据可视化—柱状图数据可视化—饼图、环形图、雷达图统…

【为数据之道学习笔记】5-7五类数据主题联接的应用场景

在数字化转型的背景下,华为的数据消费已经不再局限于传统的报表分析,还要支持用户的自助分析、实时分析,通过数据的关联,支持业务的关联影响分析以及对目标对象做特征识别,进行特定业务范围圈定、差异化管理与决策等。…

Linux CentOS7安装harbor

1、下载harbor离线包 wget https://github.com/goharbor/harbor/releases/download/v2.4.2/harbor-offline-installer-v2.4.2.tgz 2、解压安装 tar -zxvf harbor-offline-installer-v2.4.2.tgz #解压离线安装包 3、配置harbor cd harbor #切换到harbor目录下…

RabbitMQ入门指南(二):架构和管理控制台的使用

专栏导航 RabbitMQ入门指南 从零开始了解大数据 目录 专栏导航 前言 一、RabbitMQ架构 二、RabbitMQ管理控制台的使用 1.Exchange交换机 2.Queue队列 3.绑定Exchange交换机和Queue队列 4.发送消息 5.数据隔离 总结 前言 RabbitMQ是一个高效、可靠的开源消息队列系统…

阅览窗格功能虽然便利,但有时会出错,特别是在Word和Excel文件中更为常见

当你打开预览窗格功能时,每次你打开Windows文件资源管理器并选择任何文件,你将在屏幕的右窗格上看到该文件的小预览缩略图。 由于这个新功能,你可以在Windows资源管理器的右窗格上以缩略图的形式看到文件的小预览。此功能在更快地识别文件方…

Axure交互样式,交互事件,交互动作,情形基本介绍及使用,完成ERP的菜单跳转到各个页面的跳转案例,省市联动案例,下拉刷新案例

目录 一.Axure交互样式 二.交互事件 三.情形 四.交互动作 五. 完成ERP的菜单跳转到各个页面的跳转 ​编辑 五. 省市联动 ​六.下拉刷新 一.Axure交互样式 鼠标悬停;鼠标按下;选中;禁用;获取焦点; 悬停就是鼠标放上去时,按下是鼠标左键单击,选中是…

【深度学习目标检测】九、基于yolov5的路标识别(python,目标检测)

YOLOv5是目标检测领域一种非常优秀的模型,其具有以下几个优势: 1. 高精度:YOLOv5相比于其前身YOLOv4,在目标检测精度上有了显著的提升。YOLOv5使用了一系列的改进,如更深的网络结构、更多的特征层和更高分辨率的输入图…

14:00面试,14:05就出来了,问的问题有点变态。。。

从小厂出来,没想到在另一家公司又寄了。 到这家公司开始上班,加班是每天必不可少的,看在钱给的比较多的份上,就不太计较了。没想到12月一纸通知,所有人不准加班,加班费不仅没有了,薪资还要降40…

【Vue2】Component template should contain exactly one root element.

问题描述 [plugin:vite:vue2] Component template should contain exactly one root element. If you are using v-if on multiple elements, use v-else-if to chain them instead.原因分析 这个错误通常是由于 Vue 组件的模板中包含多个根元素导致的。Vue 要求组件模板中只…

HTML基础

目录 1.格式化文本1.1.& nbsp1.2.设置水平分割线粗细为51.3.粗细为5且颜色为 #0033ff1.4.对齐方式1.5.两端对齐代码小结 2.段落2.1.块级标记2.2.那些块级标记不能包含其他块级标记,哪些可以2.3.hr标签如何设置高度2.4.拼音音标注释ruby标记和rt/rp标记2.5.block…

纵横字谜的答案 Crossword Answers

纵横字谜的答案 Crossword Answers - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 翻译后大概是&#xff1a; 有一个 r 行 c 列 (1<r,c<10) 的网格&#xff0c;黑格为 * &#xff0c;每个白格都填有一个字母。如果一个白格的左边相邻位置或者上边相邻位置没有白格&…

三大主流前端框架介绍

在前端项目中&#xff0c;可以借助某些框架&#xff08;如React、Vue、Angular等&#xff09;来实现组件化开发&#xff0c;使代码更容易复用。此时&#xff0c;一个网页不再是由一个个独立的HTML、CSS和JavaScript文件组成&#xff0c;而是按照组件的思想将网页划分成一个个组…

JS的浅拷贝和深拷贝

首先理解什么是浅拷贝和深拷贝&#xff1a; 浅拷贝&#xff1a; 浅拷贝只会复制对象的第一层属性&#xff0c;而不会递归地复制嵌套的对象。浅拷贝仅复制对象的引用&#xff0c;新对象和原始对象仍然共享相同的引用&#xff0c;因此对新对象的修改可能会影响到原始对象。浅拷…

Java小案例-SpringBoot火车票订票购票票务系统

目录 前言 详细资料 源码获取 前言 SpringBoot火车票订票购票票务系统 前端使用技术&#xff1a;HTML5,CSS3、JavaScript、VUE等 后端使用技术&#xff1a;Spring boot&#xff08;SSM&#xff09;等 数据库&#xff1a;Mysql数据库 数据库管理工具&#xff1a;phpstud…

tp8 模型save保存方法 method not exist:think\db\Query->record

1.$schema 有一个字段存在&#xff0c;但是实际表中是缺少这个字段的 2.必填值&#xff0c;没有值

什么是关键词排名蚂蚁SEO

关键词排名是指通过搜索引擎优化&#xff08;SEO&#xff09;技术&#xff0c;将特定的关键词与网站相关联&#xff0c;从而提高网站在搜索引擎中的排名。关键词排名对于网站的流量和用户转化率具有至关重要的影响&#xff0c;因此它是SEO工作中最核心的部分之一。 如何联系蚂…

二叉树的最大深度(LeetCode 104)

文章目录 1.问题描述2.难度等级3.热门指数4.解题思路方法一&#xff1a;深度优先搜索GolangC 方法二&#xff1a;广度优先搜索GolangC 参考文献 1.问题描述 给定一个二叉树 root &#xff0c;返回其最大深度。 叉树的「最大深度」是指从根节点到最远叶子节点的最长路径上的节…