《互联网大厂 Java 面试全流程大揭秘:核心知识与热门框架深度考察》

46 阅读7分钟

互联网大厂 Java 面试全流程大揭秘:核心知识与热门框架深度考察

面试官:请简要介绍一下 Java 中的多线程,以及在什么场景下你会选择使用多线程?

王铁牛:多线程就是在一个程序里可以同时执行多个线程。比如服务器处理多个客户端请求的时候,就可以用多线程来提高效率。

面试官:还不错。那说说线程池吧,它有哪些参数,分别有什么作用?

王铁牛:线程池有 corePoolSize、maximumPoolSize、keepAliveTime 这些参数。corePoolSize 是核心线程数,maximumPoolSize 是最大线程数,keepAliveTime 是线程池线程在空闲时的存活时间。

面试官:很好。再问一个,如何保证多线程环境下数据的一致性?

王铁牛:可以用 synchronized 关键字或者 Lock 接口来同步代码块或者方法,还可以用 volatile 关键字保证变量的可见性。

第一轮结束。

面试官:接下来聊聊 JVM,它的内存结构分为哪几个部分?

王铁牛:JVM 内存结构有堆、栈、方法区、本地方法栈、程序计数器。

面试官:那类加载机制的过程是怎样的?

王铁牛:类加载机制包括加载、验证、准备、解析、初始化这几个过程。

面试官:说说垃圾回收算法有哪些?

王铁牛:有标记清除算法、标记整理算法、复制算法、分代收集算法。

第二轮结束。

面试官:谈谈 Spring 框架中 IoC 和 AOP 的概念。

王铁牛:IoC 就是控制反转,把对象的创建和依赖注入交给 Spring 容器。AOP 是面向切面编程,在不修改原有代码的基础上增强功能。

面试官:Spring Boot 有什么优势?

王铁牛:Spring Boot 可以快速搭建项目,自动配置,减少配置文件,提高开发效率。

面试官:MyBatis 中如何进行动态 SQL 语句的编写?

王铁牛:可以用 、、 等标签来编写动态 SQL。

第三轮结束。

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

面试结束后,面试官会综合王铁牛的回答来判断他是否符合岗位要求。对于多线程问题,王铁牛回答出了基本概念和一些应用场景,线程池参数也回答正确,在保证多线程数据一致性方面提到了关键方法,表现尚可。JVM 部分内存结构和类加载机制回答正确,但垃圾回收算法的回答稍显简略。Spring 相关概念回答基本准确,但深度和细节方面还有提升空间。整体来看,王铁牛对基础知识有一定的掌握,但在复杂问题和细节方面还有待加强。

答案

  • 多线程:多线程是指在一个程序中可以同时执行多个线程。线程是程序执行的最小单元。在服务器处理多个客户端请求时,使用多线程可以提高效率,因为可以同时处理多个请求,而不是依次处理。例如一个电商平台的服务器,同时会有大量用户进行下单、查询商品等操作,使用多线程就能并行处理这些请求,加快响应速度。
  • 线程池参数
    • corePoolSize:核心线程数。当提交的任务数小于 corePoolSize 时,线程池会创建新的线程来执行任务。
    • maximumPoolSize:最大线程数。当提交的任务数大于 corePoolSize 时,且任务队列已满,线程池会创建新的线程直到线程数达到 maximumPoolSize。
    • keepAliveTime:线程池线程在空闲时的存活时间。当线程数大于 corePoolSize 且线程空闲时间超过 keepAliveTime 时,多余的线程会被销毁。
  • 保证多线程数据一致性
    • synchronized 关键字:可以修饰代码块或方法,保证在同一时刻只有一个线程能访问被修饰的代码块或方法,从而实现同步。例如在一个银行转账的方法中,使用 synchronized 修饰该方法,就能保证在转账操作时不会有其他线程同时进行转账,避免数据不一致。
    • Lock 接口:提供了比 synchronized 更灵活的锁控制。比如 ReentrantLock,可以实现公平锁、可中断锁等特性。
    • volatile 关键字:保证变量的可见性,即当一个变量被声明为 volatile 时,它会保证对该变量的写操作会立即刷新到主内存中,读操作会从主内存中读取最新的值,而不是从线程的工作内存中读取,避免了数据不一致问题。
  • JVM 内存结构
    • :是 JVM 中最大的一块内存区域,用于存放对象实例。
    • :每个线程都有自己独立的栈空间,用于存放局部变量、方法调用等。
    • 方法区:用于存储已被虚拟机加载的类信息、常量、静态变量等数据。
    • 本地方法栈:与虚拟机栈类似,只不过它是为本地方法服务的。
    • 程序计数器:记录当前线程执行的字节码指令地址。
  • 类加载机制过程
    • 加载:将类的字节码文件加载到内存中。
    • 验证:检查加载的字节码文件是否符合 JVM 规范,是否安全。
    • 准备:为类的静态变量分配内存,并设置默认初始值。
    • 解析:将符号引用转换为直接引用。
    • 初始化:执行类构造器 方法,对静态变量进行初始化赋值等操作。
  • 垃圾回收算法
    • 标记清除算法:先标记出所有需要回收的对象,然后统一回收所有被标记的对象。这种算法会产生大量不连续的内存碎片。
    • 标记整理算法:先标记出需要回收的对象,然后将存活的对象向一端移动,最后清理掉端边界以外的内存。
    • 复制算法:将内存分为两块,每次只使用其中一块。当这一块内存用完时,将存活的对象复制到另一块内存,然后清理掉原来的那块内存。适用于对象存活率较低的场景。
    • 分代收集算法:根据对象的存活周期将内存划分为不同的区域,一般分为新生代、老年代等。针对不同区域采用不同的垃圾回收算法,以提高垃圾回收效率。
  • Spring 的 IoC 和 AOP
    • IoC(控制反转):把对象的创建和依赖注入交给 Spring 容器来管理。传统方式下,对象之间的依赖关系由程序员自己创建和维护,而 IoC 中,对象只需要声明自己的依赖,由 Spring 容器负责注入具体的实现,降低了对象之间的耦合度。例如在一个电商系统中,订单服务类依赖于用户服务类,使用 IoC 后,Spring 容器会自动将用户服务类的实例注入到订单服务类中。
    • AOP(面向切面编程):在不修改原有代码的基础上,对业务逻辑进行增强。比如可以在方法执行前、执行后、抛出异常时等切入点执行一些额外的逻辑,如日志记录、事务管理等。例如在一个用户注册的方法上,通过 AOP 可以在方法执行前记录用户注册的请求信息,在方法执行后记录注册结果信息。
  • Spring Boot 优势
    • 快速搭建项目:提供了很多默认配置,使用 Spring Initializr 可以快速创建一个基于 Spring Boot 的项目框架,减少了项目搭建的时间和工作量。
    • 自动配置:Spring Boot 会根据项目中引入的依赖自动进行配置,例如引入了数据库相关依赖,就会自动配置好数据源等相关信息,大大简化了配置文件。
    • 减少配置文件:很多配置都可以通过属性文件或者注解来完成,相比于传统的 Spring 项目,配置文件更加简洁。
  • MyBatis 动态 SQL 编写
    • 标签:用于根据条件判断来决定是否包含某条 SQL 语句。例如:
<select id="getUserById" parameterType="int" resultType="User">
    SELECT * FROM user
    <if test="id != null">
        WHERE id = #{id}
    </if>
</select>
- **<where> 标签**:当有多个条件判断时,<where> 标签可以自动处理 SQL 语句中的 WHERE 关键字,并且会智能地处理 ANDOR 连接词,避免出现多余的 ANDOR。例如:
<select id="getUserList" parameterType="User" resultType="User">
    SELECT * FROM user
    <where>
        <if test="name != null">
            AND name = #{name}
        </if>
        <if test="age != null">
            AND age = #{age}
        </if>
    </where>
</select>
- **<foreach> 标签**:用于循环遍历集合,构建 IN 子句等。例如:
<select id="getUserByIds" parameterType="list" resultType="User">
    SELECT * FROM user
    WHERE id IN
    <foreach collection="list" item="item" open="(" separator="," close=")">
        #{item}
    </foreach>
</select>