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

经典面试题:TCP 三次握手、四次挥手详解

在网络通信的复杂架构里,“三次握手”与“四次挥手”仿若一座无形的桥梁,它们是连接客户端与服务器的关键纽带。这座“桥梁”不仅确保了连接的稳固建立,还保障了连接的有序结束,使得网络世界中的信息能够顺畅、准确地流动。

在面试过程中,TCP 三次握手、四次挥手也经常被问到的问题。本文就来快速、详细的介绍下 TCP 三次握手、四次挥手的全部过程。

TCP 的三次握手和四次挥手实质就是 TCP 通信的连接和断开:

  • **三次握手:**同步双方的初始序列号(ISN),确认双方收发能力正常;
  • **四次挥手:**双方独立关闭数据通道,确保数据完整传输。

TCP头格式组成

为了使你更好的理解 TCP 三次握手和四次挥手过程,本小节先介绍下 TCP 头部格式。

  • 源端口号和目的端口号:代表连接发起方和连接接收方
  • 序号:在建立连接时,由计算机生产的随机数作为初始值,通过SYN包传给接收端主机,每发送一次数据,就累加一次该数据字节数的大小。用来解决网络包乱序问题。
  • 确认序号:指下一次期望收到的数据的序号,发送端收到这个确认应答以后,可以认为在这个序号以前的数据,都已经被正常接收。 用来解决网络丢包的问题
  • 标志位,如上图,一共6个
    • URG
    • ACK:该位为 1 时,「确认应答」的字段变为有效,TCP 规定除了最初建立连接时的 SYN 包之外该位必须设置为 1
    • PSH
    • RST:该位为 1 时,表示 TCP 连接中出现异常必须强制断开连接。
    • SYN:该位为 1 时,表示希望建立连接,并在其「序列号」的字段进行序列号初始值的设定。
    • FIN:该位为 1 时,表示今后不会再有数据发送,希望断开连接。当通信结束希望断开连接时,通信双方的主机之间就可以相互交换 FIN 位为 1 的 TCP 段。
  • 数据:连接需要发送的内容。

建立连接:三次握手

三次握手(Three-way Handshake)是 TCP 协议中用于建立连接的一个重要环节。在这一过程中,客户端和服务器需要互相发送三个数据包,以确保双方的接收和发送能力均正常,并为后续的数据传输指定初始化序列号,从而确保数据传输的可靠性。

TCP 三次握手流程图如下所示:

图中字符详解:

  • SYN:代表连接请求或接收的报文段。
  • seq:指发送的第一个字节的序号。
  • ACK:确认报文段,用于回应 SYN。
  • ack:确认号,表示希望收到的下一个数据的第一个字节的序号。

在 TCP 协议中,主动发起连接请求的一方被称为客户端,而被动等待连接的一方则被称为服务端。无论是客户端还是服务端,一旦 TCP 连接成功建立,双方均可进行数据的发送与接收。

连接建立之初,服务器和客户端都处于 CLOSED 状态。在通信正式开始前,双方需要分别创建自己的传输控制块(TCB)。服务器完成 TCB 创建后,会进入 LISTEN 状态,随时准备接收客户端发来的连接请求。

第一次握手

客户端向服务端发送一个 SYN 报文(SYN=1),并指明客户端的初始化序列号 ISN(x),即图中的 seq=x,它表示本报文段所发送的数据的第一个字节的序号。在发送 SYN 报文后,客户端进入 SYN_SENT 状态,意味着它正在等待服务端的连接确认。

SYN_SENT 状态解释:当客户端发送连接请求后,它进入 SYN_SENT 状态,等待服务端的响应。在这个状态下,客户端准备好了接受服务端的连接确认。

TCP 协议规定:SYN=1 的报文段是用于建立连接的请求,它不携带任何数据,但会消耗一个序号。这是 TCP 协议确保连接建立过程中的有序性和可靠性的一种方式。

第二次握手

服务器在接收到客户端的 SYN 报文后,会以 SYN 报文作为回应(SYN=1),并赋予自己独特的初始化序列号ISN(y),即图中的 seq=y。同时,服务器将客户端的 ISN+1 设置为确认号 ack 的值,以此确认已收到客户端的 SYN 报文,并期待接收到的下一个数据报的起始序号为 x+1。在此之后,服务器会进入 SYN-RCVD 状态,等待对连接请求的进一步确认。

**SYN-RCVD 状态解析:**当服务器在收到并发送连接请求后,会进入 SYN-RCVD 状态,此时它正在等待对初始连接请求的确认。在这个状态下,服务器已经准备好接受来自客户端的进一步通信。

TCP 协议规定:SYN=1 且 ACK=1 的报文段是用于确认连接的应答,它同样不携带任何数据,但通过确认号的使用,确保了连接建立过程中的有序性和可靠性。

第三次握手

在收到服务器发送的 SYN 报文后,客户端会回应一个 ACK 报文。这个 ACK 报文将服务器的 ISN+1 作为 ack 的值,表明客户端已经收到了服务器的 SYN 报文,并期待接收到的下一个数据报的起始序号为 y+1。

同时,客户端将自己的序列号 seq 设置为 x+1,即初始序列号 seq=x 增加 1。完成这些操作后,客户端进入 ESTABLISHED 状态,表示连接已成功建立。服务器在收到这个 ACK 报文后,也会转入 ESTABLISHED 状态,此时双方连接的建立工作全部完成。

**ESTABLISHED 状态解释:**当一个 TCP 连接进入 ESTABLISHED 状态时,它意味着连接已经打开,数据可以开始在双方之间传送。

断开连接:四次挥手

TCP 连接的终止需要经过四次包的交换,因此被称为四次挥手。在这四次交换中,客户端或服务器都可以主动发起连接的释放动作。值得注意的是,TCP 连接是双向的,因此四次挥手中,前两次主要用于断开一个方向的连接,后两次则用于断开另一方向的连接。

第一次挥手

客户端首先发送一个 FIN 报文,其中包含一个序列号 seq=u,表示请求连接终止。在发送完毕后,客户端停止数据发送,并主动关闭 TCP 连接。此时,客户端进入 FIN_WAIT_1 状态,等待服务器的确认。

**FIN_WAIT_1 状态解析:**该状态表示客户端正在等待远程 TCP 的连接中断请求,或者等待先前连接中断请求的确认。FIN=1 标志着该报文段是一个连接释放请求。而 seq=u 则代表客户端向服务器发送的最后一个字节的序号。

第二次挥手

服务端在收到客户端的 FIN 报文后,会发送一个 ACK 报文作为回应。这个 ACK 报文中,序列号值设为客户端序号值加 1,意在确认已收到客户端的报文。随后,服务端进入 CLOSE_WAIT 状态,等待本地用户的连接中断请求。

CLOSE_WAIT 状态解析:在此状态下,服务端等待来自本地用户的连接释放请求。ACK 报文中的 ACK=1 表示应答,而 seq=v 则指明了服务端释放应答报文段的首字节序号。同时,ack=u+1 表明服务端希望从第 u+1 个字节开始接收报文段,并已成功接收了前 u 个字节。

完成第二次挥手后,客户端到服务端的连接已释放,服务端不再接收客户端数据,而客户端也已无数据待发送。然而,服务端到客户端的连接仍保持开启,若服务端在此期间发送数据,客户端仍需正常接收。此状态将持续一段时间,直至整个 CLOSE-WAIT 状态结束。

第三次挥手

服务端在完成数据的发送后,会向客户端发送一个连接释放报文。这个报文头包含 FIN 标志位为 1,以及 ack 序号值为 u+1。由于在 CLOSE_WAIT 状态期间,服务端可能又发送了一些数据,假设此时的序列号为 seq=w。发送完毕后,服务端进入 LAST_ACK 状态,等待来自客户端的连接中断确认。

第四次挥手

客户端在收到服务端的 FIN 报文后,会响应一个 ACK 报文,其中 ack 序号值为 w+1,同时将自己的序列值加 1作为 ACK 报文的 seq 序号值,即 seq=u+1。此后,客户端进入 TIME_WAIT 状态。

**TIME_WAIT:**确保远程 TCP 收到连接中断请求的确认状态会持续 2MSL(最长报文段寿命)的时间。在此期间, TCP 连接并未完全释放。若在这段时间内未收到服务端的重发请求,客户端将进入 CLOSED 状态,并撤销 TCB。

服务端在收到客户端的确认 ACK 报文后,会立即进入 CLOSED 状态,并撤销 TCB,从而结束此次 TCP 连接。值得注意的是,服务端结束 TCP 连接的时间点通常早于客户端。

四次挥手 vs 三次握手

阶段三次握手四次挥手
目的建立连接,同步序列号安全关闭双向数据通道
交互次数3次4次
关键标志位SYNACKFINACK
状态复杂度简单(直接建立)复杂(需处理半关闭和TIME_WAIT

关联面试题

1. 为何 TCP 建立连接时采用三次握手而非两次或四次?

  • 两次不够:无法确认客户端的接收能力(若服务端的SYN-ACK丢失,客户端不知服务端已就绪)。
  • 四次冗余:三次已能确保双向通信能力,无需额外交互。

具体原因如下:

  1. 确保双方都能发送和接收:三次握手可以确保双方都具备发送和接收数据的能力。在第一次握手时,客户端发起请求,第二次握手时,服务器确认收到了请求并表示自己也可以通信,第三次握手时,客户端确认收到了服务器的响应。这保证了通信的可靠性。
  2. 防止重复连接初始化问题:假设没有三次握手,而是两次握手,那么可能会出现一种情况:客户端发送了一个连接请求(SYN),但由于网络问题,服务器没有及时收到或者延迟了。客户端在等待了一段时间后认为请求失败,重新发送了一个新的 SYN,而此时第一个 SYN 报文延迟到达服务器,服务器误认为客户端又发起了一次新的连接请求,从而产生混乱。通过三次握手,能够有效避免这种问题,确保连接的一致性。
  3. 同步初始序列号:三次握手过程中,客户端和服务器会相互交换各自的初始序列号,以保证接下来的数据传输能够按顺序接收和处理。这是实现TCP可靠传输的关键步骤之一。

三次握手的设计主要是为了确保在不可靠的网络环境中,TCP连接的建立过程能够具有可靠性和一致性,并能够防止潜在的错误连接。

2. 为何 TCP 关闭连接时需要四次挥手?

  1. 保证双方数据完整性:在关闭连接之前,双方需要确认所有数据已经被成功接收。第一次挥手时,客户端发送 FIN 报文,表示自己不再发送数据,但仍然可以接收数据。第二次挥手时,服务器确认收到这个 FIN,并且可以继续发送数据。第三次挥手时,服务器发送自己的 FIN 报文,表示自己也不再发送数据。最后,客户端确认服务器的 FIN,确保双方都完成了数据传输。
  2. 分半关闭(Half-Close):TCP 连接是全双工的,这意味着数据可以双向流动。四次挥手允许连接的一方关闭数据发送通道,但仍然可以接收数据,直到另一方也关闭发送通道。因此,四次挥手过程允许双向关闭连接,确保双方都能完成数据传输。
  3. 确保完整关闭:客户端在进入TIME-WAIT状态后,会等待一段时间以确保服务器收到了最后的 ACK 报文。这段时间可以避免因网络延迟等问题导致的重复数据问题,确保连接完全关闭后再释放资源。

3. 为何 TIME_WAIT 状态需持续 2MSL 后才能转为 CLOSE 状态?

当 TCP 连接的一方完成连接释放后,会进入 TIME_WAIT 状态。这个状态需要持续 2 倍的最大段寿命(Maximum Segment Lifetime,MSL)的时间,这是为了确保在传输过程中可能存在的延迟数据包能够被对方完全接收。只有当 2MSL 时间过去后,确认对方已收到所有数据,该 TCP 连接才能完全关闭,进 入CLOSE 状态。

1、确保服务端能够接收到客户端的确认应答。

如果客户端在发送完确认应答后立即进入 CLOSED 状态,而该应答不幸丢失,服务端在等待超时后将尝试重新发送连接释放请求。但此时,由于客户端已经关闭,无法再作出响应,这会导致服务端无法正常关闭 TCP 连接。因此,TIME_WAIT 状态的持续存在,是为了保证服务端能够接收到并处理客户端的确认应答,从而确保连接的平滑关闭。

2、防止“三次握手”中提及的“已失效的连接请求报文段”干扰当前连接。

当客户端发送完最后一个确认报文后,经过 2MSL 的时间间隔,可以确保在本连接持续时间内产生的所有报文段都已从网络中清除。这样,新建立的连接就不会受到旧连接请求报文的影响。

3、为什么是 2MSL?

2MSL 的时间是从客户端收到 FIN 报文段后发送给服务器 ACK 开始计时的,考虑到重传的因素,那么就需要服务器再次给客户端传 FIN+ACK 报文段。

保证在两个传输方向上的尚未被接收或迟到的报文段都消失,理论上保证最后一个报文可靠到达,就需要 2MSL,一个方向一个 1MSL。

4. CLOSE_WAIT 状态有什么影响?

当服务器收到客户端的 FIN,并回复了 ACK 后,会进入 CLOSE_WAIT 状态,此时 TCP 链接处于半关闭状态。CLOSE_WAIT 状态一直存在就说明服务器没有调用 close 并没有发送 FIN 报文段。而服务期长期保持这个状态,就会一直占用这大量的 socket 文件描述符,大量的 CLOSE_WAIT 状态存在就会导致文件描述符被占用,一些客户端无法连接。

5. TIME_WAIT和CLOSE_WAIT的区别?

CLOSE_WAIT 状态是被动关闭的一端在接收到另一端关闭请求过后并将 ACK 发送出去后所处的状态。这种状态表示:收到了对端关闭的情况,但是本端还没有完成工作,未关闭。

TIME_WAIT 状态是主动关闭一端在本端已经关闭的前提下,收到对端的关闭请求并且将 ACK 发送出去所处的状态。这种状态表示:双方都已经完成工作,只是为了确保迟来的数据报能被识别丢弃,可靠的终止 TCP 连接。

6. 为什么连接的时候是三次握手,关闭的时候却是四次挥手?

因为当服务端收到客户端的 SYN 连接请求报文后,可以直接发送 SYN+ACK 报文。其中 ACK 报文是用来应答的,SYN 报文是用来同步的。

但是关闭连接时,当服务端收到 FIN 报文时,很可能并不会立即关闭 SOCKET,所以只能先回复一个 ACK 报文,告诉客户端,“你发的 FIN 报文我收到了”。只有等到我服务端所有的报文都发送完了,我才能发送 FIN 报文,因此不能一起发送。故需要四步握手。

7. 如果已经建立了连接,但是客户端突然出现故障了怎么办?

TCP 设有一个保活计时器,显然,客户端如果出现故障,服务器不能一直等下去,白白浪费资源。服务器每收到一次客户端的请求后都会重新复位这个计时器,时间通常是设置为 2 小时,若 2 小时还没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔 75 分钟发送一次。若一连发送 10 个探测报文仍然没反应,服务器就认为客户端出了故障,接着就关闭连接。

8. 在三次握手中,SYN 和 ACK 的作用是什么?

在 TCP 的三次握手中,SYN 和 ACK 确保了连接的建立和通信的同步。

  • SYN(Synchronize)是 TCP 协议中的一个标志位,用于在建立连接时进行通信的同步。在三次握手的第一次交互中,客户端发送一个 SYN=1,ACK=0 标志的数据包给服务端,请求建立连接。这个 SYN 包的作用是向服务端发起连接请求,并附带一个序列号(Sequence Number),用于标识后续发送的数据包。SYN 标志位的设置表示客户端希望建立一个新的连接或确认一个连接请求;
  • ACK(Acknowledgement)是确认标志,用于确认接收到的数据包。在第二次握手中,服务端收到客户端的 SYN 包后,会发送一个 SYN=1,ACK=1 标志的数据包给客户端。这个 SYN+ACK 包的作用是告诉客户端,服务端已经收到了连接请求,并允许建立连接。同时,ACK=1 表示服务端对客户端发送的 SYN 包进行了确认。此外,服务端也会发送自己的序列号给客户端,用于后续的数据传输。
  • 在第三次握手中,客户端收到服务端的 SYN+ACK 包后,会发送一个 SYN=0,ACK=1 的数据包给服务端。这个 ACK 包的作用是告诉服务端,客户端已经收到了 SYN+ACK 包,并对服务端的 SYN 包进行了确认。
  • 至此,三次握手完成,TCP 连接建立成功,双方可以开始进行数据传输。

在整个过程中,SYN 和 ACK 标志位确保了连接的建立和通信的同步。SYN 用于发起连接请求和标识序列号,而ACK 用于确认接收到的数据包。这种机制可以有效地确保数据的可靠传输和连接的稳定性。

9. 三次握手过程中可以携带数据吗?

在 TCP 的三次握手过程中,SYN 和 SYN+ACK 报文段是不携带数据的,它们仅仅用于建立连接时的同步和确认。但是,最后一次的 ACK 报文段是可以携带数据的。这是因为当发送方收到对方的 SYN+ACK 报文段后,连接就已经建立了,此时发送方就可以立即发送数据,而这个数据就可以和 ACK 报文段一起发送,从而提高了效率。

虽然第三次握手可以携带数据,但在实际网络编程中,并不推荐这样做。因为这样做可能会带来一些问题,比如接收方可能无法及时准备好接收数据,导致数据丢失或乱序。

因此,通常建议将数据的发送放在三次握手完成之后进行,以确保数据的可靠传输。

10. TCP 连接中的半连接队列和全连接队列是什么?

TCP 连接中的半连接队列(也称为 SYN 队列)用于存储处于 TCP 三次握手过程中第一步的连接请求。

当服务端收到客户端发起的 SYN 请求后,内核会把该连接存储到半连接队列中,等待完成三次握手的过程。此时,连接请求还没有完成握手,因此被认为是“半连接”。如果半连接队列满了,新来的连接请求可能会被丢弃或者根据系统配置发送 RST 报文。

全连接队列就是已经完成三次握手,建立起连接的就会放在全连接队列中。

半连接队列的主要作用是管理并跟踪那些尚未完全建立的连接,确保在三次握手完成之前,这些连接请求能够得到妥善的处理。它是 TCP 协议保证连接可靠性和性能的重要机制之一。

需要注意的是,当服务端并发处理大量请求时,如果 TCP 半连接队列过小,就容易出现溢出的情况,导致后续的请求被丢弃,从而影响服务端的请求处理能力。因此,合理设置和调整半连接队列的大小对于优化网络性能和提升系统稳定性具有重要意义。

11. TCP 连接中 ISN(Initial Sequence Number)是什么?

在 TCP 连接中,ISN(Initial Sequence Number,初始序列号)是每个 TCP 连接在建立时由 TCP 协议为每一个数据包所赋予的序列号。它是 TCP 可靠传输的一个重要组成部分,用于确保数据的顺序性和完整性。

  • 当 TCP 连接建立时,客户端和服务器都会选择一个初始序列号(ISN)作为它们发送的第一个数据包的序列号。这个序列号是一个随机值,通常不会重复,用于标识该连接中的每一个数据包的顺序。
  • 在数据传输过程中,TCP 协议会根据数据包的发送顺序为每个数据包分配一个递增的序列号。ISN 可以看作是一个 32 比特的计数器,每 4ms 加 1 。
  • 通过序列号,接收方可以准确地按照发送方的发送顺序来重组数据,从而确保数据的顺序性。
  • 此外,序列号还可以用于检测丢失或重复的数据包。当接收方发现数据包的序列号不连续时,它会向发送方发送一个 ACK(确认)消息,请求发送方重传丢失的数据包。同样地,如果接收方接收到一个重复的数据包(即具有相同序列号的数据包),它可以通过序列号来识别并丢弃这个重复的数据包。

因此,ISN 在 TCP 连接确保了数据的顺序性和完整性,为 TCP 的可靠传输提供了基础。

12. 为什么 TCP 连接建立需要发送序列号?

TCP 连接建立需要发送序列号的原因主要有以下几点:

  • 确保数据的顺序性: TCP 是一个面向连接的、可靠的、基于字节流的传输层通信协议。在 TCP 通信中,发送方和接收方都需要按照数据的发送顺序来接收和处理数据。序列号用于标识每一个发送的数据包,确保接收方能够按照正确的顺序重组数据。
  • 实现可靠传输: TCP 通过序列号来实现数据的可靠传输。当接收方收到数据包后,会向发送方发送一个确认(ACK)消息,告知已经成功接收到的数据包的序列号。如果发送方在某个时间点内没有收到某个数据包的 ACK,它会认为该数据包丢失,并重新发送该数据包。序列号使得发送方能够准确地知道哪些数据包已经成功发送并被接收,哪些数据包需要重传。
  • 处理网络中的数据包乱序: 在网络传输过程中,由于网络拥塞、路由变化等原因,数据包可能会乱序到达接收方。通过序列号,接收方能够识别并重新排序这些乱序的数据包,确保数据的完整性和正确性。
  • 流量控制和拥塞控制: TCP 还利用序列号来实现流量控制和拥塞控制。发送方会根据接收方的确认消息和当前的网络状况来调整发送速率,以避免网络拥塞和数据丢失。序列号在这个过程中起到了关键作用,帮助发送方和接收方协调数据的发送和接收。

TCP 连接建立需要发送序列号是为了确保数据的顺序性、实现可靠传输、处理网络中的数据包乱序以及实现流量控制和拥塞控制。这些功能共同保证了 TCP 能够提供高效、可靠的数据传输服务。

13. 在 TCP 通信中,如果一方突然崩溃,另一方如何知道?

在 TCP 通信中,如果一方突然崩溃(例如,由于硬件故障、操作系统崩溃或应用程序异常终止),另一方通常通过以下几种机制来检测这种情况:

  • 心跳机制(Keep-Alive): TCP 本身并没有一个显式的“心跳”机制,但许多操作系统和应用程序层协议实现了这种机制。通过定期发送小的数据包(通常称为“探测包”或“心跳包”),接收方可以通知发送方它仍然存活并且连接仍然有效。如果发送方在一段时间内没有收到响应,它可能会认为接收方已经崩溃,并关闭连接。
  • 超时重传和重试: TCP 使用超时重传机制来处理丢失的数据包。当发送方发送一个数据包后,它会等待一个确认(ACK)。如果在一定的超时时间内没有收到 ACK,发送方会重传该数据包。如果经过多次重传仍然未收到确认,发送方会认为连接已经中断,并关闭连接。同样,接收方在收到乱序的数据包或数据包丢失时,也会通过发送重复 ACK 或通知发送方进行快速重传来处理。
  • 应用层协议: 除了 TCP 本身的机制外,应用层协议(如 HTTP、FTP 等)通常也会实现自己的连接管理和错误处理机制。这些协议可能会定义特定的消息或命令来通知对方连接已经中断,或者通过超时和重试策略来处理突然的崩溃。
  • 操作系统和网络栈的通知: 在某些情况下,当一方崩溃时,操作系统或网络栈可能会向另一方发送一个特殊的信号或错误消息。例如,当 TCP 连接的一方异常终止时,操作系统可能会向另一方发送一个 RST(重置)数据包来关闭连接。

由于网络的复杂性和不确定性,有时候即使一方崩溃,另一方也可能无法立即检测到。这取决于网络状况、操作系统的实现以及应用层协议的设计。因此,在设计和实现基于 TCP 的应用程序时,应该考虑到这种可能性,并采取相应的错误处理和恢复策略。

  • 知识星球:云原生AI实战营。10+ 高质量体系课( Go、云原生、AI Infra)、15+ 实战项目,P8 技术专家助你提高技术天花板,入大厂拿高薪;
  • 公众号:令飞编程,分享 Go、云原生、AI Infra 相关技术。回复「资料」免费下载 Go、云原生、AI 等学习资料;
  • 哔哩哔哩:令飞编程 ,分享技术、职场、面经等,并有免费直播课「云原生AI高新就业课」,大厂级项目实战到大厂面试通关;

相关文章:

经典面试题:TCP 三次握手、四次挥手详解

在网络通信的复杂架构里,“三次握手”与“四次挥手”仿若一座无形的桥梁,它们是连接客户端与服务器的关键纽带。这座“桥梁”不仅确保了连接的稳固建立,还保障了连接的有序结束,使得网络世界中的信息能够顺畅、准确地流动。 在面…...

Raft算法学习(1)博士论文大纲

参考资料 原文一共257页,其中前六章为算法重点介绍,第七章有点像A/B TEST 论文标题: 共识:连接理论与实践 (CONSENSUS: BRIDGING THEORY AND PRACTICE) 作者: Diego Ongaro 日期: 2014年8月 机构&#xff…...

PDF处理控件Aspose.PDF教程:以编程方式将 PDF 导出为 JPG

在本节中,我们将探讨如何使用 Aspose.PDF 库将 PDF 文档转换为 JPG 图像。Aspose.PDF 是一个功能强大且用途广泛的库,专为需要以编程方式处理 PDF 文件的开发人员而设计。它提供了丰富的功能,可用于跨多个平台创建、编辑和转换 PDF 文档。其主…...

记录一下flutter项目自己封窗的弹窗

在评委项目开发中我使用到的弹窗dialog与modal sheet底部弹出组件,我对其进行了基础的封装,以适用于本项目,代码如下: class JudgeDialog {// 内容边距static EdgeInsetsGeometry _contentPadding(String? content) {return c…...

计算机网络基础概念

网络通信的本质就是进程间通信。我们日常使用的聊天软件、在线视频软件等,事实上都是本机客户端进程与远地服务端进程之间进行网络通信所实现的。我们与朋友进行远程聊天,本质上是从本地客户端将聊天内容发送给服务端,再由服务端转发给目标客…...

【原创】ubuntu22.04下载编译AOSP 15

repo init -u http://mirrors.tuna.tsinghua.edu.cn/git/AOSP/platform/manifest -b master source build/envsetup.sh lunch aosp_cf_x86_64_phone-trunk_staging-userdebug find ./ -name “index.lock” -exec rm -f {} ; find ./ -name “index.lock” -exec rm -i {} ;…...

鸿蒙PC新物种发布!华为MateBook Pro/ Fold深度解析:折叠屏革命与生态破局

华为在5月19日发布会上推出的两款鸿蒙电脑新品——华为MateBook Pro和HUAWEI MateBook Fold 非凡大师,标志着其在PC领域的深度布局和技术突破。结合发布会信息和行业背景,以下为分析及影响预测: 一、产品核心亮点及创新 华为MateBook Pro&…...

数据要素如何重构人力资本升级

一、数字经济时代 在传统工厂车间,老师傅的经验智慧曾是企业最宝贵的资产。而在现代的数字化办公室,每天产生的千万条数据流正在重塑企业创新规则。这个变革的核心密码锁定在两个关键维度:人力资本结构的质变与创新资源的智配。 数据要素与…...

【爬虫】12306自动化购票

上文: 【爬虫】12306查票-CSDN博客 下面是简单的自动化进行抢票,只写到预定票,没有写完登陆, 跳出登陆后与上述代码同理修改即可。 感觉xpath最简单,复制粘贴: 还有很多写法: 官网地址&#…...

保密行业工作沟通安全:吱吱软件的“四重防泄露”设计

“工作沟通安全威胁是指在金融、科技、医疗等保密行业中,错发、泄露、窃取一条消息或者一份文件,都有可能引发数据安全灾难性失控。以往的即时通讯软件仅依赖单一的加密手段,无法满足保密行业从发送、传输到接受全链路加密的更高规格的数据安…...

2001-2023年上市公司管理讨论与分析文本数据(MDA文本数据)

2001-2023年上市公司管理讨论与分析文本数据(MD&A文本数据) 1、时间:2001-2023年 2、来源:上市公司年报 3、格式:txt 4、样本量:6W 5、说明:“管理层讨论与分析”(MANAGEME…...

Unity3D仿星露谷物语开发46之种植/砍伐橡树

1、目标 种植一棵橡树,从种子变成大树。 然后可以使用斧头砍伐橡树。 2、删除totalGrowthDays字段 修改growthDays的含义,定义每个值为到达当前阶段的累加天数。此时最后一个阶段就是totalGrowthDays的含义。所以就可以删除totalGrowthDays字段。 &…...

9-社区动态(Stack布局)

涉及知识点: stack布局 video组件 3.组件状态控制: State、Prop以及Link装饰器 组件状态控制:Observed&ObjectLink装饰器 课时: 2 1 任务 1.1 需求 完成社区动态功能,社区动态显示用户发布的跟游戏相关的短视频,自动循环…...

如何使用MATLAB NLP工具箱进行文本聚类

文章目录 前言一、核心流程与代码实现二、高级聚类技术三、评估聚类质量四、实战案例:新闻聚类五、优化技巧与注意事项 前言 在 MATLAB 中使用 NLP 工具箱进行文本聚类主要分为数据预处理、特征提取、相似度计算、聚类算法应用和结果分析五个核心步骤。以下是详细教…...

deepseek梳理java高级开发工程师es面试题

Elasticsearch 面试题及答案(高级 Java 开发工程师版) 基础概念 1. 解释 Elasticsearch 中的倒排索引是什么?为什么它比传统数据库更适合全文搜索? 答案: 倒排索引是一种将文档中的词项(token)映射到包含该词项的文…...

查看mysql配置文件my.cnf的位置

3.删除mysql相关文件 想要完全卸载mysql,不仅要卸载应用,配置文件及相关文件也需要一一清除,还原环境配置,减少一些麻烦。 sudo rm -rf /usr/local/mysql sudo rm -rf /etc/my.cnf sudo rm -rf /var/db/mysql sudo rm -rf /var/…...

PyTorch进阶实战指南:01自定义神经网络组件开发

PyTorch进阶实战指南:01自定义神经网络组件开发 前言 在深度学习领域,PyTorch凭借其动态计算图和灵活的模块化设计,已成为学术研究和技术落地的首选框架之一。本文聚焦于神经网络组件的自定义开发,旨在帮助开发者突破现成模型的限…...

【MySQL】04.数据类型

首先我们来看一下数据类型分类: 我们接下来对红色标识的进行介绍,其他的自行了解即可。 1. 数值类型 1.1 bit 我们以bit为例来介绍整型。 mysql> create table test_bit(-> sex bit(1)-> ); mysql> desc test_bit; -----------------…...

MCP专题 | 探索MCP服务器世界:增强AI能力的精选推荐

在人工智能快速发展的今天,模型上下文协议(MCP,Model Context Protocol)已成为一项重要的技术标准,它使AI模型能够安全地与外部资源交互。MCP服务器作为AI与工具、数据库和API之间的桥梁,极大地扩展了AI的功…...

深入解析OrientDB:多模型数据库的技术优势与实际应用

OrientDB 是一款开源的多模型 NoSQL 数据库,融合了文档数据库、图数据库和对象数据库的特性。它不仅支持灵活的数据建模,还提供了高性能的查询能力,适用于社交网络、物联网、内容管理等场景。本文详细探讨 OrientDB 的核心特性、应用场景&…...

芯片分享之AD976性能介绍

产品特征: D976和AD976A均为高速、低功耗、16位模数转换器(ADC),采用5 V单电源供电。AD976A的吞吐速率为200 ksps,而AD976的吞吐速率为100 ksps。各器件均内置一个逐次逼近型开关电容ADC、一个2.5 V内部基准电压源和一个高速并行接口。最大功…...

Flutter - 集成三方库:数据库(sqflite)

数据库 $ flutter pub add sqlite $ flutter pub get$ flutter run运行失败,看是编译报错,打开Xcode工程 ⌘ B 编译 对比 GSYGithubAppFlutter 的Xcode工程Build Phases > [CP] Embed Pods Frameworks 有sqfite.framework。本地默认的Flutter工程默认未生成Pod…...

野火鲁班猫(arrch64架构debian)从零实现用MobileFaceNet算法进行实时人脸识别(三)用yolov5-face算法实现人脸检测

环境直接使用第一篇中安装好的环境即可 先clone yolov5-face项目 git clone https://github.com/deepcam-cn/yolov5-face.git 并下载预训练权重文件yolov5n-face.pt 网盘链接: https://pan.baidu.com/s/1xsYns6cyB84aPDgXB7sNDQ 提取码: lw9j (野火官方提供&am…...

基于matlabcd7.x的无网格近似方法

无网格近似方法(Meshless Methods)是一类数值计算方法,用于解决偏微分方程(PDEs)问题,特别是在几何形状复杂或需要动态网格更新的场景中。与传统的有限元方法(FEM)相比,无…...

塔式服务器都有哪些重要功能?

塔式服务器作为一种拥有着独特立式设计的服务器,能够帮助企业节省一定的放置空间,提供一系列的功能和优势,可以运用在多种应用场景当中,下面将探讨一下塔式服务器的主要功能都有哪些? 塔式服务器可以支持基本的应用程序…...

【基于SpringBoot的图书购买系统】深度讲解 分页查询用户信息,分析前后端交互的原理

引言📚 在企业级应用开发中,用户管理系统是几乎所有后台管理系统的核心模块之一。它不仅需要实现用户数据的增删改查,还需要考虑数据分页展示、状态管理、前后端交互效率等问题。本文将以一个实际的用户管理系统为例,详细讲解基于…...

机器学习算法-聚类K-Means

先来看看K-Means算法的核心流程吧 下面我们通过一个简单聚类来介绍K-Means算法迭代过程 如图(a)所示:表示初始化数据集。 如图(b)所示:假设K2,随机选择两个点作为类别质心,分别为图中的红色和蓝色质心。 如图©所示&#xff…...

初识Linux 进程:进程创建、终止与进程地址空间

目录 0.写在前面 1.进程创建 fork(): exec(): 2.进程地址空间 3.进程终止 正常终止(主动退出) 异常终止(被动终止) 0.写在前面 本文将对Linux环境下的进程:包括进程创建、终止与进程等待…...

2025年PMP 学习二十二 15章 项目绩效域

2025年PMP 学习二十二 15章 项目绩效域 文章目录 2025年PMP 学习二十二 15章 项目绩效域项目绩效域1.项目绩效域2.项目持续效域3.项目管理中的干系人管理 1.干系人持续效域促进干系人参与的步骤: 2 团队持续效域1 团队持续效域及项目团队人员有关系的活动和职能&…...

顶级流媒体服务商 Spotify 2025.04 故障复盘报告,吃他人的堑长自己的智

2025 年 4 月 16 日,Spotify 经历了一次影响全球用户的中断。以下就是发生了什么以及我们将如何解决它。 背景 我们使用 Envoy Proxy 作为我们的网络外围系统。外围是我们的软件接收用户(您!)网络流量的第一部分。然后&#xff…...

服装收银系统哪个好?服装店进销存管理软件全面评测

在服装批发零售行业,选择一款合适的收银系统和进销存管理软件至关重要。好的系统不仅能提高工作效率,还能帮助商家精准掌握库存、优化销售策略。 本文将全面分析服装收银系统的选择标准,并重点介绍秦丝进销存这一专业解决方案。 一、服装收…...

Java程序员从0学AI(二)

一、前言 在上一篇文章中,我们初步认识了 AI 领域的核心基础概念,如大语言模型(LLM)的参数量特征、提示词(Prompt)对交互效果的关键作用、文本处理单元 Token 的独特定义,以及通过向量转换实现…...

进阶知识:无参的函数装饰器之深入理解@wraps()

进阶知识:无参的函数装饰器之深入理解wraps(func) 一、wraps(func)的本质解析 1.1 核心作用 wraps(func)是functools模块提供的装饰器工具,用于保留被装饰函数的元信息。它通过将被装饰函数的名称(__name__)、文档字符串&#…...

《C 语言 sizeof 与 strlen 深度对比:原理、差异与实战陷阱》

目录 一. sizeof 和 strlen 的对比 1.1 sizeof 1.2 strlen 1.3 对比表格 二. 数组和指针笔试题解析 2.1 一维数组 2.2 字符数组 2.2.1 代码练习一 2.2.2 代码练习二 2.2.3 代码练习三 2.2.4 代码练习四 2.2.5 代码练习五 2.2.6 代码练习六 2.3 二维数组 …...

C++ 初阶 | 类和对象易错知识点(上)

目录 0.引言 1.访问限定符 2.域 3.类的实例化和声明 4.this指针 5.构造函数(自动执行) 6.拷贝构造 7.运算符重载 8.日期类的实现 9.总结 0.引言 今天,小邓儿和大家分享一下,C在类和对象中的易错知识点🤭&am…...

USB转TTL

USB转TTL模块是实现计算机USB接口与TTL电平串口设备(如单片机、嵌入式系统)通信的核心组件,其原理涉及协议转换和电平适配两大关键技术 一、核心功能与应用场景 功能:将计算机的USB信号(高速差分信号、USB协议&#…...

汽车生产中的测试台连接 – EtherCAT 转CANopen高效的网关通信

使用 EtherCAT 和 CANopen协议,实现对汽车零部件的高效生产线末端测试 某电动机、电桥和变速箱制造商之一,正在其生产线上使用ETHERCAT转canopen网关WL-ECAT-COP的解决方案。集成到测试线中的下线测试必须映射众多待测设备的测试应用。该制造商已指定 Et…...

汽车充电过程中--各个电压的关系(DeepSeek)

在电动汽车的充电过程中,电池的充电机制涉及多个电压参数的协调控制,以下从原理到实际应用逐步分析: 1. 充电基础原理 电动汽车电池(通常为锂离子电池组)的充电本质是通过外部电源向电池注入电能,使锂离子…...

基于HTML的Word风格编辑器实现:从零打造功能完备的富文本编辑器

引言 在Web开发中,实现一个功能完备的富文本编辑器是一个常见需求。本文将基于HTML5和JavaScript,结合第三方库,打造一个具有Word风格界面的富文本编辑器,支持格式设置、图片插入、表格创建、文件导入导出等核心功能。 完整代码…...

亚远景-汽车软件开发的“升级之路”:ASPICE各等级说明

ASPICE(Automotive SPICE)将汽车软件开发过程的成熟度划分为六个等级,从0级到5级,每个等级代表了组织在软件开发过程中的不同能力水平。以下是各等级的详细说明: 等级0:不完整(Incomplete&#…...

Unity Display 1 No cameras rendering

一个相机不能同时输出到屏幕和RenderTexture​​。 Output Texture,要么是 None (屏幕),要么是RenderTexture。 如果此时相机已经输出到RenderTexture,场景中又没有别的相机在渲染,屏幕将变黑并显示No cam…...

Python Selenium 使用指南

Selenium 是一个用于自动化 Web 浏览器交互的强大工具,常用于网页测试、数据抓取和自动化任务。以下是 Python 中 Selenium 的详细使用说明。 安装 Selenium 首先需要安装 Selenium 库和浏览器驱动: pip install selenium 然后下载对应浏览器的驱动&…...

Cribl 对数据源进行过滤-01

先说一个项目中实际的例子: Cribl 利用filter expression 来过滤 data, 举个例子: source1: sourcerouter=A, source 2: sourcerouter=B, 这个时候,可以要把他们合并起来: sourcerouter=A || sourcerouter=B 来进行过滤想要的数据。 最后可以使用一个pipeline 来对数据进行…...

python 通过 pymysql 获取 select count(*) xxx 的数量

在使用 pymysql 库来获取 SELECT COUNT(*) 语句的结果时,你可以通过以下步骤实现: 安装 pymysql:如果你还没有安装 pymysql,可以通过 pip 安装它。 pip install pymysql连接到数据库:使用 pymysql.connect() 方法连接…...

定时任务延迟任务

二者的区别: 定时任务:有固定周期的,有明确的触发时间。 延迟任务:没有固定的开始时间,它常常是由一个事件触发的,而在这个事件触发之后的一段时间内触发另一个事件,任务可以立即执行&#xff0…...

【动手学深度学习】1.1~1.2 机器学习及其关键组件

目录 一、引言1.1. 日常生活中的机器学习1.2. 机器学习中的关键组件1)数据2)模型3)目标函数4)优化算法 一、引言 1.1. 日常生活中的机器学习 应用场景: 以智能语音助手(如Siri、Alexa)的唤醒…...

LLaVA-MoD:基于MoE结构和蒸馏训练方法,训练轻量化多模态大模型!!

摘要:我们介绍了LLaVA-MoD,这是一个旨在高效训练小型多模态语言模型(s-MLLM)的创新框架,通过从大规模多模态语言模型(l-MLLM)中提取知识来实现。我们的方法解决了多模态语言模型(MLL…...

YOLOv8 的双 Backbone 架构:解锁目标检测新性能

一、开篇:为何踏上双 Backbone 探索之路 在目标检测的领域中,YOLOv8 凭借其高效与精准脱颖而出,成为众多开发者和研究者的得力工具。然而,传统的单 Backbone 架构,尽管已经在诸多场景中表现出色,但仍存在一…...

SSRF(服务器端请求伪造)基本原理靶场实现

1、漏洞原理 攻击者通过构造恶意请求,诱使服务器向内部系统或第三方服务发起非预期的网络请求。其核心在于 服务器信任了不可信的用户输入,并基于该输入发起网络操作。 2、攻击场景与利用方式 1. 基础利用 攻击类型示例Payload目标读取本地文件file://…...

自动化测试脚本点击运行后,打开Chrome很久??

亲爱的小伙伴们大家好。 小编最近刚换了电脑,这几天做自动化测试发现打开Chrome浏览器需要等待好长时间,起初还以为代码有问题,或者Chromedriver与Chrome不匹配造成的,但排查后发现并不是!! 在driver.py中…...