基本概念:

        · ABSD是架构驱动,即强调由业务【商业】、质量和功能需求的组合驱动架构设计。

        · ABSD方法有三个基础。第一个基础是功能的分解。在功能分解中,ABSD方法使用已有的基于模块的内聚和耦合技术;第二个基础是通过选择架构风格来实现质量和业务需求;第三个基础是软件模版的使用。

  • 最顶层:
    • 系统被分解为:
      • 概念子系统(若干)
      • 软件模板(一个或若干个)
  • 第2层:
    • 概念子系统被分解:
      • 概念构件
      • 附加软件模板

       

         视角与视图:从不同的视角来检查,所以会有不同的视图。

            要从不同的视角(Perspective) 来观察对架构的描述,如:
            展示功能组织的静态视角:判断质量特性
            展示并发行为的动态视角:判断系统行为特性
            作用:全方位考虑体系结构设计

        · 用例用来捕获功能需求、特定场景【刺激、环境、响应】用来捕获质量需求(质量属性要求)。
变更场景:捕获变更
性能场景:捕获性能
可靠性场景:捕获可靠性
交互性场景:捕获交互性
预期的和非预期的场景
质量场景必须包含预期场景和非预期场景
预期场景:是指系统在正常操作条件下应该能够正确处理和执行的场景
非预期场景:是指系统在异常或意外情况下的场景
非预期场景可能不会真正实现,但它们在决定设计的边界条件时很有用

       

        开发过程:     

                ABSD模型把整个软件开发过程划分为:架构需求、架构设计、架构文档化、架构复审、架构实现、架构演化。

                ABSD能很好的【支持软件重用】

                ABSD方法是一个自顶向下,递归细化的方法。

                软件系统的体系结构通过该方法得到细化,直到能产生软件构件和类。

        1、架构需求 

需求是指用户对目标软件系统在功能、行为、性能、设计约束等方面的期望。架构需求受技术环境和架构设计师经验的影响。需求过程主要是获取用户需求,标识系统中所要用到的构件。如果以前有类似的系统架构的需求,我们可以从需求库中取出,加以利用和修改,以节省获取需求的时间,减少重复劳动,提高开发效率。

                            


                1.1 需求获取
           架构需求是指用户对目标软件系统在功能、行为、性能、设计约束等方面的期望。如果以前有类似的系统架构的需求,我们可以从需求库中取出,加以利用和修改,以节省获取需求的时间,减少重复劳动,提高开发效率。

  • 体系结构需求获取的3个来源:
    • 系统的质量目标
    • 系统的商业目标
    • 系统开发人员的商业目标
  • 体系结构需求获取过程:定义开发人员必须实现的软件功能
    • 满足业务上的功能需求
    • 满足质量属性非功能需求

                1.2 标识构件
             上图中虚框部分属于标识构件过程,该过程为系统生成初始逻辑结构,包含大致的构件。这一过程又可分为3步来实现。
第1步:生成类图。生成类图的 CASE 工具有很多,例如 Rational Rose 2000能自动生成类图。
第2步:对类进行分组。在生成的类图基础上,使用一些标准对类进行分组可以大大简化类图结构,使之更清晰。一般地,与其他类隔离的类形成一个组,由概括关联的类组成一个附加组,由聚合或合成关联的类也形成一个附加组。
第3步:把类打包成构件。把在第2步得到的类簇打包成构件,这些构件可以分组合并成更大的构件。

                1.3 架构需求评审
                        由分析人员,客户,设计人员,测试人员组成小组,检查需求是否真实,类的分组是否合理,构件的合并是否合理。组织一个由不同代表(如分析人员、客户、设计人员和测试人员)组成的小组,对体系结构需求及相关构件进行仔细地审查。审查的主要内容包括:所获取的需求是否真实地反映了用户的要求;类的分组是否合理,构件合并是否合理等。必要时,可以在“需求获取一标识构件一需求评审”之间进行迭代。

        2、架构设计

架构需求用来激发和调整设计决策,不同的视图被用来表达与质量目标有关的信息。架构设计是一个迭代过程,如果要开发的系统能够从已有的系统中导出大部分,则可以使用已有系统的设计过程。

                                   
                2.1 提出架构模型
                        选择一个合适的架构风格,该模型为将来的实现和演化建立了目标。在建立体系结构的初期,选择一个合适的体系结构风格是首要的。在这个风格的基础上,开发人员通过体系结构模型,可以获得关于体系结构属性的理解。此时,虽然这个模型是理想化的(其中的某些部分可能错误地表示了应用的特征),但是,该模型为将来的实现和演化过程建立了目标。

                2.2 映射构件
                        把已标识的构件映射到架构中,将产生一个中间结构,它只包含适合架构模型的构件。 把在体系结构需求阶段已标识的构件映射到体系结构中,将产生一个中间结构,这个中间结构只包含那些能明确适合体系结构模型的构件。

                2.3 分析构件的相互作用

为了把所有已标识的构件集成到体系结构中,必须认真分析这些构件的相互作用和关系。
                2.4 产生架构
                        当决定了关键构件之间的相互作用后,就可以在中间结构的基础上进行精化,得到软件架构。一旦决定了关键构件之间的关系和相互作用,就可以在第2阶段得到的中间结构的基础上进行精化。

                2.5 设计评审
                        邀请独立于系统开发的外部人员对架构进行评审。

        3、架构文档化

       绝大多数的架构都是抽象的,由一些概念上的构件组成。例如,层的概念在任何程序设计语言中都不存在。因此,要让系统分析师和程序员去实现架构,还必须得把架构进行文档化。文档是在系统演化的每一个阶段,系统设计和开发人员的通讯媒介,是为验证架构设计和提炼或修改这些设计(必要时)所执行预先分析的基础。架构文档化过程的主要输出结构是架构需求规格说明和和测试架构需求的质量设计说明书这两个文档。生成需求模型构件的精确的形式化的描述,作为用户和开发者之间的一个协约。软件架构的文档要求与软件开发项目中的其他文档是类似的。文档的完整性和质量是软件架构成功的关键因素,软件架构文档应该从使用者的角度进行书写,针对不同背景的人员采用不同的书写方式,并将文档分发给相关人员。架构文档要保持较新,但不要随时保证文档最新,要保持文档的稳定性。
                 架构文档化过程的主要输出结果是架构规格说明和测试架构需求的质量设计说明书这两个文档。

                文档的完整性和质量是软件架构成功的关键因素。

                关于文档的三大注意事项:

                (1)文档要从使用者的角度进行编写。

                (2)必须分发给所有与系统有关的开发人员 。

                (3)且必须保证开发者手上的文档是最新的。

  • 必须输出的文档:
    • 体系结构规格说明
    • 质量设计说明书
      • 作用:测试体系结构需求

        4、架构复审


        架构设计、文档化和复审是一个迭代过程。从这个方面来说,在一个主版本的软件架构分析之后,要安排一次由外部人员(用户代表和领域专家)参加的复审。复审的目的是标识潜在的风险,及早发现架构设计中的缺陷和错误,包括架构能否满足需求、质量需求是否在设计中得到体现、层次是否清晰、构件的划分是否合理、文档表达是否明确、构件的设计是否满足功能与性能的要求等。由外部人员进行复审的目的是保证架构的设计能够公正地进行检验,使组织的管理者能够决定正式实现架构。
                架构复审【架构评估】的目的是标识潜在的风险,及早发现架构设计中的缺陷和错误。

  • 复审人员:外部人员,如用户、领域专家
  • 行为:搭建一个可运行的最小化系统
  • 目的:标识潜在的风险,及早发现体系结构设计中的缺陷和错误
  • 体系结构能否满足需求
    质量需求是否在设计中得到体现
    层次是否清晰
    构件的划分是否合理
    文档表达是否明确
    构件的设计是否满足功能与性能的要求等。
  • 从体系结构开发模型的图中可以看到,体系结构设计、文档化和复审是一个迭代过程。从这个方面来说,在一个主版本的软件体系结构分析之后,要安排一次由外部人员(用户代表和领域专家)参加
    的复审。
    复审的目的是标识潜在的风险,及早发现体系结构设计中的缺陷和错误,包括体系结构能否满足需求、质量需求是否在设计中得到体现、层次是否清晰、构件的划分是否合理、文档表达是否明确、构件的设计是否满足功能与性能的要求等。

        5、架构实现

       所谓实现就是要用实体来显示出一个软件架构,即要符合架构所描述的结构性设计决策,分割成规定的构件,按规定方式互相交互。

                         

虚框部分是体系结构的实现过程
整个实现过程是以复审后的文档化的体系结构说明书为基础的,每个构件必须满足软件体系结构中说明的对其他构件的责任。这些决定即实现的约束是在系统级或项目范围内给出的,每个构件上工作的实现者是看不见的
                5.1 分析与设计
                        在架构说明书中,已经定义了系统中构件与构件之间的关系,构件接口约束对外唯一代表了构件,所以可以从构件库中直接查找符合接口约束的构件

                5.2 构件实现
                        必要时开发新的满足要求的构件。

                5.3 构件组装
                5.4 系统测试 
                        包括单个构件的功能性测试和被组装应用的整体功能和性能测试

        6、架构演化

在构件开发过程中,最终用户的需求可能还有变动。在软件开发完毕,正常运行后,由一个单位移植到另一个单位,需求也会发生变化。在这两种情况下,就必须相应地修改软件架构,以适应新的变化了的软件需求。

  • 需求的变动
    • 构件开发过程中,用户的需求可能还有变动
    • 软件运行后,由一个单位移植到另一个单位,需求也会发生变化
  • 需求变动引起体系结构的修改

                               
             

1.需求变化归类
首先必须对用户需求的变化进行归类,使变化的需求与已有构件对应。对找不到对应构件的变动,也要做好标记,在后续工作中,将创建新的构件,以对应这部分变化的需求。
2.制订体系结构演化计划
在改变原有结构之前,开发组织必须制订一个周密的体系结构演化计划,作为后续演化开发工作的指南。
3.修改、增加或删除构件
在演化计划的基础上,开发人员可根据在第1步得到的需求变动的归类情况,决定是否修改或删除存在的构件、增加新构件。最后,对修改和增加的构件进行功能性测试。
4.更新构件的相互作用
随着构件的增加、删除和修改,构件之间的控制流必须得到更新。
5.构件组装与测试
通过组装支持工具把这些构件的实现体组装起来,完成整个软件系统的连接与合成,形成新的体系结构。然后对组装后的系统整体功能和性能进行测试。
6.技术评审
对以上步骤进行确认,进行技术评审。评审组装后的体系结构是否反映需求变动、符合用户需求。如果不符合,则需要在第2到第6步之间进行迭代。
在原来系统上所做的所有修改必须集成到原来的体系结构中,完成一次演化过程。

1.在ABSD(基于架构的软件开发)方法中,顶层被分解为(),ABSD体系结构需求一般来自3个方面,分别是系统的质量目标、系统的商业目标和()。

问题1

A功能子系统

B概念子系统

C层次子系统

D逻辑子系统

问题2

A用户需求

B系统需求

C开发人员商业目标

D现有的遗留系统

解析:

Architecture Based Software Design,是一个 自顶向下,递归细化 的方法,软件体系通过该方法得到细化,直到产生 构件和类。在顶层,系统被分解为若干概念子系统和一个或若干个软件模板。概念子系统又被分解为 概念构件或若干个附加软件模板。体系结构需求来自三个方面,分别是 系统的质量目标、系统的商业目标和系统开发人员的商业目标。

2.ABSDM(Architecture-Based Software Design Mode)把整个基于体系结构的软件过程划分为体系结构需求、体系结构设计、体系结构文档化、体系结构复审、()和体系结构演化等6个子过程。其中,()过程的主要输出结果是体系结构规格说明和测试体系结构需求的质量设计说明书。

第1空

A. 体系结构实现

B. 体系结构测试

C. 体系结构建模

D. 体系结构管理

正确答案 :A

第2空

A. 体系结构设计

B. 体系结构需求

C. 体系结构文档化

D. 体系结构测试

正确答案:C

解析:

本题考查基于架构的软件卡发模型方面的知识。基于架构的软件开发模型(Architecture-Based Software Design Model,ABSDM)把整个基于架构的软件过程划分为架构需求、设计、文档化、复审、实现、演化等6个子过程。

绝大多数的体系结构都是抽象的,由一些概念上的构件组成。例如,层的概念在任何程序设计语言中都不存在。因此,要让系统分析员和程序员去实现体系结构,还必须将体系结构进行文档化。文档是在系统演化的每一个阶段,系统设计与开发人员的通信媒介,是为验证体系结构设计和提炼或修改这些设计(必要时)所执行预先分析的基础。

架构文档化过程的主要输出结果是架构需求规格说明和测试架构需求的质量设计说明书这两个文档。生成需求模型构件的精确的形式化的描述,作为用户和开发者之间的一个协约。

3.在基于体系结构的软件设计方法中,采用()来描述软件架构,采用()来描述功能需求,
采用()来描述质量需求。
A.类图和序列图 B.视角与视图 C.构件和类图 D.构件与功能
A.类图 B.视角 C.用例 D.质量场景
A.连接件 B.用例 C.质量场景 D.质量属性

在基于体系结构的软件设计方法中,通常采用以下方式来描述不同方面:

软件架构:使用B.视角与视图来描述软件架构。视角指的是从不同的角度观察和理解软件系统,而视图是这些角度的具体表示。视图可以包括类图、组件图、部署图等,用于展示系统的不同方面。

功能需求:通常使用C.用例来描述功能需求。用例是描述系统如何与外部实体(通常是用户)交互以实现特定目标或功能的场景描述。

质量需求:一般使用C.质量场景来描述质量需求。质量场景是描述系统在某种特定情况下满足某个质量属性的场景。质量属性可以包括性能、可靠性、安全性等方面的要求。

因此,正确的答案是:

在基于体系结构的软件设计方法中,采用B.视角与视图来描述软件架构,采用C.用例来描述功能需求,采用C.质量场景来描述质量需求。

总结要点

基于体系结构的软件设计(Architecture-Based Software Design,ABSD)方法是由体系结构驱动的,即指由构成体系结构的「商业、质量和功能需求」的组合驱动。

ABSD方法是一个自顶向下、递归细化的方法,软件系统的体系结构通过该方法得到细化,直到能产生软件「构件」和「类」。

ABSD设计活动从项目总体框架明确就开始,此时需求抽取和分析还没完成。

 要点1:  使用ABSD方法的3个基础
1. 功能的分解:使用已有的基于模块的内聚和耦合技术。

2. 选择架构风格:实现质量和业务需求。

3. 软件模块的使用:复用软件系统的结构。

 要点2:  视图与视角
视角与视图:描述系统的体系结构,体现关注点分离的思想。

静态视角:展示功能组织,判断质量特性。

动态视角:展示并发行为,判断行为特性。

 要点3:  用例和质量场景
描述软件架构:视角 + 视图

描述需求:用例(功能需求) + 质量属性场景(质量需求)

用例:用来捕获功能需求。

质量属性:通过定义特定场景来捕获质量需求。

要点4: 基于架构的开发模型
1. 架构需求:需求获取 -> 生成类图 -> 对类进行分组 -> 把类打包成构件 -> 需求评审

2. 架构设计:提出架构模型 -> 映射构件 -> 分析构件相互作用 ->产生架构 -> 设计评审

3. 架构文档化:体系结构规格说明 + 测试体系结构需求的质量设计说明书

4. 架构复审:标识潜在的风险,及早发现架构设计中的缺陷和错误。

5. 架构实现:分析与设计 -> 构件实现 -> 构件组装 -> 系统测试

6. 架构演化:制订演化计划 -> 增删改构件 -> 更新构件的相互作用 -> 构件组装与测试

1. 基于架构的软件设计(ABSD)强调由商业、质量和功能需求的组合驱动软件架构设计。ABSD方法有三个基础:功能分解、()和软件模板的使用。

A. 对需求进行优先级排列

B. 根据需求自行设计系统的总体架构

C. 选择架构风格实现质量及商业需求

D. 开发系统原型用于测试

正确答案:C。

解析:

本题考查ABSD的相关概念。

ABSD方法有三个基础:

(1)功能的分解。使用已有的基于模块的内聚和耦合技术。

(2)通过选择体系结构风格来实现质量和商业需求。

(3)软件模板的使用。软件模板是一个特殊类型的软件元素,包括描述所有这种类型的元素在共享服务和底层构造的基础上如何进行交互。软件模板还包括属于这种类型的所有元素的功能,这些功能的例子有:每个元素必须记录某些重大事件,每个元素必须为运行期间的外部诊断提供测试点等。

2. 某公司采用基于架构的软件设计(Architecture-Based Software Design,ABSD)方法进行软件设计与开发。ABSD方法有三个基础,分别是对系统进行功能分解、采用()实现质量属性与商业需求、采用软件模板设计软件架构。

ABSD方法主要包括架构需求等6个主要活动,其中:()活动的目标是标识潜在的风险,及早发现架构设计中的缺陷和错误;()活动针对用户的需求变化,修改应用架构,满足新的需求。

小王是该公司的一位新任架构师,在项目中主要负责架构文档化方面的工作。小王()的做法不符合架构文档化的原则。架构文档化的主要输出结果是架构规格说明书和()。

第1空

A. 架构风格

B. 设计模式

C. 架构策略

D. 架构描述

正确答案:A。

第2空

A. 架构设计

B. 架构实现

C. 架构复审

D. 架构演化

正确答案:C。

第3空

A. 架构设计

B. 架构实现

C. 架构复审

D. 架构演化

正确答案:D。

第4空

A. 从使用者的角度书写文档

B. 随时保证文档都是最新的

C. 将文档分发给相关人员

D. 针对不同背景的人员书写文档的方式不同

正确答案:B。

第5空

A. 架构需求说明书

B. 架构实现说明书

C. 架构质量说明书

D. 架构评审说明书

正确答案:C。

解析:

ABSD方法有3个基础。第一个基础是功能的分解。在功能分解中,ABSD方法使用已有的基于模块的内聚和耦合技术。第二个方法是通过选择体系结构风格来实现质量和业务需求。第三个基础是软件模板的使用。软件模板利用了一些软件系统的结构。

论文

论基于架构的软件开发方法在新媒体平台系统的实践

摘要

2023年03月,我所在的团队承接了某大学的媒体中心委托的《新媒体平台》的开发,我在项目中担任系统架构师,主要完成技术方案评估与实现,项目立项论证等工作。该系统以文章阅览功能为核心,分为文章搜索模块、用户评论模块、文章审核模块、用户管理模块、社团管理模块等。本文结合作者的实践,以《新媒体平台》为例,采用SpringCloud微服务架构,讨论基于架构的软件设计方法在项目中的具体应用,架构需求获取、架构需求设计和架构需求实现三个阶段。在架构需求获取阶段通过问卷调查和用户访谈等方式全面获取需求;在架构设计阶段使用了UML4+1视图进行建模设计;在架构实现阶段对系统构件进行获取、开发和组装。最终项目顺利上线并稳定运行,获得用户一致好评。

正文

随着移动信息化技术的迅猛发展,自媒体平台日益增多,各种平台之间的切换十分繁琐,每次都要在不同的平台发布同一内容,不利于媒体中心实时发布信息和全校师生阅览且不便于管理,而校官网又不便于发布日常文章。为了解决这一问题,校媒体中心制定了校园专属媒体平台战略,根据这一战略要求,新媒体平台(以下简称为“NMS”系统)应运而生,将全校院系社团的动态集中于该系统上,降低了全校师生对文章内容的检索难度,使师生可以快速准确地了解学校的最新动态。NMS系统以文章阅览功能为核心,分为文章搜索模块、用户评论模块、文章审核模块、用户管理模块等。文章搜索模块主要负责为用户提供检索文章的接口;用户评论模块负责对于各个文章中不同用户的评论内容的管理;文章审核模块允许管理员对申请发布的文章内容合法性进行审核;用户管理模块负责对以注册的用户信息进行管理;社团管理模块提供各院系社团管理自己发布内容的功能。2021年12月,我有幸参与了项目前期的一些工作,担任系统架构设计师的职务,主要负责设计平台系统架构和安全体系架构。

基于架构的软件设计方法(ABSD)包括架构需求、架构设计、架构文档化、架构复审、架构实现和架构演化六个阶段。架构需求阶段明确用户对系统在功能、行为、性能、设计约束等方面的期望,包括需求获取、标识构件和架构评审;架构设计阶段根据需求生成并调整架构决策,包括提出架构模型、上映射构件、分析构件相互作用、产生架构和评审;架构文档化阶段对架构设计分析与整理,产生架构规格说明书和架构质量说明书;架构复审阶段评价架构能和否满足需求与实现质量属性层次构件划分是下合理,标识潜在的风险,及早发现设计中的缺陷错姓;架构实现阶段对架构进行实现,包括架构分析与设计、构件实现、组装和系统测试;架构演化阶段主要解决开发中用户需求变更问题,包括架构演化计划、构件变动、更新构件相互作用、构件组装测试与技术评审。

在架构需求获取阶段遇到的主要问题是NMS平台需要为全校师生进行服务,这就需要有效、快速地全面获取需求。在需求的前期阶段,我们采用了用户面对面访谈和线上问卷调查的方式,把需求调研团队分成了几组,分别进行需求收集。通在与各个院系、社团的负责人面对面访谈,我们对NMS的主要业务功能、用户角色有了整体、全面的了解。并且在线上向全校师生发布问卷调查的来获取需求,经统计,我们了解了NMS在与用户交互时的更多细节。在需求获取的中期阶段,我们分析了市面上多种社交媒体平台,了解了系统在具体使用时的基本操作逻辑。

随后我们召开小组会议对需求进行了整理和优先级判定,用户对系统的性能抱有较高的要求,希望不要像教务系统一样在接受到大量访问的时候便出现卡顿崩溃的现象;其次是用户希望对于自身的隐私有较好的保障;最后用户希望在使用过程中操作流畅,性能要好。

在架构设计阶段我们要有效合理地设计和描述软件架构,对于系统我们首先要实现用户可以在不同场景下应用;其次系统应该具有文章推送、文章订阅、文章评论、文章发布以及系统管理等多项基础功能;最后为确保盈利,系统应该支持第三方商家的广告推广功能。经过我们讨论分析,决定采用层级结构架构风格开发,使用MVC模型将系统分为表示层、负载均衡层、控制层和持久层。表示层用于前端和用户进行交互;负载均衡层对请求进行处理和转发;控制层为请求做出相应;持久层负责数据存储和处理。对于用户们最关心的系统可用性方面,我们将采用容器化技术来实现,设置多个从节点,一旦主节点发生故障,立刻选举从节点成为新的主节点,同时将容器调度到新的主节点上,防止系统崩溃;建立完善的日志记录和监控系统保证系统的安全性;采用负载均衡技术提高系统的性能,增加可扩展性。

在架构实现阶段我们着重聚焦于系统构件的实现和组装。在NMS系统中使用Nginx作为前端服务器处理静态资源的请求并使用IP哈希算法将请求转发给后端的多个实例,并在每个服务实例中嵌入ribbon库使用轮询算法对其内部实现负载均衡,确保在高并发应用场景下的系统仍具有较好的性能。Spring Cloud Gateway作为API网关入口在后端服务器负责路由请求到相应的后端服务。使用zabbix对系统进行实时监控,记录关键事件、用户活动和系统行为。定期检查日志和监控数据,及时发现异常行为和安全事件,并采取相应的措施进行调查和应对,保证系统的安全性。我们还对系统使用了docker容器技术进一步提高系统的高并发和高可用性,将每一个后端服务打包部署在独立的容器中实现良好的伸缩性;配置编排工具对容器进行健康检查,实现对故障容器实例的停止和重启功能,确保高可用性和稳定性;将数据存储在外部持久化存储卷中,防止由于容器实例故障破坏数据的完整性。

在架构决策阶段,我所选择的这种架构得到了集团领导的认可和采纳,2024年6月,新媒体平台系统正式上线运行,至今已稳定运行。系统平稳经历了访问量激增、大量活动上线、紧急应用接入等复杂运维状况,系统所采用的基于架构的软件开发方法在软件开发的初期团队便可以进行讨论写作,确保了团退队开发目标拥有共同的理解,并且可以更早的考虑到系统的可维护性和可扩展性,有效的提高了软件开发效率,降低了风险管理的成本,获得了领导和同事的好评。但是在系统运行过程中,我也发现了这种架构存在的一些不足。因为过早的确定了系统的整体架构风格,因此在中期出现了小幅的需求变更的时候我们有在是否进行架构风格的更改问题上进行了多次的讨论,由于设计变更的难度增加,对项目的开发进度有了一定的负面影响。基于架构的软件开发方法所具有的优点和面临的问题将是我今后在同类系统的架构决策方面需要重点考虑因素。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐