《互联网大厂 Java 面试:核心知识、框架与中间件大考验》

40 阅读9分钟

互联网大厂 Java 面试:核心知识、框架与中间件大考验

在互联网大厂宽敞明亮的面试室内,严肃的面试官正襟危坐,对面坐着略显紧张的求职者王铁牛。面试开始,一场关于 Java 技术深度与广度的考验拉开帷幕。

第一轮提问

  • 面试官:首先,我们来聊聊 Java 核心知识。Java 中基本数据类型有哪些,它们的默认值分别是什么?
  • 王铁牛:基本数据类型有 byte、short、int、long、float、double、char、boolean。byte、short、int、long 默认值是 0;float 和 double 默认值是 0.0;char 默认值是 '\u0000';boolean 默认值是 false。
  • 面试官:不错,回答得很准确。那 Java 中继承和组合有什么区别,使用场景是怎样的?
  • 王铁牛:继承是子类继承父类的属性和方法,是一种 “is - a” 的关系,比如猫是动物。组合是一个类包含另一个类的对象,是 “has - a” 的关系,像汽车有发动机。继承适合代码复用和扩展父类功能,组合更强调功能的组装和灵活性。
  • 面试官:很好,理解得很清晰。那说说 Java 中的异常处理机制,try - catch - finally 是怎么工作的?
  • 王铁牛:try 块里放可能会抛出异常的代码,catch 块捕获并处理相应的异常,finally 块不管是否发生异常都会执行,一般用于释放资源。

第二轮提问

  • 面试官:接下来我们谈谈 JUC 和多线程。线程有哪些状态,如何进行状态转换?
  • 王铁牛:线程有新建、就绪、运行、阻塞、死亡这几种状态。新建的线程调用 start() 方法进入就绪状态,就绪状态获得 CPU 时间片进入运行状态,运行状态遇到同步锁等情况进入阻塞状态,阻塞解除回到就绪状态,线程执行完任务或者异常退出进入死亡状态。
  • 面试官:回答得不错。那在 JUC 里,CountDownLatch 和 CyclicBarrier 有什么区别?
  • 王铁牛:呃……这个嘛,好像都是和线程同步有关的,具体区别我有点说不太清。
  • 面试官:那我们换个问题,线程池的工作原理是什么,有哪些重要的参数?
  • 王铁牛:线程池就是预先创建一些线程,当有任务提交时就分配线程去执行。重要参数有核心线程数、最大线程数、线程空闲时间、任务队列、拒绝策略。

第三轮提问

  • 面试官:现在说说框架相关的。Spring 的 IOC 和 AOP 是什么,它们的实现原理是怎样的?
  • 王铁牛:IOC 是控制反转,把对象的创建和依赖关系的管理交给 Spring 容器。AOP 是面向切面编程,用于在不修改原有代码的情况下增加新的功能。实现原理嘛,IOC 好像是通过反射和工厂模式,AOP 不太清楚。
  • 面试官:那 Spring Boot 有什么优点,它是如何实现自动配置的?
  • 王铁牛:Spring Boot 优点是简化配置、快速开发。自动配置嘛,就是根据 classpath 里的依赖自动配置 Bean,具体怎么弄的我不太明白。
  • 面试官:最后问问 MyBatis,MyBatis 是如何实现 SQL 映射的?
  • 王铁牛:呃,好像是通过 XML 文件或者注解把 SQL 和 Java 方法对应起来,具体细节不太清楚了。

面试官扶了扶眼镜,表情严肃地说:“王铁牛,今天的面试就到这里。你对一些基础的 Java 知识掌握得还可以,但对于一些稍微复杂的技术点,回答得不够深入和准确。我们会综合评估这次面试情况,你回家等通知吧。”

问题答案

  1. Java 中基本数据类型有哪些,它们的默认值分别是什么?
    • Java 中有 8 种基本数据类型,分别是 byte(1 字节)、short(2 字节)、int(4 字节)、long(8 字节)、float(4 字节)、double(8 字节)、char(2 字节)、boolean(理论上没有明确大小)。
    • 它们的默认值:byte、short、int、long 默认值为 0;float 默认值为 0.0f;double 默认值为 0.0d;char 默认值为 '\u0000',这是一个空字符;boolean 默认值为 false。
  2. Java 中继承和组合有什么区别,使用场景是怎样的?
    • 区别:继承是一种 “is - a” 的关系,子类继承父类的属性和方法,子类可以重写父类的方法。组合是 “has - a” 的关系,一个类包含另一个类的对象,通过调用包含对象的方法来实现功能。
    • 使用场景:继承适合当子类和父类有明确的层次关系,需要复用父类代码和扩展父类功能时使用。组合适用于需要灵活组装不同功能模块,避免继承带来的耦合问题。
  3. Java 中的异常处理机制,try - catch - finally 是怎么工作的?
    • try 块:用于包含可能会抛出异常的代码。当 try 块中的代码抛出异常时,程序会停止执行 try 块中剩余的代码,跳转到相应的 catch 块。
    • catch 块:用于捕获并处理特定类型的异常。可以有多个 catch 块,按顺序匹配异常类型,匹配到则执行该 catch 块中的代码。
    • finally 块:无论 try 块中是否发生异常,finally 块中的代码都会执行。通常用于释放资源,如关闭文件、数据库连接等。
  4. 线程有哪些状态,如何进行状态转换?
    • 线程的状态有新建(New)、就绪(Runnable)、运行(Running)、阻塞(Blocked)、等待(Waiting)、超时等待(Timed Waiting)、死亡(Terminated)。
    • 状态转换:新建的线程调用 start() 方法进入就绪状态,就绪状态的线程获得 CPU 时间片进入运行状态;运行状态的线程遇到同步锁、调用 sleep()、wait() 等方法会进入阻塞、等待或超时等待状态;阻塞解除后回到就绪状态;线程执行完任务或者遇到异常退出进入死亡状态。
  5. 在 JUC 里,CountDownLatch 和 CyclicBarrier 有什么区别?
    • CountDownLatch 是一个同步辅助类,它允许一个或多个线程等待其他线程完成操作。通过一个计数器来实现,计数器初始化为一个正整数,每个线程完成任务后调用 countDown() 方法将计数器减 1,当计数器变为 0 时,等待的线程可以继续执行。它是一次性的,不能重复使用。
    • CyclicBarrier 也是一个同步辅助类,它允许一组线程相互等待,直到所有线程都到达一个屏障点,然后所有线程可以继续执行。它有一个初始的计数值,每个线程到达屏障点时调用 await() 方法,当所有线程都调用了 await() 方法后,屏障打开,所有线程继续执行。它可以重复使用,重置计数器后可以再次使用。
  6. 线程池的工作原理是什么,有哪些重要的参数?
    • 工作原理:线程池预先创建一定数量的线程,当有任务提交时,线程池会从线程池中获取一个空闲线程来执行任务。如果线程池中的线程都在忙碌,任务会被放入任务队列中等待。如果任务队列也满了,会根据拒绝策略来处理新提交的任务。
    • 重要参数:
      • 核心线程数(corePoolSize):线程池中的核心线程数量,即使这些线程空闲也不会被销毁。
      • 最大线程数(maximumPoolSize):线程池允许的最大线程数量。
      • 线程空闲时间(keepAliveTime):当线程池中的线程数量超过核心线程数时,空闲线程在多长时间后会被销毁。
      • 任务队列(workQueue):用于存放等待执行的任务。
      • 拒绝策略(handler):当任务队列满了且线程池中的线程数量达到最大线程数时,对新提交任务的处理策略,如抛出异常、丢弃任务等。
  7. Spring 的 IOC 和 AOP 是什么,它们的实现原理是怎样的?
    • IOC(控制反转):是一种设计思想,把对象的创建和依赖关系的管理从代码中转移到 Spring 容器中。实现原理主要基于反射和工厂模式。Spring 容器通过读取配置文件(XML 或注解)来创建对象,使用反射机制实例化对象,并通过 setter 方法或构造函数注入依赖。
    • AOP(面向切面编程):是一种编程范式,用于在不修改原有代码的情况下增加新的功能,如日志记录、事务管理等。实现原理主要基于代理模式,Spring AOP 有两种代理方式,JDK 动态代理和 CGLIB 代理。JDK 动态代理基于接口,CGLIB 代理基于继承。
  8. Spring Boot 有什么优点,它是如何实现自动配置的?
    • 优点:简化配置,通过 starter 依赖自动引入所需的依赖和配置;快速开发,提供了默认的配置和约定,减少了开发人员的配置工作量;内嵌服务器,方便部署和运行。
    • 自动配置原理:Spring Boot 通过 classpath 里的依赖自动配置 Bean。它有一个自动配置类(在 spring - boot - autoconfigure 模块中),这些配置类使用 @Conditional 注解根据条件判断是否进行配置。当应用启动时,Spring Boot 会扫描 classpath 中的依赖,根据依赖情况自动加载相应的配置类,从而实现自动配置。
  9. MyBatis 是如何实现 SQL 映射的?
    • MyBatis 可以通过 XML 文件或者注解来实现 SQL 映射。
    • XML 方式:在 XML 文件中定义 SQL 语句,使用 、、、 等标签来编写 SQL,同时通过 标签来映射查询结果和 Java 对象的属性。MyBatis 会解析 XML 文件,将 SQL 语句和 Java 方法关联起来。 注解方式:在 Java 接口的方法上使用 @Select、@Insert、@Update、@Delete 等注解来编写 SQL 语句,MyBatis 会根据注解中的 SQL 语句和方法参数进行映射。