网络——初识网络

在现如今,网络已经成了一种基础设施,大到国家,小到个人,网络已经充斥在我们每个人的身
边,如果一个人突然失去了网络,那么它的生活或多或少会出现一些不方便的地方,网络现在已
经伴随着我们的吃穿住行,所以在学习计算机专业知识的路上,网络一定是我们未来作为软件开
发人员必须掌握的技能,所以这篇博客我会介绍关于网络的一些简单的知识,以便能对计算机中
的网络有一种大致的认识。

1. 网络发展的大致历程

在早些年代的时候计算机一般是被一些科学家工程师所使用的,他们一般用来处理并计算数据,在这个过程中人与人之间的协作配合是必须的,那也意味着人所使用的工具之间也存在协作。例如在工程师进行大型计算时,有专门的人负责收集数据,整理数据,处理数据,这些数据存储在计算机上,所以当一个人收集完数据之后需要把数据交给下一个工作人员,而这之间就涉及到了计算机间的数据的迁移,在早些时候,计算机间的数据迁移一般是通过软盘拷贝,然后在人力下进行迁移的过程。
在这里插入图片描述

在这个数据迁移的过程中中间有着人力的参与,而对于计算机来说中间只要参杂了人力,那就势必会降低整体的效率,在这种情况之下,一个简单的网络结构就出现了:
在这里插入图片描述
在这种结构下,所有工作人员的数据都会通过网线在服务器中存取,这样计算机与计算机之间数据的迁移就会快很多了。这种网络叫做局域网(LAN)
随着时间的发展,计算机即主机的数目发展规模越来越大,就产生了更大规模的局域网:
在这里插入图片描述
再随着时间的发展,更大规模的局域网出现了,也出现了新的名词,叫做广域网(WAN)。
到了现在互联网的规模已经是非常之大了,它不再是一个小小的试验室里几台计算机之间存在网络,省与省、国家与国家之间都存在着网络的连接。

2. 网络协议

a. 网络协议的引出

但是我们也要认清一点,互联网发展到现在,并不单单是互联网本身在发展,互联网发展的背后还有着硬件(路由器、交换机,调制解调器等等)以及基础设施(基站、网线、光纤)的迭代和建设也推动着互联网的发展。
现在软件和硬件都有了,那么究竟是什么东西支持着计算机与计算机之间能够相隔万里进行通信呢?它就是网络协议。
了解冯诺依曼结构体系的都知道,计算机有输入设备、输出设备、内存、运算器、控制器,他们之间通过总线进行连接,其实这种状态下的单个的计算机也是一种网络结构。
而通过网络进行计算机间通信,首先最直观的能够看到的就是两台计算机之间的距离变大了。他们之间实现通信的方式无非就是通过网卡来实现,但是仍然面临着许多问题:

1. 整么长的数据传输,如果在传输的过程中数据丢包了怎么办?
2. 世界上这么多计算机每台计算机都;连接了公网,如何能够找到目标计算机?
3. 在上面我们看到了,当一个局域网中的计算机增多之后,就出现了路由器,交换机
等设备这意味着我们的数据在传输过程中,一定会经过很多个设备,那么一台计算机
发出的数据是如何能经过多台设备之后仍然发送到远端机器上的。

而这一切的解决方案都是依靠网络协议,这也就是为什么要有网络协议。

b. 协议是什么?

其实协议就是一种约定,就像旗语一样,在一开始军队之间就制定好旗子的摆动方式与某种信息建立关系,这样在将来,两个同样懂一种旗语的人,相隔很远,纵使两人不能通过大声呼喊来进行信息交流,他们也可以通过旗语来进行信息交流。
在计算机中,我们可以通过固定的数据格式来表明特定的任务,比如二进制0101就是执行下载任务,0110就是执行播放任务等等。这就是一种协议,也是软件层的协议。
而根据冯诺依曼机构体系,计算机中数据的迁移必须经过硬件,计算机间也不例外,它们也需要硬件来进行信息的传递,而传递的方式一般是通过光电信号来实现的。通过光电信号的频率,或者是量亮度的大小、或者是光电信号的有无来进行二进制的表示。
但是电脑厂商很多,假如A家的电脑和B家的电脑都支持网络协议,它们的计算机都知道0101是下载任务,0110是播放任务,但是A家电脑的底层的网络通信的依据是光电信号的频率,B家电脑的底层的网络通信的依据是光电信号的亮度,这两家电脑都同样遵循了网络协议,但是这两台电脑之间不能通信,则会显然也不是正确的。所以网络协议不仅仅存在与软件层,也存在于底层硬件的电气特性,也就是说,硬件上也要存在协议。
也就是说网络协议的存在一定要保证机器能够无障碍地接入互联网中。
上面也说了,网络协议存在于软件层,那也就是说需要将协议编码到计算机中,而操作系统也是编码到计算机中的。所以我们有必要了解网络与操作系统之间的关系。

3. 网络与操作系统

a. 网络通信的问题

我们现在再次细分一下网络通信存在的问题:
上面说了,计算机与计算机之间在逻辑上是直接进行通信,但其实在物理上数据是经过了很多的设备才能到达目标计算机的,这就产生了一个问题,怎么保证将数据发给下一跳主机?
在这里插入图片描述

在每一跳之间,每个环节的设备肯定不止一个,在转发数据的过程中怎么进行路径的选择以及目标主机的定位?
在这里插入图片描述
在报文传输的过程中,假如数据出现了错误,或者丢失怎么办?
以上的问题都是因为两台机器之间距离太长所导致的。
而数据送到之后,数据如何处理?也是一个问题,以上的一切都需要网络协议来解决与统一。

b. 网络通信的解决方案

网络协议解决上面问题的方式采用的是层状结构,什么是层状结构,这里给出简单的例子:
在这里插入图片描述

假如小明和小红在通电话,从逻辑上来说,是小明与小红进行通话,但是实际情况是,小明说出的话会经过电话从汉语转化为电话能够存储的信息再传给另一台电话,然后另一台电话再将电话中的信息,转化为汉语然后,小红才听到了小明的声音。
这种逻辑上具有明显的层状关系的结构,就是层状结构。
层状结构完成了软件的解耦,方便后续进行软件的更新与维护。
例如,小明和小红之间改用英语交流,他们不需要更换电话也能实现通信。他们的电话换了之后,他们之间仍能用汉语交流。
而一个好的项目,其中必定能够体现出一种层状机构,例如操作系统的设计。就算是现在主流的面向对象的语言中的继承也是层状结构的体现。
在实际的网络通信中,网络协议的层状结构如下:
在这里插入图片描述
上面说到,网络的发展也伴随着硬件的发展。
这里只讨论上四层的协议,至于硬件层是一些硬件的电气特性,这里就不再讨论了,而其中有一个设备叫做集线器,集线器的作用是,在长距离的数据传输时当信号衰弱时,会将信号增强。。
在数据链路层(Mac)中,它能够保证将数据交给下一跳,这个过程中有一个设备叫交换机,用来解决数据碰撞的问题,关于数据碰撞问题之后会提到。
网络层(IP)解决数据传输过程中,路径选择以及目标主机定位的问题,硬件层面路由器可以解决这个问题。
接下来是传输层(tcp/udp),从传输层开始就是纯软件部分了,处理传输报文出现错误或者丢失的问题,可能会采取重发等措施。
再往上是应用层,决定数据如何使用。
以上就是,实际网络通信中的四层协议,带上硬件层五层,他还有一种叫法,网络协议栈或TCP/IP协议。而还有一种协议:
在这里插入图片描述
这是OSI组织制定的一个用于计算机或通信系统间互联的标准体系。那有人就犯嘀咕了,不是说网络世界是统一的吗,为什么一会儿五层一会儿七层呢?其实OSI指定的七层网络模型你可以理解为就是理论上的协议,而上面介绍的五层模型是实际实现模型之后的结果,原因就是在编码过程中人们发现实际上会话层、表示层、应用层他们很难通过编码来分层实现,所以三层合一就有了一个应用层。
需要说明的一点是,OSI执行的协议标准是非常完善的,本身没有任何问题。

c. 网络与操作系统

认识了网络分层模型之后,我们来正式认识一下,网络与操作系统的关系:
在这里插入图片描述
首先是硬件层,不用多说,自然是我们的网卡。
数据链路层,其实就是硬件的驱动程序。
网络层和传输层是嵌套在系统内核中的。
应用层就是供用户所使用的,我们知道用户通过计算机通信不是直接从应用层到另一个应用层的,根据冯诺依曼体系,我们要实现两台计算机之间数据的传输,我们应该通过硬件也就是网卡来传输,也就是说用户要实现通信必须贯穿底层,但是这是不实际的,操作系统不让你这么做,所以就有了系统调用,而网络的系统调用也是由网络协议提供的。
现在我们再次理解网络与操作系统之间的关系,以及计算机之间实现通信的方式就更加明了一些了,在不同的平台比如Windows、Linux、macOS,我们的系统内核的具体实现方式可能不一样(比如Windows线程、Linux的线程),这是因为操作系统并没有规定一套标准,但是网络不一样,不管你是哪个系统,你都系须遵守一套网络协议,要不然没人使用你的系统,这样无论哪个系统哪个厂商的电脑,都可以实现在网络上随意通信了:
在这里插入图片描述
现在我们再来理解一点:既然我们的电脑能够从网上接收报文,那么它可以可以接收多个报文呢?答案一定是可以的,而这多个报文加载到计算机的内存中之后,那自然不可避免的要被管理,而管理的方式那自然就是先描述再组织了。

4. 网络通信流程

经过上面对网络协议的大致认识,现在我们就可以认识网络通信的具体流程了,但是在了解网络上通信具体流程之前,我们首先得重新认识一下网络协议以及局域网中的计算机通信

a. 重新认识网络协议

经过上面的介绍,我们知道网络其实本质上就是一种约定,是一种发送方和接收方都心知肚明的东西,这种约定不仅仅在网络上,也在我们的生活中,比如快递:
我们在收发快递的时候,我们是只单单发出或接收到了我们的商品吗?显然不是的,上面还有一个重要的东西就是快递单。快递单上一般会携带发件人信息,收件人信息,收件人目的地,还有发出人地址,这些都需要进行填写,那么发送方和接收方很显然对这个快递当单上的内容是心知肚明的,要不然发送方是无法送到目的地,接收方也不能正确接收到自己的商品了。而快递单何尝又不是一种约定呢?
在这里我们发现,在我们要发送一个东西的时候,往往实际发送的要比真正的物品多出一部分东西来,而多出来的这部分就叫做报头,对于快递来说,快递单就是报头。
而我们作为开发人员,我们假如要想对这个快递单进行描述,用C语言那就是直接来个结构体,把相关字段干进去就行了。
而对于网络协议也是这样,我们真实发送的消息往往会大于我们预期的大小。
这样,才能保证两台计算机之间能够正确的进行通信。

b. 局域网中计算机通信

我在上面曾贴出一张局域网的大致样子,现在可以思考一下,局域网中的计算机能直接通信吗?
在这里插入图片描述
这里直接给出结果,局域网中的计算机是可以直接通信的,在网络协议栈中有数据链路层mac,而计算机中有一个地址叫做mac地址,这个地址一般来说具有世界上唯一的特性,比如在Linux系统中:
在这里插入图片描述
这就是mac地址,mac地址的大小一般是48个字节,上图表示的是十六进制。通过mac地址就可以实现局域网中计算机的通信。
这种通信方式就好像一间教室里老师正在上课,突然老师叫道:“小明,你来说一下操作系统中进程和线程的区别”。这时候不只小明听到了,教室里的其他学生也听到了,但是其他人都不会做出回答的举动,因为这句话有一个关键词能辨别这个信息是给谁的那就是小明。
而局域网中通信也一样,A电脑想要给B电脑发送消息,那就就会根据B电脑的mac地址来作为辨别信息,其他电脑也会接受到这个信息,但是由于它们的mac地址不是目标mac地址,所以其他电脑就将这条信息丢弃了,而B电脑接收到这条信息后,发现自己的mac地址与这条信息的目标mac地址一样,所以它就会接收并处理这条信息,当然这条信息中不止存储着目标mac地址,也携带着发送者的mac地址。这就是局域网中计算机的通信。
但是我们知道,在一间教室中,往往会出现很多个人的声音,在局域网中,多个电脑可能也会同时发消息,但是网线只有一条,这是就会出现多条消息同时被网线传输,要知道网线传输的可是光电信号表示的二进制,这么混在一起是无法进行区分的,所以这种情况要避免,而这种现象叫做数据碰撞,避免这个过程叫做碰撞避免,而避免的方式就是确保同意时间内只能有一台机器在网线上发送消息,而这种避免方式在操作系统中不就是我们的互斥吗?而局域网就是一种临界资源。
那么基于这种随机碰撞的要进行碰撞避免的网络我们也叫做以太网。

c. 网络通信流程

那么我们现在就来认识一下网络通信的流程:
在这里插入图片描述
这张图较为完整的诠释了网络通信的流程,在这其中我们发现两台机器间数据的传输不是直接传输的而是自顶向下然后再从下到上,传给B用户,从逻辑上来说每个层都收到了自己想要的内容。
但是这其中涉及到了报文的封装,解包与分用,这也是我们需要探讨的点,因为每层协议都需要解决这个问题。
在上面这句话和这张图中我们只看到了封装和解包,那分用是什么呢?其实图中每一层的协议只展现了一个,比如在传输层中不只有TCP协议还有UDP协议,那么在应用层传给传输层或者网络层传输给传输层时,它怎么知道接下来的属于传输层的报头是遵守了哪个协议的报头呢?这时候就体现出来分用了。
其中用户层的报头封装叫做request&response。
传输层的叫做数据段
网络层的叫数据报
链路层的叫数据帧
而我们发现,在封装报头与报头的解包与分用,看起来就像一个栈结构一样,进行入栈和出栈。

5. IP地址

a. IP地址的引入

在在上面的局域网通信中,我们看到有一个协议叫IP协议,我们在现实生活中就算不了解网络协议,也知道一个地址叫做IP地址,但是IP地址具体用来做什么,为什么要有它,我们好像并不清楚,所以现在我就来介绍这个IP地址:
在这里插入图片描述
在这里插入图片描述
我们的Linux和Windows中都有着IP地址(如不做特殊说明,我所说的IP地址都是指IPv4的IP地址),IP地址遵循点分十进制的格式,在C/C++中是一个字符串,它的每个小数点分隔的数字范围就是0~255。而IP地址分为内网IP和公网IP,我们目前看到的IP地址大多都是内网IP,而像云服务器提供的IP就是公网IP,前面我们说Mac地址可以在局域网中唯一的标识一台主机,而IP地址可以在互联网(内网和公网的结合)中唯一的表示一台主机,在网络传输过程中在网络层的报头中携带着IP地址,那么IP地址如果是以字符串在网络中传输的话比较浪费空间,我们也发现IP地址其实可以使用四个字节就可以表示:

struct ip_addr
{uint8_t p1;uint8_t p2;uint8_t p3;uint8_t p4;
};

所以在网络中只需要使用四个字节就可以存储一个IP地址,这就是IP地址的简单介绍。

b. IP vs Mac

我们在上面介绍了两个地址,一个是Mac地址,一个是IP地址,我们又说Mac地址在局域网中唯一,IP地址在互联网中唯一,那么这两个之间有什么区别或者有什么联系呢?
其实要理解他们俩之间的关系很简单,我在这里举一个例子:
假如你现在要自驾游从宁夏到安徽,那么我们现在就有一个起始地址和一个最终地址,但是当我们自驾游的时候,我们是直接从宁夏到安徽而不途径任何地方吗?答案显然不是的,在地图导航的过程中,我们可能会先到达陕西然后再到河南,最后才到安徽。我们发现当我们从一地驶向另一地时,往往会中间经过多个地方,也就是从这一站到下一站,但是我们有一个最终的目的地和一个最开始的起点,而这就是IP地址和Mac地址的区别:
IP地址就好像我们的起始地址和最终地址一样是在我们的路程中一直不变的(IP起始地址有可能改变),但是Mac就像上一站下一站一样是会一直改变的,这就是IP地址与Mac地址的区别。

c. 例子

接下来我们来举一个跨网络通信的例子,以便更好了解Mac地址和IP地址
在这里插入图片描述
在上面图中我们可以看到一个新的网络,令牌环网,这个网络的大致理解就是,在一个局域网中有且仅有一个令牌,谁拥有这个令牌谁就可以向局域网中发送消息。看起来就像是一种互斥的行为。
我们现在再来看这张图,这是一个跨网络通信的图,在上面介绍一条消息在局域网中是如何通信的,当消息从顶向下要封装不同的报头,这里也是一样:
在这里插入图片描述
当报头封装到网络层时,网络层中的报头会携带源IP地址和目的IP地址在这里就是A主机和B主机的IP地址,
在这里插入图片描述
当封装到网络层时,因为这是跨网络通信,以太网是不能直接跟令牌环网通信的,所以需要中间设备那就是路由器(路由器中可能会有多张网卡),所以我们这里的目标Mac地址就是路由器的Mac地址,这样传给路由器之后,然后路由器再将报文的链路层的报头解包,到了路由器的网络层,然后再通过令牌环网的驱动程序再封装上链路层的报头,再发给B主机,B主机再进行解包与分用:
在这里插入图片描述
这就是一个简单的跨网络传输的流程,我们可以再将这个图抽象一下:
在这里插入图片描述
在实际情况中,我们两台主机的网络通信所需要经过的中间设备有很多,但是我们都可以将网络通信抽象成上图,在上图中我们发现中间设备只到传输层,更多的是解决跨网络传输问题,但是传输层往上包括传输层,我们从上上张图中发现,他们的内容是没有区别的,所以我们可以得出网络报文无差异,一切皆IP的说法。
以上就是网络的一些基础的认识。

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

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

相关文章

axios-mock-adapter使用

文章目录 1. 安装 axios-mock-adapter2. 引入所需的库3. 创建一个模拟适配器实例4. 定义模拟响应5. 在你的代码中使用 axios6. 在测试或开发完成后清理模拟 axios-mock-adapter 是一个用于模拟 axios HTTP 请求的库。它允许你在测试或开发过程中,为 axios 实例提供…

Solana主网使用自定义的RPC进行转账

1、引言 如果用 browser 连接主网的 RPC server 会收到 error code 403 message 為 Access forbidden, contact your app developer or supportrpcpool.com. 错误,因为主网的 RPC server 会检查 HTTP Header 如果判断出來是 browser 就会报告 403 錯誤。 要解決这…

【LeetCode热题100】53. 最大子数组和(数组)

一.题目要求 给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。 子数组 是数组中的一个连续部分。 二.题目难度 中等 三.输入样例 示例 1: 输入:nu…

N 皇后 - 蓝桥杯?-Lua 中文代码解题第6题

n 皇后问题 研究的是如何将 n 个皇后放置在 n n 的棋盘上,并且使皇后彼此之间不能相互攻击。 给你一个整数 n ,返回 n 皇后问题 不同的解决方案的数量。 示例 1: 输入:n 4 输出:2 解释:如上图所示&…

吴恩达2022机器学习专项课程(一) 5.2 向量化(1) 5.3 向量化(2)

问题预览/关键词 什么是向量化?向量化的好处是?如何向量化多元线性回归函数的参数?如何在Python中向量化参数?计算机底层是如何计算向量化的?向量化示例 笔记 1.向量化 一种在数学和计算中广泛使用的概念&#xff…

[Mac]安装App后“XX已损坏,无法打开“

问题: “xx.app”已损坏,无法打开。你应该将它移到废纸篓。 解决: 终端输入sudo xattr -r -d com.apple.quarantine 后将Applications中对应的问题app拖入生成路径,然后执行。 $ sudo xattr -r -d com.apple.quarantine /Appli…

备战蓝桥杯(日益更新)(刷题)

备战蓝桥杯(日益更新)(刷题) 文章目录 备战蓝桥杯(日益更新)(刷题)前言:一、二分:1. acwing503 借教室:(二分 差分)2. ac…

使用列表递推实现螺旋矩阵

下面是使用列表递推实现螺旋矩阵的代码: def generate_spiral_matrix(n):# 创建一个大小为n*n的矩阵,初始值为0matrix [[0] * n for _ in range(n)]# 定义上下左右四个边界top, bottom, left, right 0, n - 1, 0, n - 1# 定义当前要填充的数字num 1w…

Socks5代理IP如何使用?详细教程解析

当我们在互联网上浏览网页、下载文件或者进行在线活动时,隐私和安全问题常常被提及。在这样的环境下,一个有效的解决方案是使用Sock5IP。本教程将向您介绍Sock5IP的使用方法,帮助您保护个人隐私并提升网络安全。 一、什么是Sock5IP&#xff1…

上线后菜单卡片未显示

上线后菜单卡片未显示 背景 需要开发儿童模式,对菜单、通知等页面根据年龄段进行隐藏。为了兼容二期需求,这次的开发划分了三个年龄段:14岁以下,14~17岁,18岁以上。 实现方式 涉及的表添加一个可见度字段&#xff…

Mybatis-Plus使用入门

Mybatis-Plus 一、Mybatis-plus的简介 官方文档的地址: MyBatis-Plus (一)什么是Mybatis-Plus Mybatis-Plus是一个Mybatis(opens new window)的增强工具,在Mybatis的基础上只做增强不做改变&#xff0c…

ChatGPT在日常生活与工作中的应用,以及Hulu AI 的探索之旅

ChatGPT在日常生活与工作中的应用,以及Hulu AI 的探索之旅 💬ChatGPT 的多面应用💬Hulu AI:一个AI工具聚合平台的探索平台优势为何选择Hulu AI?珍稀优惠 💬结束语 在数字化快速发展的当下,人工智…

冯喜运:4.11外汇黄金原油晚间行情分析及独家作家操作建议

【 黄金消息面分析】:周四(4月11日)亚市早盘,现货黄金窄幅震荡,周三金价从纪录高位下滑,盘中一度失守2320关口至2319.一线,收报2333附近,因此前强于预期的通胀数据削弱了美国提前降息的预期,美元…

go 使用pprof查看内存分布

一、引入依赖 "runtime/pprof""github.com/labstack/echo/v4" 二、在main方法中,新启一个协程,启动http接口 go func() {e : echo.New()e.POST("/api/mem", func(c echo.Context) error {log.Info("start export …

常见交通微观指标的中英文对照表

常见交通微观指标的中英文对照表: 车流量 - Vehicle Flow 截面流量 - Section Flow 车头时距 - Headway 车间距 - Spacing 平均旅行速度 - Average Travel Speed 占有率 - Occupancy 队列长度 - Queue Length 通行能力 - Capacity 饱和度 - Saturation 延误 - Dela…

尝试CSDN语法使用-2

尝试语法使用 一级标题 二级标题 三级标题 四级标题 五级标题 六级标题 强调文本 强调文本 加粗文本 加粗文本 标记文本 删除文本 引用文本 H2O is是液体。 210 运算结果是 1024。 项目 项目 项目 项目1项目2项目3 计划任务 完成任务

Python初级第二次作业

一、 def reverse(num):anumt0b0cnumwhile a//10>0:if a%10>0:t1aa//10print(t)for i in range(t,-1,-1):if c%100:b0else:b(c%10)*(10**i)c//10print(b) if bnum:return Trueelse:return Falsedef isPalind(num):kreverse(num)if kTrue:print(f"{num}是回文&…

uniapp 轮播列表一排展示3个,左右滑动,滑动到中间放大

一、效果展示 二、代码实现 1.html代码&#xff1a; <!-- 轮播 --><view class"heade"><swiper class"swiper" display-multiple-items3 circulartrue previous-margin1rpx next-margin1rpxcurrent0 change"swiperChange">&l…

60、ARM/汇编实现控制外设

一、编写汇编程序&#xff0c;实现控制外设三个LED灯闪烁 代码&#xff1a; .text .global _start _start: 要使三个灯闪烁 需要设置三个灯的管脚输出高电平对应到STM32MP157AAA的PE10、PF10、PE8使能GPIOE、GPIOF的外设时钟 它们对应的总线均为AHB4GPIOE在[4]位 GPIOF在[5]…

书生·浦语2.0(InternLM2)大模型实战--Day02 茴香豆 | 搭建RAG智能助理

视频地址&#xff1a;https://www.bilibili.com/video/BV1QA4m1F7t4/文档地址&#xff1a;https://github.com/InternLM/Tutorial/blob/camp2/huixiangdou/readme.md作业地址&#xff1a;https://github.com/InternLM/Tutorial/blob/camp2/huixiangdou/homework.md RAG 概述 R…