<?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>Tin&#039;s Blog &#187; Tech.技术</title>
	<atom:link href="http://www.diamondtin.com/category/tech-posts/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.diamondtin.com</link>
	<description>you are coming a long way...</description>
	<lastBuildDate>Thu, 05 Jan 2012 00:19:04 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.3</generator>
		<item>
		<title>That&#8217;s not the problem of B player</title>
		<link>http://www.diamondtin.com/2011/thats-not-the-problem-of-b-player/</link>
		<comments>http://www.diamondtin.com/2011/thats-not-the-problem-of-b-player/#comments</comments>
		<pubDate>Sat, 08 Oct 2011 13:23:20 +0000</pubDate>
		<dc:creator>tin</dc:creator>
				<category><![CDATA[Tech.技术]]></category>
		<category><![CDATA[ognizational-transformation]]></category>
		<category><![CDATA[team]]></category>

		<guid isPermaLink="false">http://www.diamondtin.com/2011/thats-not-the-problem-of-b-player/</guid>
		<description><![CDATA[我的朋友米糕陈写了一篇「Don&#8217;t hire B player」的文章分析他们团队面临的问题，这篇短文是对他的回复。 其实A player被B player拖累只是一个结果。杠杆模型是最大的问题，你希望提高杠杆的... ]]></description>
			<content:encoded><![CDATA[<p>我的朋友米糕陈写了一篇「<a href="http://michael.nona.name/archives/388">Don&#8217;t hire B player</a>」的文章分析他们团队面临的问题，这篇短文是对他的回复。<br />
其实A player被B player拖累只是一个结果。杠杆模型是最大的问题，你希望提高杠杆的比例，用少量的A player撬动BCDEF player，这样总体上活跃的A player被稀释了，团队文化是人创造的，人的稀释会改变文化，团队文化就退化了。而杠杆模型的本意是scale business，但忽略了团队文化和商业模式的对应。公司扩大并进入了总体利润丰厚的外包行业，团队自然就会相应的变化，留住人的方法自然会从团队文化转移到这种业务模式对应的薪酬模型，团队组成也会从偏向精神收获到偏向物质收获的个体。<br />
然后商业转型完成了，人的结构也变了。那个牌子没变，但是牌子所代表的价值改变了。过程有阵痛，不可避免，但这过程是代表shareholder的意思的，你只能用脚投票了。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.diamondtin.com/2011/thats-not-the-problem-of-b-player/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to upgrade EeePad TF101</title>
		<link>http://www.diamondtin.com/2011/how-to-upgrade-eeepad-tf101/</link>
		<comments>http://www.diamondtin.com/2011/how-to-upgrade-eeepad-tf101/#comments</comments>
		<pubDate>Sat, 03 Sep 2011 12:32:02 +0000</pubDate>
		<dc:creator>tin</dc:creator>
				<category><![CDATA[Tech.技术]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[eeepad]]></category>
		<category><![CDATA[honeycomb]]></category>
		<category><![CDATA[howto]]></category>
		<category><![CDATA[upgrade]]></category>

		<guid isPermaLink="false">http://www.diamondtin.com/?p=1035</guid>
		<description><![CDATA[The firmware download site is here: ftp://ftp.asus.com.tw/pub/ASUS/EeePAD/TF101/ Our TF101 is using honeycomb 3.01, and the build date is about 2001.4.18. So we plan to update it to ftp://ftp.asus.com.tw/pub/ASUS/EeePAD/TF101/UpdateLauncher_CN_epaduser86... ]]></description>
			<content:encoded><![CDATA[<p>The firmware download site is here: <a href="ftp://ftp.asus.com.tw/pub/ASUS/EeePAD/TF101/">ftp://ftp.asus.com.tw/pub/ASUS/EeePAD/TF101/</a></p>
<p>Our TF101 is using honeycomb 3.01, and the build date is about 2001.4.18.</p>
<p>So we plan to update it to <a href="ftp://ftp.asus.com.tw/pub/ASUS/EeePAD/TF101/UpdateLauncher_CN_epaduser8659.zip">ftp://ftp.asus.com.tw/pub/ASUS/EeePAD/TF101/UpdateLauncher_CN_epaduser8659.zip</a> This is honeycomb 3.2, and build date is 2011.8.26.</p>
<p>I didn&#8217;t find how to upgrade it without using OTA. So this is how to I found:</p>
<ol>
<li>Extract UpdateLauncher_CN_epaduser8659.zip, Under ASUS/Update there is CN_epad-user-8.6.5.9.zip.</li>
<li>Copy CN_epad-user-8.6.5.9.zip into the root folder of TF card. And rename it to EP101_SDUPDATE.zip.</li>
<li>Power down your TF101</li>
<li>hold the volume down and power buttons together till you see there is some small text appears on upper left of screen. Then push the volume up, you need to do this in 5 seconds, otherwise it will continue boot up. Then you should see some progress bars showing it&#8217;s upgrading, don&#8217;t turn it off before it&#8217;s finished.</li>
</ol>
<p>Yes, that&#8217;s it. So the magical step is rename the update firmware package to <strong>EP101_SDUPDATE.zip</strong>, so it will flash the update to main rom.</p>
<p><img src="http://images.instagram.com/media/2011/09/02/1e10e06a163049f788e0c38638f9a642_7.jpg" alt="upgrading the TF101" /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.diamondtin.com/2011/how-to-upgrade-eeepad-tf101/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>为什么极力支持测试驱动开发TDD</title>
		<link>http://www.diamondtin.com/2011/why-i-support-tdd/</link>
		<comments>http://www.diamondtin.com/2011/why-i-support-tdd/#comments</comments>
		<pubDate>Thu, 30 Jun 2011 10:11:31 +0000</pubDate>
		<dc:creator>tin</dc:creator>
				<category><![CDATA[Tech.技术]]></category>
		<category><![CDATA[Agile]]></category>
		<category><![CDATA[Consulting]]></category>
		<category><![CDATA[Inception]]></category>
		<category><![CDATA[Positive-thinking]]></category>
		<category><![CDATA[TDD]]></category>
		<category><![CDATA[XP]]></category>

		<guid isPermaLink="false">http://www.diamondtin.com/?p=1024</guid>
		<description><![CDATA[国内的一个很流行的博客上面讨论了TDD的一些问题，并且顺带批评了某咨询公司的咨询师不够脚踏实地。我在那个博客留言表达过我的不同意见，前几天随着另外一篇对TDD质疑的文章发表我和... ]]></description>
			<content:encoded><![CDATA[<p>国内的一个很流行的博客上面讨论了TDD的一些问题，并且顺带批评了某咨询公司的咨询师不够脚踏实地。我在那个博客留言表达过我的不同意见，前几天随着另外一篇对TDD质疑的文章发表我和文章的作者在Twitter上论战了一番，不过论战是不能解决问题的（之前InfoQ上的虚拟讨论也没有解决问题），所以我再简单的整理一下我的意见。</p>
<p>首先，我声明我是一个笃信极限编程对『编程』有巨大价值的人。而TDD是极限编程XP里面的实践之一，在讨论XP的过程中我们一般都倾向于使用『实践（practice）』这个词，而不是『方法论（methodology）』，原因是极限编程描述的这些『方法』实际上是很多做事的具体方式，而不是一种『理论』。</p>
<p>我不应该咬文嚼字，不过有些时候这很重要。我需要从极限编程这个名字开始讨论这个问题。以前的一次OpenParty上，o6z问我『你知道极限编程为什么叫极限编程么？』，我当时真的不知道答案，只是隐约觉得极限编程的很多个体实践都是一种极限的挑战。而后o6z说『其实极限编程就是指程序员公认一些最佳实践，他们致力于不断的改进、优化这些最佳实践，最后把他们推向极致，这就叫极限编程』。这个答案可能是官方的，也可能是坊间流传的，不过我觉得它特别贴切，解释了极限编程的价值观。我当前公司的CEO上次调侃过『价值观』这个词，他说价值观说出来就不灵了，就成狗屁了……他说真正的价值观体现在你做每个决策的时候左右你的那种抽象的直觉。极限编程的每个写下来的『实践』其实就是写下来的价值观的体现，在实践的过程中最重要的就是不断的去磨练你的直觉，让价值观内在化。OK，极限编程我说道这里。</p>
<p>TDD，测试驱动开发。我们按照刚才阐述极限编程的涵义推演一下TDD是怎么来的。我们在写程序的时候发现不对程序进行细粒度的验证就很容易产生Bug，逐渐的整个编程社区有了一个最佳实践『单元测试』，我们也知道『单元测试』是相对于『集成测试』和『系统测试』的，我们提高程序内在质量的时候这些测试工具我们都要使用，只是有时其它测试会通过那种被叫做QA的程序员编写。为了不扯到另外一个话题，我们继续，当大家公认测试是最佳实践的时候，极限编程社区把测试推向极致。极致的测试应该具有细的粒度，高的覆盖率，有意义的验证条件，全面的边界条件，不脆弱等等，这些指标单个都不产生价值，但是在某个平衡的状态它具有最高的价值。极限的TDD的目的就是找到那个平衡。</p>
<p>我们退一步说，其实目前我们的程序员社区绝大部分人面临的都不是是否可以做好TDD，找到那个最佳的平衡点的问题。现在的主要问题还是是否可以写出有意义的测试，如何写测试的问题。其实质疑TDD的朋友经常的理由是『只要写好单元测试就可以了』，这其实正是我现在说的我们大多数程序员的困惑。也就是说『使用TDD』的对面是『能够写好单元测试但是不做TDD』，我认为这是一个伪命题。因为TDD的目的就是把测试这种最佳实践推向极限，这是一个过程，我可以把它分成两个阶段：</p>
<ul>
<li>第一个阶段是通过TDD强制从不写测试向写测试转变，因为绑定了写测试和写代码的节奏，它可以保证你写出的代码是可以测试的；</li>
<li>第二阶段是通过不断实践和优化TDD让你能够写好测试。因为测试不只是有单元测试，还有系统测试和集成测试，随着对TDD的熟悉你会发现可以用不同层级的测试来驱动你的设计。使用越高层级的测试越有难度，这也是极限的一种体现。现在比较普遍的BDD其实就是将领域模型驱动DDD这种建模的方式与TDD结合的产物， Spec的描述形式让它不仅可以组织好单元测试，也可以组织好系统测试（如验收测试驱动设计，ATDD）。第二个阶段可以一直优化，永远没有极限，这个过程是最有价值的；</li>
</ul>
<p>这种阶段化的实践其实内置了一些积极的意图：</p>
<ul>
<li>先写测试后写实现其实是把同时写测试和实现更近一步的产物。同时写测试的一种形容就是『可测试性驱动程序开发』，前几年老赵就写过这方面的博文，并且从可测试性上论证了TDD的积极意义。因为只有同时写测试和实现才能最好的保证你的代码是可测试的。而解决可测试性的难题的关键点是有可以检查验证条件（而不是足够细的粒度，细粒度既不是充分条件也不是必要条件，只是细粒度容易找到验证条件而已），也就是测试结果需要可验证。如果没有已知的可检查验证条件，那么可测试性就无法保证。所以先构思一个测试验证点再写代码是这个逻辑的体现。</li>
<li>测试准备耗时费事，但是如果我们偷懒不做，那么后期可能面临的是完全无法做。保证测试容易准备需要在设计上多加考虑，如慎用Singleton等。这些思考可以影响你的设计，帮助你着力思考系统中的哪些状态是可变的，哪些是不变的，帮助你强化设计出无副作用或者少副作用的代码（因为有副作用的代码更难准备测试环境，环境的组合会多变），这帮助你函数化思考。</li>
<li>红绿的节奏和小步前进可以帮助你减少对调试的依赖。调试和测试都是我们验证Bug的工具，不过我们最好在难以复现的场景使用调试这种终极武器，在编码阶段反复的进入调试说明你的测试有问题。编码阶段调试的常见原因就是测试没有跟上，因为我们知道最最常见的代码错误就是拼写错误。测试和调试找到拼写错误的代价是完全不同的。小步前进配合现代版本控制工具可以让我们完美的通过折半查找找到出问题的代码所在，如果有自动化测试套件的话折半查找还会事半功倍。这一条是说TDD的节奏所鼓励的小步前进的好处。</li>
<li>测试驱动的测试需要有一个明确的名字。在寻找名字的过程你会重新思考这条验证的目的，让你整理需求的思路，也就是提醒你经常的问『为什么？』。细粒度的问为什么，并且为这些需求设计测试场景，这对每个想要贯彻『具体问题具体分析』的程序员非常重要。</li>
</ul>
<p>这样的王婆卖瓜的理由我还有很多，多说无益。其实这里有一个关键的问题需要澄清，我们说TDD有这么多积极的意义，但是我们不能说『所有的代码都要TDD』，因为它很容易让TDD成为不现实的『生产力毒药』。当初比我经验丰富的一位同事就和我说『Spike（技术验证）的时候不需要TDD』，我发现在需要自由翱翔的时候放弃TDD的确是很舒服的事情，不过每当我们看这些Spike产生的代码时我们会发现TDD的重要性。因为这些 Spike出来的代码经常惨不忍睹。另外一位资深的同事就又和我说『Spike完成后，你应该删掉那些代码。然后重新TDD去实现它们，因为严格测试、精心设计过的代码才是为生产环境准备的』。我举的这个例子不能绝对化，不过我想表达的是，如果你想知道不做TDD的后果，那么一定要先做好TDD，回去对比观察没有TDD代码的不是。大部分关于TDD的批评大都来自那些还没有完全掌握TDD的人，工作流还没有很好的优化，此时对比『写单元测试』的自己就开始觉得TDD让自己混身不适了，『把最佳实践推向极限这个行为』要在完全掌握『最佳实践』的前提下才可以继续修炼。</p>
<p>我这里放一个比喻，我不知道是否贴切：有一种修行是爬看不到顶峰的山，视力可及的半山腰上有一片开满鲜花的平台。有些人爬到平台就下结论『爬到山顶也不过如此，也许还没有这么多鲜花呢』。但是另外一些人则继续攀登，以致山下都看不到他们的身影了。半山腰的人也许会开始质疑那些继续攀登的人的动机，说这完全是一种宗教。对于继续攀登的人来说，的确是一种信仰让他们坚持下去，那就是极限编程。关键的问题在于，对于那些山脚下的『沉默的大多数』人而言他们应该听谁的呢？是应该相信半山腰的人说『那些持续攀登的人走火入魔了，其实半山腰这里就最好了』？还是跟随那些持续攀登的人所走过的路走下去？其实，持续攀登的人会告诉所有山下的人你随时可以转身回到那个平台去，所以我们的行为是安全的，不过如果你持续攀登，那山上一定有一个更好的世界。有些人听了前者的话停留在山下徘徊，因为他们绝得那半山腰也不过如此，山下的日子很好过。但是有些人听了后者的话爬上了半山腰，还有一些也成为了后者。</p>
<p>这种比喻可以写的很华丽，不过这不是什么论据，它只是一种修辞而已。《思考的技术》这本书的第二章叫「逻辑打动人心」，我摘一些句子：</p>
<blockquote><p>“但是”、“然而”这种话，对于改善经营而言，有白害而无一利</p></blockquote>
<p>这是借口中常用的词，它会给出一个反面的评价，而后是中庸的『具体问题具体分析』。极限编程不是这样，它是单向的夸张，把最佳实践推向极限。所谓『写好单元测试就好了，要具体问题具体分析』其实是不写测试的一个好借口。如果你想让自己积极的去实践，请给自己一个极限的理由，当然，你随时都可以转身回到那个平台的。</p>
<blockquote><p>如果给客户的药方，只是没有什么感觉的营养剂，客户的经营状况将无法改善</p></blockquote>
<p>这是我想说明极限编程的极限的意义。这些推向极限的过程不是邪教，让你以为最后可以看到神迹而葬身途中，它的目的是给你一剂猛药，让你更好的走到那个平台，甚至到下一个层次上去（第一个平台的人兴许都不知道后面还有其它平台吧？）。</p>
<p>其实说到这里咨询公司的秘密也揭开了。咨询公司的医生不是包治百病的，他们的大部分都是希望给你一个最佳的『盗梦空间中的术语，植入想法，Inception』，期望这个植入可以帮助你向积极的方向前进，不过你的行为依然是你自己控制的。好的咨询公司不会利用这个机会『洗脑』，因为他们自己也在不断追求极致的过程中。这更像把酿造啤酒的技术推向极致的修士们（Trappist，非常著名的修道院啤酒的修士们通过几代人不断的优化酿造他们认为完美的啤酒，具有稳定而微妙的口味）所做的修行，他们自己在不断优化自己所做的事情，并通过咨询把这些Inception植入客户的思想。这里还要澄清一个问题，不是修道院中的所有修士都有崇高理想，有些新进来的修士不会酿酒，有些隐藏在修士中的南郭先生可能没有追求极致的精神，这非常正常，我们都是不完美的，我们的组织也不会完美，不过我们依然可以有追求完美的组织。</p>
<p>写到这里，我重复一下我在OpenParty的朋友中经常说的一句话『要把积极的影响施加给身边的朋友们』，我不像Cleverpig信仰巴哈依教，不过我坚持积极做人，积极影响人。极限编程和其中的TDD都出于同样的动机，施加给所有的程序员积极的愿望，不断的优化自己的工作流，以期达到最终的『极致』。谢谢观赏。</p>
<p><strong>内文的一些链接我会稍后添加</strong></p>
<p><em>后记</em>：最近工作家里都忙，有了一个小公主需要伺候，所以没有太多时间更新Blog。我写博客不是让人围观的，而是写给自己和我所爱的家人朋友。我在Twitter上口水战还有写这篇博文主要是『质疑TDD和某咨询公司』与我的价值观冲突，所以我才不得不写这篇博文表达我的观点。我和我的朋友们还在努力组织好OpenParty的Unconference活动，我们的理想主义可以在这个活动上得到满足，我们给大家一个自由的分享与获取知识的机会，并且更重要的是我们要把积极的态度植入到参与活动的朋友的意识中，我想这是让我们生活更美好的最佳途径。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.diamondtin.com/2011/why-i-support-tdd/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>在VPS上装东西优先参考它们的wiki</title>
		<link>http://www.diamondtin.com/2010/best_how_to_is_on_vps_wiki/</link>
		<comments>http://www.diamondtin.com/2010/best_how_to_is_on_vps_wiki/#comments</comments>
		<pubDate>Thu, 18 Nov 2010 01:20:58 +0000</pubDate>
		<dc:creator>tin</dc:creator>
				<category><![CDATA[Tech.技术]]></category>
		<category><![CDATA[howto]]></category>
		<category><![CDATA[vpn]]></category>
		<category><![CDATA[vps]]></category>

		<guid isPermaLink="false">http://www.diamondtin.com/?p=980</guid>
		<description><![CDATA[有个朋友问我装OpenVPN哪个教程好，可那是很久以前搭的所以我不记得是用的哪篇教程了。还好，在Ubuntu的linode上面搭OpenVPN基本上没什么障碍。据我的经验，在VPS上面装任何软件最好的方式就是... ]]></description>
			<content:encoded><![CDATA[<p>有个朋友问我装OpenVPN哪个教程好，可那是很久以前搭的所以我不记得是用的哪篇教程了。还好，在Ubuntu的linode上面搭OpenVPN基本上没什么障碍。据我的经验，在VPS上面装任何软件最好的方式就是看注明VPS的wiki：</p>
<ul>
<li><a href="http://library.linode.com/" title="Linode Library">Linode Library</a></li>
<li><a href="http://wiki.slicehost.com/" title="Slicehost wiki">Slicehost wiki</a></li>
</ul>
<p>这两个都很不错，可以优先看看这里是否有需要的教程。</p>
<p>VPN还有其它选择，如PPTP和L2TP，它们在桌面和移动平台基本上都可以用，不像OpenVPN由于授权问题在一些封闭的移动系统里面不可以用。不过最好……你的VPS三种VPN都部署上，以备不时之需。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.diamondtin.com/2010/best_how_to_is_on_vps_wiki/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Leopard下如何让你的sudo不需要输密码</title>
		<link>http://www.diamondtin.com/2010/disable_password_for_sudo_in_leopard/</link>
		<comments>http://www.diamondtin.com/2010/disable_password_for_sudo_in_leopard/#comments</comments>
		<pubDate>Wed, 21 Jul 2010 08:21:52 +0000</pubDate>
		<dc:creator>tin</dc:creator>
				<category><![CDATA[Tech.技术]]></category>
		<category><![CDATA[leopard]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[terminal]]></category>

		<guid isPermaLink="false">http://www.diamondtin.com/?p=964</guid>
		<description><![CDATA[在Snow Leopard的Terminal里面用sudo的时候总是需要输入密码，而在单位的FreeBSD服务器上则不需要。我觉得从安全角度来说这个密码用处不大，有了反而会浪费时间。 搜索了一下，发现要这样做： ... ]]></description>
			<content:encoded><![CDATA[<p>在Snow Leopard的Terminal里面用sudo的时候总是需要输入密码，而在单位的FreeBSD服务器上则不需要。我觉得从安全角度来说这个密码用处不大，有了反而会浪费时间。</p>
<p>搜索了一下，<a href="http://mattdanger.net/2009/01/sudo-without-a-password-in-mac-os-x/">发现要这样做</a>：</p>
<p>修改/etc/sudoers文件（记得sudo vi它，存的时候要w!），去掉这一行前面的#号：</p>
<p><code>%wheel	ALL=(ALL)	NOPASSWD: ALL</code></p>
<p>然后执行下面命令，记得将your_username替换为你的用户名：</p>
<p><code>sudo dscl . append /Groups/wheel GroupMembership your_username</code></p>
<p>从此就不需要在sudo的时候输入密码了。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.diamondtin.com/2010/disable_password_for_sudo_in_leopard/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Cassandra的一致性级别</title>
		<link>http://www.diamondtin.com/2010/cassandra_consistent_level/</link>
		<comments>http://www.diamondtin.com/2010/cassandra_consistent_level/#comments</comments>
		<pubDate>Wed, 14 Jul 2010 05:53:44 +0000</pubDate>
		<dc:creator>tin</dc:creator>
				<category><![CDATA[Tech.技术]]></category>
		<category><![CDATA[cassandra]]></category>
		<category><![CDATA[consistency]]></category>

		<guid isPermaLink="false">http://www.diamondtin.com/?p=961</guid>
		<description><![CDATA[翻译Cassandra文档中的一段。 写一致性级别Write ZERO 不保证一致。写操作在后台异步执行。除非CASSANDRA-685 修正，否则当太多写错作排队的时候，buffer会膨胀，后果很坏。 ANY （需要0.6的Cassandra）... ]]></description>
			<content:encoded><![CDATA[<p>翻译<a href="http://wiki.apache.org/cassandra/API#ConsistencyLevel">Cassandra文档中的一段。</a></p>
<h3>写一致性级别Write</h3>
<dl>
<dt>ZERO</dt>
<dd>不保证一致。写操作在后台异步执行。除非CASSANDRA-685 修正，否则当太多写错作排队的时候，buffer会膨胀，后果很坏。</dd>
</dl>
<dl>
<dt>ANY</dt>
<dd>（需要0.6的Cassandra）保证至少写入到1个节点中，包括示意（hinted）的接收者。</dd>
</dl>
<dl>
<dt>ONE</dt>
<dd>保证写操作在回复客户端前至少已经进入1个节点的commit log和memory table。</dd>
</dl>
<dl>
<dt>QUORUM</dt>
<dd>保证写操作在回复客户端前至少被写入到 （&lt;复制因数&gt; / 2 + 1）个节点中。</dd>
</dl>
<dl>
<dt>ALL</dt>
<dd>保证写操作在回复客户端前已经被写入到 &lt;复制因数&gt; 个节点中。任何节点如果没有响应，则操作失败。</dd>
</dl>
<h3>读一致性级别别Read</h3>
<dl>
<dt>ZERO</dt>
<dd>不支持，因为没有意义。</dd>
</dl>
<dl>
<dt>ANY</dt>
<dd>不支持，应该使用ONE来代替。</dd>
</dl>
<dl>
<dt>ONE</dt>
<dd>将会返回第一个有响应结果的节点返回的数据。在使用ConsistencyLevel.ONE的时候，一致性检查永远是在后台线程中来修复一致性问题。这意味着如果开始的读取得到了旧数据时后续的调用可以返回正确的数据（这叫做读取修复 read repair）</dd>
</dl>
<dl>
<dt>QUORUM</dt>
<dd>查询所有的节点，一但绝大多数复制节点返回了结果，返回具有最新的时间戳的纪录。其余复制节点的结果会在后台进行检查。</dd>
</dl>
<dl>
<dt>ALL</dt>
<dd>查询所有的节点，一但所有复制节点返回了结果，返回具有最新的时间戳的纪录。任何节点如果没有响应，则操作失败。</dd>
</dl>
]]></content:encoded>
			<wfw:commentRss>http://www.diamondtin.com/2010/cassandra_consistent_level/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>python里面检测内存容量</title>
		<link>http://www.diamondtin.com/2010/python_memory_usage_profile/</link>
		<comments>http://www.diamondtin.com/2010/python_memory_usage_profile/#comments</comments>
		<pubDate>Thu, 15 Apr 2010 03:16:28 +0000</pubDate>
		<dc:creator>tin</dc:creator>
				<category><![CDATA[Tech.技术]]></category>

		<guid isPermaLink="false">http://www.diamondtin.com/?p=917</guid>
		<description><![CDATA[今天要做一个python里面内存效率的测试，所以需要查看当前运行的python unittest的内存占用情况，查了一下发现psutil可以帮助你做这个事情，这样的代码就可以工作，需要安装psutil，我用的sudo pip... ]]></description>
			<content:encoded><![CDATA[<p>今天要做一个python里面内存效率的测试，所以需要查看当前运行的python unittest的内存占用情况，查了一下发现psutil可以帮助你做这个事情，这样的代码就可以工作，需要安装psutil，我用的sudo pip install psutil：</p>
<pre class="code">
class MemoryInfo(object):
    def __init__(self):
        self.current_process_id = os.getpid()
        self.current_process = Process(self.current_process_id)

    def usage(self):
        return self.current_process.get_memory_info()

    def print_usage(self):
        usage = self.usage()
        print '物理内存: %sKB, 虚拟内存: %sKB' % (usage[0]/1024, usage[1]/1024)
</pre>
<p>用的时候你可以实例化一个MemoryInfo()然后分多次调用它的print_usage方法。结绳记事。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.diamondtin.com/2010/python_memory_usage_profile/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Web as a platform</title>
		<link>http://www.diamondtin.com/2010/web-as-a-platform/</link>
		<comments>http://www.diamondtin.com/2010/web-as-a-platform/#comments</comments>
		<pubDate>Fri, 09 Apr 2010 22:48:49 +0000</pubDate>
		<dc:creator>tin</dc:creator>
				<category><![CDATA[Tech.技术]]></category>
		<category><![CDATA[web rest atom]]></category>

		<guid isPermaLink="false">http://www.diamondtin.com/2010/web-as-a-platform/</guid>
		<description><![CDATA[Matin fowler 大师在这篇文章 《Richardson Maturity Model: steps toward the glory of REST》，用一种伪成熟度模型的方式为我们揭示简单的Rest如何让Web成为未来软件开发的一个通用平台。其实我以前就职的Thoug... ]]></description>
			<content:encoded><![CDATA[<p>Matin fowler 大师在这篇文章 <a href="http://martinfowler.com/articles/richardsonMaturityModel.html">《Richardson Maturity Model: steps toward the glory of REST》</a>，用一种伪成熟度模型的方式为我们揭示简单的Rest如何让Web成为未来软件开发的一个通用平台。其实我以前就职的ThoughtWorks里面的同事早就在研究Web as platform这个Buzz，因为这是一种通过成熟的标准让我们日常的开发更简单更容易被Mashup的好方法。其核心思想就是利用Rest和Atom让应用程序API变成Plain web应用，这样所有现有的Web应用api就很容易被你的应用Mash up进来，这样我们的世界就真的成为了一个网。所以，坚持Rest best practice，争取早点让你的系统建在Web平台上。</p>
<p>Atom在让Rest api连接起来，让你的应用变为以资源为中心很重要：</p>
<ul>
<li><a href="http://atompub.org/rfc4287.html">RFC 4287: The Atom Syndication Format</a></li>
<li><a href="http://www.iana.org/assignments/link-relations/link-relations.xhtml">Atom Link Relations</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.diamondtin.com/2010/web-as-a-platform/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Python中的method_missing和*get*钩子方法族</title>
		<link>http://www.diamondtin.com/2009/method_missing_and_get_methods_in_python_object/</link>
		<comments>http://www.diamondtin.com/2009/method_missing_and_get_methods_in_python_object/#comments</comments>
		<pubDate>Fri, 11 Dec 2009 14:50:05 +0000</pubDate>
		<dc:creator>tin</dc:creator>
				<category><![CDATA[Tech.技术]]></category>
		<category><![CDATA[language]]></category>
		<category><![CDATA[meta programming]]></category>
		<category><![CDATA[method_missing]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://tin.zztin.com/2009/%e5%88%9a%e6%89%8d%e5%ae%9e%e9%aa%8c%e4%ba%86%e4%b8%80%e4%b8%8b%ef%bc%8c%e5%8f%91%e7%8e%b0python%e9%87%8c%e9%9d%a2%e5%a3%b0%e6%98%8e%e7%b1%bb%e7%9a%84%e6%97%b6%e5%80%99%e6%98%af%e5%90%a6%e9%80%89/</guid>
		<description><![CDATA[刚才实验了一下，发现Python里面声明类的时候是否选择继承objects还是有很大区别的。只有继承了objects，才可以使用钩子方法如&#8217;__get__&#8217;, &#8216;__set__&#8217;, &#8216;__getattr__&#8217;, &#8216;__getat... ]]></description>
			<content:encoded><![CDATA[<p>刚才实验了一下，发现Python里面声明类的时候是否选择继承objects还是有很大区别的。只有继承了objects，才可以使用钩子方法如&#8217;__get__&#8217;, &#8216;__set__&#8217;, &#8216;__getattr__&#8217;, &#8216;__getattribute__&#8217;这些方法。也就是说这些有用的钩子方法是所谓的new object里面的东西。今天我在项目的代码里面尝试了一下类似Ruby method_missing的写法，实验在Python里面加点元编程的东西。发现很相似的三个方法&#8217;__get__&#8217;, &#8216;__getattr__&#8217;, &#8216;__getattribute__&#8217;方法区别挺大。注意，一定要继承object才可以享用三个钩子方法。</p>
<ul>
<li>访问对象方法的时候首先会访问&#8217;__getattribute__&#8217;，它是访问类里面所有属性的时候都要经过的方法，包括创建对象的时候访问&#8217;__init__&#8217;, &#8216;_meta&#8217;这些都回经过&#8217;__getattribute__&#8217;访问。如果你什么异常都不抛出，它就不会访问&#8217;__getattr__&#8217;方法。
<li>
<li>如果&#8217;__getattribute__&#8217;方法抛出&#8217;AttributeError&#8217;，那么会继续尝试访问&#8217;__getattr__&#8217;方法。再有异常抛出，那么这个类就没有钩子再接住异常了。所以从这个角度来说它的工作方式非常相似于Ruby的method_missing。</li>
<li>我本以为&#8217;__getattr__&#8217;是系统内建函数hasattr(object, property)优先访问的方法。不过实验证明，实际上还是先走&#8217;__getattribute__&#8217;后走&#8217;__getattr__&#8217;的。也就是说hasattr这样的函数没有优先绑定&#8217;__getattr__&#8217;。</li>
<li>&#8216;__get__&#8217;方法是用来监视自己的类作为其它类的成员的时候被访问的钩子。对应的是&#8217;__set__&#8217;，是相应属性被赋值时的钩子。这个方法与&#8217;__getattr__&#8217;和&#8217;__getattribute__&#8217;完全不是一会儿事。刚才看《Python核心编程一书》完全没有解释清楚。<a href="http://users.rcn.com/python/download/Descriptor.htm">《How-To Guide for Descriptors》</a>这篇文章对解释&#8217;__get__&#8217;帮助很大，有兴趣可以看看，不过我倒是没有想到什么是合理的应用场合。</li>
</ul>
<p>我目前还没有调用方法的method_missing，目前只是访问一些属性。我们实际处理的是一个可以直接用属性名读取/修改对象里面的持久化json属性的方法，就是类持有一个{&#8216;property&#8217;: &#8216;value&#8217;}的json文本属性，我们就可以直接用Model.property访问和修改里面的方法，而不用特别的去生命json结构过来。是一个在Python中做meta programming的尝试。</p>
<p>测试刚才说的几个*get*方法的测试如下:</p>
<pre>
# -*- coding: utf8 -*-
import unittest

class A(object):
    def __init__(self):
        print 'init A'

    def __get__(self, *args):
        print '__get__ A', args

    def __set__(self, *args):
        print '__set__ A', args

class B(object):
    a = A()

    def __init__(self):
        print 'init B'

    def __getattr__(self, *args):
        print '__getattr__ B', args

    def __getattribute__(self, *args):
        print '__getattribute__ B', args
        raise AttributeError

    def __get__(self, *args):
        print '__get__ B', args

    def __set__(self, *args):
        print '__set__ B', args

class MeTest(unittest.TestCase):
    def test_simple(self):
        b = B()
        print b.a
        b.a = A()
        b.c
        hasattr(b, 'e')
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.diamondtin.com/2009/method_missing_and_get_methods_in_python_object/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>在Mac下使用脚本重载proxy自动配置脚本（pac）</title>
		<link>http://www.diamondtin.com/2009/reloading-pac-script-in-mac/</link>
		<comments>http://www.diamondtin.com/2009/reloading-pac-script-in-mac/#comments</comments>
		<pubDate>Thu, 05 Nov 2009 00:53:43 +0000</pubDate>
		<dc:creator>tin</dc:creator>
				<category><![CDATA[Tech.技术]]></category>
		<category><![CDATA[great firewall]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[pac]]></category>
		<category><![CDATA[proxy]]></category>
		<category><![CDATA[script]]></category>

		<guid isPermaLink="false">http://tin.zztin.com/?p=825</guid>
		<description><![CDATA[Mac下对网络设备使用proxy自动配置脚本可以透明使用代理穿墙（可以配合ssh tunnel和tor）。但是我一直不知道如何用脚本让系统重新载入pac文件（在更新了pac的规则时我们需要重载配置）。昨天... ]]></description>
			<content:encoded><![CDATA[<p>Mac下对网络设备使用proxy自动配置脚本可以透明使用代理穿墙（可以配合<a href="http://tin.zztin.com/2009/ssh-tunnel-and-pac">ssh tunnel</a>和tor）。但是我一直不知道如何用脚本让系统重新载入pac文件（在更新了pac的规则时我们需要重载配置）。昨天一位叫做Dylan的网友留言告诉了我如何做，我在此记录一下。在命令行下面：</p>
<p><code>networksetup listallnetworkservices</code></p>
<p>然后会会返回一个网络连接服务的列表：</p>
<p><code><br />
An asterisk (*) denotes that a network service is disabled.<br />
Bluetooth DUN<br />
ADSL<br />
Ethernet<br />
FireWire<br />
AirPort<br />
Bluetooth PAN<br />
</code></p>
<p>我一般需要配置pac文件的是Ethernet和AirPort，那么相应的重载命令是：</p>
<p><code><br />
sudo networksetup -setautoproxystate 'AirPort' off<br />
sudo networksetup -setautoproxyurl 'AirPort' 'file://localhost/Users/tin/pac/tin.pac'<br />
sudo networksetup -setautoproxystate 'AirPort' on<br />
sudo networksetup -setautoproxystate 'Ethernet' off<br />
sudo networksetup -setautoproxyurl 'Ethernet' 'file://localhost/Users/tin/pac/tin.pac'<br />
sudo networksetup -setautoproxystate 'Ethernet' on<br />
</code></p>
<p>然后pac文件就已经被重载完毕啦！在此感谢Dylan。</p>
<p>顺便共享一下我在bash下的alias：</p>
<p><code><br />
alias px='ssh -qTfnNC -D 7777 tin@zztin.com'<br />
alias rpx="sudo networksetup -setautoproxystate 'AirPort' off;sudo networksetup -setautoproxyurl 'AirPort' 'file://localhost/Users/tin/pac/tin    .pac';sudo networksetup -setautoproxystate 'AirPort' on;sudo networksetup -setautoproxystate 'Ethernet' off;sudo networksetup -setautoproxyurl     'Ethernet' 'file://localhost/Users/tin/pac/tin.pac';sudo networksetup -setautoproxystate 'Ethernet' on"<br />
</code></p>
]]></content:encoded>
			<wfw:commentRss>http://www.diamondtin.com/2009/reloading-pac-script-in-mac/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

