一文讲透 Java 中transient的用处(结合 Flink 理解)

一文讲透 Java 中transient的用处(结合 Flink 理解)

文章目录

在 Java / Flink 开发中,我们经常看到字段前面加了一个 transient
但很多人只知道“照着写”,并不清楚它到底解决了什么问题

本文从 Java 序列化原理 出发,再结合 Flink State 的真实运行模型,一次性把 transient 讲清楚。

一、transient 是干什么的?

一句话定义:

transient 用来告诉 Java:这个字段不要参与对象的序列化与反序列化。
classUserimplementsSerializable{String name;transientString password;}

序列化之后:

  • name 会被保存
  • password 会被忽略,反序列化后为 null

二、Java 默认的序列化规则

在 Java 中,只要满足以下条件:

  • 类实现了 Serializable
  • 字段 不是 static
  • 字段 不是 transient

👉 那么这个字段就会被 自动序列化

也就是说:

privateValueState<LastPoint> lastPoint;

在 Java 看来,这只是一个普通成员变量,会跟着对象一起被序列化。


三、如果不加 transient 会怎样?

1️⃣ 普通 Java 场景

ObjectOutputStream oos =newObjectOutputStream(...); oos.writeObject(obj);
  • transient 字段不会被写入
  • transient 字段会被写入

这是 Java 层面的规则


2️⃣ 在 Flink 中的隐蔽问题(重点)

Flink 在以下场景中,会涉及算子对象的序列化:

  • 作业下发(JobManager → TaskManager)
  • Task 重启 / failover
  • checkpoint / savepoint
  • 扩缩容(rescale)

如果你不加 transient

privateValueState<LastPoint> lastPoint;

Java 会尝试序列化这个 State 句柄对象,而这通常会导致:

  • NotSerializableException
  • 作业启动失败
  • checkpoint 异常
  • failover 后状态错乱

📌 很多问题不是立刻出现,而是线上才爆


很多人以为:

ValueState 是存在这个字段里的

这是 错误的

真实结构是:

Operator 对象(Java) └── transient ValueState handle(句柄) ↓ StateBackend(RocksDB / 内存) └── 真正的状态数据 

也就是说:

  • ValueState / ListState / MapState
    👉 只是一个“访问入口(handle)”
  • 真正的数据由 Flink StateBackend 管理

原因一:State 不是业务数据

State:

  • 不是你对象的一部分
  • 不该由 Java 序列化
  • 不该跟着对象“复制”

它的生命周期由 Flink 运行时 管理,而不是 JVM。


原因二:State 需要在运行时重新绑定

Flink 的正确流程是:

new Operator() ↓ open() ↓ getRuntimeContext().getState(...) 

而不是:

反序列化旧对象里的 state 

所以 State 字段必须:

  • transient
  • open() 中初始化

六、哪些字段该加 transient?哪些不该?

✅ 必须 / 强烈建议加 transient

  • ValueState
  • ListState
  • MapState
  • ReducingState
  • 运行时句柄(Metric、client、连接等)
privatetransientValueState<A> stateA;

❌ 不要加 transient

  • 配置类
  • 常量
  • 业务规则
  • 普通 POJO 字段
privatefinalTrajConfig cfg;

这些字段:

  • 需要被序列化
  • 需要在每个 task 中保持一致

七、常见误区

❌ 误区 1:不加 transient 也能跑

是的,但只是在:

  • 本地模式
  • 未开启 checkpoint
  • 未发生 failover

👉 这是延迟爆炸型 Bug


❌ 误区 2:在构造函数里初始化 State

publicMyFn(){ lastPoint =getRuntimeContext().getState(...);// ❌}

原因:

  • 构造阶段还没有 RuntimeContext
  • state 绑定信息还不存在

八、推荐的标准写法模板

publicclassMyProcessFunctionextendsKeyedProcessFunction<K, IN, OUT>{privatefinalConfig cfg;privatetransientValueState<A> stateA;privatetransientListState<B> buffer;privatetransientMapState<Long,Boolean> dedup;@Overridepublicvoidopen(Configuration parameters){ stateA =getRuntimeContext().getState(newValueStateDescriptor<>("stateA",A.class)); buffer =getRuntimeContext().getListState(newListStateDescriptor<>("buffer",B.class)); dedup =getRuntimeContext().getMapState(newMapStateDescriptor<>("dedup",Long.class,Boolean.class));}}

九、总结

transient 的本质作用:
阻止 Java 默认序列化,
让运行时资源交给运行时系统(如 Flink)管理。

在 Flink 中可以再加一句:

State 的生命周期属于 Flink,不属于 Java 对象。

Read more

近五年体内微/纳米机器人赋能肿瘤精准治疗综述:以 GBM 为重点

近五年体内微/纳米机器人赋能肿瘤精准治疗综述:以 GBM 为重点

摘要 实体瘤治疗长期受制于递送效率低、肿瘤组织渗透不足以及免疫抑制与耐药等问题。传统纳米药物多依赖被动累积与扩散,难以在肿瘤内部形成均匀有效的药物浓度分布。2021–2025 年,体内微/纳米机器人(包括外场驱动微型机器人、自驱动纳米马达以及生物混合机器人)围绕“运动能力”形成了三条相互收敛的技术路线: 其一,通过磁驱、声驱、光/化学自驱等方式实现运动增强递药与深层渗透,将治疗从“被动到达”推进到“主动进入”; 其二,与免疫治疗深度融合,实现原位免疫唤醒与肿瘤微环境重塑; 其三,针对胶质母细胞瘤(glioblastoma, GBM)等难治肿瘤,研究趋势转向“跨屏障递送(BBB/BBTB)+ 成像/外场闭环操控 + 时空可控释放”的系统工程。 本文围绕“运动—分布—疗效”的因果链条,总结 2021–2025 年代表性研究与关键评价指标,讨论临床转化所需的安全性、

By Ne0inhk

Moonshine专为端侧/边缘设备做的深度架构优化+可变长度推理+隐私原生+多语言强适配

一、架构与推理效率:端侧原生设计(核心优势) 1. 可变长度输入,无强制30秒窗口 * Whisper固定30秒块,短音频也要填充到30秒再处理,固定开销大。 * Moonshine支持任意长度音频,计算量与音频长度线性正比,短音频(1–3秒)速度提升5–15倍。 * 延迟:10秒音频在手机/树莓派上仅50–150ms,Whisper同条件约500–1500ms。 2. 轻量化Transformer+高效算子 * 基于Transformer但大幅精简,参数仅27M–245M(Tiny/Base/Medium),远小于Whisper同定位模型。 * 采用旋转位置嵌入(RoPE),更好捕捉语音时序,减少冗余计算。 * 推理引擎深度优化,支持INT8/FP16量化,内存占用再降70%+。 3. 流式/实时推理原生支持 * 内置流式解码,边录边转,无需等整段音频结束。 * 端到端延迟**<50ms*

By Ne0inhk
开发兜不住?让数据库来兜底:金仓 SQL 防火墙的工程化实践

开发兜不住?让数据库来兜底:金仓 SQL 防火墙的工程化实践

开发兜不住?让数据库来兜底:金仓 SQL 防火墙的工程化实践 在真实的生产环境中,数据库安全从来不是“写完代码就结束”的问题,而是一个贯穿系统生命周期的持续对抗过程。哪怕你已经严格执行参数化查询、ORM 框架封装、输入校验等规范,仍然无法保证系统绝对无注入风险——遗留系统、动态 SQL、第三方组件、甚至临时脚本,都会成为潜在突破口。 这也是为什么越来越多企业开始将防线下沉到数据库层:既然应用层不可控,那就让数据库成为最后一道“强制执行的安全边界”。 本文结合 KingbaseES 的 SQL 防火墙机制,从原理、模式设计到性能表现,讲清楚它是如何在工程上解决 SQL 注入问题的。 一、SQL 注入的本质:语义劫持,而不是“字符串拼接问题” 很多人对 SQL 注入的理解还停留在“拼接字符串不安全”,但从数据库视角来看,本质其实是: 攻击者篡改了 SQL 的语义结构(

By Ne0inhk
【Linux】——从0到1的学习,让你熟练掌握,带你玩转Linux,教你安装Java常用软件、及spring boot项目部署

【Linux】——从0到1的学习,让你熟练掌握,带你玩转Linux,教你安装Java常用软件、及spring boot项目部署

🎼个人主页:【Y小夜】 😎作者简介:一位双非学校的大三学生,编程爱好者, 专注于基础和实战分享,欢迎私信咨询! 🎆入门专栏:🎇【MySQL,Java基础,Rust】 🎈热门专栏:🎊【Python,Javaweb,Springboot】  感谢您的点赞、关注、评论、收藏、是对我最大的认可和支持!❤️ 目录 🎈Linux安装 🎁安装步骤 🎁网卡设置 🎁目录功能及介绍  🎈常用命令 🎁初体验 🎟命令  🎟实战 🎟出现乱码 🎟小技巧 🎟Linux命令格式 🎁文件目录操作命令 🎟ls 🎟cd 🎟cat 🎟more 🎟tail 🎟rmdir 🎟rm 🎁拷贝移动命令 🎟cp 🎟mv 🎁打包压缩命令 🎟tar 🎁文本编辑 🎟vi/vim 🎗命令模式 🎗插入模式

By Ne0inhk