写点什么

阿里定向广告 CTR 模型最新突破:基于搜索的超长用户行为建模范式

  • 2020-07-02
  • 本文字数:10554 字

    阅读完需:约 35 分钟

阿里定向广告CTR模型最新突破:基于搜索的超长用户行为建模范式

对用户沉淀的海量历史行为数据进行充分的理解和学习,是电商、信息流、短视频推荐这类强用户行为反馈驱动的应用中,近几年技术研发的关键方向,尤其在 CTR 模型这个领域,更是关键的胜负手。


以淘宝为例,大量用户在网站上沉淀了长达数年甚至十几年的历史行为数据:平均每个用户每年产生的点击量超过 10000,更不用提其中高频用户的活跃行为。然而,如何建模这种超长行为序列的数据,学术界和工业界都还在早期摸索阶段。传统的如 LSTM、Transformer 等序列建模的技术,普遍适用于序列数据长度在 100 以内的情况,当序列长度提高一个数量级达到 1000 以上时,就会存在建模困难。此外,即使离线模型能够处理,如何将模型部署到实际生产系统,在时延和吞吐上都达到工业级标准,更是极具挑战的难题。18 年我们团队研发上线、19 年在 KDD 上披露的 MIMN[1],是业界首个处理超长行为序列的工业级解决方案,其提出了一套能够对长达 1000 长度的行为序列数据进行训练和在线 serving 的整体解决方案。然而,MIMN 算法基于的是 memory network 算法,在处理更大规模的序列数据时,容易被数据的噪声干扰、效果很不理想。


2019 年,我们从一个全新的视角来思考这个难题,提出并实现了一套基于搜索范式的超长用户行为建模新方法。跟以往建模考虑如何提取有效的模式拟合整个样本的分布不同,考虑到每个用户的数据足够的丰富,我们提出“一人一世界”的全新建模理念:将每个用户的 life-long 行为数据构建成可以被高效检索的索引库,在做预估任务时将候选的 item 信息作为 Query 来对用户的历史行为库做搜索,获取和此 item 相关的信息来辅助预估。这样每个用户私有的行为索引库就类似其大脑里面存储的记忆,任何一次预测就是访问记忆做决策的过程。我们将这个模型命名为 Search-based user Interest Model(SIM),用于解决工业级应用大规模的用户行为建模的挑战。在我们实际的线上系统中,SIM 处理的用户最长行为序列长度达到了 54000,是过去 SOTA 的 54 倍,且这个序列长度可以随需要进一步扩充。2019 年底,SIM 正式上线并取得了显著效果。目前 SIM 模型已经部署到阿里定向展示广告各个主要的业务线,成为新一代主模型。

为什么我们持续投入探索用户的长期行为建模问题?

互联网的世界蓬勃发展,用户每时每刻都在和互联网世界进行交互,这些交互行为是用户意愿的表达,是用户的决策。用户的行为数据价值巨大,孕育了多样的应用和研究,推动了不同领域的技术飞速的发展。比如在淘宝这样一个电商场景,我们的许多应用都是基于用户的行为数据所研发的,如推荐、计算广告、搜索等。



图一:左图展示了用户行为长度和用户行为天数的关系;右图展示了我们利用这些数据给推荐场景离线模型带来的提升,随着引入更多的数据,离线提升越大。


数据让电商给用户带来了完全不同的体验,淘宝拥有用户从初入淘宝开始 life-long 的行为数据。通过这些数据,推荐系统可以推测用户的兴趣,给每个用户个性化的体验,给用户展现其可能感兴趣的商品,极大的增加了用户在逛淘宝过程中的信息获取效率。如图一所示,我们引入更丰富的用户数据,对于用户点击行为预估将会更为准确。


但是电商也有其困境,和传统的线下购物相比,电商和用户的交互过程是局部的,收集到的数据偏向于决策结果,是一种局部观测数据。想象一下线下的购物情景,用户可以和销售人员交互,交互的信息不仅仅局限于对某个商品的点击、购买与否,还包括一些与用户个人兴趣、喜好、购物目的、预算等决策逻辑相关的丰富信息。


在电商场景,劣势是我们收集到的数据大部分仅仅是最终的决策结果,优势是相比线下的情景可以记录这个用户 life-long 的数据。推荐系统需要根据用户的行为数据去建模和推测用户潜在的兴趣、喜好、目的等抽象信息,进一步的给用户个性化的推荐结果。



图二:在丰富的用户行为中,目前我们模型只能看到用户的部分行为,可能会导致预估不准确。


过去大部分的推荐系统使用的都是用户局部数据,更具体的是用户短期数据,如淘宝用户的平均 life-long 行为序列可能长达数万,过去的算法使用的行为数据长度却普遍只有几十、几百。如图二所示,用户的点击行为非常丰富,但是我们模型仅仅只能捕捉到用户最近的几十个行为。这样的做法没有真正发挥线上推荐系统的优势,本就是局部观测数据的行为数据仅仅只有很小一部分被使用会带来许多问题:


  1. 短期的行为不能代表用户,基于此的建模让用户很容易被近期热点和大多数所代表。

  2. 基于短期行为的算法无法建模用户长期以来坚持的兴趣,如品质、风格方面长期才能反映的喜好。

  3. 推荐系统大多数都是 data-driven 的,本就会形成数据闭环,而基于短期行为的推荐系统,可能会将自己的“视野”局限在一个非常窄的范围内。

长期行为建模在算法 &工业实践的难点

前文中我们分析了长期行为建模的重要性,事实上无论是在工业界还是研究界,长期行为建模都吸引了大量的注意,但真正落实到业界应用的进展还比较有限。这确实是一个挑战极大的问题,当我们将建模的行为数据从过去短期的 100 量级扩充到 life-long 如接近 100000 量级,无论是在算法建模层面还是在系统实现上,行为建模都面临新的问题。同时算法建模和系统实现的问题又会耦合在一起,让这个问题挑战重重却又魅力无穷。


为了更简单和清晰地描述问题,后文我们将把问题的讨论范围缩小到 CTR 预估问题上。

系统实现的挑战:

真实系统中 CTR 预估需要样本准备、训练、实时预估服务三个模块来提供完整的系统服务能力。行为序列长度的增加会带来样本数据的膨胀,意味着存储和训练计算开销的增长。具体来说,如果我们的核心数据和建模计算模块都在行为序列上,那么行为序列从过去常见的 100 量级到 100000 量级将带来约一千倍的存储和离线计算增长。当然实际情况会少一些,但也会是一个很夸张的数字。这会让未来系统的日常维护、更新迭代成本急剧提高。


相比于样本准备和训练部分的挑战,在线实时预估计算服务是一个更大的难题。不同于样本准备和训练仅仅面对的是处理量的问题,在线服务还受很强的时间约束,它需要具备高并发且低延时的处理能力。用户的请求发起后,要求在极短的时间内完成响应,否则便会降低用户的体验,甚至错过这次展示的机会。


比如在我们的系统里如图三所示,CTR 预估模块需要对每次请求在几十 ms 内完成对几百上千的候选集的 CTR 预估计算,而流量高峰时,可能我们需要在短时间内服务几百上千万的用户请求。普遍的系统设计下,在线 CTR 预估服务需要完成单条请求数据构造、模型参数获取、模型计算等几个串行的过程。整个过程涉及在线存储、通信、计算等资源需求。而传统的涉及精细用户建模的 CTR 预估模型,如 DIN/DIEN[2,3]等,其存储、通信、计算资源的开销几乎都随用户行为序列长度线性增长。在经过了非常仔细的系统优化以及设计后,DIN[3]和 DIEN[2]能在线处理 150 左右的序列长度。但如果我们希望建模用户 life-long 的行为序列,如 100000 量级,在现有的方案下,这是一个遥不可及的目标。



图三:目前我们在线的 RTP 系统架构。


算法建模的挑战:

超长的行为序列建模的算法设计也是一个非常困难的问题。想象一下,我们对原始的 life-long 行为序列数据直接做建模,系统上,因为数据规模是不可接受的。很自然的,我们可以考虑预先对行为序列做一些信息压缩,比如做一些降维 encode。Memory network 或者说 NTM 看起来非常适合处理这样的问题。


然而实践过程中,却有诸多问题:


  1. 动态数据分布捕获问题和一些静态数据研究问题不一样。工业界推荐系统要处理的问题并不是在一个固定的数据上去拟合一个确定的 ground truth。真实世界的系统中,CTR 预估面对的数据分布是不断变化的,我们需要不停根据最新的数据来更新模型的参数,让模型能适应近期数据的分布。这个需求和 encode 的思路存在天然的冲突。对行为序列的 encode 依赖哪个版本的参数?参数更新后需不需要去重新对行为序列进行 encode?

  2. 信息遗忘问题。如果模型拟合的目标是当前样本,对当前样本有效的 encode 信息,这个 encode 结果并不一定对未来的样本有效,如何让模型能找到对用户 life-long 的行为序列进行 encode 并长期持续有效的方法?

  3. 建模噪声问题。受限于实际系统使用,encode 的空间复杂度是有限的,源于问题 1 和问题 2,又会有新的问题,我们怎么在有限的 encode 空间内去建模用户 life-long 的行为序列,表达用户多个方面的兴趣。将用户的行为序列 encode 为一个固定的向量(或者矩阵,可以展开为向量),这个用户向量的表达能力是随向量的维度增加的。同时其空间复杂度以及后续的计算复杂度也几乎和向量维度线性相关。也就意味着这是一个表达能力受限的方法。


去年,我们借鉴了 NLP 领域的 memory network 思路,在 encode 这条线路上做了一次尝试。我们提出 MIMN[1]模型,来解决推荐点击预估领域引入用户长序列建模带来的问题。由于用户兴趣状态随着用户新增行为发生变化,和广告请求无关。因此我们试图利用兴趣 memory 来建模用户的原始行为,将用户原始行为进行归纳和抽象为用户抽象的兴趣表达。


从工业系统实现上,我们设计了一个 UIC 模块将用户兴趣 memory 计算和广告请求独立,从而解决了系统计算时长和行为长度相关的问题。同时由于 UIC 内部是增量的更新计算,新的行为进入后,对于该行为进行兴趣归纳,无需存储原始的用户行为,系统仅需存储固定大小的用户抽象的兴趣表达 memory。因此基于 memory-based 的 MIMN&UIC 方案缓解了超长用户行为建模在工业生产带来的压力。


然而 memory-based 的模型在将大量用户行为压缩成为固定大小的兴趣 memory 的过程中,存在信息损失。当用户行为膨胀到数万数十万时,有限的兴趣 memory 向量维度难以完整记录用户原始的行为信息。与此同时,MIMN 难以准确建模用户和广告相关的兴趣,在面对不同候选广告提取相关兴趣时,由于信息压缩,单个兴趣槽内存在大量噪声。因此从算法角度,memory-based 的模型很难精确刻画用户在预估广告上的兴趣表达。


既然对于用户行为进行抽象归纳和建模存在信息损失,同时在表达动态的用户兴趣时还存在噪声,那么我们能否直接从原始的用户行为角度出发,根据原始的用户行为建模和预估广告相关的用户兴趣?


DIN[3]直接利用用户原始的行为,根据预估广告采用遍历的方式,从用户原始行为中捕捉和候选广告相关的行为进行动态用户兴趣表达建模。但是在生产上存储和计算压力下,DIN[3]很难直接对于上万的用户序列行为进行搜索。


因此我们从单个用户的视角,对于单用户行为进行结构化的组织,试图打破原来遍历方式带来的计算和存储压力。我们试图利用用户数万的历史行为,来完整的对于单个用户在淘宝上的全周期兴趣进行建模,试图打造出用户在电商场景上的“一人一世界”的预估模式。我们利用预估广告和用户的信息作为 query 从我们构造的单用户数据库中快速检索到相关的用户行为,直接在原始用户行为数据上建模用户在当前广告上的动态兴趣表达。为此我们提出了一个基于搜索的用户兴趣建模范式 SIM(Search Interest Model)来解决超长用户行为建模中的计算和存储挑战。


SIM 借鉴了 DIN[3]中通过候选广告搜索相关用户行为的方法。在 SIM,我们利用两个阶段来捕捉用户在广告上的精准兴趣表达:


(1) 第一阶段我们提出了 GSU(General Search Unit) 从原始的超长用户行为中根据广告信息搜索到和广告相关的用户行为。由于在线的计算和服务时长的限制,GSU 采用了比较简单但是有效的方法来提取相关用户行为。搜索后的用户行为数据能够由原来的上万长度降低到数百长度,与此同时大部分和当前广告无关的信息都会被过滤。


(2) 第二阶段我们提出 ESU(Exact Search Unit) 利用第一阶段提取出和广告相关的用户行为和候选的广告信息来精准建模用户的多样兴趣。在 ESU 中,我们可以采用类似 DIN[3]或者 DIEN[2]这样复杂的模型来捕捉用户和广告相关的动态兴趣表达。


通过我们提出的基于两阶段搜索的用户兴趣建模范式,能很好的缓解超长用行为建模给在线带来的压力。从 2019 年底,我们就将 SIM 部署到阿里的定向展示广告场景,并在信息流场景上取得了很大的提升。目前 SIM 的方法已经部署到阿里定向展示广告各个主要的业务线,作为各个场景的主流量模型服务生产。现阶段 SIM 建模的最长用户长度能到 54000,相比之前 MIMN 引入 1000 长度用户序列提升了 54 倍。

算法方案

为了打破局部用户行为数据给推荐系统带来的局限性,能够个性化的建模用户需求、精准的刻画用户偏好,我们引入了超长的用户行为数据。我们从全新视角出发提出了一个两阶段搜索范式来建模用户的超长行为序列。算法框架如图四所示。SIM 包含两级检索模块 General Search Unit (GSU) 和 Exact Search Unit (ESU)。


在第一阶段,我们利用 General Search Unit (GSU) 从原始用户行为中搜索 Top-K 相关的用户子序列行为。这个搜索时间远低于原始行为遍历时间,同时 K 也比原始用户行为小几个数量级。我们在限制的时间内采用了合适且有效的方案来对于超长用户行为进行搜索。如图所示,我们在 GSU 中提出了两种搜索方案:sotf-search 和 hard-search。GSU 将原始的用户行为从数万降低到数百,同时还过滤掉了和候选广告信息不相关的用户行为数据。


在第二阶段,ESU 利用 GSU 产出的和广告相关的用户序列数据来捕捉用户跟广告更精准的兴趣表达。由于用户行为已经降低到数百量级,因此在这个部分我们采用复杂的模型结构来进行建模。



图四:SIM 范式模型结构图


General Search Unit

由于在面对单个候选广告时,只有部分用户行为对当前预估有效,因此我们提出 GSU(General Search Unit)来提取超长用户行为中和广告相关的行为数据,从而降低后续基于长期行为的用户兴趣建模难度。


我们提出了两种方案:hard-search 和 soft-search。给定用户行为,其中代表了用户第 i 个行为,T 代表了行为长度。GSU 对于每一个用户行为计算一个相关性分数。然后根据从原始行为中选出 Top-K 相关的行为然后生成一个新的子序列的计算方式如下:



hard-search 是无参数的。只有和候选广告类目相同的用户行为数据才会被选出送到下一级进行建模。其中代表了候选广告类目,代表了第 i 个用户行为的类目。虽然 hard-search 是一种基于数据特性的一种比较直观的方案,但是它非常容易部署到实际工业界在线预估系统。在 Soft-search 中,我们将用户序列 B 行为映射成为 embedding 表达都是模型参数。其中代表了候选广告 embedding,代表了第 i 个用户行为 embedding。


然后我们采用向量检索的方式来筛选出 top-K 和广告相关的用户行为。通过这样的方式原始行为序列能够降低到百量级。由于长期兴趣和短期兴趣的数据分布存在差异,我们不能直接采用已经学习充分的短期兴趣模型向量来进行相似用户行为计算。因此,对于 soft-search 我们采用了一个辅助 CTR 任务来学习长期数据和候选广告之间的相关性。如图四左面所示。

Exact Search Unit

在第二阶段,我们采用 GSU 筛选出 Top-K 和广告相关的用户行为子序列作为输入。我们考虑到我们引入的是超长的用户行为序列,用户行为间横跨较长的时间。因此我们将每个用户行为引入了一个时间状态属性。我们引入用户行为时间和当前预估广告时间差来表达每个行为的时间状态属性。最后我们利用一个 multi-head attention 结构来捕捉用户在广告上的动态的用户兴趣。其中第一阶段和第二阶段是采用交叉熵 loss 联合学习。Loss 函数如下:


工业实现

在工业界,推荐或者广告系统需要在一秒内处理完大规模在线请求,返回展示结果。所以 CTR 预估服务需要实时响应,响应时间通常不超过 30ms。由于在 attention-based 模型上系统处理的通信量和用户行为长度呈正相关,同时我们的系统在流量高峰将会处理超过 100 万的用户请求,在面对超长用户行为序列建模时,在线的响应时长和存储都倍感压力。因此将超长用户行为算法模型部署到在线 CTR 预估系统将会面临很大的挑战。


如算法部分,我们提出了两种 GSU 方案 soft-search 和 hard-search,并在阿里生产数据集上进行了实验。我们发现 soft-search 相比 hard-search 方式提升微弱,如表三所示。同时我们发现大部分 soft-search 中的相似 Top-K 行为和 ad 共享相同的类目。这个是基于阿里场景数据发现的特性,大部分的 item 在相同的类目下往往比较相似。


考虑到离线效果提升和在线资源开销的性价比,我们将 hard-search 方式的 SIM 部署到我们的在线广告系统。对于 hard-search,我们发现用户行为可以直接按照类目进行组织并建立好离线索引,使得在线检索时间消耗非常小。因此我们构建了一个两级的索引来组织用户行为,取名为 User Behavior Tree(UBT)(如图五所示)。


UBT 采用 Key-Key-Value 数据结构来进行存储:第一级 key 是用户 ID,第二级 key 是叶子行为所属的类目。我们采用分布式部署的方式处理 22T UBT 数据使得它能服务大规模的在线流量请求,并采用广告类目作为 hard-search 检索 query。经过了 GSU 模块之后,我们将原始用户行为长度从上万数量级降低到百级。因此在线的对于长序列的存储压力得以缓解。图五显示了基于 SIM 改造后的在线 RTP 系统。



图五:SIM 范式下 RTP 系统架构图


实验

我们在两个公开数据集和一个生产数据集分别进行了实验来证明 SIM 模型在引入超长用户行为后的广告点击预估任务中的有效性。表一显示了各个数据集数据规模具体情况。同时我们还将 SIM 部署到我们在线系统,将它和我们系统基线模型进行了严格的在线 A/B test。



表一


在 Amazon 数据中最大长度为 100,我们将最近 10 次行为作为用户短期行为,后面 90 次行为作为用户长期行为。Taobao 数据集最大长度为 500,我们将前 100 数据作为用户短期行为,后面 400 数据作为用户长期行为进行建模。在生产上,我们收集了 49 天曝光样本数据,然后利用第 50 天数据作为测试。在生产数据中我们将用户 180 天行为数据作为长期用户行为,14 天行为作为短期用户行为。其中超过 30%样本特征长度超过 10000,最长用户行为长度为 54000,相比 MIMN 提升了 54 倍。


实验设置如下:


(1)DIN:是我们早期的建模用户短期兴趣的模型。


(2)Avg-Pooling Long DIN:为了能分析长序列数据带来的价值,我们将长序列 avg pooling 处理后和 DIN 其他特征 concat 一起进行建模。


(3)MIMN 是我们之前提出基于 memory-base 的长序列用户行为建模方法。


(4)SIM(hard)是 GSU 采用 hard-search 的 SIM 方案。


(5)SIM(soft)是 GSU 采用 soft-search 的 SIM 方案。


(6)SIM(soft/hrad) with Timeinfo 是引入时间间隔属性的 SIM 方案。


我们在公开数据集 Amazon(book)和 Taobao 进行了实验对比。实验结果如表二。


我们可以看到,在公开数据集上,其他引入长期数据模型都比 DIN 表现更优异。这说明长期用户行为数据对于 CTR 建模很有帮助。同时 SIM 比 MIMN 有较大提升,也说明了 MIMN 将用户行为压缩到 memory 的方式,候选很难捕捉到精确的用户相关兴趣。其中 SIM 两阶段方案在所有方法中表现最好。


我们在生产数据上进行了实验,实验结果如表三:



表二



表三


我们对于 SIM 这样两阶段的检索方式进行了实验拆分验证其有效性,结果如表四所示。



表四


采用 SIM 的方法都能带来提升,说明长期用户行为内存在和当前预估广告不相关的噪声。同时在引入第二阶段对于用户兴趣进行精准刻画之后还能带来更进一步的提升。


2019 年底,我们将 SIM 模型部署到了生产环境,进行了严谨公平的在线 A/B test。从 2020-01-07 到 2020-02-07 观察期间,在阿里展示广告猜你喜欢场景,SIM 相比在线主流量模型实现了显著提升:CTR+7.1%, RPM+4.4%。目前 SIM 已经覆盖了淘宝内主要展示广告场景业务线,成为了各个业务线主流量模型,每天在线服务。


由于淘宝流量请求非常大,同时我们需要实时响应在线请求,在线工程实现需要考虑到性能问题。对于一个用户请求,我们需要预估上百个候选广告,计算量非常大。我们离线构建了一个两级索引来检索用户行为,索引每天都会更新。尽管我们需要给每个请求预估上百个广告,但是这些广告总体类目低于 20。同时出于性能考虑我们将每个类目下检索到的用户行为按照 200 截断(大部分行为都会低于 150),通过这样的方式在线请求的压力缓解。另外,我们对于 mutil-head attention 部分的在线计算实现进行了 fusion 优化。


图六显示了目前线上部署的模型在超长用户行为建模中的性能。其中 MIMN/DIEN 是处理 1000 长度行为序列时的性能指标。SIM 是处理最长用户行为长度为 54000 的性能指标,计算长度相比 DINE/MIMN 提升了 54 倍。SIM 能处理超过 10000 以上的用户行为,相比 MIMN 只增加了 5ms。



图六:不同模型系统性能关系图


同时,我们还对 SIM 给淘宝用户和推荐系统带来的影响进行分析。我们将用户的点击行为进行统计,赋予每个点击行为一个兴趣时长。我们用当前点击广告对应的类目信息,对过去这个用户全网点击进行比对。如果这个用户过去 15 天内的点击商品都不属于当前点击的类目,那么这个点击的兴趣时长就是 15 天。按照这样的方式,我们对于一天的所有用户行为点击都进行了统计,画出不同兴趣时长不同模型的点击行为占比,如图七所示。


我们发现 SIM 相比于线上的短期 DIEN 模型,在较长的兴趣时长点击数量有明显的提升(其中 DIEN 和 SIM 流量大小一样)。这说明我们的推荐系统的视野变得“开阔”起来,能够给用户推荐更长期的商品。同时在推荐长期兴趣相关的商品时,能够准确的对用户兴趣偏好进行精准的刻画,使得用户点击兴趣时长变长。



图七


未来工作

我们试图引入更多的用户行为数据来打破对于用户推荐的局限性,希望构建一个更加智能的推荐体系。通过对于用户 life-long 行为的建模,从用户最末端的行为决策中,透过现象看本质,捕捉到用户真正进入电商场景内的需求。我们希望能够充分的尊重用户,真正独立打造出“一人一世界”的建模体系。在电商场景内,用户的需求和偏好不会被大部分的行为模式所代表,能够通过用户自身的大量行为数据来进行个性化的刻画。


目前我们仅仅迈出了一小步,引入了更多的用户行为数据来表达用户偏好。不过我们目前的建模方式和参数学习仍然是全库共享,依靠大数据驱动的方式来进行信息提取。在推荐领域,单用户单模型的模式还需要进行持续探索和思考,从而实现真正的个性化推荐。


论文原文下载地址:https://arxiv.org/abs/2006.05639


参考文献:


[1] Qi Pi, Weijie Bian, Guorui Zhou, Xiaoqiang Zhu, and Kun Gai. 2019. Practice on Long Sequential User Behavior Modeling for Click-through Rate Prediction. In Proceedings of the 25th ACM SIGKDD International Conference on Knowledge Discovery & Data Mining. ACM, 1059–1068.


[2] Zhou G, Mou N, Fan Y, et al. Deep interest evolution network for click-through rate prediction[C]//Proceedings of the AAAI conference on artificial intelligence. 2019, 33: 5941-5948


[3] Guorui Zhou, Xiaoqiang Zhu, Chenru Song, Ying Fan, Han Zhu, Xiao Ma, Yanghui Yan, Junqi Jin, Han Li, and Kun Gai. 2018. Deep interest network for click-through rate prediction. In Proceedings of the 24th ACM SIGKDD International Conference on Knowledge Discovery & Data Mining. ACM, 1059–1068.


2020-07-02 12:004406

评论

发布
暂无评论
发现更多内容

王者荣耀商城异地多活架构设计分析

俞嘉彬

架构实战营

在Git项目中使用husky统一管理hooks

DoneSpeak

git

王者荣耀商城异地多活架构设计

贯通

架构实战营

Linux之locate命令

入门小站

Linux

模块七 作业

CR

架构训练营模块七作业

Neil43

架构训练营

聊聊客户数据平台(CDP)建设

水滴

CDP 精细化运营 客户数据 用户标签 用户生命周期

架构实战营-模块7-作业

大可

模块七:课后作业

Geek_9cf7b5

架构实战营模块 7

阿体

通过Git Hook关联Tapd和Commit

DoneSpeak

git Shell

架构实战营 模块七作业

Dylan

架构实战营

架构实战营-模块一作业

思梦乐

架构实战营

模块7作业 王者荣耀商城异地多活架构设计

高亮

架构训练营

架构实战营模块一作业

一个字

#架构实战营

在Git项目中使用pre-commit统一管理hooks

DoneSpeak

Python git Shell

架构实战营 - 模块7 - 作业

笑春风

Redisson 分布式锁源码 03:可重入锁互斥

程序员小航

redis 源码 分布式锁 redisson

模块7作业

薛定谔的指南针

架构实战营

模块一作业

seawolflin

架构实战营

定义全局Git Hooks和自定义Git Hooks

DoneSpeak

git Shell

在线HTTP请求/响应头转JSON工具

入门小站

工具

架構實戰營 - 模塊 7 作業

Frank Yang

架构实战营

2022vue面试题+答案

buchila11

Vue Vue 3

王者荣耀商城异地多活架构

白发青年

架构实战营

6 月日更总结 | 总是断更的失败经验分享

耳东@Erdong

7月日更 日更

架构实战营 - 模块一作业

Julian Chu

#架构实战营

【LeetCode】 错误的集合Java题解

Albert

算法 LeetCode 7月日更

gk-module1

泰戈

图分析入门

6979阿强

反恶意收购的几种方式

石云升

职场经验 7月日更

阿里定向广告CTR模型最新突破:基于搜索的超长用户行为建模范式_语言 & 开发_阿里定向广告团队_InfoQ精选文章