2010年度总结

已经是2011年的第三天了,这几天在家疯狂地玩,现在才慢慢静下心来,回顾一下这一年的付出与收获,也得做 一下下一年的规划了。

性能优化:从09年末开始,我开始接手产品性能优化的工作,一开始,我对性能优化的知识几乎是一无所知,跟着一个设计管理部的专家慢慢摸索,我渐渐找到了一套定位性能问题的思路。然而,在参加了两个版本的性能优化工作后,我发现我遇到瓶颈了:产品所用的技术、架构有了瓶颈,靠修改代码、调整系统参数的方式已经无法解决,也没有人可以求助。因此,11年我的计划是:加深操作系统、网络方面基础知识的学习,了解业界其他先进的产品的架构设计经验,提升自己对高并发系统架构把控的能力。

 

 

    敏捷实践:从一开始接触敏捷概念时,我就疯狂的迷恋上这样的软件开发理念;它可以尽可能地减少产品开发过程中的浪费,而且可以让开发、测试人员很“爽”地去工作。于是我一本本读了敏捷开发的经典书籍:Kent Back的《TDD》、Bob大叔的 《敏捷开发:原则,模式与实践》以及Martin Folwer的《重构:改善既有代码的设计》,阅读这些大师的作品的过程,也是与这世界上顶尖的程序员、架构师进行心灵对话的过程,从他们的字里行间,可以看出他们对于软件开发优秀实践的执着的追求,而且,他们很乐意把自己的想法分享给更多的人。在平时的开发过程中,我也在尝试这样的实践,曾经有机会得到一个ThoughtWorker的指点,虽然只有短短的一小时,他那严谨的态度,对事情精益求精的态度,着实令人敬佩,作为一个代码的完美主义者,我希望有一天也可以成为像他们一样顶尖的Coder,加油。

     做人:人进入社会以后,他就是个社会人,他对他周边的每个人,无论是认识的,还是不认识的人,都会产生影响,我的最基本的原则是:“尊重别人,然后让别人尊重自己”。 无论他是你的同事,还是你的朋友,还是你的家人,还是公交车售票员、还是10000号的话务员、还是路边的一个可怜的乞丐。带着一颗博爱、感恩的心,尊重他们,爱护他们。今年,看过一部温暖、感人的电影——《唐山大地震》,今天又重新温习了一遍,在大灾大难面前,普通人之间的互助、友爱感动着我,希望平时能够看到更多这样的感动。

    个人:2010年春节在家订婚了,今年家里开始催着结婚,感谢我亲爱的她,每天工作累的时候,回家与她逗逗嘴,一切不开心就烟消云散了,她就是我的开心果,她真的是一个很漂亮、很可爱、很体贴的女孩,还有我的岳父岳母、小姨子,都是性格很好的人,能够娶到这样的好老婆,心满意足了。10月份拍了婚纱照,挺漂亮的,计划明年结婚,后年养娃。只是——买房的事情还没有着落,家里条件一般,肯定帮不上忙,只有靠自己,到现在首付还没凑齐,继续努力。

 

总结就写到这儿,工作、生活都有了,最后送自己一句话: 提升视野,开阔眼界,突破瓶颈、继续成长、努力工作,快乐生活。

 

 

 

梦想/目标

今天项目组例会中,老大发起了一项写出你的梦想、目标的活动,在想了一会儿后,我写下了下面三个梦想、目标:

1) 找个安静、漂亮的地方和老婆一起去散散心,陶冶一下心灵。

2)能够拥有一台自己的油动飞机模型,并且有时间去玩。

3) 在目前工作的领域能够有所建树,能够成为一名成功的coderarchitect

对于第一个目标,我有很深的体会:在今年10月份的时候,我们的项目还处在一个比较紧急的时期,我们去安徽石台玩了两天,满眼的青山绿水,那两天刚好都在下着毛毛细雨,几乎所有的山上都是云雾缭绕,像是到了仙境,再深的水也是清澈见底的,偶尔会碰到买山货的纯朴山民,我被眼前的美景吸引着,压在心头的各种烦心事也很快烟消云散了。很遗憾没能带老婆去,要是能有她一起来看这样的美景,那就太好了。所以,想找个机会和老婆一起出去散散心,暂时逃离这喧嚣的城市,平静一下自己浮躁的心灵。

    我时常对老婆说起一个让我神往的场景:当我累了的时候,能够在一个有着温暖阳光的冬日里,在老家的院子里,裹着个大棉袄,眯着眼睛晒太阳,哪儿痒了就拿个痒挠儿挠两下……  多么惬意。

 

第二个目标,小时候就非常喜欢飞机,由于家里条件不好,只好自己做模型飞机,做了无数个纸飞机、木飞机,有橡皮筋动力的、有滑翔机等等,高考时候还差点填报了西工大的飞行器专业,最终出于“计算机学出来好找工作”的考虑,报了计算机,入了软件这行。然而,儿时的梦想依然在心头萦绕,今年买了个电动的直升飞机,由于工作时间紧张,没有时间练习,只在屋子里飞了几次就摔坏了,很是心疼。希望自己能够有机会拥有自己的油动飞机,并且能有时间去飞,完成自己的儿时梦想。

第三个目标,工作也已经3.5年了,算是有了一定的经验积累,目前感觉像是到了第一个天花板,无法再进行一次大的提升。前阵子找老大交流的时候,我也提起此事,老大给的建议是:拓宽视野、提升高度。

 

同事们写的梦想也是千奇百怪:有梦想不工作天天玩游戏的,有梦想周游世界,甚至去太空旅游的,有想减肥的,有想生个漂亮宝宝的。每个人都有自己的梦想,聪明的人都会制定计划,努力实现梦想,在实现梦想的过程中,他的人生就有了意义,他也获得了快乐。祝我亲爱的同事们、朋友们都能够实现自己的梦想,获得自己的快乐。

 

2010年就要结束了,是时候写个总结了,做好计划,迎接新的一年。

No SQL DB初探

利用周末的空闲时间,了解了下Neo4J, Neo4J是一种No SQL DB, No SQL DB是一种和关系型数据库相对应的对象数据库。按照数据模型保存性质将当前NoSQL分为四种:

  1. Key-value stores键值存储, 保存keys+BLOBs
  2. Table-oriented 面向表, 主要有Google的BigTable和Cassandra.
  3. Document-oriented面向文本, 文本是一种类似XML文档,MongoDB 和 CouchDB
  4. Graph-oriented 面向图论. 如Neo4J.

关系型数据库的弊端:

关系型数据库的历史已经有30余年了,因此,在某些情况下,关系型数据库的弱点就会暴露出来:

  1. 对象-关系 阻抗不匹配。关系模型和面向对象模型在概念上存在天然的不匹配的地方,比如对象模型当中特有的继承,组合,聚合,依赖的概念在关系模型当中是不存在的。
  2. 模式演进。即随着时间的推移,需要对数据库模式进行调整以便适应新的需求,然而,对数据库模式的调整是的成本很高的动作,因此很多设计师在系统设计之初会设计一个兼容性很强的数据库模式,以应对将来可能出现的需求,然而在现在的web系统开发过程中,系统的变更更加频繁,几乎无法预先设计出一种万能的数据库模式以满足所有的需求,因此 模式演进的弊端就愈发凸显。
  3. 关系型数据库处理 稀疏表时的性能非常差。
  4. network oriented data 很适合处理 人工智能、社交网络中的一些需求。

所以,各种各样的No SQL DB 出现了,这里只简单介绍下Neo4J 的基本知识。 Neo 数据模型 Neo4J 是一个基于图实现的No SQL DB, 其基本的数据类型有如下几种: Node, Relationship, Property. Node 对应于图中的 节点,Relationship 对应图中的边,Node 和 Relationship 都可以拥有Property, Property 的数据结构为。

数据遍历 Neo 提供了Traverser对数据中的数据进行遍历。

为什么用spring

遇到这个问题时,我突然没有了头绪,使用spring已经接近三年了,也阅读了不少spring的源代码,从中获取了不少的编码灵感,但是却忽略了这个最根本的问题,为什么我们需要spring?很多时候我们就是这样走着走着,确忘记了自己为什么要走这条路…… 
如果走得太远,会不会忘了当初为什么出发? 
总结一下,备忘。 
spring 的特点: 

    1 spring 提供的是管理你的业务对象的方法。 

    2 spring既是全面的,又是模块化的,我们可以选择使用spring中的某个独立的部分。 
    
    3 spring的设计从一开始就是要帮助你编写易于测试的代码(所有的业务对象都是可以独   立于容器运行的,spring提供了大量的mock对象来实现对容器的隔离),是使用测试驱动开发   的工程的理想框架。 

    4 spring不会给你的工程添加对其他框架的依赖。 


spring带给我们的好处: 
    1. spring能够有效地组织中间层对象。 
    
    2. spring能够消除在很多工程中常见的对singleton的过多使用。 
    
    3. 通过一种在不同应用程序和项目之间一致的方法处理配置文件,spring能够消除各种各样自定义格式的属性文件的需要。 
    
    4. 把对面向接口编程而不是面对类编程的代价减少到几乎没有,spring能够促成良好的编程习惯。 
    
    5. spring被设计为让使用它创建的应用尽可能少的依赖于它的APIs。 
    
    6. spring能够使EJB的使用成一个实现选择,而不是必然选择。你能够选择用POJO或者locale EJBs 来实现业务接口,确不影响调用代码。 
    
    7. spring 帮你解决许多问题而无需使用EJB,spring能够提供一种EJB的替换物。如spring能够使用AOP提供声明式事务管理而不通过EJB容器。 

spring中事务管理中的事务传播机制

PROPAGATION_REQUIRES_NEW starts a new, independent "inner" transaction for the given scope. This transaction will be committed or rolled back completely independent from the outer transaction, having its own isolation scope, its own set of locks, etc. The outer transaction will get suspended at the beginning of the inner one, and resumed once the inner one has completed. 

PROPAGATION_REQUIRES_NEW会在当前运行的范围内创建一个全新的内部事务,这个的事务会独立地被提交或回滚(完全独立于外部事务),它拥有自己的隔离级别,以及锁等等。当内部事务被执行时,外部事务会被挂起,知道内部事务结束时才会继续执行。 

Such independent inner transactions are for example used for id generation through manual sequences, where the access to the sequence table should happen in its own transactions, to keep the lock there as short as possible. The goal there is to avoid tying the sequence locks to the (potentially much longer running) outer transaction, with the sequence lock not getting released before completion of the outer transaction. 
这种独立的内部事务会被诸如从序列生成ID的应用中,从序列取得id的动作应该发生在自己的事务内部,并且保持对这个sequence表的锁的时间越短越好。这么做是为了避免在获得ID以后可能仍然在很长时间内持有这个sequence表的锁(外部事务仍在运行中)。 

PROPAGATION_NESTED on the other hand starts a "nested" transaction, which is a true subtransaction of the existing one. What will happen is that a savepoint will be taken at the start of the nested transaction. íf the nested transaction fails, we will roll back to that savepoint. The nested transaction is part of of the outer transaction, so it will only be committed at the end of of the outer transaction. 
PROPAGATION_NESTED启动了一次嵌套的事务(一个当前事务的子事务),在内部嵌套事务开始时,会保留一个保存点(savepoint),如果内部嵌套事务失败,将会回滚到savepoint处,内部嵌套事务是外部事务的一部分,所以只有在外部事务完成时才会被提交。 

Nested transactions essentially allow to try some execution subpaths as subtransactions: rolling back to the state at the beginning of the failed subpath, continuing with another subpath or with the main execution path there - all within one isolated transaction, and not losing any previous work done within the outer transaction. 
嵌套事务可以满足子事务“多路执行”的需求:回滚到失败的内部嵌套事务开始的地方,然后执行另外的一个内部嵌套事务,或者继续执行主事务-上面提及的事务都是独立的,不会丢失外部事务所作的修改。 

For example, consider parsing a very large input file consisting of account transfer blocks: The entire file should essentially be parsed within one transaction, with one single commit at the end. But if a block fails, its transfers need to be rolled back, writing a failure marker somewhere. You could either start over the entire transaction every time a block fails, remembering which blocks to skip - or you mark each block as a nested transaction, only rolling back that specific set of operations, keeping the previous work of the outer transaction. The latter is of course much more efficient, in particular when a block at the end of the file fails. 

例如,分块传输一个很大的文件,整个文件的传输应该放在一个事务内部,在文件传输完成后提交事务。如果一个文件块传输失败了,就需要在某个地方写一个失败标记,然后重新传这个文件块,你可以在每次传输一个文件块失败时重新开始事务,然后记住那些块已经成功传输了,忽略即可-或者你可以把每个文件块的传输作为一个内部嵌套事务,只回滚失败的事务,保存前面事务的更改结果,当然这种方法要有效得多,想像一个最后一个文件块出错的情形。