速来报名!AICon北京站鸿蒙专场~ 了解详情
写点什么

敏捷为何在企业中鲜有成效?

  • 2021-10-03
  • 本文字数:8004 字

    阅读完需:约 26 分钟

敏捷为何在企业中鲜有成效?

从差不多 2005 年一直到现在,我都在或多或少做着一些敏捷工作。而到了 2021 年的今天,我对敏捷的现状感到有些失望了。就像大多数踏入敏捷世界的人们一样,我过去和现在都是敏捷宣言的支持者。我个人尝试过 XP、Scrum、看板、SAFe、Scrumban,也看过很多人的经验总结,还参加过很多会议、看过很多 Youtube 的主题视频。有些人,比如说 Jez Humble 就曾试图解决我最熟悉的企业世界的问题,企业界也恰恰可能是我幻灭的起源。


所以,下面的内容会从大企业的角度,而非初创公司的角度来探讨敏捷开发的问题,因为初创公司的所有流程都可能随时变化。本文还会从北欧商业文化的视角切入,在这种文化中企业想解雇不合适或表现不佳的员工远不像美国那么容易。另外在某种程度上来说,大多数敏捷思想领袖似乎都来自英国。换句话说我是在提前声明,我觉得有一些文化问题会影响敏捷方法的成功与否。总之本文会有不少吐槽,也会有一些关于我们如何在企业软件世界中做出改进的想法。不管怎样,我也是没有银弹的。


免责声明:这不是一篇科学论文,所以我不会在文末写上引用来源,基本上这都是我自己的观点和经验,我也很清楚我的观点有时会同敏捷思想领袖的思维方式相悖,我对此表示遗憾。

我对“企业”这个词的定义

我曾经开玩笑说,企业级(Enterprise)软件公司指的是那种所有事情都庞大而笨重的公司,这种说法也有一定的道理。虽然这些公司并非生来如此,但更多会因为传统、恐惧和激励而变成行动迟缓的巨兽。


大企业的管理人员往往缺乏技术背景,或者就算他们做过技术工作,也已经有十年或更长时间没有真正捡起过自己的手艺了。企业架构师一般也会是这种情况,这个岗位完全没什么用途,还成为了许多敏捷工作的障碍。SAFe 中设置了这么一个角色,但在我熟悉的其他敏捷方法中都没有它的位置。


大企业,还有公共服务组织也是一样,在很大程度上是被对失败的恐惧所支配的。高层管理人员对股东负责,公共组织里则是对政府和选民负责。他们不想看到中层管理人员去冒险做一些没有得到高层批准的事情,所以一般来说负责开发工作的中层管理人员并不会因为冒险行动而获得奖励,他们的任务是循规蹈矩、完成目标。如何实现这些目标,如何打造“太大而不能失败”的项目,就是另一个话题了。但如果你的奖金取决于你影响范围之外的项目的成败,你也得研究其中的门道才行。


在公共组织里,你也会非常害怕坏消息,所以所有重大决策当然都应该由第三方咨询公司来审核,反正他们也并不知道你在做什么。这种情况有时也发生在私营公司中,但情况没那么严重。基本上这是一种“找好背锅人”的心态,并且是敏捷的天然障碍(现在更好的说法似乎是“灵活”)。


许多大企业也很喜欢企业架构师这个岗位,因为架构师应该有大局观和产品愿景,并为开发团队提供可以遵循和实施的设计方案。问题是这种架构师要么就完全不具备一线的开发经验,要么就是十多年没亲自上过阵了。直到 2017 年,我还碰到过有企业架构师团队坚决捍卫 SOAP 和企业服务总线。在那个 6-7 人的架构师团队中,只有一个人有编程经验,而且上一次编程是在他 9 岁的年纪。所以他们给出的方案往往都是些过时的设计,甚至完全不切实际,同时它还拖了开发团队的后腿,造成了许多困惑。


但是怎么办呢,总得有人来负责对吧?

自组织团队

大多数敏捷方法都有某种自组织团队的概念,这本质上是和大企业文化相矛盾的。所以根据我的经验,这些自组织理念只能是纸上谈兵。在敏捷的理想概念中(比如大家的榜样 Spotify),团队可以自己控制很多预算;可以自己踢掉一些成员;只从外部架构师那里接受建议,而无需强制遵守后者的要求;团队成员都活力十足、思想成熟,并一心想着为公司实现最大利益。确实有的团队做到了这些目标,成为他们中的一员是一种乐趣。然而,在大型企业内部,情况往往并非如此,原因有很多。


简单来说,这些因素包括:


  • 缺乏技能

  • 缺乏动力

  • 缺乏业务理解

  • 对团队内部地位的挑战

  • 支配型团队成员

  • 学习自组织过程中出现的组织问题

  • 价值未能交付


其中,想要修复最后一个问题,就得先把前面的都搞定才行。

缺乏技能

这可能是敏捷支持者谈论最少的一个问题。似乎所有传授敏捷方法的人们都从来不承认有时团队成员不够出色这一事实。他们都说错在管理层,因为他们没有给出足够的信任、教育和授权。我在管理层和团队两边都呆过,我得说这种说法就是瞎扯。


的确,管理层,就像公司过时的做事方式一样,确实会带来很多障碍。但也确实有些人永远都不应该被允许去写代码,他们永远都学不会编程。我某种程度上同意 Edsger Dijkstra 的观点,他认为被允许进入计算机科学领域的人实在太多了。我自己可能不符合他的标准,但这一观点还是成立。有些人永远学不会编程。我见过的这种情况太多了。具体的问题可能更复杂一些,比如说有人能写点代码,但搞不懂分布式编程,或者没法真正了解客户的需求。这里说的也不光是技术技能,还包括与业务部门交流的能力,这样你才能指出他们设想的解决方案中存在的问题。

缺乏动力

大企业一般会有很多开发人员需要遵循的代码标准、标准架构和语言,而且大多数都是垃圾。如果你像我一样喜欢使用最好的工具来完成工作,很喜欢学习新东西,那么经过十五个年头还在写 Java 或 Javascript 可能就没什么动力可言了。如果最关键的部分,也就是业务主题本身也很无聊,或者你根本无权对业务指手画脚,那么你所做的也就会是正常上下班打卡,正常完成 KPI,但肯定不会有什么激动人心的突破。这种问题很容易通过管理层来解决,但管理层通常不愿意这么做,原因还是主要来自对未知的恐惧。

缺乏业务理解

用户故事本来只是一个说明,是同业务部门(PO)就他们想要的特定特性达成的共识。但在大企业中这一部分经常会出问题,他们把故事变成了完整的需求规范,而开发人员就成了需求到代码的翻译器。与其这样,还不如没有用户故事比较好(这会让人想起从 UML 生成代码的可怕例子,他们是有多想摆脱程序员啊)。


根据我的经验,软件要取得成功就要求开发人员理解系统的“why”和“what”。我见过那种独断专行搞出来的用户故事,开发人员资历很老(好多年经验),在项目中也干了一两年,但因为写故事的人啥都不懂,所以业务效果几乎为零。你可以争辩说,纠正 PO 的错误并不是开发人员的工作;但我的反驳是,系统的实际实现人员应该和实际业务人员一样了解业务规则,往往了解得更深才对。我经常参加开发人员/支持人员纠正业务人员所提出的假设的会议,因为后者已经忘记了他们自己早些时候制定的一些规则。系统就是业务,实现人员应该意识到这一点。

对团队内部地位的挑战

在敏捷环境中,团队中的所有人都应该是平等的。虽然产品负责人和 Scrum Master 显然同开发人员有着不一样的岗位描述,但每个人的意见还是有着同等的价值。有时,当进展不符合预期的情况下团队会加上一名负责人,但这并不是真正的敏捷实践,而是一种应急方法,一般用来应对质量太低或团队输出太低的情况。


然而,如果你在大型组织中的职位是高级架构师,或者你身处某个非敏捷组织中,权力比其他人更大,那么强行让所有人平等总会引发怨恨、争斗,或者团队根本没把心思放在应该做的事情上面。在这种情况下,想打造一支同心协力的团队可能并非易事。项目经理面临的情况也差不多,大多数敏捷方法中都没有这样一种角色,所以他们往往会被选为 PO 或 SM,但到头来做的还是 PM 的工作,因为他们只会做这个而已。高层管理人员需要非常了解权力结构或者打破权力差异,否则一线人员往往难以发挥应有的贡献,你可能无法获得有价值的意见。

支配型团队成员

有些人就是不适合与其他人共事,除非他们真的被委以领导重任。我多次经历过这种麻烦的状况,其中一些团队成员要求加入另一个团队,因为某位同事的行为非常霸道/有侵略性。这破坏了团队本应具备的凝聚力和领域知识。


如果这种情况持续发生,而且再多的谈话或回顾似乎也无济于事,那么最好的办法是摆脱那些支配型的成员,或者给他们分配单独的任务——如果他们确实是优秀的开发人员。这自然也是说起来容易做起来难,因为在公共服务部门或大型企业中解雇人员几乎是不可能的,除非人们犯下了严重错误甚至罪行。我觉得敏捷世界中大多数思想领袖都没有针对这种情况给出妥善的解决方案,主要是因为他们从未在工会等背景下工作过,所以实际上并不知道该如何应对。

学习自组织过程中出现的组织问题

大多数敏捷支持者喜欢把引入敏捷工作方法过程中的失败归咎于管理层,事实确实如此。敏捷并没有给中层管理人员安排什么角色,只把他们看作是一种障碍。因此,由于他们没什么事情可做,因此如果出现一些阻力也是不难理解的。另一方面,我也多次见过组织对敏捷文化的期望是来源于管理层,这种期望通常是从遵循 Scrum 或 SAFe 开始产生的;当结果不符合预期时,大多数经理会认为他们的工作是做点什么来改变状况,这也是很合理的想法。


不幸的是,关于“他们应该做什么”这件事,很少有什么好的建议。如上所述,你的敏捷团队表现不佳的原因可能有很多,有时这个原因是出于管理层的不切实际的期望。然而,负责开发团队的每一位经理都要对权力链条上游的某个人负责,而且当团队觉得自身遇到了不切实际的期望,或被告知不要包装某个解决方案时,他们往往会忘记这一点。争论的焦点往往是开发团队想要提供很好的质量,但有时实际上更重要的是证明某些事情是可行的,然后再修复那些边缘情况。被取消的项目什么都提供不了,而且开发人员常常忘记,给经理一些东西向最高管理层炫耀,可能会为真正的项目争取来资金。


当然,我们也存在组织障碍,比如运营、安全、测试和开发是不同的部门,传统上他们不是作为一个团队来互动,而更像是对手。在这些情况下,一线人员完全可以责怪(高层)管理人员。不幸的是,出于多种原因,管理层很少愿意打破界限,其中许多原因与保持管理层次结构有关,还有一个原因是除了开发人员外,其他人也要对产品负责。如果这不是你的责任,而你的角色只是提供建议或需求(比如说安全部门),那么你真的背不了锅。这对某些人来说是一个舒适的角色,但却不利于交付高质量的软件。

价值未交付

当团队没有交付管理层期望的价值时,一般来说各种各样的指导委员会都会采取行动。我们可以做些什么来降低风险?这往往会让管理层引入更多的微观管理操作,或聘请外部敏捷教练,以试图引导团队朝着管理层想要的方向发展——一般来说是为利益相关者提供价值。当指导者被传唤到 CEO 办公室并解释团队没能交付价值的原因时,利益相关者并不真正关心架构、重构或技术债务。这一点,根据我的经验,有时很难让团队成员理解。


基本上,如果你无法正常交付,就会导致团队被施加更多的流程和控制,结果最优秀的那些人往往会选择走人。解决这个问题的唯一办法是和团队认真地谈一谈,如果团队还是没能交付价值,就要判断是不是目前的期望是无法做到的,还是说一些团队成员在做自己的事情、包装代码、一直在重构(完美是够用的大敌),等等。在第一种情况下,管理者应该取​​消或修改项目;在第二种情况下应该替换一些团队成员,换上更有紧迫感的人。

SAFe 和 Scrum 的经验

大多数大企业选择的敏捷框架是 SAFe 或 Scrum。SAFe 是一个令人厌恶的框架,我真不想听到有敏捷教练说服我用它。它是一个可怕的框架,基本上就是瀑布挂了个敏捷的幌子。这些团队不是自组织的,他们有发布经理和架构师组等。只要看看官方的 SAFe 图表,你就会知道它不是很敏捷。


简而言之,不要用它。


Scrum 更复杂,也是一个更老的框架。如果你没有出现需要立即修复的生产问题,并且管理层也能理解根据 Scrum 模式手册,你只有 50%的时间实现了目标,并且你的 PO 没有充当项目经理,他也具备领域知识,并且知道这就是他的目的,并且你的 Scrum 主管也真的能够消除障碍,那么这个框架就可以正常工作。不幸的是,Scrum 仅适用于一个团队,因此你需要有明确定义的有界上下文才能设法扩展它。SAFe 是一种扩展 Scrum 的尝试,这很可怕。Nexus 似乎是一个更好的选择,LeSS 要简洁很多,所以也好得多。但所有的问题都在于 Scrum 真的不打算以企业期望的方式扩展。


Scrum 和 SAFe 都没有告诉你如何做估算,但普遍的共识是故事点。故事点应该是一些无量纲的东西,但在实践中总会等同于时间。8 个故事点=一名开发人员的 1 个冲刺,或类似的东西。


据称故事点的发明者 Ron Jeffries 似乎后悔了,这里有一份有趣的参考资料:https://ronjeffries.com/articles/019-01ff/story-points/Index.html


所以基本上当你试图计算速度(没有方向的速度标量)时,你交付的是时间/时间=一些和价值没关系的数字。理想情况下,你的故事应该具有 CoD(延迟成本)值,这样你就可以说我们交付了 10000 美元/2 周的价值。这是有实际信息的,但故事点只会给你一个随便冒出来的数字。


通常你的估计也就能到这个地步了,但利益相关者一般会将它们视为承诺,因此只需坚持使用 T 恤尺寸(s、m、l),并将它们与 CoD 搭配来确定优先级即可。理想情况下,你会知道你的速度有多快,所以能够用 T 恤来加速你的冲刺。但这种情况很罕见,因为你的团队很难稳定,一直都在招聘新人。产假在发达国家是真实存在的,还有 6 周的假期。敏捷中有一大类“无估计”场景,它们确实有道理。如果它很重要就好好研究一下,否则就别这么做。


在实践中,我的经验是 Scrum 在大企业中运作得不是特别好,而且大多数开发人员发现各种仪式都很无聊或令人沮丧。站立会议,实际上是一个小型计划会议,被视为某种状态会议。一般来说,仪式,特别是如果你再加上积压微调的话,是很浪费时间的。你很容易会把 15%的时间花在会议上,此外还要参加一些必须参加的团队外会议。在后面的这些会议中,你实际上会与其他人清理各种事情,或参加什么公众会议,但这类会议在 Scrum 中是没有安排的——Scrum 认为 PO 应该了解领域的一切知识。他们很少做到这一点,所以如果你是公司在某个领域的一号人物,那么你预计至少要花 20%的时间在会议上——实际上往往会有 50%。


Scrum 还为团队成员设定了一个非常高的标准,这是没有多少团队能够实现的。在最近的一次 Pod 演讲中,Jim Coplien 谈到 swarming 是最重要的 Scrum 模式,但要实现这一点,据我所知,所有开发团队成员都必须是全栈开发人员才行,这在企业界是非常罕见的。


简而言之,有了合适的人员和合适的组织,Scrum 是可行的,但这种情况下大多数方法也可以。

管理者在敏捷企业中的角色是什么

一些思想领袖认为,经理这个职位似乎只是在制造问题,但当然必须有人负责招聘和解雇人员、建议给人加薪,并且在总体上确定方向,还要做出不受欢迎的决定,例如取消某些项目或技术上没有成功的实验。但做这些事情的人们会不断地把他们深陷其中的坑挖得越来越深。


经理的职责之一是让他的团队尽可能找到最优秀的成员,不仅是技术上最好的,而且是个性和心态上最棒的。我对自己过多关注技术这一事实感到内疚,我也不该假设人们可以像成年人一样解决问题。毕竟,这就是敏捷教练告诉我的。可是在现实世界中并不是这么回事,因为我们业务环境中的大多数人都厌恶冲突,并且有充分的理由。你不应该因为不同意什么事而在工作场所受到辱骂。因此,团队成员之间的分歧有时到最后会需要管理者来解决。不幸的是,当事情走到这一步时,通常唯一的解决方案是将互相对抗的团队成员分成不同的团队。当同一团队中的成员多次发生这种情况时,正确的解决方案可能是摆脱他们,无论他们的技术有多优秀。如前所述,不幸的是,这几乎是不可能的,然后你最好的办法可能是将这些团队成员隔离在他们自己的小任务上,并希望他们自己退出。


为薪水、培训等用途寻找资金当然是经理的责任。当然有些公司尝试安排一个公共的教育资金池,你可以一直花到池子空了为止。我可能是一个愤世嫉俗的人,但我觉得这种池子放出来第一周内就会被瓜分完毕——也许有一些人真的会为别人着想,但反正我是会先把我的份额保下来!


在我看来,为团队设定方向是经理的职责,因为他通常是最接近业务侧的人,并且最了解业务的财务信息。理想情况下,他也会懂一些技术,并且能够阻止别人重复一些实验,或者做一些被经验证明不可行的事情。当然,如果你的团队有足够的经验,他们应该能够决定什么时候以及如何在事情不顺利的时候转向。但团队往往会滋生骄傲自满的情绪,以至于偏离正轨,这对公司是不利的。有些经理经常不得不做出艰难的决定来拔掉某人的小项目的插头,因为除了小项目的主人以外大家都看得很清楚,那就是它永远不会变成有用的东西。

改进建议

在我们生活的非理想世界中,尤其是在大企业公司中,我已经意识到,如果敏捷项目要在企业中取得成功就需要管理人员,但也需要合适的团队成员。一项大多数人都认可的共识可能是,做出正常软件的最大障碍是人,他们可以是经理、PO、开发人员、利益相关者或是其他任何人。不幸的是,我听到的大多数敏捷思想领袖只会抱怨经理缺乏能力,而不会抱怨团队成员缺乏足够的技能,在我看来这是错误的。之所以会这样,可能是因为团队成员在各种会议等事务中是这些思想领袖的直接目标群体。


基本上,你需要在所有职位上都有合适的人选才能取得成功。这很难做到,原因有很多,比如说企业形象不佳、薪酬过低、权力结构太深、缺乏开发文化、无法解雇表现不佳的团队成员,等等。但无论如何,这都是成功的关键所在。


如果公司的官僚主义氛围成为了正常工作的障碍,那么即使是最好的团队也无法取得成功。独立的安全部门、荒谬的网络配置、持续的业绩评估和 KPI 为核心的战略,都是这种官僚主义的例子,它们会将团队关注的焦点从生产高质量软件这个目标转移到其他事情上。管理层需要消除各种障碍,这些障碍中也包括一些人员。


如果你安排好了团队和外部环境,你还需要一个流程来让你的团队专注于最重要的事情,即创建软件。我会选择尽可能低复杂性的方法,可能是类似看板的设置,摆脱 PO 和 SM,让团队与实际用户或利益相关者会面,通过事件风暴和故事映射会议提出所需的计划,然后与经理以及实际的最终用户或利益相关者的一些代表(如果可能)一起确定优先级。PO 代理可能在某些地方起到作用,但我个人从未真正体验过这种感觉。尤其是在大型项目中,你会有首席 PO,还会有子 PO 负责实际的故事写作。这与只安排一个 PO 的基本理念背道而驰,这种理念中这一位 PO 的头脑中应该对系统有实际的了解。你要经常与利益相关者一起重新审视计划结果,获得反馈,并根据反馈重新确定优先级。但做这些事情的时候都要让团队参与进来,这样每个人都会了解哪些才是重要的事情。


一个关键技巧可能是建立一个像样的 CI/CD 系统,并在部署变得太慢时重构它。在一个 git push 和能让你看到的结果之间通常应该不超过一分钟。自动化测试当然也是这里的一个重要部分,但它不是放在单元测试级别。如何做测试又是一大堆细节要谈,其中有一些非常固执的 TDD 信徒会指手画脚。我可能会在另一篇文章中讨论这个主题,但总的来说,所有事情都要适度,当然啤酒除外:)。


另一个有争议的话题是强制拉取请求,它最初是为极度分布式的开源团队设计的(这种团队中长延迟是可行的),并且很适合那里。在商业环境中,它会大大减慢每个人的速度。尽管很多人都在推荐它,但根据我的经验,代码审查非常无聊,因此没什么意义可言,每个人都坐在那里等待别人来完成工作。我个人很讨厌它,并且宁愿去相信人们自己会做好本职工作,并且如果出于某种监管原因强制要求某种控制策略的话,我可能会把验收测试改成某种结对编程练习的形式。

结论

Brooks 那句没有任何银弹的老话仍然是正确的。在我看来,进步的唯一途径就是在团队中找到更优秀、技能更多样化的人才,这样每个人都不仅仅是技术人员,而且还会了解业务目标,也可以了解经营业务的动态。在一个企业迫切需要更多开发人员的世界中,这似乎只是一个白日梦。我知道这是一种愤世嫉俗的想法,但在大企业中,有太多人不知道自己在做什么,但他们很擅长夸夸其谈,说服其他无知的人们,让别人以为他们自己很清楚自己在做什么。如何大范围解决这个问题呢?我不知道,而且很多人也应该承认他们也不知道。


原文链接:


https://medium.com/@gramr/why-agile-rarely-works-in-the-enterprise-816561515549

2021-10-03 08:007075

评论 3 条评论

发布
用户头像
作者知道的太多啦。。。 条条都命中
2021-10-12 10:20
回复
用户头像
说得太好了,一针见血,就是个样子的
2021-10-09 10:44
回复
用户头像
是文化不同么?完全不知道在说什么
2021-10-09 09:32
回复
没有更多了
发现更多内容

架构训练营模块三作业

张建闯

架构实战营

安卓、iOS、小游戏三端同发?介绍给你一个新方式 - 普洱WebGL

僵尸浩

typescript 小游戏 Unity3D

SRE运维解密-应对过载

董哥的黑板报

微服务 SRE 限流 SRE实践

Web入门:CSS下拉图片

小院里的霍大侠

JavaScript Web 初学者 入门者

运维进阶训练营 -W09H

赤色闪电

运维

数据可视化图表系列解析——饼图

Data 探险实验室

数据分析 可视化 数据可视化 可视化数据 可视化工具

模块三-外包学生管理系统的架构文档

悟空

学生管理系统架构

WEB21

Lenyi

网络安全 CTF ctfshow 爆破

FFA 2022 主会场 Keynote:Flink Towards Streaming Data Warehouse

Apache Flink

大数据 flink 实时计算

【IntelliJ IDEA】idea 2018版本中没有SVN按钮或者图标的解决方法

No8g攻城狮

svn IDEA git 学习

SDK更新不了问题解决

梦笔生花

android hosts SDK 教程

SAP MM SPED输出报错-No authorization for delivery from shipping point US##-之对策

SAP虾客

SAP MM SPED VL31N 公司间STO

基于Go的缓存实现

俞凡

架构

2022-12-25:etcd可以完全替代zookeeper,原因是k8s用的etcd,不用担心不成熟。请问etcd部署在k3s中,yaml如何写?

福大大架构师每日一题

云原生 k8s etcd k3s 福大大

Flink 1.16:Hive SQL 如何平迁到 Flink SQL

Apache Flink

大数据 flink 实时计算

学生管理系统

KING

架构实战营 3-5 消息队列备选架构随堂练习

西山薄凉

「架构实战营」

【web 开发基础】PHP 中的预定义数组详解续集 (48)

迷彩

post GET 文件上传 PHP基础 预定义数组

spaa 22

黄敏

设计模式之美——里式替换(LSP)

GalaxyCreater

设计模式

WEB23

Lenyi

网络安全 CTF ctfshow 爆破

2022年浪过的那些城市

SAP虾客

杭州 2022年 无锡 东莞 SAP项目

Web入门开发【二】

小院里的霍大侠

编程开发 初学者 入门实战 Web入门

【IntelliJ IDEA】连接https报错问题: E230001: Server SSL certificate verification failed:

No8g攻城狮

svn IDEA

Flink 在米哈游的应用实践

Apache Flink

大数据 flink 实时计算

OpenTelemetry系列 (四)| 如何使用Java Agent来实现无侵入的调用链

骑牛上青山

Java javaagent 调用链 OpenTelemetry 微服务调用链

架构误区系列10:不合理的分层

agnostic

软件分层

Web入门开发【四】

小院里的霍大侠

Web 编程开发 初学者 入门实战

HTTP请求首部字段

穿过生命散发芬芳

HTTP 12月月更

架构实战营 3-4 架构设计后期随堂练习

西山薄凉

「架构实战营」

【架构设计】你的类足够“专一”吗

JAVA旭阳

Java 架构

敏捷为何在企业中鲜有成效?_文化 & 方法_Gramr_InfoQ精选文章