<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom">
 
 <title>无网不剩</title>
 
 <link href="http://blog.leezhong.com/" />
 <updated>2012-02-09T09:06:53-08:00</updated>
 <id>http://blog.leezhong.com/</id>
 <author>
   <name>lzyy</name>
   <email>healdream@gmail.com</email>
 </author>

 
 <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/lzyy" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="lzyy" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry>
   <title>写了个基于SQLAlchemy的ORM</title>
   <link href="http://blog.leezhong.com/tech/2012/02/10/introduce-thing-an-sqlalchemy-based-orm.html" />
   <updated>2012-02-10T00:00:00-08:00</updated>
   <id>http://blog.leezhong.com/tech/2012/02/10/introduce-thing-an-sqlalchemy-based-orm</id>
   <content type="html">&lt;p&gt;看Rails时，觉得Rails的ORM用起来好方便，就想找找python有没有类似的，没发现太尽如人意的，就按照自己的意愿，基于SQLAlchemy Core重新写了个，取名为Thing，项目主页: &lt;a href="https://github.com/lzyy/thing"&gt;https://github.com/lzyy/thing&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;主要特性&lt;/h3&gt;
&lt;ol&gt;
	&lt;li&gt;使用方便，灵活&lt;/li&gt;
	&lt;li&gt;支持验证&lt;/li&gt;
	&lt;li&gt;支持事件触发&lt;/li&gt;
	&lt;li&gt;支持多数据库连接&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;不想把ORM做得太magic，将来优化起来会不太方便，所以只是简单地封装了下，既保证了使用起来比较方便，将来涉及到分库分表或缓存时也可以从容应付。&lt;/p&gt;
&lt;h3&gt;安装&lt;/h3&gt;
&lt;p&gt;推荐使用virtualenvwrapper&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="python"&gt;&lt;span class="n"&gt;mkvirtualenv&lt;/span&gt; &lt;span class="n"&gt;thing&lt;/span&gt;
&lt;span class="n"&gt;cdvirtualenv&lt;/span&gt;
&lt;span class="n"&gt;pip&lt;/span&gt; &lt;span class="n"&gt;install&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;git+git://github.com/lzyy/thing.git&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h3&gt;创建模型&lt;/h3&gt;
&lt;p&gt;创建一个继承Thing的基类，主要是设置数据库连接&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="python"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;sqlalchemy&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;create_engine&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;thing&lt;/span&gt;

&lt;span class="n"&gt;master_engine&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;create_engine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;mysql://root:123456@localhost:3306/test&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;slave_engine&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;create_engine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;mysql://root:123456@localhost:3307/test&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BaseThing&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;thing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Thing&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;thing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Thing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;master&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;master_engine&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                                    &lt;span class="s"&gt;&amp;#39;slave&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;slave_engine&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h5&gt;注意事项：&lt;/h5&gt;
&lt;ol&gt;
	&lt;li&gt;所有的模型类都要继承BaseThing&lt;/li&gt;
	&lt;li&gt;如果没有在子类里定义_tablename，则默认使用小写的子类名作为表名&lt;/li&gt;
	&lt;li&gt;表字段会被自动获取&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;假设有这么个场景：一个用户有多个答案，每个答案可以被多人投票。我们可以新建3个Model&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="python"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;thing&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;sqlalchemy&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;create_engine&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;formencode&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;validators&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;blinker&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;signal&lt;/span&gt;

&lt;span class="n"&gt;vote_before_insert&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;vote.before_insert&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Member&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BaseThing&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c"&gt;# 验证email字段&lt;/span&gt;
    &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;validators&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Email&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;messages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;noAt&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;u&amp;#39;invalid email&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="nd"&gt;@property&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;answers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Answer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;member_id&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;=&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Answer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BaseThing&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nd"&gt;@property&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;votes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Vote&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;answer_id&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;=&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nd"&gt;@vote_before_insert.connect&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;_vote_before_insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vote&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;vote&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;answer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;test&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;vote&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;errors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;answer&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;signal test&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Vote&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BaseThing&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nd"&gt;@property&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;member&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Member&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;id&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;=&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;member_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;find&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="nd"&gt;@property&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;answer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Answer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;id&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;=&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;answer_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;find&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;用户与答案是一对多的关系，这里通过@property装饰器来实现，在answers方法内，可以很灵活地实现答案获取的方法。&lt;/p&gt;
&lt;p&gt;在Answer模型里有一个vote_before_insert装饰器，在vote执行insert操作前_vote_before_insert方法会被触发，可以在这里做很多事，如缓存的处理，数据的验证等等。如果验证不通过，可以设置sender的errors属性，该属性一旦被设置，后续的操作将被中断，在这里vote就不会执行insert操作。&lt;/p&gt;
&lt;h5&gt;注意事项：&lt;/h5&gt;
&lt;ol&gt;
	&lt;li&gt;验证使用的是formencode，这个库支持很多的验证操作，&amp;quot;http://www.formencode.org/en/latest/Validator.html&amp;quot;:http://www.formencode.org/en/latest/Validator.html&lt;/li&gt;
	&lt;li&gt;一共有6类事件：model.before_validation / after_validation / before_insert / after_insert / before_update / after_update&lt;/li&gt;
	&lt;li&gt;事件触发时第一个参数为model本身，第二个参数为数据，如果在某个事件响应函数处，设置了model.errors属性，则此次事件之后的代码都不会执行。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;使用&lt;/h3&gt;
&lt;h4&gt;列出一个用户的id&amp;gt;10的所有回答，每次取10个&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="python"&gt;&lt;span class="n"&gt;member&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Member&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;answer&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;member&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;answers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;id&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;&amp;gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;findall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;limit&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;offset&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="n"&gt;answer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h4&gt;创建新用户&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="python"&gt;&lt;span class="n"&gt;member&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Member&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;member&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;foo@bar.com&amp;#39;&lt;/span&gt;
&lt;span class="n"&gt;member&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;123&amp;#39;&lt;/span&gt;
&lt;span class="n"&gt;member&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;save&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="n"&gt;member&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;saved&lt;/span&gt; &lt;span class="c"&gt;# True&lt;/span&gt;
&lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="n"&gt;member&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="c"&gt;# foo@bar.com&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h4&gt;更新用户信息&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="python"&gt;&lt;span class="n"&gt;member&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Member&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;member&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;foo@bar.com&amp;#39;&lt;/span&gt;
&lt;span class="n"&gt;member&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;save&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="n"&gt;member&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;saved&lt;/span&gt; &lt;span class="c"&gt;# True&lt;/span&gt;
&lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="n"&gt;member&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="c"&gt;# foo@bar.com&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h4&gt;验证信息&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="python"&gt;&lt;span class="n"&gt;member&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Member&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;member&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;123&amp;#39;&lt;/span&gt;
&lt;span class="n"&gt;member&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;
&lt;span class="n"&gt;member&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;save&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="n"&gt;member&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;email&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="c"&gt;# invalid email&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h3&gt;多数据库连接&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="python"&gt;&lt;span class="n"&gt;member&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Member&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;slave&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;在执行find / findall / save操作时，有一个db_section选项，如果忽略，则默认使用初始化时传入的engide dict的第一项，在这里就是master，如果想选择其他的数据库，传入该数据库对应的key就行，比如slave&lt;/p&gt;
&lt;h3&gt;其他&lt;/h3&gt;
&lt;ol&gt;
	&lt;li&gt;查看某次插入或更新是否成功，可以检查errors属性，如果为空表示执行成功&lt;/li&gt;
	&lt;li&gt;如果model的key中包含主键，如id，则执行save时是一个更新操作，否则为插入&lt;/li&gt;
	&lt;li&gt;欢迎fork / test / feedback&lt;/li&gt;
&lt;/ol&gt;</content>
 </entry>
 
 <entry>
   <title>小谈摄影</title>
   <link href="http://blog.leezhong.com/essay/2011/12/25/about-photograph.html" />
   <updated>2011-12-25T00:00:00-08:00</updated>
   <id>http://blog.leezhong.com/essay/2011/12/25/about-photograph</id>
   <content type="html">&lt;p&gt;这个标题我纠结了好久，因为『谈论』一般是牛人们的用词，本人摄影小菜鸟一枚，不敢随便用，但一时又找不到合适的词，就先借用一下了。&lt;/p&gt;
&lt;p&gt;注：以下内容，纯属个人观点，如有同感，深感荣幸 :)&lt;/p&gt;
&lt;p&gt;摄影的时间不长，拍照倒是有些年头了，很多人会把拍照和摄影混为一谈，就好像会写代码的都是程序员，会入侵电脑的都是黑客一样。在我看来，摄影最重要的是一颗敏感的心和善于发现的眼睛(器材当然也重要，但重要性不如前者），而拍照只需要一个还过得去的相机就行。拍照的一个很重要作用是留念，如和李开复合影，或者在故宫门前摆个POSE，或者看到某个美景，忍不住按下了快门。而摄影不一样，摄影要累多了，同样是面对某个美景，一个优秀的摄手会尝试各种拍摄手法、构图、用光、光圈大小、快门时间等等，比如面对瀑布，增加快门时间，可以营造水幕的感觉，缩短快门时间又可以抓住飞溅而起的水花。但如果只是拍照，那么拿相机对着瀑布，咔嚓一下就可以了，算是对自己去过某地的证明。&lt;/p&gt;
&lt;p&gt;一个优秀的摄影作品至少要满足『美』和『故事』两者中的一个。美不用说了，故事的意思是，看到一张照片，你会被照片中的主体所吸引，进而去猜测作者拍此照片的意图，甚至去想像作者当时的心情，姿态，等等。照片本身不一定惊艳，但背后的故事却值得细细回味。比如&lt;a href="http://www.flickr.com/photos/zhou_mengjie/6318039145"&gt;这张&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="http://farm7.staticflickr.com/6094/6318039145_0eef0af250_z.jpg" /&gt;&lt;/p&gt;
&lt;p&gt;第一眼可能觉得并不是很漂亮，但马上会被主体所吸引：dancing in the rain。可以从这张照片中看到一种生活态度：大多数人在雨天的路上，多半是行色匆匆，而照片中的主角却可以享受这场雨，雨仿佛成为了一个道具。如果喜欢的话还可以进一步把雨抽象为各种挫折，然后你会看到一种与困境共舞的心态。此时，作者真正想要表达的是什么已经不重要了，重要的是你从这张照片中看到了什么。&lt;/p&gt;
&lt;p&gt;摄影的难度还在于抓住瞬间。当你去参加婚礼，整个场面让你感到很喜庆，但当你认认真真地想找到几个喜庆的镜头时，就会卡住。大家看上去都很happy，那么是来张全景的，还是抓拍某个特别happy的人；婚礼布置的很漂亮，但是从哪个角度去拍效果最好；怎么才能表现出新郎新娘很恩爱，等等。首先脑海中要先有这些意识，然后再从现场找到能够凸显这些特点的画面，这些画面很可能稍纵即逝，或者你没有注意到，或者拍摄角度不对，等等。所以你需要不断调整，不断发现，不断按下快门。这么做的结果就是你无法融入到整个婚礼的过程，只是纯粹以一个摄影师的身份在记录。引用豆友&lt;a href="http://www.douban.com/people/shinewewe/"&gt;想念的树&lt;/a&gt;的一段话：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;我越来越意识到，好多时候我并不愿意拿出相机来截断那些美妙的时刻。我不是说拍下来那就不美妙了，只是你必须意识到并且接受那种变化，一旦发生，即产生了一个时间节点。气氛，记忆发生或多或少的改变。于是我更愿意就那样放弃拍摄的想法，让那些瞬间在记忆中延续下去，流动成诗篇。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;再来说说器材。经常会看到对是否应该配备高端器材的争论，主要争论点是：硬件上去了，那么出来的照片主要是你的功劳还是相机的功劳？你是否沦为了高端器材的奴隶？DigitalRev曾经做过一个实验，让一个专业的摄影师使用低端的卡片机，然后让一个基本不会摄影的人使用高端相机，结果卡片机的效果并不差，而高端相机的效果也没有好到哪去。所以一张好照片肯定是人与相机完美合作的结果。最悲惨的一个场景是，一个高端相机被一个不懂摄影的人当作炫耀的资本，那个相机一定很郁闷，空有一身好武艺，奈何主人无色心。但我还是不太喜欢一味地追求高配（因为我很穷 XDD），这会让你偏离摄影的主旨(除非是工作原因)，少了那颗发现的心，照片即使看上去很漂亮，也经不起细细品味。&lt;/p&gt;
&lt;p&gt;摄影很难，也很累，但很有乐趣，也很有意义。送上我很喜欢的一首小诗（&lt;a href="http://www.douban.com/group/topic/3764247/"&gt;青铮：迦陵频伽——我们所追寻的&lt;/a&gt;）&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;我伸手想要握住光， &lt;br /&gt;
光却消失掉； &lt;br /&gt;
我用镜头对准风， &lt;br /&gt;
风不知去了哪里。 &lt;br /&gt;
然而我从不曾气馁， &lt;br /&gt;
也从来不曾放弃希望； &lt;br /&gt;
我总是背着我的相机， &lt;br /&gt;
走过每一天，走遍这个城市。&lt;/p&gt;
&lt;p&gt;我曾经寻找一个女孩子的身影， &lt;br /&gt;
不肯相信我不能找到， &lt;br /&gt;
因为我寻找的不是她的身份或名字， &lt;br /&gt;
也不是发生在她生命中的我所不知道的故事。 &lt;br /&gt;
我寻找的是她留在我画面上的东西， &lt;br /&gt;
还有我的画面不曾清晰表达的东西； &lt;br /&gt;
光一样会消失，却又永远在那里的东西， &lt;br /&gt;
风一样不可捉摸，但总是会回来的东西。&lt;/p&gt;
&lt;p&gt;你别问我那是什么， &lt;br /&gt;
我将不知如何回答。 &lt;br /&gt;
正如我不知为何我要背着相机， &lt;br /&gt;
走遍这个城市，走遍这个世界， &lt;br /&gt;
年复一年，直到我生命的最后一天， &lt;br /&gt;
直到我还能为一个画面感动不已。&lt;/p&gt;
&lt;p&gt;是的，我不知道为什么， &lt;br /&gt;
一如这个世界上的每一种追寻， &lt;br /&gt;
我只能说，它使我的人生完整， &lt;br /&gt;
它使我的生命具有意义。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;最后小小的宣传下自己的小站：&lt;a href="http://wuditoo.com"&gt;无敌兔&lt;/a&gt;，如果你有不错的照片，不妨去分享下:)&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>一次失败的上线</title>
   <link href="http://blog.leezhong.com/tech/2011/12/04/learned-from-an-unsuccessful-project.html" />
   <updated>2011-12-04T00:00:00-08:00</updated>
   <id>http://blog.leezhong.com/tech/2011/12/04/learned-from-an-unsuccessful-project</id>
   <content type="html">&lt;p&gt;由于上一次通知的上线引来用户的一些不满，所以产品马不停蹄，在一轮又一轮的需求讨论中设计了下一版通知，希望尽快上线，我负责通知的后端实现，当时看到图后，有点小小的崩溃：时间太紧，难度很大，很多地方不属于通知。但是既然定下来了，就只能咬咬牙，拼一拼了。&lt;/p&gt;
&lt;p&gt;于是接下来的9天，变成了一段难忘的回忆，基本上都是3点以后回家，第二天赶上免费的午餐后，继续coding。最后一天还剩了些bug，索性就不回家了，就这样勉强完成了新版的通知，但随后又被推翻，当时确实很愤怒，但细细想想确实有不少地方还不够到位，尤其是新通知的架构，作为责任人之一，以下是我的一些感悟和反思。&lt;/p&gt;
&lt;h3&gt;没有不可能&lt;/h3&gt;
&lt;p&gt;阿迪同学让这句话在全世界流行，但越是常见的东西，越容易熟视无睹。我们相信没有不可能，因为有太多的案例可以证明这句话，但要身体的每一个细胞都坚信这句话就很难了。只有在自己做了一些让后来的自己都不得不佩服的事情时，才会把这句话刻在心里。这样的事对我来说还太少了。&lt;/p&gt;
&lt;h3&gt;好的队友很关键&lt;/h3&gt;
&lt;p&gt;产品同学(ecvip)会把每个设计和交互讲解地很清楚，会陪着我们熬到很晚。前端同学(Dang &amp;amp; 骁哥)总是能高效地完成页面，思路很清晰，我总是觉得自己在拖他们的后腿。后端同学也就是我，估计是这个木桶最短的那块。还有就是CTO申申同学并没有过于责备这次的失败，而是要请我们撮一顿，那个感动啊。&lt;/p&gt;
&lt;h3&gt;需求是会变化的&lt;/h3&gt;
&lt;p&gt;我这次就是栽倒这上了，为了满足当前的需求而设计了对应的架构，导致后来需求发生变化时很难应对。在设计时就应该考虑到将来的可变性，尽量灵活。&lt;/p&gt;
&lt;h3&gt;多向别人请教&lt;/h3&gt;
&lt;p&gt;由于时间比较紧，加上自己理解上的偏差，在设计后端架构时没有与其他同学进行沟通，就直接进行代码实现。写着写着就觉得有点奇怪，但已经这样了，就只能继续按着现在的架构走。等到后来杨昆同学review代码时才发现：我靠，怎么成了这样。&lt;/p&gt;
&lt;h3&gt;升级自己的技能&lt;/h3&gt;
&lt;p&gt;海贼王里，每一次战斗，大家的技能都会有提升，越是大的战斗，敌人越强劲，技能升级地越高。在现实中，应该是在大的战役前做好充足的技能储备，打完战役后，总结哪些地方还需要继续提升和完善，接下来再有目的地去改进，避免在下次的战役中出现同样的问题。&lt;/p&gt;
&lt;p&gt;&lt;img src="/image/little-miss-sunshine1.jpg" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="/image/little-miss-sunshine2.jpg" /&gt;&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>使用python和redis实现实时聊天室</title>
   <link href="http://blog.leezhong.com/tech/2011/10/26/python-comet.html" />
   <updated>2011-10-26T00:00:00-07:00</updated>
   <id>http://blog.leezhong.com/tech/2011/10/26/python-comet</id>
   <content type="html">&lt;p&gt;实时的实现一般有ajax long poll / iframe stream / websocket 这三种。websocket有浏览器的限制;iframe会使页面一直处于loading状态(如果没有这个限制，iframe stream相比long poll还是比较有优势的); ajax long poll因为它的跨浏览器特性，加上实现比较简单，所以不少的实时应用都选择了long poll, 这里也选择ajax long poll来实现&lt;/p&gt;
&lt;p&gt;放个截图先：&lt;/p&gt;
&lt;p&gt;&lt;img src="/image/comet_chat.png" /&gt;&lt;/p&gt;
&lt;p&gt;主要工具：python (flask / gevent / apscheduler) + redis&lt;/p&gt;
&lt;p&gt;目前这个聊天室的功能还比较简单，可以实时更新全局在线用户，当前聊天室在线用户和聊天内容，都是通过一个ajax长连接实现的。在这个连接里定义了需要实时的内容，相应的内容一旦在服务端更新，可以马上推送到各个客户端。&lt;/p&gt;
&lt;p&gt;实时最大的挑战在于如何能在服务端尽量简单，灵活地实现。因为越是简单，就越不容易滋生bug，即使出现问题，查找起来也很方便;越是灵活，就越容易应付多变的需求。以聊天室为例，当新用户加入后需要更新所有客户端的当前成员列表;有成员退出后也要更新该列表。每个聊天室有了新内容后都要实时推到所有客户端;给某个用户发私信，对方也可以实时收到。这些如果处理地不好，很容易与当前的逻辑发生耦合，为将来的调整和bug的查找带来困难。&lt;/p&gt;
&lt;p&gt;依靠强大的redis，设计了这个简易的实时聊天室，基本架构如下:&lt;/p&gt;
&lt;p&gt;&lt;img src="/image/comet_arch.png" /&gt;&lt;/p&gt;
&lt;p&gt;匆忙完成了初步的代码，还有不少需要优化的地方，有些功能也还没加上（如私信的实时通知）。接下来的一段时间内会逐步完善，如果有更好的idea，欢迎沟通 :)&lt;/p&gt;
&lt;p&gt;代码地址：&lt;a href="https://github.com/lzyy/chat"&gt;https://github.com/lzyy/chat&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;如果使用过程中遇到什么问题，或有好的建议可以在&lt;a href="https://github.com/lzyy/chat/issues"&gt;这里&lt;/a&gt;反馈&lt;/p&gt;
&lt;h3&gt;version 0.2&lt;/h3&gt;
&lt;ul&gt;
	&lt;li&gt;调整了实时的策略，抛弃pubsub模式，使用zset+timestamp。同时修正了在聊天内容频繁发送时会丢部分信息的bug&lt;/li&gt;
	&lt;li&gt;添加了管理员角色（目前只能用于删除聊天室）&lt;/li&gt;
	&lt;li&gt;修正重复名的bug（无法完全避免，只能在登录时验证）&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;version 0.1.1&lt;/h3&gt;
&lt;ul&gt;
	&lt;li&gt;调整了添加聊天室的体验&lt;/li&gt;
	&lt;li&gt;更快的聊天内容显示速度&lt;/li&gt;
	&lt;li&gt;可以删除自己创建的聊天室&lt;/li&gt;
	&lt;li&gt;bugfixes&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;version 0.1&lt;/h3&gt;
&lt;h4&gt;intro&lt;/h4&gt;
&lt;p&gt;某天晚上打球回来，到家已将近11点，洗完澡，代码敲到2点左右倒下，天还没亮就被猫叫醒，醒来后就一直想如何改进这个聊天室，觉得能在一个页面实时看到每个聊天室的内容，还是很酷的，于是就按着这个想法实现了。&lt;/p&gt;
&lt;p&gt;PS: 如果不是全新安装，需要执行 bin/python scripts/clear_key.py 来清除redis cache&lt;/p&gt;
&lt;h4&gt;changelog&lt;/h4&gt;
&lt;ul&gt;
	&lt;li&gt;可以自定义昵称&lt;/li&gt;
	&lt;li&gt;调整了聊天页的内容和样式&lt;/li&gt;
	&lt;li&gt;添加了home页（显示所有的聊天室，并实时更新每个聊天室的内容）&lt;/li&gt;
	&lt;li&gt;使用coffee-script重写了js部分&lt;/li&gt;
	&lt;li&gt;bugfixes&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;screenshot&lt;/h4&gt;
&lt;p&gt;&lt;img src="/image/comet_home_0.1.png" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="/image/comet_room_0.1.gif" /&gt;&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>python的简单MapReduce实现：计算π</title>
   <link href="http://blog.leezhong.com/tech/2011/09/10/python-mapreduce-pi.html" />
   <updated>2011-09-10T00:00:00-07:00</updated>
   <id>http://blog.leezhong.com/tech/2011/09/10/python-mapreduce-pi</id>
   <content type="html">&lt;p&gt;MapReduce是Google提出的一个软件架构，一般用于大规模数据集的并行运算。核心概念就是&amp;quot;Map（映射）&amp;quot;和&amp;quot;Reduce（化简）&amp;quot;。&lt;/p&gt;
&lt;p&gt;简单说来就是把一个任务分割成多个独立的子任务，子任务的分发由map实现，子任务计算结果的合并由reduce实现。&lt;/p&gt;
&lt;p&gt;mapreduce的应用场景多是那种互不依赖，上下文无关的任务。所以类似Fibonacci数列这种对输入有依赖的就不适合使用mapreduce。&lt;/p&gt;
&lt;p&gt;回到正题，要计算圆周率，我们先构建这么个模型&lt;/p&gt;
&lt;p&gt;&lt;img src="http://code.google.com/edu/parallel/img/inscribe.png" /&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="python"&gt;&lt;span class="c"&gt;# 外面的正方形面积&lt;/span&gt;
&lt;span class="n"&gt;As&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;
&lt;span class="c"&gt;# 里面的圆的面积&lt;/span&gt;
&lt;span class="n"&gt;Ac&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pi&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;

&lt;span class="n"&gt;pi&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Ac&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;As&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;
&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;As&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;
&lt;span class="n"&gt;pi&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;Ac&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;As&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;也就是说只要算出圆的面积与正方形面积的比，就可以求出圆周率。&lt;/p&gt;
&lt;p&gt;可以通过以下步骤计算Ac / As：&lt;/p&gt;
&lt;p&gt;1) 随机在正方形里生成许多点&lt;br /&gt;
2) 计算点在圆内与在正方形内的比例&lt;/p&gt;
&lt;p&gt;测试的随机点越多，结果越精确&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="python"&gt;&lt;span class="c"&gt;#coding=utf-8&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;random&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;multiprocessing&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;multiprocessing&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Process&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MapReduce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;object&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;map_func&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;reduce_func&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;workers_num&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map_func&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;map_func&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;reduce_func&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;reduce_func&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;workers_num&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;workers_num&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;workers_num&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;workers_num&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;multiprocessing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cpu_count&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;multiprocessing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Pool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;workers_num&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__call__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;inputs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;map_result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pool&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map_func&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;inputs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;reduce_result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;reduce_func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;map_result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;reduce_result&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;calculator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="n"&gt;multiprocessing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;current_process&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;&amp;#39; processing&amp;#39;&lt;/span&gt;
    &lt;span class="n"&gt;points&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;circle_round&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;points_in_circle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;points&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
	    &lt;span class="c"&gt;# 这里其实只取了1/4圆&lt;/span&gt;
        &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;circle_round&lt;/span&gt;
        &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;circle_round&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;circle_round&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;points_in_circle&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;points_in_circle&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;count_circle_points&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;points_list&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;points_list&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;__main__&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="c"&gt;# 半径&lt;/span&gt;
    &lt;span class="n"&gt;CIRCLE_ROUND&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
    &lt;span class="c"&gt;# 总点数&lt;/span&gt;
    &lt;span class="n"&gt;POINTS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10000000&lt;/span&gt;
    &lt;span class="c"&gt;# 总进程数&lt;/span&gt;
    &lt;span class="n"&gt;WORKERS_NUM&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;

    &lt;span class="n"&gt;map_reduce&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;MapReduce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;calculator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;count_circle_points&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;WORKERS_NUM&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;inputs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[(&lt;/span&gt;&lt;span class="n"&gt;POINTS&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;WORKERS_NUM&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;CIRCLE_ROUND&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;WORKERS_NUM&lt;/span&gt;
    &lt;span class="n"&gt;all_points_in_circle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;map_reduce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;inputs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;ac_as&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;all_points_in_circle&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;POINTS&lt;/span&gt;
    &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;pi approach to:&lt;/span&gt;&lt;span class="si"&gt;%7f&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;ac_as&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;这是比较简单的单机mapreduce，用多进程就可以实现。如果是多机运算的话，就麻烦多了，类似这张图：&lt;/p&gt;
&lt;p&gt;&lt;img src="http://code.google.com/edu/parallel/img/mrfigure.png" width='700px'/&gt;&lt;/p&gt;
&lt;p&gt;参考链接&lt;sup class="footnote"&gt;&lt;a href="#fn2"&gt;2&lt;/a&gt;&lt;/sup&gt;有对这张图的解释&lt;/p&gt;
&lt;p&gt;参考：&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;sup class="footnote"&gt;&lt;a href="#fn1"&gt;1&lt;/a&gt;&lt;/sup&gt; &lt;a href="http://blog.doughellmann.com/2009/04/implementing-mapreduce-with.html"&gt;http://blog.doughellmann.com/2009/04/implementing-mapreduce-with.html&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;sup class="footnote"&gt;&lt;a href="#fn2"&gt;2&lt;/a&gt;&lt;/sup&gt; &lt;a href="http://code.google.com/edu/parallel/mapreduce-tutorial.html"&gt;http://code.google.com/edu/parallel/mapreduce-tutorial.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content>
 </entry>
 
 <entry>
   <title>How To Find What You Love To Do</title>
   <link href="http://blog.leezhong.com/translate/2011/09/04/how-to-find-what-you-love-to-do.html" />
   <updated>2011-09-04T00:00:00-07:00</updated>
   <id>http://blog.leezhong.com/translate/2011/09/04/how-to-find-what-you-love-to-do</id>
   <content type="html">&lt;p&gt;我们都知道要做自己喜欢的，但自己真正喜欢什么，却未必清楚。也很少有时间问问自己：这辈子究竟要做些什么？怎么做才无愧此生？生活就像一个没有设置break的while True循环，一旦开始就停不下来了。上班要忙上班的事，周末要聚会，看电影，玩游戏，逛街，把上班时的痛苦补回来，然后在不情愿中迎接下一个周一。这是自己想要的生活吗？&lt;/p&gt;
&lt;p&gt;&lt;a href="http://briankim.net/blog/2006/07/how-to-find-what-you-love-to-do/"&gt;原文链接&lt;/a&gt;(gfwed)&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;这篇文章是受乔布斯在斯坦福大学的演讲的启发，在那次演讲中，他说了我们听了不下千次的建议：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;你必须找到你所爱的。无论是工作还是爱人。工作将占据你生命中大部分时间，你只有相信自己所做的是伟大的工作, 才能怡然自得。而有伟大成就的唯一途径就是爱你所做的。&amp;#8212; Steve Jobs&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;这也自然而然地牵扯出另一个问题：&lt;/p&gt;
&lt;h3&gt;如何找到自己所爱的？&lt;/h3&gt;
&lt;p&gt;这是一个大问题。&lt;/p&gt;
&lt;p&gt;真正让自己热血沸腾的是我们可以一直做自己最爱的事，但却没有循序渐进的教程可以帮助我们找到自己所爱的。以往的经验能起一点作用，但无法形成一套体系。&lt;/p&gt;
&lt;p&gt;为了找到自己的热情，可以问自己：如果有一百万美元，你想做什么？&lt;/p&gt;
&lt;p&gt;典型的回答是：会把这些钱存入银行，然后每年光利息就可以生活了。然后会搬到夏威夷，买一个别墅，品尝所有的美味，看看书，搞点体育运动，等等。&lt;/p&gt;
&lt;p&gt;这样的回答有帮助吗？可能吧。比如，你知道了自己原来是个大懒鬼，但这并没有回答背后的问题：如何能做自己喜欢的事，还能挣到钱？&lt;/p&gt;
&lt;p&gt;人们从事着自己讨厌的工作，感觉像掉入了陷阱，因为他们无法离开，他们靠着这唯一的收入来维持目前的生活状态，以此来逃避现实，漂流在严酷、漫无目的的生活中，简而言之：活在平静的绝望中。&lt;/p&gt;
&lt;p&gt;你或许会问：他们为什么不辞职，追求自己喜欢的呢？&lt;/p&gt;
&lt;p&gt;两个原因：&lt;/p&gt;
&lt;p&gt;原因1：他们不知道自己最喜欢的事&lt;br /&gt;
原因2：恐惧。他们要维持目前的生活，有账单要付，家人要照顾，怕没有稳定的收入来源，怕别人异样的目光或说三道四，等等。搞定原因1，接下来的就会迎刃而解。&lt;/p&gt;
&lt;p&gt;无论你信不信，想要找到自己的激情所在已经是一个很大的进步了。很多人，他们一生都在回避或者根本没想过这个问题。当他们听到这个问题时，会很熟练地忽视之。&lt;/p&gt;
&lt;h4&gt;如何找到自己所爱的？这是一个很重要的问题，而你必须找到答案&lt;/h4&gt;
&lt;p&gt;你必须自己决定目的地，不然生活就会替你做决定。如果知道了目的地，剩下的就很简单了。&lt;/p&gt;
&lt;p&gt;你会发现，一旦你找到了自己所爱的，所有的不确定、负担都会从你的肩上滑落，你会很清楚地看到自己的旅程，一趟充满欢喜的旅程。&lt;/p&gt;
&lt;p&gt;&lt;b&gt;在你看完这篇文章时，我真心地希望你能够实践之。&lt;/b&gt;&lt;/p&gt;
&lt;h3&gt;为什么找到自己所爱的那么难？&lt;/h3&gt;
&lt;p&gt;答案是：&lt;/p&gt;
&lt;p&gt;这一点都不难。是的，你没看错，一点都不难&lt;/p&gt;
&lt;p&gt;那为什么这么多人都被这个问题所困扰呢？&lt;/p&gt;
&lt;p&gt;&lt;b&gt;因为他们从未真正地问过自己&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;我觉得很有意思的一件事是，人们好像总是要让自己做点什么，停不下来。比如：出去玩、聚会、逛街等等。不要误解，做这些事没有任何问题。但我怀疑大部分人都有这样的心态：我必须每时每分都做点什么，因为我做不了自己。只是想让自己在别人面前看起来风光一点。但事实上，要让自己充实起来，应该多花一点时间在自己身上。&lt;/p&gt;
&lt;p&gt;人们以为必须环游世界，尝试新事物等等才能找到自己的所爱。不，你只要坐下来，然后决定。答案已经在你心里。你只要把它挖出来，别耽搁。&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Just let it out.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;说实话，你有没有曾经独自一人坐下来，抛开手机，离开电脑，关上电视、聊天工具，关上自己最爱听的歌，关闭游戏，停止检查邮件、回复电话、浏览杂志等等其他一切分心的事，扪心自问：自己到底喜欢什么？&lt;/p&gt;
&lt;p&gt;你害怕问题的答案，因为答案是：我不知道。&lt;/p&gt;
&lt;p&gt;这也是为什么你必须找到答案的原因。承认自己不知道，这是ok的，比那些自动跳过的好多了。&lt;/p&gt;
&lt;p&gt;下面让我们一步一步地来找到答案。&lt;/p&gt;
&lt;h4&gt;Step 1: 毫无疑问，你一定会找到答案&lt;/h4&gt;
&lt;p&gt;你一定会找到，无庸置疑。&lt;/p&gt;
&lt;p&gt;带着这样的心态，你就一定会找到。会花多长时间？不重要。你终将会找到。&lt;/p&gt;
&lt;p&gt;这样做，你会自动开启反放弃机制，因为你知道你一定会找到答案。&lt;/p&gt;
&lt;p&gt;比如，如果你知道你要去纽约，你就会找到去那里的方法，你会搭车、火车或飞机，然后到达。&lt;/p&gt;
&lt;p&gt;如果没有钱，你可以借，或者找份工作省钱，或者找一份空姐/空哥的工作，这样就可以免费去那。花多长时间不重要，要做些什么也不重要，因为你知道你要去纽约。&lt;/p&gt;
&lt;p&gt;你这个决定之后所有的行动都会围绕着『去纽约』而展开。&lt;/p&gt;
&lt;p&gt;再读一遍最后这句&lt;/p&gt;
&lt;p&gt;你这个决定之后所有的行动都会围绕着『去纽约』而展开。&lt;/p&gt;
&lt;p&gt;找到你所爱的 ＝ 决定去纽约&lt;/p&gt;
&lt;h4&gt;Step 2: 分两列，列一个技能清单和兴趣列表，并且写下来&lt;/h4&gt;
&lt;p&gt;再强调一遍：写下来。不要以为你可以在头脑中完成。&lt;/p&gt;
&lt;p&gt;我这说的技能是任何技能。可以是无形的。比如编程，网页制作，聊天，倾听，说服别人，打字，调情，分析，演讲，让事情易于理解，吹口哨等等。不要害羞，列出所有自己的技能。&lt;/p&gt;
&lt;p&gt;在另一列，列出自己的兴趣，同样，也不要害羞。列出所有你能想到的兴趣。蜘蛛、鞋子、头发、化妆品、篮球、网球、幻想、保姆、散步、ps、fireworks、帮助别人、搞笑、钓鱼、空手道、瓶起子等等，什么都行。是的，我提到了瓶起子。你的兴趣也可以包含自己擅长的方面。计算机、经济学、生物学、篮球、足球、魔术等等。&lt;/p&gt;
&lt;p&gt;为了帮助你写下更多的兴趣爱好，想想之前的那份工作你最感兴趣的是什么，不感兴趣的又是什么。&lt;/p&gt;
&lt;p&gt;问自己以下这些问题有助于发现自己追求的技能和兴趣&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;如果你去一个书店，那个书架上的书对你的引力最大？问问朋友他们眼中你的技能和兴趣。你会惊叹于他们的洞察力。&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
	&lt;li&gt;你把大多数的时间都花在了哪些事上？做这些事你期望得到怎样的结果？像小孩子一样想像自己的成就。都有哪些技能和兴趣对你的成就有帮助？&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
	&lt;li&gt;你做了什么别人会感谢你？&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
	&lt;li&gt;你的老师或家人有没有说过你有什么诀窍？&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
	&lt;li&gt;为什么我一再强调技能和兴趣？&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;技能：你必须依赖你的强项。不要告诉我你什么也没有。每个人都有技能。你只是没有坐下来细想，并且写下来。&lt;/p&gt;
&lt;p&gt;兴趣：很简单，你必须爱你所做的。&lt;/p&gt;
&lt;p&gt;专注于你能想到的兴趣和技能，并且写下来&lt;/p&gt;
&lt;p&gt;你会发现你的技能好像受了引力作用一样偏向一种或两种技能，兴趣也一样。好，下面让我们进入步骤3&lt;/p&gt;
&lt;h4&gt;Step 3：问正确的问题来找到自己的最爱&lt;/h4&gt;
&lt;p&gt;找一个真正属于自己的时间和空间，没有任何分心的东西，通过问正确的问题来找到自己的最爱&lt;/p&gt;
&lt;p&gt;我发现一个很有趣的现象，人们总是为税务、烹饪、电影、阅读留出时间，但是涉及到自己的将来时，却从来不会腾出时间。&lt;/p&gt;
&lt;p&gt;现在，假如你已经安排了私人时间，没有杂事干扰，然后呢？&lt;/p&gt;
&lt;p&gt;你必须问自己一个清晰的问题，清晰是关键，问题越清晰，回答越简单。&lt;/p&gt;
&lt;p&gt;比如，我问，12x12等于多少？答案很明了：144&lt;/p&gt;
&lt;p&gt;如果我问两个偶数和另外两个偶数的乘积？这就很难回答了&lt;/p&gt;
&lt;p&gt;&lt;b&gt;清晰的问题引出清晰的答案&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;另外一个关键点是：写下来。我知道你听过一万次了，不过这是有原因的。把东西写下来有助于你在各项之间建立联系，这在脑海里是很难完成的。&lt;/p&gt;
&lt;p&gt;如果你在之前的阶段没有写下技能和兴趣，那么停下，马上写下来。放在大脑里是不会有帮助的。&lt;/p&gt;
&lt;p&gt;现在利用独处的时间问自己一个清晰的问题，这个问题会是：“我最喜欢做什么？”吗？&lt;/p&gt;
&lt;p&gt;这个问题有点广泛了，再缩小一点，问自己：&lt;/p&gt;
&lt;p&gt;&lt;b&gt;在每天的生活中，我最喜欢做什么，可以同时结合我的技能和兴趣，并给人们的生活带来重大价值？&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;看到区别了吗？问题越具体，越清晰，回答起来就越方便。我为什么加了价值这一项，？因为这会帮助你找到挣钱的方法。&lt;/p&gt;
&lt;p&gt;“通过技能和兴趣带来重大价值”，可以自动过滤那些普遍的答案，如：“看电视”，或“玩游戏”，这些答案往往会带来消极因素，因为看不到挣钱的方法。&lt;/p&gt;
&lt;p&gt;顺带一句，很多人会误解这句话的核心，把重点放在了挣钱上。钱只是通过产品或服务为人们的生活带去方便的一个副产品&lt;/p&gt;
&lt;p&gt;当你知道你可以为别人的生活带来方便时，你就会知道如何挣钱。&lt;/p&gt;
&lt;p&gt;打开Word或纸张，在最前面写下这个问题。&lt;/p&gt;
&lt;p&gt;在每天的生活中，我最喜欢做什么，可以同时结合我的技能和兴趣，并给人们的生活带来重大价值？&lt;/p&gt;
&lt;p&gt;再强调一遍，重点是写下你自己的答案&lt;/p&gt;
&lt;p&gt;看看之前列的两列清单，写下答案，有多少，写多少。不必完美，也不一定要有什么意义。因为迟早你会把这些关连起来。下面这个故事可以帮助阐述我的意思。&lt;/p&gt;
&lt;p&gt;有一个小镇，以滑雪而出名，吸引了一大批游客前来，这对于促进经济有很大的作用。但是，下雪时，雪会沉积在电缆上，直到把电缆压跨，导致部分能源过载。慢慢的游客们都不来了，于是小镇举行了一个会议，讨论如何解决雪压跨电缆的问题。很久都没有好的解决方案。&lt;/p&gt;
&lt;p&gt;突然有人在会议室的后面大声喊道“我们可以在电缆上放几盆蜂蜜，让熊爬上电缆，拿到蜂蜜，熊的这一系列动作会把电缆上的雪抖落”&lt;/p&gt;
&lt;p&gt;在座的都笑了，有人接这个话茬“那我们怎么再在这些盆里放蜂蜜呢？”“可以用直升飞机”，另一个人说。&lt;/p&gt;
&lt;p&gt;于是答案就出来了，让直升飞机在电缆上飞，通过螺旋桨的风力把雪吹落。&lt;/p&gt;
&lt;p&gt;我想说的是，无论答案有多可笑，都不用害怕，因为它们常常能帮你找到最终的结果。这是过程的一部分。&lt;/p&gt;
&lt;p&gt;所以无论多滑稽，写下来。写下所有的答案。直到你有了20个答案，然后回顾它们。你会发现，你写下的答案会帮助你找到新的答案。&lt;/p&gt;
&lt;p&gt;你会惊叹写下的所有东西，以及各个富有创意的想法。&lt;/p&gt;
&lt;p&gt;&lt;b&gt;现在又要集中注意力了&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;你肯定听过通过放大镜来聚焦阳光的事。但我还是想说，如果你打算一次处理多件事，那么哪件事都完不成。即使在最热的天，如果你不停移动放大镜，并不会聚焦多大的能量，什么也烧不着。只是无端地浪费自己的精力。&lt;/p&gt;
&lt;p&gt;通过管理你的精力，时间，思考等等，在攻克一个目标时，你会惊叹目标完成的深度和效率。就像你在一个东西上放了一个放大镜，而你的欲望，精力，时间，思考，想像就是太阳光。&lt;/p&gt;
&lt;p&gt;专注很重要，这里我想再举个例子。想像自己是一只猎豹，正在追逐两只羚羊。如果想同时追逐两个的话，那么什么也抓不到，只能饿死。先拿下一只，这可能需要时间去追击去撕咬，但当你真的吃掉了它，你又充满电了。你可以收集信息：羚羊都往哪个方向跑了，可能在哪块停留，等等。这有助于你今后捕获更多的羚羊，这就形成了良性循环。简而言之：专注于一个目标。&lt;/p&gt;
&lt;p&gt;所以检查你刚刚的列表，选择一个最感兴趣的。你可能会发现，你可以把多个想法集中到一个。最好选择一个不仅能给自己带来极大的满足感，还能够帮助别人的想法。&lt;/p&gt;
&lt;h4&gt;如何知道自己已经找到了最爱？&lt;/h4&gt;
&lt;p&gt;做这件事让你觉得爽吗？如果发自肺腑地觉得很爽，那就对了。&lt;/p&gt;
&lt;p&gt;如果你的朋友跟你谈论这个话题，你愿意跟他没完没了地谈论吗？&lt;/p&gt;
&lt;p&gt;你必须毫无保留地喜欢这件事。如果你感到一丁点的怀疑，那这就不是你的激情所在。你必须急切地渴望克服任何困难来追逐你的激情。&lt;/p&gt;
&lt;p&gt;一旦你找到了这件事，你的任务就完成了。&lt;/p&gt;
&lt;p&gt;至于如何通过它来挣钱，在你写下答案时，可能已经找到方法了。如果想找到更多挣钱的方法，只需重复之前的步骤。&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Step 1: 毫无疑问，你一定会找到答案&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Step 2: 分两列，列一个技能清单和兴趣列表，并且写下来，你会发现其实有很多挣钱的方法&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;挣钱的方法只能靠你自己了，不过对你来说应该不难。&lt;/p&gt;
&lt;p&gt;现在你知道了自己的最爱以及如何挣钱，该是行动的时候了。&lt;/p&gt;
&lt;p&gt;很多人看到这里，没有任何行动，所以他们的生活也没有发生任何变化。&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>知乎的困境</title>
   <link href="http://blog.leezhong.com/essay/2011/07/19/zhihu.html" />
   <updated>2011-07-19T00:00:00-07:00</updated>
   <id>http://blog.leezhong.com/essay/2011/07/19/zhihu</id>
   <content type="html">&lt;p&gt;个人观点，欢迎指正:)&lt;/p&gt;
&lt;h3&gt;知乎要解决一个什么问题？&lt;/h3&gt;
&lt;p&gt;如果我遇到以下问题：&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;为什么有的照片拍出来建筑物是倾斜的？&lt;/li&gt;
	&lt;li&gt;陈奕迅的『爱情转移』到底想要表达什么？&lt;/li&gt;
	&lt;li&gt;iphone4升级到ios5 beta3后，可不可以降到4.3.3？&lt;/li&gt;
	&lt;li&gt;如何训练台球的基本功？&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;第一反应是到知乎提问，且能在较短时间内得到满意的答复，那么知乎就成了。其实从产品上是完全可以应付的，最难的是用户为什么要来这里提问？&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;如果我有iphone4，第一反应肯定是去weiphone。&lt;/li&gt;
	&lt;li&gt;如果我想更了解电影，豆瓣或mtime都是不错的选择。&lt;/li&gt;
	&lt;li&gt;如果我想精通摄影，会选择蜂鸟或无忌。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;什么时候会想到去知乎？&lt;/p&gt;
&lt;p&gt;知乎就好比是宾馆，如果要讨论某个领域的问题，先到前台领门牌号，然后到一个房间讨论。而垂直社区直接就是一个房间，打开门后就可以看到一大堆人在那讨论。&lt;/p&gt;
&lt;p&gt;用一段程序来表述大致如下&lt;/p&gt;
&lt;h4&gt;当前状态&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="python"&gt;&lt;span class="n"&gt;tags&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;摄影&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;电影&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;创业&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;摄影&amp;quot;&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
	&lt;span class="n"&gt;goto&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;蜂鸟&amp;quot;&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;无忌&amp;quot;&lt;/span&gt;
	&lt;span class="k"&gt;return&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;电影&amp;quot;&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
	&lt;span class="n"&gt;goto&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;mtime&amp;quot;&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;douban&amp;quot;&lt;/span&gt;
	&lt;span class="k"&gt;return&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;创业&amp;quot;&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
	&lt;span class="n"&gt;goto&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;咖啡厅&amp;quot;&lt;/span&gt;
	&lt;span class="k"&gt;return&lt;/span&gt;

&lt;span class="c"&gt;# when will you think of zhihu&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h4&gt;理想状态&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="python"&gt;&lt;span class="n"&gt;tags&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;摄影&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;电影&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;创业&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="n"&gt;whatever&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
	&lt;span class="n"&gt;goto&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;知乎&amp;quot;&lt;/span&gt;
	&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;answers&lt;/span&gt; &lt;span class="n"&gt;found&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
		&lt;span class="k"&gt;return&lt;/span&gt;
	&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
		&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;摄影&amp;quot;&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
			&lt;span class="n"&gt;goto&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;蜂鸟&amp;quot;&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;无忌&amp;quot;&lt;/span&gt;
			&lt;span class="k"&gt;return&lt;/span&gt;

		&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;电影&amp;quot;&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
			&lt;span class="n"&gt;goto&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;mtime&amp;quot;&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;douban&amp;quot;&lt;/span&gt;
			&lt;span class="k"&gt;return&lt;/span&gt;

		&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;创业&amp;quot;&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
			&lt;span class="n"&gt;goto&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;咖啡厅&amp;quot;&lt;/span&gt;
			&lt;span class="k"&gt;return&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;要让用户产生这种观念上的改变，那时的知乎在某个领域(如摄影)一定已经积累的相当的人气和问答。以摄影为例，摄影的初始问答从何而来？我觉得只可能是知乎重度用户打算学摄影，或者在学习过程中遇到问题，然后抱着试试看的心情发了个问题。为什么是知乎重度用户？因为如果只是偶尔过来逛逛的用户，在他眼里，这只是一个有点意思的网站，并没有太深的感情，就算遇到了摄影方面的问题，一看相关问题很少，直接就放弃了发问题的念头，因为对他来说浏览是一种习惯，而我们的行为都受习惯的支配。这也好解释为什么知乎重度用户明知可能得不到比较理想的答案，也可能会发问题，因为他习惯了参与，习惯了回答或提问。&lt;/p&gt;
&lt;p&gt;所以知乎如果要向各个领域扩展，至少要具备这几个条件：&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;足够数量的重度用户&lt;/li&gt;
	&lt;li&gt;重度用户的爱好最好广泛些&lt;/li&gt;
	&lt;li&gt;各个领域都有些活跃的达人&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;第三个条件很难。假如一个摄影相关的问题被提出后没有很快地得到好的答案，会很打击用户的积极性，下次如果再有类似问题，可能会选择其他的专业论坛。这时就需要该领域的达人出现了，这里又有一些问题：&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;达人一般都很忙，很难抽出时间静下心来回答问题&lt;/li&gt;
	&lt;li&gt;有那么几天，达人关注的领域都没有什么新问题或有意思的问题，以后索性就不来了&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;达人很少制造问题，所以把某些领域的达人作为种子用户，问答的氛围也很难建立。&lt;/p&gt;
&lt;h3&gt;内容为王，逐步开放&lt;/h3&gt;
&lt;p&gt;国内不乏人气很旺的大站，但普遍有一种很水的感觉，简单说来就是，社交氛围多于思维碰撞。这往往是站长们追求pv/用户数/发贴数的结果。这也是知乎的吸引力所在，在知乎能感觉到一种宁静，如果让我给知乎写一个slogan的话，应该会是：正经提问和回答的地方。如果不是这样，那就没理由来知乎了，水区多的是。&lt;/p&gt;
&lt;h3&gt;如何维持高质量的回答&lt;/h3&gt;
&lt;p&gt;业界达人不是回答的主力军，因为已经有足够的影响力了，也很少有时间来回答。但他们的回答能带来极好的效果。所以氛围的维系主要落在准达人身上，他们愿意回答是因为帮助别人是一种很自然的事，同时也可以向其他人展示自己的阅历、知识和才华。但是这些准达人是很挑剔的，如果问题的质量明显下降了，或者另一层次的用户大量入驻，或者感觉整个氛围不对，很可能就say goodbye了，所以如何让这些准达人持续贡献高质量的回答也是个问题。&lt;/p&gt;
&lt;h3&gt;不局限于问答&lt;/h3&gt;
&lt;p&gt;单纯的问答很难持久，用户很难养成每天习惯性地上来看看这种行为。要让用户泡起来，还需要具备&amp;quot;信息&amp;quot;输出。我们习惯上hacker news，因为那里总是能发现很酷的东西，或者行业新闻；上weifeng也是因为大量的信息和资源。所以Quora支持&amp;quot;Write Post&amp;quot;，支持blog feed import。&lt;/p&gt;
&lt;p&gt;前面的路很难，但创业从来都是要披荆斩棘的，带着一颗不安份的心，奋斗吧&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>time to leave</title>
   <link href="http://blog.leezhong.com/life/2011/07/12/time-to-leave.html" />
   <updated>2011-07-12T00:00:00-07:00</updated>
   <id>http://blog.leezhong.com/life/2011/07/12/time-to-leave</id>
   <content type="html">&lt;p&gt;五个月前，去豆瓣面试，结果由于自己的薪资要求偏高，与豆瓣失之交臂。&lt;/p&gt;
&lt;p&gt;两个月前，杭州一家我挺中意的公司对我抛出了橄榄枝，由于公司股票的原因，我放弃了那次机会。&lt;/p&gt;
&lt;p&gt;这次又是类似的一幕：北京一家我挺喜欢的公司对我有兴趣，但由于中期考核拿到了AA(最高等级，研发部一共两个人)，所以如果现在提出离职的话，奖金就没戏了。除非等到月底拿完钱，然后再提出离职。于是又开始小小的纠结了。&lt;/p&gt;
&lt;p&gt;几番思量，加上总结之前的教训，提出了辞职，不想再因为钱而耽误了这次机会。而且如果等着这笔钱，人格上实在是不怎么光辉，也是对自己能力的不自信。还有一个原因是: 新公司那边的座位紧张，不想站着coding。XD&lt;/p&gt;
&lt;p&gt;其实，如果不去新公司，也想歇歇了。调整一下心情，明确一下目标，问问自己究竟想要什么。跟新东家接触后发现，非常接近我之前说的理想中的公司，于是我心动了。&lt;/p&gt;
&lt;p&gt;在那里上下班不用刷卡，有免费的午餐，发mbp，用git管理源码，不在windows下写程序，工程师主导。最重要的是我认可那里的人，以及他们正在做的事。忽然有种找到组织的感觉。&lt;/p&gt;
&lt;p&gt;知乎，我来了&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>纪念L君</title>
   <link href="http://blog.leezhong.com/life/2011/06/24/disillusion.html" />
   <updated>2011-06-24T00:00:00-07:00</updated>
   <id>http://blog.leezhong.com/life/2011/06/24/disillusion</id>
   <content type="html">&lt;p&gt;套用《纪念刘和珍君》的一段话：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;我也早觉得有写一点东西的必要了，这虽然于离者毫不相干，但在职者，却大抵只能如此而已&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;一个我抬头就能看到他开着四个小窗口进行调试的人，一个当初把我带到公司的人，一个前两天还在地铁跟我说他开发的nginx模块已经基本可用的人，一个可以让我们安心搞研发的人，一个刚搬到新办公地点就因为有地方可以放那么多技术书籍而高兴的人，一个因为带着书度蜜月而被MM抱怨的人，忽然就这么离开了。&lt;/p&gt;
&lt;p&gt;如果把公司比作在前线战斗的军队，L的职责是为前线的战士提供好用，高效的作战武器，从手枪到导弹，还有自己的一部分军队。但是忽然某一天指挥官说：L，你可以走了。就像死神宣布某个人的生命结束那样直接，残酷。&lt;/p&gt;
&lt;p&gt;L离开的原因有很多的版本：研发成果没有被项目使用；搞小团体；底下的部门投诉太多；权利太大，上层被架空等等。但是无论哪种或几种理由都至少可以坐下来谈谈吧。三四天的时间，几乎没有什么交接，就让技术部的三位核心走人，简单粗暴。即使理在你那一边，这种做法实在是我不敢苟同的。为公司效力了三年多的技术部管理层，在没有犯明显错误的情况下，居然是像瘟神一样被&amp;quot;请出&amp;quot;公司，作为一个普通员工，我实在不能没有想法。&lt;/p&gt;
&lt;p&gt;我不知道上层是怎么想的，貌似他们觉得也没有必要让我们知道他们是怎么想的，真正的原因是什么。在这种信息不对称的情况下，我只能通过平时的接触，有限的信息来得出自己的判断。L是一个比较典型的技术牛人，由于职责所在，也会负责管理。但是L以这种方式离开，加上公司重心的转移，以及与上层的交谈，我只能得出这么个结论：业务为主，技术为辅，业务搞好，则赢；反之则输。技术，技术人才的储备，技术团队的磨合都不重要，至少优先级比较低。我的脑海中忽然想起去年年终会时，一位高层说：明年我们的目标是打造业界第一的PHP团队。有那么一瞬间我几乎信了，因为他说得那么真诚。&lt;/p&gt;
&lt;p&gt;L的离去还有一个影响就是带走了部分技术氛围。对于技术人员来说，这种技术氛围是很珍贵的。平时即使不常跟L沟通，但只要看到人在那，心里就多少会觉得踏实。&lt;/p&gt;
&lt;p&gt;L走好，不知道何时还能再见到你那天真无邪的小眼睛 :)&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>小心PHP的类定义顺序与继承的问题</title>
   <link href="http://blog.leezhong.com/tech/2011/06/15/be-careful-with-php-extends.html" />
   <updated>2011-06-15T00:00:00-07:00</updated>
   <id>http://blog.leezhong.com/tech/2011/06/15/be-careful-with-php-extends</id>
   <content type="html">&lt;p&gt;以下代码的运行环境均为PHP5.3.4&lt;/p&gt;
&lt;p&gt;先来看一段代码&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="php"&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;A&lt;/span&gt; &lt;span class="k"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;B&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;B&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;代码很简单，也可以正常运行。看起来PHP的类定义与顺序无关。&lt;/p&gt;
&lt;p&gt;再来看下面一段代码&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="php"&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;A&lt;/span&gt; &lt;span class="k"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;B&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;B&lt;/span&gt; &lt;span class="k"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;C&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;C&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;猜猜结果会怎样？有点出乎意料，代码报Fatal Error。&lt;/p&gt;
&lt;p&gt;这就奇怪了，上一段代码也是在后面声明的类B，正常。多了一层继承关系后，就报错了，错误信息是&amp;quot;Fatal Error: class &amp;#8216;B&amp;#8217; not found &amp;quot;。 这又不能理解了，为什么会说找不到类B呢。&lt;/p&gt;
&lt;p&gt;再来尝试一下新的组合&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="php"&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;A&lt;/span&gt; &lt;span class="k"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;B&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;C&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;B&lt;/span&gt; &lt;span class="k"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;C&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;好了，又正常了。&lt;/p&gt;
&lt;p&gt;再来尝试一下namespace&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="php"&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nx"&gt;A&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
	&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;A&lt;/span&gt; &lt;span class="k"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;\B\B&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nx"&gt;B&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
	&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;B&lt;/span&gt; &lt;span class="k"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;\C\C&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nx"&gt;C&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
	&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;C&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;结果跟不是用ns是一样的。&lt;/p&gt;
&lt;p&gt;这种时候，只能看看官方是怎么说的了 &lt;a href="http://php.net/manual/en/keyword.extends.php"&gt;http://php.net/manual/en/keyword.extends.php&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Classes must be defined before they are used! If you want the class Named_Cart to extend the class Cart, you will have to define the class Cart first. If you want to create another class called Yellow_named_cart based on the class Named_Cart you have to define Named_Cart first. To make it short: the order in which the classes are defined is important.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;说得很明确，类必须先定义后使用，哪怕是在一个文件里。但这又无法解释第一段代码为什么可以正常运行。所以基本可以认为这是一个php的bug。&lt;/p&gt;
&lt;p&gt;好在有autoload机制，这种情况完全可以避免。不过对那些想通过把许多类文件合并成一个来提高PHP运行效率的童鞋们来说，这就有点麻烦咯。&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>缩进输出目录结构并计算文件/文件夹大小</title>
   <link href="http://blog.leezhong.com/tech/2011/06/10/cacl-tree.html" />
   <updated>2011-06-10T00:00:00-07:00</updated>
   <id>http://blog.leezhong.com/tech/2011/06/10/cacl-tree</id>
   <content type="html">&lt;p&gt;如果把这个命题分开来实现会方便点，比如缩进输出目录结构可以通过先序遍历实现，计算文件夹大小可以通过后续遍历实现，但结合到一块就稍微有点麻烦了。比如我们要得到如下的输出&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="php"&gt;&lt;span class="x"&gt;LICENSE (1.040K)&lt;/span&gt;
&lt;span class="x"&gt;README.md (0.951K)&lt;/span&gt;
&lt;span class="x"&gt;UPDATE.ja.md (23.951K)&lt;/span&gt;
&lt;span class="x"&gt;UPDATE.md (19.390K)&lt;/span&gt;
&lt;span class="x"&gt;autoload.php.dist (0.875K)&lt;/span&gt;
&lt;span class="x"&gt;check_cs (3.312K)&lt;/span&gt;
&lt;span class="x"&gt;phpunit.xml.dist (1.160K)&lt;/span&gt;
&lt;span class="x"&gt;src (8302.127K) // 文件夹&lt;/span&gt;
&lt;span class="x"&gt;    Symfony (8302.127K) // 文件夹&lt;/span&gt;
&lt;span class="x"&gt;        Bridge (84.567K) // 文件夹&lt;/span&gt;
&lt;span class="x"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;我首先想到的方法是把文件/文件夹的计算和输出分开来实现，不过这样效率不高，因为有些文件会被多次使用filesize方法。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="php"&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;get_size&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$file_or_dir&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
	&lt;span class="nv"&gt;$filesize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

	&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;is_file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$file_or_dir&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
	&lt;span class="p"&gt;{&lt;/span&gt;
		&lt;span class="nv"&gt;$filesize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;filesize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$file_or_dir&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
	&lt;span class="p"&gt;}&lt;/span&gt;
	&lt;span class="k"&gt;else&lt;/span&gt;
	&lt;span class="p"&gt;{&lt;/span&gt;
		&lt;span class="nv"&gt;$filesize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
		&lt;span class="k"&gt;foreach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;glob&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$file_or_dir&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;/*&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nv"&gt;$file&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
		&lt;span class="p"&gt;{&lt;/span&gt;
			&lt;span class="nv"&gt;$filesize&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;get_size&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$file&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
		&lt;span class="p"&gt;}&lt;/span&gt;
	&lt;span class="p"&gt;}&lt;/span&gt;

	&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$filesize&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;tree&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$prefix&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$file_or_dir&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
	&lt;span class="nv"&gt;$filename&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$prefix&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;/&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;$file_or_dir&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
	&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;is_file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$filename&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
	&lt;span class="p"&gt;{&lt;/span&gt;
		&lt;span class="c1"&gt;// 每次输出都计算一次，如果是文件夹的话，文件夹下的文件会被多次计算，浪费也就在此&lt;/span&gt;
		&lt;span class="nx"&gt;pad_output&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$file_or_dir&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;get_size&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$filename&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nv"&gt;$length&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
	&lt;span class="p"&gt;}&lt;/span&gt;
	&lt;span class="k"&gt;else&lt;/span&gt;
	&lt;span class="p"&gt;{&lt;/span&gt;
		&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$handle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;opendir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$filename&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
		&lt;span class="p"&gt;{&lt;/span&gt;
			&lt;span class="nx"&gt;pad_output&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$file_or_dir&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;get_size&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$filename&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nv"&gt;$length&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
			&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nv"&gt;$file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;readdir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$handle&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
			&lt;span class="p"&gt;{&lt;/span&gt;
				&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$file&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;.&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nv"&gt;$file&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;..&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
				&lt;span class="p"&gt;{&lt;/span&gt;
					&lt;span class="nx"&gt;tree&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$filename&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$file&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nv"&gt;$length&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
				&lt;span class="p"&gt;}&lt;/span&gt;
			&lt;span class="p"&gt;}&lt;/span&gt;
		&lt;span class="p"&gt;}&lt;/span&gt;
	&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;这样，假如a/b/c.txt这个文件，在获取c.txt文件大小时会计算c.txt一次，获取b文件夹大小时还会计算一次，获取a文件夹时仍然会计算一次。也就是说文件的重复计算次数跟目录深度成正比。&lt;/p&gt;
&lt;p&gt;后来又想了一个方法可以避免重复计算，且占用不多的内存，自认为效率还算高。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="php"&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;cacl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$file&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
	&lt;span class="k"&gt;global&lt;/span&gt; &lt;span class="nv"&gt;$padding&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

	&lt;span class="nv"&gt;$f_pad&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$file&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
	&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nv"&gt;$pos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;strrpos&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$file&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;/&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
	&lt;span class="p"&gt;{&lt;/span&gt;
		&lt;span class="nv"&gt;$f_pad&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;substr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$file&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$pos&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
	&lt;span class="p"&gt;}&lt;/span&gt;
	&lt;span class="nv"&gt;$f_pad&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;str_repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$padding&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;$f_pad&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

	&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;is_file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$file&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
	&lt;span class="p"&gt;{&lt;/span&gt;
		&lt;span class="nv"&gt;$size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;filesize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$file&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
		&lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;$f_pad&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$size&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
	&lt;span class="p"&gt;}&lt;/span&gt;
	&lt;span class="k"&gt;else&lt;/span&gt;
	&lt;span class="p"&gt;{&lt;/span&gt;
		&lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;$f_pad&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
		&lt;span class="nv"&gt;$size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
		&lt;span class="k"&gt;foreach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;glob&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$file&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;/*&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nv"&gt;$filename&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
		&lt;span class="p"&gt;{&lt;/span&gt;
			&lt;span class="nv"&gt;$size&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;cacl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$filename&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nv"&gt;$length&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
		&lt;span class="p"&gt;}&lt;/span&gt;
		&lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;$f_pad&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$size&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;_&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
	&lt;span class="p"&gt;}&lt;/span&gt;
	&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$size&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;这个只用了一个函数，更短，更快。引用数组负责数据的存储，递归返回值负责文件的大小，为了减少内存的使用，在文件夹的size后面加了&amp;quot;_&amp;quot;来表示这是一个文件夹，输出时去掉&amp;quot;_&amp;quot;就行了。&lt;/p&gt;
&lt;p&gt;如果你有更好的想法，欢迎交流 :)&lt;/p&gt;
&lt;p&gt;github地址：&lt;a href="https://github.com/lzyy/cacl_tree"&gt;https://github.com/lzyy/cacl_tree&lt;/a&gt;&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>一道面试题的思考</title>
   <link href="http://blog.leezhong.com/tech/2011/06/03/php-xor-find-num.html" />
   <updated>2011-06-03T00:00:00-07:00</updated>
   <id>http://blog.leezhong.com/tech/2011/06/03/php-xor-find-num</id>
   <content type="html">&lt;p&gt;前几天下班途中跟同事聊到了一道面试题，大意是，给你1-1000个连续自然数，然后从中随机去掉两个，再打乱顺序，要求只遍历一次，求出被去掉的两个数。&lt;/p&gt;
&lt;p&gt;这题其实挺为面试者的，因为要求1分钟内说出解法，且不能使用计算机、纸和笔。如果之前没有遇到过类似的题目，加上面试时的紧张心情，很难能在那么短的时间里想到解决方案，至少我做不到。&lt;/p&gt;
&lt;p&gt;好在我有时间，上网看了一下，比较常见的有两种方法&lt;/p&gt;
&lt;h3&gt;求方程组的解&lt;/h3&gt;
&lt;p&gt;遍历被打乱的数组时，计算value的累加值和value平方的累加值。结合未打乱之前的数组，这样就能得出x+y = m与x*x+y*y = n两个方程，解这组方程即可算出被去掉的两个数。这种方法比较容易理解，实现起来也比较简单&lt;/p&gt;
&lt;h3&gt;使用异或&lt;/h3&gt;
&lt;p&gt;这个就麻烦点了。先来说说异或的定义：两个二进制位不同的取1。再来说说异或的两个特性：顺序无关 / 对一个数异或两次等于没有异或。顺序无关就是说异或的元素可以随意交换顺序，而不会影响结果。异或两次可以理解为+x和-x。&lt;/p&gt;
&lt;h4&gt;计算出x^y的值&lt;/h4&gt;
&lt;p&gt;首先，这两个数组(打乱前和打乱后)各自异或，也就是1^2^&amp;#8230;^1000，得到两个异或值。再对这两个异或值进行一次异或，这样就得到了x^y的指(重复部分互相抵消了)。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="php"&gt;&lt;span class="x"&gt;// 其实就是把数组的所有元素进行异或，重复部分互相抵消&lt;/span&gt;
&lt;span class="x"&gt;result = 1^2^...^1000^1^2...^1000;&lt;/span&gt;
&lt;span class="x"&gt;result = 1^1^2^2...^x...^y...^1000^1000;&lt;/span&gt;
&lt;span class="x"&gt;result = x^y;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h4&gt;获取计算出的异或值的1所在的位置，并继续异或&lt;/h4&gt;
&lt;p&gt;因为x和y是两个不同的整数，所以这两个数的异或结果，转化为二进制的话，一定在某位是1，假设在第3位。也就是说如果把原始数组按第3位是否为0进行划分，就可以分成两个数组，每个数组各包含一个被抽取的数。如果打乱后的数组也按这个规则划分为两个数组，这样就得到了4个数组，其中两组是第3位为0，另外两组是第3位为1。把第3位为0的两个数组所有元素进行异或就能得到被抽取的一个数，同理也就能获得另外一个被抽取的数，于是问题解决。&lt;/p&gt;
&lt;h3&gt;PHP的实现&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="php"&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt; 
&lt;span class="c1"&gt;// 起始长度&lt;/span&gt;
&lt;span class="nv"&gt;$length&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nv"&gt;$arr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$arr_copy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$length&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// 将要被移除的两个数&lt;/span&gt;
&lt;span class="nv"&gt;$num1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$num2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// 两个数组异或再互相异或的结果&lt;/span&gt;
&lt;span class="nv"&gt;$num1_num2_xor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// 存放被pos分割的数字&lt;/span&gt;
&lt;span class="nv"&gt;$arr_0&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$arr_1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$arr_copy_0&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$arr_copy_1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;array&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// 获取一个数字转化为二进制后1所在的位置&lt;/span&gt;
&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;get_pos&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$num&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
	&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
	&lt;span class="p"&gt;{&lt;/span&gt;
		&lt;span class="nv"&gt;$b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;pow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
		&lt;span class="nv"&gt;$rs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$num&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nv"&gt;$b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
		&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$rs&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nv"&gt;$rs&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
		&lt;span class="p"&gt;{&lt;/span&gt;
			&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
		&lt;span class="p"&gt;}&lt;/span&gt;
	&lt;span class="p"&gt;}&lt;/span&gt;
	&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// 进行异或计算&lt;/span&gt;
&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;do_xor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
	&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$x&lt;/span&gt;&lt;span class="o"&gt;^&lt;/span&gt;&lt;span class="nv"&gt;$y&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
	&lt;span class="k"&gt;global&lt;/span&gt; &lt;span class="nv"&gt;$arr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$arr_copy&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$num1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$num2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$num1_num2_xor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

	&lt;span class="nv"&gt;$rand_index_1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;mt_rand&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$length&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
	&lt;span class="nv"&gt;$rand_index_2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;mt_rand&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$length&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$length&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

	&lt;span class="c1"&gt;// 获取两个随机数，然后去掉从数组中去掉它们&lt;/span&gt;
	&lt;span class="nv"&gt;$num1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;$rand_index_1&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
	&lt;span class="nv"&gt;$num2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;$rand_index_2&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

	&lt;span class="nb"&gt;unset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;$rand_index_1&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
	&lt;span class="nb"&gt;unset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;$rand_index_2&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

	&lt;span class="nx"&gt;cacl_num1_num2_xor&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
	&lt;span class="nx"&gt;divide_by_pos&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;get_pos&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$num1_num2_xor&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
	&lt;span class="nx"&gt;get_num&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// 获取两个数组各自异或再互相异或的结果&lt;/span&gt;
&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;cacl_num1_num2_xor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
	&lt;span class="k"&gt;global&lt;/span&gt; &lt;span class="nv"&gt;$arr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$arr_copy&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$num1_num2_xor&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
	&lt;span class="nv"&gt;$arr_xor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;array_reduce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$arr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;do_xor&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
	&lt;span class="nv"&gt;$arr_copy_xor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;array_reduce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$arr_copy&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;do_xor&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

	&lt;span class="nv"&gt;$num1_num2_xor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$arr_xor&lt;/span&gt; &lt;span class="o"&gt;^&lt;/span&gt; &lt;span class="nv"&gt;$arr_copy_xor&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// 根据pos将两个数组再各自细分成两个数组&lt;/span&gt;
&lt;span class="c1"&gt;// 其中$arr_copy_0和$arr_copy_1各自包含了一个被抽取的数&lt;/span&gt;
&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;divide_by_pos&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$pos&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
	&lt;span class="k"&gt;global&lt;/span&gt; &lt;span class="nv"&gt;$arr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$arr_copy&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$arr_0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$arr_1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$arr_copy_0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$arr_copy_1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
	&lt;span class="nv"&gt;$b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;pow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$pos&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

	&lt;span class="k"&gt;foreach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$arr&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nv"&gt;$val&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
	&lt;span class="p"&gt;{&lt;/span&gt;
		&lt;span class="nv"&gt;$rs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$val&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nv"&gt;$b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
		&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$rs&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
		&lt;span class="p"&gt;{&lt;/span&gt;
			&lt;span class="nv"&gt;$arr_0&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$val&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
		&lt;span class="p"&gt;}&lt;/span&gt;
		&lt;span class="k"&gt;else&lt;/span&gt;
		&lt;span class="p"&gt;{&lt;/span&gt;
			&lt;span class="nv"&gt;$arr_1&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$val&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
		&lt;span class="p"&gt;}&lt;/span&gt;
	&lt;span class="p"&gt;}&lt;/span&gt;

	&lt;span class="k"&gt;foreach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$arr_copy&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nv"&gt;$val&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
	&lt;span class="p"&gt;{&lt;/span&gt;
		&lt;span class="nv"&gt;$rs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$val&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nv"&gt;$b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
		&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$rs&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
		&lt;span class="p"&gt;{&lt;/span&gt;
			&lt;span class="nv"&gt;$arr_copy_0&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$val&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
		&lt;span class="p"&gt;}&lt;/span&gt;
		&lt;span class="k"&gt;else&lt;/span&gt;
		&lt;span class="p"&gt;{&lt;/span&gt;
			&lt;span class="nv"&gt;$arr_copy_1&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$val&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
		&lt;span class="p"&gt;}&lt;/span&gt;
	&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// 对这4个数组进行对应的异或操作，就出结果了&lt;/span&gt;
&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;get_num&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
	&lt;span class="k"&gt;global&lt;/span&gt; &lt;span class="nv"&gt;$arr_0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$arr_1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$arr_copy_0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$arr_copy_1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$num1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$num2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
	&lt;span class="nv"&gt;$arr_0_xor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;array_reduce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$arr_0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;do_xor&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
	&lt;span class="nv"&gt;$arr_copy_0_xor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;array_reduce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$arr_copy_0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;do_xor&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
	&lt;span class="nv"&gt;$cacl_num1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$arr_0_xor&lt;/span&gt;&lt;span class="o"&gt;^&lt;/span&gt;&lt;span class="nv"&gt;$arr_copy_0_xor&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

	&lt;span class="nv"&gt;$arr_1_xor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;array_reduce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$arr_1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;do_xor&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
	&lt;span class="nv"&gt;$arr_copy_1_xor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;array_reduce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$arr_copy_1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;do_xor&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
	&lt;span class="nv"&gt;$cacl_num2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$arr_1_xor&lt;/span&gt;&lt;span class="o"&gt;^&lt;/span&gt;&lt;span class="nv"&gt;$arr_copy_1_xor&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

	&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$cacl_num1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39; / &amp;#39;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;$cacl_num2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="nx"&gt;PHP_EOL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
	&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$num1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39; / &amp;#39;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;$num2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;init&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;</content>
 </entry>
 
 <entry>
   <title>做完猜电影的一点感想</title>
   <link href="http://blog.leezhong.com/essay/2011/05/30/iguess-feeling.html" />
   <updated>2011-05-30T00:00:00-07:00</updated>
   <id>http://blog.leezhong.com/essay/2011/05/30/iguess-feeling</id>
   <content type="html">&lt;p&gt;如果你认真，持续地去做了一件事，几乎不可能没有收获。&lt;a href="http://iguess.me"&gt;猜电影&lt;/a&gt;这个业余项目也断断续续进行了将近20天，从GAE到VPS，从python到PHP，反正就是各种折腾，现在成品基本上出来了，当然还有很多需要完善和改进的，&lt;a href="http://iguess.me"&gt;欢迎访问&lt;/a&gt; :)。以下是一些我的小感想&lt;/p&gt;
&lt;h3&gt;你能在凌晨4点半起来吗？&lt;/h3&gt;
&lt;p&gt;早起其实不难，如果你对这一天充满了期待，或者急不可耐地想要去做一件事。做这个项目的时候，经常会有一些有意思的想法，然后就恨不得马上去实现，但是太晚了，而且工作了一天后，晚上的效率也不高。于是只能放到凌晨，我清楚地记得那天给自己定了4点半的闹钟，结果3点醒来后，就再也睡不着了，于是从3点一直开发到早上7点多，再睡一个小回笼觉到8点多，就屁颠屁颠地上班去了。上班时的感觉也很好，因为一块大石头已经放到杯子里，有底了。&lt;/p&gt;
&lt;p&gt;记得当年从时光网辞职后，在家帮朋友开发一个手机社区，也有过一阵类似的感觉，当然那时自由多了，想几点起就几点起，起床后可以痛快地做自己的项目，现在还真有点怀念。&lt;/p&gt;
&lt;p&gt;37signals的招聘中写到：认同一个伟大的工作并驱动自己，这非常重要。不知道大家对自己的工作还有没有激情，有没有憧憬，有没有感觉到挑战，如果没有或者比较少，又是如何释放自己的激情，为什么不到一个更广阔的空间？&lt;/p&gt;
&lt;p&gt;国内有梦想的公司不少，或者说，每个公司都应该有自己的梦想吧，或大或小，或远或近而已。但你真的能够认同吗？你发自肺腑地希望公司能够蒸蒸日上吗？在公司最困难的时候，你愿意留下来吗？答案很可能是否定的。公司不是我们的归宿，她只是与我们进行着一笔交易，她出钱，我们出时间和技能。最危险的是我们会渐渐地习惯这个交易，以为人生本应如此，梦想这玩意不现实。呵呵，有点扯远了。&lt;/p&gt;
&lt;h3&gt;表面看起来简单的事，做起来真不简单&lt;/h3&gt;
&lt;p&gt;这也是我喜欢苹果的一个原因，她可以让一个操作尽量简单，易懂，一用就会，但是易用的背后往往包含着很复杂的处理过程。这才是用户至上。写猜电影的时候，我常常会想: 这个功能应该怎样在页面上体现，应该怎样交互用户才不会迷茫，是否有必要加一个提交按钮，loading效果怎样做才看着比较舒服等等。当然，如果只是想实现这个功能就没必要费这个周折了。&lt;/p&gt;
&lt;p&gt;前期只需要完成最核心的功能，让用户可以无障碍地使用，功能尽量少，但每个功能都要做到看着舒服，用着流畅。功能越少，用户越不容易迷茫，后期再推出新功能时，也更加能接受。好比税收一样，一下子扣去一年的税和分月扣，虽然结果是一样的，但哪个更能接受？&lt;/p&gt;
&lt;p&gt;要有追求完美的心态。就拿那个投票来说吧，看上去很简单的上下箭头加上中间的数字，其实要考虑的因素有不少：是否已登入？是否之前投过票？投过票的话是否要高亮显示？是否是自己发的帖子？如何防止多次投票？等等。要做到完美并不容易。&lt;/p&gt;
&lt;h3&gt;记得重构&lt;/h3&gt;
&lt;p&gt;一开始为了能尽快出第一个版本，往往对代码的质量就不那么讲究，这很正常，说正确也无妨。敏捷嘛，就是要讲究快速发布版本，但庞大的函数，一段又一段又一段的if else判断，臃肿的类，无意义的数字、变量，重复的代码等等，这些虽然成功地帮助你实现了最基本的功能，但如果放任不管，将来开发新功能，或修改bug时就够你受的了，这也严重影响了下一版本的发布。&lt;/p&gt;
&lt;p&gt;如果代码量已经挺大了，且可重构部分还不少，那就有点不妙了，不过好在自己写的代码最熟悉，多费点时间还是可以重构地差不多的。不过更好的方法是持续重构，也就是隔三差五地让自己的代码变得更优雅。软件开发就是与熵的战斗，如果不用心，熵就会很大，结果嘛，你懂的:)&lt;/p&gt;
&lt;h3&gt;不要给自己贴标签&lt;/h3&gt;
&lt;p&gt;我是个PHP程序员，不会设计，不会js，不会前端交互，无法独立完成一个网站。&lt;br /&gt;
我是个编辑，要我使用SQL语句，天哪，杀了我吧(我从朋友的口中得知，他们公司有如此BT的编辑存在)。&lt;br /&gt;
我是个产品经理，我不需要动那些具体的技术细节，我只要把我的想法表达清楚就好了。&lt;/p&gt;
&lt;p&gt;老罗当年招了好几茬设计都没有一个合适的，到最后不也是自己上嘛，那可是老罗啊，一个相声表演艺术家，自学设计，貌似效果还不错。&lt;/p&gt;
&lt;p&gt;爱给自己贴标签的人，往往在他自己的领域也难有太大的建树，因为如果你是一个PHP程序员，你可以拒绝学习linux，mysql，nginx，设计模式，等等，也可以拒绝了解PHP内部的运行机制，因为你可以告诉自己：我是一个普通的php程序员，不需要了解这些。其实说白了，还是对自己学习能力的不自信，没有刨根问底的精神，没有探索未知领域的意愿。&lt;/p&gt;
&lt;h3&gt;想得稍微长远一点&lt;/h3&gt;
&lt;p&gt;比如，花了很长的时间，终于把你的作品熬出来了，然后呢？怎么让目标用户知道并且喜欢上你的作品？哎，我是个天真的程序员，总是幻想着，我把一个idea实现了，慢慢地就会有人来用，然后慢慢地他们会口口相传。我的目标不是有多少用户数，我只在乎我的这个应用能为多少人带来便利，能为多少人解决问题。虽然如此，看着自己消耗了那么多的ATP，做出来的东西没人用，难免会有点伤感。&lt;/p&gt;
&lt;p&gt;所以除非只是想练练手，不然最好想一下如何去推广，除非你在该领域有足够的影响力或资源。&lt;/p&gt;
&lt;h3&gt;小结&lt;/h3&gt;
&lt;p&gt;鉴于我懒得推广，又想做点能够影响一批人的东东，所以我打算以后多花点时间在正事上，把基本功练好，加入一个靠谱的团队。十个巴掌怎么也比一个巴掌拍得响。&lt;/p&gt;
&lt;p&gt;有不少人担心程序员是吃青春饭的，过了30，就会力不从心，到时要么做管理要么转行。有了这个想法后，就更不可能用心地去写程序，去思考。恶性循环就这么产生了。我倒愿意相信，各行各业之间是相通的。计算机系统是如此地神奇，算法是如此地考验脑力，linux是如此地优雅。如果真的把程序搞得很明白透彻了，其间你所收获的知识，经验一定可以运用到(至少是部分)其他领域，这也是达芬奇老人家能够精通多门领域的一个原因吧。&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>have you lost yourself?</title>
   <link href="http://blog.leezhong.com/essay/2011/05/23/have-you-lost-your-self.html" />
   <updated>2011-05-23T00:00:00-07:00</updated>
   <id>http://blog.leezhong.com/essay/2011/05/23/have-you-lost-your-self</id>
   <content type="html">&lt;ul&gt;
	&lt;li&gt;期待周五，讨厌周一吗？&lt;/li&gt;
	&lt;li&gt;期待发薪水的那天吗？&lt;/li&gt;
	&lt;li&gt;下班后急着回家吗？&lt;/li&gt;
	&lt;li&gt;上班时盼望领导今天不在吗？&lt;/li&gt;
	&lt;li&gt;有花一半以上的时间在工作或工作相关的事情上吗？&lt;/li&gt;
	&lt;li&gt;是否不太情愿地打开工作相关的文件？&lt;/li&gt;
	&lt;li&gt;有没有分析过自己的优势和劣势，及如何提高和弥补？&lt;/li&gt;
	&lt;li&gt;回到家后还会从事工作相关的事情吗？&lt;/li&gt;
	&lt;li&gt;第二天醒来不知道今天要干什么？&lt;/li&gt;
	&lt;li&gt;不知道这周/月都做了什么？&lt;/li&gt;
	&lt;li&gt;盼望有一天能通过彩票/抽奖改变自己的命运？&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;有一份稳定的工作，领着满意的薪水，跟同事相处融洽，也有和睦的家庭。看上去一切都是那么美好，但这真是自己想要的吗？还是只是想让别人看上去很好？从小我们就生活在别人的眼里，但凡有一点出格的表现，就会马上被家人纠正，被朋友取笑。渐渐地，我们妥协了，放弃了追求自己想成为的那个人。&lt;/p&gt;
&lt;p&gt;&amp;quot;一个人如果遵照他的内心去活着，他要么成为一个疯子，要么成为一个传奇&amp;quot;。如果在别人眼里，你是一个正常的人，很可能，你已经有那么点不正常了。&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>做了个猜电影的小应用</title>
   <link href="http://blog.leezhong.com/project/2011/05/12/iguess.html" />
   <updated>2011-05-12T00:00:00-07:00</updated>
   <id>http://blog.leezhong.com/project/2011/05/12/iguess</id>
   <content type="html">&lt;p&gt;话说前一阵子和朋友出去聚餐，闲着没事，就想来猜电影，但是各种搜索，都没找到一个比较靠谱的地方，于是俺就打算做一个猜电影的小应用&lt;/p&gt;
&lt;p&gt;目前该应用的功能还很简单，就是你给出一段台词，让用户猜这段台词是哪部电影的。更多的后续功能正在悄悄开发中，欢迎使用和反馈 :)&lt;/p&gt;
&lt;p&gt;应用地址：&lt;a href="http://iguess.leezhong.com"&gt;iguess.leezhong.com&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;del&gt;PS: Mobile Friendly&lt;/del&gt;&lt;/p&gt;
&lt;h3&gt;11/05/14&lt;/h3&gt;
&lt;p&gt;绑定新域名：&lt;a href="http://www.iguess.me"&gt;www.iguess.me&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;11/05/17&lt;/h3&gt;
&lt;p&gt;开源: &lt;a href="https://github.com/lzyy/iguess"&gt;https://github.com/lzyy/iguess&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;11/05/29&lt;/h3&gt;
&lt;p&gt;用PHP重写了整个应用，放在自己的VPS上&lt;/p&gt;
&lt;h3&gt;11/05/30&lt;/h3&gt;
&lt;p&gt;添加了一组默认头像&lt;/p&gt;
&lt;h3&gt;11/06/04&lt;/h3&gt;
&lt;p&gt;添加了独立URL页面&lt;br /&gt;
添加了评论功能&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>漫谈互联网产品开发</title>
   <link href="http://blog.leezhong.com/tech/2011/05/08/web-product-develop.html" />
   <updated>2011-05-08T00:00:00-07:00</updated>
   <id>http://blog.leezhong.com/tech/2011/05/08/web-product-develop</id>
   <content type="html">&lt;p&gt;每个公司都有自己的产品开发规范，我自己也大概想了下，比较适合小团队。&lt;/p&gt;
&lt;p&gt;借鉴Unix的设计哲学：一个工具只做好一件事，并提供接口。放到产品开发就是：产品可以被划分成多个模块，每个模块都有相应的API。这样就能做到分工明确和解耦。&lt;/p&gt;
&lt;h3&gt;三层架构&lt;/h3&gt;
&lt;h4&gt;表现层&lt;/h4&gt;
&lt;p&gt;web / mobile / app &amp;#8230;&lt;/p&gt;
&lt;h4&gt;API层&lt;/h4&gt;
&lt;p&gt;user / article / comment / &amp;#8230;&lt;/p&gt;
&lt;h4&gt;基础服务层&lt;/h4&gt;
&lt;p&gt;db / queue / memcache / &amp;#8230;&lt;/p&gt;
&lt;p&gt;如果使用GAE的话，就不用花心思去构建基础服务层了。这样就只剩下表现层和API层。&lt;/p&gt;
&lt;h3&gt;分工&lt;/h3&gt;
&lt;p&gt;每个人都要负责产品的一部分，有两种构建方式：水平构建和垂直构建&lt;/p&gt;
&lt;h4&gt;垂直构建&lt;/h4&gt;
&lt;p&gt;假如我负责用户系统，则所有与用户相关的事情都由我来完成，从前端到后端，包括API，页面展示，互动等等。这样做的话，对开发人员的要求比较高，需要同时对前后台都比较熟悉。但能减少沟通成本，提高开发效率。假如用户系统出现了一个bug，我就能很快地修复，因为我最熟悉，且所有与用户相关的都由我负责。&lt;/p&gt;
&lt;h4&gt;水平构建&lt;/h4&gt;
&lt;p&gt;这也是大部分公司采用的方法，把开发人员分为前端/后端等等。前端的任务就是负责页面的展示和交互，后端开发人员负责API的构建，可能还会有专门的DBA。这样做的好处是可以发挥每个人的特长。但也有不少问题，比如用户系统出现了一个bug，前端相信自己的程序没有问题，就会把问题推给后端，后端查看了一遍也觉得没问题，可能又会把问题推回去。这样一来二去，不仅浪费时间，影响效率，还会破坏团队的氛围。&lt;/p&gt;
&lt;p&gt;假如又有了一项新任务，是开发一个评论系统，前端可能1天就把页面做完了，然后就干别的事去了，结果后端花了4天才把API搞定。然后前端又要从别的地方把心收回来，阅读API文档，再整合，又耽搁了不少时间。这就有点不够敏捷了。&lt;/p&gt;
&lt;h3&gt;项目管理&lt;/h3&gt;
&lt;p&gt;我推荐使用Basecamp+Campfire+github。Basecamp用来管理项目；Campfire是团队讨论的地方(已与Basecamp集成)，可以开设多个版块；github用来管理源码。&lt;/p&gt;
&lt;p&gt;一个高效的开发者最不能接受的就是被打断，我好不容易进入了状态，结果被迫去跟你讨论一个不太重要的问题，这简直是谋杀，所以开发项目时最好把IM关掉，或者设置成离开状态。&lt;/p&gt;
&lt;p&gt;dropbox可以作为辅助工具，用来在团队内部共享资料。&lt;/p&gt;
&lt;p&gt;github的开发流程，可以参考&lt;a href="http://blog.leezhong.com/translate/2010/10/30/a-successful-git-branch.html"&gt;此文&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Tips&lt;/h3&gt;
&lt;ul&gt;
	&lt;li&gt;frontController要尽可能的薄，通常只需负责渲染页面&lt;/li&gt;
	&lt;li&gt;使用&lt;a href="http://techportal.ibuildings.com/2010/02/22/scaling-web-applications-with-hmvc/"&gt;hmvc&lt;/a&gt;将各个页面模块组合成一个页面&lt;/li&gt;
	&lt;li&gt;可以使用内部REST的方式来合并多个REST请求&lt;/li&gt;
	&lt;li&gt;API层可以模拟http的403状态码来减少数据传输&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;暂时就想到这些了，实际情况肯定要复杂地多。有哪些地方可以改进，或者根本就不现实，欢迎指出 :)&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>iframe无刷新跨域上传文件并获取返回值</title>
   <link href="http://blog.leezhong.com/tech/2011/05/06/crossdomain-upload.html" />
   <updated>2011-05-06T00:00:00-07:00</updated>
   <id>http://blog.leezhong.com/tech/2011/05/06/crossdomain-upload</id>
   <content type="html">&lt;p&gt;通常我们会有一个统一的上传接口，这个接口会被其他的服务调用。如果出现不同域，还需要无刷新上传文件，并且获取返回值，这就有点麻烦了。比如，新浪微博启用了新域名www.weibo.com，但接口还是使用原来的域：picupload.t.sina.com.cn。&lt;/p&gt;
&lt;p&gt;研究了一下新浪微博的处理方法，这里大概演示一下。&lt;/p&gt;
&lt;p&gt;首先是一个正常的上传页面 upload.html&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="html"&gt;&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
	&lt;span class="c1"&gt;// 这个函数将来会被iframe用到&lt;/span&gt;
	&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;getIframeVal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
	&lt;span class="p"&gt;{&lt;/span&gt;
		&lt;span class="nx"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
	&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;&amp;lt;!-- 我把upload.com指向了127.0.0.1 --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;form&lt;/span&gt; &lt;span class="na"&gt;method=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;post&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;target=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;if&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;enctype=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;multipart/form-data&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;action=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;http://upload.com/playground/js/deal.php?cb=http://localhost/playground/js/deal_cd.html&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
	&lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;file&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;file&amp;quot;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
	&lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;SUBMIT&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;upload&amp;quot;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;IFRAME&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;if&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;if&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;about:blank&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;frameborder=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;0&amp;#39;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/IFRAME&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;这里有一个关键点是form的target要指向iframe，同时把iframe隐藏起来，这样上传的处理结果就会显示在该iframe里。action里的cb(callback)参数表示处理完成后要跳转的url，因为我们的目标是iframe，所以只会把跳转的页面输出到iframe，而不会让当前页面跳转。&lt;/p&gt;
&lt;p&gt;还有一点，callback url要和当前页面同域。跨域的iframe无法调用父页面的内容。&lt;/p&gt;
&lt;p&gt;再来看看deal.php，也就是form的action&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="php"&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class="c1"&gt;// deal upload file&lt;/span&gt;
&lt;span class="c1"&gt;// and get file id, you can pass other params either&lt;/span&gt;
&lt;span class="nb"&gt;header&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;location:&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;$_GET&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;cb&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;?file_id=123&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;这里可以处理文件，然后入库。操作完成后，把文件的id及其他信息都放在url里，最后跳转到这个url。&lt;/p&gt;
&lt;p&gt;最后来看看deal_cd.html，也就是刚刚deal.php跳转到的url，这个文件的内容会填充到页面的iframe里。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="html"&gt;&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
	&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;rs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;search&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;?&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
	&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getIframeVal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;=&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;这里调用了父窗口的getIframeVal方法，这样父页面就获得了文件的id。&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>API的返回值形式</title>
   <link href="http://blog.leezhong.com/tech/2011/05/04/api-return-format.html" />
   <updated>2011-05-04T00:00:00-07:00</updated>
   <id>http://blog.leezhong.com/tech/2011/05/04/api-return-format</id>
   <content type="html">&lt;p&gt;假设我们有一个rest服务，该rest服务会返回json格式的信息，以twitter为例：访问`http://api.twitter.com/1/users/show.json?user_id=12345`会得到如下结果：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="javascript"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
	&lt;span class="nx"&gt;id_str&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;12345&amp;quot;&lt;/span&gt;
	&lt;span class="nx"&gt;is_translator&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
	&lt;span class="nx"&gt;following&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;
	&lt;span class="nx"&gt;profile_text_color&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;333333&amp;quot;&lt;/span&gt;
	&lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;ID 12345&amp;quot;&lt;/span&gt;
	&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
		&lt;span class="nx"&gt;coordinates&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;
		&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nx"&gt;Follow&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="nx"&gt;ha&lt;/span&gt;
	&lt;span class="p"&gt;}&lt;/span&gt;
	&lt;span class="c1"&gt;//...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;这是一个正常用户的信息，如果访问一个不存在用户，会返回类似下面的结果&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="javascript"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
	&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;/1/users/show.json?user_id=12345111&amp;quot;&lt;/span&gt;
	&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Not found&amp;quot;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;有没有发现，两次请求只是userid不一样，但返回形式却截然不同，这其实也不是什么大问题，客户端只要先检查一下是否有error这个key，就能知道这次请求是否出错。不过我想了个另一个方法，能让返回形式有相同的结构。&lt;/p&gt;
&lt;p&gt;借鉴了一下http协议，把返回结果分为header和body两部分，一个正常的请求会返回如下的信息&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="javascript"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
	&lt;span class="s1"&gt;&amp;#39;status&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;ok&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
	&lt;span class="s1"&gt;&amp;#39;content&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; 
	&lt;span class="p"&gt;{&lt;/span&gt;
		&lt;span class="s1"&gt;&amp;#39;blah&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;blah&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
		&lt;span class="c1"&gt;//...&lt;/span&gt;
	&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;status相当于http的status头信息，通过检查该信息可以知道请求是否正常，如果是&amp;#8217;ok&amp;#8217;则为正常，如为&amp;#8217;error&amp;#8217;则不正常，如果返回出错，则会在content字段里包含足够的错误信息&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="javascript"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
	&lt;span class="s1"&gt;&amp;#39;status&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;error&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
	&lt;span class="s1"&gt;&amp;#39;content&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; 
	&lt;span class="p"&gt;{&lt;/span&gt;
		&lt;span class="s1"&gt;&amp;#39;request&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;http://...&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
		&lt;span class="s1"&gt;&amp;#39;code&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;404&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
		&lt;span class="s1"&gt;&amp;#39;message&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;file not found&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
	&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;这里只包含了最基本的3项信息，request指代的是本次请求的url，code类似http状态码，message指代出错信息。&lt;/p&gt;
&lt;p&gt;这样是不是更优雅些？&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>关于选择</title>
   <link href="http://blog.leezhong.com/essay/2011/04/10/about-choice.html" />
   <updated>2011-04-10T00:00:00-07:00</updated>
   <id>http://blog.leezhong.com/essay/2011/04/10/about-choice</id>
   <content type="html">&lt;p&gt;选择少的时候，痛苦，因为这说明你还不够强大。选择多的时候也痛苦，因为你要仔细考量每一个选择带来的成本。所以我们苦恼，我们总是想找到一个最好的选择，为了这个最好的选择，我们可以在候选者之间徘徊很长时间，但每每一想到这些选择，都会重复着上一次的过程，只是依然没有结果。&lt;/p&gt;
&lt;p&gt;想起了一个故事，大意是一只驴很渴，这时它遇到了两桶水，但最后它还是渴死了，因为它不知道到底该先喝哪桶水。&lt;/p&gt;
&lt;p&gt;选择确实重要，但没那么重要，你的人生不可能因为一次选择而彻底改变。做选择时最重要的是知道自己想要的是什么，再做决定就容易了，如果还是很纠结，那就随便选一个。也可以扔一枚硬币，两个面分别对应两个选择，但不是看它最后显示的是哪个面，而是在抛起的过程中，你最希望它是哪个面。follow your heart&lt;/p&gt;
&lt;p&gt;&lt;img src="/image/choice-coin.jpg" /&gt;&lt;/p&gt;
&lt;p&gt;小时候，我们不怕做选择，因为没什么太大的后果，顶多就是被老师训一顿，被父母打打屁股，说两句。但随着年龄的增长，肩上的担子越来越重，压力也越来越大。你可能跟自己斗争了很久，做了个决定，但女友不同意，家里人反对，朋友劝说。有了孩子/房子/车子之后更麻烦。牵绊的事越多，越不利于做决定，于是我们妥协了，对生活说：生活你赢了，再见理想。&lt;/p&gt;
&lt;p&gt;可是我们的人生只有一次啊。&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>我理想中的公司</title>
   <link href="http://blog.leezhong.com/essay/2011/04/07/my-ideal-company.html" />
   <updated>2011-04-07T00:00:00-07:00</updated>
   <id>http://blog.leezhong.com/essay/2011/04/07/my-ideal-company</id>
   <content type="html">&lt;p&gt;我特别喜欢那种少而精的团队，大家齐心协力为了共同的目标而努力。人一多，心就容易散，这也增加了管理成本和沟通成本，而这两个因素往往是造成低效的重要原因。而且员工的质量很难得到控制，你不知道他们是来混日子的，还是冲着舒适来的，或是其他的目的，这就很难做到公平，除非每个入职员工都严格把关。不过这里也有个悖论，如果员工们个个都是精英，在公司规模不是很大的情况下，不会需要更多的外援；如果老是发现任务完成不了，或者效率低下，想通过扩招来弥补这些问题，那说明现在的员工很可能不够优秀。&lt;/p&gt;
&lt;p&gt;人一多，互相熟悉也会是问题。我的理念是，我要么跟你很熟，或愿意跟你很熟，要么一点不熟。如果路上看到一个同事，知道他叫什么名字，做什么的，然后点个头示意一下，这是多么冷淡的一种表现啊，我不喜欢这样。&lt;/p&gt;
&lt;p&gt;优秀的人才设计出来的产品，写出来的代码，是10个平庸的人加一起也无法超越的。但如团队中老是有那么一个或几个很嗝应的B类员工在掺和，而且上级对此些人还比较信任，这时事情就会向不好的方向开始发展了。因为A类人是很难或者无法与B类人共处的: 理念不一样，学习能力不一样，目标不一样。所以如果对新员工的质量降低了要求，必然会对A类员工带来不小的影响，所以要少招人，招对人。&lt;/p&gt;
&lt;p&gt;公司是员工的家，员工是公司的家人。虽然很多公司挂出了类似的口号，但也只是口号，这甚至比没有这个口号更糟：这个公司只会说说而已。公司首先要对员工表现出家的感觉：环境舒适，水果自便，iMac，福利，不用刷卡，等等。最重要一点，把员工当人看，这是很基本的一点，但很多公司就是做不到，他们把员工当成资源，不去或者很少考虑他们的需求，他们的反馈，他们的任务量。&lt;/p&gt;
&lt;p&gt;想想是谁决定了公司的未来，是员工啊。他们是人，他们需要被尊重，被认可，被关爱，而这些又能促使员工进一步去提升自己，去为公司创造更多的价值。这才是良性循环。领导们问都不问员工的意见，一拍板就把事情给定了，然后让他们什么时间之前完成，这不是扯淡嘛。&lt;/p&gt;
&lt;p&gt;作为一个技术人员，当然希望到一个技术主导的公司。这样的公司国内有，且数量也还不算太少。但有自己理念的，有家的感觉的，技术主导的公司，就太少了。豆瓣算一个，除此之外还真想不出第二个。如果真找不到合适的，就只能自己创建一个了。&lt;/p&gt;
&lt;p&gt;我比较喜欢yy, 这个场景在我的脑海里出现了好多次了：在大城市的周边，租一个大别墅，员工们如果租的房子离得比较远，或者交通不太方便，可以在那住着。选择大城市是因为大城市的人才相对较多，选择郊区是因为清静，空气好，风景好，房租便宜。别墅的前面是一片草坪，搞点什么活动都可以。&lt;/p&gt;
&lt;p&gt;&lt;img src="/image/the-whole-team.jpg" /&gt;&lt;/p&gt;
&lt;p&gt;公司内部的氛围一定要轻松，环境要舒适，工作区就算达不到每个人单独一间房间，至少空间要足够大，尽量少的干扰。可以配一块白板，但最好在一个独立的房间，以免打扰到其他人。&lt;/p&gt;
&lt;p&gt;&lt;img src="/image/team.jpg" width="640"/&gt;&lt;/p&gt;
&lt;p&gt;要有休闲区，如电影放映厅、游戏室、乒乓球、K歌厅等等，总之，就是要让员工感觉到公司为了员工的生活做了很多努力。那如果员工花很多的时间在休闲上怎么办？没有问题，只要你高质量地完成了自己的任务。&lt;/p&gt;
&lt;p&gt;&lt;img src="/image/game-room.jpg" /&gt;&lt;/p&gt;
&lt;p&gt;员工把生命中的一部分时间给了公司，公司当然要给予相应的回报。对于那些对公司做出很多贡献的更应该奖励，这些人不光是公司觉得他们付出了很多，员工也会觉得他们获此待遇是应该的，并会以他们为榜样。这样就建立起了良性循环。&lt;/p&gt;
&lt;p&gt;有点幼稚，有点过于理想，随着时间的流逝，阅历的增长，肯定会有部分变化，真希望在不远的将来多看到那样的公司，那里是理想主义者的天堂。&lt;/p&gt;</content>
 </entry>
 
 
</feed>

