面试知识点

121 阅读3分钟

1.Java

1.1 IO:

Blocking IO(阻塞IO)、Non Blocking(非阻塞IO)、IO多路复用、信号驱动IO、AIO(异步IO)

  • 传统IO

传统IO读取数据需要经过:从磁盘等外部设备将数据拷贝到内核空间,在再从内核空间拷贝到用户线程;
同样,IO写数据需要经过:从用户线程空间拷贝到内核空间,再从内核空间到磁盘等外部设备。数据的读写都需要至少两次拷贝

在此过程中,涉及到4次用户线程/内核线程和内核态/用户态的切换

  • NIO零拷贝

改进:a. 数据拷贝减少到3次 b. 内核态与用户态的切换减少为2次

  • Selector

  • Epoll

  • Reactor:是大多数IO相关组件如Netty、Redis在使用的IO模式,常见的Reactor有三类:

    • 单线程模型

    acceptor作为新连接的接受者,handler负责处理各个网络连接,它们都在一个线程中执行。看起来线程数很少,很高效,但是这个模型的缺陷是其中某个handler阻塞会导致其他所有的client的handler都得不到执行,并且更严重的问题是,当N个handler长时间阻塞,会导致整个服务不能接收新的外部请求(因为acceptor也被阻塞了)。因此单线程Reactor模型用的比较少。

    • 多线程模型

    多线程模型与单线程模型的区别是多线程reactor模型的acceptor是一个单独的线程,即Acceptor线程只用于监听客户端连接请求。具体的处理工作交给一组特定的NIO线程来负责各个客户端连接的I/O操作,每个客户端连接都与一个NIO线程绑定,因此在这个客户端连接中的所有I/O操作都是在同一个线程中完成。客户端连接有很多,但是NIO线程数比较少,一个NIO线程可以同时绑定到多个客户端连接中,它们属于一对多的关系

1.2 并发

1.2.1 类加载机制

1.2.2 JMM(Java内存模型)

1.2.3 锁

  • synchronized原理:对象锁(monitor)

  • volatile:通过插入内存屏障禁止特定类型的处理器重排序。

    • 在每个volatile写操作的前面插入一个StoreStore屏障,禁止上面的普通写和下面的volatile写重排序
    • 在每个volatile写操作的后面插入一个StoreLoad屏障,防止上面的volatile写与下面可能有的volatile读/写重排序
    • 在每个volatile读操作的后面插入一个LoadLoad屏障,禁止下面所有的普通读操作和上面的volatile读重排序
    • 在每个volatile读操作的后面插入一个LoadStore屏障,禁止下面所有的普通写操作和上面的volatile读重排序
  • CAS(compare and swap),atomic包中的类都是通过这种方式实现的;CAS的ABA问题、自旋时间过长、只能保证一个共享变量的原子操作