【by 初学者 2016.1.23——】
【为什么要写这篇几万字的“读书笔记”?】
软件与程序的区别,恐怕就是实用性与理想性的区别。软件=程序+软件工程;程序=数据结构+算法。我们现在学的,只是后者的构成,而从理想迈向实用的最关键的一步,就是软件工程。
1)软件构建:除了代码和静态数据,还有各种文件和数据来描述各个程序文件之间的依赖关系等;
2)源代码管理/配置管理:保证代码的平台兼容性、配置兼容性等;
3)质量保障(软件测试):保证软件的质量在修改过程中可以不断提高,或者至少可以保持;
4)项目管理:软件维护和服务运营
5)生命周期:以上称为软件的生命周期SLC
我以为,软件工程是构建在计算机科学这一学科之上的、拥有庞大的学科支持体系、致力于解决实际应用中层出不穷的需求和问题以期获得趋于完善的实用“工具(软件)”的体系。
这一章重点介绍的是以前了解过但未曾注重过的单元测试&回归测试;个人技术素养是团队协作的基础。
源代码
public Class User() { public User(string userEmail) { memail = userEmail; } private string memail;//private变量拒绝外部类访问(除非用get/set方法) }
测试代码1
public void ConstructorTest() { string userEmail = "[email protected]"; User target = new User(userEmail); Assert.IsTrue(target != null);//测试制定条件为真时测试成功 } 测试E-mail是否确实保存在了User类中。关于Assert:在工程之中可以使用该类对特定的功能进行验证,单元测试方法执行开发代码中的方法代码,但只有包含该语句的时候才能报告代码行为方面的内容。
测试代码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),前者是由于空参数传递给不接受它的方法中引发的异常,后者是由于向方法中提供的一个参数无效而引发的。
在新版本上运行所有已经通过的测试用例,以验证是否有“退化”的情况发生。单元测试是回归测试的基础。
源代码(伪代码)
//分析一个文本文件中各个词出现的概率,然后把出现频率最高的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;
}
【抽样】得到运行时间的函数分布的大致抽样,速度快但是不能得到精确数据;
【代码注入】将检测的代码注入每一个函数中,速度慢但是各个效能数据可以被精确测量
【调用关系树(call tree)】从mainh函数开始,调用者与被调用者函数形成的树型关系
【消逝时间(elapsed time)】用户角度看程序运行所花的时间
【本函数时间(exclusive time)】所有在本函数花费的时间,不包括被调用者花费的时间
【应用程序时间(application time)】应用程序占用CPU的时间,不包括CPU在核心态时花费的时间
耗时最高的前三个函数:FreqOneWorld,EqualsHelper,ArrayList.get_Item
举例来说明耗时时间的长短:
for(i = 0;i<m_worldList.Count;i++)
{
......
}
验证表明,mworldList.Count被调用了1 600 000次以上。也就是说,如果将for循环中的mworldList.Count用一个变量代替,将极大地节省时间。
【一些寻常的习惯可能极大地拖慢程序代码的整体时间性能。效能分析是给我们一种“强迫式”改善思维方式的外力】
个人开发流程(personal software process)又叫PSP,是指导软件工程师进行开发的方法论;一般包括计划、开发(含测试)、报告。PSP目的是记录工程师如何实现需求的效率,而不是记录顾客对产品的满意度。
【也就是说,PSP并不是万能的(事实上也不存在万能的方法论);只是在前人实践的基础上总结出的通用方法集】
关于软件工程师这一现实职业(而非大学中与计算机有关的专业)的发展标准与前景展望,引入了相当多的、作为一名本科生鲜少去注意的职业概念
目的是为了提高软件开发、运营、维护的效率,以及提升用户的满意度、软件的可靠性和可维护性。
【其实这个说法不容易理解,因为我们(至少是我)所理解的“技能”的表现形式就是“解决问题”。但是作者的意思在于:能够称之为“技能”的项目,是你(或者我)已经机械化地精通低层次问题、用时间和脑力正在去思考高层次问题的项目。比如,以C语言为例,我应该对基本语法烂熟于心、对数据结构也已经很有研究、正在思考的是如何对C代码进行时间效率和空间效率的改进】
两人合作是团队合作的基础;这里介绍的这个基础型“团队”中通用的一些方法以及最重要的——交流——的细节
代码复审的目的在于找出代码的错误。因为越是项目后期发现的错误,修复的代价就越大——这也是learning by doing思想的体现。
典型的团队开发模式和流程,完全是新的内容;涉及到更多的术语和有意思的策略性东西
RUP就是把软件开发的各个阶段整合在一个统一的框架里面。其规程(discipline)或者工作流(workflow)如下———
- 业务建模:用精确语言描述用户活动
- 这里提到了UML(统一建模语言),其实这种建模的思想应用很广泛;举例来说,“编码理论”或者是“数字电路基础”这种课程所用的状态图等都可以归属于UML中
- 需求:从活动中感知并表达需求,从需求中抓出软件(至少)要实现的功能;
- 分析和设计:将系统划分成子模块;
- 实现:紧接上一步,搭建可执行的系统;
- 测试:验证已经交付的组件之间的正确性、组件之间交互的正确性以及所有的需求是否已经被正确地实现;
- 部署:生成最终的版本并分发给所有用户;【其实我之前的想法是到此为止,然而在现实中并不是这样,作为一个目标是拥有一定生命周期的软件,后期的维护、管理也是必不可少的】
- 配置和变更管理:记录各个阶段产生的各种工作结果;
- 项目管理:平衡各种因素,以便在各个阶段交付达到要求的产品;
- 环境:向软件开发组织提供软件开发环境【每个阶段都有点类似迭代开发(把一个大的目标逐步完成,每一个阶段所完成的都可以为下一个阶段做铺垫)】
敏捷是一种很“年轻态”的思路/策略,是以“万事万物都在不停地发展变化”为指导去组织软件工程的需求分析、内部的调和、代码编写甚至维护,所以我读起来会觉得很有共鸣。然而并不是所有的地方都适合让“敏捷”去闯一闯。
【适应瞬息万变的形式,力求在大潮中可持续发展;年轻态】
【个人进行了分析组合】 1. 可用的、尽早交付的软件是项目进展的主要指标 2. 保持可持续的发展,以需求作为发展优势 3. 自我管理。无论是交流还是信任还是共同工作
另外,如何让敏捷流程不流于形式?
因为作者是微软的资深工程师,所以这一章里面我看到的一篇很原汁原味的精髓版软件开发方法。并不是说我一定要在有生之年参与一个多么浩大的项目然后用尽这里的所有知识;而是站到高处去看会很精彩。
无责任的旁观者和有重大责任的当局者的看法自然是不一样的
一个团队如果没有经得起考验的商业价值,没有明确的远景,是很难坚持下去的
其实这是“啃硬骨头”的第一步,就是如何从“茫茫”中锁定需求相关方、挖出来需求的方法论
深入面谈(in-depth interview):采取一对一的采访方式,着重探究用户在使用的时候有哪些困难 【以下方法我认为可以看做是进行需求分类的方法】
卡片分类(card sorting):将杂乱无章的需求分条目地写到卡片上,然后对这些卡片进行讨论、归类甚至排序
以NABCD模型为例 1. N——NEED需求 2. A——APPROACH做法 - 有什么(独特的)做法去解决用户的困难 3. B——BENEFIT好处 - 特别注意用户迁移成本的问题。指的是用户要得到我们所做的软件带来的好处,需要花费多少时间、金钱甚至精力(去转移使用) 4. C——COMPETITORS竞争 5. D——DELIVERY推广
【酒香也怕巷子深。对自己的产品有着清楚的功能定位——或者知道如何表述这种功能,是很重要的一个“让酒走出去”的手段】
要把用户从竞争对手那里吸引过来,团队自己的产品要有一个差异化的焦点,在这个焦点上,我们的团队能做得比别人好10倍,高一个数量级。 于是我们有了两种不同类型的功能:杀手功能(core)/外围功能(context) 还有另外一种划分:必要需求/辅助需求
WBS通常从最终的产品开始,一层一层往下,把大型交付件(deliverable)分割为小型、具体的交付件(从结果出发,而不是团队的活动)
PM最大、最独特的贡献是带领团队达成最重要的目标,并保持团队的平衡
【这里特别提出了作为在校生如何培养PM素质。作者首先推荐的不是“学好专业课”,而是“多参加活动(特别是从下而上的草根活动)”,感觉别有深意】
作为软件,最大的目的不是考验“软件工程”,而是“用户至上”的使用性好坏。所以多了解一些“用户之法”多有裨益。另外,关于spec也在本章中有所涉及
参考http://www.cnblogs.com/xinz/p/3855296.html
ATM机操作界面的典型用户?(至少五种)【个人观点】
将用户需求变成团队成员可以直接操作的开发工作
主要是介绍开发的流程
- 当场景、功能都计划好的时候,要给员工足够多的时间,让他们投入到工作中去,而不要经常打断他们
- 如果开发人员的“小强”(bug)数量超过一定值,则此君被送入“小强地狱”,在地狱中,他唯一能做的事情就是修复小强,直到小强数量低于此阙值
无论软件还是硬件,都有很多功能,各个部件还要有机地结合起来,才能够满足用户的需求
1.用户需要帮助,但是用户没有那么笨
- 比如,能够使用计算机软件的用户肯定不用翻译软件去解释a,the,this……是什么意思
2.dogfood的传统可以帮助发现问题(自己使用自己开发的软件)
3.长期使用之后,软件会变得好用吗?(我认为可以把这个称之为“软件的记忆问题”或者“软件与使用者的契合度”)
另外,
花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.结果的检验(支持结果为整数和真分数的运算,即结果不合法的算式将不会被打印出来而是重新产生)
(参见http://www.cnblogs.com/xinz/p/3852177.html)
一共37条选择题,既是对自己的测评,也算是一种比较严格的目标。我自己算了一下,能做到的只有(2.)主动解决问题、(3.)经常给自己充电、(4.) DRY (Don't Repeat Yourself)——别重复、(8.)估计任务所花费的时间,避免意外、(10.)有很多代码编辑器,请把其中一个用得非常熟练、(13.)在debug的时候,不要惊慌,想想导致问题的原因可能在哪里。
其中,关于“善始善终”和“重视算法的效率”这两条确实是我之前可以做到但是很少考虑到的。
【我认为,软件开发:
就像评论家在评论苏轼作品的时候曾说,苏轼在词方面的造诣如此让人惊叹,是因为他已经做到了“戴着脚镣跳舞”——遵循严格而刻板的规则,却同时可以写出十分漂亮的词。
软件发展也可以借用这个道理。没有规则的“绞刑架”,导致的不仅是软件行业的鱼龙混杂,更可能导致这个行业的覆灭。
程序员小飞计划用三天完成某个任务,现在是第三天的中午,他马上就可以做完。他越来越意识到原来的设计中的缺点,应该采取另一个办法;然而这个办法要耗费额外的时间。 要不要做这个改进?
思路: 理性分析当前问题的解决方向和后果——
(参见http://www.techug.com/norris-numbers)
实际上,这种思想已经在老师的课堂上给我们或多或少的渗透过一些了,现阶段对于我们而言比较重要的一个节点就是2000行这个瓶颈。我们班中大多数人的代码书写量肯定已经突破了这个数量。根据比较科学的理论(就如 程序师 中这篇文章所言),我们已经进入了一个“需要更换交通工具”的时期;也就是说,除了蛮力之外,还需要一些新的方法(比如大量阅读代码)。
参考http://baike.baidu.com/link?url=EZ3MAPdwTpRsHDZTBQJCnE2U5cT9qypV-bTM7chk_fV7xJJs90c0yuDi0z0S4UPv7JEtkcY3mjnzC3PJNHWfDq
随手百度了一下MBTI的理论;虽然网上有观点认为其不靠谱,然而我认为其四个维度的划分还是很科学的:
我自己找了一些测试测了一下;其实也很容易可以根据自己往常表现有基本正确的推断。我个人比较ISTJ(传统的思考者)。
探寻目标数值背后的假设,这是作为项目经理最重要的能力
【估计的结果并不是十分重要,然而“理由”才最重要】
另外,如何验证假设? 1. 快速原型法——用一两个先锋去探路 2. 理性估计 1. 自底向上。 2. 回溯
参考http://blog.jobbole.com/18650/
最开始用vim的时候我也抱怨过为什么不能用键盘上的方向键作为上下左右的按键;看完我才知道,创始者们用的键盘和现在的键盘不一样……
关于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的系统上。接下来就是尝试使用了。
什么是六西格玛?
我在第三章中第一次见到这个名词,之后在第六章中又出现;因此我上网查了一下这一名词的解释。百科上对这个概念的解释也比较晦涩复杂,要结合着书本和图例进行理解。 (参考http://baike.baidu.com/link?url=slFyAzux3dO4Rf2Ov-c81WSKs2glvEOI1SO5XCG-FhY45mK2NWRkX8BWgsZ-qCjm_FjuJHMj0zoB4sJ-FN99Sq)
其实这是一种音译,西格玛(σ)是统计员用的希腊字母,指标准偏差。术语六西格玛指换算为百万分之3.4的错误/缺陷率的流程变化(六个标准偏差)尺度。作为一种管理策略,六西格玛代表一种很高的目标要求;为了达到这一目标,核心团队必须有着极高质量的运行过程和及其明确的项目改进套路。我认为,源自通用电气、由摩托罗拉提出的6σ方法应该就是为了适应日趋激烈的竞争潮流和日趋严苛的市场要求和产生的高速、高效、高能的管理策略。
什么是破窗效应?
参考http://baike.baidu.com/link?url=1oCKmvZNnfKn67dAo6dxPPgUsyjlp12RApy3TrqCiz-rRykexpfsntcaSi_PaE-whgyqwwFLFOOB-mKXvz0UIK
我发现这是一个很有魔性的心理学实验结论。有了任何(即使是很细小的)不良环境现象存在,后续就会产生越来越多的、变本加厉的不良环境现象。
BSTR类型?
参考http://www.cnblogs.com/kwliu/archive/2011/07/15/2107805.html以及http://baike.baidu.com/link?url=YmDes2v5BHCbsrxxq7UBrhyiI6vmRT0mzd8MR73ZLvOzajR7TF3WGFMlp1NfC8mRb4BjP7-lGmcBcKjXuu7K4q
按照头文件的定义,BSTR其实就是指向WCHAR类型的指针;而在百科中,对char类型与wchar_t类型做出了解释。
关于代码的复审,其实作者说的是相对比较专业的。有一些地方,比如———什么算“容易维护”的代码?什么叫做“硬编码”?都是值得考究的。
很惭愧,对于重构的概念已经记得比较模糊。
又叫PDCA还,是一种质量管理环。其实这个环形对我而言是很熟悉的,有点类似于PPDR的防护模型;也是旨在通过环环相扣的概念力求完整包含高质量管理的各个方面
若要将已修改的源代码管理文件用于其他用户,必须将这些文件签入到源代码管理中。签入文件时,所签入的版本将写入源代码管理提供程序,并成为文件的最新版本。