InfoQ:最热门的敏捷书籍

转:http://www.infoq.com/cn/news/2010/08/top-agile-books

从奥兰多2010敏捷大会的氛围中获得灵感,Jurgen Appelo汇总了一份书籍清单,列举出100本最热门的敏捷书籍,它们对软件开发社区有所帮助。

Jurgen使用的方法是利用Amazon和GoodReads上的评级,以及书籍首次出版的日期来衡量书籍的热门程度。他也利用了Amazon上“同时购买了此书”的功能,书籍的知名度由评分人数得出,书籍的质量如何则基于其平均评级,结合一些其他因素得出,由此产生了他的书籍清单。

Jurgen最新的清单上,最热门的100本书籍中跻身前10的书籍包括:

编号 书名 作者 发行年份 1 《敏捷估计与规划》 Mike Cohn 2005 2 《代码整洁之道》 Robert C. Martin 2008 3 《修改代码的艺术》 Michael Feathers 2004 4 《重构:改善既有代码的设计》 Martin Fowler, et al. 1999 5 《The Art of Unit Testing: With Examples in .Net》 Roy Osherove 2009 6 《敏捷软件开发:原则、模式与实践 》 Robert C. Martin 2002 7 《程序员修炼之道—从小工到专家》 [...]

应用程序性能测试

一. 性能度量

可用性

应用程序对于最终用户的可用时间,即平均无故障时间。可用性不好是很严重的问题,因为即便是一个小小的故障也会导致大量的商务上的花费。在性能测试方面,这将意味着最终用户无法有效地使用该应用程序。

响应时间

应用程序对用户请求给出响应的时间。对于性能测试而言,一个最常用的衡量指标就是系统的响应时间、即从用户端发出请求到完整响应经过的时间。

吞吐量

面向应用程序事件的发生频率。例如,在一段特定的时间内对某个Web页面点击的次数。

利用率

占用系统资源的百分比。例如,当1000个用户同时在线时,在应用程序上消耗了多少网络带宽,以及在服务器上占用了多少内容等。

二. 性能指标

超过15秒

出现这种情况,基本排除了交互的可能性。如果真的发生了延迟,系统就应该设计成可以让用户转向其他操作,并且在后续时间里继续请求响应。

超过4秒

一般对于一个要求最终用户保存在短暂记忆里的会话来说太长了。这样的延迟将妨碍解决问题的活动和破坏数据的录入。

2~4秒

超过2秒的延迟可以被这种需求的高度集中所抑制。当用户专注地去完成一项手头的任务时,终端2~4秒左右的延迟看起来就似乎很长了。

低于2秒

当系统的用户需要记住几个响应信息时,此时的响应时间就必须很短,如果要就住更为详细的信息,则要求就更高了,要求响应时间不能超过2秒。因此,某些复杂的活动,2秒是一个很重要的响应时间限制。

亚秒

对于那些思想密集型的工作来说,尤其是一个图形应用程序,响应时间要非常短,才能保持用户的兴趣和吸引他长时间的关注。

0.1秒

在键盘上桥下一个按键,并在屏幕上出现响应的字符,或者用鼠标点击屏幕上的一个对象,这种响应几乎是瞬时的。

三. 性能测试成熟度

1. Firefighting

应用程序部署之前很少或从来没有进行过性能测试的情况,因此,实际上在生产环境上发现的所有性能方面的缺陷都必须去解决。

2. Performance Validation

这一级别的情况是:公司为性能测试单独安排了一段时间,而不是在产品的后期才开始进行性能测试。因此,在研发过程中,仍然有相当多的性能缺陷被发现(30%)。

3. Performance Driven

在应用程序生命周期中的每一个阶段,均对系统性能加以考虑。因此,当系统上线后,出现的性能缺陷就不会太多(50%)。

四. 性能测试的类型

基准测试

基准测试时指建立了一个可与进一步测试比较的点,通常用户衡量事物响应时间。这个测试通常是单用户在一段时间或一定的循环次数内执行单个事务。在基准测试执行过程中不应进行任何其他系统操作,以便提供在“最好情况下”的测量。通关基准测试所得到的值可用户评估,它随着用户数或吞吐量的增长而导致系统响应性能的衰减。

负载测试

负载测试是典型的性能测试,对应用程序施加负载直到达到目标,但通常不会进一步施压。这样做的目的是满足性能指标的可用性、并发性和吞吐量,以及响应时间。负载测试最接近真实的使用场景,它通常会包括一些虚拟应用程序客户端与用户交互时的影响。

压力测试

压力测试会导致应用程序或部分支撑硬件的崩溃,这样做的目的是确定硬件的支撑大小和上限。因此,压力测试会持续进行,直到有什么东西出了故障:没有更多用户可以登录,响应时间超过了界定的可以接受的范围。进行压力测试的原因是,假设我们的目标是1000个并发用户,但是当仅仅1005个用户时,硬件就崩溃了,则这一点是值得关注的,因为它清楚表明,系统能力几乎没有额外的扩展空间。

压力测试的结果不仅仅可以衡量系统的性能,还可以衡量功能。重要的是要知道应用程序的上限,特别是当未来增长的应用量难以预料的时候。

渗透或稳定测试

渗透测试的目的是找出那些可能只出现在一段较长时间里的问题。一个典型的例子是,在一个事物重复执行时所出现的缓慢增长的内存泄露或者一些不可预见的极限情况。除非能够进行适当的监控,否则这种测试没法有效地进行。这类问题的表现形式通常是逐渐变慢的响应速度,或者是应用程序突然变得不可用。确保准确诊断的关键是与用户和服务器执行失败的故障点相关的数据,以及证明系统变慢的相关数据。

冒烟测试

冒烟测试源自硬件行业,指在硬件的一段或是元件发生了变化或者维修,会对该电气设备简单的通电,如果没有冒烟,就意味着该元件通关了测试。冒烟测试只关注发生改变的部分。一个性能的冒烟测试可能只涉及那些发生了代码修改的事务。

隔离测试

这种完全不同的测试用于在内部确定问题。它通常会重复执行一些特定的事务,这些事务已被确定为会导致系统的性能问题。

 

[...]

DW 2.0

W.H.Inmon的新书《DW2.0》,介绍了数据仓库新的范式;个人觉得其实也不新,只是在数据仓库实践了这么多年之后,理论上的一次整理更新。这本书的内容,边看边记吧!

                              DW2.0数据结构

数据的生命周期

在DW2.0中,重新定义了数据在DW中的作用,主要根据入仓库的时间定义了数据的生命周期。而数据的访问频率也会随着存储时间的增加而下降。这样的分区方式为仓库的架构尤其是硬件架构设计提供了支持。

1. 交互区

交互区是数据进入数据仓库的第一站,是数据联机更新的场所。

2.整合区

在一定的时间点,数据需要进行整合;存储在交互区的数据通过ETL进入整合区,数据脱离了应用状态。

3.近线区

近线区是整合区的一个延伸,在分区中是可选的。当数据量非常大并且数据间访问的概率差别很大时,可以利用近线区来处理。

4.归档区

存储访问频率很低的历史数据,通常是5-10年,甚至更长。

元数据

由于数据仓库更大,更多样化(用户多样化、数据源多样化等),为了能更好的管理和使用数据仓库,元数据的作用显得更加重要。

存储方案

在交互区,元数据与应用数据本身是分开存储的,即元数据与它所描述的数据在物理上是分开的;而在归档区,元数据直接与数据一起存储。这样的存储方式就避免了分析历史数据的困难。

元数据分类

DW2.0对于元数据的分类还是挺不错的,这样就避免元数据本身显得杂乱。

1. 本地元数据  被各种工具所专业的元数据,例如ETL工具的元数据、BI工具的元数据:

1)业务元数据     用业务语言书写的适合于公司业务的元数据;

2)技术元数据     公司的技术人员所应用的元数据。

2. 企业范围元数据

结构化数据和非结构化数据

在DW2.0中,数据库被要求整合结构化和非结构化的数据至数据仓库中。在现代环境下,对于非结构化的数据也同样蕴含着大量的价值。当数据仓库中包含非结构化的数据时可以有三种处理方式:a)非结构化数据单独进行访问分析;b)非结构化数据可以同结构化数据一起分析;c)一些非结构化数据可以近似的与结构化数据链接。

对于非结构化数据处理除了普遍存在的文本分析的难题上,还有两个需要特别注意的地方:

1)非结构化数据同样充斥着无用的信息,在进入DW的环境中,需要对这部分数据进行筛选;

2)文本的规范化。同结构化数据需要对不同的术语进行统一类似,为了在仓库中更好的利用文本信息,也需要对文本信息进行规范。规范化的过程需要将文字映射为两种格式——特定格式(自然语言)和一般格式(规范化)。对特定数据添加一般数据才能使得数据更适合分析。

应对业务需求的变化 [...]

数据仓库三要素

来自:《数据仓库结构设计与实施——建造信息系统的金字塔》

程序语言类型

“图灵完备”:所有主要的通用编程语言,都具有相同表现力;即,没有一种 语言可以写出其他语言不能表达的程序。不同的语言提供了不同的抽象机制和不同技术来支撑不同的解决方案。

 

语言范型:

类别 定义 实例 命令式 修改内存状态的语句序列 Fortran、汇编 过程式 通过过程(即一组语句)组织语言 C、Pascal、Cobol 面向对象式 通过对象组织程序 Smalltalk、Java、Ruby 函数式 通过无状态函数组织语言 Lisp,Scheme,Haskell 逻辑式 通过公里和推演规则表述期望结果的特征 Prolog,OPS5 声明式 描述解决方法而不是如何实现解决方法 XSLT,SQL,Prolog

 

类型特征:

类别 定义 实例 命令式 修改内存状态的语句序列 Fortran、汇编 过程式 通过过程(即一组语句)组织语言 C、Pascal、Cobol 面向对象式 通过对象组织程序 Smalltalk、Java、Ruby 函数式 通过无状态函数组织语言 Lisp,Scheme,Haskell 逻辑式 通过公里和推演规则表述期望结果的特征 Prolog,OPS5 声明式 描述解决方法而不是如何实现解决方法 XSLT,SQL,Prolog

 

语言特征:

语言 范型 类型系统 实现 [...]

《Clean Code》之代码坏味及启发

注释 不恰当的信息 注释只应该描述有关代码和设计的技术性信息,而不是那些本应该在源代码控制系统中保存的信息。 废弃的注释 注释很快会过时。废弃的注释应及时删除 冗余注释 若果注释解释的是一目了然的东西,就是多余的 糟糕的注释 如果值得编写注释就好好写,保证正确的语法和拼写 注释掉的代码 注释掉的代码吗污染了所属模块,放散了注意力。应该删除! 环境 需要多步才能实现的构建 构建系统应该是单步的小操作——应当能够用单个命令签出系统,并用单个指令构建 需要多步才能做到的测试 应该发出单个指令就可以运行全部单元测试 函数 过多的参数 函数参数应该少 输出参数 输出参数违反直觉。若果函数非要修改某东西的状态,就修改它所在对象的状态 标识参数 布尔值参数的存在就意味着函数不止做了一件事,应该消灭 死函数 永不调用的函数应该丢弃 一般性问题 一个源文件中存在多种语言 理想的源文件有且仅有一种语言 明显的行为未被实现 函数或类应该实现其他程序员有理由期待的行为。通过函数名的直觉应该能够理解函数的行为 不正确的边界行为 代码应该在所有的边界情况下都能工作。别依赖直觉。探寻每种边界条件,并编写测试 忽视安全 不要忽视编译器的警告和错误 重复 重复的代码,意味着遗漏了抽象。尽可能找到重复并消除它 在错误的抽象层次上的代码 创建分离较高层级一般性概念与较低层级细节概念的抽象模型。所有较低层级概念放在派生类中,所有较高层级概念放在基类中 基类依赖于派生类 如果看到基类提到派生类名称,就可能出问题了 信息过多 设计良好的模块有着非常小的接口。应该限制类或模块中暴露的接口数量。 死代码 不执行的代码应该从系统中删除 垂直分割 变量和函数应该在靠近被使用的地方定义 前后不一致 消息选择约定,一旦选中,就消息持续遵循 混淆视听 保存源代码整洁,良好的组织 晦涩的意图 代码要尽可能居有表达力。联排表达式、匈牙利标记法和魔术数都遮盖了作者的意图 位置错误的权责 代码应该放在读者自热而然期待它所在的位置 [...]

《Clean Code》之格式

垂直格式 短小精悍 每个空白行都是一条线索,标识出新的独立概念 靠近的代码行则暗示了代码间的紧密关系 变量声明应尽可能靠近其使用位置 实体变量应该在类的顶部声明 被调用函数应该在执行调用函数下面 横向格式

使用空格字符将彼此紧密相关的代码连接起来,也用空格字符把相关性较弱的代码分隔开。

在赋值操作符周围加油空格,达到强调的目的

不在函数名和左圆括号之间空格

空格可以强调其前面的运算符

缩进原则

团队规则

每个程序员都有自己喜欢的格式规则,如果在一个团队中,就是团队说了算!

《Clean Code》之注释

“别给糟糕的代码加注释——重新写吧”

                                                   Brian W.Kernighan与P.J.Plaugher

1. 注释不能美化糟糕的代码 2. 用代码来阐述 3. 好注释 法律信息 提供信息的注释 如:解释正则表达式的作用 对意图的解释 阐释 对于某些不能修改的代码,阐释其含义 警示 TODO注释 TODO是程序员认为应该做,但由于某些原因目前还没做的工作 放大 放大某种看来不合理之物的重要性 4. 坏注释 喃喃自语 仅只是因为觉得应该或者因为过程需要就添加注释 多余的注释 误导性的注释 注释往往不够精确 循规式注释 日志式注释 废话式注释 能用函数或变量时就别用注释 位置标记 不要滥用标记栏 括号后面的注释 如:标记循环结束的括号 //while 归属或署名 源代码控制系统是这类信息最好的归属地 注释掉的代码 HTML注释 非本地信息 信息过多 不明显的联系 注释及其描述的代码之间的联系应该显而易见 [...]

Page 1 of 3123