锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

SWEBOK软件工程知识体系 - 13.计算基础

时间:2023-02-14 15:30:00 nt4光纤传感器

在这里插入图片描述

计算基础(COMPUTING FOUNDATIONS)

计算基础知识领域(KA)范围包括软件演化和执行的开发和操作环境。由于没有计算机就不能存在或运行任何软件,这种环境的核心是计算机及其各种组件。计算机及其软硬件的基本原理是软件工程的基础。因此,所有的软件工程师都必须对计算基础有良好的理解。

人们普遍认为软件工程是基于计算机科学的。例如,软件工程2004:软件工程本科课程指南[1]明确指出,软件工程基于计算机科学和数学的一个特别重要的方面(斜字补充)。

Steve Tockey他在《软件回报》一书中写道:

计算机科学和软件工程都涉及计算机、计算和软件。计算机科学作为一个知识系统,是这两个学科的核心。软件工程注重计算机、计算和软件在实际应用中的应用,特别是高效经济的软件系统的设计、结构和运行。

因此,软件工程的核心是对计算机科学的理解。

虽然很少有人否认计算机科学作为一门学科和一个知识体系在软件工程开发中的作用,但如何强调计算机科学对软件工程的重要性并不过分;因此,这本书正在编写中。

计算机基础课程的大部分主题也是计算机科学本科和研究生课程的主题。这些课程包括程序设计、数据结构、算法、计算机组织、操作系统、编译器、数据库、网络、分布式系统等。因此,在分解主题时,计算基础可以根据相关课程中经常出现的划分进行分解。

然而,基于课程的主题划分存在严重缺陷。首先,并非所有的计算机科学课程都与软件工程相关或同等重要。因此,计算机科学课程中应涵盖的一些主题并不包括在本课程中。例如,虽然计算机图形学是计算机科学学位课程中的一门重要课程,但它不包括在本课程中。

第二,本指南讨论的一些主题不存在于本科或研究生计算机科学课程中。因此,基于课程的分类可能不能完全涵盖这些主题。对于几门不同的计算机科学课程;在基于课程的主题细分中,不清楚抽象应该属于哪门课程。

计算基础分为17个不同的主题。一个主题对软件工程师的直接有用性是用于选择要包含在这个KA主题标准(见图13.1)。主题故障的优点是,如果要牢牢把握计算基础,必须将其视为逻辑连接的主题集合,特别是软件工程和软件建设。

计算基础KA软件设计、软件结构、软件测试、软件维护、软件质量和数学基础KA密切相关。

计算基础专题分类
计算基础KA主题分类如图13所示.1所示。

1.解决问题的技巧

这里介绍的概念、概念和术语是理解问题和解决技术范围的基础。

1.1. 解决问题的定义

解决问题是指思考和活动来解决问题。解决问题的方法有很多,每种方法都使用不同的工具和过程。这些不同的概念和定义最终产生了不同的学科。例如,软件工程专注于使用计算机和软件来解决问题。

虽然不同的问题需要不同的解决方案,可能需要不同的工具和过程,但解决问题的方法和技术确实遵循一些标准,通常可以概括为问题解决技术。例如,解决一般工程问题的一般标准是使用以下三个步骤[2*]。

  • 提出真正的问题。
  • 分析问题。
  • 搜索策略设计解决方案。

1.2. 提出真正的问题

杰拉德·沃兰德写道:如果一个人想制定一个具体的解决方案,那么认识到一个具体的问题应该制定是非常重要的[2*]。这个公式被称为问题陈述,它清楚地指出了问题和预期的结果。

虽然没有一种常见的解释问题的方式,但一般来说,一个问题的表达应该有助于制定解决方案。一些帮助人们描述真实问题的一般技能包括重复陈述、确定来源和原因、修改陈述、分析当前状态和预期状态以及使用新的视角。

1.3. 分析问题

一旦问题陈述可用,下一步就是分析问题陈述或情况,帮助我们搜索解决方案。四种分析包括情况分析,首先确定情况的最紧急或关键方面;问题分析,必须确定问题的原因;决策分析,必须确定纠正问题或消除原因所需的行动;以及潜在问题分析,必须确定防止问题再次发生或新问题发展所需的行动。

1.4. 搜索策略设计解决方案

一旦问题分析完成,我们就可以专注于构建搜索策略来找到解决方案。为了找到最佳解决方案(在这里,最佳可能意味着不同的人有不同的东西,比如更快、更便宜、更可用、不同的功能等。),我们需要消除找不到可行解决方案的路径,在寻找解决方案时提供最多的指导来设计任务,并利用最终解决状态的各种属性来指导我们在解决问题的过程中的选择。

1.5. 用程序解决问题

与一般工程问题不同,计算机软件的独特性使问题得以解决。要用计算机解决一个问题,我们必须回答以下问题。

  • 如何确定计算机应该做什么?
  • 如何将问题陈述转化为算法?
  • 如何将算法转换为机器指令?

使用计算机解决问题的第一项任务是决定让计算机做什么。讲故事的方法可能有很多种,但它们都应该从计算机的角度出发,这样计算机才能最终解决问题。一般来说,为了开发算法和数据结构,应以这种方式表达一个问题。

第一个任务的结果是一个问题陈述。下一步是将问题陈述转换为解决问题的算法。一旦找到算法,最后一步是将算法转换为机器指令,形成最终的解决方案:解决问题的软件。

抽象地说,使用计算机解决问题可以被视为一个问题转换的过程,换句话说,它是将问题陈述逐渐转化为问题解决方案的过程。对于软件工程学科,解决问题的最终目标是将自然语言表达的问题转化为围绕电路运行的电子产品。一般来说,这种转换可以分为三个阶段:

a) 从问题陈述开发算法。
b) 算法在问题中的应用。
c) 转换算法到程序代码。

将问题陈述转化为算法,将算法转化为程序代码通常遵循逐步细化(也称为系统分解),即从问题陈述开始,将其重写为任务,并将任务分解为几个简单的子任务,直到任务非常简单,解决方案非常简单。分解有三种基本方法:顺序分解、条件分解和迭代分解。

2.抽象

抽象是解决问题不可或缺的技术。它是指通过减少概念、问题或可观察的信息来总结的过程和结果,使人们能够专注于整体情况。在任何项目中,最重要的技能之一是适当地确定抽象的水平。
沃兰德说:通过抽象,我们从更高层次的概念理解来看待问题及其可能的解决方案。因此,我们可以更好地认识到问题不同方面之间可能存在的关系,从而产生更具创意的设计解决方案[2*]。尤其是在一般的计算机科学(如硬件与软件)和软件工程(数据结构与数据流等)中。

2.1. 抽象层次

抽象的时候,我们一次专注于大局的层次,自信地认为自己能有效地与上下层次联系起来。虽然我们只关注一个层次,但抽象并不意味着对相邻层次一无所知。抽象级不一定对应于现实或问题域中的离散组件,而是对应于定义良好的标准接口,如编程api。标准接口提供的优点包括可移植性、更容易的软件/硬件集成和更广泛的使用。

2.2. 封装

包装是实现抽象的机制。当我们处理一个抽象层次时,与上下层次相关的信息被封装。这些信息可以是概念、问题或观察现象;也可以允许操作这些相关实体。封装通常伴随着某种程度的信息隐藏,其中一些或所有底层细节从抽象提供的接口之上的级别隐藏。对于一个对象来说,信息隐藏意味着我们不需要知道对象是如何表达的,也不需要知道的操作是如何实现的。

2.3. 等级制度

当我们在问题的表达和解决方案中使用抽象时,我们可以在不同的时间使用不同的抽象,换句话说,我们根据情况在不同的抽象水平上工作。在大多数情况下,这些不同的抽象水平被组织在一个水平结构中。建立具体水平结构的方法有很多,确定水平结构中每层的具体内容的标准因个人而异。

有时,抽象的层次结构是连续的,这意味着除了顶层(没有后继层)和底层(没有前置层)外,每层只有一个前置层(下层)和一个后继层(上层)。有时,结构意味着每层可以有多个前置层,但只有一个后续层。有时,层次结构可以有多对多结构,每层可以有多个前导和后继。层次结构在任何时候都不应该有任何循环。

层次结构通常在任务分解中自然形成。通常,任务分析可以从组织中较大的任务和目标分解为较小的子任务,然后进一步细分。将任务连续分解为较小的子任务将产生任务子任务的分层结构。

2.4. 交替抽象

有时,对同个问题有多种不同的抽象方法是有用的,这样人们就可以记住不同的观点。例如,我们可以有一个类图、一个状态图和一个序列图,用于相同抽象级别的相同软件。这些交替的抽象并没有形成一个层次结构,而是在帮助理解问题及其解决方案方面相互补充。虽然有益,但保持交替的抽象同步是困难的。

3.编程基础

编程是由创建执行所需功能的计算机程序的方法或活动组成的。它是软件建设中不可缺少的一部分。一般来说,编程可以看作是设计、编写、测试、调试和维护源代码的过程。此源代码是用编程语言编写的。

编写源代码的过程通常需要许多不同学科领域的专业知识,包括应用领域的知识、适当的数据结构、专门的算法、各种语言结构、良好的编程技术和软件工程。

3.1. 编程过程

编程包括设计、编写、测试、调试和维护。设计是将客户对计算机软件的需求转化为操作软件的方案的构思或发明。它是将应用程序需求与编码和调试联系起来的活动。写作是用适当的编程语言对设计进行实际编码。testing是验证一个人编写的代码是否真的做了它应该做的事情的活动。调试是在源代码(或设计)中发现并修复bug(错误)的活动。维护是更新、纠正和增强现有程序的活动。这些活动中的每一个都是一个巨大的主题,通常需要在SWEBOK指南和许多书中对整个KA进行解释。

3.2. 程序设计范式

编程是高度创造性的,因此有点个人化。不同的人常常为相同的需求编写不同的程序。这种编程的多样性给大型复杂软件的构建和维护带来了很大的困难。多年来,人们开发了各种各样的编程范例,将一些标准化应用到这项极具创造性和个性化的活动中。当一个人编写程序时,他或她可以使用几种编程范式中的一种来编写代码。下面将讨论编程范例的主要类型。

非结构化编程:在非结构化编程中,只要函数是可操作的,程序员就按照自己的直觉以自己喜欢的方式编写代码。通常,实践是编写代码来实现特定的实用程序,而不考虑其他任何事情。以这种方式编写的程序没有特定的结构,因此被称为“非结构化编程”。非结构化编程有时也被称为即席编程。

结构化/程序化/命令式编程:结构化编程的一个特点是使用定义良好的控制结构,包括程序(和/或函数),每个程序(或函数)执行特定的任务。过程之间存在接口,以便于正确、顺利地调用程序。在结构化编程中,程序员在编写代码时通常遵循既定的协议和经验法则。这些协议和规则可以很多,几乎涵盖了编程的整个范围,从最简单的问题(如如何命名变量、函数、过程等)到更复杂的问题(如如何构造接口、如何处理异常等)。

面向对象编程:过程编程围绕过程组织程序,而面向对象编程(OOP)围绕对象组织程序,对象是抽象的数据结构,结合了数据和用于访问或操作数据的方法。OOP的主要特点是创建表示各种抽象和具体实体的对象,这些对象相互作用,共同实现所需的功能。

面向方面编程:面向方面编程(AOP)是建立在OOP之上的一种编程范式。AOP的目的是通过关注对象的横截面(关注点),将辅助功能或支持功能与主程序的业务逻辑隔离开来。AOP的主要目的是解决OOP中对象的纠缠和散射,其中对象之间的交互变得非常复杂。AOP的本质是非常强调的关注点分离,它将非核心功能关注点或逻辑分离为各个方面。

函数式编程:虽然不太流行,但函数式编程在解决编程问题上与其他范式一样可行。在函数式编程中,所有的计算都被看作是对数学函数的求值。与强调状态变化的命令式编程不同,函数式编程强调函数的应用,避免状态和可变数据,并提供引用透明性。

4.编程语言基础

使用计算机解决问题涉及到编程,即编写和组织指令,告诉计算机在每一步要做什么。程序必须用某种编程语言编写,我们用这种语言来描述必要的计算。换句话说,我们使用编程语言提供的工具来描述问题、开发算法和推理问题的解决方案。要编写任何程序,必须至少懂一种编程语言。

4.1. 程序设计语言概述

程序设计语言是用来表达计算机可以执行的计算。在实际意义上,编程语言是一种用于编写程序的符号,因此应该能够表达大多数数据结构和算法。有些人(但不是所有人)将术语“编程语言”限定为那些能够表达所有可能算法的语言。

不是所有的语言都有同样的重要性和流行性。最流行的规范通常是由一个著名和受人尊敬的组织建立的规范文档来定义的。例如,C编程语言由名为ISO/iec9899的ISO标准指定。其他语言,如Perl和Python,不喜欢这种处理方式,通常有一个主要的实现作为参考。

4.2. 程序设计语言的语法和语义

就像自然语言一样,许多编程语言的语法(形式)和语义(意义)都有某种形式的书面规范。例如,这些规范包括变量和常量定义的具体要求(换言之,声明和类型)以及指令本身的格式要求。
一般来说,编程语言支持变量、数据类型、常量、文本、赋值语句、控制语句、过程、函数和注释等结构。必须清楚地指定每个构造的语法和语义。

4.3. 低级程序设计语言

程序设计语言可分为两类:低级语言和高级语言。低级语言可以被计算机理解而不需要或很少的帮助,通常包括机器语言和汇编语言。机器语言使用1和0来表示指令和变量,并且可以被计算机直接理解。汇编语言包含与机器语言相同的指令,但指令和变量具有便于人类记忆的符号名称。

汇编语言不能被计算机直接理解,必须由称为汇编程序的实用程序翻译成机器语言。汇编语言的指令与机器语言的指令之间往往存在着对应关系,汇编代码到机器代码的翻译是直接的。例如,“add r1,r2,r3”是一条汇编指令,用于将寄存器r2和r3的内容相加,并将总和存储到寄存器r1中。此指令可以很容易地翻译成机器代码“0001 0001 0010 0011”。(假设加法的操作代码为0001,见图13.2)。

add r1, r2, r3
0001 0001 0010 0011

Figure 13.2. Assembly-to-Binary Translations

这两种语言的一个共同特点是,它们与一种计算机或指令集体系结构(ISA)的特性密切相关。

4.4. 高级程序设计语言

高级编程语言对计算机的ISA细节有很强的抽象性。与低级编程语言相比,它通常使用自然语言元素,因此更易于人类理解。这些语言允许变量的符号命名,提供表达能力,并支持底层硬件的抽象。例如,虽然每个微处理器都有自己的ISA,但用高级编程语言编写的代码通常可以在许多不同的硬件平台之间移植。由于这些原因,大多数程序员使用高级编程语言,大多数软件都是用高级编程语言编写的。包括C++、C++、C语言和java语言。

4.5. 声明式与命令式编程语言

大多数编程语言(高级或低级)允许程序员指定计算机要执行的单个指令。这种编程语言被称为命令式编程语言,因为人们必须向计算机清楚地说明每一步。但是有些编程语言允许程序员只描述要执行的函数,而不指定要执行的确切指令序列。这种编程语言被称为声明式编程语言。声明性语言是高级语言。用这种语言编写的计算的实际实现对程序员来说是隐藏的,因此他们不必担心。

需要注意的关键点是,声明式编程只描述程序应该完成什么,而不描述如何完成它。因此,许多人认为声明式编程有助于简化软件开发。声明性编程语言包括LISP(也是函数式编程语言)和PROLO,而命令式编程语言包括C、C++和java。

5.调试工具和技术

一旦一个程序被编码和编译(编译将在第10节中讨论),下一步就是调试,这是一个有条不紊地发现并减少程序中错误或错误的过程。调试的目的是找出程序不工作或产生错误结果或输出的原因。除了非常简单的程序外,调试总是必要的。

5.1. 错误类型

当一个程序不工作时,通常是因为程序包含错误或错误,这些错误可以是语法错误、逻辑错误或数据错误。在软件工程术语中,逻辑错误和数据错误也被称为两类“错误”(参见软件测试KA中的主题1.1,测试相关术语)。

语法错误就是任何阻止转换器(编译器/解释器)成功解析语句的错误。程序中的每一条语句都必须是可解析的,才能理解和解释它的含义(因此,执行)。在高级编程语言中,在将高级语言编译或翻译成机器代码的过程中会发现语法错误。例如,在C/C++编程语言中,语句“123=常数”包含编译过程中编译器会捕获的语法错误。

逻辑错误是导致错误计算或程序行为的语义错误。你的程序是合法的,但错了!因此结果与问题陈述或用户期望不符。例如,在C/C++编程语言中,内联函数“int f(int x){f f(x-1)”}用于计算阶乘x!是合法的,但逻辑上是不正确的。这种类型的错误在编译过程中不能被编译器捕获,通常是通过跟踪程序的执行来发现的(现代的静态检查器确实识别了其中的一些错误)。然而,关键仍然是这些不是机器检查(一般来说)。

数据错误是导致输入数据与程序预期不同或处理错误数据的输入错误。

5.2. 调试技术

调试涉及许多活动,可以是静态的、动态的或事后的。静态调试通常采用代码评审的形式,而动态调试通常采用跟踪的形式,与测试密切相关。事后调试是调试进程的核心转储(内存转储)的行为。核心转储通常是在进程由于未处理的异常而终止之后生成的。这三种技术都在程序开发的不同阶段使用。

动态调试的主要活动是跟踪,即一次执行一个程序,检查寄存器和内存的内容,以便检查每一步的结果。跟踪程序有三种方法。

5.3. 调试工具

调试可能是复杂、困难和乏味的。与编程一样,调试也很有创造性(有时比编程更有创造性)。因此,需要工具的帮助。对于动态调试,调试器被广泛使用,它使程序员能够监视程序的执行、停止执行、重新启动执行、设置断点、更改内存中的值,甚至在某些情况下可以返回时间。

对于静态调试,有许多静态代码分析工具,它们在源代码中查找一组特定的已知问题。商业工具和免费工具都有不同的语言版本。这些工具在检查非常大的源代码树时非常有用,因为在这些树中进行代码演练是不切实际的。UNIX lint程序是一个早期的例子。

6.数据结构和表示

程序处理数据。但是数据在被程序处理之前必须在计算机中被表达和组织。这种供程序使用的数据的组织和表达是数据结构和表示的主题。简单地说,数据结构试图在计算机中存储和组织数据,以便有效地使用数据。有许多类型的数据结构,每种类型的结构都适用于某些类型的应用程序。例如,B/B+树非常适合实现大规模文件系统和数据库。

6.1. 数据结构概述

数据结构是数据的计算机表示。几乎每个程序都使用数据结构。从某种意义上说,没有某种数据结构,就无法构造出有意义的程序。一些设计方法和编程语言甚至围绕数据结构组织整个软件系统。从根本上说,数据结构是在数据集合及其相关操作上定义的抽象。

通常,设计数据结构是为了提高程序或算法的效率。此类数据结构的示例包括堆栈、队列和堆。有时,数据结构用于概念统一(抽象数据类型),例如人名和地址。通常,数据结构可以确定程序是在几秒钟内运行,还是在几个小时甚至几天内运行。

从物理和逻辑顺序的角度来看,数据结构要么是线性的,要么是非线性的。其他观点产生了不同的分类,包括同质与异质、静态与动态、持久与瞬时、外部与内部、原始与聚合、递归与非递归、被动与主动、有状态与无状态结构。

6.2. 数据结构类型

如上所述,可以使用不同的视角对数据结构进行分类。然而,分类中使用的主要观点集中在结构之间的物理和逻辑顺序上,在单个维度中组织数据项,其中每个数据项都有一个(物理或逻辑)前置项和一个后继项(第一个和最后一个条目除外)。第一个条目没有前置项,最后一个条目没有后续项。非线性结构以两个或更多维度组织数据项,在这种情况下,一个条目可以有多个前导项和后继项。线性结构的示例包括列表、堆栈和队列。非线性结构的示例包括堆、哈希表和树(例如二叉树、平衡树、B-树等)。

编程中经常遇到的另一种数据结构是复合结构。复合数据结构构建在其他(更原始的)数据结构之上,并且在某种程度上可以被视为与底层结构相同的结构。复合结构的例子包括集合、图和分区。例如,分区可以看作是一组集合。

6.3. 数据结构操作

所有数据结构都支持某些操作,这些操作生成特定的结构并进行排序,或者从结构中检索相关数据,将数据存储到结构中,或者从结构中删除数据。所有数据结构支持的基本操作包括创建、读取、更新和删除(CRUD)。

  • 创建:在结构中插入新的数据条目。
  • 读取:从结构中检索数据条目。
  • 更新:修改现有数据条目。
  • 删除:从结构中删除数据项。

一些数据结构还支持其他操作:

  • 找到结构中的特定元素。
  • 根据某种顺序对所有元素进行排序。
  • 以特定顺序遍历所有元素。
  • 重组或重新平衡结构。

不同的结构以不同的效率支持不同的操作。运行效率之间的差异可能是显著的。例如,检索插入到堆栈中的最后一个项很容易,但是在堆栈中查找特定元素则相当缓慢和乏味。

7.算法和复杂性

程序不是随机的代码片段:它们被精心编写来执行用户期望的操作。编写程序的指南是算法,它将各种功能组织成一系列步骤,并考虑到应用领域、解决方案策略和所使用的数据结构。算法可以非常简单,也可以非常复杂。

7.1.算法概述

抽象地说,算法指导着计算机的操作,由一系列用来解决问题的动作组成。其他定义包括但不限于:

  • 算法是任何定义良好的计算过程,它将某个值或一组值作为输入,并产生某个值或一组值作为输出。
  • 算法是将输入转换为输出的一系列计算步骤。
  • 算法是解决特定计算问题的工具。

当然,不同的定义受到不同的人的青睐。虽然没有普遍接受的定义,但存在一些共识,即一个算法需要是正确的、有限的(换句话说,最终终止,或者一个人必须能够用有限的步骤来编写它)和明确的。

7.2.算法属性

算法的属性很多,通常包括模块性、正确性、可维护性、功能性、健壮性、用户友好性(即易于理解)、编程时间、简单性和可扩展性。通常强调的属性是“性能”或“效率”,我们指的是时间和资源使用效率,而通常强调时间轴。在某种程度上,效率决定了一个算法是可行的还是不切实际的。例如,一个需要一百年才能终止的算法实际上是无用的,甚至被认为是不正确的。

7.3.算法分析

算法分析是计算机程序性能和资源利用的理论研究,在一定程度上决定了算法的优劣。这种分析通常把特定计算机的特定细节抽象出来,集中在渐进的、与机器无关的分析上。

分析有三种基本类型。在最坏情况分析中,确定算法在大小为n的任何输入上所需的最大时间或资源。在平均情况分析中,确定算法在大小为n的所有输入上所需的预期时间或资源;在执行平均情况分析时,人们常常需要对投入的统计分布作出假设。第三种类型的分析是最佳案例分析,其中一种分析确定算法对大小为n的任何输入所需的最小时间或资源。在三种类型的分析中,平均案例分析是最相关的,但也是最难执行的。

除了基本分析方法外,还有摊销分析法,即确定算法在一系列操作中所需的最长时间;竞争分析法,即确定算法相对于同类最佳算法(可能未知)的相对性能优势(对于相同的操作)。

7.4.算法设计策略

算法的设计一般遵循以下策略之一:暴力、分而治之、动态规划和贪婪选择。蛮力策略实际上是一种无策略。它用尽一切可能的办法来解决问题。如果一个问题有一个解决方案,这个策略一定能找到;但是,时间开销可能太大。分而治之策略是对暴力策略的改进,它将一个大问题分解成更小的同质问题。它通过递归求解小问题来解决大问题,并将小问题的解组合起来形成大问题的解。分而治之的基本假设是较小的问题更容易解决。

动态规划策略是对分而治之策略的改进,它认识到分而治之产生的一些子问题可能是相同的,从而避免了反复求解相同的问题。这种消除冗余子问题的方法可以极大地提高效率。

贪婪选择策略进一步改进了动态规划,认识到不是所有的子问题都有助于大问题的解决。贪婪选择策略通过消除除一个子问题外的所有子问题,在所有算法设计策略中实现了最高的效率。有时使用随机化可以通过消除投币或随机化确定贪婪选择的复杂性来改进贪婪选择策略。

7.5.算法分析策略

算法的分析策略包括基本计数分析,实际计算算法完成任务的步数;渐近分析,只考虑算法完成任务的步数的数量级;概率分析,其中利用概率分析算法的平均性能;摊销分析,其中利用聚合、潜在和会计方法分析算法在一系列操作中的最差性能;以及竞争分析,在这种方法中,人们使用诸如潜力和会计等方法来分析算法相对于最优解的相对性能算法复杂的问题和算法,可能需要结合使用上述分析策略。

8.系统的基本概念

Ian Sommerville写道,“系统是一个有目的的相互关联的组件集合,这些组件共同工作以实现某些目标”[6*]。一个系统可以非常简单,只包含几个组件,比如一支钢笔,或者更复杂一些,比如一架飞机。根据人类是否是系统的一部分,系统可以分为基于计算机的技术系统和社会技术系统。一个基于计算机的技术系统在没有人类参与的情况下运行,例如电视、手机、恒温器和一些软件;一个社会技术系统在没有人类参与的情况下无法运行。这类系统的例子包括载人航天器、嵌入人体内部的芯片等等。

8.1.应急系统特性

一个系统不仅仅是它各个部分的总和。因此,一个系统的属性并不仅仅是其组成部分属性的总和。相反,一个系统通常表现出的属性是系统作为一个整体的属性。这些属性被称为涌现属性,因为它们只有在系统的组成部分整合之后才会发展。紧急系统属性可以是功能性的,也可以是非功能性的。函数属性描述系统所做的事情。例如,飞机的功能特性包括在空中漂浮、运载人员或货物以及用作大规模杀伤性武器。非功能属性描述系统在其操作环境中的行为。这些质量包括一致性、容量、重量、安全性等。

8.2.系统工程

“系统工程(engineering)是一种跨学科的方法,它管理着将一系列客户需求、期望和约束转化为解决方案并在解决方案的整个生命周期内支持该解决方案所需的全部技术和管理工作。”。系统工程的生命周期阶段因所构建的系统而异,但通常包括系统需求定义、系统设计、子系统开发、系统集成、系统测试、系统安装、系统演化和系统退役。

过去已经制定了许多实用的指导方针,以帮助人们执行每个阶段的活动。例如,系统设计可以分解为子系统识别、子系统需求分配、子系统功能规范、子系统接口定义等较小的任务。

8.3.计算机系统概述

在所有的系统中,计算机系统显然与软件工程界有关。计算机是执行程序或软件的机器。它由机械、电气和电子元件组成,每个元件都执行预设功能。这些组件能够共同执行程序给出的指令。

抽象地说,计算机接收一些输入,存储和处理一些数据,并提供一些输出。计算机最显著的特点是它能够存储和执行称为程序的指令序列。有关计算机的一个有趣现象是功能上的普遍等价性。根据图灵的理论,所有具有一定最小能力的计算机在执行计算任务的能力上是等价的。换言之,只要有足够的时间和内存,从上网本到超级计算机的所有计算机都能够计算完全相同的东西,而不考虑速度、大小、成本或其他任何因素。

大多数计算机系统都有一种被称为“冯·诺依曼模型”的结构,它由五个部分组成:存储指令和数据的存储器,执行算术和逻辑运算的中央处理器,对指令排序和解释的控制单元,用于将外部信息输入内存的输入,以及用于为用户生成结果的输出。基于冯·诺依曼模型的计算机系统的基本组件如图13.3所示。


9.计算机组织

从计算机的角度来看,它的预期行为和在计算机内实际工作的底层电子设备的工作方式之间存在很大的语义鸿沟。这一差距通过计算机组织来弥合,计算机组织将各种电气、电子和机械设备整合成一个设备,形成一台计算机。计算机组织处理的对象是设备、连接和控件。建立在计算机组织中的抽象就是计算机。

9.1.计算机组织概述

计算机通常由CPU、内存、输入设备和输出设备组成。抽象地说,计算机的组织可以分为四个层次(图13.4)。宏体系结构级别是特定机器可以执行的所有功能的正式规范,称为指令集体系结构(ISA)。微体系结构级别是在特定CPU中实现ISA,换句话说,就是ISA规范实际执行的方式。逻辑电路层是指微体系结构的每个功能部件都由基于简单规则做出决策的电路组成的层。最后,器件级是指每个逻辑电路实际上由诸如互补金属氧化物半导体(CMOS)、n沟道金属氧化物半导体(NMOS)或砷化镓(GaAs)晶体管等电子器件构成的级。

Macro Architecture Level (ISA)
Micro Architecture Level
Logic Circuits Level
Devices Level

Figure 13.4. Machine Architecture Levels

每个级别都提供了对上面级别的抽象,并且依赖于下面的级别。对于程序员来说,最重要的抽象是ISA,它指定了本地数据类型、指令、寄存器、寻址模式、内存体系结构、中断和异常处理以及I/o。总的来说,ISA规定了计算机的能力以及通过编程可以在计算机上做什么。

9.2.数字系统

在最底层,计算是由计算机中的电气和电子设备进行的。计算机使用电路和存储器来保存表示有无电压的电荷。有电压等于1,无电压等于0。在磁盘上,电压的极性用0和1来表示,而1又表示存储的数据。包括指令和数据在内的一切都是用数字0和1来表示或编码的。从这个意义上说,计算机变成了一个数字系统。例如,十进制值6可以编码为110,加法指令可以编码为0001,等等。计算机的组成部分,如控制单元、ALU、存储器和I/O,使用这些信息来计算指令。

9.3.数字逻辑

显然,需要逻辑来操作数据和控制计算机的运行。这种逻辑是计算机正常功能的基础,它被称为数字逻辑,因为它处理数字0和1的运算。数字逻辑规定了用最简单的元件(如晶体管)构建各种数字设备和控制数字设备运行的规则。例如,数字逻辑阐明了如果0和1同时被and、or或独占or,值将是什么。它还指定了如何构建用于组装计算机的解码器、多路复用器(MUX)、内存和加法器。

9.4.数据的计算机表达

如前所述,计算机用电信号或数字0和1来表示数据。由于在数据表达式中只使用了两个不同的数字,这样的系统称为二进制表达式系统。由于二进制系统的固有特性,n位二进制代码可表达的最大数值为2n−1。具体而言,二进制数anan−1…a1a0对应于an×2n+an−1×2n−1+…+a1×21+a0×20。因此,1011的二进制表达式的数值为1×8+0×4+1×2+1×1=11。为了表示一个非数值,我们需要确定要使用的零和一的数目以及这些零和一的排列顺序。

当然,有不同的编码方式,这就产生了不同的数据表达模式和子模式。例如,整数可以表示为无符号、一的补码或二的补码。对于字符,有ASCII、Unicode和IBM的EBCDIC标准。对于浮点数,有IEEE-754 FP 1、2和3标准。

9.5.中央处理器(CPU)

中央处理器是实际执行指令(或程序)的地方。执行通常需要几个步骤,包括获取程序指令、解码指令、获取操作数、对操作数执行算术和逻辑运算以及存储结果。CPU的主要部件包括寄存器,其中指令和数据经常被读取和写入寄存器,执行实际算术(如加法、减法、乘法和除法)和逻辑(如and、OR、shift等)操作的算术逻辑单元(ALU),负责产生适当的信号来控制操作,以及各种(数据、地址和控制)总线,这些总线将组件连接在一起,并在这些组件之间传输数据。

9.6.内存系统组织

内存是计算机的存储单元。它涉及从较小的单位数存储单元组装大规模存储系统。内存系统体系结构涵盖的主要主题包括:

  • 存储单元和芯片
  • 内存板和模块
  • 内存层次结构和缓存
  • 内存作为计算机的一个子系统。

存储单元和芯片处理单个数字存储和将单个数字单元组装成一维存储阵列以及将一维存储阵列组装成多维存储芯片。存储板和模块涉及将存储芯片组装到存储系统中,重点是系统中各个芯片的组织、操作和管理。内存层次结构和缓存用于支持高效的内存操作。内存作为一个子系统处理内存系统和计算机其他部分之间的接口。

9.7.输入和输出(I/O)

没有输入/输出的计算机是无用的。常用的输入设备包括键盘和鼠标;常用的输出设备包括磁盘、屏幕、打印机和扬声器。不同的I/O设备以不同的数据速率和可靠性工作。计算机如何连接和管理各种输入输出设备,以方便计算机与人(或其他计算机)之间的交互,是I/O研究的重点。输入输出中必须解决的主要问题是I/O可以和应该执行的方式。

一般来说,I/O是在硬件和软件两个级别执行的。硬件I/O可以用三种方式中的任何一种来执行。专用I/O将CPU指定给I/O期间的实际输入和输出操作;内存映射I/O将I/O操作视为内存操作;hybridI/O将专用I/O和内存映射I/O组合为一个整体I/O操作模式。

巧合的是,软件I/O也可以通过以下三种方式之一执行。编程I/O使CPU在I/O设备进行I/O时等待;中断驱动I/O使CPU对I/O的处理由I/O设备驱动;directmemory access(DMA)使I/O由嵌入DMA设备(或通道)的辅助CPU处理。(除了在初始设置期间,在DMA I/O操作期间主CPU不会受到干扰。)

无论使用何种类型的I/O方案,I/O中涉及的主要问题包括I/O修整(处理如何识别特定I/O操作的I/O设备的问题)、同步(处理如何使CPU和I/O设备在I/O期间协调工作的问题)以及错误检测和纠正(处理处理传输错误的发生)。

10.编译器基础知识

10.1.编译器/解释器概述

程序员通常用高级语言代码编写程序,CPU无法执行这些代码;因此,必须将这些源代码转换成计算机可以理解的机器代码。由于不同ISA之间的差异,必须对每个ISA或特定的机器语言进行翻译。

翻译通常由一个称为编译器或翻译。这个从高级语言到机器语言的翻译过程称为编译,有时称为解释。

10.2.解释和汇编

将用高级语言编写的程序翻译成机器代码有两种方法:解释和编译。解释将源代码一次翻译成机器语言,当场执行,然后返回另一个语句。每次运行程序时都需要高级语言源代码和解释器。

编译通过称为编译器的程序将高级语言源代码转换为整个机器语言程序(可执行映像)。编译后,运行程序只需要可执行映像。大多数应用软件都是以这种形式销售的。

虽然编译和解释都将高级语言代码转换为机器代码,但这两种方法有一些重要的区别。首先,编译器只进行一次转换,而解释器通常在每次执行程序时都进行转换。其次,解释代码比运行编译代码慢,因为解释器必须在执行程序中的每条语句时对其进行分析,然后执行所需的操作,而编译代码只是在编译确定的固定上下文中执行操作。第三,在解释器中访问变量的速度也较慢,因为标识符到存储位置的映射必须在运行时而不是在编译时重复进行。

编译器的主要任务可能包括预处理、词法分析、解析、语义分析、代码生成和代码优化。由不正确的编译器行为引起的程序错误很难追踪。因此,编译器实现者投入大量时间来确保软件的正确性。

10.3.编制过程

编译是一项复杂的任务。大多数编译器将编译过程分为许多阶段。典型故障如下:

  • 词汇分析
  • 语法分析或解析
  • 语义分析
  • 代码生成

词法分析将输入的文本(源代码)分成单独的注释和基本符号,注释是一个字符序列,注释在后续操作中被忽略,基本符号具有词法意义。这些基本符号必须对应于特定编程语言语法的一些终端符号。这里的终端符号是指语法中不能改变的基本符号(或记号)。

语法分析基于词法分析的结果,发现程序中的结构,并确定文本是否符合预期格式。这是一个文本正确的C++程序吗?或者这个条目在文字上是正确的?是典型的问题,可以回答语法分析。语法分析确定程序的源代码是否正确,并将其转换为更结构化的表示(解析树),以便进行语义分析或转换。

语义分析将语义信息添加到语法分析期间构建的解析树中,并构建符号表。它执行各种语义检查,包括类型检查、对象绑定(关联变量和函数赋值(要求在使用之前初始化所有局部变量))。如果发现错误,语义不正确的程序语句将被拒绝并标记为错误。

一旦语义分析完成,代码生成阶段就开始了,并将前一阶段生成的中间代码转换为所考虑的计算机的本机语言。这涉及到资源和存储决策,例如决定将哪些变量放入寄存器和内存,选择和调度适当的机器指令,以及它们相关的寻址模式。

在编译器实现中,通常可以将多个阶段组合成一次代码传递。有些编译器在词法分析的开始或之后也有一个预处理阶段,进行必要的内务处理工作,例如处理编译器的程序指令(指令)。一些编译器在最后提供了一个可选的优化阶段(如指令序列的重新排列),以提高效率和用户要求的其他理想目标。

11.操作系统基础

每一个有意义的复杂系统都需要管理。计算机作为一个相当复杂的机电系统,需要有自己的管理者来管理计算机上发生的资源和活动。这个管理器被称为操作系统(OS)。

11.1. 操作系统概述

操作系统是软件和固件的集合,它控制计算机程序的执行,并在计算机系统中提供诸如计算机资源分配、作业控制、输入/输出控制和文件管理等服务。从概念上讲,操作系统是一种计算机程序,它管理硬件资源,并通过呈现良好的抽象使应用程序更易于使用。这种很好的抽象通常被称为虚拟机,包括进程、虚拟内存和文件系统等。操作系统隐藏了底层硬件的复杂性,可以在所有现代计算机上找到。

开放源码软件的主要角色是管理和幻想。管理是指操作系统在多个相互竞争的用户/应用程序/任务之间对物理资源的管理(分配和恢复)。幻觉指的是操作系统提供的美好抽象。

11.2. 操作系统的任务

操作系统的任务因其发明的机器和时间的不同而有很大的不同。然而,现代操作系统已经就操作系统必须执行的任务达成一致。这些任务包括CPU管理、内存管理、磁盘管理(文件系统)、I/O设备管理以及安全和保护。每个操作系统任务管理一种类型的物理资源。

具体来说,CPU管理处理CPU在相互竞争的程序(在OS术语中称为进程/线程)之间的分配和释放,包括操作系统本身。CPU管理提供的主要抽象是进程/线程模型。内存管理涉及在相互竞争的进程之间分配和释放内存空间,而内存管理提供的主要抽象是虚拟内存。磁盘管理涉及多个程序/用户之间共享磁盘、光盘或固态磁盘,其主要抽象是文件系统。I/O设备管理处理各种I/O设备在竞争进程之间的分配和释放。安全和保护涉及保护计算机资源不被非法使用。

11.3. 操作系统抽象

开放源码软件的兵工厂是抽象的。与五个物理任务相对应,OSs使用五个抽象:进程/线程、虚拟内存、文件系统、输入/输出和保护域。整个操作系统抽象是虚拟机。

对于操作系统的每个任务领域,都有一个物理现实和一个概念抽象。物理现实是指管理下的硬件资源;概念抽象是指操作系统向上述用户/程序提供的接口。例如,在操作系统的线程模型中,物理实体是CPU,抽象是多个CPU。因此,用户在处理OS提供的抽象时不必担心与其他人共享CPU。在操作系统的虚拟内存抽象中,物理实体是物理RAM或ROM(无论什么),抽象是多个无限内存空间。因此,用户不必担心与他人共享物理内存,也不必担心有限的物理内存大小。

抽象可以是虚拟的,也可以是透明的;在这个上下文中,虚拟的应用于似乎存在但不存在的东西(比如物理之外的可用内存),而透明的应用于存在但似乎不存在的东西(比如从磁盘或物理内存中提取内存内容)。

11.4. 操作系统分类

不同的操作系统可以有不同的功能实现。在计算机时代的早期,操作系统相对简单。随着时间的推移,复杂性显著增加。从历史的角度来看,操作系统可以分为以下几种。

  • 分批操作系统:分批组织和处理工作。这类操作系统的例子包括IBM的FMS、IBSYS和密歇根大学的UMES。
  • 多道程序批处理操作系统:将多任务功能添加到早期的简单批处理操作系统中。这种操作系统的一个例子是IBM的OS/360。
  • 分时操作系统:将多任务和交互功能添加到操作系统中。这种操作系统的例子包括UNIX、Linux和NT。
  • 实时操作系统:通过根据每个任务的完成期限安排单个任务,将时间可预测性添加到操作系统中。这类操作系统的例子包括VxWorks(WindRiver)和DART(EMC)。
  • 分布式操作系统:将管理计算机网络的功能添加到操作系统中。
  • 嵌入式操作系统:功能有限,用于汽车和掌上电脑等嵌入式系统。这类操作系统的例子包括Palm操作系统、windowsce和TOPPER。

或者,操作系统可以按其适用的目标机器/环境分为以下几类。

  • 大型机操作系统:在大型机计算机上运行,包括OS/360、OS/390、AS/400、MVS和VM。
  • 服务器操作系统:在工作站或服务器上运行,包括UNIX、Windows、Linux和VMS等系统。
  • 多计算机操作系统:在多台计算机上运行,包括Novell Netware等示例。
  • 个人计算机操作系统:在个人计算机上运行,包括DOS、Windows、Mac OS和Linux等示例。
  • 移动设备操作系统:在手机、IPAD等个人设备上运行,包括iOS、Android、Symbian等。

12.数据库基础和数据管理

数据库由一个或多个用途的有组织的数据集合组成。从某种意义上说,数据库是数据结构的泛化和扩展。但不同的是,数据库通常位于单个程序的外部,与数据结构相比是永久存在的。当数据量很大或数据项之间的逻辑关系很重要时,使用数据库。数据库设计中考虑的因素包括性能、并发性、完整性和硬件故障恢复。

12.1. 实体和模式

数据库试图建模和存储的东西称为实体。实体可以是真实世界的对象,比如人、汽车、房子等等,也可以是抽象概念,比如人、薪水、名字等等。实体可以是原始的,例如名称,也可以是复合的,例如员工工资、地址等等。

数据库中最重要的一个概念是模式,它描述了构建所有其他数据库活动的整个数据库结构。模式定义组成数据库的各种实体之间的关系。例如,公司工资单系统的模式将由雇员ID、姓名、工资率、地址等组成。数据库软件根据模式维护数据库。

数据库中的另一个重要概念是描述各种实体之间关系类型的数据库模型。常用的模型包括关系模型、网络模型和对象模型。

12.2. 数据库管理系统

数据库管理系统(DBMS)组件包括用于存储结构化和非结构化数据的数据库应用程序,以及查看、收集、存储和检索数据库中数据所需的数据库管理功能。DBMS控制数据库的创建、维护和使用,通常根据其支持的数据库模型(如关系模型、网络模型或对象模型)进行分类。例如,关系数据库管理系统(RDBMS)实现了关系模型的特性。对象数据库管理系统(ODBMS)实现了对象模型的特性。

12.3. 数据库查询语言

用户/应用程序通过数据库查询语言(databasequerylanguage)与数据库交互,数据库查询语言是一种专门针对数据库使用而设计的编程语言。数据库模型倾向于确定可用于访问数据库的查询语言。关系数据库的一种常用查询语言是结构化查询语言,通常缩写为SQL。对象数据库的通用查询语言是对象查询语言(缩写为OQL)。SQL有三个组件:数据定义语言(DDL)、数据操作语言(DML)和数据控制语言(DCL)。DML查询的示例如下所示:

从组件中选择组件编号,数量,其中项目编号=100
上面的查询从名为Component的数据库表中选择所有Component及其对应的数量,其中Item等于100。

12.4. DBMS包的任务

DBMS系统提供以下功能:

12.5. 数据管理

数据库必须管理存储在其中的数据。这种管理包括组织和存储。
数据库中实际数据的组织取决于数据库模型。在关系模型中,数据被组织为表,不同的表表示不同的实体或一组实体之间的关系。数据存储处理这些数据库表在磁盘上的存储。实现这一点的常用方法是使用文件。顺序文件、索引文件和散列文件都用于此目的,不同的文件结构提供了不同的访问性能和方便性。

12.6. 数据挖掘

在查询数据库之前,通常必须知道要查找什么。这种类型的“精确定位”访问并没有充分利用数据库中存储的大量信息,实际上将数据库简化为离散记录的集合。为了充分利用数据库,可以使用称为数据挖掘的技术对数据库的内容执行统计分析和模式发现。此类操作可用于支持许多业务活动,包括但不限于营销、欺诈检测和趋势分析。

在过去的十年中,人们发明了许多进行数据挖掘的方法,包括诸如类描述、类判别、聚类分析、关联分析和离群点分析等常用技术。

13.网络通信基础

计算机网络连接一组计算机,并允许不同计算机的用户与其他用户共享资源。网络有助于所有连接的计算机之间的通信,并可能给人一种单一的、无所不在的计算机的错觉。连接到网络的每台计算机或设备都称为网络节点。

为了从计算机网络提供的功能和能力中获益,出现了许多计算范式。这些模式包括分布式计算、网格计算、互联网计算和云计算。

13.1. 网络类型

计算机网络并不都是相同的,可以根据各种各样的特征来分类,包括网络的连接方式、有线技术、无线技术、规模、网络拓扑、功能和速度。但大多数人熟悉的分类是基于网络的规模。

  • 个人区域网/家庭网络是一种计算机网络,用于计算机和靠近一个人的不同信息技术设备之间的通信。连接到这种网络的设备可以包括pc、传真、pda和tv。这是构建物联网的基础。
  • 局域网(LAN)连接有限地理区域内的计算机和设备,如校园、计算机实验室、办公楼或位置较近的建筑群。
  • 校园网是由有限地理区域内的局域网(LAN)互连而成的计算机网络。
  • 广域网(WAN)是一种覆盖大地理区域的计算机网络,例如城市或国家,甚至跨越洲际距离。仅限于城市的广域网有时称为城域网。
  • 互联网是连接许多(也许所有)国家的计算机的全球网络。

其他分类可以将网络分为控制网络、存储网络、虚拟专用网络(VPN)、无线网络、点对点网络和物联网。

13.2. 基本网络组件

所有网络都由相同的基本硬件组件组成,包括计算机、网络接口卡(NIC)、网桥、集线器、交换机和路由器。所有这些组件在网络术语中都被称为节点。每个组件执行一个独特的功能,这对于数据的打包、连接、传输、放大、控制、解包和解释都是必不可少的。例如,中继器放大信号,交换机执行多对多连接,集线器执行一对多连接,接口卡连接到计算机并执行数据打包和传输,网桥将一个网络与另一个网络连接,路由器本身就是一台计算机,它执行数据分析和流控制来调节来自网络的数据。
各种网络组件所执行的功能对应于七层开放系统互连(OSI)网络模型的一个或多个级别所指定的功能,这将在下面讨论。

13.3. 网络协议和标准

计算机之间使用协议进行通信,协议规定了用于打包和解包数据的格式和规则。为了方便通信和更好的结构,网络协议被分为不同的层,每一层处理通信的一个方面。例如,物理层处理要通信的各方之间的物理连接,数据链路层处理原始数据传输和流控制,网络层处理将数据打包和取消打包成相关各方可以理解的特定格式。最常用的OSI网络模型将网络协议分为七层,如图13.5所示。

需要注意的一点是,并不是所有的网络协议都实现OSI模型的所有层。例如,TCP/IP协议既不实现表示层也不实现会话层。

每个层可以有多个协议。例如,UDP和TCP都工作在IP网络层之上的传输层上,提供尽力而为、不可靠传输(UDP)和可靠传输功能(TCP)。物理层协议包括令牌环、以太网、快速以太网、千兆以太网和无线以太网。数据链路层协议包括帧中继、异步传输模式(ATM)和点对点协议(PPP)。应用层协议包括光纤通道、小型计算机系统接口(SCSI)和蓝牙。对于每一层甚至每一个单独的协议,可能有国家或国际组织制定的标准来指导相应协议的设计和开发。

Application Layer
Presentation Layer
Session Layer
Transport Layer
Network Layer
Data link Layer
Physical Layer

Figure 13.5. The Seven-Layer OSI Networking Model

13.4. 互联网

因特网是一个由政府、学术、企业、公共和私人计算机网络相互连接的全球系统。在公共领域,通过被称为互联网服务提供商(ISP)的组织接入互联网。ISP维护一个或多个交换中心,称为存在点,它实际上将用户连接到Internet。

元器件数据手册IC替代型号,打造电子元器件IC百科大全!

相关文章