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

<channel>
	<title>猪在笑</title>
	<atom:link href="http://www.huangwei.me/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.huangwei.me/blog</link>
	<description>暇时吃紧，忙里偷闲</description>
	<lastBuildDate>Wed, 21 Mar 2012 09:06:07 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>2011&#8243;微”总结</title>
		<link>http://www.huangwei.me/blog/2012/01/01/2011_wei_review/</link>
		<comments>http://www.huangwei.me/blog/2012/01/01/2011_wei_review/#comments</comments>
		<pubDate>Sat, 31 Dec 2011 16:00:08 +0000</pubDate>
		<dc:creator>c4pr1c3</dc:creator>
				<category><![CDATA[纯净水]]></category>
		<category><![CDATA[总结]]></category>

		<guid isPermaLink="false">http://www.huangwei.me/blog/?p=1079</guid>
		<description><![CDATA[忙忙碌碌的2011马上就要过去了，往年都是早早的写好年终总结等着年底发布，今年最后两个小时了，终于可以开始动手写总结了。

先点开<a href="http://www.huangwei.me/blog/2010/12/30/2010_review/" target="_blank">2010年B总结</a>回顾一下，去年此时给今年定下的主题词<span style="font-size: medium"><strong>发展</strong></span>在今年一年得到了非常彻底的贯彻和执行。2010年的那些未刷完的进度条，在2011年得到了大幅度的增长刷新。很开心，很欣慰！

2011年围脖织得多了，博客写得少了。以至于写不到140字就习惯性的来个EOF，切换到下一条思路。。。

好吧，还有1个小时了，不写文字细节了，用一组数据来做一个2011"微"总结吧。
<h2>1. 事业</h2>
从2011年初的第一个6000元合同项目，1个人做开始，一步一个台阶，五位数，六位数，七位数。我们一路走了上来！

从2011年初的2个学生开始，脚踏实地的团队建设+1次机会，我们做到了30+的硕士/博士和4名社招员工！

从2011年初借实验室工位开始，5月借助一个项目的机会和学院领导的支持，拥有了一个独立的校内实验室；8月在另一所学校附近开辟了一个新的空间；12月在CBD卫城，第1个社会化"战场"就位。

2011年能够实现<a href="http://www.huangwei.me/blog/2009/12/31/2009%E5%B9%B4a%E6%80%BB%E7%BB%93%E5%92%8C2010%E5%B9%B4b%E8%AE%A1%E5%88%92/" target="_blank">2009年的B计划</a>，必须要感谢所有帮助过我的人，感恩所有给予我机会的人，感激团队里共同努力和奋斗的每一员：老师、学生和同事！
<h2>2. 个人</h2>
"做自己喜欢的事情，做自己擅长的事情"，前者培养了自己的兴趣和做事的内在动力，让自己快乐！后者通过不断成事激励自己，增强自信。幸运的是，我同时做到了两者。

教书育人，传道授业，我所乐也！

敲敲代码，写写文档，亦我所乐也！

暇时8卦一下安全圈的那点娱乐事，捣鼓一下vim/mac/perl，玩玩PoC，忙时潜水、织围脖。

最后贴一下2011年最后3个月的工作日历表，3个月一共休息了15天。其中，11月休息了2天，12月休息了3天。

写到这里，2012已经来了，新的一年里我希望自己能够做到：坚持！
<a href="http://www.huangwei.me/blog/wp-content/uploads/2011/12/屏幕快照-2011-12-31-下午10.18.34.png"><img class="alignnone size-full wp-image-1080" src="http://www.huangwei.me/blog/wp-content/uploads/2011/12/屏幕快照-2011-12-31-下午10.18.34.png" alt="" width="156" height="418" /></a>]]></description>
			<content:encoded><![CDATA[<div style="margin-top: 2px;">
<A href="http://creativecommons.org/licenses/by/3.0/deed.zh"><FONT color=#11779f><STRONG>版权声明</STRONG></FONT></A><FONT color=#11779f><STRONG>：可以任意转载，转载时请务必以超链接形式标明文章原始出处和<a href="http://www.huangwei.me/blog/">作者信息</a></STRONG></FONT>
</div>
<p>忙忙碌碌的2011马上就要过去了，往年都是早早的写好年终总结等着年底发布，今年最后两个小时了，终于可以开始动手写总结了。</p>
<p>先点开<a href="http://www.huangwei.me/blog/2010/12/30/2010_review/" target="_blank">2010年B总结</a>回顾一下，去年此时给今年定下的主题词<span style="font-size: medium"><strong>发展</strong></span>在今年一年得到了非常彻底的贯彻和执行。2010年的那些未刷完的进度条，在2011年得到了大幅度的增长刷新。很开心，很欣慰！</p>
<p>2011年围脖织得多了，博客写得少了。以至于写不到140字就习惯性的来个EOF，切换到下一条思路。。。</p>
<p>好吧，还有1个小时了，不写文字细节了，用一组数据来做一个2011&#8243;微”总结吧。</p>
<h2>1. 事业</h2>
<p>从2011年初的第一个6000元合同项目，1个人做开始，一步一个台阶，五位数，六位数，七位数。我们一路走了上来！</p>
<p>从2011年初的2个学生开始，脚踏实地的团队建设+1次机会，我们做到了30+的硕士/博士和4名社招员工！</p>
<p>从2011年初借实验室工位开始，5月借助一个项目的机会和学院领导的支持，拥有了一个独立的校内实验室；8月在另一所学校附近开辟了一个新的空间；12月在CBD卫城，第1个社会化”战场”就位。</p>
<p>2011年能够实现<a href="http://www.huangwei.me/blog/2009/12/31/2009%E5%B9%B4a%E6%80%BB%E7%BB%93%E5%92%8C2010%E5%B9%B4b%E8%AE%A1%E5%88%92/" target="_blank">2009年的B计划</a>，必须要感谢所有帮助过我的人，感恩所有给予我机会的人，感激团队里共同努力和奋斗的每一员：老师、学生和同事！</p>
<h2>2. 个人</h2>
<p>“做自己喜欢的事情，做自己擅长的事情”，前者培养了自己的兴趣和做事的内在动力，让自己快乐！后者通过不断成事激励自己，增强自信。幸运的是，我同时做到了两者。</p>
<p>教书育人，传道授业，我所乐也！</p>
<p>敲敲代码，写写文档，亦我所乐也！</p>
<p>暇时8卦一下安全圈的那点娱乐事，捣鼓一下vim/mac/perl，玩玩PoC，忙时潜水、织围脖。</p>
<p>最后贴一下2011年最后3个月的工作日历表，3个月一共休息了15天。其中，11月休息了2天，12月休息了3天。</p>
<p>写到这里，2012已经来了，新的一年里我希望自己能够做到：坚持！<br />
<a href="http://www.huangwei.me/blog/wp-content/uploads/2011/12/屏幕快照-2011-12-31-下午10.18.34.png"><img class="alignnone size-full wp-image-1080" src="http://www.huangwei.me/blog/wp-content/uploads/2011/12/屏幕快照-2011-12-31-下午10.18.34.png" alt="" width="156" height="418" /></a>
<div style="margin-top: 15px; ">
<hr style="border: 1px solid #cccccc;"/>
<p><strong>原创文章，转载请注明：</strong> 转载自<a href="http://www.huangwei.me/blog/">猪在笑</a> <a href="http://www.huangwei.me/blog/">[ http://www.huangwei.me/blog/ ]</a><br/><strong>本文链接地址:</strong> <a href="http://www.huangwei.me/blog/2012/01/01/2011_wei_review/">http://www.huangwei.me/blog/2012/01/01/2011_wei_review/</a></p>
<hr style="border: 1px solid #cccccc;"/>
</div>
<div  class="related_post_title">您可能还对以下文章感兴趣</div><ul class="related_post"><li><a href="http://www.huangwei.me/blog/2010/12/30/2010_review/" title="2010年B总结">2010年B总结</a></li><li><a href="http://www.huangwei.me/blog/2010/08/09/2010-8-8/" title="log@2010.8.8 Lunar 6.28">log@2010.8.8 Lunar 6.28</a></li><li><a href="http://www.huangwei.me/blog/2010/07/01/thanks-to-friends/" title="毕业了，感谢我的好友们">毕业了，感谢我的好友们</a></li><li><a href="http://www.huangwei.me/blog/2010/06/30/thanks-to-tutors/" title="毕业了，感谢我的老师们">毕业了，感谢我的老师们</a></li><li><a href="http://www.huangwei.me/blog/2010/06/29/thanks-to-elder/" title="毕业了，感谢我的师兄师姐们">毕业了，感谢我的师兄师姐们</a></li><li><a href="http://www.huangwei.me/blog/2010/06/28/thanks-to-the-young/" title="毕业了，感谢我的师弟师妹们">毕业了，感谢我的师弟师妹们</a></li><li><a href="http://www.huangwei.me/blog/2010/06/09/nothing-but-bull-shit/" title="胡思乱想一篇">胡思乱想一篇</a></li><li><a href="http://www.huangwei.me/blog/2009/12/31/2009%e5%b9%b4a%e6%80%bb%e7%bb%93%e5%92%8c2010%e5%b9%b4b%e8%ae%a1%e5%88%92/" title="2009年A总结和2010年B计划">2009年A总结和2010年B计划</a></li><li><a href="http://www.huangwei.me/blog/2008/12/29/%e6%80%bb%e7%bb%932008/" title="总结2008">总结2008</a></li><li><a href="http://www.huangwei.me/blog/2007/12/31/ua2007-2/" title="总结2007">总结2007</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.huangwei.me/blog/2012/01/01/2011_wei_review/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>关于”灵创众和”</title>
		<link>http://www.huangwei.me/blog/2011/10/25/about_cleaderwin/</link>
		<comments>http://www.huangwei.me/blog/2011/10/25/about_cleaderwin/#comments</comments>
		<pubDate>Tue, 25 Oct 2011 09:22:13 +0000</pubDate>
		<dc:creator>c4pr1c3</dc:creator>
				<category><![CDATA[纯净水]]></category>
		<category><![CDATA[cleaderwin]]></category>
		<category><![CDATA[灵创众和]]></category>

		<guid isPermaLink="false">http://www.huangwei.me/blog/?p=1060</guid>
		<description><![CDATA[“灵创团队”是杨义先教授和钮心忻教授领导的由一批志同道合的教育家、科学家、企业家和自由职业者等组成的专注于教育、科研、成果转化和企业孵化的跨机构集体。<a href="http://www.cleaderwin.com" target="_blank">北京灵创众和科技有限公司</a>的创始人均博士毕业于灵创团队，我们对团队多年的培养心怀感恩，“灵创众和”脱胎于灵创团队实至名归。

“众”，顾名思义，三人成“众”，后指代“大家”，“许多人”的意思。2008年的北京奥运会开幕式上，“和”字的演变展示了中国自古以来一直追求的以和为贵，和谐和平的敦厚理论。甚至有人说，把中国五千年的文化用一个字表达的话，这个“和”字也许是再理想不过的选择。“众和”既表达了我们追求和谐、和平、和善、和气生财的理念，更重要的是要把“众和”理念作为公司发展的文化基石。

<span style="font-size: large">我们渴望“<strong>一唱百和</strong>”的发展目标，努力构建“<strong>和而不同</strong>”的团队，保持“<strong>心平气和</strong>”的行事作风，致力于创造“<strong>一团和气</strong>”的公司内外部发展环境。</span>
<h2>1. 一唱百和</h2>
1953年哈佛大学曾经做过这样一个关于目标对人生结果影响的调查，一群智力、学历、环境、条件都相差无几的学生在走出校门之前，哈佛大学对他们进行了一次关于人生目标的调查。25年后，哈佛大学再次对这群学生进行了跟踪调查，结果是这样的：
<table>
<tbody>
<tr>
<td>25年前</td>
<td>25年后</td>
</tr>
<tr>
<td>3%有清晰而且长远的目标的人</td>
<td>一直朝着同一个方向努力，成为社会各界的顶尖成功人士，他们不乏白手创业者、行业领袖、社会精英</td>
</tr>
<tr>
<td>10%有清晰但比较短期的目标的人</td>
<td>他们生活在社会的上层，他们的短期目标不断达成，成为行业专业人士，有很好的工作，比如医生、律师、公司高级管理人员等</td>
</tr>
<tr>
<td>60%目标模糊的人</td>
<td>他们生活在社会的中层或下层，尽管能够安稳地生活，但是没有取得什么成绩。</td>
</tr>
<tr>
<td>27%没有目标的人</td>
<td>他们生活在社会底层，生活得十分不如意，不断抱怨社会和他人，经常失业，家庭也不幸福。</td>
</tr>
</tbody>
</table>
从这个调查结果，我们可以看到设定一个清晰的奋斗目标，在个人成功的道路上所起到的重要作用。而目标明确之所以可以让人受益并助力获得成功，主要原因在于明确的目标带给人清晰的方向感，使人充分了解到自己每个行为的目的，并能够及时的将行为的结果和自己的目标进行比对，不断检讨和修正自己的行为。让人能够从忙乱中转移到自己的工作重点上，关注自己的行为结果，产生持久的动力，激发出人的潜能。对于团队来说，就是要将个人目标融入到团队目标中，个人目标统一于团队目标，达到“一唱百和”。

21世纪的前10年，我们经历了跌宕起伏、精彩不断、惊喜不停的互联网十年，这个期间诞生了一系列伟大的互联网公司：Google、阿里巴巴、百度、腾讯、新浪、网易等等。任何一个伟大的公司的开始，都离不开那一群默默无闻的创业者。Google的2位大神，百度七剑客，阿里巴巴十八罗汉，他们的共同点是什么？是的，高校基因！Larry Page和Sergey Brin均博士毕业于斯坦福大学，百度七剑客分别来自北大、清华、北邮等国内知名高校，阿里巴巴十八罗汉的领头人马云创办阿里巴巴之前是高校英语教师。

我们认为21世纪的下一个10年，移动互联网必将掀起一波又一波的“技术改变生活”的热潮。我们正在做的事情，和移动互联网紧密相关，解决最广大用户的最迫切需求是我们创业项目的出发点。

我们的项目已经得到了一些有识之士的资金投入认可！亲，如果你认同我们的背景，认可我们对大势的判断，自认英雄尚无用武之地，那你还在犹豫什么，赶快<a href="http://www.cleaderwin.com/" target="_blank">联系加入我们</a>吧。
<h2>2. 和而不同</h2>
现代社会已经不再是个人英雄唱主角就能够主导竞争，并获得最后成功的时代了。越来越多矢志于成功的人士开始意识到团队在一个人成功的道路上所扮演的重要角色，凝聚力、团队精神得到了成功人士的普遍关注。拳头攥紧的力量之所以比一个巴掌的力量大得多，就是因为手上的全部力量都被凝聚到了拳心。“一个好汉三个帮，一个篱笆三个桩”说的也是同样的道理，都是在强调团队内部的凝聚力、团结对成功的重要影响。经常有人说，要想走的快，就一个人走；要想走的远，就一起走。

足球之所以能够成为世界第一体育运动，是因为有两个看似矛盾因素的支撑：团队配合和个人发挥。一方面，一支常胜的球队必然有着一个稳固的球队组成和统一的战术打法；另一方面，一支获胜的球队必然离不开获胜功臣的发挥。一支获胜的球队之所以能够成为一个常胜的球队，就是因为在多数场次的比赛中总能涌现出一个又一个的获胜功臣。在球场下，一个优秀球员的伤病和退役，会有一大批新的优秀球员崭露头角。在球场上，每一个球员都能坚定、统一的贯彻执行教练的技战术部署。就一场比赛而言，前锋射门得分固然是球队获胜的必要条件，但离开了防守队员的坚守城池，球队同样无法获得最终的比赛胜利。就一个赛季的联赛而言，战胜强队的比赛虽然可以鼓舞士气，但不能全力以赴的对待每一个对手、每一场比赛，球队同样无法加冕最终的冠军。

因此，一个优秀的团队必须是一个由“持有相同价值观、怀有共同目标、具有互补技能的人”所组成，所谓“和而不同”。在优秀团队中工作的成员是幸福的：相同的价值观是幸福的基础，共同目标是幸福的前提，互补技能是幸福的动力。而一个成功的团队必须是一个长期努力，坚持不懈的优秀团队。每一个团队成员为了共同目标的全力以赴，才是获得幸福的保障。
<h2>3. 心平气和</h2>
每个人都渴望成功，每个人都在乎成功。每个人都想取得一些成果，并且觉得自己的投入就应该获得这些的成果。罗贯中的《三国演义》一书中，诸葛亮设计上方谷火烧司马懿，可谓机关算尽，司马懿父子也已经是束手待毙，但怎料天降大雨救了司马懿父子。孔明最后也只得叹曰：“谋事在人，成事在天。不可强也！”。所以，与其投资于结果，我们不如投资于过程。不要只盯着结果，结果只应该是个指路灯，指引我们的正确方向，而我们应该心平气和、全力专注于整个过程。如果成功了，那很好，如果我们没有成功，仍然不坏，因为现在我们有了一个全新的起始模式。这样，我们才能感受到每天都是一种赐予。这个过程就像初学走路的婴儿，不管跌倒多少次，最终它能够自己走路而再也不会跌倒。如果母亲在最初只是不断专注于婴儿走路的结果，而不是这个充满跌倒的过程，婴儿最终是学不会走路的。
<h2>4. 一团和气</h2>
“是金子总会发光的，但金子本身是不能发光的。”不论是一个成功的个人，还是一个成功的团队，都离不开它所处的环境。我们无需讨论“环境决定论”或“机遇决定论”的对与错，至少谁也无法否认“环境”和“机遇”在成功的道路上所起到的关键作用。不管是决定性因素也好，催化剂作用也罢。一个好的环境，一次难得的机遇对于一个人，一个团队的成长一定是起到正面和积极作用的。假如没有机遇，纵使你有才华也得不到展现抱负的机会和舞台。常言道，成功者和失败者的区别就在于能否捉住机遇。所谓正人适时而动，英雄应运而生；快跑未必能赢，力战未必得胜。一个糟糕的大环境下，虽然也会“乱世出英雄”，但必定道路曲折。

人的成功不能只为自己一个人，要为身边的人谋福利，求改善，有帮助。公司的成功也是相同的，饮水思源，知恩图报。行业发展的大环境好了，个体公司才能从大环境中获得更多的机遇，得到更好的发展。只有一团和气的成功，才是有生命力的成功。]]></description>
			<content:encoded><![CDATA[<div style="margin-top: 2px;">
<A href="http://creativecommons.org/licenses/by/3.0/deed.zh"><FONT color=#11779f><STRONG>版权声明</STRONG></FONT></A><FONT color=#11779f><STRONG>：可以任意转载，转载时请务必以超链接形式标明文章原始出处和<a href="http://www.huangwei.me/blog/">作者信息</a></STRONG></FONT>
</div>
<p>“灵创团队”是杨义先教授和钮心忻教授领导的由一批志同道合的教育家、科学家、企业家和自由职业者等组成的专注于教育、科研、成果转化和企业孵化的跨机构集体。<a href="http://www.cleaderwin.com" target="_blank">北京灵创众和科技有限公司</a>的创始人均博士毕业于灵创团队，我们对团队多年的培养心怀感恩，“灵创众和”脱胎于灵创团队实至名归。</p>
<p>“众”，顾名思义，三人成“众”，后指代“大家”，“许多人”的意思。2008年的北京奥运会开幕式上，“和”字的演变展示了中国自古以来一直追求的以和为贵，和谐和平的敦厚理论。甚至有人说，把中国五千年的文化用一个字表达的话，这个“和”字也许是再理想不过的选择。“众和”既表达了我们追求和谐、和平、和善、和气生财的理念，更重要的是要把“众和”理念作为公司发展的文化基石。</p>
<p><span style="font-size: large">我们渴望“<strong>一唱百和</strong>”的发展目标，努力构建“<strong>和而不同</strong>”的团队，保持“<strong>心平气和</strong>”的行事作风，致力于创造“<strong>一团和气</strong>”的公司内外部发展环境。</span></p>
<h2>1. 一唱百和</h2>
<p>1953年哈佛大学曾经做过这样一个关于目标对人生结果影响的调查，一群智力、学历、环境、条件都相差无几的学生在走出校门之前，哈佛大学对他们进行了一次关于人生目标的调查。25年后，哈佛大学再次对这群学生进行了跟踪调查，结果是这样的：</p>
<table>
<tbody>
<tr>
<td>25年前</td>
<td>25年后</td>
</tr>
<tr>
<td>3%有清晰而且长远的目标的人</td>
<td>一直朝着同一个方向努力，成为社会各界的顶尖成功人士，他们不乏白手创业者、行业领袖、社会精英</td>
</tr>
<tr>
<td>10%有清晰但比较短期的目标的人</td>
<td>他们生活在社会的上层，他们的短期目标不断达成，成为行业专业人士，有很好的工作，比如医生、律师、公司高级管理人员等</td>
</tr>
<tr>
<td>60%目标模糊的人</td>
<td>他们生活在社会的中层或下层，尽管能够安稳地生活，但是没有取得什么成绩。</td>
</tr>
<tr>
<td>27%没有目标的人</td>
<td>他们生活在社会底层，生活得十分不如意，不断抱怨社会和他人，经常失业，家庭也不幸福。</td>
</tr>
</tbody>
</table>
<p>从这个调查结果，我们可以看到设定一个清晰的奋斗目标，在个人成功的道路上所起到的重要作用。而目标明确之所以可以让人受益并助力获得成功，主要原因在于明确的目标带给人清晰的方向感，使人充分了解到自己每个行为的目的，并能够及时的将行为的结果和自己的目标进行比对，不断检讨和修正自己的行为。让人能够从忙乱中转移到自己的工作重点上，关注自己的行为结果，产生持久的动力，激发出人的潜能。对于团队来说，就是要将个人目标融入到团队目标中，个人目标统一于团队目标，达到“一唱百和”。</p>
<p>21世纪的前10年，我们经历了跌宕起伏、精彩不断、惊喜不停的互联网十年，这个期间诞生了一系列伟大的互联网公司：Google、阿里巴巴、百度、腾讯、新浪、网易等等。任何一个伟大的公司的开始，都离不开那一群默默无闻的创业者。Google的2位大神，百度七剑客，阿里巴巴十八罗汉，他们的共同点是什么？是的，高校基因！Larry Page和Sergey Brin均博士毕业于斯坦福大学，百度七剑客分别来自北大、清华、北邮等国内知名高校，阿里巴巴十八罗汉的领头人马云创办阿里巴巴之前是高校英语教师。</p>
<p>我们认为21世纪的下一个10年，移动互联网必将掀起一波又一波的“技术改变生活”的热潮。我们正在做的事情，和移动互联网紧密相关，解决最广大用户的最迫切需求是我们创业项目的出发点。</p>
<p>我们的项目已经得到了一些有识之士的资金投入认可！亲，如果你认同我们的背景，认可我们对大势的判断，自认英雄尚无用武之地，那你还在犹豫什么，赶快<a href="http://www.cleaderwin.com/" target="_blank">联系加入我们</a>吧。</p>
<h2>2. 和而不同</h2>
<p>现代社会已经不再是个人英雄唱主角就能够主导竞争，并获得最后成功的时代了。越来越多矢志于成功的人士开始意识到团队在一个人成功的道路上所扮演的重要角色，凝聚力、团队精神得到了成功人士的普遍关注。拳头攥紧的力量之所以比一个巴掌的力量大得多，就是因为手上的全部力量都被凝聚到了拳心。“一个好汉三个帮，一个篱笆三个桩”说的也是同样的道理，都是在强调团队内部的凝聚力、团结对成功的重要影响。经常有人说，要想走的快，就一个人走；要想走的远，就一起走。</p>
<p>足球之所以能够成为世界第一体育运动，是因为有两个看似矛盾因素的支撑：团队配合和个人发挥。一方面，一支常胜的球队必然有着一个稳固的球队组成和统一的战术打法；另一方面，一支获胜的球队必然离不开获胜功臣的发挥。一支获胜的球队之所以能够成为一个常胜的球队，就是因为在多数场次的比赛中总能涌现出一个又一个的获胜功臣。在球场下，一个优秀球员的伤病和退役，会有一大批新的优秀球员崭露头角。在球场上，每一个球员都能坚定、统一的贯彻执行教练的技战术部署。就一场比赛而言，前锋射门得分固然是球队获胜的必要条件，但离开了防守队员的坚守城池，球队同样无法获得最终的比赛胜利。就一个赛季的联赛而言，战胜强队的比赛虽然可以鼓舞士气，但不能全力以赴的对待每一个对手、每一场比赛，球队同样无法加冕最终的冠军。</p>
<p>因此，一个优秀的团队必须是一个由“持有相同价值观、怀有共同目标、具有互补技能的人”所组成，所谓“和而不同”。在优秀团队中工作的成员是幸福的：相同的价值观是幸福的基础，共同目标是幸福的前提，互补技能是幸福的动力。而一个成功的团队必须是一个长期努力，坚持不懈的优秀团队。每一个团队成员为了共同目标的全力以赴，才是获得幸福的保障。</p>
<h2>3. 心平气和</h2>
<p>每个人都渴望成功，每个人都在乎成功。每个人都想取得一些成果，并且觉得自己的投入就应该获得这些的成果。罗贯中的《三国演义》一书中，诸葛亮设计上方谷火烧司马懿，可谓机关算尽，司马懿父子也已经是束手待毙，但怎料天降大雨救了司马懿父子。孔明最后也只得叹曰：“谋事在人，成事在天。不可强也！”。所以，与其投资于结果，我们不如投资于过程。不要只盯着结果，结果只应该是个指路灯，指引我们的正确方向，而我们应该心平气和、全力专注于整个过程。如果成功了，那很好，如果我们没有成功，仍然不坏，因为现在我们有了一个全新的起始模式。这样，我们才能感受到每天都是一种赐予。这个过程就像初学走路的婴儿，不管跌倒多少次，最终它能够自己走路而再也不会跌倒。如果母亲在最初只是不断专注于婴儿走路的结果，而不是这个充满跌倒的过程，婴儿最终是学不会走路的。</p>
<h2>4. 一团和气</h2>
<p>“是金子总会发光的，但金子本身是不能发光的。”不论是一个成功的个人，还是一个成功的团队，都离不开它所处的环境。我们无需讨论“环境决定论”或“机遇决定论”的对与错，至少谁也无法否认“环境”和“机遇”在成功的道路上所起到的关键作用。不管是决定性因素也好，催化剂作用也罢。一个好的环境，一次难得的机遇对于一个人，一个团队的成长一定是起到正面和积极作用的。假如没有机遇，纵使你有才华也得不到展现抱负的机会和舞台。常言道，成功者和失败者的区别就在于能否捉住机遇。所谓正人适时而动，英雄应运而生；快跑未必能赢，力战未必得胜。一个糟糕的大环境下，虽然也会“乱世出英雄”，但必定道路曲折。</p>
<p>人的成功不能只为自己一个人，要为身边的人谋福利，求改善，有帮助。公司的成功也是相同的，饮水思源，知恩图报。行业发展的大环境好了，个体公司才能从大环境中获得更多的机遇，得到更好的发展。只有一团和气的成功，才是有生命力的成功。
<div style="margin-top: 15px; ">
<hr style="border: 1px solid #cccccc;"/>
<p><strong>原创文章，转载请注明：</strong> 转载自<a href="http://www.huangwei.me/blog/">猪在笑</a> <a href="http://www.huangwei.me/blog/">[ http://www.huangwei.me/blog/ ]</a><br/><strong>本文链接地址:</strong> <a href="http://www.huangwei.me/blog/2011/10/25/about_cleaderwin/">http://www.huangwei.me/blog/2011/10/25/about_cleaderwin/</a></p>
<hr style="border: 1px solid #cccccc;"/>
</div>
<div  class="related_post_title">随机日志</div><ul class="related_post"><li><a href="http://www.huangwei.me/blog/2009/09/02/%e6%8e%a8%e8%8d%90%e5%9f%ba%e4%ba%8ewindbg%e7%9a%84%e4%b8%80%e4%b8%aa%e6%bc%8f%e6%b4%9e%e5%8f%af%e5%88%a9%e7%94%a8%e6%80%a7%e5%88%86%e6%9e%90%e6%8f%92%e4%bb%b6/" title="[推荐]基于Windbg的一个漏洞可利用性分析插件">[推荐]基于Windbg的一个漏洞可利用性分析插件</a></li><li><a href="http://www.huangwei.me/blog/2010/08/02/ssh-security-harden/" title="SSH安全加固一二三">SSH安全加固一二三</a></li><li><a href="http://www.huangwei.me/blog/2011/08/17/lsof-and-fuser/" title="分享1个Linux命令lsof">分享1个Linux命令lsof</a></li><li><a href="http://www.huangwei.me/blog/2009/07/29/%e5%bd%93nmap%e9%81%87%e5%88%b0ipod-touch/" title="当Nmap遇到ipod touch?">当Nmap遇到ipod touch?</a></li><li><a href="http://www.huangwei.me/blog/2007/05/28/zzooodhauaoiye-2/" title="zz一种新的带宽攻击方式">zz一种新的带宽攻击方式</a></li><li><a href="http://www.huangwei.me/blog/2010/12/03/js-interview-test/" title="4道js面试题">4道js面试题</a></li><li><a href="http://www.huangwei.me/blog/2006/11/30/oiiaiaiouacaiut_t-2/" title="一次聪明反被聪明误的注册表操作T_T">一次聪明反被聪明误的注册表操作T_T</a></li><li><a href="http://www.huangwei.me/blog/2009/07/19/%e6%8e%a8%e8%8d%90%e4%b8%80%e4%b8%aa%e5%9c%a8%e7%ba%bf%e5%a4%87%e4%bb%bd%e5%92%8c%e6%96%87%e4%bb%b6%e5%90%8c%e6%ad%a5%e7%9a%84%e7%bd%91%e7%ab%99/" title="[推荐]一个在线备份和文件同步的网站">[推荐]一个在线备份和文件同步的网站</a></li><li><a href="http://www.huangwei.me/blog/2006/10/20/ouaeonunloadeatheuu-2/" title="[源代码]onunload事件实践">[源代码]onunload事件实践</a></li><li><a href="http://www.huangwei.me/blog/2010/04/07/web-app-tools/" title="推荐几个好玩且实用的Web App Tools">推荐几个好玩且实用的Web App Tools</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.huangwei.me/blog/2011/10/25/about_cleaderwin/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>分享1个Linux命令lsof</title>
		<link>http://www.huangwei.me/blog/2011/08/17/lsof-and-fuser/</link>
		<comments>http://www.huangwei.me/blog/2011/08/17/lsof-and-fuser/#comments</comments>
		<pubDate>Wed, 17 Aug 2011 05:06:09 +0000</pubDate>
		<dc:creator>c4pr1c3</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[安全技术]]></category>

		<guid isPermaLink="false">http://www.huangwei.me/blog/?p=444</guid>
		<description><![CDATA[今天微博上看到一篇文章，叫做《<a href="http://linuxtoy.org/archives/10-linux-commands-youve-never-used.html" target="_blank">你从未用过的 10 条 Linux 命令？</a>》，原文也不长，转过来也不费事。

== 以下内容是转载，版权归原作者所有 ==
这 10 条 Linux 命令依次是：

pgrep：比如，你可以使用 pgrep -u root 来代替 ps -ef &#124; egrep '^root ' &#124; awk '{print $2}'，以便抓取属于 root 的 PID。

pstree：我觉得这个命令很酷，它可以直接列出进程树，或者换句话说是按照树状结构来列出进程。

bc：这个命令在我的系统中没有找到，可能需要安装。这是用来执行计算的一个命令，如使用它来开平方根。

split：这是一个很有用的命令，它可以将一个大文件分割成几个小的部分。比如：split -b 2m largefile LF_ 会将 largefile 分割成带有 LF 文件名前缀且大小为 2 MB 的小文件。

nl：能够显示行号的命令。在阅读脚本或代码时，这个命令应该非常有用。如：nl wireless.h &#124; head。
mkfifo：作者说这是他最喜欢的命令。该命令使得其他命令能够通过一个命名的管道进行通信。嗯，听起来有点空洞。举例说明，先创建一个管道并写入内容： mkfifo ive-been-piped ls -al split/* &#124; head > ive-been-piped

然后就可以读取了：head ive-been-piped。

ldd：其作用是输出指定文件依赖的动态链接库。比如，通过 ldd /usr/java/jre1.5.0_11/bin/java 可以了解哪些线程库链接到了 java 依赖（动态链接）了哪些库。（感谢 NetSnail 的指正。）

col：可以将 man 手册页保存为无格式的文本文件。如： PAGER=cat man less &#124; col -b > less.txt

xmlwf：能够检测 XML 文档是否良好。比如： curl -s 'http://bashcurescancer.com' > bcc.html xmlwf bcc.html perl -i -pe 's@
@
@g' bcc.html xmlwf bcc.html bcc.html:104:2: mismatched tag

lsof：列出打开的文件。如：通过 lsof &#124; grep TCP 可以找到打开的端口。

== 以上内容是转载，版权归原作者所有 ==

关于lsof，网管员应该了解以下这个用法：
# 显示当前SSH的连接用户和源IP地址
<pre lang="bash" escaped="true">$ sudo lsof -n &#124; grep sshd &#124; grep TCP &#124; cut -c18-28,70-
root  TCP *:22 (LISTEN)
root  TCP *:22 (LISTEN)
root  TCP 1.2.3.4:22->6.7.8.9:2544 (ESTABLISHED)
huangwei  TCP 1.2.3.4:22->6.7.8.9:2544 (ESTABLISHED)
root  TCP 1.2.3.4:22->6.7.8.9:29340 (ESTABLISHED)
huangwei  TCP 1.2.3.4:22->6.7.8.9:29340 (ESTABLISHED)
root  TCP 1.2.3.4:22->6.7.8.9:33223 (ESTABLISHED)
huangwei  TCP 1.2.3.4:22->6.7.8.9:33223 (ESTABLISHED)
huangwei  TCP [::1]:cisco-sccp (LISTEN)
huangwei  TCP 127.0.0.1:cisco-sccp (LISTEN)
huangwei  TCP 1.2.3.4:40183->74.125.227.8:https (ESTABLISHED)
root  TCP 1.2.3.4:22->6.7.8.9:43698 (ESTABLISHED)
huangwei  TCP 1.2.3.4:22->6.7.8.9:43698 (ESTABLISHED)
root  TCP 1.2.3.4:22->6.7.8.9:44943 (ESTABLISHED)
huangwei  TCP 1.2.3.4:22->6.7.8.9:44943 (ESTABLISHED)
huangwei  TCP 1.2.3.4:38038->74.125.227.20:www (ESTABLISHED)</pre>
看看是谁在大量并发连接呢？

DDoS？网站管理员的噩梦！一条"简单"命令就能找出script kids？看过来：
<pre lang="bash" escaped="true">$ sudo netstat -anp &#124;grep 'tcp\&#124;udp' &#124; awk '{print $5}' &#124; cut -d: -f1 &#124; sort &#124; uniq -c &#124; sort -nr
      8 192.168.0.218
      7 192.168.0.38
      6 192.168.0.14
      6 0.0.0.0
      2 192.168.0.166
      2 192.168.0.110
      2 192.168.0.10
      1 192.168.232.223
      1 192.168.0.70
      1 192.168.0.6
      1 192.168.0.50
      1 192.168.0.22
      1 192.168.0.210
      1 192.168.0.194</pre>
看看现在服务器打开了多少端口？看过来：
<pre lang="bash" escaped="true">$ sudo lsof -i
COMMAND    PID     USER   FD   TYPE  DEVICE SIZE/OFF NODE NAME
mysqld    1190    mysql   10u  IPv4    5022      0t0  TCP localhost:mysql (LISTEN)
apache2   1347     root    3u  IPv4    5327      0t0  TCP *:www (LISTEN)
svnserve  1759      svn    3u  IPv4    6612      0t0  TCP ooxx-vpn:svn (LISTEN)
sshd      2583     root    3r  IPv4 1194924      0t0  TCP 192.168.1.176:8822->192.168.2.223:40876 (ESTABLISHED)
sshd      2651 huangwei    3u  IPv4 1194924      0t0  TCP 192.168.1.176:8822->192.168.2.223:40876 (ESTABLISHED)
apache2   2714 www-data    3u  IPv4    5327      0t0  TCP *:www (LISTEN)
apache2   2715 www-data    3u  IPv4    5327      0t0  TCP *:www (LISTEN)
apache2   2722 www-data    3u  IPv4    5327      0t0  TCP *:www (LISTEN)
apache2   2722 www-data   11u  IPv4 1198941      0t0  TCP ooxx-vpn:www->192.168.0.50:4068 (ESTABLISHED)
apache2   2723 www-data    3u  IPv4    5327      0t0  TCP *:www (LISTEN)
apache2   2725 www-data    3u  IPv4    5327      0t0  TCP *:www (LISTEN)
apache2   2725 www-data   11u  IPv4 1198939      0t0  TCP ooxx-vpn:www->192.168.0.194:15397 (ESTABLISHED)
apache2   2734 www-data    3u  IPv4    5327      0t0  TCP *:www (LISTEN)
apache2   2809 www-data    3u  IPv4    5327      0t0  TCP *:www (LISTEN)
apache2   2809 www-data   11u  IPv4 1198940      0t0  TCP ooxx-vpn:www->192.168.0.218:1521 (ESTABLISHED)
apache2   2810 www-data    3u  IPv4    5327      0t0  TCP *:www (LISTEN)
apache2   2811 www-data    3u  IPv4    5327      0t0  TCP *:www (LISTEN)
apache2   2818 www-data    3u  IPv4    5327      0t0  TCP *:www (LISTEN)
apache2   2819 www-data    3u  IPv4    5327      0t0  TCP *:www (LISTEN)
apache2   2845 www-data    3u  IPv4    5327      0t0  TCP *:www (LISTEN)
apache2   2845 www-data   11u  IPv4 1198938      0t0  TCP ooxx-vpn:www->192.168.0.14:36802 (ESTABLISHED)
proftpd   7191      ftp    0u  IPv4   29954      0t0  TCP ooxx-vpn:ftp (LISTEN)
sshd      9720     root    3u  IPv4   47070      0t0  TCP *:8822 (LISTEN)
sshd      9720     root    4u  IPv6   47072      0t0  TCP *:8822 (LISTEN)
svnserve 11217      svn    4u  IPv4 1019658      0t0  TCP ooxx-vpn:svn->192.168.0.166:6211 (ESTABLISHED)
svnserve 11350      svn    4u  IPv4 1020389      0t0  TCP ooxx-vpn:svn->192.168.0.166:6286 (ESTABLISHED)
svnserve 12706      svn    4u  IPv4  627093      0t0  TCP ooxx-vpn:svn->192.168.0.22:1084 (ESTABLISHED)

</pre>

看看本机上所有占用 TCP 80端口的应用程序
<pre lang="bash" escaped="true">$ sudo lsof -i tcp:80</pre>
样例输出如下：
<pre lang="bash" escaped="true">
COMMAND   PID     USER   FD   TYPE  DEVICE SIZE/OFF NODE NAME
apache2  2827 www-data    3u  IPv4 1609898      0t0  TCP *:www (LISTEN)
apache2  2827 www-data   11u  IPv4 2026780      0t0  TCP ooxx-vpn:www->192.168.0.22:14949 (ESTABLISHED)
apache2  2875 www-data    3u  IPv4 1609898      0t0  TCP *:www (LISTEN)
apache2  2919 www-data    3u  IPv4 1609898      0t0  TCP *:www (LISTEN)
apache2  2920 www-data    3u  IPv4 1609898      0t0  TCP *:www (LISTEN)
apache2  2921 www-data    3u  IPv4 1609898      0t0  TCP *:www (LISTEN)
apache2  2924 www-data    3u  IPv4 1609898      0t0  TCP *:www (LISTEN)
apache2  2926 www-data    3u  IPv4 1609898      0t0  TCP *:www (LISTEN)
apache2  2928 www-data    3u  IPv4 1609898      0t0  TCP *:www (LISTEN)
apache2  2930 www-data    3u  IPv4 1609898      0t0  TCP *:www (LISTEN)
apache2  2932 www-data    3u  IPv4 1609898      0t0  TCP *:www (LISTEN)
apache2  2933 www-data    3u  IPv4 1609898      0t0  TCP *:www (LISTEN)
apache2 26081     root    3u  IPv4 1609898      0t0  TCP *:www (LISTEN)
</pre>]]></description>
			<content:encoded><![CDATA[<div style="margin-top: 2px;">
<A href="http://creativecommons.org/licenses/by/3.0/deed.zh"><FONT color=#11779f><STRONG>版权声明</STRONG></FONT></A><FONT color=#11779f><STRONG>：可以任意转载，转载时请务必以超链接形式标明文章原始出处和<a href="http://www.huangwei.me/blog/">作者信息</a></STRONG></FONT>
</div>
<p>今天微博上看到一篇文章，叫做《<a href="http://linuxtoy.org/archives/10-linux-commands-youve-never-used.html" target="_blank">你从未用过的 10 条 Linux 命令？</a>》，原文也不长，转过来也不费事。</p>
<p>== 以下内容是转载，版权归原作者所有 ==<br />
这 10 条 Linux 命令依次是：</p>
<p>pgrep：比如，你可以使用 pgrep -u root 来代替 ps -ef | egrep &#8216;^root &#8216; | awk &#8216;{print $2}&#8217;，以便抓取属于 root 的 PID。</p>
<p>pstree：我觉得这个命令很酷，它可以直接列出进程树，或者换句话说是按照树状结构来列出进程。</p>
<p>bc：这个命令在我的系统中没有找到，可能需要安装。这是用来执行计算的一个命令，如使用它来开平方根。</p>
<p>split：这是一个很有用的命令，它可以将一个大文件分割成几个小的部分。比如：split -b 2m largefile LF_ 会将 largefile 分割成带有 LF 文件名前缀且大小为 2 MB 的小文件。</p>
<p>nl：能够显示行号的命令。在阅读脚本或代码时，这个命令应该非常有用。如：nl wireless.h | head。<br />
mkfifo：作者说这是他最喜欢的命令。该命令使得其他命令能够通过一个命名的管道进行通信。嗯，听起来有点空洞。举例说明，先创建一个管道并写入内容： mkfifo ive-been-piped ls -al split/* | head > ive-been-piped</p>
<p>然后就可以读取了：head ive-been-piped。</p>
<p>ldd：其作用是输出指定文件依赖的动态链接库。比如，通过 ldd /usr/java/jre1.5.0_11/bin/java 可以了解哪些线程库链接到了 java 依赖（动态链接）了哪些库。（感谢 NetSnail 的指正。）</p>
<p>col：可以将 man 手册页保存为无格式的文本文件。如： PAGER=cat man less | col -b > less.txt</p>
<p>xmlwf：能够检测 XML 文档是否良好。比如： curl -s &#8216;http://bashcurescancer.com&#8217; > bcc.html xmlwf bcc.html perl -i -pe &#8216;s@<br />
@<br />
@g&#8217; bcc.html xmlwf bcc.html bcc.html:104:2: mismatched tag</p>
<p>lsof：列出打开的文件。如：通过 lsof | grep TCP 可以找到打开的端口。</p>
<p>== 以上内容是转载，版权归原作者所有 ==</p>
<p>关于lsof，网管员应该了解以下这个用法：<br />
# 显示当前SSH的连接用户和源IP地址</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">sudo</span> lsof <span style="color: #660033;">-n</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">grep</span> sshd <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">grep</span> TCP <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">cut</span> -c18-<span style="color: #000000;">28</span>,<span style="color: #000000;">70</span>-
root  TCP <span style="color: #000000; font-weight: bold;">*</span>:<span style="color: #000000;">22</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span>LISTEN<span style="color: #7a0874; font-weight: bold;">&#41;</span>
root  TCP <span style="color: #000000; font-weight: bold;">*</span>:<span style="color: #000000;">22</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span>LISTEN<span style="color: #7a0874; font-weight: bold;">&#41;</span>
root  TCP 1.2.3.4:<span style="color: #000000;">22</span>-<span style="color: #000000; font-weight: bold;">&gt;</span>6.7.8.9:<span style="color: #000000;">2544</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span>ESTABLISHED<span style="color: #7a0874; font-weight: bold;">&#41;</span>
huangwei  TCP 1.2.3.4:<span style="color: #000000;">22</span>-<span style="color: #000000; font-weight: bold;">&gt;</span>6.7.8.9:<span style="color: #000000;">2544</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span>ESTABLISHED<span style="color: #7a0874; font-weight: bold;">&#41;</span>
root  TCP 1.2.3.4:<span style="color: #000000;">22</span>-<span style="color: #000000; font-weight: bold;">&gt;</span>6.7.8.9:<span style="color: #000000;">29340</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span>ESTABLISHED<span style="color: #7a0874; font-weight: bold;">&#41;</span>
huangwei  TCP 1.2.3.4:<span style="color: #000000;">22</span>-<span style="color: #000000; font-weight: bold;">&gt;</span>6.7.8.9:<span style="color: #000000;">29340</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span>ESTABLISHED<span style="color: #7a0874; font-weight: bold;">&#41;</span>
root  TCP 1.2.3.4:<span style="color: #000000;">22</span>-<span style="color: #000000; font-weight: bold;">&gt;</span>6.7.8.9:<span style="color: #000000;">33223</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span>ESTABLISHED<span style="color: #7a0874; font-weight: bold;">&#41;</span>
huangwei  TCP 1.2.3.4:<span style="color: #000000;">22</span>-<span style="color: #000000; font-weight: bold;">&gt;</span>6.7.8.9:<span style="color: #000000;">33223</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span>ESTABLISHED<span style="color: #7a0874; font-weight: bold;">&#41;</span>
huangwei  TCP <span style="color: #7a0874; font-weight: bold;">&#91;</span>::<span style="color: #000000;">1</span><span style="color: #7a0874; font-weight: bold;">&#93;</span>:cisco-sccp <span style="color: #7a0874; font-weight: bold;">&#40;</span>LISTEN<span style="color: #7a0874; font-weight: bold;">&#41;</span>
huangwei  TCP 127.0.0.1:cisco-sccp <span style="color: #7a0874; font-weight: bold;">&#40;</span>LISTEN<span style="color: #7a0874; font-weight: bold;">&#41;</span>
huangwei  TCP 1.2.3.4:<span style="color: #000000;">40183</span>-<span style="color: #000000; font-weight: bold;">&gt;</span>74.125.227.8:https <span style="color: #7a0874; font-weight: bold;">&#40;</span>ESTABLISHED<span style="color: #7a0874; font-weight: bold;">&#41;</span>
root  TCP 1.2.3.4:<span style="color: #000000;">22</span>-<span style="color: #000000; font-weight: bold;">&gt;</span>6.7.8.9:<span style="color: #000000;">43698</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span>ESTABLISHED<span style="color: #7a0874; font-weight: bold;">&#41;</span>
huangwei  TCP 1.2.3.4:<span style="color: #000000;">22</span>-<span style="color: #000000; font-weight: bold;">&gt;</span>6.7.8.9:<span style="color: #000000;">43698</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span>ESTABLISHED<span style="color: #7a0874; font-weight: bold;">&#41;</span>
root  TCP 1.2.3.4:<span style="color: #000000;">22</span>-<span style="color: #000000; font-weight: bold;">&gt;</span>6.7.8.9:<span style="color: #000000;">44943</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span>ESTABLISHED<span style="color: #7a0874; font-weight: bold;">&#41;</span>
huangwei  TCP 1.2.3.4:<span style="color: #000000;">22</span>-<span style="color: #000000; font-weight: bold;">&gt;</span>6.7.8.9:<span style="color: #000000;">44943</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span>ESTABLISHED<span style="color: #7a0874; font-weight: bold;">&#41;</span>
huangwei  TCP 1.2.3.4:<span style="color: #000000;">38038</span>-<span style="color: #000000; font-weight: bold;">&gt;</span>74.125.227.20:www <span style="color: #7a0874; font-weight: bold;">&#40;</span>ESTABLISHED<span style="color: #7a0874; font-weight: bold;">&#41;</span></pre></div></div>

<p>看看是谁在大量并发连接呢？</p>
<p>DDoS？网站管理员的噩梦！一条”简单”命令就能找出script kids？看过来：</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">netstat</span> <span style="color: #660033;">-anp</span> <span style="color: #000000; font-weight: bold;">|</span><span style="color: #c20cb9; font-weight: bold;">grep</span> <span style="color: #ff0000;">'tcp\|udp'</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">awk</span> <span style="color: #ff0000;">'{print $5}'</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">cut</span> -d: <span style="color: #660033;">-f1</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">sort</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">uniq</span> <span style="color: #660033;">-c</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">sort</span> <span style="color: #660033;">-nr</span>
      <span style="color: #000000;">8</span> 192.168.0.218
      <span style="color: #000000;">7</span> 192.168.0.38
      <span style="color: #000000;">6</span> 192.168.0.14
      <span style="color: #000000;">6</span> 0.0.0.0
      <span style="color: #000000;">2</span> 192.168.0.166
      <span style="color: #000000;">2</span> 192.168.0.110
      <span style="color: #000000;">2</span> 192.168.0.10
      <span style="color: #000000;">1</span> 192.168.232.223
      <span style="color: #000000;">1</span> 192.168.0.70
      <span style="color: #000000;">1</span> 192.168.0.6
      <span style="color: #000000;">1</span> 192.168.0.50
      <span style="color: #000000;">1</span> 192.168.0.22
      <span style="color: #000000;">1</span> 192.168.0.210
      <span style="color: #000000;">1</span> 192.168.0.194</pre></div></div>

<p>看看现在服务器打开了多少端口？看过来：</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">sudo</span> lsof <span style="color: #660033;">-i</span>
COMMAND    PID     USER   FD   TYPE  DEVICE SIZE<span style="color: #000000; font-weight: bold;">/</span>OFF NODE NAME
mysqld    <span style="color: #000000;">1190</span>    mysql   10u  IPv4    <span style="color: #000000;">5022</span>      0t0  TCP localhost:mysql <span style="color: #7a0874; font-weight: bold;">&#40;</span>LISTEN<span style="color: #7a0874; font-weight: bold;">&#41;</span>
apache2   <span style="color: #000000;">1347</span>     root    3u  IPv4    <span style="color: #000000;">5327</span>      0t0  TCP <span style="color: #000000; font-weight: bold;">*</span>:www <span style="color: #7a0874; font-weight: bold;">&#40;</span>LISTEN<span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #c20cb9; font-weight: bold;">svnserve</span>  <span style="color: #000000;">1759</span>      <span style="color: #c20cb9; font-weight: bold;">svn</span>    3u  IPv4    <span style="color: #000000;">6612</span>      0t0  TCP ooxx-vpn:<span style="color: #c20cb9; font-weight: bold;">svn</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span>LISTEN<span style="color: #7a0874; font-weight: bold;">&#41;</span>
sshd      <span style="color: #000000;">2583</span>     root    3r  IPv4 <span style="color: #000000;">1194924</span>      0t0  TCP 192.168.1.176:<span style="color: #000000;">8822</span>-<span style="color: #000000; font-weight: bold;">&gt;</span>192.168.2.223:<span style="color: #000000;">40876</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span>ESTABLISHED<span style="color: #7a0874; font-weight: bold;">&#41;</span>
sshd      <span style="color: #000000;">2651</span> huangwei    3u  IPv4 <span style="color: #000000;">1194924</span>      0t0  TCP 192.168.1.176:<span style="color: #000000;">8822</span>-<span style="color: #000000; font-weight: bold;">&gt;</span>192.168.2.223:<span style="color: #000000;">40876</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span>ESTABLISHED<span style="color: #7a0874; font-weight: bold;">&#41;</span>
apache2   <span style="color: #000000;">2714</span> www-data    3u  IPv4    <span style="color: #000000;">5327</span>      0t0  TCP <span style="color: #000000; font-weight: bold;">*</span>:www <span style="color: #7a0874; font-weight: bold;">&#40;</span>LISTEN<span style="color: #7a0874; font-weight: bold;">&#41;</span>
apache2   <span style="color: #000000;">2715</span> www-data    3u  IPv4    <span style="color: #000000;">5327</span>      0t0  TCP <span style="color: #000000; font-weight: bold;">*</span>:www <span style="color: #7a0874; font-weight: bold;">&#40;</span>LISTEN<span style="color: #7a0874; font-weight: bold;">&#41;</span>
apache2   <span style="color: #000000;">2722</span> www-data    3u  IPv4    <span style="color: #000000;">5327</span>      0t0  TCP <span style="color: #000000; font-weight: bold;">*</span>:www <span style="color: #7a0874; font-weight: bold;">&#40;</span>LISTEN<span style="color: #7a0874; font-weight: bold;">&#41;</span>
apache2   <span style="color: #000000;">2722</span> www-data   11u  IPv4 <span style="color: #000000;">1198941</span>      0t0  TCP ooxx-vpn:www-<span style="color: #000000; font-weight: bold;">&gt;</span>192.168.0.50:<span style="color: #000000;">4068</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span>ESTABLISHED<span style="color: #7a0874; font-weight: bold;">&#41;</span>
apache2   <span style="color: #000000;">2723</span> www-data    3u  IPv4    <span style="color: #000000;">5327</span>      0t0  TCP <span style="color: #000000; font-weight: bold;">*</span>:www <span style="color: #7a0874; font-weight: bold;">&#40;</span>LISTEN<span style="color: #7a0874; font-weight: bold;">&#41;</span>
apache2   <span style="color: #000000;">2725</span> www-data    3u  IPv4    <span style="color: #000000;">5327</span>      0t0  TCP <span style="color: #000000; font-weight: bold;">*</span>:www <span style="color: #7a0874; font-weight: bold;">&#40;</span>LISTEN<span style="color: #7a0874; font-weight: bold;">&#41;</span>
apache2   <span style="color: #000000;">2725</span> www-data   11u  IPv4 <span style="color: #000000;">1198939</span>      0t0  TCP ooxx-vpn:www-<span style="color: #000000; font-weight: bold;">&gt;</span>192.168.0.194:<span style="color: #000000;">15397</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span>ESTABLISHED<span style="color: #7a0874; font-weight: bold;">&#41;</span>
apache2   <span style="color: #000000;">2734</span> www-data    3u  IPv4    <span style="color: #000000;">5327</span>      0t0  TCP <span style="color: #000000; font-weight: bold;">*</span>:www <span style="color: #7a0874; font-weight: bold;">&#40;</span>LISTEN<span style="color: #7a0874; font-weight: bold;">&#41;</span>
apache2   <span style="color: #000000;">2809</span> www-data    3u  IPv4    <span style="color: #000000;">5327</span>      0t0  TCP <span style="color: #000000; font-weight: bold;">*</span>:www <span style="color: #7a0874; font-weight: bold;">&#40;</span>LISTEN<span style="color: #7a0874; font-weight: bold;">&#41;</span>
apache2   <span style="color: #000000;">2809</span> www-data   11u  IPv4 <span style="color: #000000;">1198940</span>      0t0  TCP ooxx-vpn:www-<span style="color: #000000; font-weight: bold;">&gt;</span>192.168.0.218:<span style="color: #000000;">1521</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span>ESTABLISHED<span style="color: #7a0874; font-weight: bold;">&#41;</span>
apache2   <span style="color: #000000;">2810</span> www-data    3u  IPv4    <span style="color: #000000;">5327</span>      0t0  TCP <span style="color: #000000; font-weight: bold;">*</span>:www <span style="color: #7a0874; font-weight: bold;">&#40;</span>LISTEN<span style="color: #7a0874; font-weight: bold;">&#41;</span>
apache2   <span style="color: #000000;">2811</span> www-data    3u  IPv4    <span style="color: #000000;">5327</span>      0t0  TCP <span style="color: #000000; font-weight: bold;">*</span>:www <span style="color: #7a0874; font-weight: bold;">&#40;</span>LISTEN<span style="color: #7a0874; font-weight: bold;">&#41;</span>
apache2   <span style="color: #000000;">2818</span> www-data    3u  IPv4    <span style="color: #000000;">5327</span>      0t0  TCP <span style="color: #000000; font-weight: bold;">*</span>:www <span style="color: #7a0874; font-weight: bold;">&#40;</span>LISTEN<span style="color: #7a0874; font-weight: bold;">&#41;</span>
apache2   <span style="color: #000000;">2819</span> www-data    3u  IPv4    <span style="color: #000000;">5327</span>      0t0  TCP <span style="color: #000000; font-weight: bold;">*</span>:www <span style="color: #7a0874; font-weight: bold;">&#40;</span>LISTEN<span style="color: #7a0874; font-weight: bold;">&#41;</span>
apache2   <span style="color: #000000;">2845</span> www-data    3u  IPv4    <span style="color: #000000;">5327</span>      0t0  TCP <span style="color: #000000; font-weight: bold;">*</span>:www <span style="color: #7a0874; font-weight: bold;">&#40;</span>LISTEN<span style="color: #7a0874; font-weight: bold;">&#41;</span>
apache2   <span style="color: #000000;">2845</span> www-data   11u  IPv4 <span style="color: #000000;">1198938</span>      0t0  TCP ooxx-vpn:www-<span style="color: #000000; font-weight: bold;">&gt;</span>192.168.0.14:<span style="color: #000000;">36802</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span>ESTABLISHED<span style="color: #7a0874; font-weight: bold;">&#41;</span>
proftpd   <span style="color: #000000;">7191</span>      <span style="color: #c20cb9; font-weight: bold;">ftp</span>    0u  IPv4   <span style="color: #000000;">29954</span>      0t0  TCP ooxx-vpn:<span style="color: #c20cb9; font-weight: bold;">ftp</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span>LISTEN<span style="color: #7a0874; font-weight: bold;">&#41;</span>
sshd      <span style="color: #000000;">9720</span>     root    3u  IPv4   <span style="color: #000000;">47070</span>      0t0  TCP <span style="color: #000000; font-weight: bold;">*</span>:<span style="color: #000000;">8822</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span>LISTEN<span style="color: #7a0874; font-weight: bold;">&#41;</span>
sshd      <span style="color: #000000;">9720</span>     root    4u  IPv6   <span style="color: #000000;">47072</span>      0t0  TCP <span style="color: #000000; font-weight: bold;">*</span>:<span style="color: #000000;">8822</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span>LISTEN<span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #c20cb9; font-weight: bold;">svnserve</span> <span style="color: #000000;">11217</span>      <span style="color: #c20cb9; font-weight: bold;">svn</span>    4u  IPv4 <span style="color: #000000;">1019658</span>      0t0  TCP ooxx-vpn:svn-<span style="color: #000000; font-weight: bold;">&gt;</span>192.168.0.166:<span style="color: #000000;">6211</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span>ESTABLISHED<span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #c20cb9; font-weight: bold;">svnserve</span> <span style="color: #000000;">11350</span>      <span style="color: #c20cb9; font-weight: bold;">svn</span>    4u  IPv4 <span style="color: #000000;">1020389</span>      0t0  TCP ooxx-vpn:svn-<span style="color: #000000; font-weight: bold;">&gt;</span>192.168.0.166:<span style="color: #000000;">6286</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span>ESTABLISHED<span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #c20cb9; font-weight: bold;">svnserve</span> <span style="color: #000000;">12706</span>      <span style="color: #c20cb9; font-weight: bold;">svn</span>    4u  IPv4  <span style="color: #000000;">627093</span>      0t0  TCP ooxx-vpn:svn-<span style="color: #000000; font-weight: bold;">&gt;</span>192.168.0.22:<span style="color: #000000;">1084</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span>ESTABLISHED<span style="color: #7a0874; font-weight: bold;">&#41;</span></pre></div></div>

<p>看看本机上所有占用 TCP 80端口的应用程序</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">sudo</span> lsof <span style="color: #660033;">-i</span> tcp:<span style="color: #000000;">80</span></pre></div></div>

<p>样例输出如下：</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">COMMAND   PID     USER   FD   TYPE  DEVICE SIZE<span style="color: #000000; font-weight: bold;">/</span>OFF NODE NAME
apache2  <span style="color: #000000;">2827</span> www-data    3u  IPv4 <span style="color: #000000;">1609898</span>      0t0  TCP <span style="color: #000000; font-weight: bold;">*</span>:www <span style="color: #7a0874; font-weight: bold;">&#40;</span>LISTEN<span style="color: #7a0874; font-weight: bold;">&#41;</span>
apache2  <span style="color: #000000;">2827</span> www-data   11u  IPv4 <span style="color: #000000;">2026780</span>      0t0  TCP ooxx-vpn:www-<span style="color: #000000; font-weight: bold;">&gt;</span>192.168.0.22:<span style="color: #000000;">14949</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span>ESTABLISHED<span style="color: #7a0874; font-weight: bold;">&#41;</span>
apache2  <span style="color: #000000;">2875</span> www-data    3u  IPv4 <span style="color: #000000;">1609898</span>      0t0  TCP <span style="color: #000000; font-weight: bold;">*</span>:www <span style="color: #7a0874; font-weight: bold;">&#40;</span>LISTEN<span style="color: #7a0874; font-weight: bold;">&#41;</span>
apache2  <span style="color: #000000;">2919</span> www-data    3u  IPv4 <span style="color: #000000;">1609898</span>      0t0  TCP <span style="color: #000000; font-weight: bold;">*</span>:www <span style="color: #7a0874; font-weight: bold;">&#40;</span>LISTEN<span style="color: #7a0874; font-weight: bold;">&#41;</span>
apache2  <span style="color: #000000;">2920</span> www-data    3u  IPv4 <span style="color: #000000;">1609898</span>      0t0  TCP <span style="color: #000000; font-weight: bold;">*</span>:www <span style="color: #7a0874; font-weight: bold;">&#40;</span>LISTEN<span style="color: #7a0874; font-weight: bold;">&#41;</span>
apache2  <span style="color: #000000;">2921</span> www-data    3u  IPv4 <span style="color: #000000;">1609898</span>      0t0  TCP <span style="color: #000000; font-weight: bold;">*</span>:www <span style="color: #7a0874; font-weight: bold;">&#40;</span>LISTEN<span style="color: #7a0874; font-weight: bold;">&#41;</span>
apache2  <span style="color: #000000;">2924</span> www-data    3u  IPv4 <span style="color: #000000;">1609898</span>      0t0  TCP <span style="color: #000000; font-weight: bold;">*</span>:www <span style="color: #7a0874; font-weight: bold;">&#40;</span>LISTEN<span style="color: #7a0874; font-weight: bold;">&#41;</span>
apache2  <span style="color: #000000;">2926</span> www-data    3u  IPv4 <span style="color: #000000;">1609898</span>      0t0  TCP <span style="color: #000000; font-weight: bold;">*</span>:www <span style="color: #7a0874; font-weight: bold;">&#40;</span>LISTEN<span style="color: #7a0874; font-weight: bold;">&#41;</span>
apache2  <span style="color: #000000;">2928</span> www-data    3u  IPv4 <span style="color: #000000;">1609898</span>      0t0  TCP <span style="color: #000000; font-weight: bold;">*</span>:www <span style="color: #7a0874; font-weight: bold;">&#40;</span>LISTEN<span style="color: #7a0874; font-weight: bold;">&#41;</span>
apache2  <span style="color: #000000;">2930</span> www-data    3u  IPv4 <span style="color: #000000;">1609898</span>      0t0  TCP <span style="color: #000000; font-weight: bold;">*</span>:www <span style="color: #7a0874; font-weight: bold;">&#40;</span>LISTEN<span style="color: #7a0874; font-weight: bold;">&#41;</span>
apache2  <span style="color: #000000;">2932</span> www-data    3u  IPv4 <span style="color: #000000;">1609898</span>      0t0  TCP <span style="color: #000000; font-weight: bold;">*</span>:www <span style="color: #7a0874; font-weight: bold;">&#40;</span>LISTEN<span style="color: #7a0874; font-weight: bold;">&#41;</span>
apache2  <span style="color: #000000;">2933</span> www-data    3u  IPv4 <span style="color: #000000;">1609898</span>      0t0  TCP <span style="color: #000000; font-weight: bold;">*</span>:www <span style="color: #7a0874; font-weight: bold;">&#40;</span>LISTEN<span style="color: #7a0874; font-weight: bold;">&#41;</span>
apache2 <span style="color: #000000;">26081</span>     root    3u  IPv4 <span style="color: #000000;">1609898</span>      0t0  TCP <span style="color: #000000; font-weight: bold;">*</span>:www <span style="color: #7a0874; font-weight: bold;">&#40;</span>LISTEN<span style="color: #7a0874; font-weight: bold;">&#41;</span></pre></div></div>

<div style="margin-top: 15px; ">
<hr style="border: 1px solid #cccccc;"/>
<p><strong>原创文章，转载请注明：</strong> 转载自<a href="http://www.huangwei.me/blog/">猪在笑</a> <a href="http://www.huangwei.me/blog/">[ http://www.huangwei.me/blog/ ]</a><br/><strong>本文链接地址:</strong> <a href="http://www.huangwei.me/blog/2011/08/17/lsof-and-fuser/">http://www.huangwei.me/blog/2011/08/17/lsof-and-fuser/</a></p>
<hr style="border: 1px solid #cccccc;"/>
</div>
<div  class="related_post_title">您可能还对以下文章感兴趣</div><ul class="related_post"><li><a href="http://www.huangwei.me/blog/2010/08/02/sniffer-with-perl-pcap/" title="[CodeSnippet]Perl抓包分析之DNS debug">[CodeSnippet]Perl抓包分析之DNS debug</a></li><li><a href="http://www.huangwei.me/blog/2010/08/02/ssh-security-harden/" title="SSH安全加固一二三">SSH安全加固一二三</a></li><li><a href="http://www.huangwei.me/blog/2010/05/30/simple-ddos-detection/" title="简单几条命令检测DDoS攻击">简单几条命令检测DDoS攻击</a></li><li><a href="http://www.huangwei.me/blog/2010/01/30/%e7%a0%b4%e8%a7%a3%e5%90%88%e8%82%a5%e7%94%b5%e4%bf%a1%e7%9a%84adsl%e7%8c%ab%e4%b8%8a%e7%bd%91%e9%99%90%e5%88%b6/" title="破解合肥电信的ADSL猫上网限制">破解合肥电信的ADSL猫上网限制</a></li><li><a href="http://www.huangwei.me/blog/2007/03/20/obacktrack-2oaiec-2/" title="[原创]BackTrack 2硬盘安装笔记">[原创]BackTrack 2硬盘安装笔记</a></li><li><a href="http://www.huangwei.me/blog/2011/02/06/cert-secure-coding-standard/" title="[译]CERT Secure Coding Standard — C语言安全编程规范(5)">[译]CERT Secure Coding Standard — C语言安全编程规范(5)</a></li><li><a href="http://www.huangwei.me/blog/2011/02/06/cert-secure-coding-standard-4/" title="[译]CERT Secure Coding Standard — C语言安全编程规范(4)">[译]CERT Secure Coding Standard — C语言安全编程规范(4)</a></li><li><a href="http://www.huangwei.me/blog/2011/02/05/cert-secure-coding-standard-3/" title="[译]CERT Secure Coding Standard — C语言安全编程规范(3)">[译]CERT Secure Coding Standard — C语言安全编程规范(3)</a></li><li><a href="http://www.huangwei.me/blog/2011/02/04/cert-secure-coding-standard-2/" title="[译]CERT Secure Coding Standard — C语言安全编程规范(2)">[译]CERT Secure Coding Standard — C语言安全编程规范(2)</a></li><li><a href="http://www.huangwei.me/blog/2011/02/03/cert-secure-coding-standard-1/" title="[译]CERT Secure Coding Standard — C语言安全编程规范(1)">[译]CERT Secure Coding Standard — C语言安全编程规范(1)</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.huangwei.me/blog/2011/08/17/lsof-and-fuser/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>苹果小白的上手笔记(2)</title>
		<link>http://www.huangwei.me/blog/2011/04/06/new-to-mac-2/</link>
		<comments>http://www.huangwei.me/blog/2011/04/06/new-to-mac-2/#comments</comments>
		<pubDate>Wed, 06 Apr 2011 13:50:18 +0000</pubDate>
		<dc:creator>c4pr1c3</dc:creator>
				<category><![CDATA[Mac]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[git-svn]]></category>
		<category><![CDATA[leopard]]></category>
		<category><![CDATA[mac]]></category>
		<category><![CDATA[Mac Programming]]></category>
		<category><![CDATA[macbook]]></category>
		<category><![CDATA[MacPorts]]></category>
		<category><![CDATA[Mac程序员]]></category>
		<category><![CDATA[mac笔记]]></category>
		<category><![CDATA[meld]]></category>
		<category><![CDATA[osx]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[svn]]></category>

		<guid isPermaLink="false">http://www.huangwei.me/blog/?p=1012</guid>
		<description><![CDATA[续上篇，本篇小白笔记是从一个程序员的角度谈谈我的使用经验，上手时间有限，难免有认识上的浅薄之处，欢迎老白们留言指正。

言归正传，我目前在Mac平台上的开发虽然是为了iOS，但本文的写作不是为iOS程序员量身订制。写作本文的主要动机是记录一下我是如何从Linux开发环境逐渐转变适应Mac开发环境的。所以，如果你也和我一样，刚从Linux平台转到Mac上，那么本文所记录的一些笔记应该就是为你准备的。
<h1>MacPorts</h1>
只要你最近一直在用Linux的主流发行版本（Ubuntu、Fedora、Debian、Gentoo等等），或者有过BSD使用经验，一定对*nix平台上的软件包管理机制不陌生。不管是Apt-get、rpm、pkg等等，对于普通用户的体验来说，都是一键安装（一条命令）软件，不用考虑不同软件之间复杂的依赖关系，也不用考虑去哪儿下载软件比较靠谱，更不用担心软件的自动更新问题。依托开源社区的强大支持，海量软件随用随装。

Mac作为BSD系统商业化的最成功代表，继承了BSD系统稳定、可靠的传统和特性，但没有经过调教的Mac OS X不是为程序员而定制的。这和乔帮主一贯的产品设计理念是分不开的：苹果的产品能够让一个小学二年级教育文化水平的人，无需说明书即可开始使用。程序员嘛，受教育文化水平肯定是要高于小学二年级教育文化水平的。所以，程序员需要控制台，用键盘的时间要多于用鼠标。非程序员，不需要控制台，最好连键盘都不要用到。

<a href="http://www.macports.org/" target="_blank">MacPorts</a>可以看做是BSD系统上的ports机制在苹果系统上的移植版本，关于MacPorts的安装，如果你是用的Snow Leopard或者其他较新的苹果系统版本的话，官方网站上提供了直接可用的<a href="http://www.macports.org/install.php" target="_blank">二进制dmg版本</a>，下载双击安装即可。

下面重点介绍安装好MacPorts后的几个关键环节：
<h2>MacPorts改良</h2>
MacPorts的默认安装版本(1.9.2)有两个对于我来说非常不爽的“缺陷”：
<ol>
	<li><span style="color: #ff0000"><strong>不支持多线程下载</strong></span></li>
	<li><span style="color: #ff0000"><strong>下载过程没有任何进度提示</strong></span></li>
</ol>
经过一段时间的hack之后，我找到了上述两个问题的改良方法。

修改/opt/local/share/macports/Tcl/port1.0/portfetch.tcl，大约在489行（修改前请先备份原始文件，以避免修改出错！！）

新增：
<pre lang="tcl" escaped="true">
set currentTTy [exec "tty"]
</pre>
替换原489行代码（使用curl下载的代码片段）为以下代码
<pre lang="tcl" escaped="true">
if  {![catch {system "/opt/local/bin/axel -n 10 -o  ${distpath}/${distfile}.TMP $file_url &#62; $currentTTy"} result] &#38;&#38; ![catch {file rename -force "${distpath}/${distfile}.TMP"  "${distpath}/${distfile}"} result]} {
</pre>
上述代码使用axel，10线程并发下载。根据自己的网速情况，可以增加或减少并发线程数。只要下载速度还可以，就别设置太多并发下载线程了，为服务器节约点带宽给其他人用，呵呵。
看官看到这里请注意了，axel不是系统默认中就有的，正好可以先通过安装axel来体验一把给力的MacPorts。
<h2>MacPorts速成</h2>
以上述axel安装为例来体验MacPorts。
首先是更新MacPorts的本地软件列表
<pre lang="bash" escaped="true">
$ sudo port selfupdate
</pre>
然后是在MacPorts中查找是否有axel这个软件
<pre lang="bash" escaped="true">
$ port search axel
axel @2.4 (net, www)
    A light Unix download accelerator
</pre>
安装
<pre lang="bash" escaped="true">
$ sudo port install axel
</pre>
MacPorts安装软件的过程可以简单分为：下载代码、编译代码、安装二进制程序、配置程序，实际的安装软件过程还包含代码依赖性问题的解决过程。
关于MacPorts的常用命令，我整理了一个列表，如下：
<ol>
	<li> 更新port： port selfupdate</li>
	<li> 升级port里面的所有软件包：port -d sync</li>
	<li> 查询port里面是否有该软件：port search xxx</li>
	<li> 用port安装某软件：port install xxx</li>
	<li> 查看port里面的软件是否有升级：port outdated</li>
	<li> 查看某个软件是否有升级：port outdated xxx</li>
	<li> 升级某个软件： port upgrade xxx</li>
	<li> 升级某个软件(不升级依赖软件)： port -n upgrade xxx</li>
	<li> 升级所有能升级的软件： port upgrade installed</li>
	<li> 禁用某个软件（但不删除）： port uninstall xxx</li>
	<li> 彻底清除某个软件： port clean --all xxx</li>
	<li> 查看某个软件的详细信息：port info xxx</li>
	<li> 查看某款软件的备注信息：port notes xxx （例如启动dbus的方法：port notes dbus）</li>
	<li> 查看软件在系统上安装了哪些文件：port contents xxx</li>
	<li> 查看已安装的软件列表：port installed [xxx]</li>
	<li> 查看软件的可选安装组件或编译参数：port variants xxx</li>
</ol>
以安装curl为例：
<pre lang="bash" escaped="true">
$ port variants curl
curl has the variants:
  ares: Add support for resolving names asynchronously
  gnutls: Allow secure connections using GNU TLS
    * conflicts with ssl
  gss: Support the Generic Security Service API
  openldap: Support performing Lightweight Directory Access Protocol queries with
            OpenLDAP
  sftp_scp: Add SFTP/SCP support via libssh2
  spnego: Enable SPNEGO authentication support
[+]ssl: Allow secure connections using OpenSSL
  universal: Build for multiple architectures
</pre>
有[+]的选项表示非默认组件或编译参数，如果需要安装或启用则需要在安装时显式的指定，如：
<pre lang="bash" escaped="true">
$ sudo port install curl +ssl
</pre>
&#160;
<h2>MacPorts排错</h2>
命令行提示找不到通过MacPorts安装的程序？
默认情况下，通过MacPorts安装软件的根目录在/opt，而系统默认的环境变量没有包含这个目录下的可执行程序目录，所以为了一劳永逸，可以修改用户自己的环境变量，以便于程序的启动。

修改环境变量，将通过MacPorts安装的软件的默认搜索路径加到PATH中。和*nix一样，修改~/.bashrc即可。

<pre lang="bash" escaped="true">
export PATH=/opt/subversion/bin:/opt/local/bin:$PATH
</pre>

通过MacPorts安装软件出现校验和错误的解决办法：<a href="http://trac.macports.org/wiki/FAQ#checksums" target="_blank">官方链接</a>
<pre lang="bash" escaped="true">
$ sudo port selfupdate
$ sudo port clean --dist 
$ sudo port install 
</pre>

<h1>Meld</h1>

关于Meld是什么，可以看我之前写的这篇文章：<a href="http://www.huangwei.me/blog/2010/08/30/gnome-nautilus-scripts-meld/">nautilus脚本应用实例之一：用meld比较选中的文件或文件夹</a>。Meld之于程序员的意义是：源代码差异比较的神器，没有之一。

meld可以通过MacPorts直接安装，如果遇到安装meld后无法启动，命令行报错提示信息：
...
Dynamic session lookup supported but failed: launchd did not provide a socket path, verify that org.freedesktop.dbus-session.plist is loaded!
…

官方已经给出了<a href="https://trac.macports.org/ticket/26119">解决办法</a>：
<pre lang="bash" escaped="true">
$ sudo launchctl load -w /Library/LaunchDaemons/org.freedesktop.dbus-system.plist
$ launchctl load -w /Library/LaunchAgents/org.freedesktop.dbus-session.plist
</pre>
执行完上面的两条语句之后就可以顺利启动meld了

<h1>后记</h1>
写完后我才发现，这一篇所谓程序员视角的小白笔记其实就是讲了MacPorts而已，只是顺带又推荐了meld这个神器，无它。但沉思片刻，似乎对于程序员来说，特别是有Linux背景的程序员来说，有了MacPorts，似乎不需要再多介绍什么了。头文件、库、编译工具、工具链，这些都可以通过MacPorts来安装，一切还和之前一样，没太多不同。

不过MacPorts由于是基于源代码的包管理机制，所以在编译一些“大”软件的时候，耗费的时间有些长。今天在更新boost的时候，我看了一下时间，差不多得有1个小时吧。如果想试试基于二进制可执行文件的包管理机制，可以试试<a />Fink</a>，我暂时还没用过。MacPorts目前可以满足我的所有需求了，唯一没有找到的一个开源软件就是MadEdit。Fink里似乎有MadEdit的源，改天再试试。]]></description>
			<content:encoded><![CDATA[<div style="margin-top: 2px;">
<A href="http://creativecommons.org/licenses/by/3.0/deed.zh"><FONT color=#11779f><STRONG>版权声明</STRONG></FONT></A><FONT color=#11779f><STRONG>：可以任意转载，转载时请务必以超链接形式标明文章原始出处和<a href="http://www.huangwei.me/blog/">作者信息</a></STRONG></FONT>
</div>
<p>续上篇，本篇小白笔记是从一个程序员的角度谈谈我的使用经验，上手时间有限，难免有认识上的浅薄之处，欢迎老白们留言指正。</p>
<p>言归正传，我目前在Mac平台上的开发虽然是为了iOS，但本文的写作不是为iOS程序员量身订制。写作本文的主要动机是记录一下我是如何从Linux开发环境逐渐转变适应Mac开发环境的。所以，如果你也和我一样，刚从Linux平台转到Mac上，那么本文所记录的一些笔记应该就是为你准备的。</p>
<h1>MacPorts</h1>
<p>只要你最近一直在用Linux的主流发行版本（Ubuntu、Fedora、Debian、Gentoo等等），或者有过BSD使用经验，一定对*nix平台上的软件包管理机制不陌生。不管是Apt-get、rpm、pkg等等，对于普通用户的体验来说，都是一键安装（一条命令）软件，不用考虑不同软件之间复杂的依赖关系，也不用考虑去哪儿下载软件比较靠谱，更不用担心软件的自动更新问题。依托开源社区的强大支持，海量软件随用随装。</p>
<p>Mac作为BSD系统商业化的最成功代表，继承了BSD系统稳定、可靠的传统和特性，但没有经过调教的Mac OS X不是为程序员而定制的。这和乔帮主一贯的产品设计理念是分不开的：苹果的产品能够让一个小学二年级教育文化水平的人，无需说明书即可开始使用。程序员嘛，受教育文化水平肯定是要高于小学二年级教育文化水平的。所以，程序员需要控制台，用键盘的时间要多于用鼠标。非程序员，不需要控制台，最好连键盘都不要用到。</p>
<p><a href="http://www.macports.org/" target="_blank">MacPorts</a>可以看做是BSD系统上的ports机制在苹果系统上的移植版本，关于MacPorts的安装，如果你是用的Snow Leopard或者其他较新的苹果系统版本的话，官方网站上提供了直接可用的<a href="http://www.macports.org/install.php" target="_blank">二进制dmg版本</a>，下载双击安装即可。</p>
<p>下面重点介绍安装好MacPorts后的几个关键环节：</p>
<h2>MacPorts改良</h2>
<p>MacPorts的默认安装版本(1.9.2)有两个对于我来说非常不爽的“缺陷”：</p>
<ol>
<li><span style="color: #ff0000"><strong>不支持多线程下载</strong></span></li>
<li><span style="color: #ff0000"><strong>下载过程没有任何进度提示</strong></span></li>
</ol>
<p>经过一段时间的hack之后，我找到了上述两个问题的改良方法。</p>
<p>修改/opt/local/share/macports/Tcl/port1.0/portfetch.tcl，大约在489行（修改前请先备份原始文件，以避免修改出错！！）</p>
<p>新增：</p>

<div class="wp_syntax"><div class="code"><pre class="tcl" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">set</span> currentTTy <span style="color: black;">&#91;</span><span style="color: #008000;">exec</span> <span style="color: #483d8b;">&quot;tty&quot;</span><span style="color: black;">&#93;</span></pre></div></div>

<p>替换原489行代码（使用curl下载的代码片段）为以下代码</p>

<div class="wp_syntax"><div class="code"><pre class="tcl" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">if</span>  <span style="color: black;">&#123;</span><span style="color: #66cc66;">!</span><span style="color: black;">&#91;</span><span style="color: #ff7700;font-weight:bold;">catch</span> <span style="color: black;">&#123;</span>system <span style="color: #483d8b;">&quot;/opt/local/bin/axel -n 10 -o  ${distpath}/${distfile}.TMP $file_url &gt; $currentTTy&quot;</span><span style="color: black;">&#125;</span> result<span style="color: black;">&#93;</span> <span style="color: #66cc66;">&amp;&amp;</span> <span style="color: #66cc66;">!</span><span style="color: black;">&#91;</span><span style="color: #ff7700;font-weight:bold;">catch</span> <span style="color: black;">&#123;</span><span style="color: #008000;">file</span> <span style="color: #ff7700;font-weight:bold;">rename</span> -force <span style="color: #483d8b;">&quot;${distpath}/${distfile}.TMP&quot;</span>  <span style="color: #483d8b;">&quot;${distpath}/${distfile}&quot;</span><span style="color: black;">&#125;</span> result<span style="color: black;">&#93;</span><span style="color: black;">&#125;</span> <span style="color: black;">&#123;</span></pre></div></div>

<p>上述代码使用axel，10线程并发下载。根据自己的网速情况，可以增加或减少并发线程数。只要下载速度还可以，就别设置太多并发下载线程了，为服务器节约点带宽给其他人用，呵呵。<br />
看官看到这里请注意了，axel不是系统默认中就有的，正好可以先通过安装axel来体验一把给力的MacPorts。</p>
<h2>MacPorts速成</h2>
<p>以上述axel安装为例来体验MacPorts。<br />
首先是更新MacPorts的本地软件列表</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">sudo</span> port selfupdate</pre></div></div>

<p>然后是在MacPorts中查找是否有axel这个软件</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ port search axel
axel <span style="color: #000000; font-weight: bold;">@</span><span style="color: #000000;">2.4</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span>net, www<span style="color: #7a0874; font-weight: bold;">&#41;</span>
    A light Unix download accelerator</pre></div></div>

<p>安装</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">sudo</span> port <span style="color: #c20cb9; font-weight: bold;">install</span> axel</pre></div></div>

<p>MacPorts安装软件的过程可以简单分为：下载代码、编译代码、安装二进制程序、配置程序，实际的安装软件过程还包含代码依赖性问题的解决过程。<br />
关于MacPorts的常用命令，我整理了一个列表，如下：</p>
<ol>
<li> 更新port： port selfupdate</li>
<li> 升级port里面的所有软件包：port -d sync</li>
<li> 查询port里面是否有该软件：port search xxx</li>
<li> 用port安装某软件：port install xxx</li>
<li> 查看port里面的软件是否有升级：port outdated</li>
<li> 查看某个软件是否有升级：port outdated xxx</li>
<li> 升级某个软件： port upgrade xxx</li>
<li> 升级某个软件(不升级依赖软件)： port -n upgrade xxx</li>
<li> 升级所有能升级的软件： port upgrade installed</li>
<li> 禁用某个软件（但不删除）： port uninstall xxx</li>
<li> 彻底清除某个软件： port clean &#8211;all xxx</li>
<li> 查看某个软件的详细信息：port info xxx</li>
<li> 查看某款软件的备注信息：port notes xxx （例如启动dbus的方法：port notes dbus）</li>
<li> 查看软件在系统上安装了哪些文件：port contents xxx</li>
<li> 查看已安装的软件列表：port installed [xxx]</li>
<li> 查看软件的可选安装组件或编译参数：port variants xxx</li>
</ol>
<p>以安装curl为例：</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ port variants curl
curl has the variants:
  ares: Add support <span style="color: #000000; font-weight: bold;">for</span> resolving names asynchronously
  gnutls: Allow secure connections using GNU TLS
    <span style="color: #000000; font-weight: bold;">*</span> conflicts with ssl
  gss: Support the Generic Security Service API
  openldap: Support performing Lightweight Directory Access Protocol queries with
            OpenLDAP
  sftp_scp: Add SFTP<span style="color: #000000; font-weight: bold;">/</span>SCP support via libssh2
  spnego: Enable SPNEGO authentication support
<span style="color: #7a0874; font-weight: bold;">&#91;</span>+<span style="color: #7a0874; font-weight: bold;">&#93;</span>ssl: Allow secure connections using OpenSSL
  universal: Build <span style="color: #000000; font-weight: bold;">for</span> multiple architectures</pre></div></div>

<p>有[+]的选项表示非默认组件或编译参数，如果需要安装或启用则需要在安装时显式的指定，如：</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">sudo</span> port <span style="color: #c20cb9; font-weight: bold;">install</span> curl +ssl</pre></div></div>

<p>&nbsp;</p>
<h2>MacPorts排错</h2>
<p>命令行提示找不到通过MacPorts安装的程序？<br />
默认情况下，通过MacPorts安装软件的根目录在/opt，而系统默认的环境变量没有包含这个目录下的可执行程序目录，所以为了一劳永逸，可以修改用户自己的环境变量，以便于程序的启动。</p>
<p>修改环境变量，将通过MacPorts安装的软件的默认搜索路径加到PATH中。和*nix一样，修改~/.bashrc即可。</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">PATH</span>=<span style="color: #000000; font-weight: bold;">/</span>opt<span style="color: #000000; font-weight: bold;">/</span>subversion<span style="color: #000000; font-weight: bold;">/</span>bin:<span style="color: #000000; font-weight: bold;">/</span>opt<span style="color: #000000; font-weight: bold;">/</span>local<span style="color: #000000; font-weight: bold;">/</span>bin:<span style="color: #007800;">$PATH</span></pre></div></div>

<p>通过MacPorts安装软件出现校验和错误的解决办法：<a href="http://trac.macports.org/wiki/FAQ#checksums" target="_blank">官方链接</a></p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">sudo</span> port selfupdate
$ <span style="color: #c20cb9; font-weight: bold;">sudo</span> port clean <span style="color: #660033;">--dist</span> 
$ <span style="color: #c20cb9; font-weight: bold;">sudo</span> port <span style="color: #c20cb9; font-weight: bold;">install</span></pre></div></div>

<h1>Meld</h1>
<p>关于Meld是什么，可以看我之前写的这篇文章：<a href="http://www.huangwei.me/blog/2010/08/30/gnome-nautilus-scripts-meld/">nautilus脚本应用实例之一：用meld比较选中的文件或文件夹</a>。Meld之于程序员的意义是：源代码差异比较的神器，没有之一。</p>
<p>meld可以通过MacPorts直接安装，如果遇到安装meld后无法启动，命令行报错提示信息：<br />
&#8230;<br />
Dynamic session lookup supported but failed: launchd did not provide a socket path, verify that org.freedesktop.dbus-session.plist is loaded!<br />
…</p>
<p>官方已经给出了<a href="https://trac.macports.org/ticket/26119">解决办法</a>：</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">sudo</span> launchctl load <span style="color: #660033;">-w</span> <span style="color: #000000; font-weight: bold;">/</span>Library<span style="color: #000000; font-weight: bold;">/</span>LaunchDaemons<span style="color: #000000; font-weight: bold;">/</span>org.freedesktop.dbus-system.plist
$ launchctl load <span style="color: #660033;">-w</span> <span style="color: #000000; font-weight: bold;">/</span>Library<span style="color: #000000; font-weight: bold;">/</span>LaunchAgents<span style="color: #000000; font-weight: bold;">/</span>org.freedesktop.dbus-session.plist</pre></div></div>

<p>执行完上面的两条语句之后就可以顺利启动meld了</p>
<h1>后记</h1>
<p>写完后我才发现，这一篇所谓程序员视角的小白笔记其实就是讲了MacPorts而已，只是顺带又推荐了meld这个神器，无它。但沉思片刻，似乎对于程序员来说，特别是有Linux背景的程序员来说，有了MacPorts，似乎不需要再多介绍什么了。头文件、库、编译工具、工具链，这些都可以通过MacPorts来安装，一切还和之前一样，没太多不同。</p>
<p>不过MacPorts由于是基于源代码的包管理机制，所以在编译一些“大”软件的时候，耗费的时间有些长。今天在更新boost的时候，我看了一下时间，差不多得有1个小时吧。如果想试试基于二进制可执行文件的包管理机制，可以试试<a />Fink</a>，我暂时还没用过。MacPorts目前可以满足我的所有需求了，唯一没有找到的一个开源软件就是MadEdit。Fink里似乎有MadEdit的源，改天再试试。
<div style="margin-top: 15px; ">
<hr style="border: 1px solid #cccccc;"/>
<p><strong>原创文章，转载请注明：</strong> 转载自<a href="http://www.huangwei.me/blog/">猪在笑</a> <a href="http://www.huangwei.me/blog/">[ http://www.huangwei.me/blog/ ]</a><br/><strong>本文链接地址:</strong> <a href="http://www.huangwei.me/blog/2011/04/06/new-to-mac-2/">http://www.huangwei.me/blog/2011/04/06/new-to-mac-2/</a></p>
<hr style="border: 1px solid #cccccc;"/>
</div>
<div  class="related_post_title">您可能还对以下文章感兴趣</div><ul class="related_post"><li><a href="http://www.huangwei.me/blog/2011/03/21/new-to-mac-1/" title="苹果小白的上手笔记(1)">苹果小白的上手笔记(1)</a></li><li><a href="http://www.huangwei.me/blog/2011/02/06/cert-secure-coding-standard/" title="[译]CERT Secure Coding Standard — C语言安全编程规范(5)">[译]CERT Secure Coding Standard — C语言安全编程规范(5)</a></li><li><a href="http://www.huangwei.me/blog/2011/02/06/cert-secure-coding-standard-4/" title="[译]CERT Secure Coding Standard — C语言安全编程规范(4)">[译]CERT Secure Coding Standard — C语言安全编程规范(4)</a></li><li><a href="http://www.huangwei.me/blog/2011/02/05/cert-secure-coding-standard-3/" title="[译]CERT Secure Coding Standard — C语言安全编程规范(3)">[译]CERT Secure Coding Standard — C语言安全编程规范(3)</a></li><li><a href="http://www.huangwei.me/blog/2011/02/04/cert-secure-coding-standard-2/" title="[译]CERT Secure Coding Standard — C语言安全编程规范(2)">[译]CERT Secure Coding Standard — C语言安全编程规范(2)</a></li><li><a href="http://www.huangwei.me/blog/2011/02/03/cert-secure-coding-standard-1/" title="[译]CERT Secure Coding Standard — C语言安全编程规范(1)">[译]CERT Secure Coding Standard — C语言安全编程规范(1)</a></li><li><a href="http://www.huangwei.me/blog/2010/12/06/linux-c-programming-faq-4/" title="Linux C/C++编程FAQ系列 之四">Linux C/C++编程FAQ系列 之四</a></li><li><a href="http://www.huangwei.me/blog/2010/12/03/js-interview-test/" title="4道js面试题">4道js面试题</a></li><li><a href="http://www.huangwei.me/blog/2010/11/30/improve-vim-javascript-edit/" title="增强vim的js语法高亮和代码阅读能力">增强vim的js语法高亮和代码阅读能力</a></li><li><a href="http://www.huangwei.me/blog/2010/11/28/linux-c-programming-faq-3/" title="Linux C/C++编程FAQ系列 之三">Linux C/C++编程FAQ系列 之三</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.huangwei.me/blog/2011/04/06/new-to-mac-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>苹果小白的上手笔记(1)</title>
		<link>http://www.huangwei.me/blog/2011/03/21/new-to-mac-1/</link>
		<comments>http://www.huangwei.me/blog/2011/03/21/new-to-mac-1/#comments</comments>
		<pubDate>Mon, 21 Mar 2011 15:42:04 +0000</pubDate>
		<dc:creator>c4pr1c3</dc:creator>
				<category><![CDATA[Mac]]></category>
		<category><![CDATA[leopard]]></category>
		<category><![CDATA[mac]]></category>
		<category><![CDATA[macbook]]></category>
		<category><![CDATA[mac笔记]]></category>
		<category><![CDATA[osx]]></category>

		<guid isPermaLink="false">http://www.huangwei.me/blog/?p=981</guid>
		<description><![CDATA[<span style="font-size: 20px;font-weight: bold">Last update: 2012-03-21</span>

Macbook Pro入手整一周，上手笔记稍加整理了一下，发个水帖。这第一篇笔记侧重于我在一周的办公型日常使用中遇到的问题和解决方案，软件使用心得。
<h2>Windows用户必读</h2>
<a href="http://www.apple.com.cn/support/switch101/"></a><a href="http://support.apple.com/kb/HT2514?viewlocale=zh_CN">http://support.apple.com/kb/HT2514?viewlocale=zh_CN</a>

<span style="font-size: 20px;font-weight: bold">Macbook的触摸板手势</span>

<a href="http://support.apple.com/kb/ht3211?viewlocale=zh_CN">http://support.apple.com/kb/ht3211?viewlocale=zh_CN</a>

不会使用鼠标右键的一定要看看这个链接。

btw: 系统的这个设置界面做得太棒了，直接用视频来辅助说明设置项的作用和效果，一目了然。
<h2>Mac OS X的键盘快捷键</h2>
<a href="http://support.apple.com/kb/HT1343?viewlocale=zh_CN">http://support.apple.com/kb/HT1343?viewlocale=zh_CN</a>

我最常用的一些快捷键：

程序完全退出：Command+Q

关闭标签/“简单”退出（程序保留在Dock）：Command+W

新开标签页：Command+T

截图：Shift+Command+4

屏幕缩放：Control+两根手指划呀划（鼠标滚轮滚动）

用键盘重命名：回车

用键盘在Finder中打开程序/目录：Command+O

用键盘在Finder中打开上一级（父）目录：Command+上方向键

光标快速移动行首/行尾：Command+左键/右键

<span style="font-size: 20px;font-weight: bold">中文输入法</span>

开启系统默认输入法：<a href="http://zhidao.baidu.com/question/106508545">http://zhidao.baidu.com/question/106508545</a>

推荐的第三方输入法：<a href="http://fit4.cn/mac">http://fit4.cn/mac</a>
<h2>Office</h2>
如果你安装了Mac Office 2011英文版（话说迅雷上有cracked版本，我就不提供下载链接了），那么你很可能还需要去解决一下中文字体的问题。英文版自带的简体中文字体实在太少，没有这些字体，甚至连仿宋都没有。中文模板中的一些字体在我这里还会显示日文字体名。。。

这些Google大神都知道，问问他吧。
<h2>虚拟机</h2>
虽然有原生的ms office了，但是没有visio，所以虚拟机偶尔还要开一下。开源/免费的可以用经典的<a href="http://www.virtualbox.org/wiki/Downloads" target="_blank">VirtualBox</a>，VMware fusion是商业版的。当然Google大神也会告诉你去哪儿下载破解版的。。。
<h2>下载</h2>
在Mac版迅雷正式发布之前，Firefox+Downthemall应该是最佳的免费、多线程、支持端点续传的下载方案了。

sftp可以用filezilla，官网果断下载之。
<h2>IM</h2>
Adium在Mac OS上的意义基本和pidgin之于Linux，支持多种IM的集成，地位无须多解释了。QQ？我基本不用，偶尔WebQQ就能满足需求了。

淘宝玩家可以用Mac版的阿里旺旺，官方出品，品质有保障，功能逐渐完善中。

<h2>图片查看器</h2>
<a href="http://wakaba.c3.cx/s/apps/xee">xee</a>：如果你和我一样，对狮子自带的预览程序在查看图片文件夹时居然不能用键盘左右键控制上一张/下一张查看图片，试试这款软件吧:D

<h2>终端</h2>
自带的终端有2个严重让我不满的bug。第一，不支持256色。我以前的.vimrc需要修改，.bashrc需要修改。否则vim界面下会一闪一闪的。第二，命令行超长（典型情况是进入较深层次的目录）时如果调整终端窗口的大小会造成命令行提示符发疯似的重复多次。

现在改用<a href="http://www.iterm2.com/">iTerm2</a>，免费，基本和gnome-terminal一致的用户体验了。
<h2>在此处打开终端/命令行</h2>
推荐两个我在用的app:

DTerm：App Store中就有，免费。可以方便的在Finder中激活一个命令行提示符，方便执行一些简单的终端命令（例如使用命令行解压缩文件）。

<del>&#62;cd to ..：正牌的“在此处/当前目录打开终端”</del>

<a href="http://www.macupdate.com/app/mac/23173/openterminal" target="_blank">OpenTerminal</a>：支持使用iTerm而不是系统自带的终端。
<h2>解压缩rar</h2>
<a href="http://www.kekaosx.com/en/" target="_blank">Keka</a>: 推荐保留在Dock中，需要解压缩文件时使用拖拽操作。把要解压缩的文件拖拽到图标上，不过有的时候在Finder中双击压缩文件也可以自动解压缩到当前目录。

<h2>强制退出应用程序</h2>
Option+Command+Esc

<h2>桌面工作效率提升</h2>
<a href="http://www.irradiatedsoftware.com/cinch/index.html">clinch</a>：应用程序窗口贴边自适应最大化/只填满半屏，离边自适应屏幕大小缩放（共享版，定期弹出注册提示，但不影响使用，强烈推荐）；

下一篇笔记将从程序员的视角来记录一些心得和体会。]]></description>
			<content:encoded><![CDATA[<div style="margin-top: 2px;">
<A href="http://creativecommons.org/licenses/by/3.0/deed.zh"><FONT color=#11779f><STRONG>版权声明</STRONG></FONT></A><FONT color=#11779f><STRONG>：可以任意转载，转载时请务必以超链接形式标明文章原始出处和<a href="http://www.huangwei.me/blog/">作者信息</a></STRONG></FONT>
</div>
<p><span style="font-size: 20px;font-weight: bold">Last update: 2012-03-21</span></p>
<p>Macbook Pro入手整一周，上手笔记稍加整理了一下，发个水帖。这第一篇笔记侧重于我在一周的办公型日常使用中遇到的问题和解决方案，软件使用心得。</p>
<h2>Windows用户必读</h2>
<p><a href="http://www.apple.com.cn/support/switch101/"></a><a href="http://support.apple.com/kb/HT2514?viewlocale=zh_CN">http://support.apple.com/kb/HT2514?viewlocale=zh_CN</a></p>
<p><span style="font-size: 20px;font-weight: bold">Macbook的触摸板手势</span></p>
<p><a href="http://support.apple.com/kb/ht3211?viewlocale=zh_CN">http://support.apple.com/kb/ht3211?viewlocale=zh_CN</a></p>
<p>不会使用鼠标右键的一定要看看这个链接。</p>
<p>btw: 系统的这个设置界面做得太棒了，直接用视频来辅助说明设置项的作用和效果，一目了然。</p>
<h2>Mac OS X的键盘快捷键</h2>
<p><a href="http://support.apple.com/kb/HT1343?viewlocale=zh_CN">http://support.apple.com/kb/HT1343?viewlocale=zh_CN</a></p>
<p>我最常用的一些快捷键：</p>
<p>程序完全退出：Command+Q</p>
<p>关闭标签/“简单”退出（程序保留在Dock）：Command+W</p>
<p>新开标签页：Command+T</p>
<p>截图：Shift+Command+4</p>
<p>屏幕缩放：Control+两根手指划呀划（鼠标滚轮滚动）</p>
<p>用键盘重命名：回车</p>
<p>用键盘在Finder中打开程序/目录：Command+O</p>
<p>用键盘在Finder中打开上一级（父）目录：Command+上方向键</p>
<p>光标快速移动行首/行尾：Command+左键/右键</p>
<p><span style="font-size: 20px;font-weight: bold">中文输入法</span></p>
<p>开启系统默认输入法：<a href="http://zhidao.baidu.com/question/106508545">http://zhidao.baidu.com/question/106508545</a></p>
<p>推荐的第三方输入法：<a href="http://fit4.cn/mac">http://fit4.cn/mac</a></p>
<h2>Office</h2>
<p>如果你安装了Mac Office 2011英文版（话说迅雷上有cracked版本，我就不提供下载链接了），那么你很可能还需要去解决一下中文字体的问题。英文版自带的简体中文字体实在太少，没有这些字体，甚至连仿宋都没有。中文模板中的一些字体在我这里还会显示日文字体名。。。</p>
<p>这些Google大神都知道，问问他吧。</p>
<h2>虚拟机</h2>
<p>虽然有原生的ms office了，但是没有visio，所以虚拟机偶尔还要开一下。开源/免费的可以用经典的<a href="http://www.virtualbox.org/wiki/Downloads" target="_blank">VirtualBox</a>，VMware fusion是商业版的。当然Google大神也会告诉你去哪儿下载破解版的。。。</p>
<h2>下载</h2>
<p>在Mac版迅雷正式发布之前，Firefox+Downthemall应该是最佳的免费、多线程、支持端点续传的下载方案了。</p>
<p>sftp可以用filezilla，官网果断下载之。</p>
<h2>IM</h2>
<p>Adium在Mac OS上的意义基本和pidgin之于Linux，支持多种IM的集成，地位无须多解释了。QQ？我基本不用，偶尔WebQQ就能满足需求了。</p>
<p>淘宝玩家可以用Mac版的阿里旺旺，官方出品，品质有保障，功能逐渐完善中。</p>
<h2>图片查看器</h2>
<p><a href="http://wakaba.c3.cx/s/apps/xee">xee</a>：如果你和我一样，对狮子自带的预览程序在查看图片文件夹时居然不能用键盘左右键控制上一张/下一张查看图片，试试这款软件吧:D</p>
<h2>终端</h2>
<p>自带的终端有2个严重让我不满的bug。第一，不支持256色。我以前的.vimrc需要修改，.bashrc需要修改。否则vim界面下会一闪一闪的。第二，命令行超长（典型情况是进入较深层次的目录）时如果调整终端窗口的大小会造成命令行提示符发疯似的重复多次。</p>
<p>现在改用<a href="http://www.iterm2.com/">iTerm2</a>，免费，基本和gnome-terminal一致的用户体验了。</p>
<h2>在此处打开终端/命令行</h2>
<p>推荐两个我在用的app:</p>
<p>DTerm：App Store中就有，免费。可以方便的在Finder中激活一个命令行提示符，方便执行一些简单的终端命令（例如使用命令行解压缩文件）。</p>
<p><del>&gt;cd to ..：正牌的“在此处/当前目录打开终端”</del></p>
<p><a href="http://www.macupdate.com/app/mac/23173/openterminal" target="_blank">OpenTerminal</a>：支持使用iTerm而不是系统自带的终端。</p>
<h2>解压缩rar</h2>
<p><a href="http://www.kekaosx.com/en/" target="_blank">Keka</a>: 推荐保留在Dock中，需要解压缩文件时使用拖拽操作。把要解压缩的文件拖拽到图标上，不过有的时候在Finder中双击压缩文件也可以自动解压缩到当前目录。</p>
<h2>强制退出应用程序</h2>
<p>Option+Command+Esc</p>
<h2>桌面工作效率提升</h2>
<p><a href="http://www.irradiatedsoftware.com/cinch/index.html">clinch</a>：应用程序窗口贴边自适应最大化/只填满半屏，离边自适应屏幕大小缩放（共享版，定期弹出注册提示，但不影响使用，强烈推荐）；</p>
<p>下一篇笔记将从程序员的视角来记录一些心得和体会。
<div style="margin-top: 15px; ">
<hr style="border: 1px solid #cccccc;"/>
<p><strong>原创文章，转载请注明：</strong> 转载自<a href="http://www.huangwei.me/blog/">猪在笑</a> <a href="http://www.huangwei.me/blog/">[ http://www.huangwei.me/blog/ ]</a><br/><strong>本文链接地址:</strong> <a href="http://www.huangwei.me/blog/2011/03/21/new-to-mac-1/">http://www.huangwei.me/blog/2011/03/21/new-to-mac-1/</a></p>
<hr style="border: 1px solid #cccccc;"/>
</div>
<div  class="related_post_title">您可能还对以下文章感兴趣</div><ul class="related_post"><li><a href="http://www.huangwei.me/blog/2011/04/06/new-to-mac-2/" title="苹果小白的上手笔记(2)">苹果小白的上手笔记(2)</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.huangwei.me/blog/2011/03/21/new-to-mac-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>善用搜索是从傻瓜到砖家的第一步</title>
		<link>http://www.huangwei.me/blog/2011/03/19/learn-to-search-is-vital/</link>
		<comments>http://www.huangwei.me/blog/2011/03/19/learn-to-search-is-vital/#comments</comments>
		<pubDate>Sat, 19 Mar 2011 13:49:48 +0000</pubDate>
		<dc:creator>c4pr1c3</dc:creator>
				<category><![CDATA[Google]]></category>
		<category><![CDATA[学术研究]]></category>
		<category><![CDATA[Google搜索]]></category>
		<category><![CDATA[成长积淀]]></category>
		<category><![CDATA[搜索技巧]]></category>
		<category><![CDATA[百度搜索]]></category>
		<category><![CDATA[程序员成长]]></category>

		<guid isPermaLink="false">http://www.huangwei.me/blog/?p=1000</guid>
		<description><![CDATA[<span style="color: #ff0000">update: 我发现国内的搜索引擎似乎都把“高级搜索”的链接从首页上移走了。看来确实是点击率太低，所以被废了。只有Google的首页上还保留着“高级搜索”的链接。百度的高级搜索功能可以通过在百度搜索框中输入“百度高级搜索”来访问，我猜是百度上下严格贯彻总裁“框计算”战略的行为吧，去除复杂且不常用功能？。</span>

想写这个文章已经不是一天两天了，网上有很多关于Google搜索的奇技淫巧，安全界的淫才们甚至还发明了Google Hacking一词。我，作为一个深度搜索控，Google技术爱好者，“毁人不倦”的教育行业从业者之一，对搜索技术的崇拜是落实到了实际行动中的。多年搜索应用的使用经验告诉我，<strong>傻瓜和砖家的距离其实并不是万水千山，真的就只是一次搜索的距离</strong>。

等等，有看官看到此处，可能会有疑问：“为什么是搜索，不是搜索引擎呢？”

对头，我要说的确实是搜索，而不仅仅是搜索引擎。如果你到今天还在认为，搜索就等于搜索引擎，就约等于Google+百度，那你就out了。这篇文章就是要写给你看的。

首先，大家没有必要去羡慕嫉妒恨那些所谓精通Google搜索奇技淫巧的人，其实每一个人都可以在瞬间成为Google搜索的砖家。为什么呢？其实不管是Google，还是百度，或者其他任何搜索引擎门户，在首页上都明确的提供了“高级搜索”的链接，点击进去之后，你就成为高级搜索砖家了。只找pdf、doc？没问题。站内搜索？很简单。查相关网页，也有入口了。你还需要记忆类似site、filetype这样的搜索语法吗？用几次就都知道了吧。

其次，除了通用搜索引擎，用好垂直搜索是提升你搜索层次、档次的一个重要途径。比如，如果你要买技术书籍，特别是计算机类的图书，面对市场上成千上万种的计算机图书，你到底该买谁？你用Google来找推荐吗？不用这么麻烦，上<a href="http://www.douban.com" target="_blank">豆瓣</a>吧。看书评，找豆列，让大家帮助大家。读者用脚投票的结果，还是靠谱的。再比如，你在学习一门新语言，新技术，想找一个教学视频来看看。问Google？filetype:avi？不用这么麻烦，国内用户可以上优酷，会翻墻的用户可以上有土伯，既有网友的自制教学视频，也不乏一些培训、书籍、学校的教学视频。好了，举例就到此为止。我常用的一些垂直细分的搜索网站列一下：
<ul>
	<li>找代码：<a href="http://www.google.com/codesearch" target="_blank">Google CodeSearch</a>、<a href="http://www.koders.com/" target="_blank">Koders.com</a></li>
	<li>找推荐书：豆瓣网</li>
	<li>找视频：优酷、youtube、土豆，太多了</li>
	<li>找电子图书：新浪的ishare、CSDN等内容门户有很多“盗版”电子书。。。当然了，百度文库也是很重要一个的罪恶之源</li>
	<li>找ppt: slideshare</li>
	<li>鉴别网图：TinEye</li>
	<li>找最新最新update：微博（新浪、腾讯，等等）、Google实时搜索（主要数据来源是推特）</li>
	<li>找飞机票、火车票、旅游信息：酷讯、去哪儿、途牛，等等</li>
	<li>其他，自己Google搜索：“垂直搜索”。</li>
</ul>
我常用的都已经列在上面了，按重要性程度依次递减。

再有，就是搜索关键词的质量！虽然搜索引擎现在越来越智能，越来越懂中文，但你也不能用“垃圾”关键词来虐搜索引擎的那个框。。。

什么样的关键词会被称为“垃圾”？简单来说，别人能搜到的结果，你搜不到，那你就是输入“垃圾”关键词了。

怎样提高搜索关键词的质量？我总结了几条还算不错的个人经验吧。
<ul>
	<li>“特征签名/模板信息”直接复制+粘贴，最典型的就是程序员遇到的编译器错误提示信息，系统管理员遇到的日志错误信息，等等。</li>
	<li>总结一些重要的个人黄金关键词。比如我的一些最爱关键词：cheatsheet、tutorial、howto等等，之所以只列举英文关键词，可能和我个人的搜索习惯有吧。在我看来，计算机类的问题确实还是英文的搜索结果往往更贴近我的问题的答案。特别是这两年，stackoverflow.com这样的专业计算机类问答网站的出现，你会发现这是真正的广大程序员、IT人士的福音。</li>
	<li>善于使用搜索引擎高级技巧中的一些信息精简功能。例如限制只搜索pdf、doc，限制搜索结果的时间范围，限制只搜索某个站点，等等。很多时候，不是没找到答案。而是答案太多了，无从下手。</li>
</ul>
最后，其实最重要了，搜索精华结果信息来源的“follow”。这句话怎么说呢？比如你查到一篇博客文章，解决了你的问题。你有没有想过，再看看这篇博客的其他文章？更进一步，看了之后，有没有意识到这个博客上的文章内容和你的研究方向/工作内容相关性较大？ok，为什么不订阅他的博客feed呢？我们不能因为解决了问题，就认为ok了。好文章不常有，好博主更是少有的哦。IT技术，日新月异，如果你不能保持自动更新，很快你就会成为奥特曼，再过一段时间，你面临的可能就是失业了。搜索引擎之所以能解决问题，并不是因为搜索技术有多强大，而是有千千万万的用户在贡献内容，奉献精华。内容为王！

现在虽然出现了很多优秀的社会化内容推荐和分享系统、应用，但在我兲朝，所有的UGC（用户产生内容）网站都很难长命。所以，该靠自己的时候，还是要靠自己。紧跟行业领袖，向业界的先进工作者学习是“傻瓜”成长的必由之路。

搜索技术是解决你眼前的问题，RSS订阅和阅读是解决你成长的问题。微博时代，又增加了follow学习之道。

总结一下，善用搜索包括了搜索前、搜索中、搜索后三个阶段的工作。

搜索前，要确定好“去哪儿搜”？

搜索中，要确定“搜什么关键词”？

搜索后，要确定“是否有必要保存信息来源”？]]></description>
			<content:encoded><![CDATA[<div style="margin-top: 2px;">
<A href="http://creativecommons.org/licenses/by/3.0/deed.zh"><FONT color=#11779f><STRONG>版权声明</STRONG></FONT></A><FONT color=#11779f><STRONG>：可以任意转载，转载时请务必以超链接形式标明文章原始出处和<a href="http://www.huangwei.me/blog/">作者信息</a></STRONG></FONT>
</div>
<p><span style="color: #ff0000">update: 我发现国内的搜索引擎似乎都把“高级搜索”的链接从首页上移走了。看来确实是点击率太低，所以被废了。只有Google的首页上还保留着“高级搜索”的链接。百度的高级搜索功能可以通过在百度搜索框中输入“百度高级搜索”来访问，我猜是百度上下严格贯彻总裁“框计算”战略的行为吧，去除复杂且不常用功能？。</span></p>
<p>想写这个文章已经不是一天两天了，网上有很多关于Google搜索的奇技淫巧，安全界的淫才们甚至还发明了Google Hacking一词。我，作为一个深度搜索控，Google技术爱好者，“毁人不倦”的教育行业从业者之一，对搜索技术的崇拜是落实到了实际行动中的。多年搜索应用的使用经验告诉我，<strong>傻瓜和砖家的距离其实并不是万水千山，真的就只是一次搜索的距离</strong>。</p>
<p>等等，有看官看到此处，可能会有疑问：“为什么是搜索，不是搜索引擎呢？”</p>
<p>对头，我要说的确实是搜索，而不仅仅是搜索引擎。如果你到今天还在认为，搜索就等于搜索引擎，就约等于Google+百度，那你就out了。这篇文章就是要写给你看的。</p>
<p>首先，大家没有必要去羡慕嫉妒恨那些所谓精通Google搜索奇技淫巧的人，其实每一个人都可以在瞬间成为Google搜索的砖家。为什么呢？其实不管是Google，还是百度，或者其他任何搜索引擎门户，在首页上都明确的提供了“高级搜索”的链接，点击进去之后，你就成为高级搜索砖家了。只找pdf、doc？没问题。站内搜索？很简单。查相关网页，也有入口了。你还需要记忆类似site、filetype这样的搜索语法吗？用几次就都知道了吧。</p>
<p>其次，除了通用搜索引擎，用好垂直搜索是提升你搜索层次、档次的一个重要途径。比如，如果你要买技术书籍，特别是计算机类的图书，面对市场上成千上万种的计算机图书，你到底该买谁？你用Google来找推荐吗？不用这么麻烦，上<a href="http://www.douban.com" target="_blank">豆瓣</a>吧。看书评，找豆列，让大家帮助大家。读者用脚投票的结果，还是靠谱的。再比如，你在学习一门新语言，新技术，想找一个教学视频来看看。问Google？filetype:avi？不用这么麻烦，国内用户可以上优酷，会翻墻的用户可以上有土伯，既有网友的自制教学视频，也不乏一些培训、书籍、学校的教学视频。好了，举例就到此为止。我常用的一些垂直细分的搜索网站列一下：</p>
<ul>
<li>找代码：<a href="http://www.google.com/codesearch" target="_blank">Google CodeSearch</a>、<a href="http://www.koders.com/" target="_blank">Koders.com</a></li>
<li>找推荐书：豆瓣网</li>
<li>找视频：优酷、youtube、土豆，太多了</li>
<li>找电子图书：新浪的ishare、CSDN等内容门户有很多“盗版”电子书。。。当然了，百度文库也是很重要一个的罪恶之源</li>
<li>找ppt: slideshare</li>
<li>鉴别网图：TinEye</li>
<li>找最新最新update：微博（新浪、腾讯，等等）、Google实时搜索（主要数据来源是推特）</li>
<li>找飞机票、火车票、旅游信息：酷讯、去哪儿、途牛，等等</li>
<li>其他，自己Google搜索：“垂直搜索”。</li>
</ul>
<p>我常用的都已经列在上面了，按重要性程度依次递减。</p>
<p>再有，就是搜索关键词的质量！虽然搜索引擎现在越来越智能，越来越懂中文，但你也不能用“垃圾”关键词来虐搜索引擎的那个框。。。</p>
<p>什么样的关键词会被称为“垃圾”？简单来说，别人能搜到的结果，你搜不到，那你就是输入“垃圾”关键词了。</p>
<p>怎样提高搜索关键词的质量？我总结了几条还算不错的个人经验吧。</p>
<ul>
<li>“特征签名/模板信息”直接复制+粘贴，最典型的就是程序员遇到的编译器错误提示信息，系统管理员遇到的日志错误信息，等等。</li>
<li>总结一些重要的个人黄金关键词。比如我的一些最爱关键词：cheatsheet、tutorial、howto等等，之所以只列举英文关键词，可能和我个人的搜索习惯有吧。在我看来，计算机类的问题确实还是英文的搜索结果往往更贴近我的问题的答案。特别是这两年，stackoverflow.com这样的专业计算机类问答网站的出现，你会发现这是真正的广大程序员、IT人士的福音。</li>
<li>善于使用搜索引擎高级技巧中的一些信息精简功能。例如限制只搜索pdf、doc，限制搜索结果的时间范围，限制只搜索某个站点，等等。很多时候，不是没找到答案。而是答案太多了，无从下手。</li>
</ul>
<p>最后，其实最重要了，搜索精华结果信息来源的“follow”。这句话怎么说呢？比如你查到一篇博客文章，解决了你的问题。你有没有想过，再看看这篇博客的其他文章？更进一步，看了之后，有没有意识到这个博客上的文章内容和你的研究方向/工作内容相关性较大？ok，为什么不订阅他的博客feed呢？我们不能因为解决了问题，就认为ok了。好文章不常有，好博主更是少有的哦。IT技术，日新月异，如果你不能保持自动更新，很快你就会成为奥特曼，再过一段时间，你面临的可能就是失业了。搜索引擎之所以能解决问题，并不是因为搜索技术有多强大，而是有千千万万的用户在贡献内容，奉献精华。内容为王！</p>
<p>现在虽然出现了很多优秀的社会化内容推荐和分享系统、应用，但在我兲朝，所有的UGC（用户产生内容）网站都很难长命。所以，该靠自己的时候，还是要靠自己。紧跟行业领袖，向业界的先进工作者学习是“傻瓜”成长的必由之路。</p>
<p>搜索技术是解决你眼前的问题，RSS订阅和阅读是解决你成长的问题。微博时代，又增加了follow学习之道。</p>
<p>总结一下，善用搜索包括了搜索前、搜索中、搜索后三个阶段的工作。</p>
<p>搜索前，要确定好“去哪儿搜”？</p>
<p>搜索中，要确定“搜什么关键词”？</p>
<p>搜索后，要确定“是否有必要保存信息来源”？
<div style="margin-top: 15px; ">
<hr style="border: 1px solid #cccccc;"/>
<p><strong>原创文章，转载请注明：</strong> 转载自<a href="http://www.huangwei.me/blog/">猪在笑</a> <a href="http://www.huangwei.me/blog/">[ http://www.huangwei.me/blog/ ]</a><br/><strong>本文链接地址:</strong> <a href="http://www.huangwei.me/blog/2011/03/19/learn-to-search-is-vital/">http://www.huangwei.me/blog/2011/03/19/learn-to-search-is-vital/</a></p>
<hr style="border: 1px solid #cccccc;"/>
</div>
<div  class="related_post_title">您可能还对以下文章感兴趣</div><ul class="related_post"><li><a href="http://www.huangwei.me/blog/2011/03/18/development-of-good-habits/" title="好习惯不是养出来的，是逼出来的">好习惯不是养出来的，是逼出来的</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.huangwei.me/blog/2011/03/19/learn-to-search-is-vital/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>好习惯不是养出来的，是逼出来的</title>
		<link>http://www.huangwei.me/blog/2011/03/18/development-of-good-habits/</link>
		<comments>http://www.huangwei.me/blog/2011/03/18/development-of-good-habits/#comments</comments>
		<pubDate>Fri, 18 Mar 2011 14:40:08 +0000</pubDate>
		<dc:creator>c4pr1c3</dc:creator>
				<category><![CDATA[纯净水]]></category>
		<category><![CDATA[习惯养成]]></category>
		<category><![CDATA[好习惯]]></category>
		<category><![CDATA[成长积淀]]></category>

		<guid isPermaLink="false">http://www.huangwei.me/blog/?p=993</guid>
		<description><![CDATA[<p>我承认这个标题是唬人的，但以下我要说的确实都是自己的真实成长案例。从这些自己的亲身经历中，我确实体会到了“好习惯不是养出来的，是逼出来的。”</p>
<p><strong>案例一：及时洗衣服（坏习惯强迫）</strong></p>
<p>上大学时，很多男生寝室总是“臭气”熏天，这“臭气”的来源嘛其实就是堆在某个角落的脏衣服、臭袜子，whatever。许多人也许会说，这是男生“懒”的表现。确实，我也懒过。一次偶然的“事故”，我的两个盆被摔坏了一个。懒得去再买一个盆，于是我养成了一个“坏”习惯：一个盆，既当脸盆，又当脚盆。不过，在养成坏习惯的同时，我很快发现我改掉了堆积脏衣服的“坏习惯”，养成了脏衣服即脱即洗的好习惯。为什么呢？只有一个盆呀！衣服堆盆里，不洗的话，早晨洗漱的时候特别麻烦。</p>
<p>于是，在不知不觉之中，我被自己的懒逼的“勤快”了起来，大学毕业前再也没有堆脏衣服的习惯了。毕业后嘛，由于某人勤快的给我买了个脏衣框，所以我就。。。</p>
<p><span style="color: #ff0000">经验与教训：如果你特别想养成一个好习惯，最快见效的方法就是用另一个自己特别乐意的坏习惯来强迫你自己，让自己心甘情愿的“养成”好习惯！不过友情提醒一下，小心别人帮你帮你改了你的那个驱动力“坏习惯”，从而导致好不容易养成的好习惯瞬间付之东流。</span></p>
<p><strong>案例二：早起（环境强迫）</strong></p>
<p>很多人都有这种体会，如果是自己“要求”自己做一件事情的时候，如果这件事情对自己没啥好处的话，一般自己都会用各种理由来“搪塞”自己，推延磨蹭。但如果是你“主动答应”别人做的事情或者“上级指示”或者“硬性规定”，你却总能“硬着头皮”把事情扛下来。这就是为什么上班族每天能够早起挤公交、挤地铁，只为上班别迟到，别扣钱。大学生日晒三杆才睁眼，因为迟到、旷课没人罚，没人管。这就是环境强迫与不强迫你的差别。</p>
<p>我的早上准时起床经验就是：用两个闹铃，设置相同的闹铃时间，不同的铃音，分别放在我睡觉时伸手够不到的两个地方。这就算是自己给自己设置了一个强迫的早起环境吧。我不下床，就不能关掉闹铃，闹铃就会一直在那儿响啊响。再不关？老婆一脚就把我从床上踹起来了。下床关闹铃吧，关掉2个，我也差不多清醒了，想再睡个回笼觉都困难了。久而久之，我就习惯早上准时起床了。现在基本我醒的时间都能和闹铃同步，睡眠质量反而更高了。</p>
<p><strong>案例三：每天记日志（虚荣心强迫）</strong></p>
<p>很多人一定会觉得每天坚持写日志是一件很难的事情，因为稍不留神就会“忘了”写。以前我也是这么认为的，不过自从进了实验室之后，我开始发现，不记日志，每周写周报的时候特别痛苦。特别是明明自己一周干了很多事情，但如果没有日志的支持，写周报的时候经常会有所遗漏。明明是自己做了的事情，却没有“汇报”，总觉得自己很亏。于是开始坚持每天记日志，当然偶尔也会有当天遗忘记录的，但第二天一定会赶紧补上前一天的日志。渐渐的，我的周报内容越来越丰满，老板满意自然给你的脸色就好，你也就感觉“倍有面子”，而且坚持时间久了之后，经常翻翻以前的日志本身就会带来一种很自然的自我满足感。虽然现在我已经不需要给老板写周报了，但日志还是每天在记。不为别的，就是为了自己的这点“自我满足感”。</p>
<p><strong>后记</strong></p>
<p>这篇文章也是一篇拖了很久的草稿，之前写了个提纲，就放在草稿箱了。今天翻出来写完这个草稿，是有感于今天和老妈的一次聊天，谈到了家里的小字辈的一些所谓“坏习惯”，让我想到了自己的这些“好习惯”是如何被“逼”出来的，有必要给我的小弟小妹们分享一下。在我看来，好习惯确实不是靠“养”就能养出来的，你今天订了一个好习惯列表，坚持了三天，三个月，你就可以宣称“养成”了？你以为你是在玩“养成类”游戏了吧，还通关了呢。我自以为一个好习惯的“养成”一定是有一些因素“强迫”，被逼出来的。这就像喝水，吃饭一样。没人会说喝水，吃饭需要“养成”吧？因为不喝水，不吃饭你会死。你迫于生存必须喝水，吃饭，而且你能坚持一生。所以，要“养成”一个好习惯，就赶紧找一个“被逼”的理由吧。</p>
<p><strong>后记的补充</strong></p>
<p>我的文字水平有限，全是大白话，且无任何理论依据和方法论总结，我再分享几篇我看过的关于好习惯养成的好文，以飨读者。</p>
<ul>
<li><a href="http://www.mifengtd.cn/articles/what-is-a-habit-and-how-to-culture-a-good-habit.html" target="_blank">褪墨：让我们“晒”习惯</a></li>
<li><a href="http://www.mifengtd.cn/articles/culture-a-habit-in-a-month.html" target="_blank">褪墨：一个月培养一个好习惯</a></li>
<li><a href="http://www.chedong.com/blog/archives/001060.html" target="_blank">34个好习惯</a></li>
</ul>]]></description>
			<content:encoded><![CDATA[<div style="margin-top: 2px;">
<A href="http://creativecommons.org/licenses/by/3.0/deed.zh"><FONT color=#11779f><STRONG>版权声明</STRONG></FONT></A><FONT color=#11779f><STRONG>：可以任意转载，转载时请务必以超链接形式标明文章原始出处和<a href="http://www.huangwei.me/blog/">作者信息</a></STRONG></FONT>
</div>
<p>我承认这个标题是唬人的，但以下我要说的确实都是自己的真实成长案例。从这些自己的亲身经历中，我确实体会到了“好习惯不是养出来的，是逼出来的。”</p>
<p><strong>案例一：及时洗衣服（坏习惯强迫）</strong></p>
<p>上大学时，很多男生寝室总是“臭气”熏天，这“臭气”的来源嘛其实就是堆在某个角落的脏衣服、臭袜子，whatever。许多人也许会说，这是男生“懒”的表现。确实，我也懒过。一次偶然的“事故”，我的两个盆被摔坏了一个。懒得去再买一个盆，于是我养成了一个“坏”习惯：一个盆，既当脸盆，又当脚盆。不过，在养成坏习惯的同时，我很快发现我改掉了堆积脏衣服的“坏习惯”，养成了脏衣服即脱即洗的好习惯。为什么呢？只有一个盆呀！衣服堆盆里，不洗的话，早晨洗漱的时候特别麻烦。</p>
<p>于是，在不知不觉之中，我被自己的懒逼的“勤快”了起来，大学毕业前再也没有堆脏衣服的习惯了。毕业后嘛，由于某人勤快的给我买了个脏衣框，所以我就。。。</p>
<p><span style="color: #ff0000">经验与教训：如果你特别想养成一个好习惯，最快见效的方法就是用另一个自己特别乐意的坏习惯来强迫你自己，让自己心甘情愿的“养成”好习惯！不过友情提醒一下，小心别人帮你帮你改了你的那个驱动力“坏习惯”，从而导致好不容易养成的好习惯瞬间付之东流。</span></p>
<p><strong>案例二：早起（环境强迫）</strong></p>
<p>很多人都有这种体会，如果是自己“要求”自己做一件事情的时候，如果这件事情对自己没啥好处的话，一般自己都会用各种理由来“搪塞”自己，推延磨蹭。但如果是你“主动答应”别人做的事情或者“上级指示”或者“硬性规定”，你却总能“硬着头皮”把事情扛下来。这就是为什么上班族每天能够早起挤公交、挤地铁，只为上班别迟到，别扣钱。大学生日晒三杆才睁眼，因为迟到、旷课没人罚，没人管。这就是环境强迫与不强迫你的差别。</p>
<p>我的早上准时起床经验就是：用两个闹铃，设置相同的闹铃时间，不同的铃音，分别放在我睡觉时伸手够不到的两个地方。这就算是自己给自己设置了一个强迫的早起环境吧。我不下床，就不能关掉闹铃，闹铃就会一直在那儿响啊响。再不关？老婆一脚就把我从床上踹起来了。下床关闹铃吧，关掉2个，我也差不多清醒了，想再睡个回笼觉都困难了。久而久之，我就习惯早上准时起床了。现在基本我醒的时间都能和闹铃同步，睡眠质量反而更高了。</p>
<p><strong>案例三：每天记日志（虚荣心强迫）</strong></p>
<p>很多人一定会觉得每天坚持写日志是一件很难的事情，因为稍不留神就会“忘了”写。以前我也是这么认为的，不过自从进了实验室之后，我开始发现，不记日志，每周写周报的时候特别痛苦。特别是明明自己一周干了很多事情，但如果没有日志的支持，写周报的时候经常会有所遗漏。明明是自己做了的事情，却没有“汇报”，总觉得自己很亏。于是开始坚持每天记日志，当然偶尔也会有当天遗忘记录的，但第二天一定会赶紧补上前一天的日志。渐渐的，我的周报内容越来越丰满，老板满意自然给你的脸色就好，你也就感觉“倍有面子”，而且坚持时间久了之后，经常翻翻以前的日志本身就会带来一种很自然的自我满足感。虽然现在我已经不需要给老板写周报了，但日志还是每天在记。不为别的，就是为了自己的这点“自我满足感”。</p>
<p><strong>后记</strong></p>
<p>这篇文章也是一篇拖了很久的草稿，之前写了个提纲，就放在草稿箱了。今天翻出来写完这个草稿，是有感于今天和老妈的一次聊天，谈到了家里的小字辈的一些所谓“坏习惯”，让我想到了自己的这些“好习惯”是如何被“逼”出来的，有必要给我的小弟小妹们分享一下。在我看来，好习惯确实不是靠“养”就能养出来的，你今天订了一个好习惯列表，坚持了三天，三个月，你就可以宣称“养成”了？你以为你是在玩“养成类”游戏了吧，还通关了呢。我自以为一个好习惯的“养成”一定是有一些因素“强迫”，被逼出来的。这就像喝水，吃饭一样。没人会说喝水，吃饭需要“养成”吧？因为不喝水，不吃饭你会死。你迫于生存必须喝水，吃饭，而且你能坚持一生。所以，要“养成”一个好习惯，就赶紧找一个“被逼”的理由吧。</p>
<p><strong>后记的补充</strong></p>
<p>我的文字水平有限，全是大白话，且无任何理论依据和方法论总结，我再分享几篇我看过的关于好习惯养成的好文，以飨读者。</p>
<ul>
<li><a href="http://www.mifengtd.cn/articles/what-is-a-habit-and-how-to-culture-a-good-habit.html" target="_blank">褪墨：让我们“晒”习惯</a></li>
<li><a href="http://www.mifengtd.cn/articles/culture-a-habit-in-a-month.html" target="_blank">褪墨：一个月培养一个好习惯</a></li>
<li><a href="http://www.chedong.com/blog/archives/001060.html" target="_blank">34个好习惯</a></li>
</ul>
<div style="margin-top: 15px; ">
<hr style="border: 1px solid #cccccc;"/>
<p><strong>原创文章，转载请注明：</strong> 转载自<a href="http://www.huangwei.me/blog/">猪在笑</a> <a href="http://www.huangwei.me/blog/">[ http://www.huangwei.me/blog/ ]</a><br/><strong>本文链接地址:</strong> <a href="http://www.huangwei.me/blog/2011/03/18/development-of-good-habits/">http://www.huangwei.me/blog/2011/03/18/development-of-good-habits/</a></p>
<hr style="border: 1px solid #cccccc;"/>
</div>
<div  class="related_post_title">您可能还对以下文章感兴趣</div><ul class="related_post"><li><a href="http://www.huangwei.me/blog/2011/03/19/learn-to-search-is-vital/" title="善用搜索是从傻瓜到砖家的第一步">善用搜索是从傻瓜到砖家的第一步</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.huangwei.me/blog/2011/03/18/development-of-good-habits/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>邮件沟通的艺术和技术</title>
		<link>http://www.huangwei.me/blog/2011/03/09/art-of-communication-in-email/</link>
		<comments>http://www.huangwei.me/blog/2011/03/09/art-of-communication-in-email/#comments</comments>
		<pubDate>Wed, 09 Mar 2011 11:40:47 +0000</pubDate>
		<dc:creator>c4pr1c3</dc:creator>
				<category><![CDATA[纯净水]]></category>
		<category><![CDATA[沟通技巧]]></category>
		<category><![CDATA[邮件沟通]]></category>
		<category><![CDATA[邮件礼仪]]></category>

		<guid isPermaLink="false">http://www.huangwei.me/blog/?p=984</guid>
		<description><![CDATA[<span style="font-family: arial,helvetica,sans-serif"><span style="color: #ff0000">update:2011/03/30 今天看到一个让我深有同感，说出我心声的邮件：</span><a href="http://tech2ipo.com/5303" target="_blank"><span style="color: #ff0000">《千万不要写长邮件》</span></a></span>。

最近因为工作的原因，我每天都要处理数量可观的邮件和简历。许多优秀的学生简历其实很漂亮，内容充实，过往表现可圈可点，但简历的精彩无法遮掩他/她邮件的丑陋“外表”。如果是一个“外貌”协会的会员来处理这个邮件，最可能执行的操作就是“批量已读”，甚至是“标记为垃圾邮件”。

一封邮件的“外表”都包括些什么呢？什么样的外表会让人眼前一亮，让人有继续阅读的兴趣呢？下面让我从写一封邮件的正常流程来逐步谈谈我的一些体会。
<h2>发件人（From）</h2>
很多人都会忽略这个细节，特别是对于那些使用Web Mail来发邮件的人来说，可能都没有意识到这个字段。举例来说，很多人使用QQ邮箱来发邮件，QQ邮箱会默认使用你的QQ昵称作为发件人的姓名。于是，有些人就杯具了。从一个老师的角度来说，如果我收到一封简历，发件人写的是 <span style="color: #ff0000">牛13 &#60;10000@qq.com&#62;</span>，我一定会对发件人“轻看”一分的，不够专业。
<h2>收件人（To）</h2>
收件人肯定是需要发件人指定的，如果不明确收件人的完整、准确姓名，直接填写对方的邮箱地址最稳妥的。如果非要给收件人邮箱地址扣上个“帽子”，切记不要“张冠李戴”，没有人会喜欢自己的名字被别人乱写吧？
<h2>抄送（CC）</h2>
如果你的这封邮件需要多个人阅读，但并不是每个人都需要去实际处理这个邮件中所提到的事情，你只是需要“告知”其他收件人：“我和收件人之间有这封邮件通信的凭证，需要你知晓这件事情的存在性”。这就是抄送对象存在的意义。职场里有这样一个不成文的规定，抄送对象的重要性程度决定了这封邮件的重要性程度。试想，你如果在发送邮件时抄送我们敬爱的胡主席一份，那这封邮件的重要性是不是不言自明？
<h2>密送（BCC）</h2>
密送和抄送的唯一区别就是，密送的邮件地址不会被收件人“察觉”到。使用的概率相比较CC要小很多。
<h2>主题（Subject）</h2>
首先需要认识到的是主题一定不要留空，“无主题”邮件是随意的表现。上级给下级“无主题”邮件，不会有啥影响。可如果你是有事相求，“无主题”只会让收件人感到被藐视。

再有，主题的精髓是“精准、概要”，引起收件人注意。在这里最忌讳的是使用花里胡哨的主题，例如使用大量特殊符号堆砌，似乎本意也是吸引收件人注意，实则让人生厌。

如果收件人对主题的格式已有要求，务必严格遵守执行。因为，收件人很可能在处理邮件的客户端上使用了邮件过滤规则，自动对邮件进行分类。不符合格式要求的主题的下场就是被收件人“自动”忽略。
<h2>正文</h2>
我个人对邮件正文书写的最大体会可以总结为12个字：有礼有节、条理清楚、重点突出。

<strong>有礼有节</strong>：首次给对方发邮件或是正式场合邮件，一定要在邮件的一开始礼貌称呼，“你好/您好/你们好”总有一个适合你，但不要“您们好”，语法错误，读起来更别扭。礼貌招呼完，进入正文后，务求篇幅有节制。收件人级别越高，重要性程度越高的邮件，正文内容的篇幅越要务求简短。只有情书是越长越好的，正式邮件越短越好。当然了，前提一定是把事情交待清楚了。正文写完后，可以酌情使用“祝好！”、“致礼！”等表达感谢、祝愿的措辞，也算是贯彻了礼貌贯穿全文。

<strong>条理清楚</strong>：要想让邮件内容短小精炼，最好的办法就是采用列表的方法，1、2、3、4、5。。。一件一件，一条一条。每一条有一个短标题的话，表达效果更佳。看邮件，不是看小说。邮件内容不能像小说剧情那样跌宕起伏，峰回路转的。列表式邮件的另一个重要好处，就是方便收件人逐条回复。

<strong>重点突出</strong>：虽然邮件越短越好，但有时候确实需要多一些篇幅来说事情，那怎么办呢？我的建议是可以使用格式化，粗体、颜色、高亮背景等都是可选的突出重点的形式化方法。这里唯一需要注意的是，突出重点不能变成“水彩画”，适度原则必须严格执行。
<h2>签名</h2>
在Gmail出现之前，国内的很多免费邮箱都喜欢给你的发出邮件自动的加上一个“邮箱签名”。如果只是纯粹推广邮箱也就罢了，如果是一个“性病治疗”广告呢？这也许就是那时候收费邮箱存在的一个“市场价值”吧。

好了，现在的主流免费邮箱都不会打你的邮件签名的主意了，你的邮件签名终于可以你自己做主了，写些什么呢？我的建议是：姓名、单位、联系方式（手机）是最有意义的签名内容，中英文对照、格式化的签名可以为你的邮件多增加几分“职业感”。
<h2>附件</h2>
大小、格式、文件命名是附件的三要素。虽然现在主流免费邮箱的附件大小是越来越大，甚至还有个别邮件服务提供商的G级别附件的“噱头”，但在现实的正式邮件沟通场合中，5MB以内的邮件附件大小还是相对安全的传送标准，如果是简历之类的附件则是100KB以内为佳。如果要在Word之中插入图片，务必先对图片进行压缩处理，不要以为在Word中调整一下图片“大小”就ok了。

格式的通用性是附件需要考虑的，在不了解收件人的邮件处理终端配置时，尽可能用大众化的附件格式。例如，能用zip就不用rar，能用pdf就不用doc，能用txt就不用doc，等等。

文件命名也有讲究，可以参考本文中“主题”一节的说明。“新建文档.doc”是会被赤裸裸鄙视的。
<h2>自动回复</h2>
有些人喜欢设置邮件的自动回复，似乎本意是为了让人感觉到自己的勤奋。但假如你把本应该给你爱人的自动邮件回复设置成了全局自动邮件回复，你的老板因此收到了你的“情意绵绵”邮件回复会是怎样一种思想感情？

如果你非要使用邮件自动回复，我的建议一是使用过滤器，根据邮件规则有针对性的自动回复。建议二则是使用更通用的自动回复，并在邮件标题中标识本邮件是“自动回复”。例如这样的自动回复邮件正文是不会给你添麻烦的：您发来的信件已经收到，看完后我会及时回复。十分感谢！
<h2><strong>反面案例</strong>
<strong> </strong></h2>
<strong>1. 发送超大附件</strong>
同学甲把自己的本科成绩单的扫描原件（BMP格式，8MB）试图通过邮件的方式发送到我的邮箱。我很理解这位同学的“坦诚”本意，但从邮件系统的可靠传输角度来看，这样做是很不明智的。至少，我的学校邮箱就对这封“大附件”邮件进行了“延迟”接收（发件日期和实际接收到的日期前后相差了10天！！）操作。

<strong>2. 让人莫名其明的邮件个性签名</strong>
同学乙用了一个美女头像作为自己的邮件个性签名。在邮件中使用个性签名很平常，但请务必确认你所发出的邮件签名要传递的是什么信息，是否和你的此次邮件通信相关。

<strong>3. 不完整邮件</strong>
这类邮件大约占到了所有保研咨询邮件的1/3。所谓不完整邮件包括没有在来信附上个人简历、没有在来信留下联系方式、没有说自己是谁（这点最汗。。。）。通常，对这类邮件我只能千篇一律的回复说“请补充完整个人信息/个人简历，blabla。。。”。你咨询保研/考研，怎么能不说明一下自己的基本情况呢？完整的个人基本信息是一个成功的“陶瓷”信的前提。

感兴趣的读者还可以移步我之前在北邮人论坛的这篇文章：<a href="http://bbs.byr.cn/article/AimGraduate/488140" target="_blank">[原创心得]保研/考研时联系导师的艺术和技术</a>]]></description>
			<content:encoded><![CDATA[<div style="margin-top: 2px;">
<A href="http://creativecommons.org/licenses/by/3.0/deed.zh"><FONT color=#11779f><STRONG>版权声明</STRONG></FONT></A><FONT color=#11779f><STRONG>：可以任意转载，转载时请务必以超链接形式标明文章原始出处和<a href="http://www.huangwei.me/blog/">作者信息</a></STRONG></FONT>
</div>
<p><span style="font-family: arial,helvetica,sans-serif"><span style="color: #ff0000">update:2011/03/30 今天看到一个让我深有同感，说出我心声的邮件：</span><a href="http://tech2ipo.com/5303" target="_blank"><span style="color: #ff0000">《千万不要写长邮件》</span></a></span>。</p>
<p>最近因为工作的原因，我每天都要处理数量可观的邮件和简历。许多优秀的学生简历其实很漂亮，内容充实，过往表现可圈可点，但简历的精彩无法遮掩他/她邮件的丑陋“外表”。如果是一个“外貌”协会的会员来处理这个邮件，最可能执行的操作就是“批量已读”，甚至是“标记为垃圾邮件”。</p>
<p>一封邮件的“外表”都包括些什么呢？什么样的外表会让人眼前一亮，让人有继续阅读的兴趣呢？下面让我从写一封邮件的正常流程来逐步谈谈我的一些体会。</p>
<h2>发件人（From）</h2>
<p>很多人都会忽略这个细节，特别是对于那些使用Web Mail来发邮件的人来说，可能都没有意识到这个字段。举例来说，很多人使用QQ邮箱来发邮件，QQ邮箱会默认使用你的QQ昵称作为发件人的姓名。于是，有些人就杯具了。从一个老师的角度来说，如果我收到一封简历，发件人写的是 <span style="color: #ff0000">牛13 &lt;10000@qq.com&gt;</span>，我一定会对发件人“轻看”一分的，不够专业。</p>
<h2>收件人（To）</h2>
<p>收件人肯定是需要发件人指定的，如果不明确收件人的完整、准确姓名，直接填写对方的邮箱地址最稳妥的。如果非要给收件人邮箱地址扣上个“帽子”，切记不要“张冠李戴”，没有人会喜欢自己的名字被别人乱写吧？</p>
<h2>抄送（CC）</h2>
<p>如果你的这封邮件需要多个人阅读，但并不是每个人都需要去实际处理这个邮件中所提到的事情，你只是需要“告知”其他收件人：“我和收件人之间有这封邮件通信的凭证，需要你知晓这件事情的存在性”。这就是抄送对象存在的意义。职场里有这样一个不成文的规定，抄送对象的重要性程度决定了这封邮件的重要性程度。试想，你如果在发送邮件时抄送我们敬爱的胡主席一份，那这封邮件的重要性是不是不言自明？</p>
<h2>密送（BCC）</h2>
<p>密送和抄送的唯一区别就是，密送的邮件地址不会被收件人“察觉”到。使用的概率相比较CC要小很多。</p>
<h2>主题（Subject）</h2>
<p>首先需要认识到的是主题一定不要留空，“无主题”邮件是随意的表现。上级给下级“无主题”邮件，不会有啥影响。可如果你是有事相求，“无主题”只会让收件人感到被藐视。</p>
<p>再有，主题的精髓是“精准、概要”，引起收件人注意。在这里最忌讳的是使用花里胡哨的主题，例如使用大量特殊符号堆砌，似乎本意也是吸引收件人注意，实则让人生厌。</p>
<p>如果收件人对主题的格式已有要求，务必严格遵守执行。因为，收件人很可能在处理邮件的客户端上使用了邮件过滤规则，自动对邮件进行分类。不符合格式要求的主题的下场就是被收件人“自动”忽略。</p>
<h2>正文</h2>
<p>我个人对邮件正文书写的最大体会可以总结为12个字：有礼有节、条理清楚、重点突出。</p>
<p><strong>有礼有节</strong>：首次给对方发邮件或是正式场合邮件，一定要在邮件的一开始礼貌称呼，“你好/您好/你们好”总有一个适合你，但不要“您们好”，语法错误，读起来更别扭。礼貌招呼完，进入正文后，务求篇幅有节制。收件人级别越高，重要性程度越高的邮件，正文内容的篇幅越要务求简短。只有情书是越长越好的，正式邮件越短越好。当然了，前提一定是把事情交待清楚了。正文写完后，可以酌情使用“祝好！”、“致礼！”等表达感谢、祝愿的措辞，也算是贯彻了礼貌贯穿全文。</p>
<p><strong>条理清楚</strong>：要想让邮件内容短小精炼，最好的办法就是采用列表的方法，1、2、3、4、5。。。一件一件，一条一条。每一条有一个短标题的话，表达效果更佳。看邮件，不是看小说。邮件内容不能像小说剧情那样跌宕起伏，峰回路转的。列表式邮件的另一个重要好处，就是方便收件人逐条回复。</p>
<p><strong>重点突出</strong>：虽然邮件越短越好，但有时候确实需要多一些篇幅来说事情，那怎么办呢？我的建议是可以使用格式化，粗体、颜色、高亮背景等都是可选的突出重点的形式化方法。这里唯一需要注意的是，突出重点不能变成“水彩画”，适度原则必须严格执行。</p>
<h2>签名</h2>
<p>在Gmail出现之前，国内的很多免费邮箱都喜欢给你的发出邮件自动的加上一个“邮箱签名”。如果只是纯粹推广邮箱也就罢了，如果是一个“性病治疗”广告呢？这也许就是那时候收费邮箱存在的一个“市场价值”吧。</p>
<p>好了，现在的主流免费邮箱都不会打你的邮件签名的主意了，你的邮件签名终于可以你自己做主了，写些什么呢？我的建议是：姓名、单位、联系方式（手机）是最有意义的签名内容，中英文对照、格式化的签名可以为你的邮件多增加几分“职业感”。</p>
<h2>附件</h2>
<p>大小、格式、文件命名是附件的三要素。虽然现在主流免费邮箱的附件大小是越来越大，甚至还有个别邮件服务提供商的G级别附件的“噱头”，但在现实的正式邮件沟通场合中，5MB以内的邮件附件大小还是相对安全的传送标准，如果是简历之类的附件则是100KB以内为佳。如果要在Word之中插入图片，务必先对图片进行压缩处理，不要以为在Word中调整一下图片“大小”就ok了。</p>
<p>格式的通用性是附件需要考虑的，在不了解收件人的邮件处理终端配置时，尽可能用大众化的附件格式。例如，能用zip就不用rar，能用pdf就不用doc，能用txt就不用doc，等等。</p>
<p>文件命名也有讲究，可以参考本文中“主题”一节的说明。“新建文档.doc”是会被赤裸裸鄙视的。</p>
<h2>自动回复</h2>
<p>有些人喜欢设置邮件的自动回复，似乎本意是为了让人感觉到自己的勤奋。但假如你把本应该给你爱人的自动邮件回复设置成了全局自动邮件回复，你的老板因此收到了你的“情意绵绵”邮件回复会是怎样一种思想感情？</p>
<p>如果你非要使用邮件自动回复，我的建议一是使用过滤器，根据邮件规则有针对性的自动回复。建议二则是使用更通用的自动回复，并在邮件标题中标识本邮件是“自动回复”。例如这样的自动回复邮件正文是不会给你添麻烦的：您发来的信件已经收到，看完后我会及时回复。十分感谢！</p>
<h2><strong>反面案例</strong><br />
<strong> </strong></h2>
<p><strong>1. 发送超大附件</strong><br />
同学甲把自己的本科成绩单的扫描原件（BMP格式，8MB）试图通过邮件的方式发送到我的邮箱。我很理解这位同学的“坦诚”本意，但从邮件系统的可靠传输角度来看，这样做是很不明智的。至少，我的学校邮箱就对这封“大附件”邮件进行了“延迟”接收（发件日期和实际接收到的日期前后相差了10天！！）操作。</p>
<p><strong>2. 让人莫名其明的邮件个性签名</strong><br />
同学乙用了一个美女头像作为自己的邮件个性签名。在邮件中使用个性签名很平常，但请务必确认你所发出的邮件签名要传递的是什么信息，是否和你的此次邮件通信相关。</p>
<p><strong>3. 不完整邮件</strong><br />
这类邮件大约占到了所有保研咨询邮件的1/3。所谓不完整邮件包括没有在来信附上个人简历、没有在来信留下联系方式、没有说自己是谁（这点最汗。。。）。通常，对这类邮件我只能千篇一律的回复说“请补充完整个人信息/个人简历，blabla。。。”。你咨询保研/考研，怎么能不说明一下自己的基本情况呢？完整的个人基本信息是一个成功的“陶瓷”信的前提。</p>
<p>感兴趣的读者还可以移步我之前在北邮人论坛的这篇文章：<a href="http://bbs.byr.cn/article/AimGraduate/488140" target="_blank">[原创心得]保研/考研时联系导师的艺术和技术</a>
<div style="margin-top: 15px; ">
<hr style="border: 1px solid #cccccc;"/>
<p><strong>原创文章，转载请注明：</strong> 转载自<a href="http://www.huangwei.me/blog/">猪在笑</a> <a href="http://www.huangwei.me/blog/">[ http://www.huangwei.me/blog/ ]</a><br/><strong>本文链接地址:</strong> <a href="http://www.huangwei.me/blog/2011/03/09/art-of-communication-in-email/">http://www.huangwei.me/blog/2011/03/09/art-of-communication-in-email/</a></p>
<hr style="border: 1px solid #cccccc;"/>
</div>
<div  class="related_post_title">随机日志</div><ul class="related_post"><li><a href="http://www.huangwei.me/blog/2011/01/06/write_zotero_translator/" title="[原创Zotero系列教程之六]编写翻译器">[原创Zotero系列教程之六]编写翻译器</a></li><li><a href="http://www.huangwei.me/blog/2006/06/29/javascriptieueoaaeoeodhauaoo-2/" title="javascript动态生成页面元素心得[部分原创]">javascript动态生成页面元素心得[部分原创]</a></li><li><a href="http://www.huangwei.me/blog/2008/03/17/security-in-ie7-ie8/" title="Security In IE7 &#38; IE8">Security In IE7 &#38; IE8</a></li><li><a href="http://www.huangwei.me/blog/2009/07/07/%e6%8e%a8%e8%8d%90web%e7%95%8c%e9%9d%a2%e5%8e%9f%e5%9e%8b%e8%ae%be%e8%ae%a1%e5%b7%a5%e5%85%b7%e2%80%94%e2%80%94mockups/" title="推荐Web界面原型设计工具——Mockups">推荐Web界面原型设计工具——Mockups</a></li><li><a href="http://www.huangwei.me/blog/2006/06/29/oioudhuao-2/" title="猪在笑的出处">猪在笑的出处</a></li><li><a href="http://www.huangwei.me/blog/2011/02/05/cert-secure-coding-standard-3/" title="[译]CERT Secure Coding Standard — C语言安全编程规范(3)">[译]CERT Secure Coding Standard — C语言安全编程规范(3)</a></li><li><a href="http://www.huangwei.me/blog/2008/12/09/%e7%81%8c%e6%b0%b4%e4%b8%80%e7%af%87/" title="灌水一篇">灌水一篇</a></li><li><a href="http://www.huangwei.me/blog/2010/02/20/ubuntu-keyboard-shortcuts/" title="Ubuntu中你可能不知道的一些有用的键盘快捷键">Ubuntu中你可能不知道的一些有用的键盘快捷键</a></li><li><a href="http://www.huangwei.me/blog/2008/08/25/%e5%8e%9f%e5%88%9bvim%e5%ad%97%e5%85%b8%e6%96%87%e4%bb%b6%e8%87%aa%e5%8a%a8%e6%8f%90%e5%8f%96%e5%b7%a5%e5%85%b7/" title="[原创]vim字典文件自动提取工具">[原创]vim字典文件自动提取工具</a></li><li><a href="http://www.huangwei.me/blog/2010/06/28/thanks-to-the-young/" title="毕业了，感谢我的师弟师妹们">毕业了，感谢我的师弟师妹们</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.huangwei.me/blog/2011/03/09/art-of-communication-in-email/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[译]CERT Secure Coding Standard — C语言安全编程规范(5)</title>
		<link>http://www.huangwei.me/blog/2011/02/06/cert-secure-coding-standard/</link>
		<comments>http://www.huangwei.me/blog/2011/02/06/cert-secure-coding-standard/#comments</comments>
		<pubDate>Sun, 06 Feb 2011 05:27:43 +0000</pubDate>
		<dc:creator>c4pr1c3</dc:creator>
				<category><![CDATA[安全技术]]></category>
		<category><![CDATA[CERT Secure Coding Standard]]></category>
		<category><![CDATA[C语言安全编程规范]]></category>
		<category><![CDATA[C语言编程安全规范]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[编程规范]]></category>

		<guid isPermaLink="false">http://www.huangwei.me/blog/?p=911</guid>
		<description><![CDATA[<h2>写在最后的话</h2>
<p>规范很精彩，评论更精彩。很多建议和规则虽然本身写的有瑕疵，但是当你看了建议/规则页的评论之后，你会发现你并不是第一个提问的人。很多时候你的疑问和疑惑别人已经给你解答了。在我看来，CERT的这个C语言安全编程规范的最重要的意义不是告诉你怎样使用C语言编写一个“无漏洞”的系统，重要的是通过阅读这个规范，你会知道怎样使用C语言会编写出一个“有漏洞”的系统。和很多安全编程规范一样，《CERT Secure Coding Standard》不是要告诉你"What to do"，而是让你知道"What is bad"。</p>
<p>《CERT Secure Coding Standard》中有很多建议/规则都是面向“可移植”代码需求写的，对于确定性的运行在某一个专有平台上，没有代码可移植性需求的C程序员来说，要特别留意不同平台上的一些比较tricky的情况。虽然代码并不总是跨平台的，但程序员却有很大可能性跨平台的。一旦养成了某个平台上的一些“思维惯性”和“经验假设”，写出来的代码跑到另一个平台上时就会出现“可移植性”代码相关的安全漏洞了。</p>
<p>《CERT Secure Coding Standard》通篇都在引经据典，围绕C99、C1X、IEEE等等标准来提建议，定规则。一方面，可以看出建议和规则的制订者们非常重视科学的态度和权威的影响；另一方面，我在翻译的时候得到的一点小小的体会。看过RFC文档的人都知道，RFC标准里关于标准的需求强烈程度专门有一个RFC——<a href="http://www.ietf.org/rfc/rfc2119.txt">RFC 2119</a>来定义"MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED",  "MAY", 和"OPTIONAL"。通过使用不同的“情态动词”来让标准的阅读者更好的理解哪些是“强制要求”，哪些是“一般性要求”。虽然《CERT Secure Coding Standard》中很多规则/建议都只是使用Do not ...来开头，实际上每一条规则/建议都有一个“打分”——<a href="https://www.securecoding.cert.org/confluence/display/seccode/Risk+Assessment">Risk Assessment</a>，我在翻译的时候没有把这些“打分”包含进来，主要还是blog排版的问题，谁让我从一开始用的是表格这种形式呢。如果每条规则/建议后面都附上“打分”，可能可读性会更强一些吧。这对我们在制订自己的编程规范时也是一个很好的学习范例，不仅可以通过“情态动词”这种方式，采用量化得分的形式也可以有效的提高标准的“可读性”。</p>
<p>原计划是在春节期间分5天连载完所有的译稿，计划赶不上变化，明天不能上网，索性今天就全部发布完结。我不是英语专业出身，也不通“信、达、雅”，我只是从一个C语言使用者的角度，尽可能用自己的话把建议和规则都说清楚。水平有限，欢迎拍砖。</p>
<h2><a href="https://www.securecoding.cert.org/confluence/display/seccode/49.+Miscellaneous+%28MSC%29">49. 杂项 </a></h2>
<table style="width: 100%" border="1">
<thead>
<tr>
<td style="font-weight: bold;text-align: center">规则/建议条目全称</td>
<td style="vertical-align: top"><span style="font-weight: bold">例外</span></td>
<td style="vertical-align: top"><span style="font-weight: bold">笔记 /备注/点评</span></td>
</tr>
</thead>
<tbody>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/MSC00-C.+Compile+cleanly+at+high+warning+levels">MSC00-C. 使用高警告等级编译代码</a></td>
<td style="vertical-align: top">MSC00-EX1: 编译器会提供诊断信息以帮助改正代码。但有时代码确实正确，但编译器仍然产生警告，可以通过编译器支持的格式化注释方法或其他编译器指令消除警告，或通过注释明确指出相关代码的警告信息为何可以被安全的忽略。</td>
<td style="vertical-align: top"></td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/MSC01-C.+Strive+for+logical+completeness">MSC01-C. 尽可能实现逻辑完备性</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">很多软件漏洞都是由于程序员没有考虑所有可能的逻辑状态而引起的，例如缺少缺省处理逻辑或缺省错误处理逻辑等。</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/MSC02-C.+Avoid+errors+of+omission">MSC02-C. 避免粗心遗漏造成的错误</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">该条建议已经被以下3条建议代替：</p>
<ul>
<li><a href="https://www.securecoding.cert.org/confluence/display/seccode/EXP16-C.+Do+not+compare+function+pointers+to+constant+values">EXP16-C. 禁止将函数指针和常量进行比较</a></li>
<li><a href="https://www.securecoding.cert.org/confluence/display/seccode/EXP17-C.+Do+not+perform+bitwise+operations+in+conditional+expressions">EXP17-C. 禁止在条件语句中使用按位运算符</a></li>
<li><a href="https://www.securecoding.cert.org/confluence/display/seccode/EXP18-C.+Do+not+perform+assignments+in+selection+statements">EXP18-C. 禁止在选择语句中使用赋值操作</a></li>
</ul>
</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/MSC03-C.+Avoid+errors+of+addition">MSC03-C. 避免粗心画蛇添足造成的错误</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">
该条建议已经被以下2条建议代替：</p>
<ul>
<li><a href="https://www.securecoding.cert.org/confluence/display/seccode/EXP15-C.+Do+not+place+a+semicolon+on+the+same+line+as+an+if%2C+for%2C+or+while+statement">EXP15-C. 禁止在if, for, while语句的同一行上写分号</a></li>
<li><a href="https://www.securecoding.cert.org/confluence/display/seccode/MSC12-C.+Detect+and+remove+code+that+has+no+effect">MSC12-C. 检测并删除无效代码</a></li>
</ul>
</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/MSC04-C.+Use+comments+consistently+and+in+a+readable+fashion">MSC04-C. 注释风格统一且可读性高</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top"></td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/MSC05-C.+Do+not+manipulate+time_t+typed+values+directly">MSC05-C. 禁止直接操作time_t类型数据</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top"></td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/MSC06-C.+Be+aware+of+compiler+optimization+when+dealing+with+sensitive+data">MSC06-C. 操作敏感数据时小心编译器的优化</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">优化的结果可能是代码的屏蔽执行、常量化或者缓存等，可以使用编译器支持的指令禁止某段代码的自动优化，或者使用一些不会被优化的API。</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/MSC07-C.+Detect+and+remove+dead+code">MSC07-C. 检测并删除死代码</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">死代码指的是逻辑上永远不会被执行到的代码。</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/MSC09-C.+Character+Encoding+-+Use+Subset+of+ASCII+for+Safety">MSC09-C. 字符集编码——使用ASCII字符的子集以保证安全</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">屏蔽掉一些可能会引起异常或冲突的“元字符”，例如文件名命名中的一些禁用字符。</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/MSC10-C.+Character+Encoding+-+UTF8+Related+Issues">MSC10-C. 字符集编码——UTF8相关问题</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">UTF-8是Unicode的变长编码方式。UTF-8根据要表示的Unicode符号，会使用1~4字节来表示一个字符。在实际使用UTF-8字符集时要注意检查UTF-8字节序列的合法性，特别是大部分的Unicode系统最多只支持到16bit长的字符集范围，而不是ISO 10646标准的31bit完全UTF-8字符集空间。</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/MSC11-C.+Incorporate+diagnostic+tests+using+assertions">MSC11-C. 使用断言将诊断测试整合到代码中</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">注意断言的适用场合，特别是一些运行时（依赖于具体用户输入或运行环境）错误不要使用断言来测试。</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/MSC12-C.+Detect+and+remove+code+that+has+no+effect">MSC12-C. 检测并删除无效代码</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top"></td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/MSC13-C.+Detect+and+remove+unused+values">MSC13-C. 检测并删除不再使用的值</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top"></td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/MSC14-C.+Do+not+introduce+unnecessary+platform+dependencies">MSC14-C. 禁止引入不必要的平台依赖性</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">从代码的可移植性角度，C99定义了4类不可移植代码的行为：</p>
<ul>
<li>非确定行为</li>
<li>未定义行为</li>
<li>具体实现相关的行为</li>
<li>本地化相关行为</li>
</ul>
</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/MSC15-C.+Do+not+depend+on+undefined+behavior">MSC15-C. 禁止依赖“未定义”行为</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top"></td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/MSC16-C.+Consider+encrypting+function+pointers">MSC16-C. 考虑加密函数的调用地址</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">函数的内存调用地址正常情况下是在编译器确定并存储在二进制程序文件中。如果攻击者能够覆盖（hook）该地址，则攻击者可以执行任意代码。为了减轻这种攻击的效果，可以使用运行时函数调用地址确定的方法，来随机化函数的调用地址。Windows平台提供了两个相关的API来实现该功能：EncodePointer()和DecodePointer()。</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/MSC17-C.+Finish+every+set+of+statements+associated+with+a+case+label+with+a+break+statement">MSC17-C. 每一个选择语句分支都使用一个case标签和break</a></td>
<td style="vertical-align: top">MSC17-EX1: 最后一个分支语句可以不使用break，一般情况下最后一个分支语句的标签是default。<br />
<br />MSC17-EX2: 当一个控制流确实需要跨越多个分支语句标签时，可以不用每个分支标签配备一个break。但必须在文档注释中明确标记理由。
</td>
<td style="vertical-align: top"></td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/MSC18-C.+Be+careful+while+handling+sensitive+data%2C+such+as+passwords%2C+in+program+code">MSC18-C. 在程序代码中要小心操作敏感数据，例如口令</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top"></td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/MSC19-C.+For+functions+that+return+an+array%2C+prefer+returning+an+empty+array+over+a+null+value">MSC19-C. 函数返回值是数组类型的，优先使用空数组而不是null值作为返回值</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top"></td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/MSC20-C.+Do+not+use+a+switch+statement+to+transfer+control+into+a+complex+block">MSC20-C. 禁止在switch流程控制语句分支中使用复杂逻辑代码块</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top"></td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/MSC21-C.+Use+inequality+to+terminate+a+for+loop">MSC21-C. 使用不等号来终结for循环</a></td>
<td style="vertical-align: top">MSC21-EX1: 如果循环计数器是连续递增/递减，则可以使用相等关系来终结for循环。</td>
<td style="vertical-align: top"></td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/MSC22-C.+Use+the+setjmp%28%29%2C+longjmp%28%29+facility+securely">MSC22-C. 安全的使用setjmp(), longjmp()</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">详细建议请移步官方原文，引用内容较多。</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/MSC30-C.+Do+not+use+the+rand%28%29+function+for+generating+pseudorandom+numbers">MSC30-C. 禁止使用rand()函数产生伪随机数</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top"></td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/MSC31-C.+Ensure+that+return+values+are+compared+against+the+proper+type">MSC31-C. 确保函数返回值的比较对象类型匹配</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top"></td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/MSC32-C.+Ensure+your+random+number+generator+is+properly+seeded">MSC32-C. 确保你的随机数产生器的种子选择恰当</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top"></td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/MSC33-C.+Do+not+pass+invalid+data+to+the+asctime%28%29+function">MSC33-C. 禁止传递非法数据给asctime()函数</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top"></td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/MSC34-C.+Do+not+use+deprecated+or+obsolescent+functions">MSC34-C. 禁止使用废弃或过时的函数</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top"></td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/MSC35-C.+Do+not+include+any+executable+statements+inside+a+switch+statement+before+the+first+case+label">MSC35-C. 禁止在switch语句的第一个case标签之前包含任何可执行语句</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">编译器会忽略这些可执行语句。如果在switch语句的第一个case标签之前声明了一个变量，并试图在后续的case标签语句中使用该变量，该变量的有效作用域范围局限于swtich语句代码块内，但不会被初始化因而只会包含垃圾数据。</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/MSC36-C.+Check+for+alignment+of+memory+space+before+calling+realloc%28%29+function">MSC36-C. 调用realloc()函数之前检查内存地址的对齐情况</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">本条规则仅适用于遵循C1X 标准（即将出版）的编译器。</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/MSC37-C.+Ensure+that+control+never+reaches+the+end+of+a+non-void+function">MSC37-C. 确保非-void函数的控制流程不会到达函数尾部</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">确保非-void函数的尾部总是有一个默认的返回值语句存在。</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/MSC38-C.++Do+not+treat+as+an+object+any+predefined+identifier+that+might+be+implemented+as+a+macro">MSC38-C. 禁止将那些可能为宏实现的预定义标识当作一个对象</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">例如：ssert, errno, math_errhandling, setjmp, va_start, va_arg, va_copy, 和va_end。不要把这些宏直接当作函数来重新定义实现，如果需要用作全局变量，必须包含必要的头文件。</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/MSC39-C.+Do+not+call+va_arg%28%29+on+a+va_list+that+has+indeterminate+value">MSC39-C. 禁止将va_arg()作用于有未确定值的va_list</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top"></td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/MSC40-C.+Do+not+use+an+empty+infinite+loop">MSC40-C. 禁止使用空的无限循环</a></td>
<td style="vertical-align: top">MSC40-EX1: 在极少的情况下需要使用空的无限循环。例如，在某些平台上不支持用户态sleep()或等价函数。另一种情况是在操作系统内核，一个任务开始于任务调度相关函数从而无法调用sleep()或等价函数。在这些情况下就有必要采取一些其他方法来避免编译器优化导致空无限循环代码被删除。可用的方法包括使用volatile型变量作为无限循环的条件变量或者使用编译器支持的函数级别的关闭编译器优化选项指令。</td>
<td style="vertical-align: top"></td>
</tr>
</tbody>
</table>
<h2><a href="https://www.securecoding.cert.org/confluence/display/seccode/50.+POSIX+%28POS%29">50. POSIX</a></h2>
<table style="width: 100%" border="1">
<thead>
<tr>
<td style="font-weight: bold;text-align: center">规则/建议条目全称</td>
<td style="vertical-align: top"><span style="font-weight: bold">例外</span></td>
<td style="vertical-align: top"><span style="font-weight: bold">笔记 /备注/点评</span></td>
</tr>
</thead>
<tbody>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/POS01-C.+Check+for+the+existence+of+links+when+dealing+with+files">POS01-C. 操作文件时检查文件链接的存在性</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">
<p>Windows和*nix都支持文件链接，如硬链接，符号（软）链接和虚拟磁盘。在*nix系统中可以使用ln命令创建硬链接，在Windows系统上可以使用CreateHardLink()这个API。*nix上还可以使用ln -s创建符号链接，Windows系统可以在NTFS文件系统上使用目录junction、Linkd.exe（Win2K系统工具集）或者"junciton"这个免费软件来创建符号链接。Windows系统可以使用subst 命令创建虚拟磁盘。</p>
<p>由于文件链接机制的存在，当使用API打开一个文件的时候，有可能实际上操作的是另一个被链接到的文件。如果目标进程是运行在高权限下，则会对系统造成很大的隐患。</p>
<p>通常并不需要检查符号链接的存在性，只需要在打开文件前先执行“降权”操作，将当前进程的权限降低为普通用户，从而避免操作重要系统文件。</p>
<p>当创建一个新文件时，需要先检查目标文件是否已经存在，避免覆盖已有重要文件。</p>
<p>只要极个别情况下，需要检查软/硬链接文件的存在性以确保程序操作的是预期的文件，而不是其他目录下的文件。在这些情况下，在检查符号链接文件存在性时要避免造成竞争条件。</p>
<p>建议遵循<a href="https://www.securecoding.cert.org/confluence/display/seccode/FIO05-C.+Identify+files+using+multiple+file+attributes">FIO05-C. 使用多重文件属性识别一个文件</a>，确定一个文件到底是普通文件，还是某种类型的链接文件、虚拟磁盘文件、设备文件等等。对于符号链接文件，可以在打开文件时，使用O_NOFOLLOW属性参数来避免打开真实目标文件。对于硬链接文件，由于其不能跨不同设备链接。因此，在生产系统上，通常把重要目录和普通目录分别挂载在不同的设备上。</p>
</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/POS02-C.+Follow+the+principle+of+least+privilege">POS02-C. 遵循最小化权限原则</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top"></td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/POS03-C.+Do+not+use+volatile+as+a+synchronization+primitive">POS03-C. 禁止使用volatile类型的同步原语</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">关于volatile类型变量用于多线程编程有以下三点误解：</p>
<ul>
<li>原子性：不可再拆分的内存操作</li>
<li>可见性：（一个线程的）写操作是所有其他线程可见的</li>
<li>有序性：一个线程的实际内存操作顺序可以确保在被其他线程“看到”的顺序完全一致</li>
</ul>
<p>实际上，volatile类型变量<font color="red"><b>不具备以上三点性质中的任意一点</b></font>volatile修饰符作用于变量只是为了告诉编译器：该变量可能会以不确定的方式被改变，因此禁止编译器在该变量所在内存区域执行优化操作。使用volatile类型变量只能保证该变量值不会被“意外”的缓存到CPU的寄存器，从而导致一个线程的修改，其他线程再访问的可能是寄存器中的“旧”值。
</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/POS04-C.+Avoid+using+PTHREAD_MUTEX_NORMAL+type+mutex+locks">POS04-C. 避免使用PTHREAD_MUTEX_NORMAL类型的互斥锁</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top"></td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/POS30-C.+Use+the+readlink%28%29+function+properly">POS30-C. 恰当的使用readlink()函数</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top"></td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/POS33-C.+Do+not+use+vfork%28%29">POS33-C. 禁止使用vfork()</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top"></td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/POS34-C.+Do+not+call+putenv%28%29+with+a+pointer+to+an+automatic+variable+as+the+argument">POS34-C. 禁止调用putenv()时传递一个指向自动变量的指针作为参数</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top"></td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/POS35-C.+Avoid+race+conditions+while+checking+for+the+existence+of+a+symbolic+link">POS35-C. 检查符号链接存在性时避免出现竞争条件</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">例如time-of-check-time-of-use (TOCTOU)竞争条件。</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/POS36-C.+Observe+correct+revocation+order+while+relinquishing+privileges">POS36-C. 释放权限时遵循正确的撤销顺序</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">先setgid(getgid())，再setuid(getuid())。除此之外，还要注意一个用户可能同时属于多个用户组，因此一个进程除了egid之外，还会有多个补充组id（supplementary group ID）。getgroups()会返回一个包含所有补充组id的数组，该数组中也可能会包括egid。POSIX标准中定义了getgroups()，但没有定义setgroups()。正常情况下setuid()相关的API调用不会改变补充组id，除非该进程运行在setuid-root模式下。所以正确释放所有补充组id的顺序应该是先释放所有的补充组id，最后再释放root权限。</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/POS37-C.+Ensure+that+privilege+relinquishment+is+successful">POS37-C. 确保权限释放成功</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top"></td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/POS38-C.+Beware+of+race+conditions+when+using+fork+and+file+descriptors">POS38-C. 使用fork和文件描述符时小心竞争条件</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">使用fork创建子进程时，文件描述符会被拷贝到子进程中因此可能会导致对同一个文件的并发操作。</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/POS39-C.+Use+the+correct+byte+ordering+when+transferring+data+between+systems">POS39-C. 跨系统传输数据时注意字节顺序</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">htonl(), htons(), ntohl(), 和 ntohs()用于网络字节顺序（big endian）和主机字节顺序（little endian）之间的转换。在big endian系统上执行这些函数是没有效果的。</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/POS41-C.+When+a+thread+exit+status+is+not+of+concern%2C++pthread_detach%28%29+or+an+equivalent+function+must+be+used">POS41-C. 当一个线程的退出状态不重要时，必须使用pthread_detach()或其他等效函数</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">当线程退出但没有detach时，线程的栈内存会被释放，但其他资源，包括堆内存和操作系统级别对象，将一直存在直到pthread_join()或pthread_detach()被调用。</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/POS44-C.+Do+not+use+signals+to+terminate+threads">POS44-C. 禁止使用信号来终结线程</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top"></td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/POS45-C.+Avoid+memory+leaks+and+clean+up+thread-specific+data+for+a+key+by+defining+an+explicit+destructor">POS45-C. 为线程专有数据定义显式的销毁器以避免内存泄漏</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">pthread_key_create()调用时传递一个内存清理函数指针作为第二个参数。</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/POS47-C.+Do+not+use+threads+that+can+be+canceled+asynchronously">POS47-C. 禁止使用可能会被异步取消的线程</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top"></td>
</tr>
</tbody>
</table>]]></description>
			<content:encoded><![CDATA[<div style="margin-top: 2px;">
<A href="http://creativecommons.org/licenses/by/3.0/deed.zh"><FONT color=#11779f><STRONG>版权声明</STRONG></FONT></A><FONT color=#11779f><STRONG>：可以任意转载，转载时请务必以超链接形式标明文章原始出处和<a href="http://www.huangwei.me/blog/">作者信息</a></STRONG></FONT>
</div>
<h2>写在最后的话</h2>
<p>规范很精彩，评论更精彩。很多建议和规则虽然本身写的有瑕疵，但是当你看了建议/规则页的评论之后，你会发现你并不是第一个提问的人。很多时候你的疑问和疑惑别人已经给你解答了。在我看来，CERT的这个C语言安全编程规范的最重要的意义不是告诉你怎样使用C语言编写一个“无漏洞”的系统，重要的是通过阅读这个规范，你会知道怎样使用C语言会编写出一个“有漏洞”的系统。和很多安全编程规范一样，《CERT Secure Coding Standard》不是要告诉你”What to do”，而是让你知道”What is bad”。</p>
<p>《CERT Secure Coding Standard》中有很多建议/规则都是面向“可移植”代码需求写的，对于确定性的运行在某一个专有平台上，没有代码可移植性需求的C程序员来说，要特别留意不同平台上的一些比较tricky的情况。虽然代码并不总是跨平台的，但程序员却有很大可能性跨平台的。一旦养成了某个平台上的一些“思维惯性”和“经验假设”，写出来的代码跑到另一个平台上时就会出现“可移植性”代码相关的安全漏洞了。</p>
<p>《CERT Secure Coding Standard》通篇都在引经据典，围绕C99、C1X、IEEE等等标准来提建议，定规则。一方面，可以看出建议和规则的制订者们非常重视科学的态度和权威的影响；另一方面，我在翻译的时候得到的一点小小的体会。看过RFC文档的人都知道，RFC标准里关于标准的需求强烈程度专门有一个RFC——<a href="http://www.ietf.org/rfc/rfc2119.txt">RFC 2119</a>来定义”MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”,  “MAY”, 和”OPTIONAL”。通过使用不同的“情态动词”来让标准的阅读者更好的理解哪些是“强制要求”，哪些是“一般性要求”。虽然《CERT Secure Coding Standard》中很多规则/建议都只是使用Do not &#8230;来开头，实际上每一条规则/建议都有一个“打分”——<a href="https://www.securecoding.cert.org/confluence/display/seccode/Risk+Assessment">Risk Assessment</a>，我在翻译的时候没有把这些“打分”包含进来，主要还是blog排版的问题，谁让我从一开始用的是表格这种形式呢。如果每条规则/建议后面都附上“打分”，可能可读性会更强一些吧。这对我们在制订自己的编程规范时也是一个很好的学习范例，不仅可以通过“情态动词”这种方式，采用量化得分的形式也可以有效的提高标准的“可读性”。</p>
<p>原计划是在春节期间分5天连载完所有的译稿，计划赶不上变化，明天不能上网，索性今天就全部发布完结。我不是英语专业出身，也不通“信、达、雅”，我只是从一个C语言使用者的角度，尽可能用自己的话把建议和规则都说清楚。水平有限，欢迎拍砖。</p>
<h2><a href="https://www.securecoding.cert.org/confluence/display/seccode/49.+Miscellaneous+%28MSC%29">49. 杂项 </a></h2>
<table style="width: 100%" border="1">
<thead>
<tr>
<td style="font-weight: bold;text-align: center">规则/建议条目全称</td>
<td style="vertical-align: top"><span style="font-weight: bold">例外</span></td>
<td style="vertical-align: top"><span style="font-weight: bold">笔记 /备注/点评</span></td>
</tr>
</thead>
<tbody>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/MSC00-C.+Compile+cleanly+at+high+warning+levels">MSC00-C. 使用高警告等级编译代码</a></td>
<td style="vertical-align: top">MSC00-EX1: 编译器会提供诊断信息以帮助改正代码。但有时代码确实正确，但编译器仍然产生警告，可以通过编译器支持的格式化注释方法或其他编译器指令消除警告，或通过注释明确指出相关代码的警告信息为何可以被安全的忽略。</td>
<td style="vertical-align: top"></td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/MSC01-C.+Strive+for+logical+completeness">MSC01-C. 尽可能实现逻辑完备性</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">很多软件漏洞都是由于程序员没有考虑所有可能的逻辑状态而引起的，例如缺少缺省处理逻辑或缺省错误处理逻辑等。</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/MSC02-C.+Avoid+errors+of+omission">MSC02-C. 避免粗心遗漏造成的错误</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">该条建议已经被以下3条建议代替：</p>
<ul>
<li><a href="https://www.securecoding.cert.org/confluence/display/seccode/EXP16-C.+Do+not+compare+function+pointers+to+constant+values">EXP16-C. 禁止将函数指针和常量进行比较</a></li>
<li><a href="https://www.securecoding.cert.org/confluence/display/seccode/EXP17-C.+Do+not+perform+bitwise+operations+in+conditional+expressions">EXP17-C. 禁止在条件语句中使用按位运算符</a></li>
<li><a href="https://www.securecoding.cert.org/confluence/display/seccode/EXP18-C.+Do+not+perform+assignments+in+selection+statements">EXP18-C. 禁止在选择语句中使用赋值操作</a></li>
</ul>
</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/MSC03-C.+Avoid+errors+of+addition">MSC03-C. 避免粗心画蛇添足造成的错误</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">
该条建议已经被以下2条建议代替：</p>
<ul>
<li><a href="https://www.securecoding.cert.org/confluence/display/seccode/EXP15-C.+Do+not+place+a+semicolon+on+the+same+line+as+an+if%2C+for%2C+or+while+statement">EXP15-C. 禁止在if, for, while语句的同一行上写分号</a></li>
<li><a href="https://www.securecoding.cert.org/confluence/display/seccode/MSC12-C.+Detect+and+remove+code+that+has+no+effect">MSC12-C. 检测并删除无效代码</a></li>
</ul>
</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/MSC04-C.+Use+comments+consistently+and+in+a+readable+fashion">MSC04-C. 注释风格统一且可读性高</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top"></td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/MSC05-C.+Do+not+manipulate+time_t+typed+values+directly">MSC05-C. 禁止直接操作time_t类型数据</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top"></td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/MSC06-C.+Be+aware+of+compiler+optimization+when+dealing+with+sensitive+data">MSC06-C. 操作敏感数据时小心编译器的优化</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">优化的结果可能是代码的屏蔽执行、常量化或者缓存等，可以使用编译器支持的指令禁止某段代码的自动优化，或者使用一些不会被优化的API。</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/MSC07-C.+Detect+and+remove+dead+code">MSC07-C. 检测并删除死代码</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">死代码指的是逻辑上永远不会被执行到的代码。</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/MSC09-C.+Character+Encoding+-+Use+Subset+of+ASCII+for+Safety">MSC09-C. 字符集编码——使用ASCII字符的子集以保证安全</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">屏蔽掉一些可能会引起异常或冲突的“元字符”，例如文件名命名中的一些禁用字符。</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/MSC10-C.+Character+Encoding+-+UTF8+Related+Issues">MSC10-C. 字符集编码——UTF8相关问题</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">UTF-8是Unicode的变长编码方式。UTF-8根据要表示的Unicode符号，会使用1~4字节来表示一个字符。在实际使用UTF-8字符集时要注意检查UTF-8字节序列的合法性，特别是大部分的Unicode系统最多只支持到16bit长的字符集范围，而不是ISO 10646标准的31bit完全UTF-8字符集空间。</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/MSC11-C.+Incorporate+diagnostic+tests+using+assertions">MSC11-C. 使用断言将诊断测试整合到代码中</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">注意断言的适用场合，特别是一些运行时（依赖于具体用户输入或运行环境）错误不要使用断言来测试。</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/MSC12-C.+Detect+and+remove+code+that+has+no+effect">MSC12-C. 检测并删除无效代码</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top"></td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/MSC13-C.+Detect+and+remove+unused+values">MSC13-C. 检测并删除不再使用的值</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top"></td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/MSC14-C.+Do+not+introduce+unnecessary+platform+dependencies">MSC14-C. 禁止引入不必要的平台依赖性</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">从代码的可移植性角度，C99定义了4类不可移植代码的行为：</p>
<ul>
<li>非确定行为</li>
<li>未定义行为</li>
<li>具体实现相关的行为</li>
<li>本地化相关行为</li>
</ul>
</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/MSC15-C.+Do+not+depend+on+undefined+behavior">MSC15-C. 禁止依赖“未定义”行为</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top"></td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/MSC16-C.+Consider+encrypting+function+pointers">MSC16-C. 考虑加密函数的调用地址</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">函数的内存调用地址正常情况下是在编译器确定并存储在二进制程序文件中。如果攻击者能够覆盖（hook）该地址，则攻击者可以执行任意代码。为了减轻这种攻击的效果，可以使用运行时函数调用地址确定的方法，来随机化函数的调用地址。Windows平台提供了两个相关的API来实现该功能：EncodePointer()和DecodePointer()。</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/MSC17-C.+Finish+every+set+of+statements+associated+with+a+case+label+with+a+break+statement">MSC17-C. 每一个选择语句分支都使用一个case标签和break</a></td>
<td style="vertical-align: top">MSC17-EX1: 最后一个分支语句可以不使用break，一般情况下最后一个分支语句的标签是default。</p>
<p>MSC17-EX2: 当一个控制流确实需要跨越多个分支语句标签时，可以不用每个分支标签配备一个break。但必须在文档注释中明确标记理由。
</td>
<td style="vertical-align: top"></td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/MSC18-C.+Be+careful+while+handling+sensitive+data%2C+such+as+passwords%2C+in+program+code">MSC18-C. 在程序代码中要小心操作敏感数据，例如口令</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top"></td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/MSC19-C.+For+functions+that+return+an+array%2C+prefer+returning+an+empty+array+over+a+null+value">MSC19-C. 函数返回值是数组类型的，优先使用空数组而不是null值作为返回值</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top"></td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/MSC20-C.+Do+not+use+a+switch+statement+to+transfer+control+into+a+complex+block">MSC20-C. 禁止在switch流程控制语句分支中使用复杂逻辑代码块</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top"></td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/MSC21-C.+Use+inequality+to+terminate+a+for+loop">MSC21-C. 使用不等号来终结for循环</a></td>
<td style="vertical-align: top">MSC21-EX1: 如果循环计数器是连续递增/递减，则可以使用相等关系来终结for循环。</td>
<td style="vertical-align: top"></td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/MSC22-C.+Use+the+setjmp%28%29%2C+longjmp%28%29+facility+securely">MSC22-C. 安全的使用setjmp(), longjmp()</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">详细建议请移步官方原文，引用内容较多。</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/MSC30-C.+Do+not+use+the+rand%28%29+function+for+generating+pseudorandom+numbers">MSC30-C. 禁止使用rand()函数产生伪随机数</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top"></td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/MSC31-C.+Ensure+that+return+values+are+compared+against+the+proper+type">MSC31-C. 确保函数返回值的比较对象类型匹配</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top"></td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/MSC32-C.+Ensure+your+random+number+generator+is+properly+seeded">MSC32-C. 确保你的随机数产生器的种子选择恰当</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top"></td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/MSC33-C.+Do+not+pass+invalid+data+to+the+asctime%28%29+function">MSC33-C. 禁止传递非法数据给asctime()函数</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top"></td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/MSC34-C.+Do+not+use+deprecated+or+obsolescent+functions">MSC34-C. 禁止使用废弃或过时的函数</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top"></td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/MSC35-C.+Do+not+include+any+executable+statements+inside+a+switch+statement+before+the+first+case+label">MSC35-C. 禁止在switch语句的第一个case标签之前包含任何可执行语句</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">编译器会忽略这些可执行语句。如果在switch语句的第一个case标签之前声明了一个变量，并试图在后续的case标签语句中使用该变量，该变量的有效作用域范围局限于swtich语句代码块内，但不会被初始化因而只会包含垃圾数据。</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/MSC36-C.+Check+for+alignment+of+memory+space+before+calling+realloc%28%29+function">MSC36-C. 调用realloc()函数之前检查内存地址的对齐情况</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">本条规则仅适用于遵循C1X 标准（即将出版）的编译器。</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/MSC37-C.+Ensure+that+control+never+reaches+the+end+of+a+non-void+function">MSC37-C. 确保非-void函数的控制流程不会到达函数尾部</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">确保非-void函数的尾部总是有一个默认的返回值语句存在。</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/MSC38-C.++Do+not+treat+as+an+object+any+predefined+identifier+that+might+be+implemented+as+a+macro">MSC38-C. 禁止将那些可能为宏实现的预定义标识当作一个对象</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">例如：ssert, errno, math_errhandling, setjmp, va_start, va_arg, va_copy, 和va_end。不要把这些宏直接当作函数来重新定义实现，如果需要用作全局变量，必须包含必要的头文件。</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/MSC39-C.+Do+not+call+va_arg%28%29+on+a+va_list+that+has+indeterminate+value">MSC39-C. 禁止将va_arg()作用于有未确定值的va_list</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top"></td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/MSC40-C.+Do+not+use+an+empty+infinite+loop">MSC40-C. 禁止使用空的无限循环</a></td>
<td style="vertical-align: top">MSC40-EX1: 在极少的情况下需要使用空的无限循环。例如，在某些平台上不支持用户态sleep()或等价函数。另一种情况是在操作系统内核，一个任务开始于任务调度相关函数从而无法调用sleep()或等价函数。在这些情况下就有必要采取一些其他方法来避免编译器优化导致空无限循环代码被删除。可用的方法包括使用volatile型变量作为无限循环的条件变量或者使用编译器支持的函数级别的关闭编译器优化选项指令。</td>
<td style="vertical-align: top"></td>
</tr>
</tbody>
</table>
<h2><a href="https://www.securecoding.cert.org/confluence/display/seccode/50.+POSIX+%28POS%29">50. POSIX</a></h2>
<table style="width: 100%" border="1">
<thead>
<tr>
<td style="font-weight: bold;text-align: center">规则/建议条目全称</td>
<td style="vertical-align: top"><span style="font-weight: bold">例外</span></td>
<td style="vertical-align: top"><span style="font-weight: bold">笔记 /备注/点评</span></td>
</tr>
</thead>
<tbody>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/POS01-C.+Check+for+the+existence+of+links+when+dealing+with+files">POS01-C. 操作文件时检查文件链接的存在性</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">
<p>Windows和*nix都支持文件链接，如硬链接，符号（软）链接和虚拟磁盘。在*nix系统中可以使用ln命令创建硬链接，在Windows系统上可以使用CreateHardLink()这个API。*nix上还可以使用ln -s创建符号链接，Windows系统可以在NTFS文件系统上使用目录junction、Linkd.exe（Win2K系统工具集）或者”junciton”这个免费软件来创建符号链接。Windows系统可以使用subst 命令创建虚拟磁盘。</p>
<p>由于文件链接机制的存在，当使用API打开一个文件的时候，有可能实际上操作的是另一个被链接到的文件。如果目标进程是运行在高权限下，则会对系统造成很大的隐患。</p>
<p>通常并不需要检查符号链接的存在性，只需要在打开文件前先执行“降权”操作，将当前进程的权限降低为普通用户，从而避免操作重要系统文件。</p>
<p>当创建一个新文件时，需要先检查目标文件是否已经存在，避免覆盖已有重要文件。</p>
<p>只要极个别情况下，需要检查软/硬链接文件的存在性以确保程序操作的是预期的文件，而不是其他目录下的文件。在这些情况下，在检查符号链接文件存在性时要避免造成竞争条件。</p>
<p>建议遵循<a href="https://www.securecoding.cert.org/confluence/display/seccode/FIO05-C.+Identify+files+using+multiple+file+attributes">FIO05-C. 使用多重文件属性识别一个文件</a>，确定一个文件到底是普通文件，还是某种类型的链接文件、虚拟磁盘文件、设备文件等等。对于符号链接文件，可以在打开文件时，使用O_NOFOLLOW属性参数来避免打开真实目标文件。对于硬链接文件，由于其不能跨不同设备链接。因此，在生产系统上，通常把重要目录和普通目录分别挂载在不同的设备上。</p>
</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/POS02-C.+Follow+the+principle+of+least+privilege">POS02-C. 遵循最小化权限原则</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top"></td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/POS03-C.+Do+not+use+volatile+as+a+synchronization+primitive">POS03-C. 禁止使用volatile类型的同步原语</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">关于volatile类型变量用于多线程编程有以下三点误解：</p>
<ul>
<li>原子性：不可再拆分的内存操作</li>
<li>可见性：（一个线程的）写操作是所有其他线程可见的</li>
<li>有序性：一个线程的实际内存操作顺序可以确保在被其他线程“看到”的顺序完全一致</li>
</ul>
<p>实际上，volatile类型变量<font color="red"><b>不具备以上三点性质中的任意一点</b></font>volatile修饰符作用于变量只是为了告诉编译器：该变量可能会以不确定的方式被改变，因此禁止编译器在该变量所在内存区域执行优化操作。使用volatile类型变量只能保证该变量值不会被“意外”的缓存到CPU的寄存器，从而导致一个线程的修改，其他线程再访问的可能是寄存器中的“旧”值。
</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/POS04-C.+Avoid+using+PTHREAD_MUTEX_NORMAL+type+mutex+locks">POS04-C. 避免使用PTHREAD_MUTEX_NORMAL类型的互斥锁</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top"></td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/POS30-C.+Use+the+readlink%28%29+function+properly">POS30-C. 恰当的使用readlink()函数</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top"></td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/POS33-C.+Do+not+use+vfork%28%29">POS33-C. 禁止使用vfork()</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top"></td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/POS34-C.+Do+not+call+putenv%28%29+with+a+pointer+to+an+automatic+variable+as+the+argument">POS34-C. 禁止调用putenv()时传递一个指向自动变量的指针作为参数</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top"></td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/POS35-C.+Avoid+race+conditions+while+checking+for+the+existence+of+a+symbolic+link">POS35-C. 检查符号链接存在性时避免出现竞争条件</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">例如time-of-check-time-of-use (TOCTOU)竞争条件。</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/POS36-C.+Observe+correct+revocation+order+while+relinquishing+privileges">POS36-C. 释放权限时遵循正确的撤销顺序</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">先setgid(getgid())，再setuid(getuid())。除此之外，还要注意一个用户可能同时属于多个用户组，因此一个进程除了egid之外，还会有多个补充组id（supplementary group ID）。getgroups()会返回一个包含所有补充组id的数组，该数组中也可能会包括egid。POSIX标准中定义了getgroups()，但没有定义setgroups()。正常情况下setuid()相关的API调用不会改变补充组id，除非该进程运行在setuid-root模式下。所以正确释放所有补充组id的顺序应该是先释放所有的补充组id，最后再释放root权限。</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/POS37-C.+Ensure+that+privilege+relinquishment+is+successful">POS37-C. 确保权限释放成功</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top"></td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/POS38-C.+Beware+of+race+conditions+when+using+fork+and+file+descriptors">POS38-C. 使用fork和文件描述符时小心竞争条件</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">使用fork创建子进程时，文件描述符会被拷贝到子进程中因此可能会导致对同一个文件的并发操作。</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/POS39-C.+Use+the+correct+byte+ordering+when+transferring+data+between+systems">POS39-C. 跨系统传输数据时注意字节顺序</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">htonl(), htons(), ntohl(), 和 ntohs()用于网络字节顺序（big endian）和主机字节顺序（little endian）之间的转换。在big endian系统上执行这些函数是没有效果的。</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/POS41-C.+When+a+thread+exit+status+is+not+of+concern%2C++pthread_detach%28%29+or+an+equivalent+function+must+be+used">POS41-C. 当一个线程的退出状态不重要时，必须使用pthread_detach()或其他等效函数</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">当线程退出但没有detach时，线程的栈内存会被释放，但其他资源，包括堆内存和操作系统级别对象，将一直存在直到pthread_join()或pthread_detach()被调用。</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/POS44-C.+Do+not+use+signals+to+terminate+threads">POS44-C. 禁止使用信号来终结线程</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top"></td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/POS45-C.+Avoid+memory+leaks+and+clean+up+thread-specific+data+for+a+key+by+defining+an+explicit+destructor">POS45-C. 为线程专有数据定义显式的销毁器以避免内存泄漏</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">pthread_key_create()调用时传递一个内存清理函数指针作为第二个参数。</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/POS47-C.+Do+not+use+threads+that+can+be+canceled+asynchronously">POS47-C. 禁止使用可能会被异步取消的线程</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top"></td>
</tr>
</tbody>
</table>
<div style="margin-top: 15px; ">
<hr style="border: 1px solid #cccccc;"/>
<p><strong>原创文章，转载请注明：</strong> 转载自<a href="http://www.huangwei.me/blog/">猪在笑</a> <a href="http://www.huangwei.me/blog/">[ http://www.huangwei.me/blog/ ]</a><br/><strong>本文链接地址:</strong> <a href="http://www.huangwei.me/blog/2011/02/06/cert-secure-coding-standard/">http://www.huangwei.me/blog/2011/02/06/cert-secure-coding-standard/</a></p>
<hr style="border: 1px solid #cccccc;"/>
</div>
<div  class="related_post_title">您可能还对以下文章感兴趣</div><ul class="related_post"><li><a href="http://www.huangwei.me/blog/2011/02/06/cert-secure-coding-standard-4/" title="[译]CERT Secure Coding Standard — C语言安全编程规范(4)">[译]CERT Secure Coding Standard — C语言安全编程规范(4)</a></li><li><a href="http://www.huangwei.me/blog/2011/02/05/cert-secure-coding-standard-3/" title="[译]CERT Secure Coding Standard — C语言安全编程规范(3)">[译]CERT Secure Coding Standard — C语言安全编程规范(3)</a></li><li><a href="http://www.huangwei.me/blog/2011/02/04/cert-secure-coding-standard-2/" title="[译]CERT Secure Coding Standard — C语言安全编程规范(2)">[译]CERT Secure Coding Standard — C语言安全编程规范(2)</a></li><li><a href="http://www.huangwei.me/blog/2011/02/03/cert-secure-coding-standard-1/" title="[译]CERT Secure Coding Standard — C语言安全编程规范(1)">[译]CERT Secure Coding Standard — C语言安全编程规范(1)</a></li><li><a href="http://www.huangwei.me/blog/2010/02/20/2010cwe25/" title="2010 CWE TOP 25">2010 CWE TOP 25</a></li><li><a href="http://www.huangwei.me/blog/2009/09/02/%e6%8e%a8%e8%8d%90%e5%9f%ba%e4%ba%8ewindbg%e7%9a%84%e4%b8%80%e4%b8%aa%e6%bc%8f%e6%b4%9e%e5%8f%af%e5%88%a9%e7%94%a8%e6%80%a7%e5%88%86%e6%9e%90%e6%8f%92%e4%bb%b6/" title="[推荐]基于Windbg的一个漏洞可利用性分析插件">[推荐]基于Windbg的一个漏洞可利用性分析插件</a></li><li><a href="http://www.huangwei.me/blog/2007/12/13/oip-dnsooauedhss-2/" title="[原创]IP-&#62;DNS域名反查小工具">[原创]IP-&#62;DNS域名反查小工具</a></li><li><a href="http://www.huangwei.me/blog/2011/08/17/lsof-and-fuser/" title="分享1个Linux命令lsof">分享1个Linux命令lsof</a></li><li><a href="http://www.huangwei.me/blog/2011/04/06/new-to-mac-2/" title="苹果小白的上手笔记(2)">苹果小白的上手笔记(2)</a></li><li><a href="http://www.huangwei.me/blog/2011/01/20/build-your-own-vulnerable-web-application/" title="自己动手搭建缺陷Web App">自己动手搭建缺陷Web App</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.huangwei.me/blog/2011/02/06/cert-secure-coding-standard/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[译]CERT Secure Coding Standard — C语言安全编程规范(4)</title>
		<link>http://www.huangwei.me/blog/2011/02/06/cert-secure-coding-standard-4/</link>
		<comments>http://www.huangwei.me/blog/2011/02/06/cert-secure-coding-standard-4/#comments</comments>
		<pubDate>Sun, 06 Feb 2011 05:23:10 +0000</pubDate>
		<dc:creator>c4pr1c3</dc:creator>
				<category><![CDATA[安全技术]]></category>
		<category><![CDATA[CERT Secure Coding Standard]]></category>
		<category><![CDATA[C语言安全编程规范]]></category>
		<category><![CDATA[C语言编程安全规范]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[编程规范]]></category>

		<guid isPermaLink="false">http://www.huangwei.me/blog/?p=913</guid>
		<description><![CDATA[<h2><a href="https://www.securecoding.cert.org/confluence/display/seccode/11.+Signals+%28SIG%29">11. 信号</a></h2>
<table style="width: 100%" border="1">
<thead>
<tr>
<td style="font-weight: bold;text-align: center">规则/建议条目全称</td>
<td style="vertical-align: top"><span style="font-weight: bold">例外</span></td>
<td style="vertical-align: top"><span style="font-weight: bold">笔记 /备注/点评</span></td>
</tr>
</thead>
<tbody>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/SIG00-C.+Mask+signals+handled+by+noninterruptible+signal+handlers">SIG00-C. 屏蔽由不可中断信号处理函数处理的信号</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">POSIX标准建议使用sigaction()，废弃signal()。但sigaction()不是C99标准。</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/SIG01-C.+Understand+implementation-specific+details+regarding+signal+handler+persistence">SIG01-C. 理解信号处理函数持久化相关的实现细节</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">*nix平台上的信号处理函数一般是实现为“持久化”的，即除非显式的删除该信号处理函数，否则该信号处理函数会一直运行时有效。而Windows平台上则恰好相反，信号处理函数被执行一次后就会自动被删除。</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/SIG02-C.+Avoid+using+signals+to+implement+normal+functionality">SIG02-C. 避免使用信号机制来实现普通函数功能</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">从代码可安全移植的角度设计的本条建议。</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/SIG30-C.+Call+only+asynchronous-safe+functions+within+signal+handlers">SIG30-C. 在信号处理函数内部仅调用异步安全函数</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">查手册确定异步安全函数有哪些。</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/SIG31-C.+Do+not+access+or+modify+shared+objects+in+signal+handlers">SIG31-C. 禁止在信号处理函数内部访问或修改共享对象</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">否则会导致竞争读写问题，引起数据状态的不一致。读写volatile sig_atomic_t类型变量则没有问题，读写其他类型变量的行为则是“未定义”的。</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/SIG32-C.+Do+not+call+longjmp%28%29+from+inside+a+signal+handler">SIG32-C. 在信号处理函数内部禁止调用longjmp()</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">本条规则和<a href="https://www.securecoding.cert.org/confluence/display/seccode/SIG30-C.+Call+only+asynchronous-safe+functions+within+signal+handlers">SIG30-C. 在信号处理函数内部仅调用异步安全函数</a>是相关的。</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/SIG33-C.+Do+not+recursively+invoke+the+raise%28%29+function">SIG33-C. 禁止递归调用raise()</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top"></td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/SIG34-C.+Do+not+call+signal%28%29+from+within+interruptible+signal+handlers">SIG34-C. 禁止在可中断信号处理函数内调用signal()</a></td>
<td style="vertical-align: top">SIG34-EX1: 在支持持久化信号处理函数的平台上信号处理函数可以安全的修改自己的信号处理行为。</td>
<td style="vertical-align: top">一个信号处理函数仅仅在其不需要是异步安全时可以嵌套调用signal()。</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/SIG35-C.+Do+not+return+from+SIGSEGV%2C+SIGILL%2C+or+SIGFPE+signal+handlers">SIG35-C. 禁止从SIGSEGV, SIGILL, 或SIGFPE的信号处理函数返回</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">否则会引起“未定义”行为。</td>
</tr>
</tbody>
</table>
<h2><a href="https://www.securecoding.cert.org/confluence/display/seccode/12.+Error+Handling+%28ERR%29">12. 错误处理 </a></h2>
<table style="width: 100%" border="1">
<thead>
<tr>
<td style="font-weight: bold;text-align: center">规则/建议条目全称</td>
<td style="vertical-align: top"><span style="font-weight: bold">例外</span></td>
<td style="vertical-align: top"><span style="font-weight: bold">笔记 /备注/点评</span></td>
</tr>
</thead>
<tbody>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/ERR00-C.+Adopt+and+implement+a+consistent+and+comprehensive+error-handling+policy">ERR00-C. 采用和实现一个一致和全面的错误处理策略</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top"></td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/ERR01-C.+Use+ferror%28%29+rather+than+errno+to+check+for+FILE+stream+errors">ERR01-C. 使用ferror()而不是errno来检查文件流错误</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">errno仅仅在某些库函数调用出错返回错误代码并会设置errno位时才有意义，并非所有的文件流操作操作都会设置errno。ferror()则是针对特定文件流是否操作出错的检查。</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/ERR02-C.+Avoid+in-band+error+indicators">ERR02-C. 避免“带内”(in-band)错误指示符</a></td>
<td style="vertical-align: top">ERR02-EX1: 空指针是另一个in-band错误指示符的例子，但空指针不会引起任何副作用。</p>
<p>ERR02-EX2: 如果你能保证函数在执行过程中出错时绝不会继续执行(可以通过调用abort()或者longjmp()中断函数执行过程)，你的函数就可以返回in-band错误指示符。</p>
</td>
<td style="vertical-align: top">所谓in-band，学过通信的都知道所谓“带内”信号和“带外”信号，in-band的含义就是所传递的信息会占用“正常”的传输通道资源。在C语言的标准库函数实现里大量的使用了in-band错误指示符，即函数的返回值在正常执行成功时会返回一些操作成功相关的变量值，函数执行出错时又利用返回值设置错误变量值。相当于函数的返回值在这里既是正常“返回结果”的传递通道，又是错误“返回结果”的传递通道。由于两种返回结果可能是不同的数据类型，因此函数在定义时可能会使用“兼容”数据类型，从而增加了函数调用者调用函数时的逻辑处理复杂度，可能会导致一些“二义性”或者“理解偏差”错误。</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/ERR03-C.+Use+runtime-constraint+handlers+when+calling+functions+defined+by+TR24731-1">ERR03-C. 调用TR24731-1标准定义的系列函数时使用运行时约束条件处理函数</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">strcpy_s()就是TR24731-1定义的一个函数，所谓“运行时约束条件处理函数”就是指的调用set_constraint_handler_s()注册一个运行时约束条件违反处理函数。该条建议主要针对微软平台，*nix平台忽略该条建议应该问题不大。</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/ERR04-C.+Choose+an+appropriate+termination+strategy">ERR04-C. 选择一个合适的程序退出策略</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">C99标准提供了4种程序退出策略：exit()、从main()函数返回、_Exit()和abort()。这四个函数的退出时动作差别如下表总结所示：</p>
<table class="confluenceTable" style="margin: 5px 0px;padding: 0px;font-size: 10pt;line-height: 13pt;color: #000000;font-weight: normal;clear: left;border-collapse: collapse">
<tbody>
<tr style="font-size: 10pt;line-height: 13pt;color: #000000;font-weight: normal">
<th>函数名</th>
<th>关闭所有打开的流</th>
<th>flush所有的流缓冲</th>
<th>删除所有临时文件</th>
<th>调用atexit()注册的处理函数</th>
<th>程序退出状态</th>
</tr>
<tr style="font-size: 10pt;line-height: 13pt;color: #000000;font-weight: normal">
<td style="border: 1px solid #dddddd;padding: 5px;font-size: 10pt;line-height: 13pt;color: #000000;font-weight: normal;vertical-align: top"><tt>abort()</tt></td>
<td style="border: 1px solid #dddddd;padding: 5px;font-size: 10pt;line-height: 13pt;color: #000000;font-weight: normal;vertical-align: top"><img class="emoticon" src="http://www.huangwei.me/blog/wp-content/uploads/2011/02/information.gif" border="0" alt="" width="16" height="16" align="absmiddle" /></td>
<td style="border: 1px solid #dddddd;padding: 5px;font-size: 10pt;line-height: 13pt;color: #000000;font-weight: normal;vertical-align: top"><img class="emoticon" src="http://www.huangwei.me/blog/wp-content/uploads/2011/02/information.gif" border="0" alt="" width="16" height="16" align="absmiddle" /></td>
<td style="border: 1px solid #dddddd;padding: 5px;font-size: 10pt;line-height: 13pt;color: #000000;font-weight: normal;vertical-align: top"><img class="emoticon" src="http://www.huangwei.me/blog/wp-content/uploads/2011/02/information.gif" border="0" alt="" width="16" height="16" align="absmiddle" /></td>
<td style="border: 1px solid #dddddd;padding: 5px;font-size: 10pt;line-height: 13pt;color: #000000;font-weight: normal;vertical-align: top"><img class="emoticon" src="http://www.huangwei.me/blog/wp-content/uploads/2011/01/error.gif" border="0" alt="" width="16" height="16" align="absmiddle" /></td>
<td style="border: 1px solid #dddddd;padding: 5px;font-size: 10pt;line-height: 13pt;color: #000000;font-weight: normal;vertical-align: top">异常退出</td>
</tr>
<tr style="font-size: 10pt;line-height: 13pt;color: #000000;font-weight: normal">
<td style="border: 1px solid #dddddd;padding: 5px;font-size: 10pt;line-height: 13pt;color: #000000;font-weight: normal;vertical-align: top"><tt>_Exit()</tt></td>
<td style="border: 1px solid #dddddd;padding: 5px;font-size: 10pt;line-height: 13pt;color: #000000;font-weight: normal;vertical-align: top"><img class="emoticon" src="http://www.huangwei.me/blog/wp-content/uploads/2011/02/information.gif" border="0" alt="" width="16" height="16" align="absmiddle" /></td>
<td style="border: 1px solid #dddddd;padding: 5px;font-size: 10pt;line-height: 13pt;color: #000000;font-weight: normal;vertical-align: top"><img class="emoticon" src="http://www.huangwei.me/blog/wp-content/uploads/2011/02/information.gif" border="0" alt="" width="16" height="16" align="absmiddle" /></td>
<td style="border: 1px solid #dddddd;padding: 5px;font-size: 10pt;line-height: 13pt;color: #000000;font-weight: normal;vertical-align: top"><img class="emoticon" src="http://www.huangwei.me/blog/wp-content/uploads/2011/02/information.gif" border="0" alt="" width="16" height="16" align="absmiddle" /></td>
<td style="border: 1px solid #dddddd;padding: 5px;font-size: 10pt;line-height: 13pt;color: #000000;font-weight: normal;vertical-align: top"><img class="emoticon" src="http://www.huangwei.me/blog/wp-content/uploads/2011/01/error.gif" border="0" alt="" width="16" height="16" align="absmiddle" /></td>
<td style="border: 1px solid #dddddd;padding: 5px;font-size: 10pt;line-height: 13pt;color: #000000;font-weight: normal;vertical-align: top">正常退出</td>
</tr>
<tr style="font-size: 10pt;line-height: 13pt;color: #000000;font-weight: normal">
<td style="border: 1px solid #dddddd;padding: 5px;font-size: 10pt;line-height: 13pt;color: #000000;font-weight: normal;vertical-align: top"><tt>exit()</tt></td>
<td style="border: 1px solid #dddddd;padding: 5px;font-size: 10pt;line-height: 13pt;color: #000000;font-weight: normal;vertical-align: top"><img class="emoticon" src="http://www.huangwei.me/blog/wp-content/uploads/2011/01/check.gif" border="0" alt="" width="16" height="16" align="absmiddle" /></td>
<td style="border: 1px solid #dddddd;padding: 5px;font-size: 10pt;line-height: 13pt;color: #000000;font-weight: normal;vertical-align: top"><img class="emoticon" src="http://www.huangwei.me/blog/wp-content/uploads/2011/01/check.gif" border="0" alt="" width="16" height="16" align="absmiddle" /></td>
<td style="border: 1px solid #dddddd;padding: 5px;font-size: 10pt;line-height: 13pt;color: #000000;font-weight: normal;vertical-align: top"><img class="emoticon" src="http://www.huangwei.me/blog/wp-content/uploads/2011/01/check.gif" border="0" alt="" width="16" height="16" align="absmiddle" /></td>
<td style="border: 1px solid #dddddd;padding: 5px;font-size: 10pt;line-height: 13pt;color: #000000;font-weight: normal;vertical-align: top"><img class="emoticon" src="http://www.huangwei.me/blog/wp-content/uploads/2011/01/check.gif" border="0" alt="" width="16" height="16" align="absmiddle" /></td>
<td style="border: 1px solid #dddddd;padding: 5px;font-size: 10pt;line-height: 13pt;color: #000000;font-weight: normal;vertical-align: top">正常退出</td>
<td></td>
<td></td>
</tr>
<tr style="font-size: 10pt;line-height: 13pt;color: #000000;font-weight: normal">
<td style="border: 1px solid #dddddd;padding: 5px;font-size: 10pt;line-height: 13pt;color: #000000;font-weight: normal;vertical-align: top"><tt>从main()返回</tt></td>
<td style="border: 1px solid #dddddd;padding: 5px;font-size: 10pt;line-height: 13pt;color: #000000;font-weight: normal;vertical-align: top"><img class="emoticon" src="http://www.huangwei.me/blog/wp-content/uploads/2011/01/check.gif" border="0" alt="" width="16" height="16" align="absmiddle" /></td>
<td style="border: 1px solid #dddddd;padding: 5px;font-size: 10pt;line-height: 13pt;color: #000000;font-weight: normal;vertical-align: top"><img class="emoticon" src="http://www.huangwei.me/blog/wp-content/uploads/2011/01/check.gif" border="0" alt="" width="16" height="16" align="absmiddle" /></td>
<td style="border: 1px solid #dddddd;padding: 5px;font-size: 10pt;line-height: 13pt;color: #000000;font-weight: normal;vertical-align: top"><img class="emoticon" src="http://www.huangwei.me/blog/wp-content/uploads/2011/01/check.gif" border="0" alt="" width="16" height="16" align="absmiddle" /></td>
<td style="border: 1px solid #dddddd;padding: 5px;font-size: 10pt;line-height: 13pt;color: #000000;font-weight: normal;vertical-align: top"><img class="emoticon" src="http://www.huangwei.me/blog/wp-content/uploads/2011/01/check.gif" border="0" alt="" width="16" height="16" align="absmiddle" /></td>
<td style="border: 1px solid #dddddd;padding: 5px;font-size: 10pt;line-height: 13pt;color: #000000;font-weight: normal;vertical-align: top">正常退出</td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/ERR05-C.+Application-independent+code+should+provide+error+detection+without+dictating+error+handling">ERR05-C. 应用程序独立的代码应提供错误检测而不需强制错误处理</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">应用程序独立的代码包括：</p>
<ul>
<li>编译器或操作系统提供</li>
<li>来自第三方库</li>
<li>自己开发的</li>
</ul>
<p>应用程序专属代码在检测到错误时可以立刻进行错误处理，而应用程序独立的代码则无法在特定应用程序出错时提供相应的错误处理方法。但必须要能检测错误并向应用程序中的调用者报告错误。错误检测和报告方法包括：</p>
<ul>
<li>返回值（特别是errno_t类型返回值）</li>
<li>一个地址参数</li>
<li>一个全局对象（例如errno）</li>
<li>longjmp()</li>
<li>以上方法的组合</li>
</ul>
</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/ERR06-C.+Understand+the+termination+behavior+of+assert%28%29+and+abort%28%29">ERR06-C. 理解assert()和abort()的退出行为</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">assert()宏会在执行时被展开为一个void表达式，并且在表达式的值为false时，在标准错误输出上给出相关错误信息，然后调用abort()终止程序运行。由于调用了abort()，atexit()注册的退出清理函数不会被调用执行，因此建议在可能的条件下调用static_assert宏而不是运行时assert宏。</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/ERR07-C.+Prefer+functions+that+support+error+checking+over+equivalent+functions+that+don%27t">ERR07-C. 优先使用支持错误检测机制的函数</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">例如优先使用strtol()而不是atoi()。</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/pages/viewpage.action?pageId=6619179">ERR30-C. 调用可能会出错并设置errno的库函数前先将errno置0,并在该函数返回值表示出错时再检查errno</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top"></td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/ERR31-C.+Don%27t+redefine+errno">ERR31-C. 禁止重新定义errno</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">该条规则已经被<a href="https://www.securecoding.cert.org/confluence/display/seccode/DCL37-C.+Do+not+use+identifiers+that+are+reserved+for+the+implementation" target="_blank">DCL37-C. 不要使用预留实现的标识符</a>和<a>MSC38-C. 禁止访问会引起未定义行为的库对象或函数 </a>代替</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/ERR32-C.+Do+not+rely+on+indeterminate+values+of+errno">ERR32-C. 禁止依赖不确定的errno值</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top"></td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/ERR33-C.+Detect+and+handle+errors">ERR33-C. 检测并处理错误</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top"></td>
</tr>
</tbody>
</table>
<h2><a href="https://www.securecoding.cert.org/confluence/display/seccode/13.+Application+Programming+Interfaces+%28API%29">13. 应用程序编程接口 </a></h2>
<p><span style="font-size: large"><span style="background-color: #ff0000"><strong>提示：本节的官方文档还处于“建设期”，故暂不提供翻译。</strong></span></span></p>
<table style="width: 100%" border="1">
<thead>
<tr>
<td style="font-weight: bold;text-align: center">规则/建议条目全称</td>
<td style="vertical-align: top"><span style="font-weight: bold">例外</span></td>
<td style="vertical-align: top"><span style="font-weight: bold">笔记 /备注/点评</span></td>
</tr>
</thead>
<tbody>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/API00-C.+Functions+should+validate+their+parameters">API00-C. Functions should validate their parameters</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top"></td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/API02-C.+Functions+that+read+or+write+to+or+from+an+array+should+take+an+argument+to+specify+the+source+or+target+size">API02-C. Functions that read or write to or from an array should take an argument to specify the source or target size</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top"></td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/API03-C.+Create+consistent+interfaces+and+capabilities+across+related+functions">API03-C. Create consistent interfaces and capabilities across related functions</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top"></td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/API04-C.+Provide+a+consistent+and+usable+error+checking+mechanism">API04-C. Provide a consistent and usable error checking mechanism</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top"></td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/API07-C.+Enforce+type+safety">API07-C. Enforce type safety</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top"></td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/API08-C.+Protect+header+prototypes+from+misinterpretation">API08-C. Protect header prototypes from misinterpretation</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top"></td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/API09-C.+Compatible+values+should+have+the+same+type">API09-C. Compatible values should have the same type</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top"></td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/DCL09-C.+Declare+functions+that+return+errno+with+a+return+type+of+errno_t">DCL09-C. Declare functions that return errno with a return type of errno_t</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top"></td>
</tr>
</tbody>
</table>
<h2><a href="https://www.securecoding.cert.org/confluence/display/seccode/14.+Concurrency+%28CON%29">14. 并发 </a></h2>
<table style="width: 100%" border="1">
<thead>
<tr>
<td style="font-weight: bold;text-align: center">规则/建议条目全称</td>
<td style="vertical-align: top"><span style="font-weight: bold">例外</span></td>
<td style="vertical-align: top"><span style="font-weight: bold">笔记 /备注/点评</span></td>
</tr>
</thead>
<tbody>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/CON00-C.+Avoid+race+conditions+with+multiple+threads">CON00-C. 避免多线程的竞争条件</a></td>
<td style="vertical-align: top">CON01-EX1: 允许取消运行的线程一般都会提供一个清理函数，在清理函数中释放互斥锁是允许的行为。</td>
<td style="vertical-align: top"></td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/CON01-C.+Acquire+and+release+synchronization+primitives+in+the+same+module%2C+at+the+same+level+of+abstraction">CON01-C. 在同一个模块、同一个抽象层次获得和释放同步原语</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top"></td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/CON31-C.+Do+not+unlock+or+destroy+another+thread%27s+mutex">CON31-C. 禁止解锁或删除其他线程的互斥锁</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top"></td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/CON32-C.+When+data+must+be+accessed+by+multiple+threads%2C+provide+a+mutex+and+guarantee+no+adjacent+data+is+also+accessed">CON32-C. 当多线程访问相同数据时，使用互斥锁并确保没有邻近数据也被访问到</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">当多线程访问相同变量时，由于内存数据表示的原因，可能会出现在同一个地址空间（一个字节）中同时存在多个变量值的问题（特别是多个bit类型变量共享同一个字节的存储空间）。因此，当一个或多个连续字节地址空间被互斥锁锁定时，可能会出现“误锁定”的情况（锁定一个变量的同时，锁定了目标变量所在地址空间的其他变量。后续其他线程试图访问“看上去没有加锁”的其他变量时，出现访问失败或加锁失败的“意外”情况）。针对此问题没有通用的跨平台解决方案，一般情况下建议将一个并发访问变量“嵌入”在一个共用体中，并且在共用体中同时嵌入一个long类型变量（目的是填充内存地址空间，保证共享变量所在内存地址附近不会再有其他变量）。以下就是一个“安全”共享变量的声明实例：</p>
<pre lang="c">struct multi_threaded_flags {
  volatile unsigned int flag1 : 2;
  volatile unsigned int flag2 : 2;
};

union mtf_protect {
  struct multi_threaded_flags s;
  long padding;
};
</pre>
</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/CON33-C.+Avoid+race+conditions+when+using+library+functions">CON33-C. 使用库函数时避免竞争条件</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">主要指的是多线程程序避免调用非“可重入安全”的库函数。典型的非“可重入安全”的库函数包括：</p>
<pre lang="c">    rand()
    getenv()
    strtok()
    strerror()
    asctime()
    ctime()
</pre>
</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/CON34-C.+Declare+objects+shared+between+threads+with+appropriate+storage+durations">CON34-C. 声明多线程共享对象时要注意使用恰当的存储周期</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">A线程访问其他线程的栈变量或线程本地变量时会导致非法内存访问错误。</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/CON35-C.+Avoid+deadlock+by+locking+in+predefined+order">CON35-C. 使用预定义的加锁顺序来避免死锁</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">死锁的产生需要四个条件同时满足：</p>
<ul>
<li>互斥访问</li>
<li>保持并且等待</li>
<li>无抢占</li>
<li>循环等待</li>
</ul>
<p>因此，预防死锁发生只需要破坏上述任意一个死锁必要条件即可。本规则建议“使用预定义的加锁顺序来避免死锁”。</p>
</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/CON36-C.+Do+not+perform+operations+that+can+block+while+holding+a+lock">CON36-C. 当持有锁时禁止执行可能会阻塞的操作</a></td>
<td style="vertical-align: top">CON36-EX1: 线程在持有一个或多个锁的同时又在等待另一个锁时会阻塞. 当获取多个锁时, 加锁顺序必须避免死锁, 如<a href="https://www.securecoding.cert.org/confluence/display/seccode/CON35-C.+Avoid+deadlock+by+locking+in+predefined+order">CON35-C. 使用预定义的加锁顺序来避免死锁</a></td>
<td style="vertical-align: top">阻塞操作包括但不限于：网络、文件和终端I/O。</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/CON37-C.+Do+not+use+more+than+one+mutex+for+concurrent+waiting+operations+on+a+condition+variable">CON37-C. 禁止使用超过1个互斥锁于一个条件变量的并发等待操作</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">pthread_cond_wait()和pthread_cond_timedwait()接受一个条件变量和一个互斥锁作为参数，并在条件变量被信号“唤醒”时先解锁再在运行前重新加锁。当一个线程A在等待特定的条件变量被满足和获得互斥锁时，另一个线程B可能已经持有该互斥锁并且只是在等待条件变量满足。但如果另一个线程B是持有另一个互斥锁的同时等待相同的条件变量被满足，则该行为是“未定义”的。</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/CON38-C.+Notify+all+threads+waiting+on+a+condition+variable+instead+of+a+single+thread">CON38-C. 通知所有在等待同一个条件变量的线程而不是某一个线程</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">避免死锁。</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/CON39-C.+Avoid+the+ABA+problem+with+lock-free+programming">CON39-C. 无锁编程时避免ABA问题</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">无锁编程指的是不使用显式的锁来同步更新一个共享数据结构。这种方法可以确保任意一个线程都不会被阻塞。该方法的优点体现在：</p>
<ul>
<li>可以应用于无法使用锁的场景，例如中断处理函数</li>
<li>相比较于基于锁的算法，在某些场景下更有优势，如多处理器环境下的扩展性会更好</li>
<li>避免实时系统中的优先级交错问题</li>
</ul>
<p>局限性体现在：</p>
<ul>
<li> 需要特殊的CPU原子操作指令支持，如 CAS (compare and swap)或LL/SC (load linked/store conditional)</li>
</ul>
<p>应用场景：</p>
<ul>
<li>Linux 2.5内核引入的“Read-copy-update” (RCU) </li>
<li>AMD多核系统上的无锁编程</li>
</ul>
<p>ABA问题指的是在数据同步过程中，一个变量值被先后读取了两次，并且两次读取结果完全相同。但实际上在这两次读取之间的时间片段里，另一个线程先修改了该变量值，然后做了些其他工作后又将该值修改回去。如果是内存分配或指针相关操作，则第二次读取操作有可能会出现“访问已释放的内存”错误。<br />
 避免ABA问题的方法可以使用加锁或者hazard指针（唯一写，并发读）。</p>
</td>
</tr>
</tbody>
</table>]]></description>
			<content:encoded><![CDATA[<div style="margin-top: 2px;">
<A href="http://creativecommons.org/licenses/by/3.0/deed.zh"><FONT color=#11779f><STRONG>版权声明</STRONG></FONT></A><FONT color=#11779f><STRONG>：可以任意转载，转载时请务必以超链接形式标明文章原始出处和<a href="http://www.huangwei.me/blog/">作者信息</a></STRONG></FONT>
</div>
<h2><a href="https://www.securecoding.cert.org/confluence/display/seccode/11.+Signals+%28SIG%29">11. 信号</a></h2>
<table style="width: 100%" border="1">
<thead>
<tr>
<td style="font-weight: bold;text-align: center">规则/建议条目全称</td>
<td style="vertical-align: top"><span style="font-weight: bold">例外</span></td>
<td style="vertical-align: top"><span style="font-weight: bold">笔记 /备注/点评</span></td>
</tr>
</thead>
<tbody>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/SIG00-C.+Mask+signals+handled+by+noninterruptible+signal+handlers">SIG00-C. 屏蔽由不可中断信号处理函数处理的信号</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">POSIX标准建议使用sigaction()，废弃signal()。但sigaction()不是C99标准。</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/SIG01-C.+Understand+implementation-specific+details+regarding+signal+handler+persistence">SIG01-C. 理解信号处理函数持久化相关的实现细节</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">*nix平台上的信号处理函数一般是实现为“持久化”的，即除非显式的删除该信号处理函数，否则该信号处理函数会一直运行时有效。而Windows平台上则恰好相反，信号处理函数被执行一次后就会自动被删除。</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/SIG02-C.+Avoid+using+signals+to+implement+normal+functionality">SIG02-C. 避免使用信号机制来实现普通函数功能</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">从代码可安全移植的角度设计的本条建议。</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/SIG30-C.+Call+only+asynchronous-safe+functions+within+signal+handlers">SIG30-C. 在信号处理函数内部仅调用异步安全函数</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">查手册确定异步安全函数有哪些。</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/SIG31-C.+Do+not+access+or+modify+shared+objects+in+signal+handlers">SIG31-C. 禁止在信号处理函数内部访问或修改共享对象</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">否则会导致竞争读写问题，引起数据状态的不一致。读写volatile sig_atomic_t类型变量则没有问题，读写其他类型变量的行为则是“未定义”的。</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/SIG32-C.+Do+not+call+longjmp%28%29+from+inside+a+signal+handler">SIG32-C. 在信号处理函数内部禁止调用longjmp()</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">本条规则和<a href="https://www.securecoding.cert.org/confluence/display/seccode/SIG30-C.+Call+only+asynchronous-safe+functions+within+signal+handlers">SIG30-C. 在信号处理函数内部仅调用异步安全函数</a>是相关的。</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/SIG33-C.+Do+not+recursively+invoke+the+raise%28%29+function">SIG33-C. 禁止递归调用raise()</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top"></td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/SIG34-C.+Do+not+call+signal%28%29+from+within+interruptible+signal+handlers">SIG34-C. 禁止在可中断信号处理函数内调用signal()</a></td>
<td style="vertical-align: top">SIG34-EX1: 在支持持久化信号处理函数的平台上信号处理函数可以安全的修改自己的信号处理行为。</td>
<td style="vertical-align: top">一个信号处理函数仅仅在其不需要是异步安全时可以嵌套调用signal()。</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/SIG35-C.+Do+not+return+from+SIGSEGV%2C+SIGILL%2C+or+SIGFPE+signal+handlers">SIG35-C. 禁止从SIGSEGV, SIGILL, 或SIGFPE的信号处理函数返回</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">否则会引起“未定义”行为。</td>
</tr>
</tbody>
</table>
<h2><a href="https://www.securecoding.cert.org/confluence/display/seccode/12.+Error+Handling+%28ERR%29">12. 错误处理 </a></h2>
<table style="width: 100%" border="1">
<thead>
<tr>
<td style="font-weight: bold;text-align: center">规则/建议条目全称</td>
<td style="vertical-align: top"><span style="font-weight: bold">例外</span></td>
<td style="vertical-align: top"><span style="font-weight: bold">笔记 /备注/点评</span></td>
</tr>
</thead>
<tbody>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/ERR00-C.+Adopt+and+implement+a+consistent+and+comprehensive+error-handling+policy">ERR00-C. 采用和实现一个一致和全面的错误处理策略</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top"></td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/ERR01-C.+Use+ferror%28%29+rather+than+errno+to+check+for+FILE+stream+errors">ERR01-C. 使用ferror()而不是errno来检查文件流错误</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">errno仅仅在某些库函数调用出错返回错误代码并会设置errno位时才有意义，并非所有的文件流操作操作都会设置errno。ferror()则是针对特定文件流是否操作出错的检查。</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/ERR02-C.+Avoid+in-band+error+indicators">ERR02-C. 避免“带内”(in-band)错误指示符</a></td>
<td style="vertical-align: top">ERR02-EX1: 空指针是另一个in-band错误指示符的例子，但空指针不会引起任何副作用。</p>
<p>ERR02-EX2: 如果你能保证函数在执行过程中出错时绝不会继续执行(可以通过调用abort()或者longjmp()中断函数执行过程)，你的函数就可以返回in-band错误指示符。</p>
</td>
<td style="vertical-align: top">所谓in-band，学过通信的都知道所谓“带内”信号和“带外”信号，in-band的含义就是所传递的信息会占用“正常”的传输通道资源。在C语言的标准库函数实现里大量的使用了in-band错误指示符，即函数的返回值在正常执行成功时会返回一些操作成功相关的变量值，函数执行出错时又利用返回值设置错误变量值。相当于函数的返回值在这里既是正常“返回结果”的传递通道，又是错误“返回结果”的传递通道。由于两种返回结果可能是不同的数据类型，因此函数在定义时可能会使用“兼容”数据类型，从而增加了函数调用者调用函数时的逻辑处理复杂度，可能会导致一些“二义性”或者“理解偏差”错误。</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/ERR03-C.+Use+runtime-constraint+handlers+when+calling+functions+defined+by+TR24731-1">ERR03-C. 调用TR24731-1标准定义的系列函数时使用运行时约束条件处理函数</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">strcpy_s()就是TR24731-1定义的一个函数，所谓“运行时约束条件处理函数”就是指的调用set_constraint_handler_s()注册一个运行时约束条件违反处理函数。该条建议主要针对微软平台，*nix平台忽略该条建议应该问题不大。</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/ERR04-C.+Choose+an+appropriate+termination+strategy">ERR04-C. 选择一个合适的程序退出策略</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">C99标准提供了4种程序退出策略：exit()、从main()函数返回、_Exit()和abort()。这四个函数的退出时动作差别如下表总结所示：</p>
<table class="confluenceTable" style="margin: 5px 0px;padding: 0px;font-size: 10pt;line-height: 13pt;color: #000000;font-weight: normal;clear: left;border-collapse: collapse">
<tbody>
<tr style="font-size: 10pt;line-height: 13pt;color: #000000;font-weight: normal">
<th>函数名</th>
<th>关闭所有打开的流</th>
<th>flush所有的流缓冲</th>
<th>删除所有临时文件</th>
<th>调用atexit()注册的处理函数</th>
<th>程序退出状态</th>
</tr>
<tr style="font-size: 10pt;line-height: 13pt;color: #000000;font-weight: normal">
<td style="border: 1px solid #dddddd;padding: 5px;font-size: 10pt;line-height: 13pt;color: #000000;font-weight: normal;vertical-align: top"><tt>abort()</tt></td>
<td style="border: 1px solid #dddddd;padding: 5px;font-size: 10pt;line-height: 13pt;color: #000000;font-weight: normal;vertical-align: top"><img class="emoticon" src="http://www.huangwei.me/blog/wp-content/uploads/2011/02/information.gif" border="0" alt="" width="16" height="16" align="absmiddle" /></td>
<td style="border: 1px solid #dddddd;padding: 5px;font-size: 10pt;line-height: 13pt;color: #000000;font-weight: normal;vertical-align: top"><img class="emoticon" src="http://www.huangwei.me/blog/wp-content/uploads/2011/02/information.gif" border="0" alt="" width="16" height="16" align="absmiddle" /></td>
<td style="border: 1px solid #dddddd;padding: 5px;font-size: 10pt;line-height: 13pt;color: #000000;font-weight: normal;vertical-align: top"><img class="emoticon" src="http://www.huangwei.me/blog/wp-content/uploads/2011/02/information.gif" border="0" alt="" width="16" height="16" align="absmiddle" /></td>
<td style="border: 1px solid #dddddd;padding: 5px;font-size: 10pt;line-height: 13pt;color: #000000;font-weight: normal;vertical-align: top"><img class="emoticon" src="http://www.huangwei.me/blog/wp-content/uploads/2011/01/error.gif" border="0" alt="" width="16" height="16" align="absmiddle" /></td>
<td style="border: 1px solid #dddddd;padding: 5px;font-size: 10pt;line-height: 13pt;color: #000000;font-weight: normal;vertical-align: top">异常退出</td>
</tr>
<tr style="font-size: 10pt;line-height: 13pt;color: #000000;font-weight: normal">
<td style="border: 1px solid #dddddd;padding: 5px;font-size: 10pt;line-height: 13pt;color: #000000;font-weight: normal;vertical-align: top"><tt>_Exit()</tt></td>
<td style="border: 1px solid #dddddd;padding: 5px;font-size: 10pt;line-height: 13pt;color: #000000;font-weight: normal;vertical-align: top"><img class="emoticon" src="http://www.huangwei.me/blog/wp-content/uploads/2011/02/information.gif" border="0" alt="" width="16" height="16" align="absmiddle" /></td>
<td style="border: 1px solid #dddddd;padding: 5px;font-size: 10pt;line-height: 13pt;color: #000000;font-weight: normal;vertical-align: top"><img class="emoticon" src="http://www.huangwei.me/blog/wp-content/uploads/2011/02/information.gif" border="0" alt="" width="16" height="16" align="absmiddle" /></td>
<td style="border: 1px solid #dddddd;padding: 5px;font-size: 10pt;line-height: 13pt;color: #000000;font-weight: normal;vertical-align: top"><img class="emoticon" src="http://www.huangwei.me/blog/wp-content/uploads/2011/02/information.gif" border="0" alt="" width="16" height="16" align="absmiddle" /></td>
<td style="border: 1px solid #dddddd;padding: 5px;font-size: 10pt;line-height: 13pt;color: #000000;font-weight: normal;vertical-align: top"><img class="emoticon" src="http://www.huangwei.me/blog/wp-content/uploads/2011/01/error.gif" border="0" alt="" width="16" height="16" align="absmiddle" /></td>
<td style="border: 1px solid #dddddd;padding: 5px;font-size: 10pt;line-height: 13pt;color: #000000;font-weight: normal;vertical-align: top">正常退出</td>
</tr>
<tr style="font-size: 10pt;line-height: 13pt;color: #000000;font-weight: normal">
<td style="border: 1px solid #dddddd;padding: 5px;font-size: 10pt;line-height: 13pt;color: #000000;font-weight: normal;vertical-align: top"><tt>exit()</tt></td>
<td style="border: 1px solid #dddddd;padding: 5px;font-size: 10pt;line-height: 13pt;color: #000000;font-weight: normal;vertical-align: top"><img class="emoticon" src="http://www.huangwei.me/blog/wp-content/uploads/2011/01/check.gif" border="0" alt="" width="16" height="16" align="absmiddle" /></td>
<td style="border: 1px solid #dddddd;padding: 5px;font-size: 10pt;line-height: 13pt;color: #000000;font-weight: normal;vertical-align: top"><img class="emoticon" src="http://www.huangwei.me/blog/wp-content/uploads/2011/01/check.gif" border="0" alt="" width="16" height="16" align="absmiddle" /></td>
<td style="border: 1px solid #dddddd;padding: 5px;font-size: 10pt;line-height: 13pt;color: #000000;font-weight: normal;vertical-align: top"><img class="emoticon" src="http://www.huangwei.me/blog/wp-content/uploads/2011/01/check.gif" border="0" alt="" width="16" height="16" align="absmiddle" /></td>
<td style="border: 1px solid #dddddd;padding: 5px;font-size: 10pt;line-height: 13pt;color: #000000;font-weight: normal;vertical-align: top"><img class="emoticon" src="http://www.huangwei.me/blog/wp-content/uploads/2011/01/check.gif" border="0" alt="" width="16" height="16" align="absmiddle" /></td>
<td style="border: 1px solid #dddddd;padding: 5px;font-size: 10pt;line-height: 13pt;color: #000000;font-weight: normal;vertical-align: top">正常退出</td>
<td></td>
<td></td>
</tr>
<tr style="font-size: 10pt;line-height: 13pt;color: #000000;font-weight: normal">
<td style="border: 1px solid #dddddd;padding: 5px;font-size: 10pt;line-height: 13pt;color: #000000;font-weight: normal;vertical-align: top"><tt>从main()返回</tt></td>
<td style="border: 1px solid #dddddd;padding: 5px;font-size: 10pt;line-height: 13pt;color: #000000;font-weight: normal;vertical-align: top"><img class="emoticon" src="http://www.huangwei.me/blog/wp-content/uploads/2011/01/check.gif" border="0" alt="" width="16" height="16" align="absmiddle" /></td>
<td style="border: 1px solid #dddddd;padding: 5px;font-size: 10pt;line-height: 13pt;color: #000000;font-weight: normal;vertical-align: top"><img class="emoticon" src="http://www.huangwei.me/blog/wp-content/uploads/2011/01/check.gif" border="0" alt="" width="16" height="16" align="absmiddle" /></td>
<td style="border: 1px solid #dddddd;padding: 5px;font-size: 10pt;line-height: 13pt;color: #000000;font-weight: normal;vertical-align: top"><img class="emoticon" src="http://www.huangwei.me/blog/wp-content/uploads/2011/01/check.gif" border="0" alt="" width="16" height="16" align="absmiddle" /></td>
<td style="border: 1px solid #dddddd;padding: 5px;font-size: 10pt;line-height: 13pt;color: #000000;font-weight: normal;vertical-align: top"><img class="emoticon" src="http://www.huangwei.me/blog/wp-content/uploads/2011/01/check.gif" border="0" alt="" width="16" height="16" align="absmiddle" /></td>
<td style="border: 1px solid #dddddd;padding: 5px;font-size: 10pt;line-height: 13pt;color: #000000;font-weight: normal;vertical-align: top">正常退出</td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/ERR05-C.+Application-independent+code+should+provide+error+detection+without+dictating+error+handling">ERR05-C. 应用程序独立的代码应提供错误检测而不需强制错误处理</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">应用程序独立的代码包括：</p>
<ul>
<li>编译器或操作系统提供</li>
<li>来自第三方库</li>
<li>自己开发的</li>
</ul>
<p>应用程序专属代码在检测到错误时可以立刻进行错误处理，而应用程序独立的代码则无法在特定应用程序出错时提供相应的错误处理方法。但必须要能检测错误并向应用程序中的调用者报告错误。错误检测和报告方法包括：</p>
<ul>
<li>返回值（特别是errno_t类型返回值）</li>
<li>一个地址参数</li>
<li>一个全局对象（例如errno）</li>
<li>longjmp()</li>
<li>以上方法的组合</li>
</ul>
</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/ERR06-C.+Understand+the+termination+behavior+of+assert%28%29+and+abort%28%29">ERR06-C. 理解assert()和abort()的退出行为</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">assert()宏会在执行时被展开为一个void表达式，并且在表达式的值为false时，在标准错误输出上给出相关错误信息，然后调用abort()终止程序运行。由于调用了abort()，atexit()注册的退出清理函数不会被调用执行，因此建议在可能的条件下调用static_assert宏而不是运行时assert宏。</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/ERR07-C.+Prefer+functions+that+support+error+checking+over+equivalent+functions+that+don%27t">ERR07-C. 优先使用支持错误检测机制的函数</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">例如优先使用strtol()而不是atoi()。</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/pages/viewpage.action?pageId=6619179">ERR30-C. 调用可能会出错并设置errno的库函数前先将errno置0,并在该函数返回值表示出错时再检查errno</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top"></td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/ERR31-C.+Don%27t+redefine+errno">ERR31-C. 禁止重新定义errno</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">该条规则已经被<a href="https://www.securecoding.cert.org/confluence/display/seccode/DCL37-C.+Do+not+use+identifiers+that+are+reserved+for+the+implementation" target="_blank">DCL37-C. 不要使用预留实现的标识符</a>和<a>MSC38-C. 禁止访问会引起未定义行为的库对象或函数 </a>代替</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/ERR32-C.+Do+not+rely+on+indeterminate+values+of+errno">ERR32-C. 禁止依赖不确定的errno值</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top"></td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/ERR33-C.+Detect+and+handle+errors">ERR33-C. 检测并处理错误</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top"></td>
</tr>
</tbody>
</table>
<h2><a href="https://www.securecoding.cert.org/confluence/display/seccode/13.+Application+Programming+Interfaces+%28API%29">13. 应用程序编程接口 </a></h2>
<p><span style="font-size: large"><span style="background-color: #ff0000"><strong>提示：本节的官方文档还处于“建设期”，故暂不提供翻译。</strong></span></span></p>
<table style="width: 100%" border="1">
<thead>
<tr>
<td style="font-weight: bold;text-align: center">规则/建议条目全称</td>
<td style="vertical-align: top"><span style="font-weight: bold">例外</span></td>
<td style="vertical-align: top"><span style="font-weight: bold">笔记 /备注/点评</span></td>
</tr>
</thead>
<tbody>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/API00-C.+Functions+should+validate+their+parameters">API00-C. Functions should validate their parameters</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top"></td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/API02-C.+Functions+that+read+or+write+to+or+from+an+array+should+take+an+argument+to+specify+the+source+or+target+size">API02-C. Functions that read or write to or from an array should take an argument to specify the source or target size</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top"></td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/API03-C.+Create+consistent+interfaces+and+capabilities+across+related+functions">API03-C. Create consistent interfaces and capabilities across related functions</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top"></td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/API04-C.+Provide+a+consistent+and+usable+error+checking+mechanism">API04-C. Provide a consistent and usable error checking mechanism</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top"></td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/API07-C.+Enforce+type+safety">API07-C. Enforce type safety</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top"></td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/API08-C.+Protect+header+prototypes+from+misinterpretation">API08-C. Protect header prototypes from misinterpretation</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top"></td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/API09-C.+Compatible+values+should+have+the+same+type">API09-C. Compatible values should have the same type</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top"></td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/DCL09-C.+Declare+functions+that+return+errno+with+a+return+type+of+errno_t">DCL09-C. Declare functions that return errno with a return type of errno_t</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top"></td>
</tr>
</tbody>
</table>
<h2><a href="https://www.securecoding.cert.org/confluence/display/seccode/14.+Concurrency+%28CON%29">14. 并发 </a></h2>
<table style="width: 100%" border="1">
<thead>
<tr>
<td style="font-weight: bold;text-align: center">规则/建议条目全称</td>
<td style="vertical-align: top"><span style="font-weight: bold">例外</span></td>
<td style="vertical-align: top"><span style="font-weight: bold">笔记 /备注/点评</span></td>
</tr>
</thead>
<tbody>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/CON00-C.+Avoid+race+conditions+with+multiple+threads">CON00-C. 避免多线程的竞争条件</a></td>
<td style="vertical-align: top">CON01-EX1: 允许取消运行的线程一般都会提供一个清理函数，在清理函数中释放互斥锁是允许的行为。</td>
<td style="vertical-align: top"></td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/CON01-C.+Acquire+and+release+synchronization+primitives+in+the+same+module%2C+at+the+same+level+of+abstraction">CON01-C. 在同一个模块、同一个抽象层次获得和释放同步原语</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top"></td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/CON31-C.+Do+not+unlock+or+destroy+another+thread%27s+mutex">CON31-C. 禁止解锁或删除其他线程的互斥锁</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top"></td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/CON32-C.+When+data+must+be+accessed+by+multiple+threads%2C+provide+a+mutex+and+guarantee+no+adjacent+data+is+also+accessed">CON32-C. 当多线程访问相同数据时，使用互斥锁并确保没有邻近数据也被访问到</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">当多线程访问相同变量时，由于内存数据表示的原因，可能会出现在同一个地址空间（一个字节）中同时存在多个变量值的问题（特别是多个bit类型变量共享同一个字节的存储空间）。因此，当一个或多个连续字节地址空间被互斥锁锁定时，可能会出现“误锁定”的情况（锁定一个变量的同时，锁定了目标变量所在地址空间的其他变量。后续其他线程试图访问“看上去没有加锁”的其他变量时，出现访问失败或加锁失败的“意外”情况）。针对此问题没有通用的跨平台解决方案，一般情况下建议将一个并发访问变量“嵌入”在一个共用体中，并且在共用体中同时嵌入一个long类型变量（目的是填充内存地址空间，保证共享变量所在内存地址附近不会再有其他变量）。以下就是一个“安全”共享变量的声明实例：</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">struct</span> multi_threaded_flags <span style="color: #009900;">&#123;</span>
  <span style="color: #993333;">volatile</span> <span style="color: #993333;">unsigned</span> <span style="color: #993333;">int</span> flag1 <span style="color: #339933;">:</span> <span style="color: #0000dd;">2</span><span style="color: #339933;">;</span>
  <span style="color: #993333;">volatile</span> <span style="color: #993333;">unsigned</span> <span style="color: #993333;">int</span> flag2 <span style="color: #339933;">:</span> <span style="color: #0000dd;">2</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #993333;">union</span> mtf_protect <span style="color: #009900;">&#123;</span>
  <span style="color: #993333;">struct</span> multi_threaded_flags s<span style="color: #339933;">;</span>
  <span style="color: #993333;">long</span> padding<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></pre></div></div>

</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/CON33-C.+Avoid+race+conditions+when+using+library+functions">CON33-C. 使用库函数时避免竞争条件</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">主要指的是多线程程序避免调用非“可重入安全”的库函数。典型的非“可重入安全”的库函数包括：</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;">    rand<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    getenv<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    strtok<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    strerror<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    asctime<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    ctime<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span></pre></div></div>

</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/CON34-C.+Declare+objects+shared+between+threads+with+appropriate+storage+durations">CON34-C. 声明多线程共享对象时要注意使用恰当的存储周期</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">A线程访问其他线程的栈变量或线程本地变量时会导致非法内存访问错误。</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/CON35-C.+Avoid+deadlock+by+locking+in+predefined+order">CON35-C. 使用预定义的加锁顺序来避免死锁</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">死锁的产生需要四个条件同时满足：</p>
<ul>
<li>互斥访问</li>
<li>保持并且等待</li>
<li>无抢占</li>
<li>循环等待</li>
</ul>
<p>因此，预防死锁发生只需要破坏上述任意一个死锁必要条件即可。本规则建议“使用预定义的加锁顺序来避免死锁”。</p>
</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/CON36-C.+Do+not+perform+operations+that+can+block+while+holding+a+lock">CON36-C. 当持有锁时禁止执行可能会阻塞的操作</a></td>
<td style="vertical-align: top">CON36-EX1: 线程在持有一个或多个锁的同时又在等待另一个锁时会阻塞. 当获取多个锁时, 加锁顺序必须避免死锁, 如<a href="https://www.securecoding.cert.org/confluence/display/seccode/CON35-C.+Avoid+deadlock+by+locking+in+predefined+order">CON35-C. 使用预定义的加锁顺序来避免死锁</a></td>
<td style="vertical-align: top">阻塞操作包括但不限于：网络、文件和终端I/O。</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/CON37-C.+Do+not+use+more+than+one+mutex+for+concurrent+waiting+operations+on+a+condition+variable">CON37-C. 禁止使用超过1个互斥锁于一个条件变量的并发等待操作</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">pthread_cond_wait()和pthread_cond_timedwait()接受一个条件变量和一个互斥锁作为参数，并在条件变量被信号“唤醒”时先解锁再在运行前重新加锁。当一个线程A在等待特定的条件变量被满足和获得互斥锁时，另一个线程B可能已经持有该互斥锁并且只是在等待条件变量满足。但如果另一个线程B是持有另一个互斥锁的同时等待相同的条件变量被满足，则该行为是“未定义”的。</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/CON38-C.+Notify+all+threads+waiting+on+a+condition+variable+instead+of+a+single+thread">CON38-C. 通知所有在等待同一个条件变量的线程而不是某一个线程</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">避免死锁。</td>
</tr>
<tr>
<td><a href="https://www.securecoding.cert.org/confluence/display/seccode/CON39-C.+Avoid+the+ABA+problem+with+lock-free+programming">CON39-C. 无锁编程时避免ABA问题</a></td>
<td style="vertical-align: top"></td>
<td style="vertical-align: top">无锁编程指的是不使用显式的锁来同步更新一个共享数据结构。这种方法可以确保任意一个线程都不会被阻塞。该方法的优点体现在：</p>
<ul>
<li>可以应用于无法使用锁的场景，例如中断处理函数</li>
<li>相比较于基于锁的算法，在某些场景下更有优势，如多处理器环境下的扩展性会更好</li>
<li>避免实时系统中的优先级交错问题</li>
</ul>
<p>局限性体现在：</p>
<ul>
<li> 需要特殊的CPU原子操作指令支持，如 CAS (compare and swap)或LL/SC (load linked/store conditional)</li>
</ul>
<p>应用场景：</p>
<ul>
<li>Linux 2.5内核引入的“Read-copy-update” (RCU) </li>
<li>AMD多核系统上的无锁编程</li>
</ul>
<p>ABA问题指的是在数据同步过程中，一个变量值被先后读取了两次，并且两次读取结果完全相同。但实际上在这两次读取之间的时间片段里，另一个线程先修改了该变量值，然后做了些其他工作后又将该值修改回去。如果是内存分配或指针相关操作，则第二次读取操作有可能会出现“访问已释放的内存”错误。<br />
 避免ABA问题的方法可以使用加锁或者hazard指针（唯一写，并发读）。</p>
</td>
</tr>
</tbody>
</table>
<div style="margin-top: 15px; ">
<hr style="border: 1px solid #cccccc;"/>
<p><strong>原创文章，转载请注明：</strong> 转载自<a href="http://www.huangwei.me/blog/">猪在笑</a> <a href="http://www.huangwei.me/blog/">[ http://www.huangwei.me/blog/ ]</a><br/><strong>本文链接地址:</strong> <a href="http://www.huangwei.me/blog/2011/02/06/cert-secure-coding-standard-4/">http://www.huangwei.me/blog/2011/02/06/cert-secure-coding-standard-4/</a></p>
<hr style="border: 1px solid #cccccc;"/>
</div>
<div  class="related_post_title">您可能还对以下文章感兴趣</div><ul class="related_post"><li><a href="http://www.huangwei.me/blog/2011/02/06/cert-secure-coding-standard/" title="[译]CERT Secure Coding Standard — C语言安全编程规范(5)">[译]CERT Secure Coding Standard — C语言安全编程规范(5)</a></li><li><a href="http://www.huangwei.me/blog/2011/02/05/cert-secure-coding-standard-3/" title="[译]CERT Secure Coding Standard — C语言安全编程规范(3)">[译]CERT Secure Coding Standard — C语言安全编程规范(3)</a></li><li><a href="http://www.huangwei.me/blog/2011/02/04/cert-secure-coding-standard-2/" title="[译]CERT Secure Coding Standard — C语言安全编程规范(2)">[译]CERT Secure Coding Standard — C语言安全编程规范(2)</a></li><li><a href="http://www.huangwei.me/blog/2011/02/03/cert-secure-coding-standard-1/" title="[译]CERT Secure Coding Standard — C语言安全编程规范(1)">[译]CERT Secure Coding Standard — C语言安全编程规范(1)</a></li><li><a href="http://www.huangwei.me/blog/2010/02/20/2010cwe25/" title="2010 CWE TOP 25">2010 CWE TOP 25</a></li><li><a href="http://www.huangwei.me/blog/2009/09/02/%e6%8e%a8%e8%8d%90%e5%9f%ba%e4%ba%8ewindbg%e7%9a%84%e4%b8%80%e4%b8%aa%e6%bc%8f%e6%b4%9e%e5%8f%af%e5%88%a9%e7%94%a8%e6%80%a7%e5%88%86%e6%9e%90%e6%8f%92%e4%bb%b6/" title="[推荐]基于Windbg的一个漏洞可利用性分析插件">[推荐]基于Windbg的一个漏洞可利用性分析插件</a></li><li><a href="http://www.huangwei.me/blog/2007/12/13/oip-dnsooauedhss-2/" title="[原创]IP-&#62;DNS域名反查小工具">[原创]IP-&#62;DNS域名反查小工具</a></li><li><a href="http://www.huangwei.me/blog/2011/08/17/lsof-and-fuser/" title="分享1个Linux命令lsof">分享1个Linux命令lsof</a></li><li><a href="http://www.huangwei.me/blog/2011/04/06/new-to-mac-2/" title="苹果小白的上手笔记(2)">苹果小白的上手笔记(2)</a></li><li><a href="http://www.huangwei.me/blog/2011/01/20/build-your-own-vulnerable-web-application/" title="自己动手搭建缺陷Web App">自己动手搭建缺陷Web App</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.huangwei.me/blog/2011/02/06/cert-secure-coding-standard-4/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

