「网络编程」数据链路层协议_ 以太网协议学习
「前言」文章内容是数据链路层以太网协议的讲解。
「归属专栏」网络编程
「主页链接」个人主页
「笔者」枫叶先生(fy)
目录
- 一、以太网协议简介
- 二、以太网帧格式(报头)
- 三、MTU对上层协议的影响
- 四、ARP协议
- 4.1 ARP协议的作用
- 4.2 ARP协议报头
一、以太网协议简介
以太网协议是TCP/IP体系中的数据链层协议
以太网协议位于数据链路层:

链路层解决的问题
- 网络层解决的问题是:将数据从一台主机跨网络送到另一台主机,也就是数据的路由(路径选择)
- 网络层的数据包封装成IP报文之后,依旧要继续向下交付,交付给下一层:数据链路层
- 再由数据链路层把IP报文封装成数据帧,再由数据链路层发送到网络里。这时,所谓的“数据包”才真正意义的进入网络
- 即在网络(网线)上跑的是数据帧,不是IP报文
- 网络层的IP协议是为数据的路由提供决策(提供跨网络传输的能力,有能力不一定能做到),而真正的对数据进行转发的是数据链路层(正真做事的)
- 把数据帧转发给与当前主机直接相连的下一跳主机(两台主机直接相连也就意味着这两台主机属于同一网段,因此将数据转发到下一跳主机实际是属于局域网通信范畴的,而这实际就是链路层需要解决的问题)
即数据链路层要解决的问题是:把数据帧转发给与当前主机直接相连的下一跳主机,即解决两台直接相连的主机之间的通信问题
注:不同的协议层对数据包有不同的称谓,在传输层叫做段(segment),在网络层叫做数据报 (datagram),在链路层叫做帧(frame)
跨网络传输的本质是无数个子网(局域网)转发的结果

要彻底理解跨网络转发,首先要理解一个局域网中报文的转发原理
基本概念
- “以太网”不是一种具体的网络,而是一种技术标准:既包含了数据链路层的内容,也包含了一些物理层的内容
- 例如:以太网规定了网络拓扑结构,访问控制方式,传输速率等
- 例如:以太网中的网线必须使用双绞线;传输速率有10M,100M,1000M等
- 以太网是当前应用最广泛的局域网技术,和以太网并列的还有令牌环网,无线LAN等
局域网技术
不同局域网所采用的通信技术可能是不同的,常见的局域网技术有以下三种:
- 以太网:以太网是一种局域网(LAN)技术,应用最普遍的局域网技术。以太网的特点是具有较高的数据传输速率和较低的成本
- 令牌环网:令牌环网是一种早期的局域网技术,令牌环网使用了一种称为令牌传递的机制来控制数据传输(只有持有令牌的设备才能发送数据)
- 无线局域网(WLAN)和无线广域网(WAN)是无线网络技术。WLAN使用无线电波代替有线电缆来连接设备,使设备可以无线访问局域网。
MAC地址
- 在同一局域网的两台主机能够直接进行通信
- 每一台主机都有自己的“名字”:每一台主机都有网卡,每一张网卡都有自己的地址,这个地址称为MAC地址,表明自己在局域网中的唯一性(主机唯一)
- MAC地址长度为48位,6个字节,一般用16进制数字加上冒号的形式来表示(例如:
08:00:27:03:fb:19)
在Linux查看自己的主机的MAC地址:使用ifconfig命令查看, ether对应就有”以太“的意思(但实际云服务器上的MAC地址可能不是真正的MAC地址,该MAC地址可能虚拟技术模拟模拟出来的)

以太网通信原理
以太网中所有的主机共享一个通信信道,当局域网中的一台主机发出数据后,该局域网中的所有主机都能够收到该数据

- 例如,当局域网中的主机A想要发送数据给主机E时,其实局域网当中的每一台主机都能收到主机A发出去的数据
- 各个主机在对比自己的MAC地址和数据帧中的目的MAC地址,发现数据帧中的目的MAC地址与自己的MAC地址不匹配,就直接丢弃该报文,不进行向上交付(在数据链路层丢弃)
- 只最终只有主机E会将主机A发来的数据向上进行交付
补充
- 网络抓包工具(局域网抓包),不进能抓自己主机的数据报文,也能抓该局域网下其他主机的报文
- 原理是:网卡有一种模式叫做混杂模式,被设置为混杂模式的网卡能够接收所有经过它的数据帧,不管该数据包是不是自己主机的,只要接收到数据帧就直接向上交付
令牌环网(简单赘述)
- 在令牌环网中,令牌按照固定的顺序在节点之间传递。每个节点在拥有令牌时可以访问共享资源,然后将令牌传递给下一个节点。当一个节点完成对共享资源的访问后,它将令牌传递给下一个节点(按顺序传递)
- 在令牌环网中,只有持有令牌的主机才能发送数据(令牌相当于互斥锁)
二、以太网帧格式(报头)
以太网帧格式如下:

字段解释:
- 源地址和目的地址是指网卡的硬件地址(也叫MAC地址),长度是48位,是在网卡出厂时固化的
- 帧协议类型字段有三种值,分别对应IP协议、ARP协议和RARP协议
- 帧末尾是CRC校验码
MAC帧如何将报头与有效载荷进行分离??
- 简单粗暴:固定字长
- 以太网MAC帧的帧头和帧尾都是固定长度的(18字节),因此当底层收到一个MAC帧后,直接提取出MAC帧当中固定长度的帧头和帧尾,此时剩下的就是有效载荷了
MAC帧如何决定将有效载荷交付给上层的哪一个协议?(如何分用)
- MAC帧的帧头当中有2个字节的类型字段,该字段填写有协议的编号,如果是
0800就是交付给IP协议,0806就是交付给ARP协议,0838交付给RARP协议 - 因此在分离出报头和有效载荷后,根据该字段将有效载荷交付给对应的上层协议即可
数据碰撞
- 由于以太网中的所有的主机共享一个通信信道,因此在同一时刻只允许有一台主机发送数据,否则各个主机发送的数据就会相互干扰
- 站在系统的角度来看,这里各个主机所共享的通信信道就是一种临界资源,这个临界资源同一时刻只允许一台主机使用
- 在同一局域网中,如果多台主机同时发生数据(同一时刻),发送的数据就会互相干扰,就会造成数据碰撞,这些数据就变成了无效的数据,只能被丢弃
- 每一个局域网都可以看作是一个碰撞域,如果某个主机发送出去的数据与其他主机发送的数据之间产生了干扰,我们就称这两台主机在该碰撞域中发生了碰撞
如何知道发生数据碰撞了??
-
通过碰撞检测算法进行检测,发生碰撞了通过碰撞避免算法解决
-
如果检测到发生碰撞了,在数据链路层的协议就会触发策略,发生数据碰撞的主机就不发数据了,等一段时间再进行发送
-
数据碰撞发生的概率比较低,如果局域网中的主机过多或者发送数据过多,也会容易发生碰撞
一个局域网不能很大,为什么??
- 局域网太大,就意味着主机多,任何时刻发生碰撞的概率就增加了
如果一个局域网过大,就要引入一种设备,叫做交换机,交换机是工作在数据链路层的
- 交换机的作用之一就是隔离,交换机可以识别局部性的碰撞,对碰撞的数据不进行转发
- 例如,主机A和主机D发生了数据碰撞,交换机识别到了数据碰撞,就对该碰撞的数据不进行转发到右边的网络里,右侧的网络在一定程度上发生碰撞的概率就降低了
- 交换机有效的对碰撞域进行了分割(划分碰撞域)

一台主机发送数据的时候,发送数据量长了好,还是短了好??
- 数据量长了容易发生碰撞,数据量短了效率也低
- 所以,对发送的数据帧要有一定的范围大小,既不能太大,也不能太小
- 在以太网协议里,就有对发送数据的有效载荷大小有规定,有效载荷最小46字节,最大1500字节
- 如果发送数据量小于46字节,则需要在数据后面补填充位,超过1500字节无法发送

最大传输单元 MTU
最大发送的有效载荷1500字节,1500字节就是MTU
- 最大传输单元(
Maximum Transmission Unit,MTU)是指在网络通信中,数据链路层能够传输的最大有效载荷的大小。MTU的大小通常由网络设备或网络协议规定,它限制了一次可传输的数据量 - MTU默认的大小一般是1500字节,不同的数据链路层标准的MTU是不同的
- 如果一次要发送的数据超过了MTU,则需要在IP层对数据进行分片
在Linux下使用ifconfig命令可以查看对应的MTU

三、MTU对上层协议的影响
MTU对IP协议的影响
- 由于数据链路层MTU的限制,对于较大的IP数据包要进行分片
- 分片已经在IP协议谈过了,不再赘述
MTU对UDP协议的影响
- IP报头当中如果不携带选项字段,那么IP报头的长度就是20字节,而UDP采用的是定长的8字节报头
- 因此如果UDP一次携带的数据超过了
1500 − 20 − 8 = 1472字节,此时数据就需要在IP层进行分片 - 那么这就意味着,如果UDP数据报在网络层被分片,整个数据被丢失的概率就大大增加了
MTU对于TCP协议的影响
对于TCP来说,分片也会增加TCP报文丢包的概率,但与UDP不同的是TCP丢包后还需要进行重传,因此TCP应该尽量减少因为分片导致的数据重传
- TCP的一个数据报也不能无限大, 还是受制于MTU
- TCP的单个数据报的最大消息长度,称为
MSS(Max Segment Size) - TCP在建立连接的过程中,通信双方会进行MSS协商
- 最理想的情况下,MSS的值正好是在IP不会被分片处理的最大长度(这个长度仍然是受制于数据链路层的MTU)
- 双方在发送SYN的时候会在TCP报头写入自己能支持的MSS值
- 然后双方得知对方的MSS值之后,选择较小的作为最终MSS
- MSS的值就是在TCP首部的40字节变长选项中
MSS和MTU的关系如下:

- 假设IP报头当中如果不携带选项字段,那么IP报头的长度就是20字节;TCP报头当中如果不携带选项字段那么IP报头的长度就是20字节
- 即TCP的有效载荷最多
1500-20-20 = 1460字节,即MSS的最大值
四、ARP协议
4.1 ARP协议的作用
ARP(
Address Resolution Protocol)是一种根据IP地址获取MAC地址的协议,ARP是一个介于数据链路层和网络层之间的协议
例如:

- 比如,数据从主机B经过各种路由转发到达主机C
- 每两个相连的节点隶属于同一个子网,但是想给另一个节点发送数据,就必须知道对方的MAC地址
- 但是每个节点只知道下一个直接相连节点的IP地址,因此每个主机必须通过某种方式得到下一个主机的MAC地址,只有知道了对方的MAC地址,才能给对方发数据
实际大部分情况下我们只知道对方的IP地址,因此需要通过ARP协议来根据IP地址来获取目标主机的MAC地址
注: ARP不是一个单纯的数据链路层的协议,而是一个介于数据链路层和网络层之间的协议
ARP协议的定位
介于数据链路层和网络层之间

4.2 ARP协议报头
ARP协议报头如下:

字段解释:
- 硬件类型:指链路层的网络类型,1为以太网
- 协议类型:指要转换的地址类型,0x0800为IP地址
- 硬件地址长度:对于以太网地址为6字节,因为MAC地址是48位的
- 协议地址长度:对于IP地址为4字节,因为IP地址是32位的
- op字段:为1表示ARP请求,op字段为2表示ARP应答
从ARP的数据格式也可以看出,ARP是MAC帧协议的上层协议,由于ARP数据包的长度不足46字节,因此ARP数据包在封装成为MAC帧时还需要补上18字节的填充字段
ARP请求的过程
同一局域网内,主机A想给主机B发送数据(知道IP地址),但是主机A不知道主机B的MAC地址,此时主机A就会触发ARP请求,把ARP请求广播到该局域网中,然后等待主机B发送ARP应答给主机A,最后得知主机B的MAC地址
主机A构建ARP请求流程如下:
- 主机A构建的是ARP请求,所以ARP请求当中的op字段设置为
1 - ARP请求当中的硬件类型字段设置为
1,表示以 以太网通信 - ARP请求当中的协议类型设置为
0800,代表的是使用另一台主机的IP地址来获取另一台主机的MAC地址 - ARP请求当中的硬件地址长度和协议地址长度分别设置为6和4字节,因为MAC地址的长度是48位,IP地址的长度是32位
- ARP请求当中的发送端以太网地址和发送端IP地址,对应就是主机A自己的MAC地址和IP地址
- ARP请求当中的目的以太网地址和目的IP地址,对应就是主机B的MAC地址和IP地址,但由于主机A不知道主机B的MAC地址,因此将目的以太网MAC地址的二进制序列设置为全1,表示在局域网中进行广播
ARP请求构建完成,如下:

ARP请求构建完成后,需要向下交付给以太网协议,进行封装MAC帧,然后才能发送到以太网里
- 封装MAC帧报头时,以太网源MAC地址对应主机A的MAC地址,以太网目的MAC地址对应主机B的MAC地址
- 但由于主机A不知道主机B的MAC地址,因此MAC帧报头当中的以太网目的地址的二进制序列也只能设置为全1(16进制全F),表示在局域网中进行广播
- 封装的是一个ARP请求数据包,因此MAC帧当中的帧类型字段设置为
0806,代表ARP请求 - 由于ARP请求数据包的长度只有28字节,不足46字节,因此还需要在MAC帧的有效载荷当中补上18字节的填充字段(PAD)
封装好的数据帧如下:

封装好MAC帧之后,就可以发送到局域网中了
- 局域网中的每台主机都收到该数据帧,每台主机都会对该数据帧进行解包
- 这些主机识别到MAC帧当中的帧类型字段为
0806后,便知道这是一个ARP的请求或应答的数据包,于是会将MAC帧的有效载荷向上交付给ARP协议 - ARP协议对该ARP请求进行解包,首先查看OP字段,于是判定这是一个ARP请求
- 然后再提取出ARP数据包当中的目的IP地址字段,与自己主机的IP地址进行匹配,不匹配直接丢弃该报文
- 只有IP地址匹配的主机,才会构建ARP应答
ARP应答的过程
主机B进行构建ARP应答:(相同的地方就不再赘述)
- ARP应答当中的op字段设置为2,代表ARP应答
- ARP应答当中的源MAC地址和源IP地址,对应就是主机B的MAC地址和IP地址
- ARP应答当中的目的以太网地址和目的IP地址,对应就主机A的MAC地址和IP地址(从ARP请求里获取)
ARP应答构建完成如下:

ARP应答构建完成后,需要向下交付给以太网协议,进行封装MAC帧,然后才能发送到以太网里
- 封装MAC帧报头时,以太网源MAC地址对应主机B的MAC地址,以太网目的MAC地址对应主机A的MAC地址
- 封装的是一个ARP应答数据包,因此MAC帧当中的帧类型字段设置为
0835,代表ARP应答 - 由于ARP请求数据包的长度只有28字节,不足46字节,因此还需要在MAC帧的有效载荷当中补上18字节的填充字段(PAD)
封装好的数据帧如下:

MAC帧封装完毕后,主机B就可以将封装好的MAC帧发送到局域网当中了
- 局域网当中的每台主机在底层都能收到这个MAC帧,只有主机A将解包后MAC帧的有效载荷向上交付给ARP协议
- ARP收到这个数据包后,发现ARP数据包当中的op字段为2,于是判定这是一个ARP应答,然后就会提取出ARP数据包当中的源MAC地址和源IP地址
- 此时主机A就拿到了主机B的MAC地址
ARP缓存表
ARP缓存表(Address Resolution Protocol Cache Table)是一种用于存储IP地址与MAC地址之间映射关系的缓存表
- 当一台主机需要与另一台主机通信时,首先会检查自己的ARP缓存表,看是否已经有目标主机的IP地址与MAC地址的映射关系
- 如果有,则直接使用该映射关系进行通信
- 如果没有,则会发送一个ARP请求广播,询问局域网中的其他主机,以获取目标主机的MAC地址
- 目标主机收到ARP请求后,会发送一个ARP回应,将自己的IP地址与MAC地址发送给请求方,请求方将这个映射关系存储到自己的ARP缓存表中
也就是说,一台主机需要与另一台主机通信时,并不是每次都会进行ARP请求,而是先去ARP缓存表里面查看是否有另一台主机的MAC地址
注意:ARP缓存表中的映射关系有一定的有效期限,如果在有效期限内没有再次使用该映射关系,系统会自动删除该条目,以保持ARP缓存表的更新和有效性(即ARP缓存表会不断更新,覆盖老的映射关系)
在Linux查看ARP缓存表,使用命令arp -a

ARP欺骗
ARP欺骗(ARP spoofing)是一种网络攻击技术,也被称为ARP缓存投毒(ARP cache poisoning)
攻击者通过伪造ARP回应,将自己的MAC地址与其他主机的IP地址进行映射,从而欺骗网络中的其他主机
大致如下:
- ARP协议是将IP地址转换为MAC地址的协议,它在局域网中进行通信时使用。当一台主机需要与另一台主机通信时,会发送一个ARP请求广播,询问目标主机的MAC地址
- 目标主机收到ARP请求后,会发送一个ARP回应,将自己的IP地址与MAC地址发送给请求方
- 目标主机收到ARP请求后,会发送一个ARP回应,将自己的IP地址与MAC地址发送给请求方
- 在ARP欺骗攻击中,攻击者会发送伪造的ARP回应,将自己的MAC地址与其他主机的IP地址进行映射
- 这样,当其他主机需要与目标主机通信时,会通过ARP缓存表中的映射关系发送数据给攻击者,而不是真正的目标主机
- 攻击者可以利用这种方式进行数据窃取、中间人攻击等恶意行为
RARP协议
- RARP(
Reverse Address Resolution Protocol,逆地址解析协议)是一种与ARP相对应的协议 - 与ARP协议将IP地址解析为MAC地址相反,RARP协议将MAC地址解析为IP地址
--------------------- END ----------------------
「 作者 」 枫叶先生
「 更新 」 2023.10.28
「 声明 」 余之才疏学浅,故所撰文疏漏难免,或有谬误或不准确之处,敬请读者批评指正。
相关文章:
「网络编程」数据链路层协议_ 以太网协议学习
「前言」文章内容是数据链路层以太网协议的讲解。 「归属专栏」网络编程 「主页链接」个人主页 「笔者」枫叶先生(fy) 目录 一、以太网协议简介二、以太网帧格式(报头)三、MTU对上层协议的影响四、ARP协议4.1 ARP协议的作用4.2 ARP协议报头 一、以太网协…...
通过python操作neo4j
在neo4j中创建结点和关系 创建结点 创建电影结点 例如:创建一个Movie结点,这个结点上带有三个属性{title:‘The Matrix’, released:1999, tagline:‘Welcome to the Real World’} CREATE (TheMatrix:Movie {title:The Matrix, released:1999, tagl…...
Ubuntu中查看电脑有多少个核——lscpu
1. 使用lscpu命令: 打开终端并输入以下命令: lscpu你会看到与CPU相关的详细信息。查找"CPU(s)"这一行来看总的核心数。另外,“Core(s) per socket”表示每个插槽或每个物理CPU的核数,“Socket(s)”表示物理CPU的数量。将这两个值相乘即得到总…...
Python学习笔记第七十二天(Matplotlib imread)
Python学习笔记第七十二天 Matplotlib imread读取图像数据修改图像裁剪图像图像颜色 后记 Matplotlib imread imread() 方法是 Matplotlib 库中的一个函数,用于从图像文件中读取图像数据。 imread() 方法返回一个 numpy.ndarray 对象,其形状是 (nrows,…...
安卓核心板_天玑700、天玑720、天玑900_5G模块规格参数
5G安卓核心板是采用新一代蜂窝移动通信技术的重要设备。它支持万物互联、生活云端化和智能交互的特性。5G技术使得各类智能硬件始终处于联网状态,而物联网则成为5G发展的主要动力。物联网通过传感器、无线网络和射频识别等技术,实现了物体之间的互联。而…...
CS224W2.2——传统基于特征的方法(边层级特征)
在这篇中,我们介绍了链接预测的重要任务,以及如何提取链接级特征来更好地解决这类问题。这在我们需要预测缺失的边或预测将来会出现的边的情况下很有用。我们将讨论的链路级功能包括基于距离的功能,以及本地和全局邻域重叠。 文章目录 1. 边层…...
python—openpyxl操作excel详解
前言 openpyxl属于第三方模块,在python中用来处理excel文件。 可以对excel进行的操作有:读写、修改、调整样式及插入图片等。 但只能用来处理【 .xlsx】 后缀的excel文件。 使用前需要先安装,安装方法: pip install openpyxl…...
汽车行驶性能的主观评价方法(2)-驾驶员的任务
人(驾驶员)-车辆-环境闭环控制系统 驾驶过程中,驾驶员承担着操纵车辆和控制车辆的任务。驾驶员在不知不觉中接受了大量光学、声学和动力学信息并予以评价,同时不断地通过理论值和实际值的比较来完成控制作用(图 2.1&a…...
server2012 通过防火墙开启局域网内限定IP进行远程桌面连接
我这里需要被远程桌面的电脑系统版本为windows server2012 1、打开允许远程连接设置 2、开启防火墙 3、设置允许“远程桌面应用”通过防火墙 勾选”远程桌面“ 3、入站规则设置 高级设置→入站规则→远程桌面-用户模式(TCP-In) 进入远程桌面属性的作用域——>远程IP地址—…...
lvs+keepalived: 高可用集群
lvskeepalived: 高可用集群 keepalived为lvs应运而生的高可用服务。lvs的调度器无法做高可用,于是keepalived软件。实现的是调度器的高可用。 但是:keepalived不是专门为集群服务的,也可以做其他服务器的高可用。 lvs的高可用集群…...
C++标准模板(STL)- 类型支持 (类型特性,is_pointer,is_lvalue_reference,is_rvalue_reference)
类型特性 类型特性定义一个编译时基于模板的结构,以查询或修改类型的属性。 试图特化定义于 <type_traits> 头文件的模板导致未定义行为,除了 std::common_type 可依照其所描述特化。 定义于<type_traits>头文件的模板可以用不完整类型实…...
C++——类和对象(上)
1.面向过程和面向对象初步认识 C语言是面向过程的,关注的是过程,分析出求解问题的步骤,通过函数调用逐步解决问题。 例如手洗衣服 C是基于面向对象的,关注的是对象,将一件事情拆分成不同的对象,靠对象之间…...
ffmpeg中examples编译报不兼容错误解决办法
ffmpeg中examples编译报不兼容错误解决办法 参考examples下的README可知,编译之前需要设置 PKG_CONFIG_PATH路径。 export PKG_CONFIG_PATH/home/user/work/ffmpeg/ffmpeg/_install_uclibc/lib/pkgconfig之后执行make出现如下错误: 基本都是由于库的版…...
Python与CAD系列基础篇(十一)图形旋转、镜像、缩放
目录 0 简述1 图形旋转2 图形镜像3 图形缩放0 简述 本篇详细介绍使用①通过pyautocad连接AutoCAD进行处理②通过ezdxf处理dxf格式文件进行图形旋转、镜像、缩放的方法。 1 图形旋转 pyautocad方式 from pyautocad import Autocad, APoint, aDouble import mathacad = Autoca…...
STM32串口通信
数据通信的基础概念 在单片机的应用中,数据通信是必不可少的一部分,比如:单片机和上位机、单片机和外 围器件之间,它们都有数据通信的需求。由于设备之间的电气特性、传输速率、可靠性要求各 不相同,于是就有了各种通信…...
Kafka笔记
一、Kafka 概述 1.1.定义 传统定义:Kafka 是一个分布式的基于发布/订阅模式的消息队列,主要用于大数据实时处理领域。最新定义:Kafka 是一个开源的分布式事件流平台,被数千家公司用于高性能数据管道、流分析、数据集成和关键任务…...
【1.2】神经网络:神经元与激活函数
✅作者简介:大家好,我是 Meteors., 向往着更加简洁高效的代码写法与编程方式,持续分享Java技术内容。 🍎个人主页:Meteors.的博客 💞当前专栏: 神经网络(随缘更新) ✨特色…...
【PythonRS】Pyrsgis库安装+基础函数使用教程
pyrsgis库是一个用于处理地理信息系统(GIS)数据的Python库。它提供了一组功能强大的工具,可以帮助开发人员使用Python语言创建、处理、分析和可视化GIS数据。通过使用pyrsgis库,开发人员可以更轻松地理解和利用地理信息。 pyrsgis库包含了许多常见的GIS操…...
线扫相机DALSA--分频倍频计算公式及原理
分频倍频计算公式及原理 推导原理: 假设编码器脉冲精度为P;同步轮/辊周长为C,Fov为视野,Res为线扫相机分辨率,N代表N倍频编码器,分频为D,倍频为M 线扫项目常规采用N(N 4࿰…...
1818_ChibiOS的计数信号量
全部学习汇总: GreyZhang/g_ChibiOS: I found a new RTOS called ChibiOS and it seems interesting! (github.com) 之前见过计数信号量,也是在FreeRTOS中看到的。也看到过这样的功能在驱动设计中的应用,但是当时没有理解这个使用的方式。 1.…...
第19节 Node.js Express 框架
Express 是一个为Node.js设计的web开发框架,它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用,和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...
Java如何权衡是使用无序的数组还是有序的数组
在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...
Python实现prophet 理论及参数优化
文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候,写过一篇简单实现,后期随着对该模型的深入研究,本次记录涉及到prophet 的公式以及参数调优,从公式可以更直观…...
剑指offer20_链表中环的入口节点
链表中环的入口节点 给定一个链表,若其中包含环,则输出环的入口节点。 若其中不包含环,则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...
【Go】3、Go语言进阶与依赖管理
前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课,做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程,它的核心机制是 Goroutine 协程、Channel 通道,并基于CSP(Communicating Sequential Processes࿰…...
2025盘古石杯决赛【手机取证】
前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来,实在找不到,希望有大佬教一下我。 还有就会议时间,我感觉不是图片时间,因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...
【RockeMQ】第2节|RocketMQ快速实战以及核⼼概念详解(二)
升级Dledger高可用集群 一、主从架构的不足与Dledger的定位 主从架构缺陷 数据备份依赖Slave节点,但无自动故障转移能力,Master宕机后需人工切换,期间消息可能无法读取。Slave仅存储数据,无法主动升级为Master响应请求ÿ…...
【论文阅读28】-CNN-BiLSTM-Attention-(2024)
本文把滑坡位移序列拆开、筛优质因子,再用 CNN-BiLSTM-Attention 来动态预测每个子序列,最后重构出总位移,预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵(S…...
【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分
一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计,提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合:各模块职责清晰,便于独立开发…...
【JavaWeb】Docker项目部署
引言 之前学习了Linux操作系统的常见命令,在Linux上安装软件,以及如何在Linux上部署一个单体项目,大多数同学都会有相同的感受,那就是麻烦。 核心体现在三点: 命令太多了,记不住 软件安装包名字复杂&…...
