数据链路层(超详细)

news2024/11/15 9:28:52

引言

数据链路层是计算机网络协议栈中的第二层,位于物理层之上,负责在相邻节点之间的可靠数据传输。数据链路层使用的信道主要有两种类型:点对点信道广播信道。点对点信道是指一对一的通信方式,而广播信道则是一对多的通信方式。在这一章中,我们将详细介绍数据链路层的基本概念、点对点信道和广播信道的数据链路层协议,以及数据链路层的分组交换设备和无线局域网的基本原理。


3.1 使用点对点信道的数据链路层

数据链路层的基本概念

数据链路层在整个网络协议栈中起着关键作用。它主要负责确保数据帧在相邻节点之间的可靠传输。数据链路层通过封装成帧、差错检测和可靠传输等机制实现这一目标。


3.1.1 数据链路层的地位
数据链路层在通信中的角色

当两个主机通过互联网进行通信时,数据链路层在协议栈中扮演着重要角色。如图3-1所示,数据在主机H和远程主机H2之间传输时,需要经过多个路由器(R1、R2和R3)。这些路由器在转发数据时,只使用协议栈的前3层:物理层、数据链路层和网络层。

在这里插入图片描述

数据流动

数据从主机H传送到主机H2时,在每个路径节点上会在协议栈中向上和向下流动多次,如图3-1中的灰色粗箭头所示。当我们专门研究数据链路层的问题时,可以只关心协议栈中水平方向的数据链路层

然而当我们专门研究数据链路层的问题时,在许多情况下我们可以只关心协议栈中水平方向的各数据链路层。于是,当主机H向主机H2发送数据时,我们可以想象数据就是在数据链路层从左向右水平传送,如图3-2中从左到右的灰色粗箭头所示,即通过以下链路:

H1的链路层→R1的链路层→R2的链路层→R3的链路层→H2的链路层。

在这里插入图片描述


3.1.2 数据链路和帧
链路与数据链路的区别

链路(Link) 是指从一个节点到相邻节点的一段物理线路,中间没有其他交换节点。数据链路(Data Link) 则不仅包含物理线路,还包括控制数据传输的通信协议和实现这些协议的硬件和软件。

帧的概念

数据链路层的协议数据单元称为帧(Frame) 。帧由网络层的数据和数据链路层的首部和尾部组成,用于在链路上传输。

三层模型

如图3-3所示,点对点信道的数据链路层通信可以简化为三层模型,主要步骤如下:

  1. 封装成帧:结点A将网络层的IP数据报封装成帧。
  2. 发送帧:结点A将帧发送给结点B。
  3. 解封帧:结点B接收帧后,解封装并上交给网络层。
点对点信道的数据链路层通信的主要步骤如下:
  1. 结点A的数据链路层把网络层交下来的IP数据报添加首部和尾部封装成帧
  2. 结点A把封装好的帧发送给结点B的数据链路层。
  3. 若结点B的数据链路层收到的帧无差错,则结点B的数据链路层从收到的提取出IP数据报上交给上面的网络层,否则丢弃这个帧。

数据链路层不必考虑物理层实现比特传输的细节。我们甚至可以更简单地设想好像是沿着两个数据链路层之间的水平方向把帧直接发送给对方,如图3-3(b)所示。

在这里插入图片描述


3.1.3 封装成帧
数据链路层以帧为单位传输和处理数据

在数据链路层,数据是以为单位进行传输和处理的。每个帧由网络层的数据(例如IP数据报)以及附加的首部和尾部组成。这个过程被称为封装成帧

封装成帧的过程
  1. 接收数据报:首先,网络层的IP数据报向下传送到数据链路层。
  2. 添加首部和尾部:数据链路层在IP数据报的前面和后面分别添加首部和尾部。这些附加部分包含了控制信息和其他必要的数据,用于确保数据的正确传输。
  3. 形成完整的帧:经过上述步骤,IP数据报被封装成一个完整的帧。帧的总长度等于数据部分的长度加上首部和尾部的长度。
    在这里插入图片描述
帧定界的重要性

为了确保数据链路层的接收方能够正确识别每个帧的开始和结束,需要进行帧定界。帧定界的目的是在接收到的比特流中准确定位每个帧。

帧定界的方法
  1. 时间间隔:一种简单的方法是在传输的帧之间插入时间间隔,就像在英文单词之间插入空格一样。例如,以太网采用了这种方法。然而,某些物理层传输服务无法保证帧之间的时间间隔。因此,这种方法并不总是适用。

    帧1 | 时间间隔 | 帧2
    
  2. 帧长度字段:在帧的首部设置一个帧长度字段,用于指示帧的长度。这种方法依赖于帧长度字段的正确传输,如果该字段在传输过程中出现差错,可能会导致后续一系列帧无法正确定界。

  3. 帧定界符:一种更常用的方法是在每个帧的开始和结束处添加特殊的帧定界标志。帧定界符可以是特定的比特序列或字符,用于标记帧的边界。帧开始标志和帧结束标志可以相同,也可以不同。

    | 帧定界符 | 数据部分 | 帧定界符 |
    

在这里插入图片描述

解决透明传输问题

为了实现透明传输,即确保数据链路层对上层协议的数据没有任何限制,可以使用字节填充比特填充的方法:

  • 字节填充(Byte Stuffing) :在数据中出现的标记字符前插入一个转义字符(例如“ESC”)。接收方在接收数据时,会删除这个转义字符,从而恢复原始数据。
    在这里插入图片描述

  • 比特填充(Bit Stuffing) :在发送数据时,每当发现连续5个“1”时,插入一个“0”。接收方在接收数据时,会删除这个填充的“0”,从而还原数据。
    在这里插入图片描述

通过这些方法,数据链路层能够有效地实现帧定界,确保数据的正确传输和处理。


3.1.4 差错检测

现实的通信链路并非理想

在实际的通信链路中,比特在传输过程中可能会产生差错:即1可能会变成0,而0也可能变成1。这种现象称为比特差错。比特差错是传输差错中的一种。本小节所指的“差错”,如无特殊说明,均指比特差错。

误码率(Bit Error Rate,BER)

误码率表示在一段时间内,传输错误的比特数与所传输比特总数的比率。例如,误码率为1/100,表示平均每传送100个比特就会出现一个比特的差错。误码率与信噪比有很大的关系。如果设法提高信噪比,就可以使误码率减小。然而,实际的通信链路无法使误码率降到零。因此,为了保证接收到的数据是正确的,计算机网络在传输数据时,必须采用某种差错检测措施

差错检测的基本原理

虽然各种差错检测技术的具体方法差别很大,但其基本原理是相同的。图3-9展示了利用差错检测码(Error-Detecting Code,EDC)实现差错检测的基本原理。

在这里插入图片描述

差错检测过程
  1. 发送方:采用某种差错检测算法,用发送的数据D计算出差错检测码EDC(D),并将EDC随数据一起发送给接收方。
  2. 接收方:通过同样的算法计算接收数据D’的差错检测码EDC(D’),如果接收到的EDC与计算出的EDC不同,则可判断传输的数据中出现了差错,即检测出了差错。

需要注意的是,未检测出差错并不意味着传输的数据中一定没有出现差错,但出现差错的概率非常小。为了提高差错检测的检错率,可以使用更长的差错检测码和更复杂的算法。当然,这也会增加传输的开销。

帧检验序列(Frame Check Sequence,FCS)

在数据链路层,为了便于硬件检测差错,通常会在帧的尾部设置一个差错检验字段,存放整个帧(包含首部和数据)的差错检测码,这个差错检验字段常称为帧检验序列(FCS) 。因此,要在数据链路层进行差错检验,就必须把数据划分为帧,每一帧都加上差错检测码,一帧接一帧地传送,然后在接收方逐帧进行差错检验。

循环冗余检验(Cyclic Redundancy Check,CRC)

在数据链路层通常使用循环冗余检验(CRC) 技术进行差错检测。CRC编码的基本原理如图3-10所示。

在这里插入图片描述

CRC编码过程
  1. 生成式G:发送方和接收方首先必须协商一个k+1比特的生成式G。算法要求G的最高位和最低位的比特为1。
  2. 计算冗余码R:发送方选取一个合适的比特冗余码R(即检错码),并将它附加到D上,使得得到的d+r比特模式用模2算术恰好能被G整除。
  3. 差错检测:接收方用G去除接收到的d+r比特,如果余数非零则检测出差错,否则认为数据正确。
多项式编码

CRC编码也称为多项式编码,因为该编码能够将要发送的比特串看作系数为0和1的一个多项式,对比特串的模2算术被解释为多项式算术。在上面的例子中,可以用多项式G(X)=X³+X²+1表示生成式G=1101(最高位对应于X³,最低位对应于X⁰)。多项式G(X)称为生成多项式。

广泛使用的生成多项式

目前广泛使用的生成多项式有:

  • CRC-16:X¹⁶+X¹²+X⁵+1
  • CRC-CCITT:X¹⁶+X¹²+X⁵+1
  • CRC-32:X³²+X²⁶+X²³+X²²+X¹⁶+X¹²+X¹¹+X¹⁰+X⁸+X⁷+X⁵+X⁴+X²+X+1
CRC的优点

CRC具有非常好的检错能力,尽管计算复杂,但非常易于用硬件实现,因此被广泛应用于现代计算机网络的数据链路层。在数据链路层,发送端FCS的生成和接收端的CRC完全由硬件完成,处理速度非常快,对数据传输的延误极小。

CRC的局限性

使用CRC的差错检测技术只能检测出传输中的差错,并不能纠正错误。虽然任何差错检测技术都无法做到检测出所有差错,但通常我们认为:凡是接收端数据链路层通过差错检测接受的帧,我们都能以非常接近于1的概率认为这些帧在传输过程中没有产生差错。接收端丢弃的帧虽然曾收到,但最终因为有差错被丢弃,即没有被接受。上述原则可以近似地表述为:凡是接收端数据链路层接受的帧均无差错

深入了解crc的计算过程,请点击: https://blog.csdn.net/2301_80064376/article/details/139942132

纠错码(Error-Correcting Code)

要想纠正传输中的差错,可以使用冗余信息更多的纠错码(Error-Correcting Code)进行前向纠错(Forward Error Correction, FEC) 。通过纠错码能检测数据中出现差错的具体位置,从而纠正错误。由于纠错码要发送更多的冗余信息,开销非常大,在计算机网络中较少使用。通常采用检错重传方式来纠正传输中的差错,或者仅仅是丢弃检测到差错的帧,由上层协议去解决数据丢失的问题。


3.1.5 可靠传输

在某些情况下,我们需要数据链路层向上面的网络层提供“可靠传输”的服务。可靠传输的目标是确保发送端发送的数据能够被接收端完整无误地接收。保证数据传输的可靠性是计算机网络中的一个非常重要的任务,也是各层协议均可选择的一个重要功能。本文讨论的可靠传输基本原理不仅适用于数据链路层,而且可以应用于计算机网络体系结构的各层协议中。例如,无线局域网和TCP协议都使用了这些原理和方法来实现可靠传输。

在这里插入图片描述

可靠传输的基本模型

可靠传输协议为上层的对等实体间提供一条可靠信道,即发送方上层实体通过该信道发送的分组都会正确地到达接收方上层实体,不会出现比特差错、分组丢失、分组重复,也不会出现分组失序。然而,底层信道却是不可靠的,分组可能出现差错、丢失、重复和失序。可靠传输协议的目标是在不可靠的信道上实现可靠的数据传输服务。为了实现可靠的单向数据传输,可靠传输协议需要进行双向通信,因此底层的不可靠信道必须是双向的。

1. 停止等待协议

基本原理

在计算机网络中实现可靠传输的基本方法是发现错误后重传。首先要解决的问题是如何知道分组在传输过程中是否出现了差错。对于分组中的比特差错,接收方使用差错检测技术识别接收的分组中是否存在比特差错。为了让发送方知道是否出现了差错,接收方必须将是否正确接收分组的信息反馈给发送方。

在这里插入图片描述

2.停止协议的特点
  • 确认与否认

    当正确接收到一个分组时,接收方向发送方发送一个确认分组ACK(Acknowledgment) 。如果接收到的分组存在比特差错,接收方丢弃该分组并发送一个否认分组NAK(Negative Acknowledgment) 。发送方收到ACK后可以发送下一个分组,而收到NAK则要重传原来的分组,直到收到ACK为止。由于发送方每发送完一个分组必须停下来等待确认,因此该协议被称为停止等待协议(Stop-and-Wait, SW)

  • 超时重传

    如果底层的信道会丢失分组,当数据分组或确认分组丢失时,发送方将会一直等待接收方的确认分组。为了解决这个问题,可以在发送方发送完一个数据分组时,启动一个超时计时器(Timeout Timer) 。若超时计时器时间到而发送方仍未收到接收方的确认分组,则重传原来的分组。这种机制被称为超时重传

  • 重复分组

    当确认分组丢失时,接收方会收到两个相同的数据分组,即重复分组。为了识别重复分组,每个数据分组都带有不同的发送序号。接收方连续收到相同序号的数据分组时,表明出现了重复分组,应当丢弃重复分组,并向发送方补发一个确认分组ACK。

  • 序号

    任何编号系统的序号所占用的比特数是有限的。因此,经过一段时间后,发送序号会重复使用。对于停止等待协议,只需1比特来编号即可,因为每次发送一个新的数据分组,其发送序号与上次发送的分组序号不同即可。

  • 自动重传请求(ARQ)

    通过上述确认和超时重传机制实现的可靠传输协议,称为自动重传请求(Automatic Repeat reQuest,ARQ) 协议。发送方发送完一个分组后,必须暂时保留已发送的分组副本(用于重传)。只有在收到相应的确认后才能清除该分组副本。保留副本、重传、确认和编号都是可靠传输协议实体自己的行为,上层实体不会感觉到这些操作。

2. 停止等待协议的算法描述

为了使读者对停止等待协议有一个完整而准确的理解,下面给出此协议的算法,读者应弄清算法中的每一个步骤。

在发送方:

  1. 从主机取一个数据帧。

  2. 初始化发送状态变量V(S)=0

  3. 将发送状态变量的数值写入发送序号N(S) ,将数据帧送交发送缓存

  4. 将发送缓存中的数据帧发送出去。

  5. 设置超时计时器

  6. 等待以下三个事件中最先出现的一个:

    1. 若收到ACK,且确认序号A®=V(S) ,则从主机取一个新的数据帧,更新发送状态变量,转到步骤3。
    2. 若收到ACK,且确认序号A®≠V(S) ,则忽略重复确认,转到步骤6。
    3. 超时计时器时间到,则重传数据帧,转到步骤4。

在接收方:

  1. 初始化接收状态变量V®=0

  2. 等待接收数据帧。

  3. 当收到一个数据帧时,检查有无产生传输差错(如用CRC)。

    1. 若检查结果正确无误,则执行后续算法。
    2. 否则丢弃此数据帧,转到步骤2。
  4. N(S)=V® ,则执行后续算法,表示收到发送序号正确的数据帧,否则丢弃此数据帧,转到步骤8。

  5. 将收到的数据帧中的数据部分送交主机。

  6. 生成新的ACK,将接收状态变量的数值写入确认序号

  7. 更新接收状态变量,准备接收下一个数据帧。

  8. 发送已生成的ACK,并转到步骤2。

3. 停止等待协议的信道利用率

停止等待协议的优点是简单,但缺点是信道利用率较低。图3-13展示了这一问题。假定A和B之间有一条直通的信道来传送分组。

在这里插入图片描述

假定A发送分组需要的时间是T。T等于分组长度除以数据率。再假定分组正确到达B后,B处理分组的时间可以忽略不计,立即发回确认分组。假定B发送确认分组需要时间T。如果A处理确认分组的时间也可以忽略不计,那么A在经过时间(TD+RTT+TA)后可以发送下一个分组,这里的RTT是往返时间。信道的利用率U可用下式计算:

                       U = T / (T<sub>D</sub> + RTT + T<sub>A</sub>)

RTT远大于分组发送时间T时,信道的利用率就会非常低。若出现差错后的分组重传,会进一步降低信道的利用率。

4. 回退N帧协议

为提高传输效率,发送方可以不使用低效率的停止等待协议,而采用流水线传输方式。发送方可连续发送多个分组,不必每发完一个分组就停顿等待确认。这样可使信道上一直有数据不间断地传送。回退N帧(Go-Back-N,GBN) 协议在流水线传输的基础上,利用发送窗口限制发送方连续发送分组的个数,是一种连续ARQ协议。

在这里插入图片描述

滑动窗口

GBN协议规定,发送方每收到一个确认,就把发送窗口向前滑动一个分组的位置。发送窗口的大小决定了发送方已发送但还没有收到确认的最大分组数。

在这里插入图片描述

GBN协议的工作过程
  1. 接收方只按序接收分组:若某个分组出现差错,其后的所有分组都要被重传。
  2. 超时机制重传:一旦发送方超时,立即重传发送窗口内所有已发送的分组。
  3. 累积确认:接收方对分组n的确认,表明接收方已正确接收到分组n及以前的所有分组。

在这里插入图片描述

5. 选择重传协议(SR)

GBN协议的一个缺点是:一个分组的差错可能引起大量分组的重传。选择重传(Selective Repeat,SR) 协议通过选择重传出现差错的分组来提高性能。接收方需要对每个正确接收到的分组进行逐一确认(选择确认)。

在这里插入图片描述

SR协议GBN协议更复杂,接收方需要足够的缓存来暂存失序到达的分组。

6. 数据链路层的可靠传输

从以上的讨论可以看出,不可靠的链路加上适当的协议(如停止等待协议)就可以使数据链路层向上提供可靠传输服务。但这样做会降低数据传输效率,并增加协议的复杂性。因此,应根据链路的具体情况决定是否需要数据链路层提供可靠传输服务。

过去,通信链路质量较差,数据链路层广泛使用可靠传输协议。然而,随着通信技术的发展,现在的有线通信链路质量已经非常好,数据链路层一般不采用确认和重传机制,而由上层协议(如运输层的TCP)来完成差错改正。这样可以提高通信效率,降低设备成本。然而,在无线信道传输数据时,由于无线信道误码率较高,往往需要在数据链路层实现可靠传输服务,以尽快改正差错,为上层提供较好的传输服务。


总结

数据链路层在计算机网络中扮演着关键角色,确保数据在相邻节点间可靠传输。通过介绍点对点信道广播信道的数据链路层协议,读者可以全面了解数据链路层的基本概念、封装成帧、差错检测和可靠传输等内容。


图文来源:《计算机网络教程》

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

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

相关文章

办公必备——ONLYOFFICE8.1版本桌面编辑器

一、介绍ONLYOFFICE ONLYOFFICE是一款免费的开源办公软件&#xff0c;它可以让你创建、编辑和分享文档、表格和演示文稿。就像微软的Office一样&#xff0c;但它是完全免费的&#xff0c;而且可以在多种设备上使用&#xff0c;包括电脑和手机。它还支持多人同时在线编辑文档&am…

Golang | Leetcode Golang题解之第223题矩形面积

题目&#xff1a; 题解&#xff1a; func computeArea(ax1, ay1, ax2, ay2, bx1, by1, bx2, by2 int) int {area1 : (ax2 - ax1) * (ay2 - ay1)area2 : (bx2 - bx1) * (by2 - by1)overlapWidth : min(ax2, bx2) - max(ax1, bx1)overlapHeight : min(ay2, by2) - max(ay1, by1)…

独立开发者系列(22)——API调试工具apifox的使用

接口的逻辑已经实现&#xff0c;需要对外发布接口&#xff0c;而发布接口的时候&#xff0c;我们需要能自己简单调试接口。当然&#xff0c;其实自己也可以写简单的代码调试自己的接口&#xff0c;因为其实就是简单的request请求或者curl库读取&#xff0c;调整请求方式get或者…

第11章 规划过程组(二)(11.10制订进度计划)

第11章 规划过程组&#xff08;二&#xff09;11.10制订进度计划&#xff0c;在第三版教材第395~397页&#xff1b;文字图片音频方式 第一个知识点&#xff1a;定义及作用 分析活动顺序、持续时间、资源需求和进度制约因素&#xff0c;创建项目进度模型&#xff0c;从而落实项目…

基于单片机的太阳能热水器控制系统设计

随着我国经济水平的不断提高&#xff0c;民众对生活质量的追求也在不断进步&#xff0c;对于现代家庭而言&#xff0c;热水器成为了必备的生活电器。目前市面上的电器主要是电热水器、燃气热水器以及太阳能热水器。就能源节约性能而言&#xff0c;太阳能热水器占据了绝对优势&a…

01day C++初入学习

这里写目录标题 1.C区别于C的输入输出2.什么是命名空间3. namespace的定义namespace的使用(1)namespace嵌套使用(2)多⽂件中可以定义同名namespace(3) 4.命名空间的使用5.C输⼊&输出6.缺省参数7.函数重载8.引用8.1引用的特性8.3引用的使用 1.C区别于C的输入输出 #include&…

接口调用的三种方式

例子&#xff1a; curl --location http://110.0.0.1:1024 \ --header Content-Type: application/json \ --data {"task_id": 1 }方式一&#xff1a;postman可视化图形调用 方式二&#xff1a;Vscode中powershell发送请求 #powershell (psh) Invoke-WebRequest -U…

探展2024世界人工智能大会之令人惊艳的扫描黑科技~

文章目录 ⭐️ 前言⭐️ AIGC古籍修复文化遗产焕新⭐️ 高效的文档图像处理解决方案⭐️ AIGC扫描黑科技一键全搞定⭐️ 行业级的知识库大模型加速器⭐️ 结语 ⭐️ 前言 大家好&#xff0c;我是 哈哥&#xff08;哈哥撩编程&#xff09;&#xff0c;这次非常荣幸受邀作为专业…

科研绘图系列:R语言分组柱状图一(Grouped Bar Chart)

介绍 分组柱状图(Grouped Bar Chart)是一种数据可视化图表,用于比较不同类别(分组)内各子类别(子组)的数值。在分组柱状图中,每个分组有一组并列的柱子,每个柱子代表一个子组的数值,不同的分组用不同的列来表示。 特点: 并列柱子:每个分组内的柱子是并列的,便于…

python-24-零基础自学python while循环+交互+数据的存储

学习内容&#xff1a;《python编程&#xff1a;从入门到实践》第二版 知识点&#xff1a; 文件处理 with open&#xff08;&#xff09;while 练习内容&#xff1a;10章练习题10-3、10-4、10-5 练习10-3&#xff1a;访客 编写一个程序&#xff0c;提示用户输入名字。用户做…

Redis基础教程(十五):Redis GEO地理信息查询与管理

&#x1f49d;&#x1f49d;&#x1f49d;首先&#xff0c;欢迎各位来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里不仅可以有所收获&#xff0c;同时也能感受到一份轻松欢乐的氛围&#xff0c;祝你生活愉快&#xff01; &#x1f49d;&#x1f49…

jQuery 笔记

一、什么是jQuery 框架&#xff1a;半成品软件 Jquery就是封装好的js 本质上还是js jQuery是一个快速、简洁的JavaScript**框架**&#xff0c;是继Prototype之后又一个优秀的**JavaScript代码库**&#xff08;*或JavaScript框架*&#xff09;。 JQuery:封装好的代码库。有一…

树莓派_Pytorch学习笔记20:初步认识深度学习框架

今日继续学习树莓派4B 4G&#xff1a;&#xff08;Raspberry Pi&#xff0c;简称RPi或RasPi&#xff09; 本人所用树莓派4B 装载的系统与版本如下: 版本可用命令 (lsb_release -a) 查询: ​ Python 版本3.7.3&#xff1a; ​ 本文很水&#xff0c;就介绍一下我以后的学习使用P…

全志A527 T527 android13支持usb摄像头

1.前言 我们发现usb摄像头在A527 android13上面并不能正常使用,需要支持相关的摄像头。 2.系统节点查看 我们查看系统是否有相关的节点生成,发现/dev/video相关的节点已经生成了。并没有问题,拔插正常。 3.这里我们需要查看系统层是否支持相关的相机, 我们使用命令进行…

前端传到后端的data数组中有些属性值为空

将前端输入框中的值全部放入data中传入后端&#xff0c;但是在后端查看发现后端接收到的数据有些属性值为空。 第一种情况&#xff1a;只有第一个属性为空&#xff0c;其余属性接收正常 可能原因&#xff1a;后端用来接收的 比如前端发送数据&#xff1a; 实际上前端发送的数…

Java | Leetcode Java题解之第224题基本计算器

题目&#xff1a; 题解&#xff1a; class Solution {public int calculate(String s) {Deque<Integer> ops new LinkedList<Integer>();ops.push(1);int sign 1;int ret 0;int n s.length();int i 0;while (i < n) {if (s.charAt(i) ) {i;} else if (s…

政安晨:【Keras机器学习示例演绎】(五十三)—— 使用 TensorFlow 决策森林进行分类

目录 简介 设置 准备数据 定义数据集元数据 配置超参数 实施培训和评估程序 实验 1&#xff1a;使用原始特征的决策森林 检查模型 实验 2&#xff1a;目标编码决策森林 创建模型输入 使用目标编码实现特征编码 使用预处理器创建梯度提升树模型 训练和评估模型 实验…

FastReport 指定sql,修改数据源 ( 非DataSet修改 )

FastReport 指定sql&#xff0c;修改数据源&#xff0c;非DataSet修改 介绍报告文件&#xff1a; codetest.frx 文件核心代码&#xff1a;&#xff08;扩展&#xff09;小结一下&#xff1a; 介绍 在FastReport中&#xff0c;经常会遇到需要给 sql 加条件的情况。 &#xff0…

k8s 部署 metribeat 实现 kibana 可视化 es 多集群监控指标

文章目录 [toc]环境介绍老(来)板(把)真(展)帅(示)helm 包准备配置监控集群获取集群 uuid生成 api_key配置 values.yaml 配置 es 集群获取集群 uuid 和 api_key配置 values.yaml 查看监控 缺少角色的报错 开始之前&#xff0c;需要准备好以下场景 一套 k8s 环境 k8s 内有两套不同…

jvisualvm工具使用--添加远程监视

jvisualvm简介 jvisualvm该工具位于jdk的bin目录下&#xff0c;是jdk自带的可用于监控线程、内存情况、查看方法的CPU时间和内存中的对 象、已被GC的对象、反向查看分配的堆栈等&#xff0c;即&#xff1a;Java虚拟机监控、故障排查及性能分析工具。 远程监控方法 以windows端…