【C++ QT项目实战-03】---- C++ QT系统实现读取JSON文件数据的自动化模式

🎩 欢迎来到技术探索的奇幻世界👨‍💻

📜 个人主页@一伦明悦-CSDN博客

✍🏻 作者简介C++软件开发、Python机器学习爱好者

🗣️ 互动与支持💬评论      👍🏻点赞      📂收藏     👀关注+

如果文章有所帮助,欢迎留下您宝贵的评论!

欢迎点赞加收藏支持我,点击关注,一起进步!


前言      

        本篇在该篇博客的基础上,继续进行系统功能的完善操作,比如,一般生产国臣各种,跟定希望机器是能自动化的,这样即使工作人员不在,生产依然在进行。

【C++ QT项目实战-02】---- C++ QT系统实现基于QT调用RESTful接口访问JSON文件中数据-CSDN博客文章浏览阅读457次,点赞5次,收藏3次。本篇在做项目的基础上进行了项目中难点的一些总结,我们都知道,在如今大数据时代下,数据对项目系统开发起到决定性的作用,可以帮助企业实现实时决策、提升用户体验、实现业务智能、提高系统性能、提供定制化服务和增强业务竞争力等方面的优势,有利于项目系统的发展和成功。因此,在项目系统开发过程中,需要充分重视数据的快速读取和处理能力,以满足日益增长的数据需求和用户期望。https://blog.csdn.net/m0_59951855/article/details/139065776

        项目中的计算等功能已经是自动化模式的,这里的难题就是如何在读取数据的过程中也实现自动化模式,当然,为了便于操作,不仅需要自动化模式,也需要随时可以切换到手动模式。

        这里包含了以下几个难点:

        (1)主系统线程与计算线程是双线程运行,两种模式下,如何进行线程通信?

        (2)自动模式下,系统访问平台的方式,或者说是否需要给定时间,定时访问平台?而不是不停歇的访问。

        (3)自动模式下如何实现系统读完数据直接进行计算,手动模式下又怎样切换?这些也需要进行解决。

        (4)如何判断平台中是否存在数据,当判断之后,又该怎样运行?
        带着这四个问题,将进行详细分析如何实现这些功能,并给出代码解释和功能演示。

正文 

01- 双模式下,主线程与计算线程通信实现   

        主界面上的自动和手动两种模式通过控件进行选择,当选择自动模式时,主线程发送一个信号,通过信号与槽函数的方式与计算线程中的函数进行连接。

        在自动模式下,发送信号 send_cmBox_ToWFC,计算线程中使用函数cmBox_switch()和model_switch()来接收信号并实现各种功能。在手动模式下,发送信号 send_modelcmBox_ToWFC,计算线程中使用函数model_switch_0来接收信号。

这种设计模式可以让你在不同模式下灵活地控制计算线程的行为,实现自动化或手动化操作。

mainwindow.h文件#ifndef MAINWINDOW_H
#define MAINWINDOW_H
/*#include "Mp_Pred.h"*/
#include"ui_mainwindow.h"
#include <QMainWindow>
#include <QLabel>#include "spdlog/fmt/ostr.h"
#include "Zanj_WFC_ctrl.h"
#include <QVariant>
#include "wfc_to_main.h"#include <QtSql/QtSql>
#include <QDateTime>
#include <QTimer>
#include <qtextcodec.h> 
#include <QtWidgets/QApplication>
#include <QtWidgets/QMainWindow>
#include <QtCharts/QChartView>
#include <QtCharts/QBarSeries>
#include <QtCharts/QBarSet>
#include <QtCharts/QLegend>
#include <QtCharts/QBarCategoryAxis>
#include <QMouseEvent>
//一定要声明!!!
#include"dialog_data_log.h"namespace Ui {class MainWindow;
}};
class MainWindow : public QMainWindow
{Q_OBJECTpublic:explicit MainWindow(QWidget *parent = nullptr);~MainWindow();Zanj_WFC_ctrl * m_Zanj_WFC_ctrl; // 预报计算的类QThread * m_Zanj_WFC_ctrl_Thread; //m_Mp_Pred将被移动到此线程执行void connectZanj_WFC_ctrl(Zanj_WFC_ctrl *m_Zanj_WFC_ctrl);signals:void send_cmBox_ToWFC();void send_modelcmBox_ToWFC();mainwindow.cpp文件#include  <QTimer>
#include  <time.h>
#include  <QLabel>
#include  <QValueAxis>
#include  <QMargins>
#include  <QtWidgets/QApplication>
#include  <QtWidgets/QMainWindow>
#include  <QtCharts/QChartView>
#include  <QtCharts/QBarSeries>
#include  <QtCharts/QBarSet>
#include  <QtCharts/QLegend>
#include  <QtCharts/QBarCategoryAxis>
#include <ctime>  using namespace std::literals;
// using namespace fmt;
using namespace std;
namespace spd = spdlog;
auto console_mainWindow = spd::stdout_color_mt("主界面控制台");
auto rotating_logger_mainWindow = spdlog::rotating_logger_mt("baori_CAO8_Winmain_rotating", "logs/baori_CAO8_rotating.logger", 1048576 * 5, 12);MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{ui->setupUi(this);OpenDatabase();//Matlab_mcl_Init();setWindowTitle(QString::fromLocal8Bit("主系统")); // 此处写应用程序在标题栏上显示的名称setStyleSheet("background - color:pink; ");reshow();data_log_tblview();connect(this, &MainWindow::send_cmBox_ToWFC, m_Zanj_WFC_ctrl, &Zanj_WFC_ctrl::cmBox_switch);connect(this, &MainWindow::send_cmBox_ToWFC, m_Zanj_WFC_ctrl, &Zanj_WFC_ctrl::model_switch);connect(this, &MainWindow::send_modelcmBox_ToWFC, m_Zanj_WFC_ctrl, &Zanj_WFC_ctrl::model_switch_0);
}MainWindow::~MainWindow()
{delete ui;
}void MainWindow::deploy_cmBox_switch()
{if (ui->deploy_cmBox->currentText() == QString::fromLocal8Bit("自动模式")){ui->Iplate4j_IP_QLE->setText("127.0.0.1");ui->model_PC_IP_QLE->setText("127.0.0.1");emit send_cmBox_ToWFC();}else if (ui->deploy_cmBox->currentText() == QString::fromLocal8Bit("手动模式")){emit send_modelcmBox_ToWFC();}
}

02-cmBox_switch()函数实现  

        这里接受信号的计算线程的函数分为两个,第一个cmBox_switch()函数是实现打开配置文件和定时访问数据,定时访问数据这里加入死循环,设置30s的时间间隔。

        startSystem()函数的这段代码是一个无限循环,在每次循环中执行以下操作:

         调用 OnGETSlot() 函数:这个函数用于执行数据读取和预测的操作。具体实现可能涉及从网络或文件系统中读取数据,并对数据进行处理和预测。

         调用 this_thread::sleep_for(chrono::seconds(30)):这行代码会使当前线程暂停执行,模拟定时器或轮询间隔。在这个例子中,线程会休眠30秒钟,然后再次执行循环中的操作。        

        整体来说,这段代码实现了一个简单的定时器功能,每隔30秒钟执行一次数据读取和预测的操作,然后再次休眠30秒钟,循环执行这个过程        


计算线程.cpp文件void Zanj_WFC_ctrl::cmBox_switch()
{configuration_read();startSystem();	
}bool Zanj_WFC_ctrl::configuration_read()
{string err;QFile config_ini("config.ini");//QFile config_ini("config_baori.ini");  打开baori配置文件,如果需要访问宝日大数据平台,就需要打开baori配置文件if (!config_ini.open(QIODevice::ReadOnly | QIODevice::Text)){console_WFC_thread->critical("配置文件config.ini不能打开!");rlogger_WFC_thread->critical("配置文件config.ini不能打开!");//		std::cout << "configuration.ini Open failed." << endl;return false;}console_WFC_thread->info("配置文件config.ini已打开! ");rlogger_WFC_thread->info("配置文件config.ini已打开! ");QTextStream config_txtInput(&config_ini);QString config_lineStr;config_lineStr = config_txtInput.readLine();config_lineStr = config_txtInput.readLine();clientID = config_lineStr.mid(9);config_lineStr = config_txtInput.readLine();clientSecret = config_lineStr.mid(13);config_lineStr = config_txtInput.readLine();serverIP = config_lineStr.mid(9);config_lineStr = config_txtInput.readLine();serviceID_get = config_lineStr.mid(14);config_lineStr = config_txtInput.readLine();serviceID_post = config_lineStr.mid(15);config_lineStr = config_txtInput.readLine();name = config_lineStr.mid(5);config_lineStr = config_txtInput.readLine();unit = config_lineStr.mid(5);config_lineStr = config_txtInput.readLine();user_ID = config_lineStr.mid(8);config_lineStr = config_txtInput.readLine();companyCode = config_lineStr.mid(12);config_lineStr = config_txtInput.readLine();mssql_serverName = config_lineStr.mid(17);config_lineStr = config_txtInput.readLine();mssql_dbName = config_lineStr.mid(13);config_lineStr = config_txtInput.readLine();mssql_username = config_lineStr.mid(15);config_lineStr = config_txtInput.readLine();mssql_pwd = config_lineStr.mid(10);config_lineStr = config_txtInput.readLine();mssql_datasource = config_lineStr.mid(17);return true;
}void Zanj_WFC_ctrl::startSystem() {while (true) {// 每隔一定时间执行一次数据读取和预测OnGETSlot();//Temp_KNNval_Auto_Cal();// 休眠一段时间,模拟定时器或轮询间隔this_thread::sleep_for(chrono::seconds(30)); // 30秒钟间隔}
}

03-model_switch()函数实现  

       实现另一个函数之前,先定义了一个全局变量,用于设置工作模式,这里设置的是,当变量为0,为手动模式,变量为1,为自动模式,在读取数据函数那里,加入if判断语句,如果变量为1,则直接进行计算,否则,需要手动计算

        如果变量为1,直接调用该函数Temp_KNNval_Auto_Cal()进行计算,如果为0,则手动操作进行计算。

计算线程.cpp文件void Zanj_WFC_ctrl::json_doc_get_parse()
{//总的思路是:对象.value(),如果取到string、int、double类型 就直接.toString()等输出;//如果取到object或array类型 ,就通过toObject()或toArray() 转到对象或数组类型,接着取值。。循环if (json_doc_get.isNull()){console_WFC_thread->critical("unable to parse! ");rlogger_WFC_thread->critical("unable to parse! ");}else{console_WFC_thread->info("parse start! ");rlogger_WFC_thread->info("parse start! ");}QJsonObject::Iterator it;for (it = doc_get_Obj.begin(); it != doc_get_Obj.end(); ++it) {HdglPredict tempData;QString aentid, atentid, atime, acode, agrade, asource;float ahthick, athick, awidth, CT_TMP, FT_TMP, DSH, SPEED, TPM;float C, Si, Mn, P, S, Cu, Ni, Cr, Mo, Nb, Ti, B, N, Al;int st_product_no;QString zoneKey = it.key();QJsonObject zoneObj = it.value().toObject();// 检查钢卷是否已经读取过,如果已经读取过,则跳过if (readCoils.contains(zoneKey)){console_WFC_thread->warn("文件里没有其他钢卷! ");continue;}// 将已读取的钢卷添加到集合中readCoils.insert(zoneKey);aentid = zoneObj["aentid"].toString();atentid = zoneObj["atentid"].toString();atime = zoneObj["atime"].toString();acode = zoneObj["acode"].toString();agrade = zoneObj["agrade"].toString();asource = zoneObj["asource"].toString();tempData.ZoneKey = zoneKey;tempData.ENTID = aentid;tempData.AENTID = atentid;tempData.ATIME = atime;tempData.ST_code = acode;tempData.ST_grade = agrade;tempData.ST_source = asource;tempData.CGL_SPEED_INPUT = SPEED;tempData.SPM_ELONG_INPUT = TPM;tempData.st_product_no = st_product_no_determin();// 将结构体对象添加到容器中hdglPredictList.append(tempData);strt_hdgl_predict.ENTID = aentid;strt_hdgl_predict.AENTID = atentid;strt_hdgl_predict.ATIME = atime;strt_hdgl_predict.ST_code = acode;strt_hdgl_predict.ST_grade = agrade;strt_hdgl_predict.ST_source = asource;strt_hdgl_predict.CGL_SPEED_INPUT = SPEED;strt_hdgl_predict.SPM_ELONG_INPUT = TPM;if (model_switch_num == 1){Temp_KNNval_Auto_Cal();} else{continue;}}}void Zanj_WFC_ctrl::model_switch() {model_switch_num = 1;}
void Zanj_WFC_ctrl::model_switch_0() {model_switch_num = 0;}

04-数据存在判断操作实现  

       最后实现系统对平台是否存在新的数据的判断,定义了一个字符串变量readCoils,用于存储已经读取的钢卷,对于已经读取过的钢卷,直接跳过,不进行计算,若是没有钢卷存在,系统也会发出警告。通过下面这部分代码判断即可

        if (readCoils.contains(zoneKey))
        {
            
            console_WFC_thread->warn("文件里没有其他钢卷! ");
            continue;
        }

        // 将已读取的钢卷添加到集合中
        readCoils.insert(zoneKey);

void Zanj_WFC_ctrl::json_doc_get_parse()
{//总的思路是:对象.value(),如果取到string、int、double类型 就直接.toString()等输出;//如果取到object或array类型 ,就通过toObject()或toArray() 转到对象或数组类型,接着取值。。循环if (json_doc_get.isNull()){console_WFC_thread->critical("unable to parse! ");rlogger_WFC_thread->critical("unable to parse! ");}else{console_WFC_thread->info("parse start! ");rlogger_WFC_thread->info("parse start! ");}QJsonObject::Iterator it;for (it = doc_get_Obj.begin(); it != doc_get_Obj.end(); ++it) {HdglPredict tempData;QString aentid, atentid, atime, acode, agrade, asource;float ahthick, athick, awidth, CT_TMP, FT_TMP, DSH, SPEED, TPM;float C, Si, Mn, P, S, Cu, Ni, Cr, Mo, Nb, Ti, B, N, Al;int st_product_no;QString zoneKey = it.key();QJsonObject zoneObj = it.value().toObject();// 检查钢卷是否已经读取过,如果已经读取过,则跳过if (readCoils.contains(zoneKey)){console_WFC_thread->warn("文件里没有其他钢卷! ");continue;}// 将已读取的钢卷添加到集合中readCoils.insert(zoneKey);aentid = zoneObj["aentid"].toString();atentid = zoneObj["atentid"].toString();atime = zoneObj["atime"].toString();acode = zoneObj["acode"].toString();agrade = zoneObj["agrade"].toString();asource = zoneObj["asource"].toString();tempData.ZoneKey = zoneKey;tempData.ENTID = aentid;tempData.AENTID = atentid;tempData.ATIME = atime;tempData.ST_code = acode;tempData.ST_grade = agrade;tempData.ST_source = asource;tempData.CGL_SPEED_INPUT = SPEED;tempData.SPM_ELONG_INPUT = TPM;tempData.st_product_no = st_product_no_determin();// 将结构体对象添加到容器中hdglPredictList.append(tempData);strt_hdgl_predict.ENTID = aentid;strt_hdgl_predict.AENTID = atentid;strt_hdgl_predict.ATIME = atime;strt_hdgl_predict.ST_code = acode;strt_hdgl_predict.ST_grade = agrade;strt_hdgl_predict.ST_source = asource;strt_hdgl_predict.CGL_SPEED_INPUT = SPEED;strt_hdgl_predict.SPM_ELONG_INPUT = TPM;if (model_switch_num == 1){Temp_KNNval_Auto_Cal();} else{continue;}}}

  05-功能演示  

      下面对上述介绍的功能进行演示:

   如下图所示,为系统登录界面,登录之后,才可以对各种功能进行操作。 

         主界面如下图所示:仅展示部分主界面,分为自动模式和手动模式

        选择自动模式之后,就可以持续进行计算,不断进行访问数据文件 

         当再次访问,发现数据文件中没有数据之后,便会发出警告,如下图所示。

 总结      

       在C++ QT系统中实现自动化读取JSON数据文件的过程有几个好处:

        提高效率:自动化读取JSON数据文件可以省去手动操作的时间和精力,提高系统运行效率。特别是在需要定期更新或获取数据时,自动化读取可以保证数据及时可用,减少了人为干预的需要。

        减少错误:手动处理JSON数据文件容易出现错误,例如文件路径错误、解析错误等。自动化读取通过编程实现,可以减少人为错误的发生,提高系统的稳定性和可靠性。

        增强灵活性:自动化读取JSON数据文件的实现可以根据需求进行定制化,例如可以设置读取频率、读取条件等,从而增强了系统的灵活性和可配置性。

        方便维护:通过自动化读取,可以将数据获取的逻辑封装在函数或模块中,便于维护和修改。当需求变化时,只需要修改相应的代码逻辑,而不必修改大量的手动操作步骤。

        综上所述,自动化读取JSON数据文件可以提高系统效率、减少错误、增强灵活性,并方便系统的维护和升级。

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

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

相关文章

解决在cmd里下载的库,但IDLE还是显示不存在的问题

原因一&#xff1a; 环境变量配置 首先&#xff0c;你需要确认你安装库的时候使用的Python环境是否和IDLE使用的Python环境是同一个。如果cmd中你使用的是系统路径下的Python&#xff0c;而IDLE使用的是另一个路径下的Python&#xff0c;那么你在cmd中下载的库&#xff0c;IDL…

SQLiteOpenHelper数据库帮助器

SQLiteOpenHelper数据库帮助器是Android提供的数据库辅助工具。 1、继承SQLiteOpenHelper类&#xff0c;需要重写onCreate和onUpgrade两个方法 案例&#xff1a;实现增删改查 package com.example.databases_text;import android.app.PictureInPictureParams; import androi…

Echarts图表使用

ECharts是一个用JS实现开源可视化库&#xff0c;它提供了丰富的图表类型和交互能力。使用户可以通过简单的配置生成各种各样的图表。 先安装ECharts图表直接下载echarts.min.js并用<script>标签引入也可以使用源代码版本echarts.js并用<script>标签引入&#xff0…

Go 1.23 Release Notes编写方式改进!

2024.5.22日&#xff0c;Go 1.23 feature冻结&#xff01;Go团队开始Go 1.23rc1的冲刺&#xff0c;截至发文时&#xff0c;Go 1.23 milestone已经完成59%(https://github.com/golang/go/milestone/212)&#xff0c;还有188个open的issue待解决。 Go 1.23有哪些新feature&#x…

民国漫画杂志《时代漫画》第13期.PDF

时代漫画13.PDF: https://url03.ctfile.com/f/1779803-1247458360-14efab?p9586 (访问密码: 9586) 《时代漫画》的杂志在1934年诞生了&#xff0c;截止1937年6月战争来临被迫停刊共发行了39期。 ps:资源来源网络&#xff01;

简易进程池的实现

什么是进程池&#xff1f; 进程池&#xff08;Process Pool&#xff09;是一种用于管理和复用多个进程的技术或设计模式。在进程池中&#xff0c;一定数量的进程会被预先创建并保持在内存中&#xff0c;以便在需要时立即使用&#xff0c;而不是每次需要进程时都重新创建新的进程…

基于Qt的社团信息管理系统

企鹅2583550535 项目和论文都有 第1章 绪论... 1 1.1 研究背景与意义... 1 1.2 国内外发展现状... 2 1.3 研究内容... 3 第2章 关键技术介绍... 4 2.1 主要开发技术... 4 2.1.1 C. 4 2.1.2 QT框架... 4 2.1.3 MySQL数据库... 5 2.1.4 TCP协议... 6 2.2 其他技术介绍.…

GPIO模拟spi时序点亮数码管

目录 spi.h spi.c main.c 实验效果 spi.h #ifndef __SPI_H__ #define __SPI_H__#include "stm32mp1xx_gpio.h" #include "stm32mp1xx_rcc.h"//spi初始化 void spi_init(); //spi写入数据 void spi_write(unsigned char data);#endif spi.c #include…

Andoird使用Room实现持久化及使用Room进行增删查改

文章目录 Room概述Room的使用一、在gradle.build中添加依赖库kotlinJava 创建实体类创建抽象Dao层接口创建DataBase层使用创建的查看数据库 总结&#xff1a; 这篇文章会告诉你如何在Android中通过kotlin或者Java来实现数据持久化 Room概述 处理大量结构化数据的应用可极大地受…

深入了解Socket套接字

目录 一、引入&#x1f64c; 1、概念 &#x1f389; 2、分类&#x1f389; Socket 套接字主要针对传输层协议分为流套接字、数据报套接字、原始套接字&#xff08;了解即可&#xff09;三类。 1&#xff09;流套接字&#xff1a;使用传输层TCP协议 2&#xff09;数据报套…

温故而知新-MySQL篇【面试复习】

温故而知新-数据库篇【面试复习】 前言版权推荐温故而知新-Mysql篇Mysql常见面试题Mysql事务Mysql索引Mysql锁Mysql日志Mysql中的Buffer 数据库的三范式是什么MySQL对于LRU的优化InnoDB三大特性自适应哈希索引&#xff08;Adaptive Hash Index&#xff09;插入缓存&#xff08;…

基于51单片机的盆栽自动浇花系统

一.硬件方案 工作原理是湿度传感器将采集到的数据直接传送到ADC0832的IN端作为输入的模拟信号。选用湿度传感器和AD转换&#xff0c;电路内部包含有湿度采集、AD转换、单片机译码显示等功能。单片机需要采集数据时&#xff0c;发出指令启动A/D转换器工作&#xff0c;ADC0832根…

HLS入门

文章目录 一HLS是什么1HLS介绍 二HLS核心技术以及技术局限性1HLS的核心技术2HLS的技术局限性 三HLS的LED流水灯1创建项目工程2代码3仿真 一HLS是什么 1HLS介绍 HLS是一种将高级编程语言&#xff08;如 C、C等&#xff09;描述的算法或逻辑自动转换为 FPGA 可实现的硬件描述语…

计算机网络学习小结_物理层

数据通信基础知识 信道相关概念 单工&#xff0c;半双工&#xff0c;全双工 基带信号&#xff1a;信源发出的信号&#xff0c;如计算机输出的文字和图像都是基带信号。基带信号常包含较多低频成分&#xff0c;有的还有直流成分&#xff0c;有的信道不能传输低频成分和直流成…

数据结构--顺序表

目录 1.顺序表 1.1顺序表的概念及结构 线性表 2、顺序表分类 2.1顺序表和数组的区别 静态顺序表 动态顺序表 3.顺序表的实现 3.1初始化 随后便可对顺序表初始化 3.2插入数据 尾插 头插 在指定位置插入数据 顺序表的查找 头删、尾删及指定位置删除 实现代码&#x…

汽车R155法规中,汽车获取到的VTA证书,E后面的数字表示什么意思?

标签&#xff1a; 汽车R155法规中&#xff0c;汽车获取到的VTA证书&#xff0c;E后面的数字表示什么意思&#xff1f;&#xff1b; 汽车&#xff1b;VTA认证; 有些厂商汽车拿到的VTA证书上面写着E9&#xff0c; 有些厂商汽车拿到的VTA证书上面写着E5&#xff0c;E9与E5有什么差…

primeflex样式库笔记 Display相关的案例

回顾 宽度设置的基本总结 w-full&#xff1a;表示widtdh&#xff1a;100%&#xff1b;占满父容器的宽度。 w-screen&#xff1a;表示占满整个屏幕的宽度。 w-1到w-12&#xff0c;是按百分比划分宽度&#xff0c;数字越大&#xff0c;占据的比例就越大。 w-1rem到w-30rem&…

Vitis HLS 学习笔记--控制驱动任务示例

目录 1. 简介 2. 代码解析 2.1 kernel 代码回顾 2.2 功能分析 2.3 查看综合报告 2.4 查看 Schedule Viewer 2.5 查看 Dataflow Viewer 3. Vitis IDE的关键设置 3.1 加载数据文件 3.2 设置 Flow Target 3.3 配置 fifo 深度 4. 总结 1. 简介 本文对《Vitis HLS 学习…

零拷贝(Zero-Copy)

1.背景 现在有这样一个场景&#xff0c;我们需要在本地选择一个文件后&#xff0c;然后上传到网络上。 我们再看看文件的内容数据的具体搬运过程&#xff1a; 你会发现&#xff0c;在整个文件搬运的过程中&#xff0c;发生了多次的数据拷贝和上下文转换。 4次数据拷贝&#…

Git总结超全版

最近想系统的回顾一下Git的使用&#xff0c;如果只想快速的集成git到idea&#xff0c;可以参考另一篇我的博客中的git部分 目录 版本管理工具简介Git安装与配置Git远程仓库配置 Git常用命令为常用命令配置别名(可选)Git忽略文件.gitignore一些概念*本地仓库操作删除仓库内容 *远…