Z么Sun Microsystem的工E师要将hashMap keyI间的长度设?的Nơ方呢?q里参考R.W.Floyedl出的衡量散列思想的三个标准:
Z各元素的hashCode保存至长度ؓLength的key数组中,一般采用取模的方式Q即index = hashCode % Length。不可避免的Q存在多个不同对象的hashCode被安排在同一位置Q这是我们qx所谓的“冲突”。如果仅仅是考虑元素均匀化与冲突极小化,g应该Length取ؓ素数Q尽没有明昄理论来支持这一点,但数学家们通过大量的实践得出结论,对素数取模的产生l果的无x要大于其它数字Q。ؓ此,Craig Larman and Rhett Guthrie《Java Performence》中Ҏ也大加抨凅Rؓ了弄清楚q个问题QBruce EckelQThinking in JAVA的作者)专程采访了java.util.hashMap的作者Joshua BlochQƈ他采用q种设计的原因放C|上Q?a target=_blank>
上述设计的原因在于,取模q算在包括JAVA在内的大多数语言中的效率都十分低下,而当除数?的Nơ方Ӟ取模q算退化ؓ最单的位运,其效率明显提升(按照Bruce Eckell出的数据,大约可以提升5?倍) 。看看JDK中是如何实现的:
static int indexFor(int h, int length) {
return h & (length-1);
}
当keyI间长度?的Nơ方Ӟ计算hashCode为h的元素的索引可以用简单的与操作来代替W拙的取模操作!假设某个对象的hashCode?5Q二q制?00011Q,而hashMap采用默认的initialCapacityQ?6Q,那么indexFor计算所得结果将会是100011 & 1111 = 11Q即十进制的3Q是不是恰好?5 Mod 16?
上面的方法有一个问题,是它的计算l果仅有对象hashCode的低位决定,而高位被l统屏蔽了;以上面ؓ例,19Q?0011Q?5Q?00011Q?7Q?000011Q等具有相同的l果。针对这个问题, Joshua Bloch采用?#8220;防M性编E?#8221;的解x法,在用各对象的hashCode之前对其q行二次HashQ参看JDK中的源码Q?
static int hash(Object x) {
int h = x.hashCode();
h += ~(h << 9 );
h ^= (h >>> 14 );
h += (h << 4 );
h ^= (h >>> 10 );
return h;
}
static int hash(Object x) {
int h = x.hashCode();
h += ~(h << 9);
h ^= (h >>> 14);
h += (h << 4);
h ^= (h >>> 10);
return h;
}
采用q种旋{Hash函数的主要目的是让原有hashCode的高位信息也能被充分利用Q且兼顾计算效率以及数据l计的特性,其具体的原理已超Z本文的领域?
加快Hash效率的另一个有效途径是编写良好的自定义对象的HashCodeQString的实现采用了如下的计方法:
for ( int i = 0 ; i < len; i++) {
h = 31 *h + val[off++];
}
hash = h;
for (int i = 0; i < len; i++) {
h = 31*h + val[off++];
}
hash = h;
q种ҎHashCode的计方法可能最早出现在Brian W. Kernighan和Dennis M. Ritchie的《The C Programming Language》中Q被认ؓ是性h比最高的法Q又被称为times33法Q因为C中乘数常量ؓ33QJAVA中改?1Q,实际上,包括List在内的大多数的对象都是用q种Ҏ计算Hash倹{?
另一U比较特D的hash法UCؓ布隆qo器,它以牺牲l微_ֺZP换来存储I间的大量节俭,常用于诸如判断用户名重复、是否在黑名单上{等Q可以参考李开复的数学之美pdW?3(
http://googlechinablog.com/2006/08/blog-post.html Q?
Fail-Fast机制
众所周知QHashMap不是U程安全的集合类。但在某些容错能力较好的应用中,如果你不想仅仅因?%的可能性而去承受hashTable的同步开销Q则可以考虑利用一下HashMap的Fail-Fast机制Q其具体实现如下Q?
Entry<K,V> nextEntry() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
……
}
Entry<K,V> nextEntry() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
……
}
其中modCount为HashMap的一个实例变量,q且被声明ؓvolatileQ表CZQ何线E都可以看到该变量被其它U程修改的结果(ҎJVM内存模型的优化,每一个线E都会存一份自q工作内存Q此工作内存的内容与本地内存q时时d都同步,因此可能会出现线E间的修改不可见的问题) 。用Iterator开始P代时Q会modCount的赋值给expectedModCountQ在q代q程中,通过每次比较两者是否相{来判断HashMap是否在内部或被其它线E修攏VHashMap的大多数修改Ҏ都会改变ModCountQ参考下面的源码Q?
public V put(K key, V value) {
K k = maskNull(key);
int hash = hash(k);
int i = indexFor(hash, table.length);
for (Entry<K,V> e = table[i]; e != null ; e = e.next) {
if (e.hash == hash && eq(k, e.key)) {
V oldValue = e.value;
e.value = value;
e.recordAccess( this );
return oldValue;
}
}
modCount++;
addEntry(hash, k, value, i);
return null ;
}
public V put(K key, V value) {
K k = maskNull(key);
int hash = hash(k);
int i = indexFor(hash, table.length);
for (Entry<K,V> e = table[i]; e != null; e = e.next) {
if (e.hash == hash && eq(k, e.key)) {
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
}
modCount++;
addEntry(hash, k, value, i);
return null;
}
以putҎZQ每ơ往HashMap中添加元素都会导致modCount自增。其它诸如remove、clearҎ也都包含cM的操作?
从上面可以看出,HashMap所采用的Fail-Fast机制本质上是一U乐观锁机制Q通过查状态——没有问题则忽略——有问题则抛出异常的方式Q来避免U程同步的开销Q下面给Z个在单线E环境下发生Fast-Fail的例子:
class Test {
public static void main(String[] args) {
java.util.HashMap<Object,String> map= new java.util.HashMap<Object,String>();
map.put( new Object(), "a" );
map.put( new Object(), "b" );
java.util.Iterator<Object> it=map.keySet().iterator();
while (it.hasNext()){
it.next();
map.put( "" , "" );
System.out.println(map.size());
}
}
class Test {
public static void main(String[] args) {
java.util.HashMap<Object,String> map=new java.util.HashMap<Object,String>();
map.put(new Object(), "a");
map.put(new Object(), "b");
java.util.Iterator<Object> it=map.keySet().iterator();
while(it.hasNext()){
it.next();
map.put("", "");
System.out.println(map.size());
}
}
q行上面的代码会抛出java.util.ConcurrentModificationExceptionQ因为在q代q程中修改了HashMap内部的元素导致modCount自增。若上面代码中 map.put(new Object(), "b") q句注释掉,E序会顺利通过Q因为此时HashMap中只包含一个元素,l过一ơP代后已到了尾部,所以不会出现问题,也就没有抛出异常的必要了?
在通常q发环境下,q是采用同步机制。这一般通过对自然封装该映射的对象进行同步操作来完成。如果不存在q样的对象,则应该?Collections.synchronizedMap Ҏ?#8220;包装”该映。最好在创徏时完成这一操作Q以防止意外的非同步讉K?
LinkedHashMap
遍历HashMap所得到的数据是杂ؕ无章的,q在某些情况下客户需要特定遍历顺序时是十分有用的。比如,q种数据l构很适合构徏 LRU ~存。调?put ?get Ҏ会讉K相应的条目(假定调用完成后它q存在)。putAll Ҏ以指定映的条目集合q代器提供的?值映关pȝ序Qؓ指定映射的每个映关pȝ成一个条目访问。Sun提供的J2SE说明文特别规定M其他Ҏ均不生成条目讉KQ尤Ӟcollection 集合cȝ操作不会影响底层映射的P代顺序?
LinkedHashMap的实C HashMap 的不同之处在于,前者维护着一个运行于所有条目的双重链接列表。此链接列表定义了P代顺序,该P代顺序通常是集合中元素的插入序。该cd义了header、before与after三个属性来表示该集合类的头与前?#8220;指针”Q其具体用法cM于数据结构中的双链表Q以删除某个元素ZQ?
private void remove() {
before.after = after;
after.before = before;
}
private void remove() {
before.after = after;
after.before = before;
}
实际上就是改变前后指针所指向的元素?
昄Q由于增加了l护链接列表的开支,其性能要比 HashMap E逊一{,不过有一点例外:LinkedHashMap的P代所需旉与其的所包含的元素成比例Q而HashMap q代旉很可能开支较大,因ؓ它所需要的旉与其定wQ分配给KeyI间的长度)成比例。一a以蔽之,随机存取用HashMapQ顺序存取或是遍历用LinkedHashMap?
LinkedHashMapq重写了removeEldestEntryҎ以实现自动清除过期数据的功能Q这在HashMap中是无法实现的,因ؓ后者其内部的元素是无序的。默认情况下QLinkedHashMap中的removeEldestEntry的作用被关闭Q其具体实现如下Q?
protected boolean removeEldestEntry(Map.Entry<K,V> eldest) {
return false ;
}
protected boolean removeEldestEntry(Map.Entry<K,V> eldest) {
return false;
}
可以使用如下的代码覆盖removeEldestEntryQ?
private static final int MAX_ENTRIES = 100 ;
protected boolean removeEldestEntry(Map.Entry eldest) {
return size() > MAX_ENTRIES;
}
private static final int MAX_ENTRIES = 100;
protected boolean removeEldestEntry(Map.Entry eldest) {
return size() > MAX_ENTRIES;
}
它表C,刚开始,LinkedHashMap中的元素不断增长Q当它内部的元素过MAX_ENTRIESQ?00Q后Q每当有新的元素被插入时Q都会自动删除双链表中最前端Q最旧)的元素,从而保持LinkedHashMap的长度稳定?
~省情况下,LinkedHashMap采取的更新策略是cM于队列的FIFOQ如果你惛_现更复杂的更新逻辑比如LRUQ最q最用) {,可以在构造函C指定其accessOrder为trueQ因为的讉K元素的方法(getQ内部会调用一?#8220;钩子”Q即recordAccessQ其具体实现如下Q?
void recordAccess(HashMap<K,V> m) {
LinkedHashMap<K,V> lm = (LinkedHashMap<K,V>)m;
if (lm.accessOrder) {
lm.modCount++;
remove();
addBefore(lm.header);
}
}
void recordAccess(HashMap<K,V> m) {
LinkedHashMap<K,V> lm = (LinkedHashMap<K,V>)m;
if (lm.accessOrder) {
lm.modCount++;
remove();
addBefore(lm.header);
}
}
上述代码主要实现了这L功能Q如果accessOrder被设|ؓtrueQ则每次讉K元素Ӟ都将该元素移至headr的前面,即链表的N。将removeEldestEntry与accessOrder一起用,可以实现最基本的内存缓存,具体代码可参?a target=_blank>
http://bluepopopo.javaeye.com/blog/180236 ?
WeakHashMap
99%的JAVA教材教导我们不要d预JVM的垃圑֛收机Ӟ但JAVA中确实存在着与其密切相关的四U引用:强引用、Y引用、弱引用以及q象引用?
JAVA中默认的HashMap采用的是采用cM于强引用的强键来理的,q意味着即作ؓkey的对象已l不存在了(指没有Q何一个引用指向它Q,也仍然会保留在HashMap中,在某些情况下Q例如内存缓存)中,q些q期的条目可能会造成内存泄漏{问题?
WeakHashMap采用的策略是Q只要作为key的对象已l不存在了(出生命周期Q,׃会阻止垃圾收集器清空此条目,即当前机器的内存ƈ不紧张。不q,׃GC是一个优先很低的线E,因此不一定会很快发现那些只具有弱引用的对象,除非你显C地调用它,可以参考下面的例子Q?
public static void main(String[] args) {
Map<String, String>map = new WeakHashMap<String, String>();
map.put( new String( "Alibaba" ), "alibaba" );
while (map.containsKey( "Alibaba" )) {
try {
Thread.sleep( 500 );
} catch (InterruptedException ignored) {
}
System.out.println( "Checking for empty" );
System.gc();
}
public static void main(String[] args) {
Map<String, String>map = new WeakHashMap<String, String>();
map.put(new String("Alibaba"), "alibaba");
while (map.containsKey("Alibaba")) {
try {
Thread.sleep(500);
} catch (InterruptedException ignored) {
}
System.out.println("Checking for empty");
System.gc();
}
上述代码输出一ơChecking for empty退ZȝE,意味着GC在最q的一ơ垃圑֛收周期中清除了new String(“Alibaba”),同时WeakHashMap也做Z及时的反应,该键对应的条目删除了。如果将map的类型改为HashMap的话Q由于其内部采用的是强引用机Ӟ因此即GC被显C用,map中的条目依然存在Q程序会不断地打出Checking for empty字样。另外,在用WeakHashMap的情况下Q若是将
map.put( new String( "Alibaba" ), "alibaba" );
map.put(new String("Alibaba"), "alibaba");
改ؓ
map.put( "Alibaba" , "alibaba" );
map.put("Alibaba", "alibaba");
E序q是会不断输出Checking for empty。这与前面我们分析的WeakHashMap的弱引用机制q不矛盾Q因为JVMZ减小重复创徏和维护多个相同String的开销Q其内部采用了蝇量模式(《JAVA与模式》)Q此时的“Alibaba”是存攑֜帔R池而非堆中的,因此即没有对象指向“Alibaba”Q它也不会被GC回收。弱引用特别适合以下对象Q占用大量内存,但通过垃圾回收功能回收以后很容易重新创建?
介于HashMap和WeakHashMap之中的是SoftHashMapQ它所采用的Y引用的策略指的是Q垃圾收集器q不像其攉弱可及的对象一样尽量地攉软可及的对象Q相反,它只在真?“需?#8221; 内存时才攉软可及的对象。Y引用对于垃圾攉器来说是一U?#8220;睁一只眼Q闭一只眼”方式Q即 “只要内存不太紧张Q我׃保留该对象。但是如果内存变得真正紧张了Q我׃L集ƈ处理q个对象?#8221; p一点看Q它其实要比WeakHashMap更适合于实现缓存机制。遗憄是,JAVA中ƈ没有实现相关的SoftHashMapc(Apache和Google提供了第三方的实玎ͼQ但它却是提供了两个十分重要的类java.lang.ref.SoftReference以及ReferenceQueueQ可以在对象应用状态发生改变是得到通知Q可以参考com.alibaba.common.collection.SofthashMap中processQueueҎ的实?
private ReferenceQueue queue = new ReferenceQueue();
ValueCell vc;
Map hash = new HashMap(initialCapacity, loadFactor);
……
while ((vc = (ValueCell) queue.poll()) != null ) {
if (vc.isValid()) {
hash.remove(vc.key);
} else {
valueCell.dropped--;
}
}
}
private ReferenceQueue queue = new ReferenceQueue();
ValueCell vc;
Map hash = new HashMap(initialCapacity, loadFactor);
……
while ((vc = (ValueCell) queue.poll()) != null) {
if (vc.isValid()) {
hash.remove(vc.key);
} else {
valueCell.dropped--;
}
}
}
processQueueҎ会在几乎所有SoftHashMap的方法中被调用到QJVM会通过ReferenceQueue的pollҎ通知该对象已l过期ƈ且当前的内存现状需要将它释放,此时我们可以将其从hashMap中剔除。事实上Q默认情况下QAlibaba的MemoryCache所使用的就是SoftHashMap?
来源Q?a >http://grunt1223.javaeye.com/blog/544497
]]>
转蝲QY件开发的一些感?/title> http://m.tkk7.com/ArcticOcean/archive/2010/08/04/327923.htmlCool Jazz Cool Jazz Wed, 04 Aug 2010 04:34:00 GMT http://m.tkk7.com/ArcticOcean/archive/2010/08/04/327923.html http://m.tkk7.com/ArcticOcean/comments/327923.html http://m.tkk7.com/ArcticOcean/archive/2010/08/04/327923.html#Feedback 0 http://m.tkk7.com/ArcticOcean/comments/commentRss/327923.html http://m.tkk7.com/ArcticOcean/services/trackbacks/327923.html
把他文章的部分{接过来,Z自己也备注下Q对自己有个参考?br />
一、需求分?设计,开?试和项目管理整个流E:
对Q何系l来? 无非是做?件事: IPO. 也就是Input,Process,Output. Q偏重于设计Q类g计算机本w,作ؓȝ本nq是蛮清楚的Q?/p>
寚w求分析来? 你最重要的是搞明?用户的需?也就是搞清用L输入(Input)和输?Output)是什?它的要求辑ֈ的功?Process)是什? 明白以后,你就可以写一些用户需求说明书,描述用例,输入输出处理异常什么的,或者做一个简单的Demopȝ,拿去l用L,看看q个界面是不是用户喜Ƣ的,q个程是不是用h需要的{等.Q注Q如果加入点理Q就丰满了。还有以后的需求变_要知道需要可能是不断变化的)
然后是pȝ分析: 首先,你需要对用户的需求分模块,每个模块的IPO是什?他们应采用什么架?需要和那些模块交互,互相之间的接口是怎样?需要用什么技?每个模块的运行环境是什么样子的,Ҏ?安全或者容错等Ҏ是否要着重考虑.Q注Q考虑的蛮多的Q加个词Q系l的可扩展性)
接着是pȝ设计: 每个模块的数据库要怎么设计,所用技术和架构军_?要确定不同层ơ有哪些接口,比如说表现层,业务逻辑?数据库访问层,怺之间怎么调用,定好框架和开发模式和格式,剩下的就是编码了..Q注Q说的似乎少了点Q?/p>
~码部分: 首先团队要有一个良好的~码规范.q且Ҏ个h提交的代码要review,我发现程序编多了,自己成了一台计?看到E序׃知道会出C么结?Ҏ都不用跑h.Q注Q编码的时候,多考虑下:复用和模式)
试: 单元试是否~写试用例? Junit是个好工?每个人都要保证好自己的代码没有问? 整体试p整个程的跑一?看看需求实现的对不?q有没有什么其他纰? .Q注Q测试分好多U,单元Q压力,持久性、黑白盒{,有专门的试部分或组׃一样了Q?/p>
风险理: q一点很重要,要时ȝ道自q目有什么风?无论是h员的,技术的,旉?q是协调上面?都要心里有数,按时按周向领导汇报?br />
以下部分—?/p>
记得我去IBM面试的时?问过,以后有几条职业发展的方向,回答有三?一条是IT Specialist,一条是Project Manager,q有一条是IT Architect. 我还曾要求以后能不能向IT Architect发展,那h?Architect要熟悉很多技术呢,我问了两?他这样回{了两遍.后来l我订了Advisory I/T Specialist. 我当时很U闷,我搞Javaq么?J2ME,J2SE,J2EE全都搞过,而且对Gof?lt;Design Pattern>也悟?q?了熟于心,各种各样的经怹c也看了不少,怎么不能向Architect发展? 现在我加入了IBM,q入一个香港的目,q段旉要去香港培训几星?才明白了,原来一个大目会涉及到各种各样的语a,技?什么Cobal(韌),forturn(韌),java,vb,C#,soa xxȝ模式,mq,大型机开?{?很多我只在书上看到过的古老语a,q有一些听都没听过的语a,框架,模式,全都出现?我当时这个汗?我才发现我真的很无知.知识是一个气?你知道的多,接触的越多就会发现自p无知.所以这也是我要今天赶紧把这个写出来的原? 我怕以后又有了变故,q要沉淀,需要时?
本文部分来自CSDN博客Q?a >http://blog.csdn.net/Eric77/archive/2010/08/01/5781573.aspx
]]> 分布式计框架Hadoop http://m.tkk7.com/ArcticOcean/archive/2010/08/03/327836.htmlCool Jazz Cool Jazz Tue, 03 Aug 2010 09:03:00 GMT http://m.tkk7.com/ArcticOcean/archive/2010/08/03/327836.html http://m.tkk7.com/ArcticOcean/comments/327836.html http://m.tkk7.com/ArcticOcean/archive/2010/08/03/327836.html#Feedback 0 http://m.tkk7.com/ArcticOcean/comments/commentRss/327836.html http://m.tkk7.com/ArcticOcean/services/trackbacks/327836.html Hadoop 上{来的。其中有?/span>介绍HDFS的pdf文档 Q对Hadoop介绍的比较全面?br />
先说一下Hadoop的来龙去脉。谈到Hadoop׃得不提到 Lucene ?/span>Nutch 。首先,Luceneq不是一个应用程序,而是提供了一个纯Java的高性能全文索引引擎工具?/span>Q它可以方便的嵌入到各种实际应用中实现全文搜?索引功能?span style="color: rgb(0,0,255)">Nutch是一个应用程序,是一个以Lucene为基实现的搜索引擎应?/span>QLucene 为Nutch提供了文本搜索和索引的APIQNutch不光有搜索的功能Q还有数据抓取的功能。在nutch0.8.0版本之前QHadoopq属?Nutch的一部分Q而从nutch0.8.0开始,其中实现的NDFS和MapReduce剥离出来成立一个新的开源项目,q就是HadoopQ?nutch0.8.0版本较之以前的Nutch在架构上有了Ҏ性的变化Q那是完全构徏在Hadoop的基之上了。在Hadoop中实C Google的GFS和MapReduce法QHadoop成ؓ了一个分布式的计^台?br />
Hadoopq不仅仅是一个用于存储的分布式文件系l,而是设计用来在由通用计算讑֤l成的大型集上执行分布式应用的框架?br />
Hadoop包含两个部分Q?/span>
1、HDFS
即Hadoop Distributed File System (Hadoop分布式文件系l?
HDFS h高容错性,q且可以被部|在低h的硬件设备之上。HDFS很适合那些有大数据集的应用Qƈ且提供了Ҏ据读写的高吞吐率。HDFS是一?master/slave的结构,通常的部|来_在master上只q行一个NamenodeQ而在每一个slave上运行一个Datanode?br />
HDFS 支持传统的层ơ文件组l结构,同现有的一些文件系l在操作上很cMQ比如你可以创徏和删除一个文Ӟ把一个文件从一个目录移到另一个目录,重命名等{操 作。Namenode理着整个分布式文件系l,Ҏ件系l的操作Q如建立、删除文件和文g夹)都是通过Namenode来控制?nbsp;
下面是HDFS的结构:
从上面的图中可以?出,NamenodeQDatanodeQClient之间的通信都是建立在TCP/IP的基之上的。当Client要执行一个写入的操作的时候,命o 不是马上发送到NamenodeQClient首先在本Z临时文g夹中~存q些数据Q当临时文g夹中的数据块辑ֈ了设定的Block的|默认?64MQ时QClient便会通知NamenodeQNamenode便响应Client的RPChQ将文g名插入文件系l层ơ中q且?Datanode中找C块存放该数据的blockQ同时将该Datanode及对应的数据块信息告诉ClientQClient便这些本C时文件夹?的数据块写入指定的数据节炏V?br />
HDFS采取了副本策略,其目的是Z提高pȝ的可靠性,可用性。HDFS的副本放|策略是三个副本Q?一个放在本节点上,一个放在同一机架中的另一个节点上Q还有一个副本放在另一个不同的机架中的一个节点上。当前版本的hadoop0.12.0中还没有?玎ͼ但是正在q行中,怿不久可以出来了?br />
2、MapReduce的实?br />
MapReduce 是Google 的一w要技术,它是一个编E模型,用以q行大数据量的计。对于大数据量的计算Q通常采用的处理手法就是ƈ行计。至现阶段而言Q对许多开发h员来 _q行计算q是一个比较遥q的东西。MapReduce是一U简化ƈ行计的~程模型Q它让那些没有多ƈ行计经验的开发h员也可以开发ƈ行应用?br />
MapReduce的名字源于这个模型中的两Ҏ心操作:Map?Reduce。也许熟悉Functional ProgrammingQ?/span>函数式编E?/span> Q?的h见到q两个词会倍感亲切。简单的说来QMap是把一l数据一对一的映ؓ另外的一l数据,其映的规则׃个函数来指定Q比如对[1, 2, 3, 4]q行?的映就变成了[2, 4, 6, 8]。Reduce是对一l数据进行归U,q个归约的规则由一个函数指定,比如对[1, 2, 3, 4]q行求和的归U得到结果是10Q而对它进行求U的归约l果?4?br />
关于MapReduce的内容,看看孟岩的这?/span>MapReduce:The Free Lunch Is Not Over! q篇是介绍的比较详l的。MapReduce的算法内容见Google文档Q?a title="MapReduce.pdf" >MapReduce.pdf
有关其它介绍Hadoop的文章徏议看下:分布式计开源框架Hadoop介绍 。(whatQwhyQhow提的不错Q?br />
安装配置可以看:1?a rel="permalink">Hadoop中的集群配置和用技?/a>
2?a >Hadoop应用之Hadoop安装?/a>
3?a title="Hadoop安装部v指南" >Hadoop安装部v指南
如果要开发的话,初步参考:Hadoop基本程与应用开?/a>
其中用到数据库的部分Q在Hadoop?.19.0开始支撑数据库讉KQ主要采用DBInputFormat来访问数据库。文章可见: Hadoop中的数据库访?/a>
]]> 字符集编码研I?/title> http://m.tkk7.com/ArcticOcean/articles/324841.htmlCool Jazz Cool Jazz Wed, 30 Jun 2010 01:08:00 GMT http://m.tkk7.com/ArcticOcean/articles/324841.html http://m.tkk7.com/ArcticOcean/comments/324841.html http://m.tkk7.com/ArcticOcean/articles/324841.html#Feedback 0 http://m.tkk7.com/ArcticOcean/comments/commentRss/324841.html http://m.tkk7.com/ArcticOcean/services/trackbacks/324841.html --字符集编?/h1>
1. 概述
本文主要包括以下几个斚wQ编码基本知识,javaQ系lYӞurlQ工兯Y件等?/p>
在下面的描述中,以"中文"两个字ؓ例,l查表可以知道其GB2312~码?d6d0 cec4 "QUnicode~码?4e2d 6587 "QUTF~码是"e4b8ad e69687 "。注意,q两个字没有iso8859-1~码Q但可以用iso8859-1~码?表示"?/p>
2. ~码基本知识
最早的~码是iso8859-1Q和ascii~码怼。但Z方便表示各种各样的语aQ逐渐出现了很多标准编码,重要的有如下几个?/p>
2.1. iso8859-1
属于单字节编码,最多能表示的字W范围是0-255Q应用于英文pd。比如,字母'a'的编码ؓ0x61=97?/p>
很明显,iso8859-1~码表示的字W范围很H,无法表示中文字符。但是,׃是单字节~码Q和计算机最基础的表C单位一_所以很多时候,仍旧使用iso8859-1~码来表C。而且在很多协议上Q默认用该~码。比如,虽然"中文"两个字不存在iso8859-1~码Q以gb2312~码ZQ应该是"d6d0 cec4 "两个字符Q用iso8859-1~码的时候则它拆开?个字节来表示Q?d6 d0 ce c4 "Q事实上Q在q行存储的时候,也是以字节ؓ单位处理的)。而如果是UTF~码Q则?个字?e4 b8 ad e6 96 87 "。很明显Q这U表C方法还需要以另一U编码ؓ基础?/p>
2.2. GB2312/GBK
q就是汉子的国标码,专门用来表示汉字Q是双字节编码,而英文字母和iso8859-1一_兼容iso8859-1~码Q。其中gbk~码能够用来同时表示J体字和体字Q而gb2312只能表示体字Qgbk是兼容gb2312~码的?/p>
2.3. unicode
q是最l一的编码,可以用来表示所有语a的字W,而且是定长双字节Q也有四字节的)~码Q包括英文字母在内。所以可以说它是不兼容iso8859-1~码的,也不兼容M~码。不q,相对于iso8859-1~码来说Quniocode~码只是在前面增加了一?字节Q比如字?a'?00 61 "?/p>
需要说明的是,定长~码便于计算机处理(注意GB2312/GBK不是定长~码Q,而unicode又可以用来表C所有字W,所以在很多软g内部是用unicode~码来处理的Q比如java?/p>
2.4. UTF
考虑到unicode~码不兼容iso8859-1~码Q而且Ҏ占用更多的空_因ؓ对于英文字母Qunicode也需要两个字节来表示。所以unicode不便于传输和存储。因此而生了utf~码Qutf~码兼容iso8859-1~码Q同时也可以用来表示所有语a的字W,不过Qutf~码是不定长~码Q每一个字W的长度?-6个字节不{。另外,utf~码自带单的校验功能。一般来Ԍ英文字母都是用一个字节表C,而汉字用三个字节?/p>
注意Q虽然说utf是ؓ了用更的I间而用的Q但那只是相对于unicode~码来说Q如果已l知道是汉字Q则使用GB2312/GBK无疑是最节省的。不q另一斚wQ值得说明的是Q虽然utf~码Ҏ字?个字节,但即使对于汉字网,utf~码也会比unicode~码节省Q因为网中包含了很多的英文字符?/p>
3. java对字W的处理
在java应用软g中,会有多处涉及到字W集~码Q有些地斚w要进行正的讄Q有些地斚w要进行一定程度的处理?/p>
3.1. getBytes(charset)
q是java字符串处理的一个标准函敎ͼ其作用是字W串所表示的字W按照charset~码Qƈ以字节方式表C。注意字W串在java内存中L按unicode~码存储的。比?中文"Q正常情况下Q即没有错误的时候)存储?4e2d 6587 "Q如果charset?gbk"Q则被编码ؓ"d6d0 cec4 "Q然后返回字?d6 d0 ce c4 "。如果charset?utf8"则最后是"e4 b8 ad e6 96 87 "。如果是"iso8859-1"Q则׃无法~码Q最后返?"3f 3f "Q两个问P?/p>
3.2. new String(charset)
q是java字符串处理的另一个标准函敎ͼ和上一个函数的作用相反Q将字节数组按照charset~码q行l合识别Q最后{换ؓunicode存储。参考上qgetBytes的例子,"gbk" ?utf8"都可以得出正的l果"4e2d 6587 "Q但iso8859-1最后变成了"003f 003f "Q两个问P?/p>
因ؓutf8可以用来表示/~码所有字W,所以new String( str.getBytes( "utf8" ), "utf8" ) === strQ即完全可逆?/p>
3.3. setCharacterEncoding()
该函数用来设|httph或者相应的~码?/p>
对于requestQ是指提交内容的~码Q指定后可以通过getParameter()则直接获得正的字符Ԍ如果不指定,则默认用iso8859-1~码Q需要进一步处理。参见下q?表单输入"。值得注意的是在执行setCharacterEncoding()之前Q不能执行Q何getParameter()。java doc上说明:This method must be called prior to reading request parameters or reading input using getReader()。而且Q该指定只对POSTҎ有效Q对GETҎ无效。分析原因,应该是在执行W一个getParameter()的时候,java会按照~码分析所有的提交内容Q而后l的getParameter()不再q行分析Q所以setCharacterEncoding()无效。而对于GETҎ提交表单是,提交的内容在URL中,一开始就已经按照~码分析所有的提交内容QsetCharacterEncoding()自然无效?/p>
对于responseQ则是指定输出内容的~码Q同Ӟ该设|会传递给览器,告诉览器输出内Ҏ采用的编码?/p>
3.4. 处理q程
下面分析两个有代表性的例子Q说明java对编码有关问题的处理Ҏ?/p>
3.4.1. 表单输入
User input *(gbk:d6d0 cec4) browser *(gbk:d6d0 cec4) web server iso8859-1(00d6 00d 000ce 00c4) classQ需要在class中进行处理:getbytes("iso8859-1")?u>d6 d0 ce c4Qnew String("gbk")?u>d6d0 cec4Q内存中以unicode~码则ؓ4e2d 6587 ?/p>
l 用户输入的编码方式和面指定的编码有养I也和用户的操作系l有养I所以是不确定的Q上例以gbkZ?/p>
l 从browser到web serverQ可以在表单中指定提交内Ҏ使用的字W集Q否则会使用面指定的编码。而如果在url中直接用?的方式输入参敎ͼ则其~码往往是操作系l本w的~码Q因时和面无关。上qC旧以gbk~码Z?/p>
l Web server接收到的是字节流Q默认时QgetParameterQ会以iso8859-1~码处理之,l果是不正确的,所以需要进行处理。但如果预先讄了编码(通过request. setCharacterEncoding ()Q,则能够直接获取到正确的结果?/p>
l 在页面中指定~码是个好习惯,否则可能失去控制Q无法指定正的~码?/p>
3.4.2. 文g~译
假设文g是gbk~码保存的,而编译有两种~码选择Qgbk或者iso8859-1Q前者是中文windows的默认编码,后者是linux的默认编码,当然也可以在~译时指定编码?/p>
Jsp *(gbk:d6d0 cec4) java file *(gbk:d6d0 cec4) compiler read uincode(gbk: 4e2d 6587; iso8859-1: 00d6 00d 000ce 00c4) compiler write utf(gbk: e4b8ad e69687; iso8859-1: *) compiled file unicode(gbk: 4e2d 6587; iso8859-1: 00d6 00d 000ce 00c4) class。所以用gbk~码保存Q而用iso8859-1~译的结果是不正的?/p>
class unicode(4e2d 6587) system.out / jsp.out gbk(d6d0 cec4) os console / browser?/p>
l 文g可以以多U编码方式保存,中文windows下,默认为ansi/gbk?/p>
l ~译器读取文件时Q需要得到文件的~码Q如果未指定Q则使用pȝ默认~码。一般class文gQ是以系l默认编码保存的Q所以编译不会出问题Q但对于jsp文gQ如果在中文windows下编辑保存,而部|在英文linux下运?~译Q则会出现问题。所以需要在jsp文g中用pageEncoding指定~码?/p>
l Java~译的时候会转换成统一的unicode~码处理Q最后保存的时候再转换为utf~码?/p>
l 当系l输出字W的时候,会按指定~码输出Q对于中文windows下,System.out用gbk~码Q而对于responseQ浏览器Q,则用jsp文g头指定的contentTypeQ或者可以直接ؓresponse指定~码。同Ӟ会告诉browser|页的编码。如果未指定Q则会用iso8859-1~码。对于中文,应该为browser指定输出字符串的~码?/p>
l browser昄|页的时候,首先使用response中指定的~码Qjsp文g头指定的contentType最l也反映在response上)Q如果未指定Q则会用网中metaҎ定中的contentType?/p>
3.5. 几处讄
对于web应用E序Q和~码有关的设|或者函数如下?/p>
3.5.1. jsp~译
指定文g的存储编码,很明显,该设|应该置于文件的开头。例如:<%@page pageEncoding="GBK"%>。另外,对于一般class文gQ可以在~译的时候指定编码?/p>
3.5.2. jsp输出
指定文g输出到browser是用的~码Q该讄也应该置于文件的开头。例如:<%@ page contentType="text/html; charset= GBK" %>。该讄和response.setCharacterEncoding("GBK"){效?/p>
3.5.3. meta讄
指定|页使用的编码,该设|对静态网尤其有作用。因为静态网|法采用jsp的设|,而且也无法执行response.setCharacterEncoding()。例如:<META http-equiv="Content-Type" content="text/html; charset=GBK" />
如果同时采用了jsp输出和meta讄两种~码指定方式Q则jsp指定的优先。因为jsp指定的直接体现在response中?/p>
需要注意的是,apache有一个设|可以给无编码指定的|页指定~码Q该指定{同于jsp的编码指定方式,所以会覆盖静态网中的meta指定。所以有人徏议关闭该讄?/p>
3.5.4. form讄
当浏览器提交表单的时候,可以指定相应的编码。例如:<form accept-charset= "gb2312">。一般不必不使用该设|,览器会直接使用|页的编码?/p>
4. pȝ软g
下面讨论几个相关的系lY件?/p>
4.1. mysql数据?/p>
很明显,要支持多语言Q应该将数据库的~码讄成utf或者unicodeQ而utf更适合与存储。但是,如果中文数据中包含的英文字母很少Q其实unicode更ؓ适合?/p>
数据库的~码可以通过mysql的配|文件设|,例如default-character-set=utf8。还可以在数据库链接URL中设|,例如Q?useUnicode=true&characterEncoding=UTF-8。注意这两者应该保持一_在新的sql版本里,在数据库链接URL里可以不q行讄Q但也不能是错误的设|?/p>
4.2. apache
appache和编码有关的配置在httpd.conf中,例如AddDefaultCharset UTF-8。如前所qͼ该功能会所有静态页面的~码讄为UTF-8Q最好关闭该功能?/p>
另外Qapacheq有单独的模块来处理|页响应_其中也可能对~码q行讄?/p>
4.3. linux默认~码
q里所说的linux默认~码Q是指运行时的环境变量。两个重要的环境变量是LC_ALL和LANGQ默认编码会影响到java URLEncode的行为,下面有描q?/p>
都设|ؓ"zh_CN.UTF-8"?/p>
4.4. 其它
Z支持中文文g名,linux在加载磁盘时应该指定字符集,例如Qmount /dev/hda5 /mnt/hda5/ -t ntfs -o iocharset=gb2312?/p>
另外Q如前所qͼ使用GETҎ提交的信息不支持request.setCharacterEncoding()Q但可以通过tomcat的配|文件指定字W集Q在tomcat的server.xml文g中,形如Q?lt;Connector ... URIEncoding="GBK"/>。这U方法将l一讄所有请求,而不能针对具体页面进行设|,也不一定和browser使用的编码相同,所以有时候ƈ不是所期望的?/p>
5. URL地址
URL地址中含有中文字W是很麻烦的Q前面描q过使用GETҎ提交表单的情况,使用GETҎӞ参数是包含在URL中?/p>
5.1. URL~码
对于URL中的一些特D字W,览器会自动q行~码。这些字W除?/?&"{外Q还包括unicode字符Q比如汉子。这时的~码比较Ҏ?/p>
IE有一个选项"L使用UTF-8发送URL"Q当该选项有效ӞIE会对特D字W进行UTF-8~码Q同时进行URL~码。如果改选项无效Q则使用默认~码"GBK"Qƈ且不q行URL~码。但是,对于URL后面的参敎ͼ则L不进行编码,相当于UTF-8选项无效。比?中文.html?a=中文"Q当UTF-8选项有效Ӟ发送链?%e4%b8%ad%e6%96%87.html?a=\x4e\x2d\x65\x87 "Q而UTF-8选项无效Ӟ发送链?\x4e\x2d\x65\x87.html?a=\x4e\x2d\x65\x87 "。注意后者前面的"中文"两个字只?个字节,而前者却?8个字节,q主要时URL~码的原因?/p>
当web serverQtomcatQ接收到该链接时Q将会进行URL解码Q即L"%"Q同时按照ISO8859-1~码Q上面已l描qͼ可以使用URLEncoding来设|成其它~码Q识别。上qC子的l果分别?\ue4\ub8\uad\ue6\u96\u87.html?a=\u4e\u2d\u65\u87 "?\u4e\u2d\u65\u87.html?a=\u4e\u2d\u65\u87 "Q注意前者前面的"中文"两个字恢复成?个字W。这里用"\u"Q表C是unicode?/p>
所以,׃客户端设|的不同Q相同的链接Q在服务器上得到了不同结果。这个问题不h都遇刎ͼ却没有很好的解决办法。所以有的网站会用户试关闭UTF-8选项。不q,下面会描qC个更好的处理办法?/p>
5.2. rewrite
熟悉的h都知道,apache有一个功能强大的rewrite模块Q这里不描述其功能。需要说明的是该模块会自动将URL解码Q去?Q,卛_成上qweb serverQtomcatQ的部分功能。有相关文介绍说可以用[NE]参数来关闭该功能Q但我试验ƈ未成功,可能是因为版本(我用的是apache 2.0.54Q问题。另外,当参C含有"?& "{符L时候,该功能将Dpȝ得不到正常结果?/p>
rewrite本ng完全是采用字节处理的方式Q而不考虑字符串的~码Q所以不会带来编码问题?/p>
5.3. URLEncode.encode()
q是Java本n提供对的URL~码函数Q完成的工作和上qUTF-8选项有效时浏览器所做的工作怼。值得说明的是Qjava已经不赞成不指定~码来用该ҎQdeprecatedQ。应该在使用的时候增加编码指定?/p>
当不指定~码的时候,该方法用系l默认编码,q会D软gq行l果得不定。比如对?中文"Q当pȝ默认~码?gb2312"Ӟl果?%4e%2d%65%87 "Q而默认编码ؓ"UTF-8"Q结果却?%e4%b8%ad%e6%96%87 "Q后l程序将难以处理。另外,q儿说的pȝ默认~码是由q行tomcat时的环境变量LC_ALL和LANG{决定的Q曾l出现过tomcat重启后就出现q的问题,最后才郁闷的发现是因ؓ修改修改了这两个环境变量?/p>
l一指定?UTF-8"~码Q可能需要修改相应的E序?/p>
5.4. 一个解x?/p>
上面说vq,因ؓ览器设|的不同Q对于同一个链接,web server收到的是不同内容Q而Y件系l有无法知道q中间的区别Q所以这一协议目前q存在缺陗?/p>
针对具体问题Q不应该侥幸认ؓ所有客LIE讄都是UTF-8有效的,也不应该_暴的徏议用户修改IE讄Q要知道Q用户不可能去记住每一个web server的设|。所以,接下来的解决办法只能是让自qE序多一Ҏ能:Ҏ内容来分析编码是否UTF-8?/p>
比较q运的是UTF-8~码相当有规律,所以可以通过分析传输q来的链接内容,来判断是否是正确的UTF-8字符Q如果是Q则以UTF-8处理之,如果不是Q则使用客户默认~码Q比?GBK"Q,下面是一个判断是否UTF-8的例子,如果你了解相应规律,容易理解?/p>
public static boolean isValidUtf8(byte[] b,int aMaxCount){
int lLen=b.length,lCharCount=0;
for(int i=0;i<lLen && lCharCount<aMaxCount;++lCharCount){
byte lByte=b[i++];//to fast operation, ++ now, ready for the following for(;;)
if(lByte>=0) continue;//>=0 is normal ascii
if(lByte<(byte)0xc0 || lByte>(byte)0xfd) return false;
int lCount=lByte>(byte)0xfc?5:lByte>(byte)0xf8?4
:lByte>(byte)0xf0?3:lByte>(byte)0xe0?2:1;
if(i+lCount>lLen) return false;
for(int j=0;j<lCount;++j,++i) if(b[i]>=(byte)0xc0) return false;
}
return true;
}
相应圎ͼ一个用上q方法的例子如下Q?/p>
public static String getUrlParam(String aStr,String aDefaultCharset)
throws UnsupportedEncodingException{
if(aStr==null) return null;
byte[] lBytes=aStr.getBytes("ISO-8859-1");
return new String(lBytes,StringUtil.isValidUtf8(lBytes)?"utf8":aDefaultCharset);
}
不过Q该Ҏ也存在缺P如下两方面:
l 没有包括对用户默认编码的识别Q这可以Ҏh信息的语a来判断,但不一定正,因ؓ我们有时候也会输入一些韩文,或者其他文字?/p>
l 可能会错误判断UTF-8字符Q一个例子是"学习"两个字,其GBK~码? \xd1\xa7\xcf\xb0 "Q如果用上qisValidUtf8Ҏ判断Q将q回true。可以考虑使用更严格的判断ҎQ不q估计效果不大?/p>
有一个例子可以证明google也遇C上述问题Q而且也采用了和上q相似的处理ҎQ比如,如果在地址栏中输入"
最后,应该补充说明一下,如果不用rewrite规则Q或者通过表单提交数据Q其实ƈ不一定会遇到上述问题Q因时可以在提交数据时指定希望的~码。另外,中文文g名确实会带来问题Q应该}慎用?/p>
6. 其它
下面描述一些和~码有关的其他问题?/p>
6.1. SecureCRT
除了览器和控制C~码有关外,一些客L也很有关pR比如在使用SecureCRTq接linuxӞ应该让SecureCRT的显C编码(不同的sessionQ可以有不同的编码设|)和linux的编码环境变量保持一致。否则看到的一些帮助信息,可能是q?/p>
另外Qmysql有自q~码讄Q也应该保持和SecureCRT的显C编码一致。否则通过SecureCRT执行sql语句的时候,可能无法处理中文字符Q查询结果也会出Cؕ码?/p>
对于Utf-8文gQ很多编辑器Q比如记事本Q会在文件开头增加三个不可见的标志字节,如果作ؓmysql的输入文Ӟ则必要Lq三个字W。(用linux的vi保存可以Lq三个字W)。一个有的现象是,在中文windows下,创徏一个新txt文gQ用C本打开Q输?q?两个字,保存Q再打开Q你会发C个字没了Q只留下一个小黑点?/p>
6.2. qo?/p>
如果需要统一讄~码Q则通过filterq行讄是个不错的选择。在filter class中,可以l一为需要的h或者回应设|编码。参加上qsetCharacterEncoding()。这个类apache已经l出了可以直接用的例子SetCharacterEncodingFilter?/p>
6.3. POST和GET
很明显,以POST提交信息ӞURL有更好的可读性,而且可以方便的用setCharacterEncoding()来处理字W集问题。但GETҎ形成的URL能够更容易表辄늚实际内容Q也能够用于收藏?/p>
从统一的角度考虑问题Q徏议采用GETҎQ这要求在程序中获得参数是进行特D处理,而无法用setCharacterEncoding()的便利,如果不考虑rewriteQ就不存在IE的UTF-8问题Q可以考虑通过讄URIEncoding来方便获取URL中的参数?/p>
6.4. J体~码转换
GBK同时包含体和J体~码Q也是说同一个字Q由于编码不同,在GBK~码下属于两个字。有时候,Z正确取得完整的结果,应该繁体和体进行统一。可以考虑UTF、GBK中的所有繁体字Q{换ؓ相应的简体字QBIG5~码的数据,也应该{化成相应的简体字。当Ӟ仍旧以UTF~码存储?/p>
例如Q对?语言 語言"Q用UTF表示?\x E8\xAF\xAD\xE8\xA8\x80 \xE8\xAA\x9E\xE8\xA8\x80 "Q进行简J体~码转换后应该是两个相同?"\x E8\xAF\xAD\xE8\xA8\x80> "?br />
转蝲于:刘科?Manufacturer.com
]]> 邮g历照片显C,试成功Q在BlogjavaQ?/title> http://m.tkk7.com/ArcticOcean/archive/2008/11/09/239543.htmlCool Jazz Cool Jazz Sun, 09 Nov 2008 12:01:00 GMT http://m.tkk7.com/ArcticOcean/archive/2008/11/09/239543.html http://m.tkk7.com/ArcticOcean/comments/239543.html http://m.tkk7.com/ArcticOcean/archive/2008/11/09/239543.html#Feedback 0 http://m.tkk7.com/ArcticOcean/comments/commentRss/239543.html http://m.tkk7.com/ArcticOcean/services/trackbacks/239543.html 最q比较忙。因为我马上p毕业了,正在扑ַ作。自己去|上下了html版的历。编辑了Q放入邮。在自己的机子上能看出来Q我以ؓ发出去别h也能看得到呢。后来我同学问我怎么才能在邮仉昄照片Q我把Ҏ告诉他,q且把他的照片传C我在JR的相册里。v初在他的邮g里(本地|络Q可以看到。我׃为成功了呢。改天他发了邮gl他同学看,却发现看不到?br />
我真是奇怪了。怎么会看不到呢?
照片的地址Q单独点ȝ话可以看到。在别h的邮仉是看不刎ͼ除非那个Z点击了照片的地址Qƈ把照片显C出来后Q才能在邮g里显C。搞了好几次都是q个样子Q我无语了?br />
N说JR的相册不能被外h看到Q?br />
不应该啊Q别人是可以看到的呀。莫非JR的相册自动限制了Q照片的下蝲Q?br />
也许是这个原因,我想?br />
我换了BlogjavaQ找了我的同学测试。把JR的测试了3Q?ơ都不能昄。最后我试了BlogjavaQ成功了Q(Ҏ׃用我在啰嗦了吧:Q)
看来q是Blogjava好啊。我后一定要在这里多写blogQ?br />
以前Q我很少写技术的blogQ因己想写的东西多数和公司的代码有关Q有时候想写却不能把代码脓出来。烦性就不写blog。只是去技术性的|站或开源的|站看最新的英文新闻。如果有新消息,把它翻译过来,攑ֈ自己的blog里?br />
Blogjaval我的感觉是Q功能比JR的强。但是h气似乎要׃些?br />
不关怎么P我以后会多到q里来的?br />
]]> 好多天没来了Q因为在写论?/title> http://m.tkk7.com/ArcticOcean/archive/2008/09/21/230255.htmlCool Jazz Cool Jazz Sun, 21 Sep 2008 05:46:00 GMT http://m.tkk7.com/ArcticOcean/archive/2008/09/21/230255.html http://m.tkk7.com/ArcticOcean/comments/230255.html http://m.tkk7.com/ArcticOcean/archive/2008/09/21/230255.html#Feedback 0 http://m.tkk7.com/ArcticOcean/comments/commentRss/230255.html http://m.tkk7.com/ArcticOcean/services/trackbacks/230255.html
毕竟以前做了数据库的目Q相Ҏ说好写点。只是我做的那些东西被师兄给“?#8221;了。所以留l自q隑ֺ不小?br />
哎,公司现在q行的东西比较老了Q虽然有市场。多年都是q样的老架构。没有新东西出来Q将来会比较ȝ。现在是在公司,w不由己。既然公叔R目帮不上什么忙Q就自己动手了。采用现在的L框架Q结合IEC规约Q在整合上数据库集群Q服务器集群。。。似乎是多了Q但是不写,自己会觉得没有什么东ѝ学校那些老师Q都不知道现在外面的技术进展情况,是那老技术来写,他们可能q觉得挺新的。不q,不能骗自己啊。搞q么多架构的东西Q没有程序,没有实际的运行和试Q你能说服得了谁Q程序是写了Q把原来在学校研I的目拿来Q加上Spring攚w,DWR包装成JavaScriptQ在传给试界面。。?br />
真难啊,最隄也就是调试了。也是只能每天晚上搞,真篏Q?br />
q好我搞出来了,攑֜Apache和Tomcat集群下,q行q些E序抓了些图Q真爽啊Q?br />
只是我的服务器集是|上参考别人的Q还真没q行q。哎Q没机器啊,公司的机器又不能随便用。我最怕的是通信Q我没做q,只是用了公司以前做的通信lg拿来用,q行能用。要是连RTU的话,更好了Q可惜。。?br />
庆祝一下,我的服务器后台架构测试成功!感谢JavaQ感谢Spring和HibernateQ感谢PostgreSQLQ感谢开源!
整理论文?Q)
]]> q么快,Hibernate3.3.1GA发布Q?/title> http://m.tkk7.com/ArcticOcean/archive/2008/09/12/228510.htmlCool Jazz Cool Jazz Fri, 12 Sep 2008 01:50:00 GMT http://m.tkk7.com/ArcticOcean/archive/2008/09/12/228510.html http://m.tkk7.com/ArcticOcean/comments/228510.html http://m.tkk7.com/ArcticOcean/archive/2008/09/12/228510.html#Feedback 0 http://m.tkk7.com/ArcticOcean/comments/commentRss/228510.html http://m.tkk7.com/ArcticOcean/services/trackbacks/228510.html
在距Hibernate3.3.0GA发布不到一个月的时间内Q?.3.1GA发布了。感觉真是快啊。原来是修正了bug?/p>
q次发布主要是修正了CurrentSessionContext(SessionFactory.getCurrentSession())q行在IBM WebSphered的严重问题?span style="white-space: normal; ">它也包括了id发生器等不少改进。细节部分和全部变化Q请查看变化日志?/span>
Hibernate Core 3.3.1 has just been released with its artifacts published to the JBoss Maven Repository . This release fixed a serious issue with CurrentSessionContext (SessionFactory.getCurrentSession()) when running on IBM WebSphere. It also includes quite a few improvements to the enhanced id generators . For details about all the changes in this release, check out it's changelog