面试常考知识点整理_3

1、TCP三次握手、四次挥手

  • TCP:
    传输控制协议(TCP,Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议。
  • TCP三次握手过程:
    tcp三次握手.png

    开始客户端处于closed状态,服务端处于listen状态。
    第一次握手:客户端向服务端发送SYN报文(即同步标志位SYN=1),并指明客户端的初始化序列号ISN(比如seq=x),此时客户端处于SYN_SEN状态。
    第二次握手:服务端收到客户端的SYN报文,会以自己的SYN报文作为应答,并指定自己的初始化序列号ISN(比如seq=y),同时会把客户端的ISN+1作为ack的值,表示自己已经收到了客户端的SYN,此时服务端处于SYN_RCVD状态。
    第三次握手:客户端收到服务端的SYN报文之后,会发送应答报文,将服务端的ISN+1作为ack的值,此时客户端处于established状态。
    当服务端收到客户端的ACK报文后,服务端也处于established状态,此时连接正式建立。
  • 三次握手的作用:
    (1) 确认双方的接收和发送能力都是正常的。
    (2) 指定自己的初始化序列号,为以后的可靠传输做准备。
  • ISN是固定的吗?
    三次握手的一个重要功能就是客户端和服务端交换ISN,以便让对方知道接下来接收数据时如何通过序列号来组装数据。ISN不是固定不变的,攻击者很容易猜出后边的序列号,因此ISN是动态生成的。
  • 第三次握手失败会怎样?
    当服务端向客户端发送了SYN-ACK包而未收到客户端的确认,服务端会进行首次重传,当等待一段时间还是未收到,会进行第二次重传,当重传次数超过系统规定的最大重传次数,服务端会从半连接队列中删除连接信息。此时如果客户端向服务端发送数据,服务端会返回RST报文。
  • RST报文:
    RST(Reset the connection)用于复位因某种原因引起出现的错误连接,也用来拒绝非法数据和请求。
  • 半连接队列和全连接队列:
    当服务端处于SYN_RCVD状态时,会把连接信息放到半连接队列中。全连接队列用来存放已经完成三次握手的那些连接信息。
  • 三次握手中是否可以携带数据?
    第一次握手和第二次握手是不可以携带数据的,第三次握手是可以携带数据的。如果第一次握手和第二次握手可以携带数据,则服务端或客户端会花费大量的时间和内存来接收这些报文,从而造成攻击。
  • TCP四次挥手过程:
    TCP四次挥手.png

    上图以客户端主动关闭连接为例,开始客户端和服务端都处于ESTABLISED状态。
    第一次挥手:客户端发送FIN报文,并指定自己的序列号(seq=u),此时客户端处于FIN_WAIT1状态。
    第二次挥手:服务端接收到客户端的FIN报文后,会发送ACK报文,且把客户端的的序列号值加1作为ack的值,表明已经收到了客户端的报文,此时服务端处于CLOSE_WAIT状态。而客户端收到服务端的ACK报文后,处于FIN_WAIT2状态。
    第三次握手:当服务端也想断开连接,则向客户端发送FIN报文,并制定序列号值,此时服务端处于LAST_ACK 状态。
    第四次握手:当客户端收到服务端的FIN报文时,会发送ACK报文,并将服务端的序列号值加1作为ack的值,此时客户端处于TIME_WAITED状态。需要经过一段时间(一般是一个报文来回的时间)客户端才进入CLOSED状态。服务端收到客户端的ACK报文后就会进入CLOSED状态。
  • TIME_WAIT状态:客户端为什么需要等待一段时间才进入CLOSED状态?
    确保服务端已经收到了客户端的ACK报文,如果服务端没有收到客户端的确认,服务端会重新发送FIN报文给客户端,如果此时客户端立刻关闭了,则服务端会一直以为客户端没有收到FIN报文。

2、java类加载过程

  • 类加载的七个阶段:
    类从加载到虚拟机内存到卸载出虚拟机内存,包括加载、连接(验证、准备、解析)、初始化、使用、卸载七个阶段。
    类加载过程.png

    加载:根据一个类的全限定名(包名+类名)来读取此类的二进制字节流到JVM内部,将字节流代表的静态存储结构转换为方法区的运行时数据结构,转换为一个与目标类型对应的java.lang.class对象。
    验证:主要是为了确保class字节流中包含的信息是否符合当前虚拟机规范,不会危害虚拟机自身的安全。包括文件格式验证、元数据验证、字节码验证、符号验证。
    准备:为类中的所有静态变量分配内存空间,并设置初值。
    解析:将常量池中的符号引用转换成直接引用,即得到类或者字段、方法在内存中的指针或者偏移量,一遍直接调用该方法。
    初始化:根据代码逻辑为静态变量赋初值。静态变量的声明和静态代码块是按代码先后顺序执行的。
  • 类加载器:
    启动类加载器(BootStrapClassLoader):负责加载JDK中的核心类库(java.lang.*等)。
    扩展类加载器(ExtClassLoader):负责加载java的扩展类库,默认加载JAVA_HOME/jre/lib/ext/目下的所有jar。
    系统类加载器(AppClassLoader):负责加载应用程序classpath目录下的所有jar和class文件。
    用户自定义类加载器(UserClassLoader):
  • 双亲委派机制:
    当一个ClassLoader实例需要加载某个类时,会先检查是否已经加载过,如果已经加载了则直接返回,如果没有加载则递归调用父加载器去加载,如果父加载器都不能加载,则尝试自己加载。
    好处:
    (1) 避免一个类被重复加载
    (2) 确保每个类加载器只加载自己范围的类
    在JVM中如何唯一确定一个java类?
    类路径加类加载器,即使是同一个类被不同的类加载器加载,JVM也会认为是不同的类。
  • 如何打破双亲委派模型?
    (1) 继承ClassLoader类
    (2) 重写loadClass 和 findClass方法。其中loadClass实现了双亲委派机制的逻辑。即先让父加载器加载类,不行在自己加载。
  • 类什么时候会被加载?
    (1) 实例化对象时
    (2) 通过类名访问静态变量或静态方法时
    (3) 通过反射访问一个类时
  • 类什么时候会被卸载?
    (1) 该类所有的实例都已经被GC,也就是JVM中不存在该Class的任何实例。
    (2) 加载该类的ClassLoader已经被GC。
    (3) 该类的java.lang.Class 对象没有在任何地方被引用,如不能在任何地方通过反射访问该类的方法 。
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容