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

53 阅读6分钟

面试官:第一轮面试开始,首先问你,在多线程环境下,如何保证数据的一致性?

王铁牛:可以使用 synchronized 关键字来同步代码块或者方法,这样同一时间只有一个线程能访问被同步的部分。

面试官:回答得不错。那说说线程池的核心参数有哪些,它们的作用分别是什么?

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

面试官:很好。再问一个,简述一下 HashMap 的底层实现原理。

王铁牛:HashMap 底层是数组 + 链表 + 红黑树。当链表长度大于阈值(8)时会转成红黑树,这样能提高查询效率。

面试官:第一轮面试结束。

面试官:第二轮面试。说说 JVM 的内存结构有哪些,各自的作用是什么?

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

面试官:那 Spring 框架的核心特性有哪些?

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

面试官:MyBatis 框架的优点是什么?

王铁牛:MyBatis 优点是 SQL 与代码分离,便于维护,支持动态 SQL,性能较高。

面试官:第二轮面试结束。

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

王铁牛:Dubbo 的集群容错策略有 failover、failfast、failsafe、failback 等。

面试官:RabbitMq 的消息确认机制是怎样的?

王铁牛:RabbitMq 有发送确认和接收确认。发送确认有 confirm 模式和 return 模式,接收确认有自动确认和手动确认。

面试官:xxl-job 的执行器类型有哪些?

王铁牛:xxl-job 的执行器类型有 BEAN、GLUE、CMD 等。

面试官:第三轮面试结束。本次面试就到这里,回家等通知吧。

答案

多线程环境下保证数据一致性:

使用 synchronized 关键字同步代码块或方法时,同一时间只有一个线程能访问被同步的部分。这是通过对象头中的 Mark Word 来实现的,当一个线程访问被 synchronized 修饰的代码块或方法时,它会先检查对象头中的 Mark Word 是否被设置为偏向锁状态。如果是,该线程可以直接执行代码。如果不是,它会通过 CAS(Compare and Swap)操作尝试将 Mark Word 设置为自己的线程 ID,表示获取到锁。如果设置成功,线程可以执行代码;如果设置失败,说明有其他线程已经获取到锁,该线程会进入阻塞状态,直到锁被释放。

线程池核心参数及作用:

corePoolSize(核心线程数):线程池创建时初始化的线程数。当提交的任务数小于 corePoolSize 时,线程池会创建新线程来执行任务。

maximumPoolSize(最大线程数):线程池能够容纳的最大线程数。当提交的任务数大于 corePoolSize 且任务队列已满时,线程池会创建新线程,直到线程数达到 maximumPoolSize。

keepAliveTime(线程存活时间):当线程数大于 corePoolSize 时,多余的线程在空闲多长时间后会被销毁。

unit(时间单位):与 keepAliveTime 配合,指定时间单位。

workQueue(任务队列):用于存放提交到线程池但尚未被执行的任务。当提交的任务数大于 corePoolSize 时,任务会被放入任务队列中。

HashMap 底层实现原理:

HashMap 底层是数组 + 链表 + 红黑树。

初始化时会创建一个长度为 2 的幂次方的数组。

当插入键值对时,会通过 key 的 hashCode 计算出数组的索引位置。

如果该位置为空,则直接插入新节点。

如果该位置不为空,则会遍历链表或红黑树,找到相同 key 的节点则更新其 value,否则在链表或红黑树的末尾插入新节点。

当链表长度大于阈值(默认 8)时,链表会转成红黑树,以提高查询效率。

JVM 内存结构及作用:

堆:用于存放对象实例。是 JVM 中最大的一块内存区域,被所有线程共享。

栈:用于存储局部变量、方法调用等。每个线程都有自己独立的栈空间。

方法区:存储类信息、常量、静态变量等。被所有线程共享。

Spring 框架核心特性:

依赖注入:通过控制反转(IoC)实现,将对象的创建和依赖关系的管理交给 Spring 容器,由容器负责将依赖的对象注入到需要的地方。

面向切面编程(AOP):允许将一些横切关注点(如日志、事务管理等)与业务逻辑分离,提高代码的可维护性和复用性。

IoC 容器:负责创建、配置和管理对象之间的依赖关系,是 Spring 框架的核心。

MyBatis 框架优点:

SQL 与代码分离:SQL 语句写在 XML 文件中,与 Java 代码分开,便于维护和管理。

支持动态 SQL:可以根据不同的条件动态生成 SQL 语句,提高 SQL 的灵活性。

性能较高:通过优化 SQL 执行、缓存机制等,提高了系统的性能。

Dubbo 集群容错策略:

failover(失败自动切换):失败后自动切换到其他服务器重试,默认策略。

failfast(快速失败):调用失败立即抛出异常,不重试。

failsafe(失败安全):调用失败不抛出异常,直接忽略。

failback(失败自动恢复):失败后记录失败请求,定时重试。

RabbitMq 消息确认机制:

发送确认:

confirm 模式:生产者发送消息后,Broker 接收到消息会返回确认结果,生产者可以根据确认结果进行后续处理。

return 模式:当消息无法路由到队列时,Broker 会返回给生产者,生产者可以根据返回信息进行处理。

接收确认:

自动确认:消费者接收到消息后,自动确认消息已接收。

手动确认:消费者接收到消息后,需要手动调用方法确认消息已接收,这样可以更好地控制消息的处理流程。

xxl-job 执行器类型:

BEAN:执行器类型为 BEAN 时,会通过反射调用 Spring 容器中的 Bean 来执行任务。

GLUE:GLUE 类型允许用户在页面上编写任务逻辑代码,支持多种语言,运行时会动态编译执行。

CMD:执行器类型为 CMD 时,会执行指定的命令。