0%

程序之美系列

  • 团队之美
  • 项目管理之美
  • 架构之美
  • 数据之美
  • 测试之美
  • 安全之美

团队之美

任何一个稍具规模的项目都不是一个人能够完成的。我们看到的也许是一两个明星,但是他们背后必定会有一个团队的支持,体现的是集体的智慧。毫无疑问,人员和团队是使项目成功的最重要因素。作为员工,他们希望有成长的空间;作为项目,它们需要满足客户的需求。如何打造一个卓有成效的团队,让员工与项目和企业一起成长?这是任何一位领导或项目经理都无法回避的问题。团队成员在一起工作的方式是什么?什么样的团队可以称之为美?如何处理项目过程中的重重障碍?项目取得成功的因素是什么?或者说,项目为什么会失败?

领导力

丑陋团队的获胜之道

构建视频游戏

打造完美团队

激发开发人员的因素

激励队员

将音乐带向21世纪

我很孤单,渴望找一些人聊聊计算机。

内部开源

真正成功的开源项目通常有三个层次截然不同的文档。在不同的时候,开源项目中的人们叫这些文档的名字不同,或者组织方式不同,但是通常有三个截然不同的层次。第一个是README:项目是干什么的,谁参与了项目。第二个层次是如何使用:如何安装,运行时的依赖是什么样的。文档中不会事无巨细什么都记,而是会说:“通常可以按下列方式入手使用。”第三个层次是贡献者信息:人们应该如何自己构建新版本的软件,需要哪些依赖,如何做贡献等。注意这符合社区中三种完全不同的人:用户、项目贡献者、代码提交者。README帮人们决定是否要成为用户,安装信息帮人们成为用户,而贡献者信息可以让一个用户成为贡献者。

在与团队一起工作时,团队目标不一致是可能出现的最糟糕的错误。然而遗憾的是,这种现象比我们意识到的情况要严重得多。这种现象本来不应当让人感到特别吃惊。随便打开一本软件工程的大学教科书,可能都会看到类似这样的图表:缺陷发现得越晚,修复成本就越高,并且成本呈指数级增长。但是大多数经验丰富的程序员都不需要从教科书上去了解这些数据——他们在实际工作中基本上都看到过这种情况。

创建团队文化

制定计划

公众利益斗士攻占邪恶之城

保卫自由世界

拯救生命

改变团队的文化可能非常危险,这一点不必怀疑。实际上,不仅仅是文化会受到影响,改变甚至会威胁到团队自身的存在。在尝试使用新实践的时候,团队会面临两个主要风险。一个风险是实践本身可能没有价值,而推动这个实践的人对此一无所知。毫无用处的进度报告会议就是一个最广为人知的例子,这个实践没有任何益处,可团队还得忍受它的存在。但并不是说所有的进度报告会议都没有意义。(从运转良好的Scrum团队中随便找个人问问,他们会告诉你他们如何举行有效的会议!)不过有些进度报告会议肯定是毫无用处的,一般来说,开这样的会仅仅是为了让项目经理或公司高层了解进展情况。团队中所有人都坐在桌子旁边,每个人都等着发言(不是自己发言的时候,他们通常都在查看邮件)。轮到某个团队成员发言时,他就会总结上一周自己完成的工作。人们并不清楚这样的信息是否在某个地方有记录,但通常仅仅是为了满足某个资深管理人员的自我需要才开这样的会议。没有人在听别人说什么,整个会议每周都会耗费团队几个小时的时间,而且毫无任何有效产出。

一旦人们学着阅读测试,测试就会成为非常有效的详细文档。它们不像那些文字写成的文档,还需要人们的阅读和诠释。测试这样的规格说明可以执行,不管是什么时候,我们就能看到是否存在对需求的偏离。“测试就像一种能够不断送出的礼物。”我说道。

团队中的人都很棒。他们技能纯熟,但是不会自认为全知全能。团队那种“我能做到”的积极态度和持续不断的学习,让工作成为了一种快乐。早期的成功给予我们信心,大大推进了我们的工作进展。我们发现了能够起作用的一点:我们让工作进度透明可见。每一天都有新的成果出现,而且这些成果依赖于团队的写作。我们互相挑战,也挑战了组织。真是值得牢记的团队经历。即使我不能将泡菜变成黄瓜,我们还是改变了泡菜的口味!

更好的实践

Steve:我在本科阶段的辅修专业是计算机科学,当时并没有哪个作业是多人合作完成的。在我读研究生的时候,我有一个明确的目标,那就是获得更多的经验,更好地处理团队工作。西雅图大学软件工程硕士学位课程中一个吸引人的地方是很多作业都是团队作业。不仅最后一年的项目如此,大多数课程中的很多作业,特别是稍微大一些的作业,都是以团队方式完成的。

TRW软件生产率项目回忆录

建造宇宙飞船

成功的需求

在Google的开发工作

团队与工具

开源程序通常由组织很松散的软件开发人员联盟组成。有些人自愿投入时间,还有些人由公司支付薪酬,为了公司的利益而维护软件。因为参与者常常分布在不同时区,可能从来都没有见过面,所以项目在很大程度上依赖于高度协作的工作:缺陷跟踪程序、邮件列表和归档资料、网络聊天室、版本控制储存库、wiki以及其他很多东西。你不一定要熟悉所有这些工具,在后面出现这些工具的时候我会再做解释的。

每个开源项目都必须确定下来如何对项目进行组织和管理。通常采用非正式的方式解决:项目开始的时候一般都是一小组的人(有时候只有一个人),随着时间的推移,感兴趣的志愿者出现并加入,最初的核心小组认识到如果能够把那些新加入的人也邀请到核心小组,那么对项目是有好处的。但是在项目有了很多贡献者之后,可能会很难跟踪他们,也很难识别出哪些人能够培养成为潜在的核心维护人员。我们要看的第一个工具就是在项目中产生的,解决的就是这个问题。

研究团队

HADS团队

糟糕的上司

欢迎使用过程

跨越障碍

质量与速度

层层障碍铺垫之路

办公室内外

汇集团队的声音

公司关注高质量的用户手册,尊重文档人员,这是吸引我加入公司担任技术编辑的原因。我主要是和编译器团队合作,但也得到了为不同项目工作的机会。

制作音乐

在那些课上,他了解到:软件开发一部分是艺术,另一部分是科学。在现实世界中,他认识到软件开发实际上是商业行为。他的梦想是:有朝一日,能够生活在自己的瓦尔登湖旁边,当然,还要有高速的Internet连接。

除了好好工作之外,生活中还有更重要的东西。

项目管理之美

项目管理简史

1.项目管理和软件开发不是神秘的艺术。对于漫长的造物史而言,任何现代的工程项目都是一种新的出现。技术和技能可能会改变,但那些造成工程难题的关键挑战依然存在。无论是编程语言,还是开发方法,它们在某些方面是独一无二的,而在其他方面则是从其他事物衍生而来的。但是,如果我们想要尽可能多地复用已有的知识,在与过去进行比较时,必须以开放的态度来考虑知识的唯一性和衍生性。

2.对于您所做的事情了解得越少,您就有越多的精力去完成它。如果我们对工作有一个简单的了解,我们就能够从制造其他身边已有事物的过程中发现有益的类比。历史上曾有很多的例子和教训,可以供现代工业来借鉴、比较和对照。这类似于日语单词shoshin所表述的概念,即习武规则的最重要之处——初学者态度 [1]或开放态度。保持求知和开放的态度才能取得进步,同时还需要实践来维持这种心态。只要不断学习,我们就可以避免走入歧途,安全地考虑我们所做的事情。

3.简单并不等于容易。优秀的运动员、作家、程序员以及经理人都有这种认识,认为他们所做的事在本质上很简单,但同时也非常困难。要记住,简单并不等于容易。例如,跑马拉松是个简单的事。你开始跑,跑了26.2英里后就停下来。有什么比这更简单的?跑完马拉松很困难这个事实并无损其简单性。领导力和管理也很困难,但其本质是很简单的,就是以特定方式朝特定目标把事情做好。

“人类是万物之灵,有能力学习他人的经验,却也最容易对他人经验视若无睹。”

——Douglas Adams

当研究项目历史时,会引发一个简单的问题:既然我们可以避免,为什么还有人愿意去经历错误和失望?如果古代及现代工程史都是公开的,而且无论灵感来自何处,我们也因做些聪明的事而领取薪水,为什么很少有组织奖赏那些从过去获取经验的人?每天都有项目完成或取消(许多开发项目都以此结束,),但很少有人从中吸取经验。大多数组织中的经理人似乎很少奖赏那些寻找这类知识的人。也许是害怕他们找出来的东西(害怕必须为此负责),或者也可能对此缺乏兴趣。当我们花费时间来开展新项目时,没有人愿意回顾痛苦或令人沮丧的经验。

Henry Petroski在其《To Engineer Is Humman:The Role of Failure is Successful Design》(Vintage Books出版,1992年)一书中提及:许多工程的突破都来源于失败的结果。产生这种现象的部分原因在于,失败会使我们集中注意力,重新检查我们忘却的假设(当原型出现问题时,很难假装一切正常)。正如Karl Popper 所说的,只存在两种理论:错误的理论和不完整的理论。如果没有失败,我们就会变得骄傲,忘记了我们对事物的了解实际上并不像我们所想像的那样周全。

因此,窍门就是尽可能从他人的失败中学习。我们应该利用他人的经验来应对未来的挑战。虽然失败的表象对于不同项目有很大的差异,但引发这些问题的根本原因或团队行动也许可以借鉴(并且是可避免的)。即使是我们自己的项目,也要避免逃避失败的习惯。相反,我们应该视之为学习机会。失败的因素是什么?哪些因素可能很容易减少或消除?根据Petroski的说法,只要我们有勇气仔细检查发生过的事情,从实际失败中学得的实践知识将是我们取得进步的最有力的源泉。

也许这就是为什么波音公司——全球最大的飞机设计和制造公司之一,会留着一本黑皮书,来记载从过去的设计和制造失败中获取的经验教训 [4]。自从波音公司成立之后,就一直保存着这份文件,用来帮助现代设计师,从过去的经历中吸取经验。任何这样做的组织,都可以增加项目成功的几率,同时也有助于建立一种可以公开讨论、面对失败的环境,而非否认和隐藏失败。看起来,软件开发人员也需要保存他们自己的黑皮书。

历史的一个问题就是并不总是能和现实产生关联。要把几十年前的经验用到如今差别似乎很大的事情上,又要维持同理性,的确很难。另一种做法是,对当代几种有趣的项目进行比较。虽然没有工程史的庄严感,不过,却让人可以亲身体验和观察。通常,亲眼所见是能给人充分信息的唯一办法,只有通过这些信息,才能在众多概念间建立联系。

我们希望医学是关于知识和过程的有条理的专业。但实际并非如此,医学是不完美的科学,是由不断更新的知识、不确定的信息以及容易犯错的个人共同组成的,同时又要按规则操作。是的,我们所做的事情有科学的做法,但同时也有习惯、直觉以及偶尔单纯的经验猜测。我们所知道的与我们持续追求的目标之间存在着差距,该差距把我们所做的一切都复杂化了。

项目管理新手的恐惧之一就是成功需要改变。新项目建立的目的是要借着修改、构造或摧毁某些事物来改变世界的状态。维持现状不是成功的结果——除非由于某种奇怪的原因而将此定为目标。世界一直在变,如果和去年相比,项目已经没那么好,这通常就意味着落后了,因为目标被误导或者项目的执行在某些方面失败了。

进度表的原理

熵是无所不在的,既不是项目也不是经理人的朋友。

如何知道该做什么

“制作软件系统最困难的一个部分是决定要构建什么样的系统。在概念性工作中,建立详细的技术需求是最困难的。其中包括对人、对机器以及对其他软件系统的接口。没有其他工作像这项工作这样,一旦做错,将对结果造成极大的伤害。也没有其他工作像这项工作这样难以修正。因此,软件制造者需要执行的对客户最重要的事情就是反复精炼产品需求。”

——Fred Brooks

·项目需要做什么?

·产品怎么工作?其中的每个组件怎么工作?

·如何构建产品?如何检查它是否按我们所希望的方式工作?

·当前的系统或我们将要建立的系统的可靠性、性能、扩展性如何?需求和现状之间是否存在差距?

·可用为我们立即使用的技术或架构有哪些?我们是否要冒险使用那些将很快普及但现在还不流行的新技术?

·哪些工程过程和方法适用于当前团队及项目?

·我们的人员具有哪些可用的知识和专业技术?他们如果不参与这个项目,将会如何?

·我们如何弥补专业技术的差距?(培训/聘用/学习/忽视,以及希望这些差距神奇地消失)

·需要多少时间来构建系统?能做到什么样的质量?

·首页中很难找到经常需要的项目。

·部门信息的页面加载很慢,用户必须等待。

·当使用大数据表时,数据库查询页面会发生故障,用户必须再来一次。

·站点没有提供自动访问HR服务的功能,手动做将花很多时间。

·以目前的页面布局,很难发现搜索结果。

·注册页面没有提示必须输入内容的字段,很容易犯错。

·状态页面没有包含电子邮件信息,用户不能发现电子邮件不能使用的原因。

·没有办法保存关于首页如何显示的参数配置信息。

想法从何而来

“计算机没什么用,它只能给你答案。”

——Pablo Picasso

“技术空想家永远分不清可行的和理想的之间的差别。”

——Edward Mendelson

·很多团队都没有恰当地管理需求和规格说明书之间的这段时间。

·考虑质量需求和设计探索是对这段时间的最佳利用。

·想法的优劣只和目标或其他想法有关。

·限制条件在寻找想法时很有用处,但是,“跳出框框”思考不一定就是答案。有时,最佳的解决方案是找出一种聪明的方式,可以在限制条件内工作。

·问题、视角以及即兴游戏,是发现新想法的工具。

·客户体验是开始设计想法的最佳起点。

·经过不同专业人员的多次交流后,想法就可以发展成为设计。

有了想法之后做什么

撰写优秀的规格说明书

如何制定好的决策

神探福尔摩斯曾说过;“如果你删掉不可能的部分,无论剩下的是什么,无论多么不可能,那一定就是真相。”对决策而言也是如此:如果你删掉最差的选择,无论剩下的是什么,无论有多么差,那一定就是你的最好选择。的确,这诚然是一种决定事情的愤世嫉俗的方法,但有的时候,排除法是唯一能让你获得动力去做决定的方法。

如果你已经做了一份可能的选择列表,而且需要把范围缩小,找出那些不能满足项目最低基准的选择。你之前把它们包括进来,可能是因为在讨论时加进来,让你有机会找到混合式的抉择,或者是因为当时正重新考虑需求,但现在是该把它们删除的时候了。查看你的文件和需求列表,和你的客户进行确认,然后把不够好的选择删掉。

另一种能够缩小可能性的工具被称为“奥卡姆剃刀”原理。奥卡姆的威廉是12世纪的古典哲学家,他以简化的概念来推动决策而出名。他认为,人们为各种情况增加不必要的复杂度。他建议,理解事情的最好方法就是找出最简单的解释,然后先利用它,因为多数时候,这就是正确的解释(也就是,以现代的话来说,“保持简单、笨拙”)。

“奥卡姆剃刀”原理指的是一种过程,这一过程试着砍掉挡在路上的所有不必要的细节,回归到问题的核心上。这也意味着,最简单的逻辑有最大机率成为最好的方法。也许有个大有希望的选择,这个选择需要高风险的工程或者仰赖不可靠的人。应用“奥卡姆剃刀”原理时,缺少简单的选择就是把它从可能的列表中删除的一个理由。

沟通和人际关系

怎样才能不惹恼别人:流程、电子邮件和会议

把流程定义为任何可重复的一组动作,由团队决定定期执行以确保事情会以某种方式完成。流程有很多其他名称:规则、指导方针、形式、程序或限制规定。(例如,如何签入代码、测试和构建,就是工程流程的常见实例。其他实例包括规格说明书的撰写和管理日程表和进度表等等。)好的流程可以提高项目完工的机会,而且效益要大于成本。然而,因为很少花时间研究流程存在的原因,或者流程(应该)解决什么问题,所以很多团队只是空有很多流程而已,无法从中获得益处。

事情出错时该做什么

“我们应该担心的,不是反对我们的人数,而是他们这么做的理由有多充分。”

——Alain de Botton

为什么领导力以信任为基础

“信任是所有有意义的人际关系的核心。没有信任,就没有付出、结盟和风险承担。”

——Terry Mizrahi,社区组织教育中心主任(Education Center for Community Organizations)

1.做出承诺的人非常愿意这样做。

2.承诺不是轻易做出的,这就是说,承诺是在充分地考虑了工作、资源和进度的情况下做出的。

3.双方对做什么,由谁来做,以及什么时候去做,达成一致意见。

4.公开且坦诚地做出承诺。

5.即使需要帮助,责任人也要尽力实现承诺。

6.在承诺兑现之前,如果有任何影响其中一方履行承诺的事情发生,都要提前通知对方,并且重新做出承诺。

“不分日夜,保持真诚,则不论对谁,你都不会虚伪。”

——莎士比亚,《哈姆雷特》

“不管你在哪里读到,或者谁说的,除非符合你自己的理由和常情,否则什么也不要相信,即使是我说的也不要相信。”

——佛陀

SELF-RELIANCE

·信任是通过有效承诺而建立起来的。

·信任是因为对重要事情的不一致行为而丧失的。

·利用授权和信任,让众人能够出色完成工作。

·授予型权力来自组织阶层体制。挣得型权力来自众人对你行动的响应。尽管这两种权力都是十分必要的,但是,挣得型权力比授予型权力更加有用。

·利用授权建立你对团队的信任,确保你的团队能够抵御灾祸。

·以能够维持众人信任的方式来应对问题。在危难时刻,支持队友,这样他们才会把问题告诉你,而不是隐藏起来。

·信任自己是领导力的核心内容。自我发现是了解自己和发展健康自我依靠的好办法。

SCOTT BERKUN

如何让事情发生

“世界只回应行为,而不是别的什么”

——Scott Adams

很多PM所犯的基本错误,就是忘了去评估与他们共事的人,以及据此调整他们的处理方法。美国海军海豹特战队和陆军巡逻骑兵团的训练,是要在各种不同的地形中执行任务:沙漠、沼泽、丛林、苔原。没有这些训练,他们的效力会受限:因为他们的技巧若不起作用,他们就得在不熟悉的地形上挣扎求生(想像一下,穿着绿色军装、带着橄榄枝伪装的士兵,试图在冰雪覆盖的旷野上躲藏)。他们学的第一课就是如何评估他们所在的环境,然后考虑他们的技能里哪些战术和战略在这种环境下可以发挥作用。对PM而言也是如此。只是PM面对的不是地理环境,但必须注意他们所处的各种不同的社会、政治以及组织环境,然后据此采用正确方法。

·激励和鼓舞人心

·组织团队,并规划行动

·解决争论或打破僵局

·和其他组织或文化协商

·为资源建立论据

·说服所有人相信任何事

·管理报告表(职员)

中盘战略

“机会青睐于有准备的人”

——Louis Pasteur

1.第一天结束时,如果事情进展顺利,那么第二天的目标就是要继续保持下去。

2.任何时候如果项目出现问题,你的工作就是要找出问题,然后采取行动,使项目再度运转顺利。这可能会花费数小时,数天或数周。

3.如此重复,直到项目完成。

很明显的问题在于,总是有数不尽的麻烦会发生,使项目进展不顺利。更糟糕的是,只有有限的时间去查清什么问题,以及更少的时间来解决它们。更别提要让项目的健康部分,继续运转顺利而不遇上麻烦而需付出的努力了。

认为一切都在掌握中的人之所以失望,是因为他们对未知的力量采取更正行动,导致不可预测的结果(通常会令人发狂)

事实上,当飞机、汽车或项目变得不稳定时,控制就变得困难而有危险——即使是对有专业技能和经验的人也是如此(较小的项目当然比较敏捷且易于回应,但这些项目也有它们的动量)。不稳定会让多数行动的结果无法预测,因为有太多可变因素在迅速的变化着。因此,优秀的项目管理,大多是先走在项目前面一两步,投注必要的精力,在开始就避开这些境况。

终盘战略

“你如何演奏音符,和音符本身同等重要。”

——Henry Kaiser

·大的截至期限就是一系列小的截至期限。

·任何里程碑都有3个较小的期限:设计完成(规格说明书完成),功能完成(实现完成),以及里程碑完成(质量保证和精炼完成)。

·在里程碑一开始就定义退出标准,可以提高团队赶上交付日期的能力。

·赶上交付日期就像飞机着陆一样:你需要一个又长又慢的路线。同时,你希望能够准备好再次快速起飞,而不用做出重大的修整。

·你需要各种评价方法来追踪项目。通常的方法包括每日构建版本、Bug管理和活动图表。

·你需要各种控制来完成项目层次的调整。常见的控制元素包括查看会议、Bug分类和作战团队。

·终局阶段的结束,是一个很慢、很折磨人的过程。挑战在于如何缩小改变的范围,直到令人满意的发行版本出现为止。

·现在是时候开始事后分析流程了。让你自己和你的团队,通过从那些进展顺利以及不顺利的事情的学习中,获得益处。

·如果幸运降临到你头上,你的项目顺利推出,要快乐。非常,非常地快乐。很多人没出过错,但是却从来没有过这样的成就。计划一个疯狂的夜晚。做些荒谬有趣而奢侈的事情(包括邀请我这个作者参加聚会)。让你多年之后有自己的事情可以讲。

政治与权力

每次当你试着安排人们去做一些事情时,无论是举行聚会还是成立公司,每一个参与的人都有不同的态度、愿望和技能。也就是说,不管带领项目的领导多么有天赋,还是无法满足每个人得到他们想要的每件事。因此,积极而充满野心的人有一种自然的本能,试着影响有权使之发生的人,去获得他们想要的东西。我尽我所能用一段最简单的文字说明来解释,政治为什么会存在:政治就是群体互动时人性的副产品,而在群体互动时,我们会经历各种政治情势的挫败和挑战。亚里士多德说:“人是政治的动物。”这里讲的大概就是他所说的部分意思。

“每一种管理行为都是政治行为。我的意思是,每种管理行为都是以某种方式重新分配或者重新强化权力。”

——Richard Farson,《Management of the Absurd:Paradoxes in Leadership》

参考资料

de Botton,Alam,《The Consolations of Philosophy》(Vintage出版,2001年)ISBN 0679779175

Russell,Bertrand,《The Conquest of Happiness》(Liveright Publlshing Corporatlon出版,1930年)ISBN 0871401622

孙子,《孙子兵法》(《The Art of war》),袖珍版(Shambala出版,1991年)ISBN 0877735379

Zeldin,Theodore,《An Intimate History of Humanity》(Vintage出版,1998年),ISBN 0749396237

架构之美

  • 序一 如何看到一滴水的美丽
  • 序二 架构的架构
  • 序三 美丽架构的含义

美丽至简。美丽的架构应尽可能简单,但不要过于简单。书中通过多种例子表达了这个最基本的道理。我见过很多大型的软件架构,从大型的电信网络管理系统,到大规模应用的互联网架构,以及企业级的ERP软件,系统总是遵循从无到有,从简单到复杂,再到简单这样的过程。最终,支撑这些大型系统稳定可靠运行的就是这个最基本的道理。

美丽的架构应尽可能精益,并且是演进式发展的。当你架构一个亿万人同时在线的大规模网站系统的时候,你无法从一开始就提供最完善的解决方案,它应该是随着用户的增长而可扩展的。精益的思想让你避免了过度设计,也使架构不断演进,趋于完美。书中从企业级应用架构、用户级应用架构等多个角度提供了相应的解决方案,对于架构师无不是一顿美味的大餐。

  • 序四 美丽架构之道

从代码逻辑到物理网络,从单机到分布式,无数的技术可供架构师选择,如分层、组件化、服务化、标准化、缓存、分离、队列、复制、冗余、代理等,不过它们仍然只是“术”的范畴,而何时何处如何恰到好处地使用它们才是“道”的范畴,比如顿悟变化的道理,在博弈中寻找平衡,以系统化的角度来分析问题,寻找相对与绝对的奥秘、开放的心态……

译者序 架构与美

  • 架构之美体现了关注点的分离与结合。
  • 架构之美注重表达的简洁性。
  • 架构之美需要解决实际问题,它既是艺术,也是生活。
  • 架构之美需要经过专业的学习才能更好地欣赏和创造。
  • 架构之美经过时间打磨。

WIDE AWAKE DEVELOPERS

序 Stephen J.Mellor

使用随意的、非正式的工程技术去开发高性能、高可靠性和高品质的软件系统会遇到非常多的困难。这些技术对于过去要求较低的系统也许还能对付,而目前系统的复杂性已经达到了这样一种程度:如果不开发并维护一个基础架构,利用它将系统组织成一致的整体并避免零碎的实现,那么我们就无法应对,必将导致测试和集成失败。

架构概述

建筑师、音乐家、作家、计算机设计师、网络设计师和软件开发者都在使用“架构”这个术语,其他人也用(你有没有听说过“食物架构”?),然而不同的用法其结果也不同。建筑与交响乐完全不同,但都有架构。而且,所有的架构师都在谈论他们工作中的美,以及因此而导致的结果。建筑师可能会说,一座建筑应该提供适合工作或生活的环境,而且它应该看起来很美。音乐家可能会说,音乐应该能演奏,包含能够辨明的主题,而且它应该听起来很美。软件架构师可能会说,系统应该对用户友好、响应及时、可维护、没有重大错误、易于安装、可靠,应该通过标准的方式与其他系统通信,而且也应该是美的。

相对来说,计算机是比较年轻的一个学科。因为年轻,所以不像建筑、音乐或写作等领域那样,有那么多的例子;也因为年轻,则需要更多的例子。我们希望这本书能满足这种需要。

架构:“建造的艺术或科学;特别是设计和建造人类使用的建筑时的艺术或实践,同时考虑到美学因素和实用因素。”

——《The Shorter Oxford English Dictionary》(小型牛津英语字典,第5版)

在所有学科中,架构都提供了一种方式来解决共同的问题:确保建筑、桥梁、乐曲、书籍、计算机、网络或系统在完成后具有某些属性或行为。换言之,架构既是所构建系统的计划,确保由此得到期望的特性,同时也是所构建系统的描述。维基百科上说:“根据这方面已知最早的著作,即Vitruvius的‘On Architecture’,好的建筑应该美观(Venustas)、坚固(Firmitas)、实用(Utilitas);架构可以说是这三方面的一种平衡和配合,没有哪一个方面比其他方面更重要。”

我们谈到交响乐的“架构(architecture)”,反过来,又将架构(architecture)称为“凝固的音乐”。

——Deryck Cooke,《The Language of Music》(音乐的语言)

我们将计算机系统的架构定义为一组最小的特征集,它们决定了哪些程序将运行,以及这些程序将得到什么结果。

——Gerrit Blaauw和Frederick Brooks,《Computer Architecture》(计算机体系结构)

架构观点中的常见思想是结构,每种结构都由各种类型的组件及其关系构成:它们如何组合、相互调用、通信、同步,以及进行其他交互。组件可以是建筑中的支架横梁或内部腔室、交响乐中的旋律、故事中的章节或人物、计算机中的CPU和内存、通信栈中的层或连接到一个网络上的处理器、协作的顺序过程、对象、编译时的宏、构建时的脚本。每个学科都有自己的一套组件和组件间的相互关系。

从更大的范围来说,术语“架构”总是意味着“不变的深层次结构”。

——Stewart Brand,《How Buildings Learn》

面对不断增长的系统复杂性,以及它们内部和相互之间的交互,由一组结构形成的架构提供了对付复杂性的主要手段,目的是确保得到的系统具备所要求的特征。结构为我们提供途径,将系统化解为一些交互的组件。

一个程序或计算系统的软件架构是系统的一种结构或一组结构,它包含软件元素、这些元素的外部可见的属性,以及元素之间的关系。

“外部可见”的属性是其他元素对该元素可以做出的假定,诸如它提供的服务、执行时的特征、错误处理、共享资源的使用等。

——Len Bass、Paul Clements和Rick Kazman《Software Architecture in Practice,Second Edition》

两个系统的故事:现代软件神话

Pete Goodliffe

架构是一种很浪费空间的艺术。

——Philip Johnson

·低品质的软件和漫长的版本发布周期。

·系统没有弹性,不能够适应变更或添加新的功能。

·无处不在的代码问题。

·员工问题(压力大、士气低、跳槽等)。

·大量混乱的公司内部政治。

·公司不能成功。

·许多痛苦和面对代码深夜加班。

形式永远服从功能。

——Louis Henry Sullivan

·我们如何对事物命名。

·顶层文件结构。

·“内部”展示的风格。

·共用的编码惯例。

·选择单元测试框架。

·支持基础设施(例如版本控制、适合的构建系统和持续集成)。

这些“细节”完美的因素非常重要:它们与软件架构密切相当,影响到后来的许多决定。

等那完全的来到,这有限的必归于无有了。

——《哥林多前书》第13章10节

1.什么是你看到过的最好的系统架构?

·你怎么知道它是好的?

·这个架构在代码集之内和之外带来了什么结果?

·你从中学到了什么?

2.什么是你看到过的最差的系统架构?

·你怎么知道它是差的?

·这个架构在代码集之内和之外带来了什么结果?

·你从中学到了什么?

伸缩性架构设计

记忆留存

面向资源的架构:在Web中

数据增长:Facebook平台的架构

给我看你的流程图而藏起你的表,我将仍然莫名其妙。如果给我看你的表,那么我将不再需要你的流程图,因为它们太明显了。

—Fred Brooks,《The Mythical Man-Month》(人月神话)

Xen和虚拟化之美

计算机科学中的任何问题都可以用另外的间接层解决,但是这通常会引发另一个问题。

—David Wheeler

Guardian:一个容错操作系统环境

优化的第一准则:不要优化。

优化的第二准则(仅限于专家):还是不要优化。

——Michael A. Jackson

JPC:一个纯Java的x86 PC模拟程序

元循环虚拟机的力量:Jikes RVM

GNU Emacs:滋长的特性是其优势

当集市开始构建教堂

软件架构:面向对象与面向函数

重读经典

如果程序员在解决面对的问题时可以使用更多的工具,那他就更富有。只要工具的流行程度不是问题,他就可以选择最合适当前情况的工具。关于这一点,Bjarne Stroustrup在《The Design and Evolution of C++》(1994)中表达得很漂亮:

我对计算机和编程语言的兴趣基本上是实用主义的。

我更习惯经验主义而不是理想主义……也就是说,我更喜欢亚里士多德而不是柏拉图,更喜欢休谟而不是笛卡儿,对帕斯卡只能难过地摇摇头。我发现一些完备的“系统”就像柏拉图和康德梦想的那样,但基本上不能让我满意,因为它们离我的日常经验极其遥远,也与个人的基本特点相去甚远。

我发现克尔凯郭尔对个人的狂热关注和敏锐的心理学洞见对我来说更有吸引力,远甚于黑格尔或马克思对人性的崇高计划和关注。尊重一个群体而不尊重群体中的个人,则根本不是尊重。许多C++的设计决定的根源都在于我不喜欢强制人们用某种特定的方式来做事情。从历史上看,许多最大的灾难都来自于理想主义者试图强迫人们“做对他们有好处的事情”。这种理想主义不仅会导致无辜的受害者遭受痛苦,而且会导致理想主义者应用强制力时的幻觉和腐败。我也发现理想主义者常常倾向于忽略经验和实验,这些经验和实验不巧恰好与教义或理论相抵触。当理想发生冲突时,有时甚至是权威们一致同意时,我倾向于提供支持,让程序员自行选择。

数据之美

在数据中观察生活

美丽的人们:设计数据收集方法时牢记用户

火星上的嵌入式图像数据处理

PNUTShell中的云存储设计

信息平台和数据科学家的兴起

照片档案的地理之美

数据发现数据

实时的可移动数据

探寻Deep Web

构建Radiohead的“House of Cards”

都市数据可视化

Sense.us的设计

数据所做不到的

自然语言语料库数据

数据中的生命:DNA漫谈

美化真实世界中的数据

数据浅析:探索形形色色的社会定型

旧金山海湾之殇:次贷危机的影响

美丽的政治数据

连接数据

测试之美

程序之美始于静,用之于动:精巧的设计、缜密的思维才能保证程序运行可靠、性能卓越;测试之美始于动,归之于静:在测试活动中不断寻找客户满意与团队能力之间的平衡点,寻找复杂测试方法与有限的测试资源的平衡点,寻找自动化测试的高效性与工程师的创意能力最有效的结合点。测试要求亦正亦奇,又要做到正奇结合,平衡工程活动当中的各种要素,这些特点最终成就了《测试之美》。

诚如李政道博士所言:科学与艺术是一枚硬币的两面。他极力倡导科学艺术化与艺术科学化,追求科学与艺术融合共生的综合之美。他首次提出“物艺相通”(后称“科艺相通”)这一科学概念,认为科学与艺术一旦达至炉火纯青之境界,步入到超越自我的火候,就可触类旁通、举一反三,达到促进人们的非线性思维、创造性思维及立体化思维良性拓展的作用。《测试之美》讲述的正是漂亮的测试工具、完美的测试流程、颇具审美情趣的测试诀窍以及凸显创造力之美的测试理念。是的,测试既是一门科学,也是一门艺术。从某种角度来说,融合了测试工程师的非凡智慧和高度创造性的测试之作,当然也是美的艺术作品。这其中,饱含测试工程师们对测试的热爱与执著,我们用挑剔的眼光从不同的层面(理念层面、技术层面、用户层面、待升级产品的预设层面等)来审视测试对象的期望行为并寻找缺陷,努力使之达至高效、完善、和谐之美;让测试工具以及人们使用的过程更具美感,产生“使用即享受”的美好体验。

·思维流程之美。测试专家们是如何思考测试命题的,其思路的定位、辨析、取舍、抉择之间的思维过程是那么生动、奇特与传神。众多案例中的众多思维模式,让我们受益终生。

·探索发现之美。书中每个人大都讲述自己探索最佳测试方案中经历的酸甜苦辣,他们那种不断进取的精神之美,既帮助他们取得突破的成功,也激励了我们克服困难的毅力长存。

·结构和谐之美。测试也是一项系统工程。既有测试工程的总体架构,又有经过仔细挑选的测试手段以保证测试工作得以可持续改进和完善。本书不仅剖析了测试专家们是如何追求测试方案的流程美、畅达美和节律美,也阐述了测试集成框架的组合美、整体美与和谐美。

·卓越功能之美。专家们介绍的多种自动化、快捷化的测试方案,都是设法把枯燥的回归测试交给机器来完成,从而有效地将测试人员从手动测试解放出来。这种把功能测试之苦变为测试之乐当然是愉悦的、美好的了。这也可以叫做自动化测试——感受功能之美吧。

·团队合作之美。本书不乏各种测试团队合作攻关的有趣故事。团队协作历来是国内外大型IT企业的制胜法宝。大家在共同目标的指引下,有效、动态的分工依靠完美的协作制度来保证,而测试团队中每个成员的沟通与交流,构成了高效、和谐的大家庭,表现出团队合作的步调整齐之美、能力互补之美、集体攻关中的雄浑之美。

这对你有好处吗

这么说吧,我正在测试现实世界的边界。

我好奇于将会发生些什么。好奇心,仅此而已。

——Jim Morrison

不同的测试人员为搜寻缺陷做着不同方面的准备。他们的准备工作取决于你的环境和研发方法,一些准备工作源自个人偏好,他们可能提前开始写测试用例,也可能从一个笔记列表入手。但是不管技术方面怎么样,有些事情是各种技术都共通的。

他们要阅读一切帮助了解测试目标的资料,要问问题——很多很多的问题,一直问到他们满意觉得足够了解该应用程序为止,然后他们要决定如何最好地进行测试并制定一个计划。这个计划也许很正规,也许只在他们的脑子里,但大多数测试人员在开始测试之前就知道他们想要检查什么,在开始实验的时候也大致知道系统应该是什么样以及如何工作。

完美的测试让利益相关者满意

创建开源的QA社区

一个开源项目的存亡取决于它的志愿者队伍。越轻量级的项目,越是如此。随着我们开始使用越来越多的在线社交网络,我们有机会去把每一个项目,甚至是那些传统意义上的闭源项目,变成一个大众参与的项目。我们曾参与Mozilla日历项目,也就是一个Mozilla平台上的日历程序。我们开发两个产品:一个独立运行的日历程序——Sunbird和流行电子邮件客户端Thunderbird的一个插件Lightning。

有一种简单的机制,可以让志愿者参与项目:动力、合作、及时回应和成功。让有兴趣的志愿者参与的最好结果就是得到他系统的支持。要达到这个状态,志愿者必须始终保持动力,因此要明白它如何受其他因素影响是很重要的。请记住,单个志愿者,绝对不如一个团队行之有效,你应该尽力促进QA社区的所有成员精诚合作。友好竞争是可以的,但如果人们不互帮互助,产品就惨了。资深志愿者和协调员应该尽可能快地回应其他志愿者的问题和要求。每当一个志愿者停滞在一个死胡同手足无措时,需要有人作出回应并提供帮助。否则,她可能会开始离开项目。此外,不要低估成功给志愿者带来的能量。告诉志愿者他们的行动为项目贡献了多大力量非常重要。这就又产生了动力,创建了一个良性循环。

协作是性能测试之美的基石

性能测试通常是软件开发项目中最无奈、最复杂、最缺人手、时间最紧迫、最易被误解、最好斗以及最吃力不讨好的方面,但它并不必要如此。我曾在几个不同场合亲身经历过美丽的性能测试。事实上,似乎大多数优秀的职业测试人员都有至少一个关于美丽的性能测试的故事。

那么,美丽的性能测试有哪些特性呢?我认为它们应该是:

·期望的

·有意的

·有用的

·有技术含量的

·社会的

·值得尊敬的

·谦逊的

·有效率的

·(适度)挑战性的

·价值驱动的

·价值导向的

用模糊测试让办公软件更可靠

1.粘贴

2.保存

3.复制

4.撤销

5.加粗

·该缺陷与一个测试过程紧密关联(发现这个缺陷的大概测试过程)。

·当根本原因被发现后,一份详细的附件辅助解释了该原因。一段泛黄的玻璃纸胶带仍将两英寸大小的蛾子尸体附在该缺陷报告的边缘!

为什么将根本原因附加到缺陷报告中是十分重要的呢?如果我发现我的系统中的一个缺陷并修复了它,为什么我不能直接关闭这个缺陷?谁在乎根本原因是什么?随着越来越多的组织采用开放源代码(open source)的软件,这个问题的答案愈来愈明显。如果在某个具体的分发(distribution)中发现缺陷并修复了,该缺陷补丁应向上游(upstream)提交,这样从补丁开始的下游(downstream)的其他发行版(distro)都可获得该修复。但由于稳定性要求,其他的发行版可能无法脱离一个基于该补丁提交之前的分支(branch)产品。此时就应该到缺陷报告中去寻找根本原因、补丁以及其他对想要把这个修复回迁(backport)到另一个分支上的人可能有用的信息。遗憾的是,开源缺陷跟踪系统很少能提供这些细节。

哈佛蛾子的一个不幸遗产,是使一个原本代表有点麻烦却“基本无害的”小生灵的单词(即bug)逐渐植根于计算机科学的语言中。这个可爱的小词使得我们低估了软件缺陷可能造成的问题的规模和严重性,并几乎可以肯定,导致了软件公司在质量保证和缺陷管理方面没有足够的投资。

随着我们生活的更多方面越来越依赖于软件的安全和正常运行,我们必须认真地对待缺陷……甚至我们必须为软件缺陷另取一个名字。怪兽?恶魔?在本节的剩余部分中,我们将尝试使用“缺陷(defect)”这个词来代替”bug”,以帮助提醒我们:我们在处理的并不总是一个可爱的小生灵。

一个美丽的缺陷跟踪系统,应该是最终用户、技术支持人员、开发和质量保证工程师之间的信息渠道。它应该帮助这些人在缺陷的解决方案中合作。为了做到这一点,缺陷跟踪系统应维护关键的信息,并阻止不必要或不正确的信息。一个缺陷的重要方面可以被归结为侦探调查案件时提问的那几个种类:时间、地点、人物、事件,以及原因。

同样的工具和流程被用于在整个产品生命周期中跟踪缺陷。然而,“典型的缺陷”的粒度却随着产品生命周期而变化。

缺陷在哪里?软件缺陷都与独特的软件部件组合形成的系统相联系。

缺陷管理和测试用例的有效性

漂亮的XMPP测试

我第一次工作面试的时候,一位面试官问我是否知道并使用过“单元测试”。尽管我已经从事一款基于XMPP的即时通信(IM)客户端软件的开发工作很多年了,但是不得不承认,我只是很粗浅地了解单元测试,并没有写过任何自动测试程序。不过我有自己的理由。既然XMPP客户端处理的都是关于XML数据、网络,以及用户交互的工作,它们就不需要任何形式的自动测试。面试几个月以后,我在一个敏捷环境中工作的经验告诉我,这个理由是多么的牵强。我只花了几个月的时间就发现了测试代码的漂亮之处,特别是对于像XMPP这样的环境,它完全出乎你的预料。

大规模测试自动化之美

一个需要测试人员花费他们大部分的时间来监控测试执行,检查错误(或者毛病),推动测试的进行,使之从一个阶段进入到下一个阶段的系统,远远称不上美。只有当整个系统的自动化程度可以让测试人员能集中精力在他们做得最好的事情,也即是测试软件上,美才可能体现得出。

美比丑好

测试随机数发生器

以变化为中心的测试

软件以用为本

软件开发是创新过程

测试驱动开发:驾驭美之新标准

完美测试是商业成功的基石

剥析Socialtext的测试

我不明白为什么我们从一开始就认为这种方式能行。

——James Mathis,2004年

·实际的软件测试与学校学到的软件测试,甚至与有些企业在做演示时描述的软件测试都很不一样。

·关于什么是好的软件测试和如何很好地测试有很多不同的观点。

·上一条是说没有“最佳实践”,意味着没有任何观点或测试方法能够成功地适用所有的测试环境,但确有可供初学者遵循的经验法则。

对于一个使用锤子的人来说,所有东西看起来都像一颗钉子。

——马克吐温

高效测试之美

参照测试之美

Clam Anti-Virus:用开源工具测试开源代码

用Windmill测试Web应用程序

测试一百万个网页

在多机场景中测试网络服务

安全之美

心理上的安全陷阱

·我们可以保证最初的决定并不会影响创造性的思维,以克服习得性无助和无从选择。

·我们可以寻找不同人群的输入并强制自己试图推翻自己的假设,以克服确认陷阱。

·我们可以通过寻求工具的替代用法并通过其他路径来实现目标,以克服功能锁定。

无线网络:社会工程的沃土

美丽的安全度量指标

当你可以对自己所论及的东西进行度量,并可以用数字表达它时,你就对它有了相当程度的了解。当你无法对它进行度量,无法用数字表达它时,说明你对它缺乏了解,也就无法达到满意的程度。它可能是知识的起点,但你觉得很难把它推进到科学的状态。

——William Thomson,Kelvin勋爵,1883

界定现代和过去的革命性思想就是对风险的掌握;未来并不是上帝的一时兴趣,人类在自然界面前并不是全然被动的。在人类找到办法跨越这个边界之前,未来仍然是过去的一面镜子,它是在预测未来事件方面占据垄断地位的巫师和占卜者的独有领地。

——Peter Bernstein,1996

安全漏洞的地下经济

美丽的交易:重新思考电子商务的安全

捍卫在线广告:新狂野西部的盗匪和警察

PGP信任网络的演变

开源Honeyclient:先发制人的客户端漏洞检测

未来的安全齿轮和杠杆

如果不改变思维模式,就无法解决我们用当前的思维模式所创建的问题。

——阿尔伯特・爱因斯坦

如果一个人就靠不理解某样东西领取薪水,就很难指望他理解这样东西。

文明的进步常常是通过增加不假思索就可执行的重要操作而实现的。

——Alfred North Whitehead《数字入门》(1911)

事实上,几乎每家公司都会想方设法为它们的员工提供一些工具,但通过这些工具所收获的价值上的巨大差别取决于公司如何审视自身,思考它们的业务流程、思考它们的业务怎么改变、思考它们的项目管理以及顾客的反馈。它们的计划周期可能与以前截然不同。

——比尔・盖茨

人类在学习他人经验方面具有独到之处(在所有动物中),在表现自己的不情愿方面也是表现突出。

——Douglas Adams

“平台”是一个可以进行编程的系统,因此可以由外部开发人员所定制,从而满足难以尽数的各种需求和利基,这可能是平台的最初开发者完全没有想到的,更不用说花时间去适应了。

——Marc Andreessen,Netscape的创始人

安全设计

“美就是真,真即美”,这是我们所有人在世上所知道的和需要知道的。

——《希腊古瓮颂》,约翰济慈

美并不是浮于表面的。真正的美是对一个人、事物或系统的所有方面的写照。对于安全来说,美体现在其简洁而又优雅的设计上,它是在系统设计初期就把安全作为一个重要的目标来考虑的产物。在设计合理的系统中,安全是不可或缺的一部分,它贯穿于系统的设计、构建和测试过程;它又是轻量级的,适应性强,能够让整个系统在面临不断变化的需求时仍然保持灵活。如果把安全作为马后炮来对待,或者是在独立于整个系统的设计需求之外进行开发,那么它经常会是丑陋和死板的。

促使公司思考:未来的软件安全吗

俗话说:万变不离其宗(换得越勤,变得越少)[1]。在信息安全领域,技术变革的步伐极为迅速。一旦“好人们”跟上队伍,“坏人们”就会加速前进,采取新的攻击手段。但是在信息安全领域,有一种说法总是对的,那就是“换得越勤,变得越少”。

·竭全国之力,开发一个针对网络空间的全面国家安全策略,创建美国网络安全综合计划(CNCI)。

·通过一种平衡的方法管理网络空间,既避免强制规定,又避免过度依赖市场力量。

·需要一种更健壮的身份认证机制访问关键的基础设施组成部分。

·创建公共和私人的咨询组织,以支持NOC。

·与私营部门建立合作关系,专注于关键的基础设施和协作活动,预防网络空间事故并对这类事故作出响应。

信息安全律师来了

美丽的日志处理

有一句广为人知的格言“知识就是力量”,但是我们应该从哪里去获取我们所负责的包括计算机、网络设备、应用程序框架、SOA Web基础设施甚至是目前还没有发明的未来组件在内的信息技术(IT)组件的知识呢?这类信息最丰富的来源尽管总是可供使用,但常常不被人们所注意。这种来源就是系统和应用程序所产生的日志和审计跟踪。通过日志和审计跟踪以及相关的警告,信息系统常常可以提示我们什么东西出了差错,甚至允许我们把目光投向未来,并告诉我们什么东西将会出现差错。

日志可能还会揭露更多的脆弱性,例如在我们在控制中对规章制度的顺应性方面的不足。它们甚至会对IT的管理产生重要影响,并可能通过扩展影响公司的管理。因此,它们的影响范围甚至会超出IT领域。

但是,有许多日志常常只包含了数据(有时候是垃圾数据)而没有包含信息。我们需要付出额外的努力(有时候甚至付出需要巨大的努力)对数据进行过滤,才能把它变成与IT和业务相关的可以付诸行动的实用信息。

需求4——责任(accountability)——审核信息必须有选择地保存和保护,使影响安全的活动可以被追踪到责任方。受信任的系统必须能够在一个审核日志中记录安全相关事件的发生。

由于与日志有关的正规课程极为缺乏,那么该怎么讲述日志文件和审核记录的例子呢?我们可以根据产生日志的来源对日志文件进行分类,因为它通常粗略地确定了它们所包含的信息类型。例如,Unix、Linux和Windows系统所产生的日志文件与Cisco、Nortel和Lucent所生产的路由器、交换机和其他网络设备所产生的网络设备日志显然是不同的。类似地,防火墙、入侵检测和预防系统和消息安全设备所产生的安全设备日志与系统日志和网络日志都截然不同。

事实上,不同的安全系统在日志所记录的内容和格式方面存在很大的区别。从简单地记录可疑的IP地址到想方设法捕捉所有的网络流量,安全日志可能存储数量惊人的数据,有些内容具有相关性,有些内容则是无关紧要的,甚至有些内容对于判断当时的情况具有欺骗性。

人们一般会首先注意防火墙日志,然后是服务器日志,然后是其他电子邮件和Web日志,然后是数据库日志(这是最近才出现的),最终才是其他应用程序日志甚至是非IT的日志来源。

事件检测:寻找剩余的68%

无需真实数据就能出色完成工作

铸造新词:PC安全剧场