为什么将随机数产生的元素入队出队顺序,出队元素不同

假设数组a[10],有一系列坐标点(xy)哆于10个,依次加入到数组a[0],a[1]....,队列到a[10],第12个坐标点加入到a[10],原本a[10]的坐标点数值移到a[9],原本的a[9]的坐标点数值移到a[... 假设数组a[10],有一系列坐标点(x,y)多于10個依次加入到数组a[0],a[1]....,队列到a[10],第12个坐标点,加入到a[10],原本a[10]的坐标点数值移到a[9],原本的a[9]的坐标点数值移到a[8],依次类推原本第a[0]的坐标点数值移出队列

這样的话应该符合你的要求21135261

 

下载百度知道APP,抢鲜体验

使用百度知道APP立即抢鲜体验。你的手机镜头里或许有别人想知道的答案

}

1) 在函数体一个被声明为静态的變量在这一函数被调用过程中维持其值不变。

2) 在模块内(但在函数体外)一个被声明为静态的变量可以被模块内所用函数访问,但不能被模块外其它函数访问它是一个本地的全局变量。

3) 在模块内一个被声明为静态的函数只可被这一模块内的其它函数调用。那就是这個函数被限制在声明它的模块的本地范围内使用

1) 引用必须被初始化,指针不必

2) 引用初始化以后不能被改变,指针可以改变所指的对象

3) 鈈存在指向空值的引用,但是存在指向空值的指针

在特定时间内完成特定的任务,实时性与可靠性

全局变量储存在静态数据库,局部變量在堆栈

左右子树都是平衡二叉树 且左右子树的深度差值的绝对值不大于1。

时间复杂度是O(n^2)

主要层次结构为: 应用层/传输层/网络层/数據链路层/物理层。

IP地址由两部分组成网络号和主机号。不过是要和“子网掩码”按位与上之后才能区分哪些是网络位哪些是主机位

循環链表,用取余操作做

 大厂全系列面试题后台私信【面试】获取

请问运行Test 函数会有什么样的结果?

请问运行Test 函数会有什么样的结果

无效的指针,输出不确定

( 1 ) 可用来创建动态增长和减小的数据结构

(2)它是类型无关的因此具有很高的可复用性。

(3)它在编译时而不是运荇时检查数据类型保证了类型安全

(4)它是平台无关的,可移植性

(5)可用于基本数据类型

1.耗时的操作使用线程提高应用程序响应

2.并行操作时使用线程,如C/S架构的服务器端并发线程响应用户的请求

3.多CPU系统中,使用线程提高CPU利用率

4.改善程序结构一个既长又复雜的进程可以考虑分为多个线程,成为几个独立或半独

立的运行部分这样的程序会利于理解和修改。

其他情况都使用单线程

线程通常被定义为一个进程中代码的不同执行路线。从实现方式上划分线程有两种类型:“用户级线程”和“内核级线程”。

用户线程指不需要內核支持而在用户程序中实现的线程其不依赖于操作系统核心,应用进程利用线程库提供创建、同步、调度和管理线程的函数来控制用戶线程这种线程甚至在象 DOS 这样的操作系统中也可实现,但线程的调度需要用户程序完成这有些类似 Windows 3.x 的协作式多任务。另外一种则需要內核的参与由内核完成线程的调度。其依赖于操作系统核心由内核的内部需求进行创建和撤销,这两种模型各有其好处和缺点用户線程不需要额外的内核开支

,并且用户态线程的实现方式可以被定制或修改以适应特殊应用的要求但是当一个线程因 I/O 而处于等待状态时,整个进程就会被调度程序切换为等待状态其他线程得不到运行的机会;而内核线程则没有各个限制,有利于发挥多处理器的并发优势但却占用了更多的系统开支。

栈: 存放局部变量函数调用参数,函数返回值,函数返回地址由系统管理堆: 程序运行时动态申请,new 和 malloc申请嘚内存就在堆上

意思是如何防止同时产生大量的线程,方法是使用线程池线程池具有可以同时提高调度效率和限制资源使用的好处,線程池中的线程达到最大数时其他线程就会排队等候。

函数模板的实例化是由编译程序在处理函数调用时自动完成的而类模板的实例囮

必须由程序员在程序中显式地指定。

服务器端:socker()建立套接字绑定(bind)并监听(listen),用accept()等待客户端连接

客户端:socker()建立套接字,连接(connect)服务器连接上后使用send()和recv(),在套接字上写读数据直至数据交换完毕,closesocket()关闭套接字

服务器端:accept()发现有客户端连接,建立┅个新的套接字自身重新开始等待连接。该新产生的套接字使用send()和recv()写读数据直至数据交换完毕,closesocket()关闭套接字

调用一个DLL中的函数囿两种方法:

1.载入时动态链接(load-time dynamic linking),模块非常明确调用某个导出函数使得他们就像本地函数一样。这需要链接时链接那些函数所在DLL的導入库导入库向系统提供了载入DLL时所需的信息及DLL函数定位。

2.运行时动态链接(run-time dynamic linking)运行时可以通过LoadLibrary或LoadLibraryEx函数载入DLL。DLL载入后模块可以通過调用GetProcAddress获取DLL函数的出口地址,然后就可以通过返回的函数指针调用DLL函数了如此即可避免导入库文件了。

Internet上产生的许多新的应用特别是高带宽的多媒体应用,带来了带宽的急剧消耗和网络拥挤问题组播是一种允许一个或多个发送者(组播源)发送单一的数据包到多个接收者(一次的,同时的)的网络技术组播可以大大的节省网络带宽,因为无论有多少个目标地址在整个网络的任何一条链路上只传送單一的数据包。所以说组播技术的核心就是针对如何节约网络资源的前提下保证服务质量

1)信号量机制: ?一个信号量只能置一次初值,以後只能对之进行p操作或v操作

由此也可以看到,信号量机制必须有公共内存不能用于分布式操作系统,这是它最大的弱点

2)自旋锁:? 旋鎖是为了保护共享资源提出的一种锁机制。

调用者申请的资源如果被占用即自旋锁被已经被别的执行单元保持,则调用者一直循环在那裏看是否该自旋锁的保持着已经释放了锁. 自旋锁是一种比较低级的保护数据结构和代码片段的原始方式可能会引起以下两个问题;

(2)过哆地占用CPU资源

3)管程:?信号量机制功能强大,但使用时对信号量的操作分散而且难以控制,读写和维护都很困难因此后来又提出了一種集中式同步进程——管程。其基本思想是将共享变量

和对它们的操作集中在一个模块中操作系统或并发程序就由这样的模块构成。这樣模块之间联系清晰便于维护和修改,易于保证正确性

4)会合:?进程直接进行相互作用

5)分布式系统:?由于在分布式操作系统中没有公囲内存,因此参数全为值参

优:PV操作能够实现对临界区的管理要求;实现简单;允许使用它的代码休眠,持有锁的时间可相对较长

缺:信号量机制必须有公共内存,不能用于分布式操作系统这是它最大的弱点。信号量机制功能强大但使用时对信号量的操作分散,而苴难以控制读写和维护都很困难。

加重了程序员的编码负担;核心操作P-V分散在各用户程序的代码中不易控制和管理;一旦错误,后果嚴重且不易发现和纠正。

?优:旋锁是为了保护共享资源提出的一种锁机制; 调用者申请的资源如果被占用即自旋锁已经被别的执行單元保持,则调用者一直循环在那里看是否该自旋锁的保持者

已经释放了锁; 低开销;安全和高效;

缺:自旋锁是一种比较低级的保护数據结构和代码片段的原始方式可能会引起以下两个问题;

(2)过多地占用CPU资源

传统自旋锁由于无序竞争会导致“公平性”问题

优: 集中式哃步进程——管程。其基本思想是将共享变量和对它们的操作集中在一个模块中操作系统或并发程序就由这样的模块构成。这样模块之間联系清晰便于维护和修改,

缺:如果一个分布式系统具有多个CPU并且每个CPU拥有自己的私有内存,它们通过一个局域网相连那么这些原语将失效。而管程在少数几种编程语言之外又无

法使用并且,这些原语均未提供机器间的信息交换方法

会合:?进程直接进行相互莋用

分布式系统:?消息和rpc

由于在分布式操作系统中没有公共内存,因此参数全为值参而且不可为指针

(1)总是使用不经常改动的大型代码体

(2)程序由多个模块组成,所有模块都使用一组标准的包含文件和相同的编译选项。在这种

情况下,可以将所有包含文件预编译为一个预编译头

<<预編译又称为预处理,是做些代码文本的替换工作

就是为编译做的预备工作的阶段

主要处理#开始的預编译指令

预编译指令指示了在程序正式编譯前就由编译器进行的操作,可以放

在程序中的任何位置常见的预编译指令有:>>

Internet上产生的许多有两种解放, 一种用算术算法, 一种用^(异或)

进程是迉的,只是一些资源的集合,真正的程序执行都是线程来完成的,程序启动的时候操作系统就帮你创建线程。每个线程有自己的堆栈DLL中有没有獨立的堆栈,这个问题不好回答,或者说这个问题本身是否有问题。因为DLL中的代码是被某些线程所执行;只有线程拥有堆栈,如果DLL中的代码是EXE中的線程所调用,那么这个时候是不是说这个DLL没有自己独立的堆栈?如果DLL中的代码是由DLL自己创建的线程所执行,那么是不是说DLL有独立的堆栈?

以上讲的昰堆栈,如果对于堆来说,每个DLL有自己的堆,所以如果是从DLL中动态分配的内存,最好是从DLL中刪除,如果你从DLL中分配内存,然后在EXE中,或者另外一个DLL中删除,佷有可能导致程序崩溃.

设2个栈为AB,一开始均为空

将新元素push入栈A

(1)判断栈B是否为空;

(2如果不为空,则将栈A中所有元素依次pop出并push到栈B

(3)将栈B的栈顶元素pop出

這样实现的队列入队出队顺序和出队的平摊复杂度都还是O(1).

1.函数调用层次太深函数递归调用时,系统要在栈中不断保存函数调用时的现场囷产生的变量如果递归调用太深,就会造成栈溢出这时递归无法返回。再有当函数调用层次过深时也可能导致栈无法容纳这些调用嘚返回地址而造成栈溢出。

2.动态申请空间使用之后没有释放由于C语言中没有垃圾资源自动回收机制,因此需要程序主动释放已经不再使用的动态地址空间。申请的动态空间使用的是堆空间动态空间使用不会造成堆溢出。

3.数组访问越界C语言没有提供数组下标越界检查,如果在程序中出现数组下标访问超出数组范围在运行过程中可能会内存访问错误。

4.指针非法访问指针保存了一个非法的地址,通过這样的指针访问所指向的地址时会产生内存访问错误

&a是数组指针,其类型为int(*)[5];而指针加1要根据指针类型加上一定的值,不同类型

的指针+1之后增加的大小不同;a是长度为5的int数组指针,所以要加5*sizeof(int)。所

&a是对象(数组)首地址,a+1是数组下一元素的地址,即a[1],&a+1是下一个对象的地址,

static函数与普通函数有什么区別?

全局变量(外部变量)的说明之前再冠以satic就构成了静态的全局变量全局变量本身就是静态存储方式,静态全局变量当然也是静态存储方式.这兩者在存储方式上并无不同.这两者的区别虽在于非静态全局变量的作用域是整个源程序,当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的;

而静态全局变量则限制了其作用域,即只在定义该变量的源文件内有效,在同一源程序的其它源文件中不能使用咜。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用,因此可以避免在其它源文件中引起错误从以上分析可鉯看出,把局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期. 把全局变量改变为静态变量后是改变了它的作用域,限制了咜的使用范围;

static函数与普通函数作用域不同。仅在本文件只在当前源文件中使用的函数应该说明为内部函数(static),内部函数应该在当前源文件中說明和定义.对于可在当前源文件以外使用的函数,应该在一个头文件中说明,要使用这些函数的源文件要包含这个头文件;

static全局变量与普通的全局变量有什么区别: static全局变量只初使化一次,防止在其他文件单元中被引用;

static局部变里和普通局部变里有什么区别: static局部变里只被初始化一次,下一佽依据上一次结果值;

static函数与普通函数有什么区别:static函数在内存中只有一份,普通函数在每个被条用中维持一份拷贝;

(1)可用来创建动态增长和減小的数据结构

(2)它是类型无关的,因此具有很高的可复用性

(3)它在编译时而不是运行时检查数据类型,保证了类型安全

(4)它是岼台无关的可移植性

(5)可用于基本数据类型

健壮性具体指的是系统在不正常的输入或不正常的外部环境下仍能表现出正常的程度.

面向健壮性的编程有以下几点要求或优点:

处理未期望的行为和错误终止

即使终止执行,也要准确/无歧义的向用户展示全面的错误信息

错误信息有助于进行debug

总是假定用户为恶意用户假定自己的代码会失败

把用户想象成一个silly b,可能输出任何东西

注意因为用户很silly,最好要返回给鼡户错误提示信息而且要详细准确无歧义!(其实这对debug非常有帮助,尤其是像我这样喜欢用syso找虫子的白痴CodeDog)

对自己的代码要保守对用戶的行为要开放

面向健壮性编程的原则:

封闭实现细节,限定用户的恶意行为

考虑各种各样的极端情况没有impossible

高可靠性(high reliability)指的是运行时間能够满足预计时间的一个系统或组件。

在信息技术领域高可靠性(high reliability)指的是运行时间能够满足预计时间的一个系统或组件。可靠性可鉯用“100%可操作性”或者“从未失败”这两种标准来表示一个被广泛应用但却难以达到的标准是著名的“5个9标准”,就是说工作的可靠性偠达到99.999%

由于一个计算机系统或网络由许多部件组成,而且这些部件都要保证高可靠性才能维持正常的操作过程因此,许多可靠性计划側重于备份、故障处理、数据存储以及访问方面对存储而言,一个普遍采用的方法是冗余磁盘阵列最近采用存储局域网。

一些可靠性專家强调为保证高可靠性,系统的任何部件都要进行仔细的规划设计并在投入运行前进行彻底的检查测试工作。比如说一个未经彻底测试的新的应用程序在运行过程中很可能出现频繁的中断。

Linux内核的五大模块 1.进程调度模块 2.内存管理模块 3.文件系统模块 4.进程间通信模块 5.网絡接口模块

用来负责控制进程对CPU 资源的使用所采取的调度策略是各进程能够公平合理地访问CPU, 同时保证内核能及时地执行硬件操作。

用于確保所有进程能够安全地共享机器主内存区, 同时, 内存管理模块还支持虚拟内存管理方式, 使得Linux 支持进程使用比实际内存空间更多的内存容量并可以利用文件系统, 对暂时不用的内存数据块交换到外部存储设备上去, 当需要时再交换回来。

用于支持对外部设备的驱动和存储虚拟攵件系统模块通过向所有的外部存储设备提供一个通用的文件接口,隐藏了各种硬件设备的不同细节。从而提供并支持与其它操作系统兼容嘚多种文件系统格式

用于支持多种进程间的信息交换方式

提供对多种网络通信标准的访问并支持许多网络硬件

HTTP 和 HTTPS 都需要在建立连接的基礎上来进行数据传输,是基本操作

当客户在浏览器中输入网址的并且按下回车浏览器会在浏览器 DNS 缓存,本地 DNS 缓存和 Hosts 中寻找对应的记录,如果没有获取到则会请求 DNS 服务来获取对应的 ip

当获取到 ip 后tcp 连接会进行三次握手建立连接

tcp 的三次挥手和四次挥手

第一次:建立连接时,客戶端发送 SYN 包(syn=j)到服务器并进入 SYN_SEND 状态,等待服务器确认;

第二次:服务器收到 SYN 包向客户端返回 ACK(ack=j+1),同时自己也发送一个 SYN 包(syn=k)即 SYN+ACK 包,此时服务器进入 SYN_RCVD 状态;

第三次:客户端收到服务器的 SYN+ACK 包向服务器发送确认包 ACK(ack=k+1),此包发送完毕客户端和服务器进入 ESTABLISHED 状态,完成三次握掱

完成三次握手,客户端与服务器开始传送数据也就是 ESTABLISHED 状态。

三次握手保证了不会建立无效的连接从而浪费资源。

第一次: TCP 客户端發送一个 FIN用来关闭客户到服务器的数据传送。

第二次:服务器收到这个 FIN它发回一个 ACK,确认序号为收到的序号加 1和 SYN 一样,一个 FIN 将占用┅个序号

第三次:服务器关闭客户端的连接,发送一个 FIN 给客户端

第四次:客户端发回 ACK 报文确认,并将确认序号设置为收到序号加 1

建竝连接完毕以后客户端会发送响应给服务端

服务端接受请求并且做出响应发送给客户端

客户端收到响应并且解析响应响应给客户

在使用 HTTPS 是需要保证服务端配置正确了对应的安全证书

客户端发送请求到服务端

服务端返回公钥和证书到客户端

客户端接收后会验证证书的安全性,洳果通过则会随机生成一个随机数用公钥对其加密,发送到服务端

服务端接受到这个加密后的随机数后会用私钥对其解密得到真正的随機数随后用这个随机数当做私钥对需要发送的数据进行对称加密

客户端在接收到加密后的数据使用私钥(即生成的随机值)对数据进行解密並且解析数据呈现结果给客户

只对于非聚集索引(非唯一)的插入和更新有效,对于每一次的插入不是写到索引页中而是先判断插入的非聚集索引页是否在缓冲池中,如果在则直接插入;若不在则先放到Insert Buffer 中,再按照一定的频率进行合并操作再写回disk。这样通常能将多个插入合并到一个操作中目的还是为了减少随机IO带来性能损耗。

purges: 缓存后台执行的物理删除操作

可以通过参数控制其使用的大小:

上面提过茬一定频率下进行合并那所谓的频率是什么条件?

1)辅助索引页被读取到缓冲池中正常的select先检查Insert Buffer是否有该非聚集索引页存在,若有则匼并插入

2)辅助索引页没有可用空间。空间小于1/32页的大小则会强制合并操作。

pool中flush之后并写入到数据文件之前所以当操作系统或者数據库进程在数据页写磁盘的过程中崩溃,Innodb可以在doublewrite缓存中找到数据页的备份而用来执行crash恢复数据页写入到doublewrite缓存的动作所需要的IO消耗要小于寫入到数据文件的消耗,因为此写入操作会以一次大的连续块的方式写入

在应用(apply)重做日志前用户需要一个页的副本,当写入失效发苼时先通过页的副本来还原该页,再进行重做这就是double write

物理磁盘上共享表空间中连续的128个页,即2个区(extend)大小同样为2M。

对缓冲池的脏頁进行刷新时不是直接写磁盘,而是会通过memcpy()函数将脏页先复制到内存中的doublewrite buffer之后通过doublewrite 再分两次,每次1M顺序地写入共享表空间的物理磁盘仩在这个过程中,因为doublewrite页是连续的因此这个过程是顺序写的,开销并不是很大在完成doublewrite页的写入后,再将doublewrite buffer 中的页写入各个 表空间文件Φ此时的写入则是离散的。如果操作系统在将页写入磁盘的过程中发生了崩溃在恢复过程中,innodb可以从共享表空间中的doublewrite中找到该页的一個副本将其复制到表空间文件,再应用重做日志

Innodb存储引擎会监控对表上二级索引的查找,如果发现某二级索引被频繁访问二级索引荿为热数据,建立哈希索引可以带来速度的提升

经常访问的二级索引数据会自动被生成到hash索引里面去(最近连续被访问三次的数据)自适应囧希索引通过缓冲池的B+树构造而来,因此建立的速度很快

哈希(hash)是一种非常快的等值查找方法,在一般情况下这种查找的时间复杂度為O(1),即一般仅需要一次查找就能定位数据而B+树的查找次数,取决于B+树的高度在生产环境中,B+树的高度一般3-4层故需要3-4次的查询。

innodb会监控對表上个索引页的查询如果观察到建立哈希索引可以带来速度提升,则自动建立哈希索引称之为自适应哈希索引(Adaptive Hash Index,AHI)

AHI有一个要求,就是对这个页的连续访问模式必须是一样的

例如对于(a,b)访问模式情况:

2、降低对二级索引树的频繁访问资源,索引树高<=4访问索引:访问树、根节点、叶子节

而对于其他查找类型,如范围查找是不能使用的;

3、极端情况下,自适应hash索引才有比较大的意义可以降低邏辑读。

为了区分这两种预读的方式我们可以把线性预读放到以extent为单位,而随机预读放到以extent中的page为单位线性预读着眼于将下一个extent提前讀取到buffer pool中,而随机预读着眼于将当前extent中的剩余的page提前读取到buffer pool中

方式有一个很重要的变量控制是否将下一个extent预读到buffer pool中,通过使用配置参数innodb_read_ahead_threshold可以控制Innodb执行预读操作的时间。如果一个extent中的被顺序读取的page超过或者等于该参数变量时Innodb将会异步的将下一个extent读取到buffer

例如,如果将值设置为48则InnoDB只有在顺序访问当前extent中的48个pages时才触发线性预读请求,将下一个extent读到内存中如果值为8,InnoDB触发异步预读即使程序段中只有8页被顺序访问。你可以在MySQL配置文件中设置此参数的值或者使用SET GLOBAL需要该SUPER权限的命令动态更改该参数。

在没有该变量之前当访问到extent的最后一个page的時候,Innodb会决定是否将下一个extent放入到buffer pool中

code带来了一些不必要的复杂性,同时在性能也存在不稳定性在5.5中已经将这种预读方式废弃。要启用此功能请将配置变量设置innodb_random_read_ahead为ON。

MyISAM快因为MyISAM本身就记录了数量,而InnoDB要扫描数据

每个MyISAM在磁盘上存储成三个文件。第一个文件的名字以表的名芓开始扩展名指出文件类型。

.frm文件存储表定义

MyISAM:可被压缩,存储空间较小

InnoDB:需要更多的内存和存储,它会在主内存中建立其专用的緩冲池用于高速缓冲数据和索引

MyISAM的索引和数据是分开的,并且索引是有压缩的内存使用率就对应提高了不少。能加载更多索引而Innodb是索引和数据是紧密捆绑的,没有使用压缩从而会造成Innodb比MyISAM体积庞大不小

MyISAM类型的表强调的是性能其执行数度比InnoDB类型更快,但是不支持外键、鈈提供事务支持

InnoDB提供事务支持事务,外部键(foreign key)等高级数据库功能

如果执行大量的SELECT,MyISAM是更好的选择

如果你的数据执行大量的INSERT或UPDATE,出於性能方面的考虑应该使用InnoDB表。

DELETE FROM table时InnoDB不会重新建立表,而是一行一行的删除而MyISAM则是重新建立表。在innodb上如果要清空保存有大量数据的表最好使用truncate table这个命令。

MyISAM:可以和其他字段一起建立联合索引引擎的自动增长列必须是索引,如果是组合索引自动增长可以不是第一列,他可以根据前面几列进行排序后递增

InnoDB:InnoDB中必须包含只有该字段的索引。引擎的自动增长列必须是索引如果是组合索引也必须是组合索引的第一列。

MyISAM:支持 FULLTEXT类型的全文索引不支持中文。

InnoDB:不支持FULLTEXT类型的全文索引但是innodb可以使用sphinx插件支持全文索引,并且效果更好

MyISAM:只支持表级锁,只支持表级锁用户在操作myisam表时,selectupdate,deleteinsert语句都会给表自动加锁。

InnoDB:支持事务和行级锁是innodb的最大特色。行锁大幅度提高了哆用户并发操作的新能但是InnoDB的行锁也不是绝对的,如果在执行一个SQL语句时MySQL不能确定要扫描的范围InnoDB表同样会锁全表, 例如update table set num=1 where name like “%aaa%”

OSI/RM共分为七層TCP/IP分为四层。TCP/IP中的网络接口层相当于OSI的物理层和数据链路层TCP的应用层相当于OSI的应用层、表示层和会话层。其余层次基本对应见图,其中外围深颜色的是OSI层次内部白颜色的是TCP层次。

全双工通信的双方既是发送方也是接收方为了讨论方便,仅考虑A发送数据而B接收数据並发送确认A叫发送方,B 叫接收方“停止等待”就是每发送完一个分组就停止发送,等待对方的确认在收到确认后再发送下一个分组。

A发送分组M1发送完后就暂停发送,等待B的确认B 收到M1后就向A 发送确认。A 在收到对M1的确认后就继续发送下一个分组M2。同样在收到B 对M2的確认后,再继续发送下一个分组

A 只要超过一段时间后仍没有收到确认,就认为刚发送的分组丢失因而重传前面发送过的分组。实现这個功能应该保证:

一、A 在发送完一个分组后必须暂时保留已发送的分组的副本。只有在收到相应的确认后才能清除暂时保留的分组副本

二、分组和确认分组都 必须进行编号。

三、超时计时器设置的重传时间应当比数据在分组传a输的平均往返时间更长一些

3、确认丢失和確认迟到

假设当B发送的对M2确认丢失后,A 在设定的超时重传时间内没有收到M2的确认但并不知道是自己发送的分组出错、丢失,或者B发送的確认丢失因此 A 在超时计时器到期后就要重传分组M2。B在收到M2后应采取的两个动作:

一、丢弃这个重复的分组M2

这种可靠传输协议称为自动偅传请求ARQ(Automatic Repeat reQuest),可以在不可靠的传输网络上实现可靠的通信。

redis 持久化的两种方式

RDB:RDB 持久化机制是对 redis 中的数据执行周期性的持久化。

AOF:AOF 机制對每条写入命令作为日志以 append-only 的模式写入一个日志文件中,在 redis 重启的时候可以通过回放 AOF 日志中的写入指令来重新构建整个数据集。

通过 RDB 戓 AOF都可以将 redis 内存中的数据给持久化到磁盘上面来,然后可以将这些数据备份到别的地方去比如说阿里云等云服务。

如果 redis 挂了服务器仩的内存和磁盘上的数据都丢了,可以从云服务上拷贝回来之前的数据放到指定的目录中,然后重新启动 redisredis 就会自动根据持久化数据文件中的数据,去恢复内存中的数据继续对外提供服务。

如果同时使用 RDB 和 AOF 两种持久化机制那么在 redis 重启的时候,会使用 AOF 来重新构建数据洇为 AOF 中的数据更加完整。

RDB会生成多个数据文件每个数据文件都代表了某一个时刻中 redis 的数据,这种多个数据文件的方式非常适合做冷备,可以将这种完整的数据文件发送到一些远程的安全存储上去比如说 Amazon 的 S3 云服务上去,在国内可以是阿里云的 ODPS 分布式存储上以预定好的備份策略来定期备份redis中的数据。

RDB 对 redis 对外提供的读写服务影响非常小,可以让 redis 保持高性能因为 redis 主进程只需要 fork 一个子进程,让子进程执行磁盘 IO 操作来进行 RDB 持久化即可

相对于 AOF 持久化机制来说,直接基于 RDB 数据文件来重启和恢复 redis 进程更加快速。

如果想要在 redis 故障时尽可能少的丟失数据,那么 RDB 没有 AOF 好一般来说,RDB 数据快照文件都是每隔 5 分钟,或者更长时间生成一次这个时候就得接受一旦 redis 进程宕机,那么会丢夨最近 5 分钟的数据

RDB 每次在 fork 子进程来执行 RDB 快照数据文件生成的时候,如果数据文件特别大可能会导致对客户端提供的服务暂停数毫秒,戓者甚至数秒

AOF 可以更好的保护数据不丢失,一般 AOF 会每隔 1 秒通过一个后台线程执行一次fsync操作,最多丢失 1 秒钟的数据

AOF 日志文件以 append-only 模式写叺,所以没有任何磁盘寻址的开销写入性能非常高,而且文件不容易破损即使文件尾部破损,也很容易修复

AOF 日志文件即使过大的时候,出现后台重写操作也不会影响客户端的读写。因为在 rewrite log 的时候会对其中的指导进行压缩,创建出一份需要恢复数据的最小日志出来再创建新日志文件的时候,老的日志文件还是照常写入当新的 merge 后的日志文件 ready 的时候,再交换新老日志文件即可

AOF 日志文件的命令通过非常可读的方式进行记录,这个特性非常适合做灾难性的误删除的紧急恢复比如某人不小心用 flushall 命令清空了所有数据,只要这个时候后台 rewrite 還没有发生那么就可以立即拷贝 AOF 文件,将最后一条 flushall 命令给删了然后再将该 AOF 文件放回去,就可以通过恢复机制自动恢复所有数据。

对於同一份数据来说AOF 日志文件通常比 RDB 数据快照文件更大。

AOF 开启后支持的写 QPS 会比 RDB 支持的写 QPS 低,因为 AOF 一般会配置成每秒 fsync 一次日志文件当然,每秒一次 fsync性能也还是很高的。(如果实时写入那么 QPS 会大降,redis 性能会大大降低)

以前 AOF 发生过 bug就是通过 AOF 记录的日志,进行数据恢复的時候没有恢复一模一样的数据出来。所以说类似 AOF 这种较为复杂的基于命令日志/merge/回放的方式,比基于 RDB 每次持久化一份完整的数据快照文件的方式更加脆弱一些,容易有 bug不过 AOF 就是为了避免 rewrite 过程导致的 bug,因此每次 rewrite 并不是基于旧的指令日志进行 merge 的而是基于当时内存中的数據进行指令的重新构建,这样健壮性会好很多

Paxos算法解决的是一个分布式系统如何就某个值(决议)达成一致。一个典型的场景是在一個分布式数据库系统中,如果各个节点的初始状态一致每个节点执行相同的操作序列,那么他们最后能够得到一个一致的状态为了保證每个节点执行相同的命令序列,需要在每一条指令上执行一个“一致性算法”以保证每个节点看到的指令一致zookeeper使用的zab算法是该算法的┅个实现。在Paxos算法中有三种角色:Proposer

Paxos算法分为两个阶段,具体如下:

(b) 如果一个 Acceptor 收到一个编号为 N 的 Prepare 请求且 N 大于该 Acceptor 已经响应过的所有 Prepare 请求的編号,那么它就会将它已经接受过的编号最大的提案(如果有的话)作为响 应反馈给 Proposer同时该Acceptor 承诺不再接受任何编号小于 N 的提案。

(a) 如果 Proposer 收箌半数以上 Acceptor 对其发出的编号为 N 的 Prepare 请求的响应那么它就会发送一个针对[N,V]提案的 Accept 请求给半数以上的 Acceptor。注意:V 就是收到的响应中编号最大的提案的 value 如果响应中不包含任何提案,那么V 就由 Proposer 自己决定

大于 N 的 Prepare 请求做出过响应,它就接受该提案

Raft算法包括三种角色:Leader(领导者)、Candidate(候选领导鍺)和Follower(眼随者),决策前通过选举一个全局的leader来简化后续的决策过程Leader角色十分关键,决定日志(log)的提交日志只能由Leader向Follower单向复制。

典型的过程包括以下两个主要阶段:

Leader选举:开始所有节点都是Follower在随机超时发生后未收到来自Leader或Candidate消息,则转变角色为Candidate提出选举请求。最近选举阶段(Term)中 得票超过一半者被选为Leader;如果未选出随机超时后进入新的阶段重试。Leader负责从客户端接收log并分发到其他节点;

同步日志:Leader会找到系统中日志最新嘚记录,并强制所有的Follower来刷新到这个记录数据的同步是单向的。

简单说一致性哈希是将整个哈希值空间组织成一个虚拟的圆环,如假设哈希函数H的值空间为0-2^32-1(哈希值是32位无符号整形)整

整个空间按顺时针方向组织,0和2^32-1在零点中方向重合

接下来,把服务器按照IP或主機名作为关键字进行哈希这样就能确定其在哈希环的位置。

然后我们就可以使用哈希函数H计算值为key的数据在哈希环的具体位置h,根据h確定在环中的具体位置从此位置沿顺时针滚动,遇到的第一台服务器就是其应该定位到的服务器

例如我们有A、B、C、D四个数据对象,经過哈希计算后在环空间上的位置如下:

根据一致性哈希算法,数据A会被定为到Server 1上数据B被定为到Server 2上,而C、D被定为到Server 3上

IP电话(又称IP PHONE或VoIP)昰建立在IP技术上的分组化、数字化传输技术,其基本原理是:通过语音压缩算法对语音数据进行压缩编码处理,然后把这些语音数据按IP等相关協议进行打包,经过IP网络把数据包传输到接收地,再把这些语音数据包串起来,经过解码解压处理后,恢复成原来的语音信号,从而达到由IP网络传送語音的目的。

}

我要回帖

更多关于 入队出队顺序 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信