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

43 阅读7分钟

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

面试官:好了,面试开始。第一轮第一个问题,简述一下Java中的多线程实现方式,以及它们的优缺点。

王铁牛:多线程实现方式有继承Thread类和实现Runnable接口,还有使用Callable和Future。继承Thread类简单但无法再继承其他类,实现Runnable接口更灵活,Callable有返回值。

面试官:回答得不错。那再问,如何创建一个线程池?线程池有哪些参数?

王铁牛:通过ThreadPoolExecutor来创建线程池。参数有corePoolSize核心线程数、maximumPoolSize最大线程数、keepAliveTime线程存活时间、unit时间单位、workQueue任务队列、threadFactory线程工厂、handler拒绝策略。

面试官:可以。最后一个问题,说说HashMap的底层数据结构以及扩容机制。

王铁牛:HashMap底层是数组+链表+红黑树。扩容机制是当容量达到阈值(容量*加载因子)时会扩容,扩容后容量变为原来的2倍,链表节点会重新计算哈希值分配到新位置。

面试官:第一轮表现还行,接下来第二轮。说说JVM的内存结构,以及各个区域的作用。

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

面试官:那类加载机制分哪几个步骤?

王铁牛:类加载机制分加载、验证、准备、解析、初始化。

面试官:讲讲Spring框架中IoC和AOP的概念及作用。

王铁牛:IoC是控制反转,把对象创建和依赖注入交给Spring容器。AOP是面向切面编程,用于处理横切关注点,比如日志、事务。

面试官:第二轮就到这里,最后一轮。简述一下MyBatis的工作原理。

王铁牛:MyBatis通过读取配置文件,创建SqlSessionFactory,然后通过SqlSession执行SQL语句,它会根据映射文件把SQL和Java对象进行映射。

面试官:Dubbo的集群容错有哪些策略?

王铁牛:Dubbo集群容错策略有Failover Cluster(失败自动切换)、Failfast Cluster(快速失败)、Failsafe Cluster(失败安全)、Failback Cluster(失败自动恢复)等。

面试官:说说RabbitMq的消息确认机制。

王铁牛:RabbitMq消息确认机制有发布确认、消费者确认。发布确认又分同步确认和异步确认,消费者确认有自动确认和手动确认。

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

答案详解

  1. Java多线程实现方式
    • 继承Thread类:创建一个类继承Thread类,重写run方法,在run方法中编写线程执行的代码。优点是简单直接,缺点是Java是单继承,继承了Thread类后无法再继承其他类。
    • 实现Runnable接口:创建一个类实现Runnable接口,实现run方法。优点是更灵活,一个类可以同时实现多个接口,缺点是没有返回值。
    • 使用Callable和Future:创建一个类实现Callable接口,实现call方法,call方法有返回值。通过FutureTask来包装Callable对象,再通过Thread来执行FutureTask。
  2. 创建线程池及参数
    • 通过ThreadPoolExecutor来创建线程池。
    • corePoolSize核心线程数:线程池创建时初始化的线程数,当提交的任务数小于corePoolSize时,会创建新线程执行任务。
    • maximumPoolSize最大线程数:线程池允许的最大线程数,当提交的任务数大于corePoolSize且任务队列已满时,会创建新线程直到线程数达到maximumPoolSize。
    • keepAliveTime线程存活时间:当线程数大于corePoolSize时,多余的线程在空闲多长时间后会被销毁。
    • unit时间单位:keepAliveTime的时间单位。
    • workQueue任务队列:用于存放提交的任务,当线程数小于corePoolSize时,任务会优先放入任务队列。
    • threadFactory线程工厂:用于创建线程,可自定义线程的名称、优先级等。
    • handler拒绝策略:当线程数达到maximumPoolSize且任务队列已满时,如何处理新提交的任务,有AbortPolicy(抛出异常)、CallerRunsPolicy(调用者运行)、DiscardPolicy(丢弃新任务)、DiscardOldestPolicy(丢弃队列中最旧的任务)等。
  3. HashMap底层数据结构及扩容机制
    • 底层数据结构:HashMap底层是数组+链表+红黑树。初始时数组长度为16,每个元素是一个Node节点,当链表长度大于8且数组长度大于64时,链表会转换为红黑树。
    • 扩容机制:当HashMap的容量达到阈值(容量*加载因子,默认加载因子为0.75)时会进行扩容。扩容后容量变为原来的2倍,扩容时会重新计算每个元素的哈希值,然后重新分配到新的数组位置。
  4. JVM内存结构及各区域作用
    • :存放对象实例,是JVM中最大的一块内存区域,被所有线程共享。
    • :存放局部变量、方法调用等信息,每个线程都有自己独立的栈空间。
    • 方法区:存放类信息、常量、静态变量等,被所有线程共享。
    • 程序计数器:记录当前线程执行的字节码指令地址,是线程私有的。
    • 本地方法栈:用于执行本地方法,是线程私有的。
  5. 类加载机制步骤
    • 加载:通过类的全限定名来获取定义此类的二进制字节流,将字节流所代表的静态存储结构转化为方法区的运行时数据结构,在内存中生成一个代表这个类的Class对象。
    • 验证:确保加载的类信息符合JVM规范,不会危害虚拟机安全。
    • 准备:为类的静态变量分配内存,并设置默认初始值。
    • 解析:将常量池内的符号引用替换为直接引用。
    • 初始化:执行类构造器方法,为类的静态变量赋予正确的初始值。
  6. Spring框架中IoC和AOP的概念及作用
    • IoC(控制反转):把对象的创建和对象之间的依赖关系交给Spring容器来管理,而不是由应用程序自己来控制。这样可以降低对象之间的耦合度,提高程序的可维护性和可扩展性。
    • AOP(面向切面编程):用于处理横切关注点,比如日志、事务、权限控制等。通过将这些横切关注点从业务逻辑中分离出来,以切面的形式织入到业务逻辑中,使业务逻辑更加清晰和简洁。
  7. MyBatis工作原理
    • 首先读取MyBatis的配置文件,通过配置文件创建SqlSessionFactory。
    • SqlSessionFactory是MyBatis的关键对象,它负责创建SqlSession。
    • SqlSession是MyBatis执行SQL语句的入口,通过它可以执行各种SQL操作,如查询、插入、更新、删除等。
    • MyBatis通过映射文件(XML文件或注解)来定义SQL语句和Java对象之间的映射关系,根据映射关系将SQL执行结果封装成Java对象返回给调用者。
  8. Dubbo集群容错策略
    • Failover Cluster(失败自动切换):失败后自动切换到其他服务器,默认策略。
    • Failfast Cluster(快速失败):调用失败立即报错,适用于幂等操作。
    • Failsafe Cluster(失败安全):调用失败不报错,直接忽略,适用于写审计日志等操作。
    • Failback Cluster(失败自动恢复):失败后会在后台定时重试,适用于消息通知等操作。
  9. RabbitMq消息确认机制
    • 发布确认
      • 同步确认:生产者发送消息后等待服务器确认,确认后才继续发送下一条消息。优点是可靠性高,缺点是性能低。
      • 异步确认:生产者发送消息后不需要等待服务器确认,通过回调函数来处理确认结果。优点是性能高,缺点是实现复杂。
    • 消费者确认
      • 自动确认:消费者接收到消息后自动确认,消息一旦被接收就从队列中删除。优点是简单,缺点是可能会导致消息丢失。
      • 手动确认:消费者接收到消息后不自动确认,需要手动调用方法确认,这样可以确保消息被正确处理后才删除。优点是可靠性高,缺点是实现复杂。