Kotlin 20:Java 调用 Kotlin 时默认参数去哪了
Kotlin 可以写 describe("task-1"),让第二个参数使用默认值;Java 调用同一个声明,却不一定能少传参数。反方向的 19已经补过 class、interface、implements、static、泛型擦除和 checked exception 的最小 Java 前置;这次将边界倒过来:用真实 src/test/java 消费者编译调用 Kotlin 方法,比较 @JvmOverloads、@JvmStatic、@Throws 到底改变了 Java 所见的哪一部分契约。 冻结组合仍是 Kotlin Gradle Plugin/stdlib 2.2.21、JDK 21、Gradle 8.14;本篇只生成单个同步 facade,不发布公共库。官方 Java 调 Kotlin 文档提供注解和属性映射规则;下文的具体生成方法、Java 编译诊断和异常结果来自本次 javap、javac 和 JUnit,不能拿滚动文档代替当前产物。 Java 消费者只认识类文件里实际存在的方法、字段访问器和 throws 签名。Kotlin 的 object、属...
Kotlin 19:Java 返回值怎样越过空安全边界
Kotlin 的非空变量在本地代码里不允许直接赋 null,但 Java 方法返回一个没有空注解的 String,实际却可以返回 null。如果 Kotlin 直接对这个返回值取 .length,编译器会放行,运行时仍可能抛 NullPointerException。已有的 05 空安全实验处理的是 Kotlin 自己声明的可空字段;本篇把同一任务系统接上一小段 Java 输入适配器,记录 Java 返回值越界后的实际行为,以及在哪里将它变回明确的 Kotlin 类型。 本章沿用 Kotlin Gradle Plugin/stdlib 2.2.21、Gradle Wrapper 8.14 和 JDK 21;未新增三方依赖。规则出处是 Kotlin 官方 Java 空安全与 platform type、SAM 转换。具体值、异常和调用时序以本仓库 19 的 Kotlin/Java 混合编译及测试日志为准。Java 类的空注解、线程调度或真实网络在本篇都不存在。 Java 前置:类、接口、擦除和 checked exception Java 的 class 承载字段、构造器、实例方...
Kotlin 18:任务注解为什么不会自动校验
给任务草稿标上 @TaskCategory("draft"),运行时可以读到这份元数据;再标一个仅供源码阶段使用的提示,运行时却读不到。更容易误会的是:类上写着“需要校验”,是否意味着创建一个正文全为空白的草稿会被自动拦住?本篇沿用 17 的 TaskDraft,比较注解目标、保留期和实际调用 Class.getAnnotation 的结果,明确哪些逻辑仍需要普通函数执行。 实验组合是 Kotlin/JVM 2.2.21、JDK 21、Gradle Wrapper 8.14。出处定位在 Kotlin 注解文档与 反射文档;本章只用 JDK 的 Class.getAnnotation 和 Kotlin 标准库的 ::class.java,没有添加 kotlin-reflect 依赖,也没有编译器插件或扫描容器。实验中的类型、编译器诊断和字节码都可在 18 证据目录核对。 注解贴在哪里,留下多久 两个注解都只能标在类上,但保留期不同: 1234567891011@Target(AnnotationTarget.CLASS)@Retention(Annotatio...
Kotlin 17:DSL 嵌套作用域怎样限制误写
任务草稿有 ID、正文和若干标签。普通函数写成 makeTaskDraft(id, text, labels),参数一目了然;改成 taskDraft { ... label { ... } } 后,在最内层 label 块里写 text = "overwritten" 到底会修改标签,还是悄悄修改外层任务正文?此前 14 的作用域函数已经说明接收者与返回值可能不是同一回事,这里让两个接收者同时进入作用域,再用编译反例确认 @DslMarker 的保护范围。 本文实验仍在 Kotlin/JVM 2.2.21、JDK 21、Gradle 8.14 上运行。语法依据是 官方类型安全构造器的作用域控制 和 带接收者函数字面量;具体允许或拒绝哪条语句,以冻结编译器的原始输出为准。 普通构造函数已经解决什么 本章的产物只是值 TaskDraft(id: TaskId, text: String, labels: List<String>)。makeTaskDraft 在构造前检查正文非空、每个标签 trim 后非空,...
Kotlin 16:值类和 reified 保留了哪些类型信息
submitValidated(store, "alpha", "task-1") 两个参数都是字符串:如果调用方把任务 ID 和文本调换,编译器无从发现。给 ID 做一层值类后,可以要求调用处明确提供 TaskId。另一个疑问来自 15 的类型擦除:内联函数写了 reified,能否就此识别 List<String> 中的实际元素?本章用同一任务系统的可控调用、预期编译失败及当前构建的 javap 结果回答这两个问题,不根据一次生成物宣称未来所有 Kotlin 编译器都产生同样的 ABI。 实验版本仍为 Kotlin/JVM 2.2.21、JDK 21、Gradle 8.14;编译器上游 tag v2.2.21 对应 SHA 2146684dcba708e5a304758b41a9e4ec9c7eff71,冻结信息见仓库 writing-plans/kotlin/VERSIONS.md。官方 inline 文档与 值类表示文档解释语义边界;本篇只读了生成字节码,尚未跟踪编译器 lowering 内部源码,后续 36 再补符号级...
Python E08:如何审计依赖与不可信输入
一个 tasklab wheel 在干净环境里安装成功,依然无法回答两个问题:下载的到底是不是当时检验的制品?网络请求中自称“任务类型”的字符串会不会被当成可执行模块?此前 26 的安装验收解决的是构建与运行可重放;本篇用现成 wheel 和 JSON 行入口审计供应与输入边界,不引入任意代码插件。 主线 wheel tasklab-0.1.0-py3-none-any.whl 的当前路径、SHA-256、成员清单和源码文件哈希记录在 examples/python-language/evidence/completion/acceptance/wheel.json;元数据要求 Python >=3.12、没有 Requires-Dist。E05 的 Starlette/HTTPX/Uvicorn 和 E06 的 NumPy 均是可移除实验环境中的额外依赖,不能从主线 pyproject.toml 推出这些工具已被主线用户安装,也不能把 pip freeze 当作经过哈希校验的跨平台锁。 先验证制品,后讨论信任 experiments/E08_audit.py 在导入位置...
Kotlin 15:泛型边界如何限定任务状态的读写
已经有一批 TaskState.Failed,想让只关心 TaskState 的代码读取它们;另有一个接收所有 TaskState 的写入口,想把它交给只会提交失败状态的调用方。前者与后者的赋值方向正好相反。若把可读、可写混在同一个泛型接口里,调用方既难获得类型上的自由,也可能把不兼容的状态放进列表。本篇在 14 的任务状态格式化旁边建立两个小端口,并用独立编译失败样本检查类型允许的动作;外部来源的嵌套列表仍需逐值校验。 本章继续使用 Kotlin/JVM 2.2.21、JDK 21、Gradle 8.14。术语与约束取自 官方泛型文档的型变与投影,具体编译诊断和运行结果取自冻结版本的 15 实验。没有 Java 适配、持久化或受管任务工作者。 只读状态源能向哪个方向赋值 把“读取一个状态”与“接收一个待写状态”拆开,接口只暴露必要的一种操作: 1234567interface TaskStateSource<out State : TaskState> { fun current(): State}interface TaskStateS...
Python E07:子解释器提供了怎样的隔离
一个进程里运行两个解释器,能否让 tasklab 的两个任务彼此不共享对象,同时避免起两个进程?在冻结的 CPython 3.12.3 上,公开标准库还没有可依赖的高级解释器池入口;实验只能明确使用当前实际存在的私有 _xxsubinterpreters 模块。它暴露 create/run_string/destroy,但本机构建里没有 channel_send 等通道 API。没有通道,就要先交代输入输出怎样过边界,不能用进程池的名义代替子解释器实验。 这项选修不改 30 的进程策略 或 29 的线程池。local、线程、进程和子解释器四种执行方式都从当前源码树导入同一份 tasklab,对 "one two one " * 50 计算已有 cpu_work(iterations=120),并提交、执行、查询词频任务。各自看到相同业务结果 {"one":100,"two":50} 和校验值 754902074;相同结果不代表存储空间相同。 哪些东西能越过解释器边界 在当前私有模块里 is_shar...
Python E06:向量化何时减少 Python 层成本
词频任务原本逐个字符找单词,再把词写进字典。如果输入只含单字母小写 ASCII 单词,整批词频能换一种做法:把字节映射为 uint8 数组,对 a 到 z 做直方图。这样减少 Python 层的逐词更新,却额外发生编码、拼接、筛选和分配。换成中文、多字母单词或任意 Unicode 文本,这个实验函数就不再与原任务等价。 本篇沿用 36 的基准限制 和 04 的文本/字节边界。选修只读已有 tasklab 的 count_words、word_batches、submit/run/query;NumPy 不进入主线 wheel,也不替换在线任务分派。当前 completion 使用仓库外 optional venv,NumPy 1.26.4 来自 PyPI 解析锁,模块路径是 /private/tmp/python-language-completion/optional/lib/python3.12/site-packages/numpy/__init__.py;这与主线运行依赖分开记录。 先关住适用域 实验输入固定为 256 段文本,每段 "a b a c &quo...
Go 26:事务与条件更新怎样防止重复领取
上篇先把 QUEUED 写进真实 PostgreSQL,但 worker 完成时 SQL 还是 QUEUED。若服务把数据库改成查询状态来源,却不改变领取和完成路径,用户会一直看见一项“等待执行”的任务。本篇继续修改同一个任务服务:领取必须先在表中赢得一个条件更新,终态和结果一起提交。完整累计工程、摘要及独立解包步骤包含本次正反证据。 领取的判断要落在数据库提交点 表中一行是 id=task[shared], status=QUEUED。两个 worker 同时先查询、都看见 QUEUED、再各自修改内存标志,并不能阻止它们重复领取。sqlTaskRepository.Claim 开始一个 database/sql 事务,在事务里执行 UPDATE go_tasks SET status='RUNNING' WHERE id=$1 AND status='QUEUED'。检查 RowsAffected():只有影响一行的调用才提交并进入分析器;另一个没有命中条件的调用回滚并报告未领取。这样做不把 Go 的互斥锁误当成跨数据库连接的领取仲裁。 本次用 PostgreSQL 16.1...














