LeSS案例之Sys商店(下)

Bob Jiang 发表于 2020/07/14 11:06:25 2020/07/14
【摘要】 本案例的关键"反事实"洞察:如果你想开始业务敏捷的旅程,期望减少过程中的许多痛苦,并快速获得LeSS所预期带来的适应性上的提升,一定要在导入LeSS的开始阶段就建立合适的组织结构,就象LeSS规则所倡导的那样。

LeSS案例之Sys商店(上)

技术卓越

技术卓越是一个对我们的LeSS导入非常重要的部分。在"引入变革"中说到,我们成功的标志是在多大程度上能减少缺陷的数量以及我们可以以多快的速度发布新的功能,以此来交付客户价值或者至少学习并理解客户和变化方向。引入并持续改进以下敏捷工程实践使我们在这两个目标上都取得了巨大的进步。

迈向持续集成和交付的婴儿步

从每个团队在不同的分支上工作几周甚至几个月才向主干合并代码,到持续集成,在我们这个案例中,经历了漫长的过程,其中有很多教练课程、对话/会议和讨论。当然,最初的工作方式毫无疑问带来了太多的问题,比如破坏系统、引入已经修复过的缺陷、在与新功能无关的系统维护与稳定等事情上耗费太多时间。见_避免…大批量的改动_。因此在研发这边对远离大发布有很高的接受度。不幸的是,没有人知道怎样才能做到。在案例中对我们有所帮助的是联系了其他IT部门的人,他们之前在Sys创建了一个内部云系统来自动化所有Sys IT系统的部署,因此对持续集成和持续发布有丰富的经验。

每个团队都加入了一位构建专家,他主要关注在两件事情上:(和他的同行一起)构建持续发布的流水线;教导其他团队成员如何自动化每次系统变更,并让所有东西都放入版本控制系统(我们用Github)。但是持续集成不只是让所有东西都版本控制和自动构建,持续集成是一个开发实践。见_避免…认为持续集成只是一个工具_。它需要团队的承诺和纪律:将小的增量变更频繁地合并到主线;并一致认为修复导致应用程序崩溃的变更是最高优先级的任务。因此作为教练,我们关注在引入并维系这样的思维方式,并不断寻找改善下面事物的机会:

  • 减少主线代码提交时间间隔

  • 增加自动化测试套件的全面性

  • 减少在服务器上构建所需的时间

  • 减少每个研发人员在开发环境里执行测试所需的时间

研发人员已经习惯通过分支来处理组件团队的复杂性和串行开发,他们无法想象与其他缺乏经验的同事一起工作在主线上,所以把分支立刻清除被认为是不现实的。我们的做法是挑战分支的持续时间。团队从此开始只工作在两类分支上:长期存在的发布分支和"短暂"存在的特性分支。在减少特性分支的持续时间上我们花了不少功夫,使之从长过一个Sprint的周期(如果该特性不包含在产品增量中)减少到几个小时。有两件事起了极大的作用:一件是持续讨论分支的缺点并展示替代方案比如隐藏新功能或增量做改变;另一件是让分支"活着的时间"透明化。研发人员引入了一个代码审查流程,每当有新的小特性增量在特性分支上做了开发,为了合并这个分支到主线并删除这个分支,另外一个研发人员必须审核分支上的代码变更和执行代码合并。通常情况下,研发人员在开始新特性增量开发时要通过主要交流工具(Slack)与其他团队成员一起讨论这一步,并在变更实现、研发环境测试完成后请求代码审查。尽管从精益研发的观念看这是一个大的缺点,因为它增加了延迟成本并引入工作交接,然而这种方式至少是沿着改进的方向在走,增加了分支持续时间的透明性,也加强了团队中互帮互助的氛围。

在我离开的时候,分支的平均持续时间已经只有一天(有很多分支只有几个小时),虽然不是最优,但相对于以前的工作方式已经是巨大的进步了。

自动化测试

如果没有自动化测试,一次成功的构建仅仅表示应用可以被编译和组装。开发一个详尽的自动化测试套件包括单元测试和验收测试对于快速反馈至关重要,这也是持续集成的核心成果。见_尝试…单元测试_,_尝试…验收测试驱动开发_。

团队里有一个对测试即有知识又有热情的成员对我们帮助极大,因为她懂得敏捷软件研发中的测试是指测试在实质上的独立性而并非与开发分离。获得这种测试实质上的独立性是在开发之前就定义好测试,最好是通过跨职能团队(产品负责人或其代表,以及任何其他了解需求的潜在干系人)在工作坊中来讨论和澄清测试需求。见_尝试…需求工作坊_。在"LeSS事件"产品待办列表梳理中我会介绍我们的产品需求工作坊的流程。

开始阶段,我们让懂编码的测试专家创建自动测试套件来将手动测试脚本自动化,比如,使用Selenium将UI测试自动化。一段时间后,大家意识到这不是一个好主意,虽然在每次构建之后都有一些反馈,但是反馈太慢而测试极其脆弱,需要很多的维护工作。见_避免…在UI上做测试_。测试常常有因为有些UI或功能改变而产生的问题,团队成员需要不停地检查系统新的行为是否符合期望。这还不是最大的问题。这里我们最大的教训是**团队里的一组人负责测试自动化同时另一组人负责实现新功能是灾难的根源 – 这导致额外的复杂性、交接工作的浪费,以及知识分散**。见_避免…单独的自动化测试团队_。我们引入结对工作来解决单一技能团队成员间的分离,使得之前懂测试的成员逐渐扩展了他们的编码知识,而懂编码的成员开始编写自动化测试案例。这不但使我们的测试转向更少的UI测试而更多的API测试,还提高了代码覆盖率。

另一个重要因素是为了减少最初的痛点 – 大量的缺陷 – 除了测试自动化外还引入了"停止并立即修复"的规则。见_尝试…所有测试通过-停止并立即修复_。把我们的构建流水线和我们的消息传递工具(Slack)连接起来,这样每当有分支合并到主线,构建就会启动并在构建结束时,一个测试通知会被发送到"通用"Slack频道。如果自动化测试套件里有测试失败,这个失败的测试信息会与触发构建的分支合并信息一同发布出去。面对这样的信息立刻有自愿者行动起来修复问题很快变成了团队文化的一部分,大部分时候会由感觉是自己的提交导致了测试失败的那个人来承担解决。

另外一个团队采纳的的行为是在修复问题之前为每一个新发现的缺陷写一个新的验收测试。这样,我们的自动化测试套件越来越大,我们对每次产品增量带来的构建都是可发布的信心也越来越强。一年后我们测试套件中的测试达到了1000多个,发布前的回归测试时间也从几周减少到了几个小时。

在修复缺陷或实现新功能之前编写(或更新)验收测试带来的另一个积极影响是,我们把Wiki或Jira中经常过时且零散的文档替换成了_活文档_,就象实例化需求(Specification by Example)中描述的那样。验收测试变成了_可执行的需求规格说明书_,也是永远更新的活文档,与代码在同一个仓库中保存和更新。

社区

对LeSS中的重要话题特别有热情的那些人会对导入带来巨大的影响。Natascha是我们最资深的测试人员,她是实例化需求(Specification by Example)的铁粉,把让团队的关注点从测试执行转向测试确认和测试设计作为她的使命。最重要的是,她拒绝成为所谓的测试主管因为她觉得成为测试瓶颈并没有什么意义。因此,她尽全力地去传播她的知识并培养团队对高效测试的理解。为了更有效地做到这点,她召开例会讨论测试话题,参会的是主要关注于质量保证和探索测试的团队成员(其他人也欢迎参加)。这些会议的成果主要是形成的共识,比如,怎样用Gherkin语言创建规格说明书,或怎样将规格说明书聚焦在测什么而不是怎么测。这些后来会被放在Wiki上与其他团队成员分享。她做的另外一件很棒的事情是向社区成员分发测试相关的书籍。越来越多的人对这个测试的"新方式"充满热情,并将这种热情注入到团队。这些实践也可见_LeSS指南:社区工作_。

除了测试社区,我们还有Scrum Master社区和架构社区。

Scrum Master社区是让Scrum Master们对齐和互相学习的好机会,也供大家分享和缓解他们在LeSS导入中遇到的挫折。跟其它两个社区一样,这里有一个单独的Slack频道,也是一个特别小的组,仅有三个Scrum Master和一个教练,后来增加到五个Scrum Master。人少让我们捆绑得更加紧密,本身也成为一个小团队。在所有团队站会之后,我们每天都有短暂的同步,但这不是Scrum of Scrum。我们不讨论团队的进度而是讨论在站会中发现的新障碍,对齐下个LeSS事件并讨论谁来作引导。大部分时间我们分享各自的观察并扩展我们的学习。我们互相交换Scrum的文章并组织会议讨论它们。特别是在开始时期,我会常常与新的Scrum Master们结对工作,先由我做会议引导再与他们讨论,然后让他们来引导会议并随后反思一些观察到的情况。甚至在Scrum Master们变得经验更丰富以后,我们还坚持了结对教练,与团队成员做定期教练对话。这是一个Scrum Master们发起的实验,目的是在团队成员和Scrum Master之间建立信任关系,使Scrum Master更加了解团队中的每个人,帮助他们应对新的工作方式。考虑到团队的分散性,这样每两个Sprint一次、每次一小时的对话无论是对团队成员还是对Scrum Master来说都非常有价值。

最后成立的是架构社区

设计/架构社区是LeSS强烈推荐的社区,所以非常奇怪这个社区在半年多以后才成立。考虑到组织那时对架构的理解,我能够预见到人们开始时看不到建立这个社区的必要性。

作为一个习惯了瀑布工作和用离岸/近岸的"便宜"研发来维护现有系统的部门来说,他们的理解是,软件是可以被资深架构师"架构"好然后被"普通"程序员按照架构实现的。在我们团队里发生的关键意识转变是理解"敏捷架构源于敏捷地架构行为 – 有实战经验的程序员架构师,卓越的代码文化,重视结对编程,培育高质量的代码/设计,敏捷建模设计工作坊,测试驱动开发和重构,以及其他代码实战行为”。见_LeSS实验:尝试…思考'培养'胜于'架构’ - 创造一个活着的、不断成长的设计_。

这是一个非常漫长的过程,从与负责系统维护(组织中完全不一样的部门)的经理们开展许多讨论开始。通过将资深架构师把设计交给研发做实现(见_LeSS实验:避免…设计交接给'码农’)的系统动态可视化,我们说服他们将近岸研发人员整合到团队中来。这些人开始时做缺陷修复工作,然后就被加入到所有的团队会议中,参与结对编程课程并随着代码审查流程的建立。他们被鼓励负责任何类型的实现,无论是新功能还是已有功能。从清晰地定义谁负责什么到整个团队集体负责产品的设计和质量,确实是一个巨大的转变。除了按需安排的日常结对编程和上面提到的代码审查流程之外,另一个帮助每个研发更好理解系统架构的关键因素是在每个Sprint计划会议中做试探_设计工作坊。我会在下面"LeSS Sprint 计划会议"章节详细描述我们是怎么做的。

一旦理解到真实的软件架构会随着每次编程而演化,突然间就需要建立一个不一样的架构完整性方法,来取代以前那种每次实现之前创建好设计文档的方式。每个团队中最资深的研发人员想要经常聚在一起,分享在设计工作坊中所做的试探设计和使用的架构模式(见_LeSS实验:尝试…架构和设计模式_)。随着时间的推移,一些额外的会议涌现出来,它们不是LeSS事件但可以看作是架构社区会议。一个"架构对齐"会议在每次产品待办列表梳理之后的几天被安排举行,使得资深研发工程师可以一起探索和讨论新需求对大规模架构的影响。这对下个Sprint的计划非常有帮助。还有一个我们称之为"解决方案设计对齐"的会议在Sprint计划会议之后的几天举行,主要是用来对齐在Sprint计划会议2中单个团队试探设计的结果。我相信如果我们都在同地办公并在需要时采用联合设计工作坊(见_Less实验:尝试…讨论更广泛的设计问题做联合设计工作坊_),这些会议是完全不必要的。然而,因为离散的团队(甚至是多个离散团队)让开展有效的会议变得困难,这些作为额外的会议也可以说是非常有价值的。

LeSS中的社区并不只是作为学习和知识传播的支持系统而存在,它们也提供了一个理想的组织决策环境。在这里管理者们并没有妨碍决策的敏捷性(成为瓶颈),决定是由领域专家(无论他们来自于哪个团队)做出的。LeSS建议社区在他们如何工作和做决定方面达成共识(见_LeSS指南:社区_)。在我们这三个社区里,我也非常惊讶地看到他们在没有正式的决策协议的情况下做得如此成功。我相信,这与以下事实有关,即团队成员通过早期参加社区活动建立了非常深层次的相互信任和尊重。在这样的环境中,社区基于每个人同意来做决定就变得容易。(同意意味着没有人会反对这个想法,而共识是指每个人都支持同样的想法。即使在这样的环境中,那也不太可能发生)。

LeSS 事件

我们的LeSS Sprint 仪式

我们从一开始就建立了所有的LeSS事件,但是如你所见,因为我们的团队是分散的,这使我们在实现这些事件本应具备的关键透明性和检视上变得极其困难。

我们所有团队都从两周的Sprint开始:所有团队同时开始和结束一个Sprint(见_LeSS规则:同产品级的Sprint_)。

LeSS Sprint计划会议

跟其他LeSS事件一样,Sprint计划会议因为有远程参与者而非常具有挑战性。开始,所有的团队成员都参与Sprint计划会议1,时间不超过30分钟。然而,随着团队数量的增加,后来只派团队代表参加。见_LeSS指南:Sprint计划会议1_。我之前在"唯一的产品待办列表"章节说过,在Sprint计划会议之前我们一直有一个"业务对齐"会议。在那里,业务代表、“业务PO们"和其他干系人一起讨论和对齐产品待办列表梳理的结果。最后,(后来的)产品负责人决定所有条目的优先顺序并在Sprint计划会议1中由他或其代表向大家展示这个列表。通常情况下,这进行得非常迅速,因为团队会自愿拿走他们梳理过的条目;但在有些情况下,当那些条目并不在前列,如果其他团队没有产能,团队也会挑一些不熟悉的条目。这时,团队代表会寻求在Sprint计划会议2中以及接下来的整个Sprint中跨组合作的机会。他们会召开一个多团队的Sprint计划会议2,这样所有相关团队就可以有共享的设计会议并协调共享的工作。

因为有分散的团队,Sprint计划会议2不得不通过电话会议来完成,使其更加困难。在团队重组之后,这个情况得到了极大的改善:大部分成员坐在一个房间,在一块白板面前,仅仅少数几个成员远程加入。这些团队在不同的时期尝试了许多不同方式,比如怎样改进Sprint计划会议2。最终,我观察到每个团队都有自己喜欢的方式来进行这个会议。有些团队喜欢把自己分成2到3人的小组,让这些小组来把每个PBI拆分成任务;然后他们再聚一起展示所有的任务,让整个团队来重新估算并评估所有的条目加在一起是否能放在一个Sprint中完成。另外一些团队倾向于把每个PBI逐个查看并确认需要完成这些PBI的所有的任务,也用小时数作估算,用这样的方式直到他们都"满了”。虽然每个团队开会的方式不一样 – 这也是LeSS鼓励的做法 ,因为团队应该拥有自己的流程而不是租用别人的流程 – 所有团队都关注在对约定的Sprint待办列表达成共识上。无论使用哪种方式,作为Scrum Master和教练的我们都意识到,团队对他们的"预测"充满信心并为某些不可预见的工作保留一些缓冲是多么重要。我们注意到当团队挑选比最初预测的更少的工作时有一种强大的积极影响,导致团队士气和绩效的提升。

产品待办列表梳理(PBR)

我确信在整个导入过程中,产品待办列表梳理是LeSS事件里改变最多的。一开始,我们(错误地)计划了每两周一次2小时的会议,只有团队成员和"业务PO"参加。业务分析师(也称为IT"产品负责人”)与"业务PO"一起提前准备所有的产品待办列表条目。所有的条目在PBR中展示,团队主要关注在问需要澄清的问题和估算条目的大小上。

所有团队都有在每个Sprint后剩余一些未完成条目的情况,这在团队回顾会议上经常被讨论,其中一个根因是跟使用的梳理方式有关。我们根据咨询教练的建议为PBI引入了一个固定结构:一个用户故事和史诗(Epic)模板包含了业务价值、用户成功场景、假设、验收测试和开放问题。就绪的定义(Definition of Ready / DoR)也被引入来保证未就绪的条目不会在Sprint计划会中展示。除此之外,业务分析师同意采用遵循Gherkin语法(Given…When…Then)的例子来写下验收测试。仍然,这并没有为当前的情形带来多大的改善。许多PBI或用户故事在Sprint结束时并没有完成,是因为一开始他们都没有被完全理解。我们还有很多"回旋镖”(一类在发布之后两个月内又回炉重做的PBI)。随着时间的推移,人们开始意识到,无论在一开始采用了多么好的模板,最能帮助获得真正理解的是在把事情写下来过程中的讨论和反思。不止这个,我们还注意到,我们作为一个团队可以设计出比业务分析师和业务人员独自在一边做出的更好的解决方案;一个让每个人都能理解真正问题并合作解决的机会。鉴于此,在产品待办列表梳理上,我们慢慢地从讨论技术性能规格说明和估算工作,过渡到讨论业务尝试达到的目标或解决的问题,一起定义在一个Sprint里能够实现的目标范围或是帮助我们迈向目标的范围并决定潜在的解决方案。业务分析师仍然负责整个PBR的运行,但后来,我们给团队成员更多的机会来合作定义范围和设计解决方案,而不只是对提前确定的关键实例提出问题。一种有效的方式是在业务分析师展示完一个清晰的实例(“快乐路径”)之后分组讨论,让团队成员们分组寻找边界并尝试提出更多的其他实例。理想情况下,每组都在同一个地点,但有些时候我们通过视频电话会议一起用在线工具(比如wiki网页)解决。之后,我们会评审这些不同的实例,并约定随后会被一起自动化的关键实例。

通过这种转换和不同的方法,我们也认识到业务分析师和"业务PO"并不能对所有讨论出来的问题都有答案,所以我们开始邀请业务方面的专家参与进来。

重要的是要记得整个带有这些伪"PO"们的模式都是错误的,它既是强加于我们的,也是反映了我们对Scrum和LeSS的许多误解。

LeSS Sprint 评审

遵照LeSS的建议,我们建立了一个所有团队参加的产品Sprint评审。由于组织中分散团队和多地点的约束,我们只能通过视频会议来进行这个事件,以便来自不同地方的所有团队成员和业务代表们都可以参加。作为教练和Scrum Master,我们很高兴为所有团队提供了一个共同的Sprint评审,以至于所有参与者都能聚焦于整个产品。通过持续集成实践,团队在Sprint中就让他们的干系人评审已完成的条目以尽快得到反馈。因此大部分PBI都在Sprint中已经被产品负责人和业务代表们评审过了。在Sprint评审中,我们更关注于产品全貌,讨论我们实现了哪些又错过了哪些。不幸的是,由于上面提到的组织约束,我们的Sprint评审缺乏动手检视的特征。

在LeSS中,如同在Scrum中,Sprint评审是关于动手检视产品,并在团队、产品负责人和干系人之间进行深度会谈,以共同了解产品、利润驱动因素、战略客户、业务风险、新的问题和机会,等等。在我离开时的一个改进重点是找到方法允许干系人、产品负责人和团队成员们在多站点环境中对工作的软件进行交互并检视新产品,比如用多站点评审集市的形式并允许对检视中的发现和下个Sprint的方向进行讨论。

LeSS 回顾

另一个有影响力的改进机会是使用整体回顾,就象在第三本LeSS出版书中描述的那样:见_LeSS指南:改进系统_。很长一段时间里,我们在每个Sprint结束就只有一个**团队回顾**,因为没人认为额外的会议有任何价值。但是随后人们认识到只有让每个团队的每个人都参与,才能解决系统性问题。改进代码质量或更多业务方参与这样的事情,如果所有工作在上面的团队都共同努力,影响会完全不一样。起先,Scrum Master在团队回顾之后有一个同步会议来对齐不同团队承诺的改进措施,但后来他们认识到他们不一定能说服他们的团队成员来执行这些其他团队决定的措施,为此他们挣扎了很久。最后,我们引入了"整体回顾”,来自所有团队的成员都会参加,有时候(不幸的是这并不是一直)管理者也会加入。很多重要的改进在"整体回顾"上被讨论和解决,比如在产品待办列表梳理中引入实例化需求的改进。缺乏架构完整性的问题也在整体回顾中被解决,设计/架构社区从"解决方案设计对齐"和"架构对齐"中被创建出来,以支持得到联合的设计对齐。为了解决系统级的问题,就需要和管理层一起审视整个系统,讨论系统动态和心智模式,这个步骤我们已经开始,但在整体回顾中仍然没有成为标准。

发布Sprint

因为我们没有单独的"完成之外的部门”,所有不在完成的定义(DoD)之内的工作需要在发布之前被研发团队做掉。开始时,我们每两个月一次发布,所以每四个Sprint就有一个发布Sprint,这个Sprint里几乎所有的工作都是与完成之外的工作相关。这也符合_LeSS实验:尝试…在Scrum团队中包含一个发布Sprint_。当然我们的目标是减少完成之外的工作并改进DoD,以至于不再需要一个发布Sprint。在我离开时,完成之外的工作已经减少到只需一个团队在发布Sprint中去做,每次发布都由一个新的团队来负责,而其他团队大部分都工作在移除技术债上面。

结论

这个故事展示了应用LeSS原则、规则、指南和实验来在Sys IT部门改进和形成一个更有适应性的组织,使Sys商店得以成功实现,即使有一些组织约束阻止了我们用推荐的方式导入LeSS。就如同开篇里提到的,这并非关于怎样正确导入LeSS。通过(1)当许多团队创建一个产品时引入LeSS规则来去除反适应的元素和(2)通过移除组织结构和政策逐渐改变组织,我们在适应性方面取得了重大改进。持续对系统动态的反思和管理者支持为能持续改进做必要的组织改变,支持和指导了我们通往低切换成本适应的系统优化目标。

应用LeSS框架规则,比如实现唯一的产品待办列表、唯一的产品负责人和全体团队共享Sprint计划会议,有助于保持对产品整体的关注,并在支持自组织和内在激励的同时对团队正在进行的工作提供了可见性。有五个分散团队、许多干系人在不同的地方,这种情况的共同评审非常具有挑战性。即使缺乏真正的Sprint评审应有的深度会谈和对齐,这仍然有助于聚焦在产品整体上。整体回顾使得我们解决更大的组织变革问题,这在团队层面不会得到多少关注。除LeSS事件以外,许多LeSS推荐的指南和实验的采用对软件开发工作也产生了巨大的积极影响。

在我看来,建立比如"停止并立刻修复"之类的规则,并成为我们的文化,对我们能够在短时间内交付缺陷更少更好的产品有极好的影响。我确信,这是基于建立了技术卓越(就像测试自动化、持续集成等等),否则,是不可能以简单、快速、灵活的方式改变产品并快速获得反馈的。没有这些,“停止并立刻修复"是不可能的。

在我就职期间,有三个关键的组织方面使文化发生了转变:移除组织壁垒和层级,去除团队内部角色(所有团队成员在一起工作,每个Sprint结束时创造一个已集成的产品增量)和抛弃了所有为"特殊人群"召开的特别会议,让每个人更紧密也更贴近每个迭代交付高质量产品的目标。移除政策和会议,聚焦在整体产品和整个系统是让我们能够改变文化的主要因素。见_LeSS指南:文化跟随着组织结构_。我觉得另外两个有利因素是**社区**和**教练(对话)**。

回想起来我最大的收获是关于导入LeSS的方式。我们逐步导入LeSS组织架构的方式是由于受到我们组织约束的限制而被迫为之,很幸运我们能够实现上面所述的改进,并没有制造出更多的问题。在大多数情况下,以错误的组织结构开始增强了案例中提到的拉曼组织行为法则描述的动态。通过(1)一开始就教育_每个人_了解_背后原因_,(2)如预期从一开始就将组织设计落实到位,和(3)得到那些深入理解LeSS的组织含义、不遵循拉曼组织行为法则的高层管理团队的大力配合、达成共识并获得支持,我们本可以更快取得更多进展,让每个参与其中的人更容易些。

致谢

我想要表达我对Mark Bregenzer最诚挚的感谢。他是德国第一位LeSS培训师,从我见到他第一天起他就是我的导师,他不仅帮我构造和设计了这个案例,还在我作为大规模Scrum实践者、教练和培训师的成长路上产生巨大的影响。我还要感谢Craig和Bas在我写这个案例过程中给我的有价值的反馈和支持。最后一点也很重要,感谢在这个转型的旅程中参与和陪伴我的每个人,特别是我夫人,Oksana。如果没有你们所有人,我什么也写不了。

[原文](https://less.works/zh-CN/case-studies/sys)

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区),文章链接,文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件至:cloudbbs@huaweicloud.com进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容。
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。