<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
  <channel>
    <title>Q天空</title>
    <description>热爱技术的人</description>
    <link>http://qsky.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>Unable to connect to any hosts due to exception </title>
        <author>qsky</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://qsky.javaeye.com">qsky</a>&nbsp;
          链接：<a href="http://qsky.javaeye.com/blog/188324" style="color:red;">http://qsky.javaeye.com/blog/188324</a>&nbsp;
          发表时间: 2008年04月30日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <pre name="code" class="java">java.sql.SQLException: Unable to connect to any hosts due to exception: java.lang.ArrayIndexOutOfBoundsException: 40
at com.mysql.jdbc.Connection.createNewIO(Connection.java:1797)
at com.mysql.jdbc.Connection.&lt;init>(Connection.java:562)
at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:361)
at java.sql.DriverManager.getConnection(DriverManager.java:525)
at java.sql.DriverManager.getConnection(DriverManager.java:171)
at org.apache.commons.dbcp.DriverManagerConnectionFactory.createConnection(DriverManagerConnectionFactory.java:48)
at org.apache.commons.dbcp.PoolableConnectionFactory.makeObject(PoolableConnectionFactory.java:290)
at org.apache.commons.pool.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:771)
at org.apache.commons.dbcp.PoolingDataSource.getConnection(PoolingDataSource.java:95)
at com.community.util.ConnectionPool.getConnection(ConnectionPool.java:56)
at com.community.manager.ModelManager.getConnection(ModelManager.java:16)
at com.community.manager.MovieManager.main(MovieManager.java:48)</pre><br /><br />链接mysql的时候发现，数据库名称跟这个异常直接相关，<br /><br />1 数据库名称里不能包含下划线等特殊字符。<br /><br />2 数据库名称不能太长。<br /><br />3 如果正常的数据库名称也出现这种问题，偶的解决方法是重装mysql,换数据库名称。<br /><br /><strong>最主要的原因是：java的mysql驱动jar和当前的mysql版本不兼容造成的，稳定版是 mysql-connector-java-5.0.3.jar</strong>
          <br/>
          <span style="color:red;">
            <a href="http://qsky.javaeye.com/blog/188324#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, 30 Apr 2008 10:56:23 +0800</pubDate>
        <link>http://qsky.javaeye.com/blog/188324</link>
        <guid>http://qsky.javaeye.com/blog/188324</guid>
      </item>
      <item>
        <title>window+lighttpd+php 配置经验简谈</title>
        <author>qsky</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://qsky.javaeye.com">qsky</a>&nbsp;
          链接：<a href="http://qsky.javaeye.com/blog/186705" style="color:red;">http://qsky.javaeye.com/blog/186705</a>&nbsp;
          发表时间: 2008年04月25日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          网上找了很多资料，但都不是很全，这里汇总一下<br />准备工作：<br />1 从 lighttpd 的官方网下载window版的exe安装版<br />2 php 的可以是 window下的安装版或解压版都可以<br /><br />安装步骤：<br />1 安装lighttpd，安装到指定目录下比如C:\Server\lighttp1.4.19-1\，本人装的LightTPD-1.4.19-1-Win32-SSL.exe<br />2 解压或安装php到指定目录下，比如C:/Server/php5/<br /><br />接下来就是配置了<br />第一步把 C:\Server\lighttp1.4.19-1\conf\lighttpd-inc.conf打开<br />把cgi的modules放开<br />server.modules              = (<br />                                "mod_access",<br />                                "mod_accesslog",<br />                                "mod_alias",<br />#                               "mod_auth",<br />                               "mod_cgi",<br />#                               "mod_cml",<br />#                               "mod_compress",<br />#                               "mod_dirlisting",<br />#                               "mod_evasive",<br />#                               "mod_evhost",<br />#                               "mod_expire",<br />#                               "mod_extforward",<br />                               "mod_fastcgi",<br />#                               "mod_flv_streaming",<br />#                               "mod_indexfile",<br />#                               "mod_magnet",<br />#                               "mod_mysql_vhost",<br />#                               "mod_proxy",<br />#                               "mod_redirect",<br />#                               "mod_rewrite",<br />##                              "mod_rrdtool",<br />                               "mod_scgi",<br />#                               "mod_secdownload",<br />#                               "mod_setenv",<br />#                               "mod_simple_vhost",<br />                                "mod_ssi",<br />#                               "mod_staticfile",<br />                                "mod_status",<br />##                              "mod_trigger_b4_dl",<br />#                               "mod_userdir",<br />#                               "mod_usertrack",<br />#                               "mod_webdav"<br />                               )<br /><br /><br />#修改这里<br />cgi.assign                  = ( ".php" => "C:/Server/php5/php-cgi.exe" )<br /><br />lighttpd的配置先到这里，接下来看看php的配置<br /><br />php的主要是php.ini文件的配置，它是是否配置成功的关键<br />cgi.force_redirect = 1<br />cgi.fix_pathinfo=1<br />这两个把前面的分号去掉<br /><br />找到doc_root= 前面加;号<br />;extension=php_sockets.dll 把分号去掉，其他的dll根据需要去掉分号即可<br /><br />注：到此为止貌似已经配置完成了，但发现lighttpd的默认虚拟目录是HTDOCS/<br />这种情况下测试php程序是行不通的，这个可能是个lighttpd的win下的bug吧<br />所以把虚拟路径改变一下，最好不在安装目录下，比如：server.document-root        = "D:/phpv"<br /><br />好了 到此为止配置已完成，<br />启动lighttpd 运行C:\Server\lighttp1.4.19-1\bin\Service-Install.exe<br />(停止是Service-Remove.exe)或C:\Server\lighttp1.4.19-1\TestMode.bat<br />可以了<br />我们在D:/phpv 下建立一个test.php <br />写入&lt;? phpinfo(); ?>.<br />访问 http://1270.0.1/test.php<br />看到php信息页面就是配置成功了
          <br/>
          <span style="color:red;">
            <a href="http://qsky.javaeye.com/blog/186705#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 12:49:24 +0800</pubDate>
        <link>http://qsky.javaeye.com/blog/186705</link>
        <guid>http://qsky.javaeye.com/blog/186705</guid>
      </item>
      <item>
        <title>Share methods in Controller and Helper (Rails)</title>
        <author>qsky</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://qsky.javaeye.com">qsky</a>&nbsp;
          链接：<a href="http://qsky.javaeye.com/blog/185827" style="color:red;">http://qsky.javaeye.com/blog/185827</a>&nbsp;
          发表时间: 2008年04月23日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          在Ruby on Rails里面，首先应该明确的一点 —– Helper是view的helper，根据这个原则，在默认实现下，controller是不允许访问helper里面的方法的。当然helper在本质上是一个module，所以要在controller和helper之间共享一些方法的办法还是很多的。因为是双方都拥有的方法，所以就面临一个问题 —— 方法放在那里比较合理？controller还是helper？我阐述一下我的原则：<br /><br />如果方法中需要引入其他helper方法，那么我们建议该方法放在helper中；否则，可以放在controller中或者写一个公共module。放在controller里面需要注意安全性，因为controller里面public的方法很有可能通过URL加以执行，所以我们建议所有的helper 方法都用private 加以约束。<br /><br />下面我就详细说一下4中方法。<br /><br />Helper方法放在controller中，通过ApplicationHelper来实现公用。代码存在一定的安全隐患。 <br /><br /><pre name="code" class="java">module ApplicationHelper
  def method_missing(method, *args, &block)
    if ApplicationController.instance_methods.include? method.to_s
      controller.send(method, *args, &block)
    else
      super
    end
  end
end </pre><br /><br />Helper方法放在controller中，通过helper_method来实现公用。代码安全。 <br />private<br /><br /><pre name="code" class="java">heper_method :login?
def login?
  # your logic goes here
end </pre><br /><br />Helper方法放在Helper中，通过include module_name向controller暴露，代码安全 <br />include FullModuleName <br /><br />Helper方法放在一个独立的module中，helper和controller通过include这个module来获得公共方法。 <br />include CommonModuleName <br /><br />关于include module需要注意的是，它不会帮助你去自动解决module依赖性的问题。
          <br/>
          <span style="color:red;">
            <a href="http://qsky.javaeye.com/blog/185827#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, 23 Apr 2008 11:38:46 +0800</pubDate>
        <link>http://qsky.javaeye.com/blog/185827</link>
        <guid>http://qsky.javaeye.com/blog/185827</guid>
      </item>
      <item>
        <title>ruby 四舍五入的函数</title>
        <author>qsky</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://qsky.javaeye.com">qsky</a>&nbsp;
          链接：<a href="http://qsky.javaeye.com/blog/184986" style="color:red;">http://qsky.javaeye.com/blog/184986</a>&nbsp;
          发表时间: 2008年04月21日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <pre name="code" class="java">
#i 原始数 n 要保留的小数位数，flag=1 四舍五入 flag=0 不四舍五入
def f(i,n,flag)
  y = 1
  n.times do |x|
  	y = y*10
  end
  if flag==1
   (i*y).round/(y*1.0)
  else
  (i*y).floor/(y*1.0)
  end
end
</pre>
          <br/>
          <span style="color:red;">
            <a href="http://qsky.javaeye.com/blog/184986#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>Mon, 21 Apr 2008 15:31:17 +0800</pubDate>
        <link>http://qsky.javaeye.com/blog/184986</link>
        <guid>http://qsky.javaeye.com/blog/184986</guid>
      </item>
      <item>
        <title>中文相对时间 rails</title>
        <author>qsky</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://qsky.javaeye.com">qsky</a>&nbsp;
          链接：<a href="http://qsky.javaeye.com/blog/171265" style="color:red;">http://qsky.javaeye.com/blog/171265</a>&nbsp;
          发表时间: 2008年03月14日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          中文相对时间<br /><br />http://galeki.is-programmer.com/category/17<br /><br />挺不错，这类资料也不多，在这里转一下
          <br/>
          <span style="color:red;">
            <a href="http://qsky.javaeye.com/blog/171265#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, 14 Mar 2008 11:12:55 +0800</pubDate>
        <link>http://qsky.javaeye.com/blog/171265</link>
        <guid>http://qsky.javaeye.com/blog/171265</guid>
      </item>
      <item>
        <title>rials 出现 《您的主机中的软件放弃了一个已建立》</title>
        <author>qsky</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://qsky.javaeye.com">qsky</a>&nbsp;
          链接：<a href="http://qsky.javaeye.com/blog/160452" style="color:red;">http://qsky.javaeye.com/blog/160452</a>&nbsp;
          发表时间: 2008年01月30日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          整个错误如下<br /><pre name="code" class="java">
Wed Jan 30 15:16:57 +0800 2008: Read error: #&lt;Errno::ECONNABORTED: 您的主机中的软件放弃了一个已建立
的连接。>
d:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.1.3-x86-mswin32/lib/mongrel/http_response.rb:137:in `write'

d:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.1.3-x86-mswin32/lib/mongrel/http_response.rb:137:in `write'

d:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.1.3-x86-mswin32/lib/mongrel/http_response.rb:95:in `send_he
ader'
d:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.1.3-x86-mswin32/lib/mongrel/http_response.rb:146:in `finish
ed'
d:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.1.3-x86-mswin32/lib/mongrel.rb:165:in `process_client'
d:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.1.3-x86-mswin32/lib/mongrel.rb:285:in `run'
d:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.1.3-x86-mswin32/lib/mongrel.rb:285:in `initialize'
d:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.1.3-x86-mswin32/lib/mongrel.rb:285:in `new'
d:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.1.3-x86-mswin32/lib/mongrel.rb:285:in `run'
d:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.1.3-x86-mswin32/lib/mongrel.rb:268:in `initialize'
d:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.1.3-x86-mswin32/lib/mongrel.rb:268:in `new'
d:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.1.3-x86-mswin32/lib/mongrel.rb:268:in `run'
d:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.1.3-x86-mswin32/lib/mongrel/configurator.rb:282:in `run'
d:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.1.3-x86-mswin32/lib/mongrel/configurator.rb:281:in `each'
d:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.1.3-x86-mswin32/lib/mongrel/configurator.rb:281:in `run'
d:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.1.3-x86-mswin32/bin/mongrel_rails:128:in `run'
d:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.1.3-x86-mswin32/lib/mongrel/command.rb:212:in `run'
d:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.1.3-x86-mswin32/bin/mongrel_rails:281
d:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:489:in `load'
d:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:489:in `load'
d:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:342:in `new_co
nstants_in'
d:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:489:in `load'
d:/ruby/lib/ruby/gems/1.8/gems/rails-2.0.2/lib/commands/servers/mongrel.rb:64
d:/ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in `gem_original_require'
d:/ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in `require'
d:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:496:in `requir
e'
d:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:342:in `new_co
nstants_in'
d:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:496:in `requir
e'
d:/ruby/lib/ruby/gems/1.8/gems/rails-2.0.2/lib/commands/server.rb:39
d:/ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in `gem_original_require'
d:/ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in `require'
</pre><br /><br /><br />读一个url要生成一个静态文件，控制器里写个方法调用下面的方法把url内容拿到 存文件。<br /><pre name="code" class="java">
  def get_url_content url
        #o = open("http://www.baidu.com")
        o = open(url)
        c = o.read(o.size)
        o.close
        c
  end
</pre><br /><br />问题：<br />如果传进来的url地址是本服务器（就是当前服务器）的url，会出现《您的主机中的软件放弃了一个已建立》的错误。<br />如果是别的url例如 http://www.baidu.com 就会没有问题<br /><br />在一个控制器正在调用一个action的时候，不能open本服务器的url <br />难道是rails的bug么？
          <br/>
          <span style="color:red;">
            <a href="http://qsky.javaeye.com/blog/160452#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, 30 Jan 2008 16:20:29 +0800</pubDate>
        <link>http://qsky.javaeye.com/blog/160452</link>
        <guid>http://qsky.javaeye.com/blog/160452</guid>
      </item>
      <item>
        <title>发现了jrockit好用东东</title>
        <author>qsky</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://qsky.javaeye.com">qsky</a>&nbsp;
          链接：<a href="http://qsky.javaeye.com/blog/158127" style="color:red;">http://qsky.javaeye.com/blog/158127</a>&nbsp;
          发表时间: 2008年01月21日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          1. 进入到jrockit/bin目录下<br />2. 打./jrcmd 回车,会看到当前所有在执行中的java进程的PID号<br />3. 打./jrcmd [PID] help 回车,会看到指定java进程支持的操作<br />4. 打./jrcmd [PID] print_threads > xxxFile,可以把当前java进程中的所有线程堆栈轨迹打印到指定文件中<br /><br />引自：高嵩邮件内容
          <br/>
          <span style="color:red;">
            <a href="http://qsky.javaeye.com/blog/158127#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>Mon, 21 Jan 2008 18:14:03 +0800</pubDate>
        <link>http://qsky.javaeye.com/blog/158127</link>
        <guid>http://qsky.javaeye.com/blog/158127</guid>
      </item>
      <item>
        <title>Java语言深入:java匿名内部类的一点讨论</title>
        <author>qsky</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://qsky.javaeye.com">qsky</a>&nbsp;
          链接：<a href="http://qsky.javaeye.com/blog/153493" style="color:red;">http://qsky.javaeye.com/blog/153493</a>&nbsp;
          发表时间: 2008年01月06日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <a href="http://java.ccidnet.com/art/3539/20071225/1320397_1.html" target="_blank">http://java.ccidnet.com/art/3539/20071225/1320397_1.html</a><br />关于JAVA内部类:一个内部类的定义是定义在另一个类内部的类。<br />　　存在它的原因是:<br />　　1.一个内部类的对象能够访问创建它的对象的实现，包括私有数据。即内部类实例对包含它的哪个类的实例来说，是特权的。<br />　　2.对于同一个包中的其他类来说,内部类能够隐藏起来,换句话说，内部类不管方法的可见性如何，那怕是public，除了包容类，其他类都无法使用它。<br />　　3.匿名内部类可以很方便的定义回调。<br />　　4.使用内部类可以非常方便的编写事件驱动程序。<br /><br />其实它真正的目的仅仅为了定义回调－－进一步就是事件驱动。<br />接口和回调：编程一个常用的模式是回调模式,在这种模式中你可以指定当一个特定时间发生时回调对象上的方法。<br />－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－<br /> 注意事项:<br /> <br /> 匿名类和内部类中的中的this :<br /> 有时候，我们会用到一些内部类和匿名类。当在匿名类中用this时，这个this则指的是匿名类或内部类本身。<br /> 这时如果我们要使用外部类的方法和变量的话，则应该加上外部类的类名。如下面这个例子：<br /> <br />public class A {<br />  int i = 1;<br />  public A() {<br />    Thread thread = new Thread() {<br />      public void run() {<br />        for(;;) {<br />          A.this.run();<br />          try {<br />            sleep(1000);<br />          } catch(InterruptedException ie) {<br />          }<br />        }<br />      }<br />    };<br />    thread.start();<br />  } <br />  public void run() {<br />    System.out.println("i = " + i);<br />    i++;<br />  }<br />  public static void main(String[] args) throws Exception {<br />    new A();<br />  }<br />}<br /> <br /> <br />    在上面这个例子中, thread 是一个匿名类对象，在它的定义中，它的 run 函数里用到了外部类的 run 函数。<br />    这时由于函数同名，直接调用就不行了。这时有两种办法，一种就是把外部的 run 函数换一个名字，但这种办法对于一个开发到中途的应用来说是不可取的<br />    。那么就可以用这个例子中的办法用外部类的类名加上 this 引用来说明要调用的是外部类的方法 run。<br />    －－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－<br />   <br />   <br />    对于这个例子：<br /><br />this.test(new Inner(){<br />             public void method1(){<br />                 System.out.print("1111");<br />           }<br />           <br />             public void method2(){<br />                 System.out.print("22222");<br />           }<br />});<br />这个时候调用test()方法，那Inner类的method1和method2是什么时候被调用的？难道也是this对象向他们发消息（比如传入一个参数）吗？还是直接显式的调用？？<br /> <br />对于Inner类，除了this这个类，就是this.test(...那句中的this，它能够调用Inner类的方法，其他地方都不行，然而，这也需要你在类中有个地方保存有对这个内部类实例的引用才可以。再说明一次，内部类是用来在某个时刻调用外面的方法而存在的－－这就是回调。<br />为了说明内部类实例的方法只能在包容类的实例中调用，其他地方无法调用，给个例子如下：<br />JAVA2实用教程源码：<br /> <br /> /** 一个应用程序，用来演示内部类的使用 */<br />/** 类Outer */<br />class Outer{<br />private static int size;<br />/** 内部类Inner的声明 */<br />public class Inner{<br />private int size;<br />/** 方法doStuff() */<br />public void doStuff(int size){<br />size++; //存取局部变量<br />this.size++;  //存取其内部类的成员变量<br />Outer.this.size++; //存取其外部类的成员变量<br />System.out.println(size+" "+this.size+" "+Outer.this.size);<br />}<br />}//内部类Inner结束<br />/** 类Outer中定义的实例方法testInner()方法 */<br />public void testInner(){<br />Inner i=new Inner();<br />i.doStuff(5);<br />}<br />/** main()方法 */<br />public static void main(String[] a){<br />Outer o=new Outer();<br />o.testInner();<br />}<br />}//类Outer结束<br /><br /> <br />－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－<br />那么，如何使用内部类,匿名类实现事件处理呢？<br />JAVA---事件适配器<br /><br /> 1．事件适配器--EventAdapter<br />　　下例中采用了鼠标适配器：<br />　　<br /><br />import java.awt.*;<br />　　import java.awt.event.*;<br />　　public class MouseClickHandler extends MouseAdaper{<br />　　　　public void mouseClicked(MouseEvent e) //只实现需要的方法<br />　　　　　　　{ ……}<br />　　}<br /> <br />　　java.awt.event包中定义的事件适配器类包括以下几个：<br />　　1．ComponentAdapter( 组件适配器)<br />　　2．ContainerAdapter( 容器适配器)<br />　　3．FocusAdapter( 焦点适配器)<br />　　4．KeyAdapter( 键盘适配器)<br />　　5．MouseAdapter( 鼠标适配器)<br />　　6．MouseMotionAdapter( 鼠标运动适配器)<br />　　7．WindowAdapter( 窗口适配器)<br />　2. 用内部类实现事件处理<br />　　内部类（inner class）是被定义于另一个类中的类，使用内部类的主要原因是由于：<br />　　◇ 一个内部类的对象可访问外部类的成员方法和变量，包括私有的成员。<br />　　◇ 实现事件监听器时，采用内部类、匿名类编程非常容易实现其功能。<br />　　◇ 编写事件驱动程序，内部类很方便。　　<br />　　因此内部类所能够应用的地方往往是在AWT的事件处理机制中。<br />例5.11<br />　　　<br />import java.awt.* ;<br />　　　import java.awt.event.*；<br />　　　　　public class InnerClass{<br />　　　　　　　private Frame f;<br />　　　　　　　private TextField tf;<br />　　　　　　　public InnerClass(){<br />　　　　　　　f=new Frame("Inner classes example");<br />　　　　　　　tf=new TextField(30);<br />　　　　　}<br />　　　　　public voidi launchFrame(){<br />　　　　　　　Label label=new Label("Click and drag the mouse");<br />　　　　　　　f.add(label,BorderLayout.NORTH);<br />　　　　　　　f.add(tf,BorderLayout.SOUTH);<br />　　　　　　　f.addMouseMotionListener(new MyMouseMotionListener());/*参数为内部类对象*/<br />　　　　　　　f.setSize(300,200);<br />　　　　　　　f.setVisible(true);<br />　　　　　}<br />　　　　　class MyMouseMotionListener extends MouseMotionAdapter{ /*内部类开始*/<br />　　　　　　　public void mouseDragged(MouseEvent e) {<br />　　　　　　　　　String s="Mouse dragging: x="+e.getX()+"Y="+e.getY();<br />　　　　　　　　　tf.setText(s); }<br />　　　　　　　} ;<br />　　　　　　　public static void main(String args[]) {<br />　　　　　　　　　InnerClass obj=new InnerClass();<br />　　　　　　　　　obj.launchFrame();<br />　　　　　　　}<br />　　　　　}//内部类结束<br />　　　　}<br /> <br /> <br />　3．匿名类（Anonymous Class）<br />　　当一个内部类的类声名只是在创建此类对象时用了一次，而且要产生的新类需继承于一个已有的父类或实现一个接口，才能考虑用匿名类，由于匿名类本身无名，因此它也就不存在构造方法，它需要显示地调用一个无参的父<br />类的构造方法，并且重写父类的方法。所谓的匿名就是该类连名字都没有，只是显示地调用一个无参的父类的构造方法。<br />例5.12<br />　　　<br /><br />import java.awt.* ;<br />　　　import java.awt.event.*;<br />　　　　public class AnonymousClass{<br />　　　　　private Frame f;<br />　　　　　private TextField tf;<br />　　　　　public AnonymousClass(){<br />　　　　　　f=new Frame("Inner classes example");<br />　　　　　　tf=new TextField(30);<br />　　　　}<br />　　　　public void launchFrame(){<br />　　　　　　Label label=new Label("Click and drag the mouse");<br />　　　　　　f.add(label,BorderLayout.NORTH);<br />　　　　　　f.add(tf,BorderLayout.SOUTH);<br />　　　　　　f.addMouseMotionListener(new MouseMotionAdapter(){ //匿名类开始<br />　　　　　　　public void mouseDragged(MouseEvent e){<br />　　　　　　　　String s="Mouse dragging: x="+e.getX()+"Y="+e.getY();<br />　　　　　　　　tf.setText(s); }<br />　　　　　　} ); //匿名类结束<br />　　　　　　f.setSize(300,200);<br />　　　　　　f.setVisible(true);<br />　　　　　　}<br />　　　　　　　public static void main(String args[]) {<br />　　　　　　　　AnonymousClass obj=new AnonymousClass();<br />　　　　　　　　obj.launchFrame();<br />　　　　　　　　}<br />　　　　　　}<br /> <br />　　其实仔细分析，例5.11和5.12实现的都是完全一样的功能，只不过采取的方式不同。5.11中的事件处理类是一个内部类，而5.12的事件处理类是匿名类，可以说从类的关系来说是越来越不清楚，但<br />是程序也越来越简练。熟悉这两种方式也十分有助于编写图形界面的程序。<br />亲自在IDE中实践一下，会理解的更深切一点。
          <br/>
          <span style="color:red;">
            <a href="http://qsky.javaeye.com/blog/153493#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>Sun, 06 Jan 2008 16:33:12 +0800</pubDate>
        <link>http://qsky.javaeye.com/blog/153493</link>
        <guid>http://qsky.javaeye.com/blog/153493</guid>
      </item>
      <item>
        <title>对IN &amp; EXISTS NOT IN &amp; NOT EXISTS的优化</title>
        <author>qsky</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://qsky.javaeye.com">qsky</a>&nbsp;
          链接：<a href="http://qsky.javaeye.com/blog/152858" style="color:red;">http://qsky.javaeye.com/blog/152858</a>&nbsp;
          发表时间: 2008年01月03日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          转自http://yaanzy.itpub.net/post/1263/10217 <br />在平时工作中,IN & EXISTS NOT IN & NOT EXISTS是使用频率比较高的SQL语句, <br />所以对它们的优化工作是很有必要的 <br /><br />测试环境：Oracle 9.2.0.1 for Windows2000 <br /><br /><br /><br />1、IN 和 EXISTS <br /><br />IN和EXISTS的处理流程是不一样的： <br /><br />IN的执行流程 <br />select * from T1 where x in ( select y from T2 ) <br />可以理解为: <br />select * from t1, ( select distinct y from t2 ) t2 where t1.x = t2.y; <br /><br />EXISTS的执行流程 <br />select * from t1 where exists ( select null from t2 where y = x ) <br />可以理解为: <br />for x in ( select * from t1 ) <br />loop <br />if ( exists ( select null from t2 where y = x.x ) <br />then <br />OUTPUT THE RECORD <br />end if <br />end loop <br /><br />创建测试用例表big(4000 row)和small(400 row) <br /><br />create table big as select * from dba_objects where rownum &lt;= 10000; <br />insert into big select * from big; <br />insert into big select * from big; <br />commit; <br />create table small as select * from dba_objects where rownum &lt;= 400; <br /><br />当内层表为small,外层表为big时,两种语法的查询如下： <br /><br />SQL> select count(1) from big a where a.object_id in <br />(select b.object_id from sall b); <br /><br />COUNT(1) <br />---------- <br />1600 <br /><br />已用时间: 00: 00: 00.56 <br /><br />Execution Plan <br />----------------------------------------------------- <br />0 SELECT STATEMENT Optimizer=CHOOSE <br />1 0 SORT (AGGREGATE) <br />2 1 MERGE JOIN <br />3 2 SORT (JOIN) <br />4 3 TABLE ACCESS (FULL) OF 'BIG' <br />5 2 SORT (JOIN) <br />6 5 VIEW OF 'VW_NSO_1' <br />7 6 SORT (UNIQUE) <br />8 7 TABLE ACCESS (FULL) OF 'SMALL' <br /><br />Statistics <br />----------------------------------------------------- <br />0 recursive calls <br />0 db block gets <br />543 consistent gets <br />0 physical reads <br /><br />SQL> select count(1) from big a where exists <br />(select 1 from small b where a.object_id=b.object_id); <br /><br />COUNT(1) <br />---------- <br />1600 <br /><br />已用时间: 00: 00: 03.10 <br /><br />Execution Plan <br />----------------------------------------------------- <br />0 SELECT STATEMENT Optimizer=CHOOSE <br />1 0 SORT (AGGREGATE) <br />2 1 FILTER <br />3 2 TABLE ACCESS (FULL) OF 'BIG' <br />4 2 TABLE ACCESS (FULL) OF 'SMALL' <br /><br />Statistics <br />----------------------------------------------------- <br />0 recursive calls <br />0 db block gets <br />312157 consistent gets <br />0 physical reads <br /><br />当内层表为big,外层表为small时,两种语法的查询如下： <br /><br />SQL> select count(1) from small a where a.object_id in <br />(select b.object_id from big b); <br /><br />COUNT(1) <br />---------- <br />400 <br /><br />已用时间: 00: 00: 00.56 <br /><br />Execution Plan <br />----------------------------------------------------- <br />0 SELECT STATEMENT Optimizer=CHOOSE <br />1 0 SORT (AGGREGATE) <br />2 1 MERGE JOIN <br />3 2 SORT (JOIN) <br />4 3 TABLE ACCESS (FULL) OF 'SMALL' <br />5 2 SORT (JOIN) <br />6 5 VIEW OF 'VW_NSO_1' <br />7 6 SORT (UNIQUE) <br />8 7 TABLE ACCESS (FULL) OF 'BIG' <br /><br />Statistics <br />----------------------------------------------------- <br />0 recursive calls <br />0 db block gets <br />543 consistent gets <br />0 physical reads <br /><br />SQL> select count(1) from small a where exists <br />(select null from big b where a.bject_id=b.object_id); <br /><br />COUNT(1) <br />---------- <br />400 <br /><br />已用时间: 00: 00: 00.25 <br /><br />Execution Plan <br />----------------------------------------------------- <br />0 SELECT STATEMENT Optimizer=CHOOSE <br />1 0 SORT (AGGREGATE) <br />2 1 FILTER <br />3 2 TABLE ACCESS (FULL) OF 'SMALL' <br />4 2 TABLE ACCESS (FULL) OF 'BIG' <br /><br />Statistics <br />----------------------------------------------------- <br />0 recursive calls <br />0 db block gets <br />2562 consistent gets <br />0 physical reads <br /><br /><br />在对表big、small进行分析后,发现CBO下两种语法的执行计划是一样的,都使用hash连接或者hash半连接 <br /><br />SQL> analyze table big compute statistics; <br />SQL> analyze table small compute statistics; <br /><br />SQL> select count(1) from big a where a.object_id in <br />(select b.object_id from small b); <br /><br />COUNT(1) <br />---------- <br />1600 <br /><br />已用时间: 00: 00: 00.09 <br /><br />Execution Plan <br />------------------------------------------------------- <br />0 SELECT STATEMENT Optimizer=CHOOSE (Cost=58 <br />Card=1 Bytes=8) <br />1 0 SORT (AGGREGATE) <br />2 1 HASH JOIN (Cost=58 Card=1600 Bytes=12800) <br />3 2 SORT (UNIQUE) <br />4 3 TABLE ACCESS (FULL) OF 'SMALL' (Cost=2 Card=400 Bytes=1600) <br />5 2 TABLE ACCESS (FULL) OF 'BIG' (Cost=53 Card=40000 Bytes=160000) <br /><br />Statistics <br />------------------------------------------------------- <br />0 recursive calls <br />0 db block gets <br />543 consistent gets <br />0 physical reads <br /><br />SQL> select count(1) from big a where exists <br />(select 1 from small b where a.object_id=b.object_id); <br /><br />COUNT(1) <br />---------- <br />1600 <br /><br />已用时间: 00: 00: 00.09 <br /><br />Execution Plan <br />---------------------------------------------------------- <br />0 SELECT STATEMENT Optimizer=CHOOSE (Cost=58 Card=1 Bytes=8) <br />1 0 SORT (AGGREGATE) <br />2 1 HASH JOIN (Cost=58 Card=1600 Bytes=12800) <br />3 2 SORT (UNIQUE) <br />4 3 TABLE ACCESS (FULL) OF 'SMALL' (Cost=2 Card=400 Bytes=1600) <br />5 2 TABLE ACCESS (FULL) OF 'BIG' (Cost=53 Card=40000 Bytes=160000) <br /><br />Statistics <br />-------------------------------------------------------- <br />0 recursive calls <br />0 db block gets <br />543 consistent gets <br />0 physical reads <br /><br /><br />SQL> select count(1) from small a where a.object_id in <br />(select b.object_id from big b); <br /><br />COUNT(1) <br />---------- <br />400 <br /><br />已用时间: 00: 00: 00.09 <br /><br />Execution Plan <br />------------------------------------------------------ <br />0 SELECT STATEMENT Optimizer=CHOOSE (Cost=56 Card=1 Bytes=8) <br />1 0 SORT (AGGREGATE) <br />2 1 HASH JOIN (SEMI) (Cost=56 Card=400 Bytes=3200) <br />3 2 TABLE ACCESS (FULL) OF 'SMALL' (Cost=2 Card=400 Bytes=1600) <br />4 2 TABLE ACCESS (FULL) OF 'BIG' (Cost=53 Card=40000 Bytes=160000) <br /><br />Statistics <br />------------------------------------------------------ <br />0 recursive calls <br />0 db block gets <br />543 consistent gets <br />0 physical reads <br /><br />SQL> select count(1) from small a where exists <br />(select 1 from big b where a.object_id=b.object_id); <br /><br />COUNT(1) <br />---------- <br />400 <br /><br />已用时间: 00: 00: 00.09 <br /><br />Execution Plan <br />------------------------------------------------------- <br />0 SELECT STATEMENT Optimizer=CHOOSE (Cost=56 Card=1 Bytes=8) <br />1 0 SORT (AGGREGATE) <br />2 1 HASH JOIN (SEMI) (Cost=56 Card=400 Bytes=3200) <br />3 2 TABLE ACCESS (FULL) OF 'SMALL' (Cost=2 Card=400 Bytes=1600) <br />4 2 TABLE ACCESS (FULL) OF 'BIG' (Cost=53 Card=40000 Bytes=160000) <br /><br />Statistics <br />------------------------------------------------------- <br />0 recursive calls <br />0 db block gets <br />543 consistent gets <br />0 physical reads <br /><br />删除表分析,使用提示/*+ use_hash(a,b) */ 或者 /*+ hash_sj */, <br />两种语法都可以达到CBO的执行计划 <br /><br />SQL> analyze table big delete statistics; <br />SQL> analyze table small delete statistics; <br /><br />SQL> select /*+ use_hash(a,b) */count(1) from big a where a.object_id in <br />(select b.object_id from small b); <br /><br />SQL> select /*+ use_hash(a,b) */count(1) from big a where exists <br />(select 1 from small b where a.object_id=b.object_id); <br /><br />SQL> select count(1) from small a where a.object_id in <br />(select /*+ hash_sj */ b.object_id from big b); <br /><br />SQL> select count(1) from small a where exists <br />(select /*+ hash_sj */ 1 from big b where a.object_id=b.object_id); <br /><br />下表列出了各种情况下的速度情况： <br />┌───────────┬──────────────────────────┬─────────────────────────┬─────────────┐ <br />│ │ outer big,inner small │ outer small,inner big │ table rows │ <br />├───────────┼──────────┬───────────────┼──────────┬──────────────┼─────────────┤ <br />│ │ IN SQL │ EXISTS SQL │ IN SQL │ EXISTS SQL │ │ <br />├───────────┼──────────┼───────────────┼──────────┼──────────────┼─────────────┤ <br />│un-analyze │ 0.56s │ 3.10s │ 0.56s │ 0.25s │ big=40000 │ <br />├───────────┼──────────┼───────────────┼──────────┼──────────────┤ and │ <br />│ analyzed │ 0.09s │ 0.09s │ 0.09s │ 0.09s │ small=400 │ <br />├───────────┼──────────┼───────────────┼──────────┼──────────────┼─────────────┤ <br />│un-analyze │ 0.72s │ 3.53s │ 0.25s │ 2.97s │ big=5000 │ <br />├───────────┼──────────┼───────────────┼──────────┼──────────────┤ and │ <br />│ analyzed │ 0.09s │ 0.09s │ 0.09s │ 0.09s │ small=4000 │ <br />└───────────┴──────────┴───────────────┴──────────┴──────────────┴─────────────┘ <br /><br />结论：在未对表进行分析前,若两个表数据量差异很大,则外层表是大表时使用IN较快, <br />外层表是小表时使用EXISTS较快;若两表数据量接近,则使用IN较快; <br />分析表后无论用IN还是EXISTS都变得更快,由于执行计划一样,所以速度一样; <br /><br />所以：无论使用IN还是EXISTS,只要使用散列连接,即提示/*+ use_hash(a,b) */, <br />或者在子句中散列半连接提示/*+ hash_sj */, 就使其达到最优速度; <br /><br />附注：半连接的提示有hash_sj、merge_sj、nl_sj <br /><br /><br />*********************************************************************************************************************** <br />*********************************************************************************************************************** <br /><br /><br />2、NOT IN 和 NOT EXISTS <br /><br />NOT EXISTS的执行流程 <br />select ..... <br />from rollup R <br />where not exists ( select 'Found' from title T <br />where R.source_id = T.Title_ID); <br />可以理解为: <br />for x in ( select * from rollup ) <br />loop <br />if ( not exists ( that query ) ) then <br />OUTPUT <br />end if; <br />end; <br /><br />注意:NOT EXISTS 与 NOT IN 不能完全互相替换，看具体的需求。如果选择的列可以为空，则不能被替换。 <br /><br />对于not in 和 not exists的性能区别： <br />not in 只有当子查询中，select 关键字后的字段有not null约束或者有这种暗示时用not in,另外如果主查询中表大， <br />子查询中的表小但是记录多，则应当使用not in,并使用anti hash join. <br /><br />如果主查询表中记录少，子查询表中记录多，并有索引，可以使用not exists，另外not in最好也可以用/*+ HASH_AJ */ <br />或者外连接+is null，NOT IN 在基于成本的应用中较好 <br /><br />创建测试用例表big(40000 row)和small(1000 row)： <br /><br />truncate table big; <br />truncate table small; <br />insert into big select * from dba_objects where rownum &lt;=20000; <br />insert into big select * from dba_objects where rownum &lt;=20000; <br />insert into small select * from dba_objects where rownum &lt;=1000; <br />commit; <br /><br />基本句型： <br />&lt;1> not in <br />SQL> select count(1) from big a where a.object_id not in (select b.object_id from small b); <br /><br />COUNT(1) <br />---------- <br />38000 <br /><br />已用时间: 00: 00: 12.56 <br /><br />Execution Plan <br />----------------------------------------------------- <br />0 SELECT STATEMENT Optimizer=CHOOSE <br />1 0 SORT (AGGREGATE) <br />2 1 FILTER <br />3 2 TABLE ACCESS (FULL) OF 'BIG' <br />4 2 TABLE ACCESS (FULL) OF 'SMALL' <br /><br /><br />Statistics
          <br/>
          <span style="color:red;">
            <a href="http://qsky.javaeye.com/blog/152858#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>Thu, 03 Jan 2008 16:33:14 +0800</pubDate>
        <link>http://qsky.javaeye.com/blog/152858</link>
        <guid>http://qsky.javaeye.com/blog/152858</guid>
      </item>
      <item>
        <title>PHP cookie和session的分析</title>
        <author>qsky</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://qsky.javaeye.com">qsky</a>&nbsp;
          链接：<a href="http://qsky.javaeye.com/blog/151196" style="color:red;">http://qsky.javaeye.com/blog/151196</a>&nbsp;
          发表时间: 2007年12月27日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          1. PHP的COOKIE<br /><br />cookie 是一种在远程浏览器端储存数据并以此来跟踪和识别用户的机制。<br />PHP在http协议的头信息里发送cookie, 因此 setcookie() 函数必须在其它信息被输出到浏览器前调用，这和对 header() 函数的限制类似。<br /><br />1.1 设置cookie:<br />    可以用 setcookie() 或 setrawcookie() 函数来设置 cookie。也可以通过向客户端直接发送http头来设置.<br />1.1.1 使用setcookie()函数设置cookie:<br />bool setcookie ( string name [, string value [, int expire [, string path [, string domain [, bool secure [, bool httponly]]]]]] )<br />     name:   cookie变量名<br />     value:   cookie变量的值<br />     expire:  有效期结束的时间,<br />     path:    有效目录,<br />     domain: 有效域名,顶级域唯一<br />     secure:  如果值为1,则cookie只能在https连接上有效,如果为默认值0,则http和https都可以.<br />例子:<br />&lt;?php<br />$value = 'something from somewhere';<br /><br />setcookie("TestCookie", $value); /* 简单cookie设置 */<br />setcookie("TestCookie", $value, time()+3600); /* 有效期1个小时 */<br />setcookie("TestCookie", $value, time()+3600, "/~rasmus/", ".example.com", 1); /* 有效目录 /~rasmus,有效域名example.com及其所有子域名 */<br />?><br /><br />设置多个cookie变量: setcookie('var[a]','value');用数组来表示变量,但他的下标不用引号.这样就可以用$_COOKIE[‘var’][‘a’]来读取该COOKIE变量.<br /><br />1.1.2. 使用header()设置cookie;<br />header("Set-Cookie: name=$value[;path=$path[;domain=xxx.com[;...]]");<br />后面的参数和上面列出setcookie函数的参数一样.<br />比如:<br /><br />$value = 'something from somewhere';<br />header("Set-Cookie:name=$value");<br /><br /><br />1.2 Cookie的读取:<br /><br />直接用php内置超级全局变量 $_COOKIE就可以读取浏览器端的cookie.<br />上面例子中设置了cookie"TestCookie",现在我们来读取:<br /><br />print $_COOKIE['TestCookie'];<br /><br />COOKIE是不是被输出了?!<br /><br /><br />1.3 删除cookie<br />只需把有效时间设为小于当前时间, 和把值设置为空.例如:<br />setcookie("name","",time()-1);<br />用header()类似.<br /><br />1.4 常见问题解决:<br /><br />1) 用setcookie()时有错误提示,可能是因为调用setcookie()前面有输出或空格.也可能你的文档使从其他字符集转换过来,文档后面可能带有BOM签名(就是在文件内容添加一些隐藏的BOM字符).解决的办法就是使你的文档不出现这种情况.还有通过使用ob_start()函数有也能处理一点.<br />2) $_COOKIE受magic_quotes_gpc影响,可能自动转义<br />3) 使用的时候,有必要测试用户是否支持cookie<br />&lt;!--[if !supportLineBreakNewLine]--><br /><br /><br />1.5 cookie工作机理:<br /><br />有些学习者比较冲动,没心思把原理研究,所以我把它放后面.<br />a) 服务器通过随着响应发送一个http的Set-Cookie头,在客户机中设置一个cookie(多个cookie要多个头). <br />b) 客户端自动向服务器端发送一个http的cookie头,服务器接收读取.<br /><br /><br />HTTP/1.x 200 OK<br />X-Powered-By: PHP/5.2.1<br />Set-Cookie: TestCookie=something from somewhere; path=/<br />Expires: Thu, 19 Nov 2007 18:52:00 GMT<br />Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0<br />Pragma: no-cache<br />Content-type: text/html<br /><br /><br />这一行实现了cookie功能,收到这行后<br />Set-Cookie: TestCookie=something from somewhere; path=/<br />浏览器将在客户端的磁盘上创建一个cookie文件,并在里面写入:<br /><br />TestCookie=something from somewhere;<br />/<br /><br />这一行就是我们用setcookie('TestCookie','something from somewhere','/');的结果.也就是用header('Set-Cookie: TestCookie=something from somewhere; path=/');的结果.<br />&lt;!--[endif]--><br /><br /><br />--------------------------------------------------------------------------------<br /><br /><br /><br />2. PHP的Session<br /><br />session使用过期时间设为0的cookie,并且将一个称为session ID的唯一标识符(一长串字符串),在服务器端同步生成一些session文件(可以自己定义session的保存类型),与用户机关联起来.web应用程序存贮与这些session相关的数据,并且让数据随着用户在页面之间传递.<br /><br />访问网站的来客会被分配一个唯一的标识符，即所谓的会话 ID。它要么存放在客户端的 cookie，要么经由 URL 传递。 <br /><br />会话支持允许用户注册任意数目的变量并保留给各个请求使用。当来客访问网站时，PHP 会自动（如果 session.auto_start 被设为 1）或在用户请求时（由 session_start() 明确调用或 session_register() 暗中调用）检查请求中是否发送了特定的会话 ID。如果是，则之前保存的环境就被重建。 <br /><br />2.1 sessionID的传送<br /><br />2.1.1 通过cookie传送sessin ID<br /><br />     使用session_start()调用session,服务器端在生成session文件的同时,生成session ID哈希值和默认值为PHPSESSID的session name,并向客户端发送变量为(默认的是)PHPSESSID(session name),值为一个128位的哈希值.服务器端将通过该cookie与客户端进行交互.<br />   session变量的值经php内部系列化后保存在服务器机器上的文本文件中,和客户端的变量名默认情况下为PHPSESSID的coolie进行对应交互.<br />     即服务器自动发送了http头:header('Set-Cookie: session_name()=session_id(); path=/');<br />即setcookie(session_name(),session_id());<br />    当从该页跳转到的新页面并调用session_start()后,PHP将检查与给定ID相关联的服务器端存贮的session数据,如果没找到,则新建一个数据集.<br /><br />2.1.2 通过URL传送session ID<br />只有在用户禁止使用cookie的时候才用这种方法,因为浏览器cookie已经通用,为安全起见,可不用该方法.<br />&lt;a href="p.php?&lt;?php print session_name() ?>=&lt;?php print session_id() ?>">xxx&lt;/a>,也可以通过POST来传递session值.<br /><br />2.2 session基本用法实例<br /><br />&lt;?php<br />// page1.php<br />session_start();<br />echo 'Welcome to page #1';<br />/* 创建session变量并给session变量赋值 */<br />$_SESSION['favcolor'] = 'green'; <br />$_SESSION['animal'] = 'cat';<br />$_SESSION['time'] = time();<br /><br />// 如果客户端使用cookie,可直接传递session到page2.php<br />echo '&lt;br />&lt;a href="page2.php">page 2&lt;/a>';<br /><br />// 如果客户端禁用cookie<br />echo '&lt;br />&lt;a href="page2.php?' . SID . '">page 2&lt;/a>'; <br />/* <br /> 默认php5.2.1下,SID只有在cookie被写入的同时才会有值,如果该session<br /> 对应的cookie已经存在,那么SID将为(未定义)空<br /> */<br />?><br /><br />&lt;?php<br />// page2.php<br />session_start();<br />print $_SESSION['animal']; // 打印出单个session<br />var_dump($_SESSION); // 打印出page1.php传过来的session值<br />?><br /><br /><br /><br /><br />2.3 使用session函数控制页面缓存.<br />    很多情况下,我们要确定我们的网页是否在客户端缓存,或要设置缓存的有效时间,比如我们的网页上有些敏感内容并且要登录才能查看,如果缓存到本地了,可以直接打开本地的缓存就可以不登录而浏览到网页了.<br /><br />    使用session_cache_limiter('private');可以控制页面客户端缓存,必须在session_start()之前调用.<br />更多参数见http://blog.chinaunix.net/u/27731/showart.php?id=258087的客户端缓存控制.<br /><br />     控制客户端缓存时间用 session_cache_expire(int);单位(s).也要在session_start()前调用.<br /><br />    这只是使用session的情况下控制缓存的方法,我们还可以在header()中控制控制页面的缓存.<br /><br />2.4 删除session<br /><br />要三步实现.<br />&lt;?php<br />session_destroy();                                      // 第一步: 删除服务器端session文件,这使用 <br />setcookie(session_name(),'',time()-3600);  // 第二步: 删除实际的session: <br />$_SESSION = array();                                  // 第三步: 删除$_SESSION全局变量数组<br />?><br /><br />2.5 session在PHP大型web应用中的使用<br /><br />对于访问量大的站点,用默认的session存贮方式并不适合,目前最优的方法是用数据库存取session.这时,函数bool session_set_save_handler ( callback open, callback close, callback read, callback write, callback destroy, callback gc )就是提供给我们解决这个问题的方案.<br />该函数使用的6个函数如下:<br /><br />1.   bool open() 用来打开会话存储机制, <br /><br />2.   bool close() 关闭会话存储操作. <br /><br />3.  mixde read() 从存储中装在session数据时使用这个函数 <br /><br />4.   bool write() 将给定session ID的所有数据写到存储中 <br /><br />5.   bool destroy() 破坏与指定的会话ID相关联的数据 <br /><br />6.   bool gc()  对存储系统中的数据进行垃圾收集<br /><br />例子见php手册session_set_save_handler() 函数.<br />如果用类来处理,用<br />session_set_save_handler(<br />    array('className','open'),<br />    array('className','close'),<br />    array('className','read'),<br />    array('className','write'),<br />    array('className','destroy'),<br />    array('className','gc'),<br />) <br />调用className类中的6个静态方法.className可以换对象就不用调用静态方法,但是用静态成员不用生成对象,性能更好.<br /><br />2.6 常用session函数:<br /><br />bool   session_start(void); 初始化session<br />bool   session_destroy(void): 删除服务器端session关联文件。<br />string session_id() 当前session的id<br />string session_name() 当前存取的session名称,也就是客户端保存session ID的cookie名称.默认PHPSESSID。<br />array  session_get_cookie_params() 与这个session相关联的session的细节.<br />string session_cache_limiter() 控制使用session的页面的客户端缓存<br />ini    session_cache_expire() 控制客户端缓存时间<br />bool   session_destroy()     删除服务器端保存session信息的文件<br />void   session_set_cookie_params ( int lifetime [, string path [, string domain [, bool secure [, bool httponly]]]] )设置与这个session相关联的session的细节<br />bool session_set_save_handler ( callback open, callback close, callback read, callback write, callback destroy, callback gc )定义处理session的函数,(不是使用默认的方式)<br />bool session_regenerate_id([bool delete_old_session]) 分配新的session id<br /><br /><br />2.7 session安全问题<br />攻击者通过投入很大的精力尝试获得现有用户的有效会话ID,有了会话id,他们就有可能能够在系统中拥有与此用户相同的能力.<br />因此,我们主要解决的思路是效验session ID的有效性.<br /><br />&lt;?php<br /><br />if(!isset($_SESSION['user_agent'])){<br />    $_SESSION['user_agent'] = $_SERVER['REMOTE_ADDR'].$_SERVER['HTTP_USER_AGENT'];<br />}<br /><br />/* 如果用户session ID是伪造 */<br />elseif ($_SESSION['user_agent'] != $_SERVER['REMOTE_ADDR'] . $_SERVER['HTTP_USER_AGENT']) {<br />    session_regenerate_id();<br />}<br />?><br /><br /><br />2.8 Session通过cookie传递和通过SID传递的不同:<br />在php5.2.1的session的默认配置的情况下,当生成session的同时,服务器端将在发送header set-cookie同时生成预定义超级全局变量SID(也就是说,写入cookie和抛出SID是等价的.),当$_COOKIE['PHPSESSID']存在以后,将不再写入cookie,也不再生成超级全局变量SID,此时,SID将是空的.<br /><br /><br /><br />2.9 session使用实例<br /><br />&lt;?php<br />/**<br /> * 效验session的合法性<br /> *<br /> */<br />function sessionVerify() {<br />    if(!isset($_SESSION['user_agent'])){<br />        $_SESSION['user_agent'] = MD5($_SERVER['REMOTE_ADDR']<br />        .$_SERVER['HTTP_USER_AGENT']);<br />    }<br />    /* 如果用户session ID是伪造,则重新分配session ID */<br />    elseif ($_SESSION['user_agent'] != MD5($_SERVER['REMOTE_ADDR'] <br />    . $_SERVER['HTTP_USER_AGENT'])) {<br />        session_regenerate_id();<br />    }<br />}<br /><br />/**<br /> * 销毁session<br /> * 三步完美实现,不可漏<br /> *<br /> */<br />function sessionDestroy() {<br />    session_destroy();<br />    setcookie(session_name(),'',time()-3600);<br />    $_SESSION = array();<br />}<br />?><br /><br /><br /><br /><br />注明: <br /><br /><br />    session 出现头信息已经发出的原因与cookie一样.<br />    在php5中,所有php session 的注册表配置选项都是编程时可配置的,一般情况下,我们是不用修改其配置的.要了解php的session注册表配置选项,请参考手册的Session 会话处理函数处.
          <br/>
          <span style="color:red;">
            <a href="http://qsky.javaeye.com/blog/151196#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>Thu, 27 Dec 2007 13:10:59 +0800</pubDate>
        <link>http://qsky.javaeye.com/blog/151196</link>
        <guid>http://qsky.javaeye.com/blog/151196</guid>
      </item>
      <item>
        <title>使用crossdomain.xml让Flash可以跨域传输数据(转)</title>
        <author>qsky</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://qsky.javaeye.com">qsky</a>&nbsp;
          链接：<a href="http://qsky.javaeye.com/blog/150908" style="color:red;">http://qsky.javaeye.com/blog/150908</a>&nbsp;
          发表时间: 2007年12月26日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          本文来自http://www.mzwu.com/article.asp?id=975<br /><br />一、概述<br /><br />位于www.mzwu.com域中的SWF文件要访问www.163.com的文件时，SWF首先会检查163服务器目录下是否有crossdomain.xml文件，如果没有，则访问不成功；若crossdomain.xml文件存在，且里边设置了允许www.mzwu.com域访问，那么通信正常。所以要使Flash可以跨域传输数据，其关键就是crossdomain.xml。<br /><br />二、crossdomain.xml文件格式<br /><br />crossdomain.xml的格式非常简单，其根节点为&lt;cross-domain-policy> ，其下包含一个或多个&lt;allow-access-from>节点，&lt;allow-access-from>有一个属性domain，其值为允许访问的域，可以是确切的 IP 地址、一个确切的域或一个通配符域（任何域）。下边是两个例子：<br /><br /><br /><br />程序代码<br />&lt;?xml version="1.0"?><br />&lt;cross-domain-policy><br />  &lt;allow-access-from domain="www.friendOfFoo.com" /><br />  &lt;allow-access-from domain="*.foo.com" /><br />  &lt;allow-access-from domain="105.216.0.40" /><br />&lt;/cross-domain-policy><br /><br /><br /> <br /><br />程序代码<br />&lt;?xml version="1.0"?><br />&lt;cross-domain-policy><br />  &lt;allow-access-from domain="*" /><br />&lt;/cross-domain-policy><br /><br /><br />第二个例子允许任何域的访问。对于crossdomain.xml文件存放位置，建议将其存放于站点根目录中！<br /><br />三、示例<br /><br />1.SWF文件主要Actionscript：<br /><br /><br /><br />程序代码<br />on (release) {<br />    var myvar = new LoadVars();<br />    myvar.t = t2.text;<br />    myvar.sendAndLoad("http://www.163.com/test.asp",myvar,"post");<br />    myvar.onLoad = function(re){<br />        if(re){<br />            t1.text = myvar.t;<br />        }else{<br />            t1.text = "fail...";<br />        }<br />    }<br />}<br /><br />2.test.asp代码：<br /><br />程序代码<br /><br />&lt;%<br />Dim t<br />t = Request.form("t")<br />Response.write("t=" & t & " back!")<br />%>
          <br/>
          <span style="color:red;">
            <a href="http://qsky.javaeye.com/blog/150908#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, 26 Dec 2007 12:35:23 +0800</pubDate>
        <link>http://qsky.javaeye.com/blog/150908</link>
        <guid>http://qsky.javaeye.com/blog/150908</guid>
      </item>
      <item>
        <title>Ruby on Rails HTML表单语句大全</title>
        <author>qsky</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://qsky.javaeye.com">qsky</a>&nbsp;
          链接：<a href="http://qsky.javaeye.com/blog/148691" style="color:red;">http://qsky.javaeye.com/blog/148691</a>&nbsp;
          发表时间: 2007年12月16日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <pre name="code" class="ruby">
<a href="http://www.blogjava.net/wldandan/archive/2007/12/15/167920.html" target="_blank">http://www.blogjava.net/wldandan/archive/2007/12/15/167920.html</a>
初学者必备


表单开始标签:

Use :multipart => true to define a Mime-Multipart form (for file uploads) 
表单结束标签:


文本框 Text fields

生成:


实例:

text_field "post", "title", "size" => 20
                size="20" value="#{@post.title}" />

隐藏框:


密码框:


文件框


Rails Textarea框

实例:
text_area "post", "body", "cols" => 20, "rows" => 40
    &lt;br />
        &lt;a href="mailto:#%7B@post.body" _fcksavedurl="mailto:#%7B@post.body">&lt;font color="#0000ff">#{@post.body&lt;/font>&lt;/a>}&lt;br />
    

单选框 Radio Buttons

实例:
radio_button "post", "category", "rails"
radio_button "post", "category", "java"
    value="rails" 
           checked="checked" />
    value="java" />

多选框 Check Box

实例
check_box "post", "validated"   # post.validated? returns 1 or 0
                value="1" checked="checked" />
    value="0" />

check_box "puppy", "gooddog", {}, "yes", "no"
    value="yes" />
    value="no" />


下拉菜单框 Select Menu
select  "post",         
        "person_id",    
        Person.find_all.collect {|p| [ p.name, p.id ] },
        { :include_blank => true } 

         value="1" selected="selected">David    value="2">Sam    value="3">Tobias  

Collection Selection


日期选择框:


实例:
date_select "post", "written_on"
date_select "user", "birthday", :start_year => 1910
date_select "user", "cc_date", :start_year => 2005,
                               :use_month_numbers => true,
                               :discard_day => true,
                               :order => [:year, :month]

datetime_select "post", "written_on"
</pre>
          <br/>
          <span style="color:red;">
            <a href="http://qsky.javaeye.com/blog/148691#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>Sun, 16 Dec 2007 16:32:21 +0800</pubDate>
        <link>http://qsky.javaeye.com/blog/148691</link>
        <guid>http://qsky.javaeye.com/blog/148691</guid>
      </item>
      <item>
        <title>socket 模型简介</title>
        <author>qsky</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://qsky.javaeye.com">qsky</a>&nbsp;
          链接：<a href="http://qsky.javaeye.com/blog/143944" style="color:red;">http://qsky.javaeye.com/blog/143944</a>&nbsp;
          发表时间: 2007年11月27日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>共同点：<br />
ServerSocket serverSocket = new ServerSocket(80);<br />
sokcet s = serverSocket.accept(); </p>
<p>区别：<br />
1 原始：（线程池）<br />
每来一个请求分配新的一个线程来处理，继续等待下一个请求，这个过程中每一个线程一直等待数据的到来。这种情况导致随并发量多 线程数增加，系统消耗比较大<br />
2 select（2个线程）<br />
每来一个请求则把s给select，继续等待下一个请求。来数据时select里copy一个套接字，来处理缓冲区数据（这个过程很耗时），因当时的条件所限制select里只能放64个套接字，也就是说并发最大量为64. 一个线程处理接受，另一个进程处理套接字处理数据<br />
3 poll（2个线程）<br />
每来一个请求把s给poll（push进去），继续等待下一个请求，来数据时从push里弹出套接字（不用copy了），处理缓冲区的数据。支持并发可以数千个。<br />
一个线程处理接受，另一个进程处理套接字处理数据<br />
4 epoll（2个线程）<br />
每来一个请求把s给epoll（push进去），来数据时缓存，需要处理数据时，把缓冲区的数据和套接字一起返回，这样节省了readBuffer的时间，效率更高<br />
一个线程处理接受，另一个进程处理套接字处理数据</p>
<p>下面深入讲一下epoll模型和iocp模型的异同之处</p>
<p>目前国内的网游研发，在服务器使用的开发平台方面，win和linux的比例各占多少，我一时半会也没有准确数据，但从我了解的这么多公司情况来看，用win系统的还是比较多一点，这些企业一般都是比较单纯的网游公司，而用linux的则多数是一些传统的互联网公司，比如网易和腾讯。<br />
<br />
网游服务器用win还是linux，向来都是大家关注的话题。我想，原因可能很多，但此处不想过多论述这个问题，为避免多费口舌，我还是明确表明一下自己的观点：我是推荐用linux作开发的，虽然我也是刚转来作linux平台下的开发。<br />
<br />
那么，说具体一点。但凡作过比较深入的网络编程的人，都会知道，在win平台下，高效的IO模型是IOCP，而在linux底下则是epoll。那么，epoll与iocp之间到底有哪些异同之处呢？<br />
<br />
首先，我们看一下它们相同的地方。<br />
<br />
两者都是处理异步IO的高效模型，这种高效，除了&ldquo;异步处理&rdquo;这个共同的特征之外，二者都可以通过指针携带应用层数据：在IOCP里，应用层数据可以通过单句柄数据和单IO数据来与IOCP底层通信；而在epoll里，可以通过epoll_data里的&quot;void *ptr&quot;来传递。这是一种很重要的思想，也是它们高效的原因所在：当事件的通知到来时，它不仅告诉你发生了什么样的事件，还同时告诉这次事件所操作的数据是哪些。<br />
<br />
那么，epoll和iocp到底又有什么不同呢？<br />
<br />
以我目前粗浅的使用经验来看，至少可以得到以下结论：<br />
<br />
1.iocp是在IO操作完成之后，才通过get函数返回这个完成通知的；而epoll则<font color="#ff0000">不是在IO操作完成之后才通知你</font>，它的工作原理是，你如果想进行IO操作时，先向epoll查询是否可读或可写，如果处于可读或可写状态后，epoll会通过epoll_wait函数通知你，此时你再进行进一步的recv或send操作。<br />
<br />
2.在1的基础上，我们其实可以看到，epoll仅仅是一个异步事件的通知机制，其本身并不作任何的IO读写操作，它只负责告诉你是不是可以读或可以写了，而具体的读写操作，还要应用层自己来作；但iocp的封装就要多一些，它不仅会有完成之后的事件通知，更重要的是，它同时封装了一部分的IO控制逻辑。从这一点上来看，iocp的封装似乎更全面一点，但是，换个角度看，epoll仅提供这种机制也是非常好的，它保持了事件通知与IO操作之间彼此的独立性，使得epoll的使用更加灵活。</p>
          <br/>
          <span style="color:red;">
            <a href="http://qsky.javaeye.com/blog/143944#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, 27 Nov 2007 11:52:47 +0800</pubDate>
        <link>http://qsky.javaeye.com/blog/143944</link>
        <guid>http://qsky.javaeye.com/blog/143944</guid>
      </item>
      <item>
        <title>Linux下的JFreeChart和 汉子验证码 中文乱码问题解决方案 </title>
        <author>qsky</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://qsky.javaeye.com">qsky</a>&nbsp;
          链接：<a href="http://qsky.javaeye.com/blog/138371" style="color:red;">http://qsky.javaeye.com/blog/138371</a>&nbsp;
          发表时间: 2007年11月06日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <span style="font-family: Arial"><p>原因：<span style="font-family: Arial">首先,JFreeChart和中文验证码的乱码问题和jsp的编码无关,是由于Java虚拟机找不到字体文件造成的,所以同类的Swing或者AWT的中文乱码问题也适用</span></p><p>环境:<br />JDK1.5(JDK版本很重要,如果是1.4.2版本的话,JRE目录下的字体配置文件不大一样)<br />RedHat4.0<br />Tomcat5.0</p><p>解决方法:<br />1.确认%JavaHome%/jre/lib/fonts目录下存在zysong.ttf<br />2.在%JavaHome%/jre/lib/fonts目录下执行&quot;ttmkfdir -o fonts.dir&quot;命令,重新生成fonts.dir文件<br />3.确认/usr/share/fonts/zh_CN/TrueType目录存在,如果不存在则mkdir创建<br />4.确认/usr/share/fonts/zh_CN/TrueType目录下存在zysong.ttf<br />5.在%JavaHome%/jre/lib目录下,执行 cp fontconfig.RedHat.3.properties.src fontconfig.properties<br />6.重新启动tomcat,大功告成!</p><p>下面提供下载字体</p></span>
          <br/>
          <span style="color:red;">
            <a href="http://qsky.javaeye.com/blog/138371#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>Tue, 06 Nov 2007 15:03:50 +0800</pubDate>
        <link>http://qsky.javaeye.com/blog/138371</link>
        <guid>http://qsky.javaeye.com/blog/138371</guid>
      </item>
      <item>
        <title>局部模版为什么不显示呢？</title>
        <author>qsky</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://qsky.javaeye.com">qsky</a>&nbsp;
          链接：<a href="http://qsky.javaeye.com/blog/137879" style="color:red;">http://qsky.javaeye.com/blog/137879</a>&nbsp;
          发表时间: 2007年11月04日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          做了个相册，想查看相册的同时把评论在相片下列出来<br />评论信息控制台都能打出相应变量的值 但不知为什么显示不了评论<br />相关代码<br /><pre name="code" class="ruby">
&lt;%unless @album.comments.empty?%>
&lt;%render :partial =>"/comments/comment" ,:collection=>@album.comments %>
&lt;%end%>
</pre>
          <br/>
          <span style="color:red;">
            <a href="http://qsky.javaeye.com/blog/137879#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>Sun, 04 Nov 2007 13:10:13 +0800</pubDate>
        <link>http://qsky.javaeye.com/blog/137879</link>
        <guid>http://qsky.javaeye.com/blog/137879</guid>
      </item>
      <item>
        <title>Ruby 和 Rails 安装</title>
        <author>qsky</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://qsky.javaeye.com">qsky</a>&nbsp;
          链接：<a href="http://qsky.javaeye.com/blog/133202" style="color:red;">http://qsky.javaeye.com/blog/133202</a>&nbsp;
          发表时间: 2007年10月18日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          &nbsp;
<h3><a name="_Toc180149504"><span lang="EN-US" style="mso-font-kerning: 0pt">1 </span></a><span style="mso-bookmark: _Toc180149504"><span style="FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">远程安装：</span></span><span style="mso-bookmark: _Toc180149504"></span><span lang="EN-US" style="mso-font-kerning: 0pt"><o:p></o:p></span></h3>
<p style="BACKGROUND: #f9fcfe; WORD-BREAK: break-all"><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 黑体; mso-bidi-font-family: Tahoma; mso-hansi-font-family: Tahoma">步骤</span><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: Arial">1</span><span style="FONT-SIZE: 10.5pt; mso-bidi-font-family: Tahoma">： 下载并安装</span><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: Tahoma">Ruby</span><span style="FONT-SIZE: 10.5pt; mso-bidi-font-family: Tahoma">一键安装包</span><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: Tahoma"><o:p></o:p></span></p>
<p style="BACKGROUND: #f9fcfe; MARGIN-LEFT: 42pt; WORD-BREAK: break-all; mso-para-margin-left: 4.0gd">下载最新的<span lang="EN-US">Ruby </span>一键安装包，其下载地址为<span lang="EN-US">http://rubyforge.org/ projects/rubyinstaller/</span>。安装完成后打开命令行窗口，输入并运行命令<span lang="EN-US">ruby &ndash;v</span>，安装成功会显示<span lang="EN-US">Ruby</span>的版本号<span lang="EN-US" style="FONT-SIZE: 10.5pt; mso-bidi-font-family: Tahoma"><o:p></o:p></span></p>
<p class="MsoNormal" style="MARGIN-LEFT: 58.5pt; LAYOUT-GRID-MODE: char; mso-pagination: widow-orphan; mso-para-margin-left: 5.57gd"><span lang="EN-US" style="mso-bidi-font-size: 10.5pt; mso-bidi-font-family: Tahoma"><o:p>&nbsp;</o:p></span></p>
<p style="BACKGROUND: #f9fcfe; WORD-BREAK: break-all"><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 黑体; mso-bidi-font-family: Tahoma; mso-hansi-font-family: Tahoma">步骤</span><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: Arial">2</span><span style="FONT-SIZE: 10.5pt; mso-bidi-font-family: Tahoma">：使用</span><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: Tahoma">RubyGems</span><span style="FONT-SIZE: 10.5pt; mso-bidi-font-family: Tahoma">安装</span><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: Tahoma">Rails<o:p></o:p></span></p>
<p style="BACKGROUND: #f9fcfe; MARGIN-LEFT: 42pt; WORD-BREAK: break-all; mso-para-margin-left: 4.0gd"><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: Tahoma">RubyGems</span><span style="FONT-SIZE: 10.5pt; mso-bidi-font-family: Tahoma">是标准的</span><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: Tahoma">Ruby</span><span style="FONT-SIZE: 10.5pt; mso-bidi-font-family: Tahoma">包管理器，它的功能类似于</span><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: Tahoma">Linux</span><span style="FONT-SIZE: 10.5pt; mso-bidi-font-family: Tahoma">下的</span><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: Tahoma">apt-get</span><span style="FONT-SIZE: 10.5pt; mso-bidi-font-family: Tahoma">。使用</span><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: Tahoma">RubyGems</span><span style="FONT-SIZE: 10.5pt; mso-bidi-font-family: Tahoma">可以方便地从远程服务器下载并安装</span><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: Tahoma">Rails</span><span style="FONT-SIZE: 10.5pt; mso-bidi-font-family: Tahoma">。打开命令行窗口，输入并执行命令</span><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: Tahoma">gem install rails --remote</span><span style="FONT-SIZE: 10.5pt; mso-bidi-font-family: Tahoma">或</span><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: Tahoma">gem install rails-- include-dependencies<o:p></o:p></span></p>
<p class="MsoNormal" style="TEXT-INDENT: 42pt; mso-char-indent-count: 4.0"><span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: Tahoma; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">打开命令行窗口输入并运行</span><span lang="EN-US" style="FONT-FAMILY: Tahoma; mso-bidi-font-size: 10.5pt">rails &ndash;v</span><span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: Tahoma; mso-ascii-font-family: Tahoma; mso-hansi-font-family: Tahoma">，</span><span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: Tahoma; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">安装成功会显示</span><span lang="EN-US" style="FONT-FAMILY: Tahoma; mso-bidi-font-size: 10.5pt">rails</span><span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: Tahoma; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的版本号</span><span lang="EN-US" style="mso-bidi-font-size: 10.5pt; mso-bidi-font-family: Tahoma"><o:p></o:p></span></p>
<h3><a name="_Toc180149505"><span lang="EN-US">2 </span></a><span style="mso-bookmark: _Toc180149505"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">本地安装：</span></span></h3>
<p class="MsoNormal" align="left" style="BACKGROUND: #f9fcfe; WORD-BREAK: break-all; TEXT-ALIGN: left; mso-pagination: widow-orphan"><span style="FONT-FAMILY: 黑体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-bidi-font-family: Tahoma; mso-hansi-font-family: Tahoma">步骤</span><span lang="EN-US" style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">1</span><span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-bidi-font-family: Tahoma">：下载并安装</span><span lang="EN-US" style="FONT-FAMILY: Tahoma; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">Ruby</span><span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-bidi-font-family: Tahoma">一键安装包</span><span lang="EN-US" style="FONT-FAMILY: Tahoma; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="BACKGROUND: #f9fcfe; WORD-BREAK: break-all; TEXT-ALIGN: left; mso-pagination: widow-orphan"><span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-bidi-font-family: Tahoma">具体步骤请参见&ldquo;远程安装&rdquo;部分。</span><span lang="EN-US" style="FONT-FAMILY: Tahoma; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="BACKGROUND: #f9fcfe; WORD-BREAK: break-all; TEXT-ALIGN: left; mso-pagination: widow-orphan"><span style="FONT-FAMILY: 黑体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-bidi-font-family: Tahoma; mso-hansi-font-family: Tahoma">步骤</span><span lang="EN-US" style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">2</span><span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-bidi-font-family: Tahoma">：获取</span><span lang="EN-US" style="FONT-FAMILY: Tahoma; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">Rails</span><span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-bidi-font-family: Tahoma">安装插件包</span><span lang="EN-US" style="FONT-FAMILY: Tahoma; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="BACKGROUND: #f9fcfe; MARGIN-LEFT: 57pt; WORD-BREAK: break-all; TEXT-ALIGN: left; mso-pagination: widow-orphan"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; LETTER-SPACING: -0.1pt; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">从<span lang="EN-US">URL</span>地址<span lang="EN-US">http://rubyforge.org/frs/?group_id=307&amp;release_id=4878</span>下载<span lang="EN-US">rails- <st1:chsdate isrocdate="False" month="12" islunardate="False" day="30" w:st="on" year="1899">1.0.0</st1:chsdate>.gem</span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">和<span lang="EN-US">rails-1.0.0.zip</span>。将下载到的文件保存到同一目录下（<span lang="EN-US">D:\RoR</span>）。<span lang="EN-US"><o:p></o:p></span></span></p>
<p class="MsoNormal" align="left" style="BACKGROUND: #f9fcfe; WORD-BREAK: break-all; TEXT-ALIGN: left; mso-pagination: widow-orphan"><span style="BACKGROUND: black; COLOR: white; FONT-FAMILY: 方正粗倩简体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-bidi-font-family: Tahoma; mso-hansi-font-family: Tahoma">注意</span><span lang="EN-US" style="FONT-FAMILY: Tahoma; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">&nbsp; </span><span style="FONT-FAMILY: 方正楷体简体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-bidi-font-family: Tahoma; mso-hansi-font-family: Tahoma">不需要对压缩文件进行解压缩。</span><span lang="EN-US" style="FONT-FAMILY: Tahoma; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="BACKGROUND: #f9fcfe; WORD-BREAK: break-all; TEXT-ALIGN: left; mso-pagination: widow-orphan"><span style="FONT-FAMILY: 黑体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-bidi-font-family: Tahoma; mso-hansi-font-family: Tahoma">步骤</span><span lang="EN-US" style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">3</span><span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-bidi-font-family: Tahoma">：安装</span><span lang="EN-US" style="FONT-FAMILY: Tahoma; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">Rails</span><span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-bidi-font-family: Tahoma">插件包</span><span lang="EN-US" style="FONT-FAMILY: Tahoma; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="BACKGROUND: #f9fcfe; WORD-BREAK: break-all; TEXT-ALIGN: left; mso-pagination: widow-orphan"><span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-bidi-font-family: Tahoma">打开命令行窗口，进入</span><span lang="EN-US" style="FONT-FAMILY: Tahoma; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">D:\RoR</span><span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-bidi-font-family: Tahoma">目录下，执行命令</span><span lang="EN-US" style="FONT-FAMILY: Tahoma; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">gem install rails</span><span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-bidi-font-family: Tahoma">即可完成安装。</span><span lang="EN-US" style="FONT-FAMILY: Tahoma; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><o:p></o:p></span></p>
          <br/>
          <span style="color:red;">
            <a href="http://qsky.javaeye.com/blog/133202#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, 18 Oct 2007 14:52:17 +0800</pubDate>
        <link>http://qsky.javaeye.com/blog/133202</link>
        <guid>http://qsky.javaeye.com/blog/133202</guid>
      </item>
      <item>
        <title>rails的数据迁移是个麻烦工具</title>
        <author>qsky</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://qsky.javaeye.com">qsky</a>&nbsp;
          链接：<a href="http://qsky.javaeye.com/blog/132526" style="color:red;">http://qsky.javaeye.com/blog/132526</a>&nbsp;
          发表时间: 2007年10月16日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          本人开始接触rails，但是很快被它的灵活简洁所吸引了，但是我看到数据迁移的时候，<br />发现如果我们的项目很大，用它来管理表不一定是个好主意，一旦出错不好维护，而且很多时候删除数据库，然后重建，这个方法我觉得不好，不如DDL来的更方便，更有针对性。<br /><br />轻问大家 ， 数据迁移用的多么？<img src="/images/smiles/icon_smile.gif"/>
          <br/>
          <span style="color:red;">
            <a href="http://qsky.javaeye.com/blog/132526#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, 16 Oct 2007 12:59:11 +0800</pubDate>
        <link>http://qsky.javaeye.com/blog/132526</link>
        <guid>http://qsky.javaeye.com/blog/132526</guid>
      </item>
      <item>
        <title>Rails 吸引了我</title>
        <author>qsky</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://qsky.javaeye.com">qsky</a>&nbsp;
          链接：<a href="http://qsky.javaeye.com/blog/131762" style="color:red;">http://qsky.javaeye.com/blog/131762</a>&nbsp;
          发表时间: 2007年10月14日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>Rails 一个习惯于数优于配置，DRY原则 深深打动了我，我不禁不住喜欢上了它。虽然作为java开发者但偶还是尝试去做了，java 配置带来了很好的灵活性，同时也带来了配置的地狱，呵呵 这是我个人感受。rails的出现我不仅被它吸引住了，而且准备用它来开发一个广告系统 包括广告推送、报表管理和广告统计系统，不知道有没有这样一个系统的先例，没有我就创造这个先例了，呵呵 虽然用rails没有开发过项目，且正在学习ing，希望共同学习进步</p>
          <br/>
          <span style="color:red;">
            <a href="http://qsky.javaeye.com/blog/131762#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>Sun, 14 Oct 2007 14:14:18 +0800</pubDate>
        <link>http://qsky.javaeye.com/blog/131762</link>
        <guid>http://qsky.javaeye.com/blog/131762</guid>
      </item>
  </channel>
</rss>