java八股文

以下是常见的 Java 八股文内容,涵盖了 Java 基础、并发编程、JVM、IO 与 NIO、框架等方面:

Java 基础

  • Java 中序列化是怎么实现的呢?

    • 实现 Serializable 接口,就会实现数据序列化的效果。

    • 调用 JSON 做序列化,如 Jackson、fastjson 等。

    • 实现 Externalizable 接口,就可以实现反序列化的效果。

  • java的流有哪些呢?

    • 从方向方面,主要就是输入流和输出流。

    • 从单位方面,主要就是分为字节流和字符流。字节流主要就是 InputStreamOutputStream。字符流主要就是 ReaderWriter

  • 抽象类和接口有什么区别呢?

    • 从方法编写方面,抽象类中可以有抽象方法和普通方法,而接口中只能编写抽象方法。

    • 从继承和实现方面,抽象类只能继承一个类并且可以实现多个接口,而接口可以继承多个接口。

    • 在变量的定义方面,接口只能定义静态变量,抽象类可以定义普通变量和静态变量。

  • final关键值有了解过吗?

    • 在修饰方法的时候,说明该方法无法被重写。

    • 在修饰类的时候,说明该类无法被继承。

    • 在修饰属性的时候,说明该变量从创建到销毁过程中不会改变。

    • 在修饰形参的时候,说明该形参的引用在方法执行前后都会不发生改变。

  • java中共享变量有哪些?

    • 静态变量。

    • 使用 volatile 修饰 Java 中的变量就会变成共享变量。

  • 编写singleton函数?(单例模式)

    • 饿汉式:

      java复制

      public class Singleton {
          private final static Singleton instance = new Singleton();
          public Singleton getInstance() {
              return instance;
          }
      }
    • 懒汉式:

      java复制

      public class Singleton {
          private static Singleton instance;
          public Singleton getInstance() {
              return instance == null ? new Singleton() : instance;
          }
      }

并发编程

  • 并发编程三要素?

    • 原子性:一个或者多个操作,要么全部执行并且在执行的过程中不被其他操作打断,要么就全部都不执行。

    • 可见性:多个线程操作一个共享变量时,其中一个线程对变量进行修改后,其他线程可以立即看到修改的结果。

    • 有序性:即程序的执行顺序按照代码的先后顺序来执行。

  • 实现可见性的方法有哪些?

    • synchronized 或者 Lock:保证同一个时刻只有一个线程获取锁执行代码,锁释放之前把最新的值刷新到主内存,实现可见性。

  • 线程 B 怎么知道线程 A 修改了变量

    • volatile 修饰变量。

    • synchronized 修饰修改变量的方法。

    • wait/notify

    • while 轮询。

  • synchronized、volatile、CAS 比较

    • synchronized 是悲观锁,属于抢占式,会引起其他线程阻塞。

    • volatile 提供多线程共享变量可见性和禁止指令重排序优化。

    • CAS 是基于冲突检测的乐观锁(非阻塞)。

  • sleep 方法和 wait 方法有什么区别?

    • sleep 方法和 wait 方法都可以用来放弃 CPU 一定的时间,不同点在于如果线程持有某个对象的监视器,sleep 方法不会放弃这个对象的监视器,wait 方法会放弃这个对象的监视器。

  • ThreadLocal 是什么?有什么用?

    • ThreadLocal 是一个本地线程副本变量工具类。主要用于将私有线程和该线程存放的副本对象做一个映射,各个线程之间的变量互不干扰,在高并发场景下,可以实现无状态的调用,特别适用于各个线程依赖不通的变量值完成操作的场景。

  • 为什么 wait()方法和 notify()/notifyAll()方法要在同步块中被调用

    • 这是 JDK 强制的,wait() 方法和 notify()/notifyAll() 方法在调用前都必须先获得对象的锁。

  • 多线程同步有哪几种方法?

    • Synchronized 关键字,Lock 锁实现,分布式锁等。

JVM

  • Serial 垃圾收集器:单线程、复制算法。

  • ParNew 垃圾收集器Serial+ 多线程。

  • Parallel Scavenge 收集器:多线程复制算法、高效。

  • Serial Old 收集器:单线程标记整理算法。

  • Parallel Old 收集器:多线程标记整理算法。

  • CMS 收集器:多线程标记清除算法。

  • G1 收集器

  • JVM 类加载机制:类加载器、双亲委派、OSGI(动态模型系统)、动态改变构造、模块化编程与热插拔。

  • JVM 内存模型:本地方法栈、程序计数器、堆、方法区、分代回收、堆和栈的区别、什么时候会触发 FullGC、什么是 Java 虚拟机、为什么 Java 被称作是“平台无关的编程语言”、对象分配规则、描述一下 JVM 加载 class 文件的原理机制、Java 对象创建过程。

IO 与 NIO

  • Java 中 IO 流?

    • Java 中有多种 IO 流,包括字节流(InputStreamOutputStream)和字符流(ReaderWriter)等。

  • Java IO 与 NIO 的区别

    • Java IO 是面向流的,NIO 是面向缓冲区的。

    • Java IO 是阻塞 IO,NIO 支持非阻塞 IO。

    • NIO 有通道(Channel)和缓冲区(Buffer)的概念,可以提供更高效的 IO 操作。

  • 常用 io 类有哪些

    • 常用的 IO 类包括 FileInputStreamFileOutputStreamBufferedReaderBufferedWriter 等。

  • 字节流与字符流的区别

    • 字节流用于处理二进制数据,字符流用于处理文本数据。

    • 字节流的读写操作是以字节为单位,字符流的读写操作是以字符为单位。

  • 阻塞 IO 模型

    • 在用户线程要获取内核中获取数据,而此时内核中没有数据,用户线程就会等待从而导致用户线程阻塞,当内核中有数据后,数据需要从内核缓冲区复制到用户缓冲区,在这个过程中用户线程也需要等待从而导致线程堵塞。在这两个阶段中用户线程都是堵塞的,这就是阻塞 IO。

  • 非阻塞 IO 模型

    • 用户线程要从内核中获取数据,但内核中没有数据,此时内核直接返回错误信息给用户线程,反之线程堵塞,用户线程会循环的调用内核的方法直到内核中有数据,当内核中有数据后,用户线程就会等待内核缓冲区中的数据复制到用户缓冲区中,此时用户线程是阻塞的。在第一阶段是不阻塞的,而第二阶段是堵塞的,这就是非阻塞 IO。

  • 多路复用 IO 模型

    • 多路 IO 复用模型允许一个线程处理多个 IO 操作,通过使用 selectpollepoll 等系统调用,可以同时监听多个文件描述符的 IO 事件,当某个文件描述符有 IO 事件发生时,就可以进行相应的处理。

  • 信号驱动 IO 模型

    • 信号驱动 IO 模型使用信号来通知应用程序有 IO 事件发生,应用程序在收到信号后,可以进行相应的处理。

  • 异步 IO 模型

    • 异步 IO 模型允许应用程序发起 IO 请求后,立即返回继续执行其他任务,当 IO 操作完成时,会通过回调函数等方式通知应用程序。

  • JAVA NIO

    • Java NIO(New IO)是 Java 提供的一套新的 IO API,它提供了更高效的 IO 操作方式,包括非阻塞 IO、通道和缓冲区等概念。

  • NIO 的缓冲区

    • NIO 的缓冲区(Buffer)是用于存储数据的容器,可以是字节缓冲区、字符缓冲区、整数缓冲区等。缓冲区有容量(capacity)、位置(position)和限制(limit)等属性。

  • NIO 的非阻塞

    • NIO 支持非阻塞 IO 操作,可以通过设置通道(Channel)为非阻塞模式,然后使用选择器(Selector)来监听多个通道的 IO 事件。

  • Channel

    • NIO 的通道(Channel)是用于表示 IO 源或目标的对象,可以是文件通道、套接字通道等。通道可以进行读写操作,并且支持非阻塞模式。

  • Buffer

    • NIO 的缓冲区(Buffer)是用于存储数据的容器,可以是字节缓冲区、字符缓冲区、整数缓冲区等。缓冲区有容量(capacity)、位置(position)和限制(limit)等属性。

框架

  • Spring 中的设计模式有哪些?

    • 工厂模式:常见的工厂模式主要就是 BeanFactory(延迟注入)和 ApplicationContext(完全注入),我们无需知道类如何创建,直接从工厂中获取即可。

    • 单例模式:IOC 默认情况下就是一个单例模式,每次获取相同的类的时候,获取的对象是同一个。不会进行多次的创建。单例模式还分为饿汉式(主动创建单例)及懒汉式(需要时再创建单例)。

    • 代理模式:AOP 是采用代理模式来实现的。当要代理的对象实现接口的时候,我们就会使用 JDK Proxy 来生成代理对象。如果代理的对象没有实现接口的话,我们就会使用 CGLIB 生成一个被代理对象的子类作为代理对象。

    • 策略模式:在编写项目的时候就有使用到策略模式,因为要控制分布式锁的失败策略,会在枚举类编写一个抽象方法,编写多个内部方法去重写该方法,不同的内部方法就是不同的策略。

    • 责任链模式:Stream 流就是使用该模式的,按照对应的顺序去执行方法,并向下传递对象。起到解耦合的作用。

  • 事务的传播性有哪些?

    • Propagation_Required:如果 B 为 A 的子方法,并且都为该传播类型,那么它们都会在同一个事务中。如果主方法中没有开启事务的话就会开启新事务。

    • Propagation_Required_new:如果 B 为 A 子方法,B 会创建一个独立的事务,B 不会受 A 事务的影响。

    • Propagation_nested:如果 B 为 A 子方法,B 会创建一个事务内嵌到 A 的事务中,如果 A 中没有事务的话,就单独开启一个事务。

  • @Transactional 的原理有了解过嘛?

    • 事务注解是基于 AOP 来实现的,也就是在执行方法前开启事务,如果 try/catch 捕获到异常的话就会进行回滚,在方法执行完成后就会进行提交。AOP 实现涉及到动态代理的流程。如果被代理目标对象实现了接口的话,就会使用 JDK Proxy 生成代理对象。如果代理对象没有实现接口的话,就会使用 CGLIB Proxy 生成被代理对象的子类作为代理对象。

  • 说说 CGLIB 的执行流程?

    • CGLIB 是一个强大的高性能代码生成库,它可以在运行期动态生成新的类。在使用 CGLIB 时,首先需要创建一个实现 Enhancer 类的对象,然后设置要增强的类和方法,最后通过 create() 方法生成代理对象。CGLIB 会使用字节码技术生成新的类,并在运行时加载到 JVM 中。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值