qt简易网络聊天室 数据库的练习

news2024/11/20 14:37:06

qt网络聊天室

服务器:

配置文件.pro

QT       += core gui network

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++11

# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
    main.cpp \
    widget.cpp

HEADERS += \
    widget.h

FORMS += \
    widget.ui

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

头文件

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QTcpServer>   //服务器类头文件
#include <QDebug>   //信息调试类
#include <QMessageBox>  //消息对话框类头文件
#include <QTcpSocket>  //套接字类头文件

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();


private slots:
    void on_startBtn_clicked();
    void newConnection_slot();   //自定义处理newConnection信号的函数
    void readyRead_slot();   //自定义处理readyRead信号的槽函数

private:
    Ui::Widget *ui;

    //定义一个服务器指针
    QTcpServer *server;

    //定义一个客户端容器
    QList<QTcpSocket *> clientList;
};
#endif // WIDGET_H

源文件

main.cpp

#include "widget.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();
    return a.exec();
}

widget.cpp

//服务器
//1、实例化服务器类对象,该对象就是服务器
//2、服务器调用成员函数listen()将服务器设置为被动监听状态,监听时可以指定主机地址,也可以any监听所有的主机地址。 端口号若为0,则服务器自动分配,也可指定端口号
//3、若有客户端连接,则服务器会发送一个newconnection信号,连接到对应的槽函数中处理相关逻辑
//4、在处理connect信号的槽函数中,使用nextPendingConntiin获取最新连接的客户端套接字
//5、将获取的套接字存入客户端容器中
//6、若客户端有数据项向服务器发送,则客户端套接字会自动发射一个readyRead信号,来凝结到对应的槽函数中处理相关逻辑
//7、在处理readyRead信号的槽函数中,来读取数据,
//7-1、先循环遍历哪些套接字是无效的(断开连接的客户端),将其从客户端容器中删除,使用state函数判断状态,为0则是断开连接的,不为0不是断开的
//7-2、在循环遍历判断是哪个客户端发来的数据,使用BytesAviable来判断哪个客户端有数据,为0则代表无
//7-3、若有数据,使用read readLine readAll函数读取数据,
//11、向套接字中写数据,可以使用write函数


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

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    //给服务器实例化对象
    server = new QTcpServer(this);  //该对象就是服务器,服务器创建完成


}

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


//启动服务器的槽函数
void Widget::on_startBtn_clicked()
{
    if(ui->portEdit->text().isEmpty())
    {
        QMessageBox::critical(this, "失败", "端口号不可为空");
        return;
    }

    //调用成员函数listen()将服务器设置为被动监听状态
    //函数原型:bool listen(const QHostAddress &address = QHostAddress::Any, quint16 port = 0);
    //参数1:主机号,any监听所有的主机地址, 指定主机地址,监听指定的主机地址。
    //参数2:通过哪个端口号访问服务器,若为0,则服务器自由分配,若不为0,则指定要监听的端口号, quint16 是无符号的16位整型, short
    //返回值,成功返回真,失败返回假

    //获取端口号
    quint16 port = ui->portEdit->text().toUInt();  //toUInt(), 转为无符号整型

    if(!server->listen(QHostAddress::Any, port))
    {
        QMessageBox::critical(this, "失败", "服务器启动失败");
        return;
    }
    else
    {
        QMessageBox::information(this, "成功", "服务器启动成功");
    }

    //此时说明服务器启动成功,并对客户端进行监听
    //若有客户端发送连接请求,则服务器会自动发射一个newconnection信号
    //将给信号连接到对应的槽函数中
    connect(server, &QTcpServer::newConnection, this, &Widget::newConnection_slot);
}

//处理newConnection函数的槽函数的实现
void Widget::newConnection_slot()
{

    //循环遍历,从客户端套接字容器中删去已断开连接的客户端套接字

    //函数原型:SocketState state() const;
    //功能:判断套接字的状态
    //参数,无
    //返回值:返回套接字的状态(枚举, 0代表断开连接)
    for(int i = 0; i<clientList.count(); i++)
    {
        if(0 == clientList.at(i)->state())
        {
            //移除下标为i的无效的客户端
            clientList.removeAt(i);
        }
    }
     //获取新连接的客户端的套接字
     //函数原型:virtual QTcpSocket *nextPendingConnection();
    //功能:获取新连接的客户端的套接字
    //无参,返回值就是获取到的客户端的套接字的指针
    QTcpSocket *s = server->nextPendingConnection();

    //将获取到的套接字存入到客户端套接字容器中
   clientList.push_back(s);

  //此时客户端和服务器建立连接
  //如果套接字有数据项发送给服务器时,该套接字自动发射一个readyRead信号
   //将readyRead信号连接到对应的槽函数中处理相关逻辑
   connect(s, &QTcpSocket::readyRead, this, &Widget::readyRead_slot);

}

//自定义处理readyRead信号的槽函数的实现
void Widget::readyRead_slot()
{
    //遍历判断是哪个客户端套发来的数据
    //使用BytesAvalible函数,若无数据可读则为0
    for(int i=0; i<clientList.count(); i++)
    {
        if(clientList[i]->bytesAvailable() != 0)
        {
            //读取套接字中的数据,可用read/readall/readline
            //函数原型QByteArray readAll();
            //功能:读取数据
            //无参,返回值,c风格的字符串
            QByteArray msg = clientList[i]->readAll();

            //将数据展示到ui界面上
            ui->msgList->addItem(QString::fromLocal8Bit(msg));  //将C风格的字符串转为QString类型的

            //将接收到的消息发送给所有的客户端
            for(int j=0; j<clientList.count(); j++)
            {
                clientList[j]->write(msg);
            }
        }
    }


}

ui界面

客户端

配置文件.pro

QT       += core gui network

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++11

# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
    main.cpp \
    widget.cpp

HEADERS += \
    widget.h

FORMS += \
    widget.ui

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

头文件

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QTcpSocket>     //客户端头文件
#include <QDebug>        //信息调试类头文件
#include <QMessageBox>  //消息对话框类头文件

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

private slots:
    void on_connectBtn_clicked();
    void connected_slot();  //自定义处理connected信号的槽函数
    void readyRead_slot();  //自定义处理readyRead信号的槽函数

    void on_sendBtn_clicked();

    void on_disConnectBtn_clicked();
    void disconnected_slot();  //自定义处理disconnected信号的槽函数

private:
    Ui::Widget *ui;

    //定义一个客户端指针
    QTcpSocket *client;
};
#endif // WIDGET_H

源文件

main.cpp

#include "widget.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();
    return a.exec();
}

widget.cpp

//客户端
//1、实例化QTcpSocket类对象,该对象就是客户端
//2、调用客户端对象的connecTtoHost的成员函数向服务器发送连接请求,需要给定服务器的ip和端口
//3、如果与服务器连接成功,客户端自动发射一个connected信号,将信号与对应的槽函数进行连接处理相关逻辑即可
//4、如果服务器有数据项向客户端发送,客户端会自动发射一个readyRead信号,将信号连接到对应的槽函数读取数据
//5、若客户端要给服务器发送消息,使用write函数
//6、在处理readyRead信号的槽函数中,使用read/readLine/readAll函数读取数据
//7、使用该客户端对象的disconnectFromHost函数端口与服务器的连接,
//8、如果成功断开则会自动发射disconnected信号,将disconnected信号与对应的槽函数连接处理即可

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


Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    //实例化客户端空间
    client  = new QTcpSocket(this);   //该对象就是客户端,创建客户端成功

    ui->sendBtn->setEnabled(false);
    ui->disConnectBtn->setEnabled(false);

    //若连接成功,则客户端自动发射一个connected信号
    //将connected信号连接到对应的槽函数处理相关逻辑
    //因为只需要连接一次,所以将其写到构造函数中
    connect(client, &QTcpSocket::connected, this, &Widget::connected_slot);

    //若服务器有数据项向客户端发送,客户端会自动发送readyRead信号
    //将readyRead信号与对应的槽函数连接
    //由于只需连接一次,所以写在构造函数中
    connect(client, &QTcpSocket::readyRead, this, &Widget::readyRead_slot);

    //若断开成功,则客户端会自动发射一个disconnected信号
    //连接到对应的槽函数处理即可
    //因只需要连接一次,写在构造函数即可
    connect(client, &QTcpSocket::disconnected, this, &Widget::disconnected_slot);
}

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

//连接服务器按钮的槽函数
void Widget::on_connectBtn_clicked()
{
    if(ui->userNameEdit->text().isEmpty() || ui->ipEdit->text().isEmpty() || ui->portEdit->text().isEmpty())
    {
        QMessageBox::critical(this, "Error", "信息填写不完整");
        return;
    }
    //获取服务器的主机地址
    QString ip = ui->ipEdit->text();
    //获取服务器的端口号
    quint16 port = ui->portEdit->text().toUInt();  //toUInt()转化为无符号整数
    //该客户端对象调用成员函数连接服务器
    //函数原型:virtual void connectToHost(const QHostAddress &address, quint16 port, OpenMode mode = ReadWrite);
    //功能:客户端连接服务器
    //参数1:服务器的ip地址
    //参数2:客户端的端口号 , quint16 无符号的16位的整型 short
    //返回值:无
    client->connectToHost(ip, port);

    //顺便向客户端发送一条数据
    QString msg = ui->userNameEdit->text();
    msg = msg+ ": 进入聊天室";

    //使用write函数向服务器发送数据
    client->write(msg.toLocal8Bit());  // toLocal8Bit()转为C风格字符串

    //若连接成功,则客户端自动发射一个connected信号
    //将connected信号连接到对应的槽函数处理相关逻辑
    //因为只需要连接一次,所以将其写到构造函数中
}

//处理connected信号的槽函数的实现
void Widget::connected_slot()
{
    //说明连接成功
    ui->userNameEdit->setEnabled(false);
    ui->ipEdit->setEnabled(false);
    ui->portEdit->setEnabled(false);
    ui->connectBtn->setEnabled(false);
    ui->disConnectBtn->setEnabled(true);
    ui->sendBtn->setEnabled(true);

    //若服务器有数据项向客户端发送,客户端会自动发送readyRead信号
    //将readyRead信号与对应的槽函数连接
    //由于只需连接一次,所以写在构造函数中

}

//处理readyRead信号的槽函数
void Widget::readyRead_slot()
{
    //使用read/readLine/readAll读取数据
    QByteArray msg =client->readAll();
   
    //将读取的数据展示到ui界面上

    ui->msgList->addItem(QString::fromLocal8Bit(msg));

}

//发送按钮的槽函数
void Widget::on_sendBtn_clicked()
{
    //获取用户名
    QString userName = ui->userNameEdit->text();
    //获取文本输入框的内容
    QString msg = ui->textEdit->toPlainText();

    msg = userName + ": " + msg;

    //将数据发送给服务器
    client->write(msg.toLocal8Bit());

    //清空文本输入框
    ui->textEdit->clear();

}

//断开按钮对应的槽函数
void Widget::on_disConnectBtn_clicked()
{
    //告知服务器即将断开连接
    QString userName = ui->userNameEdit->text();
    QString msg = userName + ": 退出聊天室";
    client->write(msg.toLocal8Bit());

    //使用该类对象调用disconnectFromHost断开与服务器的连接
    //函数原型:virtual void disconnectFromHost();
    //无参 无返
    client->disconnectFromHost();

    //若断开成功,则客户端会自动发射一个disconnected信号
    //连接到对应的槽函数处理即可
    //因只需要连接一次,写在构造函数即可
}

void Widget::disconnected_slot()
{
    ui->sendBtn->setEnabled(false);
    ui->disConnectBtn->setEnabled(false);
    ui->userNameEdit->setEnabled(true);
    ui->ipEdit->setEnabled(true);
    ui->portEdit->setEnabled(true);
    QMessageBox::information(this, "退出", "断开成功");
}

ui界面

数据库:
配置文件.pro

QT       += core gui sql

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++11

# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
    main.cpp \
    widget.cpp

HEADERS += \
    widget.h

FORMS += \
    widget.ui

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

头文件

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QSqlDatabase>    //数据库管理类
#include <QSqlQuery>       //执行sql语句对应的类
#include <QSqlRecord>      //记录类
#include <QMessageBox>     //消息对话框类
#include <QDebug>          //信息调试类

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

private slots:
    void on_inputBtn_clicked();

    void on_showBtn_clicked();

    void on_searchBtn_clicked();

    void on_deleteBtn_clicked();

private:
    Ui::Widget *ui;

    //定义一个数据库对象
    QSqlDatabase db;
};
#endif // WIDGET_H

源文件:

main.cpp

#include "widget.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();
    return a.exec();
}

widget.cpp

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

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    //判断数据库对象是否包含了自己使用的数据库,Student.db
    if(!db.contains("Student.db"))
    {
        //添加数据库
        // static QSqlDatabase addDatabase(QSqlDriver* driver, const QString& connectionName = QLatin1String(defaultConnection));
        //参数1:数据库的版本
        //返回值:添加的数据库
        db = QSqlDatabase::addDatabase("QSQLITE");   //表明使用的是Sqlite3版本的数据库

        //给数据库命名
        db.setDatabaseName("Student.db");
    }

    //打开数据库
    if(!db.open())
    {
        QMessageBox::information(this, "提示", "数据库打开失败");
    }

    //此时说明数据库已经创建出来并打开了,就可以创建数据表了
    //创建数据表需要使用sql语句, 需要使用QSQLQuerry对象来完成
    //准备sql语句
//    QString sql = "create table if not exists myTable("
//            "id integer Primary key autoincrement,"
//            "numb integer,"
//            "name varchar(10),"
//            "sex varchar(4))";
    QString sql = "create table if not exists myTable("              //创建表的sql语句
                  "id integer primary key autoincrement,"          //id主键,允许自增
                  "numb integer,"                                   //学号,是整形
                  "name varchar(10),"                               //姓名   字符串
                  "score integer,"
                  "sex varchar(4))";                                 //性别 字符串


    //定义语句执行者
    QSqlQuery queery;
    //使用querry调用成员函数exec执行sql语句
    if(!queery.exec(sql))
    {
        QMessageBox::information(this, "失败", "表格创建失败");
        return;
    }
    else
    {
         QMessageBox::information(this, "成功", "表格创建出成功");
    }
}

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

//录入按钮对应的槽函数
void Widget::on_inputBtn_clicked()
{
    //获取ui界面中要存入数据库中的数据
    int numb_ui = ui->numEdit->text().toUInt();   //获取ui界面的学号
    QString name_ui = ui->nameEdit_2->text();  //获取ui界面的姓名
    int score_ui = ui->scoreEdit_3->text().toUInt();  //获取ui界面上的成绩
    QString sex_ui = ui->sexEdit_4->text();  //获取ui界面上的性别

    //判断是否有漏填数据
    if(numb_ui == 0 || name_ui.isEmpty() || score_ui == 0 || sex_ui.isEmpty())
    {
        QMessageBox::information(this, "提示", "请将数据填写完整");
        return;
    }

    //准备sql语句
    QString sql = QString("insert into myTable(numb, name, score, sex)"
                          "values(%1, '%2', %3, '%4')")
            .arg(numb_ui).arg(name_ui).arg(score_ui).arg(sex_ui);
    qDebug() << sql;

    //定义语句执行者
    QSqlQuery querry;
    //调用执行者的exec()函数执行sql语句
   if(!querry.exec(sql))
   {
       QMessageBox::information(this, "失败", "数据插入失败");
   }
   else
   {
       QMessageBox::information(this, "成功", "数据录入成功");
   }

}

//展示按钮对应的槽函数
void Widget::on_showBtn_clicked()
{
    QString sql = "select * from MyTable";

    //定义语句执行者
    QSqlQuery querry;

    //调用执行者的exec()函数执行sql语句
    if(!querry.exec(sql))
    {
        QMessageBox::information(this, "失败", "查询失败");
        return;
    }
    else
    {
        QMessageBox::information(this, "成功", "查询成功");
    }

    //此时,将查找到的所有结果。全部都放在querry中了
    //可以通过next函数不断遍历查询结果
    int i = 0;   //记录行号
    while(querry.next())
    {
        //遍历的就是任意一组记录querry.record
        //qDebug() << querry.record();

        //querry.record().count();  返回当前记录对应数据项的个数
        //querry.record().count();

        //要找到每条记录中的每个数据
        //qDebug() << querry.record().value(2);
        //querry.record().value(j).toString() //将记录的某一项的转为字符串

        //将数据库中的表格展示到ui界面
        for(int j = 0; j<querry.record().count()-1; j++)
        {
            ui->tableWidget->setItem(i, j, new QTableWidgetItem(querry.record().value(j+1).toString()));
        }
        i++;   //进行下一行
    }
}


void Widget::on_searchBtn_clicked()
{
    //获取学号
    QString name_ui = ui->nameEdit_2->text();
    int numb_ui = ui->numEdit->text().toUInt();

     //sql语句
    QString sql = QString("select * from myTable where numb = %1").arg(numb_ui);

    //定义语句执行者
    QSqlQuery querry;

    //执行者使用exec函数执行sql语句
    if(!querry.exec(sql))
    {
        QMessageBox::information(this , "提示", "查询失败");
        return;
    }
    else
    {
        QMessageBox::information(this , "提示", "查询成功");
    }

    int i = 0;  //行号
    while(querry.next())
    {
        for(int j=0; j<querry.record().count()-1; j++)
        {
            ui->tableWidget->setItem(i, j, new QTableWidgetItem(querry.record().value(j+1).toString()));
        }
    }
}

void Widget::on_deleteBtn_clicked()
{
    QString name_ui = ui->nameEdit_2->text();
    //sql语句
    QString sql = QString("delete from myTable where name = '%1'").arg(name_ui);
    qDebug() << sql;
    //定义语句执行者
    QSqlQuery querry;

    //querry调用自己成员函数执行sql语句
    if(!querry.exec(sql))
    {
        QMessageBox::information(this, "提示", "删除失败");
        return;
    }
    else
    {
        QMessageBox::information(this, "提示", "删除成功");
    }


}

ui界面

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

酷派30/锋尚40/大观40S首发解锁BL+完美root权限+去除密码黑砖线刷修复

早前的中华酷联&#xff0c;随着时代的发展&#xff0c;酷派手机虽热发展的并没有其他手机那么快&#xff0c;但也 是坚强的活了下来。目前主打机型为Cool系列&#xff0c;最高为Cool30机型&#xff0c;并且发布酷派锋尚 40酷派大观40S&#xff0c;起头并进。该系列机型&#x…

动手学深度学习(五)Kaggle房价预测

Kaggle房价数据集&#xff0c;前四个为房价特征&#xff0c;最后一个为标签&#xff08;房价&#xff09;。 一、下载数据集 import numpy as np import pandas as pd import torch from torch import nn from d2l import torch as d2l import hashlib import os import tarfi…

XSS简单介绍

目录 一、认识XSS 1.XSS原理 2.XSS分类 二、XSS漏洞复现 1.搭建靶机进行复现 2.案例解析 2.1第一关 2.2第二关 2.3第三关 2.4第四关 一、认识XSS 1.XSS原理 XSS跨站脚本攻击是指恶意攻击者往Web页面里插入恶意Script代码&#xff0c;当用户浏览该页之时&#xff0c;…

linux并发服务器 —— linux网络编程(七)

网络结构模式 C/S结构 - 客户机/服务器&#xff1b;采用两层结构&#xff0c;服务器负责数据的管理&#xff0c;客户机负责完成与用户的交互&#xff1b;C/S结构中&#xff0c;服务器 - 后台服务&#xff0c;客户机 - 前台功能&#xff1b; 优点 1. 充分发挥客户端PC处理能力…

分布式锁之redis实现

docker安装redis 拉取镜像 docker pull redis:6.2.6 查看镜像 启动容器并挂载目录 需要挂在的data和redis.conf自行创建即可 docker run --restart always -d -v /usr/local/docker/redis/redis.conf:/usr/local/etc/redis/redis.conf -v /usr/local/docker/redis/data:/dat…

leetcode986. 区间列表的交集(java)

区间列表的交集 题目描述贪心 - 合并区间代码演示 题目描述 难度 - 中等 leetcode986. 区间列表的交集 给定两个由一些 闭区间 组成的列表&#xff0c;firstList 和 secondList &#xff0c;其中 firstList[i] [starti, endi] 而 secondList[j] [startj, endj] 。每个区间列表…

【数学建模竞赛】超详细Matlab二维三维图形绘制

二维图像绘制 绘制曲线图 g 是表示绿色 b--o是表示蓝色/虚线/o标记 c*是表示蓝绿色(cyan)/*标记 ‘MakerIndices,1:5:length(y) 每五个点取点&#xff08;设置标记密度&#xff09; 特殊符号的输入 序号 需求 函数字符结构 示例 1 上角标 ^{ } title( $ a…

Arthas教程 - 命令篇 (二)

目录 一、Attach 黏附一个进程 1.1 准备代码 1.2 启动Demo 1.3 启动arthas 1.4 通过浏览器连接arthas 二、常用命令 2.1 dashboard 仪表盘 2.2 cls 清屏 2.3 thread 线程 2.4 jad 反编译类 2.5 watch 监视 2.6 退出arthas 三、基础命令 3.1 help 3.2 cat 3.3 …

小米新机代号“Manet”:搭载高通8 Gen 3 处理器 + 金属中框设计

根据数码闲聊站和体验more的消息爆料&#xff0c;小米Redmi K70 Pro被代号为“Manet”&#xff0c;将搭载高通SM8650处理器&#xff0c;这是骁龙8 Gen 3移动平台的一部分。该处理器基于台积电N4P工艺制程打造&#xff0c;具有强大的性能表现。 CPU包含1*3.19GHz X45*2.96GHz A7…

Python Opencv实践 - 矩形轮廓绘制(直边矩形,最小外接矩形)

import cv2 as cv import numpy as np import matplotlib.pyplot as pltimg cv.imread("../SampleImages/stars.png") plt.imshow(img[:,:,::-1])img_gray cv.cvtColor(img, cv.COLOR_BGR2GRAY) #通过cv.threshold转换为二值图 ret,thresh cv.threshold(img_gray,…

Error from server (NotFound): pods “nginx-57d84f57dc-b866m“ not found

原因&#xff1a;机房断电&#xff0c;导致服务重启 [rootmaster1 logs]# kubectl get pod NAME READY STATUS RESTARTS AGE nginx-57d84f57dc-57fkf 1/1 Running 0 75s [rootmaster1 logs]# kubectl logs -f nginx-5…

nginx使用详解

文章目录 一、前言二、nginx使用详解2.1、nginx特点2.2 静态文件处理2.3 反向代理2.4 负载均衡2.5 高级用法2.5.1 正则表达式匹配2.5.2 重定向 三、总结 一、前言 本文将详细介绍nginx的各个功能使用&#xff0c;主要包括 二、nginx使用详解 2.1、nginx特点 高性能&#xff…

【JVM】垃圾收集算法

文章目录 分代收集理论标记-清除算法标记-复制算法标记-整理算法 分代收集理论 当前商业虚拟机的垃圾收集器&#xff0c;大多数都遵循了“分代收集”&#xff08;Generational Collection&#xff09;[1]的理论进 行设计&#xff0c;分代收集名为理论&#xff0c;实质是一套符…

C#循环定时上传数据,失败重传解决方案,数据库标识

有些时候我们需要定时的上传一些数据库的数据&#xff0c;在数据不完整的情况下可能上传失败&#xff0c;上传失败后我们需要定时在重新上传失败的数据&#xff0c;该怎么合理的制定解决方案呢&#xff1f;下面一起看一下&#xff1a; 当然本篇文章只是提供一个思路&#xff0…

windows系统bat脚本调用powershell脚本

前言 项目上有些项目既使用了bat脚本&#xff0c;又使用了powershell脚本&#xff1b; 需要两种脚本配合使用&#xff1b; bat调用powershell 不隐藏窗口运行 bat脚本代码&#xff1a;执行当前路径下的1.ps1脚本文件 start powershell .\1.ps1pause powershell脚本代码&…

025: vue父子组件中传递方法控制:$emit,$refs,$parent,$children

第025个 查看专栏目录: VUE ------ element UI 专栏目标 在vue和element UI联合技术栈的操控下&#xff0c;本专栏提供行之有效的源代码示例和信息点介绍&#xff0c;做到灵活运用。 &#xff08;1&#xff09;提供vue2的一些基本操作&#xff1a;安装、引用&#xff0c;模板使…

prometheus通过blackbox-exporter监控web站点证书

1 概述 线上站点普遍是https&#xff0c;因此监控https web站点的证书的过期时间&#xff0c;是一个基础性需求。例如&#xff0c;证书过期会导致tls握手失败&#xff0c;进而导致用户无法正常访问web站点。 blackbox-expoter是一个web服务&#xff0c;它暴露了一个接口&#…

如何在面试中处理竞争与压力

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

WebSocket与SSE区别

一&#xff0c;websocket WebSocket是HTML5下一种新的协议&#xff08;websocket协议本质上是一个基于tcp的协议&#xff09; 它实现了浏览器与服务器全双工通信&#xff0c;能更好的节省服务器资源和带宽并达到实时通讯的目的 Websocket是一个持久化的协议 websocket的原理 …

算法笔记:二叉树

1 基本二叉树 二叉树是一种树形数据结构&#xff0c;其中每个节点最多有两个子节点&#xff0c;通常称为“左子节点”和“右子节点”。 二叉树的根是唯一没有父节点的节点&#xff0c;而所有其他节点都有一个父节点和零个或两个子节点。 1.1 基础术语 节点&#xff08;Node&…