??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲日本香蕉视频,亚洲日韩精品无码一区二区三区,亚洲AV日韩AV永久无码免下载http://www.tkk7.com/changedi/archive/2015/02/26/423050.htmlchangedichangediThu, 26 Feb 2015 07:19:00 GMThttp://www.tkk7.com/changedi/archive/2015/02/26/423050.htmlhttp://www.tkk7.com/changedi/comments/423050.htmlhttp://www.tkk7.com/changedi/archive/2015/02/26/423050.html#Feedback0http://www.tkk7.com/changedi/comments/commentRss/423050.htmlhttp://www.tkk7.com/changedi/services/trackbacks/423050.html首先Q我先声明一点,我讨论的仅限于互联网数据产品Q当然可能会(x)涉及(qing)C些其他的抽象Q但是所有的l论不代表能复用到所有场景?/p>

 

        几乎每个JavaE序员都清楚知道Java的异常和错误机制Q无论是在面试过E中Q还是在学习(fn)中,你看?/span>ExceptionQ无非就是了解一下承关pR子cR和Error的关pȝ{。当然这些知识点是基Q那么在实践中,用到了吗Q你定你?/span>Exception时没有偷懒?我的l验告诉我,良好的?/span>Exception能让你的E序bug更少Q或者至能保证你的E序更容易被理解和跟t?/span>

 

        先回到老的知识点吧——Java的异常机Ӟ我们知道Java里的异常是完全?/span>Throwable的,正如java doc里注释的Q无Zthrow的还?/span>JVM throw的,抑或是你?/span>catch的,都必ȝ?/span>Throwable。我q里帮助大家U正的第一个点是Q?/span>java.lang.Throwable是一?/span>classQ不是一?/span>interfaceQ千万别被名字欺骗。优U的程序员有好的命名习(fn)惯,?/span>JavaE序员默认认为带?/span>-able后缀的都该是接口Ӟ Josh Blochl大家上了一?#8212;—Throwable是cR回到正题,Throwable有两大子c,一个是java.lang.ErrorQ一个是java.lang.ExcpetionQ?/span>Error是错误,一般多用于pȝ异常和底层错误,Error抛出׃(x)DE序l止Q?/span>Exception是异常,有程序引P又分为受?/span>checked和非受检?/span>uncheckedQ不知道哪本书这么翻译的来着Q,受检的异常是普通异常,是你需?/span>catch的来打日志或者补救的Q这U做法叫吞掉异常Q,非受的多数是RuntimeExceptionQ就是运行时异常Q这cd怸catchQ因个是E序bugQ需要被人发玎ͼ所以徏议抛出引L(fng)序终止?/span>Blah~blah~ q些都是老生常谈的话题,需要深入的Ҏ(gu)有几个:(x)

 

        W一Q?/span>Error是徏议到pȝU别的错误的Q包括虚拟机的,我们常见的就?/span>java.lang.VirtualMachineErrorQ这是一?/span>JVMU别的抽?/span>ErrorQ如果你觉得没见q?那么不用奇怪,它的两个儿子你肯定见q:(x)OutOfMemoryError?/span>StackOverflowError?/span>Error其实真没好说的,一般情况不捕获Q程序员也用的较?yu),但是你看很多基础框架或者系lYӞ都是有自定义Error的,所以当你的工作层次或者范围你能确定比较底层时Q其实是可以自定义一?/span>Error来控制程序的错误的。我q样说可能也不是很好理解Q换个简单的话:(x)你的架构设计中需要考虑到异常的处理Q那么首先要对异常定U别Q如果有可能有偏底层的异常时Q或者是本不该出C不徏议用P多数是依赖你的库q行开发的其他E序员)捕获Ӟ定义?/span>Error是个不错的选择。当然也不是说做上层开发的E序员就不能使用ErrorQ只要你设计合理Q你可以在必要时抛出Error来终止程?#8212;—比如提醒你的老板再不加薪?/span>Error到死Q)

 

        W二Q?/span>Exception分两c这事几乎h人皆知,受检的异常往往?/span>web后端开发或者服务开发自定义的业务异常比?/span>BizServiceException或者常见的DAOExceptionQ这些异常在开发定义时L直接extends ExceptionQ而忽视了I竟q些异常我们对它们的期望是什么,q里我想一点,我们在业务系l架构中考虑到异常机Ӟ自定义的异常不是Z有异常而定义异常,一定对它本w是有期望的。我们对异常的一个基本期望是异常I竟该被谁捕P如果被你的服务下游捕P那么q必L一个受的异常,如果是系l自w需要,那么q个我个为是分阶D设计的Q在初期Q也是未发布状态,q些Exception应该L被抛出的Q因样可以快速的让测试和质量控制人员发现pȝ崩溃的点。在发布阶段Q异常可能需要被内部消化Q这时受异常p提供l业务系l,让业务开发自行捕获异常。当Ӟ好的pȝ架构可能?x)?/span>Exception作ؓ(f)一个内部可见外部不可见的内容,而基于此完全装一?/span>error code对外Q这应该是比较友好的做法了Q也是很?/span>API设计时的标准规范。毕竟对外部透明Q不要让用户看到你的ExceptionQ这是非常友好的做法?/span>

 

        W三Q关?/span>catchQ就针对上面的第二点Ԍ吞异常这事不是没人干q,我们往往担心pȝ错误而一?/span>try catch 捕获所?/span>ExceptionQ有的甚至不够,q升一U,捕获ThrowableQ这应该是最p糕的代码设计(但不q的是在我现在开发的pȝ和曾l开发过的业务系l中Q这cM码非常普遍)。开发h员不应该因ؓ(f)旉紧、赶q度{接口而忽?/span>ExceptionQ就拿最上层的业务开发D例,开发可能会(x)调用各类服务、访问数据库、访问缓存和文gpȝ{等Q而这些服务必然包含了各种异常Q?/span>catch一?/span>ExceptionQ试N过吞噬异常保护pȝ或者页面正常访问,而打日志到后収ͼ通过分析日志来偷L(fng)解决bug……说v来真是汗毛倒竖。我的观点:(x)如果有错误,那么让它?yu)早暴露出来Q我们应该通过量多的试和优化来避免错误Q而不是偷L(fng)隐藏。事实也证明Q日志里大量?/span>NPE或者其?/span>RuntimeException存在Q但是无人问z,“pȝ不是好好的吗Q?#8221;Q?#8220;面不是没问题吗”q样的说辞可以让开发看h毫无责QQ但是这为系l长期的l护和后l的扩展都带来了无尽的烦恼和坑?/span>

 

         lgQ我个h的经验告诉我几点对待Exception的方法:(x)

        1Q花旉了解涉及(qing)到的每个服务和方法所可能抛出的异常。事实往往是理解异常的关系和机制其实不花时_(d)了解后再开发,你会(x)比别人知道更多的异常点,q能保证你程序的健壮性;

        2Q无Z在服务开发还是服务用层U,都要试或者想到封装异常,提供友好错误设计的方案,最单的是自定义一个业?/span>Exception来封装?/span>

        3Q不要在你的Ҏ(gu)开?/span>tryQ结束时catchQ这防M性太ZQ很品位?/span>

        4Q前三点可能都是错的Q因为我自己也没有完全实践:(x)Q?/span>



changedi 2015-02-26 15:19 发表评论
]]>如何高效的实C个计数器maphttp://www.tkk7.com/changedi/archive/2013/01/20/394460.htmlchangedichangediSun, 20 Jan 2013 04:40:00 GMThttp://www.tkk7.com/changedi/archive/2013/01/20/394460.htmlhttp://www.tkk7.com/changedi/comments/394460.htmlhttp://www.tkk7.com/changedi/archive/2013/01/20/394460.html#Feedback0http://www.tkk7.com/changedi/comments/commentRss/394460.htmlhttp://www.tkk7.com/changedi/services/trackbacks/394460.html阅读全文

changedi 2013-01-20 12:40 发表评论
]]>
HBase的一些应用设计tiphttp://www.tkk7.com/changedi/archive/2013/01/02/393697.htmlchangedichangediWed, 02 Jan 2013 11:00:00 GMThttp://www.tkk7.com/changedi/archive/2013/01/02/393697.htmlhttp://www.tkk7.com/changedi/comments/393697.htmlhttp://www.tkk7.com/changedi/archive/2013/01/02/393697.html#Feedback1http://www.tkk7.com/changedi/comments/commentRss/393697.htmlhttp://www.tkk7.com/changedi/services/trackbacks/393697.html1Q对于HBase的存储设计,要考虑它的存储l构是:(x)rowkey+columnFamily:columnQualifier+timestamp(version)+value = KeyValue in HBaseQ一个KeyValue依次按照rowkeyQcolumnkey和timestamp有序。一个rowkey加一个column信息定位了hbase表的一个逻辑的行l构?/p>

0XJJ{2%~G~[G]JBPMW}YE~A

2Q从逻辑存储l构到实际的物理存储l构要经历一个foldq程Q所有的columnFamily下的内容被有序的合ƈQ因为HBase把一个ColumnFamily存储Z个StoreFile?

3Q把HBase的查询等价ؓ(f)一个逐层qo(h)的行为,那么在设计存储时应该明白,使设计越向单一的keyvalue性能?x)越好;如果是因为复杂的业务逻辑D查询需要确定rowkey、column、timestampQ甚x夸张的是用到了HBase的Filter在server端做value的处理,那么整个性能?x)非怽?

4Q因此在表结构设计时QHBase里有tall narrow和flat wide两种设计模式Q前者行多列,整个表结构高且窄Q后者行列多,表结构^且宽Q但是由于HBase只能在行的边界做splitQ因此如果选择flat wide的结构,那么在特D行变的大(过file或region的上限)Ӟ那么q种行ؓ(f)?x)导致compactionQ而这样做是要把rowd存的~~因此Q强烈推荐用tall narrow模式设计表结构,q样l构更趋q于keyvalueQ性能更好?

5Q一U优雅的行设计叫做partial row scanQ我们一般rowkey?x)设计?f)<key1>-<key2>-<key3>...Q每个key都是查询条gQ中间用某种分隔W分开Q对于只xkey1的所有这L(fng)情况Q在不用filter的情况下Q更高性能Q,我们可以为每个key讑֮一个v始和l束的|比如key1作ؓ(f)开始,key1+1作ؓ(f)l束Q这样scan的时候可以通过讑֮start row和stop rowp查到所有的key1的valueQ同理P代,每个子key都可以这栯设计到rowkey中?

6Q对于分|询,推荐的设计方式也不是利用filterQ而是在scan中通过offset和limit的设定来模拟cMRDBMS的分c具体过E就是首先定位start rowQ接着跌offset行,dlimit行,最后关闭scanQ整个流E结束?

7Q对于带有时间范围的查询Q一U设计是把时间放C个key的位|,q样设计有个弊端是查询时一定要先知道查询哪个维度的旉范围|而不能直接通过旉查询所有维度的|另一U设计是把timestamp攑ֈ前面Q同时利用hashcode或者MD5q样的Ş式将其打散,q样对于实时的时序数据,因ؓ(f)其打散D自动分到其他region可以提供更好的ƈ发写优势?

8Q对于读写的qQ下面这张图更好的说明了key的设计:(x)salting{h(hun)于hashQpromoted{h(hun)于在key中加入其他维度,而random是MDq样的Ş式了?

VN{YX`@[2P9AQ[@(2U8N9{0

9Q还有一U高U的设计方式是利用column来当做RDBMScM二索引的应用设计,rowkey的存储达C定程度后Q利用column的有序,完成cM索引的设计,比如Q一个CF叫做data存放数据本nQColumnQualifier是一个MD5形式的indexQ而value是实际的数据Q再Z个CF叫做index存储刚才的MD5Q这个index的CF的ColumnQualifier是真正的索引字段Q比如名字或者Q意的表字D,q样可以允许多个Q,而value是这个烦引字D늚MD5。每ơ查询时可以先在index里找到这个烦引(查询条g不同Q选择的烦引字D不同)Q然后利用这个烦引到data里找到数据,两次查询实现真正的复杂条件业务查询?/p>

10Q实CU烦引还有其他途径Q比如:(x)1Q客L(fng)控制Q即一ơ读取将所有数据取回,在客L(fng)做各U过滤操作,优点自然是控制力比较强,但是~点在性能和一致性的保证上;2QIndexed-Transactional HBaseQ这是个开源项目,扩展了HBaseQ在客户端和服务端加入了扩展实现了事务和二索引Q?QIndexed-HBaseQ?QCoprocessor?/p>

11QHBase集成搜烦的方式有多种Q?Q客L(fng)控制Q同上;2QLuceneQ?QHBaseneQ?QCoprocessor?/p>

12QHBase集成事务的方式:(x)1QITHBaseQ?QZooKeeperQ通过分布式锁?/p>

13Qtimestamp虽然叫这个名字,但是完全可以存放M内容来Ş成用戯定义的版本信息?/p>

changedi 2013-01-02 19:00 发表评论
]]>
HBase一些tiphttp://www.tkk7.com/changedi/archive/2012/12/28/393577.htmlchangedichangediFri, 28 Dec 2012 05:59:00 GMThttp://www.tkk7.com/changedi/archive/2012/12/28/393577.htmlhttp://www.tkk7.com/changedi/comments/393577.htmlhttp://www.tkk7.com/changedi/archive/2012/12/28/393577.html#Feedback0http://www.tkk7.com/changedi/comments/commentRss/393577.htmlhttp://www.tkk7.com/changedi/services/trackbacks/393577.html1Qrow是有序的Q可以看做RDBMS的一U烦?/p>

2Q一个列CF的所有列存储在一个HFile?/p>

3QCF要在时定义,变化,更不要徏太多

4Qversion和timestamp是对应的Q每个cell有不同的版本Q就说明是在不同的timestamp存储的,如果重复的timestampQ那么就说明是一个版?/p>

5Q定位一个数据,需要rowkeyQcolumn和timestampQ即SortedMap<RowKey,List<SortedMap<Column,List<Value,Timestamp>>>>

6Q初始一个regionQ之后自动shardingQ一台server大概10-1000个regionQ每个region大小?-2GB

7Q每一个HFile有一个block indexQ可以只用一ơdisk seek完成查询

8Q数据更新时要写commit log卛_说的WAL——write-ahead-logQ每ơ操作都?x)记录在内存memstoreQ当memstore满了以后自动flush到HFile的diskQ在做flushӞreader和writer不被dQ可以l服务(q是因ؓ(f)Qflush做的是一个滚动操作,老的满的数据flush到磁盘,而完成后的新的空的memstorel箋服务Q因为memstore已经是按key的顺序排好的Q所以不需要额外操作,只要写和flushpQ?/p>

9Q删除操作是逻辑的,因ؓ(f)存储文g不可变,所以会(x)攄一个删除标记到每个键值对

10Q通过compaction小的hfile合ƈ为大的,compaction有两U类型:(x)minor和majorQ前者通过多\归ƈ完成多个文件到量大文件的合ƈQ后者重写整个CFC个新的文Ӟ在做compaction的时候可以把之前标记qdelete的kv pair攑ּQ即不写到新的文?/p>

11QHBase由客L(fng)库,一台master server和多台region serverl成Qmaster负责regions的负载均衡,master不存储数据,只做调度

12Q扫表scan是线性时间的Q查询是Ҏ(gu)旉的,而极端情늚查询是常数时间的Q用bloom filterQ?/p>

13Q在putӞ要注意flush的时_(d)没有flush的数据是不会(x)被get到的Q从源码可以了解刎ͼflush有两U情况,一是显C用flushCommits()Q另外就是到了client端的writebuffer上限触发Qhbase默认client的writebuffer size?MQ可以通过配置M?/p>

14QHBase的client里,caching针对行模式(q回多少行)Q而batching针对列模式(q回多少列)Q都是在scan时提高效率(减少RPCQ的Ҏ(gu)

15Q用HBase的接口时Q通过Filter的用可以减网l传输的数据量,从而减d客户端用的旉成本Qget或scan你想要的东西Q不要的东西直接在server通过filterqo(h)?/p>

16Q在重用ConfigurationӞ要记得每ơ都?x)增加一个引用数Q因此在使用完后最好调用closeҎ(gu)connection释放?/p>

17QHBase的block size和hdfs的block size是不一L(fng)Q前者是指处理block操作时的数据大小Q默认是64KBQ而后者是用来分布式存储文Ӟ默认大小?4MB

18QRDBMS和Hbase的区别:(x)存储l构b?wi)或b+?wi),Hbase采用cMLSM?wi)的做法QLog-Structured Merge Trees)QLSMT的简单过E描q是Q数据首先被序存储C个log file里,在写满后这些数据更新到in memory storeQ然后flush有序key value pair到磁盘,生成一个文件。磁盘文件的l织形式cMB?wi),但是对于盘序讉K做了优化Q其中每个文仉被完全填充ؓ(f)单页或多늚blockQ而这些文件的update本n是rolling merge{略Q即pȝ在直到block写满的时候才in memory的数据打包。因为flush是经常进行的Q导致系l中?x)有很多的文Ӟ一个后台进E在不断的合q小文g到大文g从而将盘seek~减到少量的文g范围。于此同Ӟ盘的树(wi)也可以进行分裂操作,大文g分割q文件以便扩展更新。而所有的存储都是key有序的?/p>

19QHbase查询Ӟ先到in memory里查Q再到on disk里查Q这L(fng)行ؓ(f)可以保证了一致性;删除时是逻辑删除Q先delete标志打上Q后期在异步重写的时候,标记了delete的key?x)被最l物理删除?/p>

20QHBase有两cLӞ一cȝ于WAL的logQ另一cȝ于数据存储?/p>

21Q一般HBase的访问流E是Q先到zookeeper quorum取row keyQ通过从zk中查?ROOT-里的服务器名字实玎ͼ接着拿着取到的服务器名字去region server查询持有.META. 表regionq且包含了rowkey的server名字Q最后查?META.服务器,获取到包含对应rowkey region的server name。一旦获取这些信息,客户端将其缓存v来,以后q道如何到哪里L扑ƈ且直接和region server联系了?/p>

22Q在源码U别QHMaster负责分配HRegionServerQHRegionServerl护一个HRegionQ当HRegion建立Ӟ为每张表的每个HColumnFamily建立一个StoreQ每个Store包含一个或者多个StoreFileQ轻量的HFile包装Q,一个Store同时也有一个MemStoreQ还有一个HRegionServer׃n的HLog?/p>

23Q在做put操作Ӟregion server先检查本ơput是否需要写WALQ一旦数据写入WALQ那么它?yu)p入MemStoreQ同时检查MemStore是否满,如果是,做一ơflushQ写C个HFile里存到HDFSQ同时维护一个最后一ơ写入的序列P以便pȝ知道到目前ؓ(f)止的持久数据信息?/p>

24Q在HFile被持久化后,log文g׃再有用了Q这时自动从.log目录Ud?oldlog目录Q当然也有配|可以配|滚动周期)Q默?0分钟后由HBase自动删除?/p>

25Q每个table有一个目录,在这个目录里Q每个列族有一个自q目录?/p>

26Qregion split发生在当一个region的存储文件大达到配|的hbase.hregion.max.filesize时进行。具体过E就是:(x)pȝ为新的region创徏两个原region的烦引文Ӟ每个各持有原来一半的数据Qregion server在父region创徏一个splits目录Q接着关闭region拒绝新请求,然后再splits目录里构建必要的新的region目录文gl构存放刚才的两个half 大小的文件。成功后Q系l将两个新的region目录d到表目录Q更?META.表以表明父region做了splitQ同时表明新的两个region是什么?/p>

27QHFileZHadoop的TFilecdQ模仿了BigTable的SSTable格式Q文件是变长的,其中定长的部分是file info 和trailerQ而数据以keyvalue存入data块,默认大小64KBQ而HDFS默认块大是64MBQ两者没有关pR结构类|(x)

YYYY~H0S6~ALGP4DPBEO6DS

28QKeyValue在HFile中就是一个简单的字节序列Q结构类?/p>

A[BN}2`4~5B]F7@$83%Z@3S

29QW(xu)AL是容灄重要武器Q类似mysql的binlogQ记录了所有的变化Q这可以保证在数据q入memstore后而没有持久这D|间因为突发原因导致数据丢失时候的容灾。流E如下:(x)

8D`N7YP]%WQ}Y9LO3H0}$CL

30Q在上面q图中,有LogSyncer和LogRollerQ前者是默认关闭的,如果开启后Q那么每ơ写入都?x)触发一ơsyncQ将update同步到其他的serverQ而且q是pipeline形式的顺序写Q不是多路复写;后者负责滚动记录logQ可以设|时间间隔每隔一定时间来滚动日志Q也可以Ҏ(gu)大小来滚动,q个都可以配|?

31Q容灾恢复数据的一w要措施是replay日志Q也是重放W(wng)ALQ日志回放有两种触发条gQ一是集启动时Q二是服务器failӞ当master启动Ӟ?log目录里是否有log文gQ有的话则做log splitting——读入log然后Ҏ(gu)记录的region其分配到新文g?

32Qget和scan在近几个版本中实现等P因ؓ(f)对于特定行和列没有烦引的概念Q而最的讉K单元是blockQ因此如果要h数据Q那么一定会(x)加蝲一个RegionServer的实例的block然后扫描它,Get其实是一个确定了row的scan?

33Q在查询Ӟ一个周期是q样的:(x)因ؓ(f)客户端缓存region的,所以,?x)先到自qcache中查扑֯应regionQ找到的话则直接讉KQ?ơ网l请求即可)Q如果找不到Q则到region server?META.中去取(3ơ)Q如果再找不刎ͼ则到-ROOT-?META.信息Q?ơ)Q再找不刎ͼ只好去zk中取Q?ơ)Q这是第21条tip的逆过E) ?

34Qregion?U状态(offline,pending open,opening,open,pending close,closing,closed,splitting,splitQ,状态{Ud以再master做,也可以在持有region的region server上做。集通过zk来跟t状态变化?

35QHbase的复制策略ؓ(f)容灾提供了高可用Q基本模式是Qmaster-pushQ因为WAL的存在,跟踪复制变得很容易;一个master cluster可以复制CQ意数量的slave clustersQregion server负责自己的复制?

F9{B6EB`L4ASJ[W5(9D1WZP

changedi 2012-12-28 13:59 发表评论
]]>
JVM学习(fn)W记Q?Q?amp;mdash;&mdash;q接模型Q上Q?/title><link>http://www.tkk7.com/changedi/archive/2012/09/21/388255.html</link><dc:creator>changedi</dc:creator><author>changedi</author><pubDate>Fri, 21 Sep 2012 06:17:00 GMT</pubDate><guid>http://www.tkk7.com/changedi/archive/2012/09/21/388255.html</guid><wfw:comment>http://www.tkk7.com/changedi/comments/388255.html</wfw:comment><comments>http://www.tkk7.com/changedi/archive/2012/09/21/388255.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/changedi/comments/commentRss/388255.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/changedi/services/trackbacks/388255.html</trackback:ping><description><![CDATA[<p>很重要的内容Q可能分几天记录</p> <ol> <li>jvm为每个装载的cd接口保存一份独立的帔R池? <li>动态加载最常用的是Class.forName()Q这个方法有两个重蝲版本QClass.forName(String name)和Class.forName(String name, boolean init, ClassLoader loader)。它们均内部调用了forName0(String name, boolean initialize,ClassLoader loader)Q这是个nativeҎ(gu)。前者调用传递的参数是name、true和启动类加蝲器。name是要加蝲cȝ全限定名Qinit表明是否要初始化Q如果这个类已经被初始化q,q样的加载即使init是true也不?x)被再初始化Qloader是要加蝲的类加蝲器,null的话使用默认的启动类加蝲器? <li>另一U方式动态加载类是ClassLoader.loadClass()Ҏ(gu)Q这个方法也是两个重载版本:(x)ClassLoader.loadClass(String name)和ClassLoader.loadClass(String name, boolean resolve)Q其中前者调用了后者,resolve传递falseQresolve表示是否在装载时执行该类的连接? <li>loadClass不初始化c,而forName初始化类Q因此如果是需要动态加载类Q该c马上被用到那么应该初始化,loadClass只加载,有可能出问题Q但是会(x)有安全考虑? <li>帔R池解析:(x)上一日志也记录CQ在完成验证和准备后Q要q入解析阶段Q而解析主要做的就是解析常量池Q把W号引用转ؓ(f)直接引用? <li>对常量池CONSTANT_Class_info的解析,主要解析cd接口的符号引用,有两U入口:(x)1Q数l类Q指向数l类的符号引用最后解析ؓ(f)一个Class的实例,如果数组的元素类型是引用cdQ虚拟机用当前类加蝲器解析类型,如果数组是基本类型,虚拟Z(x)立即创徏关于那个元素cd的新数组c,定l数Q然后创建Class实例表示q个c,由启动类加蝲器定义?Q非数组c,W一步,装蝲cd或者Q何超cdQ先定引用cd已经被当前类装蝲器装载过Q虚拟机保证每一个类装蝲器都只装载一个给定名字的cdQ这个步骤只是确定类型是否被装蝲Q期间可能抛出的异常有:(x)NoClassDefFoundErrorQClassNotFoundErrorQClassFormatErrorQUnsupportedClassVersionErrorQLinkageErrorQClassCircularityErrorQIncompatibleClassChangeErrorQ第二步Q检查访问权限,如果发v引用的类型没有访问被引用cd的权限,jvm抛出IllegalAccessErrorQ第三步Q校验类型,出错则抛出VerifyErrorQ第四步Q准备类型,前面讲过Q就是ؓ(f)不同cd分配内存Q第五步Q可选的解析cdQ第六步Q初始化? <li>对常量池CONSTANT_Fieldref_info的解析,完成对Class_info的解析后QJVM按照一定顺序搜索字D:(x)在被引用的类型中查找h指定名字和类型的字段Q找不到Q则查类型直接实现或扩展的接口,递归查其接口,如果q找不到Q检查类型直接的类Qƈ递归查其所有超c,如果找不刎ͼ则失败,抛出NoSuchFieldError异常。找到字D,但是没有讉K权限Q抛出IllegalAccessError异常。解析完后标记该帔R池入口ؓ(f)已解析,q在数据中放入指向这个字D늚直接引用? <li>对常量池CONSTANT_Methodref_info的解析,完成对Class_info的解析后QJVM按照一定顺序搜索方法:(x)如果被解析类型是一个接口,虚拟机抛出IncompatibleClassChangeError异常Q如果是个类QJVM查被引用的类是否有一个方法符合指定的名字以及(qing)描述W,如果不符合,找该cȝ类Qƈ递归找所有超c,q是找不刎ͼ虚拟机检查该cL否直接实CM接口Qƈ递归查接口的接口,q找不到Q则抛出NoSuchMethodError异常Q如果找C是没有访问权限,抛出IllegalAccessError异常。解析完后标记常量池入口为已解析Qƈ在数据中攑օ指向q个Ҏ(gu)的直接引用? <li>对常量池CONSTANT_InterfaceMethodref_info的解析,完成对Class_info的解析后QJVM按照一定顺序在接口和它的超cd中搜索方法:(x)如果被解析的cd不是接口是类Q抛出IncompatibleClassChangeError异常Q否则检查接口是否有W合指定名字和限定符的方法,如果没有QJVM查接口的直接接口ƈ递归查所有超接口以及(qing)java.lang.ObjectcL找,如果q没有,抛出NoSuchMethodError异常。解析完后标记常量池入口为已解析Qƈ在数据中攑օ指向q个Ҏ(gu)的直接引用?/li></ol><img src ="http://www.tkk7.com/changedi/aggbug/388255.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/changedi/" target="_blank">changedi</a> 2012-09-21 14:17 <a href="http://www.tkk7.com/changedi/archive/2012/09/21/388255.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JVM学习(fn)W记Q?Q?amp;mdash;&mdash;cd生命周期http://www.tkk7.com/changedi/archive/2012/09/19/388086.htmlchangedichangediWed, 19 Sep 2012 10:13:00 GMThttp://www.tkk7.com/changedi/archive/2012/09/19/388086.htmlhttp://www.tkk7.com/changedi/comments/388086.htmlhttp://www.tkk7.com/changedi/archive/2012/09/19/388086.html#Feedback0http://www.tkk7.com/changedi/comments/commentRss/388086.htmlhttp://www.tkk7.com/changedi/services/trackbacks/388086.html直奔主题?/p>
  1. 一个javacȝq装载、连接和初始化三步达到程序可用状态,其中q接又包含验证、准备和可选的解析q程Q验证是查数据格式、准备是分配内存、解析负责把帔R池的W号引用转换为直接引用?
  2. jvm必须在每个类或接口首ơ主动用时初始化,有六U主动用场景:(x)1Q创建某个类的新实例Q?Q调用某个类的静态方法,3Q用某个类或接口的静态字D,用final修饰的静态字D除外,它被初始化ؓ(f)一个编译时的常量表辑ּQ?Q调用Java api中的某些反射Ҏ(gu)Q?Q初始化某个cȝ子类Q?Q虚拟机启动时某个被标明为启动类的类Q含有mainҎ(gu)的类Q?
  3. 某个c要初始化,其所有的先cdM前被初始化;接口则不同,只有在某个接口声明的非常量字D被使用Ӟ该接口才初始化?
  4. c装载的三个基本动作Q通过完全限定名找Cq制数据,解析为方法区内的数据l构Q创Z个该cd的java.lang.Class的实例?
  5. c装载有可能存在预先装蝲Q在预先装蝲时出问题Q会(x)抛出一个LinkageError的异常?
  6. 在准备阶D,内存分配是初始化为默认值的Q而不是实际的初始倹{默认值列表如下:(x)
    cd 默认初始?/td>
    int 0
    long 0L
    short (short)0
    char '\u0000'
    byte (byte)0
    boolean false
    reference null
    float 0.0f
    double 0.0d
  7. 在准备和解析完后Q才q入初始化阶D,为变量赋予真正的初始倹{?
  8. 初始化类的步骤:(x)1Q如果类存在直接类Q且直接类q没有被初始化,先初始化直接超cR?Q如果类存在一个类初始化方法,执行此Ҏ(gu)?
  9. W一个被初始化的cLq都是Object?
  10. 所有的cd量初始化语句和类型的静态初始化器都被java~译器收集在一P攑ֈ一个特D的Ҏ(gu)中—?lt;clinit>?
  11. 如果接口包含M不能在编译时被解析成Z个常量的字段初始化语句,接口׃(x)拥有一?lt;clinit>Ҏ(gu)?
  12. cd量如果直接赋帔R|那么cL不会(x)初始化的?
  13. cd例化的四U途径Q?Qnew操作W?Q调用Class或Constructor的newInstance()Ҏ(gu)?Q调用Q何现有对象的clone()Ҏ(gu)?Q通过ObjectInputStream的readObject()Ҏ(gu)反序列化?
  14. JVM为它~译的每一个类都至生成一个实例初始化Ҏ(gu)<init>?
  15. 使用启动c装载器装蝲的类Q永q都不会(x)被垃圾收集?/li>


changedi 2012-09-19 18:13 发表评论
]]>
JVM学习(fn)W记Q?Q?amp;mdash;&mdash;java classhttp://www.tkk7.com/changedi/archive/2012/09/17/387915.htmlchangedichangediMon, 17 Sep 2012 08:38:00 GMThttp://www.tkk7.com/changedi/archive/2012/09/17/387915.htmlhttp://www.tkk7.com/changedi/comments/387915.htmlhttp://www.tkk7.com/changedi/archive/2012/09/17/387915.html#Feedback0http://www.tkk7.com/changedi/comments/commentRss/387915.htmlhttp://www.tkk7.com/changedi/services/trackbacks/387915.html例子主要是《深入jvm》中的例子,class文g是其中的act.classQjava源文件是Q?/p>

class Act {

    public static void doMathForever() {
        int i = 0;
        for (;;) {
            i += 1;
            i *= 2;
        }
    }
}

class文ghex形式Q?

CA FE BA BE 00 03 00 2D  00 11 07 00 07 07 00 10
0A 00 02 00 04 0C 00 06  00 05 01 00 03 28 29 56
01 00 06 3C 69 6E 69 74  3E 01 00 03 41 63 74 01
00 08 41 63 74 2E 6A 61  76 61 01 00 04 43 6F 64
65 01 00 0D 43 6F 6E 73  74 61 6E 74 56 61 6C 75
65 01 00 0A 45 78 63 65  70 74 69 6F 6E 73 01 00
0F 4C 69 6E 65 4E 75 6D  62 65 72 54 61 62 6C 65
01 00 0E 4C 6F 63 61 6C  56 61 72 69 61 62 6C 65
73 01 00 0A 53 6F 75 72  63 65 46 69 6C 65 01 00
0D 64 6F 4D 61 74 68 46  6F 72 65 76 65 72 01 00
10 6A 61 76 61 2F 6C 61  6E 67 2F 4F 62 6A 65 63
74 00 20 00 01 00 02 00  00 00 00 00 02 00 09 00
0F 00 05 00 01 00 09 00  00 00 30 00 02 00 01 00
00 00 0C 03 3B 84 00 01  1A 05 68 3B A7 FF F9 00
00 00 01 00 0C 00 00 00  12 00 04 00 00 00 05 00
02 00 07 00 05 00 08 00  09 00 06 00 00 00 06 00
05 00 01 00 09 00 00 00  1D 00 01 00 01 00 00 00
05 2A B7 00 03 B1 00 00  00 01 00 0C 00 00 00 06
00 01 00 00 00 02 00 01  00 0E 00 00 00 02 00 08

  1. java的class文g?位二q制,数据Ҏ(gu)序存放Q无间隔Q占多字节的数据以高位在前的顺序分几个字节存放Q?
  2. java class基本cdQu1,u2,u4,u8Q分别对应:(x)1,2,4,8字节的无W号cdQ?
  3. java class file表格展示Q(太大了,来个url自己看吧Q?a >wikipediaQ?
  4. 表项详解Q?QmagicQ魔敎ͼQ说白了是cafebabeQ本来java是咖啡嘛,q?个字节用来区分是否是java的class文gQ有则是Q?Qminor_version&major_versionQ两个字节的minor和两个字节的majorQ以上ؓ(f)例就是minorQ?QmajorQ?DQJDK 1.1Q;3Q再之后是帔R池了Q?个字节表Cconstant_pool_countQ本例是17Q表Cclass文g中常量池中的Ҏ(gu)Q比实际的大1Q,接着是帔R池,q箋的constant_pool_count-1个字节存储常量池各个入口Q常量池入口解释见本文W?条笔讎ͼ4Q在之后的是access_flagsQ?个字节表C问类型,是类q是接口Q是publicq是privateQabstract或者f(xi)inal{等Q标志位具体定义见本文第6条笔讎ͼ本例?0 20Q表C版本ACC_SUPERQ?)之后是this_classQ这?字节的一个对帔R池的索引Q本例是00 01Q即本例的自w类叫做ActQ?Q之后就是super_classQ也是一?字节帔R池烦引,指向父类的名字, 本例?0 02Q即java.lang.ObjectQ?Qinterface_count和interfacesQinterface_count指出本文件有多少直接实现或者由接口扩展的父接口的数量,本例没有Q故?0 00Q之后是interfaces的具体内容,实际的项数就是之前的interface_count敎ͼ因ؓ(f)interface_count=0Q所以本例的interfaces没有|8Q接下来是fields_count和fieldsQ对本类所声明的字D늚描述Q首先是?字节的countQ本例是00 00Q所以后l也没有fields的项Q?Q再之后是methods_count和methods了,count是一?字节数据Q本例的method_count?0 02Q这个count只表C在cL接口中显式定义的Ҏ(gu)Q承的Ҏ(gu)不计敎ͼcount后是method_info的表Q包含方法的一些信息如Ҏ(gu)名、描q符{,本例?0 09表明Ҏ(gu)是publicQ?1Q?amp;staticQ?8Q,00 0F是方法名的常量池入口Q即帔R池的W?5doMathForeverQ再下来00 05是方法描q符帔R池入口,卛_量池W?:(x)()VQ然?0 01是属性表的count敎ͼ表示1属性,接下来是00 09表示属性表的常量池入口卛_量池W?CodeQ接下来?个字?0 00 00 30表示code属性长度:(x)48字节Q接着00 02是操作数最大数Q然?0 01是局部变量存储长度,q里Ҏ(gu)里只有一个变量iQ所以是1Q然?0 00 00 0c是code字节码长?2Q然后的12个字节就是字节码code了,再后?0 00是异常数Q之后异常栈数是0Q蟩q,是00 01的属性数Q然?0 0C指向帔R池的W?2即LineNumberTableQ这是一个code属性,之后?0 00 00 12是属性长度,再后?0 04是line_number_info表的Ҏ(gu)Q接下来?(每项4字节Q表Cline_number_infoQ?0 00 表示代码偏移量,00 05表示代码行号Q后面的cMQ?0Q最后是attributes_count和attributesQ表明了cȝ属性,属性比较特D,jvm定义了两U属性:(x)SourceCode和InnerClass?
  5. 帔R池各个标志解读(来源wikipediaQ?a href="http://www.tkk7.com/images/blogjava_net/changedi/WindowsLiveWriter/JVM1javaclass_A81F/image_2.png">image Q这里详解一下本例中的常量池Q常量池?
    cp_info
           {
               tag;
               info[];
           }
    cMq样的结构,先有一个无W号byte作ؓ(f)tag标志Q对应表g的数据,额外的info字节数组存储对应的数据index.
    我以表格的Ş式列出常量池的所有数据,应该一目了然了吧:(x)
  6. 帔Rindex 标志 标志内容 字节 具体数据 实际含义
    1 07 00 07 2 class reference 帔R池第7Ҏ(gu)该class的内?/td>
    2 07 00 10 2 class reference 帔R池第16Ҏ(gu)该class的内?/td>
    3 0A 00 02 00 04 4 method ref 两个indexQ前两个字节表示池内的class索引位置Q后两个字节是名字和cd描述
    4 0C 00 06 00 05 4 name & type 是W?Ҏ(gu)法指向的名字和类型的index
    5 01 00 03 2+x x个utf-8字符Q此处x=3 实际|(x)()VQ表CtypeQ第三项Ҏ(gu)的类型,具体含义参见描述W定义)
    6 01 00 06 2+x x=6 实际|(x)<init>Q表CnameQ第三项Ҏ(gu)的名字)
    7 01 00 03 2+x x=3 实际|(x)ActQ第一Ҏ(gu)向的具体字符内容
    8 01 00 08 2+x x=8 实际|(x)Act.javaQ?/td>
    9 01 00 04 2+x x=4 实际|(x)Code
    10 01 00 0D 2+x x=0D=13 实际|(x)ConstantValue
    11 01 00 0A 2+x x=0A=10 实际|(x)Exceptions
    12 01 00 0F 2+x x=0F=15 实际|(x)LineNumberTable
    13 01 00 0E 2+x x=0E=14 实际|(x)LocalVariable
    14 01 00 0A 2+x x=0A=10 实际|(x)SourceFile
    15 01 00 0D 2+x x=0D=13 实际|(x)doMathForever
    16 01 00 10 2+x x=10=16 实际|(x)java/lang/Object
  7. 讉K标志Q待完善Q?a >q里有详l的spec
  8. 描述W的完整定义Q非l结W是正常体,l结W是_体Q?可CZ前符号出?或多?
    FieldDescriptor FieldType
    ComponentType FieldType
    FieldType BaseType,ObjectType,ArrayType
    BaseType B,C,D,F,I,J,S,Z
    ObjectType L<classname>;
    ArrayType [ComponentType
    MethodDescriptor (ParameterDescriptor*)ReturnDescriptor
    ParameterDescriptor FieldType
    ReturnDescriptor FieldType,V
  9. 基本cdl结W:(x)V代表void
    l结W?/td> cd
    B byte
    C char
    D double
    F float
    I int
    J long
    S short
    Z boolean
  10. 一些描q符的例子:(x)
    描述W?/td> 字段或方法声?/td>
    I int a;
    [[J long[][] b;
    [Ljava/lang/Object; java.lang.Object[] c;
    Ljava/util/HashMap; java.util.HashMap map;
    [[[Z boolean[][][] ok;
    ()I int m1();
    ()Ljava/lang/String; String m2();
    ([Ljava/lang/String;)V void main(String[] args);
    ()V void m3();
    (JI)V void m4(long a,int b);
    (Z[Ljava/lang/String;II)Z boolean m5(boolean a,String[] b,int c, int d);
    ([BII)I int m6(byte[] a,int b,int c);
  11. 声明字段时的字段表field_infoQ?
    cd 名称 数量 含义
    u2 access_flags 1 讉K标志
    u2 name_index 1 字段单名U的帔R池utf8_info入口索引
    u2 descriptor_index 1 字段描述W的帔R池utf8_info入口索引
    u2 attributes_count 1 attribute_info表的Ҏ(gu)
    attribute_info attributes attributes_count 字段属性:(x)ConstantValue, Deprecated, SyntheticQJVM规范Q?/td>
  12. field_info中的access_flags标志含义Q?
    标志?/td> ?/td> 含义 使用范围
    ACC_PUBLIC 0x0001 public cd接口
    ACC_PRIVATE 0x0002 private c?/td>
    ACC_PROTECTED 0x0004 protected c?/td>
    ACC_STATIC 0x0008 static cd接口
    ACC_FINAL 0x0010 final cd接口
    ACC_VOLATILE 0x0040 volatile c?/td>
    ACC_TRANSIENT 0x0080 transient c?/td>
  13. 声明Ҏ(gu)时的Ҏ(gu)表method_infoQ?
    cd 名称 数量 含义
    u2 access_flags 1 讉K修饰W?/td>
    u2 name_index 1 Ҏ(gu)单名U的帔R池入?/td>
    u2 descriptor_index 1 Ҏ(gu)描述W的帔R池入?/td>
    u2 attributes_count 1 属性表的项?/td>
    attribute_info attributes attributes_count Ҏ(gu)属性:(x)Code,Deprecated, Exceptions和SyntheticQJVM规范Q?/td>
  14. method_info表中的访问标志对应含义:(x)值得说明的是接口的方法一定是public和abstract的,接口初始化方法可以用strictFP
    标志?/td> ?/td> 含义 使用范围
    ACC_PUBLIC 0x0001 public cd接口
    ACC_PRIVATE 0x0002 private c?/td>
    ACC_PROTECTED 0x0004 protected c?/td>
    ACC_STATIC 0x0008 static c?/td>
    ACC_FINAL 0x0010 final c?/td>
    ACC_SYNCHRONIZED 0x0020 synchronized c?/td>
    ACC_NATIVE 0x0100 native c?/td>
    ACC_ABSTRACT 0x0400 abstract cd接口
    ACC_STRICT 0x0800 strictFP cd接口?lt;clinit>Ҏ(gu)
  15. cd接口的初始化Ҏ(gu)(<clinit>)只有JVM可以直接调用Q永q不?x)被java字节码直接调用?
  16. JVM规范定义的所有属性:(x)
    属性名 使用?/td> 描述
    Code method_info Ҏ(gu)的字节码和其他数?/td>
    ConstantValue field_info final变量的?/td>
    Deprecated field_info,method_info 字段或方法被用的指C符
    Exceptions method_info Ҏ(gu)可能抛出的可被检的异常
    InnerClasses ClassFile 内部、外部类的列?/td>
    LineNumberTable Code_attribute Ҏ(gu)的行号与字节码的映射
    LocalVariableTable Code_attribute Ҏ(gu)的局部变量的描述
    SourceFile ClassFile 源文件名
    Synthetic field_info,method_info ~译器生的字段或者方法的指示W?/td>
  17. code属性的表code_attributeQ?
    cd 名称 数量 含义
    u2 attribute_name_index 1 包含“Code”的帔R池入?/td>
    u4 attribute_length 1 去除起始6个字节后的code属性长?/td>
    u2 max_stack 1 Ҏ(gu)执行L时刻Q该Ҏ(gu)操作数栈的最大长度(以字为单位)
    u2 max_locals 1 Ҏ(gu)局部变量需要的存储I间长度Q以字ؓ(f)单位Q?/td>
    u4 code_length 1 该方法字节码的长度
    u1 code code_length  
    u2 exception_table_length 1 异常表项?/td>
    exception_info exception_table exception_table_length 异常?/td>
    u2 attributes_count 1 属性数
    attribute_info attributes attributes_count code属性:(x)LineNumberTable和LocalVariableTableQJVM规范Q?/td>
  18. 异常表excption_infoQ?
    cd 名称 数量 含义
    u2 start_pc 1 代码数组起始处到异常处理器v始处的代码偏U量
    u2 end_pc 1 代码数组起始处到异常处理器结束后的一个字节的偏移?/td>
    u2 handler_pc 1 代码数组起始处蟩转到异常处理器的W一条指令的偏移?/td>
    u2 catch_type 1 异常处理器捕L(fng)异常cd的Class_info帔R池入口,如果?则表C处理finally子句Q即处理所有异?/td>
  19. constantValue属性:(x)各种基础cd加字W串cd的常量池入口查找Q结构很单,q里׃列出了?
  20. LineNumberTable属性徏立了Ҏ(gu)字节码流便宜量和源代码行号之间的映射关系Q?
    cd 名称 数量 含义
    u2 attribute_name_index 1 包含“LineNumberTable”的帔R池入?/td>
    u4 attribute_length 1 去除起始6字节后的属性长?/td>
    u2 line_number_table_length 1 line_number_info表长?/td>
    line_number_info line_number_table line_number_
    table_length
    属性表
  21. line_number_info表很单,׃个项Qu2的start_pcl出新行开始时代码数组的偏U量Qu2的line_numberl出了从start_pc开始的行号?

 

q次到q里。to be continued...



changedi 2012-09-17 16:38 发表评论
]]>
JVM学习(fn)W记Q?Q?amp;mdash;&mdash;JVM一把抓http://www.tkk7.com/changedi/archive/2012/09/07/387252.htmlchangedichangediFri, 07 Sep 2012 06:57:00 GMThttp://www.tkk7.com/changedi/archive/2012/09/07/387252.htmlhttp://www.tkk7.com/changedi/comments/387252.htmlhttp://www.tkk7.com/changedi/archive/2012/09/07/387252.html#Feedback0http://www.tkk7.com/changedi/comments/commentRss/387252.htmlhttp://www.tkk7.com/changedi/services/trackbacks/387252.html从毕业的时候断断箋l读q本书,发现已经很久了,一直只是到概念层次Q没有深入细节。今天重读这本书Q希望能从中获取更多?/p>

今天先开个头。笔记是无结构的式记录Q类似tips的list吧~

  1. 每个javaE序q行于自qJVM实例中,javaE序的启动入口必Lpublic static void main(String[] args)Q?
  2. 每个javaE序Q开始于mainQ结束于所有非守护U程的终止;
  3. jvm的体pȝ构包含:(x)c装载器子系l(装蝲classQ、运行时数据区(存放数据Q、执行引擎(执行被装载类的指令)Q?
  4. q行时数据区包含Q堆、方法区、java栈、本地方法栈、PC寄存器。其中堆和方法区是所有线E共享的Q而其他三者是U程独n的;
  5. jvm数据cd分两U:(x)基本cd{数值类型{点数{float,double}Q整数{byte,short,int,long,char}}QbooleanQreturnAddress}和引用类型{引用{c,接口Q数l}}Q基本类型存数据本nQ引用类型存数据引用Q?
  6. boolean是个特别的类型,jvm处理按int来操作,0为falseQ非0为trueQboolean数组是按byte数组来访问的Q?
  7. 引用cd中,cd接口都是对类或者实C接口的类的实例的引用Q数l是Ҏ(gu)l对象的引用Q一个特D引用是nullQ表C没有引用Q何对象;
  8. 数据cd取D_(d)(x){byteQ?字节有符PshortQ?字节有符PintQ?字节有符PlongQ?字节有符PcharQ?字节无符PfloatQ?字节IEEE754单精度,doubleQ?字节IEEE754双精度,returnAddressQ统一Ҏ(gu)中某操作码的地址QreferenceQ堆中对象的引用或null}
  9. JVM数据单元是字Q字长的设计最短要32bit?个字节,保证能容UbyteQshortQintQcharQfloatQreturnAddress和referencecd的|
  10. JVM有两U类加蝲器:(x)启动c装载器和用戯定义c装载器Q前者是jvm实现的一部分Q后者是javaE序的一部分Q不同类装蝲器装载的c被攑֜虚拟机内部不同的命名I间Q?
  11. Ҏ(gu)区存储:(x){cd载时Q读入class文g后,解析得到的类型信息:(x)全限定名Q直接父cȝ全限定名Q是cȝ型还是接口类型,讉K修饰W,直接实现接口的全限定名有序列表}Q{帔R池:(x)直接帔RQstringQint{)和对其他cd、字D和Ҏ(gu)的符号引用}Q{字段信息Q字D名Q字D늱型,字段修饰W}Q{Ҏ(gu)信息Q方法名Q方法返回类型,Ҏ(gu)参数的数量和cdQ方法的修饰W}Q{cd量:(x)static}Q{~译时常量:(x)final}Q{指向ClassLoader的引用:(x)如果是自定义装蝲的}Q{指向Classcȝ引用QClass.forName()或者object.getClass()}Q{Ҏ(gu)表:(x)虚拟Zؓ(f)每个非抽象类生成一个方法表}Q?
  12. 堆存储:(x)所有运行时创徏的类实例或数l都攑ֈ同一个堆中;
  13. E序计数器:(x)大小1个字长,内容L下一条将被执行指令的地址Q?
  14. java栈:(x)只有push和pop操作Q单位是一个栈帧,保存U程的运行状态,每个帧中存储当前的参数、局部变量、中间运结果等。当Ҏ(gu)以return或者异常抛出结束时Q当前popQ当调用一个javaҎ(gu)Ӟpush一个成ؓ(f)当前帧。因为java栈数据是每线E私有的Q可以不考虑同步问题。java栈的每个栈又包含三部分Q局部变量区、操作数栈和帧数据区。局部变量和Ҏ(gu)参数存入局部变量区Q操作数栈是jvm的工作区Q指令都要经q栈弹出数据q行q算Q一般的iload,istore{指令就是push和popQ数据Z要是支持帔R池解析、正常方法返回以?qing)异常派发机Ӟ?
  15. 本地Ҏ(gu)栈:(x)U程调用一个本地方法时Q本地方法接口用本地方法栈Q?
  16. 执行引擎Q执行指令,通用技术有解释、即时编译、自适应优化和芯片执行QSun的hotspot使用自适应优化Q刚开始对所有代码解释运行,监视代码q行情况Q把l常执行的代码编译ؓ(f)本地代码Q优化,然后l箋执行?/li>


changedi 2012-09-07 14:57 发表评论
]]>
服务器端的推http://www.tkk7.com/changedi/archive/2012/08/12/385309.htmlchangedichangediSun, 12 Aug 2012 02:51:00 GMThttp://www.tkk7.com/changedi/archive/2012/08/12/385309.htmlhttp://www.tkk7.com/changedi/comments/385309.htmlhttp://www.tkk7.com/changedi/archive/2012/08/12/385309.html#Feedback0http://www.tkk7.com/changedi/comments/commentRss/385309.htmlhttp://www.tkk7.com/changedi/services/trackbacks/385309.html服务器端推的技术,对于普通的互联|站式应用是很少涉及(qing)到的Q大家已l习(fn)惯了h响应式的”拉“,但是对于现在ajax的快速发展,以及(qing)html5的诞生,服务器端的推送技术被来多的提到。这里ȝ几个push技术。如何pushQ给谁pushQ这引Z推技术的核心——发布订阅模型。我们常见的推主要有emailpȝ、RSS、IM、消息系l等?/p>

假设一个场景,一个网站,惛_登陆用户q行消息提醒Q那么如何选择技术实现呢Q现在大多数的实现是轮询——也是间隔拉技术,定时的用ajaxh讉KserverQ将q回的数据更新到面上,通过间隔拉取来模拟出push的效果。但q毕竟还不是推,而且存在的核心问题就是请求浪费,资源费Q本可避免的服务器端压力QM一句话Q低效率?/p>

单纯的服务器端推Q?/p>

1Qhttp服务一般是做长q接的,q接不断开Q那么当有事件发生时Q服务器端可以定向的向持有连接的客户端push数据?/p>

2Qhttp响应header里的content-type讄为multipart/mixedq样的MIMEQ这U技术可以通过boundary来在header的content-type里设|一个边界|客户端通过解析边界值来区分不同的显C部分。换句话_(d)服务器端告诉客户端这个响应是有多个部分的Q客L(fng)应该通过boundary来区分这些部分ƈ分别处理。这U技术有个明昄劣势是IE不支持,多数是被用到webcamq样的应用中?/p>

3QwebsocketQhtml5才支持的最新技术,优点嘛自然是高效Q但是缺点就是客L(fng)览器的支持度了?/p>

另外的几U技术:(x)

1QpushletQ与刚才1中提CL(fng)持久q接Q服务端定期的返回js片段l到客户端,客户端持l显Cloading状态,在收到js后执行,结果更新到面上。缺点的话是服务器端对客L(fng)时的控制没有掌握,在超时后Q只有客L(fng)dh才能解决。详l优~点参看q篇文章

2Q长轮询Q与传统定时轮询不同Q长轮询?x)在服务器端dhQ直到有数据的时候再做响应,而服务器端在接到响应后马上重新请求,如此往复。具体可以参?a >q篇文章

3QFlash XML Socket relaysQ通过加入一个relay服务器,q个服务器接收到客户端的一个请求,且这个请求基于tcp的连接,然后relay?x)返回一个idl到客户端,然后客户端会(x)带着q个idhweb服务器,web服务器会(x)把响应消息给到relayQrelay再通过flash socket分发出去。当然tcpq发q接是个瓶颈,但是q种做法的效率很高,对于规模实现有益?/p>

众所周知的服务器端推是comet技术了Q长轮询其实也是一Ucomet技术。comet技术本w是个泛化了的概念,具体实现可以有多U,但是通用且多数的实现时基于XHRQXMLHttpRequestQ的ajax长轮询?/p>

对于具体的业务场景,我们可能选择不同的服务器端推{略Q对于现有的web应用比如聊天和消息可能TCP或者长q接p解决问题Q但是对于大q发下的大型|站Q拉取是更合适的选择Q长轮询可能用的?x)多一些。当然我们最期望的是websocket的表现~

参考文章:(x)

http://en.wikipedia.org/wiki/Push_technology

http://en.wikipedia.org/wiki/Extensible_Messaging_and_Presence_Protocol

http://en.wikipedia.org/wiki/Internet_Relay_Chat

http://en.wikipedia.org/wiki/Comet_(programming)

http://en.wikipedia.org/wiki/MIME#Mixed-Replace_.28experimental.29



changedi 2012-08-12 10:51 发表评论
]]>
分n一个LRUMap的实?amp;mdash;&mdash;来自apache common-collections框架http://www.tkk7.com/changedi/archive/2012/05/31/379658.htmlchangedichangediThu, 31 May 2012 05:16:00 GMThttp://www.tkk7.com/changedi/archive/2012/05/31/379658.htmlhttp://www.tkk7.com/changedi/comments/379658.htmlhttp://www.tkk7.com/changedi/archive/2012/05/31/379658.html#Feedback1http://www.tkk7.com/changedi/comments/commentRss/379658.htmlhttp://www.tkk7.com/changedi/services/trackbacks/379658.html阅读全文

changedi 2012-05-31 13:16 发表评论
]]>
Turbine框架http://www.tkk7.com/changedi/archive/2012/05/17/378394.htmlchangedichangediThu, 17 May 2012 05:54:00 GMThttp://www.tkk7.com/changedi/archive/2012/05/17/378394.htmlhttp://www.tkk7.com/changedi/comments/378394.htmlhttp://www.tkk7.com/changedi/archive/2012/05/17/378394.html#Feedback2http://www.tkk7.com/changedi/comments/commentRss/378394.htmlhttp://www.tkk7.com/changedi/services/trackbacks/378394.html首先Q必L认,turbine作ؓ(f)一个开发框Ӟ已经快绝q了Q阿里巴巴的webx框架是基于turbine做的Q所以这里简单介l一下,如果是阿里系新入职的同学Q可以参考一下,当然M开发h员如果感兴趣turbine的设计,都欢q?/p>

turbine是什么?

turbine是一个应用开发框Ӟ是一个开发web应用的工L(fng)Q?00%UjavaQ且Zjdk1.3?qing)以上。j2ee兼容且基于servletQ面向MVC构徏?/p>

turbine的框架架构overview如下Q?/p>

image

turbine的代码结构包含了services、modules和util几个大类Q在上图中可见,在servlet基础之上Q以MVC为基l构Qmodules包含了view部分?qing)actionQview主要是pagesQ其中有三种具体的module——screen、layout和navigationQaction作ؓ(f)controller存在Qtoolbox提供了很多通用的toolQservice则是整个框架的插件。一个完整的h处理程如下Q?/p>

image

h到来Qturbine的controller处理Qview部分渲染面Q然后响应输出?/p>

顺着q个程Q分析一下turbine的架构,对于view部分Q我们最直观惛_的就是pagesQpage模块值包含了几个概念Q是jsp的?q是velocity的?仅此而已。那么,以一个velocity面ZQ如何组l呢Qturbine讲究的是“U定胜于配置”Q记住这句真aQ也可以理解turbine了。在开发应用中Q要建立三个面目录Q分别是screen、layout和navigationQscreen是页面的M内容Qlayout是页面的布局Q而navigation则是一些页面修饰元素,比如下面q个面l构Q?/p>

image

q三个部分的调用序如下Q?/p>

image

因ؓ(f)U定的代码结构是在三个目录下写对应名字的java代码Q因此名字如果不一_(d)那么׃(x)出错。当Ӟ面模板目录有默认的l构Q如果在对应的目录下找不到文Ӟ׃(x)ddefault.vm文g?/p>

image

cMservletQ写一个java文g对应处理screen面Q那么代码可能是q样的:(x)

image

可以看到Q这U处理代码很像servletQ方法就像是servlet标准中的doGet和doPostQ只不过参数q行了封装。其实,turbine是一个servletQ看看turbine的源码,Turbinecȝ承了HttpServletQ实CdoGet和doPostҎ(gu)Q除了一开始初始化一pd配置相关的变量外Q在接到一个httphQgetQ后Qturbine?x)执行doGetҎ(gu)Qturbine装了request和responseQ构Z一个叫做RunData的对象,Rundata是个接口Q具体实现是DefaultTurbineRunDataQ其内部提供了获取http各种数据的方法接口。在每个h周期Qturbine都会(x)利用TurbineRunDataService新徏一个RunDataQ将所有基于servlet的请求相关的东西塞到q个data中。然后,利用从request中得到的h地址Q再调用PageLoader扑ֈ对应的PageQ执行其中的buildҎ(gu)Q其中DefaultPage里会(x)通过LayoutLoader和ScreenLoader来定位到对应的layout和screenQ然后执行其中的build相关Ҏ(gu)。这P一整套h执行完成了。值得说明的就是如果是表单提交Q那么多数情况会(x)多出一个action的执行,也是在page里进行的。如下图

image

至于turbine中的toolQ这cdh通过配置Q以“?#8221;模式被应用的。当应用启动后,在vm面中以$开始调用某个tool的时候,׃(x)初始化这个tool。当Ӟq里qCTurbinePullService?/p>

在初步了解了turbine后,如果使用qwebxQ那么就?x)知道ƈ一定程度理解了webx的设计;没用过的,l合自己用过的mvc框架Q也可以了解一些框架设计的思\?/p>

参考资料:(x)

Turbine Tutorial

Apache Turbine

本文全部囄都截取自Turbine TutorialQ用请注明



changedi 2012-05-17 13:54 发表评论
]]>
实际应用delegate做好apiz设?amp;mdash;&mdash;从commons-io排序器想开http://www.tkk7.com/changedi/archive/2012/04/28/376947.htmlchangedichangediSat, 28 Apr 2012 03:47:00 GMThttp://www.tkk7.com/changedi/archive/2012/04/28/376947.htmlhttp://www.tkk7.com/changedi/comments/376947.htmlhttp://www.tkk7.com/changedi/archive/2012/04/28/376947.html#Feedback1http://www.tkk7.com/changedi/comments/commentRss/376947.htmlhttp://www.tkk7.com/changedi/services/trackbacks/376947.html我们已经知道Q在完成一个通用功能的设计时Q必然会(x)抽象q且隔离功能U别Q把最一般的功能抽象出来Q放到接口里去,具体实现接口的类完成具体功能。因为所有的具体实现都有共同的接口,虽然功能实际不同Q但是抽象含义相|因此在抽象别,其他c调用时可以把最抽象的接口作Z理(委托Q来调用Q思\单清晰?/p>

在commons-ioq个开源框架中Q封装了对io的基本操作,其中org.apache.commons.io.comparator包就是经典的设计典范Qcomparator֐思义是Z提供一pd的文件排序器Q辅助排序。这里我把结构图M下:(x)

image

一个AbstractFileComparator抽象cd成了一层包内抽象,直接实现接口Comparator<File>Qƈ且提供了sortҎ(gu)完成了通过比较的排序功能:(x)

public File[] sort(File... files) {
        if (files != null) {
            Arrays.sort(files, this);
        }
        return files;
    }

public List<File> sort(List<File> files) {
        if (files != null) {
            Collections.sort(files, this);
        }
        return files;
    }

 

 

 

 

所有的具体排序器实现都l承了这个AbstractFileComparator抽象c,实现compareҎ(gu)Q完成各自的比较Q比如有Ҏ(gu)文g大小比较的SizeFileComparatorQ有Ҏ(gu)修改旉比较的LastModifiedFileComparator{等。值得一提的是用到了委托的ReverseComparator和CompositeFileComparatorQReverse֐思义是反{排序Q默认的排序器都是升序的Q谁把谁排在前面,ReverseComparator通过代理一个Comparator

private final Comparator<File> delegate;

构造时作ؓ(f)参数把delegate实例化,public ReverseComparator(Comparator<File> delegate)Q最后实现compareҎ(gu)Q?/p>

public int compare(File file1, File file2) {
       return delegate.compare(file2, file1); // parameters switched round
   }

完成整个反{排序的功能,看出端倪了吧。一个代理的引入Q减了一半的工作量,把排序功能实现的非常全面?/p>

同理Q组合排序器的实现正好利用了多维的代?/p>

private final Comparator<File>[] delegates;

构造时传入的参数是一个可变长度数l,public CompositeFileComparator(Comparator<File>... delegates)Q或者一个可q代对象Qpublic CompositeFileComparator(Iterable<Comparator<File>> delegates)Q实现的compareҎ(gu)如下Q?/p>

public int compare(File file1, File file2) {
        int result = 0;
        for (Comparator<File> delegate : delegates) {
            result = delegate.compare(file1, file2);
            if (result != 0) {
                break;
            }
        }
        return result;
    }

l合排序是提供一pd排序器,序比较Q直到出C相等情况。考虑到实际应用,我们l常是否只是实现了Comparable接口Q在compareToҎ(gu)中写if else呢?引入代理的排序器api设计Q给了我们不错的启示?/p>

changedi 2012-04-28 11:47 发表评论
]]>
分n代码pd——vlisthttp://www.tkk7.com/changedi/archive/2012/04/15/374226.htmlchangedichangediSun, 15 Apr 2012 04:29:00 GMThttp://www.tkk7.com/changedi/archive/2012/04/15/374226.htmlhttp://www.tkk7.com/changedi/comments/374226.htmlhttp://www.tkk7.com/changedi/archive/2012/04/15/374226.html#Feedback1http://www.tkk7.com/changedi/comments/commentRss/374226.htmlhttp://www.tkk7.com/changedi/services/trackbacks/374226.html阅读全文

changedi 2012-04-15 12:29 发表评论
]]>
logback那些?/title><link>http://www.tkk7.com/changedi/archive/2012/03/31/373139.html</link><dc:creator>changedi</dc:creator><author>changedi</author><pubDate>Sat, 31 Mar 2012 09:14:00 GMT</pubDate><guid>http://www.tkk7.com/changedi/archive/2012/03/31/373139.html</guid><wfw:comment>http://www.tkk7.com/changedi/comments/373139.html</wfw:comment><comments>http://www.tkk7.com/changedi/archive/2012/03/31/373139.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.tkk7.com/changedi/comments/commentRss/373139.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/changedi/services/trackbacks/373139.html</trackback:ping><description><![CDATA[<p>logbackQ?/p> <p>logback可以认ؓ(f)是log4j的升U版Q依然出自Ceki GülcüQ用简单,只需要在你的classpath里包含slf4j-api.jar、logback-core.jar以及(qing)logback-classic.jar卛_?/p> <p>单代码示例如下:(x)</p> <p>import org.slf4j.Logger;<br />import org.slf4j.LoggerFactory;</p> <p>import ch.qos.logback.classic.LoggerContext;<br />import ch.qos.logback.core.util.StatusPrinter;<br />public class LogTest {</p> <p><br />    public static void main(String[] args) {<br /><br />        Logger logger = LoggerFactory<br />                .getLogger(LogTest .class.getName());<br />        logger.debug("Hello world.");</p> <p>}</p> <p>其中的logger对象和LoggerFactory都来自slf4j目Qslf4j是一个很好的facadeQ包装了接口Q就像之前写的一文章中的提到的commons-logging框架?/p> <p>同样也可以认为logback+slf4j是log4j+commons-logging的升U版吧?/p> <p>logback的架构:(x)</p> <p>logback包含3个子工程——classic、core和access。core是其他两个的基础Q也是logback的核心;classic扩展了coreQ内|了slf4jQ但也支持各U其他log门面。同log4j一Plogback的主要构成也是Logger、Appender和Layout。Logger是核心控制器?qing)调用入口,Appenderȝ配置和写日志实际processQLayout控制日志样式Q是Appender的重要配|。值得注意的是Q?个基本核心居然不都在core模块中,Logger是在classic里的?/p> <p>对于Logger来讲Q和Log4j一PLogger是一个层ơ结构,每个logger都有一个name属性在LoggerFactory中被一个map理着。对于Logback来说Q这个factory是classic下的LoggerContext。这里插一D自我理解,在做facade模式的时候,代码l构可能?x)引入一个占位性质的类Q就像slf4j中的StaticLoggerBinderQ这个类在org.slf4j.impl包下Q是一个单例,但是U有构造函数却抛出了一个异常,q个在不熟?zhn)q种写法时会(x)产生困惑。其实这是很合理的,logback的classic中也有org.slf4j.implq个包,其中也有StaticLoggerBinderq个c,但是内容完整了许多。这完成了slf4j的Q务,同时解除了耦合。我认ؓ(f)q种解耦合方式非常好,plugin的感觉?/p> <p>再回来说LoggerContextQ这个对应了log4j的LogManager和HierarchyQ用一个hashtable来维护logger的cache。代码真的是z了很多Q再回头看看log4j中LogManager的getLoggerҎ(gu)Q就知道logback的简z了Q一个while遍历省去了一个hierarchy。当然这里得补充一句,log4j包括logback的整个日志框架对于logger对象Q是一个层ơ结构,q也是ؓ(f)什么log4j中有个Hierarchy的东西的原因。是一个层ơ的话,对于通过包名来管理日志记录等U的理方式来说Q就存在着level的控Ӟ也就是说Q你某个包名的类被设定了日志U别是什么,那么对应U别以下的日志才?x)被打印出来。有q样一个规则,logger的日志记录有效level由hierarchy中离它最q且方向向上QupwardsQ的一个logger的别决定。如官网上的例子Q?/p> <p><a href="http://www.tkk7.com/images/blogjava_net/changedi/Windows-Live-Writer/logback_C9C9/image_2.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.tkk7.com/images/blogjava_net/changedi/Windows-Live-Writer/logback_C9C9/image_thumb.png" width="244" height="106" /></a></p> <p>q里?个loggerQ但是只有root被设定了level是DEBUGQ其他几个logger׃没有被设定,依照规则Q就都是root的level了?/p> <p><a href="http://www.tkk7.com/images/blogjava_net/changedi/Windows-Live-Writer/logback_C9C9/image_4.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.tkk7.com/images/blogjava_net/changedi/Windows-Live-Writer/logback_C9C9/image_thumb_1.png" width="244" height="103" /></a></p> <p>W二个例子中Q每个logger都自p定了levelQ那么依据规则,d最q的被用,当然自己自己最q了?/p> <p><a href="http://www.tkk7.com/images/blogjava_net/changedi/Windows-Live-Writer/logback_C9C9/image_6.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.tkk7.com/images/blogjava_net/changedi/Windows-Live-Writer/logback_C9C9/image_thumb_2.png" width="244" height="104" /></a></p> <p>W三个例子里QX.Y没有讑֮levelQ那么离它最q且upwards的一个是XQ那么X.Y的level和X的一栗?/p> <p>level控制是日志框架的基础Q什么样的日志在什么环境下被打印出来,q种讑֮可以配置才是一个合理的日志pȝ。一贯的level控制规则如下昄Q?/p> <p><a href="http://www.tkk7.com/images/blogjava_net/changedi/Windows-Live-Writer/logback_C9C9/image_8.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.tkk7.com/images/blogjava_net/changedi/Windows-Live-Writer/logback_C9C9/image_thumb_3.png" width="240" height="69" /></a></p> <p>appenderq个东西Q和log4j是一L(fng)Q支持一个logger有多个appenderQ在AppenderAttachableImpl里会(x)l护一个CopyOnWriteArrayList来存放一个logger的appender。每ơlog的时候都?x)遍历这个list里的appender然后调用对应的doAppendҎ(gu)。我们在配置的时候每个logger的配|上有个additivity属性,默认为true。appenderq个东西同logger一hl承性。additivity属性就是控制这U承的Qtrue代表开启,false代表关闭Q一般用都?x)设|falseQ因为如果是trueQ那么如果appender比较多的话可能日志打的就有点太离׃?/p> <p>Layout和log4j一P我没有细研究q,但是我认是控制输出的一大法宝,下次研究layout的时候做一个详l的分nQ一般大安使用patternLayoutQ写个表辑ּ以?/p> <p>在之前的那篇写log的文章中Q提到过一个优化写法,是不要直接写出q样的代码:(x)</p><pre>logger.debug("Entry number: " + i + " is " + String.valueOf(entry[i]));</pre> <p>构造string参数是复杂且耗时的。要用if判断一下。而slf4j提供了比较合适的解决Ҏ(gu)Q?/p><pre>Object entry = new SomeObject(); <br />logger.debug("The entry is {}.", entry);</pre> <p>q样的代码就更符合程序设计h员的~写?fn)惯Q而且可读性我认ؓ(f)要远q高于用+可接。但是遗憄是,q种~码风格作者ƈ没有持箋贯彻下去Q没有用变长参数Q而是用的object[]l止了参数的个数。也是_(d)你对于多个变量的log的话Q只能这么写Q?/p><pre>Object[] paramArray = {newVal, below, above};<br />logger.debug("Value {} was inserted between {} and {}.", paramArray);</pre> <p>在执行log的时候,?x)有一个判断流E,依据官网上的介绍Q我要翻译一下:(x)</p> <p>1QGet the filter chain decisionQ如果存在,试调用<code>TurboFilter</code> Q?code>TurboFilter</code> ?x)设|一个整个上下文范围的阈值或者过滤掉每个logh的相兛_数。如果这个filterq回的参数是<code>FilterReply.DENY</code> Q那么logl束Q如?code>FilterReply.NEUTRAL</code>q回Q则q入W?步,如果FilterReply.ACCEPT Q直接第3步?/p> <p>2Q?Apply the <a >basic selection rule</a>Q如果logh的阈值和高于配置的阈|那么攑ּ处理该log?/p> <p>3Q?Create a <code>LoggingEvent</code> objectQlogback?x)构Z个LoggingEvent对象Q包含了所有的h参数。其中有些参数可能是延迟加蝲的?/p> <p>4Q?Invoking appendersQlogback调用doAppendҎ(gu)?/p> <p>5Q?Formatting the outputQlayout?x)把LoggingEvent对象按固定格式格式化q返回字W串形式Q像SocketAppenderq样的方法不?x)返回字W串Q相似的只会(x)把它序列化?/p> <p>6Q?nbsp; Sending out the <code><font face="微Y雅黑">LoggingEventQ把最lŞ式打印到对应的目的地址?/font></code></p> <p><code><font face="微Y雅黑">程图见q里<a >http://logback.qos.ch/manual/underTheHood.html</a></font></code></p> <p><code><font face="微Y雅黑">最后还是通过性能讨论l束q篇短文Q性能的东西,我们不去看代码的话,是无法估计复杂度的变化的。那么就官网上给出的3条提C,W一炚w对参数构建,W二炚w对level的定位,q个在看q代码后Q发现确实精了,其是那U复杂的hierarchyl构没有了,U性的链条q行h明显?x)快Q算是去除冗余做了优化吧。第3条针对说format和write?x)快Q尤其是format被大力投入改q,q个在看q代码后Q可以做个比较?/font></code></p> <p>本文是一半自主半翻译的文章吧,重在学习(fn)?/p> <p>参考文献:(x)</p> <p><a >http://logback.qos.ch/manual/introduction.html</a></p><img src ="http://www.tkk7.com/changedi/aggbug/373139.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/changedi/" target="_blank">changedi</a> 2012-03-31 17:14 <a href="http://www.tkk7.com/changedi/archive/2012/03/31/373139.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>微博sdk的设?/title><link>http://www.tkk7.com/changedi/archive/2012/02/12/369810.html</link><dc:creator>changedi</dc:creator><author>changedi</author><pubDate>Sun, 12 Feb 2012 03:23:00 GMT</pubDate><guid>http://www.tkk7.com/changedi/archive/2012/02/12/369810.html</guid><wfw:comment>http://www.tkk7.com/changedi/comments/369810.html</wfw:comment><comments>http://www.tkk7.com/changedi/archive/2012/02/12/369810.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.tkk7.com/changedi/comments/commentRss/369810.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/changedi/services/trackbacks/369810.html</trackback:ping><description><![CDATA[     摘要: 框架介绍Q?<br>主要分ؓ(f)几个部分Q核心httpClient部分Q认证相关的token部分和api调用部分? <br> <br>Weiboq个cL一个主体核心,调用的入口? <br> <br>当用户完成上面介l的授权后,通过weiboq个cL调用api实现功能?<br>  <a href='http://www.tkk7.com/changedi/archive/2012/02/12/369810.html'>阅读全文</a><img src ="http://www.tkk7.com/changedi/aggbug/369810.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/changedi/" target="_blank">changedi</a> 2012-02-12 11:23 <a href="http://www.tkk7.com/changedi/archive/2012/02/12/369810.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>MySql性能相关的一些概?性能tip0Q?/title><link>http://www.tkk7.com/changedi/archive/2012/01/17/368624.html</link><dc:creator>changedi</dc:creator><author>changedi</author><pubDate>Tue, 17 Jan 2012 00:58:00 GMT</pubDate><guid>http://www.tkk7.com/changedi/archive/2012/01/17/368624.html</guid><wfw:comment>http://www.tkk7.com/changedi/comments/368624.html</wfw:comment><comments>http://www.tkk7.com/changedi/archive/2012/01/17/368624.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.tkk7.com/changedi/comments/commentRss/368624.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/changedi/services/trackbacks/368624.html</trackback:ping><description><![CDATA[<p>题首Q这是最q读《高性能MySqL W二版》记录下来的东西~</p> <p>#读锁Q共享锁Q、写锁(排他锁)Q读锁是׃n的,互不dQ读取同一资源互不影响Q写锁排他,一个写锁会(x)d其他的读写操作?/p> <p>#锁定对象的粒度:(x)表锁和行锁?/p> <p>表锁Q整个表加锁Q当写操作时Q加写锁Q资源访问排他。当没有写时Q加读锁Q读锁互不冲H。写锁比读锁有高优先U。开销较小?/p> <p>行锁:(x)对一行加锁,开销大,支持最大ƈ发处理?/p> <p>#事务QACID</p> <p>A原子性:(x)一个事务是一个原子不可分的工作单元,内部的工作不?x)被部分执行Q要么全部执行,要么Ҏ(gu)不执?/p> <p>C一致性:(x)数据库从一U一致状态{到另一U一致状态,事务执行q程中的数据改变不会(x)影响数据库数据?/p> <p>I 隔离性:(x)某个事务的结果只有在事务完成后才对其他事务可见?/p> <p>D持久性:(x)一个事务提交后的结果改变将是持久的Q不?x)马上消失?/p> <p>#MVCCQ多版本q发控制</p> <p>#几个存储引擎Q?/p> <p>MyISAMQ加表锁Q在select查询时可以在同一张表完成插入Qƈ发插入)Q可以基于BLOB和TEXT的前500字符q行相关索引?/p> <p>InnoDBQ事务引擎,适合处理大量短期事务Q基于聚烦引,不压~烦?/p> <p>MemoryQ基于堆的,内存存储Q支持哈希烦?/p> <p>ArchiveQ只支持insert和selectQ不支持索引Q缓冲了数据写操作,插入时用zlib法压羃Q比MyISAM盘I(y)O消耗少Q所?的select查询执行全表扫描Q适合loggingQ支持行U锁?/p> <table border="0" cellspacing="0" cellpadding="2" width="597"> <tbody> <tr> <td valign="top" width="101"><strong>存储引擎</strong></td> <td valign="top" width="101"><strong>MySqL版本</strong></td> <td valign="top" width="99"><strong>事务</strong></td> <td valign="top" width="98"><strong>锁粒?/strong></td> <td valign="top" width="98"><strong>主要应用</strong></td> <td valign="top" width="98"><strong>忌用</strong></td></tr> <tr> <td valign="top" width="101">MyISAM</td> <td valign="top" width="103">全部</td> <td valign="top" width="99">不支?/td> <td valign="top" width="98">支持q发插入的表?/td> <td valign="top" width="98">selectQinsertQ高负蝲</td> <td valign="top" width="98">dq的场?/td></tr> <tr> <td valign="top" width="101">MyISAM Merge</td> <td valign="top" width="105">全部</td> <td valign="top" width="99">不支?/td> <td valign="top" width="98">支持q发插入的表?/td> <td valign="top" width="98">分段归档Q数据仓?/td> <td valign="top" width="97">许多全局查找</td></tr> <tr> <td valign="top" width="100">Memory(Heap)</td> <td valign="top" width="107">全部</td> <td valign="top" width="98">不支?/td> <td valign="top" width="97">表锁</td> <td valign="top" width="97">中间计算Q静态数据查?/td> <td valign="top" width="97">大型数据集,持久性存?/td></tr> <tr> <td valign="top" width="100">InnoDB</td> <td valign="top" width="108">全部</td> <td valign="top" width="98">支持</td> <td valign="top" width="97">支持MVCC的行U锁</td> <td valign="top" width="97">事务处理</td> <td valign="top" width="97">?/td></tr> <tr> <td valign="top" width="100">Falcon</td> <td valign="top" width="109">6.0</td> <td valign="top" width="98">支持</td> <td valign="top" width="97">支持MVCC的行U锁</td> <td valign="top" width="97">事务处理</td> <td valign="top" width="97">?/td></tr> <tr> <td valign="top" width="100">Archive</td> <td valign="top" width="110">4.1</td> <td valign="top" width="98">支持</td> <td valign="top" width="97">支持MVCC的行U锁</td> <td valign="top" width="97">日志记录Q聚合分?/td> <td valign="top" width="96">需要随取、更新、删?/td></tr> <tr> <td valign="top" width="99">CSV</td> <td valign="top" width="111">4.1</td> <td valign="top" width="98">不支?/td> <td valign="top" width="97">表锁</td> <td valign="top" width="97">日志记录Q大规模加蝲外部数据</td> <td valign="top" width="96">需要随取、烦?/td></tr> <tr> <td valign="top" width="99">Blackhole</td> <td valign="top" width="112">4.1</td> <td valign="top" width="98">支持</td> <td valign="top" width="96">支持MVCC的行U锁</td> <td valign="top" width="96">日志记录或同步归?/td> <td valign="top" width="96">除非有特别目的,否则不适合M场合</td></tr> <tr> <td valign="top" width="99">Federated</td> <td valign="top" width="112">5.0</td> <td valign="top" width="98">N/A</td> <td valign="top" width="96">N/A</td> <td valign="top" width="96">分布式数据源</td> <td valign="top" width="96">除非有特别目的,否则不适合M场合</td></tr> <tr> <td valign="top" width="99">NDB Cluster</td> <td valign="top" width="112">5.0</td> <td valign="top" width="98">支持</td> <td valign="top" width="96">行?/td> <td valign="top" width="96">高可靠?/td> <td valign="top" width="96">大部分典型应?/td></tr> <tr> <td valign="top" width="99">PBXT</td> <td valign="top" width="112">5.0</td> <td valign="top" width="98">支持</td> <td valign="top" width="96">支持MVCC的行U锁</td> <td valign="top" width="96">事务处理Q日志记?/td> <td valign="top" width="96">需要聚集烦?/td></tr> <tr> <td valign="top" width="99">SolidDB</td> <td valign="top" width="112">5.0</td> <td valign="top" width="98">支持</td> <td valign="top" width="96">支持MVCC的行U锁</td> <td valign="top" width="96">事务处理</td> <td valign="top" width="96">?/td></tr> <tr> <td valign="top" width="99">Maria</td> <td valign="top" width="112">6.x</td> <td valign="top" width="98">支持</td> <td valign="top" width="96">支持MVCC的行U锁</td> <td valign="top" width="97">替代MyISAM</td> <td valign="top" width="96">?/td></tr></tbody></table><img src ="http://www.tkk7.com/changedi/aggbug/368624.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/changedi/" target="_blank">changedi</a> 2012-01-17 08:58 <a href="http://www.tkk7.com/changedi/archive/2012/01/17/368624.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>mysql性能tip(1)http://www.tkk7.com/changedi/archive/2011/12/12/366123.htmlchangedichangediMon, 12 Dec 2011 02:24:00 GMThttp://www.tkk7.com/changedi/archive/2011/12/12/366123.htmlhttp://www.tkk7.com/changedi/comments/366123.htmlhttp://www.tkk7.com/changedi/archive/2011/12/12/366123.html#Feedback2http://www.tkk7.com/changedi/comments/commentRss/366123.htmlhttp://www.tkk7.com/changedi/services/trackbacks/366123.html
1Q更通常更好Q选择能正表C数据的最类型?

2Q简单就好,用简单类型优于用复杂cd?

3Q避免NULLQ尽量定义字Dؓ(f)not null。性能提升很小?

  阅读全文

changedi 2011-12-12 10:24 发表评论
]]>
工具包系?2)QimageSpider工具&mdash;&mdash;可定制的囑փ抓取http://www.tkk7.com/changedi/archive/2011/11/02/362540.htmlchangedichangediWed, 02 Nov 2011 07:43:00 GMThttp://www.tkk7.com/changedi/archive/2011/11/02/362540.htmlhttp://www.tkk7.com/changedi/comments/362540.htmlhttp://www.tkk7.com/changedi/archive/2011/11/02/362540.html#Feedback1http://www.tkk7.com/changedi/comments/commentRss/362540.htmlhttp://www.tkk7.com/changedi/services/trackbacks/362540.html
我希望这个小工具的功能点有以下几:(x)1.l定面抓取面的图片;2.l定面和过滤规则,抓取面的图片ƈ存到本地盘或内存;

主要的技术点不多Q?.囄链接的获取(htmlparser搞定Q;2.囄的读写(imageIo搞定Q;3.规则的制定(来源于需求)

介于Ҏ(gu)的多PW一个版本的spider只是很简单的功能实现Q未来希望加入的是可扩展的规则对象

废话,上代码:(x)
  阅读全文

changedi 2011-11-02 15:43 发表评论
]]>
工具包系?1)QhtmlStat工具&mdash;&mdash;l计面信息http://www.tkk7.com/changedi/archive/2011/10/31/362365.htmlchangedichangediMon, 31 Oct 2011 05:28:00 GMThttp://www.tkk7.com/changedi/archive/2011/10/31/362365.htmlhttp://www.tkk7.com/changedi/comments/362365.htmlhttp://www.tkk7.com/changedi/archive/2011/10/31/362365.html#Feedback3http://www.tkk7.com/changedi/comments/commentRss/362365.htmlhttp://www.tkk7.com/changedi/services/trackbacks/362365.html
当然先说下开发环境:(x)jdk1.6.11Qmaven2Qgit

主要的依赖目前只在pom中更C一部分Q有加入的会(x)慢慢加入Q具体可以看github上的目信息

有愿意一L(fng)代码的,可以留言我,
  阅读全文

changedi 2011-10-31 13:28 发表评论
]]>
tomcat程ȝhttp://www.tkk7.com/changedi/archive/2011/09/27/359612.htmlchangedichangediTue, 27 Sep 2011 06:54:00 GMThttp://www.tkk7.com/changedi/archive/2011/09/27/359612.htmlhttp://www.tkk7.com/changedi/comments/359612.htmlhttp://www.tkk7.com/changedi/archive/2011/09/27/359612.html#Feedback2http://www.tkk7.com/changedi/comments/commentRss/359612.htmlhttp://www.tkk7.com/changedi/services/trackbacks/359612.html首先声明Q这个可能已l算是老掉牙的东西了~~~Long Long ago

断断l箋两周旉来看了看tomcat4的源码。虽然有点古旧,但是配合着《How tomcat works》一书看看源码,q是很惬意的事情。中途数ơ想拿vU笔抑或打开word书写下笔讎ͼ但是书中z的文风让我觉得没有什么可以记下的。直到最后读完这书,q完源码。才觉得应该C一些要Ҏ(gu)。简单称之ؓ(f)ȝ吧?

clip_image002

其实搞懂tomcat或者是cM的servlet的工作原理,只要配合理解q张囑ְ可以了。这是tomcat的整个工作流E?

一个HTTPh到来Q其实本质上只是一个输入流Q在q个中蕴含了那些字节代表了q个h的语义。而图中的1.message抽象了q个,把它表示Z条信息。在到达容器的第一时刻Q容器是交给connector来处理的。首先这里得考虑一个容器的启动q程Q启动时做的一个重要事情就是初始化connectorQ而connector初始化时q什么呢Q显Ӟ创徏socket。一切初始化好了Q才有第一步消息到来这件事情咯?

信息CQconnectorq的事情是如图中的2?步——创建httph对象和响应对象。当然这个行Z不是connector自己q的Q它只是雇䄦了一个叫做HttpProcessor的兄弟来q活。真正的creation都是q个兄弟q的。HttpProcessor里面设计了一些简单的q发多线EtrickQ基本上是让socket{待着h信息的到来,来一个,处理一个。HttpProcessor的一句话ȝ是利用多线E技术parse整个h的stream。几个parse步骤分别是:(x)解析connectionQ解析requestQ解析headers。补充一句,request和response对象都是在HttpProcessor初始化的时候初始化的,但是它们内容的填充是在parse的时候完成的?

接着Qconnector的Q务就l束了。然后一个invoke其实是工作的交接,该context重磅d了。Context以其名字决定了光气的侧漏无疑Q基本上所有的东西都包含在内。我们把3的invoke当做一些context的自我设|(初始化)Q那?的invoke是context的表演开始了。首先在N没有l出的是loader和logger的处理,context?x)在q两个依赖对象不为空的情况下q行它们。Loader是设|java class loader的,tomcat自己定义了一个classloader来加载特定的cR而logger无非是把日志给启动h。当然在启动pipeline之前做了启动subcontainer的操作。这是可以理解的Q用计算机本质的递归来理解,有点像是先序遍历?wi)的感觉。而pipeline被启动后Q后l还有一个manager的启动,q个manager是主要用来管理session的。而所有这些都是可以配|的?

照着上图主要说说pipelineQpipeline是水U了Q上面有很多的阀门valveQ阀门可以自己加Qpipeline的的工作是步骤5Q顺序invoke每个阀门。其实也不是pipeline启动Qpipeline其实只是启动了内|的pipelineContext对象Q而这个对象会(x)不断的调用invokenext()Ҏ(gu)来实现流水线的执行。而这些个valve?x)调用wrapperQ他们的invokeҎ(gu)?x)启动wrapperQ在完mapping后,wrapper?x)allocate一个servlet实例Q接着servlet启动、干zR开始自q生命周期……q个世界开始活跃了?

That is it

最后奉上一张稍微详l点的图帮助理解?

clip_image004

当然Q美妙的设计q里没有Ԍ不是因ؓ(f)旉不够或者是I间不Q而是我自p没有完全的消化,tomcat我认Z设计上讲Q结构是beautiful的。光是lifecycle的设计以?qing)各个类模块区分QconnectorQloaderQcontextQwrapper以及(qing)manager{等Q之间的初始化调用等l节每个拿出来都够写本书了。So~~~read the fucking source code by yourself?

参考资料:(x)

《How tomcat works?/p>

Tomcat pȝ架构与设计模式,W?1 部分: 工作原理http://www.ibm.com/developerworks/cn/java/j-lo-tomcat1/



changedi 2011-09-27 14:54 发表评论
]]>
commons-pool学习(fn)W记http://www.tkk7.com/changedi/archive/2011/05/06/349665.htmlchangedichangediFri, 06 May 2011 02:53:00 GMThttp://www.tkk7.com/changedi/archive/2011/05/06/349665.htmlhttp://www.tkk7.com/changedi/comments/349665.htmlhttp://www.tkk7.com/changedi/archive/2011/05/06/349665.html#Feedback6http://www.tkk7.com/changedi/comments/commentRss/349665.htmlhttp://www.tkk7.com/changedi/services/trackbacks/349665.html阅读全文

changedi 2011-05-06 10:53 发表评论
]]>
调试技巧(随时ȝQ?/title><link>http://www.tkk7.com/changedi/archive/2011/04/25/348978.html</link><dc:creator>changedi</dc:creator><author>changedi</author><pubDate>Mon, 25 Apr 2011 07:45:00 GMT</pubDate><guid>http://www.tkk7.com/changedi/archive/2011/04/25/348978.html</guid><wfw:comment>http://www.tkk7.com/changedi/comments/348978.html</wfw:comment><comments>http://www.tkk7.com/changedi/archive/2011/04/25/348978.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/changedi/comments/commentRss/348978.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/changedi/services/trackbacks/348978.html</trackback:ping><description><![CDATA[     摘要: 调试技巧(随时ȝQ:(x) <br> <br>F5单步q入Q在需要进入某步方法时Q?<br> <br>F6单步调试Q一般用于单步执行) <br> <br>F7单步跛_Q蟩调试区段Ҏ(gu)Q?<br> <br>F8调试恢复 <br> <br>  <a href='http://www.tkk7.com/changedi/archive/2011/04/25/348978.html'>阅读全文</a><img src ="http://www.tkk7.com/changedi/aggbug/348978.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/changedi/" target="_blank">changedi</a> 2011-04-25 15:45 <a href="http://www.tkk7.com/changedi/archive/2011/04/25/348978.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JTidy的一些小tipshttp://www.tkk7.com/changedi/archive/2011/04/19/348595.htmlchangedichangediTue, 19 Apr 2011 13:33:00 GMThttp://www.tkk7.com/changedi/archive/2011/04/19/348595.htmlhttp://www.tkk7.com/changedi/comments/348595.htmlhttp://www.tkk7.com/changedi/archive/2011/04/19/348595.html#Feedback0http://www.tkk7.com/changedi/comments/commentRss/348595.htmlhttp://www.tkk7.com/changedi/services/trackbacks/348595.htmlJTidy是一个用java写的HTML语法查器Q用JTidy可以查ƈ修正语法不正的htmlQ同时还可以对html的DOMq行分析。Xhtml和html有很多不同,其中几个主要的区别是
  阅读全文

changedi 2011-04-19 21:33 发表评论
]]>
Velocity学习(fn)W记Q下Q?/title><link>http://www.tkk7.com/changedi/archive/2011/04/07/347794.html</link><dc:creator>changedi</dc:creator><author>changedi</author><pubDate>Thu, 07 Apr 2011 07:43:00 GMT</pubDate><guid>http://www.tkk7.com/changedi/archive/2011/04/07/347794.html</guid><wfw:comment>http://www.tkk7.com/changedi/comments/347794.html</wfw:comment><comments>http://www.tkk7.com/changedi/archive/2011/04/07/347794.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.tkk7.com/changedi/comments/commentRss/347794.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/changedi/services/trackbacks/347794.html</trackback:ping><description><![CDATA[  <h1>Velocity<span style="font-family: 宋体">W记?/span></h1> <h2>Velocity<span style="font-family: 宋体">?/span>struts<span style="font-family: 宋体">l合应用Q?/span></h2> <p><span style="font-family: 宋体">具体通过一个实际的例子来解释,例子选择以传l的注册模块ZQ主要是</span>joseph<span style="font-family: 宋体">的书上就q么写的Q?/span></p> <p><span style="font-family: 宋体">首先Q?/span>web.xml<span style="font-family: 宋体">文g配置情况</span>struts<span style="font-family: 宋体">部分׃讲了Q?/span>velocity<span style="font-family: 宋体">的配|如下所C:(x)</span></p> <p><servlet></p> <p><servlet-name>velocity</servlet-name></p> <p><servlet-class>org.apache.velocity.tools.view.servlet.</p> <p>VelocityViewServlet</servlet-class></p> <p><init-param></p> <p><param-name>toolbox</param-name></p> <p><param-value>/WEB-INF/toolbox.xml</param-value></p> <p></init-param></p> <p><load-on-startup>10</load-on-startup></p> <p></servlet></p> <p><!-- Action Servlet Mapping --></p> <p><servlet-mapping></p> <p><servlet-name>velocity</servlet-name></p> <p><url-pattern>*.vm</url-pattern></p> <p></servlet-mapping></p> <p><span style="font-family: 宋体">其中</span>velocity<span style="font-family: 宋体">?/span>servlet<span style="font-family: 宋体">配置中的初始参数传入?/span>toolbox.xml<span style="font-family: 宋体">Q该文g的具体内容如下:(x)</span></p> <p><?xml version="1.0"?></p> <p><toolbox></p> <p><tool></p> <p><key>toolLoader</key></p> <p><class>org.apache.velocity.tools.tools.ToolLoader</class></p> <p></tool></p> <p><tool></p> <p><key>link</key></p> <p><class>org.apache.velocity.tools.struts.LinkTool</class></p> <p></tool></p> <p><tool></p> <p><key>msg</key></p> <p><class>org.apache.velocity.tools.struts.MessageTool</class></p> <p></tool></p> <p><tool></p> <p><key>errors</key></p> <p><class>org.apache.velocity.tools.struts.ErrorsTool</class></p> <p></tool></p> <p><tool></p> <p><key>form</key></p> <p><class>org.apache.velocity.tools.struts.FormTool</class></p> <p></tool></p> <p></toolbox></p> <p><span style="font-family: 宋体">q个</span>xml<span style="font-family: 宋体">文g的意义就在于定义了很多类Q来串联整个</span>struts<span style="font-family: 宋体">?/span>velocity<span style="font-family: 宋体">q有</span>javabean<span style="font-family: 宋体">{各个元素?/span></p> <p><span style="font-family: 宋体">接着开始配|?/span>struts<span style="font-family: 宋体">了,首先考虑到这个应用,</span>struts<span style="font-family: 宋体">的第一步就是要?/span>form<span style="font-family: 宋体">了。首先构Z?/span>RegisterForm<span style="font-family: 宋体">。代码如下,q个</span>javabean<span style="font-family: 宋体">用来当做</span>model<span style="font-family: 宋体">定义数据?/span></p> <p style="text-align: left" class="MsoNormal" align="left"><strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 10pt">package</span></strong><span style="font-family: 'Courier New'; color: black; font-size: 10pt"> app;</span></p> <p style="text-align: left" class="MsoNormal" align="left"><strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 10pt">import</span></strong><span style="font-family: 'Courier New'; color: black; font-size: 10pt"> org.apache.struts.action.*;</span></p> <p style="text-align: left" class="MsoNormal" align="left"><strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 10pt">public</span></strong><strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 10pt">class</span></strong><span style="font-family: 'Courier New'; color: black; font-size: 10pt"> <u>RegisterForm</u> </span><strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 10pt">extends</span></strong><span style="font-family: 'Courier New'; color: black; font-size: 10pt"> ActionForm {</span></p> <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Courier New'; color: black; font-size: 10pt"> </span><strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 10pt">protected</span></strong><span style="font-family: 'Courier New'; color: black; font-size: 10pt"> String </span><span style="font-family: 'Courier New'; color: #0000c0; font-size: 10pt">username</span><span style="font-family: 'Courier New'; color: black; font-size: 10pt">;</span></p> <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Courier New'; color: black; font-size: 10pt"> </span><strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 10pt">protected</span></strong><span style="font-family: 'Courier New'; color: black; font-size: 10pt"> String </span><span style="font-family: 'Courier New'; color: #0000c0; font-size: 10pt">password</span><span style="font-family: 'Courier New'; color: black; font-size: 10pt">;</span></p> <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Courier New'; color: black; font-size: 10pt"> </span><strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 10pt">protected</span></strong><span style="font-family: 'Courier New'; color: black; font-size: 10pt"> String </span><span style="font-family: 'Courier New'; color: #0000c0; font-size: 10pt">password2</span><span style="font-family: 'Courier New'; color: black; font-size: 10pt">;</span></p> <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Courier New'; color: black; font-size: 10pt"> </span><strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 10pt">public</span></strong><span style="font-family: 'Courier New'; color: black; font-size: 10pt"> String <span style="background: silver">getUsername</span>() { </span><strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 10pt">return</span></strong><strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 10pt">this</span></strong><span style="font-family: 'Courier New'; color: black; font-size: 10pt">.</span><span style="font-family: 'Courier New'; color: #0000c0; font-size: 10pt">username</span><span style="font-family: 'Courier New'; color: black; font-size: 10pt">; }</span></p> <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Courier New'; color: black; font-size: 10pt"> </span><strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 10pt">public</span></strong><span style="font-family: 'Courier New'; color: black; font-size: 10pt"> String getPassword() { </span><strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 10pt">return</span></strong><strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 10pt">this</span></strong><span style="font-family: 'Courier New'; color: black; font-size: 10pt">.</span><span style="font-family: 'Courier New'; color: #0000c0; font-size: 10pt">password</span><span style="font-family: 'Courier New'; color: black; font-size: 10pt">; }</span></p> <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Courier New'; color: black; font-size: 10pt"> </span><strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 10pt">public</span></strong><span style="font-family: 'Courier New'; color: black; font-size: 10pt"> String getPassword2() { </span><strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 10pt">return</span></strong><strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 10pt">this</span></strong><span style="font-family: 'Courier New'; color: black; font-size: 10pt">.</span><span style="font-family: 'Courier New'; color: #0000c0; font-size: 10pt">password2</span><span style="font-family: 'Courier New'; color: black; font-size: 10pt">; }</span></p> <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Courier New'; color: black; font-size: 10pt"> </span><strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 10pt">public</span></strong><strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 10pt">void</span></strong><span style="font-family: 'Courier New'; color: black; font-size: 10pt"> setUsername(String username) { </span><strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 10pt">this</span></strong><span style="font-family: 'Courier New'; color: black; font-size: 10pt">.</span><span style="font-family: 'Courier New'; color: #0000c0; font-size: 10pt">username</span><span style="font-family: 'Courier New'; color: black; font-size: 10pt"> = username; };</span></p> <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Courier New'; color: black; font-size: 10pt"> </span><strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 10pt">public</span></strong><strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 10pt">void</span></strong><span style="font-family: 'Courier New'; color: black; font-size: 10pt"> setPassword(String password) { </span><strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 10pt">this</span></strong><span style="font-family: 'Courier New'; color: black; font-size: 10pt">.</span><span style="font-family: 'Courier New'; color: #0000c0; font-size: 10pt">password</span><span style="font-family: 'Courier New'; color: black; font-size: 10pt"> = password; };</span></p> <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Courier New'; color: black; font-size: 10pt"> </span><strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 10pt">public</span></strong><strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 10pt">void</span></strong><span style="font-family: 'Courier New'; color: black; font-size: 10pt"> setPassword2(String password) { </span><strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 10pt">this</span></strong><span style="font-family: 'Courier New'; color: black; font-size: 10pt">.</span><span style="font-family: 'Courier New'; color: #0000c0; font-size: 10pt">password2</span><span style="font-family: 'Courier New'; color: black; font-size: 10pt"> = password; };</span></p> <p><span style="font-family: 'Courier New'; color: black; font-size: 10pt">}</span></p> <p><span style="font-family: 宋体">?/span>javabean<span style="font-family: 宋体">?/span>3<span style="font-family: 宋体">?/span>field<span style="font-family: 宋体">属性,分别?/span>username<span style="font-family: 宋体">用户名,</span>password<span style="font-family: 宋体">密码?/span>password2<span style="font-family: 宋体">验证密码?/span></p> <p><span style="font-family: 宋体">接着写控制处理逻辑</span>RegisterAction<span style="font-family: 宋体">。代码如下:(x)</span></p> <p style="text-align: left" class="MsoNormal" align="left"><strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 10pt">package</span></strong><span style="font-family: 'Courier New'; color: black; font-size: 10pt"> app;</span></p> <p style="text-align: left" class="MsoNormal" align="left"><strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 10pt">import</span></strong><span style="font-family: 'Courier New'; color: black; font-size: 10pt"> org.apache.struts.action.*;</span></p> <p style="text-align: left" class="MsoNormal" align="left"><strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 10pt">import</span></strong><span style="font-family: 'Courier New'; color: black; font-size: 10pt"> javax.servlet.http.*;</span></p> <p style="text-align: left" class="MsoNormal" align="left"><strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 10pt">import</span></strong><span style="font-family: 'Courier New'; color: black; font-size: 10pt"> <u>java.io</u>.*;</span></p> <p style="text-align: left" class="MsoNormal" align="left"><strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 10pt">public</span></strong><strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 10pt">class</span></strong><span style="font-family: 'Courier New'; color: black; font-size: 10pt"> RegisterAction </span><strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 10pt">extends</span></strong><span style="font-family: 'Courier New'; color: black; font-size: 10pt"> Action {</span></p> <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Courier New'; color: black; font-size: 10pt"> </span><strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 10pt">public</span></strong><span style="font-family: 'Courier New'; color: black; font-size: 10pt"> ActionForward perform(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) {</span></p> <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Courier New'; color: black; font-size: 10pt">    RegisterForm rf = (RegisterForm) form;</span></p> <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Courier New'; color: black; font-size: 10pt">    String <u>username</u> = rf.getUsername();</span></p> <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Courier New'; color: black; font-size: 10pt">    String password = rf.getPassword();</span></p> <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Courier New'; color: black; font-size: 10pt">    String password2 = rf.getPassword2();</span></p> <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Courier New'; color: black; font-size: 10pt">    </span><strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 10pt">if</span></strong><span style="font-family: 'Courier New'; color: black; font-size: 10pt"> (password.equals(password2)) {</span></p> <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Courier New'; color: black; font-size: 10pt">        </span><strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 10pt">return</span></strong><span style="font-family: 'Courier New'; color: black; font-size: 10pt"> mapping.findForward(</span><span style="font-family: 'Courier New'; color: #2a00ff; font-size: 10pt">"success"</span><span style="font-family: 'Courier New'; color: black; font-size: 10pt">);</span></p> <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Courier New'; color: black; font-size: 10pt">    }</span></p> <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Courier New'; color: black; font-size: 10pt">    </span><strong><span style="font-family: 'Courier New'; color: #7f0055; font-size: 10pt">return</span></strong><span style="font-family: 'Courier New'; color: black; font-size: 10pt"> mapping.findForward(</span><span style="font-family: 'Courier New'; color: #2a00ff; font-size: 10pt">"failure"</span><span style="font-family: 'Courier New'; color: black; font-size: 10pt">);</span></p> <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Courier New'; color: black; font-size: 10pt"> }</span></p> <p><span style="font-family: 'Courier New'; color: black; font-size: 10pt">}</span></p> <p><span style="font-family: 宋体">通过</span>form<span style="font-family: 宋体">表单d数据Q如果密码和验证密码相同Q那么就跛_</span>success<span style="font-family: 宋体">Q否则是</span>failure<span style="font-family: 宋体">Q这个逻辑非常单?/span>Struts<span style="font-family: 宋体">中也看不ZQ何的</span>velocity<span style="font-family: 宋体">相关Q那当然Q这叫低耦合Q各q各的,分层处理Q?/span></p> <p><span style="font-family: 宋体">然后该配|熟(zhn)的</span>struts-config.xml<span style="font-family: 宋体">了。核心代码如下:(x)</span></p> <p><struts-config></p> <p><form-beans></p> <p><form-bean name="registerForm" type="RegisterForm"/></p> <p></form-beans></p> <p><action-mappings></p> <p><action path="/struts"</p> <p>type="RegisterAction"</p> <p>name="registerForm"></p> <p><forward name="success" path="/success.vm"/></p> <p><forward name="failure" path="/failure.vm"/></p> <p></action></p> <p></action-mappings></p> <p></struts-config></p> <p><span style="font-family: 宋体">配置文g与传l的</span>struts<span style="font-family: 宋体">出奇的一_(d)唯一变化的就是在</span>forward<span style="font-family: 宋体">里的</span>path<span style="font-family: 宋体">写成?/span>vm<span style="font-family: 宋体">文gQ而不是我们传l的</span>jsp<span style="font-family: 宋体">?/span></p> <p><span style="font-family: 宋体">好了Q写到现在,</span>MVC<span style="font-family: 宋体">中的</span>M<span style="font-family: 宋体">?/span>C<span style="font-family: 宋体">都完成了Q该?/span>velocity<span style="font-family: 宋体">上场了—?/span>View<span style="font-family: 宋体">层?/span></p> <p><span style="font-family: 宋体">注册面</span>register.vm<span style="font-family: 宋体">的核心代码:(x)</span></p> <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Courier New'; font-size: 10pt"><form action="struts.do" method="post"></span></p> <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Courier New'; font-size: 10pt"> username: <input type="text" name="username"/><BR></span></p> <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Courier New'; font-size: 10pt"> password: <input type="text" name="password"/><BR></span></p> <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Courier New'; font-size: 10pt"> again   : <input type="text" name="password2"/><BR></span></p> <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Courier New'; font-size: 10pt"><input type="submit" name="submit" value="Register"/></span></p> <p><span style="font-family: 'Courier New'; font-size: 10pt"></form></span></p> <p>Success<span style="font-family: 宋体">跌{面</span>success.vm<span style="font-family: 宋体">Q?/span></p> <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Courier New'; font-size: 10pt"><HTML></span></p> <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Courier New'; font-size: 10pt"><HEAD></span></p> <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Courier New'; font-size: 10pt"> <TITLE>Success</TITLE></span></p> <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Courier New'; font-size: 10pt"></HEAD></span></p> <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Courier New'; font-size: 10pt"><BODY></span></p> <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Courier New'; font-size: 10pt"> Registration Success!</span></p> <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Courier New'; font-size: 10pt"> Thanks for logging in $!registerForm.username</span></p> <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Courier New'; font-size: 10pt"> <P><A href="register.vm">Try Another?</A></P></span></p> <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Courier New'; font-size: 10pt"></BODY></span></p> <p><span style="font-family: 'Courier New'; font-size: 10pt"></HTML></span></p> <p><span style="font-family: 宋体">其中只用C一?/span><span style="font-family: 'Courier New'; font-size: 10pt">$!registerForm.username</span><span style="font-family: 宋体; font-size: 10pt">。整个代码完成了Q压Ҏ(gu)用到什?/span><span style="font-family: 'Courier New'; font-size: 10pt">context</span><span style="font-family: 宋体; font-size: 10pt">之类的东ѝ?br /> </span><span style="font-family: 宋体"><br /> 源代码来?/span><a >http://www.wiley.com//legacy/compbooks/gradecki/apache/index.html</a></p> <span style="font-family: 宋体; font-size: 10.5pt">下蝲</span><span style="font-family: 'Calibri','sans-serif'; font-size: 10.5pt">ch17.zip</span><span style="font-family: 宋体; font-size: 10.5pt">卛_?br /> ?font face="宋体"><a >http://www.ibm.com/developerworks/cn/java/j-sr1.html</a></font>?a class="dwauthor" title="" rel="#authortip1" hoverintent_t="undefined" hoverintent_s="0" jquery1302160132409="77">George Franciscus</a>讲的也很详细?br /> </span> <img src ="http://www.tkk7.com/changedi/aggbug/347794.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/changedi/" target="_blank">changedi</a> 2011-04-07 15:43 <a href="http://www.tkk7.com/changedi/archive/2011/04/07/347794.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>velocity学习(fn)W记Q上Q?/title><link>http://www.tkk7.com/changedi/archive/2011/04/07/velocity.html</link><dc:creator>changedi</dc:creator><author>changedi</author><pubDate>Thu, 07 Apr 2011 03:03:00 GMT</pubDate><guid>http://www.tkk7.com/changedi/archive/2011/04/07/velocity.html</guid><wfw:comment>http://www.tkk7.com/changedi/comments/347770.html</wfw:comment><comments>http://www.tkk7.com/changedi/archive/2011/04/07/velocity.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.tkk7.com/changedi/comments/commentRss/347770.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/changedi/services/trackbacks/347770.html</trackback:ping><description><![CDATA[     摘要: 杂七杂八的看了一些velocity的资料,把所见所得做个简单不pȝ的笔记写下来Q算是增忆?<br> <br>  <a href='http://www.tkk7.com/changedi/archive/2011/04/07/velocity.html'>阅读全文</a><img src ="http://www.tkk7.com/changedi/aggbug/347770.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/changedi/" target="_blank">changedi</a> 2011-04-07 11:03 <a href="http://www.tkk7.com/changedi/archive/2011/04/07/velocity.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Commons-lang记录http://www.tkk7.com/changedi/archive/2011/03/24/346976.htmlchangedichangediThu, 24 Mar 2011 12:05:00 GMThttp://www.tkk7.com/changedi/archive/2011/03/24/346976.htmlhttp://www.tkk7.com/changedi/comments/346976.htmlhttp://www.tkk7.com/changedi/archive/2011/03/24/346976.html#Feedback0http://www.tkk7.com/changedi/comments/commentRss/346976.htmlhttp://www.tkk7.com/changedi/services/trackbacks/346976.html一个最常用的工P作ؓ(f)jdk的补充,有必要看一下源码~~

  阅读全文

changedi 2011-03-24 20:05 发表评论
]]>
spring复习(fn)速记http://www.tkk7.com/changedi/archive/2011/03/19/346593.htmlchangedichangediSat, 19 Mar 2011 05:12:00 GMThttp://www.tkk7.com/changedi/archive/2011/03/19/346593.htmlhttp://www.tkk7.com/changedi/comments/346593.htmlhttp://www.tkk7.com/changedi/archive/2011/03/19/346593.html#Feedback0http://www.tkk7.com/changedi/comments/commentRss/346593.htmlhttp://www.tkk7.com/changedi/services/trackbacks/346593.html
 

Spring基础学习(fn)注记

Spring是轻量的,AOP的,DI的,框架的,容器?/span>

轻量U?/span>Q体U(2.5MQ,开销

DIQ通过DI来松耦。所谓依赖注入,即组件之间的依赖关系由容器在q行期决定,形象的来_(d)即由容器动态的某U依赖关pL入到lg之中

AOPQ理解ؓ(f)“切面”比较合适,AOP则是针对业务处理q程中的切面q行提取Q它所面对的是处理q程中的某个步骤或阶D,以获得逻辑q程中各部分之间低耦合性的隔离效果?/span>OOD/OOP面向名词领域Q?/span>AOP面向动词领域?/span>AOPq有另外一个重要特点:(x)源码l成无关性?/span>

容器?/span>Q负责AO的lifecycle和configuration。可以定义AO如何被创建、如何配|和如何怺兌?/span>

框架Q配|和l合应用Q管理AOQ通过XML配置Qƈ提供很多基础设施服务Q比如事务管理,持久化框枉成?br />

Spring’s core containerQ提供基本功能,包括BeanFactoryQ?/span>DI的基Q?/span>spring框架的基Q?/span>

Application context moduleQ?/span>core?/span>spring像个容器Q?/span>context则其像一个框架。常用的一个应用就是集?/span>velocity?/span>freemarker的一个集成点?/span>

Spring’s AOP moduleQ顾名思义?/span>

JDBC abstraction and the DAO moduleQ?/span>集成数据库操作。这个模块会(x)利用AOP模块提供的事务管理功能?/span>

Object-relational mapping (ORM) integration moduleQ?/span>?/span>DAO的基上提?/span>ORM?/span>solution?/span>Spring不实现自qORMQ只是提供一个与ORM框架l合的接口,比如HibernateQ?/span>JPA,JDO,IBATIS{。同?/span>spring的事务管理也与这些框架相l合?/span>

Java Management Extensions (JMX)Q?/span>Exposing the inner workings of a Java application for management is a critical part of making an application production ready. Spring’s JMX module makes it easy to expose your application’s beans as JMX MBeans. This makes it possible to monitor and reconfigure a running application.

Java EE Connector API (JCA)

The enterprise application landscape is littered with a mishmash of applications

running on an array of disparate servers and platforms. Integrating these applications

can be tricky. The Java EE Connection API (better known as JCA) provides a

standard way of integrating Java applications with a variety of enterprise information

systems, including mainframes and databases.

In many ways, JCA is much like JDBC, except where JDBC is focused on database

access, JCA is a more general-purpose API connecting to legacy systems. Spring’s

support for JCA is similar to its JDBC support, abstracting away JCA’s boilerplate

code into templates.

The Spring MVC framework

?/span>ORM不同Q?/span>MVC模块既结合已有的?/span>Struts?/span>Tapestry?/span>WebWorkq样的框Ӟ也提供了自己?/span>MVC框架?/span>

Spring Portlet MVC

Many web applications are page based—that is, each request to the application

results in a completely new page being displayed. Each page typically presents a

specific piece of information or prompts the user with a specific form. In contrast,

portlet-based applications aggregate several bits of functionality on a single web

page. This provides a view into several applications at once.

If you’re building portlet-enabled applications, you’ll certainly want to look at

Spring’s Portlet MVC framework. Spring Portlet MVC builds on Spring MVC to provide

a set of controllers that support Java’s portlet API.

Spring’s web module

提供MVC模块需要的classes?/span>

Remoting

Not all applications work alone. Oftentimes, it’s necessary for an application to

leverage the functionality of another application to get its work done. When the

other application is accessed over the network, some form of remoting is used

for communication.

Spring’s remoting support enables you to expose the functionality of your Java

objects as remote objects. Or if you need to access objects remotely, the remoting

module also makes simple work of wiring remote objects into your application as

if they were local POJOs. Several remoting options are available, including

Remote Method Invocation (RMI), Hessian, Burlap, JAX-RPC, and Spring’s own

HTTP Invoker.

Java Message Service (JMS)

The downside to remoting is that it depends on network reliability and that both

ends of the communication be available. Message-oriented communication, on

the other hand, is more reliable and guarantees delivery of messages, even if the

network and endpoints are unreliable.

Spring’s Java Message Service (JMS) module helps you send messages to JMS

message queues and topics. At the same time, this module also helps you create message-driven POJOs that are capable of consuming asynchronous messages.

解释一?/span>spring?/span>xmlQ?/span>

<beans>是根元素?/span>

<bean>告诉容器如何配置一?/span>classQ?/span>id属性表C?/span>bean对象的名字,class属性表C?/span>bean对象的具?/span>class?/span>

<bean>下的<property>用于讄一个该bean对象的属?/span>propertyQ?/span>name属性表C?/span>property的名字,value属性传递给q个property倹{用propertyq种方式Q等同于利用bean对象?/span>setҎ(gu)?/span>

<bean>下的<constructor-arg>?/span><property>cMQ只是这个等同于利用bean对象的赋值构造函数?/span>

_解DI

The key benefit of DI is loose coupling.

Interface programming

通过配置文gxmlQ写beanfactory{,来实现简单注入,从而松耦?/span>

_解AOP

解释aop?/span>xml配置元素Q?/span>

<aop:config>解释要做aop配置Q是spring aop基本必备的元?/span>

—?/span><aop:aspect>表示声明一?/span>aspectQ这?/span>aspect的功能被定义在其ref属性中Q?/span>ref一般会(x)联系一个已l定义好?/span>bean对象。一?/span>aspect?/span>pointcutsQ功能在哪里实现Q和adviceQ功能怎样实现Q组成?/span>

———?/span><aop:pointcut>定义一?/span>pointcutQ触发条件是某方法被执行?/span>

———?/span><aop:before>֐思义Q一?/span>advice

———?/span><aop:after>同上?/span>

Basic bean wiring

The act of creating these associations between application objects is the

essence of dependency injection (DI) and is commonly referred to as wiring.

Spring container

BeanFactory

֐思义Q遵循工厂模式的一个类Q管理和分发beans?/span>

通用的工厂,可以理分发各种cd?/span>beans?/span>

Beanfactory参与?/span>bean的整个生命周期?/span>

多种实现方式Q最常用的是org.springframework.beans.factory.xml.XmlBeanFactoryQ通过加蝲xml来实现。当然必要传递一?/span>Resourcel?/span>beanfactory。例Q?/span>BeanFactory factory = new XmlBeanFactory(new FileSystemResource("c:/beans.xml"));

得到一?/span>bean的方法就是调?/span>getBean()。比如:(x)MyBean myBean = (MyBean) factory.getBean("myBean");

application context

{同?/span>beanfactoryQ但是提?/span>moreQ?/span>

1Q?nbsp;支持I18N的消?/span>

2Q?nbsp;提供一般基本方法去加蝲file resources

3Q?nbsp;发布events到已l注册ؓ(f)listener?/span>beans

ClassPathXmlApplicationContext?/span>FileSystemXmlApplicationContext比较常用。例Q?/span>ApplicationContext context = new FileSystemXmlApplicationContext("c:/foo.xml"); ApplicationContext context = new ClassPathXmlApplicationContext("foo.xml");

bean’s life

Creating Beans

分两步,首先声明一?/span>beanQ即定义一个类。然后注入,即ؓ(f)其注入属性内宏V?/span>

何时选择setter注入Q何旉择constructor注入Q见spring in action原书W?/span>45c?/span>

Injecting into bean properties

通过<property>元素完成注入。其{h(hun)于调?/span>bean对应cȝsetXXXҎ(gu)?/span>

例:(x)<property name="song" value="Jingle Bells" />

其中value的|spring?x)根?/span>property的具体类别来选择不同的数据类型?/span>

<property name="instrument" ref="saxophone" />q样的声明中Q表Cproperty是一个类的对象,其类是已经声明q的某个beanQ?/span>saxophone?/span>

?/span><property>下直接定?/span>bean叫做inner bean。(当然通过constructor道理相同Q?/span>

对于复杂集合cdQ?br />

其中?/span>map需要注意一下?/span>Props的代码实C?/span>map也不同?/span>

Autowiring

The four types of autowiring

byNameQ找?/span>name相匹配的Q?/span>wire

byTypeQ找?/span>type匚w的,wire

constructorQ利?/span>constructor参数匚wQ?/span>wire

autodetectQ先constructorQ再byType

Controlling bean creation

有多对象实例,q多少bean

从静态的工厂L?/span>beanQ而不?/span>constructor

构造好bean后要?qing)时初始化,?/span>bean销毁之前要?qing)?/span>clean up

Bean scoping

所有的spring beans都是单例的?/span>

通过讄<bean>?/span>scope=”prototype”Q?/span>spring可以在需要的时候生新?/span>bean的实例?br />


Initializing and destroying beans

<bean>中有init-method?/span>destroy-method负责讄初始化和销毁时调用的方法?/span>

如果很多bean都有同样的初始化和销毁程序,那么可以?/span><beans>中设|?/span>defaultinit-

method ?/span> default-destroy-method

q有U方法就?/span>beancȝ定义Ӟ让类d?/span>InitializingBean ?/span>DisposableBean.

Advising beans

重点讲述AOP?/span>

Introducing AOP

Aspect帮助我们建模那些cross-cutting concernsQ一个应用中在多个位|vC用的点,比如securityQ?br />

Defining AOP terminology

AOP一般用advice?/span>pointcut?/span>joinpoint描述?br />

AdviceQ?/span>aspect必定是在做一?/span>jobQ即要做某个功能。其中这?/span>job叫?/span>advice?/span>Advice定义?/span>aspect?/span>what?/span>when?/span>

JoinpointQ在整个application中有可能用到advice的连接点?/span>

PointcutQ定义了aspect?/span>where?/span>

AspectQ是advice?/span>pointcut?/span>merger?/span>

Spring’s AOP support

Spring支持4U风格的aopQ?/span>

Spring?/span>advice都是java写的?/span>

Spring在运行时advise object?br />

Spring只支持方法连接点method joinpoint?/span>

Spring MVC




其中Q一?/span>command object 是一个像struts中的actionform一L(fng)东西?br />

Wizard是一个可以将多个面联合h作ؓ(f)一?/span>form的东ѝ?br />

基本搞完了,ȝ来讲Q学?fn)的东西pl常用,否则慢慢的就?x)E忘了Q尤其是技术上的一些细节。如果没遇到cM的问题,是很难记忆深ȝ~~~



changedi 2011-03-19 13:12 发表评论
]]>
Rope与StringBuilder的简单比?/title><link>http://www.tkk7.com/changedi/archive/2010/01/25/310736.html</link><dc:creator>changedi</dc:creator><author>changedi</author><pubDate>Mon, 25 Jan 2010 07:20:00 GMT</pubDate><guid>http://www.tkk7.com/changedi/archive/2010/01/25/310736.html</guid><wfw:comment>http://www.tkk7.com/changedi/comments/310736.html</wfw:comment><comments>http://www.tkk7.com/changedi/archive/2010/01/25/310736.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.tkk7.com/changedi/comments/commentRss/310736.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/changedi/services/trackbacks/310736.html</trackback:ping><description><![CDATA[<p>最q看了这文?<a >http://www.ibm.com/developerworks/cn/java/j-ropes/?S_TACT=105AGX52&S_CMP=techcsdn</a><br /> <br /> 作者比较了String和StringBuffer与Ropel构的常用操作速度。ƈ以实验证明了Rope的性能。我在自q机器上实验,同样也证明了Rope的高效,但是作者没有用StringBuilder和Rope做比较,所以我们不妨一试?br /> 暂时的实验结果表明,append和delete操作而言QStringBuilder胜过RopeQ那么Rope的真正优势在哪里呢?旉仓促Q没有深入研IӞҎ(gu)立一文,以后l看其结构~~~<br /> <br /> 我的试代码如下Q?br /> </p> <div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><span style="color: #008080"> 1</span><img id="Codehighlighter1_0_10_Open_Image" onclick="this.style.display='none'; Codehighlighter1_0_10_Open_Text.style.display='none'; Codehighlighter1_0_10_Closed_Image.style.display='inline'; Codehighlighter1_0_10_Closed_Text.style.display='inline';" align="top" src="http://www.tkk7.com/images/OutliningIndicators/ExpandedBlockStart.gif" alt="" /><img style="display: none" id="Codehighlighter1_0_10_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_0_10_Closed_Text.style.display='none'; Codehighlighter1_0_10_Open_Image.style.display='inline'; Codehighlighter1_0_10_Open_Text.style.display='inline';" align="top" src="http://www.tkk7.com/images/OutliningIndicators/ContractedBlock.gif" alt="" /><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_0_10_Closed_Text">/** */</span><span id="Codehighlighter1_0_10_Open_Text"><span style="color: #008000">/**</span><span style="color: #008000"><br /> </span><span style="color: #008080"> 2</span><span style="color: #008000"><img align="top" src="http://www.tkk7.com/images/OutliningIndicators/InBlock.gif" alt="" /> * <br /> </span><span style="color: #008080"> 3</span><span style="color: #008000"><img align="top" src="http://www.tkk7.com/images/OutliningIndicators/ExpandedBlockEnd.gif" alt="" /> </span><span style="color: #008000">*/</span></span><span style="color: #000000"><br /> </span><span style="color: #008080"> 4</span><span style="color: #000000"><img align="top" src="http://www.tkk7.com/images/OutliningIndicators/None.gif" alt="" /></span><span style="color: #0000ff">import</span><span style="color: #000000"> java.io.</span><span style="color: #000000">*</span><span style="color: #000000">;<br /> </span><span style="color: #008080"> 5</span><span style="color: #000000"><img align="top" src="http://www.tkk7.com/images/OutliningIndicators/None.gif" alt="" /></span><span style="color: #0000ff">import</span><span style="color: #000000"> java.util.</span><span style="color: #000000">*</span><span style="color: #000000">;<br /> </span><span style="color: #008080"> 6</span><span style="color: #000000"><img align="top" src="http://www.tkk7.com/images/OutliningIndicators/None.gif" alt="" /><br /> </span><span style="color: #008080"> 7</span><span style="color: #000000"><img align="top" src="http://www.tkk7.com/images/OutliningIndicators/None.gif" alt="" /></span><span style="color: #0000ff">import</span><span style="color: #000000"> org.ahmadsoft.ropes.</span><span style="color: #000000">*</span><span style="color: #000000">;<br /> </span><span style="color: #008080"> 8</span><span style="color: #000000"><img align="top" src="http://www.tkk7.com/images/OutliningIndicators/None.gif" alt="" /><br /> </span><span style="color: #008080"> 9</span><span style="color: #000000"><img id="Codehighlighter1_82_125_Open_Image" onclick="this.style.display='none'; Codehighlighter1_82_125_Open_Text.style.display='none'; Codehighlighter1_82_125_Closed_Image.style.display='inline'; Codehighlighter1_82_125_Closed_Text.style.display='inline';" align="top" src="http://www.tkk7.com/images/OutliningIndicators/ExpandedBlockStart.gif" alt="" /><img style="display: none" id="Codehighlighter1_82_125_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_82_125_Closed_Text.style.display='none'; Codehighlighter1_82_125_Open_Image.style.display='inline'; Codehighlighter1_82_125_Open_Text.style.display='inline';" align="top" src="http://www.tkk7.com/images/OutliningIndicators/ContractedBlock.gif" alt="" /></span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_82_125_Closed_Text">/** */</span><span id="Codehighlighter1_82_125_Open_Text"><span style="color: #008000">/**</span><span style="color: #008000"><br /> </span><span style="color: #008080">10</span><span style="color: #008000"><img align="top" src="http://www.tkk7.com/images/OutliningIndicators/InBlock.gif" alt="" /> * </span><span style="color: #808080">@author</span><span style="color: #008000"> Jia Yu<br /> </span><span style="color: #008080">11</span><span style="color: #008000"><img align="top" src="http://www.tkk7.com/images/OutliningIndicators/InBlock.gif" alt="" /> * @date 2010-1-25<br /> </span><span style="color: #008080">12</span><span style="color: #008000"><img align="top" src="http://www.tkk7.com/images/OutliningIndicators/ExpandedBlockEnd.gif" alt="" /> </span><span style="color: #008000">*/</span></span><span style="color: #000000"><br /> </span><span style="color: #008080">13</span><span style="color: #000000"><img id="Codehighlighter1_146_1098_Open_Image" onclick="this.style.display='none'; Codehighlighter1_146_1098_Open_Text.style.display='none'; Codehighlighter1_146_1098_Closed_Image.style.display='inline'; Codehighlighter1_146_1098_Closed_Text.style.display='inline';" align="top" src="http://www.tkk7.com/images/OutliningIndicators/ExpandedBlockStart.gif" alt="" /><img style="display: none" id="Codehighlighter1_146_1098_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_146_1098_Closed_Text.style.display='none'; Codehighlighter1_146_1098_Open_Image.style.display='inline'; Codehighlighter1_146_1098_Open_Text.style.display='inline';" align="top" src="http://www.tkk7.com/images/OutliningIndicators/ContractedBlock.gif" alt="" /></span><span style="color: #0000ff">public</span><span style="color: #000000"> </span><span style="color: #0000ff">class</span><span style="color: #000000"> Test2 </span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_146_1098_Closed_Text"><img src="http://www.tkk7.com/Images/dot.gif" alt="" /></span><span id="Codehighlighter1_146_1098_Open_Text"><span style="color: #000000">{<br /> </span><span style="color: #008080">14</span><span style="color: #000000"><img align="top" src="http://www.tkk7.com/images/OutliningIndicators/InBlock.gif" alt="" /><br /> </span><span style="color: #008080">15</span><span style="color: #000000"><img id="Codehighlighter1_150_173_Open_Image" onclick="this.style.display='none'; Codehighlighter1_150_173_Open_Text.style.display='none'; Codehighlighter1_150_173_Closed_Image.style.display='inline'; Codehighlighter1_150_173_Closed_Text.style.display='inline';" align="top" src="http://www.tkk7.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" alt="" /><img style="display: none" id="Codehighlighter1_150_173_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_150_173_Closed_Text.style.display='none'; Codehighlighter1_150_173_Open_Image.style.display='inline'; Codehighlighter1_150_173_Open_Text.style.display='inline';" align="top" src="http://www.tkk7.com/images/OutliningIndicators/ContractedSubBlock.gif" alt="" />    </span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_150_173_Closed_Text">/** */</span><span id="Codehighlighter1_150_173_Open_Text"><span style="color: #008000">/**</span><span style="color: #008000"><br /> </span><span style="color: #008080">16</span><span style="color: #008000"><img align="top" src="http://www.tkk7.com/images/OutliningIndicators/InBlock.gif" alt="" />     * </span><span style="color: #808080">@param</span><span style="color: #008000"> args<br /> </span><span style="color: #008080">17</span><span style="color: #008000"><img align="top" src="http://www.tkk7.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" alt="" />     </span><span style="color: #008000">*/</span></span><span style="color: #000000"><br /> </span><span style="color: #008080">18</span><span style="color: #000000"><img id="Codehighlighter1_215_1096_Open_Image" onclick="this.style.display='none'; Codehighlighter1_215_1096_Open_Text.style.display='none'; Codehighlighter1_215_1096_Closed_Image.style.display='inline'; Codehighlighter1_215_1096_Closed_Text.style.display='inline';" align="top" src="http://www.tkk7.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" alt="" /><img style="display: none" id="Codehighlighter1_215_1096_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_215_1096_Closed_Text.style.display='none'; Codehighlighter1_215_1096_Open_Image.style.display='inline'; Codehighlighter1_215_1096_Open_Text.style.display='inline';" align="top" src="http://www.tkk7.com/images/OutliningIndicators/ContractedSubBlock.gif" alt="" />    </span><span style="color: #0000ff">public</span><span style="color: #000000"> </span><span style="color: #0000ff">static</span><span style="color: #000000"> </span><span style="color: #0000ff">void</span><span style="color: #000000"> main(String[] args) </span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_215_1096_Closed_Text"><img src="http://www.tkk7.com/Images/dot.gif" alt="" /></span><span id="Codehighlighter1_215_1096_Open_Text"><span style="color: #000000">{<br /> </span><span style="color: #008080">19</span><span style="color: #000000"><img align="top" src="http://www.tkk7.com/images/OutliningIndicators/InBlock.gif" alt="" />        </span><span style="color: #008000">//</span><span style="color: #008000"> TODO Auto-generated method stub</span><span style="color: #008000"><br /> </span><span style="color: #008080">20</span><span style="color: #008000"><img align="top" src="http://www.tkk7.com/images/OutliningIndicators/InBlock.gif" alt="" /></span><span style="color: #000000"><br /> </span><span style="color: #008080">21</span><span style="color: #000000"><img align="top" src="http://www.tkk7.com/images/OutliningIndicators/InBlock.gif" alt="" />        </span><span style="color: #0000ff">int</span><span style="color: #000000"> max </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #000000">100000</span><span style="color: #000000">;<br /> </span><span style="color: #008080">22</span><span style="color: #000000"><img align="top" src="http://www.tkk7.com/images/OutliningIndicators/InBlock.gif" alt="" />        String eq </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #000000">""</span><span style="color: #000000">;<br /> </span><span style="color: #008080">23</span><span style="color: #000000"><img align="top" src="http://www.tkk7.com/images/OutliningIndicators/InBlock.gif" alt="" />        Rope r </span><span style="color: #000000">=</span><span style="color: #000000"> Rope.BUILDER.build(</span><span style="color: #000000">""</span><span style="color: #000000">);<br /> </span><span style="color: #008080">24</span><span style="color: #000000"><img align="top" src="http://www.tkk7.com/images/OutliningIndicators/InBlock.gif" alt="" />        StringBuffer sb </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #0000ff">new</span><span style="color: #000000"> StringBuffer(</span><span style="color: #000000">""</span><span style="color: #000000">);<br /> </span><span style="color: #008080">25</span><span style="color: #000000"><img align="top" src="http://www.tkk7.com/images/OutliningIndicators/InBlock.gif" alt="" />        StringBuilder sb2 </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #0000ff">new</span><span style="color: #000000"> StringBuilder(</span><span style="color: #000000">""</span><span style="color: #000000">);<br /> </span><span style="color: #008080">26</span><span style="color: #000000"><img align="top" src="http://www.tkk7.com/images/OutliningIndicators/InBlock.gif" alt="" /><br /> </span><span style="color: #008080">27</span><span style="color: #000000"><img align="top" src="http://www.tkk7.com/images/OutliningIndicators/InBlock.gif" alt="" />        </span><span style="color: #0000ff">double</span><span style="color: #000000"> st </span><span style="color: #000000">=</span><span style="color: #000000"> System.nanoTime();<br /> </span><span style="color: #008080">28</span><span style="color: #000000"><img id="Codehighlighter1_481_499_Open_Image" onclick="this.style.display='none'; Codehighlighter1_481_499_Open_Text.style.display='none'; Codehighlighter1_481_499_Closed_Image.style.display='inline'; Codehighlighter1_481_499_Closed_Text.style.display='inline';" align="top" src="http://www.tkk7.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" alt="" /><img style="display: none" id="Codehighlighter1_481_499_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_481_499_Closed_Text.style.display='none'; Codehighlighter1_481_499_Open_Image.style.display='inline'; Codehighlighter1_481_499_Open_Text.style.display='inline';" align="top" src="http://www.tkk7.com/images/OutliningIndicators/ContractedSubBlock.gif" alt="" />        </span><span style="color: #0000ff">for</span><span style="color: #000000"> (</span><span style="color: #0000ff">int</span><span style="color: #000000"> i </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #000000">0</span><span style="color: #000000">; i </span><span style="color: #000000"><</span><span style="color: #000000"> max; i</span><span style="color: #000000">++</span><span style="color: #000000">) </span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_481_499_Closed_Text"><img src="http://www.tkk7.com/Images/dot.gif" alt="" /></span><span id="Codehighlighter1_481_499_Open_Text"><span style="color: #000000">{<br /> </span><span style="color: #008080">29</span><span style="color: #000000"><img align="top" src="http://www.tkk7.com/images/OutliningIndicators/InBlock.gif" alt="" />            eq </span><span style="color: #000000">+=</span><span style="color: #000000"> </span><span style="color: #000000">"</span><span style="color: #000000">h</span><span style="color: #000000">"</span><span style="color: #000000">;<br /> </span><span style="color: #008080">30</span><span style="color: #000000"><img align="top" src="http://www.tkk7.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" alt="" />        }</span></span><span style="color: #000000"><br /> </span><span style="color: #008080">31</span><span style="color: #000000"><img align="top" src="http://www.tkk7.com/images/OutliningIndicators/InBlock.gif" alt="" />        </span><span style="color: #0000ff">double</span><span style="color: #000000"> ed </span><span style="color: #000000">=</span><span style="color: #000000"> System.nanoTime();<br /> </span><span style="color: #008080">32</span><span style="color: #000000"><img align="top" src="http://www.tkk7.com/images/OutliningIndicators/InBlock.gif" alt="" />        System.out.println(ed </span><span style="color: #000000">-</span><span style="color: #000000"> st);<br /> </span><span style="color: #008080">33</span><span style="color: #000000"><img align="top" src="http://www.tkk7.com/images/OutliningIndicators/InBlock.gif" alt="" /><br /> </span><span style="color: #008080">34</span><span style="color: #000000"><img align="top" src="http://www.tkk7.com/images/OutliningIndicators/InBlock.gif" alt="" />        st </span><span style="color: #000000">=</span><span style="color: #000000"> System.nanoTime();<br /> </span><span style="color: #008080">35</span><span style="color: #000000"><img id="Codehighlighter1_624_673_Open_Image" onclick="this.style.display='none'; Codehighlighter1_624_673_Open_Text.style.display='none'; Codehighlighter1_624_673_Closed_Image.style.display='inline'; Codehighlighter1_624_673_Closed_Text.style.display='inline';" align="top" src="http://www.tkk7.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" alt="" /><img style="display: none" id="Codehighlighter1_624_673_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_624_673_Closed_Text.style.display='none'; Codehighlighter1_624_673_Open_Image.style.display='inline'; Codehighlighter1_624_673_Open_Text.style.display='inline';" align="top" src="http://www.tkk7.com/images/OutliningIndicators/ContractedSubBlock.gif" alt="" />        </span><span style="color: #0000ff">for</span><span style="color: #000000"> (</span><span style="color: #0000ff">int</span><span style="color: #000000"> i </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #000000">0</span><span style="color: #000000">; i </span><span style="color: #000000"><</span><span style="color: #000000"> max; i</span><span style="color: #000000">++</span><span style="color: #000000">) </span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_624_673_Closed_Text"><img src="http://www.tkk7.com/Images/dot.gif" alt="" /></span><span id="Codehighlighter1_624_673_Open_Text"><span style="color: #000000">{<br /> </span><span style="color: #008080">36</span><span style="color: #000000"><img align="top" src="http://www.tkk7.com/images/OutliningIndicators/InBlock.gif" alt="" />            sb.append(</span><span style="color: #000000">"</span><span style="color: #000000">h</span><span style="color: #000000">"</span><span style="color: #000000">);<br /> </span><span style="color: #008080">37</span><span style="color: #000000"><img align="top" src="http://www.tkk7.com/images/OutliningIndicators/InBlock.gif" alt="" />            </span><span style="color: #008000">//</span><span style="color: #008000"> sb.deleteCharAt(0);</span><span style="color: #008000"><br /> </span><span style="color: #008080">38</span><span style="color: #008000"><img align="top" src="http://www.tkk7.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" alt="" /></span><span style="color: #000000">        }</span></span><span style="color: #000000"><br /> </span><span style="color: #008080">39</span><span style="color: #000000"><img align="top" src="http://www.tkk7.com/images/OutliningIndicators/InBlock.gif" alt="" />        ed </span><span style="color: #000000">=</span><span style="color: #000000"> System.nanoTime();<br /> </span><span style="color: #008080">40</span><span style="color: #000000"><img align="top" src="http://www.tkk7.com/images/OutliningIndicators/InBlock.gif" alt="" />        System.out.println((</span><span style="color: #0000ff">double</span><span style="color: #000000">) ed </span><span style="color: #000000">-</span><span style="color: #000000"> (</span><span style="color: #0000ff">double</span><span style="color: #000000">) st);<br /> </span><span style="color: #008080">41</span><span style="color: #000000"><img align="top" src="http://www.tkk7.com/images/OutliningIndicators/InBlock.gif" alt="" /><br /> </span><span style="color: #008080">42</span><span style="color: #000000"><img align="top" src="http://www.tkk7.com/images/OutliningIndicators/InBlock.gif" alt="" />        st </span><span style="color: #000000">=</span><span style="color: #000000"> System.nanoTime();<br /> </span><span style="color: #008080">43</span><span style="color: #000000"><img id="Codehighlighter1_809_860_Open_Image" onclick="this.style.display='none'; Codehighlighter1_809_860_Open_Text.style.display='none'; Codehighlighter1_809_860_Closed_Image.style.display='inline'; Codehighlighter1_809_860_Closed_Text.style.display='inline';" align="top" src="http://www.tkk7.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" alt="" /><img style="display: none" id="Codehighlighter1_809_860_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_809_860_Closed_Text.style.display='none'; Codehighlighter1_809_860_Open_Image.style.display='inline'; Codehighlighter1_809_860_Open_Text.style.display='inline';" align="top" src="http://www.tkk7.com/images/OutliningIndicators/ContractedSubBlock.gif" alt="" />        </span><span style="color: #0000ff">for</span><span style="color: #000000"> (</span><span style="color: #0000ff">int</span><span style="color: #000000"> i </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #000000">0</span><span style="color: #000000">; i </span><span style="color: #000000"><</span><span style="color: #000000"> max; i</span><span style="color: #000000">++</span><span style="color: #000000">) </span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_809_860_Closed_Text"><img src="http://www.tkk7.com/Images/dot.gif" alt="" /></span><span id="Codehighlighter1_809_860_Open_Text"><span style="color: #000000">{<br /> </span><span style="color: #008080">44</span><span style="color: #000000"><img align="top" src="http://www.tkk7.com/images/OutliningIndicators/InBlock.gif" alt="" />            sb2.append(</span><span style="color: #000000">"</span><span style="color: #000000">h</span><span style="color: #000000">"</span><span style="color: #000000">);<br /> </span><span style="color: #008080">45</span><span style="color: #000000"><img align="top" src="http://www.tkk7.com/images/OutliningIndicators/InBlock.gif" alt="" />            </span><span style="color: #008000">//</span><span style="color: #008000"> sb2.deleteCharAt(0);</span><span style="color: #008000"><br /> </span><span style="color: #008080">46</span><span style="color: #008000"><img align="top" src="http://www.tkk7.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" alt="" /></span><span style="color: #000000">        }</span></span><span style="color: #000000"><br /> </span><span style="color: #008080">47</span><span style="color: #000000"><img align="top" src="http://www.tkk7.com/images/OutliningIndicators/InBlock.gif" alt="" />        ed </span><span style="color: #000000">=</span><span style="color: #000000"> System.nanoTime();<br /> </span><span style="color: #008080">48</span><span style="color: #000000"><img align="top" src="http://www.tkk7.com/images/OutliningIndicators/InBlock.gif" alt="" />        System.out.println((</span><span style="color: #0000ff">double</span><span style="color: #000000">) ed </span><span style="color: #000000">-</span><span style="color: #000000"> (</span><span style="color: #0000ff">double</span><span style="color: #000000">) st);<br /> </span><span style="color: #008080">49</span><span style="color: #000000"><img align="top" src="http://www.tkk7.com/images/OutliningIndicators/InBlock.gif" alt="" /><br /> </span><span style="color: #008080">50</span><span style="color: #000000"><img align="top" src="http://www.tkk7.com/images/OutliningIndicators/InBlock.gif" alt="" />        st </span><span style="color: #000000">=</span><span style="color: #000000"> System.nanoTime();<br /> </span><span style="color: #008080">51</span><span style="color: #000000"><img id="Codehighlighter1_996_1018_Open_Image" onclick="this.style.display='none'; Codehighlighter1_996_1018_Open_Text.style.display='none'; Codehighlighter1_996_1018_Closed_Image.style.display='inline'; Codehighlighter1_996_1018_Closed_Text.style.display='inline';" align="top" src="http://www.tkk7.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" alt="" /><img style="display: none" id="Codehighlighter1_996_1018_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_996_1018_Closed_Text.style.display='none'; Codehighlighter1_996_1018_Open_Image.style.display='inline'; Codehighlighter1_996_1018_Open_Text.style.display='inline';" align="top" src="http://www.tkk7.com/images/OutliningIndicators/ContractedSubBlock.gif" alt="" />        </span><span style="color: #0000ff">for</span><span style="color: #000000"> (</span><span style="color: #0000ff">int</span><span style="color: #000000"> i </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #000000">0</span><span style="color: #000000">; i </span><span style="color: #000000"><</span><span style="color: #000000"> max; i</span><span style="color: #000000">++</span><span style="color: #000000">) </span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_996_1018_Closed_Text"><img src="http://www.tkk7.com/Images/dot.gif" alt="" /></span><span id="Codehighlighter1_996_1018_Open_Text"><span style="color: #000000">{<br /> </span><span style="color: #008080">52</span><span style="color: #000000"><img align="top" src="http://www.tkk7.com/images/OutliningIndicators/InBlock.gif" alt="" />            r.append(</span><span style="color: #000000">"</span><span style="color: #000000">h</span><span style="color: #000000">"</span><span style="color: #000000">);<br /> </span><span style="color: #008080">53</span><span style="color: #000000"><img align="top" src="http://www.tkk7.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" alt="" />        }</span></span><span style="color: #000000"><br /> </span><span style="color: #008080">54</span><span style="color: #000000"><img align="top" src="http://www.tkk7.com/images/OutliningIndicators/InBlock.gif" alt="" />        ed </span><span style="color: #000000">=</span><span style="color: #000000"> System.nanoTime();<br /> </span><span style="color: #008080">55</span><span style="color: #000000"><img align="top" src="http://www.tkk7.com/images/OutliningIndicators/InBlock.gif" alt="" />        System.out.println((</span><span style="color: #0000ff">double</span><span style="color: #000000">) ed </span><span style="color: #000000">-</span><span style="color: #000000"> (</span><span style="color: #0000ff">double</span><span style="color: #000000">) st);<br /> </span><span style="color: #008080">56</span><span style="color: #000000"><img align="top" src="http://www.tkk7.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" alt="" />    }</span></span><span style="color: #000000"><br /> </span><span style="color: #008080">57</span><span style="color: #000000"><img align="top" src="http://www.tkk7.com/images/OutliningIndicators/ExpandedBlockEnd.gif" alt="" />}</span></span><span style="color: #000000"><br /> </span><span style="color: #008080">58</span><span style="color: #000000"><img align="top" src="http://www.tkk7.com/images/OutliningIndicators/None.gif" alt="" /></span></div> <p><br /> l果如下Q?br /> 1.6120785922E10<br /> 1.0273193E7<br /> 2647639.0<br /> 9781992.0<br /> 只从数量U比较的话,String的低效就不说了,毕竟ZChar[]实现的,而StringBuffer比StringBuilder慢也可以理解Q毕竟加入了同步的考虑Q也是为线E安全付出的代h(hun)Q但是所谓的?wi)型机制的Ropeq是比不qStringBuilder啊~~~<br /> <br /> Rope for Java 下蝲Q?a >点击q里?br /> </a>q里附加了文章中的测试代码:(x)<a >点击q里?br /> </a></p> <img src ="http://www.tkk7.com/changedi/aggbug/310736.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/changedi/" target="_blank">changedi</a> 2010-01-25 15:20 <a href="http://www.tkk7.com/changedi/archive/2010/01/25/310736.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <footer> <div class="friendship-link"> <p>лǵվܻԴȤ</p> <a href="http://www.tkk7.com/" title="亚洲av成人片在线观看">亚洲av成人片在线观看</a> <div class="friend-links"> </div> </div> </footer> վ֩ģ壺 <a href="http://mtspvip.com" target="_blank">hƵѿ</a>| <a href="http://91packing.com" target="_blank">ŮڵƵ</a>| <a href="http://mlhcd.com" target="_blank">պƷƵѹۿ</a>| <a href="http://www-135888.com" target="_blank">˳ۺ7777</a>| <a href="http://taoh2510.com" target="_blank">޹va߹ۿַ</a>| <a href="http://3t77.com" target="_blank">ҹѹۿ</a>| <a href="http://dangyuming.com" target="_blank">57paoһ</a>| <a href="http://yunyitai.com" target="_blank">ˬִ̼߳Ƶ </a>| <a href="http://manghuo365.com" target="_blank">ѧһ</a>| <a href="http://my94ok.com" target="_blank">þþƷѲ</a>| <a href="http://guhey.com" target="_blank">ĻmvѸƵ7</a>| <a href="http://555yyyy.com" target="_blank">Ļһþ</a>| <a href="http://600c28.com" target="_blank">һɫþ88ۺ޾Ʒ </a>| <a href="http://guanxianedu.com" target="_blank">վ</a>| <a href="http://116603a.com" target="_blank">պƷר</a>| <a href="http://snsdtv.com" target="_blank">޾ƷһƷ99</a>| <a href="http://wuhhz.com" target="_blank">޹պa߲</a>| <a href="http://www-34595.com" target="_blank">þþƷƵۿ</a>| <a href="http://zzttt04.com" target="_blank">AVɫ</a>| <a href="http://huianpawn.com" target="_blank">ŷղ</a>| <a href="http://fsdyzs.com" target="_blank">Ļѿ</a>| <a href="http://sflhb.com" target="_blank">һ߹ۿ</a>| <a href="http://laosanqq.com" target="_blank">޺ݺady޾Ʒ</a>| <a href="http://guoyit.com" target="_blank">þùŮѹۿƷ</a>| <a href="http://jmdehong.com" target="_blank">պƷƵѹۿ</a>| <a href="http://987566.com" target="_blank">޾Ʒþþþþ </a>| <a href="http://xxzyyj.com" target="_blank">þþƷӰѶ</a>| <a href="http://pj9xx6.com" target="_blank">ѹۿĻƷ</a>| <a href="http://www6661126.com" target="_blank">Ļ</a>| <a href="http://tsj68.com" target="_blank">뾫Ʒһѿ</a>| <a href="http://857434.com" target="_blank">ѹۿ</a>| <a href="http://0149545.com" target="_blank">޾Ʒ˾þ</a>| <a href="http://youweidianqi.com" target="_blank">Ƶ</a>| <a href="http://dazhe777.com" target="_blank">޹ƷëƬa</a>| <a href="http://wenbye.com" target="_blank">Ƶ</a>| <a href="http://cao8080.com" target="_blank">Ʒ˳Ƶapp</a>| <a href="http://www2626cf.com" target="_blank">޾Ʒ͵Բ</a>| <a href="http://wkk3.com" target="_blank">ɫ͵͵޵һۺ</a>| <a href="http://xxxck.com" target="_blank">˳վ߿</a>| <a href="http://nblfkj.com" target="_blank">Ļ</a>| <a href="http://fenxiangceo.com" target="_blank">ձѹۿ</a>| <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body>