5.1 神经网络: 层和块
1 层(Layer)
1.1 定义
层是深度学习模型中的基本构建单元,它由一组神经元组成,负责对输入数据进行特定的数学运算和变换,以提取数据的某种特征或表示。每一层可以看作是一个函数,它接收输入数据,并通过该层的权重和偏置等参数以及激活函数等操作,产生输出。
1.2 作用
不同的层可以实现不同的功能,比如卷积层可以用于提取图像的空间特征,池化层可以用于下采样以减少数据的维度和计算量,全连接层可以用于对全局特征进行综合和分类等。通过堆叠多层,模型可以逐步学习数据的复杂模式和层次化特征,从而对输入数据进行更深入的理解和处理,以完成如分类、回归、生成等任务。
2 块(Block)
2.1 定义
块是比层更高层次的构建单元,它通常由多个层按照某种特定的方式组合而成,形成一个相对独立的功能模块。块可以看作是一个封装好的子网络,具有一致的输入输出接口,可以在不同的位置重复使用。
块(block)可以描述单个层、由多个层组成的组件或整个模型本身
块由类(class)表示。 它的任何子类都必须定义一个将其输入转换为输出的前向传播函数, 并且必须存储任何必需的参数(有些块不需要任何参数)。
块必须具有反向传播函数
2.2 作用
块的设计主要是为了提高模型的性能和效率,以及增强模型的可扩展性和可重用性。例如,ResBlock(残差块)通过引入残差连接,解决了深层网络训练时梯度消失和梯度爆炸的问题,使得网络可以更有效地训练;Inception Block(Inception块)通过多尺度卷积操作,能够同时捕捉不同尺度的特征,提高模型对特征的表达能力。还有像Transformer中的Encoder Block和Decoder Block,它们分别负责编码和解码序列信息,通过堆叠多个这样的块可以构建强大的序列处理模型。
3 两者的区别与联系
区别
(1)粒度不同
层是模型的微观构成部分,是最基本的计算单元;块则是由多个层组成的宏观模块,是对多个层的进一步抽象和封装。
(2)功能侧重不同
层主要关注于实现具体的数学运算和特征提取;块更侧重于组合多个层以实现某种特定的结构或功能,解决某些特定的问题或满足特定的性能要求。
联系
(1)块是由层构成的,多个层按照一定的规则组合在一起就形成了一个块。
(2)层和块在构建深度学习模型时是相互配合的,层是块的基础,块则是构建更复杂模型结构的重要单元。通过对不同层和块的组合和堆叠,可以构建出各种各样功能强大的深度学习模型,以应对不同的任务和数据特点。
4 多层感知机代码
MLP: 包含256个隐藏单元和ReLU激活函数的全连接隐藏层, 具有10个隐藏单元且不带激活函数的全连接输出层
import torch
from torch import nn
from torch.nn import functional as Fnet = nn.Sequential(nn.Linear(20, 256), nn.ReLU(), nn.Linear(256, 10))X = torch.rand(2, 20)
net(X)
4.1 自定义块
class MLP(nn.Module):# 用模型参数声明层。这里,我们声明两个全连接的层def __init__(self):# 调用MLP的父类Module的构造函数来执行必要的初始化。# 这样,在类实例化时也可以指定其他函数参数,例如模型参数params(稍后将介绍)super().__init__()self.hidden = nn.Linear(20, 256) # 隐藏层self.out = nn.Linear(256, 10) # 输出层# 定义模型的前向传播,即如何根据输入X返回所需的模型输出def forward(self, X):# 注意,这里我们使用ReLU的函数版本,其在nn.functional模块中定义。return self.out(F.relu(self.hidden(X)))
net = MLP()
net(X)
4.2 顺序块
4.2.1 代码示例
import torch
import torch.nn as nn# 定义 MySequential 类
class MySequential(nn.Module):def __init__(self, *args):super().__init__()for idx, module in enumerate(args):self._modules[str(idx)] = moduledef forward(self, X):for block in self._modules.values():X = block(X)return X
定义一个简单的神经网络模型,使用 MySequential 组合多个层
model = MySequential(nn.Linear(4, 8), # 第一层:输入维度4,输出维度8的全连接层nn.ReLU(), # 第二层:ReLU 激活函数nn.Linear(8, 10), # 第三层:输入维度8,输出维度10的全连接层nn.Sigmoid() # 第四层:Sigmoid 激活函数
)# 输入张量,假设 batch_size 为 2,输入特征维度为4
X = torch.randn(2, 4)
print("输入 X 的形状:", X.shape)# 前向传播
output = model(X)
print("输出 output 的形状:", output.shape)
4.2.2 MySequential调用过程
在上述案例中,for idx, module in enumerate(args): self._modules[str(idx)] = module
这段代码在实例化 MySequential
模型时执行,具体来说,当创建 model
实例时,传入的 args
包含四个模块:nn.Linear(4, 8)
、nn.ReLU()
、nn.Linear(8, 10)
和 nn.Sigmoid()
。以下是这段代码在该案例中的具体执行过程:
-
调用
MySequential
的构造函数- 当执行
model = MySequential(nn.Linear(4, 8), nn.ReLU(), nn.Linear(8, 10), nn.Sigmoid())
时,会调用MySequential
类的__init__
方法,传入的args
是一个包含四个模块的元组。
- 当执行
-
初始化父类
- 执行
super().__init__()
,完成nn.Module
父类的初始化,这包括初始化_modules
这个有序字典,用于存储子模块。
- 执行
-
遍历
args
中的模块- 使用
enumerate(args)
遍历传入的模块。enumerate
会返回每个模块及其对应的索引:- 第一次迭代:
idx = 0
,module = nn.Linear(4, 8)
- 第二次迭代:
idx = 1
,module = nn.ReLU()
- 第三次迭代:
idx = 2
,module = nn.Linear(8, 10)
- 第四次迭代:
idx = 3
,module = nn.Sigmoid()
- 第一次迭代:
- 使用
-
将模块添加到
_modules
- 对于每次迭代,将当前模块添加到
_modules
有序字典中,键为索引的字符串形式,值为对应的模块:- 第一次迭代后:
self._modules["0"] = nn.Linear(4, 8)
- 第二次迭代后:
self._modules["1"] = nn.ReLU()
- 第三次迭代后:
self._modules["2"] = nn.Linear(8, 10)
- 第四次迭代后:
self._modules["3"] = nn.Sigmoid()
- 第一次迭代后:
- 对于每次迭代,将当前模块添加到
-
最终结果
-
_modules
有序字典中按顺序存储了传入的四个模块,键分别为"0"
、"1"
、"2"
、"3"
,对应的值分别是nn.Linear(4, 8)
、nn.ReLU()
、nn.Linear(8, 10)
和nn.Sigmoid()
。 -
这些模块被正确地注册为
MySequential
实例的子模块,这样在后续的前向传播过程中,可以通过_modules.values()
按顺序获取并执行这些模块,确保输入数据依次经过每个模块的处理。
这段代码在实例化 MySequential
时,将传入的模块按照顺序添加到 _modules
中,为后续的前向传播做好准备。
4.2.3 forward方法调用过程
在上面的例子中,forward
方法的执行过程如下:
- 调用
forward
方法
当执行 output = model(X)
时,会自动调用 MySequential
类的 forward
方法,将输入张量 X
传递进去。
- 遍历
_modules.values()
forward
方法中通过 self._modules.values()
获取按顺序排列的子模块集合:
for block in self._modules.values():
- 依次执行每个模块的前向传播
对于每个模块(block
),将当前的输入 X
传递给该模块进行前向传播:
X = block(X)
4.2.4 forward方法具体执行过程示例
假设输入张量 X
的形状为 (2, 4)
:
-
第一个模块:
block = nn.Linear(4, 8)
- 输入:
X
(形状(2, 4)
) - 进行线性变换,权重矩阵
W
的形状为(8, 4)
,偏置项b
的形状为(8,)
- 输出:经过线性变换后的张量(形状
(2, 8)
)
- 输入:
-
第二个模块:
block = nn.ReLU()
- 输入:上一步得到的张量(形状
(2, 8)
) - 应用 ReLU 激活函数,将负值变为 0,正值保持不变
- 输出:ReLU 激活后的张量(形状
(2, 8)
)
- 输入:上一步得到的张量(形状
-
第三个模块:
block = nn.Linear(8, 10)
- 输入:ReLU 激活后的张量(形状
(2, 8)
) - 进行线性变换,权重矩阵
W
的形状为(10, 8)
,偏置项b
的形状为(10,)
- 输出:经过线性变换后的张量(形状
(2, 10)
)
- 输入:ReLU 激活后的张量(形状
-
第四个模块:
block = nn.Sigmoid()
- 输入:上一步得到的张量(形状
(2, 10)
) - 应用 Sigmoid 激活函数,将每个元素压缩到
(0, 1)
的范围内 - 输出:Sigmoid 激活后的张量(形状
(2, 10)
)
- 输入:上一步得到的张量(形状
-
返回最终输出
所有模块执行完毕后,将最后得到的张量作为整个模型的输出返回:
return X
在上面的例子中,最终输出张量的形状为 (2, 10)
4.3 在前向传播中自定义过程
在前向传播函数中执行Python的控制流,如计算函数 f ( x , w ) = c ∗ w T x f(x,w)=c*w^Tx f(x,w)=c∗wTx的层, 其中x是输入, w是参数,c是某个在优化过程中没有更新的指定常量
4.3.1 FixedHiddenMLP类示例
class FixedHiddenMLP(nn.Module):def __init__(self):super().__init__()# 不计算梯度的随机权重参数。因此其在训练期间保持不变self.rand_weight = torch.rand((20, 20), requires_grad=False)self.linear = nn.Linear(20, 20)def forward(self, X):X = self.linear(X)# 使用创建的常量参数以及relu和mm函数X = F.relu(torch.mm(X, self.rand_weight) + 1)# 复用全连接层。这相当于两个全连接层共享参数X = self.linear(X)# 控制流while X.abs().sum() > 1:X /= 2return X.sum()
4.3.2 FixedHiddenMLP 类解析
这个类定义了一个包含特定隐藏层结构的多层感知机(MLP),它具有以下特点:
__init__
方法 :用于初始化模型的参数和层。forward
方法 :定义了模型的前向传播逻辑,包括线性变换、激活函数、矩阵乘法、控制流语句等。
- 初始化过程
self.rand_weight = torch.rand((20, 20), requires_grad=False)
- 随机权重参数
self.rand_weight
:创建一个形状为(20, 20)
的随机权重矩阵,并设置requires_grad=False
,表示这个参数在训练过程中不计算梯度,即保持不变。
self.linear = nn.Linear(20, 20)
- 全连接层
self.linear
:定义一个输入和输出维度都为 20 的全连接层,这个层的权重和偏置会在训练过程中更新。
- 前向传播过程
X = self.linear(X)
- 第一步:全连接层 :将输入
X
传递给全连接层self.linear
,进行线性变换,输出结果的形状与输入相同,为(batch_size, 20)
。
X = F.relu(torch.mm(X, self.rand_weight) + 1)
- 第二步:矩阵乘法和激活函数 :将上一步的输出与随机权重矩阵
self.rand_weight
进行矩阵乘法操作,然后加上 1,再应用 ReLU 激活函数。这一步的计算可以表示为X = F.relu(torch.mm(X, self.rand_weight) + 1)
。矩阵乘法操作将输入特征与随机权重矩阵相乘,加上 1 后应用 ReLU 激活函数,引入非线性。
X = self.linear(X)
- 第三步:复用全连接层 :再次将上一步的输出传递给全连接层
self.linear
,进行线性变换。这相当于两个全连接层共享相同的参数。
while X.abs().sum() > 1:X /= 2
- 第四步:控制流语句 :使用一个
while
循环检查张量X
的绝对值之和是否大于 1。如果是,则将X
除以 2,直到其绝对值之和小于或等于 1。这个控制流语句用于对输出进行归一化,确保其值不会过大。
return X.sum()
- 第五步:返回结果 :最后返回张量
X
的所有元素之和。
- 总结
这个 FixedHiddenMLP
类定义了一个具有特定隐藏层结构的多层感知机。它的前向传播过程包括两次全连接层的线性变换,中间插入了矩阵乘法和 ReLU 激活函数,并使用了控制流语句对输出进行归一化。这种结构展示了如何在深度学习模型中使用控制流语句和共享参数的层。
在实际使用中,这个模型的输入需要是一个二维张量,形状为 (batch_size, 20)
,其中 batch_size
是批量大小。模型的输出是一个标量,即张量 X
的所有元素之和。
相关文章:
5.1 神经网络: 层和块
1 层(Layer) 1.1 定义 层是深度学习模型中的基本构建单元,它由一组神经元组成,负责对输入数据进行特定的数学运算和变换,以提取数据的某种特征或表示。每一层可以看作是一个函数,它接收输入数据ÿ…...
鸿蒙系统使用ArkTS开发语言支持身份证阅读器、社保卡读卡器等调用二次开发SDK
har库导入: { "license": "", "devDependencies": {}, "author": "", "name": "entry", "description": "Please describe the basic information.", &qu…...
【Bootstrap V4系列】学习入门教程之 组件-输入组(Input group)
Bootstrap V4系列 学习入门教程之 组件-输入组(Input group) 输入组(Input group)Basic example一、Wrapping 包装二、Sizing 尺寸三、Multiple inputs 多输入四、Multiple addons 多个插件五、Button addons 按钮插件六、Buttons with dropdowns 带下拉按钮七、Custom for…...
图像处理篇--- HTTP|RTSP|MJPEG视频流格式
文章目录 前言一、MJPEG (Motion JPEG)基本概念技术特点编码方式传输协议数据格式 优势实现简单低延迟兼容性好容错性强 劣势带宽效率低不支持音频缺乏标准控制 典型应用 二、RTSP (Real Time Streaming Protocol)基本概念技术特点协议栈工作流程传输模式 优势专业流媒体支持高…...
`RotationTransition` 是 Flutter 中的一个动画组件,用于实现旋转动画效果
RotationTransition 是 Flutter 中的一个动画组件,用于实现旋转动画效果。它允许你对子组件进行动态的旋转变换,从而实现平滑的动画效果。RotationTransition 通常与 AnimationController 和 Tween 一起使用,以控制动画的开始、结束和过渡效果…...
养生:开启健康生活的密钥
在快节奏的现代生活中,养生已成为追求健康的重要方式。从饮食、运动到生活习惯,每一个细节都关乎身体的健康。以下为你介绍科学养生的实用方法,助你打造健康生活。 饮食养生:均衡营养,滋养身体 合理的饮食是养生的基…...
大模型微调算法原理:从通用到专用的桥梁
前言 本文聚焦大模型落地中的核心矛盾——理论快速发展与实际应用需求之间的脱节,并系统探讨微调技术作为解决这一矛盾的关键手段。尽管大模型展现出强大的通用能力,但其在垂直领域的直接应用仍面临适配性不足、计算成本高等挑战。微调通过在预训练模型基础上进行针对性优化,…...
引言:Client Hello 为何是 HTTPS 安全的核心?
当用户在浏览器中输入 https:// 时,看似简单的操作背后,隐藏着一场加密通信的“暗战”。Client Hello 作为 TLS 握手的首个消息,不仅决定了后续通信的加密强度,还可能成为攻击者的突破口。据统计,超过 35% 的网站因 TL…...
深度学习中的目标检测:从 PR 曲线到 AP
深度学习中的目标检测:从 PR 曲线到 AP 在目标检测任务中,评估模型的性能是非常重要的。通过使用不同的评估指标和标准,我们可以量化模型的准确性与效果。今天我们将重点讨论 PR 曲线(Precision-Recall Curve)、平均精…...
测试左移系列-产品经理实战-实战认知1
课程:B站大学 记录产品经理实战项目系统性学习,从产品思维,用户画像,用户体验,增长数据驱动等不同方向理解产品,从0到1去理解产品从需求到落地的全过程,测试左移方向(靠近需求、设计…...
数据集-目标检测系列- 烟雾 检测数据集 smoke >> DataBall
数据集-目标检测系列- 消防 浓烟 检测数据集 smoke>> DataBall 数据集-目标检测系列- 烟雾 检测数据集 smoke >> DataBall * 相关项目 1)数据集可视化项目:gitcode: https://gitcode.com/DataBall/DataBall-detections-10…...
概率论与数理统计基础学习大纲
📅 课程规划 阶段一:基础入门(第1-3周) 目标:掌握概率基础和基本分布 核心知识点: 概率论的基本概念:随机事件、样本空间、概率公理条件概率与全概率公式:贝叶斯公式、事件独立性随机变量与分布:离散型和连续型随机变量常见分布: 离散:二项分布、泊松分布连续:…...
5大B2B数字营销社群营销标杆案例TOB企业数字化营销内容营销AI营销培训讲师培训师专家顾问唐兴通分享
全球B2B数字营销领域的企业社区(或BBS)标杆案例 在全球TOB(企业对企业)和B2B数字营销实践中,构建企业社区或在线论坛(BBS的现代演变)已成为增强客户关系、驱动产品采用、获取市场洞察和 genera…...
OC语言学习——Foundation框架(上)
一、字符串 NSString代表字符序列不可变的字符串,而NSMutable代表字符序列可变的字符串。 1.1 NSString字符串及功能 通过NSString,我们可以: 1、创建字符串。2、读取文件或网络URL来初始化字符串,或者将字符串写入文件或URL。3…...
【Linux】基础 IO(一)
📝前言: 这篇文章我们来讲讲Linux——基础IO主要包括: 文件基本概念回顾 C文件的操作介绍系统关于文件的基本操作 🎬个人简介:努力学习ing 📋个人专栏:Linux 🎀CSDN主页 愚润求学 …...
ODA服务器计算节点本地硬盘状态异常的处理
近期,在系统巡检过程中发现一个客户的ODA服务器本地硬盘节点出现告警,ODAX8 X9等,本地硬盘是使用的240GB M.2接口的SSD盘(卡式)的,这个没有外置的指示灯可以从服务器前面板查看,打开服务器机箱盖…...
图像处理篇---opencv实现坐姿检测
文章目录 前言一、方法概述使用OpenCV和MediaPipe关键点检测角度计算姿态评估 二、完整代码实现三、代码说明PostureDetector类find_pose()get_landmarks()cakculate_angle()evaluate_posture() 坐姿评估标准(可进行参数调整):可视化功能&…...
微调ModernBERT为大型语言模型打造高效“过滤器”
ModernBERT(2024 年 12 月)是最近发布的小型语言模型,由 Answer.AI、LightOn 和 HuggingFace 共同开发。它利用了现代优化技术,如用于 8,192 token 上下文窗口的 RoPE 和 GeGLU layers,在保持效率的同时提升性能。jina…...
【C++指南】STL容器的安全革命:如何封装Vector杜绝越界访问与迭代器失效?
🌟 各位看官好,我是egoist2023! 🌍 种一棵树最好是十年前,其次是现在! 🚀 使用STL的三个境界:能用,明理,能扩展 👍 如果觉得这篇文章有帮助&#…...
Linux在web下http加密和配置虚拟主机及动态页面发布
web服务器的数据加密 1.简介:由于http协议以明文方式发送,不提供任何方式的数据加密,也不适合传输一些重要的信息,如银行卡号、密码等,解决该缺陷设计了安全套接字层超文本传输协议https; 2.https的握手流…...
8.2.CICD自动化
目录 一、持续集成(CI)核心实践 代码质量管理 • 静态代码分析:SonarQube规则定制(安全漏洞、代码异味检测) • 单元测试覆盖率:Jacoco报告生成与阈值控制(覆盖率≥80%) • 代码风格…...
解密数据结构之位图和布隆过滤器
位图和布隆过滤器 前言:笔者在前面分享过哈希的知识,但是笔者在哈希那篇博客中并没有给出哈希的应用场景,今天笔者分享的知识是关于哈希的应用,也就是大名鼎鼎的位图和布隆过滤器。1.位图的定义位图解决 2.位图实现1.先使用命名空间封装&…...
《从零构建大模型》PDF下载(中文版、英文版)
内容简介 本书是关于如何从零开始构建大模型的指南,由畅销书作家塞巴斯蒂安• 拉施卡撰写,通过清晰的文字、图表和实例,逐步指导读者创建自己的大模型。在本书中,读者将学习如何规划和编写大模型的各个组成部分、为大模型训练准备…...
Linux的web服务器的部署和优化
http中访问请求中I/O结构 在HTTP协议中,I/O(输入/输出)结构主要涉及客户端与服务器之间的请求和响应交互。以下是HTTP请求和响应的基本结构及其关键组成部分: HTTP请求结构 HTTP请求由请求行、请求头和请求体三部分组成 请求行…...
vue2 上传pdf,拖拽盖章,下载图片
效果图片: 不多废话上代码: <template><div class"pdf-stamp" onbeforecopyreturn false onselectdocument.selection.empty() ondragstartreturn false onselectstart return false ><div class"scroll-box" scro…...
MindSpore框架学习项目-ResNet药物分类-模型训练
目录 3.模型训练 3.1模型训练 3.1.1 定义优化器和损失函数 定义优化器和损失函数代码解析 3.1.2定义训练、推理函数 定义训练、推理函数代码解释 3.2模型保存 模型保存代码说明 3.3绘制acc和loss的曲线 参考内容: 昇思MindSpore | 全场景AI框架 | 昇思Mind…...
Jsp技术入门指南【十二】自定义标签
Jsp技术入门指南【十二】自定义标签 前言一、什么是标签二、标签的类型有哪些?1. 空标签2. 带有属性的标签3. 带主体的标签 三、自定义标签的部件3.1 自定义标签的四步骤3.2 标签处理程序3.3 自定义标签的开发及使用步骤第一步:创建标签助手类第二步&…...
数据库故障排查指南:从连接问题和性能优化
数据库作为现代应用程序的核心组件,其稳定性和性能直接影响整个系统的运行。然而,数据库在运行过程中常常会遇到各种故障,如连接失败、性能下降、数据不一致等问题。本文将从实际问题出发,结合代码示例和工具使用,系统…...
材料创新与工艺升级——猎板PCB引领高频阻抗板制造革命
在5G通信、AI服务器和自动驾驶的推动下,高频电路对信号完整性的要求日益严苛。猎板PCB作为国内高端PCB制造的标杆企业,通过材料创新与工艺革新,实现了阻抗控制的突破性进展,为行业树立了新标杆。 1. 高频材料的突破 传统FR-4基材…...
GitHub 趋势日报 (2025年05月09日)
本日报由 TrendForge 系统生成 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日整体趋势 Top 10 排名项目名称项目描述今日获星总星数语言1voideditor/void⭐ 1879⭐ 15214TypeScript2ruanyf/weekly科技爱好者周刊&…...
SaaS场快订平台项目说明【持续更新】
一、项目介绍 SaaS场快订平台是一个高效、便捷的体育场馆在线预订平台。本项目采用SaaS方式开发,用户不需要安装软件,直接通过互联网访问在线程序即可使用。本项目主要构建了一个体育馆预订系统,项目的功能主要包括:用户注册与登…...
PyTorch API 7 - TorchScript、hub、矩阵、打包、profile
文章目录 torch.hub发布模型如何实现入口点?重要通知 从Hub加载模型运行加载的模型:下载的模型保存在哪里?缓存逻辑已知限制: TorchScript创建 TorchScript 代码混合使用追踪与脚本化TorchScript 语言内置函数与模块PyTorch 函数与…...
OpenVLA:开源的视觉-语言-动作模型
1. 简介 让我们先来介绍一下什么是OpenVLA,在这里: https://openvla.github.io/ 可以看到他们的论文、数据、模型。 OpenVLA 是一个拥有 70亿参数的开源 **视觉-语言-动作(VLA)**模型。它是在 Open X-Embodiment 数据集 中的 97万…...
android HashMap和List该如何选择
目录 一,ArrayList 1.1 数组 1.2 扩容 1.3 查询 1.4 插入,删除 1.5 小结 二,LinkedList 2.1 链表 2.2 查找 2.3 插入 2.4 小结 三,HashMap 扩容 四,SparseArray 五,ArrayMap 一,ArrayList 1.…...
Visual Studio 2022 远程调试
Visual Studio 2022 远程调试全过程 这篇文章尽可能地精细记录如何使用 Visual Studio 2022 完成 Windows 系统上的远程调试。适用场景包括本地编译,远程运行,两台机器分工合作调试。 一、设备网络通信环境 1.1 确保两台设备通信 本地设备: 安装 Visu…...
Linux:线程同步与互斥
目录 线程互斥 锁 初始化 销毁 加锁 解锁 线程同步 条件变量 初始化 销毁 等待条件满足 唤醒等待 pthread_cond_signal pthread_cond_broadcast 生产者消费者模型 3种关系 2种角色 1个交易场所 POSIX信号量 初始化 销毁 等待 发布 线程互斥 互斥相关…...
Kotlin Android LeakCanary内存泄漏检测实战
在Kotlin Android应用中使用LeakCanary检测内存泄漏的步骤如下: 1. 添加依赖 在模块的build.gradle文件中添加LeakCanary依赖: dependencies {debugImplementation com.squareup.leakcanary:leakcanary-android:2.12 // 使用最新版本 }2. 自动初始化&…...
MySQL 中 count(*)、count(1) 和 count(字段名) 有什么区别?
在 MySQL 中,COUNT(*)、COUNT(1) 和 COUNT(字段名) 的核心区别在于 统计逻辑 和 性能表现,具体如下: 1. 统计逻辑差异 函数形式统计规则COUNT(*)统计表中所有行的数量,忽略字段值是否为 NULL(包括主键、非主键、NULL …...
CAD属性图框值与Excel联动(CAD块属性导出Excel、excel更新CAD块属性)——CAD c#二次开发
CAD插件实现块属性值与excel的互动,效果如下: 加载dll插件(CAD 命令行输入netload ,运行xx即可导出Excel,运行xx1即可根据excel更新dwg块属性值。) 部分代码如下 // 4. 开启事务更新CAD数据using (Transact…...
青少年编程与数学 02-019 Rust 编程基础 05课题、复合数据类型
青少年编程与数学 02-019 Rust 编程基础 05课题、复合数据类型 一、元组(Tuple)(一)元组的定义(二)创建元组示例 (三)解构元组示例 (四)使用点号语法访问元组…...
51单片机入门教程——AT24C02数据存储
前言 本教程基于B站江协科技课程进行个人学习整理,专为拥有C语言基础的零基础入门51单片机新手设计。既帮助解决因时间差导致的设备迭代调试难题,也助力新手快速掌握51单片机核心知识,实现从C语言理论到单片机实践应用的高效过渡 。 目录 …...
cdn 是什么?
内容分发网络,Content Delivery Network 介绍 CDN(Content Delivery Network)是一种将内容分发到靠近用户的边缘服务器,以加速访问速度、减少延迟、降低源站压力的网络系统。 CDN 把网站的静态资源(如 HTML、JS、CSS、…...
ENSP三层交换机实验原理及过程
华为eNSP(Enterprise Network Simulation Platform)是一款网络仿真工具,用于模拟华为网络设备的配置和操作。在三层交换机实验中,主要涉及三层交换机的路由功能、VLAN间通信、静态路由、动态路由协议(如OSPF、RIP&…...
RK3568-OpenHarmony(1) : OpenHarmony 5.1的编译
概述: 本文主要描述了,如何在ubuntu-20.04操作系统上,编译RK3568平台的OpenHarmony 5.1版本。 搭建编译环境 a. 安装软件包 sudo apt-get install git-lfs ruby genext2fs build-essential git curl libncurses5-dev libncursesw5-dev openjdk-11-jd…...
动态路由EIGRP的配置
动态路由EIGRP的配置 动态路由EIGRP:增强内部网关协议 为何收敛快、不成环? 路由计算的无环路和路由的收敛速度是路由计算的重要指标。EIGRP协议由于使用了DUAL算法,使得EIGRP协议在路由计算中不可能有环路路由产生,同时路由计…...
Paging 3.0 + Kotlin 分页加载指南
Paging 3.0 是 Android Jetpack 组件中用于高效分页加载数据的现代化方案,结合 Kotlin 协程和 Flow 特性,能够显著简化分页逻辑的实现。以下是完整的实现指南和最佳实践: 一、Paging 3.0 核心优势 内置加载状态管理:自动跟踪加载…...
湖南(源点咨询)市场调研 商业综合体定位调研分享(下篇)
接着中篇,我们就要重点分析一下该地区消费者的特点: 综合来看,本地区还是以中等收入工薪阶层的新市民家庭为主,以亲子关系为家庭核心,居住条件改善、生活向好,渴望公共配套的提升丰富生活质感,…...
vue 中的ref
vue 中的ref vue 中的ref 1. ref ** 的基本作用** 在 Vue 中,ref 是用来获取 DOM 元素或者组件实例的一种方式。对于 <el-form> 组件,通过 ref 可以获取到该表单组件的实例,进而调用表单组件提供的各种方法和访问其属性。 …...
Kotlin 协程 vs RxJava vs 线程池:性能与场景对比
1. 轻量级任务:10,000 个并发延迟操作 假设需要并发执行 10,000 个非阻塞延迟任务(如模拟定时请求): 线程池实现 ExecutorService executor Executors.newFixedThreadPool(64); // 最多 64 线程 List<Future<?>>…...
golang-ErrGroup用法以及源码解读笔记
介绍 ErrGroup可以并发执行多个goroutine,并可以很方便的处理错误 与sync.WaitGroup相比 错误处理 sync.WaitGroup只负责等待goroutine执行完成,而不处理返回值或者错误errgroup.Group目前虽然不能直接处理函数的返回值或错误。但是当goroutine返回错…...