<?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>Life N&#039; Tech</title>
	<atom:link href="http://jaconey.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://jaconey.com</link>
	<description>Jaconey的数字化生活</description>
	<lastBuildDate>Fri, 03 Feb 2012 03:20:18 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>MySQL 笔记之一</title>
		<link>http://jaconey.com/2012/02/03/mysql-%e7%ac%94%e8%ae%b0%e4%b9%8b%e4%b8%80/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=mysql-%25e7%25ac%2594%25e8%25ae%25b0%25e4%25b9%258b%25e4%25b8%2580</link>
		<comments>http://jaconey.com/2012/02/03/mysql-%e7%ac%94%e8%ae%b0%e4%b9%8b%e4%b8%80/#comments</comments>
		<pubDate>Fri, 03 Feb 2012 03:20:17 +0000</pubDate>
		<dc:creator>jaconey</dc:creator>
				<category><![CDATA[tech]]></category>
		<category><![CDATA[journal]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://jaconey.com/?p=137</guid>
		<description><![CDATA[最近要搞MySQL 相关的工作, 工欲善其事必先利其器, 简单了解了下MySQL 的架构 MySQL 架构 分了4层: Connection/thread handling. mysql 为每个连接创建了一个线程, 并且整个过程都在此线程内完成. 而线程会被缓存, 不会为每个连接创建一个新的. 这层还会把认证及权限的工作做了. Query cache/ Parser. select 指令到达后, 会先去cache 中, 看是否有命中记录, 有即直接返回结果. Parser 会解析并创建一用于描述指令的数据结构(parser tree). Optimizer. 这里会对parser tree 进行一系列的优化, 如 重写查询, 更改指令顺序等. 可以在查询中添加参数以修正优化的结果和行为. 并且可以输出记录以供指令的优化. Storage engines. 负责存储和读取所有mysql 的数据. 其中包括有性能优先, 空间优先等不同的引擎, 可以根据不同的应用场合选择. 数据一致性 MySQl 读写都有锁. MySQL 服务器及存储引擎都提供了多种锁的方案.&#160; 常用的lock 方式有2个: table locks. 最基本的锁方案. 写的时候会锁表, <a href='http://jaconey.com/2012/02/03/mysql-%e7%ac%94%e8%ae%b0%e4%b9%8b%e4%b8%80/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>最近要搞MySQL 相关的工作, 工欲善其事必先利其器, 简单了解了下MySQL 的架构</p>
<p>MySQL 架构</p>
<p><a href="http://jaconey.com/wp-content/uploads/2012/02/image.png"><img style="border-bottom: 0px;border-left: 0px;margin: 0px;padding-left: 0px;padding-right: 0px;border-top: 0px;border-right: 0px;padding-top: 0px" border="0" alt="image" src="http://jaconey.com/wp-content/uploads/2012/02/image_thumb.png" width="186" height="244" /></a></p>
<blockquote><p>分了4层:</p>
</blockquote>
<ol>
<li>
<ol>
<li>Connection/thread handling. mysql 为每个连接创建了一个线程, 并且整个过程都在此线程内完成. 而线程会被缓存, 不会为每个连接创建一个新的. 这层还会把认证及权限的工作做了.</li>
<li>Query cache/ Parser. select 指令到达后, 会先去cache 中, 看是否有命中记录, 有即直接返回结果. Parser 会解析并创建一用于描述指令的数据结构(parser tree).</li>
<li>Optimizer. 这里会对parser tree 进行一系列的优化, 如 重写查询, 更改指令顺序等. 可以在查询中添加参数以修正优化的结果和行为. 并且可以输出记录以供指令的优化.</li>
<li>Storage engines. 负责存储和读取所有mysql 的数据. 其中包括有性能优先, 空间优先等不同的引擎, 可以根据不同的应用场合选择. </li>
</ol>
</li>
</ol>
<p>数据一致性</p>
<blockquote><p> MySQl 读写都有锁. MySQL 服务器及存储引擎都提供了多种锁的方案.&#160; 常用的lock 方式有2个:</p>
</blockquote>
<ul>
<li>
<ul>
<li>table locks. 最基本的锁方案. 写的时候会锁表, 其他读写操作都会阻塞, 直到操作结束. READ LOCAL 可以允许某些写操作. 而写操作有着更高的优先级, 即使处理队列中有读操作,&#160; 也会优先处理写操作.</li>
<li>row locks. 是并发性最好的一种锁, 但也是消耗最多的. 只能由存储引擎支持,&#160; 一般认为只有InnoDB 和 Falcon 支持这种操作.&#160; </li>
</ul>
</li>
</ul>
<p>事务性:</p>
<blockquote><p>事务性的衡量指标主要是 <i>ACID (</i>Atomicity, Consistency, Isolation, and Durability). MySQL 主要靠存储引擎做到事务性, 但服务器本身也要做许多的事情以达到事务的目的. 而事务性本身会占用更多的cpu, 更多的内存, 更多的磁盘空间. 所以是否需要事务性是选择存储引擎的一个重要的指标. </p>
<p>在一个事务中存在更新同一行数据的话, 可能出现死锁问题, 各个引擎实现有不一样. 某些存储引擎会超时, 某些会做检测, 如InnoDB. 而发生这种情况都需要rollback, 死锁很难避免.</p>
<p>事务性分4个等级: READ UNCOMMITTED, READ COMMITTED ,&#160; REPEATABLE READ , SERIALIZABLE 具体意义参考手册</p>
<p>事务log. 基本上所有存储引擎都这么做: 先把数据写到内存中, 并记录log到磁盘上, 最终(可能在某个时刻) 更新到磁盘的数据库上. 这也意味着一次事务将至少写2次IO</p>
<p>MySQL 默认使用AUTOCOMMIT, 就是说每条指令都将默认在一个事务中进行, 除非你明确指定.</p>
<p>不要在一个事务中混合使用支持和不支持的存储引擎.</p>
<p>InnoDB 可以指定使用LOCK</p>
</blockquote>
<ul>
<li>
<ul>
<li>SELECT &#8230; LOCK IN SHARE MODE</li>
<li>SELECT &#8230; FOR UPDATE</li>
</ul>
</li>
</ul>
<blockquote><p>也可以使用服务器提供的:</p>
</blockquote>
<ul>
<li>
<ul>
<li>LOCK TABLES </li>
<li>UNLOCK TABLES</li>
</ul>
</li>
</ul>
<blockquote><p>但这两条指令很危险, 容易带来性能问题. 所以除非在事务中, 并且AUTOCOMMIT 不生效的情况下谨慎使用它们.</p>
</blockquote>
<p>多版本并发控制(Multiversion Concurrency Control):</p>
<blockquote><p>一些存储引擎如InnoDB, Falcon, and PBXT 支持这个技术. 可以不锁读取非在写的行, 所以意味着更高的并发性, 但同时带来更高的消耗(数据镜像及各种检查).</p>
</blockquote>
<p>数据引擎:</p>
<blockquote><p>MySQL 会为每个表 建立一个同名文件于文件系统中, 并以.frm 为后缀, 主要记录着表的元信息. </p>
</blockquote>
]]></content:encoded>
			<wfw:commentRss>http://jaconey.com/2012/02/03/mysql-%e7%ac%94%e8%ae%b0%e4%b9%8b%e4%b8%80/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>谈谈印度</title>
		<link>http://jaconey.com/2011/12/12/%e8%b0%88%e8%b0%88%e5%8d%b0%e5%ba%a6/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=%25e8%25b0%2588%25e8%25b0%2588%25e5%258d%25b0%25e5%25ba%25a6</link>
		<comments>http://jaconey.com/2011/12/12/%e8%b0%88%e8%b0%88%e5%8d%b0%e5%ba%a6/#comments</comments>
		<pubDate>Mon, 12 Dec 2011 02:59:25 +0000</pubDate>
		<dc:creator>jaconey</dc:creator>
				<category><![CDATA[other]]></category>
		<category><![CDATA[india]]></category>
		<category><![CDATA[journal]]></category>
		<category><![CDATA[work]]></category>
		<category><![CDATA[zhihu]]></category>

		<guid isPermaLink="false">http://jaconey.com/2011/12/12/%e8%b0%88%e8%b0%88%e5%8d%b0%e5%ba%a6/</guid>
		<description><![CDATA[周末被邀请回答了一个知乎的问题, 话题正好也是我一直想说说的, 就转到周记里吧. 提问如下: 印度人针对中国人而产生的优越感到底是从哪里来的？ 在Youtube上看了几个印度人上传的视频，例如：Why China hates India？Why India doesn&#8217;t hate China？之类的（还有几个没细看），视频中充斥着对中国的嘲讽、无知、和嫉妒。我承认中国确实有不少社会问题亟须解决，但印度有什么资格蔑视中国？除了 IT 业发达些（前英国殖民地），请知友们再列出几条印度的优势。 我: 首先, 要说明的是, 我认为每个民族都有莫名的优越感. 中国人这样, 美国人这样, 韩国人, 日本人, 印度人都是人, 也是相同的, 优越感都是莫名的, 不好解释. 另外, 一两个视频不能代表一个民族是否对另一个民族有没有偏见, 从我接触到的印度朋友来说, 没有这种感觉, 也许是他们和中国的接触比较多的关系. 我认为一切偏见都是源自不了解. 中国也有不少人很仇视&#34;以美帝为首的&#34;西方社会, 那么引用楼主的一句, 中国人又 &#34;有什么资格蔑视&#34; 他们呢? 因为所供职的公司的关系, 曾经常驻印度1年的时间. 就只说一下我看到的一些优点. 民主. 印度从上世纪开始就进入了民主社会, 政府是选举出来的, 民众有结社自由. 各种党派无数, 一到选举的日子, 就看到满街的宣传横幅, 各种候选人的头像就这样挂在街道的两旁, 在国内一定是要作为&#34;影响市容市貌&#34;的典范被销毁. 当然, 也带来了一些问题, &#34;效率低下&#34;. 记得当时公司旁边的一立交桥, 来的时候那个样, <a href='http://jaconey.com/2011/12/12/%e8%b0%88%e8%b0%88%e5%8d%b0%e5%ba%a6/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>周末被邀请回答了<a href="http://zhi.hu/BSzX">一个知乎的问题</a>, 话题正好也是我一直想说说的, 就转到周记里吧. 提问如下: </p>
<p><strong>印度人针对中国人而产生的优越感到底是从哪里来的？</strong></p>
<p>在Youtube上看了几个印度人上传的视频，例如：Why China hates India？Why India doesn&#8217;t hate China？之类的（还有几个没细看），视频中充斥着对中国的嘲讽、无知、和嫉妒。我承认中国确实有不少社会问题亟须解决，但印度有什么资格蔑视中国？除了 IT 业发达些（前英国殖民地），请知友们再列出几条印度的优势。 </p>
<hr />我:
<p>首先, 要说明的是, 我认为每个民族都有莫名的优越感. 中国人这样, 美国人这样, 韩国人, 日本人, 印度人都是人, 也是相同的, 优越感都是莫名的, 不好解释.    <br />另外, 一两个视频不能代表一个民族是否对另一个民族有没有偏见, 从我接触到的印度朋友来说, 没有这种感觉, 也许是他们和中国的接触比较多的关系.     <br />我认为一切偏见都是源自不了解. 中国也有不少人很仇视&quot;以美帝为首的&quot;西方社会, 那么引用楼主的一句, 中国人又 &quot;有什么资格蔑视&quot; 他们呢?     <br />因为所供职的公司的关系, 曾经常驻印度1年的时间. 就只说一下我看到的一些优点. </p>
<ol>
<li>民主. 印度从上世纪开始就进入了民主社会, 政府是选举出来的, 民众有结社自由. 各种党派无数, 一到选举的日子, 就看到满街的宣传横幅, 各种候选人的头像就这样挂在街道的两旁, 在国内一定是要作为&quot;影响市容市貌&quot;的典范被销毁. 当然, 也带来了一些问题, &quot;效率低下&quot;. 记得当时公司旁边的一立交桥, 来的时候那个样, 走的时候还是那个样, 据当地呆了4,5年的老员工讲, 这个桥从他们来的时候就开始建了. 据说是当地议会到现在都没讨论出来结果, 所以就停工了. 这种事情在习惯了&quot;中国速度&quot;的我们眼中是不可思议的. </li>
<li>信仰自由. 和大多数人想象的不同(太多人问我印度的佛教怎样怎样了), 印度最大的教不是佛教, 而是印度教. 除此以外各种教派很多, 宗教偶像也很多. 没到周末, 出了商业街之外, 最热闹的应该就是庙宇. 每次和他们出去team building 总是免不了要去几个庙宇祈福. 有信仰的一个很大的好处就是心灵有避风港. 有了问题, 有泄愤的地方, 心理压力也小一些. </li>
<li>金融业成熟. 生活中的表现就是城市里一个很小的商店也可以刷卡. 个人支票被广泛使用, 退税制度非常完善. 货币兑换市场化, 这也给我们这些&quot;外国人&quot; 带来了很多的便利. </li>
<li>再说一些小的点: 在各种公司都会见到一些行动不便的残疾人, 因为只要聘用他们, 政府就会退税给公司. 而跨国公司好像是要求有一定比例. 医院是福利组织. 记得一次半夜同事身体不适陪他去医院, 当天很冷, 刚进医院大堂就发现睡了好多衣衫褴褛的露宿者, 原来是躲到医院来了, 在我们的地方, 估计门都进不去就被保安赶走了. </li>
</ol>
<p> 有好, 肯定也有不好了
<ol>
<li>贫富差距悬殊. 我们办公的五星级酒店的后面, 就是一个很大的烂尾工地, 挖地三尺, 就烂掉了, 里面有好多用废品搭的帐篷, 住着社会最底层, 对比很强烈. 街上有奔驰宝马, 同时有人食不果腹. 但是奇怪的是很少看到新闻有&quot;群体事件&quot;的报道, 我个人觉得是因为宗教信仰的关系. </li>
<li>效率低下. 除了上面说到的政治原因外, 他们做事情确实不如国人勤劳, 一个中国人1天可以做完的事情, 交给他们需要2,3天, 而且不是个例, 很普遍的现象. </li>
<li>基础设施落后. 由于资产私有化, 政府没有任何权力侵犯个人资产, 所以开路非常难, 当时我在的bangalore也算是印度第5大城市, 但没有看到一条像样的路, 最宽的路4车道, 比起我们现在动不动就8车道的路来比, 它们确实非常小气. 各种产业园也很难建设, 原因还是上面说到的私有化问题导致. 不过这点我有点搞不清楚是优点还是缺点. 诸君明察. </li>
</ol>
<p>乱七八糟说了一堆, 都是带着我自己偏见的文字. 其实一直想写点自己对印度的感受, 就趁这个机会吐槽一翻, 不知道对问题有否帮助. 谨以这些文字作为对那段日子的一些纪念吧.</p>
]]></content:encoded>
			<wfw:commentRss>http://jaconey.com/2011/12/12/%e8%b0%88%e8%b0%88%e5%8d%b0%e5%ba%a6/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>性能测试-valgrind和google-perftools原理</title>
		<link>http://jaconey.com/2011/12/05/%e6%80%a7%e8%83%bd%e6%b5%8b%e8%af%95-valgrind%e5%92%8cgoogle-perftools%e5%8e%9f%e7%90%86/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=%25e6%2580%25a7%25e8%2583%25bd%25e6%25b5%258b%25e8%25af%2595-valgrind%25e5%2592%258cgoogle-perftools%25e5%258e%259f%25e7%2590%2586</link>
		<comments>http://jaconey.com/2011/12/05/%e6%80%a7%e8%83%bd%e6%b5%8b%e8%af%95-valgrind%e5%92%8cgoogle-perftools%e5%8e%9f%e7%90%86/#comments</comments>
		<pubDate>Mon, 05 Dec 2011 06:43:34 +0000</pubDate>
		<dc:creator>jaconey</dc:creator>
				<category><![CDATA[tech]]></category>
		<category><![CDATA[journal]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[test]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://jaconey.com/2011/12/05/%e6%80%a7%e8%83%bd%e6%b5%8b%e8%af%95-valgrind%e5%92%8cgoogle-perftools%e5%8e%9f%e7%90%86/</guid>
		<description><![CDATA[最近都在做服务器端的性能测试, 主要在做profile, 业界用的最多的估计就是万能的valgrind, 我们的引擎还嵌入了google的google-perftools. 具体的测试数据会在这周完成, 这里只记录下我对这两个工具的原理理解 Valgrind 这东东是linux 上很出名的开源性能测试工具, 主要的功能是测试内存, 还提供了cpu cache命中, call 统计, heap 测试, 线程测试等功能, 灰常强大, 所以应用面很广. valgrind 现在已经可以算是庞然大物了, 手册都有300页, 代码没仔细看, 只简单了解了下它的原理. valgrind 的执行不需要重新编译, 只要把二进制作为参数传入即可. 运行时会先把binary的debug 信息(估计主要是符号表)都读到自己的内存中, 用于结果的输出, 否则看到一堆地址, 估计谁都抓狂. 然后在内存中根据当前运行环境为找到对应的tools , 并根据tools 参数选择交给哪个继续执行, 默认是memcheck. 而最关键的是valgrind 的core, 程序的所有cpu指令都将被core接管, 再真正被执行. tools 会对指令进行处理, 插入自己需要的指令后, 再交给cpu, 以达到测试的目的. 由于接管了所有cpu指令, 所以valgrind 不但能测试到自有代码, 还会接管系统库的代码. 不过这也是比较头疼的, 因为输出的结果会包含很多我不关心的数据, 还好的是valgrind 提供方法去过滤这些信息. 但由于插入的代码量是根据工具不同不一样, <a href='http://jaconey.com/2011/12/05/%e6%80%a7%e8%83%bd%e6%b5%8b%e8%af%95-valgrind%e5%92%8cgoogle-perftools%e5%8e%9f%e7%90%86/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>最近都在做服务器端的性能测试, 主要在做profile, 业界用的最多的估计就是万能的valgrind, 我们的引擎还嵌入了google的google-perftools. 具体的测试数据会在这周完成, 这里只记录下我对这两个工具的原理理解 </p>
<h4><a name="Valgrind"></a>Valgrind </h4>
<p>这东东是linux 上很出名的开源性能测试工具, 主要的功能是测试内存, 还提供了cpu cache命中, call 统计, heap 测试, 线程测试等功能, 灰常强大, 所以应用面很广. </p>
<p>valgrind 现在已经可以算是庞然大物了, 手册都有300页, 代码没仔细看, 只简单了解了下它的原理. </p>
<p>valgrind 的执行不需要重新编译, 只要把二进制作为参数传入即可. 运行时会先把binary的debug 信息(估计主要是符号表)都读到自己的内存中, 用于结果的输出, 否则看到一堆地址, 估计谁都抓狂. 然后在内存中根据当前运行环境为找到对应的tools , 并根据tools 参数选择交给哪个继续执行, 默认是memcheck. 而最关键的是valgrind 的core, 程序的所有cpu指令都将被core接管, 再真正被执行. tools 会对指令进行处理, 插入自己需要的指令后, 再交给cpu, 以达到测试的目的. </p>
<p>由于接管了所有cpu指令, 所以valgrind 不但能测试到自有代码, 还会接管系统库的代码. 不过这也是比较头疼的, 因为输出的结果会包含很多我不关心的数据, 还好的是valgrind 提供方法去过滤这些信息. 但由于插入的代码量是根据工具不同不一样, 而且所有调用以及内存访问都可能会被处理, 所以程序会变的很慢, 官方数据是10-50倍的减速&#8230; 所以每次valgrind 都是很折磨的, 特别是我们这样的即时战斗游戏, 技能会出现很诡异的效果. 所以用valgrind的测试也许不是非常适合我们游戏. </p>
<h4><a name="Google_45perftools"></a>Google-perftools </h4>
<p>这个最早是google内部用的性能优化工具, 最出名的是它提供的tcmalloc, 号称在多线程的情况下是ptmalloc的10倍性能提升, 峰值出现在16 threads, 分配256k字节数据的时候. 再往后性能差别不大(参考 <a href="http://google-perftools.googlecode.com/svn/trunk/doc/tcmalloc.html">tmalloc 性能测试报告</a>). 但我们没有用到这个模块, 用的是它提供的cpu profiler. </p>
<p>google的cpu profiler (下简称pprof, 本来想用gprof, 但又和GNU的prof 名字冲突了, 就用了它提供的一个工具的名字)用的是取样的方法, 这个方法我曾经在stack overflow上看到一个老外说的(@maguschen 同学推荐的). 老外说的方法更原始, gdb 调试程序, 然后随意Ctrl+C, 对断点所在函数做个统计就可以知道程序的热点大概在什么地方了. 很有道理! goolgle 的这个profiler 完全就是根据这个原理实现的. </p>
<p>由于这个工具的代码不大(src/profiler.cc), 网上也有一些指引, 所以我是大概把原理过了一遍的, 大致如下: </p>
<ul>
<li>必须把profiler的库连接到程序中. 因为pprof 的初始化是通过一个库中的static 变量来实现的. </li>
<li>在类的cstor中,会调用Start     <br /><img alt="capture_004.png" src="http://das-project-x2.gz.netease.com/foswiki/pub/Main/%E6%80%A7%E8%83%BD%E6%B5%8B%E8%AF%95_valgrind%E5%92%8Cgoogle-perftools%E5%8E%9F%E7%90%86_%E5%BC%A0%E5%85%89%E6%AF%85/capture_004.png" width="681" height="438" /></li>
<li>其中重要的函数是StartTimer, 它启动了一个定时器,      <br /><img alt="capture_001.png" src="http://das-project-x2.gz.netease.com/foswiki/pub/Main/%E6%80%A7%E8%83%BD%E6%B5%8B%E8%AF%95_valgrind%E5%92%8Cgoogle-perftools%E5%8E%9F%E7%90%86_%E5%BC%A0%E5%85%89%E6%AF%85/capture_001.png" width="540" height="109" /></li>
<li>还有一个重要的函数是EnableHandler, 它注册了SIGPROF, 下面是这两个函数的实现(src/profile-handler.cc ):     <br /><img alt="capture_002.png" src="http://das-project-x2.gz.netease.com/foswiki/pub/Main/%E6%80%A7%E8%83%BD%E6%B5%8B%E8%AF%95_valgrind%E5%92%8Cgoogle-perftools%E5%8E%9F%E7%90%86_%E5%BC%A0%E5%85%89%E6%AF%85/capture_002.png" width="652" height="122" /></li>
<li>可以看到, 默认是启动了一个1000000 usec 的定时器, 定时器fire 的时候会发出SIGPROF 信号, pprof 响应了这个信号. 所以被测试的程序不能接管这个型号(这点是我的猜测, 没有通读代码, 不敢说这个一定成立, 但尽量不要这样做)     <br />而下面这段就是pprof的精华所在了:      <br /><img alt="capture_000.png" src="http://das-project-x2.gz.netease.com/foswiki/pub/Main/%E6%80%A7%E8%83%BD%E6%B5%8B%E8%AF%95_valgrind%E5%92%8Cgoogle-perftools%E5%8E%9F%E7%90%86_%E5%BC%A0%E5%85%89%E6%AF%85/capture_000.png" width="718" height="404" /></li>
<li>这里使用了libunwind库, 把现在的调用栈dump出来了, 然后放到collector中, 可以看到pprof 是异步输出的, 数据到将来的某个时刻才最后输出(一般是程序终结的时候, 也可用ProfileFlush函数把内容flush 到io去) </li>
</ul>
<p> 可以看到pprof 是基于采样, 和最上面提到的stack overflow上面提到的老外是一个方法, 所以pprof的结果是不准确的, 应该说是提供了一个统计学上的意义, 我们知道采样的可信度是和样本空间的大小是相关的, 所以如果想要pprof比较准确就需要较大的样本空间, 这可以通过2个方法做到:
<ol>
<li>增加测试时间; </li>
<li>增加采样密度; </li>
</ol>
<p> 而用pprof最大的感受是一个字 &#8212; &quot;快&quot;, 和许多profile 工具不一样, pprof 是很快的, 基本上感觉不到性能的下降, 甚至可以在生产环境只用它.</p>
]]></content:encoded>
			<wfw:commentRss>http://jaconey.com/2011/12/05/%e6%80%a7%e8%83%bd%e6%b5%8b%e8%af%95-valgrind%e5%92%8cgoogle-perftools%e5%8e%9f%e7%90%86/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>C++11-老树新芽还是回光返照</title>
		<link>http://jaconey.com/2011/11/28/c11-%e8%80%81%e6%a0%91%e6%96%b0%e8%8a%bd%e8%bf%98%e6%98%af%e5%9b%9e%e5%85%89%e8%bf%94%e7%85%a7/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=c11-%25e8%2580%2581%25e6%25a0%2591%25e6%2596%25b0%25e8%258a%25bd%25e8%25bf%2598%25e6%2598%25af%25e5%259b%259e%25e5%2585%2589%25e8%25bf%2594%25e7%2585%25a7</link>
		<comments>http://jaconey.com/2011/11/28/c11-%e8%80%81%e6%a0%91%e6%96%b0%e8%8a%bd%e8%bf%98%e6%98%af%e5%9b%9e%e5%85%89%e8%bf%94%e7%85%a7/#comments</comments>
		<pubDate>Mon, 28 Nov 2011 07:47:16 +0000</pubDate>
		<dc:creator>jaconey</dc:creator>
				<category><![CDATA[tech]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[journal]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://jaconey.com/2011/11/28/c11-%e8%80%81%e6%a0%91%e6%96%b0%e8%8a%bd%e8%bf%98%e6%98%af%e5%9b%9e%e5%85%89%e8%bf%94%e7%85%a7/</guid>
		<description><![CDATA[上周5 听了C++11 的一次介绍讲座, 这里就随便吐槽一下. C++11, 2011年4月通过ISO appoved的一个C++标准. 当第一次听到这个标准的时候, 我有点迷惑, 因为虽然我现在对这个语言不再感冒, 但毕竟曾经在它身上耗费了不少的光阴, 如同相恋多年最终还是无奈分手的恋人, 时不时还是会关心一下, 而却几乎没有注意到这么一个标准. 众所周知, ISO 要通过某个标准的过程是异常漫长的&#8230; google了一下才知道, 原来这个标准就是之前的C++0x, 太坑爹了, 据说是为了和以前的命名规则一致, 于是改名叫C++11. 小样, 换了个马甲就不认得你啦? 不过这次C++11 确实是这帮老人家们费尽脑汁想出来的一个非常革命性的C++版本. 甚至连C++之父, Bjame Stroustrup 童鞋也不禁要说, C++11 就像一个新的语言. 那么在吐槽之前, 先简单看看这次都加了什么相对比较&#34;强大&#34;的功能. 小的就不提了, 而且我也不了解, 想知道的去看标准文档吧: http://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?csnumber=50372 一如既往, 这标准的pdf文档份量十足, 12Mb多, 怎么看怎么吐血&#8230; 记得刚毕业的时候, 年少无知的我还曾经打印过一本, 足足牛顿高阶字典一般的厚度, 拿在手上有无比的满足感, 可看的时候就怂了&#8230; lambda表达式 [capture](parameters)-&#62;return-type {body} []里是函数调用的参数列表，表示一个Lambda表达式的开始，让我们来看一个Lambda例子： 假设你想计算某个字符串包含多少个大写字母，使用for_each()遍历一个char数组，下面的Lambda表达式确定每个字母是否是大写字母，每当它发现一个大写字母，Lambda表达式给Uppercase加1，Uppercase是定义在Lambda表达式外的一个变量： for_each(s, s+sizeof(s), [&#38;Uppercase] <a href='http://jaconey.com/2011/11/28/c11-%e8%80%81%e6%a0%91%e6%96%b0%e8%8a%bd%e8%bf%98%e6%98%af%e5%9b%9e%e5%85%89%e8%bf%94%e7%85%a7/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>上周5 听了C++11 的一次介绍讲座, 这里就随便吐槽一下. </p>
<p>C++11, 2011年4月通过ISO appoved的一个C++标准. 当第一次听到这个标准的时候, 我有点迷惑, 因为虽然我现在对这个语言不再感冒, 但毕竟曾经在它身上耗费了不少的光阴, 如同相恋多年最终还是无奈分手的恋人, 时不时还是会关心一下, 而却几乎没有注意到这么一个标准. 众所周知, ISO 要通过某个标准的过程是异常漫长的&#8230; </p>
<p>google了一下才知道, 原来这个标准就是之前的C++0x, 太坑爹了, 据说是为了和以前的命名规则一致, 于是改名叫C++11. 小样, 换了个马甲就不认得你啦? </p>
<p>不过这次C++11 确实是这帮老人家们费尽脑汁想出来的一个非常革命性的C++版本. 甚至连C++之父, Bjame Stroustrup 童鞋也不禁要说, C++11 就像一个新的语言. 那么在吐槽之前, 先简单看看这次都加了什么相对比较&quot;强大&quot;的功能. 小的就不提了, 而且我也不了解, 想知道的去看标准文档吧: <a href="http://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?csnumber=50372">http://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?csnumber=50372</a> 一如既往, 这标准的pdf文档份量十足, 12Mb多, 怎么看怎么吐血&#8230; 记得刚毕业的时候, 年少无知的我还曾经打印过一本, 足足牛顿高阶字典一般的厚度, 拿在手上有无比的满足感, 可看的时候就怂了&#8230; </p>
<h5><a name="lambda_232_161_168_232_190_190_229_188_143"></a>lambda表达式 </h5>
<pre>[capture](parameters)-&gt;return-type {body}</pre>
<p>[]里是函数调用的参数列表，表示一个Lambda表达式的开始，让我们来看一个Lambda例子： </p>
<p>假设你想计算某个字符串包含多少个大写字母，使用for_each()遍历一个char数组，下面的Lambda表达式确定每个字母是否是大写字母，每当它发现一个大写字母，Lambda表达式给Uppercase加1，Uppercase是定义在Lambda表达式外的一个变量： </p>
<pre>
<li> for_each(s, s+sizeof(s), [&amp;Uppercase] (char c) {
<li>    if (isupper(c))
<li>     Uppercase++;
<li>    });</li>
</pre>
<h5><a name="auto_229_146_140decltype"></a>auto和decltype </h5>
<p>在C++03中，在声明对象时，你必须指定对象的类型，然而，在许多情况下，对象的声明包括在初始化代码中，C++11利用了这个优势，允许你声明对象时不指定类型： </p>
<pre>
<li>auto x=0; //x has type int because 0 is int
<li>auto c='a'; //char
<li>auto d=0.5; //double
<li>auto national_debt=14400000000000LL;//long long</li>
</pre>
<p>相反，你可以声明下面这样的迭代器： </p>
<pre>
<li>void fucn(const vector&lt;int&gt; &amp;vi)
<li>{
<li>  auto ci=vi.begin();
<li>}</li>
</pre>
<p>也可以使用decltype 关键字来推断返回值类型而用于声明中: </p>
<pre>
<li>const vector&lt;int&gt; vi;
<li>typedef decltype (vi.begin()) CIT;
<li>CIT another_const_iterator;</li>
</pre>
<h5><a name="Delete_229_146_140_Default_229_133_179_233_148_174_229_173_151"></a>Delete 和 Default 关键字 </h5>
<p>C++11 加入了delete关键字, 比如我们知道编译器一般都会为每个类对象生成一些默认的函数, 比如默认构造函数, 默认析构函数, 默认赋值函数等, 而在我们不希望编译器为我们生成这样的函数的时候, 可以使用delete这个关键字给这些函数&quot;赋值&quot;, 例如: </p>
<pre>struct NoCopy
{
    NoCopy &amp; operator =( const NoCopy &amp; ) = delete;
    NoCopy ( const NoCopy &amp; ) = delete;
};
NoCopy a;
NoCopy b(a); //compilation error, copy ctor is deleted</pre>
<p>而default 则恰好相反, 如果需要默认函数的时候, 就可以把该函数赋值default, 比如默认构造和析构函数. </p>
<h5><a name="A_229_133_182_228_187_150"></a>其他 </h5>
<p>C++11的新特性还包括了真正意义上的空指针, 委托构造函数, 右值引用, 统一初始化构造等等新的特性. 这里就不一一描述了, 网上描写很多, 就不一一举例. </p>
<h5><a name="A_229_144_144_230_167_189"></a>吐槽 </h5>
<p>我必须先承认, 我是anti-cpp的, 所以观点不保证任何公平性, 自问多少有点偏见. 不同意的童鞋也欢迎尽管吐槽 =) </p>
<p>对于这次C++11 的推出, 有人很乐观, 觉得是老树焕新芽, 可以救C++ 一命, 因为随着C++使用者的不断减少, 以及脚本语言的兴起, 这门语言已经越来越式微, 离开市场也许指日可待, 成为一个教科书上的语言. </p>
<p>而我觉得这次的11标准也许是它的回光返照. 因为对于这几个比较多人关注的新语法特性, 我有一些看法: </p>
<ul>
<li>确实, 引入了lambda 对于程序的结构会有很大的改变, 一些代码可以被嵌入到另一堆的代码当中去. 但这样的写法是否优雅呢? 我持保留态度. 而且这个[] 的关键字也是非常的蛋痛, 特别是比如你看到这样的一个表达式, [](){}() , 我想不抓狂的人应该属于少数吧? </li>
<li>auto是个很方便的特性, decltype 看上去也很美. 不过试想一下这样的一个场景:<br />
    <br />{ </p>
<p>auto i = foo();</p>
<p>shot(i);</p>
<p>}</p>
<p>那么这个shot的编写者可能就会开始郁闷了, i的类型是不定的, 那么我要写什么样的函数呢? 因为声明中是不能有auto的, 所以还是需要为每个i的类型写函数, 或者用范式? 明明是一个强类型的语言, 为何要装纯想减弱这个强类型呢? 多少有点不伦不类了&#8230;</p>
<p>不过, 这个功能也是唯一一个我觉得会被广泛使用的功能, 因为确实在处理iterator的时候方便好多, 因为每次写iterator的类型的时候都很让人抓狂&#8230; btw, for_each 的引入也是不错的一个功能. </li>
<li>delete 和default 就更加蛋痛的功能了. 类似的功能在03标准中就已经可以比较好的方式实现, 用了这两个关键字之后就显得有点蛋痛, 而且除了对编译器能生成的函数以外, default是没有其他用途的, 比如Car 类有个函数叫ChangeTire, 它是无论如何都没法default的. 唯一换来的好处可能是让看头文件的人更加清楚, 那些默认行为没有了, 也能省下来一点点的编译时间和编译后size(??) </li>
<li>至于右值引用我就觉得更蛋痛了. 这个功能我坦白我没非常了解它的正确用法, 在讲解会上也没有听的很明白, 本来晦涩的特性在C++里面已经不算新鲜了, 这次又引入那么一个, 那么可想而知这个功能如果使用起来会引入多少bug&#8230; </li>
<li>编译器的支持将会是这个标准被废掉的另一个原因. 这次的更新很强大, 甚至连Bjame 都觉得不认识它了. 但是这些功能对于编译器开发者来说估计是个噩梦, 支持单一的功能也许不麻烦, 但是在支持的基础上编译器还要能够编译03版本的C++程序, 做到兼容估计需要不短的时间, 据说gcc和vc 都已经支持了一部分, 但在短期内没有全面支持C++11 的打算. 如果没有编译器的支持, 这个标准只能作为一纸空文了. </li>
</ul>
<p>不得不承认, C++11 的制定者们还是很有想法的, 也不愧是牛人, 为了挽救这门语言, 他们费尽心思, 想让它焕发青春. 不过从我的角度, 这次的修改没有能够改变我对它的看法. 依然的高高在上, 依然的语法晦涩. C++活下去是一点问题没有的, 单单是全球的大学就可以让它活下去并且活得不错. 但这次修改我认为是没法让它恢复年轻的. </p>
<p>正如最近看完了7本的&lt;明朝那些事儿&gt;, 在明末的描述中, 不断的提到一个词: 气数已尽. 确实如此, 每个物体都是有生命周期的, 人会死, 植物会枯萎, 没有事物是永恒的, 不过我不是算命先生, C++ 气数如何我无从得知, 但它已经青春不再应该无容置疑了. 一厢情愿的想返老还童不太现实, 还不如趁此机会把优势发扬光大, 而不是一天黑路走到底, 更好&#8230;. </p>
]]></content:encoded>
			<wfw:commentRss>http://jaconey.com/2011/11/28/c11-%e8%80%81%e6%a0%91%e6%96%b0%e8%8a%bd%e8%bf%98%e6%98%af%e5%9b%9e%e5%85%89%e8%bf%94%e7%85%a7/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>游戏开发&#8211; 寻路系列之三</title>
		<link>http://jaconey.com/2011/11/21/%e6%b8%b8%e6%88%8f%e5%bc%80%e5%8f%91-%e5%af%bb%e8%b7%af%e7%b3%bb%e5%88%97%e4%b9%8b%e4%b8%89/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=%25e6%25b8%25b8%25e6%2588%258f%25e5%25bc%2580%25e5%258f%2591-%25e5%25af%25bb%25e8%25b7%25af%25e7%25b3%25bb%25e5%2588%2597%25e4%25b9%258b%25e4%25b8%2589</link>
		<comments>http://jaconey.com/2011/11/21/%e6%b8%b8%e6%88%8f%e5%bc%80%e5%8f%91-%e5%af%bb%e8%b7%af%e7%b3%bb%e5%88%97%e4%b9%8b%e4%b8%89/#comments</comments>
		<pubDate>Mon, 21 Nov 2011 05:45:30 +0000</pubDate>
		<dc:creator>jaconey</dc:creator>
				<category><![CDATA[tech]]></category>
		<category><![CDATA[dev]]></category>
		<category><![CDATA[game]]></category>
		<category><![CDATA[journal]]></category>
		<category><![CDATA[nav]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://jaconey.com/2011/11/21/%e6%b8%b8%e6%88%8f%e5%bc%80%e5%8f%91-%e5%af%bb%e8%b7%af%e7%b3%bb%e5%88%97%e4%b9%8b%e4%b8%89/</guid>
		<description><![CDATA[上周讲了A* 的基本原理, 不知道有人能看懂不? 其实原理并不是非常复杂, 但实现起来的方案倒是有不少, 就像所有算法一样, 一般来说, 实现都比原理难得多.不过篇幅有限, 这里就不谈实现了, 只谈原理. 寻路算法介绍完了之后, 就来讲讲如何生成数据, 就和人的双腿一样, 数据就是寻路模块的另一条腿. 这里我尽量简单的 用我自己的表达方式来描述, 由于过程很多, 我也没有能非常好的理解, 所以有遗漏还请大家补充. 我们的网格生成主要是用了这个方法Navmesh, 原理介绍我主要参考了这个网站, 有兴趣的同学也可以了解一下: http://www.critterai.org/nmgen_study navmesh的生成主要有这么几步: Voxelization &#8211; Create a solid heightfield from the source geometry. Generate Regions &#8211; Detect the top surface area of the solid heightfield and divide it up into regions of contiguous spans. <a href='http://jaconey.com/2011/11/21/%e6%b8%b8%e6%88%8f%e5%bc%80%e5%8f%91-%e5%af%bb%e8%b7%af%e7%b3%bb%e5%88%97%e4%b9%8b%e4%b8%89/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>上周讲了A* 的基本原理, 不知道有人能看懂不? 其实原理并不是非常复杂, 但实现起来的方案倒是有不少, 就像所有算法一样, 一般来说, 实现都比原理难得多.不过篇幅有限, 这里就不谈实现了, 只谈原理. </p>
<p>寻路算法介绍完了之后, 就来讲讲如何生成数据, 就和人的双腿一样, 数据就是寻路模块的另一条腿. </p>
<p>这里我尽量简单的 用我自己的表达方式来描述, 由于过程很多, 我也没有能非常好的理解, 所以有遗漏还请大家补充. </p>
<p>我们的网格生成主要是用了这个方法Navmesh, 原理介绍我主要参考了这个网站, 有兴趣的同学也可以了解一下: <a href="http://www.critterai.org/nmgen_study">http://www.critterai.org/nmgen_study</a></p>
<p>navmesh的生成主要有这么几步: </p>
<ol>
<li><a href="http://www.cs.sunysb.edu/%7Evislab/projects/volume/Papers/Voxel/index.html">Voxelization</a> &#8211; Create a solid <a href="http://www.critterai.org/nmgen_hfintro">heightfield</a> from the source geometry. </li>
<li>Generate Regions &#8211; Detect the top surface area of the solid heightfield and divide it up into regions of contiguous spans. </li>
<li>Generate Contours &#8211; Detect the contours of the regions and form them into <a href="http://en.wikipedia.org/wiki/Polygon#Convexity_and_types_of_non-convexity">simple polygons</a>. </li>
<li>Generate Polygon Mesh &#8211; Sub-divide the contours into convex polygons. </li>
<li>Generate Detailed Mesh &#8211; <a href="http://mathworld.wolfram.com/Triangulation.html">Triangulate</a> the polygon mesh and add height detail. </li>
</ol>
<h4><a name="A_228_189_147_231_180_160_229_140_150Voxelization"></a>体素化Voxelization </h4>
<p>这一步是向量空间(vector space) 到 体素空间(voxel space) 的转换. 用到的是叫保守体素化(Conservative voxelization) 的算法, 它保证了每个多边形面都能完全被生成的三维象素(voxel)包裹, 如下图: </p>
<p><img alt="" src="http://www.critterai.org/sites/default/files/study/nmgen/gen_01_conservvox.jpg" /></p>
<p>体素化后, 生成的都是可寻路的高度场(heightfield)信息, 不可寻路部分被剔除.这一步是从一个固态高度场(solid heightfield) 生成一个开放高度场(open heightfield) 的过程, 一个开放高度场表示在一个固态空间上可能寻路的平面. </p>
<p>这个概念有点抽象, 请往下看&#8230; </p>
<h4><a name="A_229_140_186_229_159_159_231_148_159_230_136_144Region_Generation"></a>区域生成Region Generation </h4>
<p>这一步的目标是进一步的定义,那部分的面是可以寻路的, 并且把寻路区域分隔成连续的平面以供最后生成简单寻路多边形. </p>
<p>最终结果如下图, 墙体,围栏, 柱子, 桌子底等不可能寻路的平面在这步根据邻居信息和分水岭算法(the watershed algorithm) 被剔除, 一些孤立的小局域(比如桌子表面) 也被剔除. </p>
<p><img alt="" src="http://www.critterai.org/sites/default/files/nmgen/stage_regions.gif" /></p>
<p>留意楼梯, 虽然是多级, 个平面并没有连通, 但是也会被当做一个平面(绿色). 楼梯扶手等平面也被剔除. </p>
<h4><a name="A_232_189_174_229_187_147_231_148_159_230_136_144Contour_Generation"></a>轮廓生成Contour Generation </h4>
<p>这一步将完成从体素空间回归到向量空间的转换. 区域(region) 的轮廓将被&quot;遍历(walk)&quot;, 形成简单的多边形. </p>
<p>其中, 有些区域被合并, 多边形的边更平滑, 边长度被优化.   <br /><img alt="" src="http://www.critterai.org/sites/default/files/nmgen/cont_11_simplified_full.jpg" /></p>
<p>这一步结束后, 可寻路区域已经被一些简化的多边形所表示 </p>
<h4><a name="A_229_135_184_229_164_154_232_190_185_229_189_162_231_148_159_230_136_144Convex_Polygon_Generation"></a>凸多边形生成Convex Polygon Generation </h4>
<p>凸多边形生成算法很多,这里就不多介绍, 这里主要是使用了把多边形切分为三角形, 然后尽量合并的方式做, 结果如下图: </p>
<p><img alt="" src="http://www.critterai.org/sites/default/files/nmgen/stage_polygon_mesh.jpg" /></p>
<h4><a name="A_231_178_190_231_187_134_231_189_145_230_160_188_231_148_159_230_136_144Detailed_Mesh_Generation"></a>精细网格生成Detailed Mesh Generation </h4>
<p>这是navmesh的最后一步, 凸多边形通过&quot;德劳内三角化&quot;(<a href="http://en.wikipedia.org/wiki/Delaunay_triangulation">Delaunay triangulation</a>) 算法三角化成包含高度信息的三角形(注意楼梯) </p>
<p><img alt="" src="http://www.critterai.org/sites/default/files/nmgen/stage_detail_mesh.jpg" /></p>
<p>顶点信息也会在这里补到各个三角形上, 以保证高度信息和模型保持一致. </p>
<p>至此, 寻路的数据生成完毕, 可以用于简单寻路系统. 各部分数据都有可能被寻路算法使用, 有多种方法去获取到数据以用于决定寻路的各个步骤. </p>
<p>其实上面的每一步都可以展开很多, 整个navmesh的生成非常复杂, 而且用到了许多算法, 完全可以写几篇论文以介绍, 这里就不展开了(我也没这实力), </p>
<p>有兴趣深入的同学可以参考下面的几个网站, 里面都非常专业的提供了实现方面的介绍(包括实现): </p>
<p><a href="http://digestingduck.blogspot.com/2010/05/constrained-movement-along-navmesh-pt-2.html">http://digestingduck.blogspot.com/2010/05/constrained-movement-along-navmesh-pt-2.html</a></p>
<p><a href="http://code.google.com/p/recastnavigation/">http://code.google.com/p/recastnavigation/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://jaconey.com/2011/11/21/%e6%b8%b8%e6%88%8f%e5%bc%80%e5%8f%91-%e5%af%bb%e8%b7%af%e7%b3%bb%e5%88%97%e4%b9%8b%e4%b8%89/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>游戏开发&#8211; 寻路系列之二</title>
		<link>http://jaconey.com/2011/11/14/%e6%b8%b8%e6%88%8f%e5%bc%80%e5%8f%91-%e5%af%bb%e8%b7%af%e7%b3%bb%e5%88%97%e4%b9%8b%e4%ba%8c/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=%25e6%25b8%25b8%25e6%2588%258f%25e5%25bc%2580%25e5%258f%2591-%25e5%25af%25bb%25e8%25b7%25af%25e7%25b3%25bb%25e5%2588%2597%25e4%25b9%258b%25e4%25ba%258c</link>
		<comments>http://jaconey.com/2011/11/14/%e6%b8%b8%e6%88%8f%e5%bc%80%e5%8f%91-%e5%af%bb%e8%b7%af%e7%b3%bb%e5%88%97%e4%b9%8b%e4%ba%8c/#comments</comments>
		<pubDate>Mon, 14 Nov 2011 03:44:00 +0000</pubDate>
		<dc:creator>jaconey</dc:creator>
				<category><![CDATA[tech]]></category>
		<category><![CDATA[journal]]></category>
		<category><![CDATA[nav]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://jaconey.com/2011/11/14/%e6%b8%b8%e6%88%8f%e5%bc%80%e5%8f%91-%e5%af%bb%e8%b7%af%e7%b3%bb%e5%88%97%e4%b9%8b%e4%ba%8c/</guid>
		<description><![CDATA[上次说到，寻路算法主要是使用A* 算法，而算法的简单流程也已经介绍过，这里贴一下更具体一点的算法内容。 A*（A-Star)算法是一种静态路网中求解最短路最有效的方法。 公式表示为： f(n)=g(n)+h(n), 其中f(n) 是节点n从初始点到目标点的估价函数， g(n) 是在状态空间中从初始节点到n节点的实际代价， h(n)是从n到目标节点最佳路径的估计代价。 保证找到最短路径（最优解的）条件，关键在于估价函数h(n)的选取： 估价值h(n)&#60;= n到目标节点的距离实际值，这种情况下，搜索的点数多，搜索范围大，效率低。但能得到最优解。 如果 估价值&#62;实际值, 搜索的点数少，搜索范围小，效率高，但不能保证得到最优解。 估价值与实际值越接近，估价函数取得就越好。 例如对于几何路网来说，可以取两节点间欧几理德距离（直线距离）做为估价值，即f=g(n)+sqrt((dx-nx)*(dx-nx)+(dy- ny)*(dy-ny))；这样估价函数f在g值一定的情况下，会或多或少的受估价值h的制约，节点距目标点近，h值小，f值相对就小，能保证最短路的搜索向终点的方向进行。明显优于Dijstra算法的毫无无方向的向四周搜索。 主要搜索过程： 创建两个表，OPEN表保存所有已生成而未考察的节点，CLOSED表中记录已访问过的节点。 遍历当前节点的各个节点，将n节点放入CLOSE中，取n节点的子节点X,-&#62;算X的估价值-&#62; While(OPEN!=NULL) { 从OPEN表中取估价值f最小的节点n; if(n节点==目标节点) break; else { if(X in OPEN) 比较两个X的估价值f //注意是同一个节点的两个不同路径的估价值 if( X的估价值小于OPEN表的估价值 ) 更新OPEN表中的估价值; //取最小路径的估价值 if(X in CLOSE) 比较两个X的估价值 //注意是同一个节点的两个不同路径的估价值 if( X的估价值小于CLOSE表的估价值 ) 更新CLOSE表中的估价值; 把X节点放入OPEN //取最小路径的估价值 if(X not in both) 求X的估价值; <a href='http://jaconey.com/2011/11/14/%e6%b8%b8%e6%88%8f%e5%bc%80%e5%8f%91-%e5%af%bb%e8%b7%af%e7%b3%bb%e5%88%97%e4%b9%8b%e4%ba%8c/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>上次说到，寻路算法主要是使用A* 算法，而算法的简单流程也已经介绍过，这里贴一下更具体一点的算法内容。 </p>
<p>A*（A-Star)算法是一种静态路网中求解最短路最有效的方法。</p>
<p>公式表示为： f(n)=g(n)+h(n),    <br />其中f(n) 是节点n从初始点到目标点的估价函数，     <br />g(n) 是在状态空间中从初始节点到n节点的实际代价，     <br />h(n)是从n到目标节点最佳路径的估计代价。</p>
<p>保证找到最短路径（最优解的）条件，关键在于估价函数h(n)的选取：</p>
<ul>
<li>估价值h(n)&lt;= n到目标节点的距离实际值，这种情况下，搜索的点数多，搜索范围大，效率低。但能得到最优解。 </li>
<li>如果 估价值&gt;实际值, 搜索的点数少，搜索范围小，效率高，但不能保证得到最优解。 </li>
<li>估价值与实际值越接近，估价函数取得就越好。 </li>
<li>例如对于几何路网来说，可以取两节点间欧几理德距离（直线距离）做为估价值，即f=g(n)+sqrt((dx-nx)*(dx-nx)+(dy- ny)*(dy-ny))；这样估价函数f在g值一定的情况下，会或多或少的受估价值h的制约，节点距目标点近，h值小，f值相对就小，能保证最短路的搜索向终点的方向进行。明显优于Dijstra算法的毫无无方向的向四周搜索。 </li>
</ul>
<p>主要搜索过程：</p>
<ul>
<li>创建两个表，OPEN表保存所有已生成而未考察的节点，CLOSED表中记录已访问过的节点。 </li>
<li>遍历当前节点的各个节点，将n节点放入CLOSE中，取n节点的子节点X,-&gt;算X的估价值-&gt; </li>
<li>While(OPEN!=NULL)      <br />{       <br />从OPEN表中取估价值f最小的节点n;       <br />if(n节点==目标节点) break;       <br />else       <br />{       <br />if(X in OPEN) 比较两个X的估价值f //注意是同一个节点的两个不同路径的估价值       <br />if( X的估价值小于OPEN表的估价值 )       <br />更新OPEN表中的估价值; //取最小路径的估价值       <br />if(X in CLOSE) 比较两个X的估价值 //注意是同一个节点的两个不同路径的估价值       <br />if( X的估价值小于CLOSE表的估价值 )       <br />更新CLOSE表中的估价值; 把X节点放入OPEN //取最小路径的估价值       <br />if(X not in both)       <br />求X的估价值;       <br />并将X插入OPEN表中; //还没有排序       <br />}       <br />将n节点插入CLOSE表中;       <br />按照估价值将OPEN表中的节点排序; //实际上是比较OPEN表内节点f的大小，从最小路径的节点向下进行。       <br />} </li>
</ul>
<p> <img alt="Image.jpg" src="http://das-project-x2.gz.netease.com/foswiki/pub/Main/%E5%AF%BB%E8%B7%AF%E7%B3%BB%E5%88%97%E4%B9%8B%E4%BA%8C_%E5%BC%A0%E5%85%89%E6%AF%85/Image.jpg" width="466" height="425" />
<p>上图是和上面Dijkstra算法使用同一个路网，相同的起点终点，用A*算法的情况，计算的点数从起始点逐渐向目标点方向扩展，计算的节点数量明显比Dijkstra少得多，效率很高，且能得到最优解。 </p>
]]></content:encoded>
			<wfw:commentRss>http://jaconey.com/2011/11/14/%e6%b8%b8%e6%88%8f%e5%bc%80%e5%8f%91-%e5%af%bb%e8%b7%af%e7%b3%bb%e5%88%97%e4%b9%8b%e4%ba%8c/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>游戏开发&#8211; 寻路系列之一</title>
		<link>http://jaconey.com/2011/11/07/%e6%b8%b8%e6%88%8f%e5%bc%80%e5%8f%91-%e5%af%bb%e8%b7%af%e7%b3%bb%e5%88%97%e4%b9%8b%e4%b8%80/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=%25e6%25b8%25b8%25e6%2588%258f%25e5%25bc%2580%25e5%258f%2591-%25e5%25af%25bb%25e8%25b7%25af%25e7%25b3%25bb%25e5%2588%2597%25e4%25b9%258b%25e4%25b8%2580</link>
		<comments>http://jaconey.com/2011/11/07/%e6%b8%b8%e6%88%8f%e5%bc%80%e5%8f%91-%e5%af%bb%e8%b7%af%e7%b3%bb%e5%88%97%e4%b9%8b%e4%b8%80/#comments</comments>
		<pubDate>Mon, 07 Nov 2011 03:12:32 +0000</pubDate>
		<dc:creator>jaconey</dc:creator>
				<category><![CDATA[tech]]></category>
		<category><![CDATA[A*]]></category>
		<category><![CDATA[journal]]></category>
		<category><![CDATA[nav]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://jaconey.com/2011/11/07/%e6%b8%b8%e6%88%8f%e5%bc%80%e5%8f%91-%e5%af%bb%e8%b7%af%e7%b3%bb%e5%88%97%e4%b9%8b%e4%b8%80/</guid>
		<description><![CDATA[上周对寻路做了一些原理和API上的了解， 由于寻路算法实在是博大精深，涉及很多知识，一周时间太短，理解尚浅，就以我现在了解到的归纳一下，如有理解不对的地方，欢迎跟帖指正~ 寻路算法属于人工智能的范畴，分静态和动态两种，动态的太高端，暂时没有了解，静态的话也有好几种，Dijkstra，A*和D*等。在网上搜寻了一下，3d 游戏的寻路算法主要还是A* （a-star，A星）使用的比较广泛，它有快速、路径短，不成环等优点，在orge，unity等引擎中得到了广泛的使用。 A*的最初设计是基于2d平面，对于3d 寻路就需要先对场景进行处理， 我们游戏貌似一般叫它navmesh，简而言之就是把场景网格化，生成一个可寻路的平面，把3d的问题转化为2d的问题，然后就可以通过A*进行寻路。 所以3d 游戏寻路大致分为2部分： navmesh A* navmesh比A* 要复杂很多，而由于A*可以在2d平面进行，理解起来会更简单一些，所以这里先简单介绍一下A*的原理。 先做一下术语的说明： 开启/关闭列表：算法的过程变量。可简单理解为临时记录区 G值：从起点A，沿着产生的路径，移动到网格上指定方格的移动耗费。 H值：从网格上那个方格移动到终点B的预估移动耗费。 F值：G + H 父节点：记录最短路径用 下面是算法过程(可直接导成伪代码）： 1，把起始格添加到开启列表。 2，重复如下的工作： a) 寻找开启列表中F值最低的格子。我们称它为当前格。 b) 把它切换到关闭列表。 c) 对相邻的8格中的每一个？ * 如果它不可通过或者已经在关闭列表中，略过它。反之如下。 * 如果它不在开启列表中，把它添加进去。把当前格作为这一格的父节点。记录这一格的F,G,和H值。 * 如果它已经在开启列表中，用G值为参考检查新的路径是否更好。更低的G值意味着更好的路径。如果是这样，就把这一格的父节点改成当前格，并且重新计算这一格的G和F值。如果你保持你的开启列表按F值排序，改变之后你可能需要重新对开启列表排序。 d) 停止，当你 * 把目标格添加进了关闭列表，这时候路径被找到，或者 * 没有找到目标格，开启列表已经空了。这时候，路径不存在。 3.保存路径。从目标格开始，沿着每一格的父节点移动直到回到起始格。这就是你的路径。 原理不是非常复杂，但是看上去有点抽象，更详细的下周继续，敬请留意。]]></description>
			<content:encoded><![CDATA[<p>上周对寻路做了一些原理和API上的了解， 由于寻路算法实在是博大精深，涉及很多知识，一周时间太短，理解尚浅，就以我现在了解到的归纳一下，如有理解不对的地方，欢迎跟帖指正~ </p>
<p>寻路算法属于人工智能的范畴，分静态和动态两种，动态的太高端，暂时没有了解，静态的话也有好几种，Dijkstra，A*和D*等。在网上搜寻了一下，3d 游戏的寻路算法主要还是A* （a-star，A星）使用的比较广泛，它有快速、路径短，不成环等优点，在orge，unity等引擎中得到了广泛的使用。 </p>
<p>A*的最初设计是基于2d平面，对于3d 寻路就需要先对场景进行处理， 我们游戏貌似一般叫它navmesh，简而言之就是把场景网格化，生成一个可寻路的平面，把3d的问题转化为2d的问题，然后就可以通过A*进行寻路。 </p>
<p>所以3d 游戏寻路大致分为2部分： </p>
<ol>
<li>navmesh </li>
<li>A* </li>
</ol>
<p> navmesh比A* 要复杂很多，而由于A*可以在2d平面进行，理解起来会更简单一些，所以这里先简单介绍一下A*的原理。
<p>先做一下术语的说明： </p>
<ul>
<li>开启/关闭列表：算法的过程变量。可简单理解为临时记录区 </li>
<li>G值：从起点A，沿着产生的路径，移动到网格上指定方格的移动耗费。 </li>
<li>H值：从网格上那个方格移动到终点B的预估移动耗费。 </li>
<li>F值：G + H </li>
<li>父节点：记录最短路径用 </li>
</ul>
<p> 下面是算法过程(可直接导成伪代码）：
<p>1，把起始格添加到开启列表。   <br />2，重复如下的工作：    <br />a) 寻找开启列表中F值最低的格子。我们称它为当前格。    <br />b) 把它切换到关闭列表。    <br />c) 对相邻的8格中的每一个？    <br />* 如果它不可通过或者已经在关闭列表中，略过它。反之如下。    <br />* 如果它不在开启列表中，把它添加进去。把当前格作为这一格的父节点。记录这一格的F,G,和H值。    <br />* 如果它已经在开启列表中，用G值为参考检查新的路径是否更好。更低的G值意味着更好的路径。如果是这样，就把这一格的父节点改成当前格，并且重新计算这一格的G和F值。如果你保持你的开启列表按F值排序，改变之后你可能需要重新对开启列表排序。 </p>
<p>d) 停止，当你   <br />* 把目标格添加进了<strong>关闭</strong>列表<strong>，</strong>这时候路径被找到，或者    <br />* 没有找到目标格，开启列表已经空了。这时候，路径不存在。    <br />3.保存路径。从目标格开始，沿着每一格的父节点移动直到回到起始格。这就是你的路径。 </p>
<p>原理不是非常复杂，但是看上去有点抽象，更详细的下周继续，敬请留意。 </p>
]]></content:encoded>
			<wfw:commentRss>http://jaconey.com/2011/11/07/%e6%b8%b8%e6%88%8f%e5%bc%80%e5%8f%91-%e5%af%bb%e8%b7%af%e7%b3%bb%e5%88%97%e4%b9%8b%e4%b8%80/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>记账软件</title>
		<link>http://jaconey.com/2011/10/31/%e8%ae%b0%e8%b4%a6%e8%bd%af%e4%bb%b6/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=%25e8%25ae%25b0%25e8%25b4%25a6%25e8%25bd%25af%25e4%25bb%25b6</link>
		<comments>http://jaconey.com/2011/10/31/%e8%ae%b0%e8%b4%a6%e8%bd%af%e4%bb%b6/#comments</comments>
		<pubDate>Mon, 31 Oct 2011 09:08:16 +0000</pubDate>
		<dc:creator>jaconey</dc:creator>
				<category><![CDATA[tech]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[app]]></category>
		<category><![CDATA[journal]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://jaconey.com/2011/10/31/%e8%ae%b0%e8%b4%a6%e8%bd%af%e4%bb%b6/</guid>
		<description><![CDATA[一直觉得“理财”这个词很高端， 也总想自己可以高端，于是就总想理理。虽然财很少，但据说理理可以有变化，变多变少不一定，但改变才是永恒。 又据说记账是理财的第一步，还必不可少，于是尝试找一些软件来协助一下。 碰巧周末又看见一微博，让我觉得还有教育下一代的必要，自己不懂就更说不过去： 【洛克菲勒家族的零花钱教育】洛克菲特家族的孩子每周都能领到三角钱零花钱，但必须分成三份：自己花、储蓄、施舍。孩子们每一分钱的用途和时间都必须记录在小账本上，周末进行检查。如果谁漏记了一笔帐，罚五分钱；而记录无误的则可得到五分钱的奖励，以此培养孩子勤劳节俭的美德和艰苦自立的品格。 简单理了下，我的记账需求大致如下： 方便，可以随时随地 有明细 可输出报表 跨平台 UI 能用（中文版软件，要求“好用”貌似有点过分。。。） 由于第一点，所以基本目标锁定了手机软件。芸芸android市场中，看见一个是由金蝶开发的，叫”随手记“，虽然从来没用过金蝶，但知道ERP，知道好多财务都是用它，大厂，名气大，我看行。于是就下载了来试试。 几番把玩，发现有几个优点： 软件不算很大，apk大概4M多，启动比较快。 记账方便，分类较细，属性有金额，帐户，商家。。。这点很关键，我不希望花费太多时间在”记&#34;这个动作上，我更希望把时间放在月终的数据整理上。 跨平台同步。这个功能也很关键，特别是现在大家每天都在各种设备上不停的切换迁移，不跨平台太痛苦。没Mac是一缺陷，但可用web版补救，也算方便。 可输出各种报表。通过各种属性进行筛选，分类，比较清晰，不愧是做ERP出身，这点小case 还是too simple。 UI 做得还不错，主界面分类较清晰 还可以为账目添加照片 总体感觉这个软件还不错，免费版基本能满足需求。VIP 版也就20RMB, 也在合理范围之内，可以接受。 不过有几个功能一直很希望能有一款软件支持，可惜没有。。。顺便吐槽一下： 根据信用卡消费明细自动记账。招行专业版有这个功能，但太独立了，总不能我两个地方分开记吧？这点很不给力。 和B2c， C2C?的电商整合。现在好多金钱都是在taobao，京东，当当这样的电商网站上消费走的，如果能导出上面的数据自动分类记账，那就很赞！ 在这个高聚合的互联网时代，能出一个这样的产品，市场应该还是不小的，至少我自己是很看好这样的应用，可惜自己没这个时间和精力去做。。。 哪位如果开发了，记得通知我，只要保密和隐私能保护的好，我一定属死忠用户! 最后补充一些界面的介绍（点击看大图）： 记账界面，看见那个摄像头的图标没有？那就是为这条流水附加的照片入口： 这是进入的主界面，可以看到汇总数据： 可以设置各种帐户： 分类汇总，类别很细，很清晰： 这是预算的分类，具体可以定制：&#160; 备份功能也很强大，直接搞到sd卡上，可以存到自己的电脑中。]]></description>
			<content:encoded><![CDATA[<p>一直觉得“理财”这个词很高端， 也总想自己可以高端，于是就总想理理。虽然财很少，但据说理理可以有变化，变多变少不一定，但改变才是永恒。 </p>
<p>又据说记账是理财的第一步，还必不可少，于是尝试找一些软件来协助一下。 </p>
<p>碰巧周末又看见一微博，让我觉得还有教育下一代的必要，自己不懂就更说不过去： </p>
<blockquote><p>【洛克菲勒家族的零花钱教育】洛克菲特家族的孩子每周都能领到三角钱零花钱，但必须分成三份：自己花、储蓄、施舍。孩子们每一分钱的用途和时间都必须记录在小账本上，周末进行检查。如果谁漏记了一笔帐，罚五分钱；而记录无误的则可得到五分钱的奖励，以此培养孩子勤劳节俭的美德和艰苦自立的品格。 </p>
</blockquote>
<p>简单理了下，我的记账需求大致如下： </p>
<ul>
<li>方便，可以随时随地 </li>
<li>有明细 </li>
<li>可输出报表 </li>
<li>跨平台 </li>
<li>UI 能用（中文版软件，要求“好用”貌似有点过分。。。） </li>
</ul>
<p> 由于第一点，所以基本目标锁定了手机软件。芸芸android市场中，看见一个是由金蝶开发的，叫”随手记“，虽然从来没用过金蝶，但知道ERP，知道好多财务都是用它，大厂，名气大，我看行。于是就下载了来试试。
<p>几番把玩，发现有几个优点： </p>
<ul>
<li>软件不算很大，apk大概4M多，启动比较快。 </li>
<li>记账方便，分类较细，属性有金额，帐户，商家。。。这点很关键，我不希望花费太多时间在”记&quot;这个动作上，我更希望把时间放在月终的数据整理上。 </li>
<li>跨平台同步。这个功能也很关键，特别是现在大家每天都在各种设备上不停的切换迁移，不跨平台太痛苦。没Mac是一缺陷，但可用web版补救，也算方便。 </li>
<li>可输出各种报表。通过各种属性进行筛选，分类，比较清晰，不愧是做ERP出身，这点小case 还是too simple。 </li>
<li>UI 做得还不错，主界面分类较清晰 </li>
<li>还可以为账目添加照片 </li>
</ul>
<p> 总体感觉这个软件还不错，免费版基本能满足需求。VIP 版也就20RMB, 也在合理范围之内，可以接受。
<p>不过有几个功能一直很希望能有一款软件支持，可惜没有。。。顺便吐槽一下： </p>
<ul>
<li>根据信用卡消费明细自动记账。招行专业版有这个功能，但太独立了，总不能我两个地方分开记吧？这点很不给力。 </li>
<li>和B2c， C2C<a href="http://das-project-x2.gz.netease.com/foswiki/bin/edit/Main/C2C?topicparent=Main.%E7%90%86%E8%B4%A2%E8%BD%AF%E4%BB%B6_%E5%BC%A0%E5%85%89%E6%AF%85">?</a>的电商整合。现在好多金钱都是在taobao，京东，当当这样的电商网站上消费走的，如果能导出上面的数据自动分类记账，那就很赞！ </li>
</ul>
<p>在这个高聚合的互联网时代，能出一个这样的产品，市场应该还是不小的，至少我自己是很看好这样的应用，可惜自己没这个时间和精力去做。。。 哪位如果开发了，记得通知我，只要保密和隐私能保护的好，我一定属死忠用户! </p>
<p>最后补充一些界面的介绍（点击看大图）：    <br />记账界面，看见那个摄像头的图标没有？那就是为这条流水附加的照片入口：     <br /><a href="http://jaconey.com/wp-content/uploads/2011/11/01.png"><img style="border-bottom: 0px;border-left: 0px;padding-left: 0px;padding-right: 0px;border-top: 0px;border-right: 0px;padding-top: 0px" border="0" alt="豌豆荚截屏(0)" src="http://jaconey.com/wp-content/uploads/2011/11/0_thumb1.png" width="128" height="244" /></a></p>
<p>这是进入的主界面，可以看到汇总数据：    <br /><a href="http://jaconey.com/wp-content/uploads/2011/11/807cf3429b96.png"><img style="border-right-width: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px;border-bottom-width: 0px;border-left-width: 0px;padding-top: 0px" border="0" alt="豌豆荚截屏" src="http://jaconey.com/wp-content/uploads/2011/11/thumb.png" width="128" height="244" /></a></p>
<p>可以设置各种帐户：    <br /><a href="http://jaconey.com/wp-content/uploads/2011/11/1.png"><img style="border-bottom: 0px;border-left: 0px;padding-left: 0px;padding-right: 0px;border-top: 0px;border-right: 0px;padding-top: 0px" border="0" alt="豌豆荚截屏(1)" src="http://jaconey.com/wp-content/uploads/2011/11/1_thumb.png" width="128" height="244" /></a></p>
<p>分类汇总，类别很细，很清晰：    <br /><a href="http://jaconey.com/wp-content/uploads/2011/11/2.png"><img style="border-bottom: 0px;border-left: 0px;padding-left: 0px;padding-right: 0px;border-top: 0px;border-right: 0px;padding-top: 0px" border="0" alt="豌豆荚截屏(2)" src="http://jaconey.com/wp-content/uploads/2011/11/2_thumb.png" width="128" height="244" /></a>    </p>
<p>这是预算的分类，具体可以定制：&#160; <br /><a href="http://jaconey.com/wp-content/uploads/2011/11/3.png"><img style="border-bottom: 0px;border-left: 0px;padding-left: 0px;padding-right: 0px;border-top: 0px;border-right: 0px;padding-top: 0px" border="0" alt="豌豆荚截屏(3)" src="http://jaconey.com/wp-content/uploads/2011/11/3_thumb.png" width="128" height="244" /></a></p>
<p>备份功能也很强大，直接搞到sd卡上，可以存到自己的电脑中。    <br /><a href="http://jaconey.com/wp-content/uploads/2011/11/4.png"><img style="border-bottom: 0px;border-left: 0px;padding-left: 0px;padding-right: 0px;border-top: 0px;border-right: 0px;padding-top: 0px" border="0" alt="豌豆荚截屏(4)" src="http://jaconey.com/wp-content/uploads/2011/11/4_thumb.png" width="128" height="244" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://jaconey.com/2011/10/31/%e8%ae%b0%e8%b4%a6%e8%bd%af%e4%bb%b6/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Linus谈软件开发</title>
		<link>http://jaconey.com/2011/10/21/linus%e8%b0%88%e8%bd%af%e4%bb%b6%e5%bc%80%e5%8f%91/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=linus%25e8%25b0%2588%25e8%25bd%25af%25e4%25bb%25b6%25e5%25bc%2580%25e5%258f%2591</link>
		<comments>http://jaconey.com/2011/10/21/linus%e8%b0%88%e8%bd%af%e4%bb%b6%e5%bc%80%e5%8f%91/#comments</comments>
		<pubDate>Fri, 21 Oct 2011 10:02:30 +0000</pubDate>
		<dc:creator>jaconey</dc:creator>
				<category><![CDATA[tech]]></category>
		<category><![CDATA[journal]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://jaconey.com/2011/10/21/linus%e8%b0%88%e8%bd%af%e4%bb%b6%e5%bc%80%e5%8f%91/</guid>
		<description><![CDATA[原文: http://h30565.www3.hp.com/t5/Feature-Articles/Linus-Torvalds-s-Lessons-on-Software-Development-Management/ba-p/440 如果让我选 &#34;谁是世界上最天才的软件项目经理&#34;, 我会认为Linus 当之无愧. Linux 内核, 一个集千万程序员智慧的结晶, 现在已经给广泛用于各种设备, 而发起者和项目最高管理者一直没有变过, 都是Linus Torvalds. 在linux 之前, 开源项目几乎从来没有如此强烈的影响力, 而如何聚拢全球开发者, 有条不紊的开发一个成功的产品, 曾经被认为是mission impossible, 但Linus 做到了. 查了下linux kernel的发布流程, 大致如下: 2.6.x 内核树 2.6.x 内核树是有Linus Torvalds维护的，可以在kernel.org的pub/linux/kernel/v2.6目录里找到。它的开发流程是这样的： － 当一个新的内核发布之后，一个为期两个星期的窗口打开，在这段时间里维护者可以提交大的补丁给Linus，通常是已经在-mm内核中存在了一定时间的补丁。推荐的提交补丁的方式是通过git（有关git的更多信息可以在http://git.or.cz/找到），但是普通的补丁也是可以的 －两个星期之后一个-rc1内核发布，然后现在只可以再加入不会为内核添加新功能的补丁，因为那样的补丁可能会影响这个内核的稳定性。请注意这个时候一个整的新驱动（或者文件系统）可以被接受。因为只要这个变动是自成一体的并且不影响它之外的代码的话，就不会有产生回归的危险。在-rc1发布之后，git可以用来发送补丁给Linus，但是这些补丁也需要发到一个公开的邮件列表里以备审查。 － 当Linus确信当前的git（内核代码管理工具）树已经处于一个合理的健全状态，足够测试时，一个新的-rc就会发布了。目标是每周发布一个新的-rc内核。 － 这个过程将会持续到内核被认为可以发布为止，整个流程会持续大概6个星期。 Andrew Morton在linux-kernel邮件列表里写的有关内核发布的一句话值得提一下： “没有人知道什么时候一个内核会发布，因为它发布的依据已经掌握的bug状态，而不是事先设想好的一个时间线。 可以看到, Linux 的内核发布是很神奇的一个存在! 最终节点只有一个: Linus! 记得有一次linux 2.6 有一个严重的bug, 导致部分显卡无法正常工作, 但是没法做hotfix, 原因是: Linus 去美国度假了&#8230; Linus 是一个传奇, <a href='http://jaconey.com/2011/10/21/linus%e8%b0%88%e8%bd%af%e4%bb%b6%e5%bc%80%e5%8f%91/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p><a href="http://h30565.www3.hp.com/t5/Feature-Articles/Linus-Torvalds-s-Lessons-on-Software-Development-Management/ba-p/440">原文: http://h30565.www3.hp.com/t5/Feature-Articles/Linus-Torvalds-s-Lessons-on-Software-Development-Management/ba-p/440</a></p>
<p>如果让我选 &quot;谁是世界上最天才的软件项目经理&quot;, 我会认为Linus 当之无愧. Linux 内核, 一个集千万程序员智慧的结晶, 现在已经给广泛用于各种设备, 而发起者和项目最高管理者一直没有变过, 都是Linus Torvalds. </p>
<p>在linux 之前, 开源项目几乎从来没有如此强烈的影响力, 而如何聚拢全球开发者, 有条不紊的开发一个成功的产品, 曾经被认为是mission impossible, 但Linus 做到了. </p>
<p>查了下linux kernel的发布流程, 大致如下: </p>
<blockquote><p>2.6.x 内核树     <br />2.6.x 内核树是有Linus Torvalds维护的，可以在kernel.org的pub/linux/kernel/v2.6目录里找到。它的开发流程是这样的：      <br />－ 当一个新的内核发布之后，一个为期两个星期的窗口打开，在这段时间里维护者可以提交大的补丁给Linus，通常是已经在-mm内核中存在了一定时间的补丁。推荐的提交补丁的方式是通过git（有关git的更多信息可以在http://git.or.cz/找到），但是普通的补丁也是可以的      <br />－两个星期之后一个-rc1内核发布，然后现在只可以再加入不会为内核添加新功能的补丁，因为那样的补丁可能会影响这个内核的稳定性。请注意这个时候一个整的新驱动（或者文件系统）可以被接受。因为只要这个变动是自成一体的并且不影响它之外的代码的话，就不会有产生回归的危险。在-rc1发布之后，git可以用来发送补丁给Linus，但是这些补丁也需要发到一个公开的邮件列表里以备审查。      <br />－ 当Linus确信当前的git（内核代码管理工具）树已经处于一个合理的健全状态，足够测试时，一个新的-rc就会发布了。目标是每周发布一个新的-rc内核。      <br />－ 这个过程将会持续到内核被认为可以发布为止，整个流程会持续大概6个星期。      <br />Andrew Morton在linux-kernel邮件列表里写的有关内核发布的一句话值得提一下： “没有人知道什么时候一个内核会发布，因为它发布的依据已经掌握的bug状态，而不是事先设想好的一个时间线。 </p>
</blockquote>
<p>可以看到, Linux 的内核发布是很神奇的一个存在! 最终节点只有一个: Linus! </p>
<p>记得有一次linux 2.6 有一个严重的bug, 导致部分显卡无法正常工作, 但是没法做hotfix, 原因是: Linus 去美国度假了&#8230; </p>
<p>Linus 是一个传奇, 就像 Steve Jobs 一样, 是一个无法复制的神一般的存在&#8230; </p>
<p>well, 仰慕到此为止, 看看这次他老人家又说了什么. </p>
<ul>
<li>对于开源项目, 他的意见是: You make it public, and then you assume that you&#8217;ll have to do all the work, and ask people to come up with suggestions of what you should do, not what they should do. 为何大多数开源项目最终都是失败, 也许就是因为出发点没有找对. 忘记那个哲学家说过: 人本自私. 这也是西方普世价值之一, 不要一开始就奢望项目一放出来就会有很多人热心的加入, idea 再好, 没实实在在的东西, 没人会想着投入的. </li>
<li>对于有人觉得代码很重要, Linus认为: “No, even if you wrote 100% of the code, and even if you are the best programmer in the world and will never need any help with the project at all, the thing that really matters is the users of the code. The code itself is unimportant; <a href="http://h30565.www3.hp.com/t5/Feature-Articles/6-Products-That-Became-Technology-Roadkill/ba-p/36">the project is only as useful as people actually find it</a>.” 他还提到, 很多公司对代码质量很关注, 我经历过华为当时那种几乎苛刻的对代码风格的追求, 所以深有感触. Linus 认为对代码的追求胜过对用户体验的追求这个想法本身就是错误的. 他举的例子也很有代表性: 如果一个bug的fix 会影响到用户体验, 那么你就已经破坏了这个规矩. 他认为很多公司都自以为是的在破坏用户体验, 为得就是fix 一个bug. </li>
<li>对于开发工具, Linus觉得工具并不是必须的. if you only have a few hundred patches per release, you can maintain those just about any way you want, including entirely by hand. (一个release几百个patch, 他都觉得可以by hand&#8230; 这是一种什么样的DIY 精神啊!!= =) </li>
<li>对于版本管理, Linus的一个想法比较体现他的性格: I personally tend to think tar-balls and patches are actually preferable to that – if only because they make all developers &#8216;equal,&#8217; and you don&#8217;t get the kind of model where certain people have &#8216;commit access,&#8217; and the rest are second-class citizens. 这个众生平等的观念也放到了他设计的git 上. git 完全没有类似svn/cvs 的那种对读写限制的权限管理模块, 如果要做, 就是通过linux本身的权限系统来管理, git不做这种dirty work. </li>
</ul>
<p> 总体来说Linus 是IT界比较出名的愤青, 同样的Jobs 也是出了名的苛刻. 也许伟大的人总是有那么点和常人不同的地方
<p>有兴趣的同学还可以回顾一下Linus 大神当年对C++的狂喷: <a href="http://blog.csdn.net/turingbook/article/details/1775488">http://blog.csdn.net/turingbook/article/details/1775488</a> 我觉得还是骂得挺对的, 我也曾经对C++热衷过, 还做过一个template嵌套的项目, 但那种痛不欲生的感觉让我再也不想再深入这苦逼语言之中去, 从此也走上了anti-cpper 的这条不归路&#8230; </p>
]]></content:encoded>
			<wfw:commentRss>http://jaconey.com/2011/10/21/linus%e8%b0%88%e8%bd%af%e4%bb%b6%e5%bc%80%e5%8f%91/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>还可以说什么</title>
		<link>http://jaconey.com/2011/10/18/%e8%bf%98%e5%8f%af%e4%bb%a5%e8%af%b4%e4%bb%80%e4%b9%88/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=%25e8%25bf%2598%25e5%258f%25af%25e4%25bb%25a5%25e8%25af%25b4%25e4%25bb%2580%25e4%25b9%2588</link>
		<comments>http://jaconey.com/2011/10/18/%e8%bf%98%e5%8f%af%e4%bb%a5%e8%af%b4%e4%bb%80%e4%b9%88/#comments</comments>
		<pubDate>Tue, 18 Oct 2011 08:13:14 +0000</pubDate>
		<dc:creator>jaconey</dc:creator>
				<category><![CDATA[life]]></category>
		<category><![CDATA[comment]]></category>
		<category><![CDATA[news]]></category>

		<guid isPermaLink="false">http://jaconey.com/2011/10/18/%e8%bf%98%e5%8f%af%e4%bb%a5%e8%af%b4%e4%bb%80%e4%b9%88/</guid>
		<description><![CDATA[周末看到一个新闻:&#8221;女童两次遭车压 十余路人漠视&#8221; 可能是心理上的应激反应, 我没有点开视频看. 对生命的漠视, 已经不能算是新闻, 已经忘记了听到过多少次世人的冷漠, 人也慢慢的开始麻木 而在终于点开视频, 看完后, 我依然还是忍不住想问: 这个社会究竟怎么了??!! 女童被碾压的过程我始终没有能看完, 不敢&#8230; 不忍&#8230; 没有勇气 有时候, 我们看着网上的视频, 已经练就一身好本事, 没有任何代入感, 感觉就像在看电影, 好像一切都离自己很遥远, 自己总会是幸运的一个, 厄运永远不会发生在自己身上&#8230; 我不认同. 让我想起美国波士顿犹太人屠杀纪念碑上所铭刻的马丁·尼莫拉的话： 在德国，起初他们追杀共产主义者，我没有说话——因为我不是共产主义者；接着他们追杀犹太人，我没有说话——因为我不是犹太人；后来他们追杀工会成员，我没有说话——因为我不是工会成员；此后他们追杀天主教徒，我没有说话，因为我是新教教徒；最后他们奔我而来。却再也没有人站出来为我说话了。 看了视频, 我有很强烈的代入感. 身为人父后, 多了一份责任. 而经历过几次生离死别后, 我更加珍惜生命, 更懂得活着的可贵. 看到这种对生命的漠视, 而且是如此幼小的一个生命&#8230;而且冷血的人还不只一个! 还看到一位带着小朋友的母亲&#8230;. 语塞, 不知道还可以说什么&#8230; 下面是网上的视频片段, 没看的请补: 珍惜生命, 善待身边的人, 纵使素未谋面, 但是, 那是一个生命啊! 希望尚存良知的人会越来越多, 而不是慢慢灭绝&#8230;. 也希望小朋友能够坚强, 我依旧相信着奇迹&#8230; UPDATE: 可怜的小悦悦已经被诊断为&#8221;脑死亡&#8221;&#8230;. 哀&#8230;]]></description>
			<content:encoded><![CDATA[<p>周末看到一个新闻:&#8221;<em>女童两次遭车压 十余路人漠视&#8221; </em></p>
<p>可能是心理上的应激反应, 我没有点开视频看. 对生命的漠视, 已经不能算是新闻, 已经忘记了听到过多少次世人的冷漠, 人也慢慢的开始麻木</p>
<p>而在终于点开视频, 看完后, 我依然还是忍不住想问: 这个社会究竟怎么了??!!</p>
<p>女童被碾压的过程我始终没有能看完, 不敢&#8230; 不忍&#8230; 没有勇气</p>
<p>有时候, 我们看着网上的视频, 已经练就一身好本事, 没有任何代入感, 感觉就像在看电影, 好像一切都离自己很遥远, 自己总会是幸运的一个, 厄运永远不会发生在自己身上&#8230;</p>
<p>我不认同.</p>
<p>让我想起美国波士顿犹太人屠杀纪念碑上所铭刻的马丁·尼莫拉的话：</p>
<p>在德国，起初他们追杀共产主义者，我没有说话——因为我不是共产主义者；接着他们追杀犹太人，我没有说话——因为我不是犹太人；后来他们追杀工会成员，我没有说话——因为我不是工会成员；此后他们追杀天主教徒，我没有说话，因为我是新教教徒；最后他们奔我而来。却再也没有人站出来为我说话了。</p>
<p>看了视频, 我有很强烈的代入感. 身为人父后, 多了一份责任. 而经历过几次生离死别后, 我更加珍惜生命, 更懂得活着的可贵. 看到这种对生命的漠视, 而且是如此幼小的一个生命&#8230;而且冷血的人还不只一个! 还看到一位带着小朋友的母亲&#8230;.</p>
<p>语塞, 不知道还可以说什么&#8230;</p>
<p>下面是网上的视频片段, 没看的请补:</p>
<p><embed src="http://player.youku.com/player.php/sid/XMzEzNDQ4Mjg0/v.swf" quality="high" width="480" height="400" align="middle" allowScriptAccess="sameDomain" allowFullscreen="true" type="application/x-shockwave-flash"></embed></p>
<p>珍惜生命, 善待身边的人, 纵使素未谋面, 但是, 那是一个生命啊! 希望尚存良知的人会越来越多, 而不是慢慢灭绝&#8230;.</p>
<p><span style="color: #a5a5a5;"><span style="text-decoration: line-through;">也希望小朋友能够坚强, 我依旧相信着奇迹&#8230;</span> </span>UPDATE: 可怜的小悦悦已经被诊断为&#8221;脑死亡&#8221;&#8230;. 哀&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://jaconey.com/2011/10/18/%e8%bf%98%e5%8f%af%e4%bb%a5%e8%af%b4%e4%bb%80%e4%b9%88/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

