博文

目前显示的是 一月, 2010的博文

今天发生的一件很寒心的事情

2009年最后一个月的工资发了。连带未休的年假的补贴一起。
某同事(ljf),因为08年实习的时候请了半个多月的假回学校答辩,导致09年没有年假。hr的理由是他08请假太多了,而事实是当时他还未入职,连劳动合同都没有。实习期之后签劳动合同之后才是漫长的试用期
另外一个同事,说他年假的天数不对。hr答曰:第一年没有年假,第13月开始每个月有5/12天的年假。于是我的同事就拿出劳动法理论,说他今年不是第一年工作,hr就要求该同事找管档案的开据劳动证明说明今年不是第一年参加工作。我同事问为什么入职的时候的离职证明上的日期不能算,答曰:不算就是不算。
你说这算什么事儿啊这!
一切福利待遇都按劳动法的最低要求来,工作环境比我老家的网吧还拥挤、空气比那网吧还差。好不容易中秋节想起来关怀下员工,每人发了2个月饼,很普通的月饼,结果,这月饼还是因为质量不合格被强迫从超市下架的,细菌含量超标。
但并不是央企就好。某同学说,他们从来没有不休年假就补钱的说法。所以有机会一定得休。也是啊,你说,国企什么时候缺人干活了?

宽带运营商无耻的404劫持

从freebsd的网站,按照如下网址下载一个软件(一个屡次被多种杀毒软件报告为盗号木马的聊天软件)#wget -c 'http://www.freebsd.org/yy-2.1.2.exe'--22:58:20-- http://www.freebsd.org/yy-2.1.2.exe> `yy-2.1.2.exe'正在解析主机 www.freebsd.org... 69.147.83.33, 2001:4f8:fff6::21Connecting to www.freebsd.org|69.147.83.33|:80... 已连接。已发出 HTTP 请求,正在等待回应... 302 Found位置:http://219.239.26.5/download/2203814/3118780/1/exe/1/117/1260924550401_373/yy-2.1.2.exe [跟随至新的 URL]--22:58:20-- http://219.239.26.5/download/2203814/3118780/1/exe/1/117/1260924550401_373/yy-2.1.2.exe> `yy-2.1.2.exe'Connecting to 219.239.26.5:80... ^C事实上,这个文件是根本不存在的。还可以随意的修改网址,只要保证依然是以这个文件名结尾# wget -c 'http://www.freebsd.org/sfdaii234/yy-2.1.2.exe'--22:59:30-- http://www.freebsd.org/sfdaii234/yy-2.1.2.exe> `yy-2.1.2.exe'正在解析主机 www.freebsd.org... 69.147.83.33, 2001:4f8:fff6::21Connecting to www.freebsd.org|69.147.83.33|:80... 已连接。已发出 HTTP 请求,正在等待回应... 302 Found位置:http://219.239.26.5/download/2203814/3118780/1/exe/1/117/1260924550401_373/yy-2.1.2.exe

打包并加密

打包并加密:
tar -cvf - myfiles | openssl enc -des > myfiles.tar
解密并解压:
openssl enc -des -d \< myfiles.tar | tar -xvf - -C /tmp
优点:
1、所用的所有工具都是开源的,不会有后门。
2、多种加密算法可选。

thunderbird关不掉的问题终于找到了

我的thunderbird最近一个月总是关不掉,窗口叉掉后进程还在。只能强行从taskmgr中杀掉。否则不能打开新的今天在卸载所有addon之后问题依旧。最终发现,原来是因为我在安全设备中加载了一个第三方的pkcs11 dll,而那个不能正确卸载。

huge page

使用大页面最大的好处是提高TLB的命中率。对于单个进程,它可以一部分内存是4K的大小page,一部分内存是2M大小的page。操作系统本身在kernel mode下已经很广泛的使用大页面。windows下在C/C++程序中使用大页面:
http://msdn.microsoft.com/en-us/library/aa366720(VS.85).aspx要让linux支持大页面,需要在编译kernel的时候打开CONFIG_HUGETLBFS和CONFIG_HUGETLB_PAGE (在file systems下)
具体参见:http://www.mjmwired.net/kernel/Documentation/vm/hugetlbpage.txtlinux/windows下在java中使用大页面:
http://java.sun.com/javase/technologies/hotspot/largememory.jspfreebsd对大页面的支持是从7.2开始的。用sysctl设置vm.pmap.pg_ps_enabled=1,操作系统会自动选择page size。因为这个也是最近一两年新加进来的,所以文档比较少。至于数据库中的PAGE_SIZE为什么通常是4K,这个是为了保持和文件系统的block size保持一致。在class PageFile中使用pread/pwrite读写文件的时候,操作系统首先会去文件系统的cache里面查找。如果db.h的PAGE_SIZE小于文件系统的block size而这部分文件内容又不在cache中,可能会导致操作系统必须先执行一次read操作把数据读出来,然后modify一部分,然后写入磁盘。如果db.h的PAGE_SIZE大于文件系统的block size,会导致单个page的读写在kernel中需要执行多次read/write。在linux下用xfs_info可以查看xfs的block size,bsize字段就是。

2010-1-8

BUG就像肉刺,拔出来后顿时神清气爽.今天找到一段奇怪的代码,加-O2编译就正确,不加就有可能会segment fault。我一直以为c++0x是200x,呃……一转眼就到2010了。如果是2xxxx,那就悲哀的可以了。最近在看bdb 1.8x的代码。很清爽

Singleton实现时要注意的地方

对于lazy initialization的singleton,实现起来总的来说有三种方式:
1.double checked locking
2.Magic Static(N2660
3.std::call_once

第一种对coding能力要求较高,写的时候容易出错。而第二种和第三种则不是所有平台都支持。

WindowsLinuxDCL可以可以Magic static>=VC 2015>=GCC 4.3std::call_once>=VC 2015 Update 1可以 Double checked locking Intel CPU上不用考虑Memory order的问题,写操作不会被reorder。
DCL最好的范例是chrome里面的lazy_instance。那个过于复杂,下面这段代码选自别的开源库:

template <class TYPE, class LOCK> TYPE * Singleton<TYPE, LOCK>::instance (void) { // First check TYPE* tmp = instance_; #if defined (ALPHA_MP) // Insert the CPU-specific memory barrier instruction // to synchronize the cache lines on multi-processor. asm ("mb"); #endif /* ALPHA_MP */ if (tmp == 0) { // Ensure serialization (guard // constructor acquires lock_). Guard<LOCK> guard (lock_); // Double check. tmp = instance_; if (tmp == 0) { tmp = new TYPE; #if defined (ALPHA_MP) asm ("mb"); …

单个变量的读写是否是原子的?

今天买了本《Effective java》,我头儿拿去看,然后来问我,书里说,java对单个变量的读写操作是原子的,是什么意思?然后我们就讨论,如果是C/C++,只是多线程对单个int变量进行读写操作,是否需要加锁?这个读写操作是原子的吗?这是一段代码,试图自己从软件层实现mutex:/** @param me 0或者1 */voidmut_excl(int me ){ staticint loser; staticint interested[2] = {0, 0}; int other=1 - me; interested[me] = 1; loser = me; while (loser == me && interested[other]); /* critical section */ interested[me] = 0; } 它在有些CPU上是好使的,但是有些CPU则不是。一个更极端的例子。static char* p=NULL;
线程A执行p=strdup(“hello”);
线程B执行if(p!=NULL) std::cout<<p<<std::endl;在极端情况下,线程B看到p被赋值了,但是去读它指向的那段内存时,读到的却是旧的数据。原因是CPU缓存向系统总线的写入顺序,并不一定严格按照CPU向缓存的写入顺序。不过我在Intel的手册中倒是看到了这么一句话:”Writes by a single processor are observed in the same order by all processors.”这一点是我很确定的,但是我不知道为什么java在讲DCLP的时候会重新把这个拿出来说事儿。也许是因为并不是所有的CPU都是intel产的。另外,即便是单纯的读写操作。假如是一个int,但是这个int未能按照4字节的边界对齐,那么多线程写入的结果是难以预料的。(困了,先睡,以后再说)

2010-01-03

在软件开发的过程中,需求方往往不懂得软件工程的概念,他们拒绝写文档,他们拒绝使用bug追踪系统提交bug和新功能需求。放在游戏开发这个行业,就是,策划一拍脑袋说他要做什么,立马就以口头方式告诉你,你去做。他觉得一个小功能一天就能开发完,因为实在是很简单。他不考虑需求分析的时间,他不考虑循环测试的时间,甚至有时都仔细去想新加入的这个功能对现有的系统会有怎样的逻辑冲突。我坚持认为,策划只是需求方。游戏的开发管理人员,必须是一个具有软件过程知识、有一定的软件开发管理经验的人。无论阻力多大,一定要把确认需求、每个模块的开发日程安排、bug管理系统推行下去。广告策划不必懂软件工程,但是游戏的主策划一定得懂。

2010-1-1

关于gcc对尾递归的优化,我做了这样一个实验:#include <iostream> intsum(int n){ return n<=1?1:sum(n-1)+n; } intmain(int argc,char* argv[]){ std::cout<<11<<std::endl; std::cout<<sum(1000000)<<std::endl; return0; } 然后在Freebsd下
> uname -a
FreeBSD fb.localdomain 8.0-RELEASE FreeBSD 8.0-RELEASE #0: Sat Nov 21 15:02:08 UTC 2009 root@mason.cse.buffalo.edu:/usr/obj/usr/src/sys/GENERIC amd64
gcc 4.4做测试
我故意把stacksize设置的比较小(20K)
#limit stacksize 20k
如果没有加-O2,那么编译完运行的时候会崩溃
#./hello
11
Segmentation fault (core dumped)
如果加了-O2 ,就不会
#./hello
11
1784293664前几天我头儿在看简历的时候,说他很讨厌这样一种写法
for(Iterator i=v.begin();i!=v.end();++i){
....
}
假如这个循环体内部并未对这个容器进行任何的修改操作,那么v.end()应该提出 来。呃,我记得这个是effective C++上的某一条。
然后我想起这样一段代码:char s[]="xxxxfsfxx"; for(int i=0;i!=strlen(s);++i){ if(s[i]=='f'){ //found it! //do something //then break break; } } 这个strlen也应该提出来。
这么做能提高代码的运行效率,但是会引入一个不必要的临时变量。
事实上编辑器的优化能力已经远远超出那些人的设想了。
首先,strlen可以被声明为__attribute__ ((pure))函数(或者更强一 点,__attribute_…