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

TCP原理特性详解



文章目录

  • 可靠传输机制
    • 1.确认应答
    • 2.超时重传
    • 2.连接管理
      • 1.三次握手
      • 2.四次挥手
  • 传输效率
    • 1.滑动窗口
    • 2.流量控制
    • 3.拥塞控制
    • 4.延时应答
    • 5.捎带应答
  • 面向字节流
    • 粘包问题
  • TCP异常情况

可靠传输机制

可靠性:即发送方知道数据是发送成功了,还是失败了。

1.确认应答

确认应答是TCP实现可靠传输最为核心的机制。


image-20230917130839885

主机A给主机B发送消息,B收到之后返回一个应答报文(ACK),A收到应答报文后就知道第一条消息发送成功了,于是继续发第二条消息…

  • 确认应答:即应答报文,也称为ACK报文。

  • 序号:类似数据(11000)等,TCP是面向字节流的,这里的11000这类数字就是1~1000个字节,每个字节都编有序号。因为字节编有序号,所以避免了发送的数据乱序的问题, 。image-20230917132307680

    TCP字节序号是依次累加的,第一条数据字节序号11000,第二条数据就是10012000。由于这1000个字节都属于一个TCP报文,所以每个TCP数据报头只存当前数据的第一个序号,比如第二条数据的TCP报文里存1001,再根据 TCP报文长度,就知道这条数据是1001~2000。

  • 确认序号:每个确认应答都带有数字(确认应答1001),这类数字就是确认序号,而确认序号只有应答报文拥有,ACK标志位为1,表示为应答报文,ACK标志位为0,表示不是应答报文。确认序号表示成功收到哪些数据,下一条数据从哪里开始发。确认序号返回的是收到当前数据最后一个字节序号的下一个序号,列如:收到11000个字节数据,返回1001,表示1001之前的数据都收到了,于是下一条消息是从编号为1001的位置开始发,即10012000。

2.超时重传

丢包分为两种情况:一是发送数据丢了,二是返回的ACK丢了。为了解决丢包问题,TCP引入了超时重传机制,在丢包的情况下,重新发送一份相同的数据。如何判断丢包呢?TCP引入了一个时间阈值,发送方传输一个数据,在一个规定的时间内,如果未收到ACK,不管三七二十一,都表示为丢包了,进行重传。

数据丢包:主机A发送的数据丢包了,在隔了一定的时间后,未收到主机B发来的确认应答,则会再次传输1~1000的数据

image-20230917142544706

ACK丢包:可以发现主机B收到了两次1~1000这个数据,TCP会根据这种重复数据进行去重,利用TCP的接收缓冲区进行去重。这个缓冲区相当于一个阻塞队列,当主机B读到了主机A发送的数据,主机B把这个数据放入这个阻塞队列中,再根据数据的序号排序、去重,如果序号重复则丢弃后来的数据。

image-20230917142620454

超时重传可能会重传几次,当重传次数达到一定的次数时,TCP会尝试重连,如果重连失败则彻底断开连接。重传的时候,第一次重传时间和第二次时间间隔不一样,重传次数越多时间间隔越大。

2.连接管理

在正常情况下,TCP要经过三次握手建立连接,通过四次挥手断开连接,所谓连接本质上是通信双方互存储了对方的信息,管理则是描述了连接如何连接和断开。

1.三次握手

举一个比较形象的列子:A先发一条消息,B收到后并响应,同时B再发送一条消息给A,A收到后并响应。

image-20230918125239110

三次握手本质上是四次交互,我们形象的把每次通信比喻成一次握手。通信双方,各自要发送一个“建立连接”的请求并各自返回对方一个ACK应答报文。由于主机B的响应和发送新消息(好啊+确认哈…)这两次交互的时间非常近,于是就把这两次交互合并为一次,也就成了三次握手;并且这两次合并是必须的,因为每次通信都需要封装分用,两次封装分用肯定要比一次封装分用的成本高。

image-20230918125939408

问题:四次合成了三次,那么直接合成两次可以完成吗?

答:显然是不能的。当主机A发送了一条消息:明天一起吃饭?主机B响应并发送新消息:好啊,确认哈?一起吃饭,别放鸽子。此时,主机A知道了主机B同意明天一起吃饭,但是主机B并不完全确定主机A会不会放鸽子。那么明天A和B可能也就吃不成饭了,也就意味着主机A和主机B连接建立不了!

三次握手的意义:一是建立通信双方的认同,保存对方的信息,二是为了验证通信双方各自的发送和接收是否正常;三是在每次交互会夹带一些重要信息,来协商一些重要的参数。

image-20230919104650158

客户端主动给服务器发起的建立连接请求,称为“SYN”/同步报文段(synchronize),对应着TCP报文结构里的“SYN”,然后服务器进行响应返回“SYN+ACK”,说明这条交互既是同步报文段,又是确认应答报文段,最后客户端返回一个“ACK”应答报文。

  • TCP连接有11种状态,分别是:LISTEN、SYN_SENT、SYN_RECEIVED、ESTABLISHED、FIN_WAIT_1、FIN_WAIT_2、CLOSE_WAIT、CLOSING、LAST_ACK、TIME_WAIT和CLOSED。

    建立连接时的状态:

  • LISTEN:表示服务器端的某个SOCKET处于监听状态,可以接受客户端的连接;

  • SYN_SENT:表示在发送连接请求后等待匹配的连接请求;

  • SYN_RECEIVED:表示在收到和发送一个连接请求后等待对连接请求的确认;

  • ESTABLISHED:表示已经建立了连接,可以进行数据传输;上图中客户端和服务器都有这个状态。

  • CLOSED表示TCP连接已经关闭 。

2.四次挥手

挥手和握手一样都是形象的比喻。四次挥手也是通信双方各自对对方发送一个断开连接的请求,再各自发送一个响应。

问题:中间两次是否能合并?(到了+你呢?)

答:显然不行,三次握手的两次交互之所以可以合并是因为这两次交互是同一时机,这一操作是纯内核操作,是我们感受不到的,当服务器收到syn后会立即返回ack;而四次挥手则不同,这两次交互是不同时机,当主机A的应用程序执行到socket的close方法时会触发FIN结束报文段,服务器接收到FIN后,内核会立即返回ACK,FIN是人为发送的,而ACK是由系统内核控制的,当主机B的应用程序执行到socket的close方法时也会触发FIN,应用程序执行到close方法前可能要经过很多道其他的程序代码,于是和ACK的时机相隔太久,也就不能合并为一次交互。

image-20230919111434977

image-20230919112122092

断开连接时的状态:

  • CLOSE_WAIT:表示被动断开连接一方等待FIN报文;

  • TIME_WAIT:表示主动断开连接的一方收到了对方的FIN报文,但是还没有发送ACK报文;

    TIME_WAIT的意义:

  • TIME_WAIT状态站在客户端视角认为已经断开连接了,但是此时TIME_WAIT会让连接状态继续保留,因为最后一个ACK还没有发出去,如果最后一个ACK丢包,服务器会进行超时重传,重新传一个FIN,客户端再重新发一个ACK,因此TIME_WAIT状态保留连接状态一定时间,就是为了有能力进行重传,如果重传的还是丢了,时间也到了,那么就认定为最后ACK没丢,直接断开连接。

  • TIME_WAIT保留时间为2MSL;(Max Segment Life,报文最大生存时

    间)2MSL表示为互联网上,两个节点之间数据传输消耗的最大时间,这个时间通常为60s。

传输效率

1.滑动窗口

活动窗口的目的是为了在可靠性传输的基础上提高传输效率。

基础的确认应答机制:主机A发一次数据,主机B只要收到一条数据就返回一个ACK,而主机A此时在没有收到ACK的时候,需要进行等待,才能发送下一条数据,每一次发送数据都要等一次,这就造成了不少的等待时间。

image-20230920101558133

加入活动窗口后的确认应答机制主机A不再需要等待第一条数据的ACK,可以一次性发送多条数据,再使用一份等待时间来等待一组数据返回的多个ACK,这就减少了多条等待ACK的时间。

下图是主机A一次性批量发送四条数据,主机B再批量返回四个ACK,收到一条数据就返回一条ACK,依次类推,只是说主机A不需要等第一个ACK,就可以连续发4条数据。

image-20230920101730003

把不需要等待就可以发送的最大的数据量就称为:“窗口大小”;上图这个“窗口大小”为4000。

发送一个窗口大小的数据后,主机A并不是要等这一个窗口大小的ACK全部返回了,才继续发送下面的数据,而是主机B接收到一条数据就返回一条ACK,主机A收到一个ACK就发一条数据,这样就保证了等待的ACK永远都是4条(窗口大小,处理的数据永远都是4条,而不是处理一条就没事做了)。

举个例子:比如一个人有4台电脑一台电脑可以刷一门课,同时只能刷4门课,需要刷满10门课,此时“窗口大小”就是4。当我刷完一门课后,手上正在刷的课为3门,那么就有一台电脑是空闲状态,于是我就可以再找一门课继续刷,一直保持刷4门课的状态。相当于用1门课的时间刷了4门课,用最少的时间刷完10门。

每次刷完一门课,就立即开始下一门,窗口大小始终未变,但是课程变了。类似于下图,本来需要等10015000的ACK,但是收到了2001的ACK,说明2001之前的数据已经被确认,此时可以立即发送50016000的数据,等待的ACK范围就成了2001~6000,这种现象看起来就像是在滑窗口,于是就形象的比喻成滑动窗口

image-20230920104420332

  • 滑动窗口情况下,丢包了怎么解决?

    1. ACK丢了:不需要做出任何处理!因为有确认序号,当返回2001的ACK,说明2001之前的数据都到达了,2001包含了1~2000的数据序号。image-20230920105210223

    2. 数据包丢了:下图显示,当10012000的数据丢了,主机B返回的是1001的ACK,意思是索要主机A1001开头的数据,主机A连续发送多条数据后收到的依旧是1001的ACK,这时主机A就会发送10012000的数据。当主机B成功收到10012000的数据后,由于主机A之前已经发送20017000的数据,并且主机B成功收到了,于是这次返回的是7001的ACK,说明7001之前的数据都收到了(包含10012000的数据),也就意味着主机A下次发送的数据是从7001开始。假设,40015000也丢包了,此时是返回的ACK是5001,而不是7001,即使主机A已经把数据发送到了7000。总结:丢哪个包就索要哪个包的数据。

      这种重传方式称为“快速重传”,表示只重传丢失的数据。

2.流量控制

滑动窗口提高了传输效率,可是窗口也不能无限大,因为接收方处理能力有限。流量控制的意义是为了根据接收方的处理能力来控制发送方的传输效率。

那么如何衡量接收方的处理能力呢?

可以根据接收方的接收缓冲区剩余大小来判断,比如传输10个,接收缓冲区还剩下20个,说明下次可以传输20个,或者30个,接收方都能处理过来。

比如主机A给主机B发送了一条数据,B就算一下接收缓冲区剩余空间,再把这个结果通过ACK返回给A,A根据这个结果来决定下次发送的窗口大小是多少,是连续发10个还是20个。

TCP报文结构里有16位窗口大小,即默认为64kb,而TCP为了让窗口大小可以更大,在选项中引入了窗口大小的扩展因子,比如扩展因子里是2,表示64kb左移2位即256kb。

image-20230920121358460

上图显示:第一次A传输了11000的数据,B返回1001ACK,接收缓冲区剩余大小为3000,A再次发送10014000的数据,B依次返回三个ACK 当B的接收缓冲区为0了,A机会进行等待,在等待时间,A会发送一个窗口探测报文来询问B的接收缓冲区是否有空余。

3.拥塞控制

流量控制和拥塞控制共同决定发送方的窗口大小。

流量控制表示接收方的处理能力;

拥塞控制表示传输过程中的中间节点的处理能力(中间节点:路由器,运营商等)。

中间节点的测量:通过实验来测试出一个合适的值。比如先发少量的数据,探探路,摸清当前的网络拥堵状态,再决定按照多大的速度传输数据;

下图表示实验中间节点的窗口大小:第0轮。窗口大小为1,没有丢包就扩大窗口,第二次就为2…以指数增长;当增长速率达到阈值时,变成线性增长;当丢包了也就是遇到网路拥堵,窗口大小一下子变为一个很小的值,再重新按指数增长线性增长,此时的增长速率阈值为上次网路拥堵的值除2…依次类推,直到找到不是网络拥堵的瓶颈并且是一个最大的值 。拥塞窗口会根据当前网络环境一直动态的调整。

image-20230920122455931

4.延时应答

延时应答:收到数据后,不是立刻返回ACK,而是稍等再返回。

在滑动窗口上进行改进,比如主机A第一次发送数据,B的原本接收缓冲区大小为1M,B计算后立即返回的ACK窗口大小为500kb,那么下次A传输的数据就是500kb;但是如果要是稍等再返回ACK,在这个稍等的时间内主机B把这个500kb给消费掉,那么返回的窗口大小就为1M,下次A就可以发1M的数据,从而提高传输效率。

image-20230920174000401

上图显示,实际上延时应答采取的方式为在滑动窗口下,ACK不再每一条数据都返回,比如上图隔一条返回一个ACK。

5.捎带应答

在延迟应答的基础上,我们发现,很多情况下,客户端服务器在应用层也是 “一发一收” 的。意味着客户端给服务器说了 “How are you”,服务器也会给客户端回一个 “Fine, thank you”;因为TCP存在延时应答,ACK等了一会,那么这个时候ACK就可以搭顺风车,和服务器回应的 “Fine,thank you” 一起回给客户端

image-20230920175409229

由于内核返回的ACK存在延时应答,于是等待,这时候应用层发了一条数据刚好和延时应答后返回的ACK时机相同,于是这两次合并为一次。

image-20230920175439006

面向字节流

粘包问题

接收缓冲区实际上是把收到的数据都放在一起,由于TCP的字节流的,但是应用层序read读取时,可以一次read一个字节或多个字节,读到哪里才算是一个完整的应用层数据报呢?这就导致可能read读取到的是半个数据报或是多个数据报。就好比下图,假设下图都是主机B返回的数据,主机A,read读取时,一次读8个字节,读取到了:“abcdefgh”,这种情况就叫粘包问题

解决方案:在应用层约定每个数据报之间用什么分隔符区分,比如用“\n",或者约定每个数据报的长度。

image-20230920180330887

TCP异常情况

  1. 进程崩溃:进程终止会释放文件描述符,仍然会完成四次挥手。和正常关闭没有什么区别。

  2. 主机正常关机:和进程崩溃一样。

  3. 主机掉电/网线断开:

    • 接收方掉电:发送方接收不到ACK,超时重传几次,会尝试重置连接,最后彻底放弃连接。
    • 发送方掉电:接收方收取不到数据,于是会周期性的发送一个消息,确认对方是否正常工作,这种操作称为“心跳包”。通过“心跳包”来确认通信双方是否正常。
  4. 进程崩溃:进程终止会释放文件描述符,仍然会完成四次挥手。和正常关闭没有什么区别。

  5. 主机正常关机:和进程崩溃一样。

  6. 主机掉电/网线断开:

    • 接收方掉电:发送方接收不到ACK,超时重传几次,会尝试重置连接,最后彻底放弃连接。
    • 发送方掉电:接收方收取不到数据,于是会周期性的发送一个消息,确认对方是否正常工作,这种操作称为“心跳包”。通过“心跳包”来确认通信双方是否正常。

相关文章:

TCP原理特性详解

文章目录 可靠传输机制1.确认应答2.超时重传2.连接管理1.三次握手2.四次挥手 传输效率1.滑动窗口2.流量控制3.拥塞控制4.延时应答5.捎带应答 面向字节流粘包问题 TCP异常情况 可靠传输机制 可靠性:即发送方知道数据是发送成功了,还是失败了。 1.确认应答…...

什么是懒加载,JS如何实现懒加载,在php中如何去实现懒加载

懒加载(Lazy Loading)是一种前端优化技术,用于推迟加载页面中的某些资源(如图片、脚本、样式等),直到用户需要访问或者接近该资源时才进行加载。这可以减少初始页面加载时间,并提高页面性能和用…...

Cesium 展示——读取文件——加载 geojson 文件数据

文章目录 需求分析方法一:加载 geojson 文件方法二:加载 后台解析后的 geojson 文件结果需求 在做项目时,对加载 geojson 格式的数据有了一定的了解,因此试着尝试接手后台解析的 geojson 数据进行绘制,因此做了总结如下 分析 方法一:加载 geojson 文件 this.od6 = wi…...

(二)Apache log4net™ 手册 - 配置

0、引言 在上一篇文章中我们简单介绍了 Log4Net 及其核心的三大组件。本文将在上一篇文章的基础上继续探讨与 Log4Net 配置相关的内容。 1、配置 将日志请求插入到应用程序代码中需要进行大量的计划和工作。观察表明,大约4%的代码专门用于日志记录。因此&#xf…...

Elasticsearch:时间点 API

Elasticsearch:时间点 API-CSDN博客 在今天的文章中,我将着重介绍 Point in time API。在接下来的文章中,我将介绍如何运用 PIT 来对搜索结果进行分页。这也是被推荐使用的方法。 Point in time API 默认情况下,搜索请求针对目标…...

hive数据表定义

分隔符 CREATE TABLE emp( userid bigint, emp_name array<string>, emp_date map<string,date>, other_info struct<deptname:string, gender:string>) ROW FORMAT DELIMITED FIELDS TERMINATED BY \t COLLECTION ITEMS TERMINATED BY , MAP KEYS TERMINAT…...

OpenMesh 网格简化之顶点聚类

文章目录 一、简介二、实现代码三、实现效果参考资料一、简介 顶点聚类方法将落在给定大小体素中的所有顶点集中到单个顶点之上,其过程有点类似于点云体素下采样,之后再基于聚类之后的顶点重新连接面片,以达到网格简化的目的。 二、实现代码 #define _USE_MATH_DEFINES #in…...

C++ 类和对象篇(八) const成员函数和取地址运算符重载

目录 一、const成员函数 1. const成员函数是什么&#xff1f; 2. 为什么有const成员函数&#xff1f; 3. 什么时候需要使用const修饰成员函数&#xff1f; 二、取地址运算符重载 1. 为什么需要重载取地址运算符&#xff1f; 2. 默认取地址运算符重载函数 3. 默认const取地址运…...

k8s 集群安装(vagrant + virtualbox + CentOS8)

主机环境&#xff1a;windows 11 k8s版本&#xff1a;v1.25 dashboard版本&#xff1a;v2.7.0 calico版本&#xff1a; v3.26.1 CentOS8版本&#xff1a;4.18.0-348.7.1.el8_5.x86_64 用到的脚本&#xff1a; https://gitcode.net/sundongsdu/k8s_cluster 1. Vagrant创建…...

8、Docker数据卷与数据卷容器

一、数据卷(Data Volumes) 为了很好的实现数据保存和数据共享&#xff0c;Docker提出了Volume这个概念&#xff0c;简单的说就是绕过默认的联合文件系统&#xff0c;而以正常的文件或者目录的形式存在于宿主机上。又被称作数据卷。 数据卷 是一个可供一个或多个容器使用的特殊目…...

大数据与Hadoop入门理论

一、大数据的3种数据类型 1、结构化数据 可定义&#xff0c;有类型、格式、结构的强制约束 如&#xff1a;RDBMS&#xff08;关系型数据库管理系统&#xff09; 2、非结构化数据 没有规律没有数据约束可言&#xff0c;很复杂难以解析 如&#xff1a;文本文件&#xff0c;视…...

持续集成部署-k8s-深入了解 Pod:探针

持续集成部署-k8s-深入了解 Pod:探针 1. 探针分类2. 探针探测方式3. 探针参数配置4. 启动探针的应用5. Liveness 探针的应用6. Readiness 探针的应用1. 探针分类 Kubernetes 中的探针是指容器内的进程用于告知 Kubernetes 组件其自身状态的机制; Readiness Probe:就绪探针用…...

来单提醒/客户催单 ----苍穹外卖day9

来单提醒 需求分析 代码开发 注意:前端请求的并不是8080端口;而是先请求Nginx,Nginx进行反向代理以后转发到8080端口 这段代码首先创建了一个orders类用于更新订单状态 并且在更新状态后使用websocket发送给后端提醒 将信息放在map后,使用json的string化方式传给一个接收对象,…...

【单片机】18-红外线遥控

一、红外遥控背景知识 1.人机界面 &#xff08;1&#xff09;当面操作&#xff1a;按键&#xff0c;旋转/触摸按键&#xff0c;触摸屏 &#xff08;2&#xff09;遥控操作&#xff1a;红外遥控&#xff0c;433M/2.4G无线通信【穿墙能力强】&#xff0c;蓝牙-WIFI-Zigbee-LoRa等…...

【Node.js】module 模块化

认识 node.js Node.js 是一个独立的 JavaScript 运行环境&#xff0c;能独立执行 JS 代码&#xff0c;可以用来编写服务器后端的应用程序。基于Chrome V8 引擎封装&#xff0c;但是没有 DOM 和 BOM。Node.js 没有图形化界面。node -v 检查是否安装成功。node index.js 执行该文…...

Vue中如何进行分布式日志收集与日志分析(如ELK Stack)

在Vue中实现分布式日志收集与日志分析&#xff08;使用ELK Stack&#xff09; 日志收集和分析在现代应用程序中是至关重要的&#xff0c;它们可以帮助开发人员监视和诊断应用程序的行为&#xff0c;从而提高应用程序的稳定性和性能。ELK Stack&#xff08;Elasticsearch、Logs…...

java学习--day23(线程池)

1.线程池Pool 线程池一个容纳了多个线程的容器&#xff0c;其中的线程可以反复的使用。省去了频繁创建线程的对象的操作&#xff0c;无需反复创建线程而消耗更多的资源 在 Java 语言中&#xff0c;并发编程都是通过创建线程池来实现的&#xff0c;而线程池的创建方式也有很多种…...

Unity Golang教程-Shader编写一个流动的云效果

创建目录 一个友好的项目&#xff0c;项目目录结构是很重要的。我们先导入一个登录界面模型资源。 我们先创建Art表示是美术类的资源&#xff0c;资源是模型创建Model文件夹&#xff0c;由于是在登录界面所以创建Login文件夹&#xff0c;下面依次是模型对应的资源&#xff0c…...

Python数据攻略-Pandas与地理空间数据分析

地理空间数据分析已经成为数据分析不可或缺的一部分。无论是在城市规划、交通分析,还是在环境科学中,地理空间数据都发挥着关键作用。 本文将为初学者和新手提供一个详细的指南,通过使用Python的Pandas库和Geopandas库,来进行地理空间数据分析。 文章目录 用Pandas处理地理…...

sourceTree无法启动

前几天win10系统自动更新后&#xff0c;sourceTree就无法打开了&#xff0c;双击只是图标闪一下&#xff0c;电脑重启后还是无法打开。找到了网上几种方法进行尝试&#xff1a; 方法一&#xff1a;修改配置信息 在自己的电脑路径下&#xff1a; C:\Users\你的用户名\AppData…...

YSYX学习记录(八)

C语言&#xff0c;练习0&#xff1a; 先创建一个文件夹&#xff0c;我用的是物理机&#xff1a; 安装build-essential 练习1&#xff1a; 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件&#xff0c;随机修改或删除一部分&#xff0c;之后…...

Angular微前端架构:Module Federation + ngx-build-plus (Webpack)

以下是一个完整的 Angular 微前端示例&#xff0c;其中使用的是 Module Federation 和 npx-build-plus 实现了主应用&#xff08;Shell&#xff09;与子应用&#xff08;Remote&#xff09;的集成。 &#x1f6e0;️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...

GitHub 趋势日报 (2025年06月06日)

&#x1f4ca; 由 TrendForge 系统生成 | &#x1f310; https://trendforge.devlive.org/ &#x1f310; 本日报中的项目描述已自动翻译为中文 &#x1f4c8; 今日获星趋势图 今日获星趋势图 590 cognee 551 onlook 399 project-based-learning 348 build-your-own-x 320 ne…...

抽象类和接口(全)

一、抽象类 1.概念&#xff1a;如果⼀个类中没有包含⾜够的信息来描绘⼀个具体的对象&#xff0c;这样的类就是抽象类。 像是没有实际⼯作的⽅法,我们可以把它设计成⼀个抽象⽅法&#xff0c;包含抽象⽅法的类我们称为抽象类。 2.语法 在Java中&#xff0c;⼀个类如果被 abs…...

系统掌握PyTorch:图解张量、Autograd、DataLoader、nn.Module与实战模型

本文较长&#xff0c;建议点赞收藏&#xff0c;以免遗失。更多AI大模型应用开发学习视频及资料&#xff0c;尽在聚客AI学院。 本文通过代码驱动的方式&#xff0c;系统讲解PyTorch核心概念和实战技巧&#xff0c;涵盖张量操作、自动微分、数据加载、模型构建和训练全流程&#…...

【堆垛策略】设计方法

堆垛策略的设计是积木堆叠系统的核心&#xff0c;直接影响堆叠的稳定性、效率和容错能力。以下是分层次的堆垛策略设计方法&#xff0c;涵盖基础规则、优化算法和容错机制&#xff1a; 1. 基础堆垛规则 (1) 物理稳定性优先 重心原则&#xff1a; 大尺寸/重量积木在下&#xf…...

自然语言处理——文本分类

文本分类 传统机器学习方法文本表示向量空间模型 特征选择文档频率互信息信息增益&#xff08;IG&#xff09; 分类器设计贝叶斯理论&#xff1a;线性判别函数 文本分类性能评估P-R曲线ROC曲线 将文本文档或句子分类为预定义的类或类别&#xff0c; 有单标签多类别文本分类和多…...

React从基础入门到高级实战:React 实战项目 - 项目五:微前端与模块化架构

React 实战项目&#xff1a;微前端与模块化架构 欢迎来到 React 开发教程专栏 的第 30 篇&#xff01;在前 29 篇文章中&#xff0c;我们从 React 的基础概念逐步深入到高级技巧&#xff0c;涵盖了组件设计、状态管理、路由配置、性能优化和企业级应用等核心内容。这一次&…...

用递归算法解锁「子集」问题 —— LeetCode 78题解析

文章目录 一、题目介绍二、递归思路详解&#xff1a;从决策树开始理解三、解法一&#xff1a;二叉决策树 DFS四、解法二&#xff1a;组合式回溯写法&#xff08;推荐&#xff09;五、解法对比 递归算法是编程中一种非常强大且常见的思想&#xff0c;它能够优雅地解决很多复杂的…...

用 Rust 重写 Linux 内核模块实战:迈向安全内核的新篇章

用 Rust 重写 Linux 内核模块实战&#xff1a;迈向安全内核的新篇章 ​​摘要&#xff1a;​​ 操作系统内核的安全性、稳定性至关重要。传统 Linux 内核模块开发长期依赖于 C 语言&#xff0c;受限于 C 语言本身的内存安全和并发安全问题&#xff0c;开发复杂模块极易引入难以…...