<?xml version="1.0" encoding="UTF-8"?><!-- generator="WordPress/2.8.6" -->
<rss version="0.92">
<channel>
	<title>StephenChan&#039;s Tech Space</title>
	<link>http://blog.endlesscode.com</link>
	<description>潜心修炼</description>
	<lastBuildDate>Tue, 10 Aug 2010 17:19:30 +0000</lastBuildDate>
	<docs>http://backend.userland.com/rss092</docs>
	<language>en</language>
	
	<item>
		<title>读过《观止》</title>
		<description>今晚总算把《观止》看完了，看得比较快，基本上是当叙事小说一样看。这个书名看起来像文艺书，但实际上是讲述Windows NT这个操作系统的创造史。为什么Windows NT这么出色，因为在当时它的诞生改变了人们对操作系统的看法，它引入了现在我们看起来很理所当然但当时还没有的技术：抢占式的多任务处理、可安装在通用的硬件平台、支持32位内存寻址、支持大容量文件并具有容错功能的NTFS（NT File System）等等。当然这些系统功能并没有在书上描述，这本书从头到尾都是在讲述整个NT团队是如此在艰苦的进度压力和技术压力之下花了将近5年时间创造出NT。

这个NT团队的领导人就是Dave Cutler，性格独断脾气火爆，技术牛B，现在来说就是一个传奇的程序员，当他领导NT团队的时候已经是个快50岁的人了。有个小插曲或者会更令人记住他是谁，就是当他招聘小秘的时候会问一个问题“How do u think about the word 'fuck'?"，只有那个回答了"Its my favorite word”的MM才拿到了offer。

从1988年10月开始到正式发布的1993年7月23日，历时接近5年时间，团队从开始的20多人到最后的200多人，在这5年时间里面NT团队面对的是各种功能需求的增加、遥遥无期的进度、不断冒出的bug，还有其他非技术问题，如家庭和爱人，可以说是可歌可泣，NT团队的每个成员为Windows NT奉献太多了。

虽然看得比较快，但是一些体会还是想记录一下，以后有时间再翻出来看或者也会有不同的体会。

从本来只有一个内核开发的团队，到后面慢慢增加了图形开发小组和网络开发小组，整个团队大部分人都是物理和数学出身，毕竟从理科出身的容易投入到计算机行业，加上当时计算机行业还远没现在这么热门。由于当时NT的目标定得比较高，因此很多迎合市场的需求都被添加到功能列表中，并要求兼容以前的DOS和Windows程序，不停地添加功能需求以及保证兼容性基本上就直接导致了进度问题，由于领导的Dave Cutler是个基本上为了NT放弃了家庭的人，因此给NT的团队带来的直接影响就是在进度压力之下的疯狂加班，纵然如此，但是在微软的给予的高股票期权和Cutler的压迫之下，团队的成员也是能积极高效地工作，其实这里，我还觉得有个原因是在这种环境之下驱动大家去工作的，就是大家都希望能够创造出一个出色的产品，虽然工作辛苦，但是这种渴望创造的欲望也是驱动团队成员努力工作的一个原因。

程序员、测试员和构建员是组成NT团队的主要3个角色，在那个年代，测试员和构建员的地位并不高，但是慢慢程序不断地被挑出bug并不断地被完善，越显得测试员和构建员的重要性。相比于目前自己所做的项目，哪怕是相差20年，目前我们项目的流程还是比不上那时的NT团队。每个程序员的commit都是基于不会导致构建失败的前提下，当然构建的时机可能是即时也可能是固定某个时候，但是每个程序员的commit都是使构建能正常进行的，整个流程都是井然有序地进行。而且，更让我欣赏NT团队的是，在项目的后期，Dave Cutler甚至是长期定居在构建实验室，来专门看每个程序员提交的各种代码，来保证程序代码的质量，那么多不知道他怎么看得过来。对于程序员犯的错误，Dave Cutler可是不留情面地批评，或者正是这种领导的压迫之下反而提高了团队成员的代码严谨，或者可以说是领导威严的作用。

团队规模变大，可能就增加了成员之间对技术问题的冲突，但是正如书上说，这种冲突有时候会激发对程序代码的改进，其实倒觉得这种冲突是来源于对自己代码逻辑的自信，或者说是个性鲜明，和提倡中庸之道的国内还是有点区别。

到了项目后期，真的可以算得上夺命狂奔，因为有了deadline，所以对bug的分类控制、暂停新功能需求的加入、不停的压力测试、客户的bug反馈和beta版的多次发布等等，各个成员都日以继夜地修正各种showstopper和一等级的bug。

最后Windows NT发布了，微软就站在了操作系统的顶峰了。而从始自终，Gates都没有对NT团队有什么干预，只是定期了解开发进度和进行产品的测试，给了NT团队很大的自由度。

《观止》这本书虽然只是描述了整个NT的创造史，其实更像一本项目管理的书。 </description>
		<link>http://blog.endlesscode.com/2010/08/11/reading-showstopper/</link>
			</item>
	<item>
		<title>香港游记</title>
		<description>上周5去香港玩了3天，本来是想昨晚就写一下的，但是10点多回到来和同学吃了个宵夜就晚了。

周5早上7点半就醒了，然后去匆匆地坐地铁去火车站，坐传说中的河蟹号到罗湖，其实这还是挺快的，河蟹号一个小时就从广州到罗湖了，不过第一次过境，还是花了点时间，到香港之后，再从地铁和公交到西环，这里也花了1.5个小时了，不过香港的公交比广州的舒服多了，没有广州挤得那么厉害，而且，小公巴如果满人了司机是不会让人再上来的。
Day 1：
第一天到阿清那已经1点多了，两个人就去附近吃了个性价比还算可以的餐厅吃了个扒，然后接下来就去港大了。港大的正门没有像一些大学那些有气势，相对来说还是比较小的，而且港大也是建在半山腰的，从西环那里上去都是坐电梯上去的。参观了一下港大，中山像、莲花池、月明池，不过有个雕塑还是纪念敏感词事件的，叫国殇之柱。就是下面这个，照得不太好，要侧着脖子看。

接着下午就去了黄大仙，我和阿清都求了个事业签，那个解签的说我的是中下签，最近2个月事业不顺，要跳槽就趁早，我听得都蒙了。然后她说阿清下下签，阿清一听，皱了皱眉头，“哼？”的一声，那个解签的又说阿清会有贵人相助，不用太担心，这个有点搞笑，后来还叫我们去求个护符，看来这个中下/下下-&#62; 护符是个固定的模式。

之后我们就去了一趟铜锣湾，商业街那是非常地热闹，不过我们也只是去买了几件衣服基本没有买什么了，毕竟逛商业街的确不应该是2个男的应该做的事情。

晚上就去了金紫荆广场，那里游客也不少，其实金紫荆广场也没有什么大的看点，就只有一个金色的紫荆花雕像。接下来就坐游轮去星光大道那边，星光大道那里都是一些明星的手印，一些较为出名的就比较多人围观，比如刘德华、成龙等等，我也照了几个，下面这张是刘德华的，嘻嘻。基本上去了星光大道就回去了，本来还想去兰桂坊的，但逛了大半天太累了。
Day 2：
因为第一天玩得太累了，因此第二天睡到很晚才起来，所以上午也就没有去什么地方玩，由于同学下午要去上课，我也背着个书包又做了一回学生。上的这门课是Network Security，professor是全程用英语讲课，不过港式英语口音太怪了。讲到Security Model的时候提到一个牛B的模型“Chinese Wall”，“Prevent information flow that will result in conflict of interest”，这个GFW都已经算是一个安全模型了。

晚上本来还想去一趟兰桂坊的，但是由于下大雨，两个人只能回去看电影玩星际了。这一天基本上没有怎么出去外面玩。
Day 3：
今天也是睡到很晚才起来，所以行程都是从下午开始。因为晚上要回广州，所以下午能计划的比较少，就去坐了一下山顶缆车，不过由于是周日，人那是相当地多。去到了山顶，俯视全香港，那景色是相当地让人看起来舒服：

晚上去大快活把晚餐消灭了，不过刚好赶上下午茶时间，所以价格还是相当地便宜，两个人70HK$已经吃得非常赞了，米线、蜜汁鸡比、西多士还有红豆冰，消费没有原来想象中那么高。


结束
总的来说，玩得还算不错，因为是借宿在同学家，因此也省了一笔，而且这3天阿清都是带我去一些性价比相当高的地方吃饭，光是吃扒都吃了2天，囧，港大饭堂的、华人餐厅、中环的餐厅，吃扒吃到牙都累了，不过凡是能点西多士的地方我都会点这个。衣服以我们这边的消费水平来讲是比较贵，但以香港那边的消费水平来看其实也是一般般。没有去海洋公园和迪士尼，两个男的去这两个景点还真是没有意思。 </description>
		<link>http://blog.endlesscode.com/2010/08/10/journey-to-hk/</link>
			</item>
	<item>
		<title>写在毕业一年后</title>
		<description>不经不觉毕业也一年了，走得太匆忙，并没有和大家留下什么伤感的回忆。

从入职到现在，除了觉得时间过得很快之外，就是觉得自己没有把握好时间，或者毕业后各方面的原因学习动力和激情也比不上在学校的时候。

回头看看这一年……

09年的下半年，大部分时间是投入在研究fopen这个Facebook开源SNS，由于这是搭建在Linux平台并用php和c++写的，Linux和php这两方面对我来说都不太熟悉，折腾了好长的一段时间。fopen并没有原本所期待那样能够真正地投入到正式的产品使用，更多的，它只是Facebook的一个超级简化版，而且文档也相当地不完整，整个fopen依赖的库文件也很多，我当时也没能弄明白这些库文件是做什么的。在改写JavaScript的部分，虽然代码逻辑是比较清晰，但是像它那样的逻辑重写1000的JavaScript代码都要10多秒，不知道它在正式投入使用的时候是怎么提升解析速度的，又或者是正式产品中是使用了C++重写或者利用其他的一些缓存技术。在OpenAPI部分，那时候还弄不明白那个timestamp和callback的参数作用，后来才明白timestamp是用于防止replay attack，而callback是为了使用jsonp的，只怪当时知识面太窄了。虽然最后也用python实现了类似的JavaScript Parser和OpenAPI以及JavaScript client lib，但实际上需要完善的空间实在太多，只是时间无法安排过来。、

09年11月份开始的时候封闭开发了好长一段时间，封闭开发最大的体会就是环境很安静，但人能够很集中精神地开发，效率的确高很多。其实这段时间最大的收获是在美林的时候认识了老邓，他是云风带领的那个工作室的成员，他把我带进了函数式编程的世界，跟我讲了很多除了c++、java、.net之外的其他语言情况，比如lisp、squeak、haskell、erlang等等，还跟我讲了计算机世界里面一些有意思的事情和人物，并介绍了好几本书给我。作为刚毕业的新人，老员工知识和经验的分享正是新人所需要的。

从新年放假回来后，前2个月是主要是完成一些比较琐碎的东西，开发一些平台上的小功能和修复一些bug。后2个月主要是开发一些营销活动，进度非常赶，这些活动项目时效比较短，我只是加班把这些活动项目做出来，但是我没有时间把这些项目做得好，我自己是个追求完美的人，作品写得这么挫却又无可奈何心里面是何等的不爽。我觉得公司的营销同事制定营销推广计划的时候应该和开发人员先协商进度安排以及项目上线的各方面可行性，而不是把计划定好了，然后有什么进度压力就直接推给开发人员。

Python写了一年多，但是我觉得在同一届入职的同事里面，掌握得最差的应该是我了。在Python花的时间的确是太少了，我仍然需要阅读更多关于Python方面的资料和写更多的代码，pythonic是我的目标。JavaScript方面在实际上项目倒是提高了不少，对闭包和作用域链的理解，一些IE的hack，页面脚本的加载顺序等等，Firebug的脚本调试作用也相当的强大和方便。总的来说，各方面都有一定的提高，不过前端的css的样式设置我依然觉得很痛苦。虽然平时都是在Linux环境下开发，但是我对Linux的理解还是相当地肤浅，Shell编程和Linux C的提高是我的下一个目标，Linux下的很多命令，如iptables、tr、sort、awk等等只是略懂一二，我觉得太多的Linux常识我需要去补充。

从自己每个月写的blog数量基本上可以反映出自己在当月的工作繁忙程度以及自身的状态。6月份的状态算是上半年中最好的了，放下了一些纠结让自己更能专注。我很怀念在学校那种为了完成一个作业或者项目连续好多个晚上搞得通宵，不分昼夜专注地去做，工作之后很难有这种机会了。前几天和大学的同事吃饭，也是舍友，他说他想花5年的时间给自己充电再去微软，他当初在百度和微软实习过，只是有点可惜。前段时间回到学校，也得知有位同学正准备出国。感慨大家都很有目标，也同时为了自己的目标而在努力地奋斗。一生何求，我也得要为自己定个目标。

胡扯了一下就写了2个小时，时间是只能靠自己把握的，这是个和青春竞争的人生阶段。 </description>
		<link>http://blog.endlesscode.com/2010/07/01/one-year-after-graduation/</link>
			</item>
	<item>
		<title>zz Dojo Javascript 编程规范</title>
		<description>虽然这说是Dojo的编程规范，但实际上大部分都是普遍应用的规范，所以就当是JavaScript的编程规范转载过来了
前言
相当不错的 Javascript 编程风格规范，建议大家采用此规范编写 Javascript。原文链接： http://dojotoolkit.org/developer/StyleGuide 。
翻译（Translated by）：i.feelinglucky{at}gmail.com from http://www.gracecode.com ，转载请注明出处、作者和翻译者，谢谢配合。
本文地址： http://code.google.com/p/grace/wiki/DojoStyle 。

序
Any violation to this guide is allowed if it enhances readability.
所有的代码都要变成可供他人容易阅读的。

快读参考
核心 API 请使用下面的风格：




结构
规则
注释


模块
小写
不要使用多重语义（Never multiple words）


类
骆驼



公有方法
混合
其他的外部调用也可以使用 lower_case()，这样的风格


公有变量
混合



常量
骆驼 或 大写



下面的虽然不是必要的，但建议使用：




结构
规则


私有方法
混合，例子：_mixedCase


私有变量
混合，例子：_mixedCase


方法（method）参数
混合，例子：_mixedCase, mixedCase


本地（local）变量
混合，例子：_mixedCase, mixedCase



命名规范

	变量名称 必须为 小写字母。
	类的命名使用骆驼命名规则，例如：
Account, EventHandler

	常量 必须 在对象（类）或者枚举变量的前部声明。枚举变量的命名必须要有实际的意义，并且其成员 必须 使用骆驼命名规则或使用大写：
var NodeTypes = {
    Element : 1,
    DOCUMENT: 2
}
	简写单词 不能使用 大写名称作为变量名：
getInnerHtml(), getXml(), XmlDocument
	方法的命令 必须 为动词或者是动词短语：
obj.getSomeValue()
	公有类的命名 必须 ...</description>
		<link>http://blog.endlesscode.com/2010/06/25/zz-coding-convention-of-javascript/</link>
			</item>
	<item>
		<title>zz HTML代码编写规范和建议</title>
		<description>转载来源：http://www.cnblogs.com/nicolaszhao/archive/2010/04/15/1712796.html
使用HTML5的DOCTYPE声明
&#60;!DOCTYPE html&#62; ，目前IE6，IE7还不认识，所以会以标准模式渲染页面。但是在其他浏览器下，在图文混排时图片下方会出现间隔空隙。 解决办法：

    img {
        vertical-align: bottom;
    }
页面显示字符集
使用HTML5的简写方式： &#60;meta charset="utf-8" /&#62;

遵循xhtml 1.0规则
这里只是为了编写HTML代码时，统一规范而已，在HTML5中已经不需要这样严格了，但是我们还是要规范下比较好。


	所有标签必须结束；
	所有标签必须小写；
	标签属性都必须用引号引起来（单引号或双引号）；
	标签属性必须有值：
    &#60;select&#62;
        &#60;option selected="selected"&#62;&#60;/option&#62;
    &#60;/select&#62;
    &#60;input type="checkbox" checked="checked" /&#62;

	所有特殊符号必须转义。


合理使用标签

	标签合理嵌套：a、span、strong、em、p、h1~h6等元素不能包含：div、ul、ol、dl、p；
	严禁多div症、多span症、多table症，正确使用标签表示DOM结构，在文档没有css的条件下，任然具有结构和可读性：

	h1~h6：文章标题、内容区块标题
	p：文本段落
	strong/em：强调文本
	dl：包括标题和内容简介的区块
	ul：无序列表
	ol：有序列表
	img：图像，必须加上alt属性来表示图像代替文本，背景和按钮不要使用该标签，请使用css处理。
	table：数据网格，规则的分栏布局，必须显性定宽和定高
	表单结构

	使用fieldset做字段分类；
	使用legend表示分类标题；
	使用label表示字段文本，添加必要的for属性。




	严禁使用已在xhtml 1.0中移除的用于表示样式的标签：s、i、b、font

规范命名

	id： ...</description>
		<link>http://blog.endlesscode.com/2010/06/25/zz-coding-convention-of-html/</link>
			</item>
	<item>
		<title>How MapReduce Works</title>
		<description>一、从Map到Reduce
MapReduce其实是分治算法的一种实现，其处理过程亦和用管道命令来处理十分相似，一些简单的文本字符的处理甚至也可以使用Unix的管道命令来替代，从处理流程的角度来看大概如下：
cat input &#124; grep &#124;      sort      &#124;  uniq -c &#124; cat &#62; output
# Input -&#62; Map -&#62; Shuffle &#38; Sort -&#62; Reduce -&#62; Output
简单的流程图如下：

对于Shuffle，简单地说就是将Map的输出通过一定的算法划分到合适的Reducer中进行处理。Sort当然就是对中间的结果进行按key排序，因为Reducer的输入是严格要求按key排序的。

Input-&#62;Map-&#62;Shuffle&#38;Sort-&#62;Reduce-&#62;Output只是从宏观的角度对MapReduce的简单描述，实际在MapReduce的框架中，即从编程的角度来看，其处理流程是Input-&#62;Map-&#62;Sort-&#62;Combine-&#62;Partition-&#62;Reduce-&#62;Output。用之前的对温度进行统计的例子来讲述这些过程。
Input Phase
输入的数据需要以一定的格式传递给Mapper的，格式有多种，如TextInputFormat、DBInputFormat、SequenceFileInput等等，可以使用JobConf.setInputFormat来设置，这个过程还应该包括对输入的数据进行任务粒度划分(split)然后再传递给Mapper。在温度的例子中，由于处理的都是文本数据，输入的格式使用默认的TextInputFormat即可。
Map Phase
对输入的key、value对进行处理，输出的是key、value的集合，即map (k1, v1) -&#62; list(k2, v2)，使用JobConf.setMapperClass设置自己的Mapper。在例子中，将（行号、温度的文本数据）作为key/value输入，经过处理后，从温度的文件数据中提取出日期中的年份和该日的温度数据，形成新的key/value对，最后以list(年,  温度)的结果输出，如[(1950, 10), (1960, 40), (1960, 5)]。
Sort Phase
对Mapper输出的数据进行排序，可以通过JobConf.setOutputKeyComparatorClass来设置自己的排序规则。在例子中，经过排序之后，输出的list集合是按年份进行排序的list(年, 温度)，如[(1950, ...</description>
		<link>http://blog.endlesscode.com/2010/06/24/how-mapreduce-works/</link>
			</item>
	<item>
		<title>HDFS简介</title>
		<description>一、HDFS
HDFS全称是Hadoop Distributed System。HDFS是为以流的方式存取大文件而设计的。适用于几百MB，GB以及TB，并写一次读多次的场合。而对于低延时数据访问、大量小文件、同时写和任意的文件修改，则并不是十分适合。

目前HDFS支持的使用接口除了Java的还有，Thrift、C、FUSE、WebDAV、HTTP等。HDFS是以block-sized chunk组织其文件内容的，默认的block大小为64MB，对于不足64MB的文件，其会占用一个block，但实际上不用占用实际硬盘上的64MB，这可以说是HDFS是在文件系统之上架设的一个中间层。之所以将默认的block大小设置为64MB这么大，是因为block-sized对于文件定位很有帮助，同时大文件更使传输的时间远大于文件寻找的时间，这样可以最大化地减少文件定位的时间在整个文件获取总时间中的比例 。

构成HDFS主要是Namenode（master）和一系列的Datanode（workers）。Namenode是管理HDFS的目录树和相关的文件元数据，这些信息是以"namespace image"和"edit log"两个文件形式存放在本地磁盘，但是这些文件是在HDFS每次重启的时候重新构造出来的。Datanode则是存取文件实际内容的节点，Datanodes会定时地将block的列表汇报给Namenode。

由于Namenode是元数据存放的节点，如果Namenode挂了那么HDFS就没法正常运行，因此一般使用将元数据持久存储在本地或远程的机器上，或者使用secondary namenode来定期同步Namenode的元数据信息，secondary namenode有点类似于MySQL的Master/Salves中的Slave，"edit log"就类似"bin log"。如果Namenode出现了故障，一般会将原Namenode中持久化的元数据拷贝到secondary namenode中，使secondary namenode作为新的Namenode运行起来。
二、读写流程
文件读取


文件读取的过程如下：

	使用HDFS提供的客户端开发库，向远程的Namenode发起RPC请求；
	Namenode会视情况返回文件的部分或者全部block列表，对于每个block，Namenode都会返回有该block拷贝的datanode地址；
	客户端开发库会选取离客户端最接近的datanode来读取block；
	读取完当前block的数据后，关闭与当前的datanode连接，并为读取下一个block寻找最佳的datanode；
	当读完列表的block后，且文件读取还没有结束，客户端开发库会继续向Namenode获取下一批的block列表。
	读取完一个block都会进行checksum验证，如果读取datanode时出现错误，客户端会通知Namenode，然后再从下一个拥有该block拷贝的datanode继续读。



写入文件


写入文件的过程比读取较为复杂：

	使用HDFS提供的客户端开发库，向远程的Namenode发起RPC请求；
	Namenode会检查要创建的文件是否已经存在，创建者是否有权限进行操作，成功则会为文件创建一个记录，否则会让客户端抛出异常；
	当客户端开始写入文件的时候，开发库会将文件切分成多个packets，并在内部以"data queue"的形式管理这些packets，并向Namenode申请新的blocks，获取用来存储replicas的合适的datanodes列表，列表的大小根据在Namenode中对replication的设置而定。
	开始以pipeline（管道）的形式将packet写入所有的replicas中。开发库把packet以流的方式写入第一个datanode，该datanode把该packet存储之后，再将其传递给在此pipeline中的下一个datanode，直到最后一个datanode，这种写数据的方式呈流水线的形式。
	最后一个datanode成功存储之后会返回一个ack packet，在pipeline里传递至客户端，在客户端的开发库内部维护着"ack queue"，成功收到datanode返回的ack packet后会从"ack queue"移除相应的packet。
	如果传输过程中，有某个datanode出现了故障，那么当前的pipeline会被关闭，出现故障的datanode会从当前的pipeline中移除，剩余的block会继续剩下的datanode中继续以pipeline的形式传输，同时Namenode会分配一个新的datanode，保持replicas设定的数量。
 </description>
		<link>http://blog.endlesscode.com/2010/06/16/hdfs-short-intro/</link>
			</item>
	<item>
		<title>简单的Streaming和Pipes示例</title>
		<description>一、Hadoop Streaming
Streaming是Hadoop提供的一个可以使用其他编程语言来进行MapReduce来的API，因为Hadoop是基于Java（由于作者比较擅长Java，Lucene和Nutch都是出于Hadoop的作者）。Hadoop Streaming并不复杂，其只是使用了Unix的标准输入输出作为Hadoop和其他编程语言的开发接口，因此在其他的编程语言所写的程序中，只需要将标准输入作为程序的输入，将标准输出作为程序的输出就可以了。

在标准的输入输出中，key和value是以tab作为分隔符，并且在reduce的标准输入中，hadoop框架保证了输入的数据是经过了按key排序的。

下面的示例是用Python重写了上一个示例：
# max_temperature_map.py
#!/usr/bin/env python
import sys
for line in sys.stdin:
 val = line.strip().split()
 # 分隔年份和温度值，输出到标准输出
 print "%s\t%s"%(val[0], val[1])

# max_temperature_reduce.py
#!/usr/bin/env python
import sys
(last_key, max_val) = (None, 0)
for line in sys.stdin:
 (key, temp) = line.strip().split('\t')
 if last_key and last_key != key:
 print "%s\t%s" % (last_key, max_val)
 (last_key, max_val) = (key, int(temp))
 else:
 (last_key, max_val) ...</description>
		<link>http://blog.endlesscode.com/2010/06/16/simple-demo-of-streaming-and-pipes/</link>
			</item>
	<item>
		<title>简单的MapReduce示例(Java)</title>
		<description>Hadoop的三种模式以及相应的安装细节Google上一大把，其实都基本上是一些参数的设置。

下面自己在.bashrc文件中的设置：
# setting in .bashrc
export HADOOP_INSTALL=/home/stephenchan/hadoop-0.20.2
export CLASSPATH=.:$HADOOP_INSTALL/hadoop-0.20.2-core.jar:$HADOOP_INSTALL/lib:$CLASSPATH
export PATH=$PATH:$HADOOP_INSTALL/bin
样例的代码是来自＜Hadoop : The Definitive Guide&#62;一书，由于没有拿到天气的数据，所以自己用代码生成了一个类似的样例数据，只有年份和温度，用MapReduce来取每年的最高温度，但我省去了日期中的天，保留了年。代码在standalone模式下运行即可，官方的参考文档 ： http://hadoop.apache.org/common/docs/r0.20.2/cn/。目前Hadoop只在Linux下完全支持商用运行，在Unix和Windows只支持用来开发。

生成示例数据的Python代码（生成后再手动给三个年份设置最大的temp值（如999）来观察结果的正常与否）：
#!/usr/bin/env python

import string
import random
import hashlib
random_chars = string.digits
year_list = [1990, 2000, 2010]
for idx in range(1, 1000):
 year = year_list[idx%3]
 temp  = random.sample(random_chars, 3)
 s = "%s %s" % (year, "".join(temp))
 print s
MaxTemperature.java的源代码：
/* MaxTemperature.java */
import java.io.IOException;

import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.*;
import org.apache.hadoop.mapreduce.*;
import ...</description>
		<link>http://blog.endlesscode.com/2010/06/16/simple-demo-of-mapreduce-in-java/</link>
			</item>
	<item>
		<title>动态链接</title>
		<description>动态链接的基本思想是把程序按照模块拆分成各个相对独立的部分，在程序运行时才将它们链接在一起形成一个完整的程序，而不是像静态链接那样把所有的程序模块都链接成一个单独的可执行文件。动态链接涉及运行时的链接及多个文件的装载，必需要有操作系统的支持，因为动态链接的情况下，进程的虚拟地址空间的分布会比静态链接情况下更为复杂，还有一些存储管理、内存共享、进程线程等机制在动态链接下也会有一些微妙的变化。在Linux系统中，ELF动态链接文件被称为“动态共享对象（DSO，Dynamic Shared Objects），简称共享对象，它们一般都是以“.so”为扩展名的一些文件，而在Windows系统中，动态链接文件被称为动态链接库（Dynamical Linking Library），即平时见到的以“.dll”为扩展名的文件。
动态链接库的特点与优势
把函数库推迟到程序运行时加载的好处有几个：

	可以实现进程之间的资源共享。就是说，某个程序的在运行中要调用某个动态链接库函数的时候，操作系统首先会查看所有正在运行的程序，看在内存里是否已有此库函数的拷贝。如果有，则让其共享那一拷贝（共享代码段，数据码各自独立一份）；只有没有才链接载入。这种模式虽然会带来一些”动态链接“额外的开销，但却大大地节省了系统的内存资源，通过一定的优化，与静态链接相比，性能损失大约在5％以下。
	程序升级变得简单。用户只需要升级动态链接库，而无需像静态链接那样重新编译其他原有的代码就可以完成整个程序的升级。
	可以使链接载入由程序员在程序代码中控制，如dlopen、dlsym、dlclose等等。

装载重定位
静态链接是通过在链接过程对所有目标文件进行重定位的。而对于动态链接库而言，在链接时，可执行文件对所有绝对地址的引用不作重定位，而把这一步推迟到装载时再完成。一旦模块装载地址确定，即目标地址确定，那么系统对程序中所有的绝对地址引用进行重定位。负责完成这部分工作的是动态链接器（Dynamic Loader，其实也是一个共享对象，ld.so）。

动态链接模块被装载遇到至虚拟空间之后，指令部分是在多个进程之间共享的，由于装载时重定位的方法需要修改指令，所以没有办法做到同一份指令被多个进程共享，因为指令被重定位后对于每个进程来讲是不同的。当然，动态链接库中的可修改数据部分对于不同的进程来说有多个副本，所以它们可以采用装载时重定位的方法来解决。

因此，地址无关代码（PIC，Position-independent Code）就在这种需求的前提产生了。这种方案就是把指令中那些需要被修改的部分分离出来，跟数据部分放在一起，这样指令部分就可以保持不变，而数据部分可以在每个进程中拥有一个副本。

可以按是否跨模块和引用方式分为4类地址引用类型：
/* a.elf */
static int a;
extern int b;
extern void ext();

void bar()
{
    a = 1;  //类型2 模块内数据访问
    b = 2;  //类型3 模块间数据访问
}

void foo()
{
    bar();  //类型1 模块内调用或跳转
    ext();  //类型4 模块间调用或跳转
}
类型一 模块内部调用或跳转

对于现代的操作系统来讲，模块内部的跳转、函数调用都可以是相对地址调用，或者是基于寄存器相对调用，所以对于这种指令是不需要重定位的，这点从静态链接时的模块内部重定位可以看出。

类型二 ...</description>
		<link>http://blog.endlesscode.com/2010/06/07/dynamic-linkage/</link>
			</item>
</channel>
</rss>
