当前位置: 首页 > news >正文

实用指南:【Java八股文】13-中间件面试篇

实用指南:【Java八股文】13-中间件面试篇

【Java八股文】13-中间件面试篇

  • RabbitMQ
    • 什么是消息队列 (MQ)?为什么要使用消息队列?
    • 同步通信和异步通信有什么区别?
    • RabbitMQ 是什么?它有哪些核心组件?
    • 如何保证消息的可靠性?
    • RabbitMQ的事务机制
    • MQ怎么避免重复消费?
    • 什么是死信队列 (DLX)?它有什么作用?
    • 什么是延时队列/延迟队列?如何实现延时队列?
    • 什么是惰性队列?它解决了什么问题?
    • 如何保证Canal+MQ同步消息的顺序性?
  • Kafka
    • 你说说 Kafka 为什么是高性能的?
    • Kafka的使用场景,是否有消息丢失的情况
    • RocketMQ、Kafka 和 RabbitMQ
  • Elasticsearch
    • 什么是 Elasticsearch?它与 MySQL 有什么区别?
    • 什么是倒排索引?在 Elasticsearch 中作用?
    • 倒排索引构建过程
    • Elasticsearch 中什么是索引 (Index)?文档 (Document)?
    • 如何保证 MySQL 和 Elasticsearch 数据同步?
    • Canal+MQ如何同步商品信息到ES中?
  • Docker
    • Docker和传统虚拟机有什么区别?
    • Docker 和 k8s 之间是什么关系?
    • Dockerfile和DockerCompose
  • Git
    • git使用工作流程
    • git merge 、git rebase、 git fetch的区别


RabbitMQ

什么是消息队列 (MQ)?为什么要使用消息队列?

消息队列 (Message Queue - MQ) 是一种异步通信机制,允许不同的应用程序或服务通过消息进行解耦和通信。 使用 MQ 的主要原因包括:

同步通信和异步通信有什么区别?

  • 同步通信 (Synchronous): 请求发出后,发送者必须等待接收者响应才能继续执行。类似于打电话,需要对方接听并回应。 问题: 阻塞等待,效率低,依赖性强。
  • 异步通信 (Asynchronous): 请求发出后,发送者无需等待接收者响应,可以继续执行其他任务。接收者会在稍后处理请求并通知发送者 (通常通过回调或消息)。类似于发短信,发送后无需等待回复。 优点: 高效,解耦,非阻塞。

RabbitMQ 是什么?它有哪些核心组件?

RabbitMQ 是一个开源的消息队列中间件,基于 AMQP (高级消息队列协议) 实现。 核心组件包括:

如何保证消息的可靠性?

消息可靠性通常从生产者、MQ Broker 和消费者三个方面考虑:

  • 生产者消息确认机制 (Producer Confirmation):
    • Publisher Confirm (发布确认): 生产者发送消息后,MQ Broker 返回确认 (ACK) 或拒绝 (NACK),生产者根据结果判断消息是否成功发送到 Broker。
    • Publisher Returns (发布回退): 当消息成功到达 Exchange,但 Exchange 无法路由到任何队列时,Broker 会将消息退回给生产者 (需要设置 mandatory 参数)。
  • 消息持久化 (Message Persistence):
    • 队列持久化: 声明队列时设置为持久化,即使 RabbitMQ 重启,队列元数据也不会丢失。
    • 消息持久化: 发送消息时设置为持久化,消息会被写入磁盘,即使 RabbitMQ 服务崩溃重启,消息也不会丢失 (但会牺牲一些性能)。
  • 消费者确认机制 (Consumer Acknowledgement - ACK):
    • 手动 ACK (Manual Acknowledgement): 消费者在成功处理消息后,手动发送 ACK 给 RabbitMQ Broker。 如果消费者在处理消息过程中崩溃或未发送 ACK,Broker 会将消息重新投递给其他消费者或重回队列。
    • 自动 ACK (Auto Acknowledgement): 消费者接收到消息后,RabbitMQ Broker 立即认为消息已被成功消费 (存在消息丢失风险,不推荐用于高可靠场景)。
  • 失败重试机制 (Retry Mechanism): 消费者消费消息失败时,可以进行重试。

RabbitMQ的事务机制

RabbitMQ 的事务是通过 Channel 的事务性 (Transactional Channel) 来实现的。 我们可以通过以下步骤开启和使用事务:

  • 将 Channel 设置为事务模式: 通过 channel.txSelect() 命令将当前的 Channel 设置为事务模式。
  • 执行消息发布操作: 在事务模式下,我们像正常一样使用 channel.basicPublish() 发布消息。
  • 提交事务或回滚事务:
    • channel.txCommit(): 如果消息发布成功,并且我们希望提交事务,就调用 txCommit()。 这会告知 Broker 提交当前事务内的所有操作 (例如,消息发布)。
    • channel.txRollback(): 如果在消息发布过程中发生任何错误,或者我们想取消本次发布,就调用 txRollback()。 这会告知 Broker 回滚当前事务内的所有操作。

MQ怎么避免重复消费?

  • 需要保证MQ消费消息的幂等性。使用数据库的唯一约束去控制。添加唯一索引保证添加数据的幂等性
  • 使用token机制发送消息时给消息指定一个唯一的ID,发送消息时将消息ID写入Redis消费时根据消息ID查询Redis判断是否已经消费,如果已经消费则不再消费。

什么是死信队列 (DLX)?它有什么作用?

死信队列 (Dead Letter Exchange - DLX) 是一种特殊的 Exchange,用于接收无法被正常消费的消息 (死信消息)。 死信消息通常是因为以下原因产生的:

作用: DLX 可以用来处理消费失败的消息,例如:

什么是延时队列/延迟队列?如何实现延时队列?

延时队列/延迟队列 (Delayed Queue) 是一种消息在发送后不会立即被消费,而是延迟一段时间后才被消费的队列。 常用于实现定时任务、订单超时取消等功能。

实现方式 (根据 outline):

  • TTL + DLX (Time-To-Live + Dead Letter Exchange):
    • 声明一个 延迟队列 (设置消息 TTL)。
    • 声明一个 死信交换机 (DLX) 和 死信队列 (DLQ)。
    • 将 延迟队列 的 死信交换机 设置为 DLX, 死信路由键 设置为 DLQ 的路由键。
    • 生产者发送消息到 延迟队列,并设置消息的 TTL。
    • 当消息 TTL 过期 后,RabbitMQ 会将消息 投递到 DLX,DLX 根据路由键将消息 路由到 DLQ。
    • 消费者 监听 DLQ,接收延迟消息并进行处理。
  • RabbitMQ Delay Exchange Plugin: RabbitMQ 官方提供的 Delay Exchange 插件,提供了更方便的延时队列实现。 可以通过设置消息头来指定消息的延迟时间。

什么是惰性队列?它解决了什么问题?

惰性队列 (Lazy Queue) 是 RabbitMQ 提供的一种 特殊的队列类型,用于解决 消息堆积问题。

问题: 默认的 RabbitMQ 队列 (经典队列) 会将消息尽可能地 保存在内存中,以提高性能。 当队列中消息堆积过多时,会 占用大量内存,可能导致 RabbitMQ 性能下降甚至崩溃。

惰性队列的特点: 惰性队列会将 消息尽可能地写入磁盘,只有在消费者需要消费时才加载到内存中。

  • 优点: 可以 存储大量消息,减少内存占用,避免内存溢出。
  • 缺点: 消息存取性能会下降,吞吐量降低。

如何保证Canal+MQ同步消息的顺序性?

Canal解析binlog日志信息按顺序发到MQ的队列中。现在是要保证消费端如何按顺序消费队列中的消息。

解决方法:

Kafka

你说说 Kafka 为什么是高性能的?

Kafka的使用场景,是否有消息丢失的情况

  • 实时数据流处理:Kafka 常用于处理实时数据流,如日志收集、监控数据传输、点击流分析等。
  • 日志聚合:它可以收集来自不同系统的日志,统一传输到中心化的日志存储或分析系统。
  • 事件源架构:用于在微服务架构中传递事件,确保不同服务之间的通信。
  • 消息队列:作为高吞吐量、高可用性的消息队列,支持异步消息处理。
  • 数据管道:Kafka 作为流数据平台,通常用于将数据从一个系统传输到另一个系统,像数据库同步、ETL等。

RocketMQ、Kafka 和 RabbitMQ

Elasticsearch

什么是 Elasticsearch?它与 MySQL 有什么区别?

Elasticsearch (ES) 是 分布式、RESTful 的搜索和分析引擎,基于 Lucene 构建。 与 MySQL 的区别:

什么是倒排索引?在 Elasticsearch 中作用?

倒排索引是 词 (Term) 到文档的映射。

  • 传统索引: 文档 -> 词列表 (找包含词的文档 - 慢)。
  • 倒排索引: 词 -> 文档列表 (找文档中的词 - 快)。

ES 中的作用:

  • 分析文档: 索引时分析文本字段 (分词等)。
  • 建倒排索引: 词指向包含它的文档 ID 列表。
  • 快速全文搜索: 搜索时查倒排索引快速找文档。

倒排索引(Inverted Index)是搜索引擎中常用的一种数据结构,目的是为了高效地进行文本搜索。具体到 Elasticsearch(ES),倒排索引用于存储文档中各个词项(词语)及其出现位置,以便快速查找包含某个词的文档。

倒排索引的基本原理:

  • 词项(Term):文档中的每个单词或短语。
  • 文档(Document)外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

倒排索引构建过程

Elasticsearch 中什么是索引 (Index)?文档 (Document)?

  • 索引 (Index):
    • 文档的逻辑分组,类似 MySQL 的数据库或表。
    • 定义文档的 Mapping (schema)。
  • 文档 (Document):
    • JSON 对象,存储在索引中,类似 MySQL 的行。
    • 包含字段 (键值对),值可以是不同数据类型。
    • 同索引的文档结构可以略有不同 (灵活 Schema)。

如何保证 MySQL 和 Elasticsearch 数据同步?

常用 消息队列 (MQ) - RabbitMQ 同步数据:

  • MySQL 变更 -> 事件: MySQL 数据变动时生成事件 (触发器、Debezium 或程序逻辑)。
  • 发布事件到 MQ (RabbitMQ): 事件发到 RabbitMQ 队列。
  • ES 消费者服务: 专门服务消费 MQ 消息。
  • 更新 Elasticsearch: 消费者服务处理事件,更新 ES 文档。

MQ 同步优势: 异步、可靠、可扩展。

Canal+MQ如何同步商品信息到ES中?

  1. 首先在Elasticsearch中创建商品的索引结构,包括商品的spu信息、sku信息,这样输入关键字可以根据商品的spu去搜索也可以根据商品的sku去搜索。
  2. 在MySQL中创建一张商品信息同步表,当修改商品信息时同时修改商品信息同步表,商品信息同步表的结构与Elasticsearch中的商品索引是一致的。
  3. Canal会读取商品信息同步表的binlog日志,解析日志的内容写入MQ。
  4. 同步程序监听MQ,收到商品的信息后写入Elasticsearch,这样就完成了同步商品信息到ES中。

Docker

Docker和传统虚拟机有什么区别?

Docker 和 k8s 之间是什么关系?

Docker 和 Kubernetes(K8s)是密切相关的,但它们的功能不同:

  • Docker:是一个容器化平台,用于打包、分发和运行应用。它提供了创建、管理和运行容器的工具。容器可以理解为轻量级的虚拟机,但它们共享宿主操作系统的内核。
  • Kubernetes(K8s):是一个容器编排平台,用于自动化容器的部署、扩展和管理。它可以帮助管理多个 Docker 容器,处理容器的生命周期、调度、负载均衡等任务。

Docker 是 K8s 使用的容器运行时(container runtime)。也就是说,K8s 管理和调度的是 Docker 容器的实例。K8s 可以启动、停止和扩展 Docker 容器,但它不提供容器创建的功能,那个是由 Docker 提供的。

Docker 用于创建和运行容器,K8s 用于管理多个 Docker 容器的集群。

Dockerfile和DockerCompose

# 指定基础镜像
FROM java:8-alpine
# # 配置环境变量,JDK的安装目录
# ENV JAVA_DIR=/usr/local
# # 拷贝jdk和java项目的包
# COPY ./jdk8.tar.gz $JAVA_DIR/
# # 安装JDK
# RUN cd $JAVA_DIR \
#  && tar -xf ./jdk8.tar.gz \
#  && mv ./jdk1.8.0_144 ./java8
# # 配置环境变量
# ENV JAVA_HOME=$JAVA_DIR/java8
# ENV PATH=$PATH:$JAVA_HOME/bin
COPY ./docker-demo.jar /tmp/app.jar
# 暴露端口
EXPOSE 8090
# 入口,java项目的启动命令
ENTRYPOINT java -jar /tmp/app.jar
  • Docker Compose可以基于Compose文件帮我们快速的部署分布式应用,而无需手动一个个创建和运行容器!Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行。
version: "3.2"
services:
nacos:
image: nacos/nacos-server
environment:
MODE: standalone
ports:
- "8848:8848"
mysql:
image: mysql:5.7.25
environment:
MYSQL_ROOT_PASSWORD: 123sjbsjb
volumes:
- "$PWD/mysql/data:/var/lib/mysql"
- "$PWD/mysql/conf:/etc/mysql/conf.d/"
userservice:
build: ./user-service
orderservice:
build: ./order-service
gateway:
build: ./gateway
ports:
- "10010:10010"

Git

git使用工作流程

工作流程步骤:

  1. master 分支创建一个新的功能分支
git checkout -b feature-branch
  1. 在功能分支上进行开发和提交
git add . # 添加更改
git commit -m "feature: add new feature" # 提交更改
  1. 保持功能分支与 master 分支同步在功能开发过程中,定期将 master分支的最新更改合并到功能分支,以防止冲突。
git checkout master # 切换到主分支
git pull origin master # 拉取最新的 master
git checkout feature-branch
git merge master # 将 master 的更新合并到 feature 分支
  1. 功能完成后将功能分支合并到 master 分支
git checkout master
git merge feature-branch
  1. 推送到远程仓库并删除功能分支
git push origin master # 推送更新到远程仓库
git branch -d feature-branch # 删除本地功能分支
git push origin --delete feature-branch # 删除远程功能分支

优点:每个功能开发都在独立的分支中进行,避免了不同功能的代码干扰。

缺点:需要频繁合并,管理多个分支可能稍显复杂。

git merge 、git rebase、 git fetch的区别

命令作用特点
git merge将两个分支的更改合并保留分支历史,产生合并提交
git rebase将一个分支的提交重放到另一个分支上重写历史,产生线性历史
git fetch从远程仓库拉取最新的提交和元数据不修改本地工作区,只更新远程跟踪分支
  • 使用 git merge 时,你的分支历史会保留原样,适合保留不同开发路径的痕迹。
  • 使用 git rebase 时,历史会变得更整洁,适合在合并前清理历史。
  • 使用 git fetch 时,只有从远程仓库拉取数据,并不会对本地分支产生直接影响。
http://www.hskmm.com/?act=detail&tid=17283

相关文章:

  • AT_agc012_d [AGC012D] Colorful Balls
  • 02、Python从入门到癫狂:函数与资料容器
  • 第二周第四天2.4
  • 9/25
  • 关闭Edge浏览器页面的圆角效果
  • 搜索二维矩阵II-leetcode
  • Rust/C/C++ 混合构建 - Cmake集成Cargo编译动态库
  • 第12章 day13 关于json请求体
  • CF1349
  • 学习敏捷课程PSM,自考证书分享
  • Rust/C/C++ 混合构建 - 用Bazel构建Rust与C
  • 9.24(补)
  • 9月25号
  • CCF CSP-J 2025_from_黄老师_d
  • 亚马逊与AWS如何通过漏洞赏金计划构建深度安全防御
  • sync.pool 面试题
  • 【JavaEE】SpringIoC与SpringDI - 详解
  • 24.Linux硬盘分区管理 - 详解
  • CCF CSP-J 2025_from_黄老师_km
  • AI一周资讯 250918-250925
  • 云栖小镇现场追踪!触摸AI 未来
  • AT_arc154_d [ARC154D] A + B C ?
  • SQL注入-联合注入
  • JVM对象创建与内存分配
  • 目录
  • 交互:在终端中输入用户信息
  • 电脑迁移技巧:适用于 Windows 10/11 的免费磁盘克隆优秀的工具
  • Java学习日记9.18
  • 一种CDN动态加速首次访问加速方法
  • 9.25