星期一, 三月 23, 2009

天津一九八三

又忙起来了,刚开了个头儿想(泛泛)研究一下OpenJDK6的,估计短时间内又没有空闲时间继续了。今儿个赶紧发篇东西来凑数,这几天这本儿相册貌似也已经被很多人转来传去的很多次了吧——Tianjin 1983 (天津市 1983年)。嗯,这儿就只发咱家乡的了。
那个时候我出生还没几个月,看着那些景致真有些唏嘘,虽说我也没怎么经历过吧…记得第一次坐车时,那些车就已经不是这个样子了,只有最后一张图里的93路使用的车型在小时候见过。一直以来我对电车都有种莫名的好感,在北京实习时也是能坐电车的话决不坐汽油/柴油车,虽然电车的加速和刹车感觉起来都很突然(某次哥们儿没抓紧扶手,电车一加速被从前半截车厢甩到后半截车厢)。

星期三, 三月 18, 2009

[浅读openjdk6] 1. 构建openjdk6

接上篇,当openjdk6的代码库已经用mercurial clone/fclone完毕之后,就可以构建openjdk6了。当然构建与阅读源代码没有太大关系,只是如果日后还要做hack的话,总要通过构建和测试来检查、调试自己的hack不是,所以了解openjdk6的构建方法还是有点必要的。
基本上,代码库根目录下的README-builds.html中的讲解已经很到位了,我这里再简要地啰嗦一下整个步骤,权当个中文翻译好了。
  1. 必需的应用程序:gcc 4,g++ 4,GNU make (>3.80),m4 (>1.4.4)。以及README-builds.html中指定的很多个开发包(dev)。我的操作系统是Ubuntu 8.10,内核版本为2.6.27-14,按照README-builds.html的包依赖关系,一下子:
    sudo apt-build install binutils cpp libfreetype6-dev g++ cpp-4.1 g++-4.1 gcc-4.1 gcc-4.1-base libstdc++6-4.1-dev gawk gcc libasound2-dev libc6 libc6-dev libc6-i686 libcupsys2-dev libgcrypt11-dev libgnutls-dev libgnutls26 libgpg-error-dev libice-dev liblockfile1 libopencdk10 libpopt-dev libsm-dev libtasn1-3-dev libx11-dev libxau-dev libxaw7-dev libxdmcp-dev libxext-dev libxi-dev libxmu-dev libxmu-headers libxmuu-dev libxp-dev libxpm-dev libxrandr-dev libxt-dev libxtrap-dev libxtst-dev libxv-dev m4 make ssl-cert x-dev x11proto-core-dev x11proto-input-dev x11proto-kb-dev x11proto-randr-dev x11proto-record-dev x11proto-trap-dev x11proto-video-dev x11proto-xext-dev zlib1g-dev
    就好了。我的机器里其实已经装了libstdc++6-4.3-dev以及g++-4.3,不过保险起见还是把g++ 4.1以及libstdc++6 4.1的东西搞进来了,尊重一下README-builds.html,也顺便给自己少找些麻烦——后来测试的时候还真发现用libstdc++6 4.3或者g++ 4.3的话会编译失败,大概看了看错误信息,结论是以我现在的c++水平如果要把它port到4.3的话还是暴有难度的…嗯,那就4.1吧,听话的孩子有糖吃。
  2. 参照README-builds.html,有2个环境变量是必需的,当然这俩环境变量的值指向的目录也不是乱来的:
    • Bootstrap JDK:README-builds.html自己都说了,编译openjdk6的时候还需要一个已有的jdk6是很那啥的。没办法,估计语言发展起来之后需要自己来编译自己的某一部分也不是很罕见的事情吧。我的系统里已经装了SUN的jdk6,所以,ALT_BOOTDIR=/usr/lib/jvm/java-6-sun。
    • JDK binary plugins:这东西还是个新鲜玩意儿,以前是没听说过。照着README-builds.html里的指示,按图索骥到最新发布的jdk 6 binary plugins:http://download.java.net/openjdk/jdk6/promoted/b14/jdk-6-ea-plug-b14-linux-i586-25_nov_2008.jar。这是个可执行jar文件,java -jar一下,accept一下条款之类的东西,指定个目录就可以安装了。安装完成后,在安装目录里会看到一个openjdk-binary-plugs的子目录,结构和普通jdk一致,内容只有两个文件:LICENSE和jre/lib/rt-closed.jar。rt-closed.jar的内容没什么惊喜,一堆SUN自己的SNMP功能的支持类,光看这文件名就知道肯定是不方便开源的东西。不管它的内容:ALT_BINARY_PLUGS_PATH=~/projects/openjdk/jdk6-bin-plugins/openjdk-binary-plugs/ 。
    • 其他的几个环境变量我是没有再手动设置,估计debian系的系统里,那些dev包安装妥当之后也不用再自己设了。
然后,终于可以开始make了,先来make sanity一下,确认当前配置没问题,没问题的话就可以直接跑make了。所有c/c++的代码无疑都是gcc、g++来编译的,其他诸如corba、jaxp、jaxws是单独用javac以及ant编译的,我用的机器上已经装好了ant 1.6.5,编译jaxp和jaxws时也没出什么问题。整个make过程在我这台P4 2.4G MHz 2G RAM的机器里花费掉了…差点儿一个小时…中间看到"linking vm..."的时候我几乎要哭出来了…
make成功后,build/目录下包括所有编译、链接出来的可执行文件以及jar包,还有javadoc。里面的j2re-image和j2sdk-image分别是…jre以及jdk,嗯,废话,是吧。进到bin目录下./java -version一下:
iusr@wisdom:~/projects/openjdk/jdk6/build/linux-i586/bin$ ./java -version
openjdk version "1.6.0-internal"
OpenJDK Runtime Environment (build 1.6.0-internal-iusr_18_mar_2009_16_32-b00)
OpenJDK Client VM (build 11.0-b17, mixed mode)

Yay!



Update: 到一台默认语言设成中文的ubuntu 8.10上重make一次,结果出错了…有3个注意事项要更新一下:
  1. g++、libstdc++6 dev包的版本问题。如果几个版本共存的话,确保g++-4.1在PATH的最前面能被最先找到。这个比较好解决,而且一旦g++版本正确的话也会确保include路径是对应的libstdc++6的头文件库。小问题。
  2. make之前要unset JAVA_HOME。这个环境变量如果存在的话make sanity会报错,错误信息也很明显,所以,同样是小问题。
  3. LANG=C。无论export出去还是运行make,一定确保LANG兼容英语,否则会出现很奇异的错误…
  4. apt-build install libmotif-dev 。这个忘记了很不应该,因为我用awesome,所以还特别地在.profile里export AWT_TOOLKIT=MToolkit了的。
其他的诸如gawk、m4之类居家旅行必备的东西,如果落下没说的话还请自己装好。

星期一, 三月 16, 2009

[浅读openjdk6] 0. 获取openjdk6源代码

最近几天在抽空看openjdk6的源代码。总觉得如果打算干很久java的话,光靠看tutor、doc、reference始终有种底气不足的感觉;src.zip里的东西可以随用随看,但各种本地方法调用以及src.zip不方便包含的类的源代码都是平日在eclipse里开发时很少会花时间看的,但这一部分往往最能决定一个java应用程序的性能。其实预谋了很久了,大概多半年到一年前就有这打算了,可始终没什么空闲,杂事也很多。
OpenJDK老窝在http://openjdk.java.net/。记得早先mustang、dolphin还都在dev.java.net这个域下,而OpenJDK直接挂在java.net下,身份自然特殊。不管别人怎么看,我是想目前先看jdk6的代码,因为日常开发正在用,jdk6也是SUN目前的主打版本,VM特性和API也更稳定,相比之下,jdk7还在密集开发之中,平日看看各种相关人员的blog,新特性、新API也是隔一阵儿就来一个,现在追起来肯定会很累,虽说jdk7也肯定是以后的主流。
获取openjdk6的代码其实也不复杂,尤其是download source bundle的方式,当然也更没劲一些——我(们)的目标是:往死里折腾。
折腾当然有折腾的好处。当你clone了整个一个mercurial forest以后,查看变更记录是了解各种特性、API以及bug fix的最直接的途径,比看什么release notes都管用,而且适合fork出自己hack过的版本——听着很吓人,其实一个hack不见得必须是一个很BT的很完善的东西,那样的话基本成了添加一个feature了,还不如去盯OpenJDK社区啥时候再出Innovators' Challenge的时候去赚些钱;很多时候hack都是临时解决一些小问题,看上去甚至会觉得有些dirty。
openjdk的源代码采用mercurial做版本管理。Mercurial也是个分布式的版本控制系统,优点是跨平台,缺点是忒慢了点儿,用惯了git尤其没法容忍管理些源代码都慢吞吞的;基本上我也只是用它来拿openjdk的代码,目前还罕见有多少我感兴趣的项目使用mercurial的,所以也没动机去深入学习一下。openjdk6的代码位于http://hg.openjdk.java.net/jdk6/jdk6/,是一个mercurial forest——一大堆源代码tree在一起就形成了源代码forest。配置mercurial以及安装那个forest插件的过程参考一下http://openjdk.java.net/guide/repositories.html应该可以搞定,不是什么大件事。有了mercurial+forest插件以后,找个干净目录来fclone一下:
iusr@wisdom:~/projects/openjdk$ hg fclone http://hg.openjdk.java.net/jdk6/jdk6/
[.]
requesting all changes
adding changesets
adding manifests
adding file changes
added 27 changesets with 63 changes to 29 files
updating working directory
29 files updated, 0 files merged, 0 files removed, 0 files unresolved

[corba]
requesting all changes
adding changesets
adding manifests
adding file changes
added 26 changesets with 1439 changes to 1376 files
updating working directory
1371 files updated, 0 files merged, 0 files removed, 0 files unresolved

[hotspot]
requesting all changes
adding changesets
adding manifests
adding file changes
added 28 changesets with 7862 changes to 3278 files
updating working directory
2964 files updated, 0 files merged, 0 files removed, 0 files unresolved

[jaxp]
requesting all changes
adding changesets
adding manifests
adding file changes
added 26 changesets with 2021 changes to 1975 files
updating working directory
1973 files updated, 0 files merged, 0 files removed, 0 files unresolved

[jaxws]
requesting all changes
adding changesets
adding manifests
adding file changes
added 29 changesets with 4864 changes to 2867 files
updating working directory
2583 files updated, 0 files merged, 0 files removed, 0 files unresolved

[jdk]
requesting all changes
adding changesets
adding manifests
adding file changes
added 97 changesets with 41623 changes to 17063 files
updating working directory
16829 files updated, 0 files merged, 0 files removed, 0 files unresolved

[langtools]
requesting all changes
adding changesets
adding manifests
adding file changes
added 40 changesets with 6616 changes to 3018 files
updating working directory
3012 files updated, 0 files merged, 0 files removed, 0 files unresolved

fclone是forest插件提供的命令,如果forest插件没有配置妥当的话mercurial会提示无法处理fclone这个命令的。等mercurial慢吞吞地把代码下载回来后,折腾的第一步就完成了。当然如果只关注openjdk6的某一模块,比如hotspot,可以单独clone这一个tree。基本上hotspot模块是每个人都感兴趣的,jdk模块次之,其他的corba、jaxp、jaxws之流也不算什么rocket science。考虑到模块大小的话:
iusr@wisdom:~/projects/openjdk$ du -s -B M jdk6/ jdk6/*
542M jdk6/
1M jdk6/ASSEMBLY_EXCEPTION
20M jdk6/corba
63M jdk6/hotspot
37M jdk6/jaxp
35M jdk6/jaxws
349M jdk6/jdk
39M jdk6/langtools
1M jdk6/LICENSE
1M jdk6/make
1M jdk6/Makefile
1M jdk6/README 1M jdk6/README-builds.html 1M jdk6/THIRD_PARTY_README 1M jdk6/TRADEMARK
大概要准备>600M的空间吧,这年头应该谁都不在乎这点儿地方了吧。
OpenJDK社区的代码仓库索引页位于http://hg.openjdk.java.net/,对其他项目感兴趣的话可以自行clone/fclone。
开始折腾前还要铭记一点:大部分openjdk6的源代码是以GPL v2许可的,部分基于其他开源项目的代码还维持其许可证不变,此外还有部分二进制模块使用的是OpenJDK二进制文件许可证。如果真折腾出来好东西了,别忘了回馈社区,没有人家夯下的基础,这一切都不可能完成。

我的饭 [0]

把最近觉得还算靠谱的饭否更新集合一下贴出来,一是因为平时在饭否上时间花的很多,blog总不更新的时候饭否的资源不能糟践了,二是也不想上一篇在顶上停留太久,人总是无趣的。
  1. 看到N多搞笑的东西,估计都是IDE用的时间太久了,也不关心底层造成的。不过构造器里return了一个其他对象还是太雷了。 2009-03-13 14:32
  2. 有N多人把一个调用都写错,搞的我要查查文档看是不是我记错了 -____-# 2009-03-13 13:27
  3. "这里聚集了大量的中国互联网骨灰级玩家",很好奇互联网是怎么被玩的。 2009-03-12 14:59
  4. 好,毙了一个外国人哪 :D 2009-03-12 14:43
  5. 酒店是靠湖,结果房间是冲着马路的 -____-# 2009-03-11 11:22
  6. mcafee太JB招摇了。以后再也不推荐丫了。谁TM还用杀毒软件来着? 2009-03-10 19:57
  7. 猛然发现一封godaddy的中文广告邮件。 2009-03-10 14:51
  8. 忽然想,TOAD Freeware这种东西,用runas启动起来的话…试验一下,果然可以启动多个进程了 :) 2009-03-08 18:30
  9. 一个人加班倒也没啥,可以开大音乐,也比较爽,虽说这内置的破喇叭一副破锣嗓子吧。 2009-03-08 13:23
  10. 对待log这事儿真是仁者见仁智者见智。我就怕log不够回头production上去了不好分析,有些人看到server上存的没多少的以往的log还清之而后快。因为吧,我是拿各种工具以及专用的.py过滤了看,人家拿ultra edit看;我用sftp get,人家用secureCRT那个sftp客户端挨个下载。 2009-03-06 13:45
  11. 算了算了,人生下来就不是平等的。我还是sudo tcpdump去吧。 2009-03-06 13:02
  12. lusr 2009-03-06 11:10
  13. 好架构是自己不断进化来的还是一开始就能搞定的?这基本就是进化论和神创论的区别了吧。 2009-03-05 14:44
  14. 一个同事正在大谈用户体验。比较同意他的看法,也是经过实际做了几版产品才得出的看法。感觉我们产品server端所有这些繁文缛节的设计直接导致了开发时间的提升,最终很难处理这么多极端情况而不伤筋动骨,导致用户体验很烂。说白了,还是做java的人常见的那些臭毛病,加上一些长年做C++积累的死脑筋,扔一个办公室里,加上一个重型的软件开发过程,发酵2年。 2009-03-05 14:42
  15. "Oops. Firefox 因未知原因无法载入此页面。" 哇塞,头一次见这个错误页啊! 2009-03-04 21:13
  16. 看到某人名字缩写最后两个是wm就想这是个什么window manager。 2009-03-04 10:35
  17. 然后看到某人的信,问为啥没人。赶紧又跑到电话那里,拨进去,还是没人。我是不是生活在某平行宇宙里了? 2009-03-04 10:24
  18. 话说一直很好奇网站是怎么做发布以及版本控制的。没看过相关的,啥时候搜搜看看。 2009-03-03 23:52
  19. eclipse v3.4, codename 干你妹的。 2009-03-03 11:31
  20. 关掉fb2k,dismount掉这个装满mp3等等的truecrypt卷,回家。真麻烦哪~ 2009-03-02 19:06
  21. 所有no vocal的曲子都很适合睡觉前听。 2009-03-02 17:04
  22. google.com太吓人了,一搜个日本姓氏就能出来几张暴露小图。 2009-03-02 16:05
  23. 某些人读agile时发音很像阿娇 -______-# 2009-03-02 14:23
  24. 算了,反正已经开始在慢慢改了。收了别人反而跑过去随人家的姓,这也够囧的。估计几个月以后,我的简历上就可以光鲜地写上"Sr. 饮水机换桶工 at GOOD"了。 2009-03-01 23:41
  25. 看了好多Visto acquires GOOD的评论,中文以及英文,开始琢磨,你说我在这公司呆着的经历到以后会不会成为被人讥讽的对象?T_____T 2009-03-01 23:39
  26. 发现东家还是很被误解的。其实早就提供企业邮件推送服务了,这块业务比较麻烦,要求很高,相比之下对付各类倒霉ISP的事儿,虽然比较恶心,但还是容易的。 2009-03-01 21:54
  27. 这收购搞的,跟TM自己跳槽了似的。 2009-03-01 21:15
  28. 终于算已婚人士了,licensed to HAWDS :D 2009-02-28 21:55
好,就这意思吧,28条,最后一条正好是2月28号领证儿,也挺有纪念价值。http://fanfou.com/iusr 欢迎光临。

星期六, 三月 14, 2009

09絮叨篇 [0]

今年第一次絮叨这些没用的事儿吧。其实也早就想说了,只不过没有什么动机。基本上如果有人能触发我絮叨这些事,也算是有点儿本事了。
  1. 不要轻易对某个人下结论,在公司里,包括你的上司。这对我这个不可知论者来说是很自然的,不过也不是完全因为不可知。我们都活在某些程度的信息不对称当中。今天,你看到上司提拔了一个"不怎么样"的人,心里觉得不爽也好,不平也罢,反正最终归结于上司的管理水平不咋地。问题在于,一件事发生是有多种因素的:水平不咋地可以导致错误的决定,水平很好但基于各种苦衷不得不做一个错误的决定也不是不可能,甚至有可能这只是一个(你)看上去很错误的决定。大概是因为,否定别人都是很容易的事情,且无师自通。
  2. "不能轻易对某个人下结论"的范围当然包括不要张口就说"XXX他都干什么了他",如果XXX不是你的部下的话。
  3. 信息不对称的一个额外产出是各种小道消息的忠实拥趸。在一家公司内部这种相对封闭的范围内,拥有信息的人是完全可以封锁其进一步流通的,这丝毫不值得惊奇,也不值得用道德什么的批判。只不过信息封锁是小道消息的温床,对苦于信息封锁的人来说,小道消息是充满诱惑力的;同样因为信息封锁,这些消息几乎是无从考据的。当小道消息被很多人口口相传开以后,我们就可以见识一下web 2.0依托的大众参与的力量了。谎言重复一千遍的时候,能不能成为真理先放一边儿,糊弄个把人还是不成问题的。历史是怎么书写的来着?
  4. "我看人很准"。谢谢告诉我这个,也许同时还抱着美好的愿望为我们提供看人服务。不过对我这种开发时都怀疑各种第三方库然后每次都要直接debug进去的人来说,一个人到底好还是不好我肯定是不会咨询旁人的眼睛的。盖棺了就能定论了么?也未必吧。
  5. 除了高管以外,一个公司里,做管理的人就一定有高于干活的人的地位(以及工资)?我一直觉得这种看法老一辈们说说也就得了,当然保不齐80后人群里也可能会有人响应,但是,在IT/计算机/软件行业,尤其在外企里,这种说法是不是也可以成立?更不用说我已经看到N个其他公司的做管理的人来应聘高级工程师了。做管理的人需要干活的人达成目标,所以我一点儿也不着急自贬身价觉得人家高我一头。
  6. 是不是干了一年了,公司就理应涨工资,而且不能涨的太少?基本上我是反感什么"没有功劳也有苦劳"的说法的,更不要说有些人守着弱智方法傻干大干,累个半死还屁点儿技术含量都没有。为什么会有mock?怎么mock才好?一个需要事先做技术研究的解决方案,即使可以成功,似乎看起来也只能减少5%-10%左右的工作量,你会选么?公司不可能是慈善机构的。
  7. 如果让我决定一家外企公司的选址,在资金充裕的条件下,我肯定不会选择天津,虽然刚毕业的时候我确实是很为天津鸣不平。天津离北京最近,而北京那是混IT这口饭吃的人乌泱乌泱地扎成一堆儿的地方, 所以很多IT公司都会选择在北京开张,搞的天津的IT公司屈指可数,更难得有影响力的大公司。不选天津,说句难听的,是因为我总算明白了什么叫穷山恶水出 刁民——这话诸位见人见智,如果谁觉得我是在说天津就是一大农村的话我只好说您圣明了。话说最近几年天津平均工资提高了,进京往返的交通也便利多了,这种 穷山恶水的情况有了很大改善,不出多久,因为强化过的竞争外加相对更低廉的各种成本,应该会有更多公司选址天津,刁民很快也会没什么市场了。
  8. 有些人似乎习惯于要别人招之即来,挥之即去,有问题了:来,IM一下;没问题了:你谁啊。如果是同事的话,这没问题,如果还定位于朋友,有点儿太说不过去。
  9. 扮虎吃猪。记得第一次看到这个说法,貌似是在《程序员》,或者csdn.net上。其实作者也说了,不希望大家都扮得像虎,而应该成为真正的虎。不过这说法在我理解,真正想点明的还是个低调的问题。原先因为兴趣,在刚买完计算机以后接触了很久网络安全的东西,不低调?想吃牢饭么?可惜,也许见过太多扮虎的人了,原本不扮虎的也慢慢扮开了?当然也有人说我是一直在扮虎的,我可不服啊:咱俩站台上,让诸位看看谁的扮相更好,来么?
  10. 考试就全是偶然,只有为了高考而准备考试是我能理解的。费心去准备自己根本都没接触过的东西,想想都觉得实在够累。有些面试官实在是没水准,专考背书题,而背书题是最容易在短时见内准备妥当的。昨天倒是问了那个法国人一些背书题,因为大哥简历实在有些单薄,估计过滤简历的HR考虑到国际友好关系而没有在第一时间过滤出去,可我是挺习惯围绕项目经历经验问的。
  11. 没毕业的时候便被教育说应届生应聘不要挑公司,要挑适合自己的职位。对此我虽然没有深信不疑,也确实是不反对。后来很走运能遇到很多不错的同事,给了我自己发展的机会。在上一家公司工作的时候,我第一次意识到公司要求和个人发展的矛盾,所以更加确信应聘不要挑公司的这个道理。除非您干到高管,否则的话,这公司是不是几百几百强,股价能不能赶GOOG超MSFT,对您的影响能有多大?微软距离破产只有18个月,您挑公司就非挑一定能做成百年老店的那家么?我也深刻怀疑在一家公司扎根一辈子是不是就一定可以干到高管:您这也基本属于直系亲属了吧?
  12. 追求技术有错么?招谁惹谁了么?如果工作了2、3年了还觉得一个产品一个项目只要技术牛就一定成功的话,那可以算作不开窍到极致。问题在于还不具备技术就开始沉浸在技术不起决定作用的论调里,自欺欺人。没人愿意和白痴同舟共济。
想说点儿啥就说点儿啥,嘴长在自己身上不是么。成熟一些的话trackback过来。trackback是啥不用讲了吧?扮虎也别太投入了些才好。