08 2010存档
爸以前跑车,曾经在养蜂人那里买了一些野蜂蜜,香味扑鼻、非常浓稠,气温偏低就会结晶,确是正宗好蜂蜜。
我睡觉不沉,喝蜂蜜可以安神助眠,所以用量不小。现在蜂蜜快喝完了,爸又不可能为了买蜂蜜再回一趟家乡,超市里的蜂蜜不用考虑了,不知道兑了多少水,看着跟糖稀似的。琢磨着在北京附近有没有散装的好蜜出售。
于是乎,周五爸妈去了趟香山,顺路去了植物园,买了些蜂蜜。
我尝了尝新买回来的蜂蜜,也很香,喝了一点,
“不错,好甜......比家乡的那个要甜的多”
“可能是品种不同,不同的花,产出的蜜不一样” 爸一边回答一边看盒子上自己贴的标签:“这是枣花蜜......嗯,这是荆条蜜......”
家乡的蜜香味重甜味淡,似乎更极品,是什么花的蜜呢?我好奇的拿起老瓶子看了一眼标签,上面写着——
“遵义蜜”
我们的API用户已经使用了快一年了,还从没遇到这种情况,多半应该是用户使用上的问题。所以我下楼去看看。
客户的问题很容易重现,但是我写了个一样的例子,却没有这个问题。
“我的例子跟你代码几乎一样啊”我问。
“是啊......不对,有点不一样,你是多进程,我是多线程的,你们的API里用到了read,而且还判断了errno是吧,errno在多线程下岂不是互相影响?”
他这么一说我还真有点怀疑了,虽然API已经被用了一年,但大多数人都是用的多进程(unix的优秀习惯,噢),这可能是大家都没发现这一问题的原因。
我跑去问架构师,说了一下我的怀疑。
“不会吧,linux上系统调用都有可能影响errno,那任何一个多线程程序岂不是都有这个问题?”
“对啊。。。”
我这个人很动摇,两头都在说我就两头都在晃。
架构师查了查errno的man,确实,errno是“thread local”的,一个线程一个errno,不会互相干扰。
干脆回去把我的例子改成多线程的,依然不能重现,这下就不是多线程的问题了。
最后用户突然想起他们有个线程比较特殊,它@X%X%@#¥%……&*,还是API使用上的问题。我松口气。
从panic的信息看,是在dcache_readdir的时候,就是从cache里读各inode的时候遇到麻烦了。
kernel本身是很坚固的,肯定是我的module某个地方把cache里的东西弄坏了,想想我确实有遍历目录的操作:
您好!
我是xxx,上周二去贵公司面试了实习生的职位。到今天已经一周了,还是没有得到通知,应该是面试没有通过被默拒了吧。自己等的也比较着急。
还是想冒昧的问一下:在面试时应该怎样表现,或者是怎样准备知识更好,能否给点建议。说实话,这三周实习的过程中悲剧了几次,但都不是很清楚企业筛选的标准。
如果您有时间,就简单回复下吧。谢谢!
我回了邮件,原文贴在这里,一字不改:
您好:
我刚问了leader,确实是拒了。
就我个人来说,我觉得你的面试表现不错,基础知识比较扎实,回答也比较迅速得体,我挑不出什么明显的问题。但是,我只是公司一个普通程序员,不是管理层,决定不了你的去留。我问了你被拒的原因:各个项目组需要的是迅速能上手的人或者说专业对口的人,你专业不够对口,同时缺乏项目经验。
你可能会觉得不公平:本来我就是找实习,怎么还要项目经验??本来我学的是软件工程,做的就是软件,有什么不对口的? 这个问题我也没有办法回答,我当年找实习一样也有这样的愤慨,但是世道艰难,5年了,也没人回答我。
你邮件里的意思,你已经找了三周的实习而没有结果,这个你不用着急,我也是软件学院的,05年找实习的时候,花了将近两个月,面试过intel、sun、IBM还有很多你根本没听说过的小公司,最后是在3721公司(就是那个著名的流氓公司)实习。
现在世道艰难,招聘公司也是挑肥拣瘦,所以花的时间肯定是越来越长,你的基础不错,所以不要太着急,小公司(甚至流氓公司)实习也可以考虑,只要是工作能长经验就好。
对了,我们核心系统组拒了,但是测试组还在招实习生,你个人愿意干测试工作吗?相对开发工作,是要枯燥一些。
妈:昨晚热得不行了。我吹个电扇,你爸又嫌冷;我盖被单,你爸盖被子,没法过了。
我:要不买个空调吧。
妈:你爸吹个电扇都怕,还空调?!
我:这样,空调买回家,不用安装,内机对着你吹,外机对着爸吹,这样都满意了。
家里办理宽带通,两年,妈叫他们送点礼品,宽带通的人说没礼品,还说歹说送了个金山的杀毒软件。
几天后,家里的小床腾了出来,打算卖掉。
我:单卖可能卖不了多少钱。
妈:那就把床垫搭送了。
我:也没多少钱。
妈:那就买单人床一个,搭送杀毒软件一份。
过去几个月自动化测试跑得都很顺利,太顺利了,每天都没有fail。
写这些用例的人有些离职了。
现在项目有大改动,很多自动case跑fail了,我们知道是哪个case fail,但是,这个case具体是做了些什么才fail的呢?没人知道了,测试人员、包括开发人员,都只能去看自动测试的code来找出原因和重现方法......这样,所谓“自动化测试”,变成了“半自动化测试”??虽然你能告诉我某个case出错了,但你没有告诉我是怎么出错的、怎样重现?
最基本的解决办法是在自动化测试的code里加入足够的用例说明,如果fail了,至少可以很快知道怎么去手工重现。唉,慢慢改吧。
内核模块里自己做了一个简化版的 find_get_page:
struct
page * my_get_page(struct address_space *mapping, unsigned long
offset)
{
struct page *page;
read_lock_irq(&mapping->tree_lock);
page =
radix_tree_lookup(&mapping->page_tree, offset);
read_unlock_irq(&mapping->tree_lock);
return
page;
}
代码是从2.6.18的内核里抄来的。
在2.6.9内核的xen虚拟机上测试,现象很诡异:服务器的ssh连接突然断开,只能重连,重连后看见模块被自动卸载掉了。仔细看代码,才发现2.6.9内核的struct address_space里的tree_lock是spinlock_t,而不是rwlock_t,结果我的代码就是对着一个spinlock_t调用read_lock_irq,锁操作不对,然后又发生了什么呢?
read_lock_irq 调用了 _raw_read_lock:
static inline void _raw_read_lock(rwlock_t
*rw)
{
#ifdef CONFIG_DEBUG_SPINLOCK
BUG_ON(rw->magic !=
RWLOCK_MAGIC);
#endif
__build_read_lock(rw, "__read_lock_failed");
}
喔,kernel会判断锁的magic number,不对的话会调用BUG_ON(),进而调用BUG(),所以机器打了个嗝。
如果没有这个magic number的检测,一旦死机,错误就更难找了,这个检测虽然很土,但很体贴,也很有效。