当前位置: 首页 > news >正文

深入解析PyTorch中MultiheadAttention的隐藏参数add_bias_kv与add_zero_attn

关键背景

最近在学习pytorch中的源码尤其是nn.modules下算子的实现,针对activation.pyMultiheadAttention下有两个不常见的参数的使用比较有趣,因为时序领域很少使用这两个参数(add_bias_kvadd_zero_attn),但是其目的似乎很适配时序场景,尽管逻辑上听起来其直接简单,但是还是打算手动推导分析其具体的变换。以熟悉其具体的变换。

参数作用

源码中针对其解释如下:

add_bias_kv: If specified, adds bias to the key and value sequences at dim=0. Default: ``False``.
add_zero_attn: If specified, adds a new batch of zeros to the key and value sequences at dim=1.Default: ``False``.
  • add_bias_kv
    • 描述:当设置 add_bias_kv=True 时,PyTorch 会在每个 attention 计算的key和value前,拼接一个 earnable向量(即bias_k, bias_v),其shape是 (1, batch_size, embed_dim)。这些bias会被视作额外的“位置”,放在序列的开头。
    • 作用:这个机制可以让模型在每个序列前加上一个全局性的learnable token,类似于BERT 的 [CLS] tokenViT(Vision Transformer)的 class token引入统一的上下文引导 token
  • add_zero_attn
    • 描述:意思是,在 每个位置的 key/value 向量中都加上一个额外的“零向量”,并作为一个新元素插入到 batch 的 attention 范围内。
    • 作用:加一个 zero-attention vector 的目的是给模型留一个“什么都不关注”的退路;在 encoder-decoder attention 中,decoder 可以选择性不关注任何输入位置,退回到这个零向量;对某些任务(如语义空洞填充、视觉 patch drop)来说,zero attention 能表示“不存在”或“缺失”的信息源

分析流程

在这里插入图片描述

✅1. 从二维矩阵开始理解

假设我们有一个序列(时序 or 文本),长度是5,模型的维度是8维,即每个token将被嵌入成一个8维的向量,那么基于seq_len = 5embed_dim = 8显然可以得到一个shape为(5,8)的矩阵,使用torch随机生成这样一个矩阵,如下:

import torchseq_len = 5
embed_dim = 8
m = torch.randn(seq_len,embed_dim)print(m.shape)
print(m)

输出如下:

torch.Size([5, 8])
tensor([[-7.4508e-01,  1.1659e+00, -7.0335e-02,  4.3215e-01,  1.3831e-01,-1.6028e+00,  2.6052e+00,  2.9472e-02],[ 6.7109e-01, -1.2629e-01,  1.3738e+00,  7.8396e-01,  1.5244e+00,5.7940e-01, -1.1636e+00,  1.1213e+00],[-3.4683e-01,  3.3295e-01, -9.1225e-02,  4.5248e-01,  1.8235e+00,-2.4852e-01,  1.0417e+00, -1.2556e-01],[-1.0605e+00,  4.5711e-01, -7.9260e-01, -2.0586e+00, -2.5313e-01,-8.0461e-01,  9.3312e-01,  4.7544e-01],[-5.2117e-01,  3.4502e-01,  1.4715e+00,  2.4684e+00,  9.4748e-01,2.0253e-03,  1.0036e+00,  4.8027e-01]])

✅2. 引入 batch 的概念(3D 张量)

一般,我们需要在一次性处理多个序列(多个样本),假设3个序列样本组成一个batch。每个序列的长度仍是5,token的维度为8。那么此时这个张量的形状就变成了:

import torchseq_len = 5
embed_dim = 8
batch_size = 3
q = torch.randn(batch_size, seq_len, embed_dim)
print(q.shape)
print(q)

输出为:

torch.Size([3, 5, 8])
tensor([[[-0.3007, -0.3443,  0.0515,  0.9153,  0.1486,  0.8630, -0.1750,-0.6688],[ 0.1970, -0.8177, -0.0302,  1.1665,  0.3290,  0.6600, -0.7473,-1.2262],[-0.3780,  0.6538,  1.3766,  0.1920, -1.0980,  0.0694,  0.8015,0.3631],[ 1.1727, -0.1484,  1.5107,  1.4208, -0.2864, -1.7283,  0.5781,-1.4435],[ 1.3020, -0.1518, -0.9987,  0.5897, -1.1685,  1.1592,  0.0360,-1.1931]],[[ 1.3530,  0.0892, -1.2635,  1.8082,  1.3397,  1.0009, -1.3071,0.0946],[-0.3749, -1.5674, -0.8663, -1.3531,  0.9437, -1.1769, -1.3152,-1.1854],[ 0.6995,  0.6464, -0.8311,  0.4104,  1.4770, -0.2067,  0.8549,-0.0366],[-0.3462,  1.0118, -1.3090, -1.5885, -0.1143,  0.1957, -1.1694,-0.1317],[-0.0216,  0.7810,  1.6990, -0.2328, -0.0163, -1.5569, -0.9106,-1.5693]],[[ 0.0365, -0.8511, -0.6117, -1.4029, -0.5794,  0.7073,  0.0607,2.2900],[ 1.6539,  0.4874,  1.0456,  0.2727,  1.0852,  1.7963, -0.4513,-0.9612],[-1.4896,  1.8739, -0.3650, -0.0476, -2.5191, -1.4645,  0.5743,0.4616],[-1.2099,  0.3355, -0.8877,  2.6665, -0.6601, -1.2705,  1.0287,-0.6931],[-0.3273,  0.2364, -1.2982, -0.6908,  1.5833, -0.2403,  1.2128,1.4706]]])

我们可以尝试使用transpose转置该3D张量对应的维度,如下:

q1 = q.transpose(0,1)
print(q1.shape)
print(q1)

输出如下:

torch.Size([5, 3, 8])
tensor([[[-0.0687,  0.3209, -0.5212, -0.1787,  0.4720,  1.0013,  0.6243,-1.8285],[-0.6348, -0.4394, -0.1964,  0.2261, -0.1205,  0.4492,  0.9841,-0.4095],[ 0.7714, -0.1087, -0.7359,  0.2492, -0.0391, -0.2462, -0.1695,1.4089]],[[-0.5181, -0.5992,  0.1055,  0.4877,  0.1648,  0.5122, -0.3526,1.7066],[ 1.5172,  1.4660, -0.2405,  2.1547, -0.8794, -1.6543, -2.0169,-0.5331],[ 0.3779,  0.4134,  1.9286,  0.3782,  1.5611, -1.6187,  1.6274,1.0527]],[[ 0.5642, -0.3944, -1.4383, -1.1361,  0.0242,  0.1435,  0.5510,-0.0472],[-1.0935,  0.0820,  0.5193,  0.1174,  0.3282, -1.9772,  0.4186,-0.5007],[-0.0845, -2.0364,  0.1124,  1.7474, -0.3131, -1.4156,  0.4046,-0.3282]],[[-2.4212, -0.4703,  1.5794,  0.8093,  0.9247, -1.4775,  0.4462,0.4256],[-0.0934, -0.2569,  0.4803, -0.3651,  0.7175, -1.0460,  0.9095,0.6421],[ 0.1579,  2.0790, -0.4982,  1.7707, -0.3657,  0.7336, -0.1482,-1.5648]],[[ 2.7056,  2.2962,  0.7005,  0.6427,  0.7578, -0.4191,  0.9064,-0.3934],[ 0.1987,  1.6104,  0.4723,  1.5453,  0.0500, -0.5176, -1.8852,-1.2235],[ 1.2145,  1.7694, -0.1546,  0.3803,  0.0489,  1.0129,  0.0513,-0.6902]]])

实际上,未转置之前是很容易理解的,即将将样本按照batch数进行了聚合,但是转置之后如何直观理解是非常重要的一个事情:

  • 转换前

(batch_size, seq_len, embed_dim)
我们可以把它看成一个“batch_size 个句子”,每个句子有 seq_len 个词,每个词是一个 embed_dim 维的向量。

  • 转换后

现在你可以把它理解成:我们将多个句子按词的位置对齐,从每个 batch 的样本中抽出相同位置的词,堆叠在一起。即第 i 个时间步(即位置 i)下,batch 中所有样本的向量被统一收集起来。

在这里插入图片描述

✅3. 输入到MultiheadAttention中

import torch
import torch.nn as nn# 定义参数
embed_dim = 8
num_heads = 2
seq_len = 5
batch_size = 3# 创建 MultiheadAttention 实例
mha_with_bias = nn.MultiheadAttention(embed_dim=embed_dim, num_heads=num_heads, batch_first=True)# 输入的 query, key, value (shape: seq_len, batch_size, embed_dim)
query = torch.randn(batch_size, seq_len, embed_dim)
key = torch.randn(batch_size, seq_len, embed_dim)
value = torch.randn(batch_size, seq_len, embed_dim)# 计算 attention 输出
out_with_bias, _ = mha_with_bias(query, key, value)# 输出两种情况下的结果
print(out_with_bias.shape)
print(out_with_bias)

输出为

torch.Size([3, 5, 8])
tensor([[[ 0.0749,  0.0814, -0.1367, -0.0314,  0.0061, -0.2369, -0.1453,-0.0241],[-0.0945, -0.0934,  0.0407, -0.2193, -0.2172, -0.1352, -0.0820,-0.1239],[-0.0591, -0.0986,  0.1017, -0.2430, -0.2136, -0.0989, -0.1641,-0.1050],[-0.0588, -0.0747,  0.0355, -0.2210, -0.1803, -0.1326, -0.0864,-0.1240],[-0.1035, -0.0213, -0.0752, -0.1356, -0.1339, -0.1776, -0.0013,-0.1460]],[[-0.0217, -0.0490,  0.2707,  0.2102, -0.0289,  0.2783, -0.2179,0.1797],[-0.1059, -0.0113,  0.2640,  0.3222,  0.0088,  0.3493, -0.2244,0.2725],[-0.0965, -0.0284,  0.4591,  0.2321,  0.0041,  0.3915, -0.2269,0.2789],[-0.0432, -0.0149,  0.5781,  0.2857,  0.0851,  0.5095, -0.2417,0.3853],[-0.3742,  0.0287,  0.2859,  0.4340, -0.0349,  0.4007, -0.2363,0.3838]],[[-0.5256,  0.0713, -0.3210,  0.1768, -0.0383,  0.0495,  0.1960,-0.1594],[-0.4588,  0.1027, -0.4966,  0.0540, -0.0393, -0.1755,  0.3327,-0.2415],[-0.4845,  0.0701, -0.2647,  0.2300, -0.0053,  0.0749,  0.1903,-0.0888],[-0.4795,  0.1241, -0.3832,  0.1589,  0.0214, -0.1044,  0.3101,-0.1343],[-0.4665,  0.1103, -0.3181,  0.2179,  0.0319, -0.0670,  0.3088,-0.0676]]], grad_fn=<TransposeBackward0>)

为什么 PyTorch 使用 (seq_len, batch_size, embed_dim)?这是为了兼容早期的 RNN 接口(nn.RNN, nn.LSTM)以及底层高效的张量操作。可以用 batch_first=True 的方式让维度变成 [batch_size, seq_len, embed_dim],这是更自然的顺序,但默认 MultiheadAttention 期望 [seq_len, batch_size, embed_dim]。

✅4. 分析add_bias_kv

按照上面的理解官方实现中要求[batch_size, seq_len, embed_dim],并且按照之前的解释其在每个 attention 计算的key和value前,拼接一个 learnable向量(即bias_k, bias_v),其shape是 (1, batch_size, embed_dim),这个拼接逻辑如何理解呢?具体的,

  • 其会创建两个可学习的参数向量bias_k和bias_v,且形状为(1,1,embed_dim)
  • 然后在前向传播时,会将这个 bias 向量沿着 batch 维复制为 [batch_size, 1, embed_dim],然后 附加在原始的 key 和 value 张量的序列维 dim=1 上(注意是 seq_len 那一维)
key = torch.cat([key, bias_k.expand(3, 1, 8)], dim=1)
value = torch.cat([value, bias_v.expand(3, 1, 8)], dim=1)

新shape:[seq_len + 1, batch_size, embed_dim]

在这里插入图片描述

✅5. 分析add_zero_attn

add_zero_attn=True 表示在 key 和 value 的序列维(即 seq_len 那一维)前面追加一行全为零的向量。注意query始终不变。即

zero_tensor = torch.zeros(batch_size, 1, embed_dim)
key = torch.cat([zero_tensor, key], dim=1)
value = torch.cat([zero_tensor, value], dim=1)

[seq_len, batch_size + 1, embed_dim]

在这里插入图片描述

✅6.特别注意

  • add_bias_kv 添加的是 bias_k 和 bias_v,这两个是模型的参数,会随着训练学习出有意义的表示(比如代表某类全局特征或辅助 attention 的 anchor 点)。
  • 而 add_zero_attn 加的是一个 固定为 0 的向量,它不会被训练,更多是出于工程目的(例如 decoder 中让 query 有可能对“无意义”的位置分配注意力,从而在 masking 时更稳定)。

相关文章:

深入解析PyTorch中MultiheadAttention的隐藏参数add_bias_kv与add_zero_attn

关键背景 最近在学习pytorch中的源码尤其是nn.modules下算子的实现&#xff0c;针对activation.py下MultiheadAttention下有两个不常见的参数的使用比较有趣&#xff0c;因为时序领域很少使用这两个参数&#xff08;add_bias_kv和add_zero_attn&#xff09;&#xff0c;但是其…...

最大化效率和性能:AKS 中节点池的强大功能

什么是节点池 在 Azure Kubernetes 服务 (AKS) 中&#xff0c;相同配置的节点会被分组到节点池中。这些节点池包含运行应用程序的底层虚拟机。创建 AKS 集群时&#xff0c;您需要定义初始节点数及其大小 (SKU)。随着应用程序需求的变化&#xff0c;您可能需要更改节点池的设置…...

用户态到内核态:Linux信号传递的九重门(一)

1. 信号的认识 1.1. 信号的特点 异步通知&#xff1a;信号是异步的&#xff0c;发送信号的进程无需等待接收进程的响应。预定义事件&#xff1a;每个信号对应一个预定义的事件&#xff08;如终止、中断、段错误等&#xff09;。 轻量级&#xff1a;信号不携带大量数据&#xf…...

c语言第一个小游戏:贪吃蛇小游戏01

hello啊大家好 今天我们用一个小游戏来增强我们的c语言&#xff01; 那就是贪吃蛇 为什么要做一个贪吃蛇小游戏呢&#xff1f; 因为这个小游戏所涉及到的知识有c语言的指针、数组、链表、函数等等可以让我们通过这个游戏来巩固c语言&#xff0c;进一步认识c语言。 一.我们先…...

JAVA EE_网络原理_网络层

晨雾散尽&#xff0c;花影清晰。 ​​​​​​​ ​​​​​​​ ​​​​​​​ ​​​​​​​ ​​​​​​​ ----------陳長生. ❀主页&#xff1a;陳長生.-CSDN博客❀ &#x1f4d5;上一篇&#xff1a;数据库Mysql_联…...

前端性能指标及优化策略——从加载、渲染和交互阶段分别解读详解并以Webpack+Vue项目为例进行解读

按照加载阶段、渲染阶段和交互阶段三个维度进行系统性阐述&#xff1a; 在现代 Web 开发中&#xff0c;性能不再是锦上添花&#xff0c;而是决定用户体验与业务成败的关键因素。为了全面监控与优化网页性能&#xff0c;我们可以将性能指标划分为加载阶段、渲染阶段、和交互阶段…...

Flink 系列之十五 - 高级概念 - 窗口

之前做过数据平台&#xff0c;对于实时数据采集&#xff0c;使用了Flink。现在想想&#xff0c;在数据开发平台中&#xff0c;Flink的身影几乎无处不在&#xff0c;由于之前是边用边学&#xff0c;总体有点混乱&#xff0c;借此空隙&#xff0c;整理一下Flink的内容&#xff0c…...

控制台打印带格式内容

1. 场景 很多软件会在控制台打印带颜色和格式的文字&#xff0c;需要使用转义符实现这个功能。 2. 详细说明 2.1.转义符说明 样式开始&#xff1a;\033[参数1;参数2;参数3m 可以多个参数叠加&#xff0c;若同一类型的参数&#xff08;如字体颜色&#xff09;设置了多个&…...

Linux为啥会重新设置中断请求号与中断向量号之间的关系?

Linux内核重新设置中断请求号&#xff08;IRQ&#xff09;与中断向量号之间的关系&#xff0c;主要出于以下核心原因和设计考量&#xff1a; ​1. 硬件多样性与抽象需求​ ​硬件中断号&#xff08;HW Interrupt ID&#xff09;的差异​ 不同处理器架构的中断控制器&#xff08…...

自然语言处理NLP中的连续词袋(Continuous bag of words,CBOW)方法、优势、作用和程序举例

自然语言处理NLP中的连续词袋&#xff08;Continuous bag of words&#xff0c;CBOW&#xff09;方法、优势、作用和程序举例 目录 自然语言处理NLP中的连续词袋&#xff08;Continuous bag of words&#xff0c;CBOW&#xff09;方法、优势、作用和程序举例一、连续词袋( Cont…...

计算机网络笔记(二十二)——4.4网际控制报文协议ICMP

4.4.1ICMP报文的种类 ICMP&#xff08;Internet Control Message Protocol&#xff09;是IP协议的辅助协议&#xff0c;主要用于传递控制消息、错误报告和诊断信息。其报文分为两大类&#xff1a;查询报文和错误报告报文。 1. 错误报告报文&#xff08;Error Messages&#x…...

【AI论文】作为评判者的感知代理:评估大型语言模型中的高阶社会认知

摘要&#xff1a;评估大型语言模型&#xff08;LLM&#xff09;对人类的理解程度&#xff0c;而不仅仅是文本&#xff0c;仍然是一个开放的挑战。 为了弥合这一差距&#xff0c;我们引入了Sentient Agent作为评判者&#xff08;SAGE&#xff09;&#xff0c;这是一个自动评估框…...

Kubernetes生产实战(二十七):精准追踪Pod数据存储位置

在生产环境中&#xff0c;快速定位Pod数据的物理存储位置是运维人员的基本功。本文将揭秘Kubernetes存储系统的核心原理&#xff0c;并提供一套经过实战检验的定位方法体系。 一、存储架构全景图 K8S存储架构 Pod --> Volume Mount --> PVC --> PV --> Storage P…...

极新携手火山引擎,共探AI时代生态共建的破局点与增长引擎

在生成式AI与行业大模型的双重驱动下&#xff0c;人工智能正以前所未有的速度重构互联网产业生态。从内容创作、用户交互到商业决策&#xff0c;AI技术渗透至产品研发、运营的全链条&#xff0c;推动效率跃升与创新模式变革。然而&#xff0c;面对AI技术迭代的爆发期&#xff0…...

[SIGPIPE 错误] 一个 Linux socket 程序,没有任何报错打印直接退出程序

1. 问题 在编写一个程序的时候&#xff0c;当然程序很复杂&#xff0c;遇到了一个 Linux socket 程序&#xff0c;没有任何报错打印直接退出程序&#xff0c;但是在程序里面我有很多 error log &#xff0c;在程序退出的时候完全没有打印。为了说明问题&#xff0c;我编写了一…...

Qt 界面优化(绘图)

目录 1. 绘图基本概念2. 绘制各种形状2.1 绘制线段2.2 绘制矩形2.3 绘制圆形2.4 绘制文本2.5 设置画笔2.6 设置画刷 3. 绘制图片3.1 绘制简单图片3.2 平移图片3.3 缩放图片3.4 旋转图片 4. 其他设置4.1 移动画家位置4.2 保存/加载画家的状态 5. 特殊的绘图设备5.1 QPixmap5.2 Q…...

AQS(AbstractQueuedSynchronizer)解析

文章目录 一、AQS简介二、核心设计思想2.1 核心设计思想回顾2.2 CLH锁队列简介2.3 AQS对CLH队列的改动及其原因 三、核心组件详解3.1 state 状态变量3.2 同步队列 (FIFO双向链表) 四、核心方法深度解析4.1 获取同步状态 (独占模式) - acquire(int arg)4.2 释放同步状态 (独占模…...

Java并发编程常见问题与陷阱解析

引言 随着计算机硬件技术的飞速发展&#xff0c;多核处理器已经变得普遍&#xff0c;Java并发编程的重要性也日益凸显。然而&#xff0c;多线程编程并非易事&#xff0c;其中充满了许多潜在的问题和陷阱。作为一名Java开发工程师&#xff0c;掌握并发编程的常见问题及其解决方案…...

DEEPPOLAR:通过深度学习发明非线性大核极坐标码(1)

原文&#xff1a;《DEEPPOLAR: Inventing Nonlinear Large-Kernel Polar Codes via Deep Learning》 摘要 信道编码设计的进步是由人类的创造力推动的&#xff0c;而且恰如其分地说&#xff0c;这种进步是零星的。极性码是在Arikan极化核的基础上开发的&#xff0c;代表了编码…...

Java多态详解

Java多态详解 什么是多态&#xff1f; 比如我们说&#xff1a;“驾驶一辆车”&#xff0c;有人开的是自行车&#xff0c;有人开的是摩托车&#xff0c;有人开的是汽车。虽然我们都说“开车”&#xff0c;但“怎么开”是由具体的车类型决定的&#xff1a;“开”是统一的动作&a…...

go程序编译成动态库,使用c进行调用

以下是使用 Go 语言打包成 .so 库并使用 C 语言调用的完整步骤&#xff1a; 1. Go 语言打包成 .so 库 &#xff08;1&#xff09;编写 Go 代码 创建一个 Go 文件&#xff08;如 calculator.go&#xff09;&#xff0c;并定义需要导出的函数。导出的函数名必须以大写字母开头…...

iVX:图形化编程与组件化的强强联合

在数字化浪潮中&#xff0c;软件开发范式正经历着从文本到图形的革命性转变。iVX 作为国产可视化编程领域的领军者&#xff0c;以 “图形化逻辑 组件化架构” 的双重创新&#xff0c;重新定义了软件开发的效率边界。其技术突破不仅体现在开发方式的革新&#xff0c;更通过一系…...

华为配置篇-RSTP/MSTP实验

MSTP 一、简介二、常用命令总结三、实验 一、简介 RSTP&#xff08;快速生成树协议&#xff09;​ RSTP&#xff08;Rapid Spanning Tree Protocol&#xff09;是 STP 的改进版本&#xff0c;基于 ​​IEEE 802.1w 标准​​&#xff0c;核心目标是解决传统 STP 收敛速度慢的问…...

端口号被占用怎么解决

windows环境下端口号被占用怎么解决 win r 快捷键打开cmd输入netstat -ano|findstr 端口号 通过这个命令找到pidtaskkill /pid pid端口号 /t /f 如下图所示 命令解读 netstat 是一个网络统计工具&#xff0c;它可以显示协议统计信息和当前的TCP/IP网络连接。 -a 参数告诉 nets…...

GO语言-导入自定义包

文章目录 1. 项目目录结构2. 创建自定义包3. 初始化模块4. 导入自定义包5. 相对路径导入 在Go语言中导入自定义包需要遵循一定的目录结构和导入规则。以下是详细指南&#xff08;包含两种方式&#xff09;&#xff1a; 1. 项目目录结构 方法1&#xff1a;适用于Go 1.11 &#…...

ES常识5:主分词器、子字段分词器

文章目录 一、主分词器&#xff1a;最基础的文本处理单元主分词器的作用典型主分词器示例 二、其他类型的分词器&#xff1a;解决主分词器的局限性1. 子字段分词器&#xff08;Multi-fields&#xff09;2. 搜索分词器&#xff08;Search Analyzer&#xff09;3. 自定义分词器&a…...

NoSQL数据库技术与应用复习总结【看到最后】

第1章 初识NoSQL 1.1 大数据时代对数据存储的挑战 1.高并发读写需求 2.高效率存储与访问需求 3.高扩展性 1.2 认识NoSQL NoSQL--非关系型、分布式、不提供ACID的数据库设计模式 NoSQL特点 1.易扩展 2.高性能 3.灵活的数据模型 4.高可用 NoSQL拥有一个共同的特点&am…...

单片机-STM32部分:12、I2C

飞书文档https://x509p6c8to.feishu.cn/wiki/MsB7wLebki07eUkAZ1ec12W3nsh 一、简介 IIC协议&#xff0c;又称I2C协议&#xff0c;是由PHILP公司在80年代开发的两线式串行总线&#xff0c;用于连接微控制器及其外围设备&#xff0c;IIC属于半双工同步通信方式。 IIC是一种同步…...

【英语笔记(四)】诠释所有16种英语时态,介绍每种时态下的动词变形!!含有所有时态的的动词变形汇总表格

1 时态的单词构成 1.1 现在 1.1.1 一般现在时态 动词原形动词原形s&#xff08;第三人称单数&#xff09; 1.1.1.1 表达事实 I eat carrots. 我吃胡萝卜&#xff1a;我是吃胡萝卜这种食物的.&#xff08;这个是事实陈述&#xff09; The rabbit eats carrots. 兔子吃胡萝卜…...

【质量管理】什么是过程?

在文章【质量管理】谁是顾客&#xff1f;什么是质量链&#xff1f;-CSDN博客 中我们了解了什么是顾客&#xff0c;顾客不仅仅是企业以外的人&#xff0c;在企业的内部我们也有大大小小的顾客。并且我们了解了什么是质量链&#xff0c;企业内部的各种供给方和客户形成了质量链。…...

效率办公新工具:PDF Reader Pro V5.0功能解析与使用体验

在日常文档处理与数字办公的场景中&#xff0c;PDF 文件依然是主流格式之一。从合同审批、项目文档、财务报表&#xff0c;到技术方案和用户手册&#xff0c;PDF 的编辑、转换、标注、归档需求始终存在。 面对这些需求&#xff0c;越来越多用户希望有一款功能完整、跨平台、智…...

Java对象内存布局和对象头

1、面试题 1&#xff09;说下JUC&#xff0c;AQS的大致流程 CAS自旋锁&#xff0c;是获取不到锁就一直自旋吗&#xff1f; 2&#xff09;CAS和synchronized区别在哪里&#xff0c;为什么CAS好&#xff0c;具体优势在哪里&#xff1f; 3&#xff09;sychro…...

Vue 跨域解决方案及其原理剖析

在现代 Web 开发中&#xff0c;跨域问题是前端开发者经常面临的挑战之一。当使用 Vue.js 构建应用时&#xff0c;跨域请求的处理尤为重要。本文将深入探讨 Vue 解决跨域的多种方法及其背后的原理&#xff0c;帮助开发者更好地理解和应对这一常见问题。 一、跨域问题概述 1. 同…...

TikTok 互动运营干货:AI 助力提升粘性

在 TikTok 运营的众多环节中&#xff0c;与用户的互动是建立紧密联系、提升账号粘性的关键所在。及时且真诚地回复评论和私信&#xff0c;能让用户切实感受到你的关注与尊重&#xff0c;从而极大地增强他们对你的好感与粘性。对于用户提出的问题&#xff0c;要以耐心、专业的态…...

Kids A-Z安卓版:儿童英语启蒙的优质选择

Kids A-Z安卓版 是一款由北美知名分级读物厂商 Learning A-Z 官方推出的英语分级学习应用&#xff0c;也被称为 Raz-Kids app。它专为 K-5 年级的学生设计&#xff0c;提供丰富的英语学习资源和互动学习体验&#xff0c;帮助孩子们在轻松愉快的环境中提升英语能力。通过动画、互…...

接口继承与扩展的使用技巧

在 TypeScript 中&#xff0c;接口继承和扩展是非常强大且灵活的功能&#xff0c;可以帮助我们更高效地管理类型和提高代码的可重用性。接口继承使得一个接口可以从另一个接口继承属性和方法&#xff0c;而接口扩展允许我们通过组合多个接口来构建更复杂的结构。这些特性使得 T…...

【React】Craco 简介

Craco 简介 Craco (Create React App Configuration Override) 是一个用于自定义 Create React App (CRA) 配置的工具&#xff0c;无需 eject&#xff08;弹出&#xff09;项目。 为什么需要 Craco Create React App 虽然提供了零配置的 React 开发体验&#xff0c;但其配置…...

HTML5中的Microdata与历史记录管理详解

Microdata 简介 Microdata 是 HTML5 引入的一种标记方式&#xff0c;用于在网页中嵌入机器可读的语义信息。通过使用 Microdata&#xff0c;开发者可以在 HTML 元素中添加特定的属性&#xff0c;以便搜索引擎和其他工具更好地理解网页内容。 Microdata 的核心属性包括 itemsc…...

UNet网络 图像分割模型学习

UNet 由Ronneberger等人于2015年提出&#xff0c;专门针对医学图像分割任务&#xff0c;解决了早期卷积网络在小样本数据下的效率问题和细节丢失难题。 一 核心创新 1.1对称编码器-解码器结构 实现上下文信息与高分辨率细节的双向融合 如图所示&#xff1a;编码器进行了4步&…...

Babel 深度解析:现代 JavaScript 开发的桥梁

1. 什么是 Babel&#xff1f; Babel 是一个 JavaScript 编译器&#xff08;又称转译器&#xff09;&#xff0c;核心使命是解决 JavaScript 的环境兼容性问题。它允许开发者使用最新的语言特性&#xff08;如 ES6、JSX、TypeScript&#xff09;&#xff0c;同时将代码转换为旧…...

MyBatis源码解读2(2.1、核心对象)

二、MyBatis的核心对象 2.1、核心对象 2.1、MappedStatement MyBatis其实是对JDBC的进一步封装&#xff0c;我们都知道JDBC有几个重要的对象&#xff1a; StatementPrepared StatementCallable StatementResultSet Statement、Prepared Statement、Callable Statement分别…...

03.three官方示例+编辑器+AI快速学习webgl_animation_multiple

本实例主要讲解内容 这个示例展示了Three.js中骨骼动画的高级应用技巧&#xff0c;重点演示了如何使用SkeletonUtils.clone()方法复制模型&#xff0c;并展示了两种不同的骨骼动画管理方式&#xff1a; 独立骨骼模式&#xff1a;每个模型拥有独立的骨骼结构&#xff0c;可播放…...

无锁秒杀系统设计:基于Java的高效实现

引言 在电商促销活动中&#xff0c;秒杀场景是非常常见的。为了确保高并发下的数据一致性、性能以及用户体验&#xff0c;本文将介绍几种不依赖 Redis 实现的无锁秒杀方案&#xff0c;并提供简化后的 Java 代码示例和架构图。 一、基于数据库乐观锁机制 ✅ 实现思路&#xf…...

MyBatis快速入门——实操

默认&#xff1a;电脑搭建好了Maven环境 本次入门实验使用的idea版本&#xff1a;ideaU2022.1 目录 一&#xff1a;前期准备工作 1. 创建一个springboot工程 2. Maven环境配置 3. 在mysql数据库中创建一个user表 4. 编写实体类User 二&#xff1a; 引入MyBatis的相关依赖…...

假如你的项目是springboot+vue怎么解决跨域问题

1. 前端代理&#xff08;开发环境推荐&#xff09; 适用场景&#xff1a;Vue 开发环境调试时&#xff0c;避免直接请求后端接口的跨域问题。 实现步骤&#xff1a; 在 Vue 项目的 vue.config.js 中配置代理&#xff1a; module.exports {devServer: {proxy: {/api: { // 代理…...

OpenResty反向代理

通过在 OpenResty 的配置文件中定义不同的 location 块&#xff0c;将匹配特定 URL 路径的请求转发到不同的后端 FastAPI 应用&#xff08;即使它们运行在不同的端口或甚至是不同的服务器/容器上&#xff09;。 核心思路&#xff1a; 多个 FastAPI 应用实例&#xff1a; 你的每…...

《Effective Python》第1章 Pythonic 思维详解——深入理解 Python 条件表达式(Conditional Expressions)

《Effective Python》第1章 Pythonic 思维详解——深入理解 Python 条件表达式&#xff08;Conditional Expressions&#xff09; 在 Python 中&#xff0c;条件表达式&#xff08;conditional expressions&#xff09;提供了一种简洁的方式来在一行中实现 if/else 的逻辑。它…...

【Typenum】 3 类型位运算(bit.rs)

一、源码 代码定义了一个类型级别的位&#xff08;bit&#xff09;系统&#xff0c;主要用于编译时的类型运算。 //! 类型级比特位实现 //! //! 这些是基础的比特位类型&#xff0c;作为本库中其他数值类型的构建基础 //! //! 已实现的**类型运算符**&#xff1a; //! //! - …...

python:trimesh 用于 STL 文件解析和 3D 操作

python&#xff1a;trimesh 是一个用于处理三维模型的库&#xff0c;支持多种格式的导入导出&#xff0c;比如STL、OBJ等&#xff0c;还包含网格操作、几何计算等功能。 Python Trimesh 库使用指南 安装依赖库 pip install trimesh Downloading trimesh-4.6.8-py3-none-any.w…...

stm32week15

stm32学习 十一.中断 2.NVIC Nested vectored interrupt controller&#xff0c;嵌套向量中断控制器&#xff0c;属于内核(M3/4/7) 中断向量表&#xff1a;定义一块固定的内存&#xff0c;以4字节对齐&#xff0c;存放各个中断服务函数程序的首地址&#xff0c;中断向量表定…...