面向对象软件工程

1.理解如下术语:子系统;类;服务;子系统接口;耦合;内聚;分层;划分;软件体系结构;软件体系结构风格;构件;逻辑构件;物理构件。

  • 子系统:一个较大的软件系统可以被划分为若干个相互独立的子系统,每个子系统专注于解决某一特定的问题域。

  • 类:一个类是一个抽象的概念,用于描述某一类具有相同属性和方法的对象。

  • 服务:服务是用来完成某种功能或提供某种服务的可交互软件模块,它们通常通过网络进行通信,并且具备良好的灵活性和可扩展性。

  • 子系统接口:子系统接口定义了子系统与其他系统或子系统之间的通信协议和数据格式,以及访问子系统所需的权限和凭证。

  • 耦合:耦合指两个或多个软件组件之间的关系,如果这些组件彼此依赖程度高,那么它们就是紧密耦合的。

  • 内聚:内聚指一个软件组件内部各个模块之间的联系程度,如果这些模块都是为实现同一目标而存在的,那么它们就是高内聚的。

  • 分层:分层是一种常见的软件体系结构,在这种结构中,整个系统被分为若干层,每层都提供一定的服务并消费下一层提供的服务。

  • 划分:系统划分是将系统按照一定规则切分为若干个模块或子系统的过程,其目的是提高软件的可维护性、可扩展性和可重用性。

  • 软件体系结构:软件体系结构是指系统中各个组件之间的关系及其约束条件,包括组件的种类、属性、接口、交互方式等。

  • 软件体系结构风格:软件体系结构风格是指一种特定的软件体系结构模式,它包含了一些常见的组件类型、连接方式和通信规则。

  • 构件:构件是系统中的一个模块或部件,它可以被单独设计、开发、测试和部署,并且具有明确的职责和接口。

  • 逻辑构件:逻辑构件是指系统中的一个抽象概念,表示系统中的某个功能单元,例如订单管理、库存管理等。

  • 物理构件:物理构件是指系统中的一个具体实现单元,例如一个独立的服务器、一个数据库等。

2.如何理解“有两种构造系统设计的方法:一是使设计足够简单以至不存在明显的缺陷,二是使系统足够复杂以至不存在明显的缺陷。”

这句话表达了一个经典的软件设计哲学,即:设计应该足够简单以至于很难出现明显的缺陷,但同时也要足够复杂以至于很难出现明显的缺陷。

第一部分强调了在设计阶段应该尽可能地去简化系统结构和逻辑,遵循KISS(Keep It Simple, Stupid)原则来排除设计中的常见错误和漏洞。在这种情况下,开发人员需要关注基本的问题和需求,并且尽量避免使用过度复杂的解决方案。这将有助于减少代码错误与问题。

而第二部分则意味着,尽管设计必须简单(因为简单性更易维护和修改),但是设计不能过于简单。如果系统设计过于简单,那么就会存在各种风险和漏洞点,容易被攻击者利用或出现其他未知问题,因此对系统进行更多的测试、修复和改进是非常必要的。

因此,在软件工程中,我们应该寻求一个平衡点,使得软件系统简单、高效、易于扩展和维护,同时还能覆盖大部分使用场景,实现核心功能,确保系统安全性。

3.简述什么是系统设计?

系统设计是指在开发软件或硬件系统时,对系统进行规划和设计的过程。

4.系统设计与算法有关,对吗?

系统设计中,需要考虑到许多方面的算法,包括但不限于数据结构、搜索算法、排序算法、分布式算法、存储算法等等,这些算法是实现系统功能所必需的。

5.系统设计中要考虑的选择需面对什么样的状态?

  • 正常状态:系统正在以正常的方式运行,没有出现错误或异常状况。
  • 边界状态:系统处于某个边缘条件,例如输入数据接近极限值、网络带宽达到最大值等等。
  • 异常状态:系统出现了某种错误或异常情况,例如文件读取失败、数据库连接中断等等。
  • 并发状态:系统需要支持多个并发请求,要确保线程安全和资源共享正确性。
  • 扩展状态:系统需要支持扩展,能够容易地添加新的功能、处理更多的数据或支持更多的用户。 可维护状态:系统需要易于维护,代码结构清晰,注释完善,易于修改和扩展。
  • 安全状态:系统需要具备安全性,能够防止恶意攻击和数据泄漏等问题。

6.简述系统设计中的主要活动。

需求分析:对用户需求与项目目标进行分析,定义系统范围和功能需求。

概念设计:制定系统的整体架构和组成部分,确定模块之间的关系以及数据流向。

详细设计:对每个组成部分进行详细设计,包括算法实现、数据结构、界面设计等方面。

构建和测试:根据设计方案进行编码实现,随后进行单元测试、集成测试和系统测试等多个阶段的测试,确保系统性能和稳定性。

部署和维护:将系统发布到生产环境中运行,并进行维护和升级,包括故障排除、安全保证、性能优化等方面。

文档编写:撰写代码注释、用户手册、技术文档等相关文档,方便项目管理和技术支持。

团队协作:系统设计过程需要多个角色协同配合完成,如项目经理、需求分析师、架构师、开发人员、测试人员、文档编写人员等,需要高效沟通和合作。

7.与系统设计过程的设计对象模型相比,分析对象模型不包含什么?

  • 技术实现细节,如具体的算法、数据结构、编码方式等。

  • 物理结构和部署方案,如服务器数量、数据中心布局等。

  • 界面和交互设计细节,如颜色、字体、图标等。

  • 安全性和质量保证方案,如访问控制策略、性能优化方案等。

8.简述系统设计的输入

  • 需求分析文档:系统设计的基础是对业务需求的理解和分析。
  • 分析对象模型:分析对象模型是对业务需求进行抽象和概括的产物。
  • 技术选型方案:系统设计需要考虑到可行的技术实现方案
  • 前期研究报告:如系统架构方案、原型实现、用户反馈等的前期研究成果。
  • 约束条件:如时间、预算、组织结构、法律法规等方面的限制和约束条件
  • 各类标准和规范:如安全标准、质量管理规则、编码规范等

9.简述系统设计的输出

  • 系统架构图:系统架构图是系统设计的核心产物,它可以清晰地呈现出系统各个组成部分之间的关系和流程。

  • 详细设计文档:详细设计文档会对每一个模块的功能、使用场景、前置条件、输入输出等进行详细说明,是开发人员实现系统所需的重要参考资料。

  • 数据库设计文档:在系统设计过程中需要对数据存储方案进行设计,在数据库设计文档中可以定义各类数据库对象、表结构、索引等详细信息。

  • 用户手册:用户手册是面向最终用户的说明书,用于介绍系统的功能、特性和使用方法。

  • 测试计划和测试报告:测试计划旨在确保系统质量,并对系统进行全面的测试,测试报告则总结测试的结果和问题,并提供优化建议。

  • 运维手册和操作指南:运维手册是面向系统管理员的说明书,使用操作指南则对系统的安装、部署、维护等方面进行详细说明。

10.简述设计目标

  • 功能目标:即设计方案需要实现的功能特性,对于不同的应用场景,系统所需的功能也会有所不同。功能目标通常由产品经理和需求分析师等角色来确定。

  • 性能目标:性能是系统设计的一个重要方面,性能目标可以包括响应时间、吞吐量、并发用户数等指标,这些指标与系统的使用场景、用户数量、负载等因素有关。

  • 可用性目标:可用性是指软件在操作过程中对用户的友好程度,包括界面设计、文档说明、错误提示、状态反馈等方面。可用性目标通常是通过用户研究和测试来确定的。

  • 安全目标:随着互联网的普及,软件的安全问题越来越受到关注。安全目标包括系统的身份认证、授权管理、数据保护等方面。

  • 可维护性目标:软件开发完成后还需要进行维护,因此在设计时也需要考虑可维护性。可维护性目标包括代码易读性、可扩展性、可测试性等方面。

  • 可靠性目标:可靠性指系统对于外部干扰的能力,包括容错性、可恢复性等。可靠性目标通常由系统管理员和运维人员等角色来确定。

11.设计目标怎样获取?

需求讨论:在系统设计之前,产品经理和需求分析师等角色需要与用户和利益相关者充分沟通,获取需求信息,并整理出详细的需求文档。

12.系统设计活动的主题是什么?

  • 确定系统需求:在系统设计活动开始之前,需要明确系统的重点和要求,通过对用户需求和利益相关者意见进行调查和收集,以便明确系统设计的关键点。

  • 定义系统体系结构:根据所需功能和性能指标,定义出系统的总体结构和组成部分。其中包括系统框架、数据流程、数据存储、用户界面等。

  • 分析系统特性:根据用户需求和利益相关者意见,对系统功能、安全、稳定性、易用性等特性进行详细分析,并制定相应的设计目标。

  • 选择技术方案:根据系统特性和需求,评估不同技术方案的优缺点,并选出最适合的技术方案。

  • 细化设计:在确定了总体设计方案和技术方案之后,进一步细化系统设计,包括技术细节的研究、系统算法的实现、模块的接口设计等。

  • 验证测试:在完成系统设计之后,进行相应的验证和测试,确保系统符合预期的特性和性能指标。

13.简述软件体系结构。

软件体系结构指的是一个软件系统整体上的组成部分,以及这些组成部分之间的相互关系、交互方式和接口规范

  • 模块划分:将系统按照功能或业务逻辑分成若干个模块。
  • 模块之间的关系:定义模块之间的依赖、调用顺序以及数据交换等规则。
  • 外部接口:定义系统与外界的接口,包括输入输出、网络连接等。
  • 运行时配置:为了保证系统的可扩展性和灵活性,在软件体系结构中需要考虑运行时配置,包括负载均衡、容错机制、自动伸缩等。
  • 可靠性和安全性:为了确保软件系统稳定可靠,软件体系结构也需要考虑安全性、故障处理等问题。

  • 性能:在软件系统设计中需要根据实际需求考虑系统的性能特点,如响应时间、吞吐量、并发度等。

14.简述边界用例

边界用例指的是在软件系统中考虑到极端情况下的处理方式,即输入值接近或超出可接受范围时需要采取的措施

15.解释图6-2

系统设计需要考虑非功能性需求,动态模型,分析对象模型,生成设计目标和子系统分解。

对象设计则需要考虑设计目标,子系统分解,生成对象设计模型。

分析生成动态模型和分析对象模型。

16.描述针对“紧急事故响应信息系统”的设计,描述各个接口子系统的主要功能,并用UML构件图给出该系统的设计(分解)结论。

报警接口:负责接收来自各种监测设备、传感器等的数据,并对异常情况进行检测和报警。

应急指挥接口:负责协调各个部门之间的信息交流和指挥安排。

数据平台接口:负责存储和处理大量的数据,包括历史数据、图像数据等。

实时视频监控接口:负责为指挥人员提供实时视频监控画面,以帮助其了解现场情况。

移动终端接口:负责为第一线应急人员提供移动式终端设备,以方便其及时掌握和反馈相关信息。

17.Web Service中负责提供通知服务涉及的相关操作定义。

在Web Service中,负责提供通知服务的相关操作定义可以使用以下两种协议来实现:

Simple Mail Transfer Protocol(SMTP):该协议允许Web Service通过电子邮件向用户发送通知消息。为了使用SMTP协议,Web Service需要支持SMTP服务器,并能够通过SMTP客户端将通知消息发送到指定的用户邮箱中。

Short Message Service(SMS):该协议允许Web Service通过短信向用户发送通知消息。为了使用SMS协议,Web Service需要支持SMS网关,并能够通过SMS客户端将通知消息发送到指定的手机号码中。

18.简述子系统接口要描述的内容。

接口名称:描述该接口的名称,便于识别和管理。

功能描述:描述该接口提供的功能和特性,以及与其他模块之间的关系等。

输入参数:描述该接口需要接收哪些输入参数,并说明每个参数的含义和数据类型等。

输出参数:描述该接口需要返回哪些输出参数,并说明每个参数的含义和数据类型等。

异常处理:描述该接口可能出现的异常情况及对应的处理方式,以确保系统能够在出现故障时正确地恢复运行。

数据格式:描述该接口所使用的数据格式和数据结构,以确保不同模块之间能够正确地解析和处理数据。

接口调用方式:描述该接口的调用方式和调用规范,包括调用方法、传递方式、安全性等。

接口版本:描述该接口的版本信息,以便系统可以支持不同版本的接口,同时也方便跟踪和维护。

19.如何用UML构件图描述由现场工作人员接口子系统、调度者接口子系统和资源管理子系统之间的依赖关系。

20.本教程中的软件体系结构风格包括哪些内容?【系统分解;全局控制流;边界条件处理;子系统之间的通信协议】

系统分解:将系统划分为多个相互独立的、可重用的部件,以便于系统的管理和开发。

全局控制流:描述系统中各个部分之间的交互和通信方式,以及它们之间的数据流向。这有助于开发人员理解系统中的整体结构和功能。

边界条件处理:描述系统与外部环境之间的接口,如用户界面、数据库、网络连接等。这样可以确保系统能够正确地处理各种输入和输出。

子系统之间的通信协议:定义了系统中各个部分之间的通信规则和通信协议,以确保它们能够正确地交互并实现系统的功能。这样可以提高系统的可维护性和可拓展性。

21.简述分层风格(包括封闭式分层结构和开放式分层结构;三层风格;四层风格)(词汇表;不变性;计算原理;典型结构;优缺点;典型应用场景;特例)。 分层风格是一种常见的软件体系结构风格,它将系统划分为多个逻辑层次,并将每个层次之间的关系定义清楚。此风格有多种实现方式,包括封闭式分层结构、开放式分层结构、三层风格和四层风格。

封闭式分层结构

词汇表 封闭式分层结构(Closed Layered Architecture):所有的模块被分成固定数量的层次,各层之间只能通过预定义的接口进行通信。 沉淀物(Deposition):数据访问和处理逻辑被封装在一起,并放置在专用层中。 应用程序接口(API):接口规范,应用程序可以使用这些规范来与下面的层进行交互。 密封(Encapsulation):组件不直接依赖于其他组件,而是通过 API 进行操作。 协议(Protocol):规定了各层之间传递信息的格式和步骤。 不变性 层数固定:封闭式分层结构规定了层数的固定数量,不能加或减。 对单一职责原则(SRP)的支持:每个层都会负责一个独特的功能,并且每个层只与下一层通信,这有助于实现对 SRP 的支持。 稳定性:稳定性良好,在拓展新功能或修改现有功能时不会影响其他层的工作。

计算原理 封闭式分层结构将整个系统划分为固定的几个层次,每个层次都有自己的任务和职责,同时又与其他层次进行交互。例如,界面层、业务逻辑层、数据访问层等,可以通过 API 进行通信。每个组件都只知道它下层组件的接口,而不用关心下层组件的具体实现。

封闭式分层结构

每个矩形代表一个层次,底部的层是数据库层,最上面的层位于应用程序的顶部。每个层次都包含了其所需的库和模块,并向上提供了必要的服务。

优缺点 优点 结构清晰:极大地降低了系统的复杂度,使其易于维护。 易于升级:如果需要添加新功能或修改现有功能,可以很容易地实现升级。 易于测试:层与层之间接口明确定义,让测试更加高效和容易维护。 缺点 系统失去弹性:每个层之间的关系都是静态的。由于层数固定,无法根据需求进行动态添加或减少,可能会导致系统失去弹性和扩展性。 性能损失:由于数据必须通过多个层来传递,因此封闭式分层结构可能会对性能产生负面影响。 过度设计:在处理小型项目时,封闭式分层结构可能会过度设计,并增加复杂性及开发时间。 典型应用场景 封闭式分层结构通常适用于需要支持多种协议和数据源的应用程序,例如企业级 web 应用程序、电子商务网站、嵌入式系统、后端服务器等。

特例 目前封闭式分层结构已不再是一种普遍使用的软件体系结构风格。但是,其思想仍然应被理解和掌握。

开放式分层结构 词汇表 开放式分层结构(Open Layered Architecture):所有的模块被分成可选数量的层次,各层之间可以通过预定义或自定义的接口进行通信。 过程(Procedure):定义了一个模块或组件上执行的任务。 插槽(Slot):插槽是一种逆向调用机制,可用于在运行时动态扩展开放式分层结构中包含的功能。 中介者(Mediator):用来协调不同层级之间的交互和传输。 服务(Service):提供特定的功能和方法集合的抽象。 不变性 层数可变:与封闭式分层结构相比,开放式分层结构支持层数可变,可以根据需求动态添加或减少层次。 计算原理 开放式分层结构中,每个层次都有自己的职责和任务,并可与下面的层次进行交互。由于所有层次都可选,因此可以为需要的场景定制相应的架构。除了系统核心层、数据存储层和 UI/界面层等常见层次,还可以添加其他层次,如远程存储设备、消息队列、安全认证等。

而当需要动态增加层次时,可以使用插槽和反射等技术实现。

典型结构 开放式分层结构中,各层之间的关系是动态可变的。

开放式分层结构

优缺点 优点 灵活性高:架构灵活,适用于不同类型的项目和场景。 可拓展性良好:支持层数的增加和减少,能够更好地适应变化的业务需求。 易维护:模块化设计和可重用组件提高了系统的可维护性。 缺点 结构复杂:每个层次都是相对独立的,需要严格定义它们之间的通信协议和规则。 可扩展性过度:如果没有很好地识别和规划,在添加太多新层后会导致系统变得过分复杂,甚至失去其可读性和可维护性。 性能问题:由于所有数据必须通过多个层来传递,因此可能会影响系统的性能。 典型应用场景 当应用程序需要为多种设备或平台提供支持时,开放式分层结构非常有用。开放式分层结构常用于网络应用程序、大型企业级应用程序、游戏引擎等。

特例 开放式分层结构具有较高的灵活性和可伸缩性,可以根据需求动态地添加和删除层次。这种架构风格使得开发人员能够为不同类型和规模的项目选择合适的架构方案,但是随着系统越来越复杂,需要谨慎设计和规划

22.简述仓库风格。(如HEARSAY II语音理解系统,给出一种系统的结构,描述该结构的计算原理)

仓库风格是一种软件架构风格,也被称为数据中心风格或数据共享风格。它的核心思想是将数据作为应用程序的中心,应用程序通过使用已经存在的数据来完成自己的功能。这种架构风格可以使得数据在整个系统中得到很好地重用,并且能够实现松散耦合的组件之间的交互。

HEARSAY II语音理解系统是一个利用仓库风格设计的语音识别系统。该系统的结构可以分为三部分:前端处理、仓库和后端处理。其中前端处理模块负责从声学信号中提取特征,将其转换成机器可读的格式。仓库模块是系统的核心,负责存储和管理所有的语言知识,如字典、句法规则和语义知识等。后端处理模块则根据前端处理模块提供的特征以及仓库模块中的知识,进行识别和理解过程,最终生成文本输出。

计算原理是将所有的数据集中存储和管理,以便各个组件可以方便地访问和使用这些数据。在仓库风格中,数据被视为应用程序的中心,通过使用已经存在的数据来完成自己的功能。当一个组件需要访问数据时,它只需要从仓库中获取所需的数据,而不需要了解数据的来源或者细节实现方式,从而实现了组件之间的松散耦合。这种架构风格也利于系统的维护和扩展,因为新增数据可以直接添加到仓库中而无需对其他组件进行太多的修改。

23.简述MVC风格。 MVC(Model-View-Controller)是一种常见的软件架构风格,将应用程序分成三个相互独立的部分:数据模型(Model)、视图(View)以及控制器(Controller)。

Model层:负责处理应用程序中使用的数据,通常包括从数据库或其他数据源检索数据的代码,也可以包括允许创建、读取、更新和删除数据的代码。

View层:负责呈现数据及与用户进行交互的界面,通常使用HTML、CSS和JavaScript等语言来构建网页或移动应用的用户界面。

Controller层:负责调度和管理应用程序中的各个组件,接收和处理用户输入、调用model层来更新数据、决定哪些view需要呈现给用户。

24.简述C/S风格。

Client层:负责呈现数据及与用户进行交互的界面,通常是桌面应用程序、Web浏览器或移动应用程序等。

Server层:负责处理客户端请求并提供服务,通常包括数据存储和管理、业务逻辑处理、安全性、 以及与其他服务的交互等。

25.简述B/S风格

Browser层:负责呈现数据及与用户进行交互的界面,通常是基于浏览器的Web应用程序。

Server层:负责处理客户端请求并提供服务,通常包括数据存储和管理、业务逻辑处理、安全性、 以及与其他服务的交互等。

26.简述对等风格。

对等风格也被称为点对点网络(P2P),是一种去中心化的网络架构模式。在对等网络中,所有计算机都可以做出相同的贡献,没有中心节点来控制整个网络。相比之下,传统的客户端/服务器架构则包含一个中央服务器用于管理和协调网络中的所有请求。

27.简述管道过滤器风格。

管道过滤器风格(Pipe and Filter Architecture Style)是一种基于数据流的软件架构模式,它通过将处理数据的组件拼接成管道来处理输入数据流。

这个架构模式中,最基本的部分是过滤器(Filter),它是一个独立的处理组件,负责对输入数据进行某种特定类型的转换、过滤或处理操作,并将结果输出到一个输出端口。管道(Pipe)则将输入数据流传递到经过多个过滤器处理之后的输出端口。每个过滤器专门处理一种类型的数据,所以不同类型的过滤器可以按照需要组合起来构建更为复杂的数据转换和处理流程。

28.简述如下术语。接口;签名;可见性;契约;不变式;前置条件;后置条件。

  • 接口(Interface): 接口定义了类或对象的公共方法和属性,提供了一种规范化的方式来与这些对象进行交互。通过接口,我们可以将实现细节隐藏起来,并提供一个抽象的视图来描述对象的功能。

  • 签名(Signature):方法的签名包括方法名称、参数列表以及返回值类型,在 Java 中还包括方法的修饰符。每个方法都有一个唯一的签名,用于区分重载方法。

  • 可见性(Visibility):指的是类中的成员(字段、方法和嵌套类)对于其他类是否可见。Java 中,我们可以使用 public、protected、private 和 default(即没有修饰符) 来控制成员的可见性。

  • 契约(Contract):契约是一组规则,定义了如何正确地使用代码库中的类、接口和方法。在设计和编写代码时,我们需要明确方法的行为,并定义清楚它们所期望的输入和输出。契约包括前置条件、后置条件和不变式。

  • 不变式(Invariant):不变式是一种约束条件,它应该始终为真。类似于接口,不变式也是一种契约,它规定了代码中某个条件的限制条件。在类中的某个操作之前和之后,不变式应该始终保持为真。

  • 前置条件(Precondition):前置条件是指方法在执行之前必须满足的所有条件。如果前置条件无法满足,则该方法应该抛出一个异常。

  • 后置条件(Postcondition):后置条件是指方法执行之后,一组应该始终满足的条件。通常通过方法的返回值或修改过的对象状态来表示。

29.以台球系列赛为例,找出该比赛中的不变式,说明接收一名选手方法的前置条件和后置条件。

所有比赛中,两位选手的得分之和应该始终等于预期总分数 在这个不变式下,接收一名选手方法的前置条件包括:

该选手尚未参加比赛 比赛尚未开始 参赛人数尚未达到最大限制 而该方法的后置条件则包括:

选手已成功注册参赛 如果此时已经有足够的选手参加比赛,则自动开始比赛 如果此时参赛人数已经达到最大限制,则不再接受新的参赛选手

Tags: 软件工程
Share: X (Twitter) Facebook LinkedIn