AI 编程的机会和未来:从 Copilot 到 Code Agent

news2024/11/16 3:44:25

大模型的快速发展带来了 AI 应用的井喷。统计 GPT 使用情况,编程远超其他成为落地最快、使用率最高的场景。如今,大量程序员已经习惯了在 AI 辅助下进行编程。数据显示,GitHub Copilot 将程序员工作效率提升了 55%,一些实验中 AI 甚至展示出超越普通程序员的能力。目前 AI 在编程领域所扮演的角色,更多的还是一个「效率工具」——以 Copilot 的形式帮助提高编程效率。

那么 AI 编程的下一步是什么?我们认为,是理解并生成复杂代码集、从而实现真正的软件自动化开发。如果 AI 能够像人类程序员一样,在大型复杂软件项目的代码集上工作,并且能有效地与人类工程师分工协作,生成几十万上百万行代码,这意味着对软件行业的根本性颠覆。

如纳德拉在 Github Universe 2023 上所说,"当你向一个组织引进 Github Copilot,工作流程将发生改变。当销售人员开始写代码,这个组织就变了,它会以代码的速度前进。现在有了 Copilot 和代码的速度,从根本上改变了数字经济。包括汽车、金融、制药... 每家公司都是家数字公司,也是家软件公司。"

本文我们将分享所看到的这一令人期待的趋势,并深入探讨 Code Agent 发展的机遇与挑战。

图片

01

现状概览:巨头林立的「Code Copilot」

编程是 ChatGPT 使用最多的场景

大模型带来了 AI 应用的井喷。在各种落地场景中,最刚需的是什么?Datos 针对 23 年 5-6 月 ChatGPT 用户使用情况做了分析,其中编程以 29.14% 占比高居榜首。

图片

相较于其他很多领域还在探索如何与 AI 结合,AI 编程是有明确商业价值的刚需,因而吸引了大量巨头及创业公司关注。Stack Overflow 在其去年 5 月发布的开发者调研报告显示如下:

最受开发者欢迎的 AI 编程工具

图片

目前主要使用场景

图片

据不完全统计,过去一年,市场中涌现的 AI 编程工具多达几十种。在此我们先对市场上的主流产品做个简要总结,方便读者对发展现状有个直观的了解。

互联网巨头

海外和国内的互联网巨头几乎都在这个赛道推出了相关产品。

图片

创业公司

创业公司的产品分为两类,一类是通用 AI 编程,跟巨头的产品重合度高;另一类聚焦垂类,在某个领域/功能做得深入。

通用AI编程

图片

聚焦垂类的AI编程

除了如上的通用 AI 编程项目外,还有一些聚焦垂直行业或聚焦编程中某个具体环节的初创公司。包括

  • 聚焦电商网站创建:Mintlify

  • 聚焦前端开发:V0.dev,Durable,Enzyme

  • 聚焦为开发者提供丰富的代码模板:Seeka

  • 聚焦代码分析和修改:Adernaline

产品切入点

通过概览 AI 编程领域的主要项目,可以看到目前主流的产品趋势还是做 Code Copilot——即作为工具,辅助人类提升编程效率,而其中最具主导地位的是 Github Copilot,同时其他巨头也纷纷入局。在这样一个巨头林立的领域,初创公司目前主打的切入点主要有如下几种:

  • 免费/开源

  • 提供更加 AI native 的编程环境;

  • 聚焦特定领域/环节的代码进行优化,提升在某个垂直领域的竞争力

02

AI编程的未来:从 Copilot 到 Code Agent

面向未来,有两个关键问题:AI 编程会朝什么方向发展? AI 会不会取代人类码农的工作,实现完全的」软件开发自动化"?

在去年 10 月召开的 AI Engineer Summit 上,Swyx 分享了他眼中未来程序开发领域生产力提升 1000 倍的图景(如下图)。

我们目前正处于第一个阶段:在这个阶段,AI 大幅加速人类程序员工作效率,就好像一个人长了多只手,能够以更少的人力完成更多的工作。展望未来,AI 编程的下个 10x 阶段,是他称之为「AI Product Engineer"的阶段,AI 可以完成大部分工作,人类只需要在几个关键环节参与协作及决策。而在更远的未来,AI 编程的终极图景,便是「AI Engineer Agent」, 届时,软件工程领域已经是 AI 主导的天下,AI Agent 可以互相协同完全自主地完成一个复杂项目。

图片

我们持类似的观点。下面我们将深入讨论,AI 编程什么时候从作为工具的 Copilot 走向真正自主决策的 Agent?从自动代码补全到自动软件开发,这其中存在哪些 Gap、最核心要攻克的难关是什么?我们将从软件工程的核心出发,分享对这个问题的思考。

软件工程的核心——不断积累的复杂系统

现代软件工程经历了从早期瀑布流到最近 25 年中的敏捷开发模式,其成功的原因之一是代码和功能的不断积累。正是这种不断地快速迭代和积累,让软件工程成为人类社会中发展最快、复杂度最高的产业之一。未来如果 AI 编程自动开发成为主体,这种通过迭代和积累实现增量开发的模式会有什么改变呢?

目前由 AI 驱动的 Code Copilot 已经可以从零开始构建相对简单的软件代码集,但跟在现有大型代码集上修改和扩充的「增量开发」难度非常不同。从零开始构建新的代码集相对容易,人进行总体规划分模块,AI 只是编些功能定义明确的代码,其中的实现相对局部、复杂性低。对于大规模的复杂项目,尤其是需要长期演化和发展的大型代码集,这种近乎一次性的构建方式是完全不够的。用户不断提出需求,要求改进现有功能和实现新的功能;代码长期下来会变得僵化,需要重构。这些涉及对现有代码的深入了解和大量复杂细节,人类程序员也是需要很长时间熟悉代码,很多时候是团队协作。

比如,在大型代码集上修改和扩充的任务相当复杂,几乎修改任何一个功能都会涉及多个模块。代码分散在众多不同的源文件和函数中,如何找到分散在各处的相关代码、对其进行修改和扩充,同时不破坏已有的软件功能是一个非常复杂的任务。相比一次性地重写整个代码集,增量的开发模式复杂度要高出几个数量级。

普林斯顿学者最近在 Swe-bench(https://arxiv.org/abs/2310.06770)中研究了用大模型解决增量开发需求的效果。他们从知名的开源项目里找了 2 千多个案例,发现大模型只能解决其中的 4%。

图片

AI 编程会改变这种开发范式吗?

大型软件项目的代码集规模远远超出 AI 目前 context 长度,未来也很难期待 AI 能够把代码集完整地装入内存。即便 context 长度可以无限扩展,它的编程能力仍受限于模型的推理能力。基于目前 Transformer 架构,仍然很难想象 AI 可以一次性地重新生成上百万行的复杂代码集。即便推理能力支持,其性价比是否真的支撑落地应用,也是一个巨大的问题。

一次性生成大型代码集的方法不仅非常脆弱,而且很不经济,其背后深刻的悖谬之处在于:一旦有人创造出能以增量式开发的 AI 自动软件开发系统,它在可靠性和经济性上一定会显著优于一次性生成整个代码集的系统。从系统演化的角度,不断优化积累的系统是唯一最终能够存活下来的系统,就像自然界最终选择的基因演化机制一样。

从这个角度,我们可以提出一个大胆假设:在未来很长一段时间里,即使 AI 完全替代了人类码农,实现了全自动的软件开发,也仍然会采用今天主流软件工程的增量开发模式,每次专注于一项具体的开发任务,对代码集的一部分进行修改和扩充。

基于这个假设,我们认为,AI要想在编程领域真正替代人,最需要解决的是如何能像人类一样在软件这个不断积累的」增量「系统中工作。这需要 AI 对现有大型复杂代码集的理解,并在此基础上进行修改、扩充、测试等工作。

03

实现 Code Agent 的关键——理解复杂代码集的「全局地图」

上文提到,AI 要想在编程领域替代人类,必须要能在复杂代码集上做增量工作。而如何能够实现 AI 对复杂代码集的理解、并在此之上让 AI 接手呢?我们从软件开发的基本结构出发,分析实现这一功能所面临的主要挑战与突破点。

软件工程解析

软件开发的三个阶段

对于一个独立的开发任务,无论新功能开发、现有功能改进、代码部分或全局重构、bug fix 等等,几乎所有开发任务都包含三个阶段:

1)定义任务:Spec

这个阶段的交付是需求文档(Spec)。Spec 具体描述任务的结果,即从软件的用户或维护者的视角看来,任务完成后软件系统有什么具体的改变,包括交互界面、系统行为和性能等。Spec 的核心是把 Why 转化成 What。

2)设计实现方案:Design Doc

这个阶段的交付是开发设计文档(Design doc)。Design Doc 描述需要对功能的哪些节点进行何种修改,并把一个任务分解为多个不同的步骤。Design Doc 把 PM 看到的产品的 What 转变成架构的 What,同时讲清楚架构要如何实现(How)。Design Doc 最后一般会包含开发计划(Dev plan)。

3)实现:代码及测试

这个阶段的交付是代码集的最终完成和测试。根据开发设计文档的规划,逐步完成代码,去跟外部 API 和底层操作系统对接,从而驱动软硬件完成任务。

AI在各阶段的作用

每个阶段的特点不同,AI 起的作用相应的不一样。

1)Spec。Spec 是把用户的需求转化成软件任务的过程。这个环节涉及到大量与人的交互,包括市场调研、反复沟通理解确认用户需求,目前这个环节靠人来做效率是最高的。

2)Design Doc。这是真正有竞争力的环节,也是AI自动生成软件的核心挑战所在。挑战的核心在于规模——如果规模很小,只是一次性任务,AI 目前的能力已经可以做到每次都从零开始生成代码,不需要设计。但如上文所述,软件真正产生价值的地方在于长时间积累的复杂系统,如何让 AI 理解现有的架构、并在此基础上进行增量工作,有很大难度。

用一个简单的例子类比,让 AI 在现有的系统上增加个新功能,就好比要给一个城市增加地铁系统。其中涉及大量对现有城市交通状态的理解与规划,需要考虑全局的交通效率、做路线规划和资源分配,每个节点的变化都牵扯到其他一些节点的,不是单独增加一个地铁站就可以的。对应到代码集,系统级代码非常复杂,有很多相互关联的复杂函数调用、全局变量等约束及边界条件。

AI要解决这个问题,需要的是一个「全局地图」——一个能够让 AI 可以快速定位每个变动对于全局影响的「地图」。一旦有了这个全局地图,AI 就能快速地理解代码、确定变化范围开始工作了。

3)Coding。实现阶段是对各模块的代码和测试。AI 核心需要解决两个问题:

其一是对于开发环境的理解。任何代码最终都要落在具体的平台上,在哪个操作系统上、用什么编程语言、如何编译、代码管理、部署等等……这些都要求 AI 要对平台有深入的了解,就像人类工程师一样。人类工程师所掌握的,远远不止对编程语言的理解,而是对这一整套适配环境的理解。

其二是自动测试和 Debug 的能力。代码生成后,需要测试它是否正确地工作,有问题要能够找到问题所在。这是一个完整的 Code Agent 必需的能力之一。

全局地图的核心——针对代码集的 RAG(检索增强生成)

对于 AI 来说,构建理解复杂代码集所需的「全局地图」,关键是把针对代码集的 RAG(retrieval-augmented generation)做好。目前 Transformer 架构的大模型,没有 RAG 很难做好增量开发场景下的代码生成。RAG 主要解决以下几个问题:

定位需求相关代码。

因为把整个代码集全部塞给大模型并不现实,所以当给定了一个需求,首先要找到代码集中需要修改的相关代码(也就是代码集的一个子集),这里很多时候会涉及多个文件。需求的描述有时候并不会指明具体的 file、class 或者 function,而是对业务模块的描述。比如,如果我们有这样一个需求:」在登录流程中加上 2FA 验证「,RAG 需要找到当前代码集里和登录相关的代码。

提供其他任务相关信息。

有些情况只依赖这些相关代码是不够的。比如说,一些其他信息(如变量的类型信息等),对生成代码的正确性和质量可能会有很大影响。很多用户希望新代码能尽量调用已有的一些函数,而不是另起炉灶完全重写。而这些很有可能并没有包含在相关代码里,这就需要 RAG 去提供这类信息。

定位受影响代码,并做修改。

当大模型生成了新的代码后,因为它推理能力不足,生成的代码可能没有考虑到对整个代码集的影响,这样生成的代码一般是不完全或错误的。这个时候需要 RAG 去找到整个代码集中所有被当前修改影响的区域,然后再对那些代码区域进行修改。

RAG 模块通常包含几种不同信息的查询服务,基本可以分为两大类:一类是依赖于程序分析的技术来构建的查询,会提供调用关系(call graph)、数据流(data flow)、符号表(symbol table)、file、class、function 等信息。另外一类是利用大模型和向量数据库去构建关于代码集的语义索引。这两部分合在一起就代表了对相关代码集的深度理解,或者说就是相关代码集的全局地图。有了这个地图,加上大模型自身已有的通用编程能力,就可以在增量开发领域生成更好的代码。

代码可维护性

代码的可维护性是 AI 编程的一个有趣的问题。

考虑自动软件开发系统的工作方式,AI 是否会像人类个体一样参与大型软件项目?是否需要和人类协作共同开发一个代码集?AI 写的代码未来由谁来维护?从机器人和自动驾驶的发展历史来看,开发人机协作的系统远比开发一个全自动的系统困难很多。如果 AI 生成的代码需要由人类工程师来维护,这个模式对自动软件开发系统提出了更严峻的挑战。

主要的困难来源于代码复用。对于大型复杂软件项目,人们往往通过代码复用来降低开发的工作量。代码复用带来的好处是维护成本,同样的功能只需要实现一遍,同一个 bug 只需 fix 一处,Don『t duplicate yourself 一直是软件工程的一个金科玉律。复用的代价是会引入一些难以预期的复杂 bug,对测试提出了更高的要求。但尽可能地避免组合爆炸仍然是人类软件工程的智慧。

AI 编程可能存在一种比较极端的新的可能性:如果代码都是 AI 生成的,而 AI 修改自己生成的代码或者重新生成代码都比人类要高效得多,那么是否可以放松复用的要求,同时也降低测试的复杂度?只要不需要人类维护 AI 生成的代码,也许更低的复用性未必会降低代码集的可维护性,甚至可能产生 bug 更少的代码。

04

竞争格局及创业机会

市场格局预判:竞争激烈的多头市场

AI 编程整个赛道还在非常早期。虽然巨头已经纷纷杀入,但这个领域很难完全垄断。

目前 GitHub 只是在开源领域占据了主要市场份额,但目前绝大多数代码是以私有形式存在的。代码是很多企业的核心资产,大量企业需要定制化的私有部署,因而未来的竞争格局极大可能是多头而非寡头市场。GitHub Copilot 作为面向所有开发者、所有语言、所有项目的通用 AI 编程工具,在未来很长一段时间的重心都会是做「最大公约数」——即最通用、受众最大的功能。但对于很多具体场景和需求,它提供的产品可能不够尖锐。

举两个例子:上文所说的增量开发场景下理解整个代码集的问题,在目前就没有被很好地解决(SWE-Bench 的研究也一部分验证了这个现实)。另一个例子是针对 Legacy 系统的维护,许多企业内部存在着大量 legacy code,这些 code 不开源,经过常年积累,已经沉淀了许多商业机密,推倒重来需要耗费极其昂贵的成本,日常维护又消耗很多人力,是 AI 非常适合发挥作用的场景。

创业公司该如何找到创造独特价值的切入点?

我们认为,AI 编程的未来是 Code Agent,让 AI 越来越多地介入软件工程的各个环节,自动开发。跟所有 AI Agent 一样,做好 Code Agent 的关键,在于构建世界模型以及 Agent 的经验积累和学习能力。

构建世界模型

面对一个复杂系统,Code Agent 需要将项目相关的所有信息提供给 AI,让 AI 有个全局地图。这个「世界模型」用什么样的方式提供给 AI——文本、图片、还是多模态?

多模态的发展让人与 Agent 沟通的方式更加丰富。GPT-5 对多模态的支持,可以用架构图和设计图帮助 AI 建立对复杂系统的理解,应该比文本和代码的沟通带宽高很多。在许多场景中,综合运用多模态的方式相比单纯的文本会大大提升沟通效率。未来 Agent 对于多模态的应用能力,是竞争中很关键的一环。能够根据不同场景灵活运用多模态的 Agent 将更具竞争力。

Code Agent 的经验积累和学习能力

一旦被提供了复杂系统的信息,AI 需要记住它。如何让 AI 记住世界是什么样子的,需要为 AI 建立好一套记忆体系——做好大模型记忆的存储、管理、调用等。

同时,AI 还需要在此基础上不断学习,进行抽象和提炼,从而提升自己的设计和编程能力。人脑的学习过程非常复杂,认知科学还没有完全研究清楚这个问题。目前很难从人脑的角度,对 Agent 如何持续学习提出一个终极解决方案。但我们知道,现阶段大模型与人脑学习有个很大的差距。人脑是一边做一边学,但大模型的训练过程(即学习过程)和推理过程是分开的。这导致大模型在训练后,只能离线学习而不能在线学习。因此 Agent 提供方需要解决离线学习到在线学习之间的时间差。

目前针对这两个问题,主流的解决方案是通过 RAG,提供一个外挂的 Memory,做推理过程中的知识和经验积累。因而在 RAG 方向上建立技术优势,然后转换成更好的产品效果和体验,也成为了一个重要的竞争点。RAG 本身有很高的技术复杂度,而代码领域的 RAG 可能是所有应用领域中最复杂的,会有很多有挑战的子场景需要解决。即使是市占率很高的 GitHub,也很难短时间把大部分问题解决掉,这便给了创业公司机会。

当然,RAG 只是目前最主流的一种解决方案,未来在记忆与学习能力上是否会出现更新、更有效的做法,非常值得关注和期待。

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

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

相关文章

《Python数据分析技术栈》第01章 03 Python基础(Python Basics)

03 Python基础(Python Basics) 《Python数据分析技术栈》第01章 03 Python基础(Python Basics) In this section, we get familiar with the syntax of Python, commenting, conditional statements, loops, and functions. 在…

dns正反解析配置

1.配置正向解析baidu.com 1、下载bind包 [rootlocalhost ~]# yum install bind -y 2、对配置文件修改 [rootlocalhost ~]# vim /etc/named.conf 3、对数据文件修改 [rootlocalhost ~]# vim /var/named/baidu 4、重启服务 [rootlocalhost ~]# systemctl restart named.service 5…

2.【C语言】(函数指针||sizeof||笔试题)

0x01.函数指针 void test(const char* str) {printf("%s\n", str); }int main() {void (*pf)(const char*) test;//pf是函数指针变量void (*pfarr[10])(const char*);//pfarr是存放函数指针的数组void (*(*p)[10])(const char*) &pfarr;//p是指向函数指针数组…

ROS学习笔记8——实现ROS通信时的常用命令

机器人系统中启动的节点少则几个,多则十几个、几十个,不同的节点名称各异,通信时使用话题、服务、消息、参数等等都各不相同,一个显而易见的问题是: 当需要自定义节点和其他某个已经存在的节点通信时,如何获取对方的话…

【Docker】Nacos的单机部署及集群部署

一、Nacos的介绍 Nacos是一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。 动态服务发现:Nacos支持DNS与RPC服务发现,提供原生SDK、OpenAPI等多种服务注册方式和DNS、HTTP与API等多种服务发现方式。服务健康监测:Nacos提供…

VUE组件--动态组件、组件保持存活、异步组件

动态组件 有些场景可能会需要在多个组件之间进行来回切换&#xff0c;在vue中则使用<component :is"..."> 来实现组件间的来回切换 // App.vue <template><component :is"tabComponent"></component><button click"change…

基于Springboot+vue图书管理系统(前后端分离)

该项目完全免费 项目技术栈前后端分离&#xff1a; 后端&#xff1a;Springboot Mybatis-plus 前端&#xff1a;Vue ElementUI 数据库&#xff1a; MySQL 项目功能描述 管理员&#xff1a; 登录、个人信息、修改密码、管理后台管理系统所有数据 首页统计&#xff1a;…

64.Spring事件监听的核心机制是什么?

Spring事件监听的核心机制是什么? spring的事件监听有三个部分组成 事件(ApplicationEvent) 负责对应相应监听器 事件源发生某事件是特定事件监听器被触发的原因监听器(ApplicationListener) 对应于观察者模式中的观察者。监听器监听特定事件,并在内部定义了事件发生后的响应…

0.96寸OLED-单独驱动和U8g2驱动-硬件软件IIC

0.96寸OLED-单独驱动和U8g2驱动-硬件软件IIC 博主平时DIY经常使用OLED&#xff0c;其中以4脚的I2C屏最多&#xff0c;就想着总结一下子&#xff0c;让广大DIY朋友更容易找到资源。 驱动采用的时SSD1306 同学们拿到代码后&#xff0c;可以直接用&#xff0c;其中博主给的代码默认…

MySQL面试总结

MySQL优化 1.MySQL如何定位慢查询 1.1开源工具 1.2MySQL自带慢日志 1.3解答 2.EXPLAIN 2.1解答 3.什么是索引 4.B树 4.1数据结构对比 5.聚簇索引&#xff08;聚集索引&#xff09; 6.覆盖索引 7.索引创建原则 8.什么情况下索引失效 9.你对sql优化经验 10.事务 11.MVCC 11.主从…

bgp--大AS分小AS

最后效果:r1能ping通r8,r4路由表有r1-r8环回,r4bgp路由表已优化 代码; [r1] ospf 1 router-id 1.1.1.1 area 0.0.0.0 network 1.1.1.1 0.0.0.0 network 12.1.1.1 0.0.0.0 bgp 64512 router-id 1.1.1.1 confederation id …

Qt/QML编程之路:OpenGL的示例(39)

Qt编程之后,会发现有版本问题,有时候一个示例不同的版本下可能会跑不同,有些Qt5跑不同Qt6已经完善,可以跑通。 我就看到有个关于OpenGL的示例: 这个示例是演示怎么基于OpenGL编程的,但是调试时却发现glViewXXX等gl打头的函数说找不到reference,或者什么link不上之类的错…

nvm-nodejs版本控制工具(window操作系统)

一、概述 可以在电脑上同时安装多个nodejs版本&#xff0c;随意切换使用&#xff1b; 二、下载和安装mvn 参考&#xff1a;window操作系统安装多个版本的nodejs——nodejs版本控制工具nvm_windows node多版本共存-CSDN博客 1. 下载 官网地址&#xff1a;https://github.com…

java数组在多线程中安全问题,HashMap是不安全的,Hashtable安全(但每次都加锁,效率低),ConcurrentHashMap完美

package com.controller;import com.myThread.AdminThread; import com.myThread.MyCallable; import com.myThread.MyRunnable; import org.springframework.web.bind.annotation.*;import java.util.concurrent.*; //上面引入*&#xff0c;所以这个可以注销 //import java.ut…

Java中锁的分类

乐观锁、悲观锁 乐观锁&#xff1a;不加锁的并发操作是安全的 可重入锁 RerntrantLock 当一个线程进入到一个同步方法中&#xff0c;然后在此方法中要调用另一个同步方法&#xff0c; 而且两个方法公用同一把锁 此时线程是可以进入到另一个同步方法中的。 读写锁 Reent…

LabVIEW继电保护测试仪自动检测系统

系统是LabVIEW软件平台和STM32F407系列微控制器的融合&#xff0c;提供了一种高效的解决方案&#xff0c;用于继电保护测试仪的自动化控制和数据采集。系统中使用了福禄克8508A型高精度数字多用表和泰克TDS2024型示波器等设备&#xff0c;以确保测试数据的准确性和可靠性。软件…

macOS安装VMware Fusion 13试用版本

1.下载: Download VMware Fusion | VMware 保存到桌面 下载成功: 双击dmg文件运行安装 安装成功 <

JVM篇--垃圾回收高频面试题

JVM垃圾回收 1 简单说下Java垃圾回收机制&#xff1f; 首先在java运行过程中&#xff0c;其实程序员并不需要去显示的调用程序来释放对象的内存&#xff0c;而是由虚拟机来完成的&#xff0c;具体来看是在jvm中有个垃圾回收线程&#xff0c;这个线程是个守护线程&#xff0c;…

LeeCode 42. 接雨水

给定 n 个非负整数表示每个宽度为 1 的柱子的高度图&#xff0c;计算按此排列的柱子&#xff0c;下雨之后能接多少雨水。 示例 1&#xff1a; 输入&#xff1a;height [0,1,0,2,1,0,1,3,2,1,2,1] 输出&#xff1a;6 解释&#xff1a;上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1]…

HarmonyOS NEXT 既是大势所趋,也是“众望所归”,2024你如何选择?

鸿蒙开发最近两个月估计是程序员圈的焦点话题。自从业内人事传出2024鸿蒙HarmonyOS Next版不在兼容安卓后,紧接着余承东高调宣布’’2024年将是原生鸿蒙的关键一年’’,再加上各大厂陆续宣布拥抱鸿蒙生态&#xff0c;使的相关话题就没停过。 01、鸿蒙系统到底是个啥 俺简单来…