计算机网络第3章(上):数据链路层全解析——组帧、差错控制与信道效率

目录

  • 一、数据链路层的功能
  • 二、组帧
    • 2.1 字符计数法(Character Count)
    • 2.2 字符填充法(Character Stuffing)
    • 2.3 零比特填充法
    • 2.4 违规编码法
  • 三、差错控制
    • 3.1 检错编码(奇偶校验码)
    • 3.2 循环冗余校验(Cyclic Redundancy Check, CRC)
    • 3.3 海明校验码(Hamming Code)
  • 四、流量控制与可靠传输
    • 4.1 滑动窗口机制
    • 4.2 停止-等待协议(S-W)
    • 4.3 后退N帧协议(GBN)
    • 4.4 选择重传协议(SR)
    • 4.5 三种协议的信道利用率分析

一、数据链路层的功能

数据链路层使用物理层提供的 "比特传输" 服务
数据链路层网络层 提供服务,将网络层的 IP 数据报(分组) 封装成帧,传输给下一个相邻结点
物理链路: 传输介质(0层)+物理层(1层) 实现了相邻结点之间的 "物理链路"

物理链路确实包含两个部分,但更准确的表述是:传输介质(第0层,物理介质层):前面讲到过的电缆(双绞线、同轴电缆)、光纤、无线信道等,负责实际承载信号(电信号、光信号、电磁波);物理层(第1层,协议层):定义如何在介质上传输原始比特流,包括:信号编码(如曼彻斯特编码)、调制解调、时钟同步等。关键区别:传输介质是物理实体(如网线),物理层是协议规范(如以太网 100BASE-TX 标准),两者共同实现 "比特传输" 服务,但属于不同抽象层次。

逻辑链路:数据链路层需要基于 "物理链路",实现相邻结点之间逻辑上无差错的 "数据链路(逻辑链路)"

数据链路的功能: 第3章主要围绕数据链路的功能进行讲解(逐个拆解细分)

过程分解(发送端)示例:

# 数据链路层构造好一个帧(以字节为单位)
10101010 10101010 10101010 ... (字节序列)# 物理层将字节拆成比特流
1 0 1 0 1 0 1 0 ...  ← bit stream# 物理层使用编码方案将比特转为信号波形
| 编码方案                    | 特点                |
| ----------------------- | ----------------- |
| NRZ(Non-Return-to-Zero) | 高电平=1,低电平=0       |
| 曼彻斯特编码                  | 一个比特周期中有电平翻转,用于同步 |
| 4B/5B 编码 + NRZI         | 增强同步性和误码检测能力      |
| 8B/10B 编码               | PCIe、USB、光纤通信中常用  |

二、组帧

由于物理层是无结构的比特流传输(bit stream),没有帧的概念,接收方无法知道什么时候是一个数据包的开始和结束。因此需要数据链路层将数据 "打包成帧",并定义好帧边界、起止、检测错误等功能。数据链路层通常通过以下几种方式实现帧的起止识别:

2.1 字符计数法(Character Count)

原理: 帧的第一个字段指明整个帧中字符的个数(即帧的总长度),接收方根据这个计数值提取出整个帧
优点: 实现简单,效率较高(无额外的比特填充或转义)
缺点: 如果计数字段本身出错,将导致整个帧的边界错乱(帧同步丢失),后续数据可能无法正确识别
最大缺点: 任何一个计数字段出错,都会导致后续所有帧无法定界

场景: 连续发送三帧(字符计数法)

1: 长度 4 + 数据(共4字节)00000100 10100001 11110000 000011112: 长度 3 + 数据(共3字节)00000011 11001100 101010103: 长度 2 + 数据(共2字节)00000010 11110011# 帧1长度出错(由4变为6)
00000110 10100001 11110000 00001111 00000011 11001100 10101010 00000010 11110011
# 字节序列(标号)如下: 
| 字节号 || 备注                 |
| --- | -------- | ------------------ |
| 1   | 00000110 | 错误的帧1长度(6|
| 2   | 10100001 |1数据1              |
| 3   | 11110000 |1数据2              |
| 4   | 00001111 |1数据3              |
.....一步错后面的都错位了......
| 5   | 00000011 |1数据4(原为帧2头)  ---错位     |
| 6   | 11001100 |1数据5(原为帧2数据) ---错位     |
| 7   | 10101010 | 开始解析下一帧的"长度"字节(错位) |
..........

2.2 字符填充法(Character Stuffing)

原理: 使用特殊字符表示帧的起始和结束,例如 FLAG = DLE STX … DLE ETX,如果帧数据中出现了这些特殊字符,为避免误解,使用转义字符(如 DLE)进行转义处理
优点: 可以较好处理帧边界识别问题,相比位填充,适用于基于字符的通信系统(如串口通信)
缺点: 只适用于字符流传输(不是比特流),帧内字符一多,转义开销较高

SOH(Start of Header) 和 EOT(End of Transmission) 也确实出现在一些组帧或通信协议中,它们和你前面看到的 STX/ETX 类似,属于字符填充法(即 "基于控制字符的组帧"),它们是 ASCII 控制字符中的一部分,常用于早期串口通信、串行线路或面向字符的协议中,比如 XMODEM、ZMODEM、早期串行打印通信等:

控制字符十六进制意义
SOH0x01Start of Header(报头开始)
STX0x02Start of Text(正文开始)
ETX0x03End of Text(正文结束)
EOT0x04End of Transmission(传输结束)
DLE0x10Data Link Escape(数据链路转义)

在字符填充法中,这些控制字符用于标识帧边界或数据部分的结构,例如:

# 常见用法一: SOH + 数据 + EOT
# 这种格式有时用于: 一帧一个包,简单可靠,传输完一帧就用 EOT 表明传输完毕
SOH(0x01) 表示帧或报头开始
EOT(0x04) 表示整个传输的结束# 常见用法二: SOH + 报文头 + STX + 数据 + ETX + EOT
SOH 开始整个帧
STX 开始正文(正文与报头之间分隔)
ETX 正文结束
EOT 整个传输完毕[SOH][帧头][STX][正文数据][ETX][校验][EOT]

字节填充法图示1:

字节填充法图示2:

字节填充法图示3:

你看到的 "字符填充" 其实可以叫 "字节填充",在早期的通信协议中,字符(character)= 字节(byte),因为一个字符就是一个字节(8位),例如 ASCII 编码,所以:"字符填充法" = "字节填充法"(在指 8 位字符编码时,是一回事),在使用 ASCII 的协议中,SOH、EOT、ESC 等这些控制字符都是一个字节,所以我们加一个 ESC,就是加了一个字节 —— 所以叫 "字节填充" 也没错。"字符填充" 突出的是在字符流中插入特殊字符(如 FLAG、ESC、DLE),早期通信设备用的是字符终端(Character-oriented protocols),所以强调 "在字符层级做填充"。举个例子:

协议类型填充术语常见写法
HDLC(比特协议)比特填充
PPP、SLIP(字符协议)字符填充 / 字节填充

现代协议中为什么偏向说 "字节填充"?因为现代通信系统中:不再以 "字符" 为核心单位(Unicode 一个字符 ≠ 一个字节),网络传输的单位是字节(byte stream),所以更技术中立、准确的说法是:字节填充(byte stuffing)

2.3 零比特填充法

原理: 用特定的比特模式来标识一帧的开始和结束,比如 HDLC 使用 01111110。若数据中出现5个连续的 1 比特,发送方自动插入一个 0(填充),接收方在收到5个连续的 1 后发现第6位是 0,就将其删除,从而恢复原始数据。示例:

原始数据中包含:01111110
则实际发送为:011111010

接收方解析后将填充的 0 去掉,优点: 适用于位导向协议,可用于任意二进制数据,缺点: 实现稍复杂(需要逐位判断和填充)。
图例1:

图例2:

2.4 违规编码法

原理: 某些物理层编码规则中存在非法的比特模式(正常传输中不会出现),数据链路层使用这些非法模式作为帧的起止标志。示例: 例如在曼彻斯特编码中,若某个比特组合违反电压跳变规则,则认为是帧边界。优点: 不需要增加额外的开销,可在物理层检测帧边界,效率高。缺点: 依赖于物理层的具体实现,不具备通用性。

知识回顾与重要考点:

三、差错控制

数据链路层的差错控制功能

3.1 检错编码(奇偶校验码)

奇偶校验(Parity Check)是一种简单的检错编码技术,用于在数据链路层中检测传输过程中发生的1位错误(bit error)。它的基本思想是:在原始数据后添加一个额外的比特(称为奇偶校验位),使得整个数据的1的个数符合 "奇数""偶数" 的要求。奇偶校验的两种类型:

  1. 奇校验码: 整个校验码(有效信息位和校验位)中 "1" 的个数为奇数
  2. 偶校验码: 整个校验码(有效信息位和校验位)中 "1" 的个数为偶数

【例】给出两个编码 1001101 和 1010111 的奇校验码和偶校验码。设最高位为校验位,余7位是信息位,则对应的奇偶校验码为:

校验码是否一定要放在数据末尾?能不能放在最前面?可以放最前面,也可以放最后,甚至中间都可以,但通常放在末尾(例子放在开头)。这是协议约定问题,不是技术限制。校验位的位置没有本质上的 "必须",关键在于发送方和接收方达成一致。但通常放在末尾的原因是: 数据生成后,再计算校验位比较自然(逻辑清晰) 接收方收到数据后,只要读完整体,再判断是否符合校验规则 与 CRC、FCS 等其他编码方式习惯保持一致。

奇偶校验码的生成与判断可以通过非常简单的数字电路(逻辑门)实现,尤其是:偶校验 = 所有比特的异或和,即:

data[0] ⊕ data[1] ⊕ data[2]... ⊕ data[n-1]
# 结果是: 
# 0 → 偶数个1(满足偶校验)
# 1 → 奇数个1(不满足偶校验)# ⊕: 异或(模2加)
00  =  0 
01  =  1 
10  =  1 
11  =  0  # 两比特相"异" 时,结果为1# 偶校验: 01001101 11010111
# 求偶校验位: 
# 1001101 ==》 经过计算得0,所以前面写0 ==》01001101
1001101 = 0 
# 1010111 ==》 经过计算得1,所以前面写1 ==》11010111
1010111 = 1# 进行偶校验(所有位进行异或,若结果为1说明出错): 
01001101 = 0  # 正确
# 假设最后一位由1变成了0,则计算结果为1,可以发现出错
11010110 = 1 # 出错
# 可以发现最后两位都由1变成了0,但是计算结果仍然是0,所以: 
# 无法检测出偶数位错误
11010100 = 0

奇偶校验的作用和局限性

  1. 优点: 实现简单,计算开销非常小(硬件中1个异或门就能实现),可以检测单个比特错误

  2. 缺点:

    缺陷点说明
    检测能力弱只能检测奇数个错误(如 1、3、5 位错),偶数位错误无法检测
    无法纠错它只能 "发现" 错误,不能 "修正" 错误的位置或内容
    不能应对高误码环境在噪声严重的物理环境中效果较差

奇偶校验码常用于以下低速或对可靠性要求不高的场景:

  1. 老式串口通信(如 RS-232)
  2. 内存 ECC 简化模式
  3. 早期网络协议(如 HDLC、PPP)中可作为第一道错误检测

知识回顾:

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

本小节总览:

CRC 的基本思想是: 把整个数据当成一个 "二进制多项式",然后用另一个 "预先约定好的多项式" 去做除法,取余数作为 "校验码" 加在数据末尾,接收方再除一次,如果余数不为0,就说明出错了。这就像你寄快递时在包裹外面贴了个验收码,收件人用规则检查发现对不上,就知道途中被调包/损坏了。

要通俗理解 CRC,需要掌握几个核心概念:

  1. 数据看成多项式, 假设你要发送的数据是这样一个 8 位二进制串:10110011,我们把它视为一个 "多项式",例如:

    1·x⁷ + 0·x⁶ + 1·x⁵ + 1·x⁴ + 0·x³ + 0·x² + 1·x¹ + 1·x⁰
    # 即为: 
    x⁷ + x⁵ + x⁴ ++ x⁰
    

    这个就叫 数据多项式

  2. 生成多项式(G(x))是事先约定好的 "除数",发送方和接收方都要提前约定一个 "生成多项式",例如:

    G(x) =+ x + 1 ⇒ 对应二进制是: 1011
    # 1 * x³ + 0·x² + 1·x¹ +  1·x⁰	
    

    这个多项式的位数 = 校验码的位数 + 1,所以这个 G(x) 的校验码长度是:3位

具体的 CRC 编码过程:

# ➤ 第一步: 数据后补 0
# 既然你打算生成一个3位校验码,就在数据后面补上3个0
# 原数据: 10110011  
# 补零后: 10110011000   ← 11位# ➤ 第二步: 用 G(x) 做二进制除法
# 对 10110011000 用生成多项式 1011 做二进制除法(注意这里的除法不是普通的除法,而是用 异或(XOR) 来代替减法):
# 只要会 "竖式除法" 和 "异或运算" 就能算 CRC
# 核心规则是: 
# 每次从高位开始,如果被除数的首位是1,就把 G(x) 对齐后异或,否则跳过这一位
# 最终余数就是 CRC 校验码# 举个直觉化的比喻: 
# 它就像你用尺子划过一段木板,哪块凸出来(1)就削一下(异或),平了就跳过
# 最后 "削剩下的" 就是校验码# ➤ 第三步: 把"余数"加在原始数据后面,假设你除完之后的余数是 101
# 那么最终发送的数据就是: 
# 10110011 101
这就是完整的 "数据帧 + CRC校验码"# 接收方做什么?
# 收到后,接收方也用同样的生成多项式 1011 去除整段 10110011101
# 如果结果 没有余数(即余数为 0) → 数据无误
# 否则说明数据在传输中出错了

这样可能不太好理解,我们结合图示来理解每一个步骤:设生成多项式为 G(x)=x3+x2+1,信息码为 101001,求对应的 CRC 码:

  1. 确定 K、R 以及生成多项式对应的二进制码。K = 信息码的长度 = 6,多项式对应二进制码为:1011,4 位,减去 1,则 R = 3(也可以直接取生成多项式的最高次幂 3),总位数:N = K + R = 9

  2. 信息码为 101001,且 R = 3,则补 0 后的数据为:101001000

  3. 对补 0 后的数据用生成多项式进行模 2 除法,产生余数

  4. 则对应的 CRC 码 为:001,完整发送的数据:101001001

  5. 检错和纠错:

总结口诀: CRC 除法就像长除法,只是每次减法用的是异或!CRC 码有些表示的是单独的校验位,不包括原始数据,有些又会把原始数据算上,这个只要你知道在说什么就好了,具体情况具体分析。----- 本小节我也混用了,不管了

拓展: 实际中,CRC 一般不用于纠错,而是用于 错误检测,所以下面的了解一下即可。

3.3 海明校验码(Hamming Code)

Richard Hamming 演讲选段:早年,我在攻克一个又一个难题,成功的多,失败的少。可是,周五解决了一个问题回到家里后,我却并不快活,反而很沮丧。我看到生活就是一个问题接着一个问题又接着另一个问题。想了相当长一阵子后,我决定以另一种方式干活:你的工作要成为别人工作的基石!于是别人就会说: "看哪,我站在他的肩膀之上,我看得更远了"。科学的本质是积累!我再也不去做相互孤立的问题,除非它能代表某一类问题的共性。我决不再去解决单一的问题。你要么让人们在你的成果上有所建树,要么别人不得不把你干的活从头再来复制一遍。

当你通过网络/通信线路发送数据时,可能某一位会出错。普通奇偶校验只能检测是否有错误,但不能定位是哪一位错了,更不能修复它。海明码的目标是: 能发现 1 位错误,能准确定位是哪一位错,并自动纠正。一句话理解: 海明码是一种能检测并纠正1位错误的纠错码,通过插入特定的校验位,使得每一位错误都能被唯一定位。海明码的基本原理: 插入若干校验位,使得每一位都有唯一 "被谁检查" 的组合,把数据分布在一个比原始数据长的 "码字" 中,每个校验位负责检查若干位(包括它自己或不包括)。

需要多少校验位?

海明码求解步骤:
① 确定校验位数量:

② 确定校验位的分布:

③ 求校验位的值:

④ 检查纠错:

⑤ 最后结果:

海明码求解步骤-格式变化:

拓展:

知识回顾:

四、流量控制与可靠传输

4.1 滑动窗口机制

滑动窗口机制是一种用于 提高链路利用率、实现流量控制保证可靠传输 的方法,广泛应用于 数据链路层(如 HDLC 协议)传输层(如 TCP)

发送窗口(Send Window):发送窗口是发送方维护的一个连续的帧编号区间,它表示当前允许发送但尚未被确认的数据帧范围。窗口大小(N): 可以同时发送的最大未确认帧数。起点: 最早发送但未确认的帧。终点: 起点 + N - 1。如果窗口满了(即未确认的帧数量等于窗口大小),则发送方暂停发送,直到收到确认(ACK)后窗口向前滑动。

接收窗口(Receive Window): 接收窗口是接收方维护的一个帧编号区间,表示其当前准备好接收的数据帧范围,一般与发送窗口同样大小(但不一定),接收到正确的帧后会向前滑动,并发送确认。

重点关注四个方面:

4.2 停止-等待协议(S-W)

要点总览:

停止-等待协议:

数据帧、确认帧、帧序号的概念:

正常情况示例:


异常情况示例:数据帧丢失

异常情况示例:确认帧丢失

为什么一定要给帧编号?

  1. 区分重复帧和新帧: 由于网络可能出现丢包或延迟,发送方可能因为没收到确认而重发上一帧。接收方通过帧编号可以判断收到的帧是新的还是之前已经接收过的重复帧。如果接收方收到的帧编号和上一次接收的帧编号相同,就说明这是重发的重复帧,应丢弃。如果帧编号不同,说明是新帧,可以接收并发送确认

  2. 保证数据的顺序和完整性: 帧编号帮助接收方确保数据按正确顺序接收,不会错乱或重复

  3. 防止确认丢失带来的误解: 如果确认帧(ACK)丢失,发送方会重发上一帧。没有帧编号,接收方无法判断这是重复帧还是新帧,会导致数据混乱。帧编号解决了这个问题

    简单举例(文字):

    发送方发送帧0,等待确认
    接收方收到帧0,处理并回复ACK0
    发送方没收到ACK0,重发帧0
    接收方收到帧0,但它已经处理过了,通过编号知道这是重复帧,丢弃并重新发送ACK0
    发送方收到ACK0后,发送帧1
    

异常情况示例:数据帧有差错

知识回顾:

4.3 后退N帧协议(GBN)

要点总览:

后退N帧协议(Go-Back-N Protocol,简称 GBN): 是数据链路层的一种重要滑动窗口协议,用于实现可靠数据传输。后退N帧协议是一种基于滑动窗口的 ARQ(自动重传请求) 协议,它允许发送方在收到确认前连续发送多个帧,从而提高信道利用率。核心特点:

  1. 发送窗口大于1: 可以连续发送多个帧而无需等待确认

  2. 累积确认: 接收方只需对按序到达的最后一个正确帧进行确认

  3. 出错时后退N帧: 当某个帧出错时,发送方需要重传该帧及其后所有已发送但未确认的帧

正常情况示例:



异常情况示例:数据帧丢失




异常情况示例:确认帧丢失

探讨:如果不满足 WT + WR ≤ 2n 会有什么问题?

知识回顾:

4.4 选择重传协议(SR)

要点总览:

选择重传协议(Selective Repeat Protocol,简称 SR) 是数据链路层另一种重要的滑动窗口协议,它通过选择性重传提高了信道利用率。选择重传协议是一种改进的 ARQ 协议,它只重传真正丢失或损坏的帧,而不是像 GBN 那样重传所有未确认帧。核心特点:

  1. 发送窗口和接收窗口都大于1: 可以缓存多个帧
  2. 独立确认: 每个正确接收的帧都会被单独确认
  3. 选择性重传: 只重传真正丢失或损坏的帧
  4. 乱序接收: 可以接收并缓存乱序但正确的帧

选择重传协议的窗口大小限制条件:

正常情况示例:


异常情况示例:数据帧丢失




异常情况示例:数据帧因差错而被丢失




异常情况示例:确认帧丢失


探讨:如果不满足 WT + WR ≤ 2n 会有什么问题?


知识回顾与重要考点:

4.5 三种协议的信道利用率分析

知识总览:

S-W 协议的信道利用率:

例题:2018真题_36

GBN、SR 协议的信道利用率:

例题:2014真题_36

例题:2015真题_35

术语补充:滑动窗口协议

术语补充:ARQ 协议、连续 ARQ 协议

知识回顾

本文为个人学习记录与复习整理之用,旨在帮助自己系统巩固计算机网络相关知识,同时也希望能为正在学习该领域的同学提供一些参考与帮助。部分内容参考了公开课资料、他人学习笔记或网络公开资源,其中部分图片或示意图来自网络,仅用于非商业性质的学习交流。如有侵权或不当引用之处,敬请联系我删除或更正。
在这里插入图片描述

    好书不厌读百回,熟读课思子自知。而我想要成为全场最靓的仔,就必须坚持通过学习来获取更多知识,用知识改变命运,用博客见证成长,用行动证明我在努力。
    如果我的博客对你有帮助、如果你喜欢我的博客内容,请 点赞评论收藏 一键三连哦!听说点赞的人运气不会太差,每一天都会元气满满呦!如果实在要白嫖的话,那祝你开心每一天,欢迎常来我博客看看。
 编码不易,大家的支持就是我坚持下去的动力。点赞后不要忘了 关注 我哦!

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

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

相关文章

铸铁试验平台的重要性及应用前景

铸铁作为一种重要的金属材料,在工业生产中扮演着举足轻重的角色。为了确保铸铁制品的质量和性能,铸铁材料的试验是必不可少的环节。而铸铁试验平台则是进行铸铁试验的关键设备之一,它为铸铁材料的研究和开发提供了重要的技术支持。本文将探讨…

std::shared_ptr引起内存泄漏的例子

目录 一、循环引用(最常见场景) 示例代码 内存泄漏原因 二、共享指针管理的对象包含自身的 shared_ptr 示例代码 内存泄漏(或双重释放)原因 三、解决方案 1. 循环引用:使用 std::weak_ptr 2. 对象获取自身的 …

AI 知识数据库搭建方案:从需求分析到落地实施

AI 知识数据库的搭建需结合业务场景、数据特性与技术架构,形成系统化解决方案。以下是一套完整的搭建框架,涵盖规划、设计、实施及优化全流程: 一、前期规划:需求分析与目标定义 1. 明确业务场景与知识需求 场景导向&#xff1a…

Tensorflow 基础知识:变量、常量、占位符、Session 详解

在深度学习领域,TensorFlow 是一个广泛使用的开源机器学习框架。想要熟练使用 TensorFlow 进行模型开发,掌握变量、常量、占位符和 Session 这些基础知识是必不可少的。接下来,我们就深入了解一下它们的概念、用处,并通过代码示例进行演示。 一、常量(Constant) 常量,顾…

linux 常见问题之如何清除大文件的内容

linux 常见问题之如何清除大文件的内容 在 Linux 系统中,我们有时会遇到文件随着时间增长变得巨大,最常见的就是服务器的日志文件,随着时间的推移占用大量的磁盘空间,下面介绍如何清楚大文件的内容,当然避免文件内容过…

薛定谔的猫思想实验如何推演到量子计算

前言 这是我的选修课作业,但是我并不喜欢小论文方式的写法,死板又老套。先在这打一份底稿。 薛定谔的猫 可能一说到量子这个关键词,大家第一时间都会想到的是“薛定谔的猫”。 实验介绍 薛定谔的猫是一个著名的思想实验,由奥…

嵌入式开发中fmacro-prefix-map选项解析

在嵌入式开发中,-fmacro-prefix-map 是 GCC 和 Clang 等编译器提供的一个路径映射选项,主要用于在预处理阶段重写宏定义中出现的绝对路径。它的核心目的是解决以下问题: 核心作用 构建可重现性 消除编译输出(如 .o、.d 文件&…

Javaweb学习——day3(Servlet 中处理表单数据)

文章目录 一、概念学习1. GET vs POST 请求方式的区别2. HttpServletRequest 获取表单数据 二、代码讲解与练习第 1 步:在 webapp 下创建 login.html第 2 步:在 com.example 包下创建 LoginServlet第 3 步:修改 web.xml 注册 LoginServlet第 …

在 iOS 开发中单独解析域名为 IP

1 为什么要自己解析? 典型场景说明劫持/污染检测比较 系统解析 与 自建 DNS 的差异QoS / CDN 选路对每个候选 IP 做 RT/丢包测速系统 API(NSURLSession / Network.framework)在「真正建立连接之前」不会把解析结果暴露出来,因此需要主动解析一步。 2 API 选型概览 API是否过…

YOLOv1 技术详解:正负样本划分与置信度设计

🔍 YOLOv1 技术详解:正负样本划分与置信度设计 一、前言 YOLOv1 是目标检测领域中具有划时代意义的算法之一,它将检测任务统一为一个回归问题,实现了“You Only Look Once”的端到端实时检测。其中,正负样本的划分机…

为 Nginx 配置 HTTPS(以 n8n 为例)完整教程【CentOS 7】

在部署如 n8n 这类自动化平台时,为了保障数据传输安全,我们通常会使用 HTTPS 访问。本文将以 n8n.example.com 为例,介绍如何在 CentOS 7 系统中通过 Nginx 为本地运行在端口 5678 的 n8n 服务配置免费 SSL 证书(Let’s Encrypt&a…

Elasticsearch从安装到实战、kibana安装以及自定义IK分词器/集成整合SpringBoot详细的教程ES(四)查询、排序、分页、高亮

基础代码 package com.test.xulk;import com.alibaba.fastjson.JSON; import com.test.xulk.es.esdoc.HotelDoc; import com.test.xulk.es.service.IHotelService; import org.apache.http.HttpHost; import org.elasticsearch.action.search.SearchRequest; import org.elast…

一个数组样式上要分成两个

如图所示&#xff0c;要有一个区分来显示&#xff0c;如果一开始就是这样还可以有很多种处理方式&#xff0c;但是这个后期一直在调整所以不好重做因为开发已经完成&#xff0c;加上很多地方联动改的地方太多&#xff0c;所以采用了一个比较笨的方法 <ul class"classif…

NLP进化史:从规则模板到思维链推理,七次范式革命全解析

“语言不是神的创造物&#xff0c;而是平凡人类的产物。”——诺姆乔姆斯基 自然语言处理&#xff08;NLP&#xff09;的发展史&#xff0c;就是人类试图教会机器理解语言本质的探索史。本文将带您穿越70年技术长河&#xff0c;揭示NLP领域关键的范式转换里程碑。 一、规则驱动…

Yarn与NPM缓存存储目录迁移

Yarn与NPM缓存存储目录迁移 背景与需求 解释Yarn和NPM缓存机制的作用及默认存储路径迁移缓存目录的常见原因&#xff08;如磁盘空间不足、系统盘性能优化、多项目协作需求&#xff09; Yarn缓存目录迁移方法 查看当前Yarn缓存目录的命令&#xff1a;yarn cache dir修改Yarn…

Python爬虫-批量爬取快手视频并将视频下载保存到本地

前言 本文是该专栏的第80篇,后面会持续分享python爬虫干货知识,记得关注。 本文笔者以快手为例子,基于Python爬虫来实现批量采集视频,并将视频下载以及保存到本地。 而具体的“视频采集以及视频下载,保存”思路逻辑,笔者将在正文中结合“完整代码”来详细介绍每个步骤。…

org.springframework.cloud.openfeign 组件解释

我们来详细解释一下 org.springframework.cloud.openfeign 这个组件。 一句话概括&#xff1a;它是一个声明式的、模板化的HTTP客户端&#xff0c;旨在让微服务之间的REST API调用变得像调用本地方法一样简单。 为了让你彻底理解&#xff0c;我会从以下几个方面来解释&#x…

2025年06月13日Github流行趋势

项目名称&#xff1a;awesome-llm-apps 项目地址url&#xff1a;https://github.com/Shubhamsaboo/awesome-llm-apps项目语言&#xff1a;Python历史star数&#xff1a;37,536今日star数&#xff1a;1,287项目维护者&#xff1a;Shubhamsaboo, Madhuvod, libw0430, AndrewHoh, …

Go语言底层(五): 深入浅出Go语言的ants协程池

在 Go 语言中&#xff0c;goroutine 的轻量特性使得高并发编程变得异常简单。然而&#xff0c;随着并发量的增加&#xff0c;频繁创建对象和无限制启动 goroutine 也可能带来内存浪费、GC 压力和资源抢占等问题。为了解决这些隐患&#xff0c;协程池成为常用的优化手段。用于控…

React Native【实战范例】网格导航 FlatList

import React from "react"; import {FlatList,Image,SafeAreaView,StyleSheet,Text,View, } from "react-native"; interface GridItem {id: string;title: string;imageUrl: string; } // 网格布局数据 const gridData Array.from({ length: 30 }, (_, …