01. Java核心基础面试题

102 阅读4分钟
  1. Java中如何选择抽象类和接口

    我认为这个是is 和 has的关系

    比如:猫is动物,他就有着动物都有的行为,睡觉,捕食,繁殖,此时用抽象类。

    而:猫经过训练后has握手的能力,这不是所有猫和动物公有的,只有一部分有,所以是has,此时用接口。

  2. 重载和重写

    重写:就是重新写,父类方法对子类不适用或者需要扩展增强时,子类可以对从父类中继承来的方法重写。

    重载:在同一个类中,允许存在多个同名的方法,只要他们的参数列表不同。

  3. 静态内部类和非静态内部类的区别

    关键区别在于是否持有对外部类实例的引用,持有则可以访问外部类的非静态成员和静态成员,否则只能访问静态成员。同时持有后就必须倚赖外部类实例才能创建。

  4. Java中在传参数时是将值进行传递,还是传递引用?

    Java没有所谓的传递值和引用,引用的本质是地址,也是值,java传递的都是值。

    举例:

    1  public class TransferTest2 {
    2     public static void main(String[] args) {
    3         Person person = new Person();
    4         System.out.println(person);
    5         change(person);
    6         System.out.println(person);
    7     }
    8
    9     public static void change(Person p) {
    10         p = new Person();
    11     }
    12 }
    13
    14 /**
    15 * Person类
    16 */
    17 class Person {
    18
    19 }
    

分析:

图片 01.当程序执行到第3行 Person person = new Person()时,程序在堆内存(heap)中开辟了一块内存空间用来存储Person类实例对象,同时在栈内存(stack)中开辟了一个存储单元来存储该实例对象的引用,即上图中person指向的存储单元。

02.当程序执行到第5行 change(person)时,person作为参数(实参)传递给了change()方法。这里是person将自己的存储单元的内容传递给了change()方法的p变量。此后在change()方法中对p变量的一切操作都是针对于p变量所指向的存储单元,与perosn所指向的存储单元就没有关系了。

  1. equals和==的区别?

==就是判断引用的地址是否相同。对于引用类型,除非是同一个new出来的对象,他们的比较的结果为true,否则为false。

equals如果不重写,那么就是==。重写后,比如对string类型,就是判断字符串是否相同。

  1. String s = new String("xxx");创建了几个String对象?

因为new了,所以至少一个。然后如果字符串常量池中不拥有xxx,那么还会在里面再创建一个。

  1. finally中的代码一定会执行吗?try里有return,finally还执行吗?

一定会执行,即使有return,也会先把retrun的值保存到栈帧的局部变量表中然后执行。只有一个情况不会,就是在执行之前终止了虚拟机。

  1. Java异常机制中,异常Exception和Error的区别?

640.webp

他们有一个共有的父类:Throwable可抛出类。

Error是严重的错误,是程序所不能处理的。例如:当 JVM 不再有继续执行操作所需的内存资源时,将出现 OutOfMemoryError等等。这些错误发生时,JVM一般会选择线程终止。

Exception是程序可以处理的异常。而Exception又分为运行时异常(RuntimeException)与非运行时异常。

运行时异常,即:编译检查时不会暴露出来的异常,需要在运行时候才会暴露出来,比如下标越界,空指针异常等。

非运行时异常:RuntimeException之外的异常我们统称为非运行时异常,比如IOException、SQLException,这些是必须进行处理的异常(检查异常) ,如果不处理(throw到上层或者try-catch),程序就不能编译通过 。

  1. 序列Parcelable,Serializable的区别

    Serializable 是Java提供的一个标准序列化机制。其本质就是转换为字节流后调用流输出到外存或网络中。

    而Parcelable是Android提供的一种更高效的序列化机制,其本质是转化为Parcel数据流,存储到共享内存中,适用于在安卓组件中传递数据。

  2. 为什么Intent传递对象需要先序列化?

    序列化通过将结构化的对象转换为字节流,方便存储到文件、数据库,或者通过网络传输。

    首先要理解Intent的原理,Intent用于启动组件(如Activity、Service等),并可以携带数据进行传输。其依赖于binder机制,

    AMS是系统服务,负责管理Activity的生命周期。当调用startActivity时,调用会离开当前应用进程,进入AMS所在的system_server进程进行处理。而又因为Android的进程隔离机制确保不同应用进程互不干扰。这意味着system_server进程无法直接访问应用进程的内存。

    因此,必须通过序列化的方式,将对象转换为可传输的字节流,再进行跨进程传输。此时AMS才能获取到对应信息。