基于SVM模型的网络入侵检测模型训练与评估(NSL-KDD数据集)

news2024/9/22 15:28:34

简介

针对网络安全领域的NSL-KDD数据集进行分类任务的预处理和模型训练、以及超参数调优。

数据预处理

  • 读取并解析数据集;
  • 检查并删除指定列(outcome)的缺失值;
  • 对类别型特征(protocol_type, service, flag)进行LabelEncoder编码转换;
  • 将攻击类型标签字段"attack"二值化,'normal’映射为0,其他攻击类型映射为1;
  • 划分训练集和测试集,并对两者执行标准化预处理。

模型训练与验证:

  • 使用线性SVM(LinearSVC)、RBF核SVM和多项式核SVM建立三个不同的分类模型;
  • 分别在训练集上训练这三种模型,并在测试集上进行预测;
  • 计算并打印每种模型在训练集和测试集上的准确率以评估模型性能。

此外,还使用GridSearchCV进行了超参数调优,针对RBF核SVM模型搜索最优的C和gamma参数,并用找到的最佳参数重新训练模型,最后计算优化后模型在测试集上的准确率。

代码步骤

主要实现了以下功能:

  1. 导入必要的库和模块,如numpy、pandas、matplotlib等,并从sklearn中导入支持向量机(SVM)及其相关工具,用于数据预处理、模型训练和性能评估。
  2. 读取KDDTrain+.txt数据集并重命名列名,检查并删除缺失值(这里没有发现缺失值),同时对其中的类别型特征进行编码转换,以适应机器学习模型的要求。将攻击类型标签字段"attack"中的’normal’标记为0,其余标记为1。
  3. 使用LabelEncoder对三个类别型特征(protocol_type, service, flag)进行编码,将其转化为数值形式。
  4. 将数据集划分为特征矩阵x和目标变量y,通过train_test_split函数分割为训练集和测试集,并对两者都应用StandardScaler进行标准化处理。
  5. 使用线性SVM模型以及RBF核函数和多项式核函数的SVM模型分别在训练集上进行训练,并在测试集上进行预测。计算并打印每种模型在训练集和测试集上的准确率。
  6. 对于RBF核函数的SVM模型,利用GridSearchCV进行参数调优,寻找最优超参数组合,然后使用最佳参数重新训练模型并在测试集上进行预测及准确率计算。

实现代码

导入必要的库和模块

import numpy as np # 提供高效的数值计算及数组操作
import pandas as pd # 提供数据处理和数据分析的功能
from pandas import Timestamp # 用于处理时间戳
import matplotlib.pyplot as plt # 提供数据可视化功能
from sklearn import svm # 支持向量机算法
from sklearn.svm import SVC # SVC为支持向量分类器
from sklearn.preprocessing import MinMaxScaler # 数据标准化处理
from sklearn.metrics import classification_report, confusion_matrix ,accuracy_score ,plot_roc_curve,roc_auc_score,roc_curve # 评估模型性能的指标
from sklearn.model_selection import train_test_split # 数据集划分
import seaborn as sns # 提供更美观的可视化效果
from sklearn.preprocessing import LabelEncoder # 对类别型数据进行编码
from sklearn.model_selection import GridSearchCV # 参数网格搜索
import matplotlib.gridspec as gridspec # 多图布局管理器

读取数据

data_Train =pd.read_csv('../input/nslkdd/KDDTrain+.txt')

数据格式如下:

0tcpftp_dataSF4910.10.20.30.40.5...0.17.10.030.17.20.00.60.00.70.00.80.050.00.9normal20
00udpotherSF14600000...0.000.600.880.000.000.000.000.00normal15
10tcpprivateS0000000...0.100.050.000.001.001.000.000.00neptune19
20tcphttpSF23281530000...1.000.000.030.040.030.010.000.01normal21
30tcphttpSF1994200000...1.000.000.000.000.000.000.000.00normal21
40tcpprivateREJ000000...0.070.070.000.000.000.001.001.00neptune21
..................................................................
1259670tcpprivateS0000000...0.100.060.000.001.001.000.000.00neptune20
1259688udpprivateSF1051450000...0.960.010.010.000.000.000.000.00normal21
1259690tcpsmtpSF22313840000...0.120.060.000.000.720.000.010.00normal18
1259700tcpkloginS0000000...0.030.050.000.001.001.000.000.00neptune20
1259710tcpftp_dataSF15100000...0.300.030.300.000.000.000.000.00normal21

125972 rows × 43 columns

data_Train.columns

Index([‘0’, ‘tcp’, ‘ftp_data’, ‘SF’, ‘491’, ‘0.1’, ‘0.2’, ‘0.3’, ‘0.4’, ‘0.5’,
‘0.6’, ‘0.7’, ‘0.8’, ‘0.9’, ‘0.10’, ‘0.11’, ‘0.12’, ‘0.13’, ‘0.14’,
‘0.15’, ‘0.16’, ‘0.17’, ‘2’, ‘2.1’, ‘0.00’, ‘0.00.1’, ‘0.00.2’,
‘0.00.3’, ‘1.00’, ‘0.00.4’, ‘0.00.5’, ‘150’, ‘25’, ‘0.17.1’, ‘0.03’,
‘0.17.2’, ‘0.00.6’, ‘0.00.7’, ‘0.00.8’, ‘0.05’, ‘0.00.9’, ‘normal’,
‘20’],
dtype=‘object’)

columns = (['duration','protocol_type','service','flag','src_bytes','dst_bytes','land','wrong_fragment','urgent'
            ,'hot','num_failed_logins','logged_in','num_compromised','root_shell','su_attempted','num_root'
            ,'num_file_creations','num_shells','num_access_files','num_outbound_cmds','is_host_login'
            ,'is_guest_login','count','srv_count','serror_rate','srv_serror_rate','rerror_rate','srv_rerror_rate'
            ,'same_srv_rate','diff_srv_rate','srv_diff_host_rate','dst_host_count','dst_host_srv_count'
            ,'dst_host_same_srv_rate','dst_host_diff_srv_rate','dst_host_same_src_port_rate'
            ,'dst_host_srv_diff_host_rate','dst_host_serror_rate','dst_host_srv_serror_rate','dst_host_rerror_rate'
            ,'dst_host_srv_rerror_rate','attack','outcome'])
data_Train.columns=columns

定义一个元组columns,包含了一系列的字段名称,这些字段主要用于描述网络活动的数据特征。
这些字段包括:
duration: 持续时间
protocol_type: 协议类型
service: 服务
flag: 标记
src_bytes: 来源字节
dst_bytes: 目标字节
land: 是否是本地连接
wrong_fragment: 错误的分片
urgent: 是否紧急
hot: 是否热门
num_failed_logins: 登录失败次数
logged_in: 是否已登录
num_compromised: 受损次数
root_shell: 是否获得根shell
su_attempted: 是否尝试过su
num_root: 根用户数量
num_file_creations: 文件创建数量
num_shells: shell数量
num_access_files: 访问文件数量
num_outbound_cmds: 出站命令数量
is_host_login: 是否为主机登录
is_guest_login: 是否为guest登录
count: 计数
srv_count: 服务计数
serror_rate: 客户端错误率
srv_serror_rate: 服务器错误率
rerror_rate: 客户端重传率
srv_rerror_rate: 服务器重传率
same_srv_rate: 同一服务率
diff_srv_rate: 不同服务率
srv_diff_host_rate: 服务不同主机率
dst_host_count: 目标主机计数
dst_host_srv_count: 目标主机服务计数
dst_host_same_srv_rate: 目标主机同一服务率
dst_host_diff_srv_rate: 目标主机不同服务率
dst_host_same_src_port_rate: 目标主机相同源端口率
dst_host_srv_diff_host_rate: 目标主机服务不同主机率
dst_host_serror_rate: 目标主机客户端错误率
dst_host_srv_serror_rate: 目标主机服务器错误率
dst_host_rerror_rate: 目标主机客户端重传率
dst_host_srv_rerror_rate: 目标主机服务器重传率
attack: 攻击类型
outcome: 结果

数据清洗

data_Train.isnull().sum()
# 从data_Train数据集中删除'outcome'列
data_Train.drop(columns='outcome',axis=1, inplace=True )

duration 0
protocol_type 0
service 0
flag 0
src_bytes 0
dst_bytes 0
land 0
wrong_fragment 0
urgent 0
hot 0
num_failed_logins 0
logged_in 0
num_compromised 0
root_shell 0
su_attempted 0
num_root 0
num_file_creations 0
num_shells 0
num_access_files 0
num_outbound_cmds 0
is_host_login 0
is_guest_login 0
count 0
srv_count 0
serror_rate 0
srv_serror_rate 0
rerror_rate 0
srv_rerror_rate 0
same_srv_rate 0
diff_srv_rate 0
srv_diff_host_rate 0
dst_host_count 0
dst_host_srv_count 0
dst_host_same_srv_rate 0
dst_host_diff_srv_rate 0
dst_host_same_src_port_rate 0
dst_host_srv_diff_host_rate 0
dst_host_serror_rate 0
dst_host_srv_serror_rate 0
dst_host_rerror_rate 0
dst_host_srv_rerror_rate 0
attack 0
outcome 0
dtype: int64

EDA

将数据集中的攻击类型标准化

attack_n = []
for i in data_Train.attack :
  # 将攻击类型转换为标准化的字符串
  if i == 'normal':
    attack_n.append("normal")
  else:
    attack_n.append("attack")
# 将转换后的攻击类型列表赋值回原数据集的对应列
data_Train['attack'] = attack_n 

计算并返回训练数据集中‘attack’列中各标签的出现次数

data_Train['attack'].value_counts()

normal 67342
attack 58630
Name: attack, dtype: int64

数据集可视化展示

根据数据集中的攻击类型绘制计数直方图。
sns.countplot: Seaborn库中的函数,用于绘制计数直方图。
data_Train.attack: 使用的数据集中的攻击类型列。
palette = ‘CMRmap’: 设置颜色映射为’CMRmap’。

sns.countplot(data_Train.attack , palette = 'CMRmap')

在这里插入图片描述

根据数据集中的’protocol_type’列绘制计数直方图。
sns.countplot函数用于绘制类别数据的计数图,可以直观地看出不同协议类型的数量分布。
参数:

  • data_Train: 训练数据集,需要是一个包含’protocol_type’列的数据框(如pandas的DataFrame类型)。
sns.countplot(data_Train[ 'protocol_type'], palette ='CMRmap')

在这里插入图片描述

生成一个基于数据集data_Train的计数柱状图,展示不同协议类型在正常与攻击情况下的分布
参数说明:
x=‘protocol_type’: 指定x轴的分类变量为’protocol_type’,即协议类型
hue=‘attack’: 指定通过颜色来区分的分类变量为’attack’,即攻击类型
data=data_Train: 使用的数据集为data_Train
palette=‘CMRmap’: 指定使用的颜色映射为’CMRmap’

sns.countplot(x='protocol_type', hue='attack', data=data_Train, palette='CMRmap')

在这里插入图片描述
生成服务类型计数的柱状图。
参数:

  • figsize: 指定图表的大小,格式为(width, height)。
  • palette: 指定图表中颜色方案。
  • y: 指定数据集中要绘制在y轴上的列。
  • data: 数据集,需要是一个DataFrame。
  • order: 指定y轴上服务类型的顺序,按照数据集中服务类型出现的频率排序。
# 创建一个新的图形窗口,并设置其大小
plt.figure(figsize=(10,40))
# 使用seaborn库绘制计数柱状图,按照服务类型的频率绘制
sns.countplot(palette='mako', y='service' , data=data_Train, order = data_Train['service'].value_counts().index)

在这里插入图片描述

生成一个基于数据集data_Train的计数柱状图,展示’flag’不同取值下的攻击事件分布
参数说明:
x=‘flag’: 指定x轴的分类变量为’flag’
hue=‘attack’: 指定通过不同颜色区分的分类变量为’attack’
data=data_Train: 使用的数据集
palette=‘CMRmap’: 指定使用的颜色映射为’CMRmap’

sns.countplot(x='flag',hue='attack' , data = data_Train , palette ='CMRmap')

在这里插入图片描述

数据编码

# 选择数据集中所有类型为'object'的列,并返回它们的列名
data_obj = data_Train.select_dtypes(['object']).columns
# 计算并返回训练数据集中“attack”列中各标签的出现次数
data_Train["attack"].value_counts()

normal 67342
attack 58630
Name: attack, dtype: int64

从sklearn.preprocessing导入LabelEncoder

# LabelEncoder用于将类别型标签数据转换为数值型,便于机器学习模型处理
from sklearn.preprocessing import LabelEncoder

# 初始化用于处理protocol_type字段的LabelEncoder实例
protocol_type_le = LabelEncoder()
# 初始化用于处理service字段的LabelEncoder实例
service_le = LabelEncoder()
# 初始化用于处理flag字段的LabelEncoder实例
flag_le = LabelEncoder()

对训练数据集中的特征进行编码

# 1. 使用LabelEncoder对'protocol_type'特征进行编码
data_Train['protocol_type'] = protocol_type_le.fit_transform(data_Train['protocol_type'])
# 2. 使用LabelEncoder对'service'特征进行编码
data_Train['service'] = service_le.fit_transform(data_Train['service'])
# 3. 使用LabelEncoder对'flag'特征进行编码
data_Train['flag'] = flag_le.fit_transform(data_Train['flag'])

将数据集中的攻击类型转化为二进制形式

attack_n = []
for i in data_Train.attack :
  # 遍历攻击类型,将'normal'标记为0,其他类型标记为1
  if i == 'normal':
    attack_n.append(0)
  else:
    attack_n.append(1)
# 将处理后的攻击类型数据添加到data_Train数据集中
data_Train['attack'] = attack_n 
data_Train['attack'].value_counts()

0 67342
1 58630
Name: attack, dtype: int64

生成并显示数据集的热力图

# 创建一个大小为30x30的画布
plt.figure(figsize=(30,30))
# 绘制热力图,显示数据集中的相关性
sns.heatmap(data_Train.corr(), annot= True,cmap='mako')

在这里插入图片描述

数据集划分

将数据集划分为训练集和测试集
y = data_Train['attack'].copy()  # 复制目标变量(攻击类型)到y
x = data_Train.drop(['attack'], axis=1)  # 从数据集中移除目标变量,得到特征矩阵x

# 使用train_test_split函数划分训练集和测试集
x_train, x_test, y_train, y_test = train_test_split(x,y , test_size=0.3, random_state=40)

数据标准化

# 导入StandardScaler类以实现数据的标准化处理
from sklearn.preprocessing import StandardScaler

# 初始化StandardScaler对象
scalar=StandardScaler()

# 对训练数据集x_train进行标准化处理
x_train=scalar.fit_transform(x_train)

# 对测试数据集x_test应用相同的标准化处理
x_test = scalar.fit_transform(x_test)

训练模型

使用线性支持向量机(LinearSVC)进行训练和预测
lin_svc = svm.LinearSVC().fit(x_train, y_train)  # 训练线性支持向量机模型
Y_pred = lin_svc.predict(x_test)  # 使用训练好的模型对测试集进行预测
print('The Training accuracy = ', lin_svc.score(x_train, y_train))  # 打印训练集的准确率
print('The Testing accuracy = ', lin_svc.score(x_test, y_test))  # 打印测试集的准确率
print("------------------------------------------------")
# 计算并打印线性SVC模型的预测准确率
print( "linearSVC accuracy : " + str(np.round(accuracy_score(y_test,Y_pred),3)))

The Training accuracy = 0.9551145384440917
The Testing accuracy = 0.9547787891617273
linearSVC accuracy : 0.955

print(classification_report(y_test,Y_pred))
在这里插入图片描述

使用RBF核函数训练SVC模型,进行训练和预测
# 使用rbf核函数训练SVC模型,并在训练集和测试集上测试模型的准确性
rbf_svc = svm.SVC(kernel='rbf').fit(x_train, y_train) # 训练SVM模型,使用径向基函数(RBF)作为核函数
Y_pred_rbf = rbf_svc.predict(x_test) # 使用训练好的模型预测测试集的标签

# 打印训练集和测试集的准确性
print('The Training accuracy = ', rbf_svc.score(x_train, y_train)) # 打印训练准确性
print('The Testing accuracy = ', rbf_svc.score(x_test, y_test)) # 打印测试准确性
print("------------------------------------------------")

# 使用accuracy_score函数计算并打印SVM模型(使用rbf核)在测试集上的准确率
print( "SVM (kernel: 'rbf') accuracy : " + str(np.round(accuracy_score(y_test, Y_pred_rbf), 3)))

The Training accuracy = 0.9920843728736675
The Testing accuracy = 0.9914796782387807
SVM (kernel: ‘rbf’) accuracy : 0.991
print(classification_report(y_test,Y_pred_rbf))
在这里插入图片描述

使用多项式核函数的SVM分类器训练和测试
# 使用多项式核函数的SVM分类器训练和测试
svclassifier_poly = SVC(kernel='poly')  # 定义SVM分类器,使用多项式核函数
poly = svclassifier_poly.fit(x_train,y_train)  # 使用训练数据拟合模型
Y_pred_poly = svclassifier_poly.predict(x_test)  # 使用测试数据进行预测

# 打印训练集和测试集的准确率
print('The Training accuracy = ',poly.score(x_train, y_train))
print('The Testing accuracy = ',poly.score(x_test, y_test))
print("------------------------------------------------")

# 打印整体的SVM(多项式核)分类器准确率和分类报告
print( "SVM (kernel: 'poly')  accuracy  : " + str(np.round(accuracy_score(y_test,Y_pred_poly),3)))
print(classification_report(y_test,Y_pred_poly))

The Training accuracy = 0.9911317759129055
The Testing accuracy = 0.989997883149873
SVM (kernel: ‘poly’) accuracy : 0.99
在这里插入图片描述

使用网格搜索进行参数调优
# 使用网格搜索进行参数调优
param_grid = {'C': [0.2,0.5,1], 'gamma': [0.5],'kernel': ['rbf']}  # 定义超参数搜索范围
grid = GridSearchCV(SVC(),param_grid ,verbose=2, cv= 3,refit=False)  # 实例化网格搜索对象
grid.fit(x_train,y_train)  # 对训练数据进行拟合,寻找最优参数组合

Fitting 3 folds for each of 3 candidates, totalling 9 fits
[CV] END …C=0.2, gamma=0.5, kernel=rbf; total time= 1.2min
[CV] END …C=0.2, gamma=0.5, kernel=rbf; total time= 1.2min
[CV] END …C=0.2, gamma=0.5, kernel=rbf; total time= 1.2min
[CV] END …C=0.5, gamma=0.5, kernel=rbf; total time= 1.4min
[CV] END …C=0.5, gamma=0.5, kernel=rbf; total time= 1.3min
[CV] END …C=0.5, gamma=0.5, kernel=rbf; total time= 1.7min
[CV] END …C=1, gamma=0.5, kernel=rbf; total time= 1.4min
[CV] END …C=1, gamma=0.5, kernel=rbf; total time= 1.4min
[CV] END …C=1, gamma=0.5, kernel=rbf; total time= 1.4min

GridSearchCV(cv=3, estimator=SVC(),
param_grid={‘C’: [0.2, 0.5, 1], ‘gamma’: [0.5], ‘kernel’: [‘rbf’]},
refit=False, verbose=2)

print(grid.best_params_)

{‘C’: 1, ‘gamma’: 0.5, ‘kernel’: ‘rbf’}

重新使用最优参数训练RBF核的SVC模型
# 使用网格搜索找到的最佳参数配置来初始化RBF核的SVC模型,并在训练数据上拟合
rbf_svc = svm.SVC(kernel=grid.best_params_['kernel'], gamma=grid.best_params_['gamma'], C=grid.best_params_['C']).fit(x_train, y_train)

# 使用拟合好的模型对测试集进行预测
Y_pred_rbf =rbf_svc.predict(x_test)

# 打印在训练集和测试集上的得分
print(rbf_svc.score(x_train, y_train))
print(rbf_svc.score(x_test, y_test))
print("------------------------------------------------")

# 打印经过四舍五入到小数点后3位的SVM(核函数为'rbf')的准确率
print( "SVM (kernel: 'rbf')  accuracy  : " + str(np.round(accuracy_score(y_test,Y_pred_rbf),3)))

0.9976525289181221
0.9947343353090601
SVM (kernel: ‘rbf’) accuracy : 0.995

print(classification_report(y_test,Y_pred_rbf))

在这里插入图片描述

绘制混淆矩阵图
def plot_cm(y_true, y_pred, title):
    # 设置图像大小
    figsize=(10,10)
    # 计算混淆矩阵
    cm = confusion_matrix(y_true, y_pred, labels=np.unique(y_true))
    # 计算每个类的总预测数,并转换为百分比
    cm_sum = np.sum(cm, axis=1, keepdims=True)
    cm_perc = cm / cm_sum.astype(float) * 100
    # 准备在矩阵上标注百分比和总数
    annot = np.empty_like(cm).astype(str)
    nrows, ncols = cm.shape
    for i in range(nrows):
        for j in range(ncols):
            c = cm[i, j]
            p = cm_perc[i, j]
            if i == j:
                s = cm_sum[i]
                annot[i, j] = '%.1f%%\n%d/%d' % (p, c, s)
            elif c == 0:
                annot[i, j] = ''
            else:
                annot[i, j] = '%.1f%%\n%d' % (p, c)
    # 将混淆矩阵数据转换为DataFrame,便于绘制
    cm = pd.DataFrame(cm, index=np.unique(y_true), columns=np.unique(y_true))
    cm.index.name = 'Actual'
    cm.columns.name = 'Predicted'
    # 创建图像和子图
    fig, ax = plt.subplots(figsize=figsize)
    plt.title(title)
    # 绘制混淆矩阵热力图
    sns.heatmap(cm, cmap= "mako", annot=annot, fmt='', ax=ax)
plot_cm(y_test,Y_pred_rbf, 'Confusion matrix for predictions on the testing using SVC(kernel : \'rbf\')')

在这里插入图片描述

优化建议

1. 数据预处理:

  • 在对类别型特征进行编码之前,可以考虑先查看各个类别数量的分布,对于不平衡类别数据,可能需要采取如过采样、欠采样或SMOTE等方法进行均衡处理。
  • 对于连续数值型特征,可以进一步探索其分布特性,例如是否存在异常值,是否需要进行归一化而非标准化。

2. 特征选择与降维:

  • 在训练模型前,可以尝试使用相关性分析(如皮尔逊相关系数)、卡方检验或基于模型的特征重要性评估(如随机森林)来筛选出对目标变量影响较大的特征,减少噪声和冗余信息。

3. 模型调优:

  • 在GridSearchCV中,可以扩大超参数搜索范围,或者针对SVM模型尝试更多类型的核函数,并寻找各自的最优参数组合。
    可以考虑集成学习策略,比如Bagging、Boosting或Stacking,结合多种基础模型提高整体性能。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Stable Diffusion 模型下载:ZavyChromaXL(现实、魔幻)

本文收录于《AI绘画从入门到精通》专栏,专栏总目录:点这里。 文章目录 模型介绍生成案例案例一案例二案例三案例四案例五案例六案例七案例八 下载地址 模型介绍 作者述:该模型系列应该是用于 SDXL 的 ZavyMix SD1.5 模型的延续。主要重点是获…

21-Java观察者模式 ( Observer Pattern )

Java备忘录模式 摘要实现范例 观察者模式 ( Observer Pattern ) 常用于对象间存在一对多关系时,比如,当一个对象被修改时,需要自动通知它的依赖对象 观察者模式属于行为型模式 摘要 1. 意图 定义对象间的一种一对多的依赖关系&#xff…

先进电机技术 —— 伺服驱动器与变频器

一、变频器与伺服驱动器发展趋势 在近年来的技术发展中,变频器和伺服驱动器均呈现出显著的先进性提升和技术融合趋势,以下是一些主要的发展方向: ### 变频器的发展趋势: 1. **智能化与网络化**: - 高级变频器集成…

律师事务所案件管理新宠:Java+SpringBoot+Vue+MySQL实战

✍✍计算机编程指导师 ⭐⭐个人介绍:自己非常喜欢研究技术问题!专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目:有源码或者技术上的问题欢迎在评论区一起讨论交流! ⚡⚡ Java实战 |…

STL之map容器代码详解

基础概念 简介: map中所有元素都是pair。pair中第一个元素为key(键值),起到索引作用,第二个元素为value(实值)。所有元素都会根据元素的键值自动排序。 本质: map/multimap属于关…

js对象 静态方法和实例方法

求下面代码的输出结果: 首先先分析一下上面各函数: Person.say function(){console.log("a")} 第一个say()方法是定义在Person函数身上的,我们如果想使用这个方法,可以通过Person().say()来调用 this.say function()…

性能测试干2年,还不会这个技术点?

nmon是一种在AIX与各种Linux操作系统上广泛使用的监控与分析工具,记录的信息比较全面,结合nmon_analyzer工具产生数据文件与图形化结果。 nmon可监控的数据类型 内存使用情况、磁盘适配器、文件系统中的可用空间、CPU使用率等等数据信息 特点 ①占用…

“删边“的并查集------反向并查集

目录 1.题目2.思路3.代码 默认大家都会并查集了 1.题目 小美认为,在人际交往中,但是随着时间的流逝,朋友的关系也是会慢慢变淡的,最终朋友关系就淡忘了。 现在初始有一些朋友关系,存在一些事件会导致两个人淡忘了他们…

业务代码中如何使用装饰器模式?

装饰器模式(Decorator Pattern)介绍 装饰器模式(Decorator Pattern)是一种结构型设计模式,我们可以动态地给一个对象添加额外的职责。而不是通过继承增加子类的方式来扩展对象的功能,装饰器模式使用组合的…

Android14之编译输出system/product/vendor/odm分区(一百九十一)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏:多媒…

【数据结构】HashMap的实现与常见问题

目录 一、概念 哈希算法与哈希表 二、哈希碰撞与解决 解决哈希冲突的四种方法 HashMap解决哈希冲突 三、代码实现 四、HashMap面试题 两个对象的hashcode一样那么equals一定一样吗?&& 两个对象的equals一样那么hashcode一定一样吗? Hash…

灵敏度都那么低了,为什么CCA的阈值还是-82

实际这个值的确是可以变化的。只是一般都不怎么变。 主要决定于两个因素。一个因素是邻区的干扰。如果干扰弱,那么就可以调高一点。跟布网有关。那么其实在家庭环境,这个不好控制。所以CCA阈值不好调整。但是如果仔细测量邻区的干扰,依然是可…

宝塔linux部署react项目 图文并茂 傻瓜式教学

华为云服务器购买与宝塔linux系统安装 购买服务器过程省略,记得付款就好,或者新人可去白嫖一个月试用 linux服务器安装宝塔 宝塔官网 不同版本安装命令 系统安装脚本Centos安装脚本yum install -y wget && wget -O install.sh https://downlo…

Android Studio轮播图使用失败怎么办【已解决】

Android Studio轮播图使用失败怎么办 1.在gethub上面搜索轮播图 2.选择要使用的轮播图 3.查看该轮播图的配置方法 4.复制该依赖放入build.gradle中 5.重新构建 6.使用banner 发现没有报错了 7.参考网址 https://github.com/youth5201314/banner

ELK-介绍及Elasticsearch集群搭建

ELK是三个开源软件的缩写,分别为Elasticsearch、Logstash、kibana它们都是开源软件。后来新增了一个FileBeat,它是一个轻量及的日志收集处理工具,因为Logstash由java程序开发,比较消耗内存资源,后来将Logstash使用go语…

解决gpt无法发送对话的问题

问题描述 如图,今天登上去发现怎么无法发送消息 解决 可能是cookie问题,重新删除了就行了 cookie删除后,需要重新登录,主题色也重置为原来的白色了

Node.js与Webpack笔记(二)

上一篇:Node.js与Webpack笔记(一)-CSDN博客 Webpack模块打包工具 1.Webpack简介以及体验 webpack是一个静态模块打包工具,从入口构建依赖图,打包有关的模块,最后用于展示你的内容 静态模块:编写…

ky10 server 银河麒麟服务器主备搭建 (nginx+keepalived)

下载脚本代码 git clone https://gitcode.net/zengliguang/nginx_keepalived_ky10_x.git 进入脚本路径 更新脚本代码 更新完成 执行安装脚本 安装nginx离线编译安装依赖 解压nginx源码 检查环境 编译 nginx安装成功 安装keepalived keepalived安装成功

华为OD机试真题-测试用例执行计划

测试用例执行计划 题目描述: 某个产品当前迭代周期内有N个特性({F1,F2,...,FN})需要进行覆盖测试,每个特性都被评估了对应的优先级,特性使用其ID作为下标进行标识。 设计了M个测试用例({T1,T2,...,TM}),每个用例对应了一个覆盖特…

【Python刷题】环形链表

问题描述 给你一个链表的头节点 head ,判断链表中是否有环。 如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置&a…