目录
(4)为什么A还要发送一次确认呢?可以二次握手呢?(半连接攻击)
(8)JAVA异常的层次结构、可查异常 、不可查异常(运行时异常和错误)
(9)finally块一定会执行么?try catch finally执行顺序
(1)什么是分布式系统?
- 分布式系统是一个硬件或软件组件分布在不同的网络计算机上,彼此之间仅仅通过消息传递进行通信和协调的系统。
套用网络上一种解释分布式与集群的关系:将一个系统比喻成一个厨房,这个时候的厨房只有一个师傅,负责洗菜,切菜、烧菜、刷锅等。有一天这个厨房不再是一个厨师了,这个厨师只去烧菜了,另外的来了个打杂负责刷锅,来了助手负责洗菜、切菜那么分布式也就形成了。再后来这个厨房来个好几个厨师一起负责烧菜烹饪,这就是一个集群的开始。
(2)分布式系统你会考虑哪些方面?
异构性:分布式系统由于基于不同的网络,操作系统、计算机硬件和编程语言来构造,必须要考虑一种通用的网络通信协议来屏蔽异构系统之间的差异。一般交由中间件来处理这些差异。
全球时钟:在程序需要协作时,他们通过交换消息来协调他们的动作,紧密的协调经常依赖于对于程序动作发生事件的共识,但是,实际上网络上计算机同步时钟的准确性收到极大的限制,没有一个正确时间的全局概念。这是通过网络发送消息作为唯一的通信方式这一事实带来的直接结果。
一致性:数据被分散或者复制到不同的机器上,如何保证各台主机之间的数据一致性将成为一个难点。
故障的独立性:任何计算机都有可能故障,且各种故障不尽相同。他们之间出现故障的时机也是互相独立的。一般分布式系统要设计成被允许出现部分故障而不影响整个系统的正常使用。(影响降低到最小)
并发:分布式系统的目的,是为了更好共享资源。那么系统中的每个资源都必须设计成这个并发环境中是安全的。
开发性:分布式系统由不同的程序员来编写不同的组件,组件最终要组成一个系统,那么组件的接口必须遵守一定的规范,并且是要求被容易理解的。
安全性:需要给共享资源提供适当的保护,在网络上传递的敏感数据也需要加密。
可扩展性:系统要设计成锁着业务量的增加,相应的系统也必须要扩展来提供对应的服务。
(3)TCP三次握手的过程
第一次握手:起初 两端都处于Close关闭状态,Client将标志位SYN置为1,随机产生一个seq=x,并将数据包发送给Server,Client进入SYN-SENT状态,等待Server确认。
第二次握手:Server收到数据包后由标志位SYN-1得知Client请求建立连接,Server将标志位SYN和ACK都置为1,ack=x+1.随机产生一个值seq=y。并将该数据包发送给client以确认连接请求,Server进入SYN-RCVD状态,此时操作系统为该TCP连接分配TCP缓存和变量。
第三次握手:Client收到确认后,检查ack是否为x+1。ACK是否为1,如果正确将ACK标志置为1,ack=y+1,ACK是否为1,如果正确则连接建立成功,Client和Server进入ESTABLISHED状态,完成三次握手后就可以开始数据传输。
过程就是:起初A与B都处于close状态,这时候B server创建了TCP,处于listen状态---------------等待A请求,A创建TCP,发送请求连接(SYN=1,seq=x),进入SYN-SENT状态,---------------------B收到连接请求,向A发送确认(SYN=ACK=1,确认号ack=x+1,初始序号seq=y),进入SYN-REVD状态-------------A收到B的确认后,给B发出确认(ACK=1,ack=y+1,seq=x+1),A进入ESTABLISHED状态,B收到确认后,进入ESTABLISTHED状态。
(4)为什么A还要发送一次确认呢?可以二次握手呢?(半连接攻击)
主要是为了防止已失效的连接请求报文突然又传送到了B,因而产生错误。如A发出连接请求,但因连接请求报文丢失而未收到确认,于是A再重传一次请求连接,后来收到确认,建立连接。数据传输完毕后,就释放了连接,A发出两个连接请求报文,其中一个丢失,第二个到达B,但是第一个丢失的报文段只是在某些网络节点长时间停滞,延误了连接释放后的某个阶段才到达B。如果不是三次握手,只要B发出确认就建立连接,此时A不理睬B的确认且不发送数据,那么会浪费资源。
半连接攻击:其实SYN半连接攻击的攻击点就是在这一部分,服务端的资源分配是在第二次握手时分配的,而客户端的资源是在完成三次握手时分配的,所以服务器容易收到SYN泛洪攻击,SYN攻击就是在client短时间伪造大量不存在的IP地址,并向Server不断发送SYN包,Server恢复确认包,并且等待Client确认,由于原地址不存在,因此Server需要不断重发直至超时,这些伪造的SYN包将长时间占用半连接队列,导致正常的syn请求因为对象满而丢弃,从而引起网络拥塞甚至瘫痪。
防范SYN攻击措施,降低主机的等待时间使主机尽快释放半连接占用,短时间收到某IP的重复SYN则丢弃后续请求。
(5)TCP四次挥手过程
假设Client端发起终端连接请求,也就是Fin报文。Server端接到Fin报文后,意思是说“我Client端没有数据要发给你”但是如果你还有数据没有发送完成,则不着急关闭socket,可以继续发送数据,所以你先发送ACK告诉Client端,你的请求我收到了,但是我还没准备好,请你继续等待我的消息。Client此时进入FIN_WAIT状态,继续等待Server的FIN报文。当Server端确定数据已发送完成,则向Client端发送Fin报文,告诉Client端好了我们这边数据发送完了。CLient收到Fin报文后就知道可以关闭了。但他还似乎还是不相信网络,怕Server不知道关闭,处于TIME_WAIT转台,如果Server端没有收到ACK就会重传,如果Server端收到ACK就可以断开连接了。Client端等待2MSL后依旧没有收到回复,Server端已正常关闭,那么client也会开始关闭。
过程就是:起初AB处于ESTABLISHED状态——A发出连接释放报文段并处于FIN-WAIT-1状态——B发出确认报文且进出CLOSE-WAIT状态——A收到确认后,进入FIN-WAIT-2状态,等待B连接释放报文段——B没有向A发送的数据,B发出连接释放进入LAST-ACK状态——A发出确认报文且进入TIME-WAIT状态——B收到确认报文后进入CLOSE状态——A经过等待时间计时器2MSL后,就会进入CLose状态
为什么A在TIME-WAIT状态必须等待2MSL的时间?1、保证A发送的最后一个ACK报文能够到达B,若没有续传2、防止之前“以失效的连接请求报文段”出现在本连接中。
(6)为什么连接的时候三次握手,关闭的时候确是四次握手?
因为Server端收到Client端的SYN请求报文后,可以直接发送SYN-ACK报文,但是ACK报文使用响应应答的,SYN报文是用来同步的,但是关闭连接时,当Server端收到Fin报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,“你发的Fin报文我收到了”。只有等到我Server端所有报文都发送完了,我才能发送到Fin报文,因此不能一起发送。
之前看过网上这么一段比喻来形容三次握手和四次握手:大致是这样的希望加深印象:
三次握手就像是A给B打电话: A“你在么” B“我在啊” A“那我开始说了啊” 这就是大致三次握手的描述
四次挥手呢 就像是A去挂B的电话 A“我有事啊,我想挂了” B“好的,那行我把这段说完” B“我一会要吃KFC和C一起” A“拜拜,您走好”
(7)什么是DoS、DDoS、DRDoS攻击?如何防御?
DOS是拒绝服务,造成Dos的攻击行为被称为DOS攻击,其目的使计算机或网络无法提供正常服务。最正常的DoS攻击有计算机网络带宽攻击和连通性攻击。(这是一个单挑的攻击,一般一对一攻击,加入你的机器每秒能够发送10个攻击数据包,而你的对手的机器每秒只能处理8个数据,那么对手的电脑就死了)
DDOS分布式拒绝服务就是类似于群殴,这是DDoS攻击,原理说白了就是群殴,通过自己的电脑控制网络上占领的“肉鸡”控制这些肉鸡发起DDos,这样扩大发起攻击的点。
DRDOS分布反射式拒绝服务:是DDoS攻击的变形,它与DDoS的不同之处就是DRDoS需要在攻击之前需要占领大量的肉鸡,攻击原理和Smurf攻击原理相近,不过DRDoS可以再广域网上进行的,而Smurf攻击在局域网进行的,他的作用原理是基于广播地址与回应请求的。DRDOS攻击正是利用这个原理,黑盒利用同样的特殊的发包工具,首先把伪造了源地址的SYN连接请求包发送到哪些被欺骗的计算机上,根据TCP三次握手,这些计算机向源IP发出SYN+ACK或者RST来响应这个请求。同Smurf攻击一样,黑客所发送请求包的源IP地址是被攻击主机的地址,这样收欺骗的主机就会把回应发送到被攻击处。(模拟受攻击的主机IP向其他机器发送请求形成一个反射)
(8)JAVA异常的层次结构、可查异常 、不可查异常(运行时异常和错误)
JAVA中所有的异常都有一个共同的祖先Throwable(可抛出),Throwable指定代码中可用的异常传播机制通过java应用程序传输的任何问题的共性。异常只不期而至的各种情况。
Throwable:有两个重要的子类Exception(异常)和Error(错误),二者都是Java异常处理的重要子类,鸽子都包含大量子类。
(一)Error:是程序无法处理的错误,表示运行应用程序中比较严重的问题,程序本身无法解决,大多数错误与代码编写执行的操作无关,而表示代码运行时JVM出现的问题,例如Java虚拟机运行错误,当JVM不在有继续执行操作锁需要的内存时,就会出现OutOfMemoryError,这些异常发生时,Java虚拟机一般会选择线程终止。
(二)Exception(异常):是程序本身可以处理的异常。RuntimeException类以及子类表示“JVM常用操作”发生的错误,例如视图使用空值对象异常、除数为零或数组越界。则分别引发运行时异常ArrayIndexOutOfBoundException。
异常和错误的区别:异常能够被自身所处理,错误是无法处理的。
(第二种分类方法)通常异常分为可查异常(checked exception)和不可查异常(uncheck exceptions) 。
可查异常(要求编译器必须处置的异常):正确的程序在运行中,很容易出现的,情理可容的异常情况。可查异常虽然是异常状况,但在一定程度上它的发生时可以预计的,而且一旦发生这种异常状况,就必须采取某种方式进行处理。这种可查异常要么用try-catch语句捕获它,要么用throws语句声明抛出,否则编译不会通过。
非运行时异常(编译异常):在Exception中除了RuntimeException其他都是可查异常,类型上都属于Exception类及其子类,从程序语法角度来讲是必须处理的异常,如果不处理,程序就不编译通过。如IOException SQLException以及用户自定义的Exception异常。
不可查异常(编译器不要求强制处置的异常):1、包括运行时异常(RuntimeException与其子类)或2、错误(Error),
运行时异常:都是RuntimeException类及其子类异常,如NullPointerException空指针异常,这些异常是不检查异常,程序中可以选择捕获处理,也可以不处理,这些异常通常是程序逻辑运行错误引起的,尽量从逻辑角度避免这类异常的发生。运行时异常的特点是这些异常不是检查异常,程序中药选择捕获处理,也可以不出。程序应该从逻辑角度尽可能避免这类异常的发生。
异常的处理机制:异常的处理机制:抛出异常和捕捉异常。
抛出异常:当一个方法出现错误异常,方法创建对象交付运行时的系统,异常对象中包含了异常类型和异常出现时的程序状态等异常信息。运行时系统负责寻找异常的代码并运行。(throws语句)
捕获异常:在方法抛出异常之后,运行时系统将转为寻找合适的异常处理器(exception handler)潜在的异常处理器是异常发生时依次留在调用栈中的方法的集合。当异常处理器所能处理的异常类型与方法抛出的异常相符时,即为合适的异常处理器。当运行时系统遍历栈而未找到合适的异常处理器,则运行时系统中依次调用栈中的方法,知道找到含有合适异常处理器的方法并执行,当运行时系统遍历调用栈而未找到合适异常处理,则运行时系统终止,同时意味着java程序终止。(try-catch-finally)
总的来说 java规定对于可查异常必须捕捉或者声明抛出,允许忽略不可查的RuntimeException和Error。
(9)finally块一定会执行么?try catch finally执行顺序
例如一个try{}中包含了一个return语句,那么紧跟这个try{}后面finally语句中代码是否会执行,如果会什么时候被执行,是return前还是return后。就这么写吧。如下:答案是会被执行首先打印execute finally,后面再return1.也就是说限制finally再return
-
try {
-
return 1;
-
} catch (Exception e) {
-
return 0;
-
}finally{
-
System.out.println("execute finally");
-
}
再Java异常处理中,finally块的作用就是为了保护无论出现什么情况,finally块里代码一定会被执行。由于程序执行return就意味着结束当前函数的调用并跳出这个函数体,因此任何语句都只在return前执行(除非碰到exit函数),因此finally块里面的代码就是return之前执行的,此外如果try-finally或者catch-finally中都有return。那么finally语句中return会覆盖别处的return。