QT 设计一个串口调试工具,用一个工程就能轻松解决,外加虚拟串口工具模拟调试,在日常工作中可类比模块间通信,非常详细建议收藏

news2024/11/16 11:46:13

QT 串口调试工具

  • 第一节 虚拟串口工具安装
  • 第二节 QT创建一个基于QWidget的项目
  • 第三节 UI界面设计
  • 第三节 项目头文件widget.h
  • 第四节 项目实现文件widget.cpp
  • 第五节 main函数
  • 第六节 编译结果重点
  • 第七节 使用QT打包程序,不安装QT的电脑可使用

在这里插入图片描述


第一节 虚拟串口工具安装

-----------------------------------------下载所需工具---------------------------------------------------------------------
链接:https://pan.baidu.com/s/1QkT36S4EnH2HEAhZ1TZ8ug?pwd=ilqg
提取码:ilqg

在这里插入图片描述
-------------------------------------首先点击.exe文件-----------------------------------------------------------------------
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

------------------------------------安装在指定目录等下要用--------------------------------------------------
将vspdctl.dll替换掉你安装文件的所在目录,不然出现错误,就掉头发了哦
在这里插入图片描述

-------------------------------------打开软件看看有啥---------------------------------------------------=
注意:请记住这里的操作,后面还要用到
在这里插入图片描述
-------------------------------------------通过上面的操作,出现以下界面,说明设置成功---------------------
点击电脑—管理—设备管理器–端口–可以看到成功了
在这里插入图片描述


第二节 QT创建一个基于QWidget的项目

在这里插入图片描述
项目.pro添加以下信息

# 添加串口
QT      += serialport

在这里插入图片描述


第三节 UI界面设计

这里不多说,只要是按钮都要转到槽,具体槽函数请看源代码
在这里插入图片描述

第三节 项目头文件widget.h

使用两个串口对象实现

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QSerialPort>          //提供访问串口得到功能
#include <QSerialPortInfo>   //提供系统中存在的串口信息
#include <QMessageBox>    //信息弹出框
#include <QDebug>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

//使用枚举保存波特率
typedef enum
{
    B1200 =1200,
    B9600 = 9600,
    B115200 = 115200,
    B921600 = 921600
}Baud;

class Widget : public QWidget
{
    Q_OBJECT

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

private slots:
     //接收串口数据
     void SerialPortReadyRead();    //比作COM6
     void Serial2PortReadyRead();  //比作COM7

private slots:
    void on_PB_receive_clicked();
    void on_PB_send_clicked();
    void on_PB_detectserial_clicked();
    void on_PB_openserial_clicked();
    void on_comboBox_b_currentIndexChanged(int index);
    void on_PB_openserial_2_clicked();
    void on_PB_send_2_clicked();

private:
    Ui::Widget *ui;

    QSerialPort serial;   //串口1
    QSerialPort serial2; //串口2
};
#endif // WIDGET_H

-------------------------------------------------------------------------------------------------------------------------------------

第四节 项目实现文件widget.cpp

----------------------实现信号与槽,信号为缓冲区有数据时,槽函数作为接收数据------------------------------------

  //连接信号与槽
    QObject::connect(&serial, SIGNAL(readyRead()),this, SLOT(SerialPortReadyRead()));
    QObject::connect(&serial2, SIGNAL(readyRead()),this, SLOT(Serial2PortReadyRead()));

------------------------------------------------串口对象一次性读取全部----------------------------------------------------------

//串口2接收串口1数据
void Widget::SerialPortReadyRead()
{
    qDebug()<<"===============有数据==================";
    //从缓冲区读取文件
    QByteArray buffer = serial.readAll();
    //获取界面已经读取的数据
    QString recv = ui->plainTextEdit_2->toPlainText();
    recv +=QString(buffer);

    //显示全部
    ui->plainTextEdit_2->appendPlainText(recv);
}
//串口1接收串口2数据
void Widget::Serial2PortReadyRead()
{
    qDebug()<<"===============有数据2==================";
    //从缓冲区读取文件
    QByteArray buffer = serial2.readAll();
    //获取界面已经读取的数据
    QString recv = ui->plainTextEdit->toPlainText();
    recv +=QString(buffer);

    //显示全部
    ui->plainTextEdit->appendPlainText(recv);
}

--------------------------------------------------------------向串口写入数据------------------------------------------------------

//作为串口1
void Widget::on_PB_send_clicked()
{
    //向串口写入数据
    QByteArray data = ui->plainTextEdit_2->toPlainText().toUtf8();
    qDebug()<<"发送数据 data = "<<data;
    serial.write(data);
    if(!serial.isWritable())
        qDebug()<<"写入失败";
}
//作为串口2
void Widget::on_PB_send_2_clicked()
{
    //向串口2写入数据
    QByteArray data = ui->plainTextEdit->toPlainText().toUtf8();
    qDebug()<<"发送数据 data2 = "<<data;
    serial2.write(data);
    if(!serial2.isWritable())
        qDebug()<<"写入失败";
}

-----------------------------------------配置串口并打开--------------------------------------------------------------------

void Widget::on_PB_openserial_clicked()
{
    if(ui->PB_openserial->text() == QString("打开串口1"))
    {
        //设置串口名
        serial.setPortName(ui->comboBox_id->currentText());
        //设置波特率
        serial.setBaudRate(ui->comboBox_b->currentText().toUInt());
        //设置数据位
        switch (ui->comboBox_data->currentIndex())
        {
            case 8:serial.setDataBits(QSerialPort::Data8);break;
            default:break;
        }
        //设置奇偶校验 无
        switch (ui->comboBox_crc->currentIndex())
        {
            case 0:serial.setParity(QSerialPort::NoParity);break;
            default:break;
        }
        //设置停止位
        switch (ui->comboBox_stop->currentIndex())
        {
            case 1:serial.setStopBits(QSerialPort::OneStop);break;
            default:break;
        }
        //设置流控 无
        serial.setFlowControl(QSerialPort::NoFlowControl);

        //打开串口
        if(!serial.open(QIODevice::ReadWrite))
        {
            QMessageBox::about(NULL,"提示","串口1打开失败");
        }
        if(serial.isOpen())
            QMessageBox::about(NULL,"提示","串口1打开成功");
        //下拉菜单控件失能
        ui->comboBox_b->setEnabled(false);
        ui->comboBox_id->setEnabled(false);
        ui->comboBox_crc->setEnabled(false);
        ui->comboBox_data->setEnabled(false);
        ui->comboBox_stop->setEnabled(false);

        ui->PB_openserial->setText(tr("关闭串口1"));
        //发送按键使能
        ui->PB_send->setEnabled(true);
    }
    else
    {
        //关闭串口
        serial.close();

        //下拉使能
        ui->comboBox_b->setEnabled(true);
        ui->comboBox_id->setEnabled(true);
        ui->comboBox_crc->setEnabled(true);
        ui->comboBox_data->setEnabled(true);
        ui->comboBox_stop->setEnabled(true);

         ui->PB_openserial->setText(tr("打开串口1"));

        //发送失能
        ui->PB_send->setEnabled(false);
    }
}

//获取波特率索引
void Widget::on_comboBox_b_currentIndexChanged(int index)
{
     if(ui->comboBox_b->itemText(index).toUInt() == B9600)
     {
         qDebug()<<"itemText = "<<ui->comboBox_b->itemText(index);
         ui->comboBox_b->setCurrentIndex(index);
     }
     else if(ui->comboBox_b->itemText(index).toUInt() == B115200)
     {
         qDebug()<<"itemText = "<<ui->comboBox_b->itemText(index);
         ui->comboBox_b->setCurrentIndex(index);
     }
}


void Widget::on_PB_openserial_2_clicked()
{
    if(ui->PB_openserial_2->text() == QString("打开串口2"))
    {
        //设置串口名
        serial2.setPortName(ui->comboBox_id_2->currentText());
        //设置波特率
        serial2.setBaudRate(ui->comboBox_b->currentText().toUInt());
        //设置数据位
        switch (ui->comboBox_data->currentIndex())
        {
            case 8:serial2.setDataBits(QSerialPort::Data8);break;
            default:break;
        }
        //设置奇偶校验 无
        switch (ui->comboBox_crc->currentIndex())
        {
            case 0:serial2.setParity(QSerialPort::NoParity);break;
            default:break;
        }
        //设置停止位
        switch (ui->comboBox_stop->currentIndex())
        {
            case 1:serial2.setStopBits(QSerialPort::OneStop);break;
            default:break;
        }
        //设置流控 无
        serial2.setFlowControl(QSerialPort::NoFlowControl);

        //打开串口
        if(!serial2.open(QIODevice::ReadWrite))
        {
            QMessageBox::about(NULL,"提示","串口2打开失败");
        }

        if(serial2.isOpen())
            QMessageBox::about(NULL,"提示","串口2打开成功");
        //下拉菜单控件失能
        ui->comboBox_b->setEnabled(false);
        ui->comboBox_id_2->setEnabled(false);
        ui->comboBox_crc->setEnabled(false);
        ui->comboBox_data->setEnabled(false);
        ui->comboBox_stop->setEnabled(false);

        ui->PB_openserial_2->setText(tr("关闭串口2"));
        //发送按键使能
        ui->PB_send_2->setEnabled(true);
    }
    else
    {
        //关闭串口
        serial2.close();

        //下拉使能
        ui->comboBox_b->setEnabled(true);
        ui->comboBox_id_2->setEnabled(true);
        ui->comboBox_crc->setEnabled(true);
        ui->comboBox_data->setEnabled(true);
        ui->comboBox_stop->setEnabled(true);

         ui->PB_openserial_2->setText(tr("打开串口2"));

        //发送失能
        ui->PB_send_2->setEnabled(false);
    }
}

-----------------------------------------------------------------源码------------------------------------------------------------

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

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

    //连接信号与槽
    QObject::connect(&serial, SIGNAL(readyRead()),this, SLOT(SerialPortReadyRead()));
    QObject::connect(&serial2, SIGNAL(readyRead()),this, SLOT(Serial2PortReadyRead()));

    //发送按钮不使能
    ui->PB_send->setDisabled(true);
    ui->PB_send_2->setDisabled(true);
}

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

//串口2接收串口1数据
void Widget::SerialPortReadyRead()
{
    qDebug()<<"===============有数据==================";
    //从缓冲区读取文件
    QByteArray buffer = serial.readAll();
    //获取界面已经读取的数据
    QString recv = ui->plainTextEdit_2->toPlainText();
    recv +=QString(buffer);

    //显示全部
    ui->plainTextEdit_2->appendPlainText(recv);
}
//串口1接收串口2数据
void Widget::Serial2PortReadyRead()
{
    qDebug()<<"===============有数据2==================";
    //从缓冲区读取文件
    QByteArray buffer = serial2.readAll();
    //获取界面已经读取的数据
    QString recv = ui->plainTextEdit->toPlainText();
    recv +=QString(buffer);

    //显示全部
    ui->plainTextEdit->appendPlainText(recv);
}


void Widget::on_PB_receive_clicked()
{
    //清空接收框数据
    ui->plainTextEdit->clear();
    ui->plainTextEdit_2->clear();
}
//作为串口1
void Widget::on_PB_send_clicked()
{
    //向串口写入数据
    QByteArray data = ui->plainTextEdit_2->toPlainText().toUtf8();
    qDebug()<<"发送数据 data = "<<data;
    serial.write(data);
    if(!serial.isWritable())
        qDebug()<<"写入失败";
}
//作为串口2
void Widget::on_PB_send_2_clicked()
{
    //向串口2写入数据
    QByteArray data = ui->plainTextEdit->toPlainText().toUtf8();
    qDebug()<<"发送数据 data2 = "<<data;
    serial2.write(data);
    if(!serial2.isWritable())
        qDebug()<<"写入失败";
}
//检测串口
void Widget::on_PB_detectserial_clicked()
{
    //清空串口id
    ui->comboBox_id->clear();
    ui->comboBox_id_2->clear();

    //通过这个类查找可用串口1
    foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
    {
        qDebug()<<"info.portName() = "<<info.portName();
        ui->comboBox_id->addItem(info.portName());
    }

    //通过这个类查找可用串口2
    foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
    {
        qDebug()<<"info.portName() = "<<info.portName();
        ui->comboBox_id_2->addItem(info.portName());
    }
}

void Widget::on_PB_openserial_clicked()
{
    if(ui->PB_openserial->text() == QString("打开串口1"))
    {
        //设置串口名
        serial.setPortName(ui->comboBox_id->currentText());
        //设置波特率
        serial.setBaudRate(ui->comboBox_b->currentText().toUInt());
        //设置数据位
        switch (ui->comboBox_data->currentIndex())
        {
            case 8:serial.setDataBits(QSerialPort::Data8);break;
            default:break;
        }
        //设置奇偶校验 无
        switch (ui->comboBox_crc->currentIndex())
        {
            case 0:serial.setParity(QSerialPort::NoParity);break;
            default:break;
        }
        //设置停止位
        switch (ui->comboBox_stop->currentIndex())
        {
            case 1:serial.setStopBits(QSerialPort::OneStop);break;
            default:break;
        }
        //设置流控 无
        serial.setFlowControl(QSerialPort::NoFlowControl);

        //打开串口
        if(!serial.open(QIODevice::ReadWrite))
        {
            QMessageBox::about(NULL,"提示","串口1打开失败");
        }
        if(serial.isOpen())
            QMessageBox::about(NULL,"提示","串口1打开成功");
        //下拉菜单控件失能
        ui->comboBox_b->setEnabled(false);
        ui->comboBox_id->setEnabled(false);
        ui->comboBox_crc->setEnabled(false);
        ui->comboBox_data->setEnabled(false);
        ui->comboBox_stop->setEnabled(false);

        ui->PB_openserial->setText(tr("关闭串口1"));
        //发送按键使能
        ui->PB_send->setEnabled(true);
    }
    else
    {
        //关闭串口
        serial.close();

        //下拉使能
        ui->comboBox_b->setEnabled(true);
        ui->comboBox_id->setEnabled(true);
        ui->comboBox_crc->setEnabled(true);
        ui->comboBox_data->setEnabled(true);
        ui->comboBox_stop->setEnabled(true);

         ui->PB_openserial->setText(tr("打开串口1"));

        //发送失能
        ui->PB_send->setEnabled(false);
    }
}

//获取波特率索引
void Widget::on_comboBox_b_currentIndexChanged(int index)
{
     if(ui->comboBox_b->itemText(index).toUInt() == B9600)
     {
         qDebug()<<"itemText = "<<ui->comboBox_b->itemText(index);
         ui->comboBox_b->setCurrentIndex(index);
     }
     else if(ui->comboBox_b->itemText(index).toUInt() == B115200)
     {
         qDebug()<<"itemText = "<<ui->comboBox_b->itemText(index);
         ui->comboBox_b->setCurrentIndex(index);
     }
}


void Widget::on_PB_openserial_2_clicked()
{
    if(ui->PB_openserial_2->text() == QString("打开串口2"))
    {
        //设置串口名
        serial2.setPortName(ui->comboBox_id_2->currentText());
        //设置波特率
        serial2.setBaudRate(ui->comboBox_b->currentText().toUInt());
        //设置数据位
        switch (ui->comboBox_data->currentIndex())
        {
            case 8:serial2.setDataBits(QSerialPort::Data8);break;
            default:break;
        }
        //设置奇偶校验 无
        switch (ui->comboBox_crc->currentIndex())
        {
            case 0:serial2.setParity(QSerialPort::NoParity);break;
            default:break;
        }
        //设置停止位
        switch (ui->comboBox_stop->currentIndex())
        {
            case 1:serial2.setStopBits(QSerialPort::OneStop);break;
            default:break;
        }
        //设置流控 无
        serial2.setFlowControl(QSerialPort::NoFlowControl);

        //打开串口
        if(!serial2.open(QIODevice::ReadWrite))
        {
            QMessageBox::about(NULL,"提示","串口2打开失败");
        }

        if(serial2.isOpen())
            QMessageBox::about(NULL,"提示","串口2打开成功");
        //下拉菜单控件失能
        ui->comboBox_b->setEnabled(false);
        ui->comboBox_id_2->setEnabled(false);
        ui->comboBox_crc->setEnabled(false);
        ui->comboBox_data->setEnabled(false);
        ui->comboBox_stop->setEnabled(false);

        ui->PB_openserial_2->setText(tr("关闭串口2"));
        //发送按键使能
        ui->PB_send_2->setEnabled(true);
    }
    else
    {
        //关闭串口
        serial2.close();

        //下拉使能
        ui->comboBox_b->setEnabled(true);
        ui->comboBox_id_2->setEnabled(true);
        ui->comboBox_crc->setEnabled(true);
        ui->comboBox_data->setEnabled(true);
        ui->comboBox_stop->setEnabled(true);

         ui->PB_openserial_2->setText(tr("打开串口2"));

        //发送失能
        ui->PB_send_2->setEnabled(false);
    }
}


第五节 main函数

#include "widget.h"

#include <QApplication>

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

第六节 编译结果重点

在这里插入图片描述


在这里插入图片描述


在这里插入图片描述


在这里插入图片描述


在这里插入图片描述


--------------------------------不想编写两个串口的,安装的串口助手里面有一个工具----------------------------------
在这里插入图片描述
在这里插入图片描述
可以看到,可以实现所需的功能

第七节 使用QT打包程序,不安装QT的电脑可使用

第一步QT编译使用如下
在这里插入图片描述
第二部,执行上述以后,去以下目录复制.exe文件到一个新建的文件夹
在这里插入图片描述
以管理员身份打开cmd,进入的这个新建的文件夹

windeployqt.exe 你的.exe文件名

在这里插入图片描述

由于没有一台未安装QT的电脑作为模拟,有些遗憾
为了提高成功率打开如下:
在这里插入图片描述

cd D:\Qt\Qt5.14.2\Tools\QtCreator\bin

进入以上目录,执行如下命令

D:\Qt\Qt5.14.2\5.14.2\mingw73_64>windeployqt.exe C:\Users\ll\Desktop\QT串口工具\QSerialPort.exe

在这里插入图片描述

在这里插入图片描述

-------------------------------------本次任务over-----------------------------------------------------------

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

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

相关文章

【C++】模拟map和set以及改造红黑树

文章目录1、set和map的基础用法1.1 set的基本使用1.2 map的基本使用2、set和map的模拟实现2.1 建立map和set类2.1 红黑树的完善1、set和map的基础用法 stl中&#xff0c;像vector、list、deque等这样的容器&#xff0c;称之为序列式容器&#xff0c;其底层是线性序列的数据结构…

RabbitMQ学习(九):延迟队列

一、延迟队列概念延时队列中&#xff0c;队列内部是有序的&#xff0c;最重要的特性就体现在它的延时属性上&#xff0c;延时队列中的元素是希望 在指定时间到了以后或之前取出和处理。简单来说&#xff0c;延时队列就是用来存放需要在指定时间内被处理的 元素的队列。其实延迟…

005 利用fidder抓取app的api,获得股票数据

一、下载安装fidder 百度搜索fidder直接下载&#xff0c;按提示安装即可。 二、配置fidder 1. 打开fidder&#xff0c;选择tools——options。 2. 选择HTTPS选项卡&#xff0c;勾选前三项&#xff0c;然后点击右侧【actions】&#xff0c;选择【trust root certificate】&a…

七大排序经典排序算法

吾日三省吾身&#xff1a;高否&#xff1f;富否&#xff1f;帅否&#xff1f;答曰&#xff1a;否。滚去学习!!!(看完这篇文章先)目前只有C和C的功底&#xff0c;暂时还未开启新语言的学习&#xff0c;但是大同小异&#xff0c;语法都差不多。目录&#xff1a;一.排序定义二.排序…

fuzz测试之libfuzzer使用小结

fuzz测试之libfuzzer使用小结背景基本原理使用方法主调DEMO参考资料背景 项目中&#xff0c;为测试算法的鲁棒性&#xff0c;经常会用到fuzz测试进行压力测试。fuzz测试是一种模糊测试方法&#xff0c;本质是通过灌入各种变异的随机数据&#xff0c;去遍历不同函数分支&#xf…

蓝桥杯训练day1

前缀和差分1.前缀和(1)3956. 截断数组(2)795. 前缀和(3)796. 子矩阵的和(4)1230. K倍区间(5)99. 激光炸弹2.差分(1)797. 差分(2)差分矩阵(3)3729. 改变数组元素(4)100. 增减序列1.前缀和 (1)3956. 截断数组 方法1&#xff1a;暴力 先用两个数组分别保存前缀和&#xff0c;后缀…

如何快速、全面、深入地掌握一门编程语言

思考路线 如何快速&#xff1f; 什么样的Demo才能让人觉得你掌握了它&#xff1f; 空 判断&#xff1a;构造一个可以判断所有空的 is_empty 函数 for 循环&#xff1a;i 和 集合迭代两种 时间获取&#xff1a;年/月/日 时分秒 时间戳与时间格式互转 休眠时间函数 字符串处理…

对比学习MoCo损失函数infoNCE理解(附代码)

MoCo loss计算采用的损失函数是InfoNCE&#xff1a; ​​ 下面是MoCo的伪代码&#xff0c;MoCo这个loss的实现就是基于cross entropy loss。 将k作为q的正样本&#xff0c;因为k与q是来自同一张图像的不同视图&#xff1b;将queue作为q的负样本&#xff0c;因为queue中含有大量…

【Python学习笔记】44.Python3 MongoDB和urllib

前言 本章介绍Python的MongoDB和urllib。 Python MongoDB MongoDB 是目前最流行的 NoSQL 数据库之一&#xff0c;使用的数据类型 BSON&#xff08;类似 JSON&#xff09;。 PyMongo Python 要连接 MongoDB 需要 MongoDB 驱动&#xff0c;这里我们使用 PyMongo 驱动来连接。…

Ansys Zemax / SPEOS | 光源文件转换器

本文解释了如何在 SPEOS 与 Zemax 之间转换二进制光源文件。 下载 联系工作人员获取附件 简介 在本文中&#xff0c;为用户提供了一组Python代码&#xff0c;用于在Zemax和SPEOS之间转换源文件。 有些光源&#xff0c;如 .IES 文件&#xff0c;可在 SPEOS 和 Zemax 中进行…

计算机网络 | 谈谈TCP的流量控制与拥塞控制

文章目录一、TCP的流量控制1、利用滑动窗口实现流量控制【⭐⭐⭐】2、如何破解【死锁】局面❓二、TCP的拥塞控制1、拥塞控制的一般原理① 解决网络拥塞的误区② 拥塞控制与流量控制的关系【重点理解✔】2、TCP的拥塞控制方法① 接收窗口【rwnd】与拥塞窗口【cwnd】② 慢开始和拥…

BPE(Byte-Pair Encoding)简介

文章目录BPE简介Vocabulary构建Encoding and DecodingBPE简介 BPE是一种数据压缩算法的简单形式&#xff0c;数据中最常见的连续字节对被替换成该数据中不存在的字节。BPE的主要目标就是使用最少的token数目来表示一个corpus 在 A New Algorithm for Data Compression中首次提…

Spring IOC 容器 Bean 加载过程

Spring IOC 容器 Bean 加载过程 Spring 对于我们所有的类对象进行了统一抽象&#xff0c;抽象为 BeanDefinition &#xff0c;即 Bean 的定义&#xff0c;其中定义了类的全限定类名、加载机制、初始化方式、作用域等信息&#xff0c;用于对我们要自动装配的类进行生成。 Sprin…

新版本 | 异步复制、交易日历、自定义状态函数......请查收!

大家好~DolphinDB 最新版本近日已经发布&#xff0c;本次的 V2.00.9 与 V1.30.21 新版本推出了很多新功能&#xff0c;并对数据库做了全方位提升&#xff0c;是迄今为止新增功能最多的一次更新。新特性一览我们先来看一看新特性包含哪些方面&#xff1a;1、数据库针对数据安全和…

管理.模型.SWOT

1. SWOT 在企业战略规划中&#xff0c;通过辨析企业自身的竞争优势&#xff08;Strengths&#xff09;、劣势&#xff08;Weaknesses&#xff09;和外部环境为企业带来的机会&#xff08;Opportunities&#xff09;和威胁&#xff08; Threats&#xff09;&#xff0c;企业可制…

Interview系列 - 05 Java|Iterator迭代器|集合继承体系|Set List Map接口特性|List实现类区别

文章目录01. 迭代器 Iterator 是什么&#xff1f;02. 迭代器 Iterator 有什么特点&#xff1f;03. 迭代器 Iterator 怎么使用&#xff1f;04. 如何边遍历边移除 Collection 中的元素&#xff1f;05. Iterator 和 ListIterator 有什么区别&#xff1f;06. 数组和集合的区别&…

Alist ——本地网盘管理器

Alist ——本地网盘管理器 一、下载工具 Alist https://github.com/alist-org/alist二、启动登录 进入下载好的文件中&#xff0c;在地址栏输入cmd进入命令行启动 进入命令行输入 alist start启动 记住密码&#xff0c;和端口进入浏览器 输入 &#xff1a;127.0.0.1:5244用…

java final关键字 详解

概述&#xff1a;作用&#xff1a;细节&#xff1a;演示&#xff1a;总结&#xff1a;一、概述 : final [ˈ faɪnl]&#xff0c;最终的&#xff0c;最后的&#xff0c;决定性的&#xff0c;不可改变的。final作为Java中的一个关键字可以用来修饰类&#xff0c;方法&#xff0c…

【程序人生】从土木专员到网易测试工程师,薪资翻3倍,他经历了什么?

转行对于很多人来说&#xff0c;是一件艰难而又纠结的事情&#xff0c;或许缺乏勇气&#xff0c;或许缺乏魄力&#xff0c;或许内心深处不愿打破平衡。可对于我来说&#xff0c;转行是一件不可不为的事情&#xff0c;因为那意味着新的方向、新的希望。我是学工程管理的&#xf…

京东测试进阶之路:初入测试碎碎念篇

1、基本的测试用例设计方法 基本的测试用例设计方法&#xff08;边界值分析、等价类划分等&#xff09;。 业务和场景的积累&#xff0c;了解测试需求以及易出现的bug的地方。 多维角度设计测试用例&#xff08;用户、业务流程、异常场景、代码逻辑&#xff09;。 2、需求分析 …