201805系分下午真题
第 1 题
某公司是一家以运动健身器材销售为主营业务的企业,为了扩展销售渠道,解决原销售系统存在的许多问题,公司委托某软件企业开发一套运动健身器材在线销售系统。目前,新系统开发处于问题分析阶段,所分析各项内容如下所述:
(a)用户需要用键盘输入复杂且存在重复的商品信息;
(b)订单信息页面自动获取商品信息并填充;
(c)商品订单需要远程访问库存数据并打印提货单;
(d)自动生成电子提货单并发送给仓库系统;
(e)商品编码应与原系统商品编码保持一致;
(f)商品订单处理速度太慢;
(g)订单处理的平均时间减少30%;
(h)数据编辑服务器CPU性能较低;
(i)系统运维人员数量不能增加。
【问题2】(9分)
因果分析是问题分析阶段一项重要技术,可以得出对系统问题的真正理解,并且有助于得到更具有创造性和价值的方案。请将题目中所列(a) ~(i)各项内容填入表中(1) ~ (4)对应位置。
【问题3】(8分)
系统约束条件可以分为四类,请将类别名称填入表中(1) ~ (4)对应的位置。
答案与解析
- 试题难度:较难
- 知识点:案例分析>系统分析
- 试题答案:【问题1】问题分析阶段的四项主要任务包括:
1)研究问题领域
2)分析问题和机会3)分析业务过程
4)制定系统改进目标
【问题2】
(1)(f)
(2)(a)(c)(h)(3)(b)(d)(g)
(4)(e)(i)
【问题3】
(1)进度
(2)成本
(3)技术
(4)政策/标准 - 试题解析:【问题1】问题分析阶段的主要任务包括:1)研究问题领域
利用信息系统框架来列出和定义系统领域
数据 – 列出所有与系统当前存储的数据(在文件、数据库、表格中)有关的内容,并按照业务词汇定义每项内容。
过程 – 定义当前为其实现了业务响应(过程)的每个业务事件
接口 – 定义运行当前系统的所有地点和每个地点的所有用户
2)分析问题和机会
3)分析业务过程(可选)
4)制定系统改进目标
5)修改项目计划6)汇报分析结果和建议
7)阶段确认其中核心任务主要有四项:研究问题领域;分析问题和机会;分析业务过程;制定系统改进目标。
【问题2】
本题对于表格,第一栏填写系统真正的问题,第二栏填写问题产生的原因,第三栏填写系统改进的目标,第四栏填写设计约束。
根据题干描述,“(f)商品订单处理速度太慢;”是系统真正的问题,产生这个问题的原因在于“(a)用户需要用键盘输入复杂且存在重复的商品信息;”、“(c)商品订单需要远程访问库存数据并打印提货单;”、“(h)数据编辑服务器CPU性能较低;”,最终想要改进的目标有“(b)订单信息页面自动获取商品信息并填充;”、“(d)自动生成电子提货单并发送给仓库系统;”、“(g)订单处理的平均时间减少30%;”,系统的设计约束包括“(e)商品编码应与原系统商品编码保持一致;”、“(i)系统运维人员数量不能增加。 ”【问题3】
系统约束是系统在改进过程中必须满足、基本上无法被改变的条件。系统约束通常分为四类:进度约束、成本约束、技术约束、政策/标准约束。
第 2 题
某软件公司为共享单车租赁公司开发一套单车租赁服务系统,公司项目组对此待开发项目进行了分析,具体描述如下:
1)用户(非注册用户)通过手机向租赁服务系统进行注册,成为可租赁共享单车的合法用户,其中包括提供身份、手机号等信息,并支付约定押金;
2)将采购的共享单车注册到租赁服务系统后方可投入使用。即将单车的标识信息(车辆编号、二维码等)录入到系统;
3)用户(注册或非注册用户)通过手机查询可获得单车的地理位置信息以便就近取用;
4)用户(注册用户)通过手机登录到租赁服务系统中,通过扫描二维码或输入车辆编号以进行系统确认,系统后台对指定车辆状态(可用或不可用),以及用户资格进行确认,通过确认后对车辆下达解锁指令;
5)用户在用完车辆后关闭车锁,车辆自身将闭锁状态上报到租赁服务系统中,完成车辆状态的更新和用户租赁费用结算;
6)系统应具备一定的扩容能力,以满足未来市场规模扩张的需要。
项目组李工认为该系统功能相对独立,系统可分解为不同的独立功能模块,适合采用结构化分析与设计方法对系统进行分析与设计。但王工认为,系统可管理的对象明确,而且项目团队具有较强的面向对象系统开发经验,建议采用面向对象分析与设计方法。经项目组讨论,决定采用王工的建议,采用面向对象分析与设计方法开发系统。
表2-1系统分析方法比较
(a)确定目标系统概念类;
(b)实体关系图(ERD);
(c)用例图;
(d)通过功能分解方式把系统功能分解到各个模块中;
(e)交互图;
(f)数据流图(DFD);
(g)建立类间交互关系。
【问题2】 (12分)
请分析下面A~Q所列出的共享单车租赁服务系统中的概念类及其方法,在图2-1所示用例图(1)~ (12)处补充所缺失信息。
A.用户,B.共享单车,C.用户管理,D.注册,E.注销,F.用户查询,G.单车管理,H.租赁,I.归还,J.单车查询,K.费用管理,L.保证金管理,M.租赁费管理,N.数据存储管理,O.用户数据存储管理,P.单车数据存储管理,Q.费用结算,R.身份认证
图2-1单车租赁服务系统用例图
【问题3】(6分)
随着共享单车投放量以及用户量的增加会存在系统性能或容量下降问题,请用200字以内的文字说明,在系统设计之初,如何考虑此类问题?
答案与解析
- 试题难度:一般
- 知识点:案例分析>系统分析
- 试题答案:【问题】(1)(d)
(2)(b)(f)
(3)(a)(g)
(4)(c)(e)
【问题2】
(1)D:注册
(2)F:用户查询
(3)C:用户管理
(4)R:身份认证
(5)A:用户
(6)N:数据存储管理
(7)P:单车数据存储管理
(8)I:归还
(9)B:共享单车
(10)K:费用管理
(11)L:保证金管理
(12)Q:费用结算
【问题3】1、数据存储容量采用独立存储系统如阵列,对于数据存储可灵活扩展。2、服务器处理性能
1)考虑可扩展性问题,利用集群,扩展时采用水平扩展方式。
2)利用分布式存储方式,将各个城市的数据分散存储,减少压力,提升处理性能。
3)利用负载均衡技术,解决高并发问题。3、通信性能
服务器网口提速,对服务器接口进行灵活扩展如采用端口聚合等。
- 试题解析:
【问题1】
结构化分析(SA)主要分析内容是对系统进行模块划分,并把识别出来的功能分配到各模块中,通过细分的模块功能来达到系统整体功能的目的。结构化分析中以数据流图DFD表示模块间数据的交互关系,以实体关系图ERD表示数据模型,以及状态转换图STD表示行为模型。
面向对象分析(OOA)主要分析内容是对系统进行概念类定义,确定类与类之间的关系,以及确定类的职责,建立交互图等,从而对系统功能进行完整描述。在面向对象分析中,以用例图来表示概念类之间的关系,以交互图来表示相关对象之间的行为。
【问题2】
根据题干描述进行推导填空。
【问题3】
可以从多个方面考虑性能或容量的扩展。
1、数据存储容量采用独立存储系统如阵列,对于数据存储可灵活扩展。2、服务器处理性能
1)考虑可扩展性问题,利用集群,扩展时采用水平扩展方式。
2)利用分布式存储方式,将各个城市的数据分散存储,减少压力,提升处理性能。
3)利用负载均衡技术,解决高并发问题。3、通信性能
服务器网口提速,对服务器接口进行灵活扩展如采用端口聚合等。
第 3 题
某公司长期从事计算机产品的研制工作,公司领导为了响应国家军民融合的发展战略,决定要积极参与我国军用设备领域的研制工作,将本公司的计算机及软件产品通过提升和改造,应用到军用装备的安全关键系统中。公司为了承担军用产品的研发任务,公司领导将论证工作交给王工负责。王工经调研分析,提交了一份完整论证报告。
1)企业要承担武器装备产品生产任务,需获得一些资格认证,请列举两种资格认证名称。
2)请说明安全关键系统的定义,并列举出两个安全关键系统的实例设备。
3)请简要说明安全性(safety)的具体含义,并给出产品设计时,安全性分析通常采用哪两种方法?
【问题2】(6分)
IEC 61508 (《电气/电子/可编程电子安全系统的功能要求》)是国际上对安全关键系统规定的一种较完整的安全性等级划分标准,本标准是由国际电工委员会(International Electronic Commission)正式发布的电气和电子部件行业标准(GB/T 20438等同于此标准)。本标准对设备或系统的安全完整性等级(SIL)划分为4个等级(SIL1、SIL2、SIL3、SIL4),SIL4是最高要求。
表3-1给出了本标准对安全功能等级和失效容忍概率的对应关系。请根据自己所掌握的安全功能等级相关知识,补充完善表3-1给出的(1)~(6)空格,并将答案写在答题纸上。
实时调度是安全关键系统的关键技术。实时调度一般分为动态和静态两种。其中,静态调度是指在离线情况下计算出的任务的可调度性,静态调度必须保证所有任务的时限、资源、优先级和同步的需求。图3-1给出了一组分布式任务执行的优先级关系,请根据图3-1给出任务间的优先级关系实例,按静态调度算法的基本原理,补充完善图3-2给出的任务静态调度搜索树的(1) ~ (10)空白,并给出最佳调度路径。
图3-1分布式任务的优先权关系图
图3-2静态调度搜索树图
答案与解析
- 试题难度:较难
- 知识点:案例分析>嵌入式方向
- 试题答案:【问题1】1)从事军工科研生产需先获得以下五种认证:
1、国军标质量管理体系认证,简称国军标认证(ISO-9001);
2、武器装备科研生产许可证认证,简称许可证认证;3、武器装备科研生产单位保密资质认证,简称保密认证;
4、装备承制单位资格审查(装备承制单位资格名录认证和武器装备质量管理体系认证),检测名录认证;5、军用软件研制能力成熟度模型资格认证,简称软件认证(GJB5000)。
2)安全关键系统是指系统功能一旦失效将引起生命、财产等重大损失以及环境可能遭到严重破坏的系统。(如果计算机系统的失效可能引起灾难性的后果,如丧失生命、大量财产损失或环境遭到灾难性损失,则这个计算机系统能被称为“安全关键系统”。)安全关键系统包括:
如战斗机的航空电子系统,火控雷达系统、火车控制系统 、核反应堆系统等。</div>
【问题2】
(1)≥10-5 to < 10-4 (2)
≥ 10-9 to < 10-8
(3)
≥ 10-4 to < 10-3 (4)
≥ 10-3 to < 10-2
(5)
≥ 10-7 to < 10-6 (6)
≥ 10-6 to < 10-5
【问题3】
(1)T6 (2)T5 (3)T7
(4)M1 (5)T1 (6)T3
(7)T4 (8)M2 (9)T6
(10)T5
最佳调度路径:T0,T2,(M1,T1),(T3,T4),(M2,T6),T5,T7
</div>
- 试题解析:
表1 PFD(按要求的故障概率)/PFH(每小时的危险故障概率)和SIL(整体安全性等级)(IEC61508-1标准,7.6节)
安全性分析是一种在军用系统研制的初期开始进行的系统性的检查、研究和分析方法,它用于检查军用系统或设备在每种使用模式中的工作状态,确定潜在的危险,预计这些危险对人员伤害或对设备损坏的严重性和可能性,并确定消除或减少危险的方法,以便能够在事故发生之前消除或尽量减少事故发生的可能性或降低事故有害影响的程度。安全性分析主要用于识别危险,以便在寿命周期的所有阶段中能够消除或控制这些危险。安全性分析通过实施各种危险分析达到下述目的。
(1)确定军用系统存在的危险,并消除这些危险或降低其风险。
(2)确定现有危险的原因、影响及各种危险的相互关系。
(3)确定军用系统设计中需要采取预防措施或修复措施的部分。
(4)确定军用系统应进行哪些专门的试验以验证其安全性以及确定可能导致事故发生的任何军用系统缺陷。
危险分析方法则包括危险分析类型(工作项目)和分析技术两个方面,分析类型将涉及到在何时、何地及对何种对象进行危险分析,分析技术是指用来支持危险分析的手段和方法。在GJB 900-90中,常用的分析类型包括初步危险分析(PHA)、分系统危险分析(SSHA)、系统危险分析(SHA)等危险分析技术很多种,最经常使用的有故障模式影响及危害性分析(FMECA)、故障树分析(FTA)、事件树分析(ETA)、故障危险分析(FHA)、潜通电路分析(SCA)等。
故障树分析(FTA):一个可能的事故开始,自上而下、一层层的寻找顶事件的直接原因和间接原因事件,直到基本原因事件。
失效模式与影响分析(FMEA):FMEA是在产品设计阶段和过程设计阶段,对构成产品的子系统、零件,对构成过程的各个工序逐一进行分析,找出所有潜在的失效模式,并分析其可能的后果,从而预先采取必要的措施,以提高产品的质量和可靠性的一种系统化的活动。
第 4 题
阅读以下关于数据库设计的叙述,在答题纸上回答问题1至问题3。
某软件企业开发一套类似于淘宝网上商城业务的电子商务网站。该系统涉及多种用户角色,包括购物用户、商铺管理员,系统管理员等。
在数据库设计中,该系统数据库的核心关系包括:
产品(产品编码,产品名称,产品价格,库存数量,商铺编码)
商铺(商铺编码,商铺名称,商铺地址,商铺邮箱,服务电话)
用户(用户编码,用户名称,用户地址,联系电话)
订单(订单编码,订单日期,用户编码,商铺编码,产品编码,产品数量,订单总价)
不同用户角色有不同的数据需求,为此该软件企业在基本数据库关系模式的基础上,定制了许多视图。其中,有很多视图涉及到多表关联和聚集函数运算。
数据库运行测试过程中,发现针对该视图查询性能比较差,不满足用户需求。
请说明数据库视图的基本概念及其优点,并说明本视图设计导致查询性能较差的原因。
【问题2】(8分)
为解决该视图查询性能比较差的问题,张工建议为该数据建立单独的商品当天货物销售、存货情况的关系表。但李工认为张工的方案造成了数据不一致的问题,必须采用一定的手段来解决。
1)说明张工方案是否能够对该视图查询性能有所提升,并解释原因。
2)解释说明李工指出的数据不一致问题产生的原因。
【问题3】(9分)
针对李工提出的问题,常见的解决手段有应用程序实现,触发器实现和物化视图实现等,请用300字以内的文字解释说明这三种方案。
**答案与解析** - 试题难度:一般 - 知识点:案例分析>数据库方向 - 试题答案:
视图的优点:
1、视图能简化用户的操作
2、视图机制可以使用户以不同的方式查询同一数据
3、视图对数据库重构提供了一定程度的逻辑独立性
4、视图可以对机密的数据提供安全保护
查询性能较差的原因是视图中“日销售产品数量”需要针对订单表做统计分析,订单表中有数量庞大的历史销售记录,所以这种操作极为耗时。
【问题2】
1)张工方案能够对该视图查询性能有所提升,因为这样做能极大的减少统计分析的数据量,对小数据量进行统计,性能是能得以保障的。
2)由于当日订单数据既存储在订单表中,又存储在单独的当天货物销售、存货情况表中。同一数据存储了两份,一旦出现修改,未同步修改,则会造成数据不一致。
【问题3】
应用程序实现:在进行订单的添加、修改、删除操作时,从应用程序中,控制对两个数据表都进行相关操作,以保障数据的一致性。
触发器实现:在应用程序中,只对订单表进行操作。但写触发器,当订单表发生变化时,把当日订单内容同步更新到当天货物销售、存货情况表中。
物化视图实现:建立“当天货物销售、存货情况”的物化视图,物化视图会把相应的数据物理存储起来,而且在订单表发生变化时,会自动更新。 - 试题解析:
第 5 题
某公司拟开发一个自由、可定制性强、用户界面友好的在线调查系统,以获取员工在课程学习、对公司重大事件的看法、对办公室环境的建议等相关反馈。因需要调查的内容各异,可选择的调查方式多样,故本在线调查系统应满足以下需求:
1)支持编辑和视图两种模式,编辑模式只对调查发起者可见,视图模式对接受调查者可见。
2)调查问卷具有可定制性,因调查的内容各异,需要多样的信息采集方式,可设置的调查问题类型包括单选、多选、矩阵类单选、矩阵类多选和开放性问题。
3)操作简单,调查者可以方便地新建和编辑各种问题类型,接受调查者可对每个问题和每个调查问卷给出评论。
4)系统支持显示调查统计结果,以及导出统计结果。
针对以上需求,经项目组讨论,拟采用REST架构风格设计实现该在线调查系统。
图5-1 在线调查系统业务流程分析
【问题2】 (10分)
REST架构风格的核心是资源抽象。在系统设计中,项目组拟将系统中的每一个实体抽象成一种资源。请列举出该系统中的5种资源。
【问题3】 (5分)
基于REST架构风格对系统进行设计,请简要叙述REST风格的5条关键原则。
答案与解析
- 试题难度:一般
- 知识点:案例分析>Web技术
- 试题答案:【问题1】(1)调查发起者
(2)接受调查者
(3)是否保存调查问卷
(4)已保存的调查问卷/待发布调查问卷
(5)显示(查看)调查问卷/填写调查问卷
【问题2】用户、接受调查者、调查发起者 、调查问卷、调查问题类型 、问卷问题、问卷问题的选项、调查结果、问卷问题评论、调查问卷评论等。(回答其中5个即可)
【问题3】
REST风格的5条关键原则包括:
(1)网络上的所有事物都被抽象为资源。
(2)每个资源对应一个唯一的资源标识。
(3)通过通用的连接件接口对资源进行操作。
(4)对资源的各种操作不会改变资源标识。
(5)所有的操作都是无状态的。 - 试题解析:REST风格的5条关键原则包括:1.为所有“事物”定义ID
在这里我使用了“事物”来代替更正式准确的术语“资源”,因为一条如此简单的原则,不应该被淹没在术语当中。思考一下人们构建的系统,通常会找到一系列值得被标识的关键抽象。每个事物都应该是可标识的,都应该拥有一个明显的ID——在Web中,代表ID的统一概念是:URI。URI构成了一个全局命名空间,使用URI标识你的关键资源意味着它们获得了一个唯一、全局的ID。
对事物使用一致的命名规则(naming scheme)最主要的好处就是你不需要提出自己的规则——而是依靠某个已被定义,在全球范围中几乎完美运行,并且能被绝大多数人所理解的规则。想一下你构建的上一个应用(假设它不是采用RESTful方式构建的)中的任意一个高级对象(high-level object),那就很有可能看到许多从使用唯一标识中受益的用例。比如,如果你的应用中包含一个对顾客的抽象,那么我可以相当肯定,用户会希望将一个指向某个顾客的链接,能通过电子邮件发送到同事那里,或者加入到浏览器的书签中,甚至写到纸上。更透彻地讲:如果在一个类似于Amazon的在线商城中,没有用唯一的ID(一个URI)标识它的每一件商品,可想而知这将是多么可怕的业务决策。
当面对这个原则时,许多人惊讶于这是否意味着需要直接向外界暴露数据库记录(或者数据库记录ID)——自从多年以来面向对象的实践告诫我们,要将持久化的信息作为实现细节隐藏起来之后,哪怕是刚有点想法都常会使人惊恐。但是这条原则与隐藏实现细节两者之间并没有任何冲突:通常,值得被URI标识的事物——资源——要比数据库记录抽象的多。例如,一个定单资源可以由定单项、地址以及许多其他方面(可能不希望作为单独标识的资源暴露出来)组成。标识所有值得标识的事物,领会这个观念可以进一步引导你创造出在传统的应用程序设计中不常见的资源:一个流程或者流程步骤、一次销售、一次谈判、一份报价请求——这都是应该被标识的事物的示例。同样,这也会导致创建比非RESTful设计更多的持久化实体。
下面是一些你可能想到的URI的例子:
注:网址中的“”代表“.”
http://examplecom/customers/1234
http://example*com/orders/2007/10/776654
http://example*com/products/4554
http://example*com/processes/salary-increase-234 正如我选择了创建便于阅读的URI——这是个有用的观点,尽管不是RESTful设计所必须的——应该能十分容易地推测出URI的含义:它们明显地标识着单一“数据项”。但是再往下看:
http://example*com/orders/2007/11
http://example*com/products?color=green 首先,这两个URI看起来与之前的稍有不同——毕竟,它们不是对一件事物的标识,而是对一类事物集合的标识(假定第一个URI标识了所有在2007年11月份提交的定单,第二个则是绿颜色产品的集合)。但是这些集合自身也是事物(资源),也应该被标识。
注意,使用唯一、全局统一的命名规则的好处,既适用于浏览器中的Web应用,也适用于机对机(machine-to-machine,m2m)通信。
来对第一个原则做下总结:使用URI标识所有值得标识的事物,特别是应用中提供的所有“高级”资源,无论这些资源代表单一数据项、数据项集合、虚拟亦或实际的对象还是计算结果等。
2.将所有事物链接在一起来对第一个原则做下总结:使用URI标识所有值得标识的事物,特别是应用中提供的所有“高级”资源,无论这些资源代表单一数据项、数据项集合、虚拟亦或实际的对象还是计算结果等。
它知道如何去处理URI的原因在于所有的资源都支持同样的接口,一套同样的方法(只要你乐意,也可以称为操作)集合。在HTTP中这被叫作动词(verb),除了两个大家熟知的(GET和POST)之外,标准方法集合中还包含PUT、DELETE、HEAD和OPTIONS。这些方法的含义连同行为许诺都一起定义在HTTP规范之中。如果你是一名OO开发人员,就可以想象到RESTful HTTP方案中的所有资源都继承自类似于这样的一个类(采用类Java、C#的伪语法描述,请注意关键的方法):
2.将所有事物链接在一起
接下来要讨论的原则有一个有点令人害怕的正式描述:“超媒体被当作应用状态引擎(Hypermedia as the engine of application state)”,有时简写为HATEOAS。(严格地说,这不是我说的。)这个描述的核心是超媒体概念,换句话说:是链接的思想。链接是我们在HTML中常见的概念,但是它的用处绝不局限于此(用于人们网络浏览)。
应用程序(已经检索过文档)如何“跟随”链接检索更多的信息。当然,如果使用一个遵守专用命名规范的简单“id”属性作为链接,也是可行的——但是仅限于应用环境之内。使用URI表示链接的优雅之处在于,链接可以指向由不同应用、不同服务器甚至位于另一个大陆上的不同公司提供的资源——因为URI命名规范是全球标准,构成Web的所有资源都可以互联互通。
超媒体原则还有一个更重要的方面——应用“状态”。简而言之,实际上服务器端(如果你愿意,也可以叫服务提供者)为客户端(服务消费者)提供一组链接,使客户端能通过链接将应用从一个状态改变为另一个状态。稍后我们会在另一篇文章中探究这个方面的影响;目前,只需要记住:链接是构成动态应用的非常有效的方式。
对此原则总结如下:任何可能的情况下,使用链接指引可以被标识的事物(资源)。也正是超链接造就了现在的Web。
3.使用标准方法
在前两个原则的讨论中暗含着一个假设:接收URI的应用程序可以通过URI明确地做一些有意义的事情。如果你在公共汽车上看到一个URI,你可以将它输入浏览器的地址栏中并回车——但是你的浏览器如何知道需要对这个URI做些什么呢?
class Resource {
Resource(URI u);
Response get();
Response post(Request r);
Response put(Request r);
Response delete();
}由于所有资源使用了同样的接口,你可以依此使用GET方法检索一个表述(representation)——也就是对资源的描述。因为规范中定义了GET的语义,所以可以肯定当你调用它的时候不需要对后果负责——这就是为什么可以“安全”地调用此方法。GET方法支持非常高效、成熟的缓存,所以在很多情况下,你甚至不需要向服务器发送请求。还可以肯定的是,GET方法具有幂等性[译注:指多个相同请求返回相同的结果]——如果你发送了一个GET请求没有得到结果,你可能不知道原因是请求未能到达目的地,还是响应在反馈的途中丢失了。幂等性保证了你可以简单地再发送一次请求解决问题。幂等性同样适用于PUT(基本的含义是“更新资源数据,如果资源不存在的话,则根据此URI创建一个新的资源”)和DELETE(你完全可以一遍又一遍地操作它,直到得出结论——删除不存在的东西没有任何问题)方法。POST方法,通常表示“创建一个新资源”,也能被用于调用任意过程,因而它既不安全也不具有幂等性。
在实践中,资源多重表述还有着其他重要的好处:如果你为你的资源提供HTML和XML两种表述方式,那这些资源不仅可以被你的应用所用,还可以被任意标准Web浏览器所用——也就是说,你的应用信息可以被所有会使用Web的人获取到。
如果你采用RESTful的方式暴露应用功能(如果你乐意,也可以称为服务功能),那这条原则和它的约束同样也适用于你。如果你已经习惯于另外的设计方式,则很难去接受这条原则——毕竟,你很可能认为你的应用包含了超出这些操作表达范围的逻辑。请允许我花费一些时间来让你相信不存在这样的情况。
来看下面这个简单的采购方案例子:
可以看到,例子中定义了两个服务程序(没有包含任何实现细节)。这些服务程序的接口都是为了完成任务(正是我们讨论的OrderManagement和CustomerManagement服务)而定制的。如果客户端程序试图使用这些服务,那它必须针对这些特定接口进行编码——不可能在这些接口定义之前,使用客户程序去有目的地和接口协作。这些接口定义了服务程序的应用协议(application protocol)。
在RESTful HTTP方式中,你将通过组成HTTP应用协议的通用接口访问服务程序。你可能会想出像这样的方式:
可以看到,服务程序中的特定操作被映射成为标准的HTTP方法——为了消除歧义,我创建了一组全新的资源。“这是骗人的把戏”,我听见你叫嚷着。不,这不是欺骗。标识一个顾客的URI上的GET方法正好相当于getCustomerDetails操作。有人用三角形形象化地说明了这一点:
把三个顶点想象为你可以调节的按钮。可以看到在第一种方法中,你拥有许多操作,许多种类的数据以及固定数量的“实例”(本质上和你拥有的服务程序数量一致)。在第二种方法中,你拥有固定数量的操作,许多种类的数据和许多调用固定方法的对象。它的意义在于,证明了通过这两种方式,你基本上可以表示任何你喜欢的事情。
为什么使用标准方法如此重要?从根本上说,它使你的应用成为Web的一部分——应用程序为Web变成Internet上最成功的应用所做的贡献,与它添加到Web中的资源数量成比例。采用RESTful方式,一个应用可能会向Web中添加数以百万计的客户URI;如果采用CORBA技术并维持应用的原有设计方式,那它的贡献大抵只是一个“端点(endpoint)”——就好比一个非常小的门,仅仅允许有钥匙的人进入其中的资源域。
统一接口也使得所有理解HTTP应用协议的组件能与你的应用交互。通用客户程序(generic client)就是从中受益的组件的例子,例如curl、wget、代理、缓存、HTTP服务器、网关还有Google、Yahoo!、MSN等等。
总结如下:为使客户端程序能与你的资源相互协作,资源应该正确地实现默认的应用协议(HTTP),也就是使用标准的GET、PUT、POST和DELETE方法。
4.资源多重表述
到目前为止我们一直忽略了一个稍微复杂的问题:客户程序如何知道该怎样处理检索到的数据,比如作为GET或者POST请求的结果?原因是,HTTP采取的方式是允许数据处理和操作调用之间关系分离的。换句话说,如果客户程序知道如何处理一种特定的数据格式,那就可以与所有提供这种表述格式的资源交互。让我们再用一个例子来阐明这个观点。利用HTTP内容协商(content negotiation),客户程序可以请求一种特定格式的表述:
GET /customers/1234 HTTP/1.1
Host: example*com
Accept: application/vnd.mycompany.customer+xml 请求的结果可能是一些由公司专有的XML格式表述的客户信息。假设客户程序发送另外一个不同的请求,就如下面这样:
GET /customers/1234 HTTP/1.1
Host: example*com
Accept: text/x-vcard 结果则可能是VCard格式的客户地址。(在这里我没有展示响应的内容,在其HTTP Content-type头中应该包含着关于数据类型的元数据。)这说明为什么理想的情况下,资源表述应该采用标准格式——如果客户程序对HTTP应用协议和一组数据格式都有所“了解”,那么它就可以用一种有意义的方式与世界上任意一个RESTful HTTP应用交互。不幸的是,我们不可能拿到所有东西的标准格式,但是,或许我们可以想到在公司或者一些合作伙伴中使用标准格式来营造一个小环境。当然以上情况不仅适用于从服务器端到客户端的数据,反之既然——倘若从客户端传来的数据符合应用协议,那么服务器端就可以使用特定的格式处理数据,而不去关心客户端的类型。
资源多重表述还有另外一种使用方式:你可以将应用的Web UI纳入到Web API中——毕竟,API的设计通常是由UI可以提供的功能驱动的,而UI也是通过API执行动作的。将这两个任务合二为一带来了令人惊讶的好处,这使得使用者和调用程序都能得到更好的Web接口。 总结:针对不同的需求提供资源多重表述。
5.无状态通信
无状态通信是我要讲到的最后一个原则。首先,需要着重强调的是,虽然REST包含无状态性(statelessness)的观念,但这并不是说暴露功能的应用不能有状态——
事实上,在大部分情况下这会导致整个做法没有任何用处。REST要求状态要么被放入资源状态中,要么保存在客户端上。或者换句话说,服务器端不能保持除了单次请求之外的,任何与其通信的客户端的通信状态。这样做的最直接的理由就是可伸缩性—— 如果服务器需要保持客户端状态,那么大量的客户端交互会严重影响服务器的内存可用空间(footprint)。(注意,要做到无状态通信往往需要一些重新设计——不能简单地将一些session状态绑缚在URI上,然后就宣称这个应用是RESTful。)
但除此以外,其他方面可能显得更为重要:无状态约束使服务器的变化对客户端是不可见的,因为在两次连续的请求中,客户端并不依赖于同一台服务器。一个客户端从某台服务器上收到一份包含链接的文档,当它要做一些处理时,这台服务器宕掉了,可能是硬盘坏掉而被拿去修理,可能是软件需要升级重启——如果这个客户端访问了从这台服务器接收的链接,它不会察觉到后台的服务器已经改变了。