VFP JSON处理利器nfJson:纯代码实现、高性能解析与实战应用

news2026/4/29 16:44:41
1. 项目概述nfJson一个为VFP开发者量身定制的JSON利器如果你还在为Visual FoxProVFP里处理JSON数据而头疼比如用那些速度慢、功能不全或者依赖一堆外部库的第三方方案那今天这个项目绝对能让你眼前一亮。nfJson一个由Marco Plaza主导开发并托管在VFPX社区下的纯VFP JSON解析与生成库它用实力证明了即使是在这个“古老”的开发环境中我们依然能拥有高性能、高可靠且极其易用的JSON处理能力。我用了它好几年从对接各种现代API到做数据交换中间件它几乎成了我VFP工具箱里的标配。它的核心卖点非常明确纯VFP代码实现、零外部依赖、执行速度快、API设计直观。这意味着你不需要去折腾什么COM组件、.NET互操作或者担心运行时环境直接把那几个.prg文件扔进你的项目就能立刻获得完整的JSON读写能力。无论是把从Web API抓回来的字符串变成VFP里能直接点号访问的对象还是把你的本地数据表、游标、对象打包成JSON发给前端或其他系统nfJson都提供了近乎“傻瓜式”的操作函数。2. 核心功能模块深度解析与选型思考nfJson的API设计得非常克制和实用主要就围绕“读JSON”和“写JSON”这两个核心场景并衍生出一些针对VFP特有数据结构如游标的便捷方法。这种设计思路很对VFP开发者的胃口——我们需要的是能快速融入现有工作流、解决实际问题的工具而不是一个庞大而复杂的新框架。2.1 核心读写函数nfJsonRead与nfJsonCreate这是nfJson的基石也是你最先会接触到的两个函数。nfJsonRead(cJsonString [, lReviveCollections]) 从字符串到VFP对象这个函数的作用是把一个JSON格式的字符串反序列化成VFP的原生对象通常是Object或Collection。它的内部实现是一个手写的、优化的解析器直接遍历字符串字符比那些用VFP字符串函数如STRTRAN、SUBSTR拼凑出来的解析器要快得多。* 一个典型的API响应解析场景 LOCAL lcJsonResponse, loData lcJsonResponse {status: success, data: {users: [{id: 1, name: 张三}, {id: 2, name: 李四}]}} loData nfJsonRead(lcJsonResponse) ? loData.status 输出success ? loData.data.users[1].name 输出张三 * 你可以像操作普通VFP对象一样访问嵌套数据 FOR EACH loUser IN loData.data.users ? loUser.id, loUser.name ENDFOR这里有个关键参数lReviveCollections。为什么需要它因为JSON标准本身没有“集合”这个概念只有数组和对象。当nfJsonCreate把一个VFP的Collection对象转换成JSON时它采用了一种特殊的数组结构来标记这个数组原本是一个集合。lReviveCollections参数默认为.F.此时解析出来的集合会以这种内部数组形式呈现便于调试。如果你确定这个JSON是由nfJsonCreate生成的且包含集合将其设为.T.nfJsonRead就会多做一个步骤把这个数组“复活”成真正的VFPCollection对象恢复其Add、Remove等方法。实操心得在大多数对接外部系统如微信支付、地图API的场景下lReviveCollections用默认的.F.即可因为外部系统不认识VFP的集合。只有在你自己的VFP应用之间用JSON传递数据并且明确传递了集合对象时才需要设为.T.。nfJsonCreate(oVfp [, lFormattedOutput, lNoNullArrayItems, cRootName, aMembersFlag, tlNoCollectionName, taProperties]) 从VFP对象到字符串这是序列化过程功能强大且参数众多提供了精细的控制能力。lFormattedOutput 是否输出格式化的JSON带缩进和换行。调试时设为.T.生产环境传输时为节省带宽通常设为.F.。tlNoCollectionName 控制集合在JSON中的命名。默认会给集合属性名加上_kv_collection后缀以标识。如果你不希望改变属性名就设为.T.。taProperties 这是一个二维数组用于高级控制。第一列是属性名第二列是逻辑值.T.排除.F.包含。这在你需要精确控制输出哪些字段或者需要调整属性名在JSON中的大小写时非常有用。LOCAL loObj, lcJson loObj CREATEOBJECT(Empty) ADDPROPERTY(loObj, userName, Marco) ADDPROPERTY(loObj, age, 40) ADDPROPERTY(loObj, “isActive“, .T.) ADDPROPERTY(loObj, “lastLogin“, DATETIME()) * 生成紧凑JSON lcJson nfJsonCreate(loObj, .F.) * 结果{userName:Marco,age:40,isActive:true,lastLogin:2023-10-27T14:30:00} * 生成格式化JSON便于阅读 lcJson nfJsonCreate(loObj, .T.) * 结果会带换行和缩进。 * 使用属性数组排除age字段并将userName改为UserName DIMENSION laProps[2,2] laProps[1,1] “age“ laProps[1,2] .T. 排除 laProps[2,1] “userName“ laProps[2,2] .F. 包含但注意这里只是包含要改变输出名需要其他逻辑通常需要配合自定义对象或包装器。此参数主要功能是过滤。 lcJson nfJsonCreate(loObj, .F., , , laProps)2.2 游标与JSON的便捷互转nfCursorToJson与nfJsonToCursor这是nfJson对VFP开发者最友好的功能之一极大简化了表格式数据和JSON的转换。nfCursorToJson家族 这个函数有几个变体最常用的是nfCursorToJson()和nfCursorToJson4vfp()。nfCursorToJson() 将当前工作区的游标转换为一个JSON数组每个记录是一个对象。它有几个参数可以控制输出是对象数组还是值数组是否包含数据结构等。nfCursorToJson4vfp() 这是为nfJsonToCursor“量身定做”的。它生成的JSON包含额外的元信息如字段类型、长度确保用nfJsonToCursor读回来时能完美重建一个结构相同的游标。如果你需要在VFP程序之间通过JSON传递整个数据表包括结构请使用这个组合。nfJsonToCursor(cJson, cCursorName, lForceImportFromArray) 顾名思义将JSON数据读入一个游标。它主要设计用来读取由nfCursorToJson4vfp()生成的JSON。参数lForceImportFromArray如果为.T.会尝试将JSON数组强制导入即使JSON不是标准的结构化格式。* 场景将本地客户表导出为JSON传输后在另一个模块中恢复。 SELECT * FROM customers INTO CURSOR csrTemp lcJsonData nfCursorToJson4vfp() 生成带结构的JSON * ... (通过网络或文件传递 lcJsonData) ... * 在接收端恢复游标 nfJsonToCursor(lcJsonData, “csrRestored“) SELECT csrRestored BROWSE 你会看到和原表一模一样的数据和结构2.3 进阶查询与扁平化工具nfOpenJson这个函数模仿了SQL Server 2016的OPENJSON功能是处理复杂、嵌套JSON并想将其“拍平”到游标里的神器。它允许你使用类似JSONPath的语法$.person.name来指定映射关系。为什么需要它想象一下你从API拿到一个深层嵌套的JSON你只关心其中某几层的数据并且希望直接放到一个二维表里做分析。用nfJsonRead得到对象再循环解析固然可以但代码繁琐。nfOpenJson让你用声明式的方法一次性完成。TEXT TO lcComplexJson NOSHOW [ { “id“: 1, “info“: { “name“: “Alice“, “contact“: {“email“: “aliceexample.com“, “phone“: “123456“} } }, { “id“: 2, “info“: { “name“: “Bob“, “contact“: {“email“: “bobexample.com“, “phone“: “654321“} } } ] ENDTEXT * 定义目标游标结构和JSON路径映射 TEXT TO lcCursorDef NOSHOW - userId I $.id - userName C(20) $.info.name - email C(50) $.info.contact.email - phone C(20) $.info.contact.phone ENDTEXT * 一键“拍平” nfOpenJson(lcComplexJson, ‘array‘, lcCursorDef) BROWSE执行后你会直接得到一个包含userId,userName,email,phone四个字段的游标数据已经整齐地填充好了。这个功能在数据清洗和ETL场景下效率提升巨大。3. 实战应用构建一个API数据同步模块光说不练假把式我们用一个完整的例子把nfJson的几个核心函数串起来用。假设我们需要从一个提供JSON格式的订单API获取数据解析后存入本地VFP表同时把本地处理后的状态更新生成JSON反馈给API。3.1 第一步获取并解析API响应我们使用VFP的WinHttp或XMLHTTP组件这里以WinHttp.WinHttpRequest.5.1为例来获取数据。LOCAL loHttp, lcResponse, loJson, llSuccess loHttp CREATEOBJECT(“WinHttp.WinHttpRequest.5.1“) TRY loHttp.Open(“GET“, “https://api.example.com/orders?statuspending“, .F.) loHttp.Send() lcResponse loHttp.ResponseText * 关键步骤使用nfJsonRead解析 loJson nfJsonRead(lcResponse) * 检查API返回状态假设API返回格式为 {“code“:0, “msg“:“ok“, “data“:{...}} IF loJson.code 0 llSuccess .T. ? “获取到“, ALEN(loJson.data.orders), “条订单数据。“ ELSE llSuccess .F. MESSAGEBOX(“API错误“ loJson.msg) ENDIF CATCH TO loException llSuccess .F. MESSAGEBOX(“网络或解析错误“ loException.Message) ENDTRY3.2 第二步将JSON数据存入本地表假设API返回的loJson.data.orders是一个订单对象的数组。我们需要将其存入本地的orders表。IF llSuccess AND TYPE(“loJson.data.orders[1]“) ‘O‘ LOCAL loOrder, lcSingleJson SELECT 0 * 确保本地表存在这里假设已存在且结构匹配 USE orders ALIAS csrLocal EXCLUSIVE FOR EACH loOrder IN loJson.data.orders SCATTER NAME loOld MEMO BLANK 创建一个空对象用于接收字段 * 手动映射字段这是最稳妥的方式因为JSON键名和表字段名可能不同 loOld.OrderID loOrder.orderId loOld.CustomerName loOrder.customer.name loOld.Amount loOrder.totalAmount loOld.OrderDate CTOT(loOrder.createTime) 假设时间是字符串需转换 loOld.Status “PENDING“ loOld.RawJson nfJsonCreate(loOrder, .F.) 可选保存原始JSON快照 * 插入记录 GATHER NAME loOld MEMO ENDFOR USE MESSAGEBOX(“订单数据已成功导入本地数据库。“) ENDIF注意事项字段映射是集成中最容易出错的地方。务必仔细核对API文档中的字段名、数据类型特别是日期时间格式与你本地表结构的对应关系。建议为每个API接口编写一个专用的映射函数或配置表。3.3 第三步处理数据并生成反馈JSON本地处理完订单后比如审核通过我们需要批量生成一个更新状态的请求JSON发回给API。* 假设我们有一个游标csrToUpdate里面有要更新的订单ID和新状态 SELECT order_id, new_status FROM processed_orders INTO CURSOR csrToUpdate READWRITE SCAN * 为每条记录构建一个更新对象 LOCAL loUpdate loUpdate CREATEOBJECT(“Empty“) ADDPROPERTY(loUpdate, “orderId“, csrToUpdate.order_id) ADDPROPERTY(loUpdate, “status“, csrToUpdate.new_status) ADDPROPERTY(loUpdate, “updateTime“, TTOC(DATETIME(), 3)) 生成ISO8601格式时间 * 将对象转换为JSON字符串并累积或直接发送 REPLACE json_payload WITH nfJsonCreate(loUpdate, .F.) IN csrToUpdate ENDSCAN * 现在csrToUpdate.json_payload 字段里每条记录都是一个JSON对象。 * 如果需要批量提交我们可以构建一个对象数组。 LOCAL laUpdates[RECCOUNT(“csrToUpdate“)], lnI lnI 1 SCAN laUpdates[lnI] nfJsonRead(csrToUpdate.json_payload) 读回成对象便于组成数组 lnI lnI 1 ENDSCAN LOCAL loBatchRequest loBatchRequest CREATEOBJECT(“Empty“) ADDPROPERTY(loBatchRequest, “updates“, laUpdates) lcBatchJson nfJsonCreate(loBatchRequest, .F.) * lcBatchJson 就是类似 {updates:[{orderId:001,...}, {orderId:002,...}]} 的字符串 * 接下来可以用WinHttp的POST方法将lcBatchJson发送给API的批量更新接口通过以上三步我们完成了一个完整的“拉取-处理-反馈”的数据同步闭环nfJson在数据的解析和构建环节起到了核心作用。4. 性能调优与深度避坑指南用了这么多年nfJson也踩过不少坑这里分享一些纯干货的经验能帮你省下大量调试时间。4.1 性能关键点大JSON字符串处理虽然nfJson解析速度很快但一次性处理几MB甚至几十MB的JSON字符串仍可能让VFP感到压力主要是内存和字符串处理。对于非常大的JSON流式处理如果API支持分页务必使用分页参数分批请求和处理。文件缓存如果JSON来自文件且需要多次读取可以先用FILETOSTR()读入但考虑用nfJsonRead解析后将得到的VFP对象序列化SAVE TO为二进制文件.scx或.vcx下次直接RESTORE FROM这比反复解析文本快得多。选择性解析如果JSON很大但你只关心其中一小部分可以考虑先用字符串函数粗略定位到所需片段再用nfJsonRead解析那个片段。但这要求你对JSON结构很熟悉。nfJsonCreate的参数选择lFormattedOutput在生产环境一定要设为.F.。格式化输出的JSON体积可能增加30%-50%严重影响网络传输和磁盘IO性能。谨慎使用taProperties参数进行大量属性过滤。如果对象属性非常多频繁的数组查找可能成为瓶颈。更好的做法是在构建源对象oVfp时就只添加需要的属性。游标转换的优化nfCursorToJson在转换大型游标时是记录循环拼接字符串。如果游标有上万条记录这个过程可能较慢。分批处理对于超大型游标考虑分批次转换和传输。索引与顺序转换前确保游标以最有效的顺序排列避免在转换过程中再进行排序操作。4.2 常见问题与排查技巧下面这个表格是我总结的一些典型问题及解决方法问题现象可能原因排查步骤与解决方案nfJsonRead报错“Invalid JSON”1. JSON字符串格式错误如缺少引号、括号不匹配。2. 字符串中包含未转义的控制字符或特殊字符。3. 从剪贴板或文件读取时引入了不可见字符如BOM头。1. 使用在线的JSON验证工具如 jsonlint.com检查原始字符串。2. 使用STRTRAN(lcJson, CHR(0), “”)等语句过滤控制字符。对于特殊字符确保API端已正确转义\”,\\,\n等。3. 对于文件尝试用FILETOSTR(lcFile, 0)第二个参数为0以二进制模式读取避免编码问题。日期时间字段解析错误或为空1. JSON中的日期字符串格式不符合ISO-8601基本格式YYYY-MM-DDTHH:MM:SS。2. VFP的STRICTDATE设置影响解析。1. 确认API返回的日期格式。如果不是标准格式需要在解析后手动用CTOT()或DATETIME()函数转换。可以在nfJsonRead后遍历对象对疑似日期字段进行转换。2. 在程序开头执行SET STRICTDATE TO 0以获得最宽松的日期解析。但要注意安全风险。nfJsonToCursor导入后字段类型不对或数据丢失1. 使用的JSON不是由nfCursorToJson4vfp()生成缺少元数据。2. 源JSON中的数据类型与VFP字段类型不兼容如超长字符串导入到短字符字段。1.确保配对使用如果要用nfJsonToCursor完美重建源JSON必须来自nfCursorToJson4vfp。2. 对于通用JSON数组更推荐先用nfJsonRead得到对象数组然后手动创建游标并插入数据这样可以完全控制字段类型和长度。中文字符在JSON中显示为乱码1. 编码问题。VFP内部使用ANSI如GBK而现代API通常返回UTF-8编码的JSON。这是VFP处理外部数据的老大难问题。解决方案1.使用支持UTF-8的HTTP组件如WinHttp配合adodb.stream来正确读取UTF-8响应体。2.转换编码获取到UTF-8字符串后用STRCONV(lcUtf8String, 11)代码页65001将其转换为VFP内部使用的ANSI码页字符串再交给nfJsonRead。nfJsonRead本身不处理编码它只处理转换后的字符串。处理包含VFP集合的JSON时出错lReviveCollections参数使用不当。明确数据流-VFP - JSON - 外部系统nfJsonCreate生成外部系统收到的是数组表示。lReviveCollections无关。-外部系统 - JSON - VFP外部系统不认识集合JSON里就是数组。用nfJsonRead(, .F.)。-VFP - JSON - VFP自己存自己读。存的时候用nfJsonCreate读的时候用nfJsonRead(, .T.)来复活集合。性能突然下降1. 循环内频繁调用nfJsonCreate创建小对象。2. 处理的JSON字符串异常庞大。1. 对于批量操作尽量在循环外构建对象数组然后一次性调用nfJsonCreate。2. 参考上文“性能关键点”实施分页、缓存或选择性解析策略。使用项目自带的nfJsonPerfTest.prg在你的机器上测试不同大小JSON的解析时间建立性能基线。4.3 关于版本与兼容性的重要提醒nfJson在VFPX上持续维护不同版本的VFP9尤其是SP2和不同版本的nfJson之间可能会有细微差别。务必注意下载与引用始终从VFPX的GitHub仓库下载最新发布版本以获得所有错误修复和性能改进。测试将nfJson集成到你的主项目之前先用项目自带的测试程序如nfJsonPerfTest.prg、collectionTest.prg跑一遍确保在你的开发环境中一切正常。错误处理务必用TRY...CATCH块包裹关键的nfJsonRead和nfJsonCreate调用因为无效的输入可能导致VFP抛出错误良好的错误处理能提升用户体验和调试效率。5. 超越基础高级技巧与场景应用掌握了基本用法和避坑技巧后我们来看看如何用nfJson玩出一些花样解决更复杂的问题。5.1 动态构建复杂JSON结构有时我们需要构建的JSON结构非常动态无法预先定义好对象。这时可以混合使用VFP的Collection和Empty对象。* 构建一个类似菜单树的复杂JSON结构 LOCAL loMenuRoot, loMenuItem, loSubItem loMenuRoot CREATEOBJECT(“Collection“) * 第一项 loMenuItem CREATEOBJECT(“Empty“) ADDPROPERTY(loMenuItem, “id“, “file“) ADDPROPERTY(loMenuItem, “name“, “文件“) ADDPROPERTY(loMenuItem, “children“, CREATEOBJECT(“Collection“)) loSubItem CREATEOBJECT(“Empty“) ADDPROPERTY(loSubItem, “id“, “new“) ADDPROPERTY(loSubItem, “name“, “新建“) loMenuItem.children.Add(loSubItem) loMenuRoot.Add(loMenuItem) * 第二项 loMenuItem CREATEOBJECT(“Empty“) ADDPROPERTY(loMenuItem, “id“, “edit“) ADDPROPERTY(loMenuItem, “name“, “编辑“) ADDPROPERTY(loMenuItem, “children“, .NULL.) 没有子菜单 loMenuRoot.Add(loMenuItem) lcMenuJson nfJsonCreate(loMenuRoot, .T., , , , .T.) 注意最后一个参数 .T.表示不改变集合属性名 * 生成的JSON就是一个清晰的树形结构数组5.2 与前端框架如Vue、React的数据交互当你的VFP程序需要提供数据给基于Web的前端时nfJson是生成RESTful API响应的理想工具。* 在VFP中创建一个简单的HTTP服务器例如使用West Wind Web Connection框架或纯API类 FUNCTION GetUserList LPARAMETERS tcRequestId LOCAL loResponse, lcJson loResponse CREATEOBJECT(“Empty“) ADDPROPERTY(loResponse, “code“, 0) ADDPROPERTY(loResponse, “message“, “success“) ADDPROPERTY(loResponse, “data“, CREATEOBJECT(“Collection“)) * 模拟从数据库获取数据 SELECT user_id AS id, user_name AS name, email FROM users INTO CURSOR csrUsers SCAN LOCAL loUser loUser CREATEOBJECT(“Empty“) ADDPROPERTY(loUser, “id“, csrUsers.id) ADDPROPERTY(loUser, “name“, csrUsers.name) ADDPERTY(loUser, “email“, csrUsers.email) loResponse.data.Add(loUser) ENDSCAN USE IN csrUsers * 转换为JSON字符串 lcJson nfJsonCreate(loResponse, .F.) * 设置HTTP响应头Content-Type: application/json; charsetutf-8 * ... (具体代码取决于你使用的Web框架) ... RETURN lcJson ENDFUNC前端JavaScript收到这个JSON后可以直接JSON.parse()使用实现了前后端分离的数据交换。5.3 配置文件与状态持久化你可以利用nfJson将程序的复杂配置或运行时状态保存为JSON文件这比传统的.ini文件或DBF表更灵活比XML更简洁。* 保存配置 LOCAL loConfig loConfig CREATEOBJECT(“Empty“) ADDPROPERTY(loConfig, “appName“, “我的VFP应用“) ADDPROPERTY(loConfig, “version“, “1.0.0“) ADDPROPERTY(loConfig, “settings“, CREATEOBJECT(“Empty“)) ADDPROPERTY(loConfig.settings, “theme“, “dark“) ADDPROPERTY(loConfig.settings, “autoSave“, .T.) ADDPROPERTY(loConfig.settings, “recentFiles“, CREATEOBJECT(“Collection“)) loConfig.settings.recentFiles.Add(“C:\work\doc1.dbf“) loConfig.settings.recentFiles.Add(“C:\work\doc2.dbf“) lcConfigJson nfJsonCreate(loConfig, .T.) 格式化保存便于查看 STRTOFILE(lcConfigJson, “config.json“) * 读取配置 IF FILE(“config.json“) lcConfigJson FILETOSTR(“config.json“) loConfig nfJsonRead(lcConfigJson, .T.) 注意复活集合 ? “当前主题“, loConfig.settings.theme ENDIF6. 测试与调试用好项目自带的宝藏很多开发者会忽略项目自带的测试样例但它们其实是学习和解决问题的金矿。nfJson的Tests文件夹里包含了一系列测试程序nfJsonPerfTest.prg这是必须运行的程序。它让你用实际的数据样本或从剪贴板粘贴测试解析性能直观感受nfJson的速度。同时它也是一个验证器如果一段JSON在这里能成功解析那在你的程序里基本也没问题。examples.prg和JsonSamples文件夹这里面包含了各种真实的、复杂的JSON样本如YouTube搜索、天气数据、地图结果。运行这个程序看nfJson如何轻松解析它们能极大增强你的信心也是学习处理复杂JSON结构的绝佳教材。collectionTest.prg如果你需要在VFP中使用集合并通过JSON传递这个程序清晰地展示了nfJsonCreate和nfJsonRead配合lReviveCollections参数的全过程是理解集合序列化的关键。我的习惯是每当遇到奇怪的JSON解析问题首先把出问题的JSON字符串复制到nfJsonPerfTest里跑一下看是否是基础格式错误。然后参考examples.prg里类似结构的处理方式。十有八九问题都能在这里找到线索或直接解决。最后再强调一个我踩过多次的坑编码问题永远是第一嫌疑犯。当看到中文字符变成问号或乱码时不要怀疑nfJson先去检查你的HTTP请求/响应、文件读写环节的编码转换是否正确。确保交给nfJsonRead的字符串是VFP能正确识别的ANSI字符串对于中文环境通常是GBK。一旦字符串本身编码正确nfJson就能稳定可靠地工作。这个库虽然小巧但它在VFP的生态里实实在在地解决了一个大问题让VFP这个经典的工具在现代数据交换的舞台上依然能够从容不迫。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2561624.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…