《使用Qt Quick從零構建AI螺絲瑕疵檢測系統》——2. C++基礎:構建程序的堅實骨架

目錄

  • 一、概述
    • 1.1 背景介紹:從UI到邏輯
    • 1.2 學習模式:Qt控制臺應用
  • 二、C++語法快速入門
    • 2.1 變量、數據類型與注釋
    • 2.2 函數與代碼封裝
    • 2.3 循環與容器:批量處理
  • 三、面向對象編程:封裝數據與行為
  • 四、Qt的核心擴展:信號與槽通信
  • 五、總結與展望

一、概述

1.1 背景介紹:從UI到邏輯

在上一篇文章中,我們成功搭建了開發環境,并為“AI螺絲瑕疵檢測系統”創建了一個專業、美觀的項目骨架。一個軟件的UI(用戶界面)是它的“面孔”,負責與用戶交互;而其C++后端則是它的“大腦”和“骨骼”,負責處理數據、執行復雜邏輯并與硬件通信。

本篇文章的核心任務,就是構建這個強大的“大腦”和“骨骼”。我們將深入C++的世界,但會聚焦于在Qt開發中最常用、最核心的部分。通過本篇的學習,讀者將掌握創建后端邏輯、組織代碼以及實現對象間通信的基本功,為后續集成真正的視覺算法和硬件交互打下堅實的語言基礎。

1.2 學習模式:Qt控制臺應用

為了讓讀者能專注于C++語法本身,暫時不受QML圖形界面的干擾,本章的所有示例都將以**Qt控制臺應用程序(Qt Console Application)**的形式呈現。這是一種沒有圖形界面的、純粹在命令行輸出信息的程序,是學習和驗證后端邏輯的絕佳工具。
在這里插入圖片描述

二、C++語法快速入門

本節面向C++初學者,旨在通過可直接運行的、獨立的控制臺程序,快速介紹后續章節將會頻繁使用的基本語法元素。

2.1 變量、數據類型與注釋

【例2-1】 產品信息存儲與顯示。

變量是程序中用于存儲數據的基本單元,可以將其看作是內存中一個帶標簽的盒子。數據類型則定義了這個“盒子”能裝什么類型的東西(如整數、小數、字符串等)以及能對它進行哪些操作。在C++中,定義任何變量都必須首先聲明其數據類型。注釋用于解釋代碼,不會被編譯器執行。

(1) 基本數據類型: int(整數), double(雙精度浮點數), bool(布爾值, true或false)。
(2) Qt常用數據類型: QString(字符串)。在Qt開發中, 推薦使用QString而非C++標準庫的std::string,因為它提供了更豐富的功能和更好的Unicode支持。
(3) 注釋: 單行注釋以//開始,多行注釋以/*開始,以*/結束。

使用 Qt Creator 創建一個Qt Console Application程序Demo_2_1_Variables。項目創建完成后,打開main.cpp,修改代碼如下:

#include <QCoreApplication>
#include <QDebug>       // 包含Qt的調試輸出頭文件
#include <QString>      // 包含Qt的字符串類頭文件int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);// --- 變量定義與初始化 ---int screwCount = 100;double diameter = 5.02;bool isQualified = true;QString batchNumber = "SN20250715-B";// --- 使用qDebug()進行控制臺輸出 ---qDebug() << "開始進行產品信息檢查...";qDebug() << "螺絲數量:" << screwCount << "個";qDebug() << "產品直徑:" << diameter << "mm";qDebug() << "質量狀態:" << isQualified;qDebug() << "生產批號:" << batchNumber;qDebug() << "檢查完畢。";return a.exec();
}

單擊 Qt Creator 左下角的綠色“運行”按鈕。在下方的“應用程序輸出”窗口,可以看到如下結果:

開始進行產品信息檢查...
螺絲數量: 100 個
產品直徑: 5.02 mm
質量狀態: true
生產批號: "SN20250715-B"
檢查完畢。

關鍵代碼分析:
(1) #include <QDebug>: 要使用qDebug(),必須包含此頭文件。
(2) #include <QString>: QString是Qt中處理文本的專用類,功能強大,完美支持Unicode(包括中文),是Qt開發的首選字符串類型。
(3) 變量定義: 數據類型 variableName = initialValue;是C++定義變量的基本格式。變量名通常使用小駝峰命名法(camelCase)。
(4) qDebug() << ...: 這是qDebug的鏈式調用語法。它會自動在每個<<分隔的變量之間加上空格,并在最后輸出一個換行符,非常便捷。

2.2 函數與代碼封裝

【例2-2】 封裝尺寸檢查邏輯。

函數是一段被命名、可重復使用的代碼塊,用于執行一個特定的任務。隨著程序邏輯變得復雜,將不同功能的代碼組織成獨立的函數,可以極大地提高程序的可讀性、可維護性和代碼的復用性。一個函數通常有輸入(參數)和輸出(返回值)。

使用 Qt Creator 創建一個Qt Console Application程序Demo_2_2_Functions。項目創建完成后,打開main.cpp,修改代碼如下:

#include <QCoreApplication>
#include <QDebug>// --- 函數定義 ---
// 這個函數接收一個double類型的參數(parameter),沒有返回值(void)
// 它的作用是封裝了完整的尺寸檢查邏輯
void checkScrewDiameter(double diameterToTest)
{qDebug() << "--- 開始檢查直徑:" << diameterToTest << "mm ---";const double standardDiameter = 5.0;const double tolerance = 0.05;if (diameterToTest > standardDiameter + tolerance) {qDebug() << "判定結果: 不合格,直徑過大。";} else if (diameterToTest < standardDiameter - tolerance) {qDebug() << "判定結果: 不合格,直徑過小。";} else {qDebug() << "判定結果: 合格,尺寸在公差范圍內。";}qDebug() << "--- 檢查結束 ---" << Qt::endl; // Qt::endl顯式地換行
}int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);// --- 函數調用 ---// 通過函數名和傳遞相應的參數來執行函數中的代碼checkScrewDiameter(5.08); // 調用函數,檢查一個過大的螺絲checkScrewDiameter(4.93); // 調用函數,檢查一個過小的螺絲checkScrewDiameter(5.01); // 調用函數,檢查一個合格的螺絲return a.exec();
}

單擊 Qt Creator 左下角的綠色“運行”按鈕,可以看到如下結果:

--- 開始檢查直徑: 5.08 mm ---
判定結果: 不合格,直徑過大。      
--- 檢查結束 ------ 開始檢查直徑: 4.93 mm ---     
判定結果: 不合格,直徑過小。      
--- 檢查結束 ------ 開始檢查直徑: 5.01 mm ---     
判定結果: 合格,尺寸在公差范圍內。
--- 檢查結束 ---

關鍵代碼分析:
(1) 函數定義: “返回值類型 函數名(參數類型1 參數名1, ...)”是定義函數的基本形式。void是一種特殊的返回類型,表示該函數執行完畢后不返回任何值。
(2) 函數參數: double diameterToTest是函數的形式參數(形參),它是在函數定義時聲明的,作為函數內部的一個局部變量來接收外部傳入的數據。
(3) 函數調用: checkScrewDiameter(5.08)是在main函數中調用已定義的函數。5.08是實際參數(實參),在調用發生時,它的值會被復制一份并傳遞給函數中的形參diameterToTest
(4) const關鍵字: const double standardDiameter = 5.0; const表示standardDiameter是一個常量,其值在程序運行期間不能被修改。對于程序中固定不變的數值(如標準、公差),使用常量是一種推薦的編程實踐,可以防止意外修改并提高代碼的可讀性。

2.3 循環與容器:批量處理

【例2-3】 批量質檢一批產品。

循環是一種控制結構,它允許一段代碼根據設定的條件重復執行多次。容器則是一種特殊的對象,專門用于存儲和管理一組數據集合。當需要對一個集合中的所有元素執行相同操作時(例如,檢查流水線上的一整批產品),將循環與容器結合使用,可以實現高效的自動化處理。

使用 Qt Creator 創建一個Qt Console Application程序Demo_2_3_LoopsAndContainers。項目創建完成后,打開main.cpp,修改代碼如下:

#include <QCoreApplication>
#include <QDebug>
#include <QVector> // 包含QVector容器的頭文件int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);// 創建一個QVector容器,用于存放一批待檢測的螺絲直徑QVector<double> diameterBatch;diameterBatch.append(5.01); // 使用append()方法向容器末尾添加元素diameterBatch.append(4.98);diameterBatch.append(5.09); // 這個不合格diameterBatch.append(4.92); // 這個也不合格diameterBatch.append(5.04);qDebug() << "流水線來了一批產品,共" << diameterBatch.size() << "個,開始質檢...";int qualifiedCount = 0;// 使用for循環遍歷QVector中的每一個元素for (int i = 0; i < diameterBatch.size(); ++i) {double currentDiameter = diameterBatch[i]; // 使用索引[i]訪問容器中的元素bool isCurrentQualified = (currentDiameter >= 4.95 && currentDiameter <= 5.05);if (isCurrentQualified) {qDebug() << "第" << i + 1 << "個螺絲,直徑" << currentDiameter << "mm, 合格。";qualifiedCount++;} else {qDebug() << "第" << i + 1 << "個螺絲,直徑" << currentDiameter << "mm, 不合格!";}}qDebug() << "質檢完成。合格數量:" << qualifiedCount;return a.exec();
}

單擊 Qt Creator 左下角的綠色“運行”按鈕,可以看到如下結果:

流水線來了一批產品,共 5 個,開始質檢...
第 1 個螺絲,直徑 5.01 mm, 合格。  
第 2 個螺絲,直徑 4.98 mm, 合格。  
第 3 個螺絲,直徑 5.09 mm, 不合格!
第 4 個螺絲,直徑 4.92 mm, 不合格!
第 5 個螺絲,直徑 5.04 mm, 合格。  
質檢完成。合格數量: 3

關鍵代碼分析:
(1) #include <QVector>: QVector是Qt提供的一個模板容器類,功能類似于一個可以動態調整大小的數組。要使用它,必須包含此頭文件。
(2) QVector<double>: 定義了一個專門用于存放double類型數據的QVector容器。尖括號< >中的類型指定了容器內所有元素的類型。
(3) append(): 這是QVector的成員函數,用于在容器的末尾追加一個新元素。
(4) size(): 這是QVector的成員函數,用于獲取容器中當前存儲的元素總數。
(5) for循環結構: for(int i = 0; i < diameterBatch.size(); ++i)是最經典的for循環結構。它包含三個部分,由分號隔開:

  • 初始化: int i = 0,創建一個循環計數器i并賦初值為0。
  • 循環條件: i < diameterBatch.size(),每次循環開始前檢查此條件,若為真則執行循環體,否則退出循環。
  • 迭代表達式: ++i,每次循環體執行完畢后執行此操作,使計數器加1。
    (6) 元素訪問: diameterBatch[i],通過方括號和索引i(從0開始)來訪問QVector容器中的具體元素。
    (7) &&運算符: (currentDiameter >= 4.95 && currentDiameter <= 5.05)中的&&是邏輯“與”運算符,它表示其兩側的條件必須同時為真,整個表達式的結果才為真。

三、面向對象編程:封裝數據與行為

當程序邏輯變得復雜時,使用零散的變量和函數來管理會變得混亂。面向對象編程(Object-Oriented Programming, OOP)提供了一種更高級的組織方式,其核心就是類(Class)

【核心概念:數據與行為的統一體】

是創建對象的“藍圖”。它將描述某個事物的數據(稱為屬性或成員變量)和能對這些數據進行的操作(稱為方法或成員函數)封裝(Encapsulation)在一起。通過類,可以創建出具體的對象(Object),每個對象都是一個獨立、完整的實體,極大地提高了代碼的結構化程度。

【例2-4】 創建一個螺絲計數器類。

1. 創建項目與類文件

  • 新建一個名為 Demo_2_4_Classes 的Qt控制臺項目。
  • 在Qt Creator中,右鍵點擊項目名稱,選擇添加新文件... -> C++ -> C++ Class,類名輸入 SimpleCounter,基類保持默認的 ,完成向導。Qt Creator會自動創建simplecounter.hsimplecounter.cpp

2. 編寫代碼 (simplecounter.h)

#ifndef SIMPLECOUNTER_H
#define SIMPLECOUNTER_H// 類的聲明
class SimpleCounter
{
public:// 構造函數:在創建對象時自動調用,用于初始化SimpleCounter();// 公有(public)成員函數: 外部代碼可以直接調用void increment();       // 計數加一void clear();           // 計數清零int getCount() const;   // 獲取當前計數值private:// 私有(private)成員變量: 外部代碼無法直接訪問,實現了封裝和保護int m_count;
};#endif // SIMPLECOUNTER_H

3. 編寫代碼 (simplecounter.cpp)

#include "simplecounter.h"// 構造函數的實現
SimpleCounter::SimpleCounter()
{// 在這里進行初始化工作m_count = 0;
}// 成員函數的實現
void SimpleCounter::increment()
{m_count++;
}void SimpleCounter::clear()
{m_count = 0;
}// const關鍵字表示這個函數不會修改類的任何成員變量
int SimpleCounter::getCount() const
{return m_count;
}

4. 編寫代碼 (main.cpp)

#include <QCoreApplication>
#include <QDebug>
#include "simplecounter.h" // 包含我們自己定義的類的頭文件int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);qDebug() << "創建兩個計數器: 合格品計數器和次品計數器";// 從SimpleCounter類創建兩個具體的對象SimpleCounter qualifiedCounter;SimpleCounter defectiveCounter;// 模擬生產過程qDebug() << "生產了3個合格品...";qualifiedCounter.increment();qualifiedCounter.increment();qualifiedCounter.increment();qDebug() << "生產了1個次品...";defectiveCounter.increment();// 通過公有方法獲取內部的計數值并打印qDebug() << "當前合格品數量:" << qualifiedCounter.getCount();qDebug() << "當前次品數量:" << defectiveCounter.getCount();return a.exec();
}

5. 運行結果

創建兩個計數器: 合格品計數器和次品計數器
生產了3個合格品...
生產了1個次品...  
當前合格品數量: 3 
當前次品數量: 1

關鍵代碼分析:
(1) 頭文件(.h)與源文件(.cpp): 在C++中,類的聲明(它有什么)通常放在頭文件中,而成員函數的具體實現(它怎么做)放在源文件中。這是一種代碼組織規范。
(2) public:private:: 這是訪問說明符。public部分是類的對外接口,任何代碼都可以訪問。private部分是類的內部實現,只有該類的成員函數才能訪問,外部代碼無法直接觸及。這體現了封裝的思想,保護了內部數據的安全性。
(3) 構造函數: SimpleCounter()是一個特殊的成員函數,它沒有返回類型,且函數名與類名完全相同。在創建類的對象時(如SimpleCounter qualifiedCounter;),構造函數會被自動調用,是執行初始化操作的最佳位置。
(4) SimpleCounter::: ::是作用域解析運算符。在.cpp文件中,它用于指明一個函數實現是屬于哪個類的。

四、Qt的核心擴展:信號與槽通信

【核心概念:Qt的靈魂機制】

在圖形界面程序中,一個對象的狀態改變(如按鈕被點擊)常常需要通知其他多個對象。如果使用直接函數調用的方式,對象之間會產生緊密的依賴關系(耦合),不利于程序的維護和擴展。

為此,Qt引入了其最核心、最強大的創新之一:信號與槽(Signals and Slots)

  • 信號(Signal): 當對象內部狀態發生改變時,由該對象發射(emit)出去的一種“廣播”或“通知”。它只負責發出通知,不關心誰會收到。
  • 槽(Slot): 一個普通的成員函數,用于接收并處理某個信號。

通過connect函數,可以將一個對象的信號與另一個(或同一個)對象的槽連接起來。當信號被發射時,所有與之連接的槽函數就會被自動調用。這種機制使得信號的發送方和接收方可以互不知道對方的存在,實現了完美的解耦。

要讓一個類支持信號與槽,必須:

  1. 公有繼承自 QObject
  2. 在類聲明的私有區頂部添加 Q_OBJECT 宏。

【例2-5】 工作者完成任務后通知管理者。

1. 創建項目與類文件

  • 新建一個名為 Demo_2_5_SignalsAndSlots 的Qt控制臺項目。
  • 分別添加 WorkerManager 兩個C++類,注意它們的基類都要選擇 QObject

2. 編寫代碼 (worker.h & worker.cpp)

// worker.h
#ifndef WORKER_H
#define WORKER_H
#include <QObject>
#include <QString>class Worker : public QObject
{Q_OBJECT // 必須添加此宏以支持信號與槽
public:explicit Worker(QObject *parent = nullptr);void doWork(); // 模擬執行一個任務
signals:// 信號只需要聲明,無需實現。在signals關鍵字下聲明void workFinished(const QString &result);
};
#endif // WORKER_H// worker.cpp
#include "worker.h"
#include <QDebug>
#include <QThread>Worker::Worker(QObject *parent) : QObject(parent) {}
void Worker::doWork()
{qDebug() << "[工作者] 開始執行耗時任務...";QThread::sleep(2); // 模擬耗時2秒QString result = "所有螺絲檢測完畢";qDebug() << "[工作者] 任務完成,準備發射信號...";emit workFinished(result); // 使用emit關鍵字發射信號
}

3. 編寫代碼 (manager.h & manager.cpp)

// manager.h
#ifndef MANAGER_H
#define MANAGER_H
#include <QObject>
#include <QString>class Manager : public QObject
{Q_OBJECT
public:explicit Manager(QObject *parent = nullptr);
public slots:// 槽函數聲明在 public slots: 區域void onWorkFinished(const QString &result);
};
#endif // MANAGER_H// manager.cpp
#include "manager.h"
#include <QDebug>Manager::Manager(QObject *parent) : QObject(parent) {}void Manager::onWorkFinished(const QString &result)
{qDebug() << "[管理者] 收到信號,槽函數被調用!";qDebug() << "  > 結果:" << result;
}

4. 編寫代碼 (main.cpp)

#include <QCoreApplication>
#include "worker.h"
#include "manager.h"
#include <QDebug>int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);Worker worker;Manager manager;// --- 信號與槽的連接 ---QObject::connect(&worker, &Worker::workFinished,&manager, &Manager::onWorkFinished);qDebug() << "[主程序] 命令工作者開始工作。";worker.doWork(); // 調用此函數將最終導致信號被發射return a.exec();
}

5. 運行結果

[主程序] 命令工作者開始工作。
[工作者] 開始執行耗時任務...
[工作者] 任務完成,準備發射信號...
[管理者] 收到信號,槽函數被調用!> 結果: "所有螺絲檢測完畢"

關鍵代碼分析:
(1) QObjectQ_OBJECT: WorkerManager都繼承自QObject,并在類聲明中包含了Q_OBJECT宏,這是使用信號槽的前提。Qt的MOC(元對象編譯器)會預處理這個宏,生成支持信號槽所需的額外代碼。
(2) signals:: 用于聲明信號函數。信號函數沒有函數體,其返回值類型通常是void
(3) emit: 這是一個空宏,在代碼中用于標記一個信號的發射。當執行到emit workFinished(...)時,Qt的元對象系統會接管,并調用所有與workFinished信號連接的槽。
(4) public slots:: 用于聲明槽函數。槽函數的本質是一個普通的成員函數,可以有自己的參數和實現。
(5) QObject::connect(...): 這是建立連接的核心函數。其最常用的形式是:
connect(信號發送者地址, &發送者類::信號名, 信號接收者地址, &接收者類::槽函數名);
這種寫法在編譯時就會進行類型檢查,如果信號和槽的參數不匹配,或者函數名寫錯,編譯器會直接報錯,非常安全。

五、總結與展望

在本篇文章中,我們不僅復習了C++的基礎語法,更深入探討了面向對象編程的核心——類與對象,以及Qt框架的靈魂——信號與槽機制。這些是構建任何復雜、可維護的Qt應用程序都不可或缺的知識。

現在,我們已經具備了用C++構建結構化、可交互的后端邏輯的能力。在下一篇文章**【《使用Qt Quick從零構建AI螺絲瑕疵檢測系統》——3. QML入門:像搭積木一樣構建UI】**中,我們將把目光轉向用戶界面,開始探索QML的精彩世界,學習如何為我們的C++后端打造一個現代化的“面孔”。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/92254.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/92254.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/92254.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Navicat 遠程連接SQLlite數據庫

1、SQLlite數據庫是一個本地.db文件&#xff0c;默認不支持遠程連接&#xff1b; 2、Navicat 可以通過ntunnel_sqlite.php文件連接遠程SQLlite庫&#xff1b; 3、安裝Navicat&#xff0c;安裝完成&#xff0c;在安裝目錄下找到ntunnel_sqlite.php文件&#xff1b; 4、上傳當前文…

OpenCV用于計算光流的一個類cv::optflow::DualTVL1OpticalFlow

操作系統&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 編程語言&#xff1a;C11 算法描述 cv::optflow::DualTVL1OpticalFlow 是 OpenCV 中用于計算光流的一個類&#xff0c;特別地&#xff0c;它實現了基于雙幀 TV-L1&#xff08;Total V…

PyQt5在Pycharm上的環境搭建 -- Qt Designer + Pyuic + Pyrcc組合,大幅提升GUI開發效率

軟件安裝 目標軟件&#xff1a; Python解釋器Pycharm編輯器 Python官網&#xff1a; 點擊訪問Python官網 Pycharm官網&#xff1a;點擊訪問Pycharm官網 環境搭建 搭建完成后最終的環境詳情&#xff1a; python安裝路徑&#xff1a;D:\ProgramEnviron\Python\Python311Pyth…

30天打牢數模基礎-卷積神經網絡講解

案例代碼實現一、代碼說明本案例使用PyTorch實現一個改進版LeNet-5模型&#xff0c;用于CIFAR-10數據集的圖像分類任務。代碼包含以下核心步驟&#xff1a;數據加載與預處理&#xff08;含數據增強&#xff0c;劃分訓練/驗證/測試集&#xff09;&#xff1b;定義CNN網絡結構&am…

Dev-C++——winAPI貪吃蛇小游戲

&#x1f680;歡迎互三&#x1f449;&#xff1a;霧狩 &#x1f48e;&#x1f48e; &#x1f680;關注博主&#xff0c;后期持續更新系列文章 &#x1f680;如果有錯誤感謝請大家批評指出&#xff0c;及時修改 &#x1f680;感謝大家點贊&#x1f44d;收藏?評論? 今天水一篇吧…

【openbmc6】entity-manager

文章目錄 2.1 事件監聽:dbus在linux上使用的底層通信方式多半是unix domain socket ,事件的到來可被抽象為:socket上有數據,可讀 2.2 事件處理:由于主線程肯定有邏輯得跑,因此新開一個線程甚至多個線程專門用來監聽和處理事件,但存在多線程就意味著可能存在競爭,存在競…

Java 實現 UDP 多發多收通信

在網絡通信領域&#xff0c;UDP&#xff08;用戶數據報協議&#xff09;以其無連接、高效率的特點&#xff0c;在實時通信場景中占據重要地位。本文將結合一段實現 UDP 多發多收的 Java 代碼&#xff0c;詳細解析其實現邏輯&#xff0c;幫助開發者深入理解 UDP 通信的底層邏輯與…

Java學習第六十二部分——Git

目錄 一、關鍵概述 二、核心概念 三、常用命令 四、優勢因素 五、應用方案 六、使用建議 一、關鍵概述 提問&#xff1a;Git 是什么&#xff1f; 回答&#xff1a;一句話&#xff0c;分布式版本控制系統&#xff08;DVCS&#xff09;&#xff0c;用來跟蹤文件&#…

CDN和DNS 在分布式系統中的作用

一、DNS&#xff1a;域名系統&#xff08;Domain Name System&#xff09; 1. 核心功能 DNS是互聯網的“地址簿”&#xff0c;負責將人類易記的域名&#xff08;如www.baidu.com&#xff09;解析為計算機可識別的IP地址&#xff08;如180.101.50.242&#xff09;。沒有DNS&…

uniapp用webview導入本地網頁,ios端打開頁面空白問題

目前還沒解決&#xff0c;DCloud官方也說不行 IOS下webview加載本地網頁時&#xff0c;無法加載資源 - DCloud問答

軟考 系統架構設計師系列知識點之面向服務架構設計理論與實踐(8)

接前一篇文章:軟考 系統架構設計師系列知識點之面向服務架構設計理論與實踐(7) 所屬章節: 第15章. 面向服務架構設計理論與實踐 第3節 SOA的參考架構 15.3 SOA的參考架構 IBM的Websphere業務集成參考架構(如圖15-2所示,以下簡稱參考架構)是典型的以服務為中心的企業集…

基于 Docker 及 Kubernetes 部署 vLLM:開啟機器學習模型服務的新篇章

在當今數字化浪潮中&#xff0c;機器學習模型的高效部署與管理成為眾多開發者和企業關注的焦點。vLLM 作為一款性能卓越的大型語言模型推理引擎&#xff0c;其在 Docker 及 Kubernetes 上的部署方式如何呢&#xff1f;本文將深入探討如何在 Docker 及 Kubernetes 集群中部署 vL…

工業互聯網六大安全挑戰的密碼“解法”

目錄 工業互聯網密碼技術應用Q&A Q1&#xff1a;設備身份認證與接入控制 Q2&#xff1a;通信數據加密與完整性保護 Q3&#xff1a;遠程安全訪問 Q4&#xff1a;平臺與數據安全 Q5&#xff1a;軟件與固件安全 Q6&#xff1a;日志審計與抗抵賴 首傳信安-解決方案 總…

基于springboot的在線問卷調查系統的設計與實現(源碼+論文)

一、開發環境 1 Java語言 Java語言是當今為止依然在編程語言行業具有生命力的常青樹之一。Java語言最原始的誕生&#xff0c;不僅僅是創造者感覺C語言在編程上面很麻煩&#xff0c;如果只是專注于業務邏輯的處理&#xff0c;會導致忽略了各種指針以及垃圾回收這些操作&#x…

民法學學習筆記(個人向) Part.1

民法學學習筆記(個人向) Part.1有關民法條文背后的事理、人心、經濟社會基礎&#xff1b;民法的結構民法學習的特色就是先學最難的民法總論&#xff0c;再學較難的物權法、合同法等&#xff0c;最后再學習最簡單的婚姻、繼承、侵權部分。這是一個由難到易的過程&#xff0c;尤為…

ElasticSearch Doc Values和Fielddata詳解

一、Doc Values介紹倒排索引在搜索包含指定 term 的文檔時效率極高&#xff0c;但在執行相反操作&#xff0c;比如查詢一個文檔中包含哪些 term&#xff0c;以及進行排序、聚合等與指定字段相關的操作時&#xff0c;表現就很差了&#xff0c;這時候就需要用到 Doc Values。倒排…

【C語言】解決VScode中文亂碼問題

文章目錄【C語言】解決VScode中文亂碼問題彈出無法寫入用戶設置的處理方法彈出無法在只讀編輯器編輯的問題處理方法【C語言】解決VScode中文亂碼問題 &#x1f4ac;歡迎交流&#xff1a;在學習過程中如果你有任何疑問或想法&#xff0c;歡迎在評論區留言&#xff0c;我們可以共…

MySQL筆記4

一、范式1.概念與意義范式&#xff08;Normal Form&#xff09;是數據庫設計需遵循的規范&#xff0c;解決“設計隨意導致后期重構困難”問題。主流有 三大范式&#xff08;1NF、2NF、3NF&#xff09;&#xff0c;還有進階的 BCNF、4NF、5NF 等&#xff0c;范式間是遞進依賴&am…

切比雪夫不等式的理解以及推導【超詳細筆記】

文章目錄參考教程一、意義1. 正態分布的 3σ 法則2. 不等式的含義3. 不等式的意義二、不等式的證明1. 馬爾科夫不等式馬爾可夫不等式證明(YYY 為非負隨機變量 &#xff09;2. 切比雪夫不等式推導參考教程 一個視頻&#xff0c;徹底理解切比雪夫不等式 一、意義 1. 正態分布的…

Spring Boot Jackson 序列化常用配置詳解

一、引言在當今的 Web 開發領域&#xff0c;JSON&#xff08;JavaScript Object Notation&#xff09;已然成為數據交換的中流砥柱。無論是前后端分離架構下前后端之間的數據交互&#xff0c;還是微服務架構里各個微服務之間的通信&#xff0c;JSON 都承擔著至關重要的角色 。它…