<?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>Leaf Duo</title>
	<atom:link href="http://blog.leafduo.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.leafduo.com</link>
	<description>All About My Life and Information Technology</description>
	<lastBuildDate>Mon, 13 Feb 2012 12:39:03 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>我们的数据库课</title>
		<link>http://blog.leafduo.com/03/database-class-at-school/</link>
		<comments>http://blog.leafduo.com/03/database-class-at-school/#comments</comments>
		<pubDate>Mon, 13 Feb 2012 12:39:03 +0000</pubDate>
		<dc:creator>Leaf Duo</dc:creator>
				<category><![CDATA[Information Technology]]></category>
		<category><![CDATA[database]]></category>

		<guid isPermaLink="false">http://blog.leafduo.com/?p=281</guid>
		<description><![CDATA[很久之前的一篇文章，怎么也是上上学期吧，写成草稿了，现在贴出来吧。 我并不是要批评我们的老师，我觉得我们的老师还是挺负责任的，能讲到的还是尽量讲到还是都讲到了。 其实最重要的是我并不知道这课到底是在讲什么，老师在某节课上说：“我们这门课主要是讲授数据库理论，这个内容就不讲了”（意思是这样的）。当时我就震惊了，我一直以为这门课讲的是数据库如何使用数据库的……老师上课的时候也经常说作为数据库的使用者如何如何，那我们的这门课到底是在讲理论还是使用呢…… 作为大学的课程，我认为应该以理论为主，怎样使用只是顺带一提，以自学为主就好，就像传言中国外大学某些课程一样，一次课讲完一门语言，SQL 这种东西完全可以一次课讲完，剩下的靠大家自学或者直接实践，但是上半学期除了绪论，就一直在讲关系代数和 SQL，这个东西需要这么多时间来讲吗？我个人认为，4个课时就足够了（可能有点太激进了）。这门课上用了八周，也就是 22 个课时来讲这些东西。 我是一个理论比较弱的人，所以就想着靠学校里的数据库课补一下理论知识的。在我眼中，这门课讲的东西确实是必须的，但是内容太少了，深度也不够。这个 playlist 是印度一所大学的数据库课程，我只看了标题，来比较一下我们课程的内容。Lecture 1～9 我们是讲过的，10～16 没讲过，17～23 讲过，24～26 没讲过，27～29 讲过，30～42 没讲过，只有 19/42 的内容我们覆盖到了，也就是只有 45%。看看我们漏掉了什么东西，存储过程、索引、查询过程和优化、分布式数据库、数据挖掘、XML 和对象数据库还有很多 case study。我想要的是什么？我想学的就是数据库是怎么实现的，存储过程、索引、查询过程和优化为什么没有？这是本科教育对吗？不是职业教育，我们要知道原理才能更好地利用数据库，对吗？学校里学不到的指望我们在工作中学吗？大家都清楚，工作了就更没有机会去学理论了。怎样用 SQL 需要教吗？DBMS 就会告诉你你的 SQL 是对是错，你也能一眼看出来结果是否正确，尝试一下，总会正确的。但是如果你一句 SQL 执行了一分钟，DBMS 会告诉你为什么吗？会告诉你子查询的速度慢吗？会告诉你优化器做了什么吗？会告诉你中间创建了哪些临时表吗？不会的，起码不会一眼就看出来，你需要理论知识的支持，可是这门课给了我们什么？ 要说这门课重视实践，那我又不明白了。现在起码在互联网方面，大家都只是把数据库当作一个存储数据的地方，很多高级的功能、很复杂的 SQL 都很少出现，那么我们写一堆长长的带着子查询，带着 ANY 带着 EXISTS 的东西有什么用呢？做教务系统吗？用非常复杂的 SQL &#8230; <a href="http://blog.leafduo.com/03/database-class-at-school/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><em>很久之前的一篇文章，怎么也是上上学期吧，写成草稿了，现在贴出来吧。</em></p>
<p>我并不是要批评我们的老师，我觉得我们的老师还是挺负责任的，能讲到的还是尽量讲到还是都讲到了。</p>
<p>其实最重要的是我并不知道这课到底是在讲什么，老师在某节课上说：“我们这门课主要是讲授数据库理论，这个内容就不讲了”（意思是这样的）。当时我就震惊了，我一直以为这门课讲的是数据库如何使用数据库的……老师上课的时候也经常说作为数据库的使用者如何如何，那我们的这门课到底是在讲理论还是使用呢……</p>
<p>作为大学的课程，我认为应该以理论为主，怎样使用只是顺带一提，以自学为主就好，就像传言中国外大学某些课程一样，一次课讲完一门语言，SQL 这种东西完全可以一次课讲完，剩下的靠大家自学或者直接实践，但是上半学期除了绪论，就一直在讲关系代数和 SQL，这个东西需要这么多时间来讲吗？我个人认为，4个课时就足够了（可能有点太激进了）。这门课上用了八周，也就是 22 个课时来讲这些东西。</p>
<p>我是一个理论比较弱的人，所以就想着靠学校里的数据库课补一下理论知识的。在我眼中，这门课讲的东西确实是必须的，但是内容太少了，深度也不够。<a href="http://www.youtube.com/playlist?p=PL9426FE14B809CC41">这个 playlist </a>是印度一所大学的数据库课程，我只看了标题，来比较一下我们课程的内容。Lecture 1～9 我们是讲过的，10～16 没讲过，17～23 讲过，24～26 没讲过，27～29 讲过，30～42 没讲过，只有 19/42 的内容我们覆盖到了，也就是只有 45%。看看我们漏掉了什么东西，存储过程、索引、查询过程和优化、分布式数据库、数据挖掘、XML 和对象数据库还有很多 case study。我想要的是什么？我想学的就是数据库是怎么实现的，存储过程、索引、查询过程和优化为什么没有？这是本科教育对吗？不是职业教育，我们要知道原理才能更好地利用数据库，对吗？学校里学不到的指望我们在工作中学吗？大家都清楚，工作了就更没有机会去学理论了。怎样用 SQL 需要教吗？DBMS 就会告诉你你的 SQL 是对是错，你也能一眼看出来结果是否正确，尝试一下，总会正确的。但是如果你一句 SQL 执行了一分钟，DBMS 会告诉你为什么吗？会告诉你子查询的速度慢吗？会告诉你优化器做了什么吗？会告诉你中间创建了哪些临时表吗？不会的，起码不会一眼就看出来，你需要理论知识的支持，可是这门课给了我们什么？</p>
<p>要说这门课重视实践，那我又不明白了。现在起码在互联网方面，大家都只是把数据库当作一个存储数据的地方，很多高级的功能、很复杂的 SQL 都很少出现，那么我们写一堆长长的带着子查询，带着 ANY 带着 EXISTS 的东西有什么用呢？做教务系统吗？用非常复杂的 SQL 来实现一些应用语言很容易就能实现的功能有什么必要呢？SQL 不是过程化的，非得拿他来做一些过程化的事情不是强人所难吗？我在 QCon 会场抢了两本书——<a href="http://book.douban.com/subject/4118579/">《SQL沉思录》</a><a href="http://book.douban.com/subject/3007085/">《SQL解惑》</a>里面写的内容就是用 SQL 做一些非常奇怪的问题，甚至于解决稳定婚姻问题（谜题67），这种东西真的有用吗？作者当时的时代还是 SQL 大行其道的时候，可能写这样的东西练习 SQL 还说的过去，但是现在 SQL 并没有那么热，各种 NoSQL 纷纷出现的现在，练习 SQL 而不是学习数据库本身的理论有什么价值呢？拿索引来说，就算某种数据库并不是利用 SQL 进行查询，那它为了性能也需要一个类似索引的东西，对吗？只要这种索引还是要用 B 树或者散列表，那我们学习索引的理论就还是有用的。就这两本书被随意赠送的可怜的处境来看，整页的 SQL 真的没有什么用。</p>
<p>说一个比较极端的例子，教大家使用数据库的时候并没有提到 LIMIT，可能很多人并不会知道 SELECT id FROM user ORDER BY id LIMIT 100000, 5 为什么总是慢的要死。</p>
<p>还有一个问题，这个希望老师改进一下，老师上课演示的所有 SQL 语句里面的关键字都是小写，SQL 是不区分大小写，但是我们都知道关键字推荐是全部大写的，希望以后不会看到我同学写出小写关键字的 SQL……我们都懒，但是老师需要教学生养成良好的习惯，不是吗？</p>
<p>发这么多牢骚，其实还是对数据库这么课抱了很大期望，希望能补一下数据库的知识，不幸让我失望了。还是自己学吧，印度人虽然英语非常差，但是讲数据库应该还可以。</p>
<p>好在期末考试没有非常坑，没有非常古怪的题目，算是真的考察水平吧，不过还是希望能多些理论知识，让同学多一些进步。我觉得现在所有的内容压缩到上半学期，下半学期讲些理论和 case study 会非常好。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.leafduo.com/03/database-class-at-school/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>iOS dev: 将 Xcode 中的 CODE SIGN IDENTITY 分离出 VCS</title>
		<link>http://blog.leafduo.com/29/ios-dev-take-code-sign-identity-out-of-vcs/</link>
		<comments>http://blog.leafduo.com/29/ios-dev-take-code-sign-identity-out-of-vcs/#comments</comments>
		<pubDate>Sat, 06 Aug 2011 07:34:29 +0000</pubDate>
		<dc:creator>Leaf Duo</dc:creator>
				<category><![CDATA[Information Technology]]></category>
		<category><![CDATA[code sign]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[Xcode]]></category>

		<guid isPermaLink="false">http://blog.leafduo.com/?p=285</guid>
		<description><![CDATA[做 iOS 开发的时候每个人都有不同的开发者证书/私钥，只有通过这个私钥进行代码签名之后 app 才能在 iPhone 上运行起来。项目中用来确定使用哪个私钥签名的配置文件是 project.pbxproj，由于它也记录了项目地很多其它信息，所以它往往会出现在版本控制系统中，这样就造成只有一个人能够成功地签名。好在我们可以通过 .xcconfig 文件来将这个配置抽离出来。 首先新建一个文件(Cmd+N)，在 Other 中选择 Configuration Settings File，新建一个配置文件 CodeSign.xcconfig。在这个文件中添加一行： CODE_SIGN_IDENTITY = iPhone Developer: 人甲 路 (XXXXXXXXXX)，其中证书的名称可以在 Keychain Access 里面找到。 之后删除原来 project.pbxproj 里面的签名，直接在 build settings 里面删除就好，注意 project 和 target 的都要删掉（都选中之后 Cmd+delete）。 最后在 Project &#8230; <a href="http://blog.leafduo.com/29/ios-dev-take-code-sign-identity-out-of-vcs/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>做 iOS 开发的时候每个人都有不同的开发者证书/私钥，只有通过这个私钥进行代码签名之后 app 才能在 iPhone 上运行起来。项目中用来确定使用哪个私钥签名的配置文件是 <code>project.pbxproj</code>，由于它也记录了项目地很多其它信息，所以它往往会出现在版本控制系统中，这样就造成只有一个人能够成功地签名。好在我们可以通过 <code>.xcconfig</code> 文件来将这个配置抽离出来。</p>
<p>首先新建一个文件(Cmd+N)，在 Other 中选择 Configuration Settings File，新建一个配置文件 <code>CodeSign.xcconfig</code>。在这个文件中添加一行：<br />
<code>CODE_SIGN_IDENTITY = iPhone Developer: 人甲 路 (XXXXXXXXXX)</code>，其中证书的名称可以在 Keychain Access 里面找到。</p>
<p><a href="https://picasaweb.google.com/lh/photo/lkf9kEWgThZpL63-LH9fjA?feat=embedwebsite"><img src="https://lh6.googleusercontent.com/-ZoEoKlecJX0/Tjzrvfr0SlI/AAAAAAAACds/CsBs8CiqWg8/s640/Screen%252520Shot%2525202011-08-06%252520at%2525203.22.07%252520PM.png" height="426" width="640" /></a></p>
<p>之后删除原来 <code>project.pbxproj</code> 里面的签名，直接在 build settings 里面删除就好，注意 project 和 target 的都要删掉（都选中之后 Cmd+delete）。</p>
<p>最后在 Project 的 info 中，看到 Configuration 一栏，在 Based on Configuration File，选择我们创建的文件 CodeSign。</p>
<p><a href="https://picasaweb.google.com/lh/photo/esruPhlQSDvSS3PxLhYrIg?feat=embedwebsite"><img src="https://lh4.googleusercontent.com/-u_Oi-idbkYs/TjztLkNdUyI/AAAAAAAACec/lNHZI9rKsU0/s640/Screen%252520Shot%2525202011-08-06%252520at%2525203.15.22%252520PM.png" height="196" width="640" /></a></p>
<p>最后在 build settings 里面应该是这个样子：（项目和目标那一栏都是空的）</p>
<p><a href="https://picasaweb.google.com/lh/photo/MLqZmfyGH8p2CLvHkYQ-Dg?feat=embedwebsite"><img src="https://lh3.googleusercontent.com/-o1g7_aMfQ6w/Tjzswj-QZpI/AAAAAAAACeE/VujRXPlMgTw/s640/Screen%252520Shot%2525202011-08-06%252520at%2525203.16.09%252520PM.png" height="61" width="640" /></a></p>
<p>最后注意不要把 <code>CodeSign.xcconfig</code> check in 进去。</p>
<p>参考：<a href="http://respectthecode.co/2011/06/11/xcode-4-and-xcconfig-files/">http://respectthecode.co/2011/06/11/xcode-4-and-xcconfig-files/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.leafduo.com/29/ios-dev-take-code-sign-identity-out-of-vcs/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Lion 对加密卷的支持</title>
		<link>http://blog.leafduo.com/48/lion-encrypted-volume-support/</link>
		<comments>http://blog.leafduo.com/48/lion-encrypted-volume-support/#comments</comments>
		<pubDate>Sun, 17 Jul 2011 18:44:48 +0000</pubDate>
		<dc:creator>Leaf Duo</dc:creator>
				<category><![CDATA[Information Technology]]></category>
		<category><![CDATA[CoreStorage]]></category>
		<category><![CDATA[diskutil]]></category>
		<category><![CDATA[Lion]]></category>
		<category><![CDATA[Mac]]></category>

		<guid isPermaLink="false">http://blog.leafduo.com/?p=283</guid>
		<description><![CDATA[今天想给硬盘数据做备份，毕竟硬盘已经用了两年了，不用查 SMART 信息也知道他已经老了，虽然诸如代码之类的都有很多备份，但是还是有些文档、照片需要备份。 又阴差阳错得到一块老旧移动硬盘，灰常好啊。开工吧。 拿来的时候是 NTFS，第一件事情就是改成 HFS+，拿 Disk Utility 格式化的时候发现多出了加密的选项，不用多说，先试试。不得不说这个 Lion 的 GM 版本还不够到正式版的水平，这个输入密码的输入框如果输入超过十位的密码就会 crash，这个完全不能忍受啊，尝试了半天发现先在别的地方输入好然后复制过来就可以了。（好吧，我不得不说我写文章想截图的时候这个 bug 又神秘的消失了） 这样格式化好了之后每次插入移动硬盘的时候都会提示你输入密码才能访问，像是做备份这种应用就会安全很多。 之后我就发现加密卷的密码无法修改，我猜测这种加密是用密码加密一个密钥，再用密钥加密数据的，应该可以修改密码，现在无法修改的原因应该是 Apple 还没想好在哪里放这个功能，也或许 Apple 不会给这个功能提供 GUI，那我们转战 CLI 吧，Disk Utility 对应的命令行工具是 diskutil，里面提供了很多 GUI 中没有的功能。鼓捣一会之后发现 diskutil 有个叫做 CoreStorage 的模块，进一步发现 diskutil coreStorage changeVolumePassphrase 可以修改 CoreStorage &#8230; <a href="http://blog.leafduo.com/48/lion-encrypted-volume-support/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>今天想给硬盘数据做备份，毕竟硬盘已经用了两年了，不用查 SMART 信息也知道他已经老了，虽然诸如代码之类的都有很多备份，但是还是有些文档、照片需要备份。</p>
<p>又阴差阳错得到一块老旧移动硬盘，灰常好啊。开工吧。</p>
<p>拿来的时候是 NTFS，第一件事情就是改成 HFS+，拿 Disk Utility 格式化的时候发现多出了加密的选项，不用多说，先试试。不得不说这个 Lion 的 GM 版本还不够到正式版的水平，这个输入密码的输入框如果输入超过十位的密码就会 crash，这个完全不能忍受啊，尝试了半天发现先在别的地方输入好然后复制过来就可以了。（好吧，我不得不说我写文章想截图的时候这个 bug 又神秘的消失了）</p>
<p><a href="https://picasaweb.google.com/lh/photo/jeCgDHO8qJqbYuM4Guqctg?feat=embedwebsite"><img src="https://lh4.googleusercontent.com/-ryRM1jL_il0/TiMs7wbtP1I/AAAAAAAACcY/SSqM8_GCDko/s640/diskutil.png" height="528" width="640" /></a></p>
<p>这样格式化好了之后每次插入移动硬盘的时候都会提示你输入密码才能访问，像是做备份这种应用就会安全很多。</p>
<p>之后我就发现加密卷的密码无法修改，我猜测这种加密是用密码加密一个密钥，再用密钥加密数据的，应该可以修改密码，现在无法修改的原因应该是 Apple 还没想好在哪里放这个功能，也或许 Apple 不会给这个功能提供 GUI，那我们转战 CLI 吧，Disk Utility 对应的命令行工具是 diskutil，里面提供了很多 GUI 中没有的功能。鼓捣一会之后发现 diskutil 有个叫做 CoreStorage 的模块，进一步发现 <code>diskutil coreStorage changeVolumePassphrase</code> 可以修改 CoreStorage 卷的密码，其中所需的卷 UUID 可以通过 <code>diskutil coreStorage list</code> 获得。</p>
<p>可以看得出，CoreStorage 又是苹果推的一种新技术，看 diskutil 里面的用语（PV、LV）推测是类似 LVM 的东西，Mac 以前似乎没有类似 LVM 的技术（AFAIK），网上搜索也搜索不到 CoreStorage 的相关信息，Lion 的 Developer Library 里面也是没有，最后还是在手册（man diskutil）里找到了一些信息。看完之后的感觉就是 CoreStorage 就是一个 LVM，Apple 终于有了 LVM。 <img src='http://blog.leafduo.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  不过看起来许多功能还没有开发出来接口，比如 LVM 的一些最基本的功能⋯⋯ <img src='http://blog.leafduo.com/wp-includes/images/smilies/icon_sad.gif' alt=':-(' class='wp-smiley' /> </p>
<p>看来 Lion 不光是在界面上模仿 iOS（我对这点颇有不满），在底层也下了不少功夫，CoreStorage 就是在看不见的地方默默发挥作用的一个好同志啊。底层的 UNIX 配合 用户友好的界面，是 Mac 的制胜法宝，只有这样才能留住如此多的开发者和一些相当挑剔的用户（比如设计师）。底层的 BSD 也给苹果减少了许多开发的困难，可以到处抄来抄去，可以派几个人推动一下某个项目的开发（比如 LLVM），看被抄的人不爽了还过去帮助修改（比如各种 BSD）。相比之下，再大的微软也不能把所有事情做好，至少给自己增加了许多开发难度。</p>
<p>另外，苹果你抄个 ZFS 过来吧，ZFS 多适合你现在的各种用途啊，又没有 Linux 的许可证问题，抓紧啊，I want a better filesystem!</p>
<p>PS：最后贴上 diskutil 手册的一部分，如果你有兴趣的话。</p>
<p><script src="https://gist.github.com/1087869.js?file=gistfile1.txt"></script></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.leafduo.com/48/lion-encrypted-volume-support/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>VMWare Fusion 装 Gentoo⋯⋯</title>
		<link>http://blog.leafduo.com/06/installing-gentoo-on-vmware-fusion/</link>
		<comments>http://blog.leafduo.com/06/installing-gentoo-on-vmware-fusion/#comments</comments>
		<pubDate>Sat, 25 Jun 2011 07:26:06 +0000</pubDate>
		<dc:creator>Leaf Duo</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.leafduo.com/?p=282</guid>
		<description><![CDATA[发现其它发行版真的没法胜任开发工作，而我又不喜欢自己编译，Ubuntu 里面的 nginx 缺少我需要用的模块，真伤心，本来想在虚拟机里弄一个不用编译的发行版来着，看样子还是得 Gentoo 出马。 VMWare Fusion 又傲娇了，又是驱动问题，偷懒用 genkernel 就好了，可谁让我这么勤奋呢？ lspci 告诉我们，VMWare 有个设备叫 00:10.0 SCSI storage controller: LSI Logic / Symbios Logic 53c1030 PCI-X Fusion-MPT Dual Ultra320 SCSI (rev 01)，查到对应的内核选项是 CONFIG_FUSION，记得选上。这样就解决了启动的时候找不到分区的问题⋯⋯ 还有一个问题是，启动到一半说 Freeing unused kernel memory，然后就死掉了，是新引入的 OpenRC 的问题，解决办法在这里。 Happy &#8230; <a href="http://blog.leafduo.com/06/installing-gentoo-on-vmware-fusion/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>发现其它发行版真的没法胜任开发工作，而我又不喜欢自己编译，Ubuntu 里面的 nginx 缺少我需要用的模块，真伤心，本来想在虚拟机里弄一个不用编译的发行版来着，看样子还是得 Gentoo 出马。</p>
<p>VMWare Fusion 又傲娇了，又是驱动问题，偷懒用 genkernel 就好了，可谁让我这么勤奋呢？</p>
<p>lspci 告诉我们，VMWare 有个设备叫 00:10.0 SCSI storage controller: LSI Logic / Symbios Logic 53c1030 PCI-X Fusion-MPT Dual Ultra320 SCSI (rev 01)，查到对应的内核选项是 <a href="http://cateee.net/lkddb/web-lkddb/FUSION.html">CONFIG_FUSION</a>，记得选上。这样就解决了启动的时候找不到分区的问题⋯⋯</p>
<p>还有一个问题是，启动到一半说 Freeing unused kernel memory，然后就死掉了，是新引入的 OpenRC 的问题，解决办法在<a href="http://dev.gentoo.org/~a3li/openrc.txt">这里</a>。</p>
<p>Happy coding!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.leafduo.com/06/installing-gentoo-on-vmware-fusion/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Installing Gentoo Linux on DELL R710</title>
		<link>http://blog.leafduo.com/10/installing-gentoo-linux-on-dell-r710/</link>
		<comments>http://blog.leafduo.com/10/installing-gentoo-linux-on-dell-r710/#comments</comments>
		<pubDate>Sun, 29 May 2011 15:42:10 +0000</pubDate>
		<dc:creator>Leaf Duo</dc:creator>
				<category><![CDATA[Information Technology]]></category>
		<category><![CDATA[DELL]]></category>
		<category><![CDATA[Gentoo]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[lvm]]></category>
		<category><![CDATA[RAID]]></category>

		<guid isPermaLink="false">http://blog.leafduo.com/?p=277</guid>
		<description><![CDATA[公司买了一台 R710，第一次自己装服务器上的 Linux，虽说区别不是很大，但是还是很值得纪录一下的哦。 服务器跟 PC 最大的区别大概就是硬件了吧，涉及到驱动的基本上就只有 RAID 控制器了吧？编译内核的时候那个纠结啊……那个启动不起来啊……真是…… 首先是得照着一个指南做，就是这个指南啦，比较适合以前装过 Gentoo 的人看。这个指南是装软件 RAID 和 LVM2，我们做的是硬件 RAID，所以里面软件 RAID 相关的东西就不用安装了，比如 dm-mod 之类的就不用装了。我还是习惯把 /boot 放在 LVM 里面，其实自己有的时候也觉得没啥必要，有点犯贱的意思……如果你也希望把 /boot 放在 LVM 里面，可以参考 Gentoo Wiki 的这篇文章，不过里面的内容略微有点过时了，比如内核参数 dolvm2，现在写成 dolvm 了。一开始安装的时候忘了做 initrd，查了半天才发现，还是不细心啊。 剩下的大概就是编译内核了，先随手把什么声卡驱动什么的去掉，然后重点是 RAID 驱动，一开始天真地以为 RAID 控制器的驱动是 LSI &#8230; <a href="http://blog.leafduo.com/10/installing-gentoo-linux-on-dell-r710/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>公司买了一台 R710，第一次自己装服务器上的 Linux，虽说区别不是很大，但是还是很值得纪录一下的哦。</p>
<p>服务器跟 PC 最大的区别大概就是硬件了吧，涉及到驱动的基本上就只有 RAID 控制器了吧？编译内核的时候那个纠结啊……那个启动不起来啊……真是……</p>
<p>首先是得照着一个指南做，就是<a href="http://www.gentoo.org/doc/en/gentoo-x86+raid+lvm2-quickinstall.xml">这个指南</a>啦，比较适合以前装过 Gentoo 的人看。这个指南是装软件 RAID 和 LVM2，我们做的是硬件 RAID，所以里面软件 RAID 相关的东西就不用安装了，比如 dm-mod 之类的就不用装了。我还是习惯把 /boot 放在 LVM 里面，其实自己有的时候也觉得没啥必要，有点犯贱的意思……如果你也希望把 /boot 放在 LVM 里面，可以参考 Gentoo Wiki 的<a href="http://www.gentoo-wiki.info/HOWTO_Install_Gentoo_on_an_LVM2_root_partition">这篇文章</a>，不过里面的内容略微有点过时了，比如内核参数 dolvm2，现在写成 dolvm 了。一开始安装的时候忘了做 initrd，查了半天才发现，还是不细心啊。</p>
<p>剩下的大概就是编译内核了，先随手把什么声卡驱动什么的去掉，然后重点是 RAID 驱动，一开始天真地以为 RAID 控制器的驱动是 LSI Logic MegaRAID SAS RAID Module 之类的，结果就是直接启动不起来了。后来认真起来，按照 lspci 的结果去网上找内核模块，发现应该是 <a href="http://cateee.net/lkddb/web-lkddb/FUSION.html">CONFIG_FUSION</a> 这个选项，之后就能顺利地启动了。</p>
<p>配置好一些基本的东西之后，还有一些硬件相关的小工具，最重要的还是 RAID 控制器的监控工具，网上找了很多，不过大多数都没法用，<a href="http://hwraid.le-vert.net/wiki/LSIFusionMPT">这一页</a>有两个工具，都比较好用，<a href="http://hwraid.le-vert.net/">HWRaid</a> 这个站似乎也很强大。里面提到的 lsiutil 是 LSI 官方提供的，Gentoo 源里那个似乎年久失修了，LSI 的官网上能够<a href="http://www.lsi.com/DistributionSystem/User/AssetMgr.aspx?asset=51101">找到</a>，不过不是很好找，下载下来是二进制。还有些能改前面板 LCD 的小工具什么的，我觉得没多大用，就算了（想改的话 BIOS 里面就有）。</p>
<p>有点后悔买了一个比较弱的 RAID 控制器，不过一切还要等有了负载再说，哈哈。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.leafduo.com/10/installing-gentoo-linux-on-dell-r710/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Python 判断一个变量是否是字符串</title>
		<link>http://blog.leafduo.com/31/python-tell-if-a-variable-is-a-string/</link>
		<comments>http://blog.leafduo.com/31/python-tell-if-a-variable-is-a-string/#comments</comments>
		<pubDate>Thu, 10 Mar 2011 15:00:31 +0000</pubDate>
		<dc:creator>Leaf Duo</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[bug]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://blog.leafduo.com/?p=270</guid>
		<description><![CDATA[忏悔啊，就写了一个类还出了 bug⋯⋯ 写了单元测试还出了 bug⋯⋯ type(data) == type("") 这种办法是不行的，因为 "" 是 str 类型，如果 data 是 unicode 的话这种判断就不成立了，而应该采用这种办法：isinstance(data, basestring)，其中 basestring 是 str 和 unicode 两个类的父类。 期待 python 3k⋯⋯]]></description>
			<content:encoded><![CDATA[<p>忏悔啊，就写了一个类还出了 bug⋯⋯</p>
<p>写了单元测试还出了 bug⋯⋯</p>
<p><code>type(data) == type("")</code> 这种办法是不行的，因为 "" 是 str 类型，如果 data 是 unicode 的话这种判断就不成立了，而应该采用这种办法：<code>isinstance(data, basestring)</code>，其中 basestring 是 str 和 unicode 两个类的父类。</p>
<p>期待 python 3k⋯⋯</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.leafduo.com/31/python-tell-if-a-variable-is-a-string/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>A Password Generator</title>
		<link>http://blog.leafduo.com/52/a-password-generator/</link>
		<comments>http://blog.leafduo.com/52/a-password-generator/#comments</comments>
		<pubDate>Sat, 12 Feb 2011 09:16:52 +0000</pubDate>
		<dc:creator>Leaf Duo</dc:creator>
				<category><![CDATA[Information Technology]]></category>
		<category><![CDATA[password]]></category>
		<category><![CDATA[pwgen]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://blog.leafduo.com/?p=269</guid>
		<description><![CDATA[一个简易的密码生成器，python 写的，遵循 2 句 BSD 许可证，应该很好懂，参数什么的可以自己调调。 PS：其实我写完了才发现有个叫 pwgen 的东西，pwgen -cns 16 似乎也不错。 参考： https://blog.delphij.net/2010/12/post-598.html phpmyadmin 生成密码的代码：https://github.com/Reen/phpmyadmin/blob/master/js/server_privileges.js#L80 #!/usr/bin/env python2.6 &#160; # Copyright 2011 Kou Zuyang. All rights reserved. # # Redistribution and use in source and binary forms, with or without &#8230; <a href="http://blog.leafduo.com/52/a-password-generator/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>一个简易的密码生成器，python 写的，遵循 2 句 BSD 许可证，应该很好懂，参数什么的可以自己调调。</p>
<p>PS：其实我写完了才发现有个叫 <code>pwgen</code> 的东西，<code>pwgen -cns 16</code> 似乎也不错。</p>
<p>参考：</p>
<ol>
<li><a href="https://blog.delphij.net/2010/12/post-598.html">https://blog.delphij.net/2010/12/post-598.html</a></li>
<li>phpmyadmin 生成密码的代码：<a href="https://github.com/Reen/phpmyadmin/blob/master/js/server_privileges.js#L80">https://github.com/Reen/phpmyadmin/blob/master/js/server_privileges.js#L80</a></li>
</ol>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">#!/usr/bin/env python2.6</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># Copyright 2011 Kou Zuyang. All rights reserved.</span>
<span style="color: #808080; font-style: italic;">#</span>
<span style="color: #808080; font-style: italic;"># Redistribution and use in source and binary forms, with or without modification, are</span>
<span style="color: #808080; font-style: italic;"># permitted provided that the following conditions are met:</span>
<span style="color: #808080; font-style: italic;">#</span>
<span style="color: #808080; font-style: italic;">#    1. Redistributions of source code must retain the above copyright notice, this list of</span>
<span style="color: #808080; font-style: italic;">#       conditions and the following disclaimer.</span>
<span style="color: #808080; font-style: italic;">#</span>
<span style="color: #808080; font-style: italic;">#    2. Redistributions in binary form must reproduce the above copyright notice, this list</span>
<span style="color: #808080; font-style: italic;">#       of conditions and the following disclaimer in the documentation and/or other materials</span>
<span style="color: #808080; font-style: italic;">#       provided with the distribution.</span>
<span style="color: #808080; font-style: italic;">#</span>
<span style="color: #808080; font-style: italic;"># THIS SOFTWARE IS PROVIDED BY Kou Zuyang ``AS IS'' AND ANY EXPRESS OR IMPLIED</span>
<span style="color: #808080; font-style: italic;"># WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND</span>
<span style="color: #808080; font-style: italic;"># FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL &lt;COPYRIGHT HOLDER&gt; OR</span>
<span style="color: #808080; font-style: italic;"># CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR</span>
<span style="color: #808080; font-style: italic;"># CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR</span>
<span style="color: #808080; font-style: italic;"># SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON</span>
<span style="color: #808080; font-style: italic;"># ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING</span>
<span style="color: #808080; font-style: italic;"># NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF</span>
<span style="color: #808080; font-style: italic;"># ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.</span>
<span style="color: #808080; font-style: italic;">#</span>
<span style="color: #808080; font-style: italic;"># The views and conclusions contained in the software and documentation are those of the</span>
<span style="color: #808080; font-style: italic;"># authors and should not be interpreted as representing official policies, either expressed</span>
<span style="color: #808080; font-style: italic;"># or implied, of Kou Zuyang.</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">random</span><span style="color: #66cc66;">;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> generate_password<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    alphabet = <span style="color: #483d8b;">'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNPOPQRSTUVWXYZ'</span>
    number = <span style="color: #483d8b;">'1234567890'</span>
    special = <span style="color: #483d8b;">'!@#$%^&amp;amp;*()-=_+[]{};:,./<span style="color: #000099; font-weight: bold;">\~</span>`?'</span>
    charset = alphabet <span style="color: #66cc66;">*</span> <span style="color: #ff4500;">3</span> + number <span style="color: #66cc66;">*</span> <span style="color: #ff4500;">7</span> + special <span style="color: #66cc66;">*</span> <span style="color: #ff4500;">2</span>
    <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">''</span>.<span style="color: black;">join</span><span style="color: black;">&#40;</span><span style="color: black;">&#91;</span><span style="color: #dc143c;">random</span>.<span style="color: black;">choice</span><span style="color: black;">&#40;</span>charset<span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">for</span> x <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">xrange</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">16</span><span style="color: black;">&#41;</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ == <span style="color: #483d8b;">&quot;__main__&quot;</span>:
    generate_password<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://blog.leafduo.com/52/a-password-generator/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Get Nagios to Work with Nginx (Gentoo)</title>
		<link>http://blog.leafduo.com/43/get-nagios-to-work-with-nginx/</link>
		<comments>http://blog.leafduo.com/43/get-nagios-to-work-with-nginx/#comments</comments>
		<pubDate>Fri, 11 Feb 2011 18:25:43 +0000</pubDate>
		<dc:creator>Leaf Duo</dc:creator>
				<category><![CDATA[Information Technology]]></category>
		<category><![CDATA[fcgi]]></category>
		<category><![CDATA[fcgiwrap]]></category>
		<category><![CDATA[Gentoo]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Nagios]]></category>
		<category><![CDATA[Nginx]]></category>
		<category><![CDATA[spawn-fcgi]]></category>

		<guid isPermaLink="false">http://blog.leafduo.com/?p=267</guid>
		<description><![CDATA[今天装 Nagios，开源监控软件。 照例第一步： emerge net-analyzer/nagios 这个包是个 meta 包，里面似乎有一个内核和一些插件，以后再研究，先搭起来再说。 跑起 Nagios： /etc/init.d/nagios start rc-update add nagios default 安装完成之后它会告诉你，要是 Apache 或者 Lighttpd 的话我会给你配好，不是的话自己看着办吧，于是我就自己来了。:-( 首先安装 spawn-fcgi 和 fcgiwrap，第一个是管理 fcgi 进程的，第二个是把 CGI 包装成 fcgi 的。fcgiwrap 这兄弟目前被 ~x86 mask 了，先 unmask。 echo www-misc/fcgiwrap ~x86 &#62;&#62; &#8230; <a href="http://blog.leafduo.com/43/get-nagios-to-work-with-nginx/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>今天装 <a href="http://www.nagios.org/">Nagios</a>，开源监控软件。</p>
<p>照例第一步：</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">emerge net-analyzer<span style="color: #000000; font-weight: bold;">/</span>nagios</pre></div></div>

<p>这个包是个 meta 包，里面似乎有一个内核和一些插件，以后再研究，先搭起来再说。</p>
<p>跑起 Nagios：</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>init.d<span style="color: #000000; font-weight: bold;">/</span>nagios start
rc-update add nagios default</pre></div></div>

<p>安装完成之后它会告诉你，要是 Apache 或者 Lighttpd 的话我会给你配好，不是的话自己看着办吧，于是我就自己来了。:-(</p>
<p>首先安装 spawn-fcgi 和 fcgiwrap，第一个是管理 fcgi 进程的，第二个是把 CGI 包装成 fcgi 的。fcgiwrap 这兄弟目前被 ~x86 mask 了，先 unmask。</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">echo</span> www-misc<span style="color: #000000; font-weight: bold;">/</span>fcgiwrap ~x86 <span style="color: #000000; font-weight: bold;">&gt;&gt;</span> <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>portage<span style="color: #000000; font-weight: bold;">/</span>package.keywords</pre></div></div>

<p>然后安装：</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">emerge www-servers<span style="color: #000000; font-weight: bold;">/</span>spawn-fcgi www-misc<span style="color: #000000; font-weight: bold;">/</span>fcgiwrap</pre></div></div>

<p>跑起 spawn-fcgi：</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">sudo</span> spawn-fcgi <span style="color: #660033;">-a</span> 127.0.0.1 <span style="color: #660033;">-p</span> <span style="color: #000000;">22222</span> <span style="color: #660033;">-P</span> <span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span>run<span style="color: #000000; font-weight: bold;">/</span>fcgiwrap.pid <span style="color: #660033;">-u</span> nagios <span style="color: #660033;">-g</span> nagios <span style="color: #660033;">--</span> <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>sbin<span style="color: #000000; font-weight: bold;">/</span>fcgiwrap</pre></div></div>

<p>-a 是主机，-p 是端口（用 unix domain 也行），-P 是 pid 文件，-u 是用户，-g 是组，-- 后面是要运行的命令，用户名和组一定要对，主机和端口要跟 nginx 对上。这条命令是起 CGI 部分的，Nagios 也用了 PHP，PHP 请通过 fcgi 自行跑起来 <img src='http://blog.leafduo.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> ，php-fpm 或者 spawn-fcgi 均可，参考 WordPress 之类就行。</p>
<p>下面是 nginx 的配置，主要是抄的别人的，主体参考<a href="http://yemaosheng.com/?p=899">这里</a>，另外也参考<a href="http://www.matejunkie.com/howto-let-nginx-serve-the-nagios-web-interface/">这里</a>。尤其是<code>fastcgi_param  AUTH_USER          $remote_user; fastcgi_param  REMOTE_USER        $remote_user;</code> 两句，前一篇没有，害惨我了，nagios 一直说认证不通过……</p>
<p>自己发挥改改就好撒。</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">location <span style="color: #000000; font-weight: bold;">/</span> <span style="color: #7a0874; font-weight: bold;">&#123;</span>
        auth_basic <span style="color: #ff0000;">&quot;Restricted&quot;</span>;
        auth_basic_user_file <span style="color: #000000; font-weight: bold;">/</span>PATH<span style="color: #000000; font-weight: bold;">/</span>TO<span style="color: #000000; font-weight: bold;">/</span>HTPASSWD;
&nbsp;
        root <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>share<span style="color: #000000; font-weight: bold;">/</span>nagios<span style="color: #000000; font-weight: bold;">/</span>htdocs;
&nbsp;
        location ~ \.php$ <span style="color: #7a0874; font-weight: bold;">&#123;</span>
                fastcgi_pass   YOUR_PHP_UPSTREAM;
                fastcgi_index  index.php;
                fastcgi_param  SCRIPT_FILENAME  <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>share<span style="color: #000000; font-weight: bold;">/</span>nagios<span style="color: #000000; font-weight: bold;">/</span>htdocs<span style="color: #007800;">$fastcgi_script_name</span>;
                include fastcgi_params;
        <span style="color: #7a0874; font-weight: bold;">&#125;</span>
&nbsp;
        location <span style="color: #000000; font-weight: bold;">/</span>nagios<span style="color: #000000; font-weight: bold;">/</span> <span style="color: #7a0874; font-weight: bold;">&#123;</span>
                location <span style="color: #000000; font-weight: bold;">/</span>nagios<span style="color: #000000; font-weight: bold;">/</span>images<span style="color: #000000; font-weight: bold;">/</span> <span style="color: #7a0874; font-weight: bold;">&#123;</span>
                        <span style="color: #c20cb9; font-weight: bold;">gzip</span> off;
                <span style="color: #7a0874; font-weight: bold;">&#125;</span>
                expires 30d;
                <span style="color: #7a0874; font-weight: bold;">alias</span> <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>share<span style="color: #000000; font-weight: bold;">/</span>nagios<span style="color: #000000; font-weight: bold;">/</span>htdocs<span style="color: #000000; font-weight: bold;">/</span>;
        <span style="color: #7a0874; font-weight: bold;">&#125;</span>
&nbsp;
        location <span style="color: #000000; font-weight: bold;">/</span>docs<span style="color: #000000; font-weight: bold;">/</span> <span style="color: #7a0874; font-weight: bold;">&#123;</span>
                root <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>share<span style="color: #000000; font-weight: bold;">/</span>nagios<span style="color: #000000; font-weight: bold;">/</span>htdocs<span style="color: #000000; font-weight: bold;">/</span>;
                index index.html;
        <span style="color: #7a0874; font-weight: bold;">&#125;</span>
&nbsp;
        location ~ \.cgi <span style="color: #7a0874; font-weight: bold;">&#123;</span>
                fastcgi_pass 127.0.0.1:<span style="color: #000000;">22222</span>;
                fastcgi_index index.cgi;
                fastcgi_param SCRIPT_FILENAME <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>lib<span style="color: #007800;">$fastcgi_script_name</span>;
                include fastcgi_params;
                fastcgi_param  AUTH_USER          <span style="color: #007800;">$remote_user</span>;
                fastcgi_param  REMOTE_USER        <span style="color: #007800;">$remote_user</span>;
        <span style="color: #7a0874; font-weight: bold;">&#125;</span>
<span style="color: #7a0874; font-weight: bold;">&#125;</span></pre></div></div>

<p>关于里面提到的 htpasswd，是 <a href="http://en.wikipedia.org/wiki/Basic_access_authentication">basic auth</a> 用的，咋生成看<a href="http://wiki.nginx.org/HttpAuthBasicModule">文档</a>吧。</p>
<p>Restart Nginx &#038; enjoy!</p>
<p>参考：</p>
<ol>
<li><a href="http://yemaosheng.com/?p=899">http://yemaosheng.com/?p=899</a></li>
<li><a href="http://www.matejunkie.com/howto-let-nginx-serve-the-nagios-web-interface/">http://www.matejunkie.com/howto-let-nginx-serve-the-nagios-web-interface/</a></li>
<li><a href="http://wiki.nginx.org/HttpAuthBasicModule">http://wiki.nginx.org/HttpAuthBasicModule</a></li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://blog.leafduo.com/43/get-nagios-to-work-with-nginx/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>禁止 ssh 密码登陆</title>
		<link>http://blog.leafduo.com/26/forbid-ssh-login-via-password/</link>
		<comments>http://blog.leafduo.com/26/forbid-ssh-login-via-password/#comments</comments>
		<pubDate>Thu, 10 Feb 2011 13:53:26 +0000</pubDate>
		<dc:creator>Leaf Duo</dc:creator>
				<category><![CDATA[Information Technology]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[ssh]]></category>

		<guid isPermaLink="false">http://blog.leafduo.com/?p=266</guid>
		<description><![CDATA[/etc/ssh/sshd_config 里面 PasswordAuthentication no UsePAM no 为啥这样不要问我……去看看 /etc/ssh/sshd_config 里面的注释或者 man sshd 之类的吧，因为我也说不非常清楚，哈哈哈哈。]]></description>
			<content:encoded><![CDATA[<p><code>/etc/ssh/sshd_config</code> 里面</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">PasswordAuthentication no
UsePAM no</pre></div></div>

<p>为啥这样不要问我……去看看 <code>/etc/ssh/sshd_config</code> 里面的注释或者 <code>man sshd</code> 之类的吧，因为我也说不非常清楚，哈哈哈哈。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.leafduo.com/26/forbid-ssh-login-via-password/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>解决 WordPress 自动升级中遇到的一个验证问题</title>
		<link>http://blog.leafduo.com/05/solution-to-wordpress-auto-update-auth-problem/</link>
		<comments>http://blog.leafduo.com/05/solution-to-wordpress-auto-update-auth-problem/#comments</comments>
		<pubDate>Wed, 09 Feb 2011 18:50:05 +0000</pubDate>
		<dc:creator>Leaf Duo</dc:creator>
				<category><![CDATA[Information Technology]]></category>
		<category><![CDATA[Gentoo]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[OpenSSH]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[ssh]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://blog.leafduo.com/?p=263</guid>
		<description><![CDATA[WordPress 要升级 3.0.5，我懒，所以自动升级，点开自动升级的页面，输入验证方式，发现木有 sftp 的选项，印象中原来是有的，去查了一下，发现不是 WordPress 的问题，而是 PHP 没有装载 ssh 的模块，于是装上。 emerge dev-php5/pecl-ssh2 然后升级页面就神奇地出现了 SSH2 的选项，于是开心地填上用户名密码，一个回车，告诉你用户名或密码错误……我说不可能啊，于是去查系统日志，日志里竟然一个字都没写……明显就不是密码错了嘛。 啥问题呢，不清楚，咋办呢，查 WordPress 的源码吧。发现 wp-admin/includes/file.php 里有个函数叫 get_filesystem_method()，它的注释告诉我 WordPress 升级写文件有这么几种方式：Direct, SSH2, FTP PHP Extension, FTP Sockets，优先级依次递减，于是发现还有 Direct 这么一种神奇的方式，快速解决问题： chown -R nobody:nobody /path/to/WordPress。（我用 php-fpm 运行的，php 的 user &#8230; <a href="http://blog.leafduo.com/05/solution-to-wordpress-auto-update-auth-problem/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>WordPress 要升级 3.0.5，我懒，所以自动升级，点开自动升级的页面，输入验证方式，发现木有 sftp 的选项，印象中原来是有的，去查了一下，发现不是 WordPress 的问题，而是 PHP 没有装载 ssh 的模块，于是装上。</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">emerge dev-php5<span style="color: #000000; font-weight: bold;">/</span>pecl-ssh2</pre></div></div>

<p>然后升级页面就神奇地出现了 SSH2 的选项，于是开心地填上用户名密码，一个回车，告诉你用户名或密码错误……我说不可能啊，于是去查系统日志，日志里竟然一个字都没写……明显就不是密码错了嘛。</p>
<p><a href="https://picasaweb.google.com/lh/photo/xkySpdVTZ8xpIVrPLffVhA?feat=embedwebsite"><img src="https://lh6.googleusercontent.com/_7Y_7M0vQVWs/TVLi45Y4HfI/AAAAAAAACZY/v4afyZn-oHM/s800/Screen%20shot%202011-02-10%20at%202.09.08%20AM.png" height="383" width="534" /></a></p>
<p>啥问题呢，不清楚，咋办呢，查 WordPress 的源码吧。发现 <a href="http://phpxref.ftwr.co.uk/wordpress/nav.html?wp-admin/includes/file.php.source.html#l850">wp-admin/includes/file.php</a> 里有个函数叫 <a href="http://phpxref.ftwr.co.uk/wordpress/nav.html?wp-admin/includes/file.php.source.html#l850"><code>get_filesystem_method()</code></a>，它的注释告诉我 WordPress 升级写文件有这么几种方式：Direct, SSH2, FTP PHP Extension, FTP Sockets，优先级依次递减，于是发现还有 Direct 这么一种神奇的方式，快速解决问题： <code>chown -R nobody:nobody /path/to/WordPress</code>。（我用 php-fpm 运行的，php 的 user 是 nobody）</p>
<p>不能把问题放着不管是不？去看看是啥问题，在 WordPress 源码里搜 "Username/Password incorrect for"，发现几个文件里都有，分别对应几种连接方式：direct、ssh2、ftpext、ftpsockets。当然我们要看 SSH2 是不？于是这个文件是 <a href="http://phpxref.ftwr.co.uk/wordpress/nav.html?wp-admin/includes/class-wp-filesystem-ssh2.php.source.html#l103">wp-admin/includes/class-wp-filesystem-ssh2.php</a>，里面那个 <a href="http://phpxref.ftwr.co.uk/wordpress/nav.html?wp-admin/includes/class-wp-filesystem-ssh2.php.source.html#l103"><code>connect()</code></a> 函数是我感兴趣的，里面有这么一句：</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #339933;">!</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">keys</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #339933;">!</span> <span style="color: #339933;">@</span><span style="color: #990000;">ssh2_auth_password</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">link</span><span style="color: #339933;">,</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">options</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'username'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">options</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'password'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">errors</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">add</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'auth'</span><span style="color: #339933;">,</span> <span style="color: #990000;">sprintf</span><span style="color: #009900;">&#40;</span>__<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Username/Password incorrect for %s'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">options</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'username'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>也就是说没有使用 key 的时候，用密码验证，<a href="http://php.net/manual/en/function.ssh2-auth-password.php"><code>ssh2_auth_password()</code></a> 失败的话就说是用户名或密码错。（PHP 达人告诉我前面的 @ 是啥？）</p>
<p>查这个函数的<a href="http://php.net/manual/en/function.ssh2-auth-password.php">原型</a>，人家只说失败的时候返回 false，谁说一定是密码错误了，你妹的……</p>
<p>不过在这个文件里还有新发现，在<a href="http://phpxref.ftwr.co.uk/wordpress/nav.html?wp-admin/includes/class-wp-filesystem-ssh2.php.source.html#l1">这个类的注释</a>里，发现了<a href="http://kevin.vanzonneveld.net/techblog/article/make_ssh_connections_with_php/">一篇 pecl-ssh2 的安装指南</a>，在里面发现了问题：On the serverside, 'PasswordAuthentication yes' must be enabled in the sshd_config. 一查我的配置，果然给弄成 no 了……</p>
<p>欣喜若狂地改成 yes，然后重启 sshd，<code>/etc/init.d/sshd restart</code>，竟然没法重启……尝试 reload，<code>/etc/init.d/sshd reload</code>，说 sshd 没运行（No /usr/sbin/sshd found running; none killed.），又开始扯淡了！！！</p>
<p>遵循不知道谁的教导，重新 emerge 一遍 openssh。</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">emerge net-misc<span style="color: #000000; font-weight: bold;">/</span>openssh</pre></div></div>

<p>然后</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>init.d<span style="color: #000000; font-weight: bold;">/</span>sshd restart</pre></div></div>

<p>就能重启了……</p>
<p>之后回到 WordPress 输上密码，发现能登录上了，变成 PHP 错误了……仔细一看，我的账户也没有改 WordPress 代码的权限啊……</p>
<p>折腾一圈白干了，专门弄个账户还不如改权限（<code>chown -R nobody:nobody</code>）呢。</p>
<p><del datetime="2011-02-09T18:03:26+00:00">不过过程中还发现了新的问题，sshd_config 里面 PasswordAuthentication no 之后还是能从别的主机用密码登陆（不过 php 这个 ssh2 的库登陆不了了），很神奇吧……以后再看是什么问题吧。</del></p>
<p>大概找到是啥问题了，下篇发出来吧。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.leafduo.com/05/solution-to-wordpress-auto-update-auth-problem/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Gentoo/Nginx with IPv6 (Tunnel) Support</title>
		<link>http://blog.leafduo.com/51/gentoonginx-with-ipv6-tunnel-support/</link>
		<comments>http://blog.leafduo.com/51/gentoonginx-with-ipv6-tunnel-support/#comments</comments>
		<pubDate>Sun, 06 Feb 2011 10:47:51 +0000</pubDate>
		<dc:creator>Leaf Duo</dc:creator>
				<category><![CDATA[Information Technology]]></category>
		<category><![CDATA[Gentoo]]></category>
		<category><![CDATA[ipv6]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Nginx]]></category>
		<category><![CDATA[tunnel]]></category>

		<guid isPermaLink="false">http://blog.leafduo.com/?p=262</guid>
		<description><![CDATA[弄了一个 he.net 的 IPv6 隧道，给服务器用。（你说你 Linode 为啥不提供原生 IPv6，为啥？） 一会就申请完了，你就获得 4 个 IP，服务器的 IPv4、IPv6，客户端的 IPv4、IPv6，你需要这些 IP 来做一些配置。 首先是配好 Gentoo，LInode 的 wiki 写的很清楚，注意 interface 的名字似乎不能太短，一开始我起的叫 he，出了奇怪的错误……改成 hetun 就好了…… 注意 Linode 的 eth0 是用的 DHCP，别乱改。 接下来是 Nginx，因为编译的时候已经带上 USE="ipv6" 了，所以就不需要重新编译了，改一下 Listen 语句就行。我原先都是用的 Listen 0.0.0.0:80，要使 &#8230; <a href="http://blog.leafduo.com/51/gentoonginx-with-ipv6-tunnel-support/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>弄了一个 <a href="http://he.net/">he.net</a> 的 <a href="http://tunnelbroker.net/">IPv6 隧道</a>，给服务器用。（你说你 <a href="http://www.linode.com/">Linode</a> 为啥不提供原生 IPv6，为啥？）</p>
<p>一会就申请完了，你就获得 4 个 IP，服务器的 IPv4、IPv6，客户端的 IPv4、IPv6，你需要这些 IP 来做一些配置。</p>
<p>首先是配好 Gentoo，<a href="http://www.linode.com/wiki/index.php/IPv6#Gentoo">LInode 的 wiki</a> 写的很清楚，注意 interface 的名字似乎不能太短，一开始我起的叫 he，出了奇怪的错误……改成 hetun 就好了……</p>
<p>注意 Linode 的 eth0 是用的 DHCP，别乱改。</p>
<p>接下来是 Nginx，因为编译的时候已经带上 USE="ipv6" 了，所以就不需要重新编译了，改一下 Listen 语句就行。我原先都是用的 Listen 0.0.0.0:80，要使 IPv6 有效的话要改成 [::]:80，于是尝试性地改了一个域名的配置。</p>
<p>重启 Nginx，报错，说 80 端口已经被 bind 了，我说不可能啊，lsof -i tcp:80 也是空的。想了想隐约知道是怎么回事了，于是把所有的配置文件都从 Listen 0.0.0.0:80 改成 Listen [::]:80，重启，OK 了。</p>
<p>想来是因为 Nginx 把 0.0.0.0:80 和 [::]:80 认成了两个端口，于是 bind 了两遍，这不就冲突了嘛……都改成 Listen [::]:80 就好了。</p>
<p>参考文献：</p>
<ol>
<li><a href="http://kovyrin.net/2010/01/16/enabling-ipv6-support-in-nginx/">http://kovyrin.net/2010/01/16/enabling-ipv6-support-in-nginx/</a></li>
<li>tunnelbroker.net 给的配置命令</li>
<li><a href="http://www.linode.com/wiki/index.php/IPv6#Gentoo">http://www.linode.com/wiki/index.php/IPv6#Gentoo</a></li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://blog.leafduo.com/51/gentoonginx-with-ipv6-tunnel-support/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>cURL 下载迅雷离线</title>
		<link>http://blog.leafduo.com/20/use-curl-to-download-xunlei-offline-download/</link>
		<comments>http://blog.leafduo.com/20/use-curl-to-download-xunlei-offline-download/#comments</comments>
		<pubDate>Sun, 06 Feb 2011 02:57:20 +0000</pubDate>
		<dc:creator>Leaf Duo</dc:creator>
				<category><![CDATA[Information Technology]]></category>
		<category><![CDATA[cURL]]></category>
		<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://blog.leafduo.com/?p=261</guid>
		<description><![CDATA[今天下载 Xcode 4 GM，很大，3G+（苹果东西一向大），于是想走这样的线路，BT->迅雷离线->某服务器->笔记本，这样就避免迅雷离线有的时候下载不稳定之类的问题，所以需要用 cURL 之类的东西下载迅雷离线，稍微尝试之后，办法出来啦。 首先用浏览器获得真实的下载链接，开头类似 http://vod19.c7.lixian.vip.xunlei.com/download 这样的，要真正开始下载之后的链接。 找到 vip.xunlei.com 这个域名下面的 cookie，名字是 gdriveid，把名字和值记下来。 curl "http://DOWNLOAD.LINK/" --cookie "gdriveid=VALUE" -o FILE_NAME OK 了。 本来是用 http://gdl.lixian.vip.xunlei.com/download? 开头的链接来尝试的，后来发现重定向到 http://vod19.c7.lixian.vip.xunlei.com/download 之后 cURL 没有把 cookie 带上，而服务器对这两个 URI 的访问都需要验证这个 cookie，我对 cURL 又不是很熟，就转而用 http://vod19.c7.lixian.vip.xunlei.com/download 这样的链接了…… 可能从文件里读取 cookie &#8230; <a href="http://blog.leafduo.com/20/use-curl-to-download-xunlei-offline-download/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>今天下载 Xcode 4 GM，很大，3G+（苹果东西一向大），于是想走这样的线路，BT->迅雷离线->某服务器->笔记本，这样就避免迅雷离线有的时候下载不稳定之类的问题，所以需要用 cURL 之类的东西下载迅雷离线，稍微尝试之后，办法出来啦。</p>
<ol>
<li>首先用浏览器获得真实的下载链接，开头类似 http://vod19.c7.lixian.vip.xunlei.com/download 这样的，要真正开始下载之后的链接。
</li>
<li>找到 vip.xunlei.com 这个域名下面的 cookie，名字是 gdriveid，把名字和值记下来。
</li>
<li>curl "http://DOWNLOAD.LINK/" --cookie "gdriveid=VALUE" -o FILE_NAME
</li>
<li>OK 了。</li>
</ol>
<p>本来是用 http://gdl.lixian.vip.xunlei.com/download? 开头的链接来尝试的，后来发现重定向到 http://vod19.c7.lixian.vip.xunlei.com/download 之后 cURL 没有把 cookie 带上，而服务器对这两个 URI 的访问都需要验证这个 cookie，我对 cURL 又不是很熟，就转而用 http://vod19.c7.lixian.vip.xunlei.com/download 这样的链接了……</p>
<p>可能从文件里读取 cookie 可行，我没试成功。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.leafduo.com/20/use-curl-to-download-xunlei-offline-download/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>2010 -&gt; 2011</title>
		<link>http://blog.leafduo.com/37/2010-2011/</link>
		<comments>http://blog.leafduo.com/37/2010-2011/#comments</comments>
		<pubDate>Fri, 04 Feb 2011 16:51:37 +0000</pubDate>
		<dc:creator>Leaf Duo</dc:creator>
				<category><![CDATA[life]]></category>
		<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Cocoa Touch]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Mac]]></category>

		<guid isPermaLink="false">http://blog.leafduo.com/?p=257</guid>
		<description><![CDATA[不知道这时候写这种标题的文章算不算有点太晚了呢？ 先总结总结吧，从年初开始。 依我自己的记忆力，估计是什么都想不起来了，于是还是询问了一位重要参考人，嗯嗯。 1 月，复习考试……咋上来就是考试呢，考试复习，高数杯具了…… 2 月放假，放假了，看书，玩，反正也没做什么正事吧。买了机械键盘，不过一直也没机会用，也就在家用用，以后或许就好了。 开学了，半路跟着做了个项目，为 MSTC PK 赛做的游戏，进去的时候就已经很乱了，其实我也没做啥……就是提供了一台笔记本测试用……帮忙调试，写了一些网络相关的代码。第一次通宵，终于做完了，天亮了起来去 M 记一起吃早饭，然后回去睡觉……中午再出去做 PK 赛的宣传。两轮比赛完了活动也就结束了，开发挺累，不过比赛就当是玩了。 结束了之后也就快考试了，再次复习考试。这次还好。 放假前找好了一个实验室，放假之后就去了，开始做项目，内容就不说了。 去看了移动开发者大会，Google 创新论坛，出去逛逛挺好。 下学期也跟上学期差不多，开学 -> 项目 -> 休息 -> 复习考试。考试也还好，嗯。 老婆说这一年我逐渐适应大学生活了，嗯，应该是这样吧。每学期换个地方，每学期做个项目，每学期一次考试，呵呵。 这一年做的项目在变，呆的地方在变，不过还是有些东西没变。比如说一直还是在玩 Linux，虽然不拿来当桌面用已经有一年半了，不过各种机会还是一直在折腾，手里有几台服务器，也装过一段时间 Gentoo Prefix。也折腾过两天 FreeBSD，觉得不好玩……主要是跟 Linux 的区别没有体会出来。 暑假还做了一会 Mac 开发，一个小项目，仿照单词随意背做的一个 Mac 版本。算是了解了一下 Objective-C &#8230; <a href="http://blog.leafduo.com/37/2010-2011/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><a href="https://picasaweb.google.com/lh/photo/I4n5vCyrJQK9YJn1A4Jrug?feat=embedwebsite"><img src="https://lh6.googleusercontent.com/_7Y_7M0vQVWs/TUwgcIkx0SI/AAAAAAAACZA/Hr1CryVNZk4/s640/Screen%20shot%202011-02-04%20at%2011.48.28%20PM.png" height="201" width="640" /></a></p>
<p>不知道这时候写这种标题的文章算不算有点太晚了呢？</p>
<p>先总结总结吧，从年初开始。</p>
<p>依我自己的记忆力，估计是什么都想不起来了，于是还是询问了一位重要参考人，嗯嗯。</p>
<p>1 月，复习考试……咋上来就是考试呢，考试复习，高数杯具了……</p>
<p>2 月放假，放假了，看书，玩，反正也没做什么正事吧。买了<a href="http://s.taobao.com/search?q=Cherry+G80-3000+LSCEU-2">机械键盘</a>，不过一直也没机会用，也就在家用用，以后或许就好了。</p>
<p>开学了，半路跟着做了个项目，为 MSTC PK 赛做的游戏，进去的时候就已经很乱了，其实我也没做啥……就是提供了一台笔记本测试用……帮忙调试，写了一些网络相关的代码。第一次通宵，终于做完了，天亮了起来去 M 记一起吃早饭，然后回去睡觉……中午再出去做 PK 赛的宣传。两轮比赛完了活动也就结束了，开发挺累，不过比赛就当是玩了。</p>
<p>结束了之后也就快考试了，再次复习考试。这次还好。</p>
<p>放假前找好了一个实验室，放假之后就去了，开始做项目，内容就不说了。</p>
<p>去看了移动开发者大会，Google 创新论坛，出去逛逛挺好。</p>
<p>下学期也跟上学期差不多，开学 -> 项目 -> 休息 -> 复习考试。考试也还好，嗯。</p>
<p>老婆说这一年我逐渐适应大学生活了，嗯，应该是这样吧。每学期换个地方，每学期做个项目，每学期一次考试，呵呵。</p>
<p>这一年做的项目在变，呆的地方在变，不过还是有些东西没变。比如说一直还是在玩 Linux，虽然不拿来当桌面用已经有一年半了，不过各种机会还是一直在折腾，手里有几台服务器，也装过一段时间 <a href="http://www.gentoo.org/proj/en/gentoo-alt/prefix/">Gentoo Prefix</a>。也折腾过两天 FreeBSD，觉得不好玩……主要是跟 Linux 的区别没有体会出来。</p>
<p>暑假还做了一会 Mac 开发，一个小项目，仿照<a href="http://www.i5023.com/works/beidanc/">单词随意背</a>做的一个 Mac 版本。算是了解了一下 Objective-C 和 Cocoa，算是为接下来的 Cocoa Touch 和 iOS 做了点铺垫。</p>
<p>接下来的比较长的一段时间，我会专注于一个项目，我的职责主要是 Linux、Web 和 iOS 开发，基本上都是我稍微有点熟的领域，另外还能远离 Windows，真好。</p>
<p>下学期的课应该不是很重了，有更多的时间做自己的事情，哈哈哈哈。</p>
<p>给自己订几个本年目标吧，截止明年寒假？</p>
<ul>
<li>翻译一篇维基百科条目。既锻炼了英语水平又做了贡献，当然，一篇只是开头而已，一旦第一篇搞定了，接下来也就简单了。</li>
<li>平均每两周一篇博客。2010 年没写多少东西，惭愧。</li>
<li>锻炼。据说 7+1>8，加油。</li>
<li>读一本自己觉得有深度的书。偏底层、偏理论或者偏思想的。</li>
<li>学五笔。唉……不知道拖了多久了……</li>
</ul>
<p>还有些推荐执行的？</p>
<ul>
<li>博客要有题图。（就像这篇一样这么烂的？）</li>
<li>读一本非技术类英语书。</li>
<li>日语。现在这个日语水平啊……惭愧啊……</li>
</ul>
<p>明年这个时候来 check 吧！</p>
<p>最后给大家拜年！</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.leafduo.com/37/2010-2011/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Flush DNS Cache on Mac &amp; Chrome</title>
		<link>http://blog.leafduo.com/30/flush-dns-cache-on-mac-chrome/</link>
		<comments>http://blog.leafduo.com/30/flush-dns-cache-on-mac-chrome/#comments</comments>
		<pubDate>Sat, 25 Dec 2010 15:30:30 +0000</pubDate>
		<dc:creator>Leaf Duo</dc:creator>
				<category><![CDATA[Information Technology]]></category>
		<category><![CDATA[Cache]]></category>
		<category><![CDATA[Chrome]]></category>
		<category><![CDATA[DNS]]></category>
		<category><![CDATA[Mac]]></category>

		<guid isPermaLink="false">http://blog.leafduo.com/?p=255</guid>
		<description><![CDATA[Mac Leopard &#038; Snow Leopard: dscacheutil -flushcache Chrome: chrome://net-internals/#dns click on "Clear host cache"]]></description>
			<content:encoded><![CDATA[<p>Mac Leopard &#038; Snow Leopard:</p>
<p>dscacheutil -flushcache</p>
<p>Chrome:</p>
<p>chrome://net-internals/#dns</p>
<p>click on "Clear host cache"</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.leafduo.com/30/flush-dns-cache-on-mac-chrome/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>西单大悦城一日游</title>
		<link>http://blog.leafduo.com/54/one-day-in-joy-sity/</link>
		<comments>http://blog.leafduo.com/54/one-day-in-joy-sity/#comments</comments>
		<pubDate>Tue, 21 Dec 2010 05:17:54 +0000</pubDate>
		<dc:creator>Leaf Duo</dc:creator>
				<category><![CDATA[Information Technology]]></category>
		<category><![CDATA[life]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[crash]]></category>
		<category><![CDATA[iPhone]]></category>

		<guid isPermaLink="false">http://blog.leafduo.com/?p=253</guid>
		<description><![CDATA[该说这是悲催呢，悲催呢，还是悲催呢？ 一切从周日早上说起，说早上女友叫我起床。迷迷糊糊接电话呢，然后（据事后报道）就没声音了……挂了再打无人接听（其实我这边没响），过段时间再打就暂时无法接通了…… 于是十一点我才起来，起来按手机，怎么按怎么不亮 >_< 接在笔记本上，iTunes 表示完全无压力……完全无视…… 于是乎马上准备去修，毕竟不能一直没手机用不是？ 调查好维修流程，发现要修去苹果，要换要在苹果开条去联通换，而且必须在领 iPhone 分别营业厅才行…… 打各种电话时发现，苹果服务就是比联通好（联通也不差……），虽然苹果那个 adviser 是个南方人（香港人？），语言有些障碍，但服务还是很好。 苹果在海淀这边有俩授权维修点，不过还是不放心，预约了晚上八点四十的西单天才吧。 提前好久到了那，人很多，没法提前，逛了逛大悦城，回去又等，八点的时候中午轮到我了。 坐在天才吧里坐了半天，我们的女天才出现了……我说我 iPhone 完全沉默了，她拿过来说试试她能不能帮我，只见她同时按住电源键和 Home 键，白苹果出现了……我……我当时就……我自己按为啥就不行呢？她看到密码框，把手机给我，输完密码我没给她，而是自己试了试，怕她看到我的 Cydia…… 我说我自己按为啥不行……她说很多人都这样说……难道这就是人品…… 接着说蛋疼地排队的时候发现的小事吧。（这才是正题？） 说我在试用 iMac，旁边一个大概初中生年纪的人也在用 iMac，他在人人上玩 flash 游戏，旁边一个穿西服工作人员（穿西服的是保安？天才穿红 T-shirt）的看他不爽，走过去，拿起桌子上的塑料配置单（价目表？）猛敲了一下桌子，那小孩吓跑了，我也吓了一跳。>_]]></description>
			<content:encoded><![CDATA[<p>该说这是悲催呢，悲催呢，还是悲催呢？<br />
一切从周日早上说起，说早上女友叫我起床。迷迷糊糊接电话呢，然后（据事后报道）就没声音了……挂了再打无人接听（其实我这边没响），过段时间再打就暂时无法接通了……<br />
于是十一点我才起来，起来按手机，怎么按怎么不亮 >_< 接在笔记本上，iTunes 表示完全无压力……完全无视……<br />
于是乎马上准备去修，毕竟不能一直没手机用不是？ 调查好维修流程，发现要修去苹果，要换要在苹果开条去联通换，而且必须在领 iPhone<br />
分别营业厅才行…… 打各种电话时发现，苹果服务就是比联通好（联通也不差……），虽然苹果那个 adviser<br />
是个南方人（香港人？），语言有些障碍，但服务还是很好。 苹果在海淀这边有俩授权维修点，不过还是不放心，预约了晚上八点四十的西单天才吧。<br />
提前好久到了那，人很多，没法提前，逛了逛大悦城，回去又等，八点的时候中午轮到我了。 坐在天才吧里坐了半天，我们的女天才出现了……我说我<br />
iPhone 完全沉默了，她拿过来说试试她能不能帮我，只见她同时按住电源键和 Home<br />
键，白苹果出现了……我……我当时就……我自己按为啥就不行呢？她看到密码框，把手机给我，输完密码我没给她，而是自己试了试，怕她看到我的<br />
Cydia…… 我说我自己按为啥不行……她说很多人都这样说……难道这就是人品…… 接着说蛋疼地排队的时候发现的小事吧。（这才是正题？）<br />
说我在试用 iMac，旁边一个大概初中生年纪的人也在用 iMac，他在人人上玩 flash<br />
游戏，旁边一个穿西服工作人员（穿西服的是保安？天才穿红<br />
T-shirt）的看他不爽，走过去，拿起桌子上的塑料配置单（价目表？）猛敲了一下桌子，那小孩吓跑了，我也吓了一跳。>_<<br />
你说这算啥，人家玩个小游戏咋了？算测试 flash 性能行不？你家跟 Adobe<br />
这么紧张人家关心下咋了？有事好好说，吓唬人家干什么，何况旁边的人做错了什么？为啥要被你吓一跳？总之很不爽。<br />
说专卖店里大部分地方都有移动信号，但是最里面的天才吧没有，只有联通信号，故意的吗？ 用 MacBook Pro 的时候突然想用<br />
terminal，手电筒搜索未果，后来发现需要搜索“终端”才行……点开终端，出来一个赤裸裸的密码框……要输密码！不知道还有没有其他程序要输密码……（另外，怎么实现的？）<br />
专卖店里的 iTunes 只能激活 iPhone 不能同步，也算意料之中。 iPod nano<br />
的体验还不错，触摸导航什么都不错，就用了一会，算是第一印象。 天才们的胸卡后面空间挺大，没看错的话是放 iPhone 4<br />
的，看有几个人放着。 店里时常响起警报，似乎是防盗用的，每次响起警报，穿黑衣（西服）的都要去看看，有点吵。<br />
从店里出来之后又在大悦城转了转，买了一对杯具，总不能白来吧……</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.leafduo.com/54/one-day-in-joy-sity/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Apache + Trac + SVN</title>
		<link>http://blog.leafduo.com/05/apache-trac-svn/</link>
		<comments>http://blog.leafduo.com/05/apache-trac-svn/#comments</comments>
		<pubDate>Wed, 01 Dec 2010 09:08:05 +0000</pubDate>
		<dc:creator>Leaf Duo</dc:creator>
				<category><![CDATA[Information Technology]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[SA]]></category>
		<category><![CDATA[svn]]></category>
		<category><![CDATA[trac]]></category>

		<guid isPermaLink="false">http://blog.leafduo.com/?p=249</guid>
		<description><![CDATA[Trac 的安装不难，主要是配置麻烦。 我一开始看的是官方文档，后来看了几份中文文档，用的是 mod_wsgi 的方法，因为之前配过 django，熟悉些。 easy_install 挺好用。 trac-admin /path/to/project initenv 就安装好了。 然后就是各种配置，配置主要是用 trac-admin 命令 conf/trac.ini 两个文件。 trac-admin 里面配置权限， permission add admin TRAC_ADMIN 之类的。 conf/trac.ini 里面要把 default_charest 改成 utf-8，注意最好在建立数据库还没安装 Trac 的时候就把数据库编码改成 UTF-8，我一开始是安装后改的，似乎无效。 Trac 的鉴权完全就是用 Apache……]]></description>
			<content:encoded><![CDATA[<p>Trac 的安装不难，主要是配置麻烦。</p>
<p>我一开始看的是官方文档，后来看了几份中文文档，用的是 mod_wsgi 的方法，因为之前配过 django，熟悉些。</p>
<p>easy_install 挺好用。</p>
<p>trac-admin /path/to/project initenv 就安装好了。</p>
<p>然后就是各种配置，配置主要是用 trac-admin 命令 conf/trac.ini 两个文件。</p>
<p>trac-admin 里面配置权限， permission add admin TRAC_ADMIN 之类的。</p>
<p>conf/trac.ini 里面要把 default_charest 改成 utf-8，注意最好在建立数据库还没安装 Trac 的时候就把数据库编码改成 UTF-8，我一开始是安装后改的，似乎无效。</p>
<p>Trac 的鉴权完全就是用 Apache……</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.leafduo.com/05/apache-trac-svn/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>把 ZY 给我倒过来！──解决德版 G1 ZY倒置问题</title>
		<link>http://blog.leafduo.com/03/remapping-zy-on-g1-de-keyboard/</link>
		<comments>http://blog.leafduo.com/03/remapping-zy-on-g1-de-keyboard/#comments</comments>
		<pubDate>Fri, 20 Aug 2010 02:23:03 +0000</pubDate>
		<dc:creator>Leaf Duo</dc:creator>
				<category><![CDATA[Information Technology]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[G1]]></category>
		<category><![CDATA[keyboard]]></category>
		<category><![CDATA[remap]]></category>

		<guid isPermaLink="false">http://blog.leafduo.com/?p=240</guid>
		<description><![CDATA[我就想不明白了，为什么我刷了一个没写是德版 ROM 的 ROM ZY 也会倒过来呢？难道能辨别机器的硬件？判断我是德版就给倒过来了？唉……自己动手 fix 吧。总不能因为这个就换个 ROM 啊。 唉……会盲打也是错啊，专为会盲打的同学准备： 首先把你的 ROM 的那个 zip 解压，解压出来之后，进到 /system/usr/keylayout 里面，这里面这写文件就是键盘映射的文件了，key 21 就是键盘中上的键，key 44 是键盘左下的键。于是看哪个文件里 key 21 后面是 Z 的，都给我改成 Y；key 44 后面是 Y 的，都给我改成 Z，就 OK 了。查找可以这样： grep &#34;key 44 &#34; ./* &#8230; <a href="http://blog.leafduo.com/03/remapping-zy-on-g1-de-keyboard/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>我就想不明白了，为什么我刷了一个没写是德版 ROM 的 ROM ZY 也会倒过来呢？难道能辨别机器的硬件？判断我是德版就给倒过来了？唉……自己动手 fix 吧。总不能因为这个就换个 ROM 啊。</p>
<p>唉……会盲打也是错啊，专为会盲打的同学准备：</p>
<p>首先把你的 ROM 的那个 zip 解压，解压出来之后，进到 /system/usr/keylayout 里面，这里面这写文件就是键盘映射的文件了，key 21 就是键盘中上的键，key 44 是键盘左下的键。于是看哪个文件里 key 21 后面是 Z 的，都给我改成 Y；key 44 后面是 Y 的，都给我改成 Z，就 OK 了。查找可以这样：</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">grep</span> <span style="color: #ff0000;">&quot;key 44 &quot;</span> .<span style="color: #000000; font-weight: bold;">/*</span>
<span style="color: #c20cb9; font-weight: bold;">grep</span> <span style="color: #ff0000;">&quot;key 21 &quot;</span> .<span style="color: #000000; font-weight: bold;">/*</span></pre></div></div>

<p>替换的话，俺也不会 sed、awk 啥的，就手动来了。反正也不多，我就找到一处。</p>
<p>这样新的键盘映射文件就准备好了，用 USB 线把手机连接在计算机上，拿出 adb：</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">adb remount
adb push trout-keypad-qwertz.kl <span style="color: #000000; font-weight: bold;">/</span>system<span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>keylayout<span style="color: #000000; font-weight: bold;">/</span></pre></div></div>

<p>仿照上面的命令把所有修改过的文件都用 adb push 复制到手机里去。（adb remount 只需要一次）</p>
<p>重启就 OK 了。</p>
<p>没用过 adb 的放狗搜索一下，在 Android 的 SDK 里有。</p>
<p>德版 G1 测试通过，听说德版里程碑 Milestone 也有这问题，应该也有效。</p>
<p>Good luck.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.leafduo.com/03/remapping-zy-on-g1-de-keyboard/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Android 观察</title>
		<link>http://blog.leafduo.com/06/android-review/</link>
		<comments>http://blog.leafduo.com/06/android-review/#comments</comments>
		<pubDate>Fri, 06 Aug 2010 06:32:06 +0000</pubDate>
		<dc:creator>Leaf Duo</dc:creator>
				<category><![CDATA[Information Technology]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[G1]]></category>
		<category><![CDATA[Google]]></category>

		<guid isPermaLink="false">http://blog.leafduo.com/?p=238</guid>
		<description><![CDATA[本文为 “首届 Google 暑期大学生博客分享大赛——2010 Android 篇” 参赛文章。 接着上篇 Android 周年纪念接着说下去： 浪迹 Android 圈也一年了，要说长不长，要说短也不短了……那我就说说一年中自己对 Android 的观察和思考。Android 优秀之处上篇已经说了不少，那我来换个角度评价一下 Android，主要说说不足和问题。 先说说 Android 系统本身的问题。Android 虽然有很多令人兴奋的功能和组件，但是仍然有很多地方做得并不好，而这些地方主要在细节方面。首先是联系人的排序问题，Android 的联系人无法按照中文拼音顺序排序，这可能是由于对中文用户并不重视，（据说）已经支持对日文进行排序了。我看了几篇文章，试着自己实现，发现都不完美，国内的 ROM 可能已经实现这个功能了，我没有尝试。按理说 Android 不应该这么不重视中文用户，毕竟还特别为 Android 做了一款字体。 接着说联系人，无法修改联系人分组的问题实在很纠结，可以选择显示哪个组的联系人，就是不能改分组，难道让我在笔记本上改好吗？Ad-hoc 网络问题，为啥 Android 就不能连接 Ad-hoc 网络？虽然有解决方法，但我觉得这是官方应该提供的。VPN 密码问题，VPN 的密码无法保存，强制的安全性扼杀了用户的便利，扼杀了用户选择的权利。我认为 Google 应当更加注重细节，细节做不好，用户体验做不好，老用户会在长期使用中感到不快，进而影响 Android 的口碑。 &#8230; <a href="http://blog.leafduo.com/06/android-review/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><em>本文为 <a href="http://www.google.com/intl/zh-CN/daxue/blog2010/index.html">“首届 Google 暑期大学生博客分享大赛——2010 Android 篇”</a> 参赛文章。</em></p>
<p><em>接着上篇 <a href="http://blog.leafduo.com/43/android-one-year-anniversary">Android 周年纪念</a>接着说下去：</em></p>
<p>浪迹 Android 圈也一年了，要说长不长，要说短也不短了……那我就说说一年中自己对 Android 的观察和思考。Android 优秀之处<a href="http://blog.leafduo.com/43/android-one-year-anniversary">上篇</a>已经说了不少，那我来换个角度评价一下 Android，主要说说不足和问题。</p>
<p><strong>先说说 <strong>Android 系统本身</strong>的问题。</strong>Android 虽然有很多令人兴奋的功能和组件，但是仍然有很多地方做得并不好，而这些地方主要在细节方面。首先是联系人的排序问题，Android 的联系人无法按照<strong>中文拼音顺序排序</strong>，这可能是由于对中文用户并不重视，（据说）已经支持对日文进行排序了。我看了几篇文章，试着自己实现，发现都不完美，国内的 ROM 可能已经实现这个功能了，我没有尝试。按理说 Android 不应该这么不重视中文用户，毕竟还特别为 Android 做了一款<a href="http://en.wikipedia.org/wiki/Droid_(font)">字体</a>。</p>
<p>接着说联系人，无法修改<strong>联系人分组</strong>的问题实在很纠结，可以选择显示哪个组的联系人，就是不能改分组，难道让我在笔记本上改好吗？<strong>Ad-hoc 网络</strong>问题，为啥 Android 就不能连接 Ad-hoc 网络？虽然有<a href="http://allenss.wordpress.com/2010/02/26/milestone_and_ad-hoc/">解决方法</a>，但我觉得这是官方应该提供的。<strong>VPN 密码</strong>问题，VPN 的密码无法保存，强制的安全性扼杀了用户的便利，扼杀了用户选择的权利。我认为 Google 应当更加注重细节，细节做不好，用户体验做不好，老用户会在长期使用中感到不快，进而影响 Android 的口碑。</p>
<p>这一点或许应当向苹果学习，虽然初代 iPhone 刚刚出来的时候缺少很多功能，但只要是苹果提供的功能，都力求做到最好，缺少的功能在日后补充，而不是发一个半成品出来，这样会让用户很反感。我说一个亲身经历的例子，那时候还是 Android 1.5，我在写一封邮件，得益于 G1 的实体键盘，我很快写了几百字，正当停下思考的时候不小心碰了一下 Discard 按钮，瞬间，几百字灰飞烟灭。遇到这样的事情，用户肯定会感到不快，有的还会跟身边的人说，这样不光是几百字的邮件没了，Android 的口碑也没了。升级到 1.6 之后，Discard 增加了确认，这么简单的功能为什么在 1.5 的时候没有做到呢？1.5 并不是测试版，它是真真正正发布出来给用户使用的，不应当犯这种实习生都不会犯的低级错误。</p>
<p>还有一些是第三方应用的问题，挑一些大家用得比较多的来说吧。先是<strong>人人客户端</strong>，我感觉人人客户端总体来说来算不错，不过有个不能容忍的 bug，在向下划新鲜事的时候，会有上面已经看过的新鲜事出现，应该是算法有问题，还有当进入一篇日志或者相册的时候，返回时可能不在原来的位置，当你翻了很多新鲜事的时候这实在是……还会出现莫名其妙的 FC（force close）。还有 <strong>QQ</strong>，不是很常上 QQ，Android QQ 给人的印象就是非常卡，打字都会卡，可能是因为我的机型比较旧了，但我想一个 IM 软件应该不应该占用很多系统资源。<strong>支付宝</strong>至今不支持横屏，登录过程中切换横竖屏的时候会 FC……<strong>Seesmic</strong> 感觉是个挺漂亮的 twitter 客户端，但是莫名其妙地网络故障让人不得不放弃……随口一说，就有这么多问题。</p>
<p>我认为出现这些问题不光是第三方开发者的问题，Google 作为管理者也应当为 Market 中应用质量普遍不高负责。首先是缺乏准入机制，我没有开发过 Android 应用，但是据观察基本没有无法进入 Market 的应用，完全没有质量的<a href="http://imtx.cn/archives/1449.html">“性感女郎”</a>之类的软件也能进入 Market，<a href="http://article.yeeyan.org/view/105279/113924">多达 144 个垃圾铃声应用和侵犯版权的应用</a>也轻松进入了 Market，严重地影响了 Android 应用的平均质量。iPhone/iPad App Store 的准入制度使得软件作者必须提高他的软件质量，才能进入市场，<a href="http://apple4.us/2010/06/2010-wwdc-wrapup.html">最起码不能频繁崩溃</a>。Google 也对应用的行为缺乏监督，举个例子，一个应用可以无视系统设置的是否允许自动转屏，自己转到横屏或者转回来，甚至这种现象出现在了 Google 自家的应用──自带的 Chrome Lite 中，当用户躺在床上的时候，他们是多么痛恨这些应用。</p>
<p><strong>付费应用</strong>数量过少，只<a href="http://www.techcrunchchina.com/1419">占到 Market 里面应用数量的的 43%</a>，相比之下 iPhone/iPad 仅有 28% 的应用是免费的，75% 都是收费的。作为一个消费者，能够免费用上优质的软件当然是件好事，但是对于大部分软件作者来说，盈利是必须要考虑的事情，免费的软件也就意味着投入更少的精力，结果只能是低劣的质量。或许 AdMob 也是盈利的一个选项，但手机屏幕空间很珍贵，放一个广告很可能会影响用户体验，国内用户对流量也很敏感，而且我个人对通过 AdMob 之类的广告来盈利不是很看好。而且对国内用户来说最重要的是，通过<a href="http://tech.it168.com/a2010/0729/1083/000001083903.shtml">正常方法并不能看到 Market 中的收费应用</a>，开发者也无法发布付费应用，这让 Android 对国内用户和开发者的吸引力骤减。我认为开发者不能赚到的平台是很危险的，无法长期发展下去。</p>
<p><strong>ROM 版本过多</strong>也是一个问题，每个 ROM 版本的功能、质量都不同，Market 中的应用数量和质量也不同，搭载旧版本的手机很难升级到更新版本，这就造成了<a href="http://www.cnetnews.com.cn/2010/0412/1700972.shtml">市场的分裂</a>，使得本来就不大的 Android 市场又变得四分五裂，而现在<a href="http://android-developers.blogspot.com/2010/07/how-to-have-your-cupcake-and-eat-it-too.html">运行着 2.1 以下系统的 Android 手机还有近一半</a>，这些手机无法享受到高版本 ROM 中的新功能和新的第三方应用，不能不说是个遗憾。不过还好，据说 Google 已经开始着手解决这个问题了（没找到链接，抱歉）。</p>
<p><strong>多媒体</strong>应用薄弱则是另一个问题，自带的 Music 实在是无法使用，音乐的管理乱到遭，管理播放列表十分麻烦，而第三方应用也没有非常出色的，缺少一个类似 iTunes 的软件来管理，创新工场推出了一个<a href="http://wandoujia.com/">豌豆荚</a>，据称不错，不过目前只有 Windows 版本，所以我没有试用。</p>
<p>最后说一说国内的特殊问题（中国特色问题？），首先是 Google 这个牌子的问题，由于<a href="http://www.google.com/press/new-approach-to-china/update.html">种种原因</a>，Google 这个牌子并不像它在美国或者世界上其他国家那样响亮了，其次还有国内特殊的情况，比如用户素质、企业文化、政策因素等等，这些引发了很多问题。其一是<a href="http://cn.engadget.com/2010/03/26/android-google-china-unicom-no-search-on-android/">很多国内的 Android 手机不选择 Google 作为搜索引擎</a>，有的甚至<a href="http://mm.10086.cn/">阉割掉了 Market 换上自己的市场</a>，我想这是 Google 不愿意看到的，也是大部分用户不愿意看到的。还有一个更严重的问题，<a href="http://tinkpad.wuyan.org/2010/01/06/android-market/">在某些地方 Market 的服务器会神奇地无法连接</a>，无法安装新应用，也无法更新，这对于 Android 用户来说无疑是致命的打击。我认为，对于某些行为明显不妥的企业，Google 应当加强监管，放出一些限制条款，不能纵容这种行为，赤裸裸的分裂长期来看对于整个社区、整个 Android 生态环境都不是好事，而对于某些神奇的问题，Google 应当加强公关能力，让这些地方的用户也用上优质的服务。</p>
<p>总体来说，Android 做得最好的就是与 Google 服务的紧密结合，最需要改进的是对 Market 的监管和第三方应用的质量。</p>
<p><a href="http://cn.engadget.com/2010/07/28/pour-one-out-t-mobile-g1-no-longer-for-sale/">作为 Android 元老的 G1 已经离我们远去了</a>，但是 Android 平台还会继续走下去，愿 Android 越走越好。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.leafduo.com/06/android-review/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Android 周年纪念</title>
		<link>http://blog.leafduo.com/43/android-one-year-anniversary/</link>
		<comments>http://blog.leafduo.com/43/android-one-year-anniversary/#comments</comments>
		<pubDate>Fri, 06 Aug 2010 06:30:43 +0000</pubDate>
		<dc:creator>Leaf Duo</dc:creator>
				<category><![CDATA[Information Technology]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[G1]]></category>
		<category><![CDATA[Google]]></category>

		<guid isPermaLink="false">http://blog.leafduo.com/?p=236</guid>
		<description><![CDATA[本文为 “首届 Google 暑期大学生博客分享大赛——2010 Android 篇” 参赛文章。 本来只想写一篇来着，写着写着就有六千多字了，于是分成两篇，这是第一篇，更多的以入门用户的眼光推荐 Android，下一篇 Android 观察，更多的讲述 Android 的不足和改进。下面进入正题： 一年前的暑假，我买了自己的第一只智能手机──HTC Dream，也就是俗称的 G1（其实也不是俗称……）。528 MHz CPU，256 MB ROM，192 MB RAM，Android 1.5，QWERT 键盘，在今天看来已经是老古董的配置了，不过在当年还是相当惊艳的，再加上只有两千冒头的售价，在各路神仙中让我选择了 HTC Dream。 Android 初体验 Android 1.5，对于我这个以前用着非智能机的人来说带来的是惊喜，让我精力了很多很多 “啊，我就需要这个” 的时刻。 比如说与 Google 服务的紧密结合，我是一个 Google 服务的重度使用者，每天都有不少邮件需要处理，然而不是每封邮件都需要打开笔记本去处理的，很多时候只是回一句话而已，还有许多时候仅仅是定期发来的 Newsletter，只需要看看就可以，这时候，手机的便携性就体现出来了，整合的 Gmail 虽然（据说）不是推送邮件，但是往往能在几分钟内刷新到邮件，比较紧急的邮件也不会错过了。 &#8230; <a href="http://blog.leafduo.com/43/android-one-year-anniversary/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><em>本文为 <a href="http://www.google.com/intl/zh-CN/daxue/blog2010/index.html">“首届 Google 暑期大学生博客分享大赛——2010 Android 篇”</a> 参赛文章。</em></p>
<p><em>本来只想写一篇来着，写着写着就有六千多字了，于是分成两篇，这是第一篇，更多的以入门用户的眼光推荐 Android，<a href="http://blog.leafduo.com/06/android-review">下一篇 Android 观察</a>，更多的讲述 Android 的不足和改进。下面进入正题：</em></p>
<p>一年前的暑假，我买了自己的第一只智能手机──<a href="http://www.htc.com/www/product/dream/overview.html">HTC Dream</a>，也就是俗称的 G1（其实也不是俗称……）。528 MHz CPU，256 MB ROM，192 MB RAM，Android 1.5，QWERT 键盘，在今天看来已经是老古董的配置了，不过在当年还是相当惊艳的，再加上只有两千冒头的售价，在各路神仙中让我选择了 HTC Dream。</p>
<h2>Android 初体验</h2>
<p>Android 1.5，对于我这个以前用着非智能机的人来说带来的是惊喜，让我精力了很多很多 “啊，我就需要这个” 的时刻。</p>
<p>比如说与 Google 服务的紧密结合，我是一个 Google 服务的重度使用者，每天都有不少<strong>邮件</strong>需要处理，然而不是每封邮件都需要打开笔记本去处理的，很多时候只是回一句话而已，还有许多时候仅仅是定期发来的 Newsletter，只需要看看就可以，这时候，手机的便携性就体现出来了，整合的 Gmail 虽然（据说）不是推送邮件，但是往往能在几分钟内刷新到邮件，比较紧急的邮件也不会错过了。</p>
<p>除了 Gmail 的同步，还有<strong>联系人的同步</strong>。刚刚换手机的时候，把联系人弄到新手机上是个比较麻烦的事情，很多同学花了半天自己手动输入了一遍，不仅麻烦无聊，而且超大量的数字，难免会发生输入错误，等到要找人的时候再着急就晚了。幸好有联系人同步，原来的手机支持 <a href="http://zh.wikipedia.org/wiki/SyncML">SyncML</a>，先用 SyncML 通过 <a href="http://www.google.com/mobile/sync/">Google Sync</a> 同步到 Gmail 的联系人上，然后再同步到 G1 上就 OK 了。再有就是要改很多联系人的时候，手机上改毕竟不太方便，在笔记本上改好之后同步过来很方便。</p>
<p><strong>Google Maps</strong> 也是个很强大的应用，在茫茫北京，俺一个外乡人，要不迷路并且安全到达目的地是一项多么困难的任务……不过有了 GPS 和 Google Maps，这工作就简单多了，GPS 定好自己的位置，搜索好目的地，剩下的就交给 Google Maps 吧，当然，路还是要自己走的，车钱还是要自己付的，这个 Google Maps 管不了……出门不问路，哈哈哈哈。</p>
<h2>杀手/必备应用推荐</h2>
<p>看完了 Google 自家的应用，来看看优秀的第三方应用推荐。</p>
<p>首先隆重推出的是 <strong><a href="http://code.google.com/p/android-sms/">SMS Backup</a></strong>，这个程序能将你的短信自动备份到 Gmail 并添加标签，每次刷 ROM 之后，它都是我安装的第一个软件，从此以后，再也不怕短信丢了。安装好，备份一次之后就不用管它了，让它自己默默地工作吧。</p>
<p>下一个当然是 <strong><a href="http://www.handcent.com/">Handcent SMS</a></strong>，1.6 自带的短信程序感觉不是很好用，于是就用上了第三方的短信程序。要说为啥非要用第三方的，是因为自带的短信程序在短信多了之后非常卡，打开一条短信都要半天，无奈，只好换掉了，Handcent SMS 会自动隐藏旧的短信，就不会卡了。Handcent SMS 比起自带的 Messaging 来强大得多，有可以显示未读短信数的 Widget，可以自定义某个联系人来短信的通知，于是就可以通过 LED 的颜色和通知图标知道是谁发的短信了。Handcent SMS 还有一个抢眼的功能就是能自定义振动的样式，在 Android 手机越来越多的今天，分辨自己手机的振动越来越难了……有了 Handcent SMS，就不怕认错震动声音了。</p>
<p>下一个是 <strong>ClockSync</strong>，对于我等对时间有着变态追求的人来说，这款能自动通过 NTP 对时的应用怎么能不装呢？有了它，再也不怕约会迟到了（误）……（对时需要 root）</p>
<p>再来个 <strong><a href="https://www.dropbox.com/">Dropbox</a></strong>，当红网络文件同步服务推出的官方客户端，之前那个不知道谁出的劣质客户端退散吧。</p>
<p>继 Google Maps 之后，路痴的福音又来了，<strong>Compass</strong>。就像名字所说的一样，仅仅是个指南针，不过在你迷失方向的时候就有大用处了……记得方向指示不准的时候请在空中画 8 字校对方向，每次画 8 字我都觉得很有喜感。</p>
<p><strong>GPS Status</strong>，能看到当前的 GPS 状态，包括有多少颗卫星可见，经纬度、海拔、速度等。我喜欢坐在车上开着 GPS Status，看看车子有多快，动车上也试过，真的有 300+ km/h……</p>
<p>祭出网购用户必装的利器──支付宝，我等非 Windows 用户的福音，选好商品，手机支付即可（支付宝啊，你还是快点去掉什么“安全”控件吧……）随时充话费也是支付宝必装的理由。</p>
<p>说了不少 Android 系统相关的心得和推荐，大家有什么心得或者想要交流的尽情留言吧，好了，不多说，我们进入下一部分──<a href="http://blog.leafduo.com/06/android-review">Android 观察</a>。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.leafduo.com/43/android-one-year-anniversary/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>C Traps &amp; Tips II -- Digraphs and Trigraphs</title>
		<link>http://blog.leafduo.com/50/c-traps-tips-ii-digraphs-and-trigraphs/</link>
		<comments>http://blog.leafduo.com/50/c-traps-tips-ii-digraphs-and-trigraphs/#comments</comments>
		<pubDate>Tue, 27 Jul 2010 13:21:50 +0000</pubDate>
		<dc:creator>Leaf Duo</dc:creator>
				<category><![CDATA[Information Technology]]></category>
		<category><![CDATA[C++]]></category>

		<guid isPermaLink="false">http://blog.leafduo.com/?p=232</guid>
		<description><![CDATA[今天写个第二遍吧，这篇有点×疼，大家见谅。 先看代码： 1 2 3 4 5 6 7 #include &#60;stdio.h&#62; &#160; int main&#40;&#41; &#123; printf&#40;&#34;%s&#34;, &#34;What's this??!\n&#34;&#41;; return 0; &#125; 1 2 3 4 5 6 7 int main&#40;&#41; &#123; int a = 0; //What's a's value??????????????/ a++; return &#8230; <a href="http://blog.leafduo.com/50/c-traps-tips-ii-digraphs-and-trigraphs/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>今天写个第二遍吧，这篇有点×疼，大家见谅。</p>
<p>先看代码：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><pre class="c" style="font-family:monospace;"><span style="color: #339933;">#include &lt;stdio.h&gt;</span>
&nbsp;
<span style="color: #993333;">int</span> main<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    <span style="color: #000066;">printf</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;%s&quot;</span><span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;What's this??!<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">int</span> main<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
  <span style="color: #993333;">int</span> a <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
  <span style="color: #666666; font-style: italic;">//What's a's value??????????????/</span>
  a<span style="color: #339933;">++;</span>
  <span style="color: #b1b100;">return</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>想想上面两段代码吧……</p>
<p>好了，答案在这里，在符合 C99 的编译器里，第一段输出 What's this|，第二段 a 的值还是零。为什么这样呢，因为 C99 增加了一个叫 trigraph 的特性，也就是三元组。由于某些键盘上无法输入某些字符，所以就定义三个字符来替代那一个字符，比如 ??! 会转换成 |，??/ 会转换成 \，也就是说 a++ 也成了注释的一部分，（三元组都是两个问号开头的），而且无论是在字符串中还是注释中都会被替换（在预处理器中进行替换，不论在代码的哪里出现都会被替换）。这样就能解释上面两段代码的输出了。想要避免这个问题可以将 ? 进行转义（写成 \?），或者把字符串拆开（写成 "?""?""!"）。</p>
<p>还有一种叫做 digraph，二元组，也就是用两个字符来表示一个字符。与三元组不同的是，二元组被当成一个独立的 token 来解释，在预处理器进行词法分析的时候被替换，也就是说，在字符串中和包括在其他 token 中的二元组不会被替换掉，这样就不会造成像三元组那样诡异的问题了。</p>
<p>为啥说这篇×疼的，是因为 GCC 默认不开启三元组的支持（M$ 的编译器不清楚）……想要开启需要在编译时指定 -std 或者 -trigraphs，没有这两个编译选项的时候出现三元组不会发生替换，编译时会有警告。</p>
<p>我觉得这东西平时没啥用，不要误用了就好。</p>
<p>References：</p>
<ul>
<li><a href="http://en.wikipedia.org/wiki/Digraphs_and_trigraphs">http://en.wikipedia.org/wiki/Digraphs_and_trigraphs</a>
</li>
<li><a href="http://gcc.gnu.org/onlinedocs/cpp/Initial-processing.html">http://gcc.gnu.org/onlinedocs/cpp/Initial-processing.html</a>
</li>
<li><a href="http://gcc.gnu.org/onlinedocs/cpp/Tokenization.html">http://gcc.gnu.org/onlinedocs/cpp/Tokenization.html</a>
</li>
<li><a href="http://stackoverflow.com/questions/1995113/strangest-language-feature/1995134#1995134">http://stackoverflow.com/questions/1995113/strangest-language-feature/1995134#1995134</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.leafduo.com/50/c-traps-tips-ii-digraphs-and-trigraphs/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic page generated in 1.053 seconds. -->
<!-- Cached page generated by WP-Super-Cache on 2012-11-05 00:35:01 -->
