用自己起的 PostgreSQL 16 与 MySQL 实例,在 JDBC 里对四个隔离级别逐个构造脏读、不可重复读、幻读、丢失更新、写偏斜:PostgreSQL 的 READ_UNCOMMITTED 等同 READ_COMMITTED、REPEATABLE_READ 拒绝丢失更新但仍有写偏斜、SERIALIZABLE 拒绝写偏斜;MySQL 的 REPEATABLE_READ 下丢失更新与写偏斜都发生,SERIALIZABLE 靠加锁导致阻塞与死锁。
用自己起的 PostgreSQL 16 与 MySQL 实例验证 JDBC 保存点:PostgreSQL 语句出错后事务中止,commit 静默变回滚,保存点可以恢复;MySQL 语句失败不会中止事务;保存点的嵌套、失效、命名规则与错误码;pgjdbc 的 autosave=always 让 20000 行逐行插入从 564.9 ms 变成 1111.3 ms。
用自己起的 PostgreSQL 16 与 MySQL 读 200 万行验证 JDBC fetchSize:PostgreSQL 必须 autocommit=false 才用游标,否则 -Xmx128m 下 OutOfMemoryError,fetchSize=10 慢到 4899 ms;MySQL 默认与只设 fetchSize 都 OOM,要用 Integer.MIN_VALUE 流式(577 ms)或 useCursorFetch(1561 ms)。
在 PostgreSQL 与 MySQL 上验证 JDBC 取生成主键:PostgreSQL 的 RETURN_GENERATED_KEYS 返回整行(RETURNING *),指定列名才只返回 id,不支持列序号;MySQL 永远只有 GENERATED_KEY 一列,没请求就报错,rewriteBatchedStatements 让批的更新计数变成 -2;并发下 select max(id) 有 2919 / 3200 次与自己的键不一致。
在 JDK 21 上用 PostgreSQL 真实验证 RowSet:CachedRowSet 断开连接后离线增删改并 acceptChanges 写回(要 autocommit=false,否则改动已提交却抛异常);写回前先 SELECT 比较原值做乐观冲突检测;WebRowSet XML、序列化、FilteredRowSet、JoinRowSet、分页、JdbcRowSet。
用自己起的 PostgreSQL 与 MySQL 跑真实的 XA 两阶段提交:start / end / prepare / commit 的流程、prepare 之后数据仍不可见、PG 延迟约束在 PREPARE 时失败触发回滚、协调者在 prepare 之后崩溃留下握着锁的 in-doubt 分支并通过 recover() 恢复、两阶段每次提交约 0.61 ms(单库本地 0.19 ms)。
用两个 JVM 真实运行 Java RMI:stub 是动态代理、监听两个端口、一次本机调用约 0.072 ms;参数按值而 Remote 对象按引用;异常原样穿过;JEP 290 过滤器拒绝 ArrayList;DGC 租约到期后 unreferenced() 在 3.01 秒后被调用、clean 调用则在 0.01 秒内。
在 JDK 21 上真实运行 JNDI:没有提供者时的 NoInitialContextException、自己写的 InitialContextFactory、JDK 自带的 RMI Registry 提供者(只能 bind Remote / Reference / Referenceable)、JDK 的 LDAP 提供者对接 UnboundID 内存 LDAP 服务器的查询与修改及错误映射。
用 JUnit 5.11.3 真实打印扩展回调的完整顺序:before 类按注册顺序、after 类反过来;异常处理器吞掉异常后后面的处理器不再被调用;TestWatcher 的三种回调;Store 在根 / 类 / 方法三级的 CloseableResource 关闭时机;@RegisterExtension 与 @ExtendWith 的注册顺序。
用 JUnit 5.11.3 真实运行参数化测试:@ValueSource、@CsvSource(引号、nullValues、空串)、@EnumSource、@MethodSource、@NullSource + @EmptySource 的调用次数与显示名;隐式 / 显式转换与聚合;参数数量不匹配与空来源的错误;每次调用都构造新实例并运行 BeforeEach / AfterEach,失败只影响自己。
用 JUnit 5.11.3 真实运行 @TestFactory:BeforeEach / AfterEach 只对工厂方法执行一次;失败的动态测试单独标记;DynamicContainer 嵌套;惰性 Stream 边产生边执行,onClose 在 AfterEach 之前;错误返回类型、工厂抛异常、空流;动态测试共享同一个实例。
用 jqwik 1.9.1 真实运行属性测试:1000 次随机调用加边界值混入;溢出缺陷的平均值被找到并收缩成 (-1, -2147483648);第二次运行从 .jqwik-database 重放失败样本(tries = 1);Integer.MIN_VALUE 的 abs 缺陷;列表缺陷 11 个元素收缩成 [0, 0, 0, 0, 0, 0];Assume、穷举与统计。