Java 平台历代特性
Created|Updated|Java
|Word Count:16|Reading Time:1mins|Post Views:
Java 9 模块化,JDK 只依赖于 PATH 不依赖于 CLASSPATH。
Author: magicliang
Link: https://magicliang.github.io/2020/03/01/Java-%E5%B9%B3%E5%8F%B0%E5%8E%86%E4%BB%A3%E7%89%B9%E6%80%A7/
Copyright Notice: All articles on this blog are licensed under CC BY-NC-SA 4.0 unless otherwise stated.
Related Articles

2026-10-04
企业应用架构01:三种领域逻辑组织
租赁费用只有“天数乘单价”时,一个过程就能清楚表达。价格在租期中途变化以后,报价与延期两个入口都要理解有效期;如果报价改成分段收费,延期仍按起租日单价算全期,同一份租期就会出现两个答案。 本篇用 Transaction Script、Domain Model、Table Module 分别实现相同计费输入,实际运行旧规则、新规则和漏改入口的反例。固定租赁基线 保持不变;这里的整日分段价格是隔离的新教学规则,没有偷偷替换上游的小时计费。 先把价格变化说清楚 输入是整日的 LocalDate 半开区间。十月一日至五日每日一百元,五日至十日每日一百五十元;结束日不计费。这里没有把日期转换为时区瞬间,也不涉及夏令时、按小时补差或跨币种换汇。 旧规则以起租日费率计算全期:三日至六日共三天,收费三百元。新规则按租期落入的有效段计算,三日和四日各一百元,五日一百五十元,共三百五十元。这是业务结果的改变,不能称为仅调整结构的等价重构。 延期输入由旧租期与新结束日组成,返回重新计算的全期总额。三日至五日延期到七日,新总额为五百元;它不是新增应收三百元,也没有执行预留或实际收费。缩短结束日不属于此...
2026-09-30
深入 OpenTelemetry 18:Logs SDK 从 emit 到批量导出
调用 emit 后,日志已经写出去了吗? logRecordBuilder().emit() 只把一条记录交给本地 processor;它既不保证已被导出,也不负责把 Logback 的普通日志自动接进来。为了分开观察“产生记录”和“处理队列”,实验设置了极长的批处理调度间隔,发出一条日志,再显式 flush。固定的事件时间是 epoch 90 秒,观察时间由测试时钟提供,为 100 秒。 阶段 本篇对象 可以判定的事实 不代表 API 调用 Logger / LogRecordBuilder body、severity、事件时间被设置 已导出 processor 队列、工作线程 已排队,可能因队列满被丢弃 已接收 exporter InMemoryLogRecordExporter 内存列表里可读到 LogRecordData Collector 或后端已入库 从 SDK 源码看对象何时定型 以下为 opentelemetry-java v1.31.0 固定 SHA c25c0a0ee0da01ab2f74ba83052d1c249ed57020 的...

2023-01-13
Java 原生 API
Java 原生 API 模式总览 本文覆盖以下可迁移模式: # 模式名称 一句话口诀 覆盖用例 1 字符串常量池复用 相同字面量共享同一对象 String.intern()、编译期常量折叠 2 契约式设计 重写 equals 必须重写 hashCode HashMap 键、Set 元素 3 线程状态机协作 interrupt 是协作式终止标志 Thread.interrupt()、Future.cancel() 4 双亲委派加载 父类加载器优先防止类冲突 ClassLoader、Tomcat 类加载 5 异常链传递 包装异常保留原始栈踪迹 ServletException、RuntimeException 6 不可变视图 原始集合的只读包装 Collections.unmodifiableList() 7 空值防御性编程 明确表达可能为空的返回值 Optional、Objects.requireNonNull() 8 异步组合编程 链式调用编排多阶段任务 CompletableFuture.thenCompose() 9 分段锁到 C...

2026-10-04
设计模式 25:用例入口如何暴露失败
下单先报价、再预留库存、最后模拟扣款。旧调用者只拿到一个布尔值:缺货是 false,扣款被拒也同样是 false。更危险的是扣款失败前库存已经减了 1。给这一串调用加一个简单入口,能否让错误变得可辨识?会不会误让读者以为它保证了事务回滚? 收敛入口,不隐瞒局部副作用 labs/25 的 Before.checkout 直接依次调用 Quote.price、Stock.reserve、Payment.charge。After 把协作收在 checkout(base) 一处,返回 Result(Status, cents):成功、NO_STOCK、PAYMENT_FAILED 是三种可区分状态。报价 1000 分得 900 分的旧成功合同不变;0 分报价在预留之前就抛错,不会扣库存。扣款失败时测试明确断言 PAYMENT_FAILED 且余额从 1 变为 0:入口没有自动恢复库存。 123if (!stock.reserve()) return new Result(NO_STOCK, cents);if (!payment.charge(cents)) return new Res...
2026-05-21
非确定性有限自动机:一次保留多个可能世界
DFA 每次只处在一个状态里。读取一个字符,规则表给出唯一的下一个状态。这个约束让 DFA 很容易实现,也让它的执行轨迹很干净:current_state + character -> next_state。 非确定性有限自动机(Nondeterministic Finite Automaton,NFA)放宽了这个约束。同一个状态读取同一个字符时,可以走到多个下一状态;机器还可以在不消耗字符的情况下移动到别的状态。NFA 的实现方式并不神秘:把“当前状态”从单个值改成一个集合,一次保留所有可能路径。 这篇文章用 Python 写一个 NFA,识别两个字符串:ab 和 ba。这个示例足够小,但能完整覆盖 NFA 的两个核心机制:分支和空转移。 非确定性不是随机 “非确定性”容易被误解成机器随机选择一条路。NFA 的更好理解是:同一时刻保留多条候选路径,只要其中一条路径最后进入接受状态,整个输入就被接受。 问题 DFA NFA 当前状态 一个状态 一组状态 同一输入的下一状态 唯一 可以有多个 是否允许不读字符就移动 不允许 允许 接受条件 当前状态...
2026-09-30
深入 OpenTelemetry 23:Instrumenter 怎样开始、结束并避免重复 Span
一次 HTTP 请求会被几个方法观察? HttpURLConnection 的 connect()、getInputStream() 与 getResponseCode() 可在同一次请求中先后调用。如果每个 Advice 都无条件新建、结束 Span,就可能留下重复记录或未结束的 Span。另一个反例是 getInputStream() 因 500 抛出 IOException:是否自动记录异常事件,不能仅看业务侧是否捕获异常。本篇把“是否启动”“结束时看到什么”与“为什么不重复”拆开,分别用源码和三个独立 JVM 检验。 层次 开始路径 结束/去重路径 Instrumenter shouldStart → start,提取名称和起点属性 end 更新终点属性、status 和结束时间 HTTP Advice 读取当前 Context、同连接的状态 CallDepth、VirtualField 保存的状态和 finished 标志 输出 Scope 临时成为 current 客户端 200/500/重复方法各得到一个 CLIENT Span 静态源码...
Announcement
人生只是,守株待兔





