当前位置: 首页 > news >正文

嵌入式设备的 Json 库基本使用

大家好,今天给介绍一款基于 C 语言的轻量级的 Json 库 – cJson。可用于资源受限的嵌入式设备中。

 

cJSON 是一个超轻巧,携带方便,单文件,简单的可以作为 ANSI-C 标准的 JSON 解析器。

cJSON 是一个开源项目,github 下载地址:

https://github.com/DaveGamble/cJSON

cJSON,目前来说,主要的文件有两个,一个 cJSON.c 一个 cJSON.h。使用的时候,将头文件 include 进去即可。

如果是在 Linux 操作系统中使用,编译 到时候需要添加数学库 libm.so,如下所示:

gcc  *.c  cJSON.c  -lm

1. cJSON 结构体

在 cJSON.h 中定义了一个非常重要的结构体 cJSON,想要熟悉使用 cJSON 库函数可从 cJSON 结构体入手,cJSON 结构体如下所示:

typedef struct cJSON {  struct cJSON *next,*prev;   struct cJSON *child;   int type;   char *valuestring;        // value值是字符串类型int valueint;  double valuedouble;   char *string;             // 对象中的key
} cJSON; 

关于这个结构体做如下几点的说明:

  1. cJOSN 结构体是一个双向链表,并且可通过 child 指针访问下一层。

  2. 结构体成员 type 变量用于描述数据元素的类型(如果是键值对表示 value 值的类型),数据元素可以是字符串可以是整形,也可以是浮点型。

  • 如果是整形值的话可通过 valueint 将值取出

  • 如果是浮点型的话可通过 valuedouble 将值取出

  • 如果是字符串类型的话可通过 valuestring 将值取出

  1. 结构体成员 string 表示键值对中键值的名称。

cJSON 作为 Json 格式的解析库,其主要功能就是构建和解析 Json 格式了,比如要发送数据:用途就是发送端将要发送的数据以 json 形式封装,然后发送,接收端收到此数据后,还是按 json 形式解析,就得到想要的数据了。

2. cJson API

Json 格式的数据无外乎有两种 Json对象和 Json数组,创建的 Json 数据串可能是二者中 的一种,也可能是二者的组合,不管哪一种通过调用相关的 API 函数都可以轻松的做到这一点。

2.1 数据的封装

在 cJSON.h 头文件中可以看到一些函数声明,通过调用这些创建函数就可以将 Json 支持的数据类型封装为 cJSON 结构体类型:

// 空值类型
extern cJSON *cJSON_CreateNull(void);
// 布尔类型
extern cJSON *cJSON_CreateTrue(void);
extern cJSON *cJSON_CreateFalse(void);
extern cJSON *cJSON_CreateBool(int b);
// 数值类型
extern cJSON *cJSON_CreateNumber(double num);
// 字符串类型
extern cJSON *cJSON_CreateString(const char *string);
// json数组(创建空数组)
extern cJSON *cJSON_CreateArray(void);
// json对象(创建空对象)
extern cJSON *cJSON_CreateObject(void);

另外,cJson 库中还给我我们提供了一些更为简便的操作函数,在创建数组的同时还可以进行初始化

// 创建一个Json数组, 元素为整形
extern cJSON *cJSON_CreateIntArray(const int *numbers,int count);
// 创建一个Json数组, 元素为浮点
extern cJSON *cJSON_CreateFloatArray(const float *numbers,int count);
extern cJSON *cJSON_CreateDoubleArray(const double *numbers,int count);
// 创建一个Json数组, 元素为字符串类型
extern cJSON *cJSON_CreateStringArray(const char **strings,int count);

2.2 Json 对象操作

当得到一个 Json 对象之后,就可以往对象中添加键值对了,可以使用 cJSON_AddItemToObject()

extern void cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item);

在 cJSON 库中节点的从属关系是通过树来维护的,每一层节点都是通过链表来维护的,这样就能分析出该函数参数的含义:

  • object:要添加的键值对从属于那个节点

  • string:添加的键值对的键值

  • item:添加的键值对的 value 值(需要先将其封装为 cJSON 类型的结构体)

为了让我的操作更加方便,cJson 库还给我们提供了一些宏函数,方便我们快速的往 Json 对象中添加键值对

#define cJSON_AddNullToObject(object,name)      cJSON_AddItemToObject(object, name, cJSON_CreateNull())
#define cJSON_AddTrueToObject(object,name)      cJSON_AddItemToObject(object, name, cJSON_CreateTrue())
#define cJSON_AddFalseToObject(object,name)     cJSON_AddItemToObject(object, name, cJSON_CreateFalse())
#define cJSON_AddBoolToObject(object,name,b)    cJSON_AddItemToObject(object, name, cJSON_CreateBool(b))
#define cJSON_AddNumberToObject(object,name,n)  cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n))
#define cJSON_AddStringToObject(object,name,s)  cJSON_AddItemToObject(object, name, cJSON_CreateString(s))

我们还可以根据 Json 对象中的键值取出相应的 value 值,API 函数原型如下:

extern cJSON *cJSON_GetObjectItem(cJSON *object,const char *string);

2.3 Json 数组操作

添加数据到 Json 数组中(原始数据需要先转换为 cJSON 结构体类型)

extern void cJSON_AddItemToArray(cJSON *array, cJSON *item);

得到 Json 数组中元素的个数:

extern int cJSON_GetArraySize(cJSON *array);

得到 Json 数组中指定位置的原素,如果返回 NULL 表示取值失败了。

extern cJSON *cJSON_GetArrayItem(cJSON *array,int item);

2.4 序列化

序列化就是将 Json 格式的数据转换为字符串的过程,cJson 库中给我们提供了 3 个转换函数,具体如下:

第一个参数 item 表示 Json 数据块的根节点。

extern char  *cJSON_Print(cJSON *item);
extern char  *cJSON_PrintUnformatted(cJSON *item);
extern char *cJSON_PrintBuffered(cJSON *item,int prebuffer,int fmt);
  • 调用 cJSON_Print() 函数我们可以得到一个带格式的 Json 字符串(有换行,看起来更直观)

  • 调用 cJSON_PrintUnformatted() 函数会得到一个没有格式的 Json 字符串(没有换行,所有的数据都在同一行)。

  • 调用 cJSON_PrintBuffered() 函数使用缓冲策略将 Json 实体转换为字符串,参数 prebuffer 是指定缓冲区的大小,参数 fmt==0 表示未格式化,fmt==1 表示格式化。

我们在编码过程中可以根据自己的实际需求调用相关的操作函数得到对应格式的 Json 字符串。

2.5 Json 字符串的解析

如果我们得到了一个 Json 格式的字符串,想要读出里边的数据,就需要对这个字符串进行解析,处理方式就是将字符串转换为 cJSON 结构体,然后再基于这个结构体读里边的原始数据,转换函数的函数原型如下:

extern cJSON *cJSON_Parse(const char *value);

2.6 内存释放

当我们将数据封装为 cJSON 结构类型的节点之后都会得到一块堆内存,当我们释放某个节点的时候可以调用 cJson 库提供的删除函数 cJSON_Delete(),函数原型如下:

extern void   cJSON_Delete(cJSON *c);

该函数的参数为要释放的节点的地址,在此强调一点:在进行内存地址释放的时候,当前节点以及其子节点都会被删除。

3. Json 数据的封装

3.1 Json 对象操作举例

创建一个对象,并向这个对象里添加字符串和整型键值:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include"cJSON.h"int main()
{cJSON * root;cJSON *arry;root=cJSON_CreateObject();                     // 创建根数据对象cJSON_AddStringToObject(root,"name","luffy");  // 添加键值对cJSON_AddStringToObject(root,"sex","man");     // 添加键值对cJSON_AddNumberToObject(root,"age",19);        // 添加键值对char *out = cJSON_Print(root);   // 将json形式转换成字符串printf("%s\n",out);// 释放内存  cJSON_Delete(root);  free(out);        
}

运行结果

{"name": "luffy","sex": "man","age": 19
}

若干说明:

  • cJSON_CreateObject 函数可创建一个根对象,返回的是一个 cJSON 指针,在这个指针用完了以后,需要手动调用 cJSON_Delete(root) 进行内存回收。

  • 函数 cJSON_Print() 内部封装了 malloc 函数,所以需要使用 free() 函数释放被 out 占用的内存空间。

3.2 Json 数组操作举例

创建一个数组,并向数组添加一个字符串和一个数字

int main(int argc, char **argv)
{cJSON *root;root = cJSON_CreateArray();cJSON_AddItemToArray(root, cJSON_CreateString("Hello world"));cJSON_AddItemToArray(root, cJSON_CreateNumber(10)); // char *s = cJSON_Print(root);char *s = cJSON_PrintUnformatted(root);if(s){printf(" %s \n",s);free(s);}cJSON_Delete(root);return 0;
}

运行结果:

["Hello world",10]

3.3 Json 对象、数组嵌套使用

对象里面包括一个数组,数组里面包括对象,对象里面再添加一个字符串和一个数字

{"person":[{"name":"luffy","age":19}]
}

示例代码:

int main(int argc, char **argv)
{cJSON *root, *body, *list;// josn 对象 rootroot = cJSON_CreateObject();// root 添加键值对 person:json数组AcJSON_AddItemToObject(root,"person", body = cJSON_CreateArray());// json数组A 添加Json对象BcJSON_AddItemToArray(body, list = cJSON_CreateObject());// 在json对象B中添加键值对: "name":"luffy"cJSON_AddStringToObject(list,"name","luffy");// 在json对象B中添加键值对: "age":19cJSON_AddNumberToObject(list,"age",19);// char *s = cJSON_Print(root);char *s = cJSON_PrintUnformatted(root);if(s){printf(" %s \n",s);free(s);}if(root){cJSON_Delete(root); }return 0;
}

运行结果:

{"person":[{"name":"luffy","age":19}]}

4. 解析 Json 字符串

4.1 解析 Json 对象

Json 字符串的解析流程和数据的封装流程相反,假设我们有这样一个 Json 字符串(字符串中的双引号需要通过转义字符将其转译为普通字符):

{\"name\":\"luffy\",\"sex\":\"man\",\"age\":19}

示例代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "cJSON.h"int main()
{cJSON *json, *name, *sex, *age;char* out="{\"name\":\"luffy\",\"sex\":\"man\",\"age\":19}";json = cJSON_Parse(out); //解析成json形式name = cJSON_GetObjectItem(json, "name");  //获取键值内容sex = cJSON_GetObjectItem(json, "sex");age = cJSON_GetObjectItem(json, "age");printf("name:%s,sex:%s,age:%d\n", name->valuestring, sex->valuestring, age->valueint);cJSON_Delete(json);  //释放内存 
}

输出的结果:

name:luffy,sex:man,age:19

如果是在严格的场所,应该先判定每个 item 的 type,然后再考虑去取值

4.2 解析嵌套的 Json 对象

加大一点难度,下面我们解析一个嵌套的 Json 对象,数据如下:

{\"list\":{\"name\":\"luffy\",\"age\":19},\"other\":{\"name\":\"ace\"}}
int main()
{char *s = "{\"list\":{\"name\":\"luffy\",\"age\":19},\"other\":{\"name\":\"ace\"}}";cJSON *root = cJSON_Parse(s);if(!root) {printf("get root faild !\n");return -1;}cJSON *js_list = cJSON_GetObjectItem(root, "list");if(!js_list) {printf("no list!\n");return -1;}printf("list type is %d\n",js_list->type);cJSON *name = cJSON_GetObjectItem(js_list, "name");if(!name) {printf("No name !\n");return -1;}printf("name type is %d\n",name->type);printf("name is %s\n",name->valuestring);cJSON *age = cJSON_GetObjectItem(js_list, "age");if(!age) {printf("no age!\n");return -1;}printf("age type is %d\n", age->type);printf("age is %d\n",age->valueint);cJSON *js_other = cJSON_GetObjectItem(root, "other");if(!js_other) {printf("no list!\n");return -1;}printf("list type is %d\n",js_other->type);cJSON *js_name = cJSON_GetObjectItem(js_other, "name");if(!js_name) {printf("No name !\n");return -1;}printf("name type is %d\n",js_name->type);printf("name is %s\n",js_name->valuestring);if(root){cJSON_Delete(root);}return 0;
}

打印结果:

list type is 6
name type is 4
name is luffy
age type is 3
age is 19
list type is 6
name type is 4
name is ace

4.3 解析 Json 数组

如果我们遇到的 Json 字符串是一个 Json 数组格式,处理方式和 Json 对象差不多,比如我们要解析如下字符串:

{\"names\":[\"luffy\",\"robin\"]}
int main(int argc, char **argv)
{char *s = "{\"names\":[\"luffy\",\"robin\"]}";cJSON *root = cJSON_Parse(s);if(!root) {printf("get root faild !\n");return -1;}cJSON *js_list = cJSON_GetObjectItem(root, "names");if(!js_list){printf("no list!\n");return -1;}int array_size = cJSON_GetArraySize(js_list);printf("array size is %d\n",array_size);for(int i=0; i< array_size; i++) {cJSON *item = cJSON_GetArrayItem(js_list, i);printf("item type is %d\n",item->type);printf("%s\n",item->valuestring);}if(root){cJSON_Delete(root);}return 0;
}

4.4 解析嵌套的 Json 对象和数组

对于 Json 字符串最复杂的个数莫过于 Json 对象和 Json 数组嵌套的形式,下面通过一个例子演示一下应该如何解析,字符串格式如下:

{\"list\":[{\"name\":\"luffy\",\"age\":19},{\"name\":\"sabo\",\"age\":21}]}

在解析的时候,我们只需要按照从属关系,一层层解析即可:

  • 根节点是一个 Json 对象,基于根节点中的 key 值取出对应的 value 值,得到一个 Json 数组

  • 读出 Json 数组的大小,遍历里边的各个元素,每个元素都是一个 Json 对象

  • 将 Json 对象中的键值对根据 key 值取出对应的 value 值

  • 从取出的 Value 值中读出实际类型对应的数值 示例代码如下:

#include "cJSON.h"
#include <stdio.h>
#include <stdlib.h>int main(int argc, char **argv)
{char *s = "{\"list\":[{\"name\":\"luffy\",\"age\":19},{\"name\":\"sabo\",\"age\":21}]}";cJSON *root = cJSON_Parse(s);if(!root) {printf("get root faild !\n");return -1;}cJSON *list = cJSON_GetObjectItem(root, "list");if(!list){printf("no list!\n");return -1;}int array_size = cJSON_GetArraySize(list);printf("array size is %d\n",array_size);for(int i=0; i< array_size; i++) {cJSON* item = cJSON_GetArrayItem(list, i);cJSON* name = cJSON_GetObjectItem(item, "name");printf("name is %s\n",name->valuestring);cJSON* age = cJSON_GetObjectItem(item, "age");printf("age is %d\n",age->valueint);}if(root){cJSON_Delete(root);}return 0;
}

相关文章:

嵌入式设备的 Json 库基本使用

大家好&#xff0c;今天给介绍一款基于 C 语言的轻量级的 Json 库 – cJson。可用于资源受限的嵌入式设备中。 cJSON 是一个超轻巧&#xff0c;携带方便&#xff0c;单文件&#xff0c;简单的可以作为 ANSI-C 标准的 JSON 解析器。 cJSON 是一个开源项目&#xff0c;github 下…...

GEEMAP 中如何拉伸图像

图像拉伸是最基础的图像增强显示处理方法&#xff0c;主要用来改善图像显示的对比度&#xff0c;地物提取流程中往往首先要对图像进行拉伸处理。图像拉伸主要有三种方式&#xff1a;线性拉伸、直方图均衡化拉伸和直方图归一化拉伸。 GEE 中使用 .sldStyle() 的方法来进行图像的…...

软件测试学术顶会——ISSTA 2023 论文(网络安全方向)清单、摘要与总结

总结 本次会议涵盖的安全研究主题广泛,包括源代码分析、二进制代码分析、恶意软件检测、漏洞检测、模糊测试、程序验证等。一些热门的研究方向包括:基于机器学习的漏洞检测、大型语言模型在软件安全中的应用、区块链智能合约安全分析。这些方向都在最近几年持续发展。一些较冷门…...

基于YOLOv8模型和PCB电子线路板缺陷目标检测系统(PyTorch+Pyside6+YOLOv8模型)

摘要&#xff1a;基于YOLOv8模型PCB电子线路板缺陷目标检测系统可用于日常生活中检测与定位PCB线路板瑕疵&#xff0c;利用深度学习算法可实现图片、视频、摄像头等方式的目标检测&#xff0c;另外本系统还支持图片、视频等格式的结果可视化与结果导出。本系统采用YOLOv8目标检…...

centos安装mysql8

检查是否有mariadb rpm -qa|grep mariadb rpm -e --nodeps mariadb-server安装mysql-8.0.31-el7-x86_64.tar.gz包 安装mysql-8.0.31-el7-x86_64.tar.gz包 cd datatar -xvf mysql-8.0.31-el7-x86_64.tar.gzmv mysql-8.0.31-el7-x86_64 mysql 依赖安装 报错解决&#xff0c;安…...

【Apollo】阿波罗自动驾驶技术:引领汽车行业革新

前言 Apollo (阿波罗)是一个开放的、完整的、安全的平台&#xff0c;将帮助汽车行业及自动驾驶领域的合作伙伴结合车辆和硬件系统&#xff0c;快速搭建一套属于自己的自动驾驶系统。 开放能力、共享资源、加速创新、持续共赢是 Apollo 开放平台的口号。百度把自己所拥有的强大、…...

一文看懂!数据管道和数据流在数据分析中的作用

当我们谈论数据分析时&#xff0c;我们通常会想到一系列的步骤&#xff0c;包括数据收集、数据清洗、数据分析和数据可视化等。然而&#xff0c;在这些步骤中&#xff0c;有两个非常重要的概念&#xff1a;数据管道和数据流。这两个概念在数据分析过程中起着至关重要的作用。本…...

Linux系统下检验Tensorflow 2.xx版本和1.xx版本是否安装成功

目录 版本问题Tensorflow 1.xx的测试代码&#xff1a;Tensorflow 2.xx的测试代码&#xff1a;Tensorflow 2.6版本实际的测验结果 总结 版本问题 查询资料发现&#xff0c;多数检验Tensorflow是否安装成功的方法&#xff0c;多数方法都是1.xx版本的&#xff0c;直接使用1.xx版本…...

暑期高铁站大量遗失物品,FindMy帮助寻找

近日&#xff0c;一女子在上海坐高铁时&#xff0c;将户口本、房产证遗落安检处的新闻引起网友的关注。然后业内人士表示&#xff1a;常事&#xff0c;车站什么都能捡到。 据中国铁路透露&#xff0c;暑运期间&#xff0c;上海虹桥站客流增加&#xff0c;日均发送旅客20多万人…...

通过安全日志读取WFP防火墙放行日志

前言 之前的文档中&#xff0c;描写了如何对WFP防火墙进行操作以及如何在防火墙日志中读取被防火墙拦截网络通讯的日志。这边文档&#xff0c;着重描述如何读取操作系统中所有被放行的网络通信行为。 读取系统中放行的网络通信行为日志&#xff0c;在win10之后的操作系统上&am…...

JDK、JRE、Java SE、Java EE和Java ME有什么区别?

Java现在已不仅仅是一种语言&#xff0c;从广义上说&#xff0c;它代表了一个技术体系。该体系根据应用方向的不同主要分为Java SE、Java EE和Java ME的3个部分。 1.SE(JavaSE)&#xff0c;standard edition&#xff0c;标准版&#xff0c;是我们通常用的一个版本&#xff0c;从…...

Neo4j之unwind基础

UNWIND 语句在 Cypher 查询中用于将列表&#xff08;数组&#xff09;中的元素逐个“展开”&#xff0c;从而将每个元素视为单独的行进行处理。它通常与 MATCH、CREATE、MERGE 等语句结合使用&#xff0c;用于对列表中的每个元素执行相应的操作。以下是一些常用的示例和解释&am…...

回归预测 | MATLAB实现SSA-SVM麻雀搜索算法优化支持向量机多输入单输出回归预测(多指标,多图)

回归预测 | MATLAB实现SSA-SVM麻雀搜索算法优化支持向量机多输入单输出回归预测&#xff08;多指标&#xff0c;多图&#xff09; 目录 回归预测 | MATLAB实现SSA-SVM麻雀搜索算法优化支持向量机多输入单输出回归预测&#xff08;多指标&#xff0c;多图&#xff09;效果一览基…...

深入探索代理技术:Socks5、IP代理与网络安全

在当今高度互联的世界中&#xff0c;代理技术在网络安全和爬虫等领域发挥着重要作用。本文将着重介绍Socks5代理、IP代理以及它们在网络安全与爬虫开发中的应用&#xff0c;旨在帮助读者深入理解这些技术&#xff0c;从而更好地应用于实际情境。 1. Socks5代理的特点与用途 S…...

Matlab 频谱图中如何设置频率刻度

Matlab 频谱图中如何设置频率刻度&#xff08;横坐标&#xff09; 1、概述 时域信号经FFT 变换后得到了频谱&#xff0c;在作图时还必须设置正确的频率刻度&#xff0c;这样才能从图中得到正确的结果。下面来介绍如何设置正确的频率刻度。 2、案例分析 有一个余弦信号&#…...

在线转换器有哪些优势?在线Word转PDF操作分享

我们如果想要将两者不同格式文件进行格式转换&#xff0c;就需要下载安装转换器。如果出门带的设备没有安装转换软件客户端&#xff0c;就无法使用&#xff0c;会比较麻烦。现在有了在线转换工具&#xff0c;只需要打开相应的网页就可使用&#xff0c;那么在线Word转PDF的操作是…...

2023国赛数学建模A题思路模型代码汇总 高教社杯

本次比赛我们将会全程更新思路模型及代码&#xff0c;大家查看文末名片获取 之前国赛相关的资料和助攻可以查看 2022数学建模国赛C题思路分析_2022国赛c题matlab_UST数模社_的博客-CSDN博客 2022国赛数学建模A题B题C题D题资料思路汇总 高教社杯_2022国赛c题matlab_UST数模社…...

vue3如何批量设置动态ref

示例如下&#xff1a; <template v-for"item in selectList"><el-select v-model"item.value" :ref"el > setRef(el, item)"><el-optionv-for"v in item.options":key"v.value":label"v.label"…...

Android Studio run app 设置 release 模式

背景 为验证我们的 SDK 集成在客户应用上的质量&#xff0c;需要我们的测试环境尽量的与客户应用保持一致。客户普遍都会打 release 包并混淆&#xff0c;然后进行上线应用&#xff0c;因此我们在测试过程中也需要使用 release 包进行验证。对于 Android Studio 运行项目&…...

【SA8295P 源码分析】41 - SA8295所有镜像位置、拷贝脚本、生成QFIL包

【SA8295P 源码分析】41 - SA8295所有镜像位置、拷贝脚本、生成QFIL包 一、SA8295 各镜像位置二、SA8295 QNX 侧镜像拷贝脚本三、SA8295 Android 侧镜像拷贝脚本四、使用QFIL 下载整包五、Fastboot 下载命令整理系列文章汇总见:《【SA8295P 源码分析】00 - 系列文章链接汇总》…...

【Redis】Redisson分布式锁原理与使用

【Redis】Redisson分布式锁原理与使用 什么是Redisson&#xff1f; Redisson - 是一个高级的分布式协调Redis客服端&#xff0c;能帮助用户在分布式环境中轻松实现一些Java的对象&#xff0c;Redisson、Jedis、Lettuce 是三个不同的操作 Redis 的客户端&#xff0c;Jedis、Le…...

Segment Anything论文阅读笔记

Segment Anything论文阅读笔记 1. Segment Anything论文基本信息2. Segment Anything论文阅读2.1 第一遍阅读 Segment Anything2.2. 第二遍阅读 Segment Anything2.2.1. Segment Anything中相关的图表 1. Segment Anything论文基本信息 论文地址https://arxiv.org/abs/2304.02…...

Python入门教程 | Python 基础语法

标识符 第一个字符必须是字母表中字母或下划线 _ 。标识符的其他的部分由字母、数字和下划线组成。标识符对大小写敏感。 在 Python 3中&#xff0c;可以用中文作为变量名&#xff0c;非 ASCII 标识符也是允许的了。默认情况下&#xff0c;Python 3 源码文件以 UTF-8 编码&am…...

JAMstack架构:快速构建安全、高性能的现代应用

随着Web应用的快速发展&#xff0c;开发者们在寻找更加高效、安全和可维护的应用架构。JAMstack架构应运而生&#xff0c;它通过将前端、后端和部署过程分离&#xff0c;提供了一种现代化的方式来构建Web应用。在本文中&#xff0c;我们将深入探讨JAMstack架构的特点、优势以及…...

Web会话技术

会话:用户打开浏览器&#xff0c;访问web服务器的资源&#xff0c;会话建立&#xff0c;直到有一方断开连接&#xff0c;会话结束。在一次会话中可以包含多次请求和响应 会话跟踪:一种维护浏览器状态的方法&#xff0c;服务器需要识别多次请求是否来自于同一浏览器&#xff0c;…...

hbuilderx打包苹果证书获取步骤

简介&#xff1a; 目前app开发&#xff0c;很多企业都用H5框架来开发&#xff0c;而uniapp又是这些h5框架里面最成熟的&#xff0c;因此hbuilderx就成为了开发者的首选。然而,打包APP是需要证书的&#xff0c;那么这个证书又是如何获得呢&#xff1f; 生成苹果证书相对复杂一些…...

JAVA下载Excel文件之后无法打开,提示损坏

resources 目录下放模板 excel 文件&#xff0c;通过接口下载后&#xff0c;可以正常下载&#xff0c;但打不开。 问题&#xff1a; springboot 项目简单的下载excel 模板功能&#xff0c;模板放在resources/template/目录中 public void downloadItemBatch(HttpServletRespo…...

复合 类型

字符串和切片 切片 切片的作用是允许你引用集合中部分连续的元素序列&#xff0c;而不是引用整个集合。 例如&#xff1a; let s String::from("hello world");let hello &s[0..5]; // 切片 [0,5) 等效于&s[..5] let world &s[6..11]; // 切片…...

Practices11|41. 缺失的第一个正数(数组)、73. 矩阵置零(矩阵)

41. 缺失的第一个正数(数组) 1.题目&#xff1a; 给你一个未排序的整数数组 nums &#xff0c;请你找出其中没有出现的最小的正整数。 请你实现时间复杂度为 O(n) 并且只使用常数级别额外空间的解决方案。 示例 1&#xff1a; 输入&#xff1a;nums [1,2,0] 输出&#xf…...

深入完整的带你了解java对象的比较

目录 元素的比较 1.基本类型的比较 2.对象比较的问题 1.运行结果 2.疑问 3.原因 对象的比较 1.覆写基类的equals 2.基于Comparble接口类的比较 3.基于比较器比较 4.三种方式对比 元素的比较 1.基本类型的比较 在Java 中&#xff0c;基本类型的对象可以直接比较大…...

ubuntu20.04升级GLIBC高版本方法,解决:version `GLIBC_2.34‘ not found

检查版本 strings /lib/x86_64-linux-gnu/libc.so.6 |grep GLIBC_ 1 显示结果 GLIBC_2.2.5 GLIBC_2.2.6 GLIBC_2.3 GLIBC_2.3.2 GLIBC_2.3.3 GLIBC_2.3.4 GLIBC_2.4 GLIBC_2.5 GLIBC_2.6 GLIBC_2.7 GLIBC_2.8 GLIBC_2.9 GLIBC_2.10 GLIBC_2.11 GLIBC_2.12 GLIBC_2.13 GLIBC_2…...

日产将使用东风纯电平台?官方回应:不是日产品牌

据财联社报道&#xff0c;日产中国在对于“日产将使用东风纯电平台”的传闻进行回应时指出&#xff0c;文中提及的平台将会用于日产在华合资企业的自主品牌&#xff0c;而不是日产品牌本身。这一消息进一步确认了之前每经网的报道&#xff0c;称日产将采用东风汽车最新发布的“…...

cdh6.3.2 Flink On Yarn taskmanager任务分配倾斜问题的解决办法

业务场景&#xff1a; Flink On Yarn任务启动 组件版本&#xff1a; CDH&#xff1a;6.3.2 Flink&#xff1a;1.13.2 Hadoop&#xff1a;3.0.0 问题描述&#xff1a; 在使用FLink on Yarn调度过程中&#xff0c;发现taskmanager总是分配在集中的几个节点上&#xff0c;集群…...

改进YOLO系列:3.添加SOCA注意力机制

添加SOCA注意力机制 1. SOCA注意力机制论文2. SOCA注意力机制原理3. SOCA注意力机制的配置3.1common.py配置3.2yolo.py配置3.3yaml文件配置1. SOCA注意力机制论文 暂未找到 2. SOCA注意力机制原理 3. SOCA注意力机制的配置 3.1common.py配置 ./models/common.p…...

SpringBoot整合Mybatis Plus——条件构造器Wrapper

Mybatis Plus为我们提供了如下的一些条件构造器&#xff0c;我们可以利用它们实现查询条件、删除条件、更新条件的构造。 条件构造器 | MyBatis-Plus (baomidou.com) 一、通过maven坐标引入依赖&#xff08;注意版本&#xff01;&#xff01;&#xff09; <dependency>…...

while循环语句

# while循环 # 通过while循环&#xff0c;计算1到100的总和 num 1 sum 0 while num < 100:sum num sumnum 1 print(f"1到100的和为{sum}") #嵌套语句--实现猜1-10数字游戏 import random flagTrue numrandom.randint(1,10) while flag:guess_numint(input(&q…...

【ARM 嵌入式 编译系列 11 -- GCC __attribute__((packed))详细介绍】

文章目录 __attribute__((packed)) 介绍上篇文章:ARM 嵌入式 编译系列 10.3 – GNU elfutils 工具小结 下篇文章:ARM 嵌入式 编译系列 11.1 – GCC attribute((aligned(x)))详细介绍 attribute((packed)) 介绍 __attribute__((packed)) 是 GCC 编译器的一个特性,它可以…...

Pytorch-day06-复杂模型构建-checkpoint

1、PyTorch 复杂模型构建 1、模型截图2、模型部件实现3、模型组装 2、模型定义 2.1、Sequential 1、当模型的前向计算为简单串联各个层的计算时&#xff0c; Sequential 类可以通过更加简单的方式定义模型。2、可以接收一个子模块的有序字典(OrderedDict) 或者一系列子模块…...

windows电脑系统自带的画图工具如何实现自由拼图

1.首先选中你要拼接的第一张图片&#xff0c;右键选着编辑&#xff0c;会自动打开自带的画图工具 然后就是打开第一张图片&#xff0c;如下图所示 接着就是将画布托大&#xff0c;如下图所示。 然后点击选择&#xff0c;选择下面的空白区域&#xff0c;选着区域的范围要比准备拼…...

直线模组的运行注意事项

直线模组是属于高精密的传动元件&#xff0c;大家都知道&#xff0c;安装不当&#xff0c;直线模组就无法显示其高精度的优势&#xff0c;不仅如此&#xff0c;使用不当也会磨损直线模&#xff0c;针对直线模组的使用安全性事宜&#xff0c;我们切记严苛遵照有关的安全操作规程…...

记录每日LeetCode 2236. 判断根结点是否等于子结点之和 Java实现

题目描述&#xff1a; 给你一个 二叉树 的根结点 root&#xff0c;该二叉树由恰好 3 个结点组成&#xff1a;根结点、左子结点和右子结点。 如果根结点值等于两个子结点值之和&#xff0c;返回 true &#xff0c;否则返回 false 。 初始代码&#xff1a; /*** Definition f…...

使用PHP生成MySQL数据字典

一个项目完成之后&#xff0c;按照需求&#xff0c;我需要给这个项目写设计文档&#xff0c;数据库字典。 设计文档到时好说&#xff0c;但是数据库字典可真的是有点吓到我了。 项目开始的比较急&#xff0c;最开始建数据库的时候没有用excel写数据库字典。 这几十张表的数据…...

React(7)

1.React Hooks 使用hooks理由 1. 高阶组件为了复用&#xff0c;导致代码层级复杂 2. 生命周期的复杂 3. 写成functional组件,无状态组件 &#xff0c;因为需要状态&#xff0c;又改成了class,成本高 1.1 useState useState();括号里面处的是初始值&#xff1b;返回的是一个…...

MySQL8.0新特性之用户管理

密码插件,在8.0中替换为了 sha2模式在8.0中不支持grant直接创建用户并授权&#xff0c;必须先建用户后grant授权。 关于密码插件sha2带来的坑&#xff1f; 客户端工具&#xff0c;navicat 、 sqlyog工具不支持&#xff08;无法连接&#xff09;主从复制&#xff0c;MGR &…...

强推9个研究生必备的免费论文下载网站

一、文献党下载器 文献党下载器把庞大的中外文献数据库资源集成在一个平台&#xff0c;就是把大量的中外数据库资源整合在一个站&#xff08;目前文献资源量名列前茅&#xff09;。不论是中文还是外文文献&#xff0c;不论是哪种文献类型&#xff0c;不论是哪个学科领域该网站…...

解读2023年上半年财报:继续押注儿童业务的361°,有着怎样的野心?

“足球热”的风还是吹到了青少年身边&#xff0c;近日&#xff0c;济南历城二中女足问鼎2023世界中学生足球锦标赛女子组冠军&#xff0c;中国球队时隔16年再次获得世界中学生足球锦标赛冠军&#xff0c;点燃了不少足球爱好者的热情。 少儿体育热之下&#xff0c;与之相关的运…...

音视频 ffplay播放控制

选项说明q, ESC退出播放f全屏切换p, SPC暂停m静音切换9, 09减少音量&#xff0c;0增加音量a循环切换音频流v循环切换视频流t循环切换字幕流c循环切换节目w循环切换过滤器或显示模式s逐帧播放left/right向后/向前拖动10秒down/up向后/向前拖动1分钟鼠标右键单击拖动与显示宽度对…...

扁线电机定子转子工艺及自动化装备

售&#xff1a;扁线电机 电驱对标样件 需要请联&#xff1a;shbinzer &#xff08;拆车邦&#xff09; 新能源车电机路线大趋势&#xff0c;自动化装配产线需求迫切永磁同步电机是新能源车驱动电机的主要技术路线。目前新能源车上最广泛应用的类型为永磁同步电机&#xff0c…...

分类预测 | MATLAB实现DRN深度残差网络多输入分类预测

分类预测 | MATLAB实现DRN深度残差网络多输入分类预测 目录 分类预测 | MATLAB实现DRN深度残差网络多输入分类预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 1.分类预测 | MATLAB实现DRN深度残差网络多输入分类预测 2.代码说明&#xff1a;MATLAB实现DRN深度残差网络…...

docker学习(十五)docker安装MongoDB

什么是MongoDB? MongoDB 是一个开源的、面向文档的 NoSQL 数据库管理系统&#xff0c;它以高性能、灵活的数据存储方式而闻名。与传统的关系型数据库不同&#xff0c;MongoDB 采用了一种称为 BSON&#xff08;Binary JSON&#xff09;的二进制 JSON 格式来存储数据。它是一种非…...