目录

常见面试题-3

异常

Java中的异常主要分为两大类:受检异常和非受检异常。

  • 受检异常在Java代码中必须通过try-catch捕获或者通过throws进行抛出,否则编译无法通过
  • 非受检异常在Java代码中不需要强制处理,也可以通过编译但是建议处理。
  • try-catch-finally中finally是最终执行的,但不是一定会执行的,如果虚拟机栈直接停止、CPU停止、线程死亡都不会执行,try中如果return了,finally执行完后会返回try中的return值,因此在finally不能出现return,不然try中的return就会被忽略。
  • try用于执行代码并捕获异常,catch用于处理异常,可以有多个catch块。

泛型

  • 通过泛型参数可以指定传入对象的类型。主要有类泛型、泛型接口、泛型方法。
  • 泛型类就比如项目中的统一返回值Result,可以指定返回的数据类型。
  • 泛型接口就比如一个接口中的返回值可以是不同类型,就可以定义一个泛型,泛型接口使用这个泛型作为返回值,这样实现这个接口就可以指定返回值类型。
  • 泛型方法就比如一个方法中的参数可以是不同类型,就可以定义一个泛型,泛型方法使用这个泛型作为参数类型,这样调用这个方法时就可以指定参数类型。

反射

  • 反射就是在程序运行时可以动态的获取到类的方法、属性等信息,并且可以动态调用方法,设置属性值。
  • 反射的优点是灵活、解耦(可以通过反射定义更加通用的代码),缺点是性能较差且不安全。
  • 依赖注入与控制反转(Ioc)、注解处理、AOP切面编程、动态代理都是利用了反射。

代理

  • 指在不修改源代码的情况下对方法进行增强。
  • 分为JDK动态代理和CGLIB代理,JDK是要求类必须实现接口,CGLIB是通过创建子类实现的,并且无法代理fainal修饰分类和方法。
  • 最常见的动态代理应用就是AOP切面编程实现系统日志的记录。可以先在方法上标记注解,然后通过动态代理获取到注解,然后在方法执行前后进行日志记录。

注解

  • 用来标记字段、类、方法等元素,提供某些信息在程序编译或运行时进行使用。
  • 注解有两种解析方式,第一种是在编译时就进行解析,例如@Override,在编译时就会解析是否重写了父类方法,另一种是运行时通过反射进行解析。

SPI

  • SPI就是调用方提供接口,实现方提供实现,通过配置文件指定实现类。
  • SPI和API的区别就是API是服务方提供接口和实现类,调用方是负责调用服务方的接口,不关心实现类。

序列化与反序列化

  • 序列化就是将对象转换成可以传输或存储的形式,一般是二进制数据,也可以是JSON、XML等格式。例如请求的返回值。
  • 反序列化就是将序列化后的数据转换成对象。例如使用对象接收请求参数。
  • 如果对象的某些属性不想被序列化,可以使用transient修饰,注意transient只能修饰属性,不能修饰类和方法,被transient修饰的属性在反序列化后值会被重置为对应的默认值。
  • JDK默认的序列化体积大、不能支持跨语言、性能差,因此现在常用JSON、XML等格式进行序列化。