《构建之法(第二版)》是一本由邹欣著作,人民邮电出版社出版的平装图书,本书定价:59,页数:400,文章吧小编精心整理的一些读者的读后感,希望对大家能有帮助。
《构建之法(第二版)》读后感(一):值得一读的现代软件工程宝典
作为一名软件工程专业的学生,我们学习了高级编程语言、设计模式、网络等等,我们在一层一层地堆砌着基础框架,但实践却很少,如何把所学运用到实践中?实践中又会遇到什么困难?如何解决?怎样才能高效敏捷地开发?这些实际上是对我们来说至关重要的问题和体验,也是只有在实践中才能慢慢探索有所感悟的,这也是《构建之法》这本书所提倡的“做中学”的重要性。
在后来的团队合作开发一个项目的过程中,我们写文档、尽可能地遵循书中所说的敏捷开发的原则。我们体验了从软件需求分析到软件维护的比较完整的开发过程,充分运用了所学;体会到团队精神的重要性,要实现1+1=2是十分不容易的,往往我们的合作效率是1+1<2的;我们用代码版本管理工具来管理项目代码,每个人在各自的分支上开发……在开发过程中,我们尽可能地遵循了书中所提倡的规范,受益匪浅。
这本书以轻松易懂的语言把软件工程开发方法血的清晰、有意思,让人读的舒服、通畅;这本书还强调了“人”在软件工程开发过程中的作用,在真实的开发中也深有体会,如果将人与人之间问题处理好,开发过程确实可以事半功倍;书中提到的“敏捷开发”是我十分推荐的,在实际的开发中帮助很大。
《构建之法(第二版)》读后感(二):学习软件工程——一本很不错的书
这学期学习软件工程,在老师的推荐下拜读了构建之法一书,感觉受益颇丰。首先,在结构上突破传统软件工程教材的框架,不是按软开发周期(概论、需求、设计、编程、测试、维护等)来叙述,而是先从软件开发个人技能开始,逐步进入两人结对编程、代码互为评审直至团队开发模式之中,更容易让学生感觉软件工作具有实实在在的内涵,而本学期的项目实践过程中,也在极大程度上参考了书中的内容进行实践开发。 书的内容精炼,文字幽默、轻松,印象最深的是: 1) 设定不同人物角色或用户角色(如大牛、小飞、阿超、芸芸等),结合所讨论的研发场景(如日常管理、持续集成、代码评审等),让读者能够感受到真实的研发环境。通过大量人物对话形式来展现不同角色的冲突、暴露问题的细节,尽可能的让读者感受到实践中可能会遇到的一些问题以及解决之道。 2) 案例丰富,对实践环境描述很细,如按小时(时间段)来介绍具体开发流程。而且,提供了足够的练习,营造了一个良好的教与学环境,能够极大地提高学生学习软件工程的兴趣,从而有效改善软件工程教学效果。 当然,也感觉有一点不足之处在于 “软件设计”内容偏少,代码覆盖率测试不够全面,没有谈到分支、条件、MCDC。
这是一本很系统讲述软件工程科学的书,印象中最深还是最开始的软件=程序+软件工程,简洁而又具有深度。作为一个开发者来说,之前学习的课程大部分主要集中在程序方面,怎么做一个好的程序。但是程序最终还是落地的,程序是要服务于人的,同时大型的程序不是课题上的小手工能比,需要团队参与。构建之法向我展示了一个真正的业务开发流程的全貌。可以说学习书本之前,我对软件的认识还停留在技术上,这个网站用了什么架构方案,那个负载均衡做的很好,听说这个系统的数据容灾不错,而这本书提供我另一种视角看待软件,这个项目是一个什么样的工程,需要多少人力物力,同时团队协调工作好做吗?这些都是以前我不会想到的。
工程能力,工程思维很大程度是不同于的代码能力的,相比于单单注重逻辑的代码。工程能力关注在时间与成本,对人的管理上面。而这些是一个大型项目所必要的。用一个简单的比方,代码能力好比是建筑工地工人们搬砖的能力,代码能力好的人,或许能够自己盖一个不错的小房子,甚至能够很精致。但是对于摩天大楼来说,需要的就是工程能力,如何协调工人干活,如何整理记录,让新成员也能够快速接手,避免项目烂尾。可以说,这本书对于每一个软件工程师来说,都是不同于以往其它专业知识的。
还有一个很大的收获,是这本书描述了需求的重要性,作为一个科班生来说,往往更加注重于程序的健壮性和功能性,但是软件在不考虑的用户需求的前提下,不管多么强大的程序都显得毫无意义,用户不会关心这个程序你写了多久,花费了多少心思,用了什么强大的技术实现的,用户只想知道,这个软件能帮我做什么。 面向用户是十分重要并且必要,搞明白需求的过程中,也是逐步明白一个软件的价值的过程。
当然,纸上得来终觉浅,绝知此事要躬行,虽然这本书很多内容都不错,但是作为在校生来说,书本的内容是比较难完全实现的,大部分项目都比较小打小闹,如果能够在一流的IT公司实习,想必是可以很好的锻炼构建以及软件工程方面的能力。
聊了这么多自己的感悟,这本书本显然是值得推荐的,一个方面是因为它十分的系统,介绍了软件工程需要的技能以及方式。第二个方面在于这本书行为并不枯燥,举得例子也很形象,一改工程类书籍留给人们的印象。书本中的很多方法结合了心理学,用户行为学,尝试从很多科学的角度解读软件工程。
最后也说点自己觉得书本不够好的地方,首先是书本的注释,注释都放在了章节的末尾,我觉得可以使用特定的专栏把注释放在前面,这样会比较方便。有些重要的内容,细节不够丰富,单元测试,黑盒测试这样的例子书本中只给出了定义,但是流程化的测试方法现在已经不少。如果能给出一些代码的例子我想对于程序员阅读者来说也不错。
《构建之法(第二版)》读后感(四):读《构建之法》有感
非常感谢邹老师能赠送给我《构建之法》这本书的电子版,也非常感谢周老师费心帮我弄兑换码等相关事宜。可惜的是我是教网络的,如果有朝一日能开软件工程的相关课程,我一定会选择这本书作为教材,就算不能让学生真正的理解软件工程,起码提高一下学生的代码量或者让学生养成每周写技术博客的习惯也是好的。
《构建之法》这本书我基本每天睡前读一章,有时实在太困了,可能就读半章。不得不说,这本书绝对是良心之作,不仅在软件工程方面让我很受启发,在教育教学方面我也觉得邹老师提出的方法非常值得借鉴。
书中用使用了移山公司,王屋村这样的经典词汇。都说程序员每天的工作就是搬砖,邹老师还真是把这点描绘的淋漓尽致呢。邹老师可能也想通过这些名字告诉我们,矢志不渝必能成功吧。
书很多人物之间的对话悄然道出了在开发项目的过程中,各色人等对项目的看法,对项目某些问题产生的质疑,以及日常生活中都会遇到的沟通障碍等等问题,基本上是我看到了一个问题我刚想找老师讨论,后面的小节就出现了人物之间就这个问题的讨论。
最让我欣喜的地方是邹老师不仅用这本书讲述了软件工程,还向我展示了作为一名老师的课程设计。如果讲这门课,课程知识点都有哪些,实验如何安排,个人项目、结对项目、团队项目都有哪些,如何验收,如何给学生成绩评定。其实在上课的过程中,我最痛苦的就是学生对课程实验敷衍了事,全班总有一两个能做出实验的同学,那么全班其它同学的结果就和这一两名同学的结果完全一致,这让我如何进行成绩评定,又如何得知大多数同学的学习效果是怎么样的呢。
邹老师提出在课程中要求学生写技术博客,并且通过博客与老师或者助教交流,博客大家总不能写的都一样吧,如果一样,那一定是抄袭无疑。通过博客也可以看到学生对项目和知识点的掌握情况。在课程中要设立个人项目、两人项目、团队项目,并且相信学生想做好,能够做好。那些多写测试工具,多写读书报告,多为大家服务的同学,也一定是认真的同学,同样能得到好分数。
团队贡献分,这是一个对同学很好的评价标准,平时同学都觉得生杀大权掌握在老师的手中,然而我们要转变这种局面,让同学自己决定。在一个团队中,谁干活了,谁没干,谁干得多,谁干得少,这大家都是清楚的,如果你在团队中很有威望,做了很多贡献自然分数会很高。
用客观数据来评分这也是一个非常好的评价标准。大家把自己写好的程序发到网上,下载量一目了然。你的程序好不好,不是你自己说了算的,你对技术理解的咋样看看你博客阅读量就知道了。当然了,这些也都是可以刷出来了,但大家把自己的东西都放到了网上,大家一定会更加认真的对待自己的作品,因为“是骡子是马拉出来溜溜”,全世界的人都能看到你的作品了,都可以给你的作品点赞或者抵毁你的作品了,是不是抄袭,谁抄袭谁的,不用我说,别人也一定看得出来。
课程设计这件事对于我这个新入职的老师来说受益匪浅,在我还在为课程如何设计,如何考核犯难时,邹老师已经在书中给我做了典范了。
《构建之法(第二版)》读后感(五):Build To Win
很早以前就想写篇长书评来致敬邹欣老师、周筠老师的编辑团队以及这本书。今日又翻开构建之法,忽觉自己亏欠这本书一个公正的评价,做事情不能虎头蛇尾,所以特地赶来写这豆瓣上的第一篇书评。
我想我是有必要来写这篇书评的,不仅是为了让更多人认识到构建之法本身的价值,更深层次的原因是:我是这本书所探讨的软工改革模式下的一位体验者,也是一名大大的受益者。我希望通过我上这门课的切身体会,打消那些还在犹豫是否要改革软工教学的老师们的顾虑。【我是北航计算机学院的学生,个人博客主页:http://cnblogs.com/SivilTaram,团队博客主页:http://cnblogs.com/buaase,这些都是软件工程课及构建之法带来的收获与成长】
首先对这本书给一个自己的评分,如果满分是10分的话,我给这本书9.5分。
我读这本书的历程和大多数人不同,我是通过`软件工程课`认识这本书的。开课第一周,老师要求略读一遍构建之法。当时自己偷懒,其实没读完,大致翻了翻。翻看粗读后,感受就像部分书评里说的:
其他感受?当时并没有细致去读,其实感受不是很深刻。只是觉得为什么软件工程里还会有这么多方法,软件工程不就是一些人合作做个项目就好了嘛?但现实远远没有想象的那么简单。团队项目刚开始时,老师要求进行典型用户的场景分析。为了做好用户的需求分析,作为项目PM的我仔细读了《构建之法》的第8章(需求分析)和第10章(典型用户和场景)。
第10章提出的典型用户和典型场景,尤其是关于典型用户的分析那一部分,讲得非常精彩!规格说明书(Spec)绝不是用来摆放的花瓶,它督促着一个团队对一个产品、一个项目的全方位思考。比如我们第一轮迭代启程会议时大家提出的若干个需求,在场景分析后删删改改成为了两个真正的刚需,后面产品的上线与使用的人数也映证了当初需求的化繁为简是多么明智。场景分析的过程是一次产品典型用户的反思过程,能让开发者真正从用户的角度思考一个产品的价值,这是以往的软件工程理论所不曾强调的。
与本书提倡的实践理念形成鲜明对比的是,传统的软件工程课只写需求文档,不做实践项目,不做产品运营和推广。但是,一个项目连用户都没有,又何来用户需求之说?而构建之法所提倡的实践软件工程的模式,文档是实实在在地发挥了作用。以前做过的课程设计大作业,都是先写代码,再写文档,居然是实验指导文档(笑)。而在构建之法中,第一次体会到团队项目中设计与架构的重要性——文档就是设计的蓝图啊!横向对比其他团队项目,在文档中投入的精力越多,整个团队项目的配合就越好,最终在"市场"上的赢面就越大。
起初为了做好项目经理,仔细翻阅了第9章的内容。完整地体验过项目的两轮迭代后,书中提到的“PM和风险管理”一节引起了我深深的共鸣。风险是一定会有的,如何缓和、预估甚至是将风险转换为机遇,在书中都有具体例子佐证。项目经理就是那划船的舵手,虽然他不“赤膊上阵”,但他是团队节奏的核心。是一盘散沙还是一只拳头?PM是关键。
构建之法跟代码大全的结构很像,每一章都是独立的子章节,并且涵盖了测试、项目经理、开发人员、用户体验等多个方面。个人来说比较喜欢这种风格,可以在合适的时候随时温习自己想看的一部分。即使本书涵盖软件工程很多领域,但每一章都值得精读,配合实际项目中的实际角色扮演效果更佳。
相比其他章节而言,个人最喜欢9、10、17章。同时,每个章节最后的练习与讨论是一堂丰富的扩展课,有非常好的资源。【唯一略感缺憾的是实体书每章最后所附的链接略显多余。如果可以按照较好的排版,将参考链接单独取出,排版好置于统一的网页上,再给出一个总链接,那样更方便读者浏览:)】。另外,如果能针对每一次的讨论和练习,让大家在网上有一个专门讨论探讨的地方是不是更好呢?
总而言之,构建之法是一本产生于实践(邹老师的多年工程经验与教学方式的结合)并应用于实践(结合书上课的人都会有很多的软工实践)的书,比现在很多只讲框架不讲细节,只讲理论的软件工程理论书棒得多。可作床头书常读,常读常收获 :) 期待第三版!
《构建之法(第二版)》读后感(六):简评《构建之法》
首先,这是一本全景式图书,会让你更了解这个行业,能让毕业生在对行业从陌生到熟悉的过程中,较少地感到惊讶和出乎意料,这是一本与现实接轨的教材。
其次,这是一本最佳实践式的书,涵盖了科学、健康的软件工程开展中的每个方面,介绍了种种方法论,但不是高高在上、纲领性的方法论,而是方法论的最佳实践,确实可用,拿来就用。
第三,这本书让人有情怀,学生对“古老的”瀑布教材或“舶来的”敏捷书籍,难免会缺乏信心:这东西行吗?适用于现代吗?适用于中国吗?而如果到各大论坛、社区、或者询问“过来人”,往往会收获更多的负面信息,让本来有情怀的学生失望,让本来就缺乏情怀的学生甘心。但很明显我们这个行业需要的是更有情怀的人才、更好的职业道德和素养,如果学生在毕业前就俯首认输,行业还有什么希望可言?邹欣老师的教材会让学生知道“应该如此”而且“可以如此”,从这点上看,功德无量。
第四,这本书在介绍方法论的同时,居然会介绍方法论不适用的场景,介绍方法论在现实中是怎样跑偏的,这就好像讲下棋,“这样走,之后的发展会怎样怎样,所以不行”,怎样做会对,怎样做会错——什么叫宏观视角?什么叫最佳实践?什么叫算无遗策?就像画一棵决策树,向哪个分支走,结果会怎么样,清清楚楚,明明白白,让人信服。
第五,这本书在介绍方法论的时候,并没有把“人”放到“方法论”的下层,而是介绍了种种角色、有血有肉有情绪的人,能让学生了解到工作中接触的种种角色及其想法、诉求,避免“以程序为中心”思考问题,而懂得以人为中心来思考,毕竟程序要解决的,是人的事情。这个思想的转变,对程序员来说,至关重要。
这本书涵盖了现代软件工程的全部,每个章节甚至每个段落拿出来,都可以在实践中作为指导。
这是一本浓缩了无数精华的好书,搞软件的应该人手一册,就像每个兵家必备一本《孙子兵法》一样。
《构建之法(第二版)》读后感(七):具体而微
--构建之法随笔,范飞龙,TL;DR,原文在知乎首发:具体而微
年前计划过要重读《构建之法》这本软件工程的书,于是就花了两个晚上重读了一遍,写下这篇随笔记录下一些横向的思考。从理解的便利性上考虑,涉及到专业术语的地方会做适当的简要说明。
把目录列出来,根据自己的理解做分类,便于按图索骥。《构建之法》第2版全书一共17章,涵盖了软件开发中的各个方面,这些章节在我看来是一个阶梯式的格局,概述的内容主要理清软件工程学科的内涵外延、提出一些针对全书而言是基石的模型和概念。而针对其他章节,按我的理解可以大致拆分如下:
个人部分:
2.个人技术和流程
3.软件工程师的成长
结对部分:
4.两人合作
团队部分:
5.团队和流程
6.敏捷流程
7.MSF
软件开发完整环节部分:
8.需求分析
9.项目经理
10.典型用户和场景
11.软件设计和实现
12.用户体验
13.软件测试
14.质量保证
15.稳定和发布阶段
创新和小队管理部分:
16.IT行业的创新
17.人、绩效和职业道德
后文涉及内容大都从这些章节中延伸出来。
我发现,重新读一遍,又再次看到许多漏掉的片段。我是一个程序员,我知道再复杂的代码,如果是自己写的,那么想要找到一处具体的细节都是相对容易的;而如果不是自己写的,读别人的代码是需要很多技巧和投入许多精力去深挖才能做到同样的了如指掌,正如市面上诸多的源码剖析书籍所展现的一样。
《构建之法》正是软件工程领域的这样一本看似复杂的书,我想书中所展现的从个人软件开发技能、结对编程到团队开发;从需求分析、用户画像、设计实现到用户体验;从测试和QA到稳定和发布;从“创新的迷思”到绩效的理性分析以至于职业道德的拆解;这些软件工程环环相扣的组合拳,作者是最熟练理解和运用的。而我们读者,则可以顺着书中所强调的做中学的理念在阅读、思考和实践中去做深入的挖掘。而基本目标,从狭义上来说,正如书中开篇所提,理解和掌握软件工程的知识和方法,并做出有实际用户的软件,通过文档和代码展示了软件的可持续开发的价值。这是一个具体明确的小目标,看上去似乎并不大,但这正是重要的,如果我们能把第一个小目标做好,再迭代100次,可能比我们做了100次雷同的事情结果要好。
软件开发中存在各种隐喻,例如《程序员修炼之道--从小工到专家》这本书,就提到各种隐喻。有:“提供选择,不要找各种蹩脚的借口”,“不要容忍破窗户”(破窗效应),“做变化的催化剂”...等等,这样的书籍有利于我们在欣赏隐喻的过程中提高我们的段位,然而我们人是容易忘记的,100个隐喻我们能记住3条常用的并运用到极致就非常不错了,缺失的地方在哪里呢?我们也读过《重构--改善既有代码的设计》,也认真阅读和实践《Clean Code》的理念,设计模式从套路的学习到抛弃,编码规范的排斥到遵守到入乡随俗,语言书籍从Primer,到Advance到The Good Parts。这些,都是重要的组成部分,然而它们远不是全部。
我们要看到大地图!看到大地图是一个正常的逻辑,但又不正常。程序员有时会过于陷入细节而太Geek,我们的成长经历就是不断地在自己的细节迷思与大地图需求之间博弈的过程。这一切的根源,在于: 软件=程序+软件工程,我是在构建之法这本书里第一次明确地看到这样一个公式,这是重要的,我们有了一个地图。而更大的地图是:软件公司=软件+商业模式,也在这本书里第一次看到。理解了大地图,可以把那些碎片的部分放在合适的位置,例如哪些是软件工程师个人成长的部分?哪些是与人协作的部分?哪些是与团队协作的部分?哪些强调了技术制胜的策略,哪些又强调了流程的必要,哪些强调了人剑合一的高效,哪些又说明了分工的必然和规律性。确实,许多时候一个人手里有一把锤子,看什么都是钉子,而这并没错,只是我们不断地在寻找更合适的锤子而已。当然,有的高手不强调全面,只强调特色锤子。只是,我们看到的时候要理解那不并不是全部,甚至只是一小点。
小节注释:
“迷思”一词起源于希腊语单词μθο(mythos),是英语单词Myth的音译,又意译为神话、幻想、故事、虚构的人或事,指通过口口相传流传于世的十分古老的传说和故事,泛指人类无法以科学方法验证的领域或现象,强调其非科学、属幻想的,无法结合现实的主观价值,《构建之法》第16章:IT行业里的创新 第一节讨论创新的迷思。有一辆火车行驶在苏格兰的土地上。上面有一个天文学家,一个物理学家。当然还有一个数学家。这时,天文学家突然看到苏格兰的草地上有一只黑羊在吃草。他大叫:看呀,苏格兰的羊是黑的!物理学家说,“不对,你应该说,在苏格兰,有一只黑色的羊”。这时,数学家笑了笑说,“你们这么说都不合适。应该说:在苏格兰,至少存在这么一只羊,它的一侧是黑色的”。这个故事说的是逻辑。
为什么我要提到逻辑呢?因为从工作开始,我们就开始了与队友协作,在团队中协作,在软件开发工作中,同时伴随的就是对于小组、团队、组织、流程、产品、开发、测试等等的各种迷思。有时候,我们会听到一些似是而非的关于个人在这些不同群组、不同流程里的定位的观点和看法,例如常见的开发和产品、开发和测试、个人与团队的各种矛盾的关系,还有诸如“我有一个想法,就差一个程序员”,“你这是事后诸葛亮,马后炮”等等,网络上也常见各路高手从一个角度写的文章,大家都在强调自己认可的那方面理念,有的人几十年如一日专注于编程语言,有的人一路偏好通过程序解决问题,有的人反复尝试各种产品套路,有的人强调精英在高效团队中的作用,有的人强调良好战术的重要,有的人认为年龄是技术的制约,有的人则认为年龄代表技术的沉淀,而路人粉丝们总是冲到下面一路点赞或者反对。
好的方法一定是符合逻辑的,这是我看过王鼎钧《讲理》这本书的感受。讲理,学习的不只是写论说文的各个侧面,更是学习如何看别人的文章的文法,一个文章,立了是非标题,我们就要它给出靠谱的证据,如果有好的故事,可以感受故事的吸引力和比喻之妙,但也要明白故事毕竟只是故事,并不是证据,所谓充分不必要。如果用了诗句和子曰,我们就要问权威是否真的说过以及权威是否过时了。如果有反问,我们也要判断反问的主体是事实还是判断,区分事实和判断,我们才能做情绪的主人。如果有倒彩,看其是否轻薄,毕竟倒彩也是充分非必要。欣赏是非标题下的写景,明知它是铺垫和吸引,如此才能正经欣赏文字的同时不失理性。
而《构建之法》这本书在讲理方面很合逻辑。首先,在很多环节里,作者都注重集合的使用,例如,在讨论“两人合作”的时候,对评论人的层次的分类:{行为和后果,习惯和动机,本质和固有属性};在“需求分析”里对需求做分类:{必要需求,辅助需求},对功能分类:{杀手功能,外围功能};在“人、绩效和职业道德”里分析团队成员在做事方面投入的分类:P={P1:做事的,P2:不做事的,P3:不让别人做事的,P4:做假事的,P5:假装做事的};在“软件设计与实现”中“开发阶段的日常管理”里对BUG的分类:{已修复的BUG,不能重现的BUG,这个产品就是这样设计的不是BUG,不是BUG没有能力修复将来也不打算修复,这个BUG的确应该修复但是没有资源在这个版本修复推到下一个版本}...,我们看到在软件工程中处处体现着分类的作用。
在分类之后,可以使用优先级排序,例如对任务的优先级,可以使用坐标分析法等等,这就给软件工程上处理人与人、处理流程带来了理性分析的地方。例如我们对功能和需求两个维度建立四象坐标系之后,我们可以针对不同的象限采取不同的策略;再比如根据任务的{重要,不重要}和{紧急,不紧急}两种维度,我们可以有节奏有先后做事。此外,作者设计了许多独特的情景对话,通过虚拟软件公司的人物对话之间的断言、质疑、释疑,将方法和知识徐徐展开。这需要读者对应地慢读,因为慢读之下,我们会发现对话的逻辑性,而一旦逻辑的主线出来,实践上应该怎样更合理,便自然分明。
我们在实际工作中由于分工的原因,以及每个具体工作所需卷入精力的原因,许多工程师会觉的自己所做的工作是单一,具体和明确的,并不需要那么多复杂的框框条条。正如许多人看过软件工程的理论,常见的感想是:“这些不错,但是离我的工作好像有点远”。另外一种类型是一些高手说:“这些都是套路,我们并不希望把日常工作的流程搞成这样”。这也是一个常见的迷思,即有效的流程是必要的,但流于形式和无效率的流程则是一种对人和事的不必要约束。
实际上我能理解这两种回复的合理性。一方面,在许多公司里程序员的分工是必要的,有时我们会几个月甚至一两年专注于特定领域的程序开发工作。小公司和大公司对开发周期的需求也不同,几个人的团队和几十人的团队也不同。有的人会认为那些全局性的工程方法不是我的事情。另一方面,许多高手都是经验主义的精英。经验与直觉足以让他们有自己的一套方式和方法去构建。
正如那个“苏格兰草地上的一侧黑羊”。软件开发的团队模式有不同的模式,正如书中“团队与流程”一章对软件开发团队模式的分类,有主治医师模式,有明星模式,甚至有交响乐模式,还有新手的一窝蜂模式等等,成员的素质高低会导致各种模式都有成功或失败的可能性。成功了,就会形成一种经验主义和选择偏好。而,任何一种偏好,都是一种偏见。因此,会有许多人排斥流程、排斥分工、排斥管理,而选择交由高素质成员的自发组织、自发协作、自发管理以及通过洞察力得到的设计来取得过程的成功。
我在这点上也思考了许多。软件工程的许多方法形式在逻辑上并不明显具有充分必要性,否则,只要大家照着这种形式去做,岂非一定能够成功?项目的成功,在构建之法1.2节讨论不同类型项目时有不同的定义,但殊途同归,最重要的是“Build To Win:以在市场上赢得用户为目标而构建的软件”。但这个问题在所有强调方法的地方都会适用,例如在火热的育儿界,我们有什么方法是万能的吗?没有。软件工程界更是如此,《人月神话》这本讲述IBM公司System 360家族和OS 360中项目管理经验的书中,作者Brooks提出了“没有银弹”这个概念,这也被许多软件工程师经常挂在嘴边,所谓的没有银弹是指没有任何一项技术或方法可以能让软件工程的生产力在十年内提高十倍。
但没有银弹并不是说那些方法毫无用处,没有银弹在我理解指代的是每个方法和技术都有其局限,每个方法都有其适用的假设条件。在理解了方法的下限之后,我们再针对一个一个具体环节,一个一个具体方法功能上的讨论、理解和使用,这是具体和重要的。而这也是工程角度擅长的,我们希望解决问题,那就要有可操作的解决问题的招数。有招数至少比一窝蜂模式强,有效利用招数又比流于形式的招数强,理解招数的内涵则是拾级而上的进阶。《构建之法》正是在那些看似技止于尔的地方,针对环节和招数的上限和下限做了足够好的分析、说理、比喻、举例、聚焦和发散。单一的方法和工具有上限和下限,从而我们更需要有章法的去做好组合,让方法、工具、人在约束条件下达到最优,为构建赢得市场的软件服务,而这些都是具体而微小的。
形式做的爽了,有可能会流于形式。这就切中了另一个重要的问题,招数是为解决问题服务的,而解决问题的核心是人。所以,前提是人的动机是有效解决问题,做出好的东西。理解这点,可以重点阅读MSF(Microsoft Solution Framework)这一章,MSF有一个9点的基本原则,其中我最喜欢的有:
● 为共同的远景而工作
● 充分授权和信任
● 各司其职,为项目共同负责
为什么单独挑出这三点呢?因为这和此处讨论的形式有关。形式是死的,人是活的。当人的主观意愿是为了解决问题,人去理解形式的优缺点,能做到扬长避短,让形式发挥其适当的作用,那么形式就和内涵是契合的,此时我认为是最佳的。反之,如果形式和内涵相违背,那么,形式的作用会打折扣,或者起的是负面作用。
招数的使用上,也有新手和老手之分,这就需要反复的练习,也就是唯手熟尔。还有一个重要的点在于善于使用工具。例如,下面这些招数都属于需要反复练习的:
● 做需求分析和立项的NABCD(Need,Approach,Benefit,Competitors,Delivery)。
● 做任务分解的WSB(Work Structural BreakDown),配合思维导图。
● 做尸体解剖的事后诸葛亮分析(Postmortem),马后炮其实是有用的。
先定一个小目标,设置一个里程碑,然后持续迭代,在里程碑结束后进入下一个里程碑。构建之法书中体现了这个重要的过程,特别是“敏捷流程”的内涵。年初和年末的时候,我们常常会看到很多人为自己设定了很长的todo list(当然更多的人是走一步看一步的随缘流派),而往往许多todo list最后变成了undo list。究其原因,一个重要的原因在于目标定的不具体,或者说不符合SMART原则,因此会不敢下手。这是说个人,而在团队上,则会体现在里程碑周期的控制失效上。
越是大的目标,越容易做不到,越是长的周期越容易延期和失控。这也是所谓保持敏捷,预期和适应变化。通过设置可操作性强的小目标,通过设置短周期的里程碑。我们可以上来就上手做,短平快的要么成功要么失败。成功我们就有更多的信心增量改进,失败则给出必要的改进反馈。
增量的一个前提是完整执行大地图上的所有环节,每个环节都要做到位。具体环节如果不做到位,那么它的质量就下降,环节的质量下降,会导致整体质量的下降,到最后事后诸葛亮分析起来,有的人会说是形式和流程害了他们。回顾下公式:软件的质量=程序的质量+软件工程的质量。
构建之法的章节布局是按个人、结对、团队(团队的内部由通过介绍瀑布、讨论敏捷,到MSF的柔和)的模式来的,环节大致是按软件开发的生命周期。这个线性模式本身似乎是显然的,但我观察有许多人实际上并没有有效建立起这种增量的模式。比如可能在个人上投入太多,或者因为结对的不显性而忽略之,又或者在团队上只是粗糙使用瀑布或者不重视敏捷的内涵。我想把理论消化掉的过程,都属于构建之法开篇提到的大马哈鱼巡回游的模型,这个模型用来比喻软件工程师进入软件公司从改BUG、维护一些小模块…,绕了一圈到成为骨干后才能独立设计新项目的过程,事实上我们从事任何一项行业,都有这种类似的过程。
小节注释:
Alpha:指集成了主要功能的第一个试用版本。在这个版本中有些小功能并未实现。事实上很多软件的Alpha版本只是在内部使用。Beta:功能基本完备,稳定性较Alpha版本高,用户可以有Beta1,Beta2,Beta3…--《构建之法》第15章“稳定和发布阶段”《构建之法》有单独的两章分别介绍“瀑布模式”和“敏捷流程”(Agile),其中瀑布模式狭义上指按部就班执行需求分析、设计、实现、测试、发布的流程,瀑布模型衍生出了一些变种模型,例如让相邻两个环节更加紧密的“生鱼片模型”。
而敏捷流程强调短周期的里程碑,每个里程碑开始都把要解决的问题拆分成一个个卡片,一个里程碑叫做一个敏捷冲刺过程。形式上,每日会有一个站立会议简单碰一下前一天完成的任务,遇到的问题以及当天要做的事情等,完成任务和解决问题中的重要步骤要及时有序小结。在敏捷冲刺期间,组队的(叫做敏捷大师)要适当拒绝不在计划内的任务,保证本次队列的完成度。在里程碑开始的时候,以图形化的方式展现了剩余的工作量(y轴)与时间(x轴)的关系,形成一个工作量随着时间消逝的“燃尽图”曲线,而在实际开发过程中记录真实的完成情况,实际的曲线和预期的曲线之间的差距即可以衡量估计的准确度,也可以衡量整体的进度。
构建之法里也提到戴明环,或者叫PDCA循环,又叫质量环,是管理学中的一个通用模型,最早由休哈特于1930年构想,后来被美国质量管理专家戴明博士在1950年再度挖掘出来,PDCA是英语单词Plan(计划)、Do(执行)、Check(检查)和Action(纠正)的第一个字母的缩写。
这三种模式都强调检查的作用。有时和一些中小学老师交流,意识到在软件开发中貌似新鲜的所谓单元测试,其实我们从小到大在学校里的考试都是这样做的,从每周的单元测试到期中期末的里程碑测试。有效的知识学习和使用,都伴随着测试的过程。而结果也是明显的,并非每个走过这套流程的效果都一样。究其原因,还是质量。
以中学生为例,一次单元测试,大部分人只看结果加上老师的讲解了事,在这个过程中,存在的一种现象是对已经做对的不再重视,而对做错的只是了解下表面原因就丢弃。这样实在可惜,那么应该需要的是什么呢?复审。有效的学习也总是伴随着复审,通过复审,我们深入去理解测试所表征出来的问题背后的原因,把可重复操作的1,2,3步骤写下来。软件工程理论上也是重视复审的,但实际上我们总是好了伤疤忘了疼。说到这里,我所理解的构建之法里体现出的那种强调具体的事情要做到位的意识,是值得重视的。实际上,复审是一个再普通不过的方法,但人是惰性的,我们在生活、工作中有太多时候随随便便就放弃了改进的机会,只因为我们随随便便做了复审,比如说团队的Leader认真写了复审的邮件,但成员可能只是收过来回复已阅,并未付出同等深入的思考。
回到软件工程,短周期的里程碑结束,我们需要具体科学地去做事后诸葛亮分析,并在下一个里程碑里跟踪增量改进。有检查和没检查是两个效果,这需要协作者在意识上重视并参与,参与就表征这事我有份,我检查了它并改进了它,是构建者而不仅仅是阅读者。
我们几乎总是估计失败。但我们还是要估计,让粗略估计逐渐变的准确。所有写过迭代算法的人,应该对预估-矫正的做法不陌生。在个人软件开发中使用PSP(Personal software process)对分析、设计、实现、测试的时间做估计并事后统计;在团队开发中PM(Project Manager, Product Manager 或者 Programmer Manager)对各种风险做分类估计并采用分类应对策略。这都需要反复的通过预估-矫正机制去锻炼我们的粗略估计能力,这样我们才能更好的拥抱敏捷,预期变化(不是期望)。
正如构建之法写到的:
“一个成熟的软件工程师应该能够降低任务交付时间的标准方差。如果你能长时间稳定而按时地交付工作的结果,内部和外部的顾客就会对你的工作有信心,更喜欢与你合作。”构建之法里还提到了一个估计时间的经验公式:
实际时间花费主要取决于两个因素,对某件事的估计时间X,以及他做过类似开发工作的次数N,则实际耗时大概是:Y=X±X÷N有敏锐意识的工程师,应该对延迟敏感,捕捉软件开发中的关键延迟点,并采取有效手段规避。然而这并非易事,一个人在某件事情上很有经验,估计比较准确,当他去做另一件事的时候,并不能轻易地迁移在之前那件事上的经验,从而达到同样的估计准确度。迁移并非不可能,如果上面的估计公式是有效的,我们可以反复在做一件新事情时尝试利用已有的经验去估计和逼近,当N足够多的时候,Y就会足够准确。问题是,我们是否有足够的自律去训练自己的估计能力?
源代码需要版本化管理。构建之法强调做中学,在软件开发过程中,一个最直接的工具就是版本管理工具。时下最流行的版本管理工具就是git,在git的使用上,有各种工具可以选择,有的人选择纯命令行工具,有的人选择各种平台上的GUI工具。到底哪种更好呢?我想用构建之法里的一段话来表达我的看法:
“那怎么提高技能呢?答案很简单,通过不断的练习,把那些低层次的问题都解决了,变成不用经过大脑的自动操作,然后才有时间和脑力来解决较高层次的问题。”版本管理工具是软件工程师日常开发天天使用的,工程师要做到日常开发的添加、提交、同步、以及项目版本上的分支管理和维护。一个流畅开发的团队应该把它作为一个低层次问题,通过练习达到不用经过大脑的自动操作,这样团队才会聚焦在较高层次的任务达成和问题解决上。
当然,任何事情都有一定的代价,也并非任何一个看似“低层”的问题都是人人都能做到熟练的。这又体现了我们要从小的事情做起,通过一个又一个小问题的解决,从而在整体上拉开好坏优劣的差距的必要。有时候,道理是明显的,差别还只是在行动上。
工具提供的灵活性,有时候是一把双刃剑。例如像Git这样的版本工具,在分支管理策略选择上的不同有时就会对团队开发的效率产生不同的影响。
例如常见的Github 协作工作流:Understanding the GitHub Flow,
以及常见的Git工作流:A successful Git branching model
而在Software Enginerring At Google这篇文章中,我们会看到Google的工程师倾向于选择尽量减少分支来规避潜在的合并问题:
“Almost all development occurs at the “head” of the repository , not on branches. This helps identify integration problems early and minimizes the amount of merging work needed. It also makes it much easier and faster to push out security fixes.”版本管理里面还有一个常见的问题是,多久提交一次,什么时候提交,对于这个问题,下面的这篇文章光看标题就能给人启发:
Commit Often, Perfect Later, Publish Once: Git Best Practices
构建之法里有一个魔方的故事,具体的故事细节此处不展开,可以看这里:技能的反面-魔方和模仿。通过魔方的故事,我们可以看到围绕玩魔方和卖魔方这件事上,就有不同的进阶版本,我想软件工程技能与内涵的学习和理解上,也存在不同的版本。
Keep Balance! 这又是一个说起来容易,做起来需要技巧的事情。事物总是非线性的,但我们思考的时候却总是容易幼稚地以线性的眼光去看待。最简单的非线性模型,我认为是这样一个公式:Y=X*(1-X)。我们要求得这样一个公式的极值点,需要的是寻找X的最佳平衡点。放在软件工程里,取代线性思考方式的,是这样的一些事情:
例如,一个团队建立,团队成员和团队Leader之间就有这样一种双向视角:
● 如果你是组员,你是否在理解自身职责的基础上理解Leader的职责
● 如果你是Leader,你是否在理解自身职责的基础上理解组员的职责
例如,团队确立共同的目标,建立充分授权和信任的意识,同样存在双向视角:
● 如果你是组员,你理解团队的目标和个人的目标之间的差异么,怎样取得共识?
● 如果你是组长,你理解团队的目标和每个组员目标之间的差异么,怎样最大化共识?
● 如果你是组员,你会在理解了共识的基础上和组长及其他组员充分信任么?
● 如果你是组长,你会在理解了共识的基础上和每个组员建立充分信任么?
● 如果你是组长,你理解每个人内心真正的意愿并充分授权和分解任务么?
例如,在考虑绩效的时候,不同的人理解的不同:
● 如果你是组员,你理解贡献分平均分配和非平均分配的区别么?绩效的目的是什么?
● 如果你是组长,你理解贡献分平均分配和非平均分配的区别么?绩效的目的是什么?
例如,在做一个涉及他人的改动时,不同权责需要采用不同的模式:
● 请求模式:你好,我能改动这个么?
● 通知模式:xxx,我改了这个,你要更新下。
每个人的精力都是有限的,当我们把精力投入在一个方面,必然会在另一个方面吃紧。《构建之法》里有一个对成员在团队里投入程度不同的刻画:猪、鸡和鹦鹉
“一个人可以同时做很多事, 这些事情对每个人的轻重缓急各不相同, 有些事情只能业余帮一些忙, 这无可厚非。 加入一个团队时要弄清楚自己在团队中投入的级别是什么, 别人的期望值是什么. 不要拿着卖白菜的钱, 操那卖白粉的心 - 太不值得。 人可以在 n 个地方做鸡, 或者 n*m 个地方做鹦鹉, 但不可能在两个地方同时做猪, 这太难了!”在管理学里面有一个典型的模型是唐僧师徒四人,每个人也都代表不同投入、技能、贡献度的角色,常常会提的一个问题是:如果徒弟三人只留一个人,你会留谁?当然这是极度简化的模型,事实上每个角色都会有不只一个人。
在角色之间,常常会有情绪卷入问题。特别是一个角色在做一件事的过程中,被需要修复的BUG、紧急添加的Feature、临时乱入的会议等等打断的时候,被打断往往会导致情绪上的对抗,内在的原因可能是预期的结果和实际结果不一致导致的,这也是需要平衡的地方。
对于个人来说,平衡自己在不同角色上的付出,同时理解其他角色的付出,调度自己的多角色,在许多时候需要良好的角色管理意识。
计算机的一大类问题就是输入输出问题,根据能处理的输入数据的规模大小,程序设计和实现会有不同的策略。是否一开始就要考虑规模比较大的数据处理?未必。从能处理小规模数据的程序开始迭代,在迭代中让程序逐步能解决和处理更大规模的数据。这是一个开发策略上的伸缩性问题。
在软件的功能设计中,也会有伸缩性问题:
● 基本功能
● 扩展功能
● 高级功能
而在软件工程师个人的成长方面,也有伸缩性问题,软件工程师在成长中一开始会投入很大心力在程序这一端,例如编程语言的学习,算法的学习,设计模式的学习,抽象和复用方面的学习,调试能力的学习,构架的学习。进而在成长中会考虑与单人协作的方式,与多人协作的方式。在任务数上会从同时处理一件事到同时处理N件事。这个过程中,逐渐必须解新的问题:问题规模变大了,原来的处理方式是否还能流畅运行?有的时候会遇见各种危机,每次危机都同时是一次机遇。
同样在Google 工程师写的这篇文章:Software Enginerring At Google 里,Google工程师在Code Review这件事上的做法包括: 一个模块由至少2-3个人共同负责,模块代码改动后会发给模块拥有者或者非模块拥有者做Code Review,每个人也可以主动去给别人的模块做Code Review。那么一个显然的问题是如果Code Review做的很慢,岂不是整体进度会被减缓?此处文章里推荐的做法是简单的小的改动可以发给相对较少的能力要求不是那么高的成员,复杂的大的改动则可以发给经验丰富的效率高的成员做Review,也或者你可以同时发给N个人,只要有些人比较快的回复review即可,…,方法是很多的,比较特别的是这里体现出的对问题规模变动引起的复杂性的认识和应对策略。
在问题的输入规模变大(输入有可能是需求)的时候,问题开始变的繁杂,所以我们需要适应繁杂问题的工程方法。如果把问题的规模变大作为一种变化,我们就应该预期规模的变大,在需求分析、构架设计、实现上及时响应可能的变化。
许多年前,我就听到一种说法:“完整的看完一本书比看了10本没都没看完重要”,这让我想起了最后一里路的问题。工程师常常在完成“80%”之后,就放松下来,以为完成了一切。而实际上最后20%的事情要做完整,有时在时间上要耗去整体的80%。最后的20%这个尾巴的部分,体现的是后劲、耐力以及对事物完整性的认识。
但是,另外一种观点是:只有20%是重要的,其他80%都不是重点。也就是俗称的二八原则。二八原则在挑重点方面是重要的,在工具的使用中也是重要的。如果你是用户,你会优先关注那20%最重要的部分。但是,如果你是个构建者,也许最核心的设计就20%,但是要把软件完整迭代出来,则需要关注那80%在设计上也许不是核心,但在实现上是必要的部分上。《构建之法》强调一个重要的目标:做有人用的软件,比如从10个真实的用户开始。从这10个真实用户里通过洞察和科学分析提取出真实需求,通过有效的设计解决用户的痛点,比别人家做的更好或者颠覆别人家,把足够好的软件做出来,并递到真实用户手里。在这样一个过程中,去关注每个环节的尾巴部分,把被忽视的20%尾巴做到位,这是竞争力的一部分,有时,也会是创新的一种路径。
许多软件工程的学生,在实践做中学的过程中,就会在这点上做的不足,这可能是由于学生项目带有“作业截止日期”到了就完了的原因。但“软件开发不是闭卷考”,真实的软件开发,关注那20%的尾巴,每个环节的尾巴收集起来,做完整,是重要的一环。
《社会心理学精要》这本书里谈到人在社会中,基于个体内在和外在,个体私下和公开;个体为中心还是群体为中心,内群和外群;个体的积极和消极、刷脸与被刷脸,等等这些方面都存在着复杂的多还少补式的调节与反馈作用,核心目标是维护个体的自尊、安全、稳定可预期的社会自我定位。
我们掌握工程的方法要通过在实践中设定优化目标,在反复的实践中消化和建构知识、方法。特别是软件工程这样一门实践性很强的学科。实践有两种:一种是在工作环境中反复运用所学,另一种是将自己所掌握和理解的知识和方法用以分析别人的案例。
这两种方式我都有实践。第一种自然不用说,在工作中我会逐渐去对比自己所在环境下对应那些概念、逻辑的日常事件。这是一个过程性的体验,将虚化的名词、概念跟日常工作的小事件建立连接、印证、改进是做中学的一种方式。第二种,我在过去两年里实际的参与过《构建之法》线上线下结合的教学里的线上助教/评论环节。实际上有更多的工程师在业余时间做这件事。这种方式中,通过参与大量学生软件工程教学环节的评论,评分和建议分析,我们不但巩固自身的知识和方法,也让学校的学生和比他们水平高(也有可能反过来)的经验丰富的软件工程师之间建立一种近距离互动式学习环境,教师也在这个过程中协作推动课程设计的立体化。
回到主题,掌握和理解原理,在自己的领地里运用软件工程的知识和方法做出一流的软件,持续去优化这个目标。当然,你的产品未必是软件。
《构建之法(第二版)》读后感(八):软件起于代码,而不止于代码
作为一名软件工程专业的学生,软件工程是本专业的核心,但是当时分发的教材经常翻着翻着就发困了。不过这次有幸在我们老师的推荐下能够读到邹欣老师的《构建之法》,实在是欣喜不已。
相信对于很多人来说,一听到别人学习计算机专业或者软件工程等有关计算类的专业,第一直觉是“哦,程序员啊,我懂你们这行啊,就是敲代码。。。”如果听到这种说法,那么你应该庆幸你遇到的还是比较懂这行的人。要不更多情况下你会听到,“呀,学计算机的啊,给我们家看看电脑,为什么我们家电脑老是。。。”接着你要解释半天,可能你也会被绕进去。那么究竟什么是软件工程呢?或者说我们要怎么要怎么理解这个专业呢?这就进入了主题《构建之法》。
初次接触邹欣老师的《构建之法》也是被起被其书特有的幽默风趣所吸引。它不同于其它的专业书一样,枯燥无趣深奥。反而是采用对话、举例等形式展现,像书上用来阿超、小飞等人物风趣幽默的对话打破了传统计算类讲解书的单调。这样一本书适合于各水平的人阅读观看,可以学习到软件工程的
方方面面,结合自己,查缺补漏。本书共有十七个章节,从基本的概论讲起到开发管理创新等等。以我本身来讲吧,我也是一名软件工程的学生,敲代码那是家常便饭,团队合作交流也必不可少,比如一项简单的课堂设计一般也是一小组合作完成,就像书上讲的一样很难这样的合作往往很难做到1+1>2的效果,甚至面临1+0+0+0……=1的效果。
这样的局面造成因素是方方面面的。看完整本本后,给我最大的感受就是构建之法超越软件而不止于代码。也就是说软件工程不是我们常理解的只是敲代码而已。书中也举例了一些团队合作的的案例,相信你不难发现管理等也是其中不可或缺的因素。要创造1+1>2的效果不止要技术推进还有管理推动,那么所谓的管理不单单是管理者的事了,团队中的每一个人都应参与其中,每个成员都应有义务。书中也特别案例,可以精读以便自己在今后的工作中出现类似问题便于解决,更能举一反三。
当然书中涉及到技能方面对学习该知识的学生有一定的指导作用。就其书没有通篇枯燥的技术讲解来说,会很容易就能理解软件、软件工程、单元测试、软件开发流程等等的知识。
通本书读下来,从事软件行业要在拥有写代码能力上还要有管理能力、分析程序性能、bug和测试等等。我想软件起于代码,而不止于代码。
像小时候学习的课文画杨桃一样,不同角度看到的也就不同,可能画出的事杨桃全景,又或者是五角星。程序员可以找到技能提升和职业进阶的宝典,非专业人员更能理解该专业和找到管理的方法……总而言之,《构建之法》是一本值得一品的书。