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

网站建设明细报价单南昌网站建设如何

网站建设明细报价单,南昌网站建设如何,wordpress怎么做优化,哪个网站可以做代练海康威视 1.函数指针和指针函数区别 1.定义的差异 函数指针#xff1a;函数指针的定义涉及到函数的地址。例如#xff0c;定义一个指向函数的指针 int (*fp)(int)#xff0c;这里 fp 是一个指针#xff0c;它指向一个接受一个整数参数并返回整数的函数。 指针函数#…海康威视 1.函数指针和指针函数区别 1.定义的差异 函数指针函数指针的定义涉及到函数的地址。例如定义一个指向函数的指针 int (*fp)(int)这里 fp 是一个指针它指向一个接受一个整数参数并返回整数的函数。 指针函数指针函数是指其返回类型为指针的函数。例如int* f(int) 表示一个函数 f它接受一个整数参数 并返回一个指向整数的指针。 2.用法的不同 函数指针在编程中函数指针主要用于指向和调用不同的函数特别是在实现策略模式、回调函数或事件驱动程序时。这使得代码更加模块化和可重用。(挂钩子) 指针函数指针函数通常用于在函数内部动态分配内存并将其地址返回给调用者。这在处理大型数据结构或提供灵活的内存管理方案时非常有用。 3.应用场景的区别 函数指针它们广泛应用于实现接口、回调机制以及函数作为参数的情况。例如在C标准库中的 qsort 函数使用函数指针来定制排序行为。 指针函数主要用于当函数需要返回多个值或大型数据结构时。例如在操作字符串或复杂数据结构时指针函数可以有效地返回所需的数据。 4.语法结构的差异 函数指针在定义函数指针时重点在于指针的位置和它指向的函数类型。正确的语法和理解函数的签名是关键。 指针函数其定义类似于常规函数只是其返回类型为指针。理解如何声明返回指针的函数并确保正确的内存管理是使用指针函数的关键。 2.进程与线程的区别 0、什么是线程 线程英语thread是操作系统能够进行运算调度的最小单位。它被包含在进程之中是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流一个进程中可以并发多个线程每条线程并行执行不同的任务。在Unix System V及SunOS中也被称为轻量进程lightweight processes但轻量进程更多指内核线程kernel thread而把用户线程user thread称为线程。 线程是独立调度和分派的基本单位。线程可以为操作系统内核调度的内核线程如Win32线程由用户进程自行调度的用户线程如Linux平台的POSIX Thread或者由内核与用户进程如Windows 7的线程进行混合调度。 同一进程中的多条线程将共享该进程中的全部系统资源如虚拟地址空间文件描述符和信号处理等等。但同一进程中的多个线程有各自的调用栈call stack自己的寄存器环境register context自己的线程本地存储thread-local storage。 一个进程可以有很多线程每条线程并行执行不同的任务。 在多核或多CPU或支持Hyper-threading的CPU上使用多线程程序设计的好处是显而易见即提高了程序的执行吞吐率。在单CPU单核的计算机上使用多线程技术也可以把进程中负责I/O处理、人机交互而常被阻塞的部分与密集计算的部分分开来执行编写专门的workhorse线程执行密集计算从而提高了程序的执行效率。 1、根本区别 进程是操作系统进行资源分配的最小单元线程是操作系统进行运算调度的最小单元。 进程Process是计算机中的程序关于某数据集合上的一次运行活动是系统进行资源分配和调度的基本单位是操作系统结构的基础。 线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中是进程中的实际运作单位。 2、从属关系不同 进程中包含了线程线程属于进程。一个进程可以有很多线程每条线程并行执行不同的任务。一条线程指的是进程中一个单一顺序的控制流一个进程中可以并发多个线程每条线程并行执行不同的任务。 3、开销不同 进程的创建、销毁和切换的开销都远大于线程。由于线程比进程更小基本上不拥有系统资源故对它的调度所付出的开销就会小得多能更高效的提高系统内多个程序间并发执行的程度从而显著提高系统资源的利用率和吞吐量。 4、拥有资源不同 每个进程有自己的内存和资源一个进程中的线程会共享这些内存和资源。进程是资源分配的基本单位。 所有与该进程有关的资源都被记录在进程控制块PCB中。以表示该进程拥有这些资源或正在使用它们。 另外进程也是抢占处理机的调度单位它拥有一个完整的虚拟地址空间。 当进程发生调度时不同的进程拥有不同的虚拟地址空间而同一进程内的不同线程共享同一地址空间。 5、控制和影响能力不同 子进程无法影响父进程而子线程可以影响父线程如果主线程发生异常会影响其所在进程和子线程。 与进程相对应线程与资源分配无关它属于某一个进程并与进程内的其他线程一起共享进程的资源。 6、CPU利用率不同 进程的CPU利用率较低因为上下文切换开销较大而线程的CPU的利用率较高上下文的切换速度快。 在多核或多CPU或支持Hyper-threading的CPU上使用多线程程序设计的好处是显而易见即提高了程序的执行吞吐率。 在单CPU单核的计算机上使用多线程技术也可以把进程中负责I/O处理、人机交互而常被阻塞的部分与密集计算的部分分开来执行编写专门的workhorse线程执行密集计算从而提高了程序的执行效率。 3.malloc和new的区别 new与malloc的10点区别https://www.cnblogs.com/QG-whz/p/5140930.html 1. 申请的内存所在位置 new操作符从自由存储区free store上为对象动态分配内存空间而malloc函数从堆上动态分配内存。 自由存储区是C基于new操作符的一个抽象概念凡是通过new操作符进行内存申请该内存即为自由存储区。 而堆是操作系统中的术语是操作系统所维护的一块特殊内存用于程序的内存动态分配C语言使用malloc从堆上分配内存使用free释放已分配的对应内存。 那么自由存储区是否能够是堆问题等价于new是否能在堆上动态分配内存这取决于operator new 的实现细节。自由存储区不仅可以是堆还可以是静态存储区这都看operator new在哪里为对象分配内存。 特别的new甚至可以不为对象分配内存定位new的功能可以办到这一点 new (place_address) type place_address为一个指针代表一块内存的地址。当使用上面这种仅以一个地址调用new操作符时new操作符调用特殊的operator new也就是下面这个版本 void * operator new (size_t,void *) //不允许重定义这个版本的operator new 这个operator new不分配任何的内存它只是简单地返回指针实参然后右new表达式负责在place_address指定的地址进行对象的初始化工作。 2.返回类型安全性 new操作符内存分配成功时返回的是对象类型的指针类型严格与对象匹配无须进行类型转换故new是符合类型安全性的操作符。 而malloc内存分配成功则是返回void *** 需要通过强制类型转换将void*指针转换成我们需要的类型**。 类型安全很大程度上可以等价于内存安全类型安全的代码不会试图方法自己没被授权的内存区域。关于C的类型安全性可说的又有很多了。 3.内存分配失败时的返回值 new内存分配失败时会抛出bac_alloc异常它不会返回NULL malloc分配内存失败时返回NULL。 在使用C语言时我们习惯在malloc分配内存后判断分配是否成功 int *a (int *)malloc ( sizeof (int )); if(NULL a) {... } else {... } 从C语言走入C阵营的新手可能会把这个习惯带入C int * a new int(); if(NULL a) {... } else { ... } 实际上这样做一点意义也没有因为new根本不会返回NULL而且程序能够执行到if语句已经说明内存分配成功了如果失败早就抛异常了。正确的做法应该是使用异常机制 try {int *a new int(); } catch (bad_alloc) {... } 如果你想顺便了解下异常基础可以看http://www.cnblogs.com/QG-whz/p/5136883.htmlC 异常机制分析。 4.是否需要指定内存大小 使用new操作符申请内存分配时无须指定内存块的大小编译器会根据类型信息自行计算而malloc则需要显式地指出所需内存的尺寸。 class A{...} A * ptr new A; A * ptr (A *)malloc(sizeof(A)); //需要显式指定所需内存大小sizeof(A); 当然了我这里使用malloc来为我们自定义类型分配内存是不怎么合适的请看下一条。 5.是否调用构造函数/析构函数 使用new操作符来分配对象内存时会经历三个步骤 第一步调用operator new 函数对于数组是operator new[]分配一块足够大的原始的未命名的内存空间以便存储特定类型的对象。 第二步编译器运行相应的构造函数以构造对象并为其传入初值。 第三部对象构造完成后返回一个指向该对象的指针。 使用delete操作符来释放对象内存时会经历两个步骤 第一步调用对象的析构函数。 第二步编译器调用operator delete(或operator delete[])函数释放内存空间。 总之来说new/delete会调用对象的构造函数/析构函数以完成对象的构造/析构。而malloc则不会。如果你不嫌啰嗦可以看下我的例子 6.对数组的处理 C提供了new[]与delete[]来专门处理数组类型: A * ptr new A[10];//分配10个A对象 使用new[]分配的内存必须使用delete[]进行释放 delete [] ptr; new对数组的支持体现在它会分别调用构造函数函数初始化每一个数组元素释放对象时为每个对象调用析构函数。注意delete[]要与new[]配套使用不然会找出数组对象部分释放的现象造成内存泄漏。 至于malloc它并知道你在这块内存上要放的数组还是啥别的东西反正它就给你一块原始的内存在给你个内存的地址就完事。所以如果要动态分配一个数组的内存还需要我们手动自定数组的大小 int * ptr (int *) malloc( sizeof(int)* 10 );//分配一个10个int元素的数组 7.new与malloc是否可以相互调用 operator new /operator delete的实现可以基于malloc而malloc的实现不可以去调用new。下面是编写operator new /operator delete 的一种简单方式其他版本也与之类似 void * operator new (sieze_t size) {if(void * mem malloc(size)return mem;elsethrow bad_alloc(); } void operator delete(void *mem) noexcept {free(mem); } 8.是否可以被重载 opeartor new /operator delete可以被重载。标准库是定义了operator new函数和operator delete函数的8个重载版本 //这些版本可能抛出异常 void * operator new(size_t); void * operator new[](size_t); void * operator delete (void * )noexcept; void * operator delete[](void *0noexcept; //这些版本承诺不抛出异常 void * operator new(size_t ,nothrow_t) noexcept; void * operator new[](size_t, nothrow_t ); void * operator delete (void *,nothrow_t )noexcept; void * operator delete[](void *0,nothrow_t noexcept; 我们可以自定义上面函数版本中的任意一个前提是自定义版本必须位于全局作用域或者类作用域中。 太细节的东西不在这里讲述总之我们知道我们有足够的自由去重载operator new /operator delete ,以决定我们的new与delete如何为对象分配内存如何回收对象。 而malloc/free并不允许重载。 9. 能够直观地重新分配内存 使用malloc分配的内存后如果在使用过程中发现内存不足可以使用realloc函数进行内存重新分配实现内存的扩充。realloc先判断当前的指针所指内存是否有足够的连续空间如果有原地扩大可分配的内存地址并且返回原来的地址指针如果空间不够先按照新指定的大小分配空间将原有数据从头到尾拷贝到新分配的内存区域而后释放原来的内存区域。 new没有这样直观的配套设施来扩充内存。 10. 客户处理内存分配不足 在operator new抛出异常以反映一个未获得满足的需求之前它会先调用一个用户指定的错误处理函数这就是new-handler。new_handler是一个指针类型 namespace std {typedef void (*new_handler)(); }指向了一个没有参数没有返回值的函数,即为错误处理函数。为了指定错误处理函数客户需要调用set_new_handler这是一个声明于的一个标准库函数: namespace std {new_handler set_new_handler(new_handler p ) throw(); }set_new_handler的参数为new_handler指针指向了operator new 无法分配足够内存时该调用的函数。 其返回值也是个指针指向set_new_handler被调用前正在执行但马上就要发生替换的那个new_handler函数。 对于malloc客户并不能够去编程决定内存不足以分配时要干什么事只能看着malloc返回NULL。 总结 将上面所述的10点差别整理成表格 特征new/deletemalloc/free分配内存的位置自由存储区堆内存分配成功的返回值完整类型指针void*内存分配失败的返回值默认抛出异常返回NULL分配内存的大小由编译器根据类型计算得出必须显式指定字节数处理数组有处理数组的new版本new[]需要用户计算数组的大小后进行内存分配已分配内存的扩充无法直观地处理使用realloc简单完成是否相互调用可以看具体的operator new/delete实现不可调用new分配内存时内存不足客户能够指定处理函数或重新制定分配器无法通过用户代码进行处理函数重载允许不允许构造函数与析构函数调用不调用 malloc给你的就好像一块原始的土地你要种什么需要自己在土地上来播种 而new帮你划好了田地的分块数组帮你播了种构造函数还提供其他的设施给你使用: 当然malloc并不是说比不上new它们各自有适用的地方。在C这种偏重OOP的语言使用new/delete自然是更合适的。 4.TCP的三次握手和四次挥手 三次握手证明对端没问题。四次回收为了关闭双工 请画出三次握手和四次挥手的示意图为什么连接的时候是三次握手什么是半连接队列ISN(Initial Sequence Number)是固定的吗三次握手过程中可以携带数据吗如果第三次握手丢失了客户端服务端会如何处理SYN攻击是什么挥手为什么需要四次四次挥手释放连接时等待2MSL的意义? 1. 三次握手 三次握手Three-way Handshake其实就是指建立一个TCP连接时需要客户端和服务器总共发送3个包。进行三次握手的主要作用就是为了确认双方的接收能力和发送能力是否正常、指定自己的初始化序列号为后面的可靠性传送做准备。实质上其实就是连接服务器指定端口建立TCP连接并同步连接双方的序列号和确认号交换TCP窗口大小信息。 刚开始客户端处于 Closed 的状态服务端处于 Listen 状态。进行三次握手 第一次握手客户端给服务端发一个 SYN 报文并指明客户端的初始化序列号 ISN©。此时客户端处于 SYN_SEND 状态。 首部的同步位SYN1初始序号seqxSYN1的报文段不能携带数据但要消耗掉一个序号。 第二次握手服务器收到客户端的 SYN 报文之后会以自己的 SYN 报文作为应答并且也是指定了自己的初始化序列号 ISN(s)。同时会把客户端的 ISN 1 作为ACK 的值表示自己已经收到了客户端的 SYN此时服务器处于 SYN_RCVD 的状态。 在确认报文段中SYN1ACK1确认号ackx1初始序号seqy。 第三次握手客户端收到 SYN 报文之后会发送一个 ACK 报文当然也是一样把服务器的 ISN 1 作为 ACK 的值表示已经收到了服务端的 SYN 报文此时客户端处于 ESTABLISHED 状态。服务器收到 ACK 报文之后也处于 ESTABLISHED 状态此时双方已建立起了连接。 确认报文段ACK1确认号acky1序号seqx1初始为seqx第二个报文段所以要1ACK报文段可以携带数据不携带数据则不消耗序号。 发送第一个SYN的一端将执行主动打开active open接收这个SYN并发回下一个SYN的另一端执行被动打开passive open。 在socket编程中客户端执行connect()时将触发三次握手。 1.1 为什么需要三次握手两次不行吗 弄清这个问题我们需要先弄明白三次握手的目的是什么能不能只用两次握手来达到同样的目的。 第一次握手客户端发送网络包服务端收到了。 这样服务端就能得出结论客户端的发送能力、服务端的接收能力是正常的。 第二次握手服务端发包客户端收到了。 这样客户端就能得出结论服务端的接收、发送能力客户端的接收、发送能力是正常的。不过此时服务器并不能确认客户端的接收能力是否正常。 第三次握手客户端发包服务端收到了。 这样服务端就能得出结论客户端的接收、发送能力正常服务器自己的发送、接收能力也正常。 因此需要三次握手才能确认双方的接收与发送能力是否正常。 试想如果是用两次握手则会出现下面这种情况 如客户端发出连接请求但因连接请求报文丢失而未收到确认于是客户端再重传一次连接请求。后来收到了确认建立了连接。数据传输完毕后就释放了连接客户端共发出了两个连接请求报文段其中第一个丢失第二个到达了服务端但是第一个丢失的报文段只是在某些网络结点长时间滞留了延误到连接释放以后的某个时间才到达服务端此时服务端误认为客户端又发出一次新的连接请求于是就向客户端发出确认报文段同意建立连接不采用三次握手只要服务端发出确认就建立新的连接了此时客户端忽略服务端发来的确认也不发送数据则服务端一致等待客户端发送数据浪费资源。1.2 什么是半连接队列 服务器第一次收到客户端的 SYN 之后就会处于 SYN_RCVD 状态此时双方还没有完全建立其连接服务器会把此种状态下请求连接放在一个队列里我们把这种队列称之为半连接队列。 当然还有一个全连接队列就是已经完成三次握手建立起连接的就会放在全连接队列中。如果队列满了就有可能会出现丢包现象。 这里在补充一点关于SYN-ACK 重传次数的问题 服务器发送完SYN-ACK包如果未收到客户确认包服务器进行首次重传等待一段时间仍未收到客户确认包进行第二次重传。如果重传次数超过系统规定的最大重传次数系统将该连接信息从半连接队列中删除。 注意每次重传等待的时间不一定相同一般会是指数增长例如间隔时间为 1s2s4s8s… 1.3 ISN(Initial Sequence Number)是固定的吗 当一端为建立连接而发送它的SYN时它为连接选择一个初始序号。ISN随时间而变化因此每个连接都将具有不同的ISN。ISN可以看作是一个32比特的计数器每4ms加1 。这样选择序号的目的在于防止在网络中被延迟的分组在以后又被传送而导致某个连接的一方对它做错误的解释。 三次握手的其中一个重要功能是客户端和服务端交换 ISN(Initial Sequence Number)以便让对方知道接下来接收数据的时候如何按序列号组装数据。如果 ISN 是固定的攻击者很容易猜出后续的确认号因此 ISN 是动态生成的。 1.4 三次握手过程中可以携带数据吗 其实第三次握手的时候是可以携带数据的。但是第一次、第二次握手不可以携带数据 为什么这样呢? 大家可以想一个问题假如第一次握手可以携带数据的话如果有人要恶意攻击服务器那他每次都在第一次握手中的 SYN 报文中放入大量的数据。因为攻击者根本就不理服务器的接收、发送能力是否正常然后疯狂着重复发 SYN 报文的话这会让服务器花费很多时间、内存空间来接收这些报文。 也就是说第一次握手不可以放数据其中一个简单的原因就是会让服务器更加容易受到攻击了。而对于第三次的话此时客户端已经处于 ESTABLISHED 状态。对于客户端来说他已经建立起连接了并且也已经知道服务器的接收、发送能力是正常的了所以能携带数据也没啥毛病。 1.5 SYN攻击是什么 服务器端的资源分配是在二次握手时分配的而客户端的资源是在完成三次握手时分配的所以服务器容易受到SYN洪泛攻击。SYN攻击就是Client在短时间内伪造大量不存在的IP地址并向Server不断地发送SYN包Server则回复确认包并等待Client确认由于源地址不存在因此Server需要不断重发直至超时这些伪造的SYN包将长时间占用未连接队列导致正常的SYN请求因为队列满而被丢弃从而引起网络拥塞甚至系统瘫痪。SYN 攻击是一种典型的 DoS/DDoS 攻击。 检测 SYN 攻击非常的方便当你在服务器上看到大量的半连接状态时特别是源IP地址是随机的基本上可以断定这是一次SYN攻击。在 Linux/Unix 上可以使用系统自带的 netstats 命令来检测 SYN 攻击。 netstat -n -p TCP | grep SYN_RECV常见的防御 SYN 攻击的方法有如下几种 缩短超时SYN Timeout时间增加最大半连接数过滤网关防护SYN cookies技术 2. 四次挥手 建立一个连接需要三次握手而终止一个连接要经过四次挥手也有将四次挥手叫做四次握手的。这由TCP的半关闭half-close造成的。所谓的半关闭其实就是TCP提供了连接的一端在结束它的发送后还能接收来自另一端数据的能力。 TCP 的连接的拆除需要发送四个包因此称为四次挥手(Four-way handshake)客户端或服务器均可主动发起挥手动作。 刚开始双方都处于 ESTABLISHED 状态假如是客户端先发起关闭请求。四次挥手的过程如下 第一次挥手客户端发送一个 FIN 报文报文中会指定一个序列号。此时客户端处于 FIN_WAIT1 状态。 即发出连接释放报文段FIN1序号sequ并停止再发送数据主动关闭TCP连接进入FIN_WAIT1终止等待1状态等待服务端的确认。 第二次挥手服务端收到 FIN 之后会发送 ACK 报文且把客户端的序列号值 1 作为 ACK 报文的序列号值表明已经收到客户端的报文了此时服务端处于 CLOSE_WAIT 状态。 即服务端收到连接释放报文段后即发出确认报文段ACK1确认号acku1序号seqv服务端进入CLOSE_WAIT关闭等待状态此时的TCP处于半关闭状态客户端到服务端的连接释放。客户端收到服务端的确认后进入FIN_WAIT2终止等待2状态等待服务端发出的连接释放报文段。 第三次挥手如果服务端也想断开连接了和客户端的第一次挥手一样发给 FIN 报文且指定一个序列号。此时服务端处于 LAST_ACK 的状态。 即服务端没有要向客户端发出的数据服务端发出连接释放报文段FIN1ACK1序号seqw确认号acku1服务端进入LAST_ACK最后确认状态等待客户端的确认。 第四次挥手客户端收到 FIN 之后一样发送一个 ACK 报文作为应答且把服务端的序列号值 1 作为自己 ACK 报文的序列号值此时客户端处于 TIME_WAIT 状态。需要过一阵子以确保服务端收到自己的 ACK 报文之后才会进入 CLOSED 状态服务端收到 ACK 报文之后就处于关闭连接了处于 CLOSED 状态。 即客户端收到服务端的连接释放报文段后对此发出确认报文段ACK1sequ1ackw1客户端进入TIME_WAIT时间等待状态。此时TCP未释放掉需要经过时间等待计时器设置的时间2MSL后客户端才进入CLOSED状态。 收到一个FIN只意味着在这一方向上没有数据流动。客户端执行主动关闭并进入TIME_WAIT是正常的服务端通常执行被动关闭不会进入TIME_WAIT状态。 在socket编程中任何一方执行close()操作即可产生挥手操作。 2.1 挥手为什么需要四次 因为当服务端收到客户端的SYN连接请求报文后可以直接发送SYNACK报文。其中ACK报文是用来应答的SYN报文是用来同步的。 但是关闭连接时当服务端收到FIN报文时很可能并不会立即关闭SOCKET所以只能先回复一个ACK报文告诉客户端“你发的FIN报文我收到了”。只有等到我服务端所有的报文都发送完了我才能发送FIN报文因此不能一起发送。故需要四次挥手。 2.2 2MSL等待状态 TIME_WAIT状态也成为2MSL等待状态。每个具体TCP实现必须选择一个报文段最大生存时间MSLMaximum Segment Lifetime它是任何报文段被丢弃前在网络内的最长时间。这个时间是有限的因为TCP报文段以IP数据报在网络内传输而IP数据报则有限制其生存时间的TTL字段。 对一个具体实现所给定的MSL值处理的原则是当TCP执行一个主动关闭并发回最后一个ACK该连接必须在TIME_WAIT状态停留的时间为2倍的MSL。这样可让TCP再次发送最后的ACK以防这个ACK丢失另一端超时并重发最后的FIN。 这种2MSL等待的另一个结果是这个TCP连接在2MSL等待期间定义这个连接的插口客户的IP地址和端口号服务器的IP地址和端口号不能再被使用。这个连接只能在2MSL结束后才能再被使用。 2.3 四次挥手释放连接时等待2MSL的意义? MSL是Maximum Segment Lifetime的英文缩写可译为“最长报文段寿命”它是任何报文在网络上存在的最长时间超过这个时间报文将被丢弃。 为了保证客户端发送的最后一个ACK报文段能够到达服务器。因为这个ACK有可能丢失从而导致处在LAST-ACK状态的服务器收不到对FIN-ACK的确认报文。服务器会超时重传这个FIN-ACK接着客户端再重传一次确认重新启动时间等待计时器。最后客户端和服务器都能正常的关闭。假设客户端不等待2MSL而是在发送完ACK之后直接释放关闭一但这个ACK丢失的话服务器就无法正常的进入关闭连接状态。 两个理由 保证客户端发送的最后一个ACK报文段能够到达服务端。 这个ACK报文段有可能丢失使得处于LAST-ACK状态的B收不到对已发送的FINACK报文段的确认服务端超时重传FINACK报文段而客户端能在2MSL时间内收到这个重传的FINACK报文段接着客户端重传一次确认重新启动2MSL计时器最后客户端和服务端都进入到CLOSED状态若客户端在TIME-WAIT状态不等待一段时间而是发送完ACK报文段后立即释放连接则无法收到服务端重传的FINACK报文段所以不会再发送一次确认报文段则服务端无法正常进入到CLOSED状态。 防止“已失效的连接请求报文段”出现在本连接中。 客户端在发送完最后一个ACK报文段后再经过2MSL就可以使本连接持续的时间内所产生的所有报文段都从网络中消失使下一个新的连接中不会出现这种旧的连接请求报文段。 2.4 为什么TIME_WAIT状态需要经过2MSL才能返回到CLOSE状态 理论上四个报文都发送完毕就可以直接进入CLOSE状态了但是可能网络是不可靠的有可能最后一个ACK丢失。所以TIME_WAIT状态就是用来重发可能丢失的ACK报文。 3. 总结 《TCP/IP详解 卷1:协议》有一张TCP状态变迁图很具有代表性有助于大家理解三次握手和四次挥手的状态变化。如下图所示粗的实线箭头表示正常的客户端状态变迁粗的虚线箭头表示正常的服务器状态变迁。 5.插入排序的整体实现 1.什么是插入排序 每一步将一个待排序的数据插入到前面已经排序好的有序序列里直到插完所有的元素为止。插入排序与打扑克牌很类似你摸到第一张牌的时候是不需要排序的后续摸到的牌可以根据第一张牌进行向左或者向右排序。算法实现 直接插入排序是把无序的序列里的数据插入到有序的序列中去。在遍历无序序列的时候首先拿无序序列里的第一个元素跟有序序列里的每一个元素比较并且插入到合适的位置一直到无序序列里的所有元素插入完毕为止。 2.插入排序算法图解 • 初始化序列如下所示分为有序序列没有任何元素和无序序列8,2,6,4,3,7,5一开始有序序列是没有任何元素的。 第一轮用8和2比较返现2比8小交换位置变成2 8 第二轮用8和6比较交换位置然后再用2和6比较发现6比2大不用交换位置变成 2 6 8 第三轮用8和4比较交换位置再用6和4比较交换位置2和4比较不用交换位置 第四轮8和3比较交换位置6和3比较交换位置4和3比较交换位置2和3比较不用交换位置 后面以此类推都是向左比较到第一个元素也就是当前元素左边都是有序的右边都是无序的 3.插入排序代码实现 1整体编码实现 public class InsertSort {public static void main(String[] args) {int[] arr {8,2,6,4,3,7,5};System.out.println(排序前);System.out.println(Arrays.toString(arr));insertSort(arr);System.out.println(排序后);System.out.println(Arrays.toString(arr));}public static void insertSort(int[] arr){//第一层循环把数组分成两部分左边是已将排好序的右边是未排序的//当前下表左边的元素已经排好序右边还未排序for (int i 1; i arr.length; i) {//内层循环从当前下标开始祥左比较如果发现比左边元素小就惊醒交换//直到比较到左边第一个元素for (int j i; j 0; j--) {//依次交换依次比较如果不比前一个元素小就跳出if(arr[j-1]arr[j]){int temp arr[j-1];arr[j-1] arr[j];arr[j] temp;}else{break;}}System.out.println(第 i 轮: Arrays.toString(arr));}} }2代码测试
http://www.zqtcl.cn/news/164197/

相关文章:

  • 建立网站备案的法律依据wordpress 招商系统
  • 建设银行全球门户网站网站建设技能
  • 提供企业网站建设价格10元一年的虚拟主机
  • 塔城建设局网站电子商务网站建设方案目录
  • 网站容易被百度收录个人建购物网站怎么备案
  • 中文网站什么意思wordpress电脑访问不了
  • 杨家坪网站建设企业生产erp软件公司
  • 网站模块设计软件河北seo优化_网络建设营销_网站推广服务 - 河北邢台seo
  • 陕西正天建设有限公司网站西安专业网页制作
  • 网站建设工作室介绍范文seo网站排名的软件
  • 上海网站建设-网建知识可编辑个人简历模板
  • 北京新鸿儒做的网站shopify做国内网站
  • 网站怎样做百度推广机关门户网站建设要求
  • 好看的网站后台模板沧州网站群
  • 深圳做网站排名公司哪家好哪些网站seo做的好
  • 国内网站建设推荐网站建设合同标准版
  • 哈尔滨网站制作费用企业成品网站模板
  • 网络广告网站怎么做北京海淀建设中路哪打疫苗
  • 房地产公司网站制作电影发布网站模板
  • 如何利用开源代码做网站网站本科
  • 公司是做小程序还是做网站宜宾住房与城乡建设部网站
  • 做网站哪个公司最社区问答网站开发
  • 网站引量方法网站建设推广页
  • 书店网站的建设网络营销方法有哪些
  • 深圳网站优化软件顺企网怎么样
  • 做网站的需要什么要求中国五百强企业排名表
  • 网络营销 企业网站外贸响应式网站建设
  • 网站网页制作公司o2o平台是什么意思啊
  • 惠州市网站建设个人网站怎么进入后台维护
  • 微信网站链接怎么做wordpress 绑定手机版