Qt 天气预报项目
参考引用
- QT开发专题-天气预报
1. JSON 数据格式
1.1 什么是 JSON
- JSON (JavaScript Object Notation),中文名 JS 对象表示法,因为它和 JS 中对象的写法很类似
- 通常说的 JSON,其实就是 JSON 字符串,本质上是一种特殊格式的字符串
- JSON 是一种轻量级的数据交换格式,客户端和服务端数据交互,基本都是 JSON 格式的
- JSON 有以下特点
- 便于阅读和书写
- 除了 JSON 格式,还有一种数据传输格式 XML,相对于 XML,JSON 更加便于阅读和书写独立于编程语言
- 网络传输的标准数据格式
- 完全独立于编程语言
- 几乎在所有的编程语言和开发环境中,都有解析和生成 JSON 字符串的库
// C Jansson cJSON// C++ jsonCpp、JSON for Modern C++// Java json-lib、org-json// Qt QJSONxxx
- 便于阅读和书写
1.2 JSON 的两种数据格式
JSON 有两种数据格式
- JSON 对象(被大括号包裹)
- JSON 数组(被中括号包裹)
1.2.1 JSON 数组
- JSON 数组格式
[元素1, 元素2, 元素3, ... 元素n]
- 类似于 c/C++ 中的数组,元素之间以逗号分隔。不同的是,JSON 数组中的元素可以是不同的数据类型
- 包括:整型、浮点、字符串、布尔类型、JSON 数组、JSON 对象、空值
// JSON 数组中的元素是同一类型 [1, 2, 3, 4] ["Spring", "Summer", "Autumn", "Winter"]// JSON 数组中的元素是不同类型 [1, 2.5, "hello", true, false, null]// JSON 数组的嵌套 [[1, 2, 3, 4],["Spring", "Summer", "Autumn", "Winter"],[1, 2.5, "hello", true, false, null] ]// JSON 数组嵌套 JSON 对象 [{"name": "Tom","age": 18,"gender": "male"}{"name": "Lucy","age": 20,"gender": "female"} ]
1.2.2 JSON 对象
- JSON 对象格式
{"key1": value1,"key2": value2,"key3": value3 }
- JSON 对象内部使用键值对的方式来组织
- 键和值之间使用冒号分隔,多个键值之间使用逗号分隔
- 键是字符串类型,值的类型可以是:整型、浮点、字符串、布尔类型、JSON 数组、JSON 对象、空值
{"name": "Tom","age": 18,"gender": "male" }
- JSON 对象中,还可以嵌套 JSON 对象和 JSON 数组
{"name": "China","info": {"capital": "beijing","asian": true,"founded": 1949},"provinces": [{"name": "hunan","capital": "changsha"}, {"name": "hubei","capital": "wuhan"}] }
1.3 JSON 在线解析
- JSON 本质就是一种特殊格式的字符串
- 实际工作中,这个 JSON 字符串可能是自己手写的,也可能是来自网络接收的数据
- 下面的一段 JSON 字符串,它可能是自己写的,也可能是服务端返回的
- 它是压缩的格式,也就是没有换行和缩进,不方便判断格式是否正确
- 可以通过 JSON 在线解析工具来校验这个 JSON 的格式是否正确
{"name":"China","info":{"capital":"beijing","asian":true,"founded":1949},"provinces": [{"name":"hunan","capital":"changsha"},{"name":"hubei","capital": "huhan"}]}
1.4 Qt 中使用 JSON
1.4.1 JSON 相关的类
(1)QJsonObject
- QJsonObject 封装了 JSON 中的对象,可以存储多个键值对
- 其中,键为字符串类型,值为 QJsonValue 类型
- 创建一个 QJsonObject 对象
QJsonObject::QJsonObject();
- 将键值对添加到 QJsonObject 对象中
QJsonObject::iterator insert(const QString &key, const QJsonValue &value);
- 获取 QJsonObject 对象中键值对的个数
int QJsonObject::count() const; int QJsonObject::size() const; int QJsonObject::length() const;
- 通过 key 得到 value
QJsonValue QJsonObject::value(const QString &key) const; QJsonValue QJsonObject::operator[](const QString &key) const;
- 检查 key 是否存在
iterator QJsonObject::find(const QString &key); bool QJsonObject::contains(const QString &key) const;
- 遍历 key
QStringList QJsonObject::keys() const;
(2)QJsonArray
- QJsonArray 封装了 Json 中的数组,数组中元素类型统一为 QJsonValue 类型
- 创建一个 QJsonArray
QJsonArray::QJsonArray();
- 添加数组元素
// 添加到头部和尾部 void QJsonArray::append(const QJsonValue &value); void QJsonArray::prepend(const QJsonValue &value);// 插入到 i 的位置之前 void QJsonArray::insert(int i, const QJsonValue &value);// 添加到头部和尾部 void QJsonArray::push_back(const QJsonValue &value); void QJsonArray::push_front(const QJsonValue &value);
- 获取 QJsonArray 中元素个数
int QJsonArray::count() const; int QJsonArray::size() const;
- 获取元素的值
// 获取头部和尾部 QJsonValue QJsonArray::first() const; QJsonValue QJsonArray::last() const;// 获取指定位置 QJsonValue QJsonArray::at(int i) const; QJsonValueRef QJsonArray::operator[](int i);
- 删除元素
// 删除头部和尾部 void QJsonArray::pop_back(); void QJsonArray::pop_front();void QJsonArray::removeFirst(); void QJsonArray::removeLast();// 删除指定位置 void QJsonArray::removeAt(int i); QJsonValue QJsonArray::takeAt(int i);
(3)QJsonValue
-
封装了 JSON 支持的六种数据类型
QJsonValue::Bool // 布尔类型 QJsonValue::Double // 浮点(含整型)类型 QJsonValue::String // 字符串类型 QJsonValue::Array // Json 数组类型 QJsonValue::Object // Json 对象类型 QJsonValue::Null // 空值类型
-
可以通过以下方式构造 QJsonValue 对象
// 字符串 QJsonValue(const char *s); QJsonValue(QLatin1String s); QJsonValue(const QString &s);// 整型 and 浮点型 QJsonValue(qint64 v); QJsonValue(int v); QJsonValue(double v);// 布尔类型 QJsonValue(bool b);// Json 对象 QJsonValue(const QJsonObject &o);// Json 数组 QJsonValue(const QJsonArray &a);// 空值类型 QJsonValue(QJsonValue::Type type = Null);
-
判断一个 QJsonValue 对象内部封装数据类型
// 是否是字符串类型 bool isString() const;// 是否是浮点类型(整形也是通过该函数判断) bool isDouble const;// 是否是布尔类型 bool isBool() const;// 是否是Json对象 bool isObject() const;// 是否是 Json 数组 bool isArray() const;// 是否是未定义类型(无法识别的类型) bool isUndefined() const;// 是否是空值类型 bool isNull() const;
-
数据类型之间的转换 API 函数
// 转换为字符串类型 QString toString() const; QString toString(const QString &defaultValue) const;// 转换为浮点类型 double toDouble(double defaultValue = 0) const;// 转换为整形 int toInt(int defaultValue = 0) const;// 转换为布尔类型 bool toBool(bool defaultValue = false) const;// 转换为 Json 对象 QJsonObject toObject() const; QJsonObject toObject(const QJsonObject &defaultValue) const;// 转换为 Json 数组 QJsonArray toArray() const; QJsonArray toArray(const QJsonArray &defaultValue) const;
(3)QJsonDocument
-
它封装了一个完整的 JSON 文档
- 它可以从 UTF-8 编码的基于文本的表示,以及 Qt 本身的二进制格式读取和写入该文档
- QJsonObject 和 QJsonArray 不能直接转换为字符类型,需通过 QJsonDocument 来完成二者的转换
-
QJsonObject/QJsonArray ==> 字符串
// 1. 创建 QJsonDocument 对象 // 以 QJsonObject 或 QJsonArray 为参数来创建 QJsonDocument 对象 QJsonDocument::QJsonDocument(const QJsonObject &object); QJsonDocument::QJsonDocument(const QJsonArray &array);// 2. 将 QJsonDocument 对象中的数据进行序列化 // 通过调用 toXXX() 方法就可得到文本格式或者二进制格式的 Json 字符串 QByteArray QJsonDocument::toBinaryData() const; // 二进制格式的 json 字符串 QByteArray QJsonDocument::toJson(JsonFormat format = Indented) const; // 文本格式// 3. 使用得到的字符串进行数据传输,或者保存到文件
-
字符串 ==> QJsonObject/QJsonArray
- 通常,通过网络接收或者读取磁盘文件,会得到一个 JSON 格式的字符审,之后可以按照如下步骤,解析出 JSON 字符串中的一个个字段
// 1. 将 JSON 字符串转换为 QJsonDocument 对象 [static] QJsonDocument QJsonDocument::fromBinaryData(const QByteArray &data,DataValidation validation = Validate); [static] QJsonDocument QJsonDocument::fromJson(const QByteArray &json, QJsonParseError *error = Q_NULLPTR);// 2. 将文档对象转换为 json 数组 / 对象 // 2.1 判断文档对象中存储的数据是 JSON 数组还是 JSON 对象 bool QJsonDocument::isArray() const; bool QJsonDocument::isObject() const;// 2.2 转换为 JSON 数组或 JSON 对象 QJsonObject QJsonDocument::object() const; QJsonArray QJsonDocument::array() const;// 3. 调用 QJsonArray / QJsonObject 类提供的 API 获取存储在其中的数据
1.4.2 构建 JSON 字符串
- 在网络传输时,通常是传输的 JSON 字符串,传输之前,首先要生成 JSON 字符串
- 接下来使用 Qt 提供的工具类,来生成如下格式的 JSON 字符串
{"name": "China","info": {"capital": "beijing","asian": true,"founded": 1949},"provinces": [{"name": "hunan","capital": "changsha"}, {"name": "hubei","capital": "wuhan"}] }
- 代码实现
#include <QCoreApplication>#include <QJsonObject> #include <QJsonArray> #include <QJsonDocument>#include <QFile> #include <QByteArray> #include <QDebug> #include <QString>void writeJson() {QJsonObject rootObj;// 1. 插入 name 字段rootObj.insert("name", "China");// 2. 插入 info 字段QJsonObject infoObj;infoObj.insert("capital", "beijing");infoObj.insert("asian", true);infoObj.insert("founded", 1949);rootObj.insert("info", infoObj);// 3. 插入 provinces 字段QJsonArray provinceArray;QJsonObject hunanObj;hunanObj.insert("name", "hunan");hunanObj.insert("capital", "changsha");QJsonObject hubeiObj;hubeiObj.insert("name", "hubei");hubeiObj.insert("capital", "wuhan");provinceArray.append(hunanObj);provinceArray.append(hubeiObj);rootObj.insert("provinces", provinceArray);// 4. 将 QJsonObject 对象 rootObj 转换为 Json 字符串QJsonDocument doc(rootObj);QByteArray json = doc.toJson();// 5.1 打印输出qDebug() << QString(json).toUtf8().data();// 5.2 将 json 字符串写入文件QFile file("d:\\china.json");file.open(QFile::WriteOnly);file.write(json);file.close(); }int main(int argc, char *argv[]) {QCoreApplication a(argc, argv);writeJson();return a.exec(); }
1.4.3 解析 JSON 字符串
- 通常接收网络数据的格式是JSON 格式,在接收完毕之后,需要解析出其中的每一个字段,根据各个字段的值做相应的显示或者其他处理
#include <QCoreApplication>#include <QJsonObject>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonValue>#include <QFile>
#include <QByteArray>
#include <QDebug>
#include <QString>
#include <QStringList>void fromJson() {// 1. 读取文件QFile file("d:\\china.json");file.open(QFile::ReadOnly);QByteArray json = file.readAll();file.close();QJsonDocument doc = QJsonDocument::fromJson(json);if (!doc.isObject()) {qDebug() << "Not an object!";return;}// 2. 开始解析QJsonObject obj = doc.object();QStringList keys = obj.keys();for (int i = 0; i < keys.size(); i++) {// 获取 key-value 对QString key = keys[i];QJsonValue value = obj.value(key);if (value.isBool()) {qDebug() << key << ":" << value.toBool();} else if (value.isString()) {qDebug() << key << ":" << value.toString();} else if (value.isDouble()) {qDebug() << key << ":" << value.toInt();} else if (value.isObject()) {qDebug() << key << ":";QJsonObject infoObj = value.toObject();QString capital = infoObj["capital"].toString();bool asian = infoObj["asian"].toBool();int founded = infoObj["founded"].toInt();qDebug() << " " << "capital" << capital;qDebug() << " " << "asian" << asian;qDebug() << " " << "founded" << founded;} else if (value.isArray()) {qDebug() << key;QJsonArray provinceArray = value.toArray();for (int i = 0; i < provinceArray.size(); i++) {QJsonObject provinceObj = provinceArray[i].toObject();QString name = provinceObj["name"].toString();QString capital = provinceObj["capital"].toString();qDebug() << " " << "name" << ":" << name << ", capital" << ":" << capital;}}}
}int main(int argc, char *argv[]) {QCoreApplication a(argc, argv);fromJson();return a.exec();
}
- 控制台输出
"info" :capital "beijing"asian truefounded 1949 "name" : "China" "provinces"name : "hunan" , capital : "changsha"name : "hubei" , capital : "wuhan"
2. HTTP 通信
2.1 HTTP 概述
HTTP:超文本传输协议 (HyperText Transfer Protocol),HTTP 是浏览器端 web 通信的基础
2.1.1 两种架构
- B/S 架构:Browser/server,浏览器/服务器架构
- B:浏览器,比如 Firefox、Internet Explorer、Google Chrome、Safari、Opera 等
- S:服务器,比如 Apache、nginx 等
- C/S 架构:client/server,客户端/服务器架构
- B/S 架构相对于 C/S 架构,客户机上无需安装任何软件,使用浏览器即可访问服务器,因此,越来越多的 C/S 架构正被 B/S 架构所替代
2.1.2 基于请求响应的模式
- HTTP 协议永远都是客户端发起请求,服务器做出响应
- 也就是说,请求必定是先从客户端发起的,服务器端在没有接收到请求之前不会发送任何响应
- 这就无法实现这样一种场景:服务端主动推送消息给客户端
2.1.3 无状态
-
当浏览器第一次发送请求给服务器时,服务器做出了响应
-
当浏览器第二次发送请求给服务器时,服务器同样可以做出响应,但服务器并不知道第二次的请求和第一次来自同一个浏览器
- 也就是说,服务器不会记住你是谁,所以是无状态的
-
而如果要使 HTTP 协议有状态,就可以使浏览器访问服务器时,加入 cookie,这样,只要你在请求时有了这个 cookie,服务器就能够通过 cookie 知道,你就是之前那个浏览器,这样,HTTP 协议就有状态了
2.1.4 请求报文
请求报文由四部分组成
- 请求行 + 请求头(请求首部字段) + 空行 + 实体
-
请求行
- 请求方法:比如 GET、POST
- 资源对象 (URL)
- 协议名称和版本号 (HTTP/1.1)
-
请求头(请求首部字段)
- 请求头用于告诉服务器该请求的一些信息,起到传递额外信息的目的
- 请求头用于告诉服务器该请求的一些信息,起到传递额外信息的目的
-
空行
- 空行是为了区分请求头和请求实体
-
请求实体
- 请求实体即真正所需要传输的数据
2.1.5 响应保文
响应报文同样是由四部分组成
- 状态行 + 响应头(响应报文首部) + 空行 + 消息体
-
状态行
- HTTP 版本
- 状态码 (表示相应的结果)
- 原因短语 (解释)
-
响应头(响应报文首部)
- 和请求报文首部一样,响应报文首部同样是为了传递额外信息
- 和请求报文首部一样,响应报文首部同样是为了传递额外信息
-
空行
- 同样是为了区别响应实体和响应首部
-
响应实体
- 真正存储响应信息的部分
2.1.6 请求方式
- HTTP 常用的请求方式有很多中,最常用的是 GET 和 POST
- 二者最主要的区别就是
- GET 请求的参数位于 URL 中,会显示在地址栏上
- POST 请求的参数位于 request body 请求体中
因此,GET 请求的安全性不如 POST 请求,并且 GET 请求的参数有长度限制,而 POST 没有
2.2 调试利器 Postman
- HTTP 包含客户端和服务端,试想下面的两种情况(Postman 使用场景)
- 服务端开发完毕,而客户端还未完成开发,此时服务端开发人员能否对自己写的服务端程序进行测试呢?
- 客户端开发人员访问服务端出错,比如无法访问服务端,有没有第三方的测试工具做进一步验证呢?
- Postman 是一个接口测试工具,主要是用来模拟各种 HTTP 请求 (比如 GET 请求、POST 请求等),在做接口测试的时候,Postman 相当于客户端,它可模拟用户发起的各类 HTTP 请求,将请求数据发送至服务端,并获取对应的响应结果
2.2.1 安装
- Postman 下载
2.2.2 发送请求
- 这里以获取北京的天气为例
- 获取北京天气的 URL 为:http://t.weather.itboy.net/api/weather/city/101010100
- 其中,101010100 是北京的城市编码,是 9 位的
2.3 Qt 实现 HTTP 请求
2.3.1 创建 “网络访问管理” 对象
- 首先需要创建一个 QNetworkAccessManager 对象,这是 Qt 中进行 HTTP 请求的开端
mNetAccessManager = new QNetworkAccessManager(this);
2.3.2 关联信号槽
- 在发送 HTTP 请求之前,先关联信号槽
// 获取到数据之后 connect(mNetAccessManager, &QNetworkAccessManager::finished, this, &MainWindow::onReplied);
2.3.3 发送请求
- 根据请求的地址构建出一个 Qurl 对象,然后直接调用 QNetworkAccessManager 的 get 方法,即可发送一个 GET 请求
Qurl ur1("http://t.weather.itboy.net/api/weather/city/101010100"); mNetAccessManager->get(QNetworkRequest(url));
2.3.4 接收数据
- 由于上面绑定了信号槽,服务器返回数据后,自动调用自定义的槽函数 onReplied
- 如下是 onReplied 函数的标准写法,QNetworkReply 中封装了服务器返回的所有数据,包括响应头、响应的状态码、响应体等
void MainWindow::onReplied(QNetworkReply *reply) {// 响应的状态码为200,表示请求成功int status_code = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();qDebug() << "operation:" << reply->operation(); // 请求方式qDebug() << "status code:" << status_code; // 状态码qDebug() << "url:" << reply->url(); // urlqDebug() << "raw header:" << reply->rawHeaderList(); // headerif (reply->error() != QNetworkReply::NoError || status_code != 200) {QMessageBox::warning(this, "提示", "请求数据失败!", QMessageBox::OK);} else {// 获取响应信息QByteArray reply_data = reply->readAll();QByteArray byteArray = QString(reply_data).toUtf8();qDebug() << "read all:" << byteArray.data();// parseJson()}reply->deleteLater(); }
3. 详细代码实现
- WeatherForecast
相关文章:

Qt 天气预报项目
参考引用 QT开发专题-天气预报 1. JSON 数据格式 1.1 什么是 JSON JSON (JavaScript Object Notation),中文名 JS 对象表示法,因为它和 JS 中对象的写法很类似 通常说的 JSON,其实就是 JSON 字符串,本质上是一种特殊格式的字符串…...

新知识-Tuple元组的使用
文章目录 前言一、tuple元组是什么?二、解决方法总结 前言 这次碰到一个需求,大致需要把表A中的字段1和字段2作为共同的表去查表B,并且一次性需要查多条,一开始是想的是根据字段1和字段2去查然后循环多次,但是这样反复…...

“此应用专为旧版android打造,因此可能无法运行”,问题解决方案
当用户在Android P系统上打开某些应用程序时,可能会弹出一个对话框,提示内容为:“此应用专为旧版Android打造,可能无法正常运行。请尝试检查更新或与开发者联系”。 随着Android平台的发展,每个新版本通常都会引入新的…...

【Leetcode题单】(01 数组篇)刷题关键点总结03【数组的改变、移动】
【Leetcode题单】(01 数组篇)刷题关键点总结03【数组的改变、移动】(3题) 数组的改变、移动453. 最小操作次数使数组元素相等 Medium665. 非递减数列 Medium283. 移动零 Easy 大家好,这里是新开的LeetCode刷题系列&…...

Lag-Llama:基于 LlaMa 的单变量时序预测基础模型
文章构建了一个通用单变量概率时间预测模型 Lag-Llama,在来自Monash Time Series库中的大量时序数据上进行了训练,并表现出良好的零样本预测能力。在介绍Lag-Llama之前,这里简单说明什么是概率时间预测模型。概率预测问题是指基于历史窗口内的…...

vue3 :deep() 深度选择器不生效
vue3 :deep() 深度选择器不生效 问题出在根节点上,如果没有这个根节点,那么:deep()不起作用,我把根节点加上,:deep()样式就生效了。在组件外加个 就生效了 参考: 添加链接描述...

从零构建属于自己的GPT系列1:数据预处理(文本数据预处理、文本数据tokenizer、逐行代码解读)
🚩🚩🚩Hugging Face 实战系列 总目录 有任何问题欢迎在下面留言 本篇文章的代码运行界面均在PyCharm中进行 本篇文章配套的代码资源已经上传 从零构建属于自己的GPT系列1:文本数据预处理 从零构建属于自己的GPT系列2:语…...

c++中函数的引用
函数中的引用 引用可以作为函数的形参 不能返回局部变量的引用 #include<iostream> #include<stdlib.h> using namespace std; //形参是引用 void swap(int *x, int *y)//*x *y表示对x y取地址 { int tmp *x; *x *y; *y tmp; } void test01() { …...

IDA常用操作、快捷键总结以及使用技巧
先贴一张官方的图,然后我再总结一下,用的频率比较高的会做一些简单标注 快捷键 F系列【主要是调试状态的处理】 F2 添加/删除断点F4 运行到光标所在位置F5 反汇编F7 单步步入F8 单步跳过F9 持续运行直到输入/断点/结束 shift系列【主要是调出对应的页…...

Kibana使用指南
使用介绍主要特点应用场景数据可视化还有哪些类型安装步骤安装配置参数Elasticsearch配置参数注意事项 使用介绍 Kibana是一个开源的分析与可视化平台,设计出来用于和Elasticsearch一起使用的。可以用Kibana搜索、查看、交互存放在Elasticsearch索引里的数据&#…...

wvp如果确认音频udp端口开放成功
用到工具 在服务器上开启端口监听 选中udp server,点击创建按钮 设置服务器监听端口 在客户端连接服务器端口 选中udp客户端,点击创建 输入服务器地址 远程端口和本地端口,本地端口只要没被占用都可以使用 ,点击确认 发送数据 …...

C#文件夹基本操作(判断文件夹是否存在、创建文件夹、移动文件夹、删除文件夹以及遍历文件夹中的文件)
目录 一、判断文件夹是否存在 1.Directory类的Exists()方法 2. DirectoryInfo类的Exists属性 二、创建文件夹 1. Directory类的CreateDirectory()方法 2.DirectoryInfo类的Create()方法 三、移动文件夹 1. Directory类的Move()方法 2.DirectoryInfo类的MoveT…...

python 交互模式和命令行模式的问题
python 模式的冲突 unexpected character after line continuation character 理论上 ide里,输入 python 文件路径\文件.py 就可以执行 但是有时候却报错 unexpected character after line continuation character 出现上述错误的原因是没有退出解释器&#x…...

计算机网络——数据链路层
目录 一、数据链路层的基本概念 (一)数据链路层的概念 (二)帧 (三)数据链路层分为哪两个部分 (1)LLC(逻辑控制访问) (2)MAC&…...

【限时免费】20天拿下华为OD笔试之【哈希集合】2023B-明明的随机数【欧弟算法】全网注释最详细分类最全的华为OD真题题解
文章目录 题目描述与示例题目描述输入描述输出描述:示例 1输入输出说明 解题思路代码PythonJavaC时空复杂度 华为OD算法/大厂面试高频题算法练习冲刺训练 题目描述与示例 题目描述 明明生成了N 个 1 至 500 之间的随机整数。请你删去其中重复的数字,即…...

播放器开发(五):视频帧处理并用SDL渲染播放
目录 学习课题:逐步构建开发播放器【QT5 FFmpeg6 SDL2】 步骤 VideoOutPut模块 1、初始化【分配缓存、读取信息】 2、开始线程工作【从队列读帧->缩放->发送渲染信号到窗口】 VideoWidget自定义Widget类 1、定义内部变量 2、如果使用SDL,需要进…...

Spring MVC数据绑定的几种方法(一)
这篇文章包含spring mvc的默认数据类型绑定和简单数据类型绑定。内容来自实验。 准备: (1)在IDEA环境中从archetye创建webapp类型的maven项目exp6。 (2)在src\main目录下创建并标注java源代码文件夹和resources资源文…...

CSP-坐标变换(其二)
问题描述 对于平面直角坐标系上的坐标 (x,y),小 P 定义了如下两种操作: 拉伸 k 倍:横坐标 x 变为 kx,纵坐标 y 变为 ky; 旋转 θ:将坐标 (x,y) 绕坐标原点 (0,0) 逆时针旋转 θ 弧度(0≤θ<…...

docker 安装jekins
echo Asia/Shanghai >/etc/timezone,容器中操作报错:docker容器中 Permission denied 使用该-u选项时,可以使用root用户(ID 0),而不是用默认用户登录docker容器 docker exec -u 0 -it f8a2b3d91455 /bin/bash 或者ÿ…...

ChatGPT 问世一周年之际,开源大模型能否迎头赶上?
就在11月30日,ChatGPT 迎来了它的问世一周年,这个来自 OpenAI 的强大AI在过去一年里取得了巨大的发展,迅速吸引各个领域的用户群体。 我们首先回忆一下 OpenAI和ChatGPT这一年的大事记(表格由ChatGPT辅助生成)&#x…...

数据结构和算法-哈夫曼树以相关代码实现
文章目录 总览带权路径长度哈夫曼树的定义哈夫曼树的构造法1法2 哈夫曼编码英文字母频次总结实验内容: 哈夫曼树一、上机实验的问题和要求(需求分析):二、程序设计的基本思想,原理和算法描述:三、调试和运行…...

Kafka 的起源和背景
Apache Kafka 是一个分布式流处理平台,被广泛用于构建实时数据流应用程序和大数据处理系统。本文将深入探讨 Kafka 的起源、设计原则以及它在大数据领域中的重要作用。 大数据和实时数据处理背景 在大数据时代,处理海量数据和实时数据成为了一项关键挑…...

三极管在数字电路中的应用
一、认识三极管 三极管拥有3个引脚,分别对应3个级:基极(Base)、发射极(Emitter)、集电极(Collector),如下图所示;下图横向左侧的是基极,带箭头的那个引脚就是发射极,另一个就是集电…...

java后端自学错误总结
java后端自学错误总结 MessageSource国际化接口总结 MessageSource国际化接口 今天第一次使用MessageSource接口,比较意外遇到了一些坑 messageSource是spring中的转换消息接口,提供了国际化信息的能力。MessageSource用于解析 消息,并支持消息的参数化…...

CLion安装与配置教程
目录 一、下载并安装CLion1、下载1、官网:2、注意: 2、安装1、下载完成后,直接点击安装包安装,即可。2、开始安装,然后下一步3、可以在此处自定义地址,然后下一步4、根据系统版本选择,然后下一步…...

初识主力投资者
在股票市场中,真正赚钱的散户并不多。“七亏二平一赚”似乎已经成为了大家公认的一个股市定律。 为什么散户炒股赚的人少呢?原因很简单,就是因为市场上除了散户之外,还存在着一个重要的投资主体——主力。股市交易的过程ÿ…...

vue项目报错及解决npm run build:prod打包错误
vue项目报错及解决npm run build:prod打包错误 执行dev环境时加载失败了该变量,在package.json文件中 删掉 解决方法: 打包成功:...

Go连接mysql数据库
package main import ("database/sql""fmt"_ "github.com/go-sql-driver/mysql" ) //go连接数据库示例 func main() {// 数据库信息dsn : "root:roottcp(192.168.169.11:3306)/sql_test"//连接数据库 数据库类型mysql,以及数据库信息d…...

⭐ Unity 里让 Shader 动画在 Scene 面板被持续刷新
写 Unity Shader的时候,只有播放状态下的 Game 面板能看到Shader 顺畅的动态效果,不方便。 想要带有动态效果的 Shader 在 Scene 面板持续更新动画,只需要打开一个开关就能让 Scene 持续刷新动画了。 感谢大家的观看,您的点赞和关…...

面试--各种场景问题总结
1.在开发过程中,你是如何保证机票系统的正常运行的? 用户、测试、监控和日志、安全措施、数据备份、系统设计、需求分析 2.在机票系统开发过程中,你最有成就的事情,为什么? 用户体验感、高可用和稳定性、客户满意度、系…...