软件工程复习

软件工程

  • 软件的概念

    软件是计算机系统的重要组成部分

    软件是逻辑产品,需要计算机硬件和系统软件的支撑

    软件是计算机控制系统的指挥中枢

    软件是信息转换器,它能对信息进行加工、处理或变换

    软件是工具,在人们的生活、工作、休闲,在社会的经济、军事、政治、文化、科学技术、教育中发挥巨大作用

  • 软件的特点

    软件是能够完成预定功能和性能,并对相应数据进行加工的程序和描述程序及其操作的文档。

    软件=程序+数据+文档

    程序=算法+数据结构

    文档:自然语言,结构化英语,图表

    数据:用程序设计语言要求的数据结构表示

  • 软件发展的四个阶段

    • 1950-1965:没有系统的软件开发方法和管理机制、自定义软件、批处理、有限分布
    • 1965-1975:产生人机交互的新概念、新技术软件产品、多用户、实时、数据库
    • 1973-1988:微处理器的出现并广泛应用,分布式系统、嵌入智能、低成本硬件、消费者的影响
    • 1986-至今:互联网、局域网、移动互联网迅速普及,AI快速发展
  • 软件发展的四个重要阶段

    1. 传统的软件工程:

      60年代末到70年代初为了克服“软件危机”提出“软件工程”的名词,将软件开发纳入工程化的轨道,基本形成软件工程的概念、框架、技术和方法,称为传统的软件工程。

    2. 对象工程:

      80年代中到90年代,面向对象的方法与技术得到发展,研究的重点转移到面向对象的分析与设计,演化为一种完整的软件开发方法和系统的技术体系,称为对象工程。

    3. 过程工程:

      80年代中开始,人们在软件开发的实践过程中认识到:提高软件质量的关键是“软件过程”,是软件开发和维护中的管理和支持能力,逐步形成软件过程工程。

    4. 构件工程:

      90年代起,基于构件的开发方法取得重要进展,软件系统的开发可通过使用现成的可复用构件组装完成,而无需从头开始构造,以此达到提高效率和质量、降低成本的目的。称为构件工程。

  • 软件危机

    软件危机是软件开发和维护过程中遇到的一系列严重问题。

    原因:

    1. 软件的规模加大、复杂性提高、性能增强
    2. 软件是逻辑产品,尚未完全认识其本质和特点
    3. 缺乏有效的、系统的开发,以及维护大型软件项目的技术手段和管理方法
    4. 用户对软件需求的描述与软件开发人员对需求的理解往往存在差异,用户经常要求修改需求,开发人员很难适应
    5. 软件开发的技术人员和管理人员缺乏软件工程化的素质和要求,对工程化的开销认识不足
  • 软件工程过程

    在软件工具的支持下所进行的一系列软件开发和进化的活动。

    包括4类基本过程:

    软件规格说明

    软件开发

    软件确认

    软件演进

  • 软件的生存周期

    每个软件从定义到开发、使用和维护,直到最终被废弃,要经历一个漫长的时期,通常把软件经历的这个漫长的时期称为生存周期。软件生存周期就是从提出软件产品开始,直到该软件产品被淘汰的全过程。它包括制定计划、需求分析、软件设计、程序编写、软件测试、运行维护等

  • 软件生命周期各阶段及其基本任务

    问题定义:产生目标与范围说明书

    可行性研究:产生可行性论证报告

    需求分析:产生需求说明书

    软件设计:分为总体设计和详细设计,产生设计文档

    编码:编写软件的程序

    测试:测试程序,产生测试报告

    运行与维护:产生维护报告

  • 软件开发模型

    描述软件开发过程中各种活动如何执行的模型,因此又称为软件过程模型。是对软件开发实际过程的抽象和简化。

    不同的开发方法有不同的软件过程模型。

  • 瀑布模型

    特点:

    • 软件开发过程与软件生命周期是一致的
    • 相邻二阶段之间存在因果关系
    • 需要对阶段性产品进行评审

    优点:

    • 是软件生命周期模型,使软件开发过程可以在分析、设计、编码、测试、维护的框架下进行,每个阶段都有输出产物,是一个很经典的模型
    • 软件开发过程具有系统性、可控性,克服了软件开发的随意性

    缺点:

    • 项目开始阶段用户很难精确地提出产品需求,由于技术进步、用户对系统深入的理解,修改需求十分普遍。每个阶段都依赖于上一阶段,不能应对客户需求变更。项目开发晚期才能得到程序的运行版本,这时修改软件需求和开发中的错误代价很大。
    • 采用线性组织模型进行项目开发经常发生小组人员“堵塞状态”,特别是项目的开始和结束阶段
  • 增量模型

    在前面增量的基础上开发后面的增量

    每个增量的开发可用瀑布或快速原型模型

    迭代的思路,具有较大的灵活性,适合于软件需求不明确、设计方案有一定风险的软件项目。

  • 螺旋模型

    融合了原型模型(原始版本)瀑布模型(各个阶段)演化模型(逐步完善),引入了风险分析。

  • 螺旋模型作用

    螺旋模型沿着螺线进行若干次迭代,四个象限分别代表以下活动:

    • 确立目标、方案和限制条件
    • 评估方案、标识风险和解决风险
    • 开发确认产品
    • 计划下一阶段的工作
  • 螺旋模型的使用

    第一圈:产生产品规格说明

    第二圈:产生一个用于开发的原型

    第三圈:产生软件产品的初始版本

    第四圈:产生软件产品的一个较为完善的版本

  • 螺旋模型的优点

    1. 符合人们认识现实世界和软件开发的客观规律
    2. 支持软件的整个生命周期
    3. 保持了瀑布模型的系统性、阶段性
    4. 利用原型评估降低开发风险
    5. 开发者和用户共同参与软件开发,尽早发现软件中的错误
    6. 不断推出和完善软件版本,有助于需求变化,获取用户需求,加强对需求的理解
  • 原型模型

    优点:

    1. 可及早为用户提供有用的产品
    2. 可及早发现问题,随时纠正错误
    3. 减少技术、应用风险,缩短开发时间,减少费用、提高生产率
    4. 加强了信息反馈

    缺点:

    1. 缺乏丰富而强有力的软件工具和开发环境
    2. 缺乏有效的管理机制,还未建立起自己的开发标准
    3. 对设计开发环境要求较高
    4. 在多次重复改变原型的过程中,程序员会感到厌倦
    5. 系统的易变性对测试有一定影响,难以做到彻底测试,更新文档较为困难

    适用范围:软件需求不明确、设计方案有一定风险的软件项目

  • 喷泉模型

    面向对象的模型,体现来迭代和无缝的特性。

  • McCabe复杂度度量

    V(G) = 边数 - 节点数 + 2

  • 需求分析的三个层次包括哪些主要内容

    软件需求包括三个不同的层次:业务需求、用户需求、功能需求,

  • 需求分析的基本活动

    获取需求:深入实际,在充分理解用户需求的基础上,获取系统需求

    需求分析与建模:进行需求建模,对原型和模型进行分析

    确认需求:确保需求说明准确、完整地表达系统的主要特性

    进化需求:客户的需要总是不断增长的

  • 需求分析的作用

    在传统软件工程生命周期中,涉及需求的阶段称为需求分析。

    作用:

    • 定义软件的范围及必须满足的约束
    • 确定软件的功能和性能及与其他系统成分的接口
    • 建立数据模型、功能模型和行为模型
    • 最终提供需求规格说明,并用于作为评估软件质量的依据
  • 需求分析常用技术

    • 分解:将大问题分解为小问题,通常是自顶向下、逐步细化的过程

      • 自顶向下、逐步细化

        就是将软件的体系结构按照自顶向下的方法,对各个层次的过程细节和数据细节逐层细化,直到可以用程序设计语言的语句实现,最终确立整个的体系结构。

    • 抽象:根据问题的本质特征,从不同的抽象层次进行分析,提出解决方案

    • 多视点:从各类开发人员和不同用户的角度考虑问题,才能获得对系统的全面完整的需求

  • 需求的有效性验证

    • 有效性检查:功能需求是否符合用户所提出的需求
    • 一致性检查:系统功能描述及约束是否一致
    • 完备性检查:是否包含所有系统用户的需求和约束
    • 可检验性检查:是否能设计出一组验证方法,确定了检验的标准
  • 需求分析方法

    • 功能分解方法

      将系统看作若干功能模块的集合,每个功能又可以分解为子功能,子功能还可以继续分解,分解的结果即是系统的雏形

      • 存在的问题
        • 需要人工完成
        • 无法对描述的准确度进行验证
        • 难以适应需求的变化
    • 结构化分析方法

      结构化分析方法给出一组帮助系统分析人员产生功能归约的原理与技术。它一般利用图形表达用户需求,使用的手段主要有数据流图、数据字典、结构化语言、判定表、判定树等。

      数据流图是SA方法中用于表示逻辑系统模型的一种工具。它从数据传递和加工的角度,以图形的方式来刻画数据流从输入到输出的变换过程。

      建立:当前系统具体模型

      抽象:当前系统逻辑模型(分析用户需求,用DFD图描述)

      建立:目标系统逻辑模型(分析用户需求,用DFD图描述)

      改进:完善的系统逻辑模型

      • 结构化描述方法

        SA法的描述方法:

        1. 数据流图DFD

        2. 数据词典

          • 数据流条目:列出该数据流的组成数据项

          • 数据项条目:给出某个数据单项的定义,包括值类型和取值范围

          • 文件条目:列出文件记录的组成数据流

          • 加工条目:“加工说明”,给出加工的精确描述。包括加工的激发条件、加工逻辑、优先级、执行频率和出错处理

            对基本加工说明的描述方式:结构化语言、判定表、判定树

        3. 描述加工逻辑的结构化语言、判定表及判定树

          结构化语言:

          顺序结构

          选择结构:IF-THEN-ELSE, CASE-OF-ENDCASE

          循环结构:WHILE-DO, REPEAT-UNTIL

    • 面向对象分析方法

      面向对象分析方法(OOA)的关键是识别问题域内的对象,分析它们之间的关系,并建立起三类模型:

      • 功能模型
      • 对象模型
      • 动态模型
  • SA的基本思想

    分解和抽象

  • 数据词典的写法

    x = [a|b], x = [a, b]:x由a或b构成

    m{…}n, {…}:m和n的默认值是0和∞,{}内的内容可重复m到n-1次

    (…):可选项

    𝑆𝑡𝑢𝑑𝑒𝑛𝑡𝐸𝑛𝑡𝑖𝑡𝑦=𝑠𝑡𝑢𝑑𝑒𝑛𝑡𝐼𝐷+𝑠𝑡𝑢𝑑𝑒𝑛𝑡𝑁𝑎𝑚𝑒+𝑠𝑡𝑢𝑑𝑒𝑛𝑡𝐼𝐷𝐶𝑎𝑟𝑑+𝑠𝑡𝑢𝑑𝑒𝑛𝑡𝑆𝑒𝑥+{𝑠𝑡𝑢𝑑𝑒𝑛𝑡𝐼𝑛𝑡𝑒𝑟𝑒𝑠𝑡}+(𝑠𝑡𝑢𝑑𝑒𝑛𝑡𝐼𝑛𝑓𝑜)

    𝑠𝑒𝑙𝑒𝑐𝑡𝑅𝑒𝑞𝑢𝑒𝑠𝑡𝐼𝑛𝑓𝑜=[𝑠𝑒𝑙𝑒𝑐𝑡𝑆𝑡𝑢𝑑𝑒𝑛𝑡𝐼𝑛𝑓𝑜 | 𝑠𝑒𝑙𝑒𝑐𝑡𝐶𝑜𝑢𝑟𝑠𝑒𝐼𝑛𝑓𝑜 | 𝑠𝑒𝑙𝑒𝑐𝑡𝑆𝑡𝑢𝑑𝑒𝑛𝑡_𝐶𝑜𝑢𝑟𝑠𝑒𝐼𝑛𝑓𝑜]+{𝐼𝑙𝑙𝑒𝑔𝑎𝑙𝑅𝑒𝑞𝑢𝑒𝑠𝑡}


    数据流名称:取款单、存款单

    别名:无

    简述:顾客存/取款时填写的单据

    来源:顾客

    去向:核查

    数据流量:200份/天

    组成:日期+[取|存款金额]+姓名+地址+[存|取款类型]+密码+{账号}


    数据流名称

    别名

    简述

    来源

    去向

    数据流量

    组成


    数据存储(文件)名称:帐卡

    别名:无

    简述:存放用户信息及存取款情况

    组成:储户姓名+储户地址+账号+日期+[存/取款金额]+存款类型+利率+密码+操作员

    组织方式:数据文件,以储户姓名或账号为关键字进行索引

    查询要求:能立即查询并修改


    数据存储(文件)名称

    别名

    简述:这个文件存储的是什么

    组成:由哪些数据流组成

    组织方式:数据文件,以…为关键字进行索引

    查询要求:查询后是否能修改、是否有读写权限


    数据项名称:存款类型

    别名:无

    简述:国家规定的几类存款方式

    类型:字符串

    长度:2位

    取值范围及含义:00:定期,01:零存整取,10:活期,11:定/活两便


    数据项名称

    别名

    简述

    类型

    长度

    取值范围及含义


    加工名:核查

    编号:1

    激发条件:接受存款单或取款单

    输入:存款单或取款单

    输出:审查认定后合格的存/取款信息

    加工逻辑:根据帐卡及用户存/取款单据

    1
    2
    3
    4
    if 单据 == 存款单 then
    ...
    else
    ...
  • 软件体系结构

    软件体系结构确定了系统的组织结构和拓扑结构,显示了系统需求和构成系统的元素之间的对应关系,提供了一些设计决策的基本原理。

    软件体系结构设计:系统分解、控制建模、模块分解

    几种典型的软件体系结构:

    • 仓库模型

      一种集中式的模型。各子系统可以直接访问中央数据库中的共享数据。子系统间紧密耦合。

      子系统可以有自己的数据库。子系统之间通过消息传递进行数据交换。

      • 优点
        1. 共享大数据量的有效方法
        2. 子系统不必关系其他子系统如何使用它产生的数据
        3. 易于将新子系统合成,如果新子系统也采用相同的规范
      • 缺点
        1. 为了共享数据,子系统必须有一致的数据视图,影响了系统的性能
        2. 子系统的改变,使产生的数据结构也会发生改变
        3. 统一的数据结构会影响子系统的效率
    • 客户机/服务器模型

      采用发请求、得结果的模式。

    • 分布式对象模型

    • 抽象机模型

    • 控制模型

  • 软件设计准则

    • 软件结构的准则

      软件结构就是软件的系统结构,是模块间关系的表示,均表示为层次结构。

      • 指标
        • 深度:软件结构中从最顶层模块到最底层模块的层数
        • 宽度:表示控制的总分布
        • 扇入数:一个模块的直接上属模块个数
        • 扇出数:一个模块直接控制下属的模块个数

      好的软件结构的形态是:顶部宽度小,中部宽度大,底部宽度次之;结构顶部有较高的扇出数,底部有较高的扇入数。

    • 模块化准则

      模块:又称“构件”,一般指用一个名字调用的一段程序。

      模块化准则:按适当的原则将软件划分为一个个较小的、相关而又相对独立的模块。这些模块集中起来组成一个整体,可以满足所要求的整个系统的功能。模块化能够降低软件的复杂度,需要注意选择分解的最佳模块数。

    • 软件独立性准则

      模块的独立性是指软件系统中的每个模块只涉及软件要求的具体的子功能,而和软件系统中其他模块的接口是简单的。这种类型的模块可以并行开发,减少错误的影响,使模块容易组合、修改及测试。

      • 内聚

        由高到低:模块独立性也由高到低

        功能内聚、信息内聚、通信内聚、过程内聚、时间内聚、逻辑内聚、巧合性内聚

      • 耦合

        由低到高:

        非直接耦合、数据耦合、标记耦合、控制耦合、外部耦合、公共耦合、内容耦合

  • 高内聚低耦合

    软件设计的目标就是建立一个高内聚低耦合的软件模型。

    内聚:模块内部各功能之间联系的紧密程度

    耦合:模块之间联系的紧密程度

    高内聚低耦合:提高模块内部的联系的紧密程度,降低模块之间的联系的紧密程度。

    • 举例
      • 实现低耦合
        • 少使用类的继承,多用接口隐藏实现的细节。例如Java面向对象编程引入接口除了支持多态外,隐藏实现细节也是其中一个目的。
        • 一个定义只在一个地方出现
        • 少使用全局变量
        • 少用公有类,多用私有类
        • 尽量不用“硬编码”的方式写程序
      • 实现高内聚
        • 模块只对外暴露最小限度的接口,形成最低的依赖关系
        • 只要对外接口不变,模块内部的修改就不得影响其他模块
        • 删除一个模块,应当只影响有依赖关系的模块,而不影响其他无关的部分
  • 结构化设计方法(软件结构图)

    结构化设计(SD)是以结构化分析(SA)产生的数据流图为基础,将数据流图按一定的步骤映射成软件结构图(SC)。

    这里的软件结构图和下面的模块结构图是一个东西

    结构化设计的目的是要把数据流图映射成软件结构,根据数据流的特性,一般可分为变换型数据流图和事务型数据流图。

    SD法的两个阶段:

    • 总体设计:分解模块,确定模块的层次,模块结构图
    • 详细设计:对模块的过程进行描述,流程图、N-S图、PAD图

    SD法的步骤:

    1. 从DFD图导出初始的模块结构图(SC)。
      • 中心变换型
      • 事务处理型
    2. 按照SD法设计总则,改进模块结构图。
    • 中心变换型的DFD图

      “输入-处理-输出”三部分

      变换分析

    • 事务处理型DFD图

      有一个数据处理中心,按加工结果选择一个数据流继续执行。

      事务分析

  • 选择程序设计语言的一般准则

    1. 项目的应用领域。
    2. 算法和计算复杂性。
    3. 软件的执行环境。
    4. 性能因素。
    5. 数据结构的复杂性。
    6. 软件开发人员的知识水平及心理因素。
  • 结构化程序设计特点

    1. 自顶向下、逐步求精。这种逐步求精的思想符合人类解决复杂问题的普遍规律,从而可以显著提高软件开发的效率。体现了先全局后局部、先抽象后具体的方法,使开发的程序层次结构清晰,易读、易理解还易验证,因而提高了程序的质量。
    2. 单入口和单出口的控制结构:结构化的程序由且仅由顺序、选择、循环三种基本控制结构组成,既保证了程序结构清晰,又提高了程序代码的可重用性。
  • 影响程序效率的因素

    1. 算法对效率的影响
    2. 存储效率
    3. 输入输出效率
  • 软件测试的对象

    软件测试不等于程序测试。软件测试应贯穿于软件定义与开发的整个期间。因此,需求分析、概要设计、详细设计、程序编码等所得到的文档资料,包括需求规格说明、概要设计说明、详细设计规格说明以及源程序,都应成为软件测试的对象。

  • 测试与软件开发阶段的关系

    软件开发过程是一个自顶向下、逐步细化的过程,而测试是自底向上、逐步集成的过程。

  • 黑盒测试

    不考虑程序的内部结构和特性,仅根据程序的功能和外部特性设计测试用例。

  • 黑盒测试的设计策略

    根据被测程序功能来进行测试。也称为功能测试。

    1. 等价分类法
    2. 边界值分析
    3. 错误猜测法
    4. 因果图法
  • 白盒测试

    利用程序内部的逻辑结构和有关信息设计测试用例,对程序的所有逻辑路径进行测试。

  • 白盒测试的设计策略

    1. 逻辑覆盖法

      采用流程图来设计测试用例,考察重点是图中的判定框,因为这些判定通常与选择或循环结构有关。

      • 语句覆盖
      • 判定覆盖
      • 条件覆盖
      • 判定/条件组合覆盖
      • 条件组合覆盖
    2. 路径测试法

  • 软件维护

    软件系统交付使用以后,为了改正错误或满足新的需求而修改软件的过程。

  • 软件维护的类型

    纠错性维护、适应性维护、完善性维护、预防性维护

  • 软件维护的技术

    1. 面向维护的技术

      在软件开发阶段用来减少错误,提高软件可维护性的技术。涉及到软件开发的所有阶段。

    2. 软件支援技术

      在软件维护阶段用于提高维护工作的效率和质量的技术。主要用到测试阶段的技术。

  • 结构化方法的优缺点

    优点:

    1. 整体思路清晰,目标明确
    2. 设计工作中阶段性非常强,有利于系统开发的总体管理和控制
    3. 在系统分析时可以诊断出原系统中存在的问题和结构上的缺陷

    缺点:

    1. 用户难以在分析阶段准确定义,使得系统交付时产生许多问题
    2. 用系统开发每个阶段的成果来进行控制,不能适应事物变化的要求
    3. 系统的开发周期长
  • 面向对象技术的特点

    1. 认为客观世界是由各种对象组成的,任何事物都是对象,复杂的对象可以由比较简单的对象以某种方式组合而成。
    2. 把所有对象都划分为各种对象类,每个对象类都定义了一组数据和一组方法。
    3. 按照子类和父类的继承关系,把若干个对象类组成一个层次结构的系统。
    4. 对象彼此之间仅能通过传递消息互相联系。

    OO = Objects + Classes + Inheritance + Communication with message

    面向对象 = 对象 + 类 + 继承 + 传递消息

  • 面向对象的概念

    • 对象

      定义:

      1. 从面向对象程序设计角度,对象是具有相同状态的一组操作的集合。

      2. 从信息模拟角度,对象是对问题域中某个东西的抽象,这种抽象反映了系统保存有关这个东西的信息或与它交互的能力。(对象是对属性值和操作的封装)

      3. 形式化定义:

        对象 ::=

        ID:对象的标识或名字

        MS:对象中的操作集合

        DS:对象的数据结构

        MI:对象受理的消息名集合

      特点:

      • 以数据为中心
      • 对象是主动的
      • 实现了数据封装
      • 本质上具有并行性
      • 模块独立性好
    • 类是对具有相同数据和相同操作的一组相似对象的定义,是对具有相同属性和行为的一个或多个对象的描述。

    • 继承

      指直接获得已有的性质和特征,而不必重复定义它们。

      在面向对象的软件技术中,继承是子类自动地共享基类中定义的数据和方法的机制。

    • 消息

      就是要求某个对象执行在定义它的那个类中所定义的某个操作的规格说明。

      通常一个消息由3部分组成:

      • 接受消息的对象
      • 消息选择符(消息名)
      • 零个或多个变元

      例如,

      1
      MyCircle.show("Green");

      MyCircle是接收信息的对象

      show是消息选择符

      “Green”是消息的变元

    • 多态性

      概念:

      • 一个父类包含一个被子类覆盖的方法
      • 通过一个父类的引用值来引用其不同的子类对象
      • 父类引用在调用被覆盖方法时,不同子类对象的方法将会执行

      目的:

      增加了面向对象软件系统的灵活性,进一步减少了数据冗余,显著提高了软件的可重用性和可扩充性

  • RUP

    统一软件开发过程:用例驱动,以体系结构为中心,迭代,增量的软件开发过程。包括4个阶段:初始、精化、构建、交付

  • 类图

    用户根据用例图抽象成类,描述类的内部结构和类与类之间的关系,是一种静态结构图。

  • 类与类之间的关系

    泛化 = 实现 > 组合 > 聚合 > 关联 > 依赖

    • 泛化

      是一种继承关系,表示一般与特殊的关系,指定了子类如何继承父类的所有特征和行为。

    • 实现

      是一种类与接口的关系,表示类是接口所有特征和行为的实现。

    • 组合

      是整体和部分的关系,且部分不能离开整体而单独存在。(因此比聚合关系要强)

      菱形要涂黑

    • 聚合

      是整体和部分的关系,且部分可以离开整体而单独存在。

    • 关联

      是一种拥有的关系,使一个类知道另一个类的属性和方法。

    • 依赖

      是一种使用的关系,即一个类的实现需要另一个类的协助。

      指向被使用者。

图表📈

数据流图

软件结构图(DFD转换而来)

流程图、N-S图、PAD图

用例图、类图、时序图

名词解释

  • CMM

    答:即软件能力成熟度模型,是由美国卡内基-梅隆大学软件工程研究所(CMU/SEI)推出的评估软件能力与成熟度的一套标准,该标准基于众多软件专家的实践经验。CMM侧重于软件开发过程的管理及工程能力的提高与评估,是国际上流行的软件生产过程标准和软件企业成熟度等级认证标准,它更代表了一种管理哲学在软件企业中的应用。

  • UML

    统一建模语言,是一种标准的图形化建模语言。

    主要用于软件的分析与设计,用定义完善的图形符号来图形化地展现一个软件系统。

    是基于面向对象技术的标准建模语言。

  • 软件和软件工程

    软件:能够完成预定功能和性能,并对相应数据进行加工的程序和描述程序及其操作的文档。

    软件工程:为了克服软件危机,在软件的开发过程中采用工程化的方法,采用一系列科学的、现代化的方法和技术开发软件,将工程化的思想贯穿到软件开发和维护的全过程。

Author

preccrep

Posted on

2021-11-14

Updated on

2021-11-14

Licensed under

You need to set install_url to use ShareThis. Please set it in _config.yml.
You forgot to set the business or currency_code for Paypal. Please set it in _config.yml.

Comments

You forgot to set the shortname for Disqus. Please set it in _config.yml.
You need to set client_id and slot_id to show this AD unit. Please set it in _config.yml.