站在自己的浪头唱自己的歌

 我知道你在问:Jack Johnson是谁?
回答很简单,一个唱民谣的。
的确,Jack Johnson对于大多数人还是一个相当陌生的名字。他没有漂亮脸蛋,没有绝世靓嗓,也没拿过什么大奖,你也不太可能在主流媒体上看到他。也许唯一卖点的就是他转入这行之前曾是职业冲浪冠军,可是显然这并不必比某些转行的电影明星那样来得引人注目。
可是这不是说他毫无魅力,相反,他是全美无数大学生的偶像。而且歌迷的数量和层次正在基于这个层次疯长。
Jack Johnson的音乐并不属于主流,显然不属于商业产品,也算不上另类,只能说是是他玩音乐的产物。可能勉强算得上是所谓College Rock,或者说是我们所说的校园民谣。这样的音乐照说是没法取得商业成功的,但是很怪异,他卖得非常好。此前他发行的两张专辑都已经是白金唱片。而白金对于这次来说恐怕只是时间问题:这张专辑3月1日发行的专辑当州打入Billboard Top100的前三,这一成绩与上张专辑的首周第3追平,可是这次的竞争显然比上次强太多;至于第二周甚至来到第二的位置,更是他在榜上的最好成绩。尽管这张专辑是他在自己厂牌下发行的。如此可见他的歌迷如今人数之众。
之前两张专辑,Jack Johnson的创作似乎一直奉行极简主义,从曲子到内容。整个听下来他的歌曲里找到除木吉他和鼓之外的乐器都是很困难的事情,讲述的也不是爱得死去活来,恨得痛不欲生,而是生活中细小得不能在细小的事情,比如开车路上看到一块路标(上张专辑On And On中的Track 16, Symbol In My Driveway)。这样的毫无所谓卖点音乐在如今的主流圈子里恐怕找不到第二个。没有华丽的旋律和节奏,但是不是说他的歌不值一听。令人惊异的他的每一首歌都是张力十足,这种张力甚至使我一连听下十几首大同小异的曲目都不会觉得乏味。因为他在音乐里谈论的一切都充满于生活的个个角落,朴实的道理娓娓道来。与其说是听他倾诉,不如是说是听他替自己吐露心声。

在VeryCD下了张叫《听见好心情》的音乐专辑,原本抱着很高的期望,只可惜听到之后,十几首歌曲里面只有这首让人心动。 网上是这么评论BreakDown的:个感觉就是比较活泼的摇篮曲,表达的却是难以承受压力的痛苦。歌中很长一段歌词押韵得很有意思,听起来很天真,跟儿歌一样。

这里下载BreakDown

整张专辑下载(VeryCD)

RamDisk-让你的大内存物尽其用

前两周去中关村加了内存,一根金士顿的DDR2 800笔记本内存190块,相当的便宜。现在我的T60已经是2GB内存,跑起一些吃内存的程序呼呼的,实在是爽!不过在大多数情况下,内存还是有一些结余的,在开了一些程序之后,我的空余内存一般都在1GB左右,如何有效的利用这1GB的内存呢?恩,没错,用RamDisk!

RamDisk可以将内存分一块出来当硬盘使用,许多频繁访问磁盘的程序例如Firefox的缓存就可以放在RamDisk指定的目录下(可以在firefox 地址栏输入about:config来配置)。我现在主要用RamDisk模拟出来的磁盘存放要编译程序,一些比较大部头的程序放在里面,编译起来速度明显要比放在磁盘上快了很多。

你还可以把Windows的虚拟内存设置到这个分区,系统性能也会有很大的提升。

软件可以在这里下载,里面有注册机,我在Windows XP SP2英文版下使用没有问题,非常稳定!

米粉&IVR&理发

米粉

每天在公司最头疼的就是吃饭问题,大楼地下一层的食堂垃圾的很,十块钱自助,只给半勺荤菜,荤菜里面还有九成是菜,一成是肉。其余自助全青菜之类,吃起来还有点苦,据同事说,青菜苦是因为不新鲜……那天同事三个人去吃午饭,说华语那边有个桂林米粉还不错,就一起去吃。店铺不大,在门口买单后找个位子三个人坐下,就等叫号了。一会就听见服务员喊“41号~41~……”连着喊了好几声,没人反应,服务员端着米粉在店里走了个来回,把桌上的单子一个个扫了一眼,终于找到那个41号,一个女的。服务员气冲冲的说:“我叫了半天怎么都不反应,你坐那发啥呆呢!”说完直接把米粉摔在桌子上走了。那个女的没想到服务员竟然如此大的脾气,她还没来得及发火,服务员都扭头走了。我们在旁边的桌子看着笑死了,吃个米粉,还要被服务员欺负,真是够郁闷的……

一会我们的米粉来了,一碗牛肉的,还有两碗忘记啥名字了。同事吃了几口,觉得奇怪,怎么牛肉米粉没什么肉呢,然后就叫服务员。那个巧的,刚好问的就是刚才发脾气的服务员,那个服务员看了眼那晚米粉,楞了下,然后说:哦,你这都吃了,我咋能看出来是不是牛肉米粉啊……三人狂晕……

IVR

老大上周让我学Tcl(一种脚本语言Tools Control Language的缩写),我看了两天,然后他分配给我个任务,做一个自动更换登机牌的语音服务系统。你打个电话进去,输入你的航班号,身份证,选一下你想要靠窗还是靠后这样的座位,系统自动给你分配一个登机牌,然后发送一条短信到你手机。到时候你可以直接去指定的窗口更换已经分给你的登机牌,挺方便的。

不方便的是,那个IVR服务器不怎么好用,我手上只有一个服务器接口函数的文档,还有几个很简单的Tcl写的控制程序。摸索了一天,写程序然后调试,一共用了三天,包括昨天早上,还跑去加班,最后终于搞定。IVR的服务器会调我的Tcl脚本,程序本身对异常处理不太好,我的脚本写的有一点问题,服务程序直接就异常退出,连个提示也没有。加上我这个Tcl新手,怎么可能键盘敲下去,一保存程序就能用,写C++都做不到。那个服务程序一旦异常退出就得重启,一般得半分钟左右,启动后我拨电话测试,按上两三个键又崩溃了,实在让人抓狂。后来没办法,只好找到一个不崩溃的点,一点一点加代码进去调试,直到整个程序调通,真不容易。

Tcl的if elseif的用法很龟毛,elseif必须跟if的结束括号在同一行,而且括号后面必须加个空格才能继续写elseif,不然程序就解释不通。之前不知道这个,调试了老半天就是找不出问题所在,后来找到了,狂晕……气的我直敲桌子。

理发

好久没去理发,理发店那个会员卡上清晰的写着,上次理发是8月19号,今天11月18号,算起来我都3个月没理发了,实在是省钱。三个月没去,那家理发店竟然装修了,以至于我在门口瞅了半天没敢进去。还好老板的小胡子我还认得,走进去才发现没错。一个毛头小孩招呼我,说话不怎么清楚,估计初中毕业吧,直接给我来了句:请问有什么可以帮您的……晕死,你说我这么老长的头发不是来剪头发,还能干啥。你又不是人家10086的客服,问题多多,直接说您剪头发不就行了么,好象学着10086说话就很职业很高档一样。我躺着洗完头,那个小孩给我头上缠上毛巾,直接给我说了句:您辛苦了……好家伙,我就洗头么,都没做啥,都是他给我洗的,还说我辛苦……

剪完头发确实爽了很多,本来LP还说要给我剪头呢,实在等不到了,再过些日子我真怕城管把我拦住说我有碍市容,有损北京形象,把我拉去剃光头,呵呵

好了,就写这么多,继续洗衣服~呼

珊珊的老公

如果你哪天在路上碰见个背着绿色的休闲包,双手握着一部全键盘的手机在投入的发短信,脸上还有幸福的微笑的家伙,恩,都不用想,那一定是我。之前舍友专门叮嘱过,走路要看路,别发短信,可是作用不大。几个月下来,除了撞过一次人以外(那个人估计是有意的),还有两次差点撞到停在路边的车,基本上练就了一身可以边看路边发短信的功夫……比较猪头

恩,我是珊珊的老公,珊珊的老公就是我:)我们跟普通的男女朋友不一样,因为我们从来不吵架,只闹别扭:( 老婆很生气,后果很严重。虽然只有两次,但每次在短信或者QQ收到:“你忙不,我有话要说”,就一阵寒颤。之后便是我主动交代问题,表决心的时间。还好,老婆对我的政策较为宽松,每次都能宽大处理, 所以现在才能在这里写这篇博客,还要美滋滋的起个名字叫“珊珊的老公”,恩,确实比较猪……

在认识GF之前,虽然也有过短暂的情感经历,但对于自己希望未来的老婆应该是什么样子,都没有想法。直到GF的出现,这一切都被改变了。她的说话的语气,她的样子,她的性格……她所有的所有让我心中那个模糊的样子变得越来越清晰,越来越亲切。我很爱她,胜过爱我自己。她每一次笑声,会象水波一样,在我的心中荡漾开来,让我内心久久不能平静。她心情不好,我心中就像压着一块大石一样,透不过气,心疼,急切的想让她心情好起来,不再难受。在我心中,我们的未来是紧紧的联系在一起的。在闲暇时,我都在考虑我们的未来,什么时候找工作,什么时候去见父母,什么时候去买房,结婚……以前觉得很遥远的事情,现在都在认真的考虑,因为我知道,这辈子,我们都会在一起,幸福的生活:)

珊珊老婆?我爱你!

一个容器设计的迷思

前些日子有些忙,一个结算项目的编码,跟女朋友闹别扭,直到今天才有时间静下心来写这篇关于上次所说的容器设计的一些问题。原本想写一篇关于自己GF的博,下一篇吧,LP看了可别生气,呵呵,我又写技术博了。

再叙述一遍需求,懂C++的程序员都知道在STL里面有Map类,里面存一个pair类型的对象,一个Key,一个Value。Key插入以后是不可修改的,Map里面的pair对象,根据Map构造函数中第三个参数决定,决定排序的方式是降序还是升序。需求中,比Map多了一点,就是在顺序迭代Map时,里面的Value是有序的,升序降序可以根据容器的第三个参数来实现。更进一步,容器还需要支持数组形式的访问。比如容器类名是SortedMap,创建一个该类型的对象:

SortedMap<std::string, std::string> sMap;
sMap[“op1”] = “avg”; // 插入Key为op1, Value 为avg的元素到容器
sMap[‘”op2″] = “ban”;
for ( SortMap<std::string, std::string>::iterator iter = sMap.begin(); iter != sMap.end(); ++iter)
// 顺序迭代容器
{
std::cout << “sMap[” << iter->first << “] = ” << iter->second << std::endl;
}

string tmp = sMap[“op2”]; // 支持容器赋值给其Value类型

这样输出后,容器中的元素是按照Value有序输出的。要支持这样的功能,我选择是用Map和Vector组合实现。Map里面保存Key和Value,在Vector中保存Map的迭代器。在插入新值后,Vector对新插入的迭代器根据其Value值进行排序。顺序迭代时,实际迭代的是Vector,通过Vector中保存的顺序的迭代器来达到输出的Map元素根据value排序的效果。其中较为麻烦的地方,是如何实现支持数组效果访问的功能。一般来讲,要支持数组效果的访问,必须在类中重载中括号,重载函数返回一个元素所存位置的引用。问题就在这里,如果要使用Map与Vector来实现这样的功能,你可以根据中括号重载后得到一个key值,但是value得值只有在引用被赋值后才能得到。而引用赋值是调用引用类型的赋值操作符来完成的,对于内置的STL类型,无法将Value与Key组合插入Map中,并将其返回的迭代器插入到Vector中这样的功能插入到该类型的重载赋值操作符的函数中,怎么办呢?
在查过一些资料之后,其实可以这么实现。

1、在SortedMap类,就是我们实现的容器中,重载中括号,并返回一个ReturnObject类;
ReturnObject<SortedMap>
operator[](const key_type& key)
{
return ReturnObject<SortedMap>(*this,key);
}
2、在ReturnObject类中, 重载赋值操作符,完成向容器中插入元素的功能;
ReturnObject& operator=(const typename T::value_type& v){}
3、增加一个类类型转换,来支持 string tmp = sMap[“op1”]; 这样的功能。
operator const typename T::value_type&()const{}
这样以来,支持了容器上述的数组访问与赋值功能,其后的迭代器功能,大家到源码里面自己研究一下吧,呵呵

在此之前,舍友就问我,为啥会有这样的需求。我也不明白,我们的组长也没具体说自己的需求从何而来,看似对自己两三周以来一个人潜心琢磨的设计十分自信。老大让这么做,那就做呗,说多了老大觉得你比较逞能,怎么可以理解他高深的设计思想。四天后,我写好了这堆代码,交给他,问他这个东西到底有啥用。他告诉我,这个东西要用到公式计算里面。他的思路是这样的:
从数据库中获得一串计算公式,比如某个过程包含三个计算过程:

a + b
step(1)*C
ste(2)*m

其中step代表上一个计算过程的结果。而我的容器所提供的功能,就是提供一个接口,通过变量名(如a)得到一个变量的值(比如1),将表达式中的变量替换,然后输入到计算器类中进行求值。我思考了以后,还是给组长说了自己的想法,在计算器类注册这些变量,这样的话,这些变量对于计算器来说,变量都是已知的,也就省去了每次替换的重复工作,况且,计算器类做变量解析的工作是必不可少的,如果在外部做替换,实际上这样的工作是重复了。
组长似乎也意识到这种做法的低效,只是说自己再看看,让我继续写别的程序。几天以后,他的计算器注册变量的功能搞定了,我的容器也没啥用了……后来他让我用抽象工厂来写一个东西,最后在他合并的程序里面,那些代码也都无影无踪,不为别的,只是因为其实所谓的抽象工厂,并不需要,只是名字看上去更专业,听起来更好维护一些罢了。真的是否需要,真的合理?只有在调用者去使用的时候,才能感受到。
所谓的程序设计,实际上是解域空间里面的一个选择问题,实现的方法千差万别,如何在性能、设计成本、开发成本、维护成本、移植成本、客户需求、时间上做权衡,找到一个最优解,确实是一个很难的问题,这个不光需要高超的技术水平,经验也相当的重要。

 代码下载