没有理想的人不伤心

Java - 常识及中间件概述

2025/09/11
0
0

1 JDBC

JDBC 提供一些访问各类数据库的接口规范,具体如何访问数据库,由对应的数据库驱动实现 JDBC 的接口
而在用户侧与数据库交互,只需要调用接口与数据库驱动进行交互,数据库驱动再与数据库进行交互

2 Servlet

与 JDBC 类似,Servlet 是 Java 提供的构建 web 应用的接口,用户侧调用 Servlet 接口不需要处理 TCP 连接、解析 HTTP 协议等底层工作,具体的 Servlet 接口由 WEB 服务器实现,用户只需要把 WEB 应用放到诸如 Tomcat 的 WEB 服务器上运行即可。

类比一下:
可以把 Servlet 等价于 GIN web 框架,用于快速构建应用程序,而 Tomcat 负责处理底层的工作,在 go 中,底层的工作由 go 提供的 net/http 包实现。

3 JSP

Java server pages

jsp 文件与 html 文件没有太大区别,只是 jsp 在需要插入变量或者在动态输入的地方使用特殊指令

4 MVC

Model-View-Controller
模型-视图-控制器

Model:管理数据,与数据源交互,以及业务逻辑的编写
View:呈现数据的界面
Controller:处理用户请求,调用相应 Model,并选择视图进行相应

协作流程:

  • 用户通过视图与应用程序交互(例如,点击按钮或填写表单)。
  • 控制器接收用户输入,解析请求,并调用模型来处理数据。
  • 模型执行业务逻辑并更新数据。
  • 控制器从模型获取处理结果,并选择适当的视图来展示这些结果。
  • 视图将更新后的数据呈现给用户。

前后端分离架构下的 MVC:

后端:控制器处理来自前端的请求,调用模型中的业务逻辑,并返回数据(视图)

这里的视图被一定程度上弱化为接口返回的数据,如 json 格式的数据

前端:

  • 前端框架本身也可能采用类似 MVC 的模式。例如,React 中的组件可以看作是视图,而状态管理工具(如 Redux)可以承担模型的角色。
  • 前端负责处理用户交互、更新 UI 并与后端通信。

5 Redis

Redis 是一款高性能的内存键值存储数据库

为什么要用 redis:(高性能、多功能、高可靠性)

  1. 高性能:redis 是基于内存的数据库,读取速度非常快,远高于磁盘存储的数据库(如 mysql),尤其适合处理高频访问的数据
  2. 丰富的数据结构支持:支持 string、hash、list、set 等多种数据结构1736249512210-93662fa2-4156-4edd-8273-90c458f08ae0.png
  3. 持久化机制:提供快照(RDB)、日志(AOF)两种持久化方式,保证内存数据的高效访问的同时,又能避免宕机后的数据丢失
  4. 高可用和分布式支持:支持主从复制、哨兵模式(自动故障转移)和 Redis Cluster(分片集群),能轻松实现高可用部署和水平扩展,满足大规模业务的需求。
  5. 提供了原子性操作,避免在了并发场景的竞态问题

怎么用:
核心操作:

  • Stringset key value(存)、get key(取)、incr key(自增),适合存储简单值(如用户 token、计数器)。
  • Hashhset key field value(存字段)、hget key field(取字段),适合存储对象(如用户信息: user:1 {name: "xxx",age:20})。
  • Listlpush key elem(左插)、rpop key(右取),适合实现队列 / 栈(如消息队列、最新消息列表)。
  • Setsadd key elem(添加元素)、sinter key1 key2(交集),适合去重或关系计算(如共同好友)。

使用 redis 的典型场景:

  1. 缓存(最核心场景)

    • 存储高频访问的热点数据(如商品详情、用户信息),减轻数据库压力。
    • 注意:需设计缓存更新策略(如 Cache Aside 模式:更新数据库后删除缓存),避免缓存穿透(缓存和数据库都无数据,用布隆过滤器拦截)、缓存击穿(热点 key 过期,加互斥锁)、缓存雪崩(大量 key 同时过期,加随机过期时间)。
  2. 会话存储

    • 存储用户登录会话(如 token),替代传统的服务器本地 session,支持分布式系统中多服务共享会话(如微服务架构下的单点登录)。

为什么适合会话存储的场景:

  1. 会话(Session)是用户登录后服务器生成的临时凭证,几乎所有用户操作(如页面跳转、接口请求)都需要验证会话有效性,属于高频访问数据
  2. 会话有明确的 “时效性”(如用户 30 分钟无操作自动失效),需要自动清理过期会话以释放资源。Redis 内置了键过期机制expire key seconds命令),支持为会话设置精确的过期时间、
  3. 分布式支持解决会话共享问题
  1. 简易消息队列
    • 用 List 的lpush(生产者发消息)和rpop(消费者取消息)实现简单队列,适合低延迟、非高可靠要求的场景(高可靠需用专业 MQ 如 RabbitMQ)。

常见面试题:

  1. Redis 为什么是单线程的?单线程为什么能支持高并发?
    答题思路:
  • 单线程原因:Redis 的性能瓶颈是内存而非 CPU,单线程可避免多线程切换的开销(上下文切换、锁竞争),简化设计。
  • 高并发原因:
    • 基于内存操作,避免磁盘 IO 阻塞;
    • 采用 IO 多路复用模型(如 epoll/kqueue),单线程可同时处理多个客户端的网络 IO 请求(非阻塞 IO);
    • 核心操作(如 set、get)是原子性的,无需加锁,执行效率高。
  1. Redis 的持久化机制有哪些?RDB 和 AOF 的区别是什么?如何选择?
    答题思路:
  • 两种机制:RDB(快照)和 AOF(Append Only File)。
  • 区别:
    • RDB:按配置的触发条件(如定时、手动 save/bgsave)生成内存数据的二进制快照;优点是体积小、恢复快;缺点是可能丢失最近一次快照后的数(如宕机)。
    • AOF:记录所有写命令(如 set、hset)到日志文件,恢复时重新执行命令;优点是数据安全性高(可配置每秒 / 每次写同步);缺点是文件体积大、恢复慢。
  • 选择:追求性能和快速恢复用 RDB;追求数据安全性(如金融场景)用 AOF;生产环境常两者结合(RDB 做全量备份,AOF 做增量补充)。
  1. Redis 的过期键删除策略是什么?内存满了之后会怎么处理?
    答题思路:
  • 过期删除策略(混合策略):
    • 惰性删除:访问键时才检查是否过期,过期则删除(节省 CPU,可能浪费内存)。
    • 定期删除:每隔一段时间随机扫描部分过期键并删除(平衡 CPU 和内存)。
  • 内存满时(maxmemory限制):触发内存淘汰策略,按配置删除部分键,常见策略:
    • volatile-lru:从过期键中删除最近最少使用的;
    • allkeys-lru:从所有键中删除最近最少使用的;
    • volatile-ttl:删除过期键中剩余时间最短的;
    • 其他(如 LFU、随机等)。
  • 注意:若淘汰策略为noeviction(默认),则不删除键,拒绝所有写操作。

6 kafka

Kafka 是一个分布式、高吞吐量、高可靠性流处理平台(最初定位为分布式消息队列,后扩展为流处理)

分布式消息队列

核心概念

  • Topic:消息的 “分类标签”,所有消息按 Topic 划分(类似消息队列的 “队列名”)。
  • Partition:每个 Topic 分为多个 Partition(分区),消息按顺序写入 Partition(类似 “日志文件”)。Partition 是 Kafka 并行处理的核心(可分布在不同服务器,实现负载均衡)。
  • Producer:消息生产者,向 Topic 写入消息(可指定 Partition 或按规则自动分配)。
  • Consumer:消息消费者,从 Topic 读取消息(可多消费者组并行消费,组内消费者分工读取不同 Partition)。
  • Broker:Kafka 服务器节点,一个 Kafka 集群由多个 Broker 组成,负责存储消息和处理读写请求。
  • Replica:每个 Partition 有多个副本(Replica),主副本(Leader)负责读写,从副本(Follower)同步主副本数据,保证数据可靠性(Leader 故障时,Follower 可切换为 Leader)。

为什么要用 kafka:

  1. 超高吞吐量

    • 基于 “分区并行”(多 Partition 同时读写)、“批量发送 / 接收”(减少网络 IO 次数)、“零拷贝”(数据直接从内核缓冲区写入磁盘,跳过用户态)等机制,单 Broker 吞吐量可达每秒数十万条消息,远超传统消息队列,适合海量数据场景。
  2. 高可靠性与持久化

    • 消息写入磁盘(而非仅存内存),支持配置保留时间(如 7 天),配合多副本(Replica)机制,即使部分 Broker 故障,数据也不会丢失(通过 ISR 机制保证副本同步)。
  3. 强扩展性

    • 集群可通过增加 Broker 节点水平扩展(无需停机),Partition 可动态迁移到新节点,轻松应对数据量增长。
  4. 流处理原生支持

    • 提供 Kafka Streams API,可直接基于 Kafka 进行简单的流处理(如过滤、聚合),无需依赖外部框架,降低架构复杂度。
  5. 灵活的消费模式

    • 支持 “至少一次”“最多一次”“精确一次” 三种消费语义(通过 offset 记录消费位置),满足不同场景的数据一致性需求(如金融场景需 “精确一次”)。

适用场景:

  1. 日志 / 数据收集(最经典场景)
  • 场景描述:分布式系统中,各服务(如 Web 服务、数据库、缓存)会产生大量日志(访问日志、错误日志、操作日志等),需要集中收集后进行分析(如监控、审计、故障排查)。
  • 为何适合
    • 日志产生速度快、数据量大(如每秒数万条),Kafka 的高吞吐量(单 Broker 可达每秒数十万条)可轻松承载。
    • 支持持久化存储(消息写入磁盘,可配置保留时间),避免日志丢失,方便后续离线分析(如结合 ELK 栈:Kafka 作为日志管道,将日志转发给 Elasticsearch 存储、Kibana 可视化)。
  1. 消息队列(异步通信与服务解耦)
  • 场景描述:微服务架构中,服务间需要异步通信(如订单系统下单后,通知库存系统减库存、支付系统扣钱、消息系统发通知),避免同步调用导致的 “服务耦合” 和 “级联故障”。
  • 为何适合
    • 支持 “发布 - 订阅” 模式(多消费者组可独立消费同一 Topic),满足不同服务对同一事件的处理需求(如订单消息同时被库存、支付、消息服务消费)。
    • 高可靠性(多副本机制)保证消息不丢失,避免因下游服务临时故障导致的消息丢失。
  1. 实时流处理
  • 场景描述:对实时产生的数据进行即时分析(如实时监控、实时推荐、实时风控),例如电商平台实时统计商品销量、金融系统实时检测异常交易。
  • 为何适合
    • 低延迟(毫秒级)可满足实时处理需求。
    • 结合流处理框架(如 Spark Streaming、Flink),Kafka 可作为 “数据源” 和 “结果存储”,形成完整的实时数据处理链路(如数据从 Kafka 流入 Flink 计算,结果写回 Kafka 供下游使用)。

7 MQ

MQ(message queue,消息队列)是一种基于 “生产者 - 消费者” 模型的中间件,核心作用是在不同系统 / 服务之间传递消息,并通过 “异步通信”“缓冲消息” 等特性解决系统间的耦合、流量峰值、数据同步等问题。

简单说,MQ 就像 “系统间的邮差”:生产者(发送消息的系统)把消息投递到队列,消费者(接收消息的系统)从队列中取走消息处理,双方无需直接通信,通过队列间接交互。

MQ 的核心价值是 “解耦、异步、削峰“

MQ 有 rocket MQ、rabbit MQ 等不同家的产品

为什么使用 mq:

MQ 的本质是通过 “异步化”“解耦”“缓冲” 解决分布式系统的核心痛点,具体优势如下:

  1. 降低系统耦合度
    服务间通过 MQ 间接通信,无需知道对方的存在,新增 / 移除服务只需修改订阅关系,减少代码改动,提高系统灵活性。

  2. 提高系统响应速度
    非核心流程异步处理,用户无需等待所有步骤完成,核心接口响应时间大幅缩短,提升用户体验。

  3. 保护后端系统稳定
    面对流量峰值时,MQ 缓冲请求,避免后端服务(如数据库、业务服务)被瞬间高并发压垮,起到 “削峰” 作用。

  4. 支持分布式场景扩展
    在微服务、分布式系统中,MQ 是服务间通信的核心组件,支持跨机器、跨集群的数据传输,适配大规模部署。

MQ 使用场景:

  1. 系统解耦(核心场景)
  • 问题:在分布式系统中,服务间直接调用会导致 “强耦合”(比如 A 服务调用 B、C、D 服务,若新增一个 E 服务需要 A 的数据,必须修改 A 的代码)。
  • MQ 解决方式:A 服务作为生产者,将消息发送到 MQ 的某个队列,B、C、D、E 等服务作为消费者,自行从队列中获取消息。A 无需关心谁在消费,新增服务只需订阅队列即可,彻底解除服务间的直接依赖。
  • 例子:电商订单系统下单后,需要通知库存、支付、物流、短信服务。若订单系统直接调用这四个服务,耦合度极高;用 MQ 后,订单系统只需发送 “订单创建” 消息到队列,其他服务各自消费处理,订单系统代码无需修改。
  1. 异步通信(提升系统响应速度)
  • 问题:同步调用时,一个流程需要等待所有依赖服务处理完成才能返回(比如用户注册后,需要同步发送短信、邮件、创建用户档案,总耗时是各步骤之和,导致用户等待时间长)。
  • MQ 解决方式:核心流程(如用户注册)完成后,将非核心流程(发短信、邮件)的消息异步发送到 MQ,无需等待其处理,直接返回结果。消费者后续再异步处理这些消息。
  • 例子:用户注册接口,只需写入数据库后返回 “注册成功”,同时发送 “发送短信”“发送邮件” 消息到 MQ。用户无需等待短信 / 邮件发送完成,接口响应时间从几百毫秒缩短到几十毫秒。
  1. 削峰填谷(应对流量峰值)
  • 问题:秒杀、大促等场景下,流量会瞬间暴涨(比如每秒 10 万请求),直接冲击后端服务(如数据库),可能导致服务崩溃。
  • MQ 解决方式:MQ 作为 “缓冲池”,接收所有峰值请求并暂存,后端服务按自身处理能力(比如每秒 1 万请求)从 MQ 中 “匀速” 取消息处理,避免被峰值压垮。
  • 例子:秒杀系统中,用户下单请求先进入 MQ,订单服务以稳定速度消费队列中的请求,超出处理能力的请求在 MQ 中排队,避免数据库因瞬间高并发宕机。

8 Elasticsearch

Elasticsearch(简称 ES)是一个分布式、高扩展、高实时的全文搜索引擎,基于 Lucene 引擎封装,专注于解决海量数据的检索、分析和存储问题。

JSON 格式存储数据,提供 RESTful API 进行交互,支持复杂的查询和聚合分析,广泛应用于日志分析全文检索、实时监控等场景。

为什么要使用 ES:

  1. 全文检索能力:支持对文本进行分词、模糊匹配、同义词扩展、相关性排序等,远超传统数据库的 LIKE 查询。
  2. 分布式架构:数据自动分片存储在多个节点,支持水平扩展(加机器就能提升性能),天然具备高可用(节点故障不影响服务)。
  3. 实时性:写入数据后秒级可查询(近实时,默认 1 秒刷新一次索引),适合对时效性要求高的场景。
  4. 丰富的查询与聚合:支持结构化查询(类似数据库  where)、全文检索、地理空间查询、统计聚合(分组、求和、平均值等)。
  5. 灵活的 schema:无需预先定义严格的数据结构(类似 MongoDB),字段可以动态添加,适合处理半结构化 / 非结构化数据(如日志、文档)。

ES 使用场景:

  1. 全文检索(最核心场景)
  • 电商商品搜索:用户输入 “超薄笔记本”,ES 会分词(“超薄”“笔记本”),匹配商品标题、描述中的关键词,并按相关性(如关键词出现频率、位置)排序,同时支持筛选(价格区间、品牌)、高亮显示匹配内容。
  • 网站 / APP 站内搜索:如知乎的内容搜索、论坛的帖子搜索,需要快速从百万级文章中找到匹配内容,并支持模糊查询(如错别字容错)。
  1. 日志与指标分析(ELK 生态核心)
  • 日志集中收集与分析:通过 ELK 栈(Elasticsearch + Logstash + Kibana)收集服务器、应用的日志(如 Nginx 访问日志、Java 错误日志),用 ES 存储并检索,通过 Kibana 可视化分析(如错误率趋势、访问量峰值)。
  • 监控指标存储:收集服务器 CPU、内存、接口响应时间等指标,实时检索异常数据(如 “过去 5 分钟响应时间> 1s 的接口”)。
  1. 实时数据分析
  • 业务监控:如电商平台实时统计 “近 10 分钟各地区下单量”“某商品的实时销量排名”,ES 的聚合功能可快速计算结果。
  • 用户行为分析:存储用户点击、浏览记录,分析 “某页面的停留时长分布”“不同地区用户的偏好” 等。
  1. 地理空间搜索
  • 基于地理位置的检索:如外卖 APP 搜索 “3 公里内的咖啡店”,ES 支持地理坐标存储和距离计算,快速筛选符合条件的结果。
  1. 推荐系统辅助
  • 存储用户画像、商品标签,通过 ES 的相关性查询快速找到 “与用户历史浏览商品相似的商品”,辅助推荐算法生成结果。