tag:blogger.com,1999:blog-30512796387844761212024-03-14T02:45:57.280-07:00韩国恺(hanguokai)的博客hgk's blog - blog.hanguokai.comhgkhttp://www.blogger.com/profile/18248256147814166844noreply@blogger.comBlogger88125tag:blogger.com,1999:blog-3051279638784476121.post-9349402287196126642012-02-12T07:51:00.000-08:002012-02-12T07:56:43.608-08:00有趣的字符比较规则(Collation)<p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "><span class="c8" style="background-color: rgb(255, 255, 255); ">在理解了字符集、字符编码的概念后,另一个很少有人理解的问题是如何对字符进行比较,也就是Collation的概念。发现网上很多文章只是解释了字符集设置的同时捎带的说了一下Collation,所以我就想重点解释Collation。</span></p><p class="c0 c4" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; height: 11pt; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "><span class="c8" style="background-color: rgb(255, 255, 255); "></span></p><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "><span class="c8" style="background-color: rgb(255, 255, 255); ">前些天我突然意识到 mysql 默认是字符比较是不区分大小写的,比如“abc”、“ABC”和“aBc”认为是相等的。这和我的直觉不一致,尤其在编程语言中,两个字符串的内容完全一致才认为是相等的(equals),除非明确地使用不区分大小写的比较方法(如equalsIgnoreCase)。</span></p><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "><span class="c8" style="background-color: rgb(255, 255, 255); ">(注:mysql 支持很多字符集,而每种字符集又有多种collation,各种字符集的默认collation都是以ci 结尾的,即不区分大小写的方式)</span></p><p class="c0 c4" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; height: 11pt; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "><span class="c8" style="background-color: rgb(255, 255, 255); "></span></p><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "><span class="c8" style="background-color: rgb(255, 255, 255); ">对文字做排序主要是为了方便查找,可以快速定位到自己要找的地方,比如在有序的通讯录中我们可以快速定位到“王”字开头的人,另外排序后看起来也会比较整齐美观。</span></p><p class="c0 c4" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; height: 11pt; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "><span class="c8" style="background-color: rgb(255, 255, 255); "></span></p><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "><span class="c8" style="background-color: rgb(255, 255, 255); ">对于中国人而言,比较缺少文字排序这方面的意识。因为汉字是象形文字,字数非常多,每个字都是独立的,在日常生活中字之间没有明确的先后顺序或相等规则一说。现在常见的是以汉字对应的拼音字母顺序和笔画顺序。用拉丁字母表示汉字的拼音是近代才出现的,历史较短。</span></p><p class="c0 c4" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; height: 11pt; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "><span class="c8" style="background-color: rgb(255, 255, 255); "></span></p><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "><span class="c8" style="background-color: rgb(255, 255, 255); ">与之相反,英语等西方语言是由数量较少的基本字母组成的,而这些基本字母是有明确顺序的。所以很自然的就有了以字母表为基础的排序规则,历史就很长了。</span></p><p class="c0 c4" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; height: 11pt; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "><span class="c8" style="background-color: rgb(255, 255, 255); "></span></p><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "><span class="c8" style="background-color: rgb(255, 255, 255); ">在Unicode中的CJK部分,据说是以四字典中的顺序为基础的。四字典的排序顺序为:《康熙字典》、《大漢和辭典》、《汉语大字典》、《大字源》。即在查一个汉字,先在《康熙字典》查,查不到再在《大漢和辭典》查,依次类推。而康熙字典是以部首笔画为序的。</span></p><p class="c0 c4" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; height: 11pt; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "><span class="c8" style="background-color: rgb(255, 255, 255); "></span></p><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "><span class="c8" style="background-color: rgb(255, 255, 255); ">而中国的GB2312、GBK 是以拼音为顺序的。</span></p><p class="c0 c4" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; height: 11pt; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "><span class="c8" style="background-color: rgb(255, 255, 255); "></span></p><p class="c0 c4" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; height: 11pt; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "><span class="c8" style="background-color: rgb(255, 255, 255); "></span></p><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "><span class="c8" style="background-color: rgb(255, 255, 255); ">Collation就是对字符串如何比较的规则。也就是不同字符的前后顺序,以及哪些字符可以认为是相等的。比如在德语中 </span>ß<span class="c8" style="background-color: rgb(255, 255, 255); "> 可以看做 ss 。</span></p><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "><span class="c8" style="background-color: rgb(255, 255, 255); ">Collation问题的本质是:一些表面上不同的符号,在人们看来可能是相同的,取决于人们是如何“认为”的。有些表面上不同的符号,其意义可能是相同的,或者在一定级别下认为是相同的。</span></p><p class="c0 c4" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; height: 11pt; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "><span class="c8" style="background-color: rgb(255, 255, 255); "></span></p><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "><span class="c8" style="background-color: rgb(255, 255, 255); ">对字符进行比较:如何判断相等、如何比较大小,影响到查询和排序问题。</span></p><p class="c0 c4" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; height: 11pt; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "><span class="c8" style="background-color: rgb(255, 255, 255); "></span></p><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "><span class="c8" style="background-color: rgb(255, 255, 255); ">相等问题英文中最常见的就是大小写问题,在计算机中大小写是不同的字符,对应的编码也不同,但人们在使用过程中,一般又当做是一样的。在中文中全角和半角字符在意义上是相同的,还有中文的数字也有大小写,如“一”和“壹”在一定意义上也是相同的。</span></p><p class="c0 c4" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; height: 11pt; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "><span class="c8" style="background-color: rgb(255, 255, 255); "></span></p><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "><span class="c8" style="background-color: rgb(255, 255, 255); ">相等的判断在mysql中就是== 或 like。一般在编程语言中,字符串是按照他们(对应的编码)是否完全相等来判断的,大小比较也是按照他们的字典顺序比较的。这样对计算机而言是非常简单的,把每个字符当做字节就是纯数字的判断,相等和比较大小都很容易。</span></p><p class="c0 c4" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; height: 11pt; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "><span class="c8" style="background-color: rgb(255, 255, 255); "></span></p><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "><span class="c8" style="background-color: rgb(255, 255, 255); ">但是在不同的国家、语言环境中,根据当地人的文化习惯制定了很多特殊的规则。要让计算机去遵循这些规则,毕竟机器是为人服务的。</span></p><p class="c0 c4" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; height: 11pt; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "><span class="c8" style="background-color: rgb(255, 255, 255); "></span></p><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "><span class="c8" style="background-color: rgb(255, 255, 255); ">Collation简单的说就是描述这种规则的,哪些字符认为是等价的,以及这些字符比较排序等。</span></p><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "><span class="c8" style="background-color: rgb(255, 255, 255); ">更复杂一点说,里面又可以分一些不同的比较级别。比如在这个级别下,认为是不同的,但在另一个级别下就认为是相同的。</span></p><p class="c0 c4" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; height: 11pt; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "><span class="c8" style="background-color: rgb(255, 255, 255); "></span></p><p class="c0 c4" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; height: 11pt; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "></p><h2 class="c0" style="padding-top: 18pt; line-height: 1.15; font-size: 14pt; font-family: Arial; padding-bottom: 4pt; direction: ltr; "><a name="h.hobts35hgd7d"></a>语言文化</h2><h3 class="c0" style="padding-top: 14pt; line-height: 1.15; color: rgb(102, 102, 102); font-size: 12pt; font-family: Arial; padding-bottom: 4pt; direction: ltr; "><a name="h.85o58yon477n"></a>1. 拉丁字母</h3><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; ">拉丁字母主要就是我们常说的 26 个字母 a-z 及大写形式。</p><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; ">另外拉丁字母还有一些衍生字母:</p><table cellpadding="0" cellspacing="0" class="c9" style="border-collapse: collapse; font-family: Arial; "><tbody><tr><td class="c2" style="vertical-align: top; width: 66.8pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">尖音</p></td><td class="c7" style="vertical-align: top; width: 36.8pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Áá</p></td><td class="c12" style="vertical-align: top; width: 33pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Éé</p></td><td class="c17" style="vertical-align: top; width: 30.8pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Íí</p></td><td class="c12" style="vertical-align: top; width: 33pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Óó</p></td><td class="c11" style="vertical-align: top; width: 33.8pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Úú</p></td><td class="c18" style="vertical-align: top; width: 28.5pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Ýý</p></td></tr><tr><td class="c2" style="vertical-align: top; width: 66.8pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">重音</p></td><td class="c7" style="vertical-align: top; width: 36.8pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Àà</p></td><td class="c12" style="vertical-align: top; width: 33pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Èè</p></td><td class="c17" style="vertical-align: top; width: 30.8pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Ìì</p></td><td class="c12" style="vertical-align: top; width: 33pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Òò</p></td><td class="c11" style="vertical-align: top; width: 33.8pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Ùù</p></td><td class="c18" style="vertical-align: top; width: 28.5pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1 c4" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; height: 11pt; "></p></td></tr><tr><td class="c2" style="vertical-align: top; width: 66.8pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">折音</p></td><td class="c7" style="vertical-align: top; width: 36.8pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Ââ</p></td><td class="c12" style="vertical-align: top; width: 33pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Êê</p></td><td class="c17" style="vertical-align: top; width: 30.8pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Îî</p></td><td class="c12" style="vertical-align: top; width: 33pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Ôô</p></td><td class="c11" style="vertical-align: top; width: 33.8pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Ûû</p></td><td class="c18" style="vertical-align: top; width: 28.5pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1 c4" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; height: 11pt; "></p></td></tr><tr><td class="c2" style="vertical-align: top; width: 66.8pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">德语变音/分音</p></td><td class="c7" style="vertical-align: top; width: 36.8pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Ää</p></td><td class="c12" style="vertical-align: top; width: 33pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Ëë</p></td><td class="c17" style="vertical-align: top; width: 30.8pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Ïï</p></td><td class="c12" style="vertical-align: top; width: 33pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Öö</p></td><td class="c11" style="vertical-align: top; width: 33.8pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Üü</p></td><td class="c18" style="vertical-align: top; width: 28.5pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Ÿÿ</p></td></tr><tr><td class="c2" style="vertical-align: top; width: 66.8pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">软音</p></td><td class="c7" style="vertical-align: top; width: 36.8pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Çç</p></td><td class="c12" style="vertical-align: top; width: 33pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Şş</p></td><td class="c17" style="vertical-align: top; width: 30.8pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1 c4" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; height: 11pt; "></p></td><td class="c12" style="vertical-align: top; width: 33pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1 c4" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; height: 11pt; "></p></td><td class="c11" style="vertical-align: top; width: 33.8pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1 c4" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; height: 11pt; "></p></td><td class="c18" style="vertical-align: top; width: 28.5pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1 c4" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; height: 11pt; "></p></td></tr><tr><td class="c2" style="vertical-align: top; width: 66.8pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">鼻音</p></td><td class="c7" style="vertical-align: top; width: 36.8pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Ãã</p></td><td class="c12" style="vertical-align: top; width: 33pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Õõ</p></td><td class="c17" style="vertical-align: top; width: 30.8pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Ññ</p></td><td class="c12" style="vertical-align: top; width: 33pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1 c4" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; height: 11pt; "></p></td><td class="c11" style="vertical-align: top; width: 33.8pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1 c4" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; height: 11pt; "></p></td><td class="c18" style="vertical-align: top; width: 28.5pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1 c4" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; height: 11pt; "></p></td></tr><tr><td class="c2" style="vertical-align: top; width: 66.8pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">鼻化元音</p></td><td class="c7" style="vertical-align: top; width: 36.8pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Ąą</p></td><td class="c12" style="vertical-align: top; width: 33pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Ęę</p></td><td class="c17" style="vertical-align: top; width: 30.8pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Įį</p></td><td class="c12" style="vertical-align: top; width: 33pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Ųų</p></td><td class="c11" style="vertical-align: top; width: 33.8pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1 c4" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; height: 11pt; "></p></td><td class="c18" style="vertical-align: top; width: 28.5pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1 c4" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; height: 11pt; "></p></td></tr><tr><td class="c2" style="vertical-align: top; width: 66.8pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">合字</p></td><td class="c7" style="vertical-align: top; width: 36.8pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Ææ</p></td><td class="c12" style="vertical-align: top; width: 33pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Œœ</p></td><td class="c17" style="vertical-align: top; width: 30.8pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Øø</p></td><td class="c12" style="vertical-align: top; width: 33pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">IJij</p></td><td class="c11" style="vertical-align: top; width: 33.8pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">ß</p></td><td class="c18" style="vertical-align: top; width: 28.5pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1 c4" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; height: 11pt; "></p></td></tr><tr><td class="c2" style="vertical-align: top; width: 66.8pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">卢恩字母</p></td><td class="c7" style="vertical-align: top; width: 36.8pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Þþ</p></td><td class="c12" style="vertical-align: top; width: 33pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1 c4" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; height: 11pt; "></p></td><td class="c17" style="vertical-align: top; width: 30.8pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1 c4" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; height: 11pt; "></p></td><td class="c12" style="vertical-align: top; width: 33pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1 c4" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; height: 11pt; "></p></td><td class="c11" style="vertical-align: top; width: 33.8pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1 c4" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; height: 11pt; "></p></td><td class="c18" style="vertical-align: top; width: 28.5pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1 c4" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; height: 11pt; "></p></td></tr></tbody></table><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "> </p><p class="c0 c4" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; height: 11pt; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "></p><h3 class="c0" style="padding-top: 14pt; line-height: 1.15; color: rgb(102, 102, 102); font-size: 12pt; font-family: Arial; padding-bottom: 4pt; direction: ltr; "><a name="h.jy80zknp254s"></a>2. 德语</h3><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; ">德语字母表是由拉丁字母组成,除了拉丁字母的26个字母外德语还有四个字母的变体。</p><table cellpadding="0" cellspacing="0" class="c9" style="border-collapse: collapse; font-family: Arial; "><tbody><tr><td class="c10" style="vertical-align: top; width: 31.4pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Aa</p></td><td class="c20" style="vertical-align: top; width: 35.2pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; "><span class="c16" style="background-color: rgb(217, 217, 217); ">(Ää)</span></p></td><td class="c23" style="vertical-align: top; width: 26.2pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Bb</p></td><td class="c10" style="vertical-align: top; width: 31.4pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Cc</p></td><td class="c10" style="vertical-align: top; width: 31.4pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Dd</p></td><td class="c10" style="vertical-align: top; width: 31.4pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Ee</p></td><td class="c10" style="vertical-align: top; width: 31.4pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Ff</p></td><td class="c10" style="vertical-align: top; width: 31.4pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Gg</p></td><td class="c10" style="vertical-align: top; width: 31.4pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Hh</p></td><td class="c11" style="vertical-align: top; width: 33.8pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Ii</p></td><td class="c15" style="vertical-align: top; width: 27.8pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Jj</p></td><td class="c10" style="vertical-align: top; width: 31.4pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Kk</p></td><td class="c10" style="vertical-align: top; width: 31.4pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Ll</p></td><td class="c10" style="vertical-align: top; width: 31.4pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Mm</p></td><td class="c10" style="vertical-align: top; width: 31.4pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Nn</p></td></tr><tr><td class="c10" style="vertical-align: top; width: 31.4pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Oo</p></td><td class="c20" style="vertical-align: top; width: 35.2pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; "><span class="c16" style="background-color: rgb(217, 217, 217); ">(Öö)</span></p></td><td class="c23" style="vertical-align: top; width: 26.2pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Pp</p></td><td class="c10" style="vertical-align: top; width: 31.4pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Qq</p></td><td class="c10" style="vertical-align: top; width: 31.4pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Rr</p></td><td class="c10" style="vertical-align: top; width: 31.4pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Ss</p></td><td class="c10" style="vertical-align: top; width: 31.4pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; "><span class="c16" style="background-color: rgb(217, 217, 217); ">(ß)</span></p></td><td class="c10" style="vertical-align: top; width: 31.4pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Tt</p></td><td class="c10" style="vertical-align: top; width: 31.4pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Uu</p></td><td class="c11" style="vertical-align: top; width: 33.8pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; "><span class="c16" style="background-color: rgb(217, 217, 217); ">(Üü)</span></p></td><td class="c15" style="vertical-align: top; width: 27.8pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Vv</p></td><td class="c10" style="vertical-align: top; width: 31.4pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Ww</p></td><td class="c10" style="vertical-align: top; width: 31.4pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Xx</p></td><td class="c10" style="vertical-align: top; width: 31.4pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Yy</p></td><td class="c10" style="vertical-align: top; width: 31.4pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Zz</p></td></tr></tbody></table><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; ">注意:不要把德语中的 ß 和 希腊字母 β 混淆。一般 ß 也可以用 ss 代替。</p><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; ">替换规则:Ü=Ue Ä=Ae Ö=Oe ß=ss</p><p class="c0 c4" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; height: 11pt; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "></p><h3 class="c0" style="padding-top: 14pt; line-height: 1.15; color: rgb(102, 102, 102); font-size: 12pt; font-family: Arial; padding-bottom: 4pt; direction: ltr; "><a name="h.jwke4i4rolyx"></a>3. 瑞典语</h3><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; ">瑞典语有29个字母:拉丁字母的26个加上Å / å、Ä / ä及Ö / ö。这3个字母排在z之后。W经常不算作一个独立的字母。</p><table cellpadding="0" cellspacing="0" class="c9" style="border-collapse: collapse; font-family: Arial; "><tbody><tr><td class="c5" style="vertical-align: top; width: 31.3pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Aa</p></td><td class="c5" style="vertical-align: top; width: 31.3pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Bb</p></td><td class="c5" style="vertical-align: top; width: 31.3pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Cc</p></td><td class="c5" style="vertical-align: top; width: 31.3pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Dd</p></td><td class="c5" style="vertical-align: top; width: 31.3pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Ee</p></td><td class="c5" style="vertical-align: top; width: 31.3pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Ff</p></td><td class="c5" style="vertical-align: top; width: 31.3pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Gg</p></td><td class="c5" style="vertical-align: top; width: 31.3pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Hh</p></td><td class="c5" style="vertical-align: top; width: 31.3pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Ii</p></td><td class="c17" style="vertical-align: top; width: 30.8pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Jj</p></td><td class="c17" style="vertical-align: top; width: 30.8pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Kk</p></td><td class="c5" style="vertical-align: top; width: 31.3pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Ll</p></td><td class="c5" style="vertical-align: top; width: 31.3pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Mm</p></td><td class="c5" style="vertical-align: top; width: 31.3pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Nn</p></td><td class="c5" style="vertical-align: top; width: 31.3pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Oo</p></td></tr><tr class="c21" style="height: 0pt; "><td class="c5" style="vertical-align: top; width: 31.3pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Pp</p></td><td class="c5" style="vertical-align: top; width: 31.3pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Qq</p></td><td class="c5" style="vertical-align: top; width: 31.3pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Rr</p></td><td class="c5" style="vertical-align: top; width: 31.3pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Ss</p></td><td class="c5" style="vertical-align: top; width: 31.3pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Tt</p></td><td class="c5" style="vertical-align: top; width: 31.3pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Uu</p></td><td class="c5" style="vertical-align: top; width: 31.3pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Vv</p></td><td class="c5" style="vertical-align: top; width: 31.3pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Ww</p></td><td class="c5" style="vertical-align: top; width: 31.3pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Xx</p></td><td class="c17" style="vertical-align: top; width: 30.8pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Yy</p></td><td class="c17" style="vertical-align: top; width: 30.8pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Zz</p></td><td class="c5" style="vertical-align: top; width: 31.3pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Åå</p></td><td class="c5" style="vertical-align: top; width: 31.3pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Ää</p></td><td class="c5" style="vertical-align: top; width: 31.3pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; line-height: 1; ">Öö</p></td><td class="c5" style="vertical-align: top; width: 31.3pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding-top: 5pt; padding-right: 5pt; padding-bottom: 5pt; padding-left: 5pt; "><p class="c0 c4" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; height: 11pt; "></p></td></tr></tbody></table><p class="c0 c4" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; height: 11pt; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "></p><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; ">其它语言如<span class="c6" style="color: rgb(17, 85, 204); text-decoration: underline; "><a class="c14" href="http://zh.wikipedia.org/wiki/%E6%B3%95%E8%AF%AD" style="text-decoration: inherit; ">法语</a></span> 、<span class="c6" style="color: rgb(17, 85, 204); text-decoration: underline; "><a class="c14" href="http://zh.wikipedia.org/wiki/%E8%A5%BF%E7%8F%AD%E7%89%99%E8%AF%AD" style="text-decoration: inherit; ">西班牙语</a></span> 等不再列出,请参考相关资料。</p><p class="c0 c4" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; height: 11pt; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "></p><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; ">不同语言间Collation差异举例:</p><ol class="c13" start="1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; list-style-type: disc; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "><li class="c3 c0" style="padding-left: 0pt; margin-left: 36pt; direction: ltr; ">在瑞典语中z < ö,而在德语中ö < z。</li><li class="c3 c0" style="padding-left: 0pt; margin-left: 36pt; direction: ltr; ">在西班牙语中连字ch 在c之后,而在斯洛伐克语中 ch 看做独立字符排在 h 之后。</li><li class="c3 c0" style="padding-left: 0pt; margin-left: 36pt; direction: ltr; ">同样是在德语中,按字典规则:of < öf,而按电话簿规则:öf < of。</li><li class="c3 c0" style="padding-left: 0pt; margin-left: 36pt; direction: ltr; ">在主要的拉丁语言中,ø被看作是o的语音变种排在o旁边,而在挪威和丹麦语中是在z之后的独立字母。</li></ol><p class="c0 c4" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; height: 11pt; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "></p><p class="c0 c4" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; height: 11pt; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "></p><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "><span class="c8" style="background-color: rgb(255, 255, 255); ">大多数Collation有许多个规则:不仅仅是大小写不敏感,还包括重音符不敏感(“重音符” 是附属于一个字母的符号,象德语的‘</span>Ö<span class="c8" style="background-color: rgb(255, 255, 255); ">’符号)和多字节映射(例如,作为规则‘</span>Ö<span class="c8" style="background-color: rgb(255, 255, 255); ">’=‘OE’就是两个德语校对规则的一种)。</span></p><p class="c0 c4" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; height: 11pt; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "><span class="c8" style="background-color: rgb(255, 255, 255); "></span></p><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "><span class="c8" style="background-color: rgb(255, 255, 255); ">Collation是随国家、语言、文化的不同而不同的。比如德国、法国、瑞典对同样字符的排序是不同的。甚至对同一种语言也可能有不同的排序方式。西方语言一般是以字母表的顺序为基础,而东方语言一般是以语音或者字形为基础的。Collation也可以根据用户的偏好来设置,比如是否忽略标点、大写字母在小写字母之前还是之后。</span></p><p class="c0 c4" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; height: 11pt; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "><span class="c8" style="background-color: rgb(255, 255, 255); "></span></p><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "><span class="c8" style="background-color: rgb(255, 255, 255); ">一个有趣的现象:在我的Chrome浏览器上Ctrl+F搜索</span>Ö<span class="c8" style="background-color: rgb(255, 255, 255); ">会当做o来搜索、</span>ß<span class="c8" style="background-color: rgb(255, 255, 255); ">会当做ss来搜索,而在Firefox和IE就只当做自身来搜索。</span></p><p class="c0 c4" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; height: 11pt; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "><span class="c8" style="background-color: rgb(255, 255, 255); "></span></p><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "><span class="c8" style="background-color: rgb(255, 255, 255); ">Unicode Collation Algorithm (UCA)</span></p><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "><span class="c8" style="background-color: rgb(255, 255, 255); ">UCA是Unicode技术标准 #10 的定义的内容,是说Unicode中如何Collation的。因为Unicode涉及的语言情况很多,充分考虑这些语言要求是比较复杂的。对Collation感兴趣的人强烈建议读此内容。</span></p><p class="c0 c4" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; height: 11pt; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "></p><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; ">collation 不是 code point (binary) order。</p><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; ">字符在字符集中的顺序被称为二进制顺序,Unicode中就叫code point顺序。</p><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; ">二进制顺序对计算机而言是最容易最高效的处理方式,但这种顺序不一定符合人们的期望,比如ascii中大写字母排在小写字母的前面,所以才有collation,它是为了满足语言的特定要求。</p><p class="c0 c4 c22" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; text-indent: 256pt; height: 11pt; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "></p><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; ">严格的说collation是一种排序规则,独立于字符集</p><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; ">一种字符集可以有多种不同的collation。比如瑞典和德国共用大部分相同的字母,但是他们却有不同的排列顺序。</p><p class="c0 c4" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; height: 11pt; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "></p><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; ">单个字符的顺序不意味着多字符也是这样,比如:</p><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; ">x < y 不意味着 xz < yz</p><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; ">x < y 不意味着 zx < zy</p><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; ">xz < yz 不意味着 x < y</p><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; ">zx < zy 不意味着 x < y</p><p class="c0 c4" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; height: 11pt; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "></p><p class="c0 c4" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; height: 11pt; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "></p><h2 class="c0" style="padding-top: 18pt; line-height: 1.15; font-size: 14pt; font-family: Arial; padding-bottom: 4pt; direction: ltr; "><a name="h.xjlpnloqtctn"></a>Java中的Collation</h2><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; ">Java 最初就是支持Unicode的:</p><ol class="c13" start="1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; list-style-type: disc; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "><li class="c3 c0" style="padding-left: 0pt; margin-left: 36pt; direction: ltr; ">Java 1.4 支持 Unicode 3.0</li><li class="c3 c0" style="padding-left: 0pt; margin-left: 36pt; direction: ltr; ">Java 5 和 Java 6 支持Unicode 4.0</li><li class="c0 c3" style="padding-left: 0pt; margin-left: 36pt; direction: ltr; ">Java 7支持Unicode 6.0</li></ol><p class="c0 c4" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; height: 11pt; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "></p><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; ">Java中以String、Character为字符串的基础,以及StringBuffer、StringBuilder 。</p><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; ">Java中的java.text包下提供了一些与Collation相关的类,主要是抽象类 Collator 及其具体子类 RuleBasedCollator。</p><p class="c0 c4" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; height: 11pt; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "></p><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; ">相等和大小写问题</p><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; ">String.equals 方法是两个字符串的完全相同才认为是相等的。</p><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; ">String.equalsIgnoreCase 是不区分大小写的比较。</p><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; ">注意:Java中的大小写判断是基于Unicode的,也就是以 <span class="c6" style="color: rgb(17, 85, 204); text-decoration: underline; "><a class="c14" href="ftp://ftp.unicode.org/Public/UNIDATA/UnicodeData.txt" style="text-decoration: inherit; ">UnicodeData</a></span> 文件的大小写映射信息来判断的,不仅仅是指26个字母的大小写,实际上包括了很多字符。</p><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; ">比如:"Ä".equalsIgnoreCase("ä"); 返回true,再比如"Ạ"的小写是"ạ"。</p><p class="c0 c4" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; height: 11pt; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "></p><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; ">但是注意 String.toLowerCase、toUpperCase 和 Character.toLowerCase、toUpperCase稍有区别:</p><ol class="c13" start="1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; list-style-type: disc; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "><li class="c3 c0" style="padding-left: 0pt; margin-left: 36pt; direction: ltr; ">Character.toLowerCase提供char 和 int(code point)来自不同参数的方法</li><li class="c3 c0" style="padding-left: 0pt; margin-left: 36pt; direction: ltr; ">Character.toLowerCase是以UnicodeData 文件的大小写映射信息将字符参数转换</li><li class="c3 c0" style="padding-left: 0pt; margin-left: 36pt; direction: ltr; ">String.toLowerCase 和语言环境有关,默认使用本地Locale规则进行大小写转换,同时也提供了带Locale参数的方法。</li><li class="c3 c0" style="padding-left: 0pt; margin-left: 36pt; direction: ltr; ">通常,应该使用 String.toLowerCase() 将字符映射为小写。String 大小写映射方法有几个胜过 Character 大小写映射方法的优点。String 大小写映射方法可以执行语言环境敏感的映射、上下文相关的映射和 1:M 字符映射,而 Character 大小写映射方法却不能。</li></ol><p class="c0 c4" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; height: 11pt; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "></p><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; ">String.toLowerCase 是和语言环境有关的,例如:土耳其语言环境中,小写字母 i 对应的大写字母不是英文的 I, "i".toUpperCase(new Locale("tr")); //输出 İ (上面有个点),而在一般语言环境中小写 i 对应的大写就是 I 。</p><p class="c0 c4" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; height: 11pt; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "></p><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; ">"ß".toUpperCase(); // 输出 SS。这是1对多的映射。</p><p class="c0 c4" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; height: 11pt; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "></p><p class="c0 c4" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; height: 11pt; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "></p><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; ">Collator 及其子类 RuleBasedCollator.</p><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; ">Collator 是用于字符串比较的,所以它实现了Comparator接口。当然String类自身就实现了Comparable 接口。他们的差异是String的比较是按照字典排序的。而Collator 提供了区分语言环境的 String 比较,而进一步说是和Unicode Collation Algorithm (UCA)相关的比较方式。(另外 ICU 提供了C/C++和Java的UCA实现,它是一个Unicode和国际化支持的库。)</p><p class="c0 c4" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; height: 11pt; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "></p><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; ">Java中Collator 提供了四种强度的差异级别:PRIMARY、SECONDARY、TERTIARY 和 IDENTICAL。具体每个级别的含义和特定的Locale相关。</p><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; ">例如在Locale.US等环境下,PRIMARY和SECONDARY强度是下不区分大小写的。</p><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; ">捷克语中,"e" 和 "f" 被认为是 PRIMARY 差异,而 "e" 和 "ě" 则是 SECONDARY 差异,"e" 和 "E" 是 TERTIARY 差异,"e" 和 "e" 是 IDENTICAL。</p><p class="c0 c4" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; height: 11pt; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "></p><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; ">由于这种Collation实现比较稍复杂,而一般对String 列表排序的话,每个 String 要进行多次比较。所以从性能考虑,可以利用Collator类先将要比较的字符串一次性转换为CollationKey对象再做比较。</p><p class="c0 c4" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; height: 11pt; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "></p><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; ">RuleBasedCollator 类是 Collator 的具体子类,它提供了一个简单的、数据驱动的表的 collator。利用它自定义collation的时候只要设计规则就行了。实际上抽象类Collator的工厂方法返回的特定 Locale的实例其实就是定义了某种规则的RuleBasedCollator对象。</p><p class="c0 c4" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; height: 11pt; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "></p><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; ">随便说点Java字符串的基础部分:</p><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; ">Java的内部字符是以UTF-16为编码的,实际上UTF-16是变长编码。当初Java是以早期的Unicode为参考的,那时所有Unicode只需要16位就能表示(现在的BMP部分),所以char 选择了固定宽度的16位来表示一个字符。String内部是以char为基础的,索引值是指的char。但是后来Unicode中的字符数早就超过了这个限制。现在char 只能表示BMP部分的代码点(code point),BMP以外的增补字符需要2个char来表示,所以char被称为代码单元(code unit),而Unicode 代码点才表示真正的字符。int 是32位,在Java中用来表示所有的code point。因为以char为参数的方法处理不了增补字符,所以现在一般会提供两种方法以char为参数的和以int为参数的方法。</p><p class="c0 c4" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; height: 11pt; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "></p><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; ">由于这个历史原因,导致Java 中常见的误解是char表示一个字符、length方法返回的是字符长度。实际上char是代码单元(code unit)、length返回是char的数量。而际上char是16位,只能表示基本字符BMP,而增补字符多于16位需要2个char来表示。所以求字符串长度或迭代字符的时候,完全正确的方法是使用基于代码点(code point)的方法,否则可能有误。</p><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; ">比如求String s的长度是: s.codePointCount(0, s.length());</p><p class="c0 c4" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; height: 11pt; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "></p><p class="c0 c4" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; height: 11pt; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "></p><p class="c0 c4" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; height: 11pt; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "></p><h2 class="c0" style="padding-top: 18pt; line-height: 1.15; font-size: 14pt; font-family: Arial; padding-bottom: 4pt; direction: ltr; "><a name="h.471qs9rr4bhq"></a>Mysql相关</h2><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; ">对数据库而言,Collation是很重要的,对于查找和排序需要符合用户语言环境的期望结果。</p><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; ">Mysql支持很多字符集和collation,每种字符集对应一种或多种collation,每个字符集有一个默认collation。mysql 各字符集的默认collation都是不区分大小写(xxx_ci)。</p><p class="c0 c4" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; height: 11pt; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "></p><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; ">查看mysql支持的字符集及其默认collation命令:SHOW CHARACTER SET;</p><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; ">查看mysql支持的collation的命令:SHOW COLLATION;</p><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; ">上面两个语句都可附加like 做条件限定,如 LIKE 'utf8%' 。</p><p class="c0 c4" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; height: 11pt; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "></p><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; ">mysql collation命名约定:以相关的字符集名开始,通常包括一个语言名,并且以_ci(大小写不敏感)、_cs(大小写敏感)或_bin(二进制)结束。</p><p class="c0 c4" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; height: 11pt; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "></p><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; ">可以设置数据库、表、字段的默认字符集及其collation。</p><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; ">可以在sql语句中指定要使用的collation,如查询字段的条件或排序。BINARY 操作符表示使用二进制collation,相当于使用对应字符集的_bin 的 collation。</p><p class="c0 c4" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; height: 11pt; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "></p><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; ">latin1的默认collation是latin1_swedish_ci,latin1有9种不同的collation:</p><ol class="c13" start="1" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; list-style-type: disc; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "><li class="c3 c0" style="padding-left: 0pt; margin-left: 36pt; direction: ltr; ">latin1_german1_ci</li><li class="c3 c0" style="padding-left: 0pt; margin-left: 36pt; direction: ltr; ">latin1_swedish_ci</li><li class="c3 c0" style="padding-left: 0pt; margin-left: 36pt; direction: ltr; ">latin1_danish_ci</li><li class="c3 c0" style="padding-left: 0pt; margin-left: 36pt; direction: ltr; ">latin1_german2_ci</li><li class="c3 c0" style="padding-left: 0pt; margin-left: 36pt; direction: ltr; ">latin1_bin</li><li class="c3 c0" style="padding-left: 0pt; margin-left: 36pt; direction: ltr; ">latin1_general_ci</li><li class="c3 c0" style="padding-left: 0pt; margin-left: 36pt; direction: ltr; ">latin1_general_cs</li><li class="c3 c0" style="padding-left: 0pt; margin-left: 36pt; direction: ltr; ">latin1_spanish_ci</li></ol><p class="c0 c4" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; height: 11pt; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "></p><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; ">utf8的默认collation是utf8_general_ci ,还有utf8_unicode_ci、utf8_bin 以及针对不同语言的utf8 。utf8_unicode_ci是根据Unicode校对规则算法(UCA)执行的。utf8_unicode_ci的最主要的特色是支持扩展,即当把一个字母看作与其它字母组合相等时。例如,在德语中‘ß’等于‘ss’。</p><p class="c0 c4" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; height: 11pt; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "></p><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; ">utf8_general_ci是一个遗留的校对规则,不支持扩展。它仅能够在字符之间进行逐个比较。但utf8_general_ci校对规则进行的比较速度很快,但是与使用utf8_unicode_ci相比正确性稍差。</p><p class="c0 c4" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; height: 11pt; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "></p><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; ">例如,utf8_general_ci和utf8_unicode_ci 都认为Ä = A、Ö = O、Ü = U。差异在于utf8_general_ci 认为ß = s ,而utf8_unicode_ci 认为ß = ss。</p><p class="c0 c4" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; height: 11pt; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "></p><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; ">utf8_unicode_ci 对德语和法语都工作得很好,所以不需要再单独建立对应的utf8校对规则。</p><p class="c0 c4" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; height: 11pt; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "></p><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; ">utf8_swedish_ci,与其它语言相关的utf8的校对规则相似,来源于utf8_unicode_ci,使用额外的语言规则。例如,在瑞典语中,以下的关系式成立,它在德语和法语中不成立:Ü = Y < Ö</p><p class="c0 c4" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; height: 11pt; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "></p><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; ">utf8_spanish_ci和utf8_spanish2_ci校对规则分别适用于现代和古典西班牙语。在两种校对规则中,ñ’(n-发音符)是‘n’和‘o’之间的间隔字母。另外,对于古典西班牙语,‘ch’是‘c’和d之间的间隔字母,并且‘ll’是‘l’和‘m’之间的间隔字母。</p><p class="c0 c4" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; height: 11pt; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "></p><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; ">latin1_german1_ci和latin1_german2_ci校对规则基于DIN-1和DIN-2标准,这里DIN代表Deutsches Institut für Normung。DIN-1被叫做“字典校对规则”,DIN-2被叫做“电话簿校对规则”。</p><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; ">DIN-1中:Ä = a、Ö = O、Ü = U、ß = s</p><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; ">DIN-2中:Ä = aE、Ö = OE、Ü = UE、ß = ss</p><p class="c0 c4" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; height: 11pt; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "></p><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; ">中文字符集gbk,只有gbk_chinese_ci和gbk_bin两种。实际上除了latin和unicode系列外,其它很多字符集大都以这两种形式出现。</p><p class="c0 c4" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; height: 11pt; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "></p><p class="c0 c4" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; height: 11pt; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "></p><p class="c0 c4" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; height: 11pt; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "></p><h2 class="c0" style="padding-top: 18pt; line-height: 1.15; font-size: 14pt; font-family: Arial; padding-bottom: 4pt; direction: ltr; "><a name="h.esap67qtbftf"></a>参考资料:</h2><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "><span class="c6 c8" style="color: rgb(17, 85, 204); text-decoration: underline; background-color: rgb(255, 255, 255); "><a class="c14" href="http://www.unicode.org/reports/tr10/" style="text-decoration: inherit; ">Unicode Collation Algorithm(UCA)</a></span><span class="c8" style="background-color: rgb(255, 255, 255); "> 及其 </span><span class="c6 c8" style="color: rgb(17, 85, 204); text-decoration: underline; background-color: rgb(255, 255, 255); "><a class="c14" href="http://unicode.org/faq/collation.html" style="text-decoration: inherit; ">FAQ</a></span></p><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "><span class="c6 c8" style="color: rgb(17, 85, 204); text-decoration: underline; background-color: rgb(255, 255, 255); "><a class="c14" href="http://site.icu-project.org/" style="text-decoration: inherit; ">ICU</a></span><span class="c8" style="background-color: rgb(255, 255, 255); "> (International Components for Unicode)提供C/C++、Java的UCA 实现支持。</span></p><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "><span class="c8" style="background-color: rgb(255, 255, 255); ">Wiki条目: </span><span class="c6 c8" style="color: rgb(17, 85, 204); text-decoration: underline; background-color: rgb(255, 255, 255); "><a class="c14" href="http://en.wikipedia.org/wiki/Collation" style="text-decoration: inherit; ">Collation</a></span> , <span class="c6" style="color: rgb(17, 85, 204); text-decoration: underline; "><a class="c14" href="http://zh.wikipedia.org/wiki/%E5%BE%B7%E8%AF%AD" style="text-decoration: inherit; ">德语</a></span> , <span class="c6" style="color: rgb(17, 85, 204); text-decoration: underline; "><a class="c14" href="http://zh.wikipedia.org/wiki/%E6%B3%95%E8%AF%AD" style="text-decoration: inherit; ">法语</a></span> , <span class="c6" style="color: rgb(17, 85, 204); text-decoration: underline; "><a class="c14" href="http://zh.wikipedia.org/wiki/%E7%91%9E%E5%85%B8%E8%AA%9E" style="text-decoration: inherit; ">瑞典语</a></span> , <span class="c6" style="color: rgb(17, 85, 204); text-decoration: underline; "><a class="c14" href="http://zh.wikipedia.org/wiki/%E8%A5%BF%E7%8F%AD%E7%89%99%E8%AF%AD" style="text-decoration: inherit; ">西班牙语</a></span><span class="c8" style="background-color: rgb(255, 255, 255); "> , </span><span class="c6 c8" style="color: rgb(17, 85, 204); text-decoration: underline; background-color: rgb(255, 255, 255); "><a class="c14" href="http://zh.wikipedia.org/wiki/%E6%8B%89%E4%B8%81%E5%AD%97%E6%AF%8D" style="text-decoration: inherit; ">拉丁字母</a></span></p><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "><span class="c6 c8" style="color: rgb(17, 85, 204); text-decoration: underline; background-color: rgb(255, 255, 255); "><a class="c14" href="http://www.collation-charts.org/" style="text-decoration: inherit; ">Collation Charts</a></span></p><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; "><span class="c6 c8" style="color: rgb(17, 85, 204); text-decoration: underline; background-color: rgb(255, 255, 255); "><a class="c14" href="http://dev.mysql.com/doc/refman/5.5/en/charset.html" style="text-decoration: inherit; ">Mysql 相关文档</a></span></p><p class="c0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; direction: ltr; font-family: Arial; font-size: 15px; text-align: -webkit-auto; ">Java Api: <span class="c6 c8" style="color: rgb(17, 85, 204); text-decoration: underline; background-color: rgb(255, 255, 255); "><a class="c14" href="http://docs.oracle.com/javase/7/docs/api/java/text/Collator.html" style="text-decoration: inherit; ">java.text.Collator</a></span><span class="c8" style="background-color: rgb(255, 255, 255); "> 、</span><span class="c6 c8" style="color: rgb(17, 85, 204); text-decoration: underline; background-color: rgb(255, 255, 255); "><a class="c14" href="http://docs.oracle.com/javase/7/docs/api/java/text/RuleBasedCollator.html" style="text-decoration: inherit; ">java.text.RuleBasedCollator</a></span></p><div><br /></div>hgkhttp://www.blogger.com/profile/18248256147814166844noreply@blogger.com5tag:blogger.com,1999:blog-3051279638784476121.post-44371636827261615352011-10-16T09:54:00.000-07:002011-10-16T09:57:15.913-07:00浏览器窗口标题栏闪烁通知<span class="Apple-style-span" style="color: rgb(51, 51, 51); font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; line-height: 25px; background-color: rgb(255, 255, 255); "><span style="line-height: 23px; "><span style="line-height: 23px; border-collapse: collapse; "><div style="line-height: normal; "><span style="line-height: 23px; "><span style="line-height: normal; border-collapse: collapse; ">对于WebIM 对话或其它各种Comet应用场景,当收到新消息时,希望能够及时提醒用户。</span></span></div></span></span><span style="line-height: normal; border-collapse: collapse; font-family: arial, sans-serif; font-size: small; "><div style="line-height: 23px; "><span style="line-height: normal; border-collapse: collapse; font-family: arial, sans-serif; font-size: small; "><br /></span></div><div style="line-height: 23px; "><span style="line-height: normal; border-collapse: collapse; font-family: arial, sans-serif; font-size: small; "><br /></span></div>但是用户</span><span style="line-height: 20px; border-collapse: collapse; font-family: arial, sans-serif; font-size: 13px; ">可能将窗口切换到计算机上其它窗口上了,<wbr style="line-height: 20px; ">比如看其它网页、</span><span style="line-height: 20px; border-collapse: collapse; font-family: arial, sans-serif; font-size: 13px; ">聊一下QQ、收发一下邮件等各种其它事情,此时web窗口就不在用户焦点上了,收到的新消息时很可能看不到。而</span><span style="line-height: normal; border-collapse: collapse; font-family: arial, sans-serif; font-size: small; ">javascript控制的web窗口并不能很好融入到OS级别的窗口系统中。比较普遍的一种做法就是让浏览器标题栏不断闪烁,</span><span style="line-height: 20px; border-collapse: collapse; font-family: arial, sans-serif; font-size: 13px; ">应用程序的标题闪烁是很容易被注意到的,</span><span style="line-height: 20px; border-collapse: collapse; font-family: arial, sans-serif; font-size: 13px; ">不管是浏览器和其它各种程序之间,还是浏览器多tab或windows之间。</span><span style="line-height: normal; border-collapse: collapse; font-family: arial, sans-serif; font-size: small; ">这算是最接近OS级别窗口的提示方式了。</span><div style="line-height: 25px; "><div style="line-height: 25px; "><div style="line-height: 25px; "><span style="line-height: 23px; "><span style="line-height: normal; border-collapse: collapse; "><div style="line-height: 23px; "><br /></div><div style="line-height: 23px; "><br /></div></span></span><span style="line-height: normal; border-collapse: collapse; font-family: arial, sans-serif; font-size: 13px; "><div style="line-height: 23px; ">实现的目标:</div><div style="line-height: 23px; "><ul style="line-height: 23px; margin-top: 5px; margin-right: 0px; margin-bottom: 5px; margin-left: 40px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><li style="line-height: 23px; margin-left: 15px; ">当对话窗口失去焦点(切换到其它程序或其它浏览器窗口),<wbr style="line-height: 23px; ">并且收到新消息时,标题栏闪烁。</li><li style="line-height: 23px; margin-left: 15px; ">没有失去焦点时不闪烁提示。焦点重新回到窗口时,<wbr style="line-height: 23px; ">标题栏恢复正常不再闪烁。</li></ul></div></span><span style="line-height: 25px; "><span style="line-height: normal; border-collapse: collapse; "><div style="line-height: 23px; font-size: small; "><span style="line-height: 23px; "><span style="line-height: normal; border-collapse: collapse; "><br /></span></span></div><div style="line-height: 23px; font-size: small; "><span style="line-height: 23px; "><span style="line-height: normal; border-collapse: collapse; "><br /></span></span></div><div style="line-height: 25px; "><span style="line-height: 28px; "><span style="line-height: normal; border-collapse: collapse; ">一、标题栏的闪烁</span></span></div></span></span><span style="line-height: 23px; "><span style="line-height: normal; border-collapse: collapse; ">要实现标题栏闪烁的效果很简单,只要</span></span><wbr style="line-height: 25px; "><span style="line-height: 23px; "><span style="line-height: normal; border-collapse: collapse; ">让 title 的内容来回变化就可以。</span></span><div style="line-height: normal; border-collapse: collapse; font-family: arial, sans-serif; font-size: 13px; ">比如每500ms,</div><div style="line-height: normal; border-collapse: collapse; font-family: arial, sans-serif; font-size: 13px; ">document.title=“【您有新的消息】”</div><div style="line-height: normal; border-collapse: collapse; font-family: arial, sans-serif; font-size: 13px; ">下次</div><div style="line-height: normal; border-collapse: collapse; font-family: arial, sans-serif; font-size: 13px; ">document.title=“【 】”</div><div style="line-height: normal; border-collapse: collapse; font-family: arial, sans-serif; font-size: 13px; ">这样来回变化就实现了闪烁效果。</div><div style="line-height: normal; border-collapse: collapse; font-family: arial, sans-serif; font-size: 13px; "><br /></div><div style="line-height: normal; border-collapse: collapse; font-family: arial, sans-serif; font-size: 13px; "><br /></div><div style="line-height: normal; border-collapse: collapse; font-family: arial, sans-serif; font-size: 13px; "><br /></div><div style="line-height: normal; border-collapse: collapse; font-family: arial, sans-serif; "><span style="line-height: 28px; ">二、浏览器窗口焦点的判断</span></div><div style="line-height: 23px; border-collapse: collapse; font-family: arial, sans-serif; font-size: 13px; ">根据目标的要求,<span style="line-height: normal; ">首先要知道当前窗口激活状态。</span></div><div style="line-height: 23px; border-collapse: collapse; font-family: arial, sans-serif; font-size: 13px; "><span style="line-height: normal; "><br /></span></div><div style="line-height: normal; border-collapse: collapse; font-family: arial, sans-serif; font-size: 13px; ">注册window.onblur和window.<wbr style="line-height: 23px; ">onfocus函数来记录焦点变化,但是IE上的行为有差异,<wbr style="line-height: 23px; ">不能直接用,而应该用document.<wbr style="line-height: 23px; ">onfocusin和document.onfocusout。</div><div style="line-height: normal; border-collapse: collapse; font-family: arial, sans-serif; font-size: 13px; ">关于window或Dom元素的focus焦点这方面的行为,<wbr style="line-height: 23px; ">各浏览器行为有差异,尤其IE的行为有很多bug。</div><div style="line-height: normal; border-collapse: collapse; font-family: arial, sans-serif; font-size: 13px; "><br /></div><div style="line-height: 23px; border-collapse: collapse; font-family: arial, sans-serif; font-size: 13px; "><span style="line-height: 23px; color: rgb(204, 0, 0); font-family: '??'; ">//当前浏览器窗口是否处于焦点</span></div><div style="line-height: normal; border-collapse: collapse; "><div style="line-height: 23px; font-size: 13px; "><pre style="line-height: 23px; font-family: arial, sans-serif; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; text-indent: 0px; background-color: rgb(255, 255, 255); "><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 153, 102); ">var</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(0, 0, 0); "> isWindowFocus </span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 0, 0); ">=</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(0, 0, 0); "> </span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 153, 102); ">true</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 0, 0); ">;</span></pre><pre style="line-height: 23px; font-family: arial, sans-serif; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; text-indent: 0px; background-color: rgb(255, 255, 255); "><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 153, 102); ">function</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(0, 0, 0); "> </span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(153, 102, 255); ">focusin</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 0, 0); ">() {</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(0, 0, 0); "> isWindowFocus</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 0, 0); ">=</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 153, 102); ">true</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 0, 0); ">;}</span></pre><pre style="line-height: 23px; font-family: arial, sans-serif; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; text-indent: 0px; background-color: rgb(255, 255, 255); "><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 153, 102); ">function</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(0, 0, 0); "> </span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(153, 102, 255); ">focusout</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 0, 0); ">() {</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(0, 0, 0); "> isWindowFocus</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 0, 0); ">=</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 153, 102); ">false</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 0, 0); ">;}</span></pre><pre style="line-height: 23px; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; text-indent: 0px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); "></pre><pre style="line-height: 23px; font-family: arial, sans-serif; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; text-indent: 0px; background-color: rgb(255, 255, 255); "><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(204, 0, 0); ">//注册焦点变化监听器</span></pre><pre style="line-height: 23px; font-family: arial, sans-serif; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; text-indent: 0px; background-color: rgb(255, 255, 255); "><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 153, 102); ">if</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(0, 0, 0); "> </span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 0, 0); ">(</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(255, 0, 204); ">"onfocusin"</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(0, 0, 0); "> </span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 153, 102); ">in</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(0, 0, 0); "> document</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 0, 0); ">){</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(204, 0, 0); ">//for IE </span></pre><pre style="line-height: 23px; font-family: arial, sans-serif; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; text-indent: 0px; background-color: rgb(255, 255, 255); "><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(0, 0, 0); "> document</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 0, 0); ">.</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(0, 0, 0); ">onfocusin </span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 0, 0); ">=</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(0, 0, 0); "> focusin</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 0, 0); ">;</span></pre><pre style="line-height: 23px; font-family: arial, sans-serif; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; text-indent: 0px; background-color: rgb(255, 255, 255); "><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(0, 0, 0); "> document</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 0, 0); ">.</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(0, 0, 0); ">onfocusout </span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 0, 0); ">=</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(0, 0, 0); "> focusout</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 0, 0); ">;</span></pre><pre style="line-height: 23px; font-family: arial, sans-serif; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; text-indent: 0px; background-color: rgb(255, 255, 255); "><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 0, 0); ">}</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(0, 0, 0); "> </span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 153, 102); ">else</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(0, 0, 0); "> </span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 0, 0); ">{</span></pre><pre style="line-height: 23px; font-family: arial, sans-serif; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; text-indent: 0px; background-color: rgb(255, 255, 255); "><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(0, 0, 0); "> window</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 0, 0); ">.</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(0, 0, 0); ">onblur </span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 0, 0); ">=</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(0, 0, 0); "> focusout</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 0, 0); ">;</span></pre><pre style="line-height: 23px; font-family: arial, sans-serif; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; text-indent: 0px; background-color: rgb(255, 255, 255); "><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(0, 0, 0); "> window</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 0, 0); ">.</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(0, 0, 0); ">onfocus</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 0, 0); ">=</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(0, 0, 0); "> focusin</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 0, 0); ">;</span></pre><pre style="line-height: 23px; font-family: arial, sans-serif; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; text-indent: 0px; background-color: rgb(255, 255, 255); "><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 0, 0); ">}</span></pre></div><div style="line-height: 23px; font-family: arial, sans-serif; font-size: 13px; "><br /></div><div style="line-height: 23px; font-family: arial, sans-serif; font-size: 13px; "><br /></div><div style="line-height: 23px; font-family: arial, sans-serif; font-size: 13px; "><br /></div><div style="line-height: 25px; font-family: arial, sans-serif; "><span style="line-height: 28px; ">三、具体实现</span></div><div style="line-height: 23px; font-family: arial, sans-serif; font-size: 13px; ">使用方式:<wbr style="line-height: 23px; ">每当收到新消息时就调用 doFlashTitle 方法实现闪烁,调用者不做任何判断。</div><div style="line-height: 23px; font-family: arial, sans-serif; font-size: 13px; ">要求:</div><div style="line-height: 23px; font-family: arial, sans-serif; font-size: 13px; ">1.如果当前窗口失去焦点一直执行title闪烁,<wbr style="line-height: 23px; ">如果当前处于窗口焦点则什么也不做。</div><div style="line-height: 23px; font-family: arial, sans-serif; font-size: 13px; ">2.当窗口重新获得焦点时,停止闪烁(退出闪烁循环)。</div><div style="line-height: 23px; font-family: arial, sans-serif; font-size: 13px; ">3.多次调用,闪烁循环本身只应执行一次。<wbr style="line-height: 23px; ">也就是说闪烁函数只同时运行一个,<wbr style="line-height: 23px; ">否则多个同样的调用一起执行的话会导致标题闪动异常(快),<wbr style="line-height: 23px; ">消耗资源。</div><div style="line-height: 23px; font-family: arial, sans-serif; font-size: 13px; "><br /></div><div style="line-height: 23px; font-family: arial, sans-serif; font-size: 13px; "><div style="line-height: 23px; "><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(204, 0, 0); ">//实现标题闪动效果</span><p style="line-height: 23px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "></p><pre style="line-height: 23px; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; text-indent: 0px; background-color: rgb(255, 255, 255); "><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 153, 102); ">var</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(0, 0, 0); "> flashStep</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 0, 0); ">=</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(255, 0, 0); ">0</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 0, 0); ">;</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(0, 0, 0); "> </span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(204, 0, 0); ">//交替变量</span></pre><pre style="line-height: 23px; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; text-indent: 0px; background-color: rgb(255, 255, 255); "><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 153, 102); ">var</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(0, 0, 0); "> flashTitleRun </span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 0, 0); ">=</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(0, 0, 0); "> </span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 153, 102); ">false</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 0, 0); ">;</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(0, 0, 0); "> </span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(204, 0, 0); ">//是否正在执行</span></pre><pre style="line-height: 23px; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; text-indent: 0px; background-color: rgb(255, 255, 255); "><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 153, 102); ">var</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(0, 0, 0); "> normalTitle </span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 0, 0); ">=</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(0, 0, 0); "> </span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(255, 0, 204); ">"正常显示的标题"</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 0, 0); ">;</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(0, 0, 0); "> </span></pre><pre style="line-height: 23px; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; text-indent: 0px; background-color: rgb(255, 255, 255); "><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 153, 102); ">function</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(0, 0, 0); "> </span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(153, 102, 255); ">flashTitle</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 0, 0); ">()</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(0, 0, 0); "> </span></pre><pre style="line-height: 23px; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; text-indent: 0px; background-color: rgb(255, 255, 255); "><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 0, 0); ">{</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(0, 0, 0); "> </span></pre><pre style="line-height: 23px; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; text-indent: 0px; background-color: rgb(255, 255, 255); "><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(0, 0, 0); "> </span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(204, 0, 0); ">//仅窗口不在焦点时闪烁title,回到焦点时停止闪烁并将title恢复正常</span></pre><pre style="line-height: 23px; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; text-indent: 0px; background-color: rgb(255, 255, 255); "><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(0, 0, 0); "> </span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 153, 102); ">if</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 0, 0); ">(</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(0, 0, 0); ">isWindowFocus</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 0, 0); ">){</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(204, 0, 0); ">//当前处于焦点</span></pre><pre style="line-height: 23px; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; text-indent: 0px; background-color: rgb(255, 255, 255); "><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(0, 0, 0); "> document</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 0, 0); ">.</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(0, 0, 0); ">title</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 0, 0); ">=</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(0, 0, 0); ">normalTitle</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 0, 0); ">;</span></pre><pre style="line-height: 23px; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; text-indent: 0px; background-color: rgb(255, 255, 255); "><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(0, 0, 0); "> flashTitleRun </span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 0, 0); ">=</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(0, 0, 0); "> </span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 153, 102); ">false</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 0, 0); ">;</span></pre><pre style="line-height: 23px; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; text-indent: 0px; background-color: rgb(255, 255, 255); "><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(0, 0, 0); "> </span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 153, 102); ">return</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 0, 0); ">;</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(204, 0, 0); ">//退出循环</span></pre><pre style="line-height: 23px; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; text-indent: 0px; background-color: rgb(255, 255, 255); "><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(0, 0, 0); "> </span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 0, 0); ">}</span></pre><pre style="line-height: 23px; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; text-indent: 0px; background-color: rgb(255, 255, 255); "><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(0, 0, 0); "> </span></pre><pre style="line-height: 23px; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; text-indent: 0px; background-color: rgb(255, 255, 255); "><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(0, 0, 0); "> flashTitleRun </span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 0, 0); ">=</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(0, 0, 0); "> </span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 153, 102); ">true</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 0, 0); ">;</span></pre><pre style="line-height: 23px; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; text-indent: 0px; background-color: rgb(255, 255, 255); "><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(0, 0, 0); "> flashStep</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 0, 0); ">++;</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(0, 0, 0); "> </span></pre><pre style="line-height: 23px; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; text-indent: 0px; background-color: rgb(255, 255, 255); "><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(0, 0, 0); "> </span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 153, 102); ">if</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(0, 0, 0); "> </span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 0, 0); ">(</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(0, 0, 0); ">flashStep</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 0, 0); ">==</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(255, 0, 0); ">3</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 0, 0); ">) {</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(0, 0, 0); ">flashStep</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 0, 0); ">=</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(255, 0, 0); ">1</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 0, 0); ">;}</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(0, 0, 0); "> </span></pre><pre style="line-height: 23px; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; text-indent: 0px; background-color: rgb(255, 255, 255); "><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(0, 0, 0); "> </span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 153, 102); ">if</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(0, 0, 0); "> </span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 0, 0); ">(</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(0, 0, 0); ">flashStep</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 0, 0); ">==</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(255, 0, 0); ">1</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 0, 0); ">) {</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(0, 0, 0); ">document</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 0, 0); ">.</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(0, 0, 0); ">title</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 0, 0); ">=</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(255, 0, 204); ">"【您有新的消息】"</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 0, 0); ">;}</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(0, 0, 0); "> </span></pre><pre style="line-height: 23px; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; text-indent: 0px; background-color: rgb(255, 255, 255); "><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(0, 0, 0); "> </span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 153, 102); ">if</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(0, 0, 0); "> </span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 0, 0); ">(</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(0, 0, 0); ">flashStep</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 0, 0); ">==</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(255, 0, 0); ">2</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 0, 0); ">) {</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(0, 0, 0); ">document</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 0, 0); ">.</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(0, 0, 0); ">title</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 0, 0); ">=</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(255, 0, 204); ">"【 】"</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 0, 0); ">;}</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(0, 0, 0); "> </span></pre><pre style="line-height: 23px; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; text-indent: 0px; background-color: rgb(255, 255, 255); "><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(0, 0, 0); "> </span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(153, 102, 255); ">setTimeout</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 0, 0); ">(</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(255, 0, 204); ">"flashTitle()"</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 0, 0); ">,</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(255, 0, 0); ">500</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 0, 0); ">);</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(0, 0, 0); "> </span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(204, 0, 0); ">//循环</span></pre><pre style="line-height: 23px; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; text-indent: 0px; background-color: rgb(255, 255, 255); "><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 0, 0); ">}</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(0, 0, 0); "> </span></pre><pre style="line-height: 23px; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; text-indent: 0px; font-family: '??'; font-size: 10pt; color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); "></pre><pre style="line-height: 23px; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; text-indent: 0px; background-color: rgb(255, 255, 255); "><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(204, 0, 0); ">//调用这个执行标题闪烁,而不是直接调用flashTitle,保证多次调用只会执行一次。</span></pre><pre style="line-height: 23px; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; text-indent: 0px; background-color: rgb(255, 255, 255); "><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 153, 102); ">function</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(0, 0, 0); "> </span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(153, 102, 255); ">doFlashTitle</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 0, 0); ">(){</span></pre><pre style="line-height: 23px; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; text-indent: 0px; background-color: rgb(255, 255, 255); "><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(0, 0, 0); "> </span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 153, 102); ">if</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 0, 0); ">(!</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(0, 0, 0); ">flashTitleRun</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 0, 0); ">)</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(204, 0, 0); ">//没有执行时,才执行</span></pre><pre style="line-height: 23px; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; text-indent: 0px; background-color: rgb(255, 255, 255); "><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(0, 0, 0); "> </span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; color: rgb(153, 102, 255); ">flashTitle</span><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 0, 0); ">();</span></pre><pre style="line-height: 23px; margin-top: 0px; margin-bottom: 12px; margin-left: 0px; margin-right: 0px; text-indent: 0px; background-color: rgb(255, 255, 255); "><span style="line-height: 23px; font-family: '??'; font-size: 10pt; font-weight: 600; color: rgb(0, 0, 0); ">}</span></pre></div></div></div><div style="line-height: normal; border-collapse: collapse; font-family: arial, sans-serif; font-size: 13px; "><br /></div><div style="line-height: normal; border-collapse: collapse; font-family: arial, sans-serif; font-size: 13px; "><br /></div><div style="line-height: normal; border-collapse: collapse; font-family: arial, sans-serif; "><span style="line-height: 28px; ">四、小结</span></div><div style="line-height: normal; border-collapse: collapse; font-family: arial, sans-serif; font-size: 13px; ">title闪烁并不难,但跨浏览器的焦点判断的问题比较多,IE非常诡异。参考资料都是焦点判断方面的。</div><div style="line-height: normal; border-collapse: collapse; font-family: arial, sans-serif; font-size: 13px; ">只能判断出窗口焦点是否激活,没有办法判断窗口对人是不是可见的。</div><div style="line-height: normal; border-collapse: collapse; font-family: arial, sans-serif; font-size: 13px; "><br /></div><div style="line-height: normal; border-collapse: collapse; font-family: arial, sans-serif; font-size: 13px; ">在js中调用window.focus()方法,窗口到底会不会被激活是完全不可靠的。而在IE上执行此方法,不管窗口是否激活了,都会导致focus事件的触发,使得上述的判断方法认为已经获得焦点了,但其实没有。所以最好就不要再使用window或dom的focus方法,以免干扰判断。而非IE浏览器正常,只有窗口确实被激活了才触发focus事件。</div><div style="line-height: normal; border-collapse: collapse; font-family: arial, sans-serif; font-size: 13px; "><br /></div><div style="line-height: normal; border-collapse: collapse; font-family: arial, sans-serif; font-size: 13px; "><br /></div><div style="line-height: normal; border-collapse: collapse; font-family: arial, sans-serif; font-size: 13px; ">参考资料:</div><div style="line-height: 25px; "><ul style="line-height: 25px; margin-top: 5px; margin-right: 0px; margin-bottom: 5px; margin-left: 40px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><li style="line-height: 25px; "><a target="_blank" rel="nofollow" href="http://stackoverflow.com/questions/3737175/window-onfocus-not-firing-in-ie7-inconsistent-in-opera" style="line-height: 25px; text-decoration: none; color: rgb(60, 145, 13); ">window.onfocus not firing in IE7, inconsistent in Opera</a><br /><span style="line-height: 23px; "></span></li><li style="line-height: 25px; "><span style="line-height: 23px; "><a target="_blank" rel="nofollow" href="http://odondo.wordpress.com/2007/08/28/javascript-and-cross-browser-window-focus/" style="line-height: 23px; text-decoration: none; color: rgb(60, 145, 13); ">Javascript and Cross-browser Window focus</a></span></li><li style="line-height: 25px; "><span style="line-height: 23px; "><a target="_blank" rel="nofollow" href="http://www.sitepoint.com/forums/javascript-15/check-if-window-focused-582012.html" style="line-height: 23px; text-decoration: none; color: rgb(60, 145, 13); ">Check if window is focused</a></span></li><li style="line-height: 25px; "><span style="line-height: 20px; font-family: arial, sans-serif; font-size: small; "><a target="_blank" rel="nofollow" href="http://javascript.info/tutorial/focus" style="line-height: 23px; text-decoration: none; color: rgb(60, 145, 13); ">Focus/blur methods and events</a></span></li><li style="line-height: 25px; "><span style="line-height: 20px; font-family: arial, sans-serif; font-size: small; "><a target="_blank" rel="nofollow" href="http://www.sitepen.com/blog/2008/10/13/the-cross-browser-window-focus-blues/" style="line-height: 23px; text-decoration: none; color: rgb(60, 145, 13); ">The Cross-Browser Window Focus Blues</a></span></li><li style="line-height: 25px; "><span style="line-height: 20px; font-family: arial, sans-serif; font-size: small; "><a target="_blank" rel="nofollow" href="http://www.sencha.com/forum/showthread.php?65380-2.2-Ext.Viewport-utilizing-browser-focus-blur-events" style="line-height: 23px; text-decoration: none; color: rgb(60, 145, 13); ">Ext.Viewport - utilizing browser focus/blur events</a></span></li></ul></div></div></div></div></span>hgkhttp://www.blogger.com/profile/18248256147814166844noreply@blogger.com4tag:blogger.com,1999:blog-3051279638784476121.post-18803980670010069262011-10-16T09:49:00.000-07:002011-10-16T09:53:39.401-07:00hotmail前端优化<span class="Apple-style-span" style="color: rgb(51, 51, 51); font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; line-height: 25px; background-color: rgb(255, 255, 255); "><div style="line-height: 25px; ">前两天(2011-7-1),有一篇hotmail前端优化的文章,使用户响应比以前快10倍,自己简单小结一下。原文地址:<a target="_blank" rel="nofollow" href="http://windowsteamblog.com/windows_live/b/windowslive/archive/2011/06/30/instant-email-how-we-made-hotmail-10x-faster.aspx" style="line-height: 25px; text-decoration: none; color: rgb(60, 145, 13); ">这里</a> 。不过,只能说hotmail以前优化做得太少了,这些gmail老早就做了。(遗憾的是国内用户最近访问hotmail也不太顺畅)</div><div style="line-height: 25px; "><br /></div><div style="line-height: 25px; "><br /></div><div style="line-height: 25px; "><div style="line-height: 22px; ">现代浏览器越来越强大,可以把更多的工作从server端交给浏览器去做。更一般地说,C/S模型中,如果C越强大,就可以考虑把更多S的工作放到C中去完成。</div></div><div style="line-height: 25px; "><br /></div><div style="line-height: 25px; "><br /></div><div style="line-height: 25px; ">缓存、预加载、异步操作。</div><div style="line-height: 25px; ">优化的关键是找到平衡点。</div><div style="line-height: 25px; "><br /></div><div style="line-height: 25px; "><br /></div><div style="line-height: 25px; ">缓存:</div><div style="line-height: 25px; ">已加载的数据缓存住,不要每次都重新加载。</div><div style="line-height: 25px; ">即使今天的美国,网络依然是瓶颈。所以数据离浏览器越近就越快。</div><div style="line-height: 25px; ">如果数据不在浏览器,应该使用更加有效的方式获取。</div><div style="line-height: 25px; ">浏览器中可以直接用DOM对象缓存,需要的时候直接切换过去。</div><div style="line-height: 25px; "><br /></div><div style="line-height: 25px; "><br /></div><div style="line-height: 25px; ">缓存的平衡:</div><div style="line-height: 25px; "><div style="line-height: 22px; ">缓存何时需要更新,比如有新邮件时?server通知浏览器,然后浏览器获取数据。也就是,服务器推送通知。</div><div style="line-height: 22px; ">退出hotmail时清掉缓存,保证隐私安全。当然,如果没有安全方面的问题,可以考虑缓存更长时间。</div></div><div style="line-height: 25px; "><br /></div><div style="line-height: 25px; "><br /></div><div style="line-height: 25px; ">预加载:</div><div style="line-height: 25px; ">如果内容已经有了,响应自然就是即时的。</div><div style="line-height: 25px; ">预加载的数据类型:可以是数据,也可以是代码。</div><div style="line-height: 25px; "><br /></div><div style="line-height: 25px; ">什么时候预加载什么?</div><div style="line-height: 25px; ">原则上说应该预加载最有效的、命中率高的内容。而这<b style="line-height: 25px; ">要基于用户的行为特征</b>,也就是通过用户(各阶段的)行为分析来决定。</div><div style="line-height: 25px; ">比如:</div><div style="line-height: 25px; "><ul style="line-height: 25px; margin-top: 5px; margin-right: 0px; margin-bottom: 5px; margin-left: 40px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><li style="line-height: 25px; ">用户一上来一般会查看列表中新邮件标题,然后会选择查看他们,利用用户这个停顿的时机来预加载新邮件的内容。</li><li style="line-height: 25px; ">用户看这封邮件的内容很可能也会看挨着的下一封或上一封邮件的内容,所以可以预加载下一封邮件内容。</li><li style="line-height: 25px; ">用户看这封邮件的时候,下一步的行为可能是删除或回复,所以可以预加载好删除和回复的代码和数据(发送时需要有地址簿的数据)。</li></ul></div><div style="line-height: 25px; "><br /></div><div style="line-height: 25px; ">时机的技巧:利用人在操作的间歇预加载。人不是机器,人的行为是由一系列的动作组成,中间会有或长或短的间歇时间,就算对人而言是很短的间歇,对机器而言也是很长的间隔时间了。</div><div style="line-height: 25px; "><br /></div><div style="line-height: 25px; ">为了效果更好,设计上也应该需要调整。</div><div style="line-height: 25px; "><br /></div><div style="line-height: 25px; ">加载技巧:可以将下载的内容分成小块,并按一定的优先顺序下载,用户最需要的应该尽快可用。而不是一次加载太多的数据,那样可能造成不能及时响应。</div><div style="line-height: 25px; "><br /></div><div style="line-height: 25px; ">考虑到巨大的用户量,前端应要防止server过载,保持服务有效 。另外,后台还要努力提升存储系统的吞吐率。</div><div style="line-height: 25px; "><br /></div><div style="line-height: 25px; ">我顺便补充一下懒加载:</div><div style="line-height: 25px; "><div style="line-height: 25px; ">预加载和懒加载是两个相反的行为,但都是性能优化的手段,改善用户体验,具体看怎么用了。</div><div style="line-height: 25px; ">预加载那些用户下一步马上需要的,如初次加载就包含,或在初次加载之后,利用用户的下一步行为的间歇时间提前加载。</div><div style="line-height: 25px; ">而懒加载是先不加载那些用户不会马上用到的,或不常用到的部分,这样减少了加载内容。</div></div><div style="line-height: 25px; "><br /></div><div style="line-height: 25px; "><br /></div><div style="line-height: 25px; ">异步操作:</div><div style="line-height: 25px; ">没啥说的,界面立刻响应,任务在后台执行,而不是等待。</div><div style="line-height: 25px; "><br /></div><div style="line-height: 25px; ">最后,性能是特性,优化无止境。</div></span>hgkhttp://www.blogger.com/profile/18248256147814166844noreply@blogger.com0tag:blogger.com,1999:blog-3051279638784476121.post-45940681046742512002011-10-16T09:43:00.000-07:002011-10-16T09:47:57.626-07:00Macbook Pro 使用小记<span class="Apple-style-span" style="color: rgb(51, 51, 51); font-family: Arial, Helvetica, sans-serif; font-size: 14px; line-height: 22px; background-color: rgb(255, 255, 255); "><div style="line-height: normal; font-family: STHeiti; font-size: medium; ">本周(2011年5月)到手Macbook Pro,很激动。刚刚使用了几天,简单记下自己的感受。</div><div style="line-height: normal; font-family: STHeiti; font-size: medium; "><br /></div><div style="line-height: normal; font-family: STHeiti; font-size: medium; ">Macbook Pro的硬件配置和做工真没得说,非常完美。</div><div style="line-height: normal; font-family: STHeiti; font-size: medium; ">触控板很强大、很好用,鼠标可以基本不用了,但要稍微学习一下。</div><div style="line-height: normal; font-family: STHeiti; font-size: medium; ">主要说说软件系统的差异。<br /></div><div style="line-height: normal; font-family: STHeiti; font-size: medium; "><br /></div><div style="line-height: normal; font-family: STHeiti; font-size: medium; ">鼠标右键功能使用较少,大部分功能设计使用单键就可以搞定。</div><div style="line-height: normal; font-family: STHeiti; font-size: medium; "><br /></div><div style="line-height: normal; font-family: STHeiti; font-size: medium; "><br /></div><div style="line-height: normal; font-family: STHeiti; font-size: medium; ">Dock:</div><div style="line-height: normal; font-family: STHeiti; font-size: medium; ">很多程序关闭按钮的行为不是退出,而是类似于最小化到dock中,需要Command+Q或菜单来退出。</div><div style="line-height: normal; font-family: STHeiti; font-size: medium; "><br /></div><div style="line-height: normal; font-family: STHeiti; font-size: medium; ">Finder相当于资源浏览器,但是没有地址栏不太习惯。</div><div style="line-height: normal; font-family: STHeiti; font-size: medium; ">命令行终端和linux差不多,特权命令也需要sudo执行。</div><div style="line-height: normal; font-family: STHeiti; font-size: medium; "><br /></div><div style="line-height: normal; font-family: STHeiti; font-size: medium; "><br /></div><div style="line-height: normal; font-family: STHeiti; font-size: medium; ">widget小工具集也不错。</div><div style="line-height: normal; font-family: STHeiti; font-size: medium; "><br /></div><div style="line-height: normal; font-family: STHeiti; font-size: medium; "><br /></div><div style="line-height: normal; font-family: STHeiti; font-size: medium; ">键盘与菜单:</div><div style="line-height: normal; font-family: STHeiti; font-size: medium; "><div style="line-height: 25px; ">快捷键不一样,大多需要Command键组合,很多组合习惯也不一样。</div><div style="line-height: 25px; ">程序中“关于”菜单,是最左边的菜单中的第一项,而windows一般是最右边菜单的最后一项。</div><div style="line-height: 25px; ">程序的菜单不是在应用程序上,而是统一在桌面顶部,切换程序菜单就跟着变。</div><div style="line-height: 25px; "><br /></div><div style="line-height: 25px; ">Mac笔记本上的按键比标准键盘少很多。</div><div style="line-height: 25px; ">F1-F12功能不一样,直接按就可以,不需要Fn,而一般笔记本相反,都需要Fn来使用功能。</div><div style="line-height: 25px; "><div style="line-height: 25px; ">键盘没有Home、End、PageUp、PageDown,需要 Fn+4个方向键 替代。</div><div style="line-height: 25px; ">光标移到行首或行尾:command+左箭头或右箭头。</div></div><div style="line-height: 25px; ">标准键盘右两个删除键:backspace(向左删)和Del(向右删),而Mac上只有一个delete键,作用和backspace键一样,如果想向右删需要用Fn+delete。</div><div style="line-height: 25px; "><span style="line-height: normal; ">剪切、复制、粘贴、撤消:不是用Ctrl,而是Command组合。</span></div><div style="line-height: 25px; "><br /></div><div style="line-height: 25px; "><br /></div><div style="line-height: 25px; ">窗口的关闭、最小化、最大化:</div><div style="line-height: 25px; ">这三个按钮在窗口左上角,而windows是右上角。</div><div style="line-height: 25px; ">关闭按钮也是反的,在三个按钮的最左边,而不是最右边。</div><div style="line-height: 25px; ">最大化按钮很不一样,不是真的最大化,而是根据窗口内容的最合适大小(一般比最大化小很多),只能自己拖到更大的大小。小提示:chrome浏览器用 “shift+最大化” 可以真的最大化。</div><div style="line-height: 25px; "><br /></div><div style="line-height: 25px; "> </div><div style="line-height: 25px; ">Cmd+X只能操作文本,不能操作文件或文件夹。必须用拖拽的方式实现:</div><div style="line-height: 25px; ">拖动到其它目录就是剪切,或者Command+拖拽强制剪切到外部存储设备;</div><div style="line-height: 25px; ">Option+拖拽是复制;Cmd+Option+拖拽是创建快捷方式。<br /></div><div style="line-height: 25px; "><br /></div><div style="line-height: 25px; ">windows上弹出的提示窗口一般出现在桌面右下角,而Mac是右上角。</div><div style="line-height: 25px; "> </div><div style="line-height: 25px; "><br /></div><div style="line-height: 25px; ">文件系统方面:Mac可以读写Fat格式文件。注意:mac可以读ntfs格式的数据,但<strong style="line-height: 28px; ">不能写ntfs</strong>(修改、删除、新建),比如使用ntfs格式的移动硬盘。<br /></div></div><div style="line-height: normal; font-family: STHeiti; font-size: medium; "><br /></div><div style="line-height: normal; font-family: STHeiti; font-size: medium; ">软件:Mac上有自己的App Store,没事可以进去看看,很多常用软件都有,但不是很全。</div><div style="line-height: normal; font-family: STHeiti; font-size: medium; "><br /></div><div style="line-height: normal; font-family: STHeiti; font-size: medium; "> </div><div style="line-height: normal; font-family: STHeiti; font-size: medium; ">安装软件:安装包一般是一个dmg格式的文件,其实就是一个镜像。常见有两种安装方法:</div><ol style="line-height: 25px; margin-top: 5px; margin-right: 0px; margin-bottom: 5px; margin-left: 40px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><li style="line-height: 25px; "><div style="line-height: normal; font-family: STHeiti; font-size: medium; ">带安装向导的,一路点下去即可。一般也提供了卸载程序。</div></li><li style="line-height: 25px; "><div style="line-height: normal; font-family: STHeiti; font-size: medium; ">直接将程序拖动到应用程序文件夹。删除也是从应用程序中拖到回收站。</div></li></ol><div style="line-height: normal; font-family: STHeiti; font-size: medium; "> </div><div style="line-height: normal; font-family: STHeiti; font-size: medium; "><br /></div><div style="line-height: normal; font-family: STHeiti; font-size: medium; ">Mac上自带了大量应用软件和实用工具,不介绍了,挺好玩的。</div><div style="line-height: normal; font-family: STHeiti; font-size: medium; ">默认就有Java、Python、Ruby等语言支持,这对开发人员非常友好。</div><div style="line-height: normal; font-family: STHeiti; font-size: medium; ">Mac自带的中文输入法不太好用,可以自己安装FIT输入法(和SunPinyin合作了),搜狗和QQ输入法也出了Mac版了。</div><div style="line-height: normal; font-family: STHeiti; font-size: medium; ">MPlayerX播放器不错,可以播rmvb这种国内经常使用的格式。</div><div style="line-height: normal; font-family: STHeiti; font-size: medium; "><br /></div><div style="line-height: normal; font-family: STHeiti; font-size: medium; "> </div><div style="line-height: normal; font-family: STHeiti; font-size: medium; ">我常用的软件:</div><ul style="line-height: 25px; margin-top: 5px; margin-right: 0px; margin-bottom: 5px; margin-left: 40px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><li style="line-height: 25px; "><div style="line-height: normal; font-family: STHeiti; font-size: medium; ">浏览器:Chrome、Firefox、Safari</div></li><li style="line-height: 25px; "><div style="line-height: normal; font-family: STHeiti; font-size: medium; ">输入法:FIT输入法(SunPinyin)、搜狗输入法、QQ输入法</div></li><li style="line-height: 25px; "><div style="line-height: normal; font-family: STHeiti; font-size: medium; ">BT下载工具:Vuze</div></li><li style="line-height: 25px; "><div style="line-height: normal; font-family: STHeiti; font-size: medium; ">MPlayerX播放器</div></li></ul><ul style="line-height: 25px; margin-top: 5px; margin-right: 0px; margin-bottom: 5px; margin-left: 40px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><li style="line-height: 25px; "><div style="line-height: normal; font-family: STHeiti; font-size: medium; ">编辑器:TextWrangler、jEdit、Bluefish、MacVim</div></li></ul><ul style="line-height: 25px; margin-top: 5px; margin-right: 0px; margin-bottom: 5px; margin-left: 40px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><li style="line-height: 25px; "><div style="line-height: normal; font-family: STHeiti; font-size: medium; ">Twitter for mac</div></li><li style="line-height: 25px; "><div style="line-height: normal; font-family: STHeiti; font-size: medium; ">虚拟机:VirtualBox</div></li><li style="line-height: 25px; "><div style="line-height: normal; font-family: STHeiti; font-size: medium; ">Dropbox</div></li><li style="line-height: 25px; "><div style="line-height: normal; font-family: STHeiti; font-size: medium; ">The Unarchiver(7zip、rar解压)</div></li><li style="line-height: 25px; "><div style="line-height: normal; font-family: STHeiti; font-size: medium; ">QQ、MSN都有官方的Mac版,自带iChat就支持Gtalk</div></li><li style="line-height: 25px; "><div style="line-height: normal; font-family: STHeiti; font-size: medium; "><a rel="nofollow" href="http://www.microsoft.com/mac/" style="line-height: 28px; text-decoration: none; color: rgb(60, 145, 13); ">http://www.microsoft.com/mac/</a> 除了MSN,还有Mac版的远程桌面,方便访问Windows</div></li><li style="line-height: 25px; "><div style="line-height: normal; font-family: STHeiti; font-size: medium; ">chnroutes vpn路由<br /></div></li></ul><p style="line-height: normal; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; font-family: STHeiti; font-size: medium; "> </p><p style="line-height: normal; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; font-family: STHeiti; font-size: medium; "><br /></p><p style="line-height: normal; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; font-family: STHeiti; font-size: medium; ">开发工具:</p><ul style="line-height: 25px; margin-top: 5px; margin-right: 0px; margin-bottom: 5px; margin-left: 40px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><li style="line-height: 25px; "><div style="line-height: normal; font-family: STHeiti; font-size: medium; ">XCode,包括了unix常用工具gcc等,开发人员必备。已经免费了,自带系统光盘中有,也可以从App Store中下载。</div></li><li style="line-height: 25px; "><div style="line-height: normal; font-family: STHeiti; font-size: medium; ">Eclipse</div></li><li style="line-height: 25px; "><div style="line-height: normal; font-family: STHeiti; font-size: medium; ">自带终端(Terminal),多种风格、保存书签等功能都有</div></li><li style="line-height: 25px; "><div style="line-height: normal; font-family: STHeiti; font-size: medium; ">安装各种Linux开源软件的工具,MacPorts、Homebrew 和fink,推荐Homebrew</div></li><li style="line-height: 25px; "><div style="line-height: normal; font-family: STHeiti; font-size: medium; ">Mysql官方有Mac版,App Store有免费的Navicat for mysql Lite<br /></div></li></ul><p style="line-height: normal; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; font-family: STHeiti; font-size: medium; "> </p><p style="line-height: normal; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; font-family: STHeiti; font-size: medium; "><br /></p><p style="line-height: normal; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; font-family: STHeiti; font-size: medium; ">文件名关联办法:右键-显示简介-打开方式(调整为希望的默认程序)-<strong style="line-height: 28px; ">全部更改<br /></strong>注意:右键-打开方式-其它-总是以此方式打开,只对当前文件有效,不是都改。<br />技术上是和叫做Launch Service的系统服务有关。<br /></p><p style="line-height: normal; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; font-family: STHeiti; font-size: medium; "> </p><p style="line-height: normal; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; font-family: STHeiti; font-size: medium; "><br /></p><p style="line-height: normal; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; font-family: STHeiti; font-size: medium; ">Mac自带终端(Terminal),因为没有PageUp、PageDonw,查看man、less等命令时无法翻页,使用Fn或Command组合也不成。<strong style="line-height: 28px; ">解决方法是用传统Unix的空格/b或ctrl+f和ctrl+b</strong></p></span>hgkhttp://www.blogger.com/profile/18248256147814166844noreply@blogger.com0tag:blogger.com,1999:blog-3051279638784476121.post-16455032363238941932011-03-29T19:03:00.000-07:002011-03-29T19:04:34.359-07:00【原创】Kyoto Cabinet 基本规格书<span class="Apple-style-span" style="color: rgb(51, 51, 51); font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; line-height: 22px; ">如果你知道 Tokyo Cabinet ,那么就应该知道 Kyoto Cabinet,因为他们都是同一个作者(平林幹雄)开发出来的 Key-Value 数据库。<div style="line-height: 22px; "><b style="line-height: 22px; ">Kyoto Cabinet</b>:a straightforward implementation of DBM,主页:<a href="http://fallabs.com/kyotocabinet/" style="line-height: 22px; text-decoration: none; color: rgb(60, 145, 13); ">http://fallabs.com/kyotocabinet/</a> ,演示文稿:<a href="http://www.slideshare.net/estraier/kyotoproducts-5886452" style="line-height: 22px; text-decoration: none; color: rgb(60, 145, 13); ">http://www.slideshare.net/estraier/kyotoproducts-5886452</a> 。</div><div style="line-height: 22px; "><b style="line-height: 22px; ">Tokyo Cabinet</b>:a modern implementation of DBM,主页: <a href="http://fallabs.com/tokyocabinet/" style="line-height: 22px; text-decoration: none; color: rgb(60, 145, 13); ">http://fallabs.com/tokyocabinet/</a> </div><div style="line-height: 22px; "><br /><div style="line-height: 22px; ">以下Tokyo Cabinet简称为TC, Kyoto Cabinet简称为KC,本文主要对KC做介绍。</div><div style="line-height: 22px; ">KC是TC的后继者或兄弟项目,因为KC在各方面都超过了,所以作者在TC的首页上的开头向所有人推荐使用KC(我也是这个推荐才开始关注KC的)。TC为C实现,为了更好的可维护性,KC采用C++实现。</div></div><div style="line-height: 22px; "><br /></div><div style="line-height: 22px; ">以下内容的英文原文来自:<a href="http://fallabs.com/kyotocabinet/spex.html" style="line-height: 22px; text-decoration: none; color: rgb(60, 145, 13); ">http://fallabs.com/kyotocabinet/spex.html</a></div><div style="line-height: 22px; "><br /></div><div style="line-height: 22px; "><span style="line-height: 28px; "><b style="line-height: 28px; ">一、介绍</b></span></div><div style="line-height: 22px; ">KC是一个数据库管理的 lib。数据库是一个简单的包含记录的数据文件,每个记录是一个键值对(key/value),key和value都是变长的字节序列。key和value既可以是二进制的,也可以是文本字符串。数据库中的key必须唯一。数据库既没有表的概念,也不存在数据类型。所有的记录被组织为hash表或B+树。</div><div style="line-height: 22px; "><br /></div><div style="line-height: 22px; ">在数据库中,可以储存key-value记录,也可以根据key来获取和删除记录。还可以遍历访问所有的key。这些方法类似于UNIX标准中的DBM库(及后来的NDBM和GDBM)。因为KC的高性能,可以作为DBM的替代品。</div><div style="line-height: 22px; "><br /></div><div style="line-height: 22px; "><b style="line-height: 22px; ">Hash 数据库</b> 的每个操作的时间复杂度是 O(1),因此理论上,性能是常量而与数据库的规模无关。在实践中,性能由内存或存储设备的速度决定。如果数据库的大小小于内存大小,性能表现为内存的速度,比STL中的std::map要快。当然数据库大小可以大于内存大小,最大上限是8EB(1024×1024×1024GB)。即使在这样的情况下,每个操作也只需要一两个存储设备的seek操作。</div><div style="line-height: 22px; "><br /></div><div style="line-height: 22px; "><b style="line-height: 22px; ">B+ tree 数据库</b>的每个操作的时间复杂度是 O(log N)。因此理论上,性能是数据库规模的对数。尽管B+ tree 数据库的随机访问性能要慢于 hash数据库,但B+ tree数据库支持对 key 顺序的连续访问,这可以实现对字符串的前向匹配查找和整数的范围查找。连续访问的性能远快于随机访问。</div><div style="line-height: 22px; "><br /></div><div style="line-height: 22px; ">API是基于面向对象设计的,hash数据库和B+ tree数据库都有从同一个超类继承而来的同样的方法。除了他们,还有7种数据库也继承了同样的超类。<b style="line-height: 22px; ">prototype hash</b> 数据库采用标准容器 std::unordered_map 实现,<b style="line-height: 22px; ">prototype tree</b> 数据库采用标准容器 std::map 实现,<b style="line-height: 22px; ">stash</b> 数据库是采用naive hash map的原始实现来节省内存,<b style="line-height: 22px; ">cache hash</b> 数据库是采用 LRU删除算法的双向链接 hash map 原始实现。<b style="line-height: 22px; ">cache tree</b> 数据库是基于cache hash 数据库并提供B+ tree的机制。<b style="line-height: 22px; ">directory hash</b> 数据库是采用文件系统的目录机制实现,每个记录存储为一个目录下的文件。<b style="line-height: 22px; ">directory tree</b> 数据库基于directory hash数据库并提供B+ tree的机制。所有的数据库都有相关的事物(transaction)和游标(cursor)的实用方法。软件也包含了命令行接口的程序。</div><div style="line-height: 22px; "><br /></div><div style="line-height: 22px; ">KC的运行速度非常快。例如,保存一百万记录到hash数据库中只需要0.9秒,保存到B+ tree数据库只需要1.1秒。而且数据库本身还非常小。例如,hash数据库的每个记录头只有16字节,B+ tree数据库是4字节。更进一步,KC的伸缩性非常大,数据库大小可以增长到8EB(9.22e18 bytes)。</div><div style="line-height: 22px; "><br /></div><div style="line-height: 22px; ">KC是C++语言编写的,并提供C++、C、Java、Python、Ruby、Perl 和 Lua 的API。KC可以用在所有符合 C++03标准并带TR1库扩展的平台。KC是GNU General Public License的自由软件。FOSS License例外也提供用来适应其它免费和开源的licenses。另一方面也提供商业license。如果你在专有软件中使用KC,那么你需要商业license。</div><div style="line-height: 22px; "><br /></div><div style="line-height: 22px; "><span style="line-height: 28px; "><b style="line-height: 28px; ">二、特性</b></span></div><div style="line-height: 22px; ">下面描述KC的特性。</div><div style="line-height: 22px; "><br /></div><div style="line-height: 22px; "><b style="line-height: 22px; ">起源</b></div><div style="line-height: 22px; ">最初的DBM是由 Kenneth Thompson 开发,作为最初AT&T UNIX的一部分。后来,很多跟随者开发了和 DBM 类似的NDBM、SDBM、GDBM、TDB 和 BerkeleyDB。在2003年,出于性能原因,我(作者)开发了QDBM代替GDBM。</div><div style="line-height: 22px; "><br /></div><div style="line-height: 22px; ">在2007年,TC出于以下目的被开发来作为QDBM的后继者。这些目标都实现了,TC可以替代传统的DBM产品。</div><div style="line-height: 22px; "><ul style="line-height: 22px; margin-top: 5px; margin-right: 0px; margin-bottom: 5px; margin-left: 40px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><li style="line-height: 22px; ">改进的<b style="line-height: 22px; ">空间效率</b>:更小的数据库文件</li><li style="line-height: 22px; ">改进的<b style="line-height: 22px; ">时间效率</b>:更快的处理速度</li><li style="line-height: 22px; ">改进的<b style="line-height: 22px; ">并行性</b>:多线程环境下的高性能</li><li style="line-height: 22px; ">改进的<b style="line-height: 22px; ">可用性</b>:简单的API</li><li style="line-height: 22px; ">改进的<b style="line-height: 22px; ">健壮性</b>:即使在灾难情况下数据库文件也不会损坏</li><li style="line-height: 22px; ">支持<b style="line-height: 22px; ">64位架构</b>:巨大的内存空间和数据库文件可用</li></ul><div style="line-height: 22px; ">在2009年,KC作为另一个QDBM后继者被开发出来。和兄弟产品(TC)相比较,追加了下面这些优势。然而,至少在单线程操作环境下,TC的性能要高于KC。</div></div><div style="line-height: 22px; "><ul style="line-height: 22px; margin-top: 5px; margin-right: 0px; margin-bottom: 5px; margin-left: 40px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><li style="line-height: 22px; ">改进的<b style="line-height: 22px; ">空间效率</b>:更小的数据库文件</li><li style="line-height: 22px; ">改进的<b style="line-height: 22px; ">并行性</b>:多线程环境下的高性能</li><li style="line-height: 22px; ">改进的<b style="line-height: 22px; ">可移植性</b>:对底层的抽象来支持 非POSIX系统</li><li style="line-height: 22px; ">改进的<b style="line-height: 22px; ">可用性</b>:简单的API,面向对象的设计</li><li style="line-height: 22px; ">改进的<b style="line-height: 22px; ">健壮性</b>:即使在灾难情况下数据库文件也不会损坏</li></ul><div style="line-height: 22px; ">我(作者)将同时维护TC和KC,因为他们的价值不同。</div></div><div style="line-height: 22px; "><br /></div><div style="line-height: 22px; "><b style="line-height: 22px; ">高效的Hash数据库实现</b></div><div style="line-height: 22px; ">KC使用hash算法获取记录。如果 bucket array 拥有足够的元素数量,那么获取的时间复杂度是O(1)。这样获取记录的时间是常量,而和数据库规模无关。存储和删除记录也一样。hash值的碰撞是通过分离链接(separate chaining)管理的。每个链(chain)的数据结构是二分查找树。即使 bucket array 极度缺乏元素,获取的时间复杂度也只是O(log n)。</div><div style="line-height: 22px; "><br /></div><div style="line-height: 22px; ">KC的高性能获取是通过将整个 bucket array 加载到内存中。如果 bucket array 在内存中,那么访问目标记录的区域可能仅需要一组如 lseek、read、write这样的文件操作即可。如果 bucket array 保存在文件中,不会使用 read 调用读到内存中而是通过 mmap 调用直接映射到内存中。这样,连接到数据库的准备时间非常短,二个或更多的进程能够共享同样的内存映射。</div><div style="line-height: 22px; "><br /></div><div style="line-height: 22px; ">在哈希表中使用的哈希函数是 MurMurHash 2.0 。如果 bucket array 的元素数量为数据库记录数的一半,尽管取决于输入的特性,哈希值碰撞的概率大概是55.3%(一样的话是35.5%,二倍的话是20.4%,4倍是11.0%,8倍是5.7%)。如果是这样,获取一个记录大概需要2个或更少的一组文件操作。如果作为一个性能指标,为了处理有一百万记录的数据库,需要一个拥有一半元素数量的 bucket array 。每个元素是6字节。这样只需要用3M内存,就可以处理一个拥有一百万记录的数据库。</div><div style="line-height: 22px; "><br /></div><div style="line-height: 22px; ">如果用一个更大长度的值覆盖记录现有的值,那么必须移动区域到文件的另一个位置。因为这个操作的时间复杂度取决于一个记录的区域大小,所以连续地扩展值是低效的。然而,KC通过对齐(alignment)处理这个问题。如果增加的数据可以放置在记录尾部的填充区域(padding region),就不必移动记录的区域了。</div><div style="line-height: 22px; "><br /></div><div style="line-height: 22px; ">一般而言,在连续更新的同时,可用区域会出现碎片,并且数据库的大小会快速增长。KC通过空闲块池(free block pool)和自动的碎片整理机制处理这个问题。如果一个记录被删除或被移到另一个位置,那个区域将被作为一个空闲块处理。空闲块池管理着空闲块并重用最合适的区域给一个新的记录。自动碎片整理会分别移动记录和空闲块。连续的空闲块会被合并成一个。</div><div style="line-height: 22px; "><br /></div><div style="line-height: 22px; "><b style="line-height: 22px; ">有用的B+ Tree数据库</b></div><div style="line-height: 22px; ">尽管B+ tree数据库比hash数据库慢,但它的特点在于顺序访问每个记录。顺序可以由用户指定。B+ tree数据库中的记录被存储和安排到逻辑页中(logical pages)。被组织在B树这种多路平衡树中的稀疏索引,用来维护每个页。这样获取等操作的时间复杂度是O(log n)。通过游标(Cursor)可以按顺序访问每个记录。游标可以跳到指定key的位置,并能够从当前位置向前或向后移动。因为每个页被组织为双向链表,所以游标步进的时间复杂度是O(1)。</div><div style="line-height: 22px; "><br /></div><div style="line-height: 22px; ">B+ tree数据库的实现是基于上面的hash数据库。因为B+ tree数据库的每个页是作为hash数据库中的一个记录保存的,所以B+ tree数据库继承了hash数据库的存储管理效率。因为每个记录的头更小并且每个页的对齐是根据这个页的大小来调整的,大部分情况下,数据库文件大小比对应的hash数据库小一半。</div><div style="line-height: 22px; "><br /></div><div style="line-height: 22px; ">虽然许多页操作需要更新B+ tree数据库,但KC通过页缓存(page cache)加快了这一过程并减少了文件操作。页缓存是用双层的 LRU 列表实现的,这使得频繁访问的页被缓存在“hot”列表中,最近访问的页被缓存在“warm”LRU列表中。如果页缓存能够有效地工作并且整个稀疏索引被缓存在内存中,那么获取一个记录可能只需要一个或更少的一组文件操作。</div><div style="line-height: 22px; "><br /></div><div style="line-height: 22px; ">B+ tree数据库的每个页可以被压缩存储。默认的压缩方法是ZLIB的"Deflate"方法。因为一个页中的记录有相似的模式,由于Lempel-Ziv算法预计会有较高的压缩率。对于处理文本数据的情况,数据库的大小可能被减小到50%或更小。如果数据库的规模很大并且磁盘IO成为瓶颈,使用压缩方法会使处理速度有巨大地提高。此外,可以指定外部的LZO和LZMA压缩算法。</div><div style="line-height: 22px; "><br /></div><div style="line-height: 22px; "><b style="line-height: 22px; ">实用的功能</b></div><div style="line-height: 22px; ">KC具有事物机制特征。可以在一个事物的开始和结束之间一次性提交一组操作,或者终止事物并回滚到事物之前的状态。支持两种隔离级别:"serializable" 和 "read uncommitted"。持久性是通过预写日志(write ahead logging)和影式分页(shadow paging)保证的。</div><div style="line-height: 22px; "><br /></div><div style="line-height: 22px; ">还提供自动事物和自动恢复的机制。如果在打开数据库的时候指定了自动事物选项,那么每一个更新操作都受隐式提交事务的保护。因此不需要显式的事物操作就可以保证持久性。事务外的数据库崩溃后,自动恢复机制开始工作。在打开数据库的时候如果发现数据库不一致,所有的区域会被按照“fsck”的方式扫描,并且隐式地将完好的记录重建。</div><div style="line-height: 22px; "><br /></div><div style="line-height: 22px; ">KC提供两种模式连接到数据库:“读”和“写”。读只能获取记录但不能保存和删除。写可以执行所有方法。通过文件锁定方式连接数据库时,可以排斥多进程的控制。当一个写连接到一个数据库后,既不允许读也不允许写连接。当一个读连接到数据库后,其它的读可以连接,但是写不能。根据这种机制,保证了多任务环境中同时连接的数据一致性。</div><div style="line-height: 22px; "><br /></div><div style="line-height: 22px; ">API函数是可重入的,可以用在多线程环境中。不同的数据库对象可以完全并行地操作。对于同时操作同一个数据库对象,读写锁被用来排斥控制。就是说,一个写线程正在操作一个对象,其它的读线程和写线程将被阻塞。锁定粒度取决于数据结构。hash数据库使用记录锁定,而B+ tree数据库使用页锁定。</div><div style="line-height: 22px; "><br /></div><div style="line-height: 22px; ">为了改进性能和并发性,KC使用内建于主流CPU的原子操作,如原子递增和CAS(compare-and-swap)。如POSIX线程包提供的原生环境的锁原语被使用CAS的原语所替换。</div><div style="line-height: 22px; "><br /></div><div style="line-height: 22px; "><b style="line-height: 22px; ">简单而灵活的接口</b></div><div style="line-height: 22px; ">KC通过基于面向对象设计的简单API。数据库的每个操作被封装发布为易懂的方法,如open、close、set、remove、get 等等。hash数据库和B+ tree数据库的类都衍生自公共的抽象类,它定义了接口。很容易将应用从一个数据库移植到另一个。此外,多态数据库API在运行时被赋予一个数据库。</div><div style="line-height: 22px; "><br /></div><div style="line-height: 22px; ">KC支持 visitor 模式。你可以通过回调函数的方式定义任意的数据库操作。visitor类封装了回调函数和他们的状态数据。database类有个 accept 方法,可以接受一个visitor类的实例并用一个记录数据为参数调用它的函数。回调函数的返回值反映了一个记录的新状态。</div><div style="line-height: 22px; "><br /></div><div style="line-height: 22px; ">另外,提供了许多有用的工具方法,如前缀查询(prefix search)、正则查询(regex search)、日志(logging)、热备份(hot backup)、伪快照(pseudo-snapshot) 和 合并(merging)。还提供了一个MapReduce框架。尽管它不是分布式和并发的,对于较少CPU负载和较少内存使用的聚合计算还是有用的。</div><div style="line-height: 22px; "><br /></div><div style="line-height: 22px; ">给C++提供的核心API的同时,绑定了其它语言,如C、Java、Python、Ruby、Perl 和 Lua 。每个API也提供了相关的命令行接口。他们对于原型、测试和调试很有用。</div><div style="line-height: 22px; "><br /></div><div style="line-height: 22px; "><span style="line-height: 28px; "><b style="line-height: 28px; ">三、安装</b></span></div><div style="line-height: 22px; ">支持Linux、FreeBSD、Solaris、Mac OS X、Windows等,需要 gcc 4.2 和 ZLIB库。具体安装说明详见:<a href="http://fallabs.com/kyotocabinet/spex.html#installation" style="line-height: 22px; text-decoration: none; color: rgb(60, 145, 13); ">http://fallabs.com/kyotocabinet/spex.html#installation</a></div><div style="line-height: 22px; "><br /></div><div style="line-height: 22px; "><span style="line-height: 28px; font-size: large; "><b style="line-height: 28px; ">四、向导</b></span></div><div style="line-height: 22px; ">稍后考虑翻译,请先看原文:<a href="http://fallabs.com/kyotocabinet/spex.html#tutorial" style="line-height: 22px; text-decoration: none; color: rgb(60, 145, 13); ">http://fallabs.com/kyotocabinet/spex.html#tutorial</a></div><div style="line-height: 22px; "><br /></div><div style="line-height: 22px; "><br /></div><div style="line-height: 22px; "><span style="line-height: 28px; font-size: large; "><b style="line-height: 28px; ">五、提示和技巧</b></span></div><div style="line-height: 22px; "><span style="line-height: 20px; "><span style="line-height: 20px; ">这一节描述KC的提示和技巧。</span></span></div><div style="line-height: 22px; "><span style="line-height: 20px; "><span style="line-height: 20px; "><br /></span></span></div><div style="line-height: 22px; "><span style="line-height: 20px; "><span style="line-height: 20px; "><b style="line-height: 20px; ">调优 Stash 数据库</b></span></span></div><div style="line-height: 22px; "><span style="line-height: 20px; "><span style="line-height: 20px; ">stash数据库(StashDB)是省内存的内存数据库。可以使用如下优化方法。</span></span></div><div style="line-height: 22px; "><ul style="line-height: 22px; margin-top: 5px; margin-right: 0px; margin-bottom: 5px; margin-left: 40px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><li style="line-height: 22px; "><span style="line-height: 20px; "><b style="line-height: 20px; ">tune_buckets</b>:设置hash数据库的 bucket 数量</span></li></ul></div><div style="line-height: 22px; "><span style="line-height: 20px; ">默认的bucket数量大约是1百万。如果你想存更多的记录,调用</span><span style="line-height: 20px; font-size: small; "><b style="line-height: 20px; ">tune_buckets</b><span style="line-height: 20px; ">设置bucket数量。建议的bucket数量的比率是和记录总数量相同,可以是从80%到400% 。如果比率低于100%,因为碰撞链是线性链接表,所以时间效率会快速下降。</span></span></div><div style="line-height: 22px; "><span style="line-height: 20px; font-size: small; "><span style="line-height: 20px; "><br /></span></span></div><div style="line-height: 22px; "><span style="line-height: 20px; font-size: small; "><span style="line-height: 20px; "><b style="line-height: 20px; ">调优 Cache Hash 数据库</b></span></span></div><div style="line-height: 22px; "><span style="line-height: 20px; font-size: small; "><span style="line-height: 20px; ">cache hash数据库(CacheDB)是一个带LRU删除特性的内存数据库。</span></span><span style="line-height: 20px; font-size: small; ">可以使用如下优化方法。</span></div><div style="line-height: 22px; "><ul style="line-height: 22px; margin-top: 5px; margin-right: 0px; margin-bottom: 5px; margin-left: 40px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><li style="line-height: 22px; "><span style="line-height: 20px; "><b style="line-height: 20px; ">tune_options</b>:设置可选特性(optional features)</span></li><li style="line-height: 22px; "><span style="line-height: 20px; "><b style="line-height: 20px; ">tune_buckets</b>:</span><span style="line-height: 20px; font-size: small; ">设置hash数据库的 bucket 数量</span></li><li style="line-height: 22px; "><span style="line-height: 20px; "><b style="line-height: 20px; ">tune_compressor</b>:设置数据压缩方法</span></li><li style="line-height: 22px; "><span style="line-height: 20px; "><b style="line-height: 20px; ">cap_count</b>:设置记录数的容量</span></li><li style="line-height: 22px; "><span style="line-height: 20px; "><b style="line-height: 20px; ">cap_size</b>:设置内存使用的容量</span></li></ul></div><div style="line-height: 22px; "><span style="line-height: 20px; font-size: small; "><b style="line-height: 20px; ">tune_options </b><span style="line-height: 20px; ">特性以牺牲时间效率为代价来减少内存的使用。如果指定为 <b style="line-height: 20px; ">CacheDB::TCOMPRESS</b>,每个记录的key和value在存储到文件时会被隐式压缩处理。如果value大于1KB或更多,压缩是很有效的。</span></span></div><div style="line-height: 22px; "><span style="line-height: 20px; font-size: small; "><span style="line-height: 20px; "><br /></span></span></div><div style="line-height: 22px; "><span style="line-height: 20px; font-size: small; "><span style="line-height: 20px; ">默认的 bucket 数量是大约1百万。如果你想存储更多的记录,调整 </span></span><span style="line-height: 20px; font-size: small; "><b style="line-height: 20px; ">tune_buckets </b></span><span style="line-height: 20px; font-size: small; "><span style="line-height: 20px; ">来设置bucket数量。建议bucket数量的比率是和记录数量一样,可以是记录数量的50%到400% 。如果这个比率小于100%,时间效率会逐渐下降,因为碰撞链是二分查找树。</span></span></div><div style="line-height: 22px; "><span style="line-height: 20px; font-size: small; "><span style="line-height: 20px; "><br /></span></span></div><div style="line-height: 22px; "><span style="line-height: 20px; font-size: small; "><span style="line-height: 20px; "> <b style="line-height: 20px; ">CacheDB::TCOMPRESS </b><span style="line-height: 20px; ">选项</span><span style="line-height: 20px; ">的默认压缩算法是由ZLIB 实现的 "Deflate"算法。如果你想用别算法,调用 </span></span></span><span style="line-height: 20px; font-size: small; "><b style="line-height: 20px; ">tune_compressor </b></span><span style="line-height: 20px; font-size: small; ">来设置一个压缩与解压的函数是实现。</span></div><div style="line-height: 22px; "><span style="line-height: 20px; font-size: small; "><br /></span></div><div style="line-height: 22px; "><span style="line-height: 20px; font-size: small; ">默认cache hash数据库在内存中维护所有的记录,并且没有记录会过期。如果想让老的记录过期来保持内存使用为常量,调用 </span><span style="line-height: 20px; font-size: small; "><b style="line-height: 20px; ">cap_count </b><span style="line-height: 20px; ">和/或</span><b style="line-height: 20px; "> </b></span><span style="line-height: 20px; font-size: small; "><b style="line-height: 20px; ">cap_size</b><span style="line-height: 20px; "> 来限制容量。</span></span></div><div style="line-height: 22px; "><span style="line-height: 20px; "><br /></span></div><div style="line-height: 22px; "><span style="line-height: 20px; ">如果你想缓存一千万记录,并且保持内存使用小于8GB,建议按下面示例这样设置。</span></div><div style="line-height: 22px; "><span style="line-height: 20px; "><span style="line-height: normal; color: rgb(17, 17, 17); font-family: Simsun; font-size: medium; "><pre style="line-height: 19px; margin-top: 0.8ex; margin-right: 1.5ex; margin-bottom: 0.8ex; margin-left: 1.5ex; padding-top: 0.2ex; padding-right: 0.2ex; padding-bottom: 0.2ex; padding-left: 0.2ex; background-color: rgb(238, 238, 248); border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(221, 221, 238); border-right-color: rgb(221, 221, 238); border-bottom-color: rgb(221, 221, 238); border-left-color: rgb(221, 221, 238); font-size: 12px; ">db.tune_buckets(10LL * 1000 * 1000); db.cap_count(10LL * 1000 * 1000); db.cap_size(8LL << 30); db.open(...);</pre></span></span></div><div style="line-height: 22px; "><span style="line-height: 20px; ">所有的调优方法必须在数据库打开前设置。</span></div><div style="line-height: 22px; "><span style="line-height: 20px; "><br /></span></div><div style="line-height: 22px; "><span style="line-height: 20px; "><b style="line-height: 20px; ">调优 Cache Tree 数据库</b></span></div><div style="line-height: 22px; "><span style="line-height: 20px; ">cache tree数据库(GrassDB)是B+ tree的内存数据库。因为B+ tree中的每个node被序列化为一个page buffer,并被作为cache hash数据库中的一个记录看待,所以cache hash数据库中的所有配置项(除了容量限制外)都可以用在cache tree数据库中。此外,还有下面这些优化方法。</span></div><div style="line-height: 22px; "><ul style="line-height: 22px; margin-top: 5px; margin-right: 0px; margin-bottom: 5px; margin-left: 40px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><li style="line-height: 22px; "><span style="line-height: 20px; "><b style="line-height: 20px; ">tune_page</b>:设置每个页大小</span></li><li style="line-height: 22px; "><span style="line-height: 20px; "><b style="line-height: 20px; ">tune_page_cache</b>:设置页缓存(page cache)容量大小</span></li><li style="line-height: 22px; "><span style="line-height: 20px; "><b style="line-height: 20px; ">tune_comparator</b>:设置记录比较器</span></li></ul></div><div style="line-height: 22px; "><span style="line-height: 20px; "><span style="line-height: 20px; ">通过</span><b style="line-height: 20px; ">tune_page </b><span style="line-height: 20px; ">调整</span><span style="line-height: 20px; ">的页大小,大部分情况下不用修改。默认是8192,这是主流环境中典型页大小的两倍。如果每个节点的大小超过了这个值,节点被分为两个。</span></span></div><div style="line-height: 22px; "><span style="line-height: 20px; "><span style="line-height: 20px; "><br /></span></span></div><div style="line-height: 22px; "><span style="line-height: 20px; "><span style="line-height: 20px; ">页缓存的默认大小是64MB。如果你想减少内存使用,调整 </span></span><span style="line-height: 20px; font-size: small; "><b style="line-height: 20px; ">tune_page_cache </b><span style="line-height: 20px; ">可以把大部分的页转换为平的字节数组(flat byte arrays),这是为了改进空间效率做的序列化或压缩。</span></span></div><div style="line-height: 22px; "><span style="line-height: 20px; font-size: small; "><span style="line-height: 20px; "><br /></span></span></div><div style="line-height: 22px; "><span style="line-height: 20px; font-size: small; "><span style="line-height: 20px; ">默认的记录比较器是词汇顺序(lexical ordering)函数。这样B+ tree数据库中的记录按照key的词汇顺序放置。如果你想使用其它顺序,调整 </span></span><span style="line-height: 20px; font-size: small; "><b style="line-height: 20px; ">tune_comparator </b><span style="line-height: 20px; ">来设置一个实现排序功能的函数。</span></span></div><div style="line-height: 22px; "><span style="line-height: 20px; font-size: small; "><span style="line-height: 20px; "><br /></span></span></div><div style="line-height: 22px; "><span style="line-height: 20px; font-size: small; "><span style="line-height: 20px; ">如果你想缓存一千万记录,并让内存使用尽可能小,</span></span><span style="line-height: 20px; font-size: small; ">建议按下面示例这样设置。</span></div><div style="line-height: 22px; "><span style="line-height: 20px; font-size: small; "><span style="line-height: normal; color: rgb(17, 17, 17); font-family: Simsun; font-size: medium; "><pre style="line-height: 19px; margin-top: 0.8ex; margin-right: 1.5ex; margin-bottom: 0.8ex; margin-left: 1.5ex; padding-top: 0.2ex; padding-right: 0.2ex; padding-bottom: 0.2ex; padding-left: 0.2ex; background-color: rgb(238, 238, 248); border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(221, 221, 238); border-right-color: rgb(221, 221, 238); border-bottom-color: rgb(221, 221, 238); border-left-color: rgb(221, 221, 238); font-size: 12px; ">db.tune_options(GrassDB::TCCOMPESS); db.tune_buckets(500LL * 1000); db.tune_page(32768); db.tune_page_cache(1LL << 20); db.open(...);</pre></span></span></div><div style="line-height: 22px; "><span style="line-height: 20px; font-size: small; ">所有的调优方法必须在数据库打开前设置。</span></div><div style="line-height: 22px; "><span style="line-height: 20px; "><span style="line-height: 20px; "><br /></span></span></div><div style="line-height: 22px; "><span style="line-height: 20px; "><span style="line-height: 20px; "><b style="line-height: 20px; ">调优 File Hash 数据库</b></span></span></div><div style="line-height: 22px; "><span style="line-height: 20px; "><span style="line-height: 20px; ">file hash数据库(HashDB)是哈希表的文件数据库。提供下面这些调整参数设置。</span></span></div><div style="line-height: 22px; "><ul style="line-height: 22px; margin-top: 5px; margin-right: 0px; margin-bottom: 5px; margin-left: 40px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><li style="line-height: 22px; "><span style="line-height: 20px; "><b style="line-height: 20px; ">tune_alignment</b>:设置记录的对齐幂数</span></li><li style="line-height: 22px; "><span style="line-height: 20px; "><b style="line-height: 20px; ">tune_fbp</b>:设置空闲块池的容量</span><span style="line-height: 20px; font-size: small; ">幂数</span></li><li style="line-height: 22px; "><span style="line-height: 20px; "><b style="line-height: 20px; ">tune_options</b>:设置可选特性</span></li><li style="line-height: 22px; "><span style="line-height: 20px; "><b style="line-height: 20px; ">tune_buckets</b>:设置哈希表的bucket数量</span></li><li style="line-height: 22px; "><span style="line-height: 20px; "><b style="line-height: 20px; ">tune_map</b>:设置内部内存映射区域的大小</span></li><li style="line-height: 22px; "><span style="line-height: 20px; "><b style="line-height: 20px; ">tune_defrag</b>:设置自动碎片整理的单位步数</span></li><li style="line-height: 22px; "><span style="line-height: 20px; "><b style="line-height: 20px; ">tune_compressor</b>:设置数据压缩器</span></li></ul></div><div style="line-height: 22px; "><span style="line-height: 20px; "><span style="line-height: 20px; ">默认对其值幂数是3,就是说每个记录的地址被分配为8个字节(1<<3)的倍数。如果你确信数据库被创建之后很少更新,可以设置</span></span><span style="line-height: 20px; font-size: small; "><b style="line-height: 20px; ">tune_alignment</b><span style="line-height: 20px; ">为0,这样对齐就是1个字节(1<<0)。如果每个记录的典型大小预期超过1KB,把对齐调到8或更大。</span></span></div><div style="line-height: 22px; "><span style="line-height: 20px; font-size: small; "><span style="line-height: 20px; "><br /></span></span></div><div style="line-height: 22px; "><span style="line-height: 20px; "><span style="line-height: 20px; ">大部分情况下空闲块池的大小</span></span><span style="line-height: 20px; font-size: small; "><b style="line-height: 20px; ">tune_fbp</b><span style="line-height: 20px; ">不用调整</span><span style="line-height: 20px; ">。参数默认是10,这就是说空闲块池的大小是1024(1<<10)。</span></span></div><div style="line-height: 22px; "><span style="line-height: 20px; font-size: small; "><span style="line-height: 20px; "><br /></span></span></div><div style="line-height: 22px; "><span style="line-height: 20px; font-size: small; "><span style="line-height: 20px; ">可选特性</span></span><span style="line-height: 20px; font-size: small; "><b style="line-height: 20px; ">tune_options</b><span style="line-height: 20px; ">可以减少数据库文件大小,以损失伸缩性或时间效率为代价。如果设置为 <b style="line-height: 20px; ">HashDB::TSMALL</b> ,记录的地址宽度将从6字节减小到4字节。这样导致每个记录占用(footprint)从16字节减小到12字节。然而,它限制了数据库文件的最大大小为16GB(2GB乘以对齐)。如果设置为 <b style="line-height: 20px; ">HashDB::TLINEAR</b> ,哈希表的碰撞链的数据结构将从二叉树改为线性链表。这种情况下,每个记录的占用从16字节减少到10字节,然而时间效率变得与hash bucket的数量敏感了。如果设置为 <b style="line-height: 20px; ">HashDB::TCOMPRESS</b> ,每个记录在存储到文件时被隐式压缩。如果value大于1KB或更多,压缩会很有效。</span></span></div><div style="line-height: 22px; "><span style="line-height: 20px; font-size: small; "><span style="line-height: 20px; "><br /></span></span></div><div style="line-height: 22px; "><span style="line-height: 20px; font-size: small; "><span style="line-height: 20px; ">默认bucket数量是大约1百万。</span></span><span style="line-height: 20px; font-size: small; "><span style="line-height: 20px; ">如果你想存储更多的记录,调整 </span></span><span style="line-height: 20px; font-size: small; "><b style="line-height: 20px; ">tune_buckets </b><span style="line-height: 20px; ">来设置bucket数量。建议的bucket数量的比率是记录数量的2倍,也可以是100%到400%。如果比率低于100%,时间效率会逐渐降低。</span></span><span style="line-height: 20px; font-size: small; ">如果你设置了bucket数量,建议设置 <b style="line-height: 20px; ">HashDB::TLINEAR </b>选项来改进时间和空间效率。</span></div><div style="line-height: 22px; "><span style="line-height: 20px; font-size: small; "><span style="line-height: 20px; "><br /></span></span></div><div style="line-height: 22px; "><span style="line-height: 20px; font-size: small; "><span style="line-height: 20px; ">默认内部内存映射区域的大小是64MB。如果数据库大小预期大于64MB,通过</span></span><span style="line-height: 20px; font-size: small; "><b style="line-height: 20px; ">tune_map</b><span style="line-height: 20px; ">设置映射的大小大于预期的数据库大小。尽管机器的内存容量限制了映射的大小,但是增加映射大小可以有效改进性能。</span></span></div><div style="line-height: 22px; "><span style="line-height: 20px; font-size: small; "><span style="line-height: 20px; "><br /></span></span></div><div style="line-height: 22px; "><span style="line-height: 20px; font-size: small; "><span style="line-height: 20px; ">默认自动碎片整理是禁用的。如果数据库中现存的记录被修改(删除或者用不同的大小修改),可用区域的碎片会逐渐发生。这种情况下,设置 <b style="line-height: 20px; ">tune_defrag</b> 来启用自动碎片整理并设置</span></span><span style="line-height: 20px; font-size: small; ">单位步数(unit step number)。建议的单位步数是8,意味着每8个更新操作执行一组碎片整理操作。更大的数,空间效率会变高但时间效率会变低。</span></div><div style="line-height: 22px; "><span style="line-height: 20px; font-size: small; "><br /></span></div><div style="line-height: 22px; "><span style="line-height: 20px; font-size: small; "><span style="line-height: 22px; font-size: 14px; "><span style="line-height: 20px; font-size: small; "><span style="line-height: 20px; "><span style="line-height: 20px; "><b style="line-height: 20px; ">HashDB::TCOMPRESS </b></span><span style="line-height: 20px; ">选项</span><span style="line-height: 20px; ">默认压缩算法是由ZLIB 实现的 "Deflate"算法。如果你想用别算法,调用 </span></span></span><span style="line-height: 20px; font-size: small; "><b style="line-height: 20px; ">tune_compressor </b></span><span style="line-height: 20px; font-size: small; ">来设置一个压缩与解压的函数是实现。</span></span></span></div><div style="line-height: 22px; "><span style="line-height: 20px; font-size: small; "><span style="line-height: 20px; "><br /></span></span></div><div style="line-height: 22px; "><span style="line-height: 20px; font-size: small; "><span style="line-height: 20px; ">如果你想存储1万个记录,并尽可能减小数据库大小,</span></span><span style="line-height: 20px; font-size: small; ">建议按下面示例这样设置。</span></div><div style="line-height: 22px; "><span style="line-height: 20px; font-size: small; "><span style="line-height: 20px; "><span style="line-height: normal; color: rgb(17, 17, 17); font-family: Simsun; font-size: medium; "><pre style="line-height: 19px; margin-top: 0.8ex; margin-right: 1.5ex; margin-bottom: 0.8ex; margin-left: 1.5ex; padding-top: 0.2ex; padding-right: 0.2ex; padding-bottom: 0.2ex; padding-left: 0.2ex; background-color: rgb(238, 238, 248); border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(221, 221, 238); border-right-color: rgb(221, 221, 238); border-bottom-color: rgb(221, 221, 238); border-left-color: rgb(221, 221, 238); font-size: 12px; ">db.tune_alignment(0); db.tune_options(HashDB::TSMALL | HashDB::TLINEAR); db.tune_buckets(10LL * 1000); db.tune_defrag(8); db.open(...);</pre></span></span></span></div><div style="line-height: 22px; "><span style="line-height: 20px; font-size: small; "><span style="line-height: 20px; ">如果你有巨兽般的512GB内存的机器,想存储百亿个记录,并想尽可能改进时间效率,</span></span><span style="line-height: 20px; font-size: small; ">建议按下面示例这样设置。</span></div><div style="line-height: 22px; "><span style="line-height: 20px; font-size: small; "><span style="line-height: normal; color: rgb(17, 17, 17); font-family: Simsun; font-size: medium; "><pre style="line-height: 19px; margin-top: 0.8ex; margin-right: 1.5ex; margin-bottom: 0.8ex; margin-left: 1.5ex; padding-top: 0.2ex; padding-right: 0.2ex; padding-bottom: 0.2ex; padding-left: 0.2ex; background-color: rgb(238, 238, 248); border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(221, 221, 238); border-right-color: rgb(221, 221, 238); border-bottom-color: rgb(221, 221, 238); border-left-color: rgb(221, 221, 238); font-size: 12px; ">db.tune_options(HashDB::TLINEAR); db.tune_buckets(20LL * 1000 * 1000 * 1000); db.tune_map(300LL << 30); db.open(...);</pre></span></span></div><div style="line-height: 22px; "><span style="line-height: 20px; font-size: small; ">所有的调优方法必须在数据库打开前设置。因为 <b style="line-height: 20px; ">tune_alignment</b>, <b style="line-height: 20px; ">tune_fbp</b>, <b style="line-height: 20px; ">tune_options</b>, 和 <b style="line-height: 20px; ">tune_buckets </b>设置项是作为数据库的元数据存储的,这些方法必须在数据库被创建的前调用,并且之后不能修改。因为其它的调优参数不是保存在数据库中的,所以他们可以在每次打开数据库时设置。</span></div><div style="line-height: 22px; "><span style="line-height: 20px; font-size: small; "><br /></span></div><div style="line-height: 22px; "><span style="line-height: 20px; font-size: small; "><b style="line-height: 20px; ">调优 File Tree 数据库</b></span></div><div style="line-height: 22px; "><span style="line-height: 20px; font-size: small; "><span style="line-height: 20px; ">file tree数据库(TreeDB)是B+ tree的文件数据库。</span></span><span style="line-height: 20px; font-size: small; ">因为B+ tree中的每个node被序列化为一个page buffer,并被存储为 file hash数据库中的一个记录,所以file hash数据库中的所有配置项都可以用在file tree数据库中。此外,还有下面这些优化方法。</span></div><div style="line-height: 22px; "><ul style="line-height: 22px; margin-top: 5px; margin-right: 0px; margin-bottom: 5px; margin-left: 40px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><li style="line-height: 22px; "><span style="line-height: 20px; "><b style="line-height: 20px; ">tune_page</b>:</span><span style="line-height: 20px; font-size: small; ">设置每个页大小</span></li><li style="line-height: 22px; "><span style="line-height: 20px; "><b style="line-height: 20px; ">tune_page_cache</b>:</span><span style="line-height: 20px; font-size: small; ">设置页缓存(page cache)容量大小</span></li><li style="line-height: 22px; "><span style="line-height: 20px; "><b style="line-height: 20px; ">tune_comparator</b>:</span><span style="line-height: 20px; font-size: small; ">设置记录比较器</span></li></ul></div><div style="line-height: 22px; "><span style="line-height: 20px; "><span style="line-height: 20px; "><span style="line-height: 20px; ">通过</span><b style="line-height: 20px; ">tune_page </b><span style="line-height: 20px; ">调整</span><span style="line-height: 20px; ">的页大小,大部分情况下不用修改。默认是8192,这是主流环境中典型页大小的两倍。如果每个节点的大小超过了这个值,节点被分为两个。</span></span></span></div><div style="line-height: 22px; "><span style="line-height: 20px; "><span style="line-height: 20px; "><br /></span></span></div><div style="line-height: 22px; "><div style="line-height: 22px; font-size: 14px; "><span style="line-height: 20px; "><span style="line-height: 20px; ">页缓存的默认大小是64MB。如果你的机器有大量的内存,设置 </span></span><span style="line-height: 20px; font-size: small; "><b style="line-height: 20px; ">tune_page_cache </b><span style="line-height: 20px; ">加载所有的节点到页缓存中。如果内存不富裕,最好保持默认的页缓存大小,并通过 </span></span><span style="line-height: 20px; font-size: small; "><b style="line-height: 20px; ">tune_map </b><span style="line-height: 20px; ">来对内部内存映射区域分配内存。</span></span></div><div style="line-height: 22px; font-size: 14px; "><span style="line-height: 20px; font-size: small; "><b style="line-height: 20px; "><br /></b></span></div><div style="line-height: 22px; font-size: 14px; "><span style="line-height: 20px; font-size: small; "><span style="line-height: 20px; ">默认的记录比较器是词汇顺序(lexical ordering)函数。这样B+ tree数据库中的记录按照key的词汇顺序放置。如果你想使用其它顺序,调整 </span></span><span style="line-height: 20px; font-size: small; "><b style="line-height: 20px; ">tune_comparator </b><span style="line-height: 20px; ">来设置一个实现排序功能的函数。</span></span></div></div><div style="line-height: 22px; font-size: 14px; "><span style="line-height: 20px; font-size: small; "><span style="line-height: 20px; "><br /></span></span></div><div style="line-height: 22px; font-size: 14px; "><span style="line-height: 20px; font-size: small; "><span style="line-height: 20px; ">file tree数据库的默认对齐是256(1<<8)。默认的bucket数量大概是65536。其它的默认参数和file hash数据库一样。注意bucket的数量应该按照页的数量计算。建议 bucket数量的比率大约是记录数量的10% 。如果压缩选项被指定,每个页的所有记录被立刻压缩。因此,压缩对于 file tree数据库更有效,而不是file hash数据库。</span></span></div><div style="line-height: 22px; font-size: 14px; "><span style="line-height: 20px; font-size: small; "><span style="line-height: 20px; "><br /></span></span></div><div style="line-height: 22px; font-size: 14px; "><span style="line-height: 20px; font-size: small; "><span style="line-height: 20px; ">如果你想存储1万个记录,并尽可能减小数据库大小,</span></span><span style="line-height: 20px; font-size: small; ">建议按下面示例这样设置。</span></div><div style="line-height: 22px; font-size: 14px; "><span style="line-height: 20px; font-size: small; "><span style="line-height: normal; color: rgb(17, 17, 17); font-family: Simsun; font-size: medium; "><pre style="line-height: 19px; margin-top: 0.8ex; margin-right: 1.5ex; margin-bottom: 0.8ex; margin-left: 1.5ex; padding-top: 0.2ex; padding-right: 0.2ex; padding-bottom: 0.2ex; padding-left: 0.2ex; background-color: rgb(238, 238, 248); border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(221, 221, 238); border-right-color: rgb(221, 221, 238); border-bottom-color: rgb(221, 221, 238); border-left-color: rgb(221, 221, 238); font-size: 12px; ">db.tune_options(TreeDB::TLINEAR | TreeDB::TCCOMPESS); db.tune_buckets(1LL * 1000); db.tune_defrag(8); db.tune_page(32768); db.open(...);</pre></span></span></div><div style="line-height: 22px; font-size: 14px; "><span style="line-height: 20px; font-size: small; "><span style="line-height: 22px; font-size: 14px; "><span style="line-height: 20px; font-size: small; "><span style="line-height: 20px; ">如果你有巨兽般的512GB内存的机器,想存储百亿个记录,并想尽可能改进时间效率,</span></span><span style="line-height: 20px; font-size: small; ">建议按下面示例这样设置。</span></span></span></div><div style="line-height: 22px; font-size: 14px; "><span style="line-height: 20px; font-size: small; "><span style="line-height: 22px; font-size: 14px; "><span style="line-height: 20px; font-size: small; "><span style="line-height: normal; color: rgb(17, 17, 17); font-family: Simsun; font-size: medium; "><pre style="line-height: 19px; margin-top: 0.8ex; margin-right: 1.5ex; margin-bottom: 0.8ex; margin-left: 1.5ex; padding-top: 0.2ex; padding-right: 0.2ex; padding-bottom: 0.2ex; padding-left: 0.2ex; background-color: rgb(238, 238, 248); border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(221, 221, 238); border-right-color: rgb(221, 221, 238); border-bottom-color: rgb(221, 221, 238); border-left-color: rgb(221, 221, 238); font-size: 12px; ">db.tune_options(TreeDB::TLINEAR); db.tune_buckets(1LL * 1000 * 1000 * 1000); db.tune_map(300LL << 30); db.tune_page_cache(8LL << 30); db.open(...);</pre></span></span></span></span></div><div style="line-height: 22px; font-size: 14px; "><span style="line-height: 20px; font-size: small; "><span style="line-height: 22px; font-size: 14px; "><span style="line-height: 20px; font-size: small; ">所有的调优方法必须在数据库打开前设置。因为 </span></span></span><span style="line-height: 20px; font-size: small; "><b style="line-height: 20px; ">tune_page </b>设置项是作为数据库的元数据存储的,这些方法必须在数据库被创建的前调用,并且之后不能修改。因为其它的调优参数不是保存在数据库中的,所以他们可以在每次打开数据库时设置。</span></div><div style="line-height: 22px; font-size: 14px; "><span style="line-height: 20px; font-size: small; "><span style="line-height: 22px; font-size: 14px; "><span style="line-height: 20px; font-size: small; "><br /></span></span></span></div><div style="line-height: 22px; font-size: 14px; "><span style="line-height: 20px; font-size: small; "><span style="line-height: 22px; font-size: 14px; "><span style="line-height: 20px; font-size: small; "><b style="line-height: 20px; ">调优 Directory Hash 数据库</b></span></span></span></div><div style="line-height: 22px; font-size: 14px; "><span style="line-height: 20px; font-size: small; "><span style="line-height: 22px; font-size: 14px; "><span style="line-height: 20px; font-size: small; ">directory hash 数据库(DirDB)是由文件系统的目录机制驱动的,每个记录对应于目录中的一个文件。</span></span></span><span style="line-height: 20px; font-size: small; ">提供下面这些调整参数设置。</span></div><div style="line-height: 22px; "><ul style="line-height: 22px; margin-top: 5px; margin-right: 0px; margin-bottom: 5px; margin-left: 40px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><li style="line-height: 22px; "><span style="line-height: 20px; "><b style="line-height: 20px; ">tune_options</b>:</span><span style="line-height: 20px; font-size: small; ">设置可选特性</span></li></ul><div style="line-height: 22px; "><span style="line-height: 20px; "><span style="line-height: 20px; "><span style="line-height: 22px; font-size: 14px; "><span style="line-height: 20px; font-size: small; "><span style="line-height: 20px; ">可选特性</span></span><span style="line-height: 20px; font-size: small; "><b style="line-height: 20px; ">tune_options</b><span style="line-height: 20px; ">可以减少数据库文件大小</span></span></span></span></span><span style="line-height: 20px; font-size: small; ">,以损失伸缩性或时间效率为代价。如果设置为 <b style="line-height: 20px; ">DirDB::TCOMPRESS</b> ,</span><span style="line-height: 20px; font-size: small; ">每个记录的key和value在存储到文件时会被隐式压缩处理。如果value大于1KB或更多,压缩是很有效的。</span></div></div><div style="line-height: 22px; font-size: 14px; "><span style="line-height: 20px; font-size: small; "><br /></span></div><div style="line-height: 22px; font-size: 14px; "><span style="line-height: 20px; font-size: small; ">directory hash 数据库的性能严重依赖于文件系统的实现和设置。像EXT2这样的文件系统并不善于在一个目录中存储很多文件。但是这种情况下,其它文件系统如 EXT3 和 ReiserFS 是相对有效的。一般而言,具有B tree特性的文件系统及其变体比线形搜索算法更适合。</span></div><div style="line-height: 22px; font-size: 14px; "><span style="line-height: 20px; font-size: small; "><br /></span></div><div style="line-height: 22px; font-size: 14px; "><span style="line-height: 20px; font-size: small; ">所有的调优方法必须在数据库打开前设置。</span><span style="line-height: 20px; font-size: small; "><span style="line-height: 22px; font-size: 14px; "><span style="line-height: 20px; font-size: small; ">因为 </span></span></span><span style="line-height: 20px; font-size: small; "><b style="line-height: 20px; "><span style="line-height: 20px; font-weight: normal; "><b style="line-height: 20px; ">tune_options</b></span> </b>设置项是作为数据库的元数据存储的,这些方法必须在数据库被创建的前调用,并且之后不能修改。</span></div><div style="line-height: 22px; font-size: 14px; "><span style="line-height: 20px; font-size: small; "><br /></span></div><div style="line-height: 22px; font-size: 14px; "><b style="line-height: 22px; "><span style="line-height: 20px; font-size: small; "><span style="line-height: 22px; font-size: 14px; "><span style="line-height: 20px; font-size: small; ">调优 </span></span></span><span style="line-height: 20px; font-size: small; "><span style="line-height: 20px; ">Directory Tree</span></span><span style="line-height: 20px; font-size: small; "> 数据库</span></b></div><div style="line-height: 22px; font-size: 14px; "><span style="line-height: 20px; font-size: small; ">directory tree 数据库(ForestDB)是B+ tree的目录数据库。正如 file tree 数据库是基于 file hash 数据库一样,</span><span style="line-height: 20px; font-size: small; ">directory tree 数据库是基于 </span><span style="line-height: 20px; font-size: small; ">directory hash 数据库。</span><span style="line-height: 20px; font-size: small; ">所以 </span><span style="line-height: 20px; font-size: small; ">directory hash </span><span style="line-height: 20px; font-size: small; ">数据库中的所有配置项都可以用在 </span><span style="line-height: 20px; font-size: small; ">directory tree </span><span style="line-height: 20px; font-size: small; ">数据库中。其它调优方法与 file tree 数据库相同。</span></div><div style="line-height: 22px; font-size: 14px; "><span style="line-height: 20px; font-size: small; "><br /></span></div><div style="line-height: 22px; font-size: 14px; "><span style="line-height: 20px; font-size: small; ">directory tree 数据库的性能特征类似于 </span><span style="line-height: 20px; font-size: small; ">directory hash 数据库。然而,因为记录被组织在页中,所以在许多情况下,I/O操作的频率要少些、性能更好些。</span></div><div style="line-height: 22px; font-size: 14px; "><b style="line-height: 22px; "><span style="line-height: 20px; font-size: small; "><br /></span></b></div><div style="line-height: 22px; font-size: 14px; "><b style="line-height: 22px; "><span style="line-height: 20px; font-size: small; ">选择合适的数据库</span></b></div><div style="line-height: 22px; font-size: 14px; "><span style="line-height: 20px; font-size: small; ">为了针对你的应用选择合适的数据库,清晰的需求规格书非常重要。如果不需要记录持久保存,建议使用内存数据库。有 prototype hash数据库(ProtoHashDB),prototype tree 数据库(ProtoTreeDB),stash 数据库(StashDB),cache hash数据库(CacheDB),和cache tree数据库(GrassDB)。如果对你应用逻辑而言,key的顺序非常重要,那么cache tree数据库比较合适。如果不是,stash数据库比较合适。cache tree数据库的内存占用要小于其它的。cache hash数据库能够隐式删除老的记录并保持内存占用为常量。prototype 数据库在少数情况下有用。</span></div><div style="line-height: 22px; "><ul style="line-height: 22px; margin-top: 5px; margin-right: 0px; margin-bottom: 5px; margin-left: 40px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><li style="line-height: 22px; "><span style="line-height: 20px; "><span style="line-height: 20px; ">时间效率:CacheDB > StashDB > ProtoHashDB > ProtoTreeDB > GrassDB</span></span></li><li style="line-height: 22px; "><span style="line-height: 20px; "><span style="line-height: 20px; ">空间效率:GrassDB > StashDB > CacheDB > ProtoHashDB > ProtoTreeDB</span></span></li></ul><div style="line-height: 22px; "><span style="line-height: 20px; "><span style="line-height: 20px; "><br /></span></span></div><div style="line-height: 22px; "><span style="line-height: 20px; "><span style="line-height: 20px; ">如果你的应用需要持久化保存记录,建议使用持久数据库。有 file hash 数据库(HashDB),file tree 数据库(TreeDB),</span></span><span style="line-height: 20px; font-size: small; ">directory hash 数据库(DirDB)和 </span><span style="line-height: 20px; font-size: small; ">directory tree 数据库(ForestDB)。</span><span style="line-height: 20px; font-size: small; ">如果对你应用逻辑而言,key的顺序非常重要,那么 </span><span style="line-height: 20px; font-size: small; ">file tree 数据库比较合适。如果不是,</span><span style="line-height: 20px; font-size: small; "> file hash 数据库比较合适。在大部分情况下,</span><span style="line-height: 20px; font-size: small; "> file hash 数据库的性能和并发性要好于其它的。如果每个记录的大小很大,</span><span style="line-height: 20px; font-size: small; ">directory hash 数据库比较合适。</span></div></div><div style="line-height: 22px; "><span style="line-height: 20px; font-size: small; "><br /></span></div><div style="line-height: 22px; "><span style="line-height: 20px; font-size: small; ">包括 KC 和 TC 在内的大部分DBM实现是对存储小记录而优化的。既然如此,如果你想处理非常大的记录,直接使用文件系统是更好的解决方案,而不是DBM。如果你存储和获取大记录,那么 read 和 write 系统调用的处理时间是主要的,而不是 open 和 lseek 系统调用。尽管典型的DBM会减小每个记录的定位时间的工作量,但是他们会增加每个记录数据</span><span style="line-height: 20px; font-size: small; ">读写</span><span style="line-height: 20px; font-size: small; ">的工作量。如果你处理大记录但不想直接使用文件系统,那么使用 </span><span style="line-height: 20px; font-size: small; ">directory hash 数据库。它仅仅是对文件系统的目录机制的包装。如果你想按照key的顺序处理大记录,应该使用 </span><span style="line-height: 20px; font-size: small; ">directory tree 数据库。</span><span style="line-height: 20px; font-size: small; "> </span><span style="line-height: 20px; font-size: small; ">directory tree 数据库是可扩展性的最后武器。</span></div><div style="line-height: 22px; "><ul style="line-height: 22px; margin-top: 5px; margin-right: 0px; margin-bottom: 5px; margin-left: 40px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><li style="line-height: 22px; "><span style="line-height: 20px; "><span style="line-height: 20px; ">时间效率:HashDB > TreeDB > DirDB > ForestDB</span></span></li><li style="line-height: 22px; "><span style="line-height: 20px; "><span style="line-height: 20px; ">空间效率:TreeDB > HashDB > ForestDB > DirDB</span></span></li></ul><div style="line-height: 22px; "><span style="line-height: 20px; "><span style="line-height: 20px; "><br /></span></span></div></div><div style="line-height: 22px; "><span style="line-height: 20px; "><span style="line-height: 20px; ">如果你想使用产品代码做性能测试来决定数据库的类型,那么使用多态(polymorphic)数据库。它可以在打开数据库的时候动态指定数据库类型。事实上,多态数据库被建议在大部分场景下使用,尽管它会在运行时带来一点点的性能损失。这就是为什么官方的脚本语言绑定只支持多态数据库。</span></span></div><div style="line-height: 22px; "><span style="line-height: 20px; "><span style="line-height: 20px; "><br /></span></span></div><div style="line-height: 22px; "><span style="line-height: 20px; "><span style="line-height: 20px; "><b style="line-height: 20px; ">事物性</b></span></span></div><div style="line-height: 22px; font-size: 14px; "><span style="line-height: 20px; font-size: small; ">如果打开数据库的应用进程没有关闭数据库,它会带来数据丢失和数据库损坏的风险。默认,正确地关闭数据库时持久性是稳定的,对于每个更新操作是不稳定的。KC处理这个问题是基于WAL(write ahead logging)的事物机制。事物由应用显示的开始和提交。在事物期间的每个更新操作的持久性是稳定的。事物可以由应用取消。这种情况下,所有事物期间的更新操作将被废弃,数据库的内容会被回滚。像这样尽管事物是非常有用的,但是</span><span style="line-height: 20px; font-size: small; ">由于增加了写WAL数据,</span><span style="line-height: 20px; font-size: small; ">更新操作的吞吐率会下降到默认方式的大约50%。</span></div><div style="line-height: 22px; font-size: 14px; "><span style="line-height: 20px; font-size: small; "><span style="line-height: normal; color: rgb(17, 17, 17); font-family: Simsun; font-size: medium; "><pre style="line-height: 19px; margin-top: 0.8ex; margin-right: 1.5ex; margin-bottom: 0.8ex; margin-left: 1.5ex; padding-top: 0.2ex; padding-right: 0.2ex; padding-bottom: 0.2ex; padding-left: 0.2ex; background-color: rgb(238, 238, 248); border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(221, 221, 238); border-right-color: rgb(221, 221, 238); border-bottom-color: rgb(221, 221, 238); border-left-color: rgb(221, 221, 238); font-size: 12px; ">db.begin_transaction(); db.set("japan", "tokyo"); db.set("korea", "seoul"); db.end_transaction();</pre></span></span></div><div style="line-height: 22px; font-size: 14px; "><span style="line-height: 20px; font-size: small; ">如果你对显示地开始和提交事务感到烦恼,那么可以使用自动事物机制,在打开数据库的时候指定 <b style="line-height: 20px; ">BasicDB::AUTOTRAN</b> 选项。这样自动事物对每个更新操作隐式地开始和提交。自动事物的额外负担要轻于显示地事物。</span></div><div style="line-height: 22px; font-size: 14px; "><span style="line-height: 20px; font-size: small; "><span style="line-height: normal; color: rgb(17, 17, 17); font-family: Simsun; font-size: medium; "><pre style="line-height: 19px; margin-top: 0.8ex; margin-right: 1.5ex; margin-bottom: 0.8ex; margin-left: 1.5ex; padding-top: 0.2ex; padding-right: 0.2ex; padding-bottom: 0.2ex; padding-left: 0.2ex; background-color: rgb(238, 238, 248); border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(221, 221, 238); border-right-color: rgb(221, 221, 238); border-bottom-color: rgb(221, 221, 238); border-left-color: rgb(221, 221, 238); font-size: 12px; ">db.open("casket.kch", HashDB::OWRITER | HashDB::OCREATE | HashDB::OAUTOTRAN); db.set("japan", "tokyo"); db.set("china", "beijing");</pre></span></span></div><div style="line-height: 22px; font-size: 14px; "><span style="line-height: 20px; font-size: small; ">毕竟,根据你的应用的需求选择使用方式是非常重要的。</span></div><div style="line-height: 22px; font-size: 14px; "><span style="line-height: 20px; font-size: small; "><br /></span></div><div style="line-height: 22px; font-size: 14px; "><span style="line-height: 20px; font-size: small; "><b style="line-height: 20px; ">默认</b></span></div><div style="line-height: 22px; "><span style="line-height: 20px; "><span style="line-height: 20px; ">进程崩溃的风险:一些记录可能丢失</span></span></div><div style="line-height: 22px; "><span style="line-height: 20px; "><span style="line-height: 20px; ">系统崩溃的风险:</span></span><span style="line-height: 20px; font-size: small; ">一些记录可能丢失</span></div><div style="line-height: 22px; "><span style="line-height: 20px; "><span style="line-height: 20px; ">性能损失:无</span></span></div><div style="line-height: 22px; "><span style="line-height: 20px; "><span style="line-height: 20px; ">注意:崩溃后的自动恢复花的时间与数据库大小成比例</span></span></div><div style="line-height: 22px; "><span style="line-height: 20px; "><span style="line-height: 20px; "><br /></span></span></div><div style="line-height: 22px; "><span style="line-height: 20px; "><span style="line-height: 20px; "><b style="line-height: 20px; ">事物</b></span></span></div><div style="line-height: 22px; "><span style="line-height: 20px; "><span style="line-height: 20px; ">隐式使用:open(..., BasicDB::OAUTOTRAN);</span></span></div><div style="line-height: 22px; "><span style="line-height: 20px; "><span style="line-height: 20px; ">显示使用:begin_transaction(false); ...; end_transaction(true);</span></span></div><div style="line-height: 22px; "><span style="line-height: 20px; "><span style="line-height: 20px; ">进程崩溃的风险:</span></span><span style="line-height: 20px; font-size: small; ">无</span></div><div style="line-height: 22px; "><span style="line-height: 20px; font-size: small; "><span style="line-height: 22px; font-size: 14px; "><span style="line-height: 20px; "><span style="line-height: 20px; ">系统崩溃的风险:</span></span><span style="line-height: 20px; font-size: small; ">一些记录可能丢失</span></span></span></div><div style="line-height: 22px; "><span style="line-height: 20px; font-size: small; "><span style="line-height: 22px; font-size: 14px; "><span style="line-height: 20px; font-size: small; ">性能损失:吞吐率将下降到大约30%或更低</span></span></span></div><div style="line-height: 22px; "><span style="line-height: 20px; "><span style="line-height: 20px; "><br /></span></span></div><div style="line-height: 22px; "><span style="line-height: 20px; "><span style="line-height: 20px; "><b style="line-height: 20px; ">事物+同步</b></span></span></div><div style="line-height: 22px; font-size: 14px; "><span style="line-height: 20px; font-size: small; ">隐式使用:open(..., BasicDB::OAUTOTRAN | BasicDB::OAUTOSYNC);</span></div><div style="line-height: 22px; font-size: 14px; "><span style="line-height: 20px; font-size: small; ">显示使用:begin_transaction(true); ...; end_transaction(true);</span></div><div style="line-height: 22px; font-size: 14px; "><span style="line-height: 20px; font-size: small; "><span style="line-height: 22px; font-size: 14px; "><span style="line-height: 20px; "><span style="line-height: 20px; ">进程崩溃的风险:</span></span><span style="line-height: 20px; font-size: small; ">无</span></span></span></div><div style="line-height: 22px; font-size: 14px; "><span style="line-height: 20px; font-size: small; "><span style="line-height: 22px; font-size: 14px; "><span style="line-height: 20px; font-size: small; "><span style="line-height: 22px; font-size: 14px; "><span style="line-height: 20px; "><span style="line-height: 20px; ">系统崩溃的风险:</span></span></span></span></span></span><span style="line-height: 20px; font-size: small; ">无</span></div><div style="line-height: 22px; font-size: 14px; "><span style="line-height: 20px; font-size: small; ">性能损失:</span><span style="line-height: 20px; font-size: small; ">吞吐率将下降到大约1%或更低</span></div><div style="line-height: 22px; "><span style="line-height: 20px; "><span style="line-height: 20px; "><br /></span></span></div><div style="line-height: 22px; "><span style="line-height: 20px; "><span style="line-height: 20px; "><b style="line-height: 20px; ">备份</b></span></span></div><div style="line-height: 22px; "><span style="line-height: 20px; "><span style="line-height: 20px; ">任何硬件设备都可能突然发生故障。尤其是存储设备,如HDD和SSD是脆弱的。因此,定期备份你的数据库文件是很重要的,即使你使用事物。当数据库不被另一个进程更新的时候,你可以使用如 cp 、 tar 这样的命令复制数据库文件。</span></span></div><div style="line-height: 22px; "><span style="line-height: 20px; "><span style="line-height: 20px; "><br /></span></span></div><div style="line-height: 22px; "><span style="line-height: 20px; "><span style="line-height: 20px; ">如果应用使用了多线程,你想安全地做数据库的备份文件,使用 <b style="line-height: 20px; ">BasicDB::copy</b> 方法,它会同步数据库状态和数据库文件并生成一个复制文件。在数据复制期间,应该保证数据库文件不被更新。</span></span></div><div style="line-height: 22px; "><span style="line-height: 20px; "><span style="line-height: 20px; "><span style="line-height: normal; color: rgb(17, 17, 17); font-family: Simsun; font-size: medium; "><pre style="line-height: 19px; margin-top: 0.8ex; margin-right: 1.5ex; margin-bottom: 0.8ex; margin-left: 1.5ex; padding-top: 0.2ex; padding-right: 0.2ex; padding-bottom: 0.2ex; padding-left: 0.2ex; background-color: rgb(238, 238, 248); border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(221, 221, 238); border-right-color: rgb(221, 221, 238); border-bottom-color: rgb(221, 221, 238); border-left-color: rgb(221, 221, 238); font-size: 12px; ">db.copy("backup.kch");</pre></span></span></span></div><div style="line-height: 22px; "><span style="line-height: 20px; "><span style="line-height: 20px; ">你可能想要“热备份”,意味着在一个线程创建备份文件的同时,其它线程不被阻塞。这种情况,使用 <b style="line-height: 20px; ">File::synchronize</b> 方法,它将同步数据库文件并调用一个任意定义的函数。回调函数能执行一个操作系统提供的"snapshot"命令。</span></span></div><div style="line-height: 22px; "><span style="line-height: 20px; "><span style="line-height: 20px; "><span style="line-height: normal; color: rgb(17, 17, 17); font-family: Simsun; font-size: medium; "><pre style="line-height: 19px; margin-top: 0.8ex; margin-right: 1.5ex; margin-bottom: 0.8ex; margin-left: 1.5ex; padding-top: 0.2ex; padding-right: 0.2ex; padding-bottom: 0.2ex; padding-left: 0.2ex; background-color: rgb(238, 238, 248); border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(221, 221, 238); border-right-color: rgb(221, 221, 238); border-bottom-color: rgb(221, 221, 238); border-left-color: rgb(221, 221, 238); font-size: 12px; ">class BackupImpl : public FileProcessor { bool process(const std::string& path, int64_t size, int64_t count) { char cmd[1024]; sprintf(cmd, "snapshot.sh %s", path.c_str()); return system(cmd) == 0; } } proc; db.synchronize(&proc);</pre></span></span></span></div><div style="line-height: 22px; "><span style="line-height: 20px; "><span style="line-height: 20px; "><br /></span></span></div><div style="line-height: 22px; "><span style="line-height: 20px; "><span style="line-height: 20px; "><b style="line-height: 20px; ">伪快照(Pseudo-snapshot)</b></span></span></div><div style="line-height: 22px; "><span style="line-height: 20px; "><span style="line-height: 20px; ">主要为 cache hash数据库和 cache tree数据库提供伪快照机制。<b style="line-height: 20px; ">BasicDB::dump_snapshot</b> 方法 dump 所有记录到一个流或一个文件中。<b style="line-height: 20px; ">BasicDB::load_snapshot</b> 方法从一个流或一个文件中加载记录。尽管操作是原子执行的,但是它不会立刻完成,需要花数据库大小比例时间并阻塞其它线程。因为伪快照数据的格式是在所有数据库类通用的,所以适合合并彼此记录。</span></span></div><div style="line-height: 22px; "><span style="line-height: 20px; "><span style="line-height: 20px; "><span style="line-height: normal; color: rgb(17, 17, 17); font-family: Simsun; font-size: medium; "><pre style="line-height: 19px; margin-top: 0.8ex; margin-right: 1.5ex; margin-bottom: 0.8ex; margin-left: 1.5ex; padding-top: 0.2ex; padding-right: 0.2ex; padding-bottom: 0.2ex; padding-left: 0.2ex; background-color: rgb(238, 238, 248); border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(221, 221, 238); border-right-color: rgb(221, 221, 238); border-bottom-color: rgb(221, 221, 238); border-left-color: rgb(221, 221, 238); font-size: 12px; ">db.dump_snapshot("backup.kcss"); db.load_snapshot("backup.kcss");</pre></span></span></span></div><div style="line-height: 22px; "><span style="line-height: 20px; "><span style="line-height: 20px; ">如果你不想要其它线程被阻塞,自己使用游标机制来保存/加载记录。</span></span></div><div style="line-height: 22px; "><span style="line-height: 20px; "><span style="line-height: 20px; "><br /></span></span></div><div style="line-height: 22px; "><span style="line-height: 20px; "><span style="line-height: 20px; "><b style="line-height: 20px; ">加密数据库</b></span></span></div><div style="line-height: 22px; "><span style="line-height: 20px; ">file tree 等的数据库的 <b style="line-height: 20px; ">tune_compressor</b> 方法可以设置任意的数据压缩功能。事实上,功能不仅可以执行时间压缩,也可以执行数据加密。<b style="line-height: 20px; ">ArcfourCompressor</b> 类实现了基于Arcfour (aka. RC4)的轻量加密算法。它可以用来临时改进你数据库的安全性而不会增加高负载。</span></div><div style="line-height: 22px; "><span style="line-height: 20px; "><span style="line-height: normal; color: rgb(17, 17, 17); font-family: Simsun; font-size: medium; "><pre style="line-height: 19px; margin-top: 0.8ex; margin-right: 1.5ex; margin-bottom: 0.8ex; margin-left: 1.5ex; padding-top: 0.2ex; padding-right: 0.2ex; padding-bottom: 0.2ex; padding-left: 0.2ex; background-color: rgb(238, 238, 248); border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(221, 221, 238); border-right-color: rgb(221, 221, 238); border-bottom-color: rgb(221, 221, 238); border-left-color: rgb(221, 221, 238); font-size: 12px; ">ArcfourCompressor comp; comp.set_key("foobarbaz", 9); TreeDB db; db.tune_options(kc::TreeDB::TCOMPRESS); db.tune_compressor(&comp); db.open(...); comp.begin_cycle((uint64_t)getpid() << 32 + (uint64_t)time());</pre></span></span></div><div style="line-height: 22px; "><span style="line-height: 20px; ">如果你使用多态数据库,很容易启用加密。zcomp 选择指定压缩算法,zkey 指定密钥。</span></div><div style="line-height: 22px; "><span style="line-height: 20px; "><span style="line-height: normal; color: rgb(17, 17, 17); font-family: Simsun; font-size: medium; "><pre style="line-height: 19px; margin-top: 0.8ex; margin-right: 1.5ex; margin-bottom: 0.8ex; margin-left: 1.5ex; padding-top: 0.2ex; padding-right: 0.2ex; padding-bottom: 0.2ex; padding-left: 0.2ex; background-color: rgb(238, 238, 248); border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(221, 221, 238); border-right-color: rgb(221, 221, 238); border-bottom-color: rgb(221, 221, 238); border-left-color: rgb(221, 221, 238); font-size: 12px; ">PolyDB db; db.open("casket.kct#zcomp=arc#zkey=foobarbaz", ...);</pre></span></span></div><div style="line-height: 22px; "><span style="line-height: 20px; ">zcomp支持用 zlib 对于ZLIB的原始格式, def对于 Deflate格式, gz对于gzip格式,arc对于</span><span style="line-height: 20px; font-size: small; ">Arcfour加密,arcz对于ZLIB的</span><span style="line-height: 20px; font-size: small; ">Arcfour加密压缩。</span></div><div style="line-height: 22px; "><span style="line-height: 20px; font-size: small; ">注意哈希数据库类型(CacheDB,HashDB,DirDB)只压缩每个记录的value。这样,每个记录的key不会被压缩。然而,树型数据库(GrassDB,TreeDB,ForestDB)压缩数据库中的所有数据。所以,如果你想要通过压缩来加密,请选择一种树型数据库。</span></div><div style="line-height: 22px; "><span style="line-height: 20px; "><br /></span></div><div style="line-height: 22px; "><span style="line-height: 20px; "><span style="line-height: 20px; "><b style="line-height: 20px; ">内存数据库的空间效率</b></span></span></div><div style="line-height: 22px; "><span style="line-height: 20px; "><span style="line-height: 20px; ">stash 数据库(StashDB),cache hash 数据库(CacheDB),和 cache tree 数据库(GrassDB)可以节省字符串形式的关联数组的内存使用。他们可以替代 C++中的std::map,Java中的java.util.Map,和许多脚本语言内建的关联数组机制。stash数据库和cache hash数据库可以改进空间效率,由于将每个记录的key和value序列化到一个字节数组中。cache tree 数据库改进了空间效率,由于将每个页中记录序列化到了一个字节数组。</span></span></div><div style="line-height: 22px; "><span style="line-height: 20px; "><span style="line-height: 20px; "><br /></span></span></div><div style="line-height: 22px; "><span style="line-height: 20px; "><span style="line-height: 20px; ">例如,如果你存储一千万记录并且每个key和value都是8字节,`std::map<std::string, string="">' (ProtoTreeDB) 使用大约 1.2GB内存。同样的情况下,stash 数据库使用 465MB 内存;cache hash数据库使用 618MB 内存;cache tree数据库使用 318MB 内存。在这种情况下,cache tree数据库提供了最佳的空间效率。然而,关于时间效率, stash 数据库和 cache 数据库 优于 cache tree数据库,由于哈希表和B+ tree的不同。注意B+ tree是非常适合顺序访问,但不适合随机访问的。要改进B+ tree的时间效率,设置 页大小为1024或更小。</std::string,></span></span></div><div style="line-height: 22px; "><span style="line-height: 20px; "><span style="line-height: 20px; "><br /></span></span></div><div style="line-height: 22px; "><span style="line-height: 20px; "><span style="line-height: 20px; ">如果你想要极端减小内存使用,使用带压缩选项的 cache tree数据库。此外,设置bucket数量为记录数量的5%,设置页大小为32768或更大,设置页缓存容量小于总记录大小的5% 。例如,上面的一千万记录的情况,bucket数量应该是50万,页大小应该是32768,页缓存应该是8MB。对于多态数据库,这些表达为"%#opts=c#bnum=500k#psiz=32768#pccap=8m"。因此,一千万记录只占用 60MB 内存。</span></span></div><div style="line-height: 22px; "><span style="line-height: 20px; "><span style="line-height: 20px; "><br /></span></span></div><div style="line-height: 22px; "><span style="line-height: 20px; "><span style="line-height: 20px; "><b style="line-height: 20px; ">多进程共享一个数据库</b></span></span></div><div style="line-height: 22px; "><span style="line-height: 20px; "><span style="line-height: 20px; ">多进程不能同时访问一个数据库文件。当一个进程连接到它时,数据库文件受读写锁的锁定。注意 <b style="line-height: 20px; ">BasicDB::ONOLOCK</b> 选项不应该被用来跳过文件锁定机制。这个选项是用来绕过一些如NFS这样的文件系统的,它不支持文件锁定机制。</span></span></div><div style="line-height: 22px; "><span style="line-height: 20px; "><span style="line-height: 20px; "><br /></span></span></div><div style="line-height: 22px; "><span style="line-height: 20px; "><span style="line-height: 20px; ">如果你想要多进程共享一个数据库,使用 </span></span><span style="line-height: 25px; color: rgb(17, 17, 17); font-family: Simsun; "><a href="http://fallabs.com/kyototycoon/" style="line-height: 22px; text-decoration: none; color: rgb(0, 34, 170); "><span style="line-height: 20px; ">Kyoto Tycoon</span></a></span><span style="line-height: 20px; font-size: small; "> 替代。它是作为 KC 网络接口的轻型数据库server。</span></div><div style="line-height: 22px; "><span style="line-height: 20px; "><span style="line-height: 20px; "><b style="line-height: 20px; "><br /></b></span></span></div><div style="line-height: 22px; "><span style="line-height: 20px; "><b style="line-height: 22px; "><span style="line-height: 28px; ">六、License</span></b></span></div><div style="line-height: 22px; "><span style="line-height: 20px; "><span style="line-height: 20px; ">要使用KC,你可以选择GNU GPL 或 商业许可。如果你选择GPL,应用程序的源码要兼容GPL的许可。如果你选择商业许可,你将免除GPL的责任。</span></span></div><div style="line-height: 22px; "><span style="line-height: 20px; "><span style="line-height: normal; color: rgb(17, 17, 17); font-family: Simsun; "><span style="line-height: 20px; "><h3 id="license_gpl" style="line-height: 24px; margin-top: 1.6ex; margin-right: 0ex; margin-bottom: 0.5ex; margin-left: 0.2ex; padding-top: 0ex; padding-right: 0ex; padding-bottom: 0ex; padding-left: 0ex; font-weight: bold; color: rgb(0, 17, 17); ">GNU General Public License</h3><p style="line-height: 22px; margin-top: 0.8ex; margin-right: 0ex; margin-bottom: 0.8ex; margin-left: 0ex; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; text-indent: 1.4ex; ">Kyoto Cabinet is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version.</p><p style="line-height: 22px; margin-top: 0.8ex; margin-right: 0ex; margin-bottom: 0.8ex; margin-left: 0ex; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; text-indent: 1.4ex; ">Kyoto Cabinet is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.</p><p style="line-height: 22px; margin-top: 0.8ex; margin-right: 0ex; margin-bottom: 0.8ex; margin-left: 0ex; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; text-indent: 1.4ex; ">You should have received a copy of the GNU General Public License along with this program. If not, see `<code style="line-height: 19px; font-style: normal; font-weight: bold; color: rgb(0, 17, 17); ">http://www.gnu.org/licenses/</code>'.</p><p style="line-height: 22px; margin-top: 0.8ex; margin-right: 0ex; margin-bottom: 0.8ex; margin-left: 0ex; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; text-indent: 1.4ex; "><span style="line-height: normal; "></span></p><h3 id="license_fossexception" style="line-height: 24px; margin-top: 1.6ex; margin-right: 0ex; margin-bottom: 0.5ex; margin-left: 0.2ex; padding-top: 0ex; padding-right: 0ex; padding-bottom: 0ex; padding-left: 0ex; font-weight: bold; color: rgb(0, 17, 17); ">FOSS License Exception</h3><p style="line-height: 22px; margin-top: 0.8ex; margin-right: 0ex; margin-bottom: 0.8ex; margin-left: 0ex; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; text-indent: 1.4ex; ">The FOSS License Exception is also provided in order to accommodate products under other free and open source licenses. See <a href="http://fallabs.com/license/fossexception.txt" style="line-height: 20px; text-decoration: none; color: rgb(0, 34, 170); ">the body text</a> for details.</p><h3 id="license_commercial" style="line-height: 24px; margin-top: 1.6ex; margin-right: 0ex; margin-bottom: 0.5ex; margin-left: 0.2ex; padding-top: 0ex; padding-right: 0ex; padding-bottom: 0ex; padding-left: 0ex; font-weight: bold; color: rgb(0, 17, 17); ">Commercial License</h3><p style="line-height: 22px; margin-top: 0.8ex; margin-right: 0ex; margin-bottom: 0.8ex; margin-left: 0ex; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; text-indent: 1.4ex; ">If you use Kyoto Cabinet within a proprietary software, a commercial license is required.</p><p style="line-height: 22px; margin-top: 0.8ex; margin-right: 0ex; margin-bottom: 0.8ex; margin-left: 0ex; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; text-indent: 1.4ex; ">The commercial license allows you to utilize Kyoto Cabinet by including it in your applications for purpose of developing and producing your applications and to utilize Kyoto Cabinet in order to transfer, sale, rent, lease, distribute or sublicense your applications to any third parties. See <a href="http://fallabs.com/license/" style="line-height: 20px; text-decoration: none; color: rgb(0, 34, 170); ">the license guide</a> for details.</p><p style="line-height: 22px; margin-top: 0.8ex; margin-right: 0ex; margin-bottom: 0.8ex; margin-left: 0ex; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; text-indent: 1.4ex; "><span style="line-height: normal; "></span></p><h3 id="license_author" style="line-height: 24px; margin-top: 1.6ex; margin-right: 0ex; margin-bottom: 0.5ex; margin-left: 0.2ex; padding-top: 0ex; padding-right: 0ex; padding-bottom: 0ex; padding-left: 0ex; font-weight: bold; color: rgb(0, 17, 17); ">Author</h3><p style="line-height: 22px; margin-top: 0.8ex; margin-right: 0ex; margin-bottom: 0.8ex; margin-left: 0ex; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; text-indent: 1.4ex; ">Kyoto Cabinet was written and is maintained by <a href="http://fallabs.com/" style="line-height: 20px; text-decoration: none; color: rgb(0, 34, 170); ">FAL Labs</a>. You can contact the author by e-mail to `<code style="line-height: 19px; font-style: normal; font-weight: bold; color: rgb(0, 17, 17); ">info@fallabs.com</code>'.</p></span></span></span></div></span>hgkhttp://www.blogger.com/profile/18248256147814166844noreply@blogger.com1tag:blogger.com,1999:blog-3051279638784476121.post-15512923258264286562011-03-06T08:09:00.001-08:002011-03-06T08:09:36.148-08:00浏览器本地数据(sessionStorage、localStorage、cookie)与server端数据<span class="Apple-style-span" style="color: rgb(51, 51, 51); font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; line-height: 22px; "><div style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; vertical-align: baseline; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: transparent; "><span style="line-height: 20px; "><span style="line-height: 20px; ">sessionStorage 和 localStorage 是HTML5 Web </span></span><span style="line-height: 20px; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: small; ">Storage API 提供的,可以方便的在web请求之间保存数据。有了本地数据,就可以避免数据在浏览器和服务器间不必要地来回传递。</span></div><div style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; vertical-align: baseline; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: transparent; "><span style="line-height: 20px; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: small; "><br /></span></div><div style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; vertical-align: baseline; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: transparent; "><span style="line-height: 20px; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: small; "><span style="line-height: 22px; font-size: 13px; "><span style="line-height: 22px; color: rgb(68, 68, 68); font-size: 14px; font-family: Arial, Helvetica, sans-serif; ">sessionStorage、localStorage、cookie都是在浏览器端存储的数据,其中sessionStorage的概念很特别,引入了一个“浏览器窗口”的概念。sessionStorage是在同源的同窗口(或tab)中,始终存在的数据。也就是说只要这个浏览器窗口没有关闭,即使刷新页面或进入同源另一页面,数据仍然存在。</span><span style="line-height: 22px; color: rgb(68, 68, 68); font-family: Arial, Helvetica, sans-serif; font-size: 14px; ">关闭窗口后,sessionStorage即被销毁。同时“独立”打开的不同窗口,即使是同一页面,sessionStorage对象也是不同的。</span></span></span></div><div style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; vertical-align: baseline; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: transparent; "><span style="line-height: 20px; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: small; "><span style="line-height: 22px; font-size: 13px; "><span style="line-height: 22px; color: rgb(68, 68, 68); font-family: Arial, Helvetica, sans-serif; font-size: 14px; "><br /></span></span></span></div><div style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; vertical-align: baseline; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: transparent; "><span style="line-height: 20px; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: small; "><span style="line-height: 22px; font-size: 13px; "><span style="line-height: 22px; color: rgb(68, 68, 68); font-family: Arial, Helvetica, sans-serif; font-size: 14px; "><span style="line-height: 22px; color: rgb(0, 0, 0); "><div style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; vertical-align: baseline; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: transparent; "><span style="line-height: 20px; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: small; "><span style="line-height: 22px; font-family: Arial, Helvetica, sans-serif; color: rgb(0, 0, 0); font-size: 14px; "><span style="line-height: 20px; "><span style="line-height: 20px; ">Web </span></span><span style="line-height: 20px; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: small; ">Storage</span></span>带来的好处:</span></div><div style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; vertical-align: baseline; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: transparent; "><ol style="line-height: 22px; margin-top: 5px; margin-right: 0px; margin-bottom: 5px; margin-left: 40px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><li style="line-height: 22px; "><span style="line-height: 20px; "><span style="line-height: 20px; ">减少网络流量:一旦数据保存在本地后,就可以避免再向服务器请求数据,因此减少不必要的数据请求,减少</span></span><span style="line-height: 20px; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: small; ">数据在浏览器和服务器间不必要地来回传递。</span></li><li style="line-height: 22px; "><span style="line-height: 20px; "><span style="line-height: 20px; ">快速显示数据:性能好,从本地读数据比通过网络从服务器获得数据快得多,本地数据可以即时获得。再加上网页本身也可以有缓存,因此整个页面和数据都在本地的话,可以立即显示。</span></span></li><li style="line-height: 22px; "><span style="line-height: 20px; "><span style="line-height: 20px; ">临时存储:很多时候数据只需要在用户浏览一组页面期间使用,关闭窗口后数据就可以丢弃了,这种情况使用</span></span><span style="line-height: 22px; color: rgb(68, 68, 68); ">sessionStorage非常方便。</span></li></ol></div></span></span></span></span></div><div style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 13px; vertical-align: baseline; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: transparent; color: rgb(51, 51, 51); font-family: Arial, sans-serif; "><br /></div><div style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 13px; vertical-align: baseline; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: transparent; color: rgb(51, 51, 51); font-family: Arial, sans-serif; "><br /></div><div style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; vertical-align: baseline; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: transparent; color: rgb(51, 51, 51); font-family: Arial, sans-serif; "><span style="line-height: 25px; "><b style="line-height: 25px; ">浏览器本地存储与服务器端存储之间的区别</b></span></div><div style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 13px; vertical-align: baseline; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: transparent; color: rgb(51, 51, 51); font-family: Arial, sans-serif; ">其实数据既可以在浏览器本地存储,也可以在服务器端存储。</div><div style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 13px; vertical-align: baseline; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: transparent; color: rgb(51, 51, 51); font-family: Arial, sans-serif; "><br /></div><div style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 13px; vertical-align: baseline; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: transparent; color: rgb(51, 51, 51); font-family: Arial, sans-serif; ">浏览器端可以保存一些数据,需要的时候直接从本地获取,sessionStorage、localStorage和cookie都由浏览器存储在本地的数据。</div><div style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 13px; vertical-align: baseline; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: transparent; color: rgb(51, 51, 51); font-family: Arial, sans-serif; "><br /></div><div style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 13px; vertical-align: baseline; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: transparent; color: rgb(51, 51, 51); font-family: Arial, sans-serif; ">服务器端也可以保存所有用户的所有数据,但需要的时候浏览器要向服务器请求数据。</div><div style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 13px; vertical-align: baseline; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: transparent; color: rgb(51, 51, 51); font-family: Arial, sans-serif; ">1.服务器端可以保存用户的持久数据,如数据库和云存储将用户的大量数据保存在服务器端。</div><div style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 13px; vertical-align: baseline; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: transparent; color: rgb(51, 51, 51); font-family: Arial, sans-serif; ">2.服务器端也可以保存用户的临时会话数据。服务器端的session机制,如jsp的 session 对象,数据保存在服务器上。实现上,服务器和浏览器之间仅需传递session id即可,服务器根据session id找到对应用户的session对象。会话数据仅在一段时间内有效,这个时间就是server端设置的session有效期。</div><div style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 13px; vertical-align: baseline; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: transparent; color: rgb(51, 51, 51); font-family: Arial, sans-serif; "><span style="line-height: 20px; "><br /></span></div><div style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 13px; vertical-align: baseline; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: transparent; color: rgb(51, 51, 51); font-family: Arial, sans-serif; "><span style="line-height: 20px; ">服务器端</span>保存所有的用户的数据,所以服务器端的开销较大,而浏览器端保存则把不同用户需要的数据分布保存在用户各自的浏览器中。</div><div style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 13px; vertical-align: baseline; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: transparent; color: rgb(51, 51, 51); font-family: Arial, sans-serif; ">浏览器端一般只用来存储小数据,而服务器可以存储大数据或小数据。</div><div style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 13px; vertical-align: baseline; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: transparent; color: rgb(51, 51, 51); font-family: Arial, sans-serif; ">服务器存储数据安全一些,浏览器只适合存储一般数据。</div><div style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 13px; vertical-align: baseline; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: transparent; color: rgb(51, 51, 51); font-family: Arial, sans-serif; "><br /></div><div style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 13px; vertical-align: baseline; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: transparent; color: rgb(51, 51, 51); font-family: Arial, sans-serif; "><br /></div><div style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; vertical-align: baseline; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: transparent; color: rgb(51, 51, 51); font-family: Arial, sans-serif; "><span style="line-height: 25px; "><b style="line-height: 25px; ">sessionStorage 、localStorage 和 cookie 之间的区别</b></span><br /></div><div style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 13px; vertical-align: baseline; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: transparent; color: rgb(51, 51, 51); font-family: Arial, sans-serif; ">共同点:都是保存在浏览器端,且同源的。</div><div style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 13px; vertical-align: baseline; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: transparent; color: rgb(51, 51, 51); font-family: Arial, sans-serif; ">区别:</div><div style="line-height: 20px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 13px; vertical-align: baseline; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: transparent; color: rgb(51, 51, 51); font-family: Arial, sans-serif; "><ol style="line-height: 20px; margin-top: 5px; margin-right: 0px; margin-bottom: 5px; margin-left: 40px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><li style="line-height: 22px; "><span style="line-height: 22px; ">cookie数据始终在同源的http请求中携带(即使不需要),即cookie在浏览器和服务器间来回传递。而sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存。cookie数据还有路径(path)的概念,可以限制cookie只属于某个路径下。</span></li><li style="line-height: 22px; "><span style="line-height: 22px; ">存储大小限制也不同,cookie数据不能超过4k,同时因为每次http请求都会携带cookie,所以cookie只适合保存很小的数据,如会话标识。sessionStorage和localStorage 虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大。</span></li><li style="line-height: 22px; "><span style="line-height: 22px; ">数据有效期不同,</span><span style="line-height: 22px; ">sessionStorage:仅在当前浏览器窗口关闭前有效,自然也就不可能持久保持;</span><span style="line-height: 22px; ">localStorage:始终有效,窗口或浏览器关闭也一直保存,因此用作持久数据;</span><span style="line-height: 22px; ">cookie只在设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭。</span></li><li style="line-height: 20px; "><span style="line-height: 22px; ">作用域不同,</span><span style="line-height: 22px; ">sessionStorage<b style="line-height: 20px; ">不在</b>不同的浏览器窗口中共享,即使是同一个页面;</span><span style="line-height: 22px; ">localStorage 在所有同源窗口中都是共享的;cookie也是在</span><span style="line-height: 22px; ">所有同源窗口中都是共享的。</span></li><li style="line-height: 20px; "><span style="line-height: 22px; "><span style="line-height: 22px; font-family: Arial, Helvetica, sans-serif; color: rgb(0, 0, 0); font-size: 14px; "><span style="line-height: 20px; "><span style="line-height: 20px; ">Web </span></span><span style="line-height: 20px; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: small; ">Storage 支持事件通知机制,可以将数据更新的通知发送给监听者。</span></span></span></li><li style="line-height: 20px; "><span style="line-height: 22px; "><span style="line-height: 22px; font-family: Arial, Helvetica, sans-serif; color: rgb(0, 0, 0); font-size: 14px; "><span style="line-height: 20px; "><span style="line-height: 20px; ">Web </span></span><span style="line-height: 20px; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: small; ">Storage </span></span>的 api 接口使用更方便。</span></li></ol></div><div style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 13px; vertical-align: baseline; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: transparent; color: rgb(51, 51, 51); font-family: Arial, sans-serif; "><br /></div><div style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 13px; vertical-align: baseline; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: transparent; color: rgb(51, 51, 51); font-family: Arial, sans-serif; "><span style="line-height: 25px; font-size: medium; "><b style="line-height: 25px; ">sessionStorage </b></span><span style="line-height: 25px; font-size: medium; "><b style="line-height: 25px; ">和 </b></span><span style="line-height: 25px; font-size: medium; "><b style="line-height: 25px; ">localStorage 之间的区别</b></span></div><div style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 13px; vertical-align: baseline; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: transparent; color: rgb(51, 51, 51); font-family: Arial, sans-serif; ">见上面的区别3、4</div><div style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 13px; vertical-align: baseline; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: transparent; color: rgb(51, 51, 51); font-family: Arial, sans-serif; "><br /></div><div style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; vertical-align: baseline; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: transparent; color: rgb(51, 51, 51); font-family: Arial, sans-serif; "><span style="line-height: 25px; "><b style="line-height: 25px; ">sessionStorage与页面 js 数据对象的区别</b></span><br /></div><div style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 13px; vertical-align: baseline; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: transparent; color: rgb(51, 51, 51); font-family: Arial, sans-serif; ">页面中一般的 js 对象或数据的生存期是仅在当前页面有效,因此刷新页面或转到另一页面这样的重新加载页面的情况,数据就不存在了。</div><div style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 13px; vertical-align: baseline; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: transparent; color: rgb(51, 51, 51); font-family: Arial, sans-serif; ">而sessionStorage 只要同源的同窗口(或tab)中,<span style="line-height: 22px; color: rgb(68, 68, 68); font-family: Arial, Helvetica, sans-serif; font-size: 14px; ">刷新页面或进入同源的不同页面,</span><span style="line-height: 20px; ">数据</span>始终存在。也就是说只要这个浏览器窗口没有关闭,加载新页面或重新加载,数据仍然存在。</div></span>hgkhttp://www.blogger.com/profile/18248256147814166844noreply@blogger.com0tag:blogger.com,1999:blog-3051279638784476121.post-14524055766783807422011-03-06T08:08:00.002-08:002011-03-06T08:09:00.549-08:00手机刷rom<span class="Apple-style-span" style="color: rgb(51, 51, 51); font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; line-height: 22px; "><span style="line-height: 20px; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 13px; ">今天手机不重启了!昨天一天我的 android 随机重启7-8回,说着说着话就关机了,晚上赶紧又刷了另一个rom,这才好了。这几天前后刷了4个rom,终于找到一个稳定好用的了。手机是09年买的,10年刷了一次但觉得有点慢,这次又刷了一次。</span><div style="line-height: 22px; "><span style="line-height: 20px; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 13px; "><br /></span></div><div style="line-height: 22px; "><span style="line-height: 20px; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 13px; "><span style="line-height: 20px; white-space: pre; "> </span>手机刷rom就类似于pc上装os,掌握了也不难,但肯定不是普通消费者都能掌握的。Android系统因为开放,所以百花齐放,人人都可以定制各种各样的rom,可以从内核、os版本、配置、软件包组合、个性化等多方面进行定制,就像linux一样。但问题也来了,首先是质量问题,因为稳定性永远第一,其它什么的都要在此基础上才行。但手机硬件型号多,系统版本多,软硬件的兼容性就是个问题。另外,单个人因为时间精力有限,条件有限,能力水平的差异等因素,很难进行充分的测试,没有能力保障质量。因此质量莠不齐,很多都有这样那样的问题。爱好者个人定制的rom和手机厂商官方的有一点是不同的——个人的rom不提供任何保障和服务,换句话说有问题别来找我,找我我也不一定给解决或有能力解决。</span></div><div style="line-height: 22px; "><span style="line-height: 20px; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 13px; "><span style="line-height: 20px; white-space: pre; "> </span>这么多rom,个性化要求倒是基本满足了。</span><span style="line-height: 20px; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 13px; ">其实很多人的rom只是在少数人做的rom基础上改改,做些个性化的定制。个性化的版本很多,但别人的个性化未必是你喜好的个性化,众口难调呀。因此,找自己满意的还是不太容易。</span></div><div style="line-height: 22px; "><span style="line-height: 20px; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 13px; "><br /></span></div><div style="line-height: 22px; "><span style="line-height: 20px; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 13px; "><span style="line-height: 20px; white-space: pre; "> </span>其实这些个人做的rom也不容易,他们大都是凭自己的兴趣和热情做的,要付出很多时间精力。</span></div><div style="line-height: 22px; "><span style="line-height: 20px; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 13px; "><span style="line-height: 20px; white-space: pre; "> </span>对于刷rom的人要做的就是从一堆声称“完美”的rom中找一个适合自己手机的、稳定的、性能好的、省电的、满足自己</span><span style="line-height: 20px; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 13px; ">基本</span><span style="line-height: 20px; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 13px; ">个性化需求的rom,要多刷几个才能找到合适的。</span></div></span>hgkhttp://www.blogger.com/profile/18248256147814166844noreply@blogger.com0tag:blogger.com,1999:blog-3051279638784476121.post-5153440302030547412011-03-06T08:08:00.001-08:002011-03-06T08:08:32.082-08:002011年春节小结<span class="Apple-style-span" style="color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 13px; line-height: 20px; "><div style="line-height: 20px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 13px; vertical-align: baseline; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: transparent; ">假期时间范围:2011.1.31-2.11,共12天。</div><div style="line-height: 20px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 13px; vertical-align: baseline; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: transparent; "><br /></div>看:《大兵小将》《非诚勿扰2》《攻壳机动队TV1》《古城荆棘王》《让子弹飞》<div style="line-height: 20px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 13px; vertical-align: baseline; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: transparent; ">玩:水立方嬉水乐园、植物园、游乐园庙会(小吃)、自然博物馆</div><div style="line-height: 20px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 13px; vertical-align: baseline; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: transparent; ">吃:“三十”全家、“初五”全家+二姨家、还有麦当劳1次<br /></div><div style="line-height: 20px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 13px; vertical-align: baseline; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: transparent; ">书:《微博改变一切》<br /></div><div style="line-height: 20px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 13px; vertical-align: baseline; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: transparent; ">健身:12天假,除了4天关门外都去了。三十前连着4天,初四开始连着6天。</div><div style="line-height: 20px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 13px; vertical-align: baseline; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: transparent; ">作息:从初一开始经常2、3点才睡,同时起得也晚,经常10点多以后才起。</div><div style="line-height: 20px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 13px; vertical-align: baseline; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: transparent; ">高中同学聚会一次。</div><div style="line-height: 20px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 13px; vertical-align: baseline; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: transparent; ">拜年短信:这次没主动发,只是“三十”当天回复了收到的短信,初一收到的短信没回(懒得会了)。<br /></div><div style="line-height: 20px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 13px; vertical-align: baseline; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: transparent; ">给压岁钱:100×2</div><div style="line-height: 20px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 13px; vertical-align: baseline; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: transparent; ">iPad:热力追踪车手模式(才发现,之前通了警察模式)、QQ象棋(初级电脑对战)</div><div style="line-height: 20px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 13px; vertical-align: baseline; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: transparent; ">手机刷rom一天<br /></div><div style="line-height: 20px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 13px; vertical-align: baseline; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: transparent; ">初雪:2月10号,北京今年第一场初雪。</div><div style="line-height: 20px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 13px; vertical-align: baseline; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: transparent; "><br /></div><div style="line-height: 20px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 13px; vertical-align: baseline; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: transparent; ">整体感觉:前面几天比较充实,最后几天比较无聊。</div></span>hgkhttp://www.blogger.com/profile/18248256147814166844noreply@blogger.com0tag:blogger.com,1999:blog-3051279638784476121.post-84136197697406800092010-12-20T02:19:00.001-08:002010-12-20T02:19:59.475-08:00国内搜索引擎提交网站入口<span class="Apple-style-span" style="color: rgb(51, 51, 51); font-family: Arial, Helvetica, sans-serif; font-size: 14px; line-height: 22px; "><div style="line-height: 22px; ">新域名、新网站还没被搜索引擎收录,那就主动提交一下网址吧。常用的各大搜索引擎都有提交网站的入口:</div><div style="line-height: 22px; "><br /></div><div style="line-height: 22px; "><span style="line-height: 20px; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 13px; ">谷歌(Google) : <a href="http://www.google.com/addurl/?hl=zh-CN&continue=/addurl" style="line-height: 20px; text-decoration: none; color: rgb(60, 145, 13); margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 13px; vertical-align: baseline; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: transparent; ">http://www.google.com/addurl/?hl=zh-CN&continue=/addurl</a><div style="line-height: 20px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 13px; vertical-align: baseline; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: transparent; ">百度(Baidu): <a href="http://www.baidu.com/search/url_submit.html" style="line-height: 20px; text-decoration: none; color: rgb(60, 145, 13); margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 13px; vertical-align: baseline; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: transparent; ">http://www.baidu.com/search/url_submit.html</a></div><div style="line-height: 20px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 13px; vertical-align: baseline; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: transparent; ">搜搜(soso) :<a href="http://www.soso.com/help/usb/urlsubmit.shtml" style="line-height: 20px; text-decoration: none; color: rgb(60, 145, 13); margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 13px; vertical-align: baseline; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: transparent; ">http://www.soso.com/help/usb/urlsubmit.shtml</a></div><div style="line-height: 20px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 13px; vertical-align: baseline; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: transparent; ">有道(youdao) : <a href="http://tellbot.youdao.com/report" style="line-height: 20px; text-decoration: none; color: rgb(60, 145, 13); margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 13px; vertical-align: baseline; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: transparent; ">http://tellbot.youdao.com/report</a></div><div style="line-height: 20px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 13px; vertical-align: baseline; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: transparent; ">搜狗(Sogou): <a href="http://www.sogou.com/feedback/urlfeedback.php" style="line-height: 20px; text-decoration: none; color: rgb(60, 145, 13); margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 13px; vertical-align: baseline; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: transparent; ">http://www.sogou.com/feedback/urlfeedback.php</a></div><div style="line-height: 20px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 13px; vertical-align: baseline; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: transparent; ">雅虎(Yahoo!) : <a href="http://search.help.cn.yahoo.com/h4_4.html" style="line-height: 20px; text-decoration: none; color: rgb(60, 145, 13); margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 13px; vertical-align: baseline; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: transparent; ">http://search.help.cn.yahoo.com/h4_4.html</a></div><div style="line-height: 20px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 13px; vertical-align: baseline; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: transparent; ">必应(Bing) : <a href="http://www.bing.com/webmaster/SubmitSitePage.aspx?mkt=zh-CN" style="line-height: 20px; text-decoration: none; color: rgb(60, 145, 13); margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 13px; vertical-align: baseline; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: transparent; ">http://www.bing.com/webmaster/SubmitSitePage.aspx?mkt=zh-CN</a></div><div style="line-height: 20px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 13px; vertical-align: baseline; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: transparent; "><br /></div><div style="line-height: 20px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 13px; vertical-align: baseline; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: transparent; ">新网站被收录的速度都比较慢,不同搜索引擎收录更新的快慢也差很多。</div></span></div></span>hgkhttp://www.blogger.com/profile/18248256147814166844noreply@blogger.com0tag:blogger.com,1999:blog-3051279638784476121.post-6355459776861210852010-12-05T07:37:00.000-08:002010-12-05T07:39:19.676-08:00Java捕获系统全局的键盘事件<span class="Apple-style-span" style="font-family: arial, sans-serif; font-size: 13px; border-collapse: collapse; color: rgb(51, 51, 51); line-height: 20px; "><div style="line-height: normal; ">我们常用的QQ、MSN程序有一个<b style="line-height: 20px; "><span style="line-height: normal; font-weight: normal; ">Idle功能,也就是当用户一段时间没有任何鼠标、<wbr style="line-height: 20px; ">键盘事件的时候自动把用户状态设为离开,<wbr style="line-height: 20px; ">有事件的时候自动设为在线。</span></b></div><div style="line-height: normal; "><b style="line-height: 20px; "><span style="line-height: normal; font-weight: normal; "><br /></span></b></div><div style="line-height: normal; "><b style="line-height: 20px; "><span style="line-height: normal; font-weight: normal; ">鼠标可以通过 MouseInfo.getPointerInfo() 得到当前的鼠标位置,判断鼠标的位置有没有变化。</span></b></div><div style="line-height: normal; "><span style="line-height: 20px; "><b style="line-height: 20px; "><span style="line-height: normal; font-weight: normal; "><br /></span></b></span></div><div style="line-height: normal; "><span style="line-height: 20px; "><b style="line-height: 20px; "><span style="line-height: normal; font-weight: normal; ">那么Java如何捕获系统全局的键盘事件呢?</span></b></span></div><div style="line-height: normal; "><span style="line-height: 20px; "><b style="line-height: 20px; "><span style="line-height: normal; font-weight: normal; "><br /></span></b></span></div><div style="line-height: normal; "><span style="line-height: 20px; "><b style="line-height: 20px; "><span style="line-height: normal; font-weight: normal; "><br /></span></b></span></div><div style="line-height: 20px; "><span style="line-height: normal; ">1. Java可以捕获自身GUI中某个组件上或全局的整个java程序上发<wbr style="line-height: 20px; ">生的键盘事件。</span></div><div style="line-height: normal; "><br /></div><div style="line-height: normal; "><br /></div><div style="line-height: normal; ">捕获整个java程序上发生的键盘事件:</div><div style="line-height: normal; ">方法一:Toolkit.getDefaultToolkit(<wbr style="line-height: 20px; ">).addAWTEventListener( listener, eventMask) </div><div style="line-height: normal; ">listener是回调函数</div><div style="line-height: normal; ">eventMask是要关注的事件,如果只关注键盘事件,填 AWTEvent.KEY_EVENT_MASK 就可以</div><div style="line-height: normal; "><br /></div><div style="line-height: normal; "><br /></div><div style="line-height: normal; ">方法二:替换默认实现的EventQueue(事件队列),覆盖<span style="line-height: 20px; ">dispatchEvent方法,</span>增加键盘处理。</div><div style="line-height: normal; "><div style="line-height: 20px; "><span style="line-height: 20px; white-space: pre-wrap; "> </span>EventQueue e = Toolkit.getDefaultToolkit().<wbr style="line-height: 20px; ">getSystemEventQueue();</div><div style="line-height: 20px; "> e.push(new EventQueue() {</div><div style="line-height: 20px; "> @Override</div><div style="line-height: 20px; "> protected void dispatchEvent(AWTEvent event) {</div><div style="line-height: 20px; "> if (event instanceof KeyEvent) {</div><div style="line-height: 20px; "> // do your code </div><div style="line-height: 20px; "><span style="line-height: 20px; white-space: pre-wrap; "> </span> }</div><div style="line-height: 20px; "><span style="line-height: 20px; white-space: pre-wrap; "> </span> super.dispatchEvent(event);</div><div style="line-height: 20px; "><span style="line-height: 20px; white-space: pre-wrap; "> </span>}</div><div style="line-height: 20px; "><span style="line-height: 20px; white-space: pre-wrap; "> </span> });</div></div><div style="line-height: normal; "><br /></div><div style="line-height: normal; ">如果Java程序处于当前操作系统的焦点,就<wbr style="line-height: 20px; ">可以捕获到所有键盘事件。</div><div style="line-height: normal; "><br /></div><div style="line-height: normal; "><br /></div><div style="line-height: normal; ">2. 但是<span style="line-height: 20px; font-family: Helvetica, Arial, sans-serif; font-size: 13px; color: rgb(54, 43, 54); "><b style="line-height: 20px; ">Java本身是无法捕获Java之外的键盘事<wbr style="line-height: 20px; ">件的</b>,也就是你无法知道在其它程序上发出的键盘事件。没办法,<wbr style="line-height: 20px; ">Java的设计就是这样。在一般的受管环境下,如 .net 一般也<wbr style="line-height: 20px; ">是只能捕获自己的键盘事件,而不是系统全局的hook,<wbr style="line-height: 20px; ">不过网上倒是有一篇文章介绍使用C#捕获全局系统键盘的办法。</span></div><div style="line-height: normal; "><span style="line-height: 20px; font-family: Helvetica, Arial, sans-serif; font-size: 13px; color: rgb(54, 43, 54); "><br /></span></div><div style="line-height: normal; "><span style="line-height: 20px; font-family: Helvetica, Arial, sans-serif; font-size: 13px; color: rgb(54, 43, 54); "><br /></span></div><div style="line-height: normal; "><span style="line-height: 20px; font-family: Helvetica, Arial, sans-serif; font-size: 13px; color: rgb(54, 43, 54); ">唯一的办法就是使用native的方式捕获系统底层的键盘事件。<wbr style="line-height: 20px; ">当然这是Java不鼓励的,也不能跨平台。</span></div><div style="line-height: normal; "><span style="line-height: 20px; font-family: Helvetica, Arial, sans-serif; font-size: 13px; color: rgb(54, 43, 54); ">使用 JNA (Java Native Access, <a href="https://jna.dev.java.net/" target="_blank" style="line-height: 20px; text-decoration: none; color: rgb(42, 93, 176); ">https://jna.dev.java.net/</a> )可以实现这点,<wbr style="line-height: 20px; ">按照其示例实现一个LowLevelKeyboardProc 的hook安装到系统来捕获底层的键盘事件。</span></div></span>hgkhttp://www.blogger.com/profile/18248256147814166844noreply@blogger.com0tag:blogger.com,1999:blog-3051279638784476121.post-25758109182108239992010-12-05T07:18:00.000-08:002010-12-05T07:19:07.986-08:00Java为什么会死<span class="Apple-style-span" style="font-family: arial, sans-serif; font-size: 13px; border-collapse: collapse; color: rgb(51, 51, 51); line-height: 20px; "><div style="line-height: 20px; ">我承认有点标题党,准确的说应该是“Java程序为什么会退出”,自己随便总结几条,欢迎大家补充。</div><ul style="line-height: 20px; margin-top: 5px; margin-right: 0px; margin-bottom: 5px; margin-left: 40px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><li style="line-height: 20px; ">调用了System.exit</li><li style="line-height: 20px; ">所有非后台线程运行结束或异常退出</li><li style="line-height: 20px; ">线程内有没有捕获的异常,抛到了最外层,线程推出。<wbr style="line-height: 20px; ">如一个简单的main程序,出现一个未捕获的异常,程序就退了。<wbr style="line-height: 20px; ">但在GUI程序中一般不会,因为窗口线程总在。</li><li style="line-height: 20px; ">遇到各种致命error,内存方面问题常见的是 OutOfMemoryError,影响整个jvm,导致退出。</li><li style="line-height: 20px; ">无线递归导致线程堆栈溢出 StackOverflowError ,只影响该线程。</li><li style="line-height: 20px; ">界面死锁,程序没反应。程序没有退出,但这时也只能kill掉了</li></ul></span>hgkhttp://www.blogger.com/profile/18248256147814166844noreply@blogger.com0tag:blogger.com,1999:blog-3051279638784476121.post-45014394809812290542010-11-29T06:30:00.001-08:002010-11-29T06:32:55.853-08:00聪明是难以验证的<span class="Apple-style-span"><span class="Apple-style-span" style="line-height: 25px; white-space: pre;"><span class="Apple-style-span" style="white-space: normal; "><span class="Apple-tab-span" style="white-space:pre"> </span>聪明是难以验证的。你说你跑得快,那好跑一个我看看,恩,百米在11秒以内,果然很快。你说你聪明,聪明一个我看看......<div style="line-height: 25px; "><span style="line-height: 25px; white-space: pre; "> <span class="Apple-tab-span" style="white-space:pre"> </span></span>聪明、能力强,自己说不算,人人都觉得自己聪明、有能力,很少有人觉得自己不聪明的。简历上写的一切在被验证之前,都是无法确认的,不能信以为真。</div><div style="line-height: 25px; "><span style="line-height: 25px; white-space: pre; "> <span class="Apple-tab-span" style="white-space:pre"> </span></span>但是,像聪明这类的东西是难以验证的,具有很强的主观性,不同的人有不同的看法。这类东西是没有绝对的、唯一的、正确的方法判断,是带有主观性的,不同的人想出不同的招进行测试。有些办法可以达到很好的测试效果,但也不是说不满足的就一定不成。</div><div style="line-height: 25px; "><span class="Apple-tab-span" style="white-space:pre"> </span>单位要招人、学校要择优录取。</div><div style="line-height: 25px; "><span class="Apple-tab-span" style="white-space:pre"> </span>筛选还有一个成本问题,要在一定的成本下完成,因此很难做到理想化。比如,为什么大企业只去名校做校园招聘,为什么非要本科以上学历,为什么非要相关专业出身。当然,非名校也有人才,没学历也有能力强的,不是专业出身也有做得好的。但是筛选方的时间精力也是有限的,这是很现实的问题。</div><div style="line-height: 25px; "><span class="Apple-tab-span" style="white-space:pre"> </span>反过来,从结果上看也具有偶然性,这里不认可你不一定说明你真的不成。</div><div style="line-height: 25px; "><span class="Apple-tab-span" style="white-space:pre"> </span>招人和找对象差不多,哪个更难?</div><div style="line-height: 25px; "><span class="Apple-tab-span" style="white-space:pre"> </span>很多时候,我们就是面临着这样的问题,在根本没有正确答案的情况下,做出选择和判断。</div></span></span></span>hgkhttp://www.blogger.com/profile/18248256147814166844noreply@blogger.com0tag:blogger.com,1999:blog-3051279638784476121.post-39383045667066554282010-10-15T05:58:00.001-07:002010-10-15T06:00:59.465-07:00利用flash实现Web中的特殊功能<span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif; font-size: 14px; line-height: 22px; "><div style="line-height: 24px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; background-color: transparent; font-size: 11pt; text-indent: 0px; margin-left: 0px; "><span class="Apple-style-span" style="white-space: pre-wrap;"><span class="Apple-style-span" style="line-height: 22px; white-space: normal; font-size: 14px; color: rgb(51, 51, 51); "><div style="line-height: 24px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; background-color: transparent; font-size: 11pt; text-indent: 0px; margin-left: 0px; "><span style="line-height: normal; font-size: 11pt; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "><span style="line-height: 24px; ">本文阅读对象是(我这样的)flash技术门外汉。</span></span><span style="line-height: 24px; "><br /><span style="line-height: 28px; "><span style="line-height: normal; font-size: 11pt; background-color: transparent; "><span style="line-height: 24px; font-size: 11pt; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "></span></span></span><br /></span></div><div style="line-height: 24px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; background-color: transparent; font-size: 11pt; text-indent: 0px; margin-left: 0px; "><span style="line-height: 24px; ">Web中有些功能看似很神奇,因为这些是难以用标准web技术实现的,其实是用flash实现的。我项目中最近的两个小功能用到了flash,分享一下。</span></div><div style="line-height: 24px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; background-color: transparent; font-size: 11pt; text-indent: 0px; margin-left: 0px; "><span style="line-height: 24px; "><br /><span style="line-height: normal; font-size: 11pt; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; ">flash 本质上不是web标准技术,而是系统上独立于浏览器之外的第三方插件程序(由Adobe公司提供)。</span><br /><span style="line-height: normal; font-size: 11pt; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; ">但因为其普及率非常之高, flash又是“事实上”web技术的一部分,是事实标准。</span><br /><span style="line-height: 28px; "><span style="line-height: normal; font-size: 11pt; background-color: transparent; "><span style="line-height: 24px; font-size: 11pt; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "></span></span></span><br /><span style="line-height: normal; font-size: 11pt; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; ">用它可以实现一些看似浏览器不支持的事情,另一个好处是跨浏览器、跨平台。</span><br /><span style="line-height: 28px; "><span style="line-height: normal; font-size: 11pt; background-color: transparent; "><span style="line-height: 24px; font-size: 11pt; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "></span></span></span><br /><span style="line-height: normal; font-size: 11pt; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "><b style="line-height: 24px; ">一、将web上的内容复制到系统剪切板</b></span></span></div><div style="line-height: 24px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; background-color: transparent; font-size: 11pt; text-indent: 0px; margin-left: 0px; "><span style="line-height: 24px; "><span style="line-height: normal; font-size: 11pt; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "><br /></span></span></div><div style="line-height: 24px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; background-color: transparent; font-size: 11pt; text-indent: 0px; margin-left: 0px; "><span style="line-height: 24px; "><span style="line-height: normal; font-size: 11pt; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; ">出于安全原因,有些浏览器不支持复制到剪切板,IE虽然可以,但也会给出个警告。前几天, 我用 </span><a href="http://co%3Cwbr%3Ede.google.com/p/zeroclipboard/" style="line-height: normal; text-decoration: none; color: rgb(60, 145, 13); "><span style="line-height: 24px; font-size: 11pt; color: rgb(0, 0, 153); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap; ">zeroclipboard</span></a><span style="line-height: normal; font-size: 11pt; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "> 实现了这个功能,zeroclipboard就是使用flash技术实现了在浏览器上复制javas<wbr style="line-height: 24px; ">cript提供的内容到系统剪切板上。正因为用的是flash,所以这个实现就可以跨浏览器、跨平台。核心api:System.setClipboard() ,当然因为安全原因,flash只能set剪切板内容,不能get剪切板内容。</span><br /><span style="line-height: 28px; "><span style="line-height: normal; font-size: 11pt; background-color: transparent; "><span style="line-height: 24px; font-size: 11pt; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "></span></span></span><br /><span style="line-height: 28px; "><span style="line-height: normal; font-size: 11pt; background-color: transparent; "><span style="line-height: 24px; font-size: 11pt; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "></span></span></span><br /><span style="line-height: normal; font-size: 11pt; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "><b style="line-height: 24px; ">二、熟客识别——使用flash本地存储替代cookie,清除cookie也没用</b></span></span></div><div style="line-height: 24px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; background-color: transparent; font-size: 11pt; text-indent: 0px; margin-left: 0px; "><span style="line-height: 24px; "><span style="line-height: 24px; font-size: 11pt; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; "></span><span style="line-height: normal; white-space: pre-wrap; "><br /></span><span style="line-height: normal; font-size: 11pt; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; ">在用户不登录验证的情况下,想识别出对方,基本的办法是在对方的电脑上加个用户标识,以此来识别。否则没人知道电脑面前坐的是一只狗。最常见的方法是利用存储在本地的cookie,这是标准技术,已经可以满足一般需求。当然用户清空浏览器cookie或使用别的浏览器cookie就没了。比如浏览器的隐私浏览模式中就不保存cookie(关闭窗口时清掉)。</span><br /><span style="line-height: 28px; "><span style="line-height: normal; font-size: 11pt; background-color: transparent; "><span style="line-height: 24px; font-size: 11pt; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "></span></span></span><br /><span style="line-height: normal; font-size: 11pt; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; ">flash也有本地存储功能,类似于cookie的技术,因此可以替代cookie完成同样的事。国内的很多在线客服产品都使用这种技术。打着所谓的“国际/国内领先技术”,描述只说是“非cookie技术,清空cookie也能识别”,但不说是什么技术,因为说了就不灵了。</span><br /><span style="line-height: 28px; "><span style="line-height: normal; font-size: 11pt; background-color: transparent; "><span style="line-height: 24px; font-size: 11pt; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "></span></span></span><br /><span style="line-height: normal; font-size: 11pt; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; ">既然技术上都是类似的,flash之所以比cookie更有效的</span><span style="line-height: normal; font-size: 11pt; color: rgb(0, 0, 0); background-color: transparent; font-weight: bold; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; ">关键在于多数网民不知道flash有本地存储、不知道可以清空flash本地存储</span><span style="line-height: normal; font-size: 11pt; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; ">。清除浏览器数据的时候是不会清除flash数据的,因为flash不受浏览器控制。这也要怪adobe公司没有在显眼的地方告诉用户,这可是用户的隐私呀。</span><br /><span style="line-height: 28px; "><span style="line-height: normal; font-size: 11pt; background-color: transparent; "><span style="line-height: 24px; font-size: 11pt; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "></span></span></span><br /><span style="line-height: normal; font-size: 11pt; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; ">用户实际上可以自己设置flash本地存储策略,在这里还可以清理flash本地存储:</span><a href="http://www.macromedia.com/support/documentation/cn/flashplayer/help/settings_manager07.html" style="line-height: normal; text-decoration: none; color: rgb(60, 145, 13); "><span style="line-height: 24px; font-size: 11pt; color: rgb(0, 0, 153); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap; ">http://www.macromedia.com/support/documentation/cn/flashplayer/help/settings_manager07.html</span></a></span></div></span></span></div></span>hgkhttp://www.blogger.com/profile/18248256147814166844noreply@blogger.com0tag:blogger.com,1999:blog-3051279638784476121.post-73476906744031057502010-08-16T10:24:00.001-07:002010-08-16T10:33:28.204-07:00正确地对待bug的逻辑和态度<span class="Apple-style-span" style="font-family: Arial; font-size: 15px; color: rgb(51, 51, 51); line-height: 24px; white-space: pre-wrap; "><div style="line-height: normal; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; background-color: transparent; font-size: 11pt; text-indent: 0px; margin-left: 0px; font-family: Simsun; white-space: normal; "><span style="line-height: 24px; "><span style="line-height: 24px; white-space: pre-wrap; ">刚看了李笑来老师写的<a href="http://www.lixiaolai.com/index.php/archives/9883.html" target="_blank" style="line-height: 24px; text-decoration: none; color: rgb(60, 145, 13); ">《关于举证责任》的系列短文</a>,又联想到平时程序员在开发中常见的错误认识,结合自己的经验写一些总结。</span></span></div><div style="line-height: normal; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; background-color: transparent; font-size: 11pt; text-indent: 0px; margin-left: 0px; font-family: Simsun; white-space: normal; "><span id="internal-source-marker_0.14325316925533116" style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; ">以下内容不是讲调试和分析问题的技巧,而遇到bug时正确地对待问题的逻辑和态度。</span><ul style="line-height: 24px; margin-top: 5px; margin-right: 0px; margin-bottom: 5px; margin-left: 40px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><li style="line-height: 24px; list-style-type: disc; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; "><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; ">你写了一堆代码,不能因为别人没有证明你的代码有错误而认为自己的代码没有错误。</span></li><li style="line-height: 24px; list-style-type: disc; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; "><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; ">自己要尽可能证明自己的代码没错误,这不是别人的责任。</span></li><li style="line-height: 24px; list-style-type: disc; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; "><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; ">别人证明你的代码有错误的难度是很大的</span></li><ul style="line-height: 24px; margin-top: 5px; margin-right: 0px; margin-bottom: 5px; margin-left: 40px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><li style="line-height: 24px; list-style-type: circle; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; "><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; ">因为证明本身难度就很大,1000行的代码中有多少个可能的状态、条件变量有多少、它们之间的组合又有多少。</span></li><li style="line-height: 24px; list-style-type: circle; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; "><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; ">多线程的偶然现象很难手工复现,往往需要编程来主动创造那种特殊的条件下才行,而这需要对复杂的代码有相当深入的整体和细节的掌握后才能做到。</span></li><li style="line-height: 24px; list-style-type: circle; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; "><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; ">别人可能对你的代码实现一无所知,别人只是使用中发现了问题而已。</span></li><li style="line-height: 24px; list-style-type: circle; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; "><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; ">出现问题后,如何复现问题往往很难。找到问题发生的条件,就像在一个巨大的状态空间中找到其中一点一样,可能需要做大量的实验。</span></li></ul><li style="line-height: 24px; list-style-type: disc; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; "><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; ">出现问题了就说明确实存在问题,只是还不清楚问题来自哪里,什么条件下发生的。不能因为没有找到复现问题的办法,而认为那个问题不存在。</span></li><li style="line-height: 24px; list-style-type: disc; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; "><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; ">想办法复现问题、分析问题可能的情况(假设+求证)</span><span style="line-height: 24px; white-space: pre-wrap; ">、定位问题、找到问题,这个过程往往是最费时间精力的事情。解决问题的主要工作量就在这里,而不是解决本身。</span></li><li style="line-height: 24px; list-style-type: disc; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; "><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; ">找到问题后,解决问题往往很简单,可能就是1、2分钟的事情,甚至就是在找到问题的同时就解决完了。</span></li><li style="line-height: 24px; list-style-type: disc; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; "><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; ">分析问题或证明问题不存在的责任在于程序的实现者,而不在于发现问题的人(尤其是普通用户)。</span></li><li style="line-height: 24px; list-style-type: disc; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; "><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; ">发现问题的人最好能提供更多信息、最好能够说明问题复现方法、甚至最好能说明问题出在哪(但这个不太现实)。但反之,不能因为发现问题的人无法做到这些而否定问题。更不能要求别人把这个问题找到并且解决了,才承认有这个问题。</span></li><li style="line-height: 24px; list-style-type: disc; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; "><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; ">最终找到的问题点可能离问题的表象很远,这也说明找到问题是不太容易的,也容易让人难于判断问题出在谁那里。</span></li><li style="line-height: 24px; list-style-type: disc; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; "><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; ">做前端的人,往往首先承受了所有的问题,尽管问题很可能不在前端。因为程序的所有交互都要从前端进行,用户也只能看到前端的东西而看不到后台的东西。所以前端工程师往往要证明问题不是出在他这里,但也很难说出问题出在哪里,这等于要他来解决问题。</span></li><li style="line-height: 24px; list-style-type: disc; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; "><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; ">问题最终可能不是出在你负责的这里,而是别的地方。</span></li><li style="line-height: 24px; list-style-type: disc; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; "><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; ">程序员不应该推卸问题,尽管可能不是你的问题,但每个人都要积极的想协助解决问题。因为解决问题是整个团队的共同目标。</span></li><li style="line-height: 24px; list-style-type: disc; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; "><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; ">自己写的简单测试没问题,并不能证明代码都没问题。因为测试代码只是证明给定那几个测试条件、数据下的结果是对的,既没有完整的覆盖所有情况(其它情况下是不是对的还不知道),也不能证明实现的过程是对的(结果对不一定过程对,可能碰巧、可能测试条件没有触发问题点)。</span></li><li style="line-height: 24px; list-style-type: disc; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; "><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; ">代码测试覆盖率,你的测试覆盖了多少代码?如果非常低,那么隐藏问题的可能性很大;很高的覆盖率也很难做到,而且工作量很大。</span></li><li style="line-height: 24px; list-style-type: disc; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; "><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "></span><span class="Apple-style-span" style="line-height: normal; white-space: pre-wrap; ">当你能够主动想到问题,而不是由别人告诉你哪里有问题的时候,你就已经提高一大截了。</span></li></ul></div></span>hgkhttp://www.blogger.com/profile/18248256147814166844noreply@blogger.com0tag:blogger.com,1999:blog-3051279638784476121.post-62355873098750762562010-08-11T08:33:00.000-07:002010-08-11T08:35:23.537-07:00ExtJs 加载优化<span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif; font-size: 14px; color: rgb(51, 51, 51); line-height: 22px; ">ExtJS 是个功能丰富、强大的 javascript 库,适合做一些富客户端界面。但是其庞大的体积会导致网页加载时间长,给人很慢的感觉。</span><div><span class="Apple-style-span" style="font-family:Arial, Helvetica, sans-serif;font-size:130%;color:#333333;"><span class="Apple-style-span" style="font-size: 14px; line-height: 22px;"><br /></span></span><div><span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif; font-size: 14px; color: rgb(51, 51, 51); line-height: 22px; "><div style="line-height: 22px; "><div style="line-height: 22px; ">为了找到网页加载慢的真正原因,首先你应该用 YSlow 这样的工具仔细分析一下,看看到底是哪些方面导致的。ExtJS可能只是其中的一个原因,也许还有别的地方影响了加载速度。下面只谈谈如何解决 ExtJs 加载慢的问题。</div><div style="line-height: 22px; "><br /></div><div style="line-height: 22px; "><div style="line-height: 22px; ">就像任何软件一样,功能越多就会体积越大,这个在所难免。</div><div style="line-height: 22px; ">对于ExtJs,最简单的<b style="line-height: 22px; ">傻瓜式</b>使用方法就是在页面中引入这三个文件:</div><div style="line-height: 22px; "><span style="line-height: 22px; color:#0000FF;">ext-all.css(138K)、ext-base.js(32K)、ext-all.js(635K)</span>,</div><div style="line-height: 22px; ">另外js文件还有对应的debug版:<span style="line-height: 22px; color:#0000FF;">ext-base-debug.js(78K)、ext-all-debug.js(1.13M)</span></div><div style="line-height: 22px; ">这仅仅是ExtJS,你的页面中肯定还有很多其它东西,加在一起可就不小了。按照一般的网速,下载这些东西就要等半天了。</div><div style="line-height: 22px; "><br /></div><div style="line-height: 22px; "><b style="line-height: 22px; "><span style="line-height: 25px; font-size: medium; ">1.</span></b><span style="line-height: 24px; font-family: Arial; white-space: pre-wrap; "><b style="line-height: 22px; "><span style="line-height: 25px; font-size: medium; ">不要使用</span></b></span><span style="line-height: 24px; font-family: Arial; white-space: pre-wrap; "><b style="line-height: 22px; "><span style="line-height: 25px; font-size: medium; ">debug的js文件(体积缩小1/2)</span></b></span></div><div style="line-height: 22px; "><span style="line-height: 28px; font-family:Arial;font-size:130%;"><span style="line-height: 24px; font-size: 15px; white-space: pre-wrap; ">debug版的js和非debug版的js完全一样,只是没有压缩而已,但体积大了一倍,</span></span>ext-all-debug.js达到1.13M!</div><div style="line-height: 22px; "><span style="line-height: 24px; font-family: Arial; font-size: 15px; white-space: pre-wrap; ">所以,不要使用debug的,除非你需要做相关调试。就算要调试,那也只是在开发的时候,别忘了换回去。</span></div><div style="line-height: 22px; "><span style="line-height: 24px; font-family: Arial; font-size: 15px; white-space: pre-wrap; "><br /></span></div><div style="line-height: 22px; "><span style="line-height: 24px; font-family: Arial; white-space: pre-wrap; "><b style="line-height: 22px; "><span style="line-height: 25px; font-size: medium; ">2.自定义裁减 extjs(体积进一步缩小几分之一)</span></b></span></div><div style="line-height: 22px; "><span style="line-height: 24px; font-family: Arial; font-size: 15px; white-space: pre-wrap; ">extjs 功能众多,但大多数人只用到其中的少数功能。傻瓜式的方式只是在开发时简单,正是环境</span><span style="line-height: 24px; font-family: Arial; font-size: 15px; white-space: pre-wrap; ">应该<b style="line-height: 24px; ">用多少使多少</b>,</span><span style="line-height: normal; font-family: Simsun; font-size: medium; "><span id="internal-source-marker_0.06131101679056883" style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; ">定制一份自己用到的部分,这样可以小很多。extjs也是模块化实现的,在其网站上可以</span><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; ">自定义一份:</span><a href="http://www.sencha.com/products/js/build/" style="line-height: 25px; text-decoration: none; color: rgb(60, 145, 13); "><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 153); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap; ">http://www.sencha.com/products/js/build/</span></a></span></div><div style="line-height: 22px; "><span style="line-height: 28px; font-family:Arial;font-size:130%;"><span style="line-height: 24px; font-size: 15px; white-space: pre-wrap; "><br /></span></span></div><div style="line-height: 22px; "><span style="line-height: 24px; font-family: Arial; white-space: pre-wrap; "><span style="line-height: 25px; font-size: medium; "><b style="line-height: 25px; ">3.启用</b></span></span><span style="line-height: 24px; font-family: Arial; white-space: pre-wrap; "><span style="line-height: 25px; font-size: medium; "><b style="line-height: 25px; ">gzip压缩</b></span></span><span style="line-height: 24px; font-family: Arial; white-space: pre-wrap; "><span style="line-height: 25px; font-size: medium; "><b style="line-height: 25px; ">(体积又缩小了几分之一)</b></span></span></div><div style="line-height: 22px; "><span style="line-height: 24px; font-family: Arial; font-size: 15px; white-space: pre-wrap; ">这个很重要。一般web服务器都支持gzip压缩,gzip压缩对于文本类型的文件都有很好的压缩效果。<b style="line-height: 24px; ">比如 635K 的 ext-all.js 经过gzip压缩后只有 168K</b>,太棒了!</span></div><div style="line-height: 22px; "><span style="line-height: 24px; font-family: Arial; font-size: 15px; white-space: pre-wrap; ">apache、nginx等服务器均支持gzip压缩,建议配置一下对所有超过2k的 js、css 文件启用gzip压缩。除了web服务器,像tomcat、jetty这样的应用服务器也都支持gzip压缩。具体查看配置文档就知道了,很简单的。</span></div><div style="line-height: 22px; "><span style="line-height: 24px; font-family: Arial; font-size: 15px; white-space: pre-wrap; "><br /></span></div><div style="line-height: 22px; "><span style="line-height: 24px; font-family: Arial; font-size: 15px; white-space: pre-wrap; "></span><span style="line-height: 24px; font-family: Arial; font-size: 15px; white-space: pre-wrap; ">提示:建议使用 <i style="line-height: 24px; ">静态gzip压缩</i> 或者叫 <i style="line-height: 24px; ">预压缩静态内容</i>,因为server在运行时进行压缩要消耗一定的cpu资源,而对于js这些静态内容而言完全可以预先压缩好,</span><span style="line-height: 24px; font-family: Arial; font-size: 15px; white-space: pre-wrap; ">如果有以 .gz 结尾的同名文件,</span><span style="line-height: 24px; font-family: Arial; font-size: 15px; white-space: pre-wrap; ">server直接返回压缩好的内容即可,这样减轻一些服务器的负担。</span></div><div style="line-height: 22px; "><span style="line-height: 24px; font-family: Arial; font-size: 15px; white-space: pre-wrap; ">Nginx和jetty都支持静态压缩,分别见这里 </span><a href="http://wiki.nginx.org/NginxHttpGzipStaticModule" style="line-height: 22px; text-decoration: none; color: rgb(60, 145, 13); ">http://wiki.nginx.org/NginxHttpGzipStaticModule</a> 和 <a href="http://wiki.eclipse.org/Jetty/Feature/GZIP_Compression" style="line-height: 22px; text-decoration: none; color: rgb(60, 145, 13); ">http://wiki.eclipse.org/Jetty/Feature/GZIP_Compression</a> 。</div><div style="line-height: 22px; ">常见的后台组合是动内容和静态内容分离,然后让Web服务器处理所有的静态资源,应用服务器专心处理动态内容。</div><div style="line-height: 22px; ">中小型应用也可以只用tomcat这样的应用服务器(简单一些),如果JavaEE的servlet容器不支持静态压缩,可以编写一个filter来实现同样的压缩或缓存效果。</div><div style="line-height: 22px; ">话说多了,这方面都属于性能优化了。</div><div style="line-height: 22px; "><span style="line-height: 24px; font-family: Arial; font-size: 15px; white-space: pre-wrap; "><br /></span></div><div style="line-height: 22px; "><span style="line-height: 24px; font-family: Arial; font-size: 15px; white-space: pre-wrap; ">最后,别忘了利用客户端浏览器上的缓存,下载一次就可以了,以后全部使用本地缓存。主要适用于用户会多次访问的情况。</span></div><div style="line-height: 22px; "><span style="line-height: 24px; font-family: Arial; font-size: 15px; white-space: pre-wrap; "><br /></span></div><div style="line-height: 22px; "><span style="line-height: 28px; font-family:Arial;font-size:130%;"><span style="line-height: 24px; font-size: 15px; white-space: pre-wrap; ">网上还有人说使用<a href="http://www.xidea.org/project/jsa/" target="_blank" style="line-height: 24px; text-decoration: none; color: rgb(60, 145, 13); ">JSA</a>这样的 javascript 脚本压缩、混淆工具还可以进一步缩小体积,实际上非debug的js已经是经过一定压缩的了,继续做语言层面的压缩效果不明显。并且如果已经使用gzip压缩了,就没必要做这个了。</span></span></div><div><span style="line-height: 28px; font-family:Arial;font-size:130%;"><span style="line-height: 24px; font-size: 15px; white-space: pre-wrap; "><br /></span></span></div></div></div></span><br /></div></div>hgkhttp://www.blogger.com/profile/18248256147814166844noreply@blogger.com0tag:blogger.com,1999:blog-3051279638784476121.post-16673311469797033252010-08-09T10:06:00.000-07:002010-08-09T10:07:17.287-07:00Ajax 同源策略限制的简单说明<span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif; font-size: 14px; color: rgb(68, 68, 68); line-height: 22px; "><span style="line-height: 25px; font-size: medium; ">出于安全原因,浏览器对页面中的ajax请求(<span style="line-height: 22px; font-family: Arial, Tahoma, Verdana, sans-serif; color: rgb(51, 51, 51); font-size: 14px; ">XMLHTTPRequest</span>)有同源策略的限制。</span><div style="line-height: 22px; "><span style="line-height: 25px; font-size: medium; "><br /></span><div style="line-height: 22px; "><span style="line-height: 25px; font-family: Tahoma, Helvetica, Arial, sans-serif; color: rgb(42, 42, 42); "><span style="line-height: 25px; font-size: medium; ">如果两个页面的</span><b style="line-height: 22px; "><span style="line-height: 25px; font-size: medium; ">协议、域名和端口是完全相同</span></b><span style="line-height: 25px; font-size: medium; ">的,那么它们就是同源的。<b style="line-height: 25px; ">当前加载页面只能发出同源的ajax请求。</b></span></span></div><div style="line-height: 22px; "><span style="line-height: 25px; font-family: Tahoma, Helvetica, Arial, sans-serif; color: rgb(42, 42, 42); "><span style="line-height: 22px; color: rgb(0, 0, 0); font-family: Arial, Helvetica, sans-serif; "><span style="line-height: 25px; font-size: medium; ">比如说你的当前页面是http://www.example.com/test.html,那么这个页面中的只能发出 </span></span></span><span style="line-height: 25px; font-size: medium; ">http://www.example.com/ 下的请求。</span></div><div style="line-height: 22px; "><span style="line-height: 25px; font-family: Tahoma, Helvetica, Arial, sans-serif; color: rgb(42, 42, 42); "><span style="line-height: 25px; font-size: medium; "><br /></span></span></div><div style="line-height: 22px; "><span style="line-height: 25px; font-family: Tahoma, Helvetica, Arial, sans-serif; color: rgb(42, 42, 42); "><span style="line-height: 25px; font-size: medium; ">一、协议指:http、https、ftp等属于不同的协议,尤其是http和https也是不同的协议。</span></span></div><div style="line-height: 22px; "><span style="line-height: 25px; font-family: Tahoma, Helvetica, Arial, sans-serif; color: rgb(42, 42, 42); "><span style="line-height: 25px; font-size: medium; ">二、域名指不同:</span></span></div><div style="line-height: 22px; "><ol style="line-height: 22px; margin-top: 5px; margin-right: 0px; margin-bottom: 5px; margin-left: 40px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><li style="line-height: 22px; "><span style="line-height: 22px; font-family:Tahoma, Helvetica, Arial, sans-serif;color:#2A2A2A;"><span style="line-height: 25px; font-size: medium; "><b style="line-height: 25px; ">顶级域名</b>不同。如 www.abc.com的页面中不能向 www.def.com发出http请求。</span></span></li><li style="line-height: 22px; "><span style="line-height: 22px; font-family:Tahoma, Helvetica, Arial, sans-serif;color:#2A2A2A;"><span style="line-height: 25px; font-size: medium; "><b style="line-height: 25px; ">IP与域名</b>也被认为是不同的,即便他们是一回事。比如在开发的时候,你自己的本机局域网地址是192.168.1.106,你用 </span><b style="line-height: 22px; "><span style="line-height: 25px; font-size: medium; ">localhost</span></b><span style="line-height: 25px; font-size: medium; "> 打开当前页面,而页面中请求的却是192.168.1.106也不行的。总之,域名和IP被认为是不同的域名,包括 localhost ,所以要么全用域名,要么全用IP。</span></span></li><li style="line-height: 22px; "><span style="line-height: 22px; font-family:Tahoma, Helvetica, Arial, sans-serif;color:#2A2A2A;"><span style="line-height: 25px; font-size: medium; ">相同顶级域名,但<b style="line-height: 25px; ">二级域名</b>不同也是不同的。这个要求对同一域名下的各个子服务之间访问造成了一些限制。比如 www.example.com 和 download.example.com 就是不同的,www.example.com 和 example.com也是不同的。不过javascript中允许设置 </span></span><span style="line-height: 18px; font-family: Verdana, Arial; "><span style="line-height: 25px; font-size: medium; ">document.domain 变量为 当前域名更短的域名,比如当前访问的是www.example.com,可以</span></span><span style="line-height: 22px; font-family:Tahoma, Helvetica, Arial, sans-serif;color:#2A2A2A;"><span style="line-height: 25px; font-size: medium; ">设置 </span></span><span style="line-height: 18px; font-family: Verdana, Arial; "><span style="line-height: 25px; font-size: medium; ">document.domain 为example.com,这样就可以访问 example.com 下的请求。一种跨子域的解决方法就是,x子域的当前页面包括一个y子域的iframe,当前页面和这个frame分别将自己的</span></span><span style="line-height: 25px; font-family: Verdana, Arial; font-size: medium; ">document.domain设置为根域名,这样当前x子域的页面就可以通过这个y子域的页面代理访问y子域的请求。</span></li></ol><div style="line-height: 22px; "><span style="line-height: 22px; font-family:Tahoma, Helvetica, Arial, sans-serif;color:#2A2A2A;"><span style="line-height: 25px; font-size: medium; ">三、端口不同:这个大家都明白,比如80和8080是不同的。</span></span></div><div style="line-height: 22px; "><span style="line-height: 22px; font-family:Tahoma, Helvetica, Arial, sans-serif;color:#2A2A2A;"><span style="line-height: 25px; font-size: medium; "><br /></span></span></div><div style="line-height: 22px; "><span style="line-height: 22px; font-family:Tahoma, Helvetica, Arial, sans-serif;color:#2A2A2A;"><span style="line-height: 25px; font-size: medium; ">注意:script标签的src属性是没有同源限制的,你的网页上可以加载互联网上任何url的js,比如在页面中嵌入Google 分析的js代码。类似的,img标签也可以加载任何url的图片,比如你的网站上链接的是别人的图片,这些都不受同源策略的限制。利用这一点,也可以实现一定程度的跨域请求,比如你可以利用js修改script或img等标签的src属性,就等于在向任意url发出了一个get请求。</span></span></div></div><div style="line-height: 22px; "><span style="line-height: 22px; font-family:Tahoma, Helvetica, Arial, sans-serif;color:#2A2A2A;"><span style="line-height: 25px; font-size: medium; ">iframe也可以是任意url,但当前页面只能向自己的同源发出请求。</span></span></div><div style="line-height: 22px; "><span class="Apple-style-span" style="line-height: 25px; font-size: medium;"><br /></span></div><div style="line-height: 22px; "><span class="Apple-style-span" style="line-height: 25px; font-size: medium;"><br /></span></div><div style="line-height: 22px; "><span style="line-height: 25px; font-size: medium; ">同源策略在带来安全性的同时,也对应用程序造成了很多限制,所以又引出了ajax跨域</span><span style="line-height: 25px; font-size: medium; ">问题</span><span style="line-height: 25px; font-size: medium; ">解</span><span style="line-height: 25px; font-size: medium; ">决方法。除了前面说到的方法,一般的跨域就是类似代理的方法了。</span></div></div></span>hgkhttp://www.blogger.com/profile/18248256147814166844noreply@blogger.com0tag:blogger.com,1999:blog-3051279638784476121.post-10089628185211755832010-08-08T23:32:00.000-07:002010-08-08T23:33:23.962-07:00Geo Location 地理位置信息小结<span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif; font-size: 14px; color: rgb(68, 68, 68); line-height: 22px; "><div style="line-height: normal; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; background-color: transparent; font-size: 12pt; text-indent: 0px; margin-left: 0px; font-family: 微软雅黑; "><h5 id="internal-source-marker_0.5406793216243386" style="line-height: 20px; "><span style="line-height: 20px; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "><span style="line-height: 20px; font-weight: normal; "><span style="line-height: 20px; font-size: small; ">周末调研了一下Geo Location 地理位置信息方面的内容,自己小结一下。</span></span></span></h5><h5 id="internal-source-marker_0.5406793216243386" style="line-height: 20px; "><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: bold; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; ">一、通过 IP 地址获得用户的地理位置信息</span></h5><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "></span><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "><div style="line-height: normal; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; background-color: transparent; font-size: 12pt; text-indent: 0px; margin-left: 0px; font-family: 微软雅黑; "><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; ">也就是根据用户的IP,通过IP数据库查询获得信息。</span><span style="line-height: 24px; font-size: 15px; font-family: Arial; ">一般IP数据库中,</span></div>每条记录的基本结构:</span></div><div style="line-height: normal; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; background-color: transparent; font-size: 12pt; text-indent: 0px; margin-left: 0px; font-family: 微软雅黑; "><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "><span style="line-height: 24px; white-space: pre; "> </span><span style="line-height: 24px; color:#0000FF;">IP地址段(起始、结束),以及对应的信息数据</span></span><br /><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; ">一般包含的信息:国家、区域(省/州)、城市、街道、经纬度、ISP提供商等信息</span><br /><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "></span><br /><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; ">因为IP数据库随着时间经常变化(不过一段时间内变化很小),所以需要有人经常维护和更新。这个数据也不可能完全准确、也不可能覆盖全。这是maxmind的城市准确度 </span><a href="http://www.maxmind.com/app/city_accuracy" style="line-height: 25px; text-decoration: none; color: rgb(100, 160, 56); "><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 153); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap; ">http://www.maxmind.com/app/city_accuracy</span></a><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "> 。</span><br /><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "></span><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; ">因为没有权威的数据组织机构,且经常有变化。各家数据供应商,基本上做着做着就形成自己的一套数据了。</span><br /><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "></span><br /><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; ">目前,国内用的比较有名的是“纯真IP数据库”,国外常用的是 maxmind、ip2location。</span><br /><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "></span><br /><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; ">IP数据库是否收费:收费、免费都有。一般有人维护的数据往往都是收费的,准确率和覆盖率会稍微高一些。</span><br /><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "></span><br /><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; ">质量方面:</span><br /><ol style="line-height: 25px; margin-top: 5px; margin-right: 0px; margin-bottom: 5px; margin-left: 40px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><li style="line-height: 25px; "><span style="line-height: 24px; font-size: 15px; font-family: Arial; white-space: pre-wrap; ">主要概念是准确率和覆盖率。</span></li><li style="line-height: 25px; "><span style="line-height: 24px; font-size: 15px; font-family: Arial; white-space: pre-wrap; ">记录数据总条数。纯真现在是38万条(2010年07月30日更新)</span></li><li style="line-height: 25px; "><span style="line-height: 24px; font-size: 15px; font-family: Arial; white-space: pre-wrap; ">是否有人维护。</span></li><li style="line-height: 25px; "><span style="line-height: 24px; font-size: 15px; font-family: Arial; white-space: pre-wrap; ">数据库更新频率:每月、每周。数据库会定期更新的,maxmind开源版是每月更新一次。</span></li></ol></div><div style="line-height: normal; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; background-color: transparent; font-size: 12pt; text-indent: 0px; margin-left: 0px; font-family: 微软雅黑; "><span style="line-height: 25px; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; "></span><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "></span><br /><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; ">查询形式:</span><ul style="line-height: 25px; margin-top: 5px; margin-right: 0px; margin-bottom: 5px; margin-left: 40px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><li style="line-height: 24px; list-style-type: disc; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; "><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; ">本地,将IP数据库下载到本地使用,查询效率高、性能好。常用在统计分析方面。具体形式又分为:</span></li><ul style="line-height: 25px; margin-top: 5px; margin-right: 0px; margin-bottom: 5px; margin-left: 40px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><li style="line-height: 24px; list-style-type: circle; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; "><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; ">内存查询:将全部数据直接加载到内存中,便于高性能查询</span></li><li style="line-height: 24px; list-style-type: circle; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; "><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; ">数据库查询:将数据导入到数据库,再用数据库查询。效率没有内存查询快。</span></li></ul><li style="line-height: 24px; list-style-type: disc; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; "><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; ">远程(web service或ajax),调用远程第三方服务。查询效率自然比较低,一般用在网页应用中。</span></li></ul><br /><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "></span><br /><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; ">是否提供API:有的IP数据库提供API,支持多语言(java、javascript、C#等),这样你就不用自己直接分析数据格式、整理、写查询代码了。</span><br /><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "></span><br /><span style="line-height: 28px; font-family:Arial;font-size:130%;"><span style="line-height: 24px; font-size: 15px; white-space: pre-wrap; "></span></span><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "></span><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; ">是否提供经纬度:纯真IP数据库不提供经纬度,Maxmind提供。如果做地图应用,一般是需要经纬度的。</span><br /><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "></span><br /><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; ">语言方面:英文还是中文。maxmind提供的数据,所有信息都是英文的,国家是iso的国家码,如中国是China,北京是Beijing,国内环境使用不方便,除非你自己再维护一个中英对照表。而纯真IP数据库就中文信息。</span><br /><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "></span><br /><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; ">另外,有些Web服务器也有这方面的功能集成。因为对Web应用而言,IP数据显然是通过Web服务器获得的,因此这部分工作也可以交给web 服务器来做。比如 Nginx 就带了一个GeoIP 的可选模块( </span><a href="http://wiki.nginx.org/NginxHttpGeoIPModule" style="line-height: 25px; text-decoration: none; color: rgb(100, 160, 56); "><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 153); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap; ">http://wiki.nginx.org/NginxHttpGeoIPModule</span></a><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; ">),集成了</span><span style="line-height: 25px; font-size: 12pt; font-family: Arial; color: rgb(85, 85, 85); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "> </span><span style="line-height: 25px; font-size: 12pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; ">MaxMind</span><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; ">,安装时需要在configure中指定该模块。</span><span style="line-height: 25px; font-size: 12pt; font-family: Arial; color: rgb(85, 85, 85); background-color: rgb(249, 249, 249); font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "></span><br /><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "></span><br /><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "></span><br /><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "><b style="line-height: 24px; ">Maxmind</b></span><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; ">,</span><a href="http://www.maxmind.com/" style="line-height: 25px; text-decoration: none; color: rgb(100, 160, 56); "><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 153); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap; ">http://www.maxmind.com</span></a><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; ">,</span><br /><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; ">有收费版,也有开源版本。</span><br /><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; ">数据下载,</span><a href="http://geolite.maxmind.com/download/geoip/database/" style="line-height: 25px; text-decoration: none; color: rgb(100, 160, 56); "><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 153); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap; ">http://geolite.maxmind.com/download/geoip/database/</span></a><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "></span><br /><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; ">准确度,</span><a href="http://www.maxmind.com/app/city_accuracy" style="line-height: 25px; text-decoration: none; color: rgb(100, 160, 56); "><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 153); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap; ">http://www.maxmind.com/app/city_accuracy</span></a><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "></span><br /><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; ">支持多种语言,</span><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 153); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap; "><a href="http://www.maxmind.com/app/city" style="line-height: 24px; text-decoration: none; color: rgb(100, 160, 56); ">http://www.maxmind.com/app/city</a></span></div><div style="line-height: normal; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; background-color: transparent; font-size: 12pt; text-indent: 0px; margin-left: 0px; font-family: 微软雅黑; "><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 153); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap; "><a href="http://www.maxmind.com/app/city" style="line-height: 24px; text-decoration: none; color: rgb(100, 160, 56); "></a></span><span style="line-height: 24px; font-size: 15px; font-family: Arial; white-space: pre-wrap; ">Open Source binary API available for the following languages:</span><ul style="line-height: 25px; margin-top: 5px; margin-right: 0px; margin-bottom: 5px; margin-left: 40px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><li style="line-height: 20px; list-style-type: disc; font-size: 10pt; font-family: Verdana; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; "><a href="http://www.maxmind.com/app/c" style="line-height: 20px; text-decoration: none; color: rgb(100, 160, 56); "><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 153); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap; ">C</span></a></li><li style="line-height: 20px; list-style-type: disc; font-size: 10pt; font-family: Verdana; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; "><a href="http://www.maxmind.com/app/php" style="line-height: 20px; text-decoration: none; color: rgb(100, 160, 56); "><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; ">PHP (Pure)</span></a></li><li style="line-height: 20px; list-style-type: disc; font-size: 10pt; font-family: Verdana; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; "><a href="http://www.maxmind.com/app/java" style="line-height: 20px; text-decoration: none; color: rgb(100, 160, 56); "><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 153); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap; ">Java</span></a></li><li style="line-height: 20px; list-style-type: disc; font-size: 10pt; font-family: Verdana; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; "><a href="http://www.maxmind.com/app/perl" style="line-height: 20px; text-decoration: none; color: rgb(100, 160, 56); "><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; ">Perl (XS)</span></a></li><li style="line-height: 20px; list-style-type: disc; font-size: 10pt; font-family: Verdana; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; "><a href="http://www.maxmind.com/app/perl" style="line-height: 20px; text-decoration: none; color: rgb(100, 160, 56); "><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; ">Perl (Pure)</span></a></li><li style="line-height: 20px; list-style-type: disc; font-size: 10pt; font-family: Verdana; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; "><a href="http://www.maxmind.com/app/mod_geoip" style="line-height: 20px; text-decoration: none; color: rgb(100, 160, 56); "><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 153); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap; ">Apache</span></a></li><li style="line-height: 20px; list-style-type: disc; font-size: 10pt; font-family: Verdana; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; "><a href="http://www.maxmind.com/app/python" style="line-height: 20px; text-decoration: none; color: rgb(100, 160, 56); "><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; ">Python</span></a></li><li style="line-height: 20px; list-style-type: disc; font-size: 10pt; font-family: Verdana; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; "><a href="http://www.maxmind.com/app/com" style="line-height: 20px; text-decoration: none; color: rgb(100, 160, 56); "><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 153); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap; ">MS COM</span></a></li><li style="line-height: 20px; list-style-type: disc; font-size: 10pt; font-family: Verdana; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; "><a href="http://www.maxmind.com/app/csharp" style="line-height: 20px; text-decoration: none; color: rgb(100, 160, 56); "><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; ">C#</span></a></li><li style="line-height: 20px; list-style-type: disc; font-size: 10pt; font-family: Verdana; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; "><a href="http://www.maxmind.com/app/pascal" style="line-height: 20px; text-decoration: none; color: rgb(100, 160, 56); "><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 153); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap; ">Pascal</span></a></li><li style="line-height: 20px; list-style-type: disc; font-size: 10pt; font-family: Verdana; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; "><a href="http://www.maxmind.com/app/ruby" style="line-height: 20px; text-decoration: none; color: rgb(100, 160, 56); "><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; ">Ruby</span></a></li><li style="line-height: 20px; list-style-type: disc; font-size: 10pt; font-family: Verdana; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; "><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 153); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap; ">For performance details, see our </span><a href="http://www.maxmind.com/app/benchmark" style="line-height: 20px; text-decoration: none; color: rgb(100, 160, 56); "><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; ">benchmark</span></a><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 153); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap; "> page</span><span style="line-height: 20px; font-size: 10pt; font-family: Verdana; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "></span></li></ul><br /><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "></span><span style="line-height: 32px; font-size: 15pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "></span><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "><b style="line-height: 24px; ">ip2location</b></span><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "> ,</span><span style="line-height: 25px; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; "> </span><span style="line-height: 24px; font-size: 11pt; font-family: Arial; background-color: transparent; font-weight: normal; font-style: normal; vertical-align: baseline; white-space: pre-wrap; "><a href="http://www.ip2location.com/" target="_blank" style="line-height: 24px; text-decoration: none; color: rgb(100, 160, 56); "><span style="line-height: 24px; color:#000000;">http://www.ip2location.com/</span></a> </span><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 153); background-color: transparent; font-weight: normal; font-style: normal; vertical-align: baseline; white-space: pre-wrap; ">,</span><span style="line-height: 24px; font-size: 15px; font-family: Arial; white-space: pre-wrap; ">和Maxmind类似,不多介绍了。</span></div><div style="line-height: normal; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; background-color: transparent; font-size: 12pt; text-indent: 0px; margin-left: 0px; font-family: 微软雅黑; "><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "></span><br /><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "><b style="line-height: 24px; ">纯真IP数据库</b></span><br /><a href="http://www.cz88.net/" style="line-height: 25px; text-decoration: none; color: rgb(100, 160, 56); "><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 153); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap; ">http://www.cz88.net/</span></a><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "></span><br /><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; ">主要是国内信息,比较准确,也比较精确(可以到小区、网吧什么的),数据也是中文的。比较适合分析国内数据,国内够用了。国外数据非常少,如果主要处理国外的,不要用这个。没有经纬度。</span><br /><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "></span><br /><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; ">官方组织:</span><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "><b style="line-height: 24px; ">APNIC</b></span><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "> </span><br /><a href="http://www.apnic.net/" style="line-height: 25px; text-decoration: none; color: rgb(100, 160, 56); "><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 153); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap; ">http://www.apnic.net/</span></a><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "></span><br /><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; ">APNIC is an open, membership-based, not-for-profit organization providing Internet addressing services to the Asia Pacific.</span><br /><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; ">数据下载:</span><a href="http://ftp.apnic.net/apnic/dbase/data/" style="line-height: 25px; text-decoration: none; color: rgb(100, 160, 56); "><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 153); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap; ">http://ftp.apnic.net/apnic/dbase/data/</span></a><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "></span><br /><a href="http://ftp.apnic.net/apnic/dbase/data/country-ipv4.lst" style="line-height: 25px; text-decoration: none; color: rgb(100, 160, 56); "><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 153); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap; ">http://ftp.apnic.net/apnic/dbase/data/country-ipv4.lst</span></a><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "> 提供了IP段到国家的映射。小工具</span><a href="http://code.google.com/p/chnroutes/" style="line-height: 25px; text-decoration: none; color: rgb(100, 160, 56); "><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 153); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap; ">chnroutes</span></a><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "> 就是利用这个数据。</span><br /><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "></span><br /><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "></span><br /><h5 style="line-height: 20px; "><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: bold; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; ">二、通过 W3C Geo API 获得用户地理位置</span></h5><h3 style="line-height: 30px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; ">也就是html5中关于地理位置的方面</span></h3><h3 style="line-height: 30px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; ">geolocation api,地理位置由浏览器提供,需要浏览器支持。很多基于地理位置的网站都开始使用了,一般需要浏览器用户同意。</span></h3><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; ">W3C 的 Geolocation API Specification:</span><a href="http://dev.w3.org/geo/api/spec-source.html" style="line-height: 25px; text-decoration: none; color: rgb(100, 160, 56); "><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 153); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap; ">http://dev.w3.org/geo/api/spec-source.html</span></a><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "></span><br /><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "></span><br /><h5 style="line-height: 20px; "><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: bold; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; ">三、移动领域</span></h5><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; ">手机:GPS(精确度高、刚开启时搜星比较慢、手机上比较费电)、根据手机信号的基站定位(不太精确、范围较大),</span><br /><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; ">Wifi信号应该也可以,但要有这方面的数据收集</span><br /><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "></span><br /><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "></span><br /><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; ">其它参考:</span><br /><h3 style="line-height: 30px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; ">Web 地理定位(Geo-Location)知识大全,</span><a href="http://www.javaeye.com/news/13813-web-geo" style="line-height: 30px; text-decoration: none; color: rgb(100, 160, 56); "><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 153); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap; ">http://www.javaeye.com/news/13813-web-geo</span></a><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "></span></h3><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; ">根据IP定位地理位置,</span><a href="http://www.huachu.com.cn/read/readbookinfo.asp?sectionid=1000004203" style="line-height: 25px; text-decoration: none; color: rgb(100, 160, 56); "><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 153); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap; ">http://www.huachu.com.cn/read/readbookinfo.asp?sectionid=1000004203</span></a><span style="line-height: 24px; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "></span><br /></div></span>hgkhttp://www.blogger.com/profile/18248256147814166844noreply@blogger.com0tag:blogger.com,1999:blog-3051279638784476121.post-38116218186496219552010-08-07T20:17:00.000-07:002010-08-07T20:18:29.671-07:00Tomcat无法正常关闭<span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif; font-size: 14px; color: rgb(68, 68, 68); line-height: 22px; "><span style="line-height: normal; font-family: Helvetica, Arial, sans-serif; font-size: 13px; color: rgb(54, 43, 54); ">Tomcat的正常启动和停止是用 startup 和 shutdown 两个脚本,但有时候tomcat因为其中部署的某个应用导致不能正常 shutdown 。判断是不是由应用引起的问题,很简单,试试tomcat不部署任何应用时是不是也有这个问题。</span><div style="line-height: 22px; "><div style="line-height: 22px; "><span style="line-height: normal; font-family: Helvetica, Arial, sans-serif; font-size: 13px; color: rgb(54, 43, 54); "><br /></span></div><div style="line-height: 22px; "><span style="line-height: normal; font-family: Helvetica, Arial, sans-serif; font-size: 13px; color: rgb(54, 43, 54); ">其实,不能正常shutdown八成是由于应用自身没有释放资源造成的,比如在应用中使用了非daemon的线程或Timer(timer是使用独立线程来实现的),而在容器stop时</span><span style="line-height: normal; font-family: Helvetica, Arial, sans-serif; color: rgb(54, 43, 54); font-size: 13px; ">自己</span><span style="line-height: normal; font-family: Helvetica, Arial, sans-serif; font-size: 13px; color: rgb(54, 43, 54); ">又不销毁就导致容器不能正常停止,只能kill。</span><span style="line-height: normal; font-family: Helvetica, Arial, sans-serif; color: rgb(54, 43, 54); font-size: 13px; "><b style="line-height: 20px; ">容器只按照Java EE规范来管理应用中标准组件的生命周期,但你自己创建出来的资源要自己负责处理,容器是不会替你管理的。</b></span><span style="line-height: normal; font-family: Helvetica, Arial, sans-serif; color: rgb(54, 43, 54); font-size: 13px; "><b style="line-height: 20px; ">JVM中,所有的非守护线程都停止了,JVM自然就停止了。</b></span></div></div><div style="line-height: 22px; "><span style="line-height: normal; font-family: Helvetica, Arial, sans-serif; font-size: 13px; color: rgb(54, 43, 54); "><br /></span></div><div style="line-height: 22px; "><span style="line-height: normal; font-family: Helvetica, Arial, sans-serif; font-size: 13px; color: rgb(54, 43, 54); ">解决方法无非两种:</span></div><div style="line-height: 22px; "><span style="line-height: normal; font-family: Helvetica, Arial, sans-serif; font-size: 13px; color: rgb(54, 43, 54); ">1.将应用自己创建的线程、timer、scheduler<b style="line-height: 20px; ">这类的资源设为守护线程(daemon)</b>。因为这些东西一般就是用来在应用运行期间做些例行维护的工作。</span></div><div style="line-height: 22px; "><span style="line-height: normal; font-family: Helvetica, Arial, sans-serif; font-size: 13px; color: rgb(54, 43, 54); ">2.自己管理非守护线程的生命周期,<b style="line-height: 20px; ">当容器停止时手工释放资源</b>。比如你可以在 Servlet 或 ServletContextListener 的 init 方法中初始化资源,在 destroy 方法中释放资源。</span></div><div style="line-height: 22px; "><span style="line-height: 25px; font-family:Helvetica, Arial, sans-serif;font-size:100%;color:#362B36;"><span style="line-height: normal; font-size: 13px; "><br /></span></span></div><div style="line-height: 22px; "><span style="line-height: 25px; font-family:Helvetica, Arial, sans-serif;font-size:100%;color:#362B36;"><span style="line-height: normal; font-size: 13px; ">后话:很多应用开发人员并没有很好地理解原理,不清楚容器替你做了什么也就不清楚自己应该负责什么。</span></span></div><div style="line-height: 22px; "><span style="line-height: 25px; font-family:Helvetica, Arial, sans-serif;font-size:100%;color:#362B36;"><span style="line-height: normal; font-size: 13px; ">这是在我维护别人的写的一个web应用时发现的问题。</span></span></div></span>hgkhttp://www.blogger.com/profile/18248256147814166844noreply@blogger.com0tag:blogger.com,1999:blog-3051279638784476121.post-1957013458823032092010-06-19T21:46:00.005-07:002010-06-19T21:46:37.319-07:002010/6/20 一种 Database+程序 的ID生成策略<div><font face="arial, helvetica, sans-serif"><font color="#444444"><font size="3"><b>特点:持久化、通用性、性能好、多进程共用。</b></font></font></font></div><div><font face="arial, helvetica, sans-serif"><font color="#444444"><font size="3">这种实现保证了id递增的唯一性,并且多个VM同时使用同一个Database也没问题,vm突然强制关闭也没问题。</font></font></font></div><font size="3"><br></font><div><font face="arial, helvetica, sans-serif"><font color="#444444"><font size="3"><b>方法概述</b>:采用 Database+VM(表示一个程序)结合的策略生成ID,生成的ID为递增的整数。用Database做id生成的持久层,采用vm进行分段递增。由程序负责一个段内的递增,vm每次开始分配id前先向数据库申请一段可用id。数据库记录上次分配出去的id最大值。</font></font></font></div><font size="3"><br></font><div><font face="arial, helvetica, sans-serif"><font color="#444444"><font size="3">具体方法:数据库中建一张表,表中有一个长整数的Id字段,负责记录已分配出的ID最大值。然后程序在开始生成id前,先向数据库申请一段id,获得这段id的起始值和最大值,然后程序自己就可以在这段范围内采用原子递增方式分配id了。id段用完了就再次向数据库申请。申请的id段的大小由程序自己指定,大小适中即可。</font></font></font></div><font size="3"><br></font><div><font face="arial, helvetica, sans-serif"><font color="#444444"><font size="3">申请的过程就是get and set,这个过程要保证数据一致。不一定采用事物的方式来保证,因为每个程序可以分配一段,所以冲突的可能性小,属于乐观的情况,所以可以采用非事物的方式如果不一致重试几次即可。</font></font></font></div><font size="3"><br></font><div><font face="arial, helvetica, sans-serif"><font color="#444444"><font size="3">所谓ID,即唯一标识符,所以ID生成器的实现目标就是要保证每次分配的id唯一。</font></font></font></div><div><font face="arial, helvetica, sans-serif"><font color="#444444"><font size="3">既然id生成过程是在程序中完成的,如果程序退出或强制关闭了,那么下次程序启动时会再次向数据库申请新的id段,因而id唯一性是有保证的,但不保证id一定是连续的,程序退出时可能会浪费掉少量段内还没分配完的id。</font></font></font></div><font size="3"><br></font><div><font face="arial, helvetica, sans-serif"><font color="#444444"><font size="3">特点:</font></font></font></div><ol style="margin-left:40px;margin-right:0px"><li><font face="arial, helvetica, sans-serif"><font color="#444444"><font size="3"><b>持久化:</b>使用数据库记录上次分配出的最大id。一般而言,如果仅使用程序自身生成id,只能保证程序一次性运行中生成的id可靠,下次再运行就不成了。除了UUID等特殊算法外,一般ID生成策略是需要持久化一些数据的,而持久化的方法无疑最好是使用数据库。</font></font></font></li><li><font face="arial, helvetica, sans-serif"><font color="#444444"><font size="3"><b>通用性:</b>只是自己在数据库新建一个简单的表,其它工作都有程序完成,因而不依赖于特定数据库的主键或Sequence生成方式,具有很好的可移植性。(不依赖于特定数据库带来的好处是可移植性,坏处就是这部分工作转给了程序自己实现)</font></font></font></li><li><font face="arial, helvetica, sans-serif"><font color="#444444"><font size="3"><b>性能好:</b>因为不是每生成一个id都要更新数据库,而是在程序中完成的,所以效率高,性能好。</font></font></font></li><li><font face="arial, helvetica, sans-serif"><font color="#444444"><font size="3"><b>多进程共用:</b>多个程序同时使用一张数据表也没问题,只要保证vm向数据库申请id段的一致性即可,由数据库做中介。</font></font></font></li></ol><font size="3"><br></font><div><font face="arial, helvetica, sans-serif"><font color="#444444"><font size="3">上面描述的方法只是利用了数据库表中的一条记录维护一个递增的ID,可以使用多条记录维护多种不相关的ID,供系统中的多处使用。</font></font></font></div><font size="3"><br></font><div><font face="arial, helvetica, sans-serif"><font color="#444444"><font size="3">这个实现方法是在 Openfire 中使用的 ID 生成方法,具体实现见org.jivesoftware.database.SequenceManager。</font></font></font></div><div><font face="arial, helvetica, sans-serif"><font color="#444444"><font size="3">表结构:</font></font></font></div><div><font face="arial, helvetica, sans-serif"><font color="#444444"><font size="3">CREATE TABLE ofID (</font></font></font></div><div><font face="arial, helvetica, sans-serif"><font color="#444444"><font size="3"> idType INTEGER NOT NULL,</font></font></font></div><div><font face="arial, helvetica, sans-serif"><font color="#444444"><font size="3"> id BIGINT NOT NULL,</font></font></font></div><div><font face="arial, helvetica, sans-serif"><font color="#444444"><font size="3"> PRIMARY KEY (idType)</font></font></font></div><div><font face="arial, helvetica, sans-serif"><font color="#444444"><font size="3">);</font></font></font></div><br>hgkhttp://www.blogger.com/profile/18248256147814166844noreply@blogger.com182tag:blogger.com,1999:blog-3051279638784476121.post-50515410570957391152010-06-19T21:46:00.003-07:002010-06-19T21:46:24.214-07:002010/6/9 Ajax的同步调用场景——使用同步Ajax在 onunload 事件时通知服务器<font face="arial, helvetica, sans-serif"><font color="#444444"><font size="3">在一种场景下,server端维护了浏览器客户端的状态信息,当浏览器关闭时需要<b>立刻通知</b>server用户已经离开了,server端好清理状态。这种情况的典型案例就是:浏览器客户端的即时通信,即web IM。因为用户关闭了窗口就表明用户已经不在线了,所有对话都结束了,server端和对话的另一方需要立刻知道这个状态变化。而一般情况下,server端并<b>不需要立刻通知</b>的情况,那就无所谓了,只要过期超时即可。</font></font></font><br><font size="3"><br></font><div><font face="arial, helvetica, sans-serif"><font color="#444444"><font size="3">要想在用户关闭浏览器后,server端得到通知,一般有两种做法:</font></font></font></div><div><font face="arial, helvetica, sans-serif"><font color="#444444"><font size="3"><b>方法一</b>:通过 javascript 轮询的方式向 server 发送心跳(使用异步ajax),server端记下上次心跳时间,server端Timer定期检查会话的心跳时间是否超时来判断用户是否已经离开了。这种方法的缺点是,要想即时通知就得把心跳间隔时间设得短,server端检查的时间也要短,这样会导致server端的负担大大增加,所能承载的用户就会较少。</font></font></font></div><div><font face="arial, helvetica, sans-serif"><font color="#444444"><font size="3"><b>方法二</b>:不采用发送心跳的方式,而是在用户关闭浏览器时,通知server即可。这样server端的负担就小了。</font></font></font></div><div><font face="arial, helvetica, sans-serif"><font color="#444444"><font size="3">window.onunload = function(){</font></font></font></div><div><font face="arial, helvetica, sans-serif"><font color="#444444"><font size="3"> <i>ajax.callServer();</i></font></font></font></div><div><font face="arial, helvetica, sans-serif"><font color="#444444"><font size="3">}</font></font></font></div><font size="3"><br></font><div><font face="arial, helvetica, sans-serif"><font color="#444444"><font size="3">重点说一下方法二的实现。</font></font></font></div><div><font face="arial, helvetica, sans-serif"><font color="#444444"><font size="3"><b>首先</b>,页面上注册 onunload 事件。如 body元素的 onunload 属性,或直接设置 window.onunload 。</font></font></font></div><div><font face="arial, helvetica, sans-serif"><font color="#444444"><font size="3">注意是 onunload 而不是 onbeforeunload 事件,因为用户可以在 onbeforeunload 事件时选择“取消”从而不关闭窗口,而onunload 事件意味着窗口肯定是要被关闭的。</font></font></font></div><font size="3"><br></font><div><font face="arial, helvetica, sans-serif"><font color="#444444"><font size="3"><b>其次</b>,在onunload事件中<b>调用同步的ajax请求通知server,而非默认的异步ajax请求</b>。因为调用异步的ajax请求在一些浏览器下无法真正使server得到通知,实际上根本无法保障!在发出了这个异步请求之后,浏览器就要关闭窗口并清理所有相关资源,因为这是异步请求,所以浏览器有理由认为无需等待该请求完成即可开始关闭窗口,这样该请求就可能失败(IE上就是这样,用异步请求无法通知到server)。这也解释了为什么异步callServer()调用后面再加个alert语句就没问题了,因为alert语句在后面挡着,需要人来点确认,所以可以完成对server的请求。而用同步的ajax请求则浏览器会等待该请求完成后才关闭窗口清理资源,因而就不会有这个问题。</font></font></font></div><font size="3"><br></font><div><font face="arial, helvetica, sans-serif"><font color="#444444"><font size="3">这就是一种使用同步ajax的场景,ajax中第一个a指的是 asynchronous 异步,当初引入ajax的主要目的就是引入一种异步执行的方法,绝大部分情况下应该使用异步方式执行ajax。同步ajax也许应该叫做 sjax ( s 是 synchronously)。</font></font></font></div><div><font face="arial, helvetica, sans-serif"><font color="#444444"><font size="3">XMLHttpRequest 的 open 方法中的第三参数表示是同步还是异步,xmlHttp.open("GET", url, true); 各种支持Ajax的框架,如prototype、ext、dwr等肯定都有选项设置是否为异步模式。</font></font></font></div><font size="3"><br></font><div><font face="arial, helvetica, sans-serif"><font color="#444444"><font size="3">最后,<b>实际情况的做法是要结合方法一和方法二</b>。方法二由于各种原因(比如用户电脑突然停电、浏览器崩溃等,这你总没办法吧),总是难免浏览器在关闭时没有成功的通知server。尽管是少数情况,但server端是要保证长期运行稳定的,要避免资源泄漏,所以必然server端还是需要定期检查会话是否过期的。但因为已经保证了大部分情况下server得到了通知,所以server端的定期检查可以时间长一些,心跳间隔也可以时间长一些(但要小于server检查的时间间隔),因而对server也不造成什么负担。</font></font></font></div><font size="3"><br></font><div><font face="arial, helvetica, sans-serif"><font color="#444444"><font size="3">相关参考资料:</font></font></font></div><div><font face="arial, helvetica, sans-serif"><font color="#444444"><font size="3">Snippets: Synchronous AJAX: <a href="http://www.hunlock.com/blogs/Snippets:_Synchronous_AJAX" style="color:#64a038;text-decoration:none">http://www.hunlock.com/blogs/Snippets:_Synchronous_AJAX</a></font></font></font></div><div><font face="arial, helvetica, sans-serif"><font color="#444444"><font size="3">Making AJAX calls onUnload: <a href="http://www.livelearncode.com/archives/11" style="color:#64a038;text-decoration:none">http://www.livelearncode.com/archives/11</a></font></font></font></div><br>hgkhttp://www.blogger.com/profile/18248256147814166844noreply@blogger.com0tag:blogger.com,1999:blog-3051279638784476121.post-80055112740127721252010-06-19T21:46:00.001-07:002010-06-19T21:46:11.448-07:002010/5/25 Eclipse 中 drop to frame 的调试技巧<font face="arial, sans-serif"><font color="#444444">前些天和同事交流调试技巧时,知道了 Eclipse debug 时有个 drop to frame 的技巧。这是我以前不知道的,自己又查了一下这个功能的含义。官方的解释是:</font></font><br><p style="color:#000000;font-family:Arial, Helvetica, sans-serif;margin-left:0px;margin-right:0px"><font color="#444444"><font face="arial, helvetica, sans-serif"><font size="2">Select the <b>Drop to Frame</b> command [ <img alt="Drop to Frame" src="http://help.eclipse.org/galileo/topic/org.eclipse.jdt.doc.user/images/org.eclipse.debug.ui/elcl16/drop_to_frame.png" style="border-color:initial;border-style:initial" title="Eclipse 中 drop to frame 的调试技巧 - hgk - 韩国恺的博客"> ] to re-enter the selected stack frame in the <b>Debug View</b>.</font></font></font></p><p style="color:#000000;font-family:Arial, Helvetica, sans-serif;margin-left:0px;margin-right:0px"><font color="#444444"><font face="arial, helvetica, sans-serif"><font size="2">Note this command is only available if the current VM supports drop to frame and the selected stackframe is not the top frame or a frame in a native method.</font></font></font></p><div><font face="arial, sans-serif"><font color="#444444">就是说,这个功能可以重新跳到当前方法的开始处重新执行,并且所有上下文变量的值也回到那个时候。不一定是当前方法,可以点击当前调用栈中的任何一个frame跳到那里(除了最开始的那个frame)。主要用途是所有变量状态快速恢复到方法开始时候的样子重新执行一遍,即可以一遍又一遍地在那个你关注的上下文中进行多次调试(结合改变变量值等其它功能),而不用重来一遍调试到哪里了。当然,原来执行过程中产生的副作用是不可逆的(比如你往数据库中插入了一条记录)。</font></font></div><div><br><font face="arial, sans-serif"><font color="#444444">这里也说了如何使用这个功能:<a href="http://www.javalobby.org/forums/thread.jspa?threadID=15271&tstart=0" style="color:#2a5db0;text-decoration:none" target="_blank">http://www.javalobby.org/forums/thread.jspa?threadID=15271&tstart=0</a></font></font></div><div><font face="arial, sans-serif"><font color="#444444">其实这个功能早就有了,就是一般人不知道或很少使用。</font></font></div><br>hgkhttp://www.blogger.com/profile/18248256147814166844noreply@blogger.com8tag:blogger.com,1999:blog-3051279638784476121.post-49816468671754280702010-06-19T21:45:00.005-07:002010-06-19T21:45:58.121-07:002010/5/24 收到联通寄来的0元发票<font face="arial, helvetica, sans-serif"><font color="#444444"><font size="3">你们见过面额为0元的发票吗?反正我以前没见过,但上周真的见到了,中国联通开的。</font></font></font><br><font size="3"><br></font><div><font face="arial, helvetica, sans-serif"><font color="#444444"><font size="3">上周帮人在联通网上营业厅买了个3g手机号,只买号不要钱,并且免费寄送给你。在下单的时候,可以填写发票抬头,我一看金额为0,觉得很有意思,没花钱也给开发票?结果在收到东西的时候还真有这个0元的发票。</font></font></font></div><font size="3"><br></font><div><font face="arial, helvetica, sans-serif"><font color="#444444"><font size="3">根据自己的个人经验,开发票一般就有点麻烦,更何况是没花钱还要让人给你开发票。我猜可能联通规定,只要办了业务就开对应的发票,不管金额多少。</font></font></font></div><br>hgkhttp://www.blogger.com/profile/18248256147814166844noreply@blogger.com0tag:blogger.com,1999:blog-3051279638784476121.post-9682024467697847112010-06-19T21:45:00.003-07:002010-06-19T21:45:25.939-07:002010/5/20 抱着做产品的心态做开发<div><font color="#444444"><font face="arial, sans-serif"><font size="2">我这半年主要在负责做一个产品。</font></font></font></div><div><font face="arial, sans-serif"><font color="#444444"><font face="arial, sans-serif"><font size="2">有几个不错的</font></font>同类产品,同事发了那个产品的反馈意见的论坛链接。里面有很多人提出的建议。</font></font></div><br><div><font face="arial, sans-serif"><font color="#444444">我在邮件的回复了下面这些内容:</font></font></div><div><font face="arial, sans-serif"><font color="#444444">只有当你的产品对别人有用,并且有很多人用的时候,你才会收到很多别人给你的建议。所以先参考一下这个比较实际一些。</font></font></div><br><div><font face="arial, sans-serif"><font color="#444444">我浏览了一下第一页的标题,从别人的建议中,<b>我发现其实都不是什么技术上的难题</b>,我相信他们和我们还有其它同类产品都可以解决这些问题。从技术人的角度看,往往喜欢分析技术本身是不是够难,说这个我们能做、那个也可以做、这个地方只要如何如何就实现了。其实,我想对开发人员说,<b>技术上一旦确定了架构,能力就已经确定了</b>,这个架构提供了基本模型,并且子模块都是可扩展的,满足各种未来的扩展需要。所以,我明确告诉大家技术上的问题都可以解决。<b>现在是能不能做出一个好产品的问题。这要求大家非常注重产品的每一个细节,精益求精,多从使用者的角度出发理解各种业务功能而不是从技术实现的角度,提升产品的品质和价值。从根上说,就是大家要抱着一种做产品的心态来开发,你敢自豪地向别人说这个产品是我做的。</b>内核虽是以开源项目为基础的,但是产品是我们自己做的!任何人都可以拿这个核来做产品,而大家工作的真正意义在于所有人都拿这个核做产品的情况下我们做出来的产品是最好的,这是我们存在的意义。比较直观的一个类比是,很多浏览器都以IE或Webkit为内核的,比如chrome、傲游、搜狗等浏览器,浏览器才是最终用户使用的产品,内核只有那么少数几个,但浏览器确非常多。你想想既然傲游是以IE为内核的,但为什么在国内用傲游的甚至比用IE的人还多?</font></font></div><br>hgkhttp://www.blogger.com/profile/18248256147814166844noreply@blogger.com0tag:blogger.com,1999:blog-3051279638784476121.post-8095792342157665052010-06-19T21:45:00.001-07:002010-06-19T21:45:12.684-07:002010/5/13 Javascript实现输入内容变化的监控通知<div><font face="arial, sans-serif"><font color="#444444">目前做个即时通讯的web客户端,类似于Web QQ。我们使用qq、msn时,经常会看到“对方正在打字”的提示,这样就知道对方正在输入一些东西。实现就是当用户做出一些改变的时候,向对方发送一个通知信息。至于如何定义什么时候发这个通知,则由客户端实现自己决定。一般就是监测用户的键盘事件或输入内容的变化。</font></font></div><br><div><font face="arial, sans-serif"><font color="#444444"><b>实现目标:当用户在输入框中输入或改变了一些内容时,发送一个通知。</b></font></font></div><div><font face="arial, sans-serif"><font color="#444444">起初的简单实现:监听浏览器中输入框的 keypress 事件。因为不应该每一个改变都应该立刻发送通知,那样过于频繁了,所以设置一个计数器counter,counter大于一个值(比如3)才是发送通知,再把counter设为0。</font></font></div><br><div><font face="arial, sans-serif"><font color="#444444">除了常规输入(输入字符和数字)外,用户按下Backspace和Delete键时会怎样?自己测试时发现一些问题:</font></font></div><div><font face="arial, sans-serif"><font color="#444444">keypress 事件在按下非字符键时,有些键会触发,有些键不会触发,而且具体随浏览器还不同。比如在ie中,仅字符键会触发keypress,那就是说你在IE上按Backspace删除了很多内容时,也不会发通知,因为没有触发keypress事件,而我的目标是应该发送通知。但在 Firefox 上就会触发keypress事件,也就是会发送通知。</font></font></div><div><font face="arial, sans-serif"><font color="#444444">一种解决方式是,你需要在specialKey中单独监控Backspace键,就可以在不同浏览器上都监控好。</font></font></div><div><font face="arial, sans-serif"><font color="#444444">但是我发现同样的方法监控不到Delete键。</font></font></div><br><div><font face="arial, sans-serif"><font color="#444444">后来又发现中文输入法也会干扰正常的事件,影响我目标的实现。</font></font></div><div><font face="arial, sans-serif"><font color="#444444">在输入中文时,在输入法窗口中显示了很多字,但只会产生一个keypress事件,这是正常的。但这样我原来的简单实现就没有很好地达到我的目的。而这时不应该仅靠事件触发的次数,还应该看每次事件时,字数变化的多少。</font></font></div><br><div><font face="arial, sans-serif"><font color="#444444">而且不同的输入法的兼容性和不同的浏览器实现都会有影响。</font></font></div><div><font face="arial, sans-serif"><font color="#444444">比如在IE上,使用谷歌拼音输入法,按数字键或输入中文,虽然都正常输入了,但都不会产生事件,而用智能abc输入中文没有事件,输入数字有事件;</font></font></div><div><font face="arial, sans-serif"><font color="#444444">而在Firefox上,使用谷歌拼音输入法,事件都是正常的。</font></font></div><br><div><font face="arial, sans-serif"><font color="#444444">小结:不同浏览器的键盘事件的处理有差异,同时中文输入法事件也有影响,并且还是二者交错的,比较复杂。</font></font></div><div><font face="arial, sans-serif"><font color="#444444">可以采用另一种方法绕开浏览器事件差异、中文输入和输入法兼容的影响,而实现我们原本的目的:</font></font></div><div><font face="arial, sans-serif"><font color="#444444">在浏览器上采用 timer 的方式,比如每隔0.5秒检查一下输入框中的内容变化,只根据内容的变化情况决定是否发送通知(据说Google搜索的自动补全就是这样做的)。</font></font></div><div><font face="arial, sans-serif"><font color="#444444">比如记录上次发送通知时输入框的内容(lastInput),每隔0.5秒查看当前内容(currentInput)与 lastInput 的长度之差的绝对值是否大于3。</font></font></div><br><div><font face="arial, sans-serif"><font color="#444444">参考资料:</font></font></div><div><font face="arial, sans-serif"><font color="#444444">JavaScript键盘事件测试小结:<a href="http://lifesinger.org/blog/wp-content/uploads/2008/08/keyboard_events.html" style="color:#2a5db0;text-decoration:none" target="_blank">http://lifesinger.org/blog/wp-content/uploads/2008/08/keyboard_events.html</a></font></font></div><div><a href="http://lifesinger.org/blog/wp-content/uploads/2008/08/keyboard_events.html" style="color:#2a5db0;text-decoration:none" target="_blank"></a><font face="arial, sans-serif"><font color="#444444">JavaScript Madness: Keyboard Events:<a href="http://unixpapa.com/js/key.html" style="color:#2a5db0;text-decoration:none" target="_blank">http://unixpapa.com/js/key.html</a></font></font></div><div><a href="http://unixpapa.com/js/key.html" style="color:#2a5db0;text-decoration:none" target="_blank"></a><font face="arial, sans-serif"><font color="#444444"><font face="arial, sans-serif, helvetica, tahoma"><font size="3">从谷歌的一个Bug说起,谈谈键盘事件的兼容性:</font></font><a href="http://www.javaeye.com/topic/233038" style="color:#2a5db0;text-decoration:none" target="_blank">http://www.javaeye.com/topic/233038</a></font></font></div><div><font color="#444444"><font face="arial"><font size="2">事件events <a href="http://www.quirksmode.org/dom/w3c_events.html" style="color:#64a038;text-decoration:none" target="_blank">http://www.quirksmode.org/dom/w3c_events.html</a><br>键盘keys <a href="http://www.quirksmode.org/dom/events/keys.html" style="color:#64a038;text-decoration:none" target="_blank">http://www.quirksmode.org/dom/events/keys.html</a></font></font></font></div><br>hgkhttp://www.blogger.com/profile/18248256147814166844noreply@blogger.com0tag:blogger.com,1999:blog-3051279638784476121.post-74858751849541720432010-06-19T21:44:00.009-07:002010-06-19T21:44:59.535-07:002010/4/15 XMPP服务器的SRV DNS配置<div><font color="#444444"><font face="arial, sans-serif"><font size="2">对XMPP客户端而言,首先查询 DNS 中的 SRV 记录如:_xmpp-client._TCP.example.com 。从而获得 xmpp</font></font></font></div><div><font color="#444444"><font face="arial, sans-serif"><font size="2"> server 的 hostname 和 port,然后使用这个进行连接。如果没有找到 SRV 记录,则会直接使用该 domain 和 默认端口进行连接。所以需要在DNS中设置 SRV 记录。</font></font></font></div><font size="2"><br></font><div><font color="#444444"><font face="arial, sans-serif"><font size="2">比如在Windows上可以使用 nslookup 命令查询 srv 的配置(linux就用 dig 命令):</font></font></font></div><div><font color="#444444"><font face="arial, sans-serif"><font size="2">nslookup -qt=SRV _xmpp-client._TCP.gmail.com</font></font></font></div><div><font color="#444444"><font face="arial, sans-serif"><font size="2">得到的是 Google Talk 服务的SRV配置,Google Talk 使用的xmpp hostname 是 talk.google.com。 </font></font></font></div><font size="2"><br></font><div><font face="arial, helvetica, sans-serif"><font color="#444444"><font size="3">参考资料:</font></font></font></div><div><font size="3"><font face="arial"><font color="#333333">tim yang 的 blog <font face="arial, verdana, helvetica, sans-serif"><font color="#000000"><a href="http://hi.baidu.com/jabber/blog/item/9e203d2afb62be3f5343c1d2.html" style="color:#64a038;text-decoration:none" target="_blank">XMPP/Jabber服务器的SRV DNS配置</a> </font></font></font></font></font></div><div><font face="arial, helvetica, sans-serif"><font color="#444444"><font size="3">SRV record 的定义 <a href="http://en.wikipedia.org/wiki/SRV_record" style="color:#64a038;text-decoration:none" target="_blank">http://en.wikipedia.org/wiki/SRV_record</a></font></font></font></div><div><font face="arial, helvetica, sans-serif"><font color="#444444"><font size="3">XMPP RFC 3920 中的关于 SRV 的说明 <a href="http://xmpp.org/rfcs/rfc3920.html#rfc.section.14.3" style="color:#64a038;text-decoration:none" target="_blank">http://xmpp.org/rfcs/rfc3920.html#rfc.section.14.3</a></font></font></font></div><div><font face="arial, helvetica, sans-serif"><font color="#444444"><font size="3">Google Talk 的XMPP Service说明 <a href="http://co%3Cwbr%3Ede.google.com/apis/talk/open_communications.html" style="color:#64a038;text-decoration:none" target="_blank">http://code.google.com/apis/talk/open_communications.html</a></font></font></font></div><div><font face="arial, helvetica, sans-serif"><font color="#444444"><font size="3">如果用 Smack api 作为xmpp client api,smack 中使用的是 org.jivesoftware.smack.util.DNSUtil 的方法按照上述原则执行查找的。</font></font></font></div><font size="3"><br></font><div><a href="http://img.ph.126.net/x9AZNfzaLsw0WjUP76SNNA==/3278057578773152701.png" style="color:#64a038;text-decoration:none" target="_blank"><img alt="XMPP服务器的SRV DNS配置 - hgk - 韩国恺的博客" src="http://img.ph.126.net/x9AZNfzaLsw0WjUP76SNNA==/3278057578773152701.png" style="border-color:initial;border-style:initial" title="XMPP服务器的SRV DNS配置 - hgk - 韩国恺的博客"></a></div><br>hgkhttp://www.blogger.com/profile/18248256147814166844noreply@blogger.com0