qyb的博客

DV-2-XviD 0.8.3

又是一个老外报告了 bug,如果目标文件夹路径包括空格的话,lame.exe 执行会失败。很容易就改好了。

关于 DV-2-XviD 的中文信息可参考这里

另:今天看到一篇文章 (http://weblogs.mozillazine.org/roadmap/archives/2007/02/threads_suck.html)

看起来 JS 未来将会加上对线程的支持,就是说 Ajax 应用将会更有效的利用你的多核系统的计算资源。感觉 Gecko 在 JS/ECMAScript 上还是很有话语权的。

Topic: 技术

Apache Module 开发后记

上一篇文章

开发出 apache 2.0 的模块以后,又面对着要将其移植到 apache 其他版本的需求,经过这段时间一点点的修补,现在我的模块已经可以同时在 1.3/2.0/2.2 下编译。甚至在 2.0/Win32 环境下也编译出了 dll,供在个人PC上做开发的同事使用。

我感觉如果项目不复杂的话,可以学习我这样把所有的内容放在一个文件里面的做法。

最重要的就是利用 MODULE_MAGIC_COOKIE 的定义,把 1.3 和 2.0/2.2 的不同之处融合在一起。例子:

  1. #if MODULE_MAGIC_COOKIE == 0x41503230UL || MODULE_MAGIC_COOKIE == 0x41503232UL
  2.  
  3. #include "util_filter.h"
  4. #include "apr_strings.h"
  5. module AP_MODULE_DECLARE_DATA foobar_module;
  6. #define APLOG_FOOBAR APLOG_ERR,0
  7.  
  8. #else
  9.  
  10. module MODULE_VAR_EXPORT foobar_module;
  11. #define apr_pool_t          pool
  12. #define apr_table_t         table
  13. #define apr_pcalloc         ap_pcalloc
  14. #define apr_table_unset     ap_table_unset
  15. #define apr_table_set       ap_table_set
  16. #define apr_table_get       ap_table_get
  17. #define apr_table_make      ap_make_table
  18. #define apr_pstrdup         ap_pstrdup
  19. #define apr_snprintf        ap_snprintf
  20. #define apr_pstrndup        ap_pstrndup
  21. #define APLOG_FOOBAR APLOG_ERR
  22.  
  23. #endif /* MODULE_MAGIC_COOKIE == 0x41503230UL */

同样,模块初始化的部分也这样针对不同版本定义一下。

这样主要的功能函数就可以使用同样的代码模块,并使用 apr_* 系列函数族了。

之所以要对 APLOG_ERR 做定义,是因为在 1.3 和 2.x 版本中,ap_log_error 和 ap_log_rerror 所使用的参数数目不一致,2.x 的参数要多一个,因此针对 2.x自动增加一个参数——",0"

2.0 和 2.2 有些地方也有小差别,我的代码里面就碰到了 apr_socket_create 的参数不一样。同样简单 #if 就可以处理了。

在 1.3 里面 module initializer 如果 2.x 里面的 post_config 会运行两次,而且2.x 上的这个小技巧无法直接使用了。本来是不影响程序运行的,但还是想出了一个变态的办法来解决它。module initializer 两次执行之间的一个重要事件就是 apache 的 daemonize。那样怎么来判断当前进程是否在 daemon 状态下呢?我的方案是:

  1. /* 小技巧,用于帮助 init_module 只执行一次检查 */
  2. #define MAX_FDS 1024
  3. int daemon_flag(int fds[MAX_FDS])
  4. {
  5.     int fd;
  6.     int newfd;
  7.     int i;
  8.     int opt;
  9.     socklen_t optlen = sizeof(int);
  10.     int ret = 0;
  11.  
  12.     memset(fds, 0, sizeof(int) * MAX_FDS);
  13.     newfd = fd = socket(AF_INET,SOCK_STREAM,0);
  14.     while (newfd < MAX_FDS && newfd > 0) {
  15.         fds[newfd] = 1;
  16.         newfd = dup(fd);
  17.     }
  18.     for (i = 0; i < MAX_FDS; i++) {
  19.         if (fds[i] == 1) {
  20.             close(i);
  21.         } else {
  22.             if (0 == getsockopt(i, SOL_SOCKET, SO_REUSEADDR, &opt, &optlen)) {
  23.                 fds[i] = -1; //这样返回以后也知道哪些 fd 被监听
  24.                 ret = 1;
  25.             }
  26.         }
  27.     }
  28.     return ret;
  29. }

因为我知道 apache 必然会对监听套接字设置 SO_REUSEADDR,所以可如此判断。

由于 apache2 有了 apr 的支持,几乎不用修改任何代码模块就可以在 win32 下编译。而且只需要 MS 的免费工具就可以了,包括 MSVC C++ Toolkit 2003 和 Platform SDK。设置好 INCLUDE/LIB 路径后,只需要执行
cl /MD /D "WIN32" /c mod_foobar.c
link /DLL mod_foobar.obj libhttpd.lib libapr.lib

这样就得到了可被 LoadModule 的 mod_foobar.dll

win32 下我碰到的问题稍微麻烦一些。启动 apache 无法成功,报告什么 OPENSSL_Applink 错误。看了 openssl 的 FAQ,说什么要 include 一个 applink.c,但仍然无济于事。不过查看 applink.c 后发现,它似乎和 IO 库相关;最后我把以前使用的 stdio 替换成了 openssl 自己的 bio 函数族,该问题就消失了。

openssl 的 win32 库从这里下载并安装

一下记住28个!

这是我上周完成的最得意的事情。

在周四的公司部门介绍、周五的职业发展ABC之后,周五下午就把我们30个新员工拉到城郊的一个小院子里准备第二天的体验式培训——俗称拓展。

周五晚上饭后的活动叫“融冰”,因为大家都是新员工,来自各个不同的部门,以前都没有怎么接触过,要求大家记住彼此的名字。

其实记名字还是挺简单的,所有人围成一个圈,起点的人开始报名:“我是XXX”,然后旁边的人说:“我是XXX右边的YYY”,再接着是:“我是XXX右边YYY右边的ZZZ”......这样直到最后一个人。

教练事先询问谁有信心一晚上把所有人的名字都记下来,我毫不犹豫的举手——并不是因为我觉得自己记忆力有多好,而是知道这类项目理论上是大多数人都能通过的,只要我不是属于最弱的那群人,肯定能完成项目。

但是除了我好像再也没有人有信心,于是教练宣布有信心的人在他右手边站好,没有信心的人靠他左边站着,然后围成一个圈。最后他指着俺说,就从你第一个报名字吧,大家纷纷 faint。

记不住名字的惩罚措施是,男生如果记不住男生的名字,则背那个人走一圈,如果记不住女生的名字,则抱着那个女生走一圈!!!结果有一个不法之徒前后抱着4个女生走了一圈,各位男士看得热血沸腾,恨得牙痒痒的。有一个女生名字比较难记,加之排她前面几个女生的名字都特简单,猛然到了她这里就是一个坎,好像她最后是被男生抱着走了4圈。

俺的任务最轻松,不过报完名字后就开始记人名,到了第二天,仍然能记得当时一圈下来的各个人的排列顺序。除去一个和我同一个部门的同事外,一下子记住 28 个人!这里自我陶醉一小下下。其实这项活动非常适合搜狐这样大的公司的新员工培训,相当于立即创建一个各部门之间的人脉关系网,而且新员工也特别需要这样的关系网。培训结束后我们这30人迅速创建了一个 QQ 群和一个 ChinaRen 班级;过去一周中也有好几个人看见我的 MSN 签名后推荐程序员。

周六的项目印象最深刻的是一个室内项目,团队完成的一塌糊涂,可以说极难,号称通过率不到 5%

另一个有意思的项目是“空中断桥”,当我看着队友一个个在上面犹豫的时候我就豁然开朗——看你能不能迈出那一步。立刻我就想到三个月前我迈出的一个人生中最重要的一步:虽然以往也做过很多影响命运的决定,比如毕业工作、结婚、要小孩...但要么是年轻懵懵懂懂,要么是受别人影响或者说情感因素;直到离开亿邮这个决定,才是个人非常理智、经历很长时间、选择非常痛苦的决策。

轮到我时,没有任何犹豫就跳了过去。一个教练问我是否曾经做过这个项目,我微笑说没有。看着同事们一个个眉飞色舞的讲述高台上的心路历程,我想他们不知道要等什么时候才会走到人生的空中断桥上,年轻真好,逃避和畏缩很容易找到借口。

最后给这次培训的公司和教练(负责我们一小队的其实也是该公司的总经理)做一个广告:北京标准体验管理咨询公司,吴海东。我之前已经参加过多次拓展培训了,觉得什么背摔、电网这类活动已经是泛滥到呕吐的感觉,可这次的项目,尤其是室内项目(包括最后的教练总结)让人耳目一新。后来我和吴海东在 MSN 上交流,他说:“同样的项目,不同的培训师,效果千差万别”,深以为然。

Topic: 商业 生活

人品爆发

周五下午,作为年终的一系列活动之一,CPC 和 NO 在一起举行一个小小的抽奖仪式。结果抽中一个睡袋,结束 N 年以前抽奖不中的记录.. 不过真正的人品爆发是下班前的一件事情:

不知道为什么,临下班的时候内部网络出现故障,结果导致 MySQL 连接过多,too many connections,当时也没有可用的 mysql client 连接,无法去 show processlist 看看都发生了什么。心急如焚,这得影响多少网民啊;另一个心急如焚的原因是偶要赶晚上8点13的火车去天津,票都已经买好,如果为了不被网民以及上级骂死而耽误火车,势必会被老婆骂死。

终于在一个偶然的机会,mysql 连接了上去(很快连接又被占满了)。看了看 processlist,一堆的 unauthenticated user 在试图 connect/login

我立刻想起就在昨天赵宏威在 MSN 上问我同样的问题,当时偶也觉得这个事情比较诡异,但没有帮他找答案,没想到第二天同样的问题就碰上我了。赶紧在 MSN 上问他最后是怎么解决的故障,说是启动的时候加 --skip-name-resolve 参数就好了。

赶紧告诉 DBA 重启,果然问题消失。然后感叹人品之坚挺——出的问题正好是别人刚碰到的,而且他又正好来问我,真是幸运啊幸运。

重新探讨故障原因,应该是 MySQL 的安全模型里面进行用户认证和授权的过程中,除了对 IP 地址做校验之外,还包括了对 HostName 验证的配置。因此所有的用户连接进来以后都需要做一次反向域名查询,然后根据 IP 和 HOST 来进行授权。这样如果因为网络故障导致反向域名解析很慢的话,就会让一个连接很长时间也无法完成...

由此引申开去:

一、MySQL 是否能处理的更好一些呢?相关的 BUG 在 2005 年就有人报告。我觉得在执行反向域名解析之前,至少可以先判断一下来源 IP 是否已经在策略表里面存在,如果存在的话就可以直接做用户认证了

二、标准 C 库(glibc)能不能想法降低做反向解析的时间?比如执行查询之前可以设置一个超时时间?因为反向解析而给用户带来困惑我已经见过好多好多回了

三、我们使用的连接池程序(据说是 resin 自带)是否有问题?当然我不是 Java 程序员,而且这次故障原因和 Java 没有任何的关系。可是明明有连接池限制怎么还会出现 too many connections?看起来是因为 mysql 连接迟迟没有响应,导致连接池程序开始后继的尝试。做新的尝试没有问题,为什么不去 close 以前的连接??或许是写这个连接池的人对 GC 过于自信了?很难想象一个有本事写连接池的 C 程序员会犯这样的失误。嘻嘻,腹谤一次 java

最后虽然有些赶时间,但还是坐上了开往天津的火车。我很严肃的思索了一下为什么今天会有如此之好的人品——结论是周五我做的唯一和以往不同的事情就是偷偷使用了老婆的保湿水和面霜,看来美容活动得坚持下去啊...

以前听人说:女人三十岁前的模样是天生的,三十岁后的模样是自己给的。我补充一下,男人三十岁前的模样是天生的,三十岁后的模样是老婆给的。

Topic: 技术

新员工培训——搜狐介绍

周四,也就是第一天的课程是公司介绍,目的是让员工对公司的各大业务线有一个基本的了解,还有就是和所有人都有紧密关系的服务部门也做详细解说,特别是 HR 和 ES/admin,整个上午的半天都是在讲这两个部门的工作流程。

一、搜狐业务

按收入来源说,搜狐的业务线分为:广告、游戏、无线

游戏分成游戏运营、RPG开发、休闲游戏开发三个子部门;无线增值的业务大家都很熟悉

广告现在是分为面向大企业大广告主的 Content 业务,以及面向中小企业的搜索业务。17173、focus、chinaren、乃至邮件等应该算前一种的;go2map 现在被归入后一种业务。不过最近 chinaren 似乎被划归王小川管,难道意味着 chinaren 日后的广告业务会和搜索靠拢??(另外还有一个可能,不过只能想不能说,嘻嘻)

对于内容/Content业务来说纵向上是设计(SAS)、市场、销售、编辑、CS(客服似乎涵盖了广告投放、PV分析、callcenter、QA等一系列工作)、技术(CMS,总体上看 club 也应该算是 CMS 的一部分,但我接触的 club.sohu.com 的技术人员和 CMS 没有直接从属关系)。从横向上来说内容也分好几块,除了 club 外,最近还新分出来的3个事业部——体育、娱乐、奥运,尤其是娱乐事业部还在培养自己的艺人!!!搜狐的内容业务真是我这种新员工所看不懂的啊.. hehe。

奥运事业部比较有趣,因为这可以说就是今明两年一锤子买卖的业务,来自奥运事业部的同事调侃说他们是“奥运失业部”。仔细一想会发现虽然奥运的政治意义大于商业意义,可是奥运官方网站的建设还是很有技术难度的——全球24小时不间断访问,五门语言(现在正在紧急招募会西班牙语、阿拉伯语的人才),多个赛场实时比分同步...要克服很大困难才能做出一个好的官网。当年清华的王浩老师说起参与北京亚运会的 IT 建设,自豪之情溢于言表。虽然我一直认为这个北京奥运会极其无聊,但若是有参加相关的工程项目的机会,还是很吸引我的。

研发中心和搜狗互为表里,搜狗有自己的销售和渠道市场部门。除了 go2map 外,研发中心包括两大产品:搜索产品、桌面产品。

二、支持部门

从培训内容来看,搜狐的支持部门包括 HR、ES、Tech-NO、LEGAL、FINANCE、IA、MIS 等。

HR 的工作包括三部分:员工控制和服务;企业管理运营的顾问,以及推进变革(在购并或者裁员的话就需要了);业务线合作,就是说从HR方面支持各个部门的工作。

HR 分成两部分:CorpHR 和 BizHR。所谓 BizHR 就是和业务线专职的 HR,比如负责技术人员的田春,印象最深刻的是面试我的时候说她能叫出搜狐所有技术部门人员的名字,BizHR 一共是 7 个人。CorpHR 也分三个部门:一个是负责薪酬的部门,一个是负责招聘渠道,一个是负责员工培训和员工关系。

搜狐的社保基数上限是前一年北京市平均工资的三倍,06 年的基数上限大约是 8k 出头(我觉得应该不属于机密信息吧)。五险一金里个人共负担 20%,除此外搜狐还免费提供商业的补充医疗保险以及一份人生意外伤害险。

津贴通常只是午餐津贴,每月400,从老张开始人人有份。长期出差的人有另外的津贴待遇,目前似乎只有那些在各个省移动做业务的才有。

搜狐的奖金政策是:业务线有业务线的奖金,销售部门有提成奖,其他部门则是 PM 奖。

由于现在股票价格比较稳定,期权已经没有什么吸引力,搜狐现在改成 RSU(限制性股票单元),可以看作是零授予价格的期权。但现在要拿 RSU 需要很强的背景才有了,xjb 时代似乎是新员工或多或少总会有一些的。

经理没有加班费。员工的加班费为周六、日每天200;周一至周五八点以后的加班用餐票、的票来补,餐费30上限,车费40上限;节假日的加班费算法举例:初一到初三200x3,初四到初七200x2

说到经理,据俺个人的猜测和分析:搜狐似乎是 5 级(含)以上算是那种无加班费的经理;7、8级为(高级)总监;9,10级为(高级)VP;11级属于核心管理层——目前只有一位CFO;12级是金字塔的顶尖张朝阳博士。

这里说的都是员工手册上没有涵盖的内容,仅供参考。其实员工手册里面的信息已经非常详尽,我也非常不明白为什么不对公众披露,比如提供一个 PDF 版本供下载,hoho

说了半天 HR,下面各个部门的介绍就简单多了

ES(行政部)分成4个小组:资产小组——包括入职领取计算机、IP电话就是从这里库房取到的;物业小组——负责协调大楼物业,内部物业等,当时我想到的是《人件》里描述的家具警察;差旅小组——负责公司的商务差旅;最后是新分离出来的客服小组,如果对 ES 工作流程不熟悉的话可以统一找客服小组帮忙,另外前台也属于客服小组。

Tech-NO 我已经很熟悉了,就在旁边,交流也多,还都属于 KCN 的管理。Tech-NO 分成值班组——专门蹲机房,接受新机器,很辛苦;系统组——安全、调优等;网络组——公司所有网络设备,和IDC机房的接口,公司、机房、分公司之间的内网连接,IP、网络流量管理;DBA,这个比较容易理解;还有一些不是特别容易划分的职责,包括备份、PV、DNS、采购、TechNO内部IT系统维护等等

MIS 是内部的 IT HelpDesk 部门,包括 sohu-inc.com 邮箱、IP 电话、设备维修更换、办公耗材、甚至做了一个会议室预定系统. hehe。似乎最近也归 KCN,和 Tech-NO 一起合作。

LEGAL 的准备其实很充分,很精彩。可惜是下午的第一堂课,我非常困.. 只是记下了目前这个部门一共七位律师,一个助理。

所有的商务合同都必须一式四份,除了 LEGAL 要留底外,FINANCE 也需要留底。FINANCE 反复强调预算的重要性,任何费用都要事先填写 PR 单。介绍者最后拿出一个表格出来,讲解什么样级别的人可以批准什么样费用标准的 PR 单。

严格来说 IA(内部审计)部门和公司直接运营没有任何关系,这个部门的存在是为了符合 SO404 的要求。部门的最终领导/负责对象是董事会任命的审计委员会,和搜狐管理层没有任何关系。哪天如果发现 Charles 有贪污行为可以去告发他,呵呵。SO404 规定如果高管未尽职责而确认了会误导投资者的文件,将受到1M美元罚款,直至10年的监禁;如果是蓄意误导投资者,将面临5M处罚直至20年的监禁。

本来课程计划里还有 CS 部分的介绍的,因为时间因素就取消了,小小遗憾一下。

最后从 ES 那里获得一个消息,威新大厦将被更名为搜狐网络大厦(或搜狐国际网络大厦),回来搜索了一下,报导还不少

目前的分布是:
8层 CallCenter、QA、GameOper、Sports、Entertainment
9层 sogou、go2map
10层 wireless、ES、MIS
11层 Olympic、游戏研发、TechNO、CPC、ChinaRen、Club、CMS 的技术人员
12层 Content、SAS、Marketing
15层 Focus、HR、LEGAL、FINANCE、销售?管理层

除此外在华清嘉园还有一部分人,上海、广州、福州有分公司,每个省有移动增值业务相关的人员

机房情况为:
最大的是皂君庙机房,将近 2k 台
其次是电信兆维机房
网通土城机房
赛尔的教育网机房
移动和联通的机房——做移动增值业务
GAME 全国各地都有分区服务器
天津、上海、成都、广州、南京等地有静态 HTML 发布镜像

威海、杭州、南通等地也有做视频加速的机房

Topic: 商业 生活

"似是故人来"

周三在搜狐碰到一位故人,搜狐RD测试部的头头,罗学超。

其实我和她彼此对人都没有什么印象,只是说起我是来自亿邮的时候,她恍然大悟的说起她以前接触过亿邮的人:她的第一份测试工作就是在"renren"测亿邮的邮件系统,那是2000年的事情了。然后她还补充说当时来测试的是两个人。

我激动万分,那可不就是屠敏和我么。那时候可真算是两大帅哥哦,不过现在都是人老珠黄了。

罗MM还记得俺们的CTO李勇先生,估计主要是和两大帅哥的反差太强烈了,所以印象也很深刻... //grin

附: 替老朋友做个广告,测试部门很缺人,欢迎加盟。据她说搜狐的测试是几大门户里面最好的,姑妄信之。

Topic: 生活

俺也回来了

过了三天没有泡网的日子。

周四、周五、周六参加新员工培训,周四、五是在十五层的四海会议室,周六是参加一个拓展训练。正是项目最紧张的时候,前两天培训的时候每当有休息时间,我就赶紧冲回办公室,检查我们部门和其他业务部门的进度情况。周四晚上还别人都下班了还得回复并撰写一堆 email。周六晚上打开 bloglines,顿时发现三天时间积攒了好多好多的 feeds,硬着头皮看下来......找两条有意思的吧:

1. 云风也开始讨论用户身份认证方案。内容没有什么,倒是回复中有人提到多服务 SSO (single sign on) 的标准解决方案是用 kerberos。其它解决方案也是用 kerberos 的模型,日后有时间学习学习 kerberos

2. 最新的一期 Firefox trunk build 增加了好多特性。Trunk 版本自从 Win32 加入 Cairo 后我基本上就天天用了;办公室的系统由于 FireBug 还不完全支持 trunk (无法在 console 中输入命令),所以最近一直在用 2.0。不过总体来说 trunk 的可用性稳定性和正式版没有什么区别,没事可以考虑装个试试看,不过还是应该创建一个和正式版不一样的 profile。

Topic: 技术

使用 httplib 而不是 urllib/urllib2

决定写一个 python 脚本来定时检查用户登录是否好用,本打算使用以前用过的 urllib2 模块的——qyt同志和我曾合力写了一个脚本从网站上爬数据,追踪我妈购买的三支股票的情况,结果发现并不那么合适。因为挂在 passport.sohu.com 这个域名下的机器有多台,urllib2 无法分布通过不同的内部 IP 进行连接。

在 CHM 里面搜索了一番,找到了 httplib。首先用 HTTPSConnection(host) 指定连接的目标,然后就可以发送 request 了;另外它也支持 https。

另外要注意的是 httplib 缺省是阻塞无超时机制的 socket 连接。使用之前需要

  1. import socket
  2. socket.setdefaulttimeout(5.0)
Topic: 技术

尝试了一下 Python for S60

两个月前就在我的 3650 上安装了 Python for S60 1.2,不过一直很忙没有时间尝试写个脚本玩玩。因为 PuTTY 刚发布的最新版本 0.59 加入了串口支持,所以今天通过蓝牙连上手机上的 Python Console 跑了几行代码。

WinXP SP2 缺省的 Native Bluetooth 驱动连接 S60 后会安装 2 个串口,一个 Outgoing 一个 Incoming。用 PuTTY 连接 Incoming 的串口,然后在手机上运行 Python 后执行 "Bluetooth console" 就可以进入 PuTTY 的终端界面了。

最新的 Python S60 已经不再从 Nokia 网站上下载了,而是 sf.net。对于我的 3650 来说(相同平台的包括 N-Gage 等),仅有 1.3.1 可以使用,从 S60 2nd 开始最新的 Python S60 就都可以用了。

Python S60 似乎只支持几种 Unicode 的编码,所幸 PuTTY 可以使用 UTF-8;不过 PuTTY 0.59 刚刚支持串口,似乎还有很多 bug,动不动就崩溃掉。

仿造教程写了一个脚本,看起来运行很正常,呵呵。

  1. import contacts
  2. import time
  3.  
  4. db = contacts.open()
  5. for i in db:
  6.     contact = db[i]
  7.     title = contact.title.encode('utf8')
  8.     last_modified = time.strftime('%X, %x', time.gmtime(contact.last_modified))
  9.     print contact.id, title, last_modified
订阅 RSS - qyb的博客