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

【JavaEE初阶】第六节.网络原理TCP/IP协议

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

前言

一、TCP/IP协议五层协议栈;

1.1 应用层协议;

二、传输层协议;

2.1 UDP协议;

2.2 TCP协议;

          2.2.3 序号

2.3 UDP和TCP协议传输的区别;

2.4 超时重传;

2.5 连接管理(面试中最高频的问题.网络知识中,最最高频的考题,没有之一!!!)

2.5.1 建立连接(“三次握手”)

2.5.2 断开连接(“四次挥手”)

2.5.3 三次握手;四次挥手总结;

2.6 滑动窗口

2.7 流量控制

2.8 拥塞控制

2.9流量控制和拥塞控制的联系;

2.10 延时应答;

2.11 捎带应答

2.22 面向字节流

2.23 TCP连接出现异常时,如何处理?

总结


前言

本节内容我们将介绍有关TCP与IP的有关协议,介绍了其中最重要的几个知识点;

比如三次四次挥手,滑动窗口,流量控制等等;


提示:以下是本篇文章正文内容,下面案例可供参考

一、TCP/IP协议五层协议栈;

1.1 应用层协议;

1)介绍:

咱们自己编写的应用程序,就是在应用层;

(也是实际开发中最常打交道的)

虽然应用层里面有一些现成的协议. 但是咱们在工作中少不了一个重要的事情, 自定义应用层协议

自定义应用层协议相当于发明协议;

协议就是约定,约定好客户端和服务器;按照啥样的格式来传输数据;

2)应用层协议是如何约定的?

举例说明:(回显服务器)

约定了:每个请求,都是以\n结尾;每个响应,也都是\n结尾.

scanner.next();这是一个非常简单的约定;

3)自定义应用层协议,需要从两个方面入手:

1.考虑清楚,交互过程要传递的信息有哪些;

举例说明:

点外卖的案例;

比如我们现在需要在美团上面点一个外卖;

1)启动程序,涉及到网络交互.(交互中涉及到哪些信息的传递,和需求又是密切相关!)

请求:需要用户的身份信息,位置信息;

响应:商家的信息(商家名称,商家的评分,商家的位置,商家的预览图)

2)  点击某个商家,涉及到网络交互.

请求:用户信息,点击的商家信息;

响应:该商家的详细情况(有哪些外卖可以点,每个菜都是多少钱,评价如何,销量多少,预览图,分类信息)

2.考虑清楚,这些信息组织格式;

方式一:

直接使用简单分隔符来对不同部分的信息做区分;

注意:使用的;以及\n都是可以灵活的替换成其他符号的;

方式二:

使用固定长度来区分是从哪里到哪里的一个信息;

方式三:

 上述的两种风格,还可以混搭.

有些字段使用固定长度,有些字段使用分割符;

上述格式,比较的简单粗暴;

除此之外,还有一些业界更通用的数据约定的格式~~但是格式就要更复杂些了;

方式四:

通过XML的格式来约定数据;

 方式五:

 

 方式六:

总结:

咱们应用层协议数据格式,有很多种可以参考的方式!!!

在实际开发中,就要根据实际的情况来决定使用哪种更合适;

应用程不仅仅是可以写代码自定义协议,也有一些现成的协议,可以直接使用的.

其中最著名的就是HTTP协议 (后面的课程再介绍)

二、传输层协议;

2.1 UDP协议;

1)UDP协议端格式:

实际情况的格式: 

 1.源端口号和目的端口号;

使用的是ip地址;主要用来区分当前是哪个主机;

一个主机上可能有多个应用程序,使用端口号来区分应用程序;

eg:送快递的话;

源端口号就是发件人电话;目的端口号就是收件人电话;

2.UDP长度;

一个UDP数据报最长就是64KB; 

为啥不把UDP协议升级更新下?把长度用更大的字节(4字节, 8字节)

原因:

UDP已经内置到各个操作系统内核中了;发布到全世界无数的主机中了.

要想进行升级,就得要求全世界的主机的操作系统都统一升级到这个新版本的UDP才行.

万一有一部分没升级.... UDP就无法工作了.

务必要考虑到升级带来的影响!!很多的升级操作,都要考虑到"兼容性";

3.UDP效验和;
1)作用:
接收方,收到了数据之后,就得验证下,看看当前的数据是否是正确的!!

因为网络传输中,传输的数据,不一定是准确无误的!!!

本质上是光信号/电信号;使用不同频率的光信号,表示1-0,使用不同电平的电信号,表示1-0;

干扰就可能造成"比特反转";

2)举实例说明:

比如生活中买电脑台式机(组装的);

就需要选配置;买之前就需要确定每个硬件的配置单;

电脑商家把电脑组装好了,发给你的时候,会带着配置单一起再发给你.

拿着这个配置单,来检查看这里的每个部分都是是否匹配;所以这里的配置单就起到了效验的效果;

3)使用流程:

UDP传输数据,网络上的数据是可能收到干扰;

发送的时候,针对要传输的数据,计算一 个"校验和”(相当于配置单);

发送的时候,把数据连带校验和一起发送过去;

接收的时候,针对收到的数据重新计算校验和,对比一下自己计算的校验和和发来的校验和是否是一样的;

如果是一样的,就说明数据没啥问题;不一样数据就有问题的;

效验和的注意点:

校验和,不仅仅是在UDP这里,很多别的地方也会涉及到;

只要是数据传输可能出现问题,都可以使用校验和的思想;

2.2 TCP协议;

1)特点:

1.有连接;2.可靠传输;3.面向字节流;4.全双工;

2)可靠传输:

可靠传输,是TCP最核心的部分. TCP内部的很多机制,都是在保证可靠传输;

(1)概念:

传输了数据之后,对方收没收到,我心里清楚;

而不是说,发出去之后,对方100%能收到!!毕竟极端情况,网线断了.

(2)可靠性是如何保证的:

通过确认应答的操作;

举实例说明:

比如汤老师约女神去吃饭;

当我收到这个应答的报文的时候,就知道了对方一定是收到了!! 

如果我没收到,估计是不是对方没看到,或者短信发丢了(十几年前经常见到的);

情况1:

 但是在网络上存在后发先至的问题;

 所以说在后发先至的背景下,不能通过顺序;

来判断当前应答报文是在应答哪个数据;

解决上述问题的方法,我们可以通过编号来解决;

总结:

TCP在解决可靠性传输的时候;核心机制是确认应答;

确认应答需要通过序号进行控制;需要通过序号来知道我们当前应答的报文是在应答哪一条;

2.2.3 序号

1) 图示说明:

由于TCP是面向字节流的,编号的时候,也不是说按照"条"的方式遍的,而是按照字节来编;

举例说明:

现在有两台主机A,B,他们之间进行链接;

1.这一口气,发了1000个字节的数据;

TCP报头中的序号是1,整个报文长度是1000;

2.应答报文中的确认序号,就是1001 ;

应答报文,可以视为只有TCP报头,没有载荷;

在这个报头里,确认序号字段,填写了1001 .意思就是<1001的数据,B已经收到了.接下来A要从1001开始往后发送!!!

3.4类似1.2;

如何区分,一个报文是普通的报文,还是应答报文呢?

TCP报头;

 在TCP报头中,有六个非常重要的bit位.其中第二位,ACK就表示是否是应答报文;

ACK为О表示不是应答报文ACK为1表示是应答报文;也把应答报文称为ACK报文;(ACK就是acknowledge)

2.3 UDP和TCP协议传输的区别;

1.UDP协议传输

 B这边调用recv方法;每次调用recv就是从接收缓冲区里取走一个数据;在应用层写代码的时候,感知到的事情;

第一次调用,读取出来的一定是1111;

第二次调用,读取出来的一定是2222;

第三次调用,读取出来的一定是3333;

UDP的接收缓冲区,相当于一个链表,里面有三个节点.每次读,都得以节点为单位;

2.TCP传输协议

InputStream. read(buffer)

byte[1] buffer读出来的就是1;

byte[3] buffer读出来的就是111;

byte[5] buffer读出来的就是11112;

byte[7] buffer读出来的就是1111222;

TCP 的接收缓冲区,更像是一个数组.若千个TCP 数据报的载荷会一直追加到这个数组里,彼此之间融为一体;

总结:

面向字节流和面向数据报,主要是在影响代码是咋写(影响着应用层)!!!

而在传输层自身这里;仍然是一个一个报文的方式来传输的.

(传输了报文,不意味着"面向数据报",两个不同的概念)

2.4 超时重传;

1) 超时重传的原因;

在确认应答的情况下,如果收到了ACK,就好办.如果没收到呢??还需要通过其他途径来处理!!

此时我们就会用到超时重传的方法;

不是说没收到ACK,立即就放弃;而是需要重新再发一遍;

网络的环境是非常复杂的.尤其是有些时候,网络会拥堵;拥堵就可能导致丢包

丢包:丢包,是"无差别"丢的.

任何一个数据报,都有可能会丢包!!

发的普通的报文,可能丢;发的ACK也是可能丢的!

2)丢包的分类情况:

(1)业务数据丢了:

发送方等待一定的时间之后,没有收到ACK就会重传数据; 

                                                                                                                                                                                                     

(2) ACK丢了:

 业务数据已经到了主机B了!!反馈的ACK没有回过去;

 发送方等待一会之后,就触发了重传;这个情况下,B收到了两份1-1000这个数据!!!

所以说此时,如果在应用层调用read,读出来的是1份数据好,还是读出两份一样的数据好? 

肯定希望读出一份数据好,节省内存空间;

此时,接收方(B)会根据序号,来进行数据去重;

B知道自己都收到了哪些数据.当发现又收到了一份之前的数据,就会自动丢弃,保证应用层读到的数据是不重复的!!!

总结

对于发送方来说,无法区分是业务数据丢了,还是ACK丢了.

因此发送方能做的只是,达到一定时间之后,就重传!!!!!!

3):超时重传机制下,发一个数据丢包了;重传数据,是否还会再丢包呢?

当然是可能的;

但是站在概率的角度来看,就比如假设一次传输数据,丢包概率是10%(已经是一个很大的数字了)

A->B发一次数据,丢包的概率10% .A->B连续发两次都丢包的概率10%* 10%=> 1%;

丢包操作,还有一个超时时间.

超时时间具体是多少,在操作系统内核是可以配置的;

eg:

第一次传输丢包,超时时间是t1‘;

第二次又丢包,超时时间是t2;

t2 > t1;这里的等待时间间隔,随着时间的推移,要越来越大;

如果连续两次都没发过去,意味着当前单次发送的丢包概率已经相当大了!!

连续重传之后又丢包的次数越多,此时意味着单次发送的丢包概率就更大;很可能是网络上遇到了非常严重的故障,短期内恢复不了.多次发送也没什么用了;

 注意:

超时重传也不会无限制的重传下去.尝试几次之后,仍然无法传输过去,此时就会放弃尝试,然后就只能断开连接尝试重连.如果重连也还是连不上,就彻底放弃了;

2.5 连接管理(面试中最高频的问题.网络知识中,最最高频的考题,没有之一!!!)

 TCP是有连接的协议;需要建立连接和断开连接;

2.5.1 建立连接(“三次握手”)

"三次握手"主动的那一方是客户端.三次握手,一定是客户端先发起的!!

1) “三次握手”的流程;

图示举例说明:

 经历了这四次交互,就完成了建立连接的过程;

两对操作:客户端和服务器,互相给对方发送了一个SYN,再互相给对方发送了一个ACK;

一共是四次交互,完成了这个过程;

为啥还是叫做"三次握手"???因为中间的两次可以合并成一次!!

原因:

每次数据报文传输,都要经过一系列的封装分用!!分成两个包来发,就比一个包,代价大很多!!

eg:两个单,商家合并成一个快递给我发过来;成本低!!!运费只需要付一份就行了!!

注意:

三次握手的时候,B返回的ACK和SYN都是内核收到A的SYN之后,立即返回!!!

2)为什么要“三次握手”??

三次握手,认为是一种保证可靠性的机制!!这个东西相当于“投石问路";

在正式通信之前,先确定好通信链路是否畅通!!!如果通信链路不畅通,后续大概率要丢包!!

eg:地铁/高铁.......一早上第一趟车,都是空车先跑一遍~~(投石问路)

但是为啥三次握手要握三次呢?四次行不行?(行,但是没必要,因为效率低)两次行不行?铁定不行的!!

三次握手也是在验证通信双方的发送能力和接收能力是否正常!!!

举实例说明:

3)三次握手的重要意义;

能够让通信双方协商一些重要的参数!!

eg:

两个人商量;比如,像序号要从几开始(实际上,一次连接中的序号不一定是从1开始的).包括MSS ;

举例说明:

总结三次握手的意义;

1.投石问路,验证通信双方发送/接收能力是否正常;

2.协商重要参数;

2.5.2 断开连接(“四次挥手”

四次挥手:断开连接的流程;

三次握手,客户端主动发起第一次.

四次挥手,客户端和服务器都可以主动;

1)四次挥手的流程:

图示举例说明:

 和三次握手不同,四次挥手,看起来也是双方各自给对方发送FIN各自给对方发送ACK;

但是这里是四次挥手!!中间两次,不一定能合并!!

不能合并的原因:

B返回ACK是内核的行为.操作系统内核收到FIN之后,就会立即返回ACK.而接下来B的FIN是用户代码的行为.用户在代码中调用socket.close方法,才会触发FIN !!!

因此,B发送FIN和发送ACK之间会有不可忽视的时间间隔!!正因为有时间间隔了,就不能合并!!

TCP还有一个机制,延时应答和捎带应答.(后面再讲)

2.5.3 三次握手;四次挥手总结;

举实例说明:

如果把建立连接,理解成入职;

B这边,属于没工作的状态,A抛出橄榄枝了,B立即就同意了.

断开连接,就是离职;

A通知B,你被解雇了,你自己提交一个辞职报告吧; B是有一些工作交接的;

所以说:

TC建立连接,是没有历史包袱的.立即就能完成;

断开连接.很可能A=>B发FIN的时候,B还有数据没读完.B一般不会立即断开,要把未处理的数据都处理完了再说;B啥时候发FIN就是代码层次的了.


2.6 滑动窗口

1)作用:

提高传输效率的机制;

2)本质:

就是把等待ACK的时间重叠起来.

减少等待时间,就相当于提高了效率!!

注意:

可靠性和效率是冲突的!!保证可靠性肯定会影响到效率的!!

TCP在可靠性的前提下,尽可能的提高效率;

3)图示说明其功能的体现:

之前:

每次传输,都需要等待ACK,收到ACK再发下一条数据;

                                                                                                                                                                                                       

使用滑动窗口之后:

不再是一次发送一条,等待一条;而是一次发送一批,等待一批ACK;

                                                                                                                                                                                                       

 在不等待的前提下,最多可以一次发N条数据;(N指的是窗口大小)

这里的N越大,则同时批量发的数据,就越多,传输效率就越高;

但是N也不是越大越好;传输效率=发送效率&接收效率

3)扩展:

 每一小块都是一个TCP数据报;

 白色的区域,当前已经批量的发送了:

 ??????????????????????????????????

4)在滑动窗口之下,可靠性是否有影响呢?

确认应答,还是正常应答,没啥影响;

5)超时重传,有影响嘛?在滑动窗口下,丢包了,该咋办?

丢包的情况分为两种:

1.数据报丢了;

2.ACK丢了;

(1)情况1:数据报抵达;ACK丢了;

 如果1001丢了,2001到了;

此时对于A来说,就知道1-1000这个数据也是到了的!!!后一个会涵盖前一个;

(2)情况2:数据包直接丢了;

主机A发了半天之后,看到了连续好几个1001,就明白了,怕是1001丢了!!!!!

接下来,A就会重传1001这个数据了!!!!!

此处的原则是,哪条丢了,就重传哪条;

已经传输到的数据,不必重复传输;

快速重传:不是说重传的有多快,而是没有冗余的动作;

举实例说明:

注意误区:

说,滑动窗口能提高效率,指的是相比于没有滑动窗口的普通的确认应答;

但是如果和无可靠性的传输相比(UDP),效率还是要差一些的!!

说它是提高效率,不如说是在补救低效率.

2.7 流量控制

1)概念:

滑动窗口,窗口大小越大,发送速率就越快!!

而流量控制就是限制滑动窗口的重要机制!!

流量控制,就是在针对发送速率进行制约;

整体的传输速率=发送速率&接收速率;

如果发送速率>接收速率;这个时候继续提高发送速率,不能够提高整体的效率了!!!

反而会因为接收方丢包,触发更多的重传,反而还降低了速率;

2)

现在要做的是,要让发送速率和接收速率相当(步调一致)

发送数据时候的窗口大小用于衡量发送速率;那么接受速率如何衡量呢?

 3) 接收方如何把接收缓冲区剩余空间,告知发送方呢???

可以在ACK这个报文中带上这个信息!!

当16位窗口大小当前是ACK报文的时候会生效;

这个窗口大小,就表示了接收缓冲区的剩余空间大小;

根据这个大小就可以进一步的影响到发送速率了;

举实例说明:

可以建立一个蓄水池的场景;

2.8 拥塞控制

流量控制,站在接收方的角度,来控制发送速率!!!!

 但是整体的传输,其实不光有发送方和接收方,还有中间的一系列用来转发的设备!!!

 控制A发的快慢,不能光考虑B的接收能力,也要考虑中间设备转发能力!!!

也就像木桶原理:能装多少水,取决于最短的木板;

衡量B的处理能力,是使用了B的接收缓冲区的剩余空间;

要想衡量中间的设备,咋办?

1.中间的设备都有几个??

2.中间的设备各个参数是啥??

3.两次传输,经历的中间设备是否相同??

等等...........................

拥塞控制,采取的办法,做实验!!

通过实验的方式,找出一个合适的窗口大小!!

1.刚开始按照小的窗口来发送;

2.如果不丢包,说明网络中间环境比较畅通;就可以逐渐放大发送窗口的大小;

3.放大到一定程度,速率已经比较快,网络上就容易出现拥堵;进一步出现丢包!!!

当发送方发现丢包之后;就减小发送的窗口;

之后就反复在2-3之间循环!!

这个过程,就达到了一个动态平衡";

发送速率不慢,接近了能承载的极限;同时还可以尽量少丢包;

还能够适应网络环境的动态变化;

2.9流量控制和拥塞控制的联系;

流量控制和拥塞控制都能影响发送方的滑动窗口大小!!!

最终的滑动窗口大小,就取决于流量控制的窗口和拥塞控制的窗口中的较小值;

都是通过控制窗口大小,来制约发送方的发送速率的;

在保证可靠性的前提下,尽量提高一下发送的速度;

(1)如果是拥塞控制的窗口大,流量控制的窗口小;

         则中间节点的转发能力强,接收端的代码处理的慢;

(2)如果是拥塞控制的窗口小,流量控制的窗口大‘

         则中间节点的转发能力弱,接收端的代码处理的快;

拥塞控制的窗口:发送方自己做实验做出来的;

流量控制的窗口:接收方通过接收缓冲区剩余空间大小

                             通过ACK报文的报头返回给发送方的;

上述两者最终发送方下一次发送的窗口大小就是通过这两个值的较小值,来确定的

2.10 延时应答;

1)概念:

也是一个用来提高效率的机制.

延时应答,则是让窗口能够大一些!!让流量控制别限制的太狠;

2)工作原理:

 举实例说明:

2.11 捎带应答

1)作用:

基于延时应答的策略;为了提高传输效率;

2)工作原理:

正常来说ACK是收到请求之后,内核立即返回的; 

响应数据,则是应用程序代码,发送的;

上述两者处于不同的时机,就不能把上个ACK和下个响应报文合并;

但是上面介绍延时应答

延时一会,就可能和返回响应数据,时间上就重合了;

响应在收到请求之后,多长时间之内返回??

不确定!!可能快(几个ms),也可能慢!!!(几百ms);

本来也要发送数据报文;就搭个顺风车,直接就走了呗;

2.22 面向字节流

1)概念:

面向字节流,指的是读写载荷数据的时候,是按照"字节流"的方式来读取的.

TCР数据报,本身仍然是一个一个"数据报"这样的方式来传输的.(应用程序这里,感知不到从哪里到哪里是一个数据报的)

2)图示举例说明:

 优点:

可以一次读M个字节,分N次读;

此时,应用程序,在读取数据的时候,就可以很灵活的进行了;

缺点:

面向字节流的最核心的问题:粘占(nian)包问题!!

如果一个TCP连接,里面只传一个应用层数据包,这个时候,不会粘包;(短连接)

如果一个TCP 连接里,传输多个应用层数据报,这个时候就容易区分不清,从哪到哪是一个完整的应用层数据!![粘包问题](长连接)

粘占(nian)包问题实例:

上述数据aaabbbccc; 这些数据都进入接收缓冲区了;

接收方就区分不了,这些数据是来自于几个应用层数据;

也区分不了从哪到哪是一个应用层数据报;

3)粘占(nian)包问题出现的原因及其解决方案;

粘包问题,根本原因,是TCP面向字节流.但是直接影响,却是影响的应用层的代码;

粘包问题的解决方案:

在应用程序代码中,明确包之间的边界;

1.使用分隔符;

2.约定长度;

1.2属于自定义应用层协议的知识点;

2.23 TCP连接出现异常时,如何处理?

1)主机关机(按照固定程序关机) 

按照程序关机,会先杀死所有的用户进程(也就包括咱们自己写的tcp程序);

杀死进程=>释放进程PCB=>释放文件描述符表上对应的文件资源(相当于调用close );

这个时候就会触发FIN,开启四次挥手的流程!(这里的异常情况,还是比较好处理)

                                                                                                                                                  

如果在挥手挥完了,继续关机(没啥特殊的);

如果还没挥完,就已经关机了,对端重传FIN若干次,没有响应,也就放弃了;

2)程序崩溃

同上. 程序是正常关闭,还是异常崩溃,都会释放PCB,都会释放文件描述符表(相当于调用close);

                                                                                                                                                  

也还是会正常四次挥手(虽然进程没了,但是本身TCP连接也是内核负责,内核仍然会继续完成后续的挥手过程);

3)主机掉电(突然拔电源)

笔记本还好(内置电源);

如果是台式机之类的,直接就没了!!肯定是来不及挥手;

1.接收方掉电.对方尝试发送数据,发现没有ack;尝试重传;重传几次,仍然没有ack ~~发送方尝试重新建立连接~~如果重新建立也不成,认为是当前网络上出现了严重问题~~~也就自然放弃了;

⒉发送方掉电. 接收方就在等待发送方发的数据.由于发送方没了~这个数据显然发不过来了;

接收方,不知道,是对方还没发呢,还是对方出问题了;(接收方区分不了)

接收方如果一段时间没有收到数据,就会定期的给发送方,发送“心跳包"

“心跳包":1.周期性的;2.判定对方是否存活的;

接收方,给发送方发一个特殊的报文(ping)

发送方,对方返回一个特殊的报文(pong)

如果有上述发的两个报文;就认为对方是正常的状态.如果ping没有对应的pong,就认为对方挂了;

4)网线断开

和主机掉电相同;

总结

今天的内容就介绍到这里,我们下期再见!!!!

相关文章:

【JavaEE初阶】第六节.网络原理TCP/IP协议

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言 一、TCP/IP协议五层协议栈&#xff1b; 1.1 应用层协议&#xff1b; 二、传输层协议&#xff1b; 2.1 UDP协议&#xff1b; 2.2 TCP协议&#xff1b; 2.…...

模式识别 —— 第六章 支持向量机(SVM)与核(Kernel)

模式识别 —— 第六章 支持向量机&#xff08;SVM&#xff09;与核&#xff08;Kernel&#xff09; 文章目录模式识别 —— 第六章 支持向量机&#xff08;SVM&#xff09;与核&#xff08;Kernel&#xff09;硬间隔&#xff08;Hard-Margin&#xff09;软间隔&#xff08;Soft…...

总结 synchronized

目录synchronized的特性1. 互斥2. 刷新内存3. 可重入synchronized的使用1. 直接修饰普通方法2. 修饰静态方法3. 修饰代码块synchronized的锁机制基本特点关键锁策略 : 锁升级synchronized的特性 1. 互斥 synchronized 会起到互斥效果, 某个线程执行到某个对象的 synchronized…...

360周鸿祎又“开炮”:GPT 6-8就将产生自主意识!我们来测算一下对错

‍数据智能产业创新服务媒体——聚焦数智 改变商业近日&#xff0c;360的周鸿祎放言“GPT6到GPT8人工智能将会产生意识&#xff0c;变成新的物种。未来&#xff0c;人工智能大语言模型有可能实现自我进化&#xff0c;自动更新系统和自我升级&#xff0c;或者指数级进化能力&am…...

python——飞机大战小游戏

目录 1、导入模块 2、窗口操作 3、事件操作 4、长按事件 5、添加游戏背景 6、添加英雄飞机 7、获取飞机的图片矩形 8、基本游戏窗口 9、添加游戏窗口图片 10、英雄飞机登场 11、英雄飞机装备子弹并发射 1、enemy_plane 2、game_main 3、game_map 4、game_score …...

数组(完全二叉树)向下建堆法与堆排序O(N*logN)

TIPS AdjustUp & AdjustDown向上调整AdjustUp与向下调整AdjustDown的参数是一个数组&#xff08;完全二叉树&#xff09;需要进行调整操作的数值的下标/一个数组&#xff08;完全二叉树&#xff09;堆元素个数需要调整操作的数值的下标。实际上就是对完全二叉树当中的某一点…...

Lua require 函数使用

从 Lua 的用户文档中我们知道 require("modName") 函数是用来加载模块的&#xff0c;而如果这个modName已经用require 加载过的&#xff0c;再调用require时&#xff0c;将直接返回模块的值。因为函数首先查找 package.loaded 表&#xff0c; 检测 modName 是否被加载…...

【面试】如何定位线上问题?

这个面试题我在两年社招的时候遇到过&#xff0c;前几天面试也遇到了。我觉得我每一次都答得中规中矩&#xff0c;今天来梳理复盘下&#xff0c;下次又被问到的时候希望可以答得更好。 下一次我应该会按照这个思路去答&#xff1a; 1、如果线上出现了问题&#xff0c;我们更多…...

字节二面,原来我对自动化测试的理解太浅了

如果你入职一家新的公司&#xff0c;领导让你开展自动化测试&#xff0c;作为一个新人&#xff0c;你肯定会手忙脚乱&#xff0c;你会如何落地自动化测试呢&#xff1f; 01 什么是自动化 有很多人做了很长时间的自动化但却连自动化的概念都不清楚&#xff0c;这样的人也是很悲…...

Android11.0 应用升级成功后立即断电重启,版本恢复

问题&#xff1a;客户反馈内置的应用升级成功后立刻断电重启&#xff0c;应用的版本被恢复。 使用adb命令升级客户应用&#xff0c;查看版本显示已更新&#xff0c;/data/system目录下packages.xml和packages.xml中应用版本信息均已更新 C:\Users\dell>adb shell dumpsys …...

关于python常用软件用法:Pycharm 常用功能

人生苦短&#xff0c;我用python 一.Pycharm的基本使用 1.在Pycharm下为你的Python项目配置Python解释器 &#xff08;1&#xff09;.Setting>Project Interpreter>源码资料电子书:点击此处跳转文末名片获取 二.在Pycharm下创建Python文件、Python模块 1.File>New&g…...

SOLIDWORKS你不知道的小技巧

◉ SOLIDWORKS圆弧长度标注点智能标注&#xff0c;再选中该圆弧&#xff0c;然后分别点圆弧的两个端点&#xff0c;点击左键可以标注圆弧长度。◉ SOLIDWORKS强力裁剪剪裁实体中的强劲剪裁&#xff0c;除了可以裁剪实体外&#xff0c;还可以任意延伸实体。◉ SOLIDWORKS转折线转…...

有了HTTP,为啥还要用RPC

既然有 HTTP 请求&#xff0c;为什么还要用 RPC 调用&#xff1f; 一直以来都没有深究过RPC和HTTP的区别&#xff0c;不都是写一个服务然后在客户端调用么&#xff1f; HTTP和RPC最本质的区别&#xff0c;就是 RPC 主要是基于 TCP/IP 协议的&#xff0c;而 HTTP 服务主要是基…...

[leetcode] 动态规划

背包 先啃懂 背包九讲 01背包&#xff0c;即物品有限。 for 物品for 容量&#xff08;倒序&#xff09;P1048 [NOIP2005 普及组] 采药 [ 原题 | 题解 ] P1049 [NOIP2001 普及组] 装箱问题 [ 原题 | 题解 ] P1507 NASA的食物计划 [ 原题 | 题解 ] P1510 精卫填海 [ 原题 | 题…...

科大奥瑞物理实验——热电偶特性及其应用研究

实验名称&#xff1a;热电偶特性及其应用研究 1. 实验目的&#xff1a; 掌握电位差计的工作原理和结构特点&#xff1b;了解温差电偶测温的原理和方法&#xff1b;学会电位差计的使用及注意事项。 2. 实验器材&#xff1a; 电位差计 标准电池 光电检流计 稳压电源 温差电偶…...

Eclips快捷键大全(超详细)

Eclips快捷键大全&#xff08;超详细&#xff09;前言一、常用快捷键二、编辑快捷键三、导航快捷键四、运行和调试快捷键五、重构快捷键六、代码生成快捷键七、项目导航快捷键八、帮助快捷键九、搜索快捷键十、标记快捷键十一、版本控制快捷键十二、其它快捷键前言 本博主将用C…...

整懵了,蚂蚁金服4面成功拿下测开offer,涨薪10k,突然觉得跳槽也不是那么难

蚂蚁的面试挺独特的&#xff0c;每轮面试都没有HR约时间&#xff0c;一般是晚上8点左右面试官来一个电话&#xff0c;问是否能面试&#xff0c;能的话开始面&#xff0c;不能就约一个其他时间。 全程4面&#xff0c;前四面技术面&#xff0c;电话面试&#xff0c;最后一面是HR面…...

C++内存分布malloc-free-new-delete的区别和联系

目录 一、内存分布 1.1内存分布图&#xff1a; 1.2 为什么要将bss和data区分开呢&#xff1f; 1.3 堆和栈有什么区别 二、malloc、free&#xff1b;new、delete 2.1 new和delete是如何实现的&#xff0c;new与malloc的异同处 2.2既然有了malloc/free&#xff0c;C为什么还…...

【华为OD机试 2023最新 】 最多颜色的车辆(C++ 100%)

文章目录 题目描述输入描述输出描述用例题目解析C++题目描述 在一个狭小的路口,每秒只能通过一辆车,假设车辆的颜色只有 3 种,找出 N 秒内经过的最多颜色的车辆数量。 三种颜色编号为0 ,1 ,2 输入描述 第一行输入的是通过的车辆颜色信息 [0,1,1,2] 代表4 秒钟通过的车…...

Linux安全加固

一、重要文件 /etc/passwd #记录本地用户的属性信息&#xff0c;如UID、GID /etc/shadow #存放用户的口令信息 只有系统管理员能查看 /etc/pam.d/system-auth #账户安全配置文件 /etc/login.defs #修改登录的配置文件 /etc/profile …...

MPNet:旋转机械轻量化故障诊断模型详解python代码复现

目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...

基于大模型的 UI 自动化系统

基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...

stm32G473的flash模式是单bank还是双bank?

今天突然有人stm32G473的flash模式是单bank还是双bank&#xff1f;由于时间太久&#xff0c;我真忘记了。搜搜发现&#xff0c;还真有人和我一样。见下面的链接&#xff1a;https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...

DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径

目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...

JAVA后端开发——多租户

数据隔离是多租户系统中的核心概念&#xff0c;确保一个租户&#xff08;在这个系统中可能是一个公司或一个独立的客户&#xff09;的数据对其他租户是不可见的。在 RuoYi 框架&#xff08;您当前项目所使用的基础框架&#xff09;中&#xff0c;这通常是通过在数据表中增加一个…...

C++:多态机制详解

目录 一. 多态的概念 1.静态多态&#xff08;编译时多态&#xff09; 二.动态多态的定义及实现 1.多态的构成条件 2.虚函数 3.虚函数的重写/覆盖 4.虚函数重写的一些其他问题 1&#xff09;.协变 2&#xff09;.析构函数的重写 5.override 和 final关键字 1&#…...

【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的“no matching...“系列算法协商失败问题

【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的"no matching..."系列算法协商失败问题 摘要&#xff1a; 近期&#xff0c;在使用较新版本的OpenSSH客户端连接老旧SSH服务器时&#xff0c;会遇到 "no matching key exchange method found"​, "n…...

android13 app的触摸问题定位分析流程

一、知识点 一般来说,触摸问题都是app层面出问题,我们可以在ViewRootImpl.java添加log的方式定位;如果是touchableRegion的计算问题,就会相对比较麻烦了,需要通过adb shell dumpsys input > input.log指令,且通过打印堆栈的方式,逐步定位问题,并找到修改方案。 问题…...

提升移动端网页调试效率:WebDebugX 与常见工具组合实践

在日常移动端开发中&#xff0c;网页调试始终是一个高频但又极具挑战的环节。尤其在面对 iOS 与 Android 的混合技术栈、各种设备差异化行为时&#xff0c;开发者迫切需要一套高效、可靠且跨平台的调试方案。过去&#xff0c;我们或多或少使用过 Chrome DevTools、Remote Debug…...

WPF八大法则:告别模态窗口卡顿

⚙️ 核心问题&#xff1a;阻塞式模态窗口的缺陷 原始代码中ShowDialog()会阻塞UI线程&#xff0c;导致后续逻辑无法执行&#xff1a; var result modalWindow.ShowDialog(); // 线程阻塞 ProcessResult(result); // 必须等待窗口关闭根本问题&#xff1a…...