重构我的blog

代码重构(Code Refactoring)是一个编程的术语:在保留原有的功能的情况下改变计算机程序代码让其容易被修改为适应变化、增加可读性或者简化结构。这个实践对于产生高质量程序非常重要,而且这种想法不仅限于编程概念,也完全可以用在生活上。我的blog里面也会经常用到这个词(重构我人生),所以今天我决定就把生活的记录工具blog给重构一下

对于程序员朋友,这里插播一个问题,我发现中文的wikipedia对于代码重构(Code Refactoring)的定义非常的不准确,摘抄如下:

代码重构指对软件代码做任何更动以增加可读性或者简化结构而不影响输出结果。软件重构需要借助工具完成,重构工具能够修改代码同时修改所有引用该代码的地方。在极限编程的方法学中,重构需要单元测试来支持。

为什么呢?因为martin folwer使用的定义和英文wikipedia这个一致:

Code refactoring is the process of changing a computer program’s code to make it amenable to change, improve its readability, or simplify its structure, while preserving its existing functionality.

中文解释里面所说的重构需要借助工具完成支持纯属放屁。而且遗忘了重构的一个目的是为了让代码易于维护那么就没有说明重构的经济意义。所以,大家看看我上面那个翻译如何?一起修改一下我去修改一下wikipedia的条目。

回到我要说的blog重构的话题。我现在的blog使用的是Wordpress,但是再往前推我还在Live SpaceBlogJava写Blog。但是那个时候没有使用Tag来管理blog post,所以都使用了很复杂的分类(Directory),再后来我把Live Space的blog通过MSN Space mover迁移到了现在你阅读的这里,所以那些目录也就都被迁移过来了。

所以多分类Category是我第一个要重构的地方。原因在于分类最早的设计是一个严格的树形结构,也就是分类是一个逐级缩小范围的概念,它适合于自上而下的查找。比较常见的就是传统电子商务网站的目录和网站的树形导航。但是这两年大家发现很多人的阅读习惯并不是这样的,尤其对于blog这样的形式。blog我们分成两种场景来分析分类的使用:

  • 搜索引擎或者链接:这种情况下用户是偶然看到了一篇他感兴趣的文章,那么他下一步会查找相关的主题,这个时候分类会是他第一个寻找的。但是,很少有用户会在乎分类的树形结构,而是对哪个具体的话题感兴趣就点进去。所以最好的方式就是话题和分类一一对应。如果你的blog的话题太多了,那么你一定不会注意到你的分类也太多了,这些噪音会影响用户探索你的blog。所以人们发明了Tag,也就是一个简短的关键词来定义你的一些话题,每个post还可以打多个标签,这个也方便了你自己,不用在给文章分类的时候抓耳挠腮。然后人们使用Tag Cloud这种方式突出你的blog的最重要的关键词(也就是统计使用频率最高的Tag配以较大的字体),它也帮助你了解自己写blog的习惯。那么对于这种场景,Tag Cloud是比Multi-Category(单篇文章多目录)更好的详细管理主题方式。
  • 订阅:平常我们在使用工具订阅blog的feeds的时候我们一般都是按照这个时间序列来阅读,我们会忽略不感兴趣的feed,然后阅读感兴趣的,那么订阅的feeds需要满足这种习惯。不过最常见的订阅方式是订阅全部,这种方式有的时候不太好。比如我们公司有个员工blog聚合服务,我没有加进去,因为我的blog有很多生活的内容,别人肯定并不想阅读那些部分。也就是说不区分主题的feeds输出会让人看到很多不感兴趣的主题。如果你使用了Tag Cloud,它可以区分主题,但是它太多了,没有人会逐个Tag Cloud订阅你的blog,人们希望有一种稍微粗略一些的方式来订阅。我发现的一种最好实践就是按工作/生活的主题区分,对于技术人员也常见技术/非技术的分开,这种分法很粗放,但是却很有效。因为如果我是生活上的朋友我就会关注你非技术的post,而相反如果我是你的同事或者社区里面的朋友,那么我会关心你的话题。所以,这种场景下的一个最佳实践就是让你的blog的分类尽量的简单,2-5个我觉得就可以了。

啰嗦了半天,其实行动很简单。我需要把现在复杂的Category转换为Tags,还有添加新的简单分类“Tech.技术”和“NoneTech.非技术”。在Wordpress里面这个很简单,因为在wordpress里面Tag和Category实际上是同样的东西,但支持不同的显示方式。在wordpress的后台的Manage->Categories下面有一个category to tag converter的链接进去选择你想要转换的Category然后转换一下就OK了。一个简单的操作以后这些Category就都不见了。那么所有的文章就都跑到Uncategoires下面了。我好需要重新做一下分类,这是个体力活……不过我使用了Wordpress的客户端来实现。

那么下一步就是重构blog的下一个话题,选择一个客户端工具来更新你的blog。我试用了ecto和MarsEdit,它们是mac下两个有名的blog客户端,它们对blog的管理功能都差不多,但是编辑方式不一样,其中ecto的编辑器是所见即所得的,而MarsEdit是一个直接写HTML源码然后预览的界面。我对HTML烂熟,所以用MarsEdit没有困难。大家可以根据自己的需求选择,它们都是需要交注册费的。试用客户端的好处就是不用忍受浏览器的崩溃,不用忍受网络闪断造成的提交失败,不用因为写post时间太久而session过期,可以方便的存在本地,可以在离线的方式下修改/添加blog post,这些功能可以帮助你频繁的写blog,而不是每次都需要准备很久来登陆->新建post。我其实已经试用了几天Ecto了,比较满意,但是Ecto的试用版不能选择取回条目的数量(不知道注册以后是否可以?),所以对于修改分类这样的任务来说MarsEdit才可以修改我全部的项目。

在整理blog post的时候,我发现我这里有很多以前留下的Twitter聚合内容,我把它们都删掉了。以前我曾经想把micro blogging(微博客)的内容也放到blog里面,可是我发现有了FriendsFeed这样的工具以后我就不需要用blog来聚合了,这样是一种明显的Bad smell-重复。冰云同学批评过我聚合Twitter,他说的很对,现在我本人也很反感聚合Twitter,有这种行为的人的blog一律退订。

上面说的这些就是今天重构的实践,之前我还做过几个实践:保持只有一个blog服务(不需要同时使用Space和blogjava),如果不满意BSP(Blog service provider),那就自己买空间架一个Wordpress。定时备份你的Blog,并且最好有工具让你的blog可以转移成中立的源文件(如SQL、XML),方便以后迁移,选择BSP也可以以这个为标准。

最后总结一下我提到的重构blog的几个实践:

  • 将复杂的Category转换为Tag,删除多余的Category,使用简单的Category,2-5个为好
  • 使用一个Blog客户端,事半功倍
  • 停止使用Twitter和Google Reader聚合生成blog post的功能,如果需要可以把它们放到你的blog的sidebar上,而不要生成到feeds里面

如果以后还有其它重构行为我还会更新这个post。今天已经好累了 -。。-

工具-不会用不丢人,怕会用才丢人

工具就是进行生产劳动时所使用的器具。工具的目的在于提高生产劳动的效率。感慨于一些真正的Geek的blog,我也想了一些工具对于我的重要意义,用来作为下一段的目标。

人家说工欲善其事必先利其器,还有磨刀不误砍柴工,实际上在说明工具对提高工作效率真的非常有意义。

今年的我,上游离于前端开发和后端开发之间,同时我还要在两个不同的团队(ThoughtWorks StudioCruiseMingle两个产品开发团队)之间切换,所以对于我来说频繁的需要Context Switch(工作环境切换)。两个团队所使用的技术也不同。

  • Cruise是一个标准的Java团队,大家的开发工作站都是Ubuntu环境,IDE是Intellij IDEA,源代码控制是Mercurial(aka. HG),自动化构建脚本基于Ant,持续集成工具就是自己开发的Cruise。
  • Mingle团队是标准的JRuby on Rails团队,大家开发机器是Macbook pro或者Mac mini,编辑器是TextMate(JRuby部分有IntelliJ IDEA的工程),源代码控制是Git,自动化构建脚本基于Rake,持续集成工具有两个,其中提交前使用的precommit CI是基于我们公司的开源产品CruiseControl.rb,而主持续集成服务器是基于Cruise(也就是前面那个团队的产品)。
  • 两个团队所使用的敏捷环境是Mingle,用过Mingle的朋友知道,这个NB的工具的可配置性很高,这两个团队的Mingle项目模板区别很大。
  • 这两个环境的区别还是相当大的,而且每次我切换了团队(大约2个月的周期),我很有可能就需要很大的更新我的Macbook pro上面的各种库。
  • 当我做前端开发的时候,我还要切换与我的Mac上的Photoshop CS3和Mac的VMWare Fusion上的Fireworks中(使用Windows的Fireworks的原因是授权,我的正版授权是Windows的)。使用Fireworks的原因是我们的设计师使用它,所以我需要使用它来调整一些小的设计。
  • 在做Javascript逻辑的部分,我需要在Firefox 3/2、Safari 3、IE6/7(VMWare Fusion)之间切换,每个浏览器都有不同的附加调试工具(主要的三个Firebug、Inspector、IE Dev toolbar)。

我想对于一个强悍的程序员(最近比较崇拜的delphijhdcola云风等神人)来说做这样的环境切换也许还是可以的。可是对于我这个不善于multi-task工作的人来说,马上让脑子适应不同环境,熟练使用不同的工具就成为了一个挑战。

所以,结果是,这一年中,我基本上对于这些工具很少深入学习,基本上就是凑合着使用,如果没有通用的快捷键我就懒得去翻手册学习了。结果就是使用HG的queue功能(超级有用的qnew、qrm、qpop、qpush系列)的时候经常把自己搞崩溃(今年居然有和李彦辉教授在pair的时候搞丢了2个小时内的修改,相当丢人),所以后来在使用HG的时候异常小心,生活在心理阴影下面。而对于Git,我居然完全没有使用过stash功能(和HG的queue类似)。昨天胡凯还问我是否用过bisect,是一个折半查找坏提交的功能(在HG和Git里面有等价的功能),我完全没有使用过。因为这些精巧的基于命令行的源代码控制工具对于程序员来说非常之重要,从这个角度体现了我对于工具的不求甚解达到了什么程度。突然想到梅兰芳里面十三燕那个很棒的台词“输不丢人,怕才丢人”,用不好工具没事,但是害怕学习用工具那就是很丢人的问题了。

那么自我分析的结果就是,由于环境切换,我缺少了专注,形成了对学习环境中的工具的恐惧,最后影响了我的工作效率。

下面的内容用来自勉,分析一下工具对于我到底有多么的重要(也就是说这个是我使用和学习工具中比较Happy的部分)。对于还没有注意到工具重要性的朋友,可以关注一下,看看是否有所借鉴。

  1. 关于GTD:去年看了不少退墨的文章,我深感这种意为减轻压力的“Todo list“对我的重要。最早我使用了文本文件来记录,每天一个文件。但是后来发现跨天完成的任务使用这种方式不好,需要手工拷贝。所以后来按照每个Context(家、单位、电脑、手机…)放一个文件,然后使用日期作为风格,跨天的任务我就拷贝一下,这个文件本身放在EverNote里面实现多平台共享。但是后来我发现这样也不好,因为不明显,也不好做计划。再后来我开始使用iGTD,发现似乎不错,它的结构比较简单,而且它分开了context和project两个概念,所以像“OpenParty、Mingle、Cruise、梦想”也有了自己的归宿。GTD的做法,please google之。
  2. 关于工作和休息的切换:一开始我惊艳于Livid修改过的TimeOut这个软件,但是它运行的经常很慢。后来我使用了原版的AntiRSI这个抗劳损软件,它的原理就是根据你设定的时间提醒你做短休息(一般是15分钟,站起来休息30秒),还有长休息(一般是45分钟,站起来休息5分钟)。再做结对编程的时候弹出它可能你的pair会有意见,但是你需要通过它的实际效果来感动他们。结果是Mingle的队友已经基本上都在使用它了。
  3. 分布式版本控制工具:DVCS可以帮助你更好的管理本地分支,让分支变得轻量,而且它还可以帮助较大的分布式团队更好的管理自己的本地主干。而且他们里面还有很多帮你管理提交习惯的工具,比如前面提到的提交队列工具,可以鼓励你使用更加频繁的本地提交。当然使用分布式版本控制工具的前提就是你要仔细阅读一下hand book,学习一下他们的基本概念和原理,这样才能达到更好的效果。
  4. Feeds工具:我使用Google Reader阅读文字型RSS Feeds,使用iTunes订阅Podcast。
    • 阅读工具多了去了,你的选择很多。但是要做的是学会更好的使用这些工具。今年从Patrik lightbody那里学会了重构Rss Feed订阅的重要性,要减少一个feed使用多个tag进行管理,因为一般鼓励在一定时间段里面保持未读feed不要积攒太多(这就失去了持续阅读的能力),但是如果使用多个Tag标记feed,那么在统计未读条目的时候往往会重复统计,会造成很大的阅读压力,而且对于给自己的不同feed组定不同的优先级也不利。
    • 所以我首先做的是将所有的订阅单一化,分类清晰了很多。分类有一个小技巧,不要对个人博客按照主题打标签,比如以前我给robbin的博客打上java的标签,而livid打上了apple的标签,那么在我决定要看哪个标签下的主题的时候就会感觉很迷惑,因为个人博客都没有固定主题,所以这些标签就编程没有意义的误导了,所以我现在对于这类feed直接标记为“Interesting Person(有意思的人)”,我可以给这些人很高的优先级。
    • 另一类是如GizmodoLifehacker这种信息门户型,他们每天要更新50+的新条目,所以我把他们放到一个单独的如news portal这样的分类里面,我可以给他们很低的阅读优先级。
    • 不同优先级的条目在Google reader里面还可以对应列表/展开的方式查看,可以很好的提高使用效率。再有就是Google Reader的快捷键,在吃午饭的时候,右手用来吃饭,左手可以通过一个空格健来实现滚动和查看下一条,s是标星,Shift+S是共享,这个基本上就可以实现单手阅读了,很方便。
    • Podcast是坐地铁上班时很重要的学习工具:因为地铁和很多交通工具非常拥挤,即使带上书也没有空间看(尤其时备上电脑上班的我们)。所以在非常拥挤的时候我会选择听音频的Podcast,如锵锵三人行(了解时事)开卷八分钟(了解好书,不过越来越没意思了)、Ruby on Rails Podcast(Rails的)、RailsEnvyTackSharpJDD主讲的关于摄影)等等。在不是那么拥挤,也就是胸前有10厘米以上空间的时候,我会选择看视频Podcast,最精彩的是TED Talks的演讲,不错的有Apple Quick TipsX-Play Game Previews等。用这种方式消磨时间比用PSP好很多。这是一个购买iPod touch 2的理由^__^
  5. 信息分享服务:这个又是一个很大的话题。大家在聊天的时候经常感觉很有收获,原因是兴趣相投的人在互通有无可以带来很多的有用信息,而不是像电视的新闻节目或者报纸那样给你带来没有针对性的噪音。社会化网络SNS实际上是个很好的分享有用信息的平台,可是我不是很喜欢facebook等给我带来的参与压力,所以我一般通过一些通用的分享服务来满足自己的需求。
    • 我一般通过Last.fm来实现音乐播放历史的跟踪,通过它的推荐服务来发现一些我喜欢的音乐。这实际是一个相关度算法的应用场景,它不同于简单的试听型的网站(现在国内的xiami.comkedou.com我觉得基本上属于这种类型),它的目的不是给你知道的音乐听,而是根据你听过的音乐推荐你一些音乐听,收集音乐品味的过程叫scrobbler,我在使用iTunes放音乐以后会被自动同步到last.fm并用来做数据挖掘。使用Last.fm服务需要注意的就是要及时更正你的mp3-tag信息,这样你提交的数据就不会是垃圾,这对未来享用推荐服务非常重要。但是现在我发现的一个问题是,由于中文有简体和繁体,所以很和多时候Last.fm的亚洲歌手的名字都会出现多个版本,这给推荐带来了难度,也许国内的服务上可以帮我们解决这个问题吧。使用iTunes的朋友可能苦恼于mp3-tag信息乱码,那么使用Glider开发的ID3Mod2这个软件。
    • 看电影和看书通过豆瓣就很爽了,我对它使用的很初级,但是豆单等已经聚合过的相关分组已经可以给我看电影很多启发了。使用豆瓣这样的工具我们要做的就是尽量及时的更新你的阅读列表,这样豆瓣得到你的更多数据,那么推荐也会更加准确。
    • 我非常珍惜Google Reader的share功能,尤其是share with note。因为这个几乎是最好的和靠谱的朋友分享信息的手段,我一直认为这个是最好的一个人肉过滤器,你的朋友圈子越准确,得到的share也就更符合你的品味。自己在share的同时,可以看到你的share的朋友就和你做了非面对面的交流。而且有的时候如果你1个月没有读feed,已经无从看起的时候,完全可以把他们置为已读,然后去看朋友的分享。这减少了很多信息过滤的成本。
    • 最后一个重要的分享服务就是Twitter了。Twitter解决了你不能和所有的你想交朋友的人聊天的缺憾,这样你可以轻松的follow业界大牛,如d2hkent beck等。它也是一些重要信息的最快速发布场所,同时也是一个重要的社交场所。在使用Twitter以后我发现我甚至越来越少的在使用IM软件了。使用Twitter这个工具你需要做的就是有节奏的发信息,而不是三天打鱼两天晒网,这样大家不会因为你太贫而退订你,也不会因为常年见不到你的twitt而忘记你。
  6. 信息存储服务:网上看到好东西我们经常想收藏,这种行为叫做网摘,最早我使用CyberArticle(荣幸的买了正版,用的很High),而后用了Linux,所以改用Scrapbook,作为firefox的插件它是跨平台的。此时我的同时推荐我使用在线的Google记事本,这几个软件都能很好的做网摘。但是这几个软件的缺点是缺少协作,那么后来最常见的就是社会化书签应用,delicious,在浏览器装个插件以后它可以帮你用tag管理书签,好处是还顺便帮你做推荐服务,很方便。后来我发现并非只有这些数据需要存储,我们还需要网络磁盘服务,这类服务很多,我个人倾向于使用Dropbox,它的好处是各个平台都有客户端(Win、Mac、Linux),而且是用户空间磁盘系统,用起来和本地磁盘一样,它同样可以用来在项目组之间共享一些文档、电子书等。最后,我还推荐一个类似M$的OneNote的免费在线文档、及数据存储服务EverNote,我用它来存储一些简单的文本文档,还有用它写一些视频note,因为它有一些方便的工具帮你来做音频或者视频的记录。(对了,还有梦断代码里面描述的难产的软件Chandler,它是一个本地的数据中心软件)
  7. 快速启动服务:就是使用键盘快捷索引的启动工具,有代表性的是QuickSilver(是Mac下的,详情看Robbinlu的这篇blog),它显然比Mac自己的Spotlight好用(而它又比win下的很多桌面搜索强很多很多)。通过培养这样的软件可以帮你极大的提高效率。Windows下有launchy也很不错。
  8. 还有很多,但是我没有必要一次全部说完……

下面要分析一下我做的不好的地方,迎来跟踪我的改进:

  • 没有认真的学习Git和HG的用法,没有很好的贯彻他们的最佳实践。
  • 没有很好的学习shell。很少给自己写脚本来提高每天工作的效率。对很多*nix命令还很不了解,如wc、du……,对于微语言awk等不了解,这就限制了我制造自己的组合工具的能力。
  • 没有学习如何使用Mac的automator和appleScript。
  • 对于C语言的了解太初级,还是大学上课的水平,而它又是读懂很多code的关键(我并不想成为c程序员)。
  • 没有很好的整理好自己在各个网站的帐号。所以经常忘记去使用这些服务。
  • 没有很好的整理自己家的硬盘,没有对里面的电影和音乐进行过删减。因为数据也会过期,如果总是舍不得那么它们都被积累为工作噪音。所以要勇于与过去告别。
  • 没有好好学习Photoshop和Fireworks的使用,总是在使用低效的重复劳动。
  • 没有管理好自己的博客。我今年做了的事情就是把blog从BlogJavaLive Space移动到了朋友的机器上的wordpress上,但是由于访问速度比较慢,而且离线的时候写东西不方便,我今年也很少写blog post。
  • 没有学会使用一个有效的照片库软件,iPhoto的分库功能我最近才知道,不过没有认真整理(要减少单个iPhoto Lib的大小,这算个最佳实践)。我也应该学会使用一个LightRoom或者Apeture那样的面向摄影的后期软件。
  • 没有学会使用图片分享服务,我游离于flickr、picasa web和好看簿之间,前两者现在都有了iPhoto客户端,但是我还没有很好的使用。在9的内容做好后,我要更好的利用图片分享服务。
  • 没有很好的学习Ruby on rails,虽然一开始仔细阅读并且也用1.0的rails写了些小应用,但是我的知识没有及时更新。
  • 没有很好的清理自己的数据遗迹,我这个人很注意备份,但是没有注意清理过期的备份,想个好的工具来解决它,如TimeMachine。
  • 没有使用好Facebook和Linkedin这两种SNS,它们实际上能够帮助我很多
  • 没有利用好我买的图书,书是学习工具,而不是收藏品,我没能很好的阅读它们。

暂时先准备写到这里,其它的关于工具的话题我会另开post来总结。(最后更新于2008年12越21日)

[转载]Ruby的并发的一些基本限制

因为是feedburner的feeds,所以我就转过来。

Concurrency is a Myth in Ruby


Concurrency introduces parallelism into our applications, and threading is, of course, one way to achieve concurrency. But it turns out that in Ruby, this relation is not transitive: execution parallelism is not the same thing as threading. In fact, if you’re looking for parallelism in your Ruby application, you should be looking at process parallelism instead. So why is that?

Ruby under the covers: Global Interpreter Lock

To understand what’s going on, we need to take a closer look at the Ruby runtime. Whenever you launch a Ruby application, an instance of a Ruby interpreter is launched to parse your code, build an AST tree, and then execute the application you’ve requested – thankfully, all of this is transparent to the user. However, as part of this runtime, the interpreter also instantiates an instance of a Global Interpreter Lock (or more affectionately known as GIL), which is the culprit of our lack of concurrency:

Global Interpreter Lock is a mutual exclusion lock held by a programming language interpreter thread to avoid sharing code that is not thread-safe with other threads. There is always one GIL for one interpreter process.Usage of a Global Interpreter Lock in a language effectively limits concurrency of a single interpreter process with multiple threads — there is no or very little increase in speed when running the process on a multiprocessor machine.

Deciphering the Global Interpreter Lock

To make this a little less abstract, let’s first look at Ruby 1.8. First, a single OS thread is allocated for the Ruby interpreter, a GIL lock is instantiated, and Ruby threads (‘Green Threads‘), are spooled up by our program. As you may have guessed, there is no way for this Ruby process to take advantage of multiple cores: there is only one kernel thread available, hence only one Ruby thread can execute at a time.

Ruby 1.9 looks much more promising! Now we have many native threads attached to our Ruby interpreter, but now the GIL is the bottleneck. The interpreter guards itself against non thread-safe code (your code, and native extensions) by only allowing a single thread to execute at a time. End effect: Ruby MRI process, or any other language which has a Global Interpreter Lock (Python, for example, has a very similar threading model to Ruby 1.9) will never take advantage of multiple cores! If you have a dual core CPU, you’ll have to run two separate processes.

JRuby is, in fact, the only Ruby implementation that will allow you to natively scale your Ruby code across multiple cores. By compiling Ruby to bytecode and executing it on the JVM, Ruby threads are mapped to OS threads without a GIL in between – that’s at least one reason to look into JRuby.

Process parallelism

The implications of the GIL are surprising at first, but it turns out the solution to this problem is not all that complex: instead of thinking in threads, think how you could split the workload between different processes. Not only will you bypass an entire class of problems associated with concurrent programming (it’s hard!), but you are also much more likely to end up with a horizontally scalable architecture for your application. Here are the steps:

  1. Partition the work, or decompose your application
  2. Add a communications / work queue (Starling, Beanstalkd, RabbitMQ)
  3. Fork, or run multiple instances of you application
  4. Not surprisingly, many of the Ruby applications have already adopted this strategy: a typical Rails deployments is powered by a cluster of app servers (Mongrel, Ebb, Thin), and alternative strategies like EventMachine, and Revactor (equivalents of Twisted in Python) are gaining ground as a simple way to defer and parallelize your network IO without introducing threads into your application.

虽然本文是介绍Ruby1.8、1.9和JRuby对线程的不同实现。但是却清晰的解释了线程安全的意义,还有为什么MRI(或者同样使用GIL的CPython)需要使用多进程模型部署。再延伸我们可以知道Apach上面的Mod_rails(Passenger和Ruby Enterprise Edition)还有Mod_python的神奇之处,他们都hack并实现了使用fork让进程共享内存。最后本文还同样引出了为什么传统Ruby和Python应用只有使用多进程才可以利用多个CPU,还有为什么Twisted和EventMachine使用了单进程单线程+event IO的模型。

最近很迷陈绮贞

最近很迷陈绮贞,买了国内能买到的几张正版专辑。


可惜的是因为经济状况不好,所以没法去看她的演唱会。之所以写下我的想法,一个是因为总是被她的歌曲所打动,也是要告诉自己我还是有追求的。今天就再回忆一下我对她的歌的回忆。
最早一次听到她的歌是在05年底一个周五下午从密云回到北京的980长途车上,那是入冬的时候了,车外是棕灰色的北京,车窗上凝结了水汽,我穿的厚厚的坐在车上睡着了,在醒来的时候车到大山子了,耳机传来好听的吉他旋律,然后是一个声音非常奇怪的女声唱歌,歌的旋律也很怪,高潮的部分能听到华丽的冒险几个字。因为她的声音很像童声,所以突然留下了奇怪的印象,很难抹去。而后在我的Meizu E5里面反复的听到这首歌,但是我从来没有去看她是谁。我只记得那一些歌曲是dream4ever的CPOP 9月精选。
因为懒惰一连几个星期没有更换Mp3里面的歌曲,所以有幸反复听到了华丽的冒险,越发的觉得好听了。突然有一天想看看她到底是谁…看到原来她叫陈绮贞,专辑的名字就是华丽的冒险。这个名字让我有点震撼,因为我女朋友(现在她是我夫人)的名字被包含在她的名字中,所以我觉得很奇怪。
然后就这样过去了很久,我没有可以的去找她的更多专辑听,也没有想到我会迷她的音乐。
后来老张同学(我的非常好的哥们)要去英国了,去之前他碰巧弄到了许巍演唱会的门票,地点就在人民大会堂。本来计划我和老婆一起去听,可是碰巧她发烧了,所以我就碰巧和老张一起听了这么一场印象深刻的演唱会。许巍的演唱会绝对是非常非常的牛B,好听的要命。他请到的嘉宾碰巧就是陈绮贞,当时我突然想到原来她的歌我是听过的,而且我很喜欢。忘记她在演唱会唱了什么,因为沉醉在许巍的歌声中。不过我记得和许巍的音乐相反,她的音乐是那么的通透、那么的华丽、那么的忧伤、那么的美妙,所以在回来以后我就种下了一个仔细听听她的音乐的种子。
回家后我去Verycd下载了她的专辑,好像是花的姿态演唱会实录和华丽的冒险,然后就又过了很久很久,专辑就躺在硬盘上。
在有一次整理硬盘的时候我又找到了这几个专辑,听了花的姿态,惊叹原来她的歌是这么这么的好听,每一首都好听。然后,从去年就迷到了今年,在知道了她要在北京开演唱会的时候很兴奋,不过我知道我很难去现场看,所以只能先买几张CD来支持一下了,忏悔一下听盗版的岁月。在Google她的背静的时候我才发现她真的过着我所向往的那种有追求的生活,她喜欢Lomo,她也喜欢DIY一个个细节。她有艺术家的气质,可是我没有,我却想追求。在这个时候我才知道她来自台湾,我本一位它来自那个小而清新的新加坡,后来知道她其实是地道的台湾人。我也很喜欢台湾的民谣老将陈升,还有他的徒弟刘若英。陈升在鱼说这张专辑里面翻唱了《花的姿态》,不过冠以《你一直在玩》的名字,初听感觉很怪,就好像第一次在听陈绮贞。跑题一下鱼说这张专辑,让我感动,陈升已经是一个参与到铁人三项里面的歌手了,也曾是个酒鬼,很有趣,他居然这么自由的创作了这样一张专辑。陈绮贞的专辑也是这样的自由,这种自己自由的追求让我感动。
在开车的时候很喜欢听她的音乐。她的音乐都有标志性的巨好听的前奏,那前奏每次都让我误以为是另外的一首什么歌,让我每次都陶醉在里面,忘记那是什么歌,那是谁在唱,我在干什么。在歌曲进入主题,每次都能听到那种忧伤的情绪,或者说是脆弱或者清脆的理智的小女生的倾诉,我的爱人也是脆弱的女声,所以每次听到这样的音乐都回触动我心里那脆弱的神经,让我想要抱紧我爱的人。别人的博客把她的声音比作软刀子,暴露你的脆弱。好听的旋律倾诉恐怖的情绪,也许我喜欢这样的矛盾,这种偏执的感觉。这种感觉让我想起了Nick cave的谋杀情歌那张专辑,缓慢的民谣下面却是那可以刺激你的神镜的情绪和故事。
在买了她的几张专辑以后老婆质疑我为什么喜欢一个女歌手,问我她的长相。其实我才想起我一直没有关心过她长什么样子,她的专辑上的照片很少有面部特写,很多都用Lofi的效果处理过去了。其实好听的音乐人让我不敢关心她的长相,不过在我仔细寻找了一些照片以后我发现她的长相并没有让人失望,起码让我有一种想要祝福的感觉,祝福这个美女。跑题。
无法说出最喜欢哪一首么?其实我最喜欢《旅行的意义》,因为歌词就好像一首叙事的诗。歌词本身也是一首诗,提出这个问题已经足够了,因为我们要活的明白。听说陈绮贞在巴黎被小偷偷窃后追讨钱包还被打过,对她产生了非常大的崇拜之情。我是软弱的,虽然看似坚强,女人看似是软弱的,可是她们之中很多都非常坚强!我也经常问我自己生活所做的各种事情的意义,也包括旅行的意义,在今年旅行时我也一直问我自己旅行到底是为什么?我想我有我的答案。
写这篇博文是为了让这些记忆的片断告诉我自己我是非常的爱她的歌,非常热爱她的追求,非常的认同她做事的方式,非常向往,向往那份自由的生活。当然所有的这些都是有沉重的责任的,只有很少的音乐人过上了好日子,大部分都还在为温饱而斗争,那么能够在DIY的道路上走到所有人都认同愿意出钱买票去看演唱会的局面是多么的不容易。
Kudos to cheer!

找到了我的Mac下的git-svn不工作的问题

前一段时间把Mingle的svn用git-svn在本地clone了一个git repository,不过后来非常奇怪的是git svn的时候提示命令找不到了。没有在意。

今天需要用git svn rebase一下这个repository,所以到处搜索为什么?最后发现了问题在于我使用macports安装的git-svn,但是升级的时候却使用了git install,结果造成了系统中安装了两个配置不同的git-core包,而包含git-svn的却没有被激活。

执行

tin@tw-dell:git_mingle >port installed The following ports are currently installed: … git-core @1.6.0.2_0+bash_completion+doc+svn git-core @1.6.0.2_0+doc (active) …

就是说+svn的git-core目前没有激活,那么好办了。

tin@tw-dell:git_mingle >sudo port deactivate git-core @1.6.0.2_0+doc —> Deactivating git-core 1.6.0.2_0+doc tin@tw-dell:git_mingle >sudo port activate git-core @1.6.0.2_0+bash_completion+doc+svn —> Activating git-core 1.6.0.2_0+bash_completion+doc+svn

其中先deactivate现在激活的git-core,再activate+svn版本的git就OK了。 如果你还没有安装,这样安装:

sudo port install git-core+svn+bash_completion+doc

–EOM–

iPod touch 2入手

托同事从香港给带了iPod touch 2,好兴奋的拿到了这个iPhone的替代品。因为我一直以来很像有一个像样的掌上设备可以有空做做开发,而iPhone/touch可以说是不二之选,因为从艺术的眼光上看他们很完美(起码我这么看)。而且多点触摸带来的交互革命激发了我作为UE边缘认识的兴趣。

iPod touch 2多了录音功能,所以也可以配合fring实现skype通话,不过前提是你需要购买带mic的耳机,目前似乎只有Apple原装的,要220港元,好贵,所以暂时还没有出手买这个。但是机身先下手了。是从国美(香港)买的,因为很多retail的地方都售空了。

现在的iPod包装实在是简单,连说明书都没有,只有一个简单的开箱指南,还有一个基本的连接iTunes的说明,仅此而已,不过倒是这样就够了,因为可以把你的眼球固定在touch上,让你自己好奇的去探索。我觉得激发用户的探索意识是很好的一种让用户产生沉浸感的营销方式,而且从苹果一向的交互设计理念上来说,他们非常注重启发式探索,并且尽量让你本能的达到自己所期待的结果,这个正是交互设计的重点所在。

那么不废话这么多,上图。图是上周一晚上照的,最近生活节奏太快,现在才抽空出来显摆^____^

InfoQ“构建的可伸缩性”文摘

InfoQ上面的一篇文章《构建的可伸缩性和达到的性能:一个虚拟座谈会》
http://www.infoq.com/cn/articles/scalability-panel
这篇文章很好,给了你很多做可伸缩性的线索,记录下这些点滴。推荐感兴趣的人去InfoQ阅读原文。

  • ab & httperf: 它给我们提供了一些自动化的负载测试,因此对比于我们从firebug中获得页面级的计时,使用这个工具可以获得会话级的计时。
  • firebug:
  • Ganglia是非常优秀的。同时Nagios或Zabbix(举个例子)将告诉你何时资料遭到破坏,使用少量加工你就能够让ganglia给你提供任何东西。
  • 对于MySQL,Innotop + slow query log 帮了大忙
  • GDB和DTrace是用于C++的基础架构。core或 pstack是个颇有价值的工具
  • 我们使用各种工具来重现问题并调试它们(包括栈的问题)——Visual Studio、 Eclipse、WinDbg、cdb、Purify、Fortify、dtrace以及许多定制的东西,为我们的架构所构建的东西
  • 从某点上讲,伸缩性已经从领域问题(即,如果你不使用内存缓存或者一个等价的分布式哈希表和基于内存的缓存)转移了,而你仍然处于“领域”范围
  • 当今静态内容的可伸缩性已不那么重要了,那只是花钱的问题并需要公司有好的社会组织的问题
  • 不要试图在部署之前就捕获性能问题。你不可能重建真实环境中的条件,因此你不可能得到真实可靠的测量结果
  • 监测。非常仔细的监测
  • 墨菲法则(一种幽默的规则,它认为任何可能出错的事终将出错)确保了你没有严密跟踪的衡量标准就是那个对你不利的标准!
  • 除非你知道当时正在执行什么业务功能,否则一个CPU测量是无意义的
  • 你只能通过使用软件实现伸缩性。“语言是不能伸缩的。框架是不能伸缩的。而架构是可以伸缩的。”

我的旅行的意义,去澳大利亚后

我在想,我为什么和老婆去澳大利亚旅游。我们旅行的意义是什么?

记得今年我读了阿兰德波顿的旅行的艺术,里面探讨的就是旅行的意义。我记得书中说旅行是为了验证什么或者逃避什么。那么我们去澳大利亚是验证什么或者逃避什么呢?其实在去之前我并没有问我自己这个问题。

我很怕在熟悉的人面前出丑,但是到了陌生的环境我感觉我就自由了。这种现象在幼儿园的时候就有了,爸爸来接的时候我都特别乖,特别的沉默,但是爸爸走了我就怂恿身边的小伙伴们做坏事,气老师。这些其实我也记不清除了,是爸爸和我说的,老师抱怨过,我记忆中就是身边的男孩女孩都特别听我的,而且我记得做得最好的就是我能够让他们在做了坏事以后不说是我让做的,所以我一直以为我是非常安全的。不过,实际上是怎样我也不知道,我所认为和我所记得的都是在那个年龄的心智范围以内的。

去了澳大利亚这么远的国家我就不怕出丑了,我就又可以自信的做自己想做的了。自信,不怕出错,感觉很自由,就像回到了童年。回到童年是非常快乐的事情,因为童年在我的记忆里是个太快乐的年龄段了。那个时候搜索所有的记忆也只有两件害怕的事情,一个是“从山上掉下来”一个是“杀人”,其实都是梦境。梦境里面梦到过很多次和爸爸一起爬山,爸爸总是爬在我的前面,而我跟在后面,我们爬的是笔直的峭壁,我非常害怕,但是最后还是掉下去了,身上会感受到失重的感觉,非常可怕,因为我是个恐高的人,我能做的就是呼叫我爸爸,呼叫,大声的呼叫,最后我醒了,自觉的下地去撒尿。嗯,这个恐高症的梦原来就是意味着我要撒尿了。另外一个是在上了小学的时候会做的梦,我会杀掉Turtle同学(是我的发小,最好的朋友(之一)),一般就是用铅笔戳死或者用手攥死。这种梦很离奇,因为杀人以后Turtle同学就神奇的消失了,而且我每次都没有看到我杀掉他的细节,只是强烈的知道我杀了他,然后就是好害怕,开始想念我的好朋友,开始害怕蹲监狱,害怕见不到爸爸妈妈,最后几乎都是哭醒的,不过哭醒以后我发现我没有哭,甚至眼睛里面没有湿润,爸爸妈妈也没有听到我哭。这个梦大概是说那个时候我在意的这些人吧,我怕失去最好的朋友,怕失去爸爸妈妈。那么这两个噩梦就是所有了,其余的记忆都是那么的鲜艳。

澳大利亚就是这么一个鲜艳的国度,鲜艳的要命,就像有生命要从那鲜艳的颜色里边爆发出来,都咄咄逼人的让你目眩。它让我想起了我的童年,我可以和我的老婆撒娇。我终于可以拉着一个漂亮的小姑娘的手一起在大街上面看到所有的东西都兴奋的大呼小叫了。小的时候我不好意思和女孩子说话,实际上在幼儿园的时候我还是和小女孩说话的。但是上了小学以后我发现女孩不能欺负,因为会被老师和父母加倍责备。还有就是我对女孩的身体感觉很神秘,很像偷偷看看,但是又不敢偷偷看,所以干脆不如不看、不听、不想,那么当然也就不说了,所以那个时候开始不怎么和女孩子说话了。但是内心里面我也想和一个打扮的漂亮的有大眼睛长头发的小姑娘一起拉拉手的,直到二十多年以后我的这个梦想才实现。这次去澳大利亚似乎就是让我牵着我漂亮的小姑娘走到了童年,我得到了我一直想要却从来没有得到的东西。我的老婆就是最爱的女人,但是她也是一个童年的伙伴,我在童年直到青年都不认识她,但是现在拉着她的时候她看起来还是一个小女孩,非常可爱,有小圆鼻子,大眼睛,漂亮的细眉毛,薄而细的嘴唇,脸上有几个小小的祛斑,耳朵又小又圆很俏皮,所以她就是我小小的女神。我曾经梦到过很多次,小的时候,我在胡同里面玩的时候,她也在某条胡同里面玩着,我在一刹那,想到了她,她也感知到了我。拉着我亲爱的女神,走在童话的街道上面,我感觉好幸福,就好像我喜欢的摄影画册,浪漫的街头,带有颗粒感的画面,我们傻傻的微笑。为什么会想到摄影画册,是因为悉尼的阳光是那样的赤裸的闪耀,穿过各种神奇的大树小树投射在我们的身上和脚下,光影就这样交错在一起,和我们的身体和空气交织。我喜欢有光影的空气,这种空气可以滋润你的心情,让心情被热带的潮湿空气软化。悉尼的空气我很怀念,那是一种湿润和凉爽的空气,水滴像是水晶的雾摩擦着你的皮肤,闪烁的广从水晶里面渗透到身体里面,身体的内部都被水和光射透了,感觉就像在天堂一样。光非常强烈,感觉心情非常神圣。童年、女孩、颜色、光影、神圣,实际上这是我从宫崎骏的动画里面读到的一些关键字。正巧上周和爱人看了《悬崖上的金鱼公主》,我很强烈的知道,即使是在童年,我也知道我要的是什么样的世界,什么样的女孩,什么样的生活。似乎这个电影就是记录的我们在澳大利亚作为一对结了婚的恋人的感受,那种童年的幸福感的回归。

童年不怕什么,我回到了童年,所以我活得了2周的自由,这种自由是一个多彩的调色板,我们可以肆无忌惮的使用颜色。在那里很自由,即使没有那么多的钱住很好的旅馆,没有那么多的钱去吃正餐,没有那么多钱享受遍历出租车,可是我们可以享受愿意往哪个方向走就向哪个方向走的自由。我们可以放纵的用中文说一些肉麻的话,却不用担心有人会在意,我们就像风一样在城市里面穿梭,我们还可以相信我们是透明的。我们不会给城市留下什么印记,我们只求城市给我们留下一个快乐的印记。这种感觉非常的自由。

这是我旅行的最大意义。

这次还圆了另外一个梦,我看到了动物世界里面最多彩的珊瑚礁。我是一个看颜色上瘾的人,在动物世界里面给我最大震撼的就是大堡礁,那里有最神奇的颜色。记得小的时候我学过很多年的绘画,其中最自豪的就是在最初的配色课程上面老师总是夸奖我,那个时候就是在一个鱼的轮廓上面填充颜色,鱼身上的鳞是相同的几何图形,你可以发挥的想像让它变得五颜六色。那个时候的我很自由,所以我会按照我的心的方向去填充,所以我就有了漂亮的的图画。但是在后来那些灰色的学习会话的岁月里面我却只记得我错过了变形金刚,我错过了太多太多的周六晚上才有的动画片,就是因为我要去学习画画。所以在后来我在绘画方面没有任何发展,现在不过就是比从来不画画的人能画出圆润一些的线条,其它的所有技能都退化了。大堡礁就在我的面前的时候我又捡起了对颜色的那种自由的饥渴,我感觉我又可以自由的享受颜色带来的兴奋了。生物选择使用绚烂的色彩绽放自己的生命!所以颜色就是生命的象征,我喜欢颜色,实际上是因为我喜欢我们的生命!我在水中不停的呼唤我的亲爱的老婆,喊出不知道名字的鱼的名字,拿起活着的蓝色海星给她摸,我非常喜欢给我身边的朋友讲生物知识。虽然现在我的生物知识已经不如小学生了,但是我依然可以享受讲解那些不清楚的记忆里面的知识的快感,分享知识在任何时候都可以给你快乐。亲爱的老婆也非常兴奋的听我胡乱编造出的各种介绍,并且认真的问问题。浸泡在颜色中,享受分享快乐的幸福,这是大堡礁给我的。

在丹特里特的雨林里面,我们还划了独木舟,和亲爱的人一起冒险。水是透彻的,因为透彻,所以我就不会恐惧。一直认为密西西比河是可怕的淡水河,因为淡水里面总有奇怪的张牙舞爪的水中生物。但是在丹特里特的清澈小溪中,没有未知,所有的东西都浸泡在透明的水下,所以我不用鼓起勇气就可以用双脚去接触小溪的鹅卵石,却一点都不担心有奇怪的水中生物。我们可以看到好笑的王八和小鱼在水里游泳。

我的感情就随着这样的旅行得到了释放,得到了慰籍。我想这就是旅行的意义吧。

Tin和zz的澳大利亚游记之Woomoolloomoo Bay

Tin和zz的澳大利亚游记之Woomoolloomoo Bay

9月,tin和zz两个人独自飞到了南半球袋鼠之国澳大利亚,开始了12天的疯狂自由之旅。一本Lonely planet,一台尼康 D50,一台松下LX2,四只脚,两个箱子,成就了我们9784张照片和满心的欢喜。

从悉尼的Woomoolloomoo Bay开始吧。

P1080336-当我看到这个景色的那一刻,我就爱上了这里。

_DSC1827-悉尼的温度有些凉,夹杂着雨气,有点冷, 冷风吹走了我们刚飞机后的倦意。就这样,我们开始了一天的徒步之旅。从山上的小道顺路而下,就是令人意想不到的WoomoolooBay

P1080322-这里有三大主题:The Wharf 船坞,军舰 和 牛肉馅饼

_DSC1842-著名的牛肉馅饼店

P1080318-从山上向下拍摄,远方是市中心

P1080324-P1080324

_DSC1853-_DSC1853

_DSC1863-船坞的正面。The Blue 非常奢华的五星级酒店,名字就如船坞的颜色一样。

_DSC1867-船坞的另一侧是个小港口,港口一侧停泊着高级游艇,另一侧是高级餐馆

_DSC1878-_DSC1878

_DSC1874-_DSC1874

_DSC1876-清晨餐馆不营业的,晚上一定很热闹

_DSC1902-连排游艇

_DSC1869-从港口向市中心望去,景色壮观。

_DSC1881-其实,这个船坞于911-1915建造, 门口的介绍说,这个码头是世界上最大的全木制建筑,我肯定,他们肯定没有算上中国的故宫

_DSC1882-_DSC1882

_DSC1884-_DSC1884

_DSC1885-船坞内部一小部分经过修缮,作为纪念馆开放,另一部份就是奢华的酒店啦

_DSC1901-_DSC1901

_DSC1892-这里记录着,这里是悉尼一切开始的地方,到达和离开的起点。而这里也偶然的成为我们悉尼之旅的起点。

_DSC1893-_DSC1893

_DSC1894-起点

_DSC1924-据说著名演员Russell Crowe 就住在这里一个价值一千四百万的顶层阁楼里

_DSC1951-LonelyPlanet 推进的牛肉馅饼。澳洲特色。

_DSC1935-_DSC1935

_DSC1942-超大热狗,15cm长,料足,可口。腸下面还有青豆酱和酱牛肉块,非常不错。

_DSC1945-著名的牛肉馅饼,就是空心面包填充酱牛肉,外面糊上青豆糊。(超级难吃)

_DSC1946-牛肉馅饼内部展示

_DSC1917-Woomoolloo一侧的小山

DSC_3654-从小山上望向Woomoolloo

以上内容由zz于2008年10月11日创建于
href=”http://beta.haokanbu.com/”>好看簿
。 点击此处访问原始链接,或此用户的
href=”http://beta.haokanbu.com/user/2828/story/”>更多内容

好看簿:用照片记录和分享生活的图片博客”

关于javascript库的一个回复

我以前写过一篇说说我对moo、prototype、JQuery的看法在我的blogjava博客里面(现在我已经不更新了,完全使用这个wordpress的博客)。今天也是在Google Reader里面看到JavaEye的另外一个朋友lifesinger的一篇文章:大胆预测下几个JS框架的走势,我个人不是非常同意,所以写了如下回复,也发在我的blog吧。

完全不同意lifesinger的说法:

1、JQuery会走的比较远。因为Django会走的比较远。而且JQuery的内部设计很好,如果说它不好估计是没有理解它的核心理念。而且John Resig的确是个勤奋的福音传播者,它的js使用理念很好,所以这个库会随着它的plugins库的数量质量的双重提高,占重要位置。同时浏览器效率的的提高也会给它注上强心剂。

2、YUI的api设计不好。作为oo的库它不好,作为fp的库它更不好,所以它不会有多好。不过在widget类库里面它肯定继续占重要地位,因为YUI的widget的确兼容性很好。

3、moo我很喜欢,但是它的演化保持了小众的特点,小步前进,api设计上比较偏设计师的想法。做大型项目的时候你回发现moo没有对如何组织你的项目给很好的“风格”上的建议,所以它也就会在大型项目上哑火。

4、Ext,我看没什么大的希望了。因为它的授权问题,基本上它已经不在是开源社区友好的(它也许可以做自由软件社区友好吧)。而且作为一个UI Widget库,它并没有把可访问性放在重要的地方来重视,所以随着UI的可访问性要求的上升,它的默认皮肤带来的eyecandy估计就没法盖过usability的缺失了。

你没有提到Prototype,它目前还是js lib的第一名,随着活跃的RoR社区的继续推进,它应该还会持续足够的市场份额。而且它和JQuery同属于有强烈“风格”的库,所以即使项目很大,它还可以保证代码的可读性与可维护性,这对于很多项目来说是至关重要的。

关于dojo我不说了,以前说过:说说我对moo、prototype、JQuery的看法的回复里面有。