機器學習算法 ——XGBoost 的介紹和使用

前言:

最近在工作中遇到一個結構化數據回歸預測的問題,用到了很多回歸算法(如多元線性回歸等)都沒有很好的效果,于是使用了XGBoost,自己也沖三個特征參數人為的增加來幾個,訓練出來的效果還是很不錯的,XGBoost還是比較擅長對結構化數據的預測分析。希望對你有幫助

一、XGBoost 的基本介紹

XGBoost(eXtreme Gradient Boosting)是一種基于梯度提升樹(GBDT)的高效機器學習算法,由陳天奇等人提出。它在 GBDT 的基礎上進行了諸多優化,具有速度快、性能好、泛化能力強等特點,在各類機器學習競賽和實際工業應用中都有著廣泛的應用。

二、XGBoost 的核心原理

(一)梯度提升框架

XGBoost 遵循梯度提升的思想,通過迭代地構建一系列決策樹來進行預測。每一棵新的樹都是為了糾正前面所有樹的預測誤差而生成的。具體來說,假設已經有了 t-1 棵樹,對于每一個樣本,這些樹的預測結果之和為(\hat{y}^{(t-1)}_i),那么第 t 棵樹的目標就是使得預測誤差盡可能減小。

(二)正則化

XGBoost 引入了正則化項來防止過擬合。正則化項包括樹的葉子節點數量和葉子節點權重的 L2 范數。其目標函數可以表示為:

(Obj(\theta) = \sum{i=1}^n l(y_i, \hat{y}i) + \sum_{k=1}^K \Omega(f_k))

其中,(l(y_i, \hat{y}i))是損失函數,用于衡量預測值(\hat{y}i)與真實值(y_i)之間的差異;(\Omega(f_k))是正則化項,(f_k)表示第 k 棵樹,(K)是樹的數量。

(三)樹的構建

XGBoost 在構建樹的過程中,采用了貪心算法。對于每個特征,它會嘗試不同的分割點,計算分割后的增益,選擇增益最大的分割點進行分裂。為了提高計算效率,XGBoost 還采用了直方圖優化等技術,將連續特征的取值離散化為若干個直方圖 bins,從而減少分割點的搜索時間。

三、XGBoost 的核心特性

(一)高效性

  1. 支持并行計算:在樹的構建過程中,特征的分裂可以并行處理,大大提高了算法的運行速度。

  2. 直方圖優化:如前面所述,通過將連續特征離散化,減少了分割點的搜索時間,提高了計算效率。

(二)靈活性

  1. 支持多種損失函數:可以根據不同的任務(如分類、回歸)選擇合適的損失函數,如平方損失、邏輯損失等。

  2. 可以處理多種類型的數據:包括數值型數據和類別型數據,對于類別型數據,需要進行適當的編碼處理。

(三)魯棒性

  1. 對缺失值不敏感:XGBoost 可以自動處理缺失值,在訓練過程中會學習缺失值的處理方式。

  2. 內置正則化:通過正則化項可以有效防止過擬合,提高模型的泛化能力。

四、XGBoost 的使用步驟

(一)數據準備

  1. 數據收集:獲取用于訓練和測試的數據集。

  2. 數據清洗:處理數據中的缺失值、異常值等。對于缺失值,可以采用均值填充、中位數填充、眾數填充等方法;對于異常值,可以根據實際情況進行刪除或修正。

  3. 特征工程:對數據進行特征選擇、特征轉換等操作,以提高模型的性能。例如,可以進行標準化、歸一化處理,或者構建新的特征。

(二)模型訓練

  1. 導入 XGBoost 庫:在 Python 中,可以使用import xgboost as xgb來導入 XGBoost 庫。

  2. 劃分訓練集和測試集:可以使用train_test_split函數將數據集劃分為訓練集和測試集,一般按照 7:3 或 8:2 的比例進行劃分。

  3. 定義參數:設置 XGBoost 的相關參數,如學習率(learning_rate)、樹的數量(n_estimators)、最大深度(max_depth)等。

  4. 訓練模型:使用XGBClassifier(分類任務)或XGBRegressor(回歸任務)構建模型,并使用fit方法進行訓練。

(三)模型評估

  1. 預測:使用訓練好的模型對測試集進行預測,得到預測結果。

  2. 評估指標:根據不同的任務選擇合適的評估指標。對于分類任務,可以使用準確率、精確率、召回率、F1 值、ROC 曲線等;對于回歸任務,可以使用均方誤差(MSE)、均方根誤差(RMSE)、平均絕對誤差(MAE)等。

(四)模型調優

  1. 網格搜索:通過設置不同的參數組合,使用網格搜索來尋找最優的參數。

  2. 隨機搜索:與網格搜索類似,但隨機選擇參數組合進行搜索,在一定程度上可以提高搜索效率。

五、詳細示例

(一)分類任務示例(基于鳶尾花數據集)

  1. 數據準備

from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from xgboost import XGBClassifier
from sklearn.metrics import accuracy_score, classification_report
?
# 加載數據集
iris = load_iris()
X = iris.data
y = iris.target
?
# 劃分訓練集和測試集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
  1. 模型訓練

# 定義模型
model = XGBClassifier(learning_rate=0.1,n_estimators=100,max_depth=3,objective='multi:softmax',  # 多分類任務num_class=3,  # 類別數量random_state=42
)
?
# 訓練模型
model.fit(X_train, y_train)
  1. 模型評估

# 預測
y_pred = model.predict(X_test)
?
# 計算準確率
accuracy = accuracy_score(y_test, y_pred)
print(f"準確率:{accuracy:.2f}")
?
# 詳細評估報告
print(classification_report(y_test, y_pred))

運行結果:

準確率:1.00precision ?  recall  f1-score ? support
?0 ? ? ? 1.00 ? ?  1.00 ? ?  1.00 ? ? ?  141 ? ? ? 1.00 ? ?  1.00 ? ?  1.00 ? ? ?  152 ? ? ? 1.00 ? ?  1.00 ? ?  1.00 ? ? ?  11
?accuracy ? ? ? ? ? ? ? ? ? ? ? ? ? 1.00 ? ? ?  40macro avg ? ? ? 1.00 ? ?  1.00 ? ?  1.00 ? ? ?  40
weighted avg ? ? ? 1.00 ? ?  1.00 ? ?  1.00 ? ? ?  40

從結果可以看出,使用 XGBoost 模型在鳶尾花數據集上的分類準確率達到了 100%,效果非常好。

(二)回歸任務示例(基于波士頓房價數據集)

  1. 數據準備

from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
from xgboost import XGBRegressor
from sklearn.metrics import mean_squared_error, mean_absolute_error
?
# 注意:sklearn 1.2.0版本后移除了boston數據集,這里使用其他方式獲取(如從mlxtend庫)
# 假設已獲取數據
X, y = load_boston(return_X_y=True)
?
# 劃分訓練集和測試集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
  1. 模型訓練

# 定義模型
model = XGBRegressor(learning_rate=0.1,n_estimators=100,max_depth=3,objective='reg:squarederror',  # 回歸任務,平方誤差損失random_state=42
)
?
# 訓練模型
model.fit(X_train, y_train)
  1. 模型評估

# 預測
y_pred = model.predict(X_test)
?
# 計算評估指標
mse = mean_squared_error(y_test, y_pred)
rmse = mse **0.5
mae = mean_absolute_error(y_test, y_pred)
?
print(f"均方誤差(MSE):{mse:.2f}")
print(f"均方根誤差(RMSE):{rmse:.2f}")
print(f"平均絕對誤差(MAE):{mae:.2f}")

運行結果(示例):

均方誤差(MSE):10.23
均方根誤差(RMSE):3.20
平均絕對誤差(MAE):2.35

從結果可以看出,模型的預測效果較好,各項誤差指標都處于較低水平。

六、XGBoost 與其他算法的對比

(一)與 GBDT 的對比

  1. 相同點:兩者都屬于梯度提升樹算法,都是通過迭代構建決策樹來進行預測。

  2. 不同點

  • 正則化:XGBoost 引入了更嚴格的正則化項,包括樹的葉子節點數量和葉子節點權重的 L2 范數,而 GBDT 沒有明確的正則化項,容易過擬合。

  • 計算效率:XGBoost 支持并行計算和直方圖優化,計算速度比 GBDT 快很多。

  • 對缺失值的處理:XGBoost 可以自動處理缺失值,而 GBDT 需要手動處理。

(二)與隨機森林的對比

  1. 相同點:兩者都由多棵決策樹組成,都可以用于分類和回歸任務。

  2. 不同點

  • 構建方式:隨機森林是通過 bootstrap 抽樣構建多棵決策樹,然后進行投票或平均得到結果,樹之間是獨立的;XGBoost 是迭代地構建樹,每一棵新的樹都依賴于前面的樹。

  • 偏差與方差:隨機森林通過集成多棵樹來降低方差,XGBoost 通過梯度提升來降低偏差。

  • 性能:在很多任務中,XGBoost 的性能優于隨機森林,但隨機森林的訓練速度可能更快一些。

(三)與支持向量機(SVM)的對比

  1. 相同點:都可以用于分類和回歸任務。

  2. 不同點

  • 處理數據規模:SVM 在處理大規模數據時效率較低,而 XGBoost 可以較好地處理大規模數據。

  • 核函數:SVM 需要選擇合適的核函數來處理非線性問題,而 XGBoost 通過決策樹的組合可以自然地處理非線性問題。

  • 解釋性:XGBoost 的模型解釋性相對較強,可以通過特征重要性等指標了解特征的影響;SVM 的解釋性相對較弱。

七、我的訓練腳本(僅供參考)

  • max_depth:樹的深度,影響模型復雜度和過擬合風險。

  • learning_rate(或 eta):學習率,控制每次迭代的步長。

  • n_estimators:提升樹的數量,即訓練的輪數。

代碼:

import json
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.model_selection import train_test_split, cross_val_score, KFold
from sklearn.preprocessing import OneHotEncoder, StandardScaler
from sklearn.linear_model import Ridge
from sklearn.ensemble import RandomForestRegressor
from sklearn.metrics import mean_squared_error, r2_score
import xgboost as xgb
from matplotlib.font_manager import FontProperties
import joblib
font_path = r"simhei.ttf"
font = FontProperties(fname=font_path)
with open(r'test.json', 'r', encoding='utf-8') as f:data = json.load(f)
?
#數據處理,將嵌套列表展開為適合建模的表格
rows = []
for item in data:gcbh = item['gcbh']jxtbhj = item['jxtbhj']for debh, sl, dj,dwsl in zip(item['debh'], item['sl'], item['dj'],item['dwsl']):rows.append([gcbh, debh, sl, dj,dwsl, jxtbhj])
df = pd.DataFrame(rows, columns=['gcbh', 'debh', 'sl', 'dj', "dwsl",'jxtbhj'])
?
# 新增特征
df['single_item_total'] = df['sl'] * df['dj'] * df['dwsl']
?
# 在DataFrame創建后,添加更多特征
# 1. 工程級別的統計特征
df['total_by_gcbh'] = df.groupby('gcbh')['single_item_total'].transform('sum') ?
df['items_count'] = df.groupby('gcbh')['debh'].transform('count') ? 
df['avg_price'] = df.groupby('gcbh')['dj'].transform('mean') ? ? ? ?
df['price_std'] = df.groupby('gcbh')['dj'].transform('std') ? ? ? 
df['total_quantity'] = df.groupby('gcbh')['sl'].transform('sum') ? 
?
# 2. 項目級別的統計特征
df['price_ratio'] = df['dj'] / df['avg_price'] ? ? ? ? ? ? ? ? ? ? ?
df['quantity_ratio'] = df['sl'] / df['total_quantity'] ? ? ? ? ? ? ?
df['value_ratio'] = df['single_item_total'] / df['total_by_gcbh'] ? ? ? ? ? ? ?
?
# 修改特征列表
cat_features = ['debh'] 
num_features = ['sl', 'dj', 'single_item_total', ? ? ? ? # 基礎特征'total_by_gcbh', 'items_count','avg_price','price_std','total_quantity', 'price_ratio','quantity_ratio', 'value_ratio' ?
]
?
# 3. 處理缺失值
print("處理缺失值前的數據形狀:", df.shape)
print("缺失值統計:")
print(df[num_features].isnull().sum())
?
# 處理缺失值 - 使用中位數填充數值特征
for col in num_features:if df[col].isnull().sum() > 0:median_val = df[col].median()df[col].fillna(median_val, inplace=True)print(f"列 {col} 使用中位數 {median_val:.2f} 填充了 {df[col].isnull().sum()} 個缺失值")
?
# 處理分類特征的缺失值
for col in cat_features:if df[col].isnull().sum() > 0:mode_val = df[col].mode()[0]df[col].fillna(mode_val, inplace=True)print(f"列 {col} 使用眾數 {mode_val} 填充了 {df[col].isnull().sum()} 個缺失值")
?
print("處理缺失值后的數據形狀:", df.shape)
print("缺失值統計:")
print(df[num_features + cat_features].isnull().sum())
?
# 4. 處理異常值
def handle_outliers(df, columns, n_sigmas=3):for col in columns:mean = df[col].mean()std = df[col].std()df[col] = df[col].clip(mean - n_sigmas * std, mean + n_sigmas * std)return df
?
# 處理數值特征的異常值
df = handle_outliers(df, num_features)
?
# 目標值不做對數變換,因為看起來對數變換效果不好
y = df['jxtbhj'].values
?
# 檢查目標值是否有缺失值
if np.isnan(y).any():print("警告:目標值包含缺失值,將刪除這些行")mask = ~np.isnan(y)df = df[mask]y = y[mask]print(f"刪除缺失值后的數據形狀: {df.shape}")
?
# 工程編號獨熱編碼
encoder = OneHotEncoder(sparse_output=False, handle_unknown='ignore')
X_cat = encoder.fit_transform(df[cat_features])
X_num = df[num_features].values
?
# 最終檢查確保沒有NaN值
print("最終數據檢查:")
print(f"X_cat 包含 NaN: {np.isnan(X_cat).any()}")
print(f"X_num 包含 NaN: {np.isnan(X_num).any()}")
print(f"y 包含 NaN: {np.isnan(y).any()}")
?
X = np.hstack([X_cat, X_num])
?
# 特征縮放
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
?
# 4. 劃分訓練集和測試集
X_train, X_test, y_train, y_test = train_test_split(X_scaled, y, test_size=0.2, random_state=42)
?
# 在數據處理后,模型訓練前添加這段代碼
plt.figure(figsize=(12, 4))
?
# 原始值分布
plt.subplot(121)
plt.hist(df['jxtbhj'], bins=50)
plt.title('原始 jxtbhj 分布', fontproperties=font)
?
# 對數變換后的分布
plt.subplot(122)
plt.hist(np.log1p(df['jxtbhj']), bins=50)
plt.title('log(jxtbhj) 分布', fontproperties=font)
?
plt.tight_layout()
plt.show()
?
# 打印一些基本統計信息
print("原始 jxtbhj 統計信息:")
print(df['jxtbhj'].describe())
?
# 5. 建立多種模型
models = {# '嶺回歸': Ridge(# ? ? alpha=0.5,  # 適中的正則化# ? ? fit_intercept=True# ),# '隨機森林': RandomForestRegressor(# ? ? n_estimators=300,  # 增加樹的數量# ? ? max_depth=8, ? ? ? # 控制過擬合# ? ? min_samples_leaf=5,# ? ? max_features='sqrt',# ? ? random_state=42# ),'XGBoost': xgb.XGBRegressor(n_estimators=1500,#900max_depth=8,learning_rate=0.1, ?# 降低學習率0.09subsample=0.8, ? ? ? # 隨機采樣colsample_bytree=0.8,# 特征采樣reg_alpha=0.1, ? ? ? # L1正則化reg_lambda=1.0, ? ? ?# L2正則化random_state=42,verbosity=0)
}
results = {}
?
kf = KFold(n_splits=5, shuffle=True, random_state=42)
for name, model in models.items():cv_scores = cross_val_score(model, X_scaled, y, cv=kf, scoring='r2',error_score='raise')print(f"\n模型: {name}")print(f"交叉驗證 R2 分數: {cv_scores.mean():.4f} (+/- {cv_scores.std() * 2:.4f})")
?# 在全部數據上訓練和評估model.fit(X_train, y_train)y_pred = model.predict(X_test)mse = mean_squared_error(y_test, y_pred)r2 = r2_score(y_test, y_pred)results[name] = {'model': model, 'mse': mse, 'r2': r2, 'y_pred': y_pred}print(f"測試集 MSE: {mse:.2f}")print(f"測試集 R2: {r2:.4f}")
?# 在模型訓練后添加def analyze_predictions(y_true, y_pred, name):# 計算預測誤差百分比error_percent = np.abs((y_pred - y_true) / y_true) * 100
?print(f"\n{name} 預測分析:")print(f"平均百分比誤差: {error_percent.mean():.2f}%")print(f"中位數百分比誤差: {np.median(error_percent):.2f}%")print(f"90%預測的誤差在 {np.percentile(error_percent, 90):.2f}% 以內")
?# 計算不同誤差范圍的預測比例for threshold in [10, 20, 30, 50]:accuracy = (error_percent <= threshold).mean() * 100print(f"誤差在{threshold}%以內的預測比例: {accuracy:.2f}%")
?analyze_predictions(y_test, y_pred, name)
?
# 6. 選擇最佳模型用于解釋性分析
best_model_name = max(results, key=lambda k: results[k]['r2'])
best_model = results[best_model_name]['model']
y_pred = results[best_model_name]['y_pred']
print(f"最佳模型: {best_model_name}")
?
# 保存XGBoost模型
if best_model_name == 'XGBoost':best_model.save_model('xgb_model.json')print('XGBoost模型已保存到 xgb_model.json')# 保存encoder和scalerjoblib.dump(encoder, 'encoder.joblib')joblib.dump(scaler, 'scaler.joblib')print('encoder和scaler已保存')
?
# 7. 特征重要性分析
feature_names = list(encoder.get_feature_names_out(cat_features)) + num_features
if hasattr(best_model, 'coef_'):importances = best_model.coef_
elif hasattr(best_model, 'feature_importances_'):importances = best_model.feature_importances_
else:importances = np.zeros(len(feature_names))
?
plt.figure(figsize=(12, 6))
sns.barplot(x=feature_names, y=importances)
plt.title(f'{best_model_name} 特征重要性', fontproperties=font)
plt.xlabel('特征', fontproperties=font)
plt.ylabel('重要性', fontproperties=font)
plt.xticks(rotation=90)
plt.tight_layout()
plt.show()
?
# 8. 預測值與真實值對比圖
plt.figure(figsize=(8, 8))
plt.scatter(y_test, y_pred, alpha=0.6)
plt.plot([y_test.min(), y_test.max()], [y_test.min(), y_test.max()], 'r--', lw=2)
plt.title(f'{best_model_name} 真實值 vs 預測值', fontproperties=font)
plt.xlabel('真實值', fontproperties=font)
plt.ylabel('預測值', fontproperties=font)
plt.tight_layout()
plt.show()
?
# 9. 殘差分析
residuals = y_test - y_pred
plt.figure(figsize=(8, 5))
sns.histplot(residuals, bins=30, kde=True)
plt.title(f'{best_model_name} 殘差分布', fontproperties=font)
plt.xlabel('殘差', fontproperties=font)
plt.tight_layout()
plt.show()
?
plt.figure(figsize=(8, 5))
plt.scatter(y_pred, residuals, alpha=0.6)
plt.axhline(0, color='red', linestyle='--')
plt.title(f'{best_model_name} 預測值與殘差', fontproperties=font)
plt.xlabel('預測值', fontproperties=font)
plt.ylabel('殘差', fontproperties=font)
plt.tight_layout()
plt.show()

八、安裝與資源

  • 安裝pip install xgboostconda install -c conda-forge xgboost

  • 官方文檔:XGBoost Documentation

  • GitHub 倉庫:dmlc/xgboost

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

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

相關文章

Linux操作系統之信號:保存與處理信號

目錄 前言&#xff1a; 前文回顧與補充&#xff1a; 信號的保存 PCB里的信號保存 sigset_t 信號集操作函數 信號的處理 信號捕捉的流程&#xff1a;?編輯 操作系統的運行原理 硬件中斷 時鐘中斷 死循環 軟中斷 總結&#xff1a; 前言&#xff1a; 在上一篇文…

Spring Boot 設置滾動日志logback

Spring Boot 的 logback 框架 Spring Boot 默認內置了 Logback 作為日志實現框架&#xff0c;只需要在resources文件夾下添加一個logback-spring.xml&#xff0c;springboot會按照你的設置自動開啟logback日志功能。 配置 logback-spring.xml 實現每天產生一個日志文件&#xf…

如何定義一個只能在堆上或棧上生成對象的類

在C中&#xff0c;可以通過特定的技術手段來控制對象只能在堆(heap)或棧(stack)上創建。只能在堆上創建對象的類要實現這一點&#xff0c;我們需要阻止用戶直接實例化對象&#xff0c;而只能通過new操作符創建。class HeapOnly { public:static HeapOnly* create() {return new…

1.1 前端-vue3項目的創建

構建工具先搭好vue3框架 vue2的vue-cli腳手架基于webpack構建工具創建vue的框架. 而在vue3&#xff0c;可以通過vite構建工具創建vue3項目&#xff0c;性能更優。 兩者創建方式的區別&#xff1a;cmd命令基于的構建工具vue2/vue3vue create 項目名稱&#xff08;或 vue ui圖形化…

PHP password_get_info() 函數

password_get_info() 函數用于返回指定散列&#xff08;hash&#xff09;的相關信息。 PHP 版本要求: PHP 5 > 5.5.0, PHP 7 語法 array password_get_info ( string $hash ) 參數說明&#xff1a; $hash: 一個由 password_hash() 創建的散列值。 返回值 返回三個元素…

mac上的app如何自動分類

使用文件夾進行手動分類在Finder中創建文件夾&#xff0c;將同類應用拖入同一文件夾。右鍵點擊Dock上的應用圖標&#xff0c;選擇「選項」→「在Finder中顯示」&#xff0c;可快速定位應用安裝位置。利用Launchpad自動分組打開Launchpad&#xff08;觸控板四指捏合或按F4鍵&…

LLM面試題目 3

LLM面試題目 3 什么是自注意力機制(Self-Attention)?為什么它在LLM中很重要?如何評估LLM的性能?LLM面臨的挑戰有哪些?Transformer和RNN的區別是什么?LLM如何處理多輪對話? 題目講解 什么是自注意力機制(Self-Attention)?為什么它在LLM中很重要? 自注意力機制是一種…

linux上的軟掛載操作方法

針對linux上的軟掛載 可以查看linux已經掛載和存儲的磁盤分區 df -hfdisk 命令是檢索相同信息的另一種方法&#xff0c;可以看到所有的磁盤分區 sudo fdisk -l 要將磁盤分區 /dev/sda1 掛載到 /home/visionx/EXD1 目錄 步驟 1&#xff1a;準備工作 1.創建掛載目錄&#xff08;如…

SecretFlow 隱語 (2) --- 隱語架構概覽

在前邊兩篇文章中&#xff0c;介紹了數據要素和可信流通相關的內容&#xff0c;以及基于p2p模式的安裝方法 SecretFlow 隱語 (1) --- 快速入門 關于在Linux上部署 SecretFlow --- P2P部署模式 由于安裝過程中出現意外報錯&#xff0c;現已提交issue等待官方技術人員查閱&#x…

PHP語言基礎知識(超詳細)第二節

二十七. 數組的遍歷 1)通過函數進行遍歷:(例:demo07) (此方式不能完全遍歷數組,需要借助其他功能輔助)(不推薦,了解即可) key():返回數組中當前指針所在位置的鍵。 current():返回數組中當前指針所在位置的值。 例如:demo07: <?php/*key():返回數組中…

網絡--OSPF實驗

目錄 OSPF實驗報告 一、實驗拓撲 二、實驗要求 三、實驗思路 1.IP地址劃分 2. OSPF 部署 3. 其它配置 4. 驗證測試 四、實驗步驟 1.IP 地址配置 2.OSPF 部署 3.其它配置 4.驗證測試 OSPF實驗報告 一、實驗拓撲 二、實驗要求 1、R1-R3為區域0&#xff0c;R3-R4為…

Go語言第一個程序--hello world!

文章目錄一、Go 語言程序安裝二、運行程序三、go mod tidy 命令四、遇到的問題五、VS Code 調試 go 程序的相關配置說明一、Go 語言程序安裝 Go語言下載鏈接&#xff1a;https://studygolang.com/dl 雙擊打開下一步下一步即可。 驗證安裝&#xff1a;go version 二、運行程序 創…

【MCU控制 初級手札】1.1 電阻

作者&#xff1a;電控工程手札 本博文內容著作權歸作者所有&#xff0c;轉載請務必保留本文鏈接 目錄1. 定義2. 電導3. 電阻率4. 電導率5. 伏安特性6. 開路與短路7. 功率8. 應用元件特性&#xff08;端子特性&#xff09;&#xff1a;元件的兩個端子的電路物理量之間的代數函數…

JS中async/await功能介紹和使用演示

JS 中 async/await 功能介紹與使用演示 一、功能介紹基本概念 async&#xff1a;用于聲明異步函數&#xff0c;返回一個 Promise 對象。即使函數內沒有顯式返回 Promise&#xff0c;也會隱式將返回值封裝為 Promise.resolve()。await&#xff1a;僅能在 async 函數內部使用&…

系統調用入口機制:多架構對比理解(以 ARM64 為主)

&#x1f4d6; 推薦閱讀&#xff1a;《Yocto項目實戰教程:高效定制嵌入式Linux系統》 &#x1f3a5; 更多學習視頻請關注 B 站&#xff1a;嵌入式Jerry 系統調用入口機制&#xff1a;多架構對比理解&#xff08;以 ARM64 為主&#xff09; 本篇內容聚焦于系統調用的入口實現機…

java MultipartFile初始化

在Java中&#xff0c;MultipartFile 是Spring框架中用于處理文件上傳的接口。?開發者通常不會直接初始化MultipartFile對象&#xff0c;而是通過Spring MVC的控制器方法參數接收上傳的文件。如果需要在測試或模擬場景中創建其實例&#xff0c;可以使用Spring的MockMultipartFi…

Linux C IO多路復用

在上一節利用管道實現了一個簡單的聊天室&#xff0c;但這個聊天室有一個很明顯的問題就是&#xff0c;當A處于讀阻塞情況下是不能向B發送消息的&#xff0c;只有收到B的消息才能發送。如何實現同時既能接受B的消息&#xff0c;又能向其發送消息&#xff1f;很遺憾&#xff0c;…

day21——特殊文件:XML、Properties、以及日志框架

文章目錄一、特殊文件概述二、Properties屬性文件2.1 文件特點2.2 Properties類解析2.3 寫入屬性文件三、XML文件詳解3.1 XML核心特性3.2 XML解析&#xff08;Dom4J&#xff09;3.3 XML寫入3.4 XML約束&#xff08;了解&#xff09;四、日志技術&#xff08;Logback&#xff09…

經典VB與現代VB(VB.NET)

Visual Basic&#xff08;VB&#xff09;目前其發展狀態可以分為經典VB&#xff08;VB6及之前&#xff09;?和現代VB&#xff08;VB.NET&#xff09;?兩個階段。經典VB誕生于1991年&#xff0c;憑借?“快速開發&#xff08;Rapid Application Development, RAD&#xff09;”…

iOS UI視圖面試相關

iOS UI視圖面試相關 UITableVIew相關 重用機制 cell [tableView dequeueReusableCellWillIdentifier:identifer];其中A2、A3、A4、A5是完全顯示在屏幕&#xff0c;A2、A6顯示部分&#xff0c;A1和A7不在顯示范圍內&#xff0c;假如現在是從下滑時的結果&#xff0c;在A1消失時…