<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title type="text">博客园_Learning Traces...</title><subtitle type="text">--Great Love involves great effort</subtitle><id>http://feed.cnblogs.com/blog/u/34158/rss</id><updated>2011-03-23T11:22:32Z</updated><author><name>suyang</name><uri>http://www.cnblogs.com/suyang/</uri></author><generator>CNBlogs BlogServer</generator><link rel="alternate" type="text/html" href="http://www.cnblogs.com/suyang/"/><link rel="self" type="application/atom+xml" href="http://feed.cnblogs.com/blog/u/34158/rss"/><entry><id>http://www.cnblogs.com/suyang/archive/2011/03/23/1992997.html</id><title type="text">让 grub 重新引导 fedora 和 win7</title><summary type="text">1：先去grub官方网站下载grub4dos （官方开源项目网站：grub4dos.sourceforge.net）2：解压grldr.mbr、grldr、menu.lst 三个文件到C盘根目录，注意是根目录！3：然后以管理员模式运行cmd，输入bcdedit /create /d &amp;quot;grub&amp;quot; /application bootsector 会有一大串id，要记下，等下要用。4：执行以下命令： bcdedit /set {id} device partition=c: bcdedit /set {id} path \grldr.mbr bcdedit /displayor</summary><published>2011-03-23T11:23:00Z</published><updated>2011-03-23T11:23:00Z</updated><author><name>suyang</name><uri>http://www.cnblogs.com/suyang/</uri></author><link rel="alternate" href="http://www.cnblogs.com/suyang/archive/2011/03/23/1992997.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/suyang/archive/2011/03/23/1992997.html"/><content type="html">&lt;span style="font-size: 14pt;"&gt;&#xD;
 &#xD;
1：先去grub官方网站下载grub4dos （官方开源项目网站：grub4dos.sourceforge.net）&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 14pt;"&gt;2：解压grldr.mbr、grldr、menu.lst 三个文件到C盘根目录，注意是根目录！&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 14pt;"&gt;3：然后以管理员模式运行cmd，输入bcdedit /create /d "grub" /application bootsector 会有一大串id，要记下，等下要用。&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 14pt;"&gt;4：执行以下命令：&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 14pt;"&gt;　　bcdedit /set {id} device partition=c: &lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 14pt;"&gt;　　bcdedit /set {id} path \grldr.mbr &lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 14pt;"&gt;　　bcdedit /displayorder {id} /addlast &lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 14pt;"&gt;5：重启，选择grub&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 14pt;"&gt;6：选择commandline&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 14pt;"&gt;7：输入find，列出硬盘分区&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 14pt;"&gt;8：使用命令root (hdx,y) 以找到Linux分区，这里假设是hd0,2&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 14pt;"&gt;9: setup(hd0,2)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 14pt;"&gt;10: chainloader (hd0,2)+1&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 14pt;"&gt;11: b&lt;/span&gt;oot&lt;img src="http://www.cnblogs.com/suyang/aggbug/1992997.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/suyang/archive/2011/03/23/1992997.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/suyang/archive/2010/11/22/1884049.html</id><title type="text">fedora 11 如何解决root用户的vi无高亮</title><summary type="text">打开/etc/profile.d/vim.sh  CODE: 代码Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/--&amp;gt;if[-n"$BASH_VERSION"-o-n"$KSH_VERSION"-o-n"$ZSH_VERSION"];then[-x/usr...</summary><published>2010-11-22T05:14:00Z</published><updated>2010-11-22T05:14:00Z</updated><author><name>suyang</name><uri>http://www.cnblogs.com/suyang/</uri></author><link rel="alternate" href="http://www.cnblogs.com/suyang/archive/2010/11/22/1884049.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/suyang/archive/2010/11/22/1884049.html"/><content type="html">打开&amp;nbsp;&amp;nbsp;/etc/profile.d/vim.sh&lt;br /&gt; &lt;br /&gt; CODE:&lt;br /&gt; &lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;" onclick="cnblogs_code_show('ab79f0ed-38a4-4c0d-8644-c92904af6698')"&gt;&lt;img src="http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif"  id="code_img_opened_ab79f0ed-38a4-4c0d-8644-c92904af6698" onclick="cnblogs_code_hide('ab79f0ed-38a4-4c0d-8644-c92904af6698',event)" style="display: none;"&gt;&lt;div id="cnblogs_code_open_ab79f0ed-38a4-4c0d-8644-c92904af6698" &gt;&lt;div&gt;&lt;!--&lt;br/ /&gt;&lt;br/ /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br/ /&gt;http://www.CodeHighlighter.com/&lt;br/ /&gt;&lt;br/ /&gt;--&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;[&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt;n&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;$BASH_VERSION&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt;o&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt;n&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;$KSH_VERSION&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt;o&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt;n&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;$ZSH_VERSION&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;];&amp;nbsp;then&lt;br /&gt;&amp;nbsp;&amp;nbsp;[&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt;x&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;/&lt;/span&gt;&lt;span style="color: #000000;"&gt;usr&lt;/span&gt;&lt;span style="color: #000000;"&gt;/&lt;/span&gt;&lt;span style="color: #000000;"&gt;bin&lt;/span&gt;&lt;span style="color: #000000;"&gt;/&lt;/span&gt;&lt;span style="color: #000000;"&gt;id&amp;nbsp;]&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;||&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;[&amp;nbsp;`&lt;/span&gt;&lt;span style="color: #000000;"&gt;/&lt;/span&gt;&lt;span style="color: #000000;"&gt;usr&lt;/span&gt;&lt;span style="color: #000000;"&gt;/&lt;/span&gt;&lt;span style="color: #000000;"&gt;bin&lt;/span&gt;&lt;span style="color: #000000;"&gt;/&lt;/span&gt;&lt;span style="color: #000000;"&gt;id&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt;u`&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt;le&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;100&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;]&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt;&amp;nbsp;for&amp;nbsp;bash&amp;nbsp;and&amp;nbsp;zsh,&amp;nbsp;only&amp;nbsp;if&amp;nbsp;no&amp;nbsp;alias&amp;nbsp;is&amp;nbsp;already&amp;nbsp;set&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;alias&amp;nbsp;vi&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;/&lt;/span&gt;&lt;span style="color: #000000;"&gt;dev&lt;/span&gt;&lt;span style="color: #000000;"&gt;/&lt;/span&gt;&lt;span style="color: #000000;"&gt;null&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;2&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;||&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;alias&amp;nbsp;vi&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;vim&lt;br /&gt;fi&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt; 将 第三行 注释掉，就可以了，因为root 的 id -u 是 0，比 100 小&lt;img src="http://www.cnblogs.com/suyang/aggbug/1884049.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/suyang/archive/2010/11/22/1884049.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/suyang/archive/2010/11/21/1883405.html</id><title type="text">fedora 11 配置 thinkpad trackpoint 中键</title><summary type="text">前言： 周五irc会议上遇到asin问thinkpad的trackpoint与中键的滚动功能，后顺利解决，才有了这篇文章。 关于trackpoint的原文在thinkwiki上，我只是照着做了一遍(:-D)，原文是How to configure the TrackPoint, 具体如下： 默认情况下，中键在linux上是用作粘贴操作的，而不是和win上一样能和小红点一起组合来上下左右滚动功能的，...</summary><published>2010-11-21T11:38:00Z</published><updated>2010-11-21T11:38:00Z</updated><author><name>suyang</name><uri>http://www.cnblogs.com/suyang/</uri></author><link rel="alternate" href="http://www.cnblogs.com/suyang/archive/2010/11/21/1883405.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/suyang/archive/2010/11/21/1883405.html"/><content type="html">&lt;div&gt;                 &lt;p&gt;前言：&lt;br /&gt; 周五irc会议上遇到asin问thinkpad的trackpoint与中键的滚动功能，后顺利解决，才有了这篇文章。&lt;/p&gt;&lt;p&gt;&lt;/p&gt; &lt;p&gt;关于trackpoint的原文在thinkwiki上，我只是照着做了一遍(:-D)，原文是&lt;a href="http://www.thinkwiki.org/wiki/How_to_configure_the_TrackPoint"&gt;&lt;a href="http://www.thinkwiki.org/wiki/How_to_configure_the_TrackPoint" target="_self"&gt;How to configure the TrackPoint,&lt;/a&gt;&lt;/a&gt; 具体如下：&lt;br /&gt; 默认情况下，中键在linux上是用作粘贴操作的，而不是和win上一样能和小红点一起组合来上下左右滚动功能的，因此我们需要配置一下。在Ubuntu 8.10 和Fedora 10 以上(fedora 12当然是)，是使用udev和HAL配置这些输入设备的。&lt;/p&gt;&lt;p&gt;&lt;/p&gt; &lt;p&gt;1.使用lshal|grep input.product查看自己的设备，我的如下：&lt;br /&gt; [liuhongdan@dan ~]$ lshal | grep input.product&lt;br /&gt; input.product = &amp;#8216;ThinkPad Extra Buttons&amp;#8217;&amp;nbsp; (string)&lt;br /&gt; input.product = &amp;#8216;Lid Switch&amp;#8217;&amp;nbsp; (string)&lt;br /&gt; input.product = &amp;#8216;Macintosh mouse button emulation&amp;#8217;&amp;nbsp; (string)&lt;br /&gt; input.product = &amp;#8216;Sleep Button&amp;#8217;&amp;nbsp; (string)&lt;br /&gt; input.product = &amp;#8216;Video Bus&amp;#8217;&amp;nbsp; (string)&lt;br /&gt; input.product = &amp;#8216;Power Button&amp;#8217;&amp;nbsp; (string)&lt;br /&gt; input.product = &amp;#8216;SynPS/2 Synaptics TouchPad&amp;#8217;&amp;nbsp; (string)&lt;br /&gt; input.product = &amp;#8216;TPPS/2 IBM TrackPoint&amp;#8217;&amp;nbsp; (string)&lt;br /&gt; input.product = &amp;#8216;AT Translated Set 2 keyboard&amp;#8217;&amp;nbsp; (string)&lt;br /&gt; input.product = &amp;#8216;HDA Digital PCBeep&amp;#8217;&amp;nbsp; (string)&lt;/p&gt;&lt;p&gt;&lt;/p&gt; &lt;p&gt;2.使用root新建文件/etc/hal/fdi/policy/mouse-wheel.fdi，加入如下内容：&lt;br /&gt;&amp;lt;match key="info.product" string="TPPS/2 IBM TrackPoint"&amp;gt;&lt;br /&gt;&amp;lt;merge key="input.x11_options.EmulateWheel" type="string"&amp;gt;true&amp;lt;/merge&amp;gt;&lt;br /&gt;&amp;lt;merge key="input.x11_options.EmulateWheelButton" type="string"&amp;gt;2&amp;lt;/merge&amp;gt;&lt;br /&gt;&amp;lt;merge key="input.x11_options.YAxisMapping" type="string"&amp;gt;4 5&amp;lt;/merge&amp;gt;&lt;br /&gt;&amp;lt;merge key="input.x11_options.Emulate3Buttons" type="string"&amp;gt;true&amp;lt;/merge&amp;gt;&lt;br /&gt;&amp;lt;merge key="input.x11_options.EmulateWheelTimeout" type="string"&amp;gt;200&amp;lt;/merge&amp;gt;&lt;br /&gt;&amp;lt;/match&amp;gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt; &lt;p&gt;3.如果希望水平滚动则加入：&lt;br /&gt; &amp;lt;merge key="input.x11_options.XAxisMapping" type="string"&amp;gt;6 7&amp;lt;/merge&amp;gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt; &lt;p&gt;4.重启机器，或者重启hal服务与xorg，OK。如果设备是PS/2 Generic Mouse，需要5。&lt;/p&gt;&lt;p&gt;&lt;/p&gt; &lt;p&gt;5.如果你的机器是PS/2 Generic Mouse，则需要使用PS/2 Generic Mouse替换&amp;#8221;TPPS/2 IBM TrackPoint&amp;#8221;即可。&lt;/p&gt;&lt;p&gt;&lt;/p&gt; &lt;p&gt;6.Enjoy!&lt;/p&gt;         &lt;/div&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;转载自 http://liuhongdan.com/?p=806&lt;br /&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/suyang/aggbug/1883405.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/suyang/archive/2010/11/21/1883405.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/suyang/archive/2010/09/20/1831923.html</id><title type="text">[FW]CodeProject：The Complete Guide to C++ Strings, Part I</title><summary type="text">毫无疑问，我们都看到过像TCHAR，std::string，BSTR，等到各种各样的字符串类型，更有那些以 _tcs 开头的奇怪的宏。你也许正在盯着显示器发愁。本指引将总结引进各种字符类型的目的，展示一些简单的用法，并告诉你在必要时，怎么实现各种字符串类型之间的转换。　　在第一部分，我们将介绍3种字符编码类型。了解各种编码模式的工作方式是非常重要的事情。即使你已知道一个字符串是个字符数组，你也应该阅读本部分。一旦你了解了这些，你将对各种字符串类型之间的关系有一个清晰地了解。　　在第二部分，我们将独立讲述string类，怎样使用他及实现他们相互之间的转换。 </summary><published>2010-09-20T10:24:00Z</published><updated>2010-09-20T10:24:00Z</updated><author><name>suyang</name><uri>http://www.cnblogs.com/suyang/</uri></author><link rel="alternate" href="http://www.cnblogs.com/suyang/archive/2010/09/20/1831923.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/suyang/archive/2010/09/20/1831923.html"/><content type="html">&lt;div align="center"&gt;&lt;span style="font-size: 24pt;"&gt;C++字符串完全指引之一&amp;nbsp; Win32 字符编码 &lt;/span&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;原著：Michael Dunn&lt;br /&gt;翻译：Chengjie Sun&lt;/p&gt; &lt;p&gt;原文出处：CodeProject：The Complete Guide to C++ Strings, Part I&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;strong style="font-size: 14pt;"&gt;引言&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;毫无疑问，我们都看到过像TCHAR，std::string，BSTR，等到各种各样的字符串类型，更有那些以 _tcs 开头的奇怪的宏。你也许正在盯着显示器发愁。本指引将总结引进各种字符类型的目的，展示一些简单的用法，并告诉你在必要时，怎么实现各种字符串类型之间的转换。&lt;br /&gt;　　在第一部分，我们将介绍3种字符编码类型。了解各种编码模式的工作方式是非常重要的事情。即使你已知道一个字符串是个字符数组，你也应该阅读本部分。一旦你了解了这些，你将对各种字符串类型之间的关系有一个清晰地了解。&lt;br /&gt;　　在第二部分，我们将独立讲述string类，怎样使用他及实现他们相互之间的转换。 &lt;br /&gt;&lt;/p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;字符基础--ASCII，BDCS，Unicode&lt;/p&gt;&lt;p&gt;所有的string类都是以C-style字符串为基础的。C-style字符串是字符数组，所以我们先介绍字符类型。这里有3种编码模式对应3种字符类型。第一种编码类型是单字节字符集（single-byte charactor set or SBCS）。在这种编码模式下，所有的字符都只用一个字节表示。ASCII是SBCS。一个字节表示的0用来标志SBCS字符串的结束。 &lt;br /&gt;&lt;/p&gt;&lt;p&gt;第二种编码模式是多字节字符集（multi-byte character set or  MBCS）。一个MBCS编码包含一些一个字节长的字符，而另一些字符大于一个字节的长度。用在视窗系统里的MBCS包含两种字符类型，单字节字符 （single-byte characters）和双字节字符（double-byte  characters）。由于windows系统里使用的多字节字符绝大部分是两个字节长，所以MBCS常被用DBCS代替。&lt;/p&gt;&lt;p&gt;在DBCS编码模式中，一些特定的值被保留用来表明他们是双字节字符的一部分。&amp;nbsp;例如，在Shift-JIS编码中（一个常用的日文编码模式），0x81-0x9f之间和  0xe0-0xfc之间的值表示&amp;#8220;这是个双字节字符，下一个字节是这个字符的一部分&amp;#8221;。这样的值被称作&amp;#8220;leading  bytes&amp;#8221;，他们都大于0x7f。跟随在一个leading byte字节后面的字节被称作&amp;#8220;trail byte&amp;#8221;。在DBCS中，trail  byte能是任意非0值。像SBCS相同，DBCS字符串的结束标志也是个单字节表示的0。&lt;/p&gt;&lt;p&gt;第三种编码模式是Unicode。Unicode是一种所有的字符都使用两个字节编码的编码模式。Unicode字符有时也被称作宽字符，因为他比单 子节字符宽（使用了更多的存储空间）。注意，Unicode不能被看作MBCS。MBCS的独特之处在于他的字符使用不同长度的字节编码。Unicode 字符串使用两个字节表示的0作为他的结束标志。&lt;br /&gt;　　单字节字符包含拉丁文字母表，accented characters及ASCII标准和DOS操作系统定义的图像字符。双字节字符被用来表示东亚及中东的语言。Unicode被用在COM及视窗系统 NT操作系统内部。&lt;br /&gt;　 　你一定已非常熟悉单字节字符。当你使用char时，你处理的是单字节字符。双字节字符也用char类型来进行操作（这是我们将会看到的关于双子节字符的 非常多奇怪的地方之一）。Unicode字符用wchar_t来表示。Unicode字符和字符串常量用前缀L来表示。例如：&lt;br /&gt;&lt;/p&gt;&lt;p&gt;wchar_t wch = L"1"; // 2 bytes, 0x0031&lt;/p&gt;&lt;p&gt;wchar_t* wsz = L"Hello"; // 12 bytes, 6 wide characters&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;strong style="font-size: 14pt;"&gt;使用字符串处理函数&lt;/strong&gt;&lt;strong&gt;&lt;br /&gt;&lt;/strong&gt;　　我们都已见过C语言中的字符串函数，strcpy(), sprintf(), atoll()等。这些字符串只应该用来处理单字节字符字符串。标准库也提供了仅适用于Unicode类型字符串的函数，比如wcscpy(), swprintf(), wtol()等。&lt;br /&gt;　　微软还在他的CRT(C runtime library)中增加了操作DBCS字符串的版本。Str***()函数都有对应名字的DBCS版本_mbs***()。如果你料到可能会遇见DBCS字符串（如果你的软件会被安装在使用DBCS编码的国家，如中国，日本等，你就可能会），你应该使用_mbs***()函数，因为他们也能处理SBCS字符串。（一个DBCS字符串也可能含有单字节字符，这就是为什么_mbs***()函数也能处理SBCS字符串的原因）&lt;br /&gt;　　让我们来看一个典型的字符串来阐明为什么需要不同版本的字符串处理函数。我们还是使用前面的Unicode字符串 L"Bob"：&lt;/p&gt;&lt;table id="AutoNumber4" style="border-collapse: collapse;" border="1" cellpadding="0" cellspacing="0" width="42%"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align="center" width="25%"&gt;42 00 &lt;/td&gt;&lt;td align="center" width="25%"&gt;6F 00&lt;/td&gt;&lt;td align="center" width="25%"&gt;62 00&lt;/td&gt;&lt;td align="center" width="25%"&gt;00 00&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="center" width="25%"&gt;B&lt;/td&gt;&lt;td align="center" width="25%"&gt;o&lt;/td&gt;&lt;td align="center" width="25%"&gt;b&lt;/td&gt;&lt;td align="center" width="25%"&gt;BOS&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;因为x86CPU是little-endian，值0x0042在内存中的存储形式是42 00。你能看出如果这个字符串被传给strlen()函数会出现什么问题吗？他将先看到第一个字节42，然后是00，而00是字符串结束的标志，于是strlen()将会返回1。如果把"Bob"传给wcslen()，将会得出更坏的结果。wcslen()将会先看到0x6f42，然后是0x0062，然后一直读到你的缓冲区的末尾，直到发现00 00结束标志或引起了GPF。&lt;br /&gt;　　到目前为止，我们已讨论了str***()和wcs***()的用法及他们之间的差别。Str***()和_mbs**()之间的有差别差别呢？明白他们之间的差别，对于采用正确的方法来遍历DBCS字符串是非常重要的。下面，我们将先介绍字符串的遍历，然后回到str***()和_mbs***()之间的差别这个问题上来。&lt;strong&gt;&lt;br /&gt;&lt;/strong&gt;　　&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong style="font-size: 14pt;"&gt;正确的遍历和索引字符串&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;因为我们中大多数人都是用着SBCS字符串成长的，所以我们在遍历字符串时，常常使用指针的++-和-操作。我们也使用数组下标的表示形式来操作字符串中的字符。这两种方式是用于SBCS和Unicode字符串，因为他们中的字符有着相同的宽度，编译器能正确的返回我们需要的字符。&lt;/p&gt;&lt;p&gt;然而，当碰到DBCS字符串时，我们必须抛弃这些习惯。这里有使用指针遍历DBCS字符串时的两条规则。违背了这两条规则，你的程序就会存在DBCS有关的bugs。&lt;/p&gt;&lt;dir&gt;&lt;li&gt;1．在前向遍历时，不要使用++操作，除非你每次都检查lead byte； &lt;/li&gt;&lt;li&gt;2．永远不要使用--操作进行后向遍历。 &lt;/li&gt;&lt;/dir&gt;&lt;p&gt;我们先来阐述规则2，因为找到一个违背他的真实的实例代码是非常容易的。假设你有一个程式在你自己的目录里保存了一个设置文件，你把安装目录保存在注册表中。在运行时，你从注册表中读取安装目录，然后合成设置文件名，接着读取该文件。假设，你的安装目录是C:＼Program Files＼MyCoolApp，那么你合成的文件名应该是C:＼Program Files＼MyCoolApp＼config.bin。当你进行测试时，你发现程式运行正常。&lt;br /&gt;　　目前，想象你合成文件名的代码可能是这样的：&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&lt;div&gt;&lt;span style="color: #0000ff;"&gt;bool&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;GetConfigFileName&amp;nbsp;(&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;char&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;pszName,&amp;nbsp;size_t&amp;nbsp;nBuffSize&amp;nbsp;)&amp;nbsp;&lt;br /&gt;{&lt;br /&gt;　　&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;char&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;szConfigFilename[MAX_PATH];&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;　　&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;&amp;nbsp;Read&amp;nbsp;install&amp;nbsp;dir&amp;nbsp;from&amp;nbsp;registry...&amp;nbsp;we&amp;#8217;&amp;#8217;ll&amp;nbsp;assume&amp;nbsp;it&amp;nbsp;succeeds.&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;　　&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;&amp;nbsp;Add&amp;nbsp;on&amp;nbsp;a&amp;nbsp;backslash&amp;nbsp;if&amp;nbsp;it&amp;nbsp;wasn&amp;#8217;&amp;#8217;t&amp;nbsp;present&amp;nbsp;in&amp;nbsp;the&amp;nbsp;registry&amp;nbsp;value.&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;　　&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;&amp;nbsp;First,&amp;nbsp;get&amp;nbsp;a&amp;nbsp;pointer&amp;nbsp;to&amp;nbsp;the&amp;nbsp;terminating&amp;nbsp;zero.&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;　　&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;char&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;pLastChar&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;strchr&amp;nbsp;(&amp;nbsp;szConfigFilename,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;＼0&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;);&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;　　&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;&amp;nbsp;Now&amp;nbsp;move&amp;nbsp;it&amp;nbsp;back&amp;nbsp;one&amp;nbsp;character.&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;　　pLastChar&lt;/span&gt;&lt;span style="color: #000000;"&gt;--&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;　　&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;(&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;pLastChar&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;!=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;\\&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;　　　　strcat&amp;nbsp;(&amp;nbsp;szConfigFilename,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;\\&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;);&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;　　&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;&amp;nbsp;Add&amp;nbsp;on&amp;nbsp;the&amp;nbsp;name&amp;nbsp;of&amp;nbsp;the&amp;nbsp;config&amp;nbsp;file.&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;　　strcat&amp;nbsp;(&amp;nbsp;szConfigFilename,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;config.bin&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;);&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;　　&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;&amp;nbsp;If&amp;nbsp;the&amp;nbsp;caller&amp;#8217;&amp;#8217;s&amp;nbsp;buffer&amp;nbsp;is&amp;nbsp;big&amp;nbsp;enough,&amp;nbsp;return&amp;nbsp;the&amp;nbsp;filename.&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;　　&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;(&amp;nbsp;strlen&amp;nbsp;(&amp;nbsp;szConfigFilename&amp;nbsp;)&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;nBuffSize&amp;nbsp;)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;　　　　&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;false&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;　　&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;else&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;　　{&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;　　　　strcpy&amp;nbsp;(&amp;nbsp;pszName,&amp;nbsp;szConfigFilename&amp;nbsp;);&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;　　　　&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;true&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;　　}&amp;nbsp;&lt;br /&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;这是一段非常健壮的代码，然而在遇见 DBCS 字符时他将会出错。让我们来看看为什么。假设一个日本用户使用了你的程式，把他安装在 C:＼。下面是这个名字在内存中的存储形式：&lt;br /&gt; &lt;/p&gt;&lt;table id="AutoNumber5" style="border-collapse: collapse;" border="1" cellpadding="0" cellspacing="0" width="55%"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align="center" width="12%"&gt;43&lt;/td&gt;&lt;td align="center" width="12%"&gt;3A&lt;/td&gt;&lt;td align="center" width="12%"&gt;&lt;span style="color: #0000ff;"&gt;5C&lt;/span&gt;&lt;/td&gt;&lt;td align="center" width="12%"&gt;83 88&lt;/td&gt;&lt;td align="center" width="13%"&gt;83 45&lt;/td&gt;&lt;td align="center" width="13%"&gt;83 52&lt;/td&gt;&lt;td align="center" width="13%"&gt;83 &lt;span style="color: #0000ff;"&gt;5C&lt;/span&gt;&lt;/td&gt;&lt;td align="center" width="13%"&gt;00&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="center" width="12%"&gt;　&lt;/td&gt;&lt;td align="center" width="12%"&gt;　&lt;/td&gt;&lt;td align="center" width="12%"&gt;　&lt;/td&gt;&lt;td align="center" width="12%"&gt;&lt;span style="color: #ff0000;"&gt;LB TB &lt;/span&gt;&lt;/td&gt;&lt;td align="center" width="13%"&gt;&lt;span style="color: #ff0000;"&gt;LB TB &lt;/span&gt;&lt;/td&gt;&lt;td align="center" width="13%"&gt;&lt;span style="color: #ff0000;"&gt;LB TB &lt;/span&gt;&lt;/td&gt;&lt;td align="center" width="13%"&gt;&lt;span style="color: #ff0000;"&gt;LB TB &lt;/span&gt;&lt;/td&gt;&lt;td align="center" width="13%"&gt;　&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="center" width="12%"&gt;C&lt;/td&gt;&lt;td align="center" width="12%"&gt;:&lt;/td&gt;&lt;td align="center" width="12%"&gt;＼&lt;/td&gt;&lt;td align="center" width="12%"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td align="center" width="13%"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td align="center" width="13%"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td align="center" width="13%"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td align="center" width="13%"&gt;&lt;span style="font-size: 12pt; color: #ff0000; font-family: Courier New;"&gt;EOS&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;当使用 GetConfigFileName() 检查尾部的&amp;#8217;&amp;#8217;＼＼&amp;#8217;&amp;#8217;时，他寻找安装目录名中最后的非0字节，看他是等于"\\"的，所以没有重新增加一个"\\"。结果是代码返回了错误的文件名。&lt;br /&gt;　　哪里出错了呢？看看上面两个被用蓝色高量显示的字节。斜杠"\\"的值是0x5c。&amp;#8217;&amp;#8217; &amp;#8217;&amp;#8217;的值是83 5c。上面的代码错误的读取了一个 trail byte，把他当作了一个字符。&lt;br /&gt;　　正确的后向遍历方法是使用能够识别DBCS字符的函数，使指针移动正确的字节数。下面是正确的代码。（指针移动的地方用红色标明） &lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&lt;div&gt;&lt;span style="color: #0000ff;"&gt;bool&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;FixedGetConfigFileName&amp;nbsp;(&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;char&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;pszName,&amp;nbsp;size_t&amp;nbsp;nBuffSize&amp;nbsp;)&amp;nbsp;&lt;br /&gt;{&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;　　&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;char&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;szConfigFilename[MAX_PATH];&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;　　&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;&amp;nbsp;Read&amp;nbsp;install&amp;nbsp;dir&amp;nbsp;from&amp;nbsp;registry...&amp;nbsp;we&amp;#8217;ll&amp;nbsp;assume&amp;nbsp;it&amp;nbsp;succeeds.&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;　　&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;&amp;nbsp;Add&amp;nbsp;on&amp;nbsp;a&amp;nbsp;backslash&amp;nbsp;if&amp;nbsp;it&amp;nbsp;wasn&amp;#8217;&amp;#8217;t&amp;nbsp;present&amp;nbsp;in&amp;nbsp;the&amp;nbsp;registry&amp;nbsp;value.&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;　　&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;&amp;nbsp;First,&amp;nbsp;get&amp;nbsp;a&amp;nbsp;pointer&amp;nbsp;to&amp;nbsp;the&amp;nbsp;terminating&amp;nbsp;zero.&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;　　&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;char&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;pLastChar&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;_mbschr&amp;nbsp;(&amp;nbsp;szConfigFilename,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;\0&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;);&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;　　&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;&amp;nbsp;Now&amp;nbsp;move&amp;nbsp;it&amp;nbsp;back&amp;nbsp;one&amp;nbsp;double-byte&amp;nbsp;character.&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;　　pLastChar&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;CharPrev&amp;nbsp;(&amp;nbsp;szConfigFilename,&amp;nbsp;pLastChar&amp;nbsp;);&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;　　&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;(&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;pLastChar&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;!=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;\\&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;　　　　_mbscat&amp;nbsp;(&amp;nbsp;szConfigFilename,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;\\&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;);&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;　　&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;&amp;nbsp;Add&amp;nbsp;on&amp;nbsp;the&amp;nbsp;name&amp;nbsp;of&amp;nbsp;the&amp;nbsp;config&amp;nbsp;file.&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;　　_mbscat&amp;nbsp;(&amp;nbsp;szConfigFilename,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;config.bin&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;);&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;　　&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;&amp;nbsp;If&amp;nbsp;the&amp;nbsp;caller&amp;#8217;s&amp;nbsp;buffer&amp;nbsp;is&amp;nbsp;big&amp;nbsp;enough,&amp;nbsp;return&amp;nbsp;the&amp;nbsp;filename.&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;　　&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;(&amp;nbsp;_mbslen&amp;nbsp;(&amp;nbsp;szInstallDir&amp;nbsp;)&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;nBuffSize&amp;nbsp;)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;　　　　&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;false&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;　　&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;else&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;　　{&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;　　　　_mbscpy&amp;nbsp;(&amp;nbsp;pszName,&amp;nbsp;szConfigFilename&amp;nbsp;);&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;　　　　&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;true&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;　　}&amp;nbsp;&lt;br /&gt;}&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;上面的函数使用CharPrev() API使pLastChar向后移动一个字符，这个字符可能是两个字节长。在这个版本里，if条件正常工作，因为lead byte永远不会等于0x5c。&lt;br /&gt;　　让我们来想象一个违背规则1的场合。例如，你可能要检测一个用户输入的文件名是否多次出现了&amp;#8217;&amp;#8217;:&amp;#8217;&amp;#8217;。如果，你使用++操作来遍历字符串，而不是使用CharNext()，你可能会发出不正确的错误警告如果恰巧有一个trail byte他的值的等于&amp;#8217;&amp;#8217;:&amp;#8217;&amp;#8217;的值。&lt;br /&gt;和规则2相关的关于字符串索引的规则：&lt;/p&gt;&lt;pre&gt;2a. 永远不要使用减法去得到一个字符串的索引。&lt;/pre&gt;&lt;p&gt;违背这条规则的代码和违背规则2的代码非常相似。例如，&lt;/p&gt;&lt;pre&gt;char* pLastChar = &amp;amp;szConfigFilename [strlen(szConfigFilename) - 1];&lt;/pre&gt;&lt;p&gt;这和向后移动一个指针是同样的效果。&lt;br /&gt;&lt;strong&gt;回到关于str***()和_mbs***()的差别&lt;br /&gt;&lt;br /&gt;&lt;/strong&gt;　　目前，我们应该非常清晰为什么_mbs***()函数是必需的。Str***()函数根本不考虑DBCS字符，而_mbs***()考虑。如果，你调用strrchr("C:＼＼ ", &amp;#8217;&amp;#8217;＼＼&amp;#8217;&amp;#8217;)，返回结果可能是错误的，然而_mbsrchr()将会认出最后的双字节字符，返回一个指向真的&amp;#8217;&amp;#8217;＼＼&amp;#8217;&amp;#8217;的指针。&lt;br /&gt;　　关于字符串函数的最后一点：str***()和_mbs***()函数认为字符串的长度都是以char来计算的。所以，如果一个字符串包含3个双字节字符，_mbslen()将会返回6。Unicode函数返回的长度是按wchar_t来计算的。例如，wcslen(L"Bob")返回3。&lt;br /&gt;&lt;strong&gt;Win32 API中的MBCS和Unicode&lt;br /&gt;&lt;br /&gt;&lt;/strong&gt;两组 APIs： &lt;br /&gt;　　尽管你也许从来没有注意过，Win32中的每个和字符串相关的API和message都有两个版本。一个版本接受MBCS字符串，另一个接受Unicode字符串。例如，根本没有SetWindowText()这个API，相反，有SetWindowTextA()和SetWindowTextW()。后缀A表明这是MBCS函数，后缀W表示这是Unicode版本的函数。&lt;br /&gt;　　当你 build 一个 视窗系统 程式，你能选择是用 MBCS 或 Unicode APIs。如果，你原来用过VC向导并且没有改过预处理的设置，那表明你用的是MBCS版本。那么，既然没有 SetWindowText() API，我们为什么能使用他呢？winuser.h头文件包含了一些宏，例如： &lt;/p&gt;&lt;pre&gt;BOOL WINAPI SetWindowTextA ( HWND hWnd, LPCSTR lpString ); &lt;br /&gt;BOOL WINAPI SetWindowTextW ( HWND hWnd, LPCWSTR lpString );   &lt;br /&gt;#ifdef UNICODE &lt;br /&gt;　　#define SetWindowText  SetWindowTextW &lt;br /&gt;#else &lt;br /&gt;　　#define SetWindowText  SetWindowTextA &lt;br /&gt;#endif      &lt;/pre&gt;&lt;p&gt;当使用MBCS APIs来build程式时，UNICODE没有被定义，所以预处理器看到：&lt;/p&gt;&lt;pre&gt;#define SetWindowText SetWindowTextA&lt;/pre&gt;&lt;p&gt;这个宏定义把所有对SetWindowText的调用都转换成真正的API函数SetWindowTextA。（当然，你能直接调用SetWindowTextA() 或 SetWindowTextW()，虽然你不必那么做。）&lt;br /&gt;　　所以，如果你想把默认使用的API函数变成Unicode版的，你能在预处理器设置中，把_MBCS从预定义的宏列表中删除，然后添加UNICODE和_UNICODE。(你需要两个都定义，因为不同的头文件可能使用不同的宏。) 然而，如果你用char来定义你的字符串，你将会陷入一个尴尬的境地。考虑下面的代码：&lt;/p&gt;&lt;pre&gt;HWND hwnd = GetSomeWindowHandle(); char szNewText[] = "we love Bob!"; SetWindowText ( hwnd, szNewText );&lt;/pre&gt;&lt;p&gt;在预处理器把SetWindowText用SetWindowTextW来替换后，代码变成：&lt;/p&gt;&lt;pre&gt;HWND hwnd = GetSomeWindowHandle(); char szNewText[] = "we love Bob!"; SetWindowTextW ( hwnd, szNewText );&lt;/pre&gt;&lt;p&gt;看到问题了吗？我们把单字节字符串传给了一个以Unicode字符串做参数的函数。解决这个问题的第一个方案是使用 #ifdef 来包含字符串变量的定义：&lt;/p&gt;&lt;pre&gt;HWND hwnd = GetSomeWindowHandle(); #ifdef UNICODE wchar_t szNewText[] = L"we love Bob!"; #else char szNewText[] = "we love Bob!"; #endif SetWindowText ( hwnd, szNewText );&lt;/pre&gt;&lt;p&gt;你可能已感受到了这样做将会使你多么的头疼。完美的解决方案是使用TCHAR.&lt;br /&gt;&lt;strong&gt;使用TCHAR&lt;br /&gt;&lt;br /&gt;&lt;/strong&gt;　　TCHAR是一种字符串类型，他让你在以MBCS和UNNICODE来build程式时能使用同样的代码，不必使用繁琐的宏定义来包含你的代码。TCHAR的定义如下：&lt;/p&gt;&lt;pre&gt;#ifdef UNICODE typedef wchar_t TCHAR; #else typedef char TCHAR; #endif&lt;/pre&gt;&lt;p&gt;所以用MBCS来build时，TCHAR是char，使用UNICODE时，TCHAR是wchar_t。更有一个宏来处理定义Unicode字符串常量时所需的L前缀。&lt;/p&gt;&lt;pre&gt;#ifdef UNICODE #define _T(x) L##x #else #define _T(x) x #endif&lt;/pre&gt;&lt;p&gt;##是个预处理操作符，他能把两个参数连在一起。如果你的代码中需要字符串常量，在他前面加上_T宏。如果你使用Unicode来build，他会在字符串常量前加上L前缀。&lt;/p&gt;&lt;pre&gt;TCHAR szNewText[] = _T("we love Bob!");&lt;/pre&gt;&lt;p&gt;像是用宏来隐藏SetWindowTextA/W的细节相同，更有非常多能供你使用的宏来实现str***()和_mbs***()等字符串函数。例如，你能使用_tcsrchr宏来替换strrchr()、_mbsrchr()和wcsrchr()。_tcsrchr根据你预定义的宏是_MBCS还是UNICODE来扩展成正确的函数，就像SetWindowText所作的相同。&lt;br /&gt;　　不仅str***()函数有TCHAR宏。其他的函数如， _stprintf（代替sprinft()和swprintf()）,_tfopen（代替fopen()和_wfopen()）。 MSDN中"Generic-Text Routine Mappings."标题下有完整的宏列表。&lt;br /&gt;&lt;strong&gt;字符串和TCHAR typedefs&lt;br /&gt;&lt;br /&gt;&lt;/strong&gt;　　由于Win32 API文件的函数列表使用函数的常用名字（例如，"SetWindowText"），所有的字符串都是用TCHAR来定义的。（除了XP中引入的只适用于Unicode的API）。下面列出一些常用的typedefs，你能在msdn中看到他们。&lt;/p&gt;&lt;table id="AutoNumber6" style="border-collapse: collapse;" border="1" cellpadding="4" cellspacing="4" width="98%"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align="center" width="16%"&gt;&lt;strong&gt;type &lt;/strong&gt;&lt;/td&gt;&lt;td align="center" width="42%"&gt;&lt;strong&gt;Meaning in MBCS builds &lt;/strong&gt;&lt;/td&gt;&lt;td align="center" width="42%"&gt;&lt;strong&gt;Meaning in Unicode builds&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width="16%"&gt;WCHAR&lt;/td&gt;&lt;td width="42%"&gt;wchar_t&lt;/td&gt;&lt;td width="42%"&gt;wchar_t&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width="16%"&gt;LPSTR &lt;/td&gt;&lt;td width="42%"&gt;zero-terminated string of char (char*)&lt;/td&gt;&lt;td width="42%"&gt;zero-terminated string of char (char*)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width="16%"&gt;LPCSTR &lt;/td&gt;&lt;td width="42%"&gt;constant zero-terminated string of char (const char*)&lt;/td&gt;&lt;td width="42%"&gt;constant zero-terminated string of char (const char*)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width="16%"&gt;LPWSTR&lt;/td&gt;&lt;td width="42%"&gt;zero-terminated Unicode string (wchar_t*) &lt;/td&gt;&lt;td width="42%"&gt;zero-terminated Unicode string (wchar_t*)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width="16%"&gt;LPCWSTR&lt;/td&gt;&lt;td width="42%"&gt;constant zero-terminated Unicode string (const wchar_t*)&lt;/td&gt;&lt;td width="42%"&gt;constant zero-terminated Unicode string (const wchar_t*) &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width="16%"&gt;TCHAR&lt;/td&gt;&lt;td width="42%"&gt;char&lt;/td&gt;&lt;td width="42%"&gt;wchar_t&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width="16%"&gt;LPTSTR&lt;/td&gt;&lt;td width="42%"&gt;zero-terminated string of TCHAR (TCHAR*) &lt;/td&gt;&lt;td width="42%"&gt;zero-terminated string of TCHAR (TCHAR*)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width="16%"&gt;LPCTSTR &lt;/td&gt;&lt;td width="42%"&gt;constant zero-terminated string of TCHAR (const TCHAR*)&lt;/td&gt;&lt;td width="42%"&gt;constant zero-terminated string of TCHAR (const TCHAR*)&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;strong&gt;何时使用 TCHAR 和 Unicode&lt;br /&gt;&lt;br /&gt;&lt;/strong&gt;　　到目前，你可能会问，我们为什么要使用Unicode。我已用了非常多年的char。下列3种情况下，使用Unicode将会使你受益：&lt;dir&gt;&lt;li&gt;1．你的程式只运行在视窗系统 NT系统中。 &lt;/li&gt;&lt;li&gt;2． 你的程式需要处理超过MAX_PATH个字符长的文件名。 &lt;/li&gt;&lt;li&gt;3． 你的程式需要使用XP中引入的只有Unicode版本的API. &lt;/li&gt;&lt;/dir&gt;&lt;p&gt;视窗系统 9x 中大多数的 API 没有实现 Unicode 版本。所以，如果你的程式要在windows 9x中运行，你必须使用MBCS APIs。然而，由于NT系统内部都使用Unicode，所以使用Unicode APIs将会加快你的程式的运行速度。每次，你传递一个字符串调用MBCS API，操作系统会把这个字符串转换成Unicode字符串，然后调用对应的Unicode API。如果一个字符串被返回，操作系统还要把他转变回去。尽管这个转换过程被高度优化了，但他对速度造成的损失是无法避免的。&lt;br /&gt;　　只要你使用Unicode API，NT系统允许使用非常长的文件名（突破了MAX_PATH的限制，MAX_PATH=260）。使用Unicode API的另一个好处是你的程式会自动处理用户输入的各种语言。所以一个用户能输入英文，中文或日文，而你不必额外编写代码去处理他们。&lt;br /&gt;　　最后，随着windows 9x产品的淡出，微软似乎正在抛弃MBCS APIs。例如，包含两个字符串参数的SetWindowTheme() API只有Unicode版本的。使用Unicode来build你的程式将会简化字符串的处理，你不必在MBCS和Unicdoe之间相互转换。&lt;br /&gt;　　即使你目前不使用Unicode来build你的程式，你也应该使用TCHAR及其相关的宏。这样做不仅能的代码能非常好地处理DBCS，而且如果将来你想用Unicode来build你的程式，你只需要改动一下预处理器中的设置就能实现&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/suyang/aggbug/1831923.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/suyang/archive/2010/09/20/1831923.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/suyang/archive/2010/05/14/1735582.html</id><title type="text">[广告] LS 情侣 淘宝 店, 有事没事就去逛逛哦</title><summary type="text">http://lizishan.taobao.com/</summary><published>2010-05-14T08:21:00Z</published><updated>2010-05-14T08:21:00Z</updated><author><name>suyang</name><uri>http://www.cnblogs.com/suyang/</uri></author><link rel="alternate" href="http://www.cnblogs.com/suyang/archive/2010/05/14/1735582.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/suyang/archive/2010/05/14/1735582.html"/><content type="html">&lt;p&gt;&lt;a target="_blank" href="http://www.cnblogs.com/suyang/admin/lizishan.taobao.com"&gt;http://lizishan.taobao.com/&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;img alt="" src="http://images.cnblogs.com/cnblogs_com/suyang/QQ%E6%88%AA%E5%9B%BE%E6%9C%AA%E5%91%BD%E5%90%8D.jpg" border="0" /&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/suyang/aggbug/1735582.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/suyang/archive/2010/05/14/1735582.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/suyang/archive/2010/04/27/1721809.html</id><title type="text">[转]UML(Unified Modeling Language)统一建模语言--类图详解</title><summary type="text">类图是面向对象系统建模中最常见的图，类图显示了一组类、接口、协作以及它们之间的关系。类图用于对系统的静态设计视图建模。 在UML中类以矩形表示，具有名称、属性、操作、和关系等描述。接下来我们将全面的对类里面的每个元素的表现作出详细的介绍。 </summary><published>2010-04-27T02:33:00Z</published><updated>2010-04-27T02:33:00Z</updated><author><name>suyang</name><uri>http://www.cnblogs.com/suyang/</uri></author><link rel="alternate" href="http://www.cnblogs.com/suyang/archive/2010/04/27/1721809.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/suyang/archive/2010/04/27/1721809.html"/><content type="html">&lt;div&gt; 		&lt;p&gt;&lt;strong&gt;&lt;a target="_blank" id="ctl04_TitleUrl" href="http://www.cnblogs.com/fenglin1985/archive/2010/04/10/1709209.html"&gt;[转]UML(Unified  Modeling Language)统一建模语言--类图详解&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; 	&lt;/div&gt; 	&lt;div&gt;类图是面向对象系统建模中最常见的图，类图显示了一组类、接口、协作以及它们之间的关系。类图用于对系统的静态设计视图建模。  在UML中类以矩形表示，具有名称、属性、操作、和关系等描述。接下来我们将全面的对类里面的每个元素的表现作出详细的介绍。 &lt;ul&gt;&lt;li&gt;类:     &lt;ul&gt;&lt;li&gt;在UML中类以一个矩形表示，类的名称用一个字符串表示。 &lt;br /&gt;         &lt;img alt="" src="http://images.cnblogs.com/cnblogs_com/fenglin1985/simpleclass.jpg" /&gt;&lt;/li&gt;&lt;li&gt;抽象类通过将类名改为斜体字表示。 &lt;br /&gt;         &lt;img alt="" src="http://images.cnblogs.com/cnblogs_com/fenglin1985/abstract-class.jpg" /&gt;&lt;/li&gt;&lt;li&gt;不能继承的类（叶子类，封闭类）通过在类名下面增加 leaf 特性说明。 &lt;br /&gt;         &lt;img alt="" src="http://images.cnblogs.com/cnblogs_com/fenglin1985/simpleclass.jpg" /&gt;  &lt;/li&gt;&lt;/ul&gt;     &lt;/li&gt;&lt;li&gt;属性:     &lt;ul&gt;&lt;li&gt;属性在类下面的栏中列出，可以仅显示属性名。 &lt;br /&gt;         &lt;img alt="" src="http://images.cnblogs.com/cnblogs_com/fenglin1985/attribute.jpg" /&gt;&lt;/li&gt;&lt;li&gt;静态属性通过在属性名下加下划线表示。 &lt;br /&gt;         &lt;img alt="" src="http://images.cnblogs.com/cnblogs_com/fenglin1985/static-attribute.jpg" /&gt;&lt;/li&gt;&lt;li&gt;属性其他特征完整语法: [可见性] 属性名 [':'类型] [多重性] ['='初始值] [{特性串]}] &lt;br /&gt;         &lt;img alt="" src="http://images.cnblogs.com/cnblogs_com/fenglin1985/attribute-description.jpg" /&gt;&lt;/li&gt;&lt;li&gt;不能重写属性通过在特性串中增加 leaf 特性说明。 &lt;br /&gt;         &lt;img alt="" src="http://images.cnblogs.com/cnblogs_com/fenglin1985/sealed-attribute.jpg" /&gt;  &lt;/li&gt;&lt;/ul&gt;     &lt;/li&gt;&lt;li&gt;操作:     &lt;ul&gt;&lt;li&gt;属性在类下面的第二栏中列出，可以仅显示操作名。 &lt;br /&gt;         &lt;img alt="" src="http://images.cnblogs.com/cnblogs_com/fenglin1985/operation.jpg" /&gt;&lt;/li&gt;&lt;li&gt;静态操作与静态属性同样通过在名称下加下划线表示。 &lt;br /&gt;         &lt;img alt="" src="http://images.cnblogs.com/cnblogs_com/fenglin1985/static-operation.jpg" /&gt;&lt;/li&gt;&lt;li&gt;抽象操作与抽象类同样通过斜体字表示。 &lt;br /&gt;         &lt;img alt="" src="http://images.cnblogs.com/cnblogs_com/fenglin1985/abstract-operation.jpg" /&gt;&lt;/li&gt;&lt;li&gt;操作特征完整语法: [可见性] 操作名 [([方向] 参数名 ':' 参数类型 ['=' 默认值])] [':'  返回类型] [{特征串}] &lt;br /&gt;         &lt;img alt="" src="http://images.cnblogs.com/cnblogs_com/fenglin1985/operation-description.jpg" /&gt;&lt;/li&gt;&lt;li&gt;不能重写的操作与属性一样使用特征串中增加 leaf 表示。 &lt;br /&gt;         &lt;img alt="" src="http://images.cnblogs.com/cnblogs_com/fenglin1985/sealed-operation.jpg" /&gt;  &lt;/li&gt;&lt;/ul&gt;     &lt;/li&gt;&lt;li&gt;可见性:     &lt;ul&gt;&lt;li&gt;可见性通过在属性或方法名称前增加特定的符号表示。公共的（+）私有的的（-）受保护的（#）包内的（~） &lt;br /&gt;         &lt;img alt="" src="http://images.cnblogs.com/cnblogs_com/fenglin1985/visibility.jpg" /&gt; &lt;/li&gt;&lt;/ul&gt;     &lt;/li&gt;&lt;/ul&gt; 接下来我们一起来研究一下类之间的关系。 &lt;ul&gt;&lt;li&gt;依赖(dependency)是一种使用关系，他描述一个事物的规约变化可能影响到使用它的另一个事物。个人认为在参数或者方法体中使用 到另外的类就是对该类有依赖的关系。use a &lt;br /&gt;     &lt;img alt="" src="http://images.cnblogs.com/cnblogs_com/fenglin1985/dependency.jpg" /&gt;&lt;/li&gt;&lt;li&gt;泛化(dependency)用于描述子类到父类之间的关系。 Is a kind of &lt;br /&gt;     &lt;img alt="" src="http://images.cnblogs.com/cnblogs_com/fenglin1985/generalization.jpg" /&gt;&lt;/li&gt;&lt;li&gt;关联(association)是一种结构关系，他描述一个对象与另一个对象相联系。 Has a     &lt;ul&gt;&lt;li&gt;双向关联(association)通过A对象可以找到B对象，B对象同样可以找到A对象的关联为双向关联。 &lt;br /&gt;         &lt;img alt="" src="http://images.cnblogs.com/cnblogs_com/fenglin1985/association.jpg" /&gt;&lt;/li&gt;&lt;li&gt;单向关联(direction-association)通过A对象可以找到B对象，但通过B对象不能找到A对象的关联为单向关 联。 &lt;br /&gt;         &lt;img alt="" src="http://images.cnblogs.com/cnblogs_com/fenglin1985/directed-association.jpg" /&gt;&lt;/li&gt;&lt;li&gt;聚合(aggreation)A对象是B对象的一个组成部份，但A对象同时可能是C对象的组成部分这种关联为聚合。 &lt;br /&gt;         &lt;img alt="" src="http://images.cnblogs.com/cnblogs_com/fenglin1985/aggregation.jpg" /&gt;&lt;/li&gt;&lt;li&gt;组合(composition)A对象是B对象的一个组成部份，除非B对象将A对象转交给其他对象，否则A对象只能是B对象的组 成部分，这种关联为组合。 &lt;br /&gt;         &lt;img alt="" src="http://images.cnblogs.com/cnblogs_com/fenglin1985/composition.jpg" /&gt;  &lt;/li&gt;&lt;/ul&gt;     &lt;/li&gt;&lt;/ul&gt; &lt;/div&gt;[转自：http://www.cnblogs.com/fenglin1985/archive/2010/04/10/1709209.html]&lt;img src="http://www.cnblogs.com/suyang/aggbug/1721809.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/suyang/archive/2010/04/27/1721809.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/suyang/archive/2010/03/30/1700523.html</id><title type="text">[转]memcachedb 压力测试及调优</title><summary type="text">一.需求：我们希望找到一个key-value型数据库，具有以下特点1.稳定高效2.基于memcache或其它方便调用的包,以便在PHP中分布调用3.如果有热备能力更佳，但至少有主从结构。可选择的有：memcachedb和Tokyo Tyrant。它们的官方报告数据都不错。我们曾经对Tokyo Tyrant-Tokyo Cabinet寄予厚望，因为它可以做双主。但结果是，在插入200万100字节的数据之后，Tokyo Tyrant就像蜗牛一样，而且不断报错。 二.测试数据：软硬件环境：CPU: 64位4核Intel(R) Xeon(R) CPU E5310 @ 1.60GHz内存：8G操作系统：centos硬盘：120G客户端：PHP PECL扩展启动方式：memcachedb -p11211 -d -r -u root -H /opt/mdb/ -m 6144 -N -t 4或memcachedb -p11222 -d -r -u root -H /opt/mdb/ -m 7000 -N -t 8 </summary><published>2010-03-30T04:47:00Z</published><updated>2010-03-30T04:47:00Z</updated><author><name>suyang</name><uri>http://www.cnblogs.com/suyang/</uri></author><link rel="alternate" href="http://www.cnblogs.com/suyang/archive/2010/03/30/1700523.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/suyang/archive/2010/03/30/1700523.html"/><content type="html">&lt;p&gt;一.需求：&lt;/p&gt; &lt;p&gt;我们希望找到一个key-value型数据库，具有以下特点&lt;br /&gt; 1.稳定高效&lt;br /&gt; 2.基于memcache或其它方便调用的包,以便在PHP中分布调用&lt;br /&gt; 3.如果有热备能力更佳，但至少有主从结构。&lt;/p&gt; &lt;p&gt;可选择的有：memcachedb和Tokyo Tyrant。它们的官方报告数据都不错。&lt;br /&gt; 我们曾经对Tokyo Tyrant-Tokyo Cabinet寄予厚望，因为它可以做双主。但结果是，在插入200万100字节的数据之后，Tokyo Tyrant就像蜗牛一样，而且不断报错。&lt;/p&gt; &lt;p&gt;&lt;wbr&gt;&lt;/p&gt; &lt;p&gt;二.测试数据：&lt;/p&gt; &lt;p&gt;软硬件环境：&lt;br /&gt; CPU: 64位4核Intel(R) Xeon(R) CPU E5310 @ 1.60GHz&lt;br /&gt; 内存：8G&lt;br /&gt; 操作系统：centos&lt;br /&gt; 硬盘：120G&lt;br /&gt; 客户端：PHP PECL扩展&lt;br /&gt; 启动方式：memcachedb -p11211 -d -r -u root -H /opt/mdb/ -m 6144 -N -t 4&lt;/p&gt; &lt;p&gt;或memcachedb -p11222 -d -r -u root -H /opt/mdb/ -m 7000 -N -t 8 -E -X -v&lt;br /&gt; 网络环境：未明确标注的均为localhost&lt;/p&gt; &lt;p&gt;&lt;br /&gt; (1)400字节数据单主机新增数据测试（10万数据）&lt;br /&gt; 内网：ping值：time=0.151 ms 千兆带宽&lt;br /&gt; 400字节：2.8秒/万&lt;br /&gt; 100字节：2.0秒/万&lt;/p&gt; &lt;p&gt;本机:&amp;nbsp;&lt;wbr&gt; ping值：time=0.010 ms&lt;br /&gt; 400字节：0.7秒/万&lt;/p&gt; &lt;p&gt;结论：&lt;br /&gt; 在小数据量的情况下，localhost和内网差别为4:1左右。&lt;br /&gt; 数据的大小对写效率有一定的影响，400字节和100字节的数据在写入数据时，速度差别为3：2左右，读数据效率差别较小。&lt;/p&gt; &lt;p&gt;(2)100字节数据单主机测试结果：（2千万数据）&lt;br /&gt; 新增：7280条/秒 （客户端8进程，其余未标明的测试均为单进程）&lt;br /&gt; 更改：200万以前1860条/s，200万稳定在以后&amp;gt;10000条/秒（这个现象原因还未找到，更改数据测试有待重测）&lt;br /&gt;  读取：&amp;gt;10000万条/秒&lt;/p&gt; &lt;p&gt;结论：&lt;br /&gt; 客户端程序多进程与单进程对效率影响差别很小。甚至过多客户端进程写入时，反而影响效率。&lt;/p&gt; &lt;p&gt;&lt;br /&gt; (2)将数组转成字符串存取能提高效率么？压缩选项是否能较大地提高效率？&lt;br /&gt; 某数组（如下），序列化后长度为700字节，用分隔符将数组的值转成字符串为350字节左右。下面测试中，已经包含把数组序列化和转字符串的时间。&lt;br /&gt;  array ( 0 =&amp;gt; 10735, 1 =&amp;gt; 10720, 2 =&amp;gt; 10705, 3 =&amp;gt; 10690, 4 =&amp;gt; 10675, 5 =&amp;gt; 10660, 6 =&amp;gt; 10645, 7 =&amp;gt; 10630, 8 =&amp;gt; 10615, 9 =&amp;gt; 10600, 10 =&amp;gt; 10585, 11 =&amp;gt; 10570, 12 =&amp;gt; 10555, 13 =&amp;gt; 10540, 14 =&amp;gt; 10525, 15 =&amp;gt; 10510, 16 =&amp;gt; 10495, 17 =&amp;gt; 10480, 18 =&amp;gt; 10465, 19 =&amp;gt; 10450, 20 =&amp;gt; 10435, 21 =&amp;gt; 10420, 22 =&amp;gt; 10405, 23 =&amp;gt; 10390, 24 =&amp;gt; 10375, 25 =&amp;gt; 10360, 26 =&amp;gt; 10345, 27 =&amp;gt; 10330, 28 =&amp;gt; 10315, 29 =&amp;gt; 10300, 30 =&amp;gt; 10285, 31 =&amp;gt; 10270, 32 =&amp;gt; 10255, 33 =&amp;gt; 10240, 34 =&amp;gt; 10225, 35 =&amp;gt; 10210, 36 =&amp;gt; 10195, 37 =&amp;gt; 10180, 38 =&amp;gt; 10165, 39 =&amp;gt; 10150, 40 =&amp;gt; 10135, 41 =&amp;gt; 10120, 42 =&amp;gt; 10105, 43 =&amp;gt; 10090, 44 =&amp;gt; 10075, 45 =&amp;gt; 10060, 46 =&amp;gt; 10045, 47 =&amp;gt; 10030, 48 =&amp;gt; 10015, 49 =&amp;gt; 10000);&lt;/p&gt; &lt;p&gt;在内网环境：&lt;br /&gt; 数组直接存取：&lt;br /&gt; 无压缩 写3.5秒/万，读3.2秒/万&lt;br /&gt; 带压缩 写3.3秒/万，读2.6秒/万&lt;br /&gt; 字符串存取：&lt;br /&gt; 无压缩 写3.0秒/万，读2.3秒/万。&lt;br /&gt; 带压缩 写3.1秒/万，读2.4秒/万&lt;br /&gt; 把数组的值都改成一样时（可压缩性高，压缩后只占了10字节以内），带压缩地写2.6秒/万，读1.9秒/万。&lt;/p&gt; &lt;p&gt;在本机：&lt;br /&gt; 数组直接存取：带压缩地写1.9秒/万，读1.1秒/万&lt;br /&gt; 字符串存取：&amp;nbsp;&lt;wbr&gt; 带压缩地写1.1秒/万，读0.9秒/万&lt;/p&gt; &lt;p&gt;&lt;br /&gt; 结论：&lt;br /&gt; 数组对象转成字符串存入能可以节约一半左右的空间，但在效率方面的提高非常有限，仅在本机上写数据上有所提高。&lt;br /&gt; 在数据可压缩性较好时，可以大量节省空间和时间。但可压缩性不太好时，几乎没有差别。&lt;/p&gt; &lt;p&gt;&lt;br /&gt; (4)主从测试结果：（100万数据以下）&lt;br /&gt; 100字节数据&lt;br /&gt; 新增：1000条/秒&lt;/p&gt; &lt;p&gt;400字节&lt;br /&gt; 更改：100条/秒（客户端单进程）&lt;br /&gt; 读取：3570条/秒 （客户端单进程）&lt;/p&gt; &lt;p&gt;结论：&lt;br /&gt; 在使用主从结构时，写效率很大影响，效率差别在100:1左右,所以不建议使用主从。&lt;/p&gt; &lt;p&gt;&lt;wbr&gt;&lt;br /&gt; (5)使用SVN最新版本的测试情况(新增350字节数据)&lt;br /&gt; 方案1：32位4核CPU，内存8G，-m2048启动:&lt;br /&gt; 表现优秀：0-443万&amp;nbsp;&lt;wbr&gt;&amp;nbsp;&lt;wbr&gt;&amp;nbsp;&lt;wbr&gt;&amp;nbsp;&lt;wbr&gt;&amp;nbsp;&lt;wbr&gt; 4000条/秒，非常稳定&lt;br /&gt; 表现较差：在443-800万&amp;nbsp;&lt;wbr&gt; 2100条/秒，忽快忽慢&amp;nbsp;&lt;wbr&gt;&amp;nbsp;&lt;wbr&gt;data.db在2.5G左右。&lt;br /&gt;  表现很差：在800-1千万&amp;nbsp;&lt;wbr&gt; 1400条/秒，忽快忽慢&amp;nbsp;&lt;wbr&gt;&amp;nbsp;&lt;wbr&gt;data.db在4G左右&amp;nbsp;&lt;wbr&gt;&amp;nbsp;&lt;wbr&gt;负载load average在5左右，服务器基本不响应。&lt;br /&gt; 出错情况：17次/1千万&lt;/p&gt; &lt;p&gt;在本服务器上启动两个mdb时，负载比一个高，性能较快地达到瓶颈。三个mdb时，负载很高，启动5个mdb进程时，写数据在1000多条/秒了，基本就 没有性能可言。&lt;/p&gt; &lt;p&gt;&lt;wbr&gt;&lt;/p&gt; &lt;p&gt;方案2：64位4核CPU，内存8G，-m6144启动:&lt;br /&gt; 0-1200万&amp;nbsp;&lt;wbr&gt;&amp;nbsp;&lt;wbr&gt; 5000条/秒，非常稳定&lt;br /&gt; 1300万后&amp;nbsp;&lt;wbr&gt;&amp;nbsp;&lt;wbr&gt; 2000条/秒，忽快忽慢&amp;nbsp;&lt;wbr&gt;data.db在6G左右&lt;br /&gt; 1800万后&amp;nbsp;&lt;wbr&gt;&amp;nbsp;&lt;wbr&gt; 1400条/秒，忽快忽慢&amp;nbsp;&lt;wbr&gt;data.db在8G左右&amp;nbsp;&lt;wbr&gt;&amp;nbsp;&lt;wbr&gt;此时读数据性能也不太稳定，但大部分保持在3000-4000条 /秒以上。负载load average在3左右，服务器仍然响应。&lt;br /&gt; 出错情况： 20次/1千万&lt;/p&gt; &lt;p&gt;&lt;wbr&gt;&lt;/p&gt; &lt;p&gt;在本服务器上，起2个mdb进程的效率比一个稍好一些，写数据在5599条/秒左右，读数据在10000条/秒左右。在32位CPU的服务器上则相反，性 能更快地达到瓶颈。&lt;/p&gt; &lt;p&gt;&lt;strong&gt;在重新启动mcdb后，读和写的速度都又恢复到了最好的状态，测试到单个文件大小达到14G时，仍然能和刚开始的速度一样。另外，当负载 下降后，再插入数据也能有很高的性能。&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;mdb停止时不能删除日志，否则不能在原数据基础上再重启。&lt;/p&gt; &lt;p&gt;&lt;wbr&gt;&lt;/p&gt; &lt;p&gt;结论：&lt;br /&gt; mcdb根据硬件的情况，对应着相应的性能瓶颈。强烈建议使用CPU4核64位，8G内存的服务器，测试大数量时，表现很稳定和高效。而32位的服务器因 为不能管理大内存，差别很大,很容易达到瓶颈，进入不稳定状态，如果负载重需要人工重启干预。&lt;/p&gt; &lt;p&gt;重新启动mcdb，可以达到释放内存，提高性能的效果。隔一断时间插入数据，也可以降低负载。&lt;br /&gt; 应该使用SVN的版本。SVN的最新版本整体数据也比发布版在开始时更为稳定。&lt;/p&gt; &lt;p&gt;一台服务器上最好不要超过两个以上mdb服务。&lt;br /&gt; mcdb出错的概率比较低，在20次/1千万左右，如果出错率更高，可能是服务器负载很大造成。有些写错误实际上已经写入，报错的原因仅仅是返回的数据未 读到。&lt;/p&gt; &lt;p&gt;&lt;wbr&gt;&lt;/p&gt; &lt;p&gt;(6)并发测试（内网环境）&lt;/p&gt; &lt;p&gt;10并发读和写&amp;nbsp;&lt;wbr&gt; 每线程50000次 每线程错误量15次左右 错误率0.03%&lt;br /&gt; 500并发读和写 每线程100次&amp;nbsp;&lt;wbr&gt;&amp;nbsp;&lt;wbr&gt; 每线程错误量5次左右&amp;nbsp;&lt;wbr&gt; 错误率5%，允许失败重连，最高连接数达到2300个。&lt;/p&gt; &lt;p&gt;300并发写 每线程100次&amp;nbsp;&lt;wbr&gt;&amp;nbsp;&lt;wbr&gt; 每线程错误量2次左右&amp;nbsp;&lt;wbr&gt; 错误率2%，&lt;/p&gt; &lt;p&gt;100并发读 每线程50次&amp;nbsp;&lt;wbr&gt;&amp;nbsp;&lt;wbr&gt; 错误率5%以上，允许失败重连，最高连接数达到2650以上。&lt;/p&gt; &lt;p&gt;50并发读 每线程5000次 错误率1%，速度很快，正常。&lt;/p&gt; &lt;p&gt;&lt;wbr&gt;&lt;/p&gt; &lt;p&gt;结论：&lt;/p&gt; &lt;p&gt;mdb不是一个可靠db,不能&lt;strong&gt;独立&lt;/strong&gt;作为db使用，可作为大缓存。我理解，mdb虽说是持久层，但它继承自缓存的性质， 决定了它不可能是可靠的。&lt;/p&gt; &lt;p&gt;mdb对高并发的支持并不好，读写分离解决不了问题，客户端如使用并发的长连接不断地读写，长连接数保持在50左右时效率是可靠的。&lt;/p&gt; &lt;p&gt;&lt;wbr&gt;&lt;/p&gt; &lt;p&gt;&lt;wbr&gt;&lt;/p&gt; &lt;p&gt;&lt;wbr&gt;&lt;/p&gt; &lt;p&gt;三.总结：在并发较高的环境下，将memcachedb定义为大缓存更合适，而不适用为单独的db.&lt;/p&gt; &lt;p&gt;1.memcachedb 必须使用多线程启动，需要在编译时加上--enable-threads，否则在100万左右数以后据时，写入数据将不断报错，并效率极低，且读写并行能 力极差。另外，如果要使用-m参数，需要从SVN拿，发布版不行。&lt;/p&gt; &lt;p&gt;2.使用8G内存与2G内存对比，速度差别在2：1左右。(2G的数据就不提供了)&lt;/p&gt; &lt;p&gt;3.使用localhost和千兆内网速度比为4:1。&lt;/p&gt; &lt;p&gt;4.在使用主从结构时，写效率很大影响，效率差别在100:1左右,所以不建议使用主从。&lt;/p&gt; &lt;p&gt;5.数据的大小对写效率有一定的影响，400字节和100字节的数据在写入数据时，速度差别为3：2左右，读数据效率差别较小。&lt;/p&gt; &lt;p&gt;6.客户端程序多进程与单进程对效率影响差别很小。甚至过多客户端进程写入时，反而影响效率。&lt;/p&gt; &lt;p&gt;7.数组对象转成字符串存入能可以节约一半左右的空间，但在效率方面的提高非常有限，仅在本机上写数据上有所提高。&lt;/p&gt; &lt;p&gt;8.在数据可压缩性较好时，可以大量节省空间和时间。但可压缩性不太好时，几乎没有差别。&lt;/p&gt; &lt;p&gt;9.mcdb根据硬件的情况，对应着相应的性能瓶颈。在方案1中，存放3G以下数据量能得到最佳性能，方案2则在6G以下。可以启动多个进程来解决单个文 件太大的问题。&lt;br /&gt;  10.单线程连接时，mcdb出错的概率比较低，在20次/1千万左右&lt;/p&gt; &lt;p&gt;11.如果将log全都删除，重启数据库会失败。可以在启动时用-E选项，由mdb自动管理日志。&lt;/p&gt; &lt;p&gt;12.并发时，mdb不是一个可靠db,有一定的出错率，不能&lt;strong&gt;独立&lt;/strong&gt;作为db使用，可作为大缓存。&lt;/p&gt; &lt;p&gt;13.mdb对高并发的支持并不好，读写分离解决不了问题，客户端如使用并发的长连接不断地读写，长连接数保持在50左右时效率是可靠的。&lt;/p&gt; &lt;p&gt;&lt;br /&gt; 四.参考：&lt;br /&gt; 1.memcachedb官方测试结果： &lt;a target="_blank" href="http://memcachedb.org/benchmark.html"&gt;http://memcachedb.org/benchmark.html&lt;/a&gt;&lt;br /&gt;  2.Tokyo Cabinet的测试结果和介绍：&lt;a target="_blank" href="http://blog.s135.com/read.php?362&amp;amp;guid=9"&gt;http://blog.s135.com/read.php?362&amp;amp;guid=9&lt;/a&gt;&lt;br /&gt;  3.某网友的Tokyo Cabinet测试:http://blog.zol.com.cn/861/article_860439.html 结果比我在基于Tokyo Tyrant的测试好看多了，但也明确表示在200万数据以后变慢很多。&lt;/p&gt; &lt;p&gt;官网：&lt;a target="_blank" href="http://memcachedb.org/"&gt;http://memcachedb.org/&lt;/a&gt;&lt;br /&gt; 作者的讨论组:http://groups.google.com/group/memcachedb&lt;br /&gt; 安装和启动指南：&lt;a target="_blank" href="http://blog.csdn.net/simonlsy/archive/2008/01/07/2027940.aspx"&gt;http://blog.csdn.net/simonlsy/archive/2008/01/07/2027940.aspx&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;[转自: http://blog.sina.com.cn/s/blog_403b3b8f0100coe7.html ]&lt;br /&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/suyang/aggbug/1700523.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/suyang/archive/2010/03/30/1700523.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/suyang/archive/2010/02/12/1667682.html</id><title type="text">[转]hibernate-memcached补丁：支持Whalin的MemCached Java客户端</title><summary type="text">hibernate-memcached（http://code.google.com/p/hibernate-memcached/ ）是允许hibernate使用MemCached作为二级缓存的项目，它用到了spymemcached（http://code.google.com/p/spymemcached/ ）这个MemCached的Java客户端。花了一点时间做了个补丁，让它也支持Whalin的Java客户端（http://whalin.com/memcached/ ）。所有的代码（包括原hibernate-memcached的所有源码）、javadoc及重新制作的发布包请见附件，限于篇幅就不具体说明了。以下是我更新过的hibernate-memcached的配置说明，原配置说明请参见http://code.google.com/p/hibernate-memcached/wiki/Configuration </summary><published>2010-02-11T16:39:00Z</published><updated>2010-02-11T16:39:00Z</updated><author><name>suyang</name><uri>http://www.cnblogs.com/suyang/</uri></author><link rel="alternate" href="http://www.cnblogs.com/suyang/archive/2010/02/12/1667682.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/suyang/archive/2010/02/12/1667682.html"/></entry><entry><id>http://www.cnblogs.com/suyang/archive/2010/01/29/1659529.html</id><title type="text">[转] Log4j 1.2.15 使用指南</title><summary type="text">        Log4j发展的真快，2005年用的时候版本是1.2.8。现在再看时发现都出到2.0了，仔细一看，还有点意思，log4j上作了个说明。log4j有3个分支，1.2是稳定版，1.3不再继续，2.0是实验版。　　看来还是用1.2版的比较好，现在的版本是1.2.15，和1.2.8比有很大的变化。从配置文件里反映出来，大的结构都变了。现把要点摘录如下：　　Log4j有3个主要部件，loggers, appenders and layouts.　　logger有如下几个级别，排列如下：DEBUG &lt; INFO &lt; WARN &lt; ERROR &lt; FATAL   　　logger引入了继承的概念，这里指的是名称继承，logger com.foo是 com.foo.Bar的父logger。同样java.util是java.util.Vector的父类。另外Logger x = Logger.getLogger("wombat"); 和 Logger y = Logger.getLogger("wombat"); 是指向同一个对象，这样的话不需要到处传递对象的引用。  &#xD;</summary><published>2010-01-29T14:06:00Z</published><updated>2010-01-29T14:06:00Z</updated><author><name>suyang</name><uri>http://www.cnblogs.com/suyang/</uri></author><link rel="alternate" href="http://www.cnblogs.com/suyang/archive/2010/01/29/1659529.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/suyang/archive/2010/01/29/1659529.html"/></entry><entry><id>http://www.cnblogs.com/suyang/archive/2010/01/25/1655519.html</id><title type="text">云计算、Amazon EC2、Hadoop简介</title><summary type="text">近来云计算越来越热门了，云计算已经被看作 IT 业的新趋势。云计算可以粗略地定义为使用自己环境之外的某一服务提供的可伸缩计算资源，并按使用量付费。可以通过 Internet 访问 “云” 中的任何资源，而不需要担心计算能力、带宽、存储、安全性和可靠性等问题。本文简要介绍 Amazon EC2 这样的云计算平台，可以租借这种平台上的虚拟 Linux® 服务器；然后介绍开放源码 MapReduce 框架 Apache Hadoop，这个框架将构建在虚拟 Linux 服务器中以建立云计算框架。但是，Hadoop 不仅可以部署在任何厂商提供的 VM 上，还可以部署在物理机器上的一般 Linux OS 中。在讨论 Apache Hadoop 之前，我们先简要介绍一下云计算系统的结构。</summary><published>2010-01-24T16:30:00Z</published><updated>2010-01-24T16:30:00Z</updated><author><name>suyang</name><uri>http://www.cnblogs.com/suyang/</uri></author><link rel="alternate" href="http://www.cnblogs.com/suyang/archive/2010/01/25/1655519.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/suyang/archive/2010/01/25/1655519.html"/></entry></feed>
