入职的话也偶尔也可以感言一把

[咱最近中了银魂毒。。这标题有木有银魂味道orz|||有木有!]

好久没有写博客了。因为都是找实习啦看房子啦搬家啦这档子事,很累人,压力很大,也没啥值得写的。

今天好不容易混进百度做了张江猥琐男,偶尔感言一把应该不会被吐槽吧。

由于机密原因,咱就不说咱在百度具体干嘛了。今天光答个弱智保密测试题就花了一上午时间。。。

反正在看android以及symbian相关的东西吧。混蛋为毛没有iphone!!!
被骗进了质量部,如果不是老大恰好去年也在微软,比较有缘的话,咱是决计不会来这边的。不过既来之则安之吧,说是测试开发,其实是写一些测试工具之类的吧,也能从另一个角度修炼自己。真呆的不爽的话,早点滚蛋就是了。

晚上骑着车逛张江,在空无一人的寂寥大道上驰骋,尽情高声唱着歌,映衬着桔黄色的路灯,滚滚红尘(黄尘)汹涌地灌进领口、袖口,大有一骑绝尘、一往无前的气势。
(背景更换|||)
然。。。忽然发现。。莫名走进了一条还没修通的荒路(怪不得空无一人来着|||)

然而,大丈夫就应该相信自己的直觉,坚定自己的信念。挫折怕什么,吃亏怕什么,走回头路怕什么。
只要勇敢地向前冲!
只要相信自己!

就能从黑暗中,走出黎明!

就像明明迷了路的咱,也稀里糊涂找到了另外一条回家的路,虽然稍微远些原先在地图上没有选定,但是却是路更平更直,而且没有那么多烦人的摩托车的路。

真喜欢骑着辆破自行车四处乱转不计方向的感觉啊~好像回到了高中那无忧无虑的年代。

咱还真是中了银魂毒了啊啊啊。。
心中某处的那啥,不知道折断没有。。。

空的xls文件反而更大

有没有哪位对微软office文件格式有研究的?

最近发现个有趣的事情,新建的xls文件有15.5KB,而假如打开,往里面写一个数据,则这个文件就会变成13.5KB。
这是为什么呢?新建的文件反而更大?

<编辑>
又做了几个实验。发现如果打开office excel然后新建-保存,则得到的将会是13.5KB的文件。
但是,如果直接在文件夹或者桌面右键-新建-xls文件,则会得到15.5KB的文件。

同样的实验在office 2007上也尝试了一下,同样右键新建的xlsx文件会更大,有9.64KB,而在程序里新建-保存的xlsx文件只有7.8KB。写入一个数据a之后,文件大小变成8.16KB。但这次不同的是,向9.64KB的文件里写入一个数据a,文件大小不会减小了,而是增加到10KB。两个文件的大小增幅都是0.36KB,这里还是应该可以看出某种规律的。

另外,对office word的测试则有另外的结果。桌面右击新建的word文件为0字节。而新建-保存的word文件为9.89KB。

</编辑>

dota与人生

最近被实验室同学拉着打dota,打得昏天暗地的,太荒废了。
不过既然玩过头了,就干脆彻底玩痛快算了。其实咱是随遇而安的典型啊。。。|||

其实dota和人生还是很像的。当然dota和人生的最大区别就是人生没有输赢而已。不过其实dota路人局,自己打得再好还是可能输,与其追求胜负不如杀个痛快。从这个角度讲,就与人生过得是否精彩可以类比了。

初期:打好基础,积累优势
打dota,前期就是拼补刀,拼走位,拼基本功。同样道理,少年时代的我们拼的就是努力,拼的就是基础。当然还有玩。很多人不懂其实玩同样是一种重要的积累,积累知识,积累判断,积累价值观。面临生死抉择的挑战,只给你几秒钟时间判断局势预测趋势,不是每个人都能整天遇到这种事情的。假如真是这样,估计神经紧张累都得累死了。然而玩捉迷藏、丢沙包,却可以随时给你这种挑战。电子游戏更是如此(例如dota。。。啊啊啊我不是给自己打游戏找借口啊|||)。
初期人和人差别不显著,只需稍微用功大家都能达到接近的水平。这个阶段要耐住性子慢慢积累,所谓细节决定成败。日后这一点点的积累将会指数级别扩大为人生的度量衡。

中期:抓住机会,团结作战,减少损失,奠定局势
中期的dota变化多端,局势扑朔迷离。这个阶段,嗅觉和灵感非常重要。在良好的基本功的积累下,在这个阶段要抓机会,配合队友打几波成功的团战,或者自己趁局势混乱单抓/迅速farm/推塔,确立优势。
同样的,青年时代的我们需要的就是机遇和挑战,需要的就是认识更多朋友,当然还有长辈,老师,学长和前辈的帮助。
现在的我正向这个阶段迈进。真要说如何做得好,我没有那个资格。不过我非常憧憬将来可能发生的团战、gank还有集中推塔。希望能和各式各样的人合作,共同创造未来,“向胜利迈进”。

后期:耐心、决心
当dota到达可怕的后期,假如游戏还没有结束,则一定会进入一个胶着阶段。任何一个小失误都可能将前面建立的优势损失殆尽。这个阶段,必须耐心。原本大优的一方,经常为了破掉一路兵强上高地,结果被团灭反扑一波带走。然而,一旦对手露出破绽,又一定要有决心,一口气拿下,决不给对方喘息机会,否则下次失败的可能就是自己。
那些在人生的巅峰奋斗着的人们,一定就是在这样的巨大压力下度过的吧。就像一盘dota能达到2个小时很罕见一样,能走到这个地步的人也很少。不知道我的未来如何呢,是成是败,是速战速决40分钟推倒,还是真的打到了超级大后期?
人生就是因为变数才有乐趣啊!

谨以此献给大学以来所有一起打过dota的同学们~~

windows下不能创建名称为con的文件

今天偶然发现的,我想创建一个叫做con.txt的文件来保存数据库连接字符串,居然提示我“指定的设备名无效”。
网上查了查,原来con是windows的控制台设备描述符,所以被保留来不能创建这个名字的文件。
同样道理,例如com1之类名称的文件也都是不能创建的。

当然,你也可以想办法创建出这样的文件,方法网上有很多,这里不说了。而且创建出来之后,就无法简单地删除掉了。(当然想要删,方法也还是有的,网上也同样有很多这里不解释了)

emacs + cygwin fail

真郁闷啊,装了cygwin还没怎么好好玩过。最近因为拆机-重装系统,暂时没装linux,就想着也摸索摸索cygwin,结果上来就给我难题。。
xemacs不太会用,关键是貌似函数名什么的都变掉了,配置文件还要重新写?麻烦啊。
于是emacs有什么问题呢?
居然ctrl-c 是默认绑定到ctrl-g上面去了。。所以怎么退出emacs啊C x C c啊。
查了查资料,原来这个问题04年就有人在问了。真的没有解吗。。

cygwin’s emacs

这里转载一下内容:

>On Tue, Mar 09, 2004 at 10:46:47PM -0500, George Hester wrote:
>>I go into emacs easy enough.  I start cygwin and type emacs and there I
>>am in emacs.  The directions say to exit type C-x C-c where C is the
>>control key.  I am assuming that is the left control key.  So I hold
>>down the left control key and type x.  I get a C-x in the lower bottom
>>of the window.  I then try C-c which is holding down the left control
>>key and hitting the c key.  Nothing.  Justy a ding.  In fact I casnnot
>>exit from emacs at all.  Does anyone have a way of exiting from emacs
>>which works?  Thanks.
>
>Either set the environment variable CYGWIN=tty prior to running any
>cygwin program or run emacs under rxvt.  CTRL-C is not remappable in
>the normal cygwin console due to windows constraints.

2 more options:
1. Run emacs under the X-Windows server.
2. Use "M-x kill-emacs", which is either:
	a. Hit the key ALT-x, then type "kill-emacs", then hit the key ENTER.
	b. Hit the key ESCAPE, then hit the key x, then type "kill-emacs", then hit the key ENTER.

-Richard Campbell.

好吧,所以结果还是可以接受的。反正emacs一般也就是一直开着他了。就让他tty设定过去也无所谓吧。

<编辑>
后来又发现这个网站,给了一个更好的解决方案~~
Cygwin

Cygwin下的Emacs不能退出的问题
Xemacs就没有这个问题
 
需要在cygwin.bat里面加进:
@echo off
set CYGWIN=binmode tty ntsec   #加进这句话Emacs就能正常退出了
g:
chdir g:\cygwin\bin           #$PATH/Cygwin/bin/
bash --login -

问题解决~~
</编辑>

圆周率节转圆周

上帝啊。。。我终于复活了!(是我家CQ…|||)
本来3.14节想出了一个挺好玩的想法,想实现一下,结果准备重启进入linux的时候机器就挂了orz|||
反复重启。光驱引导不能。
是BIOS病毒吗?

已经是晚上了,等不及送修,居然真的自己动手拆起机器来了!

真可惜啊,心情太焦急了居然没有心情拍照。人生第一次推倒啊(compaq娘|||

拆掉屏幕,拉下键盘,掀开后盖。取下风扇,拿掉散热片。CPU和显卡明晃晃地立着。为什么就是找不到CMOS线啊。。。
找到了个形似开关的东西按了几按。这样好像跟重置BIOS毫不相关吧。。
拆得这么零碎,真的还能组回去吗?组回去真的还能用吗?

还好。网上的攻略很给力……除了多出几个螺丝不知往哪里按,基本上都装回去了。尽管。。尽管原本的开机重启的问题完全没有解决。。
本来绝望的心冷静下来反而清醒了。重启或许只是硬盘本身的故障呢?光盘引导不能或许只是因为光盘没有读出来,所以又默认从硬盘引导,然后又重启了而已呢?
拔掉硬盘后再试光盘引导,果然不是反复重启的症状了。所以。。所以到头来无非是。。光盘太脏这个缘故吗。。多吐两口涂抹擦擦干净。。居然真的就进了live CD了。。。

转了一大圈,又回到原地。果然只不过是硬盘分区表损坏而已,什么BIOS病毒的。。都是自己胡诌啊胡诌。
或许。。或许我只是想找个借口拆拆本子吧。从来还没拆过本本的人。。

可惜这不明情况的分区表故障,貌似导致了grub无法识别硬盘,所以最后还是不得不重装系统了。。
所以本来圆周率节那个挺好的想法,只好留到其他节日再做咯。。。|||

啊哈哈凑足30小时无睡眠时间,好啦洗澡爬床~~

linux内核学习 – C风格的面向对象

linux内核大量使用面向对象的编码风格。然而linux内核是完全使用C写就。学习他们如何使用C模拟面向对象机制很有意思。这种做法很可能被人贬为扯淡,但是的确使用C模拟面向对象机制,使得程序员对类型构造/析构,拷贝/赋值等操作有了绝对的控制权,可以提高对效率的嗅觉,减少错误,同时也避免了对C++编译器各种不同类/对象实现机制的依赖。

类的多态特征是linux内核经常用到的。例如在驱动代码中常常使用函数指针来定义一组设备操作函数,从而模拟了多态的特点。


struct file_operations scull_fops = {
    .owner = THIS_MODULE,
    .llseek = scull_llseek,
    .read = scull_read,
    .write = scull_write,
    .ioctl = scull_ioctl,
    .open = scull_open,
    .release = scull_release,
};

上面的例子是Linux Device Driver中抄来的示例代码。很好地展示了file operation结构体如何使用这种机制来定义一组文件操作的方式。用这种方式,Linux很好地贯彻了所有的设备都是文件这种概念。不同的设备可以有不同的处理函数,但使用相同的接口,这样就把底层设备的差异在文件系统这一层隔离开来了。

Linux内核中也经常用到类的继承关系。这种关系使用C也很容易模拟,就是使用结构体嵌套。例如


struct scull_dev {
     struct scull_qset *data;   
     int quantum;               
     int qset;                  
     unsigned long size;    
     unsigned int access_key;  
     struct semaphore sem;     
     struct cdev cdev;      //内嵌linux内核定义的cdev结构体
};

这个例子同样来自LDD。注意在自定义的cdev字符设备结构体中包含了struct cdev cdev成员。这个成员同样是一个结构体,由内核定义,是字符设备描述符。使用这种方式,可以一定程度模拟C++的继承机制,当然有他的局限,例如他不能如同在C++中一样直接引用cdev的成员,而必须通过scull_dev.cdev来引用。

另一方面,这种方式也无法通过“基类”,即cdev的指针,访问“子类”,即scull_dev的成员。精彩的部分来了,linux通过一组宏,巧妙的实现了这一点。在文件处理的函数中,入参会给入inode指针,从这个指针可获得其cdev成员。如何从这个cdev成员获取包含它的“子类”对象,scull_dev的指针呢?

container_of(ptr, type, member)

使用这个宏,container_of(inode->i_cdev, struct scull_dev, cdev)就可获得包含cdev的scull_dev的地址。这个巧妙的宏是如何实现的呢?

#define container_of(ptr, type, member) ({ \
                const typeof( ((type *)0)->member ) *__mptr = (ptr); 
                (type *)( (char *)__mptr - offsetof(type,member) );})

这个宏首先定义一个指向结构体成员的指针__mptr = (ptr),他的类型是const typeof(...)。这里用到了C语言一个较新的关键字typeof,可以在编译期获得变量的类型。而这个类型是((type*)0)->member,这里type和member分别是宏传入的参数。这一行代码就比较清晰了。得到这个__mptr之后,将他向回移动一个offset,(char*)__mprt - offsetof(...),而这个offset恰好为member相对于type的偏移量,offsetof(type,member),则移动完毕__mptr就指向type类型的起始地址了,只需将其转换为type*类型就可以了,(type*)(...)

好了,这个宏已经看懂,神奇的地方就出在这个offsetof宏了,他是如何计算成员相对于结构体的偏移量呢?这里linux内核hacker们用了一个小小trick。

#define offsetof(s, m)   (size_t)&(((s *)0)->m)

是的,代码非常简单。其思想是,假如结构体处于0地址,获取其成员的地址。这个地址就是成员相对于结构体初始地址的偏移量了。没错0地址是不能运行时访问的,但这句代码只在编译期使用了0地址,因此是合法的。当然其实使用成员指针和结构体指针相减也可做到,但用这种方式可以减少一次运算,确保了这个宏可以在编译期求出结果。可谓是精益求精。

我说错了。即使使用减法也可以做到编译期求值,因为结构体和成员指针地址都是可以编译期得到的,常量数值计算应该可以做到编译期优化,计算完成。这种做法应该是
&((type*)0)->member - ((type*)0)
这样的代码的一个直觉性的优化,减0的话,何必还要减呢。事实上两句代码的运行时间是一样的,但这样做可以减轻编译时间。
在container_of宏中,也有一句减法计算。这个计算引用了运行时求值的__mptr,所以无法做到编译期求值。

类似这种用法,在linux内核中经常出现。深深佩服大牛们的创造力,并且深深的意识到了即使是C语言也是学无止境的。

远程解析DNS躲避DNS污染

我发现我前两天发的博nslookup-解决ssh隧道无法访问twitter很受大家的欢迎,sjw同学也说到,其实使用OpenDNS就可解决这个问题。

因为我之前尝试过OpenDNS仍然发现问题,才出此下策的,因此专门去研究了一下,发现其实@williamlong有一篇老文,早就可以解决这个问题。OpenDNS不能解决DNS解析错误,而这文的解决方案,比我提出的要简单许多,就是使用远程解析DNS。

关于如何使用远程DNS解析,月光博客提到了firefox的启动参数。至于我所喜爱的chrome,网上的讨论也很多。具体的方法就是使用sock代理和switchy扩展的自动模式(auto switch mode)。当然,正如sjw同学提到的,使用vpn的同学直接使用墙外dns就可以了,有些客户端似乎是默认使用本地dns,可能是需要配置一下的。因为我不用vpn所以不是很了解。
我找到的比较好的参考是这篇chrome 扩展: Proxy Switchy!之图解使用方法和这篇在 Chrome + Switchy 下使用 AutoProxy gfwList PAC这篇正是来自autoproxy的博,下面回复讨论很多,很值得看。而这一篇关于 SOCKS 代理的远端 DNS 解析的讨论则可让我们把一些原理搞得更清楚。