腾讯云后端15连问
1月5日 霸王亭投稿 前言
大家好,我是捡田螺的小男孩,最近一位朋友(6年工作经验)面了腾讯云,以下是面试题和答案。加油,一起卷。聊聊项目,好的设计,好的代码谈谈什么是零拷贝?一共有几种IO模型?NIO和多路复用的区别?Future实现阻塞等待获取结果的原理?ReentrantLock和Synchronized的区别?Synchronized的原理?聊聊AOS?ReentrantLock的实现原理?乐观锁和悲观锁,让你来写你怎么实现?Paxos协议了解?工作流程是怎么样的?B树聊一下?B树是不是有序?B树和B树的主要区别?TCP的拥塞机制工作中有过JVM实践嘛数据库分库分表的缺点是啥?分布式事务如何解决?TCC了解?RocketMQ如何保证消息的准确性和安全性?算法题:三个数求和1。聊聊项目,好的设计,好的代码
项目的话,你可以聊聊你平时做的项目,尤其有亮点的项目。如果没有什么特别亮点的项目,也可以说说一些好的设计,或者你优化了什么接口,性能提升了多少,优化了什么慢SQL都可以。甚至是一些好的代码写法都可以。
如果是讲优化接口的话,你可以看下我这篇文章哈:
记一次接口性能优化实践总结:优化接口性能的八个建议
如果是代码优化细节,可以看我这篇:
工作四年,分享50个让你代码更好的小建议
如果是慢SQL优化,可以看下我之前MySQL专栏系列文章哈:看一遍就理解:orderby详解看一遍就理解:groupby详解实战!聊聊如何解决MySQL深分页问题后端程序员必备:书写高质量SQL的30条建议阿里一面,给了几条SQL,问需要执行几次树搜索操作?生产问题分析!deletein子查询不走索引?!2。谈谈什么是零拷贝?
零拷贝是指计算机执行IO操作时,CPU不需要将数据从一个存储区域复制到另一个存储区域,从而可以减少上下文切换以及CPU的拷贝时间。它是一种IO操作优化技术。
传统IO的执行流程
传统的IO流程,包括read和write的过程。read:把数据从磁盘读取到内核缓冲区,再拷贝到用户缓冲区write:先把数据写入到socket缓冲区,最后写入网卡设备。
用户应用进程调用read函数,向操作系统发起IO调用,上下文从用户态转为内核态(切换1)DMA控制器把数据从磁盘中,读取到内核缓冲区。CPU把内核缓冲区数据,拷贝到用户应用缓冲区,上下文从内核态转为用户态(切换2),read函数返回用户应用进程通过write函数,发起IO调用,上下文从用户态转为内核态(切换3)CPU将用户缓冲区中的数据,拷贝到socket缓冲区DMA控制器把数据从socket缓冲区,拷贝到网卡设备,上下文从内核态切换回用户态(切换4),write函数返回
传统IO的读写流程,包括了4次上下文切换(4次用户态和内核态的切换),4次数据拷贝(两次CPU拷贝以及两次的DMA拷贝)。
零拷贝实现方式:
零拷贝并不是没有拷贝数据,而是减少用户态内核态的切换次数以及CPU拷贝的次数。零拷贝一般有这三种实现方式:mmapwritesendfile带有DMA收集拷贝功能的sendfile
mmapwrite
mmap就是用了虚拟内存这个特点,它将内核中的读缓冲区与用户空间的缓冲区进行映射,以减少数据拷贝次数!
用户进程通过mmap方法向操作系统内核发起IO调用,上下文从用户态切换为内核态。CPU利用DMA控制器,把数据从硬盘中拷贝到内核缓冲区。上下文从内核态切换回用户态,mmap方法返回。用户进程通过write方法向操作系统内核发起IO调用,上下文从用户态切换为内核态。CPU将内核缓冲区的数据拷贝到的socket缓冲区。CPU利用DMA控制器,把数据从socket缓冲区拷贝到网卡,上下文从内核态切换回用户态,write调用返回。
mmapwrite实现的零拷贝,IO发生了4次用户空间与内核空间的上下文切换,以及3次数据拷贝(包括了2次DMA拷贝和1次CPU拷贝)。
sendfile
sendfile表示在两个文件描述符之间传输数据,它是在操作系统内核中操作的,避免了数据从内核缓冲区和用户缓冲区之间的拷贝操作
用户进程发起sendfile系统调用,上下文(切换1)从用户态转向内核态DMA控制器,把数据从硬盘中拷贝到内核缓冲区。CPU将读缓冲区中数据拷贝到socket缓冲区DMA控制器,异步把数据从socket缓冲区拷贝到网卡,上下文(切换2)从内核态切换回用户态,sendfile调用返回。
sendfile实现的零拷贝,IO发生了2次用户空间与内核空间的上下文切换,以及3次数据拷贝。其中3次数据拷贝中,包括了2次DMA拷贝和1次CPU拷贝。
带有DMA收集拷贝功能的sendfile
linux2。4版本之后,对sendfile做了优化升级,引入SGDMA技术,其实就是对DMA拷贝加入了scattergather操作,它可以直接从内核空间缓冲区中将数据读取到网卡。使用这个特点搞零拷贝,即还可以多省去一次CPU拷贝。
用户进程发起sendfile系统调用,上下文(切换1)从用户态转向内核态DMA控制器,把数据从硬盘中拷贝到内核缓冲区。CPU把内核缓冲区中的文件描述符信息(包括内核缓冲区的内存地址和偏移量)发送到socket缓冲区DMA控制器根据文件描述符信息,直接把数据从内核缓冲区拷贝到网卡上下文(切换2)从内核态切换回用户态,sendfile调用返回。
可以发现,sendfileDMAscattergather实现的零拷贝,IO发生了2次用户空间与内核空间的上下文切换,以及2次数据拷贝。其中2次数据拷贝都是包DMA拷贝。这就是真正的零拷贝(Zerocopy)技术,全程都没有通过CPU来搬运数据,所有的数据都是通过DMA来进行传输的。
看一遍就理解:零拷贝详解3。一共有几种IO模型?NIO和多路复用的区别?
一共有五种IO模型阻塞IO模型非阻塞IO模型IO多路复用模型IO模型之信号驱动模型IO模型之异步IO(AIO)
NIO(非阻塞IO模型)
NIO,即NonBlockingIO,是非阻塞IO模型。非阻塞IO的流程如下:
应用进程向操作系统内核,发起recvfrom读取数据。操作系统内核数据没有准备好,立即返回EWOULDBLOCK错误码。应用程序进程轮询调用,继续向操作系统内核发起recvfrom读取数据。操作系统内核数据准备好了,从内核缓冲区拷贝到用户空间。完成调用,返回成功提示。
NIO(非阻塞IO模型)存在性能问题,即频繁的轮询,导致频繁的系统调用,同样会消耗大量的CPU资源。可以考虑IO复用模型去解决这个问题。
IO多路复用模型
IO多路复用就是,等到内核数据准备好了,主动通知应用进程再去进行系统调用。
IO复用模型核心思路:系统给我们提供一类函数(如我们耳濡目染的select、poll、epoll函数),它们可以同时监控多个fd的操作,任何一个返回内核数据就绪,应用进程再发起recvfrom系统调用。
IO多路复用之select
应用进程通过调用select函数,可以同时监控多个fd,在select函数监控的fd中,只要有任何一个数据状态准备就绪了,select函数就会返回可读状态,这时应用进程再发起recvfrom请求去读取数据。
非阻塞IO模型(NIO)中,需要N(N1)次轮询系统调用,然而借助select的IO多路复用模型,只需要发起一次询问就够了,大大优化了性能。
但是呢,select有几个缺点:监听的IO最大连接数有限,在Linux系统上一般为1024。select函数返回后,是通过遍历fdset,找到就绪的描述符fd。(仅知道有IO事件发生,却不知是哪几个流,所以遍历所有流)
因为存在连接数限制,所以后来又提出了poll。与select相比,poll解决了连接数限制问题。但是呢,select和poll一样,还是需要通过遍历文件描述符来获取已经就绪的socket。如果同时连接的大量客户端,在一时刻可能只有极少处于就绪状态,伴随着监视的描述符数量的增长,效率也会线性下降。
IO多路复用之epoll
为了解决selectpoll存在的问题,多路复用模型epoll诞生,它采用事件驱动来实现,流程图如下:
epoll先通过epollctl()来注册一个fd(文件描述符),一旦基于某个fd就绪时,内核会采用回调机制,迅速激活这个fd,当进程调用epollwait()时便得到通知。这里去掉了遍历文件描述符的坑爹操作,而是采用监听事件回调的机制。这就是epoll的亮点。4。Future实现阻塞等待获取结果的原理?
Future。get()用于异步结果的获取。它是阻塞的,背后原理是什么呢?
我们可以看下FutureTask的类结构图:
FutureTask实现了RunnableFuture接口,RunnableFuture继承了Runnable和Future这两个接口,对于Runnable,我们太熟悉了,那么Future呢?
Future表示一个任务的生命周期,并提供了相应的方法来判断是否已经完成或取消,以及获取任务的结果和取消任务等。publicinterfaceFutureV{booleancancel(booleanmayInterruptIfRunning);Future是否被取消booleanisCancelled();当前Future是否已结束booleanisDone();或取Future的结果值。如果当前Future还没有结束,当前线程阻塞等待,Vget()throwsInterruptedException,ExecutionE获取Future的结果值。与get()一样,不过多了超时时间设置Vget(longtimeout,TimeUnitunit)throwsInterruptedException,ExecutionException,TimeoutE}
FutureTask就是Runnable和Future的结合体,我们可以把Runnable看作生产者,Future看作消费者。而FutureTask是被这两者共享的,生产者运行run方法计算结果,消费者通过get方法获取结果。
生产者消费者模式,如果生产者数据还没准备的时候,消费者会被阻塞。当生产者数据准备好了以后会唤醒消费者继续执行。我们来看下FutureTask内部是如何实现的。
FutureTask内部维护了任务状态stateNEW新建状态,表示FutureTask新建还没开始执行privatestaticfinalintNEW0;完成状态,表示FutureTaskprivatestaticfinalintCOMPLETING1;任务正常完成,没有发生异常privatestaticfinalintNORMAL2;发生异常privatestaticfinalintEXCEPTIONAL3;取消任务privatestaticfinalintCANCELLED4;发起中断请求privatestaticfinalintINTERRUPTING5;中断请求完成privatestaticfinalintINTERRUPTED6;
生产者run方法:publicvoidrun(){如果状态state不是NEW,或者设置runner值失败,直接返回if(state!NEW!UNSAFE。compareAndSwapObject(this,runnerOffset,null,Thread。currentThread()))try{CallableVif(c!nullstateNEW){Vtry{调用callable的call方法,获取结果resultc。call();运行成功}catch(Throwableex){运行不成功设置异常setException(ex);}运行成功设置返回结果if(ran)set(result);}}finally{if(sINTERRUPTING)handlePossibleCancellationInterrupt(s);}}
消费者的get方法publicVget()throwsInterruptedException,ExecutionException{如果状态小于等于COMPLETING,表示FutureTask任务还没有完成,则调用awaitDone让当前线程等待。if(sCOMPLETING)sawaitDone(false,0L);returnreport(s);}
awaitDone做了什么事情呢?privateintawaitDone(booleantimed,longnanos)throwsInterruptedException{finallongdeadlinetimed?System。nanoTime()nanos:0L;WaitNfor(;;){如果当前线程是中断标记,则if(Thread。interrupted()){那么从列表中移除节点q,并抛出InterruptedException异常removeWaiter(q);thrownewInterruptedException();}如果状态已经完成,表示FutureTask任务已结束if(sCOMPLETING){if(q!null)q。返回}表示还有一些后序操作没有完成,那么当前线程让出执行权elseif(sCOMPLETING)cannottimeoutyetThread。yield();将当前线程阻塞等待elseif(qnull)qnewWaitNode();elseif(!queued)queuedUNSAFE。compareAndSwapObject(this,waitersOffset,q。nextwaiters,q);timed为true表示需要设置超时elseif(timed){nanosdeadlineSystem。nanoTime();if(nanos0L){removeWaiter(q);}让当前线程等待nanos时间LockSupport。parkNanos(this,nanos);}elseLockSupport。park(this);}}
当然,面试的时候,不一定要讲到源码这么细,只需要讲个大概思路就好啦。5。ReentrantLock和Synchronized的区别?Synchronized原理?
ReentrantLock和Synchronized的区别?Synchronized是依赖于JVM实现的,而ReenTrantLock是API实现的。在Synchronized优化以前,synchronized的性能是比ReenTrantLock差很多的,但是自从Synchronized引入了偏向锁,轻量级锁(自旋锁)后,两者性能就差不多了。Synchronized的使用比较方便简洁,它由编译器去保证锁的加锁和释放。而ReenTrantLock需要手工声明来加锁和释放锁,最好在finally中声明释放锁。ReentrantLock可以指定是公平锁还是公平锁。synchronized只能是公平锁。ReentrantLock可响应中断、可轮回,而Synchronized是不可以响应中断的,
至于Synchronized的原理,大家可以看我这篇文章哈
Synchronized解析如果你愿意一层一层剥开我的心6。聊聊AOS?ReentrantLock的实现原理?
AQS(抽象同步队列)的核心回答要点就是:state状态的维护。CLH队列ConditionObject通知模板方法设计模式独占与共享模式。自定义同步器。
大家可以看下我之前这篇文章哈:AQS解析与实战
大家综合ReentrantLock的功能,比如可重入,公平锁,非公平锁等,与AQS结合一起讲就好啦。7。乐观锁和悲观锁,让你来写你怎么实现?
悲观锁:
悲观锁她专一且缺乏安全感了,她的心只属于当前线程,每时每刻都担心着它心爱的数据可能被别的线程修改。因此一个线程拥有(获得)悲观锁后,其他任何线程都不能对数据进行修改啦,只能等待锁被释放才可以执行。
SQL语句select。。。forupdate就是悲观锁的一种实现还有Java的synchronized关键字也是悲观锁的一种体现
乐观锁:
乐观锁的很乐观,它认为数据的变动不会太频繁,操作时一般都不会产生并发问题。因此,它不会上锁,只是在更新数据时,再去判断其他线程在这之前有没有对数据进行过修改。实现方式:乐观锁一般会使用版本号机制或CAS算法实现。
之前业务上使用过CAS解决并发问题,大家有兴趣可以看一下哈:CAS乐观锁解决并发问题的一次实践8。Paxos协议了解?工作流程是怎么样的?8。1为什么需要Paxos算法?
当前我们应用都是集群部署的,要求所有机器状态一致。假设当前有两台机器A和B,A要把状态修改为a,B要把状态修改为b,那么应该听谁的呢?这时候可以像2PC一样,引入一个协调者,谁最先到就听谁的。
这里有个问题,就是协调者是单节点,如果它挂了呢。因为可以引入多个协调者
但是这么多协调者,应该听谁的呢?
引入Paxos算法解决这个问题,Paxos算法是一种基于消息传递的分布式一致性算法。8。2Paxos的角色
Paxos涉及三种角色,分别是Proposer、Accecptor、Learners。Proposer:它可以提出提案(Proposal),提案信息包括提案编号和提案值。Acceptor:接受接受(accept)提案。一旦接受提案,提案里面的提案值(可以用V表示)就被选定了。Learner:哪个提案被选定了,Learner就学习这个被选择的提案
一个进程可能是Proposer,也可能是Acceptor,也可能是Learner。8。2Paxos算法推导过程
一致性算法需要前置条件在这些被提出的提案中,只有一个会被选定
如果没有提案被提出,就不应该有被选定的提案当提案被选定后,learner可以学习被选中的提案
假设只有一个Acceptor,只要Acceptor接受它收到的第一个提案,就可以保证只有一个value会被选定。但是这个Acceptor宕机,会导致整个系统不可用。
如果是是多个Proposer和多个Acceptor,如何选定一个提案呢?
我们可以加个约定条件,假设就叫约束P1:一个Acceptor必须接受它收到的第一个提案。但是这样还是可能会有问题,如果每个Proposer分别提出不同的value(如下图V1,V2,V3),发给了不同的Acceptor,最后会导致不同的value被选择。
我们可以给多一个额外的约定P1a:一个提案被选定,需要被半数以上Acceptor接受。这跟P1有点矛盾啦,我们可以使用一个全局的编号来标识每一个Acceptor批准的提案,当一个具有某value值的提案被半数以上的Acceptor批准后,我们就认为该value被选定了。即提案P提案参数提案值,可以记为【M,V】。
现在可以允许多个提案被选定,但必须保证所有被选定的提案都具有相同的value值。要不然又会出现不一致啦。因此可以再加个约束P2:如果提案P〔M1,V1〕被选定了,那么所有比M1编号更高的被选定提案P,其value的值也必须是V1。
一个提案要被选定,至少要被一个Acceptor接受,因此我们可以把P2约束改成对Acceptor接受的约束P2a:如果提案P〔M1,V1〕被接受了,那么所有比M1编号更高的,且被Acceptor接受的P,其值也是V1。
多提案被选择的问题解决了,但是如果是网络不稳定或者宕机的原因,还是会有问题。
假设有5个Acceptor。Proposer2提出〔M1,V1〕的提案,Acceptor25(半数以上)均接受了该提案,于是对于Acceptor25和Proposer2来讲,它们都认为V1被选定。Acceptor1刚刚从宕机状态恢复过来(之前Acceptor1没有收到过任何提案),此时Proposer1向Acceptor1发送了〔M2,V2〕的提案(V2V1且M2M1)。对于Acceptor1来讲,这是它收到的第一个提案。根据P1(一个Acceptor必须接受它收到的第一个提案),Acceptor1必须接受该提案。同时Acceptor1认为V2被选定。
这就出现了两个问题:Acceptor1认为V2被选定,Acceptor25和Proposer2认为V1被选定。出现了不一致。V1被选定了,但是编号更高的被Acceptor1接受的提案〔M2,V2〕的value为V2,且V2V1。这就跟P2a(如果提案P〔M1,V1〕被接受了,那么所有比M1编号更高的,且被Acceptor接受的P,其值也是V1。)矛盾了。
我们要对P2a约束强化一下得到约束P2b,如果P〔M1,V1〕被选定后,任何Proposer产生的P,其值也是V1。
对于P2b中的描述,如何保证任何Proposer产生的P,其值也是V1?只要满足P2c即可:对于任意的M和V,如果提案〔M,V〕被提出,那么肯定存在一个由半数以上的Acceptor组成的集合S,满足以下两个条件中的任意一个:
要么S中每个Acceptor都没有接受过编号小于M的提案。
要么S中所有Acceptor批准的所有编号小于Mn的提案中,编号最大的那个提案的value值为Vn8。3算法流程8。3。1。Proposer生成提案Prepare请求Accept请求
在P2c约束基础上,如何生成提案呢?
Proposer选择一个新的提案编号N,向Acceptor集合S(数目在半数以上)发送请求,要求S中的每一个Acceptor做出如下响应:如果Acceptor没有接受过提案,则向Proposer保证不再接受编号小于N的提案。如果Acceptor接受过请求,则向Proposer返回已经接受过的编号小于N的编号最大的提案。
我们将这个请求称为编号为N的Prepare请求。如果Proposer收到半数以上的Acceptor响应,则生成编号为N,value为V的提案〔N,V〕,V为所有响应中编号最大的提案的value。如果Proposer收到的响应中没有提案,那么value由Proposer自己生成,生成后将此提案发给S,并期望Acceptor能接受此提案。
我们称这个请求为Accept请求8。3。2Acceptor接受提案
一个Acceptor可能会受到来自Proposer的两种请求:Prepare请求和Accept请求。Acceptor什么时候可以响应一个请求呢,它也有个约束:P1b:一个Acceptor只要尚未响应过任何编号大于N的Prepare请求,那么他就可以接受这个编号为N的提案。
Acceptor收到编号为N的Prepare请求,如果在此之前它已经响应过编号大于N的Prepare请求。由约束P1b,该Acceptor不会接受这个编号为N的提案。因此,Acceptor会忽略这个请求。
一个Acceptor只需记住两点:已接受的编号最大的提案和已响应的请求的最大编号。8。3。3Paxos算法描述
阶段一:Proposer选择一个提案编号N,然后向半数以上的Acceptor发送编号为N的Prepare请求。如果一个Acceptor收到一个编号为N的Prepare请求,且N大于该Acceptor已经响应过的所有Prepare请求的编号,那么它就会将它已经接受过的编号最大的提案(如果有的话)作为响应反馈给Proposer,同时该Acceptor承诺不再接受任何编号小于N的提案。
阶段二:如果Proposer收到半数以上Acceptor对其发出的编号为N的Prepare请求的响应,那么它就会发送一个针对〔N,V〕提案的Accept请求给半数以上的Acceptor。注意:V就是收到的响应中编号最大的提案的value,如果响应中不包含任何提案,那么V就由Proposer自己决定。如果Acceptor收到一个针对编号为N的提案的Accept请求,只要该Acceptor没有对编号大于N的Prepare请求做出过响应,它就接受该提案。8。3。4Learner学习被选定的value
9。B树是不是有序?B树和B树的主要区别?B树索引,一次查找过程?
B树是有序的。
B树和B树的主要区别?B树内部节点是保存数据的;而B树内部节点是不保存数据的,只作索引作用,它的叶子节点才保存数据。B树相邻的叶子节点之间是通过链表指针连起来的,B树却不是。查找过程中,B树在找到具体的数值以后就结束,而B树则需要通过索引找到叶子结点中的数据才结束B树中任何一个关键字出现且只出现在一个结点中,而B树可以出现多次。
假设有这么一个SQL:selectfromTemployeewhereage32;
age加个一个索引,这条SQL是如何在索引上执行的?大家可以举例子画个示意图哈,比如二级索引树,
再画出id主键索引,我们先画出聚族索引结构图,如下:
因此,这条SQL查询语句执行大概流程就是酱紫:搜索idxage索引树,将磁盘块1加载到内存,由于3237,搜索左路分支,到磁盘寻址磁盘块2。将磁盘块2加载到内存中,在内存继续遍历,找到age32的记录,取得id400。拿到id400后,回到id主键索引树。搜索id主键索引树,将磁盘块1加载内存,在内存遍历,找到了400,但是B树索引非叶子节点是不保存数据的。索引会继续搜索400的右分支,到磁盘寻址磁盘块3。将磁盘块3加载内存,在内存遍历,找到id400的记录,拿到R4这一行的数据,好的,大功告成。10。TCP怎么实现拥塞控制?
拥塞控制是作用于网络的,防止过多的数据包注入到网络中,避免出现网络负载过大的情况。它的目标主要是最大化利用网络上瓶颈链路的带宽。
实际上,拥塞控制主要有这几种常用算法慢启动拥塞避免拥塞发生快速恢复慢启动算法
慢启动算法,表面意思就是,别急慢慢来。它表示TCP建立连接完成后,一开始不要发送大量的数据,而是先探测一下网络的拥塞程度。由小到大逐渐增加拥塞窗口的大小,如果没有出现丢包,每收到一个ACK,就将拥塞窗口cwnd大小就加1(单位是MSS)。每轮次发送窗口增加一倍,呈指数增长,如果出现丢包,拥塞窗口就减半,进入拥塞避免阶段。TCP连接完成,初始化cwnd1,表明可以传一个MSS单位大小的数据。每当收到一个ACK,cwnd就加一;每当过了一个RTT,cwnd就增加一倍;呈指数让升
为了防止cwnd增长过大引起网络拥塞,还需设置一个慢启动阀值ssthresh(slowstartthreshold)状态变量。当cwnd到达该阀值后,就好像水管被关小了水龙头一样,减少拥塞状态。即当cwndssthresh时,进入了拥塞避免算法。拥塞避免算法
一般来说,慢启动阀值ssthresh是65535字节,cwnd到达慢启动阀值后每收到一个ACK时,cwndcwnd1cwnd当每过一个RTT时,cwndcwnd1
显然这是一个线性上升的算法,避免过快导致网络拥塞问题。
拥塞发生
当网络拥塞发生丢包时,会有两种情况:RTO超时重传快速重传
如果是发生了RTO超时重传,就会使用拥塞发生算法慢启动阀值sshthreshcwnd2cwnd重置为1进入新的慢启动过程
这真的是辛辛苦苦几十年,一朝回到解放前。其实还有更好的处理方式,就是快速重传。发送方收到3个连续重复的ACK时,就会快速地重传,不必等待RTO超时再重传。
image。png
慢启动阀值ssthresh和cwnd变化如下:拥塞窗口大小cwndcwnd2慢启动阀值ssthreshcwnd进入快速恢复算法快速恢复
快速重传和快速恢复算法一般同时使用。快速恢复算法认为,还有3个重复ACK收到,说明网络也没那么糟糕,所以没有必要像RTO超时那么强烈。
正如前面所说,进入快速恢复之前,cwnd和sshthresh已被更新:cwndcwnd2sshthreshcwnd
然后,真正的快速算法如下:cwndsshthresh3重传重复的那几个ACK(即丢失的那几个数据包)如果再收到重复的ACK,那么cwndcwnd1如果收到新数据的ACK后,cwndsshthresh。因为收到新数据的ACK,表明恢复过程已经结束,可以再次进入了拥塞避免的算法了。
11。JVM调优11。1一般什么时候考虑JVM调优呢?Heap内存(老年代)持续上涨达到设置的最大内存值;FullGC次数频繁;GC停顿时间过长(超过1秒);应用出现OutOfMemory等内存异常;应用中有使用本地缓存且占用大量内存空间;系统吞吐量与响应性能不高或下降。11。2JVM调优的目标延迟:GC低停顿和GC低频率;低内存占用;高吞吐量;11。3JVM调优量化目标Heap内存使用率70;Oldgeneration内存使用率70;avgpause1秒;Fullgc次数0或avgpauseinterval24小时;11。4JVM调优的步骤分析GC日志及dump文件,判断是否需要优化,确定瓶颈问题点;确定JVM调优量化目标;确定JVM调优参数(根据历史JVM参数来调整);依次调优内存、延迟、吞吐量等指标;对比观察调优前后的差异;不断的分析和调整,直到找到合适的JVM参数配置;找到最合适的参数,将这些参数应用到所有服务器,并进行后续跟踪。11。5常见的JVM参数
堆栈配置相关Xmx3550mXms3550mXmn2gXss128kXX:MaxPermSize16mXX:NewRatio4XX:SurvivorRatio4XX:MaxTenuringThreshold0Xmx3550m:最大堆大小为3550m。Xms3550m:设置初始堆大小为3550m。Xmn2g:设置年轻代大小为2g。Xss128k:每个线程的堆栈大小为128k。XX:MaxPermSize:设置持久代大小为16mXX:NewRatio4:设置年轻代(包括Eden和两个Survivor区)与年老代的比值(除去持久代)。XX:SurvivorRatio4:设置年轻代中Eden区与Survivor区的大小比值。设置为4,则两个Survivor区与一个Eden区的比值为2:4,一个Survivor区占整个年轻代的16XX:MaxTenuringThreshold0:设置垃圾最大年龄。如果设置为0的话,则年轻代对象不经过Survivor区,直接进入年老代。
垃圾收集器相关XX:UseParallelGCXX:ParallelGCThreads20XX:UseConcMarkSweepGCXX:CMSFullGCsBeforeCompaction5XX:UseCMSCompactAtFullCollection:XX:UseConcMarkSweepGCXX:UseParallelGC:选择垃圾收集器为并行收集器。XX:ParallelGCThreads20:配置并行收集器的线程数XX:UseConcMarkSweepGC:设置年老代为并发收集。XX:CMSFullGCsBeforeCompaction:由于并发收集器不对内存空间进行压缩、整理,所以运行一段时间以后会产生碎片,使得运行效率降低。此值设置运行多少次GC以后对内存空间进行压缩、整理。XX:UseCMSCompactAtFullCollection:打开对年老代的压缩。可能会影响性能,但是可以消除碎片XX:UseConcMarkSweepGC使用CMS垃圾收集器
辅助信息XX:PrintGCXX:PrintGCDetails11。6常用调优策略选择合适的垃圾回收器调整内存大小(垃圾收集频率非常频繁,如果是内存太小,可适当调整内存大小)调整内存区域大小比率(某一个区域的GC频繁,其他都正常。)调整对象升老年代的年龄(老年代频繁GC,每次回收的对象很多。)调整大对象的标准(老年代频繁GC,每次回收的对象很多,而且单个对象的体积都比较大。)调整GC的触发时机(CMS,G1经常FullGC,程序卡顿严重。)调整JVM本地内存大小(GC的次数、时间和回收的对象都正常,堆内存空间充足,但是报OOM)12。数据库分库分表的缺点是啥?事务问题,已经不可以用本地事务了,需要用分布式事务。跨节点Join的问题:解决这一问题可以分两次查询实现跨节点的count,orderby,groupby以及聚合函数问题:分别在各个节点上得到结果后在应用程序端进行合并。ID问题:数据库被切分后,不能再依赖数据库自身的主键生成机制啦,最简单可以考虑UUID跨分片的排序分页问题(后台加大pagesize处理?)13。分布式事务如何解决?TCC了解?
分布式事务:
就是指事务的参与者、支持事务的服务器、资源服务器以及事务管理器分别位于不同的分布式系统的不同节点之上。简单来说,分布式事务指的就是分布式系统中的事务,它的存在就是为了保证不同数据库节点的数据一致性。
聊到分布式事务,需要知道这两个基本理论哈。CAP理论BASE理论
CAP理论一致性(C:Consistency):一致性是指数据在多个副本之间能否保持一致的特性。例如一个数据在某个分区节点更新之后,在其他分区节点读出来的数据也是更新之后的数据。可用性(A:Availability):可用性是指系统提供的服务必须一直处于可用的状态,对于用户的每一个操作请求总是能够在有限的时间内返回结果。这里的重点是有限时间内和返回结果。分区容错性(P:Partitiontolerance):分布式系统在遇到任何网络分区故障的时候,仍然需要能够保证对外提供满足一致性和可用性的服务。
BASE理论
它是对CAP中AP的一个扩展,对于我们的业务系统,我们考虑牺牲一致性来换取系统的可用性和分区容错性。BASE是BasicallyAvailable,Softstate,和Eventuallyconsistent三个短语的缩写。BasicallyAvailable(基本可用):通过支持局部故障而不是系统全局故障来实现的。如将用户分区在5个数据库服务器上,一个用户数据库的故障只影响这台特定主机那20的用户,其他用户不受影响。SoftState(软状态):状态可以有一段时间不同步EventuallyConsistent(最终一致):最终数据是一致的就可以了,而不是时时保持强一致。
分布式事务的几种解决方案:2PC(二阶段提交)方案、3PCTCC(Try、Confirm、Cancel)本地消息表最大努力通知seata事务
TCC(补偿机制)
TCC采用了补偿机制,其核心思想是:针对每个操作,都要注册一个与其对应的确认和补偿(撤销)操作。TCC(TryConfirmCancel)包括三段流程:try阶段:尝试去执行,完成所有业务的一致性检查,预留必须的业务资源。Confirm阶段:该阶段对业务进行确认提交,不做任何检查,因为try阶段已经检查过了,默认Confirm阶段是不会出错的。Cancel阶段:若业务执行失败,则进入该阶段,它会释放try阶段占用的所有业务资源,并回滚Confirm阶段执行的所有操作。
下面再拿用户下单购买礼物作为例子来模拟TCC实现分布式事务的过程:
假设用户A余额为100金币,拥有的礼物为5朵。A花了10个金币,下订单,购买10朵玫瑰。余额、订单、礼物都在不同数据库。
TCC的Try阶段:生成一条订单记录,订单状态为待确认。将用户A的账户金币中余额更新为90,冻结金币为10(预留业务资源)将用户的礼物数量为5,预增加数量为10。Try成功之后,便进入Confirm阶段Try过程发生任何异常,均进入Cancel阶段
TCC的Confirm阶段:订单状态更新为已支付更新用户余额为90,可冻结为0用户礼物数量更新为15,预增加为0Confirm过程发生任何异常,均进入Cancel阶段Confirm过程执行成功,则该事务结束
TCC的Cancel阶段:修改订单状态为已取消更新用户余额回100更新用户礼物数量为5
TCC的优点是可以自定义数据库操作的粒度,降低了锁冲突,可以提升性能TCC的缺点是应用侵入性强,需要根据网络、系统故障等不同失败原因实现不同的回滚策略,实现难度大,一般借助TCC开源框架,ByteTCC,TCCtransaction,Himly。
大家有兴趣可以看下我之前这篇文章哈:
后端程序员必备:分布式事务基础篇14,RocketMQ如何保证消息的准确性和安全性?
我个人理解的话,这道题换汤不换药,就是为如何保证RocketMQ不丢消息,保证不重复消费,消息有序性,消息堆积的处理。
消息不丢失的话,即从生产者、存储端、消费端去考虑
大家可以看下我之前这篇文章哈:
消息队列经典十连问15。三个数求和
给你一个包含n个整数的数组nums,判断nums中是否存在三个元素a,b,c,使得abc0?请你找出所有和为0且不重复的三元组。
注意:答案中不可以包含重复的三元组
实例1:输入:nums〔1,0,1,2,1,4〕输出:〔〔1,1,2〕,〔1,0,1〕〕
实例2:输入:nums〔0〕输出:〔〕
思路:
这道题可以先给数组排序,接着用左右双指针。
完整代码如下:classSolution{publicListListIntegerthreeSum(int〔〕nums){ListListIntegerresultnewLinkedList();if(numsnullnums。length3){为空或者元素个数小于3,直接返回}Arrays。sort(nums);排序for(inti0;inums。length2;i){遍历到倒数第三个,因为是三个数总和if(nums〔i〕0){大于0可以直接跳出循环了}if(i0nums〔i〕nums〔i1〕){过滤重复}intlefti1;左指针intrightnums。length1;右指针inttargetnums〔i〕;目标总和,是第i个的取反,也就是abc0,则bca即可while(leftright){if(nums〔left〕nums〔right〕target){bca,满足abc0result。add(Arrays。asList(nums〔i〕,nums〔left〕,nums〔right〕));左指针右移右指针左移while(leftrightnums〔left〕nums〔left1〕)继续左边过滤重复while(leftrightnums〔right〕nums〔right1〕)继续右边过滤重复}elseif(nums〔left〕nums〔right〕target){小于目标值,需要右移,因为排好序是从小到大的}else{}}}}}来源:https:mp。weixin。qq。comsaMYJODhtWsBt9CTJxySQEQ
投诉 评论 两难境地,苹果正在遭遇冲击,拥抱印度市场,不如服务学小米11智能手机市场这几年持续下滑,在产品同质化的创新乏力的当下,曾经一度以创新驱动的苹果也没能独善其身。多年在产品外观上几乎没有新变化的iphone,在大中华市场原本一枝独秀,但是随……
马龙携手五将晋级十六强,14号中日战两场,莎莎一日双赛WTT乒乓球大满贯结束了13日全部比赛,国乒共取得六胜两负,其中只有小将林诗栋是输掉了外战,蒯曼则是不敌莎莎,两位小将虽早早止步,但整体发挥令人满意,像蒯曼首轮就轻取名将冯天薇……
读刘子超的旅行文学(2)读刘子超的旅行文学(2)无论去哪,这都是一本。可以毫不犹豫,放进背囊的书。并非游记指南,只让你在旅程中,离自己的内心更近。刘子超再度沿着季风的方向出发,前往南亚腹地……
刘强东背后的三个女人除了章泽天,另外两个也是京东的贵人文鉴史人编辑Q前几天,京东收购德邦快递的消息在资本圈掀起了一阵浪潮。京东正式接手德邦,这也就意味着京东德邦达达的京邦达局面正式形成,无疑是对京东的发展起到至关重要的……
又一款开源中文编程语言气出品开源中国作者局长本文将介绍的气语言是一种轻量级、快速、开源的中文编程语言。气的英文名Qi从拼音衍生而来,气包含了空气的意思,作者表示希望这种语言能够快速、……
昆凌孕期与好友小聚,怀孕6个月发福明显,脸圆一圈孕肚超抢镜2月27日,周杰伦爱妻昆凌在个人社交平台转发了一张和好友小聚的照片,虽然没有配上任何文字,但她的好心情已经一览无余了。晒出的照片里,昆凌坐在两位好友中间。已经怀孕6个月左……
春敏来袭,这个春天不做敏感肌春季风和日丽,万物复苏,但是这个令人愉悦的季节却给肌肤带来了挑战春季敏感。即将到来的三月是春敏高发季,空气中的尘螨,花粉,柳絮都容易让脸蛋面临着红,肿,干,痒等肌肤问题。尤其是……
07年火箭20领先爵士,为何最后被翻盘?麦迪姚明防不住布泽尔麦迪认为,07年季后赛火箭在2比0的领先情况下,被爵士翻盘的主要原因是姚明防不住布泽尔,甚至在第六场比赛的时候,布泽尔一个人为爵士贡献了35分,而且姚明的防守也是非常不到位的,……
腾讯云后端15连问前言大家好,我是捡田螺的小男孩,最近一位朋友(6年工作经验)面了腾讯云,以下是面试题和答案。加油,一起卷。聊聊项目,好的设计,好的代码谈谈什么是零拷贝?一共有几种IO模型……
刘志超大美新疆雅丹地貌之奇新疆是个好地方这句充满家国情怀的历史名言,早已由国人延伸于世人的用语和向往之地。人们所体验到的不仅仅是大漠戈壁、雪域碧水、风土人情的赞美,还有新疆亿万年经大自然风雨洗礼、千锤百……
国乒洗牌!WTT新加坡大满贯未结束,但两大世界冠军提前淘汰出目前,WTT新加坡大满贯的比赛正在火热进行中,国乒选手们总的来说发挥很稳定,可圈可点!但是,也有冷门出现,两大世界冠军遭到淘汰出局,或将影响未来在队内的位置,经过这一次比赛,国……
国足公布西征名单归化仅蒋光太入围,吴曦领衔戴伟浚在列结束了和U23国足的热身赛之后,国足也确定了最后2轮12强赛的参赛名单。3月24日,国足将在中立场地阿联酋沙迦迎战沙特,3月29日的末轮比赛,国足将做客面对阿曼。根据安排,国足……
摩托罗拉motoX30Pro真机曝光,后摄2亿像素主摄镜头摩托罗拉将会在8月2日召开新品发布会,一次性发布两款旗舰手机,分别是首款2亿像素的motoX30Pro以及折叠屏手机motorazr2022。近日,motoX30Pro的真机渲……
城建规划局办公室主任述职述廉报告精选多篇第一篇:城建规划局办公室主任述职述廉报告各位领导、同志们:2014年是我市率先发展的决战之年,也是我们面对繁重工作任务,不断接受挑战和自我加压的一年。作为办公室主任……
如何赢回一个女生在本文中:让她再次渴望你展示给她看你改变是如此的大制造感动赢回一个女生的心要比吸引一个新的女生的注意难得多,但是如果你真的想和你的旧情人旧情复燃,再难也是值得的。无论你是……
狮子鱼是什么颜色会变色吗狮子鱼是会变色的。它们一般生活在珊瑚附近,身体的颜色和珊瑚很像。当环境的颜色发生改变的时候,它们的颜色也会发生改变。这种变色能力是非常实用的,不仅能让狮子鱼更好地保护自己,同时……
透透气高中时,一生物老师言行举止,穿着打扮特随便,很不合同学味口。每每轮他上课时,教室里就乱了。一天该老师又穿着背心短裤光着脚来上课,全身还充满粪臭味,估计又浇菜了。(外表纯农民一个……
GTA6或将迎来第一个女性可控角色,灵感来自美国的鸳鸯大盗据外媒透露,正在开发的新作《GTA6》将迎来女主角的首次登场,玩家将在以迈阿密为背景的虚构新地图上冒险。RockstarGames旗下的知名系列《GTA5》自2013年发……
10个词送给不甘平庸的你来源:人民日报转眼,2022年已过半,年初许下的愿望都实现了吗?无论过去如何,未来都是崭新的。分享提升自己的10个词,起身行动,以最好的状态开启下半年。行动怨……
吃鸡光子放大招?7级圣装8个提车币的黄金跑车长这样欢迎诸位小伙伴来到天哥开讲的吃鸡小课堂熟悉吃鸡游戏的老玩家们都知道,《和平精英》与PubgM一脉相承,无论是玩法、地图,还是皮肤,两者之间经常会同步还原。所以当《和平精英……
用直觉去做考试中的选择题真的靠谱吗考试中如何做选择题?译者:黄晓婷丨壹心理翻译专栏ForPsy。经常在做决定的时候听人说:相信你的直觉。但是直觉作出的真的是最佳选择吗?心理学研究显示,直觉并不……
月第二周规则变动汇总8月第二周规则变动汇总:1。卖家承诺赠品,但赠品延迟发货也要进行赔付;2。淘宝直播平台管理规范变正式出台;3。淘宝汇吃管理规则出台,想要淘宝二楼的卖家要仔细看……
心脑血管病病发前十大警号,出现这些症状,说明它正在盯着你心脑血管病是一个大的概念,在我国如果心脑血管病放在一起,它的患病率是第一位的,涉及到心血管系统和脑血管系统,在脑血管病当中主要表现的是缺血性卒中和出血性的卒中。再有一个在心血管……
隧道二衬防水有哪些措施初衬完全受力,等围岩变形稳定、初支完全受力的情况下再施作二衬,这种方法也是一般理论和现阶段最流行的说法。初衬与二衬共同受力,这种说法基于围岩压力特大以及一些特殊围岩的特殊处理时……