ChatGPT规模化服务的经验与教训

5f8008e3ab3ca6ad2cbcfb61b1c5becf.jpeg

2022年11月30日,OpenAI发布ChatGPT,以很多人未曾预料的速度迅速走红。与此同时,由于短时间内用户量的暴涨,导致服务器过载,迫使OpenAI停止新用户的注册。

ChatGPT发布这一年,同样的情景发生了好几次。在最近的OpenAI开发日之后,使用量再度激增,随后OpenAI宣布暂停新用户使用其付费服务。

这背后体现了大模型提供规模化服务时运维的重要性。Evan Morikawa是OpenAI的工程团队经理,目前他主要负责将ChatGPT API等工程产品和设计安全地推向全世界。在近期的一次演讲中,他分享了OpenAI在ChatGPT发布过程中面临的工程、产品和组织方面经历的挑战以及从中学到的经验和教训。

(以下内容由OneFlow编译发布,转载请联系授权。原文:https://www.youtube.com/watch?v=PeKMEXUrlq4&t=109s)

来源 | LeadDev

OneFlow编译

翻译|杨婷、宛子琳

2022年11月30日,我们发布了ChatGPT。当时,OpenAI团队对ChatGPT发布后的前景持不同看法。

这是我们第一次允许公众无需预约即可自由访问模型,这让一些同事感到紧张。在团队内部,我们已经感受到ChatGPT的有趣之处,并且认为在它发布以后很可能迅速走红。此外,我们的GPU资源有限,可能会出现访问资源上的供不应求。过去,我们对聊天应用一直持保守态度,尽管ChatGPT更安全,对齐程度更高,安全系统更加完善,但仍面临着被滥用的风险。

同时,团队中有人对此并不太担心,因为人们已经可以通过开发者平台免费使用ChatGPT,并且ChatGPT也不一定会走红。此外,这只是几个月前发布的GPT-3.5的微调版本,并不是下一代模型GPT-4,而微调版本的模型更加安全。最后,我们没有媒体发布会,只是发布了一篇博客和一条推文,因此,似乎不会出什么问题。

在完成最后一次负载测试后,我们发布了ChatGPT。随后,平台流量开始上涨,并逐渐稳定,实际上,发布后的流量低于我们的预期。我们一直密切关注发布后的情况,在当天的Hacker News上,我们的最高热度甚至没有进入前五,但我们还是感到比较满意。

在内部,我们将这种情况称为“低调的研究预览(low key research preview)”,现在这一术语已经带上了一些负面色彩,但当时,我们的发布会确实是一个相对低调的研究预览,因此,当天大家都能在11月30日晚上正常休息。


第二天早上凌晨4点,我们收到了值班室的警报。出于某种原因,日本的用户访问量激增,因为日本是最早醒来的地区。之后,消息在Twitter上传开,Elon Musk也发布了一篇关于ChatGPT的推文,导致热度进一步高涨。

这时候我们遇到了一点麻烦,为处理突增的流量,团队实施了一个容量控制措施,这种方法类似于俱乐部门卫,即一旦达到容量限制,我们将不允许新用户注册,直到有用户离开。

我们认为,相比传统的预约等待列表,这种方式能让更多人有机会体验ChatGPT。然而,在内部,我们将这称之为“失败鲸(fail whale)”。当时,我们已经达到了容量上限,没有更多GPU可用了,但“失败鲸”数量一直在上涨。网站常常崩溃,网页经常显示“容量已达上限”,实际上,我们已经尽了最大努力提供最大容量。

在ChatGPT发布后的几个月里,网站流量越涨越多,越涨越快,因此,我们团队一直在努力使网站保持稳定,以满足人们的需求。

在ChatGPT的发布过程中,我们学到了很多经验教训,在这里,我主要强调三点:第一,GPU和大规模运行语言大模型的能力;第二,打造一个理智且不断学习成长的团队;第三,学习应对模型可能面临的滥用问题和安全挑战

1

ChatGPT与GPU

首先,我想讨论一下GPU以及ChatGPT如何更好地利用GPU。GPU对ChatGPT及其构建的API至关重要,由于GPU供应极为有限,其特性和成本决定了我们的运营和扩展方式。

为ChatGPT提供动力的计算机拥有大量GPU,每个节点有8块A100 GPU,每个GPU都配备了特殊的高带宽内存(HPM),并且需要在所有GPU之间进行通信。为实现这一点,我们采用了NVIDIA提供的特殊NVLink互联技术,并通过板上的开关将多个GPU紧密连接起来,使它们能够高速交换数据。同时,系统的每张GPU卡还通过以太网和InfiniBand技术连接到外界,该技术为每张GPU提供了200Gb/s或将提升到400Gb/s的网络带宽。对于ChatGPT等大模型,每一点额外的计算能力或带宽的提升都直接影响模型的用户体验和我们所能提供的服务质量。

GPU有许多值得关注的方面,但今天我主要专注以下几个方面:GPU内存和KV缓存、批处理大小、算子、数据传输量与浮点运算数量(Bytes and arithmetic intensity)、任务调度以及自动扩展等。

GPU内存和KV缓存

为了更好地介绍这些内容,先简要带大家复习一下AI模型的工作原理。

c20014922c5cfd4feecc98236358a3af.png

当我们向ChatGPT提问时,模型首先接收文本,将其切分成词元(tokens),然后将每个词元转换为一组数字向量,再通过数百亿个模型权重进行乘法运算。这些模型权重通过梯度下降逐渐微调,方法是预测互联网上所有单词的下一个单词来进行训练,然后,我们会计算出下一个最可能出现的词元的概率。通过不断重复这个步骤,ChatGPT会最终生成相应的内容。

在这种架构中,每个词元都能感知到其他单个词元,这就是自注意机制。文本或上下文越长,我们需要进行的数学运算就越多。不幸的是,自注意机制的复杂度是二次的,文本越长,所需的数学运算也会呈二次增长。此外,我们还需要昂贵的投影操作来用不同维度来映射事物,这听起来可能不太具有优势,但我们需要关注几个相关的属性。

首先,我们可以在先前的所有词元上进行数学计算并进行缓存,这就是KV缓存,K、V指的是在注意力机制中使用的主要矩阵的名称。需要注意的是,第三个矩阵Q的数值每次都会变化,并且无法被缓存,实际上这只是一种命名约定。最关键的是,我们需要将这个缓存存储在GPU中,这是一种特殊的HBM3内存。之所以选择使用HBM3内存,是因为通过PCIe总线传输数据的速度比HBM3内存慢两个数量级,而HBM3内存的传输速度达到3TB/s,对于处理大量数据非常重要。由于HBM3内存与GPU相连,因此具有极高的并行数据吞吐量。

由于GPU HBM内存价格昂贵且容量有限,因此主要用于存储模型权重。一旦这些内存空间用完,系统将按照“最旧的先过期”原则来管理内存。如果发生缓存未命中,即需要的数据不在缓存中,我们就需要重新计算整个聊天对话。此外,由于我们在所有用户之间共享GPU内存,如果某个对话在一段时间内没有操作,它可能会被移出内存。

上述情况意味着:首先,GPU内存实际上成为我们最宝贵的资源之一,它常常代表着某些运算瓶颈,而不仅仅是计算量本身。其次,缓存未命中会对GPU的工作量产生显著的非线性影响,因为我们突然需要重新计算所有内容。

因此,在扩展ChatGPT时,我们不能只简单考虑CPU利用率指标,还需要关注KV缓存,尽可能充分利用所有GPU内存。

批处理大小

批处理大小是另一个指标,大致表示在同一时间发送到GPU的并行请求数量。在H100 GPU中,最多可以在内存寄存器中移动3.35TB/s的RAM,并且在这一秒内,我们可以执行1.98千万亿次8位浮点数的乘法运算。

这意味着,在移动一个字节的时间可以执行591次浮点运算,在行业中,这被称为591:1的运算比率。换句话说,如果要花一定时间移动整个千兆字节的数据,就应该至少执行5910亿次浮点运算,否则会浪费GPU和潜在计算能力。但如果超过这一比率,就需等待内存带宽将数据传输到内存中。

在ChatGPT模型中,需要移动的内存量基本是固定的,大致等于模型权重大小。这意味着,通过改变批处理大小,可以控制可执行的数学运算量。

因此,在扩展ChatGPT时,我们还需要监视批处理大小,以确保GPU得到充分利用。

总体而言,批处理大小和KV缓存的结合是我们确定服务器负载程度的主要指标,我们花了一些时间才确定这一结论。最初,我们使用类似于标准CPU利用率指标的简化GPU利用率指标,但结果证明这一指标具有误导性。

简单的利用率指标只能告诉我们在某个时间段内GPU是否在进行数学计算,而不能告知我们计算强度是否已经饱和,或者我们是否正在耗尽KV缓存。

数据传输量与计算强度

虽然在这里我只讨论了KV缓存和批处理大小,但实际上瓶颈也可能来自内存带宽、网络带宽、GPU以及节点等各种因素。此外,这些瓶颈的位置在模型大小、架构和使用模式上也差异巨大。例如,相比让ChatGPT写文章,它在总结文章方面的性能特性有着天壤之别。

实际上,对于OpenAI和芯片制造商来说,由于上述差异,要设计出完美平衡的芯片十分困难。例如,尽管下一代H100相比A100计算性能提高了6倍,但内存带宽只增加了2倍,我们与其他语言大模型公司发现,很容易碰到内存限制,这实际上限制了新GPU的增益价值。而且,由于H100设计方案几年前就已经确定,NVIDIA本身无法预知这一点。

未来的机器学习架构和规模对于我们和其他人来说都难以预测,但总体而言,我们需要不断调整数学计算,使其与模型的演进相匹配。

其次,我们面临的挑战是GPU的供应问题。OpenAI和整个AI领域的发展速度远远超过了NVIDIA或整个台积电供应链能够生产的速度。由于半导体和数据中心供应链的复杂性,我们会遭遇各种瓶颈。因此,摆脱这一困境的方式之一就是尽可能地获取GPU,而选择合适的地理位置可能会缓解GPU紧张的问题。

51a082ad519addcbd6113747fa80f47d.png

因此,我们的业务范围很快就覆盖了全球多个地区。需要注意的是,上图实际上是Azure公共区域的地图,我们是基于Microsoft Azure进行部署的,但仅限于图中所示的部分地区。为应对业务范围的扩展,团队不得不迅速熟悉Terraform和集群管理,以便快速创建和管理这些部署。尽管从一开始就实现多区域和多集群的部署极具挑战,但由于GPU资源紧缺,这是不可避免的。

此外,需要注意的是,响应时间主要由GPU逐个输出词元的时间所决定。因此,为提高整体响应速度,关键是增加服务器集群的容量并优化,而不是单纯追求服务器与用户离得近(以减少网络延迟)

最后一个主要挑战是,无法迅速扩展服务器集群,没有更多GPU资源可供自动扩展。这意味着,当ChatGPT显示“已满载”页面时,团队无法手动或自动地增加服务器来应对增加的用户流量。这也导致由于GPU容量不足,我们不得不推迟一些发布计划和产品功能的推出。

我认为,人们可能没有充分意识到,如果GPU不受限地供应,ChatGPT所取得的增长可能会更大、更快。

因此,在解决GPU带来的挑战时,我们学到了一些关键教训。

首先,我们需要明确这是一个系统工程挑战,而不仅仅是纯粹的研究项目,这至关重要。我们优化键值(KV)缓存、全球数据中心战略以及产品需求的能力非常重要,团队能够跨越整个技术栈也是关键所在。

其次,适应性地考虑系统的约束条件十分关键。在OpenAI之前,我习惯于观察只有80%的CPU利用率指标就自动扩展到一个无限大的云平台,并优先考虑边缘计算,但在这里,这一切都不适用。此外,每当模型架构发生变化、提出新的推理想法或产品决策发生变化时,我们都需要灵活适应并重新运行这些计算。

最后,深入研究的重要性。对于我们而言,最底层的实现细节至关重要。尽管我愿意将其视为一个黑匣子,接收文本输入,然后在另一端输出更智能的文本,但实际上,更多人深入研究这个“匣子”的细节,我们就能取得更大进步。随着GPT-5、微调、代码执行和更大规模等问题不断升级,这些挑战只会变得更加复杂。尽管我谈论这些问题时是以ChatGPT为背景,但我预计这些经验在未来仍将继续发挥作用。

2

团队建设

我想讨论的第二个经验教训是,在努力保持灵活性和快速推进的同时扩大团队。

在ChatGPT项目发布时,应用工程团队包括我在内总共大约有30人。现在,10个月后,团队规模已增长到近100人。众所周知,OpenAI在团队规模增长方面一直存在着高度的紧张关系。我们的首席执行官Sam Altman一直坚信高人才密度,并致力于以尽可能小的团队完成尽可能多的工作。因此,我们一直在努力保持团队的小规模,以保持快速迭代、充满朝气的实干文化。

然而,随着产品规模的扩大,我意识到扩大团队规模的迫切性。在其他地方可能需要数百人的部门,在我们团队却只有几个人在支撑,而且有时甚至有人在度假。我认为,我们做过的最有影响力的事情之一就是将自己组织起来,以捕捉高度整合、快速发展的初创企业最初阶段的本质。

2d73e809b8a8c3db564464f54cd9a4c0.png

ChatGPT背后的团队看起来像一家刚成立10个月的初创公司。在ChatGPT项目刚开始时,团队有意识地选择了一个全新的代码仓库、新的集群和轻量级的安全控制。我们还确保研究团队与产品开发周期紧密结合,对我们来说,DERP(设计、工程、研究和产品)应该集中在一个团队中。

如今,团队的运行节奏、流程状况、沟通效率以及每个人的责任水平都更加贴近我们对成立一年的初创公司的预期。此外,OpenAI还有一点与众不同,当初大家都在同一个办公室里共同努力,实际上,这在混乱的初创时期起到了一定作用。

实际上,ChatGPT并非OpenAI第一次采用这种合作模式的项目。大约三年前,当应用团队研究API时,我们也做了类似的事。因此,在整个组织中,尽管ChatGPT项目感觉像是一个嵌套在有三年历史初创公司中的10个月大的创业项目,但这些都嵌套在有八年历史的OpenAI研究实验室中。随着新的产品类别不断涌现,我们预计将尝试并继续采用这种分形初创公司模式(fractal startup pattern)。


如今,这一策略要取得成功确实存在一定挑战,我们承担了部分技术债务和重复的情况,现在开始加大对泛工程平台团队的投资,以提前应对其中的部分挑战。

我们还存在人才扩张的严重倾向,因为OpenAI一直推崇小团队理念,希望充分利用其优势,但我们也开始面临规模和安全相关问题,这些问题需要定制化程度更高和更高效的解决方案。

实际上,我们确实需要一个极具抱负的团队和一个非常坚定的使命来帮助保持每个人都朝着同一个方向前进。


OpenAI的首要使命是实现一个安全且对齐的通用人工智能(AGI),这使得我们需要权衡许多不同的愿景。我们的确会扪心自问,这是否使我们更接近实现安全且对齐的AGI,以指导未来的发展。

与此同时,像这样的小型初创公司具有巨大的优势。当拥有高度的所有权、低依赖性和简化的流程时,工作更容易完成。初创公司更能保持一种斗志旺盛的环境,我们的迭代周期可以非常短。

同时,在这一领域中,产品问题与研究问题密切相关。我们可以深入思考一下,使创业公司保持高效率的因素,并观察如何在结构上融入这些因素。这并非毫无代价,但我们认为,当高效率成为我们的关键优势之一时,这种权衡是值得的。

3

滥用问题和安全挑战

最后,系统滥用和即将到来的人工智能安全问题是我们面临的主要挑战。在OpenAI,AI安全、API滥用和产品是密不可分的。防止AI用于大规模的虚假信息宣传、放大互联网上最糟糕的部分或导致其他形式的伤害是我们的核心使命。确保采取适当的安全措施一直是项目发布和其他行动的主要阻碍因素。

尽管OpenAI采取了一系列的安全措施来防止系统滥用,但是,滥用者往往能够迅速适应并找到新的方式来滥用系统。特别是当滥用行为可以带来经济利益时,这种适应性尤为明显。

我想给大家分享一个故事,关于一群人对ChatGPT的API进行逆向工程,以及我们对此所采取的措施。一位工程师发现我们的端点上出现了一些与标准客户端签名不完全匹配的流量。当时,相比API流量,ChatGPT应用程序在某种程度上拥有特权。因此,通过ChatGPT获取访问权限的滥用者可以比普通API做更多的事。如果我们直接封锁这些攻击者,他们会立即察觉,并做出调整。

31f6322ba8517770799deb41a2a6a393.png

团队中的一位成员提出了一个想法,我们采纳了该想法,并立即采取了相应行动。事实证明,我们的安全团队一直在积极监控这些滥用者的活动。他们加入了滥用行为发生的Discord社区,以便能够从滥用者的角度观察和了解情况。

攻击者很快就察觉到了异常,他们的山寨API不再有任何意义。但他们很快弄清了状况,不仅如此,甚至给了我们下次更新的建议。随着时间推移,我们发现了更多试图滥用API的人,尽管他们的能力不及ChatGPT。

因此,虽然ChatGPT可能只是今天一个有趣的例子,但随着模型变得更加强大,如果落入错误的人手中,可能造成更大的危害。我们需要以指数级速度增加对滥用行为的警惕性。尽管如此,仅靠团队成员、研究人员和红队成员是不可能识别所有可能的滥用和误用途径。这就是为什么我们相信逐步与现实世界进行有限的接触是识别和解决安全问题最重要的方式之一。

与真实用户进行早期和频繁的迭代是产品开发中一种常见的做法。在开发ChatGPT时,我们也采用了这种理念。不过,我需要指出的是,一次性向所有人发布ChatGPT,是因为我们花了数年时间在更受控制的环境中逐渐适应了这些模型。而对于较新、风险较高的产品,我们将在识别和缓解风险的过程中经历几个阶段后才会推出。

此外,我们还相信随着风险的增加,需要根据情况调整这一策略。波音公司之所以不像Facebook那样快速地发布产品,是有其原因的,而我们今天的关注点与明天的关注点将会有很大不同。

4

结语

ChatGPT的故事只是刚刚开始,我预计今天我谈到的这三个挑战将以新的形式持续存在。虽然随着芯片供应链的迎头赶上,GPU可能会变得更加丰富,但随着消耗越来越大的预算,更加高效地利用GPU的需求也将不断增长。

GPT-5和其他产品的发布,对计算资源的需求将变得更加紧迫。这个层面会考虑到不同的扩展因素,因为GPU的RAM和高带宽互连与每秒能够进行多少次乘法运算同等重要。

保持团队中初创企业的本质一直是我们保持灵活性的唯一方式。虽然这涉及到权衡,但我们已经多次重复这样的努力。随着我们的成长,这将变得更加具有挑战性。同时,随着新的挑战出现,OpenAI在企业文化方面的努力也必须不断调整,以延续这种精神。

最后,OpenAI一直面临一些意想不到的挑战,尤其是那些精明滥用者的挑战。虽然这些挑战并不总是令人愉快,但有时我们也能从中有所收获。因此,尽管前文提到的CatGPT可以缓解先前的滥用问题,但在未来,滥用安全和对齐挑战将更加严峻,如果这些问题变得更为复杂,我们将需要投入更多努力。安全任务是一个核心问题,我们将持续重点关注这一领域。

关于ChatGPT的幕后故事还有很多,至少和那些为实现这一切作出贡献的人一样多。即使这些故事的一小部分,也代表了数十位工作人员的辛勤努力。非常有幸与你分享他们的工作。

其他人都在看

  • GPU架构与计算入门指南

  • 为什么开源大模型终将胜出

  • 可复现的语言大模型推理性能指标

  • OpenAI:“驾驭”超级智能的四年计划

  • 语言大模型推理性能工程:最佳实践

  • OpenAI首席科学家:直面AGI的可能性

  • 开源语言大模型演进史:向LLaMA2看齐

试用OneFlow: github.com/Oneflow-Inc/oneflow/icon-default.png?t=N7T8http://github.com/Oneflow-Inc/oneflow/​​​​​​​

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

RT-Thread 线程间同步【信号量、互斥量、事件集】

线程间同步 一、信号量1. 创建信号量2. 获取信号量3. 释放信号量4. 删除信号量5. 代码示例 二、互斥量1. 创建互斥量2. 获取互斥量3. 释放互斥量4. 删除互斥量5. 代码示例 三、事件集1. 创建事件集2. 发送事件3. 接收事件4. 删除事件集5. 代码示例 简单来说,同步就是…

基于PCA算法的点云平面拟合

平面拟合 1、平面拟合2、参考文献3、相关代码 1、平面拟合 PCA 是一种数学变换的方法,利用降维的思想在变换中保持变量的总方差不变,将给定的一组变量线性变换为另一组不相关的变量,并且使变换后的第一变量的方差最大,即第一主成分…

2023亚太杯数学建模赛题人工精准翻译

大家好,亚太杯今天早上6点已经开赛啦,然后我在这里给大家带来赛题的精准人工翻译,防止大家直接用软件翻译导致某些地方乱码或者翻译不精准,这会导致后续做题过程出现很大偏差。 注意,以下翻译均免费发放word形式的哈&…

使用websocket获取thingsboard设备的实时数据

背景 有一个读者前来咨询,如何实时获取设备的遥测数据。 其实tb是有提供websocket接口来获取设备数据的。而且还支持js跨域调用。下面给大家演示一下。 websocket地址 完整代码 <!DOCTYPE HTML> <html><h

ImportError: cannot import name ‘contextfilter‘ from ‘jinja2‘解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…

redis的主从复制,哨兵模式

1.主从复制 主从复制&#xff1a;主从复制是redis实现高可用的基础&#xff0c;哨兵模式和集群都是在主从复制的基础之上实现高可用 主从复制实现数据的多机备份&#xff0c;以及读写分离&#xff08;主服务器负责写&#xff0c;从服务器只能读&#xff09; 缺陷&#xff1a…

让SOME/IP运转起来——SOME/IP系统设计(下)之数据库开发

上一篇我们介绍了SOME/IP矩阵的设计流程&#xff0c;这一篇重点介绍如何把SOME/IP矩阵顺利的交给下游软件团队进行开发。 车载以太网通信矩阵开发完成后&#xff0c;下一步应该做什么&#xff1f; 当我们完成SOME/IP矩阵开发&#xff0c;下一步需要把开发完成的矩阵换成固定格…

10.docker的网络network-概述

1.docker的网络模式 docker共有四种网路模式&#xff0c;分别是bridge、host、none和container. 1.1 bridge bridge,也称为虚拟网桥。在bridge模式下&#xff0c;为每个容器分配、配置IP等&#xff0c;并将容器连接到一个docker0。使用–network bridge命令指定&#xff0c;…

【每日OJ —— 622. 设计循环队列】

每日OJ —— 622. 设计循环队列 1.题目&#xff1a;622. 设计循环队列2.解法2.1.解法讲解2.1.1.算法讲解2.1.2.代码实现2.1.3.提交通过展示 1.题目&#xff1a;622. 设计循环队列 2.解法 1.本题有很多解法&#xff1a;可以使用数组&#xff0c;单链表&#xff0c;双链表&#x…

控制论与科学方法论

《控制论与科学方法论》&#xff0c;真心推荐。 书籍原文电子版PDF&#xff1a;https://pan.quark.cn/s/aa40d59295df&#xff08;分类在学习目录下&#xff09; 备用链接&#xff1a;https://pan.xunlei.com/s/VNgj2vjW-Hf_543R2K8kbaifA1?pwd2sap# 控制论是一种让系统按照我…

【精选】CSS入门必看知识点大合集

CSS简介 CSS概念 CSS&#xff08;Cascading Style Sheets&#xff09;层叠样式表&#xff0c;又叫级联样式表&#xff0c;简称样式表 CSS文件后缀名为.css CSS用于HTML文档中元素样式的定义 为什么需要CSS 使用css的唯一目的就是让网页具有美观一致的页面 语法 CSS 规则…

每日一题(LeetCode)----链表--分隔链表

每日一题(LeetCode)----链表–分隔链表 1.题目&#xff08;86. 分隔链表&#xff09; 给你一个链表的头节点 head 和一个特定值 x &#xff0c;请你对链表进行分隔&#xff0c;使得所有 小于 x 的节点都出现在 大于或等于 x 的节点之前。 你应当 保留 两个分区中每个节点的初…

Vue3使用dataV报错问题解决

DataV官网&#xff1a;https://datav-vue3.jiaminghi.com/guide/ vue2中是没有问题的&#xff0c;这是第一次在vue3中使用发现的报错问题 报错问题 首先安装&#xff1a; pnpm add dataview/datav-vue3 1. 全局注册报错 然后main.ts全局注册 import { createApp } f…

Redis-Day1基础篇(初识Redis, Redis常见命令, Redis的Java客户端)

Redis-Day1基础篇 初识Redis认识NoSQL认识Redis安装Redis启动RedisRedis客户端 Redis命令数据结构介绍通用命令操作命令StringHashListSetSortedSet Redis的Java客户端客户端对比Jedis客户端Jedis快速入门Jedis连接池 SpringDataRedis客户端SpringDataRedis概述SpringDataRedis…

浅谈WPF之各种Template

前几天写了一篇文章【浅谈WPF之控件模板和数据模板】&#xff0c;有粉丝反馈说这两种模板容易弄混&#xff0c;不知道什么时候该用控件模块&#xff0c;什么时候该用数据模板&#xff0c;以及template和itemtemplate之间的关系等&#xff0c;今天专门写一篇文章&#xff0c;简述…

推荐一款适合做智慧旅游的前端模板

目录 前言 一、功能介绍 二、前端技术介绍 三、功能及界面设计介绍 1、数据概览 2、车辆监控 3、地图界面 4、其它功能 四、扩展说明 总结 前言 智慧旅游是一种全新的旅游业务模式&#xff0c;它充分利用先进的信息技术&#xff0c;提升旅游体验&#xff0c;优化旅游管…

【HarmonyOS】元服务卡片本地启动拉起加桌没问题,上架后拉起加桌时卡片展示异常

【关键字】 加桌选卡展示异常 、 2卡共用一个布局 、 代码混淆 【问题现象】 元服务卡片在本地启动拉起加桌时&#xff0c;多卡的选卡过程显示是没问题的。但是在上架后拉起加桌时&#xff0c;多卡的选卡过程卡片展示异常。 代码逻辑是通过创建卡片的时候判断卡片的尺寸大小…

设计模式-16-Spring源码中的设计模式

1-Spring之观察者模式 Java、Google Guava都提供了观察者模式的实现框架。Java提供的框架比较简单&#xff0c;只包含java.util.Observable和java.util.Observer两个类。Google Guava提供的框架功能比较完善和强大&#xff1a;通过EventBus事件总线来实现观察者模式。实际上&am…

对比两个数组中对应位置的两个元素将每次对比的最大值用于构成新的数组np.maximum()

【小白从小学Python、C、Java】 【计算机等考500强证书考研】 【Python-数据分析】 对比两个数组中对应位置的两个元素 将每次对比的最大值用于构成新的数组 np.maximum() 选择题 以下代码的输出结果为&#xff1f; import numpy as np a1 [1,2,33] a2 [11,2,3] print("…

查看当前laravel版本三种方法(笔记二)

1、在终端中使用 Artisan 命令&#xff1a;在 Laravel 项目的根目录下&#xff0c;打开终端&#xff08;命令行界面&#xff09;&#xff0c;然后运行以下命令&#xff1a; php artisan --version 2、控制器中打印版本 var_dump(app()->version()); 3、在 Laravel 项目的根目…