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

24 阅读5分钟

面试官:请简要介绍一下 Java 中的多线程,包括线程的创建方式和线程安全问题。

王铁牛:线程创建方式有继承 Thread 类和实现 Runnable 接口。线程安全问题主要是多个线程同时访问共享资源时可能出现数据不一致等情况,通过加锁等方式来解决。

面试官:不错,回答得挺清晰。那再问你,说说 JUC 包中的常用类及其作用。

王铁牛:比如说 CountDownLatch 可以用来实现线程间的同步,CyclicBarrier 能让一组线程相互等待直到全部到达某个状态。

面试官:很好。接下来问几个关于 JVM 的问题,Java 内存区域分为哪几个部分?

王铁牛:嗯……有程序计数器、虚拟机栈、本地方法栈、堆和方法区。

第一轮结束。

面试官:进入第二轮,讲讲线程池的核心参数及其含义。

王铁牛:有 corePoolSize、maximumPoolSize、keepAliveTime、unit 和 workQueue 等。corePoolSize 是核心线程数,maximumPoolSize 是最大线程数,keepAliveTime 是线程存活时间,unit 是时间单位,workQueue 是任务队列。

面试官:那 HashMap 在多线程环境下会出现什么问题?

王铁牛:会出现数据丢失、死循环等问题,好像是因为扩容的时候链表会形成环形结构。

面试官:ArrayList 呢,在多线程操作时如何保证线程安全?

王铁牛:可以用 Collections.synchronizedList 方法把它变成线程安全的。

第二轮结束。

面试官:最后一轮,Spring 框架的核心特性有哪些?

王铁牛:嗯……有依赖注入、面向切面编程之类的吧。

面试官:Spring Boot 相对于 Spring 有哪些优势?

王铁牛:Spring Boot 更简单,自动配置功能很强大,能快速搭建项目。

面试官:说说 MyBatis 的工作原理。

王铁牛:就是通过 XML 配置文件或者注解来映射 SQL 语句,然后执行查询、插入等操作。

面试结束,面试官表示会让王铁牛回家等通知。

答案:

  • Java 多线程
    • 线程创建方式
      • 继承 Thread 类:创建一个类继承 Thread 类,重写 run 方法,然后创建该类的实例并调用 start 方法启动线程。
      • 实现 Runnable 接口:创建一个类实现 Runnable 接口,实现 run 方法,然后将该类实例作为参数传递给 Thread 类的构造函数创建线程对象并启动。
    • 线程安全问题:当多个线程同时访问共享资源时,可能会导致数据不一致等问题。解决方法通常有加锁(如 synchronized 关键字)、使用并发容器(如 ConcurrentHashMap)等。
  • JUC 包
    • CountDownLatch:用于实现线程间的同步,允许一个或多个线程等待其他一组线程完成操作。例如,主线程可以调用 await 方法等待其他子线程完成任务后再继续执行,子线程完成任务后调用 countDown 方法递减计数器,当计数器为 0 时,await 方法返回。
    • CyclicBarrier:让一组线程相互等待直到全部到达某个状态。例如,多个线程同时执行任务,当所有线程都执行到某个阶段时,通过 CyclicBarrier 进行同步,然后继续执行后续任务。
  • JVM 内存区域
    • 程序计数器:记录当前线程执行的字节码指令地址。
    • 虚拟机栈:每个线程都有自己的虚拟机栈,用于存储局部变量、操作数栈等。
    • 本地方法栈:与虚拟机栈类似,用于执行本地方法。
    • :是 Java 对象存储的地方,所有对象实例都在这里分配内存。
    • 方法区:存储已被虚拟机加载的类信息、常量、静态变量等数据。
  • 线程池核心参数
    • corePoolSize:核心线程数,当提交的任务数小于 corePoolSize 时,线程池会创建新线程来执行任务。
    • maximumPoolSize:最大线程数,当提交的任务数大于 corePoolSize 且任务队列已满时,会创建新线程直到线程数达到 maximumPoolSize。
    • keepAliveTime:线程存活时间,当线程数大于 corePoolSize 且空闲时间超过 keepAliveTime 时,多余的线程会被销毁。
    • unit:keepAliveTime 的时间单位。
    • workQueue:任务队列,用于存放提交的任务,当线程池繁忙时,任务会被放入该队列。
  • HashMap 多线程问题:在多线程环境下,HashMap 在扩容时可能会出现链表形成环形结构,导致后续查询陷入死循环。同时,在多线程同时操作时,可能会出现数据覆盖等问题。
  • ArrayList 线程安全:ArrayList 本身是非线程安全的。可以使用 Collections.synchronizedList 方法将其包装成线程安全的 List。例如:List synchronizedList = Collections.synchronizedList(new ArrayList<>());
  • Spring 框架核心特性
    • 依赖注入:通过容器将对象之间的依赖关系注入到对象中,降低对象之间的耦合度。
    • 面向切面编程(AOP):可以在不修改原有代码的基础上,对业务逻辑进行增强,如日志记录、事务管理等。
  • Spring Boot 优势
    • 更简单:基于约定大于配置的原则,减少了大量的 XML 配置文件。
    • 自动配置功能强大:能够根据项目依赖自动配置相关的组件和功能,快速搭建项目。
  • MyBatis 工作原理:通过 XML 配置文件或者注解来映射 SQL 语句。在执行 SQL 操作时,MyBatis 会根据配置信息创建 SqlSession 对象,SqlSession 负责执行 SQL 语句并返回结果。例如,通过 XML 配置文件定义 SQL 语句的映射关系,然后在 Java 代码中通过 SqlSession 调用相应的 SQL 语句进行查询、插入等操作。