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

5 阅读4分钟

面试官:请简要介绍一下 Java 核心知识中面向对象的三大特性。

王铁牛:嗯……这个我知道,是封装、继承和多态。

面试官:不错,回答正确。那请说说封装的作用是什么?

王铁牛:封装就是把对象的属性和方法结合成一个独立的整体,这样可以提高代码的安全性和可维护性,防止外部对内部数据的非法访问和修改。

面试官:很好,理解得挺到位。接下来问你一个多线程的问题,在多线程环境下,如何保证共享资源的线程安全?

王铁牛:这个嘛……可以用 synchronized 关键字,或者用 Lock 接口来实现线程同步。

面试官:嗯,勉强算对。第一轮面试结束。

面试官:JUC 包下有哪些重要的类和接口?

王铁牛:有 ExecutorService、Callable、Future 这些吧……

面试官:那 ExecutorService 有什么作用?

王铁牛:它可以用来管理线程池,提交任务执行。

面试官:线程池有哪几种类型?

王铁牛:这个……好像有几种,但是我不太记得清了。

面试官:第二轮面试结束。

面试官:请描述一下 JVM 的内存结构。

王铁牛:有堆、栈、方法区这些……

面试官:那对象是在 JVM 的哪个区域创建和存储的?

王铁牛:在堆里创建和存储。

面试官:类加载器有哪些类型?

王铁牛:这个我真不太清楚了。

面试官:好,三轮面试结束。回去等通知吧。

答案:

  • Java 面向对象三大特性
    • 封装:将对象的属性和方法结合成一个独立的整体,提高代码安全性和可维护性,防止外部非法访问和修改内部数据。通过访问修饰符(如 private、public 等)来控制属性和方法的访问权限。
    • 继承:子类继承父类的属性和方法,实现代码复用。子类可以扩展和重写父类的方法。
    • 多态:同一个行为具有不同表现形式或形态的能力。包括编译时多态(方法重载)和运行时多态(方法重写)。运行时多态通过动态绑定实现,根据对象的实际类型来调用相应的方法。
  • 多线程保证共享资源线程安全的方法
    • synchronized 关键字:可以修饰代码块或方法,确保在同一时刻只有一个线程能访问被修饰的资源。它通过对象头中的 Mark Word 来实现锁机制。
    • Lock 接口:提供了更灵活的锁控制,如可中断锁、定时锁等。常用的实现类有 ReentrantLock。使用 Lock 时需要手动获取和释放锁,一般配合 try - finally 块来确保锁能正确释放。
  • JUC 包下重要的类和接口
    • ExecutorService:用于管理线程池,提交任务执行。它提供了一系列方法来控制线程池的生命周期和任务提交。
    • Callable:类似于 Runnable,但 Callable 有返回值,通过 call 方法返回结果。
    • Future:表示异步计算的结果。可以通过 Future 来获取 Callable 任务的执行结果,也可以取消任务等。
  • 线程池类型
    • FixedThreadPool:固定大小的线程池,当提交的任务数大于线程池大小时,任务会在队列中等待。
    • CachedThreadPool:可缓存的线程池,线程池大小无界,当线程空闲一段时间后会被回收。
    • SingleThreadExecutor:单线程的线程池,保证所有任务按照顺序执行。
    • ScheduledThreadPool:定时任务线程池,支持定时执行任务。
  • JVM 内存结构
    • :是 JVM 中最大的内存区域,用于存储对象实例。新生代、老年代、永久代(Java 8 后为元空间)都在堆中。
    • :每个线程都有自己的栈,用于存储局部变量、方法调用等。
    • 方法区:存储类信息、常量、静态变量等。
  • 对象在 JVM 中的创建和存储:对象在堆中创建,对象的实例变量存储在堆中,对象的引用存储在栈中。对象创建过程包括类加载、分配内存、初始化零值、设置对象头、执行构造方法等步骤。
  • 类加载器类型
    • 启动类加载器:负责加载 JDK 核心类库。
    • 扩展类加载器:加载 JRE 的扩展目录下的类。
    • 应用程序类加载器:加载应用程序的 classpath 下的类。
    • 自定义类加载器:用户可以根据需求自定义类加载器,实现特殊的类加载逻辑。