真实验证 TCP 没有消息边界:50 字节 × 2000 次写入被合并成 855 次 read(平均 116 字节),20000 字节的消息被拆成不整的读取 34 次;Netty 不加解码器时 2000 条消息只触发 50 次 channelRead,加 LengthFieldBasedFrameDecoder / LineBasedFrameDecoder / FixedLengthFrameDecoder 后恰好 2000 次。
真实验证 Java 序列化:71 字节的流里只有 7 字节数据,其余是魔数与类描述;transient/static 不进流、字段初始化器不运行、不可序列化父类的无参构造器被调用;共享引用被保留;没有显式 serialVersionUID 时加一个字段就让旧数据读取失败,显式声明后读取成功但新字段是 null。
javap 与运行时验证 lambda 的实现:lambda 没有类文件、函数体变成私有静态合成方法加一条 invokedynamic(引导方法 LambdaMetafactory.metafactory);不捕获变量的 lambda 是同一个对象、捕获变量的每次求值新建;运行时类是隐藏类 Main$$Lambda/0x…;第一个 lambda 位置首次求值约 3 ms,多加载 90 个类。
用带日志的流水线验证 Stream 的执行方式:没有终结操作什么都不发生;每个元素依次走完整条流水线;sorted() 是屏障;limit/findFirst/anyMatch 让无限流或百万元素流只处理很少的元素;limit 的位置改变上游产生的元素数;大小已知时 count() 会跳过 peek 与 map(JDK 17、21、27 一致)。
真实验证 StampedLock:乐观读只拿版本号、写锁期间与写锁之后旧 stamp 都失效;验证之前确实会读到 x+y≠100 的数据(2417 次),validate 通过后 0 次;8 个读线程下乐观读 2756 百万次/秒,读锁只有 1.9~2.4;不可重入。
JDK 21 虚拟线程实测:10000 个各 sleep 1 秒的任务,虚拟线程 1073 ms 完成、RSS 85 MB;每任务一个平台线程在第 4059 个任务时因 unable to create native thread 失败;200 线程池要 50358 ms;纯计算任务虚拟线程没有优势;2000 个虚拟线程只用了 10 个载体线程。
载体线程限制为 2 个时,10 个虚拟线程各阻塞 500 ms:JDK 21 上 synchronized 里阻塞要 2548 ms(被固定、分 5 批),ReentrantLock 与无锁都只要约 520 ms;JDK 27 上三种都约 519 ms;用 -Djdk.tracePinnedThreads=full 看固定发生的栈。
真实验证 CompletableFuture 的超时与取消:orTimeout 超时后任务从 4 步继续跑到 15 步,cancel(true) 不中断任务,依赖阶段抛 CompletionException(cause 为 CancellationException);executor.submit 的 Future.cancel(true) 才能中断任务,并可与 CompletableFuture 组合;completeOnTimeout 与 get(timeout) 的语义差别。
真实验证 MethodHandle:invokeExact 的类型必须完全一致、invoke 自动适配、bindTo 绑定接收者、访问检查在查找时发生;static final 的 MethodHandle 与直接调用一样快(0.31 ns),放在非 final 字段里慢到 2.34 ns,Method.invoke 是 2.76 ns。
真实验证 JDK 动态代理:代理类是 public final 的 jdk.proxy1.$ProxyN,toString/hashCode/equals 也进 handler;handler 里直接 m.invoke 会让目标的 IOException 变成 UndeclaredThrowableException;default 方法要 invokeDefault;代理调用约 3.28 ns(直接 0.35 ns);并把生成的代理类导出来看字节码。
真实验证注解的运行时形态:注解实例是 $ProxyN 代理对象、同一注解读两次是同一对象;@Inherited 只沿父类继承,接口和方法注解不继承;重复注解被包进容器后 getAnnotation 读到 null;CLASS/SOURCE 读不到;TYPE_USE 注解要走 getAnnotatedType;第一次 getAnnotation 约 12 ms;并用 javap 看注解在类文件里的位置。
真实验证 ServiceLoader:META-INF/services 里的顺序就是迭代顺序、load 与 stream 不实例化、迭代时才构造并缓存、reload 清缓存;配置出错在迭代到该项时抛 ServiceConfigurationError;模块方式用 provides/uses,module-path 里没有 impl 时找不到实现也不报错。