<?xml version="1.0" encoding="gb2312"?>
<rss version="2.0">
<channel>
<title><![CDATA[分享·快乐 - coollzh]]></title>
        <image>
        <title>http://hi.baidu.com</title>
        <link>http://hi.baidu.com</link>
        <url>http://img.baidu.com/img/logo-hi.gif</url>
        </image>
<description><![CDATA[Sharing Internet Technology,我是一切的根源]]></description>
<link>http://hi.baidu.com/coollzh</link>
<language>zh-cn</language>
<generator>www.baidu.com</generator>
<ttl>5</ttl>


<item>
        <title><![CDATA[实战 Groovy 系列]]></title>
        <link><![CDATA[http://hi.baidu.com/coollzh/blog/item/428a6738de9a1ff8b311c7df.html]]></link>
        <description><![CDATA[
		
		<table class="FCK__ShowTableBorders" border="0" cellspacing="0" cellpadding="0" width="100%" sizset="42" sizcache="2">
    <tbody sizset="42" sizcache="1">
        <tr valign="top">
            <td width="100%">
            <h1>实战 Groovy 系列</h1>
            <img class="display-img" src="http://www.ibm.com/i/c.gif" width="1" height="6"></td>
            <td class="no-print" width="192"><img alt="developerWorks" src="http://www.ibm.com/developerworks/i/dw.gif" width="192" height="18"></td>
        </tr>
    </tbody>
</table>

<table class="FCK__ShowTableBorders" border="0" cellspacing="0" cellpadding="0" width="100%" sizset="43" sizcache="2">
    <tbody sizset="44" sizcache="2">
        <tr valign="top" sizset="44" sizcache="2">
            
            <td width="10"><img src="http://www.ibm.com/i/c.gif" width="10" height="1"></td>
            
            <td width="100%" sizset="44" sizcache="2">
            <p> </p>
            <p><span class="small"><font size="2">Groovy 是运行在 Java 平台上的现代编程语言。它将提供与现有 Java 代码的无缝集成，同时引入闭包和元编程等出色的新功能。简言之，Groovy 是 21 世纪根据 Java 语言的需要编写的。</font></span></p>
            <p><span class="small"><font size="2">把任意一个新工具集成到开发工具包中的关键是：知道何时使用以及何时不应使用该工具。Groovy 可以提供强大的功能，但是必须正确地应用到适当的场景中。为此，实战 Groovy 系列将探究 Groovy 的实际应用，帮助您了解何时及如何成功应用它们。 </font></span></p>
            <p> </p>
            
            <table class="FCK__ShowTableBorders" border="0" cellspacing="0" cellpadding="0" width="100%" sizset="44" sizcache="2">
                <tbody sizset="44" sizcache="1">
                    <tr>
                        <td width="160"><font size="2"><img border="0" src="http://www.ibm.com/i/c.gif" width="160" height="17"></font></td>
                        <td valign="middle" width="100%" align="right"><span class="small"><font size="2">2009 年 3 月 9 号 更新</font></span></td>
                    </tr>
                    <tr>
                        <td colspan="4"><font size="2"><img src="http://www.ibm.com/i/v14/rules/dblue_rule.gif" width="100%" height="3"></font></td>
                    </tr>
                </tbody>
            </table>
            <table class="FCK__ShowTableBorders" border="0" cellspacing="0" cellpadding="0" width="100%" sizset="46" sizcache="2">
                <tbody sizset="46" sizcache="1">
                    <tr valign="top">
                        <td width="150"><a href="http://www.ibm.com/developerworks/cn/java/j-pg02179.html" cmimpressionsent="1"><font size="2"><img border="0" alt="Groovy:Java 程序员的 DSL" src="http://www.ibm.com/developerworks/i/t-j-f-groovy.jpg"></font></a></td>
                        <td width="10"><img src="http://www.ibm.com/i/c.gif" width="10" height="1"></td>
                        <td width="100%"><img border="0" src="http://www.ibm.com/i/c.gif" width="270" height="8"><br>
                        <a class="feature" href="http://www.ibm.com/developerworks/cn/java/j-pg02179.html" cmimpressionsent="1"><font color="#5c81a7">Groovy：Java 程序员的 DSL</font></a><br>
                        Groovy 专家 Scott Davis 将重新开始撰写 <em>实战 Groovy</em> 系列文章，该系列文章于 2006 年停止编写。作为开篇文章，本文将介绍 Groovy 最近的发展以及 Groovy 当前的状态。然后了解大约 从 2009 年开始，使用 Groovy 是多么的轻松！ <a href="http://www.ibm.com/developerworks/cn/java/j-pg02179.html" cmimpressionsent="1"><font color="#5c81a7">更多 &gt;</font></a></td>
                        <td width="3"><img src="http://www.ibm.com/i/c.gif" width="3" height="1"></td>
                    </tr>
                </tbody>
            </table>
            <br>
            <table class="FCK__ShowTableBorders" border="0" cellspacing="0" cellpadding="0" width="100%" sizset="47" sizcache="2">
                <tbody sizset="47" sizcache="1">
                    <tr>
                        <td class="v14-header-3"><a name="2006">2006 年</a></td>
                    </tr>
                </tbody>
            </table>
            <p><strong><a href="http://www.ibm.com/developerworks/cn/java/j-pg09196.html" cmimpressionsent="1"><font color="#5c81a7">用 Groovy 减少代码冗余</font></a></strong> <font size="2"><span class="small">（2006 年 10 月）</span><br>
            </font>Groovy 简洁的语法将开发人员从那种需要进行代码编译但却无助于表达 什么 是程序真正想要实现的典型的 Java 结构中解放了出来。本文将带您进行一系列对常规 Java 代码和 Groovy 代码的比较，展示这门令人兴奋的语言如何将您解放出来，让您能够专注于编码的重要方面。</p>
            <table class="FCK__ShowTableBorders" cellspacing="0" cellpadding="0" align="right" sizset="48" sizcache="2">
                <tbody sizset="49" sizcache="2">
                    <tr align="right" sizset="49" sizcache="2">
                        <td sizset="49" sizcache="2"><img src="http://www.ibm.com/i/c.gif" width="100%" height="8"><br>
                        <table class="FCK__ShowTableBorders" border="0" cellspacing="0" cellpadding="0" sizset="49" sizcache="2">
                            <tbody sizset="49" sizcache="1">
                                <tr>
                                    <td valign="middle"><img border="0" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" height="16"></td>
                                    <td valign="top" align="right"><a class="fbox" href="http://www.ibm.com/developerworks/cn/java/j-pg/#main" cmimpressionsent="1"><strong><font color="#5c81a7">回页首</font></strong></a></td>
                                </tr>
                            </tbody>
                        </table>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br>
            <br>
            <br>
            <table class="FCK__ShowTableBorders" border="0" cellspacing="0" cellpadding="0" width="100%" sizset="50" sizcache="2">
                <tbody sizset="50" sizcache="1">
                    <tr>
                        <td class="v14-header-3"><a name="2005">2005 年</a></td>
                    </tr>
                </tbody>
            </table>
            <p><strong><a href="http://www.ibm.com/developerworks/cn/java/j-pg09205/" cmimpressionsent="1"><font color="#5c81a7">关于 MOP 和迷你语言</font></a></strong> <font size="2"><span class="small">（2005 年 10 月）</span><br>
            </font>将耳朵贴到地上仔细听 &mdash;&mdash; MOP 正在前进！了解一下元对象协议（Meta Object Protocol，MOP）吧，这是一种将应用程序、语言和应用程序构建为 语言的翻新方法。</p>
            <p><strong><a href="http://www.ibm.com/developerworks/cn/java/j-pg08235/" cmimpressionsent="1"><font color="#5c81a7">用 curry 过的闭包进行函数式编程</font></a></strong> <font size="2"><span class="small">（2005 年 9 月）</span><br>
            </font>在 Groovy 中处处都是闭包，Groovy 闭包惟一的问题是：当每天都使用它们的时候，看起来就有点平淡了。本文介绍了如何对标准的闭包（例如闭包复合和 Visitor 设计模式）进行 curry 处理。curry() 方法是由 Haskell Curry 发明的，在 JSR 标准发布之前就已经在 Groovy 语言中了。</p>
            <p><strong><a href="http://www.ibm.com/developerworks/cn/java/j-pg07195.html" cmimpressionsent="1"><font color="#5c81a7">Groovy 的腾飞</font></a></strong> <font size="2"><span class="small">（2005 年 8 月）</span><br>
            </font>随着 Groovy JSR-1（及其后续发行版本）的发布，Groovy 语法的变化已经规范化 &mdash;&mdash; 这意味着如果以前没有对此加以注意，那么现在是开始注意它的时候了。本文将介绍 Groovy 语法最重要的变化，以及在经典 Groovy 中找不到的一个方便特性。</p>
            <p><strong><a href="http://www.ibm.com/developerworks/cn/java/j-pg05245/" cmimpressionsent="1"><font color="#5c81a7">在 Java 应用程序中加一些 Groovy 进来</font></a></strong> <font size="2"><span class="small">（2005 年 6 月）</span><br>
            </font>您有没有想过在自己相对复杂的 Java 程序中嵌入 Groovy 简单的、易于编写的脚本呢？本文将介绍把 Groovy 集成到 Java 代码中的多种方法，并解释在什么地方、什么时候适合这么做。</p>
            <p><strong><a href="http://www.ibm.com/developerworks/cn/java/j-pg04125/" cmimpressionsent="1"><font color="#5c81a7">用 Groovy 生成器作标记</font></a></strong> <font size="2"><span class="small">（2005 年 4 月）</span><br>
            </font>Groovy 生成器让您能够利用诸如 Swing 这样的框架来模拟标记语言（如 XML、HTML、Ant） 任务以及 GUI。它们对于快速原型化非常有用，并且正像本文中向您展示的那样，当您马上需要可消费的标记时，它们是数据绑定框架的一种便利的替代方案。</p>
            <p><strong><a href="http://www.ibm.com/developerworks/cn/java/j-pg03155/" cmimpressionsent="1"><font color="#5c81a7">用 Groovy 打造服务器端</font></a></strong> <font size="2"><span class="small">（2005 年 3 月）</span><br>
            </font>Groovlet 和 GroovyServer Pages（GSP）框架都是建立在 Java Servlet API 基础之上。不过，与 Strut 和 JSF 不同，Groovy 的服务器端实现不意味着适用于所有情况。相反，它提供了一种快速而又方便地开发服务器端应用程序的简化方法。本文介绍这些框架，并展示它们的应用。</p>
            <p><strong><a href="http://www.ibm.com/developerworks/cn/java/j-pg02155/" cmimpressionsent="1"><font color="#5c81a7">使用 Groovy 模板进行 MVC 编程</font></a></strong> <font size="2"><span class="small">（2005 年 2 月）</span><br>
            </font>视图是 MVC 编程的一个重要部分，而 MVC 编程本身又是企业应用程序开发的一个重要组件。本文向您介绍了 Groovy 的模板引擎框架是如何用来简化视图编程的，并如何使您的代码更加经久容易维护。</p>
            <p><strong><a href="http://www.ibm.com/developerworks/cn/java/j-pg01115.html" cmimpressionsent="1"><font color="#5c81a7">用 Groovy 进行 JDBC 编程</font></a></strong> <font size="2"><span class="small">（2005 年 1 月）</span><br>
            </font>随着本文向您演示的如何用 GroovySql 构建简单的数据报告应用程序，您对 Groovy 的实用知识会更进一步。GroovySql 结合利用闭包（closure）和迭代器（iterator），把资源管理的负担转移到 Groovy 框架本身，从而简化了 Java 数据库连通性（Java Database Connectivity，JDBC）的编程。</p>
            <p><strong><a href="http://www.ibm.com/developerworks/cn/java/j-pg12144.html" cmimpressionsent="1"><font color="#5c81a7">用 Groovy 进行 Ant 脚本编程</font></a></strong> <font size="2"><span class="small">（2005 年 1 月）</span><br>
            </font>Ant 和 Maven 两者在构建处理工具的世界中占统治地位。但是 XML 却凑巧是一种非常没有表现力的配置格式。本文将介绍 Groovy 的生成器实用工具，这个工具能够极其容易地把 Groovy 与 Ant 和 Maven 结合在一起，形成更具表现力、更可控的构建。</p>
            <table class="FCK__ShowTableBorders" cellspacing="0" cellpadding="0" align="right" sizset="51" sizcache="2">
                <tbody sizset="52" sizcache="2">
                    <tr align="right" sizset="52" sizcache="2">
                        <td sizset="52" sizcache="2"><img src="http://www.ibm.com/i/c.gif" width="100%" height="8"><br>
                        <table class="FCK__ShowTableBorders" border="0" cellspacing="0" cellpadding="0" sizset="52" sizcache="2">
                            <tbody sizset="52" sizcache="1">
                                <tr>
                                    <td valign="middle"><img border="0" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" height="16"></td>
                                    <td valign="top" align="right"><a class="fbox" href="http://www.ibm.com/developerworks/cn/java/j-pg/#main" cmimpressionsent="1"><strong><font color="#5c81a7">回页首</font></strong></a></td>
                                </tr>
                            </tbody>
                        </table>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br>
            <br>
            <br>
            <table class="FCK__ShowTableBorders" border="0" cellspacing="0" cellpadding="0" width="100%" sizset="53" sizcache="2">
                <tbody sizset="53" sizcache="1">
                    <tr>
                        <td class="v14-header-3"><a name="2004">2004 年</a></td>
                    </tr>
                </tbody>
            </table>
            <p><strong><a href="http://www.ibm.com/developerworks/cn/java/j-pg11094/" cmimpressionsent="1"><font color="#5c81a7">用 Groovy 更迅速地对 Java 代码进行单元测试</font></a></strong> <font size="2"><span class="small">（2004 年 11 月）</span><br>
            </font>本文是第一期，将介绍使用 Groovy 和 JUnit 对 Java 代码进行单元测试的一个简单策略。</p>
            <p><strong><a href="http://www.ibm.com/developerworks/cn/java/j-alj08034/" cmimpressionsent="1"><font color="#5c81a7">感受 Groovy</font></a></strong> <font size="2"><span class="small">（2004 年 8 月）</span><br>
            </font>虽然 Java 语言因其严密性和扩展性的承诺而在整整一代程序员中胜出，但是 Groovy 预示了 Java 平台上的一个编程新时代，这种语言是以方便性、适宜性和敏捷性为出发点定义的。本文对提议添加到 Java 平台的标准编程语言作了非正式的介绍。</p>
            
            <table class="FCK__ShowTableBorders" cellspacing="0" cellpadding="0" align="right" sizset="54" sizcache="2">
                <tbody sizset="55" sizcache="2">
                    <tr align="right" sizset="55" sizcache="2">
                        <td sizset="55" sizcache="2"><img src="http://a248.e.akamai.net/f/248/47542/30d/www.ibm.com/i/c.gif" width="100%" height="8"><br>
                        <table class="FCK__ShowTableBorders" border="0" cellspacing="0" cellpadding="0" sizset="55" sizcache="2">
                            <tbody sizset="55" sizcache="1">
                                <tr>
                                    <td valign="middle"><img border="0" src="http://a248.e.akamai.net/f/248/47542/30d/www.ibm.com/i/v14/icons/u_bold.gif" width="16" height="16"></td>
                                    <td valign="top" align="right"><a class="fbox" href="http://www.ibm.com/developerworks/cn/java/j-pg/#main" cmimpressionsent="1"><strong><font color="#5c81a7">回页首</font></strong></a></td>
                                </tr>
                            </tbody>
                        </table>
                        </td>
                    </tr>
                </tbody>
            </table>
            </td>
        </tr>
    </tbody>
</table> <a href="http://hi.baidu.com/coollzh/blog/item/428a6738de9a1ff8b311c7df.html">阅读全文</a>
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/coollzh/blog/category/Groovy">Groovy</a>&nbsp;<a href="http://hi.baidu.com/coollzh/blog/item/428a6738de9a1ff8b311c7df.html#comment">查看评论</a>]]></description>
        <pubDate>2009-12-03  23:58</pubDate>
        <category><![CDATA[Groovy]]></category>
        <author><![CDATA[coollzh]]></author>
		<guid>http://hi.baidu.com/coollzh/blog/item/428a6738de9a1ff8b311c7df.html</guid>
</item>

<item>
        <title><![CDATA[NoSQL数据库探讨之一 － 为什么要用非关系数据库【转】]]></title>
        <link><![CDATA[http://hi.baidu.com/coollzh/blog/item/ff227dd137b92dd9562c8426.html]]></link>
        <description><![CDATA[
		
		<table class="FCK__ShowTableBorders" cellspacing="1">
    <tbody >
        <tr >
            <td class="postauthor">
            <ul>
                <li> </li>
            </ul>
            </td>
            <td class="postcontent">
            <div class="postactions">
            <div class="description"> </div>
            </div>
            <div class="postbody clearfix">
            
            随着互联网web2.0网站的兴起，非关系型的数据库现在成了一个极其热门的新领域，非关系数据库产品的发展非常迅速。而传统的关系数据库在应付web2.0网站，特别是超大规模和高并发的SNS类型的web2.0纯动态网站已经显得力不从心，暴露了很多难以克服的问题，例如： <br>
            <br>
            <span style="font-size: medium"><font size="3">1、High performance - 对数据库高并发读写的需求</font></span> <br>
            web2.0网站要根据用户个性化信息来实时生成动态页面和提供动态信息，所以基本上无法使用动态页面静态化技术，因此数据库并发负载非常高，往往要达到每秒上万次读写请求。关系数据库应付上万次SQL查询还勉强顶得住，但是应付上万次SQL写数据请求，硬盘IO就已经无法承受了。其实对于普通的BBS网站，往往也存在对高并发写请求的需求，例如像JavaEye网站的实时统计在线用户状态，记录热门帖子的点击次数，投票计数等，因此这是一个相当普遍的需求。 <br>
            <br>
            <span style="font-size: medium"><font size="3">2、Huge Storage - 对海量数据的高效率存储和访问的需求</font></span> <br>
            类似Facebook，twitter，Friendfeed这样的SNS网站，每天用户产生海量的用户动态，以Friendfeed为例，一个月就达到了2.5亿条用户动态，对于关系数据库来说，在一张2.5亿条记录的表里面进行SQL查询，效率是极其低下乃至不可忍受的。再例如大型web网站的用户登录系统，例如腾讯，盛大，动辄数以亿计的帐号，关系数据库也很难应付。 <br>
            <br>
            <span style="font-size: medium"><font size="3">3、High Scalability &amp;&amp; High Availability- 对数据库的高可扩展性和高可用性的需求</font></span> <br>
            在基于web的架构当中，数据库是最难进行横向扩展的，当一个应用系统的用户量和访问量与日俱增的时候，你的数据库却没有办法像web server和app server那样简单的通过添加更多的硬件和服务节点来扩展性能和负载能力。对于很多需要提供24小时不间断服务的网站来说，对数据库系统进行升级和扩展是非常痛苦的事情，往往需要停机维护和数据迁移，为什么数据库不能通过不断的添加服务器节点来实现扩展呢？ <br>
            <br>
            在上面提到的&ldquo;三高&rdquo;需求面前，关系数据库遇到了难以克服的障碍，而对于web2.0网站来说，关系数据库的很多主要特性却往往无用武之地，例如： <br>
            <br>
            <span style="font-size: medium"><font size="3">1、数据库事务一致性需求</font></span> <br>
            很多web实时系统并不要求严格的数据库事务，对读一致性的要求很低，有些场合对写一致性要求也不高。因此数据库事务管理成了数据库高负载下一个沉重的负担。 <br>
            <br>
            <span style="font-size: medium"><font size="3">2、数据库的写实时性和读实时性需求</font></span> <br>
            对关系数据库来说，插入一条数据之后立刻查询，是肯定可以读出来这条数据的，但是对于很多web应用来说，并不要求这么高的实时性，比方说我（JavaEye的robbin）发一条消息之后，过几秒乃至十几秒之后，我的订阅者才看到这条动态是完全可以接受的。 <br>
            <br>
            <span style="font-size: medium"><font size="3">3、对复杂的SQL查询，特别是多表关联查询的需求</font></span> <br>
            任何大数据量的web系统，都非常忌讳多个大表的关联查询，以及复杂的数据分析类型的复杂SQL报表查询，特别是SNS类型的网站，从需求以及产品设计角度，就避免了这种情况的产生。往往更多的只是单表的主键查询，以及单表的简单条件分页查询，SQL的功能被极大的弱化了。 <br>
            <br>
            因此，关系数据库在这些越来越多的应用场景下显得不那么合适了，为了解决这类问题的非关系数据库应运而生，现在这两年，各种各样非关系数据库，特别是键值数据库(Key-Value Store DB)风起云涌，多得让人眼花缭乱。前不久国外刚刚举办了<a href="http://journal.uggedal.com/nosql-east-2009---summary-of-day-1" target="_blank"><font color="#006699">NoSQL Conference</font></a>，各路NoSQL数据库纷纷亮相，加上未亮相但是名声在外的，起码有超过10个开源的NoSQLDB，例如： <br>
            <br>
            Redis，Tokyo Cabinet，Cassandra，Voldemort，MongoDB，Dynomite，HBase，CouchDB，Hypertable， Riak，Tin， Flare， Lightcloud， KiokuDB，Scalaris， Kai， ThruDB，  ...... <br>
            <br>
            这些NoSQL数据库，有的是用C/C++编写的，有的是用Java编写的，还有的是用Erlang编写的，每个都有自己的独到之处，看都看不过来了，<a href="http://robbin.javaeye.com/" target="_blank"><font color="#006699">我(robbin)</font></a>也只能从中挑选一些比较有特色，看起来更有前景的产品学习和了解一下。这些NoSQL数据库大致可以分为以下的三类： <br>
            <br>
            <span style="font-size: medium"><font size="3">一、满足极高读写性能需求的Kye-Value数据库：Redis，Tokyo Cabinet， Flare</font></span> <br>
            <br>
            高性能Key-Value数据库的主要特点就是具有极高的并发读写性能，Redis，Tokyo Cabinet， Flare，这3个Key-Value DB都是用C编写的，他们的性能都相当出色，但出了出色的性能，他们还有自己独特的功能： <br>
            <br>
            1、<a href="http://code.google.com/p/redis/" target="_blank"><font color="#006699">Redis</font></a> <br>
            Redis是一个很新的项目，刚刚发布了1.0版本。Redis本质上是一个Key-Value类型的内存数据库，很像memcached，整个数据库统统加载在内存当中进行操作，定期通过异步操作把数据库数据flush到硬盘上进行保存。因为是纯内存操作，Redis的性能非常出色，每秒可以处理超过10万次读写操作，是我知道的性能最快的Key-Value DB。 <br>
            <br>
            Redis的出色之处不仅仅是性能，Redis最大的魅力是支持保存List链表和Set集合的数据结构，而且还支持对List进行各种操作，例如从List两端push和pop数据，取List区间，排序等等，对Set支持各种集合的并集交集操作，此外单个value的最大限制是1GB，不像memcached只能保存1MB的数据，因此Redis可以用来实现很多有用的功能，比方说用他的List来做FIFO双向链表，实现一个轻量级的高性能消息队列服务，用他的Set可以做高性能的tag系统等等。另外Redis也可以对存入的Key-Value设置expire时间，因此也可以被当作一个功能加强版的memcached来用。 <br>
            <br>
            Redis的主要缺点是数据库容量受到物理内存的限制，不能用作海量数据的高性能读写，并且它没有原生的可扩展机制，不具有scale（可扩展）能力，要依赖客户端来实现分布式读写，因此Redis适合的场景主要局限在较小数据量的高性能操作和运算上。目前使用Redis的网站有github，Engine Yard。 <br>
            <br>
            2、<a href="http://1978th.net/" target="_blank"><font color="#006699">Tokyo Cabinet和Tokoy Tyrant</font></a> <br>
            TC和TT的开发者是日本人Mikio Hirabayashi，主要被用在日本最大的SNS网站mixi.jp上，TC发展的时间最早，现在已经是一个非常成熟的项目，也是Kye-Value数据库领域最大的热点，现在被广泛的应用在很多很多网站上。TC是一个高性能的存储引擎，而TT提供了多线程高并发服务器，性能也非常出色，每秒可以处理4-5万次读写操作。 <br>
            <br>
            TC除了支持Key-Value存储之外，还支持保存Hashtable数据类型，因此很像一个简单的数据库表，并且还支持基于column的条件查询，分页查询和排序功能，基本上相当于支持单表的基础查询功能了，所以可以简单的替代关系数据库的很多操作，这也是TC受到大家欢迎的主要原因之一，有一个Ruby的项目<a href="http://github.com/tsukasaoishi/miyazakiresistance" target="_blank"><font color="#006699">miyazakiresistance</font></a>将TT的hashtable的操作封装成和ActiveRecord一样的操作，用起来非常爽。 <br>
            <br>
            TC/TT在mixi的实际应用当中，存储了2000万条以上的数据，同时支撑了上万个并发连接，是一个久经考验的项目。TC在保证了极高的并发读写性能的同时，具有可靠的数据持久化机制，同时还支持类似关系数据库表结构的hashtable以及简单的条件，分页和排序操作，是一个很棒的NoSQL数据库。 <br>
            <br>
            TC的主要缺点是在数据量达到上亿级别以后，并发写数据性能会大幅度下降，<a href="http://bjclark.me/2009/08/04/nosql-if-only-it-was-that-easy/" target="_blank"><font color="#006699">NoSQL: If Only It Was That Easy</font></a>提到，他们发现在TC里面插入1.6亿条2-20KB数据的时候，写入性能开始急剧下降。看来是当数据量上亿条的时候，TC性能开始大幅度下降，从TC作者自己提供的mixi数据来看，至少上千万条数据量的时候还没有遇到这么明显的写入性能瓶颈。 <br>
            <br>
            这个是Tim Yang做的一个<a href="http://timyang.net/data/mcdb-tt-redis/" target="_blank"><font color="#006699">Memcached，Redis和Tokyo Tyrant的简单的性能评测，仅供参考</font></a> <br>
            <br>
            3、<a href="http://labs.gree.jp/Top/OpenSource/Flare-en.html" target="_blank"><font color="#006699">Flare</font></a> <br>
            TC是日本第一大SNS网站mixi开发的，而Flare是日本第二大SNS网站green.jp开发的，有意思吧。Flare简单的说就是给TC添加了scale功能。他替换掉了TT部分，自己另外给TC写了网络服务器，Flare的主要特点就是支持scale能力，他在网络服务端之前添加了一个node server，来管理后端的多个服务器节点，因此可以动态添加数据库服务节点，删除服务器节点，也支持failover。如果你的使用场景必须要让TC可以scale，那么可以考虑flare。 <br>
            <br>
            flare唯一的缺点就是他只支持memcached协议，因此当你使用flare的时候，就不能使用TC的table数据结构了，只能使用TC的key-value数据结构存储。 <br>
            <br>
            <span style="font-size: medium"><font size="3">二、满足海量存储需求和访问的面向文档的数据库：MongoDB，CouchDB</font></span> <br>
            <br>
            面向文档的非关系数据库主要解决的问题不是高性能的并发读写，而是保证海量数据存储的同时，具有良好的查询性能。MongoDB是用C++开发的，而CouchDB则是Erlang开发的： <br>
            <br>
            1、<a href="http://www.mongodb.org/display/DOCS/Home" target="_blank"><font color="#006699">MongoDB</font></a> <br>
            MongoDB是一个介于关系数据库和非关系数据库之间的产品，是非关系数据库当中功能最丰富，最像关系数据库的。他支持的数据结构非常松散，是类似json的bjson格式，因此可以存储比较复杂的数据类型。Mongo最大的特点是他支持的查询语言非常强大，其语法有点类似于面向对象的查询语言，几乎可以实现类似关系数据库单表查询的绝大部分功能，而且还支持对数据建立索引。 <br>
            <br>
            Mongo主要解决的是海量数据的访问效率问题，根据官方的文档，当数据量达到50GB以上的时候，Mongo的数据库访问速度是MySQL的10倍以上。Mongo的并发读写效率不是特别出色，根据官方提供的性能测试表明，大约每秒可以处理0.5万－1.5次读写请求。对于Mongo的并发读写性能，我（robbin）也打算有空的时候好好测试一下。 <br>
            <br>
            因为Mongo主要是支持海量数据存储的，所以Mongo还自带了一个出色的分布式文件系统GridFS，可以支持海量的数据存储，但我也看到有些评论认为GridFS性能不佳，这一点还是有待亲自做点测试来验证了。 <br>
            <br>
            最后由于Mongo可以支持复杂的数据结构，而且带有强大的数据查询功能，因此非常受到欢迎，很多项目都考虑用MongoDB来替代MySQL来实现不是特别复杂的Web应用，比方说<a href="http://blog.boxedice.com/2009/07/25/choosing-a-non-relational-database-why-we-migrated-from-mysql-to-mongodb/" target="_blank"><font color="#006699">why we migrated from MySQL to MongoDB</font></a>就是一个真实的从MySQL迁移到MongoDB的案例，由于数据量实在太大，所以迁移到了Mongo上面，数据查询的速度得到了非常显著的提升。 <br>
            <br>
            MongoDB也有一个ruby的项目<a href="http://github.com/jnunemaker/mongomapper" target="_blank"><font color="#006699">MongoMapper</font></a>，是模仿Merb的DataMapper编写的MongoDB的接口，使用起来非常简单，几乎和DataMapper一模一样，功能非常强大易用。 <br>
            <br>
            2、CouchDB <br>
            CouchDB现在是一个非常有名气的项目，似乎不用多介绍了。但是我却对CouchDB没有什么兴趣，主要是因为CouchDB仅仅提供了基于HTTP REST的接口，因此CouchDB单纯从并发读写性能来说，是非常糟糕的，这让我立刻抛弃了对CouchDB的兴趣。 <br>
            <br>
            <span style="font-size: medium"><font size="3">三、满足高可扩展性和可用性的面向分布式计算的数据库：Cassandra，Voldemort</font></span> <br>
            <br>
            面向scale能力的数据库其实主要解决的问题领域和上述两类数据库还不太一样，它首先必须是一个分布式的数据库系统，由分布在不同节点上面的数据库共同构成一个数据库服务系统，并且根据这种分布式架构来提供online的，具有弹性的可扩展能力，例如可以不停机的添加更多数据节点，删除数据节点等等。因此像Cassandra常常被看成是一个开源版本的Google BigTable的替代品。Cassandra和Voldemort都是用Java开发的： <br>
            <br>
            1、<a href="http://incubator.apache.org/cassandra/" target="_blank"><font color="#006699">Cassandra</font></a> <br>
            Cassandra项目是Facebook在2008年开源出来的，随后Facebook自己使用Cassandra的另外一个不开源的分支，而开源出来的Cassandra主要被Amazon的Dynamite团队来维护，并且Cassandra被认为是Dynamite2.0版本。目前除了Facebook之外，twitter和digg.com都在使用Cassandra。 <br>
            <br>
            Cassandra的主要特点就是它不是一个数据库，而是由一堆数据库节点共同构成的一个分布式网络服务，对Cassandra的一个写操作，会被复制到其他节点上去，对Cassandra的读操作，也会被路由到某个节点上面去读取。对于一个Cassandra群集来说，扩展性能是比较简单的事情，只管在群集里面添加节点就可以了。我看到有文章说Facebook的Cassandra群集有超过100台服务器构成的数据库群集。 <br>
            <br>
            Cassandra也支持比较丰富的数据结构和功能强大的查询语言，和MongoDB比较类似，查询功能比MongoDB稍弱一些，twitter的平台架构部门领导Evan Weaver写了一篇文章介绍Cassandra：<a href="http://blog.evanweaver.com/articles/2009/07/06/up-and-running-with-cassandra/" target="_blank"><font color="#006699">http://blog.evanweaver.com/articles/2009/07/06/up-and-running-with-cassandra/</font></a>，有非常详细的介绍。 <br>
            <br>
            Cassandra以单个节点来衡量，其节点的并发读写性能不是特别好，有文章说评测下来Cassandra每秒大约不到1万次读写请求，我也看到一些对这个问题进行质疑的评论，但是评价Cassandra单个节点的性能是没有意义的，真实的分布式数据库访问系统必然是n多个节点构成的系统，其并发性能取决于整个系统的节点数量，路由效率，而不仅仅是单节点的并发负载能力。 <br>
            <br>
            2、<a href="http://project-voldemort.com/" target="_blank"><font color="#006699">Voldemort</font></a> <br>
            Voldemort是个和Cassandra类似的面向解决scale问题的分布式数据库系统，Cassandra来自于Facebook这个SNS网站，而Voldemort则来自于Linkedin这个SNS网站。说起来SNS网站为我们贡献了n多的NoSQL数据库，例如Cassandar，Voldemort，Tokyo Cabinet，Flare等等。Voldemort的资料不是很多，因此我没有特别仔细去钻研，Voldemort官方给出Voldemort的并发读写性能也很不错，每秒超过了1.5万次读写。 <br>
            <br>
            从Facebook开发Cassandra，Linkedin开发Voldemort，我们也可以大致看出国外大型SNS网站对于分布式数据库，特别是对数据库的scale能力方面的需求是多么殷切。前面我（robbin）提到，web应用的架构当中，web层和app层相对来说都很容易横向扩展，唯有数据库是单点的，极难scale，现在Facebook和Linkedin在非关系型数据库的分布式方面探索了一条很好的方向，这也是为什么现在Cassandra这么热门的主要原因。 <br>
            <br>
            如今，NoSQL数据库是个令人很兴奋的领域，总是不断有新的技术新的产品冒出来，改变我们已经形成的固有的技术观念，我自己（robbin）稍微了解了一些，就感觉自己深深的沉迷进去了，可以说NoSQL数据库领域也是博大精深的，我（robbin）也只能浅尝辄止，我（robbin）写这篇文章既是自己一点点钻研心得，也是抛砖引玉，希望吸引对这个领域有经验的朋友来讨论和交流。 <br>
            <br>
            从我（robbin）个人的兴趣来说，分布式数据库系统不是我能实际用到的技术，因此不打算花时间深入，而其他两个数据领域（高性能NoSQLDB和海量存储NoSQLDB）都是我很感兴趣的，特别是Redis，TT/TC和MongoDB这3个NoSQL数据库，因此我接下来将写三篇文章分别详细介绍这3个数据库。 <br>
            原帖:http://www.javaeye.com/topic/524977</div>
            </td>
        </tr>
    </tbody>
</table> <a href="http://hi.baidu.com/coollzh/blog/item/ff227dd137b92dd9562c8426.html">阅读全文</a>
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/coollzh/blog/category/%CA%FD%BE%DD%BF%E2">数据库</a>&nbsp;<a href="http://hi.baidu.com/coollzh/blog/item/ff227dd137b92dd9562c8426.html#comment">查看评论</a>]]></description>
        <pubDate>2009-12-02  01:02</pubDate>
        <category><![CDATA[数据库]]></category>
        <author><![CDATA[coollzh]]></author>
		<guid>http://hi.baidu.com/coollzh/blog/item/ff227dd137b92dd9562c8426.html</guid>
</item>

<item>
        <title><![CDATA[职场交流：一位软件工程师的7年总结[转]]]></title>
        <link><![CDATA[http://hi.baidu.com/coollzh/blog/item/3661a7a2cd6e8ea7caefd018.html]]></link>
        <description><![CDATA[
		
		<p minmax_bound="true"><strong minmax_bound="true">1、分享第一条经验</strong>：&ldquo;<strong><font color="#ff9900">学历代表过去、能力代表现在、学习力代表未来</font></strong>。&rdquo;其实这是一个来自国外教育领域的一个研究结果。相信工作过几年、十几年的朋友对这 个道理有些体会吧。但我相信这一点也很重要：&ldquo;重要的道理明白太晚将抱憾终生！&rdquo;所以放在每一条，让刚刚毕业的朋友们早点看到哈！</p>
<p minmax_bound="true"><strong minmax_bound="true">2、一定要确定自己的发展方向，并为此目的制定可行的计划</strong>。不要说什么，&ldquo;我刚毕业，还不知道将来可能做什么？&rdquo;，&ldquo;跟着感觉走，先做做看&rdquo;。因为，这样的观点会通过 你的潜意识去暗示你的行为无所事事、碌碌无为。一直做技术，将来成为专家级人物？向管理方向走，成为职业经理人？先熟悉行业和领域，将来自立门户？还是先 在行业里面混混，过几年转行做点别的？这很重要，它将决定你近几年、十年内&ldquo;做什么事情才是在做正确的事情！&rdquo;。</p>
<p minmax_bound="true"><strong minmax_bound="true">3、软件开发团队中，技术不是万能的，但没有技术是万万不能的</strong>！在技术型团队中，技术与人品同等重要，当然长相也比较重要哈，尤其在MM比较多的团队中。在软件项目团队 中，技术水平是受人重视和尊重的重要砝码。无论你是做管理、系统分析、设计、编码，还是产品管理、测试、文档、实施、维护，多少你都要有技术基础。算我孤 陋寡闻，我还真没有亲眼看到过一个外行带领一个软件开发团队成功地完成过软件开发项目，哪怕就一个，也没有看到。倒是曾经看到过一个&ldquo;高学历的牛人&rdquo;(非 技术型)带一堆人做完过一个项目，项目交付的第二天，项目组成员扔下一句&ldquo;再也受不了啦！&rdquo;四分五裂、各奔东西。那个项目的&ldquo;成功度&rdquo;大家可想而知了。</p>
<p minmax_bound="true"><strong minmax_bound="true">4、详细制定自己软件开发专业知识学习计划</strong>，并注意及时修正和调整(软件开发技术变化实在太快)。请牢记：&ldquo;<strong><font color="#ff0000">如果一个软件开发人员在1、2年内都没有更 新过自己的知识，那么，其实他已经不再属于这个行业了。&rdquo;</font></strong>不要告诉自己没有时间。来自时间管理领域的著名的&ldquo;三八原则&rdquo;告诫我们：<font color="#0000ff"><strong><u>另外的那8小时如何使用 将决定你的人生成败！</u></strong></font>本人自毕业以来，平均每天实际学习时间超过2小时。</p>
<p minmax_bound="true"><strong minmax_bound="true">5、书籍是人类进步的阶梯</strong>，对软件开发人员尤其如此。书籍是学 习知识的最有效途径，不要过多地指望在工作中能遇到&ldquo;世外高人&rdquo;，并不厌其烦地教你。对于花钱买书，我个人经验是：千万别买国内那帮人出的书！我买的那些 家伙出的书，100%全部后悔了，无一本例外。更气愤的是，这些书在二手市场的地摊上都很难卖掉。&ldquo;拥有书籍并不表示拥有知识；拥有知识并不表示拥有技 能；拥有技能并不表示拥有文化；拥有文化并不表示拥有智慧。&rdquo;只有将书本变成的自己智慧，才算是真正拥有了它。</p>
<p minmax_bound="true"><strong minmax_bound="true">6、不要仅局限于对某项 技术的表面使用上</strong>，哪怕你只是偶尔用一、二次。&ldquo;对任何事物不究就里&rdquo;是任何行业的工程师所不应该具备的素质。开发Windows应用程序，看看 Windows程序的设计、加载、执行原理，分析一下PE文件格式，试试用SDK开发从头开发一个Windows应用程序；用VC＋＋、</p>
<p minmax_bound="true">Delphi、Java、.Net开发应用程序，花时间去研究一下MFC、VCL、J2EE、.Net它们框架设计或者源码；除了会用J2EE、 JBoss、Spring、Hibernate等等优秀的开源产品或者框架，抽空看看大师们是如何抽象、分析、设计和实现那些类似问题的通用解决方案的。 试着这样做做，你以后的工作将会少遇到一些让你不明就里、一头雾水的问题，因为，很多东西你&ldquo;知其然且知其所以然&rdquo;！</p>
<p minmax_bound="true"><strong minmax_bound="true">7、在一种语言上编程，但别为其束缚了思想</strong>。&ldquo;代码大全&rdquo;中说：&ldquo;深入一门语言编程，不要浮于表面&rdquo;。深入一门语言开发还远远不足，任何编程语言的存在都有其自身的理由， 所以也没有哪门语言是&ldquo;包治百病&rdquo;的&ldquo;灵丹妙药&rdquo;。编程语言对开发人员解决具体问题的思路和方式的影响与束缚的例子俯拾皆是。</p>
<p minmax_bound="true">我的经验 是：用面对对象工具开发某些关键模块时，为什么不可以借鉴C、C51、汇编的模块化封装方式？用传统的桌面开发工具(目前主要有VC++、Delphi) 进行系统体统结构设计时，为什么不可以参考来自Java社区的IoC、AOP设计思想，甚至借鉴像Spring、Hibernate、JBoss等等优秀 的开源框架？在进行类似于实时通信、数据采集等功能的设计、实现时，为什么不可以引用来自实时系统、嵌入式系统的优秀的体系框架与模式？为什么一切都必须 以个人、团队在当然开发语言上的传统或者经验来解决问题？？？&ldquo;<strong><u>他山之石、可以攻玉</u></strong>&rdquo;。</p>
<p minmax_bound="true"><strong minmax_bound="true">8、养成总结与反思的习惯</strong>，并有意识地提炼日常 工作成果，形成自己的个人源码库、解决某类问题的通用系统体系结构、甚至进化为框架。众所周知，对软件开发人员而言，有、无经验的一个显著区别是：无经验 者完成任何任务时都从头开始，而有经验者往往通过重组自己的可复用模块、类库来解决问题（其实这个结论不应该被局限在软件开发领域、可以延伸到很多方 面）。这并不是说，所有可复用的东西都必须自己实现，别人成熟的通过测试的成果也可以收集、整理、集成到自己的知识库中。但是，最好还是自己实现，这样没 有知识产权、版权等问题，关键是自己实现后能真正掌握这个知识点，拥有这个技能。</p>
<p minmax_bound="true"><strong minmax_bound="true">9、理论与实践并重，内外双修</strong>。工程师的内涵是：以工 程师的眼光观察、分析事物和世界。一个合格的软件工程师，是真正理解了软件产品的本质及软件产品研发的思想精髓的人（个人观点、欢迎探讨）。掌握软件开发 语言、应用语言工具解决工作中的具体问题、完成目标任务是软件工程师的主要工作，但从软件工程师这个角度来看，这只是外在的东西，并非重要的、本质的工 作。学习、掌握软件产品开发理论知识、软件开发方法论，并在实践中理解、应用软件产品的分析、设计、实现思想来解决具体的软件产品研发问题，才是真正的软 件工程师的工作。站在成熟理论与可靠方法论的高度思考、分析、解决问题，并在具体实践中验证和修正这些思想与方式，最终形成自己的理论体系和实用方法论。</p>
<p minmax_bound="true"><strong minmax_bound="true">10、心态有多开放，视野就有多开阔</strong>。不要抱着自己的技术和成果，等到它们都已经过时变成垃圾了，才拿出来丢人现眼。请及时发布自己的研究成果：开发的 产品、有创意的设计或代码，公布出来让大家交流或者使用，你的成果才有进化和升华的机会。想想自己2000年间开发的那些Windows系统工具，5、6 年之后的今天，还是那个样子，今天流行的好多Windows系统工具都比自己的晚，但进化得很好，且有那么多用户在使用。并且，不要保守自己的技术和思 想，尽可能地与人交流与分享，或者传授给开发团队的成员。&ldquo;与人交换苹果之后，每个人还是只有一个苹果；但交换思想之后，每个人都拥有两种思想&rdquo;，道理大 家都懂，但有多少人真正能做到呢？</p>
<p minmax_bound="true">11、<strong minmax_bound="true">尽量参加开源项目的开发、或者与朋友共同研制一些自己的产品</strong>，千万不要因为没有钱赚而不做。网 络早已不再只是&ldquo;虚拟世界&rdquo;，网上有很多的开源项目、合作开发项目、外包项目，这都是涉猎工作以外的知识的绝好机会，并且能够结识更广的人缘。不要因为工 作是做ERP，就不去学习和了解嵌入式、实时、通信、网络等方面的技术，反过来也是一样。如果当别人拿着合同找你合作，你却这也不会，那也不熟时，你将后 悔莫及。</p>
<p minmax_bound="true"><strong minmax_bound="true">12、书到用时方恨少</strong>，不要将自己的知识面仅仅局限于技术方面。诺贝尔经济学奖得主西蒙教授的研究结果表明：&ldquo;<font color="#9900ff"><strong><u>对于一个有一定基础的人来说，他只要真正肯下功夫，在6个月内就可以掌握任何一门学问。</u></strong></font>&rdquo;教育心理学界为感谢西蒙教授的研究成果，故命名为西蒙学习法。</p>
<p minmax_bound="true">可见，掌握一门陌生的学问远远没有想象的那么高难、深奥。多方吸取、广泛涉猎。极力夯实自己的影响圈、尽量扩大自己的关注圈。财务、经济、税务、管理等等知识，有空花时间看看，韬光养晦、未雨绸缪。</p>
<p minmax_bound="true">13、本文的总结与反思：</p>
<p minmax_bound="true">A：不要去做技术上的高手，除非你的目标如此。虽然本文是关于提高软件开发知识的建议，做技术的高手是我一向都不赞同的。你可以提高自己的专业知识，但能胜任工作即止。</p>
<p minmax_bound="true">B：提高软件知识和技术只是问题的表面，本质是要提高自己认识问题、分析问题、解决问题的思想高度。软件专业知识的很多方法和原理，可以很容易地延伸、应用到生活的其它方面。</p>
<p minmax_bound="true">C：在能胜任工作的基础上，立即去涉猎其它领域的专业知识，丰富自己的知识体系、提高自己的综合素质，尤其是那些目标不在技术方面的朋友。</p> <a href="http://hi.baidu.com/coollzh/blog/item/3661a7a2cd6e8ea7caefd018.html">阅读全文</a>
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/coollzh/blog/category/%BC%DC%B9%B9%D3%EB%C9%E8%BC%C6">架构与设计</a>&nbsp;<a href="http://hi.baidu.com/coollzh/blog/item/3661a7a2cd6e8ea7caefd018.html#comment">查看评论</a>]]></description>
        <pubDate>2009-11-20  21:59</pubDate>
        <category><![CDATA[架构与设计]]></category>
        <author><![CDATA[coollzh]]></author>
		<guid>http://hi.baidu.com/coollzh/blog/item/3661a7a2cd6e8ea7caefd018.html</guid>
</item>

<item>
        <title><![CDATA[Principles and Patterns of .NET Software Development]]></title>
        <link><![CDATA[http://hi.baidu.com/coollzh/blog/item/38e72b60c5c6e4d58cb10d34.html]]></link>
        <description><![CDATA[
		
		<a href="http://www.devproconnections.com/Events/eLearning.aspx">http://www.devproconnections.com/Events/eLearning.aspx</a> 
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/coollzh/blog/category/%2Enet%26%2347%3Basp%2Enet%26%2347%3Bc%23">.net&#47;asp.net&#47;c#</a>&nbsp;<a href="http://hi.baidu.com/coollzh/blog/item/38e72b60c5c6e4d58cb10d34.html#comment">查看评论</a>]]></description>
        <pubDate>2009-11-18  23:34</pubDate>
        <category><![CDATA[.net&#47;asp.net&#47;c#]]></category>
        <author><![CDATA[coollzh]]></author>
		<guid>http://hi.baidu.com/coollzh/blog/item/38e72b60c5c6e4d58cb10d34.html</guid>
</item>

<item>
        <title><![CDATA[开源项目汇总]]></title>
        <link><![CDATA[http://hi.baidu.com/coollzh/blog/item/20d93cfbb6a71e6e024f564f.html]]></link>
        <description><![CDATA[
		
		<a href="http://www.cnblogs.com/shanyou/category/32025.html">http://www.cnblogs.com/shanyou/category/32025.html</a><br>
<br>
<div class="entrylistItem">
<div class="entrylistPosttitle">
<p><a class="entrylistItemTitle" href="http://www.cnblogs.com/shanyou/archive/2009/09/24/1573008.html">OpenSSL的托管项目</a></p>
<div class="entrylistPosttitle"><a class="entrylistItemTitle" href="http://www.cnblogs.com/shanyou/archive/2009/09/20/1570424.html"><font color="#f03331">MySpace:开源数据处理Qizmt</font></a></div>
<div class="entrylistPostSummary">
<p>&nbsp;&nbsp;&nbsp;&nbsp;  摘要: MySpace发布了一个新的开源项目-Qizmt，是数据挖掘小组开发的一个分布式计算框架。Qizmt是基于MapReduce的分布式处理框架，丛所周知，这是Google搜索引擎基础设施的一个核心部分。但是Qizmt运行在微软服务器的大型集群上，具体内容可参看InfoQ：Qizmt：MySpace的开源MapReduce框架。 &nbsp;&nbsp;<a href="http://www.cnblogs.com/shanyou/archive/2009/09/20/1570424.html"><font color="#f03331">阅读全文</font></a></p>
<div class="entrylistPosttitle"><a class="entrylistItemTitle" href="http://www.cnblogs.com/shanyou/archive/2009/07/16/1524515.html"><font color="#f03331">微软反跨站脚本库3.0 RTM</font></a></div>
<div class="entrylistPostSummary">
<p>&nbsp;&nbsp;&nbsp;&nbsp;  摘要: 跨站脚本Cross-Site Scripting（XSS）是最为流行的Web安全漏洞之一。据统计，2007年，跨站脚本类的安全漏洞的数目已经远远超出传统类型的安全漏洞。以及在ASP.NET应用程序中如何避免XSS攻击。&nbsp;&nbsp;<a href="http://www.cnblogs.com/shanyou/archive/2009/07/16/1524515.html"><font color="#f03331">阅读全文</font></a></p>
<p> </p>
<div class="entrylistItem">
<div class="entrylistPosttitle"><a class="entrylistItemTitle" href="http://www.cnblogs.com/shanyou/archive/2008/12/13/1354156.html"><font color="#f03331">Json.NET 3.0</font></a></div>
<div class="entrylistPostSummary">&nbsp;&nbsp;&nbsp;&nbsp;  摘要: Json.NET，提供相当完整的文档之外，还提供了 LINQ to JSON 的 LINQ Provider 可以更方便的读取JSON 对象，今后将可比以往用更轻松的方式用 .NET编写 JSON 相&nbsp;&nbsp;<a href="http://www.cnblogs.com/shanyou/archive/2008/12/13/1354156.html"><font color="#f03331">阅读全文</font></a></div>
<div class="entrylistItemPostDesc"> </div>
</div>
<div class="postSeparator"> </div>
<div class="entrylistItem">
<div class="entrylistPosttitle"><a class="entrylistItemTitle" href="http://www.cnblogs.com/shanyou/archive/2008/12/11/1353288.html"><font color="#f03331">asp.net mvc cms项目Oxite</font></a></div>
<div class="entrylistPostSummary">&nbsp;&nbsp;&nbsp;&nbsp;  摘要: Oxite更是一个asp.net mvc项目的实例，Oxite目的就是向开发者展示ASP.Net MVC的功能。微软使用Oxite创建了Mix Online网站，并向开发者提供了该站点的源代码以供学习。 &nbsp;&nbsp;<a href="http://www.cnblogs.com/shanyou/archive/2008/12/11/1353288.html"><font color="#f03331">阅读全文</font></a></div>
<div class="entrylistItemPostDesc"> </div>
</div>
<div class="postSeparator"> </div>
<div class="entrylistItem">
<div class="entrylistPosttitle"><a class="entrylistItemTitle" href="http://www.cnblogs.com/shanyou/archive/2008/12/05/1348293.html"><font color="#f03331">memcached全面剖析</font></a></div>
<div class="entrylistPostSummary">&nbsp;&nbsp;&nbsp;&nbsp;  摘要: 这是由 mixi 株式会社 开发部系统运营组的两位工程师野雅广、前坂徹所写，日常负责程序的运营。本文将针对最近在Web应用的可扩展性领域的热门话题memcached，说明其内部结构和使用。这篇连载语言简洁、通俗易懂，非常适合memcached入门的人阅读。&nbsp;&nbsp;<a href="http://www.cnblogs.com/shanyou/archive/2008/12/05/1348293.html"><font color="#f03331">阅读全文</font></a></div>
</div>
</div>
</div>
</div>
</div> <a href="http://hi.baidu.com/coollzh/blog/item/20d93cfbb6a71e6e024f564f.html">阅读全文</a>
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/coollzh/blog/category/%2Enet%26%2347%3Basp%2Enet%26%2347%3Bc%23">.net&#47;asp.net&#47;c#</a>&nbsp;<a href="http://hi.baidu.com/coollzh/blog/item/20d93cfbb6a71e6e024f564f.html#comment">查看评论</a>]]></description>
        <pubDate>2009-11-17  03:31</pubDate>
        <category><![CDATA[.net&#47;asp.net&#47;c#]]></category>
        <author><![CDATA[coollzh]]></author>
		<guid>http://hi.baidu.com/coollzh/blog/item/20d93cfbb6a71e6e024f564f.html</guid>
</item>

<item>
        <title><![CDATA[好的软件是怎么写出来的？]]></title>
        <link><![CDATA[http://hi.baidu.com/coollzh/blog/item/35e344fa88a31314a9d3116d.html]]></link>
        <description><![CDATA[
		
		正像敏捷一样，一位创始人也说敏捷其实并不神秘，一个爱动脑筋的程序员做几年软件之后，自然会采用这些方法来改进工作效果/提高效率。确实也是这样。<br>
<div> </div>
<div>软件培训内容也是这样，虽然很多问题，之前也思考过，也改进过，但在真正的工作环境中，看到很多code smell，也无能为力，只能麻木了。</div>
<div> </div>
<div>参加一下这样的培训很有好处，对各种code smell/重构方法等进行了分门别类的系统介绍，还有精心设计的实战演练，和一些方法的演示，都非常有裨益。</div>
<div> </div>
<div>概括一些我认为比较重要的经验：</div>
<div>1 代码是反复修改出来的。（我之前也有此体会，我觉得好的代码就是修改修改再修改才出来的，跟写文章是一样的。不过，事实上，软件公司可能并不这样认为，它可能觉得写完代码提交之后就不应该修改，如果修改说明质量不好，有些甚至采用强制措施锁库等，不允许修改。）</div>
<div> </div>
<div>2 小粒度重构。（把重构分为若干小步，一次只走一小步，修改一点点之后立即运行测试用例，通过之后继续走。也成为baby step。不这样做，很可能无法做到随时运行用例，检查修改是否会破坏已有功能。）</div>
<div> </div>
<div>3 用工具进行重构。（用工具效率会高很多，也不容易出错，熟练掌握这种套路之后，甚至可以放心的去对一些看不到懂代码做重构。难怪TW不懂业务，也能大刀阔斧的指导重构啊。由此看来，现在更多的倾向于补充系统用例，而不是重构，也有点保守了啊，当然安全非常重要，讲重构的也都强调有自动测试保障再重构。）</div>
<div> </div>
<div>4 注释是smell。（最好的代码是非常简洁，本身代码就是自注释，无须额外注释的。）</div>
<div> </div>
<div>5 长函数是smell。（长不是绝对长度，一个做软件的人，如果看一眼该函数，不懂它要干什么，那么就是长函数。）</div>
<div> </div>
<div>6 注意写代码的层次。（写上层的东西，也就是接近用户的[比如类的使用者]，那么它里面每句话都应该是面对用户的，用户无须弄懂内部原理也要能很容易看懂。真正的实现可能被封装在一个私有方法里面。这种思想在敏捷的story中也有体现，它要求story的描述要是用户都能懂的。这一点，我觉得也可以总结为&ldquo;写代码要像写文章一样的写&rdquo;，估计写文章，没有人会把文章写得别人看不懂吧？）</div> <a href="http://hi.baidu.com/coollzh/blog/item/35e344fa88a31314a9d3116d.html">阅读全文</a>
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/coollzh/blog/category/%C8%ED%BC%FE%B9%FD%B3%CC">软件过程</a>&nbsp;<a href="http://hi.baidu.com/coollzh/blog/item/35e344fa88a31314a9d3116d.html#comment">查看评论</a>]]></description>
        <pubDate>2009-11-16  23:57</pubDate>
        <category><![CDATA[软件过程]]></category>
        <author><![CDATA[coollzh]]></author>
		<guid>http://hi.baidu.com/coollzh/blog/item/35e344fa88a31314a9d3116d.html</guid>
</item>

<item>
        <title><![CDATA[给敏捷软件开发的26条建议]]></title>
        <link><![CDATA[http://hi.baidu.com/coollzh/blog/item/74c94d292c2345f498250ad3.html]]></link>
        <description><![CDATA[
		
		<ul class="summary">敏捷开发真正的问题是什么？其实敏捷主要还是一种观念，一种意识，通过人来推动。本文总结了26条有关敏捷开发的关键原则，供读者参考借鉴。</ul>
    <ul class="con">
        <p> </p>
        <p>我经常收集各种各样的至理名言，最近我重温敏捷开发；真正的问题是什么？下面是一份26条关键原则的清单，以指引敏捷软件开发团队。</p>
        <p> </p>
        <div class="tuij">
        <ul>
            <li><a href="http://developer.51cto.com/art/200909/151316.htm" target="_blank"><font color="#464646">新的挑战：敏捷开发与优秀的程序员</font></a></li>
            <li><a href="http://developer.51cto.com/art/200909/151721.htm" target="_blank"><font color="#464646">敏捷开发中常犯的10大错误</font></a></li>
            <li><a href="http://developer.51cto.com/art/200909/151934.htm" target="_blank"><font color="#464646">讨论：敏捷开发真的对架构设计不利吗？</font></a></li>
            <li><a href="http://developer.51cto.com/art/200909/152443.htm" target="_blank"><font color="#464646">理解敏捷开发：需求处理与齐头并进</font></a></li>
            <li><a href="http://developer.51cto.com/art/200910/156471.htm" target="_blank"><font color="#464646">详解敏捷开发全景图</font></a></li>
        </ul>
        </div>
        1、完整地干完一件事后在开始另一件事：用厨房比喻来说就是：&ldquo;先上这道菜，再开始做下一道&rdquo;。软件开发的最大问题就是同时开始几件事情，这将不可避免的造成某些工作被废弃，从而造成浪费。专注于一件事；完整地实现其功能；运行测试；编写文档；签入所有，把这当做一项工作完成，然后再开始下一件事。
        <p> </p>
        <p>2、不要破坏构建：非常明显，但必须被包含在任何软件开发建议清单中。程序员在签入之前采取所有合适的预防措施进行测试，则永远不会破坏构建。如果构建被破坏，通常是因为有人偷懒了。</p>
        <p>3、在用例需要之前，不要实现程序：当你实现一个特定的类，你应该在脑海中有一个特定的用例，同时应该只实现用例需要的方法。你可以考虑该类潜在的功能，写入注释之中，但直到用例真正需要时，才应去实现它。</p>
        <p>4、在用例需要之前，不要添加数据成员：同上一条，不过这是从类的数据成员角度考虑的。似乎显而易见地，&ldquo;客户&rdquo;记录需要&ldquo;送货地址&rdquo;，但直到有用例明确需要送货地址，才应该实现它。</p>
        <p>5、不要害怕做决定，不要害怕改变先前的决定：敏捷开发是关于相应变化和快速相应的。开发初期，你没有完整的信息。你应该尽可能的推迟决策，直到你必须做出决策的时候。没有信息，无法支持你的决定，相反，在有效信息的基础上做出最佳决定。有了新的信息，不要害怕改变先前的决定。（某些&ldquo;恐龙&rdquo;称之为摇摆不定，但我称之为响应变化的环境）</p>
        <p>6、持续学习如何改善质量：这项工作永不会结束，因此你应经常留意可以改善的事情，并收集质量问题被确认和处理的案例。</p>
        <p>7、度量、度量、度量：敏捷开发帮助处理未来不确定性问题，但对于过去应没有不确定性。测试应持续运行，每次运行的性能表现应被度量和记录。</p>
        <p>8、为人而设计，而不是系统：开发者常常因技术而使设计误入歧途。绝不要忘记设计的最终目标，那就是帮助人们完成工作。</p>
        <p>9、测试是产品的一部分：很多开发者和经理认为产品就是交付给客户的东西，而其它所有东西都不那么重要。测试应被认为是产品实实在在的一个部分，值得在设计时仔细考虑，甚至，在很多情况下，和产品一起交付给客户。（后半部分有争议，但是内建测试作为软件交付的一部分仅仅占用无关紧要的空间，却在必要时提供显而易见的好处，这种方式应该被考虑。）</p>
        <p>10、在代码之前编写测试：测试本身可以用来阐释真正需要的设计。设计的缺陷常常是通过测试用例被发现的。想想看，编码之前，通过这些用例，可以节约多少时间。但是，为用例1编写测试，然后编码，然后再开始用例2。</p>
        <p>11、消除浪费：坦率的说，这是另一个必须包含在任何开发原则清单中的陈词滥调，因为它太重要了。发现浪费并消除它，这项工作没有尽头。消除任何不能增加客户价值的东西。如果你不能确认客户价值，那很可能你并不需要它。</p>
        <p>12、建立对构建破坏立即响应的文化：要明白当构建被破坏，会影响项目中的每一个人，因此，最重要的是确认核心代码被构建并合理测试。我曾见过有些团队放任失败测试持续数月，因为那是其它人的工作。每个人都痛苦，但没人采取行动。想反，必须形成共识，那就是小工作能为团队获得大的回报。</p>
        <p>13、所有团队成员应理解客户需要：大型的复杂项目定然被分解为独立的团队，进而被分派给开发人员。但是，不应在此范围内做的是，失去关注最终项目真正用户的期望和目标。</p>
        <p>14、把相关定义放在一起：组织代码以使高度相关的事情在一起，或在一个类中。这是标准面向对象设计封装原则。理想情况下，所有的类外的代码不需要知道内部工作细节。一些开发者乐于将细节扩散到多个文件中以便按不同方式组织，如所有相同的数据类型放在一起，或者按字母顺序组织。例如，在他们要用的不同包中，将所有常量放在一个类里，这增加了不必要的程序复杂性。指导原则应该是按相关性分组从而隐藏复杂性。</p>
        <p>15、始终在签入之前运行测试：这条准则帮助你满足&ldquo;不要破坏构建&rdquo;准则。</p>
        <p>16、过早的优化时万恶之源：引用高德纳被证实的话：代码应编写良好以避免微观层面的浪费，但独立方法层次以外的优化应等待整个程序基于真实的最终用户使用情景的压力测试的进行。仅仅基于对代码的静态理解，直觉地判断对整体性能什么是重要的，结论几乎总是错误的。相反，度量整个系统的行为，辨别1%真正影响性能的代码，并专注于此。</p>
        <p>17、减少积压未完成的编码任务：当开发人员开始一个用例，会发生成本，跟已修改却未完成和测试的代码相关联。留着未完成的变化几天或几个星期会累积成巨大的重做风险。考虑每个估算需要一天的三个任务，同时开始这三个任务，并在3天内同时进行，意味着9个单位的累计成本。但是顺序进行每个任务，完成一个再开始下一个，意味着只有3个单位的成本。这个不是直觉，直觉告诉我们，在工作完成之前，我们不妨同时做三件事情。但软件不像物理构造。短小，快速和完整的工作不仅减少认知的负担，而且减少未完成工作与他人未完成工作之间冲突的可能。</p>
        <p>18、不要过度强调代码的通用性：这就是著名的&ldquo;YAGNI-你不会需要它&rdquo;。当编写一个特定类的时候，程序员总喜欢认为该类可能用于其它用途。如果现在的用例需要这些用途，这很好，但是，程序员经常考虑未被提及的用途，或者那些实际上永远不需要的。（这常常让我联想到经典的周六现场滑稽短剧，关于某产品既是地板蜡，也是糕点上的甜食。）</p>
        <p>19、两行代码能行，就不要用三行：有人阅读时，简洁的代码总能获得回报。但不要将代码压缩到难以阅读。更小的，编写良好的代码比之冗长的，编写华丽的代码更容易维护，也更容易发现错误。始终尽可能简化，但别过分。</p>
        <p>20、不要用行数来度量代码：完成特定任务所需的代码行数，不同的程序员之间和编码风格之间差异很大。代码行数不能告诉你代码完成和质量的些许东西。代码质量可以相差200倍，这足以抵消代码行数的作用。应该统计功能用例的数目。</p>
        <p>21、持续地重新设计和重构：谨慎地使用这条准则，因为有些代码脆弱而难以改变，但通常你不应害怕更改代码以符合实际使用情况。一个数据成员过去可能是整数，但是当一个用例要求它是一个浮点数时不要害怕去改变它。</p>
        <p>22、删除死代码：涉及到大量不能很好理解的代码是，有个倾向是不自找麻烦。一个例子就是往类中增加新的方法去替换另一个，开发人员常常会留下旧的方法以防万一。必须努力检查方法是否必须，如果没有证据表明它是必须的，那就删除它。最糟糕的就是注释掉大量的代码，并把它留在那儿。注释掉的代码应在测试通过后尽快删除，当然应在签入之前。因此，某个时候你发现一些东西可能并不需要，付出小小的努力去验证并消除此代码能让代码基线更易维护。</p>
        <p>23、不要发明新语言：程序员喜爱使用文本文件配置在运行时驱动功能。没有配置文件能够不编译而改变程序的行为。XML的出现推动了无休止的专门定制&ldquo;脚本语言&rdquo;的浪潮，以使功能能被最终用户定制而不需要编译。这种推理的缺陷在于，离开某个特定实施的环境，操作行为几乎从来没能很好地精确定义，同时，那些脚本语言只对那些对问题领域代码的内部运行有深入了解的人有用。因此，不具备详尽内部知识的真实最终用户永远不可能知道预料复杂的命令组合的效果需要什么。脚本语言有用，也不能被消除，但是设计者必须采取非常非常保守的态度，尽可能使用现有的语言，避免新的发明。</p>
        <p>24、在你准备实现并测试前，别做设计：你应该有行进的总体思路和对系统架构的概览，但是，直到开发迭代允许设计被实现和测试前，不要做详细设计，不要编写功能实现的详细说明。详细设计应当只涉及到处理目前的用例。软件开发中最大的浪费源于将时间花在设计那些不需要，或者因为某些错误的设计假定而需要重新设计的事情之上。</p>
        <p>25、设计是可塑的：不像物理制造，软件可以很容易地获得显著改变。事实上，有大量证据证明软件本身比描述软件的设计说明书更容易改变。此外，软件比说明书更有效地传达设计。因此，你应该把时间用于直接实现设计，让客户能看见设计的细节。如果你犯错并改变设计，改变软件比改变规格更容易。但最重要的是，客户看到代码运行后，你关于客户想要什么的信息大为完善。</p>
        <p>26、花时间编写发现和报告异常情况的代码中的问题的完整描述：程序员往往很懒惰，抛出粗浅描述错误的异常。认为他们永远是唯一会看到这个问题的人，并且他们从含糊的描述会记得这个问题的意思。但实际上，在客户支持环境，不准确或者不完整的错误报告比其它原因浪费更多的时间。编写每个错误消息，就好像你正向某个正好走进房间并且没有此代码经验的人解释状况。客户和客户支持团队毕竟没有此代码的经验。</p>
        <p>这些介绍没有特定的顺序，欢迎讨论我忽略的原则，或者（如果是这种情况）你不认同的敏捷开发原则。</p>
        <p>原文：<font color="#0000ff">26 Hints for Agile Software Development</font>  作者：<font color="#0000ff">Keith Swenson</font></p>
        <p>原译文标题：给敏捷软件开发的26条建议 译者：射覆</p>
    </ul> <a href="http://hi.baidu.com/coollzh/blog/item/74c94d292c2345f498250ad3.html">阅读全文</a>
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/coollzh/blog/category/%C8%ED%BC%FE%B9%FD%B3%CC">软件过程</a>&nbsp;<a href="http://hi.baidu.com/coollzh/blog/item/74c94d292c2345f498250ad3.html#comment">查看评论</a>]]></description>
        <pubDate>2009-11-11  19:33</pubDate>
        <category><![CDATA[软件过程]]></category>
        <author><![CDATA[coollzh]]></author>
		<guid>http://hi.baidu.com/coollzh/blog/item/74c94d292c2345f498250ad3.html</guid>
</item>

<item>
        <title><![CDATA[编程匠艺学习笔记(一)--防御性编程关键概念]]></title>
        <link><![CDATA[http://hi.baidu.com/coollzh/blog/item/2592da34bc722abdd1a2d3b6.html]]></link>
        <description><![CDATA[
		
		<p>一、不要做任何设想。没有记录下来的设想会不断的造成缺陷，特别是随着代码的增长</p>
<p>二、墨菲定律：<font color="#ff0000">凡事可能出错的事，准会出错</font>。</p>
<p>三、对防御性编程的误解：检查错误、测试、调试不是防御性编程</p>
<p>四、<font color="#ff0000">欲速则不达</font>。每敲一个字，都要想清楚你要输入的是什么，不要仓促的编写代码</p>
<p>五、<font color="#ff0000">不要相信任何人，包括你自己</font>都可能把缺陷引入到你的程序逻辑中。用怀疑的眼光审视所有的输入和所有的结果，直到你证明它们是正确的。</p>
<p>六、简单就是一种美，不要让你的代码过于复杂；编码的目标是清晰，而不是简洁。</p>
<p>七、编译时打开所有警告开关；经常使用静态分析工具分析你的代码。</p>
<p>八、大多数难以觉察的错误都是因为程序员没有<strong><font color="#ff0000">检查函数返回值</font></strong>而引起的。</p>
<p>九、重视所有稀有资源，慎重的管理他们的获取和释放。</p>
<p>十、初始化所有变量。</p>
<p>十一、变量声明的位置和使用它的位置尽可能接近，防止它干扰代码的其他部分。</p>
<p>十二、不要在多个地方重用同一个临时变量</p>
<p>十三、慎重处理默认行为，如switch语句的default case语句，没有else的if语句等。</p>
<p>十四、对程序的设想加上前置条件和后置条件，关键地方加上断言，并确保断言不会带来副作用</p>
<p> </p>
<p> </p> <a href="http://hi.baidu.com/coollzh/blog/item/2592da34bc722abdd1a2d3b6.html">阅读全文</a>
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/coollzh/blog/category/%C8%ED%BC%FE%B9%FD%B3%CC">软件过程</a>&nbsp;<a href="http://hi.baidu.com/coollzh/blog/item/2592da34bc722abdd1a2d3b6.html#comment">查看评论</a>]]></description>
        <pubDate>2009-11-07  14:45</pubDate>
        <category><![CDATA[软件过程]]></category>
        <author><![CDATA[coollzh]]></author>
		<guid>http://hi.baidu.com/coollzh/blog/item/2592da34bc722abdd1a2d3b6.html</guid>
</item>

<item>
        <title><![CDATA[Serialization in Windows Communication Foundation]]></title>
        <link><![CDATA[http://hi.baidu.com/coollzh/blog/item/1559d7eca09ec63727979122.html]]></link>
        <description><![CDATA[
		
		<p><a href="http://msdn.microsoft.com/zh-cn/magazine/cc163569(en-us).aspx#S1">http://msdn.microsoft.com/zh-cn/magazine/cc163569(en-us).aspx#S1</a></p>
<div class="ColumnTypeSubTitle"><font color="#0000ff" size="3">Serialization in Windows Communication Foundation</font></div>
<div class="ColumnByLine">Aaron Skonnard</div>
<div><span class="CodeDownloadText">
<div class="MTPS_CollapsibleRegion">
<div class="CollapseRegionLink" jquery1257516498270="2"> </div>
<div style="display: block" class="MTPS_CollapsibleSection"><a href="http://msdn.microsoft.com/zh-cn/magazine/cc163569(en-us).aspx#S1" s_oidt="0" s_oid="http://msdn.microsoft.com/zh-cn/magazine/cc163569(en-us).aspx#S1"><font color="#0066dd">Serializing and Encoding </font></a><br>
<a href="http://msdn.microsoft.com/zh-cn/magazine/cc163569(en-us).aspx#S2"><font color="#0066dd">Behind the Scenes</font></a> <br>
<a href="http://msdn.microsoft.com/zh-cn/magazine/cc163569(en-us).aspx#S3"><font color="#0066dd">Defining Serialization Mapping</font></a> <br>
<a href="http://msdn.microsoft.com/zh-cn/magazine/cc163569(en-us).aspx#S4"><font color="#0066dd">Working with XmlSerializer</font></a> <br>
<a href="http://msdn.microsoft.com/zh-cn/magazine/cc163569(en-us).aspx#S5"><font color="#0066dd">Working with DataContractSerializer</font></a> <br>
<a href="http://msdn.microsoft.com/zh-cn/magazine/cc163569(en-us).aspx#S6"><font color="#0066dd">Working with NetDataContractSerializer</font></a> <br>
<a href="http://msdn.microsoft.com/zh-cn/magazine/cc163569(en-us).aspx#S7"><font color="#0066dd">Advanced Serialization Concepts</font></a> <br>
<a href="http://msdn.microsoft.com/zh-cn/magazine/cc163569(en-us).aspx#S8"><font color="#0066dd">Conclusion</font></a></div>
</div>
</span></div>
<div class="ArticleNormalPara">Windows Communication Foundation has been built from the ground up around the tenets of service orientation. It supports several serialization mechanisms that make it easy to bring existing types forward and provides a simple, interoperable foundation for future service-oriented applications. Windows<span class="superscript"><font size="1">&reg;</font></span> Communication Foundation (which is still in beta) embraces XML as a key enabling technology. While you can use it to build services that process XML directly, most developers prefer to leverage serialization mechanisms that automate moving between objects in the Microsoft<span class="superscript"><font size="1">&reg;</font></span> .NET Framework and XML Infosets.</div>
<div class="ArticleNormalPara">There are two general approaches you can take when implementing a Web service. One is to embrace XML and program directly against the messages. This offers a high degree of flexibility, especially when tackling tough challenges like versioning, where core XML technologies like XPath, XSLT, and XQuery are indispensable. But many developers may find this technique tedious and overwhelming. The other approach is to predefine a mapping between .NET and XML, and then rely on automated serialization mechanisms. This hides the various XML details in order to simplify the developer experience. Windows Communication Foundation supports both approaches, with equal depth.</div>
<div class="ArticleNormalPara">Internally, Windows Communication Foundation represents all messages with the Message class, which is found in System.ServiceModel.Channels. The Message class models a SOAP message, commonly referred to as a SOAP envelope, which has a header section and a body that carries the payload. The Message class provides an interface for interacting with the header section and body section using either System.Xml classes or type-based serialization.</div>
<div class="ArticleNormalPara">When working at the message level, you can explicitly choose which technique to use. However, the most common way to make use of serialization in Windows Communication Foundation is to author service contracts in terms of serializable types, as shown here: <span >
<div class="libCScode">
<div class="CodeSnippetTitleBar">
<div class="CodeDisplay"> </div>
<div class="CopyCodeButton"><a class="copyCode" title="复制代码" href=" :CopyCode( ctl00_MTCS_mainContentContainer_ctl03_code );">
<div style="border-right-width: 0px; width: auto; border-top-width: 0px; border-bottom-width: 0px; height: 9px; border-left-width: 0px" class="LibC_copy_off" align="center"> </div>
复制代码 </a></div>
</div>
<div style="background-color: #ddd" dir="ltr">
<pre style="word-wrap: break-word; word-break: break-all" class="libCScode" space="preserve">[ServiceContract]
public interface IEchoService
{
    [OperationContract]
    Person EchoPerson(Person person);
}</pre>
</div>
</div>
</span></div>
<div class="ArticleNormalPara">By annotating the .NET interface with [ServiceContract], you indicate that the .NET type definition will also serve as a service contract. Think of Web Services Description Language (WSDL). Annotating the method signature with [OperationContract] indicates that you want the method to be included in the service contract. At run time, Windows Communication Foundation automatically maps the method signature to a pair of messages behind the scenes, each containing a Person in the SOAP body. It then uses a serializer to map the Person object into the message. (For complete control over what goes where in the SOAP envelope, you can use [MessageContract] types in the signature.)</div>
<p><br>
 </p>
<div class="ArticleTypeTitle">Serializing and Encoding</div>
<div class="ArticleNormalPara">Windows Communication Foundation supports three serializers: XmlSerializer, DataContractSerializer, and NetDataContractSerializer. Each of these comes with different mapping algorithms and customization techniques. (See <strong>Figure 1</strong> for a comparison.) Nevertheless, each performs the same fundamental task&mdash;mapping between .NET objects and XML Infosets.</div>
<span>
<div class="MTPS_CollapsibleRegion">
<div class="CollapseRegionLink" jquery1257516498270="3"><img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; vertical-align: middle; border-left-width: 0px" class="LibC_o" src="http://i.msdn.microsoft.com/Global/Images/clear.gif">  Figure 1 Comparing Serializers</div>
<div style="display: block" class="MTPS_CollapsibleSection"><br>
<table class="charttable FCK__ShowTableBorders">
    <tbody>
        <tr valign="top">
            <th>Feature</th>
            <th>XmlSerializer</th>
            <th>DataContractSerializer NetDataContractSerializer</th>
        </tr>
        <tr valign="top">
            <td>Explicitness</td>
            <td>Opt-out</td>
            <td>Opt-in *<br>
            Opt-out **</td>
        </tr>
        <tr valign="top">
            <td>Default mapping</td>
            <td>Public fields/props</td>
            <td>All [DataMember]s *<br>
            All fields **</td>
        </tr>
        <tr valign="top">
            <td>Attribute required</td>
            <td>No</td>
            <td>Yes</td>
        </tr>
        <tr valign="top">
            <td>Default order</td>
            <td>Same as class</td>
            <td>Alphabetical</td>
        </tr>
        <tr valign="top">
            <td>XML Schema</td>
            <td>Extensive</td>
            <td>Constrained</td>
        </tr>
        <tr valign="top">
            <td>Code generator</td>
            <td>Xsd.exe</td>
            <td>SvcUtil.exe</td>
        </tr>
        <tr valign="top">
            <td>Override</td>
            <td>IXmlSerializable</td>
            <td>ISerializable</td>
        </tr>
        <tr valign="top">
            <td>Type fidelity</td>
            <td>No</td>
            <td>NetDataContractSerializer</td>
        </tr>
        <tr valign="top">
            <td>Versioning support</td>
            <td>No</td>
            <td>Yes</td>
        </tr>
        <tr valign="top">
            <td>Initialization</td>
            <td>Constructor</td>
            <td>Callbacks</td>
        </tr>
        <tr valign="top">
            <td>Compatibility</td>
            <td>ASMX</td>
            <td>.NET Remoting</td>
        </tr>
        <tr valign="top">
            <td colspan="3">* Using [DataContract] ** Using [Serializable]</td>
        </tr>
    </tbody>
</table>
</div>
</div>
</span>
<div class="ArticleNormalPara">DataContractSerializer is the default and is always used unless specified otherwise. You can choose a different serializer by annotating the service contract with an attribute, as shown here: <span >
<div class="libCScode">
<div class="CodeSnippetTitleBar">
<div class="CodeDisplay"> </div>
<div class="CopyCodeButton"><a class="copyCode" title="复制代码" href=" :CopyCode( ctl00_MTCS_mainContentContainer_ctl05_code );">
<div style="border-right-width: 0px; width: auto; border-top-width: 0px; border-bottom-width: 0px; height: 9px; border-left-width: 0px" class="LibC_copy_off" align="center"> </div>
复制代码 </a></div>
</div>
<div style="background-color: #ddd" dir="ltr">
<pre style="word-wrap: break-word; word-break: break-all" class="libCScode" space="preserve">[XmlSerializerFormat]
[ServiceContract]
public interface IEchoService
{
    [DataContractFormat]
    [OperationContract]
    Person EchoPerson(Person person);

    [OperationContract]
    Address EchoAddress(Address address);

    [OperationContract]
    Phone EchoPhone(Phone phone);
}</pre>
</div>
</div>
</span></div>
<div class="ArticleNormalPara">In this example, [XmlSerializerFormat] specifies XmlSerializer as the default serializer for all methods on the contract. However, I've overridden the serializer on EchoPerson by annotating the method with [DataContractFormat]. There isn't an attribute for NetDataContractSerializer, but you can write a custom attribute to apply it in the same way as the others if needed. The serializer is considered part of the service contract because it directly impacts your code.</div>
<div class="ArticleNormalPara">Windows Communication Foundation also lets you specify the encoding to be used. Whereas serialization defines how .NET objects map to XML Infosets, the encoding defines how the XML Infoset is written out to a stream of bytes. Windows Communication Foundation currently supports the following encodings: text, binary, and Message Transmission Optimization Mechanism (MTOM). However, more encodings, including your own custom encodings, could be added down the road.</div>
<div class="ArticleNormalPara">If you use each of the three encodings to write out the same XML Infoset, you'll get three very different byte streams, but they'll all represent the same logical data. The encoding isn't considered part of the service contract, but rather a configuration detail since it doesn't impact your code&mdash;you control the encoding by configuring the endpoint's binding.</div>
<div class="ArticleNormalPara">The separation of serialization from encoding makes it possible to build your applications on a consistent data model (the XML Infoset) while providing flexibility in representation (the encoding). This is a key feature when applying Windows Communication Foundation to a variety of real-world scenarios. If you care about interoperability, you can choose to use the text encoding. When performance is more of a concern, you can choose to use the binary encoding. In either case, the encoding choice is decoupled from the serialization mechanism.</div>
<div class="ArticleNormalPara">At first, Windows Communication Foundation serialization might remind you of ASMX. Once you start to peel off the layers, however, you'll see an amazing world of new possibilities.</div> <a href="http://hi.baidu.com/coollzh/blog/item/1559d7eca09ec63727979122.html">阅读全文</a>
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/coollzh/blog/category/wcf%26%2347%3Brest">wcf&#47;rest</a>&nbsp;<a href="http://hi.baidu.com/coollzh/blog/item/1559d7eca09ec63727979122.html#comment">查看评论</a>]]></description>
        <pubDate>2009-11-06  22:23</pubDate>
        <category><![CDATA[wcf&#47;rest]]></category>
        <author><![CDATA[coollzh]]></author>
		<guid>http://hi.baidu.com/coollzh/blog/item/1559d7eca09ec63727979122.html</guid>
</item>

<item>
        <title><![CDATA[说是不错源代码分析工具]]></title>
        <link><![CDATA[http://hi.baidu.com/coollzh/blog/item/88e5f04436216746500ffedf.html]]></link>
        <description><![CDATA[
		
		<a href="http://www.klocwork.com/">http://www.klocwork.com/</a> 
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/coollzh/blog/category/%C8%ED%BC%FE%B9%FD%B3%CC">软件过程</a>&nbsp;<a href="http://hi.baidu.com/coollzh/blog/item/88e5f04436216746500ffedf.html#comment">查看评论</a>]]></description>
        <pubDate>2009-10-29  00:38</pubDate>
        <category><![CDATA[软件过程]]></category>
        <author><![CDATA[coollzh]]></author>
		<guid>http://hi.baidu.com/coollzh/blog/item/88e5f04436216746500ffedf.html</guid>
</item>

<item>
        <title><![CDATA[Groovy Modules 汇总]]></title>
        <link><![CDATA[http://hi.baidu.com/coollzh/blog/item/63c7e7ef4c7cc7e5cf1b3eff.html]]></link>
        <description><![CDATA[
		
		following modules and contributions are currently available:
<ul>
    <li><a title="GMaven" href="http://docs.codehaus.org/display/GROOVY/GMaven">GMaven</a></li>
    <li><a title="Groovy Transforms" href="http://docs.codehaus.org/display/GROOVY/Groovy+Transforms">Groovy Transforms</a> &mdash; <span class="smalltext">Provides additional <a class="external-link" href="http://groovy.codehaus.org/Compile-time+Metaprogramming+-+AST+Transformations" rel="nofollow">AST Transformations</a></span></li>
    <li><a title="COM Scripting" href="http://docs.codehaus.org/display/GROOVY/COM+Scripting">COM Scripting</a> &mdash; <span class="smalltext">script Windows ActiveX and COM components with Groovy</span></li>
    <li><a title="Gant" href="http://docs.codehaus.org/display/GROOVY/Gant">Gant</a></li>
    <li><a title="GFreeMarker" href="http://docs.codehaus.org/display/GROOVY/GFreeMarker">GFreeMarker</a> &mdash; <span class="smalltext">an integration of the FreeMarker template engine for Groovy</span></li>
    <li><a title="Google Data Support" href="http://docs.codehaus.org/display/GROOVY/Google+Data+Support">Google Data Support</a> &mdash; <span class="smalltext">makes using the Google Data APIs easier from within Groovy</span></li>
    <li><a title="Gram" href="http://docs.codehaus.org/display/GROOVY/Gram">Gram</a> &mdash; <span class="smalltext">a simple xdoclet-like tool for processing doclet tags or Java 5 annotations</span></li>
    <li><a title="GraphicsBuilder" href="http://docs.codehaus.org/display/GROOVY/GraphicsBuilder">GraphicsBuilder</a> &mdash; <span class="smalltext">GraphicsBuilder is a Groovy builder for Java 2D</span></li>
    <li><a title="Grapplet" href="http://docs.codehaus.org/display/GROOVY/Grapplet">Grapplet</a></li>
    <li><a title="Griffon" href="http://docs.codehaus.org/display/GROOVY/Griffon">Griffon</a> &mdash; <span class="smalltext">Dekstop Enhancements for Groovy</span></li>
    <li><a title="Groosh" href="http://docs.codehaus.org/display/GROOVY/Groosh">Groosh</a> &mdash; <span class="smalltext">Provides a shell-like capability for handling external processes.</span></li>
    <li><a title="Groovy Jabber-RPC" href="http://docs.codehaus.org/display/GROOVY/Groovy+Jabber-RPC">Groovy Jabber-RPC</a> &mdash; <span class="smalltext">allows you to make XML-RPC calls using the Jabber protocol</span></li>
    <li><a title="GroovyJMS" href="http://docs.codehaus.org/display/GROOVY/GroovyJMS">GroovyJMS</a></li>
    <li><a title="GroovyLab" href="http://docs.codehaus.org/display/GROOVY/GroovyLab">GroovyLab</a> &mdash; <span class="smalltext">Provides a domain specific language (DSL) for math engineering (matlab-like syntax).</span></li>
    <li><a title="Groovy Monkey" href="http://docs.codehaus.org/display/GROOVY/Groovy+Monkey">Groovy Monkey</a> &mdash; <span class="smalltext">is a dynamic scripting tool for the Eclipse Platform</span></li>
    <li><a title="GroovyRestlet" href="http://docs.codehaus.org/display/GROOVY/GroovyRestlet">GroovyRestlet</a> &mdash; <span class="smalltext">Groovy DSL for constructing Restlet application</span></li>
    <li><a title="Groovy Science" href="http://docs.codehaus.org/display/GROOVY/Groovy+Science">Groovy Science</a></li>
    <li><a title="Groovy SOAP" href="http://docs.codehaus.org/display/GROOVY/Groovy+SOAP">Groovy SOAP</a> &mdash; <span class="smalltext">create a SOAP server and make calls to remote SOAP servers using Groovy</span></li>
    <li><a title="GroovySWT" href="http://docs.codehaus.org/display/GROOVY/GroovySWT">GroovySWT</a> &mdash; <span class="smalltext">a wrapper around SWT, the eclipse Standard Widget Toolkit</span></li>
    <li><a title="GroovyWS" href="http://docs.codehaus.org/display/GROOVY/GroovyWS">GroovyWS</a> &mdash; <span class="smalltext">GroovySOAP replacement that uses CXF and Java5 features</span></li>
    <li><a title="GSP" href="http://docs.codehaus.org/display/GROOVY/GSP">GSP</a> &mdash; <span class="smalltext">means GroovyServer Pages, which is similar to JSP (JavaServer Pages)</span></li>
    <li><a title="GSQL" href="http://docs.codehaus.org/display/GROOVY/GSQL">GSQL</a> &mdash; <span class="smalltext">supports easier access to databases using Groovy</span></li>
    <li><a title="HTTP Builder" href="http://docs.codehaus.org/display/GROOVY/HTTP+Builder">HTTP Builder</a> &mdash; <span class="smalltext">provides a convenient builder API for complex HTTP requests</span></li>
    <li><a title="JideBuilder" href="http://docs.codehaus.org/display/GROOVY/JideBuilder">JideBuilder</a> &mdash; <span class="smalltext">JideBuilder is a Groovy builder for the open source <a class="external-link" href="http://jide-oss.dev.java.net/" rel="nofollow">JIDE Common Layer</a></span></li>
    <li><a title="MetaBuilder" href="http://docs.codehaus.org/display/GROOVY/MetaBuilder">MetaBuilder</a> &mdash; <span class="smalltext">MetaBuilder is a builder that builds builders.</span></li>
    <li><a title="Native Launcher" href="http://docs.codehaus.org/display/GROOVY/Native+Launcher">Native Launcher</a> &mdash; <span class="smalltext">a native program for launching groovy scripts</span></li>
    <li><a title="Proxy-o-Matic" href="http://docs.codehaus.org/display/GROOVY/Proxy-o-Matic">Proxy-o-Matic</a> &mdash; <span class="smalltext">Proxy-o-Matic lets you create dynamic proxies fast and in an homogeneous way</span></li>
    <li><a title="Windows NSIS-Installer" href="http://docs.codehaus.org/display/GROOVY/Windows+NSIS-Installer">Windows NSIS-Installer</a> &mdash; <span class="smalltext">a Windows-specific installer for Groovy</span></li>
    <li><a title="Windows Services" href="http://docs.codehaus.org/display/GROOVY/Windows+Services">Windows Services</a> &mdash; <span class="smalltext">framework for Groovy-based WinNT (Windows) Services</span></li>
    <li><a title="WingSBuilder" href="http://docs.codehaus.org/display/GROOVY/WingSBuilder">WingSBuilder</a> &mdash; <span class="smalltext">WingsBuilder is a Groovy builder for the <a class="external-link" href="http://wingsframework.org/" rel="nofollow">wingS Framework</a></span></li>
    <li><a title="XMLRPC" href="http://docs.codehaus.org/display/GROOVY/XMLRPC">XMLRPC</a> &mdash; <span class="smalltext">allows you to create a local XML-RPC server and/or to make calls on remote XML-RPC servers</span></li>
</ul>
<ul>
    <li><a class="external-link" href="http://grails.codehaus.org/" rel="nofollow">Grails</a> &mdash; <font color="#666666">a Groovy-based web framework inspired by Ruby on Rails</font></li>
    <li><a class="external-link" href="http://grails.codehaus.org/GORM" rel="nofollow">GORM</a> &mdash; <font color="#666666">the Grails Object-Relational Mapping persistence framework</font></li>
    <li><a class="external-link" href="http://griffon.codehaus.org/" rel="nofollow">Griffon</a> &mdash; <font color="#666666">a Groovy-based desktop framework inspired by Grails</font></li>
    <li><a class="external-link" href="http://www.jspwiki.org/wiki/GroovyPlugin" rel="nofollow">GroovyPlugin</a> &mdash; <font color="#666666">A Groovy plugin for JSPWiki</font></li>
    <li><a class="external-link" href="http://code.google.com/p/ocmgroovy" rel="nofollow">OCM Groovy</a> &mdash; <font color="#666666">A Object Content Mapping implemented in Groovy leveraging the Java Content Repository (JCR)</font></li>
    <li><a class="external-link" title="The Tellurium Automated Testing Framework" href="http://code.google.com/p/aost" rel="nofollow">Tellurium</a> &mdash; A test framework built on top of the Selenium test framework implemented in Groovy</li>
    <li><a class="external-link" title="Gradle is a build system" href="http://www.gradle.org/index.php" rel="nofollow">Gradle</a> &mdash; The next generation build system</li>
</ul>
<fieldset class="hidden parameters"><legend>Labels parameters</legend>          </fieldset>
<div class="pageSection">
<div class="section-header">
<h2 class="section-title  hidden ">Labels</h2>
</div>
<div class="labels-editor">
<div > </div>

</div>
</div>
<div class="pageSection">
<div class="section-header ">
<h2 class="section-title"><a name="children">Children (31)</a></h2>
<span class="noprint">  <a class="grey" href="http://docs.codehaus.org/display/GROOVY/Modules?showChildren=false#children">Hide Children</a>  |  <a class="grey" href="http://docs.codehaus.org/pages/listpages-dirview.action?key=GROOVY&amp;openId=58054#selectedPageInHierarchy">View in Hierarchy</a> </span></div>
<div class="pageSectionBody"><img title="GMaven" border="0" align="absMiddle" src="http://docs.codehaus.org/s/1634/11/_/images/icons/docs_16.gif" width="16" height="16"> <a href="http://docs.codehaus.org/display/GROOVY/GMaven">GMaven</a> <br>
<img title="Groovy Transforms" border="0" align="absMiddle" src="http://docs.codehaus.org/s/1634/11/_/images/icons/docs_16.gif" width="16" height="16"> <a href="http://docs.codehaus.org/display/GROOVY/Groovy+Transforms">Groovy Transforms</a> <br>
<img title="COM Scripting" border="0" align="absMiddle" src="http://docs.codehaus.org/s/1634/11/_/images/icons/docs_16.gif" width="16" height="16"> <a href="http://docs.codehaus.org/display/GROOVY/COM+Scripting">COM Scripting</a> <br>
<img title="Gant" border="0" align="absMiddle" src="http://docs.codehaus.org/s/1634/11/_/images/icons/docs_16.gif" width="16" height="16"> <a href="http://docs.codehaus.org/display/GROOVY/Gant">Gant</a> <br>
<img title="GFreeMarker" border="0" align="absMiddle" src="http://docs.codehaus.org/s/1634/11/_/images/icons/docs_16.gif" width="16" height="16"> <a href="http://docs.codehaus.org/display/GROOVY/GFreeMarker">GFreeMarker</a> <br>
<img title="Google Data Support" border="0" align="absMiddle" src="http://docs.codehaus.org/s/1634/11/_/images/icons/docs_16.gif" width="16" height="16"> <a href="http://docs.codehaus.org/display/GROOVY/Google+Data+Support">Google Data Support</a> <br>
<img title="Gram" border="0" align="absMiddle" src="http://docs.codehaus.org/s/1634/11/_/images/icons/docs_16.gif" width="16" height="16"> <a href="http://docs.codehaus.org/display/GROOVY/Gram">Gram</a> <br>
<img title="GraphicsBuilder" border="0" align="absMiddle" src="http://docs.codehaus.org/s/1634/11/_/images/icons/docs_16.gif" width="16" height="16"> <a href="http://docs.codehaus.org/display/GROOVY/GraphicsBuilder">GraphicsBuilder</a> <br>
<img title="Grapplet" border="0" align="absMiddle" src="http://docs.codehaus.org/s/1634/11/_/images/icons/docs_16.gif" width="16" height="16"> <a href="http://docs.codehaus.org/display/GROOVY/Grapplet">Grapplet</a> <br>
<img title="Griffon" border="0" align="absMiddle" src="http://docs.codehaus.org/s/1634/11/_/images/icons/docs_16.gif" width="16" height="16"> <a href="http://docs.codehaus.org/display/GROOVY/Griffon">Griffon</a> <br>
<img title="Groosh" border="0" align="absMiddle" src="http://docs.codehaus.org/s/1634/11/_/images/icons/docs_16.gif" width="16" height="16"> <a href="http://docs.codehaus.org/display/GROOVY/Groosh">Groosh</a> <br>
<img title="Groovy Jabber-RPC" border="0" align="absMiddle" src="http://docs.codehaus.org/s/1634/11/_/images/icons/docs_16.gif" width="16" height="16"> <a href="http://docs.codehaus.org/display/GROOVY/Groovy+Jabber-RPC">Groovy Jabber-RPC</a> <br>
<img title="GroovyJMS" border="0" align="absMiddle" src="http://docs.codehaus.org/s/1634/11/_/images/icons/docs_16.gif" width="16" height="16"> <a href="http://docs.codehaus.org/display/GROOVY/GroovyJMS">GroovyJMS</a> <br>
<img title="GroovyLab" border="0" align="absMiddle" src="http://docs.codehaus.org/s/1634/11/_/images/icons/docs_16.gif" width="16" height="16"> <a href="http://docs.codehaus.org/display/GROOVY/GroovyLab">GroovyLab</a> <br>
<img title="Groovy Monkey" border="0" align="absMiddle" src="http://docs.codehaus.org/s/1634/11/_/images/icons/docs_16.gif" width="16" height="16"> <a href="http://docs.codehaus.org/display/GROOVY/Groovy+Monkey">Groovy Monkey</a> <br>
<img title="GroovyRestlet" border="0" align="absMiddle" src="http://docs.codehaus.org/s/1634/11/_/images/icons/docs_16.gif" width="16" height="16"> <a href="http://docs.codehaus.org/display/GROOVY/GroovyRestlet">GroovyRestlet</a> <br>
<img title="Groovy Science" border="0" align="absMiddle" src="http://docs.codehaus.org/s/1634/11/_/images/icons/docs_16.gif" width="16" height="16"> <a href="http://docs.codehaus.org/display/GROOVY/Groovy+Science">Groovy Science</a> <br>
<img title="Groovy SOAP" border="0" align="absMiddle" src="http://docs.codehaus.org/s/1634/11/_/images/icons/docs_16.gif" width="16" height="16"> <a href="http://docs.codehaus.org/display/GROOVY/Groovy+SOAP">Groovy SOAP</a> <br>
<img title="GroovySWT" border="0" align="absMiddle" src="http://docs.codehaus.org/s/1634/11/_/images/icons/docs_16.gif" width="16" height="16"> <a href="http://docs.codehaus.org/display/GROOVY/GroovySWT">GroovySWT</a> <br>
<img title="GroovyWS" border="0" align="absMiddle" src="http://docs.codehaus.org/s/1634/11/_/images/icons/docs_16.gif" width="16" height="16"> <a href="http://docs.codehaus.org/display/GROOVY/GroovyWS">GroovyWS</a> <br>
<img title="GSP" border="0" align="absMiddle" src="http://docs.codehaus.org/s/1634/11/_/images/icons/docs_16.gif" width="16" height="16"> <a href="http://docs.codehaus.org/display/GROOVY/GSP">GSP</a> <br>
<img title="GSQL" border="0" align="absMiddle" src="http://docs.codehaus.org/s/1634/11/_/images/icons/docs_16.gif" width="16" height="16"> <a href="http://docs.codehaus.org/display/GROOVY/GSQL">GSQL</a> <br>
<img title="HTTP Builder" border="0" align="absMiddle" src="http://docs.codehaus.org/s/1634/11/_/images/icons/docs_16.gif" width="16" height="16"> <a href="http://docs.codehaus.org/display/GROOVY/HTTP+Builder">HTTP Builder</a> <br>
<img title="JideBuilder" border="0" align="absMiddle" src="http://docs.codehaus.org/s/1634/11/_/images/icons/docs_16.gif" width="16" height="16"> <a href="http://docs.codehaus.org/display/GROOVY/JideBuilder">JideBuilder</a> <br>
<img title="MetaBuilder" border="0" align="absMiddle" src="http://docs.codehaus.org/s/1634/11/_/images/icons/docs_16.gif" width="16" height="16"> <a href="http://docs.codehaus.org/display/GROOVY/MetaBuilder">MetaBuilder</a> <br>
<img title="Native Launcher" border="0" align="absMiddle" src="http://docs.codehaus.org/s/1634/11/_/images/icons/docs_16.gif" width="16" height="16"> <a href="http://docs.codehaus.org/display/GROOVY/Native+Launcher">Native Launcher</a> <br>
<img title="Proxy-o-Matic" border="0" align="absMiddle" src="http://docs.codehaus.org/s/1634/11/_/images/icons/docs_16.gif" width="16" height="16"> <a href="http://docs.codehaus.org/display/GROOVY/Proxy-o-Matic">Proxy-o-Matic</a> <br>
<img title="Windows NSIS-Installer" border="0" align="absMiddle" src="http://docs.codehaus.org/s/1634/11/_/images/icons/docs_16.gif" width="16" height="16"> <a href="http://docs.codehaus.org/display/GROOVY/Windows+NSIS-Installer">Windows NSIS-Installer</a> <br>
<img title="Windows Services" border="0" align="absMiddle" src="http://docs.codehaus.org/s/1634/11/_/images/icons/docs_16.gif" width="16" height="16"> <a href="http://docs.codehaus.org/display/GROOVY/Windows+Services">Windows Services</a> <br>
<img title="WingSBuilder" border="0" align="absMiddle" src="http://docs.codehaus.org/s/1634/11/_/images/icons/docs_16.gif" width="16" height="16"> <a href="http://docs.codehaus.org/display/GROOVY/WingSBuilder">WingSBuilder</a> <br>
<img title="XMLRPC" border="0" align="absMiddle" src="http://docs.codehaus.org/s/1634/11/_/images/icons/docs_16.gif" width="16" height="16"> <a href="http://docs.codehaus.org/display/GROOVY/XMLRPC">XMLRPC</a></div>
</div>

<div class="pageSection"> </div>
<br class="clear"> <a href="http://hi.baidu.com/coollzh/blog/item/63c7e7ef4c7cc7e5cf1b3eff.html">阅读全文</a>
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/coollzh/blog/category/Groovy">Groovy</a>&nbsp;<a href="http://hi.baidu.com/coollzh/blog/item/63c7e7ef4c7cc7e5cf1b3eff.html#comment">查看评论</a>]]></description>
        <pubDate>2009-10-18  14:42</pubDate>
        <category><![CDATA[Groovy]]></category>
        <author><![CDATA[coollzh]]></author>
		<guid>http://hi.baidu.com/coollzh/blog/item/63c7e7ef4c7cc7e5cf1b3eff.html</guid>
</item>

<item>
        <title><![CDATA[Groovy资源汇总]]></title>
        <link><![CDATA[http://hi.baidu.com/coollzh/blog/item/2592da344426d2bdd1a2d3e1.html]]></link>
        <description><![CDATA[
		
		<table class="FCK__ShowTableBorders" border="0" width="100%">
    <tbody>
        <tr>
            <td bgcolor="#f1efe2" colspan="2"><span style="color: rgb(160,82,45)"><strong>推荐文章</strong> </span></td>
        </tr>
        <tr>
            <td bgcolor="#d9e7f0" valign="top" width="50%"><span style="color: rgb(22,56,124)">Groovy简介</span></td>
            <td bgcolor="#d9e7f0" valign="top" width="50%"><span style="color: rgb(22,56,124)">Groovy解惑系列</span></td>
        </tr>
        <tr>
            <td valign="top" width="50%"><a href="http://www.blogjava.net/BlueSUN/archive/2007/03/03/101562.html" set="yes"><font color="#1a8bc8"><strong>Java帝国的王储&mdash;&mdash;Groovy !</strong> </font></a><br>
            <a href="http://www.blogjava.net/BlueSUN/archive/2007/04/28/114224.html"><font color="#1a8bc8"><strong>Groovy, 一个富有创造性且革新的工程</strong> </font></a><br>
            <a href="http://www.blogjava.net/BlueSUN/archive/2007/04/17/111394.html" set="yes"><font color="#1a8bc8"><strong>Groovy与Grails同甘共苦，苦尽甘来</strong> </font></a></td>
            <td valign="top" width="50%"><strong><a href="http://www.blogjava.net/BlueSUN/archive/2007/12/22/169580.html"><font color="#1a8bc8">Groovy解惑&mdash;&mdash;closure中的delegate</font></a> </strong><br>
            <strong><a href="http://www.blogjava.net/BlueSUN/archive/2007/12/23/169683.html"><font color="#1a8bc8">Groovy解惑&mdash;&mdash;closure中的owner</font></a> </strong></td>
        </tr>
        <tr>
            <td bgcolor="#d9e7f0" valign="top" width="50%"><span style="color: rgb(22,56,124)">Groovy轻松入门系列</span></td>
            <td bgcolor="#d9e7f0" valign="top" width="50%"><span style="color: rgb(22,56,124)">Groovy高效编程系列</span></td>
        </tr>
        <tr>
            <td valign="top" width="50%"><a href="http://www.blogjava.net/BlueSUN/archive/2007/03/17/104391.html" set="yes"><font color="#1a8bc8"><strong>Groovy轻松入门&mdash;&mdash;搭建Groovy开发环境</strong> </font></a><br>
            <a href="http://www.blogjava.net/BlueSUN/archive/2007/03/10/103014.html"></a><strong><a href="http://www.blogjava.net/BlueSUN/archive/2007/03/10/103014.html"><font color="#1a8bc8">Groovy轻松入门&mdash;&mdash;通过与Java的比较，迅速掌握Groovy</font></a> </strong><br>
            <a href="http://www.blogjava.net/BlueSUN/archive/2007/03/21/105113.html" set="yes"><font color="#1a8bc8"><strong>Groovy轻松入门&mdash;&mdash;Grails实战基础篇</strong> </font></a><br>
            <a href="http://www.blogjava.net/BlueSUN/archive/2007/04/05/108689.html" set="yes"><font color="#1a8bc8"><strong>Groovy轻松入门&mdash;&mdash;Grails实战之GORM篇</strong> </font></a><br>
            <a href="http://www.blogjava.net/BlueSUN/archive/2007/05/11/116851.html"><font color="#1a8bc8"><strong>Groovy轻松入门&mdash;&mdash;Grails实战之Ajax篇</strong> </font></a><br>
            <a href="http://www.blogjava.net/BlueSUN/archive/2007/06/06/122434.html"><font color="#1a8bc8"><strong>Groovy轻松入门&mdash;&mdash;Grails实战之遗留数据库处理篇</strong> </font></a><br>
            <strong><a href="http://www.blogjava.net/BlueSUN/archive/2007/06/22/125921.html"><font color="#1a8bc8">Groovy轻松入门&mdash;&mdash;Grails实战之遗留框架利用篇</font></a> <br>
            <a href="http://www.blogjava.net/BlueSUN/archive/2007/09/08/143544.html"><font color="#1a8bc8">Groovy轻松入门&mdash;&mdash;Grails实战之Web Flow篇</font></a> <br>
            <a href="http://www.blogjava.net/BlueSUN/archive/2008/04/04/190735.html"><font color="#1a8bc8">Groovy轻松入门&mdash;&mdash;Grails实战之GORM DSL篇</font></a> </strong></td>
            <td valign="top" width="50%"><strong><a href="http://www.blogjava.net/BlueSUN/archive/2007/02/01/97389.html"><strong><font color="#1a8bc8">Groovy高效编程&mdash;&mdash;统计单词频率 </font></strong></a><br>
            </strong><strong><a href="http://www.blogjava.net/BlueSUN/archive/2007/05/30/120968.html"><font color="#1a8bc8">Groovy高效编程&mdash;&mdash;生成XML文件</font></a> <br>
            <a href="http://www.blogjava.net/BlueSUN/archive/2007/08/18/137770.html"><font color="#1a8bc8">Groovy高效编程&mdash;&mdash;生成较为复杂的XML文件</font></a> </strong><br>
            <strong><a href="http://www.blogjava.net/BlueSUN/archive/2007/06/15/124567.html"><font color="#1a8bc8">Groovy高效编程&mdash;&mdash;用Groovy轻松搞定SOAP消息</font></a> <br>
            <a href="http://www.blogjava.net/BlueSUN/archive/2007/07/15/130318.html"><font color="#1a8bc8">Groovy高效编程&mdash;&mdash;动态改变对象的能力</font></a> <br>
            <a href="http://www.blogjava.net/BlueSUN/archive/2007/08/05/134539.html"><font color="#1a8bc8">Groovy高效编程&mdash;&mdash;利用SwingBuilder轻松构造GUI</font></a> <br>
            <a href="http://www.blogjava.net/BlueSUN/archive/2007/08/26/139460.html"><font color="#1a8bc8">Groovy高效编程&mdash;&mdash;&lsquo;匕首方法&rsquo;的使用</font></a> <br>
            <a href="http://www.blogjava.net/BlueSUN/archive/2007/11/04/158028.html"><font color="#1a8bc8">Groovy高效编程&mdash;&mdash;用Closure替代匿名类</font></a> <br>
            <a href="http://www.blogjava.net/BlueSUN/archive/2007/11/11/159766.html"><font color="#1a8bc8">Groovy高效编程&mdash;&mdash;Annotations的使用</font></a> <br>
            <a href="http://www.blogjava.net/BlueSUN/archive/2007/11/27/163561.html"><font color="#1a8bc8">Groovy高效编程&mdash;&mdash;Mixin的使用</font></a> <br>
            <a href="http://www.blogjava.net/BlueSUN/archive/2008/01/26/177945.html"><font color="#1a8bc8">Groovy高效编程&mdash;&mdash;生成Oracle表结构信息文档</font></a> </strong><br>
            <strong><a href="http://www.blogjava.net/BlueSUN/archive/2008/02/16/180202.html"><font color="#1a8bc8">Groovy高效编程&mdash;&mdash;用Gant替代Ant</font></a> <br>
            </strong><strong><a class="postTitle2" href="http://www.blogjava.net/BlueSUN/archive/2008/05/03/197895.html"><font color="#1a8bc8">Groovy高效编程&mdash;&mdash;@Bindable的使用</font></a> <br>
            <a class="postTitle2" href="http://www.blogjava.net/BlueSUN/archive/2008/05/17/201026.html"><font color="#1a8bc8">Groovy高效编程&mdash;&mdash;创建DSL</font></a> <br>
            <a class="postTitle2" href="http://www.blogjava.net/BlueSUN/archive/2008/05/24/202609.html"><font color="#1a8bc8">Groovy高效编程&mdash;&mdash;DSL实战</font></a> </strong><br>
            <strong><a href="http://www.blogjava.net/BlueSUN/archive/2008/06/13/207775.html"><font color="#1a8bc8">Groovy高效编程&mdash;&mdash;使用Mock &amp; Stub简化测试</font></a> </strong><br>
            <strong><a class="postTitle2" href="http://www.blogjava.net/BlueSUN/archive/2008/06/19/209280.html"><font color="#1a8bc8">Groovy高效编程&mdash;&mdash;导出Oracle的package源码  </font></a></strong><br>
            <a href="http://www.blogjava.net/BlueSUN/archive/2009/04/02/263637.html"><font color="#1a8bc8"><strong>Groovy高效编程&mdash;&mdash;tree命令之Groovy实现</strong> </font></a></td>
        </tr>
        <tr>
            <td bgcolor="#d9e7f0" valign="top" width="50%"><span style="color: rgb(22,56,124)">Grails插件系列 </span></td>
            <td bgcolor="#d9e7f0" valign="top" width="50%"><span style="color: rgb(22,56,124)">Groovy &amp; Grails的FAQ </span></td>
        </tr>
        <tr>
            <td valign="top" width="50%"><strong><a href="http://www.blogjava.net/BlueSUN/archive/2008/03/30/189683.html"><font color="#1a8bc8">grails-cache插件&mdash;&mdash;简介</font></a> </strong></td>
            <td valign="top" width="50%"><a href="http://www.blogjava.net/BlueSUN/archive/2007/04/28/114378.html"><font color="#1a8bc8"><strong>FAQ &mdash;&mdash; Groovy &amp; Grails</strong> </font></a></td>
        </tr>
    </tbody>
</table>
<p> </p>
<table class="FCK__ShowTableBorders" border="0" width="100%">
    <tbody>
        <tr>
            <td bgcolor="#f1efe2" colspan="2"><span style="color: rgb(160,82,45)"><strong>其他文章</strong> </span></td>
        </tr>
        <tr>
            <td bgcolor="#d9e7f0" height="21" valign="top" width="50%"><span style="color: rgb(22,56,124)">Groovy</span></td>
            <td bgcolor="#d9e7f0" valign="top" width="50%"><span style="color: rgb(22,56,124)">Grails</span></td>
        </tr>
        <tr>
            <td height="44" valign="top" width="50%"><strong><a href="http://www.blogjava.net/BlueSUN/archive/2007/06/04/121956.html"><font color="#1a8bc8">出现在J2EE Developer应聘要求中的Groovy &amp; Grails</font></a> </strong><br>
            <a href="http://www.blogjava.net/BlueSUN/archive/2007/03/13/103614.html"><font color="#1a8bc8"><strong>2007年Groovy好事连连</strong> </font></a><br>
            <a href="http://www.blogjava.net/BlueSUN/archive/2007/01/24/95771.html"><strong><font color="#1a8bc8">Groovy的春天从Java7诞生那日开始 </font></strong></a><br>
            <a href="http://www.blogjava.net/BlueSUN/archive/2006/08/29/66421.html"><strong><font color="#1a8bc8">牛刀小试&mdash;&mdash;用Groovy实现最简单的ORM </font></strong></a><br>
            <strong><a class="postTitle2" href="http://www.blogjava.net/BlueSUN/archive/2008/04/20/194370.html"><font color="#1a8bc8">一道Google算法题的解答</font></a> <br>
            <a class="postTitle2" href="http://www.blogjava.net/BlueSUN/archive/2007/10/15/153099.html"><font color="#1a8bc8">改进Groovy Console&mdash;&mdash;添加行号</font></a> </strong><br>
            <strong><a class="postTitle2" href="http://www.blogjava.net/BlueSUN/archive/2008/05/13/200310.html"><font color="#1a8bc8">改进Groovy Console&mdash;&mdash;支持自动缩进</font></a> </strong></td>
            <td valign="top" width="50%"><a href="http://www.blogjava.net/BlueSUN/archive/2007/04/15/110733.html"><strong><font color="#1a8bc8">Grails的richTextEditor标签增强型(附效果图与patch) </font></strong></a><br>
            <a href="http://www.blogjava.net/BlueSUN/archive/2007/04/10/109537.html"><strong><font color="#1a8bc8">Grails的成功案例 </font></strong></a><br>
            <a href="http://www.blogjava.net/BlueSUN/archive/2007/03/24/106002.html"><strong><font color="#1a8bc8">测试表明：Grails的性能远胜于RoR(Ruby on Rails) </font></strong></a></td>
        </tr>
    </tbody>
</table>
<p> </p>
<table class="FCK__ShowTableBorders" border="0" width="100%">
    <tbody>
        <tr>
            <td bgcolor="#f1efe2" colspan="2"><span style="color: rgb(160,82,45)"><strong>转载文章</strong> </span></td>
        </tr>
        <tr>
            <td bgcolor="#d9e7f0" valign="top" width="50%"><span style="color: rgb(22,56,124)">Groovy</span></td>
            <td bgcolor="#d9e7f0" valign="top" width="50%"><span style="color: rgb(22,56,124)">Grails</span></td>
        </tr>
        <tr>
            <td valign="top" width="50%"><strong><a href="http://www.blogjava.net/BlueSUN/archive/2007/11/12/160058.html"><font color="#1a8bc8">[转载]Groovy学习之资料篇</font></a> </strong><br>
            <a href="http://www.blogjava.net/BlueSUN/archive/2007/05/13/117154.html"><strong><font color="#1a8bc8">[转载]在Groovy1.0中使用闭包和集合 </font></strong></a><br>
            <a href="http://www.blogjava.net/BlueSUN/archive/2007/04/28/114402.html"><strong><font color="#1a8bc8">[转载]Groovy running fine on .NET </font></strong></a><br>
            <a href="http://www.blogjava.net/BlueSUN/archive/2007/04/22/112823.html"><strong><font color="#1a8bc8">[转载]Groovy 集合 </font></strong></a><br>
            <a href="http://www.blogjava.net/BlueSUN/archive/2007/04/16/111071.html"><strong><font color="#1a8bc8">[转载]Who Is Using Groovy </font></strong></a><br>
            <a href="http://www.blogjava.net/BlueSUN/archive/2007/04/16/111070.html"><strong><font color="#1a8bc8">[转载]The Future of Groovy </font></strong></a><br>
            <a href="http://www.blogjava.net/BlueSUN/archive/2007/04/16/111068.html"><strong><font color="#1a8bc8">[转载]The JSR Venture </font></strong></a><br>
            <a href="http://www.blogjava.net/BlueSUN/archive/2007/04/16/111066.html"><strong><font color="#1a8bc8">[转载]Why Groovy? </font></strong></a><br>
            <a href="http://www.blogjava.net/BlueSUN/archive/2007/04/06/109041.html"><strong><font color="#1a8bc8">[转载]I'm digging Groovy and Grails </font></strong></a><br>
            <a href="http://www.blogjava.net/BlueSUN/archive/2007/04/04/108530.html"><strong><font color="#1a8bc8">[转载]JRuby, Groovy &amp; Java Integration </font></strong></a><br>
            <a href="http://www.blogjava.net/BlueSUN/archive/2007/04/02/107858.html"><strong><font color="#1a8bc8">[转载]安装Groovy的Eclipse插件 </font></strong></a><br>
            <a href="http://www.blogjava.net/BlueSUN/archive/2007/03/21/105369.html"><strong><font color="#1a8bc8">[转载]Groovy: The Sleeping Giant </font></strong></a></td>
            <td valign="top" width="50%"><strong><a href="http://www.blogjava.net/BlueSUN/archive/2008/02/11/179613.html"><font color="#1a8bc8">[转载]Grails 1.0 Released: Productive Web App Development on the JVM</font></a> </strong><br>
            <strong><a href="http://www.blogjava.net/BlueSUN/archive/2007/10/13/152546.html"><font color="#1a8bc8">[转载]Composition on Rails: The Groovy Side of SAP NetWeaver</font></a> </strong><br>
            <strong><a href="http://www.blogjava.net/BlueSUN/archive/2007/07/14/130260.html"><font color="#1a8bc8">[转载]对Grails之误解</font></a> </strong><br>
            <strong><a href="http://www.blogjava.net/BlueSUN/archive/2007/07/07/128828.html"><font color="#1a8bc8">[转载]10 Common Misconceptions about Grails</font></a> </strong><br>
            <strong><a href="http://www.blogjava.net/BlueSUN/archive/2007/06/28/126690.html"><font color="#1a8bc8">[转载]让Grails + MySQL正确处理中文</font></a> </strong><br>
            <strong><a href="http://www.blogjava.net/BlueSUN/archive/2007/06/04/121971.html"><font color="#1a8bc8">[转载]grails调用存储过程（Grails : calling a stored procedure）</font></a> </strong><br>
            <a href="http://www.blogjava.net/BlueSUN/archive/2007/05/02/115030.html"><strong><font color="#1a8bc8">[转载]Grails Gathers Steam, Heads for 1.0 </font></strong></a><br>
            <a href="http://www.blogjava.net/BlueSUN/archive/2007/05/01/114892.html"><strong><font color="#1a8bc8">[转载]Ruby on Grails? Why the hell not? </font></strong></a><br>
            <a href="http://www.blogjava.net/BlueSUN/archive/2007/05/01/114891.html"><font color="#1a8bc8"><strong>[转载]The Charles Nutter Ruby on Grails story</strong> </font></a><br>
            <a href="http://www.blogjava.net/BlueSUN/archive/2007/04/23/112846.html"><font color="#1a8bc8"><strong>[转载]Grails生成DECIMAL(NUMERIC)类型字段</strong> </font></a><br>
            <a href="http://www.blogjava.net/BlueSUN/archive/2007/04/22/112825.html"><font color="#1a8bc8"><strong>[转载]如何在eclipse下调试grails</strong> </font></a><br>
            <a href="http://www.blogjava.net/BlueSUN/archive/2007/04/22/112824.html"><font color="#1a8bc8"><strong>[转载]Grails + EJB Domain Models</strong> </font></a><br>
            <a href="http://www.blogjava.net/BlueSUN/archive/2007/04/22/112822.html"><font color="#1a8bc8"><strong>[转载]Grails</strong> </font></a><br>
            <a href="http://www.blogjava.net/BlueSUN/archive/2007/04/22/112819.html"><font color="#1a8bc8"><strong>[转载]Groovy on rails使用</strong> </font></a><br>
            <a href="http://www.blogjava.net/BlueSUN/archive/2007/04/22/112817.html"><font color="#1a8bc8"><strong>[转载]Grails快速入门（Quick Start）</strong> </font></a><br>
            <a href="http://www.blogjava.net/BlueSUN/archive/2007/04/22/112814.html"><font color="#1a8bc8"><strong>[转载]安装Grails</strong> </font></a><br>
            <a href="http://www.blogjava.net/BlueSUN/archive/2007/04/22/112645.html"><font color="#1a8bc8"><strong>[转载]Grails Is on the Move</strong> </font></a><br>
            <a href="http://www.blogjava.net/BlueSUN/archive/2007/04/19/111814.html"><font color="#1a8bc8"><strong>[转载]Contrasting Grails SpringBuilder vs JRuby Spring DSL vs Guice</strong> </font></a><br>
            <a href="http://www.blogjava.net/BlueSUN/archive/2007/04/07/109105.html"><font color="#1a8bc8"><strong>[转载]Oracle 6月已经加入Grails开源计划</strong> </font></a><br>
            <a href="http://www.blogjava.net/BlueSUN/archive/2007/04/03/108225.html"><font color="#1a8bc8"><strong>[转载]面向 Java 开发人员的 Grails on Oracle</strong> </font></a></td>
        </tr>
    </tbody>
</table>
<p> </p>
<table class="FCK__ShowTableBorders" border="0" width="100%">
    <tbody>
        <tr>
            <td bgcolor="#f1efe2" colspan="3"><span style="color: rgb(160,82,45)"><strong>资源</strong> </span></td>
        </tr>
        <tr>
            <td bgcolor="#d9e7f0" width="33%"><span style="color: rgb(22,56,124)">技术图书</span></td>
            <td bgcolor="#d9e7f0" width="33%"><span style="color: rgb(22,56,124)">开发工具</span></td>
            <td bgcolor="#d9e7f0"><span style="color: rgb(22,56,124)">QQ群</span></td>
        </tr>
        <tr>
            <td height="21" valign="top" width="33%"><strong><a href="http://www.blogjava.net/BlueSUN/archive/2007/11/07/158940.html"><font color="#1a8bc8">Groovy &amp; Grails技术图书</font></a> <br>
            <a href="http://grails.org/doc/"><font color="#1a8bc8">Grails User Guide</font></a> <br>
            <a href="http://www.chinagroovy.org/grails-doc/index.html"><font color="#1a8bc8">Grails中文参考手册</font></a> <br>
            </strong></td>
            <td valign="top" width="33%"><strong><a href="http://www.blogjava.net/BlueSUN/archive/2007/10/21/154657.html"><font color="#1a8bc8">Groovy &amp; Grails开发利器</font></a> </strong></td>
            <td valign="top">17397986, 12110478, 50858584</td>
        </tr>
    </tbody>
</table>
<p> </p>
<table class="FCK__ShowTableBorders" border="0" width="100%">
    <tbody>
        <tr>
            <td bgcolor="#f1efe2"><span style="color: rgb(160,82,45)"><strong>友情链接</strong> </span></td>
        </tr>
        <tr>
            <td><strong><a href="http://www.chinagroovy.org/forum/index.php"><font color="#1a8bc8">Groovy中文论坛</font></a> </strong><br>
            <strong><a href="http://www.groovycn.cn/"><font color="#1a8bc8">Groovy中国</font></a> </strong><br>
            <strong><a href="http://grails.group.javaeye.com/"><font color="#1a8bc8">Groovy on Grails圈子</font></a> </strong></td>
        </tr>
    </tbody>
</table> <a href="http://hi.baidu.com/coollzh/blog/item/2592da344426d2bdd1a2d3e1.html">阅读全文</a>
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/coollzh/blog/category/Groovy">Groovy</a>&nbsp;<a href="http://hi.baidu.com/coollzh/blog/item/2592da344426d2bdd1a2d3e1.html#comment">查看评论</a>]]></description>
        <pubDate>2009-10-18  14:16</pubDate>
        <category><![CDATA[Groovy]]></category>
        <author><![CDATA[coollzh]]></author>
		<guid>http://hi.baidu.com/coollzh/blog/item/2592da344426d2bdd1a2d3e1.html</guid>
</item>

<item>
        <title><![CDATA[Groovy的字符串操作]]></title>
        <link><![CDATA[http://hi.baidu.com/coollzh/blog/item/0f02c41c447dfe8186d6b63a.html]]></link>
        <description><![CDATA[
		
		<p>We can pad and center strings:</p>
<div style="border-right-width: 1px; border-top-width: 1px; border-bottom-width: 1px; border-left-width: 1px" class="code panel">
<div class="codeContent panelContent">
<pre class="code-java"><span class="code-keyword">assert</span> 'hello'.padRight(8,'+').padLeft(10,'+') == '++hello+++'
<span class="code-keyword">assert</span> 'hello'.padLeft(7).padRight(10) == '  hello   '
<span class="code-keyword">assert</span> 'hello'.center(10, '+').center(14, ' ') == '  ++hello+++  '</pre>
</div>
</div>
<p>We can split a string into tokens:</p>
<div style="border-right-width: 1px; border-top-width: 1px; border-bottom-width: 1px; border-left-width: 1px" class="code panel">
<div class="codeContent panelContent">
<pre class="code-java"><span class="code-keyword">assert</span> 'he she\t it'.tokenize() == ['he', 'she', 'it']
    <span class="code-comment">//tokens <span class="code-keyword">for</span> split are ' \t\n\r\f'
</span><span class="code-keyword">assert</span> 'he she\t it'.tokenize() ==
    <span class="code-keyword">new</span> StringTokenizer('he she\t it').collect{ it }

<span class="code-keyword">assert</span> 'he,she;it,;they'.tokenize(',;') == ['he', 'she', 'it', 'they']
    <span class="code-comment">//supply our own tokens
</span><span class="code-keyword">assert</span> <span class="code-keyword">new</span> StringTokenizer('he,she;it,;they', ',;').collect{ it } ==
    'he,she;it,;they'.tokenize(',;')

<span class="code-keyword">assert</span> <span class="code-keyword">new</span> StringTokenizer('he,she,;it', ',;', <span class="code-keyword">true</span>).collect{ it } ==
    ['he', ',', 'she', ',', ';', 'it']
  <span class="code-comment">//<span class="code-object">long</span> form provides extra option to <span class="code-keyword">return</span> the tokens with the split-up data</span></pre>
</div>
</div>
<p>Some additional methods:</p>
<div style="border-right-width: 1px; border-top-width: 1px; border-bottom-width: 1px; border-left-width: 1px" class="code panel">
<div class="codeContent panelContent">
<pre class="code-java"><span class="code-keyword">assert</span> 'abcde'.find{ it &gt; 'b' } == 'c' <span class="code-comment">//first one found
</span><span class="code-keyword">assert</span> 'abcde'.findAll{ it &gt; 'b' } == ['c', 'd', 'e'] <span class="code-comment">//all found
</span><span class="code-keyword">assert</span> 'abcde'.findIndexOf{ it &gt; 'c' } == 3 <span class="code-comment">//first one found
</span>
<span class="code-keyword">assert</span> 'abcde'.every{ it &lt; 'g' } &amp;&amp; ! 'abcde'.every{ it &lt; 'c' }
<span class="code-keyword">assert</span> 'abcde'.any{ it &gt; 'c' } &amp;&amp; ! 'abcde'.any{ it &gt; 'g' }

<span class="code-keyword">assert</span> 'morning'.replace('n','t') == 'mortitg' &amp;&amp;
       'boo'.replace('o', 'at') == 'batat' &amp;&amp;
       'book'.replace('oo','ie') == 'biek'

<span class="code-keyword">assert</span> 'EggS'.toLowerCase() == 'eggs' &amp;&amp; 'EggS'.toUpperCase() == 'EGGS'
<span class="code-keyword">assert</span> '   Bacon   '.trim() == 'Bacon'
<span class="code-keyword">assert</span> 'noodles'.startsWith('nood') &amp;&amp; 'noodles'.endsWith('dles')
<span class="code-keyword">assert</span> 'corn soup'.startsWith('rn', 2) <span class="code-comment">//2 is offset
</span>
<span class="code-keyword">assert</span> 'abc'.concat('def') == 'abcdef'
<span class="code-keyword">assert</span> 'abcdefg'.contains('def')
<span class="code-keyword">assert</span> ''.isEmpty() &amp;&amp; ! 'abc'.isEmpty()

<span class="code-keyword">assert</span> 'morning'.indexOf('n') == 3
<span class="code-keyword">assert</span> 'morning'.indexOf('n', 4) == 5 <span class="code-comment">//ignore first 4 characters
</span><span class="code-keyword">assert</span> 'morning'.indexOf('ni') == 3
<span class="code-keyword">assert</span> 'morning'.indexOf('ni', 4) == -1 <span class="code-comment">//not found
</span><span class="code-keyword">assert</span> 'morning'.lastIndexOf('n') == 5
<span class="code-keyword">assert</span> 'morning'.lastIndexOf('n', 4) == 3 <span class="code-comment">//only search first 4 characters
</span><span class="code-keyword">assert</span> 'morning'.lastIndexOf('ni') == 3
<span class="code-keyword">assert</span> 'morning'.lastIndexOf('ni', 4) == 3
    <span class="code-comment">//only search first 4 characters <span class="code-keyword">for</span> first <span class="code-object">char</span> of search string</span></pre>
</div>
</div>
<p>We can use operators on strings:</p>
<div style="border-right-width: 1px; border-top-width: 1px; border-bottom-width: 1px; border-left-width: 1px" class="code panel">
<div class="codeContent panelContent">
<pre class="code-java"><span class="code-keyword">assert</span> 'hello, ' + 'balloon' - 'lo' == 'hel, balloon'
    <span class="code-comment">//'-' subtracts one instance at most of string
</span><span class="code-keyword">assert</span> 'hello, balloon' - 'abc' == 'hello, balloon'
<span class="code-keyword">assert</span> 'hello, '.plus('balloon').minus('lo') == 'hel, balloon'
    <span class="code-comment">//alternative method syntax
</span><span class="code-keyword">assert</span> 'value is ' + <span class="code-keyword">true</span> == 'value is <span class="code-keyword">true</span>' &amp;&amp;
       'value is ' + 1.54d == 'value is 1.54' &amp;&amp;
            <span class="code-comment">//first converts <span class="code-object">double</span> to <span class="code-object">String</span> (without info loss)
</span>       'value is ' + 7 == 'value is 7' <span class="code-comment">//we can add on various types of values
</span><span class="code-keyword">assert</span> 7 + ' is value' == '7 is value'
<span class="code-keyword">assert</span> 'telling <span class="code-keyword">true</span> lies' - <span class="code-keyword">true</span> == 'telling  lies' &amp;&amp;
       'week has 7 days' - 7 == 'week has  days'
            <span class="code-comment">//we can subtract various types of values
</span><span class="code-keyword">assert</span> 'a' * 3 == 'aaa' &amp;&amp; 'a'.multiply(3) == 'aaa'

<span class="code-keyword">assert</span> 'hello'.reverse() == 'olleh'
<span class="code-keyword">assert</span> 'hello'.count('l') == 2

<span class="code-keyword">assert</span> 'abc'.collect{ it * 2 } == ['aa', 'bb', 'cc']
def s= [], t= [:]
'abc'.each{ s &lt;&lt; it }
'abc'.eachWithIndex{ elt, i-&gt; t[i]= elt }
<span class="code-keyword">assert</span> s == ['a', 'b', 'c'] &amp;&amp; t == [0:'a', 1:'b', 2:'c']
<span class="code-keyword">assert</span> 'abcde'.toList() == ['a', 'b', 'c', 'd', 'e']

<span class="code-keyword">assert</span> 'abc'.next() == 'abd' &amp;&amp; 'abc'.previous() == 'abb'</pre>
</div>
</div>
<p>We can subscript strings just as we can lists, except of course strings are read-only:</p>
<div style="border-right-width: 1px; border-top-width: 1px; border-bottom-width: 1px; border-left-width: 1px" class="code panel">
<div class="codeContent panelContent">
<pre class="code-java"><span class="code-keyword">assert</span> 'abcdefg'[ 3 ] == 'd'
<span class="code-keyword">assert</span> 'abcdefg'.getAt( 3 ) == 'd' <span class="code-comment">//equivalent method name
</span><span class="code-keyword">assert</span> 'abcdefg'.charAt( 3 ) == 'd' <span class="code-comment">//alternative method name
</span><span class="code-keyword">assert</span> 'abcdefg'[ 3..5 ] == 'def'
<span class="code-keyword">assert</span> 'abcdefg'.getAt( 3..5 ) == 'def'
<span class="code-keyword">assert</span> 'abcdefg'[ 1, 3, 5, 6 ] == 'bdfg'
<span class="code-keyword">assert</span> 'abcdefg'[ 1, *3..5 ] == 'bdef'
<span class="code-keyword">assert</span> 'abcdefg'[ 1, 3..5 ] == 'bdef'
    <span class="code-comment">//range in subscript flattened automatically
</span><span class="code-keyword">assert</span> 'abcdefg'[-5..-2] == 'cdef'
<span class="code-keyword">assert</span> 'abcdefg'.getAt( [ 1, *3..5 ] ) == 'bdef'
<span class="code-keyword">assert</span> 'abcdefg'.getAt( [ 1, 3..5 ] ) == 'bdef'

<span class="code-keyword">assert</span> 'abcde' == 'ab' + 'c' + 'de'
<span class="code-keyword">assert</span> 'abcde'.equals('ab' + 'c' + 'de') <span class="code-comment">//equivalent method name
</span><span class="code-keyword">assert</span> 'abcde'.contentEquals('ab' + 'c' + 'de') <span class="code-comment">//alternative method name
</span><span class="code-keyword">assert</span> 'AbcdE'.equalsIgnoreCase('aBCDe')
<span class="code-keyword">assert</span> 'abcde' &lt; 'abcdf' &amp;&amp; 'abcde' &lt; 'abcdef'
<span class="code-keyword">assert</span> 'abcde'.compareTo('abcdf') == -1 &amp;&amp; 'abcde'.compareTo('abcdef') == -1
                                                      <span class="code-comment">//equivalent method
</span><span class="code-keyword">assert</span> 'AbcdEF'.compareToIgnoreCase('aBCDe') == 1
<span class="code-keyword">assert</span> 'AbcdE'.compareToIgnoreCase('aBCDef') == -1

<span class="code-keyword">assert</span> Collections.max( 'abC'.toList(), <span class="code-object">String</span>.CASE_INSENSITIVE_ORDER ) == 'C'
<span class="code-keyword">assert</span> Collections.min(
            ['abC', 'ABd', 'AbCd'], <span class="code-object">String</span>.CASE_INSENSITIVE_ORDER ) == 'abC'

<span class="code-keyword">assert</span> 'abcde'.regionMatches(2, 'ccccd', 3, 2)
    <span class="code-comment">//match from index 2 in 'abcde' to 2 chars from index 3 in 'ccccd'
</span><span class="code-keyword">assert</span> 'abcDE'.regionMatches(<span class="code-keyword">true</span>, 2, 'CCCCd', 3, 2)
    <span class="code-comment">//<span class="code-keyword">if</span> first arg is <span class="code-keyword">true</span>, ignores <span class="code-keyword">case</span></span></pre>
</div>
</div>
<p>We can format values into a string, using format():</p>
<div style="border-right-width: 1px; border-top-width: 1px; border-bottom-width: 1px; border-left-width: 1px" class="code panel">
<div class="codeContent panelContent">
<pre class="code-java"><span class="code-comment">//Strings (conversion type 's')
</span><span class="code-keyword">assert</span> <span class="code-object">String</span>.format('%1$8s', 'hello') == '   hello'
    <span class="code-comment">//width (here, 8) is minimum characters to be written
</span><span class="code-keyword">assert</span> <span class="code-object">String</span>.format('%2$6s,%1$2s', 'a', 'hello') == ' hello, a'
    <span class="code-comment">//we can re-order arguments
</span><span class="code-keyword">assert</span> <span class="code-object">String</span>.format('%1$2s', 7, 'd') == ' 7'
    <span class="code-comment">//we can give any type of input; we can ignore arguments
</span><span class="code-keyword">assert</span> <span class="code-object">String</span>.format('%1s,%2s', <span class="code-keyword">null</span>, '<span class="code-keyword">null</span>') == '<span class="code-keyword">null</span>,<span class="code-keyword">null</span>'
    <span class="code-comment">//<span class="code-keyword">null</span> treated as '<span class="code-keyword">null</span>'
</span><span class="code-keyword">assert</span> <span class="code-object">String</span>.format('%1$2.4s', 'hello') == 'hell'
    <span class="code-comment">//precision (here, 4) is maximum characters to be written
</span>
<span class="code-comment">//Characters ('c')
</span><span class="code-keyword">assert</span> <span class="code-object">String</span>.format('%1$c,%2$3c', 65, 66 as <span class="code-object">byte</span>) == 'A,  B'
    <span class="code-comment">//convert argument to character; 2nd value 3 chars wide
</span><span class="code-keyword">assert</span> <span class="code-object">String</span>.format('%-3c', 67 as <span class="code-object">short</span>) == 'C  '
    <span class="code-comment">//left-justified with '-' flag; we needn't specify parameter number (1$, etc)
</span><span class="code-keyword">assert</span> <span class="code-object">String</span>.format('%c', 'D' as <span class="code-object">char</span>) == 'D'

<span class="code-comment">//Special conversion types:
</span><span class="code-keyword">assert</span> <span class="code-object">String</span>.format('hello %n world %%') == 'hello \r\n world %'
    <span class="code-comment">//platform-specific newline; <span class="code-object">double</span> % to quote it
</span>
<span class="code-comment">//<span class="code-object">Boolean</span> ('b')
</span><span class="code-keyword">assert</span> <span class="code-object">String</span>.format('%b, %b, %b, %b, %b, %b',
                     <span class="code-keyword">null</span>, <span class="code-keyword">true</span>, <span class="code-keyword">false</span>, 0, 1, <span class="code-keyword">new</span> <span class="code-object">Object</span>()) ==
    '<span class="code-keyword">false</span>, <span class="code-keyword">true</span>, <span class="code-keyword">false</span>, <span class="code-keyword">true</span>, <span class="code-keyword">true</span>, <span class="code-keyword">true</span>'</pre>
</div>
</div>
<div class="section_3">
<h3><a name="JN1525-Strings-StringBuffers"></a>StringBuffers</h3>
<p>A StringBuffer is a mutable string. (But from Java 5.0 onwards, we should use a StringBuilder instead, because StringBuffers are normally reserved for multi-threaded processing.)</p>
<div style="border-right-width: 1px; border-top-width: 1px; border-bottom-width: 1px; border-left-width: 1px" class="code panel">
<div class="codeContent panelContent">
<pre class="code-java">def sb1= <span class="code-keyword">new</span> <span class="code-object">StringBuffer</span>(),
    sb2= <span class="code-keyword">new</span> <span class="code-object">StringBuffer</span>('Hello'),
    sb3= <span class="code-keyword">new</span> <span class="code-object">StringBuffer</span>(sb2)
<span class="code-keyword">assert</span> sb1.toString() == '' &amp;&amp;
       sb2.toString() == 'Hello' &amp;&amp;
       sb2.toString() == sb3.toString()</pre>
</div>
</div>
<p>To find the size and substrings:</p>
<div style="border-right-width: 1px; border-top-width: 1px; border-bottom-width: 1px; border-left-width: 1px" class="code panel">
<div class="codeContent panelContent">
<pre class="code-java">def sb= <span class="code-keyword">new</span> <span class="code-object">StringBuffer</span>('abcdefg')
<span class="code-keyword">assert</span> sb.size() == 7 &amp;&amp; sb.length() == 7 <span class="code-comment">//different ways to find size
</span>sb.length= 6 <span class="code-comment">//change size
</span><span class="code-keyword">assert</span> sb.toString() == 'abcdef'
<span class="code-keyword">assert</span> sb.reverse().toString() == 'fedcba'
<span class="code-keyword">assert</span> sb.toString() == 'fedcba' <span class="code-comment">//reverse() method reverses order permanently
</span><span class="code-keyword">assert</span> sb.substring(2) == 'dcba' <span class="code-comment">//substring from index 2
</span><span class="code-keyword">assert</span> sb.substring(2, 5) == 'dcb' <span class="code-comment">//substring from index 2 to &lt;5
</span><span class="code-keyword">assert</span> sb.subSequence(2, 5) == 'dcb' <span class="code-comment">//substring from index 2 to &lt;5
</span><span class="code-keyword">assert</span> sb + 'zyx' == 'fedcbazyx'</pre>
</div>
</div>
<p>To append to a StringBuffer:</p>
<div style="border-right-width: 1px; border-top-width: 1px; border-bottom-width: 1px; border-left-width: 1px" class="code panel">
<div class="codeContent panelContent">
<pre class="code-java">def sb1= <span class="code-keyword">new</span> <span class="code-object">StringBuffer</span>()
sb1 &lt;&lt; 'abc'
sb1 &lt;&lt; 'def' &lt;&lt; 'ghi' <span class="code-comment">//can chain two &lt;&lt; operators
</span>sb1.leftShift('jkl') <span class="code-comment">//equivalent method name
</span>sb1.append('mno') <span class="code-comment">//alternative method name
</span>sb1.append( ['p', 'q', 'r'] as <span class="code-object">char</span>[] )
sb1.append( ['r', 's', 't', 'u', 'v'] as <span class="code-object">char</span>[], 1, 3 )
<span class="code-keyword">assert</span> sb1.toString() == 'abcdefghijklmnopqrstu'</pre>
</div>
</div>
<p>Note that &lt;&lt; doesn't yet work with StringBuilders.</p>
<p>If we append to a String, a StringBuffer is returned:</p>
<div style="border-right-width: 1px; border-top-width: 1px; border-bottom-width: 1px; border-left-width: 1px" class="code panel">
<div class="codeContent panelContent">
<pre class="code-java">def s= 'foo'
s= s &lt;&lt; 'bar'
<span class="code-keyword">assert</span> s.class == <span class="code-object">StringBuffer</span> &amp;&amp; s.toString() == 'foobar'</pre>
</div>
</div>
<p>As with strings, we can subscript a StringBuffer, returning a string:</p>
<div style="border-right-width: 1px; border-top-width: 1px; border-bottom-width: 1px; border-left-width: 1px" class="code panel">
<div class="codeContent panelContent">
<pre class="code-java">def sb= <span class="code-keyword">new</span> <span class="code-object">StringBuffer</span>('abcdefg')
<span class="code-keyword">assert</span> sb[ 3 ] == 'd'
<span class="code-keyword">assert</span> sb[ 3 ].class == <span class="code-object">String</span>
<span class="code-keyword">assert</span> sb.getAt( 3 ) == 'd' <span class="code-comment">//equivalent method name
</span><span class="code-keyword">assert</span> sb.charAt( 3 ) == 'd' <span class="code-comment">//alternative method name
</span><span class="code-keyword">assert</span> sb[ 3..5 ] == 'def'
<span class="code-keyword">assert</span> sb[ 1, 3, 5, 6 ] == 'bdfg'
<span class="code-keyword">assert</span> sb[ 1, 3..5 ] == 'bdef'
<span class="code-keyword">assert</span> sb[-5..-2] == 'cdef'
sb[ 3..5 ] = 'xy' <span class="code-comment">//use subscripts to update <span class="code-object">StringBuffer</span>
</span><span class="code-keyword">assert</span> sb.toString() == 'abcxyg'
sb.putAt( 2..4, 'z' ) <span class="code-comment">//equivalent method name
</span><span class="code-keyword">assert</span> sb.toString() == 'abzg'
sb.setCharAt(1, 'm' as <span class="code-object">char</span>) <span class="code-comment">//alternative method name
</span><span class="code-keyword">assert</span> sb.toString() == 'amzg'</pre>
</div>
</div>
<p>We can insert into, replace within, and delete from StringBuffers using methods:</p>
<div style="border-right-width: 1px; border-top-width: 1px; border-bottom-width: 1px; border-left-width: 1px" class="code panel">
<div class="codeContent panelContent">
<pre class="code-java">def sb= <span class="code-keyword">new</span> <span class="code-object">StringBuffer</span>('hello park')
sb.delete(4, 7)
<span class="code-keyword">assert</span> sb.toString() == 'hellark'
sb.deleteCharAt(3)
<span class="code-keyword">assert</span> sb.toString() == 'helark'
def ca= <span class="code-keyword">new</span> <span class="code-object">char</span>[6]
sb.getChars(2, 5, ca, 1)
    <span class="code-comment">//<span class="code-keyword">for</span> indexes 2 to &lt;5, copy into ca beginning from index 1
</span>(['\0', 'l', 'a', 'r', '\0', '\0'] as <span class="code-object">char</span>[]).
    eachWithIndex{ elt, i-&gt; <span class="code-keyword">assert</span> ca[i] == elt }

sb.insert(4, 'se')
<span class="code-keyword">assert</span> sb.toString() == 'helaserk'
sb.insert(4, <span class="code-keyword">new</span> <span class="code-object">StringBuffer</span>('ct ') )
<span class="code-keyword">assert</span> sb.toString() == 'helact serk'
sb.insert(10, ['i', 'c'] as <span class="code-object">char</span>[] )
<span class="code-keyword">assert</span> sb.toString() == 'helact serick'
sb.insert(6, ['m', 'a', 'l', 't'] as <span class="code-object">char</span>[], 1, 2)
    <span class="code-comment">//insert 2 chars from subscript 1
</span><span class="code-keyword">assert</span> sb.toString() == 'helactal serick'
sb.insert(10, 'snapla', 3, 5) <span class="code-comment">//insert chars from subscript 3 to &lt;5
</span><span class="code-keyword">assert</span> sb.toString() == 'helactal splerick'
sb.replace(4, 13, 'dor') <span class="code-comment">//replace chars from subscript 4 to &lt;13
</span><span class="code-keyword">assert</span> sb.toString() == 'heladorrick'</pre>
</div>
</div>
<p>We can find the index of substrings:</p>
<div style="border-right-width: 1px; border-top-width: 1px; border-bottom-width: 1px; border-left-width: 1px" class="code panel">
<div class="codeContent panelContent">
<pre class="code-java">def sb= <span class="code-keyword">new</span> <span class="code-object">StringBuffer</span>('hello elm')
<span class="code-keyword">assert</span> sb.indexOf('el') == 1
<span class="code-keyword">assert</span> sb.indexOf('el', 3) == 6 <span class="code-comment">//first occurence of 'el' from index 3
</span><span class="code-keyword">assert</span> sb.lastIndexOf('el') == 6
<span class="code-keyword">assert</span> sb.lastIndexOf('el', 3) == 1 <span class="code-comment">//last occurence of 'el' up to index 3</span></pre>
</div>
</div>
<p>Some miscellaneous methods:</p>
<div style="border-right-width: 1px; border-top-width: 1px; border-bottom-width: 1px; border-left-width: 1px" class="code panel">
<div class="codeContent panelContent">
<pre class="code-java">def s= <span class="code-keyword">new</span> <span class="code-object">String</span>( <span class="code-keyword">new</span> <span class="code-object">StringBuffer</span>('abcdefg') )
<span class="code-keyword">assert</span> s == 'abcdefg'
<span class="code-keyword">assert</span> s.contains('def')
<span class="code-keyword">assert</span> s.contentEquals('abcdefg')
<span class="code-keyword">assert</span> s.contentEquals( <span class="code-keyword">new</span> <span class="code-object">StringBuffer</span>('abcdefg') )
def s2= s.replace('def', 'xyz')
<span class="code-keyword">assert</span> s2 == 'abcxyzg'</pre>
</div>
</div>
<p>We can enquire of code points in a String or StringBuffer using methods on them, just as we can with methods on Character:</p>
<div style="border-right-width: 1px; border-top-width: 1px; border-bottom-width: 1px; border-left-width: 1px" class="code panel">
<div class="codeContent panelContent">
<pre class="code-java">def minLowSurr= <span class="code-object">Character</span>.MIN_LOW_SURROGATE,
    minHighSurr= <span class="code-object">Character</span>.MIN_HIGH_SURROGATE

def s1= 'abc'+ minHighSurr + minLowSurr +'efg'
<span class="code-keyword">assert</span> s1.codePointAt(3) == 0x10000 <span class="code-comment">//<span class="code-keyword">if</span> high surrogate, add on low surrogate
</span><span class="code-keyword">assert</span> s1.codePointAt(4) == minLowSurr <span class="code-comment">//<span class="code-keyword">if</span> low surrogate, use it only
</span><span class="code-keyword">assert</span> s1.codePointAt(5) == 'e' as <span class="code-object">int</span>
<span class="code-keyword">assert</span> s1.codePointBefore(4) == minHighSurr
<span class="code-keyword">assert</span> s1.codePointBefore(5) == 0x10000
    <span class="code-comment">//<span class="code-keyword">if</span> low surrogate, look back more <span class="code-keyword">for</span> high one, and use both
</span><span class="code-keyword">assert</span> s1.codePointCount(1, 5) == 3
    <span class="code-comment">//number of code points in a substring with indexes &gt;=1 and &lt;5
</span><span class="code-keyword">assert</span> s1.offsetByCodePoints(1, 3) == 5
    <span class="code-comment">//index from 1 that's offset by 3 code points
</span>
def sb= <span class="code-keyword">new</span> <span class="code-object">StringBuffer</span>( 'abc'+ minHighSurr + minLowSurr +'efg' )
    <span class="code-comment">//also, <span class="code-keyword">for</span> StringBuffers
</span><span class="code-keyword">assert</span> sb.codePointAt(5) == 'e' as <span class="code-object">int</span>
<span class="code-keyword">assert</span> sb.codePointBefore(4) == minHighSurr
<span class="code-keyword">assert</span> sb.codePointCount(1, 5) == 3
<span class="code-keyword">assert</span> sb.offsetByCodePoints(1, 3) == 5

sb.appendCodePoint(0x10000)
<span class="code-keyword">assert</span> sb.toString() ==
    'abc'+ minHighSurr + minLowSurr +'efg'+ minHighSurr + minLowSurr</pre>
</div>
</div>
<p>We can manipulate the implementation of a StringBuffer:</p>
<div style="border-right-width: 1px; border-top-width: 1px; border-bottom-width: 1px; border-left-width: 1px" class="code panel">
<div class="codeContent panelContent">
<pre class="code-java">def sb1= <span class="code-keyword">new</span> <span class="code-object">StringBuffer</span>() <span class="code-comment">//<span class="code-keyword">default</span> initial capacity is 16
</span><span class="code-keyword">assert</span> sb1.capacity() == 16

def sb2= <span class="code-keyword">new</span> <span class="code-object">StringBuffer</span>(5) <span class="code-comment">//we can specify initial capacity
</span><span class="code-keyword">assert</span> sb2.capacity() == 5
sb2&lt;&lt; 'abc'
<span class="code-keyword">assert</span> sb2.capacity() == 5 &amp;&amp; sb2.size() == 3
sb2.trimToSize()
<span class="code-keyword">assert</span> sb2.capacity() == 3
sb2.ensureCapacity(10)
<span class="code-keyword">assert</span> sb2.capacity() == 10

def sb3= <span class="code-keyword">new</span> <span class="code-object">StringBuffer</span>(0) <span class="code-comment">//capacity approximately doubles when required
</span>def cap= 0, caps=[]
100.times{
  <span class="code-keyword">if</span>((sb3&lt;&lt; 'a').capacity() != cap) caps&lt;&lt; (cap= sb3.capacity())
}
<span class="code-keyword">assert</span> caps == [2, 6, 14, 30, 62, 126]</pre>
</div>
</div>
</div> <a href="http://hi.baidu.com/coollzh/blog/item/0f02c41c447dfe8186d6b63a.html">阅读全文</a>
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/coollzh/blog/category/Groovy">Groovy</a>&nbsp;<a href="http://hi.baidu.com/coollzh/blog/item/0f02c41c447dfe8186d6b63a.html#comment">查看评论</a>]]></description>
        <pubDate>2009-10-18  01:06</pubDate>
        <category><![CDATA[Groovy]]></category>
        <author><![CDATA[coollzh]]></author>
		<guid>http://hi.baidu.com/coollzh/blog/item/0f02c41c447dfe8186d6b63a.html</guid>
</item>

<item>
        <title><![CDATA[ADO.NET 4.0令人失望的变更！]]></title>
        <link><![CDATA[http://hi.baidu.com/coollzh/blog/item/51b4f235ddc2b81b91ef3964.html]]></link>
        <description><![CDATA[
		
		<p>System.Data.OracleClient 在将要发布的.NET Framework 4.0中还会保存，但会标记为&ldquo;不赞成&rdquo;，这对现有的程序没有影响，但如果你用.NET 4.0来重新编译你的程序，你就会发现出现大量的Worning.<br>
我们推荐我们的客户们去使用我们合作伙伴的ADO.NET Provider for Oracle,不要在使用微软现有的OracleClient。</p>
<p>---注：意思很明显，微软将不会再OracleClient上投入更多精力来更新版本了，而是交给了社区和合作伙伴，有点令人失望，我们有大量的程序都是基于OracleClient，根据社区的反应ODP.NET 不太稳定，问题多多。</p>
<p>不过看Oracle自己的网站上的对比，ODP.NET确实功能比较强劲，加以时日应该能成为主流</p>
<p>这么重大的事件，我居然才知道，看来确实孤陋寡闻了！<br>
英文原文:<br>
System.Data.OracleClient will be available in the upcoming 4.0 release of .NET Framework; however, it will be marked as deprecated. This will have no impact to existing applications and these applications will continue to work as expected. Developing new applications which use OracleClient will be supported; however, warnings will be raised if the applications are compiled against .Net 4.0. Once compiled, no warnings or errors will be generated while running these applications. We strongly recommend customers to use our partners&rsquo; ADO.NET Provider for Oracle instead of continuing to use Microsoft&rsquo;s OracleClient for new application development.</p>
<p>Microsoft will continue to provide hotfixes for critical issues in System.Data.OracleClient as per the standard support policy for .Net Framework 4.0. We will also continue to make critical bug fixes in future service packs for .Net Framework 4.0.</p>
<p>Thank you,</p>
<p>Himanshu Vasishth <br>
Program Manager, ADO.NET OracleClient<a href="http://blogs.msdn.com/adonet/archive/2009/06/15/system-data-oracleclient-update.aspx"><br>
<br>
http://blogs.msdn.com/adonet/archive/2009/06/15/system-data-oracleclient-update.aspx</a></p> <a href="http://hi.baidu.com/coollzh/blog/item/51b4f235ddc2b81b91ef3964.html">阅读全文</a>
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/coollzh/blog/category/%2Enet4%2E0">.net4.0</a>&nbsp;<a href="http://hi.baidu.com/coollzh/blog/item/51b4f235ddc2b81b91ef3964.html#comment">查看评论</a>]]></description>
        <pubDate>2009-10-17  22:24</pubDate>
        <category><![CDATA[.net4.0]]></category>
        <author><![CDATA[coollzh]]></author>
		<guid>http://hi.baidu.com/coollzh/blog/item/51b4f235ddc2b81b91ef3964.html</guid>
</item>

<item>
        <title><![CDATA[Get an annotation value in Groovy]]></title>
        <link><![CDATA[http://hi.baidu.com/coollzh/blog/item/49c7058b3fcfe718c9fc7aa4.html]]></link>
        <description><![CDATA[
		
		<p>import java.lang.annotation.*</p>
<p>@Retention(RetentionPolicy.RUNTIME) <br>
@Target(ElementType.METHOD) <br>
@interface Anno { <br>
&nbsp;&nbsp;&nbsp;  <br>
String value() default &quot;&quot;<br>
}</p>
<p>class Foo { <br>
&nbsp;&nbsp;&nbsp;  <br>
@Anno(&quot;A cool method!&quot;) <br>
&nbsp;&nbsp;&nbsp;  <br>
void method() {} <br>
}</p>
<p>def f = new Foo()</p>
<p>def method = Foo.getMethod(&quot;method&quot;, [] as Class[]) <br>
assert method.isAnnotationPresent(Anno) <br>
assert method.getAnnotation(Anno).value() == &quot;A cool method!&quot;</p> <a href="http://hi.baidu.com/coollzh/blog/item/49c7058b3fcfe718c9fc7aa4.html">阅读全文</a>
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/coollzh/blog/category/Groovy">Groovy</a>&nbsp;<a href="http://hi.baidu.com/coollzh/blog/item/49c7058b3fcfe718c9fc7aa4.html#comment">查看评论</a>]]></description>
        <pubDate>2009-10-17  21:07</pubDate>
        <category><![CDATA[Groovy]]></category>
        <author><![CDATA[coollzh]]></author>
		<guid>http://hi.baidu.com/coollzh/blog/item/49c7058b3fcfe718c9fc7aa4.html</guid>
</item>


</channel>
</rss>