深入流行推荐引擎3:Spotify音乐推荐系统

news2024/12/22 6:28:56

深入流行推荐引擎3:Spotify音乐推荐系统

  • Spotify音乐推荐系统
    • 通过矩阵分解发现每周(Discover Weekly via Matrix Factorization)
      • Discover Weekly 如何运作?(How Discover Weekly Works?)
      • 矩阵分解(Matrix Factorization)
      • 交替最小二乘法(Alternating Least Squares)
    • 用于音乐发现的 RNN(RNNs for Music Discovery)
    • 使用强化学习的播放列表推荐(Playlist Recommendation Using Reinforcement Learning)
      • 概述(Overview)
      • 世界模型设计(World Model Design)
      • 行动负责人 DQN 方法(Action Head DAN Approach)
  • 总结
  • 参考

互联网彻底改变了人们发现、消费和与音乐互动的方式。摆脱了 DVD、磁带和录音带的麻烦,现在可以通过流媒体平台(例如 Spotify、Amazon Music、Apple Music 等)随时随地收听音乐。

Spotify 在全球拥有超过 2 亿用户,已成为音频流媒体服务的行业领导者。它们已经从音乐扩展到播客和有声读物,吸引了具有不同偏好和兴趣的用户。

Spotify 最先进的音乐推荐引擎,可根据用户的兴趣、偏好和当前心情向用户推荐音乐或播客。 推荐系统在提供良好的用户体验方面发挥了重要作用,这为 Spotify 带来了如此大的成功。

这篇博客将涵盖 Spotify 推荐的几个方面(例如,音乐推荐、播放列表推荐)以及它们在幕后的工作原理。
推荐引擎3 部分系列的最后一节课深入探讨流行音乐推荐引擎 :

  1. 推荐系统基础
  2. 亚马逊产品推荐系统
  3. YouTube 视频推荐系统
  4. Spotify 音乐推荐系统(本文)

Spotify音乐推荐系统

尽管音乐推荐的任务可能感觉类似于电影推荐(正如在 Netflix 推荐系统中学到的那样),但两者的工作方式存在一些差异:

  • 与电影相比,歌曲目录相当大。同一首歌可以有多种变体(例如低保真、混音、慢速、混响、不同的歌手、乐队等)。但是,电影不太可能有变化。
  • 歌曲具有重复的消费模式,因为您可能会更频繁地听自己喜欢的歌曲。然而电影并非如此。
  • 与电影相比,音乐更小众。有些人可能喜欢民谣、1990 年代的歌曲、流行或摇滚,或者某个乐队或歌手。
  • 电影的收视率更为明确。但是对于歌曲反馈隐藏在用户的流模式中。

Spotify 拥有数百万首歌曲、用户口味、流媒体音乐和用户生成的播放列表的数据。现在将研究Spotify 如何使用这些数据源和先进的机器学习技术来解决音乐推荐问题。

通过矩阵分解发现每周(Discover Weekly via Matrix Factorization)

Discover Weekly 如何运作?(How Discover Weekly Works?)

Spotify 的 Discover Weekly是一个算法生成的播放列表,每周一发布,为听众提供定制的、精心策划的音乐推荐。在幕后Discover Weekly使用协作过滤来利用用户收听历史和具有相似历史的用户喜欢的歌曲。回想一下,协作筛选会根据具有相似兴趣的其他用户喜欢的项目向用户推荐项目。

Spotify 还通过将用户经常听的音乐分组来建立品味档案。这些集群不是基于明确的属性(例如,流派、艺术家等),而是基于歌曲的作曲相似性。

除了明确的反馈,如库保存和“从广播中点赞”,Spotify还依靠隐式反馈(例如歌曲重复、跳过歌曲、歌曲点击等)来训练他们的算法。它使用基于矩阵分解的方法,将用户项目评分矩阵分解为两个部分。第一部分根据潜在因素来描述用户,每个因素的权重不同。第二部分描述歌曲,艺术家与用户部分处于同一潜在空间。

矩阵分解(Matrix Factorization)

为了清楚地理解,假设有:

  • 一组 N N N 用户 U = ( u 1 , u 2 , … , u N ) U = (u_1, u_2,\dots,u_N) U=(u1,u2,,uN)
  • 一组 M M M 歌曲项目, I = ( i 1 , i 2 , … , i M ) I = (i_1,i_2,\dots, i_M) I=(i1,i2,,iM)
  • 用户项目观察矩阵 R = ( r u i ) n × m ) R = (r_{ui})_{n \times m}) R=(rui)n×m) 哪里 r u i ≥ 0 r_{ui} \geq 0 rui0 表示用户次数 u u u 与项目交互 i i i

用户-项目观察矩阵的设计取决于问题的性质。与隐性反馈相比可以选择更多地权衡显性反馈。此外,人们可能会选择将较新的用户流的权重高于较旧的流,因为用户的口味可能会随着时间的推移而略有变化。

请注意,矩阵 R型 通常是稀疏的,因为大多数用户只与目录中有限数量的项目进行交互。对于用户-项目组合,其中用户 u u u 尚未与项目交互 i i i r u i r_{ui} rui 设置为零。矩阵分解旨在近似于这些 r u i r_{ui} rui 未知用户-项目组合的值。

该方法分解观察矩阵 R R R 为两个矩阵:
用户矩阵: X N × f = [ x 1 , x 2 , … , x N ] X_{N \times f} = [x_1, x_2,\dots,x_N] XN×f=[x1,x2,,xN],通过未定义的潜在因素描述N个用户中的每一个
项目矩阵: Y M × f = [ y 1 , y 2 , … , y M ] Y_{M \times f} = [y_1, y_2,\dots,y_M] YM×f=[y1,y2,,yM],通过同样未定义的潜在因素描述M歌曲。
换句话说,
R ≈ X Y T R \approx XY^T RXYT
r u i = < x u , y i > r_{ui}=<x_u,y_i> rui=<xu,yi>
其中 < . , . > <.,.> <.,.>表示向量内积运算。

为了学习 X X X Y Y Y 的矩阵,Spotify最小化了未定义的观测值和未定义预测值之间的以下RMSE(均方根误差 Root Mean Square Error)损失
未定义的
m i n x , y ∑ u , i ( r u i − x u T y i − b u − b i ) 2 − λ ( ∑ u ∣ ∣ x u ∣ ∣ 2 + ∑ i ∣ ∣ y i ∣ ∣ 2 ) min_{x,y}\textstyle\sum_{u,i} (r_{ui}-x_u^Ty_i-b_u-b_i)^2-\lambda(\textstyle\sum_{u} ||x_u||^2+\textstyle\sum_{i} ||y_i||^2) minx,yu,i(ruixuTyibubi)2λ(u∣∣xu2+i∣∣yi2)

其中 λ \lambda λ 是控制正则化的超参数: b i b_i bi b u b_u bu 都是项 i i i 和 用户 u u u 的偏差。

交替最小二乘法(Alternating Least Squares)

X X X Y Y Y 的矩阵使用如下交替最小二乘算法进行优化:

  1. 随机初始化 X X X Y Y Y
  2. 修复未定义的项目向量 y i y_i yi ,并为未定义的用户向量 x u x_u xu 求解。取上述损失函数相对于未定义的用户向量 x u x_u xu 的导数,并将其设置为零,这给出
    x u = ( Y T C u Y + λ I ) − 1 Y T R ( u ) x_u=(Y^TC^uY+\lambda I)^{-1}Y^TR(u) xu=(YTCuY+λI)1YTR(u)
    其中 C u C_u Cu 是常数乘法器,undefine是观测矩阵R的未定义行型。
  3. 固定用户向量并求解项目向量(使用与步骤2相同的过程)。取上述损失函数相对于未定义的项向量的导数,并将其设置为零,这给出
    y i = ( X T C i X + λ I ) − 1 X T R ( i ) y_i=(X^TC^iX+\lambda I)^{-1}X^TR(i) yi=(XTCiX+λI)1XTR(i)
    其中 C i C^i Ci 是常数乘法器,$ R ( i ) R(i) R(i) 是观测矩阵R的第i个 i t h i^{th} ith 义列型。
  4. 重复直到收敛。

用于音乐发现的 RNN(RNNs for Music Discovery)

在音乐消费中,用户行为不断变化,可以用不同艺术家和流派的时间轨迹来描述。例如,想象一个用户听了一段时间艺术家的专辑,然后过渡到下一张专辑或同一音乐流派的汇编播放列表。Spotify使用递归神经网络(RNN)来利用用户的收听模式,将用户表示为其物品消费的函数。

RNN是最先进的神经网络,它处理可变长度的时间序列数据来学习丰富的项目表示。像任何神经网络一样,它们可以通过基于梯度的优化来学习。它们已被广泛用于对文本、语音和音频的非线性时间动态进行建模,因此是Spotify音乐发现问题的一个很好的候选者。

通常在 RNN 中,在每个时间步长 t t t、输入 x t x_t xt 用于更新隐藏的表示 h t − 1 h_{t-1} ht1 h t h_t ht 通过非线性映射。 同样,在每个时间步长,RNN 都会产生一个输出 y t y_t yt 作为输入的非线性函数 x t x_t xt 和以前的隐藏状态 h t − 1 h_{t-1} ht1

如何训练 RNN 来预测用户将来可能听的歌曲。主要有3个步骤:

  1. 管道的构建块是歌曲矢量表示,这些表示已经从目录中学习。为了学习这些矢量表示,Spotify 在目录中排名前 N 位的最流行歌曲中使用了 Google 的 Word2vec 套件。

    更具体地说,他们使用具有负采样的连续词袋 (CBoW) 算法。作为 Word2vec 算法的输入,它们采用用户创建的歌曲播放列表。在这种情况下,每个播放列表都被视为歌曲的有序“文档”。 通过以窗口方式扫描所有播放列表,Word2vec 将为每首歌曲学习具有固定维度的分布式矢量表示。

  2. RNN 输出一个味觉向量,它是从用户收听历史中学习的歌曲向量的函数,因此可以被视为用户音乐品味的表示。味觉向量应捕捉聆听行为如何随时间变化。因此RNN 预测用户将来可能会听的歌曲。为了对此进行建模,RNN 首先采用 N N N 特定用户的连续歌曲 u u u 已经听过并尝试预测下一首歌的向量。换言之,

s ^ n + 1 = RNN ( s 1 , s 2 , s 3 , … , s n ) \hat{s}_{n+1} = \text{RNN}(s_1, s_2,s_3,\dots,s_n) s^n+1=RNN(s1,s2,s3,,sn)

其中 s i s_i si 是用户在 i th i^\text{th} ith timestamp 和 s ^ n + 1 \hat{s}_{n+1} s^n+1 是未来时间戳的预测味觉向量 n + 1 n+1 n+1

作为损失函数,它们最小化了预测味觉向量之间的 L2 距离 s ^ n + 1 \hat{s}_{n+1} s^n+1 和未来的歌曲矢量 s n + 1 s_{n+1} sn+1

  1. 这些口味矢量现在可以生成歌曲推荐。由于已经训练了 RNN 来预测与用户未来可能播放的歌曲(以 L2 距离为单位)接近的味觉向量,因此可以在该向量空间中查询附近的歌曲以生成新的歌曲推荐。

为了促进高效采样,Spotify 利用了 Annoy 树,这是一种数据结构,它使用局部敏感的哈希随机投影技术将向量空间迭代划分为多个区域,从而实现近似最近邻查询。

使用强化学习的播放列表推荐(Playlist Recommendation Using Reinforcement Learning)

概述(Overview)

协作过滤方法的一个缺点是,它们依赖于显式或隐式反馈信号来判断用户是否喜欢播放列表。 因此他们往往难以考虑其他重要因素(例如,声学连贯性、聆听会话的背景以及最佳项目序列的存在)。这可能会导致离线指标与用户满意度指标(想要优化的指标)不匹配。

例如,协作过滤可以建议评分较高但包含成人和儿童音乐的混合播放列表,这不会带来良好的用户满意度。因此,播放列表生成是一项艰巨的任务。

强化学习 (RL) 是一个高级机器学习领域,它不需要明确的反馈信号,而是可以通过直接与用户交互来学习。因此,RL代理可以交互并学习重要的播放列表生成方面,以提高用户满意度指标。

RL 问题包括一个由状态、动作空间和奖励以及 RL 代理组成的环境。RL 代理查看环境的当前状态,并根据学习的策略建议操作。然后,环境会根据操作将其当前状态更改为另一种状态。除了更改其状态外,环境还会返回与此操作关联的奖励。然后,RL 代理会消耗此奖励,以优化其策略以获得更高的奖励。

现在,为了将RL应用于播放列表生成,问题陈述应该表述为马尔可夫决策过程,其中:

  • 状态对总结用户侦听会话的上下文信息进行编码
  • 操作空间表示所有可能的播放列表的空间
  • 奖励是期望的用户满意度指标

操作空间 A \mathcal{A} A 是所有可能的播放列表的空间,这在组合上是复杂的。例如,从 1000 个候选曲目池中生成包含 30 首曲目的播放列表会生成一个操作空间,其中大约 1 0 89 10^{89} 1089 可能性,使现成的RL算法不适用。为了解决这个问题,建议一次只播放一首曲目(来自候选池),而不是完整的播放列表。

世界模型设计(World Model Design)

为了准确地学习生成播放列表,RL 代理应该从模拟实际用户收听会话的环境中学习。为此Spotify提出了一种世界模型设计,该设计利用历史数据(例如,曲目特征和收听历史)来模拟过渡函数,该转换函数根据特定动作产生新状态及其奖励。

在模拟实际的用户收听会话时,世界模型还应该能够启动用户会话,跟踪所有收听的曲目,并终止会话。为了预测与操作相关的奖励,世界模型应用了一个经过训练的用户模型,该模型可以准确预测用户对项目(在例子中为音轨)的反应。 这种模型是在通过实验从真实用户那里收集的监督数据上训练的。

训练数据是通过随机随机播放来自各种收听会话的歌曲并收集用户完成的曲目(如果流式传输)的百分比及其在收听会话中的位置来生成的。然后将这些数据与以下数据相结合:

  • 上下文特征: 用户信息(例如,与个人兴趣和过去互动相关的特征)
  • 项目功能: 与用户正在与之交互的内容相关的信息

用户模型采用用户的上下文特征 在 和项目特征 i t i_t it 的轨道 t th t^\text{th} tth 在侦听会话中的位置以预测以下三个用户响应:

  • 完成候选人跟踪
  • 跳过候选人轨道
  • 收听曲目超过特定秒数(先验指定)

从数学上讲,用户模型采用以下形式:

p ( y t ∣ u , i t ) = f ( u , i t ) p(y_t | u,i_t)= f(u, i_t) p(ytu,it)=f(u,it)

f f f 是一种深度神经网络,它采用上下文和项目特征来预测用户响应。然后,每个用户响应都映射到一个奖励,供 RL 代理在训练期间使用。

行动负责人 DQN 方法(Action Head DAN Approach)

候选曲目池会随着时间的推移而不断变化,因为它们取决于用户的收听历史和品味。这使得整个操作空间是动态的。

为了解决这个问题,Spotify 提出了一个 Action Head Deep-Q-Network (AH-DQN) 代理来采取行动 a a a(例如,要推荐的曲目)和当前状态 s s s (即用户监听会话)作为推荐质量的输入和输出 Q ( s , a ) Q(s,a) Q(s,a)

AH-DQN 代理使用深度神经网络来输出推荐质量 Q ( s , a ) Q(s,a) Q(s,a)。根据每个磁道的 Q Q Q 值,智能体选择具有最高值的磁道。环境返回的奖励用于指示操作的好坏,并更新 Q-相应地网络。

总结

Spotify 是领先的音频流媒体平台,提供个性化的音乐和播客推荐。在这篇博客中了解了 Spotify 如何使用各种数据源和机器学习技术来创建不同的推荐(例如,每周发现、播放列表推荐和音乐发现(Discover Weekly, playlist recommendation, and music discovery)。

  • 通过矩阵分解发现每周(Discover Weekly via Matrix Factorization) :Spotify 如何使用矩阵分解创建符合用户口味的每周歌曲播放列表,该矩阵将用户与歌曲交互的大型矩阵分解为较小的用户和歌曲特征矩阵。
  • 用于音乐发现的 RNN(RNNs for Music Discovery) : Spotify 如何使用递归神经网络 (RNN) 来模拟音乐聆听的顺序性质,并生成与用户先前选择相似的新歌曲。
  • 使用强化学习的播放列表推荐(Playlist Recommendation Using Reinforcement Learning : Spotify 如何使用强化学习 (Reinforcement Learing RL) 创建平衡探索和利用的播放列表(即查找用户可能喜欢的新歌曲并播放用户已经喜欢的歌曲)。介绍了世界模型(学习模拟用户行为和偏好的神经网络(simulate the user’s behavior and preferences))和动作头(学习为播放列表选择最佳歌曲的深度 Q 网络 (DQN deep Q-network))的概念。

然而,这只是冰山一角,因为还有更多 Spotify 推荐系统。通过探索各种推荐引擎(例如 Netflix、LinkedIn、Amazon 和 YouTube 推荐系统)的课程深入了解推荐系统。深入了解所使用的技术(例如,文本挖掘、K 最近邻、聚类、矩阵分解和神经网络(text mining, K-nearest neighbor, clustering, matrix factorization, and neural networks)。

参考

  • https://pyimagesearch.com/2023/10/30/spotify-music-recommendation-systems/

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

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

相关文章

读书笔记--从一到无穷大的关键金句和阅读感悟

借着休假&#xff0c;重新研读了十多年前读过的乔治.伽莫夫所著图书《从一到无穷大--ONE TWO THREE...INFINITY》&#xff0c;该书作为20世纪最经典的科普类图书之一&#xff0c;当时读的懵懵懂懂&#xff0c;现在重新阅读又有了不同的感受&#xff0c;再结合过去的科研工作&am…

【Redis】zset常用命令集合间操作内部编码使用场景

文章目录 前置知识列表、集合、有序集合三者的异同点 普通命令ZADDZCARDZCOUNTZRANGEZREVRANGEZRANGEBYSCOREZPOPMAXBZPOPMAXZPOPMINBZPOPMINZRANKZREVRANKZSCOREZREMZREMRANGEBYRANKZREMRANGEBYSCOREZINCRBY 集合之间的操作ZINTERSTOREZUNIONSTORE 命令小结内部编码测试内部编…

iTerm2+oh-my-zsh搭个Mac电脑上好用好看终端

根据苹果网站上介绍&#xff0c;bash是 macOS Mojave 及更早版本中的默认Shell&#xff0c;从 macOS Catalina 开始&#xff0c;zsh(Z shell) 是所有新建用户帐户的默认Shell。 1. 安装Oh my zsh sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzs…

【Hello Go】Go语言异常处理

Go语言异常处理 异常处理error接口panicrecover延时调用错误问题 异常处理 error接口 Go语言引入了一个关于错误处理的标准模式 它是Go语言内建的接口类型 它的定义如下 type error interface {Error() string }Go语言的标准库代码包errors为用户提供了以下方法 package e…

react之基于@reduxjs/toolkit使用react-redux

react之基于reduxjs/toolkit使用react-redux 一、配置基础环境二、使用React Toolkit 创建 counterStore三、为React注入store四、React组件使用store中的数据五、实现效果六、提交action传递参数七、异步状态操作 一、配置基础环境 1.使用cra快速创建一个react项目 npx crea…

前端面试:如何实现并发请求数量控制?

题目&#xff1a;实现一个并发请求函数concurrencyRequest(urls, maxNum) 要求如下&#xff1a; 要求最大并发数 maxNum;每当有一个请求返回&#xff0c;就留下一个空位&#xff0c;可以增加新的请求;所有请求完成后&#xff0c;结果按照 urls 里面的顺序依次打出&#xff1b;…

2024年全网最全的Jmeter+ant+jenkins实现持续集成教程

jmeterantjenkins持续集成 一、下载并配置jmeter 首先下载jmeter工具&#xff0c;并配置好环境变量&#xff1b;参考&#xff1a;https://www.cnblogs.com/YouJeffrey/p/16029894.html jmeter默认保存的是.jtl格式的文件&#xff0c;要设置一下bin/jmeter.properties,文件内容…

警惕.360勒索病毒,您需要知道的预防和恢复方法。

引言&#xff1a; 网络威胁的演变无常&#xff0c;.360勒索病毒作为一种新兴的勒索软件&#xff0c;以其狡猾性备受关注。本文将深入介绍.360勒索病毒的特点&#xff0c;提供解决方案以恢复被其加密的数据&#xff0c;并分享一系列强化网络安全的预防措施。如果您在面对被勒索…

自动驾驶学习笔记(十)——Cyber通信

#Apollo开发者# 学习课程的传送门如下&#xff0c;当您也准备学习自动驾驶时&#xff0c;可以和我一同前往&#xff1a; 《自动驾驶新人之旅》免费课程—> 传送门 《Apollo Beta宣讲和线下沙龙》免费报名—>传送门 文章目录 前言 Cyber通信 编写代码 编译程序 运行…

概念解析 | 网络安全数字孪生(Digital Twin of Cyber Security, DTCS)技术

注1:本文系“概念解析”系列之一,致力于简洁清晰地解释、辨析复杂而专业的概念。本次辨析的概念是:网络安全数字孪生。 概念解析 | 网络安全的“数字镜像” —— 网络安全数字孪生 1. 背景介绍 随着数字化转型进程的深入推进,网络空间安全问题日益凸显。当前的网络安全防护面…

RTD系统

RTD&#xff08;实时派工系统&#xff09;帮助半导体工厂优化派工&#xff0c;提升生产效率&#xff0c;提高设备利用率&#xff0c;降低Lot Cycle Time&#xff0c;RTD分为&#xff1a;WhatNext和WhereNext&#xff0c;解决工厂内部机台下一步跑什么Lot和Lot生产完后去哪里的问…

人类智能的精髓超出了统计概率

处理不确定性好坏的程度是衡量各种智能系统高低的一个重要指标。在处理不确定性时&#xff0c;智能系统需要具备推理、学习和决策的能力&#xff0c;通常使用概率和统计等方法来建模和处理不确定性&#xff0c;以便更好地应对现实世界中的复杂问题。统计概率是基于大量观察和数…

可拖动、可靠边的 popupWindow 实现

0 背景 开发要实现一个可以拖动的圆角小窗&#xff0c;要求松手时&#xff0c;哪边近些靠哪边。并且还规定了拖动范围。样式如下&#xff1a; 1 实现 首先把 PopupWindow 的布局文件 pop.xml 实现 <?xml version"1.0" encoding"utf-8"?> <R…

变周期控制思路

举例&#xff1a;热值调节的过程中&#xff0c;调节周期在偏差较小时&#xff0c;可以设置较大些&#xff0c;调节周期在偏差较大时&#xff0c;可以设置较小些。并且在偏差较大时&#xff0c;立刻进入调节&#xff08;计时器清零&#xff09;。 -350<偏差<600&#xff0…

Windows安装Vmware 虚拟机

目录 一、Vmware 虚拟机介绍 二、Vmware 虚拟机的三种网络模式 2.1桥接模式 2.2仅主机模式 2.3NAT 网络地址转换模式 三、Vmware 虚拟机的安装 一、Vmware 虚拟机介绍 VMware Workstation Pro 是一款可以在个人电脑的操作系统上创建一个完全与主机操作系统隔离的 虚拟机&…

星火模型(Spark)的langchain 实现

星火模型的langchain实现 测试已通过&#xff0c;希望有所帮助。 使用前请先安装环境&#xff1a; pip install githttps://github.com/shell-nlp/spark-ai-python.git注意&#xff1a; 一定要使用上面方式安装spark库&#xff0c;因对官方的库做了改动。官方的库已经长时间不…

十、Linux运行级别

1.基本介绍 运行级别说明&#xff1a; 0&#xff1a;关机 1&#xff1a;单用户【找回丢失密码】 2&#xff1a;多用户状态没有网络服务 【非常少】 3&#xff1a;多用户状态有网络服务 【最多】 4&#xff1a;系统未使用保留给用户 5&#xff1a;图形界面【Linux一启动自动进入…

【Java集合】聊聊Hashmap的哈希函数、扩容、树化

哈希函数 hashmap是开发中常用的一个集合&#xff0c;除了一些基本的属性、put、get等流程&#xff0c;本篇文章主要介绍下哈希函数、扩容、树化的一些细节。 而hash函数就是hashmap的重中之重。 static final int hash(Object key) {int h;return (key null) ? 0 : (h key…

AVL树实现

目录 ​编辑 一&#xff0c;AVL树的概念 二&#xff0c;实现AVL树&#xff08;部分&#xff09; 1.AVL树的节点 2.AVL数的插入 1.当根节点为nullptr时要执行如下代码&#xff1a; 2.当根节点不为nullptr时 1.当parent的_bf变为0时&#xff0c;parent之前的_bf的大小就是…

使用持久卷部署 WordPress 和 MySQL

&#x1f5d3;️实验环境 OS名称Microsoft Windows 11 家庭中文版系统类型x64-based PCDocker版本Docker version 24.0.6, build ed223bcminikube版本v1.32.0 &#x1f587;️创建 kustomization.yaml 你可以通过 kustomization.yaml 中的生成器创建一个 Secret存储密码或密…