JSON 日志里的 `{“$ref“:“$.xxx“}`:从 fastjson 兼容包到原生 fastjson2 的迁移实录

深度强化Q学习-基于微软AirSim仿真环境的自动驾驶案例(原理代码详解简易可行) 最近在学习《强化学习原理与Python实现》,肖智清著。参考第十二章的自动驾驶案例,写一篇总结,尽量做到简单可行,让有志于自动驾驶的小伙伴可以通过此篇博客可以管中窥豹,初步了解自动驾驶的强化学习训练过程。 本篇将自动驾驶问题转化为回合制的强化学习任务,设计以车辆观察图像和运行状态为输入的自动驾驶算法,并在AirSim仿真环境中进行训练和测试。本篇使用带经验回放和目标网络的基于深度Q网络算法设计并实现智能体,对经验回放、目标网络和深度Q学习算法进行简单介绍,并用代码实现。 阅读详情

JSON 日志里的 {"$ref":"$.xxx"}:从 fastjson 兼容包到原生 fastjson2 的迁移实录

联调时日志里冒出 {"$ref":"$.xxx"}——菜单项的优惠券数据变成了一串 JSONPath 天书。查下去发现工程用的 com.alibaba:fastjson 其实是 fastjson2 的兼容包,为了对齐 fastjson1 行为默认开着引用检测。本文记录从定位根因、过渡止血,到彻底迁移原生 fastjson2 的全过程。

一、现象:日志里的数据变成了引用指针

联调时查看响应体日志,菜单项的 coupon 部分长这样:

"tenderName": "指定小食 (3选1) 同款买一送一优惠券",
"linkIds": {
    "$ref": "$.100012808$100089523.\\,100087662.28514$100106028.100012810$100089523..."
},
"couponCode": "Q-44212956107937024514-SZKFC2603008-14961",

linkIds 本该是数组,输出却是一个 {"$ref": "$.jsonpath"} 对象。排障时看到的不是数据,是一串指向序列化树其他位置的路径——日志基本废了。

二、根因:兼容包默认开启循环引用检测

{"$ref": "$.jsonpath"} 是 fastjson 的循环引用检测(ReferenceDetection)在起作用:同一对象实例在序列化树中出现第二次时,不再重复输出内容,而是输出一个 JSONPath 指针。菜单数据里大量共享对象引用(同一个 coupon 对象挂在多个菜单项下),于是日志里到处是指针。

关键在 pom 依赖树:

com.alibaba:fastjson:jar:2.0.45:compile        ← 注意:groupId 还是 com.alibaba,版本却是 2.x
 \- com.alibaba.fastjson2:fastjson2-extension:jar:2.0.45:compile
    \- com.alibaba.fastjson2:fastjson2:jar:2.0.45:compile

工程引的 com.alibaba:fastjson 实际是 fastjson2 的兼容包:保留 com.alibaba.fastjson.* 旧包名和旧 API,底层委托给 fastjson2 核心。为了让存量代码行为不变,兼容包默认开启 ReferenceDetection——这正是 fastjson1 的默认行为,也正是 $ref 的来源。

三、过渡止血:日志序列化先收口

最快的止血方式是序列化时显式关闭引用检测。但直接改有 25 处调用点,散落在 12 个文件里——先收口再改,而不是复制粘贴 25 遍。

在 JsonUtils 增加日志专用序列化入口:

// JsonUtils.java
public static String toLogString(Object object) {
    return JSON.toJSONString(object, SerializerFeature.DisableCircularReferenceDetect);
}

然后全局替换各文件的日志调用:

文件处数
ApiLoggingResponseBodyAdvice(截图日志的来源)1
IntentORServiceImpl5
CrowTagController / RestTemplateUtils4 / 4
ObjectLogicMethodLocal / ScopeTransformer2 / 2
DataToolMethod / GlobalExceptionHandler / IntentServiceImpl / RankCandidateFilter / RankSatisfactionEvaluator / Rule各 1

注意 AppController 用的本来就是 com.alibaba.fastjson2.JSON(原生包默认无引用检测),不用动。

能跑,但代码里同时存在 com.alibaba.fastjson(兼容包)和 com.alibaba.fastjson2(原生)两套 API,长期必须收敛——顺势升级。

四、迁移原生 fastjson2

4.1 pom:去掉兼容包,直连原生

<!-- fastjson2 -->
<dependency>
    <groupId>com.alibaba.fastjson2</groupId>
    <artifactId>fastjson2</artifactId>
    <version>2.0.45</version>
</dependency>

4.2 javap 摸清 API 面

工程用到的 fastjson API 只有四个:toJSONString / parseObject / parseArray / toJSON。对 fastjson2 核心包 javap 确认签名全部存在:

javap -cp fastjson2-2.0.45.jar com.alibaba.fastjson2.JSON | grep -E "toJSON|parseArray|parseObject"
# public static java.lang.String toJSONString(java.lang.Object);
# public static <T> T parseObject(java.lang.String, java.lang.Class<T>);
# public static <T> java.util.List<T> parseArray(java.lang.String, java.lang.Class<T>);
# public static java.lang.Object toJSON(java.lang.Object);

API 层面无痛。

4.3 用真实运行验证行为差异(关键步骤)

API 存在 ≠ 行为一致。写了个 20 行的测试类直接跑 fastjson2,抓到两个关键差异:

Object r = JSON.toJSON("{\"a\":1}");
System.out.println(r.getClass());   // fastjson1: JSONObject;fastjson2: java.lang.String !

实测结论:

行为fastjson1(兼容包)fastjson2 原生
toJSONString 共享引用输出 {"$ref":"$.xxx"}输出完整 JSON(默认无引用检测)
toJSON(String)解析成 JSONObject/JSONArray原样返回 String,不解析
parseObject/parseArray(String, Class)—行为一致
toJSONString(null)—一致

第一个差异正是我们要的:迁移后 toLogString 里的 SerializerFeature 参数直接删掉即可,$ref 天然消失。

第二个差异如果没有实测、直接迁移,isJSONString() 会被静默破坏:

// 迁移前(fastjson1)
return toJSON(content) != null;   // toJSON 会解析字符串

// 迁移后若不改:toJSON 对 String 原样返回(永远非 null)——任何字符串都被判定为合法 JSON

修正为显式解析:

// JsonUtils.java
public static boolean isJSONString(String content) {
    if (content == null) {
        return false;
    }
    if (!isJSONStringByMap(content) && !isJSONStringByArray(content)) {
        return false;
    }
    try {
        return JSON.parse(content) != null;
    } catch (Exception e) {
        return false;
    }
}

4.4 迁移落地

得益于第三步的收口,全部 fastjson1 引用只剩 4 个文件:

文件改动
JsonUtilsimport 换 fastjson2;toLogString 简化(不再需要 SerializerFeature);isJSONString 如上修正
DataToolMethodimport 换 fastjson2(parseObject(String, Class) 签名相同)
Menu删除未使用的 import static ... toJSON
VectorCondition删除未使用的 fastjson1 import(文件里 gson 的 JsonObject 不动)

4.5 迁移后的依赖树

+- com.yumchina.architecture.framework:yum-common-utils:jar:4.0.0-SNAPSHOT:compile
|  +- com.alibaba:fastjson:jar:2.0.45:compile          ← 公司工具包还在传递引入兼容包
|  |  \- com.alibaba.fastjson2:fastjson2-extension:jar:2.0.45:compile
+- com.alibaba.fastjson2:fastjson2:jar:2.0.45:compile   ← 本工程显式直连原生

yum-common-utils 仍传递依赖兼容包,但与显式 fastjson2 同版本(2.0.45),底层是同一个 fastjson2 核心,无冲突;且显式声明保证了即使将来 yum-common-utils 变化,本工程的 fastjson2 依赖不受影响。

五、验证

mvn clean test
# Tests run: 46, Failures: 0, Errors: 0, Skipped: 0
# BUILD SUCCESS

编译通过、46 个单测全绿;重启服务后日志中共享引用输出完整 JSON,$ref 消失。

六、延伸:toLogString 与 isDebugEnabled

收口完成、$ref 消失之后,还有一个隐患值得单独拿出来说:toLogString 本身的执行时机。

25 处调用点里,绝大多数是这样的 log.debug:

log.debug("sessionId:{}, menuData:{}", ApiLogContext.getSessionId(), JsonUtils.toLogString(menuData));

SLF4J 的 {} 占位符只能省掉字符串拼接,省不掉参数求值——调用 log.debug() 之前,toLogString(menuData) 已经把整个菜单对象树全量 JSON 序列化完了。而生产环境 root 级别是 INFO(见 log4j2.xml),这条 debug 日志最终会被丢弃,但序列化的开销(遍历菜单、反射取值、分配大字符串、立刻变成垃圾)一点没少。菜单数据带 round/subItem 嵌套,单个菜单序列化出几十 KB 是常态,高频请求下这笔浪费很可观。

这和 log.isDebugEnabled() 的经典场景是同一个问题:在日志真正打印之前,先判断级别,避免为注定被丢弃的日志做重计算。

// 反例:DEBUG 关闭时也会全量序列化菜单
log.debug("sessionId:{}, menuData:{}", ApiLogContext.getSessionId(), JsonUtils.toLogString(menuData));

// 正例:DEBUG 关闭时连 toLogString 都不会执行
if (log.isDebugEnabled()) {
    log.debug("sessionId:{}, menuData:{}", ApiLogContext.getSessionId(), JsonUtils.toLogString(menuData));
}

本工程能不能用 Lambda 写法?不能

网上常见这样的"现代替代方案":

// SLF4J 2.0+ 的 Supplier 重载(本项目不可用)
log.debug("sessionId:{}, menuData:{}", sessionId, () -> JsonUtils.toLogString(menuData));

要泼一盆冷水:Supplier 重载是 SLF4J 2.0 才引入的。本工程依赖树是 slf4j-api:1.7.36(Spring Boot 2.7.18 管理)+ Log4j2 2.22.1 桥接,Lombok @Slf4j 生成的是 SLF4J 1.7 的 Logger——log.debug(String, Supplier...) 这个重载根本不存在。所以在当前依赖下,isDebugEnabled() 是唯一正确的防御姿势;等将来升级 SLF4J 2.x 再考虑换 Lambda。

写法参数求值时机本工程可用
log.debug("{}", toLogString(obj))调用前必然执行,DEBUG 关闭也全量序列化✅(但有性能隐患)
if (log.isDebugEnabled()) { ... }关闭时整块跳过,零开销✅ 推荐
log.debug("{}", () -> toLogString(obj))级别开启时才求值❌ 需 SLF4J 2.0+,当前 1.7.36 不可用

一句话总结:{} 占位符解决的是字符串拼接的开销,isDebugEnabled() 解决的是参数构造的开销——当参数本身是一次重量级操作(如全量 JSON 序列化)时,后者才是真正的保护开关。

七、总结与启示

  1. fastjson 兼容包 ≠ fastjson2。com.alibaba:fastjson:2.x 只是为存量代码平滑过渡的桥:旧包名、旧 API 都在,但默认行为也对齐了 fastjson1——包括引用检测。看到依赖树里 com.alibaba:fastjson 配 2.x 版本号,要意识到它底层跑的是 fastjson2,但行为开关仍是 fastjson1 那套。要根治 $ref,切原生 com.alibaba.fastjson2。

  2. 迁移序列化框架,行为验证比 API 验证重要。javap 能确认方法存在,确认不了语义变化。fastjson2 的 toJSON(String) 不再解析字符串,这种差异 IDE 和编译器完全不会报错,只有运行时实测能暴露。迁移前写一个 20 行的行为探针测试,性价比极高。

  3. 日志序列化先收口再迁移。把散落在 12 个文件里的 25 处 JSON.toJSONString 收口到 JsonUtils.toLogString() 一个入口,后面切 fastjson2 时改动量从 25 处降到 4 个文件——基础设施收口的红利在下一步立刻兑现。

  4. $ref 不只是日志可读性问题。引用检测在"打印"场景是噪音,但如果哪天把带 $ref 的字符串落库或回传给不识别该语法的消费方,就是实打实的数据 bug。日志用 toLogString,业务序列化用各自明确的序列化器,两条路径不要混。

  5. 重量级日志参数要用 isDebugEnabled() 保护。{} 占位符挡不住参数求值:log.debug("{}", toLogString(menu)) 在 INFO 环境下依然全量序列化。凡是参数里带 toLogString、toJson、深度 toString 之类重计算的日志,一律套 isDebugEnabled();本工程 SLF4J 1.7 没有 Supplier 重载,"Lambda 惰性求值"那一套暂时用不了。

【同等学力】2005-数学⭐✨ 有r个正方形排成一行,今用红、黄、白、蓝四种颜色给这个r个正方形染色,每个正方形只能染一种颜色,如果要求染红、黄、白色的正方形分别至少出现一个,问有多少种不同的染法?3、(4分)设G是一个有n个结点m条边的连通简单平面图,若n≥3,则m≤3n-6.4、(4分)证明:任何连通简单平面图至少有一个结点的度数不超过5 阅读详情

相关推荐

浅谈“无人机通感一体化(ISAC)”

总的来说,通信和感知一体化是一个循序渐进的过程,是未来一个比较有潜力的发展场景,当然,需要研究的内容有很多,面临的挑战也有很多,但是它值得我们去探索和学习!

m0_69182322的博客 4200

训练数据示例

针对“规格书生成测试用例脚本”的任务,在 LLaMA-Factory 中使用即可。关键是把“规格书内容”放进input字段,把“期望的脚本输出”放进output字段。

liuxs2009的专栏 56

Windows打印体系结构之Windows内置打印驱动程序

时间是一种很残酷的东西,它只会冲淡能够冲淡的,但也会洗尽铅华帮你留下该留下的。1.3.4、Windows内置打印驱动程序现在的Windows下的打印机驱动程序通常分为V4打印机驱动程序(V4 Printer Driver)、XPS打印机驱动程序(XPSDrv)、微软通用打印机驱动程序(Microsoft UniversalPrinter Driver)、微软PostScri...

weixin_34309435的博客 2253

iOS 多语言本地化教程,VS Code KXApp 编辑 String Catalog .xcstrings

做 iOS 多语言本地化总要在 VS Code 和 Xcode 之间来回切?这篇讲用 KXApp(快蝎)在 VS Code 里直接编辑 String Catalog(.xcstrings):双击打开和 Xcode 一样的表格,`.xcstrings` 与老的 `.strings`、`.stringsdict` 同表编辑,加语言同步登记到工程、从源码扫描同步新 key,复数、设备变体和变量占位都在表里处理,改源语言文本后已有翻译自动标需复核。文件仍是标准格式,回 Xcode 打开一致。

2501_91592143的博客 149

VMD分子可视化实战:5个隐藏技巧让你的科研图像秒变顶刊级别

本文深入探讨了VMD分子可视化软件在科研图像美化中的5个高阶技巧,旨在帮助研究者将分子结构图提升至顶刊级别。内容涵盖原子色彩与材质的艺术化定制、沉浸式分子环境构建、专业构图与视角控制、数据驱动的动态可视化以及自动化工作流建立,通过精细的色彩映射、光照调整、周期性边界展示和脚本自动化,显著增强图像的科学叙事性与视觉冲击力。

weixin_29240343的博客 419

Android 14.0 首次开机默认授予app运行时权限(去掉运行时授权弹窗)

在14.0的系统rom产品定制化开发中,在6.0以后对于权限的申请,都需要动态申请,所以会在系统首次启动后,在app的首次运行时, 会弹出授权窗口,会让用户手动授予app运行时权限,在由于系统产品开发需要要求默认授予app运行时权限,不需要用户默认授予运行时弹窗,所以需要在首次开机默认授予所有app运行时权限

安卓兼职framework和app工程师的博客 2531

用 ijson 流式解析 SerpBase 快照归档:把 16GB 内存压回 200MB

凌晨三点,解析脚本把机器内存吃满了去年做搜索数据归档分析时,我写了一个统计脚本:读取一个月的原始响应归档,统计每个域名在自然结果里出现的次数。归档文件是把每天几千条 SerpBase 响应拼成一个大 JSON 数组,单月文件 2.4GB。脚本跑起来不到四十秒,监控告警就响了——一台 16GB 内存的机器,可用内存被吃到只剩几百兆,同机的采集任务全被拖慢。。

Y381532662的博客 268

Pytorch入门教程

Pytorch学习总结:1.张量Tensor 张量是一种特殊的数据结构,与数组和矩阵非常相似。在PyTorch中,我们使用张量对模型的输入和输出以及模型的参数进行编码。 张量类似于NumPy的ndarray,除了张量可以在 GPU 或其他硬件加速器上运行。事实上,张量和NumPy数组通常可以共享相同的底层内存,从而无需复制数据。...

专注大数据与人工智能技术分享,欢迎私信加群互相学习! 4万+

MCP接入Claude Code: 配置调用与排错全流程

💡 阅读提示: 这篇是我把 Sorftime MCP 接进 Claude Code 的完整过程, 从写配置文件到跑通第一次调用, 再到撞上 unrecognized_model、PATH、环境变量这几个坑。想给自己的 AI 助手接一

2601_96080792的博客 174

第5.2章 【自动驾驶行业融合定位核心】:手把手详解ESKF(误差卡尔曼滤波)理论公式及代码

自动驾驶定位中的ESKF(误差卡尔曼滤波)技术是解决IMU累积误差的关键,通过分离名义状态与误差状态实现高精度定位。其核心步骤包括:1)名义状态递推(位置/速度/姿态的基础物理计算);2)误差传播建模(雅可比矩阵F量化误差影响);3)协方差更新(评估定位不确定性)。ESKF在GNSS信号丢失(如隧道场景)、无卫星定位(地下车库)等场景发挥重要作用,通过融合多传感器数据维持定位精度。工程实现需解决零偏校准、协方差投影等关键问题,噪声参数需通过数据标定而非随意设置。掌握ESKF原理与实现是自动驾驶定位工程师的核

行知SLAM 702

在 ABAP 平台上搭建 OAuth 2.0 Server:架构、流程、权限与落地实战

摘要:本文为SAP ABAP开发人员提供将ABAP平台配置为OAuth 2.0授权服务器的实战指南。重点介绍两种授权流程(授权码和SAML Bearer)的实现方案,包括核心事务配置(SOAUTH2/SAML2)、授权对象(S_SCOPE)管理以及端点交互规范。通过具体配置清单和三类典型集成场景(第三方Web应用访问OData、企业集成平台调用、BTP应用对接)的落地示例,帮助读者快速构建安全的OAuth 2.0服务架构。文档强调SSL/TLS基础安全、scope最小授权原则以及授权与令牌端点的标准交互模式

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 307

AI 编程智能体零门槛调用手册:从“能跑”到“敢放进作品集”

抄下来的调用示例跑不通、密钥硬编码、换模型就崩?这份手册按使用频率排序,每条给出用途、最小示例和坑点,30秒定位你需要的片段。跟着做,你将得到一个可配置、可切换模型、密钥不入库的小型智能体脚本——正是面试常问的安全集成大模型能力。🔧 从“能跑”到“敢放进作品集”,只差这一层重构。

2601_94912102的博客 391

24. SAP UI5 应用如何使用 OData 数据模型

本教程之前的二十三个步骤,使用的数据模型都是 JSON 模型。从本步骤开始,我们要学习另一种非常重要的数据模型:OData 数据模型。 OData 数据模型也是 SAP 产品里广泛使用的数据模型,比如 SAP S/4HANA,SAP CRM Fiori 应用等等,都使用的是 OData 数据模型而不是 JSON 数据模型。 使用 OData 数据模型的典型场景就是,通过 OData 模型提供的 Read API,将远端服务器上存储的数据通过 OData 协议读取到客户端,并显示在 SAP UI5 应用里。.

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 5794

Python+Agent入门笔记(二):列表推导式、模块和异常,这些写 Agent 前得会

接上一篇《Python+Agent入门笔记(一)》。基础语法跑通之后,这篇聊几块日常写脚本绕不开的东西。还是按 JS/Go 开发者的视角写,尽量记录我实际卡过的地方。

qq_41241612的博客 428

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

MCP本地服务集成避坑:从Stdio管道僵死到双向JSON-RPC稳健通信

本文剖析MCP服务端因调试日志污染Stdio管道导致客户端挂起的根因,指出console.log等非结构化输出会破坏JSON-RPC协议解析,引发通信僵死。提出双通道隔离方案:将业务通信严格限定于stdout,所有日志分流至stderr,并强制单行原子化传输与缓冲刷新。实践证明该架构可彻底消除解析崩溃与延迟问题,实现零延迟、高可靠的本地智能体通信,是MCP插件工程化的必选项。

艺杯羹的博客 485

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

从 Prompt 到 Tool Calling:AI Agent 如何稳定连接程序世界

大语言模型原生能力是生成 Token,而软件系统要求类型、权限、状态和确定的执行结果。AI Agent 要连接数据库、搜索引擎、支付系统或企业 API,中间必须建立一层可验证的交互协议。

weixin_47983718的博客 193

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

Spring AI 全模块 API 字典一览(1.1.0 版)

本文为 Spring AI 1.1.0 全量字典,涵盖模型接入(ChatModel)、Prompt与Message架构、ChatOptions配置及实战用例。重点解析 call()/stream() 方法签名、Prompt 消息封装机制、ChatResponse 响应结构,以及工具调用(ToolCall/ToolResponse)的配对逻辑。附真实项目用例(如 WebSearchReactAgent、PlanExecuteAgent),强调多轮对话记忆机制、流式处理防空策略与参数配置顺序陷阱,适配 Open

Java 后端学习者。写 JUC 并发、Redis 实战,也记录 LLM 应用开发(Spring AI / RAG / Agent)的学习实录——少讲概念,多讲过程和踩坑。 576

c++ 超级大坑未定义行为如何避免(下)

尤其是通过。

拒绝AI文,努力在AI时代写出感动人心的好文章 141

LangChain 能力详解(二):聊天模型核心能力 —— 工具调用、结构化输出、流式传输

ChatOpenAI实时提取 JSON 字段边输出边高亮 Markdown边输出边计费yield chunk.content.upper() # ← 每个块都处理会同时实现parse(非流式)和_transform(流式),所以这个解析器在invoke和stream下都能用。能力一句话核心 API工具调用让模型从「只会说」变成「会决定做什么」@toolbind_tools结构化输出让模型从「返回字符串」变成「返回对象」流式传输让用户从「干等 20 秒」变成「立刻看到」stream。

2601_94861874的博客 344

AI 应用的数据库架构:按数据类型选技术

**AI 应用的数据库架构:按数据类型选技术** ## 一、关系型库:记录主库 对绝大多数 AI 产品,最安全、省心的起点是一个支持事务与约束的关系型库,作为默认记录主库。 适用场景:租户与用户身份、计费与权益(订阅、配额)、智能体运行与任务状态、工具审批与审计日志、对话元数据(非消息体本身)、文档归属与访问策略、评测结果。 灵活用法:可用 JSON 列存供应商元数据,而不破坏关系保证。具

search_agent的博客 346

23-JSON-Patch转成局部更新

前端仅修改部分字段时,应将 JSON Patch 的 replace 操作映射至白名单列,转为局部 UPDATE,避免整行更新导致未展示字段被清空。服务端严格校验路径、类型,拒绝主键、删除标记等敏感字段,审计字段由服务端写入,确保数据安全与一致性。通过参数化查询防止注入,结合版本控制应对并发,实现精准、安全的局部更新。

CAthlete的博客 210

Linux 下 OpenCode 接入自定义大模型 API 教程:以 DeepSeek-V4.1-Flash-1017 为例

本文介绍在Linux下通过Python脚本配置OpenCode接入自定义大模型API(以DeepSeek-V4.1-Flash-1017为例),实现永久化、非侵入式配置。通过修改~/.config/opencode/opencode.json文件,添加OpenAI兼容服务商BLSC,注册模型并设置APIKey。支持命令行测试、默认模型设定及安全权限控制,操作简单且不影响原有配置。适用于各类支持OpenAI接口的自定义模型服务,提升开发灵活性与安全性。

qq_15060477的博客 118

【Python】国家中小学智慧教育平台电子教材批量下载与 PDF 合成实战

成果:两本语文电子课本(一年级上册 118 页 / 23MB、三年级上册 130 页 / 30.3MB),合计 248 页、约 54MB,单本下载加合成 40~60 秒,PDF 页数校验全部通过。经验教训SPA 站点的数据接口优先从 bundle 里挖,比抓页面稳得多;资源链接要按 private/public 分组看待,只取平台公开部分;页数、目录名这类“可推断”的信息,永远用实际响应验证一次;受限环境里“能不能跑浏览器”要在方案定稿前确认。后续计划:这版 PDF 是图片版,没有文字层;

木头大左的博客 117

2,615 个知识点、3,003 条先修边:6,800 Star 的开源知识图谱,能顺着错题从高中回溯到小学

2,615 个知识点、3,003 条 hard/soft 先修边、约 1.16 万道题:cn-math-taxonomy 把人教版教材与课标焊进开源知识图谱,答错高中题能回溯到小学知识点。本文拆解其数据工程与自适应诊断算法。

话梅糖の优快云 Blog 317

JSON里的编号要不要加引号?用一次格式化核对清楚

用自编长编号、前导零批次号和普通数量实测JSON格式化,逐项核对字符串与数值类型。结合RFC 8259说明数字互操作边界;格式化不能替代接口契约,也不能恢复上游丢失的数据。

qq_17765433的博客 215

在自动化脚本中使用Post网络请求

httpPost在冰狐自动化脚本里的位置有些特殊。平台的大多数网络接口都以同步阻塞的方式工作,调用发出后脚本会停在那一行,直到响应回来或彻底失败才继续往下走。这种设计放在自动化场景里其实比异步回调更顺手——登录、签到、提交表单这些操作,前后步骤天然有顺序依赖,没必要为了“异步”而把逻辑拆散。不过,正因为它是阻塞的,一旦请求出问题,整条脚本链路都会卡住。所以用httpPost的关键不在于“会发 POST”,而在于对数据格式、超时边界和失败路径有明确的控制。

jcgu的专栏 471
上一篇: G1 与 GC 日志入门课程(以本次离线菜单 Full GC 事故为教材)
下一篇: Java JSON 库选型指南:Fastjson1、Fastjson2 与 Jackson 深度对比与实战
IT_Octopus
博客等级 码龄8年 1725粉丝 302原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IT_Octopus

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值