Keep-Alive

史无前例,上个月只写了一篇blog,再加上网站遭遇认证很多地方都访问不了,故而有必要keep alive一下,该reconnect的请自觉重连。

从家里出来,再次跑到北京来,就做好了艰苦卓绝的思想准备。现在的工作节奏,和2010年春天在盛大在线的时候差不多。那时一腔热血,也没什么经验,做什么事都心里没底。当然也是那段时间学到的东西最多,人生就是这样,熬过一个最困难的时候,总会有巨大的收获(如果没有收获说明还没熬过去,下同)。时过境迁,现在的情况有了巨大的不同,比如看这里。曾经没日没夜的奋斗的项目,最后烟消云散仿佛都不存在过。

人最大的瓶颈是时间,时间不可逆,挥霍掉就没有了。为了能有口饭吃,大部分时间还得拿自己的时间去换别人的金钱。如果这个时间能有合理的回报或是各取所需最好,如果这个工作自己也认同倒也不错。如果是纯粹的时间换金钱(所谓工作毕竟是工作),那就难免悲伤了。所以看到这样一篇文章,还是觉得你很有必要快速浏览一下:

  • Spend time with the right people.
  • Spend time on the right activities.
  • Enjoy experiences without spending time actually doing them.
  • Expand your time.
  • Be aware that happiness changes over time.

时间自由是人生最高自由。为了合理的利用时间,请关掉你正在折腾配置文件的emacs。

做了一个brogrammer的测验,和公司同事一起做的。结果得分-105,算是标准nerd了,在公司也是仅次于老板的-120。这个分数基本让人满意,对于那些戴墨镜编程的brogrammer,我想说的是,我的emacs一直是深色背景。

爬山!

今天是2月1号,本人决定从今天开始到月底的每个工作日中午去爬山锻炼身体,以摆脱目前体重极速增长的困局。口说无凭,立此为据。

loading map - please wait...

CuiPing_Hill 31.929620, 118.780457 山顶,海拔68米

Code 2011

成功人士是不写总结的,所以我来写个总结。

今年的coding从ABAP开始,这个很多人现在不知道以后也不用知道最好永远也不要知道的语言和他的平台,是一个脱胎于Pascal,在发展过程里又杂糅了SQL和C++的怪物,最后几乎变成了满屏幕关键字。再加上缺乏文档,实在是一段不堪回首的记忆。

3月份开始,我又重新开始了一个python项目叫做jip,他兼容maven,可以与virtualenv和setuptools集成,帮助你解决jython项目的java依赖,简化jython项目的发布,提高工作效率。这个小工具倾注了我不少时间,如果你某一天要和jython打交道的话,可以试试看。

今年还尝试了coffeescript,它恰到好处地消除了javascript里一些ugly的部分,大大提高了编码速度。我用它改写了网站首页的js

6月份我又重拾起1年前的javascript库heatcanvas,和lbt05协作完善了程序。通过HTML5的Web worker API改善了渲染canvas时的用户体验,增加了对Google Maps,OpenLayers,Baidu Map以及Leaflet的支持。这个项目的介绍被顶到hackernews的首页,这是一种前所未有的感觉。

7月份开始迎来了一个重大的转折。断断续续学习了一年半的clojure,终于开始写第一个库,reddit.clj,用clojure封装reddit网站的API。通过这个入口算是真正走进了clojure的世界,七月底reddit.clj基本完成之后我开始写他的第一个应用,rageviewer。这是个clojure的web项目,借着这个契机又接触了compojure和ring。而且写rageviewer的时候恰逢clojurescript公开,一不做二不休,于是这个项目就成了一个full stack的clojure项目:前后端都是clojure。最后rageviewer部署在当时刚刚开始邀请测试的cloudfoundry上。

8月参加了在上海的cn-clojure列表第一次聚会后,我开始用clojure克隆一个已有的并不复杂的程序,当时选择了beanstalkd,一个轻量级的task queue。这个项目取名为clojalk。最后它成功地支持了beanstalkd协议的所有命令,支持了通过Write-ahead log做持久化和恢复。这个项目用到了aleph,见识了一把clojure思维下的网络编程。

另外我还帮clojure-control写了一个leiningen的插件,现在这个插件已经合并到clojure-control项目里了。clojure能有这么快的发展,leiningen作为构建工具也有很大的帮助。就好比上半年做jip时,感受到jython的小世界里就没有一个好的方案来同时解决java和python的项目管理问题,而且人们也不重视这个问题。

年底还有一个clojure RPC框架的诞生,这个项目叫做slacker。项目还没有到总结的时候,我的org file列表上还有一长串的TODO。

总得来说,我觉得今年学习clojure的这个过程很有借鉴价值。对于一个新语言新平台新生态系统,如何入门并且getting real。你可以从一个功能简单的库开始,比如包装一个网站的API,或者(对于clojure来说),包装一个已有的java的库。在完成之后,利用这个库,写一个web应用,进而去了解这个平台上的web开发。再下一步,可以去克隆一个其他平台上的项目,规模不要太大。如此循序渐进,学习的效果很不错。另外,无论做了什么,只要是有用的,就应该说出来,这不仅是自我鼓励,有时候也能找到志同道合的朋友一起参与。

最后除了clojure之外,今年还接着gnome-shell的发布和更新,接触了gnome-shell的gjs扩展开发。又是一个不堪回首的平台,也许是还没有finalize吧,没有任何文档,而且一个平台上的库连变量拼写的风格都不一样!我是不会再浪费时间了,当然,以后的这个豆瓣电台的control还是会继续跟着gnome-shell的发布一直维护的。

除了上面提到的,今年还尝了一些groovy,common-lisp,甚至octave,不管怎么说都算是一个big year了。但愿明年能把这种状态保持下去,享受这种愉悦。

流水帐

最近没有什么特别值得一提的事情,或者说都还在进行中还没有到值得一提的时候。

中秋节休息之后的第一天清早去驾校考交规理论,这个事没什么可说的,除了在4sq上又拓展了一点疆土,后来我又后悔没把GPS带着错过了一些还没有数据的道路。倒是那天去和回分别坐错了车,想十年前本人对城市交通网络了然于胸,除了视力不好把48路看成46路就没有坐错过车走错过路。结果现在公交线路的数量翻了一番,城市的交通网络也更复杂了。人脑则不具备scalability,活地图的时代一去不复返了。

第二件值得一说的是我在VirtualBox里成功安装了ArchLinux和GNOME Shell桌面。我工作的机器是有点古老的Dell OptiPlex 760,显卡还是ATI的Radeon HD 3420。为了开发的方便,我们装的都是CentOS 5,没错是5!!这周上班后升到了8G内存我就开始琢磨开个虚拟机体会一下现代生活。多余的不说了,几个注意事项:

  • Host要装ATI的fglrx驱动,xorg-x11-drv-ati直接也能用,但是性能非常差
  • VirtualBox要在4.0.4以上,我看网上说的,具体能个版本也不知道,但是用最新的就可以
  • 3D加速要开,在虚拟机的设置里
  • 最最重要的一点!不要从虚拟机的菜单里安装Guest Addon,那个对Arch不管用。要用pacman安装仓库里,包名我忘了,请自行-Ss
  • 别忘了把rc.vboxadd加入rc.conf的Deamons里

这周最诡异的问题是在配Netty的Pipeline时,我用了:

Channels.pipeline(new HttpMessageDecoder(), new HttpMessageEncoder(), myhandler);

结果稍微上一点压力居然出现了很多decoder异常,什么包不全、头不全、空指针什么的。不明真相最后改用例子里的:

ChannelPipeline cp = Channels.pipeline();
cp.addLast("decoder", new HttpMessageDecoder());
cp.addLast("encoder", new HttpMessageEncoder());
cp.addLast("handler", myhandler);

就成功了。也许是顺序的原因也许是名字的原因,可如果这个名字真的具有意义的话为什么没有常量可用呢?不去追究具体原因了,记住就好。

此外遇到的bug还包括clojure中transient数据结构的问题,我有一个transient的map,但是persistent之后发现只有前9(依稀好像是)次assoc!的内容保存了,后面却都丢失了。1.2里的transient都被标记了alpha,不过印象1.3的changes里好像也没提transient。

另一件与clojure有关的诡异事件是一个test case的failure report:

FAIL in (test-read-job) (wal.clj:61)
expected: (= (job k) (rjob k))
actual: (not (= “tomcat” “tomcat”))

不过最后好在是冤有头债有主,睁着眼有时也要说下滑。在从stream中读字节流多读了一个byte,后来用这一组byte去new String的时候,就变成了一个不可见字符。结果在命令行里的输出就是这么骇人听闻,还是在IDEA里跑这个测试才发现错误的那个字符串后面跟了一个方块。至于为什么多读了一个byte,copy/paste害死人啊。

以上这些牢骚是关于clojure的,但是这篇就不加clojure的tag了,否则被planet clojure收录去我又给中文世界丢脸了。

周五晚上我又更新了sunng.info的首页,以后也许我会定期的放一些得意的照片(或者照片上有得意的东西)上去做背景,以免被人看到后发现太单调乏味。

最后还要感谢一下twitter网友Kymair这周将Rage Viewer部署到了Heroku上。

工作第二年

这个周末就是我正式工作两年的日子了,第二年过得稍微有些起伏,晚上写了一点总结。但是刚才读了一下觉得不太满意,也不太合适发出来。这样,即将跨入三年级的时候,我就改改风格谈谈愿望吧。

1. 把日常工作做好,积累技术,流程,项目管理的经验
2. 业余时间拓展周边领域的知识:数据挖掘,数据分析,可视化方面
3. 希望能主导去做成一点有始有终的事情
4. 希望不久的将来能参与一个志同道合齐心协力(self-motivated)的团队一起做好一个产品