C++ Qt开发:运用QJSON模块解析数据
Qt 是一个跨平台C++图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍如何运用QJson组件的实现对JSON文本的灵活解析功能。
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,它易于人阅读和编写,也易于机器解析和生成。该格式是基于JavaScript语言的一个子集,但它是一种独立于语言的数据格式,因此可以在许多不同的编程语言中使用。
该数据是以键值对的形式组织的,其中键是字符串,值可以是字符串、数字、布尔值、数组、对象(即嵌套的键值对集合)或null,在Qt中默认提供了QJson系列类库,使用该类库可以很方便的解析和处理JSON文档。
1.1 解析单一键值对
实现解析根中的单一键值对,例如解析config.json配置文件中的blog,enable,status等这些独立的字段值,在解析之前需要先通过QJsonDocument::fromJson将内存中的字符串格式化为QJsonDocument类型,当有着该类型之后,则我们可以使用*.object()将其转换为对应的QJsonObject对象,在对象中我们可以调用各种方法对内存中的JSON数据进行处理。
以下是关于 QJsonDocument 类的一些常用方法的说明:
| 方法 | 说明 |
|---|---|
QJsonDocument() |
构造函数,创建一个空的 JSON 文档。 |
QJsonDocument(const QJsonObject &object) |
通过给定的 JSON 对象构造 JSON 文档。 |
QJsonDocument(const QJsonArray &array) |
通过给定的 JSON 数组构造 JSON 文档。 |
QJsonDocument(const QJsonValue &value) |
通过给定的 JSON 值构造 JSON 文档。 |
QJsonDocument(const QJsonDocument &other) |
复制构造函数。 |
QJsonDocument &operator=(const QJsonDocument &other) |
赋值运算符。 |
bool isNull() const |
检查文档是否为空。 |
bool isEmpty() const |
检查文档是否为空,包括 JSON 数组或对象为空的情况。 |
QJsonObject object() const |
返回文档中的 JSON 对象。 |
QJsonArray array() const |
返回文档中的 JSON 数组。 |
QJsonValue value() const |
返回文档中的 JSON 值。 |
bool isArray() const |
检查文档是否包含 JSON 数组。 |
bool isObject() const |
检查文档是否包含 JSON 对象。 |
QByteArray toBinaryData() const |
将文档转换为二进制数据。 |
bool fromBinaryData(const QByteArray &data) |
从二进制数据恢复文档。 |
QString toJson(QJsonDocument::JsonFormat format = QJsonDocument::Compact) const |
返回 JSON 字符串表示,可以选择格式化的方式。 |
static QJsonDocument fromJson(const QString &json, QJsonParseError *error = nullptr) |
从 JSON 字符串创建文档。 |
以下是关于 QJsonObject 类的一些常用方法的说明:
| 方法 | 说明 |
|---|---|
QJsonObject() |
构造函数,创建一个空的 JSON 对象。 |
QJsonObject(const QJsonObject &other) |
复制构造函数。 |
QJsonObject &operator=(const QJsonObject &other) |
赋值运算符。 |
bool isEmpty() const |
检查对象是否为空。 |
int size() const |
返回对象中键值对的数量。 |
bool contains(const QString &key) const |
检查对象中是否包含指定的键。 |
QStringList keys() const |
返回对象中所有键的列表。 |
QJsonValue value(const QString &key) const |
返回与指定键关联的值。 |
void insert(const QString &key, const QJsonValue &value) |
向对象中插入键值对。 |
QJsonObject &unite(const QJsonObject &other) |
将另一个对象的键值对合并到当前对象。 |
void remove(const QString &key) |
从对象中移除指定键及其关联的值。 |
QJsonValue take(const QString &key) |
移除并返回与指定键关联的值。 |
void clear() |
移除对象中的所有键值对,使其变为空对象。 |
QJsonDocument toDocument() const |
将对象转换为 JSON 文档。 |
当需要读取参数时只需要使用find()方法查询特定字段中的key值即可,按钮on_pushButton_clicked被点击后执行如下流程;
void MainWindow::on_pushButton_clicked()
{
// 字符串格式化为JSON
QJsonParseError err_rpt;
QJsonDocument root_document = QJsonDocument::fromJson(config.toUtf8(), &err_rpt);
if(err_rpt.error != QJsonParseError::NoError)
{
QMessageBox::information(nullptr,"提示","JSON格式错误",QMessageBox::Ok);
}
// 获取到Json字符串的根节点
QJsonObject root_object = root_document.object();
// 解析blog字段
QString blog = root_object.find("blog").value().toString();
//std::cout << "字段对应的值 = > "<< blog.toStdString() << std::endl;
ui->lineEdit_blog->setText(blog);
// 解析enable字段
bool enable = root_object.find("enable").value().toBool();
//std::cout << "是否开启状态: " << enable << std::endl;
ui->lineEdit_enable->setText(QString::number(enable));
// 解析status字段
int status = root_object.find("status").value().toInt();
//std::cout << "状态数值: " << status << std::endl;
ui->lineEdit_status->setText(QString::number(status));
}
运行后点击读取数据按钮,输出效果如下;

1.2 解析单数组键值
实现解析简单的单一对象与单一数组结构,如配置文件中的GetDict与GetList既是我们需要解析的内容,在解析时我们需要通过toVariantMap将字符串转换为对应的Map容器,当数据被转换后则就可以通过Map[]的方式很容易的将其提取出来。
void MainWindow::on_pushButton_2_clicked()
{
// 字符串格式化为JSON
QJsonParseError err_rpt;
QJsonDocument root_document = QJsonDocument::fromJson(config.toUtf8(), &err_rpt);
if(err_rpt.error != QJsonParseError::NoError)
{
QMessageBox::information(nullptr,"提示","JSON格式错误",QMessageBox::Ok);
}
// 获取到Json字符串的根节点
QJsonObject root_object = root_document.object();
// 解析单一对象
QJsonObject get_dict_ptr = root_object.find("GetDict").value().toObject();
QVariantMap map = get_dict_ptr.toVariantMap();
if(map.contains("address") && map.contains("username") && map.contains("password") && map.contains("update"))
{
QString address = map["address"].toString();
QString username = map["username"].toString();
QString password = map["password"].toString();
QString update = map["update"].toString();
std::cout
<< " 地址: " << address.toStdString()
<< " 用户名: " << username.toStdString()
<< " 密码: " << password.toStdString()
<< " 更新日期: " << update.toStdString()
<< std::endl;
ui->listWidget->addItem(address);
ui->listWidget->addItem(username);
ui->listWidget->addItem(password);
ui->listWidget->addItem(update);
}
// 解析单一数组
QJsonArray get_list_ptr = root_object.find("GetList").value().toArray();
for(int index=0; index < get_list_ptr.count(); index++)
{
int ref_value = get_list_ptr.at(index).toInt();
std::cout << "输出数组元素: " << ref_value << std::endl;
ui->listWidget_2->addItem(QString::number(ref_value));
}
}
运行后点击解析数据按钮,输出效果如下;

1.3 解析多数组键值
实现解析字典嵌套字典或字典嵌套数组的结构,如配置文件中的ObjectInArrayJson则是一个字典中嵌套了另外两个字典而每个字典中的值又是一个Value数组,而与之相对应的ArrayJson则是在列表中嵌套了另外一个列表,这两中结构的使用读者可参照如下案例;
首先我们来看ObjectInArrayJson是如何被解析的,我们分别准备两个ComboBox选择框,当读者点击按钮时我们通过toVariantMap将字典转换为一个MAP容器,并通过toJsonArray转换内部的列表到JsonArray容器内,其初始化部分如下所示;
void MainWindow::on_pushButton_3_clicked()
{
// 字符串格式化为JSON
QJsonParseError err_rpt;
QJsonDocument root_document = QJsonDocument::fromJson(config.toUtf8(), &err_rpt);
if(err_rpt.error != QJsonParseError::NoError)
{
QMessageBox::information(nullptr,"提示","JSON格式错误",QMessageBox::Ok);
}
// 获取到Json字符串的根节点
QJsonObject root_object = root_document.object();
// 找到Object对象
QJsonObject one_object_json = root_object.find("ObjectInArrayJson").value().toObject();
// 转为MAP映射
QVariantMap map = one_object_json.toVariantMap();
// 寻找One键
QJsonArray array_one = map["One"].toJsonArray();
for(int index=0; index < array_one.count(); index++)
{
QString value = array_one.at(index).toString();
std::cout << "One => "<< value.toStdString() << std::endl;
ui->comboBox->addItem(value);
}
// 寻找Two键
QJsonArray array_two = map["Two"].toJsonArray();
for(int index=0; index < array_two.count(); index++)
{
QString value = array_two.at(index).toString();
std::cout << "Two => "<< value.toStdString() << std::endl;
ui->comboBox_2->addItem(value);
}
}
同理,要实现解析数组中的数组也可以通过该方式实现,如配置文件中的ArrayJson既是我们需要解析的内容,首先我们通过isArray判断该节点是否为数组,如果是则通过toArray().at方法以此得到不同下标元素参数,并依次循环即可,其代码如下所示;
void MainWindow::on_pushButton_4_clicked()
{
// 字符串格式化为JSON
QJsonParseError err_rpt;
QJsonDocument root_document = QJsonDocument::fromJson(config.toUtf8(), &err_rpt);
if(err_rpt.error != QJsonParseError::NoError)
{
QMessageBox::information(nullptr,"提示","JSON格式错误",QMessageBox::Ok);
}
// 获取到Json字符串的根节点
QJsonObject root_object = root_document.object();
// 获取MyJson数组
QJsonValue array_value = root_object.value("ArrayJson");
// 验证节点是否为数组
if(array_value.isArray())
{
// 得到数组个数
int array_count = array_value.toArray().count();
// 循环数组个数
for(int index=0;index <= array_count;index++)
{
QJsonValue parset = array_value.toArray().at((index));
if(parset.isArray())
{
QString address = parset.toArray().at(0).toString();
QString username = parset.toArray().at(1).toString();
QString userport = parset.toArray().at(2).toString();
std::cout
<< "地址: " << address.toStdString()
<< "用户名: " << username.toStdString()
<< "端口号: " << userport.toStdString()
<< std::endl;
ui->comboBox_3->addItem(address);
ui->comboBox_4->addItem(username);
ui->comboBox_5->addItem(userport);
}
}
}
}
运行后点击两个初始化按钮则可以将字典或列表中的数据依次解析到不同的ComBobox列表框内,输出效果如下;

1.4 解析多字典键值
实现解析字典中嵌套多个参数或字典中嵌套参数中包含列表的数据集,如配置文件中的ObjectJson则是字典中存在多个键值对,而ObjectArrayJson则更进一步在多键值对中增加了列表的支持,解析此类内容只需要依次逐级拆分即可,我们来看下如何实现对这些键值的灵活提取;
首先我们来实现对ObjectJson的参数解析功能,读者可自行对比与之前1.3中的区别,可以发现这两者的差别其实不大,解析ObjectJson完整代码如下所示;
void MainWindow::on_pushButton_5_clicked()
{
// 字符串格式化为JSON
QJsonParseError err_rpt;
QJsonDocument root_document = QJsonDocument::fromJson(config.toUtf8(), &err_rpt);
if(err_rpt.error != QJsonParseError::NoError)
{
QMessageBox::information(nullptr,"提示","JSON格式错误",QMessageBox::Ok);
}
// 获取到Json字符串的根节点
QJsonObject root_object = root_document.object();
// 获取MyJson数组
QJsonValue object_value = root_object.value("ObjectJson");
// 验证是否为数组
if(object_value.isArray())
{
// 获取对象个数
int object_count = object_value.toArray().count();
// 循环个数
for(int index=0;index <= object_count;index++)
{
QJsonObject obj = object_value.toArray().at(index).toObject();
// 验证数组不为空
if(!obj.isEmpty())
{
QString address = obj.value("address").toString();
QString username = obj.value("username").toString();
std::cout << "地址: " << address.toStdString() << " 用户: " << username.toStdString() << std::endl;
ui->comboBox_6->addItem(address);
ui->comboBox_7->addItem(username);
}
}
}
}
接着我们来实现一个更为复杂的需求,解析多字典中嵌套的数组,如配置文件中的ObjectArrayJson则是我们需要解析的内容,在之前解析字典部分保持与上述案例一致,唯一不同的是我们需要通过value("ulist").toArray()获取到对应字典中的数组,并通过循环的方式输出。
如下案例中,当读者点击初始化按钮时我们首先让字典中的数据填充之ComboBox列表框中,接着当读者点击第一个列表框时我们让其过滤出特定的内容并赋值到第二个列表框中,以此实现联动效果,首先初始化部分如下所示;
void MainWindow::on_pushButton_6_clicked()
{
// 字符串格式化为JSON
QJsonParseError err_rpt;
QJsonDocument root_document = QJsonDocument::fromJson(config.toUtf8(), &err_rpt);
if(err_rpt.error != QJsonParseError::NoError)
{
QMessageBox::information(nullptr,"提示","JSON格式错误",QMessageBox::Ok);
}
// 获取到Json字符串的根节点
QJsonObject root_object = root_document.object();
// 获取MyJson数组
QJsonValue object_value = root_object.value("ObjectArrayJson");
// 验证是否为数组
if(object_value.isArray())
{
// 获取对象个数
int object_count = object_value.toArray().count();
// 循环个数
for(int index=0;index <= object_count;index++)
{
QJsonObject obj = object_value.toArray().at(index).toObject();
// 验证数组不为空
if(!obj.isEmpty())
{
QString uname = obj.value("uname").toString();
std::cout << "用户名: " << uname.toStdString() << std::endl;
ui->comboBox_8->addItem(uname);
// 解析该用户的数组
int array_count = obj.value("ulist").toArray().count();
std::cout << "数组个数: "<< array_count << std::endl;
for(int index=0;index < array_count;index++)
{
QJsonValue parset = obj.value("ulist").toArray().at(index);
int val = parset.toInt();
std::cout << "Value = > "<< val << std::endl;
ui->comboBox_9->addItem(QString::number(val));
}
}
}
}
}
当第一个选择框被选中时我们触发currentIndexChanged信号,在其中只需要判断uname.compare(arg1)是否相等如果相等则addItem追加到新的列表内,运行效果如下所示,详细实现可参考附件。

1.5 解析多字典嵌套
实现解析多个字典嵌套或多个列表嵌套的结构,如配置文件中的NestingObjectJson则是字典中嵌套字典,而ArrayNestingArrayJson则是列表中嵌套列表,两种的解析方式基本一致。
我们首先来实现第一种格式的解析,当按钮被点击后,我们首先查询uuid字段并赋值到ComBobox列表中,实现代码如下所示;
void MainWindow::on_pushButton_7_clicked()
{
// 字符串格式化为JSON
QJsonParseError err_rpt;
QJsonDocument root_document = QJsonDocument::fromJson(config.toUtf8(), &err_rpt);
if(err_rpt.error != QJsonParseError::NoError)
{
QMessageBox::information(nullptr,"提示","JSON格式错误",QMessageBox::Ok);
}
// 获取到Json字符串的根节点
QJsonObject root_object = root_document.object();
// 获取NestingObjectJson数组
QJsonValue array_value = root_object.value("NestingObjectJson");
// 验证节点是否为数组
if(array_value.isArray())
{
// 得到内部对象个数
int count = array_value.toArray().count();
std::cout << "对象个数: " << count << std::endl;
for(int index=0; index < count; index++)
{
// 得到数组中的index下标中的对象
QJsonObject array_object = array_value.toArray().at(index).toObject();
QString uuid = array_object.value("uuid").toString();
// 追加数据
std::cout << uuid.toStdString() << std::endl;
ui->comboBox_10->addItem(uuid);
// 开始解析basic中的数据
QJsonObject basic = array_object.value("basic").toObject();
QString lat = basic.value("lat").toString();
QString lon = basic.value("lon").toString();
std::cout << "解析basic中的lat字段: " << lat.toStdString() << std::endl;
std::cout << "解析basic中的lon字段: " << lon.toStdString()<< std::endl;
// 解析单独字段
QString status = array_object.value("status").toString();
std::cout << "解析字段状态: " << status.toStdString() << std::endl;
}
}
}
当ComBobox组件中的currentIndexChanged信号被触发时,则直接执行对LineEdit编辑框的赋值操作,其代码如下所示;
void MainWindow::on_comboBox_10_currentIndexChanged(const QString &arg1)
{
// 字符串格式化为JSON
QJsonParseError err_rpt;
QJsonDocument root_document = QJsonDocument::fromJson(config.toUtf8(), &err_rpt);
if(err_rpt.error != QJsonParseError::NoError)
{
QMessageBox::information(nullptr,"提示","JSON格式错误",QMessageBox::Ok);
}
// 获取到Json字符串的根节点
QJsonObject root_object = root_document.object();
// 获取NestingObjectJson数组
QJsonValue array_value = root_object.value("NestingObjectJson");
// 验证节点是否为数组
if(array_value.isArray())
{
// 得到内部对象个数
int count = array_value.toArray().count();
std::cout << "对象个数: " << count << std::endl;
for(int index=0; index < count; index++)
{
// 得到数组中的index下标中的对象
QJsonObject array_object = array_value.toArray().at(index).toObject();
QString uuid = array_object.value("uuid").toString();
// 对比是否相等
if(uuid.compare(arg1) == 0)
{
// 开始解析basic中的数据
QJsonObject basic = array_object.value("basic").toObject();
QString lat = basic.value("lat").toString();
QString lon = basic.value("lon").toString();
std::cout << "解析basic中的lat字段: " << lat.toStdString() << std::endl;
std::cout << "解析basic中的lon字段: " << lon.toStdString()<< std::endl;
ui->lineEdit->setText(lat);
ui->lineEdit_2->setText(lon);
// 解析单独字段
QString status = array_object.value("status").toString();
std::cout << "解析字段状态: " << status.toStdString() << std::endl;
}
}
}
}
同理,我们也可以实现字典中嵌套列表结构,如配置文件中的ArrayNestingArrayJson既我们需要解析的内容,解析实现方法与上述代码保持一致,首先当按钮被点击后我们直接对ComBobox组件进行初始化,代码如下所示;
void MainWindow::on_pushButton_8_clicked()
{
// 字符串格式化为JSON
QJsonParseError err_rpt;
QJsonDocument root_document = QJsonDocument::fromJson(config.toUtf8(), &err_rpt);
if(err_rpt.error != QJsonParseError::NoError)
{
std::cout << "json 格式错误" << std::endl;
}
// 获取到Json字符串的根节点
QJsonObject root_object = root_document.object();
// 获取NestingObjectJson数组
QJsonValue array_value = root_object.value("ArrayNestingArrayJson");
// 验证节点是否为数组
if(array_value.isArray())
{
// 得到数组中的0号下标中的对象
QJsonObject array_object = array_value.toArray().at(0).toObject();
// 解析手机号字符串
QString telephone = array_object.value("telephone").toString();
std::cout << "手机号: " << telephone.toStdString() << std::endl;
ui->comboBox_11->addItem(telephone);
// 定位外层数组
QJsonArray root_array = array_object.find("path").value().toArray();
std::cout << "外层循环计数: " << root_array.count() << std::endl;
for(int index=0; index < root_array.count(); index++)
{
// 定位内层数组
QJsonArray sub_array = root_array.at(index).toArray();
std::cout << "内层循环计数: "<< sub_array.count() << std::endl;
for(int sub_count=0; sub_count < sub_array.count(); sub_count++)
{
// 每次取出最里层数组元素
float var = sub_array.toVariantList().at(sub_count).toFloat();
std::cout << "输出元素: " << var << std::endl;
// std::cout << sub_array.toVariantList().at(0).toFloat() << std::endl;
ui->listWidget_3->addItem(QString::number(var));
}
}
}
}
运行效果如下图所示;

C++ Qt开发:运用QJSON模块解析数据的更多相关文章
- 一起来开发Android的天气软件(四)——使用Gson解析数据
离上一篇文章过去才4.5天,我们赶紧趁热打铁继续完毕该系列的天气软件的开发. 承接上一章的内容使用Volley实现网络的通信.返回给我们的是这一串Json数据{"weatherinfo&qu ...
- Android商城开发系列(六)——使用 OkHttpUtils 请求网络 + 使用 fastjson解析数据
OkHttp是Google推荐使用的一个开源的网络请求框架,Android开发中涉及到网络请求和接口调用现在大部分都是使用OkHttp,网上已经有不少人针对OkHttp进行了封装,这里推荐一下鸿洋大神 ...
- 一步一步开发sniffer(Winpcap+MFC)(五)莫道无人能识君,其实我懂你的心——解析数据包(转)
前文已经讲过,解析数据包主要通过analyze_frame()这个函数实现的,实际上并非这个函数完成了所有的功能,其实从名字就可以看出,它只是完成了对“帧”的解析,也就是链路层数据的解析,还有anal ...
- Qt开发北斗定位系统融合百度地图API及Qt程序打包发布
Qt开发北斗定位系统融合百度地图API及Qt程序打包发布 1.上位机介绍 最近有个接了一个小型项目,内容很简单,就是解析北斗GPS的串口数据然后输出经纬度,但接过来觉得太简单,就发挥了主观能动性,增加 ...
- QT json字符串生成和解析
1 QT json字符串生成和解析 1.1 QT Json解析流程 (1) 字符串转化为QJsonDocument QJsonParseError json_error; QJso ...
- 【应用笔记】【AN005】Qt开发环境下基于RS485的4-20mA电流采集
简介 4-20mA电流环具有广泛的应用前景,在许多行业中都发挥着重要作用.本文主要介绍在Qt开发环境下基于RS485实现4-20mA电流采集,实现WINDOWS平台对数据的采集.分析及显示. 系统组成 ...
- QT开发之旅三串口设备调试工具
这里首先说明一下,这个为什么叫串口设备调试工具而不是串口调试工具,是因为这个工具比网络上的串口调试工具多出了一些真实需要的用来调试设备的功能,首先一点就是大部分的串口调试工具收到数据都是立即返回,这样 ...
- [转]使用QT开发GoogleMap瓦片显示和下载工具
第一节 之前做项目的时候经常遇到需要大量地图背景数据,然后没有数据被逼着去Google上下载瓦片数据在拼接成整张影像的工作,其实遥感影像晚上有很多可以下载到的,但是大部分是作为研究用的,作为GIS的背 ...
- windows下VisualStudio和QtCreator搭建Qt开发环境
一.简介 集成开发平台IDE都有各自的长处,编写Qt程序可根据自己的喜好来选择相应的IDE.下述文章都是装载博友的文章,其中有很多细节还得自己调整. 二.详解 1.VisualStudio搭建Qt开发 ...
- 基于arm的嵌入式QT开发(课程设计)
一. 项目要求 配置QT5.7基于x86及arm 等两种CPU架构的调试及开发环境: 移植arm编译后的QT5.7及屏幕校准工具tslib1.4至CORTEX ARM9实验平台: 开发基于QT5.7的 ...
随机推荐
- 线上活动 | AI 头像变装秀
宝子们,你的头像多久没换了? 送你一个锦囊,让你拥有既独一无二,又千变万化的专属 AI 头像 Hugging Face 将在 7 月 5 日 发起:AI 头像变装秀 ️️️游戏规则️️️ 我们将分享 ...
- BBS项目(二):首页导航条搭建 修改密码功能 首页数据展示 个人站点页面
目录 首页导航条搭建 session判断用户是否登录 更换验证码 导航条更多功能 退出系统 修改密码前端页面 使用大模态框 编写模态框 前端表单编写 修改密码后端逻辑 接受参数 验证参数 修改密码 首 ...
- Multisim 14 免费破解版,下载安装教程,2023年亲测可用,永久激活
Multisim是一款功能强大.操作流畅的专业仿真工具,适用于板级模拟/数字电路板设计工作,提供电路原理图图形输入.电路硬件描述语言输入,具有丰富的仿真分析能力.拥有专业版和教学版,深受国内外教师.科 ...
- [译]为什么你应该关注 Docker
注:该文原文为 Why You Should Care About Docker ,由 CHRIS DAWSON 编写. 当我在 Dockercon 上陶醉于那些令人激动地议题时,我想到了一个问题:我 ...
- 最全!即学即会 Serverless Devs 基础入门(下)
作者 | 刘宇(阿里云 Serverless 产品经理) 在上篇<最全!即学即会 Serverless Devs 基础入门>中,我们阐述了工具链的重要性,并对安装方式 & 密钥配置 ...
- 云原生 Serverless Database 使用体验
作者 | 李欣 近十年来互联网技术得到了飞速的发展,越来越多的行业加入到了互联网的矩阵,由此带来了更为丰富且复杂的业务场景需求,这对于数据应用系统的性能无疑是巨大的挑战. 关系型数据库 MySQL ...
- 大数据(4)---HDFS工作机制简述
一.name node管理元数据 元数据:hdfs的目录结构以及文件文件的块信息(块副本数量,存放位置等). Namenode把元数据存在内存中,以方便改动,同时也会在某个时间点上面将其写到磁盘上(f ...
- 什么是全同态加密(FHE)中的自举(Bootstrapping)?
PrimiHub一款由密码学专家团队打造的开源隐私计算平台,专注于分享数据安全.密码学.联邦学习.同态加密等隐私计算领域的技术和内容. 全同态加密(Fully Homomorphic Encrypti ...
- util工具函数
1 /** 2 * @param {Function} fn 防抖函数 3 * @param {Number} delay 延迟时间 4 */ 5 export function debounce(f ...
- spring启动流程 (4) FactoryBean详解
FactoryBean接口 实现类对象将被用作创建Bean实例的工厂,即调用getObject()方法返回的对象才是真正要使用的Bean实例,而不是直接将FactoryBean对象作为暴露的Bean实 ...