2007-05-17

Girls in IT

昨天一个低年级的小师妹问我,除了C语言、算法、Java之类的还应该学些什么比较好。这还真是个问题,不好轻易回答,万一指错了方向可是会耽误人家一辈子的幸福的,得好好思考一下。

总觉得IT这个坛子是男人的天下,艺术人文就不说了,搞化学的还有居里夫人,但搞计算机的还真没几个有名的女性。

尤其对于编程这种和感性根本不沾边的东西,实在不适合她们。你能想象一个女生赶项目连着几个星期不睡觉不洗澡地熬夜,满脸胡须发行狂放的样子么?

好在IT行业包罗万象,不是只有程序员可做。销售,项目文档管理等工作还是很适合细心的女生的。

基于以上观点,我给她列出了如下三个方向:

1、工程路线:

学软件工程,增强交际。然后找个大的软件公司去做销售或者文档管理,诸如东软,中软等公司。

2、学术路线;

接着好好学算法,读研、读博一路读下去留校或者去别的学校教书。

3、性感路线:

学化妆、美容、穿衣、泡男人。最后找个IT钻石王老五把自己给嫁掉。

隔着QQ,我也不怕被她打,自然畅所欲言。其实第三条路对于天下所有漂亮女生都是通用的,如果相貌是在不行,那真的很抱歉,估计前两条路也很难走。

现实中,很多女生都选择了考研,毕竟这条路不需要改变生活方式,是最轻松简单的一条。但两年研究生毕业了她们和本科生又有什么区别呢?在男女比例失调的工科学校,她们都已经被宠坏了。上上学期实验室期末总结,方式为轮流发言,两个女生说在实验室做项目太苦太累,到最后竟然凄然泪下。我和身边的男生面面相嘘,觉得这简直太不可思议了,哪有那么紧张,我明明觉得轻松无比嘛!

和师妹聊到最后她也没告诉我她想做什么,我想在毕业前她会知道自己适合的角色的。

2007-05-02

myspace.cn

前些天在donews上看到传说中的Myspace的中国版MySpace.cn开张了。忍不住好奇,前往一睹芳容。

打开网站主页就是失望,又土又丑。可能是为了庆祝五一和即将到来的夏天?还弄了个蓝天白云海水的背景,和页面上的内容结合的非常突兀,满满的QQ空间自定义背景的感觉。整个页面的规划布局也是乱糟糟的,怎么看怎么像刚学会计算机的高中生用FrontPage画出来的。

难道老美的myspace也是这样的?打开myspace.com发现干净多了,风格和facebook有些像,走简约风格,配色和页面布局都很顺眼,再看德国的,加拿大的,日本的都和myspace.com本家风格一致,怎么到了中国就变得这么难看?

圣卡尔教导过我们,在遇到问题的时候与其考虑是别人的毛病不如先认为是自己出毛病了。上过马哲思修课的我在第二时间想到了是不是我审美观的问题。

上google搜一下,关键字为“myspace.cn 丑”。返回结果的第一条为“myspace.cn露出真面目丑媳妇也要见公婆_TOM科技”,看来不是我的问题了,大家觉得丑那就是真的丑,对不住了。

或许有另一重可能,就是人家比较内秀,好东西都在里面,于是鼓起勇气注册一个账号继续探险。

注册时需要我填了一个常用的yahoo.com.cn的邮箱,结果提示这个邮箱不可以使用,faint,为何要歧视yahoo?
注册完成后需要填写一些用户信息,妈的文本编辑框竟然默认不支持Firefox,好在有替换选择,但只能输入最简单的文字信息。注册完成之后随便逛逛,发现原来表里如一,里面同样不堪入目。搞个文件夹图片当论坛板块的图标,还是十足的业余气息。

在关掉这个网站前我做的最后一件事是找怎么能删除我的帐号。点了数次鼠标,还需要电子邮件确认才能删除。OK,彻底服了。

想想msn中国,yahoo中国、google.cn的惨淡经营,现在又多了一个myspace.cn(预期失败者),看来中国真的很不适合国外互联网巨头前来觅食。

但这一切又是为什么?橘生南则为枳?只是这苦涩的枳之果不知道要谁来咀嚼要谁来咽下。

2007-04-22

作家 vs 诗人

昨天和04的师弟师师妹一起吃饭,席间说说笑笑的挺开心的。

坐在身旁的是一个浙江的女生。身处异乡嘛,虽说她属越国我属吴国,但怎么说也是同属江浙人士。难得碰到个习性相似的,言谈自然比较投机。我们一起回忆了一下南方的各种趣事,譬如说钓龙虾,北方是绝对没有的。同时我们还嘲笑了一下北方单调乏味没有内涵的过年方式。当然只是调侃而已,南北文化差异的背景下,各自觉得对方的不合胃口,也是再正常不过啦,人家还觉得南方过年没有北方的气氛呢。

饭过三巡,突然有人问,校报上我发表的一篇文章是怎么回事。当时我愣了一下,文字倒是写过几篇,散贴于学校论坛之上,但是实在称不上是文章,只能算是技术讨论而已,以校报主席提名的高端姿态,则能俯就刊登吾等无名之辈之絮语?

回到寝室就到处找报纸,我们寝的被垫着吃盒饭了,满是油渍,不忍卒读。从隔壁寝室搜罗出一份来,一看原来是在中软实习时写的一篇实习报告,不过删改颇多。
原文开头一段稍微抱怨了一下倒中软两三天才真正进入实训阶段,被改成了“迅速进入了实训阶段”。中间评价组员们的表现时批评了一个队员没有按时完成任务,也被删去,改成了“完成的稍晚,但也能看出其非常认真。”看到自己的文字第一次变成铅字,感觉的确不错,同时也体验了一下自己的文章被审查删改的无奈。

下铺猛男在大一的时候曾经给青春校园匿名投过一首情诗,被选中刊登,从IT民工荣升打工诗人,但后来江郎才尽,再无建树,现在正专注于一款画面糟烂的2D的网络游戏。现在我也从平民一举跃升为作家,自感地位陡升,翻身下床,欲与之攀谈研究文学之事。
但无奈室友们得知这个消息后只是表示了一下祝贺,除此外毫无敬仰之情,继续面向屏幕,弄得我好生失望。于是忍不住转而调侃之:新时代的诗人越来越不争气,写诗写到最后就成了赵丽华。下铺猛男最近疏于阅读八卦,竟然没听说过梨花体,但听我的口气便知道不是好话。开门见山就是一句“想死啊。”,杀气十足,秀才遇到兵有理说不清,我只得乖乖闭嘴。

我的妥协是有着深厚的历史原因的。

下铺猛男天生好身体,体壮如熊,我和他每次直接对抗都是失败而归。但诗人不如作家,多半不会诡辩。占着这个优势,对我来说自然武斗不如文斗。我时常用各种比喻恶心他。大家都是文明人,他也不能总是一言不合就动手,能忍则忍。于是我就时常在他爆发与不爆发的边缘游走,并乐此不疲。当然偶尔也有失手的时候,结果自然很惨。今天其竟然没有按照惯例先忍一下,直接向我发出死亡威胁,可见心情不好,见好就收,乃智者之所以为智也。

说到这边貌似走题已经走到十头牛也拉不回来的程度了,也罢,就此收笔~

–EOF–

2007-04-19

Real Folk Blue

终于把Cowboy Bebop的二十六集全部看完了。

剧终之时,我陷在深深的失落中难以自拔。

这和前些日子脑子里的一个念头有关。

一个人的力量究竟能有多大?

我也不知道是这个念头是怎么找到我的,但细细想想这真不是一个好回答的问题。

一个人的力量能有多大?大可以如商紂般葬送一个国家,中可以像周杰伦一样养活无数小报记者,小可以像我这样为导师写程序,卖出去后他拿几百万我拿几百块。

每个人都为自己的或者他人的命运忙碌着。

但无论如何,这一切的意义又在哪里?

当看到spike和jet站在bebop号的舷窗看着ED离开时在甲板上写下的goodbye,我发现我暂时失去了生活的动力。就像spike,无力地追寻着一份缥缈的爱情,被人追杀去做一名赏金猎人。奔波在各个星球之外。我想支撑他活下去的唯一理由就是julia,但当这个唯一的理由最终消失时,spike已经别无选择。

再问一遍自己,生活的意义在哪里?我实在找不出来。

“这是一个梦吧?”
“对,是一个噩梦”

生活是如此的撕心裂肺,以至于我们无法分清眼前的一切是真实还是梦境。

“我只想证明一下我是否还活着。”

生活的目的又是如此茫然,以至于我们无法知道自己是否还活着。

spike不强大么?但在命运面前同样找不到方向。

hard luck woman ,fay是不羁和凌厉的。她的生活是为了找回回忆,可当记忆回来后却发现自己依然一无所有,除了在太空中流浪的bebop 号,无家可归。

那么,强大又有什么意义?

当无路可走时,抛开这一切,来一曲blue吧。舒缓的吟唱是所有人的归宿,即使只有三分钟而已。

2007-03-26

当当购物历险记

当当购物历险记

2007-03-26

IE 6 bug on hr

最近又遇到一个IE6的bug 🙁

<hr />
<img src="CG_title.jpg" alt="" />
<hr />

这段代码在Firefox下一切正常,可是在IE 6 中却是惨不忍睹。

在Firefox 1.5中:firefox_normal同样的代码在IE 6中的显示效果:ie_normal

而且可以发现,无论用各种方法都无法调整hr的上下边距。

为此我在google中搜了好长时间,最后在ms的网站上找到一篇机器翻译的文章,读起来极其恶心,但好在代码还是能看懂的。

解决方法是用经css修饰的div来代替hr标签,代码如下:

div.HrRule {
    border: 1px solid #C0C0C0;
    background-color: #C0C0C0;
    height: 0.5px;
    margin-top:0.5px;margin-bottom:2px;
    width:100%
}
div.HrRule hr { /* for CSS1 browsers */
    display: none;
}
div.HrRule * { /* for CSS2 browsers */
    display: none;
}

<div class="HrRule"><hr /></div>
<img src="CG_title.jpg" alt="" width="100%" />
<div class="HrRule"><hr /></div>

修改后的效果:

Firefox 1.5firefox_modifiedIE 6firefox_modified

虽然在Firefox中,hack过后的代码中的灰色横条看起来比上面的宽了些,但为了兼容,只能忍受了。

感叹一下,本来好端端的一个<hr />就能搞定的事情,现在却添了这么多代码,效果也不如原来。

但转念一想,现在写前端代码应该还算是比较容易的,毕竟需要中国程序员考虑的也就是IE6和Firefox两个浏览器而已,IE6 bug虽多,但这么多年无数的程序员的积累下,大都已经被找出来了而且基本上都有了解决方案,在可以控制的范畴之内。

真正的炼狱时代,应该是在IE 7、IE 6和Firefox三分天下的时候,苦命的coder不仅要对付古怪的IE 6、注意不知底细的IE 7还要努力与Firefox兼容,呵呵,恐惧中。

2007-03-26

当signal遇上exec

一般来说,多进程环境下的Linux程序,子进程是继承父进程的信号处理方式的。也就是说,如果在父进程中为某一个信号指定了处理函数,那么子进程在收到这个信号时同样会调用这个处理函数。

举例如下:

#include <signal.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <wait.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <time.h>

void handler(int signum,siginfo_t *info,void *myact)
{
    fprintf(stderr,"receive signal %d\n", signum);
    fprintf(stderr,"Signal is sended by %d as reason : %d on error: %d\n"
                    , info->si_pid,info->si_code,info->si_errno);
}

int main(int argc,char**argv)
{
    struct sigaction act;

    sigemptyset(&act.sa_mask);

    act.sa_flags=SA_SIGINFO;
    act.sa_sigaction=handler;

    if(sigaction(SIGUSR1,&act,NULL) < 0)
    {
        printf("install sigal error\n");
    }

    pid_t pid=fork();
    if(pid == 0)
    {
        for(int i=0;i<100;i++)
        {
            if(i==5)
            {
                fprintf(stderr,"Send SIGUSR1 signal......\n");
                kill(getpid(),SIGUSR1);
            }
            else
            {
                fprintf(stderr,"Sleeping......\n");
                sleep(1);
            }
        }
        return 0;
    }

    fprintf(stderr,"Child Process id is : %d\n",pid);

    wait(NULL);

    return 0;
}

但很多情况下需要在fork之后在子进程中调用exec族函数来执行一个新的程序。那这种情况下,父子进程对于信号处理的继承关系又是怎样的呢。

将上面的程序改动一下。

main.cpp:

#include <signal.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <wait.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <time.h>

void handler(int signum,siginfo_t *info,void *myact)
{
    fprintf(stderr,"receive signal %d\n", signum);
    fprintf(stderr,"Signal is sended by %d as reason : %d on error: %d\n"
                    ,info->si_pid,info->si_code,info->si_errno);
}

int main(int argc,char**argv)
{
    struct sigaction act;

    sigemptyset(&act.sa_mask);

    act.sa_flags=SA_SIGINFO;
    act.sa_sigaction=handler;

    if(sigaction(SIGUSR2,&act,NULL) < 0)
    {
        printf("install sigal error\n");
    }

    pid_t pid=fork();

    if(pid == 0)
    {
        execlp("/root/test/sigusr","./sigusr",NULL);
        return 0;
    }

    fprintf(stderr,"Child Process id is : %d\n",pid);

    wait(NULL);

    return 0;
}

将原来子进程中的语句放到一个新的文件中,并将其编译成sigusr可执行文件 :

sigusr.cpp:

#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <sys/types.h>

int main(){

    for(int i=0;i<100;i++)
    {
        if(i==5)
        {
            fprintf(stderr,"Send SIGUSR1 signal......\n");
            kill(getpid(),SIGUSR1);
        }
        else
        {
            fprintf(stderr,"Sleeping......\n");
            sleep(1);
        }
    }
}

编译执行main.cpp可以看到,子进程打印了五条sleeping……语句后就退出了,并没有调用父进程指定的信号处理函数。

分析:

1、fork生成的子进程中继承了父进程所有的数据,当然包括信号处理函数的入口地址等信息,所以当子进程继承父进程的信号处理方式不会出现问题。

2、fork后调用exec后发生了什么呢?

open group上的exec的文档是这么说的 :

The exec functions replace the current process image with a new process image. The new image is constructed from a regular, executable file called the new process image file. There is no return from a successful exec, because the calling process image is overlaid by the new process image.

exec 后,系统用参数指定的可执行文件的映像将原由子进程完全替换掉,只留下进程号等一小部分信息不变,这样的话在exec后子进程中已经不存在父进程中的数 据,子进程也无法得知父进程信号处理函数的入口地址。在这种情况下,继承父进程的信号处理机制也就无从谈起了,因为这是不可能的。
但有一个例外情况,那就 是如果在父进程中将对某个信号的处理方式设置为忽略(SIG_IGN),那么exec后的子进程会继承父进程的设置,在子进程中忽略这个信号。因为设置为 忽略的话就不涉及到寻找处理函数入口地址了,这是可行的。

Open Group对此的描述如下:

Signals set to the default action (SIG_DFL) in the calling process image are set to the default action in the new process image. Signals set to be ignored (SIG_IGN) by the calling process image are set to be ignored by the new process image. Signals set to be caught by the calling process image are set to the default action in the new process image. After a successful call to any of the exec functions, alternate signal stacks are not preserved and the SA_ONSTACK flag is cleared for all signals.

再引申一下,还有一种情况需要注意,如果在父进程中调用了atexit()函数,那么在exec后的子进程中同样会失效。原理和前文所述的信号设置是一样的 🙂

–EOF–

参考文档:
Open Group The Single UNIX ® Specification, Version 2,exec:
http://www.opengroup.org/onlinepubs/007908799/xsh/exec.html