读书笔记《网络是怎样连接的》
目录
- 第一章
- 1.1 生成http请求消息
- 输入网址URL
- 解析URL
- URL中省略文件名的情况
- http的基本思路
- 生成HTTP请求消息
- 发送请求后收到响应
- 1.2 向DNS服务器查询Web服务器的IP地址
- IP地址的基本知识
- 域名和IP地址并用的理由
- Socket库提供查询IP地址的功能
- 通过解析器向 DNS 服务器发出查询
- 解析器的内部原理
- 1.3 全世界DNS服务器的大接力
- DNS服务器的基本工作
- 域名的层次结构
- 寻找相应的DNS服务器并获取IP地址
- 通过缓存加快DNS服务器的响应
- 1.4 委托协议栈发送消息
- 数据收发操作概览
- 创建套接字阶段 连接阶段:把管道接上去 通信阶段:传递消息
- 第二章 用电信号传输TCP/IP数据 ----探索协议栈和网卡
- 2.1 创建套接字
- 协议栈的内部结构
- 套接字的实体就是通信控制信息
- 调用socket时的操作
- 2.2 连接服务器
- 连接是什么意思
- 负责保存控制信息的头部
- 连接操作的实际过程
- 2.3 收发数据
- 将HTTP请求消息交给协议栈
- 对较大的数据进行拆分
- 使用ACK号确认网络包已收到
- 根据网络包平均往返时间调整ACK号等待事件
- 使用窗口有效管理ACK号
- ack与窗口的合并
- 接收HTTP响应消息
- 2.4 从服务器断开并删除套接字
- 数据发送完毕后断开连接
- 删除套接字
- 数据收发操作小结
第一章更新完,,,,,持续更新Ing
第一章
1.1 生成http请求消息
输入网址URL
URL:Uniform Resource Locator,统一资源定位符。并不总是以http:开头, 还可以以“ftp:”“file:”
“mailto:”等开头。浏览器是一个具备多种客户端功能的综合性客户端软件,因此它需要
一些东西来判断应该使用其中哪种功能来访问相应的数据,而各种不同的 URL 就是用来干这个的,比如访问 Web 服务器时用“http:”,而访问 FTP 服务器时用“ftp:”。
FTP:File Transfer Protocol,文件传送协议。这是一种在上传、下载文件
时使用的协议。使用 FTP 协议来传送文件的程序也被叫作 FTP。
HTTP:Hypertext Transfer Protocol,超文本传送协议。
解析URL
URL中省略文件名的情况
省略了文件名,使用默认的文件名,例如index.html
访问了根目录,省略了文件名
省略了根目录和文件名
根据服务器中whatisthis是文件名还是文件夹,来进行理解
http的基本思路
首先,客户端会向服务器发送请求消息(图 1.4)。请求消息中包含的内容是**“对什么”和“进行怎样的操作”**两个部分。(其实还有一些头字段的附加信息)
对什么:这一部分称为URI(Uniform Resource Identifier,统一资源标识符)。URI 的内容是一个存放网页数据的文件名或者是一个 CGI 程序的文件名,例如“/dir1/file1.html” “/dir1/program1.cgi”等。不过,URI 不仅限于此,也可以直接使用“http:” 开头的 URL来作为 URI。
进行怎样的操作:“进行怎样的操作”的部分称为方法。方法表示需要让Web 服务器完成怎样的工作,常见的方法就是get, post, 还有一些其他方法见下表。
**响应消息:**收到请求消息之后,Web 服务器会对其中的内容进行解析,通过 URI和方法来判断“对什么”“进行怎样的操作”,并根据这些要求来完成自己的工作,然后将结果存放在响应消息中。在响应消息的开头有一个状态码,它用来表示操作的执行结果是成功还是发生了错误。
生成HTTP请求消息
消息体: 消息的主体。
发送请求后收到响应
响应消息的格式以及基本思路和请求消息是相同的,差别只在第一行上。在响应消息中,第一行的内容为状态码和响应短语,用来表示请求的执行结果是成功还是出错。状态码和响应短语表示的内容一致,但它们的用途不同。状态码是一个数字,它主要用来向程序告知执行的结果;相对地,响应短语则是一段文字,用来向人们告知执行的结果。
由于每条请求消息中只能写 1 个 URI,所以每次只能获取 1 个文件,如果需要获取多个文件,必须对每个文件单独发送 1 条请求。比如 1 个网页中包含 3 张图片,那么获取网页加上获取图片,一共需要向 Web 服务器发送 4 条请求。
1.2 向DNS服务器查询Web服务器的IP地址
IP地址的基本知识
尽管浏览器能够解析网址并生成 HTTP 消息,但它本身并不具备将消息发送到网络中的功能,因此这一功能需要委托操作系统来实现。发送消息的功能对于所有的应用程序来说都是通用的,因此让操作系统来实现这一功能,其他应用程序委托操作系统来进行操作,这是一个比较合理的做法。
在委托操作系统发送消息时,必须要提供的不是通信对象的域名,而是它的 IP 地址。因此,在生成HTTP 消息之后,下一个步骤就是根据域名查询 IP 地址。
这个科普视频实在是太棒了!!只要几分钟!!b站:【什么是集线器,交换机,路由器和猫?】
IP地址: 在网络中,所有的设备都会被分配一个地址。这个地址就相当于现实中某条路上的**“×× 号 ×× 室”。其中“号”对应的号码是分配给整个子网的,而“室”对应的号码是分配给子网中的计算机的**,这就是网络中的地址。“号”对应的号码称为网络号,“室”对应的号码称为主机号,这个地址的整体称为 IP 地址。通过 IP 地址我们可以判断出访问对象服务器的位置,从而将消息发送到服务器。
实际的IP地址:实际的 IP 地址是一串 32 比特的数字,按照 8 比特(1 字节)为一组分成 4 组,分别用十进制表示 然后再用圆点隔开。在 IP 地址的规则中,网络号和主机号连起来总共是 32 比特,但这两部分的具体结构是不固定的。在组建网络时,用户可以自行决定它们之间的分配关系,因此,我们还需要另外的附加信息来表示 IP 地址的内部结构。
子网掩码:子网掩码的格式如图 1.10 ②所示,是一串与 IP 地址长度相同的 32 比特数字,其左边一半都是 1,右边一半都是0。其中,子网掩码为 1 的部分表示网络号,子网掩码为 0 的部分表示主机
号。可以以点分十进制形式表示(下图b),也可以把1的部分的比特数用十进制表示并写在IP地址的右侧(下图c).
域名和IP地址并用的理由
为什么不直接用ip,ip不方便记忆,所以就用相对好记忆的域名。那为什么不直接用域名来确定对应的通信对象,ip只有四字节,域名则几十个甚至255个字节而且长度也不固定,效率低。
于是,现在我们使用的方案是让人来使用名称,让路由器来使用 IP 地址。为了填补两者之间的障碍,需要有一个机制能够通过名称来查询 IP 地址,或者通过 IP 地址来查询名称,这样就能够在人和机器双方都不做出牺牲的前提下完美地解决问题。这个机制就是 DNS。
Socket库提供查询IP地址的功能
库:就是一堆通用程序组件的集合,其他的应用程序都需要使用其中的组件。
Socket 库:也是一种库,其中包含的程序组件可以让其他的应用程序调用操作系统的网络功能 。
DNS解析器:对于 DNS 服务器,我们的计算机上一定有相应的 DNS 客户端,而相当于 DNS 客户端的部分称为 DNS 解析器,或者简称解析器。解析器就是这个库中的其中一种程序组件。
通过解析器向 DNS 服务器发出查询
Socket 库中的程序都是标准组件,只要从应用程序中进行调用就可以了。具体来说,在编写浏览器等应用程序的时候,只要像图 1.11 这样写上解析器的程序名称“gethostbyname”以及 Web 服务器的域名“www.lab.glasscom.com”就可以了,这样就完成了对解析器的调用
调用解析器后,解析器会向 DNS 服务器发送查询消息,然后 DNS 服务器会返回响应消息。响应消息中包含查询到的 IP 地址,解析器会取出 IP地址,并将其写入浏览器指定的内存地址中。
解析器的内部原理
发送消息这个操作并不是由解析器自身来执行,而是要委托给操作系统内部的协议栈来执行。这是因为和浏览器一样,解析器本身也不具备使用网络收发数据的功能。解析器调用协议栈后,控制流程会再次转移,协议栈会执行发送消息的操作,然后通过网卡将消息发送给 DNS 服务器。
顺带一提,向 DNS 服务器发送消息时,我们当然也需要知道 DNS 服务器的 IP 地址。只不过这个 IP 地址是作为 TCP/IP 的一个设置项目事先设置好的,不需要再去查询了。可以在电脑的设置中查看。
1.3 全世界DNS服务器的大接力
DNS服务器的基本工作
来自客户端的查询消息包含以下 3 种信息。域名,class(最早设计的时候,不只是考虑了互联网,还考虑了别的网,后来只用于互联网 class=IN表示互联网),记录类型(表示域名对应何种类型的记录, 当类型为A:address时,表示域名对应的是IP地址,类型为MX时,表示对应的是邮件服务器)
对于邮件服务器,先通过@后的内容查出完整的域名(第二行)再通过完整的域名查出IP(第三行)
域名的层次结构
互联网中存在着不计其数的服务器,一台DNS服务器不够存,所以将信息分布在多台DNS服务器中。
一个域不可能存在多个DNS服务器中, 一个DNS服务器可以存放多个域。
DNS 服务器中的所有信息都是按照域名以分层次的结构来保存的。层次结构这个词听起来可能有点不容易懂,其实就类似于公司中的事业集团、部门、科室这样的结构。
DNS 中的域名都是用句点来分隔的,比如 www.lab.glasscom.com,这里的句点代表了不同层次之间的界限,就相当于公司里面的组织结构不用部、科之类的名称来划分,只是用句点来分隔而已。在域名中,越靠右的位置表示其层级越高,比如 www.lab.glasscom.com 这个域名如果按照公司里的组织结构来说,大概就是“com 事业集团 glasscom 部 lab 科的 www”这样。其中,相当于一个层级的部分称为域。因此,com 域的下一层是glasscom 域,再下一层是 lab 域,再下面才是 www 这个名字。
寻找相应的DNS服务器并获取IP地址
为了方便讨论,假设一个服务器只存储一个域。如何组织多个dns服务器, 最顶级的域名并不是cn, jp最顶级的是.这个点代表根域名。任何一个dns服务器中存着根域服务器对应的ip(共有13个ip,不代表共有13个根域服务器),所以可以轻松的找到根域服务器.。根域服务器当中存着下一级的域名所在的服务器的ip, 于是可以找到下一级服务器,依次类推,很快就可以找到最终的Ip, 将这个Ip返回给客户端。
通过缓存加快DNS服务器的响应
有时候并不需要从最上级的根域开始查找,因为 DNS 服务器有一个缓存功能,可以记住之前查询过的域名。如果要查询的域名和相关信息已经在缓存中,那么就可以直接返回响应,接下来的查询可以从缓存的位置开始向下进行。相比每次都从根域找起来说,缓存可以减少查询所需的时间。
息被缓存后,原本的注册信息可能会发生改变,这时缓存中的信息就有可能是不正确的。因此,DNS 服务器中保存的信息都设置有一个有效期,当缓存中的信息超过有效期后,数据就会从缓存中删除。而且,在对查询进行响应时,DNS 服务器也会告知客户端这一响应的结果是来自缓存中还是来自负责管理该域名的 DNS 服务器。
1.4 委托协议栈发送消息
数据收发操作概览
要发送给 Web 服务器的 HTTP 消息是一种数字信息(digital data),因此也可以说是委托协议栈来发送数字信息。
收发数据的两台计算机之间连接了一条数据通道,数据沿着这条通道流动,最终到达目的地。我们可以把数据通道想象成一条管道,将数据从一端送入管道,数据就会到达管道的另一端然后被取出。
这个管道
- 并不真实存在,只是为了方便理解
- 双向的
- 不是一直存在,发数据开始的时候要建立管道,收发结束后管道会断开
管道是如何建立的呢?关键在于管道两端的数据出入口,这些出入口称为套接字。
服务器程序一般会在启动后就创建好套接字并等待客户端连接管道。
这 4 个操作都是由操作系统中的协议栈来执行的,浏览器等应用程序并不会自己去做连接管道、放入数据这些工作,而是委托协议栈来代劳。本章将要介绍的只是这个“委托”的操作。关于协议栈收到委托之后具体是如何连接管道和放入数据的,我们将在第 2 章介绍。
创建套接字阶段 连接阶段:把管道接上去 通信阶段:传递消息
如下图,① 客户端创建套接字,可能有多个应用所以可能同时存在多个套接字,需要用不同描述符加以区分。
② 委托协议栈将客户端创建的套接字与服务器那边的套接字**连接起来。**三个参数,用哪个套接字;发给哪个ip; 端口号;
端口号: 光凭ip只能定位到一个电脑或者说服务器(实际上一个电脑可能有多个ip, 因为ip实际上是分给是被中安装的网络硬件的,因此如果一台设备中安装了多个硬件,就有多个Ip), 但是不能确定具体是哪个应用程序,也就是说服务器里有多个套接字出口, 不知道从哪个口出来。所以需要端口号,确定从哪个口出去,也就是连接到服务器端的哪个套接字。 不可以直接用套接字描述符,因为双方并不知道彼此的套接字。
那么端口号到底应该是多少呢?服务器上所使用的端口号是根据应用的种类事先规定好的,仅此而已。比如 Web 是 80 号端口,电子邮件是 25 号端口。关于端口号,我们将在第 6 章探索服务器内部工作的时候进行介绍,这里大家只要这样记住就行了:只要指定了事先规定好的端口号,就可以连接到相应的服务器 程序的套接字。
当连接成功后,协议栈会将对方的 IP 地址和端口号等信息保存在套接字中,这样我们就可以开始收发数据了
③ 发送和接收:
发:生成的 HTTP 请求消息就是我们要发送的数据。接下来,当调用 write 时,需要指定描述符和发送数据,然后协议栈就会将数据发送到服务器。
收:调用read 时需要指定用于存放接收到的响应消息的内存地址,这一内存地址称为接收缓冲区。于是,当服务器返回响应消息时,read 就会负责将接收到的响应消息存放到接收缓冲区中。
④ 断开阶段:收发数据结束
Web 使用的 HTTP 协议规定,当 Web 服务器发送完响应消息之后,应该主动执行断开操作,因此 Web 服务器会首先调用close 来断开连接。断开操作传达到客户端之后,客户端的套接字也会进入断开阶段。接下来,当浏览器调用 read 执行接收数据操作时,read 会告知浏览器收发数据操作已结束,连接已经断开。浏览器得知后,也会调用close 进入断开阶段。
第二章 用电信号传输TCP/IP数据 ----探索协议栈和网卡
本章我们将探索操作系统中的**网络控制软件(协议栈)和网络硬件(网卡)**是如何将浏览器的消息发送给服务器的。
2.1 创建套接字
协议栈的内部结构
协议栈的上半部分有两块,分别是负责用 TCP 协议收发数据的部分和负责用 UDP 协议收发数据的部分,它们会接受应用程序的委托执行收发数据的操作。
下面一半是用 IP 协议控制网络包收发操作的部分。在互联网上传送数据时,数据会被切分成一个一个的网络包 而将网络包发送给通信对象的 操作就是由 IP 来负责的。此外,IP 中还包括 ICMP 协议和 ARP协议。 ICMP 用于告知网络包传送过程中产生的错误以及各种控制消息,ARP 用 于根据 IP 地址查询相应的以太网 MAC 地址。
套接字的实体就是通信控制信息
本来套接字就只是一个概念而已,并不存在实体,如果一定要赋予它一个实体,我们可以说这些控制信息(例如通信对象的 IP 地址、端口号、通信操作的进行状态等。这些控制信息存储在协议栈内部)就是套接字的实体。
套接字中记录了用于控制通信操作的各种控制信息,协议栈则需要根据这些信息判断下一步的行动,这就是套接字的作用。
使用cmd命令可以查看当前套接字,命令为netstat -ano
调用socket时的操作
①协议栈首先会分配用于存放一个套接字所需的内存空间。用于记录套接字控制信息的内存空间并不是一开始就存在的,因此我们先要开辟出这样一块空间来,这相当于为控制信息准备一个容器。但光一个容器并没有什么用,还需要往里面存入控制信息。套接字刚刚创建时,数据收发操作还没有开始,因此需要在套接字的内存空间中写入表示这一初始状态的控制信息。到这里,创建套接字的操作就完成了。
2.2 连接服务器
连接是什么意思
实际上网线一直都连接着。 这里的连接实际上是指 通信双方交换控制信息,在套接字中记录这些必要信息并准备数据收发的一连串操作。
1.客户端的套接字不知道和谁通信,端口号是多少,浏览器知道这些,应该告诉套接字
2. 服务器的套接字不知道谁要和他通信,服务器的应用程序也不知道。所以需要客户端告诉服务器
负责保存控制信息的头部
控制信息有两类如下。
连接操作的实际过程
2.3 收发数据
将HTTP请求消息交给协议栈
对较大的数据进行拆分
以MSS长度为单位进行拆分
使用ACK号确认网络包已收到
简单来说,发送方说的是“现在发送的是从第 ×× 字节开始的部分,一共有 ×× 字节哦!”而接收方则回复说,“到第 ×× 字节之前的数据我已经都收到了哦!”这个返回 ACK 号的操 作被称为确认响应,通过这样的方式,发送方就能够确认对方到底收到 了多少数据。
实际通信中,为了避免被攻击,序号不是从1开始,而是随机的。这个随机的初始值再将SYN=1发送给服务器的时候,也同时设置并发送了序号字段的值。
通信是双向的,因此在开始的时候双方需要在连接过程中互相告知自己计算的序号初始值。
明白原理之后我们来看一下实际的工作过程(图 2.9)。首先,客户端
在连接时需要计算出与从客户端到服务器方向通信相关的序号初始值,并
将这个值发送给服务器(图 2.9 ①)。接下来,服务器会通过这个初始值计
算出 ACK 号并返回给客户端(图 2.9 ②)。初始值有可能在通信过程中丢
失,因此当服务器收到初始值后需要返回 ACK 号作为确认。同时,服务
器也需要计算出与从服务器到客户端方向通信相关的序号初始值,并将这
个值发送给客户端(图 2.9 ②)。接下来像刚才一样,客户端也需要根据服
务器发来的初始值计算出 ACK 号并返回给服务器(图 2.9 ③)。
数据收发操作本身是可以双向同时进行的,但 Web 中是先由客户端向服务器
发送请求,序号也会跟随数据一起发送(图 2.9 ④)。然后,服务器收到数
据后再返回 ACK 号(图 2.9 ⑤)。从服务器向客户端发送数据的过程则正好
相反(图 2.9 ⑥⑦)
TCP 采用这样的方式确认对方是否收到了数据,在得到对方确认之前,发送过的包都会保存在发送缓冲区中。如果对方没有返回某些包对应的 ACK 号,那么就重新发送这些包。
我们可以确认接收方有没有收到某个包,如果没有收到则重新发送,这样一来,无论网络中发生任何错误,我们都可以发现并采取补救措施(重传网络包)。反过来说,有了这一机 制,我们就不需要在其他地方对错误进行补救了。
如果发生网络中断、服务器宕机等问题,那么无论 TCP 怎样重传都不管用。这种情况下,无论如何尝试都是徒劳,因此 TCP 会在尝试几次重传无效之后强制结束通信,并向应用程序报错。
根据网络包平均往返时间调整ACK号等待事件
网络繁忙的时候会发生拥堵,这个时候ack返回的比较慢,如果设置的等待时间短,可能导致重传数据后,才接收到ack. 相反如果设置的太长,那么真正需要重传的情况又要等很久。
所以不同的环境,ack等待时间的设置波动很大,因此tcp采用了动态调整法,这个等待时间是根据ack号返回的实时速度来调整的。
使用窗口有效管理ACK号
等待ack的时候什么都不做很浪费时间,所以tcp采用滑动窗口的方式来管理数据发送和ack号的操作。
但如果不等返回 ACK 号就连续发送包,就有可能会出现发送包的频率超过接收方处理能力的情况。因此接收方也有一个缓冲区(接收方缓冲区的大小也称为窗口大小,只一个有名的tcp调优参数),但是缓冲区也可能满了溢出,所以最开始的时候,接收方就需要告诉发送方自己最多能接受多少数据,然后发送方根据这个数值对数据发送的快慢进行控制。
ack与窗口的合并
更新窗口大小的时机应该是接收方从缓冲区中取出数据传递给 应用程序的时候。
发送ack的时机接收到包后。
但是这样会导致一个发送的数据包要返回两条信息。要是能合并就好了。实际上接收方在发送这两条信息的时候并不会马上发,而是等待一段时间,将等待过程中得到的通知打成一个包发出去。当有多个ack的时候,只需要发送最后一个,中间的可以全部省略。同理,多个窗口更新也是,只需要发送最后一个即可。
接收HTTP响应消息
和发送数据一样,接收数据也需要将数据暂存到接收缓冲区中,这里的操作过程如下。首先,协议栈尝试从接收缓冲区中取出数据并传递给应用程序,但这个时候请求消息刚刚发送出去,响应消息可能还没返回。响应消息的返回还需要等待一段时间,因此这时接收缓冲区中并没有数据,那么接收数据的操作也就无法继续。这时,协议栈会将应用程序的委托,也就是从接收缓冲区中取出数据并传递给应用程序的工作暂时挂起,等服务器返回的响应消息到达之后再继续执行接收操作。
2.4 从服务器断开并删除套接字
数据发送完毕后断开连接
收发数据结束的时间点应该是应用程序判断所有数据都已经发送完毕的时候。这时,数据发送完毕的一方会发起断开过程,但不同的应用程序会选择不同的断开时机。协议栈允许任何一方先发起断开。
无论哪种情况,完成数据发送的一方会发起断开过程,这里我们以服
务器一方发起断开过程为例来进行讲解。首先,服务器一方的应用程序会
调用 Socket 库的 close 程序。然后,服务器的协议栈会生成包含断开信息
的 TCP 头部,具体来说就是将控制位中的 FIN 比特设为 1。接下来,协议
栈会委托 IP 模块向客户端发送数据(图 2.12 ①)。同时,服务器的套接字
中也会记录下断开操作的相关信息。
上述过程为服务器发起断开:
①②结束后,表示数据传输完,客户端就会让应用程序来读取数据。
③④客户端收到服务器返回的所有数据后,客户端就会调用close来结束数据收发操作。
删除套接字
和服务器的通信结束之后,用来通信的套接字也就不会再使用了,这时我们就可以删除这个套接字了。不过,套接字并不会立即被删除,而是会等待一段时间之后再被删除。避免误操作:比如说上图2.12的过程④丢失了,客户端就会再次发一个FIN给服务器,而这个时候服务器的套接字已经被删除就会导致原先的端口号空出来可能给别的新建的套接字了,而这个新建的套接字就收到了FIN,就停止了别人的程序。
至于具体等待多长时间,这和包重传的操作方式有关。网络包丢失之后会进行重传,这个操作通常要持续几分钟。如果重传了几分钟之后依然无效,则停止重传。在这段时间内,网络中可能存在重传的包,也就有可能发生前面讲到的这种误操作,因此需要等待到重传完全结束。
数据收发操作小结
相关文章:

读书笔记《网络是怎样连接的》
目录 第一章1.1 生成http请求消息输入网址URL解析URLURL中省略文件名的情况http的基本思路生成HTTP请求消息发送请求后收到响应 1.2 向DNS服务器查询Web服务器的IP地址IP地址的基本知识域名和IP地址并用的理由Socket库提供查询IP地址的功能通过解析器向 DNS 服务器发出查询解析…...

Java 设计模式一
Java 设计模式是软件开发中的一类解决方案,旨在解决常见的设计问题,提升代码的可维护性、可复用性和扩展性。它们通常基于一些经验和最佳实践,提供了解决问题的标准化方法。以下是常见的 Java 设计模式及其概述: 1. 创建型模式 (…...

SOME/IP服务接口
本系列文章将分享我在学习 SOME/IP 过程中积累的一些感悟,并结合 SOME/IP 的理论知识进行讲解。主要内容是对相关知识的梳理,并结合实际代码展示 SOME/IP 的使用,旨在自我复习并与大家交流。文中引用了一些例图,但由于未能找到原作…...

Java 生成 PDF 文档 如此简单
嘿,朋友!在 Java 里实现 PDF 文档生成那可真是个挺有意思的事儿,今儿个就来好好唠唠这个。咱有不少好用的库可以选择,下面就给你详细讲讲其中两个超实用的库,一个是 iText,另一个是 Apache PDFBox。 用 iTe…...

深入探究 YOLOv5:从优势到模型导出全方位解析
一、引言 在计算机视觉领域,目标检测是一项至关重要的任务,它在自动驾驶、安防监控、工业检测等众多领域都有着广泛的应用。而 YOLO(You Only Look Once)系列作为目标检测算法中的佼佼者,一直备受关注。其中ÿ…...

【PoCL】运行 LLVM 中 pass 优化过程详解
PoCL 项目中调用 LLVM 的 Pass 对编译过程的优化至关重要。本博文以PoCL 开源项目源码为例,详细说明【PoCL】运行 LLVM 中 pass 优化过程 目录 0. 个人简介 && 授权须知1. pocl_llvm_run_pocl_passes 函数作用2. 禁止 “小网格 small grid” 工作组(workGroup)特化的…...

如何将使用unsloth微调的模型部署到ollama?
目录 一、将模型保存为gguf格式 二、下载llama.cpp 三、生成 llama-quantize 可执行文件 四、使用llama-quantize 五、训练模型 六、将模型部署到ollama 一、将模型保存为gguf格式 在你的训练代码 trainer.train() 之后添加: model.save_pretrained_gguf(&q…...

【测试】UI自动化测试
长期更新,建议关注收藏点赞! 目录 概论WEB环境搭建Selenium APPAppium 概论 使用工具和代码执行用例。 什么样的项目需要自动化? 需要回归测试、自动化的功能模块需求变更不频繁、项目周期长(功能测试时长:UI自动化测…...

SSM开发(二) MyBatis两种SQL配置方式及其对比
目录 一、MyBatis两种SQL配置方式 二、使用XML映射文件配置SQL语句 三、使用注解配置SQL语句 四、两种方式对比 总结 1、注解 2、XML配置 五、MyBatis多数据源的两种配置方式 参考 一、MyBatis两种SQL配置方式 MyBatis 提供了两种方式来配置SQL语句:注解&a…...

【Redis】在ubuntu上安装Redis
文章目录 提权搜索软件包安装修改配置文件ip保护模式配置密码 重新启动服务器使用 redis 自带的客户端来连接服务器 提权 先切换到 root 用户,su 命令切换到 root. 搜索软件包 使用 apt 命令来搜索 redis 相关的软件包 apt search redis 安装 使用 apt 命令安装 redisapt …...

JS-Web API -day06
一、正则表达式 正则表达式测试工具: http://tool.oschina.net/regex 1.1 正则表达式介绍与语法 正则表达式: 正则表达式(Regular Expression)是用于匹配字符串中字符组合的模式。在 JavaScript中,正则表达式也是对象。通常用来查…...

JS-Web API -day03
一、事件流 1.1 事件流与两个阶段说明 事件流 指的是事件完整执行过程中的流动路径 假设页面有个div标签,当触发事件时,会经历两个阶段,分别是捕获阶段、冒泡阶段 捕获阶段:Document - Element html - Elementbody - Element div…...

进程优先级
基本概念 cpu资源分配的先后顺序,就是指进程的优先权(priority)。 优先权⾼的进程有优先执⾏权利。配置进程优先权对多任务环境的linux很有⽤,可以改善系统性能;还可以把进程运⾏到指定的CPU上,这样⼀来&…...

c语言(转义字符)
前言: 内容: 然后记一下转义字符 \? 在书写连续多个问号时使用,防止他们被解析成三字母词 \ 用于表示字符常量 \\ 用于表示一个反斜杠,防止他被解析为一个转义序列符 \n 换行 \r …...

easyexcel读取写入excel easyexceldemo
1.新建springboot项目 2.添加pom依赖 <name>excel</name> <description>excelspringboot例子</description><parent> <groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId&…...

【人工智能数学基础篇】——深入详解矩阵分解:奇异值分解(SVD)与主成分分析(PCA)在数据降维与特征提取中的应用
目录 1. 引言 2. 矩阵分解概述 2.1 矩阵分解的意义 3. 奇异值分解(SVD) 3.1 定义与数学基础 3.2 SVD 的性质 3.3 SVD 在数据降维中的应用 3.4 示例代码:使用 SVD 进行图像压缩 3.5 结果分析 4. 主成分分析(PCA࿰…...

ThreeJS示例教程200+【目录】
Three.js 是一个强大的 JavaScript 库,旨在简化在网页上创建和展示3D图形的过程。它基于 WebGL 技术,但提供了比直接使用 WebGL 更易于使用的API,使得开发者无需深入了解 WebGL 的复杂细节就能创建出高质量的3D内容。 由于目前内容还不多,下面的内容暂时做一个占位。 文章目…...

DC-DC稳压电源——实战(基于Ti5450芯片)基础知识篇(1)
一:基础知识-耦合 1)去耦电容 (1)耦合与去耦 耦合:系统内部的各个部分之间存在相互依赖、相互影响、相互制约的情况。用人话说就是不同部分之间的相互影响。 去耦:自然就是消除不同部分之间的影响了。 &…...

pyrender 渲染mesh
目录 render_meshes函数 调用函数 render_meshes函数 def overlay_human_meshes(humans, K, model, img_pil, unique_colorFalse):# Color of humans seen in the image._color [color[0] for _ in range(len(humans))] if unique_color else color# Get focal and princpt …...

防火墙安全策略
目录 一.拓扑信息 二.需求分析 三.命令行详细配置信息 1.配置IP 2.交换机配置 3.修改安全区域 4.安全策略 四.web界面详细配置 1.配置IP和设置安全区域 2.交换机配置 3.安全策略 五.测试 一.拓扑信息 二.需求分析 1.VLAN 2属于办公区域;VLAN 3属于生…...

selenium clear()方法清除文本框内容
在使用Selenium进行Web自动化测试时,清除文本框内容是一个常见的需求。这可以通过多种方式实现,取决于你使用的是哪种编程语言(如Python、Java等)以及你的具体需求。以下是一些常见的方法: 1. 使用clear()方法 clear…...

(回溯分割)leetcode93 复原IP地址
#include<iostream> #include<vector> #include<string> #include<algorithm> using namespace std; //卡尔的图不是按照程序执行过程而是直接画程序会执行的过程 // 实际执行是:n个字符,递推n1后(叶子节点ÿ…...

高性能队列 Disruptor 在 IM 系统中的实战
高性能队列 Disruptor 在 IM 系统中的实战 前三期我们介绍了Disruptor的典型使用场景和相关高性能原理,本期我介绍一下Disruptor在IM系统用的应用实战,IM系统即社交聊天系统,对实时性的要求非常高,非常符合Disruptor的使用场景。 …...

原生HTML集合
一、表格 1、固定表格 <div class"tablebox"><div class"table-container"><table id"myTable" border"0" cellspacing"0" cellpadding"0"><thead><tr></tr></thead>…...

ES6 简单练习笔记--变量申明
一、ES5 变量定义 1.在全局作用域中 this 其实就是window对象 <script>console.log(window this) </script>输出结果: true 2.在全局作用域中用var定义一个变量其实就相当于在window上定义了一个属性 例如: var name "孙悟空" 其实就相当于执行了 win…...

2025.1.21——六、BUU XSS COURSE 1
题目来源:buuctf BUU XSS COURSE 1 一、打开靶机,整理信息 有吐槽和登陆两个尝试点,题目名称提示是XSS漏洞 XSS(Cross-Site Scripting)漏洞 1.定义:跨站脚本攻击,是一种常见的 Web 安全漏洞。攻…...

Linux - 五种常见I/O模型
I/O操作 (输入/输出操作, Input/Output) 是指计算机与外部设备就行数据交互的过程. 什么是外部设备: 如键盘, 鼠标, 硬盘, 网卡等. 五种常见的 I/O 模型: 阻塞 I/O非阻塞 I/O信号驱动 I/OI/O 多路复用异步 I/O 阻塞 I/O 阻塞 I/O 的特点: 当用户发起 I/O 请求后, 进程/线程就…...

【负载均衡式在线OJ】加载题目信息(文件版)
目录 如何读取文件 -- 常见流程 代码 如何读取文件 -- 常见流程 在C中使用 std::ifstream来打开文件流是一个常见的操作,用于创建一个输入文件流,并尝试打开名为 question_list的文件。if (!in.is_open()):检查文件是否成功打开。如果文件未…...

“上门按摩” 小程序开发项目:基于 SOP 的全流程管理
在竞争激烈的生活服务市场,“上门按摩” 服务需求日益增长。为满足这一需求,我们启动了 O2O 模式的 “上门按摩” 小程序开发项目,该项目涵盖客户端、系统管理端、技师端。以下将通过各类 SOP 对项目进行全面管理,确保项目顺利推进。 一、项目启动 SOP:5W2H 分析法 What(…...

WPF1-从最简单的xaml开始
1. 最简单的WPF应用 1.1. App.config1.2. App.xaml 和 App.xaml.cs1.3. MainWindow.xaml 和 MainWindow.xaml.cs 2. 正式开始分析 2.1. 声明即定义2.2. 命名空间 2.2.1. xaml的Property和Attribute2.2.2. xaml中命名空间2.2.3. partial关键字 学习WPF,肯定要先学…...