Qt项目:网络1

文章目录

  • 项目:网路
    • 项目1:主机信息查询
      • 1.1 QHostInfo类和QNetworkInterface类
      • 1.2 主机信息查询项目实现
    • 项目2:基于HTTP的网络应用程序
      • 2.1 项目中用到的函数详解
      • 2.2 主要源码

项目:网路


项目1:主机信息查询

在这里插入图片描述

使用QHostInfo类和QNetworkInterface类可以获取主机的一些网络信息,如IP地址1和MAC地址2

在Qt项目里使用Qt Network模块,需要在项目配置文件(.pro 文件)中增加一条配置语句:
QT += network


1.1 QHostInfo类和QNetworkInterface类

QHostInfo类常用函数

QHostInfo类可以根据主机名获取主机的IP地址,或者通过IP地址获取主机名。

  • [static] QString QHostInfo::localHostName():返回本机主机名;
  • [static] QString QHostInfo::localDomainName():返回本机域名系统(domain name system,DNS)域名;
  • [static] QHostInfo QHostInfo::fromName(const QString &name):返回指定主机名的IP地址;
  • [static] int QHostInfo::lookupHost(const QString &name, QObject *receiver, const char *member):以异步的方式根据主机名查找主机的IP地址,并返回一个表示本次查找的ID,可用作abortHostLookup()函数的参数;
  • [static] void QHostInfo::abortHostLookup(int id):使用 lookupHost() 返回的 ID 终止主机查找。
  • QList<QHostAddress> QHostInfo::addresses() const:返回与hostName()对应主机关联的IP地址列表;
  • QString QHostInfo::hostName() const:返回通过IP地址查找到的主机名;

QNetworkInterface类常用的函数

QNetworkInterface类可以获得运行程序的主机名的所用IP地址和网络接口列表。

  • [static] QList QNetworkInterface::allAddresses():返回主机上所有IP地址的列表(如果不需要知道子网掩码和广播地址);
  • [static] QList QNetworkInterface::allInterfaces():返回主机上所有网络接口列表(一个网络接口可能包含多个IP地址,每个IP地址与掩码或广播地址关联);
  • QList QNetworkInterface::addressEntries() const:返回网络接口的IP地址列表,包括子网掩码和广播地址;
  • QString QNetworkInterface::hardwareAddress() const:返回接口的低级硬件地址,以太网里就是MAC地址;
  • bool QNetworkInterface::isValid() const:如果接口信息有效就返回true;
  • QNetworkInterface::InterfaceType QNetworkInterface::type() const:返回网络接口的类型;

1.2 主机信息查询项目实现

  1. 显示本机地址信息
//获取本机主机名和IP地址按钮
void Widget::on_btnGetHostInfo_clicked()
{
    ui->plainTextEdit->clear();
    QString hostName = QHostInfo::localHostName();  //本机主机名
    qDebug()<<hostName;
    ui->plainTextEdit->appendPlainText("HostName:"+hostName+"\n");

    QHostInfo hostInfo = QHostInfo::fromName(hostName); //本机IP地址
    QList<QHostAddress> addrList = hostInfo.addresses();//IP地址列表
    if(addrList.isEmpty()) return;
    foreach(QHostAddress host, addrList){
        bool show = ui->checkBox_OnlyIPV4->isChecked(); //只显示ipv4
        //Returns the network layer protocol of the host address.
        show = show ? (host.protocol() == QAbstractSocket::IPv4Protocol):true;
        if(show){
            ui->plainTextEdit->appendPlainText("protool:"+protocolName(host.protocol()));//协议
            ui->plainTextEdit->appendPlainText("HostIPAdddress:"+host.toString());
            ui->plainTextEdit->appendPlainText(QString("isGolbal() = %1\n").arg(host.isGlobal()));
        }
    }
}

protocol()函数:返回主机地址的网络层协议

QAbstractSocket::NetworkLayerProtocol QHostAddress::protocol() const
Returns the network layer protocol of the host address.

isGlobal()函数:如果地址是 IPv4 或 IPv6 全局地址,则返回 true,否则返回 false。全局地址是不为特殊目的(如环回或多播)或未来目的保留的地址。

bool QHostAddress::isGlobal() const
Returns true if the address is an IPv4 or IPv6 global address, false otherwise. A global address is an address that is not reserved for special purposes (like loopback or multicast) or future purposes.

自定义函数protocolName(),通过协议类型返回协议名称字符串。

//通过协议类型返回协议名称字符串
QString Widget::protocolName(QAbstractSocket::NetworkLayerProtocol protocol)
{
    switch (protocol) {
    case QAbstractSocket::IPv4Protocol:
        return "IPV4";
    case QAbstractSocket::IPv6Protocol:
        return "IPV6";
    case QAbstractSocket::AnyIPProtocol:
        return "Any Internet Protocol";
    default:
        return "Unknown NetWork Layer Protocol";
    }
}
  1. 查找主机地址信息

[static] int QHostInfo::lookupHost(const QString &name, QObject *receiver, const char *member): name表示主机名的字符串,可以是主机名、域名或IP地址;receive和member指定接收者和槽函数名称。

//查找域名的IP地址
void Widget::on_btnLookkup_clicked()
{
    ui->plainTextEdit->clear();
    QString hostName = ui->comboBox->currentText(); //读取主机名
    ui->plainTextEdit->appendPlainText("Searching for host information:"+hostName+"\n");
    QHostInfo::lookupHost(hostName, this,SLOT(do_lookedUpHostInfo(QHostInfo)));
}

//查找主机信息的槽函数
void Widget::do_lookedUpHostInfo(const QHostInfo &host)
{
    QList<QHostAddress> addrList = host.addresses();    //获取主机地址列表
    if(addrList.isEmpty())return;
    foreach(QHostAddress host, addrList)
    {
        bool show = ui->checkBox_OnlyIPV4->isChecked(); //只显示ipv4
        //Returns the network layer protocol of the host address.
        show = show ? (host.protocol() == QAbstractSocket::IPv4Protocol):true;
        if(show){
            ui->plainTextEdit->appendPlainText("protool:"+protocolName(host.protocol()));//协议
            ui->plainTextEdit->appendPlainText(host.toString());
            ui->plainTextEdit->appendPlainText(QString("isGolbal() = %1\n").arg(host.isGlobal()));
        }
    }
}
  1. QNetworkInterface类的使用

//根据枚举值返回字符串
QString Widget::interfaceType(QNetworkInterface::InterfaceType type)
{
    switch(type){
    case QNetworkInterface::Unknown:
        return "Unkown";
    case QNetworkInterface::Loopback:
        return "Loopback";
    case QNetworkInterface::Ethernet:
        return "Etherent";
    case QNetworkInterface::Wifi:
        return "Wifi";
    default:
        return "Other type";
    }
}

//allInterfaces()
void Widget::on_btnAllInterface_2_clicked()
{
    ui->plainTextEdit->clear();
    QList<QNetworkInterface> list = QNetworkInterface::allInterfaces();//网络接口列表
    foreach(QNetworkInterface interface,list){
        if(!interface.isValid())
            continue;
//        The name of the device
//        Hardware devices
//        Interface type
//        Subnet mask
//        broadcast address
        ui->plainTextEdit->appendPlainText("The name of the device:"+interface.humanReadableName());
        ui->plainTextEdit->appendPlainText("Hardware devices:"+interface.hardwareAddress());
        ui->plainTextEdit->appendPlainText("Interface type:"+interfaceType(interface.type()));
        QList<QNetworkAddressEntry> entryList = interface.addressEntries();//地址列表
        foreach(QNetworkAddressEntry entry, entryList){
            ui->plainTextEdit->appendPlainText("    IP Address:"+entry.ip().toString());
            ui->plainTextEdit->appendPlainText("    Subnet mask:"+entry.netmask().toString());
            ui->plainTextEdit->appendPlainText("    broadcast address:"+entry.broadcast().toString()+"\n");
        }
    }
}

//alladdress
void Widget::on_btnAllAddress_clicked()
{
    ui->plainTextEdit->clear();
    QList<QHostAddress> addrelist = QNetworkInterface::allAddresses();//IP地址列表
    if(addrelist.isEmpty()) return;
    foreach(QHostAddress host, addrelist){
        bool show = ui->checkBox_OnlyIPV4->isChecked();
        show = show ? (host.protocol() == QAbstractSocket::IPv4Protocol):true;
        if(show){
            ui->plainTextEdit->appendPlainText("protocol:"+protocolName(host.protocol()));
            ui->plainTextEdit->appendPlainText("IP Address:"+host.toString());
            ui->plainTextEdit->appendPlainText(QString("isGrobal() = %1\n").arg(host.isGlobal()));
        }
    }
}

Loopback:
回送地址(Loopback Address)是本机回送地址(127.X.X.X),即主机IP堆栈内部的IP地址,主要用于网络软件测试以及本地机进程间通信。因此,无论什么程序,一旦使用回送地址发送数据,协议软件会立即将其返回,不进行任何网络传输。

127.0.0.1是回送地址,又指本地机,一般用来测试使用。

项目2:基于HTTP的网络应用程序

QNetworkRequest 类通过 URL 发起网络协议请求,其也保存网络请求的信息,目前支持 HTTP、
FTP 和本地文件 URL 的下载或上传。
QNetworkAccessManager 类用于协调网络操作,在 QNetworkRequest 发起网络请求后,
QNetworkAccessManager 负责发送网络请求,以及创建网络响应。
QNetworkReply 类表示网络请求的响应,由 QNetworkAccessManager 在发送网络请求后创建网
络响应。QNetworkReply 提供的信号 finished()、readyRead()、downloadProgress()可用于监测网络响
应的执行情况,从而进行相应的操作。

发起网络协议请求
发送网络请求,以及创建网络响应
监测网络响应

在这里插入图片描述

2.1 项目中用到的函数详解

  1. clearButtonEnabled : bool
    此属性用于保存行编辑在不为空时是否显示清除按钮。
    如果启用,行编辑在包含一些文本时会显示一个尾随清除按钮,否则,行编辑不会显示清除按钮(默认值)。

  2. 默认路径按钮功能:

  • [static] QString QDir::currentPath()
    返回应用进程当前目录的绝对路径。当前目录是使用 QDir::setCurrent() 设置的最后一个目录,或者,如果从未调用过,则为父进程启动此应用进程的目录。
  • bool QDir::mkdir(const QString &dirName) const
    创建一个名为 dirName 的子目录。
  1. 下载按钮功能:
  • QString QString::trimmed() const
    返回一个字符串,该字符串删除了开头和结尾的空格。
  • [static] QUrl QUrl::fromUserInput(const QString &userInput)
    从用户提供的 userInput 字符串返回有效的 URL(如果可以扣除)。如果不可能,则返回无效的 QUrl()。
  • QString QUrl::errorString() const
    如果修改此 QUrl 对象的最后一个操作遇到解析错误,则返回错误消息。如果未检测到错误,则此函数返回一个空字符串,isValid() 返回 true。
  • QString QUrl::fileName(QUrl::ComponentFormattingOptions options = FullyDecoded) const
    返回文档名,不包括目录路径。
  • bool QFile::remove()
    删除 fileName() 指定的文档。如果成功,则返回 true;否则返回 false。文档在删除之前已关闭。
  • QNetworkReply *QNetworkAccessManager::get(const QNetworkRequest &request)
    发布一个请求以获取目标请求的内容,并返回一个新的 QNetworkReply 对象,该对象打开以供读取,每当新数据到达时,该对象都会发出 readyRead() 信号。将下载内容以及相关的标题。
  • [signal] void QIODevice::readyRead()
    每当有新数据可用时,此信号就会发出一次从设备的当前读取信道读取。只有当有新数据可用时,它才会再次发出,例如,当新的网络数据有效负载到达您的网络套接字时,或者当新的数据块附加到您的设备时。
  • [signal] void QNetworkReply::downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
    发出此信号以指示此网络请求的下载部分的进度(如果有)。如果没有与此请求关联的下载,则此信号将发出一次,其中 0 作为 bytesReceived 和 bytesTotal 的值。
  • [signal] void QNetworkReply::finished()
    当回复完成处理时,将发出此信号。发出此信号后,回复的数据或元数据将不再更新。
  1. 读取下载数据
  • qint64 QIODevice::write(const char *data, qint64 maxSize)
    将数据中最多 maxSize 字节的数据写入设备。返回实际写入的字节数,如果发生错误,则返回 -1。

  • QByteArray QIODevice::readAll()
    从设备读取所有剩余数据,并将其作为字节数组返回。

2.2 主要源码

头文件

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QNetworkAccessManager>
#include <QFile>
#include <QMessageBox>
#include <QIODevice>
#include <QNetworkReply>
#include <QDesktopServices>
#include <QFileInfo>
#include <QUrl>

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT
private:
    QNetworkAccessManager networkManager;   //网络管理
    QNetworkReply *reply;                   //网络响应
    QFile *downloadedFile;                  //下载保存的临时文件
public:
    explicit Widget(QWidget *parent = nullptr);
    ~Widget();
private slots:
    void do_finished();
    void do_readyRead();
    void do_downloadProgress(qint64 bytesRead, qint64 totalBytes);
    void on_btnDownload_clicked();

    void on_btnDefaultPath_clicked();

    void on_editURL_textChanged(const QString &arg1);

private:
    Ui::Widget *ui;
};

#endif // WIDGET_H

源文件

#include "widget.h"
#include "ui_widget.h"

#include <QDir>

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
//clearButtonEnabled : bool
//This property holds whether the line edit displays a clear button when it is not empty.
//If enabled, the line edit displays a trailing clear button when it contains some text,
//            otherwise the line edit does not show a clear button (the default).
    ui->editURL->setClearButtonEnabled(true);
    this->setLayout(ui->verticalLayout);
}

Widget::~Widget()
{
    delete ui;
}

void Widget::do_finished()
{//网络响应结束
    QFileInfo fileInfo(downloadedFile->fileName()); //获取下载文件的文件名
    downloadedFile->close();
    delete downloadedFile;  //删除临时文件
    reply->deleteLater();   //由主事件循环删除此文件对象
    if(ui->checkBoxOpen->isChecked()){
        QDesktopServices::openUrl(QUrl::fromLocalFile(fileInfo.absoluteFilePath()));
    }
    ui->btnDownload->setEnabled(true);
}

void Widget::do_readyRead()
{
    //读取下载数据
    downloadedFile->write(reply->readAll());
//    qint64 QIODevice::write(const char *data, qint64 maxSize)
//    Writes at most maxSize bytes of data from data to the device.
//            Returns the number of bytes that were actually written,
//            or -1 if an error occurred.
//    QByteArray QIODevice::readAll()
//    Reads all remaining data from the device, and returns it as a byte array.

}

void Widget::do_downloadProgress(qint64 bytesRead, qint64 totalBytes)
{//下载进度
    ui->progressBar->setMaximum(totalBytes);
    //Holds the total amount of data to download in bytes.
    ui->progressBar->setValue(bytesRead);
}


//默认了路径 按钮
void Widget::on_btnDefaultPath_clicked()
{
//    [static] QString QDir::currentPath()
//    Returns the absolute path of the application's current directory.
//            The current directory is the last directory set with QDir::setCurrent() or,
//            if that was never called,
//            the directory at which this application was started at by the parent process.
    QString curPath = QDir::currentPath();  //返回当前绝对路径给QString变量
    QDir dir(curPath);                      //定义QDir变量
    QString sub = "temp";
//    bool QDir::mkdir(const QString &dirName) const
//    Creates a sub-directory called dirName.
    dir.mkdir(sub);                         //当前路径下创立名为sub的文件夹
    ui->editPath->setText(curPath+"/"+sub+"/"); //设置lineedit的文字
}

//下载按钮,开始下载
void Widget::on_btnDownload_clicked()
{
//    QString QString::trimmed() const
//    Returns a string that has whitespace removed from the start and the end.
    QString urlSpec = ui->editURL->text().trimmed();    //将editURL中的文字给QString变量赋值
    //urlspec判空
    if(urlSpec.isEmpty()){
        QMessageBox::information(this,"error","Please specify the download address");
        return;
    }
//    [static] QUrl QUrl::fromUserInput(const QString &userInput)
//    Returns a valid URL from a user supplied userInput string if one can be deducted.
//    In the case that is not possible, an invalid QUrl() is returned.
    QUrl newUrl = QUrl::fromUserInput(urlSpec); //从urlSpaec里获取url
    //newurl判有效
    if(!newUrl.isValid()){
//        QString QUrl::errorString() const
//        Returns an error message if the last operation that modified this QUrl object ran into a parsing error.
//                If no error was detected,
//                this function returns an empty string and isValid() returns true.
        QString info = "The URL is invalid:"+urlSpec+"\n error:"+newUrl.errorString();
        QMessageBox::information(this,"error",info);
        return;
    }

    QString tempDir = ui->editPath->text().trimmed();   //临时目录
    if(tempDir.isEmpty()){
        QMessageBox::information(this,"error","Please specify the download address");
        return;
    }

    QString fullFileName = tempDir + newUrl.fileName(); //文件名
//    QString QUrl::fileName(QUrl::ComponentFormattingOptions options = FullyDecoded) const
//    Returns the name of the file, excluding the directory path.
    if(QFile::exists(fullFileName)){ //如果文件存在
        QFile::remove(fullFileName);    //删除文件
//        bool QFile::remove()
//        Removes the file specified by fileName(). Returns true if successful; otherwise returns false.
//        The file is closed before it is removed.
    }

    downloadedFile = new QFile(fullFileName);   //创建临时文件
    if(!downloadedFile->open(QIODevice::WriteOnly)){
        QMessageBox::information(this,"error","Temporary file open error");
    }
    ui->btnDownload->setEnabled(false);
    //发送网络请求,创建网络相应
    reply = networkManager.get(QNetworkRequest(newUrl));    //网络响应从网络管理里面获取网络请求
//    QNetworkReply *QNetworkAccessManager::get(const QNetworkRequest &request)
//            Posts a request to obtain the contents of the target request and
//            returns a new QNetworkReply object opened for reading
//            which emits the readyRead() signal whenever new data arrives.
//            The contents as well as associated headers will be downloaded.
//    QObject *QObject::parent() const
//    Returns a pointer to the parent object.

    connect(reply, SIGNAL(readyRead()), this, SLOT(do_readyRead()));
    connect(reply, SIGNAL(downloadProgress(qint64,qint64)),
            this, SLOT(do_downloadProgress(qint64,qint64)));
    connect(reply, SIGNAL(finished()), this, SLOT(do_finished()));
//    [signal] void QIODevice::readyRead()
//    This signal is emitted once every time new data is available for
//    reading from the device's current read channel.
//    It will only be emitted again once new data is available,
//    such as when a new payload of network data has arrived on your network socket,
//    or when a new block of data has been appended to your device.
//    [signal] void QNetworkReply::downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
//    This signal is emitted to indicate the progress of the download part of
//    this network request, if there's any. If there's no download associated with this request,
//    this signal will be emitted once with 0 as the value of both bytesReceived and bytesTotal.
//    [signal] void QNetworkReply::finished()
//    This signal is emitted when the reply has finished processing.
//    After this signal is emitted, there will be no more updates to the reply's data or metadata.
}

void Widget::on_editURL_textChanged(const QString &arg1)
{
    Q_UNUSED(arg1);
    ui->progressBar->setMaximum(100);
    ui->progressBar->setValue(0);
}


  1. IP地址(Internet Protocol Address)是指互联网协议地址,又译为网际协议地址。IP地址是IP协议提供的一种统一的地址格式,它为互联网上的每一个网络和每一台主机分配一个逻辑地址,以此来屏蔽物理地址的差异。 ↩︎

  2. MAC地址(英语:Media Access Control Address),直译为媒体存取控制位址,也称为局域网地址(LAN Address),MAC位址,以太网地址(Ethernet Address)或物理地址(Physical Address),它是一个用来确认网络设备位置的位址。在OSI模型中,第三层网络层负责IP地址,第二层数据链路层则负责MAC位址。MAC地址用于在网络中唯一标示一个网卡,一台设备若有一或多个网卡,则每个网卡都需要并会有一个唯一的MAC地址。 ↩︎

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SIMON 32/64加密电路的实现(System Verilog)

关于SIMON加密电路的原理&#xff0c;参考之前发布的博文【SIMON加密算法的原理】 1.总览与电路介绍 1.1 电路总体结构图 1.2 模式配置介绍 SIMON加密算法的分组长度、密钥长度以及必要的参数配置如下图&#xff1a; 本次需要实现的是SIMON 32/64&#xff0c;即分组长度2n3…

【数据结构】B树,B+树,B*树

文章目录 一、B树1.B树的定义2.B树的插入3.B树的中序遍历 二、B树和B*树1.B树的定义2.B树的插入3.B*树的定义4.B树系列总结 三、B树与B树的应用 一、B树 1.B树的定义 1. 在内存中搜索效率高的数据结构有AVL树&#xff0c;红黑树&#xff0c;哈希表等&#xff0c;但这是在内存…

Stable Diffusion 绘画入门教程(webui)-ControlNet(Shuffle)

Shuffle(随机洗牌)&#xff0c;这个预处理器会把参考图的颜色打乱搅拌到一起&#xff0c;然后重新组合的方式重新生成一张图&#xff0c;可以想象出来这是一个整体风格控制的处理器。 那么问题来了&#xff0c;官方为啥会设计个这样的处理器呢&#xff0c;主要是给懒人用的&am…

Atcoder ABC341 E - Alternating String

Alternating String&#xff08;交替字符串&#xff09; 时间限制&#xff1a;3s 内存限制&#xff1a;1024MB 【原题地址】 所有图片源自Atcoder&#xff0c;题目译文源自脚本Atcoder Better! 点击此处跳转至原题 【问题描述】 【输入格式】 每个查询 q u e r y i query…

STM32存储左右互搏 QSPI总线FATS文件读写FLASH W25QXX

STM32存储左右互搏 QSPI总线FATS文件读写FLASH W25QXX FLASH是常用的一种非易失存储单元&#xff0c;W25QXX系列Flash有不同容量的型号&#xff0c;如W25Q64的容量为64Mbit&#xff0c;也就是8MByte。这里介绍STM32CUBEIDE开发平台HAL库Quad SPI总线实现FATS文件操作W25Q各型号…

Vue笔记(一)

常用指令 1.v-show与v-if底层原理的区别 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>创建一个V…

快速搭建宠物医院服务小程序的步骤,无需编程经验

如果你是一家宠物医院或者宠物服务机构&#xff0c;想要拥有一款方便用户预约、查询信息的小程序&#xff0c;那么乔拓云网提供的轻应用小程序是你的不二选择。下面将为你详细介绍如何轻松打造宠物医院服务小程序。 1. 进入乔拓云网后台&#xff0c;点击【轻应用小程序】中的【…

国产服务器操作系统

为何记录 最近的开发工作经常接触到国产服务器操作系统的业务&#xff0c;经常被x86、arm、龙芯、鲲鹏、欧拉...搞得一脸懵逼&#xff0c;遂记之&#xff01; 操作系统 这里按照应用场景分&#xff1a; 桌面操作系统&#xff1a;主要用于pc&#xff0c;如Windows、macOS、Li…

★【递归】【构造二叉树】Leetcode 106.从中序与后序遍历序列构造二叉树

★【递归】【构造二叉树】Leetcode 106.从中序与后序遍历序列构造二叉树 105. 从前序与中序遍历序列构造二叉树 106.从中序与后序遍历序列构造二叉树:star:思路分析递归解法 105. 从前序与中序遍历序列构造二叉树递归解法 ---------------&#x1f388;&#x1f388;题目链接&a…

大语言模型推理加速技术:计算加速篇

原文&#xff1a;大语言模型推理加速技术&#xff1a;计算加速篇 - 知乎 目录 简介 Transformer和Attention 瓶颈 优化目标 计算加速 计算侧优化 KVCache Kernel优化和算子融合 分布式推理 内存IO优化 Flash Attention Flash Decoding Continuous Batching Page…

嵌入式学习第二十一天!(线程)

线程&#xff1a; 1. 基本概念&#xff1a; 线程&#xff1a;线程是一个轻量级的进程&#xff0c;位于进程空间内部&#xff0c;一个进程中可以创建多个线程 2. 线程创建&#xff1a; 线程独占栈空间&#xff0c;文本段、数据段和堆区与进程共享 3. 线程调度&#xff1a; 与进程…

Tomcat 下部署若依单体应用可观测最佳实践

实现目标 采集指标信息采集链路信息采集日志信息采集 RUM 信息会话重放 即用户访问前端的一系列过程的会话录制信息&#xff0c;包括点击某个按钮、操作界面、停留时间等&#xff0c;有助于客户真是意图、操作复现 版本信息 Tomcat (9.0.81)Springboot(2.6.2)JDK (>8)DDT…

2024年软件测试路线,不同等级应具备的基本能力(总结)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 1、软件测试的正确…

大数据可视化的设计规范,全面剖析,很实用。

大数据可视化的设计规范需要考虑到数据量大、复杂度高、数据类型多样等特点。以下是一份常见的大数据可视化设计规范&#xff0c;供您参考&#xff1a; 设计原则 简单易用&#xff1a;保证用户操作简单、直观&#xff0c;降低用户认知负担。数据准确&#xff1a;保证数据准确…

数据可视化引领智慧工业新时代

在智慧工业的大潮中&#xff0c;数据可视化崭露头角&#xff0c;以其直观、清晰的方式赋能工业生产&#xff0c;为智慧工业的高效运转提供了强有力的支持。下面我就以可视化从业者的角度&#xff0c;简单聊聊这个话题。 数据可视化首先在智慧工业的生产监控中大显身手。通过将…

4-Bean的循环依赖

Bean的循环依赖 循环依赖指的是依赖闭环的问题 解决 首先我们来实例化A&#xff0c;实例化A时并没有处理依赖注入&#xff0c;因此会得到半成品A。有了半成品A&#xff0c;它会被封装成一个ObjectFactory&#xff0c;并且把它放入第三个缓存区singletonFactories中。 接下来要…

tmux的使用方法

1. tmux的定义 我&#xff1a;什么是tmux&#xff1f; GPT&#xff1a;tmux&#xff08;terminal multiplexer&#xff09;是一个强大的终端复用器&#xff0c;它允许用户在一个终端窗口中创建、访问和控制多个会话。使用tmux&#xff0c;你可以在一个窗口中打开多个终端会话&…

苍穹外卖 -- day11 - Apache ECharts- 营业额统计- 用户统计- 订单统计- 销量排名Top10

苍穹外卖-day11 课程内容 Apache ECharts 营业额统计 用户统计 订单统计 销量排名Top10 功能实现&#xff1a;数据统计 数据统计效果图&#xff1a; 1. Apache ECharts 1.1 介绍 Apache ECharts 是一款基于 Javascript 的数据可视化图表库&#xff0c;提供直观&#x…

docker 常用指令(启动,关闭,查看运行状态)

文章目录 docker 常用指令启动 docker关闭 docker查看 docker的运行状态 docker 常用指令 启动 docker systemctl start docker关闭 docker systemctl stop docker查看 docker的运行状态 systemctl status docker如下图所示&#xff1a; 表示docker正在运行中

【Vue】

什么是Vue Vue是一款用于构建用户界面的JavaScript框架&#xff0c;它基于标准HTML、CSS和JavaScript构建&#xff0c;并提供了一套声明式的、组件化的编程模型&#xff0c;帮助开发者高效地开发用户界面。Vue是一个JS库&#xff0c;无依赖其他JS库&#xff0c;直接引入一个JS文…