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

65 阅读5分钟

面试官:第一轮面试开始,首先问你,Java 中多线程有哪些实现方式?

王铁牛:嗯……有继承 Thread 类,还有实现 Runnable 接口。

面试官:回答正确。那线程池有哪几种创建方式?

王铁牛:有 newFixedThreadPool、newSingleThreadExecutor、newCachedThreadPool 这些。

面试官:不错。再问你,HashMap 在 JDK1.7 和 JDK1.8 中有哪些主要区别?

王铁牛:呃……这个,1.8 好像是改成红黑树了吧。

面试官:回答得不太准确,1.7 是数组+链表结构,1.8 是数组+链表+红黑树结构,当链表长度大于 8 且数组长度大于 64 时链表会转换为红黑树。

第一轮面试结束。

面试官:第二轮面试,Spring 中 Bean 的作用域有哪些?

王铁牛:有 singleton、prototype 等。

面试官:对。那 Spring Boot 如何进行配置文件的读取?

王铁牛:好像是用注解什么的,具体不太记得了。

面试官:Spring Boot 可以通过 @Value 注解读取配置文件中的属性。再问,MyBatis 中如何进行动态 SQL 语句的编写?

王铁牛:这个……用 标签之类的吧。

面试官:基本正确,还可以用 等标签。

第二轮面试结束。

面试官:第三轮面试,Dubbo 服务调用的原理是什么?

王铁牛:就是远程调用嘛。

面试官:回答太简单了,Dubbo 是通过注册中心、集群容错、负载均衡等机制来实现服务调用的。RabbitMq 如何保证消息的可靠性?

王铁牛:不太清楚。

面试官:比如可以通过持久化消息、确认机制等。最后问你,xxl-job 有哪些核心组件?

王铁牛:这个真不知道。

面试官:xxl-job 核心组件有调度中心、执行器等。本次面试结束,回去等通知吧。

答案:

  1. Java 多线程实现方式:
    • 继承 Thread 类:通过继承 Thread 类并重写 run 方法来创建线程。
    • 实现 Runnable 接口:实现 Runnable 接口的 run 方法,然后将其作为参数传递给 Thread 类的构造函数来创建线程。这种方式更适合多个线程共享资源的场景,因为 Java 不支持多重继承,实现 Runnable 接口可以避免这个限制。
  2. 线程池创建方式:
    • newFixedThreadPool:创建一个固定大小的线程池,当提交的任务数超过线程池大小时,任务会在队列中等待,直到有线程空闲。
    • newSingleThreadExecutor:创建一个单线程的线程池,任务会依次执行,保证顺序性。
    • newCachedThreadPool:创建一个可缓存的线程池,如果线程池中有空闲线程则复用,没有则创建新线程,当线程空闲一段时间后会被回收。
  3. HashMap 在 JDK1.7 和 JDK1.8 区别:
    • JDK1.7:是数组+链表结构。当向 HashMap 中插入元素时,首先计算元素的哈希值,然后通过哈希值找到对应的数组位置,如果该位置为空,则直接插入;如果不为空,则采用头插法将新元素插入到链表头部。
    • JDK1.8:是数组+链表+红黑树结构。计算哈希值后找到数组位置,若为空则直接插入;若不为空,首先检查是否为链表,如果是链表且长度大于 8 且数组长度大于 64 时,链表会转换为红黑树,插入元素时按照红黑树的规则进行插入。当红黑树节点数小于等于 6 时,又会转换回链表。
  4. Spring 中 Bean 的作用域:
    • singleton:单例模式,整个 Spring 容器中只有一个实例。
    • prototype:原型模式,每次获取 Bean 时都会创建一个新的实例。
    • request:在一次 HTTP 请求中有效。
    • session:在一个 HTTP Session 中有效。
    • globalSession:在一个全局的 HTTP Session 中有效(一般用于 Portlet 环境)。
  5. Spring Boot 读取配置文件: 可以通过 @Value 注解读取配置文件中的属性。例如在一个类中定义一个属性,然后在属性上使用 @Value("${属性名}") 注解,Spring Boot 会自动将配置文件中对应的属性值注入到该属性中。
  6. MyBatis 动态 SQL 语句编写:
    • 标签:用于条件判断,根据条件决定是否包含某些 SQL 片段。例如:SQL 片段。
    • 标签:用于循环遍历集合或数组。例如:SQL 片段,可以方便地处理批量插入、更新等操作。
  7. Dubbo 服务调用原理:
    • 注册中心:服务提供者将自己的服务信息注册到注册中心,服务消费者从注册中心获取服务提供者的地址等信息。
    • 集群容错:当有多个服务提供者时,Dubbo 会根据集群容错策略选择一个合适的提供者进行调用,如失败重试、负载均衡等。
    • 负载均衡:Dubbo 提供了多种负载均衡策略,如随机、轮询、加权随机、加权轮询等,根据不同的场景选择合适的策略来分配请求到不同的服务提供者。
  8. RabbitMq 保证消息可靠性:
    • 持久化消息:将消息持久化到磁盘,即使 RabbitMq 服务器重启,消息也不会丢失。可以通过设置队列和消息的持久化属性来实现。
    • 确认机制:生产者发送消息后,可以通过确认机制知道消息是否成功到达 Broker。有两种确认方式,事务机制和发送方确认机制,发送方确认机制性能更好,通过设置 confirmCallback 来处理确认结果。
    • 消费者确认:消费者接收消息后,可以通过手动确认或自动确认的方式告知 RabbitMq 消息已被处理。手动确认可以保证消息处理的可靠性,避免消息丢失或重复消费。
  9. xxl-job 核心组件:
    • 调度中心:负责管理任务调度规则、触发调度等。是整个 xxl-job 的核心控制组件。
    • 执行器:负责执行具体的任务。执行器可以部署在多个机器上,接收调度中心的任务并执行。
    • 任务管理:包括任务的创建、编辑、删除等操作,在调度中心进行管理。
    • 日志管理:记录任务执行的日志,方便查看任务执行情况。