毕业设计 之 一 《构建之法》阅读笔记

《构建之法》阅读梳理篇

【by 初学者 2016.1.23——2.19】

【为什么要写这篇几万字的“读书笔记”?】

  • 一是记录读书过程,好记性不如烂笔头,梳理要点可加深记忆;
  • 二是立此存据可方便日后真正实践的时候提纲挈领地回顾;
  • 三是记录下阅读过程中的零星想法或者是偶尔得之的灵感,也算是“读中有感,感中有读”;
  • 四是请老师评判、指教,毕竟初读,见识浅薄。

CHAPTER1 概论

软件与程序的区别,恐怕就是实用性与理想性的区别。软件=程序+软件工程;程序=数据结构+算法。我们现在学的,只是后者的构成,而从理想迈向实用的最关键的一步,就是软件工程。

1.概念

1)软件构建:除了代码和静态数据,还有各种文件和数据来描述各个程序文件之间的依赖关系等;

2)源代码管理/配置管理:保证代码的平台兼容性、配置兼容性等;

3)质量保障(软件测试):保证软件的质量在修改过程中可以不断提高,或者至少可以保持;

4)项目管理:软件维护和服务运营

5)生命周期:以上称为软件的生命周期SLC

2.那么,什么是软件工程?

我以为,软件工程是构建在计算机科学这一学科之上的、拥有庞大的学科支持体系、致力于解决实际应用中层出不穷的需求和问题以期获得趋于完善的实用“工具(软件)”的体系。

CHAPTER2 个人技术和流程

这一章重点介绍的是以前了解过但未曾注重过的单元测试&回归测试;个人技术素养是团队协作的基础。

1.VSTS单元测试

  1. 源代码

    public Class User() { public User(string userEmail) { memail = userEmail; } private string memail;//private变量拒绝外部类访问(除非用get/set方法) }

  2. 测试代码1

    public void ConstructorTest() { string userEmail = "someone@somewhere.com"; User target = new User(userEmail); Assert.IsTrue(target != null);//测试制定条件为真时测试成功 } 测试E-mail是否确实保存在了User类中。关于Assert:在工程之中可以使用该类对特定的功能进行验证,单元测试方法执行开发代码中的方法代码,但只有包含该语句的时候才能报告代码行为方面的内容。

  3. 测试代码2

    [ExpectedException(typeof(ArgumentNullException))] public void ConstructorTestNull() { User target = new User(null); }

    [ExpectedException(typeof(ArgumentException))] public void ConstructorTestEmptty() { User target = new User(""); }

    [ExpectedException(typeof(ArgumentNullException))] public void ConstructorTestBlank() { User target = new User(" "); }

第三处测试的时候会出错。why?因为ArgumentNullException与ArgumentException是system中不同的类(参见https://msdn.microsoft.com/zh-cn/library/system.argumentnullexception(VS.80).aspx),前者是由于空参数传递给不接受它的方法中引发的异常,后者是由于向方法中提供的一个参数无效而引发的。

2.单元测试标准

  1. 单元测试的基础性:在最基本的功能之上进行测试,覆盖API中的每一个方法【个人认为这样应该是极大地刺激了代码的简洁性革命】但是100%的代码覆盖率并不等于100%的正确性
  2. 单元测试不受以前单元测试实例的干扰
  3. 某个单元测试的成功与否不依赖于别的测试
  4. 单元测试必须和产品代码一起保存和维护

3.回归测试(regression test)

在新版本上运行所有已经通过的测试用例,以验证是否有“退化”的情况发生。单元测试是回归测试的基础。

4.效能分析实践

  • 源代码(伪代码)

    //分析一个文本文件中各个词出现的概率,然后把出现频率最高的10个单词打印出来
    DoIt()
    {
        ProcessFile()
        ProcessBuffer()
        OutputResult()
    }
    ProcessBuffer()
    {
        GetOneWord()
        FreqOneWord()
    }
    FreqOneWord(word)
    {
        Find the word in the array list,
        if(found)
            Update the frequency
        if(not found)
            Add the word in the array list with frequency = 1
    }
    OutputResult()
    {
        Arraylist.Sort();
        Output Top 10 entry;
    }
    
  • step 1 进行分析方法的选择:抽样(sampling)or 代码注入(instrumentation)

【抽样】得到运行时间的函数分布的大致抽样,速度快但是不能得到精确数据;

【代码注入】将检测的代码注入每一个函数中,速度慢但是各个效能数据可以被精确测量

  • step 2 理解必要的名词:

【调用关系树(call tree)】从mainh函数开始,调用者与被调用者函数形成的树型关系

【消逝时间(elapsed time)】用户角度看程序运行所花的时间

【本函数时间(exclusive time)】所有在本函数花费的时间,不包括被调用者花费的时间

【应用程序时间(application time)】应用程序占用CPU的时间,不包括CPU在核心态时花费的时间

  • step 3 抽样分析(利用效能浏览器 Performance Explorer)

耗时最高的前三个函数:FreqOneWorld,EqualsHelper,ArrayList.get_Item

举例来说明耗时时间的长短:

for(i = 0;i<m_worldList.Count;i++)
{
    ......
}

验证表明,mworldList.Count被调用了1 600 000次以上。也就是说,如果将for循环中的mworldList.Count用一个变量代替,将极大地节省时间。

【一些寻常的习惯可能极大地拖慢程序代码的整体时间性能。效能分析是给我们一种“强迫式”改善思维方式的外力】

5.PSP

个人开发流程(personal software process)又叫PSP,是指导软件工程师进行开发的方法论;一般包括计划、开发(含测试)、报告。PSP目的是记录工程师如何实现需求的效率,而不是记录顾客对产品的满意度。

【也就是说,PSP并不是万能的(事实上也不存在万能的方法论);只是在前人实践的基础上总结出的通用方法集】

CHAPTER3 软件工程师的成长

关于软件工程师这一现实职业(而非大学中与计算机有关的专业)的发展标准与前景展望,引入了相当多的、作为一名本科生鲜少去注意的职业概念

1.软件开发流程

目的是为了提高软件开发、运营、维护的效率,以及提升用户的满意度、软件的可靠性和可维护性。

2.软件开发的职业概念

  • IC:individual contributor,即单个(模块开发)成员
  • LOC:Line of Code,即代码行数,用于描述任务量大小;也常用功能点(function point)表示
  • re-work:返工;次数越低表示代码质量越好
  • 交付:一是指code complete时交付给测试人员;二是指软件最终发布的时候交付给顾客。就软件开发而言,一致的、稳定的交付时间是衡量一个员工能力的重要方面。
  • CRUD:一般的信息系统,涵盖create/retrieve/update/delete(构建/检索/增加/删除)

3.软件工程师的成长衡量标准

  1. 积累软件开发的相关知识,提升技术技能
  2. 积累问题领域的知识和经验
  3. 对通用的软件设计思想和软件工程思想的理解
  4. 提升职业技能(区别于技术技能;指的是自我管理等方面的能力)
  5. 实际成果

4.技能的反面——problem solving

【其实这个说法不容易理解,因为我们(至少是我)所理解的“技能”的表现形式就是“解决问题”。但是作者的意思在于:能够称之为“技能”的项目,是你(或者我)已经机械化地精通低层次问题、用时间和脑力正在去思考高层次问题的项目。比如,以C语言为例,我应该对基本语法烂熟于心、对数据结构也已经很有研究、正在思考的是如何对C代码进行时间效率和空间效率的改进】

CHAPTER4 两人合作

两人合作是团队合作的基础;这里介绍的这个基础型“团队”中通用的一些方法以及最重要的——交流——的细节

1.代码规范

  1. 代码风格规范。主要是文字上的规定;
    • 缩进:4个空格,而不是tab;
    • 关于断行与空白的{}行:【作者的建议深得我心——{ 、}单独占一行;中间的代码缩进】
    • 下划线:用来分割变量名字中的作用域标注和变量的语义
    • 大小写:通用的做法是,所有的类/函数名都采用所有单词首字母大写(Pascal)的形式;所有的变量首字母小写,随后的单词首字母大写(Camel);
    • 注释:解释程序做什么、为什么这样做以及要特别注意的地方。注释只用ASCII码字符,不要用中文或者其他特殊字符,否则会影响可移植性
  2. 代码设计规范。牵涉到程序设计、模块之间的关系、设计模式等思维和价值观角度的东西。
    • 函数:只做一件事,做到最好。【这句话在我学java之初就听老师反复说过,印象十分深刻;这几乎可以上升到编程的“哲学智慧”层次了】
    • 函数:最好有单一的出口,必要的时候可以使用goto;
    • 错误处理:
      • 参数处理:在debug版本中,所有的参数都要验证其正确性;
      • 断言:Assert(一定正确的某条语句)

2.代码复审

代码复审的目的在于找出代码的错误。因为越是项目后期发现的错误,修复的代价就越大——这也是learning by doing思想的体现。

  • 优秀的代码复审者应该把眼光放长远,考虑除了当前代码或者改动之外的、可能产生持久影响的问题
  • 代码审核表应该囊括(不局限于)这些方面
    • 概要部分(整体风格)
    • 设计规范部分(按照已知的规则去约束)
    • 代码规范部分
    • 具体代码部分
    • 效能
    • 可读性
    • 可测试性【我认为其实最后两个是一种“精益求精”的标准】

3.结对编程

  1. 结对编程中有两个角色
    1. 驾驶员(driver):控制键盘输入;
    2. 领航员(navigator):领航提醒。
  2. 在结对编程的过程中不断重复的互相复审
    1. 传统复审最大的缺点是复审者缺少对程序的深入了解;【这正是互相复审的最大优点】
    2. 传统复审设计人员多,复审效率不能平衡。互相复审则可以十分默契地提高效率;
    3. 结对编程最大的特点在于“领航员”的引入。如果实际中这个角色不能“领航”,则不如放弃结对编程
  3. 极限编程
    • 把一些认为有效的方法发挥到极致(效用和占比最大化)
  4. 关于交流的基本素质【个人认为这一点完全可以说开去】
    1. 评论人的三种层次:
      1. 最外层:行为和后果【就事论事,对方仍然可以改正】
      2. 中间层:习惯和动机【比较难以澄清】
      3. 最里层:本质和固有属性【人格上的攻击或者赞美,基本上无法改变】
    2. 反馈的顺序
      1. 做好铺垫,拉近距离,使得对方处于相对安全的环境;
      2. 核心是对方的做法和后果,比较容易接受和改进;
      3. 最后提出鼓励和期望

CHAPTER5 团队和流程

典型的团队开发模式和流程,完全是新的内容;涉及到更多的术语和有意思的策略性东西

1.团队模式【我比较认可的】

  1. 主治医师模式
    • 由首席程序员(相当于首席医生)负责整个工程,周围人员各司其职,配合支持中心人物的工作;
    • 【我认为这种模式适合于有着杰出程序工程师的规模略小的团队】
  2. 社区模式
    • 我非常心水的linux社区就是最大的成功案例之一。
    • 社区并不意味着“随意”,而是有着严格的复审和质量控制
  3. 交响乐团模式
    • 【不适用于创新型的项目,反而是对于稳定的、种在执行的项目的效率比较高】
    • 门类齐全,各种任务都已经有了经验
  4. 功能团队模式
    • 具备不同能力的同事平等地协作,共同完成某个任务;
    • 【没有管理和被管理的模式】

2.开发流程

  1. 瀑布模型(waterfall model)
    • 用于单向的、不可逆转的生产过程;
    • 要有相邻步骤的回溯;
    • 用户及早介入非常重要。
    • 适用范围【个人认为】
      • 产品的定义准确但是正确性重要【这样才适合花力气去回溯】
      • 团队成员无法频繁交流【这样才会用得到那么多记录文档】
    • 缺陷
      • 最终产品最后才出现,这样其实是很危险且成本很高的
  2. 统一流程RUP(rational合理的 unified统一的 process)

RUP就是把软件开发的各个阶段整合在一个统一的框架里面。其规程(discipline)或者工作流(workflow)如下———

- 业务建模:用精确语言描述用户活动
    - 这里提到了UML(统一建模语言),其实这种建模的思想应用很广泛;举例来说,“编码理论”或者是“数字电路基础”这种课程所用的状态图等都可以归属于UML中
- 需求:从活动中感知并表达需求,从需求中抓出软件(至少)要实现的功能;
- 分析和设计:将系统划分成子模块;
- 实现:紧接上一步,搭建可执行的系统;
- 测试:验证已经交付的组件之间的正确性、组件之间交互的正确性以及所有的需求是否已经被正确地实现;
- 部署:生成最终的版本并分发给所有用户;【其实我之前的想法是到此为止,然而在现实中并不是这样,作为一个目标是拥有一定生命周期的软件,后期的维护、管理也是必不可少的】
- 配置和变更管理:记录各个阶段产生的各种工作结果;
- 项目管理:平衡各种因素,以便在各个阶段交付达到要求的产品;
- 环境:向软件开发组织提供软件开发环境【每个阶段都有点类似迭代开发(把一个大的目标逐步完成,每一个阶段所完成的都可以为下一个阶段做铺垫)】
  1. 渐进交付的工作流程MVP&MBP
    • MVP(minimal viable product)最小可行产品,即把产品最核心的功能用最小成本实现出来(或者甚至可以只是描绘出来),然后快速征求用户意见。
      • 强调更早地获得用户反馈,为此可以在产品完成之前就发布
    • MBP(maximal beautiful product)与MVP相反,走的是最美最强产品思路

CHAPTER6 敏捷流程

敏捷是一种很“年轻态”的思路/策略,是以“万事万物都在不停地发展变化”为指导去组织软件工程的需求分析、内部的调和、代码编写甚至维护,所以我读起来会觉得很有共鸣。然而并不是所有的地方都适合让“敏捷”去闯一闯。

1.敏捷开发原则

【适应瞬息万变的形式,力求在大潮中可持续发展;年轻态】

【个人进行了分析组合】 1. 可用的、尽早交付的软件是项目进展的主要指标 2. 保持可持续的发展,以需求作为发展优势 3. 自我管理。无论是交流还是信任还是共同工作

2.敏捷流程

  1. 找出product backlog【与之前的需求分析不同,这里的backlog不是很“厚”】
  2. 决定当前的sprint即sprint backlog【分解为16小时以下的backlog,团队成员根据任务量和自身条件认领backlog】
  3. sprint【每日一例会,各自汇报做了什么,有什么困难,下一步计划】

另外,如何让敏捷流程不流于形式?

  • 定义好任务量。特别是“还剩多长时间”
  • sprint的时候团队保持高度运转,不以外力作用而(暂时)停工或者受到其他影响
  • sprint之后如果发现大问题,还要DCR(design change request)
  • 任务都完成了不等于可以高枕无忧了。至少(往往)20%的测试任务要花掉80%的时间

3.关于敏捷的另外几条神来之笔

  1. 敏捷的团队非常“自我”——自我管理、自我组织,好像非常易于变型的填充物,很多成员都可以有很多“功能”;
  2. 不要和管理层谈“过程”,他们只要结果【见人下菜】
  3. 大多数被测试、被研究的新东西都很有效果。
  4. 我们需要敏捷(agile)的开发流程,而不是匆忙(rushed)或者忙乱(chaotic)的流程
  5. 敏捷不是万能,它只是能够帮助你更早知道自己能否如期完成任务【因为产品会很早就迎来用户“检查”】

CHAPTER7 MSF

因为作者是微软的资深工程师,所以这一章里面我看到的一篇很原汁原味的精髓版软件开发方法。并不是说我一定要在有生之年参与一个多么浩大的项目然后用尽这里的所有知识;而是站到高处去看会很精彩。

1.MSF(Microsoft Solution Framework)微软解决方案框架

  1. 基本原则
    1. 推动信息共享与沟通。所有信息都公开【比如那种很弱智的错误,也会由记录软件记录下来。这是原则问题】;
    2. 为共同的远景工作。这个远景/目标是一个对所有人而言都没有二义性并且有一定距离的可实现目标;
    3. 充分授权和信任。
      • 给予充分的权力(也会有记录软件作为“监工”防止偷懒)
      • 给予充分的自尊(领导在项目中的角色是“支持”而非“控制”)
    4. 各司其职,共同对项目负责

      无责任的旁观者和有重大责任的当局者的看法自然是不一样的

      • 我认为上面这句话很经典。所以MSF中特别提出对于每一项任务都要明确“谁负责”
    5. 重视商业价值,提供渐进的价值

      一个团队如果没有经得起考验的商业价值,没有明确的远景,是很难坚持下去的

    6. 保持敏捷,预期变化(not 期望变化)
    7. 投资质量
      • 作者在这里特别说明,“投资质量”绝对不是质量第一,而是“有条件的”重视质量:衡量质量的时机、效率、代价

2.MSF的演化之一———MSF的敏捷开发模式

  1. 质量:防患于未然。开发实用性产品的过程中,防止缺陷发生成为团队的首要任务。
  2. 注重保持一个随时可以发布的高质量

CHAPTER8 需求分析

其实这是“啃硬骨头”的第一步,就是如何从“茫茫”中锁定需求相关方、挖出来需求的方法论

1.挖取需求

  1. 获取和引导需求。需求不仅是来自外界,甚至也可以来自技术成员团队内部;
  2. 分析和定义需求。主要是对需求进行量化;
  3. 验证需求。
  4. 在软件产品的生命周期中管理需求
    • 需求不一定只在初期才有;在中后期的时候可能因为外界环境变化甚至是成员自身水平变化而出现新的需求

2.软件产品的利益相关者

  1. 最终用户(使用软件的人)
  2. 顾客(购买软件的人)
  3. 监管部门

3.获取用户需求的方法

  1. 焦点小组(focus group):找到一群用户的代表,加上利益相关者来讨论用户想要什么
  2. 深入面谈(in-depth interview):采取一对一的采访方式,着重探究用户在使用的时候有哪些困难 【以下方法我认为可以看做是进行需求分类的方法】

  3. 卡片分类(card sorting):将杂乱无章的需求分条目地写到卡片上,然后对这些卡片进行讨论、归类甚至排序

  4. 人类学调查(ethnographic study):和目标用户“同吃同住同劳动”——以便真正理解用户有什么需求、为什么用户有这些需求

4.竞争性需求分析(以说服别人)

以NABCD模型为例 1. N——NEED需求 2. A——APPROACH做法 - 有什么(独特的)做法去解决用户的困难 3. B——BENEFIT好处 - 特别注意用户迁移成本的问题。指的是用户要得到我们所做的软件带来的好处,需要花费多少时间、金钱甚至精力(去转移使用) 4. C——COMPETITORS竞争 5. D——DELIVERY推广

5.功能定位和优先级

【酒香也怕巷子深。对自己的产品有着清楚的功能定位——或者知道如何表述这种功能,是很重要的一个“让酒走出去”的手段】

要把用户从竞争对手那里吸引过来,团队自己的产品要有一个差异化的焦点,在这个焦点上,我们的团队能做得比别人好10倍,高一个数量级。 于是我们有了两种不同类型的功能:杀手功能(core)/外围功能(context) 还有另外一种划分:必要需求/辅助需求

6.分而治之

WBS通常从最终的产品开始,一层一层往下,把大型交付件(deliverable)分割为小型、具体的交付件(从结果出发,而不是团队的活动)

CHAPTER9 项目经理

PM是在前几章中反复提到过的而我本身对此比较陌生的一种团队角色。我觉得“manager”(中文翻译为经理)其实是个很广泛的概念;不过大多数情况下指的是具有“复合型功能”的人物

1.PM是什么

  1. product manager:产品经理。正确地做产品【也就是说,产品经理是以产品为中心展开工作,包括产品的定位、运营、优化等等】
  2. project manager:项目经理。正确地做流程;保证一个项目顺利按照计划结项。
  3. program manager:微软独有的PM,与项目经理类似但又有不同【我认为主要的区别在于program manager是和团队内其他成员平等地负责具体工作】

PM最大、最独特的贡献是带领团队达成最重要的目标,并保持团队的平衡

2.风险管理

  1. 层次一:缓和并防止问题。先把问题缓和下来再进一步调动队员解决问题
  2. 层次二:预计。从定性的猜测进不到定量的预计,从而有效地做准备
  3. 层次三:把问题变为机会(比如从问题的改进中使得产品获得更大的优势)

3.PM必备素质

  1. 观察、快速理解和学习能力 【我个人理解,这是因为PM有时候很像一个渠道去沟通不同的部门或者角色,所以需要很强的适应能力,而这种适应能力就是从观察中理解和学习的能力】
  2. 分析管理能力 【不论是自我的管理还是千头万绪的需求中快速分解“有用项”的能力,我认为都可以算在其中】
  3. 一定的专业能力

【这里特别提出了作为在校生如何培养PM素质。作者首先推荐的不是“学好专业课”,而是“多参加活动(特别是从下而上的草根活动)”,感觉别有深意】

CHAPTER10 典型用户和场景

作为软件,最大的目的不是考验“软件工程”,而是“用户至上”的使用性好坏。所以多了解一些“用户之法”多有裨益。另外,关于spec也在本章中有所涉及

1.典型用户

  • what?【典型用户就是互不相同的、最可能使用软件的若干类用户;要作为“典型”,还要完善他们的使用诉求、习惯以及本身的软件操作水平】
  • why?强迫我们考虑问题的时候从用户的角度出发
  • how?先定义典型用户,再从典型用户到(用户使用软件的)场景

参考http://www.cnblogs.com/xinz/p/3855296.html

  • ATM机操作界面的典型用户?(至少五种)【个人观点】

    1. 21岁的小夏,大学生,每个月都会来ATM机前取父母打给自己的生活费,平时手机、平板用的很顺溜;
    2. 33岁的夏某,白领(非财务工作者),硕士毕业,每个月工资发下来之后会来取一些钱作为日常开销使用,或者进行转账操作来给父母汇钱、交付生活费用等;
    3. 42岁的白某,个体经营者,文化程度初中,经营一家规模不是很大的餐馆,往往冬夏两季收入较好,经常来银行柜台存钱或者取现(一般是餐馆需要资金周转或者采购),数目不是很大的时候会在ATM机上进行办理;给儿子女儿汇生活费的时候也会来此进行转账操作;
    4. 65岁的白大爷,退休在家,文化程度高小,有老花眼,腿脚不灵便,一般在银行柜台办理业务(主要就是查询退休金是否到账、平时取点钱老两口花),偶尔柜台比较忙碌的时候才会来ATM机取现
    5. 50岁的高某,残疾人,低保户,文化程度无(自学了一些课程,相当于小学文化水平),偶尔来进行取现操作。

2.规格说明书(spec)

  1. 软件功能说明书(functional spec)
    • 定义好相关概念;规范好一些假设(标准);描述主流用户的步骤【这里不用创新地考虑如何玩出一个花来】;副作用;
    • 参考http://www.cnblogs.com/xinz/p/3855296.html
      • 如何写“系鞋带”的spec?【每次读邹老师的文章都会觉得很有意思。而且觉得脑洞开得虽然“大”然而很正确。比如:怎么样算是“系好鞋带了”?当然,鞋带掉在地上、两个鞋子的鞋带绑在一起是不算的】
  2. 软件技术说明书(technical spec)

3.功能驱动(feature driven design,FDD)的设计

将用户需求变成团队成员可以直接操作的开发工作

CHAPTER11软件设计与实现

主要是介绍开发的流程

1.图形建模

  1. 表现实体和实体之间的关系
    1. 思维导图(mind map)
    2. 实体关系图(entity relationship map) 将实体与实体通过“关系”连接
  2. 表达数据的流动 增加——>以及<——这样的有向箭头来说明数据如何在实体之间流动

2.一些妙语

  1. 当场景、功能都计划好的时候,要给员工足够多的时间,让他们投入到工作中去,而不要经常打断他们
  2. 如果开发人员的“小强”(bug)数量超过一定值,则此君被送入“小强地狱”,在地狱中,他唯一能做的事情就是修复小强,直到小强数量低于此阙值

CHAPTER12 用户体验

讲“用户体验”,其实就是为了能够让开发者能够在“think on customers feet”与"think by themself"之间自如切换——体验软件的时候站在用户角度,设计这些体验的时候在设计者角度

1.计算机软件的用户界面(user interface,UI)&用户体验(user experience,UX)

无论软件还是硬件,都有很多功能,各个部件还要有机地结合起来,才能够满足用户的需求

2.如何判断一个是不是一个好的设计?

  1. who:目标用户
  2. when:他们会在什么时候使用你的产品
  3. where:何处使用
  4. why:为什么要使用你的产品【个人认为这个问题很致命】
  5. how:如何使用

3.关于用户体验的妙语

1.用户需要帮助,但是用户没有那么笨

  • 比如,能够使用计算机软件的用户肯定不用翻译软件去解释a,the,this……是什么意思

2.dogfood的传统可以帮助发现问题(自己使用自己开发的软件)

3.长期使用之后,软件会变得好用吗?(我认为可以把这个称之为“软件的记忆问题”或者“软件与使用者的契合度”)

另外,

  1. 短期刺激和长期影响
    • 在测试中,测试人员受到的大多数是短期刺激;而客户在实际使用的时候受到的是长期影响(比如,一个饮料喝上一瓶和喝上5瓶是一样的感受吗?)
  2. 不让用户犯简单的错误
    • 界面设计上,比如把“submit”和“cancel”设计的距离很近,这样用户手一抖就会点错

4.用户体验的评价标准

  1. 尽快提供可感触的反馈
    • 【不知所以的等待总是特别烦人】
  2. 系统界面符合用户的现实惯例
    • 【主要指的是使用用户语言而不是开发者语言,让用户能理解】
  3. 用户有控制权
    • 【程序自己信马由缰地跑起来了之后,用户也就跑了……】
  4. 一致性和标准化 -【我认为应该指的是程序的语言使用要前后一致、有标准可循】

CHAPTER13 软件测试

从这一章开始,内容已经从“如何设计”上升到了“如何完善”,比如测试、质量保障等等;这也符合一般认知规律。软件测试这一章其实讲的东西很广泛,然而我认为视个人需要理解到一定深度即可

1.基本名词

  1. test suite:测试用例集,就是一组相关的测试用例
  2. bug【我觉得看英文更能抓住这几个词的精髓】
    1. 症状(symptom):从用户角度看,程序出现了什么问题
    2. 程序错误(fault):从代码角度看,设么错误导致的上述问题
    3. 根本原因(root cause)
  3. 测试方法分类
    1. 黑箱:也就是注重软件的行为而不是内部结构
    2. 白箱:根据内部结构和知识来选择测试数据及具体的测试方法
  4. 测试目的分类
    1. 功能测试
    2. 非功能测试

2.测试方法

  1. 代码覆盖率测试(单元测试一般在项目开发阶段)

    不同的代码是否执行,有很多种组合。一行代码被执行过,不代表没有出现问题 代码覆盖并不能测出未完成的代码导致的错误

  2. 构建验证测试(开发阶段)
    • 什么是构建系统?根据百科定义,构建系统(build system)是用来从源代码生成用户可以使用的目标(targets)的自动化工具。目标可以包括库、可执行文件、或者生成的脚本等等。
    • 通过BVT的构建可以成为可测,即团队可以用这一版本进行各种测试,因为它的各种功能都是可用的。
  3. 探索式测试
    • 往往不进行重复测试
    • 一些风险很大的领域(一旦出了安全问题就会有很大威胁),就要多鼓励一些探索式测试
  4. 效能测试
  5. 验证的问题是:软件在设计负载内能否提供令用户满意的服务质量
  6. 实战中的测试
  7. 是在项目稳定阶段执行的。团队在这一阶段的核心任务是:在满足最低接受条件的前提下,提高各个部分的质量。
  8. 关于测试时机
    • 只在项目结束的时候测试即可?
    • of course not.越早介入的测试,发现问题之后修正的代价越小
  9. 关于测试文档
    • 写文档的目的是解决问题【也就是说,这些测试文档“信息量”越大越好;不说拖泥带水的废话】
    • 包括:测试设计说明书TDS;测试用例test case;错误报告bug report(bug修复之后,还要关闭缺陷报告)

CHAPTER14 软件质量

1.软件质量=程序质量+软件工程质量

  1. 程序质量体现在软件外在功能的质量
  2. 软件工程的质量
    1. 软件开发过程的可见性(visibility)【我的理解是和前面所讲的“估计预测”有关】
    2. 软件开发过程的风险控制(risk management)【又是management,这个词基本上相当于很有力度的“全局掌控”了;我们不能排除风险,但是可以进行预防、疏导和补救】
    3. 软件开发成本的控制(cost control)【不是management而是control,何解?成本自然是越小越好,越能够control(约束)越好】

2.CMMI(capacity maturity model integrated)能力成熟度模型

  • 衡量和管理项目。降低成本的同时提高了项目质量和完成率
  • 两种实施方法
    • 连续式:衡量企业在某一个项目中的管理能力
    • 阶段式:衡量一个企业的成熟度

3.一些妙语

  1. 要达到一定的软件质量,是要付出成本的。

【我认为现在(或者以前也没有?)并不是讲求“质量第一”的时代;而是“质量成本第一”——什么样的质量投资是值得的,才会投资什么】


  1. 每个角色的水平不一样,水平最差的角色往往对软件质量的影响最大。

【我以为软件开发遵循的并不是“木桶原则”——至少有一个优秀的成员总会很有帮助。不过如果从另一个角度去想,软件的质量由很多方面的因素构成,任何一个因素的“覆灭”都会急速拉低其质量。所以,书中的意思是,不要盲目加信任“专业人士”,他的专业性仅仅指的是其所在领域,而不是“软件行业的XXX”】

CHAPTER16 IT行业的创新

1.创新之迷思

    1. 灵光一闪,创新即来
      • 【我认为这个与幻想“一步登天”的寓意基本上是一致的;人类的知识积累在今天已经达到了相对来说无比丰厚(当然还不是无穷大)的阶段,就算这个一闪而过的“灵光”货真价实而且十分有意义,也不可能给个人带来额外的几个大脑沟回并且在其中填满二十几个世纪以来的相关知识。That's to say,爱迪生的那句“成功是1%的灵感和99%的汗水,然而没有那1%也会一事无成”。】

      2. 人们都喜欢创新

      • 【从我个人的角度而言,我十分能理解反对创新的理由——安全。按部就班是活着的人减少出错的最好途径。作者举了“使得石墨变成钻石的技术实现”这个例子,实在是太深刻。】

      3. 技术的创新是关键

      • 【我的潜意识里面也一直有这样的想法:虽然我现在的水平不高,但是我孜孜不倦地学习为的是创造新技术(或者说创新)——不过理性来看,作者说的更有道理:“科研是将金钱转换为知识的过程,创新是将知识转换为金钱的过程”。科研的目的并不是创新。】

      2.关于创新的时机

      1. 只先一步

        做前沿研究的人,可以早于其他人很多年提出新想法,但是这些想法一般都是在“创新者”那个圈子里有影响,这些想法要等若干年后才能由一个或者多个企业看准时机推向大众市场

        • 【开句玩笑,怪不得诺贝尔奖得主大部分都是暮年的学者】
      2. 技术成熟度曲线

        1.  我在网上找了最初比较简单的图片贴了上来,主要就是关注曲线上陡然下降的那一部分——可以称为膨胀的期望与骨感现实之间的调整。就好像鹰在寿命过去3/7之后的那一段时间,能挺住就又可以活40年,挺不住就就此谢幕。

      1. 竞争的各个阶段

        不合时宜的创新,则往往隔靴搔痒,事倍功半

        • 在新兴市场和成长期,技术的突破和创新往往令人兴奋——因为产品有大量的目标用户,完全可以消化这些成本;然而,在衰落期之后,再创新就有点“性价比过低”了,此时的目标应该是引导用户向新产品过渡。

      3.套路【这个词没有贬义】

      1. 了解团队能力,产品方向和大环境的趋势
        • 【逆流而上需要勇气,但一般是悲剧】
      2. 选择合适的细分市场
        • 【对于细分市场,作者的解释是:“这个市场大到足以产生影响,小到让产品在其中领跑”——我猜想,比如我们一个“信息安全”专业就可以作为背单词软件的细分市场】
      3. 对于互联网消费者产品
        1. 向细分市场投放满足消费者刚性需求的产品;
        2. 吸引更多用户,跟踪产品的使用率和留存率
          • 【我也曾经看到APP排行榜的新的好玩的APP或者因为一些广告而下载了一些APP,新鲜劲儿过去之后,基本上没有APP留下来——比如一款专门用来展示团体照片的APP,恕我直言,我并不经常拍照,也不经常去四处游玩,因而这款APP对我来说就真的是“三天打鱼两天晒网”而已】
        3. 在用户中招募粉丝,让粉丝有参与感并整合到市场推广中;
          • 【我在其发展之初就订阅了“青年菜君”然后下载了们的APP(当初只是为了好玩);我看到的是他们真的会邀请用户去免费品尝新菜品、体验做菜过程然后大家一起热热闹闹开小会】
        4. 重复1.——3.

      4.小即是美(Small is beautiful)

      这句话我特别赞同,因为最初是在做古城保护性开发的大创研究的时候看到某国城市规划专家的说法,加上对阆中古城(我认为就是小而美的典型)的考察比较满意。不过在《构建之法》中到还是很惊喜的;规模大了是有好处,不过不见得“大规模==大行业”。

 

练习与拓展

1.chapter1-1 练习

花20分钟写一个自动生成小学四则运算题目的“软件”。要求:除了整数以外,还要支持真分数的四则运算。

要点:

1.x op y 的形式;

2.关于x,op,y三者的随机且合法的产生(使用rand和srand函数需要注意如何避免x,op,y的重复:每次设置不同的随机数种子之后再产生随机数;x,y,op的合法性检查:x、y设定为在0——100之间,op只有四种可能的取值+ - * / 且当op = / 的时候y !=0)

3.结果的检验(支持结果为整数和真分数的运算,即结果不合法的算式将不会被打印出来而是重新产生)

2.chapter3-1 工程师自我评价清单

(参见http://www.cnblogs.com/xinz/p/3852177.html

一共37条选择题,既是对自己的测评,也算是一种比较严格的目标。我自己算了一下,能做到的只有(2.)主动解决问题、(3.)经常给自己充电、(4.) DRY (Don't Repeat Yourself)——别重复、(8.)估计任务所花费的时间,避免意外、(10.)有很多代码编辑器,请把其中一个用得非常熟练、(13.)在debug的时候,不要惊慌,想想导致问题的原因可能在哪里。

其中,关于“善始善终”和“重视算法的效率”这两条确实是我之前可以做到但是很少考虑到的。

3.chapter3-2 软件开发是一门工程,一门手艺还是艺术?

【我认为,软件开发:

  1. 首先是一门工程,然后才能算得上是手艺;
  2. 最基本的要求是严谨,在此基础上会有适当的“精妙”,就像“妙笔偶得之”,不能为了精妙而去刻意追求;
  3. 软件开发不能算作艺术,因为优秀的文艺作品并不等同于优秀的软件工程作品;前者必须以实用性的原则作为优先考虑的因素】

4.chapter3-3 绞刑架与职业发展

就像评论家在评论苏轼作品的时候曾说,苏轼在词方面的造诣如此让人惊叹,是因为他已经做到了“戴着脚镣跳舞”——遵循严格而刻板的规则,却同时可以写出十分漂亮的词。

软件发展也可以借用这个道理。没有规则的“绞刑架”,导致的不仅是软件行业的鱼龙混杂,更可能导致这个行业的覆灭。

5.chapter3-4 关于3.4 练习与讨论 中的4.

程序员小飞计划用三天完成某个任务,现在是第三天的中午,他马上就可以做完。他越来越意识到原来的设计中的缺点,应该采取另一个办法;然而这个办法要耗费额外的时间。 要不要做这个改进?

思路: 理性分析当前问题的解决方向和后果——

  1. 如果要进行改进,预计要花费多久?如果耗时超过团队或者个人可以承受的范围,则无法在当前进行改进;否则继续考虑;
  2. 如果不进行改进,那么后续整个团队的工作以及个人的工作要多多少?而这个后果自己能否承受?否的话,则进行代码改进;否则继续考虑;
  3. 进一步考虑最坏的情况,任务期限是否非常紧张以至于完全不能花费多于的时间去改进代码?是的话则不能改进;否则继续考虑
  4. 而现有的代码完成之后是否可以正常运行或者是作为一个模块进行封装之后去作为下一步开发的基础?是的话,可以暂且交付这个版本,并在后续进行改进和替换。

6.chapter3-5 成长和代码的关系

(参见http://www.techug.com/norris-numbers

实际上,这种思想已经在老师的课堂上给我们或多或少的渗透过一些了,现阶段对于我们而言比较重要的一个节点就是2000行这个瓶颈。我们班中大多数人的代码书写量肯定已经突破了这个数量。根据比较科学的理论(就如 程序师 中这篇文章所言),我们已经进入了一个“需要更换交通工具”的时期;也就是说,除了蛮力之外,还需要一些新的方法(比如大量阅读代码)。

7.chapter4-1 性格对合作的影响?

参考http://baike.baidu.com/link?url=EZ3MAPdwTpRsHDZTBQJCnE2U5cT9qypV-bTM7chk_fV7xJJs90c0yuDi0z0S4UPv7JEtkcY3mjnzC3PJNHWfDq

随手百度了一下MBTI的理论;虽然网上有观点认为其不靠谱,然而我认为其四个维度的划分还是很科学的:

  1. 外向(E)和内向(I)
  2. 感觉(S)和直觉(N)
  3. 思考(T)和情感(F)
  4. 判断(J)和知觉(P)

我自己找了一些测试测了一下;其实也很容易可以根据自己往常表现有基本正确的推断。我个人比较ISTJ(传统的思考者)。

8.chapter6-1 微软学术搜索项目10个版本的历程

  • 参考http://www.cnblogs.com/xinz/archive/2012/02/20/2358888.html,感觉很有意思,很震撼
  • 我看到的是就像一个孩童逐渐长大一般的开发流程,历时三年多的开发流程应该是对敏捷开发最深刻的证明之一。10个版本似乎相邻项的“迭代”很重重叠,然而V10和V1却可以说是完全的天壤之别。
  • 所有的项目刚开头的时候都是特别痛苦的,就算我刚刚开始不看课本独立写一个走迷宫小程序的时候也觉得无处下手(我妄揣大型项目应该更甚);所以才会有很多方法论(比如敏捷开发)指导我们怎么走这开始的、关键的又迷茫的几步。
  • 此外,文章最后也有一个彩蛋——关于微软学术搜索的功能(更加让读者相信这样的工程完全值得做三年)。越往后越有很多特别brilliant的设计,甚至超出了我最初对“搜索”的理解——然而很有意义,(我个人认为)对很多重要的客户也很有用。
  • 干一行,专一行。在这里也可以解释为:做一个项目,研究透彻一个行业。

9.chapter8-1 估计与假设

探寻目标数值背后的假设,这是作为项目经理最重要的能力

【估计的结果并不是十分重要,然而“理由”才最重要】

另外,如何验证假设? 1. 快速原型法——用一两个先锋去探路 2. 理性估计 1. 自底向上。 2. 回溯

10.chapter8-2 关于《画扇面》的思考

  • 侯宝林大师的这个经典相声我也听过很多遍,能感觉到深意然而不能明确地说出来。看到邹欣老师的比较,发现倒是很有意思。
  • 小问题解决好也是很有意义的——而且很有价值;特别是好高骛远地追求“一步登天”却一事无成的时候。

11.chapter12-1 独特的设计总是有独特的原因

参考http://blog.jobbole.com/18650/

最开始用vim的时候我也抱怨过为什么不能用键盘上的方向键作为上下左右的按键;看完我才知道,创始者们用的键盘和现在的键盘不一样……

疑问与自查

1.第一章实践的时候反复困扰的问题

  1. 关于visual studio express 2012&visual studio ultimate 2010的安装与使用

    • 最开始的时候,处于win8.1系统兼容性的考虑,我选择安装了较为可靠的vs2012(express版本);并且找到了激活码进行激活。

    • 然而,在实际使用的时候,发现vs2012与之前的版本相比居然改掉了添加单元测试的功能。于是,我扒了若干帖子,在百度经验、博客园中发现了恢复出此功能的方法(参见http://www.cnblogs.com/Gyoung/p/3143438.html);按照步骤反复尝试之后,始终不能在“添加新项目”中找到“测试”一项。下图是正常情况;而我所安装的vs2012中缺少office和sharepoint两项:

    • 于是,我只好转战vs2010。下载了visual studio ultimate 2010.ios;用管理员身份运行之后,成功安装到了windows8.1的系统上。接下来就是尝试使用了。

2.阅读第三章的时候几个小问题

  1. 什么是六西格玛?

    • 我在第三章中第一次见到这个名词,之后在第六章中又出现;因此我上网查了一下这一名词的解释。百科上对这个概念的解释也比较晦涩复杂,要结合着书本和图例进行理解。 (参考http://baike.baidu.com/link?url=slFyAzux3dO4Rf2Ov-c81WSKs2glvEOI1SO5XCG-FhY45mK2NWRkX8BWgsZ-qCjm_FjuJHMj0zoB4sJ-FN99Sq

    • 其实这是一种音译,西格玛(σ)是统计员用的希腊字母,指标准偏差。术语六西格玛指换算为百万分之3.4的错误/缺陷率的流程变化(六个标准偏差)尺度。作为一种管理策略,六西格玛代表一种很高的目标要求;为了达到这一目标,核心团队必须有着极高质量的运行过程和及其明确的项目改进套路。我认为,源自通用电气、由摩托罗拉提出的6σ方法应该就是为了适应日趋激烈的竞争潮流和日趋严苛的市场要求和产生的高速、高效、高能的管理策略。

  2. 什么是破窗效应?

3.阅读第四章的时候几个小问题

  1. BSTR类型?

  2. 关于代码的复审,其实作者说的是相对比较专业的。有一些地方,比如———什么算“容易维护”的代码?什么叫做“硬编码”?都是值得考究的。

    • 代码的易维护性:
    • 硬编码:顾名思义, 就是把数值写成常数而不是变量。很明显的缺陷就是改动起来十分的麻烦。
  3. 很惭愧,对于重构的概念已经记得比较模糊。

    • 其实在学习java的时候,重构这个概念还是以一个高级别的概念被提到过的;而且就是字面意思那么简单——重新塑造(这个词有些严重了,或者叫改善)代码结构。
    • 不过看了博客上的一些观点之后还是觉得想的太单纯了。这个策略之所以如此受欢迎,几乎因为它可以“妙手回春”般地拯救被各种补丁折磨得面目全非的程序。我觉得就是把之前做在外面的事情以同样的效果为目的做到里面去,让代码从内而外地健壮起来。
    • 不过,怎么做呢?(博客园真是个好地方)参考http://www.cnblogs.com/Kevin-moon/archive/2010/05/10/1731358.html
    • 为了了解“病灶”,需要查看至少80%的核心代码;还要有足够的时间和资金去分析哪个模块需要重构……只能说,理想很丰满,现实很骨感。

4.阅读第6章的时候几个小问题

  1. 戴明环? 

又叫PDCA还,是一种质量管理环。其实这个环形对我而言是很熟悉的,有点类似于PPDR的防护模型;也是旨在通过环环相扣的概念力求完整包含高质量管理的各个方面

5.阅读第11章的时候几个小问题

  1. 何为“签入”?
  2. 参考http://baike.baidu.com/link?url=EfXBecQTO7RsH7E7YaoTNtIRjpt7ZR-LclWWqu2N76dTbiBt7BZ_0dFKcGgv-VTMEHlm0TEplPjqfY6X9XW8Xa

若要将已修改的源代码管理文件用于其他用户,必须将这些文件签入到源代码管理中。签入文件时,所签入的版本将写入源代码管理提供程序,并成为文件的最新版本。

6.解决问题过程中的问题

  • 书上有很多网址链接,有一些比较长,而且敲进去之后满篇外国蚂蚁我实在是无法顺溜地读完;所以吃了好几次“堑”之后我开始注意怎么一眼看出来这个网址是英文还是中文呢?
  • 然后,其实刚开始的时候还是用的老办法,第一个/之前有什么cn,cnblog,blog……之类的肯定是我比较常逛的那几个网站,一定是中文;而wiki,net之类的我就直接敬谢不敏了;
  • 后来,我又在地址栏敲网址:http://www.ui.cn/project.php?id=31286;直接跳转到了http://www.ui.cn/detail/31286.html,我有一点好奇了:?、%、&这些神器符号在网址里面这么意思?(我猜上面的?应该是连接的吧)
  • (博客园是个好地方)我又一次在博客园找到了答案:http://www.cnblogs.com/kaituorensheng/p/3776527.html
  • 大致浏览了一遍,原来我接触到的?果然是连接作用。确实很有成就感。

 

后记

  • 读这本书比我预计的时间要长,因为中间夹着除夕春节,迎来送往中我一个“贪玩”就耽误了之前的计划(原来计划是每天读这本书22页,预计约15天可以读完);还有一个原因就是我没有想到这本书如此“麻烦”——且不说VS2010与VS2012两个版本在电脑上不成功的“着陆”,就是书本上我自己勾画满篇的“?”也需要很有耐心地问百度、博客园和CSDN;
  • 一开始对这本书的名字没想那么多,只不过因为觉得好玩所以饶有兴致地研究了一下封面上的“鲁班锁”。不过,大概读到3/5(也就是第七、八章)的时候开始逐渐有了眉目——所谓“构建之法”,确实是本书最好的概括之一:通篇均为“法”,能够做到读起来“津津有味”已经很见功底了;不过,就像鲁班锁一样,并不是说学成了“法”、知道这个“锁”怎么去做就可以了;而是通过这个“锁”去打开背后的世界(我认为应该是实践吧)
posted @ 2016-02-18 18:30  5216  Views(1316)  Comments(14Edit  收藏  举报