Android用GSON替代手写序列化:数据持久化改造完整指南
1. 项目概述与改造思路把原生序列化代码替换为GSON的核心逻辑做Android开发超过一年的人大概率都经历过这种场景手里有一个用户信息对象或者一张订单列表想存到本地于是自己封装了一套SharedPreferences工具类又或者用File加JSONObject手写序列化。字段少的时候不算什么字段一多起来putString、getString、optString(name)、optInt(age)这种代码就开始失控。后台一旦改了字段名你得满项目搜索替换漏掉一个地方就是线上崩溃。这个android使用GSON保存数据替代自己开发原生代码的项目核心思路其实非常朴素用GSON把对象转成JSON字符串再写进本地存储读取时再把JSON字符串还原成对象把原生手写解析这段完全替换掉。它解决的不是少写几行代码的问题而是让内存对象和数据落地格式之间只有一个映射关系你维护好Bean剩下的序列化逻辑交给GSON改字段时不用再像捉迷藏一样到处找解析代码。我第一次完整做这种改造是经手一个登录后需要存档用户资料、筛选条件和浏览记录的项目。原实现是每个模块各写一个工具类每个工具类里都是十几行手工取值异常分支铺得很开。后来统一换GSON整个存档相关的代码量从几百行压到几十行更关键的是后续两次加字段、一次改类型都只动了Bean定义解析逻辑一行没改。这个收益在业务需求频繁变化的场景里特别明显。1.1 手写数据落盘代码的问题到底出在哪手写数据持久化通常指两条路。第一条是SharedPreferences配一堆key-value对象有几个字段就写几个putString、putInt读的时候按顺序getString、getInt还要自己处理缺省值。第二条是拿着JSONObject自己拼、自己拆复杂一点的对象还要循环数组、嵌套JSONObject代码又长又容易被某个空值点爆。这两条路的问题不是写得慢而是错误容易藏在细节里。字段名拼错一个字母编译期发现不了运行期拿到null类型没对齐optInt把100.5转成100后台某一期没有下发某个字段旧代码直接因为getString返回null继续往下传。这些坑都不是一眼能看出来的等你排查的时候往往要同时对照接口返回、Bean定义和解析逻辑三处代码非常痛苦。1.2 GSON解决的不仅是少写代码GSON解决的核心问题是把对象和JSON的转换自动化。你定义好一个类给它几个字段GSON通过反射读取字段名和值toJson生成字符串fromJson还原对象。它替你覆盖了字段遍历、类型转换、嵌套对象、数组、集合这些手写最容易出错的部分。我理解里GSON更大的价值在于统一了数据格式这一层。无论是本地缓存还是接口响应数据形态都是JSON而GSON让两边的数据结构定义都收敛到同一个Bean上。本地保存用同一套Bean接口解析也用同一套Bean少维护一套映射代码的一致性自然就上来了。还有一个隐藏好处是改动成本可控。后端把一个字段从String改成Int你只需要改Bean里那个字段的类型要新加一个字段Bean里加一个属性就能序列化进本地。这在手写时代是做不到的每加一个字段你都得去翻所有读写这个对象的代码。1.3 什么样的场景适合立刻上GSON不是所有持久化场景都适合用GSON但下面这些场景基本可以无脑替换对象字段多、嵌套深手写JSONObject取值代码明显在重复。需要把同一份Bean既用于接口解析又用于本地缓存。数据结构处于快速迭代期后端和客户端都还在频繁调整字段。本地缓存数据量不大属于MB以下级别的结构化数据。反过来如果只是存一两个key-value的配置项或者数据量大到需要考虑数据库索引和查询那GSON只是其中一环不能包打天下。它解决的是序列化这一层的问题不是存储方案本身。2. GSON功能拆解替代原生开发前必须吃透的四个能力点很多人对GSON的理解停留在toJson和fromJson两个方法。确实简单对象用这两个方法就够了但真正要替代掉手写逻辑还需要掌握TypeToken、注解、自定义适配器这几块。否则遇到泛型集合、日期格式、特殊字段时会再次退回手写。2.1 核心就两个方法toJson和fromJson先看最基础的用法。加入依赖后创建一个Gson实例然后就是对象的双向转换。implementation com.google.code.gson:gson:2.10.1Gson gson new Gson(); // 对象 - JSON 字符串 User user new User(小明, 28); String json gson.toJson(user); // JSON 字符串 - 对象 User restored gson.fromJson(json, User.class);注意一个细节别每次用都new一个Gson。Gson内部有缓存机制但频繁new会让缓存形同虚设。项目里应该全局只维护一个实例工具类里用static或者单例都可以。我习惯在封装层用lazy初始化既保证单例又保证线程安全。默认情况下Gson序列化时会忽略字段值为null的字段也忽略transient和static修饰的字段。如果你需要把null也写进JSON要这样Gson gson new GsonBuilder() .serializeNulls() .create();这个能力在数据回传接口时有用本地缓存一般用不上但要知道它存在。2.2 泛型集合必须用TypeToken别直接传Class一个最常见的翻车点是想把List转换回来直接写ListOrder orders gson.fromJson(json, List.class);代码能编译运行时不报错但拿到的List里面全是LinkedTreeMap不是你想要的Order对象。原因是JVM的泛型擦除运行时List.class并不知道元素类型是什么GSON只能给你返回一堆Map。解决办法是TypeTokenType listType new TypeTokenListOrder() {}.getType(); ListOrder orders gson.fromJson(json, listType);TypeToken内部通过匿名类的反射保留了泛型签名Gson拿到这个Type信息后才知道JSON数组里的每个对象要还原成Order。同理处理带泛型的包装类时也要这一招比如接口返回统一包一层public class ApiResponseT { public int code; public String msg; public T data; } Type type new TypeTokenApiResponseListProduct() {}.getType(); ApiResponseListProduct result gson.fromJson(json, type);在Kotlin里如果用了reified泛型和inline函数可以封装一个通用读取方法把TypeToken的写法收敛到一处。2.3 SerializedName、Expose、Since字段治理要靠Bean层手写JSON解析的年代字段名映射是散落在代码各处的用GSON后这件事应该全部收进Bean。字段名映射用SerializedName。public class User { SerializedName(user_id) public String userId; SerializedName(avatar_url) public String avatarUrl; }这样JSON里的user_id会自动映射到userIdJava/Kotlin驼峰命名的习惯不用改接口和本地数据保持一致即可。此后如果后端改字段名你只改注解或定义调用方完全无感。白名单序列化用Expose。有些字段是内部状态不需要落盘比如临时密码、内存里的计算中间结果。配合excludeFieldsWithoutExposeAnnotation使用public class User { Expose public String name; Expose(serialize false, deserialize false) public String tempToken; public String internalNote; // 没有Expose不会被序列化 } Gson gson new GsonBuilder() .excludeFieldsWithoutExposeAnnotation() .create();版本字段用Since。如果担心兼容老版本缓存数据Gson提供了setVersion加Since的组合可以按版本号忽略某些字段public class User { Since(1.0) public String name; Since(1.2) public String avatarUrl; // 1.2才加入的字段 } Gson gson new GsonBuilder() .setVersion(1.0) .create();实际项目中这个特性用得不算多但缓存迁移、灰度升级新格式时会非常有用至少不用每次升级都写一段迁移逻辑。2.4 日期、金额这类特殊类型用统一格式和自定义Adapter兜底日期是最容易埋坑的一类。Gson默认对日期类型的处理是使用JDK的默认日期格式不同Android系统语言环境下输出可能不一样直接导致你写入的日期和读出来后不是同一个样子。解决办法是给Gson定死一个格式Gson gson new GsonBuilder() .setDateFormat(yyyy-MM-dd HH:mm:ss) .create();这样无论系统是什么语言环境JSON里都是固定字符串。金额这类字段如果业务要求高精度建议统一用BigDecimal。但Gson把BigDecimal序列化成字符串还是数字默认行为在不同格式下会有差异。更稳妥的做法是注册一个自定义TypeAdapter写死序列化规则public class BigDecimalAdapter extends TypeAdapterBigDecimal { Override public void write(JsonWriter out, BigDecimal value) throws IOException { if (value null) { out.nullValue(); return; } out.value(value.stripTrailingZeros().toPlainString()); } Override public BigDecimal read(JsonReader in) throws IOException { if (in.peek() JsonToken.NULL) { in.nextNull(); return null; } try { return new BigDecimal(in.nextString()); } catch (NumberFormatException e) { return BigDecimal.ZERO; } } } gson new GsonBuilder() .registerTypeAdapter(BigDecimal.class, new BigDecimalAdapter()) .create();注意TypeAdapter里的JSON读写走的是流式接口不要在这里调用外层Gson实例不然可能出现递归调用。3. 实战落地GSON加本地缓存工具的完整封装方案理论部分聊完进入可以直接抄作业的阶段。一个完整的数据保存链路是Bean - JSON字符串 - 存储介质 - (再次启动) - JSON字符串 - Bean。下面按存储介质、Bean设计、工具封装、混淆规则、文件安全写入五个维度讲。3.1 先选存储介质SharedPreferences、File还是RoomGSON负责转换存储介质负责落地。三选一的标准很简单存储介质适合场景注意点SharedPreferences小对象、配置项、用户信息整个文件加载进内存不适合大数据File大列表、缓存数据、导出文件需要自己处理读写与文件损坏Room/数据库需要查询、分页、更新部分字段复杂字段仍可用GSON转换后存String列我个人的习惯是单次保存不超过几百KB、对象结构简单用SharedPreferences最省事内容超过这个量级或者可能要写日志、导出用File需要按条件查询就别硬塞JSON了直接上Room用GSON只处理某一个列里的复杂嵌套。另外提醒一句SharedPreferences写入有commit和apply两个方法。apply是异步落盘但会先把数据更新到内存进程不崩溃的情况下基本不会丢commit是同步落盘有返回值能判断成败。保存关键数据、或者紧接着要杀掉进程的场景用commit更稳。3.2 实体类设计能被GSON稳定持久化的Bean长什么样用GSON持久化本地对象Bean的设计直接决定稳定性。我总结了几条硬性约定避免无参构造缺失的类。Gson默认通过无参构造创建对象如果没有无参构造且没有注册构造器Gson会走Unsafe方式直接分配内存绕开构造函数导致构造函数里初始化字段的逻辑全部不执行。不要序列化带UI依赖或重量级资源的对象。Activity、Context、Bitmap这些如果出现在Bean的可达字段里轻则序列化出奇怪的东西重则内存泄漏。不要有循环引用。两个对象互相持有toJson会直接栈溢出应用崩给你看。字段语义要稳定。同一个字段今天存String明天改成Int老缓存数据解析时直接抛异常。敏感信息不进JSON。密码、token之类的明文写进SharedPreferences或File风险和自爆没区别。真要存用系统提供的加密存储方案。简单说能被GSON稳定持久化的Bean应该是一堆基本类型、字符串、嵌套Bean和集合的组合字段名稳定类型不变无UI依赖无循环。3.3 封装一个几十行就能复用的LocalCache工具这里给一个Kotlin版本Java版本思路完全一样。把Gson实例、SharedPreferences读写、异常兜底全部收敛到一个对象里object LocalCache { private val gson: Gson by lazy { GsonBuilder() .setDateFormat(yyyy-MM-dd HH:mm:ss) .create() } private fun prefs(context: Context): SharedPreferences context.getSharedPreferences(local_cache, Context.MODE_PRIVATE) fun save(context: Context, key: String, value: Any) { val json gson.toJson(value) prefs(context).edit().putString(key, json).commit() } inline fun reified T read(context: Context, key: String): T? { val raw prefs(context).getString(key, null) ?: return null return try { gson.fromJson(raw, object : TypeTokenT() {}.type) } catch (e: JsonSyntaxException) { null } } fun clear(context: Context, key: String) { prefs(context).edit().remove(key).commit() } fun T saveToFile(context: Context, fileName: String, obj: T) { val json gson.toJson(obj) val target File(context.filesDir, fileName) val tmp File(context.filesDir, $fileName.tmp) tmp.outputStream().use { out - out.write(json.toByteArray(Charsets.UTF_8)) } if (target.exists()) target.delete() tmp.renameTo(target) } inline fun reified T readFromFile(context: Context, fileName: String): T? { val file File(context.filesDir, fileName) if (!file.exists()) return null return try { file.inputStream().reader(Charsets.UTF_8).use { reader - gson.fromJson(reader, object : TypeTokenT() {}.type) } } catch (e: Exception) { null } } }用法非常直接LocalCache.save(context, user_profile, currentUser) val cachedUser: UserProfile? LocalCache.read(context, user_profile)两个关键点。第一read方法里用reified泛型配TypeToken调用方不用关心TypeToken第二解析异常必须捕获本地缓存文件可能因为历史版本、写一半崩溃等原因损坏不能让它影响主流程。3.4 R8与混淆规则上线前必须补的功课很多人功能写完了混淆一开GSON就罢工。原因是Gson靠反射读取字段名而R8混淆会把字段名改成a、b、c导致JSON里存的user_id读不到或者错位。固定套路是在ProGuard/R8规则里加三段-keepattributes Signature -keep class 你的项目包名.model.** { *; } -keepclassmembers class * { com.google.gson.annotations.SerializedName fields; }第一行保留泛型签名TypeToken才有效第二行整体保留实体类简单粗暴但管用第三行兜底哪怕没有整包keep只要字段挂了SerializedName也会保留原名。如果项目用了注解Expose可以再加一条-keepclassmembers class * { com.google.gson.annotations.Expose fields; }这里要特别强调加了keep规则后记得在发布包上真机验证一次缓存读写。混淆问题的特点是开发包正常、发布包崩溃而且往往是用户升级后第一次读旧缓存才暴露线上返工成本很高。3.5 文件写入要用临时文件加rename避免写一半崩掉直接用FileOutputStream往正式文件里写如果写到一半进程被杀、磁盘满或者异常文件就损坏了。下次启动读到半个JSONGSON直接解析崩溃。我封装里的saveToFile已经用了这个模式先写带.tmp后缀的临时文件写完后删除旧文件再把临时文件rename成正式文件。rename是一个原子性的操作系统操作要么旧文件在要么新文件在不会出现两不像的中间态。同理读取的时候如果发现文件不存在、或者解析异常返回null让上层走默认值逻辑。牺牲一点点容错换来的是缓存坏了最多重新请求不会崩溃的稳定性。4. 常见问题与排查实录GSON落地时踩过的坑这一部分全是我实际遇到并处理过的问题。每个问题都给出现象、原因和排查路径建议收藏当速查表用。4.1 混淆后字段全变成a、b、cJSON数据读取全部异常现象Release包登录后缓存能写入但重启后读出来全是null或者数据错乱。原因R8混淆把实体类的字段名改了Gson反射拿到的字段名是a、b、c跟JSON里的user_id对不上。排查先看release包的mapping文件确认实体类是否被混淆再看proguard-rules.pro里有没有keep实体类。解法按3.4的规则补keep。这是出现频率最高的问题没有之一。顺带提醒如果你用了字段名和JSON key直接同名的偷懒方案混淆后更危险因为没有任何SerializedName兜底。我的建议是核心字段一律挂上注解低成本买安全。4.2 Kotlin数据类的默认值没有生效现象data class Config( val pageSize: Int 20, val theme: String light )JSON里没有pageSize字段时理想情况应该得到pageSize20实际得到的是0。原因Gson默认通过Unsafe方式创建对象绕过了构造函数Kotlin数据类构造参数里的默认值逻辑根本不会执行。排查在fromJson调用处打印出来的对象观察默认值字段。解法三个方案任选。一是写InstanceCreator手动创建并填默认值二是解析后做一次merge从JSON的JsonObject里判断字段是否存在缺失就用手动默认值三是干脆换kotlinx.serialization它就是为Kotlin默认值问题设计的。这个坑在Java转Kotlin的项目里很常见属于代码看着没问题行为不对的典型。4.3 日期格式在真机上被本地化设置折腾现象同一套代码在中文系统、英文系统、某些厂商定制ROM上序列化出来的日期字符串格式不一样。原因Gson默认的日期适配器会依赖系统默认DateFormat。排查对比不同设备上toJson出来的日期字符串肉眼可见格式差异。解法用GsonBuilder的setDateFormat定死格式。如果你的Bean里日期字段不止一种格式注册自定义TypeAdapter统一处理更稳。这个问题的隐蔽性在于开发阶段很难发现因为测试机大概率都是中文环境等海外用户反馈日期显示不对时你才知道本地化还有这种影响面。4.4 JSON缺字段、类型变化、文件损坏导致的解析崩溃现象fromJson抛JsonSyntaxException或者IllegalStateException典型的报错长这样com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was STRING at line 1 column ...原因本地缓存的JSON和当前Bean结构不匹配。可能是旧版本缓存没有新字段、某个字段类型从数组变成了字符串、或者文件被写坏。排查把崩溃现场的JSON字符串保存下来和当前Bean结构对比。解法所有从本地读缓存的地方一律try-catch解析失败返回null走默认逻辑必要时在Bean外层再加一层版本号字段大版本升级时直接丢弃旧缓存。这里我强烈建议把本地缓存解析设计成容错路径它永远不应该是崩溃点。4.5 大列表序列化卡顿与内存峰值现象一个包含上万条记录的列表toJson时界面明显卡顿甚至OOM。原因toJson是先把整棵对象树转成中间结构再输出字符串大对象会一次性占用大量内存。排查用Profiler观察toJson时间段的内存和CPU。解法大数据别走GSON全量序列化这条路。要么改存数据库要么用JsonWriter做流式写入一行一条地写避免整棵对象树驻留内存。JsonWriter writer new JsonWriter(new OutputStreamWriter( new FileOutputStream(file), StandardCharsets.UTF_8)); writer.beginArray(); for (Item item : list) { gson.toJson(item, Item.class, writer); } writer.endArray(); writer.close();流式方案读的时候配合JsonReader逐条解析能做到近似常量内存。不过这条是进阶玩法项目没到那个量级不用急着上。4.6 循环引用、无用字段混进JSON现象序列化一个父子互相引用的对象StackOverflowError或者Bean里混进了大量内部临时字段JSON又大又杂。原因Gson默认遍历所有可达字段对循环引用没有特殊处理字段没有白名单约束什么都往里写。排查看toJson抛的异常栈是不是在同一个类之间反复横跳。解法数据结构上砍掉双向引用改成id关联生产环境用GsonBuilder加excludeFieldsWithoutExposeAnnotation只序列化声明了Expose的字段。我曾经见过一个项目把一个带Activity引用的对象存进了缓存结果是Activity连同它持有的整个View树全部被序列化成JSON文件巨大不说反序列化时各种异常。记住一条原则能落盘的Bean应该只包含纯数据。5. 选型心得GSON不是唯一答案但通常是替换成本最低的答案聊完实战最后说点选型层面的判断。近几年Moshi和kotlinx.serialization热度都不低也有人问我是不是该直接上新的。我的看法是要看项目现状不要为了追新而追新。5.1 GSON、Moshi、kotlinx.serialization横向对比对比维度GSONMoshikotlinx.serialization接入成本最低一个依赖就能跑中反射版很简单codegen要配kapt中高要引入编译插件Kotlin默认值支持需要额外处理反射版同样受限codegen支持好原生支持运行性能反射一般反射一般codegen版本好编译期生成无反射好Android兼容性老项目零成本兼容性较好需要留意版本和Gradle配置学习成本团队基本都会概念相近容易上手注解和插件体系要重新学混淆规则必须配keep规则同样要keepcodegen模式对混淆更友好做这个对比不是为了分高下而是想说明新方案的优势集中在Kotlin默认值、编译期安全、性能这三个点上。如果你的团队全是Java老代码或者只是做一次去掉手写解析的快速改造直接上Moshi或者kotlinx带来的收益可能抵消不了接入成本。5.2 我个人的选型建议与最终落地体会如果让我给一个务实的选择标准大概是这样存量项目、Java为主、团队对GSON已经很熟直接用GSON按本文的封装和规则做改造投入最小短期见效最快。新项目、纯Kotlin、数据类很多且依赖默认值优先kotlinx.serialization编译期生成代码默认值、非空类型都有保障省掉一堆Gson的坑。新项目、不想上插件、但想要更好的Kotlin体验Moshi的codegen模式是折中方案。无论如何都要保持数据结构变化不影响存储读取的稳定性不管选哪个库都要把解析封装成容错路径。我自己的落地体会是GSON替换手写代码这件事真正的难点从来不在序列化语法而在于把数据格式变化和存储边界都管理起来。建议保留一个CacheManager层所有读写都走它底层引擎今天可以是Gson明天换成Moshi上层业务只依赖CacheManager的接口。这样即使将来换了序列化库业务代码一行都不用动。另外一个很实用的习惯是每次给Bean加字段或者改类型都顺手想一下旧版本缓存数据遇到这个新结构会发生什么。养成这个习惯之后线上因为缓存解析挂掉的问题能减少九成。GSON这套方案我到现在仍然在大多数中小型项目里使用。它不算最前沿但足够可靠替代手写原生代码后维护成本下降非常明显。如果你正在犹豫要不要做类似改造我的建议是挑一个字段最多的Bean先试把读写工具封装好让数据观察几天你会很快感受到差异。

相关新闻

Claude Opus 5.5 焚诀实战:Sub-agent、CLAUDE.md 与 effort 配置指南

Claude Opus 5.5 焚诀实战:Sub-agent、CLAUDE.md 与 effort 配置指南

1. 这次“焚诀”到底更新了什么:从标题拆解到核心能力全景“Claude Opus 5.5 最新焚诀发布了”这个标题,第一次看到的时候我愣了一下——“焚诀”这个词在圈子里其实是个半开玩笑的说法,指的是那种把模型能力压榨到极限、把工作流烧到最精简的…

2026/10/9 3:45:20 阅读更多 →
Modbus PLC实战:从通讯超时到稳定运行的工程指南

Modbus PLC实战:从通讯超时到稳定运行的工程指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 3:45:20 阅读更多 →
给Claude装外挂记忆:claude-mem跨会话记忆实操全攻略

给Claude装外挂记忆:claude-mem跨会话记忆实操全攻略

如果你跟我一样每天都在跟 Claude 打交道,应该早就被同一件事折磨过:模型本身很聪明,但它没有长期记忆。上一个会话里刚定好的项目架构、命名约定、回答风格,新开一个窗口就全部清空了。你得一遍遍把同样的背景资料粘进去&#xf…

2026/10/9 3:45:20 阅读更多 →

最新新闻

工业智能体落地汽车研发制造:从概念到工程实践的关键路径

工业智能体落地汽车研发制造:从概念到工程实践的关键路径

先说个现象:前几天《人民日报》关注江淮汽车“以工业智能体赋能高端汽车研发制造”这条消息刷屏后,“智能体”这个词在行业群和热搜里彻底炸了。很多朋友把报道转给我时都在问同一个问题——工业智能体到底是什么?它凭什么能和高端的汽车研发…

2026/10/9 4:22:46 阅读更多 →
实体类驱动建表:MyBatis-Plus自动生成DDL与代码生成实践

实体类驱动建表:MyBatis-Plus自动生成DDL与代码生成实践

1. 项目思路拆解:实体类当“唯一事实来源”1.1 传统流程里重复劳动有多痛写了十年SQL,我原本以为自己最值钱的手艺就是建表和写CRUD。之前的项目节奏基本都是这样:需求评审完,先在建模工具里画出物理模型,确认字段类型…

2026/10/9 4:22:46 阅读更多 →
OpenHarmony上RN错误边界与白屏问题全链路排查方案

OpenHarmony上RN错误边界与白屏问题全链路排查方案

1. 为什么在OpenHarmony上做RN要重新审视错误边界先从这次项目的起点说起。团队在适配React Native到OpenHarmony平台时,最头疼的不是JS层面的兼容问题,反而是看起来不起眼的崩溃和白屏。很多开发者第一次跑通RN on OpenHarmony时,都会遇到一…

2026/10/9 4:22:46 阅读更多 →
ESP-Mosaico:模块化硬件方案让ESP32原型开发像拼马赛克

ESP-Mosaico:模块化硬件方案让ESP32原型开发像拼马赛克

ESP-Mosaico这个名字第一次出现在我眼前的时候,我以为是乐鑫做的某种图形界面库——毕竟mosaico在西班牙语里就是“马赛克”,听起来像是把图像拼成一块一块的东西。真正点开项目文档才发现,它其实是一套模块化硬件开发方案,把主控…

2026/10/9 4:22:46 阅读更多 →
时间自由缩放:超越压缩的智能架构如何控制时间维度

时间自由缩放:超越压缩的智能架构如何控制时间维度

我们其实已经站在了一个很有意思的拐点上。过去十年,智能系统最大的进展,表面上是模型越做越大、能力越做越强,但本质上就干了一件事:压缩。把语言压缩成token,把图像压缩成embedding,把世界知识压缩进权重…

2026/10/9 4:22:46 阅读更多 →
基于Deepseek Harness的防幻觉电源设计Agent实践

基于Deepseek Harness的防幻觉电源设计Agent实践

我一直在做电源相关的硬件设计,这两年深度用大模型辅助设计之后,发现一个很尴尬的问题:模型给出的方案,听起来头头是道,但落到具体元器件参数、环路补偿、热计算上,经常一本正经地编数据。有一回我让模型推…

2026/10/9 4:21:45 阅读更多 →

日新闻

Java时间API实战:LocalDate、Date与ZonedDateTime的转换与避坑指南

Java时间API实战:LocalDate、Date与ZonedDateTime的转换与避坑指南

Java时间API这个话题,隔三差五就会在群里被翻出来讨论一次。上周还有个同事线上处理一个订单超时问题,排查到最后发现是ZonedDateTime序列化后时区丢了,用户在下单当天晚上看到的时间整整差了8个小时。这类问题几乎每个做Java开发的人都遇到过…

2026/10/9 0:00:49 阅读更多 →
EasyTier实践:从NAT穿透到子网代理的异地组网部署与排错

EasyTier实践:从NAT穿透到子网代理的异地组网部署与排错

前几个月我手头有好几台机器需要互相访问:办公室台式机、家里 NAS、还有一台云主机。如果只是偶尔传个文件倒还好,问题是工作场景经常要在几处环境之间来回切换,每次都先登录跳板机再层层代理,实在折腾。我先后试过端口映射、自建…

2026/10/9 0:00:49 阅读更多 →
AI Agent工程实战:从七要素到七个决策点的系统设计指南

AI Agent工程实战:从七要素到七个决策点的系统设计指南

AI Agent 这个词在过去一年里被反复提及,但真正动手搭过一套能跑起来的 Agent 系统的人都知道,从"知道它是什么"到"让它稳定干活"之间隔着一整套工程决策。我前后参与过几个 Agent 项目的落地,从最初用现成框架拼装&…

2026/10/9 0:01:50 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 15:26:32 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 15:26:40 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 10:10:36 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 21:13:17 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 15:26:17 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/7 13:34:55 阅读更多 →