存档
Daniel-Journey Weekly Dose –2010/5/22
Agile
而敏捷里面所有的实践,质量是隐含的,不可侵犯的.这就是我们所说的Built Quality In.比如,刚开始写Story, 就要和测试人员定义验收条件;开发Story采用TDD的方式,通过测试来检验功能,类似于砌墙的时候先扯水平线,然后开始铺砖.
整个团队只有一个目标:产生高质量的交付
在此目标之下,以尊重 交流 反馈 勇气 简单为基本做事价值观和原则.
Agile Versus Waterfall: Part One
丰田精益生产方式中一个经常用的隐喻是“湖水和岩石”。大意是指湖水太深,你无法发现阻碍当前生产的主要原因,只有把湖水讲下去,才能发现真正的岩石在哪里。在精益生产中,湖水是指“库存”,而在软件开发中,对应的湖水则是“迭代周期”。
我们举一个例子,当发现“项目严重延期”时,通常已经是交付时间,不过开发人员最近一直加班,也挺辛苦的呀。不过如果你是项目经理或者客户,你知道开发人员的时间都花到哪儿了吗?如果采用迭代式交付,每两周一个迭代,完成一定的特性,你可能第一个迭代就发现问题我们可以抱怨团队开发人员能力不够,不过这关敏捷的什么事儿?本来大家都知道的事情,只不过敏捷让它暴露的更严重更突出罢了,谁还会任由你“掩耳盗铃”呢。
Javascript
JavaScript Debugging Techniques in IE 6
Java
Top 10 (not so popular) Eclipse Shortcuts
Design Pattern
Design Patterns Uncovered: The Flyweight Pattern
When considering this pattern, you will need to think about intrinsic and extrinsic data. Intrinsic data is the data that makes this object instance unique. Meanwhile, extrinsic data is information that can be passed in through arguments. So, if you can make some data extrinsic for cases that you have a large number of objects, the Flyweight pattern may be exactly what you are looking for.
Flyweight模式的几个要点:
1、面向对象很好的解决了抽象性的问题,但是作为一个运行在机器中的程序实体,我们需要考虑对象的代价问题。Flyweight设计模式主要解决面向对象的代价问题,一般不触及面向对象的抽象性问题。
2、Flyweight采用对象共享的做法来降低系统中对象的个数,从而降低细粒度对象给系统带来的内存压力。在具体实现方面,要注意对象的状态处理。
3、对象的数量太大从而导致对象内存开销加大(这个数量要经过评估,而不能凭空臆断)
SOA
但创建了一个SOA,自底向上的治理方法关注围绕单独ESB的集成化服务,这些ESB 可以快速装配。该方法因为需要过多的更新和重做而受到非难。
同时,相对的“自顶向下”的治理方法涉及大量严格规划和精确策略执行。这种方法也由于花费过多的时间才能产生结果而不被认可。
企业接受SOA的速度比较慢,大多数接受者倾向于接受自底向上的方法。
随着人们开始实施SOA,自身的技术就不够用了,这时就需要一些治理来辅助
Hariharan最后讲到:“如果企业以一种长期的愿景和蓝图来寻求SOA,那么自顶向下的方法是最佳的选择。如果并没有一项企业级的IT 策略以及长期的愿景,IT 可以选择自底向上的方法来实现和展示SOA的好处。”
Linux
scp 本地用户名@IP地址:文件名1 远程用户名@IP地址:文件名2
拷贝文件夹命令如下:scp -r file username@ip:filepath
多加上一个-r参数即可。
Daniel-Journey Weekly Dose-2010/4/16
Database & SQL
第一种方法,预留字段.不管怎样,预留字段的方式还是很解决很多问题的,而且基本不影响性能,除了额外的meta信息描述外,也没有其他的负担。
第二种方法,使用复杂字段.使用复杂字段的好处就在于比较灵活,同一类型的数据可以放在一起(实际上相当于把应该是一个关联表的数据放一个字段里了),操作的性能也不错,但是复杂字段里面的内容查询比较困难.
还有一种方法,将数据的存储和索引(需要查询的内容)分开存放,相当于主表就一个key-value,value就是一个大的xml(或者其他的一坨),把需要查询的字段放到其他单独的表里去,可以参考friendfeed如何使用mysql.
还有column based db,也可以很好的解决这个问题,实际上他就本本回避了加字段的问题,不过现在似乎没有性能很好的实现
SOA
面向服务架构(SOA)已被作为一种通过对齐IT和业务来促进业务机动性的方法被广泛接受。这种方法的主要不同之处在于,用相对较低的成本就能轻易 地获得某种机动性。在较高的层次,该方法试图将第n次业务变更所产生的增量成本降低到零或接近于零。组织推行SOA项目目的就是为了在他们的SOA之旅当 中尽早达到这个难以捉摸的第n个迭代。在实践中,要达到这种最佳状态的时间可能得花数年,甚至更长时间。
Architecture & Design
虽然动态横切(其中对象的运行时行为可以改变)被认为是AOP的根基之一,但静态横切却是一种远不为人所知的技术。
Scalability
Java
Reloading Java Classes 401: HotSwap and JRebel — Behind the Scenes
Difference between HashMap and IdentityHashMap
Linux
其他
张小龙(Foxmail的作者)认为互联网团队中的管理不是管人,而是管理产品体验,以产品体验为核心,产品设计和开发人 员与产品共同提升,共同进步。小龙之于QQ邮箱的影响正如乔布斯之于苹果的影响。
当时(2005)的javascript代码有很重的面向对象的味道,用传统的软件工程思想构建了 整个web框架,从软件的开发流程来说,这并没有什么问题,但是产品却有很大的问题出现了–慢,不是一般的慢,当时除了较快的电信网用户可以登陆进邮箱 之外,其他的用户基本上都被卡在登陆上。06年的大部分时间,整个团队都在解决速度慢的问题,尝试了很多方法,把js容量压缩掉了一半,js混淆之后又压 缩了很多,js文件分开为多个,但始终没有根本的转变,速度的提升仍然不能被用户接受。现在回过头分析这个问题,我觉得物理上的压缩和分割js文件之所以 解决不了问题是因为问题的根本在于js的逻辑架构上,当时的js有明显的基类和继承类结构体系,这种结构并不适合物理上的分割,即使分割开,渲染消耗的时 间是节省不下来的。
Javascript
Daniel-Journey Weekly Dose-2010/4/11
Architecture & Design
Mediator Pattern applied to Javascript
The diagram below is a general representation of the interaction between a mediator and colleagues. Each colleague stores a reference to the mediator and the mediator stores a reference to each colleague. Colleagues are unaware of each other and messages are broadcast through the mediator.
Two of the benefits of using the Mediator pattern are that that it decouples colleagues and simplifies object interaction. Instead of using the Observer pattern to explicitly set many-to-many listeners and events, Mediator allows you to broadcast events globally across colleagues. The biggest drawback of using Mediator pattern is that due to the centralized control, the mediator can become difficult to manage.
向对象开发与面向组件开发的区别
养成面向组件编程(COP)的习惯
面向组件还是面向对象
既然类和组件有着这么多类似的地方,那么传统的面向对象编程和面向组件编程有什么区别呢?简单的说,面向对象关注的是组合在一个二进制可执行文件中的各个类的关系,而面向组件的编程关注的是在彼此独立的基础上模块之间的交互性,这种交互性使得你并不需要熟悉它们内部的工作原理。
面向对象技术的基础是封装--接口与实现分离,面向对象的核心是多态--这是接口和实现分离的更高级升华,使得在运行时可以动态根据条件来选择隐藏在接口后面的实现,面向对象的表现形式是类和继承。面向对象的主要目标是使系统对象化,良好的对象化的结果,就是系统的各部分更加清晰化,耦合度大大降低。
组件技术的主要目标是复用--粗粒度的复用,这不是类的复用,而是组件的复用,如一个dll、一个中间件,甚至一个框架。一个组件可以有一个类或多个类及其它元素(枚举、)组成,但是组件有个很明oo显的特征,就是它是一个独立的物理单元,经常以非源码的形式(如二进制,IL)存在。一个完整的组件中一般有一个主类,而其它的类和元素都是为了支持该主类的功能实现而存在的。
Java
Database and SQL
Efficient Pagination Using MySQL
SOA
基于设计的组件:首先:SOA和基于设计的组件不一样。在一个SOA架构中的服务是分布式的。而基于设计的组件中的这些组件是代码片段,通过他们所处每个系统来打包这些片段。从这种意义上来讲,EJB 能够作为服务和组件。
基于重用的组件通常比基于重用的服务简单。在服务重用时,在重用组件中变更带来的影响更是难以控制。其中可能有使用我的服务以及我没有关注的系统。在组件中,也许也是这种情况,但每个系统不得不有意识的做决定来升级组件,所以在一个系统中任何意外的破坏都与系统中那个早期的变更有关系。
耦合:这是“耦合”的真正意义。如果一个系统的改变很可能需要另一个系统的改变,那这两个系统是紧耦合的。这是一个很难通过观察代码来衡量的标准,然而很多人相信可以用代码的度量来理解耦合。
其他
Daniel-Journey Weekly Dose-2010/4/4
Java
WEB
Linux
Linux内存模型
查看方式有两种,一种是直接输入umask,可以看到数字类型的权限设置分数,一种是加入 -S(Symbolic)参数,就会以符号类型的方式显示权限。
在默认权限的属性上,目录与文件是不一样的。由于我们不希望文件具有可执行的权力,默认情况中,文件是没有可执行(x)权限的。因此:
• 若用户建立为”文件”则默认“没有可执行(x)项目”,即只有rw这两个项目,也就是最大为666分,默认属性如下:
-rw-rw-rw-
• 若用户建立为”目录”,则由于x与是否可以进入此目录有关,因此默认为所有权限均开放,即为777分,默认属性如下:umask指定的是“该默认值需要减掉的权限”。因为r、w、x分别是4、2、1,所以。也就是说,当要去掉能写的权限,就是输入2,而如果要去掉能读的权限,也就是4,那么要去掉读与写的权限,也就是6,
Architecture & Design
IOU 思想是人们在处理日常债务关系时行之有效的一种方法,即:
- 债务人通过可靠的第三方保管账户,向债权人发放 IOU 债务凭证;
- 债务人通过向第三方保管账户提交结果以终止 IOU 债务;
- 债权人凭此 IOU 债务凭证通过第三方保管账户履行债权并进行结果赎回。
债务人和债权人之间的债务关系,通过可靠的第三方保管账户,实现了在时间和空间上最大程度的分离和解耦。
IOU 设计模式是 IOU 思想在软件设计领域的应用,最早由 Allan Vermeulen 于 1996 年首次提出。在软件设计领域,债务关系发生在方法调用者和方法体之间,债务对象就是方法的返回结果。普通方法的调用模型是方法体同步执行然后返回结果,调用者必须等待结果返回后才能继续执行。在 IOU 设计模式下,方法体将立即返回一个 IOU 对象,并且承诺 IOU 对象最终一定会被终止,调用者在 IOU 对象被终止后可进行结果的赎回。在此期间,调用者无需等待就能够继续进行其它有价值的事务,从而达到了提高程序整体的并发性和异步性的目的。
IOU 设计模式完全不依赖于任何一种异步机制,IOU 对象的提供者可以选择任意有效的方式来执行服务并最终终止 IOU 对象,比如启用独立的线程/进程执行、驱动异步事件产生、通过远程方法调用或是等待用户终端输入等等。这是 IOU 模式具备普遍适用性的一个重要因素。
SOA
Services Applications Perform a single or a few specialized operations. Perform a wide range of operations, and may even expose some of these operations as services. Most often accessed by other programs. Often (but not always) accessed by humans. Often (but not always) targets part of a larger problem domain. Often (but not always) targets a whole problem domain.
Java参考书…持续补充中
初级读物
关于Java入门的书籍现在已经很少阅读了,下面的几本应该是之前读过的书中算不错的。
虽然是一本SCJP的入门参考书,但语法讲解的很详细,做为新手打好基础是再好不过了。不过书有点老,应该不包含Java5中引入的新特性。
专门介绍Java5的新特性,这些特性是在太重要了,足够一本书来描述。
中级读物
Java Persistence with Hibernate
Hibernate可以说是Java 最成功的ORM框架了,相关的书籍不少,但读了以后能让人知其所以然的书也就这一本了,原因很简单因为该书的作者之一就是Hibernate之父Gavin King.
Jakarta的common工具类不但可以提高你的生产效率,另外通过阅读源代码也能增进开发水平。
单元测试已经是一门成熟的、并且普遍要求Java工程师掌握的工具,这本书介绍的是一个主流的单元测试框架TestNG的使用。
这本书介绍的是另一个Java单元测试框架Junit。
本书的作者Doug Lea 包办了java.util.concurrent包中绝大多数的代码。如果想学习Java并发编程,这本书哪有不看的道理。
获得16届Jolt大奖提名!最畅销图书!对并发、多线程的最佳阐述!Java并发编程图书中最值得一读的力作!让您沉着、踏实地迈进并发/多核时代!
高级读物
非常棒的一本书,只是理解和掌握其中的内容需要实际的开发经验和对java语言的充分理解,所以把它评定到高级读物中。
Expert One-on-One J2EE Development without EJB中文版
Expert One-on-One J2EE Design and Development
搞Java的应该没有人不知道Spring的吧,这两本书是Spring 主要创始人Rod Johnson的作品,绝对值得一读。Expert One-on-One J2EE Development without EJB有中文版 ,Expert One-on-One J2EE Design and Development的中文版式我读过的最差的中文翻译书之一,有好几个地方都在误导读者,对这本书有兴趣的同学还是读原文的比较实在。
To Be Continued
HotSpot Java常用工具介绍-jps(Java Virtual Machine Process Status Tool)
jps介绍
jps简单理解就是一个java版的ps,用来提供一些简单的jvm信息(进程ID,进程启动的路径,命令行参数等等)。jps的语法格式如下
jps [ options ] [ hostid ]
options-- 命令行参数 ,可选
-q 不输出classname 或JARfilename –-m 输出main 方法的参数-l 输出main class的类全名(包含package)或者jar的全路径-v(小写) JVM输入参数-V(大写) 输出通过标志文件传给JVM的参数
hostId是符合[protocol:][[//]hostname][:port][/servername]语法的字符串。
protocol:协议,缺省时rmi
hostname:主机名或IP地址,如果主机名忽略,就是localhost
port: 端口
如果hostId为空,jps会列出locahost上的Jvm进程信息。
命令输出
lvmid [ [ classname | JARfilename | "Unknown"] [ arg* ] [ jvmarg* ] ]lvmId lvm进程IDclassname JVM启动类名jarfilename JVM启动的jar文件名arg* 命令行参数jvmarg jvm参数
参考资料
http://java.sun.com/javase/6/docs/technotes/tools/share/jps.html
BeanUtils的copyProperties,populate实现方式分析以及容易引发的Bug
BeanUtils的copyProperties方法用来将orig中的成员变量的值复制给dest,即将已经存在的dest变为orig的副本。
public void copyProperties(Object dest, Object orig) {
.......
}
BeanUtils的populate方法用来将Map<Key,value>中的以值(String或String[])转换到目标bean对应的属性中,Map中的Key是目标bean的属性名。
public static void populate(Object bean, Map properties){
……
}
copyProperties同样支持了populate中的功能(注apache的javadoc中,明确指明这个方法是为解析http请求参数特别定义和使用的,在正常的使用中不推荐使用.他们推荐使用BeanUtils.copyProperties方法)。
BeanUtils.copyProperties和populate的实现方法是将源bean(也可以是Map)中的每个element在转换器(Converter)的帮助下,将转换的结果设置到目标bean对应的属性中。例如在HTTP 应用中需要从http request中抽取数据,http request传递过来的都是String 或是String数组类型的变量而目标类型可能是各种各样的,例如http request会有一个name=visitDate,value=’2009-05-13′的参数,而目标bean 的visitDate属性的类型是java.util.Date。
BeanUtils的copyProperties和populate需要在转换器(converter)的配合下实现源和目标对象之间的数据类型的转换。在BeanUtils.copyProperties 的javadoc中说明的(Copy property values from the origin bean to the destination bean for all cases where the property names are the same—— 只要属性名相同就可以从源bean中拷贝值到目标bean中)这句话提供到功能就是要通过转换器才能实现的。在BeanUtils的 copyProperties和populate的使用过程中Converter是一个非常重要的概念,它提供了强大的扩展能力。
/****************************************************************/
public interface Converter {
public Object convert(Class type, Object value);
}
/****************************************************************/
convert方法的参数type是目标转换的类型,参数value是被转换的值,返回值就是转换以后的结果。当有需要自定义或扩展的Converter 的时候可以通过注册自定义的转换器来实现,例如Beanutil自带的DateConverter不支持String到java.util.Date的转换,通过扩展DateConverter就可以实现支持。需要特别注意的是Converter 是注册在classloader一级的,也就是说在一个class loader中同一时间只能有一个转换器起作用(BeanUtils的copyProperties和populate会依据目标bean属性的类型来决定启用那个转换器),我之前的项目中就有因为其他模块中在特定的时候会重新注册了某个类型的转换器,而新注册的转换器又没有支持我所需要的转换,从而导致在我的模块中出现NPE。 所以在使用BeanUtils.populate和copyProperties的时候要注意以下几点:
1. 只在系统初始化的时候注册一个转换器,而不要在某个功能的执行过程中注册转换器。
2. 转换器要能够支持项目各个模块的使用需求
3. 谨慎使用或者思考一下BeanUtils.populate和copyProperties是你想要的方法吗?
在我使用BeanUtils.populate的模块中本意是实现bean和Map的属性拷贝并不需要类型和值的转换。至于说为什么会使用 BeanUtils.populate完全是被它支持Map所误导,其实PropertyUtilsBean.copyProperties和 BeanUtils.copyProperties同样支持Map。就我想要实现的功能而言通过 PropertyUtilsBean.copyProperties方法能更好地满足。 PropertyUtilsBean.copyProperties方法不会有类型转换的逻辑,所以需要程序员自己保证目标和源Bean属性间的兼容性,也正因为如此PropertyUtilsBean.copyProperties的执行效率更高。
参考资料
BeanUtils.copyProperties与PropertyUtils.copyProperties用法及区别l
http://commons.apache.org/beanutils/v1.8.0/apidocs/org/apache/commons/beanutils/BeanUtils.html







