<?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>秃驴&#039;s 网志</title>
	<atom:link href="http://www.aoqb.com/index.php/feed" rel="self" type="application/rss+xml" />
	<link>http://www.aoqb.com</link>
	<description>眼光决定高度，细节决定成败</description>
	<lastBuildDate>Wed, 16 Nov 2011 14:00:13 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>大道由我 开发至简</title>
		<link>http://www.aoqb.com/index.php/archives/138</link>
		<comments>http://www.aoqb.com/index.php/archives/138#comments</comments>
		<pubDate>Wed, 16 Nov 2011 13:58:39 +0000</pubDate>
		<dc:creator>秃驴</dc:creator>
				<category><![CDATA[其他]]></category>
		<category><![CDATA[大道由我 开发至简]]></category>

		<guid isPermaLink="false">http://www.aoqb.com/?p=138</guid>
		<description><![CDATA[在苦难和磨练中站起来的才是巨人

每个人心中都有一条康庄大道

自信 大道由我

<span class="readmore"><a href="http://www.aoqb.com/index.php/archives/138" title="大道由我 开发至简">阅读全文——共88字</a></span>]]></description>
			<content:encoded><![CDATA[<p>在苦难和磨练中站起来的才是巨人</p>
<p>每个人心中都有一条康庄大道</p>
<p>自信 大道由我</p>
<p>开发是一件很繁碎的事情</p>
<p>把简单的东西复杂化 不是能力 是蛮力</p>
<p>开发至简 才能最好的把握需求核心</p>
<p>大道由我 开发至简</p>
<p>与君共勉
<div>
<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/2.5/cn/"><img alt="知识共享许可协议" style="border-width:0" src="http://i.creativecommons.org/l/by-nc-sa/2.5/cn/88x31.png" /></a><br />本<span xmlns:dct="http://purl.org/dc/terms/" href="http://purl.org/dc/dcmitype/Text" rel="dct:type">作品</span>采用<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/2.5/cn/">知识共享署名-非商业性使用-相同方式共享 2.5 中国大陆许可协议</a>进行许可。
</div>
<div>原创文章,转载请注明：转载自<a href="http://www.aoqb.com/">秃驴&#039;s 网志</a><br />
本文地址：<a href="http://www.aoqb.com/index.php/archives/138">大道由我 开发至简</a>
</div>
<p><!-- PHP 5.x --></p>
]]></content:encoded>
			<wfw:commentRss>http://www.aoqb.com/index.php/archives/138/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>关于敏捷编程的一些思考</title>
		<link>http://www.aoqb.com/index.php/archives/131</link>
		<comments>http://www.aoqb.com/index.php/archives/131#comments</comments>
		<pubDate>Wed, 24 Aug 2011 00:21:49 +0000</pubDate>
		<dc:creator>秃驴</dc:creator>
				<category><![CDATA[技术]]></category>
		<category><![CDATA[敏捷编程]]></category>

		<guid isPermaLink="false">http://www.aoqb.com/?p=131</guid>
		<description><![CDATA[敏捷是太极：这段时间下来，感觉敏捷很像太极，两仪生四象，四象生八卦；敏捷的精髓在神而不在形。敏捷的神就包含在下面四条敏捷宣言（Agile Manifesto）中：





<span class="readmore"><a href="http://www.aoqb.com/index.php/archives/131" title="关于敏捷编程的一些思考">阅读全文——共1550字</a></span>]]></description>
			<content:encoded><![CDATA[<ul>
<li><span class="Apple-style-span" style="color: #000000;"><strong><span style="font-size: small;">敏捷是太极</span></strong><span style="font-size: small;">：这段时间下来，感觉敏捷很像太极，两仪生四象，四象生八卦；敏捷的精髓在神而不在形。敏捷的神就包含在下面四条敏捷宣言（</span><span style="font-size: small;">Agile Manifesto</span></span><span class="Apple-style-span" style="color: #000000;"><span style="font-size: small;">）中：</span></span></li>
</ul>
<ol>
<li><span style="color: #000000;"><strong><span style="font-size: small;">个人和交互重于方法和工具</span></strong><span style="font-size: small;">（</span><span style="font-size: small;">Individuals and interactions over processes and tools</span></span><span style="color: #000000;"><span style="font-size: small;">）；</span></span></li>
<li><span style="color: #000000;"><strong><span style="font-size: small;">可工作的软件重于完备的文档</span></strong><span style="font-size: small;">（</span><span style="font-size: small;">Working software over comprehensive documentation</span><span style="font-size: small;">）；</span></span></li>
<li><span style="color: #000000;"><strong><span style="font-size: small;">与客户的协作重于合同谈判</span></strong><span style="font-size: small;">（</span><span style="font-size: small;">Customer collaboration over contract negotiation</span></span><span style="color: #000000;"><span style="font-size: small;">）；</span></span></li>
<li><span class="Apple-style-span" style="color: #000000;"><strong><span style="font-size: small;">响应变化重于严格遵照计划</span></strong><span style="font-size: small;">（</span><span style="font-size: small;">Responding to change over following a plan</span><span style="font-size: small;">）；</span></span></li>
</ol>
<p><span style="color: #000000; font-size: small;">实施敏捷的关键在于掌握这些原则，然后将这些原则与组织的自身实际情况相结合，再制定合理的改进计划，而不是照搬敏捷所有的具体建议。</span></p>
<ul>
<li><span class="Apple-style-span" style="color: #000000;"><strong><span style="font-size: small;">敏捷是有国情的</span></strong><span style="font-size: small;">：如</span><span style="font-size: small;">Ivar</span><span style="font-size: small;">所说，敏捷的最重要创新在于它是一项以激励开发人员工作热情为目标的社会工程。敏捷作为一个社会工程，它的许多建议是有社会性的，比如自组织的团队（</span><span style="font-size: small;">Self organizing teams</span></span><span class="Apple-style-span" style="color: #000000;"><span style="font-size: small;">）。这一建议就跟欧美的实际情况有关：良好的替代职业发展道路、社会福利体系以及相对扁平的薪酬体系是很多优秀的程序员安心地以程序员为终生职业，程序员比开发经理资深的情况比比皆是。而这一情况在目前中国是显然不存在的。理解了这一背景之后，一个组织就应该仔细去衡量“自组织的团队”在本组织内的可能性如何了。</span></span></li>
<li><span class="Apple-style-span" style="color: #000000;"><strong><span style="font-size: small;">敏捷是要破除两个迷信</span></strong></span><span class="Apple-style-span" style="color: #000000;"><span style="font-size: small;">：俗话说，不破不立。要实施敏捷，首先需要做的是打破开发组织中的两个迷信，挣脱枷锁，才能轻装前进。一个迷信是软件开发可以成为生产线，每个岗位的职责可以被明确定义，各个岗位之间接口同样可以被明确定义，大家只要各司其职，高质量的软件就可以被生产出来；生产线是我们的愿望，但不是现实；按照这样的美好愿望去组织软件开发必然付出惨痛的代价。软件开发是一个高度复杂的团队智力活动，如同创作一件雕塑作品一样，在基本的职责框架下，团队内部必须协同合作，才能开发出高质量的软件。画地为牢是行不通的。另一个迷信是软件开发过程可以向建筑一样被准确地预测和计划，这同样是美好愿望而不是现实。敏捷号召的就是在这两个问题上回归现实。</span></span></li>
<li><span class="Apple-style-span" style="color: #000000;"><strong><span style="font-size: small;">敏捷不是要回到十年前的程序员无政府状态</span></strong><span style="font-size: small;">：回归现实并不意味着将这十年来的过程</span><span style="font-size: small;">/</span><span style="font-size: small;">质量控制经验全都付之一炬。在我们咨询的过程中，我们发现一个对敏捷的误解是：敏捷</span><span style="font-size: small;">=</span></span><span class="Apple-style-span" style="color: #000000;"><span style="font-size: small;">随心所欲；很多刚入行的程序员为此欢欣鼓舞，而大多数领导和质量保证人员则对此忧心仲仲（因为大多数现在的领导恰恰经历过十年前的无政府状态，也深知其中的问题），这种误解对敏捷是非常有害的。</span></span></li>
<li><span class="Apple-style-span" style="color: #000000;"><strong><span style="font-size: small;">敏捷是对僵化实施CMMI</span></strong><strong><span style="font-size: small;">的反正</span></strong></span><span class="Apple-style-span" style="color: #000000;"><span style="font-size: small;">：敏捷的目标应该是重新审视现有软件开发流程，放弃不切实际的梦想（流水线和准确计划），根据敏捷的基本原则，重新优化现有流程和文档体系，但不是全面推到重来。在这个过程中，需要不断地问各种问题：为什么要写这些文档？给谁看？目的是什么？这个活动的输入输出是什么？由谁负责？由谁辅助？等等。在一个组织当中，很多流程和文档是多年累积的结果，当时设计这些流程和文档的初始条件可能已经不存在了（例如，当年是主做新系统的开发，而现在已经大多数是做现有系统的维护了），因此，需要用敏捷的思想对现有流程进行优化。</span></span></li>
<li><span class="Apple-style-span" style="color: #000000;"><strong><span style="font-size: small;">敏捷是分层的</span></strong><span style="font-size: small;">：敏捷根据实施的范围应该是分层的，可以分成小组级敏捷、组织级敏捷。小组级敏捷的重点是一个小组（</span><span style="font-size: small;">10-20</span><span style="font-size: small;">人）如何进行协同工作，这是目前敏捷的热点；而组织级敏捷的重点是如何将一个大型项目分解到小组，如何保证小组能够协同工作，如何保证敏捷的流程与企业现有的管理体系接轨（如</span><span style="font-size: small;">IPD</span><span style="font-size: small;">，</span><span style="font-size: small;">QA</span><span style="font-size: small;">，</span><span style="font-size: small;">CMMI</span><span style="font-size: small;">等），如何优化现有的流程与文档体系，这些才是敏捷真正实施中的难点。</span></span></li>
</ul>
<div>
<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/2.5/cn/"><img alt="知识共享许可协议" style="border-width:0" src="http://i.creativecommons.org/l/by-nc-sa/2.5/cn/88x31.png" /></a><br />本<span xmlns:dct="http://purl.org/dc/terms/" href="http://purl.org/dc/dcmitype/Text" rel="dct:type">作品</span>采用<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/2.5/cn/">知识共享署名-非商业性使用-相同方式共享 2.5 中国大陆许可协议</a>进行许可。
</div>
<div>原创文章,转载请注明：转载自<a href="http://www.aoqb.com/">秃驴&#039;s 网志</a><br />
本文地址：<a href="http://www.aoqb.com/index.php/archives/131">关于敏捷编程的一些思考</a>
</div>
<p><!-- PHP 5.x --></p>
]]></content:encoded>
			<wfw:commentRss>http://www.aoqb.com/index.php/archives/131/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>云计算究竟是什么？</title>
		<link>http://www.aoqb.com/index.php/archives/129</link>
		<comments>http://www.aoqb.com/index.php/archives/129#comments</comments>
		<pubDate>Tue, 23 Aug 2011 19:25:21 +0000</pubDate>
		<dc:creator>秃驴</dc:creator>
				<category><![CDATA[技术]]></category>

		<guid isPermaLink="false">http://www.aoqb.com/?p=129</guid>
		<description><![CDATA[云计算究竟是什么？昨天又和朋友讨论到云计算，觉得大家对这个概念都云里雾里的。于是就激起了我的考究癖，想搞个清楚，上网查了查发现还真不容易，各家都在炒概念各说各话。

Form Wikipedia: Cloud computing refers to computing resources being accessed which are typically owned and operated by a third-party provider on a consolidated basis in Data Center locations.

<span class="readmore"><a href="http://www.aoqb.com/index.php/archives/129" title="云计算究竟是什么？">阅读全文——共610字</a></span>]]></description>
			<content:encoded><![CDATA[<p>云计算究竟是什么？昨天又和朋友讨论到云计算，觉得大家对这个概念都云里雾里的。于是就激起了我的考究癖，想搞个清楚，上网查了查发现还真不容易，各家都在炒概念各说各话。</p>
<p><em>Form Wikipedia: Cloud computing refers to computing resources being accessed which are typically owned and operated by a third-party provider on a consolidated basis in Data Center locations.</em></p>
<p>总体来讲，云计算是指计算能力和存储能力向互联网端的迁移和抽象：迁移是指计算和存储都不在本机甚至本地服务器而迁移到了互联网远端的服务器集群上，抽象是指最终用户无需关心真正的存储和计算发生在何处。</p>
<p>所以当硬件厂商（如IBM）强调云计算时，更多是在强调迁移；硬件厂商希望推动第三方云计算中心的建立（这样可以买更多的硬件）。互联网厂商（如Google）则强调抽象，即最终用户无需关心计算和存储的具体位置，从而减弱最终用户对本地资源的心理依赖（如本地的操作系统，本地的应用软件等）。传统软件厂商（如微软）则疲于应付，处于人云亦云的状态</p>
<p>p.s：云计算在我心目中的定义：</p>
<ol>
<li>一:硬件的集中类似现在的IDC，但是比IDC更有优势</li>
<li>资源的自由伸缩性，包括计算，存储，外加带宽。虚拟化是云的基础。</li>
<li>软件（服务）。就是一种廋客户端的应用，所有的桌面软件web化。</li>
</ol>
<div>
<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/2.5/cn/"><img alt="知识共享许可协议" style="border-width:0" src="http://i.creativecommons.org/l/by-nc-sa/2.5/cn/88x31.png" /></a><br />本<span xmlns:dct="http://purl.org/dc/terms/" href="http://purl.org/dc/dcmitype/Text" rel="dct:type">作品</span>采用<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/2.5/cn/">知识共享署名-非商业性使用-相同方式共享 2.5 中国大陆许可协议</a>进行许可。
</div>
<div>原创文章,转载请注明：转载自<a href="http://www.aoqb.com/">秃驴&#039;s 网志</a><br />
本文地址：<a href="http://www.aoqb.com/index.php/archives/129">云计算究竟是什么？</a>
</div>
<p><!-- PHP 5.x --></p>
]]></content:encoded>
			<wfw:commentRss>http://www.aoqb.com/index.php/archives/129/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>测试的目的应该是验证需求</title>
		<link>http://www.aoqb.com/index.php/archives/127</link>
		<comments>http://www.aoqb.com/index.php/archives/127#comments</comments>
		<pubDate>Tue, 23 Aug 2011 16:18:12 +0000</pubDate>
		<dc:creator>秃驴</dc:creator>
				<category><![CDATA[技术]]></category>
		<category><![CDATA[测试]]></category>
		<category><![CDATA[验证需求]]></category>

		<guid isPermaLink="false">http://www.aoqb.com/?p=127</guid>
		<description><![CDATA[测试的目的是什么呢？这是一个看起来很简单、不太值得讨论的问题，但往往这样的问题其实是很难回答的，比如人生的意义是什么？好，现在我们就来，列举一下我们经常听到的对这个问题的回答：



“软件测试的目的是尽可能发现并改正被测试软件中的错误，提高软件的可靠性。”，这个定义听起来很正确，但用它来指导测试会带来很多问题。比如有的组织用发现的bug数来衡量测试人员的业绩，其实这就是这种测试目的论在后面作祟，其结果如何呢：其一，有一些不够敬业的测试人员会找来一些无关痛痒的bug来充数，结果许多时间会被浪费在这些无关痛痒的bug上（其实应该修复，何时修复，严重程度是什么，优先级是什么，等等）；其二，测试人员会花很大力气设计一些复杂的测试用例去发现一些迄今尚未发现的缺陷，而不关心这些缺陷是否在实际用户的使用过程当中是否会发生，从而浪费了大量的宝贵时间。究其根源，就是因为对测试目的的这种错误理解造成的，为什么这么说呢？因为软件里bug的数量是无从估计的，那么如果测试的目的是为了找bug，那么测试工作将变成一项无法完成也无法衡量进度而且部分无效的工作（因为有些bug在实际的运行过程当中根本不会发生）。

<span class="readmore"><a href="http://www.aoqb.com/index.php/archives/127" title="测试的目的应该是验证需求">阅读全文——共1103字</a></span>]]></description>
			<content:encoded><![CDATA[<div>测试的目的是什么呢？这是一个看起来很简单、不太值得讨论的问题，但往往这样的问题其实是很难回答的，比如人生的意义是什么？好，现在我们就来，列举一下我们经常听到的对这个问题的回答：</div>
<div></div>
<div>“软件测试的目的是尽可能发现并改正被测试软件中的错误，提高软件的可靠性。”，这个定义听起来很正确，但用它来指导测试会带来很多问题。比如有的组织用发现的bug数来衡量测试人员的业绩，其实这就是这种测试目的论在后面作祟，其结果如何呢：其一，有一些不够敬业的测试人员会找来一些无关痛痒的bug来充数，结果许多时间会被浪费在这些无关痛痒的bug上（其实应该修复，何时修复，严重程度是什么，优先级是什么，等等）；其二，测试人员会花很大力气设计一些复杂的测试用例去发现一些迄今尚未发现的缺陷，而不关心这些缺陷是否在实际用户的使用过程当中是否会发生，从而浪费了大量的宝贵时间。究其根源，就是因为对测试目的的这种错误理解造成的，为什么这么说呢？因为软件里bug的数量是无从估计的，那么如果测试的目的是为了找bug，那么测试工作将变成一项无法完成也无法衡量进度而且部分无效的工作（因为有些bug在实际的运行过程当中根本不会发生）。</div>
<div></div>
<div>“测试的目的就是为了保证软件质量”，这个定义也是看似正确，但实际上，混淆了测试和质量保证工作的边界。软件质量要素有很多，包括：Understandability、Conciseness、Portability、Consistency、Maintainability、Testability、Usability、Structures、Efficiency、Security等等，所以，软件质量保证和测试其实关注的方向是不同的。</div>
<div></div>
<div>那么测试的目的应该是什么呢？IEEE在1983年提出了软件测试的定义：</div>
<div><em>“使用人工或自动手段来运行或测定某个系统的过程，其目的在于<strong>检验它是否满足规定的需求</strong>或是弄清预期结果与实际结果之间的差别。”</em></div>
<div></div>
<div>所以，简言之，<strong>测试的目的应该是验证需求</strong>，bug（预期结果与实际结果之间的差别）是这个过程中的产品而非目标。测试人员应该象工兵一样，在大部队（客户）预期前进的方向上探雷、扫雷（bug），而不需要去关心那些根本没有人会去碰的地雷。衡量一个测试人员应该去衡量他/她测试了多少需求（测试工作量），漏过了多少bug（测试有效性）。（在后面的博文里我们会进一步谈测试后评估的重要性）</div>
<div></div>
<div>因此，我们可以看到有好的需求文档/体系对测试工作的必要性，我们看到许多测试团队在业务需求/软件需求不完备的情况下，往往或重新编写测试需求。在未来的博文里，我们会在介绍为什么用例（Use Case）技术会有助于开发人员和测试人员的沟通。</div>
<div>
<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/2.5/cn/"><img alt="知识共享许可协议" style="border-width:0" src="http://i.creativecommons.org/l/by-nc-sa/2.5/cn/88x31.png" /></a><br />本<span xmlns:dct="http://purl.org/dc/terms/" href="http://purl.org/dc/dcmitype/Text" rel="dct:type">作品</span>采用<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/2.5/cn/">知识共享署名-非商业性使用-相同方式共享 2.5 中国大陆许可协议</a>进行许可。
</div>
<div>原创文章,转载请注明：转载自<a href="http://www.aoqb.com/">秃驴&#039;s 网志</a><br />
本文地址：<a href="http://www.aoqb.com/index.php/archives/127">测试的目的应该是验证需求</a>
</div>
<p><!-- PHP 5.x --></p>
]]></content:encoded>
			<wfw:commentRss>http://www.aoqb.com/index.php/archives/127/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>针对MySQL的高并发优化(MyISAM/InnoDB)</title>
		<link>http://www.aoqb.com/index.php/archives/123</link>
		<comments>http://www.aoqb.com/index.php/archives/123#comments</comments>
		<pubDate>Thu, 18 Aug 2011 18:49:04 +0000</pubDate>
		<dc:creator>秃驴</dc:creator>
				<category><![CDATA[技术]]></category>
		<category><![CDATA[InnoDB]]></category>
		<category><![CDATA[MyISAM]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[优化]]></category>
		<category><![CDATA[高并发]]></category>

		<guid isPermaLink="false">http://www.aoqb.com/?p=123</guid>
		<description><![CDATA[最近做的一个应用，功能要求非常简单，就是 key/value 形式的存储，简单的 INSERT/SELECT，没有任何复杂查询，唯一的问题是量非常大，如果目前投入使用，初期的单表 insert 频率约 20Hz（次/秒，我喜欢这个单位，让我想起国内交流电是 50Hz），但我估计以后会有 500Hz+ 的峰值。目前的工作成果，额定功率 200Hz（CPU 占用 10 – 20，load avg = 2），最大功率 500Hz（这时 load avg &#62; 20，很明显，只能暂时挺挺，应该在出现这种负载前提前拆表了）

<span class="readmore"><a href="http://www.aoqb.com/index.php/archives/123" title="针对MySQL的高并发优化(MyISAM/InnoDB)">阅读全文——共7103字</a></span>]]></description>
			<content:encoded><![CDATA[<p>最近做的一个应用，功能要求非常简单，就是 key/value 形式的存储，简单的 INSERT/SELECT，没有任何复杂查询，唯一的问题是量非常大，如果目前投入使用，初期的单表 insert 频率约 20Hz（次/秒，我喜欢这个单位，让我想起国内交流电是 50Hz），但我估计以后会有 500Hz+ 的峰值。目前的工作成果，额定功率 200Hz（CPU 占用 10 – 20，load avg = 2），最大功率 500Hz（这时 load avg &gt; 20，很明显，只能暂时挺挺，应该在出现这种负载前提前拆表了）</p>
<p>INSERT DELAYED INTO</p>
<p>从 数据的插入开始说起。如果可以容忍结果几秒以后再生效的，可以用 INSERT DELAYED INTO，因为在我的这个结构中不需要对同一个 key 频繁的 INSERT/SELECT，因为 SELECT 我是用 Memcached 挡住了，除非 Memcached 挂了，或者数据实在老到过期了，才会去 SELECT。而且要注意，如果 PHP 不需要关心 <a title="MySQL" href="http://www.ha97.com/category/database/mysql-database">MySQL</a> 操作的返回结果，应该使用 unbuffered query，简单的说，在你提交 query 后，不用等待 <a title="MySQL" href="http://www.ha97.com/tag/mysql">MySQL</a> 有返回信息就继续执行之后的 PHP 指令，具体用法是用 mysql_unbuffered_query 代替 mysql_query，如果用的 MySQLi 类，应该使用 mysqli-&gt;query($sQuery, MYSQLI_USE_RESULT);</p>
<p>如果 SHOW PROCESSLIST，可以看到用户名为 DELAYED 的进程，进程数量等于 INSERT DELAYED 的表的数量，因为表级锁的存在，每个表一条以上的 DELAYED 进程是没有意义的</p>
<p>关于这个功能的 <a title="my.cnf" href="http://www.ha97.com/tag/my-cnf">my.cnf</a> 配置有三条，我定为如下值</p>
<blockquote><p>delayed_insert_limit = 1000<br />
delayed_insert_timeout = 300<br />
delayed_queue_size = 5000</p></blockquote>
<p>连接</p>
<p>有 人说，如果报错连接数过大，你把 max_connections 调大就 OK，如果只这么说而不讲原因，完全是句废话，你调成 1M 肯定不会再报 Too many connections（但应该会报内存溢出之类的），但如果是这样 MySQL 又何必给这个参数？</p>
<p>我看到的一个很有用的公式</p>
<blockquote><p>key_buffer_size + (read_buffer_size + sort_buffer_size) * max_connections</p></blockquote>
<p>以前只有很模糊的概念，应该设的很大，但又不能太大，具体多大合适，知道这个就明确了。<a title="innoDB" href="http://www.ha97.com/tag/innodb" rel="nofollow" target="_blank">innoDB</a> 的公式比这个复杂点，一并<a href="http://dev.mysql.com/doc/refman/5.1/en/innodb-configuration.html">给出</a></p>
<blockquote><p>innodb_buffer_pool_size<br />
+ key_buffer_size<br />
+ max_connections * ( sort_buffer_size + read_buffer_size + binlog_cache_size )<br />
+ max_connections * 2MB</p></blockquote>
<p>还有一个看起来很有用的参数 <a href="http://dev.mysql.com/doc/refman/5.1/en/server-system-variables.html#option_mysqld_back_log" rel="nofollow" target="_blank">back_log</a>，给我一种连接池的感觉，而且它确实在起作用，我不知道如果设大了会占用多少内存，但估计不会很多。</p>
<p>&nbsp;</p>
<p>key_buffer_size</p>
<p>很 多文章都告诉你越大越好，要为此分配一半左右的物理内存，这么干通常不会出问题，但肯定不是最优的，甚至可以说很无理头——分多少内存应该是根据需求决 定，而不是不管什么机器，都砍掉一半内存用作 key_buffer_size ——有的时候可能是不够，还有的时候可能是浪费。</p>
<p>其实最关 键的指标，还是看 SHOW GLOBAL STATUS 时的 Key_blocks_unused，只要还有剩余，就说明 key_buffer_size 没用满。有人说看 Key_reads 跟 Key_read_requests 的比值，至少要达到 1:100。这可以作为一个结果来衡量，但不够准确，因为在服务器刚启动的时候，大多数请求都要新建缓存，缓存命中比高不起来，需要运行稳定（几小时后） 再观察。我个人建议还是看 Key_blocks_unused</p>
<p>如果不花很长时间在运行中调试，给出一个简单的计算方法，把数据库填满，达到设计时的最大值，看看这时候索引占了多大空间，然后把所有表的索引大小加起来，就是 key_buffer_size 可能达到的最大值，当然，还要留些余地，乘个 2 或 3 之类的。</p>
<p>这是我做测试的时候的 <a title="phpMyAdmin" href="http://www.ha97.com/tag/phpmyadmin">phpMyAdmin</a> 截图，可以看到 key_buffer_size 被浪费了太多</p>
<p><a href="http://www.ha97.com/wp-content/uploads/2011/07/key_buffer.png" rel="lightbox[123]" title="key_buffer"><img title="key_buffer" src="http://www.ha97.com/wp-content/uploads/2011/07/key_buffer.png" alt="" width="806" height="318" /></a></p>
<p>OPTIMIZE TABLE</p>
<p>优 化一下有好处，但会锁住表，是否值得做要权衡一下。拿我现在这个表做例子，有 text 字段，700万条记录，1.5G 大小，优化时间约两分钟，优化后性能提升了 50%，同时表的大小变为 1.4G，但随着表的频繁改写，约一天后又恢复到以前的速度，因此在我看来并不值得。</p>
<p>Query Cache</p>
<p>因为每有写操作 Query Cache 都会被清空，除了极特殊的情况（大量读，少量写，但即使这样也应该是多用 memcached 才对）完全没有必要使用这个，把 query_cache_size 设为 0 关闭这个功能吧。</p>
<p>InnoDB和<a title="MyISAM" href="http://www.ha97.com/tag/myisam">MyISAM</a>是在使用MySQL最常用的两个表类型，各有优缺点，视具体应用而定。基本 的差别为：MyISAM类型不支持事务处理等高级处理，而InnoDB类型支持。MyISAM类型的表强调的是性能，其执行数度比InnoDB类型更快， 但是不提供事务支持，而InnoDB提供事务支持已经外部键等高级数据库功能。</p>
<p>MyISAM:这个是默认类型,它是基于传统的ISAM类型,ISAM是Indexed Sequential Access Method (有索引的顺序访问方法) 的缩写,它是存储记录和文件的标准方法.与其他存储引擎比较,MyISAM具有检查和修复表格的大多数工具. MyISAM表格可以被压缩,而且它们支持全文搜索.它们不是事务安全的,而且也不支持外键。如果事物回滚将造成不完全回滚，不具有原子性。如果执行大量 的SELECT，MyISAM是更好的选择。</p>
<p>InnoDB:这种类型是事务安全的.它与BDB类型具有相同的特性,它们还支持外键.InnoDB表格速度很快.具有比BDB还丰富的特性,因此如果需 要一个事务安全的存储引擎,建议使用它.如果你的数据执行大量的INSERT或<a title="UPDATE" href="http://www.ha97.com/tag/update">UPDATE</a>,出于性能方面的考虑，应该使用InnoDB表,</p>
<p>对于支持事物的InnoDB类型的标，影响速度的主要原因是AUTOCOMMIT默认设置是打开的，而且程序没有显式调用BEGIN 开始事务，导致每插入一条都自动Commit，严重影响了速度。可以在执行sql前调用begin，多条sql形成一个事物（即使autocommit打 开也可以），将大大提高性能。</p>
<p>MyIASM是IASM表的新版本，有如下扩展：</p>
<p>1、二进制层次的可移植性。<br />
2、NULL列索引。<br />
3、对变长行比ISAM表有更少的碎片。<br />
4、支持大文件。<br />
5、更好的索引压缩。<br />
6、更好的键码统计分布。<br />
7、更好和更快的auto_increment处理。</p>
<p>InnoDB 是 MySQL 上第一个提供外键约束的引擎，除了提供事务处理外，InnoDB 还支持行锁，提供和 <a title="Oracle" href="http://www.ha97.com/category/database/oracle-database">Oracle</a> 一样的一致性的不加锁读取，能增加并发读的用户数量并提高性能，不会增加锁的数量。</p>
<p>InnoDB 的设计目标是处理大容量数据时最大化性能，它的 CPU 利用率是其他所有基于磁盘的关系数据库引擎中最有效率的。</p>
<p>InnoDB 是一套放在 MySQL 后台的完整数据库系统，InnoDB 有它自己的缓冲池，能缓冲数据和索引，InnoDB 还把数据和索引存放在表空间里面，可能包含好几个文件，这和 MyISAM 表完全不同，在 MyISAM 中，表被存放在单独的文件中，InnoDB 表的大小只受限于操作系统文件的大小，一般为 2GB。</p>
<p>InnoDB所有的表都保存在同一个数据文件 ibdata1 中(也可能是多个文件，或者是独立的表空间文件),相对来说比较不好备份，免费的方案可以是拷贝数据文件、备份 binlog，或者用 mysqldump。</p>
<p>MyISAM 是MySQL缺省存贮引擎 .</p>
<p>每张MyISAM 表被存放在三个文件 。frm 文件存放表格定义。 数据文件是MYD (MYData) 。 索引文件是MYI (MYIndex) 引伸。</p>
<p>因为MyISAM相对简单所以在效率上要优于InnoDB..小型应用使用MyISAM是不错的选择。</p>
<p>MyISAM表是保存成文件的形式,在跨平台的数据转移中使用MyISAM存储会省去不少的麻烦。</p>
<p><strong>以下是一些细节和具体实现的差别：</strong></p>
<p>1、InnoDB不支持FULLTEXT类型的索引。<br />
2、InnoDB 中不保存表的具体行数，也就是说，执行select count(*) from table时，InnoDB要扫描一遍整个表来计算有多少行，但是MyISAM只要简单的读出保存好的行数即可。注意的是，当count(*)语句包含 where条件时，两种表的操作是一样的。<br />
3、对于AUTO_INCREMENT类型的字段，InnoDB中必须包含只有该字段的索引，但是在MyISAM表中，可以和其他字段一起建立联合索引。<br />
4、DELETE FROM table时，InnoDB不会重新建立表，而是一行一行的删除。<br />
5、LOAD TABLE FROM MASTER操作对InnoDB是不起作用的，解决方法是首先把InnoDB表改成MyISAM表，导入数据后再改成InnoDB表，但是对于使用的额外的InnoDB特性（例如外键）的表不适用。<br />
6、InnoDB表的行锁也不是绝对的，如果在执行一个SQL语句时MySQL不能确定要扫描的范围，InnoDB表同样会锁全表，例如update table set num=1 where name like “%aaa%”</p>
<p><strong>综上所述，任何一种表都不是万能的，只有恰当的针对业务类型来疡合适的表类型，才能最大的发挥MySQL的性能优势。</strong></p>
<p>两种类型最主要的差别就是 InnoDB 支持事务处理与外键和行级锁.而MyISAM不支持.所以Myisam往往就容易被人认为只适合在小项目中使用。</p>
<p>我作为使用mysql的用户角度出发，innodb和myisam都是比较喜欢的，但是从我目前运维的数据库平台要达到需求：99.9%的稳定性，方便的扩展性和高可用性来说的话，myisam绝对是我的首选。</p>
<p>原因如下：</p>
<p>1.首先我目前平台上承载的大部分项目是读多写少的项目，而myisam的读性能是比innodb强不少的。</p>
<p>2.myisam的索引和数据是分开的，并且索引是有压缩的，内存使用率就对应提高了不少。能加载更多索引，而innodb是索引和数据是紧密捆绑的，没有使用压缩从而会造成innodb比myisam体积庞大不校</p>
<p>3.从平台角度来说，经常隔1，2个月就会发生应用开发人员不小心update一个表where写的范围不对，导致这个表没法正常用了，这个时候 myisam 的优越性就体现出来了，随便从当天拷贝的压缩包取出对应表的文件，随便放到一个数据库目录下，然后dump成sql再导回到主库，并把对应的binlog 补上。如果是innodb，恐怕不可能有这么快速度，别和我说让innodb定期用导出xxx.sql机制备份，因为我平台上最小的一个数据库实例的数据 量基本都是几十G大校</p>
<p>4.从我接触的应用逻辑来说，select count(*) 和order by 是最频繁的，大概能占了整个sql总语句的60%以上的操作，而这种操作innodb其实也是会锁表的，很多人以为innodb是行级锁，那个只是 where对它主键是有效，非主键的都会锁全表的。</p>
<p>5.还有就是经常有很多应用部门需要我给他们定期某些表的数据，myisam的话很方便，只要发给他们对应那表的frm.MYD,MYI的文件，让他们自 己在对应版本的数据库启动就行，而innodb就需要导出xxx.sql了，因为光给别人文件，受字典数据文件的影响，对方是无法使用的。</p>
<p>6.如果和myisam比insert写操作的话，innodb还达不到myisam的写性能，如果是针对基于索引的update操作，虽然myisam可能会逊色innodb,但是那么高并发的写，从库能否追的上也是一个问题，还不如通过多实例分库分表架构来解决。</p>
<p>7.如果是用Myisam的话，merge引擎可以大大加快应用部门的开发速度，他们只要对这个merge表做一些select count(*)操作，非常适合大项目总量约几亿的rows某一类型(如日志，调查统计)的业务表。</p>
<p>当然innodb也不是绝对不用，用事务的项目如模拟炒股项目，我就是用innodb的，活跃用户20多万时候，也是很轻松应付了，因此我个人也是很喜欢Innodb的，只是</p>
<p>如果从数据库平台应用出发，我还是会首选myisam.</p>
<p>PS:可能有人会说你myisam无法抗太多写操作，但是我可以通过架构来弥补，说个我现有用的数据库平台容量：主从数据总量在几百T以上，每天十多亿 pv的动态页面，还有几个大项目是通过数据接口方式调用未算进pv总数，(其中包括一个大项目因为初期memcached没部署,导致单台数据库每天处理 9千万的查询)。而我的整体数据库服务器平均负载都在0.5-1左右。</p>
<p><strong>MyISAM和InnoDB优化：</strong></p>
<p><strong>key_buffer_size</strong> – 这对MyISAM表来说非常重要。如果只是使用MyISAM表，可以把它设置为可用内存的 30-40%。合理的值取决于索引大小、数据量以及负载 — 记住，MyISAM表会使用操作系统的缓存来缓存数据，因此需要留出部分内存给它们，很多情况下数据比索引大多了。尽管如此，需要总是检查是否所有的 key_buffer 都被利用了 — .MYI 文件只有 1GB，而 key_buffer 却设置为 4GB 的情况是非常少的。这么做太浪费了。如果你很少使用MyISAM表，那么也保留低于 16-32MB 的 key_buffer_size 以适应给予磁盘的临时表索引所需。</p>
<p><strong>innodb_buffer_pool_size</strong> – 这对Innodb表来说非常重要。Innodb相比MyISAM表对缓冲更为敏感。MyISAM可以在默认的 key_buffer_size 设置下运行的可以，然而Innodb在默认的 innodb_buffer_pool_size 设置下却跟蜗牛似的。由于Innodb把数据和索引都缓存起来，无需留给操作系统太多的内存，因此如果只需要用Innodb的话则可以设置它高达 70-80% 的可用内存。一些应用于 key_buffer 的规则有 — 如果你的数据量不大，并且不会暴增，那么无需把 innodb_buffer_pool_size 设置的太大了。</p>
<p><strong>innodb_additional_pool_size</strong> – 这个选项对性能影响并不太多，至少在有差不多足够内存可分配的操作系统上是这样。不过如果你仍然想设置为 20MB(或者更大)，因此就需要看一下Innodb其他需要分配的内存有多少。</p>
<p><strong>innodb_log_file_size</strong> 在高写入负载尤其是大数据集的情况下很重要。这个值越大则性能相对越高，但是要注意到可能会增加恢复时间。我经常设置为 64-512MB，跟据服务器大小而异。</p>
<p><strong>innodb_log_buffer_size </strong>默 认的设置在中等强度写入负载以及较短事务的情况下，服务器性能还可 以。如果存在更新操作峰值或者负载较大，就应该考虑加大它的值了。如果它的值设置太高了，可能会浪费内存 — 它每秒都会刷新一次，因此无需设置超过1秒所需的内存空间。通常 8-16MB 就足够了。越小的系统它的值越小。</p>
<p><strong>innodb_flush_logs_at_trx_commit</strong> 是否为Innodb比MyISAM慢1000倍而头大？看来也许你忘了修改这个参数了。默认值是 1，这意味着每次提交的更新事务（或者每个事务之外的语句）都会刷新到磁盘中，而这相当耗费资源，尤其是没有电池备用缓存时。很多应用程序，尤其是从 MyISAM转变过来的那些，把它的值设置为 2 就可以了，也就是不把日志刷新到磁盘上，而只刷新到操作系统的缓存上。日志仍然会每秒刷新到磁盘中去，因此通常不会丢失每秒1-2次更新的消耗。如果设置 为 0 就快很多了，不过也相对不安全了 — MySQL服务器崩溃时就会丢失一些事务。设置为 2 指挥丢失刷新到操作系统缓存的那部分事务。</p>
<p><strong>table_cache</strong> — 打开一个表的开销可能很大。例如MyISAM把MYI文件头标志该表正在使用中。你肯定不希望这种操作太频繁，所以通常要加大缓存数量，使得足以最大限度 地缓存打开的表。它需要用到操作系统的资源以及内存，对当前的硬件配置来说当然不是什么问题了。如果你有200多个表的话，那么设置为 1024 也许比较合适（每个线程都需要打开表），如果连接数比较大那么就加大它的值。我曾经见过设置为 100,000 的情况。</p>
<p><strong>thread_cache</strong> — 线程的创建和销毁的开销可能很大，因为每个线程的连接/断开都需要。我通常至少设置为 16。如果应用程序中有大量的跳跃并发连接并且 Threads_Created 的值也比较大，那么我就会加大它的值。它的目的是在通常的操作中无需创建新线程。</p>
<p><strong>query_cache</strong> — 如果你的应用程序有大量读，而且没有应用程序级别的缓存，那么这很有用。不要把它设置太大了，因为想要维护它也需要不少开销，这会导致MySQL变慢。通 常设置为 32-512Mb。设置完之后最好是跟踪一段时间，查看是否运行良好。在一定的负载压力下，如果缓存命中率太低了，就启用它。</p>
<p><strong>sort_buffer_size</strong> –如果你只有一些简单的查询，那么就无需增加它的值了，尽管你有 64GB 的内存。搞不好也许会降低性能。
<div>
<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/2.5/cn/"><img alt="知识共享许可协议" style="border-width:0" src="http://i.creativecommons.org/l/by-nc-sa/2.5/cn/88x31.png" /></a><br />本<span xmlns:dct="http://purl.org/dc/terms/" href="http://purl.org/dc/dcmitype/Text" rel="dct:type">作品</span>采用<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/2.5/cn/">知识共享署名-非商业性使用-相同方式共享 2.5 中国大陆许可协议</a>进行许可。
</div>
<div>原创文章,转载请注明：转载自<a href="http://www.aoqb.com/">秃驴&#039;s 网志</a><br />
本文地址：<a href="http://www.aoqb.com/index.php/archives/123">针对MySQL的高并发优化(MyISAM/InnoDB)</a>
</div>
<p><!-- PHP 5.x --></p>
]]></content:encoded>
			<wfw:commentRss>http://www.aoqb.com/index.php/archives/123/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Google将整合Google+数据重启实时搜索</title>
		<link>http://www.aoqb.com/index.php/archives/118</link>
		<comments>http://www.aoqb.com/index.php/archives/118#comments</comments>
		<pubDate>Thu, 04 Aug 2011 10:51:17 +0000</pubDate>
		<dc:creator>秃驴</dc:creator>
				<category><![CDATA[其他]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[实时搜索]]></category>

		<guid isPermaLink="false">http://www.aoqb.com/?p=118</guid>
		<description><![CDATA[8月4日消息，据国外媒体报道，Google将重启实时搜索，并在尝试把Google+和其他来源的数据加到实时搜索中去。

谷歌此前推出的实时搜索使用户可以查到Twitter, Facebook和FriendFeed等社交网站即时更新的信息。7月，谷歌公司曾暂时关停了实时搜索服务，称“关停的原因是与Twitter的协议于7月2日到期”，有分析称关停是因为要把谷歌新推出的社交工具Google+整合到实时搜索中。

而Google+的强势增长劲头和实时搜索的重启表明谷歌或许已经不再需要借助Twitter的数据来提供有吸引力的实时搜索服务。

<span class="readmore"><a href="http://www.aoqb.com/index.php/archives/118" title="Google将整合Google+数据重启实时搜索">阅读全文——共263字</a></span>]]></description>
			<content:encoded><![CDATA[<p>    8月4日消息，据国外媒体报道，Google将重启实时搜索，并在尝试把Google+和其他来源的数据加到实时搜索中去。<br />
谷歌此前推出的实时搜索使用户可以查到Twitter, Facebook和FriendFeed等社交网站即时更新的信息。7月，谷歌公司曾暂时关停了实时搜索服务，称“关停的原因是与Twitter的协议于7月2日到期”，有分析称关停是因为要把谷歌新推出的社交工具Google+整合到实时搜索中。<br />
而Google+的强势增长劲头和实时搜索的重启表明谷歌或许已经不再需要借助Twitter的数据来提供有吸引力的实时搜索服务。
<div>
<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/2.5/cn/"><img alt="知识共享许可协议" style="border-width:0" src="http://i.creativecommons.org/l/by-nc-sa/2.5/cn/88x31.png" /></a><br />本<span xmlns:dct="http://purl.org/dc/terms/" href="http://purl.org/dc/dcmitype/Text" rel="dct:type">作品</span>采用<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/2.5/cn/">知识共享署名-非商业性使用-相同方式共享 2.5 中国大陆许可协议</a>进行许可。
</div>
<div>原创文章,转载请注明：转载自<a href="http://www.aoqb.com/">秃驴&#039;s 网志</a><br />
本文地址：<a href="http://www.aoqb.com/index.php/archives/118">Google将整合Google+数据重启实时搜索</a>
</div>
<p><!-- PHP 5.x --></p>
]]></content:encoded>
			<wfw:commentRss>http://www.aoqb.com/index.php/archives/118/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Attribute于.NET的重要性</title>
		<link>http://www.aoqb.com/index.php/archives/119</link>
		<comments>http://www.aoqb.com/index.php/archives/119#comments</comments>
		<pubDate>Sat, 30 Jul 2011 15:07:19 +0000</pubDate>
		<dc:creator>秃驴</dc:creator>
				<category><![CDATA[技术]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[Attribute]]></category>

		<guid isPermaLink="false">http://www.aoqb.com/?p=119</guid>
		<description><![CDATA[作为一个.NET开发人员，懂Attribute重要性，用.NET大师Jeffrey Richter的话就是“任何.NET Framework 开发人员都有必要对定制attribute有一个牢靠的掌握”，所以掌握Attitude，这是必须的！　什么是Attribute（特性）？和Property（属性）是什么区别？

　我们先来看看MSDN中对特性的描述：

Attribute 类将预定义的系统信息或用户定义的自定义信息与目标元素相关联。 目标元素可以是程序集、类、构造函数、委托、枚举、事件、字段、接口、方法、可移植可执行文件模块、参数、属性、返回值、结构或其他特性。特性在您编译代码时被发送到元数据中，并可通过运行时反射服务用于公共语言运行时以及任何自定义工具或应用程序。通俗地理解可以这么表述：你可以通过Attribute将一些额外信息加在一些目标元素上（类，字段，接口等），程序编译的时候就将这些额外的信息序列化程序集的元数据中，当你运行程序的时候可以通过反射技术从程序集元数据中读取这些额外信息，并根据这些额外信息决定你程序的行为。

<span class="readmore"><a href="http://www.aoqb.com/index.php/archives/119" title="Attribute于.NET的重要性">阅读全文——共7309字</a></span>]]></description>
			<content:encoded><![CDATA[<p>作为一个.NET开发人员，懂Attribute重要性，用.NET大师Jeffrey Richter的话就是“<strong>任何.NET Framework 开发人员都有必要对定制attribute有一个牢靠的掌握</strong>”，所以掌握Attitude，这是必须的！　<strong>什么是Attribute（特性）？和Property（属性）是什么区别？<br />
</strong>　我们先来看看MSDN中对特性的描述：</p>
<p>Attribute 类将预定义的系统信息或用户定义的自定义信息与目标元素相关联。 目标元素可以是程序集、类、构造函数、委托、枚举、事件、字段、接口、方法、可移植可执行文件模块、参数、属性、返回值、结构或其他特性。特性在您编译代码时被发送到元数据中，并可通过运行时反射服务用于公共语言运行时以及任何自定义工具或应用程序。通俗地理解可以这么表述：你可以通过Attribute将一些额外信息加在一些目标元素上（类，字段，接口等），程序编译的时候就将这些额外的信息序列化程序集的元数据中，当你运行程序的时候可以通过反射技术从程序集元数据中读取这些额外信息，并根据这些额外信息决定你程序的行为。</p>
<p>Attribute和Property有什么区别？其实这个问题是针对中文背景的开发者而言的，因为很多中文译本把Attribute和Property都翻译成属性，在这里为了区分，我们把Attribute翻译为特性，Attribute和Property基本没有什么瓜葛，因为它们是.NET中不同层面的东西，Property就是我们再熟悉不过的定义在类中的属性，它属于面向对象理论范畴，而Attribute是编程语言文法层面的东西，其定义在上面一段已经描述。</p>
<p><strong>你使用过.NET定义好的Attribute吗？</strong></p>
<p>在.NET的基础类库中提供了很多定制好的Attribute供开发人员使用，这些定制的Attribute目的的方便开发者在代码中表达他们的意图。如下面三个Attribute类都是C#编译器能够理解的特性类：</p>
<p>Obsolete：这个属性用来标记不再使用的程序实体（如类或方法），每次使用标记为过时的实体时，会设设定此特性的方法，产生警告或错误。</p>
<p>Conditional：该特性可以标示出某种环境设置下某个方法是否应该被调用。</p>
<p>Serializable：指示一个类可以序列化。</p>
<p>下面以Obsolete特性的使用为例，说明Attribute是如何应用它的目标元素的。</p>
<div>
<div>namespace AttributeDemo<br />
{<br />
class Program<br />
{<br />
static void Main(string[] args)<br />
{<br />
MyClass myclass = new MyClass();<br />
myclass.OldMethod();<br />
Console.ReadKey();<br />
}<br />
}</p>
<p>public class MyClass<br />
{<br />
[Obsolete("这是一个旧的方法，请调用新的方法NewMethod")]<br />
public void OldMethod()<br />
{<br />
Console.WriteLine(“这是旧方法”);<br />
}</p>
<p>public void NewMethod()<br />
{<br />
Console.WriteLine(“这是新方法”);<br />
}<br />
}<br />
}</p></div>
</div>
<p>&nbsp;</p>
<p>调试这段程序的时候会发出警告信息，如下图所示：</p>
<p><img src="http://images.cnblogs.com/cnblogs_com/zoupeiyang/jgao.JPG" alt="" width="321" height="147" border="0" /></p>
<p>像Obsolete这样的定制特性，编译器能够做出相应处理，如在使用标记了Obsolete特性的方法时会发出警告信息，但如果我们自己定制的Attribute时，编译器会做什么处理呢。下面我们自己定义一个Attribute。</p>
<p><strong>我也来定义一个Attribute</strong></p>
<p>为了符合“公共语言规范”（CLS），定制Attribute必须直接或间接从公共抽象类System.Attribute派生。所以我们前面提到Obsolete、Conditional和Serializable都是派生于Attribute。这里需要说明下的是自定制的Attribute的命名规范，其规则是“特性名+Attribute”，也就是我们自定制必须以Attribute为后缀，那么我们上面提到的三个特性都没有Attribute为后缀的呢，原来定义它们的时候都是有Attribute后缀的，如Obsolete是ObsoleteAttribute，只是我们将一个特性应用于某个目标元素时可以将Attribute这个后缀去掉，因为编译器会先查找没有Attribute后缀的特性，如果没有找到，则会查找加了Attribute后缀的特性名称。</p>
<p>System.Attribute类的构造器被protected修饰，说明它不能自己实例化，只能被它的派生类调用。它有三个重要的静态方法，如下：</p>
<table width="80%" border="1" align="center">
<tbody>
<tr bgcolor="gray">
<td>方法名称</td>
<td>说明</td>
</tr>
<tr>
<td>GetCustomAttributes</td>
<td>有多个重载，返回作用于目标的Attribute类实例的数组，也就是返回的类型是Attribute[]</td>
</tr>
<tr>
<td>GetCustomAttribute</td>
<td>有多个重载，返回作用于目标的Attribute类的一个实例，如果目标没有应用任何的Attribute则返回null，如果目标应用了指定的Attribute的多个实例，就抛出一个System.Reflection.AmbiguousMatchException异常。</td>
</tr>
<tr>
<td>IsDefined</td>
<td>如果至少有一个指定的Attribute派生类实例作用于目标，就返回true，否则返回false。这个方法效率很高，因为它不构建Attribute的实例，前面的两个方法返回都是Attribute实例，也就是需要从元数据中获取信息来构建实例，耗费性能多</td>
</tr>
</tbody>
</table>
<p>通常检查一个目标元素是否被应用了某个Attribute时，就调用System.Attribute.IsDefined方法，因为它的性能比GetCustomAttributes和GetCustomAttribute要高，如果需要返回Attribute的实例，则调用GetCustomAttributes或GetCustomAttribute方法。调用这三个方法都会扫描托管模块的元数据（因为Attribute是在编译的时候保存在托管模块的元数据上的），执行字符串比较来定义指定的Attribute类。这样的操作对时间性能消耗大，如果需要反复调用这些方法，可以缓存这些方法的调用结果，也就是把实例保存在全局变量中，不需要每次都扫描和构造实例。</p>
<p>除了System.Attribute类提供的上面的三个静态方法可以检查目标元素应用Attribute的情况外，System.Reflection命名空间定义的一些类也允许你检查一个模块的元数据的内容，这些类包括Assembly，Module，ParameterInfo，MemberInfo，Type，MethodInfo，ConstrucorInfo，FieldInfo，EventInfo，PropertyInfo等，它们都提供了GetCustomAttributes和IsDefined方法。这些类GetCustomAttributes返回的类型是Object[],而System.Attribute类GetCustomAttributes方法返回的类型是Attribute[]。</p>
<p>下面将分别使用System.Attribute和System.Reflection.Type各自提供的GetCustomAttributes方法获取Attribute实例提供示例代码，以让您有一个更加直观的认识。</p>
<p>定义一个Attribute</p>
<div>
<div>public class MyMsgAttribute:Attribute<br />
{<br />
public string Msg { get; set; }<br />
public MyMsgAttribute(string msg)<br />
{<br />
Msg = msg;<br />
}<br />
}</div>
</div>
<p>定义一个类，使自定制的MyMsgAttribute类能够应用在这个类上，如下：</p>
<div>
<div> [MyMsgAttribute("我的自定义Attribute")]<br />
public class MyClass<br />
{</p>
<p>}</p></div>
</div>
<p>使用System.Reflection.Type提供的GetCustomAttributes方法获取MyMsgAttribute类的实例，代码如下：</p>
<div>
<div> var attributes = typeof(MyClass).GetCustomAttributes(typeof(MyMsgAttribute), true);<br />
MyMsgAttribute myAttribute = attributes[0] as MyMsgAttribute;<br />
if (myAttribute != null)<br />
{<br />
Console.WriteLine(myAttribute.Msg);<br />
}</div>
</div>
<p>使用System.Attribute提供的GetCustomAttributes方法获取MyMsgAttribute类的实例，代码如下：</p>
<div>
<div> var attributes2 = Attribute.GetCustomAttributes(typeof(MyClass));<br />
MyMsgAttribute myAttribute2 = (MyMsgAttribute)attributes2[0];<br />
Console.WriteLine(myAttribute2.Msg);</div>
</div>
<p>上面两段代码输出的结果都是Msg是属性值——“我的自定义Attribute”。</p>
<p>经过上面两段代码的分析，我们已经知道自定义一个Attribute类，并使这个Attribute应用在一个类上，同时在了解了在运行时如何从元数据构造这个Attribute的实例，我们得到Attribute对象，就可以根据这个对象的信息来执行一些逻辑分支代码，上面只是简单地输出Attribute对象Msg属性值，可见，定制Attribute是非常有用的，因为它能在运行时决定我们执行不同的逻辑分支代码。如我们可以通过IsDefined检查一个类是否应用了SerializableAttribute，从而判断这个类是否可以用于系列化操作。这里需要提醒的是，在自定制的Attribute中一般只有属性和字段成员，不会定义方法。</p>
<p>在我们使用Attribute应用于目标元素的时候，我们会发现一个想象，就是有些Attribute可以应用于类，也可以应用于属性，如SerializableAttribute，而有些Attribute只能应用于方法这个目标元素，如ConditionalAttribute，为什么不同的Attribute会有这种应用目标元素的区别呢？我们查看这两个Attribute的定义，发现它们本身应用了一个Attribute类，这个Attribute类就是AttributeUsage。因为Attribute本身就是一个类，所以它是允许应用其它Attribute类的。而AttributeUsage的目的就是限定你的Attribute 所施加的元素的类型，比如限制你的Attribute能够应用于类还是方法或者属性上。</p>
<p>AttributeUsage的构造函数有一个参数，这个参数是AttributeTargets的枚举类型。</p>
<p>AttributeTargets的枚举成员名称说明如下：<br />
All 可以对任何应用程序元素应用特性。<br />
Assembly 可以对程序集应用特性。<br />
Class 可以对类应用特性。<br />
Constructor 可以对构造函数应用特性。<br />
Delegate 可以对委托应用特性。<br />
Enum 可以对枚举应用特性。<br />
Event 可以对事件应用特性。<br />
Field 可以对字段应用特性。<br />
GenericParameter 可以对泛型参数应用特性。<br />
Interface 可以对接口应用特性。<br />
Method 可以对方法应用特性。<br />
Module 可以对模块应用特性。 注意Module 指的是可移植的可执行文件（.dll 或 .exe），而非 Visual Basic 标准模块。</p>
<p>如果你的自定制的Attribute没有显式应用AttributeUsage，编译器会自动给你加上一个默认的AttributeUsage，而这个默认的构造函数参数就是AttributeTargets.All，也就是你的这个自定制Attribute能够应用下面元素类型为Assembly | Module | Class | Struct | Enum | Constructor | Method | Property | Field | Event | Interface | Parameter | Delegate,<br />
ClassMembers = Class | Struct | Enum | Constructor | Method | Property | Field | Event | Delegate | Interface 。</p>
<p>如果你的自定制Attribute只想作用于类和方法，实例代码如下：</p>
<div>
<div> [AttributeUsage(AttributeTargets.Class|AttributeTargets.Method)]<br />
public class MyMsgAttribute:Attribute<br />
{<br />
public string Msg { get; set; }<br />
public MyMsgAttribute(string msg)<br />
{<br />
Msg = msg;<br />
}<br />
}</div>
</div>
<p>这样定义的MyMsgAttribute只能应用于类和方法，应用于其它类型的目标元素时编译的时候会报错。</p>
<p>AttributeUsage类提供了两个公共的属性，AllowMultiple和Inherited。AllowMultiple是使用允许让多个Attribute实例应用在同一个目标元素上，当我们将AttributeUsage应用于自定制Attribute时，可以指定AllowMultiple属性值为True，这样自定制的Attribute就允许将它的多个实例应用于单个目标元素，如果不将AllowMultiple显示设为True，自定制的Attribute只能向一个选定的目标元素应用一次。Inherited属性指定自定制Attribute应用于基类时，是否同时应用于派生类和重写的方法。我们用代码演示AllowMultiple和Inherited的概念：</p>
<div>
<div> [AttributeUsage(AttributeTargets.Class|AttributeTargets.Method,AllowMultiple=true,Inherited=true)]<br />
public class MyMsgAttribute:Attribute<br />
{<br />
public string Msg { get; set; }<br />
public MyMsgAttribute(string msg)<br />
{<br />
Msg = msg;<br />
}<br />
}</p>
<p>[MyMsgAttribute("我的自定义Attribute")]<br />
[MyMsgAttribute("也是你的自定义Attribute")]<br />
public class MyClass<br />
{</p>
<p>public string Name { get; set; }</p>
<p>public string GetName()<br />
{<br />
return Name;<br />
}<br />
}</p>
<p>public class YourClass : MyClass<br />
{ }<br />
static void Main(string[] args)<br />
{<br />
var attributes = typeof(MyClass).GetCustomAttributes(typeof(MyMsgAttribute), true);<br />
foreach (var attribute in attributes)<br />
{<br />
MyMsgAttribute myAttribute = attribute as MyMsgAttribute;<br />
if (myAttribute != null)<br />
{<br />
Console.WriteLine(myAttribute.Msg);<br />
}<br />
}</p>
<p>attributes = typeof(YourClass).GetCustomAttributes(typeof(MyMsgAttribute), true);<br />
foreach (var attribute in attributes)<br />
{<br />
MyMsgAttribute myAttribute = attribute as MyMsgAttribute;<br />
if (myAttribute != null)<br />
{<br />
Console.WriteLine(myAttribute.Msg);<br />
}<br />
}</p>
<p>Console.ReadKey();<br />
}</p></div>
</div>
<p>&nbsp;</p>
<p>输出的结果为：</p>
<p><img src="http://images.cnblogs.com/cnblogs_com/zoupeiyang/fff.JPG" alt="" width="250" height="93" border="0" /></p>
<p>&nbsp;</p>
<p><strong>总结</strong></p>
<p>&nbsp;</p>
<p>我们根据上面文章的分析对自定制Attribute的定义和使用进行总结：</p>
<p>1、自定制的Attribute必须派生于System.Attribute。</p>
<p>2、在自定制的Attribute应用AttributeUsageAttribute可以对自定制的Attribute进行应用目标元素、目标元素是否支持应用同一个Attribute多个实例，目标元素应用的Attribute是否能应用于的派生类和派生类的重写方法等进行控制。</p>
<p>3、自定制的Attribute是在编译时保存在模块的元数据上的，在运行时从元数据读取信息来构建Attribute实例。</p>
<p>4、获取或判断某个目标元素应用Attribute的信息，可以通过System.Attribute提供的三个镜头方法：System.Attribute.IsDefined,</p>
<p>System.Attribute.GetCustomAttributes和System.Attribute.GetCustomAttribute，也可以通过System.Reflection命名空间定义的一些类来检查一个模块的元数据的内容，这些类包括Assembly，Module，ParameterInfo，MemberInfo，Type，MethodInfo，ConstrucorInfo，FieldInfo，EventInfo，PropertyInfo等，它们都提供了GetCustomAttributes和IsDefined方法。</p>
<p>&nbsp;</p>
<p>参考资料:</p>
<p>Jeffrey Richter CLR Via C#</p>
<p>微软 MSDN
<div>
<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/2.5/cn/"><img alt="知识共享许可协议" style="border-width:0" src="http://i.creativecommons.org/l/by-nc-sa/2.5/cn/88x31.png" /></a><br />本<span xmlns:dct="http://purl.org/dc/terms/" href="http://purl.org/dc/dcmitype/Text" rel="dct:type">作品</span>采用<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/2.5/cn/">知识共享署名-非商业性使用-相同方式共享 2.5 中国大陆许可协议</a>进行许可。
</div>
<div>原创文章,转载请注明：转载自<a href="http://www.aoqb.com/">秃驴&#039;s 网志</a><br />
本文地址：<a href="http://www.aoqb.com/index.php/archives/119">Attribute于.NET的重要性</a>
</div>
<p><!-- PHP 5.x --></p>
]]></content:encoded>
			<wfw:commentRss>http://www.aoqb.com/index.php/archives/119/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>中石化真恐怖</title>
		<link>http://www.aoqb.com/index.php/archives/116</link>
		<comments>http://www.aoqb.com/index.php/archives/116#comments</comments>
		<pubDate>Tue, 26 Jul 2011 16:36:54 +0000</pubDate>
		<dc:creator>秃驴</dc:creator>
				<category><![CDATA[其他]]></category>

		<guid isPermaLink="false">http://www.aoqb.com/?p=116</guid>
		<description><![CDATA[如题，无他。



本作品采用知识共享署名-非商业性使用-相同方式共享 2.5 中国大陆许可协议进行许可。

<span class="readmore"><a href="http://www.aoqb.com/index.php/archives/116" title="中石化真恐怖">阅读全文——共6字</a></span>]]></description>
			<content:encoded><![CDATA[<p>如题，无他。
<div>
<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/2.5/cn/"><img alt="知识共享许可协议" style="border-width:0" src="http://i.creativecommons.org/l/by-nc-sa/2.5/cn/88x31.png" /></a><br />本<span xmlns:dct="http://purl.org/dc/terms/" href="http://purl.org/dc/dcmitype/Text" rel="dct:type">作品</span>采用<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/2.5/cn/">知识共享署名-非商业性使用-相同方式共享 2.5 中国大陆许可协议</a>进行许可。
</div>
<div>原创文章,转载请注明：转载自<a href="http://www.aoqb.com/">秃驴&#039;s 网志</a><br />
本文地址：<a href="http://www.aoqb.com/index.php/archives/116">中石化真恐怖</a>
</div>
<p><!-- PHP 5.x --></p>
]]></content:encoded>
			<wfw:commentRss>http://www.aoqb.com/index.php/archives/116/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>6to4和ISATAP隧道的关系和区别(IPV6系列文章)</title>
		<link>http://www.aoqb.com/index.php/archives/114</link>
		<comments>http://www.aoqb.com/index.php/archives/114#comments</comments>
		<pubDate>Sat, 23 Jul 2011 13:08:12 +0000</pubDate>
		<dc:creator>秃驴</dc:creator>
				<category><![CDATA[其他]]></category>
		<category><![CDATA[6to4]]></category>
		<category><![CDATA[IPV6]]></category>
		<category><![CDATA[ISATAP]]></category>

		<guid isPermaLink="false">http://www.aoqb.com/?p=114</guid>
		<description><![CDATA[ISATAP和6to4都是目前比较流行的自动建立隧道的过渡技术，都可以连接被IPv4隔绝的IPv6孤岛，都是通过将IPv4地址嵌入到IPv6地址当中，并将IPv6封包封装在IPv4中传送，在主机相互通信中抽出IPv4地址建立tunnel。但具体实现的流程，IPv6地址和应用范围不尽相同。

　　ISATAP(draft-ietf-ngtrans-isatap-23.txt) 的全名是 Intra-Site Automatic Tunnel Addressing Protocol，它将IPv4地址夹入IPv6地址中，当两台 ISATAP 主机通讯时，可自动抽取出 IPv4 地址建立 Tunnel 即可通讯，且并不需透过其它特殊网络设备，只要彼此间IPv4网络通畅即可。

<span class="readmore"><a href="http://www.aoqb.com/index.php/archives/114" title="6to4和ISATAP隧道的关系和区别(IPV6系列文章)">阅读全文——共2903字</a></span>]]></description>
			<content:encoded><![CDATA[<p>ISATAP和6to4都是目前比较流行的自动建立隧道的过渡技术，都可以连接被IPv4隔绝的IPv6孤岛，都是通过将IPv4地址嵌入到IPv6地址当中，并将IPv6封包封装在IPv4中传送，在主机相互通信中抽出IPv4地址建立tunnel。但具体实现的流程，IPv6地址和应用范围不尽相同。<br />
　　ISATAP(draft-ietf-ngtrans-isatap-23.txt) 的全名是 Intra-Site Automatic Tunnel Addressing Protocol，它将IPv4地址夹入IPv6地址中，当两台 ISATAP 主机通讯时，可自动抽取出 IPv4 地址建立 Tunnel 即可通讯，且并不需透过其它特殊网络设备，只要彼此间IPv4网络通畅即可。<br />
　　双栈主机支持isatap后会自动在该隧道接口上生成本地链路的前缀(fe80::开头)和64位的接口标识符::0:5EFE:X.X.X.X(这里的X.X.X.X是双栈主机的IPv4单播地址)，这样就可以和同一子网内其他isatap客户机进行ipv6通讯了；如果需要和其他网络的isatap客户机或者IPv6网络通信，必须通过ISATAP路由器拿到全球单播地址前缀(2001:, 2002:, 3ffe:开头)，通过路由器与其他IPv6主机和网络通信。<br />
　　ISATAP过渡技术不要求隧道端节点必须具有全球惟一的IPv4地址，只要双栈主机具有IPv4单播地址即可，不管该地址公有的还是私有的都可以。<br />
　　6to4(RFC3056)机制被定义在站点之间进行IPv6通讯，每个站点必须至少有一台“6to4”路由器作为出入口，使用特需的地址格式，地址前缀为(2002:开头)，并将路由器的IPv4地址夹入IPv6地址中，因此位于不同6to4 site内的主机彼此通讯时即可自动抽出IPv4地址在路由器之间建立Tunnel。<br />
　　透过6to4 router，不同6to4 site内的主机可互相通讯，当需与一般IPv6主机通讯时，则必须过6to4 relay router。6to4 relay router必须同时具备6to4及IPv6接口，同时提供这些接口的封包转送。<br />
　　6to4需要一个全球合法的IPv4地址，所以对解决IPv4地址短缺没有太大帮助。但它不需要申请IPv6地址，通过它可使站点迅速升级到IPv6。<br />
本文来自：ISATAP和6to4都是目前比较流行的自动建立隧道的过渡技术，都可以连接被IPv4隔绝的IPv6孤岛，都是通过将IPv4地址嵌入到IPv6地址当中，并将IPv6封包封装在IPv4中传送，在主机相互通信中抽出IPv4地址建立tunnel。但具体实现的流程，IPv6地址和应用范围不尽相同。<br />
　　ISATAP(draft-ietf-ngtrans-isatap-23.txt) 的全名是 Intra-Site Automatic Tunnel Addressing Protocol，它将IPv4地址夹入IPv6地址中，当两台 ISATAP 主机通讯时，可自动抽取出 IPv4 地址建立 Tunnel 即可通讯，且并不需透过其它特殊网络设备，只要彼此间IPv4网络通畅即可。<br />
　　双栈主机支持isatap后会自动在该隧道接口上生成本地链路的前缀(fe80::开头)和64位的接口标识符::0:5EFE:X.X.X.X(这里的X.X.X.X是双栈主机的IPv4单播地址)，这样就可以和同一子网内其他isatap客户机进行ipv6通讯了；如果需要和其他网络的isatap客户机或者IPv6网络通信，必须通过ISATAP路由器拿到全球单播地址前缀(2001:, 2002:, 3ffe:开头)，通过路由器与其他IPv6主机和网络通信。<br />
　　ISATAP过渡技术不要求隧道端节点必须具有全球惟一的IPv4地址，只要双栈主机具有IPv4单播地址即可，不管该地址公有的还是私有的都可以。<br />
　　6to4(RFC3056)机制被定义在站点之间进行IPv6通讯，每个站点必须至少有一台“6to4”路由器作为出入口，使用特需的地址格式，地址前缀为(2002:开头)，并将路由器的IPv4地址夹入IPv6地址中，因此位于不同6to4 site内的主机彼此通讯时即可自动抽出IPv4地址在路由器之间建立Tunnel。<br />
　　透过6to4 router，不同6to4 site内的主机可互相通讯，当需与一般IPv6主机通讯时，则必须过6to4 relay router。6to4 relay router必须同时具备6to4及IPv6接口，同时提供这些接口的封包转送。<br />
　　6to4需要一个全球合法的IPv4地址，所以对解决IPv4地址短缺没有太大帮助。但它不需要申请IPv6地址，通过它可使站点迅速升级到IPv6。<br />
ISATAP和6to4都是目前比较流行的自动建立隧道的过渡技术，都可以连接被IPv4隔绝的IPv6孤岛，都是通过将IPv4地址嵌入到IPv6地址当中，并将IPv6封包封装在IPv4中传送，在主机相互通信中抽出IPv4地址建立tunnel。但具体实现的流程，IPv6地址和应用范围不尽相同。<br />
　　ISATAP(draft-ietf-ngtrans-isatap-23.txt) 的全名是 Intra-Site Automatic Tunnel Addressing Protocol，它将IPv4地址夹入IPv6地址中，当两台 ISATAP 主机通讯时，可自动抽取出 IPv4 地址建立 Tunnel 即可通讯，且并不需透过其它特殊网络设备，只要彼此间IPv4网络通畅即可。<br />
　　双栈主机支持isatap后会自动在该隧道接口上生成本地链路的前缀(fe80::开头)和64位的接口标识符::0:5EFE:X.X.X.X(这里的X.X.X.X是双栈主机的IPv4单播地址)，这样就可以和同一子网内其他isatap客户机进行ipv6通讯了；如果需要和其他网络的isatap客户机或者IPv6网络通信，必须通过ISATAP路由器拿到全球单播地址前缀(2001:, 2002:, 3ffe:开头)，通过路由器与其他IPv6主机和网络通信。<br />
　　ISATAP过渡技术不要求隧道端节点必须具有全球惟一的IPv4地址，只要双栈主机具有IPv4单播地址即可，不管该地址公有的还是私有的都可以。<br />
　　6to4(RFC3056)机制被定义在站点之间进行IPv6通讯，每个站点必须至少有一台“6to4”路由器作为出入口，使用特需的地址格式，地址前缀为(2002:开头)，并将路由器的IPv4地址夹入IPv6地址中，因此位于不同6to4 site内的主机彼此通讯时即可自动抽出IPv4地址在路由器之间建立Tunnel。<br />
　　透过6to4 router，不同6to4 site内的主机可互相通讯，当需与一般IPv6主机通讯时，则必须过6to4 relay router。6to4 relay router必须同时具备6to4及IPv6接口，同时提供这些接口的封包转送。<br />
　　6to4需要一个全球合法的IPv4地址，所以对解决IPv4地址短缺没有太大帮助。但它不需要申请IPv6地址，通过它可使站点迅速升级到IPv6。
<div>
<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/2.5/cn/"><img alt="知识共享许可协议" style="border-width:0" src="http://i.creativecommons.org/l/by-nc-sa/2.5/cn/88x31.png" /></a><br />本<span xmlns:dct="http://purl.org/dc/terms/" href="http://purl.org/dc/dcmitype/Text" rel="dct:type">作品</span>采用<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/2.5/cn/">知识共享署名-非商业性使用-相同方式共享 2.5 中国大陆许可协议</a>进行许可。
</div>
<div>原创文章,转载请注明：转载自<a href="http://www.aoqb.com/">秃驴&#039;s 网志</a><br />
本文地址：<a href="http://www.aoqb.com/index.php/archives/114">6to4和ISATAP隧道的关系和区别(IPV6系列文章)</a>
</div>
<p><!-- PHP 5.x --></p>
]]></content:encoded>
			<wfw:commentRss>http://www.aoqb.com/index.php/archives/114/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>用户在Facebook上因为投放Google+广告而被封</title>
		<link>http://www.aoqb.com/index.php/archives/112</link>
		<comments>http://www.aoqb.com/index.php/archives/112#comments</comments>
		<pubDate>Sun, 17 Jul 2011 15:28:44 +0000</pubDate>
		<dc:creator>秃驴</dc:creator>
				<category><![CDATA[其他]]></category>
		<category><![CDATA[Facebook]]></category>
		<category><![CDATA[Google]]></category>

		<guid isPermaLink="false">http://www.aoqb.com/?p=112</guid>
		<description><![CDATA[Google+上在发生什么，就让它停留在Google+上，至少Facebook是这样想的。

然而Web开发者Michael Lee Johnson却付出了很大代价才知道Facebook是这样想的。他在Facebook上投放了一个广告，让人们去Google+上圈他，很明显FB不喜欢他通过Facebook来建立另一个社交网络上的关系。所以FB禁止了他的广告。

Michael在Google+上说：

<span class="readmore"><a href="http://www.aoqb.com/index.php/archives/112" title="用户在Facebook上因为投放Google+广告而被封">阅读全文——共345字</a></span>]]></description>
			<content:encoded><![CDATA[<p>Google+上在发生什么，就让它停留在Google+上，至少Facebook是这样想的。</p>
<p>然而Web开发者Michael Lee Johnson却付出了很大代价才知道Facebook是这样想的。他在Facebook上投放了一个广告，让人们去Google+上圈他，很明显FB不喜欢他通过Facebook来建立另一个社交网络上的关系。所以FB禁止了他的广告。</p>
<p>Michael在Google+上说：</p>
<blockquote><p>　　我最近在Facebook上放了一个Google+的广告，导致我所有的广告都被封了，很好。</p></blockquote>
<p>是的，Facebook不同意人们在自己的网站上放竞争对手的广告，甚至已经写进了用户条款中。</p>
<p>很庆幸这是只用户的个人行为，但也说明了，除了Facebook，你还去哪拉朋友上Google+呢？</p>
<p>来源：<a href="http://techcrunch.com/2011/07/15/google-ad-on-facebook-is-banned/">TechCrunch</a><br />
<img src="http://pic003.cnblogs.com/2011/66372/201107/2011071720452856.jpg" alt="" />
<div>
<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/2.5/cn/"><img alt="知识共享许可协议" style="border-width:0" src="http://i.creativecommons.org/l/by-nc-sa/2.5/cn/88x31.png" /></a><br />本<span xmlns:dct="http://purl.org/dc/terms/" href="http://purl.org/dc/dcmitype/Text" rel="dct:type">作品</span>采用<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/2.5/cn/">知识共享署名-非商业性使用-相同方式共享 2.5 中国大陆许可协议</a>进行许可。
</div>
<div>原创文章,转载请注明：转载自<a href="http://www.aoqb.com/">秃驴&#039;s 网志</a><br />
本文地址：<a href="http://www.aoqb.com/index.php/archives/112">用户在Facebook上因为投放Google+广告而被封</a>
</div>
<p><!-- PHP 5.x --></p>
]]></content:encoded>
			<wfw:commentRss>http://www.aoqb.com/index.php/archives/112/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

