Day13

1. Java类加载过程会遇到哪些问题?

  1. 类重复加载(ClassCastException):即使是同一个class文件,但如果由不同的类加载器加载,它们会被认为是不同的类。

    • 解决方法:明确类加载器的使用,尽量共享类加载器或统一加载入口。
  2. 类找不到(ClassNotFoundException):运行时通过反射或动态加载类(如Class.forName("com.test.MyClass"))。原因是类不在当前类加载器的 classpath;可能 JAR 包未引入或路径错误。

  3. NoClassDefFoundError:编译时类存在,但运行时 JVM 加载类失败。原因是依赖的类在运行时缺失(如某个 JAR 被删除);静态初始化失败,导致类加载失败(例如抛出异常)。

  4. 类加载死循环:A 类静态字段依赖 B 类,B 类又依赖 A。可能会导致栈溢出或者某个类初始化失败。

  5. 双亲委派导致类加载冲突(或不加载):自定义类加载器加载类时,父加载器已经加载了同名类;尤其在加载 JDK 核心类重定义版本时会被拦截。

    • 打破双亲委派(如 SPI、Tomcat 插件类加载器)
    • 明确自定义加载逻辑
  6. 初始化异常(ExceptionInInitializerError):在类初始化(执行static{}块或静态字段赋值)抛出异常。原因是例如除零、空指针等导致类初始化失败。一旦初始化失败,该类就不能再被使用,JVM 会抛出该错误。

2. 介绍下MySQL的索引?

索引是提高数据库查询效率的一种数据结构。就像书的目录页,可以快速定位到想要查找的内容。在没有索引时,MySQL 只能全表扫描,查询效率低;有了索引后,可以大幅提高 SELECT 查询的速度,尤其是大数据量时。

MySQL 的 InnoDB 存储引擎使用的是 B+ 树结构来组织索引数据。B+ 树是一种多路平衡查找树,所有的实际数据都保存在叶子节点,非叶子节点仅存储索引键和指向子节点的指针。相比于 B 树,B+ 树的非叶子节点不存储具体数据,使得单个节点可以容纳更多索引项,从而降低树的高度,提高查询效率。InnoDB 中的主键索引是聚簇索引,数据以主键顺序存储在 B+ 树的叶子节点中,而普通索引是二级索引,其叶子节点存储的是对应主键的值,需要通过回表操作获取完整数据。B+ 树叶子节点之间还通过指针连接成有序链表,便于范围查询和排序操作。因此,B+ 树结构能够在保持有序的同时,兼顾查找效率和磁盘访问性能,是数据库索引的理想选择。

索引类型 简介
主键索引(Primary Key) 默认创建,唯一且非空
唯一索引(Unique) 保证列值唯一,但可为空
普通索引(Index) 最基本的加速搜索用
复合索引(Composite) 多列组成的联合索引
前缀索引(Prefix) 针对长文本字段做部分前缀索引
全文索引(Fulltext) 用于自然语言搜索(如文章)
空间索引(Spatial) 针对 GIS 类型的数据

3. MySQL订阅binlog的中间件是什么?有什么用?

阿里开源在 Canal,它是一个用于订阅和消费 MySQL Binlog 的中间件。它通过模拟 MySQL 主从赋值的交互协议,将自己伪装成一个 MySQL 的从节点,向主库发送 dump 请求。主库接收到请求后,会将实时生成的 Binlog 日志推送给 Canal。Canal 接收后对 Binlog 的字节流进行解析,提取出数据库的变更信息(如 INSERT、UPDATE、DELETE),并将其转换为结构化的增量数据格式,供下游系统(如 Kafka、Redis、Elasticsearch等)订阅使用。种机制广泛应用于数据库异构同步、缓存自动更新、实时数据分析、搜索引擎同步等场景,是构建高实时数据链路的重要组件。

通过 Canal 订阅 Binlog 并发送变更日志到 MQ,再由消费者订阅消息并删除缓存,同时结合 ACK 确认机制,可以实现 MySQL 与 Redis 缓存之间的强一致性控制,是目前微服务系统中非常实用的一种缓存同步策略。

4. 限流算法有哪些?

  1. 固定窗口算法(Fixed Window):将时间划分为固定长度的窗口(如每秒、每分钟),每个窗口内设置一个计数器,记录请求次数。一旦达到设定阈值,新请求将被拒绝,直到下一个时间窗口开始,计数器重置。
    • 举例:允许每秒 100 个请求,若第 0.999 秒来了 100 个,第 1.000 秒又来了 100 个,系统实际上在瞬间处理了 200 个请求。(容易发生"突刺流量"(窗口临界点前后大量请求累计)问题。)
  2. 滑动窗口算法(Sliding Window):把时间窗口进一步划分为多个小窗口(例如每秒分成 10 个小格,每个 100ms),记录每个小格的请求数。当前时间点的总请求数 = 当前滑动窗口中的所有小格的请求总和。如果总和 ≤ 限流值 就放行,否则限流。
  3. 漏桶算法(Leaky Bucket):可以把它想象成一个漏水的桶,请求以任意速率进入桶中,但系统处理速率是固定的(水匀速露出)。如果桶满了(处理不过来),则新请求会被丢弃或排队。
    • 桶就是"缓冲队列"
    • 控制的是处理速率:固定速率漏水
    • 超出容量的就会被丢弃
  4. 令牌桶算法(Token Bucket):系统以恒定速率往桶中放令牌(比如每 100ms 放 1 个),请求到来时必须先拿到一个令牌才能继续处理。若桶满了就不再生成新令牌;请求来了但无令牌就被拒绝。
    • 控制的是"请求通行的资格"
    • 令牌是"许可证"
    • 有令牌就放行,没有就限流
    • 允许短时间内的突发流量,因为可以积攒令牌
相关推荐
GM_8282 分钟前
【最新最完整】SpringAI-1.0.0开发MCP Server,搭建MCP Client 实战笔记(进阶+详细+完整代码)
java·后端·ai编程·springai·mcp
都叫我大帅哥3 分钟前
Java DelayQueue:时间管理大师的终极武器
java
秋千码途10 分钟前
小架构step系列27:Hibernate提供的validator
java·spring·架构·hibernate
都叫我大帅哥11 分钟前
TOGAF迁移规划阶段全解密:从菜鸟到达人的通关秘籍
java
探索java13 分钟前
深入理解 Spring 中的 XmlBeanFactory 原理及实践
java·spring·xmlbeanfactory
hqxstudying2 小时前
Java异常处理
java·开发语言·安全·异常
我命由我123455 小时前
Kotlin 数据容器 - List(List 概述、创建 List、List 核心特性、List 元素访问、List 遍历)
java·开发语言·jvm·windows·java-ee·kotlin·list
武子康7 小时前
Java-80 深入浅出 RPC Dubbo 动态服务降级:从雪崩防护到配置中心秒级生效
java·分布式·后端·spring·微服务·rpc·dubbo
PAK向日葵8 小时前
【算法导论】如何攻克一道Hard难度的LeetCode题?以「寻找两个正序数组的中位数」为例
c++·算法·面试
YuTaoShao10 小时前
【LeetCode 热题 100】131. 分割回文串——回溯
java·算法·leetcode·深度优先