﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-JBahamut</title><link>http://www.blogjava.net/JBahamut/</link><description>&lt;br&gt;最“邪恶”的问题是那些需要解决或者部分解决才能够定义的问题</description><language>zh-cn</language><lastBuildDate>Wed, 15 Oct 2008 19:29:27 GMT</lastBuildDate><pubDate>Wed, 15 Oct 2008 19:29:27 GMT</pubDate><ttl>60</ttl><item><title>coloring diff</title><link>http://www.blogjava.net/JBahamut/archive/2008/09/27/231394.html</link><dc:creator>JBahamut</dc:creator><author>JBahamut</author><pubDate>Fri, 26 Sep 2008 16:29:00 GMT</pubDate><guid>http://www.blogjava.net/JBahamut/archive/2008/09/27/231394.html</guid><wfw:comment>http://www.blogjava.net/JBahamut/comments/231394.html</wfw:comment><comments>http://www.blogjava.net/JBahamut/archive/2008/09/27/231394.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/JBahamut/comments/commentRss/231394.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/JBahamut/services/trackbacks/231394.html</trackback:ping><description><![CDATA[用惯了git觉得没有颜色的diff实在是无法忍受，还好emacs可以配置diff-mode的颜色，但svn diff却没有发现有参数可以指定highlight diff的，于是自己写了一个。是一个bash脚本，用到了sed，linux下肯定没有问题；windows下需要装MinGW的bash，sed还有msys<br />
<br />
<br />
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: rgb(0, 0, 0);">#!/bin/sh<br />
<br />
case&nbsp;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">$TERM</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&nbsp;in<br />
msys)<br />
CONTEXT_COLOR</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">[37m</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"><br />
ADD_COLOR</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">[32m</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"><br />
DELETE_COLOR</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">[31m</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"><br />
LOCATION_COLOR</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">[36m</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"><br />
INDEX_COLOR</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">[35m</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"><br />
NORM_COLOR</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">[0m</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"><br />
</span><span style="color: rgb(0, 128, 0);">;</span><span style="color: rgb(0, 128, 0);">;</span><span style="color: rgb(0, 128, 0);"><br />
</span><span style="color: rgb(0, 0, 0);">*)<br />
CONTEXT_COLOR</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">`tput&nbsp;setaf&nbsp;</span><span style="color: rgb(0, 0, 0);">7</span><span style="color: rgb(0, 0, 0);">`<br />
ADD_COLOR</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">`tput&nbsp;setaf&nbsp;</span><span style="color: rgb(0, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">`<br />
DELETE_COLOR</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">`tput&nbsp;setaf&nbsp;</span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">`<br />
LOCATION_COLOR</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">`tput&nbsp;setaf&nbsp;</span><span style="color: rgb(0, 0, 0);">6</span><span style="color: rgb(0, 0, 0);">`<br />
INDEX_COLOR</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">`tput&nbsp;setaf&nbsp;</span><span style="color: rgb(0, 0, 0);">5</span><span style="color: rgb(0, 0, 0);">`<br />
NORM_COLOR</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">`tput&nbsp;sgr0`<br />
</span><span style="color: rgb(0, 128, 0);">;</span><span style="color: rgb(0, 128, 0);">;</span><span style="color: rgb(0, 128, 0);"><br />
</span><span style="color: rgb(0, 0, 0);">esac<br />
<br />
svn&nbsp;diff&nbsp;$*&nbsp;|<br />
sed&nbsp;-e&nbsp;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">s/^+.*/${ADD_COLOR}&amp;${NORM_COLOR}/g</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&nbsp;-e&nbsp;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">s/^-.*/${DELETE_COLOR}&amp;${NORM_COLOR}/g</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&nbsp;\<br />
&nbsp;&nbsp;&nbsp;&nbsp;-e&nbsp;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">s/^@@.*/${LOCATION_COLOR}&amp;${NORM_COLOR}/g</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&nbsp;-e&nbsp;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">s/^[iI]ndex.*/${INDEX_COLOR}&amp;${NORM_COLOR}/g</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&nbsp;\<br />
&nbsp;&nbsp;&nbsp;&nbsp;-e&nbsp;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">s/.*/${CONTEXT_COLOR}&amp;${NORM_COLOR}/g</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&nbsp;|<br />
${PAGER:-less&nbsp;-QRS}<br />
</span></div>
<br />
由于windows上没有tput方法所以只能直接写操作字符，上面方块的字符可以通过下面命令将结果输出到文件得到<br />
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: rgb(0, 0, 0);">echo&nbsp;-e&nbsp;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">\033[31mtest</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&nbsp;&gt;&nbsp;out</span></div>
<br />
<span style="color: rgb(0, 0, 0);">tput&nbsp;setbf [0-7] 可以用来设置背景颜色。这有有颜色的代码:<br />
</span>http://www.frexx.de/xterm-256-notes/<br />
<br />
<br />
<img src ="http://www.blogjava.net/JBahamut/aggbug/231394.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/JBahamut/" target="_blank">JBahamut</a> 2008-09-27 00:29 <a href="http://www.blogjava.net/JBahamut/archive/2008/09/27/231394.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>如何用C++写出不依赖于stdlibc++.so的程序</title><link>http://www.blogjava.net/JBahamut/archive/2008/07/31/218866.html</link><dc:creator>JBahamut</dc:creator><author>JBahamut</author><pubDate>Wed, 30 Jul 2008 16:05:00 GMT</pubDate><guid>http://www.blogjava.net/JBahamut/archive/2008/07/31/218866.html</guid><wfw:comment>http://www.blogjava.net/JBahamut/comments/218866.html</wfw:comment><comments>http://www.blogjava.net/JBahamut/archive/2008/07/31/218866.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/JBahamut/comments/commentRss/218866.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/JBahamut/services/trackbacks/218866.html</trackback:ping><description><![CDATA[这个题目一看就很欠扁，既然用C++又不想依赖stdlibc++标准库这不是有病吗？其意义究竟<br />
何在？这实际上就是我最近被赋予的光荣使命，神奇的是原来真的可以做到！！！与标准库<br />
斗于编译器斗，其乐无穷~~~收获也不是没有，对C++，对编译器的认识又更近了一步，虽然<br />
本来就没有什么认识。<br />
<br />
故事是这样开始的，我们为公司的某产品开发了一个模块，其实就是两动态库。本来这东西<br />
也不是我们开发的，我们只是负责移植到公司的12个平台上。本来一切都很顺利，不幸的事<br />
是在test快要结束的时候发生的，某平台是build机器上与test机器上stdlibc++.so版本不<br />
一致，我们的so竟然不能load，这不是再正常不过的事情么，装一个需要的版本就一了百了<br />
了，但是。。但是可恶的印度人懒得装不说，还指责是我们的问题，说引入了新的依赖，不<br />
行不行就是不行，我的奇妙旅行就此开始了。（这个问题也可以通过静态链接stdlibc++解<br />
决，貌似他们没搞定，我也没有深入研究）<br />
<br />
总的来说C++对stdlibc++.so的依赖主要由以下几个部分产生：<br />
1. 对C++标准库的依赖<br />
&nbsp;&nbsp; 简单的看就是 include C++的头文件（不以.h结尾）<br />
&nbsp;&nbsp; 如果你大量使用的STL...请回吧，不送了。还好我们只使用到了vector和dqueue，简<br />
&nbsp;&nbsp; 单实现了一个，凑合着用了<br />
2. new 和 delete 操作符<br />
&nbsp;&nbsp; 这两个操作符实际上完成了两部分工作，首先是分配内存，其次是调用相应的构造/析构<br />
&nbsp;&nbsp; 方法。而对于gcc来说，分配内存的工作是在stdlibc++.so中完成的，所以会造成依赖，<br />
&nbsp;&nbsp; 幸运的是重载这两个操作符就是重载分配内存的部分，所以我们只需要用malloc/free简<br />
&nbsp;&nbsp; 单的重载这两个操作符就ok了<br />
3. 纯虚函数<br />
&nbsp;&nbsp; 使用继承和虚函数都是没问题的（竟然没有依赖rtti，需要继续研究），但纯虚函数是<br />
&nbsp;&nbsp; 不行的，这个估计跟实现有关。最简单的方法就是将所用的纯虚函数改为虚函数再添加<br />
&nbsp;&nbsp; 默认实现。<br />
4. exception<br />
&nbsp;&nbsp; 这是最麻烦的部分，如果exception用的不多，直接将exception作为返回值返回了结<br />
&nbsp;&nbsp; （原来有返回值的放到输出参数里），每次调用check一下，根据原来代码中的逻辑要么<br />
&nbsp;&nbsp; 返回exception（没有catch住该exception），要么做catch中的事。理论上是没问题的<br />
&nbsp;&nbsp; 就是麻烦点，代码ugly点，可能再用点goto也没啥大问题。<br />
&nbsp;&nbsp; 这里要介绍的是另一种方法，通过使用setjmp和longjmp实现exception机制，再利用宏<br />
&nbsp;&nbsp; 替换原来代码中的try throw catch，详细的就不写了，我也是从网上看到的参见：<br />
&nbsp;&nbsp; <a title="Exception Handling in C without C++" href="http://www.on-time.com/ddj0011.htm">Exception Handling in C without C++</a><br />
&nbsp;&nbsp; <a title="cexcept" href="http://www.nicemice.net/cexcept">cexcept</a>：sourceforge上的开源项目<br />
&nbsp;&nbsp; 看了就能明白，但要实现完整的exception机制还是有难度的，包括try catch的嵌<br />
&nbsp;&nbsp; 套，exception的继承，多catch等。我们现在也没能实现多catch，宏的能力还是有限啊。<br />
5. rtti<br />
&nbsp;&nbsp; 这是C++特用的东西，严重依赖于stdlibc++.so，凡是动态的类型判断都是要禁止<br />
&nbsp;&nbsp; 的，catch为了判断exception的类型就会使用到rtti，dynmaic_cast也会有同样的问<br />
&nbsp;&nbsp; 题，typeid之类的东西更是永不得的。<br />
6. 编译参数<br />
&nbsp;&nbsp; 当你完全完成了上面的工作，基本上就大功告成了，不过现代的编译器那是相当的聪明，在<br />
&nbsp;&nbsp; 背后为我们默默无闻的做了很多事情，比如对于c++的代码会默认帮你生成处理<br />
&nbsp;&nbsp; exception的代码，所以需要用 -fno-exceptions 来防止这样的事情发生，然而这还不<br />
&nbsp;&nbsp; 够，-fno-exceptions 和 -fno-rtti 必须是要同时使用的，只使用 -fno-exceptions只<br />
&nbsp;&nbsp; 能得到个半吊子的结果：依然会有rtti的代码生成（不知道gcc那帮人是怎么想的）。<br />
&nbsp;&nbsp; 你以为终于可以结束了吗？<br />
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);">&nbsp;(your_gcc_version&nbsp;</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">3.4</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">6</span><span style="color: rgb(0, 0, 0);">)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;goHome();<br />
&nbsp;&nbsp;&nbsp;&nbsp;happyEnding();<br />
}&nbsp;</span><span style="color: rgb(0, 0, 255);">else</span><span style="color: rgb(0, 0, 0);">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;听我慢慢道来();<br />
}</span></div>
&nbsp;&nbsp; 在gcc 3.4.6 以上版本会为local static生成保证线程安全的代码，不幸的是这些代码<br />
&nbsp;&nbsp; 是依赖于stdlibc++.so的，所以我们要禁止他们！！！请使用<br />
&nbsp;&nbsp; -fno-threadsafe-statics，并确保这些static代码是线程安全的<br />
<br />
终于写完了，估计没有人会再有这样奇怪的需求了，写在这里留作纪念。<br />
&nbsp; &nbsp;<br />
另外提一下模板是可以使用的，因为只是在编译时生成代码，不关标准库的事。<br />
<br />
<img src ="http://www.blogjava.net/JBahamut/aggbug/218866.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/JBahamut/" target="_blank">JBahamut</a> 2008-07-31 00:05 <a href="http://www.blogjava.net/JBahamut/archive/2008/07/31/218866.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>读 Erlang mailing list 有感</title><link>http://www.blogjava.net/JBahamut/archive/2008/05/28/203362.html</link><dc:creator>JBahamut</dc:creator><author>JBahamut</author><pubDate>Tue, 27 May 2008 16:32:00 GMT</pubDate><guid>http://www.blogjava.net/JBahamut/archive/2008/05/28/203362.html</guid><wfw:comment>http://www.blogjava.net/JBahamut/comments/203362.html</wfw:comment><comments>http://www.blogjava.net/JBahamut/archive/2008/05/28/203362.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/JBahamut/comments/commentRss/203362.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/JBahamut/services/trackbacks/203362.html</trackback:ping><description><![CDATA[多谢 erlang-china 的提醒，今天从 mailing list 中翻出了关于RPC的讨论，深有感触 -- 牛人就是牛人！！！<br />
<br />
关于 RPC is bad 的主要论点如下：<br />
<pre wrap=""><span style="font-size: 18pt;"><span style="color: red;">The fundamental problem of RPC, which is trying to make remote calls look local, is based on essentially trying to ignore the problems covered by the fallacies or trying to pretend they don't even exist</span></span><br />
<br />
严重同意，理由如下：<br />
<br />
<strong>Network partitions are real, timeouts are real, remote host and service<br />
crashes are real, the need for piecemeal system upgrade and handling<br />
version differences between systems is real, etc. The distributed<br />
systems programmer </strong><strong>*must* deal with these and other issues because<br />
they affect different applications very differently.</strong><br />
<br />
这一点非常赞同，也深有同感。在做FileServer的时候所有的节点都是通过RMI进行通讯，最初使用RMI的目的就是<br />
简化网络部分的开发，对于一般的开发人员无须理解RMI，动态代理，只需要像使用本地方法一样就可以访问远程<br />
节点。这种方案确实很好的隐藏了网络细节，使网络对开发人员完全透明，但有个问题始终无法很好的处理：<strong>异常。<br />
</strong>网络错误是随时都有可能发生的，对于不同的错误需要根据环境和需要做具体的处理，比如，多试几次，尝试下一个<br />
节点，对于无法处理的还可以直接抛出。而这种策略的选择和使用必须由应用逻辑层完成，可是应用层假设是不知道<br />
网络存在的，它甚至无法知道自己调用的方法中哪个是远程调用，哪个是本地调用。这种矛盾从根本上说明了网络的<br />
复杂性和多样性是开发分布式应用的程序员必须面对的，是逃不掉的，要直面这惨淡的人生T_T<br />
<br />
下面阐述了使用类型系统的缺陷：<br />
Such systems also have problems with impedance mismatch between the<br />
IDL and whatever languages you're translating it to. If the IDL is<br />
minimal so that it can be used with a wide variety of programming<br />
languages, it means advanced features of well-stocked languages like<br />
Java and C++ can't be used. OTOH if you make the IDL more powerful so<br />
that it's closer to such languages, then translating it to C or other<br />
more basic languages becomes quite difficult.<br />
On top of all that, no matter how you design the IDL type system, all <br />
the types won't -- indeed, can't -- map cleanly into every desired <br />
programming language.<br />
<br />
类型系统一直都在进化，从弱到强到动态，你相信会有一种类型系统可以和所有<br />
的其他语言进行完美的映射吗？如果真存在，类型系统的进化就毫无意义了。定义<br />
一个新的语言，然后映射到其他语言，最后号称&#8220;我是跨语言跨平台的！&#8221;，这种<br />
解决问题的方式根本就是有问题的。WSDL使用XML描述，有着更好的可扩展性，只是<br />
酒瓶换新酒，根烂了，再换也没用。<br />
<br />
Ultimately, RPC is a leaky abstraction. It can't hide what it tries to<br />
hide, and because of that, it can easily make the overall problem more<br />
difficult to deal with by adding a lot of accidental complexity.<br />
<br />
下面对为什么 message queuing system 适合分布式系统做了很好的总结：<br />
Message queuing systems work well because (in no particular<br />
order):<br />
<br />
* they don't pretend to be programming language procedure or method<br />
calls, so they avoid the associated impedance mismatch problems<br />
* they don't try to hide distributed systems issues<br />
* coupling is low -- drop a message into a queue here, pick up a<br />
message from a queue there<br />
* queues can be persistent, or more generally, delivery guarantees can<br />
be varied as needed<br />
* asynchrony<br />
* payloads need not conform to some made-up IDL type system<br />
* getting two different messaging systems to interoperate is easier<br />
than getting two different RPC or distributed object systems to<br />
interoperate<br />
</pre>
这和我在自己的硕士论文中的观点有些相似：完全使用消息机制进行构件间的通讯。构件可以<br />
是分布式的或在容器中的，基于消息的通讯都是完全适用的。对于网络应用同样如此。对于流行<br />
的网络协议，HTTP，FTP，LDAP 等等都是消息式的，完全经历了时间的考验。<br />
<br />
<img src ="http://www.blogjava.net/JBahamut/aggbug/203362.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/JBahamut/" target="_blank">JBahamut</a> 2008-05-28 00:32 <a href="http://www.blogjava.net/JBahamut/archive/2008/05/28/203362.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Two very little tools for git</title><link>http://www.blogjava.net/JBahamut/archive/2008/05/27/203081.html</link><dc:creator>JBahamut</dc:creator><author>JBahamut</author><pubDate>Mon, 26 May 2008 16:57:00 GMT</pubDate><guid>http://www.blogjava.net/JBahamut/archive/2008/05/27/203081.html</guid><wfw:comment>http://www.blogjava.net/JBahamut/comments/203081.html</wfw:comment><comments>http://www.blogjava.net/JBahamut/archive/2008/05/27/203081.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/JBahamut/comments/commentRss/203081.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/JBahamut/services/trackbacks/203081.html</trackback:ping><description><![CDATA[Fist one, I call it git2svn. We know 'git diff' has the format like this:<br />
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: rgb(0, 0, 0);">diff&nbsp;</span><span style="color: rgb(0, 0, 0);">--</span><span style="color: rgb(0, 0, 0);">git&nbsp;a</span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">hello.git&nbsp;b</span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">hello.git<br />
index&nbsp;808c280..3e60fff&nbsp;</span><span style="color: rgb(0, 0, 0);">100644</span><span style="color: rgb(0, 0, 0);"><br />
</span><span style="color: rgb(0, 0, 0);">---</span><span style="color: rgb(0, 0, 0);">&nbsp;a</span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">hello.git<br />
</span><span style="color: rgb(0, 0, 0);">+++</span><span style="color: rgb(0, 0, 0);">&nbsp;b</span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">hello.git<br />
@@&nbsp;</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);">3</span><span style="color: rgb(0, 0, 0);">&nbsp;@@<br />
&nbsp;</span><span style="color: rgb(0, 0, 0);">111111</span><span style="color: rgb(0, 0, 0);"><br />
&nbsp;sdfsfsdf<br />
</span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);">111</span><span style="color: rgb(0, 0, 0);"><br />
</span></div>
<br />
It's different with svn diff output format which we are familiar with, although patch can work with this format, but it would be strange if we applied a patch with git format to a open source project which use SVN as source repository. That's why i wrote git2svn, which convert git diff format to svn diff format. It's very very simple, only one line:<br />
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: rgb(0, 0, 0);">#</span><span style="color: rgb(0, 0, 0);">!</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">bin</span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">sh<br />
<br />
#&nbsp;convert&nbsp;git&nbsp;diff&nbsp;output&nbsp;to&nbsp;svn&nbsp;format:<br />
#&nbsp;git&nbsp;diff&nbsp;like:<br />
#<br />
#&nbsp;diff&nbsp;</span><span style="color: rgb(0, 0, 0);">--</span><span style="color: rgb(0, 0, 0);">git&nbsp;a</span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">hello.git&nbsp;b</span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">hello.git<br />
#&nbsp;index&nbsp;90d2950..808c280&nbsp;</span><span style="color: rgb(0, 0, 0);">100644</span><span style="color: rgb(0, 0, 0);"><br />
#&nbsp;</span><span style="color: rgb(0, 0, 0);">---</span><span style="color: rgb(0, 0, 0);">&nbsp;a</span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">hello.git<br />
#&nbsp;</span><span style="color: rgb(0, 0, 0);">+++</span><span style="color: rgb(0, 0, 0);">&nbsp;b</span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">hello.git<br />
#<br />
#&nbsp;after&nbsp;converting,&nbsp;it</span><span style="color: rgb(0, 0, 0);">'</span><span style="color: rgb(0, 0, 0);">s&nbsp;our&nbsp;familiar&nbsp;svn&nbsp;diff&nbsp;format</span><span style="color: rgb(0, 0, 0);"><br />
</span><span style="color: rgb(0, 0, 0);">#<br />
#&nbsp;Index:&nbsp;hello.git<br />
#&nbsp;</span><span style="color: rgb(0, 0, 0);">=====================================================================</span><span style="color: rgb(0, 0, 0);"><br />
#&nbsp;</span><span style="color: rgb(0, 0, 0);">---</span><span style="color: rgb(0, 0, 0);">&nbsp;hello.git<br />
#&nbsp;</span><span style="color: rgb(0, 0, 0);">+++</span><span style="color: rgb(0, 0, 0);">&nbsp;hello.git<br />
#<br />
#&nbsp;It</span><span style="color: rgb(0, 0, 0);">'</span><span style="color: rgb(0, 0, 0);">s&nbsp;useful&nbsp;to&nbsp;apply&nbsp;patch&nbsp;to&nbsp;project&nbsp;using&nbsp;svn&nbsp;as&nbsp;their&nbsp;repository&nbsp;and</span><span style="color: rgb(0, 0, 0);"><br />
</span><span style="color: rgb(0, 0, 0);">#&nbsp;you&nbsp;use&nbsp;git&nbsp;</span><span style="color: rgb(0, 0, 255);">for</span><span style="color: rgb(0, 0, 0);">&nbsp;your&nbsp;local&nbsp;work<br />
<br />
sed&nbsp;</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">e&nbsp;</span><span style="color: rgb(0, 0, 0);">'</span><span style="color: rgb(0, 0, 0);">/^[iI]ndex/s/^index.*/=====================================================================/</span><span style="color: rgb(0, 0, 0);">'</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">e&nbsp;</span><span style="color: rgb(0, 0, 0);">'</span><span style="color: rgb(0, 0, 0);">/^diff/s/^diff&nbsp;--g\</span><span style="color: rgb(0, 0, 0);"><br />
</span><span style="color: rgb(0, 0, 0);">it&nbsp;a\</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">Index:&nbsp;/'&nbsp;-e&nbsp;'/^Index:/s/&nbsp;b\/.*</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">'&nbsp;-e&nbsp;'/^---&nbsp;a\</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">s/---&nbsp;a\</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">---&nbsp;/'&nbsp;-e&nbsp;'/^+++&nbsp;b\</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">s/+++&nbsp;b\</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">+++&nbsp;/'&nbsp;$*<br />
</span></div>
<br />
Another, can't call it as 'tool' exactly, I think, just a convenient way or shortcut to query which files are changed in one or between two commits and their status, like 'svn diff --summarize':<br />
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: rgb(0, 0, 0);">#</span><span style="color: rgb(0, 0, 0);">!</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">bin</span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">sh<br />
<br />
#summary&nbsp;changed&nbsp;files&nbsp;which&nbsp;status,&nbsp;in&nbsp;one&nbsp;commit&nbsp;or&nbsp;between&nbsp;two&nbsp;commits<br />
<br />
git</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">diff</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">tree&nbsp;</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">r&nbsp;</span><span style="color: rgb(0, 0, 0);">--</span><span style="color: rgb(0, 0, 0);">name</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">status&nbsp;</span><span style="color: rgb(0, 0, 0);">--</span><span style="color: rgb(0, 0, 0);">pretty</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">format:</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">%Cgreen%s&nbsp;&nbsp;&nbsp;&nbsp;%CblueSHA1:&nbsp;%H%Creset</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&nbsp;$</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);"><br />
</span></div>
<br />
You can also do it like this:<br />
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: rgb(0, 0, 0);">alias&nbsp;git</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">diff</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">tree&nbsp;</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">r&nbsp;</span><span style="color: rgb(0, 0, 0);">--</span><span style="color: rgb(0, 0, 0);">name</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">status&nbsp;</span><span style="color: rgb(0, 0, 0);">--</span><span style="color: rgb(0, 0, 0);">pretty</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">format:</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">%Cgreen%s&nbsp;&nbsp;&nbsp;&nbsp;%CblueSHA1:&nbsp;%H%Creset</span><span style="color: rgb(0, 0, 0);">" git-changed-files<br />
</span></div>
and add this line to your $HOME/.bashrc<br />
<br />
<img src ="http://www.blogjava.net/JBahamut/aggbug/203081.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/JBahamut/" target="_blank">JBahamut</a> 2008-05-27 00:57 <a href="http://www.blogjava.net/JBahamut/archive/2008/05/27/203081.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Some very useful git commands</title><link>http://www.blogjava.net/JBahamut/archive/2008/05/27/203074.html</link><dc:creator>JBahamut</dc:creator><author>JBahamut</author><pubDate>Mon, 26 May 2008 16:29:00 GMT</pubDate><guid>http://www.blogjava.net/JBahamut/archive/2008/05/27/203074.html</guid><wfw:comment>http://www.blogjava.net/JBahamut/comments/203074.html</wfw:comment><comments>http://www.blogjava.net/JBahamut/archive/2008/05/27/203074.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/JBahamut/comments/commentRss/203074.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/JBahamut/services/trackbacks/203074.html</trackback:ping><description><![CDATA[<strong>checkout &lt;branch&gt;</strong><br />
switch branch<br />
<strong>checkout -b &lt;new branch&gt;</strong><br />
create new branch and switch to it<br />
<strong>checkout &lt;file&gt;</strong><br />
checkout file in HEAD and overwrite local file (NOTE: use it carefully, maybe lost your local work)<br />
<br />
<strong>diff</strong><br />
diff index and working copy<br />
<strong>diff --cached</strong><br />
diff index and last commit, which is what you will commit without '-a' option<br />
<br />
<strong>log</strong><br />
display commit logs<br />
<strong>log -p</strong><br />
include commit diff<br />
<strong>log --first-parent</strong><br />
follow only the first parent commit upon seeing a merge commit. This option gives a better overview of the evolution of a particular branch.<br />
<strong>log -S'string' </strong><br />
commits which add or remove data matching the 'string'<br />
<strong>log -r --name-status</strong><br />
show changed files with full path and status, just like 'svn diff --summarize'<br />
<br />
<strong>branch&nbsp;&nbsp; &nbsp;</strong>&nbsp;&nbsp;&nbsp; <br />
display all branches, current branch started with *<br />
<strong>branch -r</strong><br />
display remote branches<br />
<strong>merge --no-commit</strong>&nbsp;&nbsp;&nbsp; <br />
not commit immediately, all changes write to index<br />
<br />
<strong>reset --mixed&nbsp;&nbsp; </strong>&nbsp;&nbsp;&nbsp;&nbsp; <br />
default, adjust HEAD and clear index, changes in working copy is reserved, and changes between original HEAD and current HEAD will write to working copy<br />
<strong>reset --soft&nbsp;</strong>&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; <br />
adjust HEAD, changes between original HEAD and current HEAD will write to index<br />
<strong>reset --hard&nbsp;&nbsp; </strong>&nbsp;&nbsp;&nbsp;&nbsp; <br />
adjust HEAD, and clear index and working copy (NOTES: only use it when you are sure that the changes in index, working copy and changes reset in history will never be used)<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<img src ="http://www.blogjava.net/JBahamut/aggbug/203074.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/JBahamut/" target="_blank">JBahamut</a> 2008-05-27 00:29 <a href="http://www.blogjava.net/JBahamut/archive/2008/05/27/203074.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>感谢blogjava</title><link>http://www.blogjava.net/JBahamut/archive/2007/10/07/150936.html</link><dc:creator>JBahamut</dc:creator><author>JBahamut</author><pubDate>Sun, 07 Oct 2007 15:10:00 GMT</pubDate><guid>http://www.blogjava.net/JBahamut/archive/2007/10/07/150936.html</guid><wfw:comment>http://www.blogjava.net/JBahamut/comments/150936.html</wfw:comment><comments>http://www.blogjava.net/JBahamut/archive/2007/10/07/150936.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/JBahamut/comments/commentRss/150936.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/JBahamut/services/trackbacks/150936.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; 感谢blogjava，大半年没更新了，我的blog竟然还可以登录<img src="/CuteSoft_Client/CuteEditor/images/emdgust.gif" align="absmiddle" border="0"  alt="" /><br />
&nbsp;&nbsp;&nbsp; 发现自己真的是很懒啊，总是没法坚持写些东西，从本质上说我还是个不擅长写作的<br />
程序员，正确的表达自己比写出正确的程序要困难许多，表达出能让别让共鸣的东西<br />
更是难上加难。<br />
&nbsp;&nbsp;&nbsp; 但是，文章还是必须要是会写的，牛皮也是必须要会吹的。神啊，请允许我再一次许诺吧，<br />
试着写点东西吧。<br />
<br />
<img src ="http://www.blogjava.net/JBahamut/aggbug/150936.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/JBahamut/" target="_blank">JBahamut</a> 2007-10-07 23:10 <a href="http://www.blogjava.net/JBahamut/archive/2007/10/07/150936.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>惊喜！！发现了自己的blog-_-!!!</title><link>http://www.blogjava.net/JBahamut/archive/2006/12/26/90171.html</link><dc:creator>JBahamut</dc:creator><author>JBahamut</author><pubDate>Tue, 26 Dec 2006 13:29:00 GMT</pubDate><guid>http://www.blogjava.net/JBahamut/archive/2006/12/26/90171.html</guid><wfw:comment>http://www.blogjava.net/JBahamut/comments/90171.html</wfw:comment><comments>http://www.blogjava.net/JBahamut/archive/2006/12/26/90171.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/JBahamut/comments/commentRss/90171.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/JBahamut/services/trackbacks/90171.html</trackback:ping><description><![CDATA[整理收藏夹竟然发现了自己的blog-_-!!<br /><br />
翻翻发现最新的文章竟然是半年以前了，还号称“不再偷懒了”，实在惭愧啊。项目一忙起来<br />
确实是顾不上了，回来还有看动画片的重任在身自然更是无暇顾及了，说到底自己终久不是<br />
喜欢码字的人。不过翻翻以前写的东西还是蛮有意思的，有些东西回头看看还是很有好处<br />
的，于是决定还是写写吧，哪怕下一次会是半年以后^_^<br /><br />
最近工作搞定了，FileServer也初见成果，正在整理代码，是时候好好整理一下前段时间工作的体会了，第一次组织项目还是有很多感想可写的，请各位看官（如果有的话）敬请期待吧！！！<br /><br /><img src ="http://www.blogjava.net/JBahamut/aggbug/90171.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/JBahamut/" target="_blank">JBahamut</a> 2006-12-26 21:29 <a href="http://www.blogjava.net/JBahamut/archive/2006/12/26/90171.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>要开始写日志了</title><link>http://www.blogjava.net/JBahamut/archive/2006/05/20/47133.html</link><dc:creator>JBahamut</dc:creator><author>JBahamut</author><pubDate>Fri, 19 May 2006 17:05:00 GMT</pubDate><guid>http://www.blogjava.net/JBahamut/archive/2006/05/20/47133.html</guid><wfw:comment>http://www.blogjava.net/JBahamut/comments/47133.html</wfw:comment><comments>http://www.blogjava.net/JBahamut/archive/2006/05/20/47133.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/JBahamut/comments/commentRss/47133.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/JBahamut/services/trackbacks/47133.html</trackback:ping><description><![CDATA[    最近一直在准备做File
Server，要支持分布式存储和虚拟文件系统，我还希望能再进一步，加上日志系统。一切都始于我无止境的yy，现在仔细想想，难度真的是挺大的，不知道
我这半瓶酒能不能应付。不过是我负责，终于可以按我的想法组织项目了^_^<br />
    作为一次难得的锻炼机会，我准备把整个过程都记录下来，希望能够坚持下来。那就先表个态：<br />
        <font size="5"><b><br />
    我要写Blog了！！！不能偷懒了！！！！<br /><br /></b></font><p><font size="5"><b>
   </b><font size="3">之所以突然要写了，是因为前两天写自然基金的申请，发现许多东西只有写出来了才会有更
深刻的理解，并且写的过程还可以整理思绪，提供了足够的时间给我这样反应迟钝的人思考。而且想想研究生已经一年了，好像什么也没有留下，遇到什么问题还是
google，虽然许多已经见过并且解决了。就因为没有记录下来，没有形成积累白白浪费了许多时间，希望以后能有改观。今天就到这里，先贴个链接：</font></font></p><font size="5"><font size="3"><a href="http://www.sdsc.edu/srb/index.php/Main_Page">http://www.sdsc.edu/srb/index.php/Main_Page</a><br />
一个分布式存储系统，貌似很不错<br />
ps：竟然不能插入链接，难道是Firefox的问题？<br /></font></font><img src ="http://www.blogjava.net/JBahamut/aggbug/47133.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/JBahamut/" target="_blank">JBahamut</a> 2006-05-20 01:05 <a href="http://www.blogjava.net/JBahamut/archive/2006/05/20/47133.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于对象序列化的研究</title><link>http://www.blogjava.net/JBahamut/archive/2005/09/09/12539.html</link><dc:creator>JBahamut</dc:creator><author>JBahamut</author><pubDate>Fri, 09 Sep 2005 06:07:00 GMT</pubDate><guid>http://www.blogjava.net/JBahamut/archive/2005/09/09/12539.html</guid><wfw:comment>http://www.blogjava.net/JBahamut/comments/12539.html</wfw:comment><comments>http://www.blogjava.net/JBahamut/archive/2005/09/09/12539.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/JBahamut/comments/commentRss/12539.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/JBahamut/services/trackbacks/12539.html</trackback:ping><description><![CDATA[
		<div style="text-align: left;">    序列化是将对象变为连续的字节流，用于对象的持久化，网络传输等场合<br /><br />
一个类希望能被序列化必须实现 Serializable 接口，Serializable 本身并没有声明任何<br />
方法，只是起标记作用。可序列化类的子类自然也是可序列化的。因而实现序列化是非常方<br />
便的，只要在类的声明时添加 implenment Serializable 就可以了，java 虚拟机会帮你处<br />
理剩下的工作。序列化是递归的，一个类想要序列化则它的所有数据成员都必须是可以序列<br />
化的，否则在序列化时会抛出 NotSerializableException 异常。jsdk 中基本数据类型的<br />
封装类（Integer， Float etc），Component 都是可序列化的，如果容器中的对象都是可<br />
序列化的，则容器时可序列化的。java.lang.refect 包中的类不能序列化，Socket,<br />
URLConnection 不能序列化。<br /><br />
对于只实现了 Serializable 接口的类，可以想象 java 是如何将它们序列化的：首先要利<br />
用反射机制得到所有需要序列化的数据成员，包括 private 成员，得到 private 成员的过<br />
程是非常规的，必定要经过严格的权限和安全检查。所以用 java 自己的序列化方式开销是<br />
非常大的，这也是为什么会有这篇文章的原因，这里要讨论 java 提供的可以由我们自己控<br />
制的序列化对象的方式。<br /><br />
覆写<br />
private void writeObject(ObjectOutputStream out)<br />
private void readObject(ObjectInputStream in)<br /><br />
这两个方法会在对象序列化和反序列化时被调用，通过覆写这两个方法我们可以完全控制整<br />
个序列化的过程。我们注意到这两个方法都是 private ，这意味我们无法显示的调用这两<br />
个方法，而 java 虚拟机在调用这两个方法时也必然要经过严格的权限和安全检查。与传统<br />
的序列化方式（只实现 Serializable 接口）相比，这种方法减少了利用反射的次数以及获<br />
取 private 成员所需要的额外开销，因为在这两个方法中所有的数据成员都是可以自由使<br />
用的<br /><br />
实现 Externalizable 接口<br />
该接口中定义了两个方法<br />
public void readExternal(ObjectInput in) throws IOException<br />
public void writeExternal(ObjectOutput out) <br />
       throws IOException, ClassNotFoundException<br /><br />
这两个方法会在对象序列化和反序列化时被调用。很明显这两个方法都是 public 的，所以<br />
我们可以显示的将一个对象序列化到一个输出流，而 java 虚拟机在调用这两个方法时也不<br />
会有任何的限制。<br /><br />ANY-ACCESS_MODIFIER Object writeReplace() throws ObjectStreamException;<br />ANY-ACCESS_MODIFIER Object readResolve() throws ObjectStreamException;<br />这两个方法在序列化和反序列化时被调用,可以替换将要写入或读出的对象,在实现Singleton模式<br />时可能会用到<br /><br />
这三种方法实现序列化效率是显而易见的:传统方式最慢，实现 Externalizable 接口方式<br />
最快。但自己控制序列化过程有个明显的缺点就是当类的数据成员改变时，序列化过程也同<br />
时需要修改，相反这正好是传统方式的优点：任何改动都不会影响对象的正确序列化，虚拟<br />
机会帮你完成一切工作，虽然不算出色。<br /><br />
当我们考虑性能问题时，序列化总应该是我们首先要注意的方面，尤其是那些只实现了<br />
Serializable 接口的类，它们往往就是性能的瓶颈所在，特别是一些对象需要反复的被序<br />
列化和反序列化，实现 Externalizable 接口会给你不小的惊喜。而对于实现<br />
Externalizable 接口后需要保持数据成员和序列化方法一致的问题实际算不上问题，因为<br />
当我们考虑性能问题时应该已经到了编码的最后阶段，这时整体框架和数据结构都已经非常<br />
稳定了，数据成员被修改的可能已经非常低了，即使被修改了，能大幅提高性能，多写两行代<br />
码也不是令人沮丧的事情。<br /><br />
以上只是单纯的讨论序列化的过程，实际上序列化总是和 I/O 操作同时发生，因为序列化<br />
就是为了传输或是存储，所以对 I/O 的优化方法在这里也是同样适用的。<br /><br />使用ObjectOutputStream.writeObject()时,在流的内部会有一个引用缓存,所有已经写入流的<br />对象如果再次被写入则直接使用以前引用而不重新传输新的对象,这样可以提到流的效率,但同样带来<br />问题,一个对象写入流后,被修改,再次写入流,再另一端ObjectInputStream得到的是<br />两个相同的对象,这一点一定要注意<br /><br /></div>
<img src ="http://www.blogjava.net/JBahamut/aggbug/12539.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/JBahamut/" target="_blank">JBahamut</a> 2005-09-09 14:07 <a href="http://www.blogjava.net/JBahamut/archive/2005/09/09/12539.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>考古－－inheritance</title><link>http://www.blogjava.net/JBahamut/archive/2005/08/24/10850.html</link><dc:creator>JBahamut</dc:creator><author>JBahamut</author><pubDate>Tue, 23 Aug 2005 17:17:00 GMT</pubDate><guid>http://www.blogjava.net/JBahamut/archive/2005/08/24/10850.html</guid><wfw:comment>http://www.blogjava.net/JBahamut/comments/10850.html</wfw:comment><comments>http://www.blogjava.net/JBahamut/archive/2005/08/24/10850.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/JBahamut/comments/commentRss/10850.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/JBahamut/services/trackbacks/10850.html</trackback:ping><description><![CDATA[关于 overloading 和 overriding<br>
首先 java 中所有的方法都采用后绑定，就是在运行时绑定（除了被声明为 final 和 static 的）<br>
<br>
java通过方法的 signature 来判断一个方法与其他方法的关系，是无关的，overload 或 override<br>
方法的 signature 可以肯定的是方法名和参数。返回值，权限修饰词（public private），final，<br>
static 修饰词的情况有点复杂后面依次讨论。<br>
<br>
final &amp;&amp; private<br>
被声明为 final 或 private 的方法都是不能被 override 的，一定要注意这是两个语义完全不同的词，<br>
他们除此以外没有任何联系。final 不仅不允许子类 override，并且禁止子类使用名字和参数相同但返回<br>
值不同的方法 overload(如例子中的 functionEight（）），而 private 不同，他对子类是不可见的<br>
你完全可以在子类中定义一个与父类一摸一样的方法（这完全合理）。因此说 private 隐含有 final 的<br>
意思并不准确。 private 就是说 It's mine~~~~~~~~~ 对于类以外，没有人知道它的存在。final<br>
只是说这个方法不想被你覆写。<br>
<br>
返回值<br>
返回值不是方法的 signature，当方法名和参数相同时编译器会强制要求返回值必须一致，但子类 override<br>
父类的方法返回值可以不同,同样有一个条件返回值类型之间要有继承关系！！（例子中的<br>
functionTwo() functionThree() functionFour() 很好的演示这种关系）。要 override，<br>
子类的返回值类型必须是父类的返回值类型的子类（有点拗口，看看 fanctionTwo() functionFour <br>
就会明白了），这也应该是我们想要的行为。<br>
<br>
public &amp;&amp; private &amp;&amp; protected<br>
继承时方法的权限可以扩大但不能缩小(public &gt; protected &gt; none &gt; private)(例子 <br>
functionSix() and functionSeven())<br>
<br>
static<br>
你可以覆写 static 方法，就像 functionFive() 一样，看起来是 override，但实际上 static<br>
方法始终是前绑定，即在编译时绑定的。所有永远不会产生多态的效果，我们还是打消 override<br>
static 方法的念头吧<img src ="http://www.blogjava.net/JBahamut/aggbug/10850.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/JBahamut/" target="_blank">JBahamut</a> 2005-08-24 01:17 <a href="http://www.blogjava.net/JBahamut/archive/2005/08/24/10850.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>