<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>编码者说</title>
	<atom:link href="http://blog.webshuo.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.webshuo.com</link>
	<description>web开发者的博客</description>
	<lastBuildDate>Thu, 17 May 2012 10:34:01 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.4</generator>
		<item>
		<title>8年过去了，重读《软件开发的创新思维》</title>
		<link>http://blog.webshuo.com/2012/05/17/8%e5%b9%b4%e8%bf%87%e5%8e%bb%e4%ba%86%ef%bc%8c%e9%87%8d%e8%af%bb%e3%80%8a%e8%bd%af%e4%bb%b6%e5%bc%80%e5%8f%91%e7%9a%84%e5%88%9b%e6%96%b0%e6%80%9d%e7%bb%b4%e3%80%8b/</link>
		<comments>http://blog.webshuo.com/2012/05/17/8%e5%b9%b4%e8%bf%87%e5%8e%bb%e4%ba%86%ef%bc%8c%e9%87%8d%e8%af%bb%e3%80%8a%e8%bd%af%e4%bb%b6%e5%bc%80%e5%8f%91%e7%9a%84%e5%88%9b%e6%96%b0%e6%80%9d%e7%bb%b4%e3%80%8b/#comments</comments>
		<pubDate>Thu, 17 May 2012 10:34:01 +0000</pubDate>
		<dc:creator>dick</dc:creator>
				<category><![CDATA[工作心得]]></category>

		<guid isPermaLink="false">http://blog.webshuo.com/?p=885</guid>
		<description><![CDATA[03年第一次遇到这本书，惊为天人，8年后重读，依然觉得字字珠玑。 1 两类成功的人: 理解技术的商业人员 其成功依賴于所用信息的质量和复杂性 理解商业的技术人员 企业家型的工程师 2 在决定创造某个软件产品之前，经过简单而适当的设计，编写有很好交互性的产品 3 电脑可以告诉我们一个事实，但却不能提醒我们，它可以精确地引导我们， 却不能引导我们去我们想去的地方 4 软件产品有两类描述： 创建非常完整而详细的，实际产品的描述 描述最终用户看到产品时的描述 5 功能有负面因素，这些和正面因素一样，他们引起的最大设计问题是，每个出于善意的， 也许是不常用的功能，使常用功能模糊起来 6 写坏软件比写软件更昂贵（现在好多流氓软件。。。。） 7 让程序员长期写错误的东西，其代价比他们什么都不写还要高。 8 消费者的忠诚 我期望在百幕大有周六的假日，但我并不需要它，如果我有胆结石，我需要手术， 但它并不是我期望的，从短期看，一个人可以受到需求的强烈影响，但从长期来看， 一个人期望的东西有更大，更深刻的效果，当他期望某些东西时，他回忠诚于它， 当一个消费者期望一个产品或者一个品牌时，他的忠诚是商业中最强大的一股力量。 当你为客户提供了他们最期盼的产品时，你的竞争这实际上就快要失败了。 没有消费者长期品牌忠诚度，你的公司相对于竞争对手来说都是极其脆弱的。 9 高技术领域有三种根本的品质 实际能力 技术人员必须回答的问题，我们能干什么，哪些东西有可能干成 生存能力 商业人员的贡献 什么是能养活我们的东西，我们能卖什么 期望能力 设计人员提供的能力 ，他们必须回答 什么是令人期望的东西？ 人们究竟想要什么。 什么是可能的（技术），什么是存活的（商业），什么是期望的（设计）。 设计成功的产品：产品生产出来性能良好 进入销售领域卖得很火 ，带来利润 成为人们真正需要的东西 首先决定什么是客户期望的东西，然后工程师去建造它，商业人员去销售它，这是最明智的方法 10 为快乐而设计 假如你要设计一种款式的汽车来满足三种人的需要：带孩子的妈妈，木匠，年轻的总裁。能设计出来吗？？ 能，有人要吗？？没有！没有，因为这一定是一辆愚笨的汽车。唯一的办法是为妈妈造一辆带后门的小客车 ，为木匠造一辆皮卡，为年轻的总裁设计一辆跑车。 这就是角色设计，软件开发怎么为角色设计呢？？ [...]]]></description>
			<content:encoded><![CDATA[<p>03年第一次遇到这本书，惊为天人，8年后重读，依然觉得字字珠玑。</p>
<p>1  两类成功的人:<br />
    理解技术的商业人员 其成功依賴于所用信息的质量和复杂性<br />
    理解商业的技术人员 企业家型的工程师<br />
2  在决定创造某个软件产品之前，经过简单而适当的设计，编写有很好交互性的产品<br />
3  电脑可以告诉我们一个事实，但却不能提醒我们，它可以精确地引导我们，<br />
    却不能引导我们去我们想去的地方<br />
4  软件产品有两类描述：<br />
    创建非常完整而详细的，实际产品的描述<br />
    描述最终用户看到产品时的描述<br />
5  功能有负面因素，这些和正面因素一样，他们引起的最大设计问题是，每个出于善意的，<br />
     也许是不常用的功能，使常用功能模糊起来<br />
6  写坏软件比写软件更昂贵（现在好多流氓软件。。。。）<br />
7  让程序员长期写错误的东西，其代价比他们什么都不写还要高。</p>
<p>8  消费者的忠诚<br />
   我期望在百幕大有周六的假日，但我并不需要它，如果我有胆结石，我需要手术，<br />
但它并不是我期望的，从短期看，一个人可以受到需求的强烈影响，但从长期来看，<br />
一个人期望的东西有更大，更深刻的效果，当他期望某些东西时，他回忠诚于它，<br />
当一个消费者期望一个产品或者一个品牌时，他的忠诚是商业中最强大的一股力量。<br />
当你为客户提供了他们最期盼的产品时，你的竞争这实际上就快要失败了。<br />
没有消费者长期品牌忠诚度，你的公司相对于竞争对手来说都是极其脆弱的。</p>
<p>9  高技术领域有三种根本的品质</p>
<p> 实际能力 技术人员必须回答的问题，我们能干什么，哪些东西有可能干成<br />
 生存能力 商业人员的贡献 什么是能养活我们的东西，我们能卖什么<br />
 期望能力 设计人员提供的能力 ，他们必须回答 什么是令人期望的东西？<br />
             人们究竟想要什么。</p>
<p> 什么是可能的（技术），什么是存活的（商业），什么是期望的（设计）。</p>
<p> 设计成功的产品：产品生产出来性能良好<br />
                 进入销售领域卖得很火 ，带来利润<br />
                 成为人们真正需要的东西<br />
 首先决定什么是客户期望的东西，然后工程师去建造它，商业人员去销售它，这是最明智的方法</p>
<p>10  为快乐而设计<br />
假如你要设计一种款式的汽车来满足三种人的需要：带孩子的妈妈，木匠，年轻的总裁。能设计出来吗？？<br />
能，有人要吗？？没有！没有，因为这一定是一辆愚笨的汽车。唯一的办法是为妈妈造一辆带后门的小客车<br />
，为木匠造一辆皮卡，为年轻的总裁设计一辆跑车。<br />
这就是角色设计，软件开发怎么为角色设计呢？？<br />
精确描述我们的用户以及用户希望达到的目标<br />
目标的范围越大，迷失方向的可能性就越大<br />
缩小目标，提高目标人群内的满意度。<br />
被愉悦的用户是极其宝贵的财产。<br />
对产品满意度搞的用户是极其宝贵的财产。<br />
给角色取名字是成功定义角色的重要组成部分<br />
一个完整定义的用户角色是交互设计中非常有效的工具<br />
过分简单的市场模型无助于解决问题<br />
根据用户的工作性质和责任，用户的特点去建立角色<br />
如果你打算设计基于软件，使用户满意的产品，你必须相对精确地了解那些用户是谁，这就是角色扮演的人物，下一步是尽可能设计功能强大的产品，为此，你必须更多了解用户。</p>
<p>11  为效能而设计（面向目标的设计）<br />
 认清目标导向和电脑软件设计的人性化设计。<br />
 研究表明：人对电脑的反应与人对其他人的反应是一样的。<br />
 角色决定着需要达到的目标，而目标则反映出角色的意义。<br />
 目标是我们完成任务的缘由。<br />
 好的交互设计的实质是进行交互作用的设计，这种交互使得用户能达到他们的实际目标，而并与他们的个人 目标不冲突。<br />
 任务不是目标 ，<br />
 任务将随技术的变化而变化，但目标却具有相当稳定的。令人愉快的性质 ，比如你从公司到家，可以打车，也可以坐公交，<br />
 任务是打车或者公交，目标是回家。<br />
 目标是稳定的事物，任务是瞬变的现象，这就是为什么针对任务的设计不总能适合目标，而针对目标的设计总能适应任务的道理。<br />
 从事任务导向设计的程序员<br />
 用任务代替目标来进行设计是造成无效交互与挫败的主要原因之一。</p>
<p>目标导向的设计<br />
    个人目标：  不感到被愚弄<br />
                          不制造错误<br />
                           做适量的工作<br />
                           令人着迷(或者至少不要太令人讨厌)<br />
                            两个方面(个人工作量的减少，还有就是个人权益是否受到损害)<br />
     公司目标：  提高我们的利润<br />
                           扩大我们的市场分额<br />
                          击败我们的竞争对手<br />
                           雇用更多的人<br />
                          提供更多的产品或者服务<br />
                          公司目标与个人目标的平衡<br />
     实际目标： 避免会议<br />
                           处理客户的需求<br />
                           记录客户的订单<br />
                           建立可以量化的工作模型<br />
     虚假目标 这些都只是实现目标的手段，本身并不是目的的，目标才是最终的目的<br />
                       省钱<br />
                       减少键击<br />
                       运行于IE<br />
                      易学<br />
                      保护数据完整<br />
                       加快数据录入<br />
                       提高程序的执行效率<br />
                       使用最佳的技术和功能<br />
                       增加图形的美观<br />
                       维护跨平台的一致性</p>
<p>12  为人而设计<br />
  模块是对使用软件产品的角色为达到某个目标而进行的简洁的描述<br />
  日常使用型模块<br />
  最有用和最重要的，这里的基本动作都是用户要完成的，而且是最频繁完成的动作</p>
<p>  日常使用的模块需要最强的交互支持，新用户必须能很快掌握它，用户大量使用，<br />
  用户变得很有经验，他们将要求定制日常使用的交互，这样它将更合乎个人的工作作风。<br />
  必需使用型<br />
  必须完成的动作，但却不是频繁完成的动作，比如清理数据库和请求例外操作</p>
<p>  任何用户都情愿使用程序提供的方式去工作，不要求定制化，交互要求很低。<br />
  边缘情况的摸组<br />
  在产品设计阶段经常简要设计，但程序不能省去这些工作。<br />
  边缘情况的处理能力的编码是成功或者失败，关系到日常使用和必需使用的产品的成功或者失败。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.webshuo.com/2012/05/17/8%e5%b9%b4%e8%bf%87%e5%8e%bb%e4%ba%86%ef%bc%8c%e9%87%8d%e8%af%bb%e3%80%8a%e8%bd%af%e4%bb%b6%e5%bc%80%e5%8f%91%e7%9a%84%e5%88%9b%e6%96%b0%e6%80%9d%e7%bb%b4%e3%80%8b/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>用Twitter的cursor方式进行Web数据分页</title>
		<link>http://blog.webshuo.com/2012/03/21/%e7%94%a8twitter%e7%9a%84cursor%e6%96%b9%e5%bc%8f%e8%bf%9b%e8%a1%8cweb%e6%95%b0%e6%8d%ae%e5%88%86%e9%a1%b5/</link>
		<comments>http://blog.webshuo.com/2012/03/21/%e7%94%a8twitter%e7%9a%84cursor%e6%96%b9%e5%bc%8f%e8%bf%9b%e8%a1%8cweb%e6%95%b0%e6%8d%ae%e5%88%86%e9%a1%b5/#comments</comments>
		<pubDate>Wed, 21 Mar 2012 02:56:02 +0000</pubDate>
		<dc:creator>hunk</dc:creator>
				<category><![CDATA[转载]]></category>
		<category><![CDATA[数据分页 mysql中limit替代方式]]></category>

		<guid isPermaLink="false">http://blog.webshuo.com/?p=879</guid>
		<description><![CDATA[本文讨论Web应用中实现数据分页功能，不同的技术实现方式的性能方区别。 上图功能的技术实现方法拿MySQL来举例就是 select * from msgs where thread_id = ? limit page * count, count 不过在看Twitter API的时候，我们却发现不少接口使用cursor的方法，而不用page, count这样直观的形式，如 followers ids 接口 URL: http://twitter.com/followers/ids.format Returns an array of numeric IDs for every user following the specified user. Parameters: * cursor. Required. Breaks the results into pages. Provide a value of -1 to begin paging. Provide values [...]]]></description>
			<content:encoded><![CDATA[<h2>本文讨论Web应用中实现数据分页功能，不同的技术实现方式的性能方区别。</h2>
<div>
<p><a href="http://timyang.net/blog/wp-content/uploads/2010/01/pagination.png"><img src="http://timyang.net/blog/wp-content/uploads/2010/01/pagination.png" alt="" width="376" height="148" /></a><br />
上图功能的技术实现方法拿MySQL来举例就是</p>
<pre>select * from msgs where thread_id = ? limit page * count, count</pre>
<p>不过在看Twitter API的时候，我们却发现不少接口使用cursor的方法，而不用page, count这样直观的形式，如 followers ids 接口</p>
<blockquote><p><strong>URL:</strong></p>
<p>http://twitter.com/followers/ids.format</p>
<p>Returns an array of numeric IDs for every user following the specified user.</p>
<p><strong>Parameters:</strong><br />
* cursor. Required. Breaks the results into pages. Provide a value of -1 to begin paging. Provide values as returned to in the response body’s next_cursor and previous_cursor attributes to page back and forth in the list.<br />
o Example: http://twitter.com/followers/ids/barackobama.xml?cursor=-1<br />
o Example: http://twitter.com/followers/ids/barackobama.xml?cursor=-1300794057949944903</p></blockquote>
<div>http://twitter.com/followers/ids.<em>format</em></div>
<p>从上面描述可以看到，http://twitter.com/followers/ids.xml 这个调用需要传cursor参数来进行分页，而不是传统的 url?page=n&amp;count=n的形式。这样做有什么优点呢？是否让每个cursor保持一个当时数据集的镜像？防止由于结果集实时改变而产生查询结果有重复内容？<br />
在Google Groups这篇<a href="http://groups.google.com/group/twitter-development-talk/browse_thread/thread/712b4765028d527c/3f444faee8f8d7ef">Cursor Expiration</a>讨论中Twitter的架构师<a href="http://twitter.com/jkalucki">John Kalucki</a>提到</p>
<blockquote><p>A cursor is an opaque deletion-tolerant index into a Btree keyed by source<br />
userid and modification time. It brings you to a point in time in the<br />
reverse chron sorted list. So, since you can’t change the past, other than<br />
erasing it, it’s effectively stable. (Modifications bubble to the top.) But<br />
you have to deal with additions at the list head and also block shrinkage<br />
due to deletions, so your blocks begin to overlap quite a bit as the data<br />
ages. (If you cache cursors and read much later, you’ll see the first few<br />
rows of cursor[n+1]’s block as duplicates of the last rows of cursor[n]’s<br />
block. The intersection cardinality is equal to the number of deletions in<br />
cursor[n]’s block). Still, there may be value in caching these cursors and<br />
then heuristically rebalancing them when the overlap proportion crosses some<br />
threshold.</p></blockquote>
<p>在另外一篇<a href="http://groups.google.com/group/twitter-development-talk/browse_thread/thread/cfccfa4302ff9729/66d6b91f9a6bf96d">new cursor-based pagination not multithread-friendly</a>中John又提到</p>
<blockquote><p>The page based approach does not scale with large sets. We can no<br />
longer support this kind of API without throwing a painful number of<br />
503s.</p>
<p>Working with row-counts forces the data store to recount rows in an O<br />
(n^2) manner. Cursors avoid this issue by allowing practically<br />
constant time access to the next block. The cost becomes O(n/<br />
block_size) which, yes, is O(n), but a graceful one given n &lt; 10^7 and<br />
a block_size of 5000. The cursor approach provides a more complete and<br />
consistent result set.</p>
<p>Proportionally, very few users require multiple page fetches with a<br />
page size of 5,000.</p>
<p>Also, scraping the social graph repeatedly at high speed is could<br />
often be considered a low-value, borderline abusive use of the social<br />
graph API.</p></blockquote>
<p>通过这两段文字我们已经很清楚了，对于大结果集的数据，使用cursor方式的目的主要是为了极大地提高性能。还是拿MySQL为例说明，比如翻页到100,000条时，不用cursor，对应的SQL为</p>
<pre>select * from msgs limit 100000, 100</pre>
<p>在一个百万记录的表上，第一次执行这条SQL需要5秒以上。<br />
假定我们使用表的主键的值作为cursor_id, 使用cursor分页方式对应的SQL可以优化为</p>
<pre>select * from msgs where id &gt; cursor_id limit 100;</pre>
<p>同样的表中，通常只需要100ms以下, 效率会提高几十倍。MySQL limit性能差别也可参看我3年前写的一篇不成熟的文章 <a href="http://hi.baidu.com/jabber/blog/item/67485b43379290119313c6b5.html">MySQL LIMIT 的性能问题</a>。</p>
<h3>结论</h3>
<p>建议Web应用中<strong>大数据集翻页可以采用这种cursor方式</strong>，不过此方法缺点是翻页时必须连续，不能跳页。</p>
</div>
<p>http://twitter.com/followers/ids.<em>format</em></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.webshuo.com/2012/03/21/%e7%94%a8twitter%e7%9a%84cursor%e6%96%b9%e5%bc%8f%e8%bf%9b%e8%a1%8cweb%e6%95%b0%e6%8d%ae%e5%88%86%e9%a1%b5/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>preg_match长字符串匹配失败问题解决</title>
		<link>http://blog.webshuo.com/2012/02/10/preg_match%e5%ad%97%e7%ac%a6%e4%b8%b2%e5%8c%b9%e9%85%8d%e5%a4%b1%e8%b4%a5%e9%97%ae%e9%a2%98%e8%a7%a3%e5%86%b3/</link>
		<comments>http://blog.webshuo.com/2012/02/10/preg_match%e5%ad%97%e7%ac%a6%e4%b8%b2%e5%8c%b9%e9%85%8d%e5%a4%b1%e8%b4%a5%e9%97%ae%e9%a2%98%e8%a7%a3%e5%86%b3/#comments</comments>
		<pubDate>Fri, 10 Feb 2012 09:08:19 +0000</pubDate>
		<dc:creator>jessica</dc:creator>
				<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://blog.webshuo.com/?p=858</guid>
		<description><![CDATA[今天在查一个问题，用正则从字符串中提取内容失败，反复检查字符串和正则表达式，都没有问题。又写了小脚本测试，还没有问题，回到代码中调试，又失败了。 字符串比较长，因此怀疑是不是preg_match也有字符串长度限制，果然！ preg_match、preg_match_all都会有这种情况。 解决方法： 1、ini_set(&#8216;pcre.backtrack_limit&#8217;, 1000000); //默认的只有100000 2、修改 php.ini 的pcre.backtrack_limit参数，使之支持更大的字符串。加入配置：pcre.backtrack_limit=-1 参考来源：http://blog.csdn.net/qvbfndcwy/article/details/6946855]]></description>
			<content:encoded><![CDATA[<p>今天在查一个问题，用正则从字符串中提取内容失败，反复检查字符串和正则表达式，都没有问题。又写了小脚本测试，还没有问题，回到代码中调试，又失败了。<br />
字符串比较长，因此怀疑是不是preg_match也有字符串长度限制，果然！<br />
preg_match、preg_match_all都会有这种情况。</p>
<p>解决方法：<br />
1、ini_set(&#8216;pcre.backtrack_limit&#8217;, 1000000); //默认的只有100000<br />
2、修改 php.ini 的pcre.backtrack_limit参数，使之支持更大的字符串。加入配置：pcre.backtrack_limit=-1</p>
<p>参考来源：http://blog.csdn.net/qvbfndcwy/article/details/6946855</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.webshuo.com/2012/02/10/preg_match%e5%ad%97%e7%ac%a6%e4%b8%b2%e5%8c%b9%e9%85%8d%e5%a4%b1%e8%b4%a5%e9%97%ae%e9%a2%98%e8%a7%a3%e5%86%b3/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>[转]低效能人士的七个习惯</title>
		<link>http://blog.webshuo.com/2012/02/01/%e8%bd%ac%e4%bd%8e%e6%95%88%e8%83%bd%e4%ba%ba%e5%a3%ab%e7%9a%84%e4%b8%83%e4%b8%aa%e4%b9%a0%e6%83%af/</link>
		<comments>http://blog.webshuo.com/2012/02/01/%e8%bd%ac%e4%bd%8e%e6%95%88%e8%83%bd%e4%ba%ba%e5%a3%ab%e7%9a%84%e4%b8%83%e4%b8%aa%e4%b9%a0%e6%83%af/#comments</comments>
		<pubDate>Wed, 01 Feb 2012 01:44:43 +0000</pubDate>
		<dc:creator>jessica</dc:creator>
				<category><![CDATA[转载]]></category>

		<guid isPermaLink="false">http://blog.webshuo.com/?p=854</guid>
		<description><![CDATA[新年伊始，发篇好文大家共勉。 转自：http://book.douban.com/review/1961949/ 原文： 　Stephen Covey 在他的经久不衰的畅销书中阐述的了“高效能人士的七个习惯 ”,如果对本书熟悉这部分可以略过：　 　　 　　Habit 1 &#8211; Be Proactive 积极主动（主动选择） 　　 　　Habit 2 &#8211; Begin with the end in mind 以终为始（开始前想象结束）　　 　　 　　Habit 3 &#8211; Put first things first 要事第一 　　 　　 　　Habit 4 &#8211; Think win-win 双赢思维 　　 　　 　　Habit 5 &#8211; Seek first to understand and then to be [...]]]></description>
			<content:encoded><![CDATA[<p>新年伊始，发篇好文大家共勉。</p>
<p>转自：http://book.douban.com/review/1961949/<br />
原文：</p>
<p>　Stephen Covey 在他的经久不衰的畅销书中阐述的了“高效能人士的七个习惯 ”,如果对本书熟悉这部分可以略过：　<br />
　　<br />
　　Habit 1 &#8211; Be Proactive 积极主动（主动选择）<br />
　　<br />
　　Habit 2 &#8211; Begin with the end in mind 以终为始（开始前想象结束）　　<br />
　　<br />
　　Habit 3 &#8211; Put first things first 要事第一 　　<br />
　　<br />
　　Habit 4 &#8211; Think win-win 双赢思维 　　<br />
　　<br />
　　Habit 5 &#8211; Seek first to understand and then to be understood 知彼解己（首先理解别人，再寻求被别人理解）　<br />
　　<br />
　　Habit 6 &#8211; Synergize 统合综效 　　<br />
　　<br />
　　Habit 7 &#8211; Sharpen the saw 不断更新<br />
　　<br />
　　&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />
 　　<br />
　　这些大多来源于心理学的思想也早已被上亿人讨论学习证实挑战。<br />
　　<br />
　　今早从Steve Pavlina的twitter中看到他写下了 “低效能人士的七个习惯”（7 Habits of Highly Ineffective People ），与《 高效能人士的七个习惯 》对照起来看实在太有意思了。=）<br />
 　　<br />
　　Be reactive. Set no goals. Do whatever comes up. Think win-lose. Judge people. Compete. Burn out.<br />
 　　<br />
　<strong>　Bad Habit 1 &#8211; Be Reactive 消极被动</strong><br />
　　<br />
　　消极被动的人们在对外界进行反应时忘记了这一点：外界环境的刺激与我们的行为反应之间有一个可大可小的空间，我们在这个空间中填充的内容使一切变得不同。这就是艾利斯理性情绪疗法中著名的ABC理论（Activating events—Beliefs—emotional and behavioral Consequences） 。<br />
 　　<br />
　　Coldplay的《viva la vida》专辑中有一首歌《lost》，其中两句歌词写明白了刺激和反应之间是有选择的：<br />
　　<br />
　　Just because I&#8217;m losing, doesn&#8217;t mean I&#8217;m lost<br />
　　<br />
　　只因为我正在失去，并不意味着我已迷失自我（并不意味着我已失败了）。<br />
　　Just because I&#8217;m hurting, doesn&#8217;t mean I&#8217;m hurt<br />
　　<br />
　　只因为我正在伤痛着，并不意味着我已伤痕累累（并不意味着我已受到了伤害）。<br />
　　<br />
　　一切都在于我们选择的beliefs=)<br />
　　<br />
　　举一个例子：别人想激怒你时，你可以选择从一个高的视角客观地俯视那个人和你，思考一下他想这样做想达到什么目的，你的不同反应会对你和他以及论题或事件的进展产生什么效果等等。<br />
 　　<br />
　　或许谁都不希望完全被人控制，所以“别人想让你生气你就生气”也并不是不能避免的。别忘记了，刺激和反应之间的空间足够我们做出自己的判断和选择！<br />
　　<br />
　　当然现实生活中很多情况下我们会认为有很多没有选择的情况（重要的选择可能就更少了）；其实更准确点说是许多情况下或许没有更好的选择了，只有一个可能的选项（其他不好的选项可以轻而易举排除）。这种情况看似简单，但却很可能因为无法选择而引起很多情绪和态度的改变并产生焦虑。这时候“just do it！”就不仅仅是一句口号，或许也是一种明智的选择。<br />
 　　<br />
　　<br />
　　<br />
　<strong>　Bad Habit 2 &#8211; Set no goals 没有目标</strong><br />
　　<br />
　　这个很好理解，但很难解释清楚。<br />
　　<br />
　　因为“没有目标”的情境我们很容易遇到，“有目标”也不难做到，真正难做到的是以下的一些判断：什么时候该有目标什么时候不该有目标，怎样设定和区分对待大的目标小的目标不大不小的目标，各个目标之间分别要分配多少精力去追求，需要坚持多长时间来实现目标，是否需要近乎于倔强的坚持等等。这些判断需要我们有丰富的阅历。<br />
 　　<br />
　　很多人总说有目标不去行动也白搭，而且大多数人确实是有了目标不去行动的。那么有没有办法能让我们有了目标就去行动并且坚持下来呢？我认为就是上面的办法，认真思考你的目标，把上面的还有更多的选择题判断题都做完，在心里（最好是写下来）完成一份详尽的目标分析报告，真正在内心中接纳你的目标。当你为你的目标投入了这么多时间精力去研究思考讨论并且确认之后，你就不会想轻易放弃了。放弃成本大啊=）<br />
 　　<br />
　　如果只是说一句：“我要怎么怎么样！” 这种目标几乎一定不会达到的。你的内心就没有认可这个目标。<br />
　　<br />
　　如果上升到人生哲学的高度，像叔本华或尼采那样思考人生到底有没有意义有没有目标；或许会体会到陷入其中不能自拔的感觉。如果说“人生没有意义”，对你意味着什么呢？<br />
 　　<br />
　　个人觉得更好的办法不是局限于人生到底要不要有目标，而是试着“找一个合适的目标”，看看是否对你有帮助。我已经习惯了带着目标生活，这样会使我更幸福；虽然不时还是会去想那些终极问题。<br />
 　　<br />
　<strong>　Bad Habit 3 &#8211; Do whatever comes up 做无论什么发生的事（来什么做什么） </strong><br />
　　<br />
　　做事之前需要分清轻重缓急，但对于多数人来讲要走很多的弯路才能认清什么是重要的，什么是紧急的。在判断事情的轻重缓急时，思考是一个重要的途径，但思考的时间是一个不得不考虑的机会成本（有可能想来想去时机就错过了）。所以长时间锻炼出来融在自己血液里值得自己信赖的直觉有时候更加重要。（参见科比推荐过的Malcolm Gladwell《决战2秒间（blink）》一书）<br />
 　　<br />
　　就算我们分清楚了事情的四种类型（重要且紧急、重要但不紧急、不重要但紧急、不重要也不紧急），怎么样对不同的事分门别类进行时间管理还是一件令人头痛的事。<br />
　　<br />
　　对那些情感上不想做但理智上应该做的事（这些事往往是一些不想面对但必须总要面对的难题），我个人的处理方式是：自己设定一段可长可短的 supertime，在“超级时间”里保证自己不受任何别的因素影响专心做这些事；supertime结束时如果没做完，再设定若干时间以后下次的 supertime，如此交叉反复直到做完为止，但不勉强自己一定要完成。如果非要完成，往往会让自己精疲力尽，毕竟面对的很多可能是永远解决不了的难题，能完成就已经很棒了，为什么还要期待一次就能完成？在两个supertime之间，给自己点奖励吧。=）<br />
 　　<br />
　　<br />
　　<br />
　<strong>　Bad Habit 4 &#8211; Think win-lose 输赢思维 </strong><br />
　　<br />
　　输赢思维认为世界是个“零和游戏”，你有我就没有，你赢我就输，你多我就少。事实是这样么？社会的发展是靠大大小小的团体和个人的创造，而不是争夺或掠夺。与外界对抗，非要争个你输我赢我认为是最得不偿失的事情（没有之一）。因为在我们与外界对抗只能构筑我们坚强的盔甲，而同时失去了个人成长的机会。<br />
 　　<br />
　　其实我们唯一需要去“对抗”的就是我们自己。<br />
　　<br />
　　社会学认为，人是社会性动物，终其一生都在跟自己的基因做斗争。(参看《社会性动物》、《欲望之源 》，) 只是这样的斗争很多人几乎没有赢过，或者偶尔赢也不知道怎么赢的。<br />
 　　<br />
　　<br />
　　<br />
　<strong>　Bad Habit 5 &#8211; Judge people 评判别人 </strong><br />
　　<br />
　　<br />
　　<br />
　　在人与人之间冲突与合作时，要先去理解别人再去寻求理解；而是为自己的行为找借口，反而去评判别人的功过是非。 如果我们尝试过并且认识到理解别人其实是一件很困难的事，自己就也不会那么期待被别人理解了。而把自己的期待建立在别人身上，不总是靠谱的选择。<br />
 　　<br />
　　对大多数人来说，慕容复的“以彼之道，还施彼身”是既不可取又做不到的，但孔老夫子的“己所不欲，勿施于人”虽然容易理解却也相当难做到，所以只好“堕落”到通过评判别人去寻找少的可怜的优越感了。<br />
 　　<br />
　　圣经上说:&#8221;Do not judge, and you will not be judged; do not condemn, and you will not be condemned; give, and you will be given; forgive, and you will be forgiven.&#8221;<br />
 　　是一个意思。<br />
　　<br />
　　<br />
　　<br />
　　其实我个人觉得坏习惯六应该是（与习惯六Synergize 统合综效对比 ）：<br />
　　<br />
<strong>　　Bad Habit 6 &#8211; Separate 分割 </strong><br />
　　<br />
　　你是否会“只见树木不见森林”，只把经历的人和事看做是分离的个体，没有把生命中一个个点串联起来成一条属于你自己独特的蜿蜒优美的曲线（道路注定曲折，直线是不可能的）。<br />
 　　<br />
　　确实，很难说我们生命中所有的经历都是否“有用”，更难说这些经历这些学习得来的经验什么时候“有用”。但是，如果我们能够把生命看成不可分割的整体，总有一天会发现它们在应该的时刻发生过，这应该是一种美妙的体验，一种活在当下的体验。<br />
 　　<br />
　　Steve Jobs辍学前在学校时学了好久艺术字（英语的“书法”）。他是写程序卖电脑的，根本不知道学这么有什么用。但在许多年以后，在设计第一台mac时，那些优美的字体漂亮的界面成为了他打翻身仗的制胜法宝。如果没有这个经历，他奇幻的右脑就得不到锻炼，就不会有后来不断更新的设计理念，也就不会有ipod macbook iphone了。<br />
 　　<br />
　　在他著名的斯坦福毕业典礼演讲中也讲过要“connecting the dots（将生命中的点连接起来）”。<br />
　　<br />
　　<br />
　　<br />
<strong>　　Bad Habit 7 &#8211; Burn out （一次）燃尽</strong><br />
　　<br />
　　<br />
　　个人成长是一辈子的事，是马拉松而不是百米跑，时间长着呢，不用急着用完你的燃料。如果我们以百米跑的速度去跑马拉松，结果就提前把自己燃烧完了，燃料枯竭后就会止步不前。<br />
 　　<br />
　　正确的选择应该是不断的挑战自我，更新自我。不计较一城一地的得失，永远用初学者的心态去认真对待每一天，让每一刻在你的脑海中都是崭新的。既不期盼心想事成，失败了也不气馁。因为生命中的难题不是来打倒我们的，而是来帮助我们成长的。<br />
 　　<br />
　　尼采说：“那些杀不死我的，都会使我更强”。<br />
　　<br />
　　大家都不会否认这句话最佳的诠释人是星矢为首的五个小强，永远在Sharpen the saw， 永远在练习超强的抗击打能力，永远在面对敌人（困难）时先保存实力仔细研究对方的破绽直到看清楚敌人（困难），就算自己到了奄奄一息的时候，逐渐积累的小宇宙却已经在内心深处聚集起来，就等着雅典娜召唤呢。=）<br />
 　　<br />
　　我们的雅典娜是自己的内心。任何时候如果接收到了从自己内心发出的使命的召唤，都要像星矢小强们接收到雅典娜的召唤一样“燃烧吧小宇宙”！！</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.webshuo.com/2012/02/01/%e8%bd%ac%e4%bd%8e%e6%95%88%e8%83%bd%e4%ba%ba%e5%a3%ab%e7%9a%84%e4%b8%83%e4%b8%aa%e4%b9%a0%e6%83%af/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[转]Google的系统工程师(SA)如何工作</title>
		<link>http://blog.webshuo.com/2012/01/07/%e8%bd%acgoogle%e7%9a%84%e7%b3%bb%e7%bb%9f%e5%b7%a5%e7%a8%8b%e5%b8%88sa%e5%a6%82%e4%bd%95%e5%b7%a5%e4%bd%9c/</link>
		<comments>http://blog.webshuo.com/2012/01/07/%e8%bd%acgoogle%e7%9a%84%e7%b3%bb%e7%bb%9f%e5%b7%a5%e7%a8%8b%e5%b8%88sa%e5%a6%82%e4%bd%95%e5%b7%a5%e4%bd%9c/#comments</comments>
		<pubDate>Sat, 07 Jan 2012 09:48:17 +0000</pubDate>
		<dc:creator>jessica</dc:creator>
				<category><![CDATA[转载]]></category>

		<guid isPermaLink="false">http://blog.webshuo.com/?p=851</guid>
		<description><![CDATA[原文地址：http://user.qzone.qq.com/250332234/share/1291635502 本文根据系统管理领域知名博客 Thomas A. Limoncelli 的 What is system administration like at Google 整理而成，添加了部分笔者观点。 　　Google的系统工程师(System Administrator)如何工作 　　由于Google的服务已经集群化，系统工程师并不大量接触硬件比如做安装服务器等事情。另外大部分工作也已经自动化了，比如架设LDAP, 负载均衡等。对照而言，国内目前大部分互联网公司SA仍然要做大量重复的底层工作，比如拿一个业务的数据库过大需要拆分为例，从系统管理员的角度，需要做以下事情： 　　· 同技术人员沟通目前业务特点，制定拆分方案并评估程序风险； 　　· 搭建测试环境，技术人员测试程序兼容性； 　　· 制定实施方案，保证业务的不停机平稳过渡； 　　· 深夜上线； 　　· 观察1-2天运行情况。 　　我们需要思考上面工作是否是系统管理员以及技术人员有价值的工作。像Cassandra这样解决了分布式存储自动化扩展的问题是业内一种发展方向，尽管Cassandra的稳定性还需要改进。 　　Google的系统工程师怎么做？ 　　他们会通常1周值班，响应各种问题，比如完成上述场景中的扩容业务。然后有大约5周左右脱离一线工作来自由思考将这1周内碰到的工作进行自动化改进，将那些会反复碰到的问题通过脚本及监控程序完成，或者进一步反馈给技术人员改进应用程序来实现自动化。1:5只是个大约比例，时段可以灵活安排。比如也可以按天来安排，1天值班/7天改进。当改进完成之后，下次遇到相同的场景，自动化程序会完成大部分工作。如果在其他公司，SA通常忙碌在一线机械重复上述工作，但是在Google, 给系统工程师预留了相当多的时间让大家思考改进。 　　这就是Google的System Administrator自称SRE(Site Reliability Engineers)的原因。SRE会不断在优化所负责的系统，一些人关注运维层面，另外一些可能关注自动化工具。所有的SA都需要具备一定程序或脚本开发能力。 　　因此，当遇到Google的数据规模，自动化不是是否需要，而是如何更好实现的问题。 　　在Google其他一些令人兴奋的工作还包括： 与开发技术人员是协同的关系。 只需关心技术，在技术领域也有职业生涯上升通道，不必转向技术管理岗位或其他。 同事都非常聪明，通常会觉得自己是最逊的那一个。很多挑战，保守的估计领先行业2-10年，在这里工作就象给了你一个魔法水晶球，通过你的工作可以预见这个行业的未来。 　　受Google方式的启发，以下想到的一些可以研究的自动化方向： 　　1. 程序部署 　　C/C++/Java/PHP/Python/Ruby/C# 等语言如何不停机自动发布。 　　自动发布如何简洁的解决模块依赖性，比如1天需要同时更新10个有相互依赖的模块，并且不能停止服务。 　　Web容器虚拟化，同一Web容器上可以部署多个业务，业务之间互相隔离，互不影响。 　　将新开发的服务程序运维自动化。一般的服务程序从数量上来说，10是一个分水岭，10台以下的服务通过人工重复操作方式来管理也问题不大，但是10台以上就需要自动化管理的方法。很多优秀的开源程序(比如Tokyo Cabinet, Redis等)在单机上表现优秀，但是大规模部署不能。大公司中很多技术人员经常提到很多开源软件不适合他们就有这方面原因。 　　2. 资源部署 　　MySQL 　　分布式文件存储 [...]]]></description>
			<content:encoded><![CDATA[<table cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td valign="top">原文地址：<a href="http://user.qzone.qq.com/250332234/share/1291635502" target="_blank">http://user.qzone.qq.com/250332234/share/1291635502</a></p>
<p>本文根据系统管理领域知名博客 Thomas A. Limoncelli 的 What is system administration like at Google 整理而成，添加了部分笔者观点。</p>
<p>　　<strong>Google的系统工程师(System Administrator)如何工作</strong></p>
<p>　　由于Google的服务已经集群化，系统工程师并不大量接触硬件比如做安装服务器等事情。另外大部分工作也已经自动化了，比如架设LDAP, 负载均衡等。对照而言，国内目前大部分互联网公司SA仍然要做大量重复的底层工作，比如拿一个业务的数据库过大需要拆分为例，从系统管理员的角度，需要做以下事情：</p>
<p>　　· 同技术人员沟通目前业务特点，制定拆分方案并评估程序风险；</p>
<p>　　· 搭建测试环境，技术人员测试程序兼容性；</p>
<p>　　· 制定实施方案，保证业务的不停机平稳过渡；</p>
<p>　　· 深夜上线；</p>
<p>　　· 观察1-2天运行情况。</p>
<p>　　我们需要思考上面工作是否是系统管理员以及技术人员有价值的工作。像Cassandra这样解决了分布式存储自动化扩展的问题是业内一种发展方向，尽管Cassandra的稳定性还需要改进。</p>
<p>　　<strong>Google的系统工程师怎么做？</strong></p>
<p>　　他们会通常1周值班，响应各种问题，比如完成上述场景中的扩容业务。然后有<span style="color: #800000">大约5周左右脱离一线工作来自由思考将这1周内碰到的工作进行自动化改进，将那些会反复碰到的问题通过脚本及监控程序完成</span>，或者进一步反馈给技术人员改进应用程序来实现自动化。1:5只是个大约比例，时段可以灵活安排。比如也可以按天来安排，1天值班/7天改进。当改进完成之后，下次遇到相同的场景，自动化程序会完成大部分工作。如果在其他公司，SA通常忙碌在一线机械重复上述工作，但是在Google, 给系统工程师预留了相当多的时间让大家思考改进。</p>
<p>　　这就是Google的System Administrator自称SRE(Site Reliability Engineers)的原因。SRE会不断在优化所负责的系统，一些人关注运维层面，另外一些可能关注自动化工具。所有的SA都需要具备一定程序或脚本开发能力。</p>
<p>　　因此，当遇到Google的数据规模，自动化不是是否需要，而是如何更好实现的问题。</p>
<p>　　在Google其他一些令人兴奋的工作还包括：</p>
<ul>
<li>与开发技术人员是协同的关系。</li>
<li>只需关心技术，在技术领域也有职业生涯上升通道，不必转向技术管理岗位或其他。</li>
<li>同事都非常聪明，通常会觉得自己是最逊的那一个。很多挑战，保守的估计领先行业2-10年，在这里工作就象给了你一个魔法水晶球，通过你的工作可以预见这个行业的未来。</li>
</ul>
<p>　　受Google方式的启发，以下想到的一些可以研究的自动化方向：</p>
<p>　　<strong>1. 程序部署</strong></p>
<p>　　C/C++/Java/PHP/Python/Ruby/C# 等语言如何不停机自动发布。</p>
<p>　　自动发布如何简洁的解决模块依赖性，比如1天需要同时更新10个有相互依赖的模块，并且不能停止服务。</p>
<p>　　Web容器虚拟化，同一Web容器上可以部署多个业务，业务之间互相隔离，互不影响。</p>
<p>　　将新开发的服务程序运维自动化。一般的服务程序从数量上来说，10是一个分水岭，10台以下的服务通过人工重复操作方式来管理也问题不大，但是10台以上就需要自动化管理的方法。很多优秀的开源程序(比如Tokyo Cabinet, Redis等)在单机上表现优秀，但是大规模部署不能。大公司中很多技术人员经常提到很多开源软件不适合他们就有这方面原因。</p>
<p>　　<strong>2. 资源部署</strong><br />
　　MySQL<br />
　　分布式文件存储</p>
<p>　　Cache，拿cache自动化管理举例。</p>
<p>　　端口资源管理，不同业务使用不同端口，同一应用内不同的数据使用不同的端口，相关原因可以参看以前cache相关博文。</p>
<p>　　容量管理，不同的数据需要不同的容量。</p>
<p>　　动态扩容，应用业务规模增长，比如从10G扩容到100G。</p>
<p>　　Proxy功能，比如虚拟化端口映射，程序访问的是固定虚拟端口，这样不需要重启服务也可以随时扩充，应用也不需要一致性hash, proxy帮你做了。</p>
<p>　　<strong>3. 系统部署</strong></p>
<p>　　OS</p>
<p>　　反向代理与负载均衡。<br />
　　本地分区容量，批量管理。<br />
　　程序发布与停止，比如一个程序一个点击部署到100台服务器。<br />
　　虚拟化，比物理服务器更容易部署，资源利用率更高，部署更可控。</p>
<p>　　大部分国内互联网公司基础技术还是比较原始的，这跟行业过分强调“好产品是运营出来的”也有关系，基础研发通常不受重视，长此以往，只能在门槛低的领域打拼，与Google的技术差异就不止10年了。</td>
</tr>
</tbody>
</table>
]]></content:encoded>
			<wfw:commentRss>http://blog.webshuo.com/2012/01/07/%e8%bd%acgoogle%e7%9a%84%e7%b3%bb%e7%bb%9f%e5%b7%a5%e7%a8%8b%e5%b8%88sa%e5%a6%82%e4%bd%95%e5%b7%a5%e4%bd%9c/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>由拖库攻击谈口令字段的加密策略</title>
		<link>http://blog.webshuo.com/2012/01/05/%e7%94%b1%e6%8b%96%e5%ba%93%e6%94%bb%e5%87%bb%e8%b0%88%e5%8f%a3%e4%bb%a4%e5%ad%97%e6%ae%b5%e7%9a%84%e5%8a%a0%e5%af%86%e7%ad%96%e7%95%a5/</link>
		<comments>http://blog.webshuo.com/2012/01/05/%e7%94%b1%e6%8b%96%e5%ba%93%e6%94%bb%e5%87%bb%e8%b0%88%e5%8f%a3%e4%bb%a4%e5%ad%97%e6%ae%b5%e7%9a%84%e5%8a%a0%e5%af%86%e7%ad%96%e7%95%a5/#comments</comments>
		<pubDate>Thu, 05 Jan 2012 07:00:50 +0000</pubDate>
		<dc:creator>dick</dc:creator>
				<category><![CDATA[转载]]></category>
		<category><![CDATA[加密]]></category>
		<category><![CDATA[安全]]></category>

		<guid isPermaLink="false">http://blog.webshuo.com/?p=848</guid>
		<description><![CDATA[关键词：加密,安全 &#124; 作者：江海客 我不得不惨痛地写在前面的是，这是一个安全崩盘的时代。过去一年，已经证实的遭遇入侵、并导致关键数据被窃或者被泄露的公司，包括索尼、世嘉这样的大型游戏设备厂商；包括花旗银行这样的金融机构，也包括了RSA这样的安全厂商。 这些事件中最令业界瞠目的是RSA被入侵，这直接导致多家工业巨头遭遇连锁的攻击，很多安全企业本身也使用RSA的令牌。比RSA弱小很多的荷兰电子认证公司DigiNotar已经在被入侵后，宣告破产。 就在2011年上半年，我们还是站在旁观者的立场讨论这些事情。但随即我们就遭遇了CSDN、多玩和天涯等等的数据泄露，其中最为敏感的，一方面是用户信息，另一个当然就是用户口令。由于身份实名、口令通用等情况影响，一时间人人自危。各个站点也陷在口水当中。 但实际上根据推断，这些入侵都是一些过去时，也就是说这些库早就在地下流传。同时流出，也许就是一个集体性的心理效应。 这种针对数据库记录的窃取，被一些攻击者称为“拖库“，于是有了一个自然而谐音的戏称“脱裤”。只是攻击者日趋不厚道，从前只是偷了人家的裤子，现在还要晾在大街上，并贴上布告说，“看，丫裤子上还有补丁呢”。 如果拖库是很难避免的，那么采用合理的加密策略，让攻击者拿到库后的影响降低到更小就是必要的。 明文存放口令的时代肯定是要结束了，但加密就安全么？ 那些错误的加密策略 明文的密码固然是不能接受的，但错误的加密策略同样很糟糕。让我们看看下列情况。 简单使用标准HASH 我想起了一个90年代黑客笑话，有人进入一台UNIX主机，抓到了一个shadow文档，但破解不了。于是，他用自己的机器做了一个假的现场，故意留下这个shadow，最后看看别人用什么口令来试，最后再用这些口令与渗透原来的主机。遗憾的是，那时我们都把这个当成一个Joke，充其量回复一句“I服了you!“，而没有反思使用标准算法的问题。 目前来看，在口令保存上，使用最为广泛的算法是标准MD5 HASH。但实际上，很长时间，我们都忽略了HASH设计的初衷并不是用来加密，而是用来验证。系统设计者是因为HASH算法具有不可逆的特点所以“借”用其保存密码的。但其不可逆的前提假设，是明文集合是无限大的。但放到口令并不一样，口令的长度是受限的，同时其可使用的字符也是受限的。我们可以把口令的总数看正一个事实上的有限集（很难想象有人用100个字符作为口令）。 比如一个人的密码是“123456”，那么任何采用标准MD5加密的网站数据库中，其存放的都是这样一个MD5值：E10ADC3949BA59ABBE56E057F20F883E 由于密文均相同，加之HASH算法是单向的，因此攻击者较早使用的方法就是“密文比对+高频统计“后生成密文字典来攻击，由于绝大多数网站和系统的加密实现，都是相同明文口令生成相同的密文，因此，那些有高频密文的用户就可能是使用高频明文口令的用户。攻击者一方面可以针对标准算法来制定高频明文的对应密文档来查询，另一方面，对于那些非标准算法，高频统计攻击的方法也非常常见。 但查表攻击迅速压倒高频统计的原因，正是从2000年开始陆续有网站规模性明文口令泄漏事件开始的。在过去每一次明文的密码泄漏事件，攻击者都会把使用MD5、SHA1等常见HASH算法加工成的口令与那些采用HASH值来保存的库进行应对。 随着超算资源的廉价、GPU的普及、存储能力的增长，一个不容忽视的威胁开始跃上桌面，那就是，这些巨大的HASH表已经不仅仅是基于泄漏的密码和常见字符串字典来制作，很多攻击者通过长期的分工协作，通过穷举的方式来制作一定位数以下的数字字母组合的口令串与多种算法加密结果的映射结果集，这些结果集从百GB到几十TB，这就是传说中的彩虹表。 HASH的单向性优势在此已经只有理论意义，因为HASH的单向性是靠算法设计保证的，使用一个有限集来表示一个无限集，其必然是不可逆的。但攻击者是从查表来完成从HASH到口令明文的还原的。因此其算法的单向性也就失去了意义。 联合使用HASH 一些人误以为，HASH不够安全是因为HASH算法的强度问题，因此把MD5或者SHA1联合使用，其实这是毫无价值的（只是徒耗了存储资源）。如上面所说，HASH的不安全性在于大量口令与其HASH值的对应关系早已经被制作成彩虹表。只要你联合使用HASH的算法其中之一在彩虹表中，自然就可以查到了。 同理，那种采用“MD5的头+SHA的尾“之类的，或者采用其他的混合两个值的方法，也一样是没有意义的。因为攻击者可以很容易的观察到这种组合方法的规律，经过拆解后继续按照查表法破解。 自己设计算法 我一向认为，既然我们不是一个密码学家，而是工程师、程序员，那么放着现成的好东西不用，自己开发加密算法是相当愚蠢的事情。我相信很多程序员都遇到过挖空心思想到了一个“新算法”，然后发现早在某篇20世纪80年代的数学论文里，早就提出了相关算法的情况。 况且在开源时代，很多算法不仅被实现和发布了，而且还经历了长期的使用推敲。这些都是自己设计、自己实现无法比拟的。 关于自主设计的算法的不安全性，有一个事情深达我脑海。记得我在证券系统工作时，由于刚刚接手收购来的营业部，需要把一个clipper编译的柜台系统进行迁移，但原来的开发商已经联系不到了，当时我们制定了两条路，一位高手李老师负责，进行数据破解，看看是否能还原明文，而我则负责破解算法，如果李老师那边走不通，则我需要解出算法，把000000～999999之间的数字全部加密，然后用密文做碰撞（那时证券都是柜台操作，没有网上炒股，密码都是柜台用数字键盘输入的）。 由于原来的开发者加了一点花活，我这边还没有眉目，那边旁观李老师的工程师，已经发出了惊叹之声，我跑过去，只见李老师根据构造的几个密码的加密结果，在纸上汇出了长得非常像杨辉三角的东西。不到半个小时，李老师已经连解密程序一起做好了。 上面故事的目的是说明，自己设计算法无论怎么自我感觉良好，看看美国官方遴选算法的PK过程大家就明白了，我们无法和全球数学家的智慧组合对抗。 因此自己设计实现算法，并不是一个好主意。这其中也包括，在实现上会不会有类似输入超长字符串会溢出一类的Bug。 单独使用对称算法 在标准HASH安全破灭后，又看到有人呼吁用AES，其实这不是一个好建议。AES这些对称算法，都不具备单向性。网站被攻击的情况是复杂的，有的是只有数据库被拖，有的则整个环境沦陷。而后者AES密钥一旦被拿到，密码就会被还原出来，这比被查表还要坏。 当然我们还看到一种把AES当HASH用的思想，就是只保留一部分的AES加密结果，只验证不还原。但其实这样的AES并不见得比HASH有优势。比如即使攻击者没有拿到密钥，也只拖了库，但攻击者自己在拖库之前注册了足够多的帐号，并使用大量不同的短口令。那么就拿到了一组短明文和对应密文。而此时密钥是完全有可能被分析出来的。 而使用DES、AES一类的算法，还是使用标注HASH，还是自己设计算法，如果不解决不同用户相同口令密文相同的统计性缺陷，那么攻击者即使拿不到密钥，也都可以先把一些高频口令用于帐号注册，拖库后进行密文比对。就可以锁定大量的采用常见口令的用户。 加“一粒盐” 其实很多同仁都指出了哈希加盐法（HASH+SALT），是问题的解决之道，所谓加盐（SALT）其实很简单，就是在生成HASH时给予一个扰动，使HASH值与标准的HASH结果不同，这样就可以抗彩虹查表了。 比如说，用户的密码是123456，加一个盐，也就是随机字符串“1cd73466fdc24040b5”，两者合到一起，计算MD5，得到的结果是6c9055e7cc9b1bd9b48475aaab59358e。通过这种操作，即便用户用的弱密码，也通过加盐，使实际计算哈希值的是一个长字符串，一定程度上防御了穷举攻击和彩虹表攻击。 但从我们审计过的实现来看，很多人只加了“一粒盐”。也就是说，对同一个站点，不同用户使用同一个密码，其密文还是相同的。这就又回到了会遭遇高频统计攻击，预先注册攻击等问题。 口令的安全策略 在传统密码学家眼中只有一种加密是理想的，那就是“一次一密”，当然事实上这是不可能的。但如果我们套用这种词法，我们也可以说，口令安全策略的理想境界，我们可以称为单向、一人一密、一站一密。 单向：标准HASH算法的价值尽管在这个场景下，已经被推倒，但其单向性的思想依然是正确的，口令只要是能还原的，就意味着攻击者也能做到这一点，从而失去了意义，因此使用单向算法是必须的。 一人一密：同一个站点设置同样口令的不同用户，加密生成的密文内容并不相同。这样就能有效的应对结果碰撞和统计攻击。采用字典的攻击的方法基本是不收敛的。 一站一密：仅仅保证一人一密是不够的，还要保证使用同样信息、同样口令去注册不同网站的用户，在不同站点的口令加密结果是不同的。鉴于有大量用户用同样的信息、同样的口令去注册不同网站，如果能做到这一点，流失出的库信息会进一步打折扣。而攻击者基本会放弃生成密文字典的尝试。 实现这些说起来很简单，依然是HASH+SALT，关键在于每个站点要有不同的SALT，每个用户要有不同的盐。 但如果攻击者不是只获得了库，而且也获得了相关的加密参数和密钥，我们就要看到攻击者依然可以自己通过相关参数和密钥调用算法，使用常见密码对每个用户生成一遍密文，然后是否有匹配。当然我们可以看到由于“每人一粒盐”的策略，攻击者所需要的计算代价已经变化了，如果过去只需要生成一次的话，那么假如使用100个常见的口令来做，那么只要口令没有碰撞到，对每个用户都要做100次加密操作。但这也是不容小觑的威胁。因为有太多用户喜欢使用那些常见口令。 因此，设定一个密码禁用表，让用户避免使用常见口令，可以进一步让破解者付出更大的代价，从而最终导致计算资源不收敛而放弃，也可以是一个可以考虑的策略。但也需要提醒WEB开发者的是，这样会增大你的用户忘记口令的风险。 另外，用户是否有把密码设置为123456的自由呢，我想只要不是国防、航天、涉密系统和有安全要求的企业环境，如果只是潜潜水、骂骂街，网站或许提醒用户就好，但也许并不需要做成强制策略。 具体的实现 了这么多，怎么来具体实现一站一密、一人一密的策略呢，2011年12月23号，我们想到与其空洞的说教算法原理和策略，不如提供一些非常直接的示例程序和文档。 因此同事们写了一份名为Antiy Password Mixer（安天密码混合器）的开源代码，当然这没有什么技术含量，也不是“自有知识产权的国产算法”，有的只是对实现较好的流行开源算法包的示范性使用而已，目前的Python版本，也只有三百行代码，在其中封装了RSA和HASH+SALT使用，并给出了具体的在初始化、注册和认证时如何使用的范例文档。 大家可以在这里找到这个东西：http://code.google.com/p/password-mixer/ 当然，就像我们惋惜很多应用开发者缺乏对安全的重视一样，其实我们并不懂应用开发，所以这些代码和文档对于应用开发者看来可能非常丑陋。尽管可能被鄙视，我们还是要打开门，证明安全团队并不保守。 [...]]]></description>
			<content:encoded><![CDATA[<p>关键词：加密,安全 | 作者：江海客<br />
我不得不惨痛地写在前面的是，这是一个安全崩盘的时代。过去一年，已经证实的遭遇入侵、并导致关键数据被窃或者被泄露的公司，包括索尼、世嘉这样的大型游戏设备厂商；包括花旗银行这样的金融机构，也包括了RSA这样的安全厂商。</p>
<p>这些事件中最令业界瞠目的是RSA被入侵，这直接导致多家工业巨头遭遇连锁的攻击，很多安全企业本身也使用RSA的令牌。比RSA弱小很多的荷兰电子认证公司DigiNotar已经在被入侵后，宣告破产。</p>
<p>就在2011年上半年，我们还是站在旁观者的立场讨论这些事情。但随即我们就遭遇了CSDN、多玩和天涯等等的数据泄露，其中最为敏感的，一方面是用户信息，另一个当然就是用户口令。由于身份实名、口令通用等情况影响，一时间人人自危。各个站点也陷在口水当中。</p>
<p>但实际上根据推断，这些入侵都是一些过去时，也就是说这些库早就在地下流传。同时流出，也许就是一个集体性的心理效应。</p>
<p>这种针对数据库记录的窃取，被一些攻击者称为“拖库“，于是有了一个自然而谐音的戏称“脱裤”。只是攻击者日趋不厚道，从前只是偷了人家的裤子，现在还要晾在大街上，并贴上布告说，“看，丫裤子上还有补丁呢”。</p>
<p>如果拖库是很难避免的，那么采用合理的加密策略，让攻击者拿到库后的影响降低到更小就是必要的。</p>
<p>明文存放口令的时代肯定是要结束了，但加密就安全么？</p>
<p>那些错误的加密策略</p>
<p>明文的密码固然是不能接受的，但错误的加密策略同样很糟糕。让我们看看下列情况。</p>
<p>简单使用标准HASH</p>
<p>我想起了一个90年代黑客笑话，有人进入一台UNIX主机，抓到了一个shadow文档，但破解不了。于是，他用自己的机器做了一个假的现场，故意留下这个shadow，最后看看别人用什么口令来试，最后再用这些口令与渗透原来的主机。遗憾的是，那时我们都把这个当成一个Joke，充其量回复一句“I服了you!“，而没有反思使用标准算法的问题。</p>
<p>目前来看，在口令保存上，使用最为广泛的算法是标准MD5 HASH。但实际上，很长时间，我们都忽略了HASH设计的初衷并不是用来加密，而是用来验证。系统设计者是因为HASH算法具有不可逆的特点所以“借”用其保存密码的。但其不可逆的前提假设，是明文集合是无限大的。但放到口令并不一样，口令的长度是受限的，同时其可使用的字符也是受限的。我们可以把口令的总数看正一个事实上的有限集（很难想象有人用100个字符作为口令）。</p>
<p>比如一个人的密码是“123456”，那么任何采用标准MD5加密的网站数据库中，其存放的都是这样一个MD5值：E10ADC3949BA59ABBE56E057F20F883E</p>
<p>由于密文均相同，加之HASH算法是单向的，因此攻击者较早使用的方法就是“密文比对+高频统计“后生成密文字典来攻击，由于绝大多数网站和系统的加密实现，都是相同明文口令生成相同的密文，因此，那些有高频密文的用户就可能是使用高频明文口令的用户。攻击者一方面可以针对标准算法来制定高频明文的对应密文档来查询，另一方面，对于那些非标准算法，高频统计攻击的方法也非常常见。</p>
<p>但查表攻击迅速压倒高频统计的原因，正是从2000年开始陆续有网站规模性明文口令泄漏事件开始的。在过去每一次明文的密码泄漏事件，攻击者都会把使用MD5、SHA1等常见HASH算法加工成的口令与那些采用HASH值来保存的库进行应对。</p>
<p>随着超算资源的廉价、GPU的普及、存储能力的增长，一个不容忽视的威胁开始跃上桌面，那就是，这些巨大的HASH表已经不仅仅是基于泄漏的密码和常见字符串字典来制作，很多攻击者通过长期的分工协作，通过穷举的方式来制作一定位数以下的数字字母组合的口令串与多种算法加密结果的映射结果集，这些结果集从百GB到几十TB，这就是传说中的彩虹表。</p>
<p>HASH的单向性优势在此已经只有理论意义，因为HASH的单向性是靠算法设计保证的，使用一个有限集来表示一个无限集，其必然是不可逆的。但攻击者是从查表来完成从HASH到口令明文的还原的。因此其算法的单向性也就失去了意义。</p>
<p>联合使用HASH</p>
<p>一些人误以为，HASH不够安全是因为HASH算法的强度问题，因此把MD5或者SHA1联合使用，其实这是毫无价值的（只是徒耗了存储资源）。如上面所说，HASH的不安全性在于大量口令与其HASH值的对应关系早已经被制作成彩虹表。只要你联合使用HASH的算法其中之一在彩虹表中，自然就可以查到了。</p>
<p>同理，那种采用“MD5的头+SHA的尾“之类的，或者采用其他的混合两个值的方法，也一样是没有意义的。因为攻击者可以很容易的观察到这种组合方法的规律，经过拆解后继续按照查表法破解。</p>
<p>自己设计算法</p>
<p>我一向认为，既然我们不是一个密码学家，而是工程师、程序员，那么放着现成的好东西不用，自己开发加密算法是相当愚蠢的事情。我相信很多程序员都遇到过挖空心思想到了一个“新算法”，然后发现早在某篇20世纪80年代的数学论文里，早就提出了相关算法的情况。</p>
<p>况且在开源时代，很多算法不仅被实现和发布了，而且还经历了长期的使用推敲。这些都是自己设计、自己实现无法比拟的。</p>
<p>关于自主设计的算法的不安全性，有一个事情深达我脑海。记得我在证券系统工作时，由于刚刚接手收购来的营业部，需要把一个clipper编译的柜台系统进行迁移，但原来的开发商已经联系不到了，当时我们制定了两条路，一位高手李老师负责，进行数据破解，看看是否能还原明文，而我则负责破解算法，如果李老师那边走不通，则我需要解出算法，把000000～999999之间的数字全部加密，然后用密文做碰撞（那时证券都是柜台操作，没有网上炒股，密码都是柜台用数字键盘输入的）。</p>
<p>由于原来的开发者加了一点花活，我这边还没有眉目，那边旁观李老师的工程师，已经发出了惊叹之声，我跑过去，只见李老师根据构造的几个密码的加密结果，在纸上汇出了长得非常像杨辉三角的东西。不到半个小时，李老师已经连解密程序一起做好了。</p>
<p>上面故事的目的是说明，自己设计算法无论怎么自我感觉良好，看看美国官方遴选算法的PK过程大家就明白了，我们无法和全球数学家的智慧组合对抗。</p>
<p>因此自己设计实现算法，并不是一个好主意。这其中也包括，在实现上会不会有类似输入超长字符串会溢出一类的Bug。</p>
<p>单独使用对称算法</p>
<p>在标准HASH安全破灭后，又看到有人呼吁用AES，其实这不是一个好建议。AES这些对称算法，都不具备单向性。网站被攻击的情况是复杂的，有的是只有数据库被拖，有的则整个环境沦陷。而后者AES密钥一旦被拿到，密码就会被还原出来，这比被查表还要坏。</p>
<p>当然我们还看到一种把AES当HASH用的思想，就是只保留一部分的AES加密结果，只验证不还原。但其实这样的AES并不见得比HASH有优势。比如即使攻击者没有拿到密钥，也只拖了库，但攻击者自己在拖库之前注册了足够多的帐号，并使用大量不同的短口令。那么就拿到了一组短明文和对应密文。而此时密钥是完全有可能被分析出来的。</p>
<p>而使用DES、AES一类的算法，还是使用标注HASH，还是自己设计算法，如果不解决不同用户相同口令密文相同的统计性缺陷，那么攻击者即使拿不到密钥，也都可以先把一些高频口令用于帐号注册，拖库后进行密文比对。就可以锁定大量的采用常见口令的用户。</p>
<p>加“一粒盐”</p>
<p>其实很多同仁都指出了哈希加盐法（HASH+SALT），是问题的解决之道，所谓加盐（SALT）其实很简单，就是在生成HASH时给予一个扰动，使HASH值与标准的HASH结果不同，这样就可以抗彩虹查表了。</p>
<p>比如说，用户的密码是123456，加一个盐，也就是随机字符串“1cd73466fdc24040b5”，两者合到一起，计算MD5，得到的结果是6c9055e7cc9b1bd9b48475aaab59358e。通过这种操作，即便用户用的弱密码，也通过加盐，使实际计算哈希值的是一个长字符串，一定程度上防御了穷举攻击和彩虹表攻击。</p>
<p>但从我们审计过的实现来看，很多人只加了“一粒盐”。也就是说，对同一个站点，不同用户使用同一个密码，其密文还是相同的。这就又回到了会遭遇高频统计攻击，预先注册攻击等问题。</p>
<p>口令的安全策略</p>
<p>在传统密码学家眼中只有一种加密是理想的，那就是“一次一密”，当然事实上这是不可能的。但如果我们套用这种词法，我们也可以说，口令安全策略的理想境界，我们可以称为单向、一人一密、一站一密。</p>
<p>单向：标准HASH算法的价值尽管在这个场景下，已经被推倒，但其单向性的思想依然是正确的，口令只要是能还原的，就意味着攻击者也能做到这一点，从而失去了意义，因此使用单向算法是必须的。</p>
<p>一人一密：同一个站点设置同样口令的不同用户，加密生成的密文内容并不相同。这样就能有效的应对结果碰撞和统计攻击。采用字典的攻击的方法基本是不收敛的。</p>
<p>一站一密：仅仅保证一人一密是不够的，还要保证使用同样信息、同样口令去注册不同网站的用户，在不同站点的口令加密结果是不同的。鉴于有大量用户用同样的信息、同样的口令去注册不同网站，如果能做到这一点，流失出的库信息会进一步打折扣。而攻击者基本会放弃生成密文字典的尝试。</p>
<p>实现这些说起来很简单，依然是HASH+SALT，关键在于每个站点要有不同的SALT，每个用户要有不同的盐。</p>
<p>但如果攻击者不是只获得了库，而且也获得了相关的加密参数和密钥，我们就要看到攻击者依然可以自己通过相关参数和密钥调用算法，使用常见密码对每个用户生成一遍密文，然后是否有匹配。当然我们可以看到由于“每人一粒盐”的策略，攻击者所需要的计算代价已经变化了，如果过去只需要生成一次的话，那么假如使用100个常见的口令来做，那么只要口令没有碰撞到，对每个用户都要做100次加密操作。但这也是不容小觑的威胁。因为有太多用户喜欢使用那些常见口令。</p>
<p>因此，设定一个密码禁用表，让用户避免使用常见口令，可以进一步让破解者付出更大的代价，从而最终导致计算资源不收敛而放弃，也可以是一个可以考虑的策略。但也需要提醒WEB开发者的是，这样会增大你的用户忘记口令的风险。</p>
<p>另外，用户是否有把密码设置为123456的自由呢，我想只要不是国防、航天、涉密系统和有安全要求的企业环境，如果只是潜潜水、骂骂街，网站或许提醒用户就好，但也许并不需要做成强制策略。</p>
<p>具体的实现</p>
<p>了这么多，怎么来具体实现一站一密、一人一密的策略呢，2011年12月23号，我们想到与其空洞的说教算法原理和策略，不如提供一些非常直接的示例程序和文档。</p>
<p>因此同事们写了一份名为Antiy Password Mixer（安天密码混合器）的开源代码，当然这没有什么技术含量，也不是“自有知识产权的国产算法”，有的只是对实现较好的流行开源算法包的示范性使用而已，目前的Python版本，也只有三百行代码，在其中封装了RSA和HASH+SALT使用，并给出了具体的在初始化、注册和认证时如何使用的范例文档。</p>
<p>大家可以在这里找到这个东西：http://code.google.com/p/password-mixer/</p>
<p>当然，就像我们惋惜很多应用开发者缺乏对安全的重视一样，其实我们并不懂应用开发，所以这些代码和文档对于应用开发者看来可能非常丑陋。尽管可能被鄙视，我们还是要打开门，证明安全团队并不保守。</p>
<p>而同时，我们必须与应用走得更近，因为我们也在使用着这些自认为违反了某种安全原则的应用，却因为不是其开发者而无法改造它们。</p>
<p>过去的10余年，中国的Web应用甩开安全而飞速狂奔，开发者们凭借自身的勤奋和冲击力奠定了现有的格局，但也因快速地奔跑遗落了一些东西，比如安全。也许现在是拾起这些弃物的时间了。</p>
<p>中国的安全界则因保守、敏感和很多自身的原因，与应用的距离越拉越远，在我们还在幻想某些完美的安全图景时，发现我们已经望不到应用的脊背了。也许，在应用会回头等等我们的时候，就是我们加速前行、拾起应用所遗落的安全性，追送上去的时间了。</p>
<p>作者介绍：</p>
<p>网名江海客，安天实验室首席技术架构师，研究方向为反病毒和计算机犯罪取证等。微博：@江海客。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.webshuo.com/2012/01/05/%e7%94%b1%e6%8b%96%e5%ba%93%e6%94%bb%e5%87%bb%e8%b0%88%e5%8f%a3%e4%bb%a4%e5%ad%97%e6%ae%b5%e7%9a%84%e5%8a%a0%e5%af%86%e7%ad%96%e7%95%a5/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP实现BigPipe分chunked输出</title>
		<link>http://blog.webshuo.com/2011/12/21/php%e5%ae%9e%e7%8e%b0bigpipe%e5%88%86chunked%e8%be%93%e5%87%ba/</link>
		<comments>http://blog.webshuo.com/2011/12/21/php%e5%ae%9e%e7%8e%b0bigpipe%e5%88%86chunked%e8%be%93%e5%87%ba/#comments</comments>
		<pubDate>Wed, 21 Dec 2011 07:45:01 +0000</pubDate>
		<dc:creator>dick</dc:creator>
				<category><![CDATA[Ajax]]></category>
		<category><![CDATA[HTML/CSS]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[WEB开发]]></category>
		<category><![CDATA[服务器]]></category>
		<category><![CDATA[经验分享]]></category>

		<guid isPermaLink="false">http://blog.webshuo.com/?p=831</guid>
		<description><![CDATA[在Yahoo系的最佳实践里，建议把静态的内容尽早的输出，在 head之后就调用flush，让浏览器可以尽早去加载静态资源，包括脚本、样式、图片（javascipt，css，image一般是外链的形式）等等，后台如果有多个数据源或者api需要调用，尽可能做到完成一个输出一个，通过js在前端拼装页面，进而达到优化用户体验的效果，用户等待的时间，是木桶最短的那快木板。 下面是引用： Flush the Buffer Early tag: server When users request a page, it can take anywhere from 200 to 500ms for the backend server to stitch together the HTML page. During this time, the browser is idle as it waits for the data to arrive. In PHP you have the function flush(). It [...]]]></description>
			<content:encoded><![CDATA[<p>在Yahoo系的最佳实践里，建议把静态的内容尽早的输出，在 head之后就调用flush，让浏览器可以尽早去加载静态资源，包括脚本、样式、图片（javascipt，css，image一般是外链的形式）等等，后台如果有多个数据源或者api需要调用，尽可能做到完成一个输出一个，通过js在前端拼装页面，进而达到优化用户体验的效果，用户等待的时间，是木桶最短的那快木板。<br />
下面是引用：<br />
Flush the Buffer Early<br />
tag: server<br />
When users request a page, it can take anywhere from 200 to 500ms for the backend server to stitch together the HTML page. During this time, the browser is idle as it waits for the data to arrive. In PHP you have the function flush(). It allows you to send your partially ready HTML response to the browser so that the browser can start fetching components while your backend is busy with the rest of the HTML page. The benefit is mainly seen on busy backends or light frontends.<br />
A good place to consider flushing is right after the HEAD because the HTML for the head is usually easier to produce and it allows you to include any CSS and JavaScript files for the browser to start fetching in parallel while the backend is still processing.<br />
Example:</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="javascript"><pre class="de1">      ... <span class="sy0">&lt;!--</span> css<span class="sy0">,</span> js <span class="sy0">--&gt;</span>
    <span class="sy0">&lt;/</span>head<span class="sy0">&gt;</span>
    <span class="sy0">&lt;?</span>php flush<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span> <span class="sy0">?&gt;</span>
    <span class="sy0">&lt;</span>body<span class="sy0">&gt;</span>
      ... <span class="sy0">&lt;!--</span> content <span class="sy0">--&gt;</span></pre></div></div></div></div></div></div></div>


<p>Facebook提出的BigPipe技术，将这种思想有了更具体的实现，大体思路是，分解网页成叫做Pagelets的小块，然后通过Web服务器和浏览器建立管道并管理他们在不同阶段的运行。<br />
在php下做个小测试，</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="php"><ol><li class="li1"><pre class="de1"><span class="kw2">&lt;?php</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">echo</span> <span class="st_h">'xxxxxxxxxxxxxxxxxxxxxxx&lt;br&gt;'</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw3">ob_flush</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw3">flush</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw3">sleep</span><span class="br0">&#40;</span><span class="nu0">2</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">echo</span> <span class="st0">&quot;b&quot;</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="sy1">?&gt;</span></pre></li></ol></div></div></div></div></div></div></div>


<p>结果可以看到在ie下（7，8），不管输出内容的大小，都可以看到效果，“b“在2秒后输出，在firefox和chrome，两段文本都在2秒后展现，说明浏览器做了缓存，经过实验，缓存的大小为1024，刚好1k，也是浏览器做的优化。通过返回头可以看出，在分段输出的时候，返回包没有经过gzip。</p>
<p>通过wireshark可以看到后台输出确实是一个个chunked过来的，看来是浏览器做了工作，猜测：缓存大小应该是1024B或者MTU大小（1400B多点，看网络情况），首段输出增大到1024的时，chrome和firefox都开始正常表演了，页面里的js、css和图片在第一段下载完已经开始加载。</p>
<p>应该思考的问题：<br />
1、传输效率，尽量利用一次传输传送尽量多的东西，根据MTU大小调整；<br />
2、同步加载，第一块送过来的东西，尽量可以同步加载，需要注意不同浏览器可以同步加载域名的数量，需要考虑javascript对加载的block，对于不用立刻执行的内容，可以通过加defer或者干脆注释掉，等页面完成在eval进来；<br />
3、适用范围，任何一个技术都有自己适用的场景，对于后台需要访问多个api的应用会更适合一些，像社交类的网站，搜索之类的本来就在100ms左右就展现完毕，纯玩儿技术就没意义了，chunked也不是分的越多越好，适当的，类似的最好合并起来；<br />
4、ob_flush和flush最好结对使用，某些情况下，当用flush是没有效果的。</p>
<p>参考：</p>
<p>http://willko.iteye.com/blog/685319</p>
<p>http://developer.yahoo.com/performance/rules.html#flush</p>
<p>http://www.laruence.com/index.php?s=php&#038;x=0&#038;y=0</p>
<p>http://isux.tencent.com/bigpipe-pipelining-web-pages-for-high-performance.html</p>
<p>http://baike.baidu.com/view/4601904.htm</p>
<p>http://software.intel.com/zh-cn/blogs/2009/02/04/400001071/</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.webshuo.com/2011/12/21/php%e5%ae%9e%e7%8e%b0bigpipe%e5%88%86chunked%e8%be%93%e5%87%ba/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[转]风雨20年：我所积累的20条编程经验</title>
		<link>http://blog.webshuo.com/2011/10/11/%e8%bd%ac%e9%a3%8e%e9%9b%a820%e5%b9%b4%ef%bc%9a%e6%88%91%e6%89%80%e7%a7%af%e7%b4%af%e7%9a%8420%e6%9d%a1%e7%bc%96%e7%a8%8b%e7%bb%8f%e9%aa%8c/</link>
		<comments>http://blog.webshuo.com/2011/10/11/%e8%bd%ac%e9%a3%8e%e9%9b%a820%e5%b9%b4%ef%bc%9a%e6%88%91%e6%89%80%e7%a7%af%e7%b4%af%e7%9a%8420%e6%9d%a1%e7%bc%96%e7%a8%8b%e7%bb%8f%e9%aa%8c/#comments</comments>
		<pubDate>Tue, 11 Oct 2011 00:31:31 +0000</pubDate>
		<dc:creator>jessica</dc:creator>
				<category><![CDATA[未分类]]></category>
		<category><![CDATA[编程经验]]></category>

		<guid isPermaLink="false">http://blog.webshuo.com/?p=827</guid>
		<description><![CDATA[本文转自Jonathan Danylko的网站DCS Media。Danylko是一位资深开发顾问，DCS公司的创始人。 从11岁时，我就一直在编程，并且一直都很喜欢技术和编程。这些年来，我积累了一些艰难又容易的经验。作为一名程序员，你或许还没这些经验，但我会把它们献给那些想从中学到更多的朋友。 我会持续更新这些经验，我可能还会有更多的感想，但就我这20年来看，我想下面这个列表中基本不需要增添额外的东西了。下面就是我至今最难忘的经验。 1. 估算解决问题所需要的时间。不要怕，承认吧！我曾见过一些程序员为了解决一个特殊问题而坐在显示器前面8小时。为自己定一个时间限制吧，1小时、30分钟或甚至15分钟。如果在这期间你不能解决问题，那就去寻求帮助，或到网上找答案，而不是尝试去做“超级堆码员”。 2. 编程语言是一种语言，只是一种语言。随着时光推移，只要你理解了一种语言的原理，你会发现各种语言之间的相似之处 。你所选择的语言，你应该觉得“舒服”，并且能够写出有效（而且简洁）的代码。最重要的，让语言去适应项目，反之亦然。 3. 不要过于注重程序的“设计模式”。 有时候，写一个简单的算法，要比引入某种模式更容易。在多数情况下，程序代码应是简单易懂，甚至清洁工也能看懂。 4. 经常备份代码。在我年轻时，我就有过因硬盘故障而丢了大量代码的经历，这经历很恐怖的。只要你一次没有备份，就应当像有着严格的期限，客户明天就需要。此时就该源码/版本控制软件大显身手了。 5. 承认自己并不是最顶尖的程序员 &#8211; 知不足。我常想，我对编程了解已足够多，但是总有其他人比你优秀。正所谓，“一山总比一山高”。所以，向他们看齐吧！ 6. 学习再学习。正如第5点所说，我经常会在手里拿一本计算机或编程相关的杂志或书（不信，可以问我的朋友）。诚然，总有很多你不知道的技术，你可以从中学习以保持不落后。如果你有一种灵巧的方式来获取你需要的新技术，那你每天都应该坚持学习。 7. 永恒的变化。你对待技术/编程知识，就应像你对待股票一样：多样化。不要在某一特定技术上自我感觉良好。如果那种技术或语言已经没有足够支持，那你还不如现在就开始更新你的简历，并启动培训新计划。我能保持前行的主要原则是什么呢？至少了解两到三种语言，所以，如果某种语言过时了，你在学习新技术的时候还可以依靠另一种语言。 8. 提携新人。协助并且培养初级/入门的开发人员学习优秀的编程方法和技巧。也许你还不知道，在帮助他们向更高一层前进时，你自己也在向更高一层提升，你会更加自信。 9. 简化算法。代码如恶魔，在你完成编码后，应回头并且优化它。从长远来看，这里或那里一些的改进，会让后来的支持人员更加轻松。 10. 编写文档。无论是Web服务的API，还是一个简单的类，你尽量编写相应文档。我曾经引以为豪的代码注释，因过度注释而有人指责。给三行代码加一行注释，只需要你几秒时间。如果那是一个比较难以理解的技术，千万别担心过多注释。如果你能很好做好自己的工作，大多数架构师、后备程序员、支持组都会感激你。 11. 测试、测试再测试。我是一名黑盒测试粉丝。当你完成编码后，你“被认可”的时候就开始了。如果你们公司有QA部门，如果你的代码中有错误，那你得到的评论，会比项目经理还多。如果你不彻底测试自己的代码，那恐怕你开发的就不只是代码，可能还会声名狼藉。 12. 庆祝每一次成功。我见过很多程序员在解决编程技术难题后，会和同伴握手、击掌或甚至手舞足蹈。每个人在生命中都会碰到“顿悟”。如果一个程序员高兴地跑来叫你去看他的非凡代码，也许你已经看过这样的代码100遍了，但你也应该为了这个家伙而庆祝第101次。 13. 经常检查代码。 在公司，你的代码要经常检查（包括自查和其他同事检查）。不要把别人的检查，看成是对代码风格的苛求。应该把它们看作是有建设性的批评。对个人来说，经常检查你的代码并且自问，“我怎样才能写得更好呢？” 这会让你加速你的成长，让你成为一个更优秀的程序员。 14. 回顾你的代码。在看到自己以前的代码时，通常会有两种方式：“难以至信，这代码是我写的”和“难以至信，这代码是我写的”。第一种往往是厌恶的语气，并在想如何改进它。你也许会惊叹，旧代码也能复活成为一种更好的程序，甚至是一个完整的产品。第二种通常带着惊奇和成就感。开发人员应该一到两个自己完成的项目成果，能让众人不禁而立并注目而观的项目。同样，基于你优越的编程能力，你可以把过去的程序或项目拿出来，把它们更新为更加优秀的产品或想法。 15. 幽默是不可缺的。在我20年的开发生涯中，我还没有碰到哪位程序员是没有幽默感的。实际上，干我们这行，幽默是一项必备品。 16. 谨防那些无所不知的程序员，不愿分享的程序员，还有经验不足的程序员。当你遇到这几种程序员时，你自己要谦虚。无所不知的程序员，更想当一个英雄而不是团队成员；保守的程序员则是在编写着他们独享的代码；而经验不足的程序员则会每十分钟就来问你一下，当代码完成后，代码已经是你的，而不是他们。 17. 任何项目都不会那么简单。朋友、家人和同事曾请求我仓促做一些事情，仓促做一个程序或者网站。对于这样的事，应该从双方做计划，才能做出令两方都会满意的东西。如果某人起初只是需要一个使用Microsoft Access的、只有有3个页面的网站，但来就很可能变成一个有15个页面的网站，并使用SQL Server，有一个论坛，还有一个定制的CMS（内容管理系统）。 18. 任何时候不要想当然。假如你承接一个简单的项目，你可能会认为某个部分可以轻松完成。千万别这样想！除非你有一个类、组件、或者一段已经写好的代码，并且在现有的项目已经测试通过。不要认为这将是很容易的。 19. 没有已经完成的软件。曾经有一位程序员告诉我，没有软件是已经完成的，它只是“暂时完成了”。这是明智的忠告。如果客户还在使用你写的程序，并经受了时间的考验。如果有机会，你仍在更新它，这并不是什么坏事，这让你不断地前行。 20. 耐心是一种美德。当客户、朋友或家庭成员用电脑的时候，他们也许会受挫，进而想砸电脑，或气冲冲地离开。我一直在告诉他们，“是你掌控电脑，不是电脑掌控你。”对于用作编程的电脑，你要有一定的耐心。一旦程序员知道问题所在后，他们就会站在电脑的角度看问题，并且说“哦，这就是为什么它是这样做。”]]></description>
			<content:encoded><![CDATA[<p>本文转自Jonathan Danylko的网站DCS Media。Danylko是一位资深开发顾问，DCS公司的创始人。 </p>
<p>从11岁时，我就一直在编程，并且一直都很喜欢技术和编程。这些年来，我积累了一些艰难又容易的经验。作为一名程序员，你或许还没这些经验，但我会把它们献给那些想从中学到更多的朋友。</p>
<p>我会持续更新这些经验，我可能还会有更多的感想，但就我这20年来看，我想下面这个列表中基本不需要增添额外的东西了。下面就是我至今最难忘的经验。</p>
<p>1. 估算解决问题所需要的时间。不要怕，承认吧！我曾见过一些程序员为了解决一个特殊问题而坐在显示器前面8小时。为自己定一个时间限制吧，1小时、30分钟或甚至15分钟。如果在这期间你不能解决问题，那就去寻求帮助，或到网上找答案，而不是尝试去做“超级堆码员”。</p>
<p>2. 编程语言是一种语言，只是一种语言。随着时光推移，只要你理解了一种语言的原理，你会发现各种语言之间的相似之处 。你所选择的语言，你应该觉得“舒服”，并且能够写出有效（而且简洁）的代码。最重要的，让语言去适应项目，反之亦然。</p>
<p>3. 不要过于注重程序的“设计模式”。 有时候，写一个简单的算法，要比引入某种模式更容易。在多数情况下，程序代码应是简单易懂，甚至清洁工也能看懂。 </p>
<p>4. 经常备份代码。在我年轻时，我就有过因硬盘故障而丢了大量代码的经历，这经历很恐怖的。只要你一次没有备份，就应当像有着严格的期限，客户明天就需要。此时就该源码/版本控制软件大显身手了。</p>
<p>5. 承认自己并不是最顶尖的程序员 &#8211; 知不足。我常想，我对编程了解已足够多，但是总有其他人比你优秀。正所谓，“一山总比一山高”。所以，向他们看齐吧！</p>
<p>6. 学习再学习。正如第5点所说，我经常会在手里拿一本计算机或编程相关的杂志或书（不信，可以问我的朋友）。诚然，总有很多你不知道的技术，你可以从中学习以保持不落后。如果你有一种灵巧的方式来获取你需要的新技术，那你每天都应该坚持学习。</p>
<p>7. 永恒的变化。你对待技术/编程知识，就应像你对待股票一样：多样化。不要在某一特定技术上自我感觉良好。如果那种技术或语言已经没有足够支持，那你还不如现在就开始更新你的简历，并启动培训新计划。我能保持前行的主要原则是什么呢？至少了解两到三种语言，所以，如果某种语言过时了，你在学习新技术的时候还可以依靠另一种语言。</p>
<p>8. 提携新人。协助并且培养初级/入门的开发人员学习优秀的编程方法和技巧。也许你还不知道，在帮助他们向更高一层前进时，你自己也在向更高一层提升，你会更加自信。</p>
<p>9. 简化算法。代码如恶魔，在你完成编码后，应回头并且优化它。从长远来看，这里或那里一些的改进，会让后来的支持人员更加轻松。</p>
<p>10. 编写文档。无论是Web服务的API，还是一个简单的类，你尽量编写相应文档。我曾经引以为豪的代码注释，因过度注释而有人指责。给三行代码加一行注释，只需要你几秒时间。如果那是一个比较难以理解的技术，千万别担心过多注释。如果你能很好做好自己的工作，大多数架构师、后备程序员、支持组都会感激你。</p>
<p>11. 测试、测试再测试。我是一名黑盒测试粉丝。当你完成编码后，你“被认可”的时候就开始了。如果你们公司有QA部门，如果你的代码中有错误，那你得到的评论，会比项目经理还多。如果你不彻底测试自己的代码，那恐怕你开发的就不只是代码，可能还会声名狼藉。</p>
<p>12. 庆祝每一次成功。我见过很多程序员在解决编程技术难题后，会和同伴握手、击掌或甚至手舞足蹈。每个人在生命中都会碰到“顿悟”。如果一个程序员高兴地跑来叫你去看他的非凡代码，也许你已经看过这样的代码100遍了，但你也应该为了这个家伙而庆祝第101次。</p>
<p>13. 经常检查代码。 在公司，你的代码要经常检查（包括自查和其他同事检查）。不要把别人的检查，看成是对代码风格的苛求。应该把它们看作是有建设性的批评。对个人来说，经常检查你的代码并且自问，“我怎样才能写得更好呢？” 这会让你加速你的成长，让你成为一个更优秀的程序员。</p>
<p>14. 回顾你的代码。在看到自己以前的代码时，通常会有两种方式：“难以至信，这代码是我写的”和“难以至信，这代码是我写的”。第一种往往是厌恶的语气，并在想如何改进它。你也许会惊叹，旧代码也能复活成为一种更好的程序，甚至是一个完整的产品。第二种通常带着惊奇和成就感。开发人员应该一到两个自己完成的项目成果，能让众人不禁而立并注目而观的项目。同样，基于你优越的编程能力，你可以把过去的程序或项目拿出来，把它们更新为更加优秀的产品或想法。</p>
<p>15. 幽默是不可缺的。在我20年的开发生涯中，我还没有碰到哪位程序员是没有幽默感的。实际上，干我们这行，幽默是一项必备品。</p>
<p>16. 谨防那些无所不知的程序员，不愿分享的程序员，还有经验不足的程序员。当你遇到这几种程序员时，你自己要谦虚。无所不知的程序员，更想当一个英雄而不是团队成员；保守的程序员则是在编写着他们独享的代码；而经验不足的程序员则会每十分钟就来问你一下，当代码完成后，代码已经是你的，而不是他们。</p>
<p>17. 任何项目都不会那么简单。朋友、家人和同事曾请求我仓促做一些事情，仓促做一个程序或者网站。对于这样的事，应该从双方做计划，才能做出令两方都会满意的东西。如果某人起初只是需要一个使用Microsoft Access的、只有有3个页面的网站，但来就很可能变成一个有15个页面的网站，并使用SQL Server，有一个论坛，还有一个定制的CMS（内容管理系统）。</p>
<p>18. 任何时候不要想当然。假如你承接一个简单的项目，你可能会认为某个部分可以轻松完成。千万别这样想！除非你有一个类、组件、或者一段已经写好的代码，并且在现有的项目已经测试通过。不要认为这将是很容易的。</p>
<p>19. 没有已经完成的软件。曾经有一位程序员告诉我，没有软件是已经完成的，它只是“暂时完成了”。这是明智的忠告。如果客户还在使用你写的程序，并经受了时间的考验。如果有机会，你仍在更新它，这并不是什么坏事，这让你不断地前行。</p>
<p>20. 耐心是一种美德。当客户、朋友或家庭成员用电脑的时候，他们也许会受挫，进而想砸电脑，或气冲冲地离开。我一直在告诉他们，“是你掌控电脑，不是电脑掌控你。”对于用作编程的电脑，你要有一定的耐心。一旦程序员知道问题所在后，他们就会站在电脑的角度看问题，并且说“哦，这就是为什么它是这样做。”</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.webshuo.com/2011/10/11/%e8%bd%ac%e9%a3%8e%e9%9b%a820%e5%b9%b4%ef%bc%9a%e6%88%91%e6%89%80%e7%a7%af%e7%b4%af%e7%9a%8420%e6%9d%a1%e7%bc%96%e7%a8%8b%e7%bb%8f%e9%aa%8c/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP5.4新特性之Array dereferencing support</title>
		<link>http://blog.webshuo.com/2011/08/23/php5-4%e6%96%b0%e7%89%b9%e6%80%a7%e4%b9%8barray-dereferencing-support/</link>
		<comments>http://blog.webshuo.com/2011/08/23/php5-4%e6%96%b0%e7%89%b9%e6%80%a7%e4%b9%8barray-dereferencing-support/#comments</comments>
		<pubDate>Tue, 23 Aug 2011 01:51:24 +0000</pubDate>
		<dc:creator>ball</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[转载]]></category>

		<guid isPermaLink="false">http://blog.webshuo.com/?p=824</guid>
		<description><![CDATA[一个盼望已久的特性，终于有了，转之～ Array dereferencing是个好东西, 有了Array dereferencing, 以前的这种写法就再也不必要了: &#60;?php list($name,) = explode(",", "Laruence, male"); ?&#62; 取而代之的是: $name = explode(",", "b, x")[0]; 另外,  Array derefencing也可以出现再赋值语句的左值中, 也就是理论上你可以这么写: explode(",", "test1, test2")[3] = "phper";]]></description>
			<content:encoded><![CDATA[<p>一个盼望已久的特性，终于有了，转之～</p>
<p>Array dereferencing是个好东西,  有了Array dereferencing, 以前的这种写法就再也不必要了:</p>
<pre>&lt;?php
    list($name,) = explode(",", "Laruence, male");
?&gt;
</pre>
<p>取而代之的是:</p>
<pre>$name = explode(",", "b, x")[0];
</pre>
<p>另外,  Array derefencing也可以出现再赋值语句的左值中, 也就是理论上你可以这么写:</p>
<pre>explode(",", "test1, test2")[3] = "phper";
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.webshuo.com/2011/08/23/php5-4%e6%96%b0%e7%89%b9%e6%80%a7%e4%b9%8barray-dereferencing-support/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>腾讯搜搜8月工作机会</title>
		<link>http://blog.webshuo.com/2011/08/16/%e8%85%be%e8%ae%af%e6%90%9c%e6%90%9c8%e6%9c%88%e5%b7%a5%e4%bd%9c%e6%9c%ba%e4%bc%9a/</link>
		<comments>http://blog.webshuo.com/2011/08/16/%e8%85%be%e8%ae%af%e6%90%9c%e6%90%9c8%e6%9c%88%e5%b7%a5%e4%bd%9c%e6%9c%ba%e4%bc%9a/#comments</comments>
		<pubDate>Tue, 16 Aug 2011 07:20:57 +0000</pubDate>
		<dc:creator>dickyao</dc:creator>
				<category><![CDATA[未分类]]></category>

		<guid isPermaLink="false">http://blog.webshuo.com/?p=819</guid>
		<description><![CDATA[客户端开发 客户端开发工程师： 岗位职责： 1、负责客户端功能模块的开发，； 2、负责客户端的架构设计与整体规划； 岗位要求： 1、计算机或相关专业本科以上学历，两年以上windows客户端软件开发经验； 2、精通C++编程，熟悉COM/ATL技术； 3、了解windows界面实现机制，有一定的Windows下网络编程经验； 4、熟悉VC++开发环境，熟悉MFC框架； 5、良好的学习能力与主动性积极性，善于发现并解决问题； 6、良好的沟通和团队协作能力，工作认真负责； 7、有浏览器开发或搜索经验者优先； 职位描述： Web开发： 1.负责网页产品相关研发工作； 2.负责数据中心平台的架构和开发工作； 3.负责系统的数据处理和维护工作； Linux后台开发： 1.负责网页后台业务的研发工作； 2.负责后台数据的处理和分析挖掘工作 能力要求： Web开发： 1.熟悉WEB应用开发技术和工具； 2.熟悉至少一种网页应用开发语言，最好使用过PHP，熟悉Javascript语言； 3.熟悉http协议，数据库技术，熟悉Apache和相关的环境配置管理； 4.了解面向对象的思想，了解产品的研发管理过程，精通设计模式者优先； Linux后台开发： 1.熟悉linux开发环境，熟悉C/C++语言； 2.熟悉Socket编程和数据库技术； 3.了解至少一种脚本语言； 4.了解开发相关工具的使用，比如SVN等； 5.熟悉面向对象的设计和开发思想； 6.有良好的沟通能力和团队合作精神，能曾受一定的工作压力； 7.愿意到北京长期工作； 联系方式：dickyao@tencent.com]]></description>
			<content:encoded><![CDATA[<p>客户端开发<br />
客户端开发工程师：<br />
岗位职责：<br />
1、负责客户端功能模块的开发，；<br />
2、负责客户端的架构设计与整体规划；<br />
岗位要求：<br />
1、计算机或相关专业本科以上学历，两年以上windows客户端软件开发经验；<br />
2、精通C++编程，熟悉COM/ATL技术；<br />
3、了解windows界面实现机制，有一定的Windows下网络编程经验；<br />
4、熟悉VC++开发环境，熟悉MFC框架；<br />
5、良好的学习能力与主动性积极性，善于发现并解决问题；<br />
6、良好的沟通和团队协作能力，工作认真负责；<br />
7、有浏览器开发或搜索经验者优先；</p>
<p>职位描述：<br />
Web开发：<br />
1.负责网页产品相关研发工作；<br />
2.负责数据中心平台的架构和开发工作；<br />
3.负责系统的数据处理和维护工作；</p>
<p>Linux后台开发：<br />
1.负责网页后台业务的研发工作；<br />
2.负责后台数据的处理和分析挖掘工作<br />
能力要求：<br />
Web开发：<br />
1.熟悉WEB应用开发技术和工具；<br />
2.熟悉至少一种网页应用开发语言，最好使用过PHP，熟悉Javascript语言；<br />
3.熟悉http协议，数据库技术，熟悉Apache和相关的环境配置管理；<br />
4.了解面向对象的思想，了解产品的研发管理过程，精通设计模式者优先；<br />
Linux后台开发：<br />
1.熟悉linux开发环境，熟悉C/C++语言；<br />
2.熟悉Socket编程和数据库技术；<br />
3.了解至少一种脚本语言；<br />
4.了解开发相关工具的使用，比如SVN等；<br />
5.熟悉面向对象的设计和开发思想；<br />
6.有良好的沟通能力和团队合作精神，能曾受一定的工作压力；<br />
7.愿意到北京长期工作；</p>
<p>联系方式：dickyao@tencent.com</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.webshuo.com/2011/08/16/%e8%85%be%e8%ae%af%e6%90%9c%e6%90%9c8%e6%9c%88%e5%b7%a5%e4%bd%9c%e6%9c%ba%e4%bc%9a/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

