[线程与网络] 网络编程与通信原理(四):深入理解传输层UDP与TCP协议
🌸个人主页:https://blog.csdn.net/2301_80050796?spm=1000.2115.3001.5343
🏵️热门专栏:🍕 Collection与数据结构 (92平均质量分)https://blog.csdn.net/2301_80050796/category_12621348.html?spm=1001.2014.3001.5482
🧀Java EE(95平均质量分) https://blog.csdn.net/2301_80050796/category_12643370.html?spm=1001.2014.3001.5482
🍭MySql数据库(93平均质量分)https://blog.csdn.net/2301_80050796/category_12629890.html?spm=1001.2014.3001.5482
🍬算法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12676091.html?spm=1001.2014.3001.5482
感谢点赞与关注~~~
目录
- 1. 应用层
- 2. 传输层
- 2.1 再谈端口号
- 2.2 UDP协议
- 2.2.1 UDP协议格式
- 2.2.2 UDP协议的特点
- 2.3 TCP协议
- 2.3.1 TCP协议格式
- 2.3.2 TCP协议核心特点(必考面试题)
- 2.3.2.1 确认应答
- 2.3.2.2 超时重传
- 2.3.2.3 连接管理(三次握手,四次挥手)
- 2.3.2.4 滑动窗口
- 2.3.2.5 流量控制
- 2.3.2.6 拥塞控制
- 2.3.2.7 延迟应答
- 2.3.2.8 捎带应答
- 2.3.2.9 粘包问题
- 2.3.2.10 异常情况
1. 应用层
关于应用层协议,一个比较重要的协议就是后续我们要介绍的http协议.这是现成的应用层协议.当然,我们也可以自定义应用层协议.但是想要定义出应用层协议,我们就需要对传输数据的格式进行一系列的约定,具体包含以下两点:
- 约定传输的数据有哪些信息.
- 传输的数据要遵守什么样的格式.
关于格式这个事情,又会涉及到网络传输中字符串的序列化问题,序列化的方式有好多种,常见的有以下几种:
- 基于行文本方式传输
- 基于json
- 基于xml
- 基于yml
- 基于portobuffer
我们下面来举一个例子:比如一个外卖平台.在下单的时候,客户端请求有"配送位置"(即经纬度)和用户id两个数据.
- 基于文本行:
id,位置\n
1234,20E40N\n
- 基于json:(使用花括号作为边界,花括号中是键值对,键和值之间用:隔开)
{
userId:1234
position:"120E40N"
}
- 基于xml:(和html的方式非常相似,是以标签的形式展现的)
<request>
<userId> 1234</userId>
<position> "180E40N"</position>
</request>
- 基于yml(采用缩进的方式,和python的语法类似)
request: userId:1234 position:"120E40N"
- 最后一种portobuffer的序列化方式,是一种二进制的格式,我们后面细说.
2. 传输层
2.1 再谈端口号
在传输层,我们有一个非常重要的概念,叫做端口号,是一个两个字节的无符号整数. 范围是0到65535,其中,0到1023为知名端口号,之后的端口号在客户端启动的时候,操作系统会随机分配一个.
在端口号这里,还有两个非常重要的问题:
- 一个进程是否可以有多个端口号?
可以,比如我们在一个程序中,可能会有"管理端口"和"业务端口",两个端口,可以利用
多个端口对一个程序进行更加精细的控制.只要这个端口号不和其他进程冲突即可. - 一个端口号是否可以有多个进程?
不可以,除非有一种情况,同时使用一个端口号的多个进程使用的通信协议不同,这时候可以一个端口号绑定多个进程.正所谓"一山不能容二虎,除非一公和一母".
上面两个点的关系就像一个名字可以指代多个人,但是一个人不可以同时拥有多个名字.
2.2 UDP协议
2.2.1 UDP协议格式
下面我们对上面这个图进行解释:
- 16位源端口号:这个数据报从哪里来
- 16位目的端口号:这个数据报要到哪去
- 16位UDP长度:表示整个数据报(包括UDP报头+UDP载荷)的最大长度.最大是64KB.
- 16位校验和:在网络传输的整个过程中,可能会出现错误.这时候就需要校验和出马了.那么校验和是如何检验数据报的正确性的呢?
OS会拿着一部分数据进行计算,得到结果,如果数据部分发生了改变,此时得到的结果就会不一样,此时便可以判定该数据报出现了错误.
UDP具体在主机中是怎么进行计算的呢?它在使用一种叫做CRC的算法作为校验:
设定2个字节的变量.把数据中的每一个字节取出,往这个变量上的每个字节上进行累加.如果结果溢出,超过了两个字节,溢出的部分就会舍弃.
拓展:md5算法
处理crc算法,还有一个非常常用的算法,md5算法.是一个字符串的Hash算法,就是把String映射到Map中,这个算法有以下特点:
- 定长:无论输入的内容有多长,得到的结果,一定是固定长度.
- 分散:输入的内容,哪怕只有一点点的改变,计算结果也会有很大的差异.就是因为非常的分散,所以就适合用作字符串的Hash算法,这样可以有效减少Hash冲突.
- 不可逆:原数据转为md5数据格式非常容易,成本很低,但是md5数据格式想要还原为原来的数据,成本非常高,甚至说不可能.就是由于这种特性,所以md5算法经常用于加密领域.
2.2.2 UDP协议的特点
- 无连接
什么是无连接:就是双方不会保存对方的信息,就可以进行通信.比如我们发微信,只要发送的一方点击发送按钮的时候,信息就会发送,对方只能接受,不能拒绝. - 不可靠传输
传输数据的时候,不关心对方是否收到数据,也不管对方收到的数据是否完整,只要把数据发送出去就算完事. - 面向数据报
面相数据报流,就是传输数据的时候,使用的是整个数据报为单位进行传输,每次传输的时候,只能传输一个完整的数据报,不可以传输半个,或者1.5个. - 全双工
通俗一点来讲,就是一条通行链路上,可以进行双向通信,既可以接收,也可以发送.
与全双工相对的是半双工.半双工就是一条通信链路上,只可以进行单线的通信,要不只能接收,要不只能发送.
2.3 TCP协议
TCP全称为"传输控制协议(Transmission Control Protocol").⼈如其名,要对数据的传输进⾏⼀个详细的控制 .
2.3.1 TCP协议格式
由于部分的知识限制,我们目前有一部分的字段还无法解释,所以这里我们先解释一部分.
- 16位源端口号:数据从哪里来.
- 16位目的端口号:数据到哪里去
- 4位首部长度:这里与UDP协议中的长度有一定的区别,TCP这里是数据报头的长度,而UDP中是指报头+载荷的总长度.
这里的4位报头长度可以变化.根据下面选项字段的变化,首部长度也在发生变化.选项这一项可有可无,如果选项这一字段完全没有,这时候,TCP报头是固定字段的20字节,如果拉满,就是60个字节,去掉20个固定字段的字节数,选项最长是40个字节. - 紧急指针:和URG配合使用,一般用于带外数据传输.
2.3.2 TCP协议核心特点(必考面试题)
2.3.2.1 确认应答
确认应答是保证TCP传输可靠性的一个核心机制.所谓可靠传输,我们在之前也提到过,就是尽可能地把数据都发送给接收方,但是这里不可以100%让接收方收到,只是尽可能.
-
所谓确认应答,就是在发送方给接收方发送数据之后,接收方要给发送方返回一个确认应答的数据报,这样发送方就可以确认接收方已经收到这个消息了.我们称确认应答这样的数据报为应答报文,应答报文报头中的6个标志位中,其中ACK那一位为1,所以我们也称应答报文为ACK报文.
但是如果说上图中第二次ACK比第一次先到达主机A的话,那么主机是不是就无法把发送的数据和ACK报文对应起来了呢?不是.
-
TCP将每个字节的数据都进行了编号,用来解决由于发送数据的延迟问题所造成的"不对应"的问题.这个编号就是所谓的序列号.
其中序列号又分为32位序号和32为确认序号,分别对应的是TCP报头结构图中的第2,3两行.- 32位序号就是发送方规定传输数据的字节范围,这其中,每个字节都有编号,且一次递增,比如从1~1000位字节是要传输的数据.
- 32位确认序号就是接收方发送ACK报文确认应答的时候,用来表示发送方某个范围的数据已经收 到的序号,确认序号一般是发送方数据范围的最后一个字节+1,比如用1001表示1~1000的数据已经收到了.
确认序号有两层含义:比如发送方的序号是1~1000
- 1001表示1~1000的数据已经收到了.
- 1001表示接接收方要开始向发送方索要1001开始的数据报.
举例说明:接亲
结婚的时候,总会有男方去女方家接亲的常场面,接亲会有车队,如果后面的车走在的头车(接新娘的车)的前面,先到达娘家的就是后面的车,不可以让新娘坐在后面的车上.这时候如果告诉新娘头车的车牌号,新娘会更具车牌号来辨认头车,新娘也就不会做错车了.上面的序列号和他是同样的道理,数据报中都存在编号,就不会出现发送数据与确认应答数据对不上的情况.
2.3.2.2 超时重传
超时重传也是保证TCP可靠传输的机制.如果上述的确认应答的过程没有那么的顺利,出现了丢包的情况,那么超时重传便会起到一定的作用.
所谓丢包,就是在数据传输的过程中,数据报被丢弃,无法到达指定的发送端.这件事情客观存在,是随机的事件.原因可能是交换机或者是路由器在通信过程中繁忙.导致了多出来的部分直接被丢弃.
- 主机A发送数据给B之后,由于丢包的原因,无法使得数据到达主机B. 如果主机A在⼀个特定时间间隔内没有收到B发来的确认应答,就会进行重发.
- 如果主机A未收到B发来的ACK报文,即确认应答的报文,说明可能是因为ACK也丢失了.此时发送方就会再次对数据进行重传.
但是这种情况下会有一个问题,B会收到两份相同的数据,这一点不必担心,因为接收方有去重机制.可以利用前面的序列号达到去重的目的. - 去重机制
接收方存在一个类似于BlockingQueue的数据结构,我们称这种数据结构为接收缓冲区.
B收到数据之后,经过层层地分用,最后到达传输层TCP协议,这时候会有一个接收缓冲区,把收到的数据先放入接收缓冲区中,放入的过程中,接收缓冲区会根据序号在队列中进行判断,这个数据在队列中是否存在或存在过.
此处的这种接收缓冲区的模型其实也是一个生产者消费者模型,发送方是生产者,接收方是消费者,接收缓冲区是用来支撑上述机制的核心数据结构.
- 超时重传周期
如果说超时重传的数据报也一直在丢包,就会随着重传轮次的增加,间隔时间越来越长.
比如第一次传输的时候等待50ms,没收到ACK,重传
第二次等待100ms,没收到ACK,重传,等待150ms…
如果重传次数过多,就会尝试"重置连接",会触发"复位报文",(RST报文).通信双方清空TCP传输过程中的中间状态,重新开始传输,如果还不成功,就会断开连接.
2.3.2.3 连接管理(三次握手,四次挥手)
在正常情况下,TCP要经过三次握手建立连接,四次挥手断开连接.
- 三次握手
两个机器进行交互之前,先要建立连接,也就是一个打招呼的过程,在这个过程中,没有任何实质性的数据交互.我们前面提到过,建立连接,就是双方各自保存对方的信息.具体完成上述过程,就是经过三次握手来完成的.
[注意] 三次握手,一定是客户端优先发起的.
举例说明:相亲
在相亲之前,不是先问对方有没有车,有没有房,有没有存款,而是先嘘寒问暖,问问外面冷不冷?最近怎么样?
- SYN
这里的SYN表示的是数据报不携带任何数据,即载荷是空的,只有报头.其中TCP报头中6个标志位中的SYN一位为1.这样的数据报也被称为同步数据报.
SYN是synchronize的缩写,翻译成英文,就是"同步"的意思.这里的同步就是希望服务器与客户端达成某种有关联的状态.
- 发送数据
在建立连接之后,双方就可以通过网络进通信了.也就是我们上面确认应答和超时重传的过程.
建立连接的意义:
- 投石问路,查看通信路径是否畅通.比如地铁在早上拉客之前,要先空拉一圈.查看轨道是否存在异常.
- 确认通信双方的接收能力与发送能力正常.比如我们在打游戏开开麦的时候,要先确认双发的耳机和麦克风都是正常的.
- 协商参数,通信双方共同确认一些通信中的必备参数的数值.
上面我们所展示的序号与确认序号就是通过三次握手协商出来的.第一次连接与第二次连接以及后续的连接都会协商出不同的序列号.这样做的目的就是,防止出现"前朝的剑斩后朝的官",或者是防止不同的连接相互干扰.
在一次通信的时候,如果数据报在网络中共迷路,或者是绕远路,等到这个数据报到达服务器,发现与之前协商好的序列号不对应,说明之前的连接可能已经断开了,现在是一个新的连接,那么这个数据报就应该丢弃,不应该按照程序正常处理.举例:办酒席
办酒席这件事情,需要婆家与娘家共同商量一共有多少人,需要办几桌.
- 四次挥手
四次挥手与三次握手的效果正好相反, 是两个主机之间断开连接的一种机制.此时也没有任何实质性的数据交互,断开连接就是各自都要删除对方的信息.
[注意] 与三次握手不同,四次挥手的发起者不确定,可能是客户端,可能是服务器.
举例:恋爱
在想要交往的时候,往往是男生(客户端)比较主动,而分手,可能是男生先提出,也可能是女生先提出,这个不一定.
- FIN
这里的FIN和SYN一样,不携带任何数据,只是用于两个主机之间断开连接,其中6个标志位的FIN位为1,这样的数据报也叫结束报文. - 问题:四次挥手中间的FIN与ACK是否可以像三次握手那样合并到一起?
三次握手,服务器收到SYN之后,系统内核立即返回SYN和ACK,由于它们两个是同时返回的,所以可以合并.但是四次挥手,收到FIN之后,系统内核立即返回ACK,但是下一个FIN是由应用程序代码控制的.close()
方法被调用之后,才会触发FIN操作,两个操作相隔一定的时间.很难合并到一起.- 比如:我们前面提到的TCP协议的Socket套接字.
https://blog.csdn.net/2301_80050796/article/details/139204881
我们结合我们前面提到过的TCP协议套接字,我们来理解一下四次挥手:
在客户端close()退出之后,客户端便会给服务器发送一个FIN报文,当FIN到达服务器之后,hasNext()感受到了没有下一个字节流过来了也就是返回了ACK,break之后,才调用close()进行了关闭,也就是客户端返回了FIN报文.
- 比如:我们前面提到的TCP协议的Socket套接字.
但是这样的情况也存在一些例外,比如服务器FIN出现了延时应答,这时候就可能会出现ACK与FIN合并的情况.
- 服务器与客户端的状态
我们以上图为例来说明:- LISTEN:服务器绑定端口号之后,进入到LISTEN状态.类似与开机之后,信号良好,可以进行通信的状态.
- ESTABLISHED:连接建立完成,可以正式发送数据.
- TIME_WAIT:
- 这个状态是为了在四次挥手的过程中,防止最后一个服务器发送过来的ACK发生丢包.
在客户端收到服务器的FIN之后,不会立即断开TCP协议连接,而是会进入TIME_WAIT状态,如果说ACK发生了丢包,服务器对客户端再次发送FIN报文的时候,客户端就无法接收到服务器的FIN报文.因此,我们便会有TIME_WAIT这样一个状态,以便等待可能到达的FIN重传数据. - 但是这个状态也存在一定的生存时间.
一般是2MSL.大约是1min.这样就可以保证两个传输方向上尚未被接受的数据或者迟到的数据都已经消失.同时也在理论上保证了最后一个报文可以到达.在一定时间之内,没有FIN过来,TCP连接就会被服务器释放.
- 这个状态是为了在四次挥手的过程中,防止最后一个服务器发送过来的ACK发生丢包.
- CLOSE_WAIT : 被动一方收到主动方FIN之后进入的状态.等待被动一方调用close(),close越及时,这个状态越不容易看到.一旦被动一方调用close之后,就会给主动一方发送FIN报文.
面试题:
- 如果发现服务器出现了大量的TIME_WAIT状态,如何处理?说明服务器出现了大量主动断开TCP连接的操作.但是这样的情况并不科学,一般是在客户端中出现.
- 对于服务器上出现了大量的CLOSE_WAIT状态,原因就是服务器没有正确的关闭socket,导致四次挥手没有正常完成,可以查看服务器的close操作是否正确.
2.3.2.4 滑动窗口
TCP协议在可靠传输之外,也希望高效完成数据传输.
刚才我们讨论了确认应答策略,对每⼀个发送的数据段,都要给⼀个ACK确认应答.收到ACK后再发送下⼀个数据段.这样做有⼀个比较⼤的缺点,就是性能较差.尤其是数据往返的时间较长的时候.
既然这样⼀发⼀收的方式性能较低,那么我们⼀次发送多条数据,就可以大大的提高性能(其实是将多个段的等待时间重叠在⼀起了).一次性发送到少数据,这个称为窗口大小.
- 特点
• 窗口大小指的是无需等待确认应答可以继续发送数据的最大值.上图的窗口大小就是4000个字节
(四个段).
• 发送前四个段的时候,不需要等待任何ACK,直接发送;
• 收到第⼀个ACK后,滑动窗口向后移动,继续发送第五个段的数据;依次类推;
• 操作系统内核为了维护这个滑动窗口,需要开辟发送缓冲区来记录当前还有哪些数据没有应答;只
有确认应答过的数据,才能从缓冲区删掉;
• 窗口越大,则网络的吞吐率就越高;
[注意]
- 滑动窗口,说是提升效率的机制,其实就是"亡羊补牢"的机制,TCP为了保证可靠性,牺牲了很多效率,引入滑动窗口会让效率牺牲的少一些,但是仍然存在牺牲,没办法和UDP协议的速度比.
- 在窗口头部数据接收到ACK之后,窗口就向后滑动一位,并不是等待4个数据全部收到ACK之后再向后滑动窗口.
- 丢包情况
- 情况一: 数据报抵达,ACK丢失
这种情况下,并不要紧,因为我们可以通过后续的ACK进行确认.比如上图:
1001ACK丢包,2001会告诉发送方,1~2000的数据的数据都已经收到了,涵盖了1001的效果.比如:一个人被问到,你上大几了,那个人回答道,我娃都上小学了,是同样的道理. - 情况二: 数据报丢包
数据报丢失之后,就会触发滑动窗口的一种重传机制:快速重传.也叫快重传.
• 当某⼀段报⽂段丢失之后,发送端会⼀直收到1001这样的ACK,就像是在提醒发送端"我想要的是"1001"⼀样;
• 如果发送端主机连续三次收到了同样⼀个"1001"这样的应答,这时候发送方就会反应到,原来是1001~2000的这个数据报丢了,就会将对应的数据1001-2000重新发送;
• 这个时候接收端收到了1001之后,就会把接收缓冲区的空白补上(若空白区域一直填补不上,滑动窗口就不会向后移动),再次返回的ACK就是7001了,因为2001-7000接收端其实之前就已经收到了,被放到了接收端操作系统内核的接收缓冲区中;
- 情况一: 数据报抵达,ACK丢失
2.3.2.5 流量控制
接收端处理数据的速度是有限的.如果发送端发的太快,导致接收端的缓冲区被打满,也就是接收方处理不过来的情况下,这个时候如果发送端继续发送,就会造成丢包,继而引起丢包重传等等⼀系列连锁反应.这时候我们就需要通过控制数据流量的方式来防止这种情况的出现.TCP会根据接收端的处理能⼒,来决定发送端的发送速度.
- 流量控制原理
通过窗口大小来控制,窗口大小可变,所以可通过窗口大小,来控制发送速度.窗口大小字段越大,说明网络的吞吐量越大. - 流量控制原则
接收方根据自己的处理能力,反向制约发送方速度,使得双方达成"平衡".- 接收端⼀旦发现自己的缓冲区快满了,就会将窗口大小设置成⼀个更小的值通知给发送端;
- 发送端接受到这个窗口之后,就会减慢自己的发送速度;
- 如果接收端缓冲区满了,就会将窗口置为0;这时发送方不再发送数据,但是需要定期发送⼀个窗口探测数据段,使接收端把窗口大小告诉发送端.这个数据会通过ACK报文中的"16位窗口"字段来指定.(一般会以接收缓冲区空闲空间的大小作为发送数据的窗口大小).
- 这其中"窗口探测报文"是周期性发送的,他和前面的SYN报文和FIN报文一样,都是不带载荷的.
2.3.2.6 拥塞控制
因为⽹络上有很多的计算机(路由器,交换机,集线器等网络设备),可能当前的网络状态就已经比较拥堵.在不清楚当前网络状态下,贸然发送大量的数据,是很有可能引起雪上加霜的.
- 所以TCP引入了"慢启动"的机制:
先发送少量的数据,摸清当前的网络状态.如果网络没有拥堵,再去增加窗口大小,直到出现丢包的情况,减小窗口大小,直到不丢包,周期循环,直到找到合适的值,使得数据传输达到"动态平衡"的状态.总结一句话:在丢包的边缘疯狂试探.
- 下面的一张图是一张非常经典的图,他可以形象地描述出TCP拥塞控制的慢启动机制.
- 首先先慢启动,试探通信网络的畅通性.
- 之后确认没有问题之后,开始指数式增长.
- 增长到一定阈值之后,开始线性增长.
- 丢包之后,降低传输速度.
- 降低之后,再次线性增长.
上面这张图就好像是恋爱的感觉.
[注意]
拥塞控制窗口和流量控制窗口共同控制数据传输速度大小.这里遵循的是木桶效应.哪个窗口小,就按哪个的速度来.
2.3.2.7 延迟应答
延迟应答的核心目的,为了提升TCP传输数据的效率.
-
延时应答如何提高效率?
如果接收数据的主机立刻返回ACK,这时候返回的窗口大小可能比较小.如果说延迟应答的话,就会让应用程序消耗一部分的数据,这时候接收方的缓冲区就会增大空闲空间,从而使得返回的ACK报文中,窗口大小增大.窗口大小增大之后,自然会增大数据传输的速度.
-
延时的策略
- 按照一定的时间延时
- 按照收到的数据量延时.两者结合使用
2.3.2.8 捎带应答
由于延时应答的存在,ACK不一定立即返回,在ACK稍等一会的时候,正好响应的数据也准备返回,就会在响应数据中,ACK标志位设置为1,确认序号和窗口大小都设置上.可以提高传输的效率,两次传输合并为了一次.
2.3.2.9 粘包问题
我们拿前面的翻译服务器来说明:
当客户端给服务器发送了一个请求,服务器拿到这个请求之后.由于TCP协议面向字节流的特点,读的时候咋读都行,此时,服务器就无法区分从哪里到哪里是一个完整的单词,即应用程序看到了这么⼀连串的字节数据,就不知道从哪个部分开始到哪个部分,是⼀个完整的应用层数据包,这种问题叫做粘包问题.
那么如何避免粘包问题?归根结底就是明确两个包之间的边界.
- 对于定长的包,保证每次按照固定的大小读取.
- 对于变长的包,可以在包头的位置约定一个包的总长度字段.从而达到分割效果.
- 也可以使用分隔符的方式分割数据.比如我们在前面Socket套接字的时候,使用’\n’作为分隔符.
2.3.2.10 异常情况
- 进程终止:进程终止会释放文件描述符,仍然可以发送FIN.和正常关闭没有什么区别(调用close,4次挥手).
- 机器重启:和进程终止情况相同.
- 机器掉电/网线断开:
这样的异常分为两种情况.- 情况一: B是数据方
B接下来发送的数据,都不会有ACK,B会超时重传,重传几次之后,发送复位报文(RST),仍然没有响应,B就会单方面删除A的信息. - 情况二: B是接收方
A沉默了之后,B不知道A是暂停发送数据,还是直接挂了.B在一定时间之内没有收到A的数据之后,会触发"心跳包",和SYN,FIN,RST一样,都是没有载荷的数据报.发送之后,如果A有正常的ACK回应,就没有挂,否则就挂了.
- 情况一: B是数据方
面试题:如何使用UDP完成可靠的数据传输
可以引入TCP协议的10条特性,确认应答,超时重传,连接管理,滑动窗口,流量控制,拥塞控制,延时应答,捎带应答,粘包问题,异常情况.
相关文章:

[线程与网络] 网络编程与通信原理(四):深入理解传输层UDP与TCP协议
🌸个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 🏵️热门专栏:🍕 Collection与数据结构 (92平均质量分)https://blog.csdn.net/2301_80050796/category_12621348.html?spm1001.2014.3001.5482 🧀Java …...

IEEE编程语言排行榜:深度解析编程语言的四大维度、五大趋势、六大热门与七大挑战
IEEE编程语言排行榜:深度解析编程语言的四大维度、五大趋势、六大热门与七大挑战 在信息技术领域,编程语言排行榜一直是衡量各种编程语言流行度和影响力的重要指标。IEEE(电气电子工程师协会)作为全球最具影响力的科技专业组织之…...

【C++面试50题】
以下是针对C程序员面试可能遇到的一些问题,涵盖了从基础语法、面向对象、STL、内存管理、模板、异常处理、并发编程等多个方面。 ### 基础概念与语法 1. C与C的主要区别是什么? 2. 什么是构造函数和析构函数?它们何时被调用? 3. 什…...

外汇天眼:ESMA发布针对在投资服务中使用人工智能的公司的指导意见
欧洲证券和市场管理局(ESMA),欧盟的金融市场监管机构和监督机构,发布了一份声明,为在向零售客户提供投资服务时使用人工智能技术(AI)的公司提供初步指导。 尽管人工智能的普及仍处于初期阶段&am…...

【前缀和 记忆化搜索】LeetCode1444. 切披萨的方案数
本文涉及的基础知识点 C算法:前缀和、前缀乘积、前缀异或的原理、源码及测试用例 包括课程视频 动态规划 记忆化搜索 LeetCode1444. 切披萨的方案数 给你一个 rows x cols 大小的矩形披萨和一个整数 k ,矩形包含两种字符: ‘A’ ÿ…...

异常处理1--5.31
try--catch--finally格式: try{ }catch(错误类型){ }finally{ } 执行情况: package javatest5;public class test {public static void main(String[] args) {int num115;int num20;try{System.out.println("商等于:"num1/num…...

AI免费插件 批量条码大师,支持100多种条码类型
没想到在网上看到一款和之前 悟空条码 类似的条码插件,叫批量条码大师,他做的比 悟空条码 功能更强,界面更美观,特分享出来给大家。 本插件采用了BWIPJS条码库,支持110种条码、二维码的生成; 支持批量生成,…...

使用 Django 连接 MySQL 数据库
文章目录 步骤一:安装必要的库和驱动步骤二:配置数据库连接步骤三:执行数据库迁移步骤四:开始使用 MySQL 数据库创建一个模型迁移模型到数据库使用模型进行数据操作创建新记录:查询记录:更新记录࿱…...

【谷歌开发者月刊】五月内容汇总,Google I/O 点燃您的创新灵感
五月因 Google I/O 大会的成功举办而备受瞩目,我们在为开发者们带来技术更新的同时,更提供了丰富的学习资源。一起在本期月刊中回顾精彩内容,带着学习热情继续探索技术的更新与发展吧! 本月看点 精彩看点多多,请上下滑…...

wpf 实现长时间未操作自动退出登录
思路 在WPF应用程序中实现长时间未操作自动退出,主要思路是先收集用户操作行为,用一个全局变量记录用户最后操作时间,再用一个异步线程去监控用户的最后操作时间和当前时间进行比较如果超过了设定时间认为长时间未操作自动退出登录并显示相关…...

pytorch学习笔记3
标量数据 标量数据通常指的是单个数值,比如一个损失值、准确率、学习率等。这些单个的数值数据可以被记录下来,用于分析模型的训练过程、性能等。在代码中,writer.add_scalar() 的作用就是将这些标量数据添加到日志中,以便后续在可…...

开源监控工具monit安装部署
Monit 简介 Monit是一个轻量级(500KB)跨平台的用来监控Unix/linux系统的开源工具。部署简单,并且不依赖任何第三方程序、插件或者库。 Monit可以监控服务器进程、文件、文件系统、网络状态(HTTP/SMTP等协议)、远程主机、服务器资源变化等等。…...

Python 时间戳转时间
一、 10 位 时间戳 ,秒级 转换为时间 方式一: import timetimeStamp 1717149862 timeArray time.localtime(timeStamp) timeStr time.strftime("%Y-%m-%d %H:%M:%S", timeArray) print(timeStr) 输出: 2024-05-31 18:04:22方式二…...

【网络层】IP地址基础 与 子网掩码
文章目录 IP地址基础IP地址概念IP地址分类公网地址和私网地址 子网掩码子网掩码作用默认子网掩码网络地址、主机地址、广播地址 IP地址基础 IP地址概念 IP地址:IP Address 在网络中,通信节点都需要有一个IP地址 IP地址以点分十进制表示,有…...

Cholesky分解(A=L * L^T)
Cholesky分解是一种用于解线性方程组和计算矩阵平方根的算法,特别适用于对称正定矩阵。这种方法相比于其他解法(如高斯消元法)在数值稳定性上通常有更好的表现,并且能够有效地利用矩阵的对称性和正定性。下面简要介绍如何使用Chol…...

2024大模型新应用井喷即将到来,算力问题如何解决?
#大模型新应用 #NLP #智合同 随着人工智能技术的加速演进,AI大模型已成为全球科技竞争的新高地、未来产业的新赛道、经济发展的新引擎。大模型的快速发展,特别是在自然语言处理(NLP)和计算机视觉(CV)等…...

SpringBoot 七牛云 OSS 私有模式 获取访问链接
目录 一、问题引出 二、在SpringBoot中获取私有访问路径的操作 一、问题引出 由于七牛云OSS的公有模式存在被盗刷的风险,可能导致服务器额外的费用,于是我选择私有模式进行操作。私有模式的访问路径是一个问题,因为需要对应着token和e这两…...

python-模块-网络编程-多任务
一、模块 1-1 Python 自带模块 Json模块 处理json数据 {"key":"value"} json不是字典 本质是一个有引号的字符串数据 json注意点 {} 中的数据是字符串引号必须是双引号 使用json模块可以实现将json转为字典,使用字典的方法操作数据 。 或者将…...

火狐浏览器网页翻译
火狐浏览器网页翻译 火狐浏览器的翻译功能并不支持中文,无法将中文翻译成其他语言,也不支持将其他语言翻译成中文。如果需要翻译英文网页,可以安装翻译插件来帮助解决这个问题。 安装翻译插件的步骤如下: 打开火狐浏览器ÿ…...

R语言数据分析案例以及要点和难点
该案例将涵盖数据读取、数据清洗、探索性数据分析(EDA)、数据可视化和简单的统计分析等多个方面。本案例将以一家零售商店的销售数据为例,使用R语言进行数据分析。 1. 数据准备 假设我们有一个名为sales_data.csv的CSV文件,其中包含了零售商店的销售数据。该文件包含以下列…...

【STL源码剖析-空间配置器】stack、queue简单实现
举头天外望 无我这般人 目录 stack 的概述 stack 的实现 queue 的概述 queue 的实现 契子✨ 我们之前学过了 vector、list 这些 STL 的(容器) 而我们今天将要学习空间配置器 -- stack、queue,那什么是空间配置器呢? 简单来讲就是…...

VR导航的实现原理、技术优势和应用场景
VR导航通过虚拟现实技术提供沉浸式环境,结合室内定位技术实现精准导航。目前,VR导航已在多个领域展现出其独特的价值和潜力,预示着智能导航系统的未来发展。 一、实现原理 VR导航技术依托于虚拟现实(VR)和室内定位系统。VR技术利用计算机模…...

淘宝镜像的https证书过期
错误原因: 淘宝镜像过期 早在 2021 年,淘宝就发文称,npm 淘宝镜像已经从 http://registry.npm.taobao.org 切换到了 http://registry.npmmirror.com。旧域名也将于 2022 年 5 月 31 日停止服务(直到 HTTPS 证书到期才真正不能用了…...

VSCODE 常用快捷键
快捷按键 注释 CTRL /CTRL KSHIFT ALT A取消注释 CTRL /CTRL KSHIFT ALT A搜索文件 Ctrl P移动到某一行 Ctrl g打开一个新窗口 Ctrl Shift N关闭窗口 Ctrl Shift W新建文件 Ctrl N文件间切换 Ctrl Tab全部文件搜索 Ctrl Shift F全屏 F11 打开文件出现中文乱码 文件右下角…...

医院该如何应对网络安全?
在线医生咨询受到很多人的关注,互联网医疗行业的未来发展空间巨大,但随着医院信息化建设高速发展 医院积累了大量的患者基本信息、化验结果、电子处方、生产数据和运营信息等数据 这些数据涉及公民隐私、医院运作和发展等多因素,医疗行业办…...

【qt】多窗口开发
多窗口开发 一.应用场景二.嵌入的窗口1.设计Widget窗口2.创建窗口3.添加窗口4.总代码 三.独立的窗口1.创建窗口2.显示窗口 四.总结 一.应用场景 多窗口,顾名思义,有多个窗口可以供我们进行操作! 截个小图,你应该就知道了 OK,话不多说,直接开干,先来设计我们的主窗口 需要蔬菜…...

iOS Hittest 机制和实际应用
Hittest 机制原理 hitTest的原理就是,当我们点击的时候,会触发 window的 hittest方法,在该方法中会首先使用point inside方法判断 点击的地方是否在window范围内,如果在的话,就倒序遍历姿子视图,然后将poi…...

C# 工厂模式学习
工厂模式(Factory Pattern)是一种创建型设计模式,它提供了一种创建对象的接口,而不是通过具体类来实例化对象。工厂模式可以将对象的创建过程封装起来,使代码更具有灵活性和可扩展性。 工厂模式有几种常见的实现方式&…...

AI生成微信职业头像
加油,新时代打工人! 真别说,还挺好看的 https://chatglm.cn/main/alltoolsdetail...

遥感图像的深度学习的任务类型
在遥感图像的深度学习任务中,利用深度学习技术处理和分析遥感图像已经成为一个重要的研究方向。遥感图像来自卫星、无人机等设备,包含了丰富的地球表面信息。以下是遥感图像深度学习中的主要任务类型: 1. 图像分类(Image Classif…...