置顶随笔
今年开始,我投身于建设SAAS平台。我说,要做到紧跟业界主流,同时要有所创新。
最近几天遭遇一些麻烦事,但我尽力排除干扰,继续前行。今晚我终于有了想法,想通了怎样做!虽未完善,但是大框架已经想通。
很高兴,庆祝一下!!!!
2009年4月3日
今年开始,我投身于建设SAAS平台。我说,要做到紧跟业界主流,同时要有所创新。
最近几天遭遇一些麻烦事,但我尽力排除干扰,继续前行。今晚我终于有了想法,想通了怎样做!虽未完善,但是大框架已经想通。
很高兴,庆祝一下!!!!
2009年1月19日
17日召开金蝶集团员工大会,我很荣幸获得了“10大优秀员工”称号,这是我第二次获得公司的“十大优秀员工”称号,谢谢各位同事对我工作的认可。
谢谢给我投票的兄弟姐妹,谢谢帮我拉票的同事,谢谢杨波、郑伟彤、黄晔、文然等等,特别谢谢在博客上发文为我拉票的Duke Chen。
2008年,我的工作成果在于SAAS 2.0技术架构、核心组件、开发工具以及开发管理四个方面取得较大进展,为友商网SAAS 2.0的开发打好了基础。友商网SAAS 2.0在技术方面基本做到了“紧跟业界先进技术,在核心组件方面有创新突破”。自以为,08年的优秀员工称号,我当之无愧!
2009年,我将把精力放在建设SAAS平台。我将坚持“紧跟业界先进技术,在核心组件方面有创新突破”。作为查拉图斯特拉的追随者,我将继续超越自我。
2009年1月5日
现在很多开源项目在使用LOG的时候做了不好的示范--在基类中实例化的方式使用LOG,而不是静态变量。
例如:
class Base {
private final static Log LOG = LogFactory.getLog(this.getClass());
}
class Derived {
public void foo() {
if (LOG.isDebugEnabled()) LOG.debug("foo");
}
}
这种用法,当类被继承的时候,LOG就完全乱了。spring、struts都有这样的问题。
正确的使用方式应该是直接静态化声明LOG。
例如:
class DerivedA {
private final static Log LOG = LogFactory.getLog(DerivedA.class);
}
2008年12月19日
12月19日,2009年也快过去了。年初时豪言壮语,但实际的情况是知易难行,一年努力下来,还是做了不少事情。
今年的职务已经是总体架构师了,曾经何时我还说,我更喜欢做coder,最崇拜的人是Bill Joy。但是,能力越大,责任就越大,就要参与和决定一些事情了。
在以前,我一直作为技术尖子的角色,做过很多关键技术模块的攻关,例如多数据库支持引擎、工作流、单据转换引擎、短信网关等等,有被人称颂的成功,也有被人痛骂的教训。每次的经验和教训都让我成长,掌握的知识也变得更广。编写代码、开发管理、程序运维等方面都积累了一些知识。我经常思考以前经历过的一些项目一些基础引擎开发的经验和教训,想如何避免以前遇到的一些失败教训。友商网SAAS 2.0的开发,给了我一次机会,作为架构师的角色,去设计一个系统的技术架构和开发管理方法。
我很推崇“产生式编程”的思想,在ORMapping方面有自己的想法,在这次的机会中,可以一展抱负。有机会实现自己的想法,是很幸运的事情。我很投入,很努力。
作为架构师,我的特点就是对底层细节更了解,我一直都是认为“细节决定成败”,“魔鬼总是在细节中”。关注的面也就很多,从技术选型、系统分层、运行引擎、代码风格、配置文件结构、关键基础模块的算法、工程依赖、开发环境、知识共享方式、BUG管理方式、源代码管理、测试覆盖率、日构建、部署、运行监控等等。这些方面都或者参与,或者实现,或者决策。
我还充当技术尖子和软件配置管理员的角色,下面是我在这两个角色方面的一些成果:
多租户数据隔离技术的实现,在JDBC Driver层拦截SQL,安全高性能实现多租户数据隔离,业界领先,独此一家,已申请专利。此技术解决了多租户系统开发过程中开发人员容易漏写过隔离条件导致的“串数据不安全”和“全表扫描低效率”的问题。从而使得SAAS 2.0开发过程中完全解决了多租户数据隔离问题。
搭建了一整套SAAS 2.0开环境,定义了开发流程。将产生式编程、Maven开发管理等业界先进的研发技术引入到研发过程中。将元数据管理、代码生成、工具重构、日构建、软件制品(artifact)仓库、测试等多个部分紧密集成,极大提高了开发效率。
开发工具“利维坦”,是一个实现“产生式编程”思想的Eclipse插件。能够生成数据库、ibatis配置文件、DAO Java代码、Service层Java代码、多语言资源文件等,和Eclipse紧密集成,在代码生成后自动检查和修改spring和ibatis的配置文件,并且能够元数据级重构,添加字段和删除字段,工具能够修改,极大提高了开发效率。
独立开发了同时支持产生模式和解释模式的ORMapping引擎,支持功能完备的OQL,包括子查询、分页查询等等。能够在多租户系统中支持扩展字段。是SAAS 2.0系统中用户自定义高级功能的引擎部分。
在多个技术关键点取得突破,包括每秒钟能够产生100万唯一数的64位唯一ID生成算法、多租户环境下的用户自定义字段解决方案、扩展性更好的JSON库等。
2008年9月8日
很多人谈架构师,其实有两种架构师,一种是业务架构,一种是技术架构。我的经验和教训局限于技术架构,所以本文特指技术架构师。
毕业前一年,毕业后7年,大约8年的技术领域经验和教训,参加过大小项目若干,有被人传颂的成功经验,也有惨痛的失败教训。在以前一直作为技术尖子,在不同的领域逐步填充各方面的知识,最近一年开始做架构设计。以下是我的一些看法。
技术架构师要有责任心
比如说,过去经历过的一个大项目(数百开发人员,基础引擎数十人),这个大项目有一个基础模块,早期设计不良,有比较严重的性能问题,结构混乱,职责不清,很多人早期就发现了这个问题,众所周知。但是一直没改,说法是,改动的成本太大了,其他的部分要跟着改。但是,越晚改定,付出的成本就会越多。这个基础组件的在随后导致了多个严重问题,包括性能问题(占用内存多),开发效率问题(结构混乱,使用麻烦),等等。多年后,还问起这个组件时候,相关的同事都说,某某组件太烂了,没办法改啦。经常会想起这件事,想这究竟为什么会这样,怎么解决他。责任心是其中最重要的问题,当时的技术架构师没有负责任把这件事情解决了,让他拖下去。
谈到技术架构师的素质,当然要技术功底深厚,但这是基本素质,不是关键素质。我认为技术架构师的关键素质是责任心。作为架构师,你来设计这个架构,它是你的心血,你要“爱”它,为它的长久发展打好基础,甚至牺牲一些短期利益。
我们都是在成长的,经常遇到机会,做超出自己能力范围的事情,架构师在设计第一个架构时,甚至第N个架构师时,都有可能是超出自己能力了,然后在实际的工作中,把能力逐步提高。早期的设计可能是不够好的设计,同时已经应用在实现中了,但是你的能力随后提升了,认识到其中的问题了,你需要改正它,改正是需要成本的,作为架构师,要有责任心,敢于承担责任,对过错负责,把他改过来。
很多项目的顽症都是没有人敢于承担责任留下来的!而作为架构师,就一定要负责任,为万世开太平!
技术架构师要有坚持
有一次,我做了技术架构方面的一个方案,要执行它,大家(包括一些经理)都持反对态度,但是我最终一意孤行,坚决推行,最终取得非常好的效果,成为这个技术架构中最关键的技术之一。
作为技术架构师,可能你在团队中技术把握能力最好,比其他人思考的更多。如果你相信你的技术决定一定正确,那你就坚决推行它,不顾政治,不顾诸神!
遇到不擅长的问题怎么办?
作为架构师,面临的问题多方面,总会又遇到不擅长的领域,这时候,找其他同事,征求他们的决定,一起制定方案,或者干脆完全把决定权交给擅长这方面的同事。一定不要不懂装懂,外行管内行。
做错了,怎么办?
总会有做错的事情,怎么办呢?不要太顾面子,少找借口,接受批评,迅速改进。挨打要立正!别人也不会因为你一个错误而否定你全部的。根据经验,做错了事情然后改进的人,通常更受重用。原因是,错误发生了,领导们知道这个问题的难度,你解决了,就说明你解决了一个有难度的问题。
要深入了解实际情况
Ivar Jacobson最近讲到技术架构师,说执行代码比宏观架构更重要。古今中外,有一个共同的道理,就是细节决定成败。也有说法是“魔鬼总是在细节中”。架构的一些问题总是反映在实现细节中,或者使用细节中。作为技术架构师,你最好能够经常阅读使用架构的开发人员的实际使用情况,打开工程,阅读代码,然后把程序跑起来,观察执行情况。在最近作的一个技术架构中,其中多项重要的技术方案,都是观察了开发人员的代码之后总结然后做的改进方案。
技术架构师要面临的技术细节很多,例如分层细节,数据库命名规范,代码规范,spring配置文件管理,ibatis配置文件管理,日志输出规范,findbugs定期检查,作Eclipse插件把一些技术方案固化下来,经常维护wiki知识库,作code review,整理项目依赖,日构建制品输出管理,等等。每个具体项目的细节都不一样,细节处理不好,就会产生“魔鬼”。
2008年6月5日
摘要: 我们在开发中,经常需要遍历一个目录下的所有文件,常用的办法就是使用一个函数递归遍历是常用的办法。但是递归函数的缺点就是扩展不方便,当然你对这个函数加入一个参数FileHandler,这样扩展性稍好一些,但是仍然不够好,比如说,不能根据遍历的需要中途停止遍历,加入Filter等等。我实现了一个FileIterator,使得遍历一个目录下的文件如何遍历一个集合中的元素一般操作。
阅读全文
2008年3月8日
在新项目中,除了一些框架所依赖的配置文件使用XML外,基本没有使用XML。JSON基本替代了原来XML在程序内的位置。在以前,我们不愿意使用一种私有的格式,于是选择了XML。选择XML的理由,可能是大家都用它,所以我们也用它。
XML是一种很好的技术,但是目前的情况来看,XML被滥用了,SOAP是XML被滥用的一种典型,程序内部的表示使用XML也是滥用的一种典型。看到的一种情况,一个对象toString使用XML格式输出,导致日志文件十分罗嗦,调试时,在watch窗口中看到一大堆<tag>。
在新项目中,认真考虑这种情况,找到了另外一种选择,那就是JSON。选择JSON的理由很充分:
1、JSON的解释性能要比XML要好,要简洁紧凑。
2、可读性要比XML好。JSON本身就是JavaScript的语法,和程序员的思维,而非文档编写的思维。
3、JavaScript原生支持,客户端浏览器不需要为此使用额外的解释器,在web环境中使用特别合适。
在java中使用json,目前需要注意一些情况:
1、目前开源的JSON-LIB代码质量不好,最好是在此基础之上修改一个版本,或者自己重新开发一个版本。
2、使用new Date的方式替代JSON-LIB中的{year:2007, month:12, ....}之类的方式
3、JSON-LIB中,object的propertyName在输出的时候,都带上"",例如{"name": "温少"}, 其中name是的双引号是不必要的,在输出时应该判断,不需要的就是就不加上"",减少网络流量。
4、JSON的解释器中,应该支持简单的表达式,例如new Date()、new Date(2939234723)之类的,这使得JSON的表达能力会更强一些。
5、JSON应该分两种,一种只支持简单格式,类似开源的JSON-LIB,一种是通过JavaScript解释器来实现的。后者在程序中传输数据时,能够得到更强大的表达能力,但是也会导致安全问题,需要慎重使用。
2008年2月9日
1、XP中的结对编程。XP编程中,有一些思想总结的很好,例如测试驱动,但又有极度的荒唐的就是结对编程。结对编程是我看到过的最荒唐最可笑的软件工程方法,两倍的投入,一半的产出,可谓事倍功半。以前看结对编程只是觉得荒唐可笑,后来看了李安的电影《断背山》,觉得以“断背”来形容结对编程最适合了,结对编程简直就是专门为“男同志”们度身定做的软件工程方法,你想一对“男同志”,每天手牵手背靠背进行“结对编程”,是多么“浪漫有趣”的事情。不过这只对“男同志”们的浪漫有趣,对工作本身一点也不有趣!
--------------
2、JDO投票闹剧(2004-2005)。一个通过黑客式静态AOP方式旁门左道实现的持久化技术JDO,竟然会被一些人追捧,这本身就是一个很荒唐的事情了。在JCP的投票中,JDO被否决了,这一点也不奇怪,奇怪的是投票结果出来之后的闹剧。一些人以“政治阴谋论”来说事,说JDO不被通过,是因为政治原因,而非技术原因,这个荒唐的理由竟然被社区的很多人相信了,一片声讨,JCP迫于压力,重新投票,通过了JDO相关的JSR。但是JDO并没有因此有一点点起色,一直沉沦至今。JDO通过静态AOP(enhance)的方式使得代码无法调试,就单这一点,就足以使JDO永远无法流行。
这件事情很明确表明两点:1)、不要相信一些技术作家的判断力;2)、普通的大众没有判断能力,会人云亦云。
当年荒唐的文章选录:
《程序员》2005年第2期 http://blog.csdn.net/gigix/archive/2005/01/21/262163.aspx
---------------
2008年2月2日
竟然64个annotation,没有分类,放在同一个package下,同一个package(javax.persistance)还有其他java文件,共有88个java文件。不看内容本身,单从表面,都觉得这是混乱不堪的事情。这是那个猪头的杰作?glassfish上下载的源码中,这些java文件似乎都没有author,估计也不好意思把名字放出来见人吧!
------
觉得对象关系存储方面一直没有突破,也没有好的产品出来,其中一个原因,就是从没有过优秀的工程师投身过这个领域。关系数据库为什么能够一直坚守领地,成为绝大多数商业应用的基石,其中一个原因就是有过大量的精英投身于此,包括两个图灵奖获得者。
关系数据库,为了描述关系,创造一门SQL语言,将关系一些操作,例如投影(select)、选择(where)、分组(group by)等等,抽象得形象易懂,功能强大。对于数据的操作,SQL语言是最强大,也是最方便的,也是最易于使用的。一些非程序员的IT从业人员,非计算机专业的人员都能够熟练掌握SQL。
OO和Relational都是伟大的技术,从计算机最高荣誉奖可以看出这两个技术的伟大。OO的图灵奖获得者是三个,Relational的图灵奖获得者是两个。
面向对象技术自1967年simula引进依赖,所想披靡,93年-98年从C++开始流行,然后到Java,成为主流编程技术。Relational没有OO那么辉煌,但是在数据存储方面的地位固如磐石,长期占据绝对的地位。
曾经OO技术涉足于数据存储领域,但终究没有成功。面向对象数据库的变现总是差强人意,面向对象的方式操作数据,总是不如使用关系那么方便,那么灵活,那么易于使用,那么好的性能。于是人们在数据存储和处理方面,不在青睐面向对象技术,而是仍然使用关系方式,使用SQL语言,使用关系运算操作数据。面向对象数据库成了昙花一现的东西,并且可能永远都不会再流行了。
OO成了主流编程技术,Relational占据了绝对的数据存储地位,这两大技术需要交互,需要桥接,这需要OR-Mapping。Relational虽然好,但我们也要与时俱进,所以也需要OR-Mapping。
但是,做OR-Mapping时,不积极吸取relational方式对数据处理的灵活性、方便性、简单性,而只强调Relational和对象之间的的Mapping,试图以面向对象的方式操作数据,这是错误的方向。以前的EJB、现在Hibernate、JPA都犯了同样的错误,试图以更面向对象的方式操作数据,从而导致复杂混乱的模型,这也是JPA的现状吧。例如user.getGroup(),目前的ORM试图以纯OO的方式操作数据,所引起的LazyLoad、n+1等问题,使得事情变得复杂而且混乱不堪。
一些开发人员,去学习Hibernate,不学习SQL,有人提倡,只需要了解面向对象编程技术,不需要了解关系技术,亦属于本末倒置。需求人员都会用的SQL语言,对数据操作最方便最简单最强大的SQL语言,竟然成了令人生畏的纸老虎,可笑啊。
-------------
以下是过去的一些业界浮躁不理智:
1、面向对象数据库。曾被热衷而吹捧,面向对象数据库的变现总是差强人意,面向对象的方式操作数据,总是不如使用关系那么方便,那么灵活,那么易于使用,那么好的性能。于是人们在数据存储和处
理方面,不在青睐面向对象技术,而是仍然使用关系方式,使用SQL语言,使用关系运算操作数据。面向对象数据库成了昙花一现的东西,并且可能永远都不会再
流行了。
2、JDO投票闹剧。2004-2005年,JDO的JSR在JCP投票被否决的,无聊者在Java社区以及媒体发起闹事,阴谋论其为政治谋杀,几大公司是的迫于形象,重新投票使得JDO被通过,但JDO这种静态AOP叫雕虫小计式技术,不单开发过程不方便,而且会使得"enhance"之后的代码不可调试。这完全是对开发者不友好的技术,没有前途的技术,竟然会有人为它在JCP投票不通过鸣不平。这件事情使得我更坚信一点,不要相信那些技术编辑的判断力。
3、AOP。也是最近这几年流行的一个名词了。起了一个和OOP相似的名字,但是和伟大的OOP相比,它完全不算是什么。AOP只是一种很小很小的技巧而已,静态的AOP是黑客式的插入代码,会导致代码不可调试,动态的AOP能力有限,AOP最常被引用例子“日志AOP”是不合适,有用的日志通常是精心设计的,AOP方式的日志在生产环境中基本上是不可用。OO这么多年,这么为伟大,人们总是希望自己能做点什么和伟大的OO相比,于是命名为AOP,这是一个可笑的名字,前些年还有人谈论面向对象的未来是面向事实,也是同样的可笑。AOP有价值,但它是一种小技巧,和名字不般配。
--------------
目前在流行,但是可能是不理智的技术:
1、hibernate之类的ORM,试图以面向对象方式操作数据,和面向对象数据库一样,重蹈覆辙。
2、Ruby,一个小脚本语言,只是因为动态类型、mixin之类的功能,还没有被证明有生产力,有效益可用的脚本语言,就被媒体吹到天上去。Ruby有价值,但是最终结果会离大家的期待相差甚远。
2008年1月27日
又是新年,我有了宏大的计划,有了宏大的目标。
我要创造一个伟大产品,开创一个新的技术时代!
我已经开始在做了,我一定会成功!