【Java基础】异常体系:Error vs Exception、受检/非受检异常、try-catch-finally、try-with-resources(附《思维导图》+《面试高频考点清单》)

简介: 本文系统梳理Java异常体系:以`Throwable`为根,分`Error`(JVM级不可恢复错误)与`Exception`(可处理异常);后者再分为编译期强制处理的**受检异常**(如`IOException`)和运行时抛出的**非受检异常**(如`NullPointerException`),并详解`try-catch-finally`、`try-with-resources`、异常链及最佳实践。

思维导图

Java异常体系全方位结构化总结

一、异常体系整体架构

Java异常是程序运行时发生的非正常情况,所有异常都继承自java.lang.Throwable类,形成了严格的继承层次结构。

java.lang.Object
    └── java.lang.Throwable
        ├── java.lang.Error
        └── java.lang.Exception
            ├── java.lang.RuntimeException
            └── 其他受检异常

二、Error vs Exception:两大核心分支

2.1 Error(错误)

定义:JVM内部或系统级别的严重问题,程序无法处理,通常不应该被捕获。

特点

  • 属于非受检异常
  • 表示系统级错误或资源耗尽
  • 一旦发生,程序通常无法恢复
  • 不要求程序员在代码中显式处理

常见Error示例

  • OutOfMemoryError:内存溢出
  • StackOverflowError:栈溢出
  • NoClassDefFoundError:类定义未找到
  • VirtualMachineError:虚拟机错误

2.2 Exception(异常)

定义:程序运行时发生的可预见、可处理的非正常情况,是程序员需要关注和处理的部分。

特点

  • 分为受检异常非受检异常两大类
  • 表示程序逻辑错误或外部环境问题
  • 通常可以被捕获和处理
  • 处理后程序可以继续运行

Error与Exception核心对比

对比维度 Error Exception
发生层次 JVM/系统级别 应用程序级别
可恢复性 几乎不可恢复 通常可以恢复
处理方式 不建议捕获 建议捕获并处理
设计目的 标识系统致命错误 标识程序可处理的异常
示例 OutOfMemoryError NullPointerException, IOException

三、受检异常 vs 非受检异常

3.1 受检异常(Checked Exception)

定义:编译器强制要求必须处理的异常,否则代码无法编译通过。

特点

  • 继承自Exception但不包括RuntimeException及其子类
  • 必须显式声明throws或使用try-catch捕获
  • 用于表示程序外部的、可预见的异常情况
  • 设计目的是强制程序员处理可能的错误

常见受检异常示例

  • IOException:IO操作异常
  • SQLException:数据库操作异常
  • ClassNotFoundException:类未找到异常
  • FileNotFoundException:文件未找到异常

3.2 非受检异常(Unchecked Exception)

定义:编译器不强制要求处理的异常,也称为运行时异常。

特点

  • 包括RuntimeException及其子类和Error及其子类
  • 不要求显式声明throws或捕获
  • 通常表示程序逻辑错误
  • 发生时会导致程序终止运行

常见非受检异常示例

  • NullPointerException:空指针异常
  • ArrayIndexOutOfBoundsException:数组越界异常
  • ClassCastException:类型转换异常
  • ArithmeticException:算术异常(如除以零)
  • IllegalArgumentException:非法参数异常

3.3 设计原则与争议

  • 受检异常适用场景:外部资源操作(文件、网络、数据库)、必须处理的业务异常
  • 非受检异常适用场景:程序逻辑错误、参数校验失败、不可恢复的错误
  • 现代Java趋势:越来越多的框架倾向于使用非受检异常,避免过度的异常声明和处理

四、异常处理机制:try-catch-finally

4.1 基本语法结构

try {
   
    // 可能抛出异常的代码
} catch (ExceptionType1 e) {
   
    // 处理ExceptionType1类型的异常
} catch (ExceptionType2 e) {
   
    // 处理ExceptionType2类型的异常
} finally {
   
    // 无论是否发生异常都会执行的代码
}

4.2 执行流程详解

  1. 正常情况:执行try块全部代码 → 跳过catch块 → 执行finally块 → 继续执行后续代码
  2. 发生异常并被捕获:执行try块到异常发生处 → 执行匹配的catch块 → 执行finally块 → 继续执行后续代码
  3. 发生异常未被捕获:执行try块到异常发生处 → 执行finally块 → 异常向上抛出

4.3 关键特性与注意事项

  • catch块顺序:必须从子类到父类,否则子类异常会被父类catch块提前捕获,导致编译错误
  • finally块
    • 唯一不执行的情况:调用System.exit(0)终止JVM
    • 用于释放资源(关闭文件、数据库连接等)
    • 不要在finally块中使用return语句,会覆盖try或catch中的return值
  • 异常捕获范围:避免捕获过于宽泛的异常(如直接捕获Exception或Throwable)

4.4 异常处理的最佳实践

  1. 具体异常优先:捕获具体的异常类型,而不是通用的Exception
  2. 异常信息完整:在catch块中记录完整的异常堆栈信息
  3. 不要忽略异常:空的catch块会隐藏错误,难以排查问题
  4. 异常转译:将底层异常转换为业务异常,向上层抛出
  5. 资源释放:在finally块中释放资源,或使用try-with-resources

五、自动资源管理:try-with-resources

5.1 背景与问题

传统的try-catch-finally方式释放资源存在以下问题:

  • 代码冗长,需要多层嵌套
  • 容易忘记释放资源
  • 资源关闭时可能抛出异常,覆盖原始异常
  • 多个资源关闭时代码复杂

5.2 基本语法

try (ResourceType resource1 = new ResourceType();
     ResourceType resource2 = new ResourceType()) {
   
    // 使用资源的代码
} catch (Exception e) {
   
    // 处理异常
}

5.3 工作原理

  • 实现了java.lang.AutoCloseable接口的类可以在try-with-resources中使用
  • try块结束时,会自动调用资源的close()方法
  • 资源关闭的顺序与声明顺序相反
  • 关闭资源时抛出的异常会被抑制,原始异常会被保留

5.4 AutoCloseable接口

public interface AutoCloseable {
   
    void close() throws Exception;
}
  • Java 7引入
  • 所有实现了Closeable接口的类都自动实现了AutoCloseable
  • 自定义资源类只需实现此接口即可使用try-with-resources

5.5 异常抑制(Suppressed Exceptions)

  • 当try块抛出异常,且close()方法也抛出异常时
  • 原始异常会被保留,close()方法抛出的异常会被添加为抑制异常
  • 可以通过Throwable.getSuppressed()方法获取抑制异常列表

5.6 与传统方式对比

传统方式

InputStream in = null;
try {
   
    in = new FileInputStream("file.txt");
    // 读取文件
} catch (IOException e) {
   
    e.printStackTrace();
} finally {
   
    if (in != null) {
   
        try {
   
            in.close();
        } catch (IOException e) {
   
            e.printStackTrace();
        }
    }
}

try-with-resources方式

try (InputStream in = new FileInputStream("file.txt")) {
   
    // 读取文件
} catch (IOException e) {
   
    e.printStackTrace();
}

六、异常体系的高级特性

6.1 多异常捕获(Java 7+)

try {
   
    // 可能抛出多种异常的代码
} catch (IOException | SQLException e) {
   
    // 统一处理多种异常
}
  • 多个异常类型之间用竖线|分隔
  • 这些异常类型之间不能有继承关系
  • 异常变量e是隐式final的,不能在catch块中重新赋值

6.2 异常链

  • 将原始异常包装成新的异常抛出,保留异常的完整堆栈信息
  • 构造方法:new Exception("message", cause)
  • 获取原始异常:e.getCause()
try {
   
    // 数据库操作
} catch (SQLException e) {
   
    throw new BusinessException("数据库操作失败", e);
}

6.3 自定义异常

  • 继承自Exception(受检异常)或RuntimeException(非受检异常)
  • 提供无参构造方法和带消息的构造方法
  • 提供带消息和原因的构造方法
public class BusinessException extends RuntimeException {
   
    public BusinessException() {
   
        super();
    }

    public BusinessException(String message) {
   
        super(message);
    }

    public BusinessException(String message, Throwable cause) {
   
        super(message, cause);
    }
}

七、异常处理的最佳实践总结

  1. 异常类型选择

    • 程序逻辑错误使用非受检异常
    • 外部资源操作使用受检异常
    • 业务异常建议使用非受检异常
  2. 异常处理原则

    • 能处理的异常就地处理,不能处理的向上抛出
    • 不要捕获Throwable或Error
    • 不要忽略异常(空catch块)
    • 不要在finally块中使用return或throw语句
  3. 资源管理

    • 优先使用try-with-resources管理资源
    • 确保所有资源都被正确释放
  4. 异常信息

    • 异常消息要清晰、具体,包含上下文信息
    • 记录完整的异常堆栈信息
    • 不要在异常消息中包含敏感信息
  5. 性能考虑

    • 异常处理有一定的性能开销,不要用于控制正常流程
    • 避免在循环中使用try-catch
    • 不要频繁创建和抛出异常

Java异常体系面试核心考点清单 + 高频面试题标准答案

一、基础概念类(必问)

核心考点

  1. 异常体系完整继承结构
  2. Error与Exception的本质区别
  3. 受检异常与非受检异常的定义、区别及设计原则

高频面试题

1. 请画出Java异常体系的继承结构图

标准答案

java.lang.Object
    └── java.lang.Throwable(所有异常和错误的根类)
        ├── java.lang.Error(系统级错误,不可恢复)
        └── java.lang.Exception(程序级异常,可处理)
            ├── java.lang.RuntimeException(运行时异常,非受检)
            └── 其他Exception子类(受检异常)

2. Error和Exception有什么区别?

标准答案

维度 Error Exception
发生层次 JVM/操作系统级别的严重问题 应用程序运行时的非正常情况
可恢复性 几乎不可恢复,程序只能终止 通常可以通过捕获处理恢复运行
处理方式 不建议捕获,捕获也无法解决 必须或建议捕获并处理
设计目的 标识系统致命错误,通知JVM终止 标识程序可预见的错误,供程序员处理
常见示例 OutOfMemoryError、StackOverflowError、NoClassDefFoundError NullPointerException、IOException、SQLException

3. 什么是受检异常和非受检异常?它们的区别是什么?

标准答案

  • 受检异常(Checked Exception):编译器强制要求必须处理的异常,否则编译失败。继承自Exception但不包括RuntimeException及其子类。
  • 非受检异常(Unchecked Exception):编译器不强制要求处理的异常。包括RuntimeException及其子类和Error及其子类。

核心区别

维度 受检异常 非受检异常
编译检查 强制检查,必须声明throws或try-catch 不检查,无需显式处理
发生时机 通常由外部环境引起(如文件不存在、网络失败) 通常由程序逻辑错误引起(如空指针、数组越界)
设计目的 强制程序员处理可能的外部错误 暴露程序bug,让开发者修复
继承关系 Exception的直接子类(除RuntimeException) RuntimeException和Error的子类

二、执行机制类(高频难点)

核心考点

  1. try-catch-finally的完整执行流程
  2. finally块的执行时机与特殊情况
  3. return语句在try-catch-finally中的执行顺序

高频面试题

1. 详细说明try-catch-finally的执行流程

标准答案
分三种情况:

  1. 无异常:执行完try块所有代码 → 跳过所有catch块 → 执行finally块 → 执行try块之后的代码
  2. 有异常且被捕获:执行try块到异常发生处 → 匹配第一个类型相符的catch块并执行 → 执行finally块 → 执行try块之后的代码
  3. 有异常未被捕获:执行try块到异常发生处 → 跳过所有catch块 → 执行finally块 → 异常向上层调用栈抛出

2. finally块在什么情况下不会执行?

标准答案
唯一情况:在try块或catch块中调用了System.exit(int status)方法终止JVM进程。

其他情况(包括try/catch中有return、throw语句,线程被中断等),finally块都会执行

3. 如果try、catch、finally中都有return语句,最终会返回哪个值?

标准答案
finally块中的return语句会覆盖try或catch中的return值

执行顺序

  1. 执行try块到return语句,计算返回值并保存
  2. 执行finally块
  3. 如果finally中有return语句,返回finally中的值
  4. 如果finally中没有return语句,返回之前保存的try或catch中的值

示例

public static int test() {
   
    try {
   
        return 1;
    } finally {
   
        return 2; // 最终返回2
    }
}

注意:这是非常不好的编程实践,绝对不要在finally块中使用return或throw语句

三、资源管理类(现代Java重点)

核心考点

  1. try-with-resources的语法与优势
  2. AutoCloseable接口的作用
  3. 异常抑制(Suppressed Exceptions)机制

高频面试题

1. 为什么要使用try-with-resources?它比传统的try-catch-finally好在哪里?

标准答案
传统try-catch-finally释放资源存在以下问题:

  • 代码冗长,多层嵌套,可读性差
  • 容易忘记关闭资源,导致资源泄漏
  • 资源关闭时抛出的异常会覆盖原始异常,丢失关键错误信息
  • 多个资源关闭时代码极其复杂

try-with-resources的优势:

  • 自动关闭资源:try块结束时自动调用close()方法,无需手动编写
  • 代码简洁:消除了大量模板代码
  • 异常抑制机制:保留原始异常,关闭资源时的异常作为抑制异常附加
  • 支持多个资源:可以同时声明多个资源,自动按声明相反顺序关闭

2. try-with-resources的工作原理是什么?

标准答案

  1. 只有实现了java.lang.AutoCloseable接口的类才能在try-with-resources中使用
  2. 编译器会自动生成finally块,在其中调用资源的close()方法
  3. 资源关闭的顺序与声明顺序相反(后声明的先关闭)
  4. 当try块抛出异常,且close()方法也抛出异常时,原始异常会被保留,close()抛出的异常会被添加为抑制异常
  5. 可以通过Throwable.getSuppressed()方法获取所有抑制异常

3. AutoCloseable和Closeable接口有什么区别?

标准答案

接口 引入版本 close()方法声明 适用范围
AutoCloseable Java 7 void close() throws Exception 所有需要自动关闭的资源
Closeable Java 1.0 void close() throws IOException 专门用于IO流等资源

关系Closeable继承自AutoCloseable,所有实现了Closeable的类都可以在try-with-resources中使用。

四、高级特性类

核心考点

  1. 多异常捕获语法与限制
  2. 异常链的作用与实现
  3. 自定义异常的设计原则

高频面试题

1. Java 7中引入的多异常捕获有什么特点和限制?

标准答案
语法

try {
   
    // 代码
} catch (IOException | SQLException e) {
   
    // 统一处理
}

特点

  • 可以在一个catch块中处理多种类型的异常
  • 异常变量e是隐式final的,不能在catch块中重新赋值

限制

  • 多个异常类型之间不能有继承关系,否则编译错误
  • 只能处理非受检异常和受检异常,不能处理Error

2. 什么是异常链?为什么要使用异常链?

标准答案
异常链:将原始异常包装成新的异常抛出,保留完整的异常堆栈信息,形成异常的调用链。

实现方式

try {
   
    // 数据库操作
} catch (SQLException e) {
   
    throw new BusinessException("用户查询失败", e); // 传入原始异常作为cause
}

获取原始异常e.getCause()

使用原因

  1. 保留异常的完整上下文信息,便于问题排查
  2. 将底层异常转换为业务异常,向上层提供更友好的错误信息
  3. 解耦底层实现与上层业务逻辑

3. 如何设计自定义异常?应该继承Exception还是RuntimeException?

标准答案
自定义异常的设计步骤

  1. 继承自Exception(受检异常)或RuntimeException(非受检异常)
  2. 提供四个构造方法:
    • 无参构造方法
    • 带错误消息的构造方法
    • 带错误消息和原因的构造方法
    • 带原因的构造方法

继承选择原则

  • 继承RuntimeException(推荐)
    • 表示程序逻辑错误或业务异常
    • 不需要强制上层处理
    • 符合现代Java开发趋势
  • 继承Exception
    • 表示必须处理的外部异常
    • 强制上层调用者处理
    • 仅在明确需要强制处理时使用

五、最佳实践类(考察开发经验)

核心考点

  1. 异常处理的基本原则
  2. 常见的异常处理反模式
  3. 异常处理的性能考虑

高频面试题

1. 列举至少5条Java异常处理的最佳实践

标准答案

  1. 捕获具体异常:永远不要捕获ThrowableError或通用的Exception,应该捕获最具体的异常类型
  2. 不要忽略异常:空的catch块会隐藏错误,至少要记录日志
  3. 不要在finally中使用return或throw:会覆盖try/catch中的返回值或异常
  4. 优先使用try-with-resources:自动管理资源,避免资源泄漏
  5. 使用异常链:保留原始异常信息,便于问题排查
  6. 异常消息要具体:包含上下文信息(如文件名、用户ID等),不要只写"发生错误"
  7. 不要用异常控制流程:异常处理有性能开销,应该用于真正的异常情况
  8. 抛出合适的异常类型:不要抛出通用的Exception,应该抛出具体的业务异常

2. 列举常见的异常处理反模式

标准答案

  1. 捕获Throwable:会捕获Error,导致系统级错误被隐藏
  2. 空catch块catch (Exception e) {},完全忽略异常
  3. 打印异常后继续抛出e.printStackTrace(); throw e;,导致日志重复
  4. 在循环中使用try-catch:严重影响性能
  5. 过度使用受检异常:导致代码中充斥着throws声明和try-catch
  6. 在异常消息中包含敏感信息:如密码、身份证号等
  7. 只捕获异常不记录堆栈信息:只记录异常消息,不记录堆栈,无法定位问题

3. 异常处理对性能有什么影响?如何优化?

标准答案
性能影响

  • 创建异常对象时会生成堆栈跟踪,这是一个比较耗时的操作
  • 异常抛出和捕获的过程会中断正常的执行流程
  • 频繁抛出和捕获异常会显著降低程序性能

优化方法

  1. 不要用异常控制正常流程:异常只用于处理真正的错误情况
  2. 避免在循环中使用try-catch:将try-catch移到循环外面
  3. 不要频繁创建异常对象:可以预创建异常对象(但会丢失堆栈信息)
  4. 只在必要时捕获异常:能处理的才捕获,不能处理的向上抛出
  5. 避免捕获过于宽泛的异常:只捕获需要处理的具体异常类型

六、综合场景题(考察综合能力)

1. 下面代码的输出结果是什么?

public class Test {
   
    public static void main(String[] args) {
   
        System.out.println(test());
    }

    public static int test() {
   
        int i = 1;
        try {
   
            i++;
            return i;
        } catch (Exception e) {
   
            i++;
            return i;
        } finally {
   
            i++;
        }
    }
}

标准答案:输出2

解释

  1. try块中i自增为2,执行return i时,会先保存返回值2
  2. 执行finally块,i自增为3
  3. finally中没有return语句,所以返回之前保存的2

2. 下面代码中,close()方法抛出的异常会怎么样?

try (MyResource resource = new MyResource()) {
   
    throw new RuntimeException("原始异常");
}

class MyResource implements AutoCloseable {
   
    @Override
    public void close() throws Exception {
   
        throw new Exception("关闭异常");
    }
}

标准答案

  • 最终会抛出RuntimeException("原始异常")
  • Exception("关闭异常")会被添加为抑制异常
  • 可以通过e.getSuppressed()方法获取关闭异常

Java异常体系 一页纸面试速记版

一、核心架构(必背)

Object → Throwable(根类)
    ├─ Error(系统级错误,不可恢复,非受检)
    └─ Exception(程序级异常,可处理)
        ├─ RuntimeException(运行时异常,非受检)
        └─ 其他Exception子类(受检异常)

二、核心分类对比(必问)

1. Error vs Exception

维度 Error Exception
级别 JVM/系统 应用程序
可恢复 几乎不能 通常可以
处理 不建议捕获 建议/强制处理
示例 OOM、栈溢出 空指针、IO异常

2. 受检 vs 非受检异常

维度 受检异常 非受检异常
编译检查 强制 不强制
继承 Exception(不含RuntimeException) RuntimeException+Error
原因 外部环境问题 程序逻辑错误
处理 必须throws/try-catch 无需显式处理

三、异常处理机制(高频难点)

1. try-catch-finally执行流程

  • 无异常:try → finally → 后续代码
  • 有异常且捕获:try(中断) → catch → finally → 后续代码
  • 有异常未捕获:try(中断) → finally → 向上抛出

2. finally关键特性

  • 唯一不执行情况System.exit(0)终止JVM
  • return执行顺序:先保存try/catch返回值 → 执行finally → 返回保存值
  • 禁忌:绝对不要在finally中使用return/throw,会覆盖原有结果

四、try-with-resources(现代Java重点)

1. 核心优势

  • 自动关闭资源,避免泄漏
  • 代码简洁,消除模板
  • 异常抑制:保留原始异常,关闭异常作为抑制异常

2. 工作原理

  • 实现AutoCloseable接口(Java 7+)
  • 编译器自动生成finally块调用close()
  • 资源关闭顺序:与声明顺序相反
  • 抑制异常获取:e.getSuppressed()

五、高级特性速记

  • 多异常捕获catch (A|B|C e),异常间无继承关系,e隐式final
  • 异常链new Exception("msg", cause),保留完整堆栈,e.getCause()获取原始异常
  • 自定义异常:优先继承RuntimeException,提供4个标准构造方法

六、最佳实践与反模式

✅ 最佳实践(Top 6)

  1. 捕获具体异常,不捕获Throwable/Exception
  2. 不要忽略异常,至少记录日志
  3. 优先使用try-with-resources管理资源
  4. 使用异常链保留原始信息
  5. 异常消息包含上下文,不要只写"发生错误"
  6. 不要用异常控制正常流程

❌ 反模式(Top 5)

  1. 空catch块:catch (Exception e) {}
  2. 捕获Throwable/Error
  3. finally中使用return/throw
  4. 打印异常后重新抛出(日志重复)
  5. 过度使用受检异常

七、经典面试题速答

  1. 代码题1:try中return i=2,finally中i++ → 返回2(保存返回值后执行finally)
  2. 代码题2:try块抛异常,close()也抛异常 → 抛出原始异常,关闭异常被抑制
相关文章
|
15小时前
|
消息中间件 Java 数据处理
Java在实时流数据处理平台(基于KafkaStreams和Flink)中的运用
与批处理不同,流处理是对无界数据持续不断地计算,要求低延迟(秒级或毫秒级)和事件时间处理(处理乱序到达的数据)。Java凭借丰富的流处理框架(ApacheFlink、KafkaStreams、SparkStreaming),成为实时数据处理领域的主导语言。
24 0
|
15小时前
|
数据采集 Web App开发 缓存
无需手动清 Cookie!Python 爬虫会话维持技巧
无需手动清 Cookie!Python 爬虫会话维持技巧
|
10小时前
|
存储 人工智能
算力暂停,记忆不休——意图共鸣科技《AI记忆链商业化白皮书2.0》的“优雅降级”方案
本文提出“优雅降级”理念:AI服务可暂停算力,但用户对话记忆必须永久留存、随时查阅与导出。反对订阅制下“额度用尽即清空上下文”的粗暴断崖,主张存储与算力解耦——如手机停机保号,号码(记忆)永属用户,通话(算力)按需充值。
24 0
|
11小时前
|
SQL 存储 缓存
【Java基础】核心关键字:final、static、volatile、synchronized、transient(附《思维导图》+《面试高频考点清单》)
本文系统解析Java五大核心关键字:final(不可变性)、static(类级共享)、volatile(轻量级可见性)、synchronized(重量级同步)与transient(序列化控制)。涵盖语义、使用场景、底层原理(内存屏障、Monitor、类加载机制等)、常见误区及高频面试要点。
【Java基础】核心关键字:final、static、volatile、synchronized、transient(附《思维导图》+《面试高频考点清单》)
|
11小时前
|
存储 安全 Java
【Java基础】String不可变性、String vs StringBuffer vs StringBuilder、常量池、intern()方法(附《思维导图》+《面试考点背诵版》)
本文系统解析Java字符串核心机制:String不可变性(`final char[]`实现)、String/StringBuffer/StringBuilder三者对比(可变性/线程安全/性能)、字符串常量池(JDK7+移至堆)及`intern()`方法(JDK7+直接存堆引用)。
|
10小时前
|
存储 安全 Java
【Java基础】泛型:泛型擦除、通配符、上下界限定(附《思维导图》+《面试高频考点清单》)
本文系统梳理了Java泛型的核心知识体系,主要内容包括: 泛型概述:介绍了泛型的定义、本质和三大优势(类型安全、代码复用、可读性),以及泛型类、接口和方法的三种使用形式。 泛型擦除:深入解析了Java泛型实现的核心机制,包括擦除规则(无界类型擦除为Object,有界类型擦除为第一个边界类型)、擦除带来的问题(如无法使用instanceof、创建泛型数组等)及其解决方案。 泛型通配符:详细讲解了三种通配符类型(无界通配符、上界通配符和下界通配符)的语法、语义和使用场景。
|
2月前
|
移动开发 前端开发 JavaScript
【贪吃蛇小游戏】 HTML (Canvas)+ JavaScript
这是一个基于 HTML5(Canvas)+JavaScript 开发的贪吃蛇小游戏,通过800×800画布实现蛇体绘制、食物生成、碰撞检测及方向控制,支持键盘操作与重新开始功能,代码结构清晰,适合初学者学习Web游戏开发。
872 11
|
8天前
|
存储 安全 关系型数据库
【MySQL】MySQL日志体系:redo log/undo log/binlog 三者区别、两阶段提交、如何保证数据一致性
MySQL三大核心日志:undo log(保障原子性,支持回滚与MVCC)、redo log(保障持久性,崩溃恢复,WAL机制)、binlog(保障可复制性,主从同步与数据恢复)。三者分属不同层级,协同实现ACID与高可用。
|
8天前
|
SQL 存储 运维
【MySQL】高可用:主从复制原理、主从延迟解决方案、半同步复制、MGR
本文系统梳理MySQL高可用知识体系,涵盖主从复制原理、GTID、半同步(AFTER_SYNC)、MGR集群等核心机制,深入解析延迟成因与优化策略,并对比选型方案,助力构建稳定、一致、自动恢复的高可用数据库架构。
|
8天前
|
存储 关系型数据库 MySQL
【MySQL】 索引核心分类:聚簇索引/非聚簇索引、主键索引/二级索引、单列索引/联合索引、覆盖索引/前缀索引
本文系统梳理MySQL索引的四大分类维度:物理存储(聚簇/非聚簇)、功能层级(主键/二级)、字段数量(单列/联合)、优化用途(覆盖/前缀),厘清交叉关系与适用场景,助你科学选型、规避误区、提升查询性能。