《互联网大厂Java面试:核心知识大考验》

6 阅读5分钟

互联网大厂Java面试:核心知识大考验

面试官:好了,咱们开始面试。第一轮先问几个基础的Java核心知识问题。首先,什么是Java的多态?

王铁牛:多态就是同一个行为具有多个不同表现形式或形态。

面试官:回答得不错。那Java中的接口和抽象类有什么区别?

王铁牛:接口里只能有抽象方法,不能有方法实现,而且类实现接口要用implements;抽象类可以有抽象方法也可以有非抽象方法,类继承抽象类用extends。

面试官:很好。最后一个问题,简述一下Java的异常处理机制。

王铁牛:就是try、catch、finally块嘛,try里放可能出现异常的代码,catch捕获异常进行处理,finally不管有没有异常都会执行。

面试官:第一轮表现不错,接下来第二轮,咱们聊聊多线程和线程池相关问题。线程池有哪些主要参数?

王铁牛:有corePoolSize、maximumPoolSize、keepAliveTime、unit、workQueue、threadFactory、handler这些。

面试官:嗯,那线程池提交任务时,如果当前线程数小于corePoolSize会怎样?

王铁牛:会创建新线程执行任务。

面试官:当线程数达到corePoolSize后呢?

王铁牛:如果workQueue没满,就把任务放入workQueue。

面试官:第二轮回答得也还行,进入第三轮,关于JVM的问题。JVM的内存区域主要有哪些?

王铁牛:有堆、栈、方法区、程序计数器、本地方法栈。

面试官:那对象在堆中是怎么存储的?

王铁牛:就存对象的实例数据、对象头这些呗。

面试官:类加载机制有哪些?

王铁牛:有加载、验证、准备、解析、初始化。

面试官:好的,面试就到这里,回去等通知吧。

答案:

  1. Java多态:同一个行为具有多个不同表现形式或形态。多态存在的三个必要条件是继承、重写、父类引用指向子类对象。实现多态可以提高程序的可扩展性和可维护性。
  2. 接口和抽象类区别
    • 接口:
      • 只能有抽象方法,不能有方法实现。
      • 类实现接口使用implements关键字。
      • 接口主要用于实现多重继承的功能,一个类可以实现多个接口。
    • 抽象类:
      • 可以有抽象方法也可以有非抽象方法。
      • 类继承抽象类使用extends关键字。
      • 抽象类主要用于定义一些子类共有的属性和行为,为子类提供一个公共的抽象模板。
  3. Java异常处理机制
    • try块:用于包含可能会抛出异常的代码。
    • catch块:用于捕获try块中抛出的异常,并进行相应的处理。
    • finally块:无论try块中的代码是否抛出异常,finally块中的代码都会执行。通常用于释放资源等操作。
  4. 线程池主要参数
    • corePoolSize:线程池的核心线程数,当提交的任务数小于corePoolSize时,线程池会创建新线程来执行任务。
    • maximumPoolSize:线程池允许的最大线程数。当线程数达到corePoolSize且workQueue已满时,会创建新线程,直到线程数达到maximumPoolSize。
    • keepAliveTime:线程池中的线程在空闲时的存活时间。当线程空闲时间超过keepAliveTime时,非核心线程会被销毁。
    • unit:keepAliveTime的时间单位。
    • workQueue:用于存放任务的队列,当提交的任务数大于corePoolSize时,任务会被放入workQueue中。
    • threadFactory:用于创建线程的工厂,可自定义线程的名称、优先级等属性。
    • handler:当线程池的线程数达到maximumPoolSize且workQueue已满时,新提交的任务会交给handler来处理。常见的handler有AbortPolicy(直接抛出异常)、CallerRunsPolicy(由调用线程处理任务)、DiscardPolicy(丢弃任务)、DiscardOldestPolicy(丢弃队列中最老的任务)。
  5. 线程池提交任务规则
    • 当线程数小于corePoolSize时,创建新线程执行任务。
    • 当线程数达到corePoolSize后,如果workQueue没满,将任务放入workQueue。
    • 当线程数达到corePoolSize且workQueue已满时,如果线程数小于maximumPoolSize,创建新线程执行任务。
    • 当线程数达到maximumPoolSize且workQueue已满时,根据handler的策略处理新提交的任务。
  6. JVM内存区域
    • 堆:用于存储对象实例,是JVM中最大的内存区域,也是垃圾回收的主要区域。
    • 栈:主要存储局部变量、方法调用的上下文等信息。栈中的数据随着方法的调用和结束而进出。
    • 方法区:存储类的信息、常量、静态变量等。在Java 8及以后,方法区被元空间(MetaSpace)取代。
    • 程序计数器:记录当前线程执行的字节码指令地址,是线程私有的内存区域。
    • 本地方法栈:用于执行本地方法(用C或C++实现的方法)。
  7. 对象在堆中的存储
    • 对象头:包含对象的哈希码、对象分代年龄、锁状态标志等信息。
    • 实例数据:存储对象的具体属性值。
    • 对齐填充:为了使对象的大小是8字节的整数倍,可能会进行一些填充。
  8. 类加载机制
    • 加载:将类的字节码文件加载到内存中,并创建一个java.lang.Class对象。
    • 验证:检查加载的字节码文件是否符合JVM规范,确保其安全性。
    • 准备:为类的静态变量分配内存,并设置默认初始值。
    • 解析:将类中的符号引用转换为直接引用。
    • 初始化:执行类的静态代码块和为静态变量赋值等操作,完成类的初始化。