不是因为cache(提高速度)而管理对象生命周期,而是管理对象生命周期,而去使用cache(或者map,其实可以理解为带管理的容器,到底是数据还是对象,则看context)。在文章提到的情况,使用cache的原因很大程度在于硬件和jvm限制(map或是cache的选择原因)。若果没这些限制,我使用map,那时你还跟我讨论map是什么了么?其实这么想吧,若果cache的淘汰算法,是永不淘汰,它还是不是cache呢?我认为是(观点之前有了),而这时cache就和map同样价值了。试想,必须要淘汰掉数据,对象,实体才能成为cache么?cache不是为了淘汰数据而存在的,而是为了缓存,缓冲存储,也就是解决速度差问题。

“所以对于缓存系统而言,不需要去了解需要缓存什么”这是从里至外的看法,在外界看来,这东西就是缓存对象,就是缓存实体,对于一定的context下,所有基本单元已经不一样了。在文件系统下,cache就是缓存文件,因为若果不知道cache缓存什么东西,你就不能把东西取出来。对于使用者而言,你存入的是文件,拿出来的一定是文件,若果我缓存的东西变质了,它还能用作“存”么?还是那句若果都是数据,还有其他概念么?什么封装,抽象思维都可以不要了。引用banq的“屁股决定脑袋”。

对于“缓存”就是内存,在不改变该context(即前提:Spring,jdon框架上引入cache),此话是对的。首先,我们想想数据,对象什么时候才是活的。我引入系统的进程来说明,进程存在哪里?内存。进程是啥?就是进行着的程序,是运动着的。也就是必须要到达进程中才是活的东西,而cache就是进程中一块存储保存数据(对象)的地方。cache在进程中,进程在内存中,所以cache只是一个有边界的内存。其次,东西不是只有一个角度去观察的,根据我第一段话的意思,可以看出,cache依然带有本身的所有特性,但角度已经是作为带管理的容器了。角度的不同,不是一种否定。一种从技术角度,它依然提供了高效的载体,一种从架构设计角度,它作为带管理的容器,这两者本身并不矛盾。非彼即此的观点,在此并不适用。所以你否定其中一个,在我看来就如同否定全部一样。从技术上我们用到了其高效作用,在架构设计上我们用到其管理作用。既然谈论架构设计,也就没必要再延伸到另外一个角度了。我咋发现banq的“屁股决定脑袋”又再次适用了 - -|||(以上技术指的是支持技术,设计指的是设计思想,如实体概念这些。往往架构中是遵循一种思想,然后所有技术都是用来支持思想,注意是支持,并非决定)

说实话,看你的回帖我就头大,因为我想说的是:不知所云。
缺乏清晰的观点,缺乏抽象的思维,以及缺乏对事物的表达能力,在我的面试中这样的人我是一定不会要的。而且你对《系统原理》没有学好,希望你找一本书来加强这一部分的知识。

对于通篇的理解,我觉得你好像是说系统进程就是缓存??
如果你的结论是这个,那么我无话可说了。因为对于系统进程是什么东西都不知道的人在谈缓存实在没有意义。

一开始以为你连cache都搞错,所以说这么多,原来只是单单的角度问题,也就缩小到这一段。banq经历得比我多,一眼看出你的问题了,表示惭愧。

我还是感到你不会上升思考,转角度思考,基于系统的自然有它系统的说法,但从对象生存思考,是另外一个角度,难道你从来只从一个角度看问题?《系统原理》这书倒没看过,不过相似的书倒是看过。一种是基于底层,基于实现原理思考,一种是抽象思维,上升思维。例如一个技术就放在这里,你把它用作什么?围绕设计而选择技术的支持,但不是因为技术而去想有什么设计。进程在本本上说是那样,于是就没有其他角度理解了?屁股决定脑袋,把屁股多转转,会得到更多。系统原理并没有道出回归自然的想法,何谓回归自然呢?好好想下吧。

引用DCI的说法,角度就如context,每一个Data都有它的一个关于特定context的role说法。好了,既然知道,你是角度问题,那么回复就如上面那样。请记住,一种说法是基于一种场景的。

不知所云,是我误解了意思,表示抱歉。但问题还存在,就简单说:角度问题。可以了?所以你看看,我们并没有否定过你的说法,只是你在否定我们的角度。


PS:banq,咋不能修改回帖了?本想再增加些说明,改不了- -。算了,看得懂就懂,不懂就不懂吧。

补充:因为技术而去想有什么设计,就如你那样想:因为cache在普遍的定义上是缓冲存储数据,所以在你看来,设计上不谈cache。但技术不应该去决定设计的,而是支持设计,也就是DDD这样的设计,需要一个怎么样的东西,然后选择一样东西来支持(如cache和map)。这样就是换角度思考了,技术的定位由设计去决定,如entitycache,是一个实体容器,当然这样的想法是由“空间”这样的思维引导出来的。不要被技术绑定设计啊。


关于“系统进程就是缓存”,当然这需要特定的角度去思考,对象存在于缓存,缓存存在于系统进程,系统进程在于内存。缓存,进程,内存都是缓存对象的。还是说我用数据来代替对象,你就接受了?进程中不是缓存着数据?你尝试结束进程,再给我找回进程中的数据看看?在这个角度看,进程只是一个有边界的内存而已。若果把所有的东西都看作0和1(数据,对象),从这个角度看,你还看出进程还有啥特殊的地方?
[该贴被SpeedVan于2011-03-21 13:28修改过]
[该贴被SpeedVan于2011-03-21 13:30修改过]

没怎么学过计算机或软件的课程(比如系统原理),这方面零碎的知识多半是由于问题或兴趣而偶尔关注形成的,所以我的说法会比较外行一些,勿见怪,仅供讨论、参考。

看书时,把书柜里的书放在书桌上,书桌相对于书柜就是缓存;吃饭时,把锅里的饭盛到碗里,碗相对于锅就是缓存。这里的书或饭相当于计算机中的数据或信息,不过两者有一个显著的区别,现实的物质可以被瓜分尽,而计算机中的信息可被无限复制。

缓存机制的价值在于以尽可能快的方式提供给使用者需要的信息,简单一些就是两点:1)快(访问快) 2)准(被需要)。

快,不言而喻,就I/O的速度更快,如读寄存器比读内存快,读内存比读硬盘快,读硬盘比读外设快(网络硬盘相对本地硬盘,也可以视为一种外设)。寄存器与内存之间也可以加一块缓存,缓冲CPU与内存的I/O速度差。

光快不行,还要准。如果书桌上的书最近一段时间我根本不想看,碗里的饭最近我一点胃口都没有,这样的缓存是帮倒忙,反而可能变慢,还可能使我心情变差。准,或者命中率等别的叫法,是缓存机制隐式的一面,而快是其显式的一面。

准,如何保证命中率,需要制定一套淘汰算法,简单地比如,根据访问时间、使用频率等等进行排序淘汰,复杂的可以通过机器学习构建一个预测模型,用来筛选需要缓存的信息。

缓存与持久,共同点都是存储,不同点前者是暂时的,后者是长久的。而不同点显然是具有相对意义的,永不停机的内存,其存储的信息不丢失,也就变成长久的;被损坏的硬盘,其存储的信息丢失了,也就变成了暂时的。

至于在缓存这个时空中,数据库中的数据与领域中的实体之间互化的过程,与缓存本身可以分开来思考。缓存也可能将数据库的持久化过程与领域中的实体活动独立开来或者异步进行,就像我吃着碗里的饭的同时,可以一边对锅里的饭进行加热一样,这也是缓存的用法。

个人感觉,ACoder的言论更侧重于缓存的“体”,Banq和SpeedVan更侧重于缓存的“用”。“体”即缓存的本意在于提供一个更快、更准的(有限的)信息时空;“用”,即在这个时空中可以进行数形互换(数据与实体的转换)、过程异步(领域活动与持久化过程相对独立)等等。

内存数据库,一直是我想要的东西。停机问题,可以通过各种方式来解决:集群,云等。现在的数据库,只不过是一个有边界的硬盘而已。为什么我们运行游戏快,因为业务逻辑交互都在内存中,不在的话就会loading,loading就会损失实时感。引入cache就是实现这样的一个效果,cache加载淘汰逻辑根据情境来选择,得到的是一个内存数据库的效果。游戏大地图效果,你人物到达特定的区域,cache就会开始加载周围环境信息,只是当中的淘汰算法对于web开发不常见而已。通过这样的方式而达到的命中,还有慢可言?我提出用cache来做web,就是让人们意识到业务逻辑交互都是在内存中,值对象替换,是内存中的对象的值替换,而不是跑去更新数据库,数据库应该是异步进行的,或者你能够确保不停机,而且内存足够大,你可以不要数据库。

说了半天问题又回到了原点:什么是cache?
speedvan,我上次就说你写的内容逻辑不清,自相矛盾,而且缺乏观点。你可以将你写的东西都看一遍,找找到底什么是你想表达的东西?

如果你说cache是内存,那我想你完全搞错了,这完全两码事,按照这个理论根本无需出现cache这个词,所有的程序都需要将数据及程序调入内存,难道hello world是最简单的cache程序?如果cache是持久化,那么前面我也解释清楚了,这两种东西有着不同的设计目的及作用,cache无法替代持久化,但是变通的持久化可以起到一定cache的作用。

我用cache这个词是因选择而生的,我需要一个可管理的对象容器,选择cache是外界制约(都说了用map和cache也可,不过用map就要自己写很多管理,回过头来发现自己写了个cache而已)。

对象加载到内存,是的,的确是加载到内存,但只是使用时而已,不使用(引用)就会被回收。通过容器保存这些对象,则可以避免回收,对象生命周期将掌握在设计者手中。我一直谈论都是以对象存亡的角度来考虑的,从这个角度都会涉及其空间和时间,都会谈到内存和持久化。你从单纯的技术角度进行切割思考,当然不能读出我表达什么。

写一个helloworld,那么空间思维就在“helloworld”这个字符串对象的空间,字符串池就是字符串对象容器,字符串受池的管理。因为字符串用到flyweight,所以空间得到优化。因为一般对象是不使用flyweight,上升到实体概念的话,内部信息更是独立,如账号。可以无限新增的对象,在有限的空间内,是不可控的,于是需要一个受控的管理空间的容器(GC不能由使用者控制的)。

再来看,从硬盘提取数据时耗时的,数据转为对象是耗时的,加上复杂sql的耗时。效率上的失败。所以若果活动前就加载对象,并且活动是纯内存活动,而且没有转换,则会效率明显提高。如何纯内存活动呢?map可以,map就是put和get出对象,在这里map就是一个缓存。把对象提前从硬盘到达内存,同时缓存起来。那么明显地,缓存是在内存中,对象存到缓存也就是缓存到内存了。那么运行程序时,系统是如何的呢?系统是从硬盘加载程序的数据到内存,而且是加载到内存中的程序进程中。这里内存就如缓存,进程就如缓存。其实内存的目的是和缓存相同的,所以可以说内存是一个大缓存。因为它起了缓冲储存,解决硬盘与CPU之间速度差问题(当然CPU的运算器、CPU缓存、内存也可以同样组成相同的情况)。而我们建立一个cache,就是从这样一个大缓存切一部分出来自己用而已。在这样的场景下,从作用地位上说,我们建立的缓存就是内存(大缓存)。“hello world是最简单的cache程序”,不知道何谓“cache程序”,若果helloworld程序数据保存硬盘上,那么CPU运算时将其加载到内存中,内存就是一个缓存而已。我们把硬盘的对象加载到内存(缓存)也是同样的道理。整个计算机,整个系统的内存不是应用程序开发所能触及的(应用程序反过来控制内存?),所以需要cache来划分出来(类似于开辟空间),但作用和地位上他们是一样的东西。

若果你一味执着一个角度的概念去思考,永远想不到其他角度的。人可以从社会角度谈,也可以从动物角度谈,也可以从上帝的角度谈,也可以从伦理的角度谈……拿其中一个角度来否定其他角度,是愚蠢的行为。

补充一下时间方面,所谓持久化,也就是长久的保存起来,让其持久。只要达到这样的要求就是持久化。无论是内存还是硬盘,符合了要求就是持久化。不因你cache是啥,只要达到要求,就是持久化。
[该贴被SpeedVan于2011-03-22 13:19修改过]
[该贴被SpeedVan于2011-03-22 13:22修改过]

其实Banq,SpeedVan和ACoder说的完全是两件事情:
Banq,SpeedVan的意思是在设计领域应该以对象设计为基础,只有在需要的时候才需要时(如内存无法容纳全部数据、有时会停电等)数据库等方式的持久化。如果有一天那些前提条件都满足(Banq举的例子如云),那么就不需要持久化了。

ACoder说的是缓存,缓存的目的就是通过各种方式提高效率,这点其实大家都能理解,jdon007也举了很好的例子。

所以这两件事情更本没多大交集。所谓的交集无非就是大家都可能用到内存而已。

另外,即使如Banq,SpeedVan所说的,某一天某些应用不需要持久化了,那么面对几百G的或者上T的内存对象数据,你还是需要缓存的,而且可能还不是一层缓存,而是多个层次,多种类型的缓存来解决不同层面的效率问题。

虽然我不喜欢长篇大论,但是为了给你解释清楚,我不得不一句句来。

如果你用cache是为了让对象不被jvm回收,以为将对象放在cache中就可以了,这是一种错误的认识,实际情况是

cache会复制一份相同的东西放在自己里面,而当你需要的时候get这个东西的时候重新复制一份给你,这是一种持

久化的表现,因为你的那个东西不再是原来的那个(内存地址完全改变了,不过有可能恰好是原来的地址,这带有

极强的随机性),这种过程跟你save到一个文件有什么区别,难道这就是cache?

其二,被回收的问题只有在托管语言才有,C/C++不存在这个问题,咱们不跨语言说,就说java,对于一个生命周期

的管理,那么什么是生命周期的管理,既然称之为生命周期就代表着一定有创建和消亡的过程,何时创建取决于你

的程序,而何时消亡,不管是被jvm回收或者放入cache中,对不起,他都已经消亡了,你下次看到的只是一摸一样

的东西,但是不是原来那个。

第三点你想的太多了,我告诉你jvm中怎么实现的,他的实现是定义了一个字符串hello world放在程序的数据区,

然后运行到print的时候跳转到这个地址打印出来,没有使用任何flyweight模式,如果你的程序还有一个hello

world,那么还是这个地址,但是如果是hello cat,那么不会帮你分割出hello 和后面部分的。而且这一段gc不进

行回收:)

第四,cache谁跟你说就一定是内存,我就见过持久化的cache系统,将数据存储在db中,至于说内存是硬盘数据的

cache,呵呵,你可以问盖茨或者郭士纳,或者写Event DDD的那个,你写一封email问问他这个说法对不对,看看他

的回答。

最后:你最后一句话我喜欢,不过恰恰说明了你将持久化混为了cache,看看我给banq的回复,我想那里我已经将

cache与持久化的设计理念与作用说清楚了。

2011年03月22日 13:52 "slangmgh"的内容
其实Banq,SpeedVan和ACoder说的完全是两件事情:
Banq,SpeedVan的意思是在设计领域应该以对象设计为基础,只有在需要的时候才需要时(如内存无法容纳全部数据、有时会停电等)数据库等方式的持久化。如果有一天那些前提条 ...

我觉得你完全看懂我想说的意思了,让我也觉得不是由于我的表述不清而导致产生误解。

不过稍微错的一点是,对象化的设计也是我主张的:)

2011年03月22日 14:19 "ACoder"的内容
我觉得你完全看懂我想说的意思了,让我也觉得不是由于我的表述不清而导致产生误解。

当然,你的表达非常清楚,其实我只是重复了你的某些话而已。

2011年03月22日 14:19 "ACoder"的内容
不过稍微错的一点是,对象化的设计也是我主张的:) ...

所有的设计方法包括OO都是有它适合的环境的:)

唉,老捧着一个概念说,你可以看看原文章的环境。

不是使用因为cache技术怎样,而去使用cache,而是需要一个什么样的东西,需要cache来支持。在这样的环境下,东西的观察角度是不一样的,我回帖就说到没有否定你的角度,只是在这样的环境下,再用原来的概念已经不适合了。说白了,就是需要一个特定环境的对象(实体)的可管理的容器。而这个容器,我选择是cache,你可以选择map+自己管理,或者再新建一个,这是你自己的选择。但居于软硬件问题,我没有找到比cache更好的选择。

1、若果cache是基于复制给我的,那么他是基于对象不变性来实现的。很不幸,同样的key,只会获得同一个对象,不会如你所说通过复制。不会因为多次获取,而产生多个对象,你可以去测试观察其引用。其所谓的复制,是指,我们从低速存储器上复制一份过来使用。复制概念只存在这里,其他地方没有所谓的复制。

2、关于设计者控制生命周期,是因为CacheManager也在设计者的管核之下,所以设计者可通过算法来控制。也就是设计者可以通过算法方式来动态控制。不只是你用命令去叫它生叫它死才叫控制。而GC是平台级别的,不应该因为应用而去扰乱平台。

3、因为提到空间,提出flyweight只是额外而已(更底层的东西),你可以过滤这个词语。那段话关键是对象空间,若果有超出jvm容量限制的对象产生会发生什么问题呢?String可以通过flyweight优化,但对象(实体)这些是独立的,不想OOM就得自己控制。
你所说的数据区,就是字符串池。谁叫你把字符串切割?我说的意思是,字符串有flyweight优化(如String a ="abc")这里就用到flyweight机制,先到池找有没有"abc",没有就新建,有就flyweight。我说的是字符串对象,不是字符。也没提到要回收,不过你可以试下死循环下new String("abc"),会产生什么后果。我这里提出的是因为,业务等,实体等对象不能进行flyweight,所以对于有限的空间内,必须存在淘汰机制(但内存足够大的时候,就不需要了)。这是一个基于对象,实体空间的思考。不是cache不cache的问题。我开头就说到了,我的角度都是从对象(实体)存亡出发考虑,还是你没看到这个?

4、若果你只有一个角度看东西的话,当我任何东西都没说过,因为角度不同,而听者也死守自己的角度,无法交流也就懒得再说了。观点说场景,别把别人在特定场景下的观点,进行泛化,这只是一种不了解观点或者误解别人观点的行为而已,四个字就是“断章取义”。

若果还是不懂,那么好好想想上面黑体字的意思。

说实话,我想很多人都看明白我说的什么,而你为什么总看不懂那?

cache不能当做持久层来使用!!这是两种不同的概念。
管理对象的容器是EJB或者Spring,绝对不是cache!!

至于说复制,java这方面用了一个技巧,就是先存引用,但是当你如果修改了对象的话,它会复制一份给cache的,不信你可以把对象存到cache里面,然后你修改该对象一个属性,然后从cache里面获取这个对象比较一下。

你说的2正好证明了我说的cache不能取代持久化的。

你的3请你要明白什么时候是编译期的事情,什么是运行期的事情,而对象存亡问题取决于你的程序,当你不使用它的时候他就是亡,即使放在一个永不消失的cache,对于程序而言他也是亡,gc是否回收他,cache是否清除它都无关。

我真的很想找一个第三人来理解一下你说的场景,也许我的理解能力有问题,但是我说的东西别人能够看的懂,而你写的东西云山雾罩,让人不知所云,谁的问题自己思考吧。

我认同你的角度叫做看不懂?不同角度看东西,就需要不是你死就是我活?角度不同问题,而不是懂不懂问题。基于你的角度所的出来的没问题,对于不同角度的解析,叫做不懂?例如是静止还是运动,基于不同角度(参照物)得出的也不同。

能不能持久化,是如何看待持久化而已。

若果基于这样的复制,若果缓存对象里面也有对象,那里面的对象引用因为复制而改变了?对象的唯一标识是对象引用,若果引用不变,对象变了么?就如实体的唯一标识是id,无论世界怎么变,id没变的话,还是不是那个实体呢?虽然这种方式还是第一次听,但我不觉得它改变了对象,若果对象的唯一标识不能保证,那么所有逻辑已经失效了。

EJB是EJB容器,spring的是Ioc容器。他们各自以自己的方式来管理,全世界只有这两个来管理对象?国家有国家的管理,企业有企业的管理,只是一个人在企业上消失了,还是在国家上消失了。GC是犹如国家级别,边界在企业上时,不需要考虑它。tomcat启动,tomcat启动spring,spring启动cache,若果cache亡了,也就是spring和tomcat都亡了(不考虑自身异常终止),还何来谈管理呢?cache不是管理所有对象,例如上升到entitycache,它管理的只是实体对象,以外的交给上一级管,所有东西都有边界的,边界思维正好是OO思维。


好一句先入为主的话,说别人理解你,而不理解我。你说的我都懂,而且我也懂我们角度完全不同,为啥你就不懂这个呢?而别人就懂?我的角度就是基于对象(实体)存亡思考(边界是框架内,原文环境),所以不会因为cache是什么来主导我的设计,而是我有什么设计,再去选择cache来支持,围绕cache你能想出什么设计来?

从设计中得出,我需要一个容器,所以数据库,map,cache等一系列能存储的都符合要求,再设计,实体是活的,必须与业务是同一阵线的,所以map、cache等符合要求,到这里已经满足了我的要求了:容器,存在内存。而当中要求暗示了缓存——缓存数据库中所表达的对象,因为现在不能脱离数据库,而这样一个容器也就成了缓存。这里我使用Map一样可行,而此时Map就是一个缓存容器。我设计中没有直接要求cache,而是在我要求基础上,加上软硬件条件限制,从而使我选择cache而已,如必须使用数据库,存在容量限制等等一系列原因。


至于cache能否持久化,是对持久化的理解。可以这么想,留言版,我不需要数据库了,那么留言用什么保存呢?根据实体与业务是同一阵线的思维,选择Map可以实现(存在内存的容器)。暂时不考虑容量问题,若果我永远不停机,也不会死机,Map长久保存着数据,还没有持久化了吗?好了现在考虑容量,于是cache和数据库出来了。通过云技术,让cache达到TB级别,根据云特点,可以看成一个没有停机没有死机的大cache,数据永远保存在里面,不就等于持久化了?当数据丢失的几率达到硬盘损坏的程度——相当于用内存做成一个硬盘了,这还不算持久化,我就没话可说了。至于加多几层cache是另外一个话题。这里说出持久化,不是看载体是用来干什么,而是载体能不能达成长久保存的要求。

[该贴被SpeedVan于2011-03-22 18:21修改过]

测试了一下,没觉得有什么问题。


import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;


public class cacheTest {

/**
* @param args
*/
public static void main(String[] args) {
CacheManager cacheManager = CacheManager.create();
Cache cache = cacheManager.getCache(
"entityCache");

UserImp user = new UserImp();
System.out.println(
"userImp:"+user);
Member member1 = new Member();
System.out.println(
"member1:"+member1);
Member member2 = new Member();
System.out.println(
"member2:"+member2);
user.setMember(member1);
cache.put(new Element(
"user",user));

System.out.println(
"cache.user.element:"+cache.get("user"));
System.out.println(
"cache.user.element.userImp:"+cache.get("user").getObjectValue());
System.out.println(
"cache.user.element.userImp.member:"+((UserImp)cache.get("user").getObjectValue()).getMember());

user.setMember(member2);
//替换处
System.out.println(
"cache.user.element:"+cache.get("user"));
System.out.println(
"cache.user.element.userImp:"+cache.get("user").getObjectValue());
System.out.println(
"cache.user.element.userImp.member:"+((UserImp)cache.get("user").getObjectValue()).getMember());


}
// 输出:
// userImp:UserImp@1a52fdf
// member1:Member@3e89c3
// member2:Member@1c695a6
// cache.user.element:[ key = user, value=UserImp@1a52fdf, version=1, hitCount=1, CreationTime = 1300792137750, LastAccessTime = 1300792137750 ]
// cache.user.element.userImp:UserImp@1a52fdf
// cache.user.element.userImp.member:Member@3e89c3
// cache.user.element:[ key = user, value=UserImp@1a52fdf, version=1, hitCount=4, CreationTime = 1300792137750, LastAccessTime = 1300792137750 ]
// cache.user.element.userImp:UserImp@1a52fdf
// cache.user.element.userImp.member:Member@1c695a6

}

[该贴被SpeedVan于2011-03-22 23:13修改过]
[该贴被SpeedVan于2011-03-22 23:16修改过]

2011年03月22日 16:46 "ACoder"的内容
说实话,我想很多人都看明白我说的什么,而你为什么总看不懂那 ...

两位不要争了,ACoder是比较实在的,正如jdon007所说,双方在谈不同的东西,名可名,非常名,虽然它的名字还叫Cache缓存,当实际我的意思已经不只是缓存,而是一种In-memory model ,这是一种新的流行词语In-memory,这样有别于Cache原来的词语。

另外SpeedVan虽然理解我的观点,但是表述方面上也许更改进一步,大道至简,建议你象我一样去写微博,锻炼自己把复杂的意思浓缩在140个字内写完。言简意赅就更好。
[该贴被banq于2011-03-23 12:54修改过]