当前位置: 首页 > article >正文

【TCP】三次挥手,四次挥手详解--UDP和TCP协议详解

活动发起人@小虚竹 想对你说:

这是一个以写作博客为目的的创作活动,旨在鼓励大学生博主们挖掘自己的创作潜能,展现自己的写作才华。如果你是一位热爱写作的、想要展现自己创作才华的小伙伴,那么,快来参加吧!我们一起发掘写作的魅力,书写出属于我们的故事。我们诚挚邀请你参加为期14天的创作挑战赛!

提醒:在发布作品前,请将不需要的内容删除。

各位看官,大家早安午安晚安呀~~~

如果您觉得这篇文章对您有帮助的话

欢迎您一键三连,小编尽全力做到更好
欢迎您分享给更多人哦

今天我们来学习【Java网络编程】-【TCP】三次挥手,四次挥手详解--UDP和TCP协议详解

目录

1.UDP协议

1.1.UDP报文长度

1.2.校验和

1.2.1什么是校验和,校验和有什么用?

1.2.2.校验和是怎么计算出来的?

1.2.3:MD5

1.3.基于UDP实现应用层协议

2.TCP协议

2.1.TCP报文格式

2.2.TCP可靠传输(TCP最开始的核心)

2.2.1.确认应答

2.2.2.超时重传(三次问题)

2.2.3.连接管理(建立连接+断开连接)

2.2.4.四次挥手

2.3.提高效率

2.3.1.滑动窗口

2.3.2.流量控制

2.3.3.拥塞控制

2.3.4.延时应答

2.3.5.捎带应答(就是把本来两个数据段一起返回了)

2.4.粘包问题

2.5.异常的处理情况

2.5.1.进程异常结束

​编辑

2.5.2.通信直接断开了(进程都没来得及杀)(想回应但是回应不了)

3.UDP和TCP之间的对比


图解:(TIME_WAIT)的作用以及四次挥手的图解

大哥和小弟在心里(兄弟在心中)

首先我们要明白学习一个协议最后重要的就是了解这个协议的报文格式

协议本身就是一个简单的规则

所谓的报文格式就是按照一定的格式进行字符串拼接(当然这里是二进制拼接)

1.UDP协议

UDP的报文格式比TCP还是要简单不少的,因此我们要讲解的点不多,主要是以下两点:

1.UDP报文长度的一些问题

2.UDP校验和

1.1.UDP报文长度

问题一:

大家可以看到UDP报文长度一共就64kb,这对于以前的计算机还不错,但是如今看来就很捉襟见肘了,所以能不能把UDP进行升级处理(报文长度变长)?

当然可以!

但是代价是巨大的,如果要升级,就要通信双方都要去升级(全世界都要去升级,而且UDP是操作系统内核实现的,操作系统也要进行升级),所以说成本太大的我们还不考虑升级

除非未来出现一个新的协议把UDP完全替代掉。

问题二:

还有的人说:既然UDP不能一次性传输,能不能把数据进行拆包和组包?

答:

这个方案不太行(开发成本太大),我们如何进行拆包,万一数据丢失了,我们再进行如何校验,又如何组包?这里面有很大的开发和测试成本!!!

但是TCP就可以解决这个问题(不过带来的是性能的下降)

1.2.校验和

1.2.1什么是校验和,校验和有什么用?

网络通信中,往往都会因为一些信号干扰的因素,导致我们传输的数据出现问题,这个就需要校验和帮助我们检查一下数据的正确完整性~

首先我给大家的例子:

我给小明说一个我的游戏账户密码(很长),我就念给他听了,他说记到纸上了

然后他疏忽了少写了一个字母,这个时候就很尴尬(他回家了登录不上游戏了)

加一个校验和~

但是如果我跟他说一个20个字母,他就可以检查到他只写了19个字母,当时就知道错误了

这个校验和就可以起到检查数据是否正确的作用~~

具体解释

1.2.2.校验和是怎么计算出来的?

计算校验和有很多算法,这里UDP使用的算法是CRC算法(循环冗余算法

解释:

把当前要计算校验和的数据的每一个字节都进行累加,把这个结果保存到校验和中(校验和一共两个字节),就算溢出也没关系。

但是这个CRC算法不是很靠谱,导致两个不同的数据得到一样的CRC校验和的概率不小

就譬如前一个字节少1,后一个字节多1(有不小的概率出现)

1.2.3:MD5

要计算校验和MD5就是一个很好的算法(和他类似的还有sha1算法)

sojson工具(包含md5加密工具)

我们讲解一下MD5的特性

  1. 定长:无论你原始数据多长,计算出来的md5都是固定长度(这一点就很好,毕竟校验和本身就不应该很长)
  2. 分散:两个原始数据很接近的数据,只要一个字节不同,md5计算出来的值也会差距很大     (因此MD5也很适合做hash算法,把一个几乎相同的key尽量做到分散,降低hash冲突)
  3. 不可逆:给一个原始数据计算出MD5很容易,但是反过来极其困难(理论上是不可行的)

1.3.基于UDP实现应用层协议

NFS:网络文件系统

TFTP:简单文件传输协议

DHCP:动态主机配置协议

BOOTP:启动协议(用于无盘设备启动)

DNS:域名解析协议(后面我们会讲解这个)

当然,也包括你自己写UDP程序时自定义的应用层协议

2.TCP协议

TCP相关特性

1.有连接 Socket clientScoket  = serverSocket.accept();

用过ServerSocket api的accept方法把内核里已经建立好的连接拿过来(通过三次握手建立的连接)

2.可靠传输(我们接下俩要讲述的重点)

3.面向字节流(我们通过字节流 读/写 网卡抽象成文件里面的数据)

4.全双工(可以同时互相发送消息)

2.1.TCP报文格式

图解:(没讲到的后续会进行讲解)

2.2.TCP可靠传输(TCP最开始的核心)

解释:(得知道对方收没收到消息,如果对方一直没回应,就进行补救)

因此为了保证可靠传输我们引入如下3个机制

1.确认应答

2.超时重传

3.连接管理(三次握手,四次挥手)

2.2.1.确认应答

确认应答:顾名思义,接收方会发送方返回一个应答报文(acknowledge ,ack)

如果发送方收到这个应答报文了,就知道自己的数据已经发送成功了。

但是,网络上不稳定的情况可能会导致我们的数据出现“后发先至”的情况

所以TCP将每个字节的数据都进行了编号——即为序列号

解释:(后面我们讲述到滑动窗口的时候我们还会讲解到)

有了序号,我们只需要确认回复给发送方最后一个数据(发送方就可以确定其他数据都来了),因为如果数据没全来的话,我们是不会给发送方发送1001的

如何区分一个数据包是一个普通的数据还是ack应答报文数据呢?

TCP的可靠传输:

确认应答 是TCP最核心的机制,再借助其他机制辅助最终完成可靠传输

2.2.2.超时重传(四个问题)

我们是可以进行通过确认应答来保证我们的数据传输到了

第一个问题:但是如果我们的数据包都丢了,怎么应答呢?

(网络上也会出现“堵车”的问题:如果数据包太多,就会在路由器/交换机上出现堵车,但是路由器针对“堵车”的处理会比较除暴,它不会把积压的数据保存好,而是把这些中的大部分数据都丢调)

答:

其实一直不应答也是一种应答(给女神发消息女神一直不回也是一种应答)哈哈哈哈

这个时候我们就需要进行重新传输了——超时重传

我们肯定是等待了一会发现接收方还一直不给我们返回ack(或者已经返回了ack我们没有收到)这两种情况都是认为对方没有收到,我们就要超时重传的功能了!!!

再来一个问题:

如果是对方已经收到这个数据还返回了ack,只是我们没有收到,这个时候发送的数据不就会重复了吗?

答:

TCP里面会有一个“接收缓冲区”就是一个内存空间,保存当前已经接收到的数据,以及数据的序号。

如果接收方发现,当前发送的数据是再接收缓冲区存在的数据,就会把这个数据丢弃掉,确保我们应用程序进行read的时候接受到的只是一条数据

图解

第三个问题:发送方何时进行重传?等待时间?

1.这个等待时间是可以进行配置的,不同的系统上面不同,也可以修改一些内核参数来引起这里的时间变化

2.等待的时间也会动态变化,没多经历一次超时,等待的时间都会变长(但是也不会无限拉长,如果时间长到一定程度,就会放弃TCP连接(触发TCP重新连接操作))

第四个问题:那这样TCP的可靠性不就会导致性能的下降了吗?

当然——等价交换是炼金术不变的原则

传输效率下降,复杂程度变高

传输层的协议主要是TCP和UDP但是还是有别的协议可以做到TCP和UDP之间的效果的

譬如(quic……)

2.2.3.连接管理(建立连接+断开连接)

三次握手和四次挥手终于要来啦~~~

握手其实就是打个招呼

TCP的三次握手:TCP在建立连接的过程中,需要通信双方一共“打三次招呼”才能够建立

A先给B发送一个“同步报文段”(没有数据的应用层数据包,没有载荷)(标志位为SYN为1的时候这个这个报文就是一个同步报文段)

然后B给A回复一个ack(这个时候只有A能确定它发送过去的数据能送到,但是B不知道B发送的数据报是什么情况,所以B也要给A发送一个“同步报文段”如果A也能给B的发送一个同步报文段,那么A就知道自己没问题了)

所以情况如下

这个时候A和B就记录了对方的信息,就构成了逻辑上的“连接”

建立连接的过程就是通信双方都给对方发起syn,也都要给对方反馈ack(本来是四次握手,但是中间两次恰好可以合并成一次)

三次握手的作用(就是建立连接的作用)?

1.建立连接肯定是确保网络通信是否畅通

2.让发送方和接受方确认自己发送能力和接收能力是否正常

(如果B不给A发送syn,A就不会回应。B也不知道自己的ackA收到没有,如果A回应了ack并且B收到了,B就能确定自己的发送能力和接受能力都是正常的)

3.让通信双方对于一些重要的参数进行协商

譬如:

(1)超时重传时间

(2)序列号(序列号确保数据传输的顺序。在 TCP 通信中,发送方将数据分成多个数据包,并为每个数据包分配一个唯一的序列号(具体从那个数字开始也是需要协商的不是拍脑瓜子))

(3)窗口大小(我们等会滑动窗口会讲解)

…………

给大家一个具体的例子(这就协商出来按照65w进行充电)

2.2.4.四次挥手

接下来我带大家看一下一张完整的TCP状态转换图

建立连接是客户端主动发起的

但是断开连接客户端和服务器都可以主动发起

FIN:结束报文段(就像建立连接的SYN(同步报文段)都是一个标志位)

问题一:问什么是四次挥手而不是三次挥手?(三次挥手在延时应答的情况下也可以实现)

问题二:小编一开始学的时候就想着(你都要结束了还搞这么正式干嘛?)

直接两次挥手不就得了?

但是我少考虑了很多

解释,很重要!

服务器还要处理数据,可能还要给客户端响应其他的数据(客户端这个时候还不能关闭)

等到服务器发送FIN的时候才能证明数据已经处理完毕了(这个时候就是三次握手了)。但是服务器还不能关闭,万一客户端没收到FIN(客户端没收到FIN时不能关闭因为服务器可能还有数据要通信),服务器还要重传。所以服务器还要等待客户端返回ack才能结束。(这里就是四次握手了)

图解:(TIME_WAIT)的作用以及四次挥手的图解

TIME_WAIT作用:防止最后一个ack走丢(小弟担心大哥又多等待了一会)

我们上述的机制都是在为可靠传输效力,但是可靠传输下来,牺牲的却是效率

那我们怎么来提高效率呢?接下来我带领大家学习以下几个机制~

2.3.提高效率

接下来给大家看一下我的总结思路:

2.3.1.滑动窗口

变成这样~~~

然后进行“滑动”窗口(只要有ack回来就继续发)

但是出现了丢包的情况该如何呢?

分为两种情况~

第一种情况:

就像别人问你上初中了没有,你直接说我已经大学了(那我肯定早就上过初中了呀)

第二种情况

等到1001~2000传输到了之后,7001这个确认序号说不定就该传输过去了(3001,4001,就不用传输回去了哈哈哈)

接下来我们要说的是窗口大小的问题(窗口不能无限的大)

2.3.2.流量控制

是窗口大小的问题(窗口不能无限的大),窗口太大了,服务器处理数据就处理不过来了

这个时候“负反馈”就很重要了调整窗口的大小

发送方的发送速率不能超过接收方的处理能力

接收方每次收到数据,都会通过ack(应答报文)返回给发送方,然后发送方就会按照这个数值调整窗口的大小(不能超过)

为啥要探测呀:

刚刚不让你传输了,现在让你传输了(怕我更新可窗口通知了你,但是通知你的数据报丢了,所以一会不通知你,你就要试探一下(发个窗口探测包),问问好了没)

但是传输路径上的节点的接收能力也要计算在内呀(不能量化,我们就一点一点的增大窗口,然后综合窗口大小,选小的)。

2.3.3.拥塞控制

但是传输路径上的节点的接收能力很难量化,所以我们就一点一点的增大窗口,然后综合窗口大小,选小的)。(实验的方式)


阈值(sstresh):指数增长的终点,线性增长的起点(大加速度变成小加速度)

首先:

客户端先按照比较低的速度发送数据(小一点窗口)

如果数据传输的很顺利(几乎没有丢包的情况)--> 把窗口尝试调大,大到一定的程度,中间节点可能就会出现了丢包问题。这个时候发送方发现丢包了 --> 就把窗口调小一点 。如果还是丢包就继续调小,不丢就增大,--> 最终达到动态平衡的效果

具体过程如图

改进措施如下:

总之:

流量控制:通过接收方返回的剩余缓冲区大小来确定窗口大小(主要考虑接收方处理能力)(定量)

拥塞控制:通过实验的方式一步一步动态稳定窗口的大小(主要考虑中间节点的处理能力)

(非定量)

最终窗口大小取二者中最小值

2.3.4.延时应答

而且我们通过延时应答也可以把四次挥手变成三次挥手

2.3.5.捎带应答(就是把本来两个数据段一起返回了)

就像四次挥手变成三次一样

刚好把response和ack一起返回

进一步提高了效率

本来要传输两个tcp数据包,我们要封装分用两次

但是用过上述的操作,就可以把两个数据包合并在一起了,现在我们封装分用一次就行了

2.4.粘包问题

很多面向字节流传输数据的时候都会出现这样的情况

但是UDP就没有这样的问题(UDP本来就是一个一个的数据包(有边界的))

所以我们解决粘包问题的关键就是怎么搞一个边界出来

这就让我想起来“循环队列”

当head 和 tail 重合的时候到底是这个数组满了还是数组是空的?

两个方案

1.搞一个标志位(浪费一个格子,当head =  tail + 1的时候就是满的,head = tail就是空的)

2.引入有效长度(当length = array.length就是慢的 ,length = 0就是空的)

这个时候也是

1.搞一个标志位(引入分割符)

2.引入长度(譬如先读两个两个直接的数字表示这个数据包中的字节有多长)

2.5.异常的处理情况

一般分为两种情况

1.进程异常结束

2.进程都没来得及杀,通信就断了

2.5.1.进程异常结束

首先我要声明

TCP 连接的状态(如 ESTABLISHED(已经建立好连接)TIME_WAIT(延时等待) 等)由内核协议栈维护,而非应用程序。

在 TCP 协议中,四次挥手是由操作系统内核实现的(severSocket.accept()只是拿到内核建立好的连接),而非依赖于应用程序显式调用 socket.close()。当进程异常终止时(如崩溃或被强制杀死),操作系统会主动回收该进程占用的资源(包括文件描述符),并触发内核协议栈的 TCP 连接关闭流程。

在Java中,当创建一个Socket对象时,底层操作系统会分配一个文件描述符来管理这个连接。进程异常终止时,操作系统通常会负责清理进程占用的资源,包括关闭打开的文件描述符。

进程异常结束的两种情况:进程崩溃和主机关机了(用户自己关机的)

2.5.2.通信直接断开了(进程都没来得及杀)(想回应但是回应不了)

1.主机掉电(就像插头松了一样)(又分为客户端掉电或者服务器掉电)

(1)客户端掉电:本来还在正常的通信,结果客户端直接掉电了,服务器都懵了(客户端怎么还不返回ack?)然后就开始超时重传,结果还是一直不回(对方挂了?)。

再然后发送“心跳包”,结果还是不回,然后就认为客户端挂了这个时候就可以单方面释放连接了。

图解:

注解:

服务器不是这个时候才会发送“心跳包”,而是周期的就会发送心跳包(不带业务的数据包),期望回复,多次没回复就认为对方挂了

(2)服务器掉电:

还是一样的,客户端一直发数据,服务器不回应;超时重传还是不回应。客户端会发送一个“复位报文段”(RST)(reset),如果FST发过去还没有回复,就会单方面释放连接

ACK:应答报文

RST:复位报文段

SYN:同步报文段(建立连接时发送),建立好连接进入(ESTABLISH状态)

FIN:结束报文段(主动发起FIN的进入TIME_WAIT状态)

2.网线断开(和掉电十分相似,不过这俩一个发复位报文段,一个发心跳包,但是就是连接不上哈哈)。

TCP的心跳机制:再分布式系统中十分常见。一般检测一个机器是否挂了都是通过“心跳机制”来检测(不过后续使用的心跳机制都是在应用程序中自己实现的(一般都是毫秒级别了),而不是TCP的心跳(时间太长)

3.UDP和TCP之间的对比

第一点对比:

TCP:可靠传输,有重组机制(能传输很大的数据)。

在接收方,TCP协议会根据每个TCP段的序列号来重组这些数据。100kb的数据可以分成好几个段,接收方的TCP协议会按照序列号顺序将这些TCP段重新组装成完整的100 KB数据。(适合绝大部分的场景)

UDP:效率更高,无重组机制(只能传输很小的数据)。

UDP协议本身不提供数据分段和重组的功能。每个UDP数据报(datagram)(更适合于“可靠性不是很敏感,性能敏感,数据不多”的场景:譬如同一个局域网主机之间的通信

而且在以太网中UDP和TCP数据报最大不会超过1500字节(受MTU(最大传输单元)的影响)(后面我们会讲解到)

第二:

UDP天然适合“广播传输”(给这个局域网内所有的设备都发送信息),而TCP不支持(TCP只能遍历这个局域网设备里面的所有IP实在是太麻烦)

这是因为UDP的socket能给“广播地址”建立联系(譬如192.168.255),但是TCP无法和这个地址建立联系

第三:若UDP想要实现TCP的可靠传输,可以参考TCP的思路

确认应答(引入序号和确认序号,这样也可以组包啦)

超时重传(包丢了)

提高效率再滑动窗口等等我们TCP可靠传输的特性…………

结束啦~~~

最后一个解答

大家可能会疑惑,像TCP和UDP这么NB的协议都是谁整出来的?

当然是一群神秘的大佬,把这些协议都整理出一个标准的文档---RFC标准文档

上述就是【TCP】三次挥手,四次挥手详解--UDP和TCP协议详解的全部内容啦~~~

能看到这里相信您一定对小编的文章有了一定的认可。

有什么问题欢迎各位大佬指出
欢迎各位大佬评论区留言修正~~

您的支持就是我最大的动力​​​!!

相关文章:

【TCP】三次挥手,四次挥手详解--UDP和TCP协议详解

活动发起人小虚竹 想对你说: 这是一个以写作博客为目的的创作活动,旨在鼓励大学生博主们挖掘自己的创作潜能,展现自己的写作才华。如果你是一位热爱写作的、想要展现自己创作才华的小伙伴,那么,快来参加吧&#xff01…...

Compose 实践与探索十二 —— 附带效应

1、SideEffect Google 官方文档对 side effect 有两种翻译,简体中文翻译为附带效应,繁体中文翻译为副作用。这两个翻译我们用哪个都行,关键是如何理解它的含义。 1.1 什么是副作用 我们在日常生活中听到的副作用大多是医学领域中的&#x…...

Kubernetes 控制平面详解 —— 探秘 API Server、Controller Manager、Scheduler 与 etcd

文章目录 Kubernetes 控制平面详解 —— 探秘 API Server、Controller Manager、Scheduler 与 etcd控制平面概述API Server角色与职责工作原理 etcd角色与职责工作原理 Scheduler角色与职责工作原理 Controller Manager角色与职责工作原理 总结 Kubernetes 控制平面详解 —— 探…...

SSM基础专项复习4——Maven项目管理工具(1)

系列文章 1、SSM基础专项复习1——SSM项目整合-CSDN博客 2、SSM基础专项复习2——Spring 框架(1)-CSDN博客 3、SSM基础专项复习3——Spring框架(2)-CSDN博客 文章目录 系列文章 1. Maven 的概念 1.1. 什么是 Maven 1.2. 什…...

使用c#进行串口通信

一、串口通信协议 1.串口通信协议简介 串口通信(serial communication)是一种设备间非常常用的串行通信方式,大部分电子设备都支持,电子工程师再调试设备时也经常使用该通信方式输出调试信息。讲到某一种通信协议,离…...

Web开发-PHP应用鉴别修复AI算法流量检测PHP.INI通用过滤内置函数

知识点: 1、安全开发-原生PHP-PHP.INI安全 2、安全开发-原生PHP-全局文件&单函数 3、安全开发-原生PHP-流量检测&AI算法 一、演示案例-WEB开发-修复方案-PHP.INI配置 文章参考: https://www.yisu.com/ask/28100386.html https://blog.csdn.net/…...

蓝桥模拟+真题讲解

今天谁一篇文章哈 ! 由于本篇文章有些的题目只有图片,因此还望各位见谅。 目录 第一题 题目解析 代码原理 代码编写 填空技巧---巧用python 第二题 题目解析 ​编辑 填空技巧---巧用python 第三题 题目链接 题目解析 必备知识 解题技巧 …...

C语言【数据结构】:时间复杂度和空间复杂度.详解

引言 详细介绍什么是时间复杂度和空间复杂度。 前言:为什么要学习时间复杂度和空间复杂度 算法在编写成可执行程序后,运行时需要耗费时间资源和空间(内存)资源。因此衡量一个算法的好坏,一般是从时间和空间两个维度来衡量的,即时…...

大模型的参数数量与学习的知识数量之间

大模型的参数数量与学习的知识数量之间 大模型的参数数量与学习的知识数量之间呈现非线性、条件依赖的复杂关系,其本质是**「表达能力」与「知识编码效率」的动态博弈**。以下从五个维度拆解核心逻辑: 一、参数是知识的「载体容量」,但非唯一决定因素 理论上限:参数数量决…...

基于Python的selenium入门超详细教程(第2章)--单元测试框架unittest

学习路线 自动化测试介绍及学习路线-CSDN博客 ​自动化测试之Web自动化(基于pythonselenium)-CSDN博客 基于Python的selenium入门超详细教程(第1章)--WebDriver API篇-CSDN博客 目录 前言: 一、单元测试 1. 单元测试的定义 2. 单元测…...

日志、类加载器、XML(配置文件)

目录 一、日志1.日志技术的概述2.日志技术的体系a. Logback 3.日志的级别 二、类加载器1.概述2.类加载时机3.类加载过程3.类加载器的分类4.常用方法 三、XML(配置文件)1.概述2.XML的基本语法3.XML的文档约束a.DTD约束b.schema约束 4.XML文档解析a.Dom4jb…...

Flutter中的const和final的区别

目录 一、核心区别对比表 二、初始化机制深度解析 1. const 的编译期特性 2. final 的运行时特性 三、内存管理差异 1. const 的内存优化 2. final 的独立内存 四、集合类型的本质区别 1. const 集合的完全不可变性 2. final 集合的引用不可变性 五、在 Flutter 中的…...

DAY34 贪心算法Ⅲ

134. 加油站 - 力扣&#xff08;LeetCode&#xff09; 这种环路问题要记一下。 class Solution { public:int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {int curSum0;int totalSum0;int start0;for(int i0;i<gas.size();i){curSumga…...

AI大白话(一):5分钟了解AI到底是什么?

&#x1f31f;引言&#xff1a; 在这个信息爆炸的时代&#xff0c;“人工智能”、“AI”、“机器学习”、"深度学习"等词汇频繁出现在我们的生活中。 从手机里的语音助手&#xff0c;到网购平台的个性化推荐&#xff0c;再到最近大火的AI绘画和ChatGPT&#xff0c;人…...

(七)Spring Boot学习——Redis使用

有部分内容是常用的&#xff0c;为了避免每次都查询数据库&#xff0c;将部分数据存入Redis。 一、 下载并安装 Redis Windows 版的 Redis 官方已不再维护&#xff0c;你可以使用 微软提供的 Redis for Windows 版本 或者 使用 WSL&#xff08;Windows Subsystem for Linux&a…...

蓝桥与力扣刷题(蓝桥 字符统计)

题目&#xff1a;给定一个只包含大写字母的字符出 S, 请你输出其中出现次数最多的字符。如果有多个字母均出现了最多次, 按字母表顺序依次输出所有这些字母。 输入格式 一个只包含大写字母的字等串 S. 输出格式 若干个大写字母&#xff0c;代表答案。 样例输入 BABBACAC样…...

AtCoder Beginner Contest 397(ABCDE)

目录 A - Thermometer 翻译&#xff1a; 思路&#xff1a; 实现&#xff1a; B - Ticket Gate Log 翻译&#xff1a; 思路&#xff1a; 实现&#xff1a; C - Variety Split Easy 翻译&#xff1a; 思路&#xff1a; 实现&#xff1a; D - Cubes 翻译&#xff1a…...

Profinet转Profinet以创新网关模块为核心搭建西门子和欧姆龙PLC稳定通讯架构案例​

你是否有听过PROFINET主站与PROFINET主站之间需要做数据通讯有需求&#xff1f; 例如西门子1500与霍尼韦尔DCS系统两个主站之间的通讯。应用于PROFINET为主站设备还有欧姆龙、基恩士、罗克韦尔、施耐德、GE、ABB等品牌的PLC或DCS、FCS等平台。在生产或智能领域有通讯需求。两头…...

计算机视觉|Swin Transformer:视觉 Transformer 的新方向

一、引言 在计算机视觉领域的发展历程中&#xff0c;卷积神经网络&#xff08;CNN&#xff09; 长期占据主导地位。从早期的 LeNet 到后来的 AlexNet、VGGNet、ResNet 等&#xff0c;CNN 在图像分类、目标检测、语义分割等任务中取得了显著成果。然而&#xff0c;CNN 在捕捉全…...

C++单例模式精解

单例模式&#xff08;重点*&#xff09; 单例模式是23种常用设计模式中最简单的设计模式之一&#xff0c;它提供了一种创建对象的方式&#xff0c;确保只有单个对象被创建。这个设计模式主要目的是想在整个系统中只能出现类的一个实例&#xff0c;即一个类只有一个对象。 将单…...

【java】集合练习2

Student.java&#xff1a;保存学生类的定义。 public class Student {private String name;private int age;public Student(String name, int age) {this.name name;this.age age;}public String getName() { return name; }public int getAge() { return age; }Overridepu…...

FineBI_实现求当日/月/年回款金额分析

需求&#xff1a;原始数据结构如下&#xff0c;需要在分组表中&#xff0c;实现各城市当日/月/年的合同金额分析 实现步骤&#xff1a; ①维度拖入城市 ②分别取当日/月/年合同金额 当日DEF(SUM_AGG(${ 地区数据分析1 _ 合同金额 }),[${ 地区数据分析1 _ 城市 }],[LEFT(${ 地…...

【计算机网络】2物理层

物理层任务:实现相邻节点之间比特(或)的传输 1.通信基础 1.1.基本概念 1.1.1.信源,信宿,信道,数据,信号 数据通信系统主要划分为信源、信道、信宿三部分。 信源:产生和发送数据的源头。 信宿:接收数据的终点。 信道:信号的传输介质。 数据和信号都有模拟或数字…...

解决PC串流至IPad Pro时由于分辨率不一致导致的黑边问题和鼠标滚轮反转问题

问题背景 今天在做 电脑串流ipad pro 的时候发现了2个问题&#xff1a; 1.ipadpro 接上鼠标后&#xff0c;滚轮上下反转&#xff0c;这个是苹果自己的模拟造成的问题&#xff0c;在设置里选择“触控板与鼠标”。 关闭“自然滚动”,就可以让鼠标滚轮正向滚动。 2. ipadpro 分…...

在办公电脑上本地部署 70b 的 DeepSeek 模型并实现相应功能的大致步骤

以下是为客户在办公电脑上本地部署 70b 的 DeepSeek 模型并实现相应功能的大致步骤&#xff1a; 硬件准备&#xff1a; 70b 模型对硬件要求较高&#xff0c;确保办公电脑有足够强大的 GPU&#xff08;例如 NVIDIA A100 等高端 GPU&#xff0c;因为模型规模较大&#xff0c;普通…...

LLMs之CoD:《Chain of Draft: Thinking Faster by Writing Less》翻译与解读

LLMs之CoD&#xff1a;《Chain of Draft: Thinking Faster by Writing Less》翻译与解读 导读&#xff1a;这篇论文的核心是提出了一种名为“Chain of Draft”&#xff08;CoD&#xff0c;草稿链&#xff09;的新型提示策略&#xff0c;用于改进大型语言模型&#xff08;LLMs&a…...

Docker安装mysql——Linux系统

拉取mysql镜像 docker pull mysql 查看镜像 docker images 运行镜像&#xff08;这一步的作用&#xff1a;数据持久化&#xff0c;通过挂载卷将日志、数据和配置文件存储在主机上&#xff0c;避免容器删除导致数据丢失&#xff09; docker run -p 3306:3306 --name mysql …...

0CTF 2016 piapiapia 1

#源码泄露 #代码审计 #反序列化字符逃逸 #strlen长度过滤数组绕过 www.zip 得到源码 看到这里有flag &#xff0c;猜测服务端docker的主机里&#xff0c;$flag变量应该存的就是我们要的flag。 于是&#xff0c;我们的目的就是读取config.php 利用思路 这里存在 任意文件读取…...

2、危机应对-核心成员突然退出

一、场景&#xff1a; 当你团队中的骨干突然退出项目&#xff0c;如开发主程不干了&#xff0c;交付经理如何应对&#xff1f; 二、思考&#xff1a; 处理核心成员退出的本质是“通过系统性的减震降低人岗绑定的风险” 三、处理方式&#xff1a; 1、紧急评估影响 技术影响…...

python_巨潮年报pdf下载

目录 前置&#xff1a; 步骤&#xff1a; step one: pip安装必要包&#xff0c;获取年报url列表 step two: 将查看url列表转换为pdf url step three: 多进程下载pdf 前置&#xff1a; 1 了解一些股票的基本面需要看历年年报&#xff0c;在巨潮一个个下载比较费时间&…...