计算机网络——TCP协议

💡TCP的可靠不在于它是否可以把数据100%传输过去,而是

  • 1.发送方发去数据后,可以知道接收方是否收到数据;
  • 2.如果接收方没收到,可以有补救手段;
  • 图1.TCP组成图

TCP的可靠性是付出代价的,即传输效率和复杂程度 。

 1.确认应答

发送方把数据发给接收方,接收方收到数据需要给发送方返回一个应答报文(确认序列号)(ackownledge,ack),发送方收到应答报文,说明数据发送成功。

发送方连续发多条数据的情况,这种情况会存在"后发先至"的情况。所以引入"序列化",此处TCP需要完成:

1.确保发出去的数据与应答报文可以对号

2.确保在出现后发先至情况下可以按正确顺序解答


*序号按照字节编号,初始序号一般不从1开始。通过使用序列号Sequence Number,SEQ)和确认序列号(ACK),TCP协议可以实现可靠的数据传输。序列号用于标识和排序报文段,而确认序列号用于确认已经接收到的报文段。

图2.确认应答ack图

eg:当第一个数据报中有1000个字节的载荷数据,其中第一个字节的序号是1,就在TCP报头序号中写1,即载荷数据中只记录这次传输的载荷数据的第一个字节的序号,此时ack写入1001并返回。此时发送方就知道刚才发送的1~1000到了。——>可靠传输(确认应答就起到最核心作用)


在图一中,标志位ack为1表示它是应答报文,此时数据报中的"确认序号"字段就能生效。

2.超时重传

¹引入

上述确认应答是理想的状态,网络传输中可能会出现丢包或者网络延迟,TCP的超时重传可以保证可靠数据传输。当数据段丢失时,发送方通过超时重传机制,能够及时重新发送数据,确保接收方最终能够正确接收到数据。

💡为啥会出现丢包呢? 

 网络拥塞:数据流量超过网络链路的容量,过多的数据包同时竞争有限的带宽资源,导致一些数据包无法及时传输或被丢弃。缓冲区溢出:当接收方的缓冲区已满,无法及时处理接收到的数据包时,会导致数据包被丢弃。

了解:

Linux中超时以500ms为一个单位进行控制,每次判定超时重发的时间都是500ms的整数倍。重发一次还无应答就会以2*500在进行重传。仍得不到应答就等待4*500ms,...... ,指数递增。累计到一定程度TCP会认为网络对端主机有异常,强制关闭连接。


²丢包类型

在第一点确认应答情况下可能会出现两种类型的丢包:

1.传输的数据丢了

2.返回的ack丢了

这两种情况发送方是无法区分的,所以引入定时器。只不过这个定时器等待的时间会动态变化。如果时间等待的足够长,那就会触发TCP的重置连接操作。


³过程

当发送方向接收方发送数据时,会启动一个定时器,等待接收方对已发送数据的确认。如果在设定的超时时间内没有收到确认,发送方会认为数据丢失,并进行超时重传。

具体的超时重传过程如下:

  • 1. 发送方发送数据段,并启动定时器:发送方将数据段发送给接收方,同时启动一个定时器,等待确认。
  • 2. 接收方收到数据段并发送确认:接收方收到数据段后,会发送一个确认(ACK)给发送方,确认接收到了数据段。
  • 3. 发送方收到确认:发送方收到接收方的确认后,停止定时器,并继续发送下一个数据段(如果有)。
  • 4. 定时器超时:如果在设定的超时时间内,发送方没有收到接收方的确认,发送方认为数据丢失,gaolian:发送方重新发送未收到确认的数据段,并重新启动定时器,等待新的确认。

注意

TCP的超时重传机制可能会导致网络的拥塞,因为它会在丢包的情况下进行重传,增加了网络的负载。因此,TCP采用了一系列的拥塞控制算法来避免过多的重传造成网络拥塞。

如果因为超时重传,其实上接收方接收到两个数据,inputStream.read读取到两个一样的数据,那❌,会有严重的后果。eg:我去付款,结果因为重传,导致扣我两份的钱!!!

TCP的解决办法是:接收缓冲区,保存当前收到的数据以及序号,如果已经存在于接收缓冲区,接收方会进行去重。而且TCP还会进行重新排序,确保程序发送的顺序和应用程序读取的顺序一致。

(太厉害了,TCP设计人考虑好全面)

 3.连接管理

是对TCP可靠性的补充。TCP的连接管理包括三次握手和四次挥手,用于建立和关闭连接。建立连接是客户端发起,断开连接是客户端和服务器都可以主动发起。

三次握手(Three-Way Handshake)

  1. 第一次握手(SYN):客户端发送一个带有SYN标志的TCP报文段给服务器端,请求建立连接。此时客户端进入SYN_SENT状态。syn同步数据段,特殊的TCP数据包,没有载荷的(不携带业务数据,业务数据就是应用层数据包)当TCP组成中的六位标志位的syn为1表示它为同步报文段
  2. 第二次握手(SYN+ACK):服务器端收到客户端的SYN报文段后,发送一个带有SYN和ACK标志的TCP报文段作为响应,确认客户端请求,并提出自己请求建立连接。此时服务器端进入SYN_RECEIVED状态。都是内核触发的,同一时机可以合并。
  3. 第三次握手(ACK):客户端收到服务器端的SYN+ACK报文段后,向服务器端发送一个带有ACK标志的TCP报文段,确认连接建立。此时客户端和服务器端都进入已建立连接的ESTABLISHED状态。
  4. listen状态:服务其创建好socket,等待客户端连接;established建立连接完成;

 三次握手:

1.确定网络(通信路径)畅通;

2.确定接收方和发送方的发送能力接受能力正常;

3.双方对重要信息进行协商:比如序号,确认号,窗口大小

协商的数据也避免了前朝的剑斩本朝的官

syn确认了对方身份,ack保证了序列化

四次挥手(Four-Way Handshake):

  1. 第一次挥手(FIN):当客户端想要关闭连接时,内核发送一个带有FIN标志的TCP报文段给服务器端,表示不再发送数据。此时客户端进入FIN_WAIT_1状态。哪方主动断开哪方timewait,timewait存在的意义就是避免最后一个ack丢失,如果没有timewait状态,导致客户端直接closed,服务器发起两次 fin,甚至更多,就永远收不到ack了。so是为了处理重传的FIN,这边返回ack,fin才有意义。等待时间2msl
  2. 第二次挥手(ACK):服务器端收到客户端的FIN报文段后,发送一个带有ACK标志的TCP报文段作为确认。此时服务器端进入CLOSE_WAIT状态,而客户端进入FIN_WAIT_2状态。
  3. 第三次挥手(FIN):当服务器端也准备关闭连接时,应用程序发送一个带有FIN标志的TCP报文段给客户端(server在socket对象调用close方法发起fin/进程结束),表示不再发送数据。此时服务器端进入LAST_ACK状态。两次触发fin时机不同。具体相差时机看代码。如果close没写或者没执行到,第二个fin有可能发不出去。如果正常四次挥手,那就正常断开连接;否则异常流程断开连接。
  4. 第四次挥手(ACK):客户端收到服务器端的FIN报文段后,发送一个带有ACK标志的TCP报文段作为确认。此时客户端进入TIME_WAIT状态,服务器端收到确认后进入CLOSED状态。

通过三次握手,客户端和服务器端建立起可靠的连接。而通过四次挥手,双方完成数据传输后,优雅地关闭连接。这样可  以确保数据的可靠性和完整性,并释放连接使用的资源。

但是tcp的延时应答可以延时ack的时间,ack和fin就可能可以合并。 

4.滑动窗口(效率)

为了尽可能提高TCP传输的效率, 引入了滑动窗口机制。TCP滑动窗口(TCP sliding window)是用于流量控制和拥塞控制的一种机制。它表示发送方在不等待确认的情况下可以发送的数据量。在一定范围内窗口越大,传输效率越高。如果通信双方传输数据量大,比较频繁就会用到滑动窗口——快速重传

滑动窗口是通过TCP协议中的窗口字段来实现的。这个窗口字段指示了发送方当前可用的缓冲区大小,也就是可以发送的数据量。接收方通过发送确认报文来告知发送方它当前所能接收的数据量,即接窗口大小。

滑动窗口本质是降低了确认应答机制中等待ACK的时间..集体的措施就是:批量发送,批量接受

把多份等待时间合并成一份(不等待的批量发送数据,使用一份的等待时间来等待一组数据的多个ACK),把能不用等待就能直接发送的数据的最大的量,称为"滑动窗口的大小"
 

滑动窗口的机制使得发送方和接收方能够根据网络状况进行动态调整,以实现流量控制和拥塞控制。通过合理设置窗口大小,可以避免发送方发送过多的数据导致接收方无法及时处理,同时也可以防止网络拥塞的发生

操作系统内核为了维护这个滑动窗口,需要开辟 发送缓冲区 来记录当前还有哪些数据没有应答,只有确认应答过的数据,才能从缓冲区删掉。

丢包

1.ACK丢失

ACK丢失后,不需要做任何的处理,在之前讲给数据编序号时,序号的定义就是,表示从序号往前所有的数据都确认到达了.也就是当收到2001这个ACK时,代表是1~2000就都传输成功了,2001这个ACK涵盖了上一个1001的ACK的信息

2.数据

5.流量控制 

流量控制是一种干预发送窗口大小的机制,滑动窗口越大,传输效率越高,但是窗口也不能无限大,发送方的传输速率不能超过接收方的接受能力。否则可能出现接收方丢包还得重传,影响到TCP核心目的:可靠。窗口太大,完全不等待ACK,可靠性失去保障,一直重传会影响效率。

 n'n'h

流量控制就是根据接收方的处理能力协调发送方的发送速率  

 如何告诉发送方窗口大小呢?

当A给B发送一个数据后,将B的处理能力看作一个水池,B会计算剩余空间,将这个值通过ACK返回给发送方,A就根据这个值来确定发送速率,也就是窗口的大小

16位窗口字段,就是存放了窗口 大小信息(报文是ACK的时候,这个字段才有效),16位是否意味着窗口最大是64kb呢?其实不是这样,TCP为了扩大窗口,在选项部分引入了窗口扩展因子.如果窗口大小是64,扩展因子为2.那么64<<2=256kb.

滑动窗口大小是不固定的随着传输过程动态调整。

当窗口大小为0,就要停止发送,等待过程中,会给接收方定期发送窗口探测报文*(不携带任何业务数据),为了触发ack查询窗口大小
 

 TCP中有应用程序和系统内核。当数据到达接收方的系统内核中,tcp socket内部对象带有接收缓冲区,A——》B的数据,会先到达b的接收缓冲区,b的应用程序会调用read方法把数据从接收缓冲区读取出来,进一步处理,一旦被read就可以从接收缓冲区中删除了。

就像生产者消费者模型。

生产者a,消费者b,交易场所b的接受缓冲区,消费能力就是b的处理能力,具体去取决于b的应用程序的代码,接收方缓冲区的剩余空间越大,处理能力就越强。

6.拥塞控制

滑动窗口大小=MIN(流量控制和拥塞控制)。

流量控制考虑接收方的能力;拥塞控制考虑传输过程中中间节点的处理能力。

网络上有大量的计算机,也传输着大量的数据,网络状态被来就很拥堵,不清楚网络的状态情况下,发送大量的数据,就会引起严重后果,只要有一个节点达到处理能力的上限,就会影响到可靠传输。

TCP引入 慢启动 机制,先发少量的数据,摸清当前的网络拥堵状态,再决定按照多大的速度传输数据。(敌进我退,敌退我进,发送方不断调整窗口大小进行试验)。

慢启动只是初始比较慢,增长速度非常快

 

  • 拥塞的窗口:窗口大小,传播速度;传播伦次:当前TCP第一次发送数据。
  • 指数增长->线性增长,传输速度也越来越快,then丢包(网络拥塞),一旦出现丢包就把窗口缩小,重新进行前面的慢启动-指数-线性,并且根据当前丢包的窗口大小,重新指定线性增长阈值。
  • 少量丢包触发超时重传,大量的丢包触发拥塞控制。
    • 拥塞控制就是TCP尽可能将数据尽可能快的传给接收方,但避免速度太快造成网络拥塞造成丢包的折中方案。

7.延时应答

延时应答也是提升效率的机制。——>增大窗口大小

流量控制那块就是根据缓冲区剩余空间大小来决定发送速度即窗口大小,如果接收数据的主机立刻返回ACK应答,这时候返回的窗口可能比较小.如果收到数据之后,不是立即返回ACK,而是等待接收方消耗一些数据,剩余空间就更大了,返回的窗口就更大了。

sum:延时返回ack,给接收方更多时间,来读取缓冲区数据。缓冲区剩余空间越大,即窗口越大,网络吞吐量就越大,传输效率就越高。

但是延时应答也有限制

数量限制:每隔N个包就应答一次(一般取2)

时间限制:超过最大延迟时间就应答一次(一般200ms)
 

8.捎带应答 

用于在发送数据包时同时携带其它的信息。通常情况下,数据包中会包含应答ACK(Acknowledgement)信息,来确认之前已经接收到的数据包。而捎带应答则是利用这个ACK信息的空余空间,来携带其它信息。如三次挥手中第二次就携带了ack+syn(同步报文段),在一些高延迟、高丢包的网络环境中,捎带应答可能会导致额外的问题,如增加网络拥塞和降低网络吞吐量等。

9.面向字节流

在TCP连接中,数据被看作是一个连续的字节流,而不是被分割成独立的消息或数据包。

而UDP的接收缓冲区是一个接一个的数据报,这样应用程序读取时就知道那里到哪里是一个完整的数据。TCP面向字节流的特性意味着数据在发送端被分割成小的数据段,并在接收端重新组装。TCP协议负责将数据流切分为适合网络传输的数据段,并确保这些数据段按序到达接收端,并进行正确的重组

如果有多个应用层数据包同时被传输过去,就会出现粘包问题。接收缓冲区中的数据就以字节形式仅仅连接在一起,接收方的应用程序读取数据时就可以一次读1个,2个,......,N个,但是最终的目标是读取到完整的应用层数据包,问题:接收方的应用程序并不知道从哪到哪是一个完整的应用层数据包。

核心思路:定义好应用层协议,明确应用层数据包之间的边界。

1.引入分隔符;2.引入长度;在应用层协议的格式中常见的json,xml,protobuffer都明确了边界。


TCP粘包问题主要有两种情况:

  1. 粘包:多个数据包被接收方一次性接收到,形成了一个粘包。这种情况下,接收方需要额外的处理来正确地拆分和解析每个数据包。
  2. 拆包:一个数据包被拆分成多个片段发送,接收方需要根据片段的顺序和边界重新组装数据包。

造成TCP粘包问题的原因主要有以下几点:

  1. 发送端连续发送:如果发送端连续发送多个数据包而接收端没有及时读取,这些数据包就会被接收端一次性接收到,形成粘包。
  2. 缓冲区大小限制:TCP接收端的缓冲区大小有限,当接收端缓冲区无法容纳整个数据包时,数据包会被拆分成多个片段进行传输,从而产生拆包问题。
  3. 延迟确认机制:TCP的延迟确认机制可能会导致多个数据包被一起确认,从而产生粘包。

为了解决TCP粘包问题,可以采用以下方法:

  1. 显式消息边界:在传输的数据中加入消息边界标识,如特殊字符或长度字段,以便接收方可以准确地切分每个数据包。
  2. 消息长度字段:在发送数据时,将数据长度作为一个固定长度的字段添加到数据包中,以便接收方可以根据长度字段来正确解析每个数据包。
  3. 使用定长数据包:将发送的数据固定为固定长度的数据包,无论实际数据长度如何,都填充到固定长度,这样接收方可以按照固定长度来解析每个数据包。
  4. 清空缓冲区:接收端可以及时读取和处理数据,尽快清空接收缓冲区,减少粘包和拆包的可能性。

10.TCP异常情况 

传输过程中出现了不可抗力导致TCP异常

进程终止:进程终止会释放文件描述符,相当于调用socket.close(),触发FIN,进行四次挥手。和正常关闭没有什么区别。TCP的连接管理独立于进程而存在

机器重启/关机:触发强制终止进程,和进程终止的情况相同

机器掉电/断网: 来不及杀进程,来不及发送fin。接收端认为连接还在,一旦接收端有写入操作,接收端发现连接已经不在了,就会 进行reset(重置)。即使没有写入操作,TCP自己也内置了一个保活定时器(心跳包),会定期询问对方是否还在。如果对方不在,也会把连接释放。

A->B:

A:超时重传——连接重置——单方面断开;

B:心跳包——对方无响应——单方面释放连接;
 

TCP&UDP

  1. 连接性:

    • TCP是面向连接的协议,通过三次握手建立连接,确保通信双方能够可靠地传输数据,并进行连接的关闭。
    • UDP是无连接的协议,不需要事先建立连接,直接将数据包发送给目标地址。每个数据包都是独立的,没有顺序要求。
  2. 可靠性:

    • TCP提供可靠的数据传输,通过序列号、确认应答、超时重传等机制来确保数据的可靠性。如果数据包丢失或损坏,TCP会自动进行重传。
    • UDP不提供可靠性保证,数据包一旦发送出去就无法得知是否到达目标。它适用于对实时性要求较高的应用,如音频和视频流。
  3. 传输效率:

    • TCP通过流量控制、拥塞控制等机制来提供高效的传输服务。它可以自动调整发送速率和窗口大小,以适应网络的变化。
    • UDP没有流量控制和拥塞控制机制,发送端会尽可能快地将数据发送出去,适用于对实时性要求较高、容忍丢包的应用。
  4. 数据大小限制:

    • TCP将应用层数据按照最大传输单元(MTU)进行分段,可以传输任意大小的数据。TCP会确保数据的完整性和有序交付。
    • UDP每个数据包有固定的大小限制,最大长度为64KB。如果应用层数据超过了这个限制,需要进行分片和重组。
  5. 应用场景:

    • TCP适用于对数据可靠性和顺序性要求较高的应用,如网页浏览、文件传输、电子邮件等。
    • UDP适用于对实时性要求较高、如音频和视频流、在线游戏,局域网内部的主机之间的通信等。它在传输速度和实时性方面更加高效。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Git安装详细步骤

目录 1、双击安装包&#xff0c;点击NEXT​编辑 2、更改安装路径&#xff0c;点击NEXT 3、选择安装组件 4、选择开始菜单页 5、选择Git文件默认的编辑器 6、调整PATH环境 7、选择HTTPS后端传输 8、配置行尾符号转换 9、配置终端模拟器与Git Bash一起使用 10、配置额外…

内存管理(mmu)/内存分配原理/多级页表

1.为什么要做内存管理&#xff1f; 随着进程对内存需求的扩大&#xff0c;和同时调度的进程增加&#xff0c;内存是比较瓶颈的资源&#xff0c;如何更好的高效的利于存储资源是一个重要问题。 这个内存管理的需求也是慢慢发展而来&#xff0c;早期总线上的master是直接使用物…

【鸿蒙】大模型对话应用(一):大模型接口对接与调试

Demo介绍 本demo对接阿里云和百度的大模型API&#xff0c;实现一个简单的对话应用。 DecEco Studio版本&#xff1a;DevEco Studio 3.1.1 Release HarmonyOS API版本&#xff1a;API9 关键点&#xff1a;ArkTS、ArkUI、UIAbility、网络http请求、列表布局 官方接口文档 此…

玩转未来:Sui游戏峰会将于3月19日亮相GDC

Sui将在今年三月份的旧金山游戏开发者大会&#xff08;Game Developer Conference, GDC&#xff09;上推出其首个重大游戏活动&#xff0c;展示其为独立游戏到3A游戏提供动力&#xff0c;并为游戏开发人员开启吸引新玩家参与的能力。“Play Beyond&#xff1a;Sui游戏峰会”&am…

线程在操作系统以及java中的几种状态(源码分析)

操作系统中一般将线程划分为五种状态&#xff1a;新建、可运行&#xff08;就绪&#xff09;、运行、阻塞、终止 新建&#xff08;New&#xff09;&#xff1a;当一个线程被创建时&#xff0c;它处于新建状态。此时&#xff0c;线程对象已经创建&#xff0c;但还没有分配到CPU资…

element plus使用问题

文章目录 element plusvue.config.js注意1、有时候会报错 not a function2、使用 ElMessage 报错3、 element plus 版本过高4、警告Feature flag VUE_PROD_HYDRATION_MISMATCH_DETAILS is not explicitly defined.5、报错 ResizeObserver loop completed with undelivered noti…

网络基础---初识网络

前言 作者&#xff1a;小蜗牛向前冲 名言&#xff1a;我可以接受失败&#xff0c;但我不能接受放弃 如果觉的博主的文章还不错的话&#xff0c;还请点赞&#xff0c;收藏&#xff0c;关注&#x1f440;支持博主。如果发现有问题的地方欢迎❀大家在评论区指正 目录 一、局域网…

读取一个batch的图像并且显示出来

1读取一个batch用于训练 我们在训练模型的时候&#xff0c;除了观察图像的标签和尺寸&#xff0c;最好能读取一个batch的图像显示出来&#xff0c;观察原始图像和grountruth是否对应&#xff0c;如果正确才能正式开始后续的训练。 下面以一个皮肤病分割的数据集加以演示。 2…

保障接口安全的11个方法

一、参数校验 校验参数是否为空&#xff0c;有些接口中可能会包含多个参数&#xff0c;有些参数允许为空&#xff0c;有些参数不允许为空&#xff0c;需要对这些参数做校验&#xff0c;防止接口底层出现异常。校验参数类型&#xff0c;比如&#xff1a;age 是 int 类型的&…

对鸢尾花进行分类预测-----pycharm

项目说明 #项目&#xff1a; 对鸢尾花进行分类预测 #实例数量150个(3类各50个) #属性数量&#xff1a;4(数值型&#xff0c;数值型&#xff0c;帮助预测的属性和类) #特征&#xff1a;花萼长度&#xff0c;花萼宽度&#xff0c;花瓣长度&#xff0c;花瓣宽度 单位&#xff1…

HarmonyOS 鸿蒙组件启动规则(Stage模型)

组件启动规则&#xff08;Stage模型&#xff09; 启动组件是指一切启动或连接应用组件的行为&#xff1a; 启动UIAbility、ServiceExtensionAbility、DataShareExtensionAbility&#xff0c;如使用startAbility()、startServiceExtensionAbility()、startAbilityByCall()等相关…

FOC系列(五)----STM32F405RGT6控制板焊接与初步编写代码

声明&#xff1a;本人水平有限&#xff0c;博客可能存在部分错误的地方&#xff0c;请广大读者谅解并向本人反馈错误。    首先祝大家新年快乐&#xff0c;因为我也快放假了&#xff0c;驱动板只能是开学之后再去测试了&#xff0c;本篇博客应该是本专栏年前的最后一篇了 一…

【计网·湖科大·思科】实验三 总线型以太网的特性、集线器和交换机的区别、交换机的自学习算法

&#x1f57a;作者&#xff1a; 主页 我的专栏C语言从0到1探秘C数据结构从0到1探秘Linux &#x1f618;欢迎关注&#xff1a;&#x1f44d;点赞&#x1f64c;收藏✍️留言 &#x1f3c7;码字不易&#xff0c;你的&#x1f44d;点赞&#x1f64c;收藏❤️关注对我真的很重要&…

字符串相关的函数和内存块相关函数

&#x1d649;&#x1d65e;&#x1d658;&#x1d65a;!!&#x1f44f;&#x1f3fb;‧✧̣̥̇‧✦&#x1f44f;&#x1f3fb;‧✧̣̥̇‧✦ &#x1f44f;&#x1f3fb;‧✧̣̥̇:Solitary-walk ⸝⋆ ━━━┓ - 个性标签 - &#xff1a;来于“云”的“羽球人”。…

[学习笔记] ONNX 基础知识

1. ONNX 简介 1.1 什么是 ONNX 开放神经网络交换 ONNX&#xff08;Open Neural Network Exchange&#xff09;是一套表示深度神经网络模型的开放格式&#xff0c;由微软和 Facebook 于 2017 推出&#xff0c;然后迅速得到了各大厂商和框架的支持。通过短短几年的发展&#xf…

【JavaEE进阶】 #{}和${}

文章目录 &#x1f343;前言&#x1f333;#{}和${}使⽤&#x1f6a9;Interger类型的参数&#xff08;基础数据类型&#xff09;&#x1f388;使用#{}&#x1f388;使用${} &#x1f6a9;String类型的参数使用&#x1f388;#{}使用&#x1f388;${} &#x1f38d;#{}和${}区别&a…

林浩然与极限的“无穷”约会

林浩然与极限的“无穷”约会 Lin Haoran’s Encounter with the Mathematical “Infinity” 在数学王国里&#xff0c;有一位名叫林浩然的大侠&#xff0c;他的江湖就是高等数学的殿堂。而他要挑战的终极Boss&#xff0c;便是那个既神秘又顽皮的“极限”。 In the kingdom of …

《golang设计模式》第三部分·行为型模式-10-模板方法(Template Method)

文章目录 1. 概述1.1 角色1.2 类图 2. 代码示例2.1 设计2.2 代码2.3 类图 1. 概述 模板方法&#xff08;Template Method&#xff09;用来定义算法的框架&#xff0c;将算法中的可变步骤定义为抽象方法&#xff0c;指定子类实现或重写。 1.1 角色 AbstractClass&#xff08;…

字符串相关函数【超详细】(strcpy,strstr等string.h中的函数)

文章目录 strlen库中函数定义函数作用函数大概“工作”流程函数使用注意&#xff08;要求&#xff09;函数使用例举 strcpy库中函数定义函数作用函数使用注意&#xff08;要求&#xff09;函数大概“工作”流程函数使用例举 strcat库中函数定义函数作用函数使用注意&#xff08…

Go 的命令行解析 flag 包如何扩展新类型呢?

上篇文章 说到&#xff0c;除布尔类型 Flag&#xff0c;flag 支持的还有整型&#xff08;int、int64、uint、uint64&#xff09;、浮点型&#xff08;float64&#xff09;、字符串&#xff08;string&#xff09;和时长&#xff08;duration&#xff09;。 flag 内置支持能满足…
最新文章