写点什么

敏捷水手——单体法到微服务之旅

  • 2017-01-21
  • 本文字数:8824 字

    阅读完需:约 29 分钟

本文要点

  • 探究持续四年多的渐进式改革是什么样子;
  • 探索为什么在变革软件和组织设计时要遵循康威定律;
  • 看看如何将领导力应用到不同的团队、领域和层级;
  • 举例说明变革管理如何依赖于理念和一贯的长远目标;
  • 了解从职能型团队到跨职能团队的变革需要做多少工作以及能带来多少回报。

简介

过去几年,eSailors IT Solutions 在技术和组织层面进行了重大变革:从功能筒仓到跨职能团队,从看似装配线的工作流到动态循环,从单体平台到微服务,从层次化的命令 - 控制到团队运作的领导力。本文将简要介绍他们的变革之旅。本文将带你了解大约四年之前我们从哪里开始,经历了哪三个主要的变革阶段才成为现在这个样子。对于每个阶段,本文都将概要地介绍以下几个方面的内容:

  • 我们当时的组织设置;
  • 主要的技术栈;
  • 我们面临的最重要的挑战;
  • 我们希望取得的变革成果以及我们实际取得的成果;
  • 我们的经验教训以及它们如何推动了进一步的改进。

贯穿本文的一个重要主题是康威的假说“设计系统的组织……其产生的设计和架构等价于组织间的沟通结构。” 1 我们将把这一理论作为一面特殊的镜子,用它来照一照我们自己的历史。将组织设计和软件设计对照有什么意义?我们从对公司沟通模式的探究中学到了什么?为什么康威定律仍然在伤害着我们?

我们从哪里开始

以前,在汉堡,对于那些只有 75 名工程师、全部员工大约只有 120 多人的小型软件公司而言,生活很简单。面对着大约 300 万的客户,我们的点子来自当事人、市场或法律部门。我们的平台平均要服务于大约 35 万活跃客户,每年 2.5 亿订单。工作流程是由项目经理组织的。知识被职能筒仓完全隔离:软件部门负责编写特性,质量保证部门负责保证质量,运维部门负责确保软件的稳定运行。如果我们需要修改任何基础设施组件(如增加新服务器、不同的操作系统程序包),一个隶属于其他部门(及国家)的团队就需要进行必要的安装准备。由于各种各样的预算、合作和 / 或沟通问题,这种方法经常导致严重的延期。

图 1:eSailors 的装配线

我们那时的组织设置是什么样子?

我们那时的组织设置是什么样子?如图 1 所示,我们的工作流组织非常像老式工厂里的一条装配线。大多数员工都是在那五个部门(项目管理 / 市场营销、设计、开发、QA、运维)的其中一个部门里工作。每个部门都有自己的管理结构,都有团队负责人和部门主管。遵循着特定的冲刺周期和步骤,软件工件从一个部门传递到下一个部门:

  • 步骤 1:市场营销部门、法律要求或项目经理界定特性,但不进行有效的预验证或评估;
  • 步骤 2:设计部门根据经验进行设计;
  • 步骤 3:开发部门在一个软件工件中实现功能,团队使用 Scrum,但对于 UI 变更,会咨询一个专门的前端团队(3 周);
  • 步骤 4:QA 部门测试(2 周);
  • 步骤 5:为了防止基础设施方面的更改,基础设施团队会准备系统;
  • 步骤 6:Ops 团队将软件工件部署到生产环境,并对其进行维护;
  • 步骤 7:一个专门的团队进行 Bug 修复。

简而言之,我们的价值流是瀑布式 Scrum 2 。就是说,我们在传统结构下实现了 Scrum,我们的敏捷理念所关注的是局部,而不是整个系统。此外,我们在很大程度上还是筒仓形式的组织,采用传统方式进行管理,以决策制定为中心,沟通通常是单向的,由自上而下的策略和自下而上的报告所主导。我们的组织设置如图 2 所示:

图 2:eSailors 最初的组织设置

为了变得更加敏捷,每个产品开发团队都竭尽全力。图 3 展示了我们的团队设置。在本图及后续出现的图片中,DEV 表示开发人员,QA 表示质量保证,PM 表示项目经理。即使每个团队都有一名质量工程师,最终的质量检查和软件审批也还是由一个专门的质量部门所完成。团队的质量工程师必须以一种质量部门审批时能够执行的方式准备测试。

图 3:eSailors 最初的开发团队设置

我们的技术呢?

我们一点也不感到奇怪,这种模式反映在了我们的软件架构中。技术被设计成一个单体平台,基于一个紧耦合的代码库构建,总是作为单个软件进行部署。我们的代码大约有 80% 都打包在一个工件中。eSailors 的工程师习惯将这个平台称为“大泥团”,因为它没有一个可理解的架构,而且很难扩展和维护。部署是通过一个复杂的工具完成的,而且还受限于版本控制系统的逻辑。有时候,提交几个小时后才看到单元测试失败。由于构建和部署过程的复杂性,这个技术栈让变更变得相当困难。

我们如何设法变革我们的流程?

康威定律指出,“设计系统(广义而言)的组织其产生的设计和架构等价于组织间的沟通结构”。我们那时从对现状的审查中了解到了什么?我们如何行动起来设置这两种结构?我们的计划是什么,而我们实际上取得了什么样的成果?

我们从康威定律中汲取的其中一个最重要的教训是:转化成创新性产品以及缩短上市时间不能只依赖于技术变革。相反,组织变革和技术息息相关,需要对这两个维度都进行检查和相应的调整。虽然这在概念上听起来很简单,但改变我们的组织设置和思维花费了我们很长时间,而且现在仍然是我们需要首先处理的问题。

图 4:第一步:新的团队设置

检讨我们的装配线问题,我们决定创建跨职能团队,由他们对整个系统开发的生命周期负全责。为了达到这个目标,我们从组织设置入手。我们解散了 Bug 修复团队,让特性团队为自己的错误负责。这也可以帮助他们更好地理解操作上的需求。我们认为,跨职能团队应该包含全栈职责,所以我们将原先共享的前端团队的成员分配到特性团队。同时,我们将冲刺周期改为两周,一周用来开发,一周用来测试。

我们希望从这些组织变革中得到什么呢?从根本上说,我们希望提高软件质量,缩短交付时间。我们实际上得到了什么呢?好了,我们的结果让人觉得有点矛盾。一方面,加大团队的自主权和责任感让人们更清楚问题所在。但是,所有团队都开始寻找可持续的解决方案,而不是修复问题。这种情况就是由图 4 所示的新的组织设置所导致的。

让开发团队负责 Bug 从许多方面改善了运维和开发部门之间的沟通。DevOps 交流项目启动(开发人员在一个冲刺期间呆在 Ops 部门,反之亦然)。开发人员主动请求参与呼叫中心的工作及使用监控工具。组织文化日益趋向于端到端职责,这种变化越来越明显。开发人员、运维人员和基础设施人员开始定期讨论系统和管理问题。这是进一步改进的关键。简化后的装配线如图 5 所示。

图 5:第一步:管道

不出所料,领导力在许多层面得到了增强。过去,作为功能专家,工程师们习惯于构建自己的 I 型技能集。现在,他们开始让自己向着跨职能团队的 T 型领导者发展。团队自己承担了技术决策的职责,而不是专注于一种核心的架构。

另一方面,我们的共享代码库还是保持不变,还是会导致小的改进开发成本很高。

而且,我们开始认识到,我们的 Scrum 方法在许多方面都是失败的。它没有为我们提供正确的指导,却首先增加了我们的负担。我们经常因为需要修复即将出现的 Bug 而完全忽视了我们的冲刺承诺。将大的特性分割成较小的故事然后排定它们的优先级,这项工作费时费力。也许,最大的阻碍是作为我们主要客户的项目管理和市场营销部门的无法撼动的瀑布式思维。我们使用 Scrum 框架,但是在实现过程中没有采用特性范围。团队的产品经理充当了管理者,将瀑布项目计划分割成较小的不可变部分,而不是减少前期文档以及检查和调整每一个小的开发步骤。而且,我们的前端开发人员的工作流程很难管理。有许多次,团队的其他人员都停下来,等待 UI 修改完成。在其他冲刺中,他们又无事可做,这种让人沮丧的境况导致部分前端开发人员离职。

我们如何改变了航向?

我们从自己的变革中学到了什么?我们哪里违背了康威定律的观点?这如何促进了进一步的提升?下面是我们找到的部分答案:

  • Scrum 并不适合所有的团队、所有的情况。那就是为什么我们必须要求人们检查和调整自己的工作流程以满足需要,并鼓励他们了解业务的全局。
  • 所以,我们需要敏捷团队关注端到端的价值流程,而不是仍然面向筒仓的 Scrum。而且,我们需要敏捷教练有企业家的跨部门的视野,而不是像 Scrum 主管那样只专注于一个团队。
  • 我们还认识到,不只是领导者需要一个更趋向于 T 型的技能集,所有的工程师都需要。在特定领域拥有知识深厚的 I 型专家挺好,只要他们能够并且愿意涉及其相应技术之外的主题。在理想情况下,将来我们的工程师既对跨部门协作持开放态度,又乐于改进软件质量,而不会等到有了明确的业务需求才那么做。
  • 承担起 Bug 修复的职责增进了我们对系统性问题的了解。另一方面,在使用一个大型共享数据库的情况下,全心全意地投入到业务领域及相关软件仍然相当困难。为了提升我们的速度和敏捷性,我们越来越迫切地感觉到要减少对业务端和技术端的依赖。
  • 如果不给团队的产品经理充分授权,让他们可以推动产品愿景的实现,那么他们就无法增加价值。我们只有对每个团队充分授权,让他们在整个开发过程中自主地创建、检查及调整他们的特性,而不只是执行来自外部的需求,我们才可以有所作为。
  • 自上而下推动的决策过程无法达到预期的结果。为了鼓励更多的创新,我们也必须支持自下而上的过程。
  • 虽然团队授权是该做的事情,但跨不同团队和部门的沟通以及协作仍然是一个大问题。
  • 只是改革我们的组织设置及创建新的角色是不够的。作为一项分层桥接的跨职能的团队活动,为了建立领导力,我们还必须解决所有管理角色之间的冲突。

简而言之,我们认识到,我们必须投入更多的精力,以便使用正确的方法构建正确的东西,而不是忙个不停。而且,我们必须加快我们的整体流程,并为此定义清晰的职责。为此,我们设定了新的改进指标。

首先,我们提升了 UX 和产品管理的重要性。在最高管理层的推动和外部培训师的支持下,我们实现了一个包括用户测试、用户实验室和团队 UX 工程师在内的 UX 流程。同时,产品经理承担为我们的客户开发有价值的软件的全部职责。为了减少众所周知的沟通障碍,测试部门成了工程部门的一部分。如图 6 所示,这形成了一个新的组织设置和工作流程。图 7 展示了新的团队设置。

图 6:新的组织设置和工作流程

图 7:第二步:新的团队设置

不再坚持“纯粹的”Scrum,团队开始寻找新的敏捷方法。团队改变了自己的组织方式。这是以一系列的团队建设专题讨论会为支撑的。我们通过这些研讨会评估现状,定义可以作为构建基础的基本优势,商定新的规则和价值观。同时,通过运用各种不同的同伴反馈方法,我们培养了开放沟通和相互帮助的文化。

管理团队也关注团队建设。他们在整个业务部门内进行元回顾,定义可以作为构建基础的优势,深入问题和解决方案。一项重要的改进是,我们开始共同合作,创造性地评估相互矛盾的角色,提取出了精益领导力的第一个概念。任务重叠,界限模糊,决策策略让人困惑,对于这种有些混乱的局面,我们如何有效地进行简化?实际上需要什么样的指导?每一种领导角色都增加了什么价值?需要多少角色?那些角色之间的职责如何划分?

为了培养更多自下而上的流程,我们还修改了我们用来管理变更方案的方法。作为其中的一部分,我们开始在那些方案中包含更多的功能专家。我们新增了所谓的变更团队,而不只是执行由高级管理人员定义的策略。该团队的成员来自那些受变更影响最大的团队,他们被赋予了自主权,可以在一个清晰的界限内研究并实现自己的解决方案。这与其他增强所有权的策略是一致的,比如各种社区实践、有关松弛时间或联合黑客马拉松的明确协议。

我们主要关注的是提升人们提出更多思路和解决方案的内在动机,而不是试图通过诸如金钱、奖金等这些由高级管理人员定义的外部动力来激励人们。为了消除这种外部动力,其中一项改革是将薪金的一些动态部分移到了固定部分。由于其中的部分指标不再由上层管理人员定义,所以团队自己设置自己的指标。

同时,我们继续将我们的软件拆分成微服务。在咨询了外部软件架构师之后,我们为了实现那个目标开启了一项重大的重构计划。通过这项计划,我们希望可以获得完整的跨职能团队,通过独立部署缩短上市时间。我们希望创建对特定领域的技术和业务全权负责的团队。

在建立了重构团队并提取了第一个微服务后,项目终止了。高级管理人员的整体参与度还是太低,而且作为一个整体进行重构太大太冒险。由于重构计划停止了,所以周期时间仍然很长,创新成为意外而不是惯例。我们的技术债务仍在增加。这反映出,我们的组织结构仍然妨碍改进。我们把大量的时间浪费在了权限讨论上,而不是提升软件质量或者实现新的技术。为了有效地实现微服务,我们需要给产品团队更大的自主权,让他们选择自己的工具,并全权负责包括部署在内的整个软件生命周期。即使在上述大规模的重构计划终止以后,工程师们还是深信,将共享的遗留代码库迁移到更小的服务不可避免。现在,我们的新做法是,只要有新需求添加到相应的代码区域就删除旧有的业务逻辑部分。

作为改进工作的一部分,团队改变了维护内部部署和测试框架的习惯做法。他们停下来开发自己的解决方案,致力于保持现有工具的稳定性。我们一致同意使用一种新的策略,让我们可以使用开源的部署和测试工具部署每一个新的服务,而不是使用旧有的内部工具。这样,产品团队变得日益强大,对有效地改进东西越来越有信心,他们开始推动创新。

发现新大陆

所有这些指标把我们带到了哪里?什么有了实际的提升,什么保持不变,而什么变得更糟?以下是对我们 2015 年及 2016 年前 2 个季度一直忙于开展的工作的总结。

在技术方面,我们继续向着独立的微服务发展。同时,我们改善了基础设施部门和工程部门之间的合作。基础设施部门的人员开始向工程师们的实际需求看齐,而不是或多或少地独立创建和维护他们自己的服务,忽视了依赖。

逐渐地,部分产品团队承担起了为新服务创建所需基础设施以及运维新服务的职责。因此,团队现在可以从操作系统层面开始加入自己的技术。这是逐步建立 DevOps 文化的其中一个先决条件。

我们还实现了工程工具的现代化。工程师现在可以自由选择自己的工作站或者笔记本电脑,而不是一个中央虚拟机。一方面,他们有更大的自由来创建自己的环境和工具,另一方面,他们必须增强自己的主人翁意识。此外,我们使用 GitHub 开辟了新的软件开发路径。

在组织设置方面,我们继续向着精益领导力发展。如图 8 所示,我们删除了 ScrumMaster 的角色。对于这个角色,我们认为其作为敏捷催化剂的功能已经完成,团队已经足够成熟,可以实现自组织。我们一举建立了一个精益 - 敏捷教练(LAC)池,可以提供支持团队及管理者的新途径。

图 8:现在的开发团队设置

我们还加大力度,使重要的信息尽可能地透明。可视化管理系统的问题变得愈加重要。产品经理引入了所谓的“墙”来展示有关当前业务选项和即将到来的变更的信息。图 9 展示了设在办公室中央开放空间里的这块板子的最新版本。通过这种方式,我们增加了业务流程的透明度,从通过评估和选择创建业务选项,到开发、验证和完成——这块看板增强了人们的求知欲,促进了沟通交流。

图 9:“墙”

谈及透明度,整个公司都开始每个季度会面,分享团队在最近一个季度里完成的工作以及他们希望在下一个季度里达到什么目标。以新方法为基础,我们还构建了更为透明的变更方案。变更团队的实施方案会同各方面的利益干系人进行公开讨论,例如,使用鱼缸讨论法的形式。这种方法更容易让那些受影响的人参与进来,了解工作进展,促进总体投入。这还有助于直接传递变更的内容和原因,让人们对变更的实现方法有一个统一的认识。变更的能量来自于面对面的交流和协商一致的行动,而不是官方公告、正式的启动会议或者专家的总体规划。

我们提供了一系列的领导力培训,例如,关于如何领导一个人员来自各个领域的自组织团队。第一次,来自不同领域的领导者,如产品经理、团队负责人、董事和 HR,都致力于就未来如何管理公司达成共识。为了有效地支持自组织,需要什么?就能力和实践来说,这意味着什么?共同探讨精益和敏捷领导力的原则,他们还增进了彼此之间的了解,增加了信任和相互理解。

所有这些方案帮我们减少了筒仓逻辑,培养了专注于整个价值流的跨团队协作。与此同时,整个工程部门还形成了一种事后反思和回顾的新文化。实际问题和重大事宜现在都是直接沟通,而不是背后指责和议论。不管是在系统层面,还是在个人层面,提供和接收诚实的反馈都是非常有价值的。

我们现在的状况

所有这些变革对我们的业务有什么影响?我们的变革之旅对我们现如今的自我组织方式有什么意义?再次对照康威定律,图 10 和 11 展示了我们现在的组织结构。

图 10:2016 年 eSailors 的组织方式

图 11:2016 年 eSailors 的组织结构

在摆脱了装配线流程后,现在,跨职能产品团队成为我们关注的焦点。它们是我们保持高效、作出所有重要决策以及推动任何必要变革的引擎。产品团队的重点工作不再是根据特定的规范开发软件产品,然后交付给或多或少不连通的部门,相反,他们既可以决定实现什么,又可以决定如何实现。其他部门提供支持服务,比如数据、基础设施或者咨询。每个团队都可以独立地部署和监控他们的软件。不过,他们通常会合理利用运维部门提供的工具。类似地,团队可以自己做些用户研究,但会有一个用户实验室为他们提供支持。

图 12 说明了现如今的产品团队如何涵盖了整个开发周期。该循环始于识别客户需求和痛点。基于在这个发现阶段了解到的内容,我们可以发现商机,并使用一个特定的画布对它们进行评估。接下来是设计原型以及用户测试,从中我们可以了解到实现正确的功能所需要的一切信息。经过一定数量的循环后,这些功能就不会发布到生产环境里了,然后我们会进行监控,并通过 A/B 测试进行微调。

图 12:eSailors 的开发周期

我们的技术也发生了极大的变化。从原先一个很小的技术集和占主导地位的“大泥球”,我们设法减少了后者,并增加了前者的多样性。我们不再什么系统都仅使用一种数据库解决方案(Oracle),而是在生产环境中使用多种不同的数据库(Oracle、Mongo、Redis、Elasticsearch、Cassandra)。我们不再仅仅关注一门编程语言(Java),我们现在使用不同的语言(Java、Scala、Go、Swift)。还有其他新的工具和库,例如,docker、ansible、vagrant、angularJs、consul 或 openstack。每个团队都有特定的功能领域。他们现在有权自己选择最适合团队需求的技术栈,为他们的特性构建解耦合的微服务。通过选择恰当的工具,而不是实现某项共享技术的变通方案,将新特性交付到生产环境变得越来越快越来越简单。这是可能的,因为团队的工程师现在可以专注于自己的部分,并对自己所开发的服务的全生命周期负责。如果不是对技术栈全权负责,如果需要向其他部门进行彻底地交接,那么这种技术的异构性是不可能的。

我们还没有完成我们的微服务架构,但是我们使用微服务实现了所有的特性。我们还在继续逐步地改进我们的架构。发布新服务的提前期也有了显著的改善。现在,新服务几分钟内就可以构建、标记、测试和部署到生产环境。有时候,从构思到完全实现只需要一天,而不是几周。

虽然我们取得了许多成果,但是我们仍然面临着巨大的挑战。一方面是技术挑战,比如我们的架构的复杂性、我们接下来的微服务旅程或者保证设施随时可用的困难。同时,我们面临着组织和业务上的挑战。在通向始终如一的精益敏捷企业的道路上,我们还面临着一项挑战,就是团队没有真正的得失责任。即使一个产品团队成功地使其价值流的所有干系人都参与进来,其工作的整体成本和回报对这些人来说也是不透明的。

完备的企业产品管理职责是当前困扰我们的一个问题。产品经理关注收益(收入、注册量……),而成本本身(人员编制、工资、硬件、外部服务、培训……)是工程成本中心的一部分。内部基础设施的成本或者产品的营销成本根本没有体现到产品团队上。

为了追踪行动的成本和收益,我们在数据及 KPI 可视化方面取得了很大的进步。但是,因为无法将实现成本、基础设施的成本和工作映射到这类行动上,所以通常很难评价一项实现是否增加了任何价值。

跨团队交流和整个系统的公共视图是困扰我们的另一个问题。现在,我们还不是很清楚应该如何改进我们的端到端工作流。目前,我们即将研究如何使用我们的“墙”(见图 9)作为一种方法来更好地管理我们的价值流——即所谓的看板“飞行高度(flight level)”3 4 。通过扩大业务视角,我们可以从一步一步的价值创造流程中获得新的视角……而且,为了统一监控和积极控制整个公司里正在发生的事情,我们考虑将所有领域的代表都包含进来。我们坚信,这可以提升我们的能力,让我们可以更好地区分选项,改善提前期,通过较小的努力提供更大的价值。

参考资料

  1. How Do Committees Invent? ” Melvin E. Conway
  2. 分析师瞭望:Water-Scrum-fall 是敏捷的现状”Dave West
  3. 领导自组织团队” Siegfried Kaltenecker(免费下载)
  4. 看板的飞行高度” Klaus Leopold

关于作者

Michael Gruczel esailors 移动 App 团队的团队负责人。在实际的工作中,他像仆人一样工作,但有时候又是一名具有破坏性的领导者。他曾经做过咨询顾问,为德语版的 Java Magazin 和 jaxenter 写过一些技术文章。感兴趣的读者可以通过 linkedin 、twitter( @mgruc )联系他,或者通过他的 github 个人资料了解他。

Sigi Kaltenecker是 Loop Consultancy 的联合常务董事,专注于精益和敏捷变革。他已参与了多家国际性公司的改革,包括 Alcatel、bwin.party、eSailors、Kaba、ImmoScout24、Magna、RWE、Swiss Federal Railways 或 Thales Group。Sigi 是《领导自组织团队》《看板改革领导力:创建持续改进文化》(Wiley 2015))的作者,并在“Peer Feedback Loops”上发表了一系列的文章。感兴趣的读者可以通过电子邮件(siegfried.kaltenecker@loop-beratung.at)联系他。

Hans Gruber是 eSailors 汉堡公司的工程负责人和董事总经理。他有很强的工程背景,在类似 Tele2 和 bwin.party 这样的国际性企业里逐步建立起自己的专长。他致力于通过采用精益和敏捷实践来改善团队,因为他坚信,技术和产品团队可以做到精益求精,并借此提供卓越的客户价值。感兴趣的读者可以通过 linkedin 联系他。

查看英文原文: Agile Sailors - A Journey from a Monolithic Approach to Microservices

2017-01-21 16:122453
用户头像

发布了 1008 篇内容, 共 389.5 次阅读, 收获喜欢 344 次。

关注

评论

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

OpenAI被爆12月发布其Orion AI模型!波兰“OFF”电台解雇所有记者,启用AI“主持人”|AI日报

可信AI进展

腾讯TVQA斩获ECCV 2024压缩视频质量评估比赛冠军

Geek_2d6073

数据驱动营销:淘宝商品详情API助力电商运营精准制胜

代码忍者

API 接口 pinduoduo API

西部数据亮相安博会,展出多款领先存储产品

Geek_2d6073

捷行2024Train-the-Trainer微课程系列-用户故事地图实操工作坊

ShineScrum捷行

结构仿真流体仿真热仿真分析咨询报价 点击友商科技

Geek_2d6073

QCN6224 long-range IoT:Can Wi-Fi 7 Outperform LoRa and NB-IoT in IoT Applications?

wallyslilly

qcn9274 qcn6274

中国AI开发者应用生态调研报告

易观分析

重工业数字化转型创新实践:某国家特大型钢铁企业如何快速落地基于实时数仓的数据分析平台

tapdata

钢铁行业数字化转型 实时数仓解决方案 hive数据如何同步到doris oracle数据同步方案 mysql数据复制

AnyGo for Mac 在iPhone / iPad上轻松模拟GPS位置

Rose

专业的思维导图软件XMind Pro for mac

Mac相关知识分享

思维导图软件

云管平台供应商大汇总看这里!

行云管家

云计算 云服务 云管平台 云管理

Microsoft Remote Desktop:在不同设备之间轻松地共享文件和资源

Rose

Microsoft Word 2019 for mac(word mac)中文版

Mac相关知识分享

Autodesk AutoCAD 2024 Mac中文破解版 cad2024下载安装

Rose

适用于 Mac 系统的 SSH 工具Termius Beta for Mac

Mac相关知识分享

Microsoft Remote Desktop Beta for Mac(微软远程连接工具)

Mac相关知识分享

软件设计文档怎么写?详细步骤与注意事项

爱吃小舅的鱼

软件 软件开发 软件设计

AI驱动的低代码未来:加速应用开发的智能解决方案

天津汇柏科技有限公司

低代码平台 AI 人工智能

Charles for Mac 强大的网络代理工具

Rose

AlDente Pro for Mac:保护电池健康的小工具

Rose

IntelliJ IDEA 2024:编程新境界,高效开发新引擎

Rose

2024 必备工具:JProfiler,解锁 Java 应用性能密码

Rose

Redis Desktop Manager for Mac(Redis可视化工具)

Mac相关知识分享

数据开发革新篇:逻辑数据编织平台重塑开发流程

Aloudata

数据仓库 数据分析 数据开发 数据虚拟化 数据编织

人工智能 | 智谱 AI 大模型

测试人

人工智能 软件测试

Downie 4 :流行的 Mac 视频下载工具

Rose

华大北斗芯片级产品矩阵亮相第三届北斗规模应用国际峰会

江湖老铁

做梦都想拥有的陪伴对象,AI居然免费帮我实现了...文中附送体验地址!

可信AI进展

Lazada淘宝详情API的价值与应用解析

科普小能手

API 接口 API 测试 lazada商品数据接口 lazada API接口 lazada API

Go 错误处理指北:Defer、Panic、Recover 三剑客

江湖十年

面试 Go web 后端】

敏捷水手——单体法到微服务之旅_Scrum_Michael Gruczel_InfoQ精选文章