在 C# .NET 中驾驭 JSON:使用 Newtonsoft.Json 进行解析与 POST 请求实战
JSON (JavaScript Object Notation) 已经成为现代 Web 应用和服务之间数据交换的通用语言。无论你是开发后端 API、与第三方服务集成,还是处理配置文件,都绕不开 JSON 的解析与生成。在 C# .NET 世界里,处理 JSON 有多种选择,其中 Newtonsoft.Json
(又称 Json.NET)因其强大的功能、灵活性和广泛的应用,至今仍是许多开发者的首选。
本文将深入探讨如何使用 Newtonsoft.Json
在 C# 中解析 JSON 字符串,以及如何利用 HttpClient
结合 Newtonsoft.Json
发送带有 application/json
请求体的 POST 请求。
准备工作:安装 Newtonsoft.Json
首先,确保你的项目中已经安装了 Newtonsoft.Json
NuGet 包。在 Visual Studio 中,可以通过以下步骤安装:
- 右键点击项目,选择 “管理 NuGet 程序包…”。
- 在 “浏览” 标签页搜索 “Newtonsoft.Json”。
- 选择找到的包,点击 “安装”。
或者,在 NuGet 包管理器控制台运行以下命令:
Install-Package Newtonsoft.Json
第一部分:JSON 解析的艺术 - 将 JSON 转化为 C# 对象
处理 JSON 字符串最常见也最安全的方式是将其映射到预先定义的 C# 类或结构体。Newtonsoft.Json
提供了强大的反序列化功能,能够将 JSON 结构自动转化为对应的 C# 对象。
1. 将 JSON 反序列化为强类型对象 (JsonConvert.DeserializeObject<T>
)
这种方法适用于你知道 JSON 的具体结构,并可以为其定义一个匹配的 C# 类。这是推荐的方式,因为它提供了编译时类型检查,减少了运行时错误。
假设我们有以下 JSON 数据,代表一个用户的信息:
{"userName": "Alice","age": 30,"isActive": true,"roles": ["Viewer", "Contributor"],"profile": {"email": "alice@example.com","bio": "Software Engineer"}
}
为了解析它,我们需要定义对应的 C# 类:
using System.Collections.Generic; // 用于 List<string>public class UserProfile
{public string Email { get; set; }public string Bio { get; set; }
}public class User
{// 默认情况下,属性名需要与 JSON key 匹配(大小写敏感)public string UserName { get; set; }public int Age { get; set; }public bool IsActive { get; set; }public List<string> Roles { get; set; } // JSON 数组通常映射到 List<T> 或 T[]public UserProfile Profile { get; set; } // 嵌套对象映射到嵌套类
}
然后,使用 JsonConvert.DeserializeObject<T>
方法进行反序列化:
using System;
using Newtonsoft.Json; // 引入 Newtonsoft.Json 命名空间public class JsonParsingExample
{public static void Main(string[] args){string jsonString = @"{""userName"": ""Alice"",""age"": 30,""isActive"": true,""roles"": [""Viewer"", ""Contributor""],""profile"": {""email"": ""alice@example.com"",""bio"": ""Software Engineer""}}";try{// 反序列化 JSON 字符串到 User 对象User user = JsonConvert.DeserializeObject<User>(jsonString);// 访问反序列化后的对象属性Console.WriteLine($"User Name: {user.UserName}");Console.WriteLine($"Age: {user.Age}");Console.WriteLine($"Is Active: {user.IsActive}");Console.WriteLine($"Roles: {string.Join(", ", user.Roles)}"); // 遍历列表Console.WriteLine($"Email: {user.Profile.Email}"); // 访问嵌套对象属性Console.WriteLine($"Bio: {user.Profile.Bio}");}catch (JsonReaderException ex){// 处理 JSON 格式错误或其他解析异常Console.WriteLine($"JSON 解析错误: {ex.Message}");}catch (Exception ex){// 处理其他潜在异常Console.WriteLine($"发生错误: {ex.Message}");}}
}
处理 JSON 数组:
如果你的 JSON 根是一个数组,例如 [ {"id": 1, "name": "Item A"}, {"id": 2, "name": "Item B"} ]
,你可以反序列化到一个 List<T>
或 T[]
:
using System.Collections.Generic;public class Item
{public int Id { get; set; }public string Name { get; set; }
}string jsonArrayString = @"
[{ ""id"": 1, ""name"": ""Item A"" },{ ""id"": 2, ""name"": ""Item B"" }
]";List<Item> items = JsonConvert.DeserializeObject<List<Item>>(jsonArrayString);
// 现在 items 是一个包含两个 Item 对象的列表
自定义属性名映射 ([JsonProperty]
属性):
如果你的 C# 属性名与 JSON key 不一致(例如,C# 使用 PascalCase,JSON 使用 camelCase 或 snake_case),可以使用 [JsonProperty("json_key_name")]
属性来指定映射关系:
using Newtonsoft.Json;public class Product
{[JsonProperty("product_code")] // JSON 中是 "product_code"public string Code { get; set; } // C# 中是 Code[JsonProperty("itemPrice")] // JSON 中是 "itemPrice"public decimal Price { get; set; } // C# 中是 Price
}
2. 使用 JToken
/JObject
/JArray
进行动态解析
当你面对结构未知、不规范的 JSON,或者只需要访问/修改 JSON 中的一小部分数据时,将整个 JSON 强制映射到强类型对象可能不太方便。这时,Newtonsoft.Json.Linq
命名空间下的 JToken
、JObject
和 JArray
类提供了灵活的动态访问能力。
JToken
: 所有 JSON 元素的基类。JObject
: 代表一个 JSON 对象{}
。JArray
: 代表一个 JSON 数组[]
。JValue
: 代表一个具体的 JSON 值(字符串、数字、布尔、null)。
使用 JObject.Parse()
或 JArray.Parse()
来解析 JSON 字符串到这些动态类型:
using System;
using Newtonsoft.Json.Linq; // 引入 Newtonsoft.Json.Linqpublic class JsonDynamicParsingExample
{public static void Main(string[] args){string dynamicJsonString = @"{""metadata"": {""timestamp"": ""2023-10-27T10:00:00Z"",""version"": 1.5},""results"": [{ ""id"": 10, ""status"": ""success"" },{ ""id"": 20, ""status"": ""failed"", ""errorDetail"": ""Timeout"" }],""settings"": null}";try{// 解析为 JObject (如果 JSON 根是对象)JObject jsonObject = JObject.Parse(dynamicJsonString);// 动态访问属性(使用索引器)// 可以直接强制类型转换,但如果属性不存在或类型不匹配会抛异常string timestamp = (string)jsonObject["metadata"]["timestamp"];double version = (double)jsonObject["metadata"]["version"];Console.WriteLine($"Timestamp: {timestamp}");Console.WriteLine($"Version: {version}");// 访问嵌套数组JArray resultsArray = (JArray)jsonObject["results"];if (resultsArray != null) // 始终检查 JArray 是否为 null{Console.WriteLine("Results:");foreach (JToken resultToken in resultsArray) // 遍历数组中的每个元素 (JObject){int id = resultToken.Value<int>("id"); // 使用 Value<T>(key) 安全获取子属性值string status = resultToken.Value<string>("status");string errorDetail = resultToken.Value<string>("errorDetail"); // 如果属性不存在,Value<string> 会返回 nullConsole.WriteLine($" Id: {id}, Status: {status}, Error Detail: {errorDetail ?? "N/A"}");}}// 访问可能为 null 的属性JToken settingsToken = jsonObject["settings"];Console.WriteLine($"Settings token type: {settingsToken.Type}"); // 输出: NullJToken missingToken = jsonObject["nonexistentKey"];Console.WriteLine($"Missing token: {missingToken}"); // 输出空行 (C# null)// 修改 JSON 结构 (JObject/JArray 支持修改)jsonObject["newStatus"] = "Processed";jsonObject["results"][0]["status"] = "completed"; // 修改第一个结果的状态Console.WriteLine("\nModified JSON:");// 可以将 JObject/JArray 转换为格式化后的 JSON 字符串Console.WriteLine(jsonObject.ToString(Formatting.Indented));}catch (JsonReaderException ex){Console.WriteLine($"JSON Parsing Error: {ex.Message}");}catch (Exception ex){// 捕获强制类型转换失败、访问 null token 的属性等异常Console.WriteLine($"发生错误: {ex.Message}");}}
}
使用 JToken
/JObject
/JArray
进行动态解析非常灵活,但牺牲了编译时类型安全,需要更多的运行时检查来确保数据存在且类型正确。
3. JToken 的“判空”:理解 C# null
与 JSON null
在使用 JToken
系列进行动态访问时,正确判断一个 JToken
是否“空”或“不存在”非常重要,这也是初学者常见的困惑点。
- C#
null
引用: 当你使用索引器(如jsonObject["missing_key"]
)尝试访问一个在 JSON 中 不存在 的属性时,Newtonsoft.Json
会返回 C# 的null
引用。 - JSON
null
值: JSON 本身支持null
值 ("key": null
)。当解析到这样的值时,你会得到一个有效的JToken
对象,它的Type
属性是JTokenType.Null
。
如何判断:
using Newtonsoft.Json.Linq;
using System;string json = @"{ ""name"": ""Test"", ""nullableAge"": null, ""emptyArray"": [], ""emptyObject"": {} }";
JObject obj = JObject.Parse(json);JToken existingToken = obj["name"]; // 代表一个字符串值
JToken nullableToken = obj["nullableAge"]; // 代表 JSON null 值
JToken missingToken = obj["nonexistentKey"]; // 是 C# null 引用
JToken emptyArrayToken = obj["emptyArray"]; // 代表一个空数组
JToken emptyObjectToken = obj["emptyObject"]; // 代表一个空对象// 1. 检查是否是 C# 的 null 引用 (属性不存在)
if (missingToken == null)
{Console.WriteLine("missingToken 是 C# null"); // 输出
}// 2. 检查是否代表 JSON null 值 ("key": null)
if (nullableToken != null && nullableToken.Type == JTokenType.Null)
{Console.WriteLine("nullableToken 代表 JSON null 值"); // 输出
}// 3. 最常见的组合检查:属性不存在 或 属性值为 JSON null
bool IsNullOrMissing(JToken token)
{return token == null || token.Type == JTokenType.Null;
}if (IsNullOrMissing(missingToken)) Console.WriteLine("missingToken is null or JSON null"); // 输出
if (IsNullOrMissing(nullableToken)) Console.WriteLine("nullableToken is null or JSON null"); // 输出
if (!IsNullOrMissing(existingToken)) Console.WriteLine("existingToken 不是 null 或 JSON null"); // 输出// 4. 检查是否是空数组或空对象
if (emptyArrayToken is JArray arr && arr.Count == 0)
{Console.WriteLine("emptyArrayToken 是一个空数组"); // 输出
}if (emptyObjectToken is JObject objToken && objToken.Count == 0)
{Console.WriteLine("emptyObjectToken 是一个空对象"); // 输出
}
理解这几者之间的区别,是高效使用 JToken
的关键。
第二部分:发送 application/json
POST 请求
发送 POST 请求并附带 JSON 数据是与 Web API 交互的基本操作。在 .NET 中,我们通常使用 HttpClient
类来完成 HTTP 请求。结合 Newtonsoft.Json
,我们可以轻松地将 C# 对象序列化为 JSON 并作为请求体发送。
以下是具体步骤:
- 创建要发送数据的 C# 对象:
定义一个类来表示你想要发送的数据结构。
using System.Collections.Generic;public class OrderRequest{public string ProductId { get; set; }public int Quantity { get; set; }public string CustomerName { get; set; }public decimal TotalAmount { get; set; }public List<string> Options { get; set; }}
- 使用
HttpClient
发送 POST 请求:
using System;using System.Net.Http;using System.Text; // For Encodingusing System.Threading.Tasks; // For async/awaitusing System.Collections.Generic; // For List<string>using Newtonsoft.Json; // For JsonConvertpublic class HttpClientPostExample{// 最佳实践: 重用 HttpClient 实例private static readonly HttpClient _httpClient = new HttpClient();public static async Task PostJsonData(string url, OrderRequest orderDetails){try{// 1. 将 C# 对象序列化为 JSON 字符串string jsonPayload = JsonConvert.SerializeObject(orderDetails);Console.WriteLine($"Sending JSON payload: {jsonPayload}");// 2. 创建 StringContent,指定内容、编码和 Content-Type 为 application/jsonvar content = new StringContent(jsonPayload, Encoding.UTF8, "application/json");// 3. 使用 HttpClient 发送 POST 请求HttpResponseMessage response = await _httpClient.PostAsync(url, content);// 4. 检查响应状态码// response.EnsureSuccessStatusCode(); // 如果状态码不是 2xx 会抛异常Console.WriteLine($"Response Status Code: {response.StatusCode}");// 5. 读取响应内容 (如果需要)string responseBody = await response.Content.ReadAsStringAsync();Console.WriteLine($"Response Body: {responseBody}");// 6. 如果响应也是 JSON,可以反序列化// try// {// // 假设响应是一个表示处理结果的 JSON 对象// var responseResult = JsonConvert.DeserializeObject<OrderResponse>(responseBody);// Console.WriteLine($"Order Status: {responseResult.Status}");// }// catch (JsonReaderException jsonEx)// {// Console.WriteLine($"Failed to parse response body as JSON: {jsonEx.Message}");// }}catch (HttpRequestException e){Console.WriteLine($"HTTP Request Error: {e.Message}");// 在 .NET 5+ 可以通过 e.StatusCode 获取具体状态码}catch (Exception ex){Console.WriteLine($"An unexpected error occurred: {ex.Message}");}}// 示例响应类 (如果你的 API 返回 JSON)public class OrderResponse{public string Status { get; set; }public string OrderId { get; set; }}public static async Task Main(string[] args){// 替换成你的实际 POST 请求 URLstring apiUrl = "YOUR_API_ENDPOINT_URL_HERE"; // 例如: "https://httpbin.org/post"// 创建要发送的数据对象var myOrder = new OrderRequest{ProductId = "ABC-123",Quantity = 2,CustomerName = "John Doe",TotalAmount = 150.75m,Options = new List<string> { "Gift Wrap", "Express Shipping" }};Console.WriteLine($"Sending order POST request to {apiUrl}...");// 调用发送方法await PostJsonData(apiUrl, myOrder);Console.WriteLine("Request process finished.");}}// 定义之前创建的 OrderRequest 类public class OrderRequest{public string ProductId { get; set; }public int Quantity { get; set; }public string CustomerName { get; set; }public decimal TotalAmount { get; set; }public List<string> Options { get; set; }}
}
关键点解释:
HttpClient
生命周期: 在示例中使用了静态的_httpClient
实例。这是推荐的做法,避免了创建和销毁过多HttpClient
实例可能导致的 Socket Exhaustion 问题。JsonConvert.SerializeObject(orderDetails)
: 将OrderRequest
对象转换为 JSON 字符串。Newtonsoft.Json
会处理属性名、值类型等。new StringContent(...)
: 创建一个HttpContent
对象,它承载了要发送的数据。我们传入 JSON 字符串,指定编码为Encoding.UTF8
,并设置Content-Type
为"application/json"
。这个 Content-Type 头部是服务器用来识别请求体数据格式的关键。await _httpClient.PostAsync(url, content)
: 发送异步 POST 请求。HttpClient
会将content
作为请求体发送到指定的 URL。- 异步操作 (
async
/await
): HTTP 请求是 I/O 密集型操作,使用异步方式 (async
/await
) 可以避免阻塞调用线程,提高应用程序的响应性和可伸缩性,特别是在处理多个并发请求时。
总结
Newtonsoft.Json
是一个强大而灵活的库,为 C# 开发者提供了完整的 JSON 处理能力。无论是将复杂的 JSON 数据映射到强类型 C# 对象进行安全可靠的访问,还是使用 JToken
系列进行动态探索和操作未知结构的 JSON,它都能胜任。结合 HttpClient
发送 application/json
类型的 POST 请求,是现代 C# 应用与 Web API 交互的基石。
虽然 .NET Core 3.0 以后引入了内置的 System.Text.Json
,它在某些场景下提供更好的性能,并且是微软官方在新的 .NET 版本中推荐的内置 JSON 库。然而,Newtonsoft.Json
凭借其丰富的功能集、成熟稳定性和庞大的现有代码库,在许多项目中仍然是不可或缺的选择。
希望本文能帮助你更好地理解和应用 Newtonsoft.Json
在 C# 中的 JSON 解析和 POST 请求场景!
相关文章:
在 C# .NET 中驾驭 JSON:使用 Newtonsoft.Json 进行解析与 POST 请求实战
JSON (JavaScript Object Notation) 已经成为现代 Web 应用和服务之间数据交换的通用语言。无论你是开发后端 API、与第三方服务集成,还是处理配置文件,都绕不开 JSON 的解析与生成。在 C# .NET 世界里,处理 JSON 有多种选择,其中…...
CentOS7——Docker部署java服务
1、安装Docker 首先要确保系统已安装 Docker,若未安装,可以参考我的另一篇文章现在CentOS7上安装Docker,文章地址如下: CentOS7系统安装Docker教程-CSDN博客 Docker当中要安装必备的软件,比如Java运行必要的JDK&#…...
Python-Part2-集合、字典与推导式
Python-Part2-集合、字典与推导式 1. set集合 ⽆序,去掉重复数据。 set1 {1,2,3,4,5,5,4,3,2,1}print(type(set1))print(set1)set2.add(66666)set2.remove(55)#不能使用下标访问set,所以修改操作一般为remove操作 add操作2.dict 字典 字典ÿ…...
《AI大模型应知应会100篇》第39篇:多模态大模型应用:文本、图像和音频的协同处理
第39篇:多模态大模型应用:文本、图像和音频的协同处理 摘要 随着人工智能技术的发展,多模态大模型(Multimodal Large Models)已经成为AI领域的热点之一。这些模型能够同时处理文本、图像、音频等多种模态数据…...
kvm学习小结
安装相关包 安装虚拟化相关包 apt install qemu-kvm qemu-system libvirt-clients libvirt-daemon-system vlan bridge-utils 安装界面相关包 apt install xinit gdmd 配置机器允许root登录 检查cpu是否支持虚拟化 egrep -o vmx|svm /proc/cpuinfo 执行命令systemctl s…...
k8s基本概念-YAML
YAML介绍 YAML是“YAML Aint a Markup Language” (YAML不是一种置标语言)的递归缩进写,早先YAML的意思其实是:“Yet Another Markup Language”(另一种置标语言) YAML是一个类似XML、JSON的标记性语言。YAML强调以数据为中心,并不是以标识语言为重点。因而YAML本身的定义…...
wps批注线条怎么取消去掉wps批注后有竖线
wps批注线条怎么取消去掉wps批注后有竖线 问题 图片 解决方案 图片 word批注线条取消的方法: 1.打开Word文档,点击需要删除的批注。 2.然后点击工具栏“审阅”选项。 3.接着点击“接受“ 4.接受对文档所做的所有修订(H)...
深度解析算法之分治(归并)
48.排序数组 题目链接 给你一个整数数组 nums,请你将该数组升序排列。 你必须在 不使用任何内置函数 的情况下解决问题,时间复杂度为 O(nlog(n)),并且空间复杂度尽可能小。 示例 1: 输入: nums [5,2,3,1] 输出&am…...
僵尸进程是什么?
僵尸进程(Zombie Process)是指在 Unix/Linux 系统中,一个子进程已经终止,但其父进程尚未对它进行善后处理(即没有读取其退出状态),导致子进程的进程表项仍然保留在系统中。由于这个进程已经结束…...
城市群出行需求的时空分形
城市群出行需求的时空分形 原文:He, Zhengbing. “Spatial-temporal fractal of urban agglomeration travel demand.” Physica A: Statistical Mechanics and its Applications 549 (2020): 124503. 1. Introduction(引言) 城市区域的重…...
LangChain入门(二)安装开发环境
1.安装conda Conda 是一个开源的软件包管理系统和环境管理系统,用于安装多个版本的软件包及其依赖关系,并在它们之间轻松切换。 Anaconda是一个开源的Python发行版本,其包含了conda、python等软件包,numpy、pandas、scipy等科学…...
如何开展有组织的AI素养教育?
一、AI素养的定义与核心内涵 AI素养是智能时代个体适应与创新能力的综合体现,其内涵随着技术发展动态扩展,包含以下核心维度: 知识体系:理解AI基本原理(如算法、数据、算力)、技术边界及发展趋势ÿ…...
InnoDB对LRU算法的优化
标准 LRU 算法的核心思想是:当缓存空间不足时,淘汰掉最近最少使用的数据块(Page)。它通常用一个链表来实现,链表头部是最近访问的 Page,链表尾部是最久未访问的 Page。 然而,在数据库系统中直接…...
云原生--核心组件-容器篇-7-Docker私有镜像仓库--Harbor
1、Harbor的定义与核心作用 定义: Harbor是由VMware开源的企业级容器镜像仓库系统,后捐赠给 CNCF (Cloud Native Computing Foundation)。它基于Docker Registry扩展了企业级功能,用于存储、分发和管理容器镜像(如Docker、OCI标准…...
TypeScript 实用类型深度解析:Partial、Pick、Record 的妙用
需求背景:在后台系统的用户管理模块中,我们常遇到这样的场景:修改用户资料时只需要传部分字段,展示用户列表时要隐藏敏感信息,快速查找用户需要ID索引等等,这些业务需求都可以通过 TypeScript 的实用类型优…...
【Pandas】pandas DataFrame rmod
Pandas2.2 DataFrame Binary operator functions 方法描述DataFrame.add(other)用于执行 DataFrame 与另一个对象(如 DataFrame、Series 或标量)的逐元素加法操作DataFrame.add(other[, axis, level, fill_value])用于执行 DataFrame 与另一个对象&…...
如何搭建spark yarn 模式的集群集群
以下是搭建Spark YARN模式集群的一般步骤: 准备工作 - 确保集群中各节点安装了Java环境,并配置好 JAVA_HOME 环境变量。 - 各节点间能通过SSH免密登录。 - 安装并配置好Hadoop集群,YARN作为Hadoop的资源管理器,Spark YARN模式需要…...
云原生--核心组件-容器篇-6-Docker核心之-镜像仓库(公共仓库,私有仓库,第三方仓库)
1、Docker仓库的定义与核心作用 定义: Docker仓库(Docker Registry)是用于存储、分发和管理Docker镜像的集中式存储库。它类似于代码仓库,但专门用于容器镜像的版本控制和共享。它允许开发人员和IT团队高效地管理、部署和分享容器…...
mysql8.0版本部署+日志清理+rsync备份策略
mysql安装:https://blog.csdn.net/qq_39399966/article/details/120205461 系统:centos7.9 数据库版本:mysql8.0.28 1.卸载旧的mysql,保证环境纯净 rpm -qa | grep mariadb mariadb-5.... rpm -e --nodeps 软件 rpm -e --nodeps mariadb-5.…...
搭建spark yarn 模式的集群集群
一.引言 在大数据处理领域,Apache Spark 是一个强大的分布式计算框架,而 YARN(Yet Another Resource Negotiator)是 Hadoop 的资源管理系统。将 Spark 运行在 YARN 模式下,可以充分利用 YARN 强大的资源管理和调度能力…...
在uni-app中使用Painter生成小程序海报
在uni-app中使用Painter生成小程序海报 安装Painter 从GitHub下载Painter组件:https://github.com/Kujiale-Mobile/Painter 将painter文件夹复制到uni-app项目的components目录下 配置页面 在需要使用海报的页面的pages.json中配置 {"path": "pag…...
Uni-app网络请求AES加密解密实现
Uni-app 网络请求封装与 AES 加密解密实现 下面我将为你提供一个完整的 Uni-app 网络请求封装方案,包含 POST 请求的统一处理、请求参数和响应数据的 AES 加密解密。 1. 创建加密解密工具类 首先创建一个 crypto.js 文件用于处理 AES 加密解密: // u…...
uniapp实现统一添加后端请求Header方法
uniapp把请求写完了,发现需要给接口请求添加头部,每个接口去添加又很麻烦,uniapp可以统一添加,并且还能给某些接口设置不添加头部。 一般用于添加token登录验证信息。 在 main.js 文件中配置。 代码如下: // 在…...
uniapp打包apk如何实现版本更新
我们做的比较简单,在后端设置版本号,并在uniapp的config.js中定义版本号,每次跟后端的进行对比,不一致的话就更新。 一、下载apk 主要代码(下载安装包,并进行安装,一般得手动同意安装…...
【Java开发日记】OpenFeign 的 9 个坑
目录 坑一:用对Http Client 1.1 feign中http client 1.2 ribbon中的Http Client 坑二:全局超时时间 坑三:单服务设置超时时间 坑四:熔断超时时间 4.1 使用feign超时 4.2 使用ribbon超时 4.3 使用自定义Options 坑五&…...
RocketMQ 存储核心:深入解析 CommitLog 设计原理
一、引言 在分布式消息队列系统中,消息存储的可靠性和高吞吐能力是衡量系统优劣的核心指标。Apache RocketMQ 作为一款高性能、高可用的分布式消息中间件,其独特的 CommitLog 存储机制在消息持久化过程中扮演了关键角色。本文将深入剖析 CommitLog 的设…...
【C++ Qt】快速上手 显⽰类控件(Label、LCDNumber、ProcessBar、CalendarWidget)
每日激励:“不设限和自我肯定的心态:I can do all things。 — Stephen Curry” 绪论: 本文围绕Qt中常用的显示类控件展开,重点讲解了 QLabel(文本/图片显示)、QLCDNumber(数字显示࿰…...
Docker和K8s面试题
1.Docker底层依托于linux怎么实现资源隔离的? 基于Namespace的视图隔离:Docker利用Linux命名空间(Namespace)来实现不同容器之间的隔离。每个容器都运行在自己的一组命名空间中、包括PID(进程)、网络、挂载…...
shell--数组、正则表达式RE
1.数组 1.1定义 什么是数组? 数组也是一种变量,常规变量只能保存一个值,数组可以保存多个值 1.2 分类 普通数组:只能用整数作为数组的索引--0 下标 有序数组(普通数组):(index)索引(为整数,从0开始) 关联数组:可以使用字符串作为数组的索引 1.3 普通数组 引用: ec…...
java 使用 POI 为 word 文档自动生成书签
poi 版本:4.1.0 <properties><java.version>1.8</java.version><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><…...
redis+lua+固定窗口实现分布式限流
用key的过期时间替代固定窗口的时间戳 -- KEYS[1]: 限流的key -- ARGV[1]: 限流窗口大小(秒) -- ARGV[2]: 限流阈值local key KEYS[1] local window tonumber(ARGV[1]) local limit tonumber(ARGV[2])-- 尝试获取当前计数 local current redis.call…...
什么是SQL92标准,有什么特点和影响?
一、SQL92简介 SQL92标准是1992年由美国国家标准协会(ANSI)和国际标准化组织(ISO)联合制定的数据库语言标准,正式名称为"SQL:1992"或ISO/IEC 9075:1992。他是关系型数据库管理系统(R…...
Flink Checkpoint 与实时任务高可用保障机制实战
在实时数仓体系中,数据一致性和任务稳定性是核心保障。本文围绕 Flink Checkpoint 机制,深入讲解高可用保障的最佳实践和工程实现。 一、业务背景与痛点 在金融风控、营销实时推荐、智能监控等场景中,实时数仓的每一条数据都至关重要。常见的业务痛点包括: 断点恢复困难:…...
WebRtc08:WebRtc信令服务器实现
如何使用socket.io发送消息 发送消息 // 给本次连接发送消息 socket.emit()// 给某个房间内所有人发送消息 io.in(room).emit()// 除了自己以外,给某个房间的所有人发消息 socket.to(room).emit();// 除本连接外,给所有人发消息 socket.broadcast.emit…...
基于 SpringBoot 与 Redis 的缓存预热案例
文章目录 “缓存预热” 是什么?项目环境搭建创建数据访问层预热数据到 Redis 中创建缓存服务类测试缓存预热 “缓存预热” 是什么? 缓存预热是一种优化策略,在系统启动或者流量高峰来临之前,将一些经常访问的数据提前加载到缓存中…...
Python对比两张CAD图并标记差异的解决方案
以下是使用Python对比两张CAD图并标记差异的解决方案,结合图像处理和CAD结构分析: 一、环境准备与库选择 图像处理库:使用OpenCV进行图像差异检测、颜色空间转换和轮廓分析。CAD解析库:若为DXF格式,使用ezdxf解析实体…...
LINUX427 冒险位 粘滞位 chmod 权限
为什么不同用户能查看的文件夹不同 思索 是因为不同文件夹的权限不同吗?感觉不是 权限不就是只有rwx权限吗? o 对对对 和0GU有关 O 组内的其他用户应该 O是其他用户 不是组内用户 文件创建应该设置了r权限 但是root为什么看到的好像不一样 root 这些…...
10 DPSK原始对话记录
10 DPSK原始对话记录 前言 编程之余,在 Vscode 的 Cline 插件界面中和 ai (dpsk v3-0324) 聊起了天,得到了一个有意思的回答。就像ai有自我意识一样。在此记录。 实际对话内容 时间范围:2025-04-27 23:37:22 - 23:44:17 对话模式:PLAN MODE [23:37:22] 用户提问 “你…...
实现一个瀑布流布局
1、纯CSS实现 实现方式:借助column-count属性来创建 4 列的布局,并使用 column-gap 设置列间距。每个 .img-container 使用 break-inside: avoid 来防止图片被分割。 来看一下完整的代码: <!DOCTYPE html> <html lang"en&qu…...
Linux:进程间通信->共享内存
1. 共享内存的概念 System V共享内存,是一个高效的进程间通信IPC机制,允许多个进程共享同一块物理内存区实现快速的数据交换。如下图所示 这两个进程分别通过页表映射到这一块共享内存中 2. 共享内存的函数 shmget 功能: 创建新的共享内存…...
《Crawl4AI 爬虫工具部署配置全攻略》
《Crawl4AI 爬虫工具部署配置全攻略》 摘要 :在数据驱动的智能时代,高效爬虫工具是获取信息的关键。本文将为你详细解析 Crawl4AI 的安装配置全流程,从基础设置到进阶优化,再到生产环境部署,结合实用技巧与常见问题解…...
spring框架学习(下)
这章节讲的主要是spring在生产Bean对象时的过程 Spring实例化对象的基本流程 1、解析bean.xml 2、封装成BeanDifinition类 3、存放到BeanDIfinitionMap里 4、从BeanDIfinitionMap遍历得到bean 5、将bean存放到SingletonObjects 6、调用getBean方法得到bean 以下是简易的…...
进程与线程-----C语言经典题目(8)
一.什么是进程 定义: 进程指的是程序在操作系统内的一次执行过程。它不只是程序代码,还涵盖了程序运行时的各类资源与状态信息。包括创建、调度、消亡。 进程的状态(ps -aux): 就绪状态:进程已经…...
lstm用电量预测+网页可视化大屏
视频教学: 训练结果: 详细代码: import pandas as pd import numpy as np from sklearn.preprocessing import MinMaxScaler from sklearn.model_selection import train_test_split from tensorflow.keras.models import Sequential from tensorflow.keras.layers impo…...
linux blueZ 第六篇:嵌入式与工业级应用案例——在 Raspberry Pi、Yocto 与 Buildroot 上裁剪 BlueZ 并落地实战
本篇面向嵌入式与工业级应用场景,深入讲解如何在各类 Linux 构建系统(Raspberry Pi OS、Yocto、Buildroot)中裁剪、交叉编译与集成 BlueZ,以及在工业网关、资产追踪与蓝牙 Mesh 等典型方案中的落地实例与注意要点,帮助你打造稳定、可维护、低功耗的嵌入式蓝牙产品。 目录 …...
Dev控件RadioGroup 如何设置一排有N个显示或分为几行
1.5个选项 全部横排显示,则Columns 5 2.5个选项 每行分两个,则有三行,则Columns 2...
AOSP Android14 Launcher3——Launcher的状态介绍LauncherState类
Launcher3中有一个跟Launcher状态相关的类,叫LauncherState LauncherState 是 Launcher3 中定义各种用户界面状态的抽象基类。你可以把它想象成一个状态机,定义了 Launcher 可能处于的不同视觉和交互模式,例如主屏幕、所有应用列表、最近任务…...
Redis 笔记(三)-Redis 基本知识及五大数据类型
一、redis 基本知识 redis 默认有 16个 数据库,config get databases 查看数据库数量 127.0.0.1:6379> config get databases # 查看数据库数量 1) "databases" 2) "16"默认使用的是第 0个 16 个数据库为:DB 0 ~ DB 15&am…...
Linux——线程(2)线程互斥(锁)
知识回顾 在学习本篇内容前,我们需要先回顾一下几个概念。 临界资源:多线程执行流共享的资源就叫做临界资源 临界区:每个线程内部,访问临界资源的代码,就叫做临界区 互斥:任何时刻,互斥保证有…...
深度解析:具身AI机器人领域最全资源指南(含人形机器人,多足机器人,灵巧手等精选资源)
💡 你是否在寻找具身人工智能(Embodied AI)领域的研究资源?是否希望有一个系统性的资源集合来加速你的研究?今天给大家推荐一个重磅项目! 🌟 为什么需要这个项目? 具身人工智能是一…...