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

【DAPM杂谈之一】DAPM作用与内核文档解读

本文主要分析DAPM的设计与实现
内核的版本是:linux-5.15.164,下载链接: Linux内核下载
主要讲解有关于DAPM相关的知识,会给出一些例程并分析内核如何去实现的
/*****************************************************************************************************************/
声明: 本博客内容均由 芯心智库-CSDN博客原创,转载or引用请注明出处,谢谢!
创作不易,如果文章对你有帮助,麻烦点赞 收藏支持~感谢
/*****************************************************************************************************************/

目录

零、本文主要内容

一、DAPM的作用

二、内核文档解读

2.1 Description

2.2 DAPM Widgets

2.2.1 Stream Domain Widgets

2.2.2 Path Domain Widgets

2.2.3 Machine domain Widgets

2.2.4 Codec (BIAS) Domain

2.2.5 一种虚拟的控制方式--Virtual Widgets

2.3 Codec/DSP Widget Interconnections

2.3.1 Machine Widget Interconnections

2.4 Endpoint Widgets

2.5 DAPM Widget Events

三、总结几个重要的知识点


零、本文主要内容

本文主要是介绍一下什么是DAPM,分析其设计出来的目的是什么,并将会解读一下Linux官方对于DAPM是怎么描述的。
为何需要解读Linux文档呢,因为站在巨人的肩膀上才能看得更远,网上大多数资料都是抄袭泛滥,多数都是你引用我,我引用他,他又引用别人...口口相传后实际含义就有了偏差....

一、DAPM的作用

在DAPM的之前,可能需要了解一下kcontrol的概念,你才能知道为何需要推出DAPM了,关于kcontrol可以参考下面的文章(下次有空我也总结一下):
8.声卡驱动05-自己实现alsa驱动-虚拟声卡-kcontrol_8.声卡驱动01-自己实现alsa驱动-虚拟声卡-匹配-CSDN博客
Linux内核4.14版本——alsa框架分析(9)——ASoC(Codec control的创建)_alsa-lib中如何获取设备controls的名字-CSDN博客
Linux系统ALSA DAPM 中的控制(Controls)功能介绍-CSDN博客
我这边总结一下DAPM的作用:
  1. 自动化使能与失能路径:这是DAPM比较kcontrol引入的最大特征。我们知道对于外设,上电和下电的顺序很重要,不恰当的顺序容易引起pop音,如果全部硬件都抽象成kcontrol,那么你就需要手动的安排一下上电或者下电的顺序,但是如果定义成DAPM类型,那么系统会帮你按照一定的顺序进行上下电。
  2. 对用户层透明:DAPM和kcontrol都有的作用,对寄存器等操作进行封装,从而在用户层使用更方便,用户无须了解外设如何控制,只需要执行对应的命令,底层就会配置好外设
  3. 独立性:DAPM和kcontrol都有的作用,其在内核中拥有属于自己的一套电源管理系统,不会与其他电源管理系统冲突
那么你肯定会有疑问,那既然DAPM比kcontrol好这么多,为什么Linux内核不抛弃widget?我认为的原因是有些控制并不需要用到DAPM的自动化特征,比如声音大小的控制。在这些方面,widget更简单轻便可以实现,而DAPM的最大优势在于音频路由的控制方面。你也可以认为DAPM是kcontrol的加强版本!

二、内核文档解读

官网原链接是: 内核文档,网址为: https://www.kernel.org/doc/html/v5.15/sound/soc/dapm.html
文档主要是关于五个方面进行解读:
  1. Description:基本描述与power domains的划分
  2. DAPM Widgets:DAPM Widgets种类的划分、以及各个domains与DAPM Widgets的关系
  3. Codec/DSP Widget Interconnections:Widget如何进行连接,也就是route的相关内容
  4. Endpoint Widgets:端点widget,介绍端点widget的种类,这个端点widget决定一条route是否完整,route两端都是端点widget才能自动上电,这也是自动化上下电的前提
  5. DAPM Widget Events:个别widget支持对特定事件进行处理
这时你可以会有疑问,也就是DAPM Widgets和power domains有什么区别?
其实可以这么理解:
power domains表示一组相关的Widgets,而DAPM Widgets 则是代表具体音频组件(如 ADC、DAC、Mixer 等)的抽象。 他们是包含关系,一组power domains会包含若干个DAPM Widgets。如何知道每个power domains包括哪些DAPM Widgets,可以参考下面的源码:
/linux-5.15.164/include/sound/soc-dapm.h
那么就详细解读一下内核文档的具体内容吧

2.1 Description

下面这段是Linux关于DAPM的介绍以及DAPM会给设备带来什么好处:
Dynamic Audio Power Management (DAPM) is designed to allow portable Linux devices to use the minimum amount of power within the audio subsystem at all times. It is independent of other kernel PM and as such, can easily co-exist with the other PM systems.
DAPM is also completely transparent to all user space applications as all power switching is done within the ASoC core. No code changes or recompiling are required for user space applications. DAPM makes power switching decisions based upon any audio stream (capture/playback) activity and audio mixer settings within the device.
DAPM spans the whole machine. It covers power control within the entire audio subsystem, this includes internal codec power blocks and machine level power systems.
这里讲得特点和第一章节分析DAPM的作用差不多,因为DAPM自动上下电的策略,而不是类似kcontrol那样直接就控制硬件,因此在DAPM第一段话就指出DAPM是可以为设备省电的。
想要真正悟到这句话,还需要结合route和complete的源码来看就会比较直观了(后面文章会细讲),这里你只需要知道, 就算用amixer或者tinymix了DAPM的控件后,设备不是立马上电,需要某些条件满足才能上电
然后官方文档描述了四大domain:
这里你可以细看官方的文档,我总结一下如下:
Codec Bias domain:管理核心编解码器电源 (VREF/VMID),通常在编解码器挂载或挂载移除时处理。
Platform/Machine domain:控制物理输入输出,比如耳机插拔事件。
Path domain:与音频信号路径相关,用户通过混音器配置(如 alsamixer)触发。
Stream domain:控制音频流的启停。也就是ADC跟DAC,对应录音与播放。例如 aplay、arecord。
按照笔者的理解,这里的划分跟ASOC的三大件--codec、platform、machine的划分有点类似

2.2 DAPM Widgets

内核文档这段解释了各种DAPM类型以及他们的含义,我这边也总结一 下:

组件

描述

DAPM Widget具体含义

Mixer

混合多个模拟信号为一个单一模拟信号

用于将多个音频信号组合成一个输出信号,通常用于音量控制或音频混音。

Mux

模拟开关,输出多个输入中的一个

允许选择多个输入信号中的一个进行传输,可以用于不同音频源的切换。

PGA

可编程增益放大器或衰减控件

用于调节音频信号的增益或衰减,可以动态调整音量。

ADC

模拟到数字转换器

将模拟信号转换为数字信号,通常用于将模拟音频输入转换为数字格式。

DAC

数字到模拟转换器

将数字信号转换为模拟信号,用于将数字音频输出转换为模拟输出。

Switch

模拟开关

控制音频信号的传输或切换,通常在信号路径中切换不同的信号源。

Input

编解码器输入引脚

音频输入引脚,用于接收外部信号到编解码器。

Output

编解码器输出引脚

音频输出引脚,用于输出编解码器的音频信号。

Headphone

耳机(和可选插孔)

用于连接耳机输出或耳机插孔,通常是音频输出的最后一步。

Mic

麦克风(和可选插孔)

用于连接麦克风输入或麦克风插孔,捕捉外部声音信号。

Line

线路输入/输出(和可选插孔)

用于接收或发送线路音频信号,可以是音频源或音频输出设备。

Speaker

扬声器

用于将音频信号转换为声波输出的硬件设备。

Supply

其他控件使用的电源或时钟供给控件

提供所需电力或时钟信号给其他控件,如DAC、ADC等。

Regulator

为音频组件提供电力的外部调节器

外部电源调节器,提供稳定的电压和电流供应,确保音频组件正常运行。

Clock

为音频组件提供时钟的外部时钟

提供稳定的时钟信号,确保音频数据的同步传输。

AIF IN

音频接口输入(带TDM槽掩码)

音频接口输入控件,用于接收通过TDM协议传输的音频数据。

AIF OUT

音频接口输出(带TDM槽掩码)

音频接口输出控件,用于发送通过TDM协议传输的音频数据。

Siggen

信号发生器

用于生成特定频率或幅度的测试音频信号,通常用于音频设备的调试。

DAI IN

数字音频接口输入

数字音频输入控件,用于接收数字音频数据。

DAI OUT

数字音频接口输出

数字音频输出控件,用于发送数字音频数据。

DAI Link

两个DAI结构之间的DAI链路

在两个数字音频接口之间建立连接,通常用于实现音频传输。

Pre

特殊的PRE控件(在其他控件之前执行)

特殊类型控件,用于在其他控件之前执行初始化或前置处理。

Post

特殊的POST控件(在其他控件之后执行)

特殊类型控件,用于在其他控件之后执行后置处理或清理工作。

Buffer

DSP中的组件间音频数据缓冲区

用于在DSP内部存储音频数据,在多个组件之间传递音频数据。

Scheduler

DSP内部调度器,负责调度组件/处理流水线工作

控制DSP内部任务的执行顺序,确保音频处理任务按顺序执行。

Effect

执行音频处理效果的控件

用于执行音频效果处理,如回声、混响、均衡等。

SRC

DSP或编解码器内的采样率转换器

用于转换音频信号的采样率,通常用于不同采样率之间的信号适配。

ASRC

DSP或编解码器内的异步采样率转换器

用于异步转换采样率,能够处理源信号和目标信号不同步的情况。

Encoder

将音频数据从一种格式(通常为PCM)编码为另一种通常为压缩格式的控件

对音频数据进行编码处理,将其转换为压缩格式以减小数据大小。

Decoder

将音频数据从压缩格式解码为未压缩格式(如PCM)的控件

对压缩格式的音频数据进行解码处理,恢复为标准未压缩格式(如PCM)。

2.2.1 Stream Domain Widgets

这里是音频流相关的输入输出,内核文档指出了四大类型:
  • ADC (Analog-to-Digital Converter):模拟到数字的转换器,用于将模拟音频信号转换为数字信号。
  • DAC (Digital-to-Analog Converter):数字到模拟的转换器,用于将数字音频信号转换为模拟信号。
  • AIF IN:音频接口输入,通常用于数字音频输入(如 TDM、I2S)。
  • AIF OUT:音频接口输出,用于数字音频输出。
其实就是两组输入输出接口,一组是数字输入输出,一组是模拟输入输出,源码的体现如下:
/linux-5.15.164/include/sound/soc-dapm.h
219行  /* stream domain */

2.2.2 Path Domain Widgets

Path Domain Widgets 负责控制和影响音频信号路径。官方文档没有具体指出这部分包括什么,这里通过下面的源码分析一下:
/linux-5.15.164/include/sound/soc-dapm.h82行  /* path domain */
其实也就是五种,
  • 第一种:PGA,也就是增益放大器,通常用于调节信号的增益或衰减,比如:
#define SND_SOC_DAPM_PGA(wname, wreg, wshift, winvert, wcontrols, wncontrols)
#define SOC_PGA_ARRAY(wname, wreg, wshift, winvert, wcontrols)
#define SND_SOC_DAPM_PGA_E(wname, wreg, wshift, winvert, wcontrols, wncontrols, wevent, wflags)
#define SND_SOC_DAPM_PGA_S(wname, wsubseq, wreg, wshift, winvert, wevent, wflags)

  • 第二种:Mixer,也就是混音器,用于将多个音频输入信号混合成一个输出信号,它能够控制每个输入信号的音量或开关状态。比如:
#define SND_SOC_DAPM_MIXER(wname, wreg, wshift, winvert, wcontrols, wncontrols)
#define SND_SOC_DAPM_MIXER_NAMED_CTL(wname, wreg, wshift, winvert, wcontrols, wncontrols)
#define SOC_MIXER_ARRAY(wname, wreg, wshift, winvert, wcontrols)
#define SOC_MIXER_NAMED_CTL_ARRAY(wname, wreg, wshift, winvert, wcontrols)
#define SND_SOC_DAPM_MIXER_E(wname, wreg, wshift, winvert, wcontrols, wncontrols, wevent, wflags)
  • 第三种,Output Driver,也就是输出驱动,通常用于提供最终输出的信号,它可以驱动扬声器或其他音频输出设备,例如用在DAC后边增强DAC的输出,代码:
#define SND_SOC_DAPM_OUT_DRV(wname, wreg, wshift, winvert, wcontrols, wncontrols)
#define SND_SOC_DAPM_OUT_DRV_E(wname, wreg, wshift, winvert, wcontrols, wncontrols, wevent, wflags)
  • 第四种,Switch,也就是开关,控制音频路径的开关状态,比如:
#define SND_SOC_DAPM_SWITCH(wname, wreg, wshift, winvert, wcontrols)
#define SND_SOC_DAPM_SWITCH_E(wname, wreg, wshift, winvert, wcontrols, wevent, wflags)
  • 第五种,Mux,复用器,用于选择不同的信号源,通常用于多个输入之间的选择。比如:
#define SND_SOC_DAPM_MUX(wname, wreg, wshift, winvert, wcontrols)
#define SND_SOC_DAPM_MUX_E(wname, wreg, wshift, winvert, wcontrols, wevent, wflags)

2.2.3 Machine domain Widgets

这个跟codec domain有点区别,主要体现在 不与特定的 codec 寄存器位关联,更多的是 与硬件接口和物理组件相关。官方指出的有三个类型:
  • Speaker Amp:扬声器放大器
  • Microphone Bias:麦克风偏差
  • Jack connectors:插孔连接器

2.2.4 Codec (BIAS) Domain

codec domain区别于Machine domain,他不直接关联任何硬件 widget,而是通过 codec 的 DAPM 事件处理器来控制。这个事件处理器会在以下两种情况被调用:
  • 当 codec 的电源状态(power state)发生变化时,特别是与音频流(stream)事件相关时。
  • 当内核的电源管理(PM)事件触发时。

2.2.5 一种虚拟的控制方式--Virtual Widgets

Virtual Widgets主要就是一个虚拟的控制,个人感觉是为了代码的可理解性才提出来的,DAPM在有了route的概念后,可以做需要事情了,加上这个Virtual Widgets应该可以做更多的事情(尽管我现在没怎么使用),源码中示例了一个:
SND_SOC_DAPM_MIXER("AC97 Mixer", SND_SOC_DAPM_NOPM, 0, 0, NULL, 0),
SND_SOC_DAPM_NOPM 是一个特殊的标志,表示不进行任何电源管理(No Power Management)。而NULL 和 0表示没有控制项和数量。

2.3 Codec/DSP Widget Interconnections

内核文档这一章节讲得就是DAPM中的一个重要的概念--route了
在内核文档的原文中是这样描述的:
Widgets are connected to each other within the codec, platform and machine by audio paths (called interconnections). 
Each interconnection must be defined in order to create a map of all audio paths between widgets.This is easiest with a diagram of the codec or DSP (and schematic of the machine audio system), 
as it requires joining widgets together via their audio signal paths.
首先给出了interconnections的定义:
  • Widgets 通过音频路径连接在一起,这些路径(audio paths)称为互联(Interconnections),它们定义了音频信号如何从一个widgets传递到另一个widgets。
然后是如何实现上面的概念:
  • with a diagram of the codec or DSP (and schematic of the machine audio system)
也就是通过图表和示意图来表示,那么是何种图表和示意图呢?官方文档也指出是下面这样:
/* output mixer */
{"Output Mixer", "Line Bypass Switch", "Line Input"},
{"Output Mixer", "HiFi Playback Switch", "DAC"},
{"Output Mixer", "Mic Sidetone Switch", "Mic Bias"},
格式如下:
Destination Widget <=== Path Name <=== Source Widget
如果需要路径控制的话,那么中间的“Path Name”可以写成”NULL“。
然后文档最后给出了连接方式和注册的方式:
  • 连接的方式:snd_soc_dapm_connect_input(codec, sink, path, source);
  • 注册的方式:snd_soc_dapm_new_widgets(codec)

2.3.1 Machine Widget Interconnections

这部分跟上文的内容基本一致。这不详细介绍了。

2.4 Endpoint Widgets

这个也就是一个complete path的重要概念,也就是在音频中,应该根据什么进行判断路径已经完整了(如果路径完整了就会开始按照顺序上电)。
这里判断的依据就是Endpoint Widgets。
只有当一条路径的两头都是Endpoint Widgets的时候,才能视为路径已经完整了,在官方的文档中也给我指出了哪些是Endpoint Widgets:
  • Headphone Jack 耳机插孔
  • Internal Speaker 内置扬声器
  • Internal Mic 内置麦克风
  • Mic Jack 麦克风插孔
  • Codec Pins 编解码器引脚
官方文档这里给的是概念内容,如果要追踪到代码中,Endpoint Widgets的类型应该是下面的:
/linux-5.15.164/sound/soc/soc-dapm.c
3618  struct snd_soc_dapm_widget *
3619  snd_soc_dapm_new_control_unlocked(struct snd_soc_dapm_context *dapm,
3620  			 const struct snd_soc_dapm_widget *widget)
关键部分:
  • w->is_ep:通过设置此属性来标识端点类型。端点可以是源(Source)或接收端(Sink)。定义如下:
#define SND_SOC_DAPM_EP_SOURCE SND_SOC_DAPM_DIR_TO_EP(SND_SOC_DAPM_DIR_IN)
#define SND_SOC_DAPM_EP_SINK SND_SOC_DAPM_DIR_TO_EP(SND_SOC_DAPM_DIR_OUT)
总结一下,也就是下面的8种:
Widget ID
Widget Name
Endpoint Type
Description
snd_soc_dapm_mic
Microphone
SND_SOC_DAPM_EP_SOURCE
输入端点,作为音频信号源。
snd_soc_dapm_input
Input
SND_SOC_DAPM_EP_SOURCE
输入端点,作为音频信号源。
snd_soc_dapm_spk
Speaker
SND_SOC_DAPM_EP_SINK
输出端点,作为音频信号接收端。
snd_soc_dapm_hp
Headphone
SND_SOC_DAPM_EP_SINK
输出端点,作为音频信号接收端。
snd_soc_dapm_output
Output
SND_SOC_DAPM_EP_SINK
输出端点,作为音频信号接收端。
snd_soc_dapm_vmid
Virtual Midrail
SND_SOC_DAPM_EP_SOURCE
输入端点,作为音频信号源。
snd_soc_dapm_siggen
Signal Generator
SND_SOC_DAPM_EP_SOURCE
输入端点,作为音频信号源。
snd_soc_dapm_sink
Sink
SND_SOC_DAPM_EP_SINK
输出端点,作为音频信号接收端。
调用的函数在:
dapm_generic_check_power
- is_connected_input_ep()
- is_connected_output_ep()

2.5 DAPM Widget Events

DAPM另外还向我们提供了一些事件,以便我们可以对自己感兴趣的事件可以处理。其实这个很容易理解,就是当系统的状态发生了改变后,DAPM可以根据系统具体改变的内容,进行变化,这里ALSA定义了6种事件,Widget可以根据自己提点去响应这些事件,具体的事件如下:
  • SND_SOC_DAPM_PRE_PMU (0x1): 在 widget 电源打开之前触发。
  • SND_SOC_DAPM_POST_PMU (0x2): 在 widget 电源打开之后触发。
  • SND_SOC_DAPM_PRE_PMD (0x4): 在 widget 电源关闭之前触发。
  • SND_SOC_DAPM_POST_PMD (0x8): 在 widget 电源关闭之后触发。
  • SND_SOC_DAPM_PRE_REG (0x10): 在音频路径设置之前触发。
  • SND_SOC_DAPM_POST_REG (0x20): 在音频路径设置之后触发。
内核文档还给我们举了个例子:
/* turn speaker amplifier on/off depending on use */
static int corgi_amp_event(struct snd_soc_dapm_widget *w, int event)
{gpio_set_value(CORGI_GPIO_APM_ON, SND_SOC_DAPM_EVENT_ON(event));return 0;
}/* corgi machine dapm widgets */
static const struct snd_soc_dapm_widget wm8731_dapm_widgets =SND_SOC_DAPM_SPK("Ext Spk", corgi_amp_event);
  • event 参数是传递的事件类型,SND_SOC_DAPM_EVENT_ON(event) 是用来判断事件类型是否要求设备打开(或关闭)。
  • gpio_set_value(CORGI_GPIO_APM_ON, ...) 是控制GPIO引脚的函数,开关扬声器功放。CORGI_GPIO_APM_ON 是控制扬声器功放电源的GPIO引脚。

三、总结几个重要的知识点

  • DAPM和kcontrol的关系
-可以看做DAPM为kcontrol的加强版本,DAPM具备有了自动使能/失能通路的特点
  • DAPM的种类
-主要是分成四大类:Codec Bias domain、Platform/Machine domain、Path domain、Stream domain。详细内容见本文的第2.2节
  • 如何实现自动使能/失能通路
-抽象出route、Endpoint Widgets, route表明了每个wridget的连接关系,而Endpoint Widgets是头部或者尾部,当连接关系能满足首尾都是Endpoint Widgets,则视为这个通路已经完整,系统会按照预定的顺序上电
  • DAPM提供哪些扩展功能
-提供了6个事件类型,每个Widgets可以去注册相应的事件,随后当事件被满足后,将会调用相应的回调函数

相关文章:

【DAPM杂谈之一】DAPM作用与内核文档解读

本文主要分析DAPM的设计与实现 内核的版本是&#xff1a;linux-5.15.164&#xff0c;下载链接&#xff1a; Linux内核下载 主要讲解有关于DAPM相关的知识&#xff0c;会给出一些例程并分析内核如何去实现的 /****************************************************************…...

计算机网络之---防火墙与入侵检测系统(IDS)

防火墙与入侵检测系统(IDS) 防火墙&#xff08;Firewall&#xff09; 和 入侵检测系统&#xff08;IDS, Intrusion Detection System&#xff09; 都是网络安全的关键组件&#xff0c;但它们的作用、功能和工作方式有所不同。 防火墙 防火墙是网络安全的一种设备或软件&#…...

HTML中meta的用法

学习网络空间安全专业&#xff0c;每个人有每个人的学法和选择。不论他选择什么&#xff0c;哪都是他自己的选择&#xff0c;这就是大多数视频教学的博主教学的步骤都不同原因之一。有人选择丢掉大部分理论直接学习网安&#xff0c;而我&#xff0c;选择了捡起大部分理论学习网…...

前端学习-事件流,事件捕获,事件冒泡以及阻止冒泡以及相应案例(二十八)

目录 前言 事件流与两个阶段说明 说明 事件捕获 目标 说明 事件冒泡 目标 事件冒泡概念 简单理解 阻止冒泡 目标 语法 注意 综合示例代码 总结 前言 梳洗罢&#xff0c;独倚望江楼。过尽千帆皆不是&#xff0c;斜晖脉脉水悠悠。肠断白蘋洲 事件流与两个阶段说明…...

国产OS移植工业物联网OPC-UA协议

国家对于工业互联网、基础软件等关键领域的重视程度不断提升&#xff0c;为工业领域的硬件与软件国产化提供了坚实的政策保障。国产操作系统对工业物联网的一些重要领域的适配支持一直在推进。本次通过国产UOS系统移植测试OPC-UA协议。 1、OPC UA通信协议 OPC UA 协议&#xf…...

第25章 汇编语言--- 信号量与互斥锁

信号量&#xff08;Semaphore&#xff09;和互斥锁&#xff08;Mutex&#xff0c;全称Mutual Exclusion Object&#xff09;是两种用于管理对共享资源的访问的同步机制。它们在多线程或多进程编程中非常重要&#xff0c;可以确保同一时间只有一个线程或进程能够访问特定的资源&…...

写个自己的vue-cli

写个自己的vue-cli 1.插件代码2. 发布流程3. 模板代码讲解3.1 vue2模板的运行流程:3.2 vue3模板的运行流程: 1.插件代码 写一个自己的vue-cli插件 插件地址&#xff1a;插件地址 流程&#xff1a; 实现简单版 vue-cli 步骤文档1. 项目初始化 - 创建项目文件夹 qsl-vue-cli - …...

使用new Vue创建Vue 实例并使用$mount挂载到元素上(包括el选项和$mount区别)

new Vue({...}) 是创建一个新的 Vue 实例的方式。你可以通过传递一个选项对象来配置这个实例。常见的选项包括&#xff1a; •data&#xff1a;定义组件的数据属性。 •el&#xff1a;指定 Vue 实例应该挂载到哪个 DOM 元素上&#xff08;通常是一个选择器字符串&#xff0c;如…...

【理论】测试框架体系TDD、BDD、ATDD、MBT、DDT介绍

一、测试框架是什么 测试框架是一组用于创建和设计测试用例的指南或规则。框架由旨在帮助 QA 专业人员更有效地测试的实践和工具的组合组成。 这些指南可能包括编码标准、测试数据处理方法、对象存储库、存储测试结果的过程或有关如何访问外部资源的信息。 A testing framewo…...

机器学习全流程解析:数据导入到服务上线全阶段介绍

目录 1. 数据导入 2. 数据预处理 3. 超参数搜索与优化 4. 模型训练 5. 模型评估 6. 模型压缩与优化 7. 模型注册与版本管理 8. 服务上线与部署 总结 1. 数据导入 数据源&#xff1a;数据库、文件系统、API等。数据格式&#xff1a;CSV、JSON、SQL 数据库表、Parquet …...

shell脚本练习

1、shell 脚本写出检测 /tmp/size.log 文件如果存在显示它的内容&#xff0c;不存在则创建一个文件将创建时间写入。 if [ -f /tmp/size.log ];thencat /tmp/size.logelsestat exist.sh | awk -F: "NR5" > /tmp/size.logfi ​ 2、写一个 shel1 脚本,实现批量添加…...

金山WPS Android面试题及参考答案

说说你所知道的所有集合?并阐述其内部实现。 在 Android 开发(Java 语言基础上)中有多种集合。 首先是 List 集合,主要包括 ArrayList 和 LinkedList。 ArrayList 是基于数组实现的动态数组。它的内部有一个数组来存储元素,当添加元素时,如果数组容量不够,会进行扩容操作…...

分类模型为什么使用交叉熵作为损失函数

推导过程 让推理更有体感&#xff0c;进行下面假设&#xff1a; 假设要对猫、狗进行图片识别分类假设模型输出 y y y&#xff0c;是一个几率&#xff0c;表示是猫的概率 训练资料如下&#xff1a; x n x^n xn类别 y ^ n \widehat{y}^n y ​n x 1 x^1 x1猫1 x 2 x^2 x2猫1 x …...

高等数学学习笔记 ☞ 单调性、凸凹性、极值、最值、曲率

1. 单调性 1. 单调性定义&#xff1a;设函数在区间上有定义&#xff0c;对于区间上任意两点&#xff0c;若&#xff1a; ①&#xff1a;当时&#xff0c;恒有&#xff0c;则称函数在区间上单调递增。 ②&#xff1a;当时&#xff0c;恒有&#xff0c;则称函数在区间上单调递减…...

【操作系统】详解操作系统及其结构

考察频率难度40%--60%⭐⭐ 这又是一类面试考察题&#xff0c;是关于操作系统的一些概念问题&#xff0c;很少会单独拎出来作为一个问题进行提问&#xff0c;但却是必须要掌握的。因为如果这个你不会&#xff0c;其他的问题就已经没有回答的必要了。 什么是操作系统&#xff1…...

primitive 的 Appearance编写着色器材质

import { nextTick, onMounted, ref } from vue import * as Cesium from cesium import gsap from gsaponMounted(() > { ... })// 1、创建矩形几何体&#xff0c;Cesium.RectangleGeometry&#xff1a;几何体&#xff0c;Rectangle&#xff1a;矩形 let rectGeometry new…...

自动化测试框架搭建-接口数据结构设计

目的 确认数据库如何保存接口数据&#xff0c;既有扩展性&#xff0c;数据又全又好用 根据用途设计数据库字段 区分环境&#xff1a;可以明确当前接口自动化用例&#xff0c;是在哪个环境需要执行的 模块&#xff1a;微服务架构&#xff0c;不同测试同学负责不同的模块&…...

Python自学 - 使用自定义异常

<< 返回目录 1 Python自学 - 使用自定义异常 在Python中&#xff0c; 不仅可以使用内置异常&#xff0c;用户还可以创建自己的异常。自定义异常需要继承自Exception类或其子类&#xff0c;如下是一个自定义异常示例&#xff1a; 示例1&#xff1a;一个简单的自定义异常…...

微信小程序-Docker+Nginx环境配置业务域名验证文件

在实际开发或运维工作中&#xff0c;我们时常需要在 Nginx 部署的服务器上提供一个特定的静态文件&#xff0c;用于域名验证或第三方平台验证。若此时使用 Docker 容器部署了 Nginx&#xff0c;就需要将该验证文件正确地映射&#xff08;挂载&#xff09;到容器中&#xff0c;并…...

“AI智能服务平台系统,让生活更便捷、更智能

大家好&#xff0c;我是资深产品经理老王&#xff0c;今天咱们来聊聊一个让生活变得越来越方便的高科技产品——AI智能服务平台系统。这个系统可是现代服务业的一颗璀璨明珠&#xff0c;它究竟有哪些魅力呢&#xff1f;下面我就跟大家伙儿闲聊一下。 一、什么是AI智能服务平台系…...

【PPTist】插入形状、插入图片、插入图表

一、插入形状 插入形状有两种情况&#xff0c;一种是插入固定的形状&#xff0c; 一种是插入自定义的形状。 插入固定的形状时&#xff0c;跟上一篇文章 绘制文本框 是一样一样的&#xff0c;都是调用的 mainStore.setCreatingElement() 方法&#xff0c;只不多传的类型不一…...

云集电商:数据库的分布式升级实践|OceanBase案例

电商行业对数据库有哪些需求 云集电商作为一家传统电商企业&#xff0c;业务涵盖了美妆个护、服饰、水果生鲜、健康保健等多个领域&#xff0c;在创立四年后在纳斯达克上市&#xff08;股票代码&#xff1a;YJ&#xff09;。与京东、淘宝、拼多多等电商平台不同&#xff0c;云…...

OOM排查思路

K8S 容器的云原生生态&#xff0c;改变了服务的交付方式&#xff0c;自愈能力和自动扩缩等功能简直不要太好用。 有好的地方咱要夸&#xff0c;不好的地方咱也要说&#xff0c;真正的业务是部署于容器内部&#xff0c;而容器之外&#xff0c;又有一逻辑层 Pod 。 对于容器和…...

Q_OBJECT宏报错的问题

在Qt中继承QObject&#xff0c;并且加上Q_OBJECT宏&#xff0c;有时候会报错&#xff0c;比如我的错误&#xff1a; error: debug/httpmgr.o:httpmgr.cpp:(.rdata$.refptr._ZTV7HttpMgr[.refptr._ZTV7HttpMgr]0x0): undefined reference to vtable for HttpMgr 意思是没有虚…...

iOS - 关联对象

详细总结 Objective-C 的关联对象功能&#xff1a; 1. 基本使用 // 1. 设置关联对象 objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy);// 2. 获取关联对象 id objc_getAssociatedObject(id object, const void *key);// 3. …...

Linux之进程

Linux之进程 一.进程进程之形ps命令进程状态特殊进程孤儿进程守护进程 进程创建之创建子进程进程特性优先级进程切换&#xff08;分时操作系统&#xff09; 二.环境变量三.进程地址空间四.进程终止&进程等待五.进程替换六.自定义shell 本篇博客希望简略的介绍进程&#xff…...

数据库事务

一 事务的概念 为什么要有事务&#xff0c;我们先前没学事务&#xff0c;也能写sql语句&#xff0c;事务的意义是什么? 由来: 是为了服务应用层开发&#xff0c;降低开发难度。假如没有事务&#xff0c;那我们身为开发人员&#xff0c;要处理转账需求&#xff0c;此时一定是有…...

Python statistics 模块

在数据分析和科学计算中&#xff0c;统计学是一个非常重要的工具。 Python 提供了一个内置的 statistics 模块&#xff0c;专门用于处理基本的统计计算。本文将详细介绍 statistics 模块的功能和使用方法&#xff0c;帮助初学者快速掌握如何使用这个模块进行基本的统计分析。 …...

AI知识-TF-IDF技术(Term Frequency-Inverse Document Frequency)

摘要 TF-IDF&#xff08;Term Frequency-Inverse Document Frequency&#xff09;是一种常见的统计方法&#xff0c;用于评估一个词对于一个文档集或一个语料库中的其中一份文档的重要性。本文将全面阐述TF-IDF的通俗理解、技术原理、应用场景&#xff0c;并做以总结。 通俗理…...

spring cloud的核心模块有哪些

Spring Cloud 的核心模块就像一套精心设计的工具箱&#xff0c;每个模块都扮演着特定的角色&#xff0c;共同构建起微服务架构的坚实基础。 1. Spring Cloud Netflix&#xff08;部分组件已迁移或弃用&#xff0c;但仍是理解 Spring Cloud 的重要参考&#xff09;&#xff1a; …...

java_将数据存入elasticsearch进行高效搜索

使用技术简介&#xff1a; (1) 使用Nginx实现反向代理&#xff0c;使前端可以调用多个微服务 (2) 使用nacos将多个服务管理关联起来 (3) 将数据存入elasticsearch进行高效搜索 (4) 使用消息队列rabbitmq进行消息的传递 (5) 使用 openfeign 进行多个服务之间的api调用 参…...

RAG中的文本切分策略详解

RAG中的文本切分策略详解 1. 选择RAG中的文本切分策略 1.1 不同的文本切分策略 1. CharacterTextSplitter - 这是最简单的方法。它默认基于字符(默认为"")来切割,并且通过字符的数量来衡量块的长度 2. RecursiveCharacterTextSplitter - 基于字符列表拆分文本。 …...

1-1 电场基本概念

目录&#xff1a; 目录 目录&#xff1a; 1.0 电荷守恒定律 2.0 互斥与相吸 3.0 电场的概念 4.0 库伦定律 5.0 矢量的概念 1.0 电荷守恒定律 电荷守恒定律是物理学中的一个基本原理&#xff0c;它指出在一个封闭系统内&#xff0c;电荷的总量是保持不变的。这意味着电荷既…...

SpringBoot初始化执行自定义接口

SpringBoot初始化执行自定义接口 直接加载接口的方法上即可 PostConstructpublic void init() {//加载初始化数据}PostConstruct‌是一个在Java EE 5规范中引入的注解&#xff0c;用于标记在依赖注入完成后需要执行的方法。这个注解定义在javax.annotation包中&#xff0c;而不…...

【Ubuntu与Linux操作系统:一、Ubuntu安装与基本使用】

第1章 Ubuntu安装与基本使用 1.1 Linux与Ubuntu Linux是一种开源、类Unix操作系统内核&#xff0c;拥有高稳定性和强大的网络功能。由于其开源性和灵活性&#xff0c;Linux被广泛应用于服务器、嵌入式设备以及桌面环境中。 Ubuntu是基于Debian的一个流行Linux发行版&#xf…...

C++大端小端判断方法

文章目录 大端小端定义判断方法方法一&#xff1a;利用联合体&#xff08;Union&#xff09;特性判断方法二&#xff1a;通过指针类型转换判断方法三&#xff1a;利用位运算与移位操作判断方法四&#xff1a;使用系统提供的字节序相关宏&#xff08;特定平台支持&#xff09; 联…...

【IO编程】标准IO和文件IO的对比

标准 I/O 和 文件 I/O 是两种常见的输入输出操作方式。它们的核心功能都是处理数据流&#xff0c;但使用场景和实现方式有所不同&#xff0c;适用于不同的需求。 标准 I/O 标准 I/O 是指与标准输入、标准输出和标准错误流&#xff08;分别为 stdin、stdout 和 stderr&#xf…...

C#范围表达式,模式匹配,逆变和协变--11

目录 一.范围表达式 1.概述 2.语法 3.代码示例 4.实现原理 5.应用场景 二.模式匹配 1.概述 2.核心概念 3.常用模式类型 4.Switch表达式 5.使用示例 6.优势 三.逆变和协变 1.概述 2.泛型类型参数的变性 3.协变示例 4.逆变示例 5.注意事项 6.应用场景 总结 一…...

矩阵求逆的几种方式

矩阵求逆的几种方式&#xff08;以二阶为例&#xff09; 矩阵求逆的方法有多种&#xff0c;以下是常用的几种方式总结&#xff1a; 1. 行列式公式法 这是最常见的方法&#xff0c;适用于 2 2 2 \times 2 22矩阵。 对于矩阵&#xff1a; Φ [ a b c d ] , \Phi \begin{bma…...

全新市场阶段, Plume 生态不断壮大的 RWAfi 版图

加密市场在 2024 年迎来了新的里程碑。BTC 不仅成功推出 ETF&#xff0c;以 BTC 为代表的主流加密货币还在一系列传统金融机构的推动下逐步与主流金融市场接轨。与此同时&#xff0c;随着特朗普成功当选下一任美国总统&#xff0c;他承诺推出一系列友好的加密政策&#xff0c;并…...

HTTPS SSL/TLS 工作流程

目录 一、HTTP/HTTPS 简介1、HTTP协议相关内容2、HTTPS协议3、HTTP版本差异&#xff1a; 二、HTTPS 协议工作流程解析1. 客户端请求 SSL 握手2. 服务端接收 SSL 握手连接3. TLS 握手中的密钥协商4. HTTP 数据的加密与解密5. 安全性保障 三、HTTPS 协议的相关知识拓展1. TLS 与 …...

基于异步IO的io_uring

基于异步IO的io_uring 1. io_uring的实现原理 io_uring使用了一种异步IO机制&#xff0c;它通过一对环形缓冲区(ring buffer)实现用户态于内核态之间的高效通信&#xff0c;用户只需将IO请求放入提交队列&#xff0c;当内核完成IO请求时&#xff0c;会将结果放入完成队列&…...

【redis】centos7下安装redis7

在CentOS 7下安装Redis7可以通过以下两种方法实现&#xff1a;手动编译安装和使用YUM进行安装。 CentOS 7系统的环境和版本&#xff1a; $ cat /etc/centos-release CentOS Linux release 7.9.2009 (Core)手动编译安装 参考官方文档&#xff1a;https://redis.io/docs/lates…...

信息系统项目管理-采购管理-采购清单示例

序号类别产品/服务名称规格/功能描述数量备注1硬件服务器高性能处理器&#xff0c;大容量存储10HP、DELL2网络设备高速路由器和交换机10华为3工作站多核处理器&#xff0c;高分辨率显示器25国产设备4移动检查设备手持式移动检查仪&#xff0c;可连接云平台30国产设备5打印机和扫…...

python 代码使用 DeepXDE 库实现了一个求解二维非线性偏微分方程(PDE)的功能

import deepxde as dde import numpy as np import matplotlib.pyplot as plt import tensorflow as tf# 设置时空计算域 Lx 1 # x 范围从 0 到 1 Ly 1 # y 范围从 0 到 1 Lt 0.05 # t 范围从 0 到 0.05 geom dde.geometry.Rectangle([0, 0], [Lx, Ly]) # 空间域 timed…...

后端技术选型 sa-token校验学习 下 结合项目学习 后端鉴权

目录 后端注册拦截器 实现对 WebMvcConfigurer 接口的类实现 静态变量 方法重写 注册 Spring Framework拦截器 Sa-Token中SaServletFilter拦截器 思考 为什么使用两个拦截器 1. Spring Framework 拦截器 2. SaServletFilter 为什么要注册两个拦截器&#xff1f; 总结 …...

继承(8)

大家好&#xff0c;今天我们来学习一下继承方式相关的知识&#xff0c;有助于我们对java的继承有更深的了解&#xff0c;话不多说&#xff0c;来看。 1.10 继承方式 在现实生活中,事物之间的关系是非常复杂,灵活多样。 Java中支持以下几种继承方式: 单继承&#xff1a; 多层…...

深度学习-图神经网络-超图概念及在Hyper-YOLO的应用(小白也看懂)

为什么需要超图&#xff1f; 在一个复杂系统中&#xff0c;某些节点&#xff08;实体&#xff09;之间的互动可能不是仅限于两个节点之间的关系&#xff0c;而是多个节点同时参与的更复杂的关系&#xff08;超边&#xff09;。简单说就是为了更好的描述事物之间的关系&#xf…...

django基于Python的校园个人闲置物品换购平台

Django 基于 Python 的校园个人闲置物品换购平台 一、平台概述 Django 基于 Python 的校园个人闲置物品换购平台是专为校园师生打造的一个便捷、环保且充满活力的线上交易场所。它借助 Django 这一强大的 Python Web 开发框架&#xff0c;整合了校园内丰富的闲置物品资源&…...

opencv的NLM去噪算法

NLM&#xff08;Non-Local Means&#xff09;去噪算法是一种基于图像块&#xff08;patch&#xff09;相似性的去噪方法。其基本原理是&#xff1a; 图像块相似性&#xff1a;算法首先定义了一个搜索窗口&#xff08;search window&#xff09;&#xff0c;然后在该窗口内寻找…...