【高中生讲机器学习】28. 集成学习之 Bagging 随机森林!

news2024/12/12 21:55:20

创建时间:2024-12-09
首发时间:2024-12-09
最后编辑时间:2024-12-09
作者:Geeker_LStar

嘿嘿,你好呀!我又来啦~~

前面我们讲完了集成学习之 Boooooosting,这篇我们来看看集成学习的另一个分支——Bagging!

(嗯这篇的数学也简单,感觉集成学习这块的数学都相对简单嘿嘿~)

这是之前两篇关于 Boosting 的文章:

【高中生讲机器学习】26. 梯度提升树 GBDT 超详细讲解!
【高中生讲机器学习】25. AdaBoost 算法详解+推导来啦!

嗯,那我们开始这一篇吧~!(我觉得这会是整个专栏中第二简单的一篇哈哈哈哈哈((

Bagging 主要思想

嗯! 我们还是从 Bagging 的主要思想说起。

在第 24 篇(集成学习概述)中我说过,模型训练的过程主要会遇到两个困难——高方差和高偏差。前者主要代表过拟合,后者则主要代表欠拟合。而集成学习的两个分支——Bagging 和 Boosting,就是分别来解决这两个问题的。

和 Boosting 主要关注降低模型的偏差不同,Bagging 主要关注降低模型的方差,所以它使用的基学习器通常是深层决策树(容易过拟合,造成低偏差、高方差的情况)。

同样,和 Boosting 的串行生成,即每个基学习器都在前一个基学习器的基础上生成不同,Bagging 采用的并行生成策略,即所有的基学习器同时生成,不涉及到根据前一个基学习器动态调整权重或拟合负梯度这样的情况。

Bagging 的核心在于三个字——多样性。一个基学习器会过拟合,那我就训练出很多很多个,再综合考量它们的结果,这样不就能缓解过拟合了吗?

于是问题来了:现在的数据集只有这么多,怎么利用这个有限的数据集训练出很多不同的决策树?

显然,如果让所有的决策树都在这一整个数据集上训练,那最终训练出来的每棵树不会有任何区别,我们也就没必要把它们组合起来了。
所以,我们必须要让每棵树的训练数据有所区别

Bagging 很聪明,既然不能所有树都在相同的数据(数据集中所有的数据)上进行训练,那就让每棵树都在从原始数据集中随机抽取的样本上训练,这样每棵树训练出来就都是不同的了。

well 这就涉及到了一些更细节的问题/…
——数据抽取的过程具体是怎么样的?

啊这个问题看起来很蠢()但是还是需要 clarify 一下的(clarify 之后你就会发现这个问题一点也不蠢,相反,它还很重要!)

注意,在下面的讨论中,我们讨论的都是对于一棵树的情况。换言之,下面所说的数据抽取的流程,是给一棵树抽取训练集的流程。

有一点是需要提前明确的。在 Bagging 中,无论我们训练多少棵树,每棵树的训练样本集的大小和原始数据集的大小都是一样的。换言之,我可能训练了 100 棵树,这 100 棵树的训练集大小都是一样的,都等于原始数据集的大小。

诶这是怎么做到的? M M M 棵树对应的 M M M 个训练数据集大小都和原始数据数据集一样,但这 M M M 个训练数据集又彼此不相同…

好好好我们接着说 Bagging 的抽样方法,然后这个问题就很好解释啦~

Bagging 中的抽取是有放回的。即,第一次我抽取了一个样本 x 1 x_1 x1,在下一次抽取之前,我会把 x 1 x_1 x1 放回去。换言之,每次抽取都是在原始的完整数据集中抽取的。

这也很好理解,如果我不放回,那最终抽取得到的还是原始数据集,所以每次抽取完肯定都要放回。

举个例子,比如现在原始数据集中有五个数据 { x 1 , x 2 , x 3 , x 4 , x 5 } \{x_1, x_2, x_3, x_4, x_5\} {x1,x2,x3,x4,x5}.
第一次抽取的时候,抽出了 x 1 x_1 x1,然后把它放回去了。
第二次,抽出了 x 4 x_4 x4,又放回去了。
第三次,诶可能又抽取到了 x 1 x_1 x1
第四次, x 2 x_2 x2
第五次,可能还是 x 2 x_2 x2

这样,我们抽取出的数据其实只有 x 1 , x 2 , x 4 x_1, x_2, x_4 x1,x2,x4 x 3 , x 5 x_3, x_5 x3,x5 没有被抽到。

ok,那么,按照这样的思路,第一棵树的训练集就是 x 1 , x 4 , x 1 , x 2 , x 2 x_1, x_4, x_1, x_2, x_2 x1,x4,x1,x2,x2.
然后,我们按照有放回抽样的逻辑,继续给第二棵树抽取训练集,这次抽取到的可能是 x 3 , x 4 , x 5 , x 3 , x 1 x_3, x_4, x_5, x_3, x_1 x3,x4,x5,x3,x1

嘿嘿,发现了吗,使用有放回抽样,我们就可以让每个树的训练集都不同,但因为是从同一个原始训练集中抽取得到的,所以又会有所重合。

简言概括,Bagging 的数据抽取方式保证了,它训练出来的每棵树都有所重合,但又不完全相同。 这能够帮助它实现对方差的降低。

ooiiioo 注意(奇怪的拟声词越来越多了? ),虽然上面这个说法听起来好像是,抽取数据训练完第一棵树之后再抽取数据并训练第二棵树,但实际上不是这样的。
在 Bagging 中,所有数据抽取都是在开始训练前(并行)。也就是说,如果我计划训练 M M M 棵树,那我会在开始训练之前用有放回抽样抽出 M M M 组数据,然后开始并行地训练。

嗷对了,这种方法其实还有一个优势。
我们可以证明,虽然对于每棵树,我们都使用有放回抽样抽取了和原始数据集一样大小的数据集作为训练数据集,但是,原始数据集中依然有一部分数据没有被抽到(也就是不会被作为这棵树的训练集),并且,这部分数据的占比还不少!(证明我放在了下一部分,这一部分我们不提数学())

(就像刚才那个例子, x 3 , x 5 x_3, x_5 x3,x5 就没有被抽取到,也就是说,它们就不会成为第一棵的训练数据。

那这些数据怎么办??
其实,它们完全可以用于测试诶! 因为它们没有被这棵树学习过。

这里先剧透一下,对于每一棵树,最终会有大概 36.8 % 36.8\% 36.8% 的数据没有被它学习过,这些数据就是天然的测试数据,我们就不用再额外寻找测试数据了!!
这些没有被取到的数据被称为袋外数据(out of bag, OOB),我们可以直接在这些袋外数据上进行测试~!

(另外,你可以尝试“注意到”一下,0.368 这个数字很特殊哦…(((哈哈哈哈这里就不剧透过多了(

从上面说过的所有和数据抽取相关的内容出发举个例子,我现在一共有 100 个数据,训练第一棵树的时候,我使用有放回抽样,获得了大小为 100 的训练集;训练第二棵树的时候,又获得了大小为 100 的训练集(注意第二次抽取和第一次抽取是完全独立的);以此类推,并行训练完所有的树。

训练完以后,我发现,诶,(比如对于第一棵树),好像有 37 个数据没有被它抽取到(不在它的训练集里)诶。这些数据就可以用来当作测试数据,测试这棵树的性能。

okay,现在假设我们已经训练完所有的树了,接下来就是推理,或者说测试了。

Bagging 的推理很简单,给定一个样本,让所有训练出来的树分别预测(类别 or 值),再对所有树给出的结果多数表决(分类)或取平均值(回归),就得到了最终的结果。

比如说,我训练了四棵树,有 3 棵对于测试样本的类别预测为 A,剩下的 1 棵对于测试样本的类别预测为 B,那么最终这个样本就会被预测为 A(简单的多数表决~)。

enenen,以上就是 Bagging 算法的基本思路!! 是不是感觉比 Boosting 简单一些()

Bagging 的总体流程可以概括如下图:

Bagging 总体流程

我们来小小总结一下,Bagging 作为集成学习的另一分支,它的特点如下

  • 并行训练:Bagging 中每个基学习器都是并行训练的,基学习器之间彼此独立,不涉及到后一个基学习器在前一个基学习器的基础上进行调整的步骤。
  • 部分样本训练:Bagging 在训练每棵树的时候只会使用原始训练集中部分的数据进行训练,保证了训练出来的树的多样性
  • 有放回抽取:Bagging 每抽取完一个数据都会把它再放回去,下次抽取依然是从原始的数据集中抽取。这导致,对于每棵树,大概有 36.8 % 36.8\% 36.8% 的原始数据集中的数据不会被作为训练数据。
  • 袋外数据:对于每棵树,没有被抽取到训练集中的那 36.8 % 36.8\% 36.8% 的数据可以作为测试数据,评估这棵树在整体数据集上的表现。

其实,Bagging 的数学叙述也比 Boosting 简单,我们来看看…(这是什么生硬的转折啊不是)(()

数学叙述

这一部分我们给出 Bagging 算法的数学叙述,包括一些必要的证明。

首先我们规定一些 notation。
我们规定,原始数据集 D D D 的大小为 N N N,即 D = { x 1 , x 2 , . . . , x N } D=\{x_1, x_2, ..., x_N\} D={x1,x2,...,xN};我们要训练 M M M 个基学习器(映射) T = { f 1 , f 2 , . . . , f M } T=\{f_1, f_2, ..., f_M\} T={f1,f2,...,fM}

首先是有放回抽样得到训练数据集。对于 M M M 个基学习器,我们都从 D D D 中有放回地抽取 N N N 个数据构成训练数据集。

上一部分我们说到,对于一棵树来说,(在样本量较大的时候)平均来讲会有 36.8 % 36.8\% 36.8% 的数据没有被它抽到。上一部分我们省略了证明,下面我们来证一下。

我们一共有 N N N 个数据,那么,对于其中任意一个数据 x i x_i xi,它在某次抽取中被抽到的概率就是 1 N \frac 1 N N1,不被抽到的概率就是 1 − 1 N 1-\frac 1 N 1N1.

well,因为最终需要 N N N 个数据,所以我们一共抽取 N N N 次。
这样, x i x_i xi 在这 N N N 次都没有被抽到的概率就可以表示为:
( 1 − 1 N ) N (1-\frac 1 N)^N (1N1)N

我们考虑最极端的情况,也就是 N N N 趋于无穷大时候的情况。至于这么考虑的道理,后面会揭晓的,嘿嘿。

也就是说,我们想要得到下面这个式子的值:
lim ⁡ N → ∞ ( 1 − 1 N ) N \lim_{N \to \infty} (1-\frac 1 N)^N Nlim(1N1)N

weeeeell…
如果你学过高数或者数列的话,你可能见过这个式子,并且知道它的收敛于 1 e \frac 1 e e1。这是一个很妙的结论,在这里我给出一个证明。

首先我们先取个 ln ⁡ \ln ln 把指数变成对数。

lim ⁡ N → ∞ ( 1 − 1 N ) N = lim ⁡ N → ∞ exp ⁡ ( N ln ⁡ ( 1 − 1 N ) ) \begin{align} & \lim_{N \to \infty} \left( 1 - \frac{1}{N} \right)^N \\ & = \lim_{N \to \infty} \exp \left( N \ln \left( 1 - \frac{1}{N} \right) \right) \\ \end{align} Nlim(1N1)N=Nlimexp(Nln(1N1))

然后,我们使用一个近似,当 x → 0 x \to 0 x0 时, ln ⁡ ( 1 + x ) → x \ln (1+x) \to x ln(1+x)x.
这个近似可以通过泰勒展开得到,在这里不详细说明了。

因为 N → ∞ N\to\infty N,所以 1 N → 0 \frac 1 N\to0 N10,所以 ln ⁡ ( 1 − 1 N ) → − 1 N \ln (1-\frac 1 N) \to -\frac 1 N ln(1N1)N1.

那么,我们可以进一步化简这个式子了…
= lim ⁡ N → ∞ exp ⁡ ( N ⋅ ( − 1 N ) ) = lim ⁡ N → ∞ exp ⁡ ( − 1 ) = exp ⁡ ( − 1 ) = 1 e \begin{align} & = \lim_{N \to \infty} \exp \left( N \cdot \left( -\frac{1}{N} \right) \right) \\ & = \lim_{N \to \infty} \exp \left( -1 \right) \\ & = \exp(-1) \\ & = \frac{1}{e} \end{align} =Nlimexp(N(N1))=Nlimexp(1)=exp(1)=e1

很好!最终我们得到,这个式子收敛于 1 e \frac 1 e e1,也就是大约 0.368 0.368 0.368,或者说 36.8 % 36.8\% 36.8%.

这是说,当 N N N 足够大的时候,有放回地从原始数据集中抽取 N N N 个样本,某个样本始终没有被抽到的概率约为 36.8 % 36.8\% 36.8%

好的,从这个结论出发…

我们一共有 N N N 个数据,每个数据大约有 36.8 % 36.8\% 36.8% 的概率不被抽到,那么整个数据集就会有大约 N ∗ 1 e N* \frac 1 e Ne1 的数据不被抽到(期望),也就是大约 36.8 % 36.8\% 36.8% 的数据不被抽到。

也就是说, N N N 足够大的时候,在一次有放回抽样中,大约有 36.8 % 36.8\% 36.8% 的样本不会被抽到,或者说一次有放回抽样得到的数据集中通常包含 63.2 % 63.2\% 63.2% 原数据集中的数据。

very nice! 这为有放回抽样提供了理论支持!! 这告诉我们,在最极端的情况下,对于每一棵树,它的训练集中(平均)也只包含了原始数据集的 63.2 % 63.2\% 63.2%。这保证了树之间的多样性,对这些树进行集成,能够比较好地降低方差。

emmm 不过,别忘了我们现在讨论的情况—— N → ∞ N \to \infty N.
你可能会想,嗯在这种情况下确实,每棵树的训练集中都会随机地有将近 40% 的原始数据没有被选择,确实能保证树的多样性。但是,如果不是这种情况呢,如果 N N N 并不是很大呢?那会不会出现其它的情况,比如每棵树的训练集中都只有很少的原始数据没有被选择到,导致每棵树的训练集很相似…

好好好,其实看一下函数图像什么就都解决了,so 我画了一个:

函数图像

从图上不难看出,从 N = 6 N=6 N=6 开始,后面就几乎是一条平行于 x x x 轴的直线了,也就说,只要数据量多于 6 个,就问题不大。

实际情况中,数据量显然会多于 6 个呀。。所以没什么问题,有放回抽取是一个非常好的方法!

呃好像这篇的数学内容里有趣的部分到这里就结束了。。。?emm 不过我们还是接着把剩下的数学叙述说完。

豪德,现在 assume(这是我们的一个梗 )我们已经训练完了这 M M M 个模型。接下来我们来预测一些新样本…

(和前面我们讲的很多个模型一样)
对于分类问题,我们把 M M M 个基学习器给出的最多的类别作为最终的输出值,即:
y t = arg max ⁡ c ∑ m = 1 M I ( f m ( x t ) = c ) y_t=\argmax_c \sum_{m=1}^M \mathbb{I}(f_m(x_t)=c) yt=cargmaxm=1MI(fm(xt)=c)

其中 c c c 代表类别; M M M 是基学习器的个数; I \mathbb{I} I 是指示函数,当括号内为真时,函数的值为 1,否则为 0; f m ( x t ) f_m(x_t) fm(xt) 为第 m m m 个基学习器给出的预测(类别)。

对于回归问题,我们把 M M M 个基学习器输出的值的平均值作为最终的输出值,即:
y t = 1 M ∑ m = 1 M f m ( x t ) y_t=\frac 1 M \sum_{m=1}^M f_m(x_t) yt=M1m=1Mfm(xt)

en,拿到对新数据的预测之后,我们就可以计算损失了。对于分类问题就是交叉熵损失,对于回归问题就是平方损失。
这两种损失的计算在前面的文章当中已经讲过很多遍了,这里就不再单独展开啦~

好耶!现在我们已经把 Bagging 讲完了!
Bagging 其实可以看作一种,或者说一类思想,也可以看作一个基础版本。从它出发,我们可以得到很多变种。随机森林时其中最有代表性也是最被大家所熟知的一种,so 我们接下来来聊聊随机森林!

特例:随机森林

随机森林,Bagging 家族最经典的代表。

不知道你发没发现,虽然前面我们一直 assume Bagging 中的基学习器是决策树,但是我们好像一直没提到决策树的特征选择问题诶()

eee 这也好解释,在 Bagging 中训练决策树的时候,我们默认的都是使用最佳分裂特征。
但是…增加模型的多样性,是不是也可以从分裂特征的角度考虑呢?

关于分裂特征的更多内容:【初中生讲机器学习】13. 决策树算法一万字详解!一篇带你看懂!

更进一步,如果我们像选择数据一样,每次都从所有的分裂特征中选出一部分,再从这一部分中选出最佳分裂特征,是不是也是一种值得的尝试呢?

emmmm 怎么一不小心把随机森林的做法给说出来了()

好吧好吧不卖关子了,,,随机森林的做法就是上面我说到的:在每个分裂点(注意是每个分裂点,而不是每棵树),都从所有的分裂特征中随机选取一部分,形成候选特征集合,然后再从候选特征集合中选出最佳分裂特征

换言之,随机森林给出的每个分裂点的最佳分裂特征不一定是实际的最佳分裂特征,因为它是从随机选出的候选特征集合中选择分裂特征,而不是从所有特征中选择分裂特征。

所以其实,你可以把随机森林看作加入了特征选择随机性的 Bagging(就这么简单(

eaaa 除此之外随机森林和 Bagging 完全一样,没有什么好说的。

好耶!那其实随机森林也说完了,嘿嘿。

嗯,那我们来总结一下这一篇吧!
Bagging 是集成学习的分支之一,通常以深层决策树作为基学习器,通过组合多个基学习器来降低它们的方差

Bagging 的多样性(随机性)主要来源于它的有放回抽取策略。这种策略保证了每棵树的训练数据集都是不同的,但又有一定的重合,可以比较有效的避免过拟合。

随机森林在 Bagging 的基础上引入了特征选择的随机性。对于每个分裂节点,它都在原始的所有特征中随机选取一部分作为候选特征子集,再从候选特征子集中选出最优分裂特征。这种做法可以进一步提高基学习器的多样性,防止模型过拟合。

en!! 以上就是 Bagging 和随机森林的全部内容!


啊哈哈哈哈那这篇就到这里啦!感觉是整个系列的最简单的一篇文章((

下一篇可能会接着贝叶斯网络讲马尔可夫网络,嘿嘿,keeeep follow!

这篇文章详细讲解了 Bagging 类算法(及其特例,随机森林)的核心思想,并给出了数学叙述,希望对你有所帮助!⭐
欢迎三连!!一起加油!🎇
——Geeker_LStar

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

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

相关文章

springSecurity权限控制

权限控制:不同的用户可以使用不同的功能。 我们不能在前端判断用户权限来控制显示哪些按钮,因为这样,有人会获取该功能对应的接口,就不需要通过前端,直接发送请求实现功能了。所以需要在后端进行权限判断。&#xff0…

李飞飞的生成式3D场景,对数字孪生的未来影响几何?

大家好,我是日拱一卒的攻城师不浪,致力于技术与艺术的融合。这是2024年输出的第47/100篇文章。 前言 这两天,AI界的教母李飞飞团队重磅发布了空间智能生成式AI大模型。 仅通过一张图片就能够生成一个可操作和交互的3D空间场景。 空间智能的…

意图识别模型使用 基于BERT的对话意图和槽位联合识别 CPU运行BERT模型-亲测成功

意图识别模型使用 基于BERT的对话意图和槽位联合识别 CPU运行BERT模型-亲测成功 我们在开发AI-Agent智能体时,通常会使用提示词工程设置场景的带入,在实际项目中会有很多场景,如果所有提示词都放一起就会超过Token限制,则不得不拆…

OSG开发笔记(三十七):OSG基于windows平台msvc2017x64编译器官方稳定版本OSG3.4.1搭建环境并移植Demo

​若该文为原创文章,未经允许不得转载 本文章博客地址:https://blog.csdn.net/qq21497936/article/details/144258047 各位读者,知识无穷而人力有穷,要么改需求,要么找专业人士,要么自己研究 长沙红胖子Qt…

《毛泽东思想和中国特色社会理论概述》课程报告Latex版本

所需要的图片: 源码(可运行): \documentclass[12pt]{article} \usepackage{ctex} \usepackage{graphicx} \usepackage{booktabs} \usepackage{titlesec} \usepackage{geometry} \usepackage{float} \usepackage{tabularx} \usepackage{enumitem} …

2024.12.6——攻防世界PHP2

知识点:目录扫描 代码审计 传参知识点补充: 后缀名为.phps的文件出现在无法使用web浏览器查看php源代码的情况下,.phps文件就是php的源代码文件,通常用于提供给用户(访问者)查看php代码,因为用…

OSI模型及各层缺陷

1.TCP/IP概述 (1)TCP/IP基本结构 TCP/IP是一组Internet协议,不但包括TCP和IP两个关键协议,还包括其他协议,如UDP、ARP、ICMP、Telnet和FTP等。TCP/IP的设计目标是使不同的网络互相连接,即实现互…

【论文阅读】Fifty Years of the ISCA: A Data-Driven Retrospective

学习体会: ISCA会议近五十年文章分析, 了解论文热点方向, 处理器依旧是热点! AI和并行是大趋势, 做XPU相关目前来说还是热点~ 摘录自原文 摘录: 数据来源和分析方法: 作者收集了 ACM 数字图书馆中所有 ISCA 论文,并使用 DBLP、Google Schol…

什么是MMD Maximum Mean Discrepancy 最大均值差异?

9多次在迁移学习看到了,居然还是Bernhard Schlkopf大佬的论文,仔细看看。 一.什么是MMD? 1. MMD要做什么? 判断两个样本(族)是不是来自于同一分布 2.怎么做?(直观上)…

LDR6500:音频双C支持,数字与模拟的完美结合

在当今数字化快速发展的时代,音频设备的兼容性和性能成为了用户关注的重点。LDR6500,作为乐得瑞科技精心研发的USB Power Delivery(PD)协议芯片,凭借其卓越的性能和广泛的应用兼容性,为音频设备领域带来了新…

Leetcode 每日一题 1.两数之和

目录 问题描述 示例 示例 1 示例 2 示例 3 提示 解决方案 算法思路 过题图片 代码实现 复杂度分析 注意事项 题目链接 结论 问题描述 给定一个整数数组 nums 和一个目标值 target,请你找出数组中和为目标值的那两个整数,并返回它们的数组下…

【萤火工场CEM5826-M11测评】Arduino 采集雷达模块数据与串口绘图

【萤火工场CEM5826-M11测评】Arduino 采集雷达模块数据与串口绘图 当采用串口输出模式时,雷达检测到运动时,则输出 v0.0km/h, str1234 字样; v 表示目标速度大小,str 表示信号强度; 当雷达检测不到目标时&#xff0c…

【C++】选择排 序算法分析与扩展

博客主页: [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C 文章目录 💯前言💯代码回顾💯选择排序的算法流程💯代码详解外层循环初始化最小值内层循环比较与更新元素交换 💯选择排序的特性时间复杂度空间复杂度稳定性…

3D 生成重建024-LGM第一个开源的3D生成大模型!

3D 生成重建024-LGM第一个开源的3D生成大模型 文章目录 0 论文工作1 论文方法2 实验效果 0 论文工作 这篇论文介绍了一种名为LGM(大型多视角高斯模型)的新方法,用于从单视角图像或文本提示生成高分辨率的三维内容。该方法的核心思想是双重的…

微信 创建小程序码-有数量限制

获取小程序码:小程序码为圆图,有数量限制。 目录 文档 接口地址 功能描述 注意事项 请求参数 对接 获取小程序码 调用获取 小程序码示例 总结 文档 接口地址 https://api.weixin.qq.com/wxa/getwxacode?access_tokenaccess_token 功能描述 …

日志基础示例python和c++

文章目录 0. 引言1. python2. c 0. 引言 本文主要记录python版本和c版本常用的日志基础示例。 1. python python版本常用的是logging库,结合colorlog库,可根据不同日志级别打印不同颜色的日志,为了便于分析问题,还添加了日志保…

泷羽sec学习打卡-brupsuite4

声明 学习视频来自B站UP主 泷羽sec,如涉及侵权马上删除文章 笔记的只是方便各位师傅学习知识,以下网站只涉及学习内容,其他的都 与本人无关,切莫逾越法律红线,否则后果自负 关于brupsuite的那些事儿-proxy proxyInterceptHTTP history/WebSocket history(历史记录&a…

喜报!极限科技(INFINI Labs)通过国家高新技术企业认定

2024 年 10 月 29 日,国家高新技术企业认定管理工作网公示了北京市认定机构 2024 年认定报备的第一批高新技术企业备案名单,极限数据(北京)科技有限公司 顺利通过本次高新技术企业评审,并获得 国家级“高新技术企业”认…

STM32 USART串口通信 综合练习

USART(通用同步/异步串行接收/发送器)串口通信具有以下特点: 全双工操作:设备之间可以同时进行数据的发送和接收。异步通信:不需要共同的时钟信号,双方设备有各自的时钟。单端信号:使用一根线传…

Linux - 进程等待和进程替换

进程等待 前面我们了解了如果父进程没有回收子进程, 那么当子进程接收后, 就会一直处于僵尸状态, 导致内存泄漏, 那么我们如何让父进程来回收子进程的资源. waitpid 我们可以通过 Linux 提供的系统调用函数 wait 系列函数来等待子进程死亡, 并回收资源. #include <sys/t…