webrtc弱網-LossBasedBweV2類源碼分析與算法原理

1. 核心功能

LossBasedBweV2是WebRTC Google Congestion Control (GoogCC) 算法套件中的第二代基于丟包的帶寬估計器。它的核心功能是:

  • 帶寬估計: 根據網絡數據包的丟失情況,估算當前網絡路徑可用的帶寬上限。其核心假設是:當發送速率超過網絡容量時,將出現擁塞,表現為數據包丟失。通過分析丟包模式,它可以反向推斷出這個容量瓶頸。

  • 狀態輸出: 不僅輸出一個帶寬估計值(DataRate),還輸出一個狀態(LossBasedState)。這個狀態用于指導上層控制器(如GoogCCNetworkController)的行為,例如:

    • kIncreasing/kIncreaseUsingPadding: 建議可以嘗試增加發送速率,后者暗示可以使用填充數據來探測。

    • kDecreasing: 估計值正在因丟包而下降,應減少發送速率。

    • kDelayBasedEstimate: 當前未處于丟包受限狀態,應優先使用基于延遲的估計結果。

  • 多源信息融合: 它并非孤立工作,而是融合了多種信息源:

    • 丟包信息: 主要輸入,來自RTCP Receiver Reports或傳輸反饋。

    • 延遲基于估計值: 來自DelayBasedBwe的另一個估計值,用作上限或候選值。

    • 確認速率: 當前網絡的吞吐量測量值,用作參考和下限。

    • 配置參數: 通過字段試驗(Field Trials)提供大量可調參數,用于控制算法行為。

2. 核心算法原理

LossBasedBweV2的核心算法基于最大似然估計(Maximum Likelihood Estimation, MLE),其基本原理可以概括為:

  1. 建立丟包模型: 算法假設一個信道模型,其中包丟失概率由兩部分組成:

    • 固有丟失(inherent_loss: 代表與擁塞無關的隨機丟包(如無線鏈路錯誤)。

    • 擁塞丟失: 當發送速率(sending_rate)超過信道的“丟包受限帶寬”(loss_limited_bandwidth)時,按一定比例((sending_rate - loss_limited_bandwidth) / sending_rate)產生額外丟包。
      總的丟包概率函數為:
      loss_probability = inherent_loss + (1 - inherent_loss) * max(0, (sending_rate - loss_limited_bandwidth) / sending_rate)

  2. 定義似然函數: 給定一組觀測到的包接收/丟失情況,計算在這組信道參數(inherent_loss,?loss_limited_bandwidth)下,觀察到這組結果的似然度(Likelihood)。似然度是模型參數的函數。

  3. 最大化似然函數: 算法的目標是找到一組參數(inherent_loss,?loss_limited_bandwidth),使得觀察到的數據的似然度最大。這組參數就是最可能產生當前觀測數據的信道狀態,其中的loss_limited_bandwidth就是最終的帶寬估計值。

  4. 牛頓法優化: 為了高效地找到使似然函數最大化的參數,算法對inherent_loss參數使用了牛頓法(Newton's Method)進行迭代優化。GetDerivatives()函數計算似然函數的一階和二階導數,NewtonsMethodUpdate()根據導數更新inherent_loss的值。

  5. 高帶寬偏好: 為了防止算法在存在隨機丟包(高inherent_loss)時過于保守,似然函數中引入了一個高帶寬偏置項(high_bandwidth_bias。該項會隨著候選帶寬的增加而增加,從而讓算法更傾向于選擇高帶寬的估計,即使它需要假設一個更高的固有丟包率來解釋觀測到的丟包。GetHighBandwidthBias()AdjustBiasFactor()負責計算這個偏置。

3. 關鍵數據結構

  • LossBasedBweV2::Config

    • 作用: 包含所有可配置的實驗參數,通過字段試驗字符串(如WebRTC-Bwe-LossBasedBweV2)解析而來。這些參數控制著算法的幾乎所有方面,包括觀察窗口大小、候選因子、牛頓法迭代次數、各種閾值和開關等。其有效性由IsConfigValid()函數驗證。

    • 重要性: 使得算法行為高度可調,便于A/B測試和算法迭代。

  • LossBasedBweV2::ChannelParameters

    • 作用: 表示信道模型的一個候選參數集。

      • loss_limited_bandwidth: 待評估的帶寬估計值。

      • inherent_loss: 對應的固有丟包率估計。

    • 重要性: MLE優化過程的核心操作對象。

  • LossBasedBweV2::Observation

    • 作用: 存儲一個時間窗口內的丟包觀測結果。由多次UpdateBandwidthEstimate調用中積累的PacketResult匯總而成,直到持續時間滿足observation_duration_lower_bound

      • num_packets,?num_lost_packets,?num_received_packets

      • size,?lost_size?(字節數,use_byte_loss_rate為true時使用)

      • sending_rate: 該觀測窗口內的平均發送速率(經過平滑處理)。

      • id: 觀測的唯一ID,用于時間加權。

    • 重要性: 是似然計算的基礎數據單元。

  • LossBasedBweV2::Result

    • 作用: 算法的輸出結果。

      • bandwidth_estimate: 最終計算出的基于丟包的帶寬估計值。

      • state: 估計器的狀態(Increasing/Decreasing/DelayBasedEstimate),用于指導擁塞控制行為。

  • HoldInfo?和?PaddingInfo

    • 作用: 用于實現狀態保持(Hold)填充(Padding)邏輯。

      • HoldInfo: 在估計減少后,暫時限制估計值的增長幅度和持續時間,避免過快回升再次引發丟包。

      • PaddingInfo: 當狀態為kIncreaseUsingPadding時,記錄用于判斷是否持續進行填充探測的速率和時間戳。

    • 重要性: 這些是增強算法穩定性和主動探測能力的機制。

4. 核心方法詳解

  • UpdateBandwidthEstimate

    • 入口方法。接收新的包反饋信息(packet_results)、當前的延遲估計值(delay_based_estimate)和是否在應用限制區域(in_alr)的標志。

    • 流程:

      1. 更新觀測值: 調用PushBackObservation將新的包結果匯總到當前部分觀測中,如果持續時間足夠,則創建一個新的Observation并加入環形緩沖區。

      2. 生成候選: 調用GetCandidates生成一組待評估的ChannelParameters候選。候選來自:

        • 當前估計乘以配置的candidate_factors(如1.02, 1.0, 0.95)。

        • 確認速率(acknowledged_bitrate_)。

        • 延遲估計值(delay_based_estimate_)。

        • 即時上限(GetInstantUpperBound(),在ALR狀態下)。

      3. 評估候選: 對每個候選,使用牛頓法優化其inherent_lossNewtonsMethodUpdate),然后計算其似然函數值加上高帶寬偏置后的目標函數值GetObjective)。

      4. 選擇最佳候選: 選擇目標函數值最大的候選作為best_candidate

      5. 應用約束和規則

        • 平均丟失檢查: 如果平均上報丟包率大于最佳候選的固有丟包率,可能禁止增加(not_increase_if_inherent_loss_less_than_average_loss)。

        • 延遲增加窗口: 在剛減少帶寬后的一段時間(delayed_increase_window)內,限制增長上限(bandwidth_limit_in_current_window)。

        • 確認速率約束: 在丟包受限狀態下,如果估計要增加,則其上限受acknowledged_bitrate_乘以一個因子約束。

      6. 最終邊界處理: 將最佳候選的帶寬與即時下限(GetInstantLowerBound,主要來自確認速率)、即時上限(GetInstantUpperBound,基于平均丟包率計算)和延遲估計值進行比對,得到最終的bounded_bandwidth_estimate

      7. 狀態機更新: 根據最終估計值的變化、與延遲估計的關系以及Hold/Padding的狀態,決定新的LossBasedState

      8. 更新內部狀態: 設置current_best_estimate_loss_based_result_last_hold_info_last_padding_info_等。

  • GetCandidates

    • 根據配置和當前狀態,生成一系列帶寬候選值,然后為每個帶寬值創建一個ChannelParameters結構體,并為其設置一個可行的初始inherent_lossGetFeasibleInherentLoss)。

  • GetDerivatives?和?NewtonsMethodUpdate

    • MLE優化的核心。GetDerivatives計算當前參數下似然函數對inherent_loss的一階和二階導數。NewtonsMethodUpdate根據牛頓迭代公式?inherent_loss -= step_size * (first_derivative / second_derivative)?更新參數,并將結果鉗位到可行范圍內?[inherent_loss_lower_bound, GetInherentLossUpperBound]

  • GetObjective

    • 計算候選參數的目標函數值,即對數似然值 + 高帶寬偏置。算法目標是最大化該函數。

  • GetInstantUpperBound?和?CalculateInstantUpperBound

    • 基于近期平均丟包率計算一個帶寬上限。其模型為:instant_upper_bound = bandwidth_balance / (average_loss - loss_offset)。如果平均丟包率很低,這個上限會很高(max_bitrate_),丟包率越高,這個上限越低。

  • GetInstantLowerBound?和?CalculateInstantLowerBound

    • 計算帶寬下限,通常取max(min_bitrate_, acknowledged_bitrate_ * factor)。確保估計值不會低于當前網絡的實際吞吐量太多。

5. 設計亮點

  1. 基于模型的MLE方法: 相比于簡單的丟包閾值法(如SendSideBandwidthEstimation中使用的),V2版本采用了更嚴謹的概率模型和優化方法,理論上能更準確地反映網絡狀態。

  2. 靈活可配置性: 通過大量的字段試驗參數暴露了算法的核心旋鈕,使得算法可以快速迭代和調優,無需修改代碼。

  3. 多候選評估: 不是只做一次優化,而是生成多個候選點并評估,避免陷入局部最優,并能融合其他估計源(如延遲估計、確認速率)。

  4. 狀態機與控制邏輯: 輸出的State為上層控制器提供了豐富的語義信息,使得擁塞控制策略可以更精細,例如區分“可用填充數據探測”的增加和普通增加。

  5. 時間加權: 對觀測窗口內的歷史數據使用指數衰減加權(temporal_weights_),更重視近期的網絡狀況。

  6. Hold機制: 在帶寬下降后引入一個“冷靜期”,防止估計過快反彈,提高穩定性。

  7. 區分包丟失率和字節丟失率: 通過use_byte_loss_rate開關,可以選擇是基于包計數還是基于字節計數來計算丟包率,以適應不同的場景。

6. 典型工作流程

  1. 初始化: 創建LossBasedBweV2對象,通過字段試驗解析并驗證配置(CreateConfig,?IsConfigValid)。初始化觀察窗口、權重向量等。初始狀態為未就緒。

  2. 設置初始值: 通常由上層控制器調用SetBandwidthEstimate或通過UpdateBandwidthEstimate傳入的第一個delay_based_estimate來設置初始帶寬估計。

  3. 持續更新

    • 上層控制器定期(如每次收到傳輸反饋時)調用UpdateBandwidthEstimate

    • 該方法匯總包反饋,形成觀測點。

    • 生成多個候選帶寬值。

    • 對每個候選,優化其固有丟包率,并計算目標函數。

    • 選擇最佳候選。

    • 應用各種約束和規則(Hold、ACK速率約束等)得到最終估計。

    • 根據最終估計值的變化和與其他估計值的關系,更新狀態機。

    • 返回Result(帶寬+狀態)。

  4. 控制決策: 上層控制器(如GoogCCNetworkController)根據返回的Result中的statebandwidth_estimate,結合其他模塊(如延遲基于BWE、探測器)的輸出,最終決定目標碼率、是否發起探測等控制命令。

7. LossBasedBweV2 核心算法流程圖

7.1.總體流程圖

7.2.處理包結果并創建觀測

7.3.生成候選帶寬值

7.4.評估候選并選擇最佳

7.5.應用后處理規則

7.6.確定最終估計與狀態

7.7.牛頓法優化過程

8.核心算法精解

void LossBasedBweV2::UpdateBandwidthEstimate(rtc::ArrayView<const PacketResult> packet_results,DataRate delay_based_estimate,bool in_alr) {// 存儲延遲基于的帶寬估計值,用于后續比較和約束delay_based_estimate_ = delay_based_estimate;// 檢查估計器是否已啟用if (!IsEnabled()) {RTC_LOG(LS_WARNING) << "The estimator must be enabled before it can be used.";return;}// 檢查是否有包結果數據if (packet_results.empty()) {RTC_LOG(LS_VERBOSE) << "The estimate cannot be updated without any loss statistics.";return;}// 處理包結果并創建觀測數據if (!PushBackObservation(packet_results)) {return;}// 如果當前最佳估計尚未初始化,使用延遲基于的估計進行初始化if (!IsValid(current_best_estimate_.loss_limited_bandwidth)) {if (!IsValid(delay_based_estimate)) {RTC_LOG(LS_WARNING) << "The delay based estimate must be finite: " << ToString(delay_based_estimate);return;}current_best_estimate_.loss_limited_bandwidth = delay_based_estimate;loss_based_result_ = {.bandwidth_estimate = delay_based_estimate,.state = LossBasedState::kDelayBasedEstimate};}// 初始化最佳候選為當前最佳估計ChannelParameters best_candidate = current_best_estimate_;double objective_max = std::numeric_limits<double>::lowest();// 生成并評估所有候選帶寬值for (ChannelParameters candidate : GetCandidates(in_alr)) {// 使用牛頓法優化候選的固有丟包率參數NewtonsMethodUpdate(candidate);// 計算候選的目標函數值const double candidate_objective = GetObjective(candidate);// 選擇目標函數值最大的候選if (candidate_objective > objective_max) {objective_max = candidate_objective;best_candidate = candidate;}}// 如果估計值減少了,記錄減少時間if (best_candidate.loss_limited_bandwidth <current_best_estimate_.loss_limited_bandwidth) {last_time_estimate_reduced_ = last_send_time_most_recent_observation_;}// 如果平均丟包率大于當前固有丟包率,且配置允許,禁止增加估計值if (GetAverageReportedLossRatio() > best_candidate.inherent_loss &&config_->not_increase_if_inherent_loss_less_than_average_loss &&current_best_estimate_.loss_limited_bandwidth <best_candidate.loss_limited_bandwidth) {best_candidate.loss_limited_bandwidth =current_best_estimate_.loss_limited_bandwidth;}// 如果處于丟包受限狀態,應用額外的約束if (IsInLossLimitedState()) {// 在延遲增加窗口內限制估計值的增長if (recovering_after_loss_timestamp_.IsFinite() &&recovering_after_loss_timestamp_ + config_->delayed_increase_window >last_send_time_most_recent_observation_ &&best_candidate.loss_limited_bandwidth >bandwidth_limit_in_current_window_) {best_candidate.loss_limited_bandwidth =bandwidth_limit_in_current_window_;}// 檢查估計是否在丟包受限狀態下增加bool increasing_when_loss_limited = IsEstimateIncreasingWhenLossLimited(/*old_estimate=*/current_best_estimate_.loss_limited_bandwidth,/*new_estimate=*/best_candidate.loss_limited_bandwidth);// 如果估計在增加且確認速率有效,使用確認速率約束估計值if (increasing_when_loss_limited && IsValid(acknowledged_bitrate_)) {double rampup_factor = config_->bandwidth_rampup_upper_bound_factor;// 如果在保持狀態下,使用不同的增長因子if (IsValid(last_hold_info_.rate) &&acknowledged_bitrate_ <config_->bandwidth_rampup_hold_threshold * last_hold_info_.rate) {rampup_factor = config_->bandwidth_rampup_upper_bound_factor_in_hold;}// 應用確認速率約束best_candidate.loss_limited_bandwidth =std::max(current_best_estimate_.loss_limited_bandwidth,std::min(best_candidate.loss_limited_bandwidth,rampup_factor * (*acknowledged_bitrate_)));// 如果狀態為減少但估計值未變,稍微增加以確保狀態切換if (loss_based_result_.state == LossBasedState::kDecreasing &&best_candidate.loss_limited_bandwidth ==current_best_estimate_.loss_limited_bandwidth) {best_candidate.loss_limited_bandwidth =current_best_estimate_.loss_limited_bandwidth +DataRate::BitsPerSec(1);}}}// 應用最終邊界約束DataRate bounded_bandwidth_estimate = DataRate::PlusInfinity();if (IsValid(delay_based_estimate_)) {bounded_bandwidth_estimate =std::max(GetInstantLowerBound(),std::min({best_candidate.loss_limited_bandwidth,GetInstantUpperBound(), delay_based_estimate_}));} else {bounded_bandwidth_estimate = std::max(GetInstantLowerBound(), std::min(best_candidate.loss_limited_bandwidth,GetInstantUpperBound()));}// 如果配置要求約束最佳候選,并且約束后的估計小于最佳候選,重置估計if (config_->bound_best_candidate &&bounded_bandwidth_estimate < best_candidate.loss_limited_bandwidth) {RTC_LOG(LS_INFO) << "Resetting loss based BWE to " << bounded_bandwidth_estimate.kbps()<< "due to loss. Avg loss rate: " << GetAverageReportedLossRatio();current_best_estimate_.loss_limited_bandwidth = bounded_bandwidth_estimate;current_best_estimate_.inherent_loss = 0;} else {current_best_estimate_ = best_candidate;// 確保估計不低于確認速率的下限if (config_->lower_bound_by_acked_rate_factor > 0.0) {current_best_estimate_.loss_limited_bandwidth =std::max(current_best_estimate_.loss_limited_bandwidth,GetInstantLowerBound());}}// 處理保持狀態下的估計約束if (loss_based_result_.state == LossBasedState::kDecreasing &&last_hold_info_.timestamp > last_send_time_most_recent_observation_ &&bounded_bandwidth_estimate < delay_based_estimate_) {// 確保確認速率是保持速率的下限if (config_->lower_bound_by_acked_rate_factor > 0.0) {last_hold_info_.rate =std::max(GetInstantLowerBound(), last_hold_info_.rate);}// 帶寬估計不允許超過保持速率loss_based_result_.bandwidth_estimate =std::min(last_hold_info_.rate, bounded_bandwidth_estimate);return;}// 確定最終狀態if (IsEstimateIncreasingWhenLossLimited(/*old_estimate=*/loss_based_result_.bandwidth_estimate,/*new_estimate=*/bounded_bandwidth_estimate) &&CanKeepIncreasingState(bounded_bandwidth_estimate) &&bounded_bandwidth_estimate < delay_based_estimate_ &&bounded_bandwidth_estimate < max_bitrate_) {// 設置增加狀態,可能使用填充數據進行探測if (config_->padding_duration > TimeDelta::Zero() &&bounded_bandwidth_estimate > last_padding_info_.padding_rate) {last_padding_info_.padding_rate = bounded_bandwidth_estimate;last_padding_info_.padding_timestamp =last_send_time_most_recent_observation_;}loss_based_result_.state = config_->padding_duration > TimeDelta::Zero()? LossBasedState::kIncreaseUsingPadding: LossBasedState::kIncreasing;} else if (bounded_bandwidth_estimate < delay_based_estimate_ &&bounded_bandwidth_estimate < max_bitrate_) {// 設置減少狀態if (loss_based_result_.state != LossBasedState::kDecreasing &&config_->hold_duration_factor > 0) {RTC_LOG(LS_INFO) << this << " " << "Switch to HOLD. Bounded BWE: "<< bounded_bandwidth_estimate.kbps()<< ", duration: " << last_hold_info_.duration.ms();last_hold_info_ = {.timestamp = last_send_time_most_recent_observation_ +last_hold_info_.duration,.duration =std::min(kMaxHoldDuration, last_hold_info_.duration *config_->hold_duration_factor),.rate = bounded_bandwidth_estimate};}last_padding_info_ = PaddingInfo();loss_based_result_.state = LossBasedState::kDecreasing;} else {// 重置保持和填充信息,使用延遲基于的估計last_hold_info_ = {.timestamp = Timestamp::MinusInfinity(),.duration = kInitHoldDuration,.rate = DataRate::PlusInfinity()};last_padding_info_ = PaddingInfo();loss_based_result_.state = LossBasedState::kDelayBasedEstimate;}// 設置最終帶寬估計值loss_based_result_.bandwidth_estimate = bounded_bandwidth_estimate;// 更新延遲增加窗口和帶寬限制if (IsInLossLimitedState() &&(recovering_after_loss_timestamp_.IsInfinite() ||recovering_after_loss_timestamp_ + config_->delayed_increase_window <last_send_time_most_recent_observation_)) {bandwidth_limit_in_current_window_ =std::max(kCongestionControllerMinBitrate,current_best_estimate_.loss_limited_bandwidth *config_->max_increase_factor);recovering_after_loss_timestamp_ = last_send_time_most_recent_observation_;}
}

LossBasedBweV2是WebRCC中一個設計復雜、高度可配置的第二代基于丟包的帶寬估計器。它采用最大似然估計原理,結合了信道模型、優化算法、多源信息融合和狀態機邏輯,旨在更準確、更穩定地從丟包事件中推斷網絡帶寬,并為擁塞控制決策提供豐富的依據。

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

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

相關文章

AI代理化檢索:智能信息獲取新范式

代理化檢索(Agentic Retrieval)是一種由AI代理自主管理的信息檢索范式,通過動態規劃、工具調用和多步推理提升復雜查詢的處理能力。其核心機制、技術實現和應用特點如下: 一、核心機制 自主決策循環 代理通過循環執行"規劃-行動-觀察"流程處理查詢: 規劃階段:…

Android Studio中的各種Java版本區別

Android Studio中的各種Java版本 創建一個項目&#xff0c;app模塊的build.gradle.kts默認配置如下&#xff1a; plugins {alias(libs.plugins.android.application)alias(libs.plugins.kotlin.android) }android {namespace "cn.android666.javaversiontest"comp…

ubuntu新增磁盤擴展LV卷

登錄平臺 login as: wqbboy wqbboy172.17.2.86s password: Welcome to Ubuntu 22.04.5 LTS (GNU/Linux 5.15.0-153-generic x86_64)* Documentation: https://help.ubuntu.com* Management: https://landscape.canonical.com* Support: https://ubuntu.com/proSyst…

Day 16: GAN生成對抗網絡專項 - 從博弈論到藝術創作的完整之旅

Day 16: GAN生成對抗網絡專項 - 從博弈論到藝術創作的完整之旅 ?? 學習目標: 深度掌握生成對抗網絡理論與實踐,從博弈論基礎到風格遷移應用的完整技術棧 ? 學習時長: 6小時深度學習 (理論3小時 + 實踐3小時) ?? 技術棧: PyTorch + 數學推導 + 經典架構 + 實戰應用 ?? 核…

《QT 108好類》之16 QComboBox類

《QT 108好類》之16 QComboBox類QT 108好類之16 QComboBox類QComboBox類特性和應用場景QComboBox類繼承關系QComboBox類使用1 簡單使用2 表單輸入3 使用自定義模型和視圖4 完全自定義彈出窗口QComboBox類類使用效果QT 108好類之16 QComboBox類 QComboBox是 常用的下拉框&#…

項目模塊劃分

項目模塊劃分 服務端模塊&#xff1a; 持久化數據管理中心模塊 在數據管理模塊中管理交換機&#xff0c;隊列&#xff0c;隊列綁定&#xff0c;消息等部分數據數據。 \1. 交換機管理&#xff1a; a. 管理信息&#xff1a;名稱&#xff0c;類型&#xff0c;是否持久化標志&#…

小白也能看懂!OpenCV 從零開始安裝配置全教程(包含Windows / Ubuntu / 樹莓派)系統詳細操作配置教程

小白也能看懂&#xff01;OpenCV 從零開始安裝配置全教程&#xff08;包含Windows / Ubuntu / 樹莓派&#xff09;系統詳細操作配置教程 摘要 本教程是面向“小白也能懂”的OpenCV安裝與配置全攻略&#xff0c;涵蓋Windows、Ubuntu和樹莓派三大平臺&#xff0c;真正實現“從零…

【華為云】容器鏡像服務 SWR 詳解:從上傳下載到 ModelArts 應用

前言 華為云容器鏡像服務&#xff08;Software Repository for Container&#xff0c;簡稱 SWR&#xff09;是華為云提供的企業級容器鏡像倉庫服務。它支持 Docker 鏡像的存儲、管理和分發&#xff0c;為容器化應用提供安全可靠的鏡像托管服務。本文將詳細介紹 SWR 的核心功能…

計算機網絡知識點梳理(一)概述:組成、發展、性能、體系結構等

目錄 一、互聯網 &#xff08;1&#xff09;特點 &#xff08;2&#xff09;網絡的組成 &#xff08;3&#xff09;網絡、互連網、因特網 &#xff08;4&#xff09;互聯網發展的三個階段 &#xff08;5&#xff09;標準化 &#xff08;6&#xff09;組成 二、計算機網…

不同行業視角下的數據分析

聲明&#xff1a;以下部分內容含AI生成 基于行業維度來劃分數據分析崗位&#xff0c;可以幫助我們更好地理解不同行業對數據分析技能、業務知識和職業發展的獨特要求。 目錄 一、總體框架&#xff1a;為什么行業維度如此重要&#xff1f; 二、主要行業劃分及詳細講解 1. 互聯…

「CTF」青少年CTF·雛形系統

題目&#xff1a; 解題過程 嘗試隨便輸入點什么&#xff0c;沒有結果 使用dirsearch掃描網址目錄 可以看到有掃描到一個www.zip&#xff0c;zip文件大概率有需要的東西 網址后加上www.zip就能對該文件進行下載 文件解壓縮后如下 打開qsnctf.php&#xff0c;代碼內容如下 <…

Java實戰項目演示代碼及流的使用

project 準備牌->洗牌->發牌 import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.TreeSet;public class PokerGameplus {static HashMap<Integer,String> hs new HashMap<>();static ArrayList<Int…

使用 OpenLayers + 高德瓦片源實現旅游足跡地圖

作為一個熱愛旅行的開發者&#xff0c;我一直想要一個能夠記錄和展示自己旅游足跡的功能。市面上雖然有很多地圖應用&#xff0c;但大多功能復雜&#xff0c;而我只需要一個簡單直觀的方式來標記去過的地方和想去的地方。 于是我決定在自己的個人網站上實現一個旅游足跡地圖功…

Redis基礎(含常用命令等以快速入門)

一、初步認識 1、NoSQL SQL 關系型數據庫&#xff08;表結構&#xff0c;強一致&#xff09;NoSQL 非關系型數據庫&#xff08;靈活結構&#xff0c;最終一致&#xff0c;水平擴展爽&#xff09; 維度SQL&#xff08;關系型&#xff09;NoSQL&#xff08;非關系型&#xf…

OSPF特殊區域、路由匯總及其他特性

OSPF路由器需要同時維護域內路由、域間路由、外部路由信息數據庫。當網絡規模不斷擴大時&#xff0c;LSDB規模也不斷增長。如果某區域不需要為其他區域提供流量中轉服務&#xff0c;那么該區域內的路由器就沒有必要維護本區域外的鏈路狀態數據庫。OSPF通過劃分區域可以減少網絡…

在緩存Cacheable注解中Key值如何使用常量

1.在常量類中定義商品緩存空間和商品緩存KEY public interface CacheConstants {/*** Goods Cache Name*/String QNA_GOODS_CACHE "qna-goods";/*** Goods Cache key*/String QNA_GOODS_CACHE_KEY "qna_goods:";/*** Order Cache Name*/String QNA_ORDER…

sklearn聚類

在此將sklearn官網的一張關于聚類算法比較的圖片放過來。 下面的表格是根據sklearn官網翻譯而來。 方法名稱 參數 可擴展性 應用場景 幾何度量(距離) MiniBatchKMeans 簇的數量 非常適合處理大量樣本和中等數量的簇(使用MiniBatch時) 通用型,適用于簇大小均勻、幾何形狀平…

Recharts:React圖表庫,組件化設計助力高效數據可視化開發

你寫前端項目時有沒有卡過數據可視化的坑&#xff1f;比如要做個用戶增長折線圖&#xff0c;查了半天原生 JS 教程&#xff0c;寫了幾十行代碼&#xff0c;結果要么坐標軸對不上&#xff0c;要么數據渲染不出來&#xff1b;或者用了某個圖表庫&#xff0c;文檔全是英文&#xf…

Java 中String類的常用方法

Java 中的 String 類提供了豐富的方法用于字符串操作&#xff0c;以下是最常用的一些方法分類總結&#xff1a; 一、獲取字符串信息length()&#xff1a;返回字符串長度&#xff08;字符個數&#xff09; String s "hello"; int len s.length(); // len 5charAt(i…

【記錄】Docker|Docker內部訪問LInux主機上的Ollama服務

部分內容參考自&#xff1a;使得 docker 容器內部可以訪問宿主機的 ollama 服務_docker 訪問 ollama-CSDN 博客&#xff0c;補充添加了更多的細節&#xff0c;也補充了一個更加簡單的方案。 我測試的系統版本&#xff1a;Ubuntu 24.04.2 LTS noble&#xff0c;查看方式是指令 l…