C++硬實時調度:原理、實踐與最佳方案

在工業自動化、航空航天、醫療設備等領域,系統的實時性往往直接關系到生命安全和財產損失。C++作為高性能編程語言,為硬實時系統開發提供了強大支持。本文將深入探討C++硬實時調度的核心技術,從操作系統原理到代碼實現的全方位解析。

一、實時系統概述

1.1 實時系統定義與分類

實時系統是指系統的正確性不僅取決于計算結果的邏輯正確性,還取決于結果產生的時間。根據對時間的嚴格程度,實時系統可分為:

  • 硬實時系統(Hard Real-Time):任何截止時間的違反都可能導致災難性后果,如飛控系統、心臟起搏器
  • 軟實時系統(Soft Real-Time):偶爾違反截止時間不會導致系統失效,但會降低服務質量,如視頻流、音頻處理
  • 弱實時系統(Firm Real-Time):介于硬實時和軟實時之間,違反截止時間的后果有限,如汽車導航系統

本文主要關注硬實時系統,其對時間的要求最為嚴格。

1.2 硬實時系統的關鍵特性

  1. 確定性(Determinism)

    • 系統響應時間可預測
    • 避免不可預測的延遲,如垃圾回收、頁交換
  2. 優先級驅動調度

    • 高優先級任務必須能搶占低優先級任務
    • 優先級反轉問題需嚴格控制
  3. 資源有限性

    • 內存、CPU時間等資源必須嚴格規劃
    • 避免動態內存分配和其他不可預測操作
  4. 可靠性與容錯性

    • 系統必須能夠處理異常情況
    • 故障檢測與恢復機制必不可少

1.3 實時系統與普通系統的區別

特性普通系統硬實時系統
響應時間要求平均性能優化最壞情況響應時間保證
調度算法吞吐量優先截止時間保證
內存管理動態分配、垃圾回收靜態分配、確定性內存操作
異常處理盡力而為嚴格的故障處理機制
系統設計功能優先時間約束優先

二、操作系統實時調度基礎

2.1 實時操作系統(RTOS)

實時操作系統是專為實時應用設計的操作系統,具有以下特性:

  • 短而確定的中斷響應時間:通常在幾微秒到幾十微秒
  • 搶占式內核:高優先級任務可立即搶占低優先級任務
  • 確定性調度算法:如EDF(最早截止時間優先)、RM(速率單調)
  • 最小化的內核鎖定:減少全局鎖使用
  • 有限的系統調用延遲:所有系統調用的最壞情況時間可預測

常見的RTOS包括:

  • FreeRTOS:開源、輕量級,廣泛應用于嵌入式系統
  • VxWorks:商業RTOS,用于航空航天等高可靠性領域
  • QNX:POSIX兼容,用于汽車電子、醫療設備
  • RTLinux:Linux內核的實時擴展版本

2.2 實時調度算法

實時調度算法主要分為兩類:

2.2.1 靜態優先級調度
  • 速率單調調度(Rate Monotonic, RM)

    • 任務優先級與其周期成反比(周期越短優先級越高)
    • 適用于周期任務
    • 可調度性條件:Σ(ci/pi) ≤ n(2^(1/n) - 1)
  • 截止時間單調調度(Deadline Monotonic, DM)

    • 任務優先級與其截止時間成反比(截止時間越短優先級越高)
    • 比RM更靈活,適用于截止時間與周期不同的任務
2.2.2 動態優先級調度
  • 最早截止時間優先(Earliest Deadline First, EDF)

    • 任務優先級根據截止時間動態分配,截止時間越早優先級越高
    • 適用于混合周期和非周期任務
    • 理論上可達到100%的CPU利用率
  • 最少松弛時間優先(Least Laxity First, LLF)

    • 松弛時間 = 截止時間 - 剩余執行時間 - 當前時間
    • 松弛時間最少的任務優先執行

2.3 優先級反轉與解決方法

優先級反轉是實時系統中的一個嚴重問題,指低優先級任務持有高優先級任務所需資源,導致高優先級任務被阻塞的現象。

2.3.1 經典優先級反轉示例
  1. 任務H(高優先級)、任務M(中等優先級)、任務L(低優先級)
  2. 任務L獲取鎖資源R
  3. 任務H就緒,搶占任務L
  4. 任務H嘗試獲取鎖R,被阻塞
  5. 任務M就緒,搶占任務L(此時任務L持有鎖R)
  6. 任務M執行,延遲了任務L釋放鎖的時間
  7. 任務M執行完畢,任務L繼續執行并釋放鎖
  8. 任務H才能獲取鎖繼續執行
2.3.2 解決方案
  • 優先級繼承協議(Priority Inheritance Protocol, PIP)

    • 當高優先級任務因等待鎖而阻塞時,持有鎖的低優先級任務臨時提升到高優先級任務的級別
    • 上例中,任務L在持有鎖時會被提升到任務H的優先級,避免被任務M搶占
  • 優先級天花板協議(Priority Ceiling Protocol, PCP)

    • 每個資源分配一個優先級天花板(使用該資源的所有任務中的最高優先級)
    • 任務在獲取資源時,其優先級臨時提升到資源的優先級天花板
    • 可防止優先級反轉的級聯效應

三、C++硬實時編程技術

3.1 C++實時特性支持

C++11及以后的版本提供了一些對實時編程有用的特性:

  • 原子操作(Atomic Operations)

    #include <atomic>std::atomic<int> shared_counter(0);void increment() {shared_counter.fetch_add(1, std::memory_order_relaxed);
    }
    
  • 線程與同步原語

    #include <thread>
    #include <mutex>std::mutex mtx;
    int shared_data = 0;void worker() {std::lock_guard<std::mutex> lock(mtx);// 臨界區shared_data++;
    }
    
  • 時鐘與定時器

    #include <chrono>
    #include <thread>void periodic_task() {using namespace std::chrono;auto next_time = steady_clock::now();while (true) {// 執行任務process_data();// 計算下一個周期next_time += milliseconds(10);std::this_thread::sleep_until(next_time);}
    }
    

3.2 避免動態內存分配

動態內存分配(如newmalloc)在硬實時系統中是危險的,因為:

  1. 分配時間不確定
  2. 可能導致內存碎片
  3. 可能失敗,需要復雜的錯誤處理
3.2.1 替代方案
  • 靜態內存分配
    // 固定大小數組替代動態分配
    constexpr size_t MAX_SIZE = 1000;
    int static_buffer[MAX_SIZE];// 靜態對象池
    template<typename T, size_t N>
    class ObjectPool {
    private:union Node {T data;Node* next;};Node buffer[N];Node* free_list;public:ObjectPool() {free_list = &buffer[0];for (size_t i = 0; i < N - 1; ++i) {buffer[i].next = &buffer[i + 1];}buffer[N - 1].next = nullptr;}T* allocate() {if (!free_list) return nullptr;Node* node = free_list;free_list = node->next;return &node->data;}void deallocate(T* obj) {Node* node = reinterpret_cast<Node*>(obj);node->next = free_list;free_list = node;}
    };
    

3.3 減少中斷延遲

在硬實時系統中,中斷延遲必須最小化且可預測:

  1. 中斷服務程序(ISR)應盡可能短

    // 不好的實踐:ISR中執行復雜操作
    void isr_handler() {// 讀取傳感器數據// 處理數據// 更新顯示
    }// 好的實踐:ISR只做必要的工作,其余交給后臺任務
    std::atomic<bool> data_ready(false);void isr_handler() {// 讀取傳感器數據read_sensor_data();data_ready = true;
    }void background_task() {while (true) {if (data_ready.exchange(false)) {// 處理數據process_data();// 更新顯示update_display();}}
    }
    
  2. 禁用中斷嵌套

    // 在關鍵代碼段禁用中斷
    void critical_section() {disable_interrupts();// 執行關鍵操作// ...enable_interrupts();
    }
    

3.4 實時線程調度

在C++中,可以使用POSIX線程API設置線程優先級和調度策略:

#include <pthread.h>
#include <iostream>void* thread_function(void* arg) {// 實時線程執行的代碼while (true) {// 周期性任務process_data();pthread_yield();  // 讓出CPU}return nullptr;
}int main() {pthread_t thread;pthread_attr_t attr;struct sched_param param;// 初始化線程屬性pthread_attr_init(&attr);// 設置線程為FIFO調度策略pthread_attr_setschedpolicy(&attr, SCHED_FIFO);// 設置線程優先級(1-99,99最高)param.sched_priority = 80;pthread_attr_setschedparam(&attr, &param);// 設置線程為實時調度pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);// 創建線程pthread_create(&thread, &attr, thread_function, nullptr);// 清理pthread_attr_destroy(&attr);// 主線程繼續執行其他任務// ...// 等待線程結束pthread_join(thread, nullptr);return 0;
}

3.5 內存鎖定

為避免頁交換帶來的不可預測延遲,可鎖定內存:

#include <sys/mman.h>
#include <iostream>int main() {// 鎖定所有當前和未來的內存分配if (mlockall(MCL_CURRENT | MCL_FUTURE) == -1) {perror("mlockall failed");return 1;}// 現在可以安全地分配內存,不會發生頁交換char* buffer = new char[1024 * 1024];  // 1MB緩沖區// 使用緩沖區// ...// 釋放內存delete[] buffer;// 解鎖內存munlockall();return 0;
}

四、實時性能分析與調試

4.1 性能分析工具

  1. Cyclictest:測量系統循環延遲,評估實時性能

    cyclictest -p 80 -n -i 1000 -h 200
    
  2. RT-Tester:專門為實時系統設計的性能測試工具

    rttester -t 10 -p 70 -i 1000
    
  3. LTTng:Linux跟蹤工具包,用于分析系統行為

    lttng create my-session
    lttng enable-event --kernel sched_switch
    lttng start
    # 運行測試程序
    lttng stop
    lttng view
    

4.2 調試技術

  1. 確定性日志記錄

    // 環形緩沖區日志,避免動態內存分配
    template<typename T, size_t N>
    class CircularBuffer {
    private:T buffer[N];size_t head;size_t tail;size_t count;public:CircularBuffer() : head(0), tail(0), count(0) {}void push(const T& value) {if (count >= N) {// 緩沖區已滿,覆蓋最早的記錄tail = (tail + 1) % N;} else {count++;}buffer[head] = value;head = (head + 1) % N;}// 其他方法...
    };
    
  2. 硬件調試工具

    • 邏輯分析儀:捕獲和分析數字信號
    • 示波器:觀察電信號波形
    • JTAG/SWD調試器:直接訪問CPU內部狀態

五、C++硬實時框架與庫

5.1 OROCOS Real-Time Toolkit

OROCOS是一個開源的C++實時框架,提供:

  • 組件化架構
  • 實時通信機制
  • 任務調度
  • 與ROS集成
#include <rtt/TaskContext.hpp>
#include <rtt/Port.hpp>
#include <rtt/Component.hpp>class MyTask : public RTT::TaskContext {
public:MyTask(std::string name) : TaskContext(name) {// 初始化輸出端口addPort("output", output_port);// 設置任務周期this->setPeriod(0.01);  // 10ms周期}bool configureHook() {// 配置任務return true;}bool startHook() {// 啟動任務return true;}void updateHook() {// 周期性執行的代碼double value = get_sensor_data();output_port.write(value);}void stopHook() {// 停止任務}void cleanupHook() {// 清理資源}private:RTT::OutputPort<double> output_port;double get_sensor_data() {// 從傳感器讀取數據return 0.0;}
};// 注冊組件
ORO_CREATE_COMPONENT(MyTask)

5.2 Xenomai

Xenomai是一個Linux內核實時擴展,提供:

  • 硬實時性能
  • 多種實時調度算法
  • POSIX兼容API
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <native/task.h>
#include <native/timer.h>RT_TASK demo_task;void demo(void *arg) {RT_TASK_INFO curtaskinfo;RTIME now, previous;// 獲取任務信息rt_task_inquire(NULL, &curtaskinfo);// 設置任務為周期模式rt_task_set_periodic(NULL, TM_NOW, 1000000000);  // 1秒周期previous = rt_timer_read();while (1) {rt_task_wait_period(NULL);now = rt_timer_read();printf("Task name: %s - Execution time: %ld ms\n",curtaskinfo.name, (long)(now - previous) / 1000000);previous = now;}
}void catch_signal(int sig) {// 處理信號
}int main(int argc, char* argv[]) {char  str[10];int   ret;// 鎖定內存,防止頁交換mlockall(MCL_CURRENT|MCL_FUTURE);// 注冊信號處理signal(SIGTERM, catch_signal);signal(SIGINT, catch_signal);// 創建任務sprintf(str, "DEMO_TASK");ret = rt_task_create(&demo_task, str, 0, 99, T_JOINABLE);// 啟動任務ret = rt_task_start(&demo_task, &demo, NULL);// 等待用戶輸入getchar();// 刪除任務rt_task_delete(&demo_task);return 0;
}

5.3 FreeRTOS C++封裝

FreeRTOS是一個輕量級RTOS,可通過C++封裝提高開發效率:

#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include <iostream>// C++任務基類
class RTOS_Task {
public:RTOS_Task(const char* name, uint16_t stack_size, UBaseType_t priority): task_handle(NULL) {xTaskCreate(taskFunction,name,stack_size,this,priority,&task_handle);}virtual ~RTOS_Task() {if (task_handle != NULL) {vTaskDelete(task_handle);}}virtual void run() = 0;private:static void taskFunction(void* pvParameters) {RTOS_Task* task = static_cast<RTOS_Task*>(pvParameters);task->run();}TaskHandle_t task_handle;
};// 具體任務實現
class MyTask : public RTOS_Task {
public:MyTask() : RTOS_Task("MyTask", 1024, 2) {}void run() override {while (true) {// 任務代碼std::cout << "Task running..." << std::endl;vTaskDelay(pdMS_TO_TICKS(1000));  // 延時1秒}}
};// 主函數
int main() {// 創建任務MyTask task;// 啟動調度器vTaskStartScheduler();// 如果程序執行到這里,說明發生了錯誤while (1);return 0;
}

六、硬實時系統設計案例

6.1 工業機器人控制系統

一個典型的工業機器人控制系統包含:

  1. 關節控制任務

    • 周期:1ms
    • 優先級:最高
    • 功能:讀取編碼器數據,計算控制輸出
  2. 路徑規劃任務

    • 周期:10ms
    • 優先級:中等
    • 功能:根據目標位置計算機器人運動路徑
  3. 傳感器數據處理任務

    • 周期:5ms
    • 優先級:中等
    • 功能:處理激光雷達、視覺等傳感器數據
  4. 通信任務

    • 周期:20ms
    • 優先級:較低
    • 功能:與上位機通信,接收指令和發送狀態

以下是一個簡化的關節控制任務實現:

#include <pthread.h>
#include <iostream>
#include <atomic>// 全局標志
std::atomic<bool> running(true);// 電機控制接口
class MotorController {
public:void set_position(double position) {// 實際硬件控制代碼// ...}double get_position() {// 讀取編碼器位置// ...return 0.0;}
};// PID控制器
class PIDController {
private:double kp, ki, kd;double error_sum, last_error;public:PIDController(double p, double i, double d): kp(p), ki(i), kd(d), error_sum(0), last_error(0) {}double compute(double setpoint, double current_value, double dt) {double error = setpoint - current_value;error_sum += error * dt;double error_derivative = (error - last_error) / dt;last_error = error;return kp * error + ki * error_sum + kd * error_derivative;}
};// 關節控制任務
void* joint_control_task(void* arg) {MotorController motor;PIDController pid(10.0, 0.5, 2.0);// 設置線程為FIFO調度,優先級90pthread_setschedprio(pthread_self(), 90);// 任務周期1msconst int period_ns = 1000000;  // 1ms = 1,000,000ns// 計算第一個截止時間struct timespec next_time;clock_gettime(CLOCK_MONOTONIC, &next_time);while (running) {// 讀取當前位置double current_position = motor.get_position();// 計算目標位置(簡化示例)double target_position = 0.5 * sin(2 * M_PI * 0.1 * clock() / CLOCKS_PER_SEC);// 計算控制輸出double control_output = pid.compute(target_position, current_position, 0.001);// 設置電機位置motor.set_position(control_output);// 等待下一個周期next_time.tv_nsec += period_ns;while (next_time.tv_nsec >= 1000000000) {next_time.tv_nsec -= 1000000000;next_time.tv_sec++;}clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &next_time, NULL);}return nullptr;
}// 主函數
int main() {pthread_t thread;pthread_attr_t attr;// 初始化線程屬性pthread_attr_init(&attr);// 設置線程為FIFO調度struct sched_param param;param.sched_priority = 90;pthread_attr_setschedparam(&attr, &param);pthread_attr_setschedpolicy(&attr, SCHED_FIFO);// 創建關節控制線程pthread_create(&thread, &attr, joint_control_task, nullptr);// 主線程可以執行其他任務// ...// 等待用戶輸入退出std::cout << "Press Enter to exit..." << std::endl;std::cin.get();// 停止任務running = false;// 等待線程結束pthread_join(thread, nullptr);return 0;
}

七、硬實時系統驗證與測試

7.1 最壞情況執行時間(WCET)分析

WCET分析是硬實時系統驗證的核心,常用方法包括:

  1. 靜態分析:通過代碼分析確定最壞情況執行時間

    • 工具:aiT、CompCert
  2. 測量分析:通過實際運行測量執行時間

    • 工具:OProfile、gprof
  3. 混合分析:結合靜態和測量方法

示例:使用aiT進行WCET分析

# 編譯程序并生成分析所需信息
gcc -O2 -finstrument-functions my_program.c -o my_program# 使用aiT進行分析
ait my_program -o wcet_report.txt

7.2 可調度性分析

驗證系統中所有任務是否能滿足其截止時間:

// 可調度性分析示例(EDF算法)
bool is_schedulable_edf(const std::vector<Task>& tasks) {double utilization = 0.0;for (const auto& task : tasks) {utilization += task.execution_time / task.period;}// EDF算法在理想情況下可調度利用率<=1的任務集return utilization <= 1.0;
}// 可調度性分析示例(RM算法)
bool is_schedulable_rm(const std::vector<Task>& tasks) {double utilization = 0.0;size_t n = tasks.size();for (const auto& task : tasks) {utilization += task.execution_time / task.period;}// RM算法的可調度性充分條件double bound = n * (std::pow(2.0, 1.0/n) - 1);return utilization <= bound;
}

7.3 壓力測試與容錯測試

  1. 壓力測試

    • 在資源極限條件下運行系統
    • 驗證系統在過載情況下的行為
  2. 容錯測試

    • 注入故障(如硬件故障、通信中斷)
    • 驗證系統的恢復能力

示例:網絡中斷測試腳本

#!/bin/bash# 循環測試網絡中斷恢復能力
for i in {1..100}; doecho "Test iteration $i"# 斷開網絡ifconfig eth0 downecho "Network disconnected"sleep 2# 檢查系統是否仍在運行# ...# 恢復網絡ifconfig eth0 upecho "Network reconnected"sleep 10# 驗證系統是否恢復正常# ...
done

八、硬實時系統設計最佳實踐

  1. 最小化關鍵路徑

    • 減少關鍵任務的執行時間
    • 避免關鍵任務中的阻塞操作
  2. 確定性內存管理

    • 避免動態內存分配
    • 使用靜態分配和內存池
  3. 優先級分配策略

    • 遵循速率單調或截止時間單調原則
    • 避免優先級反轉
  4. 硬件與軟件協同設計

    • 選擇適合實時需求的硬件平臺
    • 優化硬件/軟件接口
  5. 嚴格的編碼規范

    • 避免遞歸和復雜算法
    • 限制函數調用深度
    • 使用確定性數據結構
  6. 防御性編程

    • 對所有外部輸入進行驗證
    • 實現健壯的錯誤處理機制
    • 使用斷言檢查內部狀態
  7. 全面測試與驗證

    • 執行最壞情況分析
    • 進行長時間穩定性測試
    • 模擬各種故障情況

九、總結與未來趨勢

硬實時系統開發是一項極具挑戰性的工作,需要從硬件到軟件的全方位考慮。C++作為一種高性能語言,為硬實時系統提供了必要的工具和特性,但也要求開發者具備深入的系統知識和編程技能。

未來,隨著物聯網、自動駕駛、工業4.0等領域的發展,硬實時系統的需求將不斷增長。以下趨勢值得關注:

  1. 異構計算與實時性:GPU、FPGA等異構計算設備在實時系統中的應用
  2. 機器學習與實時決策:輕量級深度學習模型在實時控制系統中的應用
  3. 實時容器與微服務:在資源受限環境中部署實時微服務
  4. 形式化方法與驗證工具:更強大的自動化驗證技術

通過合理選擇技術棧、遵循最佳實踐、利用先進工具,開發者可以構建出既滿足嚴格實時要求,又具有高可靠性和可維護性的C++硬實時系統。

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

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

相關文章

LeetCode 1156.單字符重復子串的最大長度

如果字符串中的所有字符都相同&#xff0c;那么這個字符串是單字符重復的字符串。 給你一個字符串 text&#xff0c;你只能交換其中兩個字符一次或者什么都不做&#xff0c;然后得到一些單字符重復的子串。返回其中最長的子串的長度。 示例 1&#xff1a; 輸入&#xff1a;text…

K近鄰算法的分類與回歸應用場景

K近鄰算法的分類與回歸應用場景 K近鄰&#xff08;K-Nearest Neighbors, KNN&#xff09;算法是一種基礎但強大的機器學習方法&#xff0c;它既可以用于分類問題&#xff0c;也能解決回歸問題。 兩者的核心思想都是基于"近朱者赤&#xff0c;近墨者黑"的原理&#xf…

算法精講--正則表達式(二):分組、引用與高級匹配技術

算法精講–正則表達式&#xff08;二&#xff09;&#xff1a;分組、引用與高級匹配技術 &#x1f680;正則表達式的真正力量在于組合使用各種語法元素&#xff0c;創造出強大而精確的匹配模式&#xff01; —— 作者&#xff1a;無限大 推薦閱讀時間&#xff1a;25 分鐘 適用人…

python+requests 接口自動化測試實戰

首先介紹一下python的requests模塊&#xff1a; requests的使用介紹&#xff1a;requests快速入門 Python結合requests庫實現接口自動化測試環境說明&#xff1a; 1.WIN 7, 64位 2.Python3.4.3 &#xff08;pip-8.1.2&#xff09; 3.Requests —>pip install requests 4.U…

NAT 實驗

NAT 實驗 一.實驗拓撲圖實驗目的 1.按照圖示配置 IP 地址 2.私網 A 通過 R1 接入到互聯網&#xff0c;私網 B 通過 R3 接入到互聯網 3.私網 A 內部存在 Vlan10 和 Vlan20&#xff0c;通過 R1 上單臂路由訪問外部網絡 4.私網 A 通過 NAPT 使 Vlan10 和 Vlan20 都能夠使用 R1 的公…

buuctf——web刷題第三頁

第三頁 目錄 [FBCTF2019]RCEService [0CTF 2016]piapiapia [Zer0pts2020]Can you guess it? [WUSTCTF2020]顏值成績查詢 [SUCTF 2019]Pythonginx [MRCTF2020]套娃 [CSCCTF 2019 Qual]FlaskLight [watevrCTF-2019]Cookie Store [WUSTCTF2020]CV Maker [紅明谷CTF 202…

前后端分離項目中的接口設計與調用流程——以高仙機器人集成為例

一、背景介紹在前后端分離項目開發中&#xff0c;前端頁面需要頻繁調用后端接口獲取數據。在高仙機器人對接項目中&#xff0c;我們采用了若依&#xff08;RuoYi&#xff09;框架&#xff0c;前端通過統一的 API 封裝與后端進行數據交互&#xff0c;而后端再對接高仙官方的 OPE…

【第五節】部署http接口到ubuntu server上的docker內

描述清楚需求&#xff0c;讓deepseek幫我們寫一個demo&#xff0c;文件結構如下 FLASK_API_001 ├── app.py └── Dockerfile └── requirements.txtapp.pyfrom flask import Flask, jsonify, requestapp Flask(__name__)# 根路由 app.route(/) def home():return "…

在 IntelliJ IDEA 中添加框架支持的解決方案(沒有出現Add Framework Support)

在 IntelliJ IDEA 中添加框架支持的解決方案 問題背景 版本變化&#xff1a;在 IntelliJ IDEA 2023.2 及更高版本中&#xff0c;項目右鍵菜單中的 “Add Framework Support” 選項已被移除。 常見需求&#xff1a;為 Java 項目添加框架支持&#xff08;如 Maven、Spring 等&am…

北京-4年功能測試2年空窗-報培訓班學測開-第五十天

咦&#xff0c;昨天路上寫一半就到家了&#xff0c;后來想早點睡就忘了還要發了&#xff0c;現在趕緊補上昨天是最后一節課(我們將一整天的課稱為一節&#xff09;&#xff0c;這就結課了昨天講了簡歷編寫&#xff0c;面試要準備的內容&#xff0c;還有redis和docker也沒有什么…

華為鴻蒙HarmonyOpenEye項目:開眼App的鴻蒙實現之旅

華為鴻蒙HarmonyOpenEye項目&#xff1a;開眼App的鴻蒙實現之旅 引言 在當今移動應用開發的浪潮中&#xff0c;鴻蒙系統憑借其獨特的分布式能力和高效的開發框架&#xff0c;吸引了眾多開發者的目光。今天要給大家介紹的是一個基于華為鴻蒙系統開發的開眼App項目——HarmonyO…

代碼隨想錄day36dp4

文章目錄1049.最后一塊石頭的重量II494.目標和474.一和零1049.最后一塊石頭的重量II 題目鏈接 文章講解 class Solution { public:int lastStoneWeightII(vector<int>& stones) {// 1. 確定 DP 數組及下標的含義&#xff1a;// dp[i][j] 表示考慮前 i 塊石頭&#…

Python 爬蟲實戰指南:按關鍵字搜索商品

在電商領域&#xff0c;按關鍵字搜索商品并獲取其詳情信息是一項常見的需求。無論是進行市場調研、競品分析還是用戶體驗優化&#xff0c;能夠快速準確地獲取商品信息都至關重要。1688 作為國內領先的 B2B 電商平臺&#xff0c;提供了豐富的商品資源。本文將詳細介紹如何使用 P…

【源力覺醒 創作者計劃】百度AI的開放新篇章:文心4.5本地化部署指南與未來生態戰略展望

百度AI的開放新篇章&#xff1a;文心4.5本地化部署指南與未來生態戰略展望 一起來玩轉文心大模型吧&#x1f449;文心大模型免費下載地址&#xff1a;https://ai.gitcode.com/theme/1939325484087291906 &#x1f31f; 嗨&#xff0c;我是IRpickstars&#xff01; &#x1f30…

測試工作中的質量門禁管理

一、前言 測試階段的質量門禁設計要考慮幾個維度,首先是研發流程的階段劃分,每個階段都要有明確的準入準出標準;其次要考慮不同測試類型的特點,比如功能測試和性能測試的驗收標準肯定不同;最后還要平衡質量要求和項目進度。 在單元測試階段,可以設置通過率和覆蓋率的閾值…

線上分享:解碼eVTOL安全基因,構建安全飛行生態

隨著城市空中交通&#xff08;UAM&#xff09;快速發展&#xff0c;電動垂直起降飛行器&#xff08;eVTOL&#xff09;面臨嚴格的安全與可靠性要求&#xff0c;需滿足全球適航標準及全生命周期分析。安全與可靠的飛行系統成為行業關注的焦點。在此背景下&#xff0c;本期線上分…

C回調函數基礎用法

&#x1f4cc; 定義&#xff1a;回調函數是通過函數指針傳遞給另一個函數的函數&#xff0c;這個被傳進去的函數將在某個時刻被“回調”調用。換句話說&#xff1a;你定義一個函數 A把函數 A 的地址&#xff08;即函數指針&#xff09;作為參數傳給函數 B函數 B 在合適的時機調…

手撕設計模式之消息推送系統——橋接模式

手撕設計模式之消息推送系統——橋接模式 1.業務需求 ? 大家好&#xff0c;我是菠菜啊&#xff0c;好久不見&#xff0c;今天給大家帶來的是——橋接模式。老規矩&#xff0c;在介紹這期內容前&#xff0c;我們先來看看這樣的需求&#xff1a;我們現在要做一個消息推送系統&…

Java 大廠面試題 -- JVM 垃圾回收機制大揭秘:從原理到實戰的全維度優化

最近佳作推薦&#xff1a; Java 大廠面試題 – JVM 面試題全解析&#xff1a;橫掃大廠面試&#xff08;New&#xff09; Java 大廠面試題 – 從菜鳥到大神&#xff1a;JVM 實戰技巧讓你收獲滿滿&#xff08;New&#xff09; Java 大廠面試題 – JVM 與云原生的完美融合&#xf…

圖機器學習(9)——圖正則化算法

圖機器學習&#xff08;9&#xff09;——圖正則化算法1. 圖正則化方法2. 流形正則化與半監督嵌入3. 神經圖學習4. Planetoid1. 圖正則化方法 淺層嵌入方法已經證明&#xff0c;通過編碼數據點間的拓撲關系可以構建更魯棒的分類器來處理半監督任務。本質上&#xff0c;網絡信息…