<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>OnlyLonely &#38; Marshall's &#187; csdn导入</title>
	<atom:link href="http://www.onlymarshall.com/category/imported-items/csdn-import/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.onlymarshall.com</link>
	<description>小白和小黑</description>
	<lastBuildDate>Mon, 23 Apr 2012 15:58:45 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
<atom:link rel="hub" href="http://pubsubhubbub.appspot.com"/><atom:link rel="hub" href="http://superfeedr.com/hubbub"/>		<item>
		<title>Hibernate里的重复记录</title>
		<link>http://www.onlymarshall.com/2009/02/22/hibernate-duplicate-record/</link>
		<comments>http://www.onlymarshall.com/2009/02/22/hibernate-duplicate-record/#comments</comments>
		<pubDate>Sun, 22 Feb 2009 13:51:00 +0000</pubDate>
		<dc:creator>marshall</dc:creator>
				<category><![CDATA[csdn导入]]></category>
		<category><![CDATA[Space导入]]></category>
		<category><![CDATA[技术]]></category>
		<category><![CDATA[未分类]]></category>
		<category><![CDATA[Hibernate]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://www.onlymarshall.com/?p=17</guid>
		<description><![CDATA[前几天APIS爆出了个奇怪的BUG：某个小组关闭任务后，任务自动被duplicate，然后子任务也丢失了。手工查看数据库，发现数据库里居然只有一条Task记录，Hibernate却返回两条。findById(id为主键)居然会返回两条记录，这就奇了怪了。 用Firebug看记录，发现抛出了异常。&#8221;More than one row with the given identifier was found&#8221;。可是数据库里明明只有一条记录啊。二话不说google发现了这个post，顿时想起来由于关联(association)而产生万恶的outer join。排查了几个关联（出问题的那个类偏偏是最heavily-associated），终于在一个与Part类&#60;one-to-one&#62;上发现了问题。虽然是&#60;one-to-one&#62;关联，却发现另外一方（Part）存在重复的记录，直接影响到Task类。找到原因，assign给Part类的责任人，问题解决。]]></description>
			<content:encoded><![CDATA[<p>前几天APIS爆出了个奇怪的BUG：某个小组关闭任务后，任务自动被duplicate，然后子任务也丢失了。手工查看数据库，发现数据库里居然只有一条Task记录，Hibernate却返回两条。findById(id为主键)居然会返回两条记录，这就奇了怪了。</p>
<p>用Firebug看记录，发现抛出了异常。&#8221;More than one row with the given identifier was found&#8221;。可是数据库里明明只有一条记录啊。二话不说google发现了这个<a href="http://forums.hibernate.org/viewtopic.php?p=2185257">post</a>，顿时想起来由于关联(association)而产生万恶的outer join。排查了几个关联（出问题的那个类偏偏是最heavily-associated），终于在一个与Part类&lt;one-to-one&gt;上发现了问题。虽然是&lt;one-to-one&gt;关联，却发现另外一方（Part）存在重复的记录，直接影响到Task类。找到原因，assign给Part类的责任人，问题解决。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.onlymarshall.com/2009/02/22/hibernate-duplicate-record/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>打算写一个简单的数据库迁移工具</title>
		<link>http://www.onlymarshall.com/2009/01/17/%e6%89%93%e7%ae%97%e5%86%99%e4%b8%80%e4%b8%aa%e7%ae%80%e5%8d%95%e7%9a%84%e6%95%b0%e6%8d%ae%e5%ba%93%e8%bf%81%e7%a7%bb%e5%b7%a5%e5%85%b7/</link>
		<comments>http://www.onlymarshall.com/2009/01/17/%e6%89%93%e7%ae%97%e5%86%99%e4%b8%80%e4%b8%aa%e7%ae%80%e5%8d%95%e7%9a%84%e6%95%b0%e6%8d%ae%e5%ba%93%e8%bf%81%e7%a7%bb%e5%b7%a5%e5%85%b7/#comments</comments>
		<pubDate>Sun, 18 Jan 2009 00:27:00 +0000</pubDate>
		<dc:creator>marshall</dc:creator>
				<category><![CDATA[csdn导入]]></category>
		<category><![CDATA[Space导入]]></category>
		<category><![CDATA[技术]]></category>
		<category><![CDATA[未分类]]></category>
		<category><![CDATA[DB]]></category>
		<category><![CDATA[migration]]></category>

		<guid isPermaLink="false">http://www.onlymarshall.com/?p=18</guid>
		<description><![CDATA[之前做项目一直被数据库schema改动折腾得不行，找了不少工具，比如migrate4j,dbmigrate和liquibase之类的，感觉都不是很满意。其实我的需求很简单，不需要数据库的DSL（比如migrate4j或者db:migrate的那种用Java/Ruby描述DDL），只需要纯的SQL（也就是db:migrate生成的SQL），只需要前向操纵（即不需要回滚），有Eclipse的插件。 现有的migration工具，都是使用分开的文件作为不同版本的内容，这带来了很大的灵活性。但是我的打算是对现有的开发模式有最小的影响。比如现在项目的开发方式是使用一个schema文件外加几个基础数据文件。于是我打算直接使用SVN作为数据库版本的保存工具，利用SVN的特性做版本化。最直接使用的就是SVN的版本号。不过这样的问题在于基本无法做rollback，除非使用两个文件，一个construction，一个destruction，但这要求两个文件一起提交，带来了不少复杂性。现有项目的schema不需要做rollback，正好这么做。工作的方式为：更新SVN，获得最新的schema文件和当前的版本做对比，把增加的部分（要求更新append在最后）执行一遍。就这么简单。 调查了一下午+半个晚上，基本把一些技术方案给调查清楚了。主要的难度在于和subclipse的集成。既然功能简单，就要做到易用。于是我打起了subclipse的主意，主要是subclipse保存的SVN用户名密码。发现subclipse还挺变态的，JavaHL的接口使用HOME目录保存，SVNKit接口使用Eclipse的keyrings文件。 这两天就动手，代码参考较为简单（或者说简陋）的dbmigrate。]]></description>
			<content:encoded><![CDATA[<p>之前做项目一直被数据库schema改动折腾得不行，找了不少工具，比如migrate4j,dbmigrate和liquibase之类的，感觉都不是很满意。其实我的需求很简单，不需要数据库的DSL（比如migrate4j或者db:migrate的那种用Java/Ruby描述DDL），只需要纯的SQL（也就是db:migrate生成的SQL），只需要前向操纵（即不需要回滚），有Eclipse的插件。</p>
<p>现有的migration工具，都是使用分开的文件作为不同版本的内容，这带来了很大的灵活性。但是我的打算是对现有的开发模式有最小的影响。比如现在项目的开发方式是使用一个schema文件外加几个基础数据文件。于是我打算直接使用SVN作为数据库版本的保存工具，利用SVN的特性做版本化。最直接使用的就是SVN的版本号。不过这样的问题在于基本无法做rollback，除非使用两个文件，一个construction，一个destruction，但这要求两个文件一起提交，带来了不少复杂性。现有项目的schema不需要做rollback，正好这么做。工作的方式为：更新SVN，获得最新的schema文件和当前的版本做对比，把增加的部分（要求更新append在最后）执行一遍。就这么简单。</p>
<p>调查了一下午+半个晚上，基本把一些技术方案给调查清楚了。主要的难度在于和subclipse的集成。既然功能简单，就要做到易用。于是我打起了subclipse的主意，主要是subclipse保存的SVN用户名密码。发现subclipse还挺变态的，JavaHL的接口使用HOME目录保存，SVNKit接口使用Eclipse的keyrings文件。</p>
<p>这两天就动手，代码参考较为简单（或者说简陋）的dbmigrate。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.onlymarshall.com/2009/01/17/%e6%89%93%e7%ae%97%e5%86%99%e4%b8%80%e4%b8%aa%e7%ae%80%e5%8d%95%e7%9a%84%e6%95%b0%e6%8d%ae%e5%ba%93%e8%bf%81%e7%a7%bb%e5%b7%a5%e5%85%b7/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>使用Cache-Control和gzip提升tomcat应用性能(整理)</title>
		<link>http://www.onlymarshall.com/2008/10/02/%e4%bd%bf%e7%94%a8cache-control%e5%92%8cgzip%e6%8f%90%e5%8d%87tomcat%e5%ba%94%e7%94%a8%e6%80%a7%e8%83%bd%e6%95%b4%e7%90%86/</link>
		<comments>http://www.onlymarshall.com/2008/10/02/%e4%bd%bf%e7%94%a8cache-control%e5%92%8cgzip%e6%8f%90%e5%8d%87tomcat%e5%ba%94%e7%94%a8%e6%80%a7%e8%83%bd%e6%95%b4%e7%90%86/#comments</comments>
		<pubDate>Thu, 02 Oct 2008 23:46:00 +0000</pubDate>
		<dc:creator>marshall</dc:creator>
				<category><![CDATA[csdn导入]]></category>
		<category><![CDATA[技术]]></category>
		<category><![CDATA[cache]]></category>
		<category><![CDATA[tomcat]]></category>
		<category><![CDATA[性能]]></category>

		<guid isPermaLink="false">http://www.onlymarshall.com/?p=19</guid>
		<description><![CDATA[这个其实应该是常识，只不过以前做的J2EE应用大部分是内网里跑的东西，所以性能上没什么问题。这次APIS由于有在外面用的可能，加上使用了一些比较大的javascript框架(Ext)，所以性能问题瞬间窜了上来。 以前做的J2EE应用没有使用上达500K的框架，最多就是几十K的Prototype，所以没什么问题。一个页面一般也就几十K最多了。但这次还在开发中的APIS，由于还在用debug版本的库，所以单单Ext就膨胀到了一个多M，加上不知道是Struts还是Tomcat默认写入Response的cache-control: no cache，在远程用起来就很慢，一般一个页面需要十多秒种甚至更久，实在无法忍受。前几天集中解决了问题。 首先是Cache-Control的问题，Google了好一阵，没有什么直接配置的方法，只好自己抄了一个一个Filter，通过和web.xml里配置的配合勉强凑合着用。一般就是对*.do实施no-cache政策，其他需要缓存的img, js文件，统统加上长达两周的缓存期限。ETag实在不会用，就先用这个缓存策略吧。 Filter的代码： public class ResponseHeaderFilter implements Filter { FilterConfig fc; public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletResponse response = (HttpServletResponse) res; // set the provided HTTP response parameters for (Enumeration e = fc.getInitParameterNames(); e.hasMoreElements();) { String headerName = (String) e.nextElement(); response.addHeader(headerName, fc.getInitParameter(headerName)); } // pass the request/response on chain.doFilter(req, response); } public void init(FilterConfig filterConfig) { this.fc = filterConfig; } public void destroy() { this.fc = null; } } web.xml里的巧妙配置： &#60;filter&#62; &#60;filter-name&#62;NoCache&#60;/filter-name&#62; &#60;filter-class&#62;apis.server.common.util.ResponseHeaderFilter&#60;/filter-class&#62; &#60;init-param&#62; &#60;param-name&#62;Cache-Control&#60;/param-name&#62; &#60;param-value&#62;no-cache, must-revalidate&#60;/param-value&#62; &#60;/init-param&#62; &#60;/filter&#62; &#60;filter&#62; &#60;filter-name&#62;CacheForWeek&#60;/filter-name&#62; &#60;filter-class&#62;apis.server.common.util.ResponseHeaderFilter&#60;/filter-class&#62; &#60;init-param&#62; &#60;param-name&#62;Cache-Control&#60;/param-name&#62; [...]]]></description>
			<content:encoded><![CDATA[<p>这个其实应该是常识，只不过以前做的J2EE应用大部分是内网里跑的东西，所以性能上没什么问题。这次APIS由于有在外面用的可能，加上使用了一些比较大的javascript框架(Ext)，所以性能问题瞬间窜了上来。<br />
以前做的J2EE应用没有使用上达500K的框架，最多就是几十K的Prototype，所以没什么问题。一个页面一般也就几十K最多了。但这次还在开发中的APIS，由于还在用debug版本的库，所以单单Ext就膨胀到了一个多M，加上不知道是Struts还是Tomcat默认写入Response的cache-control: no cache，在远程用起来就很慢，一般一个页面需要十多秒种甚至更久，实在无法忍受。前几天集中解决了问题。<br />
首先是Cache-Control的问题，Google了好一阵，没有什么直接配置的方法，只好自己抄了一个一个Filter，通过和web.xml里配置的配合勉强凑合着用。一般就是对*.do实施no-cache政策，其他需要缓存的img, js文件，统统加上长达两周的缓存期限。ETag实在不会用，就先用这个缓存策略吧。</p>
<p>Filter的代码：</p>
<div class="highlighter">
<ol class="highlighter-j">
<li><span class="keyword">public</span><span> </span><span class="keyword">class</span><span> ResponseHeaderFilter </span><span class="keyword">implements</span><span> Filter {</span></li>
<li class="alt"><span> FilterConfig fc; </span></li>
<li></li>
<li class="alt"><span> </span><span class="keyword">public</span><span> </span><span class="keyword">void</span><span> doFilter(ServletRequest req, ServletResponse res,</span></li>
<li><span> FilterChain chain) </span><span class="keyword">throws</span><span> IOException, ServletException {</span></li>
<li class="alt"><span> HttpServletResponse response = (HttpServletResponse) res;</span></li>
<li><span> </span><span class="comment">// set the provided HTTP response parameters</span></li>
<li class="alt"><span> </span><span class="keyword">for</span><span> (Enumeration e = fc.getInitParameterNames(); e.hasMoreElements();) {</span></li>
<li><span> String headerName = (String) e.nextElement();</span></li>
<li class="alt"><span> response.addHeader(headerName, fc.getInitParameter(headerName));</span></li>
<li><span> }</span></li>
<li class="alt"><span> </span><span class="comment">// pass the request/response on</span></li>
<li><span> chain.doFilter(req, response);</span></li>
<li class="alt"><span> } </span></li>
<li></li>
<li class="alt"><span> </span><span class="keyword">public</span><span> </span><span class="keyword">void</span><span> init(FilterConfig filterConfig) {</span></li>
<li><span> </span><span class="keyword">this</span><span>.fc = filterConfig;</span></li>
<li class="alt"><span> } </span></li>
<li></li>
<li class="alt"><span> </span><span class="keyword">public</span><span> </span><span class="keyword">void</span><span> destroy() {</span></li>
<li><span> </span><span class="keyword">this</span><span>.fc = </span><span class="keyword">null</span><span>;</span></li>
<li class="alt"><span> } </span></li>
<li></li>
<li class="alt"><span>}</span></li>
<li></li>
</ol>
</div>
<p>web.xml里的巧妙配置：</p>
<div class="highlighter">
<ol class="highlighter-xml">
<li><span class="tag">&lt;</span><span class="tag-name">filter</span><span class="tag">&gt;</span></li>
<li class="alt"><span> </span><span class="tag">&lt;</span><span class="tag-name">filter-name</span><span class="tag">&gt;</span><span>NoCache</span><span class="tag">&lt;/</span><span class="tag-name">filter-name</span><span class="tag">&gt;</span></li>
<li><span> </span><span class="tag">&lt;</span><span class="tag-name">filter-class</span><span class="tag">&gt;</span><span>apis.server.common.util.ResponseHeaderFilter</span><span class="tag">&lt;/</span><span class="tag-name">filter-class</span><span class="tag">&gt;</span></li>
<li class="alt"><span> </span><span class="tag">&lt;</span><span class="tag-name">init-param</span><span class="tag">&gt;</span></li>
<li><span> </span><span class="tag">&lt;</span><span class="tag-name">param-name</span><span class="tag">&gt;</span><span>Cache-Control</span><span class="tag">&lt;/</span><span class="tag-name">param-name</span><span class="tag">&gt;</span></li>
<li class="alt"><span> </span><span class="tag">&lt;</span><span class="tag-name">param-value</span><span class="tag">&gt;</span><span>no-cache, must-revalidate</span><span class="tag">&lt;/</span><span class="tag-name">param-value</span><span class="tag">&gt;</span></li>
<li><span> </span><span class="tag">&lt;/</span><span class="tag-name">init-param</span><span class="tag">&gt;</span></li>
<li class="alt"><span> </span><span class="tag">&lt;/</span><span class="tag-name">filter</span><span class="tag">&gt;</span></li>
<li><span> </span><span class="tag">&lt;</span><span class="tag-name">filter</span><span class="tag">&gt;</span></li>
<li class="alt"><span> </span><span class="tag">&lt;</span><span class="tag-name">filter-name</span><span class="tag">&gt;</span><span>CacheForWeek</span><span class="tag">&lt;/</span><span class="tag-name">filter-name</span><span class="tag">&gt;</span></li>
<li><span> </span><span class="tag">&lt;</span><span class="tag-name">filter-class</span><span class="tag">&gt;</span><span>apis.server.common.util.ResponseHeaderFilter</span><span class="tag">&lt;/</span><span class="tag-name">filter-class</span><span class="tag">&gt;</span></li>
<li class="alt"><span> </span><span class="tag">&lt;</span><span class="tag-name">init-param</span><span class="tag">&gt;</span></li>
<li><span> </span><span class="tag">&lt;</span><span class="tag-name">param-name</span><span class="tag">&gt;</span><span>Cache-Control</span><span class="tag">&lt;/</span><span class="tag-name">param-name</span><span class="tag">&gt;</span></li>
<li class="alt"><span> </span><span class="tag">&lt;</span><span class="tag-name">param-value</span><span class="tag">&gt;</span><span class="attribute">max-age</span><span>=</span><span class="attribute-value">604800</span><span>, public</span><span class="tag">&lt;/</span><span class="tag-name">param-value</span><span class="tag">&gt;</span></li>
<li><span> </span><span class="tag">&lt;/</span><span class="tag-name">init-param</span><span class="tag">&gt;</span></li>
<li class="alt"><span> </span><span class="tag">&lt;/</span><span class="tag-name">filter</span><span class="tag">&gt;</span></li>
<li></li>
<li class="alt"><span class="tag">&lt;</span><span class="tag-name">filter-mapping</span><span class="tag">&gt;</span></li>
<li><span> </span><span class="tag">&lt;</span><span class="tag-name">filter-name</span><span class="tag">&gt;</span><span>NoCache</span><span class="tag">&lt;/</span><span class="tag-name">filter-name</span><span class="tag">&gt;</span></li>
<li class="alt"><span> </span><span class="tag">&lt;</span><span class="tag-name">url-pattern</span><span class="tag">&gt;</span><span>*.do</span><span class="tag">&lt;/</span><span class="tag-name">url-pattern</span><span class="tag">&gt;</span></li>
<li><span> </span><span class="tag">&lt;/</span><span class="tag-name">filter-mapping</span><span class="tag">&gt;</span></li>
<li class="alt"><span> </span><span class="tag">&lt;</span><span class="tag-name">filter-mapping</span><span class="tag">&gt;</span></li>
<li><span> </span><span class="tag">&lt;</span><span class="tag-name">filter-name</span><span class="tag">&gt;</span><span>CacheForWeek</span><span class="tag">&lt;/</span><span class="tag-name">filter-name</span><span class="tag">&gt;</span></li>
<li class="alt"><span> </span><span class="tag">&lt;</span><span class="tag-name">url-pattern</span><span class="tag">&gt;</span><span>/images/*</span><span class="tag">&lt;/</span><span class="tag-name">url-pattern</span><span class="tag">&gt;</span></li>
<li><span> </span><span class="tag">&lt;/</span><span class="tag-name">filter-mapping</span><span class="tag">&gt;</span></li>
<li class="alt"><span> </span><span class="tag">&lt;</span><span class="tag-name">filter-mapping</span><span class="tag">&gt;</span></li>
<li><span> </span><span class="tag">&lt;</span><span class="tag-name">filter-name</span><span class="tag">&gt;</span><span>CacheForWeek</span><span class="tag">&lt;/</span><span class="tag-name">filter-name</span><span class="tag">&gt;</span></li>
<li class="alt"><span> </span><span class="tag">&lt;</span><span class="tag-name">url-pattern</span><span class="tag">&gt;</span><span>/img/*</span><span class="tag">&lt;/</span><span class="tag-name">url-pattern</span><span class="tag">&gt;</span></li>
<li><span> </span><span class="tag">&lt;/</span><span class="tag-name">filter-mapping</span><span class="tag">&gt;</span></li>
<li class="alt"><span> </span><span class="tag">&lt;</span><span class="tag-name">filter-mapping</span><span class="tag">&gt;</span></li>
<li><span> </span><span class="tag">&lt;</span><span class="tag-name">filter-name</span><span class="tag">&gt;</span><span>CacheForWeek</span><span class="tag">&lt;/</span><span class="tag-name">filter-name</span><span class="tag">&gt;</span></li>
<li class="alt"><span> </span><span class="tag">&lt;</span><span class="tag-name">url-pattern</span><span class="tag">&gt;</span><span>/icons/*</span><span class="tag">&lt;/</span><span class="tag-name">url-pattern</span><span class="tag">&gt;</span></li>
<li><span> </span><span class="tag">&lt;/</span><span class="tag-name">filter-mapping</span><span class="tag">&gt;</span></li>
<li class="alt"><span> </span><span class="tag">&lt;</span><span class="tag-name">filter-mapping</span><span class="tag">&gt;</span></li>
<li><span> </span><span class="tag">&lt;</span><span class="tag-name">filter-name</span><span class="tag">&gt;</span><span>CacheForWeek</span><span class="tag">&lt;/</span><span class="tag-name">filter-name</span><span class="tag">&gt;</span></li>
<li class="alt"><span> </span><span class="tag">&lt;</span><span class="tag-name">url-pattern</span><span class="tag">&gt;</span><span>/ext/*</span><span class="tag">&lt;/</span><span class="tag-name">url-pattern</span><span class="tag">&gt;</span></li>
<li><span> </span><span class="tag">&lt;/</span><span class="tag-name">filter-mapping</span><span class="tag">&gt;</span></li>
<li class="alt"><span> </span><span class="tag">&lt;</span><span class="tag-name">filter-mapping</span><span class="tag">&gt;</span></li>
<li><span> </span><span class="tag">&lt;</span><span class="tag-name">filter-name</span><span class="tag">&gt;</span><span>CacheForWeek</span><span class="tag">&lt;/</span><span class="tag-name">filter-name</span><span class="tag">&gt;</span></li>
<li class="alt"><span> </span><span class="tag">&lt;</span><span class="tag-name">url-pattern</span><span class="tag">&gt;</span><span>*.js</span><span class="tag">&lt;/</span><span class="tag-name">url-pattern</span><span class="tag">&gt;</span></li>
<li><span> </span><span class="tag">&lt;/</span><span class="tag-name">filter-mapping</span><span class="tag">&gt;</span></li>
<li class="alt"><span> </span><span class="tag">&lt;</span><span class="tag-name">filter-mapping</span><span class="tag">&gt;</span></li>
<li><span> </span><span class="tag">&lt;</span><span class="tag-name">filter-name</span><span class="tag">&gt;</span><span>CacheForWeek</span><span class="tag">&lt;/</span><span class="tag-name">filter-name</span><span class="tag">&gt;</span></li>
<li class="alt"><span> </span><span class="tag">&lt;</span><span class="tag-name">url-pattern</span><span class="tag">&gt;</span><span>*.css</span><span class="tag">&lt;/</span><span class="tag-name">url-pattern</span><span class="tag">&gt;</span></li>
<li><span> </span><span class="tag">&lt;/</span><span class="tag-name">filter-mapping</span><span class="tag">&gt;</span><span> </span></li>
</ol>
</div>
<p>(插入一段：在探测这些性能问题的时候，我使用的是一个Firebug的插件，也就是Firefox插件的插件-YSlow，好像是Yahoo的，结合Firebug里XHR的Net这块做Profiling，效果很不错，很容易就知道瓶颈)</p>
<p>还有一个gzip的办法，就是在服务器压缩内容，再传给浏览器。现在主流的浏览器都支持gzip压缩，而且这些html和js文本压缩起来很厉害，基本上可以有40%的压缩率。办法在servel.xml的注释里也有写，就是在Connector元素里加上</p>
<p>compression=&#8221;on&#8221;<br />
compressionMinSize=&#8221;2048&#8243;<br />
noCompressionUserAgents=&#8221;gozilla,traviata&#8221;<br />
compressableMimeType=&#8221;text/html,text/xml,text/javascript,text/css,text/plain&#8221;</p>
<p>以上的内容大部分都是Google得来，我自己做了一下整理</p>
]]></content:encoded>
			<wfw:commentRss>http://www.onlymarshall.com/2008/10/02/%e4%bd%bf%e7%94%a8cache-control%e5%92%8cgzip%e6%8f%90%e5%8d%87tomcat%e5%ba%94%e7%94%a8%e6%80%a7%e8%83%bd%e6%95%b4%e7%90%86/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>解决Ubuntu升级8.04 “未能计算更新”问题</title>
		<link>http://www.onlymarshall.com/2008/06/02/%e8%a7%a3%e5%86%b3ubuntu%e5%8d%87%e7%ba%a7804-%e2%80%9c%e6%9c%aa%e8%83%bd%e8%ae%a1%e7%ae%97%e6%9b%b4%e6%96%b0%e2%80%9d%e9%97%ae%e9%a2%98/</link>
		<comments>http://www.onlymarshall.com/2008/06/02/%e8%a7%a3%e5%86%b3ubuntu%e5%8d%87%e7%ba%a7804-%e2%80%9c%e6%9c%aa%e8%83%bd%e8%ae%a1%e7%ae%97%e6%9b%b4%e6%96%b0%e2%80%9d%e9%97%ae%e9%a2%98/#comments</comments>
		<pubDate>Mon, 02 Jun 2008 21:13:00 +0000</pubDate>
		<dc:creator>marshall</dc:creator>
				<category><![CDATA[csdn导入]]></category>
		<category><![CDATA[技术]]></category>
		<category><![CDATA[ubuntu]]></category>
		<category><![CDATA[升级]]></category>

		<guid isPermaLink="false">http://www.onlymarshall.com/?p=23</guid>
		<description><![CDATA[其实问题也不难，只要好好看提示就可以了。提示里说查看/var/log/dist-upgrade/里的内容，之前粗粗地看过一遍也没在意，main.log里没问题，term.log是空的，apt.log里东西挺多没仔细看。一直以为是cn99源的问题。换了cn.archive.ubuntu.com也失败。 今天把ubuntu-alternative给下了下来，发现还是这个问题。于是好好看了apt.log，发现有这么一句话： language-support-cn has broken dep on openoffice.org-l10n-zh-cn language-support-cn has broken dep on openoffice.org-l10n-zh-tw 难道这几个东西之间有冲突？卸掉openoffice l10n的包以后，问题解决。 结论：仔细看日志。]]></description>
			<content:encoded><![CDATA[<p>其实问题也不难，只要好好看提示就可以了。提示里说查看/var/log/dist-upgrade/里的内容，之前粗粗地看过一遍也没在意，main.log里没问题，term.log是空的，apt.log里东西挺多没仔细看。一直以为是cn99源的问题。换了cn.archive.ubuntu.com也失败。<br />
今天把ubuntu-alternative给下了下来，发现还是这个问题。于是好好看了apt.log，发现有这么一句话：</p>
<blockquote><p>language-support-cn has broken dep on openoffice.org-l10n-zh-cn language-support-cn has broken dep on openoffice.org-l10n-zh-tw</p></blockquote>
<p>难道这几个东西之间有冲突？卸掉openoffice l10n的包以后，问题解决。</p>
<p>结论：仔细看日志。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.onlymarshall.com/2008/06/02/%e8%a7%a3%e5%86%b3ubuntu%e5%8d%87%e7%ba%a7804-%e2%80%9c%e6%9c%aa%e8%83%bd%e8%ae%a1%e7%ae%97%e6%9b%b4%e6%96%b0%e2%80%9d%e9%97%ae%e9%a2%98/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Google TreasureHunt</title>
		<link>http://www.onlymarshall.com/2008/05/30/google-treasurehunt/</link>
		<comments>http://www.onlymarshall.com/2008/05/30/google-treasurehunt/#comments</comments>
		<pubDate>Fri, 30 May 2008 10:50:00 +0000</pubDate>
		<dc:creator>marshall</dc:creator>
				<category><![CDATA[csdn导入]]></category>
		<category><![CDATA[技术]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://www.onlymarshall.com/?p=24</guid>
		<description><![CDATA[Google悉尼一个寻找工程师的做题站点。现在还只有3题，一周更新一题。题目难度不大，但是还挺锻炼编程或者思考能力的（虽然robot那题比较火星，最新一题似乎用硬算的） http://treasurehunt.appspot.com http://treasurehunt.appspot.com]]&#62;]]></description>
			<content:encoded><![CDATA[<p>Google悉尼一个寻找工程师的做题站点。现在还只有3题，一周更新一题。题目难度不大，但是还挺锻炼编程或者思考能力的（虽然robot那题比较火星，最新一题似乎用硬算的）</p>
<p>http://treasurehunt.appspot.com</p>
<p><![CDATA[Google悉尼一个寻找工程师的做题站点。现在还只有3题，一周更新一题。题目难度不大，但是还挺锻炼编程或者思考能力的（虽然robot那题比较火星，最新一题似乎用硬算的）</p>
<p>http://treasurehunt.appspot.com]]&gt;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.onlymarshall.com/2008/05/30/google-treasurehunt/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Upgrading to Spring Security 2.0(zz)</title>
		<link>http://www.onlymarshall.com/2008/05/04/upgrading-to-spring-security-20zz/</link>
		<comments>http://www.onlymarshall.com/2008/05/04/upgrading-to-spring-security-20zz/#comments</comments>
		<pubDate>Sun, 04 May 2008 18:42:00 +0000</pubDate>
		<dc:creator>marshall</dc:creator>
				<category><![CDATA[csdn导入]]></category>
		<category><![CDATA[技术]]></category>
		<category><![CDATA[acegi]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[spring]]></category>
		<category><![CDATA[spring security]]></category>

		<guid isPermaLink="false">http://www.onlymarshall.com/?p=25</guid>
		<description><![CDATA[原文：http://raibledesigns.com/rd/entry/upgrading_to_spring_security_2 就是appfuse作者的博客，做了一些精简 1. 包变化：org.acegisecurity  =&#62; org.springframework.security 2. 依赖变化（略，不用Maven） 3. tag标签的开头authz =&#62; security, 然后把taglib的关联项改为 &#60;%@ taglib uri="http://www.springframework.org/security/tags" prefix="security" %&#62; 4. web.xml，把&#60;filter-class&#62;改为org.springframework.web.filter.DelegatingFilterProxy，另外还要加上&#60;init-param&#62;标签 &#60;init-param&#62; &#60;param-name&#62;targetBeanName&#60;/param-name&#62; &#60;param-value&#62;springSecurityFilterChain&#60;/param-value&#62; &#60;/init-param&#62; 5. 修改security.xml,使用新的语法.根据作者的说法，AppFuse的security.xml的长度从177行下降到了33行,因为使用了很多convention over configuration的元素，如&#60;http auto-config=&#8221;true&#8221;/&#62;。关于语法，还需要一些实践把握。]]></description>
			<content:encoded><![CDATA[<p>原文：http://raibledesigns.com/rd/entry/upgrading_to_spring_security_2<br />
就是appfuse作者的博客，做了一些精简</p>
<p>1. 包变化：org.acegisecurity  =&gt; org.springframework.security<br />
2. 依赖变化（略，不用Maven）<br />
3. tag标签的开头authz =&gt; security, 然后把taglib的关联项改为</p>
<pre><span class="Code">&lt;%@ taglib uri="http://www.springframework.org/security/tags"
    prefix="security" %&gt;</span></pre>
<p>4. web.xml，把&lt;filter-class&gt;改为org.springframework.web.filter.DelegatingFilterProxy，另外还要加上&lt;init-param&gt;标签</p>
<pre><span class="Code">    &lt;init-param&gt;
        &lt;param-name&gt;targetBeanName&lt;/param-name&gt;
        &lt;param-value&gt;springSecurityFilterChain&lt;/param-value&gt;
    &lt;/init-param&gt;</span></pre>
<p>5. 修改security.xml,使用<a href="http://static.springframework.org/spring-security/site/reference/html/namespace-config.html">新的语法</a>.根据作者的说法，AppFuse的security.xml的长度从177行下降到了33行,因为使用了很多convention over configuration的元素，如&lt;http auto-config=&#8221;true&#8221;/&gt;。关于语法，还需要一些实践把握。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.onlymarshall.com/2008/05/04/upgrading-to-spring-security-20zz/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>java diff 及wiki相关</title>
		<link>http://www.onlymarshall.com/2008/04/17/java-diff-%e5%8f%8awiki%e7%9b%b8%e5%85%b3/</link>
		<comments>http://www.onlymarshall.com/2008/04/17/java-diff-%e5%8f%8awiki%e7%9b%b8%e5%85%b3/#comments</comments>
		<pubDate>Thu, 17 Apr 2008 10:14:00 +0000</pubDate>
		<dc:creator>marshall</dc:creator>
				<category><![CDATA[csdn导入]]></category>
		<category><![CDATA[技术]]></category>
		<category><![CDATA[diff]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://www.onlymarshall.com/?p=26</guid>
		<description><![CDATA[diff的原理在于找两个字符串之间的最大相同子串(Longest Common Subsequence)以及编辑距离，比较有名的实现是UnixLinux上常用的diff(GNU Diff)。 实现 Java里Diff的实现我找了一下，主要是两个，java-diff 和bsmi上的Diff ，前者为LGPL，后一个为GPL。其实代码也都不多，都实现了LCS算法。前一个协议上对我们比较有利，而且文档、测试和例子多一些。 JavaDiff里主要有两个类，Diff和Difference类。前者是算法，后者是差异的表示类。下面讲一下例子： Object[] a = new Object[] {         "a",         "b",         "c",         "d",         "e"     };     Object[] b = new Object[] {         "a",         "x",         "y",         "b",         "c",         "j",         "e",     };     Difference[] expected = new Difference[] {         new Difference(1, -1,  1,  2),         new Difference(3,  3,  5,  5),     };     Diff diff = new Diff(a, b);     List diffOut = diff.diff(); 差别有三处，用两个Difference对象表示。一个Difference对象表示替换，增加，删除。Difference的构造函数： public Difference(int delStart, int delEnd, int addStart, int addEnd) 如果delEnd或者addEnd为-1的话，就代表没有删除或者增加行为。 回到例子，两个字符串之间的差别在于，目标字符串在第1-2行(从0算起)增加了x,y，第3行的d被第5行的j替换。Difference虽然只说明了行号和动作，但我们可以推算出来增加了什么，删除了什么，替换了什么。下面是另一个更长的例子，来自测试用例： public void testStrings1()     {         Object[] a = new Object[] {             "a",             "b",             "c",             "e",             "h",             "j",             "l",             "m",             "n", [...]]]></description>
			<content:encoded><![CDATA[<p>diff的原理在于找两个字符串之间的最大相同子串(Longest Common Subsequence)以及编辑距离，比较有名的实现是UnixLinux上常用的diff(GNU Diff)。</p>
<h3 id="实现">实现<a class="anchor" title="Link to this section" href="http://www.ynstudio.com/cgi-bin/trac.cgi/pub/wiki/fw/diff#%E5%AE%9E%E7%8E%B0"><br />
</a></h3>
<p>Java里Diff的实现我找了一下，主要是两个，<a class="ext-link" href="http://www.incava.org/projects/java/java-diff/"><span class="icon">java-diff</span></a> 和bsmi上的<a class="ext-link" href="http://www.bmsi.com/java/#diff"><span class="icon">Diff</span></a> ，前者为LGPL，后一个为GPL。其实代码也都不多，都实现了LCS算法。前一个协议上对我们比较有利，而且文档、测试和例子多一些。</p>
<p>JavaDiff里主要有两个类，Diff和Difference类。前者是算法，后者是差异的表示类。下面讲一下例子：</p>
<pre class="wiki">
<div>
<div><img id="_26_96_Open_Image" onclick="this.style.display='none'; document.getElementById('_26_96_Open_Text').style.display='none'; document.getElementById('_26_96_Closed_Image').style.display='inline'; document.getElementById('_26_96_Closed_Text').style.display='inline';" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif" alt="" align="top" /><span>Object[] a </span><span>=</span><span> </span><span>new</span><span> Object[] </span><span id="_26_96_Open_Text"><span>{
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" alt="" align="top" />        </span><span>"</span><span>a</span><span>"</span><span>,
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" alt="" align="top" />        </span><span>"</span><span>b</span><span>"</span><span>,
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" alt="" align="top" />        </span><span>"</span><span>c</span><span>"</span><span>,
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" alt="" align="top" />        </span><span>"</span><span>d</span><span>"</span><span>,
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" alt="" align="top" />        </span><span>"</span><span>e</span><span>"</span><span>
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif" alt="" align="top" />    }</span></span><span>;
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" alt="" align="top" />
<img id="_130_227_Open_Image" onclick="this.style.display='none'; document.getElementById('_130_227_Open_Text').style.display='none'; document.getElementById('_130_227_Closed_Image').style.display='inline'; document.getElementById('_130_227_Closed_Text').style.display='inline';" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif" alt="" align="top" />    Object[] b </span><span>=</span><span> </span><span>new</span><span> Object[] </span><span id="_130_227_Open_Text"><span>{
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" alt="" align="top" />        </span><span>"</span><span>a</span><span>"</span><span>,
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" alt="" align="top" />        </span><span>"</span><span>x</span><span>"</span><span>,
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" alt="" align="top" />        </span><span>"</span><span>y</span><span>"</span><span>,
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" alt="" align="top" />        </span><span>"</span><span>b</span><span>"</span><span>,
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" alt="" align="top" />        </span><span>"</span><span>c</span><span>"</span><span>,
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" alt="" align="top" />        </span><span>"</span><span>j</span><span>"</span><span>,
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" alt="" align="top" />        </span><span>"</span><span>e</span><span>"</span><span>,
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif" alt="" align="top" />    }</span></span><span>;
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" alt="" align="top" />
<img id="_276_360_Open_Image" onclick="this.style.display='none'; document.getElementById('_276_360_Open_Text').style.display='none'; document.getElementById('_276_360_Closed_Image').style.display='inline'; document.getElementById('_276_360_Closed_Text').style.display='inline';" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif" alt="" align="top" />    Difference[] expected </span><span>=</span><span> </span><span>new</span><span> Difference[] </span><span id="_276_360_Open_Text"><span>{
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" alt="" align="top" />        </span><span>new</span><span> Difference(</span><span>1</span><span>, </span><span>-</span><span>1</span><span>,  </span><span>1</span><span>,  </span><span>2</span><span>),
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" alt="" align="top" />        </span><span>new</span><span> Difference(</span><span>3</span><span>,  </span><span>3</span><span>,  </span><span>5</span><span>,  </span><span>5</span><span>),
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif" alt="" align="top" />    }</span></span><span>;
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" alt="" align="top" />
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" alt="" align="top" />    Diff diff </span><span>=</span><span> </span><span>new</span><span> Diff(a, b);
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" alt="" align="top" />    List diffOut </span><span>=</span><span> diff.diff();
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" alt="" align="top" />
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" alt="" align="top" /></span></div>
</div>
</pre>
<p>差别有三处，用两个Difference对象表示。一个Difference对象表示替换，增加，删除。Difference的构造函数：</p>
<pre class="wiki">public Difference(int delStart, int delEnd, int addStart, int addEnd)</pre>
<p>如果delEnd或者addEnd为-1的话，就代表没有删除或者增加行为。</p>
<p>回到例子，两个字符串之间的差别在于，目标字符串在第1-2行(从0算起)增加了x,y，第3行的d被第5行的j替换。Difference虽然只说明了行号和动作，但我们可以推算出来增加了什么，删除了什么，替换了什么。下面是另一个更长的例子，来自测试用例：</p>
<pre class="wiki">
<div>
<div><img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" alt="" align="top" /><span>
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" alt="" align="top" />
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" alt="" align="top" /></span><span>public</span><span> </span><span>void</span><span> testStrings1()
<img id="_33_818_Open_Image" onclick="this.style.display='none'; document.getElementById('_33_818_Open_Text').style.display='none'; document.getElementById('_33_818_Closed_Image').style.display='inline'; document.getElementById('_33_818_Closed_Text').style.display='inline';" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif" alt="" align="top" />    </span><span id="_33_818_Open_Text"><span>{
<img id="_69_248_Open_Image" onclick="this.style.display='none'; document.getElementById('_69_248_Open_Text').style.display='none'; document.getElementById('_69_248_Closed_Image').style.display='inline'; document.getElementById('_69_248_Closed_Text').style.display='inline';" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif" alt="" align="top" />        Object[] a </span><span>=</span><span> </span><span>new</span><span> Object[] </span><span id="_69_248_Open_Text"><span>{
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" alt="" align="top" />            </span><span>"</span><span>a</span><span>"</span><span>,
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" alt="" align="top" />            </span><span>"</span><span>b</span><span>"</span><span>,
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" alt="" align="top" />            </span><span>"</span><span>c</span><span>"</span><span>,
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" alt="" align="top" />            </span><span>"</span><span>e</span><span>"</span><span>,
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" alt="" align="top" />            </span><span>"</span><span>h</span><span>"</span><span>,
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" alt="" align="top" />            </span><span>"</span><span>j</span><span>"</span><span>,
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" alt="" align="top" />            </span><span>"</span><span>l</span><span>"</span><span>,
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" alt="" align="top" />            </span><span>"</span><span>m</span><span>"</span><span>,
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" alt="" align="top" />            </span><span>"</span><span>n</span><span>"</span><span>,
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" alt="" align="top" />            </span><span>"</span><span>p</span><span>"</span><span>
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif" alt="" align="top" />        }</span></span><span>;
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" alt="" align="top" />
<img id="_286_499_Open_Image" onclick="this.style.display='none'; document.getElementById('_286_499_Open_Text').style.display='none'; document.getElementById('_286_499_Closed_Image').style.display='inline'; document.getElementById('_286_499_Closed_Text').style.display='inline';" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif" alt="" align="top" />        Object[] b </span><span>=</span><span> </span><span>new</span><span> Object[] </span><span id="_286_499_Open_Text"><span>{
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" alt="" align="top" />            </span><span>"</span><span>b</span><span>"</span><span>,
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" alt="" align="top" />            </span><span>"</span><span>c</span><span>"</span><span>,
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" alt="" align="top" />            </span><span>"</span><span>d</span><span>"</span><span>,
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" alt="" align="top" />            </span><span>"</span><span>e</span><span>"</span><span>,
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" alt="" align="top" />            </span><span>"</span><span>f</span><span>"</span><span>,
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" alt="" align="top" />            </span><span>"</span><span>j</span><span>"</span><span>,
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" alt="" align="top" />            </span><span>"</span><span>k</span><span>"</span><span>,
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" alt="" align="top" />            </span><span>"</span><span>l</span><span>"</span><span>,
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" alt="" align="top" />            </span><span>"</span><span>m</span><span>"</span><span>,
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" alt="" align="top" />            </span><span>"</span><span>r</span><span>"</span><span>,
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" alt="" align="top" />            </span><span>"</span><span>s</span><span>"</span><span>,
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" alt="" align="top" />            </span><span>"</span><span>t</span><span>"</span><span>
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif" alt="" align="top" />        }</span></span><span>;
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" alt="" align="top" />
<img id="_552_777_Open_Image" onclick="this.style.display='none'; document.getElementById('_552_777_Open_Text').style.display='none'; document.getElementById('_552_777_Closed_Image').style.display='inline'; document.getElementById('_552_777_Closed_Text').style.display='inline';" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif" alt="" align="top" />        Difference[] expected </span><span>=</span><span> </span><span>new</span><span> Difference[] </span><span id="_552_777_Open_Text"><span>{
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" alt="" align="top" />            </span><span>new</span><span> Difference(</span><span>0</span><span>,  </span><span>0</span><span>,  </span><span>0</span><span>, </span><span>-</span><span>1</span><span>),
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" alt="" align="top" />            </span><span>new</span><span> Difference(</span><span>3</span><span>, </span><span>-</span><span>1</span><span>,  </span><span>2</span><span>,  </span><span>2</span><span>),
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" alt="" align="top" />            </span><span>new</span><span> Difference(</span><span>4</span><span>,  </span><span>4</span><span>,  </span><span>4</span><span>,  </span><span>4</span><span>),
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" alt="" align="top" />            </span><span>new</span><span> Difference(</span><span>6</span><span>, </span><span>-</span><span>1</span><span>,  </span><span>6</span><span>,  </span><span>6</span><span>),
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" alt="" align="top" />            </span><span>new</span><span> Difference(</span><span>8</span><span>,  </span><span>9</span><span>,  </span><span>9</span><span>, </span><span>11</span><span>),
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif" alt="" align="top" />        }</span></span><span>;
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" alt="" align="top" />
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" alt="" align="top" />        runDiff(a, b, expected);
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif" alt="" align="top" />    }</span></span></div>
</div>
</pre>
<p>上面比较的都是一个个字符串的差异，推广一下，把每一行文本当作一个字母，就可以得到文件的差异。在java-diff的etc下有一个FileDiff.java，是一个很好的参考。得到之间的差异之后，我们要把这个差异表示出来，这个需要包装一下，不过难度不大。</p>
<h3 id="版本保存">版本保存<a class="anchor" title="Link to this section" href="http://www.ynstudio.com/cgi-bin/trac.cgi/pub/wiki/fw/diff#%E7%89%88%E6%9C%AC%E4%BF%9D%E5%AD%98"><br />
</a></h3>
<p>还有一个wiki版本的保存问题。大的维基引擎如MediaWiki(就是维基百科那个，顺便说一下，维基百科的英文版终于可以访问了)没时间研究，就是 JSPWiki也没来得及看)(JSPWiki连数据库也不用，Web用自己写的框架，可读性可能比较不行)。只研究了trac的wiki实现。trac 的wiki实现很简单，就是把每一个版本都保存在数据库，毕竟都是文本的，还可以接受。每次比较的时候就从数据库里取两个版本出来做一个diff，具体实 现在PYTHON/site-packages/trac/wiki/web_ui.py(_render_diff函数)。trac提供两种形式的 diff结果，一个是tabular的表格形式，就是很直观的对比，还有一个是Unified的形式，也就是经常看见的diff结果。这是通过页面上 javascript读table里的文字转换成Unified格式的diff文本，虽然个人不推荐这种方式。wiki的文本修改又有一个特点，就是每一 行其实内容可能比较多，只改了几个字，这样就要对这一行的两个版本再做一个diff，然后把删除的文本用&lt;del&gt;标签，增加的文本用 &lt;ins&gt;标签展示出来。</p>
<p>最后提一下JSR-170，一个用来管理仓库内容（主要是大型CMS）的API，支持版本控制，存储多元化，很复杂，有两个商业实现和一个Apache JackRabbit的开源实现，<a class="ext-link" href="http://www.ibm.com/developerworks/cn/java/j-jcr/"><span class="icon">这里</span></a> 是一个参考资料。JSR170也是里面的例子也是把每一个版本都存储下来。</p>
<h3 id="参考资料">参考资料<a class="anchor" title="Link to this section" href="http://www.ynstudio.com/cgi-bin/trac.cgi/pub/wiki/fw/diff#%E5%8F%82%E8%80%83%E8%B5%84%E6%96%99"><br />
</a></h3>
<ul>
<li><a class="ext-link" href="http://en.wikipedia.org/wiki/Diff"><span class="icon">Wikipedia:diff</span></a></li>
<li><a class="ext-link" href="http://www.incava.org/projects/java/java-diff/"><span class="icon">java-diff</span></a></li>
<li><a class="ext-link" href="http://www.bmsi.com/java/#diff"><span class="icon">Diff</span></a></li>
<li><a class="ext-link" href="http://www.jspwiki.org/wiki/Main"><span class="icon">JSPWiki</span></a></li>
<li><a class="ext-link" href="http://www.ibm.com/developerworks/cn/java/j-jcr/"><span class="icon">Java Content Repository API 简介</span></a></li>
</ul>
<pre class="wiki">
<div style="border: 0.5pt solid windowtext; padding: 4px 5.4pt; background: #e6e6e6 none repeat scroll 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; width: 95%;">
<div><span style="color: #000000;">

</span></div>
</div>
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.onlymarshall.com/2008/04/17/java-diff-%e5%8f%8awiki%e7%9b%b8%e5%85%b3/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>看来最好的代码阅读器还是IDE</title>
		<link>http://www.onlymarshall.com/2008/03/12/%e7%9c%8b%e6%9d%a5%e6%9c%80%e5%a5%bd%e7%9a%84%e4%bb%a3%e7%a0%81%e9%98%85%e8%af%bb%e5%99%a8%e8%bf%98%e6%98%afide-2/</link>
		<comments>http://www.onlymarshall.com/2008/03/12/%e7%9c%8b%e6%9d%a5%e6%9c%80%e5%a5%bd%e7%9a%84%e4%bb%a3%e7%a0%81%e9%98%85%e8%af%bb%e5%99%a8%e8%bf%98%e6%98%afide-2/#comments</comments>
		<pubDate>Wed, 12 Mar 2008 18:33:00 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[csdn导入]]></category>
		<category><![CDATA[Space导入]]></category>
		<category><![CDATA[技术]]></category>
		<category><![CDATA[IDE]]></category>

		<guid isPermaLink="false">http://www.onlymarshall.com/?p=163</guid>
		<description><![CDATA[这两天要研究下Acegi，给人做技术讲座，内容要求和Acegi有关。于是想找个代码阅读器来看代码。 第一个想到的就是SourceInsight，但考虑到SourceInsight还是收费软件，于是转向开源产品。搜了半天，找出一个Code Browser，没想到功能比Notepad++还差一些。于是无奈就用Eclispe看看代码。因为Acegi和Spring结合得很紧密，顺便把Spring IDE的帮助看了一下，第一次用了起来，觉得很好用啊。这么多年开发Spring应用居然都没好好用Spring IDE，真是惭愧。 Attach上Source的Eclispe+Spring IDE看起Acegi代码果然非常方便，按住Ctrl进行智能导航，还有引用查找等。怪不得一直找不到合适的开源代码查看器，原来IDE就已经这么好用了。]]></description>
			<content:encoded><![CDATA[<p>这两天要研究下Acegi，给人做技术讲座，内容要求和Acegi有关。于是想找个代码阅读器来看代码。</p>
<p>第一个想到的就是SourceInsight，但考虑到SourceInsight还是收费软件，于是转向开源产品。搜了半天，找出一个Code Browser，没想到功能比Notepad++还差一些。于是无奈就用Eclispe看看代码。因为Acegi和Spring结合得很紧密，顺便把Spring IDE的帮助看了一下，第一次用了起来，觉得很好用啊。这么多年开发Spring应用居然都没好好用Spring IDE，真是惭愧。</p>
<p>Attach上Source的Eclispe+Spring IDE看起Acegi代码果然非常方便，按住Ctrl进行智能导航，还有引用查找等。怪不得一直找不到合适的开源代码查看器，原来IDE就已经这么好用了。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.onlymarshall.com/2008/03/12/%e7%9c%8b%e6%9d%a5%e6%9c%80%e5%a5%bd%e7%9a%84%e4%bb%a3%e7%a0%81%e9%98%85%e8%af%bb%e5%99%a8%e8%bf%98%e6%98%afide-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>web分页的设计原则</title>
		<link>http://www.onlymarshall.com/2007/10/13/web%e5%88%86%e9%a1%b5%e7%9a%84%e8%ae%be%e8%ae%a1%e5%8e%9f%e5%88%99/</link>
		<comments>http://www.onlymarshall.com/2007/10/13/web%e5%88%86%e9%a1%b5%e7%9a%84%e8%ae%be%e8%ae%a1%e5%8e%9f%e5%88%99/#comments</comments>
		<pubDate>Sat, 13 Oct 2007 23:16:00 +0000</pubDate>
		<dc:creator>marshall</dc:creator>
				<category><![CDATA[csdn导入]]></category>
		<category><![CDATA[技术]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://www.onlymarshall.com/?p=28</guid>
		<description><![CDATA[1. 提供大面积的点击区域 2. 不要使用下划线 3. 明显地标识出当前页码 4. 格开各页的链接 5. 提供前一页和后一页 6. 使用第一页和最后一页的链接，当有必要时 7. 把第一页和最后一页的链接放在最外面，如下 « First    ‹ Previous    Current    Next ›    Last »]]></description>
			<content:encoded><![CDATA[<p>1. 提供大面积的点击区域<br />
2. 不要使用下划线<br />
3. 明显地标识出当前页码<br />
4. 格开各页的链接<br />
5. 提供前一页和后一页<br />
6. 使用第一页和最后一页的链接，当有必要时<br />
7. 把第一页和最后一页的链接放在最外面，如下</p>
<p>« First    ‹ Previous    Current    Next ›    Last »</p>
]]></content:encoded>
			<wfw:commentRss>http://www.onlymarshall.com/2007/10/13/web%e5%88%86%e9%a1%b5%e7%9a%84%e8%ae%be%e8%ae%a1%e5%8e%9f%e5%88%99/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Validator原来不可以Render两次</title>
		<link>http://www.onlymarshall.com/2007/07/19/validator%e5%8e%9f%e6%9d%a5%e4%b8%8d%e5%8f%af%e4%bb%a5render%e4%b8%a4%e6%ac%a1/</link>
		<comments>http://www.onlymarshall.com/2007/07/19/validator%e5%8e%9f%e6%9d%a5%e4%b8%8d%e5%8f%af%e4%bb%a5render%e4%b8%a4%e6%ac%a1/#comments</comments>
		<pubDate>Thu, 19 Jul 2007 22:58:00 +0000</pubDate>
		<dc:creator>marshall</dc:creator>
				<category><![CDATA[csdn导入]]></category>
		<category><![CDATA[ASP.NET]]></category>

		<guid isPermaLink="false">http://www.onlymarshall.com/?p=29</guid>
		<description><![CDATA[公司有一个简单功能的PrintPanel，这两天却一直用不上，报以下的错误： [ArgumentException: 已存在具有相同键的条目。]    System.Collections.Specialized.ListDictionary.Add(Object key, Object value) +283    System.Web.UI.ClientScriptManager.RegisterExpandoAttribute(String controlId, String attributeName, String attributeValue, Boolean encode) +237    System.Web.UI.WebControls.BaseValidator.AddExpandoAttribute(Page page, HtmlTextWriter writer, String controlId, String attributeName, String attributeValue, Boolean encode) +105    System.Web.UI.WebControls.BaseValidator.AddAttributesToRender(HtmlTextWriter writer) +188    System.Web.UI.WebControls.RequiredFieldValidator.AddAttributesToRender(HtmlTextWriter writer) +21    System.Web.UI.WebControls.WebControl.RenderBeginTag(HtmlTextWriter writer) +17    System.Web.UI.WebControls.BaseValidator.Render(HtmlTextWriter writer) +459    System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) +53    System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter) +294    System.Web.UI.Control.RenderControl(HtmlTextWriter writer) +24    System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) +199    System.Web.UI.Control.RenderChildren(HtmlTextWriter writer) +21    System.Web.UI.WebControls.WebControl.RenderContents(HtmlTextWriter writer) +7    System.Web.UI.WebControls.WebControl.Render(HtmlTextWriter writer) +29 实在是看不懂，而.NET又不像Java一样是开源的，可以一直跟进去看代码。网上又查不到错误。只好还是回到唯一的线索：StackTrace。发现是从BaseValidator.AddExpandoAttribute这个私有方法抛上来的，于是把Validator都去掉了，发现没问题了。研究了一会儿过后，发现应该是ClientScriptManager里把相同的Javascript给注册了两次造成的。把Validator设成Disable没用，只有Visible=false管用。]]></description>
			<content:encoded><![CDATA[<p>公司有一个简单功能的PrintPanel，这两天却一直用不上，报以下的错误：<br />
<span style="font-family: Arial, Helvetica, Geneva, SunSans-Regular, sans-serif;"></p>
<pre>
<div>
<div><span><img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" alt="" align="top" /><span>[ArgumentException: 已存在具有相同键的条目。]
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" alt="" align="top" />   System.Collections.Specialized.ListDictionary.Add(Object key, Object value) </span><span>+</span><span>283</span><span>
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" alt="" align="top" />   System.Web.UI.ClientScriptManager.RegisterExpandoAttribute(String controlId, String attributeName, String attributeValue, Boolean encode) </span><span>+</span><span>237</span><span>
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" alt="" align="top" />   System.Web.UI.WebControls.BaseValidator.AddExpandoAttribute(Page page, HtmlTextWriter writer, String controlId, String attributeName, String attributeValue, Boolean encode) </span><span>+</span><span>105</span><span>
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" alt="" align="top" />   System.Web.UI.WebControls.BaseValidator.AddAttributesToRender(HtmlTextWriter writer) </span><span>+</span><span>188</span><span>
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" alt="" align="top" />   System.Web.UI.WebControls.RequiredFieldValidator.AddAttributesToRender(HtmlTextWriter writer) </span><span>+</span><span>21</span><span>
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" alt="" align="top" />   System.Web.UI.WebControls.WebControl.RenderBeginTag(HtmlTextWriter writer) </span><span>+</span><span>17</span><span>
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" alt="" align="top" />   System.Web.UI.WebControls.BaseValidator.Render(HtmlTextWriter writer) </span><span>+</span><span>459</span><span>
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" alt="" align="top" />   System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) </span><span>+</span><span>53</span><span>
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" alt="" align="top" />   System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter) </span><span>+</span><span>294</span><span>
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" alt="" align="top" />   System.Web.UI.Control.RenderControl(HtmlTextWriter writer) </span><span>+</span><span>24</span><span>
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" alt="" align="top" />   System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) </span><span>+</span><span>199</span><span>
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" alt="" align="top" />   System.Web.UI.Control.RenderChildren(HtmlTextWriter writer) </span><span>+</span><span>21</span><span>
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" alt="" align="top" />   System.Web.UI.WebControls.WebControl.RenderContents(HtmlTextWriter writer) </span><span>+</span><span>7</span><span>
<img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" alt="" align="top" />   System.Web.UI.WebControls.WebControl.Render(HtmlTextWriter writer) </span><span>+</span><span>29</span></span></div>
</div>
</pre>
<p></span> 实在是看不懂，而.NET又不像Java一样是开源的，可以一直跟进去看代码。网上又查不到错误。只好还是回到唯一的线索：StackTrace。发现是从BaseValidator.AddExpandoAttribute这个私有方法抛上来的，于是把Validator都去掉了，发现没问题了。研究了一会儿过后，发现应该是ClientScriptManager里把相同的Javascript给注册了两次造成的。把Validator设成Disable没用，只有Visible=false管用。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.onlymarshall.com/2007/07/19/validator%e5%8e%9f%e6%9d%a5%e4%b8%8d%e5%8f%af%e4%bb%a5render%e4%b8%a4%e6%ac%a1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
<br />
<b>Warning</b>:  fsockopen() has been disabled for security reasons in <b>/home/onlymars/public_html/wp/wp-includes/class-snoopy.php</b> on line <b>1148</b><br />

