<?xml version="1.0"?>
<rss version="2.0">  <channel>
    <title>Wendal随笔</title>
    <link>http://wendal.net</link>
    <pubDate>13 Aug 14 22:35 +0800</pubDate>
    <item>
      <title>YeelinkTester 总算弄好了</title>
      <link>http://wendal.net/2014/08/13.html</link>
      <pubDate>2014-08-13 12:00:00 +0800</pubDate>
      <description>&lt;h2&gt;直接上程序截图&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2014/08/13/ABC.png&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;源码:&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&#34;https://github.com/wendal/yeelink_tester&#34;&gt;https://github.com/wendal/yeelink_tester&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;用到的东西&lt;/h2&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;python 2.7.8&lt;/li&gt;&#xA;&lt;li&gt;pyqt 4.11.1&lt;/li&gt;&#xA;&lt;li&gt;mqtt&lt;/li&gt;&#xA;&lt;li&gt;pyserial&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;h2&gt;功能&lt;/h2&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;从串口读取数据,上传到yeelink&lt;/li&gt;&#xA;&lt;li&gt;从yeelink接收mqtt通知,写到串口&lt;/li&gt;&#xA;&lt;li&gt;从串口读取指令,然后会写数据(当前实现了查询最新的值)&lt;/li&gt;&#xA;&lt;li&gt;一个API测试对话框, 支持文件上传&lt;/li&gt;&#xA;&lt;li&gt;一个Yeelink Http API请求分析器(API虚拟服务器),用于排查api调用的错误&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;</description>
    </item>
    <item>
      <title>arduino pro mini的电压问题</title>
      <link>http://wendal.net/2014/08/04.html</link>
      <pubDate>2014-08-04 12:00:00 +0800</pubDate>
      <description>&lt;h2&gt;arduino pro mini的MCU是 atmega328p&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&#34;http://www.atmel.com/devices/atmega328.aspx&#34;&gt;http://www.atmel.com/devices/atmega328.aspx&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;电压从 1.8-5.5&lt;/p&gt;&#xA;&#xA;&lt;p&gt;工作频率最高20Mhz&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;电压与频率的关系&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;3.3v 安全频率 约12.5Mhz&#xA;5v   安全频率 20Mhz&lt;/p&gt;&#xA;&#xA;&lt;p&gt;淘宝上绝大多数都是5V 16Mhz的, 但我手上的几块均能工作在3.3V&lt;/p&gt;&#xA;&#xA;&lt;p&gt;所以就很奇怪这5v和3.3v到底影响了什么.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;由于3.3v下, 16Mhz高于安全频率, 所以mcu事实上工作在&amp;rdquo;超频&amp;rdquo;的状态&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>探索yeelink</title>
      <link>http://wendal.net/2014/07/31.html</link>
      <pubDate>2014-07-31 12:00:00 +0800</pubDate>
      <description>&lt;h2&gt;yeelink官网&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&#34;http://www.yeelink.net/index&#34;&gt;http://www.yeelink.net/index&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;yeelink的传感器&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;支持5种类型: 开关,数值,gps,图片,泛型&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;Yeelink API&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;支持v1和v1.1两个版本, 我是直接跳过v1,实现了v1.1的版本&lt;/p&gt;&#xA;&#xA;&lt;p&gt;不过v1.1依然是测试期,被我遇到几个bug,哈哈&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;最后弄了个java库&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&#34;http://github.com/wendal/yeelink4j&#34;&gt;http://github.com/wendal/yeelink4j&lt;/a&gt;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>用NDK编译ssdb</title>
      <link>http://wendal.net/2014/05/13.html</link>
      <pubDate>2014-05-13 12:00:00 +0800</pubDate>
      <description>&lt;h2&gt;首先,需要准备一下环境&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;ubuntu 14.04 x86 版 &amp;ndash; 当前最新啦,哈哈&lt;/p&gt;&#xA;&#xA;&lt;p&gt;android ndk r9b     &amp;ndash; 为啥用这个版本?因为我机器上有&amp;hellip;&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;编译环境准备&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;把ndk转为独立工具链, 这是今天获取的新技能,呵呵,以后不写Android.mk也能编译部分软件了.&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;/opt/android-ndk-r9b/build/tools/make-standalone-toolchain.sh --install-dir=/opt/ndk-armv7 --arch=armv7&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;下载源码,暂时从我fork出来的库里面取吧,不知道ideawu会不会合并这个修改, who knows &amp;hellip;&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;cd /opt/&#xA;wget https://github.com/wendal/ssdb/archive/android2.zip&#xA;unzip android2.zip&#xA;cd ssdb-android2&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h2&gt;执行编译&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;需要指定3个变量 CXX CC TARGET_OS, 以使用对应的编译器及源码&lt;/p&gt;&#xA;&#xA;&lt;p&gt;CC 指定c源文件的编译器&lt;/p&gt;&#xA;&#xA;&lt;p&gt;CXX 指定cpp源文件的编译器&lt;/p&gt;&#xA;&#xA;&lt;p&gt;TARGET_OS 是ssdb的build.sh和leveldb构建脚本中,判断系统环境的属性,默认是通过uname -s获取,需要指定为OS_ANDROID_CROSSCOMPILE&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;CC=/opt/ndk-armv7/bin/arm-linux-androideabi-gcc CXX=/opt/ndk-armv7/bin/arm-linux-androideabi-g++ TARGET_OS=OS_ANDROID_CROSSCOMPILE make&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h2&gt;与原版的差异&lt;/h2&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;因为android下没有pthread_cancel, 所以, 修改了thread.h里面的WorkPool::stop方法,意味着线程池不可关闭.由于线程池仅在ssdb退出时关闭,所以没大影响&lt;/li&gt;&#xA;&lt;li&gt;没有使用jemalloc&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;h2&gt;性能测试&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;测试环境, 某全志A10开发板, 单核1G内存, 8G nand&lt;/p&gt;&#xA;&#xA;&lt;p&gt;cpu参数&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;root@android:/ # cat /proc/cpuinfo&#xA;Processor       : ARMv7 Processor rev 2 (v7l)&#xA;BogoMIPS        : 238.54&#xA;Features        : swp half thumb fastmult vfp edsp neon vfpv3&#xA;CPU implementer : 0x41&#xA;CPU architecture: 7&#xA;CPU variant     : 0x3&#xA;CPU part        : 0xc08&#xA;CPU revision    : 2&#xA;&#xA;Hardware        : sun4i&#xA;Revision        : 0000&#xA;Serial          : 07c1521b5654484880778253162367cb&#xA;root@android:/ #&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;内存状态&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;root@android:/ # free -m&#xA;             total         used         free       shared      buffers&#xA;Mem:           797          428          369            0            6&#xA;-/+ buffers:                421          376&#xA;Swap:            0            0            0&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;将ssdb-server和ssdb.conf传输到/dev/shm/ 内存目录下,开始执行&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;cd /dev/shm/&#xA;mkdir var&#xA;chmod 777 ssdb-server&#xA;./ssdb-server ssdb.conf&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;显示效果, 也许有人会问为啥数据文件夹也在/dev/shm下,那是因为, 放/sdcard跟/dev/shm测试结果没多少差别.&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;root@android:/dev/shm # ./ssdb-server ssdb.conf&#xA;ssdb 1.6.8.6&#xA;Copyright (c) 2012-2014 ideawu.com&#xA;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;跑ssdb-bench, 提醒一下,测试结果极其飘忽, qps从500到2500都出现过.&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;Copyright (c) 2013-2014 ideawu.com&#xA;&#xA;========== set ==========&#xA;qps: 1196, time: 8.360 s&#xA;========== get ==========&#xA;qps: 1704, time: 5.866 s&#xA;========== del ==========&#xA;qps: 1268, time: 7.883 s&#xA;========== hset ==========&#xA;qps: 897, time: 11.141 s&#xA;========== hget ==========&#xA;qps: 772, time: 12.944 s&#xA;========== hdel ==========&#xA;qps: 635, time: 15.733 s&#xA;========== zset ==========&#xA;qps: 1251, time: 7.992 s&#xA;========== zget ==========&#xA;qps: 1584, time: 6.311 s&#xA;========== zdel ==========&#xA;qps: 1631, time: 6.129 s&#xA;========== qpush ==========&#xA;qps: 1263, time: 7.912 s&#xA;========== qpop ==========&#xA;qps: 1463, time: 6.831 s&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h2&gt;用途&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Cubieboard可以跑ssdb了, 安卓机能跑ssdb了&amp;hellip; 其他场景自行补充&amp;hellip;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>用NDK编译Live555</title>
      <link>http://wendal.net/2014/04/29.html</link>
      <pubDate>2014-04-29 12:00:00 +0800</pubDate>
      <description>&lt;p&gt;针对 live555 2014.03.25和 live 2014.04.23 也就是当前最新咯.&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;准备工作&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;下载源码 &lt;a href=&#34;http://www.live555.com/liveMedia/public/&#34;&gt;http://www.live555.com/liveMedia/public/&lt;/a&gt; 该地址经常被X,请问候非圆校长&lt;/p&gt;&#xA;&#xA;&lt;p&gt;解压到一个空文件夹, 并将目录名从live改成jni&lt;/p&gt;&#xA;&#xA;&lt;p&gt;建一个文件, 叫 Android.mk&lt;/p&gt;&#xA;&#xA;&lt;p&gt;文件内容在 &lt;a href=&#34;https://gist.github.com/wendal/11399988&#34;&gt;https://gist.github.com/wendal/11399988&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;编译&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;在jni目录下执行&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;ndk-build&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;如无意外,在 libs/armeabi/ 生成一个so文件.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>为Golang程序打上编译标记</title>
      <link>http://wendal.net/2014/04/02.html</link>
      <pubDate>2014-04-02 12:00:00 +0800</pubDate>
      <description>&lt;p&gt;参考文章: &lt;a href=&#34;http://stackoverflow.com/questions/11354518/golang-application-auto-build-versioning&#34;&gt;http://stackoverflow.com/questions/11354518/golang-application-auto-build-versioning&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;昨天在查询怎么生成一个小体积的golang程序的时候,无意中发现这个文章.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;对于固定的代码,及固定的golang版本,下面的命令总是得到一模一样的程序&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;go build&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;有时候需要为每个编译都打上标记,不然真的很乱啊&lt;/p&gt;&#xA;&#xA;&lt;p&gt;演示用的golang代码&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;package main&#xA;&#xA;var _VERSION_ = &amp;quot;unknown&amp;quot;&#xA;&#xA;func main() {&#xA;    print(&amp;quot;http_su ver=&amp;quot; + _VERSION_ + &amp;quot;\n&amp;quot;)&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;编译时,加入需要的版本号信息,而不是直接去改main.go的源码&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;export TAG=v1.b.50&#xA;go build -ldflags &amp;quot;-X main._VERSION_ &#39;$TAG&#39;&amp;quot;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;运行结果:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;&amp;gt; go build&#xA;&amp;gt; ./demo&#xA;http_su ver=unknown&#xA;&amp;gt; export TAG=v.1.b.50&#xA;&amp;gt; go build -ldflags &amp;quot;-X main._VERSION_ &#39;$TAG&#39;&amp;quot;&#xA;&amp;gt; ./demo&#xA;http_su ver=v.1.b.50&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;可以看到, 版本号根据编译参数的变化而变化了. 关键点是, 必须是 $package.$varName&lt;/p&gt;&#xA;&#xA;&lt;p&gt;本demo在linux/macos/windows/arm下测试通过.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>JDK8 Access to Parameter Names at Runtime</title>
      <link>http://wendal.net/2014/03/30.html</link>
      <pubDate>2014-03-30 12:00:00 +0800</pubDate>
      <description>&lt;h2&gt;JDK 8的新特性之一, 运行时获取方法参数的名称&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;JDK8之前, Eclipse自带的ECJ编译器,同本地变量表,把方法参数的名字,放在最前面,使其编译出来的class的名字看推测.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;而 JDK8把这种行为规范化(终于&amp;hellip;) &lt;a href=&#34;http://openjdk.java.net/jeps/118&#34;&gt;http://openjdk.java.net/jeps/118&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;参考文章 &lt;a href=&#34;http://www.java-allandsundry.com/2013/12/java-8-parameter-name-at-runtime.html&#34;&gt;Java 8 parameter name at runtime&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;演示代码&lt;/h2&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;package nutz_jdk8;&#xA;&#xA;import java.lang.reflect.Constructor;&#xA;import java.lang.reflect.Parameter;&#xA;&#xA;public class Bot {&#xA;    private final String name;&#xA;    private final String author;&#xA;    private final int rating;&#xA;    private final int score;&#xA;&#xA;    public Bot(String name, String author, int rating, int score) {&#xA;        this.rating = rating; // 注意这里的顺序,并非按参数顺序逐一调用&#xA;        this.score = score;&#xA;        this.name = name;&#xA;        this.author = author;&#xA;    }&#xA;&#xA;    public static void main(String[] args) throws NoSuchMethodException, SecurityException {&#xA;        Class&amp;lt;Bot&amp;gt; clazz = Bot.class;&#xA;        Constructor ctor = clazz.getConstructor(String.class, String.class, int.class, int.class);&#xA;        Parameter[] ctorParameters =ctor.getParameters();&#xA;        for (Parameter param: ctorParameters) {&#xA;            System.out.println(param.isNamePresent() + &amp;quot;:&amp;quot; + param.getName());&#xA;        }&#xA;    }&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;输出的结果是:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;true:name&#xA;true:author&#xA;true:rating&#xA;true:score&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;然后, 这个特性并未默认启用,javac需要额外的参数&amp;rdquo;-parameters&amp;rdquo;&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;javac -parameters nutz_jdk8\Bot.java&#xA;java -cp nutz_jdk8.Bot&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;如果是Eclipse 4.4 (正式支持JDK8的初始版本), 则需要手动在&amp;rdquo;Java Compiler&amp;rdquo;中启用之&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2014/03/30/jep118_eclipse.jpg&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;如果是maven,则需要这段&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;&amp;lt;plugin&amp;gt;&#xA;    &amp;lt;groupId&amp;gt;org.apache.maven.plugins&amp;lt;/groupId&amp;gt;&#xA;    &amp;lt;artifactId&amp;gt;maven-compiler-plugin&amp;lt;/artifactId&amp;gt;&#xA;    &amp;lt;version&amp;gt;3.1&amp;lt;/version&amp;gt;&#xA;    &amp;lt;configuration&amp;gt;&#xA;        &amp;lt;source&amp;gt;1.8&amp;lt;/source&amp;gt;&#xA;        &amp;lt;target&amp;gt;1.8&amp;lt;/target&amp;gt;&#xA;        &amp;lt;compilerArgument&amp;gt;-parameters&amp;lt;/compilerArgument&amp;gt;&#xA;    &amp;lt;/configuration&amp;gt;&#xA;&amp;lt;/plugin&amp;gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h2&gt;JDK8 , 开始学习啦&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;开始学习新特性啦,哇哈哈&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>tcpdump加Wireshark抓包分析才是王道啊</title>
      <link>http://wendal.net/2014/0223.html</link>
      <pubDate>2014-02-23 12:00:00 +0800</pubDate>
      <description>&lt;p&gt;最近折腾RTSP协议,焦头乱额.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Receiver Report RTCP Packets (RR)&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;  Receiver Reports are structured in the same way as Sender Reports. Of course, they include no sender information block, and the packet type code is 201.&#xA; 0               1               2               3&#xA; 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1&#xA;+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&#xA;|V=2|P|    RC   |   PT=RR=201   |            length L           |&#xA;+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&#xA;|                     SSRC of packet sender                     |&#xA;+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+&#xA;|                 SSRC_1 (SSRC of first source)                 |&#xA;+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&#xA;| fraction lost |       cumulative number of packets lost       |&#xA;+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&#xA;|           extended highest sequence number received           |&#xA;+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&#xA;|                      inter-arrival jitter                     |&#xA;+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&#xA;|                         last SR (LSR)                         |&#xA;+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&#xA;|                   delay since last SR (DLSR)                  |&#xA;+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+&#xA;|                 SSRC_2 (SSRC of second source)                |&#xA;+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&#xA;:                               ...                             :&#xA;+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+&#xA;|                  profile-specific extensions                  |&#xA;+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;PS: github的pages默认使用Jekyll编译了,真是无语啊,必须自行加个文件才能发布成功了. 稍后要修正一下gor,默认产生这个文件才行&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&#34;https://help.github.com/articles/using-jekyll-with-pages#troubleshooting&#34;&gt;https://help.github.com/articles/using-jekyll-with-pages#troubleshooting&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;touch .nojekyll&#xA;git add .nojekyll&#xA;git commit -m &amp;quot;...&amp;quot;&#xA;git push&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;</description>
    </item>
    <item>
      <title>为pcduino编译内核</title>
      <link>http://wendal.net/2013/12/15.html</link>
      <pubDate>2013-12-15 12:00:00 +0800</pubDate>
      <description>&lt;h2&gt;软件环境&lt;/h2&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;lubuntu 13.10 amd64版 / Ubuntu Server 13.10 amd64版&lt;/li&gt;&#xA;&lt;li&gt;虚拟机20G硬盘,1G内存&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;为这篇教程,我全新安装多次lubuntu/ubuntu,验证过每个命令,保证能编译出一个能用的内核&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;安装依赖的库/工具&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;打开控制台,执行&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;sudo apt-get install -y g++-arm-linux-gnueabihf vim make u-boot-tools libusb-1.0-0-dev openssh-server pkg-config&#xA;sudo apt-get install -y texinfo ccache zlib1g-dev gawk bison flex gettext uuid-dev lib32stdc++6 curl wget ncurses-dev&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h2&gt;下载内核源码&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;推荐从百度网盘下载 &lt;a href=&#34;http://pan.baidu.com/s/1lCgBr&#34;&gt;pcduino内核源码打包下载&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;里面的均为github官网代码库的打包, 非git版删掉了.git目录,源码内容完全一样&lt;/p&gt;&#xA;&#xA;&lt;p&gt;从github下载(建议网速可以的才使用)&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;git clone https://github.com/pcduino/kernel.git&#xA;cd kernel&#xA;git submodule init&#xA;git submodule update       #会下载全志的sun4i内核源码, 慢慢等吧&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h2&gt;开始编译&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;打开shell,开始耗cpu吧!!&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;tar xf pcduino_kernel_20131127_nogit.gz   #如果是百度网盘下载的,就需要先解压咯,git下载的就无视这句了&#xA;&#xA;cd kernel&#xA;make clean&#xA;&#xA;cd sunxi-tools&#xA;make clean&#xA;cd ..&#xA;&#xA;./configure pcduino&#xA;make hwpack&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;最后输出的信息类似&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;  INSTALL output/lib/firmware/mts_gsm.fw&#xA;  INSTALL output/lib/firmware/mts_edge.fw&#xA;  INSTALL output/lib/firmware/edgeport/boot.fw&#xA;  INSTALL output/lib/firmware/edgeport/boot2.fw&#xA;  INSTALL output/lib/firmware/edgeport/down.fw&#xA;  INSTALL output/lib/firmware/edgeport/down2.fw&#xA;  INSTALL output/lib/firmware/edgeport/down3.bin&#xA;  INSTALL output/lib/firmware/whiteheat_loader.fw&#xA;  INSTALL output/lib/firmware/whiteheat.fw&#xA;  INSTALL output/lib/firmware/keyspan_pda/keyspan_pda.fw&#xA;  INSTALL output/lib/firmware/keyspan_pda/xircom_pgs.fw&#xA;  DEPMOD  3.4.29+&#xA;make[1]: Leaving directory `/home/wendal/kernel/linux-sunxi&#39;&#xA;cd /home/wendal/kernel/build/sun4i_defconfig-linux &amp;amp;&amp;amp; arm-linux-gnueabihf-objcopy -R .note.gnu.build-id -S -O binary vmlinux bImage&#xA;#git submodule init&#xA;#git submodule update cedarx-libs&#xA;scripts/mk_hwpack.sh /home/wendal/kernel/output/pcduino_a10_hwpack_20131215.tar.xz&#xA;Debian/Ubuntu hwpack&#xA;Done.&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;编译好的压缩包在output目录中,有日期标记,例如pcduino_a10_hwpack_20131215.tar.xz&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;自定义内核&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;跟大多数A10的板子一样,你可以修改2个配置文件(ps: android的话还有个分区文件)&lt;/p&gt;&#xA;&#xA;&lt;p&gt;第一个是内核配置文件,也就是编译内核时常见的.config文件&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;#编译成功后可以找到,但编译之前是没有的,可见这不是真正的配置文件&#xA;find -name .config&#xA;&amp;gt;&amp;gt; ./build/sun4i_defconfig-linux/.config&#xA;&#xA;#真正的配置文件在&#xA;find -name sun4i_defconfig&#xA;&amp;gt;&amp;gt; ./patch/linux-sunxi/arch/arm/configs/sun4i_defconfig&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;所以,需要先在build/sun4i_defconfig-linux/进行配置,然后覆盖回去&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;cd build/sun4i_defconfig-linux/&#xA;make menuconfig&#xA;# ... ... 配置你需要的选项&#xA;#..........&#xA;&#xA;#然后把配置直接覆盖回去,不然下一次build的时候依然是老的&#xA;cp .config ../../patch/linux-sunxi/arch/arm/configs/sun4i_defconfig&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;另外一个是uboot的配置,这个文件有很多很多好东西,看文档吧&lt;a href=&#34;http://linux-sunxi.org/Fex_Guide&#34;&gt;Fex指南&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;./sunxi-boards/sys_config/a10/pcduino.fex&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h2&gt;More?&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;我上传了一个ubuntu的vbox磁盘镜像, 用vbox新建一个虚拟机,选择这个文件作为主磁盘启动,即可拥有pcduino编译环境!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;镜像地址(还在上传中&amp;hellip;)&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>pcduino报告</title>
      <link>http://wendal.net/2013/12/08.html</link>
      <pubDate>2013-12-08 12:00:00 +0800</pubDate>
      <description>&lt;h2&gt;先上个图, 399大洋的货物&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/12/08/pcduino_1.jpg&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;5V2A供电, 带USB,hdmi,tf卡槽,wifi,及最有特殊的类arduino接口&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;功能&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;抛开arduino接口,pcduino就是一个单纯的A10开发板,跑linux和Android都没任何问题,这是全志A10提供的基本功能了&lt;/p&gt;&#xA;&#xA;&lt;p&gt;其arduino接口, 源于A10芯片自带的gpio/pwm等针脚,在linux层做了一个libarduino.so,适配arduino源码&lt;/p&gt;&#xA;&#xA;&lt;p&gt;通过其&lt;a href=&#34;https://github.com/pcduino/c_enviroment&#34;&gt;pcduino c_enviroment&lt;/a&gt;,可兼容arduino源文件,本质上就是个普通的C库.&#xA;使用其Makefile改造一下,可以实现跨平台编译,而不需要使用arduino ide(与eclipse相比真是烂得可以)&lt;/p&gt;&#xA;&#xA;&lt;p&gt;在QQ群中,很多人以为pcduino能直接跑编译好的arduino程序,而非把它当成linux+arduino库来看待.&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;arduino接口的细节&lt;/h2&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;提供一个UART接口。&lt;/li&gt;&#xA;&lt;li&gt;引出6个ADC。ADC0和ADC1是6bit的ADC分辨率，其余的都是10bit的ADC分辨率。&lt;/li&gt;&#xA;&lt;li&gt;提供2个硬件PWM，能支持最大24MHz的PWM。&lt;/li&gt;&#xA;&lt;li&gt;提供14个GPIO。&lt;/li&gt;&#xA;&lt;li&gt;提供一个I2C接口。&lt;/li&gt;&#xA;&lt;li&gt;提供一个SPI接口。&lt;/li&gt;&#xA;&lt;li&gt;有5V,3.3V输出&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;h2&gt;性价比&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;单单从板子的配置看,性价比不高, 其最大卖点就是提供了arduino库及对应的针脚&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>北京几张图</title>
      <link>http://wendal.net/2013/10/28.html</link>
      <pubDate>2013-10-28 12:00:00 +0800</pubDate>
      <description>&lt;p&gt;飞机着陆&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/10/28/IMG_0857.JPG&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;北京第一餐 &amp;ndash; 脑残酸菜撸肉面&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/10/28/IMG_0935.JPG&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;灰太狼大平卖 &amp;ndash; 只要9毛9!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/10/28/IMG_0954.JPG&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;后海 &amp;ndash; Three-Person&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/10/28/IMG_1723.JPG&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;离开北京那天, 灰霾爆表了&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/10/28/IMG_2007.JPG&#34; /&gt;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>让redis支持动态库</title>
      <link>http://wendal.net/2013/10/20.html</link>
      <pubDate>2013-10-20 12:00:00 +0800</pubDate>
      <description>&lt;h1&gt;So, let&amp;rsquo;s put some fun in redis&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;redis的命令列表是写死在代码里面,编译后就没法修改(跟nginx一个德行)&lt;/p&gt;&#xA;&#xA;&lt;h1&gt;硬编码一些额外的方法到redis中&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;最初写的一个hello world级的测试命令&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;void wendalCommand(redisClient *c) {&#xA;    struct timeval tv;           // 从timeCommand拷贝的...&#xA;    addReplyMultiBulkLen(c,3);   // 共返回3个结果&#xA;    addReplyBulkCString(c, &amp;quot;Hi,Wendal&amp;quot;); // 输出个字符串啦&#xA;    gettimeofday(&amp;amp;tv,NULL);              // 获取时间, 也是从timeCommand拷贝的&#xA;    addReplyBulkLongLong(c,tv.tv_sec);   // 不解释了&#xA;    addReplyBulkLongLong(c,tv.tv_usec);  // 不解释了&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;然后在redisCommandTable中声明一个新的命令,就搞定了&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;{&amp;quot;wendal&amp;quot;, wendalCommand,1,&amp;quot;rR&amp;quot;,0,NULL,0,0,0,0,0}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h1&gt;做得更灵活?上动态库,哈哈&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;so,我声明了2个新的命令, 加载/卸载动态库&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;    {&amp;quot;loadlib&amp;quot;,loadlibCommand,2,&amp;quot;wmaR&amp;quot;,0,NULL,0,0,0,0,0},&#xA;    {&amp;quot;unloadlib&amp;quot;,unloadlibCommand,2,&amp;quot;wmaR&amp;quot;,0,NULL,0,0,0,0,0}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;其中, 加载动态库,就是接受一个路径,并执行其redis_lib_init方法&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;// 简化版的loadlibCommand&#xA;void loadlibCommand(redisClient *c) {&#xA;    void *handle;&#xA;    char *error;&#xA;    int (*redis_lib_init)(redisClient*, dict*);&#xA;    int re;&#xA;    &#xA;    handle = dlopen(c-&amp;gt;argv[1]-&amp;gt;ptr, RTLD_LAZY);&#xA;    if (!handle) {&#xA;        addReplyError(c, dlerror());&#xA;        return;&#xA;    }&#xA;    redis_lib_init = dlsym(handle, &amp;quot;redis_lib_init&amp;quot;); // 查找redis_lib_init&#xA;    if ((error = dlerror()) != NULL)  {&#xA;        dlclose(handle);&#xA;        addReplyError(c, error);&#xA;        return;&#xA;    }&#xA;    re = redis_lib_init(c, server.commands); // 执行之, 返回0就成功&#xA;    if (re) {&#xA;        dlclose(handle);&#xA;        addReplyError(c, &amp;quot;lib init error&amp;quot;);&#xA;        return;&#xA;    }&#xA;    addReply(c,shared.ok);&#xA;    server.dirty ++;                        // 使dirty自增,这样就能同步到slave了&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h1&gt;redis动态库示例&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;禁用flushdb命令&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;#include &amp;lt;redis.h&amp;gt;&#xA;&#xA;static void* flushdb;&#xA;&#xA;extern int redis_lib_init(redisClient *c) {&#xA;    flushdb = dictFetchValue(server.commands, sdsnew(&amp;quot;FLUSHDB&amp;quot;)); // 命令列表就是server.commands中,一个dict&#xA;    if (!flushdb) return 1; // 找不到? 被其他库删掉了?&#xA;    dictDeleteNoFree(server.commands, sdsnew(&amp;quot;FLUSHDB&amp;quot;)); // 删除但不要执行free&#xA;    return 0;&#xA;}&#xA;&#xA;extern void redis_lib_depose(redisClient *c) {&#xA;    dictAdd(server.commands, sdsnew(&amp;quot;FLUSHDB&amp;quot;), flushdb); // 卸载的时候就赋值回去,呵呵&#xA;    return;&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h1&gt;项目地址&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&#34;https://raw.github.com/wendal/redis_plugins&#34;&gt;https://raw.github.com/wendal/redis_plugins&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&#34;https://raw.github.com/wendal/redis&#34;&gt;https://raw.github.com/wendal/redis&lt;/a&gt;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>perth归来</title>
      <link>http://wendal.net/2013/10/15.html</link>
      <pubDate>2013-10-15 12:00:00 +0800</pubDate>
      <description>&lt;h2&gt;其实已经回国几天了,但群里的狼友依然很high&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;奋斗吧,童鞋们 -_-&lt;/p&gt;&#xA;&#xA;&lt;h1&gt;perth是什么地方? 大概做了些啥?&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;西澳大利亚的首府, 西临南印度洋&lt;/p&gt;&#xA;&#xA;&lt;p&gt;阳光下睡个觉,海滩戏水,河边看美女,超市看各种降价,郊外看农场&lt;/p&gt;&#xA;&#xA;&lt;p&gt;总之,待了七天七夜,完整地走了perth的一周&lt;/p&gt;&#xA;&#xA;&lt;h1&gt;Day1 &amp;ndash; 阳光下睡个觉&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;3号晚上21:45的飞机,实际21:55起飞,直飞perth, 凌晨5:30到达&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/10/15/day1/M1320009.JPG&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/10/15/day1/M1320018.JPG&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/10/15/day1/M1320034.JPG&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/10/15/day1/M1320065.JPG&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;按最初的想法,以为my little girl会一直睡到目的地,结果却是各种折腾.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;飞机上没有长时间的熄灯与安静,外加发动机持续的轰鸣声,一家三口都没能睡上3个小时.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/10/15/day1/M1330021.JPG&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/10/15/day1/M1330039.JPG&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/10/15/day1/M1330041.JPG&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;下飞机,大家都很困,但还是要入境的嘛,例行的移民局查护照,盖章,领取行李接受检查,就出小插曲了.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;缉毒犬(我猜是吧)盯上了我们(次偶,10人队伍,就我们需要额外检查&amp;hellip;),工作人员指出饭盒是否有使用过(看来狗狗是饿了,开玩笑的),得到&#xA;否定的答复后,就让我们pass了(汗啊,吓得半死)&lt;/p&gt;&#xA;&#xA;&lt;p&gt;perth机场并不大,但是有4个航站楼,T4还是专门给必和必拓员工用的,奇葩啊&lt;/p&gt;&#xA;&#xA;&lt;p&gt;出口处就是各种租车,电话卡的店铺,然后我惊奇发现航站楼就2层&amp;hellip; 出口处旁边就是登机柜台&lt;/p&gt;&#xA;&#xA;&lt;p&gt;出示了护照,驾驶证,翻译件,预定单后, 10分钟左右就拿到了钥匙,然后就买了个$30的电话卡,果断电话回家报平安.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/10/15/day1/M1330043.JPG&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;当我们坐上车(澳洲本地产,类似于宝来),小鸣鸣按捺不住了,看来真困了,一看时间,已经8点了&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/10/15/day1/M1330049.JPG&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;硬着头皮,在GPS还没准备好的情况下开车了&amp;hellip; 绕了10分钟吧我猜,终于找到一个停车场,里面进去了&lt;/p&gt;&#xA;&#xA;&lt;p&gt;鸣鸣急不可耐地从安全座椅上挣脱出来,趴在妈咪的怀中就睡着了&lt;/p&gt;&#xA;&#xA;&lt;p&gt;就这样,没开空调,一家三口,开着窗户,就在阳光下的车厢中睡着了&lt;/p&gt;&#xA;&#xA;&lt;p&gt;醒来已经是10点,被乌鸦叫醒的(澳洲的乌鸦真是无处不在)&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/10/15/day1/M1330060.JPG&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;虽说是阳光下,但还是不觉得热,温度就20上下,很舒服, 到停车场旁边的KFC用生硬的英文买了个套餐,一家三口吃饱了,才调好GPS去酒店&lt;/p&gt;&#xA;&#xA;&lt;p&gt;GPS里面的提示,实在不习惯,外加右胎车,不熟悉的交通规则及路面标注,花了一个多小时才到了酒店附近&lt;/p&gt;&#xA;&#xA;&lt;p&gt;但依然看不懂路边复杂的停车标记,大胆地往酒店路边一停,老婆飞奔进了酒店,不一会,一位工作人员带着一个小纸条,告知停车的事宜,&#xA;也不记得当时是否听懂了,反正能把车停进去了(好吧,停车场里面其实也绕了5分钟,各种NO NOAUTH PACKING)&lt;/p&gt;&#xA;&#xA;&lt;p&gt;到处闲逛到下午2点左右,终于能入住了,一家人又睡了一觉&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/10/15/day1/M1330222.JPG&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;剩下的就是去苹果店买了台苹果呗,哈哈&lt;/p&gt;&#xA;&#xA;&lt;h1&gt;Day2 &amp;ndash; 袋鼠并非想象中那么美好&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;最初,我打算去距离酒店30km的一个野生动物园,但老婆依然担心我的车技,so,还是到附近的perth zoo&lt;/p&gt;&#xA;&#xA;&lt;p&gt;这perth zoo,我们Day1就路过,原因?走错路咯&amp;hellip;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;跟国内的动物园一样,就是看看各种动物,但入口是自行购票,没有栏杆!!买了票就自己走进去!! 虽然29刀/人,但这个zoo door,值了!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/10/15/day2/M1340064.JPG&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;澳洲小企鹅,黑天鹅,考拉,大象,长颈鹿,鳄鱼,鹦鹉,长臂猿的一家三口,犀牛,其实跟都是那些样子&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/10/15/day2/M1340078.JPG&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;但最最让我们印象深刻的,是袋鼠!!为啥呢?? 那股味道把鸣鸣弄哭了,真的&amp;rdquo;好难顶&amp;rdquo;!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/10/15/day2/M1340216.JPG&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;外加动物园内好吃好住,袋鼠个个都在晒太阳,懒洋洋到爆,而且为啥就看不到袋鼠的袋呢?!! 万马奔腾呢!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/10/15/day2/M1340219.JPG&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/10/15/day2/M1340231.JPG&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;饥渴难耐的小鸣鸣,终于扛不住了,拉着一个自动售货机不肯走,但没零钱啊,只好自身跑了半个动物园找到一家餐厅买了点东西,悲催啊&amp;hellip;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/10/15/day2/M1340424.JPG&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;傍晚时分,去了一趟West Perth的海滩,看海草与岩石,狗狗与健身的男女&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/10/15/day2/M1340461.JPG&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;h1&gt;Day3 &amp;ndash; 超市各种打折&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;由于动物园的刺激,我们决定去找超市储备粮食,幸运地找到了woodworth,一家我之前就留意过的澳洲连锁超市&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/10/15/day3/M1350021.JPG&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;0.99刀/L的鲜牛奶,5刀/整只的熟鸡,还有各种贵到吐血的蔬菜和水果&lt;/p&gt;&#xA;&#xA;&lt;p&gt;超市是自助结账,没有收银员&amp;hellip;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/10/15/day3/M1350052.JPG&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;中午时分的超市,并没有遇到多少中国人&lt;/p&gt;&#xA;&#xA;&lt;p&gt;下午去了趟Kings Park, 看当地小孩各种疯玩(自愧不如啊)&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/10/15/day3/M1350244.JPG&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/10/15/day3/M1350253.JPG&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;h1&gt;Day4 &amp;ndash; 鲨鱼在头顶路过,还有阳光与海滩&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;充足的食物,开始熟悉的路况车况交通规则,我们一早就往AQWA(The Aquarium of Western Australia)进发&lt;/p&gt;&#xA;&#xA;&lt;p&gt;依然绕错了路,也开始熟悉导航的指令,顺利到达海边的AQWA&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/10/15/day4/M1360003_small.jpg&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;AQWA旁边就是一个游艇码头,几百艘的样子吧,各种拍照免不了&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/10/15/day4/M1360008_small.jpg&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/10/15/day4/M1360025_small.jpg&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;水族馆里面,最出名的就是其水底隧道,看大鲨鱼大海龟从头顶路过,看各种大小的鱼穿梭&lt;/p&gt;&#xA;&#xA;&lt;p&gt;但最让我印象深刻的是暗室中的水母,实在太美了,相机根本拍不到那种美妙&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/10/15/day4/M1360120_small.jpg&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;水族馆向西就是大海,没有想象中那种蓝&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/10/15/day4/M1360173_small.jpg&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/10/15/day4/M1360245_small.jpg&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;从水族馆出来,周围逛了一下,才发现这是当地人游玩的地方,浅浅的海滩,小朋友各种玩耍&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/10/15/day4/M1360003_small.jpg&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;最最强悍的是,看到一个不到一岁,看样子刚刚会爬的小奶娃,在老爸的注视下,自行从沙滩爬到海浪里玩,OMG!~!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/10/15/day4/M1360282_small.jpg&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/10/15/day4/M1360319_small.jpg&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/10/15/day4/M1360367_small.jpg&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;晚上,又是woodworth,花掉了100刀啊,背包得很沉啊&lt;/p&gt;&#xA;&#xA;&lt;h1&gt;Day5 &amp;ndash; 郊外看农场&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;这是属于我的一天,在出发来perth之前就确定要去的northam airport, 距离perth城区100km, 94号公路上的较大城镇&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/10/15/day5/M1370003_small.jpg&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/10/15/day5/M1370019_small.jpg&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;94号公路,一直向东走,连接1号公里,通往阿德莱德,墨尔本等南澳大利亚城市.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;很多时候就是2车道,双向限速110公里,没有分隔带,相向的2台车的相对速度是220公里,每次遇到对面开过来的大货车就一顿心寒.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;去northam,仅仅是我的要求,去看看那个小小的airport,走走这条94号公路&lt;/p&gt;&#xA;&#xA;&lt;p&gt;出了perth city,就开始爬坡(其实是回来的时候才知道那么高),经过几个国家森林公园之后,就是各种农场.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;看过几次袋鼠出没的警示牌,但始终没看到野生袋鼠,算是个遗憾,绵羊倒是不少&lt;/p&gt;&#xA;&#xA;&lt;p&gt;路边各种野花,正在收割的小麦,还有airport里面的小型螺旋桨飞机,让人觉得很放松&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/10/15/day5/M1370020_small.jpg&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/10/15/day5/M1370034_small.jpg&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/10/15/day5/M1370042_small.jpg&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/10/15/day5/M1370034_small.jpg&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/10/15/day5/M1370034_small.jpg&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;h1&gt;Day6 &amp;ndash; 到处逛逛&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;在河边看看跑步经过的美女,搭乘CAT(Central Area Transit&amp;rsquo;s,perth的免费bus)走马观花&lt;/p&gt;&#xA;&#xA;&lt;p&gt;看了好久查了很多资料才弄懂的停车标注&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/10/15/day6/IMG_0156.JPG&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;在售的Car&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/10/15/day6/IMG_0157.JPG&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;中餐厅的菜牌,不知道是不是又只收现金?!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/10/15/day6/IMG_0158.JPG&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;咩表&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/10/15/day6/IMG_0162.JPG&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;中介的房屋出租信息&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/10/15/day6/IMG_0163.JPG&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;本地报纸&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/10/15/day6/IMG_0165.JPG&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;推销私人气象站设备,不知道在天朝是不是非法的&amp;hellip;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/10/15/day6/IMG_0166.JPG&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;h1&gt;Day7 &amp;ndash; 买啊买&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;最后一天了,累积了几天的购物经验,开始在perth city中购买各种东西,呵呵,这就没啥好说了,顺便去了趟机场,探探路&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/10/15/day7/IMG_0213.JPG&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/10/15/day7/IMG_0214.JPG&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/10/15/day7/IMG_0215.JPG&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/10/15/day7/IMG_0216.JPG&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;忍不住还是吃了顿中餐&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/10/15/day7/IMG_0218.JPG&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;h1&gt;Day8 &amp;ndash; 凌晨起床坐飞机&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;早上8:45的飞机,为了保险起见,5点就起床了, 冷啊冷(10度以下), 然后还看到短衣短裤的美女带着耳机在河边跑过,惊呆了!~!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;路上加油,加德士,全自助,弄了5分钟还是没搞懂,唯有硬着头皮请工作人员帮忙&lt;/p&gt;&#xA;&#xA;&lt;p&gt;还车的时候,比预约时间晚了半个小时,二话没说就pass了&lt;/p&gt;&#xA;&#xA;&lt;p&gt;登机行李限制23kg/件,结果有一件超过了,又是各种翻腾重新分配&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/10/15/day8/IMG_0320_small.jpg&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;退税,一直惦记着这事,结果发现TSC(旅客退税计划)的办理点,就在海关旁边,排队,10分钟搞定&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/10/15/day8/IMG_0322_small.jpg&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/10/15/day8/IMG_0376.JPG&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/10/15/day8/IMG_0380.JPG&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/10/15/day8/IMG_0387_small.jpg&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/10/15/day8/IMG_0418_small.jpg&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;h1&gt;关于租车&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;靠左行驶,对我这种老手来说还是严重不习惯,总是偏左,不时压线&lt;/p&gt;&#xA;&#xA;&lt;p&gt;澳洲租车,护照驾驶证当然省不了,还得要驾照的翻译件,淘宝100块钱搞定, 最最关键的是信用卡,不能带银联标志!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;西澳大利亚,全州限速110km,任何道路的最高限速了,出机场的时候就看到这个牌子,可以说每条路都表明限速,而且每个人都按限速的值狂飙&lt;/p&gt;&#xA;&#xA;&lt;p&gt;也就是94号公路这种,双向无间隔,都能来个110限速,各种大货车私家车在路上狂飙&lt;/p&gt;&#xA;&#xA;&lt;p&gt;路上几乎严格的避让规则, 转弯让直行,车辆让行人&lt;/p&gt;&#xA;&#xA;&lt;p&gt;举个例子, 你突然发现前方50米处就是你需要的高速公路出口(我已经干过这事,而且我是看过其他人这样做之后才敢的),&#xA;立马打转向灯,后面的车全部减速,然后你就可以按部就班地转入到出口去.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;又如某个车道封闭,那次我走到最前面,发现是封路了,打转向灯,目标车道的车就减速让我进入了.&lt;/p&gt;&#xA;&#xA;&lt;h1&gt;Perth印象&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;店铺9点开门5点关门,准时得很,星期六日还有不一样的营业时间(反正就是更短啦)&lt;/p&gt;&#xA;&#xA;&lt;p&gt;空气质量满分,对我这种深受呼吸道疾病困扰的人来说,简直就是解脱,喉咙没疼,鼻子通畅,OMG!&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Android系统配置数据库注释(settings.db)</title>
      <link>http://wendal.net/2013/09/23.html</link>
      <pubDate>2013-09-23 12:00:00 +0800</pubDate>
      <description>&lt;h1&gt;system表&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;参考: &lt;a href=&#34;http://developer.android.com/reference/android/provider/Settings.System.html&#34;&gt;http://developer.android.com/reference/android/provider/Settings.System.html&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;1|volume_music|11               // 媒体音量&#xA;2|volume_ring|5                 // 闹钟音量&#xA;3|volume_system|7               // 系统音量&#xA;4|volume_voice|4                // 通话音量&#xA;5|volume_alarm|6                // 警报音量&#xA;6|volume_notification|5         // 提示音的音量&#xA;7|volume_bluetooth_sco|7        // 蓝牙耳机的音量&#xA;8|mode_ringer|2                 // 情景模式. 0=静音,1=震动,2=普通&#xA;9|vibrate_on|10                 // 震动的级别&#xA;10|mode_ringer_streams_affected|166 // ...&#xA;11|mute_streams_affected|46     // ...&#xA;12|power_on_able|false          // 不清楚&#xA;13|default_screen_orientation|0 //默认屏幕方向, 0=横向,1=竖向&#xA;14|dim_screen|1                 // 自动调暗屏幕, 1自然就是开启咯&#xA;15|stay_on_while_plugged_in|0   // 插入电源时保持屏幕开启,不锁屏&#xA;16|screen_off_timeout|-1        // 屏幕超时,进入锁屏的耗时, -1自然是不启用咯&#xA;17|emergency_tone|0             // &#xA;18|call_auto_retry|0            // 呼叫失败后自动重拨&#xA;19|dtmf_tone_type|0             // &#xA;20|hearing_aid|0                //&#xA;21|tty_mode|0                   //&#xA;22|airplane_mode_on|0           // 飞行模式&#xA;23|airplane_mode_radios|cell,bluetooth,wifi,nfc,wimax // 飞行模式下,需要关闭的设备&#xA;24|airplane_mode_toggleable_radios|bluetooth,wifi,nfc //&#xA;25|auto_time|1                  // 从移动网络自动获取时间, 据说中国移动和中国联通均不支持&#xA;26|auto_time_zone|1             // 从移动网络自动获取时区&#xA;27|screen_brightness|102        // 屏幕亮度&#xA;28|screen_brightness_mode|0     // 屏幕亮点自动调节&#xA;29|window_animation_scale|1.0   // 窗口动画-缩放&#xA;30|transition_animation_scale|1.0 // 依然是窗口动画&#xA;31|accelerometer_rotation|1     // 屏幕自动旋转&#xA;32|haptic_feedback_enabled|1    // 虚拟按键的反馈&#xA;33|notification_light_pulse|1   // 提示灯&#xA;34|set_install_location|0       // 允许设置安装位置&#xA;35|default_install_location|0   // 允许设置缺省的安装位置&#xA;36|power_sounds_enabled|1       // 开机关机的声音&#xA;37|low_battery_sound|/system/media/audio/ui/LowBattery.ogg // 低电量的警告语,极其恶心那个&#xA;38|dtmf_tone|1&#xA;39|sound_effects_enabled|1      // 声音效果&#xA;41|dock_sounds_enabled|0        // 插入或移除设备的时候,&amp;quot;叫&amp;quot;~~&#xA;42|desk_dock_sound|/system/media/audio/ui/Dock.ogg // 插入时的叫声&#xA;43|desk_undock_sound|/system/media/audio/ui/Undock.ogg // 拔出时的叫声&#xA;44|car_dock_sound|/system/media/audio/ui/Dock.ogg  //车载模式下,插入的叫声&#xA;45|car_undock_sound|/system/media/audio/ui/Undock.ogg //车载模式下,拔出的叫声&#xA;46|lockscreen_sounds_enabled|0  // 屏幕加锁解锁的声音&#xA;47|lock_sound|/system/media/audio/ui/Lock.ogg // 加锁的声音&#xA;48|unlock_sound|/system/media/audio/ui/Unlock.ogg //解锁的声音&#xA;49|vibrate_in_silent|1          // 静音时启用震动&#xA;50|pointer_speed|0              // 不知道...&#xA;51|accelerometer_coordinate|default&#xA;52|is_scan_tf_card|1            // 是否扫描sdcard&#xA;53|hidden_google_application|0  // 隐藏google应用&#xA;54|time_12_24|24                // 时间按12小时制还是24小时制&#xA;55|display_adaption_mode|center // 屏幕适配模式&#xA;56|is_scan_usb_host|1           // 扫描U盘不?&#xA;57|shortcut_key_0|website--split--http://tv.sohu.com // 快捷键0, 我XX&#xA;58|shortcut_key_1|website--split--http://v.qq.com/   // 快捷键1, 我XX&#xA;59|shortcut_key_2|app--split--com.android.settings--split--com.android.settings.Settings // 快捷键2, 我XX&#xA;60|shortcut_key_3|app--split--com.softwinner.TvdFileManager--split--com.softwinner.TvdFileManager.MainUI // 快捷键3, 我XX&#xA;61|display_adapter_enable|1     // 自动适配显示设备&#xA;62|display_area_ratio|100       // 显示的区域&#xA;63|smart_brightness_enable|0    // 自动调整屏幕亮度&#xA;66|mouse_advance|30             // USB鼠标的设置? 不清楚&#xA;67|color_brightness|50          // RGB的调色&#xA;68|color_contrast|50            // RGB的调色&#xA;69|color_saturation|50          // RGB的调色&#xA;70|audio_output_type|NORMAL     // 音频输出类型&#xA;71|audio_output_channel|HDMI    // 音频输出的通道 -- 可以查audiomode表, 见过: HDMI VGA LVDS&#xA;72|directly_power_off|1         // 直接关闭电源,无需再次确认&#xA;73|bd_folder_play_mode|1        // 蓝光目录模式, 当打开蓝光光盘格式的目录时,自动开始播放 -- XX&#xA;74|hdmi_output_mode|255         // hdmi的输出模式,无解中&#xA;75|display_output_format|HDMI 1080P 60HZ // 显示输出的模式,这个太重要了,可选模式? 因机器而异的...&#xA;76|first_boot_system|true       // 是否为第一次启动, 不准确的值&#xA;77|alarm_alert|content://media/internal/audio/media/9 //警告音&#xA;78|notification_sound|content://media/internal/audio/media/50 // 提示音&#xA;79|ringtone|content://media/internal/audio/media/124 // 闹钟&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h1&gt;secure 表&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;参考1: &lt;a href=&#34;http://developer.android.com/reference/android/provider/Settings.Global.html#DATA_ROAMING&#34;&gt;http://developer.android.com/reference/android/provider/Settings.Global.html#DATA_ROAMING&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;参考2: &lt;a href=&#34;http://developer.android.com/reference/android/provider/Settings.Secure.html&#34;&gt;http://developer.android.com/reference/android/provider/Settings.Secure.html&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;1|bluetooth_on|0                // 是否开启蓝牙&#xA;2|data_roaming|0                // 数据漫游&#xA;3|install_non_market_apps|1     // 安装非认证的程序--100%是开启啦(1)&#xA;4|location_providers_allowed|gps // 允许使用的定位方式, gps&#xA;5|assisted_gps_enabled|1        // 是否开启agps&#xA;6|network_preference|1          // &#xA;7|usb_mass_storage_enabled|1    // 允许使用U盘&#xA;8|wifi_on|1                     // 启用wifi&#xA;9|wifi_networks_available_notification_on|1 // 有可用网络的时候提示一下&#xA;10|wifi_country_code|EU         // wifi国家码,鬼知道啥东西,反正都一样&#xA;11|eth_on|1                     // 开启有线网络,就是网卡啦...&#xA;12|eth_conf|1                   // 启用有线网络的配置&#xA;13|eth_mode|1                   // 有线网络的模式: 1=dhcp 0=静态ip&#xA;14|eth_ifname|eth0              // 端口名, 一般就是eth0啦&#xA;15|preferred_network_mode|0     // 优选网络模式&#xA;16|cdma_cell_broadcast_sms|1    // &#xA;17|preferred_cdma_subscription|1&#xA;18|mock_location|1              // 是否允许模拟地址信息&#xA;19|backup_enabled|0             // 是否启用备份&#xA;20|backup_transport|android/com.android.internal.backup.LocalTransport&#xA;21|mount_play_not_snd|1&#xA;22|mount_ums_autostart|0&#xA;23|mount_ums_prompt|1&#xA;24|mount_ums_notify_enabled|1&#xA;25|accessibility_script_injection|0&#xA;26|accessibility_web_content_key_bindings|0x13=0x01000100; 0x14=0x01010100; 0x15=0x02000001; 0x16=0x02010001; 0x200000013=0x02000601; 0x200000014=0x02010601; 0x&#xA;200000015=0x03020101; 0x200000016=0x03010201; 0x200000023=0x02000301; 0x200000024=0x02010301; 0x200000037=0x03070201; 0x200000038=0x03000701:0x03010701:0x030207&#xA;01;&#xA;27|long_press_timeout|500&#xA;28|touch_exploration_enabled|0&#xA;29|speak_password|0&#xA;30|default_input_method|com.android.inputmethod.latin/.LatinIME // 默认输入法&#xA;31|pppoe_interface|eth0         // pppop的端口,就是ADSL咯&#xA;32|pppoe_auto_conn|0            // pppop自动连接&#xA;33|pppoe_enable|0               // 启用pppop&#xA;34|lockscreen.options|enable_facelock //锁屏设置&#xA;35|android_id|a906a1d1a3c594c   // android id?不知道神马东西&#xA;37|enabled_input_methods|com.android.inputmethod.latin/.LatinIME:jp.co.omronsoft.openwnn/.OpenWnnJAJP // 可用的输入法&#xA;38|input_methods_subtype_history| &#xA;39|selected_input_method_subtype|-1&#xA;40|selected_spell_checker|com.android.inputmethod.latin/.spellcheck.AndroidSpellCheckerService&#xA;41|selected_spell_checker_subtype|0&#xA;42|eth_ip|                     // 网卡的ip&#xA;43|eth_dns|                    // 网卡的dns&#xA;44|eth_route|                  // 网卡的route&#xA;45|eth_netmask|                // 网卡的掩码&#xA;46|adb_enabled|1               // 是否启动adb&#xA;47|throttle_reset_day|3        &#xA;48|device_provisioned|1&#xA;49|dropbox:data_app_wtf|disabled&#xA;50|ssl_session_cache|file&#xA;51|facelock_detection_threshold|0.0&#xA;52|dropbox:data_app_crash|disabled&#xA;53|send_action_app_error|1&#xA;54|dropbox:data_app_anr|disabled&#xA;55|web_autofill_query_url|http://android.clients.google.com/proxy/webautofill&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;最后说一句, id不是固定的,就是个自增的值而已&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>记录一下jetty的异步请求</title>
      <link>http://wendal.net/2013/09/06.html</link>
      <pubDate>2013-09-06 12:00:00 +0800</pubDate>
      <description>&lt;h1&gt;nutz加jetty 的测试代码&lt;/h1&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;    @At&#xA;    @Ok(&amp;quot;void&amp;quot;) //不要视图啊... 因为多次进入&#xA;    @Fail(&amp;quot;void&amp;quot;)// 一样不需要...&#xA;    public void async(final @Param(&amp;quot;wait&amp;quot;)long wait, @Attr(&amp;quot;obj&amp;quot;)Object obj, final HttpServletRequest req) {&#xA;        System.out.println(&amp;quot;async IN&amp;quot;);&#xA;        if (obj == null) { // 第一次进入时,必然是null, 第二次,如果是线程唤醒的,那就有值了,呵呵&#xA;            System.out.println(&amp;quot;OBJ NULL&amp;quot;);&#xA;            // 获取这个关键的对象,哈哈哈&#xA;            final Continuation continuation = ContinuationSupport.getContinuation(req);&#xA;            if (continuation.isExpired()) { // 往下的代码设置了超时,so,这样判断一下咯&#xA;                System.out.println(&amp;quot;async TIMEOUT&amp;quot;);&#xA;                return;&#xA;            }&#xA;            continuation.setTimeout(15*1000); //设置超时哦&#xA;            continuation.suspend(); // 非阻塞的方法... 仅仅是设置一个状态&#xA;            new Thread() { //我在这启动一个线程,休眠一定时间之后唤醒这个异步请求&#xA;                public void run() {&#xA;                    System.out.println(&amp;quot;async Thread Start&amp;quot;);&#xA;                    if (wait &amp;lt; 1) {&#xA;                        Lang.quiteSleep(10 * 1000);&#xA;                    } else {&#xA;                        Lang.quiteSleep(wait * 1000);&#xA;                    }&#xA;                    System.out.println(&amp;quot;async Thread wakeup&amp;quot;);&#xA;                    req.setAttribute(&amp;quot;obj&amp;quot;, &amp;quot;I do it!&amp;quot;);&#xA;                    continuation.resume();&#xA;                };&#xA;            }.start();&#xA;        } else {&#xA;            System.out.println(&amp;quot;async GET OBJ --&amp;gt; &amp;quot; + obj);&#xA;        }&#xA;        &#xA;        System.out.println(&amp;quot;async OUT&amp;quot;);&#xA;    }&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;简单来说,就是多次进入入口方法.通过&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>让golang的get命令兼容gitlab</title>
      <link>http://wendal.net/2013/08/28.html</link>
      <pubDate>2013-08-28 12:00:00 +0800</pubDate>
      <description>&lt;h1&gt;我们有些什么呢?&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;Gitlib已经发布了6.0,号称是企业级的版本了,作为私有git库的首选,自然越来越多人用&lt;/p&gt;&#xA;&#xA;&lt;p&gt;假设 有这样一个golang 的库,URL是 &lt;a href=&#34;http://git.wendal.net/wendal/gofly&#34;&gt;http://git.wendal.net/wendal/gofly&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;如果尝试执行下面的语句去获取这个库的话&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;go get git.wendal.net/wendal/gofly&#xA;&#xA;#会输出&#xA;package git.wendal.net/wendal/gofly: unrecognized import path &amp;quot;git.wendal.net/wendal/gofly&amp;quot;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;然而,如果我们输入&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;go get git.wendal.net/wendal/gofly.git&#xA;&#xA;#会输出&#xA;fatal: repository &#39;git.wendal.net/wendal/gofly&#39; does not exist&#xA;package git.wendal.net/wendal/gofly.git: exit status 128&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h1&gt;为什么呢?貌似go get不支持自定义的库地址啊(git的)&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;且看 $GOROOT/src/cmd/go/vcs.go里面的一段代码&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;    // General syntax for any server.&#xA;    {&#xA;        re:   `^(?P&amp;lt;root&amp;gt;(?P&amp;lt;repo&amp;gt;([a-z0-9.\-]+\.)+[a-z0-9.\-]+(:[0-9]+)?/[A-Za-z0-9_.\-/]*?)\.(?P&amp;lt;vcs&amp;gt;bzr|git|hg|svn))(/[A-Za-z0-9_.\-]+)*$`,&#xA;        ping: true,&#xA;    },&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;可以看到, 对于未知的库地址(非github/Google Code/Bitbucket/Launchpad),都按这里的配置进行设置&lt;/p&gt;&#xA;&#xA;&lt;p&gt;按上述的正则表达式,输入git.wendal.net/wendal/gofly可以得到&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;root = git.wendal.net/wendal/gofly&#xA;repo = git.wendal.net/wendal/gofly&#xA;vcs  = git&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;What? 当使用git进行clone的时候,其实就执行了&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;git clone $repo $GOPATH/src/$root&#xA;#展开之后(假设GOPATH=/opt/gopath)&#xA;git clone git.wendal.net/wendal/gofly /opt/gopath/src/git.wendal.net/wendal/gofly&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;git库的地址当成本地路径了,不出错才怪呢&lt;/p&gt;&#xA;&#xA;&lt;h1&gt;怎么解决呢? 添加自定义的库地址,跟github类似&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;首先,拷贝一份github的配置&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;    // Github&#xA;    {&#xA;        prefix: &amp;quot;github.com/&amp;quot;,&#xA;        re:     `^(?P&amp;lt;root&amp;gt;github\.com/[A-Za-z0-9_.\-]+/[A-Za-z0-9_.\-]+)(/[A-Za-z0-9_.\-]+)*$`,&#xA;        vcs:    &amp;quot;git&amp;quot;,&#xA;        repo:   &amp;quot;https://{root}&amp;quot;,&#xA;        check:  noVCSSuffix,&#xA;    },&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;改成&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;    // git.xwoods.org&#xA;    {&#xA;        prefix: &amp;quot;git.wendal.net/&amp;quot;,&#xA;        re:   `^(?P&amp;lt;root&amp;gt;git\.wendal\.net/(?P&amp;lt;p&amp;gt;.[A-Za-z0-9_.\-]+/[A-Za-z0-9_.\-]+))(/[A-Za-z0-9_.\-]+)*))$`,&#xA;        ping:   false,&#xA;        repo:   &amp;quot;git@git.wendal.net:{p}.git&amp;quot;,&#xA;        vcs :   &amp;quot;git&amp;quot;,&#xA;    },&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;注意 re和repo,做了特别处理哦,多一个p变量, 这样repo就把凑成标准的ssh式git地址,自动使用密钥(哈哈,私有库嘛)&lt;/p&gt;&#xA;&#xA;&lt;p&gt;最后,还需要把golang编译&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;# linux/mac 下&#xA;$GOROOT/src/make.bash&#xA;&#xA;#windows下&#xA;cd %GOROOT%\src\cmd\go&#xA;go install&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;</description>
    </item>
    <item>
      <title>再说Ioc</title>
      <link>http://wendal.net/2013/08/23.html</link>
      <pubDate>2013-08-23 12:00:00 +0800</pubDate>
      <description>&lt;p&gt;很多人都没搞懂Ioc到底什么原理,搞不懂里面有什么魔术.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;注: 不讨论JavaAgent/JNI/动态类创建/自定义ClassLoader/自定义JVM下的行为&lt;/p&gt;&#xA;&#xA;&lt;p&gt;这些gif我曾经在nutz群中发送多次,但多少人真的看懂了&amp;hellip;&lt;/p&gt;&#xA;&#xA;&lt;h1&gt;首先,看第一种理解 &amp;ndash; 加几个注解,对象就能注入&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/08/23/nutz_ioc_inject_not.gif&#34;&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;上面的@Inject是Nutz Ioc的注解,你可以替换成Spring之类的注解,完全没有区别.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;运行即可看到, 变量dao为null,但为什么呢? 已经加了@Inject注解了啊&lt;/p&gt;&#xA;&#xA;&lt;h1&gt;再看第二种理解 &amp;ndash; 加了注解,有Ioc容器,就能注入&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/08/23/nutz_ioc_inject_not2.gif&#34;&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;明明加了注解,而且Ioc容器(可替换为其他任何ioc容器)也启动了,为啥还是null呢?&lt;/p&gt;&#xA;&#xA;&lt;h1&gt;到底什么东西能被注入?&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;首先,被注入的,必须是个对象,而非一个类 &amp;ndash; 注解仅仅是ioc配置信息,这些配置信息可以通过js/xml/yaml/数据库记录甚至UI操作来读取&lt;/p&gt;&#xA;&#xA;&lt;p&gt;然后,必须是ioc管理的对象 &amp;ndash; 由ioc容器,通过某种方法(一般就是反射API的newInstance方法)创建的对象&lt;/p&gt;&#xA;&#xA;&lt;p&gt;就是说, 一个对象要被注入某个属性, 必须由ioc容器创建,根据配置信息进行组装,然后用户通过ioc的api直接/间接获取到.&lt;/p&gt;&#xA;&#xA;&lt;h1&gt;如何知道某个对象是否是ioc管理?&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;由于没有API可以获知一个已知对象的创建过程,所以只能在对象创建时进行跟踪&lt;/p&gt;&#xA;&#xA;&lt;p&gt;在Java中,一个对象的生成,要么new,要么反射newInstance,但总得调用其构造方法&lt;/p&gt;&#xA;&#xA;&lt;p&gt;所以,我们可以在构造方法中加入这样的代码,检测是不是ioc容器创建对象&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;        // 获取调用构造方法的堆栈信息&#xA;        // eles[0]指向Thread,eles[1]指向构造方法&#xA;        StackTraceElement[] eles = Thread.currentThread().getStackTrace();&#xA;        // 反射的特征类(仅针对Sun JDK和OpenJDK)&#xA;        if (eles[2].getClassName().startsWith(&amp;quot;sun.reflect&amp;quot;) || eles[2].getClassName().startsWith(&amp;quot;java.lang.reflect&amp;quot;)) {&#xA;            log.debug(getClass() + &amp;quot; Born using reflect&amp;quot;);&#xA;            for (int i = 2; i &amp;lt; eles.length; i++) {&#xA;                StackTraceElement stackTraceElement = eles[i];&#xA;                String className = stackTraceElement.getClassName();&#xA;                if (className.startsWith(&amp;quot;sun.reflect&amp;quot;) || className.startsWith(&amp;quot;java.lang.reflect&amp;quot;))&#xA;                    continue;&#xA;                log.debug(getClass() + &amp;quot; Born by --&amp;gt; &amp;quot; + className);&#xA;                break; //必须考虑到嵌套生成的情况,仅查找第一个非反射调用&#xA;            }&#xA;        } else {&#xA;            // 当对象通过 new XXXX(...)方式创建,就会打印下面的log&#xA;            log.debug(getClass() + &amp;quot; Born using new&amp;quot;);&#xA;        }&#xA;        //上述代码如果放在独立的方法中,那么堆栈index要相应增加&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h1&gt;剩下的,就是配置信息是否正确的问题了&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;注解到底是什么?在字节码中,就是一个新增的属性罢了,注解并非可执行的代码,换句话说,他们没法被执行,只有其他代码读取他们.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;而注解如何就变成ioc的配置呢?这纯粹就是ioc容器的约定罢了,规定某些符合规律的注解组合与值,可以转化为抽象的配置对象&lt;/p&gt;&#xA;&#xA;&lt;p&gt;这些抽象的配置对象,一样可以通过js/xml等一切可描述文档,数据,甚至UI输入,硬编码进行构建,IOC容器往往都把这一层抽象了.&#xA;不同配置方式得到的最终的配置对象,总是一样的.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>用openresty做redis订阅发布</title>
      <link>http://wendal.net/2013/08/09.html</link>
      <pubDate>2013-08-09 12:00:00 +0800</pubDate>
      <description>&lt;p&gt;openresty依然很强大,先上服务器端的代码, 定义一个通用的订阅接口&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;    location =/subscribe {&#xA;        send_timeout 365h; #很久很久很久,呵呵&#xA;        content_by_lua &amp;quot;&#xA;        local redis = require \&amp;quot;resty.redis\&amp;quot;&#xA;        local red = redis:new()&#xA;        red:connect(\&amp;quot;127.0.0.1\&amp;quot;, 6379)&#xA;        red:subscribe(ngx.var.arg_key) -- 严格来说,需要判断空值和url decode&#xA;        local res, err = red:read_reply()&#xA;        if res then &#xA;            ngx.say(res) -- 其实是个数组.. 第3个值才是publish的值&#xA;        else&#xA;            ngx.status = 500&#xA;        end&#xA;        red:close()&#xA;        &amp;quot;;&#xA;    }&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;客户端? 简单啦,Nutz一行代码搞定&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;String str = Sender.create(url).setTimeout(60*60*1000).send().getContent();&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;</description>
    </item>
    <item>
      <title>Ubuntu12.04下asoundrc不起效</title>
      <link>http://wendal.net/2013/07/25.html</link>
      <pubDate>2013-07-25 12:00:00 +0800</pubDate>
      <description>&lt;p&gt;因为要配置asound,所以用到~/.asoundrc, 但ubuntu下总是没效果的样子&lt;/p&gt;&#xA;&#xA;&lt;p&gt;最后,终于发现这个痕迹&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;wendal@ubuntu:~$ aplay -L&#xA;default&#xA;    Playback/recording through the PulseAudio sound server&#xA;sysdefault:CARD=I82801AAICH&#xA;    Intel 82801AA-ICH, Intel 82801AA-ICH&#xA;    Default Audio Device&#xA;front:CARD=I82801AAICH,DEV=0&#xA;    Intel 82801AA-ICH, Intel 82801AA-ICH&#xA;    Front speakers&#xA;surround40:CARD=I82801AAICH,DEV=0&#xA;    Intel 82801AA-ICH, Intel 82801AA-ICH&#xA;    4.0 Surround output to Front and Rear speakers&#xA;surround41:CARD=I82801AAICH,DEV=0&#xA;    Intel 82801AA-ICH, Intel 82801AA-ICH&#xA;    4.1 Surround output to Front, Rear and Subwoofer speakers&#xA;surround50:CARD=I82801AAICH,DEV=0&#xA;    Intel 82801AA-ICH, Intel 82801AA-ICH&#xA;    5.0 Surround output to Front, Center and Rear speakers&#xA;surround51:CARD=I82801AAICH,DEV=0&#xA;    Intel 82801AA-ICH, Intel 82801AA-ICH&#xA;    5.1 Surround output to Front, Center, Rear and Subwoofer speakers&#xA;iec958:CARD=I82801AAICH,DEV=0&#xA;    Intel 82801AA-ICH, Intel 82801AA-ICH&#xA;    IEC958 (S/PDIF) Digital Audio Output&#xA;dmix:CARD=I82801AAICH,DEV=0&#xA;    Intel 82801AA-ICH, Intel 82801AA-ICH&#xA;    Direct sample mixing device&#xA;dsnoop:CARD=I82801AAICH,DEV=0&#xA;    Intel 82801AA-ICH, Intel 82801AA-ICH&#xA;    Direct sample snooping device&#xA;hw:CARD=I82801AAICH,DEV=0&#xA;    Intel 82801AA-ICH, Intel 82801AA-ICH&#xA;    Direct hardware device without any conversions&#xA;plughw:CARD=I82801AAICH,DEV=0&#xA;    Intel 82801AA-ICH, Intel 82801AA-ICH&#xA;    Hardware device with all software conversions&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;最可疑的就是default这段,在我之前测试的centos 5.6上是没有的&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;default&#xA;    Playback/recording through the PulseAudio sound server&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;果断卸载之,管他是啥&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;sudo apt-get autoremove pulseaudio&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;重启,搞定,哦也!!&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>篮子里的鸡蛋</title>
      <link>http://wendal.net/2013/07/04.html</link>
      <pubDate>2013-07-04 12:00:00 +0800</pubDate>
      <description>&lt;p&gt;一个鸡蛋,一块吐司&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/07/04/1.jpg&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;成品&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/07/04/2.jpg&#34; /&gt;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>py2exe练手</title>
      <link>http://wendal.net/2013/07/03.html</link>
      <pubDate>2013-07-03 12:00:00 +0800</pubDate>
      <description>&lt;p&gt;受老同学所托,写了个字符串抽样的东西(就是N个字符串抽取固定的几个),代码如下:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;#!python&#xA;# -*- coding: UTF-8 -*-&#xA;&#xA;import os.path&#xA;import time&#xA;import sys&#xA;import itertools &#xA;import random&#xA;&#xA;if not os.path.exists(&amp;quot;numbers.txt&amp;quot;) :&#xA;    print u&amp;quot;没找到数据文件 numbers.txt&amp;quot;&#xA;    time.sleep(5)&#xA;    sys.exit()&#xA;&#xA;with open(&amp;quot;numbers.txt&amp;quot;) as f :&#xA;    d = str(f.read())&#xA;&#xA;#print d&#xA;numbs = d.split(&amp;quot;,&amp;quot;)&#xA;#print numbs, u&amp;quot;长度&amp;quot; ,len(numbs)&#xA;&#xA;re = itertools.combinations(numbs, 5) #内置的一个库,so easy&#xA;re = list(re)&#xA;random.shuffle(re)                    #把顺序打乱,哈哈&#xA;&#xA;with open(&amp;quot;re.csv&amp;quot;, &amp;quot;w&amp;quot;) as f:        #按同学要求,输出为csv文件&#xA;    for p in re :&#xA;        f.write(&#39;, &#39;.join(str(x) for x in p))&#xA;        f.write(&amp;quot;\n&amp;quot;)&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;然后?就是py2exe做成可执行文件了&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;from distutils.core import setup&#xA;import py2exe&#xA;&#xA;setup(console=[&amp;quot;main.py&amp;quot;])&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;非常简单的执行&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;python setup.py py2exe&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;搞定,哈哈&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>微信公众平台开发小结</title>
      <link>http://wendal.net/2013/07/02.html</link>
      <pubDate>2013-07-02 12:00:00 +0800</pubDate>
      <description>&lt;p&gt;只讨论低权限帐号,高端帐号请绕道&amp;hellip;&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;能做什么?不能做什么?&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;应答机,自主查询机都能做,但由于没法主动推送(除非你能拿到很高的权限),所以呢,什么预警系统的,一时半刻做不了&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;机制&lt;/h2&gt;&#xA;&#xA;&lt;h1&gt;基本流程&lt;/h1&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;用户发信息  --&amp;gt;微信服务器--&amp;gt;我们的服务器&#xA;&#xA;用户显示信息&amp;lt;--微信服务器&amp;lt;--&#xA;&#xA;#如果是图文信息,就有额外的通信&#xA;&#xA;用户访问图文--&amp;gt;我们的服务器&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h1&gt;基本限制&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&#34;http://mp.weixin.qq.com/wiki/index.php&#34;&gt;开发文档&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;所有都是基于http,服务器发给你的是xml,你响应的也是xml&lt;/li&gt;&#xA;&lt;li&gt;必须在5秒内响应,必须是合法格式&lt;/li&gt;&#xA;&lt;li&gt;xml的节点名与文档必须完全一样&lt;/li&gt;&#xA;&lt;li&gt;文本信息必须小于2k字节&lt;/li&gt;&#xA;&lt;li&gt;图文信息每次最多10个&amp;rdquo;作品&amp;rdquo;,每个都有标题,简单描述,图片链接,链接&lt;/li&gt;&#xA;&lt;li&gt;图文信息的图,是直接访问你的服务器然后显示&lt;/li&gt;&#xA;&lt;li&gt;注意图片的缓存问题,同一个URL在多次响应中,是不会重复访问&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;h1&gt;goweixin的那些代码&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&#34;https://github.com/wendal/goweixin&#34;&gt;项目地址https://github.com/wendal/goweixin&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;核心代码之一,签名校验&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;func Verify(token string, timestamp string, nonce string, signature string) bool {&#xA;    if DevMode {&#xA;        return true&#xA;    }&#xA;    strs := []string{token, timestamp, nonce}&#xA;    sort.Strings(strs)                 //需要按值进行排序,蛋疼不?&#xA;    key := strs[0] + strs[1] + strs[2] //接着拼起来 &#xA;    if _Debug {&#xA;        log.Println(&amp;quot;Verify key=&amp;quot;, key)&#xA;    }&#xA;    h := sha1.New()                    //然后算sha1&#xA;    h.Write([]byte(key))&#xA;    re := fmt.Sprintf(&amp;quot;%x&amp;quot;, h.Sum(nil))&#xA;    if _Debug {&#xA;        log.Println(&amp;quot;Verify&amp;quot;, signature, re)&#xA;    }&#xA;    return signature == re            // golang嘛,字符串直接比较值&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h1&gt;一点提醒&lt;/h1&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;使用&lt;a href=&#34;http://www.bluestacks.com/&#34;&gt;bluestacks&lt;/a&gt;在电脑上安装微信,可以抛开手机进行调试&lt;/li&gt;&#xA;&lt;li&gt;一定一定要把生成的xml打印出来检测哦,错误的响应,微信不会有任何提示!!&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;h1&gt;实例消息&lt;/h1&gt;&#xA;&#xA;&lt;h2&gt;订阅通知&lt;/h2&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;&amp;lt;xml&amp;gt;&amp;lt;ToUserName&amp;gt;&amp;lt;![CDATA[gh_2dc74cccf555]]&amp;gt;&amp;lt;/ToUserName&amp;gt;&#xA;&amp;lt;FromUserName&amp;gt;&amp;lt;![CDATA[oSmHgjqYZN7zD4pOjsb_jK88wKFs]]&amp;gt;&amp;lt;/FromUserName&amp;gt;&#xA;&amp;lt;CreateTime&amp;gt;1372736407&amp;lt;/CreateTime&amp;gt;&#xA;&amp;lt;MsgType&amp;gt;&amp;lt;![CDATA[event]]&amp;gt;&amp;lt;/MsgType&amp;gt;&#xA;&amp;lt;Event&amp;gt;&amp;lt;![CDATA[subscribe]]&amp;gt;&amp;lt;/Event&amp;gt;&#xA;&amp;lt;EventKey&amp;gt;&amp;lt;![CDATA[]]&amp;gt;&amp;lt;/EventKey&amp;gt;&#xA;&amp;lt;/xml&amp;gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h2&gt;文本信息&lt;/h2&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;&amp;lt;xml&amp;gt;&amp;lt;ToUserName&amp;gt;&amp;lt;![CDATA[gh_2dc74cccf555]]&amp;gt;&amp;lt;/ToUserName&amp;gt;&#xA;&amp;lt;FromUserName&amp;gt;&amp;lt;![CDATA[oSmHgjqYZN7zD4pOjsb_jK88wKFs]]&amp;gt;&amp;lt;/FromUserName&amp;gt;&#xA;&amp;lt;CreateTime&amp;gt;1372736658&amp;lt;/CreateTime&amp;gt;&#xA;&amp;lt;MsgType&amp;gt;&amp;lt;![CDATA[text]]&amp;gt;&amp;lt;/MsgType&amp;gt;&#xA;&amp;lt;Content&amp;gt;&amp;lt;![CDATA[演示信息]]&amp;gt;&amp;lt;/Content&amp;gt;&#xA;&amp;lt;MsgId&amp;gt;5895859052130344107&amp;lt;/MsgId&amp;gt;&#xA;&amp;lt;/xml&amp;gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h2&gt;文本响应&lt;/h2&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;&amp;lt;Content&amp;gt;&amp;lt;![CDATA[Hi,&#xA;你好啊&#xA;]]&amp;gt;&amp;lt;/Content&amp;gt;&#xA;&amp;lt;xml&amp;gt;&#xA;&amp;lt;FromUserName&amp;gt;&amp;lt;![CDATA[gh_2dc74cccf555]]&amp;gt;&amp;lt;/FromUserName&amp;gt;&#xA;&amp;lt;ToUserName&amp;gt;&amp;lt;![CDATA[oSmHgjqYZN7zD4pOjsb_jK88wKFs]]&amp;gt;&amp;lt;/ToUserName&amp;gt;&#xA;&amp;lt;MsgType&amp;gt;&amp;lt;![CDATA[text]]&amp;gt;&amp;lt;/MsgType&amp;gt;&#xA;&amp;lt;CreateTime&amp;gt;1372736571&amp;lt;/CreateTime&amp;gt;&#xA;&amp;lt;FuncFlag&amp;gt;0&amp;lt;/FuncFlag&amp;gt;&#xA;&amp;lt;/xml&amp;gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h2&gt;图文响应&lt;/h2&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;&amp;lt;xml&amp;gt;&#xA;&amp;lt;MsgType&amp;gt;&amp;lt;![CDATA[news]]&amp;gt;&amp;lt;/MsgType&amp;gt;&#xA;&amp;lt;ArticleCount&amp;gt;&amp;lt;![CDATA[6]]&amp;gt;&amp;lt;/ArticleCount&amp;gt;&#xA;&amp;lt;Articles&amp;gt;&amp;lt;item&amp;gt;&amp;lt;Title&amp;gt;&amp;lt;![CDATA[北京达诺视通]]&amp;gt;&amp;lt;/Title&amp;gt;&#xA;&amp;lt;PicUrl&amp;gt;&amp;lt;![CDATA[http://www.danoonetworks.com/css/imgs/logo.png]]&amp;gt;&amp;lt;/PicUrl&amp;gt;&#xA;&amp;lt;Url&amp;gt;&amp;lt;![CDATA[http://www.danoonetworks.net]]&amp;gt;&amp;lt;/Url&amp;gt;&#xA;&amp;lt;/item&amp;gt;&#xA;&amp;lt;item&amp;gt;&amp;lt;Title&amp;gt;&amp;lt;![CDATA[V1 2013-07-02 11:42:03]]&amp;gt;&amp;lt;/Title&amp;gt;&#xA;&amp;lt;PicUrl&amp;gt;&amp;lt;![CDATA[http://wx.wendal.net/snap/zhaoxun/1372737416.jpg?id=8589943729]]&amp;gt;&amp;lt;/PicUrl&amp;gt;&#xA;&amp;lt;Url&amp;gt;&amp;lt;![CDATA[http://wx.wendal.net/snap/zhaoxun/index.html?id=8589943729]]&amp;gt;&amp;lt;/Url&amp;gt;&#xA;&amp;lt;/item&amp;gt;&#xA;&amp;lt;item&amp;gt;&amp;lt;Title&amp;gt;&amp;lt;![CDATA[VZ 2013-07-02 11:56:01]]&amp;gt;&amp;lt;/Title&amp;gt;&#xA;&amp;lt;PicUrl&amp;gt;&amp;lt;![CDATA[http://wx.wendal.net/snap/zhaoxun/1372737416.jpg?id=8589943893]]&amp;gt;&amp;lt;/PicUrl&amp;gt;&#xA;&amp;lt;Url&amp;gt;&amp;lt;![CDATA[http://wx.wendal.net/snap/zhaoxun/index.html?id=8589943893]]&amp;gt;&amp;lt;/Url&amp;gt;&#xA;&amp;lt;/item&amp;gt;&#xA;&amp;lt;item&amp;gt;&amp;lt;Title&amp;gt;&amp;lt;![CDATA[V2 2013-06-26 10:47:08]]&amp;gt;&amp;lt;/Title&amp;gt;&#xA;&amp;lt;PicUrl&amp;gt;&amp;lt;![CDATA[http://wx.wendal.net/snap/zhaoxun/1372737416.jpg?id=8589941622]]&amp;gt;&amp;lt;/PicUrl&amp;gt;&#xA;&amp;lt;Url&amp;gt;&amp;lt;![CDATA[http://wx.wendal.net/snap/zhaoxun/index.html?id=8589941622]]&amp;gt;&amp;lt;/Url&amp;gt;&#xA;&amp;lt;/item&amp;gt;&#xA;&amp;lt;item&amp;gt;&amp;lt;Title&amp;gt;&amp;lt;![CDATA[V3 2013-07-02 11:56:04]]&amp;gt;&amp;lt;/Title&amp;gt;&#xA;&amp;lt;PicUrl&amp;gt;&amp;lt;![CDATA[http://wx.wendal.net/snap/zhaoxun/1372737416.jpg?id=8589935214]]&amp;gt;&amp;lt;/PicUrl&amp;gt;&#xA;&amp;lt;Url&amp;gt;&amp;lt;![CDATA[http://wx.wendal.net/snap/zhaoxun/index.html?id=8589935214]]&amp;gt;&amp;lt;/Url&amp;gt;&#xA;&amp;lt;/item&amp;gt;&#xA;&amp;lt;item&amp;gt;&amp;lt;Title&amp;gt;&amp;lt;![CDATA[V4 2013-07-02 11:42:23]]&amp;gt;&amp;lt;/Title&amp;gt;&#xA;&amp;lt;PicUrl&amp;gt;&amp;lt;![CDATA[http://wx.wendal.net/snap/zhaoxun/1372737416.jpg?id=8589956309]]&amp;gt;&amp;lt;/PicUrl&amp;gt;&#xA;&amp;lt;Url&amp;gt;&amp;lt;![CDATA[http://wx.wendal.net/snap/zhaoxun/index.html?id=8589956309]]&amp;gt;&amp;lt;/Url&amp;gt;&#xA;&amp;lt;/item&amp;gt;&#xA;&amp;lt;/Articles&amp;gt;&#xA;&amp;lt;FromUserName&amp;gt;&amp;lt;![CDATA[gh_2dc74cccf555]]&amp;gt;&amp;lt;/FromUserName&amp;gt;&#xA;&amp;lt;ToUserName&amp;gt;&amp;lt;![CDATA[oSmHgjqYZN7zD4pOjsb_jK88wKFs]]&amp;gt;&amp;lt;/ToUserName&amp;gt;&#xA;&amp;lt;CreateTime&amp;gt;1372737330&amp;lt;/CreateTime&amp;gt;&#xA;&amp;lt;FuncFlag&amp;gt;0&amp;lt;/FuncFlag&amp;gt;&#xA;&amp;lt;/xml&amp;gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;</description>
    </item>
    <item>
      <title>在windows下编译OpenResty</title>
      <link>http://wendal.net/2013/06/25.html</link>
      <pubDate>2013-06-25 12:00:00 +0800</pubDate>
      <description>&lt;p&gt;折腾了一天,终于解决了&lt;/p&gt;&#xA;&#xA;&lt;h1&gt;首先,准备cygwin环境&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;cygwin下载setup.exe,启动并开始安装,建议选163源或者日本的源,速度较快&lt;/p&gt;&#xA;&#xA;&lt;p&gt;需要的安装的包及其devel包:&#xA;openssl zlib pcre&lt;/p&gt;&#xA;&#xA;&lt;p&gt;还有就是一些编译需要的工具:&#xA;gcc4 make perl lua  (不使用openresty内置的lua)&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/06/25/cygwin_install.jpg&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/06/25/cygwin_install2.jpg&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;下载openresty, &lt;a href=&#34;http://openresty.org/&#34;&gt;openresty官网&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;并解压到 C:\cygwin\tmp下&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/06/25/openresty_download.jpg&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;h1&gt;修正lua的C模块编译脚本&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;共需要修正3个文件(其实就是3个模块),而且都是一样的修改. 版本号日新月异,自己搞定啦&lt;/p&gt;&#xA;&#xA;&lt;p&gt;打开 C:\cygwin\tmp\ngx_openresty-1.2.8.6\bundle\lua-cjson-1.0.3\Makefile, 加入 -llua5.1&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/06/25/cjson_fix.jpg&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;然后就是如法炮制,修正rds和redis处理模块&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/06/25/rds_fix.jpg&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/06/25/redis_fix.jpg&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;h1&gt;开始编译吧,童鞋们!&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;启动cgywin&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/06/25/cygwin_startup.jpg&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;开始执行配置,注意,这里使用系统的lua,而非openresty内置的lua,原因就是cjson等模块会找不到内置的lua(配一下也可以,但麻烦)&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;cd /tmp/ngx_openresty-1.2.8.6&#xA;&#xA;./configure --without-select_module --prefix=/opt/openresty --with-lua51=/usr&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/06/25/openresty_configure.jpg&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;开始编译(按你的实际情况设置并发数哦,不然很久很久的)&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;make -j8                  #8就是内核数,并行编译,按你的实际情况而定&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/06/25/openresty_make.jpg&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;编译完成&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/06/25/openresty_make_done.jpg&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;h1&gt;安装那点小事&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;如果你直接执行make install, 你会看到这些错误(也许?)&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/06/25/default_install_fail.jpg&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;这个我也纠结了一段时间,然后改成这样执行,注意是/opt2,而非原本的/opt&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;make install DSETDIR=/opt2&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/06/25/install_opt2.jpg&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;你以为完了?其实还没有,你需要把名字改回去&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;rm -fr /opt/openresty&#xA;mv /opt2/opt/openresty /opt/&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h1&gt;先简单测试一下&lt;/h1&gt;&#xA;&#xA;&lt;h2&gt;测试最基本的配置文件检查&lt;/h2&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;/opt/openresty/nginx/sbin/nginx.exe -t&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/06/25/openresty_simple_test.jpg&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;然后就是测试核心的lua调用&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;打开nginx.conf文件,添加一个location&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;        location /lua/hi {&#xA;            content_by_lua &#39;ngx.say(&amp;quot;LUA Here&amp;quot;)&#39; ;&#xA;        }&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;保存,启动nginx, 然后curl一下看看&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;/opt/openresty/nginx/sbin/nginx.exe&#xA;curl -v http://127.0.0.1/lua/hi&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/06/25/openresty_lua_hi.jpg&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;h1&gt;测试数据库连接&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;数据库的resty.mysql库需要LuaBitOP库(汗,为啥openresty不包含?)&lt;/p&gt;&#xA;&#xA;&lt;p&gt;下载LuaBitOP库, &lt;a href=&#34;http://bitop.luajit.org/download.html&#34;&gt;猛击下载地址&lt;/a&gt;,并解压到C:\cygwin\tmp下&lt;/p&gt;&#xA;&#xA;&lt;p&gt;惯例了,修正编译参数&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/06/25/bitop_fix.jpg&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;编译然后拷贝到openresty的lualib&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;cd /tmp/LuaBitOp-1.0.2&#xA;make&#xA;cp bit.so /opt/openresty/lualib&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;接下来,就是修改nginx.conf,加上官方的&lt;a href=&#34;https://github.com/agentzh/lua-resty-mysql&#34;&gt;测试例子&lt;/a&gt;了&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;        location /lua/mysql {&#xA;            content_by_lua &#39;&#xA;            &#xA;            local mysql = require &amp;quot;resty.mysql&amp;quot;&#xA;            local db, err = mysql:new()&#xA;            if not db then&#xA;                ngx.say(&amp;quot;failed to instantiate mysql: &amp;quot;, err)&#xA;                return&#xA;            end&#xA;&#xA;            -- 省略1000字,自行到官网拷贝吧&#xA;            &#39; ;&#xA;        }&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;让nginx重新加载配置,然后访问之&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;/opt/openresty/nginx/sbin/nginx.exe -s reload&#xA;curl -v http://127.0.0.1/lua/mysql&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;哦也,上截图&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/06/25/openresty_mysql_test.jpg&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;h1&gt;打完收工!! 但有啥不足呢?&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;没有luajit,反正我没弄出来, configure阶段总是找不到库,不管了,windows就不那么追求性能了&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>马来西亚,闲游</title>
      <link>http://wendal.net/2013/06/14.html</link>
      <pubDate>2013-06-14 12:00:00 +0800</pubDate>
      <description>&lt;h1&gt;严重声明&lt;/h1&gt;&#xA;&#xA;&lt;h2&gt;很多图,慎入!!&lt;/h2&gt;&#xA;&#xA;&lt;h2&gt;超级啰嗦,慎入!!&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;你还是想看?好吧&amp;hellip; 不同情你&lt;/p&gt;&#xA;&#xA;&lt;h1&gt;旅游是最好的投资&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;4天的马来西亚之行,是首次真正的出国之行,而且还真的是自由行了&lt;/p&gt;&#xA;&#xA;&lt;p&gt;出发: 2013-06-10 10:20 亚航 AK1013 白云机场&lt;/p&gt;&#xA;&#xA;&lt;p&gt;返航: 2013-06-13 16:05 亚航 AK1016 马来西亚LCCT机场&lt;/p&gt;&#xA;&#xA;&lt;p&gt;花费: 1.5w/4人 -_- 泪奔进行时,大部分都是机票酒店的钱&lt;/p&gt;&#xA;&#xA;&lt;h1&gt;护照和签证&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;护照是一早就办好了,200元,户籍所在地的办证大厅办理一下,20个工作日搞定.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;马来西亚签证算是最简单签证吧,只需要护照原件和2寸照片,直接去使馆的话80RMB,但我选择代送,168RMB,4天搞定&lt;/p&gt;&#xA;&#xA;&lt;p&gt;PS: 现在已经涨价到130了,泪奔吧&amp;hellip;,想省钱就自己送签吧,就在中信,2张2寸照片就行&lt;/p&gt;&#xA;&#xA;&lt;h1&gt;机票&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;亚航的机票依然是最便宜的,但由于是上有老下有小,不能简单挑选最便宜的航班.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;故,选择了早上出发,下午返航,价位偏高咯(人均2.5k),大小同价&lt;/p&gt;&#xA;&#xA;&lt;p&gt;网上好多好多攻略都是拿到什么特价机票,我是没那个本事了,呵呵,机票人均2.2k往返&lt;/p&gt;&#xA;&#xA;&lt;h1&gt;托运行李&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;出发预定了25kg,实际使用了20kg,返航预定了55kg,实际使用了26kg,明显就是浪费了不少钱&lt;/p&gt;&#xA;&#xA;&lt;p&gt;原因很简单,老婆没准我买大米,我原本打算买20kg的,哇哈哈&lt;/p&gt;&#xA;&#xA;&lt;h1&gt;货币&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;一般是100人民币对46马来西亚币,就RM46元,但银行ATM提款能到RM51(RM500实际扣了976人民币,算上10人民币的手续费),非常超值,比任何兑换点都高&lt;/p&gt;&#xA;&#xA;&lt;p&gt;所以,见到ATM你就提款吧!! 不必到处找兑换点&lt;/p&gt;&#xA;&#xA;&lt;h1&gt;飞机餐&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;往返均预定了3份饭,1份椰子汁,事实上证明口味均为负分滚粗啦.事实证明,偷偷带点食物,其实没问题的&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;值机&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;由于预定了座位(15元/人),故,提前了好多天就打印了Boarding Pass.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;白云机场,亚航的位置是H或J值机口(貌似会变化,很神奇)&lt;/p&gt;&#xA;&#xA;&lt;p&gt;护照和自行打印的机票,统统交给柜台的MM,不一会就打印了红色的登机牌.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;然后,行李过磅,贴上条形码.值得一提的是,随身行李也需要贴纸.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;亚航的规定手提行李是7kg+小挎包/电脑包(不称重的哦),你懂得啦&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/06/14/IMG_20130610_080835.jpg&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/06/14/IMG_20130610_082450.jpg&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;h1&gt;等待登机&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;分配的登机口是107,提着小包,快速通过安检和海关(需要拍照),对自己人还是很宽容的&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/06/14/IMG_20130610_085729.jpg&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;9点已经到达登机口,但亚航的飞机还没出现,跟小鸣鸣看飞机咯&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/06/14/IMG_20130610_085734.jpg&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/06/14/IMG_20130610_090112.jpg&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/06/14/IMG_20130610_091733.jpg&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;h1&gt;小鸣鸣有点烦躁了&amp;hellip;.&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/06/14/IMG_20130610_092824.jpg&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;h1&gt;亚航的飞机终于到了&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;机上的乘客正准备下机.. 次偶,真是省啊,离我的航班只剩下半小时了,够紧凑的&#xA;&lt;img src=&#34;/assets/media/2013/06/14/IMG_20130610_094341.jpg&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;h1&gt;这时候,一台飞机走过&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;怎么那么大呢,为什么呢&amp;hellip;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/06/14/IMG_20130610_094504.jpg&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;次偶,原来是A380了,对比之下,亚航的A320好小啊-_-&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/06/14/IMG_20130610_094658.jpg&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;再来一张,四发双层,好羡慕啊^_^&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/06/14/IMG_20130610_100523.jpg&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;h1&gt;飞机上,哪里是天,哪里是海呢?这是个问题.&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;刚起飞时,还是能看到陆地的&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/06/14/IMG_20130610_110549.jpg&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;然后&amp;hellip; 我发现&amp;hellip; 小鸣鸣睡着了&amp;hellip;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/06/14/IMG_20130610_112512.jpg&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;h1&gt;飞机餐来袭&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;本来就飞机餐的预期就不大,但还是被外包装吸引了(凭登机牌的尾联确认座位后派发)&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/06/14/IMG_20130610_115956.jpg&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;才说着呢,小鸣鸣闻到香味了,起床吃饭了&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/06/14/IMG_20130610_121533.jpg&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;机舱除了我身后2位no show都坐满了,满满的各种调味料的味道&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/06/14/IMG_20130610_123159.jpg&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;h1&gt;接近降落&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;起飞后3小时,我开始头皮发麻,脑袋发晕&amp;hellip; 然后,我终于又看到陆地了&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/06/14/IMG_20130610_140927.jpg&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;好吧,事实上在飞行过程中,我看到了海岛(西沙群岛?),机场,还有越南的小城市.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;为啥我知道那是越南? 看这个地址吧, &lt;a href=&#34;http://zh.flightaware.com/live/flight/AXM1013&#34;&gt;AK1013飞行记录图&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;不知道啥原因,飞机绕到马六甲海峡,然后回来,so,我看到不少油轮&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/06/14/IMG_20130610_143607.jpg&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;h1&gt;菜市场一样的LCCT&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;如网上攻略所说,全部都是楼梯下飞机,现场跟菜市场差不多&lt;/p&gt;&#xA;&#xA;&lt;p&gt;原本想多拍几张飞机的照片,机务人员不停的催赶 &lt;em&gt;-&lt;/em&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/06/14/IMG_20130610_144935.jpg&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;入境,前往酒店&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;经过长长的走廊,真的很长的啊,期间还不停地吸飞机尾气,因为离飞机不到50米!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;进入室内的时候,有个岔口,上楼就是入籍,左转就是联程,标志很明显,但还是有人走错了.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;入境大厅有一个货币兑换点,100/46的样子,比较坑(照片太模糊了,不上了)&lt;/p&gt;&#xA;&#xA;&lt;p&gt;排队准备入境时,看到几个被带走的旅客(啥情况呢?不清楚&amp;hellip; 我XXX)&lt;/p&gt;&#xA;&#xA;&lt;p&gt;到我的时候,工作人员让我一家三口同时上,然后,很神奇的,不需要按指纹,并非网上所说的必须按&lt;/p&gt;&#xA;&#xA;&lt;p&gt;而且,工作人员一句话都没说,也没要求我出示回程机票(就塞在包里呢),就盖章pass了&lt;/p&gt;&#xA;&#xA;&lt;p&gt;下楼梯,回到1楼的时候(开头上楼的了嘛),当头就是Tune talk的服务台,这时候,我忽然想起没打印行程单.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;我万马奔腾啊&amp;hellip; 开电脑找,我X,pdf被删了,好吧,试试我的英语吧.&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;me: er,I book sim card in airasia, er, online , er , how can I provive(貌似发错音了) it ?&#xA;MM: I need you booking number&#xA;me: what????... -_- (没听清啊大姐)&#xA;MM: booking ... number ...&#xA;me: ok!! ... ... (狂翻电脑包,哦也,找到了,原来订单号就ok嘛) , here, thank you&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;MM翻看了电脑上的文档, 目测是Excel,然后选了2个sim卡&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;MM: I need your passport&#xA;me: one or two?&#xA;MM: one&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;哦也,我能对话了&amp;hellip; 递上护照&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;MM: active it?&#xA;me: (what.... 哦,激活?!!) No, I will do it myself. (我日,为啥我要自己激活呢?!!)&#xA;MM: ok. (然后就用笔写上*100#   1  同2行,我觉得我看懂了...)&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;待我满头大汗的拿到了sim卡,老妈和老婆已经提着行李回来了&lt;/p&gt;&#xA;&#xA;&lt;p&gt;然后就是兑换货币啦,拿出我特意办的华夏借记卡,ATM拿钱,结果,XXX,没现钞!!!!!!!!!!!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;我又万马奔腾啊,旁边就是这家银行的柜台,分明就是要人工兑换,&lt;sup&gt;100&lt;/sup&gt;&amp;frasl;&lt;sub&gt;47&lt;/sub&gt;,忍了!!&lt;/p&gt;&#xA;&#xA;&lt;h1&gt;如何去酒店呢?&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;准备离开到达大厅的时候,有几个售票亭,售卖Taxi票和Bus票.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;按我原本的计划,是坐摆渡Bus到KLIA机场(真正的大机场),然后坐机场轻轨,最后坐Taxi去酒店&lt;/p&gt;&#xA;&#xA;&lt;p&gt;So,无视了这些售票亭,兴冲冲的跑到外面去找摆渡Bus,结果,-_-找不到,我XXX&lt;/p&gt;&#xA;&#xA;&lt;p&gt;好吧,硬着头皮,从边上偷偷进入到达大厅(直接无视工作人员的手势),在Taxi票的地方,开了张票&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/06/14/IMG_20130610_161942.jpg&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;原本预算是RM120,结果开了张RM118的Taxi票,没说什么就付钱了(后来才知道多坑爹啊&amp;hellip;)&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;酒店,4星啊!!厨房,有木有?!&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;路上的风景没啥说的了,全程紧绷神经,生怕被载到荒山野岭了(网上好多攻略说Taxi坑爹,我也怕啊)&lt;/p&gt;&#xA;&#xA;&lt;p&gt;结果,无惊无险,除了小塞车了几分钟,顺利到达酒店(难道是因为付了足够的费用,赚足了?)&lt;/p&gt;&#xA;&#xA;&lt;p&gt;酒店的气派一般般啦,前台只有一个大妈(奔腾中)&lt;/p&gt;&#xA;&#xA;&lt;p&gt;拿出预定单,对话开始了&amp;hellip;&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;me: I book this (递上打印好的预定单)&#xA;MM: I need your passport (指了指预订单上的英文姓名)&#xA;me: ok, (递上护照)&#xA;MM: (转身去办公室,复印了我的护照,并且在复印纸上按了个啥章)&#xA;MM: sign here, here (原来早已经打印好相关文件,就差签名)&#xA;me: chinese or ? (小心驶得万年船)&#xA;MM: up to you&#xA;me: (好吧,分明是给机会show我的中文书法!!)&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;10楼,恩,有点低,算了(其实,原因是不知道改房间怎么讲)&lt;/p&gt;&#xA;&#xA;&lt;p&gt;窗外的马路,听不到汽车的声音,但&amp;hellip;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/06/14/IMG_20130611_081604.jpg&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;晚上入睡前,才发现,我XX,摩托车的声音才是王道啊,响彻云霄啊!! 好吧,我的隔音耳塞上场了&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/06/14/IMG_20130611_081611.jpg&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;吃饭的时候也到了,在酒店对面吃了一顿穆斯林餐厅的美食,胃口没了&amp;hellip;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;马路对面是超市,哈哈,好多东西买(半数以上是进口货),顺便买了小番茄给鸣鸣吃&lt;/p&gt;&#xA;&#xA;&lt;p&gt;价钱嘛, 800/晚,2个独立卧式&lt;/p&gt;&#xA;&#xA;&lt;h1&gt;早餐劵&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;房费中已经包含了早餐,比较一般的马来西亚式早餐(我瞎编的),面包火腿肠炒饭各种酱料&lt;/p&gt;&#xA;&#xA;&lt;h1&gt;KLCC&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;双子塔还是要去一下的,参观要RM80,就没上去了,因为不是登顶,而且价格太贵&lt;/p&gt;&#xA;&#xA;&lt;p&gt;第一天的时候,我们是步行到Ampang Park轻轨站,然后坐一个站到KLCC站,出站就是KLCC&lt;/p&gt;&#xA;&#xA;&lt;p&gt;路上买的牛奶,RM2&#xA;&lt;img src=&#34;/assets/media/2013/06/14/IMG_20130611_104450.jpg&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;霸气不?&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/06/14/DSCF0933.JPG&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;KLCC的价目表,说是每天限量,估计这么贵也卖不完吧,懒得去问了&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/06/14/IMG_20130611_110414.jpg&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;在KLCC下的KFC吃中午餐&#xA;&lt;img src=&#34;/assets/media/2013/06/14/IMG_20130611_130012.jpg&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;h1&gt;KL Tower&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;吃完午餐,前往今天主力景点,吉隆坡塔,由于没有轻轨,就走过去了,途中还下雨了&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/06/14/IMG_20130611_132439.jpg&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;原以为RM20就能登顶(网上攻略是这样是说的啊),结果要RM49,万马奔腾啊!!好在小鸣鸣免费,算是省了点&lt;/p&gt;&#xA;&#xA;&lt;p&gt;塔上瞻仰吉隆坡的风景&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/06/14/DSCF0967.JPG&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;拿了份旅游地图,研究一下先&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/06/14/DSCF0994.JPG&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;远远看到大雨将至&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/06/14/IMG_20130611_140017.jpg&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;但一直没等到,算了,下楼,结果,XXX,暴雨了!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/06/14/IMG_20130611_152734.jpg&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;老婆跟一位马来西亚美女搭讪上了&amp;hellip; 教我们做免费bus回酒店,准备抓拍一张,结果,对不起啊&amp;hellip; 真的是美女的啊&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/06/14/IMG_20130611_165635.jpg&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;h1&gt;吉隆坡的轻轨和旅游地图&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;吉隆坡轻轨全图,价钱便宜量又足! 基本上RM3到处都能ok&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/06/14/KLMap_RailTransportion.gif&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;每个站都有自己的名字,例如Ampang Park是KJ9站,Taman Bahagia是KJ23站(去吃榴莲自助餐)&lt;/p&gt;&#xA;&#xA;&lt;p&gt;旅游地图&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/06/14/klmap.jpg&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;图片来至于 &lt;a href=&#34;http://www.visionkl.com/kl-map&#34;&gt;VisionKL&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;h1&gt;云顶&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;云顶其实是个赌场,但我去的目的是缆车&lt;/p&gt;&#xA;&#xA;&lt;p&gt;首先,响彻云霄的Bus,随便拦了一台,RM1到轻轨站. 吉隆坡的Bus没路线图,站台也没有,真是服了的&lt;/p&gt;&#xA;&#xA;&lt;p&gt;轻轨站的自助买票机(人工不售票,次偶),2种语言,没影响&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/06/14/IMG_20130612_092539.jpg&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;车上怎么没什么人呢?难道我们太早了?窃喜中&amp;hellip;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/06/14/IMG_20130612_093217.jpg&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;全自动驾驶,车很短,3节车厢,班次很密,2分钟不到就一班车, Ampang Park与KL Sentral之间的轻轨线是底下了,其他都地上站&lt;/p&gt;&#xA;&#xA;&lt;p&gt;除了轻轨站,一个讲中文的大叔前来搭讪,RM上云顶,原本想着不赖嘛,本来就是RM30,但一说缆车今天停了,次偶,我XXXXXXXXXX&lt;/p&gt;&#xA;&#xA;&lt;p&gt;连缆车停运都被我赶上了&amp;hellip; 怪不得没人啦!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/06/14/IMG_20130612_110631.jpg&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;哎,算了,还是买票去看看不动的缆车吧,结果,一算,RM10搞定,次偶,大叔想坑我RM50!!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;缆车没坐成,那只好去其他景点了,下山依然是大bus,时速90km/h不减速,各种急弯,上山已经吓得半死,下山就真吓死了,过弯不减速有没有,会车不减速,有没有?!!&lt;/p&gt;&#xA;&#xA;&lt;h1&gt;独立广场和回教堂&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;回教堂就是Masjid Jamak站(KJ13),出来就奔麦当劳,结果,依然失望!! 小鸣鸣倒是吃得很欢乐,传说中的薯条嘛&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/06/14/DSCF1072.JPG&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;回教堂&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/06/14/DSCF1096.JPG&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;独立广场的马来西亚国旗,号称100米高&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/06/14/DSCF1115.JPG&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;然后瞄了瞄吉隆坡的城市模型&lt;/p&gt;&#xA;&#xA;&lt;p&gt;马来西亚最高法院&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/06/14/DSCF1161.JPG&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;h1&gt;榴莲啊榴莲&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;按网上攻略,直奔Taman Bahagia轻轨站(KJ23),出站就有一堆taxi在等,挑了台比较新的,RM15送达&lt;/p&gt;&#xA;&#xA;&lt;p&gt;来,上图!! RM9,吃到饱!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/06/14/DSCF1248.JPG&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;吃啊吃&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/06/14/DSCF1229.JPG&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;吃饱之后,买了3公斤的山竹,RM10有交易,就是蚂蚁很多&lt;/p&gt;&#xA;&#xA;&lt;p&gt;路边拦了辆Taxi,RM7送到轻轨站(次偶,咋便宜一半呢?原来不是同一个站),是Taman Parament站(KJ22),荒芜好多&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/06/14/DSCF1256.JPG&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;站内的路线牌&#xA;&lt;img src=&#34;/assets/media/2013/06/14/DSCF1257.JPG&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;小小的车厢&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/06/14/DSCF1259.JPG&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;旁边坐的都是穆斯林,不好意思拍照了&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/06/14/DSCF1263.JPG&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;h1&gt;晚餐,自己来!&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;受不了马来西亚各种新奇的口味,还是自己煮了吧!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/06/14/DSCF1029.JPG&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;餐前水果,黄肉西瓜和蓝莓&#xA;&lt;img src=&#34;/assets/media/2013/06/14/DSCF1030.JPG&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;鸡翅面条乌冬,还有大大的果汁&#xA;&lt;img src=&#34;/assets/media/2013/06/14/DSCF1041.JPG&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;h1&gt;早餐?把剩下的食材解决掉&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;微波炉,电磁炉,冰箱,刀叉碟筷子,全用遍了&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/06/14/DSCF1268.JPG&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;h1&gt;LCCT的Taxi&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;在前台花了10秒钟就退房了,光速啊,然后工作人员喊价RM100到LCCT,貌似很超值啊,便宜了RM20&lt;/p&gt;&#xA;&#xA;&lt;p&gt;来个为黑皮肤的Taxi司机,超级能聊&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/06/14/IMG_20130613_123137.jpg&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;由于是4点的飞机,当时才12点不到,就载我们去购物点了,纯自愿,估计他也能收点返点吧&lt;/p&gt;&#xA;&#xA;&lt;p&gt;号称马来西亚最大的巧克力工厂,门外清一色的旅游大巴,全写着XX旅行社,果然是中国水鱼必到的购物点&lt;/p&gt;&#xA;&#xA;&lt;p&gt;最后,下车的时候,司机说,其实他只能拿到RM70(次偶,酒店白赚RM30!!),同情心来了,RM5消费送上,拍照之(太模糊,坑爹的手机)&lt;/p&gt;&#xA;&#xA;&lt;p&gt;亚航的skybus,果断赶过他啦&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/06/14/IMG_20130613_124823.jpg&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;h1&gt;LCCT出发大厅&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;菜市场不等于差,其实也是便宜的代名词啦,简单但指示牌很清晰&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/06/14/IMG_20130613_131152.jpg&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;瞄瞄电视机,S18办理登记手续,托运行李,才26kg,我可买了55kg,严重严重浪费啊&lt;/p&gt;&#xA;&#xA;&lt;p&gt;出境,边检,竟然把我的山竹也过机,哦也,很自觉地在候机室吃完,不带上飞机&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/06/14/DSCF1272.JPG&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;候机室离最近的飞机不到50米,不时可以看到飞机经过&amp;hellip;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/06/14/DSCF1272.JPG&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;到点登机,走好长好长的路&amp;hellip; 热浪滚滚,都快烤熟了&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/06/14/IMG_20130613_154412.jpg&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;怎么是蓝色的?!坐错飞机了??? 马来西亚航空的飞机,空姐还是亚航的,放心了&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/06/14/IMG_20130613_160313.jpg&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;准点起飞,真正看到了排队起飞&amp;hellip;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/06/14/IMG_20130613_162441.jpg&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;由于还有多余的马来西亚币,买了额外的飞机餐,味道&amp;hellip; 哎&amp;hellip;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/06/14/IMG_20130613_171155.jpg&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>X11的xcb库卡死</title>
      <link>http://wendal.net/2013/05/23.html</link>
      <pubDate>2013-05-23 12:00:00 +0800</pubDate>
      <description>&lt;p&gt;一个多月没写blog,郁闷了&amp;hellip;&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;X11的xcb库(1.7版)在不知道神马情况下会卡死&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;操作系统: opensuse 11.4 x86&#xA;语言:     Qt 4.8.4,vdpau + Nv卡&lt;/p&gt;&#xA;&#xA;&lt;p&gt;症状: 在多线程下,调用vdpau_create_decoder会卡住&lt;/p&gt;&#xA;&#xA;&lt;p&gt;堆栈:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;#0  0xffffe424 in __kernel_vsyscall ()&#xA;#1  0xb43dc03e in __poll (fds=0xa5d15798, nfds=1, timeout=-1) at ../sysdeps/unix/sysv/linux/poll.c:87&#xA;#2  0xb1cc63f0 in _xcb_conn_wait (c=0x80f0b58, cond=0xa5d157f0, vector=0x0, count=0x0) at xcb_conn.c:313&#xA;#3  0xb1cc7d4f in xcb_wait_for_reply (c=0x80f0b58, request=13576, e=0xa5d1587c) at xcb_in.c:379&#xA;#4  0xb4213f92 in _XReply (dpy=0x80ffdb0, rep=0xa5d158bc, extra=0, discard=1) at xcb_io.c:533&#xA;#5  0xb0698032 in ?? () from /usr/lib/vdpau/libvdpau_nvidia.so.1&#xA;#6  0xb061715b in ?? () from /usr/lib/vdpau/libvdpau_nvidia.so.1&#xA;#7  0xb06174b7 in ?? () from /usr/lib/vdpau/libvdpau_nvidia.so.1&#xA;#8  0xb064dddb in ?? () from /usr/lib/vdpau/libvdpau_nvidia.so.1&#xA;#9  0xb067dbef in ?? () from /usr/lib/vdpau/libvdpau_nvidia.so.1&#xA;#10 0xb063b645 in ?? () from /usr/lib/vdpau/libvdpau_nvidia.so.1&#xA;#11 0xb061a423 in ?? () from /usr/lib/vdpau/libvdpau_nvidia.so.1&#xA;#12 0x0806d123 in mx::create_decoder (vdp=0x81f37f0, w=1920, h=1080, decoder=0x8235810) at ../../src/disp/xde_res_vdpau.cpp:79&#xA;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h2&gt;最初,我猜是这个bug的原因&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;(Thread hangs in xcb_wait_for_reply() if another thread calls xcb_poll_for_event())[https://bugs.freedesktop.org/show_bug.cgi?id=40372]&lt;/p&gt;&#xA;&#xA;&lt;p&gt;看着bug的意思,是不正确的使用xcb库,但,我XXX, 那是驱动调用的,我哪知道呢&amp;hellip;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;按部就班修改了一下,测试,继续死&amp;hellip; 我XXXX!!&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;好吧,换驱动&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;换最新的310系列,依然死,我XXXXXX&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;看来是bug,但怎么解决呢?&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;还是回到堆栈去, 卡死在xcb_wait_for_reply方法上,而这个方法有这样一句&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;378         while(!poll_for_reply(c, request, &amp;amp;ret, e)) {&#xA;379             if(!_xcb_conn_wait(c, &amp;amp;cond, 0, 0)) {&#xA;380                 break;&#xA;381             }&#xA;382             count ++; // 所以我加上下面几个逻辑,强制break,看看死不死&#xA;383             if ( count &amp;gt; 1000 ) {&#xA;384                 printf(&amp;quot;Loop more than 1000 times, break&amp;quot;);&#xA;385                 break;&#xA;386             }&#xA;387         }&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;结果,还是死&amp;hellip;.&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;看来要釜底抽薪啦,从最底层的api给跳出来&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;从第1帧来灭掉它&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;#1  0xb43dc03e in __poll (fds=0xa5d15798, nfds=1, timeout=-1) at ../sysdeps/unix/sysv/linux/poll.c:87&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;这一帧调用linux标准的poll方法,但timeout传入的是-1,即永久等待.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;反正不知道神马原因,就是没等到触发条件,卡住了, SO,妹的,改成1秒吧!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;代码如下:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;312 #if USE_POLL&#xA;313         ret = poll(&amp;amp;fd, 1, 1000);&#xA;314 #else&#xA;315         ret = select(c-&amp;gt;fd + 1, &amp;amp;rfds, &amp;amp;wfds, 0, 0);&#xA;316 #endif&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;编译,重启, 测试, 竟然好了,我XXX,但为什么呢? 不知道呢&amp;hellip; 反正没再死了&amp;hellip;&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;mark一下gdb常用命令&lt;/h2&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;gdb -p $pid        直接attach到正在运行的程序中&#xA;&#xA;set height 0       显示时,不分页&#xA;info threads       显示所有线程&#xA;thread 3           切换到3号线程&#xA;bt                 显示当前线程的堆栈&#xA;f 2                调到第二帧&#xA;c                  继续运行&#xA;Ctrl+C             中断运行,进行gdb交互模式&#xA;info locals        打印全部本地变量&#xA;print fd           打印名为fd的变量的值&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;</description>
    </item>
    <item>
      <title>在windows下编译nginx</title>
      <link>http://wendal.net/2013/0412.html</link>
      <pubDate>2013-04-12 12:00:00 +0800</pubDate>
      <description>&lt;p&gt;又有人在windows下编译nginx &amp;ndash; 为什么那么多人喜欢自残呢?&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;官网教程&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&#34;http://nginx.org/en/docs/howto_build_on_win32.html&#34;&gt;Building nginx on the Win32 platform with Visual C&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;本文基本上就是对着做,但需要对其进行微调 &amp;ndash; 不爽吗?咬我啊!!&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;准备工具&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;系统: winxp sp3 32位, 例如你可以用个虚拟机什么的安装一个winxp&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&#34;https://msys-cn.googlecode.com/files/MSYS-Update.7z&#34;&gt;MSYS-CN 2010-08-19 更新版本&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&#34;http://zlib.net/zlib-1.2.7.tar.gz&#34;&gt;zlib 1.2.7&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&#34;http://nchc.dl.sourceforge.net/project/pcre/pcre/8.32/pcre-8.32.zip&#34;&gt;pcre 8.32&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&#34;http://www.openssl.org/source/openssl-1.0.1e.tar.gz&#34;&gt;openssl 1.0.1e&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&#34;http://download.microsoft.com/download/3/0/2/3025EAE6-2E15-4972-972A-F5B1ED248E85/VS2008ExpressWithSP1CHSX1504735.iso&#34;&gt;VS2008 Express With SP1&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&#34;http://strawberry-perl.googlecode.com/files/strawberry-perl-5.16.3.1-32bit.msi&#34;&gt;Perl 5.16.3.1&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&#34;http://www.sliksvn.com/pub/Slik-Subversion-1.7.9-win32.msi&#34;&gt;Subversion&lt;/a&gt; 或者你喜欢的svn客户端&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;安装必要的程序&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;VS2008,附带的sqlserver无需安装,也用不上&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Perl,一直下一步即可&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Slik-Subversion,一直就是下一步&lt;/p&gt;&#xA;&#xA;&lt;p&gt;将MSYS-CN解压到C盘&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;下载源码&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;到C:\MSYS启动msys.bat,进入msys的bash&lt;/p&gt;&#xA;&#xA;&lt;p&gt;非常重要哦, 官网的tar包是不包含windows构建文件的!!&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;svn co svn://svn.nginx.org/nginx/tags/release-1.3.15&#xA;cd release-1.3.15&#xA;mkdir objs&#xA;mkdir objs/lib&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;然后, 把pcre/zlib/openssl的源码,均解压到C:\MSYS\home\UserName\release-1.3.15\objs\lib,&#xA;即上述语句所建立的文件夹,其中UserName是你的用户名.&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;生成构建脚本&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;依然在msys bash下.&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;cd release-1.3.15&#xA;auto/configure --with-cc=cl --builddir=objs --prefix= \&#xA;--conf-path=conf/nginx.conf --pid-path=logs/nginx.pid \&#xA;--http-log-path=logs/access.log --error-log-path=logs/error.log \&#xA;--sbin-path=nginx.exe --http-client-body-temp-path=temp/client_body_temp \&#xA;--http-proxy-temp-path=temp/proxy_temp \&#xA;--http-fastcgi-temp-path=temp/fastcgi_temp \&#xA;--with-cc-opt=-DFD_SETSIZE=1024 --with-pcre=objs/lib/pcre-8.32 \&#xA;--with-zlib=objs/lib/zlib-1.2.7 --with-openssl=objs/lib/openssl-1.0.1e \&#xA;--with-select_module --with-http_ssl_module --with-ipv6&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;语句比较长,可以写到build.bat中,然后执行 ./build.bat&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;编译&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;总有要编译啦,哇哈哈. 在开始菜单找VS2008的VS2008命令行,启动之&lt;/p&gt;&#xA;&#xA;&lt;p&gt;执行下面的语句&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;C:&#xA;cd \MSYS\home\UserName\release-1.3.15\&#xA;nmake -f objs/Makefile&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;你很快就会发现报错了,说找不到某某头文件.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;用你喜欢的编辑器打开 C:\MSYS\home\UserName\release-1.3.15\objs\lib\pcre-8.32\config.h&lt;/p&gt;&#xA;&#xA;&lt;p&gt;找到并注释掉(加//):&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;#ifndef HAVE_INTTYPES_H&#xA;#define HAVE_INTTYPES_H 1&#xA;#endif&#xA;&#xA;#ifndef HAVE_STDINT_H&#xA;#define HAVE_STDINT_H 1&#xA;#endif&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;然后再执行就成功了:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;nmake -f objs/Makefile&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h2&gt;好吧,祝你好运!!&lt;/h2&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;C:\MSYS\home\Administrator\release-1.3.15&amp;gt;nginx.exe -V&#xA;nginx version: nginx/1.3.15-http://wendal.net&#xA;TLS SNI support enabled&#xA;configure arguments: --with-cc=cl --builddir=objs --prefix= --conf-path=conf/ng&#xA;nx.conf --pid-path=logs/nginx.pid --http-log-path=logs/access.log --error-log-p&#xA;th=logs/error.log --sbin-path=nginx.exe --http-client-body-temp-path=temp/clien&#xA;_body_temp --http-proxy-temp-path=temp/proxy_temp --http-fastcgi-temp-path=temp&#xA;fastcgi_temp --with-cc-opt=-DFD_SETSIZE=1024 --with-pcre=objs/lib/pcre-8.32 --w&#xA;th-zlib=objs/lib/zlib-1.2.7 --with-openssl=objs/lib/openssl-1.0.1e --with-selec&#xA;_module --with-http_ssl_module&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;</description>
    </item>
    <item>
      <title>Golang下通过syscall调用win32的api</title>
      <link>http://wendal.net/2013/0406.html</link>
      <pubDate>2013-04-06 12:00:00 +0800</pubDate>
      <description>&lt;p&gt;源于golang群中再次提到windows下获取磁盘空间的方法&lt;/p&gt;&#xA;&#xA;&lt;p&gt;由于golang的api并非完全跨平台, golang本身并没有直接提供windows下的方式&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;syscall.Syscall系列方法&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;当前共5个方法&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;syscall.Syscall&#xA;syscall.Syscall6&#xA;syscall.Syscall9&#xA;syscall.Syscall12&#xA;syscall.Syscall15&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;分别对应 3个/6个/9个/12个/15个参数或以下的调用&lt;/p&gt;&#xA;&#xA;&lt;p&gt;参数都形如&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;syscall.Syscall(trap, nargs, a1, a2, a3)&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;第二个参数, nargs 即参数的个数,一旦传错, 轻则调用失败,重者直接APPCARSH&lt;/p&gt;&#xA;&#xA;&lt;p&gt;多余的参数, 用0代替&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;调用示例&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;获取磁盘空间&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;//首先,准备输入参数, GetDiskFreeSpaceEx需要4个参数, 可查MSDN&#xA;dir := &amp;quot;C:&amp;quot;&#xA;lpFreeBytesAvailable := int64(0) //注意类型需要跟API的类型相符&#xA;lpTotalNumberOfBytes := int64(0)&#xA;lpTotalNumberOfFreeBytes := int64(0)&#xA;&#xA;//获取方法的引用&#xA;kernel32, err := syscall.LoadLibrary(&amp;quot;Kernel32.dll&amp;quot;) // 严格来说需要加上 defer syscall.FreeLibrary(kernel32)&#xA;GetDiskFreeSpaceEx, err := syscall.GetProcAddress(syscall.Handle(kernel32), &amp;quot;GetDiskFreeSpaceExW&amp;quot;)&#xA;&#xA;//执行之. 因为有4个参数,故取Syscall6才能放得下. 最后2个参数,自然就是0了&#xA;r, _, errno := syscall.Syscall6(uintptr(GetDiskFreeSpaceEx), 4,&#xA;            uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(&amp;quot;C:&amp;quot;))),&#xA;            uintptr(unsafe.Pointer(&amp;amp;lpFreeBytesAvailable)),&#xA;            uintptr(unsafe.Pointer(&amp;amp;lpTotalNumberOfBytes)),&#xA;            uintptr(unsafe.Pointer(&amp;amp;lpTotalNumberOfFreeBytes)), 0, 0)&#xA;            &#xA;// 注意, errno并非error接口的, 不可能是nil&#xA;// 而且,根据MSDN的说明,返回值为0就fail, 不为0就是成功&#xA;if r != 0 {&#xA;    log.Printf(&amp;quot;Free %dmb&amp;quot;, lpTotalNumberOfFreeBytes/1024/1024)&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h2&gt;简单点的方式? 用syscall.Call&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;跟Syscall系列一样, Call方法最多15个参数. 这里用来Must开头的方法, 如不存在,会panic.&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;    h := syscall.MustLoadDLL(&amp;quot;kernel32.dll&amp;quot;)&#xA;    c := h.MustFindProc(&amp;quot;GetDiskFreeSpaceExW&amp;quot;)&#xA;    lpFreeBytesAvailable := int64(0)&#xA;    lpTotalNumberOfBytes := int64(0)&#xA;    lpTotalNumberOfFreeBytes := int64(0)&#xA;    r2, _, err := c.Call(uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(&amp;quot;F:&amp;quot;))),&#xA;        uintptr(unsafe.Pointer(&amp;amp;lpFreeBytesAvailable)),&#xA;        uintptr(unsafe.Pointer(&amp;amp;lpTotalNumberOfBytes)),&#xA;        uintptr(unsafe.Pointer(&amp;amp;lpTotalNumberOfFreeBytes)))&#xA;    if r2 != 0 {&#xA;        log.Println(r2, err, lpFreeBytesAvailable/1024/1024)&#xA;    }&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h2&gt;小提示&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;传struct不是个好想法, 不同语言之间的差异不好磨合&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Python还是很适合快速开发的</title>
      <link>http://wendal.net/2013/0325.html</link>
      <pubDate>2013-03-25 12:00:00 +0800</pubDate>
      <description>&lt;p&gt;上周为了重写公司的其中一个关键进程,断然选用Python快速开发了一版&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;首先,是启动器&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;虽然python脚本可以直接启动,但为了兼容其他进程,需要封装成一个原命名的进程&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;#include &amp;lt;Python.h&amp;gt;&#xA;#include &amp;lt;sched.h&amp;gt;&#xA;&#xA;int main(int argc, char *argv[]) {&#xA;    //设置进程优先级,因为有其他更重要的进程&#xA;    nice(10);&#xA;    // 设置cpu亲和性,因为是4线程的机器,所以仅亲和后2个cpu&#xA;    cpu_set_t  mask;&#xA;    CPU_ZERO(&amp;amp;mask);&#xA;    CPU_SET(2, &amp;amp;mask);//第3个&#xA;    CPU_SET(3, &amp;amp;mask);//第4个,其实就是第二个core&#xA;    sched_setaffinity(0, sizeof(mask), &amp;amp;mask);&#xA;&#xA;    Py_SetProgramName(argv[0]);&#xA;    Py_Initialize(); //标准的啦,初始化Python环境&#xA;    PySys_SetArgv(argc, argv);&#xA;    FILE * fp = fopen(&amp;quot;/home/xxx/yyy/zzz.py&amp;quot;, &amp;quot;r&amp;quot;); //打开入口py脚本的句柄,准备打开&#xA;    // 这里并没有去判断是否真的存放,因为必须存放,不然也什么都做不了&#xA;    //PyRun_SimpleFile(fp, &amp;quot;zzz.py&amp;quot;);&#xA;    PyRun_AnyFile(fp, &amp;quot;zzz.py&amp;quot;); //启动之,哈哈&#xA;    Py_Finalize(); // 严格来说从不调用,哈哈,因为是守护进程,退出的话,都是直接退&#xA;    return 0;//符合标准C嘛,哈哈&#xA;}&#xA;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;编译之&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;gcc -O2 -I/usr/include/python2.7 -lpython2.7 -MD -MT -pthread -ldl zzz.c -o zzz&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;需要带上-pthread和-dl等参数,否则可能无法加载模块&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;python代码部分&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;把路径添加进去,防止找不到py文件&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;import sys&#xA;sys.path.append(&amp;quot;/home/xxx/yyy&amp;quot;)&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;接下来的,自然就是业务逻辑了&lt;/p&gt;&#xA;&#xA;&lt;p&gt;话说,最近耗子哥跟百毒闹得很欢哦,哈哈&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Golang的坑之http读取大文件必须读完</title>
      <link>http://wendal.net/2013/0316.html</link>
      <pubDate>2013-03-16 12:00:00 +0800</pubDate>
      <description>&lt;h2&gt;先上代码&lt;/h2&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;package main&#xA;&#xA;import (&#xA;    &amp;quot;fmt&amp;quot;&#xA;    &amp;quot;net/http&amp;quot;&#xA;)&#xA;&#xA;func main() {&#xA;    resp, err := http.Get(&amp;quot;http://mirrors.ustc.edu.cn/opensuse/distribution/12.3/iso/openSUSE-12.3-GNOME-Live-i686.iso&amp;quot;)&#xA;    if err != nil {&#xA;        panic(err)&#xA;    }&#xA;    fmt.Println(&amp;quot;Resp code&amp;quot;, resp.StatusCode)&#xA;    resp.Body.Close() // 注意,这里并不读取resp.Body, 而resp.Body有大概700mb未读取&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;你猜会怎样呢? 卡住了?!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;如果你的网速够快,你会发现, 几十秒之后, 程序自动退出了,但如果你很不幸是小水管,你会发现一直卡住&amp;hellip;&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;原因是啥呢?&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;http包默认会重用连接,重用连接就需要先把前一个连接的数据读完&lt;/p&gt;&#xA;&#xA;&lt;p&gt;代码片段(net/http/transfer.go)&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;func (b *body) Close() error {&#xA;    if b.closed {&#xA;        return nil&#xA;    }&#xA;    defer func() {&#xA;        b.closed = true&#xA;    }()&#xA;    if b.hdr == nil &amp;amp;&amp;amp; b.closing {&#xA;        return nil&#xA;    }&#xA;    &#xA;    if b.res != nil &amp;amp;&amp;amp; b.res.requestBodyLimitHit {&#xA;        return nil&#xA;    }&#xA;&#xA;    // 操,问题就在这了,读完整个body!!&#xA;    if _, err := io.Copy(ioutil.Discard, b); err != nil {&#xA;        return err&#xA;    }&#xA;    return nil&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h2&gt;怎么解决呢?&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;按上面代码片段的逻辑, 需要提前返回nil,从而避免被读取&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;    // b.hdr 总是为nil,因为从不设置&#xA;    // 那b.closing什么时候为true呢?&#xA;    if b.hdr == nil &amp;amp;&amp;amp; b.closing {&#xA;        return nil&#xA;    }&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;读源码可知, b.closing依赖于transferReader的Close值&lt;/p&gt;&#xA;&#xA;&lt;p&gt;而transferReader的Close值, 是根据shouldClose方法判断的&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;// 这里的header是resp的&#xA;func shouldClose(major, minor int, header Header) bool {&#xA;    if major &amp;lt; 1 {&#xA;        return true&#xA;    } else if major == 1 &amp;amp;&amp;amp; minor == 0 {&#xA;        if !strings.Contains(strings.ToLower(header.Get(&amp;quot;Connection&amp;quot;)), &amp;quot;keep-alive&amp;quot;) {&#xA;            return true&#xA;        }&#xA;        return false&#xA;    } else {&#xA;        // TODO: Should split on commas, toss surrounding white space,&#xA;        // and check each field.&#xA;        if strings.ToLower(header.Get(&amp;quot;Connection&amp;quot;)) == &amp;quot;close&amp;quot; {&#xA;            header.Del(&amp;quot;Connection&amp;quot;)&#xA;            return true&#xA;        }&#xA;    }&#xA;    return false&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;由于没法在这些代码之前修改resp的header,所以修改req的header,使服务器总是返回Connection: close&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;最终代码&lt;/h2&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;package main&#xA;&#xA;import (&#xA;    &amp;quot;fmt&amp;quot;&#xA;    &amp;quot;net/http&amp;quot;&#xA;)&#xA;&#xA;func main() {&#xA;    req, _ := http.NewRequest(&amp;quot;GET&amp;quot;, &amp;quot;http://mirrors.ustc.edu.cn/opensuse/distribution/12.3/iso/openSUSE-12.3-GNOME-Live-i686.iso&amp;quot;, nil)&#xA;    req.Header.Set(&amp;quot;Connection&amp;quot;, &amp;quot;close&amp;quot;)&#xA;    resp, err := http.DefaultClient.Do(req)&#xA;    if err != nil {&#xA;        panic(err)&#xA;    }&#xA;    fmt.Println(&amp;quot;Resp code&amp;quot;, resp.StatusCode)&#xA;    resp.Body.Close()&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;一个月没写blog了, 心情欠佳+身体抱恙 ~_~ 哎,多事的3月&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;2013年4月5号更新&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;coocood提醒到, go1.1有个新的API来完成这个蛋碎的东西&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;http.DefaultTransport.(*http.Transport).CancelRequest(req)&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;如果不是默认的DefaultTransport,就找你自己set的Transport吧&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>天语T619也能Root</title>
      <link>http://wendal.net/2013/0216.html</link>
      <pubDate>2013-02-16 12:00:00 +0800</pubDate>
      <description>&lt;h2&gt;昨天,小黄蜂终于到手 &amp;ndash; 广东移动周销售1.4w台的299元廉价机&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;玩了一天,还是忍不住要root掉的. 实在无法忍受那些百度的app!!!&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;但,官方固件在哪里呢?&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;官网,木有&#xA;常见论坛,木有&lt;/p&gt;&#xA;&#xA;&lt;p&gt;最后,在592zn找到了&#xA;&lt;a href=&#34;http://www.592zn.com/thread-209732-1-1.html&#34;&gt;天语T619官方固件+592zn带ROOT固件&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;接下来,当然是root固件啦: 用&lt;a href=&#34;http://yaffey.googlecode.com/files/yaffey-v0.2-win32.zip&#34;&gt;yaffey&lt;/a&gt;&#xA;修改好,刷机,搞定!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;接下来,就是各种删除,哈哈&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;刷机步骤&lt;/h2&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;安装驱动(文章末尾有地址),会提示签名无效,一概接受.(win7 x64需要重启系统,按F8进高级选项,选禁用驱动签名)&lt;/li&gt;&#xA;&lt;li&gt;手机关机,按住&amp;rdquo;音量减&amp;rdquo;,接入USB线,出现驱动安装就可放手.待驱动安装完毕,拔掉USB线&lt;/li&gt;&#xA;&lt;li&gt;打开刷机工具,载入官方固件&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/02/16/load_pac.jpg&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;根据图中的路径,找到system.img文件,将root好的system.img覆盖上去&lt;/li&gt;&#xA;&lt;li&gt;刷机软件按&amp;rdquo;Start&amp;rdquo;, 手机按住&amp;rdquo;音量减&amp;rdquo;,接入USB线,应该很快就开始刷机,一旦开始刷机,就可以松手&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;h2&gt;刷机固件及资源&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&#34;http://pan.baidu.com/share/link?shareid=405128&amp;amp;uk=2214894781&#34;&gt;百度云,Wendal的T619专用文件夹&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;我的T619是1月27号生产的, 软件版本(设置-关于手机,最底下)是 TBT960230_8514_V0101&lt;/p&gt;&#xA;&#xA;&lt;p&gt;据说T619有N个版本,不能通刷&amp;hellip; 如果没有更加可靠的官方版本,以后就只能玩这版了,呵呵&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;声明&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;刷机有风险,官方固件常备哦!!&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Gor 2.1 发布了</title>
      <link>http://wendal.net/2013/0215.html</link>
      <pubDate>2013-02-15 12:00:00 +0800</pubDate>
      <description>&lt;h2&gt;重要改进&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;脱离了libyaml引入的cgo限制, 使用纯golang实现, 实现真正的跨平台&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&#34;http://code.google.com/p/gor/downloads/list&#34;&gt;下载地址&lt;/a&gt;&#xA;已编译好的linux/windows/macx下的二进制程序&lt;/p&gt;&#xA;&#xA;&lt;p&gt;当然, 也可以通过go install来安装&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;go get -u github.com/wendal/gor&#xA;go install github.com/wendal/gor/gor&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h2&gt;ChangeLog&lt;/h2&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;Update:  goyaml2 v2.0     纯golang实现的yaml解析器,兼容部分yaml语法(常用的部分)&lt;/li&gt;&#xA;&lt;li&gt;Update:  mustache v2.0   纯golang实现的mustache模板引擎&lt;/li&gt;&#xA;&lt;li&gt;Add:      同时支持yaml与json格式的配置文件及meta数据&lt;/li&gt;&#xA;&lt;li&gt;Add:      对自定义partials的支持&lt;/li&gt;&#xA;&lt;li&gt;Add:      对自定义widget的支持&#xA;6: Add:      更换markdown引擎,支持github形式的markdown格式&lt;/li&gt;&#xA;&lt;li&gt;Fix:       引用不存在的layout会NPE&lt;/li&gt;&#xA;&lt;li&gt;Fix:       Post元数据与widget可能冲突&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;p&gt;项目地址: &lt;a href=&#34;http://github.com/wendal/gor&#34;&gt;Gor@github&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;哈哈,终于能在真正跨平台了!!&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>获取goroutine的id</title>
      <link>http://wendal.net/2013/0205.html</link>
      <pubDate>2013-02-05 12:00:00 +0800</pubDate>
      <description>&lt;h2&gt;获取goroutine的id? 官方不支持的!!&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;人家官方说了:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;&amp;quot;This, among other reasons, to prevent programmers &#xA;for simulating thread local storage using the goroutine id as a key. &amp;quot;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;就为了避免咱们当成ThreadLocal的key!! 这是为了神马?为神马?!!&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;方法还是有的嘛,改动一下源码&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;神马?!改源码这么大件事?! 对的,但只是添加,不修改不覆盖,不影响其他功能&lt;/p&gt;&#xA;&#xA;&lt;p&gt;文件一, $GOPATH/src/pkg/runtime/runtime.c, 在最后面添加一个方法&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;void&#xA;runtime·GetGoId(int32 ret)&#xA;{&#xA;        ret = g-&amp;gt;goid;&#xA;        USED(&amp;amp;ret);&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;文件二, $GOPATH/src/pkg/runtime/extern.go 在最后面导出这个方法&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;func GetGoId() int&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;然后,就是重新编译golang了&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;cd $GOROOT/src&#xA;./make.bash&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h2&gt;好了,测试一下吧&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;写一个main.go&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;package main&#xA;&#xA;import &amp;quot;fmt&amp;quot;&#xA;import &amp;quot;runtime&amp;quot;&#xA;&#xA;func main() {&#xA;        fmt.Println(&amp;quot;Id =&amp;quot;, runtime.GetGoId())&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;编译并运行之&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;go run main.go&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;结果是&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;Id = 1&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h1&gt;恩,暴力到此结束哦,保重啦各位&amp;hellip;&lt;/h1&gt;&#xA;</description>
    </item>
    <item>
      <title>在Linux下安装Cuda5</title>
      <link>http://wendal.net/2013/0130.html</link>
      <pubDate>2013-01-30 12:00:00 +0800</pubDate>
      <description>&lt;p&gt;所有操作均为root用户.&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;安装环境&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;系统环境: Ubuntu 11.10 Desktop 32位&#xA;硬件环境: Nvidia GT540M&#xA;注意!! 虚拟机是不行的!!&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;下载cuda&lt;/h2&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;wget http://developer.download.nvidia.com/compute/cuda/5_0/rel-update-1/installers/cuda_5.0.35_linux_32_ubuntu11.10-1.run&#xA;#当然,我更喜欢用QQ旋风之类的先下载好&#xA;#无需额外下载显卡驱动, cuda 5.0已经包含了最适合的显卡驱动&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h2&gt;安装必要的库&lt;/h2&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;apt-get install g++ gcc make freeglut-dev vim&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h2&gt;切换到控制台&lt;/h2&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;service stop lightdm&#xA;#立马会退出桌面,黑乎乎的控制台背景就出来了&#xA;#按 Ctrl+Alt+F2, 切换到第2控制台&#xA;#使用root登陆&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h2&gt;第一次安装(自动配置环境的阶段)&lt;/h2&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;#假设你已经把安装文件准备好了&#xA;chmod a+x /cuda_5.0.35_linux_32_ubuntu11.10-1.run&#xA;bash /cuda_5.0.35_linux_32_ubuntu11.10-1.run&#xA;#按空格键看完授权书&#xA;#按提示输入accept/y等同意,严重建议不要修改安装路径&#xA;&#xA;#第一次安装,会报错,要求重启机器&#xA;&#xA;#!!!!重启后再重复上述步骤,即第二三次安装,哈哈!!!&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h2&gt;第二次安装(安装驱动及cuda sdk)&lt;/h2&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;#如无意外(缺库之类的),会提示安装驱动成功,安装cuda成功,但安装samples失败&#xA;bash /cuda_5.0.35_linux_32_ubuntu11.10-1.run&#xA;&#xA;#配置环境变量&#xA;export PATH=$PATH:/usr/local/cuda/bin&#xA;&#xA;#修改ldconfig配置&#xA;vim /etc/ld.so.conf.d/cuda.conf&#xA;#加入 /usr/local/cuda/lib&#xA;#保存,执行使其生效&#xA;ldconfig&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h2&gt;第三次安装(安装samples)&lt;/h2&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;#再运行一次安装程序&#xA;bash /cuda_5.0.35_linux_32_ubuntu11.10-1.run&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h2&gt;测试samples了&lt;/h2&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;cd /usr/local/cuda/samples&#xA;cd 1_Utilities/deviceQuery&#xA;make&#xA;&#xA;#如果出错,执行下面的语句即可查询当前GPU的信息&#xA;./deviceQuery&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h1&gt;原本期望CUDA 5.0会为Linux加入Video Encode,结果,再次失望了&amp;hellip;&lt;/h1&gt;&#xA;</description>
    </item>
    <item>
      <title>一个神奇的周末</title>
      <link>http://wendal.net/2013/0127.html</link>
      <pubDate>2013-01-27 12:00:00 +0800</pubDate>
      <description>&lt;h2&gt;周六,重写了新版的NutJson的前解析器&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Nutz.Json的解析器分2部分, String-&amp;gt;MapList, MapList-&amp;gt;Pojo&lt;/p&gt;&#xA;&#xA;&lt;p&gt;单纯对一个简单的json字符串执行String-&amp;gt;Map操作&lt;/p&gt;&#xA;&#xA;&lt;p&gt;改造前(3~4x)&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;Nutz-Json 500w次耗时: 14288&#xA;Fast-Json 500w次耗时: 4330&#xA;Nutz-Json 500w次耗时: 12336&#xA;Fast-Json 500w次耗时: 3029&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;改造后(1.3~1.6x)&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;Nutz-Json 500w次耗时: 6033&#xA;Fast-Json 500w次耗时: 4618&#xA;Nutz-Json 500w次耗时: 4717&#xA;Fast-Json 500w次耗时: 3048&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;当然,这只是String-&amp;gt;Map的速度,String-Pojo依然有很大差距&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;更换了新的机械硬盘&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;最近,原装的机械硬盘经常出现开机找不到盘,休眠后找不到盘,甚至发展&#xA;到使用过程中,忽然被卸载&lt;/p&gt;&#xA;&#xA;&lt;p&gt;为了避免数据丢失,果断购入新硬盘&lt;/p&gt;&#xA;&#xA;&lt;p&gt;接下来,必然是漫长的数据拷贝咯,使用了Ghost的disk2disk功能(哈哈,俺是正版用户&amp;ndash;还是不忘&amp;rdquo;吹嘘&amp;rdquo;)&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/01/ghost.gif&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;&amp;ldquo;别忽略那些偶发的出错&amp;rdquo;&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;周末发现一个公司系统中的bug,深藏不露,一直在寻找,一直没找到那种&amp;hellip;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;这算是一个很不错的教训.也让我重新思考ErrReport机制,即关注每个出错信息(使用计数器,Log记录器等手段),并尝试为其找到合理的解释,如果找不到,那就肯定是个bug了.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Golang的坑之DNS查询与系统线程</title>
      <link>http://wendal.net/2013/0123.html</link>
      <pubDate>2013-01-23 12:00:00 +0800</pubDate>
      <description>&lt;h2&gt;这个问题源之于我3个月前开发的一个缓存服务&lt;/h2&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;代理Http请求&lt;/li&gt;&#xA;&lt;li&gt;缓存部分请求,减少外网访问&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;h2&gt;但是,在不稳定的网络环境下(例如3G网络),不时出现崩溃的情况&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;纠结啊纠结啊&amp;hellip;&lt;/p&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;难道是因为我在32位系统下使用golang?&lt;/li&gt;&#xA;&lt;li&gt;难道是RP问题?&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;p&gt;出错信息非常长(几百~上千个goroutine),就只贴头尾&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;runtime/cgo: pthread_create failed: Resource temporarily unavailable&#xA;SIGABRT: abort&#xA;PC=0xffffe424&#xA;&#xA;&#xA;goroutine 1 [chan receive]:&#xA;net.(*pollServer).WaitRead(0xd0170f0, 0xd02e850, 0xcfff5e0, 0xb)&#xA;    /opt/go/src/pkg/net/fd.go:268 +0x75&#xA;net.(*netFD).accept(0xd02e850, 0x80923d3, 0x0, 0xcfc0320, 0xcf7b178, ...)&#xA;    /opt/go/src/pkg/net/fd.go:622 +0x199&#xA;net.(*TCPListener).AcceptTCP(0xd030358, 0xcfc0d20, 0x0, 0x0)&#xA;    /opt/go/src/pkg/net/tcpsock_posix.go:320 +0x56&#xA;net.(*TCPListener).Accept(0xd030358, 0x0, 0x0, 0x0, 0x0, ...)&#xA;    /opt/go/src/pkg/net/tcpsock_posix.go:330 +0x39&#xA;net/http.(*Server).Serve(0xd0170c0, 0xcfff920, 0xd030358, 0x0, 0x0, ...)&#xA;    /opt/go/src/pkg/net/http/server.go:1029 +0x77&#xA;net/http.(*Server).ListenAndServe(0xd0170c0, 0xd0170c0, 0x40)&#xA;    /opt/go/src/pkg/net/http/server.go:1019 +0x9f&#xA;net/http.ListenAndServe(0x81f73c4, 0x5, 0xcfff840, 0xd0301f8, 0xd0301f8, ...)&#xA;    /opt/go/src/pkg/net/http/server.go:1091 +0x55&#xA;    &#xA;尾部&#xA;eax     0x0&#xA;ebx     0x231f&#xA;ecx     0x2357&#xA;edx     0x6&#xA;edi     0xb77ceff4&#xA;esi     0xb&#xA;ebp     0xafa112f8&#xA;esp     0xafa11050&#xA;eip     0xffffe424  //就这个,虽然不知道是什么,但很厉害的样子&#xA;eflags  0x202&#xA;cs      0x73&#xA;fs      0x0&#xA;gs      0x33&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;一直没找到原因&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;直至几天前,忽然灵机一动,难道是DNS的问题?&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;因为每次崩溃,总会带几个类似的goroutine&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;goroutine 1614 [syscall]:&#xA;net._C2func_getaddrinfo(0x87af730, 0x0)&#xA;    net/_obj/_cgo_defun.c:42 +0x32&#xA;net.cgoLookupIPCNAME(0xd20b36c, 0x1a, 0x0, 0x0, 0x0, ...)&#xA;    net/_obj/_cgo_gotypes.go:177 +0xe7&#xA;net.cgoLookupIP(0xd20b36c, 0x1a, 0x0, 0x0, 0x0, ...)&#xA;    net/_obj/_cgo_gotypes.go:223 +0x3d&#xA;net.cgoLookupHost(0xd20b36c, 0x1a, 0x0, 0x0, 0x0, ...)&#xA;    net/_obj/_cgo_gotypes.go:101 +0x43&#xA;net.lookupHost(0xd20b36c, 0x1a, 0x0, 0x0, 0x0, ...)&#xA;    /opt/go/src/pkg/net/lookup_unix.go:56 +0x3d&#xA;net.LookupHost(0xd20b36c, 0x1a, 0x0, 0x0, 0x0, ...)&#xA;    /opt/go/src/pkg/net/doc.go:10 +0x3d&#xA;net.hostPortToIP(0x81f6d58, 0x3, 0xd20b36c, 0x1f, 0x0, ...)&#xA;    /opt/go/src/pkg/net/ipsock.go:120 +0x183&#xA;net.ResolveTCPAddr(0x81f6d58, 0x3, 0xd20b36c, 0x1f, 0x0, ...)&#xA;    /opt/go/src/pkg/net/tcpsock.go:31 +0x37&#xA;net.resolveNetAddr(0x81f9c14, 0x4, 0x81f6d58, 0x3, 0xd20b36c, ...)&#xA;    /opt/go/src/pkg/net/dial.go:50 +0x35d&#xA;net._func_001(0xd4bf228, 0xd4bf230, 0xd4bf238, 0xd4bf240, 0x0, ...)&#xA;    /opt/go/src/pkg/net/dial.go:134 +0x44&#xA;created by net.DialTimeout&#xA;    /opt/go/src/pkg/net/dial.go:142 +0x13b&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;So,做了一个简单的DNS Cache,在执行net.Dail前,先自行解析域名&lt;/p&gt;&#xA;&#xA;&lt;p&gt;结果,在虚拟机上,模拟各种垃圾网络(断网,拔网线,拔路由器&amp;hellip;),没有再出现崩溃&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;原因是什么呢?&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;看我10月份发送到讨论组的邮件 &lt;a href=&#34;https://groups.google.com/group/golang-china/browse_thread/thread/96e25b27abf9673b/98d271d98925fa98?lnk=gst&amp;amp;q=pthread_create#98d271d98925fa98&#34;&gt;runtime/cgo: pthread_create failed: Resource temporarily unavailable&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;待我解决问题后,马上有人解释原因了(汗&amp;hellip; 为啥之前就没人回复呢? 问得太次?)&lt;/p&gt;&#xA;&#xA;&lt;p&gt;关键就是: &lt;em&gt;系统调用阻塞时大量生成内核级线程导致的&lt;/em&gt;, 而cgo启用的情况下, 每一次DNS查询,都会起动一个系统线程!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;我只能说,你妹啊!! 系统线程啊!! 难道就不能弄个线程池啊!! 再说,有pthread_cancel啊,为啥timeout不执行一下呢?!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;写着写着, 忽然回想起之前遇到的一个情况,就是http.Get不返回(一直卡着,不往下执行),现在想起来,99%也是DNS的问题&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Golang的坑之文件覆写</title>
      <link>http://wendal.net/2013/0116.html</link>
      <pubDate>2013-01-16 12:00:00 +0800</pubDate>
      <description>&lt;h2&gt;在Java/Python中, 文件打开后,默认是覆写,但golang默认是不覆盖的&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;最初以为这些代码会&amp;rdquo;无则创建,有则覆盖&amp;rdquo;&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;f, err := os.OpenFile(dst, os.O_WRONLY|os.O_CREATE, os.ModePerm)&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;这样得到f, 如果不执行&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;f.Truncate(0)&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;就f.Write就只是覆盖当前位置的内容,并不会截断文件.&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;事实上需要这样写&lt;/h2&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;f, err := os.OpenFile(dst, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, os.ModePerm)&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;</description>
    </item>
    <item>
      <title>Golang下进行字符集转换</title>
      <link>http://wendal.net/2013/0115.html</link>
      <pubDate>2013-01-15 12:00:00 +0800</pubDate>
      <description>&lt;h1&gt;演示一下gb2312转UTF8&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;源网页是国家地震局的一周内地震统计,编码是gb2312&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;package main&#xA;&#xA;import (&#xA;    iconv &amp;quot;github.com/djimenez/iconv-go&amp;quot;&#xA;    &amp;quot;io/ioutil&amp;quot;&#xA;    &amp;quot;log&amp;quot;&#xA;    &amp;quot;net/http&amp;quot; &#xA;)&#xA;&#xA;func main() {&#xA;    log.SetFlags(log.LstdFlags | log.Lshortfile)&#xA;    resp, err := http.Get(&amp;quot;http://data.earthquake.cn/datashare/globeEarthquake_csn.html&amp;quot;)&#xA;    if err != nil {&#xA;        log.Fatal(err)&#xA;    }&#xA; &#xA;    defer resp.Body.Close()&#xA;    input, err := ioutil.ReadAll(resp.Body)&#xA;    out := make([]byte, len(input))&#xA;    out = out[:]&#xA;    iconv.Convert(input, out, &amp;quot;gb2312&amp;quot;, &amp;quot;utf-8&amp;quot;)&#xA;    ioutil.WriteFile(&amp;quot;out.html&amp;quot;, out, 0644)&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;</description>
    </item>
    <item>
      <title>最近买了2款软件</title>
      <link>http://wendal.net/2013/0113.html</link>
      <pubDate>2013-01-13 12:00:00 +0800</pubDate>
      <description>&lt;p&gt;最近又入手了2款软件&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;Sublime Text 2&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/01/13/1.jpg&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;IDEA 12&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/01/13/2.jpg&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Gor--极快的静态博客引擎</title>
      <link>http://wendal.net/2013/0111.html</link>
      <pubDate>2013-01-11 12:00:00 +0800</pubDate>
      <description>&lt;h2&gt;1秒编译200篇文章&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Gor的速度极快哦, 编译本网站200篇文章仅需1秒!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/01/gor_1.jpg&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;为什么写Gor?&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Gor源于对ruhoh的不满&lt;/p&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;依赖一大堆东西&lt;/li&gt;&#xA;&lt;li&gt;ruby编写,看不懂&lt;/li&gt;&#xA;&lt;li&gt;速度慢, 需要10秒以上&lt;/li&gt;&#xA;&lt;li&gt;gor在很多方面就是ruhoh for golang版&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;p&gt;Gor跟jekyll/octopress 有啥不同&lt;/p&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;模板引擎不一样, gor/ruhoh使用mustache模板,更易懂易写&lt;/li&gt;&#xA;&lt;li&gt;gor更快,必须的&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;p&gt;Gor有啥缺陷?&lt;/p&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;刚起步,还不够成熟&lt;/li&gt;&#xA;&lt;li&gt;因为基于golang,插件机制比较弱&lt;/li&gt;&#xA;&lt;li&gt;在windows下还不能很好地工作&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;h2&gt;Gor使用了些神马golang的第三库&lt;/h2&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;markdown, 负责将markdown转为html&lt;/li&gt;&#xA;&lt;li&gt;mustache库,wendal自行实现,实现大部分mustache语法(官方版实在太烂)&lt;/li&gt;&#xA;&lt;li&gt;当前依赖goyaml库,负责解析配置文件和元数据,将来会实现一个纯go的版本&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;h2&gt;基本用法&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;建立新站点(无需联网)&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;gor new wendal.net&#xA;cd wendal.net&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;新建一篇文章&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;gor post &amp;quot;Hi,Gor&amp;quot;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;编译&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;gor compile&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;预览编译结果&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;gor http&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;然后,打开你浏览器,访问 &lt;a href=&#34;http://127.0.0.1:8080&#34;&gt;http://127.0.0.1:8080&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;更多用法,请访问&lt;a href=&#34;http://github.com/wendal/gor&#34;&gt;Gor@github&lt;/a&gt;&lt;/h2&gt;&#xA;</description>
    </item>
    <item>
      <title>Nutz福利之轻功</title>
      <link>http://wendal.net/2013/0108.html</link>
      <pubDate>2013-01-08 12:00:00 +0800</pubDate>
      <description>&lt;h2&gt;作为挨踢人士,翻过伟大的强,总是那么频繁,Nutz新年福利之轻功,提供给大家一个免费的途径,方便大家访问讨论组,查找技术文章&amp;hellip;&lt;/h2&gt;&#xA;&#xA;&lt;h2&gt;连接服务器(Linux下)&lt;/h2&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;ssh -C -N -D 7070 nutz_xxxx@ci.wendal.net&#xA;#输入密码即可, nutz_xxxx即为你的账号&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h2&gt;连接服务器(Windows下)&lt;/h2&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&lt;a href=&#34;http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html&#34;&gt;下载putty&lt;/a&gt;, 请使用官网地址,切勿使用所谓汉化版&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;启动putty, 填入域名&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/01/fuck_gfw_1.jpg&#34;&gt;&lt;/img&gt;&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;设置不启动shell及启用压缩&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/01/fuck_gfw_2.jpg&#34;&gt;&lt;/img&gt;&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;添加tunnel&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2013/01/fuck_gfw_3.jpg&#34;&gt;&lt;/img&gt;&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;返回到session, 按&amp;rdquo;Save&amp;rdquo;保存设置,然后点击Open,启动连接,输入密码即可&lt;/p&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;h2&gt;然后就是浏览器设置了&lt;/h2&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;Chrome用户,&lt;a href=&#34;https://chrome.google.com/webstore/detail/proxy-switchy/caehdcpeofiiigpdhbabniblemipncjj&#34;&gt;安装ProxySwitcher&lt;/a&gt;, 使用127.0.0.1端口7070, sockt5协议&lt;/li&gt;&#xA;&lt;li&gt;Firefox用户, 安装AutoProxy,选择ssh -D配置&lt;/li&gt;&#xA;&lt;li&gt;IE,貌似IE对sockt5支持得不太好,不推荐&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;h1&gt;祝各位Nutzer轻功了得&lt;/h1&gt;&#xA;</description>
    </item>
    <item>
      <title>Linux下通过CiscoAnyConnectVPN访问Windows远程桌面</title>
      <link>http://wendal.net/2012/1228.html</link>
      <pubDate>2012-12-24 12:00:00 +0800</pubDate>
      <description>&lt;p&gt;Cisco的AnyConnect产品,好多大公司都在用,但貌似木有官方的Linux客户端(如果你有,请提供链接,无比感谢)&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;首先,需要一个开源的客户端openconnect&lt;/h2&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;#部分Linux发行版中有预编译版,但毕竟老&#xA;#应该也能用,没试过  yum install openconnect&#xA;&#xA;wget ftp://ftp.infradead.org/pub/openconnect/openconnect-4.07.tar.gz&#xA;tar xvf openconnect-4.07.tar.gz&#xA;cd openconnect-4.07&#xA;./configure&#xA;make&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h2&gt;得到编译好的openconnect后, 连接服务器&lt;/h2&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;#root权限哦, 或者能添加tun的帐户也行&#xA;./openconnect vpn.wendal.net&#xA;#提示如下:&#xA;Attempting to connect to 124.99.99.99:443&#xA;SSL negotiation with vpn.wendal.net&#xA;Connected to HTTPS on vpn.wendal.net&#xA;GET https://vpn.wendal.net/&#xA;Got HTTP response: HTTP/1.0 302 Object Moved&#xA;SSL negotiation with vpn.wendal.net&#xA;Connected to HTTPS on vpn.wendal.net&#xA;GET https://vpn.wendal.net/+webvpn+/index.html&#xA;Please enter your username and password.&#xA;username: #输入帐户&#xA;password: #输入密码&#xA;&#xA;#当然,你可以先指定user和password咯&#xA;./openconnect -u wendal -p wendal vpn.wendal.net&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h2&gt;登陆成功后, 查看本地地址&lt;/h2&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;ifconfig tun0&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h2&gt;接下来,就是远程桌面了&lt;/h2&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;#安装rdesktop&#xA;yum install -y rdesktop&#xA;./rdesktop -z win.wendal.net&#xA;#哈哈,你能看到界面了吗? 输入帐户密码就可以登陆了&#xA;&#xA;#-z是压缩参数&#xA;#还可以指定用户名和密码实现自动登陆&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h2&gt;看看成果&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2012/12/vpn_remote_desktop.jpg&#34;&gt;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>在Golang中获取系统的磁盘空间内存占用</title>
      <link>http://wendal.net/2012/1224.html</link>
      <pubDate>2012-12-24 12:00:00 +0800</pubDate>
      <description>&lt;h2&gt;获取磁盘占用情况(Linux/Mac下有效)&lt;/h2&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;import (&#xA;    &amp;quot;syscall&amp;quot;&#xA;)&#xA;&#xA;type DiskStatus struct {&#xA;    All  uint64 `json:&amp;quot;all&amp;quot;`&#xA;    Used uint64 `json:&amp;quot;used&amp;quot;`&#xA;    Free uint64 `json:&amp;quot;free&amp;quot;`&#xA;}&#xA;&#xA;// disk usage of path/disk&#xA;func DiskUsage(path string) (disk DiskStatus) {&#xA;    fs := syscall.Statfs_t{}&#xA;    err := syscall.Statfs(path, &amp;amp;fs)&#xA;    if err != nil {&#xA;        return&#xA;    }&#xA;    disk.All = fs.Blocks * uint64(fs.Bsize)&#xA;    disk.Free = fs.Bfree * uint64(fs.Bsize)&#xA;    disk.Used = disk.All - disk.Free&#xA;    return&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h2&gt;获取内存占用&lt;/h2&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;import (&#xA;    &amp;quot;runtime&amp;quot;&#xA;)&#xA;&#xA;type MemStatus struct {&#xA;    All  uint32 `json:&amp;quot;all&amp;quot;`&#xA;    Used uint32 `json:&amp;quot;used&amp;quot;`&#xA;    Free uint32 `json:&amp;quot;free&amp;quot;`&#xA;    Self uint64 `json:&amp;quot;self&amp;quot;`&#xA;}&#xA;&#xA;func MemStat() MemStatus {&#xA;    //自身占用&#xA;    memStat := new(runtime.MemStats)&#xA;    runtime.ReadMemStats(memStat)&#xA;    mem := MemStatus{}&#xA;    mem.Self = memStat.Alloc&#xA;&#xA;    //系统占用,仅linux/mac下有效&#xA;    //system memory usage&#xA;    sysInfo := new(syscall.Sysinfo_t)&#xA;    err := syscall.Sysinfo(sysInfo)&#xA;    if err == nil {&#xA;        mem.All = sysInfo.Totalram * uint32(syscall.Getpagesize())&#xA;        mem.Free = sysInfo.Freeram * uint32(syscall.Getpagesize())&#xA;        mem.Used = mem.All - mem.Free&#xA;    }&#xA;    return mem&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h2&gt;后记&lt;/h2&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;很明显,Windows下的支持是最弱的, 当然,还能通过调用win32 API的方式获取缺失的信息&lt;/li&gt;&#xA;&lt;li&gt;Golang的API并非完全跨平台, 正如上述的syscall.Statfs_t结构体,在Windows下是没有的&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;h2&gt;2013年4月6号更新,windows下获取磁盘空间的方法&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;通过调用win32 api&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;func main() {&#xA;    kernel32, err := syscall.LoadLibrary(&amp;quot;Kernel32.dll&amp;quot;)&#xA;    if err != nil {&#xA;        log.Panic(err)&#xA;    }&#xA;    defer syscall.FreeLibrary(kernel32)&#xA;    GetDiskFreeSpaceEx, err := syscall.GetProcAddress(syscall.Handle(kernel32), &amp;quot;GetDiskFreeSpaceExW&amp;quot;)&#xA;&#xA;    if err != nil {&#xA;        log.Panic(err)&#xA;    }&#xA;&#xA;    lpFreeBytesAvailable := int64(0)&#xA;    lpTotalNumberOfBytes := int64(0)&#xA;    lpTotalNumberOfFreeBytes := int64(0)&#xA;    r, a, b := syscall.Syscall6(uintptr(GetDiskFreeSpaceEx), 4,&#xA;        uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(&amp;quot;C:&amp;quot;))),&#xA;        uintptr(unsafe.Pointer(&amp;amp;lpFreeBytesAvailable)),&#xA;        uintptr(unsafe.Pointer(&amp;amp;lpTotalNumberOfBytes)),&#xA;        uintptr(unsafe.Pointer(&amp;amp;lpTotalNumberOfFreeBytes)), 0, 0)&#xA;&#xA;    log.Printf(&amp;quot;Available  %dmb&amp;quot;, lpFreeBytesAvailable/1024/1024.0)&#xA;    log.Printf(&amp;quot;Total      %dmb&amp;quot;, lpTotalNumberOfBytes/1024/1024.0)&#xA;    log.Printf(&amp;quot;Free       %dmb&amp;quot;, lpTotalNumberOfFreeBytes/1024/1024.0)&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;或者更简单的版本&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;func main() {&#xA;    h := syscall.MustLoadDLL(&amp;quot;kernel32.dll&amp;quot;)&#xA;    c := h.MustFindProc(&amp;quot;GetDiskFreeSpaceExW&amp;quot;)&#xA;    lpFreeBytesAvailable := int64(0)&#xA;    lpTotalNumberOfBytes := int64(0)&#xA;    lpTotalNumberOfFreeBytes := int64(0)&#xA;    r2, _, err := c.Call(uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(&amp;quot;F:&amp;quot;))),&#xA;        uintptr(unsafe.Pointer(&amp;amp;lpFreeBytesAvailable)),&#xA;        uintptr(unsafe.Pointer(&amp;amp;lpTotalNumberOfBytes)),&#xA;        uintptr(unsafe.Pointer(&amp;amp;lpTotalNumberOfFreeBytes)))&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;</description>
    </item>
    <item>
      <title>在Golang中获取func的名称</title>
      <link>http://wendal.net/2012/1223.html</link>
      <pubDate>2012-12-23 12:00:00 +0800</pubDate>
      <description>&lt;p&gt;这个问题源之于群友SeanWu的一个提问&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;期望的效果&lt;/h2&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;func ABC() {&#xA;}&#xA;&#xA;func GetFuncName(fn func()) string {&#xA;    return //返回ABC&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h2&gt;stackoverflow上的方法&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&#34;http://stackoverflow.com/questions/7052693/how-to-get-the-name-of-a-function-in-go&#34;&gt;链接&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;func GetFunctionName(i interface{}) string {&#xA;    return runtime.FuncForPC(reflect.ValueOf(i).Pointer()).Name()&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h2&gt;分析&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;我曾经尝试这种写法&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;runtime.FuncForPC(reflect.ValueOf(i).Addr()).Name()&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;但func是不能执行Addr()的, 而&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;funcPc,_,_ := runtime.Caller(0)&#xA;runtime.FuncForPC(funcPc).Name()&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;只能在func被调用时才能获取到自身的名字&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;reflect.ValueOf(i).Pointer()&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;就是绕过了执行过程,直接通过PC值来获取Func对象,从而得到名字&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Android中以root权限调用本地程序</title>
      <link>http://wendal.net/2012/1221.html</link>
      <pubDate>2012-12-21 12:00:00 +0800</pubDate>
      <description>&lt;p&gt;最近用到Android,需要执行一些本地程序,以前root机做过不少,但还没真正用Java代码调用过&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;今天,总算解决了&lt;/h2&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;public static boolean runAsRoot(String cmd) {&#xA;    try {&#xA;        Process p = Runtime.getRuntime().exec(&amp;quot;su&amp;quot;);&#xA;        OutputStream out = p.getOutputStream();&#xA;        out.write((cmd + &amp;quot;\n&amp;quot;).getBytes());&#xA;        out.flush();&#xA;        out.close();&#xA;        if (p.waitFor() == 0) {&#xA;            return true;&#xA;        }&#xA;        return false;&#xA;    } catch (Exception e) {&#xA;        return false;&#xA;    }&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h2&gt;原理&lt;/h2&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;前提,当然是你的机器已经root&lt;/li&gt;&#xA;&lt;li&gt;所谓root过,就是能无限制地执行su&lt;/li&gt;&#xA;&lt;li&gt;android上的su,就是改变当前进程的uid和gid,然后转为一个shell&lt;/li&gt;&#xA;&lt;li&gt;上述代码就是先执行su,然后将所需命令传入这个&amp;rdquo;shell&amp;rdquo;来执行&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;</description>
    </item>
    <item>
      <title>在Linux下查看硬盘信息</title>
      <link>http://wendal.net/2012/1215.html</link>
      <pubDate>2012-12-15 12:00:00 +0800</pubDate>
      <description>&lt;h2&gt;很简单,用hdparm程序就可以了&lt;/h2&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;hdparm -i /dev/sda&#xA;&#xA;/dev/sda:&#xA;hdparm: ioctl 0x304 failed: Inappropriate ioctl for device&#xA;&#xA;Model=HSPS35L4U16GCJC0914                     , FwRev=20101212, SerialNo=AA20120906000000181&#xA;Config={ HardSect NotMFM Fixed DTR&amp;gt;10Mbs }&#xA;RawCHS=16383/16/63, TrkSize=0, SectSize=576, ECCbytes=0&#xA;BuffType=(2) DualPort, BuffSize=1kB, MaxMultSect=1, MultSect=?0?&#xA;CurCHS=16383/16/63, CurSects=16514064, LBA=yes, LBAsects=30932992&#xA;IORDY=on/off, tPIO={min:120,w/IORDY:120}, tDMA={min:120,rec:120}&#xA;PIO modes:  pio0 pio1 pio2 pio3 pio4&#xA;DMA modes:  mdma0 mdma1 mdma2&#xA;UDMA modes: udma0 udma1 udma2&#xA;AdvancedPM=no WriteCache=enabled&#xA;Drive conforms to: Unspecified:  ATA/ATAPI-7&#xA;&#xA;* current active mode&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h2&gt;不得不提一下万能的busybox,竟然也包含hdparm&lt;/h2&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;./busybox-i686 hdparm -i /dev/sda&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h2&gt;看来以后找小工具,先看看busybox带不带才行,嘿嘿&lt;/h2&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;./busysbox-i686&#xA;&#xA;BusyBox v1.20.0 (2012-08-22 21:37:17 CDT) multi-call binary.&#xA;Copyright (C) 1998-2011 Erik Andersen, Rob Landley, Denys Vlasenko&#xA;and others. Licensed under GPLv2.&#xA;See source distribution for full notice.&#xA;&#xA;Usage: busybox [function] [arguments]...&#xA;    or: busybox --list[-full] //列出全部小工具&#xA;    or: busybox --install [-s] [DIR] //安装到指定文件夹&#xA;    or: function [arguments]... //直接调用小工具&#xA;&#xA;        BusyBox is a multi-call binary that combines many common Unix&#xA;        utilities into a single executable.  Most people will create a&#xA;        link to busybox for each function they wish to use and BusyBox&#xA;        will act like whatever it was invoked as.&#xA;&#xA;Currently defined functions:&#xA;    [, [[, acpid, add-shell, addgroup, adduser, adjtimex, arp, arping, ash, awk, base64, basename, beep, blkid, blockdev, bootchartd, brctl,&#xA;    bunzip2, bzcat, bzip2, cal, cat, catv, chat, chattr, chgrp, chmod, chown, chpasswd, chpst, chroot, chrt, chvt, cksum, clear, cmp, comm,&#xA;    conspy, cp, cpio, crond, crontab, cryptpw, cttyhack, cut, date, dc, dd, deallocvt, delgroup, deluser, depmod, devmem, df, dhcprelay, diff,&#xA;    dirname, dmesg, dnsd, dnsdomainname, dos2unix, du, dumpkmap, dumpleases, echo, ed, egrep, eject, env, envdir, envuidgid, ether-wake, expand,&#xA;    expr, fakeidentd, false, fbset, fbsplash, fdflush, fdformat, fdisk, fgconsole, fgrep, find, findfs, flock, fold, free, freeramdisk, fsck,&#xA;    fsck.minix, fsync, ftpd, ftpget, ftpput, fuser, getopt, getty, grep, groups, gunzip, gzip, halt, hd, hdparm, head, hexdump, hostid,&#xA;    hostname, httpd, hush, hwclock, id, ifconfig, ifdown, ifenslave, ifplugd, ifup, inetd, init, insmod, install, ionice, iostat, ip, ipaddr,&#xA;    ipcalc, ipcrm, ipcs, iplink, iproute, iprule, iptunnel, kbd_mode, kill, killall, killall5, klogd, last, less, linux32, linux64, linuxrc, ln,&#xA;    loadfont, loadkmap, logger, login, logname, logread, losetup, lpd, lpq, lpr, ls, lsattr, lsmod, lsof, lspci, lsusb, lzcat, lzma, lzop,&#xA;    lzopcat, makedevs, makemime, man, md5sum, mdev, mesg, microcom, mkdir, mkdosfs, mke2fs, mkfifo, mkfs.ext2, mkfs.minix, mkfs.vfat, mknod,&#xA;    mkpasswd, mkswap, mktemp, modinfo, modprobe, more, mount, mountpoint, mpstat, mt, mv, nameif, nanddump, nandwrite, nbd-client, nc, netstat,&#xA;    nice, nmeter, nohup, nslookup, ntpd, od, openvt, passwd, patch, pgrep, pidof, ping, ping6, pipe_progress, pivot_root, pkill, pmap,&#xA;    popmaildir, poweroff, powertop, printenv, printf, ps, pscan, pstree, pwd, pwdx, raidautorun, rdate, rdev, readahead, readlink, readprofile,&#xA;    realpath, reboot, reformime, remove-shell, renice, reset, resize, rev, rm, rmdir, rmmod, route, rpm, rpm2cpio, rtcwake, run-parts, runlevel,&#xA;    runsv, runsvdir, rx, script, scriptreplay, sed, sendmail, seq, setarch, setconsole, setfont, setkeycodes, setlogcons, setserial, setsid,&#xA;    setuidgid, sh, sha1sum, sha256sum, sha512sum, showkey, slattach, sleep, smemcap, softlimit, sort, split, start-stop-daemon, stat, strings,&#xA;    stty, su, sulogin, sum, sv, svlogd, swapoff, swapon, switch_root, sync, sysctl, syslogd, tac, tail, tar, tcpsvd, tee, telnet, telnetd, test,&#xA;    tftp, tftpd, time, timeout, top, touch, tr, traceroute, traceroute6, true, tty, ttysize, tunctl, udhcpc, udhcpd, udpsvd, umount, uname,&#xA;    unexpand, uniq, unix2dos, unlzma, unlzop, unxz, unzip, uptime, users, usleep, uudecode, uuencode, vconfig, vi, vlock, volname, wall, watch,&#xA;    watchdog, wc, wget, which, who, whoami, whois, xargs, xz, xzcat, yes, zcat, zcip&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;busybox 是居家旅行,杀人灭口之必备武器,900k不到,却带了N种强大工具.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>rm文件不再需要按y了,解脱啊</title>
      <link>http://wendal.net/2012/1214.html</link>
      <pubDate>2012-12-14 12:00:00 +0800</pubDate>
      <description>&lt;h1&gt;终于解决了在某些linux下rm特定文件需要按y的问题&lt;/h1&gt;&#xA;&#xA;&lt;h2&gt;原因就是在alias&lt;/h2&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;[root@MyVPS2923 ~]# alias&#xA;alias cp=&#39;cp -i&#39;&#xA;alias l.=&#39;ls -d .* --color=tty&#39;&#xA;alias ll=&#39;ls -l --color=tty&#39;&#xA;alias ls=&#39;ls --color=tty&#39;&#xA;alias mv=&#39;mv -i&#39;&#xA;alias rm=&#39;rm -i&#39;&#xA;alias which=&#39;alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde&#39;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h2&gt;再找根源&lt;/h2&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;[root@MyVPS2923 ~]# cat ~/.bashrc&#xA;# .bashrc&#xA;&#xA;# User specific aliases and functions&#xA;&#xA;alias rm=&#39;rm -i&#39;&#xA;alias cp=&#39;cp -i&#39;&#xA;alias mv=&#39;mv -i&#39;&#xA;&#xA;# Source global definitions&#xA;if [ -f /etc/bashrc ]; then&#xA;    . /etc/bashrc&#xA;fi&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h2&gt;注释掉那3行alias,保存,重新登录, 哦也, 世界清静了!!&lt;/h2&gt;&#xA;</description>
    </item>
    <item>
      <title>Deploy Nutz as HttpAPI by Jetty 7</title>
      <link>http://wendal.net/2012/1213.html</link>
      <pubDate>2012-12-13 12:00:00 +0800</pubDate>
      <description>&lt;h1&gt;将Nutz挂载到jetty上,作为HttpAPI&lt;/h1&gt;&#xA;&#xA;&lt;h2&gt;这里描述的,一个这样的web服务&lt;/h2&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;不需要jsp&lt;/li&gt;&#xA;&lt;li&gt;不需要静态资源,例如js/css&lt;/li&gt;&#xA;&lt;li&gt;仅挂载一个NutFilter,不需要其他jar&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;h2&gt;实现&lt;/h2&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;//新建一个Jetty Server,监听8080端口&#xA;Server server = new Server(8080); &#xA;//创建一个Servlet容器,并映射在根路径&#xA;ServletContextHandler ctx = new ServletContextHandler();&#xA;ctx.setContextPath(&amp;quot;/&amp;quot;);&#xA;&#xA;//加入默认Servlet或者空Servlet类,否则Filter类无法访问NutFilter&#xA;ctx.addServlet(DefaultServlet.class, &amp;quot;/*&amp;quot;);&#xA;//设置Session容器,否则Session不可以(Nutz会使用Session容器)&#xA;ctx.setSessionHandler(new SessionHandler(new HashSessionManager()));&#xA;&#xA;//创建Filter持有者,也就是挂载NutFilter&#xA;FilterHolder fh = new FilterHolder(NutFilter.class);&#xA;//传入必需的参数modules,你还可以传入ignore之类的参数&#xA;fh.setInitParameter(&amp;quot;modules&amp;quot;, &amp;quot;net.wendal.web.MainModule&amp;quot;);&#xA;ctx.addFilter(fh, &amp;quot;/*&amp;quot;, null);&#xA;&#xA;server.setHandler(ctx);&#xA;&#xA;//启动服务&#xA;server.start();&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h2&gt;通过nutz-web来实现&lt;/h2&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;// 创建一个web.properties,填入&#xA;app-root=.&#xA;app-port=8080&#xA;admin-port=8081&#xA;#mainModuleClassName这个参数请查阅最新的nutz-web代码&#xA;mainModuleClassName=net.wendal.web.MainModule&#xA;&#xA;//启动代码&#xA;public static void main(String[] args) {&#xA;    org.nutz.web.WebLauncher.main(args);&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h2&gt;nutz-web项目简介&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;一个Jetty封装,外加几个NutMvc的View, (项目地址)[http://github.com/nutzam/nutz]&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>ssh tunnel without shell</title>
      <link>http://wendal.net/linux/ssh-tunnel-without-shell/</link>
      <pubDate>2012-12-10 12:00:00 +0800</pubDate>
      <description>&lt;h1&gt;IT人士,必备翻墙梯&lt;/h1&gt;&#xA;&#xA;&lt;h2&gt;在VPS创建无权限的用户&lt;/h2&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;useradd -s /bin/false free2&#xA;passwd free2 #创建密码&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h2&gt;在本地访问之&lt;/h2&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;ssh -D 0.0.0.0:7070 -N -C free2@nutz.cn&#xA;#输入密码,就可以了&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h1&gt;前提?当然是你有自己的VPS了&lt;/h1&gt;&#xA;</description>
    </item>
    <item>
      <title>Reflect Of Golang</title>
      <link>http://wendal.net/2012/1130.html</link>
      <pubDate>2012-11-30 12:00:00 +0800</pubDate>
      <description>&lt;h2&gt;正在重新实现mustache for golang&lt;/h2&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;mustache作为模板引擎,必然需要用到反射啦&lt;/li&gt;&#xA;&lt;li&gt;官方的实现,就一个go源文件,几百行,蛋碎&lt;/li&gt;&#xA;&lt;li&gt;官方实现只返回一个string类型,出错就返回空字符串!!&lt;/li&gt;&#xA;&lt;li&gt;原本打算在上面改的,结果还是算了,重新实现一个更好,现在已经完成60%&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://github.com/wendal/mustache&#34;&gt;mustache from wendal&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;h2&gt;访问Map&lt;/h2&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;// 这里的参数和返回值都用了reflect.Value,是因为这是最下层的实现&#xA;// 在此之上,我们可以封装为 Get(_map interface{}, key string)之类的形式&#xA;func GetMapValue(value reflect.Value, key reflect.Value) (rs reflect.Value) {&#xA;    //进行任何反射操作之前,判断其可用性很重要&#xA;    if !value.IsVaild() {&#xA;        return&#xA;    }&#xA;    //判断其真实类型&#xA;    //注意,这里的真实,是指最终的类型,例如&#xA;    // type AAA map[string]string, 那么仍会得到map,而非AAA&#xA;    // 如果想得到AAA,那么应该使用 value.Type().Name()或者全路径value.Type().String()&#xA;    if value.Type().Kind() != reflect.Map {&#xA;        return &#xA;    }&#xA;&#xA;    //reflect包很多方法都是针对具体类型的,不合乎就panic&#xA;    //例如MapIndex,如果value不是map,就直接panic了&#xA;    rs = value.MapIndex(key)&#xA;    return&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h2&gt;访问数组/切片&lt;/h2&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;// 在取值方法,数组和切片的规则是一样的,提供索引值即可&#xA;func GetArrayValue(value reflect.Value, index int) (rs reflect.Value) {&#xA;    if !value.IsVaild() {&#xA;        return&#xA;    }&#xA;    if value.Type().Kind() != reflect.Array ||&#xA;         value.Type().Kind() != reflect.Slice {&#xA;        return &#xA;    }&#xA;&#xA;    // value.Len()仅限于array和slice,map,string哦&#xA;    if 0 &amp;lt;= index &amp;amp;&amp;amp; index &amp;lt; value.Len() {&#xA;        rs = value.Index(index)&#xA;    }&#xA;    return&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h2&gt;访问结构体及其指针&lt;/h2&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;// 这算是最复杂的了吧&#xA;// 这里演示一下把T和*T当成Map用,呵呵&#xA;// 也就是mustache模板引擎中Section节点&#xA;func GetStructValue(value reflect.Value, key string) (rs reflect.Value) {&#xA;    if !value.IsVaild() {&#xA;        return&#xA;    }&#xA;    if value.Type().Kind() == reflect.Ptr {&#xA;        //value.Elem()可以得到指针所指向的对象&#xA;        if value.Elem().Kind() != reflect.Struct {&#xA;            return&#xA;        }&#xA;    } else if value.Type().Kind() == reflect.Struct {&#xA;        return&#xA;    }&#xA;&#xA;    //好了,来取Struct的Field吧!&#xA;&#xA;    //首先,我们把*T还原为T&#xA;    //如果本来就是Struct,那么只是简单返回而已&#xA;    //指针类型是不能获取Field的&#xA;    v := reflect.Indirect(ctx.value)&#xA;    field := v.FieldByName(key)&#xA;    if field.IsValid() { //字段存在时返回true&#xA;        rs = field&#xA;        return&#xA;    }&#xA;&#xA;    //接下来,看看有米有对应的Method&#xA;    //注意,如果是*T,那么全部方法都能拿到&#xA;    //如果是T,那么只能获取那些非指针的方法哦&#xA;    //我也很纠结这个,尝试突破但没有成功&#xA;    t := value.Type()&#xA;    method, ok := t.MethodByName(key)&#xA;    if !ok { //没找到&#xA;        return&#xA;    }&#xA;&#xA;    //输入的参数必须为1,也就是当前value,当然,如果你知道其他参数,也可以是传参的,也就一个数组嘛&#xA;    //输出的参数不为0就好了,我们只需要取第一个&#xA;    if method.Func.Type().NumIn() != 1 || method.Func.Type().NumOut() == 0 {&#xA;        return  &#xA;    }&#xA;    //调用之&#xA;    rs = method.Func.Call([]reflect.Value{value})[0] //最后的[0]就是取第一个返回值&#xA;    return&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h2&gt;总结一下&lt;/h2&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;在任何reflect的func调用前,判断IsVaild&lt;/li&gt;&#xA;&lt;li&gt;判断具体类型,然后再调用相应的反射方法,不然分分钟会panic&lt;/li&gt;&#xA;&lt;li&gt;如果传入的是T,那么是无法访问指针类的方法的&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;</description>
    </item>
    <item>
      <title>Way of VPS</title>
      <link>http://wendal.net/linux/Way-of-VPS/</link>
      <pubDate>2012-11-25 12:00:00 +0800</pubDate>
      <description>&lt;h1&gt;VPS之路&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;从2009年5月份第一次购买VPS,已经3年多了.&#xA;尝试过超过5家的vps,最近换用80vps,但它能靠谱多久呢?&#xA;下一步,是不是独立服务器呢?&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;先说说vps&lt;/h2&gt;&#xA;&#xA;&lt;h3&gt;网速&lt;/h3&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;香港机房,对于南方来说,显然是最快的&lt;/li&gt;&#xA;&lt;li&gt;美国机房,西海岸的,对北方来说也很快&lt;/li&gt;&#xA;&lt;li&gt;但购买之前,仅能通过ping测试ip的方式来判断, 我就是这样上了yardvps&lt;/li&gt;&#xA;&lt;li&gt;yardvps的ping很快,貌似配置也给力,结果呢, 网络一段一段的,完全是废品级&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;h3&gt;IO性能&lt;/h3&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;大部分VPS的IO,都能到30m/s&lt;/li&gt;&#xA;&lt;li&gt;除了我遇到的某vps,IO性能烂到家, 有时候ls一下都要等2秒,能忍不?&lt;/li&gt;&#xA;&lt;li&gt;一般来说, 多跑几次dd就知道IO性能了&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;h3&gt;软件环境&lt;/h3&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;大部分VPS提供商都提供centos 5.x, 真正提供6.x系列的很少&lt;/li&gt;&#xA;&lt;li&gt;我正在使用80vps的香港机房就不能用centos 6.x,颇为不爽&lt;/li&gt;&#xA;&lt;li&gt;老内核, 尤其是glibc的版本太低,很多软件会安装不上,很是郁闷&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;h3&gt;虚拟化技术&lt;/h3&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;除非是玩php,那么OpenVZ肯定是死刑&lt;/li&gt;&#xA;&lt;li&gt;SunJDK在OpenVZ下是基本上启动不了,mongo也是&amp;hellip;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;h3&gt;客服&lt;/h3&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;vpsee的印象挺好的,但自从网速慢如乌龟,客服的答复一概推到GFW身上&lt;/li&gt;&#xA;&lt;li&gt;ctohome的客服很好,但是,机器实在太烂,多好的客服也白搭&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;h3&gt;罗列一下用过的vps&lt;/h3&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;ctohome OpenVZ 美国机房,各方面都平平&lt;/li&gt;&#xA;&lt;li&gt;vpsee   Xen    美国机房,一起挺好的,用得最久的提供商,今年来网速实在太慢&lt;/li&gt;&#xA;&lt;li&gt;yardvps Xen    美国机房,网络一断一断的,属于垃圾级&lt;/li&gt;&#xA;&lt;li&gt;某vps   Xen    美国机房,IO不给力,实在没法忍受&lt;/li&gt;&#xA;&lt;li&gt;80vps   Xen    香港机房,网速好(20ms,非常给力),但价钱贵,且不支持CentOS 6.x &lt;em&gt;更新: 已经支持了&lt;/em&gt;&lt;/li&gt;&#xA;&lt;li&gt;80vps   Xen    美国凤凰城机房,网速一般(170ms),价格够便宜(折合45/月), 峰值50M够给力&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;h2&gt;以后的计划, 独立服务器?&lt;/h2&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;vps毕竟是多人分享,资源竞争是必然的&lt;/li&gt;&#xA;&lt;li&gt;但,如果买那台相中的香港独立服务器,2年付送产品,要2w港币,实在不忍心&amp;hellip;&lt;/li&gt;&#xA;&lt;li&gt;好吧,再等等吧&lt;/li&gt;&#xA;&lt;li&gt;干脆贴一下 &lt;a href=&#34;http://vcp.80vps.com/page.aspx?c=referral&amp;amp;u=77998&#34;&gt;80vps的推荐链接&lt;/a&gt; 付费15天后,可以找我要回10%的费用, 相当于再9折&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;</description>
    </item>
    <item>
      <title>低调发布&#34;短点&#34;</title>
      <link>http://wendal.net/2012/1115.html</link>
      <pubDate>2012-11-15 12:00:00 +0800</pubDate>
      <description>&lt;h1&gt;庆祝SB大的结束&lt;/h1&gt;&#xA;&#xA;&lt;h2&gt;访问网址&lt;/h2&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;http://nutz.cn&#34;&gt;短点!&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;h2&gt;动机&lt;/h2&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;现有的短地址服务,各种河蟹,各种验证码,各种墙,XXXXXXXXXXXX!!&lt;/li&gt;&#xA;&lt;li&gt;只单独网址或文件,Wendal我极度不爽!!&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;h2&gt;用法&lt;/h2&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;直接贴长网址,然后按&amp;rdquo;短点!&amp;ldquo;,即刻给你清爽的短地址&lt;/li&gt;&#xA;&lt;li&gt;贴log,代码,长文章, 然后按&amp;rdquo;短点!&amp;ldquo;, 生成的网址有代码高亮哦&lt;/li&gt;&#xA;&lt;li&gt;需要分享文件?直接将其拖入输入框,即刻自动开始上传,完成后即得到短地址&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;h2&gt;功能限制&lt;/h2&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;文件及文本信息,上限10mb&lt;/li&gt;&#xA;&lt;li&gt;不保证时效(国内的服务压根就没告诉你这个),因为是无备份机制&lt;/li&gt;&#xA;&lt;li&gt;服务器总空间约15G,容量超标了我才会考虑删除老的记录&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;h2&gt;源码呢?&lt;/h2&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Wendal一向的风格, 猛击 (短点的源码)[https://github.com/wendal/shortit]&lt;/li&gt;&#xA;&lt;li&gt;基于Nutz,并没有使用数据库,是文件系统来实现&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;</description>
    </item>
    <item>
      <title>从WordPress迁移到Ruhoh的经验</title>
      <link>http://wendal.net/linux/%E4%BB%8EWordPress%E8%BF%81%E7%A7%BB%E5%88%B0Ruhoh%E7%9A%84%E7%BB%8F%E9%AA%8C/</link>
      <pubDate>2012-11-07 12:00:00 +0800</pubDate>
      <description>&lt;h2&gt;预备工作&lt;/h2&gt;&#xA;&#xA;&lt;h3&gt;备份旧博客&lt;/h3&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;备份mysql数据库中的wordpress数据&lt;/li&gt;&#xA;&lt;li&gt;备份wordpress所在的目录&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;h3&gt;迁移评论&lt;/h3&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;由于ruhoh是静态博客引擎,只能使用社会化评论系统了&lt;/li&gt;&#xA;&lt;li&gt;wordpress的评论转到DISQUS最为方便, 到DISQUS注册好,wordpress安装插件,等待导入完成即可&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;h3&gt;导出并转换旧博客的文章&lt;/h3&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;由于ruhoh只认markdown格式,需要将进行转换&lt;/li&gt;&#xA;&lt;li&gt;在wordpress控制界面导出wordpress.xml&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;h2&gt;转换老文章&lt;/h2&gt;&#xA;&#xA;&lt;h3&gt;安装ruby,以Fedora 14为例&lt;/h3&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;yum install libxml2-devel libtool gcc gcc-c++ make curl autoconf automake readline-devel&#xA;curl -L get.rvm.io | bash -s stable&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h3&gt;安装Jekyll,因为要用到其转换脚本&lt;/h3&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;gem install jekyll&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h3&gt;下载&lt;a href=&#34;https://gist.github.com/1394128&#34;&gt;转换脚本&lt;/a&gt;,并执行&lt;/h3&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;wget https://gist.github.com/raw/1394128/cc8a3113c76ab51ea262da517db533e43e7e8c5c/wordpressdotcom.rb&#xA;ruby wordpressdotcom.rb wordpress.xml /tmp/output/&#xA;#少量文章会转换失败,记下来,需要手工导入&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h2&gt;安装ruhoh&lt;/h2&gt;&#xA;&#xA;&lt;h3&gt;安装ruhoh和git,并测试一下是否可用&lt;/h3&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;yum install git&#xA;gem install ruhoh&#xA;ruhoh help&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h3&gt;建文件夹,拷贝已转的文章&lt;/h3&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;mkdir -p /home/web/&#xA;cd /home/web&#xA;ruhoh new wendal.net&#xA;cp /tmp/output/*.xml wendal.net/posts/&#xA;cd wendal.net&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h3&gt;编译一下,看看是否正常&lt;/h3&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;ruhoh compile&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h2&gt;清理自动转换的结果&lt;/h2&gt;&#xA;&#xA;&lt;h3&gt;为老文章修正为原本的wordpress permalink, 我原本的permalink是 /400.html&lt;/h3&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;wget https://github.com/wendal/wendal.net/raw/master/tools/fix_wp_id_permalink.go   &#xA;go run fix_wp_id_permalink.go posts/     #这是一个golang小脚本&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h3&gt;清理空行, 因为我发现自动转换后的文章带很多空行, 所以又写了一个脚本clean一下&lt;/h3&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;wget https://github.com/wendal/wendal.net/raw/master/tools/cleanup_blank_line.go&#xA;go run cleanup_blank_line.go posts/&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h3&gt;好了,清理完毕,再编译一次吧&lt;/h3&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;ruhoh compile&#xA;find compiled/ #可以看到老文章全部都变回/450.html形式的文件名&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h2&gt;设置DISQUS和google分析的账号,然后做些小配置&lt;/h2&gt;&#xA;&#xA;&lt;h3&gt;DISQUS的ID&lt;/h3&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;vim widgets/comments/config.yml #填入你老博客的ID&#xA;#当文章的路径跟原博客中的路径相同,DISQUS就能无缝还原之前的屏幕&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h3&gt;google分析的账号&lt;/h3&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;vim widgets/analytics/config.yml #然后填入你自己的ID&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h3&gt;关闭代码高亮的行号显示&lt;/h3&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;vim widgets/google_prettify/config.yml #设置为false&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h3&gt;修改首页,里面有些ruhoh的信息,删掉前面那部分即可&lt;/h3&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;vim pages/index.html &#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h3&gt;将图片/附件,导入新博客&lt;/h3&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;cp -r wp所在目录/wp-content/uploads/* media/&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h3&gt;在文章中查找 http://博客域名/wp-content/uploads,替换为&lt;/h3&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;\{\{ urls.media}} 并做适当的修正&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h3&gt;修正文章中的错误排版 &amp;ndash; 纯体力了&lt;/h3&gt;&#xA;&#xA;&lt;h3&gt;把导入失败的文章,按照&lt;a href=&#34;http://wowubuntu.com/markdown/&#34;&gt;markdown语法&lt;/a&gt;,手工转换为新格式&lt;/h3&gt;&#xA;&#xA;&lt;h3&gt;再编译一次吧&lt;/h3&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;ruhoh compile&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h2&gt;安装并配置nginx,实现平滑转换,减少坏链接&lt;/h2&gt;&#xA;&#xA;&lt;h3&gt;安装nginx,当然了,我建议自行编译&lt;/h3&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;yum install nginx&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h3&gt;修改nginx的配置文件,在将location / {} 替换为&lt;/h3&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;\# 这里是原本的feed地址, ruhoh下叫做rss.xml,需要映射一下&#xA;location = /feed {&#xA;    root   /home/web/wendal.net/compiled;&#xA;    rewrite /feed /rss.xml;&#xA;}&#xA;&#xA;\# 一起的分类目录,转到categories页面 -- 貌似不能直接跳到具体分类,原因不明&#xA;location /category/ {&#xA;    rewrite /category/(.+)/ /categories/#$1-ref permanent;&#xA;}&#xA;&#xA;\# 之前的标签页,转到tags页面&#xA;location /tag/ {&#xA;    rewrite /tag/(.+)/ /tags#$1-ref permanent;&#xA;}&#xA;&#xA;\# 直接指向compiled目录,并启用gzip,因为全是静态文件&#xA;location / {&#xA;    root   /home/web/wendal.net/compiled;&#xA;    gzip             on;&#xA;    gzip_min_length  1024;&#xA;    index  index.html index.htm;&#xA;    add_header Cache-Control &amp;quot;max-age=3600, must-revalidate&amp;quot;;&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h3&gt;启动nginx并测试之&lt;/h3&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;/usr/local/nginx/sbin/nginx -t&#xA;/usr/local/nginx/sbin/nginx&#xA;&#xA;#访问一下&#xA;curl -I http://127.0.0.1/&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h2&gt;呵呵,你已经搞定了,用浏览器访问一下你的新博客吧!&lt;/h2&gt;&#xA;</description>
    </item>
    <item>
      <title>Ruhoh,Now!</title>
      <link>http://wendal.net/linux/Ruhoh%2CNow%21/</link>
      <pubDate>2012-11-06 12:00:00 +0800</pubDate>
      <description>&lt;h2&gt;正式转用Ruhoh静态博客引擎&lt;/h2&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;wordpress贴code实在太痛苦,还要排版&lt;/li&gt;&#xA;&lt;li&gt;由于生成的是静态html,再也不必用神马php,世界清净了&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;h2&gt;博客内容完整迁移&lt;/h2&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;很早就转用DISQUS,所以全部评论都完整保留&lt;/li&gt;&#xA;&lt;li&gt;博客文章,转为markdown格式后,使用fix_wp_id_permalink.go和cleanup_blank_line.go修正为原链接及清理空行&lt;/li&gt;&#xA;&lt;li&gt;本网站的源码存在github的&lt;a href=&#34;http://github.com/wendal/wendal.net&#34;&gt;wendal.net库&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;前端使用nginx 1.2.4, 配合git hook实现自动更新(待完成)&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;h2&gt;启用80vps的香港机房,弃用vpsee&lt;/h2&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;自从上传GFW发威, vpsee的机房就没快过&lt;/li&gt;&#xA;&lt;li&gt;80vps的香港机房暂时看来还是很靠谱的,但峰值带宽只有1M&lt;/li&gt;&#xA;&lt;li&gt;作为翻墙主要途径, vpsee的速度根本无法满足需求了&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;h2&gt;启用cdnzz,放弃cloudflare&lt;/h2&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;自从使用cloudflare,总用人投诉说博客无法访问,甚为不爽&lt;/li&gt;&#xA;&lt;li&gt;当前使用cloudflare,也就是因为vpsee太慢&lt;/li&gt;&#xA;&lt;li&gt;cndzz收费,但1元/G,比较划算,按经验,每月流量也就2G&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;</description>
    </item>
    <item>
      <title>我做运维的那几个月</title>
      <link>http://wendal.net/465.html</link>
      <pubDate>2012-10-31 11:28:43 +0800</pubDate>
      <description>&lt;p&gt;怎么我觉得这题目这么俗呢? 好吧,将就着吧&lt;/p&gt;&#xA;&#xA;&lt;p&gt;肯定又有人骂了,wendal你不是做开发的吗?怎么又做运维了,你让不让人活啊?难道你公司就一个人?&lt;/p&gt;&#xA;&#xA;&lt;p&gt;话说,6月的最后一天,公司的someone说:&amp;ldquo;广州有几台机器需要修一下,要不你跑一趟?&amp;rdquo;,然后我答:&amp;ldquo;行啊,不就几台嘛&amp;rdquo;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;然后,就开始了漫长的运维&amp;hellip;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;谁想到要去这么多趟呢?谁想到那么多机器会出问题呢?谁想到那么多地方的信号不好呢? 那叫一个郁闷和纠结啊&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;说说经验吧&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;1. 别跟硬件较劲,坏了就是坏了,你是修不好的&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;灰尘太多,风扇卡死,机柜密封不透气,电压不稳,漏水,小昆虫,老鼠 &amp;ndash; 各种靠谱不靠谱的原因,导致各种各样的硬件损坏, 解决之道,唯有更换&lt;/p&gt;&#xA;&#xA;&lt;p&gt;最初硬是较劲,尝试fix各种不靠谱的问题,最近才发现很多都是硬件问题,浪费精力&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;2. 要精通各种网络连接方式(各种网络隧道,嘿嘿,就是翻V墙)&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;直接在大屏幕上看命令太不靠谱了,有时候还需要机器联网,让其他同事看&lt;/p&gt;&#xA;&#xA;&lt;p&gt;方法1: 设备&amp;ndash;网线&amp;ndash;笔记本电脑&amp;ndash;共享3G连接, 然后配合VPN,即可让同事远程访问故障机&lt;/p&gt;&#xA;&#xA;&lt;p&gt;方法2: 设备&amp;ndash;网线&amp;ndash;笔记本电脑&amp;ndash;Putty映射设备端口到远程服务器的某个端口,这样也可以让其他人访问到故障机&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;3. 尝试fix一个损坏的软件是不靠谱的&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;程序损坏,数据库数据错误,重新安装并导入数据,比尝试fix要快得多&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;4. 一次弄好,别太急了,弄不好就拿回家&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;遇到神奇的问题,一味尝试是没结果的,把设备带回家,网络好,什么都好,一会就搞定了&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>在windows下编译goexif</title>
      <link>http://wendal.net/462.html</link>
      <pubDate>2012-10-20 11:28:21 +0800</pubDate>
      <description>&lt;p&gt;纯go版:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;go get github.com/rwcarlsen/goexif/exif&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;cgo版:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;# 1. 下载libexif源码,获取头文件&#xA;# 2. 下载exif.dll, 记得下载cygwin下的版本, 直接google得到的版本不靠谱,版本太老&#xA;go get github.com/gosexy/exif&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&#34;/assets/media/2012/10/libexif-0.6.21.zip&#34;&gt;libexif-0.6.21&lt;/a&gt;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>查找mysql中的低效索引</title>
      <link>http://wendal.net/461.html</link>
      <pubDate>2012-10-11 09:39:38 +0800</pubDate>
      <description>&lt;p&gt;从一个&lt;a href=&#34;http://parand.com/say/index.php/2009/09/01/finding-and-fixing-slow-mysql-queries/&#34;&gt;外国博客&lt;/a&gt;引用过来的&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;SELECT t.TABLE_SCHEMA AS `db`,&#xA;t.TABLE_NAME AS `table`,&#xA;s.INDEX_NAME AS `index name`,&#xA;s.COLUMN_NAME AS `FIELD name`,&#xA;s.SEQ_IN_INDEX `seq IN index`,&#xA;s2.max_columns AS `# cols`,&#xA;s.CARDINALITY AS `card`,&#xA;t.TABLE_ROWS AS `est rows`,&#xA;ROUND(((s.CARDINALITY / IFNULL(t.TABLE_ROWS, 0.01)) * 100), 2) AS `sel %`&#xA;&#xA;FROM INFORMATION_SCHEMA.STATISTICS s&#xA;INNER JOIN INFORMATION_SCHEMA.TABLES t ON s.TABLE_SCHEMA = t.TABLE_SCHEMA AND s.TABLE_NAME = t.TABLE_NAME&#xA;INNER JOIN (&#xA;SELECT TABLE_SCHEMA, TABLE_NAME, INDEX_NAME, MAX(SEQ_IN_INDEX) AS max_columns&#xA;FROM INFORMATION_SCHEMA.STATISTICS&#xA;WHERE TABLE_SCHEMA != &#39;mysql&#39; GROUP BY TABLE_SCHEMA, TABLE_NAME, INDEX_NAME ) AS s2 ON s.TABLE_SCHEMA = s2.TABLE_SCHEMA AND s.TABLE_NAME = s2.TABLE_NAME AND s.INDEX_NAME = s2.INDEX_NAME&#xA;&#xA;WHERE t.TABLE_SCHEMA != &#39;mysql&#39; /* Filter out the mysql system DB */&#xA;AND t.TABLE_ROWS &amp;gt; 10 /* Only tables with some rows */&#xA;AND s.CARDINALITY IS NOT NULL /* Need at least one non-NULL value in the field */&#xA;AND (s.CARDINALITY / IFNULL(t.TABLE_ROWS, 0.01)) &amp;lt; 1.00 /* unique indexes are perfect anyway */&#xA;&#xA;ORDER BY `sel %`, s.TABLE_SCHEMA, s.TABLE_NAME /* DESC for best non-unique indexes */&#xA;LIMIT 10;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;</description>
    </item>
    <item>
      <title>Windows下隐藏Golang的DOS黑色窗口</title>
      <link>http://wendal.net/460.html</link>
      <pubDate>2012-10-07 09:45:59 +0800</pubDate>
      <description>&lt;p&gt;纯属自己mark一下,其实就是编译为Windows GUI程序, 默认是Windows Console程序&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;go build -ldflags -Hwindowsgui XXX.go&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;参考文档 &lt;a href=&#34;https://golang.org/cmd/ld/&#34;&gt;https://golang.org/cmd/ld/&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;续: 那怎么关掉这个程序呢?&lt;/p&gt;&#xA;&#xA;&lt;p&gt;可选方法: 在go代码中监听一个管理端口,用浏览器或telnet访问这个端口,就执行exit操作&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Golang连接Oracle数据库(通过OCI库)</title>
      <link>http://wendal.net/459.html</link>
      <pubDate>2012-10-06 11:17:54 +0800</pubDate>
      <description>&lt;p&gt;这是我对mattn/go-oci8的一个fork &lt;a href=&#34;https://github.com/wendal/go-oci8&#34;&gt;https://github.com/wendal/go-oci8&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;在Linux下的安装,应该是没啥难度的了,唯独蛋疼的Windows需要介绍一下:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;//假设的GOPATH指向C:\gohome&#xA;0. 执行 go get github.com/wendal/go-oci8 ,然后肯定是报错了,没关系,代码会下载下来.&#xA;1. 首先,你需要安装mingw到C:\mingw&#xA;2. 然后,到Oracle官网,下载OCI及其SDK,解压到instantclient_11_2  -- 当前最新版&#xA;3. 从我的go-oci8库的windows文件夹,拷贝pkg-config.exe到C:\mingw\bin\,拷贝oci8.pc到C:\mingw\lib\pkg-config\&#xA;4. 设置环境变量 PATH           ,值为     原有PATH;C:\instantclient_11_2;C:\mingw\bin;&#xA;5. 设置环境变量 PKG_CONFIG_PATH,值为     C:\mingw\lib\pkg-config&#xA;6. 接下来,就最重要的,就是再执行一次,这次应该能成功的:  go get github.com/wendal/go-oci8&#xA;7. 测试一下:&#xA;    cd %GOPATH%/src/github.com/wendal/go-oci8/example&#xA;    go run oracle.go&#xA;    #提醒一句, oracle.go里面的写的密码是system/123456, 实例名XE  &#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&#34;http://www.tudou.com/programs/view/yet9OngrV_4/&#34;&gt;视频演示&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&#34;https://github.com/wendal/go-oci8/downloads&#34;&gt;下载视频及编译环境&lt;/a&gt;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>简单好用的sshfs -- 通过ssh映射远程路径</title>
      <link>http://wendal.net/457.html</link>
      <pubDate>2012-09-26 08:52:25 +0800</pubDate>
      <description>&lt;p&gt;最近习惯性访问N个Linux机器,在不同机器间跳来跳去,很是麻烦,最终,找到了sshfs,可以把远程目录直接映射到本地,无需修改远程机器的设置,仅要求有ssh连接的权限(ssh都没有的话,还能干啥?!~!)&lt;/p&gt;&#xA;&#xA;&lt;p&gt;官网地址: &lt;a href=&#34;http://fuse.sourceforge.net/sshfs.html&#34;&gt;http://fuse.sourceforge.net/sshfs.html&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;安装:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;#如果是ubuntu&#xA;apt-get install sshfs&#xA;#如果是Fedore&#xA;yum install fuse-sshfs&#xA;#如果是CentOS,貌似只能自己安装了&#xA;wget http://nchc.dl.sourceforge.net/project/fuse/sshfs-fuse/2.4/sshfs-fuse-2.4.tar.gz&#xA;tar xvf sshfs-fuse-2.4.tar.gz&#xA;cd sshfs-fuse-2.4&#xA;./configure&#xA;#如果缺glib2什么的,就自行装上&#xA;make install&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;先看看选项:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;general options:&#xA;    -o opt,[opt...]        mount options&#xA;    -h   --help            print help&#xA;    -V   --version         print version&#xA;&#xA;SSHFS options:&#xA;    -p PORT                equivalent to &#39;-o port=PORT&#39;&#xA;    -C                     equivalent to &#39;-o compression=yes&#39; #启用压缩,建议配上&#xA;    -F ssh_configfile      specifies alternative ssh configuration file #使用非默认的ssh配置文件&#xA;    -1                     equivalent to &#39;-o ssh_protocol=1&#39; #不要用啊&#xA;    -o reconnect           reconnect to server               #自动重连&#xA;    -o delay_connect       delay connection to server&#xA;    -o sshfs_sync          synchronous writes&#xA;    -o no_readahead        synchronous reads (no speculative readahead) #提前预读&#xA;    -o sshfs_debug         print some debugging information&#xA;    -o cache=BOOL          enable caching {yes,no} (default: yes) #能缓存目录结构之类的信息&#xA;    -o cache_timeout=N     sets timeout for caches in seconds (default: 20)&#xA;    -o cache_X_timeout=N   sets timeout for {stat,dir,link} cache&#xA;    -o workaround=LIST     colon separated list of workarounds&#xA;             none             no workarounds enabled&#xA;             all              all workarounds enabled&#xA;             [no]rename       fix renaming to existing file (default: off)&#xA;             [no]nodelaysrv   set nodelay tcp flag in sshd (default: off)&#xA;             [no]truncate     fix truncate for old servers (default: off)&#xA;             [no]buflimit     fix buffer fillup bug in server (default: on)&#xA;    -o idmap=TYPE          user/group ID mapping, possible types are:  #文件权限uid/gid映射关系&#xA;             none             no translation of the ID space (default)&#xA;             user             only translate UID of connecting user&#xA;    -o ssh_command=CMD     execute CMD instead of &#39;ssh&#39;&#xA;    -o ssh_protocol=N      ssh protocol to use (default: 2) #肯定要2的&#xA;    -o sftp_server=SERV    path to sftp server or subsystem (default: sftp)&#xA;    -o directport=PORT     directly connect to PORT bypassing ssh&#xA;    -o transform_symlinks  transform absolute symlinks to relative&#xA;    -o follow_symlinks     follow symlinks on the server&#xA;    -o no_check_root       don&#39;t check for existence of &#39;dir&#39; on server&#xA;    -o password_stdin      read password from stdin (only for pam_mount)&#xA;    -o SSHOPT=VAL          ssh options (see man ssh_config)&#xA;&#xA;Module options:&#xA;&#xA;[subdir]&#xA;    -o subdir=DIR       prepend this directory to all paths (mandatory)&#xA;    -o [no]rellinks     transform absolute symlinks to relative&#xA;&#xA;[iconv]&#xA;    #字符集转换,对我这种UTF8控,默认已经是最好的&#xA;    -o from_code=CHARSET   original encoding of file names (default: UTF-8)&#xA;    -o to_code=CHARSET      new encoding of the file names (default: UTF-8)&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;实际使用:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;挂载(如果配上ssh key就可以完全自动化了):&#xA;sshfs root@192.168.9.109:/opt /opt/s109&#xA;卸载:&#xA;fusermount -u /opt/s109&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;</description>
    </item>
    <item>
      <title>在Android中运行go程序(Golang 1.0.2, ARM 6)</title>
      <link>http://wendal.net/454.html</link>
      <pubDate>2012-08-31 10:14:37 +0800</pubDate>
      <description>&lt;p&gt;原本以为很简单的,网上一堆什么5g啊5l啊, 下载go 1.0.2才发现, 我去,根本就没有5g和5l&lt;/p&gt;&#xA;&#xA;&lt;p&gt;难道是官方编译版本没带而已,我自己编译一个呗&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;apt-get install gcc libc6-dev ercurial&#xA;#yum install gcc libc6-devel mercurial&#xA;&#xA;#预先把变量设置好&#xA;export GOROOT=$HOME/go&#xA;export PATH=$PATH:$GOROOT/bin&#xA;&#xA;#获取go的源码&#xA;cd $HOME&#xA;hg clone -u release https://code.google.com/p/go&#xA;cd go/src&#xA;./all.bash&#xA;&#xA;#这样就安装好适合当前系统的go,但还需要arm(即Android的低层环境)的版本&#xA;CGO_ENABLED=0 GOARCH=arm GOOS=linux ./make.bash&#xA;&#xA;#验证一下,应该会显示有5g和5l&#xA;go tool&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;接下来,就是写个hello world,然后编译&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;CGO_ENABLED=0 GOARCH=arm go build hi.go&#xA;./hi&#xA;#呵呵,自己试试吧&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;提醒一句, 虽然可以通过变通的方式用上cgo,但据说不推荐,所以暂时还是不要用了&lt;/p&gt;&#xA;&#xA;&lt;p&gt;参考文章: &lt;a href=&#34;https://groups.google.com/forum/?fromgroups=#!topic/golang-nuts/ESQ0_yxH130&#34;&gt;https://groups.google.com/forum/?fromgroups=#!topic/golang-nuts/ESQ0_yxH130&lt;/a&gt;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>换种顺序来执行TestCase(Junit适用)</title>
      <link>http://wendal.net/453.html</link>
      <pubDate>2012-08-26 10:18:26 +0800</pubDate>
      <description>&lt;p&gt;Junit的TestCase,总是按固定的顺序执行的. 正如你在Eclipse中跑Run As Junit Test, 无论你跑多少次, TestCase的执行顺序都是一致的,可重复的. 这就导致一个问题, TestCase之间的独立性无法保证.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;例如下面一个Test类中的2个TestCase:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;public class DaoTest {&#xA;&#xA;    @Test&#xA;    public void test_count() {&#xA;        dao.insert(new User(&amp;quot;root&amp;quot;, &amp;quot;123456&amp;quot;));&#xA;        assertEquals(1, dao.count(User.class));&#xA;    }&#xA;&#xA;    @Test&#xA;    public void test_insert() {&#xA;        dao.clear(User.class, null);&#xA;        dao.insert(new User(&amp;quot;admin&amp;quot;, &amp;quot;123456&amp;quot;));&#xA;        assertEquals(1, dao.count(User.class));&#xA;    }&#xA;&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;如果先执行test_count()然后执行test_insert(),两个TestCase都能通过.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;但如果先执行test_insert(),然后执行test_count(),则test_count()会失败.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;所以,有必要去打乱TestCase的默认执行顺序,以暴露出TestCase本身的问题. TestCase更可靠,才能让主代码更可靠.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;我实现了一个简单的方式,使用的是Junit的公开API, 测试过4.3和4.8.2,均可使用:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;        //得到所有带@Test的方法,这里用的是Nutz的资源扫描,反正你能得到全部Test类就行&#xA;        List&amp;lt;Class&amp;gt; list = Scans.me().scanPackage(&amp;quot;org.nutz&amp;quot;);&#xA;        List&amp;lt;request&amp;gt; reqs = new ArrayList&amp;lt;request&amp;gt;();&#xA;        Map&amp;lt;Request, Method&amp;gt; reqMap = new HashMap&amp;lt;Request, Method&amp;gt;();&#xA;        for (Class clazz : list) {&#xA;            Method[] methods = clazz.getMethods();&#xA;            for (Method method : methods) {&#xA;                if (method.getAnnotation(Test.class) != null) {&#xA;                    //将单个TestCase(即一个Test Method),封装为Junit的Test Request&#xA;                    Request req = Request.method(clazz, method.getName());&#xA;                    reqs.add(req);&#xA;                    reqMap.put(req , method);//在最终打印测试结果时,方便查找具体出错的Method&#xA;                }&#xA;            }&#xA;        }&#xA;&#xA;        // 因为reqs 是一个List,我们可以按需调整TestCase的顺序&#xA;        // 正序 //nothing change.&#xA;        // 反序Collections.reverse(reqs)&#xA;        // 乱序Collections.shuffle(reqs)&#xA;&#xA;        //把执行顺序保存下来,方便重现执行顺序&#xA;        try {&#xA;            FileWriter fw = new FileWriter(&amp;quot;./test_order.txt&amp;quot;);&#xA;            for (Request request : reqs) {&#xA;                fw.write(reqMap.get(request).toString());&#xA;                fw.write(&amp;quot;\n&amp;quot;);&#xA;            }&#xA;            fw.flush();&#xA;            fw.close();&#xA;        }&#xA;        catch (IOException e) {}&#xA;&#xA;        //到这里, List已经按我们预期的方式排好,可以执行测试了&#xA;        final TestResult result = new TestResult();&#xA;        RunNotifier notifier = new RunNotifier();&#xA;        notifier.addListener(new RunListener() { //需要设置一个RunListener,以便收集测试结果&#xA;&#xA;            public void testFailure(Failure failure) throws Exception {&#xA;                result.addError(asTest(failure.getDescription()), failure.getException());&#xA;            }&#xA;            public void testFinished(Description description) throws Exception {&#xA;                result.endTest(asTest(description));&#xA;            }&#xA;            public void testStarted(Description description) throws Exception {&#xA;                result.startTest(asTest(description));&#xA;            }&#xA;&#xA;            public junit.framework.Test asTest(Description description) {&#xA;                return new junit.framework.Test() {&#xA;&#xA;                    public void run(TestResult result) {&#xA;                        throw Lang.noImplement();&#xA;                    }&#xA;&#xA;                    public int countTestCases() {&#xA;                        return 1;&#xA;                    }&#xA;                };&#xA;            }&#xA;        });&#xA;        //来吧,执行之!!&#xA;        for (Request request : reqs) {&#xA;            request.getRunner().run(notifier);&#xA;        }&#xA;&#xA;        //接下来,就是打印结果了.&#xA;        System.out.printf(&amp;quot;Run %d , Fail %d , Error %d \n&amp;quot;, result.runCount(), result.failureCount(), result.errorCount());&#xA;&#xA;        if (result.failureCount() &amp;gt; 0) { //断言失败的TestCase&#xA;            Enumeration&amp;lt;testfailure&amp;gt; enu = result.failures();&#xA;            while (enu.hasMoreElements()) {&#xA;                TestFailure testFailure = (TestFailure) enu.nextElement();&#xA;                System.out.println(&amp;quot;--Fail------------------------------------------------&amp;quot;);&#xA;                System.out.println(testFailure.trace());&#xA;                testFailure.thrownException().printStackTrace(System.out);&#xA;            }&#xA;        }&#xA;&#xA;        if (result.errorCount() &amp;gt; 0) { //抛异常的TestCase&#xA;            Enumeration&amp;lt;testfailure&amp;gt; enu = result.errors();&#xA;            while (enu.hasMoreElements()) {&#xA;                TestFailure testFailure = (TestFailure) enu.nextElement();&#xA;                System.out.println(&amp;quot;--ERROR------------------------------------------------&amp;quot;);&#xA;                System.out.println(testFailure.trace());&#xA;                testFailure.thrownException().printStackTrace(System.out);&#xA;            }&#xA;        }&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;来, 考验一下你的TestCase吧!! 让它在乱序中多次执行. Nutz按这种思路,已经爆出几个Bug(当然,我已经迅速fix了)&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&#34;https://github.com/nutzam/nutz/blob/master/test/org/nutz/AdvancedTestAll.java&#34;&gt;https://github.com/nutzam/nutz/blob/master/test/org/nutz/AdvancedTestAll.java&lt;/a&gt;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>fql改造记录 -- fql is a tool that use SQL like query to manipulate files</title>
      <link>http://wendal.net/450.html</link>
      <pubDate>2012-08-13 04:52:41 +0800</pubDate>
      <description>&lt;p&gt;fql is a tool that use SQL like query to manipulate files&lt;/p&gt;&#xA;&#xA;&lt;p&gt;挺好玩的一个小工具, 用SQL语法来find文件,官网 &lt;a href=&#34;https://github.com/dccmx/fql&#34; title=&#34;fql is a tool that use SQL like query to manipulate files.&#34; target=&#34;_blank&#34;&gt;https://github.com/dccmx/fql&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&lt;p&gt;添加readline支持, 原本是极其简单的fgets读取输入,那叫一个简陋啊&lt;/p&gt;&#xA;&#xA;&lt;p&gt;//添加headers&#xA;#if defined(HAVE_LIBREADLINE) &amp;amp;&amp;amp; HAVE_LIBREADLINE==1&lt;/p&gt;&#xA;&#xA;&lt;h1&gt;&lt;a style=&#34;display: block;&#34; name=&#34;include-&amp;lt;readline/readline.h&amp;gt;&#34; href=&#34;#include-&amp;lt;readline/readline.h&amp;gt;&#34;&gt;&lt;/a&gt;include &lt;readline/readline.h&gt;&lt;/h1&gt;&#xA;&#xA;&lt;h1&gt;&lt;a style=&#34;display: block;&#34; name=&#34;include-&amp;lt;readline/history.h&amp;gt;&#34; href=&#34;#include-&amp;lt;readline/history.h&amp;gt;&#34;&gt;&lt;/a&gt;include &lt;readline/history.h&gt;&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;#endif&lt;/p&gt;&#xA;&#xA;&lt;p&gt;//改造其获取输入的代码:&#xA;#if defined(HAVE_LIBREADLINE) &amp;amp;&amp;amp; HAVE_LIBREADLINE==1&#xA;  if (isatty(STDIN_FILENO)) { //如果是控制台输入,则输出提示符&#xA;      str = readline(&amp;ldquo;&amp;gt; &amp;ldquo;);&#xA;      if( str &amp;amp;&amp;amp; *str )&#xA;          add_history(str); //加入到readline历史记录&#xA;      else&#xA;          continue;&#xA;  } else {&#xA;      str = readline(&amp;ldquo;&amp;rdquo;);&#xA;      if (! str) break;&#xA;  }&#xA;#else&#xA;  //老的,直接读取的方法, 不带历史记录,无法读取多行文本&#xA;  if (isatty(STDIN_FILENO)) printf(&amp;ldquo;&amp;gt; &amp;ldquo;);&#xA;  char str[1024];&#xA;  fgets(str, 1024, stdin);&#xA;  if (feof(stdin)) break;&#xA;  if (!str || !strcmp(&amp;rdquo;\n&amp;rdquo;, str) || !strcmp(&amp;rdquo;\r\n&amp;rdquo;, str)) continue;&#xA;#endif&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;改为autoconf. 原项目是手写的Makefile,比较蛋疼(例如无法直接使用clang编译)&lt;/p&gt;&#xA;&#xA;&lt;p&gt;autoscan&#xA;mv configure.scan configure.in&lt;/p&gt;&#xA;&#xA;&lt;p&gt;vim configure.in&#xA;#添加AM_INIT_AUTOMAKE,填上版本号,联系人等信息&lt;/p&gt;&#xA;&#xA;&lt;p&gt;vim Makefile.am&#xA;#写上fql_SOURCES bin_PROGRAMS等&lt;/p&gt;&#xA;&#xA;&lt;p&gt;aclocal&#xA;automake -a&lt;/p&gt;&#xA;&#xA;&lt;p&gt;#搞定, 可以编译了&#xA;./configure&#xA;make&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;修正一个小bug&amp;ndash;当文件夹或文件的uid或gid不合法时(指向一个不存在的用户),会发生段错误&lt;/p&gt;&#xA;&#xA;&lt;p&gt;if (*ite == &amp;ldquo;uname&amp;rdquo;) {&#xA;  struct passwd *pw = getpwuid(st.st_uid);&#xA;  if (pw)&#xA;      row.push_back(new String(pw-&amp;gt;pw_name));&#xA;  else&#xA;      row.push_back(new String(&amp;ldquo;&amp;rdquo;));&#xA;} else if (*ite == &amp;ldquo;gname&amp;rdquo;) {&#xA;  struct group *grp = getgrgid(st.st_gid);&#xA;  if (grp)&#xA;      row.push_back(new String(grp-&amp;gt;gr_name));&#xA;  else&#xA;      row.push_back(new String(&amp;ldquo;&amp;rdquo;));&#xA;}&lt;/p&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;p&gt;再fix掉clang编译时的一个小warning,搞定!&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;CXX=clang CC=clang LDFLAGS=&amp;quot;-Wall -lstdc++&amp;quot; ./configure&#xA;make&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;最大的收获,就是知道原来平时命令行中,向上向下,查询历史命令,都是readline做的,一直以为是系统级的功能&amp;hellip;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Golang连接Mysql</title>
      <link>http://wendal.net/448.html</link>
      <pubDate>2012-07-31 07:33:39 +0800</pubDate>
      <description>&lt;p&gt;首先,安装golang-mysql库, 我这里选用是google上的&lt;a href=&#34;http://code.google.com/p/go-mysql-driver/&#34;&gt;go-mysql-driver&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;go get code.google.com/p/go-mysql-driver/mysql&#xA;#如果访问失败,请翻墙吧!! 需要mysql 4.1以上哦&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;然后,当然是我的最爱 &amp;ndash; 代码&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;package main&#xA;&#xA;// 导入sql包, 跟java.sql类似的&#xA;import &amp;quot;database/sql&amp;quot;&#xA;import _ &amp;quot;code.google.com/p/go-mysql-driver/mysql&amp;quot;&#xA;import &amp;quot;encoding/json&amp;quot;&#xA;import &amp;quot;fmt&amp;quot;&#xA;&#xA;// 定义一个结构体, 需要大写开头哦, 字段名也需要大写开头哦, 否则json模块会识别不了&#xA;// 结构体成员仅大写开头外界才能访问&#xA;type User struct {&#xA;    User      string    `json:&amp;quot;user&amp;quot;`&#xA;    Password string `json:&amp;quot;password&amp;quot;`&#xA;    Host   string `json:&amp;quot;host&amp;quot;`&#xA;}&#xA;&#xA;// 一如既往的main方法&#xA;func main() {&#xA;    // 格式有点怪, @tcp 是指网络协议(难道支持udp?), 然后是域名和端口&#xA;    db, e := sql.Open(&amp;quot;mysql&amp;quot;, &amp;quot;root:123456@tcp(localhost:3306)/mysql?charset=utf8&amp;quot;)&#xA;    if e != nil { //如果连接出错,e将不是nil的&#xA;        print(&amp;quot;ERROR?&amp;quot;)&#xA;        return&#xA;    }&#xA;    // 提醒一句, 运行到这里, 并不代表数据库连接是完全OK的, 因为发送第一条SQL才会校验密码 汗~!&#xA;    _, e2 := db.Query(&amp;quot;select 1&amp;quot;)&#xA;    if e2 == nil {&#xA;        println(&amp;quot;DB OK&amp;quot;)&#xA;        rows, e := db.Query(&amp;quot;select user,password,host from mysql.user&amp;quot;)&#xA;        if e != nil {&#xA;            fmt.Print(&amp;quot;query error!!%v\n&amp;quot;, e)&#xA;            return&#xA;        }&#xA;        if rows == nil {&#xA;            print(&amp;quot;Rows is nil&amp;quot;)   &#xA;            return&#xA;        }&#xA;        for rows.Next() { //跟java的ResultSet一样,需要先next读取&#xA;            user := new(User)&#xA;            // rows貌似只支持Scan方法 继续汗~! 当然,可以通过GetColumns()来得到字段顺序&#xA;            row_err := rows.Scan(&amp;amp;user.User;,&amp;amp;user.Password;, &amp;amp;user.Host;)&#xA;            if row_err != nil {&#xA;                print(&amp;quot;Row error!!&amp;quot;)&#xA;                return&#xA;            }&#xA;            b, _ := json.Marshal(user)&#xA;            fmt.Println(string(b)) // 这里没有判断错误, 呵呵, 一般都不会有错吧&#xA;        }&#xA;        println(&amp;quot;Done&amp;quot;)&#xA;    }&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;编译后, 体积高达2.5mb, 实在惊人. 运行速度也很不错, 0.012秒完成:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;linux-9rhn:/home/go # time ./test_mysql&#xA;DB OK&#xA;{&amp;quot;user&amp;quot;:&amp;quot;root&amp;quot;,&amp;quot;password&amp;quot;:&amp;quot;*6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9&amp;quot;,&amp;quot;host&amp;quot;:&amp;quot;localhost&amp;quot;}&#xA;{&amp;quot;user&amp;quot;:&amp;quot;root&amp;quot;,&amp;quot;password&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;host&amp;quot;:&amp;quot;linux-9rhn&amp;quot;}&#xA;{&amp;quot;user&amp;quot;:&amp;quot;root&amp;quot;,&amp;quot;password&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;host&amp;quot;:&amp;quot;127.0.0.1&amp;quot;}&#xA;{&amp;quot;user&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;password&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;host&amp;quot;:&amp;quot;localhost&amp;quot;}&#xA;{&amp;quot;user&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;password&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;host&amp;quot;:&amp;quot;linux-9rhn&amp;quot;}&#xA;Done&#xA;&#xA;real 0m0.012s&#xA;user 0m0.008s&#xA;sys  0m0.000s&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;附上一句, 不用猜密码了,是123456, 写着呢&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>在Golang中,Log打印行号等信息</title>
      <link>http://wendal.net/446.html</link>
      <pubDate>2012-07-24 07:11:08 +0800</pubDate>
      <description>&lt;p&gt;做个小笔记, 默认情况下,log模块的只打印日期和时间, 没具体行号,比较不爽,嘿嘿&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;package main&#xA;/*&#xA;#include &amp;lt;stdlib.h&amp;gt;&#xA;*/&#xA;import &amp;quot;C&amp;quot;&#xA;import &amp;quot;log&amp;quot;&#xA;&#xA;func main() {&#xA;    log.SetFlags(log.Lshortfile | log.LstdFlags)&#xA;    log.Println( C.random())&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;打印结果:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;2012/07/24 19:27:55 X.cgo1.go:14: 1804289383&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;其中, log.Lshortfile 还可以设置为log.Llongfile 即完整文件路径&lt;/p&gt;&#xA;&#xA;&lt;p&gt;获取当前行数,文件名,函数名(方法名):&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;package main&#xA;&#xA;import (&#xA;       &amp;quot;runtime&amp;quot;&#xA;       &amp;quot;fmt&amp;quot;&#xA;)&#xA;&#xA;func main() {&#xA;        funcName, file, line, ok := runtime.Caller(0)&#xA;        if ok {&#xA;            fmt.Println(&amp;quot;Func Name=&amp;quot; + runtime.FuncForPC(funcName).Name())&#xA;            fmt.Printf(&amp;quot;file: %s    line=%d\n&amp;quot;, file, line)&#xA;        }&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;</description>
    </item>
    <item>
      <title>Nutz T恤与小鸣鸣</title>
      <link>http://wendal.net/441.html</link>
      <pubDate>2012-07-21 09:29:48 +0800</pubDate>
      <description>&lt;p&gt;&lt;img src=&#34;/assets/media/2012/07/DSCF06572.jpg&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>45分钟的Nutz敲门砖,高清无码 -- [视频教程] Nutz详解-基础框架的搭建</title>
      <link>http://wendal.net/438.html</link>
      <pubDate>2012-07-20 09:47:17 +0800</pubDate>
      <description>&lt;p&gt;Nutz入门教程, 高清无码哦&lt;/p&gt;&#xA;&#xA;&lt;p&gt;下载地址:&#xA;&lt;a href=&#34;http://code.google.com/p/nutz/downloads/list&#34;&gt;http://code.google.com/p/nutz/downloads/list&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;长达45分钟,让你一次性体会Nutz的3大块: Mvc Ioc Dao&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2012/07/A.jpg&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2012/07/B.jpg&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>NutMVC的View怎么玩?</title>
      <link>http://wendal.net/436.html</link>
      <pubDate>2012-06-29 11:24:44 +0800</pubDate>
      <description>&lt;p&gt;&lt;strong&gt;撒手不管 VoidView:&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;@Ok(&amp;quot;void&amp;quot;) //不做任何操作,不理会任何返回值,不碰resp对象!!&#xA;&#xA;//适合控制欲极强的童鞋,或有特别需要的&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;ajax好基友 UTF8JsonView:&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;@Ok(&amp;quot;json&amp;quot;) // 将任何返回值转换为json字符串,后面可以加jsonFormat参数&#xA;//注意,使用这个视图,你就不要自己拼json字符串了!! 返回map/list/pojo吧!!&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;示例页面js调用:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;$.ajax({&#xA;  url: &amp;quot;${base}/login&amp;quot;,&#xA;  dataType : &amp;quot;json&amp;quot;,&#xA;  data : {&amp;quot;user&amp;quot; : &amp;quot;wendal&amp;quot;, &amp;quot;passwd&amp;quot; : &amp;quot;123456&amp;quot;}, //或者 表单数据&#xA;  //如果是复杂的对象,建议使用$.toJSON(obj) 然后后台使用@Adpter(JsonAdpter.class)&#xA;  success : function(re) {&#xA;    if (re.ok) {&#xA;      alert(&#39;登陆成功&#39;);&#xA;      windows.location = &amp;quot;${base}/home&amp;quot;; //跳转到某个URL去, 多嘴一句,ajax是不能自动识别302的!!&#xA;    } else {&#xA;      alert(&#39;登陆失败,请检查用户名及密码!!&#39;);&#xA;    };&#xA;  },&#xA;  fail : function(err) {&#xA;    alert(&amp;quot;服务器错误: &amp;quot;+ err);&#xA;  }&#xA;});&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;纯情 RawView:&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;@Ok(&amp;quot;raw&amp;quot;) //非常单纯地把返回值写入resp&#xA;&#xA;//虽然很外表单纯,但很有内涵哦&#xA;// 如果返回值是File的话,会让浏览器弹出下载框哦 -- 传说中的文件下载&#xA;// 这个视图可以接受具体ContentType哦: @Ok(&amp;quot;raw:application/vnd.ms-excel&amp;quot;)&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;一意孤行 HttpStatusView:&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;@Ok(&amp;quot;http:403&amp;quot;) //管你返回什么,一概sendError(403) !!&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;幕后英雄 AbstractPathView:&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;这可是ForwardView和ServerRedirectView,JspView的超类,虽然没啥人直接用它&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Nutz视图中的路径转换,就是这个类做的,我这里再描述一下这个规则:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;//首先,不考虑后缀的情况下:&#xA;// 1. 将路径中的.全部转换为/&#xA;// 2. 如果路径不是/开头,则添加/WEB-INF/&#xA;&#xA;//然后是带后缀了, 简单来说就是直接添加后缀&#xA;&#xA;// 来个小测试, 假设后缀为jsp&#xA;abc.efg.QQ       --&amp;gt; /WEB-INF/abc/efg/QQ.jsp 不以/开头,故,添加/WEB-INF/&#xA;/abc.efg.QQ      --&amp;gt; /abc/efg/QQ.jsp         以/开头,全部.转为/后,添加后缀.jsp&#xA;abc.jsp          --&amp;gt; /WEB-INF/abc/jsp.jsp    记住,是先全部替换.为/,然后添加后缀哦!!&#xA;/abc/jsp/ZZ      --&amp;gt; /abc/jsp/ZZ.jsp&#xA;&#xA;//JspView只是带后缀的ForwardView而已!!&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;自给自足 自定义View:&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;国情就是这么复杂,需求就是这么纠结,Nutz的内置View就是说没法满足你的要求?&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;情况1: 需要根据不同情况跳转(或forward)到不同的URL&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;继承AbstractPathView的类,均支持EL表达式&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;@Ok(&amp;quot;jsp:${obj == null ? &#39;/index&#39; : &#39;/home&#39;}&amp;quot;) &#xA;// obj即方法的返回值, 事实上有需要可用的变量,例如req_attr,p,u等等非公开变量,快去看看源码吧!!&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;情况2 按需使用不同的视图:&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;return HttpStatusView(403); //当方法的返回值是View实例时,将无视@Ok的设置&#xA;// 很多时候,你需要携带一些信息, 故,你会这样写:&#xA;return new ViewWrapper(new JspView(&amp;quot;fuck.gfw&amp;quot;), msg); //这里的msg,在JspView看来,就是方法的返回值obj&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;情况3 符合固定行为的视图:&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;这个就完成是自定义视图了,实现你自己的ViewMaker及View类,例如最简单的jsonext视图:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;public SuperViewMaker implements ViewMaker {&#xA;  public View make(Ioc ioc, String type, String value) {&#xA;    if (&amp;quot;jsonext&amp;quot;.equals(type))&#xA;      return new JsonExtView(value);&#xA;    return null; //这个很重要,你不认识的视图类型,就应该返回null哦!&#xA;  }&#xA;}&#xA;&#xA;public JsonExtView extend UTF8JsonView {&#xA;  public JsonExtView() {&#xA;    super(JsonFormat.nice());&#xA;  }&#xA;  public void render(HttpServletRequest req, HttpServletResponse resp, Object obj)&#xA;            throws IOException {&#xA;    resp.setHeader(&amp;quot;Cache-Control&amp;quot;, &amp;quot;no-cache&amp;quot;);&#xA;    resp.setContentType(&amp;quot;application/json&amp;quot;); //这是跟UTF8JsonView唯一不一样的逻辑&#xA;    Json.toJson(resp.getWriter(), obj, format);&#xA;    resp.flushBuffer();&#xA;  }&#xA;}&#xA;&#xA;//当然,你还需要在主模块声明一下这个ViewMaker&#xA;@Views({SuperViewMaker.class})&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;另外,你可以通过IocView的方式变通一下,免得自己写ViewMaker&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>NutIoc的执行过程</title>
      <link>http://wendal.net/434.html</link>
      <pubDate>2012-06-23 07:05:17 +0800</pubDate>
      <description>&lt;p&gt;越来越多人阅读Nutz的源码,很是欣慰.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;首先,什么是Ioc呢? Ioc本质上就是一个有状态的Map&lt;String,Object&gt;, 其中bean就是用户通过各种形式的配置信息所定义的对象&lt;/p&gt;&#xA;&#xA;&lt;p&gt;先上一段代码,通过一个js配置一个Ioc容器,并获取一个bean&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;public static void main(String[] args) {&#xA;    IocLoader loader = new JsonLoader(&amp;quot;ioc.js&amp;quot;);&#xA;    Ioc ioc = new NutIoc(loader);&#xA;    Pet pet = ioc.get(Pet.class, &amp;quot;pet&amp;quot;);&#xA;    System.out.println(pet.getName());&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;ioc的js配置文件(ioc.js,名字是随意的)&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;var ioc = {&#xA;    pet : {&#xA;        type : &amp;quot;net.wendal.test.Pet&amp;quot;,&#xA;        fields : {&#xA;            name : &amp;quot;wendal&amp;quot;&#xA;        }&#xA;    }&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;Ioc第一步,读取bean的配置信息&lt;/strong&gt; : 任何bean,都有其对应的配置信息,都必须通过一个IocLoader来读取&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;IocLoader loader = new JsonLoader(&amp;quot;ioc.js&amp;quot;);&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&lt;p&gt;从ioc.js中读取配置信息&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;ioc.js中,有个前缀&amp;rdquo;var ioc =&amp;ldquo;字符串,这是为了方便Eclipse进行语法提示而已, 写不写都可以,但只能写这个字符串,这是JsonLoader所约定的&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;ioc.js仅定义了一个bean,名叫pet,任何bean都必须有唯一的名字, 因为Ioc实质上就是一个Map&lt;String,Object&gt;,其中的key就是bean的名字&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;这个bean的信息,会保存在IocObject中, 注意,这是配置信息, 真正的对象并未生成&lt;/p&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;第二步,生成Ioc容器&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;Ioc ioc = new NutIoc(loader);&#xA;//只是进行一些必要的初始化,并完成与Aop的连接点&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;第三步,获取对象&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;Pet pet = ioc.get(Pet.class, &amp;quot;pet&amp;quot;);&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;这时候, 具体的Pet实例要准备生成了&lt;/p&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&lt;p&gt;首先,需要生成IocLoading &amp;ndash;&amp;gt; createLoading()&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;然后通过 iocloader的load方法,拿到IocObject, 即bean的配置信息&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;接着IocMaker实例,通过IocObject和IocMaking实例, 新建实际的bean对象&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;下一步,就是为刚刚生成的bean注入字段, 因为当前的bean对象,仅仅是new之后的全新状态&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;收尾的一步, 看看这个bean,是否为单例,是否需要保存到app作用域&amp;ndash;大部分的bean都是单例的&lt;/p&gt;&#xA;&#xA;&lt;p&gt;// 每一作用域(IocContext),都管理着符合其生命周期的bean &amp;ndash; 默认情况下,bean都是app作用域的,单例的&lt;/p&gt;&#xA;&#xA;&lt;p&gt;// 如果bean还定义了create/fetch等IocEvent的话,那么,这时候也会触发&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;将bean作为返回值,交给用户&lt;/p&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;p&gt;==补充一句,整个流程,等价于:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;Pet pet = new Pet();&#xA;pet.setName(&amp;quot;wendal&amp;quot;);&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;延伸一下:&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;1. 注解式Ioc&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;IocLoader loader = AnnotationIocLoader(&amp;quot;net.wendal.test&amp;quot;);&#xA;&#xA;//而bean需要定义为&#xA;@IocBean&#xA;public class Pet {&#xA;    @Inject(&amp;quot;wendal&amp;quot;) //这里只是演示,正常情况下,不可能这样写死&#xA;    private String name;&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;就是注解&amp;ndash;&amp;gt;IocObject这一步&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;2. MVC中的Ioc&lt;/strong&gt;&#xA;是通过IocProvider提供的. 不妨看看JsonIocProvider的代码:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;public class JsonIocProvider implements IocProvider {&#xA;&#xA;    public Ioc create(NutConfig config, String[] args) {&#xA;        //可以看到,就跟我们在main中写的差不多呢&#xA;        return new NutIoc(new JsonLoader(args), new ScopeContext(&amp;quot;app&amp;quot;), &amp;quot;app&amp;quot;);&#xA;    }&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;然后,是谁调用了ioc.get(XXX.class, &amp;ldquo;xxx&amp;rdquo;)呢? 是ModuleProcessor,摘取一部分源码看看:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;Object obj;&#xA;/*&#xA;* 如果 Ioc 容器实现了高级接口，那么会为当前请求设置上下文对象&#xA;*/&#xA;if (ioc instanceof Ioc2) {&#xA;    reqContext = new RequestIocContext(ac.getRequest());&#xA;    SessionIocContext sessionContext = new SessionIocContext(Mvcs.getHttpSession());&#xA;    IocContext myContext = new ComboContext(reqContext, sessionContext);&#xA;    Mvcs.setIocContext(myContext);&#xA;    //看上去比main方法里面写得复杂,事实上还是一个样!!多个上下文而已!&#xA;    obj = ((Ioc2) ioc).get(moduleType, injectName, myContext);&#xA;}&#xA;/*&#xA; * 否则，则仅仅简单的从容器获取&#xA; */&#xA;else&#xA;    obj = ioc.get(moduleType, injectName); &#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;延展阅读: &lt;a href=&#34;http://code.google.com/p/nutz/wiki/lang_mirror&#34;&gt;Mirror&lt;/a&gt;类,封装了Nutz中大部分的反射操作&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>北京之行,就上一张图吧</title>
      <link>http://wendal.net/429.html</link>
      <pubDate>2012-06-01 10:19:17 +0800</pubDate>
      <description>&lt;p&gt;&lt;img src=&#34;/assets/media/2012/06/6f91c323jw1dtdb6o9986j.jpg&#34;&gt;Nutz的代码就是这么来滴~~~~&lt;/img&gt;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>今天生日,上一张图!</title>
      <link>http://wendal.net/427.html</link>
      <pubDate>2012-05-24 09:58:24 +0800</pubDate>
      <description>&lt;p&gt;&lt;img src=&#34;/assets/media/2012/05/psb.jpg&#34;&gt;鸣鸣玩电脑&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;明天去帝都: 机票OK,酒店OK,保险OK&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>香港的婚礼,不一样的</title>
      <link>http://wendal.net/426.html</link>
      <pubDate>2012-05-21 10:32:38 +0800</pubDate>
      <description>&lt;p&gt;先上个google地图:&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&#34;http://ditu.google.com/maps?f=d&amp;amp;source=embed&amp;amp;saddr=%E5%B9%BF%E5%B7%9E%E5%B8%82%E8%8A%B1%E9%83%BD%E5%8C%BA%E6%96%B0%E5%8D%8E%E8%A1%97%E9%94%A6%E5%B0%9A%E5%90%8D%E8%8B%91&amp;amp;daddr=%E9%A6%99%E6%B8%AF%E6%9F%B4%E6%B9%BE%E9%81%93%E9%B2%A4%E9%B1%BC%E9%97%A8%E5%85%AC%E5%9B%AD%E5%8F%8A%E6%B8%A1%E5%81%87%E6%9D%91&amp;amp;hl=en&amp;amp;geocode=FQAZZQEdcti_BiHOsyv7oLhdCg%3BFfPtUwEdcxHPBiG9kDx6EHJRAynv0E63eAEENDHYfuKNakENzw&amp;amp;aq=2&amp;amp;oq=%E9%A6%99%E6%B8%AF+%E9%B2%A4%E9%B1%BC%E9%97%A8%E5%85%AC%E5%9B%AD+&amp;amp;sll=22.840186,113.734884&amp;amp;sspn=1.354174,2.705383&amp;amp;t=w&amp;amp;brcurrent=3,0x3402f895a35c2bc7:0xe59e075adeae415,0%3B5,0,0&amp;amp;dirflg=r&amp;amp;ttype=now&amp;amp;noexp=0&amp;amp;noal=0&amp;amp;sort=def&amp;amp;mra=ltm&amp;amp;ie=UTF8&amp;amp;ll=22.83893,113.733585&amp;amp;spn=1.12796,0.99499&amp;amp;start=0&#34;&gt;View Larger Map&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;整个婚礼的流程如下:&lt;/p&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&lt;p&gt;律师兼主持人,宣布仪式开始,全场肃静,婚礼进行曲响起&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;新郎站在前台(高台),等待新娘入场&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;大门打开,2个小女孩撒花开路,2个姐妹间隔2米左右,引领新娘缓缓走向新郎&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;新郎挽住新娘的手,走上前台&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;律师站2人正中,新郎新娘分站2边,对视&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;律师提示婚姻在法律上的约束力,并询问双方是否自愿成为夫妻&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;新郎宣读誓言&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;新娘宣读誓言&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;新郎为新娘佩戴戒指&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;新娘为新郎佩戴戒指&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;律师摆好结婚证,家长上台,见证双方签字确认&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;律师宣布2人成为合法夫妻&lt;/p&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;p&gt;得强调一下,我参加的是&amp;rdquo;婚礼&amp;rdquo;,而非喝喜酒&lt;/p&gt;&#xA;&#xA;&lt;p&gt;而且,跟我预先的不太一样,并非一个基督教/天主教婚礼, 虽然带一点基督教婚礼的形式,当然,地点是礼堂,而非教堂&lt;/p&gt;&#xA;&#xA;&lt;p&gt;在电视中,香港电影,美国电影,&amp;ldquo;看过&amp;rdquo;无数次婚礼,总以为婚礼就是怎样怎样的,呵呵&lt;/p&gt;&#xA;&#xA;&lt;p&gt;比较有意思的地方:&#xA;1. 誓言是律师亲自修改的 &amp;ndash; 原来并不需要官方版本!!&#xA;2. 嘿嘿,女方是讲普通话的哦,也就是我前同事, 宣读誓言都是用普通话的&#xA;3. 在一个有点点偏僻寂静的公园内,比较现代的礼堂,有空调的呢&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>在LuaJIT中通过FFI直接调用newlisp</title>
      <link>http://wendal.net/424.html</link>
      <pubDate>2012-05-17 10:02:59 +0800</pubDate>
      <description>&lt;ol&gt;&#xA;&lt;li&gt;首先,当然是编译newlisp,并拷贝到/usr/lib/libnewlisp.so&lt;/li&gt;&#xA;&lt;li&gt;编译luajit,启动之&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;p&gt;上代码&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;--载入ffi&#xA;ffi = require(&amp;quot;ffi&amp;quot;)&#xA;--载入newlisp&#xA;newlisp = ffi.load(&amp;quot;newlisp&amp;quot;)&#xA;--定义newlisp的公开API&#xA;ffi.cdef[[&#xA;char * newlispEvalStr(char * cmd);&#xA;]]&#xA;&#xA;--接下来,就是调用过程了&#xA;newlisp_str = &amp;quot;()&amp;quot;&#xA;tmp = ffi.new(&amp;quot;char[2]&amp;quot;) -- 因为newlispEvalStr的参数是char*,而newlisp_str是string,需要转一下&#xA;ffi.copy(tmp, newlisp_str)&#xA;&#xA;--执行&#xA;newlisp.newlispEvalStr(tmp)&#xA;&#xA;---------------------------------------------&#xA;--------------封装一下,做个库------------------&#xA;---------------------------------------------&#xA;&#xA;function newlisp(newlisp_str)&#xA;    local ffi = require(&amp;quot;ffi&amp;quot;)&#xA;    local newlisp = ffi.load(&amp;quot;newlisp&amp;quot;)&#xA;    ffi.cdef[[&#xA;       char * newlispEvalStr(char * cmd);&#xA;    ]]&#xA;    local tmp = ffi.new(&amp;quot;char[&amp;quot; .. #newlisp_str .. &amp;quot;]&amp;quot;)&#xA;    ffi.copy(tmp, newlisp_str)&#xA;    newlisp.newlispEvalStr(tmp)&#xA;end&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;TODO: 改为&lt;a href=&#34;https://github.com/wendal/lua-newlisp&#34;&gt;lua-newlisp&lt;/a&gt;形式的调用&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>将诺顿Ghost(诺顿克隆精灵)正版化了</title>
      <link>http://wendal.net/423.html</link>
      <pubDate>2012-05-12 09:17:33 +0800</pubDate>
      <description>&lt;p&gt;&lt;strong&gt;不打算说其他的,就贴一下邮件内容吧:&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;感谢您光临诺顿网络商店。&#xA;以下是您所购买产品的下载信息。&#xA;请务必妥善保管本邮件。&#xA;&#xA;[订单内容]&#xA;───────────────────────────────────&#xA;[订单号码]       NSCN0000017XXXX&#xA;[定购日期]       2012-05-12 22:09:28&#xA;───────────────────────────────────&#xA;[订购的商品1]      诺顿克隆精灵15.0 一用戶 下载版&#xA;[类别]             下载&#xA;[数量]             1 个&#xA;[产品密钥]   09-A052-0969-XXXXXX&#xA;───────────────────────────────────&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;</description>
    </item>
    <item>
      <title>增强型Proxy_Pass - 替换nginx内置的proxy_pass</title>
      <link>http://wendal.net/422.html</link>
      <pubDate>2012-05-09 10:33:34 +0800</pubDate>
      <description>&lt;p&gt;&lt;strong&gt;项目地址: &lt;a href=&#34;https://github.com/wendal/lua-resty-http&#34;&gt;https://github.com/wendal/lua-resty-http&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;这个项目是&lt;a href=&#34;https://github.com/liseen/lua-resty-http&#34;&gt;https://github.com/liseen/lua-resty-http&lt;/a&gt;的fork版本, 暂未被合并.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;nginx内置的proxy_pass有几个问题&lt;/strong&gt;:&#xA;1. 无法方便的调整后端host&#xA;2. 总是等待后端host把响应写完了,才开始向客户端写数据&#xA;3. proxy_next_upstream不灵活&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;演示,实时proxy_pass,每读取1k就往浏览器写1k数据:&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;local url = &#39;http://&#39;&#xA;if ngx.var.http_host then&#xA;   url = url .. ngx.var.http_host &#xA;end&#xA;url = url .. ngx.var.request_uri  -- 拼接完整的URL&#xA;if ngx.var.args then&#xA;   url = url .. &#39;?&#39; .. ngx.var.args&#xA;end&#xA;local ok, code, headers, status, body  = hc:proxy_pass {&#xA;    url = url,&#xA;    fetch_size = 1024, -- 分段大小&#xA;    max_body_size = 100*1024*1024 ,  --响应体的最大大小.&#xA;    headers = ngx.req.get_headers(), -- 传递客户端的参数,可以根据需要进行修改哦.&#xA;    method = ngx.var.request_method, -- 真实还原客户端的请求方法,当然,你可以改!!&#xA;}&#xA;if not ok and not ngx.headers_sent then&#xA;    ngx.exit(502) -- 出错了哦? 这里只是简单遵循了nginx在后端报错时的响应,你完全可以实现自己的逻辑,进行错误处理&#xA;else&#xA;    ngx.eof()&#xA;end&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;核心扩展点,这是http.lua中的代码,我在这里附上中文注释:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;-- proxy_pass方法支持3种回调哦&#xA;-- 提醒一句,回调里面,你可以调用任意ngx_lua的代码哦,就是说,你连ngx.exit(404)之类的中断请求的操作,也是完全可以的&#xA;function proxy_pass(self, reqt)&#xA;    local nreqt = {}&#xA;    for i,v in pairs(reqt) do nreqt[i] = v end&#xA;&#xA;    -- 响应回调,可以替代proxy_next_stream的功能哦,例如替换响应码,或者进行转向其他请求&#xA;    if not nreqt.code_callback then &#xA;        nreqt.code_callback = function(code, ...)&#xA;            ngx.status = code&#xA;        end&#xA;    end&#xA;&#xA;    -- header回调,可增减resp的header&#xA;    if not nreqt.header_callback then&#xA;        nreqt.header_callback = function (headers, ...)&#xA;            for i, v in pairs(headers) do&#xA;                ngx.header[i] = v&#xA;            end&#xA;        end&#xA;    end&#xA;&#xA;    -- body回调,注意chunked的情况哦&#xA;    if not nreqt.body_callback then&#xA;        nreqt.body_callback = function (data, chunked_header, ...)&#xA;            ngx.print(data)&#xA;            if chunked_header then&#xA;                ngx.print(&#39;\r\n&#39;)&#xA;            end&#xA;        end&#xA;    end&#xA;    return request(self, nreqt)&#xA;end&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;安装:&#xA;先编译&lt;a href=&#34;http://openresty.org/&#34;&gt;openresty&lt;/a&gt;&#xA;将lib/resty/url.lua和lib/resty/http.lua拷贝进openresty的lualib中&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;注意: 回调的API尚未锁定, 将来可能根据需要添加更多参数&lt;/strong&gt;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>bfr-非阻塞的管道缓存器,解决Linux管道缓冲区过小的问题!!</title>
      <link>http://wendal.net/421.html</link>
      <pubDate>2012-05-07 11:34:03 +0800</pubDate>
      <description>&lt;p&gt;官网地址: &lt;a href=&#34;http://glines.org/software/bfr&#34; target=&#34;_blank&#34;&gt;http://glines.org/software/bfr&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Google上,&amp;ldquo;Linux Pipe Buffer size&amp;rdquo;,&amp;ldquo;Linux管道缓冲区是否可调整&amp;rdquo;&amp;ldquo;增大pipe缓冲区大小&amp;rdquo;之类的查询,能出30万条记录&amp;hellip;&#xA;Linux上的管道, 要不就是4k,要不就是64k, 很多时候根本不够用 &amp;ndash; 我遇到需求的比较夸张,每秒传输200mb的数据通过一个管道,悲催&amp;hellip;, 问题如果从几秒钟的跨度看, 输入输出是均衡的,但细看一下, 一秒之内的输入输出非常不均衡, 导致输入输出都耗费大量时间在阻塞式读写中&lt;/p&gt;&#xA;&#xA;&lt;p&gt;前一段时间,已经打算自己写一个类似的缓冲器, 桥接管道两段,做个大缓存,可惜,由于C水平有限,且找到替代方案,就不了了之&lt;/p&gt;&#xA;&#xA;&lt;p&gt;终于,问题还是回来了, 而且,很巧的,我找到了bfr,一个古老的管道缓冲器(2004年之后就没有更新了&amp;hellip;),So, 为其建立一个github的库 &lt;a href=&#34;https://github.com/wendal/bfr&#34; target=&#34;_blank&#34;&gt;https://github.com/wendal/bfr&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;使用说明,简单翻译:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;bfr v1.6 (c) 1999-2003 Mark Glines &amp;lt;mark@glines.org&amp;gt;&#xA;Usage follows:&#xA;&#xA;bfr [-v|--verbose] [-t0|--threshold=0] [-T0|--timeout=0]&#xA;    [-b100|--bufsize=100] [-p&amp;lt;arg&amp;gt;|--progress=&amp;lt;arg&amp;gt;] [-m0|--minimum=0]&#xA;    [-T90|--throttle=90] [-C0|--speedcap=0] [&amp;lt;input file or -&amp;gt; ...]&#xA;&#xA;short --long       default desc&#xA;-h    --help       -       display this (hopefully) helpful message.(帮助信息)&#xA;-v    --verbose            enable verbosity (use twice for pedantic verbosity) (详尽信息,除非你遇到bug!!)&#xA;-p    --progress   k1k     Enables &amp;quot;progress mode&amp;quot; (see manpage) (进度显示, 强烈建议无视这个选项)&#xA;-m    --minimum    600k    set the amount of buffer to reach before output&#xA;                       begins (to ensure a full stream even at start).(低于多少缓冲,就先不输出)&#xA;-i    --initial    minimum Special case of --minimum to preload at the start&#xA;                       of operation.  If unset, --mimumum value is used.(真正输出前,先接收多少数据)&#xA;-t    --timeout    0       time, in seconds, to wait before aborting if both&#xA;                       input and output are locked.  0 = wait forever.(输入输出被阻塞的超时设置,基本上是用不上的)&#xA;-T    --throttle   90      after filling the buffer, the percentage to let the&#xA;                       amount of onhand data to go down to before accepting&#xA;                       more input. (缓冲区接近满的时候,停止接收数据,直至缓冲区的占有率下降)&#xA;-C    --speedcap   0       If set to a non-zero value, bfr will allow only&#xA;                       this many bytes to be output per second. (限制流出的速率,基本上没用)&#xA;&#xA;-b    --buffersize 1M      full size of memory buffer.(总的缓冲区大小,非常重要!!)&#xA;&#xA;-f    --fork               forks off the read half, to work around buggy&#xA;                       kernels which block even in nonblocking mode, such&#xA;                       as when reading from a cdrom or nfs volume hangs&#xA;&#xA;-o    --output     -       selects the output device(输出到哪里,默认是stdout)&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;关于编译,虽然它提供了configure等标准的构建脚本,但实际上,仅bfr.c和bfr.h是必须的, 简单修改bfr.h,定义VERSION,移除config.h,即可直接编译bfr!!&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>成功编译OpenJDK 7u2 ! 哦也！</title>
      <link>http://wendal.net/420.html</link>
      <pubDate>2012-05-06 11:12:24 +0800</pubDate>
      <description>&lt;p&gt;这个周末，连续编译了好几款开源程序：&#xA;ffmpeg+x264 很传统的编译,./configure和make&#xA;mongo+v8     使用scons进行编译，改为V8引擎的mongo，性能是否会大幅提速呢？ 打算出个报告哦！&#xA;mysql5.5       使用cmake&lt;/p&gt;&#xA;&#xA;&lt;p&gt;最后一个重头戏，本打算编译Chrome的，但发现其源码实在太大了，改为编译向往已久的OpenJDK 7u2&lt;/p&gt;&#xA;&#xA;&lt;p&gt;编译环境，Ubuntu 12.04 x64桌面版, root用户下操作&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;准备工作&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;apt-get build-dep openjdk-6&#xA;apt-get install openjdk-6-jdk&#xA;apt-get install libasound-dev build-essential&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;下载OpenJDK 7 update 2 的源码&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;cd /opt&#xA;wget http://www.java.net/download/openjdk/jdk7u2/promoted/b13/openjdk-7u2-fcs-src-b13-17_nov_2011.zip&#xA;unzip openjdk-7u2-fcs-src-b13-17_nov_2011.zip&#xA;cd /opt/openjdk&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;开始编译，会经历多个错误zzZZ&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;export ALT_BOOTDIR=/usr/lib/jvm/java-1.6.0-openjdk-amd64&#xA;export LANG=c&#xA;jdk/make/jdk_generic_profile.sh&#xA;make sanity&#xA;&#xA;#确认无错误后，执行&#xA;make ALLOW_DOWNLOADS=true&#xA;&#xA;#然后，就等吧，必然出错，需要编辑一个文件&#xA;vim hotspot/make/linux/makefiles/gcc.make&#xA;#将其中的 WARNINGS_ARE_ERRORS = -Werror 注释掉&#xA;&#xA;#OK，再启动make&#xA;make ALLOW_DOWNLOADS=true&#xA;&#xA;#然后，就到sound出错了&#xA;cd jdk/make/javax/sound/jsoundalsa&#xA;vim Makefile&#xA;#找到CPPFLAGS ，在其结尾，添加 -lasound&#xA;#如果再次make还是失败在这里，那么 ，先还原上一个修改， 并拷贝出错的最后一条gcc命令，添加-lasound后执行，应该无错误地pass&#xA;&#xA;#再次make&#xA;make ALLOW_DOWNLOADS=true&#xA;&#xA;#OK，你会遇到最后的错误， corba的什么什么类找不到？！&#xA;cp -r /opt/openjdk/build/linux-amd64/corba/classes/* /opt/openjdk/build/linux-amd64/classes/&#xA;&#xA;#好了，你最后一次跑make了，这次应该能够成功了！！&#xA;make ALLOW_DOWNLOADS=true&#xA;&#xA;#漫长编译后，你终于能看到编译成功的提示：&#xA;########################################################################&#xA;##### Leaving jdk for target(s) sanity all docs images             #####&#xA;########################################################################&#xA;##### Build time 00:04:19 jdk for target(s) sanity all docs images #####&#xA;########################################################################&#xA;&#xA;-- Build times ----------&#xA;Target all_product_build&#xA;Start 2012-05-06 23:07:41&#xA;End   2012-05-06 23:12:30&#xA;00:00:04 corba&#xA;00:00:14 hotspot&#xA;00:00:02 jaxp&#xA;00:00:06 jaxws&#xA;00:04:19 jdk&#xA;00:00:04 langtools&#xA;00:04:49 TOTAL&#xA;-------------------------&#xA;make[1]: Leaving directory `/opt/openjdk&#39;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;大功告成，来玩玩吧！&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;#现在，跑一下你的OpenJDK 7u2吧！！&#xA;/opt/openjdk/build/linux-amd64/bin/java -version&#xA;openjdk version &amp;quot;1.7.0-internal&amp;quot;&#xA;OpenJDK Runtime Environment (build 1.7.0-internal-root_2012_05_06_19_19-b00)&#xA;OpenJDK 64-Bit Server VM (build 22.0-b10, mixed mode)&#xA;&#xA;编译一个HelloWorld试试：&#xA;/opt/openjdk/build/linux-amd64/bin/javac /tmp/Hi.java&#xA;#################################&#xA;root@ubuntu:/opt/openjdk/build/linux-amd64# /opt/openjdk/build/linux-amd64/bin/java -cp /tmp Hi&#xA;Hi, this is my openJDK!&#xA;root@ubuntu:/opt/openjdk/build/linux-amd64# &#xA;#################################&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;</description>
    </item>
    <item>
      <title>深入一下Git的Hook(钩子)机制</title>
      <link>http://wendal.net/418.html</link>
      <pubDate>2012-05-06 01:35:16 +0800</pubDate>
      <description>&lt;p&gt;首先, 先来看看我刚刚翻译完成的&lt;a href=&#34;https://github.com/wendal/wendal/blob/master/githooks/githooks.txt&#34;&gt;GitHooks.txt(官方文档的翻译)&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;接着,当然是俺的总结发言了(已经附在翻译稿后面):&#xA;&lt;strong&gt;1. hook列表&lt;/strong&gt;:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;------------------------------------------------------&#xA;|钩子名字          |触发命令    |参数|非0导致取消|备注|&#xA;|applypatch-msg    |git am      |1   |Yes||&#xA;|pre-applypatch    |git am      |0   |Yes||&#xA;|post-applypatch   |git am      |0   |No ||&#xA;&#xA;|pre-commit        |git commit  |0   |Yes||&#xA;|prepare-commit-msg|git commit  |1~3 |Yes||&#xA;|commit-msg        |git commit  |1   |Yes||&#xA;|post-commit       |git commit  |0   |No ||&#xA;&#xA;|pre-rebase        |git rebase  |2   |Yes||&#xA;&#xA;|post-checkout     |git checkout|3   |No ||&#xA;&#xA;|post-merge        |git merge   |1   |No ||&#xA;&#xA;|pre-receive       |git-receive-pack |0   |Yes|通过标准输入获取信息|&#xA;|update            |git-receive-pack |3   |Yes||&#xA;|post-receive      |git-receive-pack |0   |No |通过标准输入获取信息|&#xA;|post-update       |git-receive-pack |可变|No ||&#xA;------------------------------------------------------&#xA;注: 最后4个才是远程资源库执行的hook,其他都是本地资源库的hook&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;2. hook的示例&lt;/strong&gt;&#xA;虽然示例中,hook都是perl脚本,但绝对不表示只能用perl.只要是可执行的东西,都可以作为钩子&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;3. 源码级别的hook信息&lt;/strong&gt;&#xA;我非常神奇地发现, hook的名字,并没有独立写在某个h文件中,而是分布于几个具体的c文件中&#xA;主执行入口: run_hook(const char *index_file, const char *name, &amp;hellip;) 定义于run-command.h,实现于run-command.c&#xA;官方说明:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;`run_hook`::&#xA;&#xA;    Run a hook.(执行一个hook)&#xA;    The first argument is a pathname to an index file, or NULL(第一个参数是index file,可能为NULL)&#xA;    if the hook uses the default index file or no index is needed.&#xA;    The second argument is the name of the hook.(第二个参数是hook的名字)&#xA;    The further arguments correspond to the hook arguments.(剩下的,就是hook自己需要的参数了)&#xA;    The last argument has to be NULL to terminate the arguments list.(最后一个参数必须是NULL,C的常识性用法)&#xA;    If the hook does not exist or is not executable, the return&#xA;    value will be zero.(当hook不存在或不可执行,则返回0 )&#xA;    If it is executable, the hook will be executed and the exit&#xA;    status of the hook is returned. (方法的返回值,就是hook的退出状态)&#xA;    On execution, .stdout_to_stderr and .no_stdin will be set.&#xA;    (See below.)&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;最后说一句&lt;/strong&gt;:&#xA;所谓远程,其实就是你push的目标, 也就是说,仅当push操作时,远程资源库才会有hook触发!!&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Nutz编年史--简单图表版</title>
      <link>http://wendal.net/417.html</link>
      <pubDate>2012-05-01 12:14:01 +0800</pubDate>
      <description>&lt;p&gt;&lt;strong&gt;先上干货,纯数据&lt;/strong&gt;:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;|版本   |构建日期|文件总数|文件大小|&#xA;|1.a.15|2009-09-20| 505| 524|&#xA;|1.a.16|2009-10-18| 524| 544|&#xA;|1.a.17|2009-11-03| 542| 559|&#xA;|1.a.18|2009-11-15| 534| 544|&#xA;|1.a.20|2009-11-19| 535| 544|&#xA;|1.a.21|2009-11-26| 550| 566|&#xA;|1.a.22|2009-11-29| 550| 568|&#xA;|1.a.23|2009-11-30| 550| 568|&#xA;|1.a.24|2009-12-20| 586| 636|&#xA;|1.a.25|2009-12-29| 587| 640|&#xA;|1.a.26|2010-03-01| 598| 638|&#xA;|1.a.27|2010-04-26| 631| 712|&#xA;|1.a.28|2010-05-30| 655| 737|&#xA;|1.a.29|2010-06-13| 665| 752|&#xA;|1.a.30|2010-07-13| 674| 759|&#xA;|1.a.31|2010-08-12| 689| 775|&#xA;|1.a.32|2010-10-13| 720| 816|&#xA;|1.a.33|2010-11-11| 729| 825|&#xA;|1.b.34|2010-12-24| 729| 828|&#xA;|1.b.35|2011-02-14| 829| 877|&#xA;|1.b.36|2011-03-25| 845| 933|&#xA;|1.b.37|2011-04-25| 858| 945|&#xA;|1.b.38|2011-07-15| 878| 994|&#xA;|1.b.39|2011-08-13| 880| 999|&#xA;|1.b.40|2011-10-21| 892|1019|&#xA;|1.b.41|2012-01-18| 896|1042|&#xA;|1.b.42|2012-02-14| 902|1053|&#xA;|1.b.43|2012-04-01| 918|1082|&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;Jar文件大小变化&lt;/strong&gt;:&#xA;&lt;img src=&#34;http://chart.apis.google.com/chart?chxl=0:|%E6%96%87%E4%BB%B6%E5%A4%A7%E5%B0%8F&amp;amp;chxr=0,0,1024&amp;amp;chxs=0,676767,10.5,0,l,676767&amp;amp;chxt=t&amp;amp;chs=300x225&amp;amp;cht=lc&amp;amp;chco=3D7930&amp;amp;chds=0,1082&amp;amp;chd=t:524,544,559,544,544,566,568,568,636,640,638,712,737,752,759,775,816,825,828,877,933,945,994,999,1019,1042,1053,1082&amp;amp;chg=9,-1,1,1&amp;amp;chls=2,4,0&amp;amp;chm=B,C5D4B5BB,0,0,0&amp;amp;chtt=Nutz&#34; alt=&#34;Nutz文件大小变化&#34; /&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;Class文件总数变化&lt;/strong&gt;:&#xA;&lt;img src=&#34;http://chart.apis.google.com/chart?chxl=0:|Class%E6%96%87%E4%BB%B6%E6%80%BB%E6%95%B0&amp;amp;chxr=0,0,1024&amp;amp;chxs=0,676767,10.5,0,l,676767&amp;amp;chxt=t&amp;amp;chs=300x225&amp;amp;cht=lc&amp;amp;chco=3D7930&amp;amp;chds=0,1082&amp;amp;chd=t:505,524,542,534,535,550,550,550,586,587,598,631,655,665,674,689,720,729,729,829,845,858,878,880,892,896,902,918&amp;amp;chg=9,-1,1,1&amp;amp;chls=1,4,0&amp;amp;chm=B,C5D4B5BB,0,0,0&amp;amp;chtt=Nutz&#34; alt=&#34;Nutz&#34; /&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;第一个公开版本,1.a.15发布于2009年9月20号,文件大小524kb,包含505个class文件&#xA;最新正式版本, 1.b.43发布于2012年4月1号,文件大小1082kb(增大了106%),包含了918个class文件&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;大事件&lt;/strong&gt;:&#xA;1.a.15 第一个公开版本&#xA;1.a.25 真正无依赖第三方jar&#xA;1.a.31 将Filter作为NutMvc的首选配置方式&#xA;1.a.33 提交到Maven中央库&#xA;1.b.34 第一个Beta版本&#xA;1.b.35 增加el引擎&#xA;1.b.36 重写Mvc&#xA;1.b.38 重写Dao,并迁移到Github&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;Nutz, 继续前行中!!&lt;/strong&gt;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>在Ant/Maven中使用ecj编译器(Eclipse内置的Java编译器)</title>
      <link>http://wendal.net/416.html</link>
      <pubDate>2012-04-30 04:10:55 +0800</pubDate>
      <description>&lt;p&gt;为什么要换ecj呢? JDK自带的java不够好吗? 是的, 尤其是debug信息. 那两种兼容吗? 完全兼容, ecj和javac一样是经过认证的哦, 事实上,如果你正在使用Eclipse,那么,你的java源码, 100%是ecj编译的呢(当然,是你自己写的那部分)&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Ant换用ecj&#xA;1. 在build.xml中加入:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;&amp;lt;property name=&amp;quot;build.compiler&amp;quot; value=&amp;quot;org.eclipse.jdt.core.JDTCompilerAdapter&amp;quot;&amp;gt;&amp;lt;/property&amp;gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&lt;p&gt;下载独立的ecj.jar&#xA;&lt;a href=&#34;http://mirrors.ustc.edu.cn/eclipse/eclipse/downloads/drops/R-3.7.2-201202080800/ecj-3.7.2.jar&#34;&gt;ECJ 3.7.2&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;将ecj-3.7.2.jar放入ant的lib文件夹中&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;如果是eclipse中跑ant,那么,需要设置一下,     Run As &amp;ndash; Ant Build &amp;hellip; &amp;ndash; ClassPath ,加入ecj.jar&lt;/p&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;p&gt;Maven换用ecj&#xA;1. 官网文档: &lt;a href=&#34;http://maven.apache.org/plugins/maven-compiler-plugin/non-javac-compilers.html&#34;&gt;http://maven.apache.org/plugins/maven-compiler-plugin/non-javac-compilers.html&lt;/a&gt;&#xA;2. 设置为plexus-compiler-eclipse即可&lt;/p&gt;&#xA;&#xA;&lt;p&gt;带来的好处: [](http://wendal.net/394.html)&#xA;事实证明, 只有ecj编译的class文件的debug信息会原样遵循方法参数的声明顺序, 悲催啊&amp;hellip;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Nutz资源扫描的重新实现</title>
      <link>http://wendal.net/414.html</link>
      <pubDate>2012-04-28 08:44:50 +0800</pubDate>
      <description>&lt;p&gt;&lt;strong&gt;Nutz.Resource包,是2010年4月创建的,至今2年了.当初的设计,就是为了 &amp;ldquo;资源扫描&amp;rdquo; 这个基础话题.&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Spring中也有类似的基础设施,但复杂很多,例如classpath与classpath*等定义.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;之前的实现,按以下思路完成:&lt;/strong&gt;&#xA;1. 传入一个路径,通过Files.findFile尝试寻找是否有这个文件&#xA; &amp;ndash;2. 路径是文件系统上的文件夹,将立马可以找到具体的File对象,可以直接扫描文件夹但&#xA; &amp;ndash;2. 文件存在于jar包,则需要解析出其jar文件的路径,读取jar文件进行扫描&#xA;3. 如果还没找到,搜索classpath和WEB-INF/lib,遍历里面的文件夹/jar文件&lt;/p&gt;&#xA;&#xA;&lt;p&gt;一个突出的问题是,Files.findFile的返回值是File对象,这意味着,如果该路径存在于多个不同的classpath路径或jar中,只有第一个路径会被返回.&#xA;而且,因为是File对象,对于Jar文件中的文件,读取比较麻烦(例如jarinjar打包的可执行jar文件).&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;解决复杂路径的jar文件读取问题&lt;/strong&gt;:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;    public static ZipInputStream makeZipInputStream(String jarPath)&#xA;            throws MalformedURLException, IOException {&#xA;        ZipInputStream zis = null;&#xA;        try {&#xA;            zis = new ZipInputStream(new FileInputStream(jarPath));&#xA;        } catch (IOException e) {&#xA;            zis = new ZipInputStream(new URL(jarPath).openStream());&#xA;        }&#xA;        return zis;&#xA;    }&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;之前的实现,使用JarFile jar = new JarFile(jarPath)形式,未能正确识别嵌套jar(jarinjar)的读取.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;解决Files.findFile导致的问题,则需要完全重写Scans.&lt;/strong&gt;&#xA;&amp;ndash; 以前的实现,是无状态的,每次扫描都尝试所有可能的方式&#xA;&amp;ndash; 新的实现,有状态,记录可以扫描的位置信息,直接查找&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;新版的实现思路:&lt;/strong&gt;&#xA;1. 初始化Scans类时,记录可以进行扫描的路径&#xA;&amp;ndash; 当前文件夹 new File(&amp;ldquo;.&amp;rdquo;)&#xA;&amp;ndash; 通过查找META-INF/MANIFEST.MF文件(这是每个标准jar文件必有的文件),得到classpath中所有的jar文件路径&#xA;&amp;ndash; 通过环境变量java.class.path遍历classpath中的路径&#xA;2. 当处于Web环境下,额外调用Scans.init(ServletContext)&#xA;&amp;ndash; 得到并遍历WEB-INF/lib文件夹中的jar文件&#xA;&amp;ndash; 得到WEB-INF/classes文件夹的路径&#xA;3. 以上得到的路径,都封装在ResourceLocation对象List中,分别处理具体路径与具体jar文件的扫描任务&#xA;4. 基于性能的考虑,会对jar文件进行预先索引&#xA;5. 查找将变得非常轻松,因为仅需要 将查询条件传递给各个ResourceLocation对象,并汇总他们的结果&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;可靠性,总体性能,内存占用:&lt;/strong&gt;&#xA;1. 由于预先探知所有可能的资源路径,所以找到资源的可靠性明显增加, 再加上Scans.registerLocation方法允许用户自行登记路径,使扫描结果更可靠.&#xA;2. Scans初始化的耗时增加,但scan操作性能明显提高&#xA;3. 内存占用稍微增加&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;功能改进:&lt;/strong&gt;&#xA;1. 支持按文件夹扫描,即使这个文件夹只存在于jar中,且jar文件并未加入目录实体&#xA;2. 用户可自行添加额外路径,在maven下的生存能力明显提高&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Nginx二级域名自动匹配到子文件夹(通过rewrite)</title>
      <link>http://wendal.net/413.html</link>
      <pubDate>2012-04-11 08:32:23 +0800</pubDate>
      <description>&lt;p&gt;网站目录结构&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;html --&#xA;       index.html&#xA;       xxx.html&#xA;       tuan --&#xA;              index.html&#xA;              tuan800.html&#xA;       blog --&#xA;              index.html&#xA;              1.html&#xA;              19.html&#xA;       news --&#xA;              index.html&#xA;              how_to_XX.html&#xA;              XX_XX_XX.html&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;分别对应主站(nutz.cn, www.nutz.cn), 团购子站(tuan.nutz.cn),博客子站(blog.nutz.cn),新闻子站(news.nutz.cn)&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&#34;https://gist.github.com/2359053&#34;&gt;nginx.conf示例&lt;/a&gt;:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;events {&#xA;    worker_connections  1024;&#xA;}&#xA;http {&#xA;    include       mime.types;&#xA;    default_type  application/octet-stream;&#xA;&#xA;    server {&#xA;        listen       80;&#xA;        server_name  nutz.cn *.nutz.cn;&#xA;&#xA;        set $sub_domain &amp;quot;&amp;quot;;&#xA;        if ($http_host ~ &amp;quot;(.+).nutz.cn$&amp;quot;) {&#xA;            set $sub_domain $1;&#xA;        }&#xA;        if ($http_host = &amp;quot;www.nutz.cn&amp;quot;) {&#xA;            set $sub_domain &amp;quot;&amp;quot;;&#xA;        }&#xA;        if ($sub_domain != &amp;quot;&amp;quot;) {&#xA;            rewrite /(.+) /$sub_domain/$1 break;&#xA;        }&#xA;&#xA;        location / {&#xA;            root   html;&#xA;            index  index.html index.htm;&#xA;        }&#xA;    }&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;善用if/rewrite哦, 更好的方式,是通过lua来做,呵呵&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>lua-newLISP 包装器</title>
      <link>http://wendal.net/412.html</link>
      <pubDate>2012-04-10 10:48:51 +0800</pubDate>
      <description>&lt;p&gt;&lt;strong&gt;更新: 新实现的eval只返回最后的表达式的值,并添加新的eval_file方法&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;今天第一次写lua模块,就做了一个lua-newLISP包装器,即在lua中执行newLISP脚本&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;首先遇到的是newLISP的编译:&lt;/strong&gt;&#xA;1. 官方提供的configure智能化程度极低,估计是手写的&#xA;2. 生成的Makefile,是Ubuntu下的配置, 在centos下编译无法通过&#xA;虽然修改一下,还是顺利能pass,但还是觉得不爽&#xA;故, 动手做了一个&lt;a href=&#34;https://gist.github.com/2351735&#34;&gt;cmake for newLISP&lt;/a&gt;的脚本.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;生成so文件后,默认是newlisp.so,改名为libnewlisp.so,并放入/usr/lib中&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;由于newLISP的对外API仅2个(其中一个还不能用&amp;hellip;),且自带的h文件比较混乱,&lt;strong&gt;干脆自己写了一个h文件&lt;/strong&gt;&lt;a href=&#34;https://github.com/wendal/lua-newlisp/blob/master/newLISP.h&#34;&gt;newlisp.h&lt;/a&gt;,就一行:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;char * newlispEvalStr(char * cmd); //把传入的cmd当成newlisp脚本执行,并返回char*&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;然后,当然是主体c文件&lt;a href=&#34;https://github.com/wendal/lua-newlisp/blob/master/newLISP.c&#34;&gt;newLISP.c&lt;/a&gt;啦&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;//载入lua的头文件&#xA;#include &amp;quot;lua.h&amp;quot;&#xA;#include &amp;quot;lualib.h&amp;quot;&#xA;#include &amp;quot;lauxlib.h&amp;quot;&#xA;&#xA;//载入我自己写的newlisp头文件&#xA;#include &amp;quot;newLISP.h&amp;quot;&#xA;&#xA;//lua中require语法将调用这个方法  lisp = require &amp;quot;newLISP&amp;quot;&#xA;//最终生成的名字,必须全部一致,库的名字叫newLISP,文件叫newLISP.so,luaopen方法也得叫luaopen_newLISP&#xA;int luaopen_newLISP(lua_State *L);&#xA;&#xA;static int newLISP_eval(lua_State *L) {&#xA;   char * str = lua_tostring(L, 1);     //获取第一个方法参数, lua中数组下标以1开始&#xA;   char * result = newlispEvalStr(str); //调用newLISP库执行脚本&#xA;   lua_pushstring(L, result); //将返回值压入堆栈&#xA;   return 1; //返回值的数量; 因为lua支持同时返回多个值&#xA;}&#xA;&#xA;//定义lua中方法与方法名的映射表&#xA;static const luaL_reg newLISP_lib[] = {&#xA;   {&amp;quot;eval&amp;quot;, newLISP_eval},&#xA;   {0,0}&#xA;};&#xA;&#xA;//模块注册入口方法&#xA;int luaopen_newLISP(lua_State *L) {&#xA;   luaL_register(L, &amp;quot;newLISP&amp;quot;, newLISP_lib);&#xA;   return 1;&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;编译:&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;gcc -O3 -Wall -shared -o newLISP.so -lnewlisp -llua newLISP.c&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;测试:&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;$&amp;gt; lua&#xA;Lua 5.1.5  Copyright (C) 1994-2012 Lua.org, PUC-Rio&#xA;&amp;gt; lisp = require &amp;quot;newLISP&amp;quot;&#xA;&amp;gt; print(lisp.eval(&amp;quot;(* 1 100)&amp;quot;))&#xA;100&#xA;&#xA;&amp;gt; print(lisp.eval(&amp;quot;(setq lst &#39;(1 2 3))&amp;quot;))&#xA;(1 2 3)&#xA;&#xA;&amp;gt; print(lisp.eval(&amp;quot;(define (abc x y) (+ (* x x) (* y y)) )  (abc 3 4)&amp;quot;))&#xA;(lambda (x y) (+ (* x x) (* y y)))&#xA;25&#xA;&#xA;&amp;gt; &#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;&lt;del&gt;&lt;strong&gt;可以看到, 这个方法有2个很明显的问题:&lt;/strong&gt;&#xA;1. 总是多一个换行&#xA;2. 会把执行过程中的所有output都作为返回值 .. 汗&amp;hellip;&lt;/del&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;恩, 起码能用上了&lt;/p&gt;&#xA;&#xA;&lt;p&gt;代码所在项目 &lt;a href=&#34;https://github.com/wendal/lua-newlisp&#34;&gt;lua-newLISP&lt;/a&gt;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Nutz是一个轮子吗?</title>
      <link>http://wendal.net/411.html</link>
      <pubDate>2012-04-06 10:59:30 +0800</pubDate>
      <description>&lt;p&gt;不要重复发明轮子(Don&amp;rsquo;t Reinvent the Wheel.) &amp;ndash; 在开源社区经常都能看到的论调.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;问: Nutz是SSH的轮子吗?&#xA;答: 飞机轮子与单车轮子,是同一种轮子吗?&#xA;问: Nutz的Ioc,Aop,Dao,MVC,在SSH都有,这难道不是重复发明轮子吗?&#xA;答: 你确定这是发明轮子吗? Nutz发明了Ioc?Nutz发明了Aop?&#xA;&amp;hellip; &amp;hellip;&#xA;&amp;hellip; &amp;hellip;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&amp;ldquo;不要重复发明轮子&amp;rdquo;,其实是有后半句的,&amp;ldquo;学会制造轮子,改进轮子&amp;rdquo;.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;你可以批评他人的轮子做得不好,做得有多烂,但不可否定制造轮子的权利及付出的努力.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;如果中国的JavaWeb工程师,都能做一个Spring轮子,或者Hibernate轮子,或者Struts轮子,那么,Java也能强国了.&#xA;可惜, 由于SSH/SSH2已经成为国内的JavaWeb的事实标准,以至于很大一部分人只会使用SSH, 而Ioc容器这种基本的概念都弄不清楚. 有多少号称&amp;rdquo;精通SSH&amp;rdquo;的工程师研读过其源码呢?&lt;/p&gt;&#xA;&#xA;&lt;p&gt;的确,国内的程序员太忙了,天天加班,以至于&amp;rdquo;怎么可能有空参与开源项目?!&amp;ldquo;.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>用简单的方式,实现NutDao的懒加载(延迟加载, Lazy Load)</title>
      <link>http://wendal.net/409.html</link>
      <pubDate>2012-04-05 10:45:56 +0800</pubDate>
      <description>&lt;p&gt;一直以来, NutDao的懒加载问题,都无数次被提起,我也曾经在另外一篇博客中提及其可行性: &lt;a href=&#34;http://wendal.net/317.html&#34;&gt;NutDao实现Lazy加载的可行性&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;为了回应广大Nutzer的呼声,我花了点时间完成了一个&lt;a href=&#34;https://github.com/nutzam/nutz/commit/a6e1d49f6e883aa75edc2938f36a475ab314d3ac&#34;&gt;LazyNutDao&lt;/a&gt;,如果你需要这个功能,那么只需要把NutDao简单换成LazyNutDao&lt;/p&gt;&#xA;&#xA;&lt;p&gt;整个实现,算上空行及注释,大概200行,并修改了另外3个类(就是把部分属性改成protected)&lt;/p&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&lt;p&gt;POJO的属性,必须带setter/getter,否则无法进行懒加载注入&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;setter/getter应当是无逻辑的,不应加入业务逻辑.&lt;/p&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;p&gt;需要注意的问题:&lt;/p&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&lt;p&gt;无Session控制,自行处理事务问题 &amp;ndash; 对象在事务模板包裹下取出,但在事务模板外调用getter以获取属性值,那么,这部分的调用是在事务之外的&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;多线程问题,LazyMethodInterceptor并非线程安全的,因为其中的代码并未锁定当前对象&lt;/p&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;实现思路:&lt;/strong&gt;&#xA;1. POJO的实例化,是由NutEntity完成的,由于懒加载是通过AOP实现的,所以需要接管其实例化过程&#xA;2. NutEntity是由AnnotationEntityMaker创建,有NutDao持有,所以,通过覆写setDataSource方法,接管EntityHolder实例&#xA;3. LazyNutEntity继承于NutEntity,通过生成Aop拦截链,生成Aoped类,以便拦截@One/@Many字段的setter/getter&#xA;4. 懒加载状态管理: 当setter被调用,那么懒加载机制结束使命,回退为普通机制.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;整个实现,最难抉择的是&amp;rdquo;&lt;strong&gt;懒加载状态管理&lt;/strong&gt;&amp;rdquo;,如果引入Hibernate形式的Session机制,必然导致大幅膨胀.而且,Session机制也是Hibernate中非常容易导致错误的机制之一. 最后简化为简单的2步式控制:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;public void filter(InterceptorChain chain) throws Throwable {&#xA;  if (status == LazyStatus.CAN_FETCH) {&#xA;    if (chain.getCallingMethod() != setter) {&#xA;      dao.fetchLinks(chain.getCallingObj(), fieldName);// 这里会触发setter被调用&#xA;      status = LazyStatus.FETCHED;&#xA;    } else&#xA;      status = LazyStatus.NO_NEED; // 如果setter被调用,那么也就不再需要懒加载了&#xA;  }&#xA;  chain.doChain();&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;200行的代价,实现NutDao的懒加载,应该算不上膨胀吧? 呵呵&lt;/strong&gt;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Nutz 1.b.43 发行后记</title>
      <link>http://wendal.net/408.html</link>
      <pubDate>2012-04-01 10:43:22 +0800</pubDate>
      <description>&lt;p&gt;折腾了半天,终于把1.b.43发布出去了.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;简单介绍修正的Bug及新功能,毕竟&amp;rdquo;发行注记&amp;rdquo;比较少涉及这些.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Bug修正:&#xA;1. #177 NutFilter关闭时,报NPE,原因是销毁NutFilter时,没有设置ThreadLocal的属性,导致获取IOC容器失败&#xA;2. #177 PropertiesProxy只认最后一个配置文件,原因是加载新配置文件时,把旧数据clear了&#xA;3. #170 高并发的情况下,当数据库连接池的连接耗尽,NutDao抛出NPE, 原因是处理连接池异常的代码,没有考虑到获取连接也会失败&#xA;4. #155 入口方法如果包含Date参数,当页面不传值,会抛出NPE,原因是String2Datetime类没有把&amp;rdquo;&amp;ldquo;当初null来处理&#xA;5. #172 nutz + Oracle JDBC 10.1.0.2.0 分页会出错,原因是这驱动有BUG!!&#xA;6. #75  NutDao动态实体解析报错,原因是默认会以为动态实体也有主键,但实际上用户执行的是update,并不包含主键.&#xA;7. Json.fromJson(Set.class, &amp;ldquo;[1,2,3]&amp;ldquo;)会报错,原因是没对Set进行特别处理,直接当成List返回了&lt;/p&gt;&#xA;&#xA;&lt;p&gt;需求:&#xA;1. #187 支持JarInJar,即eclipse打包输出Runnable Jar的第二项.&#xA;2. #130 自定义SQL也支持Pager分页&#xA;3. #158 Dao支持Set存入数据库,字段类型为varchar&#xA;4. #120 JSON循环引用的序列化与反序列化, 以及EL支持Json需求&#xA;5. MVC中,如果入口方法的参数没有@Param注解,且不被适配器所识别,那么,按@Param(&amp;ldquo;参数名&amp;rdquo;)进行处理&#xA;6. 添加内置的fetchBoolean回调函数&#xA;7. 新增@SessionBy注解,允许自定义Session的获取方式&#xA;8. 新增SimpleDataSource,内置的DataSource实现&lt;/p&gt;&#xA;&#xA;&lt;p&gt;注意,我这里描述的是BUG导致的问题及原因,而非BUG的标题&lt;/p&gt;&#xA;&#xA;&lt;p&gt;值得注意的是,由于对resource包的修改,扫描资源及Class的速度有所下降,但更准确更可靠,特别是对Class的扫描,对扫描到的文件,不再通过文件名等方式推断类名,而是改为直接读取类文件,从中解析出其真实类名.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>newLISP的ShellGame配套lsp源文件</title>
      <link>http://wendal.net/406.html</link>
      <pubDate>2012-03-27 10:08:44 +0800</pubDate>
      <description>&lt;p&gt;&lt;a href=&#34;http://www.newlisp.org/&#34;&gt;newLISP&lt;/a&gt;官方提供的&lt;a href=&#34;http://www.neglook.com/?Shell_Games&#34;&gt;ShellGame&lt;/a&gt;系列视频,并未提供lsp源文件,我看完了整个系列,顺便把源文件补了一部分,地址:&#xA;&lt;a href=&#34;https://github.com/wendal/learn-newLISP/tree/master/ShellGame&#34;&gt;https://github.com/wendal/learn-newLISP/tree/master/ShellGame&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;总共有23个视频,当前我完成了17个配套的lsp文件,剩下6个视频,没看懂,所以lsp文件还没写出来 &amp;ndash; 难道是比较高阶的?&lt;/p&gt;&#xA;&#xA;&lt;p&gt;附上第一个视频的lsp文件&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;;;视频原地址: http://www.neglook.com/&#xA;;;lsp文件由wendal创建 http://wendal.net&#xA;&#xA;;; 用默认的context方法,创建数值生成器 -- 类似于自增&#xA;&#xA;(setq generator:acc 0)  ; 创建一个名叫generator的上下文,并添加一个符号acc&#xA;&#xA;(define (generator:generator) (inc generator:acc)) ;缺省的context方法(即与context同名的方法),其中的inc是方法,等同于++&#xA;&#xA;(generator)   ;;分号是单行注释的开始,而非语句的结束符&#xA;&#xA;(generator) &#xA;(generator)&#xA;(generator)   ;;连续调用几次后,现在的值应该是acc应当等于4&#xA;&#xA;;;费波那西数列（Fibonacci Sequence）&#xA;&#xA;(define (fibo:fibo) &#xA;    (if (not fibo:mem) &#xA;        (setq fibo:mem &#39;(0 1))) &#xA;    (last (push (+ (fibo:mem -2) (fibo:mem -1)) fibo:mem -1)))&#xA;&#xA;(fibo)&#xA;(fibo)&#xA;(fibo)&#xA;(fibo)&#xA;(fibo)&#xA;&#xA;(println fibo:mem) ;;打印fibo上下文(context)中mem变量的值&#xA;&#xA;(exit) ;; 执行完毕,环境关闭&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;同时,我也发现一个bug,就是中文注释后的一行代码,会被无视&amp;hellip;汗 &amp;mdash;&amp;mdash;- 已经提交bug report&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Python的while 1跟while True到底有什么区别?</title>
      <link>http://wendal.net/405.html</link>
      <pubDate>2012-03-26 02:41:59 +0800</pubDate>
      <description>&lt;p&gt;定义两个方法,分别使用while循环&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;def w() :&#xA;  while 1 :&#xA;    pass&#xA;&#xA;def w2() :&#xA;  while True:&#xA;    pass&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;单从功能上说,两种无任何区别,那么,来看看字节码上的区别:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;import dis  #载入反编译模块,Python内置的&#xA;&#xA;dis.dis(w) #对应的是while 1,下面是输出&#xA;  2           0 SETUP_LOOP               3 (to 6)&#xA;&#xA;  3     &amp;gt;&amp;gt;    3 JUMP_ABSOLUTE            3&#xA;        &amp;gt;&amp;gt;    6 LOAD_CONST               0 (None)&#xA;              9 RETURN_VALUE&#xA;&#xA;dis.dis(w2) #对应的是while True,下面是输出&#xA;  2           0 SETUP_LOOP              10 (to 13)&#xA;        &amp;gt;&amp;gt;    3 LOAD_GLOBAL              0 (True)&#xA;              6 POP_JUMP_IF_FALSE       12&#xA;&#xA;  3           9 JUMP_ABSOLUTE            3&#xA;        &amp;gt;&amp;gt;   12 POP_BLOCK&#xA;        &amp;gt;&amp;gt;   13 LOAD_CONST               0 (None)&#xA;             16 RETURN_VALUE&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;很明显, while 1的字节码只有while True的一半.&#xA;为什么呢? 因为Python2.x中True不是关键字,只是一个全局变量而已&lt;/p&gt;&#xA;&#xA;&lt;p&gt;更详细,更专业的分析,请看&#xA;&lt;a href=&#34;http://stackoverflow.com/questions/3815359/while-1-vs-for-whiletrue-why-is-there-a-difference&#34;&gt;http://stackoverflow.com/questions/3815359/while-1-vs-for-whiletrue-why-is-there-a-difference&lt;/a&gt;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Java匿名内部类的传值</title>
      <link>http://wendal.net/404.html</link>
      <pubDate>2012-03-24 09:37:42 +0800</pubDate>
      <description>&lt;p&gt;在Nutz中,存在大量需要使用匿名内部类的情况,很多童鞋都对传值很困惑,所以我这里说明一下&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;传入:&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;//匿名内部类,只能访问final的本地变量及方法参数&#xA;public void addUser(final String name, String passwd, final String userType) {&#xA;    User user = null;&#xA;    if (&amp;quot;admin&amp;quot;.equal(userType))&#xA;        user = new AdminUser(name, passwd); //仅作演示.&#xA;    else&#xA;        user = new User(name, passwd);&#xA;    final User _user = user; //因为user变量不能设置为final,所以需要新加一个变量来中转&#xA;    Trans.run(new Atom(){&#xA;        public void run() {&#xA;            dao.insert(_user);&#xA;            if (log.isDebugEnable())&#xA;                log.debugf(&amp;quot;Add user id=%d, name=%s , type=%s&amp;quot;, _user.getId(), name, userType);&#xA;        }&#xA;    });&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;传出(获取方法返回值等等):&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;方法1 &amp;ndash; 对象数组法&lt;/strong&gt;&#xA;通过一个final的Object对象数组,存放需要的值&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;public long countUser(final String userType) {&#xA;    final Object[] objs = new Object[1];&#xA;    Trans.run(new Atom(){&#xA;        public void run() {&#xA;            objs[0] = dao.count(User.class, Cnd.where(&#39;userType&#39;, &#39;=&#39;, userType));&#xA;        }&#xA;    });&#xA;    return ((Number)objs[0]).longValue();&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;方法2 &amp;ndash; ThreadLocal法&lt;/strong&gt;&#xA;通过一个ThreadLocal来存放结果,这个ThreadLocal可以是静态的,供全app使用的&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;private static final ThreadLocal re = new ThreadLocal(); //自行补上泛型Object&#xA;public long countUser(final String userType) {&#xA;    Trans.run(new Atom(){&#xA;        public void run() {&#xA;            re.set(dao.count(User.class, Cnd.where(&#39;userType&#39;, &#39;=&#39;, userType)));&#xA;        }&#xA;    });&#xA;    return ((Number)re.get()).longValue(); //严谨一点的话,应该将ThreadLocal置空&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;方法3 &amp;ndash; Molecule法&lt;/strong&gt;&#xA;Molecule类是Nutz内置的抽象类类,实现Runnable和Atom接口,添加了两个获取/设置值的方法.&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;public long countUser(final String userType) {&#xA;    Molecule mole = new Molecule() { //需要自行补齐泛型&#xA;        public void run() {&#xA;            setObj(dao.count(User.class, Cnd.where(&#39;userType&#39;, &#39;=&#39;, userType)));&#xA;        }&#xA;    };&#xA;    Trans.run(mole);&#xA;    return ((Number)mole.getObj()).longValue(); &#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;</description>
    </item>
    <item>
      <title>学习Java字节码的一些提示</title>
      <link>http://wendal.net/403.html</link>
      <pubDate>2012-03-23 08:49:14 +0800</pubDate>
      <description>&lt;p&gt;Java Class Format : &lt;a href=&#34;http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html&#34;&gt;http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html&lt;/a&gt;&#xA;Class文件格式定义,永远是最权威的&lt;/p&gt;&#xA;&#xA;&lt;p&gt;jclasslib : &lt;a href=&#34;http://www.ej-technologies.com/products/jclasslib/overview.html&#34;&gt;http://www.ej-technologies.com/products/jclasslib/overview.html&lt;/a&gt;&#xA;可视化查看/修改Class文件的工具,以树形结构显示Class文件,并列出具体方法的字节码数据&lt;/p&gt;&#xA;&#xA;&lt;p&gt;asm : &lt;a href=&#34;http://asm.ow2.org/&#34;&gt;http://asm.ow2.org/&lt;/a&gt;&#xA;性能最强悍的读写class格式的类库,因为大部分写法都接近于直接写字节码&#xA;其中的ASMifierClassVisitor类,能打印出构造一个完整class文件所需要的全部Java代码,非常方便&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Java字节码,跟汇编差不多,喜欢深入Java语法的童鞋不妨学学. 看清实际生成的字节码,你能更清晰的知道,哪些语法仅仅是编译器语法糖果.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>实用主义的Lisp方言 -- newLisp</title>
      <link>http://wendal.net/402.html</link>
      <pubDate>2012-03-21 08:32:20 +0800</pubDate>
      <description>&lt;p&gt;先引用newLisp的官方定义:&#xA;&lt;a href=&#34;http://www.newlisp.org/index.cgi?FAQ&#34;&gt;newLISP is a LISP-like scripting language for doing things you typically do with scripting languages: programming for the internet, system administration, text processing, gluing other programs together, etc. newLISP is a scripting LISP for people who are fascinated by LISP&amp;rsquo;s beauty and power of expression, but who need it stripped down to easy-to-learn essentials.&lt;/a&gt;&#xA;&lt;strong&gt;newLISP is LISP reborn as a scripting language&lt;/strong&gt;: pragmatic and casual, simple to learn without requiring you to know advanced computer science concepts.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;自称是Lisp的重生,对自己的期望非常高.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;我是在&lt;a href=&#34;http://my.opera.com/freewinger/blog/&#34;&gt;天国之翼&lt;/a&gt;的解释下接触newLisp,这人高人独自翻译了&lt;a href=&#34;http://www.newlisp.org/CodePatterns-cn.html&#34;&gt;newLisp的代码模式&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;之前看了实用Lisp编程,对Lisp了解了不少,但发现Lisp世界的很大特点就是一上来就吹嘘括号和宏,在无尽的不理解,不明白,我的热情很快退去&amp;hellip;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;而newLisp,起码,我跑通了一个http服务器!! 我跑通了mysql的demo!!&lt;/strong&gt;&#xA;安装文件非常小巧,安装过程只需几秒,启动极快 &amp;ndash; 主程序仅280kb!!&#xA;没有一味推荐Emacs(事实上我很讨厌这玩意),所以我用notepad++进行编辑,感觉也不错嘛&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;现在,我把两个小demo列一下&lt;/strong&gt;:&#xA;&lt;strong&gt;1. 小小的静态文件http服务器,无需写代码,一条命令就能启动,最起码做个能用的http服务&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;newlisp -L log.txt -http -w E:/htmls&#xA;#-L 日志,可省略&#xA;#-w 工作目录,可省略&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;2. 访问mysql 能访问数据库,不激动吗?!&lt;/strong&gt;&#xA;首先,你需要下载libmysql(&lt;a href=&#34;http://mysql.oss.eznetsols.org/Downloads/Connector-C/mysql-connector-c-noinstall-6.0.2-win32.zip&#34;&gt;windows&lt;/a&gt;),或者安装mysql客户端(一般都包含libmysql)&#xA;然后,到newLisp的安装文件夹里面的modules文件夹,找到mysql.lsp,打开编辑:&#xA;找以下语句(跳过开头的注释,就看到了),对应你所在的操作系统,确定libmysql已经放好&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;(set &#39;files &#39;(&#xA;    &amp;quot;/usr/local/lib/libmysqlclient.so.20.0&amp;quot; ; OpenBSD 4.9&#xA;    &amp;quot;/usr/lib/libmysqlclient.so&amp;quot; ; Linux, UNIX&#xA;    &amp;quot;/usr/lib/mysql/libmysqlclient.so&amp;quot; ; Linux Fedora&#xA;    &amp;quot;/usr/local/mysql/lib/libmysqlclient.so&amp;quot; ; Linux, UNIX&#xA;    &amp;quot;/usr/local/mysql/lib/libmysqlclient.dylib&amp;quot; ; MacOS X&#xA;    &amp;quot;/usr/lib/libmysqlclient.dylib&amp;quot; ; MacOS X&#xA;    &amp;quot;E:\\newlisp\\modules\\libmysql.dll&amp;quot; ; 这是我自己加的,windows用户需要到mysql网站下载32位的libmysql,并填上绝对路径&#xA;))&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;在结尾往前找,第一个方法, (define (test-mysql) , 设置mysql用户名密码&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;(define (test-mysql)&#xA;  (MySQL:init)&#xA;  (unless (MySQL:connect 0 &amp;quot;root&amp;quot; &amp;quot;root&amp;quot; &amp;quot;test&amp;quot;) ;第一个参数是host,如果为0,则代表localhost,第二三个分别是用户名和密码,第四个的测试数据库名&#xA;    (println &amp;quot;Could not connect to MySQL&amp;quot;)&#xA;    (exit))&#xA;))&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;好了,可以执行了&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;#首先,进入命令行,敲入newlisp,进入newLisp的交换模式&#xA;newLISP v.10.4.0 on Win32 IPv4/6 UTF-8, execute &#39;newlisp -h&#39; for more info.&#xA;&#xA;&amp;gt;&#xA;&amp;gt;   (module &amp;quot;mysql.lsp&amp;quot;)                 ; 载入mysql模块,如果一切顺利,会把test-mysql方法打印了一通,原因是test-mysql为最后一个方法,默认会将最后一个表达式的值做法返回值&#xA;&amp;gt;   (test-mysql)                         ; 执行test-mysql,如果之前的步骤都正确,那么,就开始打印创建表,查询,删除等操作&#xA;&amp;gt;   (exit)                               ; (exit)的含义是退出newlisp,另外说一句,&amp;quot;;&amp;quot;是注释的开始&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;如果上述2个demo都顺利pass,那么,你以后可以大胆地说: lisp很简单嘛,我都跑通2个demo了!!&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>如何阅读Nutz的源码</title>
      <link>http://wendal.net/400.html</link>
      <pubDate>2012-03-19 10:50:37 +0800</pubDate>
      <description>&lt;p&gt;一直以来都有很多人问,我一直以来就有一个简单直接的回答:&#xA;&amp;ldquo;看你喜欢看的模块&amp;rdquo;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;今天,我决定用长一点的篇幅及内容来解释一下&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;Nutz的基础设施 &amp;ndash; Lang/Castor/Json/Log/Plugin&lt;/strong&gt;&#xA;所有模块都是无约束地使用这个几个package所提供的方法&#xA;&amp;ndash;Lang,提供的是帮助方法,各种各样的,其名字来源于对java.lang包的补充. 注意,其中的Mirror类封装了大量的反射,但请不要再以JDK1.2的思维去想象反射的性能!!&#xA;&amp;ndash;Castor,负责类型转换, 例如String&amp;ndash;&amp;gt;List&#xA;&amp;ndash;Json,一个基本完整(不解析科学计数),Json字符串与Java对象的互转实现&#xA;&amp;ndash;Log,日志接口,Nutz的代码,在运行时并不强制依赖具体的日志实现,这个package就是做了封装&#xA;&amp;ndash;Plugin,插件模块,最初的设计是为了一套简单的插件机制,现在仅Log模块在使用,意义已经不大&#xA;建议重点关注的类/接口:&#xA;Mirror Castors Json Lang Files Streams Log Log4jLogAdapter SimplePluginManager MultiLineProperties&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;反向注入/依赖注入 &amp;ndash; Ioc&lt;/strong&gt;&#xA;由于Spring的横行,许多童鞋连Ioc的基本原理都已经忘掉了&#xA;IocLoader负责加载配置信息(如js,注解)&#xA;Ioc(NutIoc)按配置信息生成具体对象(bean)&#xA;IocContext按配置信息管理bean的生命周期(create/fetch/depose)&lt;/p&gt;&#xA;&#xA;&lt;p&gt;建议重点关注的类/接口:&#xA;Ioc Ioc2 NutIoc IocLoader AnnotationIocLoader JsonLoader MapLoader&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;Nutz的ORM &amp;ndash; Dao&lt;/strong&gt;&#xA;ORM的基本概念,就是POJO持久化. 请留意,这个package与Ioc无任何直接联系.NutIoc并不会特殊照顾NutDao,两者可以说是互不相识的.&#xA;EntityMaker(AnnotationEntityMaker)将Pojo所对应的类转换为Entity(配置信息)&#xA;Dao(NutDao)按Entity所提供的信息,将操作(insert/update/fetch等),转换为DaoStatement(抽象的Dao语句)&#xA;DaoExecutor(NutDaoExecutor)将DaoStatement转换为JDBC语句&#xA;DaoRunner(NutDaoRunner)负责执行具体的JDBC语句,并管理连接获取/释放/事务控制&#xA;建议重点关注的类/接口:&#xA;上面提到了各个类,并加上Sqls类&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;Http服务 &amp;ndash; MVC&lt;/strong&gt;&#xA;主线: Loading(NutLoading)加载配置信息,UrlMapping(UrlMappingImpl)保存路径映射信息,ActionChain(NutActionChain)按链式处理具体请求&#xA;建议重点关注的类/接口:&#xA;NutFilter ActionHandler ActionContext DefaultViewMaker Mvcs ComboIocProvider&#xA;org.nutz.mvc.impl.processor下的处理器实现类&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;切面编程 &amp;ndash; Aop&lt;/strong&gt;&#xA;这部分的代码,除具体的asm代码外,还是比较好懂的. org.nutz.aop.asm包里面的代码,由于操作的是Java字节码,必须苦涩难懂.&#xA;Aop的具体模型,请参阅手册.&#xA;建议重点关注的类/接口:&#xA;AbstractClassAgent InterceptorChain LoggingMethodInterceptor&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;表达式 &amp;ndash; EL&lt;/strong&gt;&#xA;这玩意我自己也没仔细看完,主要是jukai和zozoh实现的,我就不多嘴了.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;资源扫描 &amp;ndash; resource&lt;/strong&gt;&#xA;找jar里面的文件,通过package获取里面的全部类,都靠这个package的实现&#xA;建议重点关注的类/接口:&#xA;Scans WebResourceScan LocalResourceScan&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;其他一些零碎的package:&lt;/strong&gt;&#xA;conf &amp;ndash; jukai设计,被zozoh否决,现在仅el包还有引用,只有一个类,与EL一起看看吧&#xA;filepool &amp;ndash; 文件池,放临时文件的,NutDao操作Clob/Blob数据,MVC的upload会用到&#xA;http &amp;ndash; 简单的http客户端,功能简单够用(够我们自己用&amp;hellip;)&#xA;img &amp;ndash; 图像操作&#xA;mock &amp;ndash; 最初的计划是完成一个Mock框架,后来缩减为mock servlet的,用来模拟servlet容器&#xA;org.nutz.repo.org.objectweb.asm &amp;ndash; 被我精简过的asm 3.3,全是字节码操作,枯燥乏味.&#xA;service &amp;ndash; NutDao的小封装,看完Dao不妨看这个&#xA;trans &amp;ndash; NutDao的事物封装,跟service一样,看完Dao再看看呗&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;读源码的方法:&lt;/strong&gt;&#xA;大大前提,把nutz的源码全下载下来,按手册的说明,把test跑通.&#xA;1. 堆栈&#xA;例如Ioc,你肯定想知道一个bean是如何被创建的. 那么,在你的类的构造方法中,加入一句: new Throwable().printStackTrace();&#xA;跟着堆栈一层层了解&lt;/p&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&lt;p&gt;debug&#xA;这个更狠一些,顺着代码的执行,想深入的地方就进入,不感兴趣的地方就next,形成一个流程的概念.&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;看testcase&#xA;由于testcase是使用场景抽象出来的代码,所以很有参考价值.&lt;/p&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;p&gt;附上几个Eclipse快捷键:&#xA;ctrl+shift+T 查找某个类&#xA;ctrl+L 跳到具体的行数&#xA;alt+shift+b 打开源码视图上方的导航条,方便跳转到某个方法&lt;/p&gt;&#xA;&#xA;&lt;p&gt;看Nutz代码时,我非常非常建议你记录下任何错误,并报告给我们.即使是错别字,我们也很开心得收到你的指正哦&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>登录入口的一个小小的细节,HttpSession.setAttribute的调用顺序</title>
      <link>http://wendal.net/399.html</link>
      <pubDate>2012-03-14 09:23:40 +0800</pubDate>
      <description>&lt;p&gt;今天与zozoh的交谈中,又把这个问题提了一下. 就是登录代码中,Session处于一个不可靠的状态.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;这里用NutzMVC的代码来演示,但并不代表是nutz的问题,而是J2EE都面对的问题(PS: 如果你使用了SpringSecurity等安全框架,则可能它已经帮你出来了这个问题)&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;//登录入口方法&#xA;public View login(String userName, String passwd, HttpSession session) {&#xA;    session.setAttribute(&amp;quot;me&amp;quot;, user); //当代码运行到这里,会话中已经存在me这个attr&#xA;    session.setAttribute(&amp;quot;rule&amp;quot;, rule);&#xA;    return new JspView(&amp;quot;/index.jsp&amp;quot;);&#xA;}&#xA;&#xA;//登录后才能访问的入口方法&#xA;@Filters(@By(type = CheckSession.class, args = {&amp;quot;me&amp;quot;, &amp;quot;/&amp;quot;})) //已经HttpSession中已经包含me这个attr,所以,这个过滤器会判定为已经登录&#xA;public Object xxx(HttpSession session) {&#xA;    Rule myRule = session.get(&amp;quot;rule&amp;quot;); //由于已经被@Filters标注,所以方法会认为会话是已经完整初始化的&#xA;    // .... ... .. &#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;也就是说, HttpSession在登录入口方法完成前,处于一个不可靠的状态 &amp;ndash; 对于检测是否登录的代码来说,这个会话是已经登录的,但事实上这个会话并未完成逻辑上的初始化.&#xA;当恶意进行类似的访问(多线程),那么其他入口方法要么报NPE,要么执行不可预测的逻辑.如果入口方法需要设置多个attr,那么HttpSession将处于多个不同的半初始化状态.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;要避免这个问题,是将登录的标记,放在入口方法的最后.&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;public View login(String userName, String passwd, HttpSession session) {&#xA;    session.setAttribute(&amp;quot;rule&amp;quot;, rule);&#xA;    session.setAttribute(&amp;quot;me&amp;quot;, user); //由于jsp中不包含逻辑,所以在这里设置登录的识别信息,完成会话初始化.&#xA;    return new JspView(&amp;quot;/index.jsp&amp;quot;);&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;小小细节,轻者NPE,重者,谁知道呢,呵呵&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>图,是一种表态</title>
      <link>http://wendal.net/397.html</link>
      <pubDate>2012-03-14 09:06:57 +0800</pubDate>
      <description>&lt;p&gt;&lt;img src=&#34;/assets/media/2012/03/p_large_7rdv_2c51000037bc1263.jpg&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>获得方法形参名称列表 -- 哦也,搞定!!</title>
      <link>http://wendal.net/394.html</link>
      <pubDate>2012-03-10 10:46:33 +0800</pubDate>
      <description>&lt;p&gt;JAVA获取类的方法的参数名 &amp;ndash; 老话题,新方法!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;折腾了一天,终于搞定了.测试了nutz所有的类,均读取正常!! 完美读取任何class的变量名信息! 呵呵,当前,前提是编译时含debug信息.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;无任何依赖&lt;/strong&gt;,不需要asm,不要其他任何字节码工具,纯标准JDK API实现. 核心代码,仅一个方法,130行,哦也!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;终于完成这个一直想做到的功能 &amp;ndash; 在Java中,获取方法的形参(参数)的名字.由于这个类只做需要做的事,所以,我非常确信它比asm的vistor更快,更可靠.&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;public void list(int page , int pageSize) { //这个类的作用,就是拿到page和pageSize这两个名字,是的,是名字.&#xA;   //...&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;实现关键点:&lt;/strong&gt;:&#xA;1. 跳过一切不需要的数据结构,如版本号,接口信息,字段信息&#xA;2. 只解析常量池中UTF8_String,因为只用到这个,其他都是多余的常量&#xA;3. 实现方法到descriptor的转换函数,因为字节码中的方法签名,是descriptor格式的&lt;/p&gt;&#xA;&#xA;&lt;p&gt;代码中含义泛型,直接贴这里的话,页面显示比较麻烦,就上个截图吧.&#xA;&lt;img src=&#34;/assets/media/2012/03/method_param.jpg&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;代码已经提交到nutz,并添加了一个&lt;a href=&#34;https://gist.github.com/2011728&#34;&gt;gist&lt;/a&gt;,欢迎使用,如果有任何解析失败的类,非常欢迎发送给我进行检测.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;总结一下值得注意的写法&lt;/strong&gt;:&#xA;1. DataInputStream.skip跟DataInputStream.skipBytes不是一回事,当较大的数值传入skip方法,这个方法实际跳过的字节数,往往小于预期.虽然skipBytes也并不保证完整跳过,但至今没发现非完整跳过的情况&lt;/p&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&lt;p&gt;DataInputStream.readUnsignedShort()的返回值是int,而readShort的返回值是short,以前一直以为short是无符号的呢!! 好吧,还有readUnsignedByte方法&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;常量池中的CONSTANT_Long和CONSTANT_Double是8byte数据,其之后的一个常量池位置,是不可使用的,必须跳过. 贴一下JVM标准的中的描述:&lt;/p&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;p&gt;All 8-byte constants take up two entries in the constant_pool table of the class ﬁle. If a&#xA;CONSTANT_Long_info or CONSTANT_Double_info structure is the item in the&#xA;constant_pool table at index n, then the next usable item in the pool is located at index&#xA;n +2. The constant_pool index n +1 must be valid but is considered unusable.&#xA;有个小注释:** In retrospect, making 8-byte constants take two constant pool entries was a poor choice.** 好吧,愚蠢的选择,但这是历史遗留问题了&amp;hellip;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;这个类,兼容到JDK7.&#xA;Class Format : &lt;a href=&#34;http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html&#34;&gt;http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;提醒: 这个类无法获取接口的形参,因为接口的class文件并不保存变量名&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>NutzMongoSession -- 轻便的分布式Session实现</title>
      <link>http://wendal.net/393.html</link>
      <pubDate>2012-03-06 03:20:40 +0800</pubDate>
      <description>&lt;p&gt;作为Ngqa项目的其中一个功能, NutzMongoSession已经开发完成,并迁入zTask项目中,与NutzMongo的代码整合.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;1. 用法&lt;/strong&gt;&#xA;基本配置(web.xml),接管全部请求,并替换其获取会话的req.getSession方法:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;    &amp;lt;filter&amp;gt;&#xA;        &amp;lt;filter-name&amp;gt;mongoSession&amp;lt;/filter-name&amp;gt;&#xA;        &amp;lt;filter-class&amp;gt;org.nutz.mongo.session.MongoSessionFilter&amp;lt;/filter-class&amp;gt;&#xA;    &amp;lt;/filter&amp;gt;&#xA;    &amp;lt;filter-mapping&amp;gt;&#xA;        &amp;lt;filter-name&amp;gt;mongoSession&amp;lt;/filter-name&amp;gt;&#xA;        &amp;lt;url-pattern&amp;gt;/*&amp;lt;/url-pattern&amp;gt;&#xA;        &amp;lt;dispatcher&amp;gt;REQUEST&amp;lt;/dispatcher&amp;gt;&#xA;        &amp;lt;dispatcher&amp;gt;FORWARD&amp;lt;/dispatcher&amp;gt;&#xA;        &amp;lt;dispatcher&amp;gt;INCLUDE&amp;lt;/dispatcher&amp;gt;&#xA;    &amp;lt;/filter-mapping&amp;gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;在项目启动的代码中,加入下面的语句:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;new MongoSessionManager(dao).register(servletContext, null);&#xA;//其中,dao是MongoDao的实例&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;2. 与标准HttpSession的差异&lt;/strong&gt;&#xA;可存放的对象类型: 普通数据类型,MongoDao所管理的Pojo,一切可以顺利json序列化/反序列化的对象&#xA;由于是分布式的Session,必须考虑对象的状态托管问题,上代码:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;User user = new User();&#xA;user.setName(&amp;quot;wendal&amp;quot;);&#xA;session.setAttribute(&amp;quot;me&amp;quot;, user);&#xA;user.setName(&amp;quot;ABC&amp;quot;); //这个方法调用,改变了对象的属性,但没有再次调用session.setAttribute&#xA;//....&#xA;&#xA;//另外一个方法里面&#xA;String myName = ((User)session.getAttribute(&amp;quot;me&amp;quot;)).getName();&#xA;//这里所得到的值,将是&amp;quot;wendal&amp;quot;而非&amp;quot;ABC&amp;quot;&#xA;&#xA;//------------------------------------------------------------------------------------&#xA;&#xA;//而,如果User是一个MongoDao所管理的bean的话,那么,它的&#xA;session.setAttribute(&amp;quot;me&amp;quot;, user);&#xA;user.setName(&amp;quot;ABC&amp;quot;); //这个方法调用,改变了对象的属性,但没有再次调用session.setAttribute&#xA;dao.save(user); 把user更新到mongo&#xA;&#xA;//另外一个方法里面&#xA;String myName = ((User)session.getAttribute(&amp;quot;me&amp;quot;)).getName();&#xA;//这里所得到的值,将是&amp;quot;ABC&amp;quot;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;3. 获取全部Session&lt;/strong&gt;&#xA;一直以来,我都以为无法通过标准的ServletAPI简单获取当前应用的全部Session,直至我完成了NutzMongoSession,才发现HttpSession接口有一个已经废弃的方法可以做到&#xA;好吧,我承认,我误导了很多很多童鞋&amp;hellip;.&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;req.getSession().getSessionContext().getIds();&#xA;//这样就能拿到全部Session的Id,然后通过Id,获取&#xA;req.getSession().getSessionContext().getSession(id);&#xA;//来获取具体的Session&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;为了与标准的HttpSession最大兼容,所以,NutzMongoSession也实现了这个方法.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;4. 不足之处&lt;/strong&gt;&#xA;清理过期Session的算法,还需要改进,因为在服务器端,循环执行new Date()还是有一定成本的&lt;/p&gt;&#xA;&#xA;&lt;p&gt;当前, NutMongoSession已经应用在Ngqa和zTask,效果还不错.&#xA;有了NutMongoSession, &lt;strong&gt;应用做水平扩展&lt;/strong&gt;就会很方便了,呵呵&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Win8消费者预览版无法拨通VPN的解决方法</title>
      <link>http://wendal.net/387.html</link>
      <pubDate>2012-03-03 02:56:47 +0800</pubDate>
      <description>&lt;p&gt;用上Win8已经2天了,其中就纠结的莫过于VPN拨号失败&amp;hellip;&#xA;&lt;img src=&#34;/assets/media/2012/03/Win8_VPN_FAIL.jpg&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;失败的原因是, VPN拨号是,会自动把计算机名做为域,并附加到验证信息中!! 非常非常纠结的一个行为,而且无法自行输入(^&amp;amp;$&amp;amp;#%&amp;amp;$^%&amp;amp;)&lt;/p&gt;&#xA;&#xA;&lt;p&gt;几经探索,终于找到一个方法,就是设置VPN的选项,让其先拨ADSL:&#xA;&lt;img src=&#34;/assets/media/2012/03/Win8_VPN_1.jpg&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;拨号时,就会出现对话框了.. 鸡冻啊!!:&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2012/03/Win8_VPN_2.jpg&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>SSH隧道+Polipo+Pac文件--打造翻G功F夫W墙的共用平台</title>
      <link>http://wendal.net/383.html</link>
      <pubDate>2012-02-26 10:15:59 +0800</pubDate>
      <description>&lt;p&gt;自认翻X墙高手,却与同事交流的时候败下阵来,我最初还口口声声说 几条命令 就能搞定,绝对米问题.&#xA;结果,俺发现,这玩意还是有点技术含量的&amp;hellip; 不过,经过我不断提炼,最后是十几条命令搞定(关键语句仅3条,即启动3个进程),哦也!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;需求基本上是这样:&#xA;客户端只需要配置一下代理服务器,就能做到需要翻墙就翻墙,不需要就走普通渠道.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;最初,我的想法&#xA;1. 直接ssh隧道 &amp;ndash; 只有部分程序支持sockt5代理&#xA;2. squid+ssh隧道 &amp;ndash; squid压根不支持sockt5的后端代理,我靠&#xA;3. squid+Polipo+ssh隧道 &amp;ndash; 有点靠谱了,我差点就狠心学一下squid恶心的配置文件&#xA;4. nginx+Polipo+ssh隧道 &amp;ndash; 代理https有点问题,我一直没解决&lt;/p&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&lt;p&gt;在本地一台Linux服务器,创建用proxy,创建sshkey并上传到国外的vps:&lt;/p&gt;&#xA;&#xA;&lt;p&gt;#添加用户&#xA;adduser proxy&#xA;#切换到proxy用户&#xA;su proxy&#xA;#创建ssh密钥,一路回车&#xA;ssh-keygen&#xA;#将刚刚生成的key,上传到国外vps,以便进行无密码登录&#xA;ssh-copy-id -i ~/.ssh/id_rsa.pub root@nutz.cn&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;创建SSH隧道:&lt;/p&gt;&#xA;&#xA;&lt;p&gt;ssh -D 127.0.0.1:7070 -N -c blowfish -C -4 -2 root@nutz.cn &amp;amp;&#xA;#解释:&lt;/p&gt;&#xA;&#xA;&lt;h1&gt;&lt;a style=&#34;display: block;&#34; name=&#34;-d-127.0.0.1:7070-监听本地7070端口,转发到远程服务器&#34; href=&#34;#-d-127.0.0.1:7070-监听本地7070端口,转发到远程服务器&#34;&gt;&lt;/a&gt;-D 127.0.0.1:7070 监听本地7070端口,转发到远程服务器&lt;/h1&gt;&#xA;&#xA;&lt;h1&gt;&lt;a style=&#34;display: block;&#34; name=&#34;-n-不启动shell&#34; href=&#34;#-n-不启动shell&#34;&gt;&lt;/a&gt;-N 不启动shell&lt;/h1&gt;&#xA;&#xA;&lt;h1&gt;&lt;a style=&#34;display: block;&#34; name=&#34;-c-blowfish-采用blowfish加密,更快更安全&#34; href=&#34;#-c-blowfish-采用blowfish加密,更快更安全&#34;&gt;&lt;/a&gt;-c blowfish 采用blowfish加密,更快更安全&lt;/h1&gt;&#xA;&#xA;&lt;h1&gt;&lt;a style=&#34;display: block;&#34; name=&#34;-c-压缩数据&#34; href=&#34;#-c-压缩数据&#34;&gt;&lt;/a&gt;-C 压缩数据&lt;/h1&gt;&#xA;&#xA;&lt;h1&gt;&lt;a style=&#34;display: block;&#34; name=&#34;-4-强制ipv4&#34; href=&#34;#-4-强制ipv4&#34;&gt;&lt;/a&gt;-4 强制ipv4&lt;/h1&gt;&#xA;&#xA;&lt;h1&gt;&lt;a style=&#34;display: block;&#34; name=&#34;-2-强制使用ssh2协议&#34; href=&#34;#-2-强制使用ssh2协议&#34;&gt;&lt;/a&gt;-2 强制使用SSH2协议&lt;/h1&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;编译并启动Polipo&lt;/p&gt;&#xA;&#xA;&lt;p&gt;#如果有git客户端&#xA;git clone git://git.wifi.pps.jussieu.fr/polipo &amp;ndash;depth=0&#xA;#如果木有,则下载压缩包&#xA;wget -O polipo.zip &amp;ndash;no-check-certificate &lt;a href=&#34;https://github.com/jech/polipo/zipball/master&#34;&gt;https://github.com/jech/polipo/zipball/master&lt;/a&gt;&#xA;unzip polipo.zip&lt;/p&gt;&#xA;&#xA;&lt;p&gt;cd polipo #或者是unzip出来的文件夹&lt;/p&gt;&#xA;&#xA;&lt;p&gt;#编译&#xA;make&lt;/p&gt;&#xA;&#xA;&lt;p&gt;#启动Polipo&#xA;./polipo socksParentProxy=localhost:7070 daemonise=true proxyAddress=192.168.9.100  proxyPort=8080&#xA;#这里的7070,就是SSH隧道所监听的地址&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;下载并对外提供pac文件&lt;/p&gt;&#xA;&#xA;&lt;p&gt;wget -O proxy.pac &lt;a href=&#34;http://autoproxy2pac-charlie.appspot.com/proxy/192.168.9.100/8080?download&#34;&gt;http://autoproxy2pac-charlie.appspot.com/proxy/192.168.9.100/8080?download&lt;/a&gt;&#xA;#这里的ip及端口,需要对应Polipo的设置哦&lt;/p&gt;&#xA;&#xA;&lt;p&gt;#用Python来启动一个简单的http服务器,用于对外提供pac&#xA;python -m SimpleHTTPServer 8000&lt;/p&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;p&gt;这样,就大功告成了,只需要在IE中设置一下自动代理脚本的URL,就能自动判断是否走代理了:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;http://192.168.2.100:8000/proxy.pac&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;扩展设置:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;#防ssh短线,在服务器端的/etc/ssh/sshd_config&#xA;ClientAliveInterval 60&#xA;ClientAliveCountMax 10000000&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;还需要解决的问题:&#xA;1. Polipo崩溃后自动重启 &amp;ndash; 一个监护进程&#xA;2. SSH隧道短线自动重连  &amp;ndash; 同上&#xA;3. 流量控制            &amp;ndash; 加个nginx?squid来控制?&#xA;4. 限制视频,下载       &amp;ndash; 同上&#xA;5. 用户过滤            &amp;ndash; 同上, 我想到了伟大的nginx-lua模块&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>鸣鸣与本地樱花</title>
      <link>http://wendal.net/379.html</link>
      <pubDate>2012-02-26 03:46:35 +0800</pubDate>
      <description>&lt;p&gt;广州市花都区梯面镇,一小片的樱花树&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2012/02/C-300x225.jpg&#34;&gt;鸣鸣与樱花合影&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/2012/02/DSCF0983-300x225.jpg&#34;&gt;小樱花特写2&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media2012/02/DSCF0986-300x225.jpg&#34;&gt;小樱花特写1&lt;/img&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;相机: 富士, 非单反, 纯傻瓜机&#xA;未PS,但用Windows自带的画图工具缩小的尺寸.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Nutz-Socialauth 1.b.3 -- 支持国内社会化登录(OpenId)</title>
      <link>http://wendal.net/376.html</link>
      <pubDate>2012-02-23 10:08:55 +0800</pubDate>
      <description>&lt;p&gt;作为&lt;a href=&#34;https://github.com/howe/ngqa&#34;&gt;Ngqa&lt;/a&gt;的子项目之一,开发了2周,终于能拿得出手了&lt;/p&gt;&#xA;&#xA;&lt;p&gt;这个项目算是&lt;a href=&#34;http://code.google.com/p/socialauth/&#34;&gt;socialauth&lt;/a&gt;的一个插件项目,加上本项目的代码,将支持以下的社会化登录(打星号的是本项目添加的登录方式,&lt;strong&gt;率先支持github和BrowserID哦&lt;/strong&gt;):&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;p&gt;google&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;yahoo&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;twitter&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;facebook&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;hotmail(msn)&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;*&lt;strong&gt;QQ连接(qq)&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;*新浪微博(sina)&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;*开心网(kaixin001)&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;*&lt;strong&gt;github&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;*豆瓣(douban)&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;*百度(baidu)&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;*&lt;strong&gt;支付宝(alipay)&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;*人人网(renren)&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;Foursquare(foursquare)&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;Yammer(yammer)&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;*腾讯微博(qqweibo)&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;*搜狐(sohu)&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;*&lt;strong&gt;淘宝(taobao)&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;LinkedIn(linkedin)&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;MySpace(myspace)&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;AOL(aol)&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;*&lt;strong&gt;BrowserID&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;有2个尚未验证的,由于提供商本身的原因,尚未解决&#xA;&amp;ndash;&amp;gt; *网易(net163) &amp;ndash; 神经病机制,竟然要求自行返回原网站输入Code&#xA;&amp;ndash;&amp;gt; *盛大(sdo) &amp;ndash; 成功过,然后又挂了,QQ群直接拒绝我的加入请求,无解中&amp;hellip;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;虽然部分提供商有官方/非官方的SDK,但质量非常参差不齐,而且很多都依赖一大堆额外的jar, 故本项目没有使用这些SDK.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;大部分网站采用OAuth1/OAuth2登录,部分网站在请求其OpenAPI时需要额外提供签名参数.值得指出的是盛大连接,自行实现了一套不靠谱的规范,成功率低,行为可预测性低.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;就登录而已,这次开发,也了解到国内各家提供商对社会化登录/OpenID的态度.&#xA;态度最好的,莫过于新浪,完整且可靠的文档,其次是QQ连接. 部分网站,如支付宝/盛大,提供是代码,压根没文档!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;OAuth1与OAuth2的区别&lt;/strong&gt;:&#xA;OAuth1 是3次握手, 先检查网站的密钥的可靠性,然后转到用户登录界面,用户登录后再校验用户的返回&#xA;OAuth2 是2次握手, 网站引导用户到登录界面,用户登录后再校验用户的返回&lt;/p&gt;&#xA;&#xA;&lt;p&gt;国内有多家OAuth2提供商,部分提供商要求提供备案号,保密协议等等神奇的事,当然,在天朝,这都很正常.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;下载地址&lt;/strong&gt;: &lt;a href=&#34;https://github.com/howe/ngqa/downloads&#34;&gt;https://github.com/howe/ngqa/downloads&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;如果你有发现哪家网站提供了OAuth1/2登录的话,不妨提醒一下,很可能提供相应的实现哦&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>海淘 -- 地球绕一圈,价格反而便宜了</title>
      <link>http://wendal.net/375.html</link>
      <pubDate>2012-02-22 04:41:03 +0800</pubDate>
      <description>&lt;p&gt;2011年11月,第一次接触到海淘,现在已经有好几单&lt;/p&gt;&#xA;&#xA;&lt;p&gt;最初用的是&lt;a href=&#34;http://www.buytong.com/&#34;&gt;百通&lt;/a&gt;,走了2单, 速度一般般,后来百通爆仓,外加当时&lt;a href=&#34;http://www.thunderex.com/Register.aspx?cs=jason&amp;amp;ref=wendal&#34;&gt;风雷&lt;/a&gt;单价更低,所以至今最大一单走了风雷&lt;/p&gt;&#xA;&#xA;&lt;p&gt;价格:&#xA;   海淘第一单,是OLAY的洁面刷,美国亚马逊$20,国内报价280, 汗吧&amp;hellip;&#xA;   XBox360这种国内禁售品,更是绕了地球一圈&amp;hellip; 赶上圣诞购物月, $199实在难以抗拒,呵呵,还返$10, 一个月之后再送一张$50-$10&lt;/p&gt;&#xA;&#xA;&lt;p&gt;运费:&#xA;   百通26/磅,但不保价,很坑爹了&amp;hellip; 距QQ群的反馈,貌似越来越不给力,单子越来越慢&#xA;   风雷28/磅,保$100,之前25/磅,这个月刚刚提价&amp;hellip; 速度还不错&lt;/p&gt;&#xA;&#xA;&lt;p&gt;关税:&#xA;   至今没被税过,外加风雷对部分货物是包税的&lt;/p&gt;&#xA;&#xA;&lt;p&gt;当前觉得风雷还是很靠谱的,虽然现在贵2元,还是比较值&lt;/p&gt;&#xA;&#xA;&lt;p&gt;附上几个网站:&#xA;&lt;a href=&#34;http://www.mgpyh.com/&#34;&gt;http://www.mgpyh.com/&lt;/a&gt; 信息及时,立场比较中立&#xA;&lt;a href=&#34;http://camelcamelcamel.com&#34;&gt;http://camelcamelcamel.com&lt;/a&gt; 价格跟踪,登记一下目标价,到位就有邮件通知,很方便&#xA;&lt;a href=&#34;http://www.smzdm.com/&#34;&gt;http://www.smzdm.com/&lt;/a&gt;&#xA;&lt;a href=&#34;http://www.mgzpy.com/&#34;&gt;http://www.mgzpy.com/&lt;/a&gt;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Ngqa -- 不单单是一个QA系统</title>
      <link>http://wendal.net/372.html</link>
      <pubDate>2012-02-19 01:34:02 +0800</pubDate>
      <description>&lt;p&gt;项目地址: &lt;a href=&#34;https://github.com/howe/ngqa&#34;&gt;https://github.com/howe/ngqa&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;使用了 Nutz, Nutz-mongo, Nutz-web, Nutz-socialauth &amp;hellip;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;这项目的最初目的是为Nutz搭建一个完整好玩的QA系统,现在的作用远大于此:&lt;/p&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;Nutz-socialauth, 是本项目的其中一个亮点 &amp;ndash; 支持30种以上的社会化登录(OpenId), 号称国内第一, 率先github这个专业程序员必备网站&lt;/li&gt;&#xA;&lt;li&gt;完整可用的Demo &amp;ndash; Nutz长期被投诉的重点,没一个完整可运行的,持续更新并提供支持的demo. 这个项目就突破这个问题,将包含足够丰富的注释及使用范例&lt;/li&gt;&#xA;&lt;li&gt;作为一个QA系统,将有效积累Nutz的FAQ库&lt;/li&gt;&#xA;&lt;li&gt;激活Nutz社区 &amp;ndash; 作为一个公开的项目,在开发的过程中,Nutzer们参与进来,动手把项目运行起来&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;p&gt;项目设计, 采用OpenAPI的思想, 网站页面,只是其中一个表现方式,开发完成后,将配备SDK,方便客户端扩展&lt;/p&gt;&#xA;&#xA;&lt;p&gt;其中一个核心就是SmartView,根据访问地址的后缀来判断需要执行的视图,而非固定的配置为一种视图,示例代码:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;    public void render(HttpServletRequest req, HttpServletResponse resp,&#xA;            Object obj) throws Throwable {&#xA;        String uri = req.getRequestURI();&#xA;        if (uri.endsWith(&amp;quot;.json&amp;quot;))&#xA;            new AjaxView().render(req, resp, obj);&#xA;        else if (uri.endsWith(&amp;quot;.rss&amp;quot;))&#xA;            new RssView().render(req, resp, obj);&#xA;        else&#xA;            new JspView(viewValue).render(req, resp, obj); //这里默认跑jsp&#xA;    }&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;同时,这个项目也使用了即将发布的Nutz-Mongo, 是nutz与nosql数据库的首个结合,很多非常酷的功能哦&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>JActor最简单试用</title>
      <link>http://wendal.net/371.html</link>
      <pubDate>2012-02-12 11:59:41 +0800</pubDate>
      <description>&lt;p&gt;发现网上连一篇简单的入门都没有,我晕啊&amp;hellip; 折腾了一下,终于变菜鸟了,把官方例子注释一下给大家了解一下&lt;/p&gt;&#xA;&#xA;&lt;p&gt;共需要3个类&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;import org.agilewiki.jactor.bind.SynchronousRequest;&#xA;public class Hi extends SynchronousRequest&amp;lt;string&amp;gt; {}&#xA;// 我觉得就是一个消息对象, 传递给Greeter类里面的synchronousProcessRequest方法,可以携带任意信息啦&#xA;&#xA;//忽略import&#xA;public class Greeter extends Component {&#xA;&#xA;    public void bindery() throws Exception {&#xA;&#xA;        //这里绑定Hi对象的处理逻辑&#xA;        thisActor.bind(Hi.class.getName(), new SynchronousMethodBinding&amp;lt;Hi, String&amp;gt;() {&#xA;            @Override&#xA;            //一个处理方法,执行实际操作&#xA;            public String synchronousProcessRequest(Internals internals, Hi request) throws Exception {&#xA;                //这个request,就是外部传入的Hi实例&#xA;                return &amp;quot;Hello world!&amp;quot;; //还有无返回值的形式&#xA;            }&#xA;        });&#xA;&#xA;    }&#xA;}&#xA;&#xA;//忽略全部import&#xA;public class Main {&#xA;&#xA;    public static void main(String[] args) {&#xA;        JAMailboxFactory mailboxFactory = JAMailboxFactory.newMailboxFactory(1);&#xA;        try {&#xA;            Mailbox mailbox = mailboxFactory.createAsyncMailbox();&#xA;            JCActor a = new JCActor(mailbox);&#xA;            (new Include(Greeter.class)).call(a); //登记一个调用&#xA;            JAFuture future = new JAFuture();&#xA;            String greeting = (new Hi()).send(future, a); // 不通过mailbox直接调用actor&#xA;            System.out.println(greeting);&#xA;        } catch (Exception e) {&#xA;            e.printStackTrace();&#xA;        } finally {&#xA;            mailboxFactory.close(); //必须关闭哦, 以确保全部信息都已经安全完成&#xA;        }&#xA;    }&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;官方教程地址: &lt;a href=&#34;https://github.com/laforge49/JActor/wiki/Synchronous-Programming&#34;&gt;JActor Synchronous-Programming&lt;/a&gt;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>纯Java处理CMYK格式(32位色深)的JPEG文件!!</title>
      <link>http://wendal.net/369.html</link>
      <pubDate>2012-02-10 08:31:19 +0800</pubDate>
      <description>&lt;p&gt;无限折腾之后,终于找到一个能用的纯Java的解决方法:&#xA;1. 获取jpeg格式的ImageReader&#xA;2. 通过ImageIO.createImageInputStream生成ImageInputStream&#xA;3. ImageReader和ImageInputStream协作,产生Raster&#xA;4. 使用createJPEG4通过色彩空间变化,生成BufferedImage&#xA;5. 重要: 把BufferedImage保存为临时的jpg文件,然后重新解析为BufferedImage&lt;/p&gt;&#xA;&#xA;&lt;p&gt;这样,最后得到的BufferedImage,将是一个普通的24位色深的RGB的jpg文件所对应的BufferedImage&lt;/p&gt;&#xA;&#xA;&lt;p&gt;注意, 第4步所产生的BufferedImage,进行某些操作时会报错,因为色彩空间是ColorSpace.CS_sRGB,所以,先保存到临时jpg文件,然后再生成标准的BufferedImage是非常重要的.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;具体实现已经集成到&lt;a href=&#34;https://github.com/nutzam/nutz/blob/master/src/org/nutz/img/Images.java&#34;&gt;Nutz的Images类&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;感谢:&#xA;Sun java &lt;a href=&#34;http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4799903&#34;&gt;http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4799903&lt;/a&gt;&#xA;dsmart-30buy&#xA; &lt;a href=&#34;http://dsmart-30buy.iteye.com/blog/1226969&#34;&gt;http://dsmart-30buy.iteye.com/blog/1226969&lt;/a&gt;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>鸣鸣满一个太阳年了</title>
      <link>http://wendal.net/366.html</link>
      <pubDate>2012-02-02 10:11:36 +0800</pubDate>
      <description>&lt;p&gt;一年了, 很充实&lt;/p&gt;&#xA;&#xA;&lt;p&gt;上一张鸣鸣的小照片, 2个月的时候&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&#34;/assets/media/2012/02/20110329564-768x1024.jpg&#34;&gt;鸣鸣2个月的小照片&lt;/a&gt;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>初探Mongodb的Java驱动</title>
      <link>http://wendal.net/364.html</link>
      <pubDate>2012-01-31 09:26:08 +0800</pubDate>
      <description>&lt;p&gt;&lt;strong&gt;1. 数据格式传递&lt;/strong&gt;&#xA;上个自己画的图&#xA;&lt;a href=&#34;/assets/media/2012/01/Mongodb-Java.png&#34;&gt;Mongodb-Java驱动基本流程&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;驱动里面操作的,是DBObject(用户提供的和已经转为Command格式的DBObject),OutMessage(可以转为byte[]写入Socket),Response,WriteResult(用户真正拿到的返回值)&lt;/p&gt;&#xA;&#xA;&lt;p&gt;层层封装,绕得我头都晕&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;2. 日志与Debug信息&lt;/strong&gt;&#xA;日志采用JDK Logging,有1个比较关键的环境变量配置DB.TRACE,设置为true时,log的日志level会改变 &amp;hellip; 我汗啊&amp;hellip;.&#xA;原本以为另外一个配置DEBUG.DB也控制了什么东西,后来才发现,这配置完全没人调用,应该是历史遗留下来的&lt;/p&gt;&#xA;&#xA;&lt;p&gt;还有一些比较诡异的环境变量设置&#xA;MONGO-TRACKLEAKS &amp;ndash; SimplePool里面的设置,同样作用于连接池&#xA;DEBUG.MONGO&#xA;DEBUG.DBPOINTER &amp;ndash; 已经废弃的类,直接无视吧&#xA;com.mongodb.cleanerIntervalMS &amp;ndash; 定期轮询DB实例,执行 db.cleanCursors(true);&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;3. 切勿使用的类&lt;/strong&gt;&#xA;com.mongodb.util.TestCase和com.mongodb.util.TestNGListener属于坑爹类,依赖TestNG,却不放在test文件夹中,MyAsserts也好不到哪里去&#xA;com.mongodb.util和com.mongodb.io包里面的类也不要用,很多类连驱动本身也没有使用!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;4. 对象序列化/反序列化的规则&lt;/strong&gt;&#xA;比较有趣的是内置的Json序列化/反序列化类,里面解释了一些类型映射方面的规则(序列化的代码在JSon类,反序列的代码在JSONCallback):&#xA;ObjectId  &amp;mdash; {$oid : &amp;ldquo;具体的值&amp;rdquo;}&#xA;java.util.Date &amp;mdash; {$date : &amp;ldquo;yyyy-MM-dd&amp;rsquo;T&amp;rsquo;HH:mm:ss.SSS&amp;rsquo;Z&amp;rsquo;&amp;ldquo;} 而且是UTC的,即不保存时区数据!!&#xA;DBRefBase &amp;mdash; {$ref : &amp;ldquo;集合名&amp;rdquo;, $id : 具体id的值}&#xA;Pattern &amp;mdash; {$regex:&amp;ldquo;正则表达式原型&amp;rdquo;, $options : &amp;ldquo;表达式的flag&amp;rdquo;}&#xA;BSONTimestamp &amp;mdash; {$ts: 具体时间, $inc:具体毫秒数}&#xA;UUID &amp;mdash; {$uuid : &amp;ldquo;uuid标准的toString()&amp;rdquo;}&#xA;CodeWScope &amp;mdash; {$code: 具体的值, $scope : 具体的值}&#xA;Code &amp;mdash; {$code: 具体的值}&#xA;MinKey &amp;mdash; {$minKey : 1} 没错,是固定为1&#xA;MaxKey &amp;mdash; {$maxKey : 1} 同样是1&#xA;基本数据类型,封装类型,String,数组,List,Map当然都是支持的了,其他全部都是不可序列化的&lt;/p&gt;&#xA;&#xA;&lt;p&gt;而,真正进行DBObject转换为byte[]的类,是org.bson.BasicBSONEncoder,摘录一段关键代码:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;        if ( name.equals( &amp;quot;_transientFields&amp;quot; ) )    //不会被序列化的东西,终于有藏身之所&#xA;            return;&#xA;&#xA;        if ( DEBUG ) System.out.println( &amp;quot;\t put thing : &amp;quot; + name ); //竟然是syso,我晕&#xA;&#xA;        if ( name.equals( &amp;quot;$where&amp;quot;) &amp;amp;&amp;amp; val instanceof String ){   //特别吧? 呵呵&#xA;            _put( CODE , name );&#xA;            _putValueString( val.toString() );&#xA;            return;&#xA;        }&#xA;&#xA;        val = BSON.applyEncodingHooks( val );&#xA;&#xA;        if ( val == null )&#xA;            putNull(name);&#xA;        else if ( val instanceof Date )&#xA;            putDate( name , (Date)val );&#xA;        else if ( val instanceof Number )&#xA;            putNumber(name, (Number)val );&#xA;        else if ( val instanceof Character )&#xA;            putString(name, val.toString() );&#xA;        else if ( val instanceof String )&#xA;            putString(name, val.toString() );&#xA;        else if ( val instanceof ObjectId )&#xA;            putObjectId(name, (ObjectId)val );&#xA;        else if ( val instanceof BSONObject )&#xA;            putObject(name, (BSONObject)val );&#xA;        else if ( val instanceof Boolean )&#xA;            putBoolean(name, (Boolean)val );&#xA;        else if ( val instanceof Pattern )&#xA;            putPattern(name, (Pattern)val );&#xA;        else if ( val instanceof Map )&#xA;            putMap( name , (Map)val );&#xA;        else if ( val instanceof Iterable)&#xA;            putIterable( name , (Iterable)val );&#xA;        else if ( val instanceof byte[] )&#xA;            putBinary( name , (byte[])val );&#xA;        else if ( val instanceof Binary )&#xA;            putBinary( name , (Binary)val );&#xA;        else if ( val instanceof UUID )&#xA;            putUUID( name , (UUID)val );&#xA;        else if ( val.getClass().isArray() )&#xA;            putArray( name , val );&#xA;&#xA;        else if (val instanceof Symbol) {   //这个比较特别,在Json序列化中是不存在的,实际上就是对String简单封装一层&#xA;            putSymbol(name, (Symbol) val);&#xA;        }&#xA;        else if (val instanceof BSONTimestamp) {&#xA;            putTimestamp( name , (BSONTimestamp)val );&#xA;        }&#xA;        else if (val instanceof CodeWScope) {&#xA;            putCodeWScope( name , (CodeWScope)val );&#xA;        }&#xA;        else if (val instanceof Code) {&#xA;            putCode( name , (Code)val );&#xA;        }&#xA;        else if (val instanceof DBRefBase) {&#xA;            BSONObject temp = new BasicBSONObject();&#xA;            temp.put(&amp;quot;$ref&amp;quot;, ((DBRefBase)val).getRef());&#xA;            temp.put(&amp;quot;$id&amp;quot;, ((DBRefBase)val).getId());&#xA;            putObject( name, temp );&#xA;        }&#xA;        else if ( val instanceof MinKey )&#xA;            putMinKey( name );&#xA;        else if ( val instanceof MaxKey )&#xA;            putMaxKey( name );&#xA;        else if ( putSpecial( name , val ) ){&#xA;            // no-op&#xA;        }&#xA;        else {&#xA;            // 全都不是? 那就只能抛错了哦&#xA;            throw new IllegalArgumentException( &amp;quot;can&#39;t serialize &amp;quot; + val.getClass() ); &#xA;        }&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;没有特别针对Timestamp进行优化,只会按其父类java.util.Date进行处理咯,且BSONTimestamp是仅限内部使用的&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;5. 连接池的实现&lt;/strong&gt;&#xA;SimplePool,一个对象池, 同时也是DBPortPool的基础 &amp;ndash; 即Mongodb的内建数据库连接池,使用synchronized进行实现&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;6. 内置的Java对象 &amp;ndash; DBObject映射支持&lt;/strong&gt;&#xA;没看驱动源码之前,一直以为没这方面的支持,实际上还是有一个的,那就是ReflectionDBObject, 用法简介:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;public class TestReflectionDBObject {&#xA;&#xA;    public static void main(String[] args) throws Throwable {&#xA;        Mongo mongo = new Mongo();&#xA;        DB db = mongo.getDB(&amp;quot;wendal_test&amp;quot;);&#xA;        Person p = new Person();&#xA;        p.setId(UUID.randomUUID());&#xA;        p.setName(&amp;quot;wendal&amp;quot;);&#xA;        DBCollection ps = db.getCollection(&amp;quot;person&amp;quot;);&#xA;        ps.insert(p);&#xA;&#xA;        ps.setObjectClass(Person.class); //接受DBObject的子类&#xA;        Person p_db = (Person) ps.findOne();&#xA;        Assert.assertEquals(&amp;quot;wendal&amp;quot;, p_db.getName());&#xA;        System.out.println(Json.toJson(p_db));&#xA;&#xA;        mongo.close();&#xA;    }&#xA;&#xA;    public static class Person extends ReflectionDBObject { //必须继承,呵呵&#xA;        private UUID id; &#xA;        private String name; //省略getter/setter&#xA;    }&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;恩,这次就分享这么多吧.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>2011年回顾</title>
      <link>http://wendal.net/363.html</link>
      <pubDate>2012-01-29 01:32:36 +0800</pubDate>
      <description>&lt;p&gt;2011年,&lt;a href=&#34;http://wendal.net/224.html&#34;&gt;换了一家公司&lt;/a&gt; &amp;ndash; 号称第5家公司&#xA;2011年,接受了一份神奇的offer,神奇到我以为是去传销&#xA;2011年,最大的事情,当然是&lt;a href=&#34;http://wendal.net/234.html&#34;&gt;鸣鸣的出生&lt;/a&gt;,小家伙马上就要满一个太阳年了&#xA;2011年,第一次接触到海外网购,才知道绕半个地球,价格反而便宜好多&#xA;2011年,接触了好多&lt;a href=&#34;http://wendal.net/292.html&#34;&gt;新的编程语言&lt;/a&gt;,严重扩宽了我对编程的理解&#xA;2011年,&lt;a href=&#34;http://wendal.net/326.html&#34;&gt;接触NoSQL&lt;/a&gt;,刷新我对数据库的理解&#xA;2011年,我实现了&lt;a href=&#34;http://wendal.net/320.html&#34;&gt;RK2918的System可写&lt;/a&gt;及&lt;a href=&#34;http://wendal.net/339.html&#34;&gt;公开了其源码地址&lt;/a&gt;,引起不小的反响&lt;/p&gt;&#xA;&#xA;&lt;p&gt;新的一年,keep going!!&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Mongodb学习小记</title>
      <link>http://wendal.net/361.html</link>
      <pubDate>2012-01-26 10:54:17 +0800</pubDate>
      <description>&lt;p&gt;实现自增(跟oralce的序列是一个概念):&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;public static Integer getAutoIncreaseID(String idName) {&#xA;    BasicDBObject query = new BasicDBObject(&amp;quot;name&amp;quot;, idName);&#xA;    BasicDBObject update = new BasicDBObject(&amp;quot;$inc&amp;quot;, new BasicDBObject(&amp;quot;id&amp;quot;, 1));&#xA;    return (Integer) XX.getDB()&#xA;            .getCollection(&amp;quot;inc_ids&amp;quot;)&#xA;            .findAndModify(query, null, null, false, update, true, true)&#xA;            .get(&amp;quot;id&amp;quot;);&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;把元素添加到数组,仅当数组中没有这个值&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;BasicDBObject query = new BasicDBObject(&amp;quot;_id&amp;quot;, new ObjectId(&amp;quot;XXXXXXXXXXXXXXX&amp;quot;));&#xA;BasicDBObject update = new BasicDBObject(&amp;quot;$addToSet&amp;quot;, new BasicDBObject(&amp;quot;tags&amp;quot;, tag));&#xA;db.getCollection().update(query, update);&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;OpenId的登录信息,放入Mongodb中存放,使用JopenId&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;package org.nutz.viv.module;&#xA;&#xA;@IocBean&#xA;@InjectName&#xA;@At(&amp;quot;/user&amp;quot;)&#xA;public class UserModule {&#xA;&#xA;    static final long _5min = 300000L;&#xA;    static final String ATTR_MAC = &amp;quot;openid_mac&amp;quot;;&#xA;    static final String ATTR_ALIAS = &amp;quot;openid_alias&amp;quot;;&#xA;&#xA;    private String enpoint = &amp;quot;Google&amp;quot;;&#xA;&#xA;    private OpenIdManager manager = new OpenIdManager();&#xA;&#xA;    @At(&amp;quot;/login&amp;quot;)&#xA;    @Ok(&amp;quot;&amp;gt;&amp;gt;:${obj}&amp;quot;)&#xA;    public String login(HttpSession session) {&#xA;    manager.setReturnTo(Mvcs.getReq().getRequestURL().toString() + &amp;quot;/callback&amp;quot;);&#xA;    manager.setRealm(&amp;quot;http://&amp;quot;+Mvcs.getReq().getHeader(&amp;quot;Host&amp;quot;) + &amp;quot;/&amp;quot;);&#xA;    manager.setTimeOut(300 * 1000);&#xA;    Endpoint endpoint = manager.lookupEndpoint(enpoint);&#xA;        Association association = manager.lookupAssociation(endpoint);&#xA;        session.setAttribute(ATTR_MAC, association.getRawMacKey());&#xA;        session.setAttribute(ATTR_ALIAS, endpoint.getAlias());&#xA;        return manager.getAuthenticationUrl(endpoint, association); //返回的是一个Google登录页面的地址&#xA;    }&#xA;&#xA;    @At(&amp;quot;/login/callback&amp;quot;)&#xA;    public String returnPoint(HttpServletRequest request) {&#xA;    //checkNonce(request.getParameter(&amp;quot;openid.response_nonce&amp;quot;));&#xA;        // get authentication:&#xA;        byte[] mac_key = (byte[]) request.getSession().getAttribute(ATTR_MAC);&#xA;        String alias = (String) request.getSession().getAttribute(ATTR_ALIAS);&#xA;        Authentication authentication = manager.getAuthentication(request, mac_key, alias);&#xA;        authentication.getEmail();&#xA;        BasicDBObject query = new BasicDBObject();&#xA;        query.append(&amp;quot;email&amp;quot;, authentication.getEmail());&#xA;        query.append(&amp;quot;openid&amp;quot;, &amp;quot;Google&amp;quot;);&#xA;        BasicDBObject update = new BasicDBObject();&#xA;        update.append(&amp;quot;set&amp;quot;, new BasicDBObject(&amp;quot;lastLoginDate&amp;quot;, new Date()));&#xA;        DBObject dbObject = userDao.getCollection().findAndModify(query, null, null, false, update, true, true); //最后一个参数,表示如果没有相应的记录,则插入一条新的记录&#xA;        UserBean user = (UserBean) MapperUtil.fromDBObject(UserBean.class, dbObject);&#xA;        request.getSession().setAttribute(&amp;quot;me&amp;quot;, user);&#xA;        return &amp;quot;Login success!&amp;quot;;&#xA;    }&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;findAndModify是个好东西,呵呵&lt;/p&gt;&#xA;&#xA;&lt;p&gt;最后,mark一下Mongodb手册的下载地址: &lt;a href=&#34;http://dl.mongodb.org/dl/docs/&#34;&gt;http://dl.mongodb.org/dl/docs/&lt;/a&gt;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Viv -- 基于Nutz和BuguMongo的,使用Mongodb作为持久层的Issue管理系统</title>
      <link>http://wendal.net/360.html</link>
      <pubDate>2012-01-21 03:44:09 +0800</pubDate>
      <description>&lt;p&gt;项目地址: &lt;a href=&#34;https://github.com/wendal/viv&#34;&gt;https://github.com/wendal/viv&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;项目的核心思想,是基于Issue的Tag而非Issue的Status, 由zozoh提出来,我只是扩展并按照自己的项目设计了一套,跟github的issue系统类似.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;终于赶在春节前,把主要功能点完成了(页面还没做,看看谁愿意帮忙弄一个,前后台通信用ajax/json)&#xA;用户登录,新增issue,上传附件,添加comments &amp;hellip; &amp;hellip;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;BuguMongo 项目主页&lt;/strong&gt; &lt;a href=&#34;http://code.google.com/p/bugumongo/&#34;&gt;http://code.google.com/p/bugumongo/&lt;/a&gt;&#xA;国产的小框架,自称&amp;rdquo;BuguMongo已在多个正式商业项目中使用，并取得了理想的效果。&amp;rdquo;.我的使用感受是, 总体不错,但还很不成熟.&#xA;1. 代码中的瑕疵还是比较明显的,我个人比较在意的是出错时不打印堆栈,严重错误时也不抛出异常&amp;hellip;&#xA;2. 文档还不够齐备,JavaDoc缺失严重&lt;/p&gt;&#xA;&#xA;&lt;p&gt;这代表着,作者自己用得非常爽,但社区的人会碰很多很多的钉子&amp;hellip; 我对某些错误真是无语+无语&#xA;作为国内少有的mongodb框架,很希望它能持续发展下去.虽说Nutz的社区还不成熟,但发现BuguMongo的社区差不多等于0,基本上死寂 &amp;hellip; 跟当年nutz刚发布的时候差不多. 看来Nutz社区与BuguMongo的社区做一些交流还是很有必要的,呵呵&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;回想自己参与开源事业这好几年,发现很多开源项目都需要突破一些坎:&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;1. 勇敢发布,并产生第一个使用者&lt;/strong&gt;&#xA;&amp;gt;&amp;gt; 很多人想,这不是很容易吗? 看上去是的,但只需要到googlecode/github逛逛,你就能发现,很多项目连一个版本都没发布过,就消亡了&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;2. 收到第一个有用的Bug/Issue报告&lt;/strong&gt;&#xA;&amp;gt;&amp;gt; 有用户使用才能产生bug/issue报告,才能发现一些你没有考虑到的情况. 真正发起一个项目并得到第一个bug/issue报告,对很多开源项目来说,那是消亡之前都等不到的&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;3. 开立社区(论坛,QQ群,等一切交流工具,并维持一定的人气)&lt;/strong&gt;&#xA;&amp;gt;&amp;gt; 维持一个论坛比一个QQ群累,但效果会比QQ群好,在我看来,论坛属于知识积累的一部分,持久化的, 而QQ是过程式,临时交流的结果.可惜nutz的论坛至今发展不起来,QQ群倒是非常热闹&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;4. 找到第一个共同开发者&lt;/strong&gt;&#xA;&amp;gt;&amp;gt; 我已经深深感觉到找一个共同开发者对一个开源项目有多重要. 思想的碰撞,具体实现的差异,协助开发,等等,都非常有利于项目的延续.我自己也发起过,参与过不少的开源项目,很多很多,慢慢就变成个人项目,随之慢慢死去&lt;/p&gt;&#xA;&#xA;&lt;p&gt;各位,春节了哦,快回家吃饭吧@@@!!&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Nutz 1.b.41 发行后记</title>
      <link>http://wendal.net/359.html</link>
      <pubDate>2012-01-20 04:41:18 +0800</pubDate>
      <description>&lt;p&gt;经过3个月的长跑, nutz 1.b.41终于发布了.这里所说的,与release note并不冲突.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;我个人要提一下Mvc的一个新功能, Mvcs.getReq()等方法:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;    /*获取当前HttpServletRequest对象*/&#xA;    public static final HttpServletRequest getReq() {&#xA;        return REQ.get();&#xA;    }&#xA;&#xA;    /*获取当前HttpServletResponse对象*/&#xA;    public static final HttpServletResponse getResp() {&#xA;        return RESP.get();&#xA;    }&#xA;&#xA;    public static final String getName() {&#xA;        return NAME.get();&#xA;    }&#xA;&#xA;    /*获取当前Action上下文*/&#xA;    public static final ActionContext getActionContext() {&#xA;        return ACTION_CONTEXT.get();&#xA;    }&#xA;&#xA;    /*获取ServletContext*/&#xA;    public static ServletContext getServletContext() {&#xA;        return servletContext;&#xA;    }&#xA;&#xA;    public static IocContext getIocContext() {&#xA;        return IOC_CONTEXT.get();&#xA;    }&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;以上新增的API,既是对用户需求的响应,也代表一种妥协.&#xA;用户可以在任意代码中直接获取当前Req和Resp,而不再需要自行写Filter.但是,从代码的美观程度说,是一大让步,我自己看着都感觉有点不爽.&#xA;这个修改,顺带了另外一个功能,就是声明多个NutFilter并使用不同的配置. 之前的实现,最后一个Filter的设置,会覆盖之前所有配置.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;值得一提的,还有酝酿中的Nutz基金会,看看2月底之前,能否完成创建.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Nutz的发布,少不了打包,签名,上传,release等繁琐的操作, 貌似我每次都忘记咋签名,所以呢,写了个小脚本&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;export VER=&amp;quot;nutz-1.b.41&amp;quot;&#xA;gpg --armor --detach-sign $VER&amp;quot;-javadoc.jar&amp;quot;&#xA;gpg --armor --detach-sign $VER&amp;quot;.jar&amp;quot;&#xA;gpg --armor --detach-sign $VER&amp;quot;-sources.jar&amp;quot;&#xA;gpg --armor --detach-sign $VER&amp;quot;.pom&amp;quot;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;还有一个小事情,就是svn,为了尝试1.7.2版的svn,在Ubuntu上编译了新版,却无法使用,十分纠结!!&#xA;然而,本地安装乌龟,然后checkout,竟然飞快!!难以置信啊,2分钟完成!! 新版的svn,的确已经改进为单个.svn文件夹,清爽了很多,但我想说一句: 晚了,svn,你改进的速度太慢了!!&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>香港两天,离开天朝的2天!!</title>
      <link>http://wendal.net/357.html</link>
      <pubDate>2012-01-15 09:53:44 +0800</pubDate>
      <description>&lt;p&gt;上周,请了2天假,到香港逗留了2天,离开天朝的感觉还是不错的&lt;/p&gt;&#xA;&#xA;&lt;p&gt;好久好久没在香港住了,起码5年.这次跟老婆女儿一起住一间小酒店,非常郁闷&amp;hellip; 没住过这么小的房间,比我自己办公的小书房还小!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;这趟香港之行,收获还是不少的&#xA;离开主干道,进入市井中游荡 &amp;ndash; 跟我去过的大小城市一样,转个弯,过条巷子,就是另外一个天地&#xA;                      &amp;ndash; 8块钱的车仔面,鸣鸣吃得不亦乐乎&#xA;                      &amp;ndash; 6块钱的糖葱饼,很有意思的街边无证小摊档&#xA;                      &amp;ndash; 一群悠闲自在的中巴(红色公共小巴)司机,抽着烟,聚在一起大声交谈&#xA;                      &amp;ndash; 市井中的菜市场,跟大陆的菜市场没啥两样,除了地板比较干净之外&lt;/p&gt;&#xA;&#xA;&lt;p&gt;我依然很欣赏香港的交通,地铁,班次不算太密集,但非常高效&#xA;                      &amp;ndash; 2条线路并行2~3个站,供用户换成,分别对应两个方向的列车&#xA;                      &amp;ndash; 乘客下车后,直接走到对面就是你需要转的列车,班次一一对应,基本上做到无人滞留&#xA;                      &amp;ndash; 使用站前变轨,起点和终点是同一个地方,只有一条铁道&lt;/p&gt;&#xA;&#xA;&lt;p&gt;香港并非不夜城,9点开始,很多店铺就开始关门了,超过11点,主干道的店铺就没几家还在营业了.小巷子倒不是,某些店铺(如车仔面)却开始营业了,不时有人光顾. 12点之后就不知道了,呵呵,俺睡觉去了&lt;/p&gt;&#xA;&#xA;&lt;p&gt;我发现一个很有趣的东西,就是平时所说的&amp;rdquo;牛皮癣&amp;rdquo;式的小广告,在香港也非常非常常见,而且是入夜之后!!雨后春笋一样冒出来,难道是警察都下班了,没人管?? 很多还是比较Sex的呢,最好玩的是,我单独下楼买东西的时候,转过一个弯,看到几个哥们在很努力地贴海报,心想,真勤奋啊!! 于是凑过去一看,我X,&amp;ldquo;援交日记&amp;rdquo;的舞台剧(好象是),有个哥们还愣一下(我穿着黑衣黑裤黑鞋,还挎个黑包) &amp;hellip; 看了我几眼,然后我就走开了&amp;hellip; 等我买完回来,发现那一幅墙满满地贴满了,效率真高啊!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;去香港,最烦的就是过关,人多的时候等N久,所以呢,没办法,拿钱消灾呗,买了&amp;rdquo;广九直通车&amp;rdquo;,车程2个小时,过关5分钟搞定,155元/趟&lt;/p&gt;&#xA;&#xA;&lt;p&gt;香港,还是很不错的,呵呵&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>NutDao配置多数据源</title>
      <link>http://wendal.net/356.html</link>
      <pubDate>2012-01-06 10:20:11 +0800</pubDate>
      <description>&lt;p&gt;首先,我必须声明,这是一个非常简单的方法,很多小菜没做出来,是因为把nutz想得太复杂&lt;/p&gt;&#xA;&#xA;&lt;p&gt;数据源(或者是数据库连接池),在Nutz.Ioc看来,是一个普通的Bean,没任何特别之处. 再强调一点,除了$aop命名的bean用于配置Aop之外,其他所有的bean都是一视同仁的,没有任何特别关照!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;先看看标准的单数据源配置方法:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;var ioc = {&#xA;    dataSource : {&#xA;                type : &amp;quot;org.apache.commons.dbcp.BasicDataSource&amp;quot;,&#xA;                events : {&#xA;                        depose : &#39;close&#39;&#xA;                },&#xA;                fields : {&#xA;                        driverClassName : &#39;org.h2.Driver&#39;,&#xA;                        url : &#39;jdbc:h2:quick3;AUTO_RECONNECT=TRUE;CACHE_SIZE=65536&#39;,&#xA;                        username : &#39;sa&#39;,&#xA;                        password : &#39;&#39;&#xA;                }&#xA;        },&#xA;        /*定义NutDao*/&#xA;        dao : {&#xA;            type : &amp;quot;org.nutz.dao.impl.NutDao&amp;quot;,&#xA;            fields : {&#xA;                dataSource : {refer : &#39;dataSource&#39;}&#xA;            }&#xA;        }&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;然后,扩展成多个数据源:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;var ioc = {&#xA;/*定义第一个数据源*/&#xA;    dataSource : {&#xA;                type : &amp;quot;org.apache.commons.dbcp.BasicDataSource&amp;quot;,&#xA;                events : {&#xA;                        depose : &#39;close&#39;&#xA;                },&#xA;                fields : {&#xA;                        driverClassName : &#39;org.h2.Driver&#39;,&#xA;                        url : &#39;jdbc:h2:quick_a;AUTO_RECONNECT=TRUE;CACHE_SIZE=65536&#39;,&#xA;                        username : &#39;sa&#39;,&#xA;                        password : &#39;&#39;&#xA;                }&#xA;        },&#xA;        /*定义NutDao*/&#xA;        dao : {&#xA;            type : &amp;quot;org.nutz.dao.impl.NutDao&amp;quot;,&#xA;            fields : {&#xA;                dataSource : {refer : &#39;dataSource&#39;}&#xA;            }&#xA;        },&#xA;/*定义第二个数据源*/&#xA;    dataSource2 : {&#xA;                type : &amp;quot;org.apache.commons.dbcp.BasicDataSource&amp;quot;,&#xA;                events : {&#xA;                        depose : &#39;close&#39;&#xA;                },&#xA;                fields : {&#xA;                        driverClassName : &#39;org.h2.Driver&#39;,&#xA;                        url : &#39;jdbc:h2:quick_b;AUTO_RECONNECT=TRUE;CACHE_SIZE=65536&#39;,&#xA;                        username : &#39;sa&#39;,&#xA;                        password : &#39;&#39;&#xA;                }&#xA;        },&#xA;        /*定义第二个NutDao*/&#xA;        dao2 : {&#xA;            type : &amp;quot;org.nutz.dao.impl.NutDao&amp;quot;,&#xA;            fields : {&#xA;                dataSource : {refer : &#39;dataSource2&#39;} /*这里引用第二个数据源*/&#xA;            }&#xA;        }&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;明白了吗? 所谓多数据源的配置,其实就是几份单数据源的配置文件放在一起. 一个NutDao实例,对于一个数据源. 由于ioc里面的bean是不能重名的,所以,你需要做的,仅仅是为不同的数据源设定不同的名字,仅此而已.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;关于多数据源的事务管理问题,请看另外一篇博客: &amp;ldquo;&lt;a href=&#34;http://wendal.net/324.html&#34;&gt;Nutz事务模板值得注意的细节&lt;/a&gt;&amp;ldquo;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Java/Python/Lua/Lisp的胡思乱想</title>
      <link>http://wendal.net/355.html</link>
      <pubDate>2012-01-05 12:52:55 +0800</pubDate>
      <description>&lt;p&gt;本已入睡,但脑海中不停翻滚几个编程语言的好坏,于是爬起来写博了&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Java &amp;ndash; 我接触时间最长,自认最拿手的&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Java的语法非常精辟,但相对于当前流行的动态语言又显得非常糟糕. Java发展了这么多年,一直保持非常好的兼容性和持续改进,以前是Sun这个善意的独裁者,现在是邪恶的Oracle.&#xA;  有很长一段时间,我一直认为跨平台是Java最大的优势,直至最近,我的想法改变为: Java跨平台承诺,是各种第三方类库繁荣发展的根本源泉;苛刻的静态类型检查,令人厌恶的声明式异常机制,恰恰成就了Eclipse之类的强大IDE,因为在Java中,方法的调用是可预知的,可控的,可推导的;多年发展的JVM,在我看来,依旧是顶级的虚拟机实现;神奇的Java语言,其GC机制是精益求精,大家都在骂gc,但大家都在使用.&#xA;  当年我爱上Java,是因为这种语言能表达任何我想实现的东西,为此我把多少想法动手敲了下来. 我是这样描述的: 如果一件事手工完成需要1个小时,而编写一个Java程序来完成,编码需要59分钟,运行1分钟,那我必然选后者.&#xA;  现在基本上是,东西拿到手,立马出Java实现的思路,然后考虑用Java来做是否合适&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Python &amp;ndash; 与操作系统交互可以很美妙&lt;/p&gt;&#xA;&#xA;&lt;p&gt;我喜欢Python,但它不够好&#xA;  Python语法很优美,写出来比Java好看.但,文档太烂,类库太乱!! 虚拟机(python解析器)太慢!! 没有一款足够好用的IDE,因为在我看来IDE是提高生产效率的关键因素之一. Python总体设计还是不错的,就是有些细节非常反人类,例如import和变量作用域问题,无数次踩坑!!&#xA;  Python访问操作系统提供的东西实在方便,比Java节省80%以上的代码,但还是那句,文档太烂,不到抛错的时候,就根本没想到某某方法竟然能抛出异常!!&#xA;  真不明白为何Python不改进一下虚拟机的性能呢?!! 现在连js都有V8引擎了!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Lua &amp;ndash; 简约,而不简单&lt;/p&gt;&#xA;&#xA;&lt;p&gt;这种语言简直就是1天学完语法,1天看完API,开工干活的级别. &amp;ndash; 呵呵,有点夸张了&#xA;  整个语言,就1w行左右,源码仅那么几百k,实在让我惊叹. 这种语言还是很不错的,&amp;ldquo;只做一件事,做好一件事&amp;rdquo;,就是做最好的嵌入式语言.&#xA;  突然很期待有一本Lua源码剖析,呵呵,看看这语言是如何实现出来的&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Lisp &amp;ndash; this is another world&lt;/p&gt;&#xA;&#xA;&lt;p&gt;没错,那是另外一个世界.这个语言给我最直接的觉悟是,我所编写的任意代码,其实就是对语言的扩展,例如nutz,其实就是JDK的一个超集.&#xA;  Lisp的精髓,就存在于宏,变量,函数 3种基本元素中&#xA;  真正被执行的Lisp代码,只有变量和函数,而最精妙的宏,是用于改写源码的.&#xA;    包含宏的代码&amp;ndash;&amp;gt;展开宏&amp;ndash;&amp;gt;变量+函数&#xA;  宏,所接受的input就是源码本身,输出结果同样是源码. 实际上就是2种源码,一种是你定义的包含宏的Lisp源码,一种是只含有变量和函数的Lisp源码.&#xA;  有意思的是,宏实际上能够在被执行前才展开,运行时也能动态创建/修改宏/添加宏,这样就创建出无限的可能性 &amp;ndash; 这是一个很美妙的过程,绕过这个弯,就有很奇妙的想法,呵呵&lt;/p&gt;&#xA;&#xA;&lt;p&gt;恩,一点了,该睡觉了&amp;hellip;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>新年了,开始写论文了~_~</title>
      <link>http://wendal.net/353.html</link>
      <pubDate>2012-01-04 12:45:48 +0800</pubDate>
      <description>&lt;p&gt;拖了一年了,老婆也发话了&amp;hellip; 看来是时候认认真真把论文搞定了&lt;/p&gt;&#xA;&#xA;&lt;p&gt;文档啥的,一直都不是强项,宁愿写100行代码也想不出10行文档的我,要写出一份几十页的论文,真是情何以堪啊&amp;hellip;&lt;/p&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;文档格式&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;p&gt;说明一下,我这里说的不是文档的排版,而是文档的存储格式&lt;/p&gt;&#xA;&#xA;&lt;p&gt;最初的想法,当然是传统的Work文档,直观易用,但,这玩意真不适合程序员使用,尤其是没有版本管理,转换成其他格式也非常不便&#xA;昨晚学了一下传说中的Latex,这玩意强大得很,简直不是人用的&amp;hellip;. 一眼看上去,都不知道最终文档长啥样&lt;/p&gt;&#xA;&#xA;&lt;p&gt;所以呢,我决定尝试一把,用zDoc或者Markdown来写.现在主要是倾向于zDoc(即nutzdoc),理由很简单,自己参与的项目,如果有bug也立马修正.&#xA;但保险起见,实现zDoc&amp;ndash;&amp;gt;MarkDown转换器也立马提上日程,这个需求最初是nutz迁移到github时提出的,后来发现github的wiki的不如google code做得好,这个需求也就沉寂下去了&lt;/p&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;文档管理&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;p&gt;既然文档是zdoc格式,那么,版本管理和持续集成也就不成问题咯&#xA;Git &amp;ndash; 版本控制,话说我已经爱上这玩意,svn已经N久没有使用过&#xA;Hudson &amp;ndash; 不知道什么原因,我一直喜欢用这个进行持续集成,我也用过其他的啊,咋就还钟情于hudson呢&lt;/p&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;进度管理&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;p&gt;我想,写个论文,跟一个小小的项目应该也差不多了吧?&#xA;Google calendar &amp;ndash; 作为资深G粉,简单而实用的Google日历当然是首选.Google日历的主要用途就是记录进度,毕竟我现在能预知的,仅有一个时间点是钉死了的,不可能延期或修改的,那就是论文的截稿时间~_~&lt;/p&gt;&#xA;&#xA;&lt;p&gt;好吧,写开题报告去~_~&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Python: 为对象动态添加函数,且函数定义来自一个str</title>
      <link>http://wendal.net/351.html</link>
      <pubDate>2011-12-03 08:24:42 +0800</pubDate>
      <description>&lt;p&gt;在Python中,通常情况下,你只能为对象添加一个已经写好的方法&lt;/p&gt;&#xA;&#xA;&lt;p&gt;需求:传入一个str类型的变量,其值是一个完整的合法的Python函数定义,然后为一个对象添加这个函数:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;method_str = u&#39;&#39;&#39;&#xA;def say(self, name)&#xA;    print &#39;My name is&#39;, name&#xA;&#39;&#39;&#39;&#xA;class MyClass :&#xA;&#xA;    def __init__(self) :&#xA;        pass&#xA;&#xA;    def extends(self, method_name, method_str) :&#xA;        #完成这个方法...&#xA;&#xA;obj = MyClass();&#xA;obj.extends(&#39;say&#39;, method_str)&#xA;obj.say(&#39;wendal&#39;) #打印出My name is wendal&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;想了不少路子,在Python的QQ群里面也得到不少灵感,最后顺利实现:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;    def extends(sefl, method_name, method_str) :&#xA;        #_method = None&#xA;        exec method_str + &#39;&#39;&#39;\n_method = %s&#39;&#39;&#39; % method_name&#xA;        self.__dict__[method_name] = new.instancemethod(_method, self, None)&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;简单解释一下:&#xA;method_str在exec前,改变为:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;method_str = u&#39;&#39;&#39;&#xA;def say(self, name)&#xA;    print &#39;My name is&#39;, name&#xA;_method = abc&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;然后, exec执行后,_method变量就赋值为say函数&#xA;接下来,就是Python的自省机制了,通过new模块,生成特定对象(本例中是self)的实例方法&#xA;最后,为特定对象添加say这个函数&lt;/p&gt;&#xA;&#xA;&lt;p&gt;恩,这例子,就足以体现出Python在这方面的扩展性&#xA;1. method_str是一个字符串,可以动态创建,例如用户输出,模板生成&#xA;2. 方法的名字可以通过字符串分割等方法获取到&lt;/p&gt;&#xA;&#xA;&lt;p&gt;昨晚完成这个实现之后,足足兴奋了一个小时,哈哈 &amp;ndash; 2行代码就搞定!!&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>编译RK2918源码 -- 简单说明</title>
      <link>http://wendal.net/350.html</link>
      <pubDate>2011-11-18 01:23:23 +0800</pubDate>
      <description>&lt;p&gt;自从公布RK29的源码地址,各种模块都成为可能&lt;/p&gt;&#xA;&#xA;&lt;p&gt;我也说说如何编译吧, 环境 Ubuntu 10.10 server x86版&lt;/p&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&lt;p&gt;第一步当然是下载源码并解压啦, 以andy pad的源码为例&lt;/p&gt;&#xA;&#xA;&lt;p&gt;cd ~/&#xA;mkdir android&#xA;cd ~/android&#xA;wget &lt;a href=&#34;https://bitbucket.org/paulobrien/android_kernel_andypad/get/4c6b4f4c48d1.zip&#34;&gt;https://bitbucket.org/paulobrien/android_kernel_andypad/get/4c6b4f4c48d1.zip&lt;/a&gt;&#xA;unzip 4c6b4f4c48d1.zip&#xA;mv paulobrien-android_kernel_andypad-4c6b4f4c48d1/ rk29&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;安装依赖包&lt;/p&gt;&#xA;&#xA;&lt;p&gt;sudo apt-get install lzop sharutils libncurses5-dev vim&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;下载交叉编译器(我个人认为是错误翻译,应该叫跨平台编译器) arm 4.4.0&lt;/p&gt;&#xA;&#xA;&lt;p&gt;cd ~/android&#xA;wget &lt;a href=&#34;http://dl.google.com/android/ndk/android-ndk-r4b-linux-x86.zip&#34;&gt;http://dl.google.com/android/ndk/android-ndk-r4b-linux-x86.zip&lt;/a&gt;&#xA;unzip android-ndk-r4b-linux-x86.zip&#xA;mkdir toolchain&#xA;cp -r android-ndk-r4b/build/prebuilt/linux-x86/* toolchain/&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;拷贝编译设置&lt;/p&gt;&#xA;&#xA;&lt;p&gt;cd ~/android&#xA;cd rk29&#xA;cp arch/arm/configs/rk29_ddr3sdk_defconfig .config&#xA;#提醒: configs文件夹下面有多个配置文件,具体差异不清楚&lt;/p&gt;&#xA;&#xA;&lt;p&gt;#尝试编译一下内核&#xA;make kernel&#xA;#如无意外,你应该看到几个关于配置的提示,要求你进行选择,直接回车选默认值即可,然后编译完成&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;完整编译一次&lt;/p&gt;&#xA;&#xA;&lt;p&gt;cd ~/android/rk29&#xA;#我本地解压出来的源码包,其中的drivers/usb/storage/debug.h会出错,所以需要自行下载一个&#xA;cd drivers/usb/storage&#xA;rm debug.h&#xA;wget &lt;a href=&#34;https://bitbucket.org/paulobrien/android_kernel_andypad/raw/4c6b4f4c48d1/drivers/usb/storage/debug.h&#34;&gt;https://bitbucket.org/paulobrien/android_kernel_andypad/raw/4c6b4f4c48d1/drivers/usb/storage/debug.h&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;cd ~/android/rk29&#xA;make&#xA;#一起顺利的话,恭喜你,成功了!!&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;编译具体的模块,以cifs.ko为例&lt;/p&gt;&#xA;&#xA;&lt;p&gt;#打开配置选项界面&#xA;make menuconfig&lt;/p&gt;&#xA;&#xA;&lt;p&gt;#File system &amp;ndash;&amp;gt; Network File system (按空格,让其启用) &amp;ndash;&amp;gt; CIFS support (按空格,直至变成M,即模块)&#xA;按Esc无数次,然后提示是否保存,选保存&lt;/p&gt;&#xA;&#xA;&lt;p&gt;#编译cifs模块&#xA;make M=fs/cifs&lt;/p&gt;&#xA;&#xA;&lt;p&gt;#应该会打印出 cifs.ko字样,查看一下&#xA;find -name &amp;ldquo;cifs.ko&amp;rdquo;&#xA;#你就应该看到编译好的cifs.ko模块&lt;/p&gt;&#xA;&#xA;&lt;p&gt;#提醒一句, CIFS模块,还需要slow-work.ko和nls_utf8.ko,都可以用类似的方法进行编译得到&lt;/p&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;hr /&gt;&#xA;&#xA;&lt;p&gt;反馈1 :&#xA;编译slow-work.ko,需要修改slow-work.c哦, 请查看 &lt;a href=&#34;http://forum.xda-developers.com/showthread.php?t=1113191&#34;&gt;http://forum.xda-developers.com/showthread.php?t=1113191&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;如果你遇到什么编译问题,欢迎留言交流哦&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Git的几个实用小技巧</title>
      <link>http://wendal.net/344.html</link>
      <pubDate>2011-11-14 10:51:50 +0800</pubDate>
      <description>&lt;p&gt;不止一次听到抱怨说, &lt;strong&gt;Git库好大&lt;/strong&gt;啊,把整个历史都拉下来,慢死了&#xA;我情何以堪呢?!! 你可以单单取最后几个,甚至最后一个版本的啊?&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;#仅获取最新版和一个历史版本,即最后2个版本&#xA;git clone git@github.com:nutzam/nutz --depth=1&#xA;&#xA;#看看下载了多少数据:&#xA;Cloning into nutz...&#xA;remote: Counting objects: 2928, done.&#xA;remote: Compressing objects: 100% (1956/1956), done.&#xA;remote: Total 2928 (delta 1212), reused 2179 (delta 831)&#xA;Receiving objects: 100% (2928/2928), 3.20 MiB | 1.06 MiB/s, done.&#xA;Resolving deltas: 100% (1212/1212), done.&#xA;&#xA;#仅3.2mb哦, 小很多了吧?&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;上面的git clone,&lt;strong&gt;仅获取了最后2个版本&lt;/strong&gt;,我是如何知道的呢?&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;cd nutz&#xA;git rev-list master&#xA;&#xA;#只有2个显示哦:&#xA;eeb43e7984e7376f09896a201f82ec9fb5936e21&#xA;e905483933c0f16c1c0820c8b1834dbcb5e0c06a&#xA;&#xA;#你也许也已经发现,最新版是最先显示的,rev比较多的时候有点不方便,那么:&#xA;git rev-list master --max-count=10&#xA;#上面的命令,一眼你就明白了&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;还是不信?好吧,看具体的log信息:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;git log --pretty=format:&#39;%h : %s&#39; --topo-order --graph&#xA;&#xA;#打印:&#xA;* eeb43e7 : fix issue #107&#xA;* e905483 : add log when load iocObject in ComboIocLoader&#xA;&#xA;#如果你做了一些tag,只希望获取某两个tag直接的log&#xA;git log --pretty=format:&#39;%h : %s&#39; --topo-order --graph Tag1..Tag2&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;默认情况下, git执行N次操作后,才会压缩空间,我一般心情好的时间就敲一下:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;#这个命令耗时是比较长的哦&#xA;git gc --aggressive&#xA;&#xA;#快速指令&#xA;git gc&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;好吧,我承认,很多内容都是从&amp;rdquo;&lt;a href=&#34;http://gitbook.liuhui998.com&#34;&gt;Git Community Book 中文版&lt;/a&gt;&amp;ldquo;学来的 &amp;ndash; 你会很神奇地发现,我竟然是翻译协作者之一,呵呵&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>一波三折的一个月,鸣鸣的腹泻终于好了,我也恢复元气了</title>
      <link>http://wendal.net/342.html</link>
      <pubDate>2011-11-13 10:04:57 +0800</pubDate>
      <description>&lt;p&gt;终于有心情,有闲情来写blog了&lt;/p&gt;&#xA;&#xA;&lt;p&gt;鸣鸣的腹泻,终于告一段落,我自己也渐渐恢复元气 .. 几个安乐觉,几瓶白兰氏鸡精&amp;hellip;. 最重要的,当然是鸣鸣玩耍的嬉笑声&lt;/p&gt;&#xA;&#xA;&lt;p&gt;这一次腹泻,可以算是鸣鸣出生以来的第一次生病, 揪心啊&amp;hellip;.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;起初,只是轻微的腹泻,水样, 鸣鸣也不哭,也不闹&#xA;渐渐地,腹泻的次数不断增加,最高峰时,1~2小时一次,鸣鸣的精神状态也开始不佳&#xA;恩,鸣鸣还是大哭了, 因为不断腹泻导致小屁股红肿,每次腹泻都让她很疼 &amp;ndash; 呜呜&amp;hellip;.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;首先是去了两次的区人民医院,第二次差点跟医生吵起来 &amp;ndash; 叫我怎么说呢,事情就是发生了&#xA;  由于我坚决反对吊针,那医生几乎发狂了,竟然向后推了一下鸣鸣的头,最后,打了一支屁股针,开了点冲剂&#xA;  第二天,直奔省妇幼保健院,二话没说,验大便 &amp;ndash; 肠炎+腺病毒感染, 接着一句: 还好,不严重 &amp;hellip; 没去打针,没去吊针,只开了一次中药肚脐贴,一瓶氧化锌,3颗庆大霉素(医生说不入血,没事). 贴好肚脐,喂了一次庆大霉素,帮她涂氧化锌到小屁股,然后就睡觉了. 中午补涂氧化锌的时候,竟然还亲了一下妈妈,露出点点笑容 &amp;ndash; hold不住啊&amp;hellip; 精神状态明显好转啊!! 当天, 腹泻次数明显减少了, 也不哭闹了 &amp;ndash; 我能不激动吗?!!&#xA;  之后几天,复诊了两次,最后一次显示无发炎 &amp;ndash; 俺是不是应该捐的钱给医院呢??&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Mark一下省妇幼的用药:&#xA;1. 庆大霉素3颗,实际吃了1.5颗,因为每次仅吃半颗&#xA;2. 3次肚脐贴,不知道什么成分&#xA;3. 钙/B12冲剂&#xA;4. 纽曼斯 &amp;ndash; 一种复合益生菌,在医院之外买的,挪威进口, 大概10元/颗,一瓶30颗,每天1~2次 &amp;ndash; 你觉得贵吗?病好了,啥都值!&#xA;5. 自己买了一些丁桂儿脐贴, 感觉不错&lt;/p&gt;&#xA;&#xA;&lt;p&gt;去区人民医院    药费&amp;gt;&amp;gt;检查费&#xA;去省妇幼保健院  检查费&amp;gt;&amp;gt;药费&lt;/p&gt;&#xA;&#xA;&lt;p&gt;我很不爽区人民医院的那位医生,其一是推鸣鸣的头,其二是不停强调之前哪个患儿怎么怎么样了 &amp;ndash; 吓唬我?觉得我的心不够乱?你到底想咋样呢?&#xA;省妇幼,也有不足的地方,检查费还真不少,值得一提的是过敏原检查,没见过鸣鸣哭得这么厉害(前一晚打屁股针的阴影?),那叫一个揪心啊,而且负责检查的护士态度很不好&lt;/p&gt;&#xA;&#xA;&lt;p&gt;恩,这次总算过去了,经过一个星期的调养,每天减少到1~3次,安心多了&lt;/p&gt;&#xA;&#xA;&lt;p&gt;还是比较纠结为什么会生病呢?可能的原因:&#xA;  1. 妈妈喝奶粉过多? 因为病之前一周,翻倍地喝&#xA;  2. 妈妈吃蛋白?? 难道是过敏所致?&#xA;  3. 喂猪肝?? 难道也过敏?&#xA;  4. 吹空调?? 说不清了&amp;hellip;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;这次,我还是没能清醒面对,以至于一直没想起来&amp;rdquo;丁桂儿脐贴&amp;rdquo;这类狗皮膏药 &amp;ndash; 急起来就乱啊,不够蛋定啊&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>RK2918 内核源码 -- 想不到吧?!</title>
      <link>http://wendal.net/339.html</link>
      <pubDate>2011-11-03 09:06:50 +0800</pubDate>
      <description>&lt;p&gt;想不到, 我竟然找到了, 这都要感谢一位外国友人的提示!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;还是那句, 对国人保密,对外国人公开 &amp;ndash; 不能太&amp;rdquo;云南白药&amp;rdquo;啊!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;下载地址:&#xA;&lt;a href=&#34;http://www.odys.de/downloads/software/odys_xpress_GPLSourceCode.zip&#34;&gt;http://www.odys.de/downloads/software/odys_xpress_GPLSourceCode.zip&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;包含:&#xA;busybox源码&#xA;e2fs源码&#xA;kernel源码 &amp;ndash; 当然,这才是最关键的&lt;/p&gt;&#xA;&#xA;&lt;p&gt;根据其日期,猜测是SDK 1.x的作品, 不过,一般来说,h文件都不会大改的,呵呵!!&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>推荐OpenResty -- Nginx全能插件版</title>
      <link>http://wendal.net/338.html</link>
      <pubDate>2011-10-20 10:39:40 +0800</pubDate>
      <description>&lt;p&gt;实在吐血,这是第二次写这个文章,刚才准备保存的时候操作失误,全没了&amp;hellip;.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;官网: &lt;a href=&#34;http://openresty.org/&#34;&gt;http://openresty.org/&lt;/a&gt;&#xA;虽然是中国人做的,但没几个汉字&amp;hellip;..&lt;/p&gt;&#xA;&#xA;&lt;p&gt;我用Nginx,是这样一个过程:&#xA;1. 系统rpm中的nginx,能让其跑起来&#xA;2. 玩配置文件&#xA;3. 玩编译选项&#xA;4. 写插件,集成第三方插件&lt;/p&gt;&#xA;&#xA;&lt;p&gt;OpenResty , 是淘宝一位大牛(agentzh)集成的包含N多好插件的Nginx捆绑源码包,这位仁兄自称Nginx最活跃的第三方模块开发人员哦&lt;/p&gt;&#xA;&#xA;&lt;p&gt;下面,当然要列一下到底集成了什么模块(已经根据agentzh的微博提醒进行修正):&lt;/p&gt;&#xA;&#xA;&lt;p&gt;LuaJIT &amp;ndash; 极速版Lua实现&#xA;ArrayVarNginxModule &amp;ndash; 数组类型的Nginx变量&#xA;AuthRequestNginxModule &amp;ndash; 鉴权,想象一下以C代码的速度判断一个请求是否合法,是不是很有快感呢?!&#xA;DrizzleNginxModule &amp;ndash; Nginx-MySQL桥,非阻塞的哦,我又爱又恨的一个模块,值得注意的是,其响应是RDS流&#xA;EchoNginxModule &amp;ndash; 以非常直观的方式在Nginx配置文件中编写简单的处理逻辑,源码包含大量注释,绝对是入门好例子!!&#xA;EncryptedSessionNginxModule &amp;ndash; 加密会话&#xA;FormInputNginxModule &amp;ndash; 解析post请求中的参数,这下子,简单请求根本不需要PHP/Java来处理啦&#xA;HeadersMoreNginxModule &amp;ndash; Nginx默认的header模块只能添加或忽略,这个给你CRUD全套的!!&#xA;IconvNginxModule &amp;ndash; 编码转换,不多说,也不懂&#xA;StandardLuaInterpreter &amp;ndash; 与Lua官方实现所匹配,一般用不上,因为我们用LuaJIT!!&#xA;MemcNginxModule &amp;ndash; 与Memcached的绝配,谁用谁知道!! 与upstram_keepalive一起用,你能更High!!&#xA;Nginx&#xA;NginxDevelKit &amp;ndash; N多第三方插件都依赖的东西,&lt;del&gt;不知道为啥&lt;/del&gt; 提供一些方便使用的基础API封装&#xA;LuaCjsonLibrary &amp;ndash; Lua版的Json处理库实在太慢,这个才叫速度!!&#xA;LuaNginxModule &amp;ndash; 我的最爱,一般逻辑,完全没必要用Java/PHP啦&#xA;LuaRdsParserLibrary &amp;ndash; 在Lua中直接处理RDS流,速度杠杠的!&#xA;LuaRedisParserLibrary &amp;ndash; 在Lua中处理Redia模块的响应,暂时我还没用上&#xA;PostgresNginxModule &amp;ndash; Nginx-Postgres桥,输出的也是RDS流&#xA;RdsCsvNginxModule &amp;ndash; RDS流转CVS格式,不知道能干啥,报表?&#xA;RdsJsonNginxModule &amp;ndash; RDS流转JSON字符串,之前经常用这个&#xA;Redis2NginxModule &amp;ndash; Nginx-Redis2桥&#xA;SetMiscNginxModule &amp;ndash; 提供很多很实用的方法,例如base64编解码,URL编解码,SQL防注入等等&#xA;SrcacheNginxModule &amp;ndash; 缓存模块,据说跟Memc模块一起用比较爽&#xA;UpstreamKeepaliveNginxModule &amp;ndash; 与Memc模块的标配,号称性能提升几倍呢&#xA;XssNginxModule &amp;ndash; &lt;del&gt;防跨站攻击的&lt;/del&gt; 通过Jsonp进行跨站ajax编程&lt;/p&gt;&#xA;&#xA;&lt;p&gt;OpenResty的最大的好处是帮你弄清楚各个模块的编译顺序,别小看,学问大大的呢&lt;/p&gt;&#xA;&#xA;&lt;p&gt;当初没有这东西,单单弄清楚模块间的编译顺序就耗费不少时间&lt;/p&gt;&#xA;&#xA;&lt;p&gt;来吧,试试这个国产的精品!!&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>捐点钱给自己喜欢的开源软件</title>
      <link>http://wendal.net/335.html</link>
      <pubDate>2011-10-18 09:17:54 +0800</pubDate>
      <description>&lt;p&gt;声明: 本文并非为Nutz募捐&lt;/p&gt;&#xA;&#xA;&lt;p&gt;昨晚,点了几次鼠标,填了信用卡资料,一笔微不足道的捐款送达Python基金会&lt;/p&gt;&#xA;&#xA;&lt;p&gt;回想那些捐款过的开源/免费软件,我的款项也许还不够作者买瓶红酒或者吃一顿KFC, 但我的确捐了,以表达我的感激之情,这难道不就够了吗?&lt;/p&gt;&#xA;&#xA;&lt;p&gt;感觉国内的开源/免费软件生存环境还是太差:&#xA;1. 第一次发布, 99.99%被骂山寨,没创意&amp;hellip;.&#xA;2. 免费的,就要求开源,开源的就骂质量差&#xA;3. 只知道索取,不会有所贡献 &amp;ndash; 拿到源码就跑,有bug也不报告,更别说捐款了&#xA;&amp;hellip;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;当然,大家的理由都很多,很充分,很现实:&#xA;1. 没钱&#xA;2. 技术不够&#xA;3. 没时间&#xA;&amp;hellip;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;捐10块钱,报个bug,发邮件咨询一下作者,帮助一下新手,写blog介绍一下经验,有这么难吗?&lt;/p&gt;&#xA;&#xA;&lt;p&gt;曾经(其实现在也想)为nutz建一个基金会,但在中国,这是不现实,不可行的. 你无法建立一个合法合理的民间基金会, 注册资金,审批,都是无法通过的,原因大家都懂.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;恩,牢骚完,继续走我的路,每个月挑点喜欢的软件,或是购买,或是捐款,呵呵&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Nut.Test -- 使用Nutz一样能方便地进行单元测试</title>
      <link>http://wendal.net/332.html</link>
      <pubDate>2011-10-16 10:22:36 +0800</pubDate>
      <description>&lt;p&gt;首先,感谢Jay提出一个需求.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;这个功能很有可能出现在1.b.40中&lt;/p&gt;&#xA;&#xA;&lt;p&gt;当前Nut.Test代码,主要解决以下几个问题:&#xA;1. 测试方法使用NutzDao操作数据库,希望在测试方法执行完成后进行回滚&#xA;2. Ioc支持,方便获取与实际生产环境类似的Ioc注入功能,方便进行功能测试&lt;/p&gt;&#xA;&#xA;&lt;p&gt;这个测试Runner, 很好地平衡了侵入性与灵活性, 让用户以很低的成本与耦合度测试Nutz代码&lt;/p&gt;&#xA;&#xA;&lt;p&gt;所以,我新建org.nutz.test包, 核心类NutzJUnit4ClassRunner,这个类本身非常简单&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;public class NutzJUnit4ClassRunner extends TestClassRunner {&#xA;    public NutzJUnit4ClassRunner(final Class klass) throws InitializationError {&#xA;        super(klass, new NutTestClassMethodsRunner(klass));&#xA;    }&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;核心代码位于NutTestClassMethodsRunner&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;public class NutTestClassMethodsRunner extends TestClassMethodsRunner {&#xA;&#xA;    //其他辅助方法,属性&#xA;&#xA;    protected void invokeTestMethod(final Method method, final RunNotifier notifier) {&#xA;        //处理事务回滚问题,判断当前方法是否需要自动回滚&#xA;        ... ...&#xA;        //检查Ioc支持,主要是判断当前类及父类是否标注了@IocBy&#xA;    ... ...&#xA;&#xA;    //具体执行&#xA;        //如果不需要自动回滚,那么,直接调用父类的方法,按原生步骤执行&#xA;&#xA;        //事务自动回滚的实现,就具体的执行过程,以事务模板包裹,并确保抛出异常&#xA;        try {&#xA;            Trans.exec(new Atom(){&#xA;                public void run() {&#xA;                    NutTestClassMethodsRunner.super.invokeTestMethod(method, notifier);&#xA;                    throw JustRollback.me();//这样,无论原方法是否跑异常,事务模板都能收到异常,并回滚&#xA;                }&#xA;            });&#xA;        } catch (JustRollback e) {}&#xA;    }&#xA;&#xA;    //如果包含Ioc支持,并且当前类是一个IocBean的话,就可以从Ioc中获取对象&#xA;    protected Object createTest() throws Exception {&#xA;        if (NutTestContext.me().ioc != null &amp;amp;&amp;amp; klass.getAnnotation(IocBean.class) != null)&#xA;            return NutTestContext.me().ioc.get(klass);&#xA;        return super.createTest();&#xA;    }&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;整个实现,共用到4个注解 @NutTest @IocBy @IocBean @Inject&#xA;这里的@IocBy的具体行为,与Mvc中的@IocBy有轻微不同,因为没有web上下文&#xA;@Aop,声明式Aop均可生效,效果与MVC中的效果一致&lt;/p&gt;&#xA;&#xA;&lt;p&gt;使用示例&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;@RunWith(value=NutzJUnit4ClassRunner.class)&#xA;@IocBy(type=ComboIocProvider.class,args={&amp;quot;*org.nutz.ioc.loader.json.JsonLoader&amp;quot;,&amp;quot;ioc/&amp;quot;,&#xA;      &amp;quot;*org.nutz.ioc.loader.annotation.AnnotationIocLoader&amp;quot;,&amp;quot;net.wendal&amp;quot;})&#xA;@IocBean&#xA;public class AuthServiceTest {&#xA;&#xA;    @Inject&#xA;    private AuthDao authDao;&#xA;&#xA;    public void setAuthDao(AuthDao authDao) {this.authDao = authDao;}&#xA;&#xA;    @Test&#xA;    public void test_login() {&#xA;        User user = authDao.fetch(&amp;quot;admin&amp;quot;,&amp;quot;wendal.net&amp;quot;)&#xA;        assertNotNull(user);&#xA;   }&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;局限性:&#xA;1. 不应该用于测试Action层&#xA;2. 自动回滚,必须注意隐式事务提交和多线程事务问题&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Enjoy it!!&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>在Linux下编译Qt Libs -- 能不能快点呢?!</title>
      <link>http://wendal.net/330.html</link>
      <pubDate>2011-10-01 08:37:57 +0800</pubDate>
      <description>&lt;p&gt;出于好玩,下载了Qt libs for linux, 发现是个源码包,好吧编译呗&lt;/p&gt;&#xA;&#xA;&lt;p&gt;敲入:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;./configure -qt-sql-sqlite&#xA;gmake&#xA;gmake install&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;原本以为半个小时就万事,结果花了2个多小时!! 我吐血啊&amp;hellip;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;难道就不能快点吗? demo examples docs 能不能编译啊!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;好吧,谷哥告诉我,能这样:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;./configure -qt-sql-sqlite -opensource -fast -no-qt3support -nomake demos -nomake docs -nomake examples -optimized-qmake -nomake tools&#xA;gmake -j4&#xA;gmake install&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;呵呵,半个小时搞定!!!&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>初试Jetty使用Mongodb作为Session管理器</title>
      <link>http://wendal.net/326.html</link>
      <pubDate>2011-09-26 11:03:32 +0800</pubDate>
      <description>&lt;p&gt;闲话少说,直接上代码:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;package net.wendal.jetty.mongodb;&#xA;&#xA;import org.eclipse.jetty.nosql.mongodb.MongoSessionIdManager;&#xA;import org.eclipse.jetty.nosql.mongodb.MongoSessionManager;&#xA;import org.eclipse.jetty.server.Server;&#xA;import org.eclipse.jetty.server.SessionManager;&#xA;import org.eclipse.jetty.server.session.SessionHandler;&#xA;import org.eclipse.jetty.webapp.WebAppContext;&#xA;&#xA;public abstract class TestMongodb4Jetty {&#xA;&#xA;    public static void main(String[] args) throws Throwable {&#xA;        Server server = new Server(9090);&#xA;        WebAppContext webAppContext = new WebAppContext();&#xA;        webAppContext.setWar(&amp;quot;E:\\NutzQuickStart.war&amp;quot;); //经典的nutz入门例子&#xA;        MongoSessionManager msm = new MongoSessionManager();&#xA;        SessionHandler sessionHandler = new SessionHandler();&#xA;        sessionHandler.setSessionManager(msm);&#xA;        webAppContext.setSessionHandler(sessionHandler);&#xA;        MongoSessionIdManager idMgr = new MongoSessionIdManager(server);&#xA;        idMgr.setWorkerName(&amp;quot;wendal-mongodb-worker&amp;quot;);&#xA;        idMgr.setScavengeDelay(60);&#xA;        msm.setSessionIdManager(idMgr);&#xA;        server.setHandler(webAppContext);&#xA;        server.start();&#xA;    }&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;启动mongod,启动jetty,访问登录页面,登录,看到后台的log&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;2011-09-26 23:12:37,470 MongoSessionManager:save:org.eclipse.jetty.nosql.NoSqlSession:wendal-mongodb-worker426chatn2460pobw6a4a6m14@1179468258&#xA;2011-09-26 23:12:37,473 MongoSessionManager:save:db.sessions.update({ &amp;quot;id&amp;quot; : &amp;quot;wendal-mongodb-worker426chatn2460pobw6a4a6m14&amp;quot; , &amp;quot;valid&amp;quot; : true},{ &amp;quot;$inc&amp;quot; : { &amp;quot;context.::*.__metadata__.version&amp;quot; : 1} , &amp;quot;$set&amp;quot; : { &amp;quot;accessed&amp;quot; : 1317049954912 , &amp;quot;context.::*.org%2Enutz%2Equickstart%2Eauth%2Ebean%2EUser&amp;quot; : &amp;lt;Binary Data&amp;gt;}},true)&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;可以看到,默认情况下,使用的是标准的Java序列化,效率当然是不太高的了,呵呵&lt;/p&gt;&#xA;&#xA;&lt;p&gt;打开mongodb控制台,敲入下面的命令,也能看到登录后的session信息&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;use HttpSessions&#xA;db.sessions.find()&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;So esay!! 不过,也用掉了我2个小时,呵呵!!&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>不走寻常路--NutzCP初版</title>
      <link>http://wendal.net/325.html</link>
      <pubDate>2011-09-18 02:41:17 +0800</pubDate>
      <description>&lt;p&gt;想了一个晚上,用了一个早上完成编码 &amp;ndash; 效率还是很高的嘛&lt;/p&gt;&#xA;&#xA;&lt;p&gt;项目地址: &lt;a href=&#34;https://github.com/nutzam/nutzcp&#34;&gt;https://github.com/nutzam/nutzcp&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;很久之前,我也写过另外一个&lt;a href=&#34;http://wendal.net/243.html&#34;&gt;简单的连接池实现&lt;/a&gt;,这次我认真地实现了另一个实现,也就是现在这个&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;这个连接池,基于一些假设:&lt;/strong&gt;&#xA;1. 数据库可接纳的总连接数是固定的&#xA;2. 使用者是自律的,总是显式调用commit()/rollback(),然后调用close()&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;不走寻常路:&lt;/strong&gt;&#xA;1. 固定的连接池大小&#xA;2. 超过固定连接数后,不允许再创建新连接,除非旧连接被返还&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;为何要固定的连接池大小呢?!&lt;/strong&gt;&#xA;以MySQL为例,server端可接纳的连接数是固件的,写在配置文件里面的,就是说,实际上server-client之间的可用连接数总数是稳定的,固定的,所以,维持一个固定大小的连接池比维持一个可变大小的连接池要简洁,更快,其实也更实用&lt;/p&gt;&#xA;&#xA;&lt;p&gt;**为什么不允许overflow(连接池里面已经没有空余连接,那就创建不受管理的连接)呢? **&#xA;因为不应该由数据库告诉程序: 我是MySQL数据库服务器,我已经没有可用的新连接啦!!&#xA;客户端本身就能知道是否已经无法创建新连接,这样直接抛出异常,比服务器告知要快速得多&lt;/p&gt;&#xA;&#xA;&lt;p&gt;现在这个实现还是使用synchronized,但效率还是很不错的,使用这个实现,通过Nutz项目的TestAll完全没鸭梨!! 呵呵,心情好的时候再改为JDK5的lock吧&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;Be fun !!&lt;/strong&gt;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Nutz事务模板值得注意的细节</title>
      <link>http://wendal.net/324.html</link>
      <pubDate>2011-09-17 10:31:36 +0800</pubDate>
      <description>&lt;p&gt;Nutz.Dao事务模板的官方文档: &lt;a href=&#34;http://code.google.com/p/nutz/wiki/dao_transaction&#34;&gt;http://code.google.com/p/nutz/wiki/dao_transaction&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;需要注意的几个细节,文档还没提及:&#xA;&lt;strong&gt;1. 数据库连接池的AutoCommit属性&lt;/strong&gt;&#xA;对于我见到的大部分连接池和数据库驱动,默认情况下AutoCommit=true,应该是为了性能&#xA;这就导致如果用户不自行设置的话,Trans的大部分操作都是不可回滚的.故,如果使用Trans,那么务必设置AutoCommit&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;2. 多个数据源的事务&lt;/strong&gt;&#xA;大部分情况下,用户都不是使用XA驱动,故,多数据源的事务提交,在最后的提交阶段出错的话,已经执行commit操作的数据源,是不可能回滚的&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;3. 子线程的事务&lt;/strong&gt;&#xA;考虑下面的代码:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;Trans.exec(new Atom(){&#xA;   public void run() {&#xA;       dao.insert(pet);&#xA;       new MySuperPowerThread().start();&#xA;       dao.count(Pet.class);&#xA;   }&#xA;});&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;那么MySuperPowerThread的代码并不是在事务模板中执行的,因为这里的事务不会被子线程继承&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;4. 返回值问题(更新了)&lt;/strong&gt;&#xA;使用Molecule&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;Molecule&amp;lt;object&amp;gt; mc = new Molecule&amp;lt;object&amp;gt;() {&#xA;    public void run() {&#xA;        dao.insert(pet);&#xA;        setObj(dao.count(Pet.class));&#xA;    }&#xA;};&#xA;Trans.exec(mc);&#xA;System.out.println(mc.getObj());&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;</description>
    </item>
    <item>
      <title>让你的Android彻底裸奔吧!! -- 瘫痪Android的安全机制</title>
      <link>http://wendal.net/321.html</link>
      <pubDate>2011-09-11 08:51:23 +0800</pubDate>
      <description>&lt;p&gt;本文并非教你写病毒来破解Android系统,所提及的操作,均要求用户主动参与&lt;/p&gt;&#xA;&#xA;&lt;p&gt;本文主要针对是平板.Andoird手机由于涉及你的帐号/资金的安全,非常不建议你使用下面的方法!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;先感谢一下硬件小二,rk28小组的协助&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;第一步,/system可写&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&#34;http://wendal.net/320.html&#34;&gt;Rk2918现在可使用我不久前发明的方法,将/system映射在/data/sysrw&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Rk2818的话,自然是使用aufs这种xda发明的方法,但使用rk2918的方法会快些&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;第二步,获取root权限&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;因为是完全击垮,故需要使用完全自由的su程序,改造自Superuser的su源码&amp;ndash; &lt;a href=&#34;https://github.com/wendal/android_su&#34;&gt;无限制无管理功能的su&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;这里提供的su,去掉了GUI确认等繁琐操作,任何程序都可以无提示获取root权限&lt;/p&gt;&#xA;&#xA;&lt;p&gt;自行添加的话,请确保所在分区支持suid,并设置su的权限为6777&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;第三步,移除apk的签名验证机制&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;在此之前,尝试美化系统界面的童鞋都知道,系统apk千万千万不要签名,否则肯定用不了&lt;/p&gt;&#xA;&#xA;&lt;p&gt;对此我就不信邪,偏偏要破解掉这个限制,实现任意签名的apk,都能安装,完全跳过签名验证机制!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;方法如下:&lt;/p&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;下载apktool,并安装好JRE或JDK,把apktool解压到D:\apktool&lt;/li&gt;&#xA;&lt;li&gt;在机器上拷贝/system/framework/services.jar到硬盘的D:\apktool\services.apk&lt;/li&gt;&#xA;&lt;li&gt;进入命令行,进入D:\apktool,执行 apktool.bat d services.apk ,稍等片刻,就能能看到新建的services文件夹&lt;/li&gt;&#xA;&lt;li&gt;用UE或notepad++打开D:\apktool\services\smali\com\android\server\PackageManagerService.smali&lt;/li&gt;&#xA;&lt;li&gt;查找private verifySignaturesLP,这就是校验签名的方法&lt;/li&gt;&#xA;&lt;li&gt;在verifySignaturesLP方法体中,找到:goto_0,在后面加一行 const/4 v0, 0x1        ,含义是赋值为true,以Java来表达,就是return true,这是verifySignaturesLP方法的最终return语句之前的一句,故任何调用本方法的语句,都能拿到true,即签名验证永远为真. 注意,这里的0x1中的x是小写字母X,貌似很多人直接拷贝的话,会变成全角的X.如果你没有找到goto_0,那就找return v0之类的语句.一般都只有一个return语句!!&lt;/li&gt;&#xA;&lt;li&gt;保存,重新打包: apktool.bat b services services.jar ,然后拷贝回机器,重启就可以了&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;h2&gt;完成以上步骤,你的Android设备就彻底裸奔了&lt;/h2&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;System可写 &amp;ndash; 为任意改系统文件创造条件&lt;/li&gt;&#xA;&lt;li&gt;无限制的su &amp;ndash; 任何程序都能悄无声息地获取root权限,加上上一条的System可写,即任何程序都能修改/system&lt;/li&gt;&#xA;&lt;li&gt;不再有签名验证 &amp;ndash; 任何apk程序都可以声明自己是系统程序,甚至可以动态生成apk程序进行安装(随便签名就行!!)&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;h1&gt;从此,你的Android设备完全不设防了!!&lt;/h1&gt;&#xA;</description>
    </item>
    <item>
      <title>实现Rk2918的System分区可写</title>
      <link>http://wendal.net/320.html</link>
      <pubDate>2011-09-09 11:33:27 +0800</pubDate>
      <description>&lt;p&gt;这是2011-09-08,也就是前天顿悟出来的方法&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;核心原理&lt;/strong&gt;:在data分区下建一个文件夹/data/sysrw存放system原本的数据,启动时,软连接/data/sysrw为system分区&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;解释&lt;/strong&gt;:&#xA;1. data分区,最终挂载为/data文件夹,默认情况下,这是ext3格式的分区,但禁用了suid&#xA;2. system分区,为不可写的cramfs格式,默认挂载在/system文件夹&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;步骤&lt;/strong&gt;:&#xA;1. 在原版系统可以正常启动的前提下,将/system下的全部文件,拷贝到/data/sysrw&#xA;2. 传输su文件到/data/sysrw/下,使用我最近编译的简单版su,可跳过GUI确认&#xA;3. 修改boot.img,移除system文件夹(否则无法建立通往/system的软链接),对init.rc文件做以下修改:&#xA;..A. 不再挂载system分区 &amp;ndash; 注释掉 mount cramfs mtd@system /system &amp;ndash; 也就是前面加#号&#xA;..B. 不再建立system文件夹 &amp;ndash; 注释掉 mkdir /system&#xA;..C. 修改data分区的挂载方式,使其支持suid &amp;ndash; 挂载语句改为 mount ext3 mtd@userdata /data&#xA;..D. 修改data分区的权限 &amp;ndash; chmod 0770 /data 改为 chmod 0777 /data&#xA;..E. 修改su文件的权限,在D步骤所修改文件后面添加 chmod 6755 /system/bin/su &amp;ndash; 因为data分区启用了suid,故这个程序可以调用setgid(0)和setuid(0)了&#xA;..F. 为了提供更大自由度,修改根分区的权限 &amp;ndash; 注释掉 mount rootfs rootfs / ro remount&#xA;..G. 建立通往/system的软链接 &amp;mdash; 找到 mkdir /data ,在后面新起一行 symlink /data/sysrw /system&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;经验教训&lt;/strong&gt;&#xA;1. symlink 语法,与ln一样,前面是真实地址,后面是虚拟地址&#xA;2. 如果分区不支持suid,那么setuid/setgid将无法使用&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;关于su&lt;/strong&gt;&#xA;我为此建立一个项目: &lt;a href=&#34;https://github.com/wendal/android_su&#34;&gt;https://github.com/wendal/android_su&lt;/a&gt;&#xA;默认情况下,su是不允许其他用户使用的,而Superuser.apk附带的su又是与界面关联的.&#xA;我这个su,只要你执行,就给你root权限,非常爽!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;本文提及方法,理论上适用与一切Rk29系列的平板&lt;/p&gt;&#xA;&#xA;&lt;p&gt;针对台电P71和T760的修改工具已经完成:&#xA;&lt;a href=&#34;http://dl.dbank.com/c0xcsjwxsm&#34;&gt;http://dl.dbank.com/c0xcsjwxsm&lt;/a&gt;&#xA;其他系统的可参考着修改&lt;/p&gt;&#xA;&#xA;&lt;p&gt;再次感谢rk28小组的解包工具,你们成功解开了boot.img并顺利打包,为本方法的出现提供了可能性&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;最新更新,单单刷boot.img实现全部功能&lt;/strong&gt;,下载地址:&#xA;&lt;a href=&#34;http://dl.dbank.com/c0vd0zds0v&#34;&gt;http://dl.dbank.com/c0vd0zds0v&lt;/a&gt;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Nutz.Json的新注解@JsonField用法详解</title>
      <link>http://wendal.net/319.html</link>
      <pubDate>2011-09-07 09:06:39 +0800</pubDate>
      <description>&lt;p&gt;长期以来Nutz的Json包,仅有一个注解@toJson,用于指定当前对象的通过什么方法进行Pojo&amp;ndash;&amp;gt;String的转换&lt;/p&gt;&#xA;&#xA;&lt;p&gt;1.b.38版新增了@JsonField,在即将发布的1.b.40版将这个注解再次增强&#xA;正如其名,@JsonField是针对Json处理中字段级别的控制&lt;/p&gt;&#xA;&#xA;&lt;p&gt;首先是字段命名,看代码&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;@JsonField(&amp;quot;z-index&amp;quot;)&#xA;private String zIndex;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;对应的Json将会是:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;{&#xA;    &#39;z-index&#39; : &#39;10px&#39;&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;可以看到,无需再强求 json的key的名字与类属性名一致了&lt;/p&gt;&#xA;&#xA;&lt;p&gt;然后是&amp;rdquo;忽略&amp;rdquo;,看代码&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;@JsonField(ignore=true)&#xA;private String password;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;很清楚,就是不序列化这个字段&lt;/p&gt;&#xA;&#xA;&lt;p&gt;最后,是刚刚加入的by(生成器),这次用一个完整的例子:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;public class User {&#xA;&#xA;    @JsonField(by=&amp;quot;toString&amp;quot;)&#xA;    private ObjectId objectId;&#xA;&#xA;    @JsonField(&amp;quot;username&amp;quot;)&#xA;    private String name;&#xA;&#xA;    @JsonField(by=&amp;quot;net.wendal.helper.Md5#create&amp;quot;)&#xA;    private String password;&#xA;&#xA;    @JsonField(ignore=true)&#xA;    private String ip;&#xA;}&#xA;&#xA;public final class Md5 {&#xA;&#xA;    public static final String create(Object obj) {&#xA;        return XXXXX;&#xA;    }&#xA;&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;上面演示了by的两种写法,规则非常简单:&#xA;如果不包含#号,则代表调用自身的无参数方法,例子中的by=&amp;ldquo;toString&amp;rdquo; 将调用objectId.toString()&#xA;如果包含#号,则代表调用指定类的指定静态方法,这个方法必须以Object作为参数,但可以返回任意类型的参数&lt;/p&gt;&#xA;&#xA;&lt;p&gt;@toJson加上@JsonField应该足够满足很大一部分的需要了&lt;/p&gt;&#xA;&#xA;&lt;p&gt;另外,这种by的语法,我正在积极考虑应用到Nutz.Dao的@Prev注解中,解决长期以来注解生成机制的缺失&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>NutDao实现Lazy加载的可行性</title>
      <link>http://wendal.net/317.html</link>
      <pubDate>2011-09-06 11:33:16 +0800</pubDate>
      <description>&lt;p&gt;不知道多少人问过@Many @One等注释能否实现懒加载或者自动加载&lt;/p&gt;&#xA;&#xA;&lt;p&gt;从代码上说,NutDao实现的是不加载,你需要的时候自行调用 &amp;ndash; 其实也就是有点不方便,外加效率较低&lt;/p&gt;&#xA;&#xA;&lt;p&gt;我这里讨论的是NutDao做到真正懒加载的可能性与实现方式&#xA;焦点集中在NutDao.query方法,因为大部分DB&amp;ndash;&amp;gt;Pojo都是走这个方法的,fetch方法其实就是封装了一下query方法&lt;/p&gt;&#xA;&#xA;&lt;p&gt;由于实现的是懒加载,不可避免的使用Aop,以拦截@Many/@One的getter&#xA;使用Aop会导致一个问题,就是query方法返回的对象的类改变了,变成用户请求的类的一个定制化的子类的对象,这本身就导致一些问题:&#xA;    1. 使用query出来的对象进行update/delete时,由于其并非用户期望的类(实际上是其子类),导致getEntity需要改造,因为@Table等注解是不被继承的,@Column也是,这样,写在@Many/@One字段上的信息会被隐藏掉&#xA;    2. 用户代码可能会需要修改,当然,都是那些不好的写法,例如Class对象进行equal比较&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Aop实现的关键点:&#xA;    1. 获取Dao对象,并存为其一个属性的值&#xA;    2. 记录当前getter是否已经获取过,或者setter已经被执行过&#xA;    3. 跳过Hibernate式的事务问题,平等对待getter调用时的事务问题&lt;/p&gt;&#xA;&#xA;&lt;p&gt;可能的改造方法:&#xA;    1. Aop整个NutDao,对于query以外的方法,进行对象解包/类解包,以移除query方法带出Aoped类的影响&#xA;    2. 改造/继承AnnotationEntityMaker,让其生成对象时,使用Aop改造过的类&lt;/p&gt;&#xA;&#xA;&lt;p&gt;恩,应该OK了&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>广工,3年来,你改变了什么?</title>
      <link>http://wendal.net/316.html</link>
      <pubDate>2011-08-27 09:57:46 +0800</pubDate>
      <description>&lt;p&gt;广东工业大学,我本科的母校,毕业3年了&lt;/p&gt;&#xA;&#xA;&lt;p&gt;今天,我再次回去,看看它的变化&lt;/p&gt;&#xA;&#xA;&lt;p&gt;看着以前上课的课室,实验楼,一条条熟悉的过道 &amp;ndash; 记忆中画面不停飘过&lt;/p&gt;&#xA;&#xA;&lt;p&gt;校园内,树木高了,绿化多了,然而,栏杆,铁门,围墙也多了 &amp;ndash; 以安全/治安的名义,能干很多事&lt;/p&gt;&#xA;&#xA;&lt;p&gt;晚饭过后,去看看校外江边的公园,想不到啊,3年就能荒废成这样子,以至于我不敢为其拍照!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;还是晚饭后,还是晚上7点,还是这个地理坐标,完全不一样的景象&lt;/p&gt;&#xA;&#xA;&lt;p&gt;杂草丛生,灯看上去已经很久很久没亮过,路,如果那还是路的话,80%的面积被草覆盖了&#xA;那曾经的草坪,是多么美,今天我只看到了杂草,小灌木,以至于我不敢踏足 &amp;ndash; 曾几何时,我躺着看着星空&#xA;那座小桥,木板桥,已经破烂不堪,露出30%以上的水泥底座 &amp;ndash; 多少次与挚友,情侣路过这座小桥&#xA;那条小河,已经不是小河,最多能说得上是条垃圾填埋沟 &amp;ndash; 曾经,它流淌着小小溪流&lt;/p&gt;&#xA;&#xA;&lt;p&gt;以至于那座山,我不敢上前来,我甚至无法确认那条路还存在&lt;/p&gt;&#xA;&#xA;&lt;p&gt;敢问,还有广工的在读生,还有多少人知道这片江边公园的美景,甚至还有多少人知道其曾经存在过?&lt;/p&gt;&#xA;&#xA;&lt;p&gt;恩,那个曾经的江边公园,也只能留在记忆中了&lt;/p&gt;&#xA;&#xA;&lt;p&gt;广工,3年来,你改变了什么?&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>NutzMole -- Nutz的代码生成器</title>
      <link>http://wendal.net/314.html</link>
      <pubDate>2011-08-21 11:39:55 +0800</pubDate>
      <description>&lt;p&gt;惯例,先上下载地址:&#xA;&lt;a href=&#34;http://nutz.googlecode.com/files/rapid-generator-for-nutzmole-1.1.zip&#34;&gt;NutzMole 1.1 for rapid&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;这个项目的原始地址,原本是nutzlab的一个实验项目:&#xA;&lt;a href=&#34;http://code.google.com/p/nutzlab/source/browse/#svn%2Ftrunk%2FzMole&#34;&gt;http://code.google.com/p/nutzlab/source/browse/#svn%2Ftrunk%2FzMole&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;历史:&lt;/strong&gt;&#xA;最初的代码,是在2010年11月提交的,之后一直处于冻结状态 &amp;ndash; 为什么? 因为我的Html页面做不出来,前端我可不在行. 当时,模板基本上就已经定下来,代码结构也基本确定&#xA;直到几天前,我重启这个项目,并作了少量修正后,发布了NutzMole 1.0版,可独立运行,说白了,就是把旧代码清理一下,打包成一个独立运行包&lt;/p&gt;&#xA;&#xA;&lt;p&gt;1.0发布后,意见/建议/批评纷纷袭来,很大的原因是这个版本并未严格测试,模板本身使用的一些代码在Nutz 1.b.39已经无法使用&lt;/p&gt;&#xA;&#xA;&lt;p&gt;很快的, 1.1版发布了,更新了模板,并采用了rapid的代码生成器平台&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;对比一下最初的NutzMole和rapid代码生成器平台&lt;/strong&gt;:&#xA;    NutzMole使用多个配置文件,rapid仅一个配置文件&#xA;    NutzMole使用传统的接口/实现类来配置,rapid提供的文件模板&amp;ndash;&amp;gt;文件的机制&lt;/p&gt;&#xA;&#xA;&lt;p&gt;NutzMole以专用工具的思想设计, rapid是按平台的理念设计,我对其代码生成器的印象是:&#xA;    1. 单一配置文件,对用户非常友好&#xA;    2. 平等的文件模板机制 &amp;ndash;&amp;gt; 路径本身也可以使用表达式,全部模板都是使用相同的context&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;NutzMole 1.1的使用指南&lt;/strong&gt;:&#xA;    修改generator.xml以符合你的数据库配置,如果lib文件夹未包含你需要的数据库驱动,请自行添加,然后执行rapid-gen.bat&lt;/p&gt;&#xA;&#xA;&lt;p&gt;非常简单的使用方法,另外我正考虑做一个简单的GUI供用户填写信息&lt;/p&gt;&#xA;&#xA;&lt;p&gt;另外,值得注意的是,我在nutzmole的模板中使用了lombok,一个非常非常好用的工具包,最大的用处就是免去写Getter/Setter&#xA;下载地址:&#xA;&lt;a href=&#34;http://projectlombok.org/&#34;&gt;http://projectlombok.org/&lt;/a&gt;&#xA;我已经多次思考是否把lombok加入模板中,最近决定:这东西实在太好,非常值得推广!!强推吧!!&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>把VPS翻新了一下</title>
      <link>http://wendal.net/312.html</link>
      <pubDate>2011-08-20 11:34:53 +0800</pubDate>
      <description>&lt;p&gt;话说在vpsess的这个vps,用了一年了,感觉一直不错,昨天到期,干脆要了一个新的VPS,把数据迁移过去&lt;/p&gt;&#xA;&#xA;&lt;p&gt;旧的VPS,是20G空间,用了10G,其实我也不清楚到底为何用了10G,删来删去,还是这么多&lt;/p&gt;&#xA;&#xA;&lt;p&gt;步骤:&lt;/p&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&lt;p&gt;拷贝.ssh文件夹 &amp;ndash; scp就不需要密码了&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;新vps装lnmp,旧vps导出数据库,打包/opt和nginx的配置&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;新vps导入数据库sql,覆盖nginx设置&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;拷贝hudson历史数据,拷贝博客的文件&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;还有就是一些杂七杂八的数据,也迁移过去&lt;/p&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;p&gt;哦也,重启lnmp服务,启动tomcat,验证一下,搞定!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;接着,当然是安装python和git,不过vps上的ubuntu是10.04,找不到现成的python3.2和git,二话不说,直接下源码编译咯&lt;/p&gt;&#xA;&#xA;&lt;p&gt;就这样折腾了一个晚上,最后让vpsee帮忙切换到旧ip,完成,收工!!&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>数据库连接长时间空闲后,爆连接已经关闭的解决方法</title>
      <link>http://wendal.net/309.html</link>
      <pubDate>2011-08-13 09:31:59 +0800</pubDate>
      <description>&lt;p&gt;本文仅讨论使用连接池的情况:&lt;/p&gt;&#xA;&#xA;&lt;p&gt;在很多场合都碰到有人提问: 第二天第一次访问应用,总是报连接已经关闭(Connection Close)&lt;/p&gt;&#xA;&#xA;&lt;p&gt;其实,数据库连接池大都已经考虑了这个问题,进行设置一下即可:&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&#34;http://commons.apache.org/dbcp/api-1.4/org/apache/commons/dbcp/BasicDataSource.html&#34;&gt;Apache DBCP&lt;/a&gt;:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;dataSource.setValidationQuery(&#39;select 1&#39;);&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&#34;http://sourceforge.net/projects/c3p0/&#34;&gt;C3po&lt;/a&gt;:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;dataSource.setTestConnectionOnCheckout(true);&#xA;dataSource.setPreferredTestQuery(&#39;select 1&#39;)&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&#34;http://proxool.sourceforge.net/api-dev/org/logicalcobwebs/proxool/ProxoolDataSource.html&#34;&gt;Proxool&lt;/a&gt;:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;dataSource.setTestBeforeUse(true);&#xA;dataSource.setHouseKeepingTestSql(&#39;select 1&#39;)&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Bonecp:&#xA;找不到对应的属性,不过可以配置连接的最大空闲时间&lt;/p&gt;&#xA;&#xA;&lt;p&gt;其实原来也就这么简单,返回连接给用户之前,先执行一条简单无害快速的SQL&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>鸣鸣第一次出境, Mark一下</title>
      <link>http://wendal.net/308.html</link>
      <pubDate>2011-08-07 07:44:14 +0800</pubDate>
      <description>&lt;p&gt;嘻嘻, 鸣鸣第一次去香港了,行程如下:&#xA;第一天&#xA;广州&amp;ndash;&amp;gt;深圳,游深圳夜景&#xA;深圳&amp;ndash;&amp;gt;香港&amp;ndash;&amp;gt;深圳,通过深圳湾口岸,坐B2到元朗,买1天地铁通票,到湾仔会展中心,进&amp;rdquo;第19界婴幼儿用品展览会&amp;rdquo;购物,游香港街景,然后到太子坐车会深圳湾过关&#xA;深圳&amp;ndash;&amp;gt;广州,深圳红树林,深圳街景,回广州&lt;/p&gt;&#xA;&#xA;&lt;p&gt;这次购买了不少的用品,但最打动我但有无法购买的是&amp;rdquo;轮状病毒疫苗&amp;rdquo;&#xA;我咨询到的轮状病毒疫苗 仅限6~24周的婴儿使用,呜呜,我女儿已经半岁了,能预防/减轻5岁以下儿童的轮状病毒腹泻,非常非常有用&lt;/p&gt;&#xA;&#xA;&lt;p&gt;另外一个,就是2700港元的&amp;rdquo;子宫颈癌疫苗&amp;rdquo;,香港刚刚推出的,适用于45岁以下的女性,分3次肌肉注射,6个月内完成 &amp;ndash; 积极考虑中,呵呵&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Nutz的Scans类,你用过没?</title>
      <link>http://wendal.net/307.html</link>
      <pubDate>2011-08-04 08:40:25 +0800</pubDate>
      <description>&lt;p&gt;你是否想得到某个package下的全部类呢?&#xA;你是否想得到某个文件夹下全部的配置文件?&lt;/p&gt;&#xA;&#xA;&lt;p&gt;你还在自己写这种的实现? 你还在拼命地问谷哥?&lt;/p&gt;&#xA;&#xA;&lt;p&gt;好吧,不吹水了,正式介绍Scans类:&#xA;org.nutz.resource.Scans&lt;/p&gt;&#xA;&#xA;&lt;p&gt;首先,必须先强调一点,在J2EE环境中,如果你没有使用NutzMVC的话,请在Filter/Servlet中加入这一句:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;Scans.me().init(config.getServletContext());&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;这个语句必须优先于其他任何Nutz相关语句&lt;/p&gt;&#xA;&#xA;&lt;p&gt;好,如何得到某个文件夹下全部的配置文件呢?即使打包成jar也无需改代码呢?&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;//第一个参数是需要扫描的文件夹,第二个是文件名需要匹配正则表达式,可以为null&#xA;List&amp;lt;nutresource&amp;gt; list = Scans.me().scan(&amp;quot;config/&amp;quot;,&amp;quot;^.+\\.ini&amp;quot;);&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;得到某个package下全部的类&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;//第一个参数是需要扫描的文件夹,第二个是文件名需要匹配正则表达式,可以为null&#xA;List&amp;lt;class &amp;lt;?&amp;gt;&amp;gt; list = Scans.me().scanPackage(&amp;quot;net.wendal.mvc&amp;quot;);&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;注意,你应该已经发现, 返回的是NutResource,而不是File之类的对象,why?&#xA;其实,这正是我当时做resource包的初衷 &amp;ndash; File对象无法表达jar里面的文件,而InputStream又不包含文件名之类的信息&lt;/p&gt;&#xA;&#xA;&lt;p&gt;NutResource类最重要的两个方法:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;public String getName();&#xA;public InputStream getInputStream()&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;同时包含两中信息,满足大部分需求&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Scans类的局限性:&#xA;1. 不允许进行根路径扫描 &amp;ndash; 就是说,你不能直接把文件放在classpath根下,必须放在文件夹中&#xA;2. 现在已经测试在Tomcat/Jetty/WebLogic下正常,在Maven环境下不正常(至今搞不懂Maven的ClassLoader在某些情形下竟然返回null)&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>鸣鸣半岁了,今天第一次吃辅食!!</title>
      <link>http://wendal.net/305.html</link>
      <pubDate>2011-08-01 10:00:58 +0800</pubDate>
      <description>&lt;p&gt;&lt;strong&gt;经过6个月的纯母乳喂养,鸣鸣今天迈入新的阶段&amp;ndash;添加辅食&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;鸣鸣一天天成长,每天都很踏实 &amp;ndash; 我很反对用&amp;rdquo;眨眼就过去了&amp;hellip;&amp;ldquo;,因为那代表着空虚和不作为&lt;/p&gt;&#xA;&#xA;&lt;p&gt;鸣鸣现在的体重是出生时的3倍&amp;ndash;15斤,长高了17厘米&#xA;双眼同步正常,已经能够自己坐着玩玩具 &amp;ndash; 认真玩玩具的时候,平衡力明显减弱&lt;/p&gt;&#xA;&#xA;&lt;p&gt;值得一提的是鸣鸣最喜欢的玩具&amp;ndash;塑料玩具桶,呵呵,前身是我们刚买不久的垃圾桶!! 由于鸣鸣的不懈努力,以其鲜艳的颜色,终于纳入玩具行列&lt;/p&gt;&#xA;&#xA;&lt;p&gt;周围的人,无一例外地反对我如此&amp;rdquo;迟&amp;rdquo;地添加辅食:&#xA;1. XX出世没几天就吃米糊啦?!&#xA;2. 都4/5/6月了,还不吃米糊/辅食?!&#xA;3. 儿童保健医生:4个月开始要喂辅食啦&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;恩,我坚持自己的观点,顶住鸭梨,终于让鸣鸣顺顺利利地吃了6个月的纯母乳&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;国内很多人都认为,应该4个月开始喂辅食,但又有多少人知道, WHO的推荐做法是6个月的纯母乳喂养&lt;/p&gt;&#xA;&#xA;&lt;p&gt;据我的观察,鸣鸣是在满5月后才开始关注其他食物,开始留意我们吃饭的动作&lt;/p&gt;&#xA;&#xA;&lt;p&gt;周围很多觉得,我咋就这么不传统呢?!! 但又有多少人去批评那些所谓的传统呢?!!&#xA;1. 坐月子 &amp;ndash; 90%都是扯淡,大部分人只是遵循所谓传统而盲目地坐月子&#xA;2. 辅食   &amp;ndash; 很多家长都急于喂辅食,其实就是想自己省事&#xA;3. 学步车 &amp;ndash; 还有多少家长在购买害人的圈式学步车?!&#xA;4. BB语   &amp;ndash; 导致宝宝需要学习一种没用的语言(例如:吃饭饭)&lt;/p&gt;&#xA;&#xA;&lt;p&gt;我又想起那句广告语: &amp;ldquo;别让您的孩子输在起跑线上&amp;rdquo; &amp;ndash; 呸!!&#xA;恩,又是所谓的胎教,早教,奥数!!&#xA;一味的追求&amp;rdquo;早&amp;rdquo; &amp;ndash; 早教,各种各样的兴趣班,提前去幼儿园,提前上小学&lt;/p&gt;&#xA;&#xA;&lt;p&gt;好了,牢骚完了&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Autoproxy Forever!!</title>
      <link>http://wendal.net/303.html</link>
      <pubDate>2011-07-24 08:54:14 +0800</pubDate>
      <description>&lt;p&gt;看到不少帖子又在找兼容 Firefox 5 Firefox 6 Firefox 7 Firefox 8的Autoproxy,我鸭梨很大啊,因为官方的动作还是很慢!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;我现在用Firefox 8.0a1 , Autoproxy也很正常&lt;/p&gt;&#xA;&#xA;&lt;p&gt;好吧,放出我自己的版本,兼容至Firefox9!!:&#xA;&lt;a href=&#34;http://dl.dbank.com/c0cluqlrqw&#34;&gt;http://dl.dbank.com/c0cluqlrqw&lt;/a&gt;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Nutz 1.b.38发布了,将来怎么走呢?</title>
      <link>http://wendal.net/302.html</link>
      <pubDate>2011-07-17 07:17:19 +0800</pubDate>
      <description>&lt;p&gt;经过马拉松式的开发,在1.b.37发布之后的3个月,1.b.38终于正式发布&lt;/p&gt;&#xA;&#xA;&lt;p&gt;在我看来,这是个里程碑式的版本,截至到1.b.38,Nutz的每一部分都至少重构了一次&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Ioc很久以前就重构过,大概是1.a.27,zozoh操刀&#xA;Aop,1.a.29进行重构,我操刀&#xA;Json,1.b.38历经两次重构,先是jukai,后面是我&#xA;Dao,1.b.38,被zozoh翻天覆地地重构完成&lt;/p&gt;&#xA;&#xA;&lt;p&gt;我觉得Nutz自身已经成熟了,多次重构,用户实践 &amp;ndash; 在不停的fix bug中完善&lt;/p&gt;&#xA;&#xA;&lt;p&gt;然而,Nutz还需要些什么呢?或者说,用户还需要些什么呢?&#xA;1. 代码生成器 &amp;ndash; 很多很多用户要求这个,但是,真的能提供生产效率吗??&#xA;2. IDE &amp;ndash; 我一直在思考其必要性,Nutz复杂到需要IDE协助吗??&#xA;3. 支持NoSQL &amp;ndash; 貌似没啥意义&#xA;4. 还有一些零碎的功能增强,一时半刻没想起来&lt;/p&gt;&#xA;&#xA;&lt;p&gt;我觉得Nutz还有一些设计欠佳的地方:&#xA;1. Ioc的bean定义,由于最初的设计支持一种抽象的Bean,这种bean只声明字段 &amp;ndash; 这种遗留的设计导致Ioc本身及IocLoader不必要的复杂性,然而我至今没发现需要用到的场景&#xA;2. Ioc的单例 &amp;ndash; NutIoc中的单例的概念,我依旧觉得很怪,呵呵&#xA;3. Dao的Pojo实例的生成机制 &amp;ndash; 新版的Dao中,这部分的代码依然有些零碎,我曾经尝试改进,没有成功, 这导致编写缓存/懒加载等需要参与对象生成的插件比较困难&#xA;4. Json反序列化的定制性 &amp;ndash; 1.b.38引入的JsonField注解,恩,应该得到一些改善&#xA;5. Castor的扩展机制 &amp;ndash; 这东西到底有没有人用过呢??&lt;/p&gt;&#xA;&#xA;&lt;p&gt;恩, Nutz,继续努力!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;喜欢Nutz?? Fork它!!&lt;/strong&gt;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>JGit初试牛刀</title>
      <link>http://wendal.net/299.html</link>
      <pubDate>2011-07-16 09:53:35 +0800</pubDate>
      <description>&lt;p&gt;最近爱上了Git,当然不能忽略jGit啦&lt;/p&gt;&#xA;&#xA;&lt;p&gt;好吧废话少说,直接上代码先:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;package net.wendal.jgit;&#xA;&#xA;import java.io.File;&#xA;import java.io.FileWriter;&#xA;&#xA;import org.eclipse.jgit.api.Git;&#xA;import org.eclipse.jgit.revwalk.RevCommit;&#xA;&#xA;public class JGit {&#xA;&#xA;    public static void main(String[] args) throws Throwable {&#xA;        File root = new File(&amp;quot;gitme&amp;quot;);&#xA;        if(!root.exists())&#xA;            root.mkdir();&#xA;        File gitF = new File(&amp;quot;gitme/.git&amp;quot;);&#xA;        if(!gitF.exists()) {//如果已经初始化过,那肯定有.git文件夹&#xA;                        //初始化git库,相当于命令行的 git init&#xA;            Git.init().setDirectory(root).call();&#xA;        }&#xA;        Git git = Git.open(root); //打开git库&#xA;&#xA;                //好吧,随便写一个文件进去先&#xA;        File newFile = new File(&amp;quot;gitme/&amp;quot;+System.currentTimeMillis()+&amp;quot;.java&amp;quot;);&#xA;        FileWriter fw = new FileWriter(newFile);&#xA;        fw.write(System.currentTimeMillis() + &amp;quot; ABC&amp;quot;);&#xA;        fw.flush();&#xA;        fw.close();&#xA;&#xA;                //添加文件咯,相当于 git add .&#xA;        git.add().addFilepattern(&amp;quot;.+&amp;quot;).call();&#xA;&#xA;                //然后当然是提交啦,相当于 git commit&#xA;        git.commit().setCommitter(&amp;quot;wendal&amp;quot;, &amp;quot;wendal1985@gmail.com&amp;quot;).setMessage(&amp;quot;Try jgit!&amp;quot;).call();&#xA;&#xA;        //接下来,我们看看log信息&#xA;        for(RevCommit revCommit : git.log().call()){&#xA;            System.out.println(revCommit);&#xA;            System.out.println(revCommit.getFullMessage());&#xA;            System.out.println(revCommit.getCommitterIdent().getName() + &amp;quot; &amp;quot; + revCommit.getCommitterIdent().getEmailAddress());&#xA;        }&#xA;    }&#xA;&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;输出的内容:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;commit 5fb38fa714f42f5be72cea9221f9264a5944a14e 1310829994 ----sp&#xA;Try jgit!&#xA;wendal wendal1985@gmail.com&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;如果你重复运行,会看到好几条哦,呵呵&lt;/p&gt;&#xA;&#xA;&lt;p&gt;就现在看来,JGit的API设计得还不错,链式操作,而且比较直观&lt;/p&gt;&#xA;&#xA;&lt;p&gt;JGit项目地址: &lt;a href=&#34;http://www.eclipse.org/jgit&#34;&gt;http://www.eclipse.org/jgit&lt;/a&gt;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Rk2918固件新打包格式分析</title>
      <link>http://wendal.net/296.html</link>
      <pubDate>2011-06-26 11:25:37 +0800</pubDate>
      <description>&lt;p&gt;本文针对 台电T760的2.x固件,原道N10,酷比1.0.5等RK2918方案的新固件打包格式&lt;/p&gt;&#xA;&#xA;&lt;p&gt;文件总体结构:&#xA;文件内容描述块 0x00 ~ 0x65&#xA;Loader程序 0x66 ~ 0x66+Loader的长度&#xA;update.img 0x66+Loader的长度+1 ~ 文件结束前32个字节&#xA;MD5 文件的最后32个字节为文件其余部分的MD5码&amp;ndash;ASCII形式&lt;/p&gt;&#xA;&#xA;&lt;p&gt;文件内容描述块:&#xA;文件头 0x00~0x04 共5个字节,固定为RKFWf&#xA;固件版本号 0x05~0x09 共5个字节, 例如 00 03 00 02 00 代表 0.2.03, 00 09 00 02 08 代表 8.2.09&#xA;芯片型号 0x15 一个字节, 50代表RK29,40代表RKCROWN,30代表RKNANO,20代表RK28,10代表RK27&#xA;loader信息 0x19~0x20 共8个字节,前4个字节是偏移量,后4个字节是长度.例如66 00 00 00代表0x66,5A 55 02 00代表0x02555A&#xA;update.img信息0x22~0x29 共8个字节,与loader信息含义一致&lt;/p&gt;&#xA;&#xA;&lt;p&gt;附图片:&#xA;&lt;a href=&#34;/assets/media/2011/06/RK2918_IMG_Format.jpg&#34;&gt;RK2918_IMG_Format.jpg&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;我已经实现的版本:&#xA;&lt;a href=&#34;https://github.com/wendal/teclast_tools&#34;&gt;https://github.com/wendal/teclast_tools&lt;/a&gt; 源码&#xA;下载:&#xA;&lt;a href=&#34;http://www.everbox.com/f/kl3FWPQ7W6yvCyVKWmsLCWcf2o&#34;&gt;http://www.everbox.com/f/kl3FWPQ7W6yvCyVKWmsLCWcf2o&lt;/a&gt;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>搭建Git服务器,真的很简单</title>
      <link>http://wendal.net/295.html</link>
      <pubDate>2011-06-21 09:07:36 +0800</pubDate>
      <description>&lt;p&gt;&lt;strong&gt;重要提醒, 本教材适用于gitolite v2,与当前最新版v3不兼容!!&lt;/strong&gt;&#xA;&lt;strong&gt;需要在checkout gitolite后,切换到v2版!!&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;最近都在玩Git, &lt;a href=&#34;https://github.com/nutzam/nutz&#34;&gt;Nutz也已经迁移到Github上&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;原文地址: &lt;a href=&#34;http://sitaramc.github.com/gitolite/doc/1-INSTALL.html&#34;&gt;http://sitaramc.github.com/gitolite/doc/1-INSTALL.html&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;其实真的只需要几句&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;#现在开始是root做的&#xA;&#xA;#安装Git&#xA;apt-get install git&#xA;#拷贝你自己的公钥&#xA;cp ~/.ssh/id_rsa.pub /tmp/wendal.pub&#xA;git clone git://github.com/sitaramc/gitolite&#xA;cd gitolite&#xA;##################################&#xA;#重要!! 切换到v2版!!&#xA;git checkout g2&#xA;##################################&#xA;src/gl-system-install&#xA;&#xA;#添加git用户,并切换到git用户&#xA;adduser git&#xA;su - git&#xA;&#xA;#现在开始要变成git用户了&#xA;gl-setup /tmp/wendal.pub&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;大功告成!! 搭建完成!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;下面说说简单的管理&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;#同样需要用git进行管理,任何一台机器,能访问服务器(sshd是必须的啦)就行,并持有wendal.pub对应的私钥&#xA;#首先git clone出管理项目&#xA;git clone git@wendal.net:gitolite-admin&#xA;cd gitolite-admin&#xA;ls -l&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;你会看到两个文件夹conf 和keydir&#xA;keydir 是 存放用户的公钥的, 用户名.pub , 可以建子文件夹&#xA;conf下只有一个文件,gitolite.conf,默认内容如下:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;repo    gitolite-admin&#xA;        RW+     =   wendal&#xA;&#xA;repo    testing&#xA;        RW+     =   @all&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;一目了然的吧,你可能问: 如何添加新的库啊? 简单&#xA;往这个文件添加一个库的配置,就会自动帮你建好,例如添加:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;repo    GGG&#xA;        RW+     =   wendal,zozoh&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;就会帮你生成一个名为GGG的库&lt;/p&gt;&#xA;&#xA;&lt;p&gt;当然,以上配置,还要push到服务器才行.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;下面是简单的git指南&#xA;在我看来就几个命令:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;#克隆一个库,相当于svn的check out&#xA;git clone git@wendal.net:gitolite-admin&#xA;&#xA;#设置本地信息,非常重要!!&#xA;git config --global user.name &amp;quot;wendal&amp;quot;&#xA;git config --global user.email &amp;quot;admin@wendal.net&amp;quot;&#xA;git config core.quotepath false&#xA;&#xA;#更新本地的库,相当于svn的update&#xA;git pull&#xA;&#xA;#上传本地的修改到远程的库,其中origin是默认远程库,也就是你clone的库, master是分支名&#xA;git push origin master&#xA;&#xA;#提交修改到本地仓库&#xA;git add XXX/XXX  vabc/afda/Abc.java&#xA;git commit -a #将包含全部修改过的文件,但新增的会忽略&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;就这样,呵呵,最后,附上一些链接:&#xA;&lt;a href=&#34;http://gitref.org/&#34;&gt;http://gitref.org/&lt;/a&gt; 英文,Git指南&#xA;&lt;a href=&#34;http://gitbook.liuhui998.com/&#34;&gt;http://gitbook.liuhui998.com/&lt;/a&gt; 中文,呵呵,我参与过校对工作&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>在几种编程语言中探索(Java/Python/Lua/C)</title>
      <link>http://wendal.net/292.html</link>
      <pubDate>2011-06-10 12:15:42 +0800</pubDate>
      <description>&lt;p&gt;猛然发现自己已经快一个月没写blog,太懒惰了!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;5月,先是脚受伤,接着过敏&amp;hellip;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Java &amp;ndash; 为Nutz重写的Json解析器,最初的实现(zozoh)我看不懂,第二版(juqkai)改造得不够彻底,代码比较乱. 这次修改之后,解析将比之前严格,对于非法转义字符,不匹配的[}均直接抛出异常. 这将导致已经使用nutz的项目,其json文件可能会被报错. 然而,这并未100%的执行Json规范,主要是数字处理和map的key&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Python &amp;ndash; 最近用得比较多,但至今未打动我. 很多情况下,Python依旧是Shell的替代品,呵呵. 不知道是不是习惯于一种思维: 编程语言=语法+API , 也许还没领会到Python的精髓与思维模式. 与Java相比, 多了些语法糖果,如in和缩进式的逻辑语句&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Lua &amp;ndash; 呵呵,最近貌似很流行呢!! 最近玩的愤怒的小鸟,也是用Lua写的&#xA;成果: &lt;a href=&#34;http://www.teclast.com/bbs/forum.php?mod=viewthread&amp;amp;tid=157140&amp;amp;extra=&#34;&gt;RK29xx固件解包打包工具_v1.1测试版&lt;/a&gt; 当前唯一正确解包/打包RK2918方案固件的工具,完美解开台电T760的2.x固件,酷比1.x固件&#xA;Lua真的是一门神奇的语言, 很少的语法,极度精简的API!! 很值得学习的一门语言&lt;/p&gt;&#xA;&#xA;&lt;p&gt;C &amp;ndash; 处理字符串,真是痛苦啊&amp;hellip;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;刚刚把Nutz的代码迁移到Github了,准备写个简单教程,说说经验,呵呵&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>鸣鸣满100天了!! 申领了身份证等重要证件,嘻嘻</title>
      <link>http://wendal.net/288.html</link>
      <pubDate>2011-05-13 02:38:54 +0800</pubDate>
      <description>&lt;p&gt;嘻嘻,一百天了&lt;/p&gt;&#xA;&#xA;&lt;p&gt;花了一个上午,办:&#xA;身份证    40个工作日可取?!&#xA;港澳通行证 15天&#xA;护照        15天&lt;/p&gt;&#xA;&#xA;&lt;p&gt;恩,还挺顺利的&lt;/p&gt;&#xA;&#xA;&lt;p&gt;工作耽误了一些,明后两天加班,呵呵&lt;/p&gt;&#xA;&#xA;&lt;p&gt;附回执,嘻嘻,关键信息都已经涂黑:&#xA;&lt;a href=&#34;/assets/media/2011/05/MM_SF.jpg&#34;&gt;MM_SF-300x225.jpg&lt;/a&gt;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>不跟你玩,玩不起!!</title>
      <link>http://wendal.net/287.html</link>
      <pubDate>2011-05-10 03:37:08 +0800</pubDate>
      <description>&lt;p&gt;认认真真地把robot.txt写好了,国内的百度,Soso,搜狗,一概屏蔽!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;不跟你们玩了!!&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>宝宝快100天了,记录一下经验</title>
      <link>http://wendal.net/285.html</link>
      <pubDate>2011-05-04 07:12:41 +0800</pubDate>
      <description>&lt;p&gt;嘻嘻,鸣鸣诞生快100天,每天都如此充实.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;好,记录一下: &lt;strong&gt;13斤,63厘米&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;一些经验:&#xA;&lt;strong&gt;1. 母乳喂养&lt;/strong&gt;&#xA;除非有生理/心理疾病,母乳都是足够的.&#xA;首先,母乳是按需生产,宝宝喝得多,就产得多&#xA;其次,认为母乳不足,添加奶粉,是非常错误的,BB少吮吸,奶自然就少&#xA;最后,母乳如何才多? 1.怀孕期要按摩 2.喂奶前喝牛奶,吃鸡蛋,喂奶期间可以适当喝点水&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;2. 补钙&lt;/strong&gt;&#xA;千万被直接让BB吃钙片/液体钙!!&#xA;如果宝宝晚上突然哭,不肯睡,可能就是缺钙.&#xA;那么,妈妈就应该补钙了!! 我老婆每天补充400~500mg的钙,嘻嘻&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;3. 晚上喂奶&lt;/strong&gt;&#xA;晚上尽量不要喂奶!!&#xA;临睡觉,让宝宝多喝点&#xA;如果宝宝晚上醒了,先判断是否为纸尿裤湿了,不要急着喂奶.&#xA;宝宝是需要调教的,除了第一个月,晚上基本上可以不用喂奶的&#xA;如何调教? 临睡那一餐,多喂点,宝宝醒来的时候,慢一点喂,逐渐逐渐的,间隔时间就长起来了&amp;hellip; 最后过渡到晚上不喂,或晚上只喂一点点&#xA;我现在做的是,晚上不需要喂,或者只需要喂一两口(其实宝宝还是睡着的,眼睛都没睁开过), 整个晚上都不醒.&#xA;睡得好,宝宝才能长得快,而非吃得好哦&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;4. 纸尿裤&lt;/strong&gt;&#xA;现在的速度是 每天10片,呵呵&#xA;随着晚上无需喂宝宝, 宝宝也很配合,晚上不拉便便, 这样整晚都不太需要换纸尿裤, 这样子宝宝自己也能睡个好觉&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;5. 疫苗&lt;/strong&gt;&#xA;一概收费疫苗,对国产疫苗完全不信任&#xA;另外,每次打针,提前一天告诉宝宝要打针,到疾控中心后,让宝宝看其他孩子打针,告诉她打针会疼,但不会很疼.&#xA;宝宝其实很懂事的,提前告诉她,是尊重她; 让她了解打针会疼,千万不要骗她;让她看其他孩子打针,让其知道会发生什么事.&#xA;很多人觉得小孩子什么都不懂,就不尊重他们,哄骗他们,疾控中心哭声一片,呵呵, 我的鸣鸣,打完针,1分钟之后又睡着了,嘻嘻&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;6. 脐带血&lt;/strong&gt;&#xA;等了3个月(60个工作日), 脐带血的检验结果终于出来, 合格,嘻嘻,不错不错.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;7. 游泳&lt;/strong&gt;&#xA;每2/3天游泳一次,呵呵, 100来块的装备,每次半方水(还挺多的)&#xA;宝宝很喜欢,每次都游得很快乐&#xA;每次游完,穿好衣服,马上就去吃奶,嘻嘻,开心得很呢. 鸣鸣有时候还哼上几句才吃,嘻嘻,好像要表达愉悦心情一样&#xA;室温25度以上(必要时就用暖风机)&#xA;水温25~37度&lt;/p&gt;&#xA;&#xA;&lt;p&gt;好,欢迎交流哦,嘻嘻&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>评价一下Everbox和微盘</title>
      <link>http://wendal.net/282.html</link>
      <pubDate>2011-04-30 08:38:53 +0800</pubDate>
      <description>&lt;p&gt;&lt;strong&gt;两者的官方:&lt;/strong&gt;&#xA;Everbox &lt;a href=&#34;http://everbox.com&#34;&gt;http://everbox.com&lt;/a&gt;&#xA;微盘 &lt;a href=&#34;http://vdisk.me&#34;&gt;http://vdisk.me&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;容量:&lt;/strong&gt;&#xA;Everbox 上限15G,单一文件大小仅受限于空间大小&#xA;微盘      上限10G,单一文件大小未知(API也没说,页面也没提及&amp;hellip;)&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;运行平台:&lt;/strong&gt;&#xA;两者的前端都是nginx,我喜欢!! 而且盛大的版本比较新,嘻嘻&#xA;微盘肯定是php应用,跑在SAE上,估计是特权应用,因为SAE默认每个应用只允许存放10G数据&#xA;Everbox猜不出来, session_id的名字也隐藏了,不知道什么语言写的&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;两者API的优缺点:&lt;/strong&gt;&#xA;1. Everbox,请求一个文件的信息,响应体没有文件的指纹!!单单给edit time,受不了!! 微盘好歹也给个MD5啊!!&#xA;2. 微盘有公开的API;Everbox暂时没有(官方答复是很快就会公开,呵呵)&#xA;3. Everbox的上传机制比微盘好,起码能分段能续传;微盘对于大文件的上传还没给出API,乏力啊&#xA;4. 微盘有个dolog机制, Everbox有ver标志,估计都能做些东西,但ver标志的含义至今没搞明白,纠结!!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;最后发发牢骚:&lt;/strong&gt;&#xA;1. 微盘用HmacSHA256,天啊,啥玩意?! 貌似是OpenID的用到的,整了我一个晚上才搞明白,期间还动用了我微乎其微的php知识!!&#xA;2. Everbox API快点出啊!! /list /query都不知道应该咋用!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;总结:&lt;/strong&gt;&#xA;学到了不少文件同步的知识,呵呵&#xA;两者的Java SDK项目:&#xA;Everbox4j &lt;a href=&#34;http://code.google.com/p/everbox4j/&#34;&gt;http://code.google.com/p/everbox4j/&lt;/a&gt;&#xA;VDisk4j     &lt;a href=&#34;http://code.google.com/p/vdisk4j/&#34;&gt;http://code.google.com/p/vdisk4j/&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;暂时都是用Everbox,先入为主吧,嘻嘻,大部分代码也在Everbox4j项目中&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Nutz中你未必知道的用法</title>
      <link>http://wendal.net/280.html</link>
      <pubDate>2011-04-28 10:30:11 +0800</pubDate>
      <description>&lt;p&gt;========================================================================&lt;/p&gt;&#xA;&#xA;&lt;h1&gt;&lt;strong&gt;Ioc篇&lt;/strong&gt;&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;1. 使用properties文件&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;var ioc = {&#xA;    config : {&#xA;        type : &amp;quot;org.nutz.ioc.impl.PropertiesProxy&amp;quot;, /*1.b.37内置的一个代理类*/&#xA;        fields : {&#xA;            paths : [&amp;quot;conf/jdbc.properties&amp;quot;] /*可以写多个文件或文件夹*/&#xA;        }&#xA;    },&#xA;// Data source&#xA;    dataSource : {&#xA;        type :&amp;quot;org.apache.commons.dbcp.BasicDataSource&amp;quot;,&#xA;        events : {&#xA;            depose :&amp;quot;close&amp;quot;&#xA;        },&#xA;        fields : {&#xA;            driverClassName : {&#xA;                java :&amp;quot;$config.get(&#39;driver&#39;)&amp;quot;&#xA;            },&#xA;            url : {&#xA;                java :&amp;quot;$config.get(&#39;url&#39;)&amp;quot;&#xA;            },&#xA;            username : {&#xA;                java :&amp;quot;$config.get(&#39;username&#39;)&amp;quot;&#xA;            },&#xA;            password : {&#xA;                java :&amp;quot;$config.get(&#39;password&#39;)&amp;quot;&#xA;            }&#xA;        }&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;结合Ioc的Java调用与PropertiesProxy,无需修改Ioc内部逻辑&#xA;这个方法依赖于1.b.37新内置的PropertiesProxy,旧版本的用户可以直接拷贝其代码来使用.&#xA;PropertiesProxy其实就是一个对Properties类的简单封装,以便于在Ioc中使用.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;2. 使用JNDI获取指定资源&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;var ioc = {&#xA;    dao : {&#xA;        type :&amp;quot;org.nutz.dao.impl.NutDao&amp;quot;,&#xA;        args : [ {jndi :&amp;quot;jdbc/dataSource&amp;quot;} ]&#xA;    }&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;以上方法,仅需要在容器中配置好数据源,注入到NutDao即可.&#xA;其他类型的JNDI资源也同样可以注入.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;========================================================================&lt;/p&gt;&#xA;&#xA;&lt;h1&gt;&lt;strong&gt;MVC篇&lt;/strong&gt;&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;1. 在@Ok和@Fail中使用EL表达式&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;@Ok(&amp;quot;jsp:${obj == null ? &#39;index&#39; : &#39;user.home&#39;}&amp;quot;) &#xA;//当返回值为null,相当于&#xA;@Ok(&amp;quot;jsp:index&amp;quot;)&#xA;//否则&#xA;@Ok(&amp;quot;jsp:user.index&amp;quot;)&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;@Ok和@Fail都支持完整的NutEL语法,功能强大而且灵活,不必为跳转到Fail视图而故意抛出异常了&lt;/p&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&lt;p&gt;在@Ok和@Fail中获取Request的属性值&lt;/p&gt;&#xA;&#xA;&lt;p&gt;@Ok(&amp;ldquo;jsp:${a.preURL&amp;rsquo;}&amp;ldquo;)&lt;/p&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;p&gt;待续&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>声明一下Everbox4j的相关事项</title>
      <link>http://wendal.net/279.html</link>
      <pubDate>2011-04-28 09:38:56 +0800</pubDate>
      <description>&lt;p&gt;&lt;strong&gt;1. 你是盛大的前员工/现员工吗?&lt;/strong&gt;&#xA;不是,我只是盛大Everbox的用户,最近也没打算去盛大求职,我有一份满意的工作&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;2. Everbox4j是盛大官方发布的吗?&lt;/strong&gt;&#xA;不是, everbox4j是非官方的&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;3. Everbox4j收费吗?有广告吗?&lt;/strong&gt;&#xA;免费,开源,无广告&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;4. Everbox4j能在公司里使用吗?&lt;/strong&gt;&#xA;可以免费使用,但不得用于任何非法用途&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;5. Everbox4j基于官方的公开API吗?&lt;/strong&gt;&#xA;官方没有公开的API文档,至今没有公开发布可操作的接口&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;6. Everbox4j有任何盈利方式吗?&lt;/strong&gt;&#xA;无,没有广告,顶多为我的博客增加点流量,但我的博客一样没有广告&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;7. Everbox4j能被官方接受吗?&lt;/strong&gt;&#xA;这个很难说,毕竟盛大有自己的研发团队&#xA;Everbox4j使用固定的User-Agent, 如有必要, 官方可以随时封掉.&#xA;Everbox4j的下一版本打算使用一个自己定义的User-agent, 进一步降低官方封杀的难度.&#xA;但是,我觉得,有这样一款能在Linux/Mac上跑的客户端,应该是对Everbox的发展有好处的&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;8. Everbox4j的开发动机是什么?&lt;/strong&gt;&#xA;因为我想在Ubuntu下用Everbox!! 但官方没有提供客户端,就这么简单!!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;9. Everbox4j会是长期项目吗? 有人维护吗?&lt;/strong&gt;&#xA;会,前提是盛大没把它封掉.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;10. 官方客户端是否更好? 有什么理由选Everbox4j?&lt;/strong&gt;&#xA;是的,官方的更好,因为同步机制这一块,官方研究得比较深入.&#xA;Everbox4j能在多平台下使用,这就是最好的理由.&#xA; 如果你在Linux/Mac下使用Everbox,那么Everbox4j是你当前最好的选择.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;11. Everbox4j能过滤文件名,文件大小,上传路径等,为何官方没有呢?&lt;/strong&gt;&#xA;据我观察,官方优先考虑的是同步机制,这部分难度很大啊&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Everbox4j 1.0 终于发布啦! Everbox也能在Linux/Mac上用!!</title>
      <link>http://wendal.net/276.html</link>
      <pubDate>2011-04-27 10:10:03 +0800</pubDate>
      <description>&lt;p&gt;############################################################&#xA;#&lt;strong&gt;这东西刚刚开发完,喜欢探险的童鞋欢迎使用&lt;/strong&gt;&#xA;#&lt;strong&gt;系统出现问题,文件被误删,帐号被封,本人一概不负责!!&lt;/strong&gt;&#xA;#&lt;strong&gt;胆小怕死者,老人小孩孕妇,心脏病,高血压,切勿尝试!!&lt;/strong&gt;&#xA;############################################################&lt;/p&gt;&#xA;&#xA;&lt;p&gt;奋斗了几个晚上,终于做出来了!!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;激动,终于可以安心睡个觉了!@!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;下载地址: &lt;a href=&#34;http://code.google.com/p/everbox4j/downloads/list&#34;&gt;&#xA;http://code.google.com/p/everbox4j/downloads/list&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;已知限制:&#xA;1. 如果同时开启上传和下载,只会进行上传&#xA;2. 上传模式,只会上传服务器没有的本地文件,不会执行任何删除操作&#xA;3. 下载模式,只会下载本地没有的服务器文件,不会进行任何删除操作&#xA;4. 只支持盛大帐户&lt;/p&gt;&#xA;&#xA;&lt;p&gt;使用前请确认已经安装&lt;a href=&#34;http://www.java.com&#34;&gt;Java 1.6&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;如果有任何建议或发现有bug,请留言或发送邮件到 &lt;a href=&#34;mailto:everbox4j@wendal.net?subject=我对Everbox4j有话说&#34;&gt;everbox4j@wendal.net&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;这是一款开源的,免费的,非盈利的Java程序,不得用于任何非法行为!!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&#34;{urls.media}}/2011/04/Everbox4j-1.0.jpg&#34;&gt;Everbox4j-1.0.jpg&lt;/a&gt;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>用Jsoup查台电的固件更新情况</title>
      <link>http://wendal.net/275.html</link>
      <pubDate>2011-04-26 06:13:57 +0800</pubDate>
      <description>&lt;p&gt;最近入手台电T720 Wifi,便宜货,不要跟iPad比.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;T720用的是 Android 2.1 , 比较旧, 但官方已经说了很久会出2.2的固件,哎&amp;hellip; 何年何月啊?!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;每次都上台电查,烦,决定用Jsoup写一个检查的,上代码:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;import org.jsoup.Jsoup;&#xA;import org.jsoup.nodes.Document;&#xA;import org.jsoup.nodes.Element;&#xA;import org.jsoup.select.Elements;&#xA;&#xA;public class Main {&#xA;&#xA;    public static void main(String[] args) throws Throwable {&#xA;        Document doc = Jsoup.connect(&amp;quot;http://www.teclast.com/topic.php?channelID=78&amp;amp;topicID;=148&amp;quot;).get();&#xA;        Elements es = doc.select(&amp;quot;font[color$=003399]&amp;quot;);&#xA;        String type = &amp;quot;T720&amp;quot;;//机器型号&#xA;        for (Element e : es) {&#xA;            if(!e.ownText().startsWith(type))&#xA;                continue;&#xA;            Element f = e.parent().parent().select(&amp;quot;font[color$=0000CC]&amp;quot;).first();&#xA;            if(f!= null)&#xA;                System.out.println(e.ownText() + &amp;quot; &amp;quot; + f.ownText());&#xA;        }&#xA;    }&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;打印出:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;T720 WIFI平板电脑固件下载 2011/04/12&#xA;T720 3GE平板电脑固件下载 2011/04/12&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;最后一次更新依旧是 4月12号,郁闷, 继续等吧,不时运行一下,呜呜&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Everbox4j 当前进度(2011-04-26)</title>
      <link>http://wendal.net/274.html</link>
      <pubDate>2011-04-26 09:23:12 +0800</pubDate>
      <description>&lt;p&gt;项目地址: &lt;a href=&#34;http://code.google.com/p/everbox4j/&#34;&gt;http://code.google.com/p/everbox4j/&lt;/a&gt;&#xA;源码地址: &lt;a href=&#34;http://code.google.com/p/everbox4j/source/browse/&#34;&gt;http://code.google.com/p/everbox4j/source/browse/&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;已经完成的功能:&#xA;    &lt;strong&gt;上传指定文件(不限大小)&lt;/strong&gt;&#xA;    &lt;strong&gt;下载指定文件(支持断点续传)&lt;/strong&gt;&#xA;    新建文件夹(服务器端)&#xA;    删除文件/文件夹(服务器端)&#xA;    一个简单的管理UI界面,仅界面,功能还没做,呜呜&lt;/p&gt;&#xA;&#xA;&lt;p&gt;学到不少东西:&#xA;    上传的机制 &amp;ndash; 分段上传,由服务器决定上传哪几段&#xA;    下载机制 &amp;ndash; 先发起一个下载请求,服务器分配一个下载地址&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Everbox用到的一些东西:&#xA;    Json&#xA;    Apache HttpClient&#xA;    &lt;strong&gt;OAuth&lt;/strong&gt;&#xA;    SHA1&lt;/p&gt;&#xA;&#xA;&lt;p&gt;计划:&#xA;    完成管理UI的功能,现在只有界面,就一个壳&#xA;    实现上传+下载的同步机制,现在只能处理单向的 &amp;ndash; 只上传 或 只下载&lt;/p&gt;&#xA;&#xA;&lt;p&gt;争取劳动节前发布一个版本!!&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>EverBox Java API的非官方项目启动啦!</title>
      <link>http://wendal.net/273.html</link>
      <pubDate>2011-04-21 06:21:51 +0800</pubDate>
      <description>&lt;p&gt;项目地址:&#xA;&lt;a href=&#34;http://code.google.com/p/everbox4j/&#34;&gt;http://code.google.com/p/everbox4j/&lt;/a&gt;&#xA;动机: EverBox没有公开的API(无论是Java还是Http API),Linux和Mac用户都无法使用其客户端!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;=&lt;strong&gt;最低目标&lt;/strong&gt;=&#xA;    * 实现对指定文件夹的自动同步*&lt;/p&gt;&#xA;&#xA;&lt;p&gt;=&lt;strong&gt;期望目标&lt;/strong&gt;=&#xA;  * 实现官方版大部分功能,如代理设置,同步模式设置,限速,等等&#xA;  * 更漂亮的UI&#xA;  * 更多实用功能,如可以过滤上传/下载的文件,多帐户多文件夹同步&lt;/p&gt;&#xA;&#xA;&lt;p&gt;=&lt;strong&gt;需要解决的问题&lt;/strong&gt;=&#xA;  * 获取服务器端的已存在文件列表(已经实验出来了)&#xA;  * 下载指定的文件&#xA;  * 上传指定的文件&lt;/p&gt;&#xA;&#xA;&lt;p&gt;=&lt;strong&gt;期待你的加入&lt;/strong&gt;=&#xA;  * 探索通信协议&#xA;  * 设计UI,实现UI&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;在官方实现推出来前,完成最低目标!! 加油!!&lt;/strong&gt;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Nginx与中文域名</title>
      <link>http://wendal.net/272.html</link>
      <pubDate>2011-04-17 06:36:30 +0800</pubDate>
      <description>&lt;p&gt;这个问题来自Nginx群&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Google了一轮,发现其实很简单&lt;/p&gt;&#xA;&#xA;&lt;p&gt;直接写中文域名是无法解析到正确的Server的&#xA;中文域名其实就是一个英文域名!!&#xA;中文域名 &amp;mdash;(Punycode编码) &amp;ndash;&amp;gt; 英文域名&#xA;而且,这是在浏览器实现的,你敲入 www.中文.com , 浏览器就转为 www.xn&amp;ndash;fiq228c.com 进行访问,仅此而已!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;那Punycode编码是什么呢? 先看看Python如何调用:&#xA;尝试编码  www.坚果.com&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;&#39;坚果&#39;.decode(&#39;gbk&#39;).encode(&#39;punycode&#39;)&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;得到jfs419a,然后合成真正的URL www.xn&amp;ndash;jfs419a.com &amp;ndash; 这个域名还没启用的.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;这个Punycode还是一个标准呢 &lt;a href=&#34;http://rfc-ref.org/RFC-TEXTS/3492/&#34;&gt;http://rfc-ref.org/RFC-TEXTS/3492/&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;当然还得说说中文实现, 在Apache的HttpClient 4.x系列中就有,&lt;a href=&#34;http://www.docjar.com/html/api/org/apache/http/client/utils/Rfc3492Idn.java.html&#34;&gt;看源码&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;最新发现: JDK6中已经有相应的实现 java.net.IDN&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;另外贴一下 在线转换的地址 &lt;a href=&#34;http://www.cnnic.net.cn/html/Dir/2003/10/29/1112.htm&#34;&gt;http://www.cnnic.net.cn/html/Dir/&lt;sup&gt;2003&lt;/sup&gt;&amp;frasl;&lt;sub&gt;10&lt;/sub&gt;/&lt;sup&gt;29&lt;/sup&gt;&amp;frasl;&lt;sub&gt;1112&lt;/sub&gt;.htm&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;所有,把中文域名转一下,按普通英文域名来配置就OK了!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;奉劝一句, 离中文域名越远越好!!!&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>学习Java时需要掌握的一些技能</title>
      <link>http://wendal.net/270.html</link>
      <pubDate>2011-04-16 09:45:20 +0800</pubDate>
      <description>&lt;p&gt;本文并不涉及语法/具体API,就是一些学习方法&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;1. 找不到XXX类&lt;/strong&gt;&#xA;学习Java的路上,找不到类简直就是家常便饭,故,快速找到需要的类非常关键&#xA;&lt;a href=&#34;http://www.findjar.com&#34;&gt;Findjar&lt;/a&gt; 输入类名,一般都能找到&#xA;&lt;a href=&#34;http://repo1.maven.org/maven2/&#34;&gt;Maven repo&lt;/a&gt; 如果能猜到大概的项目,通过Maven中央库肯定是最权威的&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;2. 学习XXX框架&lt;/strong&gt;&#xA;在这个框架满天飞的时代,不懂几个框架都不好意思说是玩Java的&#xA;但是,以下事情你是否做过呢:&#xA;A. 从源码编译过&#xA;B. 跑过官方测试&#xA;C. 瞄过源码&lt;/p&gt;&#xA;&#xA;&lt;p&gt;找一个好的社区,一起看源码,是很开心的事哦&#xA;知其然,也要知其所以然&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;3. 找Bug的方法&lt;/strong&gt;&#xA;你马上就开始debug了? No! No! 请把debug放到最后,当成无计可施的最后手段&#xA;System.out.println()才是真正的利器!!&#xA;你马上会反驳,println很耗时间的 &amp;ndash; 是的,但帮你理清思路&#xA;通过println,打印变量的值/应该经过的分支,帮你一步步理清思路&#xA;使用Debug往往是最快解决问题的,但也是最容易让你无法找到问题的根源&#xA;良好的Log,是生产环境中必不可少的信息&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;4. 常备API&lt;/strong&gt;&#xA;原本打算列长长的表格,但最近发现Oschina首页就有API链接&#xA;&lt;a href=&#34;http://www.oschina.net/&#34;&gt;http://www.oschina.net/&lt;/a&gt;&#xA;页面下方就是 &amp;ldquo;常用API文档&amp;rdquo;,比较齐全&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;5. 分清楚问题的原因&lt;/strong&gt;&#xA;很多时候,Java程序的问题,更多的是API的问题,而非语法问题&#xA;但很多情况下,初学者多以为是语法问题&lt;/p&gt;&#xA;&#xA;&lt;p&gt;我简单想出几种类型: 语法问题,编译器导致的语法现象(如自动封包/解包,泛型),API问题,具体操作系统的问题&lt;/p&gt;&#xA;&#xA;&lt;p&gt;暂时就想到这么多,呵呵,看来是遇到特定场景才容易想到.&#xA;最近迷上录视频,嘻嘻,已经为Nutz录了两集,尽快跟进其他内容.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>启用新的域名 wendal.net</title>
      <link>http://wendal.net/268.html</link>
      <pubDate>2011-04-14 11:39:26 +0800</pubDate>
      <description>&lt;p&gt;为了XXXXX&#xA;为了XXXXX&#xA;为了XXXXX&lt;/p&gt;&#xA;&#xA;&lt;p&gt;我昨晚在godaddy购买了wendal.net,并指向我的博客,花了72.04元,还不错,呵呵&lt;/p&gt;&#xA;&#xA;&lt;p&gt;另外,开始进行sunfarms.net的域名外迁工作,万网已经在审核&lt;/p&gt;&#xA;&#xA;&lt;p&gt;呵呵,常出去走走,身体健康哦&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Json格式的ngx_http_stub_status_module</title>
      <link>http://wendal.net/267.html</link>
      <pubDate>2011-04-13 07:07:47 +0800</pubDate>
      <description>&lt;p&gt;原版的ngx_http_stub_status_module,查看到的状态信息是一个无格式文本,非常不好解析.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;网上有另外一些实现,例如&lt;a href=&#34;https://github.com/drmingdrmer/nginx-json-status-module&#34;&gt;nginx-json-status-module&lt;/a&gt;,但实现得极其垃圾,竟然直接调用malloc. 另外为了庆贺一下Nginx 1.0.0版本的发布,我做了一些修改,使其以Json格式返回.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;上代码:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;/*&#xA; * Copyright (C) Igor Sysoev&#xA; * Modify by Wendal Chen&#xA; */&#xA;&#xA;#include &amp;lt;ngx_config.h&amp;gt;&#xA;#include &amp;lt;ngx_core.h&amp;gt;&#xA;#include &amp;lt;ngx_http.h&amp;gt;&#xA;&#xA;static char *ngx_http_set_status(ngx_conf_t *cf, ngx_command_t *cmd,&#xA;                                 void *conf);&#xA;&#xA;static ngx_command_t  ngx_http_status_commands[] = {&#xA;&#xA;    { ngx_string(&amp;quot;stub_status&amp;quot;),&#xA;      NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,&#xA;      ngx_http_set_status,&#xA;      0,&#xA;      0,&#xA;      NULL },&#xA;&#xA;      ngx_null_command&#xA;};&#xA;&#xA;static ngx_http_module_t  ngx_http_stub_status_module_ctx = {&#xA;    NULL,                                  /* preconfiguration */&#xA;    NULL,                                  /* postconfiguration */&#xA;&#xA;    NULL,                                  /* create main configuration */&#xA;    NULL,                                  /* init main configuration */&#xA;&#xA;    NULL,                                  /* create server configuration */&#xA;    NULL,                                  /* merge server configuration */&#xA;&#xA;    NULL,                                  /* create location configuration */&#xA;    NULL                                   /* merge location configuration */&#xA;};&#xA;&#xA;ngx_module_t  ngx_http_stub_status_module = {&#xA;    NGX_MODULE_V1,&#xA;    &amp;amp;ngx;_http_stub_status_module_ctx,      /* module context */&#xA;    ngx_http_status_commands,              /* module directives */&#xA;    NGX_HTTP_MODULE,                       /* module type */&#xA;    NULL,                                  /* init master */&#xA;    NULL,                                  /* init module */&#xA;    NULL,                                  /* init process */&#xA;    NULL,                                  /* init thread */&#xA;    NULL,                                  /* exit thread */&#xA;    NULL,                                  /* exit process */&#xA;    NULL,                                  /* exit master */&#xA;    NGX_MODULE_V1_PADDING&#xA;};&#xA;&#xA;static ngx_int_t ngx_http_status_handler(ngx_http_request_t *r)&#xA;{&#xA;    size_t             size;&#xA;    ngx_int_t          rc;&#xA;    ngx_buf_t         *b;&#xA;    ngx_chain_t        out;&#xA;    ngx_atomic_int_t   ap, hn, ac, rq, rd, wr;&#xA;&#xA;    if (r-&amp;gt;method != NGX_HTTP_GET &amp;amp;&amp;amp; r-&amp;gt;method != NGX_HTTP_HEAD) {&#xA;        return NGX_HTTP_NOT_ALLOWED;&#xA;    }&#xA;&#xA;    rc = ngx_http_discard_request_body(r);&#xA;&#xA;    if (rc != NGX_OK) {&#xA;        return rc;&#xA;    }&#xA;&#xA;    ngx_str_set(&amp;amp;r-;&amp;gt;headers_out.content_type, &amp;quot;text/plain&amp;quot;);&#xA;&#xA;    if (r-&amp;gt;method == NGX_HTTP_HEAD) {&#xA;        r-&amp;gt;headers_out.status = NGX_HTTP_OK;&#xA;&#xA;        rc = ngx_http_send_header(r);&#xA;&#xA;        if (rc == NGX_ERROR || rc &amp;gt; NGX_OK || r-&amp;gt;header_only) {&#xA;            return rc;&#xA;        }&#xA;    }&#xA;&#xA;    size = sizeof(&amp;quot;{accepted:,handled:,active:,requests:,reading:,writing:}&amp;quot;) + 7 * NGX_ATOMIC_T_LEN;&#xA;&#xA;    b = ngx_create_temp_buf(r-&amp;gt;pool, size);&#xA;    if (b == NULL) {&#xA;        return NGX_HTTP_INTERNAL_SERVER_ERROR;&#xA;    }&#xA;&#xA;    out.buf = b;&#xA;    out.next = NULL;&#xA;&#xA;    ap = *ngx_stat_accepted;&#xA;    hn = *ngx_stat_handled;&#xA;    ac = *ngx_stat_active;&#xA;    rq = *ngx_stat_requests;&#xA;    rd = *ngx_stat_reading;&#xA;    wr = *ngx_stat_writing;&#xA;&#xA;    b-&amp;gt;last = ngx_sprintf(b-&amp;gt;last, &amp;quot;{accepted:%uA,handled:%uA,active:%uA,requests:%uA,reading:%uA,writing:%uA}&amp;quot;, &#xA;                                               ap,         hn,        ac,         rq,           rd,         wr);&#xA;&#xA;    r-&amp;gt;headers_out.status = NGX_HTTP_OK;&#xA;    r-&amp;gt;headers_out.content_length_n = b-&amp;gt;last - b-&amp;gt;pos;&#xA;&#xA;    b-&amp;gt;last_buf = 1;&#xA;&#xA;    rc = ngx_http_send_header(r);&#xA;&#xA;    if (rc == NGX_ERROR || rc &amp;gt; NGX_OK || r-&amp;gt;header_only) {&#xA;        return rc;&#xA;    }&#xA;&#xA;    return ngx_http_output_filter(r, &amp;amp;out;);&#xA;}&#xA;&#xA;static char *ngx_http_set_status(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)&#xA;{&#xA;    ngx_http_core_loc_conf_t  *clcf;&#xA;&#xA;    clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);&#xA;    clcf-&amp;gt;handler = ngx_http_status_handler;&#xA;&#xA;    return NGX_CONF_OK;&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;使用方法&#xA;1. 直接替换原本的文件&#xA;2. 修改一下ngx_string(&amp;ldquo;stub_status&amp;rdquo;)为ngx_string(&amp;ldquo;json_stub_status&amp;rdquo;),配合一下config文件一起作为额外模块进行编译:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;ngx_addon_name=ngx_http_json_stub_status_module&#xA;HTTP_AUX_FILTER_MODULES=&amp;quot;$HTTP_AUX_FILTER_MODULES ngx_http_json_stub_status_module&amp;quot;&#xA;NGX_ADDON_SRCS=&amp;quot;$NGX_ADDON_SRCS $ngx_addon_dir/ngx_http_json_stub_status_module.c&amp;quot;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&#34;https://docs.google.com/leaf?id=0B8hUXYDeoy_hMDJjYmUzNTktMTQyNi00MzdjLTk0YzYtMDcxYzY1NWU2MDA2&#34;&gt;下载Zip包&lt;/a&gt;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>再一次搞定UTF-8的BOM</title>
      <link>http://wendal.net/266.html</link>
      <pubDate>2011-04-12 06:55:43 +0800</pubDate>
      <description>&lt;p&gt;一年前的某天,我觉察到BOM的问题 &amp;ndash; 一个Java源文件死活无法编译&#xA;今天,我狠狠地为 Nutz的Streams类添加了一个方法,用于自动过滤掉BOM头!!&#xA;代码如下:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;private static final byte[] UTF_BOM = new byte[]{(byte) 0xEF,(byte) 0xBB,(byte) 0xBF};&#xA;&#xA;/**&#xA; * 判断并移除UTF-8的BOM头&#xA;*/&#xA;public static InputStream utf8filte(InputStream in) {&#xA;    try {&#xA;        PushbackInputStream pis = new PushbackInputStream(in,3);&#xA;        byte[] header = new byte[3];&#xA;        pis.read(header,0,3);&#xA;        if(header[0] != UTF_BOM[0] || header[1] != UTF_BOM[1] || header[2] != UTF_BOM[2]) {&#xA;            pis.unread(header,0,3);&#xA;        }&#xA;        return pis;&#xA;    } catch (IOException e) {&#xA;        throw Lang.wrapThrow(e);&#xA;    }&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;希望以后能少遇到些&lt;/p&gt;&#xA;&#xA;&lt;p&gt;原本是打算改NutzDoc的代码的,因为我写的一些文档包含了BOM头,读取的时候,NutzDoc无视第一行(标题行),直接认为是文本,导致没有标题!!!!&#xA;后来,觉得这完全是共性问题,任何读取UTF8格式的代码都会遇到,故决定添加上述方法!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;PS: Nginx 出 1.0.0了,神了!!! 版本号什么的都是浮云啊!!!!!!!!!!!!&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Logger对象是否会重复创建呢? (以Log4j为例)</title>
      <link>http://wendal.net/263.html</link>
      <pubDate>2011-04-05 08:51:34 +0800</pubDate>
      <description>&lt;p&gt;不久前有人问及 重复调用Logger.getLogger之类的语句,是否会拿到不同的Logger对象呢?&#xA;起初我并未在意,但现在觉得是应该探究一下.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;故,先是设计这样的代码:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;import org.apache.log4j.Logger;&#xA;public class LogTest {&#xA;&#xA;    public static void main(String[] args) {&#xA;        Logger log = Logger.getLogger(LogTest.class);&#xA;        Logger log2 = Logger.getLogger(LogTest.class);&#xA;        System.out.println(log == log2);&#xA;    }&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;log4j.properties文件的内容:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;log4j.rootLogger=DEBUG,Console&#xA;log4j.appender.Console=org.apache.log4j.ConsoleAppender&#xA;log4j.appender.Console.layout=org.apache.log4j.PatternLayout&#xA;log4j.appender.Console.layout.ConversionPattern=log4j: %d [%t] %-5p %c - %m%n&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;打印的结果是true,即同一个Log对象&lt;/p&gt;&#xA;&#xA;&lt;p&gt;恩,为什么呢?? 好,下载源码.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;经过简单探寻,找到关键代码,位于org.apache.log4j.Hierarchy类:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;  public&#xA;  Logger getLogger(String name, LoggerFactory factory) {&#xA;    //System.out.println(&amp;quot;getInstance(&amp;quot;+name+&amp;quot;) called.&amp;quot;);&#xA;    CategoryKey key = new CategoryKey(name);&#xA;    // Synchronize to prevent write conflicts. Read conflicts (in&#xA;    // getChainedLevel method) are possible only if variable&#xA;    // assignments are non-atomic.&#xA;    Logger logger;&#xA;&#xA;    synchronized(ht) {&#xA;      Object o = ht.get(key);&#xA;      if(o == null) {&#xA;    logger = factory.makeNewLoggerInstance(name);&#xA;    logger.setHierarchy(this);&#xA;    ht.put(key, logger);&#xA;    updateParents(logger);&#xA;    return logger;&#xA;      } else if(o instanceof Logger) {&#xA;    return (Logger) o;&#xA;      } else if (o instanceof ProvisionNode) {&#xA;    //System.out.println(&amp;quot;(&amp;quot;+name+&amp;quot;) ht.get(this) returned ProvisionNode&amp;quot;);&#xA;    logger = factory.makeNewLoggerInstance(name);&#xA;    logger.setHierarchy(this);&#xA;    ht.put(key, logger);&#xA;    updateChildren((ProvisionNode) o, logger);&#xA;    updateParents(logger);&#xA;    return logger;&#xA;      }&#xA;      else {&#xA;    // It should be impossible to arrive here&#xA;    return null;  // but let&#39;s keep the compiler happy.&#xA;      }&#xA;    }&#xA;  }&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;以上代码简单含义为,构建一个查询的key,然后获取特定的Logger对象,如果没有就创建它&lt;/p&gt;&#xA;&#xA;&lt;p&gt;问题又来啦,按照上述代码,获取Logger对象的过程,是一个同步过程,因为写着synchronized(ht) 呢!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;另外说一句,按照当前的Nutz.Log实现,每次调用getLog都是返回新的Logger封装对象哦,不过这个对象只有一个变量,就是实际的logger,故,内存消耗依旧很小的.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>神奇的Slf4J-API版本 - 2.0.99</title>
      <link>http://wendal.net/262.html</link>
      <pubDate>2011-04-03 12:29:03 +0800</pubDate>
      <description>&lt;p&gt;今天,一位群友&amp;rdquo;我思&amp;rdquo;,在组合使用slf4j和logback时报一下错误:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;Exception in thread &amp;quot;main&amp;quot; java.lang.NoSuchMethodError: org.slf4j.helpers.MessageFormatter.arrayFormat(Ljava/lang/String;[Ljava/lang/Object;)Lorg/slf4j/helpers/FormattingTuple;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;最后发现是slf4j的版本不对, 他使用的是slf4j-api-2.0.99.jar&lt;/p&gt;&#xA;&#xA;&lt;p&gt;但是,但是,官方正式版只有1.6.1,而且至今我都没发现有2.0.x系列的计划呢!!&#xA;我的神啊,哪里来的版本? 经提醒,这个jar就在 1.6.1版的发行包中!!  slf4j-1.6.1.zip\slf4j-1.6.1\integration\lib&lt;/p&gt;&#xA;&#xA;&lt;p&gt;神奇啊,为啥呢?? 找不到其源码jar,好吧,上JD-GUI,看看报错的类MessageFormatter.arrayFormat&#xA;2.0.99版的方法声明:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;public static final String arrayFormat(String messagePattern, Object[] argArray)&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;1.6.1版的方法声明:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;public static final FormattingTuple arrayFormat(String messagePattern, Object[] argArray)&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;看到区别了吧,返回值的类型不同了!!! 同样的,还有一个1.6.99版的API,内容与2.0.99版一致&lt;/p&gt;&#xA;&#xA;&lt;p&gt;继续追查, 看Slf4j源码仓库的一个提交:&#xA;&lt;a href=&#34;https://github.com/ceki/slf4j/commit/581b20f8aaa140ce722669a2cf1d8582a963ff4e&#34;&gt;https://github.com/ceki/slf4j/commit/581b20f8aaa140ce722669a2cf1d8582a963ff4e&lt;/a&gt;&#xA;里面的comments是:&#xA;&#xA;- fixed bug 154&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;It is expected that all SLF4J releases in the 1.6.x and 2.0.x series&#xA;will be mutually compatible. Note that the 2.0.x series is expected to&#xA;require JDK 1.5 or later.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;兼容旧版本?? 明显就是不兼容嘛!!! 但 bug 154 到底是什么内容呢?&lt;/p&gt;&#xA;&#xA;&lt;p&gt;几经查找,终于找到其issue系统的地址,是个bugzilla呢 &amp;ndash; 天啊,官网一个网站,下载一个网站,源码管理一个网站,issue管理又是再一个网站?!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&#34;http://bugzilla.slf4j.org/show_bug.cgi?id=154&#34;&gt;http://bugzilla.slf4j.org/show_bug.cgi?id=154&lt;/a&gt;&#xA;但内容感觉与 2.0.x无关呢.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>发布一个Httpsqs的Python客户端</title>
      <link>http://wendal.net/261.html</link>
      <pubDate>2011-04-01 09:04:15 +0800</pubDate>
      <description>&lt;p&gt;Httpsqs是张宴的一款开源队列服务器,项目首页 &lt;a href=&#34;http://code.google.com/p/httpsqs/&#34;&gt;http://code.google.com/p/httpsqs/&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;这款软件有几种客户端, Java/Perl/C,却没有Python的客户端.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;故,本人奉上一个实现,欢迎指正!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;直接去下载 &lt;a href=&#34;http://wendal-common.googlecode.com/files/httpsqs-python-client-v1.zip&#34;&gt;httpsqs-python-client-v1.zip&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;代码:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;#Verion 1.0&#xA;#Author wendal(wendal1985@gmail.com)&#xA;#If you find a bug, pls mail me&#xA;&#xA;import sys,httplib&#xA;&#xA;ERROR = &#39;HTTPSQS_ERROR&#39;&#xA;&#xA;GET_END = &#39;HTTPSQS_GET_END&#39;&#xA;&#xA;PUT_OK = &#39;HTTPSQS_PUT_OK&#39;&#xA;PUT_ERROR = &#39;HTTPSQS_PUT_ERROR&#39;&#xA;PUT_END = &#39;HTTPSQS_PUT_END&#39;&#xA;&#xA;RESET_OK = &#39;HTTPSQS_RESET_OK&#39;&#xA;RESET_ERROR = &#39;HTTPSQS_RESET_ERROR&#39;&#xA;&#xA;MAXQUEUE_OK = &#39;HTTPSQS_MAXQUEUE_OK&#39;&#xA;MAXQUEUE_CANCEL = &#39;HTTPSQS_MAXQUEUE_CANCEL&#39;&#xA;&#xA;SYNCTIME_OK = &#39;HTTPSQS_SYNCTIME_OK&#39;&#xA;SYNCTIME_CANCEL = &#39;HTTPSQS_SYNCTIME_CANCEL&#39;&#xA;&#xA;class Httpsqs(object):&#xA;    def __init__(self,host,port=1218):&#xA;        self.host = host&#xA;        self.port = port&#xA;&#xA;    def get(self,poolName):&#xA;        conn = httplib.HTTPConnection(self.host,self.port)&#xA;        conn.request(&amp;quot;GET&amp;quot;, &amp;quot;/?opt=get&amp;amp;name;=&amp;quot; + poolName)&#xA;        r = conn.getresponse()&#xA;        if r.status == httplib.OK :&#xA;            data = r.read()&#xA;            conn.close()&#xA;            return data&#xA;        return &#39;&#39;&#xA;&#xA;    def put(self,poolName,data):&#xA;        conn = httplib.HTTPConnection(self.host,self.port)&#xA;        conn.request(&amp;quot;POST&amp;quot;, &amp;quot;/?opt=put&amp;amp;name;=&amp;quot;+poolName,data)&#xA;        r = conn.getresponse()&#xA;        if r.status == httplib.OK :&#xA;            data = r.read()&#xA;            return data&#xA;        return &#39;&#39;&#xA;&#xA;    def status(self,poolName):&#xA;        conn = httplib.HTTPConnection(self.host,self.port)&#xA;        conn.request(&amp;quot;GET&amp;quot;, &amp;quot;/?opt=status&amp;amp;name;=&amp;quot;+poolName)&#xA;        r = conn.getresponse()&#xA;        if r.status == httplib.OK :&#xA;            data = r.read()&#xA;            return data&#xA;        return &#39;&#39;&#xA;&#xA;    def status_json(self,poolName):&#xA;        conn = httplib.HTTPConnection(self.host,self.port)&#xA;        conn.request(&amp;quot;GET&amp;quot;, &amp;quot;/?opt=status_json&amp;amp;name;=&amp;quot;+poolName)&#xA;        r = conn.getresponse()&#xA;        if r.status == httplib.OK :&#xA;            data = r.read()&#xA;            return data&#xA;        return &#39;&#39;&#xA;&#xA;    def reset(self,poolName):&#xA;        conn = httplib.HTTPConnection(self.host,self.port)&#xA;        conn.request(&amp;quot;GET&amp;quot;, &amp;quot;/?opt=reset&amp;amp;name;=&amp;quot;+poolName)&#xA;        r = conn.getresponse()&#xA;        if r.status == httplib.OK :&#xA;            data = r.read()&#xA;            return data&#xA;        return &#39;&#39;&#xA;&#xA;    def maxlen(self,poolName,num):&#xA;        conn = httplib.HTTPConnection(self.host,self.port)&#xA;        conn.request(&amp;quot;GET&amp;quot;, &amp;quot;/?opt=maxqueue&amp;amp;name;=&amp;quot;+poolName+&amp;quot;&amp;amp;num;=&amp;quot;+str(num))&#xA;        r = conn.getresponse()&#xA;        if r.status == httplib.OK :&#xA;            data = r.read()&#xA;            return data&#xA;        return &#39;&#39;&#xA;&#xA;    def synctime(self,poolName,num):&#xA;        conn = httplib.HTTPConnection(self.host,self.port)&#xA;        conn.request(&amp;quot;GET&amp;quot;, &amp;quot;/?opt=synctime&amp;amp;name;=&amp;quot;+poolName+&amp;quot;&amp;amp;num;=&amp;quot;+str(num))&#xA;        r = conn.getresponse()&#xA;        if r.status == httplib.OK :&#xA;            data = r.read()&#xA;            return data&#xA;        return &#39;&#39;&#xA;&#xA;def isOK(data):&#xA;    if data is &#39;&#39; :&#xA;        return False&#xA;    if data is ERROR :&#xA;        return False&#xA;    if data is GET_END :&#xA;        return False&#xA;    if data is PUT_ERROR :&#xA;        return False&#xA;    if data is RESET_ERROR :&#xA;        return False&#xA;    if data is MAXQUEUE_CANCEL :&#xA;        return False&#xA;    if data is SYNCTIME_CANCEL :&#xA;        return False&#xA;    return True&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;测试代码就不贴,需要的话就下载zip包吧.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;因为Httpsqs本身就是基于Http协议的,故各种客户端实现都只是封装一下,本python客户端也不例外.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>TMD美赞臣,竟敢打电话过来推销奶粉!!</title>
      <link>http://wendal.net/260.html</link>
      <pubDate>2011-03-30 07:19:03 +0800</pubDate>
      <description>&lt;p&gt;怒了! 彻底怒了!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;电话: 020-62610328&#xA;竟然推销美赞臣奶粉,竟然说母乳质量差!!! TMD你这是啥垃圾奶粉?!!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;我靠!! 找死啊?!!!!!!!! TMD想害我女儿!!! 还有没有人性啊??!!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;美赞臣,肯定说这是临时工,这不是我们公司的!! 靠,电话里只推销&amp;rdquo;美赞臣&amp;rdquo;,难道还有人特意害你啊!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;再敢打来就直接开骂!!!!!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;好,先去查一下WHO的投诉邮件地址!!!!&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>HTTPSQS源码初探</title>
      <link>http://wendal.net/259.html</link>
      <pubDate>2011-03-28 09:34:39 +0800</pubDate>
      <description>&lt;p&gt;官网: &lt;a href=&#34;http://code.google.com/p/httpsqs/&#34;&gt;http://code.google.com/p/httpsqs/&lt;/a&gt;&#xA;一句话介绍: HTTPSQS is a Simple Queue Service based on HTTP GET/POST protocol&#xA;               HTTPSQS（HTTP Simple Queue Service）是一款基于 HTTP GET/POST 协议的轻量级开源简单消息队列服务&lt;/p&gt;&#xA;&#xA;&lt;p&gt;其实以前就安装过这款队列实现,也简单测试过,但今天第一次看源码,呵呵&lt;/p&gt;&#xA;&#xA;&lt;p&gt;源码就一个C文件 httpsqs.c , 外加一个MakeFile文件&lt;/p&gt;&#xA;&#xA;&lt;p&gt;代码大概800行,原本以为是个很复杂的东西,最后才发现,真的如其中文介绍一样:&#xA;使用 Tokyo Cabinet 的 B+Tree Key/Value 数据库来做数据的持久化存储&lt;/p&gt;&#xA;&#xA;&lt;p&gt;我的理解就是一个Key/Value服务器的Http界面&lt;/p&gt;&#xA;&#xA;&lt;p&gt;原本打算写点代码分析的,但源码上的注解太详细,算了,不写了,把方法列一下:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;/* 全局设置 */&#xA;TCBDB *httpsqs_db_tcbdb; /* 数据表 */&#xA;int httpsqs_settings_syncinterval; /* 同步更新内容到磁盘的间隔时间 */&#xA;char *httpsqs_settings_pidfile; /* PID文件 */&#xA;&#xA;/* 创建多层目录的函数 */&#xA;void create_multilayer_dir( char *muldir ) ;&#xA;/* URL解码 */&#xA;char *urldecode(char *input_str) ;&#xA;/* 显示帮助信息 */&#xA;static void show_help(void);&#xA;&#xA;/* 读取队列写入点的值 */&#xA;static int httpsqs_read_putpos(const char* httpsqs_input_name);&#xA;/* 读取队列读取点的值 */&#xA;static int httpsqs_read_getpos(const char* httpsqs_input_name);&#xA;/* 读取用于设置的最大队列数 */&#xA;static int httpsqs_read_maxqueue(const char* httpsqs_input_name);&#xA;/* 设置最大的队列数量，返回值为设置的队列数量。如果返回值为0，则表示设置取消（取消原因为：设置的最大的队列数量小于”当前队列写入位置点“和”当前队列读取位置点“，或者”当前队列写入位置点“小于”当前队列的读取位置点） */&#xA;static int httpsqs_maxqueue(const char* httpsqs_input_name, int httpsqs_input_num);&#xA;/* 重置队列，0表示重置成功 */&#xA;static int httpsqs_reset(const char* httpsqs_input_name);&#xA;/* 查看单条队列内容 */&#xA;char *httpsqs_view(const char* httpsqs_input_name, int pos);&#xA;/* 修改定时更新内存内容到磁盘的间隔时间，返回间隔时间（秒） */&#xA;static int httpsqs_synctime(int httpsqs_input_num);&#xA;/* 获取本次“入队列”操作的队列写入点 */&#xA;static int httpsqs_now_putpos(const char* httpsqs_input_name);&#xA;/* 获取本次“出队列”操作的队列读取点，返回值为0时队列全部读取完成 */&#xA;static int httpsqs_now_getpos(const char* httpsqs_input_name);&#xA;/* 处理模块 */&#xA;void httpsqs_handler(struct evhttp_request *req, void *arg);&#xA;/* 信号处理,关闭信号,保存内存数据 */&#xA;static void kill_signal(const int sig);&#xA;/* 定时信号处理，定时将内存中的内容写入磁盘 */&#xA;static void sync_signal(const int sig);&#xA;&#xA;/* 入口方法 */&#xA;int main(int argc, char **argv);&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;功能就和一个Memcached服务器差不多.&#xA;恩,考虑做个Nginx的模块,哈哈.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>[求助]CHM文件的格式,我疑惑了!!!</title>
      <link>http://wendal.net/258.html</link>
      <pubDate>2011-03-28 12:39:57 +0800</pubDate>
      <description>&lt;p&gt;这几天想做一个CHM文件的Java读写库,困困研读这种非公开的文件格式.&#xA;参考了一篇外国人写的文档 &lt;a href=&#34;http://www.russotto.net/chm/chmformat.html&#34;&gt;Microsoft&amp;rsquo;s HTML Help (.chm) format&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;按照其规律一步步构建POJO, 结果被一个ENCINT类型难住了,实在搞不懂如何解析,呜呜:&lt;/p&gt;&#xA;&#xA;&lt;p&gt;原文:&#xA;&#xA;Encoded Integers&lt;/p&gt;&#xA;&#xA;&lt;p&gt;An ENCINT is a variable-length integer. The high bit of each byte indicates &amp;ldquo;continued to the next byte&amp;rdquo;. Bytes are stored most significant to least significant. So, for example, $EA $15 is (((0xEA&amp;amp;0x7F)&amp;lt; &amp;lt;7)|0x15) = 0x3515.&#xA;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;严重崩溃中, 求帮助啊!!&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>总结一下最近Nginx模块开发走过的弯路</title>
      <link>http://wendal.net/257.html</link>
      <pubDate>2011-03-22 08:42:00 +0800</pubDate>
      <description>&lt;p&gt;整了快一个月了,是时候总结一下:&lt;/p&gt;&#xA;&#xA;&lt;p&gt;教训:&#xA;1. 在虚拟机下编译Nginx&#xA;算是犯的第一个错误, 环境如下: Window + 虚拟机中的Ubuntu, nginx等文件放在windows的一个文件夹中, Ubuntu使用vbox的数据空间进行访问.&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;p&gt;一开始并未察觉,因为觉得编译个东西, 几分钟,很正常吧.&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;后来,做出一部分功能,开始测试. 用ab压, 总是几百req/s ,非常不爽,不应该是这种性能!!&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;无意中,改为单worker进程, 竟然效果更好, 而且ab占用的cpu比nginx还高!!&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;开始怀疑虚拟机的性能,决定用wubi安装一个&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;安装好,例行编译,靠!! 咋一会就搞定了?! 用ab压,晕死,直接上10k req/s了,而且依旧ab的cpu比nginx高!!&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;在Lua中习惯性写分号,习惯性忘记写end&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;开头,基本上每行都不自觉地敲上分号&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;每每写if语句,总是忘记写then和end&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;好久之后才发现连接字符串,其实用..就可以了,之前一直用string.format&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;以Java的想法写C&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;一开始看到echo/lua模块每几行就判断一下是否为NULL/NGX_ERROR,觉得很多余,分配内存都要check一下,结果,杯具开始了&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;指针满天飞,至今还没适应过来&lt;/p&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;其他一些零碎的问题:&#xA;1. lua-nginx-module 0.1.6rc2有个bug,折腾了2天,最后知道是bug&#xA;2. 用google-pretools工具分析性能,结果发现根本还不需要到这一步,因为ab的cpu比nginx还高!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;经验:&#xA;最大的经验就是 如果无需对请求体进行复杂处理(例如upload),以下组合可以说无敌了:&#xA;nginx + lua-nginx-module + drizzle-nginx-module + rds-json-nginx-module&lt;/p&gt;&#xA;&#xA;&lt;p&gt;使用标准nginx处理静态文件,不是一般的快和强大&#xA;drizzle + rds-json负责访问mysql数据, 速度非常快&#xA;使用lua处理逻辑,灵活而且非常快&lt;/p&gt;&#xA;&#xA;&lt;p&gt;一般的增删改查,都可以用上面的组合完成,无需Java/PHP的参与&lt;/p&gt;&#xA;&#xA;&lt;p&gt;暂时想到这么多, 另外,我在翻译lua-nginx-module的手册.虽说lua-nginx-module是国人写的,但一直没有找到中文手册,其英文文档虽然能看懂,但查找非常不便. 嘻嘻,值得期待哦&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>想不到还有这种SSH客户端- FireSSH</title>
      <link>http://wendal.net/256.html</link>
      <pubDate>2011-03-22 06:56:44 +0800</pubDate>
      <description>&lt;p&gt;在oschina中无意中看到的, 在Firefox里面使用ssh!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;简单使用:&#xA;1. 访问&lt;a href=&#34;http://firessh.mozdev.org/&#34;&gt;FireSSH主页&lt;/a&gt;&#xA;2. 安装,并重启Firefox&#xA;3. 在菜单中选择FireSSH,启动,输入ip/帐户/密码,登陆!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;马上就是 SSH的经典黑屏了,哈哈&lt;/p&gt;&#xA;&#xA;&lt;p&gt;只有想不到,没有做不到啊&amp;hellip;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;回想以前,曾尝试在手机上安装一个ssh客户端, 就为了随时随地访问 客户的服务器排除问题,哈哈&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>[已经确认]想不到真的遇到Lua-nginx-module的bug</title>
      <link>http://wendal.net/255.html</link>
      <pubDate>2011-03-17 03:32:15 +0800</pubDate>
      <description>&lt;p&gt;难以置信啊, agentzh大牛已经确认是个bug,对应的版本:&#xA;Lua-nginx-module 0.16rc2 + Nginx 0.8.54&lt;/p&gt;&#xA;&#xA;&lt;p&gt;期待修复,哈哈&lt;/p&gt;&#xA;&#xA;&lt;p&gt;原本一直以为是自己代码的原因,因为实在很诡异,附上我的原文:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;我得到的最小集合就是:&#xA;1. nginx.conf&#xA;location /test {&#xA;    root html;&#xA;    content_by_lua_file &amp;quot;conf/test.lua&amp;quot;;&#xA;}&#xA;server/http等配置按默认的, event module用的是 epoll&#xA;&#xA;2. test.lua文件仅2行:&#xA;ngx.location.capture(&#39;/1.html&#39;)&#xA;&#xA;ngx.exec(&amp;quot;/1.html&amp;quot;)&#xA;&#xA;我尝试过,无论这两句话是否请求同一个文件,结果都一样.&#xA;&#xA;3. 1.html文件里面仅有几个字母,我已经试过不同的文件大小,结果一样&#xA;&#xA;我遇到的情况是这样的:&#xA;1. 通过wget/curl/Firefox来访问 localhost/test 都能正常显示1.html中的内容&#xA;2. 使用ab访问 localhost/1.html是正常的,能够pass&#xA;3. 使用ab进行测试,总是timeout , 我使用的语句是 ab -v 5 localhost/test &#xA;Benchmarking localhost (be patient)...INFO: POST header ==&#xA;---&#xA;GET /down2 HTTP/1.0&#xA;Host: localhost&#xA;User-Agent: ApacheBench/2.3&#xA;Accept: */*&#xA;&#xA;---&#xA;LOG: header received:&#xA;HTTP/1.1 200 OK&#xA;Server: nginx/0.8.54&#xA;Date: Tue, 15 Mar 2011 07:22:30 GMT&#xA;Content-Type: text/plain&#xA;Content-Length: 4&#xA;&#xA;Last-Modified: Fri, 11 Mar 2011 09:32:28 GMT&#xA;Connection: close&#xA;Accept-Ranges: bytes&#xA;&#xA;ABC&#xA;&#xA;LOG: Response code = 200&#xA;apr_poll: The timeout specified has expired (70007)&#xA;&#xA;其中的ABC就是1.html的内容, 非常抱歉我之前写错了.&#xA;&#xA;对于0A0D的描述,仅仅是我的猜测,请无视之.&#xA;&#xA;单独写 ngx.exec(&amp;quot;/1.html&amp;quot;) 也是能够通过ab测试的.&#xA;&#xA;环境:&#xA;Ubuntu 10.10&#xA;Luajit-5.1-dev&#xA;Nginx 0.8.54&#xA;Lua-nginx-module 0.16rc2&#xA;&#xA;Thanks,&#xA;Wendal Chen&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;agentzh的回应是:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;I&#39;ve reproduced it on my side. This is indeed a bug. When ngx.exec()&#xA;is used after ngx.location.capture() or ngx.location.capture_multi(),&#xA;nginx 0.8.11+ will not close the client connection due to leaked&#xA;request reference counter (r-&amp;gt;main-&amp;gt;count). A hacky work-around is to&#xA;disable nginx http keepalive and rely on the browser (and other http&#xA;clients) to actively close the connection. And that&#39;s why wget, curl,&#xA;firefox, and other well-written http clients worked for you.&#xA;&#xA;Nginx 0.7.68 (and older) is confirmed to work in this context just&#xA;because older nginx does not use reference counting.&#xA;&#xA;I&#39;ll attempt fix in the next few days. Thank you for reporting this&#xA;and sorry about this issue :)&#xA;&#xA;Cheers,&#xA;-agentzh&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;大概的意思是:&#xA;0.8.11+才会有这个问题,0.7.68以下的版本,因为没有使用相关特性而没有问题.&#xA;解决方法: 关闭nginx的keeplive 且 客户端主动关闭连接.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;我得出几个结论:&#xA;1. taobao不是用这种版本组合,或者不用这种写法&#xA;&lt;strong&gt;2. ab不会主动释放连接, 与wget/curl的行为不一致!! 这个比较问题大&lt;/strong&gt;&#xA;3. 淘宝里面如果没有这种写法,那我要检讨一下是否应该这样写&lt;/p&gt;&#xA;&#xA;&lt;p&gt;恩,继续努力,奋斗在 nginx+lua+C指针 的苦海中&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>累趴下了,就为了办出生证!!</title>
      <link>http://wendal.net/253.html</link>
      <pubDate>2011-03-14 07:26:17 +0800</pubDate>
      <description>&lt;p&gt;原本打算一个早上就能搞好 &amp;hellip;&#xA;原本以为简单填一下表就搞定 &amp;hellip;&#xA;原本以为就一个地方搞定全部东西 &amp;hellip;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;我承认,错了, 结果是用了一天. 除了中午吃饭的半个小时,都在奔波&amp;hellip;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;宝宝42天了, 要体检,补听力筛查 .. 还得去洗澡,游泳&amp;hellip;.&#xA;老婆产后42天了, 需要复查, 验血,验尿,B超&amp;hellip;.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;跑上跑下,今天不知道走了多少层楼, 不知道签了多少次名,不知道刷了多少次卡&amp;hellip;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;不过,总算是把出生证给拿到了!! ^_^&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;哈哈,宝宝, 中国承认你这个人了, 你成为法律上的人了!!&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>最近速成Lua了,简单记一下</title>
      <link>http://wendal.net/252.html</link>
      <pubDate>2011-03-10 07:56:26 +0800</pubDate>
      <description>&lt;p&gt;最近速成Lua,写篇文章mark一下, 参考了 &lt;a href=&#34;http://luaforge.net/frs/download.php/4416/A_Quick_Start_Guide_On_Lua_For_C_C_Programmer_CN.pdf&#34;&gt;Lua-Quick-Start-Guide-CN&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Lua执行器, 官方当前最新5.1.4, 但我觉得LuaJIT 2.0 beta6 更好&lt;/p&gt;&#xA;&#xA;&lt;p&gt;我的考虑是这样的:&#xA;1. 为了性能,把固定的处理逻辑用C写&#xA;2. 为了灵活,与配置紧密相关的用Lua写&lt;/p&gt;&#xA;&#xA;&lt;p&gt;8种类型:&#xA;数字(double), 字符串, 布尔值(true/false)&#xA;函数(function)&#xA;表(相当于HashMap+List,唯一的数据结构)&#xA;用户数据(userdata,C定义的,Lua对其只读,不能直接通过Lua语句修改) &amp;ndash; 对我基本无用处&#xA;协程(thread) &amp;ndash; 其实就是Lua模拟的多线程,与Java的真线程差远了,基本无视之&#xA;nil(空,啥都不是,一般就是标志物)&lt;/p&gt;&#xA;&#xA;&lt;p&gt;语法:&#xA;1. 变量无类型&#xA;2. 无需;之类的语句终结符,最好一行一条语句, 语言本身对缩进不感冒.&#xA;3. 函数可以返回多个值 (Java中我也想啊!)&#xA;4. if语句, 除了false和nil外, 一律视为true (真的比较单纯的约定)&#xA;5. 没有数组,只有table, 相当于HashMap+List&#xA;6. 支持闭包,但我用不上,无视之&#xA;7. 有假的多线程,直接无视&lt;/p&gt;&#xA;&#xA;&lt;p&gt;好,上代码:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;--这是注释&#xA;--定义一个本地变量&#xA;local myx = 1&#xA;--变量没类型,随便赋值&#xA;myx = &amp;quot;Wendal&#39;s LUA&amp;quot;&#xA;--定义一个方法&#xA;function abc()&#xA;    -- 返回多个值,爽,最后一个是表&#xA;    return 1,&amp;quot;2&amp;quot;,{yyy=1.2,ab=&amp;quot;z&amp;quot;}&#xA;end&#xA;--多个变量一起赋值&#xA;x,y,z = abc()&#xA;--z变量保存的是table类型,故:&#xA;--索引值以1开始&#xA;myx = z.yyy&#xA;myx = z[2]&#xA;--if语句, then和end都是必须的,因为返回值不是nil和false,故abc()相当于true&#xA;if abc() then&#xA;    --内置方法,不是语法的一部分&#xA;    print(&amp;quot;cccccc&amp;quot;)&#xA;elseif&#xA;    print(&amp;quot;aaaaa&amp;quot;)&#xA;end&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;剩下的就是基础API了,没必要记,用用就知道了&lt;/p&gt;&#xA;&#xA;&lt;p&gt;突然感觉到 编程语言就是 语法+API  &amp;mdash;&amp;gt; 有点废话&lt;/p&gt;&#xA;&#xA;&lt;p&gt;另外提醒一下, Lua没有对象,不过可以通过table类型来模拟.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>[误报]难道我遇到lua-nginx-module的一个bug?</title>
      <link>http://wendal.net/251.html</link>
      <pubDate>2011-03-09 10:30:07 +0800</pubDate>
      <description>&lt;p&gt;已经确定是我自己的原因&#xA;实在不是很肯定,如果加入特定的&amp;ndash;with-cc-opt参数就报错.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;环境: Ubuntu 10.04.2 LTS Server&lt;/p&gt;&#xA;&#xA;&lt;p&gt;先安装好依赖的包:&#xA;apt-get install liblua5.1-0-dev g++&#xA;然后下载google-perftools:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;wget http://google-perftools.googlecode.com/files/google-perftools-1.6.tar.gz&#xA;tar xvf google-perftools-1.6.tar.gz&#xA;cd google-perftools-1.6&#xA;./configure&#xA;make&#xA;make install&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;然后到nginx编译:&#xA;下载ngx_devel_kit 0.2.17&#xA;下载lua-nginx-module 0.1.6rc2&lt;/p&gt;&#xA;&#xA;&lt;p&gt;执行以下编译参数:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;./configure --add-module=simpl-ngx_devel_kit --add-module=lua-nginx-module&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;可以成功配置,make也很顺利&lt;/p&gt;&#xA;&#xA;&lt;p&gt;然后试试:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;./configure --add-module=simpl-ngx_devel_kit --add-module=lua-nginx-module --with-cc-opt=-lprofile #这里写错了,应该是profiler&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;报错,难道加上&amp;ndash;with-cc-opt就报错?&#xA;试试mysql的lib&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;./configure --add-module=simpl-ngx_devel_kit --add-module=lua-nginx-module --with-cc-opt=-lmysql&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;通过.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;神奇啊&amp;hellip; 难道真的是bug?&#xA;如果直接在auto/cc/gcc将:&#xA;    NGX_GCC_OPT=&amp;ldquo;-O&amp;rdquo;&#xA;改为&#xA;    NGX_GCC_OPT=&amp;ldquo;-O2 -lprofile&amp;rdquo; 是能够pass的. &amp;ndash;&amp;gt; 写错了!! 应该是-lprofiler&lt;/p&gt;&#xA;&#xA;&lt;p&gt;好吧,困了,睡觉,明天报个issue.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;哈哈,本文是误报, 不算是个bug.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>兼容FireFox 4的AutoProxy</title>
      <link>http://wendal.net/250.html</link>
      <pubDate>2011-03-09 07:50:52 +0800</pubDate>
      <description>&lt;p&gt;#########################################&#xA;##官方已经发布兼容FF4 版本!! &lt;a href=&#34;https://addons.mozilla.org/zh-CN/firefox/addon/autoproxy/versions/&#34;&gt;马上去下载安装吧!!&lt;/a&gt;&#xA;#########################################&lt;/p&gt;&#xA;&#xA;&lt;p&gt;前几天, FF4 RC1 放出, 作为FF粉丝怎么可以不升级?&lt;/p&gt;&#xA;&#xA;&lt;p&gt;安装后,启动,检查附件组件兼容性, 什么?!! Autoproxy不兼容?!! 这可不行,这是必备的!!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;到处查找更新版,官方发布的0.4b1也不支持FF4 RC1 !!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;好吧,根据其&lt;a href=&#34;http://code.google.com/p/autoproxy/issues/detail?id=147&#34;&gt;issue 174&lt;/a&gt;,其实已经修改,只是还没有发布,只好直接跑到Autoproxy的官网下载源码进行编译(为此下载了Git For Windows,Perl,MS-DOS Zip)&lt;/p&gt;&#xA;&#xA;&lt;p&gt;经过简单试用,恩,一切正常!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;好东西不能独享,放出我自己的编译的版本给大家救急&lt;/p&gt;&#xA;&#xA;&lt;p&gt;如有更新,我也会及时跟进(前提是官方还未放出)&#xA;&lt;strong&gt;下载:&#xA;&amp;mdash;&amp;gt; autoproxy-0.4.0+.2011030823.xpi&#xA;&lt;a href=&#34;https://docs.google.com/leaf?id=0B8hUXYDeoy_hY2JhMTZjNjUtODE2ZC00ODE0LThjMjYtZTZmNmNhMDNlOGJl&amp;amp;sort=name&amp;amp;layout=list&amp;amp;num=50&#34;&gt;Google Docs 下载&lt;/a&gt; , &lt;a href=&#34;http://build.sunfarms.net/download/autoproxy-0.4.0+.2011030823.xpi&#34;&gt; 本地下载&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;&amp;mdash;&amp;gt; FF4 RC1 中文版(已经可以在官网公下载)&#xA;&lt;del&gt;&lt;a href=&#34;https://docs.google.com/leaf?id=0B8hUXYDeoy_hMjhjNmQ3M2EtOGJkZi00MWNkLWE1M2YtZTVmMjU4ZjcxZTJh&amp;amp;hl=zh_CN&#34;&gt;Google Docs 下载 &lt;/a&gt;&lt;/del&gt;&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;**提醒: 安装后右下角无&amp;rdquo;福&amp;rdquo;字,需要进入附加组件管理器进行配置.&#xA;**&lt;/p&gt;&#xA;&#xA;&lt;p&gt;常出去走走,有益身心&lt;/p&gt;&#xA;&#xA;&lt;p&gt;附上访问Google Docs简单方法:&#xA;修改Host文件     C:\WINDOWS\system32\drivers\etc\hosts&#xA;添加:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;209.85.225.101 docs.google.com&#xA;74.125.127.100 writely.google.com&#xA;72.14.203.100 spreadsheets.google.com&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;</description>
    </item>
    <item>
      <title>一个简单XML工具类,支持简单的路径求值</title>
      <link>http://wendal.net/248.html</link>
      <pubDate>2011-03-06 07:57:55 +0800</pubDate>
      <description>&lt;p&gt;估计是个轮子,因为一说起XML,自然想到的是JDom/dom4j等老牌/强大的工具.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;但我的需求如此简单: &amp;ldquo;支持简单的路径求值&amp;rdquo; ,就加一个N多垃圾的jar包,算了,一气之下,写了这个工具类.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;原本这个工具类包含 一个接口,一个实现类,一个工厂类,一个测试类&lt;/p&gt;&#xA;&#xA;&lt;p&gt;完成初版后,发现,为啥还分这么多东西,不就一个简单需求嘛!! 很不符合我的风格. 而且,我还特意建了一个工程叫NutzXML &amp;hellip;.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;不行,这种需要扩展,不考虑效率的东西, 咋调用一下都这么麻烦? 改!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;最后,整个XmlMap类,加上注释,150行, 这里展示的是无注释的版本:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;package org.nutz.xml;&#xA;&#xA;import java.io.InputStream;&#xA;import java.util.ArrayList;&#xA;import java.util.List;&#xA;&#xA;import javax.xml.parsers.DocumentBuilder;&#xA;import javax.xml.parsers.DocumentBuilderFactory;&#xA;import javax.xml.parsers.ParserConfigurationException;&#xA;&#xA;import org.w3c.dom.Document;&#xA;import org.w3c.dom.Element;&#xA;import org.w3c.dom.NodeList;&#xA;&#xA;public class XmlMap{&#xA;&#xA;    private Element element;&#xA;&#xA;    public XmlMap(Element element) {&#xA;        this.element = element;&#xA;    }&#xA;&#xA;    public List getList(String name) { //这里去掉了泛型,请自行加上&#xA;        NodeList nList = element.getElementsByTagName(name);&#xA;        List list = new ArrayList(nList.getLength());//这里去掉了泛型,请自行加上&#xA;        for (int i = 0; i &amp;lt; nList.getLength(); i++) {&#xA;            list.add(new XmlMap((Element)nList.item(i)));&#xA;        }&#xA;        return list;&#xA;    }&#xA;&#xA;    /**&#xA;     * 获取一个属性的值&#xA;     */&#xA;    protected String get(String name) {&#xA;        if (element.hasAttribute(name))&#xA;            return element.getAttribute(name);&#xA;        else if (&amp;quot;value&amp;quot;.equals(name))&#xA;            return element.getTextContent();&#xA;        return null;&#xA;    }&#xA;&#xA;    static DocumentBuilder db;&#xA;&#xA;    static {&#xA;        try {&#xA;            db = DocumentBuilderFactory.newInstance().newDocumentBuilder();&#xA;        } catch (ParserConfigurationException e) {&#xA;            throw new RuntimeException(e);&#xA;        }&#xA;    }&#xA;&#xA;    /**&#xA;     * 从输入流读取XML文件,构建XmlMap对象&#xA;     * @param is 包含Xml文件的输入流&#xA;     * @return XmlMap对象&#xA;     */&#xA;    public static final XmlMap read(InputStream is) {&#xA;        try {&#xA;            Document doc = db.parse(is);&#xA;            doc.normalizeDocument();&#xA;            return new XmlMap((Element) doc.getDocumentElement());&#xA;        } catch (Exception e) {&#xA;            throw new RuntimeException(e);&#xA;        }&#xA;    }&#xA;&#xA;    public static final Object parse(XmlMap map,String path) {&#xA;        if (path.indexOf(&#39;.&#39;) &amp;gt; 0)&#xA;            return parse(get2(map, path.substring(0,path.indexOf(&#39;.&#39;))), path.substring(path.indexOf(&#39;.&#39;)+1));&#xA;        //到这里的话,应该只剩下 abc#attr 或者abc[12]#attr 或者 abc[12] 或者abc&#xA;        if (path.indexOf(&#39;#&#39;) &amp;gt; -1) //需要获取具体的属性值&#xA;            if (path.indexOf(&#39;#&#39;) &amp;gt; 0)&#xA;                return get2(map, path.substring(0,path.indexOf(&#39;#&#39;))).get(path.substring(path.indexOf(&#39;#&#39;)+1));&#xA;            else&#xA;                return map.get(path.substring(1));&#xA;        else&#xA;            //如果指定了索引则返回XmlMap,否则返回List&#xA;            return path.indexOf(&#39;[&#39;) &amp;gt; 0 ? get3(map, path) : map.getList(path);&#xA;    }&#xA;&#xA;    private static final XmlMap get2(XmlMap map, String path) {&#xA;        return path.indexOf(&#39;[&#39;) &amp;gt; 0 ? get3(map, path) : map.getList(path).get(0);&#xA;    }&#xA;&#xA;    private static final XmlMap get3(XmlMap map, String path) {&#xA;        return map.getList(path.substring(0,path.lastIndexOf(&#39;[&#39;))).get(Integer.parseInt(path.substring(path.lastIndexOf(&#39;[&#39;)+1,path.length()-1)));&#xA;    }&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&#34;http://code.google.com/p/nutzlab/source/browse/trunk/NutXML/src/org/nutz/xml/XmlMap.java&#34;&gt;点击查看完整版&lt;/a&gt; &amp;ndash; 在&lt;a href=&#34;http://code.google.com/p/nutzlab/&#34;&gt;Nutz Lab&lt;/a&gt;项目中&lt;/p&gt;&#xA;&#xA;&lt;p&gt;使用示例:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt; XmlMap map = XmlMap.read(new FileInputStream(&amp;quot;demo.xml&amp;quot;));获取XmlMap对象&#xA; map.get(&amp;quot;authBy&amp;quot;);                       //返回值为xxxUserSeriver&#xA; XmlMap.parse(map, &amp;quot;#authBy&amp;quot;);            //返回值为xxxUserSeriver&#xA; XmlMap.parse(map, &amp;quot;other#value&amp;quot;);        //other没有value属性,则返回其文本值abc&#xA; XmlMap.parse(map, &amp;quot;url[3]#pattern&amp;quot;);     //获取第4个(索引值为3)url标签的pattern属性&#xA; XmlMap.parse(map, &amp;quot;levelA.levelB.levelC[1].levelD#key&amp;quot;);//返回值为XX2X&#xA; XmlMap.parse(map, &amp;quot;levelA.levelB&amp;quot;);      //返回值为一个包含全部levelB节点的List&#xA; XmlMap.parse(map, &amp;quot;levelA.levelB[1]&amp;quot;);   //返回值为第2个levelB节点的XmlMap&#xA; XmlMap.parse(map, &amp;quot;levelA.levelB#myKey&amp;quot;);//返回值为nutz&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;其实,我是打算做一个基于URL的权限控制, 考虑叫NutzSecurity 设想中,YY中&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>一起来,为Nutz编写插件!</title>
      <link>http://wendal.net/247.html</link>
      <pubDate>2011-03-05 09:33:29 +0800</pubDate>
      <description>&lt;p&gt;&lt;strong&gt;随着Nutz代码的不断改进,为Nutz编写插件已经越来越容易.&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;早期我们编写的插件,很多都是为了兼容/集成XX框架而写的. 例如&lt;a href=&#34;http://code.google.com/p/nutzmore/source/browse/trunk/src/org/nutz/ioc/impl/spring/SpringIocProvider.java&#34;&gt;SpringIocLoader&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;其实我们可以做更多更强大的插件,今天以当前扩展功能最好的MVC为例:&#xA;1. 视图插件&#xA;2. 适配器插件&#xA;3. 处理器插件&#xA;4. UrlMapping插件&lt;/p&gt;&#xA;&#xA;&lt;p&gt;逐一讲解:&#xA;&lt;strong&gt;1. 视图插件&lt;/strong&gt;&#xA;    要求: 实现View接口和ViewMarker接口&#xA;    能做什么?&#xA;        &amp;ndash; 实现你的视图,例如用Freemaker/Velocity的模板文件替代jsp&#xA;        &amp;ndash; Nutz本身的视图不符合你的口味? 改造一个视图吧!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;2. 适配器插件&lt;/strong&gt;&#xA;    要求: 实现HttpAdaptor接口&#xA;    能做什么?&#xA;        &amp;ndash; 你的请求的格式未被nutz识别? 例如WebService请求&#xA;        &amp;ndash; 请求是加密的? 需要解码才能读取&#xA;        &amp;ndash; 一个请求包含几种数据格式? 这年头啥需求都有,你懂的&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;3. 处理器插件 &amp;ndash; 新版的MVC使用动作链模型,你可以介入请求处理的任何阶段&lt;/strong&gt;&#xA;    要求: 实现Processor接口&#xA;    能做什么?&#xA;        &amp;ndash; 权限处理,过滤URL或者具体的方法调用&#xA;        &amp;ndash; 数据校验&#xA;**&#xA;4. UrlMapping插件**&#xA;    要求: 实现UrlMapping&#xA;    能做什么?&#xA;        &amp;ndash; REST控? 这个适合你!! 你会找到不少志同道合的童鞋&lt;/p&gt;&#xA;&#xA;&lt;p&gt;简单介绍完, 看看有无时间写篇 &amp;ldquo;Nutz插件编写指南&amp;rdquo; 哈哈, 期待吧&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>人生第一次离职,Mark一下</title>
      <link>http://wendal.net/246.html</link>
      <pubDate>2011-02-25 09:18:59 +0800</pubDate>
      <description>&lt;p&gt;终于办完离职手续,离开了工作了3年的公司.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;太困了,虽然很多话想写,下次吧,先自己Mark一下,留个纪念.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>JDiff 使用与改进</title>
      <link>http://wendal.net/245.html</link>
      <pubDate>2011-02-24 03:45:02 +0800</pubDate>
      <description>&lt;p&gt;不久前为Nutz的构建服务添加JDiff报告. 报告查看地址: &lt;a href=&#34;http://build.sunfarms.net/nutz/lastest/jdiff/&#34;&gt;http://build.sunfarms.net/nutz/lastest/jdiff/&lt;/a&gt; 以后都可以知道不同的nutz版本API有何不同了.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;JDiff报告,就是描述不同版本的代码之间的API差异, 如某某public类被删除了,某某接口改变了&lt;/p&gt;&#xA;&#xA;&lt;p&gt;感兴趣的可以先访问&lt;a href=&#34;http://www.jdiff.org&#34;&gt;官网&lt;/a&gt;,以了解基本使用.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;但,原本的JDiff有一个很大的问题,对中文支持不好.故,我改进了一下,放出一个版本(原版已经很久没用更新了)&#xA;添加了一个配置,用于设置源码的编码encoding. 另外,我移除了对xerces.jar的依赖.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;现在可以在old或者new节点添加encoding=&amp;ldquo;UTF-8&amp;rdquo;之类的设置. 实例配置,请查看Nutz项目的build2.xml文件,地址: &lt;a href=&#34;http://code.google.com/p/nutz/source/browse/trunk/build/build2.xml&#34;&gt;http://code.google.com/p/nutz/source/browse/trunk/build/build2.xml&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;我已经上传到Google Doc,需要的童鞋就下载吧.&#xA;地址: &lt;a href=&#34;https://docs.google.com/leaf?id=0B8hUXYDeoy_hMjViMjBlMGEtMDlkMi00NjllLWE0MjctNmUxNWI3N2QzZjE2&amp;amp;hl=zh_CN&#34;&gt;jdiff-1.1.1-Modify-by-Wendal.zip&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;附上对原版的修改:&lt;/p&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&lt;p&gt;移除对xerces.jar的依赖,&#xA;将XML2API中的代码:&lt;/p&gt;&#xA;&#xA;&lt;p&gt;String parserName = System.getProperty(&amp;ldquo;org.xml.sax.driver&amp;rdquo;);&#xA;if (parserName == null) {&#xA;    parser = org.xml.sax.helpers.XMLReaderFactory.createXMLReader(&amp;ldquo;org.apache.xerces.parsers.SAXParser&amp;rdquo;);&#xA;} else {&#xA;    parser = org.xml.sax.helpers.XMLReaderFactory.createXMLReader();&#xA;}&lt;/p&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;p&gt;改为:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;parser = org.xml.sax.helpers.XMLReaderFactory.createXMLReader();&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&lt;p&gt;中文支持,为ProjectInfo类添加属性encoding,然后修改JDiff的generateJavadoc方法:&lt;/p&gt;&#xA;&#xA;&lt;p&gt;//在jd.perform();前面添加&#xA;if(proj.getEncoding() != null) {&#xA;            jd.setEncoding(proj.getEncoding());&#xA;            jd.setDocencoding(proj.getEncoding());&#xA;            jd.setCharset(proj.getEncoding());&#xA;        }&lt;/p&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;p&gt;生成XML的时候也设置一下,generateXML方法:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;//添加一样的内容&#xA;if(proj.getEncoding() != null) {&#xA;            jd.setEncoding(proj.getEncoding());&#xA;            jd.setDocencoding(proj.getEncoding());&#xA;            jd.setCharset(proj.getEncoding());&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;</description>
    </item>
    <item>
      <title>完成对JBE的修正,终于可以用了.</title>
      <link>http://wendal.net/244.html</link>
      <pubDate>2011-02-22 04:08:20 +0800</pubDate>
      <description>&lt;p&gt;先放出下载地址:&#xA;&lt;a href=&#34;https://docs.google.com/leaf?id=0B8hUXYDeoy_hNDczMTQ5OWUtYjJlNC00NTE2LWI1MWItODk4NGIwNDUyZjMz&amp;amp;hl=zh_CN&#34;&gt;jbe-0.1b-Fixed-By-WendalChen.zip&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;原版下载地址: &lt;a href=&#34;http://www.cs.ioc.ee/~ando/jbe/&#34;&gt;JBE - Java Bytecode Editor&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;原版存在的问题:&#xA;对方法进行修改后,点击Save Method, 如果存在 invokeinterface 的行, 将无法保存!! 后台报错.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;以下是我在压缩包中写的描述:&#xA;This JBE had been modify by Wendal Chen , base on JBE 0.1b&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Fix:&#xA;when save method whit &amp;ldquo;invokeinterface&amp;rdquo; , app fail.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;File change:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;JAsmParser.java line 169~170:&#xA;int arg1 = getMethodConstRef(instrElems, cpg, labels);&#xA;int arg2 = Utility.methodSignatureArgumentTypes(getDescrFromFullMethod(instrElems[1])).length;&#xA;&#xA;//---------------------------------------------------------------&#xA;ConstantInterfaceMethodrefInfo.java Override getVerbose() :&#xA;&#xA;public String getVerbose() throws InvalidByteCodeException {&#xA;    ConstantNameAndTypeInfo nameAndType = getNameAndTypeInfo();&#xA;&#xA;    return classFile.getConstantPoolEntryName(classIndex) + &amp;quot;/&amp;quot; +&#xA;           classFile.getConstantPoolEntryName(nameAndType.getNameIndex())&#xA;           +classFile.getConstantPoolEntryName(nameAndType.getDescriptorIndex());&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;I check my class file, it work. I hope it work for you too.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;通过修改其中两个类来修复这个问题.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>一个极其简陋的Datasource连接池实现</title>
      <link>http://wendal.net/243.html</link>
      <pubDate>2011-02-21 01:18:41 +0800</pubDate>
      <description>&lt;p&gt;写了一段时间了,一直没提交到Nutz,哈哈. 明显没有技术含量,提上去明显找抽!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;用来跑Nutz的测试,能够全部pass.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;直接上代码:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;package org.nutz.dao.impl;&#xA;&#xA;import java.io.PrintWriter;&#xA;import java.lang.reflect.InvocationHandler;&#xA;import java.lang.reflect.Method;&#xA;import java.lang.reflect.Proxy;&#xA;import java.sql.Connection;&#xA;import java.sql.DriverManager;&#xA;import java.sql.SQLException;&#xA;import java.util.Iterator;&#xA;import java.util.Queue;&#xA;import java.util.concurrent.ConcurrentLinkedQueue;&#xA;&#xA;import javax.sql.DataSource;&#xA;&#xA;import org.nutz.lang.Lang;&#xA;&#xA;@SuppressWarnings(&amp;quot;unchecked&amp;quot;)&#xA;public class SimpleDataSource implements DataSource {&#xA;&#xA;    private String username;&#xA;    private String password;&#xA;    private String url;&#xA;&#xA;    /*保存已经建立的连接*/&#xA;    private ConcurrentLinkedQueue connQueue = new ConcurrentLinkedQueue();&#xA;&#xA;    public SimpleDataSource(String url, String driverClass, String username, String password)&#xA;            throws ClassNotFoundException {&#xA;        if (driverClass != null)&#xA;            Class.forName(driverClass);&#xA;        this.url = url;&#xA;        this.username = username;&#xA;        this.password = password;&#xA;    }&#xA;&#xA;    public Connection getConnection() throws SQLException {&#xA;        Connection conn = (Connection) connQueue.poll();&#xA;        if (conn != null)&#xA;            return conn;&#xA;        conn = DriverManager.getConnection(url, username, password);&#xA;        return (Connection) Proxy.newProxyInstance( SimpleDataSource.class.getClassLoader(),&#xA;                                                    new Class[]{Connection.class},&#xA;                                                    new ConnectionInvocationHandler(conn, connQueue));&#xA;    }&#xA;&#xA;    public void close() throws Throwable {&#xA;        Iterator it = connQueue.iterator();&#xA;        while (it.hasNext()) {&#xA;            Connection conn = (Connection) it.next();&#xA;            synchronized (conn) {&#xA;                try {&#xA;                    conn.close();&#xA;                }&#xA;                catch (Throwable e) {}&#xA;            }&#xA;        }&#xA;    }&#xA;&#xA;    protected void finalize() throws Throwable {&#xA;        close();&#xA;    }&#xA;&#xA;    static class ConnectionInvocationHandler implements InvocationHandler {&#xA;&#xA;        private Connection conn;&#xA;&#xA;        private Queue&amp;lt;connection&amp;gt; connQueue;&#xA;&#xA;        public ConnectionInvocationHandler(Connection conn, Queue&amp;lt;/connection&amp;gt;&amp;lt;connection&amp;gt; connQueue) {&#xA;            this.conn = conn;&#xA;            this.connQueue = connQueue;&#xA;        }&#xA;&#xA;        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {&#xA;            if (args == null&#xA;                &amp;amp;&amp;amp; &amp;quot;close&amp;quot;.equals(method.getName())&#xA;                &amp;amp;&amp;amp; connQueue.size() &amp;lt; 20&#xA;                &amp;amp;&amp;amp; connQueue.offer((Connection) proxy))&#xA;                return null;&#xA;            try {&#xA;                return method.invoke(conn, args);&#xA;            }&#xA;            catch (Throwable e) {&#xA;                throw Lang.unwrapThrow(e);&#xA;            }&#xA;        }&#xA;    }&#xA;&#xA;    // -------------------------------------------------------------------------&#xA;    // 其他无需实现的方法&#xA;    // -------------------------------------------------------------------------&#xA;    public Connection getConnection(String username, String password) {&#xA;        throw Lang.noImplement();&#xA;    }&#xA;&#xA;    public PrintWriter getLogWriter() throws SQLException {&#xA;        throw Lang.noImplement();&#xA;    }&#xA;&#xA;    public int getLoginTimeout() throws SQLException {&#xA;        throw Lang.noImplement();&#xA;    }&#xA;&#xA;    public void setLogWriter(PrintWriter out) throws SQLException {&#xA;        throw Lang.noImplement();&#xA;    }&#xA;&#xA;    public void setLoginTimeout(int seconds) throws SQLException {&#xA;        throw Lang.noImplement();&#xA;    }&#xA;&#xA;    public boolean isWrapperFor(Class iface) throws SQLException {&#xA;        throw Lang.noImplement();&#xA;    }&#xA;&#xA;    public Object unwrap(Class iface) throws SQLException {&#xA;        throw Lang.noImplement();&#xA;    }&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;用来跑Nutz的TestCase, 在我的机器耗时5.2秒,与DBCP相当(5.3秒).&#xA;缺点:&#xA;1. 高并发时,可能建立过多的连接&#xA;2. 高并发时,部分连接可能没有被回收&#xA;3. 限制死了最多保存20个连接(当然,这个很好改)&#xA;4. XXX都没法配置&lt;/p&gt;&#xA;&#xA;&lt;p&gt;调用方法:&lt;/p&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&lt;p&gt;直接创建:&lt;/p&gt;&#xA;&#xA;&lt;p&gt;DataSource dataSource = new SimpleDataSource(&amp;ldquo;jdbc:h2:mem:~&amp;ldquo;,&amp;ldquo;org.h2.Driver&amp;rdquo;,&amp;ldquo;sa&amp;rdquo;,&amp;ldquo;sa&amp;rdquo;);&#xA;//代码&amp;hellip;..&lt;/p&gt;&#xA;&#xA;&lt;p&gt;//最后记得关闭一下,或者等GC的时候自行关闭.&#xA;((SimpleDataSource)dataSource).close();&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;NutIoc的json方式&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;dataSource : {&#xA;    type :&amp;quot;org.nutz.dao.impl.SimpleDataSource&amp;quot;,&#xA;    events : {&#xA;        depose :&amp;quot;close&amp;quot;&#xA;    },&#xA;    args : [&amp;quot;jdbc:h2:mem:~&amp;quot;,&amp;quot;org.h2.Driver&amp;quot;,&amp;quot;sa&amp;quot;,&amp;quot;sa&amp;quot;]&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;p&gt;哈哈,没啥技术含量,来拍我吧!!&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Nutz 一些无法完成的功能</title>
      <link>http://wendal.net/242.html</link>
      <pubDate>2011-02-16 08:58:49 +0800</pubDate>
      <description>&lt;p&gt;这篇文章针对的是1.b.35&lt;/p&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&lt;p&gt;Nutz.Ioc与Spring.ioc相比,无法实现工厂类生成具体类的实例&lt;/p&gt;&#xA;&#xA;&lt;p&gt;public class A {}&lt;/p&gt;&#xA;&#xA;&lt;p&gt;public class B {&#xA;    public static A makeA(){return new A();}&#xA;}&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;Nutz.Aop与Spring.Aop相比,无法拦截构造方法,静态方法&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;Nutz.Dao与Hibernate相比,没有缓存层,无自动update表结构,没有复杂的映射关系管理,没有XML&amp;lt; &amp;ndash;&amp;gt;POJO转换工具&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;Nutz.MVC 没有校验功能,没有配置方式的URL映射&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;Nutz.MVC 与Struts2相比, 没有标签库&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;Nutz.Lang 与Apache Common 系列相比, 很多功能都没有&lt;/p&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;p&gt;问题是,我们需要这些功能吗??&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Nutz 面向大型应用吗? 面向复杂应用吗?&lt;/p&gt;&#xA;&#xA;&lt;p&gt;我的观点 够用就好!&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>做爸爸了!! 过年前有了个虎宝宝!!</title>
      <link>http://wendal.net/234.html</link>
      <pubDate>2011-02-08 08:38:16 +0800</pubDate>
      <description>&lt;p&gt;嘻嘻,母女平安. 靓照暂时就不曝光了.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;下面记一下经验,嘻嘻:&#xA;. 买生育保险能省很多钱,常规产检都是免费的哦! 仅住院/做手术,就省了4k&#xA;. 绿色(超薄干爽)的帮宝适,很舒服,但不是最好的,那只是中档货. 最好的是母乳宝宝,然后是超级棉柔,都是黄色包装的!!前者(母乳宝宝)大陆无销售,一般是美国产,需要在香港买/淘宝代购,2.5元/片;后者(超级棉柔),一般存货不多,而且标明是日本进口, 2元/片&#xA;. 早点去医院的孕妇学校,能学到很多东西,而且能提前接触到产房的人&#xA;. 手术后6小时就得翻身(很痛,但是一定要坚强),并且马上让宝宝吮吸,对恢复很有帮助!! 使用卧式,叫护士教.&#xA;. 手术后6小时开始就要喝水/喝汤了,12小时就要喝粥,24小时务必下床!! 要坚强!! 放屁后就可以吃饭了!! 不会觉得饿的,但一样要吃,按平时的饭量吃.&#xA;. 术前要求医生使用&amp;rdquo;术后镇痛术&amp;rdquo;,就是一个缓慢静脉镇痛药,250元,很值得的!!&#xA;. 宝宝出生后,2小时~4小时就要先喂一次水,然后开始喂奶粉,20毫升就够了,宝宝开头仅喝10毫升的,接下来2天,每2小时喂一次.&#xA;. 如果打算母乳喂养,那么怀孕时就要做按摩,我老婆12小时就开始有乳汁了(剖宫产啊,一般第2/3天才有的;顺产也要第二天),医院的护士都很惊讶呢!! 做法: 每天晚上,用大拇指,按压第3/4个脚趾,从脚趾的关节,顺着骨头往脚面推,不是脚底,每个脚趾按100下,共400下.这个要老公做的,我经常按到手软呢.&#xA;. 怀孕后就先休假1个月!! 好好休息一下,一般就是睡大觉,然后再上班. 这样孕期的反应就少很多了.&#xA;. 香港有卖一种仿乳头的奶瓶,英国产,淘宝也有代购,150ml的,其实完全足够了.&#xA;. 奶粉我觉得明治最好,为黄种人设计,不热气,虽然有人提到会缺锌,但相比欧美的产品,还是明治好!! 买明治,一定要买日本本土产的,买其他的话,还不如买美赞臣/牛栏牌&#xA;. 怀孕后,继续正常饮食,补充叶酸/维生素就可以了,不要经常进补!! 经常散步,即使顶着大肚子. 手术前,老婆走得比我还快呢!&#xA;. 防辐射服 &amp;ndash; 没用的,骗钱的     仅仅是心理安慰,我就没有买&#xA;. 怀孕后,上Q/看电影,一切照旧! 我们周围最强的电磁波辐射,其实是光线,除非你住在黑暗的屏蔽室内,否则啥都挡不住!&#xA;. 宝宝够暖就可以了,偶尔打个喷嚏其实很好很正常的. 衣服太多,会出红疹,严重的话要住院的!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;暂时就想到这么多,欢迎交流哦&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Hibernate的ConnectionProvider是怎么一回事?</title>
      <link>http://wendal.net/233.html</link>
      <pubDate>2011-01-28 02:28:12 +0800</pubDate>
      <description>&lt;p&gt;这次讨论一下Hibernate的ConnectionProvider接口, 因为我看到某些Hibernate项目是这样配置的:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;&amp;lt;property name=&amp;quot;c3p0.min_size&amp;quot;&amp;gt;5&amp;lt;/property&amp;gt;&#xA;&amp;lt;property name=&amp;quot;c3p0.max_size&amp;quot;&amp;gt;30&amp;lt;/property&amp;gt;&#xA;&amp;lt;property name=&amp;quot;c3p0.time_out&amp;quot;&amp;gt;1800&amp;lt;/property&amp;gt;&#xA;&amp;lt;property name=&amp;quot;c3p0.max_statement&amp;quot;&amp;gt;50&amp;lt;/property&amp;gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;问题是, 这样就配置好了吗? hibernate.connection.provider_class到底需不需要呢?&#xA;来看看Hibernate 3.3.2 GA的源码&#xA;ConnectionProviderFactory类的newConnectionProvider方法.&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;public static ConnectionProvider newConnectionProvider(Properties properties, Map connectionProviderInjectionData) throws HibernateException {&#xA;    ConnectionProvider connections;&#xA;    String providerClass = properties.getProperty(Environment.CONNECTION_PROVIDER);&#xA;    if ( providerClass!=null ) {&#xA;        try {&#xA;            log.info(&amp;quot;Initializing connection provider: &amp;quot; + providerClass);&#xA;            connections = (ConnectionProvider) ReflectHelper.classForName(providerClass).newInstance();&#xA;        }&#xA;        catch ( Exception e ) {&#xA;            log.error( &amp;quot;Could not instantiate connection provider&amp;quot;, e );&#xA;            throw new HibernateException(&amp;quot;Could not instantiate connection provider: &amp;quot; + providerClass);&#xA;        }&#xA;    }&#xA;    else if ( properties.getProperty(Environment.DATASOURCE)!=null ) {&#xA;        connections = new DatasourceConnectionProvider();&#xA;    }&#xA;    else if ( properties.getProperty(Environment.URL)!=null ) {&#xA;        connections = new DriverManagerConnectionProvider();&#xA;    }&#xA;    else {&#xA;        connections = new UserSuppliedConnectionProvider();&#xA;    }&#xA;&#xA;    if ( connectionProviderInjectionData != null &amp;amp;&amp;amp; connectionProviderInjectionData.size() != 0 ) {&#xA;        //inject the data&#xA;        try {&#xA;            BeanInfo info = Introspector.getBeanInfo( connections.getClass() );&#xA;            PropertyDescriptor[] descritors = info.getPropertyDescriptors();&#xA;            int size = descritors.length;&#xA;            for (int index = 0 ; index &amp;lt; size ; index++) {&#xA;                String propertyName = descritors[index].getName();&#xA;                if ( connectionProviderInjectionData.containsKey( propertyName ) ) {&#xA;                    Method method = descritors[index].getWriteMethod();&#xA;                    method.invoke( connections, new Object[] { connectionProviderInjectionData.get( propertyName ) } );&#xA;                }&#xA;            }&#xA;        }&#xA;        catch (IntrospectionException e) {&#xA;            throw new HibernateException(&amp;quot;Unable to inject objects into the conenction provider&amp;quot;, e);&#xA;        }&#xA;        catch (IllegalAccessException e) {&#xA;            throw new HibernateException(&amp;quot;Unable to inject objects into the conenction provider&amp;quot;, e);&#xA;        }&#xA;        catch (InvocationTargetException e) {&#xA;            throw new HibernateException(&amp;quot;Unable to inject objects into the conenction provider&amp;quot;, e);&#xA;        }&#xA;    }&#xA;    connections.configure(properties);&#xA;    return connections;&#xA;    }&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;上面的代码有点长, 精简出核心部分:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;ConnectionProvider connections;&#xA;String providerClass = properties.getProperty(Environment.CONNECTION_PROVIDER);&#xA;if ( providerClass!=null ) {&#xA;    connections = (ConnectionProvider) ReflectHelper.classForName(providerClass).newInstance();&#xA;}else if ( properties.getProperty(Environment.DATASOURCE)!=null ) {&#xA;    connections = new DatasourceConnectionProvider();&#xA;}else if ( properties.getProperty(Environment.URL)!=null ) {&#xA;    connections = new DriverManagerConnectionProvider();&#xA;}else {&#xA;    connections = new UserSuppliedConnectionProvider();&#xA;}&#xA;/**&#xA;Environment.CONNECTION_PROVIDER 的定义:&#xA;public static final String CONNECTION_PROVIDER =&amp;quot;hibernate.connection.provider_class&amp;quot;;&#xA;Environment.DATASOURCE 的定义:&#xA;public static final String DATASOURCE =&amp;quot;hibernate.connection.datasource&amp;quot;;&#xA;Environment.URL 的定义:&#xA;public static final String URL =&amp;quot;hibernate.connection.url&amp;quot;;&#xA;*/&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;可以看到, 如果hibernate.connection.provider_class和hibernate.connection.datasource都没有定义,就会使用内置的连接池,OK,那继续看默认的连接池DriverManagerConnectionProvider,只贴精华部分:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;/*连接池就是一个ArrayList !!*/&#xA;private final ArrayList pool = new ArrayList();&#xA;/*获取连接*/&#xA;public Connection getConnection() throws SQLException {&#xA;    synchronized (pool) {&#xA;        if ( !pool.isEmpty() ) {&#xA;            int last = pool.size() - 1;&#xA;            Connection pooled = (Connection) pool.remove(last);&#xA;            if (isolation!=null) pooled.setTransactionIsolation( isolation.intValue() );&#xA;            if ( pooled.getAutoCommit()!=autocommit ) pooled.setAutoCommit(autocommit);&#xA;            return pooled;&#xA;        }&#xA;    }&#xA;&#xA;    log.debug(&amp;quot;opening new JDBC connection&amp;quot;);&#xA;    Connection conn = DriverManager.getConnection(url, connectionProps);&#xA;    return conn;&#xA;}&#xA;/*释放连接*/&#xA;public void closeConnection(Connection conn) throws SQLException {&#xA;    synchronized (pool) {&#xA;        int currentSize = pool.size();&#xA;        if ( currentSize &amp;lt; poolSize ) {&#xA;            pool.add(conn);&#xA;            return;&#xA;        }&#xA;    }&#xA;    conn.close();&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;用一个简单ArrayList做出来的默认连接池,就是这样简单!!! sorry,是简陋!!! 无比简陋!! 性能能有多好?!&#xA;你的Hibernate还在用默认连接池? 你还没有配&lt;strong&gt;hibernate.connection.provider_class&lt;/strong&gt;属性? 快去看看吧!!&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>系统变量file.encoding对Java的运行影响有多大?</title>
      <link>http://wendal.net/232.html</link>
      <pubDate>2011-01-27 08:06:27 +0800</pubDate>
      <description>&lt;p&gt;这个话题来自: Nutz的&lt;a href=&#34;http://code.google.com/p/nutz/issues/detail?id=361&#34;&gt;issue 361&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;在考虑这个issue时, 我一直倾向于使用系统变量file.encoding来改变JVM的默认编码.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;今天,我想到, 这个系统变量,对JVM的影响到底有多大呢?&#xA;我使用最简单的方法看看这个变量的影响&amp;ndash;在JDK 1.6.0_20的src.zip文件中,查找包含file.encoding字眼的文件.&#xA;共找到4个, 分别是:&#xA;先上重头戏 java.nio.Charset类:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;    public static Charset defaultCharset() {&#xA;        if (defaultCharset == null) {&#xA;        synchronized (Charset.class) {&#xA;        java.security.PrivilegedAction pa =&#xA;            new GetPropertyAction(&amp;quot;file.encoding&amp;quot;);&#xA;        String csn = (String)AccessController.doPrivileged(pa);&#xA;        Charset cs = lookup(csn);&#xA;        if (cs != null)&#xA;            defaultCharset = cs;&#xA;                else &#xA;            defaultCharset = forName(&amp;quot;UTF-8&amp;quot;);&#xA;            }&#xA;    }&#xA;    return defaultCharset;&#xA;    }&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;java.net.URLEncoder的静态构造方法,影响到的方法 java.net.URLEncoder.encode(String)&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;    static {&#xA;&#xA;    dontNeedEncoding = new BitSet(256);&#xA;    int i;&#xA;    for (i = &#39;a&#39;; i &amp;lt; = &#39;z&#39;; i++) {&#xA;        dontNeedEncoding.set(i);&#xA;    }&#xA;    for (i = &#39;A&#39;; i &amp;lt;= &#39;Z&#39;; i++) {&#xA;        dontNeedEncoding.set(i);&#xA;    }&#xA;    for (i = &#39;0&#39;; i &amp;lt;= &#39;9&#39;; i++) {&#xA;        dontNeedEncoding.set(i);&#xA;    }&#xA;    dontNeedEncoding.set(&#39; &#39;); /* encoding a space to a + is done&#xA;                    * in the encode() method */&#xA;    dontNeedEncoding.set(&#39;-&#39;);&#xA;    dontNeedEncoding.set(&#39;_&#39;);&#xA;    dontNeedEncoding.set(&#39;.&#39;);&#xA;    dontNeedEncoding.set(&#39;*&#39;);&#xA;&#xA;        dfltEncName = (String)AccessController.doPrivileged (&#xA;        new GetPropertyAction(&amp;quot;file.encoding&amp;quot;)&#xA;        );&#xA;    }&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;com.sun.org.apache.xml.internal.serializer.Encoding的getMimeEncoding方法(209行起)&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;    static String getMimeEncoding(String encoding)&#xA;    {&#xA;&#xA;        if (null == encoding)&#xA;        {&#xA;            try&#xA;            {&#xA;&#xA;                // Get the default system character encoding.  This may be&#xA;                // incorrect if they passed in a writer, but right now there&#xA;                // seems to be no way to get the encoding from a writer.&#xA;                encoding = System.getProperty(&amp;quot;file.encoding&amp;quot;, &amp;quot;UTF8&amp;quot;);&#xA;&#xA;                if (null != encoding)&#xA;                {&#xA;&#xA;                    /*&#xA;                    * See if the mime type is equal to UTF8.  If you don&#39;t&#xA;                    * do that, then  convertJava2MimeEncoding will convert&#xA;                    * 8859_1 to &amp;quot;ISO-8859-1&amp;quot;, which is not what we want,&#xA;                    * I think, and I don&#39;t think I want to alter the tables&#xA;                    * to convert everything to UTF-8.&#xA;                    */&#xA;                    String jencoding =&#xA;                        (encoding.equalsIgnoreCase(&amp;quot;Cp1252&amp;quot;)&#xA;                            || encoding.equalsIgnoreCase(&amp;quot;ISO8859_1&amp;quot;)&#xA;                            || encoding.equalsIgnoreCase(&amp;quot;8859_1&amp;quot;)&#xA;                            || encoding.equalsIgnoreCase(&amp;quot;UTF8&amp;quot;))&#xA;                            ? DEFAULT_MIME_ENCODING&#xA;                            : convertJava2MimeEncoding(encoding);&#xA;&#xA;                    encoding =&#xA;                        (null != jencoding) ? jencoding : DEFAULT_MIME_ENCODING;&#xA;                }&#xA;                else&#xA;                {&#xA;                    encoding = DEFAULT_MIME_ENCODING;&#xA;                }&#xA;            }&#xA;            catch (SecurityException se)&#xA;            {&#xA;                encoding = DEFAULT_MIME_ENCODING;&#xA;            }&#xA;        }&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;最后一个javax.print.DocFlavor类的静态构造方法:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;    static {&#xA;    hostEncoding = &#xA;        (String)java.security.AccessController.doPrivileged(&#xA;                  new sun.security.action.GetPropertyAction(&amp;quot;file.encoding&amp;quot;));&#xA;    }&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;可以看到,系统变量file.encoding影响到&#xA;1. Charset.defaultCharset() Java环境中最关键的编码设置&#xA;2. URLEncoder.encode(String) Web环境中最常遇到的编码使用&#xA;3. com.sun.org.apache.xml.internal.serializer.Encoding 影响对无编码设置的xml文件的读取&#xA;4. javax.print.DocFlavor 影响打印的编码&lt;/p&gt;&#xA;&#xA;&lt;p&gt;故,影响还是很大的哦, 可以说是Java中编码的一个关键钥匙!&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>动手做一个Nginx Module-简洁版</title>
      <link>http://wendal.net/230.html</link>
      <pubDate>2011-01-24 01:57:22 +0800</pubDate>
      <description>&lt;p&gt;如果在google上搜索Nginx Module,会得到17万条结果,但是,基本上都是千篇一律.&#xA;结合我这段时间的尝试,我决定自己写一篇非常非常简单的入门,仅描述如何做出一个最简单的Hello模块&lt;/p&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;创建一个存放文件的文件夹 命名为 ngx_http_hello_module&#xA;&amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;-&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;    #进入主文件夹&#xA;    cd ~&#xA;    wget http://nginx.org/download/nginx-0.9.4.tar.gz&#xA;    tar xvf nginx-0.9.4.tar.gz&#xA;    cd nginx-0.9.4&#xA;    mkdir ngx_http_hello_module&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;创建config文件,注意,切记要在Linux下创建这个文件!!&#xA;&amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;&amp;ndash;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;    vim config&#xA;    #敲入以下内容&#xA;    ngx_addon_name=ngx_http_hello_module&#xA;    HTTP_MODULES=&amp;quot;$HTTP_MODULES ngx_http_hello_module&amp;quot;&#xA;    NGX_ADDON_SRCS=&amp;quot;$NGX_ADDON_SRCS $ngx_addon_dir/ngx_http_hello_module.c&amp;quot;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;创建ngx_http_hello_module.c文件(请使用本文结尾提供的附件中的文件)&#xA;&amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;&amp;ndash;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;    //通过vim ngx_http_hello_module.c 创建文件并录入下面的内容&#xA;&#xA;    //这3个文件必须导入,很多有用的方法都定义在里面.&#xA;    #include &amp;lt;ngx_config.h&amp;gt;&#xA;    #include &amp;lt;ngx_core.h&amp;gt;&#xA;    #include &amp;lt;ngx_http.h&amp;gt;&#xA;&#xA;    //声明配置方法&#xA;    static char *ngx_http_hello(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);&#xA;&#xA;    //声明这个模块能够识别的配置信息&#xA;    static ngx_command_t  ngx_http_hello_commands[] = {&#xA;    { ngx_string(&amp;quot;hello&amp;quot;),&#xA;      NGX_HTTP_LOC_CONF|NGX_CONF_NOARGS, //仅位于Location里,没有额外参数&#xA;      ngx_http_hello,                                       //指向配置方法&#xA;      NGX_HTTP_LOC_CONF_OFFSET,&#xA;      0,&#xA;      NULL }&#xA;    };&#xA;&#xA;    //定义模块模块上下文,即在nginx解释配置信息时的行为,这里全部为NULL&#xA;    static ngx_http_module_t  ngx_http_hello_module_ctx = {&#xA;        NULL,                               /* preconfiguration */&#xA;        NULL,                               /* postconfiguration */&#xA;&#xA;        NULL,                               /* create main configuration */&#xA;        NULL,                               /* init main configuration */&#xA;&#xA;        NULL,                               /* create server configuration */&#xA;        NULL,                               /* merge server configuration */&#xA;&#xA;        NULL,                   /* create location configuration */&#xA;        NULL                                /* merge location configuration */&#xA;    };&#xA;&#xA;    //定义本模块&#xA;    ngx_module_t  ngx_http_hello_module = {&#xA;        NGX_MODULE_V1,&#xA;        &amp;amp;ngx_http_hello_module_ctx,      /* module context 模块上下文*/&#xA;        ngx_http_hello_commands,         /* module directives  这个模块能够识别的配置信息*/&#xA;        NGX_HTTP_MODULE,               /* module type 一般都是HTTP模块的啦*/ &#xA;        NULL,                          /* init master */&#xA;        NULL,                          /* init module */&#xA;        NULL,                          /* init process */&#xA;        NULL,                          /* init thread */&#xA;        NULL,                          /* exit thread */&#xA;        NULL,                          /* exit process */&#xA;        NULL,                          /* exit master */&#xA;        NGX_MODULE_V1_PADDING&#xA;    };&#xA;&#xA;    //请求处理器,由ngx_http_hello方法向nginx登记&#xA;    static ngx_int_t&#xA;    ngx_http_hello_handler(ngx_http_request_t *r){&#xA;        ngx_int_t                  rc;&#xA;        size_t             size;&#xA;        ngx_chain_t        out;&#xA;        ngx_buf_t         *b;&#xA;&#xA;        ngx_str_set(&amp;amp;r-&amp;gt;headers_out.content_type, &amp;quot;text/plain&amp;quot;);//设置响应的类型为纯文本&#xA;        size = sizeof(&amp;quot;It is OK&amp;quot;);&#xA;        b = ngx_create_temp_buf(r-&amp;gt;pool, size); //获取内存空间&#xA;        if (b == NULL) {&#xA;            return NGX_HTTP_INTERNAL_SERVER_ERROR;&#xA;        }&#xA;        b-&amp;gt;last = ngx_sprintf(b-&amp;gt;last, &amp;quot;It is OK!&amp;quot;); //写入内容到缓存&#xA;        out.buf = b;                                        //将响应体的内容指向b缓存&#xA;        out.next = NULL;&#xA;&#xA;        r-&amp;gt;headers_out.status = NGX_HTTP_OK; //响应码,200&#xA;        r-&amp;gt;headers_out.content_length_n = b-&amp;gt;last - b-&amp;gt;pos;//设置响应体的长度&#xA;&#xA;        b-&amp;gt;last_buf = 1;&#xA; &#xA;        ngx_http_send_header(r);           //发送响应头,如Content-Type    text/plain&#xA;&#xA;        return ngx_http_output_filter(r, &amp;amp;out);//继续其他过滤器&#xA;    };&#xA;&#xA;    //将本模块的处理方法ngx_http_hello_handler登记到nginx配置上下文.&#xA;    static char *ngx_http_hello(ngx_conf_t *cf, ngx_command_t *cmd, void *conf){&#xA;        ngx_http_core_loc_conf_t  *clcf;&#xA;&#xA;        clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);&#xA;        clcf-&amp;gt;handler = ngx_http_hello_handler;&#xA;&#xA;        return NGX_CONF_OK;&#xA;    };&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&lt;h2&gt;开始编译&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;#返回到 ~/nginx-0.9.4&#xA;cd ..&#xA;#执行configure&#xA;./configure &amp;ndash;add-module=ngx_http_hello_module&#xA;#编译 &amp;amp; 安装&#xA;make &amp;amp; make install&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;h2&gt;测试&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;vim /etc/nginx/nginx.conf&#xA;#在server中键入:&#xA;location =/hello {&#xA;    hello;&#xA;}&lt;/p&gt;&#xA;&#xA;&lt;p&gt;#启动nginx&#xA;/usr/local/nginx/sbin/nginx&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;h2&gt;通过浏览器访问 &lt;a href=&#34;http://your_ip/hello&#34;&gt;http://your_ip/hello&lt;/a&gt; 就能看到 It is OK!&lt;/h2&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;p&gt;本文用的的文件: &lt;a href=&#34;/assets/media/2011/01/nginx_http_hello_module.zip&#34;&gt;nginx_http_hello_module.zip&lt;/a&gt;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Nginx不同编译选项得到的二进制文件大小对比</title>
      <link>http://wendal.net/228.html</link>
      <pubDate>2011-01-17 07:45:47 +0800</pubDate>
      <description>&lt;p&gt;Nginx信息:&#xA;版本: 0.9.3&#xA;对原版的修改, 将auto/cc/gcc的-g去掉,将-O改为-O2&#xA;附上原始数据,比较长:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;#默认编译&#xA;./configure&#xA;make&#xA;ll objs/nginx&#xA;make clean&#xA;#File size 525556&#xA;#--with-cc-opt=-g 2444312&#xA;#--with-cc-opt=-g --with-debug 2513996&#xA;&#xA;#加载大部分可选模块&#xA;./configure --with-http_ssl_module \&#xA;        --with-http_realip_module \&#xA;        --with-http_addition_module \&#xA;        --with-http_xslt_module \&#xA;        --with-http_sub_module \&#xA;        --with-http_dav_module \&#xA;        --with-http_flv_module \&#xA;        --with-http_gzip_static_module \&#xA;        --with-http_random_index_module \&#xA;        --with-http_secure_link_module \&#xA;        --with-http_degradation_module \&#xA;        --with-http_stub_status_module \&#xA;        --with-http_perl_module&#xA;make &amp;gt; /dev/null&#xA;ll objs/nginx&#xA;make clean&#xA;#File size 642031&#xA;#--with-cc-opt=-g 4557807&#xA;#--with-cc-opt=-g --with-debug 4689478&#xA;&#xA;#移除大部分可以移除的模块&#xA;./configure         --without-http_charset_module \&#xA;        --without-http_gzip_module \&#xA;        --without-http_ssi_module \&#xA;        --without-http_userid_module \&#xA;        --without-http_access_module \&#xA;        --without-http_auth_basic_module \&#xA;        --without-http_autoindex_module \&#xA;        --without-http_status_module \&#xA;        --without-http_geo_module \&#xA;        --without-http_map_module \&#xA;        --without-http_split_clients_module \&#xA;        --without-http_referer_module \&#xA;        --without-http_rewrite_module \&#xA;        --without-http_proxy_module \&#xA;        --without-http_fastcgi_module \&#xA;        --without-http_uwsgi_module \&#xA;        --without-http_scgi_module \&#xA;        --without-http_memcached_module \&#xA;        --without-http_limit_zone_module \&#xA;        --without-http_limit_req_module \&#xA;        --without-http_empty_gif_module \&#xA;        --without-http_browser_module \&#xA;        --without-http_upstream_ip_hash_module&#xA;make&#xA;ll objs/nginx&#xA;make clean&#xA;#File size 357657&#xA;#--with-cc-opt=-g 1556885&#xA;#--with-cc-opt=-g --with-debug 1616309&#xA;&#xA;#进一步移除Http-Cache&#xA;./configure         --without-http_charset_module \&#xA;        --without-http_gzip_module \&#xA;        --without-http_ssi_module \&#xA;        --without-http_userid_module \&#xA;        --without-http_access_module \&#xA;        --without-http_auth_basic_module \&#xA;        --without-http_autoindex_module \&#xA;        --without-http_status_module \&#xA;        --without-http_geo_module \&#xA;        --without-http_map_module \&#xA;        --without-http_split_clients_module \&#xA;        --without-http_referer_module \&#xA;        --without-http_rewrite_module \&#xA;        --without-http_proxy_module \&#xA;        --without-http_fastcgi_module \&#xA;        --without-http_uwsgi_module \&#xA;        --without-http_scgi_module \&#xA;        --without-http_memcached_module \&#xA;        --without-http_limit_zone_module \&#xA;        --without-http_limit_req_module \&#xA;        --without-http_empty_gif_module \&#xA;        --without-http_browser_module \&#xA;        --without-http_upstream_ip_hash_module \&#xA;        --without-http-cache&#xA;make&#xA;ll objs/nginx&#xA;make clean&#xA;#File size 343543&#xA;#--with-cc-opt=-g 1467019&#xA;#--with-cc-opt=-g --with-debug 1521963&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;附上图表(使用Google Chart).&#xA;&lt;img src=&#34;https://chart.googleapis.com/chart?cht=bvg&amp;amp;chs=700x250&amp;amp;chd=t:642031,525556,357657,343543|4557807,2444312,1556885,1467019|4689478,2513996,1616309,1521963&amp;amp;chco=4d89f9,c6d9fd,0000FF&amp;amp;chxt=y&amp;amp;chds=0,5000000&amp;amp;chxr=0,0,5000000&amp;amp;chdl=Normal|--with-cc-opt=-g|--with-cc-opt=-g%20--with-debug&amp;amp;chg=0,10&#34; alt=&#34;&#34; /&gt;&#xA;&#xA;解释:&#xA;1. 第一组, 添加大部分可选模块 如gzip_static SSL等&#xA;2. 第二组, 默认配置&#xA;3. 第三组, 移除大部分可移除的模块, 使用 &amp;ndash;without-http_XXXX&#xA;4. 第四组, 在第三组基础上,再移除Http-Cache&lt;/p&gt;&#xA;&#xA;&lt;p&gt;图表中的Y轴的单位为字节.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;PS: 本blog使用的Nginx大小为450k,哈哈!&#xA;编译参数:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;root@ubuntu:~# /usr/local/nginx/sbin/nginx -V&#xA;nginx: nginx version: nginx/0.9.3&#xA;nginx: built by gcc 4.4.3 (Ubuntu 4.4.3-4ubuntu5)&#xA;nginx: configure arguments: --user=www --group=www &#xA;--prefix=/usr/local/nginx --with-http_stub_status_module &#xA;--with-http_gzip_static_module --with-cc-opt=-ltcmalloc &#xA;--without-http_empty_gif_module --without-http_split_clients_module &#xA;--without-http_geo_module --without-http_auth_basic_module &#xA;--without-http_memcached_module --with-cpu-opt=pentium4 &#xA;--without-http_uwsgi_module --without-http_scgi_module&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;</description>
    </item>
    <item>
      <title>WP-Codebox乱码问题</title>
      <link>http://wendal.net/227.html</link>
      <pubDate>2011-01-10 10:05:52 +0800</pubDate>
      <description>&lt;p&gt;以前就发现代码高亮插件WP-Codebox在IE下乱码,且行号会分行,可惜CSS水平一直有限,一直未能修正.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;今天人品爆发,加上最近CSS修炼(从无知到极度菜鸟),终于修改成功!!&#xA;需要修改的文件:&#xA;geshi.php 解决乱码:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;var $overall_style = &#39;font-family:monospace;&#39;;&#xA;//改为&#xA;var $overall_style = &#39;&#39;;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;codebox.css 解决行号换行问题(仅解决了100行以内):&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;.line_numbers pre {&#xA;        padding: 0px;&#xA;        margin: 0px;&#xA;        text-align: right;&#xA;        width: 14px; //新加一句&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;</description>
    </item>
    <item>
      <title>Alfresco Virtual tomcat默认不解析EL</title>
      <link>http://wendal.net/226.html</link>
      <pubDate>2011-01-06 10:17:32 +0800</pubDate>
      <description>&lt;p&gt;我正在使用Alfresco 3.3 SP4 , 发现其Virtual tomcat竟然是构建在tomcat5.5上的.&#xA;在jsp页面中写el表达式,死活不出来.最后才发现,是tomcat5.5默认不解析EL !!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;查原因, 在tomcat5.5.31的源码中:&#xA;1. 类名: org.apache.jasper.compiler.JspConfig&#xA;2. 代码:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;if (webApp == null&#xA;     || !&amp;quot;2.4&amp;quot;.equals(webApp.findAttribute(&amp;quot;version&amp;quot;))) {//直接字符串判断,晕!&#xA;     defaultIsELIgnored = &amp;quot;true&amp;quot;;&#xA;     return;&#xA;}&#xA;//如果version不是2.4,那根本不走这里!&#xA;TreeNode jspConfig = webApp.findChild(&amp;quot;jsp-config&amp;quot;);&#xA;if (jspConfig == null) {&#xA;     return;&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;解决方法: :&#xA;第一种,在JSP页面头部加入指令:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;&amp;lt; %@ page isELIgnored=&amp;quot;false&amp;quot; %&amp;gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;第二种,在web.xml中设置version为2.4 :&#xA;第三种,在web.xml中添加一个设置(这解决方法依赖于第二种!!故基本上无效!!!),配置el-ignored为false!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;严重怀疑这个是bug !!&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>发起一个新项目 - NginxS</title>
      <link>http://wendal.net/225.html</link>
      <pubDate>2011-01-03 10:19:25 +0800</pubDate>
      <description>&lt;p&gt;为了更好地阅读/研究Nginx的源码,我奋斗了一个上午,终于把NginxS项目搭建起来了.&#xA;NginxS,就是要研读Nginx的代码,暂时打算做以下两个用途:&#xA;1. 在 &lt;a href=&#34;http://code.google.com/p/nginxs/source/browse/#svn%2Fbranches&#34;&gt;branches&lt;/a&gt; 中提交了0.&lt;sup&gt;7&lt;/sup&gt;&amp;frasl;&lt;sub&gt;0&lt;/sub&gt;.&lt;sup&gt;8&lt;/sup&gt;&amp;frasl;&lt;sub&gt;0&lt;/sub&gt;.9分支的源代码,便于分析不同版本之间的差异,如果官网有新版发布,就会及时跟进.&#xA;2. 在 &lt;a href=&#34;http://code.google.com/p/nginxs/source/browse/#svn%2Ftrunk&#34;&gt;trunk&lt;/a&gt; 中,现在代码是当前最新稳定版0.8.54, 准备用于学习nginx的代码,并添加中文注释/笔记&lt;/p&gt;&#xA;&#xA;&lt;p&gt;项目地址:&#xA;&lt;a href=&#34;http://code.google.com/p/nginxs/&#34;&gt;http://code.google.com/p/nginxs/&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;看看我能读出个啥东西来,哈哈!&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>3年,换了4家公司!</title>
      <link>http://wendal.net/224.html</link>
      <pubDate>2010-12-30 08:43:36 +0800</pubDate>
      <description>&lt;p&gt;不久前还说着一个朋友经常跳槽,昨天才发现,跳得最多的其实是自己!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;3年,不容易啊,换了4家!!&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;第一家,A公司, 200来人,干了5个月,美资&#xA;第二家,B公司,2000来人,干了9个月,印度公司&#xA;第三家,C公司,200来人,干了21个月,印度公司&#xA;第四家,D公司,5000人,干了1天,美资&lt;/p&gt;&#xA;&#xA;&lt;p&gt;^_^,2次被收购,1次被分拆,然而我仍在同一个办公室!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;想不到都年底了,又被收购了一次. 哈哈&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>增强型JavaDoc -- APIviz 简洁实践</title>
      <link>http://wendal.net/222.html</link>
      <pubDate>2010-12-27 01:40:55 +0800</pubDate>
      <description>&lt;p&gt;一段时间之前,为Nutz的JavaDoc添加了这个插件,&lt;a href=&#34;http://code.google.com/p/apiviz/&#34;&gt;APIviz&lt;/a&gt;,可以自动生成包依赖关系图,和简单的UML类图.&#xA;在国内还没见到公开的使用,还是介绍一下,&lt;a href=&#34;http://build.sunfarms.net/nutz/lastest/api/&#34;&gt;Nutz示例&lt;/a&gt;&#xA;第一步,安装&lt;a href=&#34;http://www.graphviz.org/&#34;&gt;Graphviz&lt;/a&gt;,该软件可以运行在N多平台上,这里以Ubuntu为例&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;apt-get install graphviz&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;第二步,当然就是下载APIviz了, 当前最新版为 1.3.1 GA&#xA;第三步, Ant调用:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;&amp;lt;javadoc doclet=&amp;quot;org.jboss.apiviz.APIviz&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; sourcepath=&amp;quot;src&amp;quot; docletpath=&amp;quot;${basedir}/build/deps/apiviz-1.3.1.GA.jar&amp;quot; charset=&amp;quot;utf-8&amp;quot; destdir=&amp;quot;${javadoc-dir}&amp;quot; additionalparam=&amp;quot;-author -version -sourceclasspath ${classes-dir-jdk6}&amp;quot; classpathref=&amp;quot;nutz-classpath&amp;quot; docencoding=&amp;quot;utf-8&amp;quot;&amp;gt;&amp;lt;/javadoc&amp;gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;与普通的JavaDoc相比,添加了3个属性:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;#引用APIviz&#xA;doclet=&amp;quot;org.jboss.apiviz.APIviz&amp;quot; &#xA;#指向APIviz的jar包&#xA;docletpath=&amp;quot;${basedir}/build/deps/apiviz-1.3.1.GA.jar&amp;quot; &#xA;#声明类文件的路径,其余的-author -version是官网上建议添加的,非必需.&#xA;#这里的${classes-dir-jdk6}就是Nutz编译好的class存放的地址&#xA;additionalparam=&amp;quot;-author -version -sourceclasspath ${classes-dir-jdk6}&amp;quot;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;这样,就可以自动生成全部包依赖关系了,执行的时候,需要一点点耐心哦&#xA;顺带说一下,这APIviz应该是Jboss的产品&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Nutz终于beta版了!!</title>
      <link>http://wendal.net/220.html</link>
      <pubDate>2010-12-24 07:00:19 +0800</pubDate>
      <description>&lt;p&gt;前前后后33版,我参与了 19(16~34)个版本,哈哈~~&#xA;文件已经上传到Google Code, 非常鸡冻!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;另外, 提交到Maven现在正在进行中,缓慢地上传&amp;hellip; 我可是1M的小水管.&#xA;顺便Mask一下生产asc签名的方法,copy自&lt;a href=&#34;http://www.madboa.com/geek/gpg-quickstart/&#34;&gt;GPG快速入门&lt;/a&gt;:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;gpg --armor --detach-sign your-file.zip&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;</description>
    </item>
    <item>
      <title>Log4j 分级输出</title>
      <link>http://wendal.net/219.html</link>
      <pubDate>2010-12-20 12:18:12 +0800</pubDate>
      <description>&lt;p&gt;一直以来,我都以为Log4j仅能配置输出日志的最低等级,不能限定只输出某一/某些特定等级,今天,无意中发现了其实是可以的.&#xA;先上一份普通的log4j.properties&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;log4j.rootLogger=INFO, Console, File&#xA;&#xA;###### Console appender definition #######&#xA;log4j.appender.Console=org.apache.log4j.ConsoleAppender&#xA;log4j.appender.Console.layout=org.apache.log4j.PatternLayout&#xA;log4j.appender.Console.layout.ConversionPattern=%d{ABSOLUTE} %x %-5p [%c{3}] %m%n&#xA;&#xA;###### File appender definition #######&#xA;log4j.appender.File=org.apache.log4j.DailyRollingFileAppender&#xA;log4j.appender.File.File=alfresco.log&#xA;log4j.appender.File.Append=true&#xA;log4j.appender.File.DatePattern=&#39;.&#39;yyyy-MM-dd&#xA;log4j.appender.File.layout=org.apache.log4j.PatternLayout&#xA;log4j.appender.File.layout.ConversionPattern=%d{ABSOLUTE} %-5p [%c] %m%n&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;现在需要定义一个名为File2的appender ,仅记录INFO和ERROR,哈哈,有请Log4j的Filter&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;log4j.appender.File2=org.apache.log4j.DailyRollingFileAppender&#xA;log4j.appender.File2.File=alfresco2.log&#xA;log4j.appender.File2.Append=true&#xA;log4j.appender.File2.DatePattern=&#39;.&#39;yyyy-MM-dd&#xA;log4j.appender.File2.layout=org.apache.log4j.PatternLayout&#xA;log4j.appender.File2.layout.ConversionPattern=%d{ABSOLUTE} %-5p [%c] %m%n&#xA;&#xA;#配置Filter&#xA;#定义id为F1的拦截器,只接受INFO到ERROR&#xA;log4j.appender.File2.filter.F1=org.apache.log4j.varia.LevelRangeFilter&#xA;log4j.appender.File2.filter.F1.LevelMin=INFO&#xA;log4j.appender.File2.filter.F1.LevelMax=ERROR&#xA;#定义id为F2的拦截器,不接受WARN&#xA;log4j.appender.File2.filter.F2=org.apache.log4j.varia.LevelMatchFilter&#xA;log4j.appender.File2.filter.F2.levelToMatch=WARN&#xA;log4j.appender.File2.filter.F2.acceptOnMatch=false&#xA;#可以继续定义你需要的拦截器F3/F4.....&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;通过定义不同组合的LevelRangeFilter/LevelMatchFilter,让特定的appender只记录你需要的log等级,非常方便的!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;详细参考,请查阅Log4j:&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&#34;http://logging.apache.org/log4j/1.2/apidocs/&#34;&gt;JavaDoc&lt;/a&gt;&#xA;&lt;a href=&#34;http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/spi/Filter.html&#34;&gt;Filter&lt;/a&gt;&#xA;&lt;a href=&#34;http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/PropertyConfigurator.html&#34;&gt;PropertyConfigurator&lt;/a&gt;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>禁用/消除 MySQL客户端的报警声</title>
      <link>http://wendal.net/218.html</link>
      <pubDate>2010-12-17 02:49:58 +0800</pubDate>
      <description>&lt;p&gt;有时候需要用MySQL客户端导入sql文件,一不小心就容易出错,然后就是一段刺耳的报警声,很是烦人!&#xA;Google一下,发现2种方法&lt;/p&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&lt;p&gt;&lt;a href=&#34;http://hi.baidu.com/abunchofgrape/blog/item/7211bd510a83485b1138c22c.html&#34;&gt;直接在服务器端禁用&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;[mysql]&#xA;no-beep&#xA;#&amp;hellip;. other configure&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;或者仅仅在本地使用mysql客户端时禁用,执行命令时多加一个参数 -b&lt;/p&gt;&#xA;&#xA;&lt;p&gt;mysql -p -u root -b&lt;/p&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;</description>
    </item>
    <item>
      <title>从源码编译MySQL 5.5 -- 简单版</title>
      <link>http://wendal.net/217.html</link>
      <pubDate>2010-12-16 01:53:13 +0800</pubDate>
      <description>&lt;p&gt;&lt;a href=&#34;http://dev.mysql.com/downloads/mysql/&#34;&gt;MySQL 5.5&lt;/a&gt;分支,今天&lt;a href=&#34;http://www.oschina.net/news/13830/mysql-5-5-final&#34;&gt;终于发布 5.5.8 GA&lt;/a&gt;了.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;一贯风格,尝鲜,马上编译之. 折腾了一段时间,发现需要用&lt;a href=&#34;http://www.cmake.org/&#34;&gt;cmake&lt;/a&gt;进行配置了&lt;/p&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&lt;p&gt;先安装cmake和ccmake&lt;/p&gt;&#xA;&#xA;&lt;p&gt;sudo apt-get install cmake cmake-curses-gui libncurses5-dev&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;下载并解压mysql-5.5.8.tar.gz到mysql-5.5.8&lt;/p&gt;&#xA;&#xA;&lt;p&gt;wget -o mysql-5.5.8.tar.gz &lt;a href=&#34;http://dev.mysql.com/get/Downloads/MySQL-5.5/mysql-5.5.8.tar.gz/from/http://mirror.csclub.uwaterloo.ca/mysql/&#34;&gt;http://dev.mysql.com/get/Downloads/MySQL-5.5/mysql-5.5.8.tar.gz/from/http://mirror.csclub.uwaterloo.ca/mysql/&lt;/a&gt;&#xA;tar xvf mysql-5.5.8.tar.gz&#xA;cd mysql-5.5.8&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;然后执行ccmake进行配置,建议将CMAKE_BUILD_TYPE设置为Release&lt;/p&gt;&#xA;&#xA;&lt;p&gt;sudo ccmake .&#xA;#或者 cmake -i 对话式配置&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;如果嫌第三步麻烦,那么直接执行&lt;/p&gt;&#xA;&#xA;&lt;p&gt;sudo cmake .&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;剩下的就是常规操作了&lt;/p&gt;&#xA;&#xA;&lt;p&gt;#编译&#xA;sudo make&#xA;#跑一下测试,全部Pass&#xA;sudo make test&#xA;#安装&#xA;sudo make install&lt;/p&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;</description>
    </item>
    <item>
      <title>JavaMail 调试参数设置</title>
      <link>http://wendal.net/214.html</link>
      <pubDate>2010-12-16 09:17:24 +0800</pubDate>
      <description>&lt;p&gt;这周折腾Alfresco升级,同时也发现Alfresco 3.3 SP4 的一个bug &amp;ndash; &lt;a href=&#34;https://issues.alfresco.com/jira/browse/ALF-6186&#34;&gt;mail.smtp.auth不起效&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;故顺便看看这个配置在代码中的位置,到处寻觅&lt;a href=&#34;http://www.oracle.com/technetwork/java/index-jsp-139225.html&#34;&gt;JavaMail&lt;/a&gt;的源码,终于在&lt;a href=&#34;http://kenai.com/projects/javamail/downloads&#34;&gt;kenai&lt;/a&gt;找到,不过其实我已经用&lt;a href=&#34;http://java.decompiler.free.fr/?q=jdgui&#34;&gt;JD-GUI&lt;/a&gt;反编译看了一下&lt;/p&gt;&#xA;&#xA;&lt;p&gt;找到以下代码:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;String str2 = this.jdField_session_of_type_JavaxMailSession.getProperty(&amp;quot;mail.&amp;quot; + this.name + &amp;quot;.auth&amp;quot;);&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;另外找到一个比较详细的&lt;a href=&#34;http://hi.baidu.com/jlhh/blog/item/823341434fdca71b9313c620.html&#34;&gt;JavaMail参数表&lt;/a&gt;,但是缺少了一个调试用的参数 &amp;ndash; mail.debug = true , 默认是false, 调试时加上,很多信息哦,O(∩_∩)O哈哈~&lt;/p&gt;&#xA;&#xA;&lt;p&gt;后续报道: &lt;a href=&#34;http://java.sun.com/products/javamail/javadocs/index.html&#34;&gt;官方API&lt;/a&gt;中已经有mail.debug , 看来有点多此一举了&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>让Nginx的SSI支持相对路径--更安全的方法</title>
      <link>http://wendal.net/212.html</link>
      <pubDate>2010-12-14 02:04:24 +0800</pubDate>
      <description>&lt;p&gt;这个比较老生长谈的问题,例如 文章 &lt;a href=&#34;http://bbs.linuxtone.org/thread-6515-1-1.html&#34;&gt;关于nginx的ssi&lt;/a&gt;&#xA;但,这种改法,实在不安全.毕竟全局的函数都被改了,任意的../../../都能被访问&#xA;故,基于我对nginx的了解,使用另外一种改法,仅仅修改SSI模块,安全性相对较高&#xA;修改src/http/modules/ngx_http_ssi_filter_module.c&#xA;找到以下代码(以nginx 0.9.3版为例):&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;    if (ngx_http_parse_unsafe_uri(r, uri, &amp;amp;args;, &amp;amp;flags;) != NGX_OK) {&#xA;        return NGX_HTTP_SSI_ERROR;&#xA;    }&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;将上述代码注释掉或直接删掉,然后按一般方法编译nginx即可(可以参考&lt;a href=&#34;/186.html&#34;&gt;升级到0.9.0&lt;/a&gt;).&#xA;测试代码:&#xA;文件1 &amp;mdash; index.html&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;测试导入&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;文件2 &amp;ndash; subdir/index.html&lt;/p&gt;&#xA;&#xA;&lt;p&gt;访问subdir/index.html,测试通过!&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Jxl与WPS的一点点不兼容</title>
      <link>http://wendal.net/211.html</link>
      <pubDate>2010-12-10 02:18:56 +0800</pubDate>
      <description>&lt;p&gt;今天与同事探讨了一个诡异的问题,用Jxl处理一个空的excel文件,&lt;strong&gt;第二次&lt;/strong&gt;运行就报错,代码如下:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;Workbook workbook = Workbook.getWorkbook(new File(&amp;quot;Book1.xls&amp;quot;));&#xA;WritableWorkbook w = Workbook.createWorkbook(new File(&amp;quot;Book1.xls&amp;quot;),workbook);&#xA;w.write();&#xA;w.close();&#xA;workbook.close();&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;很平常的代码而已,第一次运行,Pass,第二次,FAIL! 然后把旧的空xls文件覆盖回去,第一依然PASS,再跑就FAIL&#xA;折腾来折腾去,终于发现是因为这个xls文件是右键新建出来的. 如果打开WPS,然后新建一个,然后保存,就完全没有问题!!&#xA;够诡异了吧&amp;hellip; WPS的版本是: 6.6.0.2461&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>将Dom对象变成XML并写入流</title>
      <link>http://wendal.net/210.html</link>
      <pubDate>2010-12-10 12:37:21 +0800</pubDate>
      <description>&lt;p&gt;昨晚在Q群上,一位群友需要解决这样的需求:&#xA;将一个Dom对象,变回XML文本,并写入流中,以便下载.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;我想,为啥不直接让Dom对象边转换,边写入流呢? 这样效率应该最高哦,内存占用也会低.&#xA;故马上Google,查到&lt;a href=&#34;http://download.oracle.com/javaee/1.4/tutorial/doc/JAXPXSLT4.html&#34;&gt;一篇文章相关的文章(Writing Out a DOM as an XML File)&lt;/a&gt;,感觉上是能够解决这个问题的.&#xA;原文是英文,而且一大堆解释,我精简如下:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;//先创建一个Dom&#xA;DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();&#xA;DocumentBuilder builder = factory.newDocumentBuilder();&#xA;Document document = builder.parse(new File(&amp;quot;faces-config-beans.xml&amp;quot;));&#xA;//然后应用转换器&#xA;TransformerFactory tFactory = TransformerFactory.newInstance();&#xA;Transformer transformer = tFactory.newTransformer();&#xA;DOMSource source = new DOMSource(document);&#xA;StreamResult result = new StreamResult(os);//这里的os就是OutputStream对象.&#xA;transformer.transform(source, result);&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;手头没有更大的XML文件,故只拿了一个200k的XML,Dom&amp;ndash;&amp;gt;Stream的时间,约60ms. 算是可以接受了.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>一次内存泄漏的排查</title>
      <link>http://wendal.net/208.html</link>
      <pubDate>2010-12-09 09:07:10 +0800</pubDate>
      <description>&lt;p&gt;昨天,又有一位用户抱怨&lt;a href=&#34;http://code.google.com/p/sunfarm&#34;&gt;阳光牧场助手&lt;/a&gt;的内存占用过高&#xA;问用户拿到20来个帐号后,用助手加载,启动,得到一些GC的数据:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;409.879: [Full GC 409.879: [Tenured: 349567K-&amp;gt;349567K(349568K), 1.5796790 secs] 506815K-&amp;gt;382998K(506816K), [Perm : 15879K-&amp;gt;15879K(65536K)], 1.5797868 secs] [Times: user=1.55 sys=0.00, real=1.58 secs] &#xA;417.784: [Full GC 417.784: [Tenured: 349567K-&amp;gt;349568K(349568K), 1.6968523 secs] 506815K-&amp;gt;382777K(506816K), [Perm : 15880K-&amp;gt;15878K(65536K)], 1.6969534 secs] [Times: user=1.68 sys=0.00, real=1.69 secs] &#xA;422.242: [Full GC 422.242: [Tenured: 349568K-&amp;gt;349568K(349568K), 1.5697638 secs] 506815K-&amp;gt;382844K(506816K), [Perm : 15879K-&amp;gt;15879K(65536K)], 1.5698652 secs] [Times: user=1.56 sys=0.00, real=1.56 secs] &#xA;Heap&#xA; def new generation   total 157248K, used 156479K [0x029e0000, 0x0d480000, 0x0d480000)&#xA;  eden space 139776K, 100% used [0x029e0000, 0x0b260000, 0x0b260000)&#xA;  from space 17472K,  95% used [0x0b260000, 0x0c2afda8, 0x0c370000)&#xA;  to   space 17472K,   0% used [0x0c370000, 0x0c370000, 0x0d480000)&#xA; tenured generation   total 349568K, used 349568K [0x0d480000, 0x229e0000, 0x229e0000)&#xA;   the space 349568K, 100% used [0x0d480000, 0x229e0000, 0x229e0000, 0x229e0000)&#xA; compacting perm gen  total 65536K, used 16259K [0x229e0000, 0x269e0000, 0x2a9e0000)&#xA;   the space 65536K,  24% used [0x229e0000, 0x239c0e98, 0x239c1000, 0x269e0000)&#xA;No shared spaces configured.&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;由于新生代应该会很快回收,故关注另外一块已经用完的空间tenured generation&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt; tenured generation   total 349568K, used 349568K [0x0d480000, 0x229e0000, 0x229e0000)&#xA;   the space 349568K, 100% used [0x0d480000, 0x229e0000, 0x229e0000, 0x229e0000)&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;足足用掉了340M,怎么会这样呢? 最后几次都是FULL GC,故肯定是有对象一直被引用,而且用了很多内存.&#xA;用jmap把内存镜像抓下来&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;jmap -dump:format=b,file=heap.bin 1936&#xA;#1936是进程号pid&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;然后使用 &lt;a href=&#34;http://www.eclipse.org/mat/&#34;&gt;Eclipse Memory Analyzer&lt;/a&gt; 打开heap.bin , 经过漫长的等待后&#xA;不跑任何分析,直接在Overview视图,点开Dominator Tree, 哇!!! 严重震惊了,数据如下:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;Class Name                                                         | Shallow Heap | Retained Heap | Percentage &#xA;--------------------------------------------------------------------------------------------------------------&#xA;                                                                   |              |               |            &#xA;com.goojia.xiaonei.sunfarm.Config @ 0x144f8ea8                     |          136 |    15,856,928 |      4.04% &#xA;com.goojia.xiaonei.sunfarm.Config @ 0x135aa160                     |          136 |    15,856,880 |      4.04% &#xA;com.goojia.xiaonei.sunfarm.Config @ 0x1080dba8                     |          136 |    15,856,872 |      4.04% &#xA;com.goojia.xiaonei.sunfarm.Config @ 0x13382830                     |          136 |    15,856,872 |      4.04% &#xA;com.goojia.xiaonei.sunfarm.Config @ 0x1359cf10                     |          136 |    15,856,872 |      4.04% &#xA;com.goojia.xiaonei.sunfarm.Config @ 0x107e8a28                     |          136 |    15,856,864 |      4.04% &#xA;com.goojia.xiaonei.sunfarm.Config @ 0x117244d0                     |          136 |    15,856,856 |      4.04% &#xA;com.goojia.xiaonei.sunfarm.Config @ 0x12413010                     |          136 |    15,856,840 |      4.04% &#xA;com.goojia.xiaonei.sunfarm.Config @ 0x133913b0                     |          136 |    15,856,840 |      4.04% &#xA;com.goojia.xiaonei.sunfarm.Config @ 0x140dc1c8                     |          136 |    15,856,840 |      4.04% &#xA;com.goojia.xiaonei.sunfarm.Config @ 0x140d6c10                     |          136 |    15,856,824 |      4.04% &#xA;com.goojia.xiaonei.sunfarm.Config @ 0x10152860                     |          136 |    15,856,768 |      4.04% &#xA;com.goojia.xiaonei.sunfarm.Config @ 0x107ecc68                     |          136 |    15,856,768 |      4.04% &#xA;com.goojia.xiaonei.sunfarm.Config @ 0x144f7050                     |          136 |    15,856,736 |      4.04% &#xA;com.goojia.xiaonei.sunfarm.Config @ 0x1300c4d8                     |          136 |    15,856,720 |      4.04% &#xA;com.goojia.xiaonei.sunfarm.Config @ 0x117267b8                     |          136 |    15,856,712 |      4.04% &#xA;com.goojia.xiaonei.sunfarm.Config @ 0x107e8f20                     |          136 |    15,856,696 |      4.04% &#xA;com.goojia.xiaonei.sunfarm.Config @ 0xf8796a0                      |          136 |    15,856,648 |      4.04% &#xA;com.goojia.xiaonei.sunfarm.Config @ 0xf882128                      |          136 |    15,856,576 |      4.04% &#xA;com.goojia.xiaonei.sunfarm.Config @ 0xf87ea38                      |          136 |    15,856,416 |      4.04% &#xA;com.goojia.xiaonei.sunfarm.Config @ 0xf8bd308                      |          136 |    15,856,416 |      4.04% &#xA;com.goojia.xiaonei.sunfarm.Config @ 0xf87fb40                      |          136 |    15,856,408 |      4.04% &#xA;com.goojia.xiaonei.sunfarm.Config @ 0x140d7aa0                     |          136 |    15,856,280 |      4.04% &#xA;com.goojia.xiaonei.sunfarm.Config @ 0xf8ac2a8                      |          136 |    15,856,080 |      4.04% &#xA;com.goojia.xiaonei.sunfarm.Context @ 0x140d8970                    |          120 |     1,105,208 |      0.28% &#xA;class com.goojia.sunfarm.TextAreaAppender @ 0x25095de8 System Class|           16 |       501,512 |      0.13% &#xA;class java.lang.Integer$IntegerCache @ 0x24e2cdb8 System Class     |            8 |       401,032 |      0.10% &#xA;com.goojia.xiaonei.sunfarm.Context @ 0x140dc330                    |          120 |       339,344 |      0.09% &#xA;com.goojia.xiaonei.sunfarm.Context @ 0x13391438                    |          120 |       338,536 |      0.09% &#xA;com.goojia.xiaonei.sunfarm.Context @ 0x117245a0                    |          120 |       337,376 |      0.09% &#xA;Total: 30 of 8,160 entries                                         |              |               |            &#xA;--------------------------------------------------------------------------------------------------------------&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Config对象竟然占用了300多M,而且很准确的与帐号数一样,因为那是一一对应的.但,不对啊,怎么这么多呢? 打开一个Config看看&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;Class Name                                           | Shallow Heap | Retained Heap | Percentage &#xA;------------------------------------------------------------------------------------------------&#xA;com.goojia.xiaonei.sunfarm.Config @ 0x144f8ea8       |          136 |    15,856,928 |      4.04% &#xA;|- com.goojia.xiaonei.sunfarm.DataMap @ 0x144f8fa8   |           56 |    15,854,760 |      4.04% &#xA;|- java.util.HashSet @ 0x17d01f50                    |           16 |           560 |      0.00% &#xA;|- java.util.HashSet @ 0x17d01da8                    |           16 |           424 |      0.00% &#xA;|- java.util.HashSet @ 0x17d02208                    |           16 |           232 |      0.00% &#xA;|- java.lang.String[4] @ 0x17d02530                  |           32 |           224 |      0.00% &#xA;|- java.util.HashSet @ 0x17d02180                    |           16 |           136 |      0.00% &#xA;|- java.lang.String @ 0x179f3478  guanghuiyuan@qq.com|           24 |            80 |      0.00% &#xA;|- java.lang.String[1] @ 0x17d01d28                  |           16 |            64 |      0.00% &#xA;|- java.lang.String[1] @ 0x17d01d68                  |           16 |            64 |      0.00% &#xA;|- java.lang.String @ 0x179f34c8  qs828000           |           24 |            56 |      0.00% &#xA;|- java.lang.String[10] @ 0x17d02330                 |           56 |            56 |      0.00% &#xA;|- java.lang.String @ 0x17d01d00  xn                 |           24 |            40 |      0.00% &#xA;|- java.lang.String @ 0x17d022e0  3                  |           24 |            40 |      0.00% &#xA;|- java.lang.String @ 0x17d02308  30                 |           24 |            40 |      0.00% &#xA;|- java.lang.String[1] @ 0x17d02610                  |           16 |            16 |      0.00% &#xA;&#39;- Total: 15 entries                                 |              |               |            &#xA;------------------------------------------------------------------------------------------------&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;哦? 是DataMap类的实例? 进行展开&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;Class Name                                              | Shallow Heap | Retained Heap | Percentage &#xA;---------------------------------------------------------------------------------------------------&#xA;com.goojia.xiaonei.sunfarm.DataMap @ 0x144f8fa8         |           56 |    15,854,760 |      4.04% &#xA;|- net.sf.ezmorph.bean.MorphDynaBean @ 0x20b6f3f0       |           24 |    15,734,664 |      4.01% &#xA;|- java.util.HashMap @ 0x144f9108                       |           40 |        31,912 |      0.01% &#xA;|- java.util.HashMap @ 0x144f9130                       |           40 |        16,504 |      0.00% &#xA;|- java.util.HashMap @ 0x144f9068                       |           40 |        10,464 |      0.00% &#xA;|- java.util.HashMap @ 0x144f90b8                       |           40 |         6,432 |      0.00% &#xA;|- java.util.HashMap @ 0x144f9090                       |           40 |         4,216 |      0.00% &#xA;|- java.util.HashMap @ 0x144f90e0                       |           40 |         4,024 |      0.00% &#xA;|- java.text.DecimalFormat @ 0x144f8fe0                 |          136 |           672 |      0.00% &#xA;|- java.lang.String @ 0x20d78370  shenqichinesecrabapple|           24 |            80 |      0.00% &#xA;|- java.lang.String @ 0x20d7cdd0  shenqiparadiseflower  |           24 |            80 |      0.00% &#xA;|- java.lang.String @ 0x20d85b78  caomeilianrubaobing   |           24 |            80 |      0.00% &#xA;|- java.lang.String @ 0x20d8c560  shenqiPutianBlackPig  |           24 |            80 |      0.00% &#xA;|- java.lang.String @ 0x20d957d8  shengzhuanghuanxiong  |           24 |            80 |      0.00% &#xA;|- java.lang.String @ 0x20d97370  shenqishuangfengluotuo|           24 |            80 |      0.00% &#xA;|- java.lang.String @ 0x20d75070  hongtouzhuomuniao     |           24 |            72 |      0.00% &#xA;|- java.lang.String @ 0x20d78470  shenqinigerseed       |           24 |            72 |      0.00% &#xA;|- java.lang.String @ 0x20d78568  wanshengjienangua     |           24 |            72 |      0.00% &#xA;|- java.lang.String @ 0x20d78950  gaojishengdanhong     |           24 |            72 |      0.00% &#xA;|- java.lang.String @ 0x20d7a518  tianshanxuelian       |           24 |            72 |      0.00% &#xA;|- java.lang.String @ 0x20d7b780  hongbailanmeigui      |           24 |            72 |      0.00% &#xA;|- java.lang.String @ 0x20d7d410  munaiyinan_farm       |           24 |            72 |      0.00% &#xA;|- java.lang.String @ 0x20d7d898  shenqima_ti_lian      |           24 |            72 |      0.00% &#xA;|- java.lang.String @ 0x20d80770  ziyezuojiangcao       |           24 |            72 |      0.00% &#xA;|- java.lang.String @ 0x20d822e8  shenqisweetviolet     |           24 |            72 |      0.00% &#xA;|- java.lang.String @ 0x20d82790  chinesecrabapple      |           24 |            72 |      0.00% &#xA;&#39;- Total: 25 of 934 entries                             |              |               |            &#xA;---------------------------------------------------------------------------------------------------&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;哦!!!!!!!! 原来是一个MorphDynaBean 的实例!! 但是DataMap不应该持有这个类的实例的啊,仅仅是初始化的时候,作为过程量传进入而已&#xA;稍微读了一下代码,发现这个DataMap类,发现对于这个实例变量有2个用途&#xA;1. 仅仅只是把bean赋值为一个实例变量:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;this.bean = bean;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&lt;p&gt;加载文件,转换为对象,赋值给实例变量,然后再另外一个方法中获取&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;    public boolean initFromLocal() {&#xA;            loadDataFromLocal(); #这个方法仅仅在这里被调用,目的就是为this.bean赋值&#xA;            if (null != this.bean) {&#xA;                    initSeeds(bean);&#xA;                    initBabies(bean);&#xA;                    writeSeedReferenceFile();&#xA;                    return true;&#xA;            } else {&#xA;                    return false;&#xA;            }&#xA;    }&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;p&gt;显然,我轻微改动一下代码,这对象就不会被持有了! &lt;a href=&#34;http://code.google.com/p/sunfarm/source/diff?spec=svn887&amp;amp;r=887&amp;amp;format=side&amp;amp;path=/trunk/sunfarm/src/com/goojia/xiaonei/sunfarm/DataMap.java&#34;&gt;具体改动&lt;/a&gt;,就是去掉实例变量,改为过程量!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;就这样,内存就直接减下来了!! 哦也,搞定!Config对象占用的内存,从15M减到200K ,即减少98.7%!&#xA;仅仅几行代码的更改,使助手在相同内存占用的情况下,每100M内存,多运行20倍以上的帐号!!&#xA;故马上发布了助手的3.51版,哈哈!!&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>升级,升级,还是升级</title>
      <link>http://wendal.net/206.html</link>
      <pubDate>2010-12-09 12:56:44 +0800</pubDate>
      <description>&lt;p&gt;今天,升级了好几样东西&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&#34;http://nginx.org/en/download.html&#34;&gt;Nginx&lt;/a&gt; 0.9.1        &amp;mdash;&amp;gt;  0.9.2           新增一个功能.修复几个bug&#xA;&lt;a href=&#34;http://cn.wordpress.org/&#34;&gt;Wordpress&lt;/a&gt; 3.0.2             &amp;mdash;&amp;gt;  3.0.3           修复一个安全问题,号称之前所有版本都存在&#xA;&lt;a href=&#34;http://www.alfresco.com&#34;&gt;Alfresco&lt;/a&gt; 3.3.3.7             &amp;mdash;&amp;gt;  3.3.4           修复几个严重的bug,其中一个是无法容忍的&#xA;&lt;a href=&#34;http://code.google.com/p/sunfarm/&#34;&gt;阳光牧场助手&lt;/a&gt; 3.50  &amp;mdash;&amp;gt;  3.51            大幅优化内存占用,锐减90%以上&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>推荐: 国外公开课</title>
      <link>http://wendal.net/201.html</link>
      <pubDate>2010-12-04 05:32:04 +0800</pubDate>
      <description>&lt;p&gt;&lt;a href=&#34;http://v.163.com/open/&#34;&gt;网易视频-国外公开课&lt;/a&gt;&#xA;&lt;a href=&#34;http://yyets.net/?mod=2&amp;amp;ac=list_resource&amp;amp;class=juji&amp;amp;type=29&#34;&gt;人人影视-国外公开课&lt;/a&gt;&#xA;&lt;strong&gt;开眼看世界,国外优秀的公开课! 思维比知识更重要!! 思想进步,才能升华人生. 扔掉马哲,扔掉政治经济学,扔掉学校给你灌的垃圾!!&lt;/strong&gt;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Spket其实是兼容 jQuery 1.4.x的!</title>
      <link>http://wendal.net/197.html</link>
      <pubDate>2010-12-04 12:02:19 +0800</pubDate>
      <description>&lt;p&gt;前几天,折腾Spket,安装好后,配置jQuery,死活不出提示!!&#xA;翻阅Google,到处都说Spket不兼容jQuery 1.4.x .但经过我一番探索,终于发现 &lt;a href=&#34;http://forums.spket.com/viewtopic.php?f=7&amp;amp;t=1380&amp;amp;start=0&#34;&gt;官网一个论坛帖子&lt;/a&gt; 上面附带的jar就能成功!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;我自己打包好一个版本,放到Google Docs上了, &lt;a href=&#34;https://docs.google.com/leaf?id=0B8hUXYDeoy_hOGNjY2NkODAtNDliZC00NzkxLTllNDAtNjNlOGZkMTllNWEw&amp;amp;hl=zh_CN&amp;amp;authkey=CLiin-4F&#34;&gt;Spket 1.6.18 兼容jQuery1.4.x&lt;/a&gt;,是一个Eclipse插件版本&lt;/p&gt;&#xA;&#xA;&lt;p&gt;如果你已经安装好原版的Spket 1.6.8 , 仅提取com.spket.js_1.6.18.jar覆盖原文件也就可以了.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;官方很久没更新了,哈哈!!&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>归还技术债务--Alfresco升级记</title>
      <link>http://wendal.net/191.html</link>
      <pubDate>2010-12-01 10:17:45 +0800</pubDate>
      <description>&lt;p&gt;这周开始，按领导的意思，开始着力升级Alfresco到3.3.3 (发现已经发布3.3.3.7 改为升级最新3.x版本)&lt;/p&gt;&#xA;&#xA;&lt;p&gt;了解升级步骤，下载升级需要的war包。部署到测试环境，一切都似乎很顺利。&#xA;启动！！ 等待了3分钟，报错了！！ 大意是 之前的升级未完成！！&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;13:12:29,186 ERROR [org.alfresco.repo.domain.schema.SchemaBootstrap] Schema auto-update failed&#xA;org.alfresco.error.AlfrescoRuntimeException: 11010000 A previous schema upgrade failed or was not completed.  Revert to the original database before attempting the upgrade again.&#xA;    at org.alfresco.repo.domain.schema.SchemaBootstrap.onBootstrap(SchemaBootstrap.java:1373)&#xA;    at org.alfresco.util.AbstractLifecycleBean.onApplicationEvent(AbstractLifecycleBean.java:62)&#xA;    at org.springframework.context.event.SimpleApplicationEventMulticaster$1.run(SimpleApplicationEventMulticaster.java:77)&#xA;    at org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:49)&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;查阅 &lt;a href=&#34;http://wiki.alfresco.com/wiki/Schema_Upgrade_Scripts&#34;&gt;Alfresco升级指南-Schema升级&lt;/a&gt; 发现，多了一个表 alf_bootstrap_lock，删除之！&#xA;再次启动，Alfresco竟然开始建表了！！ 百思不得其解！！&#xA;没办法，出我的绝招，看源码/反编译！&#xA;研究了好久，尝试启动无数次后，发现，这Alfresco直接无视数据库中的表！！！ Why？？？！！！！&#xA;最后，发现Alfresco是通过Databasemeta来获取表信息的，其中的getTables方法，传入了catalog和schema的值。其中catalog我并未定义，为null，schema的值我设置为alfresco 。 难道。。。 难道。。。 大小写的问题！！！！ 猛然改为&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;hibernate.default_schema=ALFRESCO&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;一直以来都无视这个，虽然&lt;a href=&#34;http://wiki.alfresco.com/wiki/Database_Configuration&#34;&gt;Alfresco数据库配置&lt;/a&gt;一直写的是大写，但我从未在意！&#xA;修改后，启动成功，自动开始打补丁！！哦也！！ 成功了！！&lt;/p&gt;&#xA;&#xA;&lt;p&gt;恩，为啥会多了一个alf_bootstrap_lock表呢？肯定是之前升级过，并且失败了。但我已经对比过表结构，并未异样。 但为啥一直以来都不报错呢？ 很久之前就写着&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;db.schema.update=false&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;这个选项，屏蔽了这个错误！！ 印象中，很久很久以前，我因为看到数据库报错才加入这个选项，难道就是一个原因？？！！ 但是奇怪的是，如果没有添加&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;hibernate.default_schema=alfresco&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;的话，一个Oracle实例，只安装一个Alfresco的话，也是不会出错的！ 难道是某个事情，在某个环境中使用了两个Alfresco，然后添加了这一语句，然后导致错误，进而添加禁止更新的选项？？&lt;/p&gt;&#xA;&#xA;&lt;p&gt;就这样，花了3天！！&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;恩，这也许就是解释，这应该就是技术债务了！&lt;/strong&gt;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>升级到Nginx 0.9.0</title>
      <link>http://wendal.net/186.html</link>
      <pubDate>2010-11-30 08:36:52 +0800</pubDate>
      <description>&lt;p&gt;今早一开邮箱,发现Nginx 0.9开发分支已经发布!!&#xA;对于我这种喜欢尝鲜的人,怎么错过!!&#xA;马上下载编译:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;wget http://nginx.org/download/nginx-0.9.0.tar.gz&#xA;tar xvf nginx-0.9.0.tar.gz&#xA;cd nginx-0.9.0&#xA;vim auto/cc/gcc #将Debug去掉,优化改为o3&#xA;./configure --with-cpu-opt=pentium4 --user=www --group=www --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_gzip_static_module&#xA;make&#xA;/usr/local/nginx/sbin/nginx -s stop #停掉旧版本&#xA;cp objs/nginx /usr/local/nginx/sbin/&#xA;/usr/local/nginx/sbin/nginx #启动新版本&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;这里没有用热切换.&#xA;顺便更新了&lt;a href=&#34;http://wiki.nginx.org/NginxChs&#34;&gt;Nginx中文Wiki&lt;/a&gt;主页上的版本信息.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;最新更新： 已经发布 0.9.1 ，本blog也同步更新&lt;/strong&gt;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>3年,追忆,回顾</title>
      <link>http://wendal.net/138.html</link>
      <pubDate>2010-11-23 07:47:05 +0800</pubDate>
      <description>&lt;p&gt;2007年9月,成功考过&lt;strong&gt;SCJP&lt;/strong&gt;&#xA;2007年10月,人生第一个职业面试,竟然不问我Java的知识,只因我过了SCJP&#xA;2007年11月,拿到第一份offer,无比激动啊!! 因为我不是计算机专业本科毕业的&#xA;2008年2月,开始到公司实习,号称最低工资的Billable员工&#xA;2008年7月,正式入职,无试用期&#xA;2008年8月,正式接管项目组的管理,几个人的小团队.&#xA;2008年8月,获得季度&amp;rdquo;最佳项目&amp;rdquo;称号&#xA;2008年9月,改革项目.废弃沿用2年Excel式的任务管理,启用组内bugzilla;改变工作方式,强调分工,对Mac的依赖降低.(新官上任3把火?)&#xA;2008年10月,开发JLint,极大地提高项目组的工作效率,进一步降低对Mac的依赖&#xA;2008年10月,参加GCT考试,3小时回答185条题目,好在我答题是出了名的快!&#xA;2008年12月,顺利获得暨南大学的工程硕士入学资格,专业&amp;ndash;软件工程&#xA;2009年1月,私下改造公司第一个Android项目XRace,改进其启动性能90%以上,但未获公司的注意&#xA;2009年1月,开始组内学习计划,先后学习Ruby/ror/Perl&#xA;2009年5月,开发一个Android Dex文件反编译器,后来发现其他项目做得更好,放弃之&#xA;2009年5月,考SCJD,差4分失败而归,这可是400分的总分啊!!&#xA;2009年X月,在我的推荐下,启用CDC-bugzilla,推动Hudson自动构建&#xA;2009年X月,开始参加一个内部项目的code review&#xA;2009年7月,参与一个短期的外出培训项目,是培训学生的&#xA;2009年10月,在Javaeye上发现Nutz,当时是1.a.15版. 提出几处修改意见后,成为commiter&#xA;2009年12月,使用ASM重新实现Nut.Aop,后来又做了现在这一版.&#xA;2009年12月,试水公司的Jira系统,带壳的Jira用得非常不爽!&#xA;2010年1月,项目解散,被分配到另外一个项目组,仅仅待了几天,完成了一个小功能&#xA;2010年2月,再次被分配,到了一个深圳的网站项目,折腾到现在&#xA;2010年3月,驻深圳现场开发,2男2女,哈哈&#xA;2010年4月,一期上线,奇迹!&#xA;2010年5月,负责Alfresco的底层配置,天天对着putty敲命令&#xA;2010年6月,实现了一个改资源URL的工具,因为实际部署时, 图片等静态资源放在另外域名/机器上.&#xA;2010年7月,开发基于Alfresco的工作流定制,天啊,我之前还没搞过工作流&#xA;2010年9月,二期上线,部署到全球的3个站点,客户有钱嘛&#xA;2010年11月,获颁&amp;rdquo;季度最佳员工&amp;rdquo; &amp;ndash; 经过好几次提名后&#xA;&amp;hellip; 人生还在继续&lt;/p&gt;&#xA;&#xA;&lt;p&gt;暂时写到这,流水帐一样.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;3年,很充实.&lt;/strong&gt;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>一次不算太久的破解</title>
      <link>http://wendal.net/135.html</link>
      <pubDate>2010-11-21 03:47:46 +0800</pubDate>
      <description>&lt;p&gt;经友人推荐,发现XMind的确很好用. 不过部分功能需要收费,忽然就感觉有点不爽,毕竟这号称开源软件啊!&#xA;故今早动手破解,下午2点成功!&#xA;但无意放出破解版,毕竟是优秀的商业软件,会阻碍其发展. &lt;strong&gt;仅本人使用!!&lt;/strong&gt;&#xA;这里仅简单说说我用到的工具软件:&#xA;1. XMind 3.1.1破解版 &amp;ndash; 这是国外破解的版本,给了我很大的启发!&#xA;2. &lt;a href=&#34;http://java.decompiler.free.fr/&#34;&gt;JD-GUI&lt;/a&gt; &amp;ndash; 反编译出源码,软件逻辑一目了然!&#xA;3. &lt;a href=&#34;http://www.cs.ioc.ee/~ando/jbe/&#34;&gt;Java Bytecode Editor&lt;/a&gt; &amp;ndash; 这软件堪称神器,直接改字节码!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;其实,我只是刚刚开始用XMind,还没使用其Pro的功能.但将近300元/year,实在是高!!&#xA;我已经捐款给不少免费/开源项目,分别是我心目中的价位. 希望经过一段时间的使用,会发现XMind真正的价值!!&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>亚运比赛,还是没看成!</title>
      <link>http://wendal.net/133.html</link>
      <pubDate>2010-11-20 08:48:42 +0800</pubDate>
      <description>&lt;p&gt;6个月前买了票&#xA;2周前取了票&#xA;坐了两个小时公交车&lt;/p&gt;&#xA;&#xA;&lt;p&gt;到达后发现,&lt;strong&gt;去错场馆了&lt;/strong&gt;!!! 严格来说,是去了同一个场馆的不同区域.这两个区域相距9公里!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;哎,没法,去不了&amp;hellip;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>取亚运门票,花了一个小时</title>
      <link>http://wendal.net/126.html</link>
      <pubDate>2010-11-11 12:57:33 +0800</pubDate>
      <description>&lt;p&gt;很久很久以前,买了两张亚运的门票.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;比赛临近,觉得还是先取了吧,故飞奔到取票点. 在取票点待了5分钟,我意识到,只有我是来取票的,其他都是在买票的黄牛党!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;天啊,咋就那么多人,他们为啥一次性买这么多! 为什么我要等那么久?!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;不过,我其实是支持黄牛的,本质上,这是市场经济的一种正常表现(门票也是一种普通商品,虽然票面上写着不得交易/出售).&lt;/p&gt;&#xA;&#xA;&lt;p&gt;商品,不能强制要求购买者不得转让,这是不符合商品自由流动的规则的! 亚运门票,一种有价证劵,是应该同时也必要能够在市场上流通. 而且,亚运门票并非公益性的(除非你是从亚运大礼包中获取),故,购买者有权处理其去留.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;亚运门票,设计得还是不错的, 预定的门票是印刷的,黄牛拿到的门票,基本上都是当场打印的.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;我不满的是,这么多人在购买,工行竟然只有一个人在办理!! 我讨厌四大行!!&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>折腾了2天,终于把Nutz提交给Maven库</title>
      <link>http://wendal.net/124.html</link>
      <pubDate>2010-11-10 10:07:12 +0800</pubDate>
      <description>&lt;p&gt;昨天在 &lt;a href=&#34;https://oss.sonatype.org&#34;&gt;https://oss.sonatype.org&lt;/a&gt; 申请将Nutz加入资源库, 相关Issue:&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&#34;https://issues.sonatype.org/browse/OSSRH-983&#34;&gt;https://issues.sonatype.org/browse/OSSRH-983&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;原本以为要2天,想不到一天就通过了申请.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;下午折腾了一下,搞到傍晚才成功上传一版,期间遇到的问题有:&lt;/p&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&lt;p&gt;要求asc文件,开头无头绪,后来发现是gpg工具生存的.&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;提交后提示public key未登记,又折腾了一下,提交到公共服务器&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;签名无效, 神奇之极, 没办法,重新签名, 并打包为bundle,一次性提交!&lt;/p&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;p&gt;哦也,成功,release! 哈哈,发布成功:&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&#34;https://oss.sonatype.org/content/groups/staging/org/nutz/nutz/1.a.32/&#34;&gt;https://oss.sonatype.org/content/groups/staging/org/nutz/nutz/1.a.32/&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;不过,很奇怪,并没要在Maven中央库找到nutz,难道是同步间隔的问题??&lt;/p&gt;&#xA;&#xA;&lt;p&gt;追查! 发现pom文件少了一个packaging的属性,我晕!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;刚才把1.a.31也放上去了,应该满足同步到中央库的全部条件了. 看看明天能否在中央库找到. 期待中!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;后续报道:&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;已经同步到中央库&lt;/strong&gt;了, 地址 &lt;a href=&#34;http://repo1.maven.org/maven2/org/nutz/&#34;&gt;http://repo1.maven.org/maven2/org/nutz/&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;现在已经可以直接将Nutz加入你项目的dependency:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;    &amp;lt;dependency&amp;gt;&#xA;        &amp;lt;groupid&amp;gt;org.nutz&amp;lt;/groupid&amp;gt;&#xA;        &amp;lt;artifactid&amp;gt;nutz&amp;lt;/artifactid&amp;gt;&#xA;        &amp;lt;version&amp;gt;1.a.33&amp;lt;/version&amp;gt;&#xA;    &amp;lt;/dependency&amp;gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;</description>
    </item>
    <item>
      <title>换上1TB的希捷硬盘,虚惊一场</title>
      <link>http://wendal.net/122.html</link>
      <pubDate>2010-11-08 09:57:49 +0800</pubDate>
      <description>&lt;p&gt;狠下心,终于入手一块 1TB的希捷硬盘,在卓越买的,&lt;a href=&#34;http://www.amazon.cn/gp/product/B003N63M8A/ref=oss_product&#34;&gt;链接&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;欢喜地回家装进灰尘滚滚的机箱,开机!&#xA;BIOS打印了相关信息,顺利进入系统.&#xA;分区后,把旧硬盘上的资料盘往新硬盘copy,开头很快, 300M后,停了!!! 我晕,干啥??!! 马上取消,what? 取消也等了1分钟才完成!!&#xA;心想,完了,中招了!! 难道遇上固件门? 上Google搜ST31000528AS, 天啊, 之前出问题的型号!!!&#xA;不过,自行看看固件版本,不对, 有问题的是CC24,但我的是CC38,为啥??为啥?? 到底哪里有问题??!!!&#xA;在网上搜了一大堆原因后,还是没搞好!!&#xA;进BIOS,发现SMART没开,32bit没开, 难道这样都有影响? 我日,我打开,回到Windows,还是不行!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;难道&amp;hellip;. 难道&amp;hellip; 线的问题? 好吧,开机箱,选了一个接口,把灰尘认真清干净,插入!!开机!! 开始copy文件.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;!!!!!!!!!!! 40M/s 直至完成!!! 还真是灰尘的原因!!!!!!!!!!!!!!!!!!!!!!!!!!! 我的错!! 折腾了一个晚上!!&#xA;接着下了DiscWizard,把旧硬盘克隆到新盘,Oh yeah!! 搞定!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;感觉系统速度有所提高,声音也小了.&#xA;前后对比:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;希捷 SATA    120G&#xA;希捷 SATA2   1TB&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;</description>
    </item>
    <item>
      <title>离线下载Android SDK</title>
      <link>http://wendal.net/118.html</link>
      <pubDate>2010-11-05 11:04:22 +0800</pubDate>
      <description>&lt;p&gt;我实在搞不懂,为啥GFW要墙Android 的开发网站.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;今天,把当前最新版本的Android SDK全部下载到 &lt;a href=&#34;http://build.sunfarms.net/android/repository/&#34;&gt;http://build.sunfarms.net/android/repository/&lt;/a&gt;&#xA;同时发现一个问题,即使把 &lt;a href=&#34;http://build.sunfarms.net/android/repository/repository.xml&#34;&gt;http://build.sunfarms.net/android/repository/repository.xml&lt;/a&gt; 添加到SDK Manager ,与Google官网一样的内容,却不认平台下载.&#xA;仔细找了一下,原来写死在代码里面的 &lt;a href=&#34;http://code.google.com/p/android-sdk-tool/source/browse/src/main/java/com/m11n/android/AndroidSdkTool.java?r=6426c47fe356e9d649fe612464563960a1ca7d74&#34;&gt;点击查看&lt;/a&gt;&#xA;没办法. 只好自己编译一个了,哈哈.&#xA;Google源码截取:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;        private String repositoryUrl = &amp;quot;http://dl-ssl.google.com/android/repository/&amp;quot;;&#xA;        private String sdkUrl = &amp;quot;http://dl.google.com/android/&amp;quot;;&#xA;        private String downloadDir = System.getProperty(&amp;quot;java.io.tmpdir&amp;quot;) + &amp;quot;/&amp;quot;;&#xA;        private Boolean overwrite = true;&#xA;        private Boolean verbose = true;&#xA;        private DocumentBuilder builder;&#xA;&#xA;        public AndroidSdkTool() throws ParserConfigurationException {&#xA;                builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();&#xA;        }&#xA;&#xA;        public Repository downloadRepository() {&#xA;                String file = &amp;quot;repository.xml&amp;quot;;&#xA;                try {&#xA;                        download(repositoryUrl + file, downloadDir + file, overwrite);&#xA;                        return parse(new FileInputStream(new File(downloadDir+file)));&#xA;                }catch (Exception e) {&#xA;                        logger.error(e.getMessage(), e);&#xA;                }&#xA;                return null;&#xA;        }&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;</description>
    </item>
    <item>
      <title>为Alfresco加速PDF文件索引速度</title>
      <link>http://wendal.net/114.html</link>
      <pubDate>2010-11-01 05:14:41 +0800</pubDate>
      <description>&lt;p&gt;本文仅为 &lt;a href=&#34;http://thinkalfresco.blogspot.com/2009/03/speeding-up-pdf-indexing-alfresco-hack.html&#34;&gt;http://thinkalfresco.blogspot.com/2009/03/speeding-up-pdf-indexing-alfresco-hack.html&lt;/a&gt; 的 Alfresco 3.2版. 因为原文中的代码,已经无法在3.2版上使用.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;新的代码:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&#xA;&amp;lt;!DOCTYPE beans PUBLIC &amp;quot;-//SPRING//DTD BEAN//EN&amp;quot; &amp;quot;http://www.springframework.org/dtd/spring-beans.dtd&amp;quot;&amp;gt;&#xA;&amp;lt;beans&amp;gt;&#xA;&#xA;  &amp;lt;bean id=&amp;quot;transformer.PdfBox&amp;quot; class=&amp;quot;java.lang.String&amp;quot;&amp;gt;&amp;lt;/bean&amp;gt;&#xA;&#xA;  &amp;lt;bean id=&amp;quot;transformer.complex.OpenOffice.PdfBox&amp;quot; class=&amp;quot;java.lang.String&amp;quot;&amp;gt;&amp;lt;/bean&amp;gt;&#xA;&#xA;  &amp;lt;bean id=&amp;quot;transformer.PdfToTextTool&amp;quot; class=&amp;quot;org.alfresco.repo.content.transform.RuntimeExecutableContentTransformerWorker&amp;quot;&amp;gt;&#xA;                &amp;lt;property name=&amp;quot;mimetypeService&amp;quot;&amp;gt;&#xA;                &amp;lt;ref bean=&amp;quot;mimetypeService&amp;quot;&amp;gt;&amp;lt;/ref&amp;gt;&#xA;            &amp;lt;/property&amp;gt;&#xA;                &amp;lt;property name=&amp;quot;transformCommand&amp;quot;&amp;gt;&#xA;                        &amp;lt;bean name=&amp;quot;transformer.pdftotext.Command&amp;quot; class=&amp;quot;org.alfresco.util.exec.RuntimeExec&amp;quot;&amp;gt;&#xA;                                &amp;lt;property name=&amp;quot;commandMap&amp;quot;&amp;gt;&#xA;                                        &amp;lt;map&amp;gt;&#xA;                                                &amp;lt;entry key=&amp;quot;.*&amp;quot;&amp;gt;&#xA;                                                        &amp;lt;value&amp;gt;/usr/bin/pdftotext -enc UTF-8 ${options} ${source} ${target}&amp;lt;/value&amp;gt;&#xA;                                                &amp;lt;/entry&amp;gt;&#xA;                                        &amp;lt;/map&amp;gt;&#xA;                                &amp;lt;/property&amp;gt;&#xA;                                &amp;lt;property name=&amp;quot;defaultProperties&amp;quot;&amp;gt;&#xA;                                        &amp;lt;props&amp;gt;&amp;lt;prop key=&amp;quot;options&amp;quot;&amp;gt;&amp;lt;/prop&amp;gt;&amp;lt;/props&amp;gt;&#xA;                                &amp;lt;/property&amp;gt;&#xA;                        &amp;lt;/bean&amp;gt;&#xA;                &amp;lt;/property&amp;gt;&#xA;&#xA;                &amp;lt;property name=&amp;quot;checkCommand&amp;quot;&amp;gt;&#xA;                        &amp;lt;bean name=&amp;quot;transformer.pdftotext.checkCommand&amp;quot; class=&amp;quot;org.alfresco.util.exec.RuntimeExec&amp;quot;&amp;gt;&#xA;                                &amp;lt;property name=&amp;quot;commandMap&amp;quot;&amp;gt;&#xA;                                        &amp;lt;map&amp;gt;&#xA;                                                &amp;lt;entry key=&amp;quot;.*&amp;quot;&amp;gt;&#xA;                                                        &amp;lt;value&amp;gt;chmod 777 /usr/bin/pdftotext&amp;lt;/value&amp;gt;&#xA;                                                &amp;lt;/entry&amp;gt;&#xA;                                        &amp;lt;/map&amp;gt;&#xA;                                &amp;lt;/property&amp;gt;&#xA;                                &amp;lt;property name=&amp;quot;defaultProperties&amp;quot;&amp;gt;&#xA;                                        &amp;lt;props&amp;gt;&amp;lt;prop key=&amp;quot;options&amp;quot;&amp;gt;&amp;lt;/prop&amp;gt;&amp;lt;/props&amp;gt;&#xA;                                &amp;lt;/property&amp;gt;&#xA;                        &amp;lt;/bean&amp;gt;&#xA;                &amp;lt;/property&amp;gt;&#xA;                &amp;lt;property name=&amp;quot;explicitTransformations&amp;quot;&amp;gt;&#xA;         &amp;lt;list&amp;gt;&#xA;            &amp;lt;bean class=&amp;quot;org.alfresco.repo.content.transform.ExplictTransformationDetails&amp;quot;&amp;gt;&#xA;               &amp;lt;property name=&amp;quot;sourceMimetype&amp;quot;&amp;gt;&#xA;                  &amp;lt;value&amp;gt;application/pdf&amp;lt;/value&amp;gt;&#xA;               &amp;lt;/property&amp;gt;&#xA;               &amp;lt;property name=&amp;quot;targetMimetype&amp;quot;&amp;gt;&#xA;                  &amp;lt;value&amp;gt;text/plain&amp;lt;/value&amp;gt;&#xA;               &amp;lt;/property&amp;gt;&#xA;            &amp;lt;/bean&amp;gt;&#xA;         &amp;lt;/list&amp;gt;&#xA;      &amp;lt;/property&amp;gt;&#xA;&amp;lt;/bean&amp;gt;&#xA;&#xA;&amp;lt;bean id=&amp;quot;transformer.complex.OpenOffice.PdfToTextTool&amp;quot; parent=&amp;quot;baseContentTransformer&amp;quot; class=&amp;quot;org.alfresco.repo.content.transform.ComplexContentTransformer&amp;quot;&amp;gt;&#xA;      &amp;lt;property name=&amp;quot;transformers&amp;quot;&amp;gt;&#xA;         &amp;lt;list&amp;gt;&#xA;            &amp;lt;ref bean=&amp;quot;transformer.OpenOffice&amp;quot;&amp;gt;&amp;lt;/ref&amp;gt;&#xA;            &amp;lt;bean class=&amp;quot;org.alfresco.repo.content.transform.ProxyContentTransformer&amp;quot;&amp;gt;&#xA;                &amp;lt;property name=&amp;quot;worker&amp;quot;&amp;gt;&#xA;                &amp;lt;ref bean=&amp;quot;transformer.PdfToTextTool&amp;quot;&amp;gt;&amp;lt;/ref&amp;gt;&#xA;            &amp;lt;/property&amp;gt;&#xA;            &amp;lt;/bean&amp;gt;&#xA;         &amp;lt;/list&amp;gt;&#xA;      &amp;lt;/property&amp;gt;&#xA;      &amp;lt;property name=&amp;quot;intermediateMimetypes&amp;quot;&amp;gt;&#xA;         &amp;lt;list&amp;gt;&#xA;            &amp;lt;value&amp;gt;application/pdf&amp;lt;/value&amp;gt;&#xA;         &amp;lt;/list&amp;gt;&#xA;      &amp;lt;/property&amp;gt;&#xA;   &amp;lt;/bean&amp;gt;&#xA;&amp;lt;/beans&amp;gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;</description>
    </item>
    <item>
      <title>想不到服务器一下子就被击垮了</title>
      <link>http://wendal.net/110.html</link>
      <pubDate>2010-11-01 12:11:04 +0800</pubDate>
      <description>&lt;p&gt;上周末, 从同事口中得知我休假期间,Jboss服务器曾&lt;strong&gt;无故自己关闭&lt;/strong&gt;了一次.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;顿时非常惊讶,咋就会自己关闭自己呢?&lt;/p&gt;&#xA;&#xA;&lt;p&gt;第一反应是OOM了,一问,没啊,内存还剩好多,而且log没提示OOM.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;难道是程序里面写了System.exit(X)之类? 扫描了一遍代码,没有啊!! 我们还不至于写这么的代码&lt;/p&gt;&#xA;&#xA;&lt;p&gt;奇怪的是, JBoss是按照标准的流程顺序关闭各个应用后,再shutdown完成的,并无直接被kill掉或者异常退出,也没有找到JVM报错的log.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;由于关闭的时间点在11:37AM,故,追查nginx的access.log  , 翻翻翻, 在一堆502(Jboss已经关闭,nginx无法proxy_pass,报502)前面,有一些不寻常的请求,节选如下:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;/acunetix-wvs-test-for-some-inexistent-file-second-try&#xA;&#xA;/console/j_security_check&#xA;&#xA;/_vti_pvt/authors.pwd&#xA;&#xA;/phpmyadmin/main.php&#xA;&#xA;/jmx-console/HtmlAdaptor?action=inspectMBean&amp;amp;name=jboss.system:type%3DServerInfo&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;看来是被攻击了!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;冷静冷静,然而,攻击开始后不到5秒,Jboss就被关闭了.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;马上访问/jmx-console/, 天啊!! 竟然能够访问,Jboss的信息一览无余!! 这个默认应用竟然直接暴露给外网了!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;还真有相关的JBoss漏洞 &lt;a href=&#34;http://websec360.com/NewsInfo/124/6455.Html&#34;&gt;http://websec360.com/NewsInfo/&lt;sup&gt;124&lt;/sup&gt;&amp;frasl;&lt;sub&gt;6455&lt;/sub&gt;.Html&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;但,如何才能关闭JBoss呢? &lt;a href=&#34;http://www.shuq.org/read.asp?id=109&#34;&gt;http://www.shuq.org/read.asp?id=109&lt;/a&gt; 通过JMX,严重无语了!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;看来就是这个原因了, 哎. 实在没想到啊!!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;刚刚翻查access.log,我晕,原来还有好多针对php/phpadmin/.net漏洞的log. 看来攻击者是使用某种攻击攻击完成的,难道是他的命令集? 不知道哪里能够下载.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;解决方法:&lt;/p&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&lt;p&gt;移除JBoss的JMX,invoker应用,因为我根本就没用到.&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;在nginx添加对php文件/asp文件/cgi文件的拦截,直接返回404.&lt;/p&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;p&gt;看来网站的安全还得狠狠地加强!!&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>使用Nginx搭建Http代理服务器</title>
      <link>http://wendal.net/108.html</link>
      <pubDate>2010-10-24 08:42:46 +0800</pubDate>
      <description>&lt;p&gt;昨天, 折腾了一个下午,终于配好了.&#xA;配置如下:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;    server {&#xA;        listen       8888;&#xA;                client_body_timeout 60000;&#xA;                client_max_body_size 1024m;&#xA;                send_timeout       60000;&#xA;                client_header_buffer_size 16k;&#xA;                large_client_header_buffers 4 64k;&#xA;&#xA;                proxy_headers_hash_bucket_size 1024;&#xA;                proxy_headers_hash_max_size 4096;&#xA;                proxy_read_timeout 60000;&#xA;                proxy_send_timeout 60000;&#xA;&#xA;        location / {&#xA;            resolver 8.8.8.8;&#xA;            proxy_pass http://$http_host$request_uri;&#xA;        }&#xA;    }&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;resolver 8.8.8.8; 代表使用Google DNS来解析域名&#xA;client_body_timeout , large_client_header_buffers 等设置,确保大的请求不会返回400错误.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;但,这个代理服务器只支持Http请求, Https会报400错误.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>在Nutz MVC中使用Freemarker</title>
      <link>http://wendal.net/100.html</link>
      <pubDate>2010-10-20 12:27:06 +0800</pubDate>
      <description>&lt;p&gt;大约一年前, axhack 发布了一篇文章 &amp;ldquo;&lt;a href=&#34;http://axhack.javaeye.com/blog/542441&#34;&gt;给 nutz 添加 freemarker 视图&lt;/a&gt;&amp;rdquo; ,描述了如何集成nutz和freemarker.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;前几天,我使用另外一种更简单的方法来实现(基于Nutz 1.a.33版新增的内部重定向视图),我使用的是Freemarker 2.3.16&#xA;首先, 在web.xml添加Freemarker官方文档描述的FreemarkerServlet, &lt;a href=&#34;http://freemarker.sourceforge.net/docs/pgui_misc_servlet.html&#34;&gt;查看原文描述&lt;/a&gt;.&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;&amp;lt;servlet&amp;gt;&#xA;&amp;lt;servlet-name&amp;gt;freemarker&amp;lt;/servlet-name&amp;gt;&#xA;&amp;lt;servlet-class&amp;gt;freemarker.ext.servlet.FreemarkerServlet&amp;lt;/servlet-class&amp;gt;&#xA;&amp;lt;init-param&amp;gt;&#xA;  &amp;lt;param-name&amp;gt;TemplatePath&amp;lt;/param-name&amp;gt;&#xA;  &amp;lt;param-value&amp;gt;/&amp;lt;/param-value&amp;gt;&#xA;&amp;lt;/init-param&amp;gt;&#xA;&amp;lt;init-param&amp;gt;&#xA;  &amp;lt;param-name&amp;gt;NoCache&amp;lt;/param-name&amp;gt;&#xA;  &amp;lt;param-value&amp;gt;true&amp;lt;/param-value&amp;gt;&#xA;&amp;lt;/init-param&amp;gt;&#xA;&amp;lt;init-param&amp;gt;&#xA;  &amp;lt;param-name&amp;gt;ContentType&amp;lt;/param-name&amp;gt;&#xA;  &amp;lt;param-value&amp;gt;text/html; charset=UTF-8&amp;lt;/param-value&amp;gt;&#xA;  &amp;lt;!-- 我觉得不需要了,如果是内部重定向的话, nutz已经设置了编码 --&amp;gt;&#xA;&amp;lt;/init-param&amp;gt;&#xA;&amp;lt;init-param&amp;gt;&#xA;  &amp;lt;param-name&amp;gt;template_update_delay&amp;lt;/param-name&amp;gt;&#xA;  &amp;lt;param-value&amp;gt;0&amp;lt;/param-value&amp;gt;&amp;lt;!-- 开发时才设置为0 --&amp;gt;&#xA;&amp;lt;/init-param&amp;gt;&#xA;&amp;lt;init-param&amp;gt;&#xA;  &amp;lt;param-name&amp;gt;default_encoding&amp;lt;/param-name&amp;gt;&#xA;  &amp;lt;param-value&amp;gt;UTF-8&amp;lt;/param-value&amp;gt; &amp;lt;!-- 模板文件的编码 --&amp;gt;&#xA;&amp;lt;/init-param&amp;gt;&#xA;&amp;lt;init-param&amp;gt;&#xA;  &amp;lt;param-name&amp;gt;number_format&amp;lt;/param-name&amp;gt;&#xA;  &amp;lt;param-value&amp;gt;0.##########&amp;lt;/param-value&amp;gt;&#xA;&amp;lt;/init-param&amp;gt;&#xA;&#xA;&amp;lt;load-on-startup&amp;gt;1&amp;lt;/load-on-startup&amp;gt;&#xA;&amp;lt;/servlet&amp;gt;&#xA;&#xA;&amp;lt;servlet-mapping&amp;gt;&#xA;&amp;lt;servlet-name&amp;gt;freemarker&amp;lt;/servlet-name&amp;gt;&#xA;&amp;lt;url-pattern&amp;gt;*.ftl&amp;lt;/url-pattern&amp;gt;&#xA;&amp;lt;/servlet-mapping&amp;gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;然后在需要Freemarker渲染的方法上,添加:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;@Ok(&amp;quot;-&amp;gt;:/forum/viewTip.ftl&amp;quot;)&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;注意 1.a.33 才有内部重定向视图(-&amp;gt;), 之前的版本,建议使用重定向视图(&amp;gt;&amp;gt;)代替&#xA;ftl后缀,就是web.xml配置的后缀.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;这样,当方法正确返回时,就会使用Freemarker渲染, 返回值保存在 obj 变量中,你可以直接在Freemarker模板中调用.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>为NutLab添加一个新项目-Nutz与OpenID集成</title>
      <link>http://wendal.net/94.html</link>
      <pubDate>2010-10-12 10:16:53 +0800</pubDate>
      <description>&lt;p&gt;忙乎了两天, 终于把项目正确运行起来了.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;使用即将发布的Nutz 1.a.32 ,加 JOpenID 1.0.7&lt;/p&gt;&#xA;&#xA;&lt;p&gt;地址: &lt;a href=&#34;http://code.google.com/p/nutzlab/source/browse/#svn/trunk/NutOpenID&#34;&gt;http://code.google.com/p/nutzlab/source/browse/#svn/trunk/NutOpenID&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;同时,发现JOpenID 1.0.7的一个Bug.&#xA;JOpenID 默认使用UTF-8来对参数进行getBytes. 当参数中还有非英文字符,且没有配置URIEncoding时,获取的byte[]是错误的.&#xA;具体代码:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;package org.expressme.openid;&#xA;//......&#xA;public class OpenIdManager {&#xA;//......&#xA;&#xA;    String getHmacSha1(String data, byte[] key) {&#xA;        SecretKeySpec signingKey = new SecretKeySpec(key, HMAC_SHA1_ALGORITHM);&#xA;        Mac mac = null;&#xA;        try {&#xA;            mac = Mac.getInstance(HMAC_SHA1_ALGORITHM);&#xA;            mac.init(signingKey);&#xA;        }&#xA;        catch(NoSuchAlgorithmException e) {&#xA;            throw new OpenIdException(e);&#xA;        }&#xA;        catch(InvalidKeyException e) {&#xA;            throw new OpenIdException(e);&#xA;        }&#xA;        try {&#xA;            byte[] rawHmac = mac.doFinal(data.getBytes(&amp;quot;UTF-8&amp;quot;)); //不一定,也许是ASCII&#xA;            return Base64.encodeBytes(rawHmac);&#xA;        }&#xA;        catch(IllegalStateException e) {&#xA;            throw new OpenIdException(e);&#xA;        }&#xA;        catch(UnsupportedEncodingException e) {&#xA;            throw new OpenIdException(e);&#xA;        }&#xA;    }&#xA;&#xA;//.....&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;</description>
    </item>
    <item>
      <title>抢占我带宽的流氓软件</title>
      <link>http://wendal.net/92.html</link>
      <pubDate>2010-10-12 10:56:12 +0800</pubDate>
      <description>&lt;p&gt;&lt;strong&gt;第一款, PPS的PPSAP(PPS 加速器)&lt;/strong&gt;&#xA;对系统的影响, 后台运行,抢占无数带宽,发起N多连接!!&#xA;安装pps后, 在安装目录下有一个ppsap.exe的程序, 这个程序,在之前的版本,直接删除程序文件就可以了. 最近更新后, 发现删除后自动回复(再次启动pps后), 我日!! 这下可无敌流氓了!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;第二款, 360安全卫生的在线升级&lt;/strong&gt;&#xA;之前一直没有留意,后来打开360的流量查看器才发现其也是流氓之一! 自爆家丑!!&#xA;除了直接kill掉外,没啥办法!!&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>总结一点点项目经验–迁移/部署/静态资源</title>
      <link>http://wendal.net/90.html</link>
      <pubDate>2010-10-01 09:45:59 +0800</pubDate>
      <description>&lt;ol&gt;&#xA;&lt;li&gt;&lt;p&gt;如果可能的话, 提前一天切换一个小时, 会发现不少问题.&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;这次的部署,属于升级版,测试新版,应该在无法访问前一版本的网络环境中测试. 这一次部署,就发现项目中某些链接竟然直接指向旧的系统!!&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;使用CDN (内容分发网络),就是静态资源分开存放, 例如 放到 res.sunfarms.net . 即使不能独立域名, 则最好把项目拆成两个工程, 一个放静态文件(css/jpg/gif/swf等),一个放动态内容&lt;/p&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;p&gt;&amp;hellip; 先写这么多, 墨水不够.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>iText锚点的一个小陷阱 目标地锚点必须有字符串</title>
      <link>http://wendal.net/70.html</link>
      <pubDate>2010-09-08 09:27:32 +0800</pubDate>
      <description>&lt;p&gt;昨晚折腾了一下zDoc的PDF生成功能, 不过,一听闻锚点功能失效,顿时不爽,马上研究!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;首先发现 锚点无法对应起来,  触发锚点的编号,与锚点目的地无法对应起来! 这个通过查找实际对应的文件的绝对地址的hashcode生成&lt;/p&gt;&#xA;&#xA;&lt;p&gt;然后发现锚点总是失效,无法跳转, 最后才发现,锚点的目标地anchor, 使用 Anchor anchor = new Anchor(); 生成, 页面上无显示!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;实例:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;Anchor anchorDest = new Anchor(); anchorDest.setName(&amp;quot;dest&amp;quot;);&#xA;Anchor anchorSrc = new Anchor(&amp;quot;From&amp;quot;); anchorDest.setReference(&amp;quot;#dest&amp;quot;);&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;无法跳转! 即使写成&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;Anchor anchorDest = new Anchor(&amp;quot; &amp;quot;);&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;一样无法跳转, 必须写成:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;Anchor anchorDest = new Anchor(&amp;quot;To here&amp;quot;);&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;</description>
    </item>
    <item>
      <title>Eclipse能够启动得快些</title>
      <link>http://wendal.net/68.html</link>
      <pubDate>2010-09-08 09:18:44 +0800</pubDate>
      <description>&lt;p&gt;昨天在Javaeye上看到一篇关于Eclipse调优的文件,真是当头一棒,之前咋就没想到呢?!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;自己调整了一下,得到以下参数:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;-Xms40m&#xA;-Xmx256m&#xA;-XX:MaxPermSize=128m&#xA;-XX:ReservedCodeCacheSize=128m&#xA;-Dfile.encoding=utf8&#xA;-Xverify:none&#xA;-XX:+DisableExplicitGC&#xA;-XX:+UseParNewGC&#xA;-Xnoclassgc&#xA;-XX:+UseBiasedLocking&#xA;-XX:+UseFastAccessorMethods&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;感觉上快了不少哦&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>遇到一个关于ClassPath的奇怪问题 Classpath只认jar文件?No!</title>
      <link>http://wendal.net/65.html</link>
      <pubDate>2010-09-07 04:24:43 +0800</pubDate>
      <description>&lt;p&gt;昨天在客户现场部署应用,解压后开始修改配置文件,以为一切顺利,结果发现程序根本就无视我的配置文件!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;启动代码是这样的:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;java -cp . -Djava.ext.dirs=. xxx.yyy.Main deploy.properties&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;在当前目录有 XXX.jar deploy.properties a.zip 还有就是一堆类文件在 org文件夹下, 整个文件夹的文件,就是a.zip的解压出来的.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;deploy.properties就是我修改的配置文件,结果无论怎么改,程序都无视我的修改. 然后我怒了,把deploy.properties删除了,发现程序依旧运行!! 疯了,deploy.properties是启动该程序必须的!!怎么可能还能启动,这是使用spring properties holder 加载的, 写法是  classpath:deploy.properties&lt;/p&gt;&#xA;&#xA;&lt;p&gt;终于开始怀疑是否是zip压缩包的原因,删掉!! 结果,正确运行了!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;奇怪,为啥呢??!! 竟然zip文件都当成jar文件处理?? 找来一个有Main类的jar文件,并改名为XXXX.zip,执行:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;java -cp XXXX.zip xxx.yyy.Main     //结果正常启动了!!&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;再狠一点,改为后缀改为rar, 执行 java -cp XXXX.rar xxx.yyy.Main , 结果一样,照样运行!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;继续狠一下, 执行&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;java -Djava.ext.dirs=. xxx.yyy.Main        //没办法,照样运行!!!&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;再一次刷新我对Classpath的认识!!&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Nutz 与 XBlink 是什么关系? 兄弟!!</title>
      <link>http://wendal.net/61.html</link>
      <pubDate>2010-09-03 02:05:00 +0800</pubDate>
      <description>&lt;p&gt;昨天,在Nutz的主页看到额外链接中有这样一行:&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&#34;http://xblink.googlecode.com/&#34;&gt;XBlink - 轻量级XML序列化工具&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;点开,看完说明,并check out了源码,大概地过了一遍. 晚上到QQ群上弱弱地提了一下,结果一个新生的XBlink交流群,存在不到5分钟,就宣布与Nutz交流群合并. Nutz交流群的名字也改为 Nutz &amp;amp; XBlink&lt;/p&gt;&#xA;&#xA;&lt;p&gt;哈哈,事件都多起来了, 群里络绎不绝地询问XBlink是做什么的,与Nutz是什么关系,^_^&lt;/p&gt;&#xA;&#xA;&lt;p&gt;其实,XBlink就是  POJO &amp;lt;&amp;ndash;&amp;gt; XML , 作者希望做到与XStream分庭抗礼(我的个人理解)&lt;/p&gt;&#xA;&#xA;&lt;p&gt;而 Nutz与XBlink的关系&lt;/p&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&lt;p&gt;严格来说只是兄弟项目,两种并未依赖关系. 不过, XBlink的主要提交者 E-hunter, 同时也是Nutz的commiter之一.&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;Nutz.Plugin与XBlink的Driver机制,异曲同工.  还有就是Nutz.Resource与XBlink的ClassScaner.&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;而XBlink,现有的Log几乎没有,难以跟踪.Nutz已经做了不少功课&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;XBlink 非常早就关注性能,应该与其定位有关.Nutz的性能测试,依旧非常简陋,几乎没有&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;Nutz已经有比较完善的文档Wiki/构建方法, XBlink还比较缺&lt;/p&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;p&gt;当然, &lt;sup&gt;3&lt;/sup&gt;&amp;frasl;&lt;sub&gt;5&lt;/sub&gt;,Nutz都能帮上忙. XBlink一发布就是0.5版,感觉上作者信心很足哦, 现在已经发布了0.6 , ^_^,  不过,貌似还没有一个比较明确的发布计划.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;接下来几天仔细看看XBlink的源码,看看有无优秀经验借鉴到Nutz中,^_^&lt;/p&gt;&#xA;&#xA;&lt;p&gt;O(∩_∩)O哈哈~,唠叨完, 对中国的开源软件,越来越有信心了.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>尝试PPTP和OpenVPN失败</title>
      <link>http://wendal.net/58.html</link>
      <pubDate>2010-08-30 10:45:48 +0800</pubDate>
      <description>&lt;p&gt;尝试了两天,焦头烂额,还是没搞定,没办法,先放放&lt;/p&gt;&#xA;&#xA;&lt;p&gt;昨天去了一趟华南植物园,附图:&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/assets/media/uploads/2010/08/DSCF0189-1024x768.jpg&#34;&gt;&lt;/img&gt;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>对用户体验的一点点看法</title>
      <link>http://wendal.net/56.html</link>
      <pubDate>2010-08-29 08:16:30 +0800</pubDate>
      <description>&lt;p&gt;一直以来,SunFarm助手的使用反馈,让我体会到, 让用户想你一样思考,是不可能的!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;例如升级, 99%的用户首先想到的是,下载后直接覆盖上去! 对于现在的设计,这样是完全不行的.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;简单易用,符合常规,才是最好的选择??&lt;/p&gt;&#xA;&#xA;&lt;p&gt;纠结&amp;hellip;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>发布了阳光牧场外挂 3.34版</title>
      <link>http://wendal.net/54.html</link>
      <pubDate>2010-08-27 10:47:53 +0800</pubDate>
      <description>&lt;p&gt;原本不打算在这个blog写这个新闻的,但毕竟是该外挂一个月以来的更新,还是忍不住说说.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;阳光牧场,这款游戏,这款外挂,给了我不少体会, 写外挂本身的代码活并不算很复杂.问题的关键是用户喜欢用,继续用.相比其他外挂,界面最简陋的,选项最多,而且免费. 之前一直站在开发者的角度看这款外挂,而QQ群的建立,使我直接面对用户,直接面对需求!! 之前以为很好的功能,才发现对用户只是鸡肋.而开发纯果乐果园部分的代码,使我真正意识到设计简洁,做最需要做的事,才是软件要完成的,而非所谓的高级设计技巧&lt;/p&gt;&#xA;&#xA;&lt;p&gt;在外挂中,纯果乐部分,我使用了Nutz的Ioc与Aop,对于一款外挂,显然是无需的,甚至多余的.但是,我作为一个实验来看待,比较这些用户的环境,恰恰是测试Nutz ioc/aop的好地方,系统配置千差万别.结论是,至今没有发现大问题.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>说说这个blog的VPS提供商</title>
      <link>http://wendal.net/52.html</link>
      <pubDate>2010-08-10 06:50:12 +0800</pubDate>
      <description>&lt;p&gt;用了大半个月,感觉非常不错,地址: &lt;a href=&#34;http://www.vpsee.com/vps-plans/&#34;&gt;http://www.vpsee.com/vps-plans/&lt;/a&gt;重申一下,我不是托!&lt;img src=&#34;http://www.vpsee.com/vps-plans/&#34; alt=&#34;&#xA;&#34; /&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;准备续费了,说说感受,打算继续月付&lt;/p&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&lt;p&gt;速度, 不错, 你简单ping一下本网站就知道,而且访问这个blog应该也是很快的&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;价格,我买了的是256m方案,70元一个月, 算是比较实惠的,是Xen虚拟的!!!&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;波折,曾经试过机房断电,凤凰城机房,vpsee的主页有提及,现在免费迁移到另外一个机房,O(∩_∩)O哈哈~&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;性能,感觉不错, CPU : Intel&amp;reg; Xeon&amp;reg; CPU           X3220  @ 2.40GHz&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;操作系统, 我最初选的是openSUSE,后来改回Ubuntu 10.04.1 Server 初始化内存占用仅20M&lt;/p&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;p&gt;与vpsee的工作人员交流过,感觉上应该是几个人一起在经营,而且老板还在上班呢(有一次去开会了),没有提供7*24的服务,但是我觉得没所谓,感觉上那只会是幌子.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>VeryCD的标题–变化中的警示语</title>
      <link>http://wendal.net/43.html</link>
      <pubDate>2010-08-09 10:13:26 +0800</pubDate>
      <description>&lt;p&gt;很久以前就留意到VeryCD主页的标题栏是一句警示语,而且,刷新一下就会变成新的. 算不上非常惊人的举动,但成为以前经常访问其网站的原因.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;实现的关键:&#xA;&lt;a href=&#34;view-source:http://www.verycd.com/statics/title.saying&#34;&gt;http://www.verycd.com/statics/title.saying&lt;/a&gt;&#xA;内容为一个js文件, 定义一个数组,包含几条警示语,然后产生一个随机数,抽取出一句警示语,与原有的标题成新标题,然后再设置为页面的标题.&#xA;今天的内容:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;_VC_DocumentTitles = new Array(&#39;每一天都是一个全新的开始&#39;, &#xA;&#39;你希望掌握永恒，那你必须控制现在&#39;,&#xA; &#39;心是最大的骗子，别人能骗你一时，而它却能骗你一辈子&#39;,&#xA; &#39;你的谦逊会使别人感到高兴&#39;, &#39;自知不自见，自爱不自贵&#39;,&#xA; &#39;最艰苦之时，便是胜利将到之日&#39;, &#39;拳不离手，曲不离口&#39;, &#39;百艺通，不如一艺精&#39;,&#xA; &#39;只要功夫深，铁杵磨成绣花针&#39;, &#39;如果一个人很慷慨，那他就必须把自己的慷慨表现得充满感情&#39;);&#xA; _VC_DocumentTitleIndex = Math.floor(Math.random() * _VC_DocumentTitles.length);&#xA;document.title = &#39;VeryCD - &#39;+ _VC_DocumentTitles[_VC_DocumentTitleIndex];&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;</description>
    </item>
    <item>
      <title>InputStream与OutputStream的read/write陷阱–实际是byte</title>
      <link>http://wendal.net/41.html</link>
      <pubDate>2010-08-09 10:05:45 +0800</pubDate>
      <description>&lt;p&gt;先不要说这是标题党,我觉得这是很多人都已经在使用的误区,即误以为InputStream.read()返回的值真的是int,而OutputStream.write()接受的参数的确为int. 事实上,它们返回或接受的参数是 byte, 即一个字节, 务必仔细读清楚其JavaDoc, 明确说明是读出一个字节,而非int&lt;/p&gt;&#xA;&#xA;&lt;p&gt;我觉得这是Java核心API其中一个极度容易被人误用的地方,哈哈&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;int read();&#xA;void write(int data);&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;</description>
    </item>
    <item>
      <title>Alfresco配置 — 第四节</title>
      <link>http://wendal.net/35.html</link>
      <pubDate>2010-08-05 10:57:29 +0800</pubDate>
      <description>&lt;h4&gt;讲讲如何在WebLogic上部署Alfresco 3.2, 以EAR方式&lt;/h4&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;创建一个文件夹, 名为 WL_Alfresco&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;将alfresco.war解压到WL_Alfresco/alfresco.war&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;创建WL_Alfresco/META-INF, 放入两个文件: application.xml 和 weblogic-application.xml, 内容分别是:&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;    &amp;lt;application&amp;gt;&#xA;        &amp;lt;display -name&amp;gt;Alfresco&amp;lt;/display&amp;gt;&#xA;        &amp;lt;description&amp;gt;Alfresco&amp;lt;/description&amp;gt;&#xA;        &amp;lt;module&amp;gt;&#xA;            &amp;lt;web&amp;gt;&amp;lt;/web&amp;gt;&#xA;            &amp;lt;web-uri&amp;gt;alfresco.war&amp;lt;/web-uri&amp;gt;&#xA;            &amp;lt;context-root&amp;gt;alfresco&amp;lt;/context-root&amp;gt;&#xA;        &amp;lt;/module&amp;gt;&#xA;    &amp;lt;/application&amp;gt;&#xA;&#xA;    &amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&#xA;    &amp;lt;weblogic -application xmlns=&amp;quot;http://www.bea.com/ns/weblogic/90&amp;quot;&amp;gt;&#xA;        &amp;lt;prefer-application-packages&amp;gt;&#xA;            &amp;lt;package-name&amp;gt;org.mozilla.*&amp;lt;/package-name&amp;gt;&#xA;            &amp;lt;package-name&amp;gt;antlr.*&amp;lt;/package-name&amp;gt;&#xA;        &amp;lt;/prefer-application-packages&amp;gt;&#xA;    &amp;lt;/weblogic&amp;gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;将以下jar放到JAVA_HOME/jre/lib/endorsed 文件夹内: serializer.jar xalan.jar , 这两个jar可以到apache上下载.&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;然后按标准的方法添加到WebLogic的部署中去即可.&lt;/strong&gt;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Alfresco配置 — 第三节</title>
      <link>http://wendal.net/33.html</link>
      <pubDate>2010-08-04 10:14:25 +0800</pubDate>
      <description>&lt;p&gt;今天打算说说Alfresco里面的工作流,这个是我折腾了好几个星期的事.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Alfresco的工作流分为3部分, Define/Model/UI&lt;/p&gt;&#xA;&#xA;&lt;p&gt;其中Define就是普通的jBpm3.2工作流引擎,你可以使用Alfresco提供的AlfrescoScriptAction直接调用Alfresco的服务,最基本的就是logger&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Model,其实不单单是工作流的配置,它使用你定义的命名空间,声明需要用户输入的属性,和需要显示的属性&lt;/p&gt;&#xA;&#xA;&lt;p&gt;UI, 属于web-client-config.xml的自定义版本 web-client-config-custom.xml,用于定义各Model中的type如何显示在页面上.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;具体的工作流我就不打算详细说了,也许以后会贴出示例.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;说说几个技巧:&lt;/p&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&lt;p&gt;如果无法用AlfrescoScriptAction解决你遇到的问题,请毫不犹豫地使用自定义的ActionHandler,不过最好继承JBPMSpringActionHandler,以便获取Alfresco相应服务的bean, 而且,bean的name一般就是接口的首字母小写,例如节点服务 nodeService, 用户服务 personService,操作服务actionService(可以创建mail action).&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;流程意外停止,无法继续正常流下去,咋办? 使用 admin/workflow-console.jsp , 然后使用相关的命令对付该流程.例如signal, delete, cancel&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;开发工作流时,请先确保工作流本身是正确的,然后再调试Model/UI&lt;/p&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;p&gt;哈哈,差点忘了, UI还需要properties&amp;lt; 文件,用于定义页面上显示的label&lt;/p&gt;&#xA;&#xA;&lt;p&gt;有用的链接:&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&#34;http://wiki.alfresco.com/wiki/WorkflowAdministration&#34;&gt;alfresco WorkflowAdministration&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&#34;http://wiki.alfresco.com/wiki/Workflow_Console&#34;&gt;alfresco Workflow_Console&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&#34;http://docs.jboss.com/jbpm/v3/userguide/&#34;&gt;jbpm userguide/&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&#34;http://wiki.alfresco.com/wiki/Data_Dictionary_Guide&#34;&gt;alfresco Data_Dictionary_Guide&lt;/a&gt;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Alfresco配置 — 第二节</title>
      <link>http://wendal.net/29.html</link>
      <pubDate>2010-08-03 10:49:31 +0800</pubDate>
      <description>&lt;p&gt;如何关闭/调整部分功能(通过添加选项到alfresco-global.properties):&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;1. 关闭OpenOffice连接 ooo.enabled=false&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Alfresco默认安装OpenOffice进行文件转换,不过,大部分时间是无需的,这部分功能会占用超过100M的内存,而且是JVM之外的内容&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;2. 关闭CIFS和FTP cifs.enabled=false  ftp.enabled=false&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;当你启动Alfresco后,你也许能通过 \你的ip 访问到Alfresco的资源库,这对开发非常有用,但是一般情况下不太需要, ftp也是.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;3. 关闭用户空间配额限制 system.usages.enabled=false&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Alfresco允许你配置每个用户的空间占用,一般使用都是无需的,而且,要真正启用这个功能,你需要逐一配置每个用户的配额.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;4. 关闭自动创建用户空间 home.folder.creation.eager=false&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;这个选项,是我在配置LDAP信息同步的时候遇到的,由于有好几千的用户信息同步到Alfresco,结果在User Space中对应地产生了好几千个子空间,虽然无害,但毕竟非常不雅!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;5. 将索引恢复模式设置为自动 index.recovery.mode=AUTO&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;其实这是默认值,但我仍然要单独提出来. 当你放了成千上万的文档时,你如果设置为FULL,启动Alfresco将非常漫长.如果你配置Alfresco集群,AUTO也绝对是最佳选项.除非你的索引已经被破坏,以致启动失败,那FULL才是你的选择.另外,我建议你每周做一次FULL,能提供索引的可靠性和减少体积.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;6. 调整连接池或者使用自定义的数据源&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;先看看 &lt;a href=&#34;http://wiki.alfresco.com/wiki/Database_Configuration&#34;&gt;http://wiki.alfresco.com/wiki/Database_Configuration&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;当你使用WebLogic来部署Alfresco,那么请加上db.pool.statements.enable=false&lt;/p&gt;&#xA;&#xA;&lt;p&gt;我建议你使用自定义的数据源,替代Alfresco默认的DBCP,例如C3P0,Proxool,BoneCP&lt;/p&gt;&#xA;&#xA;&lt;p&gt;在Tomcat的server.xml添加一个全局的数据源,然后在content.xml引用它,并确保名字为jdbc/dataSource&lt;/p&gt;&#xA;&#xA;&lt;h3&gt;某些故障排除&lt;/h3&gt;&#xA;&#xA;&lt;p&gt;1.&lt;strong&gt;曾经遇到一个情况,Alfresco启动时,读取完配置后就停住,cpu为0,假死, 后来发现是数据库服务器的内存耗尽,导致HibernateSessionFastory创建时一直等待&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;2.&lt;strong&gt;务必修改/etc/hosts文件,使其与当前ip匹配&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;当服务器换ip后,没有改/etc/hosts文件里面的ip,导致启动是查找RMI端口时,长时间等待, 超时后报错停止.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;如果使用默认的127.0.0.1, 当你把vtomcat放到其他机器上,启动连接到Alfresco时就会报127.0.0.2出错, windows下无此问题.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;3.&lt;strong&gt;无法添加新文件或文件夹&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;这个问题表现为页面上提示无法添加,后台提示无法创建XX资源. 原因是磁盘已满,用df看看磁盘占用情况,清理不需要的文件.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;有个小小技巧&lt;/p&gt;&#xA;&#xA;&lt;p&gt;删除了重要文件,而且提交了修改,咋办??&lt;/p&gt;&#xA;&#xA;&lt;p&gt;不要惊慌,Alfresco并没有真正删除你的文件, 点击用户属性(上方第二个按钮),可以看到最下面有&amp;rdquo;已删除的资源&amp;rdquo; 点开,哈哈,看到你想找的文件没?&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Alfresco配置 — 第一节</title>
      <link>http://wendal.net/24.html</link>
      <pubDate>2010-08-02 11:19:53 +0800</pubDate>
      <description>&lt;p&gt;&lt;strong&gt;1. 有用的信息&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Alfresco下载地址 &lt;a href=&#34;http://wiki.alfresco.com/wiki/Download_Community_Edition&#34;&gt;社区版&lt;/a&gt; 企业版可以试用30天,区别不大.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;2. 安装&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;如果你下载的是Windows版的超大安装包,那么,基本上就是一路的next,中途填一下管理员密码就可以了.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;启动之前,我建议你看看   安装文件夹/tomcat/shared/classes/alfresco-global.properties      ,你会看到不少有用的信息:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;dir.root=./alf_data 非常非常核心的参数,务必使用绝对路径,能减少不必要的麻烦(例如移动文件夹后,启动报错)&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;db.开头的都是数据库配置, 其中db.url就是把部分参数合成jdbc url. 关于数据库,我的建议是使用数据源,Alfresco会默认查找jndi名为jdbc/dataSource的资源作为数据源.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;如果你安装的时候使用默认密码admin,就会看到一个&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;alfresco_user_store.adminpassword=209c6174da490caeb422f3fa5a7ae634&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;提前说一个问题&amp;ndash;忘记管理员密码咋办? 看看这篇文章&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&#34;http://wiki.alfresco.com/wiki/Security_and_Authentication#How_to_reset_the_admin_password&#34;&gt;http://wiki.alfresco.com/wiki/Security_and_Authentication#How_to_reset_the_admin_password&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;一般来说, 就是alf_node_properties表的第4或5行. 再提醒一句,只有使用alfresco/alfresco登录mysql才能看到alfresco数据库.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;准备去启动Alfresco或者已经启动了? 不要急嘛, 如果你是*unix系统,请修改/etc/hosts, 查看你的主机名是否被解析为正确的ip,我可吃了不少苦头!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;3. 故障排除&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;启动失败? 不要惊慌,看看是不是以下错误:&lt;/p&gt;&#xA;&#xA;&lt;p&gt;PermGen XXXX ,哈哈,内存不够了? 修改alfresco.bat/alfresco.sh里面的JAVA_OPTS吧,调整-XX:MaxPermSize=160m为-XX:MaxPermSize=256m&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Hibernate dialect Must set ,数据库连接出错啦!! 检查一下数据库是否已经启动,alfresco-global.properties里面填的数据库信息是否正确&lt;/p&gt;&#xA;&#xA;&lt;p&gt;切忌,不能安装到有空格的路径,最好连中文啥的都不要有.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;据我的经验,启动alfresco需时60秒到90秒,第一次启动因为要初始化数据库,故需要的时间更长,有时候看上去停止了,只要cpu占用还不低,就没问题.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;4. 启动成功&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;哦也,你终于启动成功了! (如果按默认安装的话,不能启动的概率=0)&lt;/p&gt;&#xA;&#xA;&lt;p&gt;访问 &lt;a href=&#34;http://localhost:8080/alfresco&#34;&gt;http://localhost:8080/alfresco&lt;/a&gt; 填入你的帐号密码(例如admin/admin) 就能看到强大的Alfresco了!&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>加班的星期天,应该是第一次</title>
      <link>http://wendal.net/20.html</link>
      <pubDate>2010-08-01 10:18:18 +0800</pubDate>
      <description>&lt;p&gt;为了Alfresco的工作流,又加班了一天.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;算是突破性的进展,终于成功把两个流连接起来了,而且可以控制把其中一个流给关闭掉呢,哈哈! 问题的关键是实现自定义的ActionHandler和AssignmentHandler,通过页面获取的工作流id,获取另外一个工作流的全部信息. 我太强大了!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;另外一个问题是发邮件, 似乎Alfresco WCM workflow的标准定义中, 串行工作流模式中, bpm_assignees的值会发生变化,争取找个时间把它简单重现!故,我有做了一个简单的ActionHandler,负责把当前Task的actorid保存在另外一个变量中. 哈哈,又解决一个难题,之前发邮件耗费了我起码一周的时间!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;应老婆建议,明天起有规律的说说Alfresco的配置. 例如如何安装,如何调整vtomcat等,还有就是一些曾经遇到的问题&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>加班的星期六</title>
      <link>http://wendal.net/18.html</link>
      <pubDate>2010-07-31 09:40:11 +0800</pubDate>
      <description>&lt;p&gt;已经忘记了上一次加班是什么时候了?是否曾经星期六加班过呢?&lt;/p&gt;&#xA;&#xA;&lt;p&gt;忙了一天的Alfresco工作流,终于有了突破性进展,放弃内置的AlfrescoScriptAction,改为自己写ActionHandler&lt;/p&gt;&#xA;&#xA;&lt;p&gt;在页面上让用户选需要绑定的工作流 &amp;ndash; 通过自定义的mytasks.jsp和改造wcm的submit-config-workflow.jsp 通过jquery完成页面修改与联动,并隐藏掉原有配置界面.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;今天上Google Reader,发现Alfresco 3.2 SP2 企业版已经发布,修复了不少的Bug,其中两个bug似乎与我们已经遇到的问题相关.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;不清楚客户那边还买不买商业授权,难道真的像我猜测那样转为社区版? 刚刚下载了社区版的3.2 SP2, 发现schema是3300的,而3.2企业版是3400的, 希望不要出乱子.说起这个,Alfresco还真他妈的贵啊!! 不知道如果帮程序换成社区版,会不会又出什么难题&amp;hellip; 悲剧啊&amp;hellip; 肯定又是我来解决.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Alfresco社区版是没有官方支持Oracle和WebLogic的,严重悲剧啊.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>本应该是周末,但是明天要加班</title>
      <link>http://wendal.net/16.html</link>
      <pubDate>2010-07-30 10:49:01 +0800</pubDate>
      <description>&lt;p&gt;没办法,明天加班咯.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;还是工作流的问题,N多问题未解决.继续奋斗咯&lt;/p&gt;&#xA;&#xA;&lt;p&gt;今天把部分Alfresco实例从SP搬到SC,以便加速访问,提高开发速度.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;今天发现并解决一个问题, 当Oracle数据库因为内存不足,cpu占用接近100%是, hibernate会停留在init sessionfactory, 而且没有任何错误提示.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;另外一个问题是RMI, 因为搬迁办公室,ip变更, alfresco启动时需要查找RMI,因为/etc/hosts文件里面的ip没改,结果停留在find RMI port一段时间后死掉.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;再说一个发现, 使用Alfresco vtomcat 3.3 去连接 Alfresco 3.2 时, 总是连不上. 但是3.3的部署接收器却能接收3.2的Alfresco发过来的数据.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>把自己搞得这么累</title>
      <link>http://wendal.net/14.html</link>
      <pubDate>2010-07-29 11:51:57 +0800</pubDate>
      <description>&lt;p&gt;8点就已经回到家了,没休息,就对着电脑&lt;/p&gt;&#xA;&#xA;&lt;p&gt;本可以休息一晚,喝杯茶,看看书&amp;hellip;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;今晚基本上就是聊Q,SunFarm的用户提出来几个挺有效的改进建议,并发布了 3.33 很好玩的一个版本号&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Nutz最近比较安静,难道大家热情消退??&lt;/p&gt;&#xA;&#xA;&lt;p&gt;今天继续磨工作流,总算有点眉目, 不过,周六日加班是必然的了&lt;/p&gt;&#xA;&#xA;&lt;p&gt;非常认同Alfresco的强大,但同时感叹其复杂与难以琢磨&amp;hellip; 学习曲线的确是高&lt;/p&gt;&#xA;&#xA;&lt;p&gt;对Alfresco的基础配置,现在算是滚瓜烂熟了,可惜啊, 对其Workflow还是入门级别,继续奋斗吧,Wendal!&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>被Alfresco的工作流搞崩溃了</title>
      <link>http://wendal.net/11.html</link>
      <pubDate>2010-07-28 08:15:00 +0800</pubDate>
      <description>&lt;p&gt;我实在不行了,投降了!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;想了一天,还是没找到什么方法来满足以下需求:&lt;/p&gt;&#xA;&#xA;&lt;p&gt;在启动一个工作流的时候,列出当前用户尚未完成的工作流,并供其选择,而且是在WCM模块内&lt;/p&gt;&#xA;&#xA;&lt;p&gt;难点: 1. 无法获取myTask 2. 即使获取了,无法以列表方式展示给用户以选择&lt;/p&gt;&#xA;&#xA;&lt;p&gt;崩溃了,我交不了差了,哎&amp;hellip;&amp;hellip;&amp;hellip;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>科学城的办公室有奶茶!</title>
      <link>http://wendal.net/9.html</link>
      <pubDate>2010-07-27 04:19:53 +0800</pubDate>
      <description>&lt;p&gt;有奶茶,有精力!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;久违的奶茶,O(∩_∩)O哈哈~ 热乎乎的泡上一杯!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;中午还吃了烧鸭饭! 半年前的味道,爽!! 之前在SC呆了一年多,现在找回习惯的味道,(&lt;em&gt;^__^&lt;/em&gt;) 嘻嘻……&lt;/p&gt;&#xA;&#xA;&lt;p&gt;继续奋斗工作流&amp;hellip;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>开始尝试jBpm</title>
      <link>http://wendal.net/7.html</link>
      <pubDate>2010-07-27 12:37:29 +0800</pubDate>
      <description>&lt;p&gt;非常无语,本周五要完成一个jBpm流程的开发,悲剧的是我才刚刚接触!!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;下载了Eclipse 3.4.2 和jBpm installer 3.2.7 开工啦&lt;/p&gt;&#xA;&#xA;&lt;p&gt;这次,我还是打算用Alfresco集成的jBpm,因为它提供了预设的UI,无需另外编写.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;参考地址: &lt;a href=&#34;http://wiki.alfresco.com/wiki/WorkflowAdministration&#34;&gt;WorkflowAdministration&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;需要建立Model和Define,Resource&lt;/p&gt;&#xA;&#xA;&lt;p&gt;难点在于Define的识别,和Model的设计. 按照分工, Define由PM完成,我负责UI(打算用Alfresco原本的Model来构建UI)&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>每天写点东西</title>
      <link>http://wendal.net/4.html</link>
      <pubDate>2010-07-26 02:06:16 +0800</pubDate>
      <description>&lt;p&gt;没啥,想写点东西了&lt;/p&gt;&#xA;&#xA;&lt;p&gt;随意吧,开心就好&lt;/p&gt;&#xA;</description>
    </item>
  </channel>
</rss>