java面试总结-分布式-题目与答案

1.分布式集群下如何做到唯一序列号

       1、 数据库自增长序列或字段

       2、UUID

       4、Redis生成ID

       5、Twitter的snowflake算法

       6、利用zookeeper生成唯一ID

2.设计一个秒杀系统,30分钟没付款就自动关闭交易

       1.我们以支付以后7天自动收货为例来说明下:

       (1)用户支付完成以后,把订单ID插入到内存的一个DelayQueue中,同时插入到Redis中。

       (2)7天之内,用户点击了确认收货,则从DelayQueue中删除,从Redis中删除。

       (3)超过7天,DelayQueue中的订单ID出队,查询数据库,改状态为自动收货,删除redis。

       (4)如果7天之内,web服务器重启过,则web服务器启动以后,从redis中读取待收货的订单,插入到DelayQueue。      

3.如何使用redis和zookeeper实现分布式锁?有什么区别优缺点,会有什么问题,分别适用什么场景

       这里利用 Redis set key 时的一个 NX 参数可以保证在这个 key 不存在的情况下写入成功。并且再加上 EX 参数可以让该 key 在超时之后自动删除。

       所以利用以上两个特性可以保证在同一时刻只会有一个进程获得锁,并且不会出现死锁(最坏的情况就是超时自动删除 key)。

       解锁也很简单,其实就是把这个 key 删掉就万事大吉了,比如使用 del key 命令。但现实往往没有那么 easy。如果进程 A 获取了锁设置了超时时间,但是由于执行周期较长导致到了超时时间之后锁就自动释放了。这时进程 B 获取了该锁执行很快就释放锁。这样就会出现进程 B 将进程 A 的锁释放了。

       所以最好的方式是在每次解锁时都需要判断锁是否是自己的。这时就需要结合加锁机制一起实现了。加锁时需要传递一个参数,将该参数作为这个 key 的 value,这样每次解锁时判断 value 是否相等即可。

       所以解锁代码就不能是简单的 del了。

4.如果有人恶意创建非法连接,怎么解决

       DDos攻击:

       分布式拒绝服务(DDoS:Distributed Denial of Service)攻击指借助于客户/服务器技术,将多个计算机联合起来作为攻击平台,对一个或多个目标发动DDoS攻击,从而成倍地提高拒绝服务攻击的威力。通常,攻击者使用一个偷窃帐号将DDoS主控程序安装在一个计算机上,在一个设定的时间主控程序将与大量代理程序通讯,代理程序已经被安装在网络上的许多计算机上。代理程序收到指令时就发动攻击。利用客户/服务器技术,主控程序能在几秒钟内激活成百上千次代理程序的运行。

       这种攻击方式可分为以下几种:

       通过使网络过载来干扰甚至阻断正常的网络通讯;

       通过向服务器提交大量请求,使服务器超负荷;

       阻断某一用户访问服务器;

       阻断某服务与特定系统或个人的通讯。

       防范:

       主机设置

       所有的主机平台都有抵御DoS的设置,总结一下,基本的有几种:

       关闭不必要的服务

       限制同时打开的Syn半连接数目

       缩短Syn半连接的time out 时间

       及时更新系统补丁

       网络设置

       网络设备可以从防火墙与路由器上考虑。这两个设备是到外界的接口设备,在进行防DDoS设置的同时,要注意一下这是以多大的效率牺牲为代价的,对你来说是否值得。

       1.防火墙

       禁止对主机的非开放服务的访问 限制同时打开的SYN最大连接数 限制特定IP地址的访问 启用防火墙的防DDoS的属性 严格限制对外开放的服务器的向外访问 第五项主要是防止自己的服务器被当做工具去害人。

       2.路由器

       设置SYN数据包流量速率 升级版本过低的ISO 为路由器建立log server

 

5.分布式事务的原理,优缺点,如何使用分布式事务,2pc 3pc 的区别,解决了哪些问题,还有哪些问题没解决,如何解决,你自己项目里涉及到分布式事务是怎么处理的。

       2pc:

java面试总结-分布式-题目与答案_第1张图片

 第一阶段:投票阶段

该阶段的主要目的在于打探数据库集群中的各个参与者是否能够正常的执行事务,具体步骤如下:

    1. 协调者向所有的参与者发送事务执行请求,并等待参与者反馈事务执行结果。

    2. 事务参与者收到请求之后,执行事务,但不提交,并记录事务日志。

    3. 参与者将自己事务执行情况反馈给协调者,同时阻塞等待协调者的后续指令。

第二阶段:事务提交阶段

在第一阶段协调者的询盘之后,各个参与者会回复自己事务的执行情况,这时候存在三种可能:

    1. 所有的参与者回复能够正常执行事务。

    2. 一个或多个参与者回复事务执行失败。

    3. 协调者等待超时。

对于第一种情况,协调者将向所有的参与者发出提交事务的通知,具体步骤如下:

    1. 协调者向各个参与者发送commit通知,请求提交事务。

    2. 参与者收到事务提交通知之后,执行commit操作,然后释放占有的资源。

    3. 参与者向协调者返回事务commit结果信息。

对于第二、三种情况,协调者均认为参与者无法正常成功执行事务,为了整个集群数据的一致性,所以要向各个参与者发送事务回滚通知,具体步骤如下:

    1. 协调者向各个参与者发送事务rollback通知,请求回滚事务。

    2. 参与者收到事务回滚通知之后,执行rollback操作,然后释放占有的资源。

    3. 参与者向协调者返回事务rollback结果信息。

两阶段提交协议解决的是分布式数据库数据强一致性问题,其原理简单,易于实现,但是缺点也是显而易见的,主要缺点如下:

  • 单点问题:协调者在整个两阶段提交过程中扮演着举足轻重的作用,一旦协调者所在服务器宕机,那么就会影响整个数据库集群的正常运行,比如在第二阶段中,如果协调者因为故障不能正常发送事务提交或回滚通知,那么参与者们将一直处于阻塞状态,整个数据库集群将无法提供服务。
  • 同步阻塞:两阶段提交执行过程中,所有的参与者都需要听从协调者的统一调度,期间处于阻塞状态而不能从事其他操作,这样效率及其低下。
  • 数据不一致性:两阶段提交协议虽然为分布式数据强一致性所设计,但仍然存在数据不一致性的可能,比如在第二阶段中,假设协调者发出了事务commit的通知,但是因为网络问题该通知仅被一部分参与者所收到并执行了commit操作,其余的参与者则因为没有收到通知一直处于阻塞状态,这时候就产生了数据的不一致性。
  • 3PC

  • 针对两阶段提交存在的问题,三阶段提交协议通过引入一个“预询盘”阶段,以及超时策略来减少整个集群的阻塞时间,提升系统性能。三阶段提交的三个阶段分别为:can_commit,pre_commit,do_commit。
  • 第一阶段:can_commit
  • 该阶段协调者会去询问各个参与者是否能够正常执行事务,参与者根据自身情况回复一个预估值,相对于真正的执行事务,这个过程是轻量的,具体步骤如下:
  • 1. 协调者向各个参与者发送事务询问通知,询问是否可以执行事务操作,并等待回复。
  • 2. 各个参与者依据自身状况回复一个预估值,如果预估自己能够正常执行事务就返回确定信息,并进入预备状态,否则返回否定信息。
  • 第二阶段:pre_commit
  • 本阶段协调者会根据第一阶段的询盘结果采取相应操作,询盘结果主要有三种:
  • 1. 所有的参与者都返回确定信息。
  • 2. 一个或多个参与者返回否定信息。
  • 3. 协调者等待超时
  • 针对第一种情况,协调者会向所有参与者发送事务执行请求,具体步骤如下:
  • 1. 协调者向所有的事务参与者发送事务执行通知。
  • 2. 参与者收到通知后,执行事务,但不提交。
  • 3. 参与者将事务执行情况返回给客户端。
  • 在上面的步骤中,如果参与者等待超时,则会中断事务。 针对第二、三种情况,协调者认为事务无法正常执行,于是向各个参与者发出abort通知,请求退出预备状态,具体步骤如下:
  • 1. 协调者向所有事务参与者发送abort通知
  • 2. 参与者收到通知后,中断事务
  • 第三阶段:do_commit
  • 如果第二阶段事务未中断,那么本阶段协调者将会依据事务执行返回的结果来决定提交或回滚事务,分为三种情况:
  • 1. 所有的参与者都能正常执行事务。
  • 2. 一个或多个参与者执行事务失败。
  • 3. 协调者等待超时。
  • 针对第一种情况,协调者向各个参与者发起事务提交请求,具体步骤如下:
  • 1. 协调者向所有参与者发送事务commit通知。
  • 2. 所有参与者在收到通知之后执行commit操作,并释放占有的资源。
  • 3. 参与者向协调者反馈事务提交结果。
  •  
  • 针对第二、三种情况,协调者认为事务无法正常执行,于是向各个参与者发送事务回滚请求,具体步骤如下:
  • 1. 协调者向所有参与者发送事务rollback通知。
  • 2. 所有参与者在收到通知之后执行rollback操作,并释放占有的资源。
  • 3. 参与者向协调者反馈事务提交结果。
  • 在本阶段如果因为协调者或网络问题,导致参与者迟迟不能收到来自协调者的commit或rollback请求,那么参与者将不会如两阶段提交中那样陷入阻塞,而是等待超时后继续commit。相对于两阶段提交虽然降低了同步阻塞,但仍然无法避免数据的不一致性。

 

6.什么是一致性hash

当用户在客户端进行请求时候,首先根据hash(用户id)计算路由规则(hash值),然后看hash值落到了hash环的那个地方,根据hash值在hash环上的位置顺时针找距离最近的ip作为路由ip.

 

7.什么是restful,讲讲你理解的restful

所以REST就是选择通过使用http协议和uri,利用client\u002Fserver model对资源进行CRUD (Create\u002FRead\u002FUpdate\u002FDelete)增删改查操

8.如何设计一个良好的API

https://www.jianshu.com/p/5c85beaec53d

9.如何设计建立和保持100w的长连接。

程序使用JAVA开发,用了Netty NIO框架。大家知道,一个JVM启动的线程数有限,也就几万,如果用传统的IO,一个连接要启动两个线程,一读一写,50万连接就是100万线程,这与JAVA虚拟机的能力相差甚远。

在测试中,服务器保持连接数与JVM内存大小直接相关,内存越大,保持连接数相应增大。在服务器启动是还增加了一些并行收集等参数。我们最后达到50万长连接时JVM的Xmx为12G。

10.解释什么是MESI协议(缓存一致性)

https://www.cnblogs.com/yanlong300/p/8986041.html

MESI代表了四种状态:

M(Modified):在缓存行中被标记为Modified的值,与主存中的值不同,这个值将会在它被读取之前写入内存,并且状态置为Shared。

E(Exclusive):在缓存行中被标记为Modified的值与主存中的值一致,被读取时置为Shared状态,被写时置为Modified状态。

S(Shared):值也可能存在于其他缓存中,但是它的值和主存中的值一致。

I(Invalid):缓存行无效。

11.说说你知道的几种HASH算法,简单的也可以

一 加法Hash

所谓的加法Hash就是把输入元素一个一个的加起来构成最后的结果。标准的加法Hash的构造如下:

 static int additiveHash(String key, int prime)

 {

  int hash, i;

  for (hash = key.length(), i = 0; i < key.length(); i++)

   hash += key.charAt(i);

  return (hash % prime);

 }

 这里的prime是任意的质数,看得出,结果的值域为[0,prime-1]。

冲突处理

冲突处理分为以下四种方式:

开放地址

再哈希

链地址

建立公共溢出区

12.什么是paxos算法,什么是zab协议。

13.一个在线文档系统,文档可以被编辑,如何防止多人同时对同一份文档进行编辑更新。

14.线上系统突然变得异常缓慢,你如何查找问题

1.检查系统是否有死锁出现:

https://blog.csdn.net/movie14/article/details/79677397

2. 代码中某个位置读取数据量较大,导致系统内存耗尽,从而导致Full GC次数过多,系统缓慢;

https://www.jianshu.com/p/27703ef3de65;

3.代码中有比较耗CPU的操作,导致CPU过高,系统运行缓慢;

4.数据库原因:

1、数据库提取数据的过程太复杂,需优化数据库。

2、看数据库有无锁死的表。

3、增加的数据量太多,SQL效率太差,可重写SQL或使用存储过程。

4、做一个statspack检查数据库的性能。

5、表的索引不完善,有大量的以非索引作为查询条件。

6、编写脚本查看系统中是否存在大量全表扫描的程序。

5.出口带宽的问题,这个很简单,加带宽,有钱就多买带宽,很简单

6.单机架构不够,需要改为分布式

7.传统数据库读写慢,改为redi这种内存型的no-sql数据库

15 如何设计一个异步系统

https://www.jianshu.com/p/9dec28eb6ee6

你可能感兴趣的:(java面试总结-分布式-题目与答案)