<?xml version="1.0" encoding="UTF-8" ?><rss version="2.0" xmlns:content="http://purl.org/Rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/"><channel><title>Crazy&#39;s Blog</title><link>http://www.i170.com/user/Crazy/Rss</link><description></description><language>zh-cn</language><pubDate>Thu, 09 Feb 2012 22:48:18  +0800</pubDate><generator>i170.com</generator><image><title>Crazy&#39;s Blog</title><url></url><link>http://www.i170.com/user/Crazy/Rss</link></image> <item><link>http://www.i170.com/Article/98647</link><title><![CDATA[关于中石油的两个爆笑搞怪作品]]></title><author>Crazy</author><category>轻松搞笑</category><pubDate>Sat, 26 Jan 2008 18:37:31  +0800</pubDate><description><![CDATA[<p><span>希望我认识的朋友们都没有买入中石油 ：）</span></p>
<p>&nbsp;</p>
<p><span><strong>工商银行写给中国石油的一封信</strong></span></p>
<p><span>石油兄鉴：
天下熙熙，皆为利来；天下攘攘，皆为利往。时当寒冬，正值丁亥猪年之末。屈指算来，石油兄现身江湖三月未满，其间却令中原大地惊涛骇浪，腥风血雨。弟工行旁观于侧，已存一腹之语，不吐不快，遂冒昧向兄鉴言。小弟不才，当年承蒙各位兄弟爱戴，惶坐江湖头把交椅。不敢沽势弄权，虽无诸葛之智，却有孔明之胆。泣血明志，偕各位兄弟，披荆斩棘，历尽艰辛，一路北上，誓于丁亥冬初，斩下八千大关，睹狂牛之真身，了多年之渴想。其心天可表，其意地可彰。石油兄正值弟攻城拔寨之紧要关头，偕大队人马自港空降于沪。兄之名头，江湖谁人不知，哪个不晓。弟本无将才，即退坐次席，愿为兄之左膀右臂，佐兄续成大业，实无怨言。弟千辛万苦所创江山，放眼望去，歌舞升平，众生居乐。兄来沪之日，也曾诏书天下，向江湖兄弟许下重诺，“买了中石油，生活不用愁；买了中石化，生活不用怕”之豪言壮语一时成为江湖美谈。然则兄自莅位次日之起，便心猿踢桃，意马难拴，备受空军首领之女诱惑，踏道义于足下，置明理于脑后，倒戈相向，骑熊南下。兄本美女立于前而面不改色，肉形坐于怀而无动于衷，何以做出如此亲者痛，仇者快之事。弟倍感心寒之际，也曾独自率亲北上，无奈祸不单行，外有异族花旗夺粮，内有叛徒平安抢草，实是屋漏连阴，有心无力。今斗胆向兄进言，望兄能浪子回头，挽江湖于熊口之下。弟
工行 酒后书于丁亥</span></p>
<p>&nbsp;</p>
<p><strong>我站在中石油48元之巅</strong></p>
<p>我站在中石油48元之巅<br>
眼含热泪向山下俯瞰<br>
看那高高耸立的井塔<br>
看那黑色石油井喷的壮观<br>
看那井架旁忙碌的股民<br>
看那庄家骗钱后得意的笑颜<br>
<br>
我站在中石油48元之巅<br>
感叹那董事长要回报祖国股民的肺腑之言<br>
虽说港股发行只有一元<br>
那也是肥水没流外人田<br>
因为大陆和香港的股民都是兄弟姐妹，血脉相连<br>
<br>
我站在中石油48元之巅<br>
回味着那铺天盖地各类媒体的宣传<br>
那是世界最大市值的公司<br>
亚洲企业最挣钱<br>
那是我们共和国的娇子<br>
垄断着国民经济的命脉------不可再生的石油资源<br>
<br>
我站在中石油48元之巅<br>
看周围同命相连的伙伴<br>
是他们以活命养家的血汗钱<br>
铸就了世界市值最大的航空母舰<br>
虽说无限风光在险峰<br>
但谁也不愿一直在这里站岗值班<br>
<br>
我站在中石油48元之巅<br>
眼望天空发出最后的呐喊<br>
什么时候让我回家<br>
什么时候让我下山<br>
<br>
我---要---回---家<br>
我---要---下---山</p>

]]></description><guid>http://www.i170.com/Article/98647</guid><trackback:ping>http://www.i170.com/Article/98647/trackback</trackback:ping><comments>http://www.i170.com/Article/98647#comment</comments><wfw:commentRss>http://www.i170.com/Article/98647/commentRss</wfw:commentRss></item> <item><link>http://www.i170.com/Article/94640</link><title><![CDATA[漂离北京]]></title><author>Crazy</author><category>生活感悟,心情随笔</category><pubDate>Mon, 26 Nov 2007 23:31:28  +0800</pubDate><description><![CDATA[<p>　　马上就要离开北京了，去一个我曾经很向往的城市——上海。现在，那里有着我的爱人。</p>
<p>
　　离别总是会让人伤感的，在北京也生活一年多了，在这里也交到了一些朋友，对这个城市慢慢地也有了感情，就这么离去竟然有了难以割舍的情怀。晚上翻看自己的博客，看到了一年前刚来北京时写的一篇文章<a href="http://www.i170.com/user/Crazy/Article_44607">《<span id="articleView_Title_span">漂在北京</span>》</a>，再想想自己在北京的这段生活，感触良多。</p>
<p>
　　北京，是国家的首都，是一个让人不由自主产生敬意的地方。但是当你在这里开始一段生活的时候，你会更留意这个城市的独有特色，我很喜欢在不同的城市都生活一段时间，是生活而不是当一个匆匆的过客，这样你才能深深的体会到这个城市的特色。对于北京我想借用一下北京交通广播的一个文案来描绘她，“北京的夏天，是白塔倒影里荡起的双桨，是故宫角楼旁绽放的晚霞，是后海水面上跳动的雨滴，是大街小巷中飞扬的裙角”，这是我很喜欢也是印象最深刻的一段描写北京的文字，将这个城市很有古典韵味的一面生动地描绘了出来，让人们在繁忙的都市生活中也能感受到一丝轻松惬意。</p>
<p>　　现在我要离开这个城市了，我会带走在这里的喜怒哀乐，留在以后慢慢的回味，谨以这篇文章纪念这段生活。</p>

]]></description><guid>http://www.i170.com/Article/94640</guid><trackback:ping>http://www.i170.com/Article/94640/trackback</trackback:ping><comments>http://www.i170.com/Article/94640#comment</comments><wfw:commentRss>http://www.i170.com/Article/94640/commentRss</wfw:commentRss></item> <item><link>http://www.i170.com/Article/91181</link><title><![CDATA[必须知道的社会生活中十二大著名法则]]></title><author>Crazy</author><category>社会思考</category><pubDate>Mon, 08 Oct 2007 21:04:47  +0800</pubDate><description><![CDATA[<p>
<strong>1、马太效应&nbsp;<br></strong>　　&nbsp;《新约马太福音》中有这样一个故事，一个国王远行前，交给3个仆人每人一锭银子，吩咐他们：“你们去做生意，等我回来时，再来见我。”国王回来时，第一个仆人说：“主人，你交给我们的一锭银子，我已赚了10锭。”于是国王奖励他10座城邑。第二个仆人报告说：“主人，你给我的一锭银子，我已赚了5锭。”于是国王例奖励了他5座城邑。第三个仆人报告说：“主人，你给我的一锭银子，我一直包在手巾里存著，我怕丢失，一直没有拿出来。”于是国王命令将第三个仆人的一锭银子也赏给第一个仆人，并且说：“凡是少的，就连他所有的也要夺过来。凡是多的，还要给他，叫他多多益善。”这就是马太效应。看看我们周围，就可以发现许多马太效应的例子。朋友多的人会借助频繁的交往得到更多的朋友；缺少朋友的人会一直孤独下去。金钱方面更是如此，即使投资回报率相同，一个比别人投资多10倍的人，收益也多10倍。<br>

　　这是个赢家通吃的社会，善用马太效应，赢家就是你。<br>
　　对企业经营发展而言，马太效应则告诉我们，要想在某一个领域保持优势，就必须在此领域迅速做大。当你成为某个领域的领头羊的时候，即使投资回报率相同，你也能更轻易的获得比弱小的同行更大的收益。而若没有实力迅速在某个领域做大，就要不停地寻找新的发展领域，才能保证获得较好的回报。</p>
<p class="partingline">[separator]</p>
<p><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
　　<br>
<strong>2、手表定理&nbsp;<br></strong>　　手表定理是指一个人有一只表时，可以知道现在是几点钟，而当他同时拥有两只表时却无法确定。两只表并不能告诉一个人更准确的时间，反而会让看表的人失去对准确时间的信心。你要做的就是选择其中较信赖的一只，尽力校准它，并以此作为你的标准，听从它的指引行事。记住尼采的话：“兄弟，如果你是幸运的，你只需有一种道德而不要贪多，这样，你过桥更容易些。”<br>

　　如果每个人都“选择你所爱，爱你所选择”，无论成败都可以心安理得。然而，困扰很多人的是：他们被“两只表”弄得无所，心身交瘁，不知自己该信仰哪一个，还有人在环境、他人的压力下，违心选择了自己并不喜欢的道路，为此而郁郁终生，即使取得了受人瞩目的成就，也体会不到成功的快乐。<br>

　　手表定理在企业经营管理方面给我们一种非常直观的启发，就是对同一个人或同一个组织的管理不能同时采用两种不同的方法，不能同时设置两个不同的目标。甚至每一个人不能由两个人来同时指挥，否则将使这个企业或这个人无所适从。手表定理所指的另一层含义在于每个人都不能同时挑选两种不同的价值观，否则，你的行为将陷于混乱。</p>
<p>&nbsp;</p>
<p><strong>3、不值得定律</strong><br>
　　不值得定律最直观的表述是：不值得做的事情，就不值得做好，这个定律似乎再简单不过了，但它的重要性却时时被人们疏忘。不值得定律反映出人们的一种心理，一个人如果从事的是一份自认为不值得做的事情，往往会保持冷嘲热讽，敷衍了事的态度。不仅成功率小，而且即使成功，也不会觉得有多大的成就感。<br>

　　哪些事值得做呢？一般而言，这取决于三个因素。<br>
　　1、价值观。只有符合我们价值观的事，我们才会满怀热情去做。<br>
　　2、个性和气质。一个人如果做一份与他的个性气质完全背离的工作，他是很难做好的，如一个好交往的人成了档案员，或一个害羞者不得不每天和不同的人打交道。<br>

　　3、现实的处境。同样一份工作，在不同的处境下去做，给我们的感受也是不同的。例如，在一家大公司，如果你最初做的是打杂跑腿的工作，你很可能认为是不值得的，可是，一旦你被提升为领班或部门经理，你就不会这样认为了。<br>

　　总结一下，值得做的工作是：符合我们的价值观，适合我们的个性与气质，并能让我们看到期望。如果你的工作不具备这三个因素，你就要考虑换一个更合适的工作，并努力做好它。<br>

　　因此，对个人来说，应在多种可供选择的奋斗目标及价值观中挑选一种，然后为之而奋斗。“选择你所爱的，爱你所选择的”，才可能激发我们的奋斗毅力，也才可以心安理得。而对一个企业或组织来说，则要很好地分析员工的性格特性，合理分配工作，如让成就欲较强的职工单独或牵头来完成具有一定风险和难度的工作，并在其完成时给予定时的肯定和赞扬；让依附欲较强的职工更多地参加到某个团体中共同工作；让权力欲较强的职工担任一个与之能力相适应的主管。同时要加强员工对企业目标的认同感，让员工感觉到自己所做的工作是值得的，这样才能激发职工的热情。<br>

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
　　<br>
<strong>4、彼得原理<br></strong>　　彼得原理是美国学者劳伦斯·彼得在对组织中人员晋升的相关现象研究后得出的一个结论；在各种组织中，由于习惯于对在某个等级上称职的人员进行晋升提拔，因而雇员总是趋向于晋升到其不称职的地位。彼得原理有时也被称为“向上爬”原理。这种现象在现实生活中无处不在：一名称职的教授被提升为大学校长后无法胜任；一个优秀的运动员被提升为主管体育的官员，而无所作为。<br>

　　对一个组织而言，一旦组织中的相当部分人员被推到了其不称职的级别，就会造成组织的人浮于事，效率低下，导致平庸者出人头地，发展停滞。因此，这就要求改变单纯的“根据贡献决定晋升”的企业员工晋升机制，不能因某个人在某一个岗位级别上干得很出色，就推断此人一定能够胜任更高一级的职务。要建立科学、合理的人员选聘机制，客观评价每一位职工的能力和水平，将职工安排到其可以胜任的岗位。不要把岗位晋升当成对职工的主要奖励方式，应建立更有效的奖励机制，更多地以加薪、休假等方式作为奖励手段。有时将一名职工晋升到一个其无法很好发挥才能的岗位，不仅不是对职工的奖励，反而使职工无法很好发挥才能，也给企业带来损失。<br>

　　对个人而言，虽然我们每个人都期待著不停地升职，但不要将往上爬作为自己的惟一动力。与其在一个无法完全胜任的岗位勉力支撑、无所适从，还不如找一个自己能游刃有余的岗位好好发挥自己的专长。<br>

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
　　<br>
<strong>5、零和游戏原理<br></strong>　　当你看到两位对弈者时，你就可以说他们正在玩“零和游戏”。因为在大多数情况下，总会有一个赢，一个输，如果我们把获胜计算为得1分，而输棋为-1分，那么，这两人得分之和就是：1
(-1)=0。<br>
　　这正是“零和游戏”的基本内容：游戏者有输有赢，一方所赢正是另一方所输，游戏的总成绩永远是零。零和游戏原理之所以广受关注，主要是因为人们发现在社会的方方面面都能发现与“零和游戏”类似的局面，胜利者的光荣后面往往隐藏著失败者的辛酸和苦涩。从个人到国家，从政治到经济，似乎无不验证了世界正是一个巨大的“零和游戏”场。这种理论认为，世界是一个封闭的系统，财富、资源、机遇都是有限的，个别人、个别地区和个别国家财富的增加必然意味著对其他人、其他地区和国家的掠夺，这是一个“邪恶进化论”式的弱肉强食的世界。<br>

　　但20世纪人类在经历了两次世界大战，经济的高速增长、科技进步、全球化以及日益严重的环境污染之后，“零和游戏”观念正逐渐被“双赢”观念所取代。人们开始认识到“利己”不一定要建立在“损人”的基础上。通过有效合作，皆大欢喜的结局是可能出现的。但从“零和游戏”走向“双赢”，要求各方要有真诚合作的精神和勇气，在合作中不要耍小聪明，不要总想占别人的小便宜，要遵守游戏规则，否则“双赢”的局面就不可能出现，最终吃亏的还是自己。<br>

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
　　<br>
<strong>6、华盛顿合作规律</strong><br>
　　华盛顿合作规律说的是：一个人敷衍了事，两个人互相推诿，三个人则永无成事之日。多少有点类似于我们“三个和尚”的故事。人与人的合作不是人力的简单相加，而是要复杂和微妙得多。在人与人的合作中，假定每个人的能力都为1，那么10个人的合作结果就有时比10大得多，有时甚至比1还要小。因为人不是静止的动物，而更像方向各异的能量，相推动时自然事半功倍，相互抵触时则一事无成。我们传统的管理理论中，对合作研究得并不多，最直观的反映就是，目前的大多数管理制度和行业都是致力于减少人力的无谓消耗，而非利用组织提高人的效能。换言之，不妨说管理的主要目的不是让每个人做到最好，而是避免内耗过多。21世纪将是一个合作的时代，值得庆幸的是，越来越多的人已经认识到真诚合作的重要性，正在努力学习合作。<br>

　　邦尼人力定律：一个人一分钟可以挖一个洞，60个人一秒种却挖不了一个洞。<br>
　　合作是一个问题，如何合作也是一个问题。</p>
<p>&nbsp;</p>
<p><strong>7、酒与污水定律</strong><br>
　　酒与污水定律是指，如果把一匙酒倒进一桶污水中，你得到的是一桶污水；如果把一匙污水倒进一桶酒中，你得到的还是一桶污水。几乎在任何组织里，都存在几个难弄的人物，他们存在的目的似乎就是为了把事情搞糟。他们到处搬弄是非，传播流言、破坏组织内部的和谐。最糟糕的是，他们像果箱里的烂苹果，如果你不及时处理，它会迅速传染，把果箱里其它苹果也弄烂，“烂苹果”的可怕之处在于它那惊人的破坏力。一个正直能干的人进入一个混乱的部门可能会被吞没，而一个人无德无才者能很快将一个高效的部门变成一盘散沙。组织系统往往是脆弱的，是建立在相互理解、妥协和容忍的基础上的，它很容易被侵害、被毒化。破坏者能力非凡的另一个重要原因在于，破坏总比建设容易。一个能工巧匠花费时日精心制作的陶瓷器，一头驴子一秒钟就能毁坏掉。如果拥有再多的能工巧匠，也不会有多少像样的工作成果。如果你的组织里有这样的一头驴子，你应该马上把它清除掉；如果你无力这样做，你就应该把它拴起来。<br>

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
　　<br>
<strong>8、水桶定律<br></strong>　　水桶定律是讲，一只水桶能装多少水，完全取决于它最短的那块木板。这就是说任何一个组织都可能面临的一个共同问题，即构成组织的各个部分往往决定了整个组织的水平。<br>

　　构成组织的各个部分往往是优劣不齐的，而劣质部分往往又决定整个组织的水平。<br>
　　“水桶定律”与“酒与污水定律”不同，后者讨论的是组织中的破坏力量，而“最短的木板”却是组织中有用的一个部分，只不过比其它部分差一些，你不能把它们当成烂苹果扔掉。强弱只是相对而言的，无法消除。问题在于你容忍这种弱点到什么程度。如果它严重到成为阻碍工作的瓶颈，就不得不有所动作。&nbsp;<br>

　　如果你在一个组织中，你应该：&nbsp;<br>
　　1、确保你不是最薄弱的部分；<br>
　　2、避免或减少这一薄弱环节对你成功的影响；<br>
　　3、如果不幸，你正处在这一环节中，你还可以采取有效的方法改进，或者转职去谋另一份工作。<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
　　<br>
<strong>9、蘑菇管理<br></strong>　　蘑菇管理是许多组织对待初出茅庐者的一种管理方法，初学者被置于阴暗的角落(不受重视的部门，或打杂跑腿的工作)，浇上一头大粪(无端的批评、指责、代人受过)，任其自生自灭(得不到必要的指导和提携)。相信很多人都有这样一段“蘑菇”的经历，但这不一定是什么坏事，尤其是当一切都刚刚开始的时候，当上几天“蘑菇”，能够消除我们很多不切实际的幻想，让我们更加接近现实，看问题也更加实际，而对一个组织而言，一般地新进的人员都是一视同仁，从起薪到工作都不会有大的差别。无论你是多么优秀的人才，在刚开始的时候都只能从最简单的事情做起，“蘑菇”的经历对于成长中的年轻人来说，是羽化前必须经历的一步。所以，如何高效率地走过生命中的这一段，从中尽可能吸取经验，成熟起来，并树立良好的值得信赖的个人形象，是每个刚入社会的年轻人必须面对的课题。<br>

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
　　<br>
<strong>10、奥卡姆剃刀定律</strong><br>
　　如果你认为只有焦头烂额、忙忙碌碌地工作才可能取得成功，那么，你错了。<br>
　　事情总是朝著复杂的方向发展，复杂会造成浪费，而效能则来自于单纯。在你做过的事情中可能绝大部分是毫无意义的，真正有效的活动只是其中的一小部分，而它们通常隐含于繁杂的事物中。找到关键的部分，去掉多余的活动，成功并不那么复杂。<br>

　　奥卡姆剃刀：如无必要，勿增实体。<br>
　　12世纪，英国奥卡姆的威廉对无休无止的关于“共相”、“本质”之类的争吵感到厌倦，主张唯名论，只承认确实存在的东西，认为那些空洞无物的普遍性要领都是无用的累赘，应当被无情地“剃除”。他主张，“如无必要，勿增实体。”这就是常说的“奥卡姆剃刀”。这把剃刀曾使很多人感到威胁，被认为是异端邪说，威廉本人也受到伤害。然而，这并未损害这把刀的锋利，相反，经过数百年越来越快，并早已超越了原来狭窄的领域而具有广泛的、丰富的、深刻的意义。<br>

　　奥卡姆剃刀定律在企业管理中可进一步深化为简单与复杂定律：把事情变复杂很简单，把事情变简单很复杂。这个定律要求，我们在处理事情时，要把握事情的主要实质，把握主流，解决最根本的问题。尤其要顺应自然，不要把事情人为地复杂化，这样才能把事情处理好。<br>

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
　　<br>
<strong>11、二八法则</strong><br>
　　你所完成的工作里80%的成果，来自于你20%的付出；而80%的付出，只换来20%的成果<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
　　<br>
<strong>12、钱的问题</strong><br>
　　当某人告诉你：“不是钱，而是原则问题”时，十有八九就是钱的问题。<br>
　　照一般的说法，金钱是价值的尺度，交换的媒介，财富的贮藏。但是这种说法忽略了它的另一面，它令人陶醉、令人疯狂、令人激动的一面，也撇开了爱钱的心理不谈。<br>

　　关于金钱的本质、作用和功过，从古到今，人们已经留下了无数精辟深刻的格言和妙语。我们常会看到，人们为钱而兴奋，努力赚钱，用财富的画面挑逗自己。金钱对世界的秩序以及我们的生活产生的影响是巨大的、广泛的，这种影响有时是潜在的，我们往往意识不到它的作用如此巨大，然而奇妙的是：它完全是人类自己创造的。致富的驱动力并不是起源于生物学上的需要，动物生活中也找不到任何相同的现象。它不能顺应基本的目标，不能满足根本的需求……<br>

　　的确，“致富”的定义就是获得超过自己需要的东西。然而这个看起来漫无目标的驱动力却是人类最强大的力量，人类为金钱而互相伤害，远超过其他原因。</p>

]]></description><guid>http://www.i170.com/Article/91181</guid><trackback:ping>http://www.i170.com/Article/91181/trackback</trackback:ping><comments>http://www.i170.com/Article/91181#comment</comments><wfw:commentRss>http://www.i170.com/Article/91181/commentRss</wfw:commentRss></item> <item><link>http://www.i170.com/Article/89058</link><title><![CDATA[关于框架应用的理解]]></title><author>Crazy</author><category>技术研究</category><pubDate>Thu, 13 Sep 2007 13:51:34  +0800</pubDate><description><![CDATA[<p>在PHPChina看到了这样一篇文章《<a href=
"http://www.phpchina.com/viewthread_36014.html">框架、模板化开发真的那么重要么？</a>》，后面还有一些有内容的回复，我也回复了一些文字，在这里也留一份。</p>
<p>&nbsp;</p>
<p>　　我的理解，框架的用途一个是提高效率，另外一个就是方便协同工作。<br>
　　每一个有经验的程序员都会有一个程序集，我感觉这就算是一个框架，一个简单的框架。当你需要实现一个经常用的功能的时候，就会去调用这个程序集，而你开发一个项目的时候也会有一个自己的模式，使用框架不也就是这样一些事情吗？<br>

　　但是使用自己的框架，除非你是一个高高手，否则我想安全和性能方面的事情你不可能做得很完善，至少为了他们你要花费大量的精力。而使用一个发布的框架，特别是经过开源社区千锤百炼的框架，不知道大家什么想法，但是我是会很安心的使用，不用担心安全和性能。好的框架也会有完善的插件接口，可以很好的整合进自己的一些改善程序。<br>

　　以上的论述都是说单兵作战的，国内的程序员单兵作战都是很强的，所以他们可能看不上别人的框架，但是当一个团队要协作的时候，一个大家都熟悉的框架应该是很好的帮手，大的公司有实力去开发自己的框架，制定自己的文档规范，那我们小团队怎么办？最好的方法就是用现成的，“别去重复的制造轮子”我想不光是写“Hello
World”的时候需要注意。中国程序员的团队协作很差已经是一个人人诟病的恶习了，希望我们大家能努力除掉这个恶名！</p>

]]></description><guid>http://www.i170.com/Article/89058</guid><trackback:ping>http://www.i170.com/Article/89058/trackback</trackback:ping><comments>http://www.i170.com/Article/89058#comment</comments><wfw:commentRss>http://www.i170.com/Article/89058/commentRss</wfw:commentRss></item> <item><link>http://www.i170.com/Article/71903</link><title><![CDATA[秀一下我做的香辣虾]]></title><author>Crazy</author><category>漂在北京,我爱美食</category><pubDate>Mon, 25 Jun 2007 20:23:49  +0800</pubDate><description><![CDATA[<p>
今天心血来潮，在超市买了一斤虾，按照自己以前转的一篇菜谱做香辣虾，自己又加了一些辅料，做出来感觉已经可以和专业的香辣虾店相比了，hoho~上桌后三个人一扫而光，很有成就感，现贴出照片来秀一下。</p>
<p>&nbsp;</p>
<p>菜谱的链接：<a href=
"http://www.i170.com/user/Crazy/Article_30501">http://www.i170.com/user/Crazy/Article_30501</a></p>
<p>&nbsp;</p>
<p><img alt="" src=
"http://www.i170.com/Attach/BFACCDF6-1DE4-417C-9785-868557AA96DE"></p>
<p><img alt="" src=
"http://www.i170.com/Attach/07FFEF04-D7F8-4063-837D-CDD2C86812E4"></p>

]]></description><guid>http://www.i170.com/Article/71903</guid><trackback:ping>http://www.i170.com/Article/71903/trackback</trackback:ping><comments>http://www.i170.com/Article/71903#comment</comments><wfw:commentRss>http://www.i170.com/Article/71903/commentRss</wfw:commentRss></item> <item><link>http://www.i170.com/Article/71663</link><title><![CDATA[798 —— 大山子艺术区]]></title><author>Crazy</author><category>漂在北京,心情随笔</category><pubDate>Sat, 23 Jun 2007 20:45:52  +0800</pubDate><description><![CDATA[<p>
这几天舅舅从西安来北京出差，他的朋友约他一起去798参加一个影展的发布会，我也跟着去凑了一下热闹，虽然对有些艺术不会欣赏，但是对那个地方还是很喜欢的，随手拍了几张自己感觉有特色的照片。</p>
<p><img height="450" alt="" width="600" src=
"http://www.i170.com/Attach/29A033C7-D951-4FA4-A0DA-C3D5C303C956"></p>
<p class="partingline">[separator]</p>
<p><img height="450" alt="" width="600" src=
"http://www.i170.com/Attach/BC697830-FBE9-4409-BD95-7DA12D2A0A4D"></p>
<p><img height="450" alt="" width="600" src=
"http://www.i170.com/Attach/E7C67D58-D941-45DC-AEE8-A9B1032A4BE3"></p>
<p><img height="450" alt="" width="600" src=
"http://www.i170.com/Attach/3142D719-4001-42B6-B15E-E3E044F307C8"></p>
<p><img alt="" src=
"http://www.i170.com/Attach/CC919FDB-53AD-46BE-B0CD-09B1DB43F0B1"></p>

]]></description><guid>http://www.i170.com/Article/71663</guid><trackback:ping>http://www.i170.com/Article/71663/trackback</trackback:ping><comments>http://www.i170.com/Article/71663#comment</comments><wfw:commentRss>http://www.i170.com/Article/71663/commentRss</wfw:commentRss></item> <item><link>http://www.i170.com/Article/70611</link><title><![CDATA[今天我用双脚丈量了后海 -_-!!!]]></title><author>Crazy</author><category>漂在北京,心情随笔,轻松搞笑</category><pubDate>Sat, 16 Jun 2007 00:13:48  +0800</pubDate><description><![CDATA[<p>
　　一连在房子里闷了几天，周末了准备出去散散心，来北京半年多了还几乎没有逛过北京城呢。在同学的建议下准备晚上去后海玩，早早就听说了那里的酒吧很有名，名气据说已经盖过三里屯了。而同学还告诉我，那里有个“九门小吃”是很不错的，建议我去尝尝。</p>
<p>
　　怀着很好的心情出发了，不过路不怎么熟，坐过站了，都坐到地安门的南边了，只好往回走了，就这样开始了我的“征途”。从南边去后海当然要先经过前海了，而我打听到“九门小吃”是在后海的北边，对这段路也没有概念，那就走着去吧。最后事实证明这真是决策失误啊，走到腿都细了，在我快绝望甚至怀疑指路的人在骗我时，总算看到一个路牌上面有“九门小吃”，不过之后又走了15分钟才找到了这家店。都已经走得没有胃口了，应该是已经饿过了，不过既然来了总是要尝尝的，还好这里的名气不是吹出来的，味道还是不错的，我想在我状态好的情况下应该会更享受一些。以后来朋友了这个地方还是值得带他们来品尝的。</p>
<p>
　　从“九门小吃”出来以后，发现已经围着前海、后海走了半圈了，随决定继续走下去，围着前海、后海转一圈也不枉此行了，顺便了解一下沿路的酒吧，为下次来做好准备，就这样我坚持着用双脚丈量了后海，那里的风景是没顾得上欣赏了，不过偶尔驻足观看还是有很惬意的感受的，住在周边胡同里的居民真是让人羡慕，希望下次再来后可以写出一篇抒情的散文来，嘿嘿~</p>

]]></description><guid>http://www.i170.com/Article/70611</guid><trackback:ping>http://www.i170.com/Article/70611/trackback</trackback:ping><comments>http://www.i170.com/Article/70611#comment</comments><wfw:commentRss>http://www.i170.com/Article/70611/commentRss</wfw:commentRss></item> <item><link>http://www.i170.com/Article/63475</link><title><![CDATA[[转]Memcached深度分析]]></title><author>Crazy</author><category>技术研究,LAMP</category><pubDate>Thu, 19 Apr 2007 01:03:37  +0800</pubDate><description><![CDATA[<p>来源：<a href=
"http://www.54np.com/docs/mc.html">http://www.54np.com/docs/mc.html</a></p>
<p><br>
Memcached是danga.com（运营LiveJournal的技术团队）开发的一套分布式内存对象缓存系统，用于在动态系统中减少数据库负载，提升性能。关于这个东西，相信很多人都用过，本文意在通过对memcached的实现及代码分析，获得对这个出色的开源软件更深入的了解，并可以根据我们的需要对其进行更进一步的优化。末了将通过对BSM_Memcache扩展的分析，加深对memcached的使用方式理解。<br>
<br>
本文的部分内容可能需要比较好的数学基础作为辅助。</p>
<p class="partingline">[separator]</p>
<p><br>
<br>
<strong>◎Memcached是什么</strong><br>
<br>
在阐述这个问题之前，我们首先要清楚它“不是什么”。很多人把它当作和SharedMemory那种形式的存储载体来使用，虽然memcached使用了同样的“Key=&gt;Value”方式组织数据，但是它和共享内存、APC等本地缓存有非常大的区别。Memcached是分布式的，也就是说它不是本地的。它基于网络连接（当然它也可以使用localhost）方式完成服务，本身它是一个独立于应用的程序或守护进程（Daemon方式）。<br>
<br>
Memcached使用libevent库实现网络连接服务，理论上可以处理无限多的连接，但是它和Apache不同，它更多的时候是面向稳定的持续连接的，所以它实际的并发能力是有限制的。在保守情况下memcached的最大同时连接数为200，这和Linux线程能力有关系，这个数值是可以调整的。关于libevent可以参考相关文档。
Memcached内存使用方式也和APC不同。APC是基于共享内存和MMAP的，memcachd有自己的内存分配算法和管理方式，它和共享内存没有关系，也没有共享内存的限制，通常情况下，每个memcached进程可以管理2GB的内存空间，如果需要更多的空间，可以增加进程数。<br>
<br>
<strong>◎Memcached适合什么场合</strong><br>
<br>
在很多时候，memcached都被滥用了，这当然少不了对它的抱怨。我经常在论坛上看见有人发贴，类似于“如何提高效率”，回复是“用memcached”，至于怎么用，用在哪里，用来干什么一句没有。memcached不是万能的，它也不是适用在所有场合。<br>
<br>
Memcached是“分布式”的内存对象缓存系统，那么就是说，那些不需要“分布”的，不需要共享的，或者干脆规模小到只有一台服务器的应用，memcached不会带来任何好处，相反还会拖慢系统效率，因为网络连接同样需要资源，即使是UNIX本地连接也一样。
在我之前的测试数据中显示，memcached本地读写速度要比直接PHP内存数组慢几十倍，而APC、共享内存方式都和直接数组差不多。可见，如果只是本地级缓存，使用memcached是非常不划算的。<br>
<br>
Memcached在很多时候都是作为数据库前端cache使用的。因为它比数据库少了很多SQL解析、磁盘操作等开销，而且它是使用内存来管理数据的，所以它可以提供比直接读取数据库更好的性能，在大型系统中，访问同样的数据是很频繁的，memcached可以大大降低数据库压力，使系统执行效率提升。另外，memcached也经常作为服务器之间数据共享的存储媒介，例如在SSO系统中保存系统单点登陆状态的数据就可以保存在memcached中，被多个应用共享。<br>
<br>
需要注意的是，memcached使用内存管理数据，所以它是易失的，当服务器重启，或者memcached进程中止，数据便会丢失，所以memcached不能用来持久保存数据。很多人的错误理解，memcached的性能非常好，好到了内存和硬盘的对比程度，其实memcached使用内存并不会得到成百上千的读写速度提高，它的实际瓶颈在于网络连接，它和使用磁盘的数据库系统相比，好处在于它本身非常“轻”，因为没有过多的开销和直接的读写方式，它可以轻松应付非常大的数据交换量，所以经常会出现两条千兆网络带宽都满负荷了，memcached进程本身并不占用多少CPU资源的情况。<br>
<br>
<strong>◎Memcached的工作方式</strong><br>
<br>
以下的部分中，读者最好能准备一份memcached的源代码。<br>
<br>
Memcached是传统的网络服务程序，如果启动的时候使用了-d参数，它会以守护进程的方式执行。创建守护进程由daemon.c完成，这个程序只有一个daemon函数，这个函数很简单（如无特殊说明，代码以1.2.1为准）：<br>
<br></p>
<div class="smalltxt" style=
"FONT-WEIGHT: bold; MARGIN-LEFT: 2em; MARGIN-RIGHT: 2em">
<div style="FLOAT: left">CODE:</div>
<div style="FLOAT: right; TEXT-ALIGN: right">[Copy to
clipboard]</div>
</div>
<div class="altbg2" id="code0" style=
"CLEAR: both; BORDER-RIGHT: #f1f1f1 1px solid; PADDING-RIGHT: 10px; BORDER-TOP: #f1f1f1 1px solid; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; MARGIN: 3px 2em 2em; BORDER-LEFT: #f1f1f1 1px solid; WORD-BREAK: break-all; PADDING-TOP: 5px; BORDER-BOTTOM: #f1f1f1 1px solid">
#include &lt;fcntl.h&gt;<br>
#include &lt;stdlib.h&gt;<br>
#include &lt;unistd.h&gt;<br>
<br>
int<br>
daemon(nochdir, noclose)<br>
&nbsp; &nbsp; int nochdir, noclose;<br>
{<br>
&nbsp; &nbsp; int fd;<br>
<br>
&nbsp; &nbsp; switch (fork()) {<br>
&nbsp; &nbsp; case -1:<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;return (-1);<br>
&nbsp; &nbsp; case 0:<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;break;&nbsp;&nbsp;<br>
&nbsp; &nbsp; default:<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;_exit(0);<br>
&nbsp; &nbsp; }<br>
<br>
&nbsp; &nbsp; if (setsid() == -1)<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;return (-1);<br>
<br>
&nbsp; &nbsp; if (!nochdir)<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;(void)chdir("/");<br>
<br>
&nbsp; &nbsp; if (!noclose &amp;&amp; (fd = open("/dev/null",
O_RDWR, 0)) != -1) {<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;(void)dup2(fd,
STDIN_FILENO);<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;(void)dup2(fd,
STDOUT_FILENO);<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;(void)dup2(fd,
STDERR_FILENO);<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;if (fd &gt;
STDERR_FILENO)<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;
&nbsp;(void)close(fd);<br>
&nbsp; &nbsp; }<br>
&nbsp; &nbsp; return (0);<br>
}</div>
这个函数 fork 了整个进程之后，父进程就退出，接着重新定位 STDIN 、 STDOUT 、 STDERR 到空设备，
daemon 就建立成功了。<br>
<br>
Memcached 本身的启动过程，在 memcached.c 的 main 函数中顺序如下：<br>
<br>
1 、调用 settings_init() 设定初始化参数<br>
2 、从启动命令中读取参数来设置 setting 值<br>
3 、设定 LIMIT 参数<br>
4 、开始网络 socket 监听（如果非 socketpath 存在）（ 1.2 之后支持 UDP 方式）<br>
5 、检查用户身份（ Memcached 不允许 root 身份启动）<br>
6 、如果有 socketpath 存在，开启 UNIX 本地连接（Sock 管道）<br>
7 、如果以 -d 方式启动，创建守护进程（如上调用 daemon 函数）<br>
8 、初始化 item 、 event 、状态信息、 hash 、连接、 slab<br>
9 、如设置中 managed 生效，创建 bucket 数组<br>
10 、检查是否需要锁定内存页<br>
11 、初始化信号、连接、删除队列<br>
12 、如果 daemon 方式，处理进程 ID<br>
13 、event 开始，启动过程结束， main 函数进入循环。<br>
<br>
在 daemon 方式中，因为 stderr 已经被定向到黑洞，所以不会反馈执行中的可见错误信息。<br>
<br>
memcached.c 的主循环函数是 drive_machine ，传入参数是指向当前的连接的结构指针，根据 state
成员的状态来决定动作。<br>
<br>
Memcached 使用一套自定义的协议完成数据交换，它的 protocol 文档可以参考：
http://code.sixapart.com/svn/memcached/trunk/server/doc/protocol.txt<br>
<br>
在API中，换行符号统一为\r\n<br>
<br>
<strong>◎Memcached的内存管理方式</strong><br>
<br>
Memcached有一个很有特色的内存管理方式，为了提高效率，它使用预申请和分组的方式管理内存空间，而并不是每次需要写入数据的时候去malloc，删除数据的时候free一个指针。Memcached使用slab-&gt;chunk的组织方式管理内存。<br>
<br>
1.1和1.2的slabs.c中的slab空间划分算法有一些不同，后面会分别介绍。<br>
<br>
Slab可以理解为一个内存块，一个slab是memcached一次申请内存的最小单位，在memcached中，一个slab的大小默认为1048576字节（1MB），所以memcached都是整MB的使用内存。每一个slab被划分为若干个chunk，每个chunk里保存一个item，每个item同时包含了item结构体、key和value（注意在memcached中的value是只有字符串的）。slab按照自己的id分别组成链表，这些链表又按id挂在一个slabclass数组上，整个结构看起来有点像二维数组。slabclass的长度在1.1中是21，在1.2中是200。<br>
<br>
slab有一个初始chunk大小，1.1中是1字节，1.2中是80字节，1.2中有一个factor值，默认为1.25<br>
<br>
在1.1中，chunk大小表示为初始大小*2^n，n为classid，即：id为0的slab，每chunk大小1字节，id为1的slab，每chunk大小2字节，id为2的slab，每chunk大小4字节……id为20的slab，每chunk大小为1MB，就是说id为20的slab里只有一个chunk：<br>
<br>
<div class="smalltxt" style=
"FONT-WEIGHT: bold; MARGIN-LEFT: 2em; MARGIN-RIGHT: 2em">
<div style="FLOAT: left">CODE:</div>
<div style="FLOAT: right; TEXT-ALIGN: right">[Copy to
clipboard]</div>
</div>
<div class="altbg2" id="code1" style=
"CLEAR: both; BORDER-RIGHT: #f1f1f1 1px solid; PADDING-RIGHT: 10px; BORDER-TOP: #f1f1f1 1px solid; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; MARGIN: 3px 2em 2em; BORDER-LEFT: #f1f1f1 1px solid; WORD-BREAK: break-all; PADDING-TOP: 5px; BORDER-BOTTOM: #f1f1f1 1px solid">
void slabs_init(size_t limit) {<br>
&nbsp; &nbsp; int i;<br>
&nbsp; &nbsp; int size=1;<br>
<br>
&nbsp; &nbsp; mem_limit = limit;<br>
&nbsp; &nbsp; for(i=0; i&lt;=POWER_LARGEST; i++, size*=2) {<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;slabclass[i].size = size;<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;slabclass[i].perslab =
POWER_BLOCK / size;<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;slabclass[i].slots = 0;<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;slabclass[i].sl_curr =
slabclass[i].sl_total = slabclass[i].slabs = 0;<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;slabclass[i].end_page_ptr =
0;<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;slabclass[i].end_page_free =
0;<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;slabclass[i].slab_list =
0;<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;slabclass[i].list_size =
0;<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;slabclass[i].killing = 0;<br>
&nbsp; &nbsp; }<br>
<br>
&nbsp; &nbsp; /* for the test suite:&nbsp;&nbsp;faking of how much
we've already malloc'd */<br>
&nbsp; &nbsp; {<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;char *t_initial_malloc =
getenv("T_MEMD_INITIAL_MALLOC");<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;if (t_initial_malloc) {<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;mem_malloced =
atol(getenv("T_MEMD_INITIAL_MALLOC"));<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;}<br>
&nbsp; &nbsp; }<br>
<br>
&nbsp; &nbsp; /* pre-allocate slabs by default, unless the
environment variable<br>
&nbsp; &nbsp;&nbsp; &nbsp; for testing is set to something non-zero
*/<br>
&nbsp; &nbsp; {<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;char *pre_alloc =
getenv("T_MEMD_SLABS_ALLOC");<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;if (!pre_alloc ||
atoi(pre_alloc)) {<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;
&nbsp;slabs_preallocate(limit / POWER_BLOCK);<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;}<br>
&nbsp; &nbsp; }<br>
}</div>
在1.2中，chunk大小表示为初始大小*f^n，f为factor，在memcached.c中定义，n为classid，同时，201个头不是全部都要初始化的，因为factor可变，初始化只循环到计算出的大小达到slab大小的一半为止，而且它是从id1开始的，即：id为1的slab，每chunk大小80字节，id为2的slab，每chunk大小80*f，id为3的slab，每chunk大小80*f^2，初始化大小有一个修正值CHUNK_ALIGN_BYTES，用来保证n-byte排列
（保证结果是CHUNK_ALIGN_BYTES的整倍数）。这样，在标准情况下，memcached1.2会初始化到id40，这个slab中每个chunk大小为504692，每个slab中有两个chunk。最后，slab_init函数会在最后补足一个id41，它是整块的，也就是这个slab中只有一个1MB大的chunk：<br>
<br>
<div class="smalltxt" style=
"FONT-WEIGHT: bold; MARGIN-LEFT: 2em; MARGIN-RIGHT: 2em">
<div style="FLOAT: left">CODE:</div>
<div style="FLOAT: right; TEXT-ALIGN: right">[Copy to
clipboard]</div>
</div>
<div class="altbg2" id="code2" style=
"CLEAR: both; BORDER-RIGHT: #f1f1f1 1px solid; PADDING-RIGHT: 10px; BORDER-TOP: #f1f1f1 1px solid; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; MARGIN: 3px 2em 2em; BORDER-LEFT: #f1f1f1 1px solid; WORD-BREAK: break-all; PADDING-TOP: 5px; BORDER-BOTTOM: #f1f1f1 1px solid">
void slabs_init(size_t limit, double factor) {<br>
&nbsp; &nbsp; int i = POWER_SMALLEST - 1;<br>
&nbsp; &nbsp; unsigned int size = sizeof(item) +
settings.chunk_size;<br>
<br>
&nbsp; &nbsp; /* Factor of 2.0 means use the default memcached
behavior */<br>
&nbsp; &nbsp; if (factor == 2.0 &amp;&amp; size &lt; 128)<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;size = 128;<br>
<br>
&nbsp; &nbsp; mem_limit = limit;<br>
&nbsp; &nbsp; memset(slabclass, 0, sizeof(slabclass));<br>
<br>
&nbsp; &nbsp; while (++i &lt; POWER_LARGEST &amp;&amp; size &lt;=
POWER_BLOCK / 2) {<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;/* Make sure items are always
n-byte aligned */<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;if (size %
CHUNK_ALIGN_BYTES)<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;size +=
CHUNK_ALIGN_BYTES - (size % CHUNK_ALIGN_BYTES);<br>
<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;slabclass[i].size = size;<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;slabclass[i].perslab =
POWER_BLOCK / slabclass[i].size;<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;size *= factor;<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;if (settings.verbose &gt; 1)
{<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;fprintf(stderr,
"slab class %3d: chunk size %6d perslab %5d\n",<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;i, slabclass[i].size,
slabclass[i].perslab);<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;}&nbsp; &nbsp;&nbsp;
&nbsp;<br>
&nbsp; &nbsp; }<br>
<br>
&nbsp; &nbsp; power_largest = i;<br>
&nbsp; &nbsp; slabclass[power_largest].size = POWER_BLOCK;<br>
&nbsp; &nbsp; slabclass[power_largest].perslab = 1;<br>
<br>
&nbsp; &nbsp; /* for the test suite:&nbsp;&nbsp;faking of how much
we've already malloc'd */<br>
&nbsp; &nbsp; {<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;char *t_initial_malloc =
getenv("T_MEMD_INITIAL_MALLOC");<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;if (t_initial_malloc) {<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;mem_malloced =
atol(getenv("T_MEMD_INITIAL_MALLOC"));<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;}&nbsp; &nbsp;&nbsp;
&nbsp;<br>
<br>
&nbsp; &nbsp; }<br>
<br>
#ifndef DONT_PREALLOC_SLABS<br>
&nbsp; &nbsp; {<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;char *pre_alloc =
getenv("T_MEMD_SLABS_ALLOC");<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;if (!pre_alloc ||
atoi(pre_alloc)) {<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;
&nbsp;slabs_preallocate(limit / POWER_BLOCK);<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;}<br>
&nbsp; &nbsp; }<br>
#endif<br>
}</div>
由上可以看出，memcached的内存分配是有冗余的，当一个slab不能被它所拥有的chunk大小整除时，slab尾部剩余的空间就被丢弃了，如id40中，两个chunk占用了1009384字节，这个slab一共有1MB，那么就有39192字节被浪费了。<br>
<br>
Memcached使用这种方式来分配内存，是为了可以快速的通过item长度定位出slab的classid，有一点类似hash，因为item的长度是可以计算的，比如一个item的长度是300字节，在1.2中就可以得到它应该保存在id7的slab中，因为按照上面的计算方法，id6的chunk大小是252字节，id7的chunk大小是316字节，id8的chunk大小是396字节，表示所有252到316字节的item都应该保存在id7中。同理，在1.1中，也可以计算得到它出于256和512之间，应该放在chunk_size为512的id9中(32位系统）。<br>
<br>
Memcached初始化的时候，会初始化slab（前面可以看到，在main函数中调用了slabs_init()）。它会在slabs_init()中检查一个常量DONT_PREALLOC_SLABS，如果这个没有被定义，说明使用预分配内存方式初始化slab，这样在所有已经定义过的slabclass中，每一个id创建一个slab。这样就表示，1.2在默认的环境中启动进程后要分配41MB的slab空间，在这个过程里，memcached的第二个内存冗余发生了，因为有可能一个id根本没有被使用过，但是它也默认申请了一个slab，每个slab会用掉1MB内存<br>
<br>
当一个slab用光后，又有新的item要插入这个id，那么它就会重新申请新的slab，申请新的slab时，对应id的slab链表就要增长，这个链表是成倍增长的，在函数grow_slab_list函数中，这个链的长度从1变成2，从2变成4，从4变成8……：<br>
<br>
<div class="smalltxt" style=
"FONT-WEIGHT: bold; MARGIN-LEFT: 2em; MARGIN-RIGHT: 2em">
<div style="FLOAT: left">CODE:</div>
<div style="FLOAT: right; TEXT-ALIGN: right">[Copy to
clipboard]</div>
</div>
<div class="altbg2" id="code3" style=
"CLEAR: both; BORDER-RIGHT: #f1f1f1 1px solid; PADDING-RIGHT: 10px; BORDER-TOP: #f1f1f1 1px solid; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; MARGIN: 3px 2em 2em; BORDER-LEFT: #f1f1f1 1px solid; WORD-BREAK: break-all; PADDING-TOP: 5px; BORDER-BOTTOM: #f1f1f1 1px solid">
static int grow_slab_list (unsigned int id) {<br>
&nbsp; &nbsp; slabclass_t *p = &amp;slabclass[id];<br>
&nbsp; &nbsp; if (p-&gt;slabs == p-&gt;list_size) {<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;size_t new_size
=&nbsp;&nbsp;p-&gt;list_size ? p-&gt;list_size * 2 : 16;<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;void *new_list =
realloc(p-&gt;slab_list, new_size*sizeof(void*));<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;if (new_list == 0) return
0;<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;p-&gt;list_size =
new_size;<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;p-&gt;slab_list =
new_list;<br>
&nbsp; &nbsp; }<br>
&nbsp; &nbsp; return 1;<br>
}</div>
在定位item时，都是使用slabs_clsid函数，传入参数为item大小，返回值为classid，由这个过程可以看出，memcached的第三个内存冗余发生在保存item的过程中，item总是小于或等于chunk大小的，当item小于chunk大小时，就又发生了空间浪费。<br>
<br>
<strong>◎Memcached的NewHash算法</strong><br>
<br>
Memcached的item保存基于一个大的hash表，它的实际地址就是slab中的chunk偏移，但是它的定位是依靠对key做hash的结果，在primary_hashtable中找到的。在assoc.c和items.c中定义了所有的hash和item操作。<br>
<br>
Memcached使用了一个叫做NewHash的算法，它的效果很好，效率也很高。1.1和1.2的NewHash有一些不同，主要的实现方式还是一样的，1.2的hash函数是经过整理优化的，适应性更好一些。<br>
<br>
NewHash的原型参考：http://burtleburtle.net/bob/hash/evahash.html。数学家总是有点奇怪，呵呵～<br>
<br>
为了变换方便，定义了u4和u1两种数据类型，u4就是无符号的长整形，u1就是无符号char(0-255)。<br>
<br>
具体代码可以参考1.1和1.2源码包。<br>
<br>
注意这里的hashtable长度，1.1和1.2也是有区别的，1.1中定义了HASHPOWER常量为20，hashtable表长为hashsize(HASHPOWER)，就是4MB（hashsize是一个宏，表示1右移n位），1.2中是变量16，即hashtable表长65536：<br>
<br>
<div class="smalltxt" style=
"FONT-WEIGHT: bold; MARGIN-LEFT: 2em; MARGIN-RIGHT: 2em">
<div style="FLOAT: left">CODE:</div>
<div style="FLOAT: right; TEXT-ALIGN: right">[Copy to
clipboard]</div>
</div>
<div class="altbg2" id="code4" style=
"CLEAR: both; BORDER-RIGHT: #f1f1f1 1px solid; PADDING-RIGHT: 10px; BORDER-TOP: #f1f1f1 1px solid; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; MARGIN: 3px 2em 2em; BORDER-LEFT: #f1f1f1 1px solid; WORD-BREAK: break-all; PADDING-TOP: 5px; BORDER-BOTTOM: #f1f1f1 1px solid">
typedef&nbsp;&nbsp;unsigned
long&nbsp;&nbsp;int&nbsp;&nbsp;ub4;&nbsp; &nbsp;/* unsigned 4-byte
quantities */<br>
typedef&nbsp;&nbsp;unsigned&nbsp; &nbsp;&nbsp; &nbsp; char
ub1;&nbsp; &nbsp;/* unsigned 1-byte quantities */<br>
<br>
#define hashsize(n) ((ub4)1&lt;&lt;(n))<br>
#define hashmask(n) (hashsize(n)-1)</div>
在assoc_init()中，会对primary_hashtable做初始化，对应的hash操作包括：assoc_find()、assoc_expand()、assoc_move_next_bucket()、assoc_insert()、assoc_delete()，对应于item的读写操作。其中assoc_find()是根据key和key长寻找对应的item地址的函数（注意在C中，很多时候都是同时直接传入字符串和字符串长度，而不是在函数内部做strlen），返回的是item结构指针，它的数据地址在slab中的某个chunk上。<br>
<br>
items.c是数据项的操作程序，每一个完整的item包括几个部分，在item_make_header()中定义为：<br>
<br>
key：键<br>
nkey：键长<br>
flags：用户定义的flag（其实这个flag在memcached中没有启用）<br>
nbytes：值长（包括换行符号\r\n）<br>
suffix：后缀Buffer<br>
nsuffix：后缀长<br>
<br>
一个完整的item长度是键长＋值长＋后缀长＋item结构大小（32字节），item操作就是根据这个长度来计算slab的classid的。<br>
<br>
hashtable中的每一个桶上挂着一个双链表，item_init()的时候已经初始化了heads、tails、sizes三个数组为0，这三个数组的大小都为常量LARGEST_ID（默认为255，这个值需要配合factor来修改），在每次item_assoc()的时候，它会首先尝试从slab中获取一块空闲的chunk，如果没有可用的chunk，会在链表中扫描50次，以得到一个被LRU踢掉的item，将它unlink，然后将需要插入的item插入链表中。<br>
<br>
注意item的refcount成员。item被unlink之后只是从链表上摘掉，不是立刻就被free的，只是将它放到删除队列中（item_unlink_q()函数）。<br>
<br>
item对应一些读写操作，包括remove、update、replace，当然最重要的就是alloc操作。<br>
<br>
item还有一个特性就是它有过期时间，这是memcached的一个很有用的特性，很多应用都是依赖于memcached的item过期，比如session存储、操作锁等。item_flush_expired()函数就是扫描表中的item，对过期的item执行unlink操作，当然这只是一个回收动作，实际上在get的时候还要进行时间判断：<br>
<br>
<div class="smalltxt" style=
"FONT-WEIGHT: bold; MARGIN-LEFT: 2em; MARGIN-RIGHT: 2em">
<div style="FLOAT: left">CODE:</div>
<div style="FLOAT: right; TEXT-ALIGN: right">[Copy to
clipboard]</div>
</div>
<div class="altbg2" id="code5" style=
"CLEAR: both; BORDER-RIGHT: #f1f1f1 1px solid; PADDING-RIGHT: 10px; BORDER-TOP: #f1f1f1 1px solid; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; MARGIN: 3px 2em 2em; BORDER-LEFT: #f1f1f1 1px solid; WORD-BREAK: break-all; PADDING-TOP: 5px; BORDER-BOTTOM: #f1f1f1 1px solid">
/* expires items that are more recent than the oldest_live setting.
*/<br>
void item_flush_expired() {<br>
&nbsp; &nbsp; int i;&nbsp;&nbsp;<br>
&nbsp; &nbsp; item *iter, *next;<br>
&nbsp; &nbsp; if (! settings.oldest_live)<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;return;<br>
&nbsp; &nbsp; for (i = 0; i &lt; LARGEST_ID; i++) {<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;/* The LRU is sorted in
decreasing time order, and an item's timestamp<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;* is never newer than its
last access time, so we only need to walk<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;* back until we hit an item
older than the oldest_live time.<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;* The oldest_live checking
will auto-expire the remaining items.<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;*/<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;for (iter = heads[i]; iter !=
NULL; iter = next) {<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;if
(iter-&gt;time &gt;= settings.oldest_live) {<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;
next = iter-&gt;next;<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;
if ((iter-&gt;it_flags &amp; ITEM_SLABBED) == 0) {<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;item_unlink(iter);<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;
}&nbsp; &nbsp;&nbsp; &nbsp;<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;} else {<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;
/* We've hit the first old item. Continue to the next queue. */<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;
break;&nbsp;&nbsp;<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;}&nbsp;
&nbsp;&nbsp; &nbsp;<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;}&nbsp; &nbsp;&nbsp;
&nbsp;<br>
&nbsp; &nbsp; }<br>
}</div>
<br>
<br>
<div class="smalltxt" style=
"FONT-WEIGHT: bold; MARGIN-LEFT: 2em; MARGIN-RIGHT: 2em">
<div style="FLOAT: left">CODE:</div>
<div style="FLOAT: right; TEXT-ALIGN: right">[Copy to
clipboard]</div>
</div>
<div class="altbg2" id="code6" style=
"CLEAR: both; BORDER-RIGHT: #f1f1f1 1px solid; PADDING-RIGHT: 10px; BORDER-TOP: #f1f1f1 1px solid; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; MARGIN: 3px 2em 2em; BORDER-LEFT: #f1f1f1 1px solid; WORD-BREAK: break-all; PADDING-TOP: 5px; BORDER-BOTTOM: #f1f1f1 1px solid">
/* wrapper around assoc_find which does the lazy
expiration/deletion logic */<br>
item *get_item_notedeleted(char *key, size_t nkey, int
*delete_locked) {<br>
&nbsp; &nbsp; item *it = assoc_find(key, nkey);<br>
&nbsp; &nbsp; if (delete_locked) *delete_locked = 0;<br>
&nbsp; &nbsp; if (it &amp;&amp; (it-&gt;it_flags &amp;
ITEM_DELETED)) {<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;/* it's flagged as
delete-locked.&nbsp;&nbsp;let's see if that condition<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;is past due, and
the 5-second delete_timer just hasn't<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;gotten to it
yet... */<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;if (!
item_delete_lock_over(it)) {<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;if
(delete_locked) *delete_locked = 1;<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;it = 0;<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;}&nbsp; &nbsp;&nbsp;
&nbsp;<br>
&nbsp; &nbsp; }<br>
&nbsp; &nbsp; if (it &amp;&amp; settings.oldest_live &amp;&amp;
settings.oldest_live &lt;= current_time &amp;&amp;<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;it-&gt;time &lt;=
settings.oldest_live) {<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;item_unlink(it);<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;it = 0;<br>
&nbsp; &nbsp; }<br>
&nbsp; &nbsp; if (it &amp;&amp; it-&gt;exptime &amp;&amp;
it-&gt;exptime &lt;= current_time) {<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;item_unlink(it);<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;it = 0;<br>
&nbsp; &nbsp; }<br>
&nbsp; &nbsp; return it;<br>
}</div>
Memcached的内存管理方式是非常精巧和高效的，它很大程度上减少了直接alloc系统内存的次数，降低函数开销和内存碎片产生几率，虽然这种方式会造成一些冗余浪费，但是这种浪费在大型系统应用中是微不足道的。<br>
<br>
<br>
<strong>◎Memcached的理论参数计算方式</strong><br>
<br>
影响 memcached 工作的几个参数有：<br>
<br>
常量REALTIME_MAXDELTA 60*60*24*30<br>
最大30天的过期时间<br>
<br>
conn_init()中的freetotal（=200）<br>
最大同时连接数<br>
<br>
常量KEY_MAX_LENGTH 250<br>
最大键长<br>
<br>
settings.factor（=1.25）<br>
factor将影响chunk的步进大小<br>
<br>
settings.maxconns（=1024）<br>
最大软连接<br>
<br>
settings.chunk_size（=48）<br>
一个保守估计的key+value长度，用来生成id1中的chunk长度（1.2）。id1的chunk长度等于这个数值加上item结构体的长度（32），即默认的80字节。<br>
<br>
常量POWER_SMALLEST 1<br>
最小classid（1.2）<br>
<br>
常量POWER_LARGEST 200<br>
最大classid（1.2）<br>
<br>
常量POWER_BLOCK 1048576<br>
默认slab大小<br>
<br>
常量CHUNK_ALIGN_BYTES (sizeof(void *))<br>
保证chunk大小是这个数值的整数倍，防止越界（void *的长度在不同系统上不一样，在标准32位系统上是4）<br>
<br>
常量ITEM_UPDATE_INTERVAL 60<br>
队列刷新间隔<br>
<br>
常量LARGEST_ID 255<br>
最大item链表数（这个值不能比最大的classid小）<br>
<br>
变量hashpower（在1.1中是常量HASHPOWER）<br>
决定hashtable的大小<br>
<br>
根据上面介绍的内容及参数设定，可以计算出的一些结果：<br>
<br>
1、在memcached中可以保存的item个数是没有软件上限的，之前我的100万的说法是错误的。<br>
2、假设NewHash算法碰撞均匀，查找item的循环次数是item总数除以hashtable大小（由hashpower决定），是线性的。<br>
3、Memcached限制了可以接受的最大item是1MB，大于1MB的数据不予理会。<br>
4、Memcached的空间利用率和数据特性有很大的关系，又与DONT_PREALLOC_SLABS常量有关。
在最差情况下，有198个slab会被浪费（所有item都集中在一个slab中，199个id全部分配满）。<br>
<br>
<strong>◎Memcached的定长优化</strong><br>
<br>
根据上面几节的描述，多少对memcached有了一个比较深入的认识。在深入认识的基础上才好对它进行优化。<br>
<br>
Memcached本身是为变长数据设计的，根据数据特性，可以说它是“面向大众”的设计，但是很多时候，我们的数据并不是这样的“普遍”，典型的情况中，一种是非均匀分布，即数据长度集中在几个区域内（如保存用户
Session）；另一种更极端的状态是等长数据（如定长键值，定长数据，多见于访问、在线统计或执行锁）。<br>
<br>
这里主要研究一下定长数据的优化方案（1.2），集中分布的变长数据仅供参考，实现起来也很容易。<br>
<br>
解决定长数据，首先需要解决的是slab的分配问题，第一个需要确认的是我们不需要那么多不同chunk长度的slab，为了最大限度地利用资源，最好chunk和item等长，所以首先要计算item长度。<br>
<br>
在之前已经有了计算item长度的算法，需要注意的是，除了字符串长度外，还要加上item结构的长度32字节。<br>
<br>
假设我们已经计算出需要保存200字节的等长数据。<br>
<br>
接下来是要修改slab的classid和chunk长度的关系。在原始版本中，chunk长度和classid是有对应关系的，现在如果把所有的chunk都定为200个字节，那么这个关系就不存在了，我们需要重新确定这二者的关系。一种方法是，整个存储结构只使用一个固定的id，即只使用199个槽中的1个，在这种条件下，就一定要定义DONT_PREALLOC_SLABS来避免另外的预分配浪费。另一种方法是建立一个hash关系，来从item确定classid，不能使用长度来做键，可以使用key的NewHash结果等不定数据，或者直接根据key来做hash（定长数据的key也一定等长）。这里简单起见，选择第一种方法，这种方法的不足之处在于只使用一个id，在数据量非常大的情况下，slab链会很长（因为所有数据都挤在一条链上了），遍历起来的代价比较高。<br>
<br>
前面介绍了三种空间冗余，设置chunk长度等于item长度，解决了第一种空间浪费问题，不预申请空间解决了第二种空间浪费问题，那么对于第一种问题（slab内剩余）如何解决呢，这就需要修改POWER_BLOCK常量，使得每一个slab大小正好等于chunk长度的整数倍，这样一个slab就可以正好划分成n个chunk。这个数值应该比较接近1MB，过大的话同样会造成冗余，过小的话会造成次数过多的alloc，根据chunk长度为200，选择1000000作为POWER_BLOCK的值，这样一个slab就是100万字节，不是1048576。三个冗余问题都解决了，空间利用率会大大提升。<br>
<br>
修改 slabs_clsid 函数，让它直接返回一个定值（比如 1 ）：<br>
<br>
<div class="smalltxt" style=
"FONT-WEIGHT: bold; MARGIN-LEFT: 2em; MARGIN-RIGHT: 2em">
<div style="FLOAT: left">CODE:</div>
<div style="FLOAT: right; TEXT-ALIGN: right">[Copy to
clipboard]</div>
</div>
<div class="altbg2" id="code7" style=
"CLEAR: both; BORDER-RIGHT: #f1f1f1 1px solid; PADDING-RIGHT: 10px; BORDER-TOP: #f1f1f1 1px solid; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; MARGIN: 3px 2em 2em; BORDER-LEFT: #f1f1f1 1px solid; WORD-BREAK: break-all; PADDING-TOP: 5px; BORDER-BOTTOM: #f1f1f1 1px solid">
unsigned int slabs_clsid(size_t size) {<br>
&nbsp; &nbsp; &nbsp; &nbsp; return 1;<br>
}</div>
修改slabs_init函数，去掉循环创建所有classid属性的部分，直接添加slabclass[1]：<br>
<br>
<div class="smalltxt" style=
"FONT-WEIGHT: bold; MARGIN-LEFT: 2em; MARGIN-RIGHT: 2em">
<div style="FLOAT: left">CODE:</div>
<div style="FLOAT: right; TEXT-ALIGN: right">[Copy to
clipboard]</div>
</div>
<div class="altbg2" id="code8" style=
"CLEAR: both; BORDER-RIGHT: #f1f1f1 1px solid; PADDING-RIGHT: 10px; BORDER-TOP: #f1f1f1 1px solid; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; MARGIN: 3px 2em 2em; BORDER-LEFT: #f1f1f1 1px solid; WORD-BREAK: break-all; PADDING-TOP: 5px; BORDER-BOTTOM: #f1f1f1 1px solid">
slabclass[1].size = 200;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; //每chunk200字节<br>
slabclass[1].perslab = 5000;&nbsp; &nbsp; &nbsp; &nbsp;
//1000000/200</div>
<strong>◎Memcached客户端</strong><br>
<br>
Memcached是一个服务程序，使用的时候可以根据它的协议，连接到memcached服务器上，发送命令给服务进程，就可以操作上面的数据。为了方便使用，memcached有很多个客户端程序可以使用，对应于各种语言，有各种语言的客户端。基于C语言的有libmemcache、APR_Memcache；基于Perl的有Cache::Memcached；另外还有Python、Ruby、Java、C#等语言的支持。PHP的客户端是最多的，不光有mcache和PECL
memcache两个扩展，还有大把的由PHP编写的封装类，下面介绍一下在PHP中使用memcached的方法：<br>
<br>
mcache扩展是基于libmemcache再封装的。libmemcache一直没有发布stable版本，目前版本是1.4.0-rc2，可以在这里找到。libmemcache有一个很不好的特性，就是会向stderr写很多错误信息，一般的，作为lib使用的时候，stderr一般都会被定向到其它地方，比如Apache的错误日志，而且libmemcache会自杀，可能会导致异常，不过它的性能还是很好的。<br>
<br>
mcache扩展最后更新到1.2.0-beta10，作者大概是离职了，不光停止更新，连网站也打不开了（~_~），只能到其它地方去获取这个不负责的扩展了。解压后安装方法如常：phpize
&amp; configure &amp; make &amp; make
install，一定要先安装libmemcache。使用这个扩展很简单：<br>
<br>
<div class="smalltxt" style=
"FONT-WEIGHT: bold; MARGIN-LEFT: 2em; MARGIN-RIGHT: 2em">
<div style="FLOAT: left">CODE:</div>
<div style="FLOAT: right; TEXT-ALIGN: right">[Copy to
clipboard]</div>
</div>
<div class="altbg2" id="code15" style=
"CLEAR: both; BORDER-RIGHT: #f1f1f1 1px solid; PADDING-RIGHT: 10px; BORDER-TOP: #f1f1f1 1px solid; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; MARGIN: 3px 2em 2em; BORDER-LEFT: #f1f1f1 1px solid; WORD-BREAK: break-all; PADDING-TOP: 5px; BORDER-BOTTOM: #f1f1f1 1px solid">
<span style="COLOR: #000000"><span style=
"COLOR: #0000bb">&lt;?php<br>
$mc&nbsp;</span><span style=
"COLOR: #007700">=&nbsp;</span><span style=
"COLOR: #0000bb">memcache</span><span style=
"COLOR: #007700">();&nbsp;&nbsp;&nbsp;&nbsp;</span><span style=
"COLOR: #ff8000">//&nbsp;创建一个memcache连接对象，注意这里不是用new！<br></span><span style="COLOR: #0000bb">$mc</span><span style="COLOR: #007700">-&gt;</span><span style="COLOR: #0000bb">add_server</span><span style="COLOR: #007700">(</span><span style="COLOR: #dd0000">'localhost'</span><span style="COLOR: #007700">,&nbsp;</span><span style="COLOR: #0000bb">11211</span><span style="COLOR: #007700">);&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #ff8000">//&nbsp;添加一个服务进程<br></span><span style="COLOR: #0000bb">$mc</span><span style="COLOR: #007700">-&gt;</span><span style="COLOR: #0000bb">add_server</span><span style="COLOR: #007700">(</span><span style="COLOR: #dd0000">'localhost'</span><span style="COLOR: #007700">,&nbsp;</span><span style="COLOR: #0000bb">11212</span><span style="COLOR: #007700">);&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #ff8000">//&nbsp;添加第二个服务进程<br></span><span style="COLOR: #0000bb">$mc</span><span style="COLOR: #007700">-&gt;</span><span style="COLOR: #0000bb">set</span><span style="COLOR: #007700">(</span><span style="COLOR: #dd0000">'key1'</span><span style="COLOR: #007700">,&nbsp;</span><span style="COLOR: #dd0000">'Hello'</span><span style="COLOR: #007700">);&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #ff8000">//&nbsp;写入key1&nbsp;=&gt;&nbsp;Hello<br></span><span style="COLOR: #0000bb">$mc</span><span style="COLOR: #007700">-&gt;</span><span style="COLOR: #0000bb">set</span><span style="COLOR: #007700">(</span><span style="COLOR: #dd0000">'key2'</span><span style="COLOR: #007700">,&nbsp;</span><span style="COLOR: #dd0000">'World'</span><span style="COLOR: #007700">,&nbsp;</span><span style="COLOR: #0000bb">10</span><span style="COLOR: #007700">);&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #ff8000">//&nbsp;写入key2&nbsp;=&gt;&nbsp;World，10秒过期<br></span><span style="COLOR: #0000bb">$mc</span><span style="COLOR: #007700">-&gt;</span><span style="COLOR: #0000bb">set</span><span style="COLOR: #007700">(</span><span style="COLOR: #dd0000">'arr1'</span><span style="COLOR: #007700">,&nbsp;array(</span><span style="COLOR: #dd0000">'Hello'</span><span style="COLOR: #007700">,&nbsp;</span><span style="COLOR: #dd0000">'World'</span><span style="COLOR: #007700">));&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #ff8000">//&nbsp;写入一个数组<br></span><span style="COLOR: #0000bb">$key1&nbsp;</span><span style="COLOR: #007700">=&nbsp;</span><span style="COLOR: #0000bb">$mc</span><span style="COLOR: #007700">-&gt;</span><span style="COLOR: #0000bb">get</span><span style="COLOR: #007700">(</span><span style="COLOR: #dd0000">'key1'</span><span style="COLOR: #007700">);&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #ff8000">//&nbsp;获取'key1'的值，赋给$key1<br></span><span style="COLOR: #0000bb">$key2&nbsp;</span><span style="COLOR: #007700">=&nbsp;</span><span style="COLOR: #0000bb">$mc</span><span style="COLOR: #007700">-&gt;</span><span style="COLOR: #0000bb">get</span><span style="COLOR: #007700">(</span><span style="COLOR: #dd0000">'key2'</span><span style="COLOR: #007700">);&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #ff8000">//&nbsp;获取'key2'的值，赋给$key2，如果超过10秒，就取不到了<br></span><span style="COLOR: #0000bb">$arr1&nbsp;</span><span style="COLOR: #007700">=&nbsp;</span><span style="COLOR: #0000bb">$mc</span><span style="COLOR: #007700">-&gt;</span><span style="COLOR: #0000bb">get</span><span style="COLOR: #007700">(</span><span style="COLOR: #dd0000">'arr1'</span><span style="COLOR: #007700">);&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #ff8000">//&nbsp;获取'arr1'数组<br></span><span style="COLOR: #0000bb">$mc</span><span style="COLOR: #007700">-&gt;</span><span style="COLOR: #0000bb">delete</span><span style="COLOR: #007700">(</span><span style="COLOR: #dd0000">'arr1'</span><span style="COLOR: #007700">);&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #ff8000">//&nbsp;删除'arr1'<br></span><span style="COLOR: #0000bb">$mc</span><span style="COLOR: #007700">-&gt;</span><span style="COLOR: #0000bb">flush_all</span><span style="COLOR: #007700">();&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #ff8000">//&nbsp;删掉所有数据<br></span><span style="COLOR: #0000bb">$stats&nbsp;</span><span style="COLOR: #007700">=&nbsp;</span><span style="COLOR: #0000bb">$mc</span><span style="COLOR: #007700">-&gt;</span><span style="COLOR: #0000bb">stats</span><span style="COLOR: #007700">();&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #ff8000">//&nbsp;获取服务器信息<br></span><span style="COLOR: #0000bb">var_dump</span><span style="COLOR: #007700">(</span><span style="COLOR: #0000bb">$stats</span><span style="COLOR: #007700">);&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #ff8000">//&nbsp;服务器信息是一个数组<br></span><span style="COLOR: #0000bb">?&gt;</span></span></div>
这个扩展的好处是可以很方便地实现分布式存储和负载均衡，因为它可以添加多个服务地址，数据在保存的时候是会根据hash结果定位到某台服务器上的，这也是libmemcache的特性。libmemcache支持集中hash方式，包括CRC32、ELF和Perl
hash。<br>
<br>
PECL
memcache是PECL发布的扩展，目前最新版本是2.1.0，可以在pecl网站得到。memcache扩展的使用方法可以在新一些的PHP手册中找到，它和mcache很像，真的很像：<br>
<br>
<div class="smalltxt" style=
"FONT-WEIGHT: bold; MARGIN-LEFT: 2em; MARGIN-RIGHT: 2em">
<div style="FLOAT: left">CODE:</div>
<div style="FLOAT: right; TEXT-ALIGN: right">[Copy to
clipboard]</div>
</div>
<div class="altbg2" id="code16" style=
"CLEAR: both; BORDER-RIGHT: #f1f1f1 1px solid; PADDING-RIGHT: 10px; BORDER-TOP: #f1f1f1 1px solid; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; MARGIN: 3px 2em 2em; BORDER-LEFT: #f1f1f1 1px solid; WORD-BREAK: break-all; PADDING-TOP: 5px; BORDER-BOTTOM: #f1f1f1 1px solid">
<span style="COLOR: #000000"><span style=
"COLOR: #0000bb">&lt;?php<br>
<br>
$memcache&nbsp;</span><span style=
"COLOR: #007700">=&nbsp;new&nbsp;</span><span style=
"COLOR: #0000bb">Memcache</span><span style=
"COLOR: #007700">;<br></span><span style=
"COLOR: #0000bb">$memcache</span><span style=
"COLOR: #007700">-&gt;</span><span style=
"COLOR: #0000bb">connect</span><span style=
"COLOR: #007700">(</span><span style=
"COLOR: #dd0000">'localhost'</span><span style=
"COLOR: #007700">,&nbsp;</span><span style=
"COLOR: #0000bb">11211</span><span style=
"COLOR: #007700">)&nbsp;or&nbsp;die&nbsp;(</span><span style=
"COLOR: #dd0000">"Could&nbsp;not&nbsp;connect"</span><span style=
"COLOR: #007700">);<br>
<br></span><span style=
"COLOR: #0000bb">$version&nbsp;</span><span style=
"COLOR: #007700">=&nbsp;</span><span style=
"COLOR: #0000bb">$memcache</span><span style=
"COLOR: #007700">-&gt;</span><span style=
"COLOR: #0000bb">getVersion</span><span style=
"COLOR: #007700">();<br>
echo&nbsp;</span><span style=
"COLOR: #dd0000">"Server's&nbsp;version:&nbsp;"</span><span style=
"COLOR: #007700">.</span><span style=
"COLOR: #0000bb">$version</span><span style=
"COLOR: #007700">.</span><span style=
"COLOR: #dd0000">"n"</span><span style="COLOR: #007700">;<br>
<br></span><span style=
"COLOR: #0000bb">$tmp_object&nbsp;</span><span style=
"COLOR: #007700">=&nbsp;new&nbsp;</span><span style=
"COLOR: #0000bb">stdClass</span><span style=
"COLOR: #007700">;<br></span><span style=
"COLOR: #0000bb">$tmp_object</span><span style=
"COLOR: #007700">-&gt;</span><span style=
"COLOR: #0000bb">str_attr&nbsp;</span><span style=
"COLOR: #007700">=&nbsp;</span><span style=
"COLOR: #dd0000">'test'</span><span style=
"COLOR: #007700">;<br></span><span style=
"COLOR: #0000bb">$tmp_object</span><span style=
"COLOR: #007700">-&gt;</span><span style=
"COLOR: #0000bb">int_attr&nbsp;</span><span style=
"COLOR: #007700">=&nbsp;</span><span style=
"COLOR: #0000bb">123</span><span style="COLOR: #007700">;<br>
<br></span><span style=
"COLOR: #0000bb">$memcache</span><span style="COLOR: #007700">-&gt;</span><span style="COLOR: #0000bb">set</span><span style="COLOR: #007700">(</span><span style="COLOR: #dd0000">'key'</span><span style="COLOR: #007700">,&nbsp;</span><span style="COLOR: #0000bb">$tmp_object</span><span style="COLOR: #007700">,&nbsp;</span><span style="COLOR: #0000bb">false</span><span style="COLOR: #007700">,&nbsp;</span><span style="COLOR: #0000bb">10</span><span style="COLOR: #007700">)&nbsp;or&nbsp;die&nbsp;(</span><span style="COLOR: #dd0000">"Failed&nbsp;to&nbsp;save&nbsp;data&nbsp;at&nbsp;the&nbsp;server"</span><span style="COLOR: #007700">);<br>
echo&nbsp;</span><span style=
"COLOR: #dd0000">"Store&nbsp;data&nbsp;in&nbsp;the&nbsp;cache&nbsp;(data&nbsp;will&nbsp;expire&nbsp;in&nbsp;10&nbsp;seconds)n"</span><span style="COLOR: #007700">;<br>
<br></span> <span style=
"COLOR: #0000bb">$get_result&nbsp;</span><span style=
"COLOR: #007700">=&nbsp;</span><span style=
"COLOR: #0000bb">$memcache</span><span style=
"COLOR: #007700">-&gt;</span><span style=
"COLOR: #0000bb">get</span><span style=
"COLOR: #007700">(</span><span style=
"COLOR: #dd0000">'key'</span><span style="COLOR: #007700">);<br>
echo&nbsp;</span><span style=
"COLOR: #dd0000">"Data&nbsp;from&nbsp;the&nbsp;cache:n"</span><span style="COLOR: #007700">;<br>
<br></span> <span style=
"COLOR: #0000bb">var_dump</span><span style="COLOR: #007700">(</span><span style="COLOR: #0000bb">$get_result</span><span style="COLOR: #007700">);<br>
<br></span><span style="COLOR: #0000bb">?&gt;</span></span></div>
这个扩展是使用php的stream直接连接memcached服务器并通过socket发送命令的。它不像libmemcache那样完善，也不支持add_server这种分布操作，但是因为它不依赖其它的外界程序，兼容性要好一些，也比较稳定。至于效率，差别不是很大。<br>
<br>
另外，有很多的PHP
class可以使用，比如MemcacheClient.inc.php，phpclasses.org上可以找到很多，一般都是对perl
client API的再封装，使用方式很像。<br>
<br>
◎BSM_Memcache<br>
<br>
从C
client来说，APR_Memcache是一个很成熟很稳定的client程序，支持线程锁和原子级操作，保证运行的稳定性。不过它是基于APR的（APR将在最后一节介绍），没有libmemcache的应用范围广，目前也没有很多基于它开发的程序，现有的多是一些Apache
Module，因为它不能脱离APR环境运行。但是APR倒是可以脱离Apache单独安装的，在APR网站上可以下载APR和APR-util，不需要有Apache，可以直接安装，而且它是跨平台的。<br>
<br>
BSM_Memcache是我在BS.Magic项目中开发的一个基于APR_Memcache的PHP扩展，说起来有点拗口，至少它把APR扯进了PHP扩展中。这个程序很简单，也没做太多的功能，只是一种形式的尝试，它支持服务器分组。<br>
<br>
和mcache扩展支持多服务器分布存储不同，BSM_Memcache支持多组服务器，每一组内的服务器还是按照hash方式来分布保存数据，但是两个组中保存的数据是一样的，也就是实现了热备，它不会因为一台服务器发生单点故障导致数据无法获取，除非所有的服务器组都损坏（例如机房停电）。当然实现这个功能的代价就是性能上的牺牲，在每次添加删除数据的时候都要扫描所有的组，在get数据的时候会随机选择一组服务器开始轮询，一直到找到数据为止，正常情况下一次就可以获取得到。<br>
<br>
BSM_Memcache只支持这几个函数：<br>
<br>
<div class="smalltxt" style=
"FONT-WEIGHT: bold; MARGIN-LEFT: 2em; MARGIN-RIGHT: 2em">
<div style="FLOAT: left">CODE:</div>
<div style="FLOAT: right; TEXT-ALIGN: right">[Copy to
clipboard]</div>
</div>
<div class="altbg2" id="code9" style=
"CLEAR: both; BORDER-RIGHT: #f1f1f1 1px solid; PADDING-RIGHT: 10px; BORDER-TOP: #f1f1f1 1px solid; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; MARGIN: 3px 2em 2em; BORDER-LEFT: #f1f1f1 1px solid; WORD-BREAK: break-all; PADDING-TOP: 5px; BORDER-BOTTOM: #f1f1f1 1px solid">
zend_function_entry bsm_memcache_functions[] =<br>
{<br>
&nbsp; &nbsp; PHP_FE(mc_get,&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;
NULL)<br>
&nbsp; &nbsp; PHP_FE(mc_set,&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;
NULL)<br>
&nbsp; &nbsp; PHP_FE(mc_del,&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;
NULL)<br>
&nbsp; &nbsp; PHP_FE(mc_add_group,&nbsp; &nbsp; NULL)<br>
&nbsp; &nbsp; PHP_FE(mc_add_server,&nbsp; &nbsp;NULL)<br>
&nbsp; &nbsp; PHP_FE(mc_shutdown,&nbsp; &nbsp;&nbsp;&nbsp;NULL)<br>
&nbsp; &nbsp; {NULL, NULL, NULL}<br>
};</div>
mc_add_group函数返回一个整形（其实应该是一个object，我偷懒了~_~）作为组ID，mc_add_server的时候要提供两个参数，一个是组ID，一个是服务器地址（ADDR<img alt=""
align="absmiddle" border="0" src=
"http://www.phpx.com/happy/images/smilies/tongue.gif">ORT）。<br>
<br>
<div class="smalltxt" style=
"FONT-WEIGHT: bold; MARGIN-LEFT: 2em; MARGIN-RIGHT: 2em">
<div style="FLOAT: left">CODE:</div>
<div style="FLOAT: right; TEXT-ALIGN: right">[Copy to
clipboard]</div>
</div>
<div class="altbg2" id="code10" style=
"CLEAR: both; BORDER-RIGHT: #f1f1f1 1px solid; PADDING-RIGHT: 10px; BORDER-TOP: #f1f1f1 1px solid; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; MARGIN: 3px 2em 2em; BORDER-LEFT: #f1f1f1 1px solid; WORD-BREAK: break-all; PADDING-TOP: 5px; BORDER-BOTTOM: #f1f1f1 1px solid">
/**<br>
* Add a server group<br>
*/<br>
PHP_FUNCTION(mc_add_group)<br>
{<br>
&nbsp; &nbsp; apr_int32_t group_id;<br>
&nbsp; &nbsp; apr_status_t rv;<br>
<br>
&nbsp; &nbsp; if (0 != ZEND_NUM_ARGS())<br>
&nbsp; &nbsp; {<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;WRONG_PARAM_COUNT;<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;RETURN_NULL();<br>
&nbsp; &nbsp; }<br>
<br>
&nbsp; &nbsp; group_id = free_group_id();<br>
&nbsp; &nbsp; if (-1 == group_id)<br>
&nbsp; &nbsp; {<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;RETURN_FALSE;<br>
&nbsp; &nbsp; }<br>
<br>
&nbsp; &nbsp; apr_memcache_t *mc;<br>
&nbsp; &nbsp; rv = apr_memcache_create(p, MAX_G_SERVER, 0,
&amp;mc);<br>
<br>
&nbsp; &nbsp; add_group(group_id, mc);<br>
<br>
&nbsp; &nbsp; RETURN_DOUBLE(group_id);<br>
}</div>
<br>
<br>
<div class="smalltxt" style=
"FONT-WEIGHT: bold; MARGIN-LEFT: 2em; MARGIN-RIGHT: 2em">
<div style="FLOAT: left">CODE:</div>
<div style="FLOAT: right; TEXT-ALIGN: right">[Copy to
clipboard]</div>
</div>
<div class="altbg2" id="code11" style=
"CLEAR: both; BORDER-RIGHT: #f1f1f1 1px solid; PADDING-RIGHT: 10px; BORDER-TOP: #f1f1f1 1px solid; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; MARGIN: 3px 2em 2em; BORDER-LEFT: #f1f1f1 1px solid; WORD-BREAK: break-all; PADDING-TOP: 5px; BORDER-BOTTOM: #f1f1f1 1px solid">
/**<br>
* Add a server into group<br>
*/<br>
PHP_FUNCTION(mc_add_server)<br>
{<br>
&nbsp; &nbsp; apr_status_t rv;<br>
&nbsp; &nbsp; apr_int32_t group_id;<br>
&nbsp; &nbsp; double g;<br>
&nbsp; &nbsp; char *srv_str;<br>
&nbsp; &nbsp; int srv_str_l;<br>
<br>
&nbsp; &nbsp; if (2 != ZEND_NUM_ARGS())<br>
&nbsp; &nbsp; {<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;WRONG_PARAM_COUNT;<br>
&nbsp; &nbsp; }<br>
<br>
&nbsp; &nbsp; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
"ds", &amp;g, &amp;srv_str, &amp;srv_str_l) == FAILURE)<br>
&nbsp; &nbsp; {<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;RETURN_FALSE;<br>
&nbsp; &nbsp; }<br>
<br>
&nbsp; &nbsp; group_id = (apr_int32_t) g;<br>
<br>
&nbsp; &nbsp; if (-1 == is_validate_group(group_id))<br>
&nbsp; &nbsp; {<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;RETURN_FALSE;<br>
&nbsp; &nbsp; }<br>
<br>
&nbsp; &nbsp; char *host, *scope;<br>
&nbsp; &nbsp; apr_port_t port;<br>
<br>
&nbsp; &nbsp; rv = apr_parse_addr_port(&amp;host, &amp;scope,
&amp;port, srv_str, p);<br>
&nbsp; &nbsp; if (APR_SUCCESS == rv)<br>
&nbsp; &nbsp; {<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;// Create this server
object<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;apr_memcache_server_t
*st;<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;rv =
apr_memcache_server_create(p, host, port, 0, 64, 1024, 600,
&amp;st);<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;if (APR_SUCCESS == rv)<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;{<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;if (NULL ==
mc_groups[group_id])<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;{<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;
RETURN_FALSE;<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;}<br>
<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// Add
server<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;rv =
apr_memcache_add_server(mc_groups[group_id], st);<br>
<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;if (APR_SUCCESS
== rv)<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;{<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;
RETURN_TRUE;<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;}<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;}<br>
&nbsp; &nbsp; }<br>
<br>
&nbsp; &nbsp; RETURN_FALSE;<br>
}</div>
在set和del数据的时候，要循环所有的组：<br>
<br>
<div class="smalltxt" style=
"FONT-WEIGHT: bold; MARGIN-LEFT: 2em; MARGIN-RIGHT: 2em">
<div style="FLOAT: left">CODE:</div>
<div style="FLOAT: right; TEXT-ALIGN: right">[Copy to
clipboard]</div>
</div>
<div class="altbg2" id="code12" style=
"CLEAR: both; BORDER-RIGHT: #f1f1f1 1px solid; PADDING-RIGHT: 10px; BORDER-TOP: #f1f1f1 1px solid; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; MARGIN: 3px 2em 2em; BORDER-LEFT: #f1f1f1 1px solid; WORD-BREAK: break-all; PADDING-TOP: 5px; BORDER-BOTTOM: #f1f1f1 1px solid">
/**<br>
* Store item into all groups<br>
*/<br>
PHP_FUNCTION(mc_set)<br>
{<br>
&nbsp; &nbsp; char *key, *value;<br>
&nbsp; &nbsp; int key_l, value_l;<br>
&nbsp; &nbsp; double ttl = 0;<br>
&nbsp; &nbsp; double set_ct = 0;<br>
<br>
&nbsp; &nbsp; if (2 != ZEND_NUM_ARGS())<br>
&nbsp; &nbsp; {<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;WRONG_PARAM_COUNT;<br>
&nbsp; &nbsp; }<br>
<br>
&nbsp; &nbsp; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
"ss|d", &amp;key, &amp;key_l, &amp;value, &amp;value_l, ttl) ==
FAILURE)<br>
&nbsp; &nbsp; {<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;RETURN_FALSE;<br>
&nbsp; &nbsp; }<br>
<br>
&nbsp; &nbsp; // Write data into every object<br>
&nbsp; &nbsp; apr_int32_t i = 0;<br>
&nbsp; &nbsp; if (ttl &lt; 0)<br>
&nbsp; &nbsp; {<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;ttl = 0;<br>
&nbsp; &nbsp; }<br>
<br>
&nbsp; &nbsp; apr_status_t rv;<br>
<br>
&nbsp; &nbsp; for (i = 0; i &lt; MAX_GROUP; i++)<br>
&nbsp; &nbsp; {<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;if (0 ==
is_validate_group(i))<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;{<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// Write
it!<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;rv =
apr_memcache_add(mc_groups[i], key, value, value_l, (apr_uint32_t)
ttl, 0);<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;if (APR_SUCCESS
== rv)<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;{<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;
set_ct++;<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;}<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;}<br>
&nbsp; &nbsp; }<br>
<br>
&nbsp; &nbsp; RETURN_DOUBLE(set_ct);<br>
}</div>
在mc_get中，首先要随机选择一个组，然后从这个组开始轮询：<br>
<br>
<div class="smalltxt" style=
"FONT-WEIGHT: bold; MARGIN-LEFT: 2em; MARGIN-RIGHT: 2em">
<div style="FLOAT: left">CODE:</div>
<div style="FLOAT: right; TEXT-ALIGN: right">[Copy to
clipboard]</div>
</div>
<div class="altbg2" id="code13" style=
"CLEAR: both; BORDER-RIGHT: #f1f1f1 1px solid; PADDING-RIGHT: 10px; BORDER-TOP: #f1f1f1 1px solid; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; MARGIN: 3px 2em 2em; BORDER-LEFT: #f1f1f1 1px solid; WORD-BREAK: break-all; PADDING-TOP: 5px; BORDER-BOTTOM: #f1f1f1 1px solid">
/**<br>
* Fetch a item from a random group<br>
*/<br>
PHP_FUNCTION(mc_get)<br>
{&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;
&nbsp;<br>
&nbsp; &nbsp; char *key, *value = NULL;<br>
&nbsp; &nbsp; int key_l;<br>
&nbsp; &nbsp; apr_size_t value_l;<br>
<br>
&nbsp; &nbsp; if (1 != ZEND_NUM_ARGS())<br>
&nbsp; &nbsp; {<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;WRONG_PARAM_COUNT;<br>
&nbsp; &nbsp; }<br>
<br>
&nbsp; &nbsp; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
"s", &amp;key, &amp;key_l) == FAILURE)<br>
&nbsp; &nbsp; {<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;RETURN_MULL();<br>
&nbsp; &nbsp; }<br>
&nbsp; &nbsp;<br>
&nbsp; &nbsp; // I will try ...<br>
&nbsp; &nbsp; // Random read<br>
&nbsp; &nbsp; apr_int32_t curr_group_id = random_group();<br>
&nbsp; &nbsp; apr_int32_t i = 0;<br>
&nbsp; &nbsp; apr_int32_t try = 0;<br>
&nbsp; &nbsp; apr_uint32_t flag;<br>
&nbsp; &nbsp; apr_memcache_t *oper;<br>
&nbsp; &nbsp; apr_status_t rv;<br>
<br>
&nbsp; &nbsp; for (i = 0; i &lt; MAX_GROUP; i++)<br>
&nbsp; &nbsp; {<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;try = i + curr_group_id;<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;try = try % MAX_GROUP;<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;if (0 ==
is_validate_group(try))<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;{<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// Get a
value<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;oper =
mc_groups[try];<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;rv =
apr_memcache_getp(mc_groups[try], p, (const char *) key,
&amp;value, &amp;value_l, 0);<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;if (APR_SUCCESS
== rv)<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;{<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;
RETURN_STRING(value, 1);<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;}<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;}<br>
&nbsp; &nbsp; }<br>
<br>
&nbsp; &nbsp; RETURN_FALSE;<br>
}</div>
<br>
<br>
<div class="smalltxt" style=
"FONT-WEIGHT: bold; MARGIN-LEFT: 2em; MARGIN-RIGHT: 2em">
<div style="FLOAT: left">CODE:</div>
<div style="FLOAT: right; TEXT-ALIGN: right">[Copy to
clipboard]</div>
</div>
<div class="altbg2" id="code14" style=
"CLEAR: both; BORDER-RIGHT: #f1f1f1 1px solid; PADDING-RIGHT: 10px; BORDER-TOP: #f1f1f1 1px solid; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; MARGIN: 3px 2em 2em; BORDER-LEFT: #f1f1f1 1px solid; WORD-BREAK: break-all; PADDING-TOP: 5px; BORDER-BOTTOM: #f1f1f1 1px solid">
/**<br>
* Random group id<br>
* For mc_get()<br>
*/<br>
apr_int32_t random_group()<br>
{<br>
&nbsp; &nbsp; struct timeval tv;<br>
&nbsp; &nbsp; struct timezone tz;<br>
&nbsp; &nbsp; int usec;<br>
<br>
&nbsp; &nbsp; gettimeofday(&amp;tv, &amp;tz);<br>
<br>
&nbsp; &nbsp; usec = tv.tv_usec;<br>
<br>
&nbsp; &nbsp; int curr = usec % count_group();<br>
<br>
&nbsp; &nbsp; return (apr_int32_t) curr;<br>
}</div>
BSM_Memcache的使用方式和其它的client类似：<br>
<br>
<div class="smalltxt" style=
"FONT-WEIGHT: bold; MARGIN-LEFT: 2em; MARGIN-RIGHT: 2em">
<div style="FLOAT: left">CODE:</div>
<div style="FLOAT: right; TEXT-ALIGN: right">[Copy to
clipboard]</div>
</div>
<div class="altbg2" id="code17" style=
"CLEAR: both; BORDER-RIGHT: #f1f1f1 1px solid; PADDING-RIGHT: 10px; BORDER-TOP: #f1f1f1 1px solid; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; MARGIN: 3px 2em 2em; BORDER-LEFT: #f1f1f1 1px solid; WORD-BREAK: break-all; PADDING-TOP: 5px; BORDER-BOTTOM: #f1f1f1 1px solid">
<span style="COLOR: #000000"><span style=
"COLOR: #0000bb">&lt;?php<br>
$g1&nbsp;</span><span style=
"COLOR: #007700">=&nbsp;</span><span style=
"COLOR: #0000bb">mc_add_group</span><span style=
"COLOR: #007700">();&nbsp;&nbsp;&nbsp;&nbsp;</span><span style=
"COLOR: #ff8000">//&nbsp;添加第一个组<br></span><span style=
"COLOR: #0000bb">$g2&nbsp;</span><span style=
"COLOR: #007700">=&nbsp;</span><span style=
"COLOR: #0000bb">mc_add_group</span><span style=
"COLOR: #007700">();&nbsp;&nbsp;&nbsp;&nbsp;</span><span style=
"COLOR: #ff8000">//&nbsp;添加第二个组<br></span><span style=
"COLOR: #0000bb">mc_add_server</span><span style=
"COLOR: #007700">(</span><span style=
"COLOR: #0000bb">$g1</span><span style=
"COLOR: #007700">,&nbsp;</span><span style=
"COLOR: #dd0000">'localhost:11211'</span><span style=
"COLOR: #007700">);&nbsp;&nbsp;&nbsp;&nbsp;</span><span style=
"COLOR: #ff8000">//&nbsp;在第一个组中添加第一台服务器<br></span><span style=
"COLOR: #0000bb">mc_add_server</span><span style=
"COLOR: #007700">(</span><span style=
"COLOR: #0000bb">$g1</span><span style=
"COLOR: #007700">,&nbsp;</span><span style=
"COLOR: #dd0000">'localhost:11212'</span><span style=
"COLOR: #007700">);&nbsp;&nbsp;&nbsp;&nbsp;</span><span style=
"COLOR: #ff8000">//&nbsp;在第一个组中添加第二台服务器<br></span><span style=
"COLOR: #0000bb">mc_add_server</span><span style=
"COLOR: #007700">(</span><span style=
"COLOR: #0000bb">$g2</span><span style=
"COLOR: #007700">,&nbsp;</span><span style=
"COLOR: #dd0000">'10.0.0.16:11211'</span><span style=
"COLOR: #007700">);&nbsp;&nbsp;&nbsp;&nbsp;</span><span style=
"COLOR: #ff8000">//&nbsp;在第二个组中添加第一台服务器<br></span><span style=
"COLOR: #0000bb">mc_add_server</span><span style=
"COLOR: #007700">(</span><span style=
"COLOR: #0000bb">$g2</span><span style=
"COLOR: #007700">,&nbsp;</span><span style=
"COLOR: #dd0000">'10.0.0.17:11211'</span><span style=
"COLOR: #007700">);&nbsp;&nbsp;&nbsp;&nbsp;</span><span style=
"COLOR: #ff8000">//&nbsp;在第二个组中添加第二台服务器<br>
<br></span> <span style="COLOR: #0000bb">mc_set</span><span style=
"COLOR: #007700">(</span><span style=
"COLOR: #dd0000">'key'</span><span style=
"COLOR: #007700">,&nbsp;</span><span style=
"COLOR: #dd0000">'Hello'</span><span style=
"COLOR: #007700">);&nbsp;&nbsp;&nbsp;&nbsp;</span><span style=
"COLOR: #ff8000">//&nbsp;写入数据<br></span><span style=
"COLOR: #0000bb">$key&nbsp;</span><span style=
"COLOR: #007700">=&nbsp;</span><span style=
"COLOR: #0000bb">mc_get</span><span style=
"COLOR: #007700">(</span><span style=
"COLOR: #dd0000">'key'</span><span style=
"COLOR: #007700">);&nbsp;&nbsp;&nbsp;&nbsp;</span><span style=
"COLOR: #ff8000">//&nbsp;读出数据<br></span><span style=
"COLOR: #0000bb">mc_del</span><span style=
"COLOR: #007700">(</span><span style=
"COLOR: #dd0000">'key'</span><span style=
"COLOR: #007700">);&nbsp;&nbsp;&nbsp;&nbsp;</span><span style=
"COLOR: #ff8000">//&nbsp;删除数据<br></span><span style=
"COLOR: #0000bb">mc_shutdown</span><span style=
"COLOR: #007700">();&nbsp;&nbsp;&nbsp;&nbsp;</span><span style=
"COLOR: #ff8000">//&nbsp;关闭所有组<br></span><span style=
"COLOR: #0000bb">?&gt;</span></span></div>
APR_Memcache的相关资料可以在这里找到，BSM_Memcache可以在本站下载。<br>
<br>
<strong>◎APR环境介绍</strong><br>
<br>
APR的全称：Apache Portable
Runtime。它是Apache软件基金会创建并维持的一套跨平台的C语言库。它从Apache
httpd1.x中抽取出来并独立于httpd之外，Apache
httpd2.x就是建立在APR上。APR提供了很多方便的API接口可供使用，包括如内存池、字符串操作、网络、数组、hash表等实用的功能。开发Apache2
Module要接触很多APR函数，当然APR可以独立安装独立使用，可以用来写自己的应用程序，不一定是Apache
httpd的相关开发。
]]></description><guid>http://www.i170.com/Article/63475</guid><trackback:ping>http://www.i170.com/Article/63475/trackback</trackback:ping><comments>http://www.i170.com/Article/63475#comment</comments><wfw:commentRss>http://www.i170.com/Article/63475/commentRss</wfw:commentRss></item> <item><link>http://www.i170.com/Article/62523</link><title><![CDATA[[转]基于JSON的高级AJAX开发技术]]></title><author>Crazy</author><category>Javascript,技术研究,LAMP</category><pubDate>Mon, 09 Apr 2007 23:03:33  +0800</pubDate><description><![CDATA[<p><strong>一、 引言<br>
<br></strong>毫无疑问，AJAX已经成为当今Web开发中一种强有力的用户交互技术，但是它的许多可能性应用仍然鲜为人知。在本文中，我们将来共同探讨如何使用JavaScript对象标志(JSON)和JSON分析器在服务器和客户端AJAX引擎之间创建复杂而强有力的JSON数据传输层。我们将详细讨论如何创建一组对象(在其它语言中经常被当作一个包)，如何把这些对象串行化为JSON以发送到服务器端，以及如何把服务器端JSON反串行化为客户端JavaScript对象。<br>
<br>
提示：你可以在Douglas Crockford的网站上找到本文中使用的JSON分析器。<br>
<br>
在继续阅读前，本文假定你已经掌握了JavaScript技术并且了解如何创建一个基本的AJAX引擎，并经由AJAX技术向服务器端发出请求和从服务器端接收响应。为了更好地理解本文中示例，你需要下载本文相应的源码文件。<br></p>
<p class="partingline">[separator]</p>
<p><br>
<strong>二、 开始</strong><br>
<br>
为了进一步抽象我们的AJAX请求并有助于我们以后在不同的应用程序间共享AJAX引擎代码，本文使用了一个我自己创建的AJAX引擎。为了使用这个引擎，我们简单地导入三个JavaScript文件并且向一个名为AjaxUpdater的对象发出请求。然后，由该引擎来负责处理其它任务，包括把响应代理到在该请求中指定的回调方法中。下面的示例展示了我们如何使用这个引擎发出请求以及导入相关的文件：<br>
<br></p>
<table cellspacing="0" bordercolordark="#ffffff" cellpadding="2"
align="center" summary="" bordercolorlight="#000000" border="1">
<tbody>
<tr>
<td class="code" bgcolor="#E6E6E6">
<pre>
＜script type="text/javascript"src="javascript/model/Ajax.js"＞＜/script＞<br>
<br>
＜script type="text/javascript" src="javascript/model/HTTP.js"＞＜/script＞<br>
<br>
＜script type="text/javascript" src="javascript/model/AjaxUpdater.js"＞＜/script＞<br>
<br>
＜script type="text/javascript"＞<br>
<br>
document.load = AjaxUpdater.Update(’GET’， URL， callback);<br>
<br>
＜/script＞ 
</pre></td>
</tr>
</tbody>
</table>
<p><br>
<br>
首先，让我们来讨论JavaScript对象。<br>
<br>
<strong>三、 JavaScript对象</strong><br>
<br>
JavaScript以前经常被误解，似乎它主要用于实现客户浏览器端图形效果。其实，JavaScript是一种强有力的语言，特别当它与AJAX以及一个应用程序的服务器端相结合时；但是，即使在客户端，JavaScript也能够实现远比你预料得多的多的功能。面向对象的JavaScript就是一个示例，它能够使我们创建对象，扩展内在对象，甚至能够把我们的对象创建成包以达到更容易的管理之目的。<br>
<br>
在本文示例中，我们将创建三个对象：Auto，Car和Wheel。其中，每一个都是简单的对象；在此，我们仅使用它们来展示如何创建一个基本包。<br>
<br>
首先，Auto对象被声明为一个新的对象：<br>
<br></p>
<table cellspacing="0" bordercolordark="#ffffff" cellpadding="2"
align="center" summary="" bordercolorlight="#000000" border="1">
<tbody>
<tr>
<td class="code" bgcolor="#E6E6E6">
<pre>
var Auto = new Object();
</pre></td>
</tr>
</tbody>
</table>
<p><br>
<br>
注意，这个Auto对象将用作Car对象的父类。因此，Car对象将成为Auto对象的一个属性，只不过它被分离到另一个文件中以更易于管理（这个概念经常被用于其它面向对象的语言中，但是在JavaScript中却并不经常提起它）。下面是这个Car对象相应的代码：<br>
<br></p>
<table cellspacing="0" bordercolordark="#ffffff" cellpadding="2"
align="center" summary="" bordercolorlight="#000000" border="1">
<tbody>
<tr>
<td class="code" bgcolor="#E6E6E6">
<pre>
Auto.Car = new Object();<br>
<br>
Auto.Car.color = "#fff";<br>
<br>
Auto.Car.setColor = function(_color)<br>
<br>
{<br>
<br>
　Auto.Car.color = _color;<br>
<br>
}<br>
<br>
Auto.Car.setColor("#333"); 
</pre></td>
</tr>
</tbody>
</table>
<p>
如你所见，该Car对象是Auto对象的一个子对象—这分明是一种类对象层次结构。这个对象有一个名为color的属性和一个用于设置它的方法。在此，我们把color属性设置为灰色以覆盖掉缺省的白色。当在后面我们串行化该对象时请牢记住这个事实。<br>
<br>
下一个对象，Wheel，是Car的一个子对象：</p>
<table cellspacing="0" bordercolordark="#ffffff" cellpadding="2"
align="center" summary="" bordercolorlight="#000000" border="1">
<tbody>
<tr>
<td class="code" bgcolor="#E6E6E6">
<pre>
Auto.Car.Wheel = new Object();<br>
<br>
Auto.Car.Wheel.color = "#000";
</pre></td>
</tr>
</tbody>
</table>
<p>
&lt;在此，Wheel是一个基本对象，但是它展示了对象层次中的又一个层。这个对象有一个称为color的缺省值为黑色（“#000”）的属性。<br>
<br>
下面，让我们来分析一下为什么这些对象如此重要以及我们是如何使用它们提供的简单的属性的。</p>
<p><strong>四、 把JavaScript对象串行化为JSON<br>
<br></strong>借助于JSON分析器，我们可以很容易地把刚才创建的JavaScript对象串行化为JSON。首先，我们需要下载该分析器的一个副本，并且要把它添加到文档中。下面是我在本文示例中用于导入该脚本的相应的代码：</p>
<table cellspacing="0" bordercolordark="#ffffff" cellpadding="2"
align="center" summary="" bordercolorlight="#000000" border="1">
<tbody>
<tr>
<td class="code" bgcolor="#E6E6E6">
<pre>
＜script type="text/javascript" src="javascript/utils/jsonparser.js"＞
</pre>
<pre>
＜/script＞
</pre></td>
</tr>
</tbody>
</table>
我已经把该分析器添加到我的javascript目录，即一个称为utils的子目录下。<br>
<br>
下面是最终的包括到其中用于导入适当的JavaScript文件的代码片断：<br>
<br>
<table cellspacing="0" bordercolordark="#ffffff" cellpadding="2"
align="center" summary="" bordercolorlight="#000000" border="1">
<tbody>
<tr>
<td class="code" bgcolor="#E6E6E6">
<pre>
＜script type="text/javascript" src="javascript/Auto.js"＞＜/script＞<br>
<br>
＜script type="text/javascript" src="javascript/Car.js"＞＜/script＞<br>
<br>
＜script type="text/javascript" src="javascript/Wheel.js"＞＜/script＞<br>
<br>
＜script type="text/javascript" src="javascript/utils/jsonparser.js"＞＜/script＞<br>
<br>
＜script type="text/javascript" src="javascript/model/Ajax.js"＞＜/script＞<br>
<br>
＜script type="text/javascript" src="javascript/model/HTTP.js"＞＜/script＞<br>
<br>
＜script type="text/javascript" src="javascript/model/AjaxUpdater.js"＞＜/script＞
</pre></td>
</tr>
</tbody>
</table>
在导入适当的文件后，我们可以通过把两个div元素和一个onload事件简单地添加到HTML文档中开始串行化。这两个div元素将分别拥有ID：body和loading。其中，这个loading标签将由AJAX引擎使用来指示进度情况，而body标签将用于显示消息。<br>
<br>
<table cellspacing="0" bordercolordark="#ffffff" cellpadding="2"
align="center" summary="" bordercolorlight="#000000" border="1">
<tbody>
<tr>
<td class="code" bgcolor="#E6E6E6">
<pre>
＜div id="loading"＞＜/div＞<br>
<br>
＜div id="body"＞＜/div＞
</pre></td>
</tr>
</tbody>
</table>
onload事件相应于body元素并且设置它的innerHTML属性为JavaScript对象（作为一个串行化的JSON字符串）。为了实现这一目的，我在Auto对象上使用了jsonparser.js文件内的toJSONString方法：<br>
<br>
<table cellspacing="0" bordercolordark="#ffffff" cellpadding="2"
align="center" summary="" bordercolorlight="#000000" border="1">
<tbody>
<tr>
<td class="code" bgcolor="#E6E6E6">
<pre>
＜body onload="document.getElementById(’body’).innerHTML = 
</pre>
<pre>
’＜b＞Local objects serialized as JSON＜/b＞
</pre>
<pre>
＜br/＞Auto Object: ’+ Auto.toJSONString();"＞
</pre></td>
</tr>
</tbody>
</table>
这段代码使用了Auto对象及其所有的子对象，并且使用JSON分析器的toJSONString方法把它们串行化为一个JSON字符串。然后，该数据可以被用作服务器端的一种数据交换格式。<br>
<br>
你可能还记得，在前面我们曾调用了一个称为setColor的方法来改变Car对象的颜色。当时，我使用它是因为我想向你展示串行化能够在运行时刻的任何点上实现，而且还为了反映出对象中最新的数据。<br>
<br>
如果你仔细分析一下onload事件，你会注意到，Car和Wheel对象都包装在方括号内，这些方括号代表了父对象（即Auto）。这意味着，该串行化的JavaScript对象能够在运行时刻被发送到服务器端以存储最新的数据，并且也可以在应用程序启动时从服务器端进行接收以便从数据库中检索多数的当前数据。最精彩的部分在于，为了创建一种“无缝”的过程，所有与服务器之间实现的数据交换都可以使用JSON技术来实现。<br>
<br>
下面，让我们来看一下相同的数据是如何从服务器端接收的，以及它们是如何被使用最新的数据（典型地，来源于一个数据库）串行化为客户端JavaScript对象的。<br>
<br>
<strong>五、 把JSON反串行化为客户端JavaScript对象</strong><br>
<br>
在本文中，我简单地把一个静态文件创建为JSON响应，但是在实际开发中，你可以把这些数据存储在一个数据库中并且使用一种服务器端语言返回它。基于这一能力，我们就可以轻松地创建一种强有力的数据交换过程！在前面，我们已经分析了这一串行化过程。凭基本的AJAX体验，你应该能够理解数据是如何被寄送到服务器端的。现在，让我们着手讨论反串行化的问题。首先来看一个针对本文示例提供的静态JSON文件。这个文件其实是我们在上一节中串行化的数据：<br>
<br>
<table cellspacing="0" bordercolordark="#ffffff" cellpadding="2"
align="center" summary="" bordercolorlight="#000000" border="1">
<tbody>
<tr>
<td class="code" bgcolor="#E6E6E6">
<pre>
{"Car":{"color":"#333"，"Wheel":{"color":"#000"}}}
</pre></td>
</tr>
</tbody>
</table>
作为一个请求JSON文件的示例，当我们点击下列链接时将请求这个串行化的Auto对象：<br>
<br>
<table cellspacing="0" bordercolordark="#ffffff" cellpadding="2"
align="center" summary="" bordercolorlight="#000000" border="1">
<tbody>
<tr>
<td class="code" bgcolor="#E6E6E6">
<pre>
＜a href="_javascript:    AjaxUpdater.Update(’GET’， ’json/data.js’，
</pre>
<pre>
 displayResponse);"＞Get remote JSON＜/a＞
</pre></td>
</tr>
</tbody>
</table>
一旦接收到响应消息，我们的称为displayResponse回调方法就会被激活，然后，我们就能够反串行化并开始使用这些对象：<br>
<br>
<table cellspacing="0" bordercolordark="#ffffff" cellpadding="2"
align="center" summary="" bordercolorlight="#000000" border="1">
<tbody>
<tr>
<td class="code" bgcolor="#E6E6E6">
<pre>
＜script type="text/javascript"＞<br>
<br>
function displayResponse()<br>
<br>
{<br>
<br>
　if(Ajax.checkReadyState(’loading’) == "OK")<br>
<br>
　{<br>
<br>
var Auto = Ajax.request.responseText.parseJSON();<br>
<br>
document.getElementById("body").innerHTML += "＜br/＞＜b＞Remote JSON unserialized＜/b＞";<br>
<br>
document.getElementById("body").innerHTML += "＜br/＞Car color: "+Auto.Car.color;<br>
<br>
document.getElementById("body").innerHTML += "＜br/＞Wheel color: "+Auto.Car.Wheel.color;<br>
<br>
　}<br>
<br>
}<br>
<br>
＜/script＞
</pre></td>
</tr>
</tbody>
</table>
<p>
这是相当激动人心的一部分！一旦我们拥有了该responseText，我们就能够简单地使用JSON分析器中的parseJSON方法来从串行化的数据中重建我们的Auto对象。借助于这个新的Auto对象，我们就可以调用相应的子对象。这个特征允许我们在服务器和客户端来回发送对象—而不必进行大量的分析工作，然而在以前标准的XML响应情况下我们将却必须这样做。这样以来，我们就可以创建出能够基于AJAX技术来保留自身状态的客户端JavaScript对象。</p>

]]></description><guid>http://www.i170.com/Article/62523</guid><trackback:ping>http://www.i170.com/Article/62523/trackback</trackback:ping><comments>http://www.i170.com/Article/62523#comment</comments><wfw:commentRss>http://www.i170.com/Article/62523/commentRss</wfw:commentRss></item> <item><link>http://www.i170.com/Article/62522</link><title><![CDATA[[转]Apache 2: MPM的引入带来性能改善]]></title><author>Crazy</author><category>技术研究,LAMP</category><pubDate>Mon, 09 Apr 2007 22:58:53  +0800</pubDate><description><![CDATA[Apache
2.0在性能上的改善最吸引人。在支持POSIX线程的Unix系统上，Apache可以通过不同的MPM运行在一种多进程与多线程相混合的模式下，增强部分配置的可扩充性能。相比于Apache
1.3，2.0版本做了大量的优化来提升处理能力和可伸缩性，并且大多数改进在默认状态下即可生效。但是在编译和运行时刻，2.0也有许多可以显著提高性能的选择。本文不想叙述那些以功能换取速度的指令，如HostnameLookups等，而只是说明在2.0中影响性能的最核心特性：MPM（Multi-Processing
Modules，多道处理模块）的基本工作原理和配置指令。<br>
<br>
　　毫不夸张地说，MPM的引入是Apache 2.0最重要的变化。大家知道，Apache是基于模块化的设计，而Apache
2.0更扩展了模块化设计到Web服务器的最基本功能。服务器装载了一种多道处理模块，负责绑定本机网络端口、接受请求，并调度子进程来处理请求。扩展模块化设计有两个重要好处：<br>
<br>
　　◆ Apache可以更简洁、有效地支持多种操作系统；<br>
<br>
　　◆ 服务器可以按站点的特殊需要进行自定制。<br>
<br>
　　在用户级，MPM看起来和其它Apache模块非常类似。主要区别是在任意时刻只能有一种MPM被装载到服务器中。
<p class="partingline">[separator]</p>
<br>
<br>
　　<strong>指定MPM的方法</strong><br>
<br>
　　下面以Red Hat Linux 9为平台，说明在Apache 2.0中如何指定MPM
(Apache采用2.0.45)。先解压缩源代码包httpd-2.0.45.tar.gz，生成httpd-2.0.45目录（Apache
1.3源代码包的命名规则是apache_1.3.NN.tar.gz，而2.0版则是httpd-2.0.NN.tar.gz，其中NN是次版本号）。<br>
<br>
　　进入httpd-2.0.45目录，运行以下代码：
<table width="550" align="center" class="t_table">
<tbody>
<tr>
<td>$ ./configure --help|grep mpm</td>
</tr>
</tbody>
</table>
　　显示如下：
<table width="550" align="center" class="t_table">
<tbody>
<tr>
<td>--with-mpm=MPMChoose the process model for Apache to
use.MPM={beos|worker|prefork|mpmt_os2|
perchild|leader|threadpool}</td>
</tr>
</tbody>
</table>
　　上述操作用来选择要使用的进程模型，即哪种MPM模块。Beos、mpmt_os2分别是BeOS和OS/2上缺省的MPM，perchild主要设计目的是以不同的用户和组的身份来运行不同的子进程。这在运行多个需要CGI的虚拟主机时特别有用，会比1.3版中的SuExec机制做得更好。leader和threadpool都是基于worker的变体，还处于实验性阶段，某些情况下并不会按照预期设想的那样工作，所以Apache官方也并不推荐使用。因此，我们主要阐述prefork和worker这两种和性能关系最大的产品级MPM
( 有关其它的MPM详细说明，请参见Apache官方文档：<a target="_blank" href=
"http://httpd.apache.org/docs-2.0/mod/)">http://httpd.apache.org/docs-2.0/mod/)</a>。<br>
<br>
　　<strong>prefork的工作原理及配置</strong><br>
<br>
　　如果不用“--with-mpm”显式指定某种MPM，prefork就是Unix平台上缺省的MPM。它所采用的预派生子进程方式也是Apache
1.3中采用的模式。prefork本身并没有使用到线程，2.0版使用它是为了与1.3版保持兼容性；另一方面，prefork用单独的子进程来处理不同的请求，进程之间是彼此独立的，这也使其成为最稳定的MPM之一。<br>
<br>
　　若使用prefork，在make编译和make install安装后，使用“httpd
-l”来确定当前使用的MPM，应该会看到prefork.c（如果看到worker.c说明使用的是worker
MPM，依此类推）。再查看缺省生成的httpd.conf配置文件，里面包含如下配置段：
<table width="550" align="center" class="t_table">
<tbody>
<tr>
<td>&lt;IfModule prefork.c&gt;<br>
StartServers&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; 5<br>
MinSpareServers&nbsp; &nbsp;&nbsp; &nbsp;5<br>
MaxSpareServers&nbsp; &nbsp;&nbsp;&nbsp;10<br>
MaxClients&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;150<br>
MaxRequestsPerChild&nbsp;&nbsp;0<br>
&lt;/IfModule&gt;<br></td>
</tr>
</tbody>
</table>
　　prefork的工作原理是，控制进程在最初建立“StartServers”个子进程后，为了满足MinSpareServers设置的需要创建一个进程，等待一秒钟，继续创建两个，再等待一秒钟，继续创建四个……如此按指数级增加创建的进程数，最多达到每秒32个，直到满足MinSpareServers设置的值为止。这就是预派生（prefork）的由来。这种模式可以不必在请求到来时再产生新的进程，从而减小了系统开销以增加性能。<br>
<br>
　　MaxSpareServers设置了最大的空闲进程数，如果空闲进程数大于这个值，Apache会自动kill掉一些多余进程。这个值不要设得过大，但如果设的值比MinSpareServers小，Apache会自动把其调整为MinSpareServers+1。如果站点负载较大，可考虑同时加大MinSpareServers和MaxSpareServers。<br>
<br>
　　MaxRequestsPerChild设置的是每个子进程可处理的请求数。每个子进程在处理了“MaxRequestsPerChild”个请求后将自动销毁。0意味着无限，即子进程永不销毁。虽然缺省设为0可以使每个子进程处理更多的请求，但如果设成非零值也有两点重要的好处：<br>
<br>
　　◆ 可防止意外的内存泄漏；<br>
<br>
　　◆ 在服务器负载下降的时侯会自动减少子进程数。<br>
<br>
　　因此，可根据服务器的负载来调整这个值。笔者认为10000左右比较合适。<br>
<br>
　　MaxClients是这些指令中最为重要的一个，设定的是Apache可以同时处理的请求，是对Apache性能影响最大的参数。其缺省值150是远远不够的，如果请求总数已达到这个值（可通过ps
-ef|grep http|wc
-l来确认），那么后面的请求就要排队，直到某个已处理请求完毕。这就是系统资源还剩下很多而HTTP访问却很慢的主要原因。系统管理员可以根据硬件配置和负载情况来动态调整这个值。虽然理论上这个值越大，可以处理的请求就越多，但Apache默认的限制不能大于256。如果把这个值设为大于256，那么Apache将无法起动。事实上，256对于负载稍重的站点也是不够的。在Apache
1.3中，这是个硬限制。如果要加大这个值，必须在“configure”前手工修改的源代码树下的src/include/httpd.h中查找256，就会发现“#define
HARD_SERVER_LIMIT 256”这行。把256改为要增大的值（如4000），然后重新编译Apache即可。在Apache
2.0中新加入了ServerLimit指令，使得无须重编译Apache就可以加大MaxClients。下面是笔者的prefork配置段：
<table width="550" align="center" class="t_table">
<tbody>
<tr>
<td>&lt;IfModule prefork.c&gt;<br>
StartServers&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;10<br>
MinSpareServers&nbsp; &nbsp;&nbsp; &nbsp;10<br>
MaxSpareServers&nbsp; &nbsp;&nbsp;&nbsp;15<br>
ServerLimit&nbsp; &nbsp;&nbsp; &nbsp; 2000<br>
MaxClients&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;1000<br>
MaxRequestsPerChild&nbsp;&nbsp;10000<br>
&lt;/IfModule&gt;<br></td>
</tr>
</tbody>
</table>
　　上述配置中，ServerLimit的最大值是20000，对于大多数站点已经足够。如果一定要再加大这个数值，对位于源代码树下server/mpm/prefork/prefork.c中以下两行做相应修改即可：
<table width="550" align="center" class="t_table">
<tbody>
<tr>
<td>#define DEFAULT_SERVER_LIMIT 256#define MAX_SERVER_LIMIT
20000</td>
</tr>
</tbody>
</table>
　　<strong>worker的工作原理及配置</strong><br>
<br>
　　相对于prefork，worker是2.0
版中全新的支持多线程和多进程混合模型的MPM。由于使用线程来处理，所以可以处理相对海量的请求，而系统资源的开销要小于基于进程的服务器。但是，worker也使用了多进程，每个进程又生成多个线程，以获得基于进程服务器的稳定性。这种MPM的工作方式将是Apache
2.0的发展趋势。<br>
<br>
　　在configure -with-mpm=worker后，进行make编译、make
install安装。在缺省生成的httpd.conf中有以下配置段：
<table width="550" align="center" class="t_table">
<tbody>
<tr>
<td>&lt;IfModule worker.c&gt;<br>
StartServers&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;2<br>
MaxClients&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;150<br>
MinSpareThreads&nbsp; &nbsp;&nbsp;&nbsp;25<br>
MaxSpareThreads&nbsp; &nbsp;&nbsp;&nbsp;75<br>
ThreadsPerChild&nbsp; &nbsp;&nbsp;&nbsp;25<br>
MaxRequestsPerChild&nbsp;&nbsp;0<br>
&lt;/IfModule&gt;<br></td>
</tr>
</tbody>
</table>
　　worker的工作原理是，由主控制进程生成“StartServers”个子进程，每个子进程中包含固定的ThreadsPerChild线程数，各个线程独立地处理请求。同样，为了不在请求到来时再生成线程，MinSpareThreads和MaxSpareThreads设置了最少和最多的空闲线程数；而MaxClients设置了所有子进程中的线程总数。如果现有子进程中的线程总数不能满足负载，控制进程将派生新的子进程。<br>
<br>
　　MinSpareThreads和MaxSpareThreads的最大缺省值分别是75和250。这两个参数对Apache的性能影响并不大，可以按照实际情况相应调节。<br>
<br>
　　ThreadsPerChild是worker
MPM中与性能相关最密切的指令。ThreadsPerChild的最大缺省值是64，如果负载较大，64也是不够的。这时要显式使用ThreadLimit指令，它的最大缺省值是20000。上述两个值位于源码树server/mpm/worker/worker.c中的以下两行：
<table width="550" align="center" class="t_table">
<tbody>
<tr>
<td>#define DEFAULT_THREAD_LIMIT 64<br>
#define MAX_THREAD_LIMIT 20000<br></td>
</tr>
</tbody>
</table>
　　这两行对应着ThreadsPerChild和ThreadLimit的限制数。最好在configure之前就把64改成所希望的值。注意，不要把这两个值设得太高，超过系统的处理能力，从而因Apache不起动使系统很不稳定。<br>
<br>
　　Worker模式下所能同时处理的请求总数是由子进程总数乘以ThreadsPerChild值决定的，应该大于等于MaxClients。如果负载很大，现有的子进程数不能满足时，控制进程会派生新的子进程。默认最大的子进程总数是16，加大时也需要显式声明ServerLimit（最大值是20000）。这两个值位于源码树server/mpm/worker/worker.c中的以下两行：
<table width="550" align="center" class="t_table">
<tbody>
<tr>
<td>#define DEFAULT_SERVER_LIMIT 16<br>
#define MAX_SERVER_LIMIT 20000<br></td>
</tr>
</tbody>
</table>
　　需要注意的是，如果显式声明了ServerLimit，那么它乘以ThreadsPerChild的值必须大于等于MaxClients，而且MaxClients必须是ThreadsPerChild的整数倍，否则Apache将会自动调节到一个相应值（可能是个非期望值）。下面是笔者的worker配置段：
<table width="550" align="center" class="t_table">
<tbody>
<tr>
<td>&lt;IfModule worker.c&gt;<br>
StartServers&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;3<br>
MaxClients&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;2000<br>
ServerLimit&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;25<br>
MinSpareThreads&nbsp; &nbsp;&nbsp;&nbsp;50<br>
MaxSpareThreads&nbsp; &nbsp;&nbsp;&nbsp;200<br>
ThreadLimit&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;200<br>
ThreadsPerChild&nbsp; &nbsp;&nbsp;&nbsp;100<br>
MaxRequestsPerChild&nbsp;&nbsp;0<br>
&lt;/IfModule&gt;<br></td>
</tr>
</tbody>
</table>
<p>　　通过上面的叙述，可以了解到Apache
2.0中prefork和worker这两个重要MPM的工作原理，并可根据实际情况来配置Apache相关的核心参数，以获得最大的性能和稳定性。&nbsp;</p>

]]></description><guid>http://www.i170.com/Article/62522</guid><trackback:ping>http://www.i170.com/Article/62522/trackback</trackback:ping><comments>http://www.i170.com/Article/62522#comment</comments><wfw:commentRss>http://www.i170.com/Article/62522/commentRss</wfw:commentRss></item> <item><link>http://www.i170.com/Article/62521</link><title><![CDATA[[转]MySQL中SQL优化和架构设计的一些简单想法]]></title><author>Crazy</author><category>技术研究,LAMP</category><pubDate>Mon, 09 Apr 2007 22:56:19  +0800</pubDate><description><![CDATA[<p>
普通MySQL运行，数据量和访问量不大的话，是足够快的，但是当数据量和访问量剧增的时候，那么就会明显发现MySQL很慢，甚至down掉，那么就要考虑优化我们的MySQL了。</p>
<p>优化无非是从三个角度入手：<br>
<strong>第一个</strong>是从硬件，增加硬件，增加服务器<br>
<strong>第二个</strong>就是对我们的MySQL服务器进行优化，增加缓存大小，开多端口，读写分开<br>
<strong>第三个</strong>就是我们的应用优化，建立索引，优化SQL查询语句，建立缓存等等</p>
<p>
我就简单的说说SQL查询语句的优化。因为如果我们Web服务器比数据库服务器多或者性能优良的话，我们完全可以把数据库的压力转嫁到Web服务器上，因为如果单台MySQL，或者
Master/Slave
架构的数据库服务器都负担比较重，那么就可以考虑把MySQL的运算放到Web服务器上去进行。当然了，如果你Web服务器比数据库服务器差，那就把压力放在数据库服务器上吧，呵呵。</p>
<p>
如果是把MySQL服务器的压力放在Web服务器上，那么很多运算就需要我们的程序去执行，比如Web程序中全部交给PHP脚本去处理数据。单台MySQL服务器，查询、更新、插入、删除都在一台服务器上的话，访问量一大，你会明显发现锁表现象，当对一个表进行更新删除操作的时候，就会拒绝其他操作，这样就会导致锁表，解决这个问题最简单直接的办法就是拿两台MySQL服务器，一台负责查询（select）操作，另外一台负责更改（update/delete/insert），然后进行同步，这样能够避免锁表，如果服务器更多，那么就更好处理了，可以采用分布式数据库架构和数据的散列存储，下面我们会简单说一下。</p>
<p>&nbsp;</p>
<p class="partingline">[separator]</p>
<p><font color="#800000" size=
"3"><strong>一、SQL的优化和注意事项</strong></font></p>
<p>
现在我们假设我们只有一台MySQL服务器，所有的select/update/insert/delete操作都是在这上面进行的，我们同时有三台Web服务器，通过DNS轮巡来访问，那么我们如何进行我们应用程序和SQL的优化。</p>
<p><strong>1. Where条件</strong><br>
在查询中，<strong>WHERE</strong>条件也是一个比较重要的因素，尽量少并且是合理的where条件是很重要的，在写每一个where条件的时候都要仔细考虑，尽量在多个条件的时候，把会提取尽量少数据量的条件放在前面，这样就会减少后一个where条件的查询时间。<br>
有时候一些where条件会导致索引无效，当使用了Mysql函数的时候，索引将无效，比如：select * from tbl1
where left(name, 4) =
'hylr'，那么这时候索引无效，还有就是使用<strong>LIKE</strong>进行搜索匹配的时候，这样的语句索引是无效的：select
* from tbl1 where name like '%xxx%'，但是这样索引是有效的：select * from tbl1
where name like 'xxx%'，所以谨慎的写你的SQL是很重要的。</p>
<p><strong>2. 关联查询和子查询</strong><br>
数据库一个很重要的特点是关联查询，<strong>LEFT JOIN</strong>
和<strong>全关联</strong>，特别是多个表进行关联，因为每个关联表查询的时候，进行扫描的时候都是一个笛卡尔乘积的数量级，扫描数量很大，如果确实是需要进行关联操作，请给where或者on的条件进行索引。<br>
关联操作也是可能交给应用去操作的，看数据量的大小，如果数据量不是非常大，比如10万条以下，那么就可以交给程序去处理（<a href=
"http://www.phpmore.com/?a=people&amp;uid=121">totododo</a>提出笔误，特此修正），程序分别提取左右两个表的数据，然后进行循环的扫描处理，返回结果，这个过程同样非常耗费Web服务器的资源，那么就需要取决于你愿意把压力放在Web服务器上或者数据库服务器上了。<br>
子查询是在mysql5中支持的功能，比如：select * from tbl1 where id in(select id from
tbl1)，那样效率是非常非常低，要尽量避免使用子查询，要是我，绝对不用，呵呵。</p>
<p><strong>3. &nbsp;一些耗费时间和资源的操作</strong><br>
SQL语句中一些浪费的操作，比如 <strong>DISTINCT、COUNT、GROUP
BY、</strong>各种MySQL函数。这些操作都是比较耗资源的，我想应用最多的是count字句吧，如果使用count，尽量不要count（*），最好count一个字段，比如count（id），或者count(1)，（据<a href="http://www.phpmore.com/?a=people&amp;uid=121">totododo</a>测试效率其实是一样的），同样能够起到统计的作用。如果不是十分必要，尽量不要使用distinct操作，就是提取唯一值，你完全可以把这个操作交给脚本程序去执行提取唯一值，减少MySQL的负担。group
by 操作也是，确实需要分组的话，请谨慎的操作，如果是小批量的数据，可以考虑交给脚本程序去做。<br>
至于MySQL的函数，估计很多常用，比如有人喜欢把截取字符串也交给MySQL去操作，或者时间转换操作，使用比较多的函数像
<strong>SUBSTR(), CONCAT(), DATE_FORMAT(), TO_DAYS(), MAX(), MIN(),
MD5()</strong> 等等，这些操作完全可以交给脚本程序去做，减轻MySQL的负担。</p>
<p><strong>4. 合理的建立索引</strong><br>
索引的提升速度的一个非常重要的手段，索引在对一些经常进行select操作，并且值比较唯一的字段是相当有效的，比如主键的id字段，唯一的名字name字段等等。<br>
但是索引对于唯一值比较少的字段，比如性别gender字段，寥寥无几的类别字段等，意义不大，因为性别是50%的几率，索引几乎没有意义。对于update/delete/insert非常频繁的表，建立索引要慎重考虑，因为这些频繁的操作同样对于索引的维护工作量也是很大的，最后反而得不偿失，这个需要自己仔细考虑。索引同样不是越多越好，适当的索引会起到很关键的作用，不适当的索引，反而减低效率维护，增加维护索引的负担。</p>
<p><strong>5. 监控sql执行效率</strong><br>
在select语句前面使用EXPLAIN字句能够查看当前这个select字句的执行情况，包括使用了什么操作、返回多少几率、对索引的使用情况如何等等，能够有效分析SQL语句的执行效率和合理程度。<br>
另外使用MySQL中本身的慢查询日志：slow-log，同样能够记录查询中花费时间比较多的SQL语句，好对相应的语句进行优化和改写。<br>
另外在MySQL终端下，使用show
processlist命令能够有效的查看当前MySQL在进行的线程，包括线程的状态，是否锁表等等，可以实时的查看SQL执行情况，同时对一些锁表操作进行优化。</p>
<p>&nbsp;</p>
<p><strong><font color="#800000" size=
"3">二、数据库服务器的架构和分布想法</font></strong></p>
<p>
对于服务器的架构设计，这个其实是比较重要的，一个合理的设计，能够让应用更好的运行。当然，架构的设计，取决于你的应用和你硬件的实际情况。我就简单的说说几种不同的数据库架构设计方式，权当是一个个人的想法，希望能够有帮助。</p>
<p><strong>1.
单台服务器开多进程和端口<br></strong>单台MySQL服务器，如果使用长链接等等都无法解决负载太大，连接太多的问题，不凡考虑采用一台MySQL上使用多个端口开启多个MySQL守护进程的方法来缓解压力。当然，前提是你的应用必须支持多端口，并且你的cpu和内存足够运行多个守护进程。<br>
<strong>优点</strong>
是能够很好的缓解暂时服务器的压力，把不同的操作放在不同的端口，或者把不同的项目模块放在不同的端口去操作，良好的分担单个守护进程的压力。<br>
<strong>缺点</strong> 是数据可能会产生紊乱，同时可能会导致很多未知的莫名错误。呵呵</p>
<p><strong>2. 使用Master/Slave的服务器结构</strong><br>
Mysql本身具有同步功能，完全可以利用这个功能。构建 Master/Slave
的主从服务器结构，最少只需要两台MySQL服务器，我们可以把 Master 服务器用户更新操作，包括
update/delete/insert，把Slave服务器用于查询操作，包括 select 操作，然后两机进行同步。<br>
<strong>优点</strong> 是合理的把更新和查询的压力分担，并且能够避免锁表的问题。<br>
<strong>缺点</strong>
是更新部实时，如果网络繁忙，可能会存在延迟的问题，并且任何一台服务器down掉了都很麻烦。</p>
<p><strong>3. 使用分布式的散列存储</strong><br>
这种结构适合大数据量，并且负载比较大，然后服务器比较充足的情况。分布式存储结构，简单的可以是多台服务器，每台服务器功能是类似的，但是存储的数据不一样，比如做一个用户系统，那么把用户ID在1-10万以内的存储在A服务器，用户ID在10-20万存储在B服务器，20-3-万存储在C服务器，以此类推。如果每个用户访问的服务器不足，可以构建组服务器，就是每组用户拥有多台服务器，比如可以在某用户组建立两台MySQL服务器，一台Master，一台Slave，同样分离他们的更新和查询操作，或者可以设计成双向同步。同时，你的应用程序必须支持跨数据库和跨服务器的操作能力。<br>
<strong>优点</strong>
是服务器的负载合理的被平摊，每台服务器都是负责一部分用户，如果一台服务器down掉了，不会影响其他用户ID的用户正常访问。同时添加节点比较容易，如果又增加了10万用户，那么又可以增加一个节点服务器，升级很方便。<br>
<strong>缺点</strong>
是任何一台数据库服务器down掉或者数据丢失，那么这部分服务器的用户将很郁闷，数据都没了，当然，这个需要良好的备份机制。</p>
<p><br>
另外，MySQL5.1已经有中文手册，第七章详细的讲解了MySQL优化的知识，值得学习：<a href=
"http://www.mysql.org/doc/refman/5.1/zh/optimization.html">http://www.mysql.org/doc/refman/5.1/zh/optimization.html</a></p>

]]></description><guid>http://www.i170.com/Article/62521</guid><trackback:ping>http://www.i170.com/Article/62521/trackback</trackback:ping><comments>http://www.i170.com/Article/62521#comment</comments><wfw:commentRss>http://www.i170.com/Article/62521/commentRss</wfw:commentRss></item> <item><link>http://www.i170.com/Article/62520</link><title><![CDATA[[转]Apache的一些必要的mod安装]]></title><author>Crazy</author><category>技术研究,LAMP</category><pubDate>Mon, 09 Apr 2007 22:53:15  +0800</pubDate><description><![CDATA[PS:
<em><br></em>Apache强大指出在于方便的插件和模块技术，这里安装的是部分不常用但是很不错的模块，包括：防范拒绝服务器攻击的mod_evasive，用于防注入等安全性防范的mod_security，以及对网页进行压缩的mod_deflate等等模块
<p>&nbsp;</p>
<p class="partingline">[separator]</p>
<p>模块：<strong>mod_evasive</strong><br>
作用：防止DDOS的攻击<br>
介绍：mod_evasive模块的前身就是mod_dosevasive<br>
下载：<a href=
"http://www.nuclearelephant.com/projects/mod_evasive">http://www.nuclearelephant.com/projects/mod_evasive</a></p>
<p>安装<br>
# tar zxvf mod_evasive_1.10.1.tar.gz<br>
# cd mod_evasive_1.10.1<br>
# /usr/local/apache/bin/apxs -i -a -c mod_evasive20.c</p>
<p>打开 httpd.conf　文件<br>
查看是否有<br>
LoadModule evasive20_module modules/mod_evasive20.so<br>
如没有则加上去</p>
<p>并在httpd.conf里加入<br>
#################################</p>
<p>DOSHashTableSize 3097<br>
DOSPageCount 2<br>
DOSSiteCount 50<br>
DOSPageInterval 1<br>
DOSSiteInterval 1<br>
DOSBlockingPeriod 10</p>
<p>###################################</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>模块：<strong>mod_security<br></strong>作用：可以加强apache的安全性特别是在防sql
注入<br>
下载：<a href=
"http://www.modsecurity.org/download/">http://www.modsecurity.org/download/</a></p>
<p>安装<br>
# tar zxvf modsecurity-apache-1.9.tar.gz<br>
# cd modsecurity-apache-1.9/apache2/<br>
# /apache2/bin/apxs -cia mod_security.c</p>
<p>打开 httpd.conf 文件<br>
查看是否有<br>
LoadModule security_module modules/mod_security.so<br>
如没有则加上去</p>
<p>并在httpd.conf里加入<br>
#################################</p>
<p>SecFilterEngine On<br>
SecFilterCheckURLEncoding On<br>
SecFilterDefaultAction "deny,log,status:500"<br>
#SecFilterForceByteRange 32 126<br>
#SecFilterScanPOST On<br>
SecAuditLog logs/audit_log<br>
###<br>
SecFilter "\.\./"<br>
#####<br>
SecFilter /etc/*passwd<br>
SecFilter /bin/*sh</p>
<p>#for css attack<br>
SecFilter "&lt;( | )*script"<br>
SecFilter "&lt;(.| )+&gt;"<br>
#for sql attack<br>
SecFilter "delete[ ]+from"<br>
SecFilter "insert[ ]+into"<br>
SecFilter "select.+from"<br>
SecFilter "union[ ]+from"<br>
SecFilter "drop[ ]"</p>
<p>###############################</p>
<p>&nbsp;</p>
<p>模块：<strong>mod_deflate</strong><br>
作用：对网页进行压缩加快网页浏览速度<br>
下载：apache2自带</p>
<p>安装<br>
# /usr/local/apache2/bin/apxs -i -a -c
/root/httpd-2.0.48/modules/filters/mod_deflate.c</p>
<p>查看是否有<br>
LoadModule deflate_module modules/mod_deflate.so<br>
如没有则加上去</p>
<p>编辑 httpd.conf 文件加入以下内容：<br>
######################################<br>
DeflateFilterNote ratio<br>
LogFormat '"%v %h %l %u %t "%r" %&gt;s %b "%{Referer}i"
"%{User-Agent}i"" (%{ratio}n)' deflate</p>
<p>&nbsp;</p>
<p>SetOutputFilter DEFLATE<br>
BrowserMatch ^Mozilla/4 gzip-only-text/html<br>
BrowserMatch ^Mozilla/4.0[678] no-gzip<br>
BrowserMatch \bMSIE !no-gzip !gzip-only-text/html<br>
SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png)$ no-gzip
dont-vary<br>
#Header append Vary User-Agent env=!dont-vary</p>
<p><br>
#查找Customlog 注释原来的的一行，改成<br>
CustomLog logs/deflate_log deflate<br>
######################################</p>
<p>&nbsp;</p>
<p><br>
######################################<br>
SetOutputFilter DEFLATE<br>
BrowserMatch ^Mozilla/4 gzip-only-text/html<br>
BrowserMatch ^Mozilla/4.0[678] no-gzip<br>
BrowserMatch \bMSIE !no-gzip !gzip-only-text/html<br>
SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png)$ no-gzip
dont-vary<br>
#Header append Vary User-Agent env=!dont-vary</p>
<p><br>
#查找Customlog 注释原来的的一行，改成<br>
CustomLog logs/deflate_log deflate<br>
######################################</p>
<p>&nbsp;</p>
<p><br>
######################################<br></p>

]]></description><guid>http://www.i170.com/Article/62520</guid><trackback:ping>http://www.i170.com/Article/62520/trackback</trackback:ping><comments>http://www.i170.com/Article/62520#comment</comments><wfw:commentRss>http://www.i170.com/Article/62520/commentRss</wfw:commentRss></item> <item><link>http://www.i170.com/Article/62519</link><title><![CDATA[[转]PHP中GBK和UTF8编码处理]]></title><author>Crazy</author><category>技术研究,LAMP</category><pubDate>Mon, 09 Apr 2007 22:41:05  +0800</pubDate><description><![CDATA[<p>来源：<a href=
"http://blog.csdn.net/heiyeshuwu/archive/2007/01/20/1488900.aspx"><font face="Tahoma">http://blog.csdn.net/heiyeshuwu/archive/2007/01/20/1488900.aspx</font></a></p>
<p><strong>一、编码范围</strong></p>
<p>1. GBK (GB2312/GB18030)<br>
\x00-\xff&nbsp; GBK双字节编码范围<br>
\x20-\x7f&nbsp; ASCII<br>
\xa1-\xff&nbsp; 中文<br>
\x80-\xff&nbsp; 中文</p>
<p>2. UTF-8 (Unicode)<br>
\u4e00-\u9fa5 (中文)<br>
\x3130-\x318F (韩文<br>
\xAC00-\xD7A3 (韩文)<br>
\u0800-\u4e00 (日文)<br>
ps: 韩文是大于[\u9fa5]的字符</p>
<p><br>
正则例子:<br>
preg_replace("/([\x80-\xff])/","",$str);<br>
preg_replace("/([u4e00-u9fa5])/","",$str);</p>
<p class="partingline">[separator]</p>
<p><strong>二、代码例子</strong></p>
<p><span style="COLOR: #008000">&nbsp;</span></p>
<div><br>
<span style=
"COLOR: #ff9900; FONT-FAMILY: Courier New">//判断内容里有没有中文-GBK
(PHP)</span><br>
<span style=
"COLOR: #0000ff; FONT-FAMILY: Courier New">function</span>
<font face="Courier New"><font color=
"#000000">check_is_chinese</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">(</span></font><span style="COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style="COLOR: #008080; FONT-FAMILY: Courier New">s</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">)</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">{</span><br>
<font face="Courier New"><font color=
"#000000">&nbsp;&nbsp;&nbsp;&nbsp;</font><span style=
"COLOR: #0000ff; FONT-FAMILY: Courier New">return</span>
<span style=
"COLOR: #ff0000; FONT-FAMILY: Courier New">preg_match</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">(</span><span style="COLOR: #ff00ff; FONT-FAMILY: Courier New">'/[\x80-\xff]./'</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">,</span>
<span style=
"COLOR: #0000ff; FONT-FAMILY: Courier New">$</span></font><span style="COLOR: #008080; FONT-FAMILY: Courier New">s</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">)</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">;</span><br>
<span style="COLOR: #0000cc; FONT-FAMILY: Courier New">}</span><br>
<br>
<span style=
"COLOR: #ff9900; FONT-FAMILY: Courier New">//获取字符串长度-GBK
(PHP)</span><br>
<span style=
"COLOR: #0000ff; FONT-FAMILY: Courier New">function</span>
<font face="Courier New"><font color=
"#000000">gb_strlen</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">(</span></font><span style="COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style="COLOR: #008080; FONT-FAMILY: Courier New">str</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">)</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">{</span><br>
<font face="Courier New"><font color=
"#000000">&nbsp;&nbsp;&nbsp;&nbsp;</font><span style=
"COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style=
"COLOR: #008080; FONT-FAMILY: Courier New">count</span>
<span style="COLOR: #0000cc; FONT-FAMILY: Courier New">=</span>
<font color="#000000">0</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">;</span></font><br>
<font face="Courier New"><font color=
"#000000">&nbsp;&nbsp;&nbsp;&nbsp;</font><span style=
"COLOR: #0000ff; FONT-FAMILY: Courier New">for</span><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">(</span><span style=
"COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style=
"COLOR: #008080; FONT-FAMILY: Courier New">i</span><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">=</span><font color=
"#000000">0</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">;</span> <span style=
"COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style=
"COLOR: #008080; FONT-FAMILY: Courier New">i</span><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">&lt;</span><span style=
"COLOR: #ff0000; FONT-FAMILY: Courier New">strlen</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">(</span><span style="COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style="COLOR: #008080; FONT-FAMILY: Courier New">str</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">)</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">;</span>
<span style=
"COLOR: #0000ff; FONT-FAMILY: Courier New">$</span></font><span style="COLOR: #008080; FONT-FAMILY: Courier New">i</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">+</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">+</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">)</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">{</span><br>
<font face="Courier New"><font color=
"#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><span style="COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style="COLOR: #008080; FONT-FAMILY: Courier New">s</span>
<span style="COLOR: #0000cc; FONT-FAMILY: Courier New">=</span>
<span style=
"COLOR: #ff0000; FONT-FAMILY: Courier New">substr</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">(</span><span style="COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style="COLOR: #008080; FONT-FAMILY: Courier New">str</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">,</span>
<span style=
"COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style=
"COLOR: #008080; FONT-FAMILY: Courier New">i</span><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">,</span> <font color=
"#000000">1</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">)</span></font><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">;</span><br>
<font face="Courier New"><font color=
"#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><span style="COLOR: #0000ff; FONT-FAMILY: Courier New">if</span>
<span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">(</span><span style=
"COLOR: #ff0000; FONT-FAMILY: Courier New">preg_match</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">(</span><span style="COLOR: #ff00ff; FONT-FAMILY: Courier New">"/[\x80-\xff]/"</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">,</span>
<span style=
"COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style=
"COLOR: #008080; FONT-FAMILY: Courier New">s</span><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">)</span><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">)</span> <span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">+</span></font><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">+</span><span style="COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style="COLOR: #008080; FONT-FAMILY: Courier New">i</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">;</span><br>
<font face="Courier New"><font color=
"#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">+</span></font><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">+</span><span style="COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style="COLOR: #008080; FONT-FAMILY: Courier New">count</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">;</span><br>
<font face="Courier New"><font color=
"#000000">&nbsp;&nbsp;&nbsp;&nbsp;</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">}</span></font><br>
<font face="Courier New"><font color=
"#000000">&nbsp;&nbsp;&nbsp;&nbsp;</font><span style=
"COLOR: #0000ff; FONT-FAMILY: Courier New">return</span>
<span style=
"COLOR: #0000ff; FONT-FAMILY: Courier New">$</span></font><span style="COLOR: #008080; FONT-FAMILY: Courier New">count</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">;</span><br>
<span style="COLOR: #0000cc; FONT-FAMILY: Courier New">}</span><br>
<br>
<span style=
"COLOR: #ff9900; FONT-FAMILY: Courier New">//截取字符串字串-GBK
(PHP)</span><br>
<span style=
"COLOR: #0000ff; FONT-FAMILY: Courier New">function</span>
<font face="Courier New"><font color=
"#000000">gb_substr</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">(</span><span style=
"COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style=
"COLOR: #008080; FONT-FAMILY: Courier New">str</span><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">,</span> <span style=
"COLOR: #0000ff; FONT-FAMILY: Courier New">$</span></font><span style="COLOR: #008080; FONT-FAMILY: Courier New">len</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">)</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">{</span><br>
<font face="Courier New"><font color=
"#000000">&nbsp;&nbsp;&nbsp;&nbsp;</font><span style=
"COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style=
"COLOR: #008080; FONT-FAMILY: Courier New">count</span>
<span style="COLOR: #0000cc; FONT-FAMILY: Courier New">=</span>
<font color="#000000">0</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">;</span></font><br>
<font face="Courier New"><font color=
"#000000">&nbsp;&nbsp;&nbsp;&nbsp;</font><span style=
"COLOR: #0000ff; FONT-FAMILY: Courier New">for</span><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">(</span><span style=
"COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style=
"COLOR: #008080; FONT-FAMILY: Courier New">i</span><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">=</span><font color=
"#000000">0</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">;</span> <span style=
"COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style=
"COLOR: #008080; FONT-FAMILY: Courier New">i</span><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">&lt;</span><span style=
"COLOR: #ff0000; FONT-FAMILY: Courier New">strlen</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">(</span><span style="COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style="COLOR: #008080; FONT-FAMILY: Courier New">str</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">)</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">;</span>
<span style=
"COLOR: #0000ff; FONT-FAMILY: Courier New">$</span></font><span style="COLOR: #008080; FONT-FAMILY: Courier New">i</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">+</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">+</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">)</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">{</span><br>
<font face="Courier New"><font color=
"#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><span style="COLOR: #0000ff; FONT-FAMILY: Courier New">if</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">(</span><span style="COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style="COLOR: #008080; FONT-FAMILY: Courier New">count</span>
<span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">=</span><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">=</span> <span style=
"COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style=
"COLOR: #008080; FONT-FAMILY: Courier New">len</span><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">)</span> <span style=
"COLOR: #0000ff; FONT-FAMILY: Courier New">break</span></font><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">;</span><br>
<font face="Courier New"><font color=
"#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><span style="COLOR: #0000ff; FONT-FAMILY: Courier New">if</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">(</span><span style="COLOR: #ff0000; FONT-FAMILY: Courier New">preg_match</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">(</span><span style="COLOR: #ff00ff; FONT-FAMILY: Courier New">"/[\x80-\xff]/"</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">,</span>
<span style=
"COLOR: #ff0000; FONT-FAMILY: Courier New">substr</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">(</span><span style="COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style="COLOR: #008080; FONT-FAMILY: Courier New">str</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">,</span>
<span style=
"COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style=
"COLOR: #008080; FONT-FAMILY: Courier New">i</span><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">,</span> <font color=
"#000000">1</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">)</span><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">)</span><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">)</span> <span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">+</span></font><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">+</span><span style="COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style="COLOR: #008080; FONT-FAMILY: Courier New">i</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">;</span><br>
<font face="Courier New"><font color=
"#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">+</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">+</span><span style="COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style="COLOR: #008080; FONT-FAMILY: Courier New">count</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">;</span></font><font face="Courier New"><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">}</span></font><br>
<font face="Courier New"><font color=
"#000000">&nbsp;&nbsp;&nbsp;&nbsp;</font><span style=
"COLOR: #0000ff; FONT-FAMILY: Courier New">return</span>
<span style=
"COLOR: #ff0000; FONT-FAMILY: Courier New">substr</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">(</span><span style="COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style="COLOR: #008080; FONT-FAMILY: Courier New">str</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">,</span>
<font color="#000000">0</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">,</span> <span style=
"COLOR: #0000ff; FONT-FAMILY: Courier New">$</span></font><span style="COLOR: #008080; FONT-FAMILY: Courier New">i</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">)</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">;</span><br>
<span style="COLOR: #0000cc; FONT-FAMILY: Courier New">}</span><br>
<br>
<span style=
"COLOR: #ff9900; FONT-FAMILY: Courier New">//统计字符串长度-UTF8
(PHP)</span><br>
<span style=
"COLOR: #0000ff; FONT-FAMILY: Courier New">function</span>
<font face="Courier New"><font color=
"#000000">utf8_strlen</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">(</span><span style=
"COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style=
"COLOR: #008080; FONT-FAMILY: Courier New">str</span><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">)</span> <span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">{</span></font><br>
<font face="Courier New"><font color=
"#000000">&nbsp;&nbsp;&nbsp;&nbsp;</font><span style=
"COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style=
"COLOR: #008080; FONT-FAMILY: Courier New">count</span>
<span style="COLOR: #0000cc; FONT-FAMILY: Courier New">=</span>
<font color="#000000">0</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">;</span></font><br>
<font face="Courier New"><font color=
"#000000">&nbsp;&nbsp;&nbsp;&nbsp;</font><span style=
"COLOR: #0000ff; FONT-FAMILY: Courier New">for</span><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">(</span><span style=
"COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style=
"COLOR: #008080; FONT-FAMILY: Courier New">i</span> <span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">=</span> <font color=
"#000000">0</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">;</span> <span style=
"COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style=
"COLOR: #008080; FONT-FAMILY: Courier New">i</span> <span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">&lt;</span> <span style=
"COLOR: #ff0000; FONT-FAMILY: Courier New">strlen</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">(</span><span style="COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style="COLOR: #008080; FONT-FAMILY: Courier New">str</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">)</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">;</span>
<span style=
"COLOR: #0000ff; FONT-FAMILY: Courier New">$</span></font><span style="COLOR: #008080; FONT-FAMILY: Courier New">i</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">+</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">+</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">)</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">{</span><br>
<font face="Courier New"><font color=
"#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><span style="COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style="COLOR: #008080; FONT-FAMILY: Courier New">value</span>
<span style="COLOR: #0000cc; FONT-FAMILY: Courier New">=</span>
<span style=
"COLOR: #ff0000; FONT-FAMILY: Courier New">ord</span></font><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">(</span><span style="COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style="COLOR: #008080; FONT-FAMILY: Courier New">str</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">[</span><span style="COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style="COLOR: #008080; FONT-FAMILY: Courier New">i</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">]</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">)</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">;</span><br>
<font face="Courier New"><font color=
"#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><span style="COLOR: #0000ff; FONT-FAMILY: Courier New">if</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">(</span><span style="COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style="COLOR: #008080; FONT-FAMILY: Courier New">value</span>
<span style="COLOR: #0000cc; FONT-FAMILY: Courier New">&gt;</span>
<font color="#000000">127</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">)</span> <span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">{</span></font><br>
<font face="Courier New"><font color=
"#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><span style="COLOR: #0000ff; FONT-FAMILY: Courier New">$</span></font><span style="COLOR: #008080; FONT-FAMILY: Courier New">count</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">+</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">+</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">;</span><br>
<font face="Courier New"><font color=
"#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><span style="COLOR: #0000ff; FONT-FAMILY: Courier New">if</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">(</span><span style="COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style="COLOR: #008080; FONT-FAMILY: Courier New">value</span>
<span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">&gt;</span><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">=</span> <font color=
"#000000">192</font> <span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">&amp;</span><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">&amp;</span>
<span style="COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style="COLOR: #008080; FONT-FAMILY: Courier New">value</span>
<span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">&lt;</span><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">=</span> <font color=
"#000000">223</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">)</span> <span style=
"COLOR: #0000ff; FONT-FAMILY: Courier New">$</span></font><span style="COLOR: #008080; FONT-FAMILY: Courier New">i</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">+</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">+</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">;</span><br>
<font face="Courier New"><font color=
"#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><span style="COLOR: #0000ff; FONT-FAMILY: Courier New">elseif</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">(</span><span style="COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style="COLOR: #008080; FONT-FAMILY: Courier New">value</span>
<span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">&gt;</span><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">=</span> <font color=
"#000000">224</font> <span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">&amp;</span><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">&amp;</span>
<span style="COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style="COLOR: #008080; FONT-FAMILY: Courier New">value</span>
<span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">&lt;</span><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">=</span> <font color=
"#000000">239</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">)</span> <span style=
"COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style=
"COLOR: #008080; FONT-FAMILY: Courier New">i</span> <span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">=</span> <span style=
"COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style=
"COLOR: #008080; FONT-FAMILY: Courier New">i</span> <span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">+</span> <font color=
"#000000">2</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">;</span></font><br>
<font face="Courier New"><font color=
"#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><span style="COLOR: #0000ff; FONT-FAMILY: Courier New">elseif</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">(</span><span style="COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style="COLOR: #008080; FONT-FAMILY: Courier New">value</span>
<span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">&gt;</span><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">=</span> <font color=
"#000000">240</font> <span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">&amp;</span><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">&amp;</span>
<span style="COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style="COLOR: #008080; FONT-FAMILY: Courier New">value</span>
<span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">&lt;</span><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">=</span> <font color=
"#000000">247</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">)</span> <span style=
"COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style=
"COLOR: #008080; FONT-FAMILY: Courier New">i</span> <span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">=</span> <span style=
"COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style=
"COLOR: #008080; FONT-FAMILY: Courier New">i</span> <span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">+</span> <font color=
"#000000">3</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">;</span></font><br>
<font face="Courier New"><font color=
"#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><span style="COLOR: #0000ff; FONT-FAMILY: Courier New">else</span>
<span style=
"COLOR: #ff0000; FONT-FAMILY: Courier New">die</span></font><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">(</span><span style="COLOR: #ff00ff; FONT-FAMILY: Courier New">'Not
a UTF-8 compatible string'</span><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">)</span><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">;</span><br>
<font face="Courier New"><font color=
"#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">}</span></font><br>
<font face="Courier New"><font color=
"#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><span style="COLOR: #0000ff; FONT-FAMILY: Courier New">$</span></font><span style="COLOR: #008080; FONT-FAMILY: Courier New">count</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">+</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">+</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">;</span><br>
<font face="Courier New"><font color=
"#000000">&nbsp;&nbsp;&nbsp;&nbsp;</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">}</span></font><br>
<font face="Courier New"><font color=
"#000000">&nbsp;&nbsp;&nbsp;&nbsp;</font><span style=
"COLOR: #0000ff; FONT-FAMILY: Courier New">return</span>
<span style=
"COLOR: #0000ff; FONT-FAMILY: Courier New">$</span></font><span style="COLOR: #008080; FONT-FAMILY: Courier New">count</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">;</span><br>
<span style="COLOR: #0000cc; FONT-FAMILY: Courier New">}</span><br>
<br>
<br>
<span style=
"COLOR: #ff9900; FONT-FAMILY: Courier New">//截取字符串-UTF8(PHP)</span><br>
<span style=
"COLOR: #0000ff; FONT-FAMILY: Courier New">function</span>
<font face="Courier New"><font color=
"#000000">utf8_substr</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">(</span></font><span style="COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style="COLOR: #008080; FONT-FAMILY: Courier New">str</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">,</span><span style="COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style="COLOR: #008080; FONT-FAMILY: Courier New">position</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">,</span><span style="COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style="COLOR: #008080; FONT-FAMILY: Courier New">length</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">)</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">{</span><br>
<font face="Courier New"><font color=
"#000000">&nbsp;&nbsp;&nbsp;&nbsp;</font><span style=
"COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style=
"COLOR: #008080; FONT-FAMILY: Courier New">start_position</span>
<span style="COLOR: #0000cc; FONT-FAMILY: Courier New">=</span>
<span style=
"COLOR: #ff0000; FONT-FAMILY: Courier New">strlen</span></font><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">(</span><span style="COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style="COLOR: #008080; FONT-FAMILY: Courier New">str</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">)</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">;</span><br>
<font face="Courier New"><font color=
"#000000">&nbsp;&nbsp;&nbsp;&nbsp;</font><span style=
"COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style=
"COLOR: #008080; FONT-FAMILY: Courier New">start_byte</span>
<span style="COLOR: #0000cc; FONT-FAMILY: Courier New">=</span>
<font color="#000000">0</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">;</span></font><br>
<font face="Courier New"><font color=
"#000000">&nbsp;&nbsp;&nbsp;&nbsp;</font><span style=
"COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style=
"COLOR: #008080; FONT-FAMILY: Courier New">end_position</span>
<span style="COLOR: #0000cc; FONT-FAMILY: Courier New">=</span>
<span style=
"COLOR: #ff0000; FONT-FAMILY: Courier New">strlen</span></font><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">(</span><span style="COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style="COLOR: #008080; FONT-FAMILY: Courier New">str</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">)</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">;</span><br>
<font face="Courier New"><font color=
"#000000">&nbsp;&nbsp;&nbsp;&nbsp;</font><span style=
"COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style=
"COLOR: #008080; FONT-FAMILY: Courier New">count</span>
<span style="COLOR: #0000cc; FONT-FAMILY: Courier New">=</span>
<font color="#000000">0</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">;</span></font><br>
<font face="Courier New"><font color=
"#000000">&nbsp;&nbsp;&nbsp;&nbsp;</font><span style=
"COLOR: #0000ff; FONT-FAMILY: Courier New">for</span><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">(</span><span style=
"COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style=
"COLOR: #008080; FONT-FAMILY: Courier New">i</span> <span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">=</span> <font color=
"#000000">0</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">;</span> <span style=
"COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style=
"COLOR: #008080; FONT-FAMILY: Courier New">i</span> <span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">&lt;</span> <span style=
"COLOR: #ff0000; FONT-FAMILY: Courier New">strlen</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">(</span><span style="COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style="COLOR: #008080; FONT-FAMILY: Courier New">str</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">)</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">;</span>
<span style=
"COLOR: #0000ff; FONT-FAMILY: Courier New">$</span></font><span style="COLOR: #008080; FONT-FAMILY: Courier New">i</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">+</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">+</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">)</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">{</span><br>
<font face="Courier New"><font color=
"#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><span style="COLOR: #0000ff; FONT-FAMILY: Courier New">if</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">(</span><span style="COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style="COLOR: #008080; FONT-FAMILY: Courier New">count</span>
<span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">&gt;</span><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">=</span> <span style=
"COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style=
"COLOR: #008080; FONT-FAMILY: Courier New">position</span>
<span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">&amp;</span><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">&amp;</span>
<span style="COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style="COLOR: #008080; FONT-FAMILY: Courier New">start_position</span>
<span style="COLOR: #0000cc; FONT-FAMILY: Courier New">&gt;</span>
<span style=
"COLOR: #0000ff; FONT-FAMILY: Courier New">$</span></font><span style="COLOR: #008080; FONT-FAMILY: Courier New">i</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">)</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">{</span><br>
<font face="Courier New"><font color=
"#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><span style="COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style="COLOR: #008080; FONT-FAMILY: Courier New">start_position</span>
<span style="COLOR: #0000cc; FONT-FAMILY: Courier New">=</span>
<span style=
"COLOR: #0000ff; FONT-FAMILY: Courier New">$</span></font><span style="COLOR: #008080; FONT-FAMILY: Courier New">i</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">;</span><br>
<font face="Courier New"><font color=
"#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><span style="COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style="COLOR: #008080; FONT-FAMILY: Courier New">start_byte</span>
<span style="COLOR: #0000cc; FONT-FAMILY: Courier New">=</span>
<span style=
"COLOR: #0000ff; FONT-FAMILY: Courier New">$</span></font><span style="COLOR: #008080; FONT-FAMILY: Courier New">count</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">;</span><br>
<font face="Courier New"><font color=
"#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">}</span></font><br>
<font face="Courier New"><font color=
"#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><span style="COLOR: #0000ff; FONT-FAMILY: Courier New">if</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">(</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">(</span><span style="COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style="COLOR: #008080; FONT-FAMILY: Courier New">count</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">-</span><span style="COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style="COLOR: #008080; FONT-FAMILY: Courier New">start_byte</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">)</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">&gt;</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">=</span><span style="COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style="COLOR: #008080; FONT-FAMILY: Courier New">length</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">)</span>
<span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">{</span></font><br>
<font face="Courier New"><font color=
"#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><span style="COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style="COLOR: #008080; FONT-FAMILY: Courier New">end_position</span>
<span style="COLOR: #0000cc; FONT-FAMILY: Courier New">=</span>
<span style=
"COLOR: #0000ff; FONT-FAMILY: Courier New">$</span></font><span style="COLOR: #008080; FONT-FAMILY: Courier New">i</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">;</span><br>
<font face="Courier New"><font color=
"#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><span style="COLOR: #0000ff; FONT-FAMILY: Courier New">break</span></font><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">;</span><br>
<font face="Courier New"><font color=
"#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">}</span></font><font face="Courier New"><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><span style=
"COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style=
"COLOR: #008080; FONT-FAMILY: Courier New">value</span>
<span style="COLOR: #0000cc; FONT-FAMILY: Courier New">=</span>
<span style=
"COLOR: #ff0000; FONT-FAMILY: Courier New">ord</span></font><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">(</span><span style="COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style="COLOR: #008080; FONT-FAMILY: Courier New">str</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">[</span><span style="COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style="COLOR: #008080; FONT-FAMILY: Courier New">i</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">]</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">)</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">;</span><br>
<font face="Courier New"><font color=
"#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><span style="COLOR: #0000ff; FONT-FAMILY: Courier New">if</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">(</span><span style="COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style="COLOR: #008080; FONT-FAMILY: Courier New">value</span>
<span style="COLOR: #0000cc; FONT-FAMILY: Courier New">&gt;</span>
<font color="#000000">127</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">)</span></font><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">{</span><br>
<font face="Courier New"><font color=
"#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><span style="COLOR: #0000ff; FONT-FAMILY: Courier New">$</span></font><span style="COLOR: #008080; FONT-FAMILY: Courier New">count</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">+</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">+</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">;</span><br>
<font face="Courier New"><font color=
"#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><span style="COLOR: #0000ff; FONT-FAMILY: Courier New">if</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">(</span><span style="COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style="COLOR: #008080; FONT-FAMILY: Courier New">value</span>
<span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">&gt;</span><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">=</span> <font color=
"#000000">192</font> <span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">&amp;</span><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">&amp;</span>
<span style="COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style="COLOR: #008080; FONT-FAMILY: Courier New">value</span>
<span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">&lt;</span><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">=</span> <font color=
"#000000">223</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">)</span> <span style=
"COLOR: #0000ff; FONT-FAMILY: Courier New">$</span></font><span style="COLOR: #008080; FONT-FAMILY: Courier New">i</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">+</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">+</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">;</span><br>
<font face="Courier New"><font color=
"#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><span style="COLOR: #0000ff; FONT-FAMILY: Courier New">elseif</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">(</span><span style="COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style="COLOR: #008080; FONT-FAMILY: Courier New">value</span>
<span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">&gt;</span><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">=</span> <font color=
"#000000">224</font> <span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">&amp;</span><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">&amp;</span>
<span style="COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style="COLOR: #008080; FONT-FAMILY: Courier New">value</span>
<span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">&lt;</span><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">=</span> <font color=
"#000000">239</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">)</span> <span style=
"COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style=
"COLOR: #008080; FONT-FAMILY: Courier New">i</span> <span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">=</span> <span style=
"COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style=
"COLOR: #008080; FONT-FAMILY: Courier New">i</span> <span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">+</span> <font color=
"#000000">2</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">;</span></font><br>
<font face="Courier New"><font color=
"#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><span style="COLOR: #0000ff; FONT-FAMILY: Courier New">elseif</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">(</span><span style="COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style="COLOR: #008080; FONT-FAMILY: Courier New">value</span>
<span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">&gt;</span><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">=</span> <font color=
"#000000">240</font> <span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">&amp;</span><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">&amp;</span>
<span style="COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style="COLOR: #008080; FONT-FAMILY: Courier New">value</span>
<span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">&lt;</span><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">=</span> <font color=
"#000000">247</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">)</span> <span style=
"COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style=
"COLOR: #008080; FONT-FAMILY: Courier New">i</span> <span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">=</span> <span style=
"COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style=
"COLOR: #008080; FONT-FAMILY: Courier New">i</span> <span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">+</span> <font color=
"#000000">3</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">;</span></font><br>
<font face="Courier New"><font color=
"#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><span style="COLOR: #0000ff; FONT-FAMILY: Courier New">else</span>
<span style=
"COLOR: #ff0000; FONT-FAMILY: Courier New">die</span></font><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">(</span><span style="COLOR: #ff00ff; FONT-FAMILY: Courier New">'Not
a UTF-8 compatible string'</span><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">)</span><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">;</span><br>
<font face="Courier New"><font color=
"#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">}</span></font><br>
<font face="Courier New"><font color=
"#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><span style="COLOR: #0000ff; FONT-FAMILY: Courier New">$</span></font><span style="COLOR: #008080; FONT-FAMILY: Courier New">count</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">+</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">+</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">;</span><br>
<br>
<font face="Courier New"><font color=
"#000000">&nbsp;&nbsp;&nbsp;&nbsp;</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">}</span></font><br>
<font face="Courier New"><font color=
"#000000">&nbsp;&nbsp;&nbsp;&nbsp;</font><span style=
"COLOR: #0000ff; FONT-FAMILY: Courier New">return</span></font><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">(</span><span style="COLOR: #ff0000; FONT-FAMILY: Courier New">substr</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">(</span><span style="COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style="COLOR: #008080; FONT-FAMILY: Courier New">str</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">,</span><span style="COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style="COLOR: #008080; FONT-FAMILY: Courier New">start_position</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">,</span><span style="COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style="COLOR: #008080; FONT-FAMILY: Courier New">end_position</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">-</span><span style="COLOR: #0000ff; FONT-FAMILY: Courier New">$</span><span style="COLOR: #008080; FONT-FAMILY: Courier New">start_position</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">)</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">)</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">;</span><br>
<span style="COLOR: #0000cc; FONT-FAMILY: Courier New">}</span><br>
<br>
<br>
<span style=
"COLOR: #ff9900; FONT-FAMILY: Courier New">//字符串长度统计-UTF8
[中文3个字节，俄文、韩文占2个字节，字母占1个字节] (Ruby)</span><br>
<font face="Courier New"><font color="#000000">def
utf8_string_length</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">(</span><font color=
"#000000">str</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">)</span></font><br>
<font face="Courier New"><font color=
"#000000">&nbsp;&nbsp;&nbsp;&nbsp;temp</font> <span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">=</span> <font color=
"#000000">CGI</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">:</span><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">:</span><font color=
"#000000">unescape</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">(</span><font color=
"#000000">str</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">)</span></font><br>
<font face="Courier New"><font color=
"#000000">&nbsp;&nbsp;&nbsp;&nbsp;i</font> <span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">=</span> <font color=
"#000000">0</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">;</span></font><br>
<font face="Courier New"><font color=
"#000000">&nbsp;&nbsp;&nbsp;&nbsp;j</font> <span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">=</span> <font color=
"#000000">0</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">;</span></font><br>
<font face="Courier New"><font color=
"#000000">&nbsp;&nbsp;&nbsp;&nbsp;temp</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">.</span><font color=
"#000000">length</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">.</span><font color=
"#000000">times</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">{</span><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">|</span><font color=
"#000000">t</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">|</span></font><br>
<font face="Courier New"><font color=
"#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><span style="COLOR: #0000ff; FONT-FAMILY: Courier New">if</span>
<font color="#000000">temp</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">[</span><font color=
"#000000">t</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">]</span> <span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">&lt;</span></font>
<font face="Courier New"><font color="#000000">127<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i</font>
<span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">+</span><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">=</span></font>
<font face="Courier New"><font color="#000000">1<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><span style=
"COLOR: #0000ff; FONT-FAMILY: Courier New">elseif</span>
<font color="#000000">temp</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">[</span><font color=
"#000000">t</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">]</span> <span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">&gt;</span><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">=</span> <font color=
"#000000">127 and temp</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">[</span><font color=
"#000000">t</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">]</span> <span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">&lt;</span></font>
<font face="Courier New"><font color="#000000">224<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;j</font>
<span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">+</span><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">=</span></font>
<font face="Courier New"><font color="#000000">1<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><span style="COLOR: #0000ff; FONT-FAMILY: Courier New">if</span>
<font color="#000000">0</font> <span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">=</span><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">=</span> <span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">(</span><font color=
"#000000">j</font> <span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">%</span> <font color=
"#000000">2</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">)</span></font><br>
<font face="Courier New"><font color=
"#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i</font>
<span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">+</span><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">=</span></font>
<font face="Courier New"><font color="#000000">2<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;j</font>
<span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">=</span></font>
<font face="Courier New"><font color="#000000">0<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><span style="COLOR: #ff0000; FONT-FAMILY: Courier New">end</span></font><br>
<font face="Courier New"><font color=
"#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><span style="COLOR: #0000ff; FONT-FAMILY: Courier New">else</span></font><br>
<font face="Courier New"><font color=
"#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;j</font>
<span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">+</span><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">=</span></font>
<font face="Courier New"><font color="#000000">1<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><span style="COLOR: #0000ff; FONT-FAMILY: Courier New">if</span>
<font color="#000000">0</font> <span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">=</span><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">=</span> <span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">(</span><font color=
"#000000">j</font> <span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">%</span> <font color=
"#000000">3</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">)</span></font><br>
<font face="Courier New"><font color=
"#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i</font>
<span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">+</span><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">=</span></font><font face="Courier New"><font color="#000000">2<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;j</font>
<span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">=</span></font>
<font face="Courier New"><font color="#000000">0<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><span style="COLOR: #ff0000; FONT-FAMILY: Courier New">end</span></font><br>
<font face="Courier New"><font color=
"#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><span style="COLOR: #ff0000; FONT-FAMILY: Courier New">end</span></font><br>
<font face="Courier New"><font color=
"#000000">&nbsp;&nbsp;&nbsp;&nbsp;</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">}</span></font><br>
<font face="Courier New"><font color=
"#000000">&nbsp;&nbsp;&nbsp;&nbsp;</font><span style=
"COLOR: #0000ff; FONT-FAMILY: Courier New">return</span></font>
<font face="Courier New"><font color=
"#000000">i<br></font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">}</span></font><br>
<br>
<span style=
"COLOR: #ff9900; FONT-FAMILY: Courier New">//判断是否是有韩文-UTF-8
(JavaScript)</span><br>
<span style=
"COLOR: #0000ff; FONT-FAMILY: Courier New">function</span>
<font face="Courier New"><font color=
"#000000">checkKoreaChar</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">(</span><font color=
"#000000">str</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">)</span> <span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">{</span></font><br>
<font face="Courier New"><font color=
"#000000">&nbsp;&nbsp;&nbsp;&nbsp;</font><span style=
"COLOR: #0000ff; FONT-FAMILY: Courier New">for</span><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">(</span><font color=
"#000000">i</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">=</span><font color=
"#000000">0</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">;</span> <font color=
"#000000">i</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">&lt;</span><font color=
"#000000">str</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">.</span><font color=
"#000000">length</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">;</span> <font color=
"#000000">i</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">+</span><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">+</span><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">)</span> <span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">{</span></font><br>
<font face="Courier New"><font color=
"#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><span style="COLOR: #0000ff; FONT-FAMILY: Courier New">if</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">(</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">(</span><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">(</span><font color="#000000">str</font><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">.</span><font color="#000000">charCodeAt</font><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">(</span><font color="#000000">i</font><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">)</span>
<span style="COLOR: #0000cc; FONT-FAMILY: Courier New">&gt;</span>
<font color="#000000">0x3130</font> <span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">&amp;</span><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">&amp;</span>
<font color="#000000">str</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">.</span><font color=
"#000000">charCodeAt</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">(</span><font color=
"#000000">i</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">)</span> <span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">&lt;</span> <font color=
"#000000">0x318F</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">)</span> <span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">|</span><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">|</span> <span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">(</span><font color=
"#000000">str</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">.</span><font color=
"#000000">charCodeAt</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">(</span><font color=
"#000000">i</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">)</span> <span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">&gt;</span><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">=</span> <font color=
"#000000">0xAC00</font> <span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">&amp;</span><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">&amp;</span>
<font color="#000000">str</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">.</span><font color=
"#000000">charCodeAt</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">(</span><font color=
"#000000">i</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">)</span> <span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">&lt;</span><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">=</span> <font color=
"#000000">0xD7A3</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">)</span><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">)</span><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">)</span> <span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">{</span></font><br>
<font face="Courier New"><font color=
"#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><span style="COLOR: #0000ff; FONT-FAMILY: Courier New">return</span>
<span style=
"COLOR: #0000ff; FONT-FAMILY: Courier New">true</span></font><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">;</span><br>
<font face="Courier New"><font color=
"#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">}</span></font><br>
<font face="Courier New"><font color=
"#000000">&nbsp;&nbsp;&nbsp;&nbsp;</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">}</span></font><br>
<font face="Courier New"><font color=
"#000000">&nbsp;&nbsp;&nbsp;&nbsp;</font><span style=
"COLOR: #0000ff; FONT-FAMILY: Courier New">return</span>
<span style=
"COLOR: #0000ff; FONT-FAMILY: Courier New">false</span></font><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">;</span><br>
<span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">}</span></div>
<p><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New"><span style=
"COLOR: #008000"><span style=
"COLOR: #ff9900; FONT-FAMILY: Courier New">//判断是否有中文字符-GBK
(JavaScript)</span><br>
<span style=
"COLOR: #0000ff; FONT-FAMILY: Courier New">function</span>
<font face="Courier New"><font color=
"#000000">check_chinese_char</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">(</span><font color=
"#000000">s</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">)</span></font><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">{</span><br>
<font face="Courier New"><font color=
"#000000">&nbsp;&nbsp;&nbsp;&nbsp;</font><span style=
"COLOR: #0000ff; FONT-FAMILY: Courier New">return</span>
<span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">(</span><font color=
"#000000">s</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">.</span><font color=
"#000000">length</font> <span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">!</span><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">=</span> <font color=
"#000000">s</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">.</span><font color=
"#000000">replace</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">(</span><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">/</span><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">[</span><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">^</span><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">\</span><font color=
"#000000">x00</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">-</span><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">\</span><font color=
"#000000">xff</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">]</span><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">/</span><font color=
"#000000">g</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">,</span><span style=
"COLOR: #ff00ff; FONT-FAMILY: Courier New">"**"</span><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">)</span><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">.</span><font color=
"#000000">length</font><span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">)</span></font><span style="COLOR: #0000cc; FONT-FAMILY: Courier New">;</span><br>
<span style=
"COLOR: #0000cc; FONT-FAMILY: Courier New">}</span></span></span><br></p>

]]></description><guid>http://www.i170.com/Article/62519</guid><trackback:ping>http://www.i170.com/Article/62519/trackback</trackback:ping><comments>http://www.i170.com/Article/62519#comment</comments><wfw:commentRss>http://www.i170.com/Article/62519/commentRss</wfw:commentRss></item> <item><link>http://www.i170.com/Article/62517</link><title><![CDATA[在网上看到使用PHP实现常见的数据结构和算法]]></title><author>Crazy</author><category>技术研究,LAMP</category><pubDate>Mon, 09 Apr 2007 22:39:35  +0800</pubDate><description><![CDATA[<p>
偶然使用google的代码搜索里面发现一个使用php实现的基本的数据结构和算法，什么二叉树、二叉搜索树、AVL树、B树、链表和常见排序、搜索算法等等，而且全部是使用面向对象来实现的，确是是很强。</p>
<p>源码地址：<a href=
"http://www.brpreiss.com/books/opus11/public/Opus11-1.0.tar.gz">http://www.brpreiss.com/books/opus11/public/Opus11-1.0.tar.gz</a></p>
<p>文档地址：<a href=
"http://www.brpreiss.com/books/opus11/">http://www.brpreiss.com/books/opus11/</a></p>

]]></description><guid>http://www.i170.com/Article/62517</guid><trackback:ping>http://www.i170.com/Article/62517/trackback</trackback:ping><comments>http://www.i170.com/Article/62517#comment</comments><wfw:commentRss>http://www.i170.com/Article/62517/commentRss</wfw:commentRss></item> <item><link>http://www.i170.com/Article/55831</link><title><![CDATA[IT人职业规划的思考]]></title><author>Crazy</author><category>IT业界,社会思考</category><pubDate>Wed, 24 Jan 2007 06:36:34  +0800</pubDate><description><![CDATA[<p><font face="Tahoma">　　在网上看了这么一个帖子<a href=
"http://bbs.tech.qq.com/cgi-bin/bbs/show/content?groupid=107:11013&amp;st=&amp;sc=&amp;titlepage=0&amp;messageid=18246&amp;ggpc=0">《IT人若是离开了IT还能干什么？》</a>，其实在网上已经看到过很多这样的讨论了，今天就来说说自己的看法，欢迎大家点评。</font></p>
<p>&nbsp;</p>
<p><font face=
"Tahoma">　　我觉得很多人，甚至是业内人士对IT职业生涯都有错误的认识。很多人认为35岁就该转行了的依据就是，人已经那么大年龄了学不动新知识了，或者是那么大年龄了还要去学习太累。<br>
　　对于前者，我个人认为没有必要那么担心，只要你对技术有激情就一定能学进去，而且IT技术虽然更新很快，但是也是讲究知识沉淀的，也就是说只要理论原理掌握了，学一个更新的技术并不是很难的事情。现在很多大师级的人物都在告诫在校学生，不要痴迷对新技术的追逐，而要苦练基本功，我从业这几年来对此也是深有认同感。</font></p>
<p><font face=
"Tahoma">　　而对于持后一种想法的人，我认为那就是一种懒人想法，是一种对生活不积极，对社会不负责任的想法。既想生活得安逸不要太辛苦，又希望能过上高物质水平的生活，很有好逸恶劳而想不劳而获的嫌疑。这样的人不光IT业不适合他，我想别的行业也不会适合他的，根本就是社会蛀虫。</font></p>
<p>
　　另外一点我想说的是，人到中年不好找工作，这是一个社会层次的问题，不光是IT界，其他行业也是存在着同样的问题。因为现在很大一部分人，主要是我们的父辈，工作还是有国家体制保护的，所以大龄找工作难的社会问题还不是那么突出，只是一少部分人的担忧。当我们这一代人进入中年的时候，这个问题会变成社会的主要矛盾，我相信到时候这个问题会解决的。</p>
<p>
　　最后我想说，真正的IT人应该是对工作、对生活富有激情的，他们喜欢挑战，对学习新技术会产生浓厚的兴趣，希望用技术来改善人们的生活，在他们的努力下生活会变得更美好。</p>

]]></description><guid>http://www.i170.com/Article/55831</guid><trackback:ping>http://www.i170.com/Article/55831/trackback</trackback:ping><comments>http://www.i170.com/Article/55831#comment</comments><wfw:commentRss>http://www.i170.com/Article/55831/commentRss</wfw:commentRss></item> </channel></rss> 
