<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
  <channel>
    <title>YM</title>
    <description>本人从事软件开发</description>
    <link>http://yymmiinngg.javaeye.com</link>
    <language>UTF-8</language>
    <copyright>Copyright 2003-2008, JavaEye.com</copyright>
    <docs>http://blogs.law.harvard.edu/tech/rss</docs>
    <generator>JavaEye - 做最棒的软件开发交流社区</generator>
      <item>
        <title>JSP SmartUpload 下载小文件异常、错误的解决方法</title>
        <author>yymmiinngg</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://yymmiinngg.javaeye.com">yymmiinngg</a>&nbsp;
          链接：<a href="http://yymmiinngg.javaeye.com/blog/213021" style="color:red;">http://yymmiinngg.javaeye.com/blog/213021</a>&nbsp;
          发表时间: 2008年07月09日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <pre name="code" class="java">&lt;%@ page contentType="application/x-msdownload;charset=UTF-8" import="com.jspsmart.upload.*,java.io.File"%&gt;
&lt;%
	String filename = request.getParameter("filename");
	String resultdir = (String) request.getAttribute("resultdir");
	File file = new File(resultdir, filename);

	//新建一个SmartUpload对象
	SmartUpload su = new SmartUpload();

	// 初始化
	su.initialize(pageContext);
	// 设定contentDisposition为null以禁止浏览器自动打开文件，
	// 保证点击链接后是下载文件。若不设定，则下载的文件扩展名为
	// doc时，浏览器将自动用word打开它。扩展名为pdf时，
	// 浏览器将用acrobat打开。
	// 下载文件
	su.setContentDisposition(null);
	su.downloadFile(file.getAbsolutePath());
	
	// 如果是小文件加上这句就能处理
	response.getOutputStream().close();
%&gt;
</pre>
<p>&nbsp;</p>
<p>写一个SmartUpload下载，下载大文件大约10K没问题，但是1K左右的小文件就会报异常：java.lang.IllegalStateException: getOutputStream() has already been called for this response</p>
<p>&nbsp;</p>
<p>我在JSP页面的最后加了一句&ldquo;response.getOutputStream().close();&rdquo;，问题解决。</p>
          <br/>
          <span style="color:red;">
            <a href="http://yymmiinngg.javaeye.com/blog/213021#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 09 Jul 2008 12:06:03 +0800</pubDate>
        <link>http://yymmiinngg.javaeye.com/blog/213021</link>
        <guid>http://yymmiinngg.javaeye.com/blog/213021</guid>
      </item>
      <item>
        <title>sql server 2005 将表记录导出到文件</title>
        <author>yymmiinngg</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://yymmiinngg.javaeye.com">yymmiinngg</a>&nbsp;
          链接：<a href="http://yymmiinngg.javaeye.com/blog/186674" style="color:red;">http://yymmiinngg.javaeye.com/blog/186674</a>&nbsp;
          发表时间: 2008年04月25日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>在使用sql server 2005数据时，需要将大量数据导出到文本文件就需要用到这个命令，该命令速度比较快。<br /><br /><span style="color: #ffffff; background-color: #000000;"><strong>命令行:&gt;bcp "select&nbsp;[字段列表] from [数据库].DBO.[表或视图]" queryout&nbsp;[本地路径，如 D:\test.txt] -c -S[服务器名，如 localhost] -U[用户名，如 sa] -P[密码]<br /><br /></strong></span>另外注意：如果环境变量里没有sql server 2005 的bin目录配置（即无法找到bcp命令），请到 sql server 2005/90/tool/bin 目录下运行此命令。</p>
          <br/>
          <span style="color:red;">
            <a href="http://yymmiinngg.javaeye.com/blog/186674#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 25 Apr 2008 11:38:32 +0800</pubDate>
        <link>http://yymmiinngg.javaeye.com/blog/186674</link>
        <guid>http://yymmiinngg.javaeye.com/blog/186674</guid>
      </item>
      <item>
        <title>PHP验证码应用，示例</title>
        <author>yymmiinngg</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://yymmiinngg.javaeye.com">yymmiinngg</a>&nbsp;
          链接：<a href="http://yymmiinngg.javaeye.com/blog/157287" style="color:red;">http://yymmiinngg.javaeye.com/blog/157287</a>&nbsp;
          发表时间: 2008年01月18日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <table border="0" style="table-layout: fixed"><tbody><tr><td><div class="cnt"><p><strong>近日试着用PHP做了一个验证码程序，示例如下：</strong></p><p>&nbsp;</p><p><strong>一、准备一个展示并提交验证码的页面</strong></p><pre name="code" class="xml">&lt;?php

    @header(&quot;content-type:text/html; charset=UTF-8&quot;);

    //打开session

    session_start();

?&gt;

&lt;html&gt;

    &lt;head&gt;

       &lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=utf-8&quot; /&gt;

       &lt;title&gt;PHP验证码示例&lt;/title&gt;

    &lt;/head&gt;

    &lt;body&gt;

       验证码：&lt;br/&gt;

       &lt;iframe id=&quot;iimg&quot; height=&quot;100&quot; width=300 src=&quot;img.php&quot; frameborder=&quot;0&quot; &gt;&lt;/iframe&gt;

       &lt;br/&gt;

       &lt;input type=button value=&quot;看不清，换一张&quot; onclick=&quot;iimg.location.reload();&quot;&gt;

       &lt;br&gt;

       &lt;form action=&quot;validate.php&quot; method=&quot;post&quot;&gt;

           输入验证码：&lt;input name=&quot;imgId&quot; style=&quot;width:60&quot;&gt;

           &lt;input type=&quot;submit&quot; value=&quot;确定&quot;&gt;

       &lt;/form&gt;

    &lt;/body&gt;

&lt;/html&gt;
</pre><p>&nbsp;</p><p><strong>二、以下是验证码生成页面，该页面在第一页面中被&lt;img&gt;调用</strong></p><pre name="code" class="xml">&lt;?php

Header(&quot;Content-type: image/gif&quot;);

session_start();

//验证码为随机字符，以下是算法

$randval;

for($i=0;$i&lt;7;$i++){

    $randstr = mt_rand(ord('A'),ord('Z'));

    srand((double)microtime()*1000000);

    $randv = mt_rand(0,10);

    if($randv%2==0){

       $randval.=mt_rand(0,10);

    }else{

       $randval.=chr($randstr);

    }

}

//注册验证码到session

session_register($randval);

//以下是绘制验证码图

$height = 50;//图高

$width = 100;//图宽

$im = ImageCreateTrueColor($width, $height);

$white = ImageColorAllocate($im, 255, 255, 255);

$blue = ImageColorAllocate($im, 0, 0, 64);

ImageFill($im, 0, 0, $white);

srand((double)microtime()*1000000000);

ImageLine($im, mt_rand(0,$width/3), mt_rand(0,$height/3), mt_rand($width/3,$width), mt_rand($height/3,$height), $blue);

srand((double)microtime()*1000000);

ImageLine($im, mt_rand($width/3,$width), mt_rand(0,$height/3), mt_rand(0,$width/3), mt_rand(0,$height/3), $blue);

srand((double)microtime()*1000000);

ImageString($im,16 , mt_rand(0,$width - strlen($randval) * 10), mt_rand(0,$height-12), $randval, $blue);

ImageGIF($im);

ImageDestroy($im);

/*

需要注意的是：为了支持以上绘图函数，我们必须在PHP载入GD2图形处理库，可修改 php.ini 文件中的

;extension=php_gd2.dll

为

extension=php_gd2.dll

即开启GD2库

*/

?&gt;
</pre><p>&nbsp;</p><p><strong>三、这是验证页面，提示是否通过验证</strong></p><pre name="code" class="xml">&lt;?php @header(&quot;content-type:text/html; charset=UTF-8&quot;);

    //开启session

    session_start();

    //得到用户输入的验证码，并转换成大写

    $imgId_req = $_REQUEST['imgId'];

    $imgId_req = strtoupper($imgId_req);

    //验证该字符串是否注册了session变量

    if (session_is_registered($imgId_req)) {

       echo &quot;&lt;font color=blue &gt;通过验证！&lt;/font&gt;&quot;;

    } else {

       echo &quot;&lt;font color=red &gt;验证错误！&lt;/font&gt;&quot;;

    }

    //关闭session，以清除所有注册过的变量

    session_destroy();

?&gt;</pre><p>&nbsp;</p><p><strong>四、开启服务，在地址栏中输入 &ldquo;.../input.php&rdquo; ，此处省略了主机及目录名</strong></p><p>&nbsp;</p><p><strong>五、更多有关GD2库的介绍请参考：</strong></p><p><a href="http://www.cndw.com/tech/server/2006042051613.asp">http://www.cndw.com/tech/server/2006042051613.asp</a></p></div></td></tr></tbody></table>
          <br/>
          <span style="color:red;">
            <a href="http://yymmiinngg.javaeye.com/blog/157287#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 18 Jan 2008 14:48:35 +0800</pubDate>
        <link>http://yymmiinngg.javaeye.com/blog/157287</link>
        <guid>http://yymmiinngg.javaeye.com/blog/157287</guid>
      </item>
      <item>
        <title>第六章、标识符和变量的作用域</title>
        <author>yymmiinngg</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://yymmiinngg.javaeye.com">yymmiinngg</a>&nbsp;
          链接：<a href="http://yymmiinngg.javaeye.com/blog/157260" style="color:red;">http://yymmiinngg.javaeye.com/blog/157260</a>&nbsp;
          发表时间: 2008年01月18日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>Ruby 的标识符用来指向常量，变量，方法，类和模块。标识符的首字符用来帮助我们确定标识所指向内容的作用域。</p><p>注意：关键字不能用来当作常量，变量，方法，类或模块的名字。</p><p>Ruby的标识符区分大小写。 </p><p>Ruby 使用一个约定来帮助它区别一个名字的用法：名字前面的第一个字符表明这个名字的用法。局部变量、方法参数和方法名称应该用一个小写字母开头或者用一个下划线开头；全局变量用美元符作为前缀&ldquo;$&rdquo;；而实例变量用&ldquo;@&rdquo;开头；类变量用&ldquo;@@&rdquo; 开头；类名、模块名和常量应该用大写字母开头。</p><p><br />词首字母后面可以是字母、数字和下划线的任意组合；&ldquo;@&rdquo;后面不可以直接跟数字。</p><p><br />Ruby&nbsp; 程序代码现在是用7位ACSII&nbsp; 码来表示，通过语言扩展来支持 EUC, SJIS &nbsp;或 UTF-8&nbsp; 等8位编码系统。Ruby 2.0&nbsp; 版本将 16位的 Unicode&nbsp; 编码。</p><p>&nbsp;</p>
          <br/>
          <span style="color:red;">
            <a href="http://yymmiinngg.javaeye.com/blog/157260#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 18 Jan 2008 13:47:30 +0800</pubDate>
        <link>http://yymmiinngg.javaeye.com/blog/157260</link>
        <guid>http://yymmiinngg.javaeye.com/blog/157260</guid>
      </item>
      <item>
        <title>第五章、ruby语法之——注释、关键字、运算符、分融符</title>
        <author>yymmiinngg</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://yymmiinngg.javaeye.com">yymmiinngg</a>&nbsp;
          链接：<a href="http://yymmiinngg.javaeye.com/blog/154852" style="color:red;">http://yymmiinngg.javaeye.com/blog/154852</a>&nbsp;
          发表时间: 2008年01月10日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>我们清楚ruby区分大小写，语法简明，代码简短精干，并且可读性较强。</p><p><br />下面让我们了解一下ruby的语法，这是学任何语言的开始(注释、关键字、运算符、分隔符等)。</p><p>&nbsp;</p><p><strong>一、注释与分行</strong></p><p>&nbsp;</p><p>Ruby中的注释有单行与多行两种，例如：</p><pre name="code" class="ruby">puts '以下是单行注释'
# 这行是单行注释，单行注释用&quot;#&quot;
=begin 
  多行注释可以用&quot;=begin&quot;和&quot;=end&quot;
  实际上，这也是Ruby的内嵌文档(Rdoc)注释，类似javadoc，可以用命令ri从源文件生产文档。 
=end
puts '=begin 和 =end 之前的是多行注释'</pre><p>&nbsp;</p><p>结果：<br /><span style="color: #ffffff; background-color: #000000">以下是单行注释<br />=begin 和 =end 之前的是多行注释</span></p><p>&nbsp;</p><p>注：Rdoc是内嵌在ruby代码之中的，可以转换为html文档说明。类似javadoc。<br />ri是一个命令行程序，用来查看函数说明、类说明。函数说明、类说明应该放置在&quot;=begin&quot;和&quot;=end&quot;之中。&quot;=begin&quot;一定要写在行首，也就是说，这一行的前六个字符是&quot;=begin&quot;，不允许有空格在这之前。</p><p>Ruby 中用分号&quot;;&quot;来表示一个语句的结束。一行如果有多个语句，每个语句用分号隔开，而最后一个语句可以省略分号。换行符表示一行结束。</p><p>&nbsp;</p><p>如果语句太长，可以用&quot;\&quot;连接行。例如：</p><pre name="code" class="ruby">p  &quot;行连接开始&gt;&gt;&gt;&quot; \
&quot;&lt;&lt;&lt;结束&quot; </pre><p>&nbsp;</p><p>结果：<br /><span style="color: #ffffff; background-color: #000000">行连接开始&gt;&gt;&gt;&lt;&lt;&lt;结束</span></p><p><br /><strong>二、关键字、运算符、分隔符</strong></p><p>&nbsp;</p><p>关键字、运算符、分隔符一起构成了一门编程语言的基本定义</p><p>&nbsp;</p><p>Ruby中的常用分隔符如下： </p><p><br /><span style="color: #999999; background-color: #ffffff">符号</span></p><p><span style="color: #999999; background-color: #ffffff">名称</span></p><p><span style="color: #999999; background-color: #ffffff">用途</span></p><p><br />；</p><p>分号</p><p>用来分隔一行中的多个语句</p><p>&nbsp;</p><p>()</p><p>圆括号</p><p>提高优先级；定义方法时容纳参数列表</p><p>&nbsp;</p><p>&quot;　&quot;</p><p>空格/分隔字符</p><p>在可省略&quot;()&quot;的地方代替&quot;()&quot;</p><p><br />,&nbsp;</p><p>逗号</p><p>隔开多个参数</p><p><br />.&nbsp;</p><p>点</p><p>将对象与它的方法隔开</p><p><br />::</p><p>双冒号</p><p>域作用符，将模块(类)与它的常量隔开</p><p>&nbsp;</p><p>Ruby中的关键字如下：</p><p><br />模块定义：module<br />类定义：　class<br />方法定义：def，undef<br />检查类型：defined?<br />条件语句：if，then，else，elsif，case，when，unless<br />循环语句：for，in，while，until，next，break，do，redo，retry，yield<br />逻辑判断：not，and，or<br />逻辑值：　true，false</p><p>空值：　　nil&nbsp;&nbsp; <br />异常处理：rescue，ensure&nbsp;&nbsp; <br />对象引用：super，self&nbsp;&nbsp; <br />块的起始：begin/end <br />嵌入模块：BEGIN，END&nbsp;&nbsp; <br />文件相关：__FILE__，__LINE__<br />方法返回：return<br />别名：　　alias</p><p>&nbsp;</p><p>注：BEGIN模块相当于C语言中的宏， END模块用来作一些收尾工作。有了require，include，应该取消BEGIN和END的语法定义。</p><p>&nbsp;</p><p>ruby中的运算符如下：优先级(由高到低)</p><p><br /><span style="color: #999999; background-color: #ffffff">能否重写<br />运算符<br />描述</span></p><p>&nbsp;</p><p>Y&nbsp;&nbsp;&nbsp;&nbsp;<br />[]、[]=<br />数组下标、数组元素赋值</p><p>&nbsp;</p><p>Y<br />**<br />乘冥</p><p>Y<br />！、~、+、-<br />非、位非、一元加(正号)、负号</p><p>&nbsp;</p><p>Y<br />*、/、%<br />乘、除、模</p><p>&nbsp;</p><p>Y<br />+、-<br />加、减</p><p>&nbsp;</p><p>Y<br />&gt;&gt;、&lt;&lt;<br />右移、左移 </p><p>&nbsp;</p><p>Y<br />&amp;<br />位与</p><p>&nbsp;</p><p>Y<br />^、|<br />位异或、位或 </p><p>&nbsp;</p><p>Y<br />&lt;=、&lt;、&gt;、&gt;=<br />小于等于、小于、大于、大于等于</p><p>&nbsp;</p><p>Y<br />&lt;=&gt;、==、===、=~、!=、!~<br />各种相等判断（不能重写=~、!=、!~） </p><p>&nbsp;</p><p>N<br />&amp;&amp;<br />短路与</p><p>&nbsp;</p><p>N<br />||<br />短路或</p><p>&nbsp;</p><p>N<br />..、...<br />区间的开始点到结束点</p><p>&nbsp;</p><p>N<br />? :<br />三元条件运算符</p><p>&nbsp;</p><p>N<br />=、%=、~=、/=、-=、+=、|=、&amp;=、&gt;&gt;=、&lt;&lt;=、*=、&amp;&amp;=、||=、**=<br />各种赋值</p><p>&nbsp;</p><p>N<br />defined? <br />检查类型</p><p>&nbsp;</p><p>N<br />not <br />逻辑非</p><p>&nbsp;</p><p>N<br />or、and <br />逻辑或、逻辑与 </p><p>&nbsp;</p><p>N<br />if、unless、while、until <br />判断与循环</p><p>&nbsp;</p><p>N<br />begin、end <br />定义方法，类，模块的范围</p><p>&nbsp;</p><p>值得注意的是，ruby中没有&quot;++&quot;、&quot;--&quot;一类的运算符，但可以通过&quot;+=1&quot;、&quot;-=1&quot;实现。</p>
          <br/>
          <span style="color:red;">
            <a href="http://yymmiinngg.javaeye.com/blog/154852#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 10 Jan 2008 19:36:34 +0800</pubDate>
        <link>http://yymmiinngg.javaeye.com/blog/154852</link>
        <guid>http://yymmiinngg.javaeye.com/blog/154852</guid>
      </item>
      <item>
        <title>MySQL数据库服务器优化详细</title>
        <author>yymmiinngg</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://yymmiinngg.javaeye.com">yymmiinngg</a>&nbsp;
          链接：<a href="http://yymmiinngg.javaeye.com/blog/154700" style="color:red;">http://yymmiinngg.javaeye.com/blog/154700</a>&nbsp;
          发表时间: 2008年01月10日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p><span style="color: #333333; background-color: #c0c0c0">我最近在网上查了一些有关优化MySql的资料，并对照MySql手册对一些调优设置进行了细结，但是由于时间比较勿忙，没来得及对这些设置进行实验/测试，你可以把这些方法应用到实际中，得出具体结论。调优方法大致如下：</span></p><p>&nbsp;</p><p>MySql服务器的后台管理程序，要想使用客户端程序，该程序必须运行，因为客户端通过连接服务器来访问数据库。下面让我们以服务器的系统变量和状态变量为根据，优化我们的MySql数据库服务。</p><p><br /><strong>在这之前，我们需要掌握以下方法：</strong></p><p><br />查看MySql状态及变量的方法：</p><p><br />Mysql&gt; show status &mdash;&mdash;显示状态信息（扩展show status like 'XXX'）<br />Mysql&gt; show variables &mdash;&mdash;显示系统变量（扩展show variables like 'XXX'）<br />Mysql&gt; show innodb status &mdash;&mdash;显示InnoDB存储引擎的状态<br />Shell&gt; mysqladmin variables -u username -p password&mdash;&mdash;显示系统变量<br />Shell&gt; mysqladmin extended-status -u username -p password&mdash;&mdash;显示状态信息</p><p><br /><strong>查看状态变量及帮助：</strong></p><p><strong><br /></strong>Shell&gt; mysqld --verbose --help [|more #逐行显示]</p><p><br /><strong>首先，让我们看看有关请求连接的变量：</strong></p><p><br />为了能适应更多数据库应用用户，MySql提供了连接（客户端）变量，以对不同性质的用户群体提供不同的解决方案，笔者就<strong>max_connections，back_log</strong>做了一些细结，如下：</p><p><br /><strong>max_connections</strong>是指MySql的最大连接数，如果服务器的并发连接请求量比较大，建议调高此值，以增加并行连接数量，当然这建立在机器能支撑的情况下，因为如果连接数越多，介于MySql会为每个连接提供连接缓冲区，就会开销越多的内存，所以要适当调整该值，不能盲目提高设值。可以过'conn%'通配符查看当前状态的连接数量，以定夺该值的大小。</p><p><br /><strong>back_log</strong>是要求MySQL能有的连接数量。当主要MySQL线程在一个很短时间内得到非常多的连接请求，这就起作用，然后主线程花些时间(尽管很短)检查连接并且启动一个新线程。back_log值指出在MySQL暂时停止回答新请求之前的短时间内多少个请求可以被存在堆栈中。如果期望在一个短时间内有很多连接，你需要增加它。也就是说，如果MySql的连接数据达到max_connections时，新来的请求将会被存在堆栈中，以等待某一连接释放资源，该堆栈的数量即back_log，如果等待连接的数量超过back_log，将不被授予连接资源。另外，这值（back_log）限于您的操作系统对到来的TCP/IP连接的侦听队列的大小。你的操作系统在这个队列大小上有它自己的限制（可以检查你的OS文档找出这个变量的最大值），试图设定back_log高于你的操作系统的限制将是无效的。</p><p><br /><strong>优化了MySql的连接后属性后，我们需要看看缓冲区变量：</strong></p><p><strong><br /></strong>使用MySql数据库存储大量数据（或使用复杂查询）时，我们应该考虑MySql的内存配置。如果配置MySQL服务器使用太少的内存会导致性能不是最优的；如果配置了太多的内存则会导致崩溃，无法执行查询或者导致交换操作严重变慢。在现在的32位平台下，仍有可能把所有的地址空间都用完，因此需要审视。</p><p><br />计算内存使用的秘诀公式就能相对地解决这一部分问题。不过，如今这个公式已经很复杂了，更重要的是，通过它计算得到的值只是&ldquo;理论可能&rdquo;并不是真正消耗的值。事实上，有8GB内存的常规服务器经常能运行到最大的理论值（100GB甚至更高）。此外，你轻易不会使用到&ldquo;超额因素&rdquo;（它实际上依赖于应用以及配置）。一些应用可能需要理论内存的10%而有些仅需1%。<br />那么，我们可以做什么呢？</p><p><br /><strong>来看看那些在启动时就需要分配并且总是存在的全局缓冲吧！</strong></p><p><br />全局缓冲：<br /><strong>key_buffer_size, innodb_buffer_pool_size, innodb_additional_mem_pool_size，innodb_log_buffer_size, query_cache_size</strong></p><p><br />注：如果你大量地使用MyISAM表，那么你也可以增加操作系统的缓存空间使得MySQL也能用得着。把这些也都加到操作系统和应用程序所需的内存值之中，可能需要增加32MB甚至更多的内存给MySQL服务器代码以及各种不同的小静态缓冲。这些就是你需要考虑的在MySQL服务器启动时所需的内存。其他剩下的内存用于连接。</p><p><br /><strong>key_buffer_size</strong>决定索引处理的速度，尤其是索引读的速度。一般我们设为16M，通过检查状态值Key_read_requests和Key_reads，可以知道key_buffer_size设置是否合理。比例key_reads / key_read_requests应该尽可能的低，至少是1:100，1:1000更好（上述状态值可以使用'key_read%'获得用来显示状态数据）。key_buffer_size只对MyISAM表起作用。即使你不使用MyISAM表，但是内部的临时磁盘表是MyISAM表，也要使用该值。可以使用检查状态值'created_tmp_disk_tables'得知详情。</p><p><br /><strong>innodb_buffer_pool_size</strong>对于InnoDB表来说，作用就相当于key_buffer_size对于MyISAM表的作用一样。InnoDB使用该参数指定大小的内存来缓冲数据和索引。对于单独的MySQL数据库服务器，最大可以把该值设置成物理内存的80%。 </p><p><br /><strong>innodb_additional_mem_pool_size</strong>指定InnoDB用来存储数据字典和其他内部数据结构的内存池大小。缺省值是1M。通常不用太大，只要够用就行，应该与表结构的复杂度有关系。如果不够用，MySQL会在错误日志中写入一条警告信息。</p><p><br /><strong>innodb_log_buffer_size</strong>指定InnoDB用来存储日志数据的缓存大小，如果您的表操作中包含大量并发事务（或大规模事务），并且在事务提交前要求记录日志文件，请尽量调高此项值，以提高日志效率。</p><p><br /><strong>query_cache_size</strong>是MySql的查询缓冲大小。（从4.0.1开始，MySQL提供了查询缓冲机制）使用查询缓冲，MySQL将SELECT语句和查询结果存放在缓冲区中，今后对于同样的SELECT语句（区分大小写），将直接从缓冲区中读取结果。根据MySQL用户手册，使用查询缓冲最多可以达到238%的效率。通过检查状态值&rsquo;Qcache_%&rsquo;，可以知道query_cache_size设置是否合理：如果Qcache_lowmem_prunes的值非常大，则表明经常出现缓冲不够的情况，如果Qcache_hits的值也非常大，则表明查询缓冲使用非常频繁，此时需要增加缓冲大小；如果Qcache_hits的值不大，则表明你的查询重复率很低，这种情况下使用查询缓冲反而会影响效率，那么可以考虑不用查询缓冲。此外，在SELECT语句中加入SQL_NO_CACHE可以明确表示不使用查询缓冲。</p><p><br /><strong>除了全局缓冲，MySql还会为每个连接发放连接缓冲。</strong></p><p><br />连接缓冲：<br />每个连接到MySQL服务器的线程都需要有自己的缓冲。大概需要立刻分配256K，甚至在线程空闲时，它们使用默认的线程堆栈，网络缓存等。事务开始之后，则需要增加更多的空间。运行较小的查询可能仅给指定的线程增加少量的内存消耗，然而如果对数据表做复杂的操作例如扫描、排序或者需要临时表，则需分配大约<strong>read_buffer_size，sort_buffer_size，read_rnd_buffer_size，tmp_table_size</strong>大小的内存空间。不过它们只是在需要的时候才分配，并且在那些操作做完之后就释放了。有的是立刻分配成单独的组块。tmp_table_size 可能高达MySQL所能分配给这个操作的最大内存空间了。注意，这里需要考虑的不只有一点 &mdash;&mdash; 可能会分配多个同一种类型的缓存，例如用来处理子查询。一些特殊的查询的内存使用量可能更大&mdash;&mdash;如果在MyISAM表上做成批的插入时需要分配 bulk_insert_buffer_size 大小的内存；执行 ALTER TABLE， OPTIMIZE TABLE， REPAIR TABLE 命令时需要分配 myisam_sort_buffer_size 大小的内存。</p><p><br /><strong>read_buffer_size</strong>是MySql读入缓冲区大小。对表进行顺序扫描的请求将分配一个读入缓冲区，MySql会为它分配一段内存缓冲区。read_buffer_size变量控制这一缓冲区的大小。如果对表的顺序扫描请求非常频繁，并且你认为频繁扫描进行得太慢，可以通过增加该变量值以及内存缓冲区大小提高其性能。</p><p><br /><strong>sort_buffer_size</strong>是MySql执行排序使用的缓冲大小。如果想要增加ORDER BY的速度，首先看是否可以让MySQL使用索引而不是额外的排序阶段。如果不能，可以尝试增加sort_buffer_size变量的大小。</p><p><br /><strong>read_rnd_buffer_size</strong>是MySql的随机读缓冲区大小。当按任意顺序读取行时(例如，按照排序顺序)，将分配一个随机读缓存区。进行排序查询时，MySql会首先扫描一遍该缓冲，以避免磁盘搜索，提高查询速度，如果需要排序大量数据，可适当调高该值。但MySql会为每个客户连接发放该缓冲空间，所以应尽量适当设置该值，以避免内存开销过大。</p><p><br /><strong>tmp_table_size是MySql的heap</strong>（堆积）表缓冲大小。所有联合在一个DML指令内完成，并且大多数联合甚至可以不用临时表即可以完成。大多数临时表是基于内存的(HEAP)表。具有大的记录长度的临时表 (所有列的长度的和)或包含BLOB列的表存储在硬盘上。如果某个内部heap（堆积）表大小超过tmp_table_size，MySQL可以根据需要自动将内存中的heap表改为基于硬盘的MyISAM表。还可以通过设置tmp_table_size选项来增加临时表的大小。也就是说，如果调高该值，MySql同时将增加heap表的大小，可达到提高联接查询速度的效果。</p><p><br /><strong>当我们设置好了缓冲区大小之后，再来看看：</strong></p><p><br /><strong>table_cache</strong>所有线程打开的表的数目，增大该值可以增加mysqld需要的文件描述符的数量。每当MySQL访问一个表时，如果在表缓冲区中还有空间，该表就被打开并放入其中，这样可以更快地访问表内容。通过检查峰值时间的状态值&rsquo;Open_tables&rsquo;和&rsquo;Opened_tables&rsquo;，可以决定是否需要增加table_cache的值。如果你发现open_tables等于table_cache，并且opened_tables在不断增长，那么你就需要增加table_cache的值了（上述状态值可以使用&rsquo;Open%tables&rsquo;获得）。注意，不能盲目地把table_cache设置成很大的值。如果设置得太高，可能会造成文件描述符不足，从而造成性能不稳定或者连接失败。</p><p><br /><strong>做了以上方面的调优设置之后，MySql应该基本能满足您需求（当然是建立在调优设置适当的情况下），我们还应该了解并注意：</strong></p><p><br />只有简单查询OLTP（联机事务处理）应用的内存消耗经常是使用默认缓冲的每个线程小于1MB，除非需要使用复杂的查询否则无需增加每个线程的缓冲大小。使用1MB的缓冲来对10行记录进行排序和用16MB的缓冲基本是一样快的（实际上16MB可能会更慢，不过这是其他方面的事了）。</p><p><br />找出MySQL服务器内存消耗的峰值。这很容易就能计算出操作系统所需的内存、文件缓存以及其他应用。在32位环境下，还需要考虑到32位的限制，限制 &ldquo;mysqld&rdquo; 的值大约为2.5G（实际上还要考虑到很多其他因素）。现在运行 &ldquo;ps aux&rdquo; 命令来查看 &ldquo;VSZ&rdquo; 的值（MySQL 进程分配的虚拟内存）。监视着内存变化的值，就能知道是需要增加或减少当前的内存值了。</p><p>&nbsp;</p><p><strong>最后来看看调优设置方法：</strong></p><p>&nbsp;</p><p>安装好MySql后，配制文件应该在 ./share/mysql (&quot;./&quot;即MySql安装目录) 目录中，配制文件有几个，有my-huge.cnf my-medium.cnf my-large.cnf my-small.cnf。win环境下即存在于MySql安装目录中的.ini文件。不同的流量的网站和不同配制的服务器环境，当然需要有不同的配制文件了。 </p><p>一般的情况下，my-medium.cnf这个配制文件就能满足我们的大多需要；一般我们会把配置文件拷贝到 /etc/my.cnf ，win环境下则拷备到 my.ini 下即可，只需要修改这个配置文件就可以了。</p>
          <br/>
          <span style="color:red;">
            <a href="http://yymmiinngg.javaeye.com/blog/154700#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 10 Jan 2008 13:07:12 +0800</pubDate>
        <link>http://yymmiinngg.javaeye.com/blog/154700</link>
        <guid>http://yymmiinngg.javaeye.com/blog/154700</guid>
      </item>
      <item>
        <title>JAVA发送HTTP请求，返回HTTP响应内容，实例及应用</title>
        <author>yymmiinngg</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://yymmiinngg.javaeye.com">yymmiinngg</a>&nbsp;
          链接：<a href="http://yymmiinngg.javaeye.com/blog/154258" style="color:red;">http://yymmiinngg.javaeye.com/blog/154258</a>&nbsp;
          发表时间: 2008年01月09日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p style="background: white"><strong><span style="font-weight: normal; font-size: 10.5pt; font-family: 宋体">JDK</span></strong><strong><span style="font-weight: normal; font-size: 10.5pt; font-family: 宋体">中提供了一些对无状态协议请求（<span>HTTP</span>）的支持，下面我就将我所写的一个小例子（组件）进行描述：</span></strong></p><strong></strong><span style="font-family: Verdana"></span>&nbsp;<strong><span style="font-size: 10.5pt; font-family: 宋体">首先让我们先构建一个请求类（<span>HttpRequester</span>）。</span></strong><span style="font-family: Verdana"></span> <p><span style="font-size: 10.5pt; font-family: 宋体">该类封装了</span><span style="font-size: 10.5pt; font-family: 'Times New Roman'">JAVA</span><span style="font-size: 10.5pt; font-family: 宋体">实现简单请求的代码，如下：</span></p><span style="font-size: 10.5pt; font-family: 宋体"><pre name="code" class="java">import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.Map;
import java.util.Vector;
 
/**
 * HTTP请求对象
 * 
 * @author YYmmiinngg
 */
public class HttpRequester {
	private String defaultContentEncoding;
 
	public HttpRequester() {
		this.defaultContentEncoding = Charset.defaultCharset().name();
	}
 
	/**
	 * 发送GET请求
	 * 
	 * @param urlString
	 *            URL地址
	 * @return 响应对象
	 * @throws IOException
	 */
	public HttpRespons sendGet(String urlString) throws IOException {
		return this.send(urlString, &quot;GET&quot;, null, null);
	}
 
	/**
	 * 发送GET请求
	 * 
	 * @param urlString
	 *            URL地址
	 * @param params
	 *            参数集合
	 * @return 响应对象
	 * @throws IOException
	 */
	public HttpRespons sendGet(String urlString, Map&lt;String, String&gt; params)
			throws IOException {
		return this.send(urlString, &quot;GET&quot;, params, null);
	}
 
	/**
	 * 发送GET请求
	 * 
	 * @param urlString
	 *            URL地址
	 * @param params
	 *            参数集合
	 * @param propertys
	 *            请求属性
	 * @return 响应对象
	 * @throws IOException
	 */
	public HttpRespons sendGet(String urlString, Map&lt;String, String&gt; params,
			Map&lt;String, String&gt; propertys) throws IOException {
		return this.send(urlString, &quot;GET&quot;, params, propertys);
	}
 
	/**
	 * 发送POST请求
	 * 
	 * @param urlString
	 *            URL地址
	 * @return 响应对象
	 * @throws IOException
	 */
	public HttpRespons sendPost(String urlString) throws IOException {
		return this.send(urlString, &quot;POST&quot;, null, null);
	}
 
	/**
	 * 发送POST请求
	 * 
	 * @param urlString
	 *            URL地址
	 * @param params
	 *            参数集合
	 * @return 响应对象
	 * @throws IOException
	 */
	public HttpRespons sendPost(String urlString, Map&lt;String, String&gt; params)
			throws IOException {
		return this.send(urlString, &quot;POST&quot;, params, null);
	}
 
	/**
	 * 发送POST请求
	 * 
	 * @param urlString
	 *            URL地址
	 * @param params
	 *            参数集合
	 * @param propertys
	 *            请求属性
	 * @return 响应对象
	 * @throws IOException
	 */
	public HttpRespons sendPost(String urlString, Map&lt;String, String&gt; params,
			Map&lt;String, String&gt; propertys) throws IOException {
		return this.send(urlString, &quot;POST&quot;, params, propertys);
	}
 
	/**
	 * 发送HTTP请求
	 * 
	 * @param urlString
	 * @return 响映对象
	 * @throws IOException
	 */
	private HttpRespons send(String urlString, String method,
			Map&lt;String, String&gt; parameters, Map&lt;String, String&gt; propertys)
			throws IOException {
		HttpURLConnection urlConnection = null;
 
		if (method.equalsIgnoreCase(&quot;GET&quot;) &amp;&amp; parameters != null) {
			StringBuffer param = new StringBuffer();
			int i = 0;
			for (String key : parameters.keySet()) {
				if (i == 0)
					param.append(&quot;?&quot;);
				else
					param.append(&quot;&amp;&quot;);
				param.append(key).append(&quot;=&quot;).append(parameters.get(key));
				i++;
			}
			urlString += param;
		}
		URL url = new URL(urlString);
		urlConnection = (HttpURLConnection) url.openConnection();
 
		urlConnection.setRequestMethod(method);
		urlConnection.setDoOutput(true);
		urlConnection.setDoInput(true);
		urlConnection.setUseCaches(false);
 
		if (propertys != null)
			for (String key : propertys.keySet()) {
				urlConnection.addRequestProperty(key, propertys.get(key));
			}
 
		if (method.equalsIgnoreCase(&quot;POST&quot;) &amp;&amp; parameters != null) {
			StringBuffer param = new StringBuffer();
			for (String key : parameters.keySet()) {
				param.append(&quot;&amp;&quot;);
				param.append(key).append(&quot;=&quot;).append(parameters.get(key));
			}
			urlConnection.getOutputStream().write(param.toString().getBytes());
			urlConnection.getOutputStream().flush();
			urlConnection.getOutputStream().close();
		}
 
		return this.makeContent(urlString, urlConnection);
	}
 
	/**
	 * 得到响应对象
	 * 
	 * @param urlConnection
	 * @return 响应对象
	 * @throws IOException
	 */
	private HttpRespons makeContent(String urlString,
			HttpURLConnection urlConnection) throws IOException {
		HttpRespons httpResponser = new HttpRespons();
		try {
			InputStream in = urlConnection.getInputStream();
			BufferedReader bufferedReader = new BufferedReader(
					new InputStreamReader(in));
			httpResponser.contentCollection = new Vector&lt;String&gt;();
			StringBuffer temp = new StringBuffer();
			String line = bufferedReader.readLine();
			while (line != null) {
				httpResponser.contentCollection.add(line);
				temp.append(line).append(&quot;\r\n&quot;);
				line = bufferedReader.readLine();
			}
			bufferedReader.close();
 
			String ecod = urlConnection.getContentEncoding();
			if (ecod == null)
				ecod = this.defaultContentEncoding;
 
			httpResponser.urlString = urlString;
 
			httpResponser.defaultPort = urlConnection.getURL().getDefaultPort();
			httpResponser.file = urlConnection.getURL().getFile();
			httpResponser.host = urlConnection.getURL().getHost();
			httpResponser.path = urlConnection.getURL().getPath();
			httpResponser.port = urlConnection.getURL().getPort();
			httpResponser.protocol = urlConnection.getURL().getProtocol();
			httpResponser.query = urlConnection.getURL().getQuery();
			httpResponser.ref = urlConnection.getURL().getRef();
			httpResponser.userInfo = urlConnection.getURL().getUserInfo();
 
			httpResponser.content = new String(temp.toString().getBytes(), ecod);
			httpResponser.contentEncoding = ecod;
			httpResponser.code = urlConnection.getResponseCode();
			httpResponser.message = urlConnection.getResponseMessage();
			httpResponser.contentType = urlConnection.getContentType();
			httpResponser.method = urlConnection.getRequestMethod();
			httpResponser.connectTimeout = urlConnection.getConnectTimeout();
			httpResponser.readTimeout = urlConnection.getReadTimeout();
 
			return httpResponser;
		} catch (IOException e) {
			throw e;
		} finally {
			if (urlConnection != null)
				urlConnection.disconnect();
		}
	}
 
	/**
	 * 默认的响应字符集
	 */
	public String getDefaultContentEncoding() {
		return this.defaultContentEncoding;
	}
 
	/**
	 * 设置默认的响应字符集
	 */
	public void setDefaultContentEncoding(String defaultContentEncoding) {
		this.defaultContentEncoding = defaultContentEncoding;
	}
}
</pre><p>&nbsp;</p><p>&nbsp;</p><strong><span style="font-size: 12pt; font-family: 宋体">其次我们来看看响应对象（<span>HttpRespons</span>）。</span></strong><span style="font-size: 12pt; font-family: 宋体"></span><span style="font-size: 12pt; font-family: 宋体">响应对象其实只是一个数据<span>BEAN</span>，由此来封装请求响应的结果数据，如下：<span></span></span><pre name="code" class="java">import java.util.Vector;
 
/**
 * 响应对象
 */
public class HttpRespons {
 
	String urlString;
 
	int defaultPort;
 
	String file;
 
	String host;
 
	String path;
 
	int port;
 
	String protocol;
 
	String query;
 
	String ref;
 
	String userInfo;
 
	String contentEncoding;
 
	String content;
 
	String contentType;
 
	int code;
 
	String message;
 
	String method;
 
	int connectTimeout;
 
	int readTimeout;
 
	Vector&lt;String&gt; contentCollection;
 
	public String getContent() {
		return content;
	}
 
	public String getContentType() {
		return contentType;
	}
 
	public int getCode() {
		return code;
	}
 
	public String getMessage() {
		return message;
	}
 
	public Vector&lt;String&gt; getContentCollection() {
		return contentCollection;
	}
 
	public String getContentEncoding() {
		return contentEncoding;
	}
 
	public String getMethod() {
		return method;
	}
 
	public int getConnectTimeout() {
		return connectTimeout;
	}
 
	public int getReadTimeout() {
		return readTimeout;
	}
 
	public String getUrlString() {
		return urlString;
	}
 
	public int getDefaultPort() {
		return defaultPort;
	}
 
	public String getFile() {
		return file;
	}
 
	public String getHost() {
		return host;
	}
 
	public String getPath() {
		return path;
	}
 
	public int getPort() {
		return port;
	}
 
	public String getProtocol() {
		return protocol;
	}
 
	public String getQuery() {
		return query;
	}
 
	public String getRef() {
		return ref;
	}
 
	public String getUserInfo() {
		return userInfo;
	}
 
}
</pre><p>&nbsp;</p><p>&nbsp;</p><p class="MsoNormal" align="left" style="background: white; margin: 0cm 0cm 0pt; text-align: left"><strong><span style="font-size: 12pt; font-family: 宋体">最后，让我们写一个应用类，测试以上代码是否正确</span></strong></p><strong><span style="font-size: 12pt; font-family: 宋体"><pre name="code" class="java">import com.yao.http.HttpRequester;
import com.yao.http.HttpRespons;
 
public class Test {
	public static void main(String[] args) {
		try {
			HttpRequester request = new HttpRequester();
			HttpRespons hr = request.sendGet(&quot;http://www.csdn.net&quot;);
 
			System.out.println(hr.getUrlString());
			System.out.println(hr.getProtocol());
			System.out.println(hr.getHost());
			System.out.println(hr.getPort());
			System.out.println(hr.getContentEncoding());
			System.out.println(hr.getMethod());
			
			System.out.println(hr.getContent());
 
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
</pre>&nbsp;</span></strong><span style="font-size: 12pt; font-family: 宋体"></span></span>
          <br/>
          <span style="color:red;">
            <a href="http://yymmiinngg.javaeye.com/blog/154258#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 09 Jan 2008 11:26:58 +0800</pubDate>
        <link>http://yymmiinngg.javaeye.com/blog/154258</link>
        <guid>http://yymmiinngg.javaeye.com/blog/154258</guid>
      </item>
      <item>
        <title>JAVA中使用Htmlparse解析HTML文档</title>
        <author>yymmiinngg</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://yymmiinngg.javaeye.com">yymmiinngg</a>&nbsp;
          链接：<a href="http://yymmiinngg.javaeye.com/blog/154250" style="color:red;">http://yymmiinngg.javaeye.com/blog/154250</a>&nbsp;
          发表时间: 2008年01月09日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <pre name="code" class="java">import java.util.HashMap;
import java.util.Map;
import org.htmlparser.Node;
import org.htmlparser.NodeFilter;
import org.htmlparser.Parser;
import org.htmlparser.tags.LinkTag;
import org.htmlparser.util.NodeList;
import com.yao.http.HttpRequester;
import com.yao.http.HttpRespons;
 
/**
 * JAVA中使用Htmlparse解析HTML文档，使用htmlparse遍历出HTML文档的所有超链接（&lt;a&gt;标记）。
 * 
 * @author YYmmiinngg
 */
public class Test {
	public static void main(String[] args) {
		try {
/* 首先我们先使用HttpRequester类和HttpRespons类获得一个HTTP请求中的数据（HTML文档）。 可以从(http://download.csdn.net/source/321516)中下载htmlloader，该库中有上述类；或从我的《JAVA发送HTTP请求，返回HTTP响应内容，实例及应用》一文中摘取上述两JAVA类的代码。htmlparse可以从(http://download.csdn.net/source/321507)中下载
*/
			Map&lt;String, String&gt; map = new HashMap&lt;String, String&gt;();
			HttpRequester request = new HttpRequester();
			HttpRespons hr = request.sendGet(&quot;http://www.baidu.com&quot;);
 
			Parser parser = Parser.createParser(hr.getContent(), hr
					.getContentEncoding());
			try {
				// 通过过滤器过滤出&lt;A&gt;标签
				NodeList nodeList = parser
						.extractAllNodesThatMatch(new NodeFilter() {
							//实现该方法,用以过滤标签
							public boolean accept(Node node) {
								if (node instanceof LinkTag)//&lt;A&gt;标记
									return true;
								return false;
							}
						});
				// 打印
				for (int i = 0; i &lt; nodeList.size(); i++) {
					LinkTag n = (LinkTag) nodeList.elementAt(i);
					System.out.print(n.getStringText() + &quot; ==&gt;&gt; &quot;);
					System.out.println(n.extractLink());
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
 
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

</pre><p>&nbsp;</p>
          <br/>
          <span style="color:red;">
            <a href="http://yymmiinngg.javaeye.com/blog/154250#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 09 Jan 2008 11:00:55 +0800</pubDate>
        <link>http://yymmiinngg.javaeye.com/blog/154250</link>
        <guid>http://yymmiinngg.javaeye.com/blog/154250</guid>
      </item>
      <item>
        <title>MYSQL数据同步,双向热备</title>
        <author>yymmiinngg</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://yymmiinngg.javaeye.com">yymmiinngg</a>&nbsp;
          链接：<a href="http://yymmiinngg.javaeye.com/blog/153875" style="color:red;">http://yymmiinngg.javaeye.com/blog/153875</a>&nbsp;
          发表时间: 2008年01月08日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>1、简要介绍：mysql从3.23.15版本以后提供数据库复制功能。利用该功能可以实现两个数据库同步，主从模式(A-&gt;B)，互相备份模式(A&lt;=&gt;B)的功能。<br />mysql数据库同步复制功能的设置都在mysql的配置文件中体现。在linux环境下的配置文件一般在/etc/mysql/my.cnf或者在mysql用户的home目录下的my.cnf，笔者的my.cnf则在/etc/my.cnf；windows环境下则可到mysql安装路径下找到my.ini。</p><p>&nbsp;</p><p>2、下面我们来看看如何配置数据同步(A-&gt;B)：<br />(笔者mysql版本 5.0.26)<br />假设数据库A为主机（将向B提供同步服务，即B中的数据来自A）：<br />A机器：<br />IP = 192.168.1.101<br />B机器：<br />IP = 192.168.1.102</p><p>&nbsp;</p><p>(1).在A机器中有数据库如下：</p><p>//数据库A<br /><span style="background-color: #99ccff">CREATE DATABASE backup_db;<br />USE backup_db;<br />CREATE TABLE `backup_table` (<br />&nbsp; `id` int(11) NOT NULL auto_increment,<br />&nbsp; `name` varchar(20) character set utf8 NOT NULL,<br />&nbsp; `sex` varchar(2) character set utf8 NOT NULL,<br />&nbsp; PRIMARY KEY&nbsp; (`id`)<br />) ENGINE=InnoDB DEFAULT CHARSET=latin1;</span></p><p>#A机器的my.cnf(或my.ini)中应该配置：<br /><span style="color: #000000; background-color: #99ccff">server-id=1<br />log-bin=c:\mysqlback #同步事件的日志记录文件<br />binlog-do-db=backup_db #提供数据同步服务的数据库</span></p><p>&nbsp;</p><p>(2).在B机器中有数据库如下：</p><p>//数据库B<br /><span style="background-color: #99ccff">CREATE DATABASE backup_db;<br />USE backup_db;<br />CREATE TABLE `backup_table` (<br />&nbsp; `id` int(11) NOT NULL auto_increment,<br />&nbsp; `name` varchar(20) character set utf8 NOT NULL,<br />&nbsp; `sex` varchar(2) character set utf8 NOT NULL,<br />&nbsp; PRIMARY KEY&nbsp; (`id`)<br />) ENGINE=InnoDB DEFAULT CHARSET=latin1;</span><br />注：数据库A和B的数据库结构一定要相同，否则无法构成同步。</p><p>#B机器的my.cnf(或my.ini)中应该配置：<br /><span style="background-color: #99ccff">server-id=2<br />master-host=192.168.1.101 #主机A的地址<br />master-user=ym #主机A提供给B的用户，该用户中需要包括数据库backup_db的权限<br />master-password=ym #访问密码<br />master-port=3306 #端口，主机的MYSQL端口<br />master-connect-retry=60 #重试间隔60秒<br />replicate-do-db=backup_db #同步的数据库</span></p><p>&nbsp;</p><p>(3).完成了以上配置之后，将A的mysql数据的权限给B。<br />A机器：<br /><span style="color: #ffffff; background-color: #000000">mysql&gt;GRANT FILE ON *.* TO </span><a href="mailto:ym@'192.168.1.102'"><span style="color: #ffffff; background-color: #000000">ym@'192.168.1.102'</span></a><span style="color: #ffffff; background-color: #000000"> IDENTIFIEDBY &lsquo;ym&rsquo;;</span></p><p>&nbsp;</p><p>(4).重启AB数据库，后：<br />B机器：<br /><span style="color: #ffffff; background-color: #000000">mysql&gt;slave start;</span></p><p>查看同步配置情况<br />A机器：<br /><span style="color: #ffffff; background-color: #000000">mysql&gt;show master status;</span><br />B机器：<br /><span style="color: #ffffff; background-color: #000000">mysql&gt;show slave status;</span></p><p>&nbsp;</p><p>(5).在A中的backup_db.backup_table表中插入一些数据，查看B中的backup_db.backup_table表是否同步了数据改动。如果没有看到同步数据结果，即同步不成功，请查看错误（如下）。<br />当有错误产生时*.err日志文件（可到mysql安装目录下找），同步的线程退出。当纠正错误后重复步骤(4)。</p><p>&nbsp;</p><p>3、实现双向热备(A&lt;=&gt;B)：<br />将以上的(1)-(5)步骤按A-B双向配置即可。</p><p>&nbsp;</p>
          <br/>
          <span style="color:red;">
            <a href="http://yymmiinngg.javaeye.com/blog/153875#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 08 Jan 2008 10:53:09 +0800</pubDate>
        <link>http://yymmiinngg.javaeye.com/blog/153875</link>
        <guid>http://yymmiinngg.javaeye.com/blog/153875</guid>
      </item>
      <item>
        <title>第四章、ruby之Hello word</title>
        <author>yymmiinngg</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://yymmiinngg.javaeye.com">yymmiinngg</a>&nbsp;
          链接：<a href="http://yymmiinngg.javaeye.com/blog/153172" style="color:red;">http://yymmiinngg.javaeye.com/blog/153172</a>&nbsp;
          发表时间: 2008年01月04日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>下面就从我们非常熟悉的&ldquo;Hello word&rdquo;入手，来学习简单的ruby语言应用。 </p><p>我们约定在windows xp操作系统平台下，使用命令行方式创建并运行ruby程序</p><p><strong>一、Hello word</strong>&nbsp;</p><p>打开命令窗口(&ldquo;开始&rdquo;-&gt;&ldquo;运行&rdquo;)： </p><p><span style="color: #ffffff; background-color: #000000">cmd&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p><p>&nbsp;</p><p>将当前目录定位在C盘(XXXX表示不确定当前目录) ：</p><p><span style="color: #ffffff; background-color: #000000">xxxx&gt;c:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />xxxx&gt;cd \&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></p><p>&nbsp;</p><p>输入编辑命令： </p><p><span style="color: #ffffff; background-color: #000000">C:\&gt;edit hello.rb&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&nbsp;</p><p>　将打开原始的文本编辑器</p><p>&nbsp;</p><p>输入如下语句</p><pre name="code" class="ruby">puts &quot;Hello word!&quot;</pre><p>&nbsp;</p><p>快捷键： &quot;Alt + F + X&quot;-&gt;选择保存退出&quot;Y&quot; </p><p><span style="color: #ffffff; background-color: #000000">C:\&gt;ruby hello.rb&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p><p>我们将看到结果： </p><p><span style="color: #ffffff; background-color: #000000">Hello word!&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span> </p><p>这样我们就完成了第一个ruby程序，也是最简单的&ldquo;Hello word&rdquo;程序！</p><p>&nbsp;</p><p><strong>二、puts与p的区别</strong></p><p>以上就是用ruby写的&ldquo;Hello word&rdquo;，&ldquo;puts&rdquo;是ruby向控制台打印文字的内置函数，将向用户输出字符定界符（&gt;&quot;&lt;或&gt;'&lt;）内的字符串（或表达式）内容。简单吧！</p><p><br />下面我们再打开hello.rb，这次我们用&quot;notepad&quot;吧：<br /><span style="color: #ffffff; background-color: #000000">C:\&gt;notepad c:\hello.rb<br /></span>将程序改为：</p><pre name="code" class="ruby">puts &quot;Hello word!&quot;
p &quot;Hello word!&quot;</pre><p><br />注：在ruby中程序代码结束可以是换行符和&ldquo;;&rdquo;<br />以上代码也可写成</p><pre name="code" class="ruby">puts &quot;Hello word&quot; ; p &quot;Hello word&quot;</pre><p><br />代码中的&ldquo;p&rdquo;同样是字符串输出语句<br />然后再运行&ldquo;hello.rb&rdquo;<br />这时我们将看到：<br /><span style="color: #ffffff; background-color: #000000">Hello word!&nbsp;&nbsp; <br />&quot;Hello word!&quot;</span></p><p><span style="color: #ffffff; background-color: #000000"><br /></span>同样是向控制台输出字符串，但结果有不同<br />这是因为在ruby中，&ldquo;puts&rdquo;是用来正常的向控制台输出结果串，&ldquo;p&rdquo;用作调试期间的输出命令，将结果串用&gt;&quot;&lt;括起来，并且将&gt;&quot;&lt;转成转义码&quot;\&quot;&quot;。<br />从运行以下代码可以看出：</p><pre name="code" class="ruby">puts &quot;\&quot;Hello word!\&quot;&quot; 
p &quot;\&quot;Hello word!\&quot;&quot; </pre><p>&nbsp;结果是：<br /><span style="color: #ffffff; background-color: #000000">&quot;Hello word!&quot;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />&quot;\&quot;Hello word!\&quot;&quot;&nbsp;&nbsp;&nbsp;</span></p><p>&nbsp;</p><p>三、使用&gt;&quot;&lt;与&gt;'&lt;的区别</p><p>下面我们来看看这段代码：</p><pre name="code" class="ruby">@a = &quot;YYmmiinngg&quot;
puts &quot;Hello #@a!&quot;
puts 'Hello #@a!'</pre><p><br />输出：<br /><span style="color: #ffffff; background-color: #000000">Hello YYmmiinngg!<br />Hello </span><a href="mailto:#@a"><span style="color: #ffffff; background-color: #000000">#@a</span></a><span style="color: #ffffff; background-color: #000000">!&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br /></span>注：@a是一个变量(有关变量的描述请参看后续章节，此处不多加解释！)<br />为什么第一行与第二行的输出又不同呢？原因是：在ruby中使用&gt;&quot;&lt;括起来的字符串中的&quot;<a href="mailto:#@XX">#@XX</a>&quot;将会解析成替换<a href="mailto:&ldquo;@XX">&ldquo;@XX</a>&rdquo;变量，而&gt;'&lt;将原样输出内容。</p><p>&nbsp;</p>
          <br/>
          <span style="color:red;">
            <a href="http://yymmiinngg.javaeye.com/blog/153172#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 04 Jan 2008 17:46:53 +0800</pubDate>
        <link>http://yymmiinngg.javaeye.com/blog/153172</link>
        <guid>http://yymmiinngg.javaeye.com/blog/153172</guid>
      </item>
      <item>
        <title>第三章、ruby命令行参数介绍</title>
        <author>yymmiinngg</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://yymmiinngg.javaeye.com">yymmiinngg</a>&nbsp;
          链接：<a href="http://yymmiinngg.javaeye.com/blog/152900" style="color:red;">http://yymmiinngg.javaeye.com/blog/152900</a>&nbsp;
          发表时间: 2008年01月03日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p><strong>命令行参数</strong> </p><p><br />&ldquo;从命令行开始&rdquo;。不管Ruby用在哪个系统上，无论是超级的科学工作站或者是嵌入式PDA设备，你无论如何都要从Ruby的解释器开始，这会给我们传递命令行参数的机会。</p><p>Ruby的命令行由三个部分组成：Ruby解释器选项，可选的要运行程序的名字，和可选的用于那个程序的一组参数。</p><p>ruby [ options ] [ -- ] [ programfile ] [ arguments ]</p><p>Ruby选项是命令行直接跟在第一个单词后面的，它不能用连字号，或特殊标志--(两个连字号)开头。</p><p>如果命令行上未出现文件名，或如果文件名是单个连字号(-)，Ruby从标准输入中读取程序源代码。</p><p>传递给程序本身的参数跟随在程序名字的后面。例如：</p><p>% ruby -w - &quot;Hello World&quot;</p><p>打开警告，从标准输入读取程序，并传递双引号字符串&quot;Hello World&quot;做为参数。</p><p>&nbsp;</p><p><strong>命令行选项</strong> </p><p><br />-0[octal] 0标志(数字零)指定记录的分隔字符(，如果没有数字跟随)。-00指出段落模式：记录由两个连续的缺省记录分隔字符分隔。-0777一次读入整个文件(它像个非法字符)。设置$/。</p><p>-a 当使用-n或-p时的自动分离模式，等价于在每个循环迭代器上执行$F = $_.split。</p><p>-C directory 在运行之前修改工作路径。</p><p>-c 只检查符号，不运行程序。</p><p>-copyright 打印版权信息并退出。</p><p>-d, -debug 设置 $DEBUG 和 $VERBOSE 为 true。这可以用于你的程序的额外追踪。</p><p>-e 'command' 执行做为一行Ruby源码的命令。允许几个-e，在同一程序中命令被视做多行。当-e出现时，如果程序文件被忽略，在-e命令被运行完后中止运行。程序运行时使用-e可访问旧的条件中的范围和正则表达式的行为-整数范围比较当前输入行号，正式表达式匹配$_。</p><p>-F pattern 指定用于split()的缺省输入字段分隔符($;)(影响-a选项)。</p><p>-h, -help 显示一个简短的帮助屏幕。</p><p>-I directories 指定预定义的$LOAD_PATH($:)指令。可以有多个-I选项。每个-I后可有多个用冒号：分隔的指令。在类Unix系统上是分号(;)。</p><p>-i[extension] 以替换形式编辑ARGV文件。ARGV内的每个文件名，你写入到标准输出的任何东西，都将被回储到那个文件的内容中。如果有扩展名的话，备份文件会被保留下来。</p><p>% ruby -pi. bak &ndash;e &quot;gsub(/Perl/, 'Ruby')&quot; *.txt</p><p>-K kcode 指定要使用的编码。当Ruby使用日语时这个选项很有用。Kcode可以是这些当中的一个： e, E for EUC; s, S 对应 SJIS; u, U 对应 UTF-8; or a, A, n, N 对应 ASCII.</p><p>-l 自动进行行尾处理；设置$的值为$/，并且对读入的行自动地进行String#chop!处理。</p><p>-n Assumes a while gets; ...; end loop around your program. For example, a simple grep command could be implemented as</p><p>% ruby &ndash;n &ndash;e &quot;print if /wombat/&quot; *.txt</p><p>-p Places your program code within the loop while gets; ...; print; end.</p><p>% ruby &ndash;p &ndash;e &quot;$_.downcase!&quot; *.txt</p><p>-r library 在运行前请求给出名字的库。</p><p>-S 查看程序文件是否使用了RUBYPATH或PATH环境变量。</p><p>-s Any command-line switches found after the program filename, but before any filename arguments or before a , are removed from ARGV and set to a global variable named for the switch. In the following example, the effect of this would be to set the variable $opt to &quot;electric&quot;.</p><p>% ruby -s prog -opt= electric ./mydata</p><p>-T[level] 设置安全级别，执行不纯度测试(见379页)。设置$SAFE。</p><p>-v, -verbose 设置$VERBOSE为true，打开冗长模式。也打印版本号。在冗长模式中，可打印编译警告。如果命令行上没有指定文件名，则Ruby退出。</p><p>--version 显示Ruby的版本信息并退出。</p><p>-w 打开冗长模式。与-v不同，如果命令行上没有指定文件名则从标准输入读入程序。我们推荐带 &ndash;w 来运行你程序。</p><p>-W level 设置警告的级别。可有一个或两个级别(或者没指定级别)，等价于-w&mdash;给出额外的警告。如果级别为1，运行在标准(缺省)警告级别上。使用-W0则不显示警告(包括使用Kernel.warn的警告)。</p><p>-X directory 在运行前更改工作目录。类似于-c directory 。</p><p>-x [directory] 从#!Ruby行取出文本，如果指定目录的话，并且要修改工作目录。</p><p>-y, -yydebug 在解析器中打开yacc调试器。</p><p>&nbsp;</p><p><strong>ARGV </strong></p><p><br />程序名字后面的任何命令行参数都会对你的程序打开全局数组ARGV。例如，假设test.rb包含了下面程序：</p><p>ARGV.each {|arg| p arg }</p><p>用下同命令行调用它：</p><p>% ruby &ndash;w test.rb &quot;Hello World&quot; a1 1.6180</p><p>会产生如下输出：</p><p>&quot;Hello World&quot;</p><p>&quot;a1&quot;</p><p>&quot;1.6180&quot;</p><p>这是给C程序员准备的&mdash;ARGV[0]是传递给程序的第一个参数，不是程序的名字。当前程序的名字是全局变量$0中的变量。注意ARGV的所有值都是字符串。</p><p>如果你的程序试图从标准输入来读(或使用特殊文件ARGF，它 321页描述)，ARGV内的程序参数将接受文件名，并且Ruby会从这些文件中读入。如果你程序带有混合参数和文件名，确信你在从文件读之前倾空了ARGV数组。</p><p>&nbsp;</p><p><strong>程序中止</strong> </p><p><br />方法Kernel#exit中止你的程序，并向操作系统返回一个状态值。虽然，不像一些语言，exit不立即中止程序。Kernel#exit首先引发一个SystemExit异常，你可以捕获它，然后程序执行一系列清除动作，包括运行所有的注册的at_exit方法和对象的finalizer。参考500页的Kernel#exit描述。</p><p>&nbsp;</p><p><strong>环境变量</strong> </p><p><br />你可以使用预定义的变量ENV来访问操作系统环境变量。它像哈希表一样响应一些方法。[ENV其实不是哈希表，但如果你需要的话，你可以使用ENV#to_hash，来把它转换到成哈希表]。</p><p>ENV['SHELL'] =&gt; &quot;/bin/sh&quot;</p><p>ENV['HOME'] =&gt; &quot;/Users/dave&quot;</p><p>ENV['USER'] =&gt; &quot;dave&quot;</p><p>ENV.keys.size =&gt; 34</p><p>ENV.keys[0, 7] =&gt; [&quot;MANPATH&quot;, &quot;TERM_PROGRAM&quot;, &quot;TERM&quot;, &quot;SHELL&quot;,</p><p>&quot;SAVEHIST&quot;, &quot;HISTSIZE&quot;, &quot;MAKEFLAGS&quot;]</p><p>当Ruby首次启动时要读取一些环境变量值。这些变量修改解释程序的行为，像表14.1中显示的。</p><p><br />Table 14.1. Ruby使用的环境变量<br />&nbsp;<br /><strong>变量名称<br />　描述<br /></strong>&nbsp;<br />DLN_LIBRARY_PATH<br />　用于搜索被动态加载的模块的路径。<br />&nbsp;<br />HOME<br />　指向用户的主目录。<br />&nbsp;<br />LOGDIR<br />　Fallback pointer to the user&rsquo;s home directory if $HOME is not set. Used only by Dir.chdir.<br />&nbsp;<br />OPENSSL_CONF<br />　指定OpenSSL的本地配置文件。<br />&nbsp;<br />RUBYLIB<br />　为Ruby程序添加搜索路径($SAFE 必须被设置成)。<br />&nbsp;<br />RUBYLIB_PREFIX (Windows only)<br />　Mangle the RUBYLIB search path by adding this prefix to each component.<br />&nbsp;<br />RUBYOPT<br />　给Ruby添加命令行选项，在命令行选项并解析后进行检查($SAFE 必须设置成0)。<br />&nbsp;<br />RUBYPATH<br />　指定&ndash;S选项，Ruby会搜索路径(缺省值是PATH)。<br />&nbsp;<br />RUBYSHELL<br />　Shell to use when spawning a process under Windows; if not set, will also check SHELL or COMSPEC.<br />&nbsp;<br />RUBY_TCL_DLL<br />　Override default name for TCL shared library or DLL.<br />&nbsp;<br />RUBY_TK_DLL<br />　Override default name for Tk shared library or DLL. Both this and RUBY_TCL_DLL must be set for either to be used.<br />&nbsp;</p><p>&nbsp;</p><p><strong>写入环境变量</strong> </p><p><br />Ruby程序可以对ENV对象进行写操作。在大多数系统上这会修改相应的环境变量的值。虽然，这种修改是本地的，只针对于这个进程或其随后的子进程。环境变量的种继承在下面例子中说明。一个子进程若修改了一个环境变量，这个修改会被一个进程继承然后启动。尽管修改对原有的父进程不可见。(这只是证明了它的父进程并不真的知道子进程再做什么。)</p><p>puts &quot;In parent, term = #{ENV['TERM']}&quot;</p><p>fork do</p><p>puts &quot;Start of child 1, term = #{ENV['TERM']}&quot;</p><p>ENV['TERM'] = &quot;ansi&quot;</p><p>fork do</p><p>puts &quot;Start of child 2, term = #{ENV['TERM']}&quot;</p><p>end</p><p>Process.wait</p><p>puts &quot;End of child 1, term = #{ENV['TERM']}&quot;</p><p>end</p><p>Process.wait</p><p>puts &quot;Back in parent, term = #{ENV['TERM']}&quot;</p><p>produces:</p><p>In parent, term = xtermcolor</p><p>Start of child 1, term = xtermcolor</p><p>Start of child 2, term = ansi</p><p>End of child 1, term = ansi</p><p>Back in parent, term = xtermcolor</p><p>&nbsp;</p><p><strong>Ruby在哪里找到它的模块</strong> </p><p><br />你使用require或load来使库模块添加到你的Ruby程序内。这些模块中一些应用于Ruby，一些你可以安装Ruby的应用程序文档(RAA),一些是你自己写。Ruby是如何找到它们呢？</p><p>当Ruby构建你的特殊机器时，它会预先确定持有库资料的标准目录。这些依赖于机器。你可以像这样在命令行中确定它们</p><p>% ruby &ndash;e 'puts $:'</p><p>在典型的Linux box 上，你或许会找到一些如下面显示的。注意Ruby1.8中，这些目录的次序已被修改&mdash;下面目录依赖于它们的机器。</p><p>/usr/local/lib/ruby/site_ruby/1.8</p><p>/usr/local/lib/ruby/site_ruby/1.8/i686linux</p><p>/usr/local/lib/ruby/site_ruby</p><p>/usr/local/lib/ruby/1.8</p><p>/usr/local/lib/ruby/1.8/i686linux</p><p>site_ruby目录持有模块和你添加扩展的模块。依赖于系统的目录(本例中是i686-linux)持有可运行的和其它指定给此机器的。所有这些目录被自动地包含在Ruby对模块的搜索路径内。<br /><br />源文出处：<a href="http://www.rorchina.net/?viewnews-933.htm" target="_blank"><span style="color: #0000ff">http://www.rorchina.net/?viewnews-933.htm</span></a></p>
          <br/>
          <span style="color:red;">
            <a href="http://yymmiinngg.javaeye.com/blog/152900#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 03 Jan 2008 18:08:03 +0800</pubDate>
        <link>http://yymmiinngg.javaeye.com/blog/152900</link>
        <guid>http://yymmiinngg.javaeye.com/blog/152900</guid>
      </item>
      <item>
        <title>第二章、ruby安装</title>
        <author>yymmiinngg</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://yymmiinngg.javaeye.com">yymmiinngg</a>&nbsp;
          链接：<a href="http://yymmiinngg.javaeye.com/blog/152893" style="color:red;">http://yymmiinngg.javaeye.com/blog/152893</a>&nbsp;
          发表时间: 2008年01月03日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <div><span style="background-color: #ffffff">window下的安装方法就不多说了，很简单，下载exe安装文件，根据提示单击安装即可。<br /><br /></span></div><div><span style="background-color: #ffffff">以下是linux下安装ruby的方式：&nbsp;</span></div><div><span style="background-color: #ffffff">1、下载ruby安装包（地址：<a href="http://www.ruby-lang.org/en/downloads/" target="_blank"><span style="color: #0000ff"><span style="color: #0000ff">http://www.ruby-lang.org/en/downloads/</span></span></a>）&nbsp;</span></div><div><span style="background-color: #ffffff">2、解压安装包：</span></div><div><span style="background-color: #ffffff">　tar xzvf ruby-1.8.5.tar.gz<br />　cd ruby-1.8.5</span></div><div><span style="background-color: #ffffff">3、配置&amp;安装<br />　./configure &ndash;prefix=/usr/local/ruby<br />　make &amp;&amp; make install<br /></span></div><div><span style="background-color: #ffffff">如果想浏览所有的configure参数，可以：<br />　./configure &ndash;help |more<br /></span></div><div><span style="background-color: #ffffff">如果不定制安装的目录，默认将安装到/usr/local目录下面。然而我建议自行定制一个ruby的安装目录，例如/usr/local/ruby，这样便于以后的升级，不会和操作系统其他软件混在一起。</span></div><div><span style="background-color: #ffffff">安装好以后，修改操作系统PATH路径，加入/usr/local/ruby/bin：<br />export PATH=/usr/local/ruby/bin:$PATH<br />将我们自己安装的ruby放在系统PATH前面，避免操作系统自带的ruby造成的干扰。在Linux上，一般将设置放在/etc/profile中，便于对全局生效。</span></div><div>有关ruby on rails以及其它支持的安装方法请访问：<a href="http://www.javaeye.com/topic/43228" title="robbin的blog:　http://www.javaeye.com/topic/43228" target="_blank"><span style="color: #0000ff"><span style="color: #0000ff">http://www.javaeye.com/topic/43228</span></span></a></div>
          <br/>
          <span style="color:red;">
            <a href="http://yymmiinngg.javaeye.com/blog/152893#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 03 Jan 2008 17:50:52 +0800</pubDate>
        <link>http://yymmiinngg.javaeye.com/blog/152893</link>
        <guid>http://yymmiinngg.javaeye.com/blog/152893</guid>
      </item>
      <item>
        <title>第一章、ruby简介</title>
        <author>yymmiinngg</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://yymmiinngg.javaeye.com">yymmiinngg</a>&nbsp;
          链接：<a href="http://yymmiinngg.javaeye.com/blog/152866" style="color:red;">http://yymmiinngg.javaeye.com/blog/152866</a>&nbsp;
          发表时间: 2008年01月03日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>Ruby是一种简单的面向对象编程语言，十分容易上手，并且功能强大。她是一个日本的Yukihiro Matsumoto（大家都叫他Matz.）在1995年首次发布的。Ruby从Perl语言那里借鉴了许多东西（有人形象地说Ruby是Perl的漂亮的妹妹：），和Perl相似，Ruby也擅长于文本处理、系统管理等任务。&nbsp;</p><p>Ruby是面向对象的编程语言，她追求的是&ldquo;简便快捷的面向对象编程&rdquo;。Ruby是解释型语言，因此不需编译即可快捷地编程。同时Ruby具有类似Perl的强大的文本处理功能，她可并不只是个玩具，您可以用她来进行实用的编程。此外，您还可以很方便地使用C语言来扩展Ruby的功能，因此可以把她当作各种库的前端来使用。</p><p>若您曾经&ldquo;想要一种简单的面向对象的语言&rdquo;，或者认为&ldquo;Perl的功能虽然好用，但它的语法真让人受不了&rdquo;，又或者觉得&ldquo;lisp系列语言的思想不错，但到处都是括号真让人讨厌，最起码算式应该按照通常的样式书写&rdquo;。那么，Ruby或许能让您满意。</p><p>&nbsp;</p><p>ruby作者简介：</p><p>Matz是一个专业的软件工程师，在日本有名的opensource公司netlab.JP工作，而且他在日本也是一个高姿态的opensource布道者。他参与了几个开源软件项目，包括cmail，这是一个基于emacs的邮件用户代理，完全用emacslisp编写。Ruby也是他的第一个在日本以外的国家如此出名的作品。<br />在1993年的时候，有一次他和同事们谈论关于脚本语言（scriptinglanguage）的事情，Matz深深的认识到了脚本语言的强大和可行性，他想也许脚本语言是他的方向。<br />由于Matz很早以前就对面向对象编程很感兴趣，所以他认为面向对象也会适合脚本语言编程。然后，他到网络上去找了一些相关的东西，并且发现了perl5，当时它还没有发布，并且打算支持面向对象的特点，但是Matz发现这并不是他想找的东西，所以他放弃了把perl当作一个面向对象的脚本语言。<br />然后Matz转向了Python。Python是一个解释型的、面向对象语言，但是Matz发现它并不能完全算作&ldquo;脚本&rdquo;语言。Matz认为Python是面向对象和程序化语言（proceduralprogramming）的混合产物。<br />Matz希望的是一种比Perl强大，比Python更面向对象的语言，所以，他打算设计一个全新的自己的语言。Matz的开发从1993年2月24日开始，同年夏天，第一个Ruby语言的HelloWorld程序成功运行，第一个alpha版本在1994年12月发布。<br />直到1996年都是Matz一个人在开发，从这时候开始Ruby社区也渐渐形成，尽管现在大部分的开发还是Matz自己来开发，但很多人都给了Matz有意义的帮助，包括提交bug和patch等。<br />Ruby这个名字意为珍贵的宝石，千万不要认为是什么缩写，比如PERL。当作者开始写ruby的时候，跟一个同事开玩笑说这个项目要以一个宝石的名字命名。那个同事就说&rdquo;ruby&rdquo;，就是一种美丽贵重的宝石的名字。所以作者用了这个名字，并且最后在官方发布版本中，也延续了这个名字。后来，作者发现珍珠（pearl）是六月的诞生石（birthstone，这个我不懂），ruby是七月的诞生石，所以作者相信ruby是perl之后自己语言的一个好的名字。&nbsp;</p><p>&nbsp;</p><p>归纳以来，Ruby有以下优点： <br />◆解释器<br />　Ruby是解释型语言，其程序无需编译即可轻松执行。 <br />◆变量无类型<br />　Ruby的变量没有类型，因此不必为静态的类型匹配而烦恼。相应地，错误检查功能也变弱了。 <br />◆不需要变量声明<br />　所有变量均无需声明即可立即使用。另外，从变量名即可判断出是何种变量（局部变量，全局变量，实例变量）。<br />◆语法简单<br />　语法比较简单，类似Algol系语法。<br />◆不需要内存管理<br />　具有垃圾回收（Garbage Collect，GC）功能，能自动回收不再使用的对象。 <br />◆一切都是对象<br />　Ruby从一开始就被设计成纯粹的面向对象语言，因此以整数等基本数据类型为首的所有东西都是对象，它们都有发送信息的统一接口。 <br />◆类，继承，方法 <br />　Ruby当然具有面向对象语言的基本功能。 <br />◆特殊方法 <br />　可向某对象添加方法。例如，可以把GUI按钮被按下时的动作作为方法记述下来，还可以用它来进行原型库（prototypebase）的面向对象编程（有人这么干吧）。 <br />◆用模块进行混合插入（Mixin） <br />　Ruby故意舍弃了多重继承，但拥有混合插入功能。使用模块来超越类的界限来共享数据和方法等。 </p><p>◆迭代器 <br />　该功能可以将循环抽象化。 <br />◆闭包 <br />　可以将某过程片段对象化。对象化后的该过程片段就称作闭包。 <br />◆功能强大的字符串操作／正则表达式 <br />　以Perl为样板创造出了功能强大的字符串操作和正则表达式检索功能。 <br />◆拥有超长整数 <br />　添加超长整数功能后，可以计算非常大的整数。例如计算400的阶乘也轻而易举。 <br />◆具有错误处理功能 <br />　错误处理功能可以使您编写代码处理出错情况。 <br />◆可以直接访问OS <br />　Ruby可以使用（UNIX的）绝大部分的系统调用。单独使用Ruby也可以进行系统编程。 <br />◆动态加载 <br />　若OS支持的话，可以在运行时读入对象文件。 </p><p>&nbsp;</p><p>但Ruby也有下列缺点：<br />◆因为Ruby是解释型语言，所以速度较慢<br />◆静态检查比较少</p><p>&nbsp;</p>
          <br/>
          <span style="color:red;">
            <a href="http://yymmiinngg.javaeye.com/blog/152866#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 03 Jan 2008 16:56:34 +0800</pubDate>
        <link>http://yymmiinngg.javaeye.com/blog/152866</link>
        <guid>http://yymmiinngg.javaeye.com/blog/152866</guid>
      </item>
  </channel>
</rss>