首页 > 其他分享 >06人月神话阅读笔记

06人月神话阅读笔记

时间:2023-05-24 18:46:24浏览次数:34  
标签:机器 神话 编程 系统 笔记 开发 06 工具 调试

第11章 未雨绸缪
不变只是愿望,变化才是永恒。——SWIFT。

普遍的做法是,选择一种方法,试试看;如果失败了,没关系,再试试别的。不管怎么样,重要的是先去尝试。——富兰克林 D. 罗斯福。

11.1 化学工程师很早就认识到,在实验室可以进行的反应过程,并不能在工厂中一步实现。一个被称为“实验性工厂(pilot planet)”的中间步骤是非常必要的。软件系统的构建人员也面临类似的问题。

对于大多数项目,第一个开发的系统并不合用。要解决所有的问题,除了重新开始以外,没有其他的办法——即开发一个更灵巧或者更好的系统。系统的丢弃和重新设计可以一步完成,也可以一块块地实现。所有大型系统的经验都显示,这是必须完成的步骤。

因此,管理上的问题不再是“是否构建一个试验性的系统,然后抛弃它?”。现在的问题是“是否预先计划抛弃原型的开发,或者是否将该原型发布给用户?”。将原型发布给用户,可以获得时间,但是它的代价高昂——对于用户,使用极度痛苦;对于重新开发的人员,分散了精力;对于产品,影响了声誉,即使最好的再设计也难以挽回名声。因此,为舍弃而计划,无论如何,你一定要这样做。

11.2 一旦认识到试验性的系统必须被构建和丢弃,具有变更思想的重新设计不可避免,从而直面整个变化现象是非常有用的。

我从不建议顾客目标和需求的所有变更必须、能够、或者应该整合到设计中。项目开始时建立的基准,肯定会随着开发的进行越来越高,甚至开发不出任何产品。抛弃原型概念本身就是对事实的接受——随着学习的过程更改设计。

11.3 如何为上述变化设计系统,是个非常著名的问题。它们包括细致的模块化、可扩展的函数、精确完整的模块间接口设计、完备的文档。另外,还可能会采用包括调用队列和表驱动的一些技术。

最重要的措施是使用高级语言和自文档技术,以减少变更引起的错误。采用编译时的操作来整合标准声明,在很大程度上帮助了变化的调整。

变更的阶段化是一种必要的技术。每个产品都应该有数字版本号,每个版本都应该有自己的日程表和冻结日期,在此之后的变更属于下一个版本的范畴。

程序员不愿意为设计书写文档的原因,不仅仅是由于惰性。更多的是源于设计人员的踌躇——要为自己尝试性的设计决策进行辩解。

11.4 当系统发生变化时,管理结构也需要进行调整。这意味着,只要管理人员和技术人才的天赋允许,老板必须对他们的能力培养给予极大的关注,使管理人员和技术人才具有互换性。

这其中的障碍是社会性的,人们必须同顽固的戒心做斗争。首先,管理人员自己常常认为高级人员太“有价值”,而舍不得让他们从事实际的编程工作;其次,管理人员拥有更高的威信。为了克服这个问题,如Bell Labs的一些实验室,废除了所有的职位头衔。每个专业人士都是“技术人员中的一员”。而IBM的另外一些实验室,保持了两条职位晋升线。

 

管理人员需要参与技术课程,高级技术人才需要进行管理培训。项目目标、进展、管理问题必须在高级人员整体中得到共享。只要能力允许,高层人员必须时刻做好技术和情感上的准备,以管理团队或者亲自参与开发工作。这是件工作量很大的任务,但显然很值得!

组建外科手术队伍式的软件开发团队,这整个观念是对上述问题的彻底冲击。其结果是当高级人才编程和开发时,不会感到自降身份。这种方法试图清除那些会剥夺创造性乐趣的社会障碍。

上述组织架构的设计是为了最小化成员间的接口。同样的,它使系统在最大程度上易于修改。当组织构架必须变化时,为整个“外科手术队伍”重新安排不同的软件开发任务,会变得相对容易一些。

11.5 在程序发布给顾客使用之后,它不会停止变化。发布后的变更被称为“程序维护”,但是软件的维护过程不同于硬件维护。

计算机系统的硬件维护包括了三项活动——替换损坏的器件、清洁和润滑、修改设计上的缺陷。

软件维护不包括清洁、润滑和对损坏器件的修复。它主要包含对设计缺陷的修复。对于一个广泛使用的程序,其维护总成本通常是开发成本的40%或更多。令人吃惊的是,该成本受用户数目的严重影响。用户越多,所发现的错误也越多。

 

程序维护中的一个基本问题是——缺陷修复总会以(20-50)%的机率引入新的bug。所以整个过程是前进两步,后退一步。

为什么缺陷不能更彻底地被修复?

首先,看上去很轻微的错误,似乎仅仅是局部操作上的失败,实际上却是系统级别的问题。修复局部问题的工作量很清晰,并且往往不大。但是,更大范围的修复工作常常会被忽视,除非软件结构很简单,或者文档书写得非常详细

其次,维护人员常常不是编写代码的开发人员,而是一些初级程序员或者新手。作为引入新bug的一个后果,程序每条语句的维护需要的系统测试比其他编程要多。理论上,在每次修复之后,必须重新运行先前所有的测试用例,从而确保系统不会以更隐蔽的方式被破坏,所以它的成本非常高。

11.6 Lehman和Belady研究了大型操作系统的一系列发布版本的历史。他们发现模块数量随版本号的增加呈线性增长,但是受到影响的模块以版本号指数的级别增长。所有修改都倾向于破坏系统的架构,增加了系统的混乱程度。用在修复原有设计上瑕疵的工作量越来越少,而早期维护活动本身的漏洞所引起修复工作越来越多。随着时间的推移,系统变得越来越无序,修复工作迟早会失去根基。每一步前进都伴随着一步后退。

实际上,整个系统已经面目全非,无法再成为下一步进展的基础。而且,机器在变化,配置在变化,用户的需求在变化,所以现实系统不可能永远可用。崭新的、基于原有系统的重新设计是完全必要的。

系统软件开发是减少混乱度(减少熵)的过程,所以它本身是处于亚稳态的。软件维护是提高混乱度(增加熵)的过程,即使是最熟练的软件维护工作,也只是放缓了系统退化到非稳态的进程。

第12章 干将莫邪
就工具而言,即使是现在,很多软件项目仍然像一家五金店。每个骨干人员都仔细地保管自己工作生涯中搜集的一套工具集,这些工具成为个人技能的直观证明。正是如此,每个编程人员也保留着编辑器、排序、内存信息转储、磁盘实用程序等工具。

这种方法对软件项目来说是愚蠢的:

首先,项目的关键问题是沟通,个性化的工具妨碍——而不是促进沟通。

其次,当机器和语言发生变化时,技术也会随之变化,所有工具的生命周期是很短的。毫无疑问,开发和维护公共的通用编程工具的效率更高。

不过,仅有通用工具是不够的。专业需要和个人偏好同样需要很多专业工具。所以在前面关于软件开发队伍的讨论中,我建议为每个团队配备一名工具管理人员。这个角色管理所有通用工具,能指导他的客户——老板使用工具。同时,他还能编制老板需要的专业工具。

项目经理必须考虑、计划、组织的工具到底有哪些呢?

首先是计算机设施。它需要硬件和使用安排策略;它需要操作系统,提供服务的方式必须明了;它需要语言,语言的使用方针必须明确;然后是实用程序、调试辅助程序、测试用例生成工具和处理文档的字处理系统。

12.1 机器支持可以有效地划分成目标机器和辅助机器。目标机器是软件所服务的对象,程序必须在该机器上进行最后测试。辅助机器是那些在开发系统中提供服务的机器。

目标机器的类型有哪些?

团队开发的监督程序或其他系统核心软件当然需要它们自己的机器。目标机器系统会需要若干操作员和一两个系统编程人员,以保证机器上的标准支持是即时更新和实时可用的。

另外,还需要配备调试机器或者软件。这样,在调试过程中,所有类型的程序参数可以被自动计数和测量。

计划安排:

目标机器时间需求具有特别的增长曲线。当目标机器刚刚被研制,或者当它的第一个操作系统被开发时,机器时间是非常匮乏的,时间的调度安排成了主要问题。

我们开始把机器时间分配成连续的块。例如,整个从事排序工作的15人小组,会得到系统4至6小时的使用时间块,由他们自己决定如何使用。即使没有安排,其他人也不能使用机器资源。这种方式,是一种更好的分配和安排方法。尽管机器的利用程度可能会有些降低(常常不是这样),生产率却提高了。

12.2 仿真装置。如果目标机器是新产品,则需要一个目标机器的逻辑仿真装置。这样,在生产出新机器之前,就有辅助的调试平台可供使用。即使在新机器出现之后,仿真装置仍然可以提供可靠的调试平台。

可靠并不等于精确。在某些方面,仿真机器肯定无法精确地达到与新型机器一致的实现。但是至少在一段时间内,它的实现是稳定的,新硬件就不会。

实验室研制和试制的模型产品和早期硬件不会像定义的那样运行,不会稳定工作,甚至每天都不会一样。。所以,一套运行在稳定平台上的可靠仿真装置,提供了远大于我们所期望的功用。

编译器和汇编平台。出于同样的原因,编译器和汇编软件需要运行在可靠的辅助平台上,为目标机器编译目标代码。接着,可以在仿真器上立刻开始后续的调试。

高级语言的编程开发中,在目标机器上开始全面测试目标代码之前,编译器可以在辅助机器上完成很多目标代码的调试和测试工作。

程序库和管理。在OS/360开发中,一个非常成功的重要辅助机器应用是维护程序库。

这个库实际上划分成不同访问规则下的子库。

首先,每个组或者编程人员分配了一个区域,用来存放他的程序拷贝、测试用例以及单元测试需要的测试辅助例程和数据。在这个开发库(playpen)中,不存在任何限制开发人员的规定。他可以自由处置自己的程序,他是它们的拥有者。

当开发人员准备将软件单元集成到更大的部分时,他向集成经理提交一份拷贝,后者将拷贝放置在系统集成子库中。此时,原作者不可以再改变代码,除非得到了集成经理的批准。当系统合并在一起时,集成经理开始进行所有的系统测试工作,识别和修补bug。

有时,系统的一个版本可能会被广泛应用,它被提升到当前版本子库。此时,这个拷贝是不可更改的,除非有重大缺陷。该版本可以用于所有新模块的集成和测试。

这有两个重要的理念。首先是受控,即程序的拷贝属于经理,他可以独立地授权程序的变更。其次是使发布的进展变得正式,以及开发库(playpen)与集成、发布的正式分离。

编程工具。随着调试技术的出现,旧方法的使用减少了,但并没有消失。因此,还是需要内存转储、源文件编辑、快照转储、甚至跟踪等工具。

文档系统。在所有的工具中,最能节省劳动力的,可能是运行在可靠平台上的、计算机化的文本编辑系统。

性能仿真装置。最好有一个。正如我们将在下章讨论到的,彻底地开发一个。使用相同的自顶向下设计方法,来实现性能仿真器、逻辑仿真装置和产品。

11.3 高级语言。使用高级语言的主要原因是生产率和调试速度。我们在前面已讨论过生产率的问题(第8章)。调试上的改进来自下列事实——存在更少的bug,而且更容易查找。

bug更少的原因,是因为它避免在错误面前暴露所有级别的工作,这样不但会造成语法上的错误,还会产生语义上的问题,如不当使用寄存器等。编译器的诊断机制可以帮助找出这些类似的错误,更重要的是,它非常容易插入调试的快照。

系统编程需要什么样的高级语言呢?

现在可供合理选择的语言是PL/I6。它提供完整的功能集;它与操作系统环境相吻合;它有各种各样的编译器,一些是交互式的,一些速度很快,一些诊断性很好,另一些能产生优化程度很高的代码。我自己觉得使用APL来解决算法更快一些,然后,将它们翻译成某个系统环境下的PL/I语言。

交互式编程。在那些系统编程所关注的方面,Multics(以及后续系统,IBM的TSS)和其他交互式计算机系统在概念上有很大的不同:多个级别上数据和程序的共享和保护,可延伸的库管理,以及协助终端用户共同开发的设施。

标签:机器,神话,编程,系统,笔记,开发,06,工具,调试
From: https://www.cnblogs.com/yuncannotjava/p/17429215.html

相关文章

  • 002 Python 学习笔记
    #通过:f"内容{变量}"的格式,实现快速格式化,如下示例print("-----------字符串快速格式化------------")name="sunwugang"age=18print(f"mynameis{name},ageis{age}")print("mynameis{},ageis{}".format(name,age)) ......
  • 05人月神话阅读笔记
    第9章削足适履9.1程序有多大?除了运行时间以外,它所占据的空间也是主要开销。当系统设计者认为对用户而言,常驻程序内存的形式比加法器、磁盘等更加有用时,他会将硬件实现中的一部分移到内存上。相反的,其他的做法是非常不负责任的。由于规模是软件系统产品用户成本中如此大的一个......
  • 04人月神话阅读笔记
    第7章为什么巴比伦塔会失败?7.1巴比伦塔项目的失败是因为缺乏交流,以及交流的结果——组织。他们无法相互交谈,从而无法合作。当合作无法进行时,工作陷入了停顿。7.2因为左手不知道右手在做什么,所以进度灾难、功能的不合理和系统缺陷纷纷出现。随着工作的进行,许多小组慢慢地修改自......
  • 01人月神话阅读笔记
    第1章焦油坑1.1编程系统产品(ProgrammingSystemsProduct)开发的工作量是供个人使用的、独立开发的构件程序的九倍。我估计软件构件产品化引起了3倍工作量,将软件构件整合成完整系统所需要的设计、集成和测试又强加了3倍的工作量,这些高成本的构件在根本上是相互独立的。1.2编程......
  • 02人月神话阅读笔记
    第3章外科手术队伍3.1同样有两年经验而且在受到同样的培训的情况下,优秀的专业程序员的工作效率是较差程序员的十倍。(Sackman、Erikson和Grand)需要协作沟通的人员的数量影响着开发成本,因为成本的主要组成部分是相互的沟通和交流,以及更正沟通不当所引起的不良结果(系统调试)。这一......
  • 03人月神话阅读笔记
    第5章画蛇添足5.1尽早交流和持续沟通能使结构师有较好的成本意识,以及使开发人员获得对设计的信心,并且不会混淆各自的责任分工。面对估算过高的难题,结构师有两个选择:削减设计或者建议成本更低的实现方法——挑战估算的结果。后者是固有的主观感性反应。此时,结构师是在向开发人员......
  • mall学习笔记(6)
    1.@Autowired和@Resource注解的区别@Autowired和@Resource注解的区别和联系(十分详细,不看后悔)_莫小兮丶的博客1.@Autowired注解是Spring提供的,而@Resource注解是J2EE本身提供的2.@Autowird注解默认通过byType方式注入,而@Resource注解默认通过byName方式注入不如先看看这两个......
  • 刷题笔记:Luogu P3956 棋盘
    ProblemSolutionDFS/BFS需要注意去重的时候可以重复走(因为有限定条件),只要新的步数比原来的步数小就可以走,其余情况模拟即可细节有点多,比如需要记录一下上一步的棋盘颜色(下一次搜索传递参数),因为牵扯到使用魔法问题,不能直接染,因为改变地图后后边很多操作都会受影响在列举可能性......
  • C#学习笔记 - using语句
    using语句某些类型的非托管对象有数量限制或很耗费系统资源,在代码使用完他们后,尽快释放他们是很重要的using语句有助于简化这一过程,并确保这些资源被适当的处理(0)资源指实现了System.IDisposable接口的类或结构.IDisposalbe接口中有个Dispose的方法,使用这个方法去处置......
  • 微服务架构基本原理学习笔记(一)
    一、什么是微服务微服务是一种技术架构,通常我们可以把它理解为一组可以相互之间协同工作的应用程序或服务,这些应用程序或服务能够被单独部署到不同的服务器中,并且能够自主运行和维护。微服务技术只是一个名称而已,或许我们在日常工作中已经或多或少在使用其中的一种或几......