《互联网大厂Java面试大揭秘:核心知识深度考察》

51 阅读6分钟

互联网大厂Java面试大揭秘:核心知识深度考察

面试官:请简要介绍一下Java中的多线程,以及如何创建一个线程?

王铁牛:Java中的多线程是指程序中包含多个执行单元,这些执行单元可以并发执行。创建线程可以通过继承Thread类或者实现Runnable接口来实现。

面试官:回答得不错。那请说一下线程池的作用和优点。

王铁牛:线程池的作用是管理线程,避免频繁创建和销毁线程,提高性能。优点是可以提高响应速度、降低资源消耗、便于线程管理。

面试官:很好。再问一个问题,HashMap在多线程环境下会有什么问题?

王铁牛:HashMap在多线程环境下会出现死循环、数据丢失等问题。因为它不是线程安全的。

第一轮结束,王铁牛对于简单问题回答得较为流畅,得到了面试官的夸赞。

面试官:接下来问一些关于JVM的问题。请简述一下JVM的内存结构。

王铁牛:JVM的内存结构包括堆、栈、方法区等。堆是存放对象实例的地方,栈是存放局部变量等,方法区存放类信息等。

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

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

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

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

第二轮结束,王铁牛对JVM相关问题回答得有好有坏,部分回答不够清晰。

面试官:最后一轮,问一些关于框架的问题。Spring框架的核心特性是什么?

王铁牛:Spring框架的核心特性包括依赖注入、面向切面编程、IoC容器等。

面试官:那Spring Boot的优势在哪里?

王铁牛:Spring Boot的优势是简化配置、快速搭建项目、内置Tomcat等。

面试官:请简述一下MyBatis的工作原理。

王铁牛:MyBatis通过XML或注解配置SQL语句,然后通过SqlSessionFactory创建SqlSession,执行SQL操作。

面试结束,面试官表示会让王铁牛回家等通知。整体来看,王铁牛在面试中对一些简单问题回答较好,但对于复杂问题的回答存在不足,需要进一步提升对Java核心知识、框架等的理解和掌握程度。

答案详解

多线程

  • 创建线程方式:
    • 继承Thread类:创建一个类继承Thread类,重写run方法,然后创建该类的实例并调用start方法启动线程。例如:
class MyThread extends Thread {
    @Override
    public void run() {
        System.out.println("线程执行");
    }
}
MyThread thread = new MyThread();
thread.start();
  • 实现Runnable接口:创建一个类实现Runnable接口,重写run方法,然后创建Thread类的实例并传入该实现类的实例,调用start方法启动线程。例如:
class MyRunnable implements Runnable {
    @Override
    public void run() {
        System.out.println("线程执行");
    }
}
Thread thread = new Thread(new MyRunnable());
thread.start();

线程池

  • 作用:管理线程,避免频繁创建和销毁线程,提高性能。
  • 优点:
    • 提高响应速度:因为线程已经存在,无需等待创建线程的时间。
    • 降低资源消耗:减少线程创建和销毁的开销。
    • 便于线程管理:可以控制线程的数量、线程的生命周期等。

HashMap在多线程环境

  • 问题:
    • 死循环:在扩容时可能会导致链表形成环形结构,从而在遍历或插入时陷入死循环。
    • 数据丢失:在多线程同时进行put操作时,可能会覆盖其他线程插入的数据。
  • 原因:HashMap内部结构是数组+链表(JDK8后引入红黑树),在多线程操作时,扩容和插入等操作可能会导致数据不一致。

JVM内存结构

  • 堆:存放对象实例,是JVM管理的最大一块内存区域,被所有线程共享。
  • 栈:存放局部变量、方法调用等信息,每个线程都有自己独立的栈空间。
  • 方法区:存放类信息、常量、静态变量等,被所有线程共享。

类加载机制

  • 加载:将类的字节码文件加载到内存中,生成Class对象。
  • 验证:检查加载的字节码文件是否符合JVM规范,确保安全。
  • 准备:为类的静态变量分配内存,并设置默认初始值。
  • 解析:将符号引用替换为直接引用。
  • 初始化:执行类的静态代码块和静态变量的赋值操作。

垃圾回收算法

  • 标记清除算法:先标记出所有需要回收的对象,然后统一回收。缺点是会产生内存碎片。
  • 标记整理算法:标记出可回收对象后,将存活对象向一端移动,然后清理边界以外的内存。
  • 复制算法:将内存分为两块,每次只使用其中一块,当一块内存使用完后,将存活对象复制到另一块,然后清理原来的内存。适用于对象存活率低的情况。
  • 分代收集算法:根据对象的存活周期将内存分为不同的区域,不同区域采用不同的垃圾回收算法,如新生代采用复制算法,老年代采用标记清除或标记整理算法。

Spring框架核心特性

  • 依赖注入:通过IoC容器将对象之间的依赖关系进行管理和注入,降低对象之间的耦合度。
  • 面向切面编程:可以将横切关注点(如日志、事务等)与业务逻辑分离,提高代码的可维护性和复用性。
  • IoC容器:负责创建、配置和管理对象,通过配置文件或注解等方式实现对象的依赖注入和生命周期管理。

Spring Boot优势

  • 简化配置:采用自动配置原理,减少了大量的XML或Java配置代码。
  • 快速搭建项目:提供了各种starter依赖,快速集成各种功能。
  • 内置Tomcat:无需额外配置Tomcat等服务器,直接运行项目。

MyBatis工作原理

  • 通过XML或注解配置SQL语句。
  • 通过SqlSessionFactory创建SqlSession,SqlSession是执行SQL操作的主要接口。
  • SqlSession通过映射器(Mapper)接口调用对应的SQL语句,映射器接口中的方法名对应XML中的SQL语句的id。
  • 执行SQL操作后返回结果,结果可以是单个对象、对象列表等。例如:
<mapper namespace="com.example.mapper.UserMapper">
    <select id="getUserById" parameterType="int" resultType="User">
        SELECT * FROM user WHERE id = #{id}
    </select>
</mapper>
SqlSession sqlSession = sqlSessionFactory.openSession();
User user = sqlSession.selectOne("com.example.mapper.UserMapper.getUserById", 1);
sqlSession.close();