【QT】系统-下

在这里插入图片描述

欢迎来到Cefler的博客😁
🕌博客主页:折纸花满衣
🏠个人专栏:QT

在这里插入图片描述


目录

  • 👉🏻QThead
    • run()
  • 👉🏻QMutex
  • 👉🏻QWaitCondition
  • 👉🏻QUdpSocket
    • 常用API
  • 👉🏻QNetworkDatagram
  • 👉🏻Udp实现客户端和服务端回显
  • 👉🏻QTcpServer 和 QTcpSocket
    • TCP回显客户端和服务端
  • 👉🏻HTTP
    • QNetworkAccessManager
    • QNetworkRequest
    • QNetworkReply
    • http发起网络请求
  • 👉🏻音视频
      • QMediaPlayer
      • QVideoWidget

👉🏻QThead

QThread是Qt框架中用于多线程编程的基类,它提供了创建和管理线程的能力。以下是QThread的一些常用API:
在这里插入图片描述

run()

在这里插入图片描述
根据官方文档,我们需要重写run函数

  1. 创建 QThread 的子类

通常,你会通过继承 QThread 并重写其 run() 方法来创建自定义的线程类。run() 方法包含了线程将要执行的代码。

#include <QThread>class WorkerThread : public QThread
{Q_OBJECTpublic:void run() override {// 在这里编写线程要执行的代码// 例如,一个耗时的循环for (int i = 0; i < 5; ++i) {QThread::sleep(1); // 模拟耗时操作qDebug() << "Working in thread" << QThread::currentThreadId();}}
};
  1. 创建并启动线程

然后,你可以创建 WorkerThread 的实例,并调用其 start() 方法来启动线程。start() 方法会自动调用 run() 方法。

#include <QCoreApplication>int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);WorkerThread *worker = new WorkerThread();worker->start(); // 启动线程// 主线程可以继续执行其他任务qDebug() << "Working in main thread" << QThread::currentThreadId();// 等待线程完成worker->wait();delete worker;return a.exec();
}

👉🏻QMutex

QMutex 是 Qt 框架中用于管理对共享资源的互斥访问的一个类。在多线程程序中,多个线程可能会尝试同时访问同一个资源(如内存中的变量、文件句柄等),这可能导致数据损坏或不一致。QMutex 提供了一种机制来确保在同一时间内只有一个线程可以访问特定的资源。

基本使用

  1. 包含头文件

在你的 Qt 项目中,使用 QMutex 之前需要包含相应的头文件:

#include <QMutex>
  1. 创建 QMutex 实例

你可以在你的类内部或外部创建一个 QMutex 的实例。通常,这个实例会被声明为类的成员变量,以便在整个类中都能访问它。

QMutex mutex;

或者作为类的成员:

class MyClass {
public:MyClass() {}void someFunction() {// 使用 mutex}private:QMutex mutex;
};
  1. 锁定和解锁
  • 锁定(Lock):在访问共享资源之前,你需要锁定 QMutex。这可以通过调用 lock() 方法实现。如果 QMutex 已经被另一个线程锁定,当前线程将被阻塞,直到 QMutex 被解锁。
mutex.lock();
// 访问共享资源
// ...
  • 解锁(Unlock):完成资源访问后,你需要通过调用 unlock() 方法来解锁 QMutex,以便其他线程可以访问该资源。
// 完成资源访问
mutex.unlock();
  1. 使用 QMutexLocker(推荐)

虽然直接调用 lock()unlock() 方法可以工作,但 Qt 推荐使用 QMutexLocker 类来自动管理锁的获取和释放。QMutexLocker 是一个在构造时自动锁定 QMutex,在析构时自动解锁 QMutex 的类。这有助于避免忘记解锁或在发生异常时未解锁的问题。

QMutex mutex;void someFunction() {QMutexLocker locker(&mutex);// 访问共享资源// ...// 当离开此作用域时,locker 对象被销毁,自动调用 unlock()
}

注意事项

  • 避免死锁:确保在程序中不会以循环的方式锁定多个 QMutex,这可能导致死锁。
  • 锁粒度:尽量减小锁的范围,只在必要时锁定,以提高程序的并发性能。
  • 锁的性能:虽然 QMutex 提供了必要的同步机制,但过多的锁操作可能会降低程序的性能。在设计多线程程序时,要仔细考虑锁的使用。

使用 QMutex 可以帮助你在 Qt 程序中安全地管理多线程对共享资源的访问。

👉🏻QWaitCondition

QWaitCondition是Qt框架中用于线程间同步的一个重要机制,它允许线程等待某个条件的发生,并在条件满足时被唤醒。以下是QWaitCondition的基本使用方法:

  1. 基本概念
  • 条件变量:QWaitCondition本质上是一个条件变量,用于线程间的同步。
  • 互斥锁:QWaitCondition通常与QMutex一起使用,以确保在访问共享资源或条件时的线程安全。
  1. 主要函数
  • wait(QMutex* mutex, unsigned long time = ULONG_MAX):使当前线程在指定的互斥锁上等待条件的发生。如果条件未满足,线程将阻塞;如果指定了超时时间(time),则线程将在超时后继续执行。
  • wakeOne():唤醒在QWaitCondition上等待的一个线程(如果有的话)。
  • wakeAll():唤醒在QWaitCondition上等待的所有线程。
  1. 使用步骤

等待条件

  1. 锁定互斥锁:在调用wait()之前,必须首先锁定一个互斥锁,以保护共享资源和条件变量。
  2. 调用wait():调用QWaitCondition的wait()函数,传入之前锁定的互斥锁。wait()函数内部会释放互斥锁,使其他线程可以修改条件或共享资源。当条件满足时,或超时时间到达时,wait()函数将返回,并重新获取互斥锁。
  3. 检查条件:从wait()返回后,应检查条件是否真正满足,因为可能存在“虚假唤醒”(spurious wakeup)的情况。
  4. 解锁互斥锁:在继续执行之前,应解锁互斥锁。

唤醒线程

  1. 锁定互斥锁:在修改条件或共享资源之前,必须首先锁定互斥锁。

  2. 修改条件:根据需要进行操作,以改变条件的状态。

  3. 唤醒线程:使用wakeOne()或wakeAll()函数唤醒等待的线程。

  4. 解锁互斥锁:在完成操作后,应解锁互斥锁。

  5. 示例场景

场景一:单个线程等待条件

QWaitCondition condition;
QMutex mutex;
bool conditionMet = false;// 等待条件的线程
mutex.lock();
while (!conditionMet) {condition.wait(&mutex); // 等待条件发生// 处理条件满足后的操作
}
mutex.unlock();// 在其他线程中
mutex.lock();
conditionMet = true; // 设置条件满足
condition.wakeOne(); // 唤醒等待的线程
mutex.unlock();

场景二:多个线程等待同一个条件

QWaitCondition condition;
QMutex mutex;
int counter = 0;// 等待条件的线程1和线程2
mutex.lock();
while (counter < 10) { // 或其他条件condition.wait(&mutex); // 等待条件发生
}
mutex.unlock();// 在其他线程中
mutex.lock();
counter = 15; // 设置条件满足
condition.wakeAll(); // 唤醒所有等待的线程
mutex.unlock();
  1. 注意事项
  • 虚假唤醒:由于系统调度等原因,线程可能会被虚假唤醒。因此,在wait()返回后,应检查条件是否真正满足。
  • 超时等待:wait()函数支持超时等待,可以在条件长时间未满足时避免线程永久挂起。
  • 线程安全:QWaitCondition和QMutex的所有操作都是线程安全的,可以在多线程环境中安全使用。

通过以上介绍,可以了解到QWaitCondition在Qt多线程编程中的基本使用方法和重要性。

👉🏻QUdpSocket

QUdpSocket是Qt框架中用于UDP网络通信的一个类,它继承自QAbstractSocket,提供了发送和接收UDP数据报的功能。UDP(User Datagram Protocol,用户数据报协议)是一种轻量级、不可靠、面向数据报的无连接协议,适用于对可靠性要求不高的场合。以下是对QUdpSocket的详细介绍:

一、基本概念

  • UDP协议:UDP是一种无连接的协议,每个数据报都是独立传输的,不会建立持久的socket连接。因此,UDP通信具有较低的延迟和较高的灵活性,但数据可能会丢失、乱序或重复。
  • QUdpSocket:QUdpSocket类用于在Qt应用程序中实现UDP网络通信。通过它,可以发送和接收UDP数据报,实现单播、广播和组播等多种通信模式。

二、主要功能

  1. 数据报发送

    • QUdpSocket提供了多个重载的writeDatagram方法来发送数据报。这些方法允许你指定目标地址(IP地址)和端口号,并将数据(通常是QByteArray类型)发送到指定的UDP客户端。
    • 数据报的长度一般建议不超过512字节,因为较大的数据报可能会被网络层分片,增加传输的复杂性和错误率。
  2. 数据报接收

    • 在接收数据报之前,通常需要使用bind方法将QUdpSocket绑定到一个端口上,以便监听传入的数据报。
    • 当有数据报到达时,QUdpSocket会发出readyRead信号。你可以在相应的槽函数中使用readDatagramreceiveDatagram方法来读取数据报。
    • readDatagram方法允许你指定一个缓冲区来接收数据报,并可选地获取发送方的地址和端口信息。
  3. 多播和广播

    • QUdpSocket支持UDP多播和广播。通过调用joinMulticastGroup方法,可以将QUdpSocket加入到指定的多播组中,以便接收该组内的数据报。
    • 要进行广播,只需将目标地址设置为特殊的广播地址(如255.255.255.255),然后发送数据报即可。在同一网络范围内的所有UDP客户端都可以接收到这个广播数据报。

三、使用注意事项

  • 端口号选择:通常选择1024到65535之间的端口号进行UDP通信。1024以下的端口号通常保留给系统或特定应用程序使用。
  • 数据报大小:如前所述,建议发送的数据报大小不超过512字节。如果需要发送更大的数据量,可以考虑将数据拆分成多个较小的数据报进行发送。
  • 错误处理:在使用QUdpSocket进行UDP通信时,需要注意处理可能发生的错误情况,如网络不可达、端口已被占用等。可以通过检查QUdpSocket的状态或捕获相关的异常来进行错误处理。

四、示例代码

以下是一个简单的QUdpSocket使用示例,展示了如何发送和接收UDP数据报:

// 发送数据报
QUdpSocket udpSocket;
QByteArray datagram = "Hello, UDP!";
udpSocket.writeDatagram(datagram.data(), datagram.size(), QHostAddress::LocalHost, 12345);// 接收数据报
udpSocket.bind(QHostAddress::LocalHost, 54321);
connect(&udpSocket, &QUdpSocket::readyRead, this, &MyClass::readPendingDatagrams);void MyClass::readPendingDatagrams() {while (udpSocket.hasPendingDatagrams()) {QByteArray datagram;datagram.resize(udpSocket.pendingDatagramSize());QHostAddress sender;quint16 senderPort;udpSocket.readDatagram(datagram.data(), datagram.size(), &sender, &senderPort);// 处理接收到的数据报...}
}

在这个示例中,首先创建了一个QUdpSocket对象,并使用writeDatagram方法发送了一个UDP数据报。然后,使用bind方法将QUdpSocket绑定到一个端口上,以便接收数据报。最后,通过连接readyRead信号到槽函数readPendingDatagrams来读取和处理接收到的数据报。

常用API

  1. 构造函数和析构函数

    • QUdpSocket(QObject *parent = nullptr): 构造函数,可以指定父对象。
    • ~QUdpSocket(): 析构函数,清理资源。
  2. 绑定端口

    • bool bind(const QHostAddress &address = QHostAddress::Any, quint16 port = 0, BindMode mode = DefaultForPlatform): 将QUdpSocket绑定到指定的地址和端口上,以便接收数据报。
  3. 发送数据报

    • qint64 writeDatagram(const char *data, qint64 size, const QHostAddress &address, quint16 port): 发送一个数据报到指定的地址和端口。
    • qint64 writeDatagram(const QByteArray &datagram, const QHostAddress &host, quint16 port): 发送一个QByteArray类型的数据报到指定的地址和端口。
  4. 接收数据报

    • qint64 pendingDatagramSize() const: 返回下一个待接收的数据报的大小(字节)。
    • qint64 readDatagram(char *data, qint64 maxSize, QHostAddress *address = nullptr, quint16 *port = nullptr): 读取一个数据报到指定的缓冲区,并可选地获取发送方的地址和端口。
    • qint64 receiveDatagram(char *data, qint64 maxSize, QHostAddress *address = nullptr, quint16 *port = nullptr): 与readDatagram类似,但在某些平台上可能更可靠。
  5. 连接和断开

    • 注意:QUdpSocket是无连接的,因此没有像TCP那样的connectdisconnect方法来建立或断开连接。但是,你可以通过bind来监听端口,并通过writeDatagram来发送数据报。
  6. 信号

    • void readyRead(): 当有新的数据报到达时发出此信号。
    • void errorOccurred(QAbstractSocket::SocketError socketError): 当发生错误时发出此信号,提供错误类型。
  7. 状态查询

    • QAbstractSocket::SocketState state() const: 返回QUdpSocket的当前状态(如未连接、监听中等)。
    • QAbstractSocket::SocketError error() const: 返回最后发生的错误类型。
  8. 多播和广播

    • bool joinMulticastGroup(const QHostAddress &groupAddress): 将QUdpSocket加入到指定的多播组中。
    • bool leaveMulticastGroup(const QHostAddress &groupAddress): 离开之前加入的多播组。

这些API提供了QUdpSocket进行UDP网络通信所需的基本功能。需要注意的是,由于UDP是无连接的协议,因此在使用QUdpSocket时,不需要像TCP那样建立连接,而是直接发送和接收数据报。

👉🏻QNetworkDatagram

QNetworkDatagram 简介

QNetworkDatagram 是 Qt 网络模块中的一个类,用于处理 UDP 数据报。它可以在无连接的情况下发送和接收数据,非常适合实时通信和小数据量的传输。

基本用法

  1. 创建 QNetworkDatagram
    你可以通过提供数据和目标地址来创建一个 QNetworkDatagram 对象。

    QByteArray data = "Hello, UDP!";
    QHostAddress address = QHostAddress::Broadcast; // 或者指定具体地址
    quint16 port = 1234;QNetworkDatagram datagram(data, address, port);
    
  2. 发送数据报
    使用 QUdpSocket 类来发送 QNetworkDatagram

    QUdpSocket udpSocket;
    udpSocket.writeDatagram(datagram);
    
  3. 接收数据报
    设置一个 QUdpSocket 来接收数据报,并在可读事件中处理它。

    QUdpSocket udpSocket;
    udpSocket.bind(QHostAddress::Any, port); // 绑定到指定端口connect(&udpSocket, &QUdpSocket::readyRead, [&]() {while (udpSocket.hasPendingDatagrams()) {QNetworkDatagram datagram = udpSocket.receiveDatagram();// 处理接收到的数据qDebug() << "Received:" << datagram.data() << "from" << datagram.senderAddress() << ":" << datagram.senderPort();}
    });
    

应用场景

  1. 实时通信:例如,在线游戏、视频会议等应用程序,使用 UDP 以减少延迟。
  2. 广播和多播:可以通过设置目标地址为广播地址或多播地址,向多个客户端发送数据。
  3. 传感器数据采集:在物联网应用中,常用于从传感器收集小量数据。

总结

QNetworkDatagram 是一个非常有用的类,可以简化 UDP 数据报的处理。结合 QUdpSocket,你可以方便地实现高效的网络通信。需要注意的是,UDP 是无连接协议,因此不保证数据的可靠性或顺序。在设计应用时,应根据需求权衡使用。

👉🏻Udp实现客户端和服务端回显

代码链接:Udp实现客户端和服务端回显
实现效果:
在这里插入图片描述

👉🏻QTcpServer 和 QTcpSocket

QTcpServerQTcpSocket 是 Qt 网络模块中用于 TCP 网络通信的类。下面是它们的常用 API 和基本用法:

QTcpServer

QTcpServer 用于创建 TCP 服务器,监听客户端的连接请求。

常用 API
在这里插入图片描述

  1. listen():

    • 启动服务器并开始监听指定的端口。
    • 示例:
      server->listen(QHostAddress::Any, port);
      
  2. nextPendingConnection():

    • 返回下一个挂起的客户端连接。
    • 示例:
      QTcpSocket *clientSocket = server->nextPendingConnection();
      
  3. hasPendingConnections():

    • 检查是否有挂起的连接。
  4. close():

    • 关闭服务器。
  5. 信号:

    • newConnection(): 当有新的客户端连接时发出。

QTcpSocket

QTcpSocket 用于与 TCP 服务器或其他客户端进行网络通信。

常用 API
在这里插入图片描述

  1. connectToHost():

    • 连接到指定的主机和端口。
    • 示例:
      socket->connectToHost("hostname", port);
      
  2. disconnectFromHost():

    • 断开与主机的连接。
  3. write():

    • 发送数据到远程主机。
    • 示例:
      socket->write("Hello, Server!");
      
  4. readAll():

    • 读取所有可用的数据。
  5. state():

    • 获取当前连接状态。
  6. 信号:

    • readyRead(): 当有新数据可读时发出。
    • connected(): 当成功连接到主机时发出。
    • disconnected(): 当与主机断开连接时发出。

示例用法

以下是一个简单的 TCP 服务器和客户端示例:

TCP 服务器示例

QTcpServer *server = new QTcpServer(this);
connect(server, &QTcpServer::newConnection, this, [&]() {QTcpSocket *clientSocket = server->nextPendingConnection();connect(clientSocket, &QTcpSocket::readyRead, [&]() {QByteArray data = clientSocket->readAll();// 处理接收到的数据clientSocket->write("Response from server");});
});
server->listen(QHostAddress::Any, 1234);

TCP 客户端示例

QTcpSocket *socket = new QTcpSocket(this);
connect(socket, &QTcpSocket::connected, this, [&]() {socket->write("Hello, Server!");
});
connect(socket, &QTcpSocket::readyRead, this, [&]() {QByteArray response = socket->readAll();// 处理服务器响应
});
socket->connectToHost("127.0.0.1", 1234);

TCP回显客户端和服务端

代码链接:
效果:
在这里插入图片描述
在这里插入图片描述

👉🏻HTTP

进⾏ Qt 开发时, 和服务器之间的通信很多时候也会⽤到 HTTP 协议

QNetworkAccessManager

QNetworkAccessManager 是 Qt 中用于处理网络请求的核心类。以下是一些关键方法:

  1. get(): 发起一个 GET 请求,返回 QNetworkReply 对象。
  2. post(): 发起一个 POST 请求,允许发送数据,返回 QNetworkReply 对象。
  3. put(): 发起一个 PUT 请求,适用于更新资源,返回 QNetworkReply 对象。
  4. deleteResource(): 发起一个 DELETE 请求,用于删除资源。
  5. sendCustomRequest(): 发送自定义请求,适用于不常见的 HTTP 方法。

QNetworkRequest

QNetworkRequest 是用于描述网络请求的类。以下是一些核心方法和常用取值:

核心方法

  1. setUrl(const QUrl &url): 设置请求的 URL。
  2. setHeader(QNetworkRequest::Header header, const QVariant &value): 设置请求头,比如 Content-Type
  3. setRawHeader(const QByteArray &headerName, const QByteArray &headerValue): 设置自定义请求头。
  4. setAttribute(QNetworkRequest::Attribute attribute, const QVariant &value): 设置请求属性,比如 SSL 配置。
  5. setPriority(QNetworkRequest::Priority priority): 设置请求的优先级。

常用取值

  • Headers:

    • QNetworkRequest::ContentTypeHeader: 表示内容类型。
    • QNetworkRequest::ContentLengthHeader: 表示内容长度。
  • Attributes:

    • QNetworkRequest::RedirectPolicyAttribute: 设置重定向策略。
    • QNetworkRequest::HttpPipeliningAllowedAttribute: 允许 HTTP 管道化。

QNetworkReply

QNetworkReply 是 Qt 中用于处理网络响应的类。以下是一些核心方法:

核心方法

  1. abort(): 取消当前的请求。
  2. bytesAvailable(): 返回当前可读取的字节数。
  3. readAll(): 读取所有响应数据并返回为 QByteArray
  4. error(): 返回请求过程中出现的错误类型。
  5. attribute(): 获取请求的某个特定属性值。
  6. rawHeaderList(): 返回所有原始响应头的名称列表。
  7. rawHeader(const QByteArray &headerName): 获取特定响应头的值。
  8. url(): 返回请求的 URL。
  9. finished(): 检查请求是否完成,通常用于信号槽连接。

http发起网络请求

#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);//实例化对象manager = new QNetworkAccessManager(this);
}Widget::~Widget()
{delete ui;
}void Widget::on_pushButton_clicked()
{//1.构造QUrl对象QUrl url(ui->lineEdit->text());//2.构造request对象QNetworkRequest request(url);//3.发起get请求QNetworkReply* reply = manager->get(request);//4.通过信号槽来处理响应connect(reply,&QNetworkReply::finished,this,[=](){if(reply->error()==QNetworkReply::NoError){//说明请求成功QString html(reply->readAll());ui->plainTextEdit->setPlainText(html);}else{ui->plainTextEdit->setPlainText(reply->errorString());}reply->deleteLater();});}

在这里插入图片描述

👉🏻音视频

QMediaPlayerQVideoWidget 是 Qt Multimedia 模块中的两个重要类,用于处理音视频播放。以下是它们的一些基本方法。

QMediaPlayer

QMediaPlayer 用于播放音频和视频。常用方法包括:

  1. setMedia(const QMediaContent &media): 设置要播放的媒体内容,可以是文件路径或网络流。
  2. play(): 开始播放媒体。
  3. pause(): 暂停播放。
  4. stop(): 停止播放。
  5. setVolume(int volume): 设置音量,范围通常是 0 到 100。
  6. position(): 获取当前播放位置(毫秒)。
  7. duration(): 获取媒体总时长(毫秒)。
  8. state(): 获取播放器的当前状态(播放、暂停、停止等)。
  9. error(): 检查是否有错误发生。

QVideoWidget

QVideoWidget 用于显示视频内容。常用方法包括:

  1. setMediaPlayer(QMediaPlayer *player): 将 QMediaPlayer 关联到此视频窗口。
  2. resizeEvent(QResizeEvent *event): 重载此方法以处理大小调整事件(可选)。
  3. show(): 显示视频窗口。
  4. setAspectRatio(Qt::AspectRatioMode aspectRatioMode): 设置视频的显示比例。

如上便是本期的所有内容了,如果喜欢并觉得有帮助的话,希望可以博个点赞+收藏+关注🌹🌹🌹❤️ 🧡 💛,学海无涯苦作舟,愿与君一起共勉成长
在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/429768.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C/C++内存管理 ——

目录 五、C/C内存管理 1、C/C内存分布 2、C语言中动态内存管理方式&#xff1a;malloc/calloc/realloc/free 3、C内存管理方式 1.new/delete操作内置类型 2.new和delete操作自定义类型 4、operator new与operator delete函数 5、new和delete的实现原理 1.内置类…

分布式事务详细笔记:什么是分布式事务--Seata--XA模式--AT模式

目录 1.分布式事务 1.1.什么是分布式事务 1.2.认识Seata 1.3.部署TC服务 1.3.1.准备数据库表 1.3.2.准备配置文件 1.3.3.Docker部署 1.4.微服务集成Seata 1.4.1.引入依赖 1.4.2.改造配置 1.4.3.添加数据库表 1.5.XA模式 1.5.1.两阶段提交 1.5.2.Seata的XA模型 1…

网络原理 HTTP与HTTPS协议

博主主页: 码农派大星. 数据结构专栏:Java数据结构 数据库专栏:MySQL数据库 JavaEE专栏:JavaEE 关注博主带你了解更多计算机网络知识 目录 1.HTTP概念 2.HTTP报文格式 3.HTTP请求 1.首行 1.1URL 1.2 GET⽅法 1.3 POST⽅法 1.4 其他⽅法 2.请求头&#xff08;head…

专业学习|动态规划(概念、模型特征、解题步骤及例题)

一、引言 &#xff08;一&#xff09;从斐波那契数列引入自底向上算法 &#xff08;1&#xff09;知识讲解 &#xff08;2&#xff09;matlap实现递归 &#xff08;3&#xff09;带有备忘录的遗传算法 &#xff08;4&#xff09;matlap实现带有备忘录的递归算法 “&#xff1…

使用库函数点亮一个LED灯

软件设计 STM32Gpio的介绍 如果想让LED0点亮&#xff0c;那么R12就要是高电平&#xff0c;LED0就要是低电平&#xff0c;也就是PF9就是低电平 F407系统主频要工作在168MHZ F103的话是工作在72mhz F429的话就180MHZ 接着我们就要使能Gpio的时钟&#xff0c;使能之后对GPIO相关…

c++----io流

提示&#xff1a;以下 是本篇文章正文内容&#xff0c;下面案例可供参考 1.标准io流 (1)数据的循环输入 对于内置类型&#xff1a;cin和cout直接使用&#xff0c;c已经重载了 (2)对于自定义类型&#xff1a; 需要我们自己对类型进行重载 2.文件io流 ifstream ifile(只输入…

着色器 简介

着色器&#xff08;Shader&#xff09;是运行在 GPU 上的小程序。这些小程序为图形渲染管线的某个特定部分而运行。从基本意义上来说&#xff0c;着色器只是一种把输入转化为输出的程序。着色器也是一种非常独立的程序&#xff0c;因为它们之间不能相互通信&#xff1b;它们之间…

【洛谷】P10417 [蓝桥杯 2023 国 A] 第 K 小的和 的题解

【洛谷】P10417 [蓝桥杯 2023 国 A] 第 K 小的和 的题解 题目传送门 题解 CSP-S1 补全程序&#xff0c;致敬全 A 的答案&#xff0c;和神奇的预言家。 写一下这篇的题解说不定能加 CSP 2024 的 RP 首先看到 k k k 这么大的一个常数&#xff0c;就想到了二分。然后写一个判…

中序遍历二叉树全过程图解

文章目录 中序遍历图解总结拓展&#xff1a;回归与回溯 中序遍历图解 首先看下中序遍历的代码&#xff0c;其接受一个根结点root作为参数&#xff0c;判断根节点是否为nil&#xff0c;不为nil则先递归遍历左子树。 func traversal(root *TreeNode,res *[]int) {if root nil …

ArcGIS核密度分析(栅格处理范围与掩膜分析)

多时候我们在进行栅格分析的时候&#xff0c;处理的结果不能完全覆盖我们需要的范围。 比如&#xff0c;我们对点数据进行密度分析、栅格插值等。比如下图 为什么会如此呢&#xff1f; 那是因为在做这个密度分析或者栅格插值的时候&#xff0c;默认是以点的四至范围来生成的&am…

国内可以使用的ChatGPT服务【9月持续更新】

首先基础知识还是要介绍得~ 一、模型知识&#xff1a; GPT-4o&#xff1a;最新的版本模型&#xff0c;支持视觉等多模态&#xff0c;OpenAI 文档中已经更新了 GPT-4o 的介绍&#xff1a;128k 上下文&#xff0c;训练截止 2023 年 10 月&#xff08;作为对比&#xff0c;GPT-4…

探索 Web Speech API:实现浏览器语音识别与合成

引言 Web Speech API 是一项由 W3C 开发的 Web 标准&#xff0c;为开发者提供了在 Web 应用程序中实现语音识别和语音合成的能力。通过 Web Speech API&#xff0c;我们可以让网页与用户进行语音交互&#xff0c;实现更加智能化和便捷的用户体验。本文将深入探讨 Web Speech A…

第十二周:机器学习

目录 摘要 Abstract 一、非监督学习 二、word embedding 三、transformer 1、应用 2、encoder 3、decoder 四、各类attention 1、最常见的类别 2、其余种类 3、小结 总结 摘要 本周继续学习机器学习的相关课程&#xff0c;首先了解了监督学习和非监督学习的概…

Flink Task 日志文件隔离

Flink Task 日志文件隔离 任务在启动时会先通过 MdcUtils 启动一个 slf4j 的 MDC 环境&#xff0c;然后将 jobId 添加到 slf4j 的 MDC 容器中&#xff0c;随后任务输出的日志都将附带 joid。 MDC 介绍如下&#xff1a; MDC ( Mapped Diagnostic Contexts )&#xff0c;它是一个…

文件操作和InputStream,OutputStream的用法

“他越拧巴&#xff0c;我越喜欢&#xff01;” 文件&#xff1a; 此处谈到的文件&#xff0c;本身有很多的含义。 狭义上的文件&#xff0c;特指 硬盘上的文件&#xff08;以及保存文件的目录&#xff09;。 广义上的文件&#xff0c;计算机上的很多硬件设备&#xff0c;软…

idea2021git从dev分支合并到主分支master

1、新建分支 新建一个名称为dev的分支&#xff0c;切换到该分支下面&#xff0c;输入新内容 提交代码到dev分支的仓库 2、切换分支 切换到主分支&#xff0c;因为刚刚提交的分支在dev环境&#xff0c;所以master是没有 3、合并分支 点击push&#xff0c;将dev里面的代码合并到…

【Web】御网杯信息安全大赛2024 wp(全)

目录 input_data admin flask 如此多的FLAG 一夜醒来之全国CTF水平提升1000倍&#x1f60b; input_data 访问./.svn后随便翻一翻拿到flag admin dirsearch扫出来 访问./error看出来是java框架 测出来是/admin;/路由打Spring View Manipulation(Java)的SSTI https:/…

C++容器list底层迭代器的实现逻辑~list相关函数模拟实现

目录 1.两个基本的结构体搭建 2.实现push_back函数 3.关于list现状的分析&#xff08;对于我们如何实现这个迭代器很重要&#xff09; 3.1和string,vector的比较 3.2对于list的分析 3.3总结 4.迭代器类的封装 5.list容器里面其他函数的实现 6.个人总结 7.代码附录 1.两…

Selenium with Python学习笔记整理(网课+网站持续更新)

本篇是根据学习网站和网课结合自己做的学习笔记&#xff0c;后续会一边学习一边补齐和整理笔记 官方学习网站在这获取&#xff1a; https://selenium-python.readthedocs.io/getting-started.html#simple-usage WEB UI自动化环境配置 (推荐靠谱的博客文章来进行环境配置,具…

Fyne ( go跨平台GUI )中文文档- 架构 (八)完结

本文档注意参考官网(developer.fyne.io/) 编写, 只保留基本用法 go代码展示为Go 1.16 及更高版本, ide为goland2021.2 这是一个系列文章&#xff1a; Fyne ( go跨平台GUI )中文文档-入门(一)-CSDN博客 Fyne ( go跨平台GUI )中文文档-Fyne总览(二)-CSDN博客 Fyne ( go跨平台GUI…