1.异常

  • Exception 和 Error 有什么区别?
    • Exception

    程序本身可以处理的异常,可以通过 catch 来捕获,Exception 又分为编译时异常和运行时异常

    • Error

    属于程序无法处理的错误,不建议通过 catch 捕获【Java虚拟机运行错误 VirtualMachineError】【虚拟机内存不够错误 OutOfMemoryError】等。这些异常发生的时候,JVM 会选择线程终止

    【两者都有一个共同的祖先 java.long 包中的 Throwable】

  • 常见非编译时异常(运行时异常)

    NullPointException(空指针)、NumberFormatException(字符串转换数字格式错误)、ArrayIndexOutOfBoundsException(数组下标越界)、ArithmeticException(算术错误)、ClassCaseException(类型转换错误)

  • Throwable 类常用方法有哪些?
    • String getMessage():返回异常发生时的简单描述信息
    • String toString():返回异常发生时的详细信息
    • String getLocalizedMessage():返回异常对象的本地化信息,如果子类没有覆盖该方法,则该方法返回的信息与 getMessage() 返回的结果相同
    • void printStackTrace():在控制台上带引 Throwable 对象封装的异常信息
  • try-catch-finally 使用
    • try:用于捕获异常,后面可以有多个 catch,如果没有则必须有 finally
    • catch:用于处理捕获到的异常
    • finally:无论有没有捕获到异常,都会执行【当 try 中遇到 return 的时候,会在方法返回前执行finally】

    当在 try 和 finally 中同时存在 return 的时候,try 中的 return 会被忽略,是因为 try 语句中的 return 返回值会被暂存在一个本地变量中,当执行完 finally 中的 return 后,本地变量也就变成了 finally 中的 return 值

  • finally 中的代码一定会执行吗?

    不一定,比如在 finally 之前虚拟机被终止运行、程序所在的线程死亡、关闭 CPU

  • 异常使用有哪些需要注意的地方?

    不吧异常定义为静态变量,会导致异常栈信息错乱、抛出的信息存在一定的意义、抛出的异常更加具体一些【比如数字转换错误的时候应该是 NumberFormatException 而不是 IllegalArgumentException】

2.泛型

  • 什么是泛型?有什么作用?

    使用泛型参数,可以增强代码的可读性和稳定性。可以用来泛指一类,比如在List集合中只存入Person类型的对象。List 返回值类型为 Object,需要手动转换类型才能使用,使用泛型后编译器自动转换

  • 泛型的使用方式有哪几种?

    泛型类、泛型接口、泛型方法

    • 泛型类
    public class Generic<T>{
    
    }
    
    • 泛型接口
    public interface Generator<T>{
    
    }
    
    • 泛型方法
    public static <E> void printArray(E[] inputArray){
    
    }
    

    静态泛型方法:泛型必须在传递类型后才能使用,类在实例化时才能传递参数类型,但静态方法的加载是在类的实例化之前的,也就是说类中的泛型还没有传递参数类型,静态反省方法就已经完成了,所以泛型方法是没法使用类上声明的泛型的,只能使用自己声明的泛型标识[]

  • 项目中哪里用到了泛型?

    自定义接口通用返回结果,通过泛型参数根据具体的返回类型动态的指定结果的数据类型、集合工具类等

3.反射

  • 反射是什么

    通过反射可以获取任意一个类的所有属性和方法,还可以调用这些属性和方法

  • 反射的优缺点
    • 优点

    反射可以让我们的代码更加灵活

    • 缺点

    可以无视泛型参数,反射的性能也较为差一些,但对于框架来说实际影响并不大

  • 反射的应用场景

    各大框架:SSM、SpringBoot等。注解的实现也是用到了反射

4.注解

  • 注解是什么

    注解可以看作是一种特殊的注释,主要用于修饰类、方法、变量,提供一些信息让程序在编译或者运行时候来使用【注解本质是继承了 Annation 一个特殊接口】

  • 注解的解析方法有哪几种?
    • 编译器的时候直接扫描:编译器在编译 Java 代码的时候扫描对应的注解并处理,比如 @Override 注解,编译器在编译的时候就会检测当前的方法是否重写了父类对应的方法
    • 运行的时候通过反射处理【比如 Spring 框架中的 @Value、@Component等】

5.SPI

  • SPI 是什么?

    服务提供者的接口,就是专门提供给服务提供者或者扩展框架功能的开发者去使用的一个接口

    SPI 将服务接口和具体的服务实现分开,将服务调用方和服务实现房进行解耦,能够提升程序的扩展性、可维护性【Spring框架、数据库加载驱动、日志接口等】

  • SPI 和 API 有什么区别?
    • API:实现方提供了接口和实现,我们就直接调用实现方的接口来使用这些方法,这种接口和实现都是放在实现方的就是 API
    • SPI:由调用方确定接口规则,然后由不同的厂商根据这个规则对这个接口进行实现从而提供服务,这种接口存在于调用方就是 SPI【比如:公司 A 设计了一种产品,需要量产,而市面上有好几家生产这种产品的公司,这个时候,只要公司 A 制定好了这种产品的标准(也就是接口标准)那么这些公司(服务提供者)就按照这个标准交付这种产品(提供不同方案的实现,但结果都是这种产品)
  • SPI 的优缺点?
    • 优点:通过 SPI 可以很大的提高接口设计的灵活性
    • 缺点:需要遍历加载所有的实现类,不能按照需求加载,效率会相对较低

6.序列化和反序列化

  • 什么是序列化?什么是反序列化
    • 序列化:将数据结构或者对象转换为二进制字节流的过程
    • 反序列化:在序列化过程中生成的二进制字节流转换成数据结构或者对象的过程
  • 序列化和反序列化常见应用场景
    • 吧对象存到文件前进行序列化,将对象从文件中拿出来进行反序列化
    • 吧对象存储到数据库(Redis)进行序列化,吧对象从缓存数据库读取出来进行反序列化
  • 如果有些字段不想进行序列化怎么 处理?

    使用 transient 关键字来修饰,作用就是被 transcient 修饰的变量值不会被持久化和恢复【transient 只能修饰变量,不能修饰类和方法,transient 修饰的变量,在反序列化后变量值会是类型的默认值。static 修饰的不属于任何对象,所以无论有没有被 transient 修饰,都不会被序列化

7.I/O

  • IO 了解吗?

    IO就是 Input/Output,输入和输出。数据输入到计算机内存这个过程为输入,输出到外部(数据库,文件等)这个过程为输出

    IO 流在 Java 中分为输入流和输出流,根据数据的处理方式又分为字节流和字符流【关于 IO 流的类都是基于 InputStream、OutputStream、Reader、Writer 这四个类】

  • IO 流为什么要分为字节流和字符流?

    字符流是 Java 虚拟机将字节转换得到的,过程是比较耗时的。而且如果不知道编码类型的情况下,使用字节流的过程容易出现乱码

  • IO 中的设计模式有哪些?
    • 装饰器模式:可以在不改变原有对象的基础上拓展它的功能【对于字节流来说,FilterInputStream(对应输入流) 和 FilterOutputStream(对应输出流) 是装饰器模式的核心,分别用于增强 InputStream 和 OutputStream 子类对象的功能(字节缓冲输入流和字节缓冲输出流都是 FilterInputStream 和 FilterOutputStream 的子类)】

      为什么不直接搞一个字符缓冲文件输入流?因为 InputStream 的子类太多,继承关系也复杂,如果给每一个子类都指定一个对应的缓冲流,太过麻烦

    • 适配器模式:主要用于接口互不兼容类的协调工作【代码中,InputStreamReader 和 OutputStreamWriter 就是两个适配器来实现字节流到字符流的转换。现实举例来说就是,充电宝,它可以吧电充给手机,也可以被充电器来蓄电】

    • 工厂模式:用于创建对象
    • 观察者模式

8.语法糖

  • 什么是语法糖?

    为了方便程序员开发设计出来的一种特殊语法,这种语法对功能并没有影响,可以实现相同的功能,但基于语法糖的代码往往更加简单、可读性更强【比如 for-each,原理就是基于普通的 for 循环和迭代器】

  • Java 中有哪些常见的语法糖?

    泛型、自动拆箱装箱、变长参数、枚举、内部类、for-each、try-with-resource、lambda 表达式等

results matching ""

    No results matching ""