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

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

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

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

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

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

 

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

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

 

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

 

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

利用周末的空闲时间,了解了下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 的特点: 

    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容器。 

我们来看看 Set的一个实现HashSet中的add方法,HashSet内部使用一个HashMap来存放对象, 
HashSet把要保存的对象做为其内部HashMap的key,如下: 

Java代码 
  1. //PRESENT为一个辅助的Object型对象  
  2. public boolean add(E o) {  
  3.     return map.put(o, PRESENT)==null;  
  4.     }  

如果有两个对象A,B, A.equals(B)返回ture,则 
A和B只会有一个被保存在set中。 
在HashMap中判断两个key相同的逻辑是 hashcode()相等并且 equals()返回true。 

再看看HashMap中的put()

Java代码 
  1. public V put(K key, V value) {  
  2.     if (key == null)  
  3.         return putForNullKey(value);  
  4.         int hash = hash(key.hashCode());  
  5.         int i = indexFor(hash, table.length);  
  6.         for (Entry e = table[i]; e != null; e = e.next) {  
  7.             Object k;  
  8.             /** 
  9.             * 因为A.equals(B)为true,故A.hashCode() == B.hashCode(); 
  10.             * 故会进入到下面的if块内部,从而保证了A和B只有一个被保存在Set里 
  11.             */      
  12.         if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {  
  13.                 V oldValue = e.value;  
  14.                 e.value = value;  
  15.                 e.recordAccess(this);  
  16.                 return oldValue;  
  17.             }  
  18.         }  
  19.   
  20.         modCount++;  
  21.         addEntry(hash, key, value, i);  
  22.         return null;  
  23.     }  

 

if (e.hash == hash && ((k = e.key) == key || key.equals(k))) 中,只有hashcode相等时 

才会调用后面的key.equals(k) 

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. 

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