»
S
I
D
E
B
A
R
«
手头有PHP的职位一大堆,人才大把大把地来吧
Mar 7th, 2010 by 一米六二

不少朋友都问我要我帮着推荐人,比如:像途牛,鲜果,都在招各种各方各面的牛人:从产品经理到市场运营,另外似乎都招大量的PHPer
中国雅虎这边也有8~10个PHP工程师名额,也还很期待c/python等人才的加盟~,前端工程师也需求旺盛,有意从速.
以上职位都相当不错,我都恨不能把自己复制粘贴一堆出来,每个公司去一个…
我的邮箱/Gtalk:xurenlu@gmail.com,不换工作的也可以认识一下,哈,以后我可以改行做猎头~

nginx mail模块的学习
Mar 7th, 2010 by 一米六二

相对HTTP模块,mail模块要简单的多,我决定从这里入手,改造一个基于nginx的memcache代理模块,并在这个模块的基础上也实现upstream,再做数据的分布,后端挂tokyotyrant做的key-value存储。于是先学学mail模块。

mail模块跟其他模块也差不多,初始化是在src/ngx/ngx_mail.c里;也是先设置对配置文件的解析:
遇到mail指令(mail指令是MAIN_CONF|CONF_BLOCK),则调用ngx_mem_block函数.
ngx_mem_block函数做了什么?
1.挂载type是NGX_MAIL_MODULE的模块;(同时给这些模块排了序号),NGX_MAIL_MODULE类型的模块也做了排序.
2.接下来依次为各个模块创建一个mail_conf,和srv_conf,loc_conf;
注:ngx_mail_core_module看来是是最重要的mail类模块了。
3.解析mail{}里的内容 ,并依次调用各模块的init_main_conf和merge_srv_conf来初始化MAIN_CONF和SERVER_CONF内容。
4.把模块ngx_mail_core_module中定义的端口号加入要监听的端口列表:调用ngx_mail_optimize_servers函数;

ngx_mail_optimize_servers做了什么?
1.对所有要监听的地址和端口排个序,如果某个地址是*:80这样的监听所有IP的,就放到列表的最后,同时会忽略其他端口的监听(这不是废话么…)
2.建立建听。设置回调函数是ngx_mail_init_connection.该函数定义在:src/mail/ngx_mail_handler.c

ngx_mail_init_connection做了什么?
建session和log对象。
调ngx_mail_init_session函数建立会话(session)对象。

ngx_mail_init_session函数干了些啥?
1.取出协议的种类;
2.设置该连接的写回调是ngx_mail_send;
3.调用指定协议的init_session函数来执行真正的会话初始化;

以smtp协议为例,查看init_session做了什么?
1.如果resolver为空,则用ngx_mail_smtp_greeting函数直接输出欢迎信息。
2.如果不是互联网联接(应该就是本地socket连接了),也直接用ngx_mail_smtp_greeting函数直接打欢迎信息。
3.解析客户端地址:
设置解析成功的的回调函数为ngx_mail_smtp_resolve_addr_handler,开始解析客户端IP.

ngx_mail_smtp_resolve_addr_handler干啥了?
1.如果解析成功:
a:记录host信息;
b;设置读事件的回调函数为:ngx_mail_smtp_resolve_name
如果解析成功,最终还是调用ngx_mail_smtp_greeting函数打出欢迎信息;
2.如果解打失败,直接用ngx_mail_smtp_greeting函数打出欢迎信息。
ngx_mail_smtp_resolve_name干啥了?
…我还没看.
ngx_mail_smtp_greeting干啥了?
1.日志记录中写上“我们欢迎来自****的朋友”….哈哈。我瞎扯的。代码中有类似动作,日志中见不到。
2.设置读取事件超时
3.处理读事件。如果失败(没有收到信息,调用ngx_mail_close_connection断开链接。
4.设置读事件回调为ngx_mail_smtp_init_protocol;
5.设置要输出的东西为greeting信息,然后写往客户端。
ngx_mail_smtp_init_protocol干什么?
1.如果已经超时,关掉它!
2.创建好会话的buffer;
3.设置状态为ngx_smtp_start;
4.设置读取回调为ngx_mail_smtp_auth_state;
调用ngx_mail_smtp_auth来启动用户校验。
ngx_mail_smtp_auth做些啥?
1.如果已经超时,函数返回。
2。如果写缓冲中还有数据,函数返回。
3。读入一段;读入失败的话函数返回;
4. 对读到的命令做处理,用smtp_parse_command解析命令:接下来就是状态机处理了,喔喔喔喔…..

懒人连ssh不输密码若干大法
Mar 7th, 2010 by 一米六二

作为一名系统管理员,经常需要在各种机器中倒腾来倒腾去的。嗯,做为一个超级大懒人,我想了不少办法来一步步简化连接方法。请一条条看,瘟到死插屁用户请绕行。
Section one:从终端复制字符串到剪贴板的工具:xclip
这个只针对linux/unix等X用户有效。我在bash_profile中写了这么一行:
alias pw=’echo PASSWORD|xclip’
然后在要输入密码之前,先在终端中输命令pw,这个密码就存在粘贴板里了。然后接下来,你就粘贴就行了,简单地Shift+Insert键搞定。我最喜欢用的就是这个。嗯,简单实用。不用写啥代码。
Section Two:Expect
Expect是一个perl工具,根据你事先设定好规则响应服务器端的某个输入。Yahoo的机器上有一个工具叫dist_install,每次操作至少要输3次密码,另一个yinst,也经常要输5次左右的密码,我就常常用这个来解压。不过这个要写脚本。
网上有现成的脚本可用,比如这里:
http://blog.chinaunix.net/u/21908/showart_1178288.html

Section Three: sshpass:一个简单的能用参数方式指定密码的ssh 连接工具
这个工具的使用方法有两种:
A: 设置SSHPASS环境变量,比如在bashrc/bash_profile中写上
export SSHPASS=’********’
接下来用sshpass -e ssh some.host.yahoo.com [some commands]
就可以了。
B: 直接用-p参数指定密码:sshpass -p ****** ssh some.host.yahoo.com [some comands]
哦,忘了说了,这个sshpass是一个开源的工具,放在sourceforge上了,http://sshpass.sourceforge.net/;但是这个程序有问题,就是那个著名的第一次问题,第一次连接一个主机时会询问你是否要将这个host加入known_hosts;原来的程序会直接退出,我做了修改,改动后的版本在这里:http://github.com/xurenlu/sshpass
安装,很简单,用tar -xzf sshpass-1.0.4.tar.gz将之解压,然后cd sshpass-1.0.4,再配置一下:./configure,最后make && sudo make install就行了。
推荐用我维护的版本,嗯,原来程序除开key问题外还有个缓冲区过小的问题,我把它从40改到1024了。另外,程序代码非常不雅,从排版到命名都相当不规范。

对TokyoTyrant的一个简单的patch,以支持列出所有的Key
Mar 7th, 2010 by 一米六二

有人在网上评价说Redis、mongodb等Key-value对的数据库,说redis特别牛,能支持列出所有的key;
其实tokyotyrant也是可以的呀,因为我看他底层持tcmdb,tchdb等都是支持遍历所有Key的,于是小小地做了一个改动,以支持列出的tokyotyrant的所有Key.
代码放在http://github.com/xurenlu/mc_list_patch_4_tokyotyrant上了。
用法:
1.启动ttserver:
ttserver db.tch
3.telnet上去,试试set命令:

telnet localhost 1978
Trying 127.0.0.1…
Connected to localhost.localdomain.
Escape character is ‘^]’.
set kw2 1 1 3
123
STORED
list
LIST 9
kw
kw2
END
看这里,已经支持list命令了。
2 再用php客户端来连接:我还没有去用c写php的memcached客户端,就从网上找了一个php做的类,在git目录里有:

include “memcache.class.php”;
$hosts = array(’127.0.0.1:1978′);
$mc = &new MemCachedClient($hosts);
var_dump($mc->listkeys());
关于安装:
1.tokyotyrant基于tokyocabinet,需要先安装 tokyocabinet,请在http://github.com/xurenlu/mc_list_patch_4_tokyotyrant/downloads 下载.

~/download@aragorn $ wget http://cloud.github.com/downloads/xurenlu/mc_list_patch_4_tokyotyrant/tokyocabinet-1.4.41.tar.gz
~/download@aragorn $ tar -xzf tokyocabinet-1.4.41.tar.gz
~/download@aragorn $ cd tokyocabinet-1.4.41
~/download/tokyocabinet-1.4.41@aragorn $ ./configure
….省却若干输出…
~/download/tokyocabinet-1.4.41@aragorn $ make && make install
接下来,请先下载tokyotyrant 1.1.37,可以在http://github.com/xurenlu/mc_list_patch_4_tokyotyrant/downloads 这里下载.
下载下来后,解压、patch:

~/download@aragorn $ wget http://cloud.github.com/downloads/xurenlu/mc_list_patch_4_tokyotyrant/tokyotyrant-1.1.37.tar.gz
~/download@aragorn $ tar -xzf tokyotyrant-1.1.37.tar.gz
~/download@aragorn $ patch -p0 < mc_list.patch
patching file tokyotyrant-1.1.37/ttserver.c
然后编译tokyotyrant:

~/download/@aragorn $cd tokyotyrant-1.1.37
~/download/tokyotyrant-1.1.37/@aragorn $ ./configure
…..若干输出,略去..
~/download/tokyotyrant-1.1.37/@aragorn $ make && sudo make install
接下来就可以启动ttserver来玩了。

Nginx 扩展开发笔记
Mar 7th, 2010 by 一米六二

Nginx 是一款轻量,高效的web server,我最近在学习他的扩展开发,这里是我的学习笔记:nginx扩展开发笔记

Tokyocabinet/Tokyotyrant文档大合集,十全大补汤,哈。
Mar 7th, 2010 by 一米六二

篇幅较长,请移步:tokycabinet/tokyo tyrant 文档.
一直还想把flare和mongodb,redis的文档也加进来,时间不够.有空再搞.

闭关九九八十一天
Jan 5th, 2010 by 一米六二

1.绍明批评我说,博客数据库回档了,丢失数据,也不出来道个歉。我说,没事,反正迟早都是要和谐的。君不见,博客大巴啦,51.com啦,域名不是也被ban吗。我这博客,丢也,也没关系。
2.新年,实在没什么好总结的。没什么好展望的。
3.做好准备,迎接宝宝的到来。
4.闭关一阵,嗯,准备成仙。
5.欲向某人讨要一份停用词表,因为,介个人是做搜索的,不过自己也觉得直接去要显得脸皮太厚了一点。于是在推特上发一推:万能的推特,请给我一份停用词表吧。没成想,没要到,tiny同志提醒说:去问万能的google吧。接下来我发现我被鄙视了:批评说,现在某些人啊,只知道有问题就来问别人,不知道自己动手解决问题。于是心里很郁闷,想:我找人要一份词表,干你鸟事啊,稀罕你装专家来教育人啊。不过后来一想,人家在推上发,全凭个人喜好。也没找上门来鄙视我,我又何必去和人理论一番呢。我不爽,说明我这个现在有点小得瑟,容不得他人批评,这是个不好的苗头。以后我还需要带团队,有很多事情需要去做,这种苗头,实在很不好。面对批评,不管批评得对与不对,先笑而纳之。有则改之,无则加勉。一旦动怒,再也没有人敢对你的不对提出批评了。人生最可怕的事情就是,你做错了事情,却没有人告诉你。古之圣人,尚一日三省其身呢。so,面对批评,平和心态,有则改之,无则加勉。
6.某程序员捐了一点点钱。我想任何人都无法承受这种大悲。凑一点,是一点。如果你也想尽一点点力,请点击这里:
7.本人在github上的page:http://github.com/xurenlu/。我希望在宝宝出生的时候,我能把nginx的扩展给理清楚。
好鸟,封闭修仙去鸟。

整理了一份招PHP高级工程师的面试题
Oct 15th, 2009 by 一米六二

嗯,基本上这些题都答得好 那就…
直接上题.

1. 基本知识点

  1. HTTP协议中几个状态码的含义:503 500 401 200 301 302。。。
  2. Include require include_once require_once 的区别.
  3. PHP/Mysql中几个版本的进化史,比如mysql4.0到4.1,PHP 4.x到5.1的重大改进等等。
  4. HEREDOC介绍
  5. 写出一些php魔幻方法;
  6. 一些编译php时的configure 参数
  7. 向php传入参数的两种方法。
  8. (mysql)请写出数据类型(int char varchar datetime text)的意思; 请问varchar和char有什么区别;
  9. error_reporting 等调试函数使用
  10. 您是否用过版本控制软件? 如果有您用的版本控制软件的名字是?
  11. posix和perl标准的正则表达式区别;
  12. Safe_mode 打开后哪些地方受限.
  13. 写代码来解决多进程/线程同时读写一个文件的问题。
  14. 写一段上传文件的代码。
  15. Mysql 的存储引擎,myisam和innodb的区别。

2. web 架构,安全,项目经验

  1. 介绍xdebug,apc,eAccelerator,Xcache,Zend opt的使用经验。
  2. 使用mod_rewrite,在服务器上没有/archivers/567.html这个物理文件时,重定向到index.php?id=567 ,请先打开mod_rewrite.
  3. MySQL数据库作发布系统的存储,一天五万条以上的增量,预计运维三年,怎么优化?
  4. 写出一种排序算法(原理),并说出优化它的方法。
  5. 请简单阐述您最得意的开发之作
  6. 对于大流量的网站,您采用什么样的方法来解决各页面访问量统计问题
  7. 您是否用过模板引擎? 如果有您用的模板引擎的名字是?
  8. 请介绍Session的原理,大型网站中Session方面应注意什么?
  9. 测试php性能和mysql数据库性能的工具,和找出瓶颈的方法。
  10. 正则提出一个网页中的所有链接.
  11. 介绍一下常见的SSO(单点登陆)方案(比如dedecms整合discuz的passport)的原理。
  12. 您写过的PHP框架的特点,主要解决什么问题,与其他框架的不同点。
  13. 大型的论坛/新闻文章系统/SNS网站在性能优化上有什么区别?
  14. 相册类应用:要求在浏览器中能同时选中并上传多个文件,图片要求能剪裁,压缩包在服务器端解压。能上传单个达50M的文件。上传过程中有进度条显示。每个图片能生成四种大小缩略图,视频文件要转成flv供flash播放。叙述要涉及的各类开源软件和简单用途。
  15. 一群猴子排成一圈,按1,2,…,n依次编号。然后从第1只开始数,数到第m只,把它踢出圈,从它后面再开始数,再数到第m只,在把它踢出去…,如此不停的进行下去,直到最后只剩下一只猴子为止,那只猴子就叫做大王。要求编程模拟此过程,输入m、n, 输出最后那个大王的编号。用程序模拟该过程。

3. unix/linux 基本使用

  1. linux下查看当前系统负载信息的一些方法。
  2. vim的基本快捷键。
  3. ssh 安全增强方法;密码方式和rsa key 方式的配置。
  4. rpm/apt/yum/ports 装包,查询,删除的基本命令。
  5. Makefile的基本格式,gcc 编译,连接的命令,-O0 和-O3区别。
  6. gdb,strace,valgrind的基本使用.

4. 前端,HTML,JS

  1. css盒模型。
  2. javascript中的prototype。
  3. javascript中this对象的作用域。
  4. IE和firefox事件冒泡的不同。
  5. 什么是怪异模式,标准模式,近标准模式。
  6. DTD的定义
  7. IE/firefox常用hack.
  8. firefox,IE下的前端js/css调试工具。
宝宝妈妈的第一次产检
Oct 13th, 2009 by 一米六二

昨天忽然发现别的孕妈妈都老早去医院检查、建档了,我们还没有准备,再一看,呀,好多医院根本挂不上号,于是,赶紧请假,今天早上一大早就去医院排队了。
光是选在哪个医院建档,就很费神。开始一直想在中日,后来说中日基本无法挂上号,因为一天只有5个号,而且不知道有多少人盯着中日呢,根据排不上号,又选煤炭总医院,结果在网上看评价不好。于是最后选了306医院。
早上那可真是早啊,不过,已经有很多人在排队了。每个队都有10多个人了。后来到三楼妇产科时,看到等假区人满为患,这才知道北京生孩子的人还真是不少啊。这还只是一般的医院啊,不知道朝阳妇幼 和朝阳医院 ,又会是怎么一幅情形呢。
今天都没怎么查到,因为B超这周都排不上了,护士小MM给在周五下午加了个塞儿。从来没听说过检查项还要提前好几天预订的。
今天的一些结果:
胎心:150 (嗯 网上好多说胎心在145以上的尤其是150以上的,一般都是女宝宝~)
嗯,周五下午我就不陪着去了,不过周六又得起一个大大的早啊。

一个有意思的题
Oct 12th, 2009 by 一米六二

在网上看到的:
1分钟内用户上线的数目是60万,如果用户在5分钟内重复上线,就给他发警告,问如何设计?

嗯,让我这个自以为是的不知天高地厚的家伙来看看该怎么设计。
嗯,首先确认的是,出题者应该是想考实际算法的,和应试者解决难题的方法,全方位思考问题的意识。所以”花600百万美刀花一套oracle的顶级牛B数据库然后把五分钟内的用户记录入库,连数据库查询“这样回答可能确实解决问题 不过不是出题想要的。
好吧,哪,准确地说,啥数据结构,啥算法?
让我们先想象数据容量和运算量。嗯,五分钟内可能有300万用户名要存储。这个嘛,不大,完全在单机范围之内,内存稍大的机呖器,就能全装下这个量级的用户名或id数据。再看时间要求:一分钟内要上线60万用户,每个用户上线时都要查询是否重复了,呀,这是一秒钟1万次查询。如果说是网络服务器的话,比如web这种效率低一点的服务,一万次每秒还是相当复杂的。不过如果是机器内运算1万次,嗯,还是可行的。
接下来,咱们要看是最麻烦的部分,也是要点一:如何应对一秒内完成一万次对该用户是否在五分钟后上线过的查询。这实际是一个要查询一个数据是否在一个列表中存在的问题。嗯,当然我们可以挨个去比对,这个列表比对完了我们就知道这个数据是不是存在了。不过,做为搞软件开发的,大家都知道,如果这个列表能够事先排好序,那是最好不过了。好吧,让我们确定一点:我们最好应该将某一时间的用户名排个序。
接下来我们假定我们把每秒钟内上线的1万个用户放在一个桶里,然后对该秒中的所有用户按名字排序,从小到大或都是从大到小,都行。现在我们时间每推进一秒,我们就噌地新建建一桶,这一秒时间内的新增的一万用户呀,就存这个桶里了。嗯,做为开发者,实际情况是,我们一始就建了300秒这么多桶,申请了大小为300的内存块。然后每块内存里要能有足够容纳一万个用户的内存大小。
嗯,每当时间的车轮进入新的一秒,我们就去这300个中间去找到已经过期的那一“秒“,给它打上当前时间标记,嗯,把它个1万个用户数据清空。每进来一个用户,我们就丢进去,让它们按用户名大小排队。
每一个新用户上线时,我们都需要向这个300个桶发出查询请求。嗯,学过二分法的话,就应该知道,一万个排好序的数据,要查询是否包含某一数据只需要log10000就行了,啊,大概是14次查找。嗯,比你一万个挨个查好了吧,那可是1万次查找啊。
再接下来,我们再思考一下,检查一下:如果是实际场景的话,我们用户们可能不那么听话,每分钟内的60万用户未必刚好平均分配到一秒一万。嗯,而且就跟电灯炮一般能承受的电压都不是220v,而会高出不少,比如250v也能工作,180v也能点亮。比如,明天突然出了个重大新闻,一秒钟内涌进了13000名用户,那我们这么桶的大小就不能承受了。这个,我们做一点点改进,因为二分法最多反正也得比较14次,我们就以2的14次方做为桶大小。如果再还不能承受,那就在用户超出时2的14次方时单独再申请内存。
嗯,这样看上去好多了,不过,排序也是一个比较繁琐的过程,嗯。假设这样一个场景….算了,直接说吧。对于这种从一堆数据中查询是否存在某一个数据的做法,有一个算法叫布隆算法,可以google 一下bloom algorithm或是bloom filter,就专门干这些事。布隆算法做这个查询会有误差,比如,有的用户明明是没有登陆,可是却被提示重复登陆了。这个误差机率我们是可以计算的。
接下来我们可以试际测试一下,看看单机测试的结果。如果实在还不行,那就需要把这300个秒上的数据分布到几台机器上去计算。比如每分钟内的时间分在一台机器上…
有的哥们是这样考虑的:
做一个长度为300的循环链表,每个链接项的数据是一个hashtable,这样来判断。也是删掉过期数据。我觉得这样难度挺大的,因为这样每秒种进1万个用户,对300个链表项中每一个项的1万个数据都要做比较,大致相当于一秒内做了10k*300*10k次比较。我的印象中,就是一亿次for循环,每个循环基本上啥也不干,这个时间,也应该在一秒左右。我偷了下懒, 用c写了个简单的测试:

#include “stdlib.h”
#include “stdio.h”

int main(int argc,void ** argv){
int i=0;
int j=10000*10000*3;
for(;i }
printf("done");
}
编译后:
$time ./a.out
done
real 0m1.363s
user 0m1.268s
sys 0m0.008s

如果再100倍,时间就远超出1秒了。还没有做其他事情呢。我用的是10000*10000*3是因为,如果是10000*10000*300,就溢出了。
不过至于究竟分桶排序后效率如何,也还不好说。没有实战。只是我凭经验觉得一秒钟几百亿次比较是不靠谱的。嗯,不知道有没有时间写个程序验证一下。

»  Substance: WordPress   »  Style: Ahren Ahimsa
30277 页面访问次数, 643 今天
11656 访问数, 258 今天
FireStats icon 由FireStats提供支持