免费智能真题库 > 历年试卷 > 系统分析师 > 2017年上半年 系统分析师 下午试卷 案例
  第3题      
  知识点:   并行处理   操作系统   程序设计   程序设计方法   进程   开发人员   模块设计   软件架构   线程   硬件   硬件架构

 
【说明】
近年来,多核技术已被广泛应用于众多安全关键领域(如:航空航天等)的电子设备中,面向多核技术的并行程序设计方法已成为软件人员急需掌握的主要技能之一。某宇航公司长期从事宇航电子设备的研制工作,随着宇航装备能力需求的提升,急需采用多核技术以增强设备的运算能力、降低功耗与体积,快速实现设备的升级与换代。针对面向多核开发,王工认为多核技术是对用户程序透明的,开发应把重点放在多核硬件架构和硬件模块设计上面,而软件方面,仅仅需要选择一款支持多核处理器的操作系统即可。而李工认为,多核架构能够使现有的软件更高效地运行,构建一个完善的软件架构是非常必要的。提高多核的利用率不能仅靠操作系统,还要求软件开发人员程序设计 中考虑多进程或者多线程并行处理的编程问题。
 
问题:3.1   (12分)
请用300字以内文字说明什么是多核技术和多线程技术,并回答李工的意见是否正确,为什么?
 
问题:3.2   (6分)
在多核环境下,线程的活动有并行和并发两种方式,请用300字以内的文字说明这两种方式的含义及差别。
 
问题:3.3   (7分)
请根据自己所掌握的多核、多线程的知识,判别表3-1给出的说法是否正确,并将答案写在答题纸上对应空白处(填写正确或错误)。
 
 
 

   知识点讲解    
   · 并行处理    · 操作系统    · 程序设计    · 程序设计方法    · 进程    · 开发人员    · 模块设计    · 软件架构    · 线程    · 硬件    · 硬件架构
 
       并行处理
        本节主要介绍几种多处理机系统。
        (1)超级标量处理机。在超级标量处理机中,配置了多个功能部件和指令译码电路,采取了多条流水线,还有多个寄存器端口和总线,因此可以同时执行多个操作,以并行处理来提高机器速度。它可以同时从存储器中取出几条指令同时送入不同的功能部件。超级标量机的硬件是不能重新安排指令的前后次序的,但可以在编译程序时采取优化的办法对指令的执行次序进行精心安排,把能并行执行的指令搭配起来。
        (2)超级流水线处理机。超级流水线处理机的周期比其他结构的处理机短。与超级标量计算机一样,硬件不能调整指令的执行次序,而由编译程序解决优先问题。
        (3)超长指令字处理机。超长指令字处理机是一种单指令流多操作码多数据的系统结构,编译程序在编译时把这个能并行执行的操作组合在一起,成为一条有多个操作段的超长指令,由这条超长指令控制计算机中多个互相独立的功能部件,每个操作段控制一个功能部件,相当于同时执行多条指令。
        (4)向量处理机。向量处理机是一种具有向量数据表示、并设置有相应的指令和硬件、能对向量的各个元素进行并行处理的计算机。当进行向量运算时,它的性能要比大型机好得多。向量处理机有巨型计算机和向量协处理机(或称为数组处理机)两种类型,巨型计算机能对大量的数据进行浮点运算,同时它还是可以进行标量计算和一般数据处理的通用计算机。向量处理机一般采用流水线工作,当它处理一条数组指令时,对数组中的每个元素执行相同的操作,而且各元素间是互相无关的,因此流水线不会阻塞,能以每个时钟周期送出一个结果的速度运行。为了存储系统能及时提供数据,向量处理器配有一个大容量的、分成多个模块交错工作的主存储器。为了提高运算速度,在向量处理机的运算部件中可采用多个功能部件,例如向量部件、浮点部件、整数运算部件和计算地址用的地址部件。向量协处理机是专门处理浮点和向量运算的数组处理机,它连接到主机总线上。
        (5)多处理机系统。多处理机具有两个或两个以上的处理机,共享I/O子系统,在操作系统统一控制下,通过共享主存或高速通信网络进行通信,协同求解一个个复杂的问题。多处理机通过利用多台处理机进行多任务处理来提高速度,利用系统的重组能力来提高可靠性、适应性和可用性。多处理机结构具有共享存储器和分布存储器两种不同的结构。具有共享存储器的多处理机中,程序员无数据划分的负担,编程容易;系统处理机数目较少,不易扩充。具有分布式存储器的多处理机结构灵活;容易扩充;难以在各个处理单元之间实现复杂数据结构的数据传送;任务动态分配复杂;现有软件可继承性差;需要设计新的并行算法。多处理机系统属于MIMD系统,与SIMD的并行处理机相比,有很大的差别。其根源就在于两者的并行性的层次不同,多处理机要实现的是更高一层的作业任务间的并行。
        (6)大规模并行处理机。并行处理机有时也称为阵列处理机。并行处理机使用按地址访问的随机存储器,以SIMD方式工作。主要用于要求大量高速进行向量矩阵运算的应用领域。并行处理机制并行性来源于资源重复,把大量相同的处理单元通过互联网连接起来,在统一的控制器控制下,对各自分配来的数据并行完成同一条指令所规定的操作。并行处理机有两种基本结构类型:采用分布式存储器的并行处理结构和采用集中式共享存储器的并行处理结构。分布式存储器的并行处理结构中,每一个处理机都有自己局部的存储器,只要控制部件将并行处理的程序分配至各处理机,它们便能并行处理,各自从自己的局部存储器中取得信息。而共享存储多处理结构中的存储器是集中共享的,由于多个处理机共享,在各处理机访问共享存储器时会发生竞争。因此,需采取措施尽可能避免竞争的发生。MPP是由众多的微处理器(从几百到上万)组成的大规模的并行系统。MPP的出现成为计算机领域中一个研发热点,被用作开发万亿次甚至更高速的巨型机的主要结构。MPP可以采用市场上的出售的RISC处理器,所以有很高的性价比。
        (7)对称多处理机。SMP目前也基于RISC微处理器。它与MPP最大的差别在于存储系统。SMP有一个统一共享主存空间,而MPP则是每个微处理器都拥有自己的本地存储器。
        按多处理机之间连接的紧密程度,多机系统可分为紧耦合系统和松耦合系统两种。
        紧耦合系统又称为直接耦合系统,是指各处理机之间通过互连网络共享内存。紧耦合多机系统由P台处理机、m个存储器模块、d个I/O通道和3个互联网络构成。处理机-存储器网络实现处理机与各存储模块的连接。处理机中断信号网络实现多处理机之间的互连。处理机-I/O互联网络实现处理机与外设的连接。每个处理机可自带局部存储器,也可自带Cache。存储器模块可采用流水工作方式。紧耦合多机系统多用于并行作业中的多任务,一般处理机是同构的。例如,SMP属于紧耦合多机系统。
        松耦合系统又称为间接耦合系统,是指各处理机间通过共享I/O子系统、通道或通信线路实现机间通信,不共享内存。松耦合多处理机由P个处理机、1个通道、1个仲裁开关和消息传送系统。构成每个处理机带有一个局部存储器和一组I/O设备。在仲裁开关的通道中有高速通信存储,用来缓冲传送的信息块。松散耦合多处理机较适合粗粒度的并行计算。例如,MPP属于松耦合多机系统。
 
       操作系统
        编写嵌入式软件有两种选择:一是自己编写内核;二是使用现成的操作系统。如果嵌入式软件只需要完成一项非常小的工作,例如在电动玩具、空调中,就不需要一个功能完整的操作系统。但如果系统的规模较大、功能较复杂,那么最好还是使用一个现成的操作系统。可用于嵌入式系统软件开发的操作系统有很多,但关键是如何选择一个适合开发项目的操作系统,可以从以下几点进行考虑:
        (1)操作系统提供的开发工具。有些实时操作系统只支持该系统供应商的开发工具,因此,还必须从操作系统供应商处获得编译器、调试器等;而有的操作系统应用广泛,且有第三方工具可用,因此选择的余地比较大。
        (2)操作系统向硬件接口移植的难度。操作系统到硬件的移植是一个重要的问题,是关系到整个系统能否按期完工的一个关键因素。因此,要选择那些可移植性程度高的操作系统,以避免因移植带来的种种困难。
        (3)操作系统的内存要求,有些操作系统对内存有较大要求。
        (4)操作系统的可剪裁性、实时性能等。
 
       程序设计
               类和继承
               1)类
               一个类是一些属性和方法的封装体,类的定义用关键字class声明,用关键字public、protected、 private指定类的成员的存取控制属性:private(私有)成员只有类内部的方法才能访问,protected(保护)成员派生类和同一文件夹下的类可以访问,public(公有)成员可以从类的外部访问。默认是public。这体现了面向对象的以下指导思想:尽量将类内部的细节隐藏起来,对类的属性的操作应该通过类的方法来进行。
               另外,public还可以用来修饰类,public类能够被其他文件夹下的类访问,非public类只能被同一文件夹下的类访问。一个.java文件中可以包含多个类,会被编译成多个.class文件,但只能有一个public类,而且该类名要和文件名一样。
               2)继承
               Java中用关键字extends表示类间的继承关系。父类的公有属性和方法成为子类的属性和方法,子类如果有和父类的同名、同参数类型的方法,那么子类对象在调用该方法时,调用的是子类的方法,亦即方法的重置。如果想要调用父类的同名方法,需要用super关键字(属性同理)。
               子类的对象可以作为祖先类的对象使用,即所谓类的向上转换,反之则不行。具体表现在:可以用子类对象来对祖先类对象赋值,可以用子类对象作为实参去调用以父类对象为形参的函数。
               对象的引用本质
               Java中的对象实际上是对象的引用,本质上和C语言中的指针是一样的;但也和C语言指针不尽相同,例如,不能自增、自减,不能强制转换成其他类型。
               例如:
               
               构造方法
               构造方法就是类的对象生成时会被调用的方法。每个类至少有一个构造方法(Constructor),也称构造函数。构造方法的名字和类名相同,没有任何返回类型。每个类都有一个默认的构造方法,但当用户自定义了构造方法后,默认的构造函数就不再有效了。
               重载
               同一个类中的两个或两个以上方法,名字相同,而参数个数不同或参数类型不同,称为重载。注意:不能有各方法名字和参数都一样,而仅仅返回值类型不同。
               静态属性和静态方法
               静态属性和静态方法的声明用关键字static实现,一个类的静态属性只有一份,由所有该类的对象共享。不需要创建对象也能访问类的静态属性和方法,访问方式为"类名.静态属性或静态方法",静态方法与对象无关,因此不能在静态方法中访问非静态属性和调用非静态方法。
               this和super关键字
               这两个关键字颇为重要。this代表当前对象,super代表当前对象的父类的东西。
               this主要用途有以下两个。
               (1)一个构造函数调用另一个构造函数,对构造函数的调用必须是第一条语句。
               (2)将对象自身作为参数来调用一个函数。
               super的用途如下:在子类中调用父类的同名方法,或在子类的构造函数中调用父类的构造函数,此时亦必须是第一条语句。
               多态
               所谓多态,是指通过基类对象调用一个基类和派生类都有的方法时,在运行时才能确定到底调用的是基类的方法还是派生类的方法。多态的好处是增加了程序的可扩展性。多态是通过动态联编实现的,即编译时不确定,程序运行时才确定调用哪个函数。
               抽象类与接口
               1)抽象类
               抽象类通过关键字abstract实现,抽象类的目的是定义一个框架,规定某些类必须具有的一些共性。
               包含抽象方法的类一定是抽象类,所谓抽象方法是指没有函数体的方法。
               抽象类的直接派生类必须实现其抽象方法;抽象类只能用于继承,不能创建对象。
               2)接口(Interface)
               接口用关键字interface声明,只能用于继承。注意:此时关键字为implements(实现)。接口用于替代多继承的概念,能实现多继承的部分特点,又避免了多继承的混乱,还能起到规定程序框架的作用。注意:接口也可以用于多态。
               直接继承了接口的类,必须实现接口中的抽象方法;间接的则可以实现,也可以不实现。
               3)抽象类与接口的异同
               接口和抽象类都不能创建对象。
               抽象类不能参与多继承,抽象类可以有非静态的成员变量,可以有非抽象方法;接口可以参与多继承,所有属性都是静态常量,所有方法都是public抽象方法。
               异常处理
               1)异常概念
               异常,即出错,比如0作为除数、找不到类、打开文件错误、数组越界等。异常如果不进行处理,那么程序运行就会结束;如果进行处理,那么会在执行完异常处理代码后继续运行。
               Java中所有异常类均继承自类Exception。
               Java中的异常类层次结构如下:
               
               此外,还有EOFException、 FileNotFoundException、 MalformedURLException等。
               2)捕获异常
               异常处理的典型用法如下,将可能出现异常的代码放在try块中,其后由一个或多个catch捕获相应异常进行处理,注意只执行第一个匹配的catch块,忽略后面的。
               
               如果某个方法中所产生的异常该方法自己没有处理,那么可以在调用该方法的方法中进行处理,如果自己处理了,那么调用它的方法就无法得到该异常。
               3)抛出异常
               异常除了运行中系统产生的之外,也可以主动抛出异常,用关键字throw,如throw new Exception()。注意:throw只能抛出Throwable子类的异常。
               4)带throws关键字的方法
               带throws关键字的方法声明如下:
               
               强制调用该方法的方法必须处理可能发生的异常,或者将异常重新定向。假定方法A带throws关键字,而方法B中调用了方法A,则方法B中必须有处理方法A中可能产生的异常的语句,或者方法B也带throws关键字,指明调用方法B的方法必须处理异常。
               final关键字
               用final关键字定义的常量,在其初始化或第一次赋值后,其值不能被改变。常量必须先有值,然后才能使用。对于常量的第一次赋值只能在构造函数中进行。
               final对象的值不能被改变,指的是该对象不能再指向其他对象,而不是指不能改变当前对象内部的属性值。
               函数参数声明为final后,函数中不能改变其值。
               final方法是不能被重置的方法。
               final类不能被继承,其所有方法都是final的,但属性可以不是final的。
 
       程序设计方法
               程序设计基础知识
               程序设计即编码(coding),也就是为各个模块编写程序。这是系统实现阶段的核心工作。在系统开发的各个阶段中,编程是最容易的、也是人们已掌握得较好的一项工作。根据结构化方法设计了详细的方案,又有了高级语言,初级程序员都可以参加这一阶段的工作。当然,程序员的水平决定了程序的水平。
                      程序设计概述
                      (1)程序设计的概念和要求。
                      程序设计阶段是系统生命周期中详细设计之后的阶段。系统设计是程序设计工作的先导和前提条件。程序设计的任务是使用选定的语言设计程序,把系统设计阶段所得到的程序设计说明书中对信息处理过程的描述,转换成能在计算机系统运行的源程序。
                      程序设计又被称为编码,由程序设计人员承担,编码工作与系统分析设计阶段的工作相比,是相对比较容易的。
                      程序设计人员应当仔细阅读系统全部文档,以保证系统设计与系统实施的一致性;深刻理解、熟练掌握并正确运用程序设计语言和软件开发的环境和工具,保证功能的正确实现。
                      对程序设计的质量要求如下。
                      .程序的正确性。包括正确运用程序设计语言环境和满足系统设计的功能要求。
                      .源程序的可读性。便于其他人员能够读懂和维护。
                      .较高的效率。程序应较少占用内存而具有较高的运行速度。
                      程序设计质量的几个方面常常是有矛盾的,因此应该结合具体情况,权衡处理。
                      (2)程序设计的步骤。
                      .了解计算机系统的性能和软硬件环境。
                      .充分理解系统分析、系统设计的全部文档。
                      .根据设计要求和软硬件环境,选定程序设计语言。
                      .编写程序代码。
                      .程序的检查、编译和调试。
                      程序的标准
                      对于什么是“好程序”,早期观点与现在有很大不同。早期计算机内存小、速度慢,人们往往把程序的长度和执行速度放在很重要的位置。费尽心机缩短程序长度、减少存储量、提高速度。现在情况有了很大的不同,一般认为好程序应具备下列特点。
                      .正常工作。
                      .调试代价低。
                      .易于维护。
                      .易于修改。
                      .设计不复杂。
                      .运行效率高。
                      正常工作是最基本的,一个根本不能够工作的程序当然谈不上“好”,谈执行速度、程序长度等指标也毫无意义;调试代价低,即花在调试上的时间少,这一条是衡量程序好坏,也是衡量程序员水平的一个重要标志;其他要求程序可读性强,易于理解。
                      在相当长的一个时期里,人们认为程序是用于给机器执行的而不是给人阅读的。因而程序员中就存在严重的低估编程方法、不注意程序风格的倾向,认为可以随意编写程序,只要结果正确就行了,读这种程序像读“天书”。可读性(readability)是后来提出的新概念,它主张程序应使人们易于阅读,编程的目标是编出逻辑上正确而又易于阅读的程序。程序可读性好,自然易于理解、易于维护,并将大大降低隐含错误的可能性,从而提高程序的可靠性。
                      要使程序的可读性好,程序员应有一定的写作能力。他应能写出结构良好、层次分明、思路清晰的文章。有人说:“对于程序员来说,最重要的不是学习程序设计语言等,而是英语(日语、汉语)”。程序员在写程序时应该记往:程序不仅是给计算机执行的,也是供人阅读的。
                      要使程序可读性好,总的要求是使程序简单、清晰。人们总结了使程序简单、清晰的种种技巧和方法,包括的内容如下。
                      .用结构化方法进行详细设计。
                      .程序中包含说明性材料。
                      .良好的程序书写格式。
                      .良好的编程风格。
                      程序设计语言的特性与选择
                      程序设计语言是程序设计人员用以求解问题的工具,程序设计人员必须适应特定的程序设计语言的限制。程序设计语言的特性表现为其心理特性、技术特性及工程特性。
                      程序的实现最终要靠人来完成,因此人的因素对程序的实现质量有很大的影响。语言的心理特性,主要表现在编写程序时对人的影响,包括对程序代码的理解等。它在语言中表现为以下几个方面:
                      (1)歧义性。
                      程序设计语言总是以一种确定的方式对源程序的语句进行解释,但程序员可能对其有不同的理解,形成歧义性。歧义影响程序的可读性,容易产生错误。
                      (2)简洁性。
                      是指在用某种程序设计语言编写程序时,人脑必须记忆的关于程序的信息量,用来表示简洁性的属性有:该语言是否便于构造逻辑块及结构化程序,有多少种关键字及缩写;有多少数据类型及默认说明;有多少个算术运算符及逻辑运算符:有多少内部函数。简洁性影响程序的理解性、可读性。
                      (3)局部性与顺序性。
                      人的记忆能力通常分为综合和顺序两类,综合是指把事物作为一个整体记忆及识别的能力,顺序能力是指预知序列中下一个元素的能力。
                      局部性是指程序设计语言的综合特性。当语句可以组合成程序块时,当结构化构造可以直接实现时,以及编写出的程序表现出高度的模块化及内聚时,局部性就比较显著。如果语言提供不连续的处理,就要降低局部性。顺序性是指一种心理特性,它会影响到软件的维护工作。当遇到逻辑操作的线性序列时,人们易于理解,而很多的分支或多个循环就违反了处理的顺序性。
                      (4)传统性。
                      对某种语言的依赖,影响程序员学习新语言的积极性。
                      从软件工程的观点来看,程序设计语言特性的表现形式包括如下内容。
                      (1)是否易于把设计转换为程序,从理论上说,根据系统设计说明去编写程序,其过程应该是明确的。把设计变成程序的难易程度实际上反映了程序设计语言与设计说明相接近的程度。如果该语言能直接实现结构化程序构造,能直接实现复杂的数据结构,能直接实现特殊的输入输出处理、位操作及字符串操作,就能很方便地把设计转换成源程序。
                      (2)编译效率,程序设计语言的编译器的性能决定了目标代码的运行效率,如果对软件性能要求较高,则配有优化编译器的程序设计语言是很有吸引力的。
                      (3)可移植性,可移植性是程序设计语言的一种特性,它的含义是,当源程序从一个处理器转换到另一个处理器,或者从一个编译器转换到另一个编译器时,源程序本身不需修改或仅需少量修改。
                      (4)是否有开发工具,使用开发工具,可以缩短编写源程序的时间,可以改进源程序的质量。这些工具可能包括排错编译器、源程序格式编排功能、内部编辑功能,用于源程序控制的工具,各种应用领域中的详尽的子程序库等。
                      (5)源程序的可维护性,设计文档是理解软件的基础,但还必须读懂源程序,才能根据设计的改动去修改源程序。是否易于从设计转变为源程序和语言本身的某些规定,是可维护性的两个主要因素。
                      语言的技术特性对系统开发的各个阶段都有一定的影响。确定系统需求后,要根据项目的特性选择相应特性的语言,有的要求提供复杂的数据结构,有的要求实时处理强,有的要求能方便地进行数据库的操作。特别是系统设计转化为程序代码时,转化的质量往往受语言性能的影响可能还会影响到设计方法。
                      为一个特定的设计课题选用程序设计语言时,必须从心理特性、工程特性及技术特性几个方面加以考虑。从所要解决的课题出发确定对语言的要求,并确定这些要求的相对重要性。既然一种语言不可能同时满足多个要求,那么就应该分别对各个要求进行衡量,比较各种可用语言的适用程度。
                      选择程序设计语言通常应考虑的因素有,项目的应用领域、系统开发的方法、算法及数据结构的复杂性、系统运行的环境、语言的性能、开发人员的知识及对语言的熟悉程度。
                      程序设计风格
                      (1)标识符的命名。
                      标识符是文件名、变量名、常量名、函数名、程序名、段名和程序标号等用户定义的名字的总称。应注意以下规则。
                      .命名规则在程序中前后一致。
                      .命名时一定要避开程序设计语言的保留字。
                      .尽量避免使用意义容易混淆的标识名。
                      (2)程序中的注释。
                      ①序言性注释。
                      在每个程序或模块的开头的一段说明,起对程序理解的作用,一般包括以下内容:
                      .程序的标识、名称和版本号。
                      .程序功能描述。
                      .接口与截面描述,包括调用及被调用关系、调用形式、参数含义以及相互调用的程序名。
                      .输入/输出数据说明,重要变量和参数说明。
                      .开发历史,包括原作者、审查者、修改者、编程日期、编译日期、审查日期、修改日期等。
                      .与运行环境有关的信息,包括对硬件、软件资源的要求,程序存储与运行方式。
                      ②解释性注释。
                      一般嵌在程序之中,与要注释的部分匹配。
                      进行程序注释应注意以下问题。
                      .注释一定要在程序编制中书写。
                      .解释性注释不是简单直译程序语句,应能说明“做什么”。
                      .一定要保证注释与程序的一致性,程序修改时注释也必须修改。
                      (3)程序的布局格式。
                      利用空格、空行和缩进等方式改善程序的布局,取得较好的视觉效果。
                      (4)数据说明。
                      先说明、后引用,应使数据便于理解和维护。
                      (5)程序语句的结构。
                      一般原则是:语旬简明、直观,直接反映程序设计意图,避免过分追求程序的技巧性,不能为追求效率而忽视程序的简明性、清晰性。应遵守如下规则。
                      .每行写一个语句。
                      .避免使用复杂的条件判断。
                      .尽量减少使用否定的逻辑条件进行测试。
                      .尽量减少循环嵌套和逻辑嵌套的层数。
                      .应采用空格、括号等符号使复杂表达式的运算次序清晰直观。
                      (6)输入和输出。
                      输入输出注意以下内容。
                      .针对用户的不同对象、特点和要求设计人机交互方式。
                      .程序在运行过程中应有表明当前状态的说明信息。
                      .交互式输入的请求应有明确的提示。
                      .对于输出的方式与格式,允许用户进行选择和应答。
                      .应设计完备的错误检测和恢复功能。
                      (7)程序的运行效率。
                      主要指计算机运行时间和存储空间两个方面,主要注意事项如下。
                      .编写程序前应尽量简化算术表达式和逻辑表达式,并尽量用逻辑表达式。
                      .尽量选用好的算法。
                      .仔细研究循环嵌套,确定语句是否可以移出循环体。
                      .尽量避免使用多维数组。
                      .尽量避免使用指针和复杂的表。
                      .充分利用语言环境提供的函数。
                      .使用有良好优化特性的编译程序。
               结构化程序设计
               结构化程序设计被称为软件发展中的第一个里程碑,其影响比前两个里程碑(子程序、高级语言)更为深远。结构化程序设计的概念和方法、支持这些方法的一整套软件工具,构成了“结构化革命”。这是存储程序计算机问世以来,对计算机界影响最大的一个软件概念。对于什么是“结构化程序设计”,至今还没有被普遍接受的定义。通常认为结构化程序设计包括以下4方面的内容。
                      限制使用GOTO语句
                      从理论上讲,只用顺序结构、选择结构、循环结构这三种基本结构就能表达任何一个只有一个入口和一个出口的程序逻辑。为实际使用方便,往往允许增加多分支结构、REPEAT型循环等两三种结构。程序中可以完全不用GOTO语句。这种程序易于阅读、易于验证。但在某些情况下,例如从循环体中跳出,使用GOTO语句描述更为直截了当。
                      因此,一些程序设计语言还是提供了GOTO语句。无限制地使用GOTO语句,将使程序结构杂乱无章、难以阅读、难以理解,其中容易隐含一些错误。
                      逐步求精的设计方法
                      在一个程序模块内,先从该模块功能描述出发,一层层地逐步细化,直到最后分解、细化成语句为止。
                      自顶向下的设计、编码和调试
                      这是把逐步求精的方法由程序模块内的设计推广到一个系统的设计与实现。这正是本书介绍的结构化方法的来源。
                      主程序员制的组织形式
                      这是程序人员的组织形式。一个主程序员组的固定成员是主程序员一人,辅助程序员一人,程序资料员(或秘书)一人。其他技术人员按需要随时加入组内。主程序员负责整体项目的开发,并负责关键部分的设计、编码和调试。辅助程序员在细节上给主程序员以充分的支持。主程序员、辅助程序员必须在程序技术方面和项目管理方面具有经验和才能,必须完全熟悉该项目的开发工作。这种组织方式的好处在于显著减少了各子系统之间、各程序模块之间通信和接口方面的问题。把设计的责任集中在少数人身上,有利于提高质量。
                      作为这种组织形式中的一个程序员,不仅应具备程序设计的基本知识,还要对项目所在的领域有较深入的了解、熟悉开发的技术环境,因而能承担一定的程序编写工作,更为重要的是必须有高度的组织纪律性和团队精神,使自己的工作融入整个系统,与组内其他成员协调一致地工作。为此,必须严格遵守以下几项规则。
                      .不使用可能干扰其他模块的命令或函数。
                      .按总体设计的要求传递参数,不随意修改其内容与含义。
                      .按规定的统一格式操作公用文件或数据库。
                      .按统一的原则使用标识符。
                      .按统一要求编写文档。
                      .保持程序风格的一致。
               面向对象的程序设计
               传统的过程式程序设计随着软件危机和应用系统的不断膨胀越来越显得力不从心,随着20世纪70年代Smalltalk及Modula-2等面向对象的编程语言(Object Oriented Programming Language, OOPL)的出现,以及C++的发展成熟,面向对象程序设计(Object Oriented Programming, OOP)思想得到了广泛的认同和普及。至20世纪90年代,各种程序语言或工具都融入了这一思想,其优越性是有目共睹的,它已成为这一时代软件产业的主体技术。
               在OOP方法中,一个对象即是一个独立存在的实体,对象有各自的属性和行为,彼此以消息进行通信,对象的属性只能通过自己的行为来改变,实现了数据封装,这便是对象的封装性。而相关对象在进行合并分类后,有可能出现共享某些性质,通过抽象后使多种相关对象表现为一定的组织层次,底层次的对象继承其高层次对象的特性,这便是对象的继承性。另外,对象的某一种操作在不同的条件环境下可以实现不同的处理、产生不同的结果:这就是对象的多态性。现有的OOPL中都不同程度地实现了对象的以上三个性质。
                      封装性
                      一般以类(class)来创建一个对象,类表现为一种数据结构。对外提供的界面包括一组数据以及操作这些数据的方法(函数或过程),而隐藏了内部实现的细节,对象操作者只需要了解该对象的界面即可。这样大大增强了模块化程度,很好地实现了软件重用和信息隐藏。
                      为了更好地保持安全性和独立性,类有部分数据可以被定义为私有教据,其他类的对象或过程不能直接访问私有数据,而一般情况下利用消息机制向对象发送消息,对象所有类就需要定义对应的消息响应函数,主动接受消息并做处理,这也是OOPL的一大特点。
                      继承性
                      类通过继承被定义成不同的层次结构,将相关类的特点抽象出来作为父类,子类继承父类的结构和方法后,再定义各自特定的数据和操作,或者还可以通过重载将父类的某些特殊操作进行重新定义。继承一个单一的父类时叫单继承,如果有两个或两个以上的父类则是多继承。这样做的目的不仅体现了软件重用技术,同时又可最大限度地精简程序、减少冗余代码,极大地提高了程序开发和运行效率。
                      多态性
                      类的某些操作允许同一名称具有多种语义。OOPL的这些特点使程序员进行面向对象程序设计时与进行过程式的程序设计有很大的不同,体现在以下这些方面。
                      .设计程序不采用顺序性的结构,而是采用对象本身的属性与方法来解决问题。
                      .在解决问题的过程中,可以直接在对象中设计事件处理程序(接受事件消息),而不用调用子过程严格地按顺序执行,很方便地让用户实现自由无顺序的操作。
                      .数据与程序不是分离的,数据是特定对象的数据,也只有对象的函数或过程才能对数据进行处理,一个对象中的函数或过程共享对象的数据,解决了因调用子过程出现大量数据传递的情况(如函数返回值和较多参数)。
                      .不用设计公用程序模块,因特定方法下的公用模块很难再被扩展为更复杂的处理方式,只需设计类就可以实现重用,而且类库中提供大量基类,掌握它们后可以加快开发过程,开发小组还可以按自己设想的基类放入类库共享。
                      .OOPL非常适合于Windows环境下的程序开发,可以充分利用Windows的各种资源来构造应用程序,这也就需要程序员比较熟悉Windows。
               可视化程序设计
               虽然OOPL提高了程序的可靠性、可重用性、可扩充性和可维护性,但应用软件为了适应Windows界面环境,使用户界面的开发越来越复杂,有关这部分的代码所占比例也越来越大,因此,微软公司推出Visual Basic以后,可视化编程技术得到了极大的欢迎,编程人员不再受Windows编程的困扰,能够所见即所得地设计标准的Windows界面。
               可视化编程技术的主要思想是用图形工具和可重用部件来交互地编制程序。它把现有的或新建的模块代码封装于标准接口封包中,作为可视化编程编辑工具中的一个对象,用图符来表示和控制。可视化编程技术中的封包可能由某种语言的一个语句、功能模块或数据库程序组成,由此获得的是高度的平台独立性和可移植性。在可视化编程环境中,用户还可以自己构造可视控制部件,或引用其他环境构造的符合封包接口规范的可视控制部件。增加了编程的效率和灵活性。
               可视化编程一般基于事件驱动的原理。用户界面中包含各种类型的可视控制部件,如按钮、列表框和滚动条等,每个可视控制部件对应多个事件和事件驱动程序。发生于可视控制部件上的事件触发对应的事件驱动程序,以完成各种操作。编程人员只要在可视化编程工具的帮助下,利用鼠标或表单建立、复制、缩放、移动或清除各种已提供的控件,然后使用该可视化编程工具提供的语言编写每个控件对应的事件程序,最后可以用解释方式运行来测试程序。这样,通过一系列的交互设计就能很快地完成一个应用项目的编程。
               另外,一般可视化编程工具还有应用专家或应用向导提供模板,按照步骤对使用者进行交互式指导,让用户定制自己的应用,然后就可以生成应用程序的框架代码,用户再在适当的地方添加或修改以适应自己的需求。
               面向对象编程技术和可视化编程开发环境的结合,改变了应用软件只有经过专门技术训练的专业编程人员才能开发的状况。它使软件开发变得容易,从而扩大了软件开发队伍。由于大量软件模块的重用和可视控件的引入,技术人员在掌握这些技术之后,就能有效地提高应用软件的开发效率、缩短开发周期、降低开发成本,并且使应用软件界面风格统一,有很好的易用性。
 
       进程
        简单而言,一个进程就是一个正在运行的程序。一般来说,一个进程至少应该包括以下几个方面的内容。
        .相应的程序:进程既然是一个正在运行的程序,当然需要有相应程序的代码和数据。
        .CPU上下文:指程序在运行时,CPU中各种寄存器的当前值,包括:程序计数器,用于记录将要取出的指令的地址;程序状态字,用于记录处理器的运行状态信息;通用寄存器,用于存放数据或地址;段寄存器,用于存放程序中各个段的地址;栈指针寄存器,用于记录栈顶的当前位置。
        .一组系统资源:包括操作系统用来管理进程的数据结构、进程的内存地址空间、进程正在使用的文件等。
        进程有动态性、独立性和并发行三个特性。
        (1)动态性。进程是一个正在运行的程序,而程序的运行状态是在不断地变化的。例如,当一个程序在运行的时候,每执行完一条指令,PC寄存器的值就会增加,指向下一条即将执行的指令。而CPU中用来存放数据和地址的那些通用寄存器,它们的值肯定也不断地变化。另外,堆和栈的内容也在不断地变化,每当发生一次函数调用时,就会在栈中分配一块空间,用来存放此次函数调用的参数和局部变量。而当函数调用结束后,这块栈空间就会被释放掉。
        (2)独立性。一个进程是一个独立的实体,是计算机系统资源的使用单位。每个进程都有自己的运行上下文和内部状态,在它运行的时候独立于其他的进程。
        (3)并发性。从宏观上来看,在系统中同时有多个进程存在,它们相互独立地运行。
        下图表示四个进程A、B、C、D在系统中并发地运行。从中可以看出,虽然从宏观上来说,这四个进程都是在系统中运行,但从微观上来看,在任何一个特定的时刻,只有一个进程在CPU上运行。从时间上来看,开始是进程A在运行,然后是进程B在运行,然后是进程C和进程D。接下来又轮到了进程A去运行。因此,在单CPU的情形下,所谓的并发性,指的是宏观上并发运行,而微观上还是顺序运行,各个进程轮流去使用CPU资源。
        
        四个进程在并发运行
        在具体实现上,以CPU中的程序计数器PC为例,真正物理上的PC寄存器只有一个。当四个进程在轮流执行时,PC取值的运动轨迹是先在进程A内部流动,然后再到进程B的内部流动,再到进程C和D。从进程的独立性角度来说,每个进程都有“自己”独立的PC寄存器,即逻辑上的PC寄存器,它们的取值相互独立、互不影响。所谓的逻辑PC,其实就是一个内存变量。例如,在上图中,当进程A要执行的时候,就把A的逻辑PC的值拷贝到物理PC中,然后开始运行。当轮到B运行的时候,先把物理PC的当前值保存到A的逻辑PC中,然后再把B的逻辑PC的值装入到物理PC中,即可运行。这样就实现了各个进程的轮流运行。
 
       开发人员
        ①多媒体软件:项目负责人、学科教学专家、教学设计专家、软件工程师、多媒体素材制作专家和多媒体课件制作专家。
        ②多媒体电子出版物:策划编导、文字编辑、美术编辑、音乐编辑和多媒体编辑。
 
       模块设计
        模块设计阶段中,在系统内部划分成各个基础部分——模块结构,确定系统的总体结构。总体结构与各个分层模块结构的关系是程序实施的重要依据。模块结构采用模块结构图来表示。模块结构图是采用HIPO图形式绘制而成的框图。
        .名称,列出系统中各主要功能的结构图名称和它们之间的关系。
        .功能,用文字简单说明主要模块结构应具有的功能。
        .功能说明,说明是用伪码形式还是用结构化语言形式,或者其他自然语言形式描述模块结构图的。
        .评价。
        .验收,指设计人员验收的决定和处理情况。
 
       软件架构
        随着嵌入式技术的发展,特别是在后PC时代,嵌入式软件系统得到了极大的丰富和发展,形成了一个完整的软件体系,如下图所示。这个体系自底向上由3部分组成,分别是嵌入式操作系统、支撑软件和应用软件。
        
        嵌入式系统的软件架构
        嵌入式操作系统(Embedded Operating System,EOS)由操作系统内核、应用程序接口、设备驱动程序接口等几部分组成。嵌入式操作一般采用微内核结构。操作系统只负责进程的调度、进程间的通信、内存分配及异常与中断管理最基本的任务,其他大部分的功能则由支撑软件完成。
        嵌入式系统中的支撑软件由窗口系统、网络系统、数据库管理系统及Java虚拟机等几部分组成。对于嵌入式系统来讲,软件的开发环境大部分在通用台式计算机和工作站上运行,但从逻辑上讲,它仍然被认为是嵌入式系统支撑软件的一部分。支撑软件一般用于一些浅度嵌入的系统中,如智能手机、个人数字助理等。
        嵌入式系统中的应用软件是系统整体功能的集中体现。系统的能力总是通过应用软件表现出来的。
 
       线程
        传统的进程有两个基本属性:可拥有资源的独立单位;可独立调度和分配的基本单位。引入线程的原因是进程在创建、撤销和切换中,系统必须为之付出较大的时空开销,故在系统中设置的进程数目不宜过多,进程切换的频率不宜太高,这就限制了并发程度的提高。引入线程后,将传统进程的两个基本属性分开,线程作为调度和分配的基本单位,进程作为独立分配资源的单位。用户可以通过创建线程来完成任务,以减少程序并发执行时付出的时空开销。
        例如,在文件服务进程中可设置多个服务线程,当一个线程受阻时,第二个线程可以继续运行,当第二个线程受阻时,第三个线程可以继续运行……从而显著地提高了文件系统的服务质量及系统的吞吐量。
        这样,对于拥有资源的基本单位,不用频繁地切换,进一步提高了系统中各程序的并发程度。需要说明的是,线程是进程中的一个实体,是被系统独立分配和调度的基本单位。线程基本上不拥有资源,只拥有一点运行中必不可少的资源(如程序计数器、一组寄存器和栈),它可与同属一个进程的其他线程共享进程所拥有的全部资源。
        线程也具有就绪、运行和阻塞3种基本状态。由于线程具有许多传统进程所具有的特性,故称为“轻型进程(Light-Weight Process)”;传统进程称为“重型进程(Heavy-Weight Process)”。线程可创建另一个线程,同一个进程中的多个线程可并发执行。
        线程分为用户级线程(User-Level Threads)和内核支持线程(Kernel-Supported Threads)两类。用户级线程不依赖于内核,该类线程的创建、撤销和切换都不利用系统调用来实现;内核支持线程依赖于内核,即无论是在用户进程中的线程,还是在系统中的线程,它们的创建、撤销和切换都利用系统调用来实现。某些系统同时实现了两种类型的线程。
        与线程不同的是,不论是系统进程还是用户进程,在进行切换时,都要依赖于内核中的进程调度。因此,不论是什么进程都是与内核有关的,是在内核支持下进行切换的。尽管线程和进程表面上看起来相似,但它们在本质上是不同的。
 
       硬件
        硬件是计算机物理设备的总称,也称为硬件设备,通常是电子的、机械的、磁性的或光的元器件或装置,一般分为中央处理器、存储器和输入、输出设备。
 
       硬件架构
        微处理器是整个嵌入式系统的核心,负责控制系统的执行。外部设备是嵌入式系统同外界交互的通道,常见的外部设备有Flash存储器、键盘、输入笔、触摸屏、液晶显示器等,在很多嵌入式系统中还有与系统用途紧密相关的各种专用外设。嵌入式系统中经常使用的存储器有3种类型,分别是RAM、ROM和混合存储器。系统的存储器用于存放系统的程序代码、数据和系统运行的结果。
        嵌入式系统的核心部件是各种类型的嵌入式处理器,根据目前的使用情况,嵌入式处理器可以分为如下几类:
        (1)嵌入式微处理器。由通用计算机中的CPU演变而来,在功能上跟普通的微处理器基本一致,但是它具有体积小、功耗低、质量轻、成本低及可靠性高的优点。通常,嵌入式微处理器和ROM(Read Only Memory,只读存储器)、RAM(Random Access Memory,随机存取存储器)、总线接口及外设接口等部件安装在一块电路板上,称为单板计算机。
        (2)嵌入式微控制器。又称为单片机,整个计算机系统都集成到一块芯片中。嵌入式微控制器一般以某一种微处理器内核为核心,芯片内部集成有存储器、总线、总线逻辑、定时器/计数器、监督定时器、并口/串口、数模/模数转换器、闪存等必要外设。与嵌入式微处理器相比,嵌入式微控制器的最大特点是单片化,因而体积更小、功耗和成本更低,可靠性更高。
        (3)嵌入式数字信号处理器。一种专门用于信号处理的处理器,DSP(Digital Signal Processor,数字信号处理器)是芯片内部采用程序和数据分开的结构,具有专门的硬件乘法器,广泛采用流水线操作,提供特殊的DSP指令,可以用来快速实现各种数字信号的处理算法。目前,DSP在嵌入式系统中使用非常广泛,如数字滤波、快速傅里叶变换及频谱分析等。
        (4)嵌入式片上系统。一种在一块芯片上集成很多功能模块的复杂系统,例如,把微处理器内核、RAM、USB(Universal Serial Bus,通用串行总线)、IEEE 1394、Bluetooth(蓝牙)等集成到一个芯片中,构成一个嵌入式片上系统,从而大幅度缩小了系统的体积、降低了系统的复杂度、增强了系统的可靠性。在大量生产时,生产成本也远远低于单元部件组成的电路板系统。根据用途不同,嵌入式片上系统可以分为通用片上系统和专用片上系统两类。专用类的嵌入式片上系统一般是针对某一或某些系统而设计的。
   题号导航      2017年上半年 系统分析师 下午试卷 案例   本试卷我的完整做题情况  
1 /
2 /
3 /
4 /
5 /
 
第3题    在手机中做本题