29

妈妈不小心闪了腰。

妹妹生日(正月廿三),打电话回家才知道这事。姥姥因为骨质增生,腿疼,妈妈想去看看她,结果就在那条走了无数遍的路上,不小心摔了一跤,闪了腰。上了医院,拍X光,医生说没有什么大碍,但打针吃药还是少不了。

还好姥姥的腿疼经过一段时间的治疗后,现在好多了。

妹妹明天在新学校分班考试。希望能考的顺利吧。印象中妹妹一直是俩小孩子,今天早上打电话祝生日快乐的时候才想起,她们都满17岁了,都成大人了。

爸爸后天生日(正月廿五)。爸妈都是快满 50 的人了,种了这么多年田,现在爸爸腿不好(大三那年摔了一跤),妈妈现在又腰疼,叫他们今年就别种田了,他们却一直不听。有什么办法能让老人听话呢?也许比让小孩听话更难吧。

工作上的郁闷终于渐渐远去,随着项目上线的时候越来越近,修改的都是一些小的问题了。只是,上线后,我又该何去何从?继续做 php 的开发,还是横下心来,转去做 C 呢?我期待的工作环境,氛围,我能得到吗?

住房的问题终于告一段落。小白也通过别的办法办了万恶的“暂住证”。“暂住”,不知道哪个脑子进了水的“领导”想出来的词。想出让居住在自己买的房子里的人办“暂住证”的法子的“领导”,脑子里进的,大概不只是水吧。

小蔡辞职算是成功了,他的老板却明确的告诉他不会给开离职证明。在单位的最后一天,请老同事们吃饭的时候,居然把腿给扭了。3天后的新单位工作的第一天,但愿到那时候能恢复过来。

26

以Daemon方式运行的程序,在运行过程中与控制台无关,即不受控制台信号影响,在控制台退出后也继续保持运行,而其他非Daemon程序会受控制台操作影响,并在控制台退出时被强行退出。因此网络服务程序绝大多数都是以Daemon方式运行。

可以在程序初始化时加入以下语句,则程序将以Daemon方式运行:

/* 生成一个新的进程并将原来的主进程退出 */
if(fork()) exit(0);

/* 关闭 stdin, stdout, stderr 等控制台句柄 */
for (n = 0; n<3; n++) close(n);

/* 将 stdin, stdout和stderr均指向/dev/null */
open(”/dev/null”, O_RDONLY);
dup2(0,1);
dup2(0,2);

/* 设置tty的I/O属性 */
if((n=open(”/dev/tty”,O_RDWR)) > 0) {
ioctl(n, TIOCNOTTY, 0) ;
close(n);
}

/* 创建一个新的session,使当前进程成为一个process greoup的leader */
setsid();

/* 生成一个新的进程并将刚才生成的进程退出,这个新的进程已经以daemon方式运行了 */
if(fork()) exit(0);

22

在北京,或者在中国的任意一个城市,房子都已经成了人们最热衷讨论的话题。

买房的梦越来越遥远,这已经是不争的事实。商品房伴着奥运的春风,价格跟着“嫦娥一号”涨到了38万公里以外,远到不能再远了,接下来,该涨的应该就是租房的价钱了。

小白的房东不知道出于什么“考虑”,要把房子收回重新装修,按照合同里写好的“提前一个月通知”,于是,小白又面临着找房的困境了。

小蔡辞职了打算另外找工作,期望的行业公司大多在朝阳区。于是,小蔡也面临着找房的困境了。

小蔡要走,于是小白打起了搬过来跟我住的念头。正在这个关节上,我们的房东大哥大姐,也不知道出于什么“考虑”,跟我们说可以让我们住到 7 月底(合同4月份到期)。该死的奥云可是选择了吉利无比的 8 月 8 号啊!7 月底去找房,还不如直接买个睡袋睡大街上算了!

我们想跟房东争取再签一年的合同,最少也要签半年,躲过奥云再搬。房东一直拖着不给回信。小白的室友出去看中了一套房子,可能马上要搬,而我这边小蔡必须要到月底才能搬走,掐指算来算去,小白还是有几天没有地方可住,即使月底搬到我这里来,我这里能住多久也还是一个未知数。。。

就在这样的困绕郁闷之中,元宵节这天,终于等到了各方的结果:小白的室友到月底才搬;小蔡也是月底搬;房东答应续签半年,到10月份,但要涨价。于是小蔡月底搬走,小白月底搬过来,我和小白继续在皂君东里住着,可能一直到秋天,也可能只到明天。

说不准的房子事,谁知道呢!

22

哈希算法将任意长度的二进制值映射为固定长度的较小二进制值,这个小的二进制值称为哈希值。哈希值是一段数据唯一且极其紧凑的数值表示形式。如果散列一段明文而且哪怕只更改该段落的一个字母,随后的哈希都将产生不同的值。要找到散列为同一个值的两个不同的输入,在计算上是不可能的,所以数据的哈希值可以检验数据的完整性。

链表查找的时间效率为O(N),二分法为log2N,B+ Tree为log2N,但Hash链表查找的时间效率为O(1)。

设计高效算法往往需要使用Hash链表,常数级的查找速度是任何别的算法无法比拟的,Hash链表的构造和冲突的不同实现方法对效率当然有一定的影响,然而Hash函数是Hash链表最核心的部分,下面是几款经典软件中使用到的字符串Hash函数实现,通过阅读这些代码,我们可以在Hash算法的执行效率、离散性、空间利用率等方面有比较深刻的了解。

下面分别介绍几个经典软件中出现的字符串Hash函数。

●PHP中出现的字符串Hash函数

static unsigned long hashpjw(char *arKey, unsigned int nKeyLength)
{
unsigned long h = 0, g;
char *arEnd=arKey+nKeyLength;

while (arKey < arEnd) {
h = (h << 4) + *arKey++;
if ((g = (h & 0xF0000000))) {
h = h ^ (g >> 24);
h = h ^ g;
}
}
return h;
}

●OpenSSL中出现的字符串Hash函数

一。

unsigned long lh_strhash(char *str)
{
int i,l;
unsigned long ret=0;
unsigned short *s;

if (str == NULL) return(0);
l=(strlen(str)+1)/2;
s=(unsigned short *)str;

for (i=0; i
ret^=(s[i]<<(i&0×0f));
return(ret);
}

二。

/* The following hash seems to work very well on normal text strings
* no collisions on /usr/dict/words and it distributes on %2^n quite
* well, not as good as MD5, but still good.
*/
unsigned long lh_strhash(const char *c)
{
unsigned long ret=0;
long n;
unsigned long v;
int r;

if ((c == NULL) || (*c == ‘′))
return(ret);
/*
unsigned char b[16];
MD5(c,strlen(c),b);
return(b[0]|(b[1]<<8)|(b[2]<<16)|(b[3]<<24));
*/

n=0×100;
while (*c)
{
v=n|(*c);
n+=0×100;
r= (int)((v>>2)^v)&0×0f;
ret=(ret(32-r));
ret&=0xFFFFFFFFL;
ret^=v*v;
c++;
}

return((ret>>16)^ret);
}

●MySql中出现的字符串Hash函数

#ifndef NEW_HASH_FUNCTION

/* Calc hashvalue for a key */
static uint calc_hashnr(const byte *key,uint length)
{
register uint nr=1, nr2=4;

while (length–)
{
nr^= (((nr & 63)+nr2)*((uint) (uchar) *key++))+ (nr << 8);
nr2+=3;
}

return((uint) nr);
}

/* Calc hashvalue for a key, case indepenently */
static uint calc_hashnr_caseup(const byte *key,uint length)
{
register uint nr=1, nr2=4;

while (length–)
{
nr^= (((nr & 63)+nr2)*((uint) (uchar) toupper(*key++)))+ (nr << 8);
nr2+=3;
}

return((uint) nr);
}
#else
/*
* Fowler/Noll/Vo hash
*
* The basis of the hash algorithm was taken from an idea sent by email to the
* IEEE Posix P1003.2 mailing list from Phong Vo (kpv@research.att.com) and
* Glenn Fowler (gsf@research.att.com). Landon Curt Noll (chongo@toad.com)
* later improved on their algorithm.
*
* The magic is in the interesting relationship between the special prime
* 16777619 (2^24 + 403) and 2^32 and 2^8.
*
* This hash produces the fewest collisions of any function that we’ve seen so
* far, and works well on both numbers and strings.
*/
uint calc_hashnr(const byte *key, uint len)
{
const byte *end=key+len;
uint hash;

for (hash = 0; key < end; key++)
{
hash *= 16777619;
hash ^= (uint) *(uchar*) key;
}

return (hash);
}

uint calc_hashnr_caseup(const byte *key, uint len)
{
const byte *end=key+len;
uint hash;

for (hash = 0; key < end; key++)
{
hash *= 16777619;
hash ^= (uint) (uchar) toupper(*key);
}

return (hash);
}
#endif

Mysql中对字符串Hash函数还区分了大小写

●另一个经典字符串Hash函数

unsigned int hash(char *str)
{
register unsigned int h;
register unsigned char *p;

for(h=0, p = (unsigned char *)str; *p ; p++)
h = 31 * h + *p;

return h;
}

21

腾讯的笔试原预计周日进行,临时调到昨天晚上。

在进行了一整天的 SetErrorCode 后,来不及做任何准备,就开始了答题。

家里小蔡的电脑很不习惯,没有 Cygwin,没有 PHP 手册,没有 SSH,用 PuTTY 连上公司的测试机还慢的像断了腿的蜗牛。自己以前留存下来的经典代码也无法参考。用 QQ 而不是更干净整洁的 TM,用 IE 而不是自己熟悉的 FF。一个小时的中文测试,居然到了快 20 分钟的时候才做完第一题。

腾讯招 PHP 的是QZone空间的部门,可是打开空间看了看,并没有发现 PHP 的丝毫痕迹。QZone 使用大量的 Js,对搜索引擎极其不友好,只支持 IE 等做法恰恰跟自己喜欢的方式相左。本来还希望往服务器配置,优化,管理的方向转,但仔细一看QZone的服务器,Server: WS CDN Server,这是啥?Server我知道,CDN我知道,可是WS是什么?

腾讯的笔试题比较重视正则表达式,短短的7道题,居然有2道与正则有关。关于 PHP 的安全模式,命令行模式,魔术函数,以及网络调用都有涉及。令我感到意外的是,居然有一道算法题,使用 PHP 实现双向队列。这本来应该是我的强项,只是最后却因为时间关系而来不及细写。

英文的测试题相对简单多了,大约腾讯并不要求很高的英文能力吧,以至于像我这样只过了六级,又好久没有折腾英语的人,都非常轻松的完成了答题,而且时间上居然还有一点富余。

其实说起来,还是要非常感谢腾讯的 lin,为了这次笔试陪我加班到那么晚。即使这次没有成功,腾讯还是以后可能优先考虑的一个选择。

15

“年好过,日子不好过” —— vetcafe 语

一晃,年过完了。

回到北京,还来不及喘口气缓缓劲,甚至来不及把在家照的照片翻出来看一看,便又开始了忙碌。压抑的工作,暗淡的生活,看不到尽头。

情人节,一周年。365 天的经历,说起来,却大都是波澜不惊。但愿未来的日子能越过越好!

小蔡辞职了,小白也因为年终的关系,想着辞职,而自己,又一次接到电话。前途总是茫茫,总是在选择和犹豫中变幻。