<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" version="2.0">

<channel>
	<title>灰色的灵魂</title>
	
	<link>http://www.xuwenhao.com</link>
	<description>生命如此短暂，掌握技艺却要如此长久</description>
	<lastBuildDate>Fri, 20 Apr 2012 15:31:32 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/xuwenhao" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="xuwenhao" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>回到问题域</title>
		<link>http://www.xuwenhao.com/2012/04/20/go-back-to-question-domain/</link>
		<comments>http://www.xuwenhao.com/2012/04/20/go-back-to-question-domain/#comments</comments>
		<pubDate>Fri, 20 Apr 2012 15:29:49 +0000</pubDate>
		<dc:creator>Stanley Xu</dc:creator>
				<category><![CDATA[Life]]></category>
		<category><![CDATA[Tech]]></category>
		<category><![CDATA[Work]]></category>

		<guid isPermaLink="false">http://www.xuwenhao.com/?p=873</guid>
		<description><![CDATA[在管理大规模数据处理工作的时候，发现不少工程师，包括一些老工程师，某种程度上，都对工作有着某种程度上的轻视，常常的口头禅是“这个技术上没有什么难度”，但是我其实不太认同，所谓数据处理，在技术上没有什么难度这种说法。 的确，在这个MapReduce的基础架构已经被Google设计清楚，由Doug Cutting通过Hadoop完善实现了之后，似乎大数据处理变成了一份体力工作。似乎工程师需要做的，只是写写简单的字符串解析，以及统计逻辑，对于外边很多人觉得看起来很美的工作，一旦实际接触后，常常又会觉得颇为无聊。不过，从我过去的经验来看，很多工程师也是这样对待Web时代的Struts和Spring，搜索时代的分词器，Lucene。 大量算得上不错的工程师，通常当熟练运用已有的技术，在一个特定模式下工作后，就会开始觉得工作无聊重复。然而实际上，一旦成为一个熟练工之后，很多人便开始停滞不前了。原先不熟悉框架的时候，他们需要10天摸索才能完成一个功能，现在熟练了，他们只需要3天了，但是之后，他们再也不能缩短开发时间，同时，他们的Bug数量也不会变少，当有新的需求出现的时候，通常第一反应就是套入到当前框架种处理，我通常称之为“1年经验重复10遍”。 有些工程师在进入这样的状况后，往往会寻求找一些新的工具、框架以及工作内容，通常，这意味着换一份工作，或者换一个开发团队，但是在新工作或者新团队下，一般在度过了一年蜜月期之后，会再次陷入“其实也就那样都是些体力劳动”状况，这种情况我一般称之为“八大菜系都吃过你也不是一个好厨子”，这个情况比“1年经验重复10遍”会好一些，但是仍然是一个糟糕的循环。 还有些工程师，会去研究所依赖的基础框架的源代码，开始依样画葫芦，搞些新轮子出来，部分热衷造轮子的同学会对所有的项目都造同样的轮子出来，这种情况我称之为“轮子爱好者”。 然而遗憾的是，这几种情况，其实都不是一个正确的，提高一个程序员解决问题水平的正常路线，这些方法也许能够帮助你从一个水准一般的程序员，变成一个还不错甚至算得上优秀的程序员，但是不能帮助你跨过平台，成为一个真正优秀的明星程序员，或者用个被用得糟烂的词——“架构师”。 这些程序员不少最终会觉得写程序是个没前途的事情，觉得只能往Manager这一条黑道上挤，从此，世界上少了一个本有希望能够贡献杰出代码的人。事实上，真正想要成为更优秀的工程师，需要做的，是在应用架构层面，去提高生产效率，乃至支持更多更强大的功能。区分真正优秀的程序员和普通程序员的差异，往往在于，是否能够真正地找到契合问题域的解决方案，通常这样的解决方案，能够在数量级上减少实际的开发工作。想像一下用EJB2做PetStore，再到用Struts，再到用Struts2/WebWork，再到用SpringMVC，乃至使用Rails。 “1年经验重复10遍”会每天反复操练EJB2，“八大菜系都吃过你也不是一个好厨子”会用JSP,Servlet,EJB2,Struts,PHP,C#.NET，“轮子爱好者”会看到Struts之后轮一个和Struts差不多的。但是真正优秀的程序员，能够改进Struts的不足，搞出WebWork，乃至Rails。这并不意味着你一定要很Fancy地去搞Google面试一样研究很多算法，也不需要你一定多熟悉编译原理，操作系统这样的底层技术，也不需要你18般武艺样样稀松地去看PHP和C#。你需要的是，在有了解决方案之后，仔细思考，真正理解问题域，寻求能够更好地满足问题域的解决方案，从细节上改进现有问题域的解决方案。这是来自我的教训，事实上，前面的三种陷阱我都荒废了不少时间，直到近两年，才愈发觉得无论是反复操练熟练工，还是18般武艺样样稀松的都会一些，甚或是轮一些别人轮过的轮子，都不是能让自己真正跨出成为顶尖程序员的一步。真正要解决好问题，交付出有价值的程序和框架，还是要回到问题域去。 这也是我喜欢Twitter技术团队以及推崇Nathan Marz的原因，无论是ElephantBird，Finagle，还是Storm，都不是庞然大物般的程序，而是贴近问题域，合理解决问题域的解决方案，也是从技术角度，希望自己能够在最近两年里能够达到的水准。]]></description>
			<content:encoded><![CDATA[<p>在管理大规模数据处理工作的时候，发现不少工程师，包括一些老工程师，某种程度上，都对工作有着某种程度上的轻视，常常的口头禅是“这个技术上没有什么难度”，但是我其实不太认同，所谓数据处理，在技术上没有什么难度这种说法。</p>
<p>的确，在这个MapReduce的基础架构已经被Google设计清楚，由Doug Cutting通过Hadoop完善实现了之后，似乎大数据处理变成了一份体力工作。似乎工程师需要做的，只是写写简单的字符串解析，以及统计逻辑，对于外边很多人觉得看起来很美的工作，一旦实际接触后，常常又会觉得颇为无聊。不过，从我过去的经验来看，很多工程师也是这样对待Web时代的Struts和Spring，搜索时代的分词器，Lucene。</p>
<p>大量算得上不错的工程师，通常当熟练运用已有的技术，在一个特定模式下工作后，就会开始觉得工作无聊重复。然而实际上，一旦成为一个熟练工之后，很多人便开始停滞不前了。原先不熟悉框架的时候，他们需要10天摸索才能完成一个功能，现在熟练了，他们只需要3天了，但是之后，他们再也不能缩短开发时间，同时，他们的Bug数量也不会变少，当有新的需求出现的时候，通常第一反应就是套入到当前框架种处理，我通常称之为“1年经验重复10遍”。</p>
<p>有些工程师在进入这样的状况后，往往会寻求找一些新的工具、框架以及工作内容，通常，这意味着换一份工作，或者换一个开发团队，但是在新工作或者新团队下，一般在度过了一年蜜月期之后，会再次陷入“其实也就那样都是些体力劳动”状况，这种情况我一般称之为“八大菜系都吃过你也不是一个好厨子”，这个情况比“1年经验重复10遍”会好一些，但是仍然是一个糟糕的循环。</p>
<p>还有些工程师，会去研究所依赖的基础框架的源代码，开始依样画葫芦，搞些新轮子出来，部分热衷造轮子的同学会对所有的项目都造同样的轮子出来，这种情况我称之为“轮子爱好者”。</p>
<p>然而遗憾的是，这几种情况，其实都不是一个正确的，提高一个程序员解决问题水平的正常路线，这些方法也许能够帮助你从一个水准一般的程序员，变成一个还不错甚至算得上优秀的程序员，但是不能帮助你跨过平台，成为一个真正优秀的明星程序员，或者用个被用得糟烂的词——“架构师”。</p>
<p>这些程序员不少最终会觉得写程序是个没前途的事情，觉得只能往Manager这一条黑道上挤，从此，世界上少了一个本有希望能够贡献杰出代码的人。事实上，真正想要成为更优秀的工程师，需要做的，是在应用架构层面，去提高生产效率，乃至支持更多更强大的功能。区分真正优秀的程序员和普通程序员的差异，往往在于，是否能够真正地找到契合问题域的解决方案，通常这样的解决方案，能够在数量级上减少实际的开发工作。想像一下用EJB2做PetStore，再到用Struts，再到用Struts2/WebWork，再到用SpringMVC，乃至使用Rails。</p>
<p>“1年经验重复10遍”会每天反复操练EJB2，“八大菜系都吃过你也不是一个好厨子”会用JSP,Servlet,EJB2,Struts,PHP,C#.NET，“轮子爱好者”会看到Struts之后轮一个和Struts差不多的。但是真正优秀的程序员，能够改进Struts的不足，搞出WebWork，乃至Rails。这并不意味着你一定要很Fancy地去搞Google面试一样研究很多算法，也不需要你一定多熟悉编译原理，操作系统这样的底层技术，也不需要你18般武艺样样稀松地去看PHP和C#。你需要的是，在有了解决方案之后，仔细思考，真正理解问题域，寻求能够更好地满足问题域的解决方案，从细节上改进现有问题域的解决方案。这是来自我的教训，事实上，前面的三种陷阱我都荒废了不少时间，直到近两年，才愈发觉得无论是反复操练熟练工，还是18般武艺样样稀松的都会一些，甚或是轮一些别人轮过的轮子，都不是能让自己真正跨出成为顶尖程序员的一步。真正要解决好问题，交付出有价值的程序和框架，还是要回到问题域去。</p>
<p>这也是我喜欢Twitter技术团队以及推崇Nathan Marz的原因，无论是ElephantBird，Finagle，还是Storm，都不是庞然大物般的程序，而是贴近问题域，合理解决问题域的解决方案，也是从技术角度，希望自己能够在最近两年里能够达到的水准。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.xuwenhao.com/2012/04/20/go-back-to-question-domain/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>程序开发中的“人类容错性”——老兵不死</title>
		<link>http://www.xuwenhao.com/2012/03/19/human-fault-tolerance-in-big-data-processing/</link>
		<comments>http://www.xuwenhao.com/2012/03/19/human-fault-tolerance-in-big-data-processing/#comments</comments>
		<pubDate>Mon, 19 Mar 2012 13:38:24 +0000</pubDate>
		<dc:creator>Stanley Xu</dc:creator>
				<category><![CDATA[Idea]]></category>
		<category><![CDATA[Life]]></category>
		<category><![CDATA[Tech]]></category>

		<guid isPermaLink="false">http://www.xuwenhao.com/?p=867</guid>
		<description><![CDATA[周末得空，把前一阵买的MEAP版本的Big Data已经出了的两张给翻完了，觉得有点不划算，主要是内容之前在Nathan Marz的博客，以及Twitter发布出来的各类Slides里都已经看过了（话说Twitter去年年头上说Rainbird要开源到现在也是坑爹地没个影）。但是有一个新词儿还是让我觉得“心有戚戚焉”，把最近在Team里数据处理架构做的各种迁移工作的精髓给说出来了，就是这个Human Fault-Tolerance。 在这个人人都热衷于叫唤Big Data，讨论CAP理论的时候，Nathan同学一针见血地指出了一点，其实CAP也好，Cassandra的Dynamo模型也好，HBase的Big Table模型也好，看似非常酷非常好用，解决或者部分解决了各种一致性和可用性问题，但是其实对于Big Data处理的架构的最关键的一点，在于对于各种人类错误的容错性。 其实即使在没有海量数据需要处理的时候，各个程序也要考虑各种人类容错性。最简单的例子就在设计数据库的时候，对于删除操作大家都喜欢用个标记字段来标记删除，而不是真把记录删掉。类似的，在各种实时数据处理的事务里，除了普通的各种check和特殊情况考虑之外，通常有经验的程序员会做两件事情，一个是做日志，记录所有实时输入的日志，而是在整个处理的逻辑外面捕获所有的Exception，然后对Exception也会记录日志。做这些事情的原因是有这样一个假设，人会犯错，程序员会写出Bug。即使对程序做了充分的测试，但是当程序进入真实环境运行的时候，仍然会有你想不到的意外情况发生。当意外发生的时候，这些日志，记录能够帮助你把数据恢复到一个正常的状态下。记得在我工作的第一个年头里，就曾经花过一整天，将由于一个Bug引发的数据错误通过人肉SQL恢复过来。 当进入Big Data时代的时候，光光依靠简单的日志记录和人工恢复，已经不能够解决这些问题了。一天如果有个几条数据在几千条数据里面出错，也许你能够手工恢复过来；但是如果当一天的数据有几亿条，聚合后生成的数据记录也有几千条的时候，恐怕你就不能使用记录错误日志，然后人肉恢复的方式来解决问题了。而需要依靠在系统实现的架构层面来解决这些问题，Twitter推荐的实现方式就是让事实数据immutable，所以所有的数据都会记录，要看的数据是基于事实数据，计算出来的视图，非常简单粗暴，但是有效的方式。 话说回来，基本上，能不能写出Human Fault-Tolerance可以看做是一个程序员是否有充足的工业界工作经验的一条标准，这个不是依靠聪明和天赋能够解决的问题，而是完全依靠血泪教训得来的，从这个角度讲，老兵不死。虽然IT特别是互联网行业常常充斥着“30岁要转行，因为加班加不动了”，但是我向来是以为，有经验的工程师的价值始终被低估了。即使是不是Super Star的老工程师，也许光光写新功能写算法，未必比新人强出多少，但是这些血泪教训带来的经验，只要能够躲过一次问题，带来的价值也许就是一个工程师一两个月的工作量了（当然，无论如何记得，10年工作经验和1年工作经验重复10次的差别）。当然，更好地是团队能够拥有天才程序员，比你年轻比你聪明还比你身体好，比如Nathan Marz同学……]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.xuwenhao.com/wp-content/uploads/2012/03/true-meaning-of-no-fear.jpg"><img src="http://www.xuwenhao.com/wp-content/uploads/2012/03/true-meaning-of-no-fear.jpg" alt="" title="Old Soldier Never Die, They Just Fade Away" width="567" height="378" class="aligncenter size-full wp-image-871" /></a></p>
<p>周末得空，把前一阵买的MEAP版本的Big Data已经出了的两张给翻完了，觉得有点不划算，主要是内容之前在Nathan Marz的博客，以及Twitter发布出来的各类Slides里都已经看过了（话说Twitter去年年头上说Rainbird要开源到现在也是坑爹地没个影）。但是有一个新词儿还是让我觉得“心有戚戚焉”，把最近在Team里数据处理架构做的各种迁移工作的精髓给说出来了，就是这个Human Fault-Tolerance。</p>
<p>在这个人人都热衷于叫唤Big Data，讨论CAP理论的时候，Nathan同学一针见血地指出了一点，其实CAP也好，Cassandra的Dynamo模型也好，HBase的Big Table模型也好，看似非常酷非常好用，解决或者部分解决了各种一致性和可用性问题，但是其实对于Big Data处理的架构的最关键的一点，在于对于各种人类错误的容错性。</p>
<p>其实即使在没有海量数据需要处理的时候，各个程序也要考虑各种人类容错性。最简单的例子就在设计数据库的时候，对于删除操作大家都喜欢用个标记字段来标记删除，而不是真把记录删掉。类似的，在各种实时数据处理的事务里，除了普通的各种check和特殊情况考虑之外，通常有经验的程序员会做两件事情，一个是做日志，记录所有实时输入的日志，而是在整个处理的逻辑外面捕获所有的Exception，然后对Exception也会记录日志。做这些事情的原因是有这样一个假设，人会犯错，程序员会写出Bug。即使对程序做了充分的测试，但是当程序进入真实环境运行的时候，仍然会有你想不到的意外情况发生。当意外发生的时候，这些日志，记录能够帮助你把数据恢复到一个正常的状态下。记得在我工作的第一个年头里，就曾经花过一整天，将由于一个Bug引发的数据错误通过人肉SQL恢复过来。</p>
<p>当进入Big Data时代的时候，光光依靠简单的日志记录和人工恢复，已经不能够解决这些问题了。一天如果有个几条数据在几千条数据里面出错，也许你能够手工恢复过来；但是如果当一天的数据有几亿条，聚合后生成的数据记录也有几千条的时候，恐怕你就不能使用记录错误日志，然后人肉恢复的方式来解决问题了。而需要依靠在系统实现的架构层面来解决这些问题，Twitter推荐的实现方式就是让事实数据immutable，所以所有的数据都会记录，要看的数据是基于事实数据，计算出来的视图，非常简单粗暴，但是有效的方式。</p>
<p>话说回来，基本上，能不能写出Human Fault-Tolerance可以看做是一个程序员是否有充足的工业界工作经验的一条标准，这个不是依靠聪明和天赋能够解决的问题，而是完全依靠血泪教训得来的，从这个角度讲，老兵不死。虽然IT特别是互联网行业常常充斥着“30岁要转行，因为加班加不动了”，但是我向来是以为，有经验的工程师的价值始终被低估了。即使是不是Super Star的老工程师，也许光光写新功能写算法，未必比新人强出多少，但是这些血泪教训带来的经验，只要能够躲过一次问题，带来的价值也许就是一个工程师一两个月的工作量了（当然，无论如何记得，10年工作经验和1年工作经验重复10次的差别）。当然，更好地是团队能够拥有天才程序员，比你年轻比你聪明还比你身体好，比如Nathan Marz同学……</p>
]]></content:encoded>
			<wfw:commentRss>http://www.xuwenhao.com/2012/03/19/human-fault-tolerance-in-big-data-processing/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Some Missing Tips For Apache Thrift</title>
		<link>http://www.xuwenhao.com/2012/03/05/some-missing-tips-for-apache-thrift/</link>
		<comments>http://www.xuwenhao.com/2012/03/05/some-missing-tips-for-apache-thrift/#comments</comments>
		<pubDate>Mon, 05 Mar 2012 14:54:44 +0000</pubDate>
		<dc:creator>Stanley Xu</dc:creator>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[thrift]]></category>

		<guid isPermaLink="false">http://www.xuwenhao.com/?p=863</guid>
		<description><![CDATA[Thrift是个好东西，我们目前在内部大量使用thrift作为跨语言的数据交换方式，以及RPC的接口，thrift对于各种语言的支持都非常不错，不过Facebook对于thrift的文档实在是太少了。好在open source总是有人会把没有的东西给补上。这不，有人仿照google给protobuf的文档，在github上写了这么个东西——Thrift: The Missing Guide，不过看了一下，相对还是比较简单，其实Thrift还是有不少undocumented的功能，比如，可以给field设默认值，比如，thrift支持union。 给field设默认值很有用，主要是为了向后的版本兼容，大量的field会以optional出现，但是可能有默认值，如果需要在代码里逐一设置，既容易犯错，写起来也麻烦，设了默认值之后，就没有这个问题了，而且序列化的时候，默认值是不占空间的。 比如这样: namespace java com.xuwh.thrift struct Person { 1:required string firstName, 2:required string lastName, 3:optional bool fullTime = 1, 4:optional bool adult = 0 } union的这个功能我还是从著名的Nathan Marz那边看来的，好处是可以让一些互斥的field作为union出现，而不是有一堆堆optional的field，语义上也更加明确了，比如这样 namespace java com.xuwh.thrift struct Person { 1:required string firstName, 2:required string lastName, 3:optional bool fullTime = 1, 4:optional bool adult = 0 } [...]]]></description>
			<content:encoded><![CDATA[<p>Thrift是个好东西，我们目前在内部大量使用thrift作为跨语言的数据交换方式，以及RPC的接口，thrift对于各种语言的支持都非常不错，不过Facebook对于thrift的文档实在是太少了。好在open source总是有人会把没有的东西给补上。这不，有人仿照google给protobuf的文档，在github上写了这么个东西——<a href="http://diwakergupta.github.com/thrift-missing-guide/">Thrift: The Missing Guide</a>，不过看了一下，相对还是比较简单，其实Thrift还是有不少undocumented的功能，比如，可以给field设默认值，比如，thrift支持union。</p>
<p>给field设默认值很有用，主要是为了向后的版本兼容，大量的field会以optional出现，但是可能有默认值，如果需要在代码里逐一设置，既容易犯错，写起来也麻烦，设了默认值之后，就没有这个问题了，而且序列化的时候，默认值是不占空间的。</p>
<p>比如这样:</p>
<pre>
<code>
namespace java com.xuwh.thrift

struct Person {
  1:required string firstName,
  2:required string lastName,
  3:optional bool fullTime = 1,
  4:optional bool adult = 0
}
</code>
</pre>
<p>union的这个功能我还是从著名的Nathan Marz那边看来的，好处是可以让一些互斥的field作为union出现，而不是有一堆堆optional的field，语义上也更加明确了，比如这样</p>
<pre>
<code>
namespace java com.xuwh.thrift

struct Person {
  1:required string firstName,
  2:required string lastName,
  3:optional bool fullTime = 1,
  4:optional bool adult = 0
}

struct Organization {
  1:required string organizationName,
  2:required i32 numOfEmployee
}

union FoundationMember {
  1:required Person person,
  2:required Organization organization
}
</code>
</pre>
<p>很多open source的project的代码虽然看起来很简单，但是还是有不少好玩精巧的功能的，只是实在没有时间一一都琢磨过来。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.xuwenhao.com/2012/03/05/some-missing-tips-for-apache-thrift/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>永远买你能买得起的最好的生产工具</title>
		<link>http://www.xuwenhao.com/2012/02/06/buy-the-best-tools-you-could-afford/</link>
		<comments>http://www.xuwenhao.com/2012/02/06/buy-the-best-tools-you-could-afford/#comments</comments>
		<pubDate>Mon, 06 Feb 2012 13:36:52 +0000</pubDate>
		<dc:creator>Stanley Xu</dc:creator>
				<category><![CDATA[Idea]]></category>
		<category><![CDATA[Life]]></category>
		<category><![CDATA[Free]]></category>
		<category><![CDATA[Tools]]></category>

		<guid isPermaLink="false">http://www.xuwenhao.com/?p=853</guid>
		<description><![CDATA[今年过年之前，最终下定决心去签了一个联通的iPhone 4s，结果是……piu的一声，整个世界终于清净了，我再也不会为手机有任何烦恼了。买完之后我唯一后悔的是为什么没有早点买iPhone，而不是在过去几年里，受够了黑莓，魅族，Android，以及Veer的折磨。(同时，印证了我一贯相信的观点——“一分钱一分货，一毛钱两分货，一块钱三分货”。) 我不想去具体讨论究竟是Android好还是iPhone好，这种嘴仗浪费时间而且毫无意义，我只是发现自己不得不再次提醒一次自己，“永远去买你能买得起得最好的生产工具”。这里的生产工具，指的是你用来干活的软硬件，比如你的笔记本电脑，你的显示器，键盘(我的最爱是微软人体工学4000)，鼠标，椅子；或者一些必要的开发用软件(比如TextMate)或者各类辅助工具(比如Beyond Compare)。作为Joel Spolsky教教徒，所以我过去一直觉得这些是显而易见的道理，但是我发现其实我自己也常常犯因为价格原因而错误地购入很多二把刀类型的工具；而更加经常地发现的是，有不少程序员同志们，在2012仍然忍受着使用只有2G的内存的笔电当开发机。看到这么多聪明智慧的程序员们仍然在为了少花点钱，饱受各种糟烂的工具折磨，我不得不写下这样一篇Blog: 把你花在“生产工具”上的钱当成是投资，而不是开销。 所以重要的不是你需要从口袋里掏出多少钱，而是最后他们是否能够给你带来更多的价值。如果你仍然在用一台只有2G内存的笔记本电脑，意味着你每天至少要浪费1个小时在等待编译，等待IDE启动，等待Debug时候程序的运行，等待在IDE和浏览器之间切换，这进一步意味着，你或者每天需要比别人多工作1小时，或者每天少完成1/8的工作。如果你是一个Freelancer，这通常代表你只能挣更少的钱，而如果一个公司只能提供糟糕的生产工具，意味着他们其实在浪费钱在程序员身上，因为一个不错的程序员一个月的开销，足够买一套所有的最好的生产工具，而只要他在公司里呆满一年，从ROI的角度来说就是赚到了。想一想吧，真正优秀的大制作电影，现在一定会上3D和IMAX，虽然这意味着更高的成本，但是也会有更高的预期票房收益的，既然好的导演会用好的拍摄工具，如果你把自己当成一个优秀的程序员，显然你也应该想方设法使用最好的工具，它会给你带来更高的回报。 你花在“生产工具”上的钱，会被摊薄到每一天，所以其实它没有看起来那么贵。 如果你平均每块键盘用两年，那么即使一块1000块钱的Cherry机械键盘，比起Dell的基本款，也只让你每天多花了1块钱而已。1块钱同学1块钱，去全家买包面巾纸都要1块五了，你去上厕所的时候会为了省1块钱不用纸么？(更别提一块好的键盘使用的时间会比一块烂糟糟的键盘长得多)。而商业软件授权的成本的摊薄时间更长，一个TextMate的License可以用上5年，即使考虑到需要升级和更新换代，也可以使用3年或者更长。每天1块钱啊，算上各种软硬件开销，最多也就意味着每天10－15块钱，也就是一个月少下一次馆子的开销啊。 好的“生产工具”的确能够用来工作！ 就像当年的Winamp的Slogan一样，Most things actually work!。我用过不下10种Merge和Diff工具，没有一种能够像BeyondCompare那样真正算得上能用(所以我一直祈祷恳求BeyondCompare能够出一个Mac版)！而我过去5年来的手机使用历程就是一场灾难！上一款我觉得有法用的手机还是S60V2时代的Nokia 6630，之后历经黑莓8310，魅族M8，HTC Magic以及HP Veer，虽然看似每款都不贵，但是加在一起都够iPhone加两年套餐的钱了。黑莓没有服务，GPS巨慢，缺少软件；魅族M8则是一堆堆的Bug；HTC Magic则是反应很慢，升级系统刷机比升级公司的生产集群还麻烦；Veer也是个容易死机的机器。而我想我浪费在折腾这些手机上的时间都够我再去挣钱买个iPhone了，糟糕的工具其实并不便宜而是更浪费你宝贵的比钱更重要的时间以及原本美好的心情。 所以，无论如何，对自己好一点，买自己买得起的好工具，不要再为省钱浪费生命了。当然，也有很多好工具是免费的，好的工具不一定比差的贵，只是“免费”很多时候是一个陷阱，当你花了过多的精力在免费上，最后很有可能得不偿失的，特别是当你已婚已育的时候，有限的时间和精力是你最宝贵的财富。]]></description>
			<content:encoded><![CDATA[<p>今年过年之前，最终下定决心去签了一个联通的iPhone 4s，结果是……piu的一声，整个世界终于清净了，我再也不会为手机有任何烦恼了。买完之后我唯一后悔的是为什么没有早点买iPhone，而不是在过去几年里，受够了黑莓，魅族，Android，以及Veer的折磨。(同时，印证了我一贯相信的观点——“一分钱一分货，一毛钱两分货，一块钱三分货”。)</p>
<p>我不想去具体讨论究竟是Android好还是iPhone好，这种嘴仗浪费时间而且毫无意义，我只是发现自己不得不再次提醒一次自己，“永远去买你能买得起得最好的生产工具”。这里的生产工具，指的是你用来干活的软硬件，比如你的笔记本电脑，你的显示器，键盘(我的最爱是<a href="http://www.microsoft.com/hardware/en-us/p/natural-ergonomic-keyboard-4000" target="_blank">微软人体工学4000</a>)，鼠标，椅子；或者一些必要的开发用软件(比如<a href="http://macromates.com/" target="_blank">TextMate</a>)或者各类辅助工具(比如<a href="http://www.scootersoftware.com/" target="_blank">Beyond Compare</a>)。作为<a href="http://www.joelonsoftware.com" target="_blank">Joel Spolsky</a>教教徒，所以我过去一直觉得这些是显而易见的道理，但是我发现其实我自己也常常犯因为价格原因而错误地购入很多二把刀类型的工具；而更加经常地发现的是，有不少程序员同志们，在2012仍然忍受着使用只有2G的内存的笔电当开发机。看到这么多聪明智慧的程序员们仍然在为了少花点钱，饱受各种糟烂的工具折磨，我不得不写下这样一篇Blog:</p>
<ul>
<li><strong>把你花在“生产工具”上的钱当成是投资，而不是开销。</strong></li>
<p>所以重要的不是你需要从口袋里掏出多少钱，而是最后他们是否能够给你带来更多的价值。如果你仍然在用一台只有2G内存的笔记本电脑，意味着你每天至少要浪费1个小时在等待编译，等待IDE启动，等待Debug时候程序的运行，等待在IDE和浏览器之间切换，这进一步意味着，你或者每天需要比别人多工作1小时，或者每天少完成1/8的工作。如果你是一个Freelancer，这通常代表你只能挣更少的钱，而如果一个公司只能提供糟糕的生产工具，意味着他们其实在浪费钱在程序员身上，因为一个不错的程序员一个月的开销，足够买一套所有的最好的生产工具，而只要他在公司里呆满一年，从ROI的角度来说就是赚到了。想一想吧，真正优秀的大制作电影，现在一定会上3D和IMAX，虽然这意味着更高的成本，但是也会有更高的预期票房收益的，既然好的导演会用好的拍摄工具，如果你把自己当成一个优秀的程序员，显然你也应该想方设法使用最好的工具，它会给你带来更高的回报。</p>
<li><strong>你花在“生产工具”上的钱，会被摊薄到每一天，所以其实它没有看起来那么贵。</strong></li>
<p>如果你平均每块键盘用两年，那么即使一块1000块钱的Cherry机械键盘，比起Dell的基本款，也只让你每天多花了1块钱而已。1块钱同学1块钱，去全家买包面巾纸都要1块五了，你去上厕所的时候会为了省1块钱不用纸么？(更别提一块好的键盘使用的时间会比一块烂糟糟的键盘长得多)。而商业软件授权的成本的摊薄时间更长，一个TextMate的License可以用上5年，即使考虑到需要升级和更新换代，也可以使用3年或者更长。每天1块钱啊，算上各种软硬件开销，最多也就意味着每天10－15块钱，也就是一个月少下一次馆子的开销啊。</p>
<li><strong>好的“生产工具”的确能够用来工作！</strong></li>
<p>就像当年的Winamp的Slogan一样，<a href="http://www.joelonsoftware.com/articles/HighNotes.html" target="_blank">Most things actually work!</a>。我用过不下10种Merge和Diff工具，没有一种能够像BeyondCompare那样真正算得上能用(所以我一直祈祷恳求BeyondCompare能够出一个Mac版)！而我过去5年来的手机使用历程就是一场灾难！上一款我觉得有法用的手机还是S60V2时代的Nokia 6630，之后历经黑莓8310，魅族M8，HTC Magic以及HP Veer，虽然看似每款都不贵，但是加在一起都够iPhone加两年套餐的钱了。黑莓没有服务，GPS巨慢，缺少软件；魅族M8则是一堆堆的Bug；HTC Magic则是反应很慢，升级系统刷机比升级公司的生产集群还麻烦；Veer也是个容易死机的机器。而我想我浪费在折腾这些手机上的时间都够我再去挣钱买个iPhone了，糟糕的工具其实并不便宜而是更浪费你宝贵的比钱更重要的时间以及原本美好的心情。
</ul>
<p>所以，无论如何，对自己好一点，买自己买得起的好工具，不要再为省钱浪费生命了。当然，也有很多好工具是免费的，好的工具不一定比差的贵，只是“免费”很多时候是一个陷阱，当你花了过多的精力在免费上，最后很有可能得不偿失的，特别是当你已婚已育的时候，有限的时间和精力是你最宝贵的财富。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.xuwenhao.com/2012/02/06/buy-the-best-tools-you-could-afford/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Hadoop背后的数学</title>
		<link>http://www.xuwenhao.com/2012/01/26/the-mathematics-behind-hadoop-based-systems/</link>
		<comments>http://www.xuwenhao.com/2012/01/26/the-mathematics-behind-hadoop-based-systems/#comments</comments>
		<pubDate>Thu, 26 Jan 2012 12:53:30 +0000</pubDate>
		<dc:creator>Stanley Xu</dc:creator>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[Work]]></category>
		<category><![CDATA[Hadoop]]></category>
		<category><![CDATA[Math]]></category>

		<guid isPermaLink="false">http://www.xuwenhao.com/?p=828</guid>
		<description><![CDATA[自从Nathan Marz同学写了那篇著名的How to beat the CAP theorem的Blog，以及Storm发布之后，俨然成为了技术界新偶像。顺着他本人的blog，翻了一下他过去几年的写的技术文章，发现老美的牛人们都爱总结，能够把技术实践提升到理论高度，然后抽象出新的设计和产品，比起我等只能每天苦逼苦逼应对实际需求的人来说，还是强出很多。我自己觉得那么多年，虽然觉得做什么都能做了，但是现在还是只能谈到模仿，做不到提炼总结和超越。 和著名的CAP的那篇Blog，Nathan Marz还有很多其他非常有料值得一读的博客，与其在国内的各种Hadoop大会上听大家泛泛而谈架构，还不如多看看老外们总结下来的技术博呢，比如这篇The mathematics behind Hadoop-based systems，比起大家简单列列机器数字来说，有价值得多。 我曾经写过，数学对于称为一名优秀的程序员是很重要的，但这不一定意味着一定要是多高深的数学。Nathan的这篇Blog用到的数学只有初中难度，但是的确写明白了我们遇到的很多Estimation以及集群数量预估的实际问题，我想一定也有很多人用hadoop但是和我们一样，对于很多机器数量或者workflow的管理是很粗放的，相信这篇blog对很多人都会有用，所以把它翻译成中文，全文如下 基于Hadoop的系统背后的数学 我希望一年之前我就知道这些。现在，根据一些简单的数学，我就可以回答： 为什么在我将处理能力翻倍之后，我的workflow的速度没有翻倍？ 为什么10%的任务失败率会导致我的运行时间上升到原来的300%？ 如果通过优化了我的workflow的运行时间的30%导致运行时间下降了80%？ 我的集群中到底需要多少机器可以满足性能和容错的需要？ 所有这些问题都可以通过这样一个简单的等式干净地回答： 运行时间(Runtime) = 额外开销(Overhead) / (1-{处理一小时数据需要的时间}) 我们很快就可以推导出这个等式。首先，让我们简单地讨论一下什么是我所说的“基于Hadoop的系统”1。Hadoop的一个常见的用例，就是通过运行一个workflow来处理来连续进入的流数据。这个工作流运行一个&#8221;while(true)&#8221;的循环，然后每个workflow的迭代，都处理自从上个迭代依赖累积的数据。 下面的这些分析的灵感可以在一个简单的示例中概括出来。假如说你有一个workflow需要运行12小时，然后它会在每个迭代中处理12个小时的数据。然后假如说你加强了这个workflow去做一些额外的分析，然后你估计你在当前的这个workflow中需要多花两个小时来处理。然后麻烦来了。你的workflow增加的运行时间可能远超过两小时。它可能增加了10个小时，100个小时，或者这个workflow可能呈螺旋式上升地在每个迭代中花费越来越多的时间知道无限。 为什么？ 问题在于，你将处理12个小时数据的workflow的运行时间增加到了14个小时。这意味着当下一次workflow运行的时候，有14小时的数据需要处理。既然下一个迭代有更多的数据，他要花费更多时间运行。这意味着下一个迭代会有更多的数据，等等。 为了确定什么时候运行时间，让我们做一些简单的算术。首先，让我们写下一个只有一个迭代的workflow的运行时间的等式 运行时间 = 额外开销 + {处理一小时数据的时间} * {多少小时的数据} 额外开销(Overhead)指的是花费在workflow上的任何常数项时间。例如，开始一个job需要的时间会计入额外开销。使用distributed cache来分发文件的时间会计入额外开销。你会把任何独立于数据规模的时间花费放到“额外开销”的分类中去。 “处理一小时数据的时间”指的是workflow中的动态时间。这是你忽视那些额外开销，花费在处理实际数据上的时间。如何一小时的数据会增加你半小时的运行时间上，这个值应该是0.5。如果一小时的数据会增加你一小时的运行时间，这是值就是2。 为了简洁，让我们把上面那个等式通过变量来重新写一下： T = O + P * H 为了确定workflow的稳定的运行时间，我们需要找到workflow的运行时间在哪个点上正好等于累积了的需要处理的数据量。为了做这个，我们可以简单地插入 T=H 来求解T: T = O [...]]]></description>
			<content:encoded><![CDATA[<p>自从<a href="http://nathanmarz.com/" target="_blank">Nathan Marz</a>同学写了那篇著名的<a href="http://nathanmarz.com/blog/how-to-beat-the-cap-theorem.html" target="_blank">How to beat the CAP theorem</a>的Blog，以及<a href="https://github.com/nathanmarz/storm" target="_blank">Storm</a>发布之后，俨然成为了技术界新偶像。顺着他本人的blog，翻了一下他过去几年的写的技术文章，发现老美的牛人们都爱总结，能够把技术实践提升到理论高度，然后抽象出新的设计和产品，比起我等只能每天苦逼苦逼应对实际需求的人来说，还是强出很多。我自己觉得那么多年，虽然觉得做什么都能做了，但是现在还是只能谈到模仿，做不到提炼总结和超越。</p>
<p>和著名的CAP的那篇Blog，Nathan Marz还有很多其他非常有料值得一读的博客，与其在国内的各种Hadoop大会上听大家泛泛而谈架构，还不如多看看老外们总结下来的技术博呢，比如这篇<a href="http://nathanmarz.com/blog/the-mathematics-behind-hadoop-based-systems.html" target="_blank">The mathematics behind Hadoop-based systems</a>，比起大家简单列列机器数字来说，有价值得多。</p>
<p>我曾经写过，<a href="http://www.xuwenhao.com/2011/02/01/how-import-is-math-for-a-programmer/" target="_blank">数学对于称为一名优秀的程序员是很重要的</a>，但这不一定意味着一定要是多高深的数学。Nathan的这篇Blog用到的数学只有初中难度，但是的确写明白了我们遇到的很多Estimation以及集群数量预估的实际问题，我想一定也有很多人用hadoop但是和我们一样，对于很多机器数量或者workflow的管理是很粗放的，相信这篇blog对很多人都会有用，所以把它翻译成中文，全文如下</p>
<hr />
<h2><a href="http://nathanmarz.com/blog/the-mathematics-behind-hadoop-based-systems.html" target="_blank">基于Hadoop的系统背后的数学</a></h2>
<p>我希望一年之前我就知道这些。现在，根据一些简单的数学，我就可以回答：</p>
<ul>
<li>为什么在我将处理能力翻倍之后，我的workflow的速度没有翻倍？</li>
<li>为什么10%的任务失败率会导致我的运行时间上升到原来的300%？</li>
<li>如果通过优化了我的workflow的运行时间的30%导致运行时间下降了80%？</li>
<li>我的集群中到底需要多少机器可以满足性能和容错的需要？</li>
</ul>
<p>所有这些问题都可以通过这样一个简单的等式干净地回答：</p>
<pre>
运行时间(Runtime) = 额外开销(Overhead) / (1-{处理一小时数据需要的时间})
</pre>
<p>我们很快就可以推导出这个等式。首先，让我们简单地讨论一下什么是我所说的“基于Hadoop的系统”<sup><a href="#sup1">1</a></sup>。Hadoop的一个常见的用例，就是通过运行一个workflow来处理来连续进入的流数据。这个工作流运行一个&#8221;while(true)&#8221;的循环，然后每个workflow的迭代，都处理自从上个迭代依赖累积的数据。</p>
<p>下面的这些分析的灵感可以在一个简单的示例中概括出来。假如说你有一个workflow需要运行12小时，然后它会在每个迭代中处理12个小时的数据。然后假如说你加强了这个workflow去做一些额外的分析，然后你估计你在当前的这个workflow中需要多花两个小时来处理。然后麻烦来了。你的workflow增加的运行时间可能远超过两小时。它可能增加了10个小时，100个小时，或者这个workflow可能呈螺旋式上升地在每个迭代中花费越来越多的时间知道无限。</p>
<p>为什么？</p>
<p>问题在于，你将处理12个小时数据的workflow的运行时间增加到了14个小时。这意味着当下一次workflow运行的时候，有14小时的数据需要处理。既然下一个迭代有更多的数据，他要花费更多时间运行。这意味着下一个迭代会有<strong>更多</strong>的数据，等等。</p>
<p>为了确定什么时候运行时间，让我们做一些简单的算术。首先，让我们写下一个只有一个迭代的workflow的运行时间的等式</p>
<pre>
运行时间 = 额外开销 + {处理一小时数据的时间} * {多少小时的数据}
</pre>
<p>额外开销(Overhead)指的是花费在workflow上的任何常数项时间。例如，开始一个job需要的时间会计入额外开销。使用distributed cache来分发文件的时间会计入额外开销。你会把任何独立于数据规模的时间花费放到“额外开销”的分类中去。</p>
<p>“处理一小时数据的时间”指的是workflow中的动态时间。这是你忽视那些额外开销，花费在处理实际数据上的时间。如何一小时的数据会增加你半小时的运行时间上，这个值应该是0.5。如果一小时的数据会增加你一小时的运行时间，这是值就是2。</p>
<p>为了简洁，让我们把上面那个等式通过变量来重新写一下：</p>
<pre>
T = O + P * H
</pre>
<p>为了确定workflow的稳定的运行时间，我们需要找到workflow的运行时间在哪个点上正好等于累积了的需要处理的数据量。为了做这个，我们可以简单地插入 T=H 来求解T:</p>
<pre>
T = O + P * T
T = O / (1 - P)
</pre>
<p>这就是我之前展示的等式。你可以看到，一个workflow的稳定的运行时间是和workflow中的额外开销呈线性比例的。所以如果你可以将额外开销减少25%，那么你的workflow运行时间就会减少25%。然而，一个workflow的稳定运行时间和动态处理的速率“P”不是呈线性比例的。这背后的隐含含义就是每为集群加入一台机器带来的性能提升是在减少的。</p>
<p>通过这个等式，我们可以回答我在文章开始时候写下的问题了。让我们一起来过一些这些问题：</p>
<h3>为什么在我将处理能力翻倍之后，我的workflow的速度没有翻倍？</h3>
<p>将你的机器数翻倍，会将你的“处理一小时数据需要的时间”减少50%<sup><a href="#sup2">2</a></sup>。这个的效果和你的运行时间的关系是完全依赖于之前的P值的。让我们用数学来展示一下。假如说你的workflow在集群的机器数量翻倍之前的运行时间是“T1”，翻倍之后是“T2”。这给了我们两个等式：</p>
<pre>
T1 = O / (1-P)
T2 = O / (1 - P/2)
</pre>
<p>那么性能加速就会是 T2/T2，新的运行时间和旧的运行时间的比值。这给到我们</p>
<pre>
T2 / T1 = (1 - P) / (1 - P/2)
T2 / T1 = 1 - P / (2 - P)
</pre>
<p>对这个式子作图，我们可以得到如下的图，其中原始的P在x轴上，性能加速在y轴<sup><a href="#sup3">3</a></sup>上：</p>
<p><img src="http://s3.media.squarespace.com/production/621062/7280691/blog/wp-content/uploads/2009/12/Screen-shot-2009-12-27-at-5.06.54-PM1.png" alt="" /></p>
<p>这个图说明了一切。如果你的P非常高，比如说，需要54分钟来处理一小时的数据，那么将你的集群数量翻倍会使得你新的运行时间是原来的18%，足足有82%的性能加速！这是一个非常违背直觉的结论 —— 我强烈推荐读者们仔细思考这种情况出现的背后的机制。</p>
<p>然后，如果你之前的P没有那么高（例如，需要6分钟的动态运行时间来处理1小时的数据），那么将集群数量翻倍对于运行时间几乎没有效果 —— 可能只有类似6%。由于运行时间被额外开销所主导，这是很合乎情理的，动态运行时间在运行时间中占得很小。</p>
<h3>为什么10%的任务失败率会导致我的运行时间上升到原来的300%？</h3>
<p>这个问题解释了<strong>workflow稳定性</strong>的属性。在一个大集群中，你总是会有不同的机器故障，所以任务失败率的峰值不会干掉mission critical系统的性能是非常重要的。关于这个问题的分析会和上一个问题看起来非常相似，除了我们会将动态运行时间变差而不是提高它之外。10%的任务失败率意味着我们需要多运行11%的任务来处理完我们的数据<sup><a href="#sup4">4</a></sup>。由于任务依赖于我们所拥有的数据量，这意味着，我们的“处理一小时数据需要的时间”会上升11%。类似于上一个问题，让我们将T1作为没有任务失败所需要的运行时间，T2作为有任务失败的运行时间</p>
<pre>
T1 = O / (1 - P)
T2 = O / (1 - 1.11*P)
T2 / T1 = (1 - P) / (1 - 1.11*P)
</pre>
<p>对此作图，我们得到：</p>
<p><img src="http://s3.media.squarespace.com/production/621062/7280691/blog/wp-content/uploads/2009/12/Screen-shot-2009-12-27-at-5.34.41-PM.png" alt="" width="95%" /></p>
<p><small><br />
(译著: 上图中X轴为P值，Y轴为花费时间增加的比例)<br />
</small></p>
<p>你可以看到，任务失败对于运行时间的影响在你的集群有“额外容量”减少的情况下戏剧性地增长。所以让保持你的P低是非常重要的。我们可以看到你的P越高，由于任务失败率的增加，你就更有可能进入“毁灭循环”的风险<sup><a href="#sup5">5</a></sup>。</p>
<h3>如果通过优化掉我的workflow的运行时间的30%而导致运行时间下降了80%？</h3>
<p>这个问题是使得我真正找出workflow的运行时间的模型。我曾在一个workflow中有一个荒谬的瓶颈，导致了大概10小时的额外开销<sup><a href="sup6">6</a></sup>，然后整个workflow的运行时间大概是30小时。在我优化了这个瓶颈(大约占据了30%的运行时间)之后，运行时间像石头一样坠落，最终稳定在6小时(减少了80%)。使用我们的模型，我们可以确定为什么这发生了：</p>
<pre>
30 = O / (1 - P)
6 = (O - 10) / (1 - P)
O = 12.5, P = 0.58
</pre>
<p>所以那10小时，占据了workflow中的80%的额外开销，这解释了整个的性能提升。</p>
<h3>我的集群中到底需要多少机器可以满足性能和容错的需要？</h3>
<p>这基本上是一个费效比分析的练习。我们可以看到，通过增加集群中机器数据来提高性能到回报在减少，而一旦P(“处理一小时数据需要的时间”)下降到30分钟以下(0.5)，通过增加机器获得的性能提升是次线性的<sup><a href="#sup7">7</a></sup>。我们也同样看到将P保持得低是很重要得，不然任务失败的增加或者其他的任务使用集群，会严重影响你的运行时间。所以，你需要运行一些数据来确定对你的应用最佳的机器数量<sup><a href="#sup8">8</a></sup>。</p>
<p>你应该在Twitter上follow<a href="http://twitter.com/nathanmarz" target="_blank">我</a>。</p>
<p>更新：看看<a href="http://nathanmarz.com/blog/hadoop-math-followup-measurement/" target="_blank">本文的后续内容</a></p>
<hr />
<p><small><br />
<sup id="sup1">1</sup> 事实上，这个等式适用于任何批量处理连续数据流的系统。<br />
<sup id="sup2">2</sup> 这里假设你的处理是完全分布式的，并且没有持有任何中心点，这对于一个基于Hadoop的workflow来说通常是真的。一个可能的例外是，你所有的tasks都通过一个中心的数据库进行通信。事实上，增加更多的机器会在额外开销(更多的机器去处理)以及数据处理速率(mapper需要将数据分发到更多的reducer中去)有少量的不利影响。对于这个分析的目的来说，我们可以忽略这些。<br />
<sup id="sup3">3</sup> 该图通过<a href="http://www.fooplot.com/" target="_blank">FooPlot</a>生成。<br />
<sup id="sup4">4</sup> 比如说我们通过100个task来处理数据，现在，当你运行这些task的时候，其中有10个会失败。当你重新运行这10个的时候，9个会成功，还有1一个会失败。所以你实际运行了111个task而不是100个，这意味着task的数量增加了11%。<br />
<sup id="sup5">5</sup> 或者其他的运行在集群上的东西，比如一次性的查询或者其他的workflow。<br />
<sup id="sup6">6</sup> 这是由于Berkeley DB在ext3的文件系统上会生成很多碎片。<br />
<sup id="sup7">7</sup> 事实上，我没有展示这个，但是你可以通过模型来自己推导。我把这个作为一个练习留给读者。<br />
<sup id="sup8">8</sup> 如果你需要的话，你可以让这个模型变得更加全面。比如，这个模型没有区分新进入的数据和已经存在需要被查询的数据(并且在每个迭代中都会增加)。这个变量必然会影响到你的长期扩展需求，记住它是非常重要的。对于那些知识对于这些workflow的性能有获得一个直觉的目的来说，这不是必须的。<br />
</small> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.xuwenhao.com/2012/01/26/the-mathematics-behind-hadoop-based-systems/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Yet Another Year</title>
		<link>http://www.xuwenhao.com/2012/01/22/yet-another-year/</link>
		<comments>http://www.xuwenhao.com/2012/01/22/yet-another-year/#comments</comments>
		<pubDate>Sun, 22 Jan 2012 07:45:00 +0000</pubDate>
		<dc:creator>Stanley Xu</dc:creator>
				<category><![CDATA[Life]]></category>

		<guid isPermaLink="false">http://www.xuwenhao.com/?p=823</guid>
		<description><![CDATA[又是超快的一年过去了，特别是从7月份开始，都觉得没有怎么喘气，一下子就2012了，翻了一下去年的新年愿望，发现完成度依然很低啊，但是其实过去这一年收获很大，在多年觉得自己没有太大成长之后，又有了升级涨经验值的感觉，在30之前再次找到这种感觉，还算是很不错的。 去年对于今年设想中，除了给Mahout打了几个超级简单的Patch之外和飞的海南过了个周末之外，其余都没有达成，生活变化得太快。忽然又开始重新承担技术管理者的角色，于是对于自身技术研究的很多设想只好放下不少，其实到现在我也还会有点怀疑回到管理者角色而不是专心写代码对我究竟是合适还是不合适，但是被逼着同时run好几个项目和模块反而在这上面重新有了不少的成长。负面效应是，集中思考记忆的能力大大下降，以前一天看个一两百页英文技术书籍不成问题，最近看个十页精神就集中不起来了，这个需要自己好好调整一下了。 想看的技术书籍没有一本看完的，SICP没动，PRML只是少量温习了去年看过的一部分，POSA完全没看，不过现在反而觉得POSA没有必要看了。但是还是一贯漫无目的的看了一些其他的，Mahout In Action看了半本，不准备接着看完，Manning的In Action系列也没有必要预先看。DSL看了一半，有点Boring，目前看到的都是我知道的内容，但是从来没有整理过知识体系，The Joy Of Clojure看了个开头。今年所有的成长感都来自&#8221;Learning By Doing&#8221;，唯一和工作相关性比较大的书是Behind The Closed Door，让自己重新找回了点感觉。 如果说每年学一门新的编程语言的话，今年能勉强算得上的就是Pig这门DSL了，相当好用啊。明年的话，应该是尝试用点Clojure，继续多用用Ruby，少用用“新时代的汇编语言”Java。 新的一年，有一些过去的目标要放弃，我自己可不是什么天才，新的一年里，争取翻一遍PRML吧，不敢说看完了，其他的，看到哪里算哪里，The Joy of Clojure估计可以轻松看完，其余的预计也抽不出太多时间。另外，争取每两周写一篇Blog吧，除了类似新年这种事情，不写生活类了，多做点有实际价值的东西吧。 对于工作，很高兴和很多超级聪明勤奋的人一起工作，希望今年能真真正正用技术手段帮公司多挣到一点钱。希望团队里的同学们都能觉得每天来上班是高兴的一件事情，少点由于我的混乱带来的加班，多点让人兴奋的新系统，新模型，新Feature带来的效果。 过去一年比较糟糕的是，忽然开始有白发，长了10斤肉到肚子上，真的要开始锻炼了，不然蹦跶不了几年了。要去把已经过期了的护照和港澳通行证办好，无论如何带儿子去趟香港，少上网，少上微博，多读书，多走动，多运动，多思考。 去年说不再多花钱在电子产品上的，但是最终还是年前签了个iPhone，然后瞬间安逸了，明年真的没有什么可买的了，把买来的书都看看完吧。 最后，祝福某两人啊，很为你们感到高兴:-)。]]></description>
			<content:encoded><![CDATA[<p>又是超快的一年过去了，特别是从7月份开始，都觉得没有怎么喘气，一下子就2012了，翻了一下去年的<a href="http://www.xuwenhao.com/2011/02/01/wishes-for-the-rabbit-year/" target="_blank">新年愿望</a>，发现完成度依然很低啊，但是其实过去这一年收获很大，在多年觉得自己没有太大成长之后，又有了升级涨经验值的感觉，在30之前再次找到这种感觉，还算是很不错的。</p>
<p>去年对于今年设想中，除了给Mahout打了几个超级简单的Patch之外和飞的海南过了个周末之外，其余都没有达成，生活变化得太快。忽然又开始重新承担技术管理者的角色，于是对于自身技术研究的很多设想只好放下不少，其实到现在我也还会有点怀疑回到管理者角色而不是专心写代码对我究竟是合适还是不合适，但是被逼着同时run好几个项目和模块反而在这上面重新有了不少的成长。负面效应是，集中思考记忆的能力大大下降，以前一天看个一两百页英文技术书籍不成问题，最近看个十页精神就集中不起来了，这个需要自己好好调整一下了。</p>
<p>想看的技术书籍没有一本看完的，SICP没动，PRML只是少量温习了去年看过的一部分，POSA完全没看，不过现在反而觉得POSA没有必要看了。但是还是一贯漫无目的的看了一些其他的，Mahout In Action看了半本，不准备接着看完，Manning的In Action系列也没有必要预先看。DSL看了一半，有点Boring，目前看到的都是我知道的内容，但是从来没有整理过知识体系，The Joy Of Clojure看了个开头。今年所有的成长感都来自&#8221;Learning By Doing&#8221;，唯一和工作相关性比较大的书是Behind The Closed Door，让自己重新找回了点感觉。</p>
<p>如果说每年学一门新的编程语言的话，今年能勉强算得上的就是Pig这门DSL了，相当好用啊。明年的话，应该是尝试用点Clojure，继续多用用Ruby，少用用“新时代的汇编语言”Java。</p>
<p>新的一年，有一些过去的目标要放弃，我自己可不是什么天才，新的一年里，争取翻一遍PRML吧，不敢说看完了，其他的，看到哪里算哪里，The Joy of Clojure估计可以轻松看完，其余的预计也抽不出太多时间。另外，争取每两周写一篇Blog吧，除了类似新年这种事情，不写生活类了，多做点有实际价值的东西吧。</p>
<p>对于工作，很高兴和很多超级聪明勤奋的人一起工作，希望今年能真真正正用技术手段帮公司多挣到一点钱。希望团队里的同学们都能觉得每天来上班是高兴的一件事情，少点由于我的混乱带来的加班，多点让人兴奋的新系统，新模型，新Feature带来的效果。</p>
<p>过去一年比较糟糕的是，忽然开始有白发，长了10斤肉到肚子上，真的要开始锻炼了，不然蹦跶不了几年了。要去把已经过期了的护照和港澳通行证办好，无论如何带儿子去趟香港，少上网，少上微博，多读书，多走动，多运动，多思考。</p>
<p>去年说不再多花钱在电子产品上的，但是最终还是年前签了个iPhone，然后瞬间安逸了，明年真的没有什么可买的了，把买来的书都看看完吧。</p>
<p>最后，祝福某两人啊，很为你们感到高兴:-)。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.xuwenhao.com/2012/01/22/yet-another-year/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>运营一个系统比开发一个系统更重要</title>
		<link>http://www.xuwenhao.com/2012/01/22/operate-a-system-is-more-important-than-develop-a-syste/</link>
		<comments>http://www.xuwenhao.com/2012/01/22/operate-a-system-is-more-important-than-develop-a-syste/#comments</comments>
		<pubDate>Sun, 22 Jan 2012 04:21:36 +0000</pubDate>
		<dc:creator>Stanley Xu</dc:creator>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[Machine Learning]]></category>
		<category><![CDATA[quora]]></category>

		<guid isPermaLink="false">http://www.xuwenhao.com/?p=815</guid>
		<description><![CDATA[互联网公司和软件公司最大的不同在于，即使对于技术团队来说，开发工作也只是一小部分工作，如何使得整个系统运营起来，才是重头戏，这是过去一年感悟最深的一点；而对于像广告质量这样的技术团队来说，运营和开发可以说是完全不可分离的。过去一年，在这点上，走了很多弯路，犯了很多错误，有很多可以总结的地方。从Quora上看到这样一个问题，“What are the keys to operationalizing a machine learning ranking system from an organization / engineering management point of view?” 觉得唯一的一个回答就很好，翻译一下以记之，虽然做不到信达雅，但是基本意思应该能描述对。 这个问题的大概内容是这样的: 如果从组织管理/工程管理的角度来看，什么是将一个机器学习的Ranking系统运营起来的关键点？ 对于那些有基于机器学习或者其他方式有Ranking系统的组织，可以保证他们运行平稳，并且随着时间的推移慢慢进步？哪些监控是重要的？如何定义目标，目标由谁来定义？如何分辨效果的提升来自于Feature工程团队还是核心算法上的提升？哪些严重依赖于Ranking的组织如何为这些来构造他们的流程? 目前唯一可见的回答，来自前Google的工程师Brandon Ballinger: 我之前在Google做语音识别和广告，这两者都以机器学习作为他们的核心。下面是我从“野外”学到的如何运营一个机器学习系统的一些重要的经验和教训 将你的成功的指标定义为让用户高兴。传统的精确性的指标，比如precision, square error, ROC等等并不能捕捉到那些你真正关心的——用户对于你的模型是如何反应的。例如，如果你运营一个广告系统，你的指标应该是每个PV的收入以及点击率。完全有可能，由于辛普森悖论，你有一个error rate减少了的模型，但是他带来的收入却降低了。 核心指标下降是很严重的问题。你需要把核心指标的大幅下降当成和一个服务器当机或者数据库中数据损坏一样严重的问题。Oncall的人需要尝试尽快诊断问题，并且必要时把别人拉进来一起解决问题 对每次Model的Launch做A/B测试。你应当始终并行运行两个模型，给不同的用于用不同的模型，然后比较用户行为。这是唯一可以确保你知道你在做正确的事情的办法。 小心丑小鸭效应。机器学习系统会在从自己的错误中学习的过程中变得更加准确。这意味着，新的模型有一个与生固来的缺陷：你的历史训练数据包含着过去模型中的错误，但不是你新训练的模型的错误。导致你的新模型一开始可能像一个丑小鸭，但是如果你用他来决策用户看到的内容，他最后会变成一个漂亮的天鹅。你可以通过将一小部分流量切给新模型，来部分抵消丑小鸭效应，然后慢慢随时间提高这个百分比。 使得算法对于噪声Feature健壮。类似于L1 regularization这样的技术可以使得你的机器学习算法对Feature进行剪枝，修剪掉那些对于预测的准确性贡献很小的Feature。这可以帮助你很好地拆分你的团队：一些人专注于算法，另一些人写Feature喂给算法。那些寻找Feature的人，可以直接“把东西扔进锅里”，然后让算法找出他们究竟好还是不好。（类似的，你应该通过确保合理的收敛性来选择一个算法） 你可以部分地将架构和算法团队解耦合。基本上，大部分机器学习算法都是在累计一个分布式的hash table的统计信息，然后将这些统计信息合并成一个分数。开发一个分布式的hash table是和开发一个用于累计的算法不同的任务，可以由不同的子Team完成。然后，让这些人一起工作仍然是很重要的。例如，一些算法在写入和写入可用之前延时的“最终一致”的系统中（例如Dynamo），会有所波动。所以这只是一个部分解耦合，你仍然需要团队中有连接架构和算法的“桥梁”人员。 在在线系统和批处理系统之间选择的时候要小心。一个在线系统可以实时学习，对于新的用户行为，可以在发生之后的几分钟内有所反应。但是这回带来巨大的开销，一个在线系统需要2-3倍的时间区开发和维护，而且他对瞬间的变化更加敏感。举个例子，如果你突然接收到了很多垃圾信息，这些噪声会立刻被吸收进你的系统并且开始降低用户的体验。类似的，一台机器如果没有可运行的内容了，如果网络连接中断了，或者一个特定的机器变慢了（导致Feature“歪了”），模型的某个输入开始生产垃圾，等等。 为所有东西打上版本。一个训练过的模型依赖于稳定的标识，如果你更改了某个标识，模型立刻就过时了。例如，如果你将用户的语言(&#8220;en-us&#8221;)作为一个feature。那么当有些人提交了一个一行的修改，用下划线替换了短横线(&#8220;en_us&#8221;)。这使得模型立刻“忘记”了所有从&#8221;en-us&#8221;中学到的，使得所有的语言看起来都是一样的。所以为所有会在你模型中生成标识的代码和数据的变更都打上版本。 你需要咬碎100-1000倍于实时的数据。如果你的训练数据来自于整整一年的历史数据，然后你的学习过程是10倍于实时，那他需要一个月来测试一个新Feature。把所有的东西都写成Map-Reduce或者Storm Topology使得你可以在数据变得足够大的时候仍然可以扩展。 看了一下，里面有不少错误我们都犯过，包括过去一个Q我们觉得由于团队小应该快点冲而省略掉的东西，现在看来也还是省略不掉的，而之前做对的部分也都是来自老大们的经验，希望今年少走弯路效果好啊。]]></description>
			<content:encoded><![CDATA[<p>互联网公司和软件公司最大的不同在于，即使对于技术团队来说，开发工作也只是一小部分工作，如何使得整个系统运营起来，才是重头戏，这是过去一年感悟最深的一点；而对于像广告质量这样的技术团队来说，运营和开发可以说是完全不可分离的。过去一年，在这点上，走了很多弯路，犯了很多错误，有很多可以总结的地方。从Quora上看到这样一个问题，<a href="http://www.quora.com/What-are-the-keys-to-operationalizing-a-machine-learning-ranking-system-from-an-organization-engineering-management-point-of-view" target="_blank">“What are the keys to operationalizing a machine learning ranking system from an organization / engineering management point of view?”</a></p>
<p>觉得唯一的一个回答就很好，翻译一下以记之，虽然做不到信达雅，但是基本意思应该能描述对。</p>
<p>这个问题的大概内容是这样的:</p>
<hr />
如果从组织管理/工程管理的角度来看，什么是将一个机器学习的Ranking系统运营起来的关键点？<br />
对于那些有基于机器学习或者其他方式有Ranking系统的组织，可以保证他们运行平稳，并且随着时间的推移慢慢进步？哪些监控是重要的？如何定义目标，目标由谁来定义？如何分辨效果的提升来自于Feature工程团队还是核心算法上的提升？哪些严重依赖于Ranking的组织如何为这些来构造他们的流程?</p>
<hr />
目前唯一可见的回答，来自前Google的工程师<a href="http://www.quora.com/Brandon-Ballinger" target="_blank">Brandon Ballinger</a>:</p>
<hr />
我之前在Google做语音识别和广告，这两者都以机器学习作为他们的核心。下面是我从“野外”学到的如何运营一个机器学习系统的一些重要的经验和教训</p>
<ul>
<li><strong>将你的成功的指标定义为让用户高兴。</strong>传统的精确性的指标，比如precision, square error, ROC等等并不能捕捉到那些你真正关心的——用户对于你的模型是如何反应的。例如，如果你运营一个广告系统，你的指标应该是每个PV的收入以及点击率。完全有可能，由于<a href="http://en.wikipedia.org/wiki/Simpson's_paradox" target="_blank">辛普森悖论</a>，你有一个error rate减少了的模型，但是他带来的收入却降低了。</li>
<li><strong>核心指标下降是很严重的问题。</strong>你需要把核心指标的大幅下降当成和一个服务器当机或者数据库中数据损坏一样严重的问题。Oncall的人需要尝试尽快诊断问题，并且必要时把别人拉进来一起解决问题</li>
<li><strong>对每次Model的Launch做A/B测试。</strong>你应当始终并行运行两个模型，给不同的用于用不同的模型，然后比较用户行为。这是唯一可以确保你知道你在做正确的事情的办法。</li>
<li><strong>小心丑小鸭效应。</strong>机器学习系统会在从自己的错误中学习的过程中变得更加准确。这意味着，新的模型有一个与生固来的缺陷：你的历史训练数据包含着过去模型中的错误，但不是你新训练的模型的错误。导致你的新模型一开始可能像一个丑小鸭，但是如果你用他来决策用户看到的内容，他最后会变成一个漂亮的天鹅。你可以通过将一小部分流量切给新模型，来部分抵消丑小鸭效应，然后慢慢随时间提高这个百分比。</li>
<li><strong>使得算法对于噪声Feature健壮。</strong>类似于L1 regularization这样的技术可以使得你的机器学习算法对Feature进行剪枝，修剪掉那些对于预测的准确性贡献很小的Feature。这可以帮助你很好地拆分你的团队：一些人专注于算法，另一些人写Feature喂给算法。那些寻找Feature的人，可以直接“把东西扔进锅里”，然后让算法找出他们究竟好还是不好。（类似的，你应该通过确保合理的收敛性来选择一个算法）</li>
<li><strong>你可以部分地将架构和算法团队解耦合。</strong>基本上，大部分机器学习算法都是在累计一个分布式的hash table的统计信息，然后将这些统计信息合并成一个分数。开发一个分布式的hash table是和开发一个用于累计的算法不同的任务，可以由不同的子Team完成。然后，让这些人一起工作仍然是很重要的。例如，一些算法在写入和写入可用之前延时的“最终一致”的系统中（例如Dynamo），会有所波动。所以这只是一个部分解耦合，你仍然需要团队中有连接架构和算法的“桥梁”人员。</li>
<li><strong>在在线系统和批处理系统之间选择的时候要小心。</strong>一个在线系统可以实时学习，对于新的用户行为，可以在发生之后的几分钟内有所反应。但是这回带来巨大的开销，一个在线系统需要2-3倍的时间区开发和维护，而且他对瞬间的变化更加敏感。举个例子，如果你突然接收到了很多垃圾信息，这些噪声会立刻被吸收进你的系统并且开始降低用户的体验。类似的，一台机器如果没有可运行的内容了，如果网络连接中断了，或者一个特定的机器变慢了（导致Feature“歪了”），模型的某个输入开始生产垃圾，等等。</li>
<li><strong>为所有东西打上版本。</strong>一个训练过的模型依赖于稳定的标识，如果你更改了某个标识，模型立刻就过时了。例如，如果你将用户的语言(&#8220;en-us&#8221;)作为一个feature。那么当有些人提交了一个一行的修改，用下划线替换了短横线(&#8220;en_us&#8221;)。这使得模型立刻“忘记”了所有从&#8221;en-us&#8221;中学到的，使得所有的语言看起来都是一样的。所以为所有会在你模型中生成标识的代码和数据的变更都打上版本。</li>
<li><strong>你需要咬碎100-1000倍于实时的数据。</strong>如果你的训练数据来自于整整一年的历史数据，然后你的学习过程是10倍于实时，那他需要一个月来测试一个新Feature。把所有的东西都写成Map-Reduce或者Storm Topology使得你可以在数据变得足够大的时候仍然可以扩展。</li>
</ul>
<hr />
<p>看了一下，里面有不少错误我们都犯过，包括过去一个Q我们觉得由于团队小应该快点冲而省略掉的东西，现在看来也还是省略不掉的，而之前做对的部分也都是来自老大们的经验，希望今年少走弯路效果好啊。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.xuwenhao.com/2012/01/22/operate-a-system-is-more-important-than-develop-a-syste/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>其实都是些常规</title>
		<link>http://www.xuwenhao.com/2011/10/06/its-just-basic-rules/</link>
		<comments>http://www.xuwenhao.com/2011/10/06/its-just-basic-rules/#comments</comments>
		<pubDate>Thu, 06 Oct 2011 02:45:22 +0000</pubDate>
		<dc:creator>Stanley Xu</dc:creator>
				<category><![CDATA[Book]]></category>

		<guid isPermaLink="false">http://www.xuwenhao.com/?p=811</guid>
		<description><![CDATA[读完了这本书，其实多年以前随便乱翻书的时候应该已经读过，不过当时读了也是白读。 读完整本书，觉得有点儿料的还是那12个问题，非常Practical，而且仔细想了一下，如果这12点一个经理能够做好，基本上整个团队应该算是积极向上正向循环了的。 但是除此之外，整本书感觉就是平平了，一个是后面大量的所谓发挥优势，寻找才干之类的部分陷入了完全难以实践应用的怪圈，很多话颠过来倒过去，比如才干这个概念，看完全书你也很难定义出什么是才干，而这个，基本上是这本书核心的基本概念了。 我比较认同的部分是了解你的员工这一部分，了解每个人的性格禀赋理想，对于团队的长期成长和稳定是很有帮助的，但是我是认为很多时候，技能态度经验太难和才干分开，强行去寻找所谓才干可能没有太大实践意义。 才干后续部分的有些Practice倒是值得实践一下，包括花更多的时间和最好的员工在一起，包括尽量发挥优势而去避免弱点，而不是去补上所谓的缺陷。不过对于实践效果我心目中还是存疑的，一方面是在开发团队中，校招的新员工仍然是需要花大量实践培训的，而且初期欠缺的主要是经验和技能，而不是才干，不然可能就是完全浪费了才干，而在一个快速成长扩张的团队中，这个可能会占用很多时间，另外是避免弱点是否可能导致大量Senior的工程师反而不能独立工作，或者说放弃独立工作的需求？ 宽带工资之类的公司层面的实践，在高科技企业总体其实实践得不错，大部分公司都有技术和管理两个Career Path，所以没什么可多说的，对于传统企业反而是可能比较有参考意义。 总体来说，看完了需要做的是： 尝试一些Practice，比如花更多的时间和精力和最好的员工在一起。 不断回顾对于12个问题具体做得怎么样。 了解团队里的每个人。 对于技术团队的管理，我倒是比较推崇另外一本书Behind Closed Doors:Secrets of Great Management，相对更加practical，而且，就像书里说得那样，大部分事情都是很小很简单的，但是需要的是持续的实践练习。]]></description>
			<content:encoded><![CDATA[<p><img src="http://img3.douban.com/mpic/s1082756.jpg" alt="首先，打破一切常规" /><br />
读完了这本书，其实多年以前随便乱翻书的时候应该已经读过，不过当时读了也是白读。</p>
<p>读完整本书，觉得有点儿料的还是那12个问题，非常Practical，而且仔细想了一下，如果这12点一个经理能够做好，基本上整个团队应该算是积极向上正向循环了的。</p>
<p>但是除此之外，整本书感觉就是平平了，一个是后面大量的所谓发挥优势，寻找才干之类的部分陷入了完全难以实践应用的怪圈，很多话颠过来倒过去，比如才干这个概念，看完全书你也很难定义出什么是才干，而这个，基本上是这本书核心的基本概念了。</p>
<p>我比较认同的部分是了解你的员工这一部分，了解每个人的性格禀赋理想，对于团队的长期成长和稳定是很有帮助的，但是我是认为很多时候，技能态度经验太难和才干分开，强行去寻找所谓才干可能没有太大实践意义。</p>
<p>才干后续部分的有些Practice倒是值得实践一下，包括花更多的时间和最好的员工在一起，包括尽量发挥优势而去避免弱点，而不是去补上所谓的缺陷。不过对于实践效果我心目中还是存疑的，一方面是在开发团队中，校招的新员工仍然是需要花大量实践培训的，而且初期欠缺的主要是经验和技能，而不是才干，不然可能就是完全浪费了才干，而在一个快速成长扩张的团队中，这个可能会占用很多时间，另外是避免弱点是否可能导致大量Senior的工程师反而不能独立工作，或者说放弃独立工作的需求？</p>
<p>宽带工资之类的公司层面的实践，在高科技企业总体其实实践得不错，大部分公司都有技术和管理两个Career Path，所以没什么可多说的，对于传统企业反而是可能比较有参考意义。</p>
<p>总体来说，看完了需要做的是：</p>
<ul>
<li>尝试一些Practice，比如花更多的时间和精力和最好的员工在一起。</li>
<li>不断回顾对于12个问题具体做得怎么样。</li>
<li>了解团队里的每个人。</li>
<p>对于技术团队的管理，我倒是比较推崇另外一本书<a href="http://book.douban.com/subject/1433489/" title="Behind Closed Doors" target="_blank">Behind Closed Doors:Secrets of Great Management</a>，相对更加practical，而且，就像书里说得那样，大部分事情都是很小很简单的，但是需要的是持续的实践练习。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.xuwenhao.com/2011/10/06/its-just-basic-rules/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>入手了个Kindle</title>
		<link>http://www.xuwenhao.com/2011/06/08/bought-a-kindle-and-ideas-on-ebook/</link>
		<comments>http://www.xuwenhao.com/2011/06/08/bought-a-kindle-and-ideas-on-ebook/#comments</comments>
		<pubDate>Wed, 08 Jun 2011 14:09:06 +0000</pubDate>
		<dc:creator>Stanley Xu</dc:creator>
				<category><![CDATA[Book]]></category>
		<category><![CDATA[Idea]]></category>
		<category><![CDATA[Life]]></category>

		<guid isPermaLink="false">http://www.xuwenhao.com/?p=804</guid>
		<description><![CDATA[一方面是收到K总蛊惑，一方面是决定调整下多看点书，不能每天浪费太多时间刷微博，但是天天带iPad一是沉，而是的确很费眼睛。于是小长假前未经领导批示，大出血入了Kindle 3G+官方带灯皮套，目前看来，Kindle物有所值，受K总忽悠入了3G版其实意义不大，带灯皮套很好，但是价格太坑爹了。 3月份过完年的时候给老妈买了个百看，这次本来也是在各类电子书之间犹豫的，买了Kindle主要还是看重有些书可以直接在Amazon买Kindle版，排版比自己用PDF转的要好多了。到手之后，发现做工上Kindle还是比百看强出一条街的，翻页响应也快不少，不过就是保修麻烦，而上次那个百看买了两个月都没怎么用过就花屏了，寄回京东重新换了个新的。所以这回干脆狠狠心入了个皮套，想想3G版都买了，于是干脆入了个带灯的皮套，于是最后花出去的钱基本可以买两个广告版的了，还是比较烧包的。 用了两天，总结如下: 从看书来说，E-Ink秒杀一切，除了随手写写画画和快速翻页比不上纸质书，其余都远远超出，而且如果是用来看非技术类书籍，因为基本不需要记录，可以认为是完美，甚至可以说超过了纸质书 Kindle最大的优势应该是Amazon背后强大的内容，这个其实和iPad是一样的，我先是下了个Kindle版的Domain Specific Languages的sample，看完了Chapter1.1于是掏出信用卡买了全本电子版。 3G对美国人民可能很有用，但是对中国人民意思不大，会检查你的ip所在的国度，要求传真验证地址身份，看看到时候麻烦哪位在美国的同学把Kindle挂到他名下去 皮套的保护很不错，可是太厚重了，加了皮套单手持着就有些中了。灯很有意义，特别是晚上坐公车回家的时候，供电设计也很有意思，只是不能均匀照射到整个屏幕 6寸的Kindle，用来看技术书，如果是Kindle版的或者正版制作好的mobi版可以接受，但是Kindle DXG应该会更加完美 键盘加bookmark和note还是有一定意义的，内置字典非常有用，没有必要刷多看，原生系统用来看书足够了 原生的PDF阅读功能基本没用，书还是要转成Mobi，因为PDF的不能重排也不能调字体，所以等于没用，专门制作的6寸的PDF太罕见了，而且如果是专门制作的，完全可以搞Mobi么 Anyway，结论是，重度阅读者必备工具啊，让随时随地的阅读体验大大提升。 回过头来说，书籍电子化已经发展了很多年了，然而作为一个中国人民，想舒舒服服看电子书仍然只有糟糕的两个选择，盗版，或者装作一个美国人民。就像我前面说得，Kindle对我来说，最有吸引力的并不是3G上网或者硬件设备，而是在良好的阅读体验之上，Amazon拥有的无数Well-Formatted的书，这样我就不再需要买纸质书占地方了，而且所有的书，我都可以在看完sample之后决定要不要买，从这个角度来说，Kindle 3G可以提供的可以说是最佳的购书体验了。不需要你没有看过书就决定买不买(目前国内网上买书最大的缺点是很多书不知道值不值得买来看)，也不许要跑到书店里去买(我已经多年没有进过书店了，但是这几年)，甚至都不需要等快递送上门了(有时候想看书买了之后等快递要一个礼拜)。 可惜，这些优势都是只有美国人民有，中国人民只能 1. 装作美国人掏美刀跑到Amazon上买还要受歧视不让你买 2. 盗版，而且那么多年，这些国内的出版商和零售商真是完全不思进取，严肃书籍，除了China-Pub搞了些没人看的技术书籍电子版之外，就没有人有动作的。我一直认为，最蠢的一种想法就是惧怕盗版，要知道，这个阵地他们不占领，就会被盗版占领，现在互联网上已经有大量的自制的盗版版本了，质量虽然比不上Amazon Kindle的那种，有些错字，但是完全可以看了，不出电子版，就只能坐等大家去看盗版。如果真能够做到像Amazon在北美那样，可以试看，购买，同步，记笔记，同步笔记，然后绑定好设备来给盗版增加麻烦，我相信虽然不可能是一个iPad这样的市场，也会完全是一个有得做的市场，事实上，国内目前的iOS的App也有不少的正版软件消费量了。 当然，其实大家都知道，国内的出版商和在线零售商是没有足够的技术支撑来干这事儿的，唯一有点指望的是卓越能够跨过外资这道门槛把Amazon在美国的服务复制到中国来，或者，用脚投票投奔U.S.A.去。如果国内的电子书渠道能够像Amazon在美国这样，我想我就会考虑再入一台Kindle DXG的。]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.xuwenhao.com/wp-content/uploads/2011/06/kindle2.jpg"><img src="http://www.xuwenhao.com/wp-content/uploads/2011/06/kindle2-300x224.jpg" alt="" title="Kindle3G" width="300" height="224" class="aligncenter size-medium wp-image-805" /></a></p>
<p>一方面是收到<a href="http://www.kimmychen.com">K总</a>蛊惑，一方面是决定调整下多看点书，不能每天浪费太多时间刷微博，但是天天带iPad一是沉，而是的确很费眼睛。于是小长假前未经领导批示，大出血入了Kindle 3G+官方带灯皮套，目前看来，Kindle物有所值，受K总忽悠入了3G版其实意义不大，带灯皮套很好，但是价格太坑爹了。</p>
<p>3月份过完年的时候给老妈买了个百看，这次本来也是在各类电子书之间犹豫的，买了Kindle主要还是看重有些书可以直接在Amazon买Kindle版，排版比自己用PDF转的要好多了。到手之后，发现做工上Kindle还是比百看强出一条街的，翻页响应也快不少，不过就是保修麻烦，而上次那个百看买了两个月都没怎么用过就花屏了，寄回京东重新换了个新的。所以这回干脆狠狠心入了个皮套，想想3G版都买了，于是干脆入了个带灯的皮套，于是最后花出去的钱基本可以买两个广告版的了，还是比较烧包的。</p>
<p>用了两天，总结如下:</p>
<ul>
<li>从看书来说，E-Ink秒杀一切，除了随手写写画画和快速翻页比不上纸质书，其余都远远超出，而且如果是用来看非技术类书籍，因为基本不需要记录，可以认为是完美，甚至可以说超过了纸质书</li>
<li>Kindle最大的优势应该是Amazon背后强大的内容，这个其实和iPad是一样的，我先是下了个Kindle版的<em><a href="http://www.amazon.com/Domain-Specific-Languages-ebook/dp/B003ZUYJ3G/ref=sr_1_1?s=digital-text&#038;ie=UTF8&#038;qid=1307542070&#038;sr=1-1">Domain Specific Languages</a></em>的sample，看完了Chapter1.1于是掏出信用卡买了全本电子版。</li>
<li>3G对美国人民可能很有用，但是对中国人民意思不大，会检查你的ip所在的国度，要求传真验证地址身份，看看到时候麻烦哪位在美国的同学把Kindle挂到他名下去</li>
<li>皮套的保护很不错，可是太厚重了，加了皮套单手持着就有些中了。灯很有意义，特别是晚上坐公车回家的时候，供电设计也很有意思，只是不能均匀照射到整个屏幕</li>
<li>6寸的Kindle，用来看技术书，如果是Kindle版的或者正版制作好的mobi版可以接受，但是Kindle DXG应该会更加完美</li>
<li>键盘加bookmark和note还是有一定意义的，内置字典非常有用，没有必要刷多看，原生系统用来看书足够了</li>
<li>原生的PDF阅读功能基本没用，书还是要转成Mobi，因为PDF的不能重排也不能调字体，所以等于没用，专门制作的6寸的PDF太罕见了，而且如果是专门制作的，完全可以搞Mobi么</li>
</ul>
<p>Anyway，结论是，重度阅读者必备工具啊，让随时随地的阅读体验大大提升。</p>
<p>回过头来说，书籍电子化已经发展了很多年了，然而作为一个中国人民，想舒舒服服看电子书仍然只有糟糕的两个选择，盗版，或者装作一个美国人民。就像我前面说得，Kindle对我来说，最有吸引力的并不是3G上网或者硬件设备，而是在良好的阅读体验之上，Amazon拥有的无数Well-Formatted的书，这样我就不再需要买纸质书占地方了，而且所有的书，我都可以在看完sample之后决定要不要买，从这个角度来说，Kindle 3G可以提供的可以说是最佳的购书体验了。不需要你没有看过书就决定买不买(目前国内网上买书最大的缺点是很多书不知道值不值得买来看)，也不许要跑到书店里去买(我已经多年没有进过书店了，但是这几年)，甚至都不需要等快递送上门了(有时候想看书买了之后等快递要一个礼拜)。</p>
<p>可惜，这些优势都是只有美国人民有，中国人民只能 1. 装作美国人掏美刀跑到Amazon上买还要受歧视不让你买 2. 盗版，而且那么多年，这些国内的出版商和零售商真是完全不思进取，严肃书籍，除了China-Pub搞了些没人看的技术书籍电子版之外，就没有人有动作的。我一直认为，最蠢的一种想法就是惧怕盗版，要知道，这个阵地他们不占领，就会被盗版占领，现在互联网上已经有大量的自制的盗版版本了，质量虽然比不上Amazon Kindle的那种，有些错字，但是完全可以看了，不出电子版，就只能坐等大家去看盗版。如果真能够做到像Amazon在北美那样，可以试看，购买，同步，记笔记，同步笔记，然后绑定好设备来给盗版增加麻烦，我相信虽然不可能是一个iPad这样的市场，也会完全是一个有得做的市场，事实上，国内目前的iOS的App也有不少的正版软件消费量了。</p>
<p>当然，其实大家都知道，国内的出版商和在线零售商是没有足够的技术支撑来干这事儿的，唯一有点指望的是卓越能够跨过外资这道门槛把Amazon在美国的服务复制到中国来，或者，用脚投票投奔U.S.A.去。如果国内的电子书渠道能够像Amazon在美国这样，我想我就会考虑再入一台Kindle DXG的。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.xuwenhao.com/2011/06/08/bought-a-kindle-and-ideas-on-ebook/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>支持Ruby1.9的MRToolkit</title>
		<link>http://www.xuwenhao.com/2011/03/25/make-mrtoolkit-support-ruby19/</link>
		<comments>http://www.xuwenhao.com/2011/03/25/make-mrtoolkit-support-ruby19/#comments</comments>
		<pubDate>Fri, 25 Mar 2011 15:20:54 +0000</pubDate>
		<dc:creator>Stanley Xu</dc:creator>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[MapReduce]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://www.xuwenhao.com/?p=791</guid>
		<description><![CDATA[虽然最近的工作整天用Java写各类数据处理代码，但是去年大半年用惯了Ruby的我每每要写个测试或者临时计算的MapReduce都觉得真是太麻烦了，于是又念叨起Ruby的好来了。 先看了看利用Hadoop Streaming和Ruby来写MapReduce，发现还是有些麻烦，一是mapper和reducer要分开两个文件，二是每个任务都要重复写从stdin读取数据解析，以及输出的代码，一点不符合DRY原则，于是就找到了mrtoolkit，然后一连串杯具开始发生了。 麻烦LJ同学先给所有的机器装了Ruby1.9，然后一跑，杯具地发现没跑起来，然后发现部分代码不兼容1.9……好吧，反正没多少源代码，改之，再跑，发现虽然每台机器都下载了mrtoolkit而且都设好了RUBYLIB但还是没能成功require mrtoolkit；于是，上github抄了个别人更改的mrtoolkit版本的gemspec和Rakefile，然后打包成gem，然后安装，于是MapReduce任务在各个node上跑起来了，但是，有一部分失败了，杯具地发现Ruby1.9开始对于字符串encoding有了很多限制，使用split通过正则分割字符串的时候居然还检查整个字符串的encoding的合法性，而我们要处理的日志里会存在GBK和UTF-8混在一行编码的可能性……试了好多种方法都不行，只好再跑到邮件组上去问，得高人指点先把字符串转成BINARY的encoding进行分割，然后再转回来，终于……能用了。 所以现在就有了这个支持Ruby1.9的mrtoolkit的版本啦，首个release包含以下变更： 支持Ruby1.9 将hadoop streaming中deprecated的-jobconf参数改成了-D 单行的文本编码可以是混合编码的不合法的Ruby1.9的字符串 可以打包成gem安装(抄袭自jashmenn的版本) 还准备做个小改动是默认output目录存在时输出警告，并且不提交任务不删除输出目录，直接删除现有的输出目录这种方法太容易搞出事情来了。]]></description>
			<content:encoded><![CDATA[<p>虽然最近的工作整天用Java写各类数据处理代码，但是去年大半年用惯了Ruby的我每每要写个测试或者临时计算的MapReduce都觉得真是太麻烦了，于是又念叨起Ruby的好来了。</p>
<p>先看了看利用Hadoop Streaming和Ruby来写MapReduce，发现还是有些麻烦，一是mapper和reducer要分开两个文件，二是每个任务都要重复写从stdin读取数据解析，以及输出的代码，一点不符合DRY原则，于是就找到了<a href="http://code.google.com/p/mrtoolkit/">mrtoolkit</a>，然后一连串杯具开始发生了。</p>
<p>麻烦LJ同学先给所有的机器装了Ruby1.9，然后一跑，杯具地发现没跑起来，然后发现部分代码不兼容1.9……好吧，反正没多少源代码，改之，再跑，发现虽然每台机器都下载了mrtoolkit而且都设好了RUBYLIB但还是没能成功require mrtoolkit；于是，上github抄了个<a href="https://github.com/jashmenn/mrtoolkit">别人更改的mrtoolkit版本的gemspec和Rakefile</a>，然后打包成gem，然后安装，于是MapReduce任务在各个node上跑起来了，但是，有一部分失败了，杯具地发现Ruby1.9开始对于字符串encoding有了很多限制，使用split通过正则分割字符串的时候居然还检查整个字符串的encoding的合法性，而我们要处理的日志里会存在GBK和UTF-8混在一行编码的可能性……试了好多种方法都不行，只好再跑到邮件组上去问，得高人指点先把字符串转成BINARY的encoding进行分割，然后再转回来，终于……能用了。</p>
<p>所以现在就有了这个<a href="https://github.com/xuwenhao/mrtoolkit">支持Ruby1.9的mrtoolkit</a>的版本啦，首个release包含以下变更：</p>
<ul>
<li>支持Ruby1.9</li>
<li>将hadoop streaming中deprecated的-jobconf参数改成了-D</li>
<li>单行的文本编码可以是混合编码的不合法的Ruby1.9的字符串</li>
<li>可以打包成gem安装(抄袭自jashmenn的版本)</li>
</ul>
<p>还准备做个小改动是默认output目录存在时输出警告，并且不提交任务不删除输出目录，直接删除现有的输出目录这种方法太容易搞出事情来了。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.xuwenhao.com/2011/03/25/make-mrtoolkit-support-ruby19/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>建议的程序员学习LDA算法的步骤</title>
		<link>http://www.xuwenhao.com/2011/03/20/suggestions-for-programmers-to-learn-lda/</link>
		<comments>http://www.xuwenhao.com/2011/03/20/suggestions-for-programmers-to-learn-lda/#comments</comments>
		<pubDate>Sun, 20 Mar 2011 04:37:52 +0000</pubDate>
		<dc:creator>Stanley Xu</dc:creator>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[LDA]]></category>
		<category><![CDATA[Machine Learning]]></category>

		<guid isPermaLink="false">http://www.xuwenhao.com/?p=785</guid>
		<description><![CDATA[这一阵为了工作上的关系，花了点时间学习了一下LDA算法，说实话，对于我这个学CS而非学数学的人来说，除了集体智慧编程这本书之外基本没怎么看过机器学习的人来说，一开始还真是摸不太到门道，前前后后快要四个月了，算是基本了解了这个算法的实现，记录一下，也供后来人快速入门做个参考。 一开始直接就下了Blei的原始的那篇论文来看，但是看了个开头就被Dirichlet分布和几个数学公式打倒，然后因为专心在写项目中的具体的代码，也就先放下了。但是因为发现完全忘记了本科学的概率和统计的内容，只好回头去看大学时候概率论的教材，发现早不知道借给谁了，于是上网买了本，花了几天时间大致回顾了一遍概率论的知识，什么贝叶斯全概率公式，正态分布，二项分布之类的。 后来晚上没事儿的时候，去水木的AI版转了转，了解到了Machine Learning的圣经PRML，考虑到反正也是要长期学习了，搞了电子版，同时上淘宝买了个打印胶装的版本。春节里每天晚上看一点儿，扫了一下前两章，再次回顾了一下基本数学知识，然后了解了下贝叶斯学派那种采用共轭先验来建模的方式。于是再次尝试回头去看Blei的那篇论文，发现还是看不太懂，于是又放下了。然后某天Tony让我准备准备给复旦的同学们share一下我们项目中LDA的使用，为了不露怯，又去翻论文，正好看到Science上这篇Topic Models Vs. Unstructured Data的科普性质的文章，翻了一遍之后，再去PRML里看了一遍Graphic Models那一张，觉得对于LDA想解决的问题和方法了解了更清楚了。之后从search engine里搜到这篇文章，然后根据推荐读了一部分的Gibbs Sampling for the Uninitiated。之后忘了怎么又搜到了Mark Steyvers和Tom Griffiths合著的Probabilistic Topic Models，在某个周末往返北京的飞机上读完了，觉得基本上模型训练过程也明白了。再之后就是读了一下这个最简版的LDA Gibbs Sampling的实现，再回过头读了一下PLDA的源码，基本上算是对LDA有了个相对清楚的了解。 这样前前后后，也过去了三个月，其实不少时间都是浪费掉的，比如Blei的论文在没有任何相关知识的情况下一开始读了好几次，都没读完而且得到到信息也很有限，如果重新总结一下，我觉得对于我们这些门外汉程序员来说，想了解LDA大概需要这些知识: 有基本的概率论的知识，这个拿个大学的课本大概翻一下就好了 PRML的前两章和Graphic Model那部分需要浏览一下，了解一下所谓的贝叶斯学派的方法论，然后理解共轭先验的概念，以及Graphic Model的图形表达的意思。 了解一下Gibbs Sampling的概念 直接读Steyvers的Probabilistic Topic Models，没必要一定去读Blei的论文，开创性的论文不一定好读，最典型的例子就是Paxos了，30多页里多少都是希腊人名，对于英文不够精通，学术训练比较少的工程师来说，其实很痛苦，意义也不大。 对照着Probabilistic Topic Models直接看LdaGibbsSampling.java的源码 基本上这样一圈下来，基本概念和算法实现都应该搞定了，当然，数学证明其实没那么容易就搞定，但是对于工程师来说，先把这些搞定就能干活了，这个步骤并不适合各位读博士发论文的同学们，但是这样先看看也比较容易对于这些数学问题的兴趣，不然，成天对这符号和数学公式，没有整块业余时间的我是觉得还是容易退缩放弃的。 发现作为工程师来说，还是看代码比较有感觉，看实际应用的实例比较有感觉，看来不能把大部分时间花在PRML上，还是要多对照着代码看。]]></description>
			<content:encoded><![CDATA[<p>这一阵为了工作上的关系，花了点时间学习了一下<a href="http://en.wikipedia.org/wiki/Latent_Dirichlet_allocation">LDA</a>算法，说实话，对于我这个学CS而非学数学的人来说，除了<a href="http://book.douban.com/subject/3288908/">集体智慧编程</a>这本书之外基本没怎么看过机器学习的人来说，一开始还真是摸不太到门道，前前后后快要四个月了，算是基本了解了这个算法的实现，记录一下，也供后来人快速入门做个参考。</p>
<p>一开始直接就下了<a href="http://scholar.google.com/scholar?q=LATENT+DIRICHLET+ALLOCATION&#038;hl=en&#038;btnG=Search&#038;as_sdt=1%2C33&#038;as_sdtp=on">Blei的原始的那篇论文</a>来看，但是看了个开头就被Dirichlet分布和几个数学公式打倒，然后因为专心在写项目中的具体的代码，也就先放下了。但是因为发现完全忘记了本科学的概率和统计的内容，只好回头去看大学时候概率论的教材，发现早不知道借给谁了，于是上网买了本，花了几天时间大致回顾了一遍概率论的知识，什么贝叶斯全概率公式，正态分布，二项分布之类的。<br />
后来晚上没事儿的时候，去水木的AI版转了转，了解到了Machine Learning的圣经<a href="http://book.douban.com/subject/2061116/">PRML</a>，考虑到反正也是要长期学习了，搞了电子版，同时上淘宝买了个打印胶装的版本。春节里每天晚上看一点儿，扫了一下前两章，再次回顾了一下基本数学知识，然后了解了下贝叶斯学派那种采用共轭先验来建模的方式。于是再次尝试回头去看Blei的那篇论文，发现还是看不太懂，于是又放下了。然后某天Tony让我准备准备给复旦的同学们share一下我们项目中LDA的使用，为了不露怯，又去翻论文，正好看到Science上这篇<a href="http://www.google.com/url?sa=t&#038;source=web&#038;cd=1&#038;ved=0CB8QFjAA&#038;url=http%3A%2F%2Fwww.umsl.edu%2F~sauterv%2FDSS4BI%2Flinks%2Fp16-anthes.pdf&#038;ei=O4GFTYCfII6osAOsibn7AQ&#038;usg=AFQjCNHHBMGPYHrA6PYi1TxM8BGcJyTnQA">Topic Models Vs. Unstructured Data</a>的科普性质的文章，翻了一遍之后，再去PRML里看了一遍Graphic Models那一张，觉得对于LDA想解决的问题和方法了解了更清楚了。之后从search engine里搜到这篇<a href="http://www.52nlp.cn/tears-and-uninitiated-learn-from-natural-language-processing-heros">文章</a>，然后根据推荐读了一部分的<a href="http://scholar.google.com/scholar?q=Gibbs+Sampling+for+the+Uninitiated&#038;hl=en&#038;as_sdt=0&#038;as_vis=1&#038;oi=scholart">Gibbs Sampling for the Uninitiated</a>。之后忘了怎么又搜到了Mark Steyvers和Tom Griffiths合著的<a href="http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.80.9625&#038;rep=rep1&#038;type=pdf">Probabilistic Topic Models</a>，在某个周末往返北京的飞机上读完了，觉得基本上模型训练过程也明白了。再之后就是读了一下这个<a href="http://www.google.com/url?sa=t&#038;source=web&#038;cd=3&#038;ved=0CCUQFjAC&#038;url=http%3A%2F%2Fwww.arbylon.net%2Fprojects%2FLdaGibbsSampler.java&#038;ei=9YGFTa2YI5CksQPx142GAg&#038;usg=AFQjCNE-aJ83icrLWIe0bBeFyDHo6Srfuw">最简版的LDA Gibbs Sampling</a>的实现，再回过头读了一下<a href="http://code.google.com/p/plda/">PLDA</a>的源码，基本上算是对LDA有了个相对清楚的了解。</p>
<p>这样前前后后，也过去了三个月，其实不少时间都是浪费掉的，比如Blei的论文在没有任何相关知识的情况下一开始读了好几次，都没读完而且得到到信息也很有限，如果重新总结一下，我觉得对于我们这些门外汉程序员来说，想了解LDA大概需要这些知识:</p>
<ul>
<li>有基本的概率论的知识，这个拿个大学的课本大概翻一下就好了</li>
<li>PRML的前两章和Graphic Model那部分需要浏览一下，了解一下所谓的贝叶斯学派的方法论，然后理解共轭先验的概念，以及Graphic Model的图形表达的意思。</li>
<li>了解一下Gibbs Sampling的概念</li>
<li>直接读Steyvers的Probabilistic Topic Models，没必要一定去读Blei的论文，开创性的论文不一定好读，最典型的例子就是Paxos了，30多页里多少都是希腊人名，对于英文不够精通，学术训练比较少的工程师来说，其实很痛苦，意义也不大。</li>
<li>对照着Probabilistic Topic Models直接看LdaGibbsSampling.java的源码</li>
</ul>
<p>基本上这样一圈下来，基本概念和算法实现都应该搞定了，当然，数学证明其实没那么容易就搞定，但是对于工程师来说，先把这些搞定就能干活了，这个步骤并不适合各位读博士发论文的同学们，但是这样先看看也比较容易对于这些数学问题的兴趣，不然，成天对这符号和数学公式，没有整块业余时间的我是觉得还是容易退缩放弃的。</p>
<p>发现作为工程师来说，还是看代码比较有感觉，看实际应用的实例比较有感觉，看来不能把大部分时间花在PRML上，还是要多对照着代码看。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.xuwenhao.com/2011/03/20/suggestions-for-programmers-to-learn-lda/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>Go Back to the Fundamental</title>
		<link>http://www.xuwenhao.com/2011/02/19/go-back-to-the-fundamental/</link>
		<comments>http://www.xuwenhao.com/2011/02/19/go-back-to-the-fundamental/#comments</comments>
		<pubDate>Sat, 19 Feb 2011 12:57:18 +0000</pubDate>
		<dc:creator>Stanley Xu</dc:creator>
				<category><![CDATA[Idea]]></category>
		<category><![CDATA[Life]]></category>

		<guid isPermaLink="false">http://www.xuwenhao.com/?p=782</guid>
		<description><![CDATA[这周LJ发现系统里有大量的缓存没有清掉，一开始误以为是我的定时提交的Job中有什么问题，虽然最终发现是因为系统对于验证阶段不能通过的Job就会缓存Job文件供日后分析，但是在怀疑自己提交的Job有问题的时候，花了两天时间清理掉了以前没有解决的Bug，并且进一步发现了某些Bug的深层原因。这事儿又是给自己一个教训，一是凡是出错必有原因。二是所有新功能都应当在显然是Bug的东西修复了之后完成。其实这样的错误不是第一次犯了，而且从道理上也清楚的知道该怎么做，但是时不时总会觉得自己已经有足够的经验去把握各种优先级了，于是时不时就会再犯一次，希望这是最后一次了。大部分事情要做好其实很简单，按照自然规律，一步一步仔仔细细做完，Over，可惜总是急躁地想抄近道，最后在事后付出代价。好在的确工作年限多了点，现在犯的错误往往不是致命的，最多也就是多浪费了那么一点时间罢了。 今天又和好久未见的Mars同学聊了一阵，现在我们算是一个行业里了，聊到目前飞速发展的互联网和电子商务，一边感慨的确入对了行，一边也都觉得行业里大部分的人还都是过于浮躁了，机会虽然看起来很多，但是大家都急冲冲地做的结果就是门槛看似很低，但是大部分都会死。然而很多死者，无论是做技术还是做市场做商务的，其实都没有真正做到把自己的事情做好，也许真是要退潮了，才能看出谁是裸泳者。 其实这个和写程序是一样的，问题暴露出来之前，各种抄近道导致的Tech Debt都不会被意识到的，所以还是告诫自己，有耐心地，一点一滴的把事情做好。 看了看春节里写的今年看三本书的计划，当时我还觉得时间还蛮宽裕的，但是仔细算算，其实也不怎么够用，如果每天看个一两节，其实看完这三本书一年都不够，不管了，每天1-3节吧，多了也坚持不下来的。]]></description>
			<content:encoded><![CDATA[<p>这周LJ发现系统里有大量的缓存没有清掉，一开始误以为是我的定时提交的Job中有什么问题，虽然最终发现是因为系统对于验证阶段不能通过的Job就会缓存Job文件供日后分析，但是在怀疑自己提交的Job有问题的时候，花了两天时间清理掉了以前没有解决的Bug，并且进一步发现了某些Bug的深层原因。这事儿又是给自己一个教训，一是凡是出错必有原因。二是所有新功能都应当在显然是Bug的东西修复了之后完成。其实这样的错误不是第一次犯了，而且从道理上也清楚的知道该怎么做，但是时不时总会觉得自己已经有足够的经验去把握各种优先级了，于是时不时就会再犯一次，希望这是最后一次了。大部分事情要做好其实很简单，按照自然规律，一步一步仔仔细细做完，Over，可惜总是急躁地想抄近道，最后在事后付出代价。好在的确工作年限多了点，现在犯的错误往往不是致命的，最多也就是多浪费了那么一点时间罢了。</p>
<p>今天又和好久未见的Mars同学聊了一阵，现在我们算是一个行业里了，聊到目前飞速发展的互联网和电子商务，一边感慨的确入对了行，一边也都觉得行业里大部分的人还都是过于浮躁了，机会虽然看起来很多，但是大家都急冲冲地做的结果就是门槛看似很低，但是大部分都会死。然而很多死者，无论是做技术还是做市场做商务的，其实都没有真正做到把自己的事情做好，也许真是要退潮了，才能看出谁是裸泳者。</p>
<p>其实这个和写程序是一样的，问题暴露出来之前，各种抄近道导致的Tech Debt都不会被意识到的，所以还是告诫自己，有耐心地，一点一滴的把事情做好。</p>
<p>看了看春节里写的今年看三本书的计划，当时我还觉得时间还蛮宽裕的，但是仔细算算，其实也不怎么够用，如果每天看个一两节，其实看完这三本书一年都不够，不管了，每天1-3节吧，多了也坚持不下来的。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.xuwenhao.com/2011/02/19/go-back-to-the-fundamental/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>不对自我设限与来自未来的挑战</title>
		<link>http://www.xuwenhao.com/2011/02/09/dont-limit-yourself-and-the-challenge-from-the-future/</link>
		<comments>http://www.xuwenhao.com/2011/02/09/dont-limit-yourself-and-the-challenge-from-the-future/#comments</comments>
		<pubDate>Wed, 09 Feb 2011 14:02:07 +0000</pubDate>
		<dc:creator>Stanley Xu</dc:creator>
				<category><![CDATA[Idea]]></category>
		<category><![CDATA[Life]]></category>

		<guid isPermaLink="false">http://www.xuwenhao.com/?p=778</guid>
		<description><![CDATA[话说我是一贯认为程序员是个很有前途的职业，因为工作的这几年来，最大的感触就是好的程序员太少，好的程序员的供给，其实是远远小于市场的需求的。这个原因有两方面，一方面是，贵国发展太快，聪明的孩子们现在的选择太多，当PM的，当Dev Manager的，甚或是转行去读MBA的，考公务员的，搞金融的，总之是聪明人的挣钱过舒服日子的实在不少，于是，程序员这个很有前途的职业就被大家放弃了；另一方面，互联网行业在贵国发展太快，现在需要好的程序员的公司实在太多。这样一两面夹击，您要真是能做个优秀的开发人员，过过中产生活应当是绰绰有余(当然，您要在北京二环买房，没有个叫李刚的爸爸可能买不了)。而且，您要真是个优秀的程序员，也是可以干到60岁的，常见的所谓30岁怎么办，其实是个巨大的误区，这个问题，因为不是本文的主旨，所以就不展开讨论了，下次专门写个文章说一下为啥这行业可以干到60岁。 然而尽管我如此认为，我最近也时常想，也许20年后我也不一定每天写程序了，虽然每天写程序的概率仍然很大。之所以这么想，其中有一部分是因为这个链接。想想几十年前，汽车业也是最NB，最伟大的行业啊，虽然现在也算不上夕阳行业了，但是远不如那时候那么激动人心了。想想福特的蓝血十杰，要搁现在应该都去华尔街或者干互联网了吧。所以虽然现在的互联网仍然是风起云涌，是各位好人们挥洒大好青春的领地，但是在等20年，可能最刺激的时代就会过去了吧。而我之所以现在仍然自称喜欢写程序，无非是三方面的原因，一是求知的乐趣，二是看得到奔头的物质回报，三是觉得自己好歹在创造点有用的东西的成就感。而每当看到这样的文章的我，就容易头脑发热，觉得自己死活应该去读个博士。 所以我想，虽然我接下来四五年一定是在做程序员这个很有前途的行业，但是几年以后如果能像Elon Musk或者John Carmack一样参与到发射火箭的活动中，我会毫不犹豫跑去吧，所以为了这个，我也应该做个学好数学的程序员吧，对于擅长逻辑思维和计算的我，写程序和数学算是我未来有机会跨行业干活的重要工具吧。 说到这里估计会被人当作少不经事太爱幻想，不过这几年我越来越发现人不能对自我设限，自我设限通常结果不是让你脚踏实地而是容易让你原地踏步。本来我想我大学没好好念书，也就不想啥再去读个PhD了，但是看了Paul McKenney老人家的简历，我觉其实准备准备也可以考虑三四十去读个PhD么？以前总觉得没指望名片上从Mr.改成Dr.的限制其实都来自自己么？其实，工作了这几年，越来越发现，其实身边的大牛们，并没有比我多个脑袋，或者一定每天只需要睡4个小时，无非是天赋、机遇、眼界，加上日供一卒的努力罢了，大部分身边的大牛们，和你我的差别不在天赋上，不在机遇上，而往往是在眼界和每日持续的努力上。而自我设限，一是愣把眼界降低一层，非觉得别人能拿一等奖能读博，自己不能总只想着卖烧饼；二是往往主动放弃了每天向前一点点的努力，因为觉得读不了博了干脆就不学点儿难的数学GRE或者Lisp了。最后是啥也没干成，但这种自我预言的实现是十足地犯傻呢。 未来还很长呢，想想十多年前上大学的时候，我还没手机呢，现在手机3G上网都比我家上网快了，又有谁会知道15年后我会去干什么，虽然多半我仍然在写着我那很有前途的程序，兴许外星人真来了我去当翻译了呢。虽然，图灵奖我估摸着的确应该是拿不了了，但咱们怎么也这辈子读个博士，发两篇有点儿意义的论文先吧。]]></description>
			<content:encoded><![CDATA[<p>话说我是一贯认为程序员是个很有前途的职业，因为工作的这几年来，最大的感触就是好的程序员太少，好的程序员的供给，其实是远远小于市场的需求的。这个原因有两方面，一方面是，贵国发展太快，聪明的孩子们现在的选择太多，当PM的，当Dev Manager的，甚或是转行去读MBA的，考公务员的，搞金融的，总之是聪明人的挣钱过舒服日子的实在不少，于是，程序员这个很有前途的职业就被大家放弃了；另一方面，互联网行业在贵国发展太快，现在需要好的程序员的公司实在太多。这样一两面夹击，您要真是能做个优秀的开发人员，过过中产生活应当是绰绰有余(当然，您要在北京二环买房，没有个叫李刚的爸爸可能买不了)。而且，您要真是个优秀的程序员，也是可以干到60岁的，常见的所谓30岁怎么办，其实是个巨大的误区，这个问题，因为不是本文的主旨，所以就不展开讨论了，下次专门写个文章说一下为啥这行业可以干到60岁。</p>
<p>然而尽管我如此认为，我最近也时常想，也许20年后我也不一定每天写程序了，虽然每天写程序的概率仍然很大。之所以这么想，其中有一部分是因为这个<a href="http://www.ruanyifeng.com/blog/2011/02/charles_kettering_quotes.html">链接</a>。想想几十年前，汽车业也是最NB，最伟大的行业啊，虽然现在也算不上夕阳行业了，但是远不如那时候那么激动人心了。想想福特的<a href="http://book.douban.com/subject/1448684/">蓝血十杰</a>，要搁现在应该都去华尔街或者干互联网了吧。所以虽然现在的互联网仍然是风起云涌，是各位好人们挥洒大好青春的领地，但是在等20年，可能最刺激的时代就会过去了吧。而我之所以现在仍然自称喜欢写程序，无非是三方面的原因，一是求知的乐趣，二是看得到奔头的物质回报，三是觉得自己好歹在创造点有用的东西的成就感。而每当看到<a href="http://soulogic.com/archives/411">这样的文章</a>的我，就容易头脑发热，觉得自己死活应该去读个博士。</p>
<p>所以我想，虽然我接下来四五年一定是在做程序员这个很有前途的行业，但是几年以后如果能像<a href="http://en.wikipedia.org/wiki/Elon_Musk">Elon Musk</a>或者<a href="http://www.google.com/url?sa=t&#038;source=web&#038;cd=1&#038;ved=0CCYQFjAA&#038;url=http%3A%2F%2Fen.wikipedia.org%2Fwiki%2FJohn_D._Carmack&#038;ei=AZlSTbmWJI6qsAO02p2aBw&#038;usg=AFQjCNE9e7BvCC6IndB7oa6IAWUYIIRtSQ">John Carmack</a>一样参与到发射火箭的活动中，我会毫不犹豫跑去吧，所以为了这个，我也应该做个<a href="http://www.xuwenhao.com/2011/02/01/how-import-is-math-for-a-programmer/">学好数学的程序员</a>吧，对于擅长逻辑思维和计算的我，写程序和数学算是我未来有机会跨行业干活的重要工具吧。</p>
<p>说到这里估计会被人当作少不经事太爱幻想，不过这几年我越来越发现人不能对自我设限，自我设限通常结果不是让你脚踏实地而是容易让你原地踏步。本来我想我大学没好好念书，也就不想啥再去读个PhD了，但是看了<a href="http://www.linkedin.com/profile/view?id=7701930&#038;authType=NAME_SEARCH&#038;authToken=X2_i&#038;locale=en_US&#038;srchid=61cc284e-f25e-43ec-9fee-000b60d5c8f2-0&#038;srchindex=1&#038;srchtotal=1&#038;pvs=ps&#038;pohelp=&#038;goback=%2Efps_Paul+E*3+McKenney+_*1_*1_*1_*1_*1_*1_*51_*1_Y_*1_*1_*1_false_1_R_true_*2_*2_*2_*2_*2_*2_*2_*2_*2_*2_*2_*2_*2_*2_*2_*2_*2_*2_*2_*2_*2">Paul McKenney</a>老人家的简历，我觉其实准备准备也可以考虑三四十去读个PhD么？以前总觉得没指望名片上从Mr.改成Dr.的限制其实都来自自己么？其实，工作了这几年，越来越发现，其实身边的大牛们，并没有比我多个脑袋，或者一定每天只需要睡4个小时，无非是天赋、机遇、眼界，加上日供一卒的努力罢了，大部分身边的大牛们，和你我的差别不在天赋上，不在机遇上，而往往是在眼界和每日持续的努力上。而自我设限，一是愣把眼界降低一层，非觉得别人能拿一等奖能读博，自己不能总只想着卖烧饼；二是往往主动放弃了每天向前一点点的努力，因为觉得读不了博了干脆就不学点儿难的数学GRE或者Lisp了。最后是啥也没干成，但这种自我预言的实现是十足地犯傻呢。</p>
<p>未来还很长呢，想想十多年前上大学的时候，我还没手机呢，现在手机3G上网都比我家上网快了，又有谁会知道15年后我会去干什么，虽然多半我仍然在写着我那很有前途的程序，兴许外星人真来了我去当翻译了呢。虽然，图灵奖我估摸着的确应该是拿不了了，但咱们怎么也这辈子读个博士，发两篇有点儿意义的论文先吧。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.xuwenhao.com/2011/02/09/dont-limit-yourself-and-the-challenge-from-the-future/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>新年愿望</title>
		<link>http://www.xuwenhao.com/2011/02/01/wishes-for-the-rabbit-year/</link>
		<comments>http://www.xuwenhao.com/2011/02/01/wishes-for-the-rabbit-year/#comments</comments>
		<pubDate>Tue, 01 Feb 2011 15:22:49 +0000</pubDate>
		<dc:creator>Stanley Xu</dc:creator>
				<category><![CDATA[Life]]></category>
		<category><![CDATA[Work]]></category>

		<guid isPermaLink="false">http://www.xuwenhao.com/?p=770</guid>
		<description><![CDATA[去年基本没写Blog，回想一下，去年想干的几件事，基本都没善终，希望今年有所改观 总结下去年的生产力 I公司的产品，技术的推动，基本上算是满盘皆输，心理感觉都快和程序员阿士顿的故事差不多了，花了很多时间精力，但是就是没有实际的商业成果。最后11月份放弃换工作了。 手机开发，本来想自己写个iPhone App的，最后也没有抽出时间来写，基本上Objective-C的程序架构都清楚了，debug也行，但是实际除了Example没有写过什么。 Ruby和Rails，倒是因为一个项目重新拾起，但是换了工作之后又放下了，不过现在的脚本都用Ruby写了，算勉强保持点功力吧。 Lisp，做了点SICP上的题，本来雄心壮志准备去年做完的，但是换了工作，又玩新东西去了，目前停留在第二章，今年怎么也把这本书上的题做完吧 儿子的某大事还算成功，算是了了一半心事。春天的时候去乌镇过了个周末，我非常喜欢那里，准备今年至少再去一次 最后，托HL总的福，换了个新工作，目前很满意，开始做些有追求的大系统，感谢HL总和NH姐姐。当然，也感谢I公司的B总，很愧疚自己还是才具不够，折腾了一年半没能干成啥事儿。 今年的目标也蛮简单，技术上和实际工作基本上完全一致，就是分布式和机器学习了，硬指标基本上是三本书，去年没看完的SICP做完所有得题，分布式看完POSA第四卷，以及机器学习看完PRML，希望做出的系统真的能够对中国互联网有点影响，希望能为Hadoop/HBase/Zookeeper/Mahout/S4这些开源项目贡献点代码。生活上么，去次海南，再去次乌镇，有机会的话，再出趟国，以后能像我毕业前三年那样每年都出去见识见识。对自己的限制么，今年不烧包买大件了，iPad、手机、笔记本电脑都不会更新换代，得开始稍微省点儿钱了。本来还想学门乐器，算算多半也不会有时间，今年就不考虑了，先重新把数学学好吧。还有就是真得锻炼身体了，游泳圈开始初现端倪了……]]></description>
			<content:encoded><![CDATA[<p>去年基本没写Blog，回想一下，去年想干的几件事，基本都没善终，希望今年有所改观</p>
<p>总结下去年的生产力</p>
<ul>
<li>I公司的产品，技术的推动，基本上算是满盘皆输，心理感觉都快和<a href="http://www.zhuoqun.net/html/y2010/1565.html">程序员阿士顿的故事</a>差不多了，花了很多时间精力，但是就是没有实际的商业成果。最后11月份放弃换工作了。</li>
<li>手机开发，本来想自己写个iPhone App的，最后也没有抽出时间来写，基本上Objective-C的程序架构都清楚了，debug也行，但是实际除了Example没有写过什么。</li>
<li>Ruby和Rails，倒是因为一个项目重新拾起，但是换了工作之后又放下了，不过现在的脚本都用Ruby写了，算勉强保持点功力吧。</li>
<li>Lisp，做了点SICP上的题，本来雄心壮志准备去年做完的，但是换了工作，又玩新东西去了，目前停留在第二章，今年怎么也把这本书上的题做完吧</li>
<li>儿子的某大事还算成功，算是了了一半心事。春天的时候去乌镇过了个周末，我非常喜欢那里，准备今年至少再去一次</li>
<li>最后，托HL总的福，换了个新工作，目前很满意，开始做些有追求的大系统，感谢HL总和NH姐姐。当然，也感谢I公司的B总，很愧疚自己还是才具不够，折腾了一年半没能干成啥事儿。</li>
</ul>
<p>今年的目标也蛮简单，技术上和实际工作基本上完全一致，就是分布式和机器学习了，硬指标基本上是三本书，去年没看完的<a href="http://book.douban.com/subject/1148282/">SICP</a>做完所有得题，分布式看完<a href="http://book.douban.com/subject/4848563/">POSA第四卷</a>，以及机器学习看完<a href="http://book.douban.com/subject/2061116/">PRML</a>，希望做出的系统真的能够对中国互联网有点影响，希望能为Hadoop/HBase/Zookeeper/Mahout/S4这些开源项目贡献点代码。生活上么，去次海南，再去次乌镇，有机会的话，再出趟国，以后能像我毕业前三年那样每年都出去见识见识。对自己的限制么，今年不烧包买大件了，iPad、手机、笔记本电脑都不会更新换代，得开始稍微省点儿钱了。本来还想学门乐器，算算多半也不会有时间，今年就不考虑了，先重新把数学学好吧。还有就是真得锻炼身体了，游泳圈开始初现端倪了……</p>
]]></content:encoded>
			<wfw:commentRss>http://www.xuwenhao.com/2011/02/01/wishes-for-the-rabbit-year/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>作为一个程序员，数学对你到底有多重要</title>
		<link>http://www.xuwenhao.com/2011/02/01/how-import-is-math-for-a-programmer/</link>
		<comments>http://www.xuwenhao.com/2011/02/01/how-import-is-math-for-a-programmer/#comments</comments>
		<pubDate>Tue, 01 Feb 2011 14:58:08 +0000</pubDate>
		<dc:creator>Stanley Xu</dc:creator>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[Math]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://www.xuwenhao.com/?p=768</guid>
		<description><![CDATA[每个计算机系毕业的人，大都学过不少数学课，而且不少学校的计算机系的数学课，通常比一般的其他工科专业的数学要难一些，比如不上高等数学，而是学数学分析，不上线性代数而去上高等代数。但是，大部分毕业了后去做程序员的人，即使是所谓的名校计算机系毕业的，大都工作中也基本完全用不上学的那些数学，基本上，一半时间在CRUD，另一半时间在处理各类字符串、链表、Hash表，知道在面试中回答各种排序的时间复杂度是他们需要的数学的上线了。 而在念书的时候，虽然上大学之前，有不少内行的外行的，年老的年轻的人告诉你，数学很重要啊。但是，通常来说，各个学校的计算机系的同学么，爱好学习的，可能重视的也是Thinking in Java，C++ Primer之类的语言书，或者设计模式之类的架构书，抑或是算法与数据结构这些玩意儿；而像我这样天天偷懒放羊的，也不会把数学当作是什么重要的课程好好学习。所以，“数学真重要”，这句话，似乎对于大家来说，始终只是飘在天上的一句话，随风飘逝了。 于是，五年过去了，程序员们都有了不少的工作经验了，如果不是对工作毫无追求混吃等死的程序员的话，对于天天干活的语言，不论是Java还是C++应该都熟能生巧了，所谓的设计模式、重构、自动化测试等等也手到擒来了，大部分人的title上都加上了Senior了，牛一点的后面大概还跟上了一个Manager，然而，大家都开始考虑一个新的问题——“30岁以后怎么半？”，于是，转PM的转PM，考公务员的考公务员，像我这样仍然抱定——“你看人家美国Rohit都50了还不是天天写程序，别人想请还请不到的”的单纯想法的人越来越少了。然后，就算这些人，时不时也会觉得，自己天天干的超越CRUD的，所谓写点OO的框架，不也是很无聊的体力活么，写程序的人干两年谁都会干。于是，又有不少人下海创业了，多年以后，这些人中的大部分都会和我一样悲催的没有挣到前继续回来给大大小小的公司写程序。 其实，杯具往往发生在一开始，其实，要是咱们当年好好学习，才会发现，也许数学对于你当个不错的程序员来说，没那么重要，但是要再往上走一步，有一点点技术上的创新，就都是数学的事儿了。两年前，我在T公司，用Configurator处理某个程序的时候，开始有点儿意识到这一点了，于是，那阵子还花了不少时间重新翻了翻数理逻辑。今年，换了新工作后为了工作看点儿机器学习的东西的时候，终于发现，这全都是数学啊。当你要超越CRUD，做任何一点点有创新性的技术的时候（不说产品），最有机会遇到的问题，其实是数学问题。虽然从Spring到Hibernate到Rails之类的框架，或者Hadoop，HBase之类的分布式计算框架，也都是技术上的重大革新，但是这些框架类的程序，完善都是阶段性的，一旦出现后，很快都会有相应的Best Practice，又会成为熟练工种的活。而真正针对问题域的解答，反是每天都可以有些新鲜的想法、思路和方案的，这些，往往有个数学的门槛。所以如果你真是挺喜欢写程序的，而且希望自己一直能写更好玩更难的程序，总有一天，你要过了这一道坎儿。 所以我很是同意不知道是谁说得，如果你只想当个good programmer，那么数学不重要。但是如果你想当个great programmer，那么数学很重要。在你手里只有锤子的时候，你看什么东西都会是个钉子，想想你如果没有学过算法和数据结构，可能你的大部分程序需要自己写排序的话，都会是傻傻地冒泡吧，反正对于大部分程序来说，在现在这么快的PC下，这点时间差别，大部分情况下，也就是让你等程序执行测试的时候，多个倒杯水的时间。但是很多新鲜，好玩，有挑战的问题，很多数学的概念没有的话，恐怕不是多等个倒水的时间了。而如果你过了这个门槛，你又会发现，一个崭新的世界，又到了你的面前。 回过头来，我说数学重要的话，那么重要的是哪些呢？大家常说的通常是离散数学，不过最近比较热门的机器学习这个方向，我目前看到的相关资料都大量依赖于线性代数和概率论，以及一点点微积分。所以，如果你和我一样，希望做点有追求的技术工作的话，开始花点时间学习数学吧。其实万事开头难，也许你和我一样，对着一堆公式符号，感到头晕眼花，但是如果真得按下心来，看上一个小时，这么坚持个一周，其实就会发现，这没啥难的，就当学门新的编程语言得了。 PS：如果在google中搜索程序员 数学的话，第一个链接是程序员怎样学数学，我觉得这篇文章写得相当不错。我也非常同意，广度有限比较有效，容易激发学习的兴趣，而且能和实际的工作和现实世界的问题、项目相结合。]]></description>
			<content:encoded><![CDATA[<p>每个计算机系毕业的人，大都学过不少数学课，而且不少学校的计算机系的数学课，通常比一般的其他工科专业的数学要难一些，比如不上高等数学，而是学数学分析，不上线性代数而去上高等代数。但是，大部分毕业了后去做程序员的人，即使是所谓的名校计算机系毕业的，大都工作中也基本完全用不上学的那些数学，基本上，一半时间在CRUD，另一半时间在处理各类字符串、链表、Hash表，知道在面试中回答各种排序的时间复杂度是他们需要的数学的上线了。</p>
<p>而在念书的时候，虽然上大学之前，有不少内行的外行的，年老的年轻的人告诉你，数学很重要啊。但是，通常来说，各个学校的计算机系的同学么，爱好学习的，可能重视的也是Thinking in Java，C++ Primer之类的语言书，或者设计模式之类的架构书，抑或是算法与数据结构这些玩意儿；而像我这样天天偷懒放羊的，也不会把数学当作是什么重要的课程好好学习。所以，“数学真重要”，这句话，似乎对于大家来说，始终只是飘在天上的一句话，随风飘逝了。</p>
<p>于是，五年过去了，程序员们都有了不少的工作经验了，如果不是对工作毫无追求混吃等死的程序员的话，对于天天干活的语言，不论是Java还是C++应该都熟能生巧了，所谓的设计模式、重构、自动化测试等等也手到擒来了，大部分人的title上都加上了Senior了，牛一点的后面大概还跟上了一个Manager，然而，大家都开始考虑一个新的问题——“30岁以后怎么半？”，于是，转PM的转PM，考公务员的考公务员，像我这样仍然抱定——“你看人家美国Rohit都50了还不是天天写程序，别人想请还请不到的”的单纯想法的人越来越少了。然后，就算这些人，时不时也会觉得，自己天天干的超越CRUD的，所谓写点OO的框架，不也是很无聊的体力活么，写程序的人干两年谁都会干。于是，又有不少人下海创业了，多年以后，这些人中的大部分都会和我一样悲催的没有挣到前继续回来给大大小小的公司写程序。</p>
<p>其实，杯具往往发生在一开始，其实，要是咱们当年好好学习，才会发现，也许数学对于你当个不错的程序员来说，没那么重要，但是要再往上走一步，有一点点技术上的创新，就都是数学的事儿了。两年前，我在T公司，用Configurator处理某个程序的时候，开始有点儿意识到这一点了，于是，那阵子还花了不少时间重新翻了翻数理逻辑。今年，换了新工作后为了工作看点儿机器学习的东西的时候，终于发现，这全都是数学啊。当你要超越CRUD，做任何一点点有创新性的技术的时候（不说产品），最有机会遇到的问题，其实是数学问题。虽然从Spring到Hibernate到Rails之类的框架，或者Hadoop，HBase之类的分布式计算框架，也都是技术上的重大革新，但是这些框架类的程序，完善都是阶段性的，一旦出现后，很快都会有相应的Best Practice，又会成为熟练工种的活。而真正针对问题域的解答，反是每天都可以有些新鲜的想法、思路和方案的，这些，往往有个数学的门槛。所以如果你真是挺喜欢写程序的，而且希望自己一直能写更好玩更难的程序，总有一天，你要过了这一道坎儿。</p>
<p>所以我很是同意不知道是谁说得，如果你只想当个good programmer，那么数学不重要。但是如果你想当个great programmer，那么数学很重要。在你手里只有锤子的时候，你看什么东西都会是个钉子，想想你如果没有学过算法和数据结构，可能你的大部分程序需要自己写排序的话，都会是傻傻地冒泡吧，反正对于大部分程序来说，在现在这么快的PC下，这点时间差别，大部分情况下，也就是让你等程序执行测试的时候，多个倒杯水的时间。但是很多新鲜，好玩，有挑战的问题，很多数学的概念没有的话，恐怕不是多等个倒水的时间了。而如果你过了这个门槛，你又会发现，一个崭新的世界，又到了你的面前。</p>
<p>回过头来，我说数学重要的话，那么重要的是哪些呢？大家常说的通常是离散数学，不过最近比较热门的机器学习这个方向，我目前看到的相关资料都大量依赖于线性代数和概率论，以及一点点微积分。所以，如果你和我一样，希望做点有追求的技术工作的话，开始花点时间学习数学吧。其实万事开头难，也许你和我一样，对着一堆公式符号，感到头晕眼花，但是如果真得按下心来，看上一个小时，这么坚持个一周，其实就会发现，这没啥难的，就当学门新的编程语言得了。</p>
<p>PS：如果在google中搜索<a href="http://www.google.com/#sclient=psy&#038;hl=en&#038;site=&#038;source=hp&#038;q=程序员+数学&#038;aq=f&#038;aqi=&#038;aql=&#038;oq=&#038;pbx=1&#038;fp=4565d1ad08660d4d">程序员 数学</a>的话，第一个链接是<a href="http://article.yeeyan.org/view/pluto/2365">程序员怎样学数学</a>，我觉得这篇文章写得相当不错。我也非常同意，广度有限比较有效，容易激发学习的兴趣，而且能和实际的工作和现实世界的问题、项目相结合。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.xuwenhao.com/2011/02/01/how-import-is-math-for-a-programmer/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>居然一年只写了一篇</title>
		<link>http://www.xuwenhao.com/2011/01/28/only-one-blog-last-year/</link>
		<comments>http://www.xuwenhao.com/2011/01/28/only-one-blog-last-year/#comments</comments>
		<pubDate>Fri, 28 Jan 2011 14:45:59 +0000</pubDate>
		<dc:creator>Stanley Xu</dc:creator>
				<category><![CDATA[Life]]></category>

		<guid isPermaLink="false">http://www.xuwenhao.com/?p=763</guid>
		<description><![CDATA[看到上篇blog的评论是“今年就这一篇”？才发现，的确，整整一年一篇blog都没写。的确，理由和借口可以找很多，因为有了娃儿，没时间写；因为工作忙，没时间写；看得越多，越觉得自己无知，觉得没必要写。但仔细想想，还是有些疏懒了，其实草稿箱里还有几篇写到一半的，其实像领导大人那样，贴贴娃儿的照片，记录记录成长过程，也挺好的。 过去一年多，其实变动还是蛮大的。生活上，有了娃儿，虽然平时都要上班，娃儿大都是爷爷奶奶带，但是自己的空余时间也多半交代给娃儿了。工作上，有一段时间做得无比痛苦，为了达成目标，花了很多精力做了许多自己并不那么擅长的事情，最后结果也不好，导致有一段时间都要对自己产生怀疑了；最后，在十一之后，托HL老大的福，最终决定换个环境，加入了欢乐无比的M公司，目前看来是个相当正确的决定，做上了两年前离开T公司时候就想做的有点儿技术挑战的技术活儿，也重新对自己有了点信心。 这一年，有了娃儿之后，生活倒是规律了很多，虽然也有偶尔熬通宵干活儿的时候，但是整体三餐正常，于是体重居然也长了那么一点儿，不知道算是奇迹还是中年发福的开始。 希望今年多写点博客，不为别的，需要对自己做过的事情多总结总结。]]></description>
			<content:encoded><![CDATA[<p>看到上篇blog的评论是“今年就这一篇”？才发现，的确，整整一年一篇blog都没写。的确，理由和借口可以找很多，因为有了娃儿，没时间写；因为工作忙，没时间写；看得越多，越觉得自己无知，觉得没必要写。但仔细想想，还是有些疏懒了，其实草稿箱里还有几篇写到一半的，其实像<a href="http://blog.prettydss.com">领导大人</a>那样，贴贴娃儿的照片，记录记录成长过程，也挺好的。</p>
<p>过去一年多，其实变动还是蛮大的。生活上，有了娃儿，虽然平时都要上班，娃儿大都是爷爷奶奶带，但是自己的空余时间也多半交代给娃儿了。工作上，有一段时间做得无比痛苦，为了达成目标，花了很多精力做了许多自己并不那么擅长的事情，最后结果也不好，导致有一段时间都要对自己产生怀疑了；最后，在十一之后，托HL老大的福，最终决定换个环境，加入了欢乐无比的M公司，目前看来是个相当正确的决定，做上了两年前离开T公司时候就想做的有点儿技术挑战的技术活儿，也重新对自己有了点信心。</p>
<p>这一年，有了娃儿之后，生活倒是规律了很多，虽然也有偶尔熬通宵干活儿的时候，但是整体三餐正常，于是体重居然也长了那么一点儿，不知道算是奇迹还是中年发福的开始。</p>
<p>希望今年多写点博客，不为别的，需要对自己做过的事情多总结总结。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.xuwenhao.com/2011/01/28/only-one-blog-last-year/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>又一年过去了</title>
		<link>http://www.xuwenhao.com/2010/02/11/another-year-passed/</link>
		<comments>http://www.xuwenhao.com/2010/02/11/another-year-passed/#comments</comments>
		<pubDate>Thu, 11 Feb 2010 08:43:38 +0000</pubDate>
		<dc:creator>Stanley Xu</dc:creator>
				<category><![CDATA[Life]]></category>

		<guid isPermaLink="false">http://www.xuwenhao.com/?p=759</guid>
		<description><![CDATA[又一年过去了，一年一年真是快啊，其实应该在元旦时候写总结的，只是实在忙得没有精神去思考总结些什么，只好拖到过年了。办公室里基本已经没什么人了，没到过年的时候，大家都无心工作，冷冷清清，窗外又是阴沉的小雨，真有些凄风苦雨的味道呢。 2009年对我来说最重要的一件事情，就是有了2.0了，一下次所有的业余时间都被占据了，基本没有了自由时间，睡眠时间也常常足足，好处是不会随便挥霍时间感到心理内疚了，坏处是也完全没时间搞点有意义的事了。2.0长得很可爱，不过我到也没有别人常说的见不到特别想的感觉，在身边的时候挺喜欢，忙得时候见不到感觉也还好，我一向是个没心没肺的家伙，看来有了孩子，也变不了多少。 然后今天年中来了这家新公司上班，写了很多代码，写了很多文档，写了很多PPT，数量比我以前写得多多了，质量写得比我以前写得差多了，希望2010年，数量稍微少一点，质量能比之前多一些吧。技术角度来说，按照去年的计划，完成度大概只有20%吧，基本上把简单的javascript和jquery摸熟了，然后今年大量的时间都浪费在无聊的struts2，spring，hibernate和axis2上了，本来想好好看看hardcore的东西，结果大半年全在折腾应用层的和项目管理的内容。Ruby和Rails在3月之后基本没怎么在看过，现在Rails3都出来了，也没精力跟了，10年应该也不会把公司的Web开发迁移到Rails上来。 今年的话，计划新学的语言应该是Objective-C和iPhone/iPad开发，顺便拾起一点基本的C，不出以外的话，应该会入手一台iPhone或者iPad。然后预计仍然要花不少时间折腾Java的服务器端，只是期望能把精力主要放在引擎和框架上，应用端，都交给手下的工程师吧。产品上，预计还是有大量的产品设计，方案PPT要做，虽然不是我喜欢的工作内容，但是总还要勉为其难地做下去，也就这一两年的时间了，如果折腾成功了，旧考虑计划计划40岁之前退休。如果成不了，也只好放弃折腾，以后就打工赚钱，养家糊口，混吃等死了。]]></description>
			<content:encoded><![CDATA[<p>又一年过去了，一年一年真是快啊，其实应该在元旦时候写总结的，只是实在忙得没有精神去思考总结些什么，只好拖到过年了。办公室里基本已经没什么人了，没到过年的时候，大家都无心工作，冷冷清清，窗外又是阴沉的小雨，真有些凄风苦雨的味道呢。</p>
<p>2009年对我来说最重要的一件事情，就是有了2.0了，一下次所有的业余时间都被占据了，基本没有了自由时间，睡眠时间也常常足足，好处是不会随便挥霍时间感到心理内疚了，坏处是也完全没时间搞点有意义的事了。2.0长得很可爱，不过我到也没有别人常说的见不到特别想的感觉，在身边的时候挺喜欢，忙得时候见不到感觉也还好，我一向是个没心没肺的家伙，看来有了孩子，也变不了多少。</p>
<p>然后今天年中来了这家新公司上班，写了很多代码，写了很多文档，写了很多PPT，数量比我以前写得多多了，质量写得比我以前写得差多了，希望2010年，数量稍微少一点，质量能比之前多一些吧。技术角度来说，按照去年的计划，完成度大概只有20%吧，基本上把简单的javascript和jquery摸熟了，然后今年大量的时间都浪费在无聊的struts2，spring，hibernate和axis2上了，本来想好好看看hardcore的东西，结果大半年全在折腾应用层的和项目管理的内容。Ruby和Rails在3月之后基本没怎么在看过，现在Rails3都出来了，也没精力跟了，10年应该也不会把公司的Web开发迁移到Rails上来。</p>
<p>今年的话，计划新学的语言应该是Objective-C和iPhone/iPad开发，顺便拾起一点基本的C，不出以外的话，应该会入手一台iPhone或者iPad。然后预计仍然要花不少时间折腾Java的服务器端，只是期望能把精力主要放在引擎和框架上，应用端，都交给手下的工程师吧。产品上，预计还是有大量的产品设计，方案PPT要做，虽然不是我喜欢的工作内容，但是总还要勉为其难地做下去，也就这一两年的时间了，如果折腾成功了，旧考虑计划计划40岁之前退休。如果成不了，也只好放弃折腾，以后就打工赚钱，养家糊口，混吃等死了。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.xuwenhao.com/2010/02/11/another-year-passed/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>飞来飞去</title>
		<link>http://www.xuwenhao.com/2010/01/26/fly-in-china/</link>
		<comments>http://www.xuwenhao.com/2010/01/26/fly-in-china/#comments</comments>
		<pubDate>Mon, 25 Jan 2010 17:40:52 +0000</pubDate>
		<dc:creator>Stanley Xu</dc:creator>
				<category><![CDATA[Life]]></category>

		<guid isPermaLink="false">http://www.xuwenhao.com/?p=756</guid>
		<description><![CDATA[先到贵阳，再到北京，然后天津，然后回上海。过去几个月，安安心心做点事的时间太少了，一旦在路上，就只能什么东西都只看个大概了，希望年后能够摆脱这样的状态。 在贵阳在路边摊吃牛肉粉，臭豆腐；在北京半夜街边吃卤煮。当时想想，总怕自己拉肚子，想想前两年可能都不会吃这些，但是要再早几年，也就又爱吃路边摊了。话说，很多时候，人都是在被外部世界改变的，要做到君子不器，还真不是一件容易的事。 工作不算顺利，整个团队需要弥补，需要专注，虽然老板们都很清楚我们要专注，但似乎大家还是忍不住，有机会总要去试那么一下，过去半年，试的太多，好好做的东西太少。有时候，遵守自己给自己的纪律都是如此之难。 看了看一家据说还算不错的竞争对手的产品两年前的演示，发现也不过尔尔，话说两年前，我正在把时间浪费在一个最后毫无意义的项目上。想一想，这时间过得还真快，大概从2007年11月之后，做的事情都不太让自己满意，希望今年，会是一个新的起点。 飞机上大致翻了一遍 iPhone 3开发基础教程，和之前看的Android的Tutorial比较起来，真的一个是设计师文化，一个是工程师文化。iPhone始终专注在于各个View之间的转化，而Android则是喜欢讲Service，Activities，Receivers，教程关注的焦点都不一样，真是很有意思呢。当然，现在的Android是远远不行的，我手上的G2就是动辄没响应，浏览器Bug无法点击，如果再来一次的话，定然会选择多出点血入iPhone的。 好吧，最后说一句，我想我们家2.0和Pretty大人了。 Dreanhost又到期了，我想我这个懒人，还会多花这些钱，再续个两年吧。]]></description>
			<content:encoded><![CDATA[<p>先到贵阳，再到北京，然后天津，然后回上海。过去几个月，安安心心做点事的时间太少了，一旦在路上，就只能什么东西都只看个大概了，希望年后能够摆脱这样的状态。</p>
<p>在贵阳在路边摊吃牛肉粉，臭豆腐；在北京半夜街边吃卤煮。当时想想，总怕自己拉肚子，想想前两年可能都不会吃这些，但是要再早几年，也就又爱吃路边摊了。话说，很多时候，人都是在被外部世界改变的，要做到君子不器，还真不是一件容易的事。</p>
<p>工作不算顺利，整个团队需要弥补，需要专注，虽然老板们都很清楚我们要专注，但似乎大家还是忍不住，有机会总要去试那么一下，过去半年，试的太多，好好做的东西太少。有时候，遵守自己给自己的纪律都是如此之难。</p>
<p>看了看一家据说还算不错的竞争对手的产品两年前的演示，发现也不过尔尔，话说两年前，我正在把时间浪费在一个最后毫无意义的项目上。想一想，这时间过得还真快，大概从2007年11月之后，做的事情都不太让自己满意，希望今年，会是一个新的起点。</p>
<p>飞机上大致翻了一遍 iPhone 3开发基础教程，和之前看的Android的Tutorial比较起来，真的一个是设计师文化，一个是工程师文化。iPhone始终专注在于各个View之间的转化，而Android则是喜欢讲Service，Activities，Receivers，教程关注的焦点都不一样，真是很有意思呢。当然，现在的Android是远远不行的，我手上的G2就是动辄没响应，浏览器Bug无法点击，如果再来一次的话，定然会选择多出点血入iPhone的。</p>
<p>好吧，最后说一句，我想我们家2.0和Pretty大人了。</p>
<p>Dreanhost又到期了，我想我这个懒人，还会多花这些钱，再续个两年吧。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.xuwenhao.com/2010/01/26/fly-in-china/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>专注产品</title>
		<link>http://www.xuwenhao.com/2010/01/18/focus-on-product/</link>
		<comments>http://www.xuwenhao.com/2010/01/18/focus-on-product/#comments</comments>
		<pubDate>Mon, 18 Jan 2010 14:12:05 +0000</pubDate>
		<dc:creator>Stanley Xu</dc:creator>
				<category><![CDATA[Life]]></category>
		<category><![CDATA[Work]]></category>

		<guid isPermaLink="false">http://www.xuwenhao.com/?p=754</guid>
		<description><![CDATA[被Mars同学留言说更新太少，一看……半年没写了……嗯，好吧，可以借口是有了2.0，没有时间了，不过今年居然没写年终总结，而且也没有未来展望，看来完全被2.0套牢了，人生没有希望了……回头想想，2009是瞎折腾的一年，越折腾越混乱，希望2010年能专注在公司的产品上，从无到有，打造出个像像样样能赚钱的产品，也是过去一年一直希望做但是总是没机会来做的事情。]]></description>
			<content:encoded><![CDATA[<p>被Mars同学留言说更新太少，一看……半年没写了……嗯，好吧，可以借口是有了2.0，没有时间了，不过今年居然没写年终总结，而且也没有未来展望，看来完全被2.0套牢了，人生没有希望了……回头想想，2009是瞎折腾的一年，越折腾越混乱，希望2010年能专注在公司的产品上，从无到有，打造出个像像样样能赚钱的产品，也是过去一年一直希望做但是总是没机会来做的事情。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.xuwenhao.com/2010/01/18/focus-on-product/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>保护源代码？</title>
		<link>http://www.xuwenhao.com/2009/08/22/protect-your-source-code/</link>
		<comments>http://www.xuwenhao.com/2009/08/22/protect-your-source-code/#comments</comments>
		<pubDate>Sat, 22 Aug 2009 02:24:18 +0000</pubDate>
		<dc:creator>Stanley Xu</dc:creator>
				<category><![CDATA[Quotation]]></category>

		<guid isPermaLink="false">http://www.xuwenhao.com/?p=751</guid>
		<description><![CDATA[引自水木 对大部分公司来说，封闭代码没多大意义，除了避免让客户知道自己公司的代码写的非常烂之外。]]></description>
			<content:encoded><![CDATA[<p>引自<a href="http://www.newsmth.net/bbscon.php?bid=126&#038;id=68201" target="_blank">水木</a></p>
<blockquote><p>对大部分公司来说，封闭代码没多大意义，除了避免让客户知道自己公司的代码写的非常烂之外。</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.xuwenhao.com/2009/08/22/protect-your-source-code/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss><!-- Dynamic page generated in 0.427 seconds. --><!-- Cached page generated by WP-Super-Cache on 2012-05-09 05:39:27 -->

