Hi3861 OpenHarmony嵌入式应用入门--MQTT
MQTT 是机器对机器(M2M)/物联网(IoT)连接协议。它被设计为一个极其轻量级的发布/订阅消息传输 协议。对于需要较小代码占用空间和/或网络带宽非常宝贵的远程连接非常有用,是专为受限设备和低带宽、 高延迟或不可靠的网络而设计。这些原则也使该协议成为新兴的“机器到机器”(M2M)或物联网(IoT)世界 的连接设备,以及带宽和电池功率非常高的移动应用的理想选择。例如,它已被用于通过卫星链路与代理 通信的传感器、与医疗服务提供者的拨号连接,以及一系列家庭自动化和小型设备场景。它也是移动应用 的理想选择,因为它体积小,功耗低,数据包最小,并且可以有效地将信息分配给一个或多个接收器。M QTT 通信模型如下图所示:

前提需要在电脑上运行起来mqtt的服务器,emqx软件非常合适,他还带了mqtt的客户端,很方便调试,具体下载和安装方法见下面博文,也可以去emqx官网下载最新版进行免费试用。
MQTT:windows最简单搭建mqtt服务端及本地客户端测试_emqx-windows-4.3.6-CSDN博客
修改网络参数
在Hi3861开发板上运行上述四个测试程序之前,需要根据你的无线路由、Linux系统IP修改 net_params.h文件的相关代码:
- PARAM_HOTSPOT_SSID 修改为你的热点名称
- PARAM_HOTSPOT_PSK 修改为你的热点密码;
- PARAM_SERVER_ADDR 修改为你的服务器IP地址;
- PARAM_SERVER_PORT 修改为你的服务器端口号;
- SERVER_IP_ADDR 修改为你的mqtt服务器IP地址;
- SERVER_IP_PORT 修改为mqtt的tcp端口,默认为1883;
- MQTT_TOPIC_SUB 订阅ID;
- MQTT_TOPIC_PUB 发布的ID;
- MQTT_CLIENT_ID MQTT的客户端ID;
- MQTT_USER_NAME MQTT的用户名;
- MQTT_PASSWORD MQTT的密码;
代码编写
修改D:\DevEcoProjects\test\src\vendor\rtplay\rt_hi3861\demo\BUILD.gn文件
# Copyright (c) 2023 Beijing HuaQing YuanJian Education Technology Co., Ltd
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License. import("//build/lite/config/component/lite_component.gni")lite_component("demo") {features = [#"base_00_helloworld:base_helloworld_example",#"base_01_led:base_led_example",#"base_02_loopkey:base_loopkey_example",#"base_03_irqkey:base_irqkey_example",#"base_04_adc:base_adc_example",#"base_05_pwm:base_pwm_example",#"base_06_ssd1306:base_ssd1306_example",#"kernel_01_task:kernel_task_example",#"kernel_02_timer:kernel_timer_example",#"kernel_03_event:kernel_event_example",#"kernel_04_mutex:kernel_mutex_example",#"kernel_05_semaphore_as_mutex:kernel_semaphore_as_mutex_example",#"kernel_06_semaphore_for_sync:kernel_semaphore_for_sync_example",#"kernel_07_semaphore_for_count:kernel_semaphore_for_count_example",#"kernel_08_message_queue:kernel_message_queue_example",#"wifi_09_hotspot:wifi_hotspot_example",#"wifi_10_sta:wifi_sta_example",#"tcp_11_server:tcp_server_example",#"tcp_12_client:tcp_client_example",#"udp_13_server:udp_server_example",#"udp_14_client:udp_client_example","network_15_mqtt:network_mqtt_example",]
}
创建D:\DevEcoProjects\test\src\vendor\rtplay\rt_hi3861\demo\network_15_mqtt文件夹
文件夹中创建D:\DevEcoProjects\test\src\vendor\rtplay\rt_hi3861\demo\network_15_mqtt\BUILD.gn文件
# Copyright (c) 2023 Beijing HuaQing YuanJian Education Technology Co., Ltd
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License. static_library("network_mqtt_example") {sources = ["network_mqtt_example.c","network_mqtt.c","wifi_connecter.c","//third_party/paho.mqtt.embedded-c/MQTTPacket/src/MQTTConnectClient.c","//third_party/paho.mqtt.embedded-c/MQTTPacket/src/MQTTConnectServer.c","//third_party/paho.mqtt.embedded-c/MQTTPacket/src/MQTTDeserializePublish.c","//third_party/paho.mqtt.embedded-c/MQTTPacket/src/MQTTFormat.c","//third_party/paho.mqtt.embedded-c/MQTTPacket/src/MQTTPacket.c","//third_party/paho.mqtt.embedded-c/MQTTPacket/src/MQTTSerializePublish.c","//third_party/paho.mqtt.embedded-c/MQTTPacket/src/MQTTSubscribeClient.c","//third_party/paho.mqtt.embedded-c/MQTTPacket/src/MQTTSubscribeServer.c","//third_party/paho.mqtt.embedded-c/MQTTPacket/src/MQTTUnsubscribeServer.c","//third_party/paho.mqtt.embedded-c/MQTTPacket/src/MQTTUnsubscribeClient.c",]include_dirs = ["//utils/native/lite/include","//kernel/liteos_m/kal/cmsis","//base/iot_hardware/peripheral/interfaces/kits","//foundation/communication/wifi_lite/interfaces/wifiservice","//vendor/hqyj/fs_hi3861/common/bsp/include","//third_party/paho.mqtt.embedded-c/MQTTPacket/src","//third_party/cJSON",]
}
文件夹中创建D:\DevEcoProjects\test\src\vendor\rtplay\rt_hi3861\demo\network_15_mqtt\network_mqtt.h文件,文件主要包含mqtt的函数。
/** Copyright (c) 2023 Beijing HuaQing YuanJian Education Technology Co., Ltd* Licensed under the Apache License, Version 2.0 (the "License");* you may not use this file except in compliance with the License.* You may obtain a copy of the License at** http://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an "AS IS" BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.*/#ifndef NETWORK_MQTT_H
#define NETWORK_MQTT_H/*** @brief MQTT 连接MQTT服务器* @return Returns {0} 成功;* Returns {-1} 失败.*/
int MQTTClient_connectServer(const char *ip_addr, int ip_port);
/*** @brief MQTT 断开连接MQTT服务器* @return Returns {0} 成功;* Returns {-1} 失败.*/
int MQTTClient_unConnectServer(void);
/*** @brief MQTT 订阅MQTT主题* @return Returns {0} 成功;* Returns {-1} 失败.*/
int MQTTClient_subscribe(char *subTopic);
/*** @brief MQTT 客户端的初始化* @param clientID 客户端ID* @param userName 用户名* @param password 密码* @return Returns {0} 成功;* Returns {-1} 失败.*/
int MQTTClient_init(char *clientID, char *userName, char *password);
/*** @brief MQTT 发布消息* @param pub_Topic 具有发布权限的主题名称* @param payloadData 发布数据* @param payloadLen 发布数据的长度* @return Returns {0} 成功;* Returns {-1} 失败.*/
int MQTTClient_pub(char *pub_Topic, unsigned char *payloadData, int payloadLen);
/*** @brief MQTT 接收消息* @param callback 当接收到消息之后,将消息传到到回调函数中* @return Returns {0} 成功;* Returns {-1} 失败.*/
int MQTTClient_sub(void);extern int8_t(*p_MQTTClient_sub_callback)(unsigned char *topic, unsigned char *payload);#endif // !NETWORK_MQTT_H
文件夹中创建D:\DevEcoProjects\test\src\vendor\rtplay\rt_hi3861\demo\network_15_mqtt\network_mqtt.c文件,文件主要包含mqtt的函数实现。
/** Copyright (c) 2023 Beijing HuaQing YuanJian Education Technology Co., Ltd* Licensed under the Apache License, Version 2.0 (the "License");* you may not use this file except in compliance with the License.* You may obtain a copy of the License at** http://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an "AS IS" BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.*/#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include "lwip/netifapi.h"
#include "lwip/sockets.h"
#include "wifi_device.h"
#include "ohos_init.h"
#include "MQTTPacket.h"
#include "network_mqtt.h"#define MQTT_BUFF_MAX_SIZE 512int g_tcp_socket_fd = 0; // 网络套接字
unsigned char mqttBuff[MQTT_BUFF_MAX_SIZE] = {0};// 发送网络数据
static int transport_sendPacketBuffer(unsigned char *buf, int buflen)
{int rc = send(g_tcp_socket_fd, buf, buflen, 0);return (rc <= 0) ? 0 : 1;
}
// 接收网络数据
static int transport_getdata(unsigned char *buf, int count)
{int rc = recv(g_tcp_socket_fd, buf, count, 0);return rc;
}// 连接服务器
int MQTTClient_connectServer(const char *ip_addr, int ip_port)
{if (ip_addr == NULL) {return -1;}int res = 0; // 函数返回值struct sockaddr_in tcpServerConfig; // tcp服务器信息// 创建TCP套接字g_tcp_socket_fd = socket(AF_INET, SOCK_STREAM, 0);if (g_tcp_socket_fd < 0) {printf("Failed to create Socket\r\n");}// 连接TCP服务器tcpServerConfig.sin_family = AF_INET; // IPV4tcpServerConfig.sin_port = htons(ip_port); // 填写服务器的IP端口号tcpServerConfig.sin_addr.s_addr = inet_addr(ip_addr); // 填写服务器的IP地址res = connect(g_tcp_socket_fd, (struct sockaddr *)&tcpServerConfig, sizeof(tcpServerConfig)); // 连接服务器if (res == -1) {printf("Failed to connect to the server\r\n");return -1;}printf("Connection to server successful\r\n");return 0;
}// 断开TCP服务器 0:成功, -1:失败
int MQTTClient_unConnectServer(void)
{int ret = 0;printf("Server shut down successfully\r\n");ret = close(g_tcp_socket_fd);g_tcp_socket_fd = 0;return ret;
}// mqtt客户端 订阅主题
int MQTTClient_subscribe(char *subTopic)
{if (subTopic == NULL) {printf("Incorrect parameters\r\n");return -1;}int len = 0, res = 0;int subcount = 0, granted_qos = 0, req_qos = 0;unsigned short submsgid = 0;MQTTString topicString = MQTTString_initializer;/* subscribe */topicString.cstring = subTopic;len = MQTTSerialize_subscribe(mqttBuff, sizeof(mqttBuff), 0, 1, 1, &topicString, &req_qos);if (len <= 0) {printf("MQTTSerialize_subscribe Error %d\r\n", len);return -1;}res = transport_sendPacketBuffer(mqttBuff, len);if (res != 1) {printf("transport_sendPacketBuffer Error %d\r\n", res);return -1;}sleep(1);memset_s(mqttBuff, sizeof(mqttBuff), 0, sizeof(mqttBuff));/* wait for suback */if (MQTTPacket_read(mqttBuff, sizeof(mqttBuff), transport_getdata) != SUBACK) {printf("MQTTPacket_read Error\r\n");return -1;}if (MQTTDeserialize_suback(&submsgid, 1, &subcount, &granted_qos, mqttBuff, sizeof(mqttBuff)) != 1) {printf("MQTTDeserialize_suback Error\r\n");return -1;}printf("MQTT subscribed to topics successfully\r\n");return 0;
}// 保持在线时长 60s
#define MQTT_KEEP_ALIVE 60
#define MQTT_DELAY_TIME 3// mqtt客户端 初始化
int MQTTClient_init(char *clientID, char *userName, char *password)
{if (clientID == NULL || userName == NULL || password == NULL) {printf("Incorrect parameters\r\n");return -1;}int res = 0, len = 0, i = 0;int mqtt_read_len = 10;unsigned char sessionPresent = 0, connack_rc = 0;MQTTPacket_connectData mqttData = MQTTPacket_connectData_initializer;// 初始化MQTT客户端mqttData.clientID.cstring = clientID;mqttData.username.cstring = userName;mqttData.password.cstring = password;mqttData.cleansession = true; // 是否初始化的时候,清除上一次的对话mqttData.keepAliveInterval = MQTT_KEEP_ALIVE;// 组MQTT消息包len = MQTTSerialize_connect(mqttBuff, sizeof(mqttBuff), &mqttData);if (len <= 0) {printf("MQTTSerialize_connect Error %d\r\n", res);return -1;}res = transport_sendPacketBuffer(mqttBuff, len);if (res != 1) {printf("transport_sendPacketBuffer Error %d\r\n", res);return -1;}sleep(MQTT_DELAY_TIME);/* 打印发送出去的数据帧,调试用 */printf("MQTT_sendPacket: \r\n");for (i = 0; i < len; i++) {printf("%x ", mqttBuff[i]);}printf("\r\n");memset_s(mqttBuff, sizeof(mqttBuff), 0, sizeof(mqttBuff));/* wait for connack */if (MQTTPacket_read(mqttBuff, sizeof(mqttBuff), transport_getdata) != CONNACK) {printf("MQTTPacket_read != CONNACK\r\n");}printf("MQTT_recvPacket: \r\n");/* 打印服务器返回的消息,调试用 */for (i = 0; i < mqtt_read_len; i++) {printf("%x ", mqttBuff[i]);}printf("\r\n");if (MQTTDeserialize_connack(&sessionPresent, &connack_rc, mqttBuff, sizeof(mqttBuff)) != 1 || connack_rc != 0) {printf("Unable to connect, return code %d\r\n", connack_rc);memset_s(mqttBuff, sizeof(mqttBuff), 0, sizeof(mqttBuff));return -1;} else {printf("MQTT initialized successfully\r\n");}memset_s(mqttBuff, sizeof(mqttBuff), 0, sizeof(mqttBuff));return 0;
}#define MQTT_PUB_DATA_TIME (100 * 1000)int MQTTClient_pub(char *pub_Topic, unsigned char *payloadData, int payloadLen)
{if (payloadData == NULL) {printf("Incorrect parameters\r\n");return -1;}printf("pubTopic: %s\n", pub_Topic);printf("pubData: %s\n", payloadData);int ret = 0, len = 0;unsigned short retry_count = 5; // 重发次数unsigned char sendBuff[MQTT_BUFF_MAX_SIZE] = {0};MQTTString topicString = MQTTString_initializer;topicString.cstring = pub_Topic;len = MQTTSerialize_publish(sendBuff, sizeof(sendBuff), 0, 0, 0, 0, topicString,payloadData,payloadLen);while (--retry_count > 0) {ret = transport_sendPacketBuffer(sendBuff, len);if (ret == 1) {break;}printf("Send MQTT_Data Fail\r\n");usleep(MQTT_PUB_DATA_TIME);}if (!retry_count && ret != 1) {printf("transport_sendPacketBuffer Error %d\r\n", ret);return -1;}// printf("send==>%s", payloadData);return 0;
}
unsigned char mqtt_topic[200];
int8_t (*p_MQTTClient_sub_callback)(unsigned char *topic, unsigned char *payload);int MQTTClient_sub(void)
{int qos, payloadlen_in;unsigned char dup, retained;unsigned short msgid;unsigned char *payload_in;MQTTString receivedTopic;memset_s(mqttBuff, sizeof(mqttBuff), 0, sizeof(mqttBuff));// $oc/devices/63ad5a6cc4efcc747bd75973_lamp/sys/commands/request_id=42c20ffb-0885-4f6e-97b5-45d8f613efafif (MQTTPacket_read(mqttBuff, sizeof(mqttBuff), transport_getdata) == PUBLISH) {MQTTDeserialize_publish(&dup, &qos, &retained, &msgid, &receivedTopic,&payload_in, &payloadlen_in, mqttBuff, sizeof(mqttBuff));printf("data: %s\n", receivedTopic.lenstring.data);printf("length: %d\n", strlen(receivedTopic.lenstring.data) - payloadlen_in);printf("payload_length: %d\n", payloadlen_in);memcpy_s(mqtt_topic, sizeof(mqtt_topic),receivedTopic.lenstring.data, strlen(receivedTopic.lenstring.data) - payloadlen_in);printf("topic: %s\n", mqtt_topic);printf("payload: %s\n", payload_in);p_MQTTClient_sub_callback(mqtt_topic, payload_in);}
}
文件夹中创建D:\DevEcoProjects\test\src\vendor\rtplay\rt_hi3861\demo\network_15_mqtt\wifi_connecter.h文件,该头文件包含wifi连接的宏。文件同tcp_12_client\wifi_connecter.h
文件夹中创建D:\DevEcoProjects\test\src\vendor\rtplay\rt_hi3861\demo\network_15_mqtt\wifi_connecter.c文件,文件同tcp_12_client\wifi_connecter.c
文件夹中创建D:\DevEcoProjects\test\src\vendor\rtplay\rt_hi3861\demo\network_15_mqtt\network_mqtt_example.c文件
/** Copyright (c) 2023 Beijing HuaQing YuanJian Education Technology Co., Ltd* Licensed under the Apache License, Version 2.0 (the "License");* you may not use this file except in compliance with the License.* You may obtain a copy of the License at** http://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an "AS IS" BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.*/#include <stdio.h>
#include <unistd.h>
#include <string.h>#include "ohos_init.h"
#include "cmsis_os2.h"
#include "network_mqtt.h"
#include "wifi_connecter.h"#define SERVER_IP_ADDR "192.168.137.1"
#define SERVER_IP_PORT 1883
#define MQTT_TOPIC_SUB "subTopic"
#define MQTT_TOPIC_PUB "pubTopic"
#define MQTT_CLIENT_ID "mqtt_client_123"
#define MQTT_USER_NAME "rtplay"
#define MQTT_PASSWORD "password"
#define TASK_STACK_SIZE (1024 * 5)
#define TASK_INIT_TIME 2 // s
#define MQTT_RECV_TASK_TIME (200 * 1000) // us
#define DELAY_TICKS_10 (10)osThreadId_t mqtt_send_task_id; // mqtt订阅数据任务
osThreadId_t mqtt_recv_task_id; // mqtt发布数据任务
int8_t mqtt_sub_payload_callback(unsigned char *topic, unsigned char *payload)
{printf("[info] topic:[%s] recv<== %s\r\n", topic, payload);
}
void mqtt_recv_task(void)
{while (1) {MQTTClient_sub();usleep(MQTT_RECV_TASK_TIME);}
}
void mqtt_send_task(void)
{// 连接WifiWifiDeviceConfig config = {0};// 准备AP的配置参数// strcpy(config.ssid, PARAM_HOTSPOT_SSID);// strcpy(config.preSharedKey, PARAM_HOTSPOT_PSK);strcpy_s(config.ssid, WIFI_MAX_SSID_LEN, PARAM_HOTSPOT_SSID);strcpy_s(config.preSharedKey, WIFI_MAX_KEY_LEN, PARAM_HOTSPOT_PSK);config.securityType = PARAM_HOTSPOT_TYPE;osDelay(DELAY_TICKS_10);int netId = ConnectToHotspot(&config);// 连接MQTT服务器if (MQTTClient_connectServer(SERVER_IP_ADDR, SERVER_IP_PORT) != 0) {printf("[error] MQTTClient_connectServer\r\n");} else {printf("[success] MQTTClient_connectServer\r\n");}sleep(TASK_INIT_TIME);// 初始化MQTT客户端if (MQTTClient_init(MQTT_CLIENT_ID, MQTT_USER_NAME, MQTT_PASSWORD) != 0) {printf("[error] MQTTClient_init\r\n");} else {printf("[success] MQTTClient_init\r\n");}sleep(TASK_INIT_TIME);// 订阅Topicif (MQTTClient_subscribe(MQTT_TOPIC_SUB) != 0) {printf("[error] MQTTClient_subscribe\r\n");} else {printf("[success] MQTTClient_subscribe\r\n");}sleep(TASK_INIT_TIME);osThreadAttr_t options;options.name = "mqtt_recv_task";options.attr_bits = 0;options.cb_mem = NULL;options.cb_size = 0;options.stack_mem = NULL;options.stack_size = TASK_STACK_SIZE;options.priority = osPriorityNormal;mqtt_recv_task_id = osThreadNew((osThreadFunc_t)mqtt_recv_task, NULL, &options);if (mqtt_recv_task_id != NULL) {printf("ID = %d, Create mqtt_recv_task_id is OK!\r\n", mqtt_recv_task_id);}while (1) {MQTTClient_pub(MQTT_TOPIC_PUB, "hello world!!!", strlen("hello world!!!"));sleep(TASK_INIT_TIME);}
}static void network_wifi_mqtt_example(void)
{printf("Enter network_wifi_mqtt_example()!\r\n");p_MQTTClient_sub_callback = &mqtt_sub_payload_callback;osThreadAttr_t options;options.name = "mqtt_send_task";options.attr_bits = 0;options.cb_mem = NULL;options.cb_size = 0;options.stack_mem = NULL;options.stack_size = TASK_STACK_SIZE;options.priority = osPriorityNormal;mqtt_send_task_id = osThreadNew((osThreadFunc_t)mqtt_send_task, NULL, &options);if (mqtt_send_task_id != NULL) {printf("ID = %d, Create mqtt_send_task_id is OK!\r\n", mqtt_send_task_id);}
}
SYS_RUN(network_wifi_mqtt_example);
使用build,编译成功后,使用upload进行烧录。
首先运行emqx
设置中文

运行后电脑ap会看到设备

串口会输出

网页中客户端会看到模块

主题也会看到


创建websocket连接服务

客户端已经有了两个

订阅模块的消息

可以收到模块发送的消息
发送模块订阅的消息

模块能收到消息

相关文章:
Hi3861 OpenHarmony嵌入式应用入门--MQTT
MQTT 是机器对机器(M2M)/物联网(IoT)连接协议。它被设计为一个极其轻量级的发布/订阅消息传输 协议。对于需要较小代码占用空间和/或网络带宽非常宝贵的远程连接非常有用,是专为受限设备和低带宽、 高延迟或不可靠的网络而设计。这些原则也使该协议成为新兴的“机器…...
[22] Opencv_CUDA应用之 使用背景相减法进行对象跟踪
Opencv_CUDA应用之 使用背景相减法进行对象跟踪 背景相减法是在一系列视频帧中将前景对象从背景中分离出来的过程,它广泛应用于对象检测和跟踪应用中去除背景 背景相减法分四步进行:图像预处理 -> 背景建模 -> 检测前景 -> 数据验证 预处理去除噪声背景建模,以便与…...
Maven在Windows中的配置方法
本文介绍在Windows电脑中,下载、配置Maven工具的详细方法。 Maven是一个广泛使用的项目管理工具,主要针对Java项目,但也可以用于其他类型的项目;其由Apache软件基金会维护,旨在简化和标准化项目构建过程,依…...
一、redis-万字长文读懂redis
高性能分布式缓存Redis `第一篇章`1.1缓存发展史&缓存分类1.1.1 大型网站中缓存的使用带来的问题1.1.2 常见缓存的分类及对比与memcache对比1.2 数据类型选择&应用场景1.2.1 string1.2.2 hash1.2.3 链表1.2.4 set1.2.5 sortedset有序集合类型1.2.6 总结1.3 Redis高级应…...
搞清楚[继承],易如反掌
穷不失义,达不离道。——孔丘《论语》 继承 1、简单理解2、继承2、1、继承的概念2、2、继承定义2、3、基类和派生类对象赋值转换2、4、继承中的作用域2、5、派生类默认成员函数2、6、继承中的特点2、6、1、友元2、6、2、静态成员2、6、3、菱形继承及菱形虚拟继承 3、…...
Perl 语言入门学习指南:探索高效脚本编程的奥秘
引言 Perl,全称Practical Extraction and Report Language,是一种功能强大的编程语言,特别擅长于文本处理、报告生成以及系统自动化管理任务。自1987年诞生以来,Perl凭借其灵活性、强大的内置功能库和广泛的社区支持,…...
【HTML】-解决页面内容无法选择、复制问题
目录 1、网页内容无法选中 1.1、问题原因 1.2、解决脚本 1.2.1、开启控制台窗口 1.2.2、执行脚本命令 2、内容复制弹出阻止框 2.2、解决脚本 1、网页内容无法选中 1.1、问题原因 今天在访问某一网站平台,需要将内容进行选择、复制时发现不可使用。 在使用…...
C#中委托与事件
一、委托 在面向对象中,我们可以将任何数据类型作为参数传递给方法,能否将一个方法作为参数传递给另一个方法?C#中通过委托可以实现将方法作为参数进行传递。 1.1概念 委托是一种引用类型,它可以用于封装并传递方法作为参数。委…...
通用后台管理(二)——项目搭建
目录 前言 一、安装vue-cli依赖 1、使用yarn下载vue-cli 2、使用npm下载 3、检查一下是否下载成功 二、创建项目 1、创建项目,my-app是项目名称 2、 这里选择vue 2,蓝色表示选中的。 3、启动项目 三、下载项目依赖 四、配置项目 1、修改esli…...
多模态大模型之达摩院通义MPLUG
引言 随着人工智能技术的飞速发展,多模态技术逐渐成为研究的热点。它结合了文本、图像、声音等多种数据类型,为机器理解世界提供了更丰富的视角。本文根据严明老师的达摩院通义MPLUG多模态预训练技术分享,及其在电商等行业的应用实践&#x…...
文章翻译记录
以 PINN 为基础,我们开发了一个框架,用于在不同震源位置和速度模型下进行地震建模。本研究的显著贡献包括: 1. 为了提高网络对不同速度模型的泛化能力,必须将速度变量 vp 作为系统的输入参数。本研究从监督学习中汲取灵感…...
C++ 语法习题(2)
第三讲 循环语句 1.偶数 编写一个程序,输出 1 到 100之间(包括 1 和 100)的全部偶数。 输入格式 无输入。 输出格式 输出全部偶数,每个偶数占一行。 输入样例 No input输出样例 2 4 6 ... 100 参考代码: #include <i…...
使用Gstreamer时遇到WARNING: erroneous pipeline: no element “x264enc“(亲测有效)
WARNING: erroneous pipeline: no element “x264enc” 解决: 我下了gstreamer1.0-plugins-ugly包就解决了 sudo apt install -y gstreamer1.0-plugins-ugly...
SAP 新增移动类型简介
在SAP系统中新增移动类型的过程涉及多个步骤,包括复制现有的移动类型、调整科目设置以及进行必要的测试。以下是新增移动类型的一般步骤和关键点: 复制现有的移动类型: 使用事务代码OMJJ进入移动类型维护界面。 勾选移动类型 这里不填写移动类型,然后直接下…...
SQL性能优化策略
发现问题 通过业务监控发现慢SQL或接口响应延迟。利用性能分析工具定位问题。 定位SQL语句 使用监控工具确定影响性能的SQL语句和表。 SQL查询变慢原因 索引失效:查询未使用索引或索引效率低。多表连接:JOIN操作导致性能下降。查询字段过多…...
代码随想录第四十八天 | 198.打家劫舍, 213.打家劫舍II,337.打家劫舍III
198.打家劫舍 看完想法:这里的偷/不偷,和背包问题中的放/不放感觉是一个道理,所以在dp递推公式中仍旧使用max(dp[i-2] nums[i], dp[i-1]) int rob(vector<int>& nums) {vector<int> dp(nums.size()1,0);if(nums.size()0) …...
C#实用的工具类库
Masuit.Tools Masuit.Tools大都是静态类,加密解密,反射操作,树结构,文件探测,权重随机筛选算法,分布式短id,表达式树,linq扩展,文件压缩,多线程下载…...
首席数据官CDO证书报考指南:方式、流程、适考人群与考试难度
在信息泛滥的今天,数据已转变为企业不可或缺的宝贵资源。 面对海量的信息,如何提炼出价值,为企业带来实质性的收益?首席数据官(CDO)认证的出现正是为了满足这一需求,它不仅是个人专业能力的体现…...
数据库基础复习
数据库简介 关系型数据库:Mysql 、Oracle 、SqlServer.... DB2 达梦 非关系型数据库:Redis 、MongoDB... MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管…...
探索AI大模型(LLM)减少幻觉的三种策略
大型语言模型(LLM)在生成文本方面具有令人瞩目的能力,但在面对陌生概念和查询时,它们有时会输出看似合理却实际错误的信息,这种现象被称为“幻觉”。近期的研究发现,通过策略性微调和情境学习、检索增强等方…...
synchronized 学习
学习源: https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖,也要考虑性能问题(场景) 2.常见面试问题: sync出…...
Spring Boot 实现流式响应(兼容 2.7.x)
在实际开发中,我们可能会遇到一些流式数据处理的场景,比如接收来自上游接口的 Server-Sent Events(SSE) 或 流式 JSON 内容,并将其原样中转给前端页面或客户端。这种情况下,传统的 RestTemplate 缓存机制会…...
基于Flask实现的医疗保险欺诈识别监测模型
基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施,由雇主和个人按一定比例缴纳保险费,建立社会医疗保险基金,支付雇员医疗费用的一种医疗保险制度, 它是促进社会文明和进步的…...
django filter 统计数量 按属性去重
在Django中,如果你想要根据某个属性对查询集进行去重并统计数量,你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求: 方法1:使用annotate()和Count 假设你有一个模型Item,并且你想…...
【HTML-16】深入理解HTML中的块元素与行内元素
HTML元素根据其显示特性可以分为两大类:块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...
NLP学习路线图(二十三):长短期记忆网络(LSTM)
在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...
SpringCloudGateway 自定义局部过滤器
场景: 将所有请求转化为同一路径请求(方便穿网配置)在请求头内标识原来路径,然后在将请求分发给不同服务 AllToOneGatewayFilterFactory import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; impor…...
学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”
2025年#高考 将在近日拉开帷幕,#AI 监考一度冲上热搜。当AI深度融入高考,#时间同步 不再是辅助功能,而是决定AI监考系统成败的“生命线”。 AI亮相2025高考,40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕,江西、…...
Hive 存储格式深度解析:从 TextFile 到 ORC,如何选对数据存储方案?
在大数据处理领域,Hive 作为 Hadoop 生态中重要的数据仓库工具,其存储格式的选择直接影响数据存储成本、查询效率和计算资源消耗。面对 TextFile、SequenceFile、Parquet、RCFile、ORC 等多种存储格式,很多开发者常常陷入选择困境。本文将从底…...
七、数据库的完整性
七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...
