2007年9月19日星期三

李彦宏

百度CEO
百度今天的宣讲不错,尤其李彦宏的演讲。
 
如果早四年创业,如今全球最大的搜索引擎还说不定是谁呢。

2007年9月18日星期二

char c=255?

char c=255;
int i=c;
what will be the value of i?

Unfortunately ,the answer is undefined.

It is implemention-defined whether a plain char is considerer signed or unsignded.

On a SGI Challenge machine,a char is unsigned,so the answer is 255. On a Sun SPARC or an IBM PC,where a char is signed,the answer is -1.

some standard library functions ,such as strcmp(), take plain chars only.

(C3.4 Signed and Unsigned Characters)

promotions

Before an arithmetic operation is performed,integral promotion is used to create ints out of shorter integer types.(C.6.1 Promotions)

The Boolean,character,and integer types are collectively called integral types. The integral and floating-point types are collectively called arithmetic types .(4.1.1 Fundamental Types)

unsigned long val = 0;
char a = 0x48;
char b = 0x52;
val = b << 8 | a;
A 20992 B 21064 C 72 D 0

what is the answer?

2007年9月16日星期日

2007年9月11日星期二

emacs tips

emacs

10 Linux commands you've never used

10 Linux commands you've never used
介绍了10个linux下面的命令,但并非是never used
1.pgrep look up or signal processes based on name and other attributes
2.pstree display a tree of processes
3.bc An arbitrary precision calculator language
4.split split a file into pieces
5.nl number lines of files
6.mkfifo make FIFOs (named pipes)
7.ldd print shared library dependencies
8.col filter reverse line feeds from input
9.xmlwf Determines if an XML document is well-formed
10.lsof list open files

LibSigC++

LibSigC++
对libsigc++的简单介绍。libsigc++是实现类型安全回调的一个C++模板库。

在很多情况下,检测事件的代码与处理事件的代码需要去耦合,特别在GUI编程里面。按键点击事件的检测与点击事件的处理是分开的。
与C++的异常处理的情况相似,检测到异常的代码并不知道如何去处理异常,需要将异常交给用户代码去处理。

libsigc++提供了信号(signal)和槽(slot)的概念。slot对应一个回调函数,信号(signal)与槽(slot)相关联(attach),但一个信号被发射(emit)时,相对应的槽被调用。

sigc::signal<返回类型,参数类型,...> * onxxxx
onxxxx=new sigc::signal<返回类型,参数类型,...>
onxxxx->connect(sigc::mem_fun(...));
onxxx->emit(...)

2007年9月7日星期五

懒惰的程序员: Interview questions

懒惰的程序员: Interview questions

netcasper,我一直在订阅他的blog,很好的程序员。
推荐的两个面试问题:
  • What are your long-term goals?
  • What book is currently on your nightstand?
Why should I hire you?
Why should I join you?
都是很狂妄的问题。

Sample Interviews - Miguel de Icaza

Sample Interviews - Miguel de Icaza

Mono的一些interviews问题,not face-to-face interviews,而是通过email分派实际的编程任务。
列举了俩个interviews的例子。
Am posting here two of the interviews that we used in the past to hire for positions into the Windows.Forms group and the Mono VM engine. These interviews are typically conducted over two to three weeks.
这两个题我都没有看懂。

什么是Mono呢
http://www.mono-project.com/

Mono provides the necessary software to develop and run .NET client and server applications on Linux, Solaris, Mac OS X, Windows, and Unix. Sponsored by Novell (http://www.novell.com), the Mono open source project has an active and enthusiastic contributing community and is positioned to become the leading choice for development of Linux applications.


inet_ntoa(), inet_aton()

inet_ntoa(), inet_aton()
点分十进制IP地址字符串与struct in_addr数据结构的相互转换。

#include 
#include
#include

char *inet_ntoa(struct in_addr in);
int inet_aton(const char *cp, struct in_addr *inp);
in_addr_t inet_addr(const char *cp);

gethostbyname(), gethostbyaddr()

gethostbyname(), gethostbyaddr()
主机名与IP地址之间的相互映射。

原型:
#include 
#include

struct hostent *gethostbyname(const char *name);
struct hostent *gethostbyaddr(const char *addr, int len, int type);

gethostbyaddr虽然传递的参数是char* 类型的,但实际传的时候应该是addr是指向struct in_addr的指针,
而len为
sizeof(struct in_addr),type为AF_INET.
struct hostent {
 char *h_name;  /* official name of host */
char **h_aliases; /* alias list */
int h_addrtype; /* host address type */
int h_length; /* length of address */
char **h_addr_list; /* list of addresses */
}


2007年9月6日星期四

Beating the Averages

Beating the Averages
当你像一般人那样行动时,你只能成为一般人。
Lisp不是一般人用的。
The average big company grows at about ten percent a year. So if you're running a big company and you do everything the way the average big company does it, you can expect to do as well as the average big company-- that is, to grow about ten percent a year.

The same thing will happen if you're running a startup, of course. If you do everything the way the average startup does it, you should expect average performance. The problem here is, average performance means that you'll go out of business. The survival rate for startups is way less than fifty percent. So if you're running a startup, you had better be doing something odd. If not, you're in trouble.

Eric Raymond has written an essay called "How to Become a Hacker," and in it, among other things, he tells would-be hackers what languages they should learn. He suggests starting with Python and Java, because they are easy to learn. The serious hacker will also want to learn C, in order to hack Unix, and Perl for system administration and cgi scripts. Finally, the truly serious hacker should consider learning Lisp:
Lisp is worth learning for the profound enlightenment experience you will have when you finally get it; that experience will make you a better programmer for the rest of your days, even if you never actually use Lisp itself a lot.

Practical: A Simple Database

Practical: A Simple Database

understanding what’s special about Lisp

2007年9月4日星期二

条条大路通Google

条条大路通Google


今天是在 Google上班的第一天,距我从北邮毕业刚好一年,但我却感觉自己像个工作三、四年的人了,这都是拜可爱的研究生教育所赐。从研一开始就不停地做兼职做 实习,毕业后这一年里又换了两次工作。回想这段求职时光,不说是跌宕起伏,也是意外丛生,充满了戏剧性。所以我想在今天把这些经历记录下来,做个笔经、面 经、感想大杂烩,如果对谁的求职有点参考和帮助,将是莫大的荣幸,同时也算弥补一下损失殆尽的RP,为我的中文系MM找工作带来一点好运气吧。
按时间顺序,从第一份兼职开始:

Computer Associates

2003的冬天,CA刚刚设立北京研发中心不久,还属于人少活多的初级阶段,只好猛招兼职。我就成了第一批幸运的壮丁。作为全球最大的IT 管理软件公司之一,CA的直接竞争对手就是IBM和Veritas,当时Veritas还没有被Symantec收购,就在王府井东方广场和CA同一幢楼 办公。
招聘的过程现在想起来还是十分有趣。简历通过初选后,直接来公司做为期三天的新员工培训。期间会被冷不丁地叫去一对一面试,针对简 历问一些项目和技术方面的问题。培训的最后一天是笔试,英文纯技术的,如果学过UNIX系统管理或者考过MCSE会很有帮助。也许因为我们是QA,所以试 题对编程要求并不高。笔试完后马上判卷,然后大BOSS逐个叫人出去谈话,被叫出去的人多半是要说拜拜的,大BOSS会耐心解释你为什么不适合公司的要 求,直到你心悦诚服地离开。即使没被录用,仍然会拿到三天全额工钱,将近1000元。
当时,CA的待遇和东方广场的高档写字楼严重不匹 配,我们的leaders一谈起4500/月的薪水,全都满脸苦相。如果是夜班工作,从下午5点干到晚上12点,会有额外的1500元补助。实习生薪水和 正式员工一样。后来听转正的同学说员工走得厉害,老板一调查,发现待遇竟是全北京最差的,也不知道比对了哪些企业,反正结果是工资翻了一番,那就该是 9000/月了,2005年初普通QA的基本工资,Dev的更多些。
CA给我留下了太多美好的回忆,我对外企最初的良好印象全是来自于CA的。情人节那天,公司在每位员工桌上放了一支玫瑰,似乎女员工还收到了巧克力。处处温馨弥漫、花香扑鼻,那一刻,我觉得被资本家剥削也真是种快乐。
此外,公司提供免费早餐, Pantry里还有免费的研磨咖啡和小饼干,那是我们这帮馋嘴的学生每天上班以后首先要疯抢的好东西~~

Bell Labs Research China

BLRC是美国贝尔实验室在国外设立的第一个研究机构,主要搞通信方面的新技术新应用研究,位置在人大西门偏北些的航天长城大厦。BLRC 的实习生绝大部分是配合正式的研究员做概念验证、程序开发、数据收集等工作,还是有相当技术含量的。美国本土的贝尔实验室号称是同类研究机构中的No. 1,牛得不行,他们的工作可以是不顾忌市场因素的纯科研,像半个国家科学院似的。而BLRC因为是有中国特色的贝尔,所以会弄一些合作项目挣挣钱,但大部 分工作还是可以做到Interest Driven的。
BLRC的正式员工多为博士,大牛硕士也有。薪水似乎很高,实习的时候坐我旁边格 子里的哥们说,他在他的mentor的桌子上看见了一张纳税单子,纳税记录是5000,这么算下来税前工资得有多少!也不知是真是假。果真如此,一个正式 员工纳的税可以给两个实习生发工资了。我是2004年11月去的,110元/天,外地学生来实习有额外的补助。
BLRC的实习环境是我见 过最好的,可以说,只有在BLRC做实习生,才叫做“实习”,其它地方都得叫兼职。首先,从环境上来说,正式员工都在航天长城大厦15层,实习生都在13 层,独门独户,工作空间都是相同的。要是负责的电脑多些,就会占两个人的地方摆机器,比总统套房的双人床都宽敞。其次,正式员工和实习生之间以师生相称, 就像是一个特殊的学校,绝没有大公司里比鲤鱼骨头还多的规矩,以至于我后来去IBM实习时严重水土不服。
最重要的一点是,老师们都很照顾 实习生的学业,支持学生把工作和完成个人论文结合起来,并且主动帮助学生们找课题。(当然,前提是你是学通信相关专业的)为了选题的事情,BLRC的 Technical Manager还亲自找我谈了一个小时,指点迷津,真是挺感激的,也深受鼓舞。这个时代,学校里的导师不顾学生死活去当老板了,反倒是这些老板给学生当起 导师来了,真是奇怪得可以。
BLRC常年招聘实习生,一轮面试即可,面试官就是你所投项目的负责人。研究员们也会互相推荐面试的学生,力争不放走一个能干活的。我当初就是这样被“调剂”了,原因可能是面试官问我对J2ME有啥看法时,我直截了当地回了一句“J2ME没前途!”
面试的问题都是技术性的,基于简历以及项目的技术需求,因为面试官都是牛人,且实习生的总人数很少(也就二三十人,不像IBM那种一招就几百人),所以面 试还是相当有挑战性的。我能够稀里糊涂地蒙混过关,想必是百折不挠地一口咬定J2ME没前途,最终感动了上苍吧!
此外要说的是,我们这届实习生多半都内推到了Lucent的工程部门,这个内部招聘是在校园招聘之前进行的,所以他们都不像我这样巴巴地找工作,轻轻松松进了Lucent,拿9K/月的工资。

Microsoft

微软是我正式开始找工作后,投的第一家大企业。微软的笔经、面经已然铺天盖地了,我只说说自己的感受。因为一直在用Java做开发,大一学 了半年VC之后就再也没动过,因此对微软是一点希望都没报,只求个当炮灰的机会。所以我参加了第一轮微软校园招聘,2005年国庆节刚过就被拉去面试了。
我投的是MSN的SDET,心想这个部门是新成立的,又是测试职位,应该不会太为难我可怜的C++。事实和我想的大概差不多,从上午九点开始到下午一点, 共四个小时,四个面试官交叉面试,其中用英语大概两个半小时,技术性面试两个小时。做智力题,问一天内时钟的时针、分针成直角有多少次;也写了代码。第一 次写代码,面试官同意我用Java;第二回,好像是MSN部门的Manager,叫Williams Wan,他一定要求用C++。我就瞎写一气,写完给他看,他边看边皱眉头,说“意思是对了,但怎么看怎么不像C++啊!”
-_-!
结果当然是干净利索地收到了据信。但这次面试的确是太重要了,从中得到的收获也很大。在被微软折腾了四个小时之后,至今所有的面试我就再也没有紧张过,全部轻松搞定。

IBM CDL(第一次)

2005年10月底,托CDL的师兄Chris内部推荐一个兼职职位,经过面试顺利拿到offer。IBM是我一直以来的梦想,为了这个兼职职位,我辞掉了BLRC的实习生,只求在IBM校园招聘时能占些先机。
我隶属WBI测试组,职责是做基于WebSphere Process Server应用程序开发,这些应用程序会被用作QA的Test Case,也可能用来做客户演示,还挺有意思的。
IBM 校园招聘开始后,我参加了笔试,成绩一般。在一线经理的推荐下,很顺利地进入了面试,共有三轮,前两轮都是一线经理加Team Leader,第三轮就是二线经理亲自来“聊天”了。IBM和微软非常不同,微软侧重于考查基础知识和分析应变能力,所以笔试题面偏窄但难度较高,面试也 会问些智力题;而IBM侧重考查知识面与项目经验,笔试题都不难,但很杂,面试基本不脱离简历,全部基于项目问问题,其中必有一半的时间要用英语。
按师兄的话说,如果能见到二线经理,基本就算搞定了。所以秘书通知三面的时候,我轻松极了,把面试真当聊天了。
二线问我,“在IBM工作遇到什么困难没有?”
我说,“编程序时找不到API的Javadoc,太不爽了。”
二线一脸惊奇,说,“不可能吧。”
我说,“就是的啊!”
面试结束后二线马上就把我的问题发给了SOA API的一个主要开发人员,然后把那个Staff Software Engineer的回信转给了我。第二天,推荐我的一线经理过来问我,昨天面试的时候说没有文档的事了?我说是啊,没问题吧?!他笑着拍拍我的肩膀没回 答。
面试之后就没了消息,等啊等啊,每天去水木上看,差不多每个部门都发offer了,就我们这个组没动静。我暗想,不会因为 Javadoc的事被开了吧,那也太悲剧了!一直等到12月中旬的某天,下班之前,一线经理满脸凝重地把我叫到小会议室,告诉我由于部门调整,这个 team所有的校园招聘名额都取消了。
从那天起,我只能重新开始疯狂找工作,直至最后签了Aicent。到Aicent报道的第二天, 2006年2月14日,CDL另一个部门的一线经理给我打电话,说是我原来部门的一线把简历推荐过去了,问我对她们的职位有没有兴趣;如果有,可以过去 “谈谈”,就能上班了。这也是IBM的规矩,如果应聘者通过的二线面试,另外的部门就无需再面,可以直接录用。
我考虑了一天,打电话过去放弃了。至此,我与IBM的第一次亲密接触宣告结束,2月15日的这个选择影响了我之后一年的生活。

Oracle

Oracle的招聘每年都是派头十足,而且总是姗姗来迟。06校园招聘一直等到2005年11月底才开始。笔试的时候每人发一块印有Oracle徽标的手表,后来我弟弟把这块手表要去了一直戴到现在。
Oracle的笔试题比较基础,像是一张数据库理论基础课的期末试卷,里面穿插一些Java编程的基础知识,有一道题至今还记得,就是问事务的四个属性是什么。
笔试过后大概两、三周的样子,面试通知下来了,地点是翠宫饭店,每个面试官一个豪华小单间,有茶水和小饼干吃。当时Oracle技术职位共有五个组,我首 选Beijing Strategic Project Group备选Server Technology Stack Testing and Performance,面试的时候才知道后者是深圳的职位,临时换了Applications Product Group的职位。面试官是位非常有气质的女士,后来知道她就是这个组的Manager。
我一点准备都没有,她上来问知不知道什么是 ERP和CRM,我是知道的,但不明白为什么一下子就卡壳了。她就笑了,我就流冷汗了。另一个组的面试更糗,我用过Oracle 9i,但说自己用过10g,面试官就问我10g的管理界面是啥样的?我说不就是Java写的那种桌面应用程序么!他就乐了,说,“10g的管理界面是基于 Web的!”
由此可见,没有做过的事情一定不要装蒜,不然面对这些经验丰富的面试官,丢人现眼只是时间问题。
Oracle 面试完后,又是漫长的等待。我已经被IBM拒了,每天行尸走肉一般地在CDL兼职,心里只想着Oracle快来拯救我吧,我一定帮你打垮IBM。见水木上 不停有人打电话过去问,而HR先是说圣诞节前肯定有消息,圣诞过了又说元旦前肯定有消息,元旦过了又说春节前肯定有消息。一直等到2006年2月7号,我 在云南元阳的梯田旁大嚼五香豆腐干的时候,Oracle打来电话,告诉我Beijing Strategic Project Group给了offer,我当时眼皮都没眨一下就直接拒了。朝思暮想了几个月的offer,一分钟之内就放弃了,自己都佩服自己的魄力。可能是因为已经 签了Aicent,也可能因为等得太久,以至等得一点感觉都没有了。反正Oracle的薪水也不太高,唯一的福利好像就是笔记本用过三年后便归个人所有 了。

中联绿盟

绿盟是国内网络安全行业的前三甲之一,那两个是天融信和启明星辰。06校园招聘,绿盟提供了安全类的、C++/Java开发类的和测试类的职位。我投了Java开发工程师。
笔试安排在2005年12月21号上午9点半,我8点55分到了楼下,看见一帮员工正急火火地往里冲,后来才知道,绿盟不是弹性工作制,每天早上9点钟必须要到岗的。
绿盟的笔试是我见过最变态的,厚厚一摞子试卷,足有50页,什么题型都有,时间好像只有两个小时。面试官提醒大家,题目铁定是做不完,所以只挑会的做!
考题包罗万象,有网络安全的基本概念,比如DOS、IDS/IPS、SQL注射等等;有C++编程的,Java编程的,都是基础知识,选择题或者写程序;有数据库方面的;还有一堆开放问题。写到最后手都不听使唤了!
一周多以后,通知面试,面试也是我见过最有阵势的,六个面试官一字排开,我像被三堂会审似的坐在对面。技术题目倒不难,针对简历的项目问题也容易对付。面 试官中有一个年纪稍大的坐在最边上,不停地打着哈欠。面到一半的时候,他冷不丁地冒出来一句,“贝尔实验室是不是在海淀南路那个?”其他人立即停下来,等 着他提问。我当时就想,这家伙肯定是个人物。果不其然,他就是绿盟的沈总,二面就是他单独出马。公司总裁亲自参加两轮面试,可见绿盟对校园招聘的重视程 度。
二面基本上就没啥技术问题了,我问了一下薪水,沈总说对于应届生,如果没有过人之特长,绿盟给薪水都是一样的,并不像传言的那样“高于业界平均水平”。
他又问我,“你是怎么看绿盟的?”
我当时也不知道哪根筋错位了,立马答道,“我觉得今天的绿盟就是三年前的华为。”
沈总笑逐颜开,把笔记本电脑转过来,对着我说,“这么说,你就拥有了一个资深投资专家的眼光。你看,这是世界顶级的人力资源咨询公司Hay Group给绿盟做的规划。这个公司开价是相当高的,国内的客户都是中石油,中移动这样的大企业。但是他们每年会选几个中小型公司,以极低的价格为他们做 规划,因为他们看准了这些小公司今后必定会成为举世瞩目的大企业,以此便可以证明他们的眼光是多么精准。上一次Hay Group选了华为;这一次,他们选中了绿盟!”
我想,我真是撞到好大一坨狗屎运啊!
不久以后,绿盟的offer就到了,这是我拿到的第一个offer,6K/月。考虑到自己的专业与绿盟的核心技术始终是不对口,薪水又不高,我最终放弃了,但绿盟人对技术的追求和友善专业的作风还是给我留下了深刻的印象。

Aicent

在绿盟面试的时候,我把手机设成呼叫转移,所有来电都转到CQ的手机上。绿盟这边刚面试完,CQ就短信我说,Aicent公司通知去面试,地点是西单首都时代广场。
Aicent 成立时间不长,但在国际短信/彩信漫游领域已经取得了不错的成绩。公司总部在美国硅谷,老板是华人,大部分员工也是华人,所以看着很像一个民族企业。公司 的研发部设在西单首都时代广场,主要分成四个大组:Java Team负责短信网关的开发,C Team负责彩信网关的开发, BOSS Team负责公司内部统一计费平台的开发,还有一个QA Team负责所有产品的测试工作。我应聘的是Java Team,面试不算难,全是常用的编程技术,offer给得也很快,6.7K/月。
Aicent的短信网关是基于JMS中间件的,兼容 SMPP、CMPP、HTTP、UCP、CIMD以及很多运营商自己搞的私有协议,对应聘者网络通信、多线程方面的知识要求较高。由于公司规模不大,做的 又是24×7的国际电信网关业务,每个人的责任就很重,而且越到节假日越不敢松气,短信网关这玩意儿最喜欢在节假日罢工,如同二环路最爱在你要误火车的时 候堵车一样。
我在Aicent学到的东西太多了,短短十个月比研究生三年的收获都多。有句话叫“小公司里学做事,大公司里学做人”。在 Aicent这种不大不小的公司里工作,做事做人的能力都得到了极大的锻炼。作为开发人员,不仅要和team内的同事打交道,和QA打交道,还要参加其它 team的设计讨论,参加业务部门的需求分析,参加客户部门的技术支持,两个星期完成一套协议栈开发,半夜三点钟一个人搞定了和菲律宾运营商的联调,还是 很有成就感的。而且,在西单上班相当爽,楼下就是五星级电影院,午饭后可以去中央音乐学院里听着钢琴散步,或者去天安门广场看看毛主席。
但我深知,虽然自己很适合Aicent,但它并不适合我。锻炼自己没有错,但个人价值不仅要靠能力来体现,工作经历也很重要。如果押定了Aicent能像 Google一样发迹起来尽人皆知,那么留在这里是不错,但我并没有这个信心,也不愿意押这个宝,我不是个喜欢押宝的人。在我现有的工作履历中,最有亮点 的部分是学生时代的实习经验,要让这些亮点发挥出最大的价值,就不能等得时间太长。出于这种考虑,在感觉自己学习得差不多的时候,我就得跳槽了。刚好某日 和本科同宿舍好友聊天,他是传说中李开复的第一批“关门弟子”之一,我问他Google招不招用Java搞通信的,他说招啊,我就把简历发过去了。于是, 漫长的Google之路由此展开,那天是2006年8月7日。

IBM CDL(第二次)

2006年9月底的时候,Chris在MSN上说CDL相熟的team里有一个开发职位社招中,我就把简历塞给他内推。Google之路过于艰难,据某个报道说99.5%以上的应聘者全被拒了,这可不是闹着玩的,所以我还是一颗红心,两手准备吧。
Chris于是嘲笑我,转了一大圈,又要回IBM了吧!
我觉得倒不是,这回申请的职位做J2EE/Domino平台的Web应用开发,比起校园招聘做QA来,还是更喜欢这个。倒不是有偏见,我做过QA,深知QA也有很大的学问,但我更喜欢把自己想的东西加以实现,做软件开发才是我的乐趣。
2006年10月13日,第一次面试。标准的IBM三人组,一线经理加两个Team Leader,问项目问技术,有30分钟左右的时间要用英语。接下来要做一份笔试题,全是选择题,Java方面的基础知识,一如既往的泛而不深。面试和笔试各一个小时。
10月19日,二线经理面试。面试完在回去的城铁上就接到电话,给了口头offer,快得也有点让人犯心脏病了!
11月15日,去亚运村签了书面offer。
12月11日,正式入职,签劳动合同。
从始至终,IBM体现出了相当高的职业素养,虽然流程繁多冗长,但井井有条纹丝不乱。在我开始正式工作以后,对这种素养有了更深刻的认识。新员工培训课的 老师说,“IBM是世界第三大官僚机构,第一大是联合国,第二大是中国政府”。公司内部各种规章条例手续流程多如牛毛,正是这些牛毛保证了一个近四十万员 工的跨国企业能高效地运行,并稳坐IT领域老大的位置。
在IBM,无论做什么事情,都可以在内网里找到相关的说明,在内部Domino应 用里找到自动化工具进行办理。无论是入职、离职、出差、请假、报销、保险、培训等等等等,不用问任何人,自有现成的工具帮你搞定。还有一个Buzz HR系统,各种各样的问题提交上去,HR部门会在24小时内给出解答,正式工作过的人肯定会有这种感受,如果能时时得到HR快速准确的答复,那是多棒的一 种感觉。
我想这就是IBM追求的风格,谁说大象不能跳舞!
IBM的福利待遇也是相当不错的,网上总有人在质疑,把IBM 尤其是CDL划入了廉价工厂的行列,我想这有失公允。不妨算一下,Band-6月薪7500加800补助,全年14个月外加最多一个半月的 Performance Bonus,这些就12万了。工作满三年会有一笔10万的Saving Fund,平摊下来,前三年的平均年薪就是15万以上,算不错了。IBM的工作时间也比较弹性,只要不是Tivoli那样变态的部门,加班不会太多。年假 17天,没结婚的探亲假一年5天,中秋节圣诞节放假,病假前3个月全额工资,产假一休就半年见不着人了,如果有适当的理由还可以申请停薪留职。假期还是足 够多的,至于有没有时间可以请假那就是另一回事了:)
2007里,IBM CDL要扩张1000多人,因为大中华区的生意很是红火,活多得急需人手来完成。Henry Chow说过,“IBM是打群架的”,所以人多并不是IBM的弊端,而是它的特色。对于追求稳定、注重长期发展的人来说,这里是不错的选择,尤其是CDL 的社招比起校园招聘要高效容易得多,想跳槽的人要优先考虑喽。

Sybase

Sybase ASE Porting Team的Manager不知道在哪里看到了我的简历,打电话过来问我想不想去面试。当时我正被Google和IBM双线夹攻,心想再多一家也无所谓了,于是就答应了。
面试安排在2006年10月19日早晨8点钟,我7点半就来到复兴门旁边的中化大厦,Sybase的办公区空无一人。等了半天,一个帅哥急火火地窜上来,他就是面试官,Porting Team Manager,姓冯。
冯Sir一大早赶过来开电话会议,见我还拎着午饭的饭盒,就领我到餐厅把饭盒放冰箱里。怎料匆忙之间竟然把门卡忘在办公区里了,冯Sir又急火火跑去叫来 一个保洁工,用她的门卡刷开了办公区的门,才算了事。两个小时以后,一面结束,我径直下楼骑车上班去了,饭盒就忘在了Sybase的冰箱里,好在中化大厦 离西单不远,中午我又走过去把饭盒拎回来,费尽周折总算吃到了这顿饭。
一面包括90分钟的笔试和半小时的面试,笔试内容和IBM的社招笔试差不多,题型丰富了些,多了简答题和编程题。冯Sir开电话会议的时候我就把笔试卷子做完了。面试由他和另一个员工搞定,问题也都是很常见的那种,会有一些英文对话。
吃完午饭,冯Sir就打电话过来说一面通过了,马上会安排美国那边进行一次电话面试。Porting Team负责的是Sybase的主打产品Adaptive Server Enterprise,我这个职位是给ASE重新设计开发一套客户端软件,所以二面的时候着重问了一些Swing/SWT方面的东西,这玩意儿被我玩得滚 瓜烂熟的,当然不在话下。
二面过后不久,接到Sybase的通知,要最后一次HR面试,也就是所谓“谈谈”了。Sybase的HR Manager是我见过的最有型有款最professional那种,叫Vinson,西服笔挺皮鞋锃亮。Vinson主要和我谈了谈这边的工作情况, offer大概是10万/年多一点,年假10天,但有5天必须在圣诞节休,很古怪的规定,最后朝我要了三个联系人做Reference Check。
IBM 的offer紧接着Sybase的来到,我也只能和Vinson编个瞎话把offer拒了。这点儿实在是太损RP了,不清楚当时咋想的,其实照实说明情况 也没什么不好。反正只能深深地道歉了,若是Vinson或者冯Sir看到这里,希望你们千千万万不要扁我,我真是一时糊涂啊!

Google

自打内推了Google的Wireless Search职位,我就开始习惯了遥遥无期的等待。Wireless Search这个职位校园招聘的时候我就投过,投了以后除了感谢信就再也没啥反应了。那还是2005年10月份的事呢,事隔将近一年再次申请,期待积累已 久的RP来一次大暴发吧!
2006年8月11日,回家路上接到HR Sandy的电话,进行了一个小时的电面,聊得很痛快。Sandy当时就告诉我,本轮电面通过了,请等待下次电面的通知。
8月21日,第一次技术电面,问了一大堆算法以及GSM短信标准相关的知识。
9月23日,第二次技术电面,一个数组查找的算法题做了足足四十分钟!
2007年1月10日,我都以为Google把我忘了,结果被拉去onsite,面了两轮,不仅画了UML图,还做了类似“估算天上一共有多少架飞机在飞”这种智力题,圆满了。
1月23日,第三次技术电面,感觉不好,题做得很勉强,一天都犯恶心,不知道咋回事。
2月14日,Google的offer成了情人节礼物。MM说Google真是好,情人节发offer,就算情场不得意的人,职场也得意了,高高兴兴过节。
关于Google的面试,已经有很多贴子说过了。秘诀就是“不要害怕”,其实问题没有那么难,主要是被面试官给“唬”住了,脑子一乱就不能集中精力思考 了。从网上面经里得到的最重要一条经验就是,要不停地和面试官沟通,哪怕有一点点新想法,都要说出来。遇到困难时也要说出来,请面试官给点提示。千千万万 不要闷着头一言不发地想,想了半天才说想不出来,那样不被毙掉才怪。
接到Google offer时,我很是犹豫了一下。毕竟对于IBM是相当留恋的,这里曾是我学生时代的梦想,也是我一直努力的方向。Google虽然红得发紫,但一个企业 的成功是真刀真枪打出来的,而不是靠免费午餐和琳琅满目的零食。对于一个不了解的人,Google的光环太过耀眼,甚至惹人嫉妒;但随着走近,这道光环就 逐渐消失了。正像onsite的面试官对我讲的,他写代码的时候什么文档都找不着,程序注释是二十世纪的,完全对不上号。想找一个合适的API,只能把所 有备选的源代码统统读一遍。“这个公司有它很fancy的地方,也有它很ugly的地方。”这是一句很中肯的评价。Google并不是神仙,它很成功,缘 于每一个Googler都很努力,但它还是创业不久的“小公司”。从这个层面上讲,与Aicent没什么区别,存在的问题也都差不多。
至于Wireless Search,虽然在美国、日本等地都取得了不错的成绩,但在中国这种啥都搞特殊的地方,前景怎么样还真不知道。何况政府时不时地给Google“优待”一下子,麻烦得很。
但我最终还是说服自己接受了Google的offer,薪水自然是原因之一,有我喜欢的工作内容是最重要的一个理由。我在北邮学了七年的通信,不想就这么 放弃去搞纯IT了。而且,我深深感觉到自己是个不安分的人,IBM适合我,但我却有点不适合它。我期待一个更宽松更自由的地方,能把自己的想法亲手变成现 实。
现在,我终于坐在Google游乐园一般的办公室里了。毕业一年,到今天为止总算安定下来了。折腾了很多地方,是该实实在在做点事情了。希望我的选择没错,希望Google是我的Company. Right。

回顾我的求职经历,一年前的选择至关重要,两种情况可以有下面的比较:
签Aicent,最终跳到Google 签IBM CDL
动荡的一年,RP狂损 稳定的一年,RP++
没有户口,自掏腰包解决 公司解决户口
第一年年收入9万 第一年年收入15万
没有积累,仍是新人 已经有了一年积累,开始寻求提高
对口的专业,喜欢的开发职位 不对口的专业,测试职位
学到很多专业知识 学不到太多专业知识
目前月薪10k+ 目前月薪8k+
在五道口上班,骑自行车 在西二旗上班,城铁加班车
对于这个比较,可能每个人都有不同的想法,我个人认为自己的选择是正确的,付出的代价得到了应有回报,虽然过程中包含很多运气的成分。

签Aicent的时候,根本没想过有一天能到Google工作。对于能否学到东西,也完全没有把握,唯一的感觉是我喜欢这个职位,而不大喜欢IBM那个。 因此当时的决定是相当感性、相当冒险或者说不尽情理的,遭到家长的反对和朋友的质疑毫不奇怪。去年的户口指标紧缩,Aicent的户口申请被拒了,CDL 校园招聘的户口却全都批了,得知这个消息后,家长的反对就变成了不停地埋怨。
但我到底没有后悔,并非意志多么坚定,只是冥冥中认为既然老 天让我在IBM校园招聘中出乎意料地功败垂成,让我在Oracle校园招聘中莫名其妙地苦苦等待,又让我恰逢其时轻而易举地拿到Aicent的 offer,那想必是他有意这么安排的,自有他的道理,我只需要听命就是了。这一年间,经历一回回波折一次次考验,最终不也顺利地搞定了么。
条条大路通Google,只要坚定信念,不懈努力,我想每个人都能找到自己得意的那一片天空,实现自己理想的那一个目标。


http://purplexsu.spaces.live.com/blog/cns!E0027AFC1939BAA8!515.entry

BenjaminRutt.emacs


BenjaminRutt.emacs
;;File:       .emacs
;;Author: Benjamin Rutt
;;Email: brutt@bloomington.in.us
;KEYBOARD SECTION
;global keyb maps
(global-set-key "C-xg" 'goto-line)
(global-set-key [home] 'beginning-of-line)
(global-set-key [end] 'end-of-line)
(global-set-key [C-home] 'beginning-of-buffer)
(global-set-key [C-end] 'end-of-buffer)
(global-set-key [S-tab] 'indent-region)
(global-set-key [?C-/] 'void) ;forward reference
(global-set-key [C-backspace] 'backward-kill-word)
(global-set-key "C-s" 'isearch-forward-regexp)
(global-set-key "C-r" 'isearch-backward-regexp)
(global-set-key "C-M-s" 'tags-search)
(global-set-key "C-xC-n" 'find-file-other-frame) ;open new frame with a file
(global-set-key "C-xC-c" 'intelligent-close) ;forward reference
(global-set-key "C-x55" 'split-window-fork) ;forward reference
(global-set-key "M-n" 'scroll-n-lines-ahead) ;forward reference
(global-set-key "M-p" 'scroll-n-lines-behind) ;forward reference
(global-set-key "M-u" 'void) ;don't bind upcase word
(global-set-key "M-l" 'void) ;don't bind downcase word
(global-set-key "C-cC-c" 'comment-region) ;have to force it for some reason
(global-set-key [C-tab] 'yic-next-buffer) ;forward reference
(global-set-key [C-S-tab] 'yic-prev-buffer) ;forward reference


;ABBREVIATION SECTION
; abbreviation mode
(setq-default abbrev-mode t)
(if (file-exists-p "~/.abbrev")
(read-abbrev-file "~/.abbrev"))
(setq save-abbrevs t)

;;dynamic abbreviation customizations
(setq dabbrev-case-replace nil)


;MISC SECTION

;; When you scroll down with the cursor, emacs will move down the buffer one
;; line at a time, instead of in larger amounts.
(setq scroll-step 1)

;syntax hilite
(global-font-lock-mode 1)
(setq font-lock-maximum-decoration t)
(custom-set-faces)

;show paren, brace, and curly brace "partners" at all times
(show-paren-mode t)

;show column number in status bar
(column-number-mode t)

;show more info in taskbar/icon than just "Emacs"
(setq-default frame-title-format (list "%65b %f"))
(setq-default icon-title-format (list "%b"))

;show time on status bar
(display-time)

;make the y or n suffice for a yes or no question
(fset 'yes-or-no-p 'y-or-n-p)

; don't automatically add new lines when scrolling down at the bottom
; of a buffer
(setq next-line-add-newlines nil)

;be able to do Ctrl-X, u/l to upper/lowercase regions without confirm
(put 'downcase-region 'disabled nil)
(put 'upcase-region 'disabled nil)

;show ascii table
(defun ascii-table ()
"Print the ascii table. Based on a defun by Alex Schroeder <asc@bsiag.com>"
(interactive)
(switch-to-buffer "*ASCII*")
(erase-buffer)
(insert (format "ASCII characters up to number %d.n" 254))
(let ((i 0))
(while (< i 254)
(setq i (+ i 1))
(insert (format "%4d %cn" i i))))
(beginning-of-buffer))

;insert date into buffer
(defun insert-date ()
"Insert date at point."
(interactive)
(insert (format-time-string "%a %b %e, %Y %l:%M %p")))

;convert a buffer from dos ^M end of lines to unix end of lines
(defun dos2unix ()
(interactive)
(goto-char (point-min))
(while (search-forward "r" nil t) (replace-match "")))

;vice versa
(defun unix2dos ()
(interactive)
(goto-char (point-min))
(while (search-forward "n" nil t) (replace-match "rn")))

;;This method, when bound to C-x C-c, allows you to close an emacs frame the
;;same way, whether it's the sole window you have open, or whether it's
;;a "child" frame of a "parent" frame. If you're like me, and use emacs in
;;a windowing environment, you probably have lots of frames open at any given
;;time. Well, it's a pain to remember to do Ctrl-x 5 0 to dispose of a child
;;frame, and to remember to do C-x C-x to close the main frame (and if you're
;;not careful, doing so will take all the child frames away with it). This
;;is my solution to that: an intelligent close-frame operation that works in
;;all cases (even in an emacs -nw session).
(defun intelligent-close ()
"quit a frame the same way no matter what kind of frame you are on"
(interactive)
(if (eq (car (visible-frame-list)) (selected-frame))
;;for parent/master frame...
(if (> (length (visible-frame-list)) 1)
;;close a parent with children present
(delete-frame (selected-frame))
;;close a parent with no children present
(save-buffers-kill-emacs))
;;close a child frame
(delete-frame (selected-frame))))

;;a no-op function to bind to if you want to set a keystroke to null
(defun void ()
"this is a no-op"
(interactive))

;;compute the length of the marked region
(defun region-length ()
"length of a region"
(interactive)
(message (format "%d" (- (region-end) (region-beginning)))))

(defun split-window-fork ()
(concat
"spawns a new frame so that a 2-way split window in one frame becomes "
"2 top-level frames. Has the same action as ")
(interactive)
(progn
(let ((current_window (selected-window))
(other_window (next-window (selected-window)))
(current_buffer (window-buffer (selected-window)))
(other_buffer (window-buffer (next-window (selected-window)))))
(make-frame)
(select-window other_window)
(delete-other-windows))))

;;the following snippet was copied from the Oreilly-published book
;;"Writing GNU Emacs Extensions" by Bob Glickstein.
(defalias 'scroll-ahead 'scroll-up)
(defalias 'scroll-behind 'scroll-down)
(defun scroll-n-lines-ahead (&optional n)
"Scroll ahead N lines (1 by default)."
(interactive "P")
(progn
(scroll-ahead (prefix-numeric-value n))
(next-line 1)))

(defun scroll-n-lines-behind (&optional n)
"Scroll behind N lines (1 by default)."
(interactive "P")
(progn
(scroll-behind (prefix-numeric-value n))
(previous-line 1)))

;;begin buffer-switching methods, which I bind to Ctrl-TAB and Ctrl-Shift-TAB
;; ----------------------------------------------------------------------
;; Original yic-buffer.el
;; From: choo@cs.yale.edu (young-il choo)
;; Date: 7 Aug 90 23:39:19 GMT
;;
;; Modified
;; ----------------------------------------------------------------------

(defun yic-ignore (str)
(or
;;buffers I don't want to switch to
(string-match "\*Buffer List\*" str)
(string-match "^TAGS" str)
(string-match "^\*Messages\*$" str)
(string-match "^\*Completions\*$" str)
(string-match "^ " str)

;;Test to see if the window is visible on an existing visible frame.
;;Because I can always ALT-TAB to that visible frame, I never want to
;;Ctrl-TAB to that buffer in the current frame. That would cause
;;a duplicate top-level buffer inside two frames.
(memq str
(mapcar
(lambda (x)
(buffer-name
(window-buffer
(frame-selected-window x))))
(visible-frame-list)))
))

(defun yic-next (ls)
"Switch to next buffer in ls skipping unwanted ones."
(let* ((ptr ls)
bf bn go
)
(while (and ptr (null go))
(setq bf (car ptr) bn (buffer-name bf))
(if (null (yic-ignore bn)) ;skip over
(setq go bf)
(setq ptr (cdr ptr))
)
)
(if go
(switch-to-buffer go))))

(defun yic-prev-buffer ()
"Switch to previous buffer in current window."
(interactive)
(yic-next (reverse (buffer-list))))

(defun yic-next-buffer ()
"Switch to the other buffer (2nd in list-buffer) in current window."
(interactive)
(bury-buffer (current-buffer))
(yic-next (buffer-list)))
;;end of yic buffer-switching methods


;C/C++ SECTION
;set up my tab length as a variable
(defun get-my-tab-length () 3)

;build a list from 1 to n
(defun iota
(n)
(if (= n 0) '()
(append (iota (- n 1)) (list n))))

;build the tab list
(defun create-tab-list
(length)
(mapcar (lambda (n) (* (get-my-tab-length) n)) (iota length)))

(defun my-c-mode-hook ()

(local-set-key "M-f" 'c-forward-into-nomenclature)
(local-set-key "M-b" 'c-backward-into-nomenclature)

;set up the tab stop list so I can do manual Ctrl-I tabs to specific points
(setq tab-stop-list (create-tab-list 60))
(setq indent-tabs-mode t)
(setq tab-width (get-my-tab-length))
(setq c-basic-offset (get-my-tab-length))
(setq standard-indent (get-my-tab-length))
(setq c-style-variables-are-local-p nil)

;don't give me newline automatically after electric expressions are entered
(setq c-auto-newline nil)

;if (0) becomes if (0)
; { {
; ; ;
; } }
(c-set-offset 'substatement-open 0)

;first arg of arglist to functions: tabbed in once
;(default was c-lineup-arglist-intro-after-paren)
(c-set-offset 'arglist-intro '+)

;second line of arglist to functions: tabbed in once
;(default was c-lineup-arglist)
(c-set-offset 'arglist-cont-nonempty '+)

;switch/case: make each case line indent from switch
(c-set-offset 'case-label '+)

;make the ENTER key indent next line properly
(local-set-key "C-m" 'newline-and-indent)

;syntax-highlight aggressively
(setq font-lock-support-mode 'lazy-lock-mode)
(setq lazy-lock-defer-contextually t)
(setq lazy-lock-defer-time 0)

;make DEL take all previous whitespace with it
(c-toggle-hungry-state 1)

;make open-braces after a case: statement indent to 0 (default was '+)
(c-set-offset 'statement-case-open 0)

;make a #define be left-aligned
(setq c-electric-pound-behavior (quote (alignleft)))

;do not impose restriction that all lines not top-level be indented at least
;1 (was imposed by gnu style by default)
(setq c-label-minimum-indentation 0)
)
(add-hook 'c++-mode-hook 'my-c-mode-hook)
(add-hook 'c-mode-hook 'my-c-mode-hook)


;;WINDOWS section
(if (or (eq system-type 'windows-nt)
(eq system-type 'ms-dos))

;;progn is like (begin e1 e2 ...) on scheme. i.e. execute one or more
;;statements in sequential order
(progn

;;get around inadequacies of WIN9x/NT's window manager, which
;;always places new application windows in the same place in
;;some cases. I want random placement of new windows so I can
;;Alt-TAB easier, and know where I'm going. The following code
;;places the top left corner of the initial frame at a random
;;horizontal location on screen and a fixed vertical location.
(setq initial-frame-alist
`((top . 0)
;;Parse out milliseconds field, and scale it down.
;;The current-time function is random enough for purposes here.
(left . ,(/ (car (cdr (cdr (current-time)))) 8000))))
)
)

;;LOCAL HOOKS SECTION - note this section should be last to allow an
;;.emacs_local file to override the .emacs. The .emacs_local file should
;;contain anything specific to a particular environment/platform/machine.
(if (file-exists-p "~/.emacs_local")
(load-file "~/.emacs_local"))


;INACTIVE/NOTES SECTION

;The following is a failed attempt to make sure that .emacs is
;byte-compiled into a new .emacs.elc whenever it changes, to support
;the fastest loading of the latest changes. This does not work,
;because emacs always loads the ~/.emacs.elc if it exists, and you
;can't overwrite it with a byte-compile command to replace it if you
;are in the middle of executing it. If anyone has an improvement that
;does work, please email me.

; (if (file-newer-than-file-p "~/.emacs" "~/.emacs.elc")
; (progn
; (message "byte-compiling .emacs to update .emacs.elc!")
; (byte-compile-file "~/.emacs")))


;useful system-information variables:
;system-name
;user-login-name
;system-configuration

2007年9月3日星期一

谈谈Google的面试

谈谈Google的面试
王咏刚

去年做了不少面试(据说自己的面试次数在Google全球都是排在前列的,有点儿不敢相信),也参加了好几次校园招聘之类的活动,体会总或多或少有一些。也许可以给大家分享一些不涉及公司秘密的东西,一来让大家了解Google为什么聚集了这么多出色的技术人才,二来也可以让那些投简历的朋友在心理上准备得更充分一些——说实话,的确有些应聘者是因为对Google招聘流,还有面试要求不太适应,而没有展现出自己应有的水平的。

毫无疑问,Google在最近几年里一直是世界顶尖技术人才的聚集地。远的不说,在Google中国,我们身边就有ACM世界冠军,奥赛金牌得主,以及若干知名技术公司的前CTO。但这并不是说Google招的全都是那些拥有偌大的名头或来历的牛人,我觉得,只要有真本事,进Google并不像想象中那么难。

关于招聘流程,其实开复在《与未来同行》那本书的第185页已经讲得非常清楚了,不外乎是下面几个主要的步骤:

1. 筛选简历
2. 电话面试或笔试
3. 若干轮面试
4. “招聘小组”讨论
5. “副总裁小组”最后复核
6. 发录用通知,签合同

筛选简历似乎和其他公司没有什么本质的不同。我经常会在内部系统中收到招聘团队转来的,要我帮忙看一看并给出建议的简历。在国内,大多数人的简历都会有中英文两份。只要有中文简历,我一般就只看中文内容了。但许多从美国来的同事就会优先看英文简历。所以,投简历时中英文简历要尽量一致。

看应届毕业生的简历和看有工作经验的应聘者的简历是大不相同的。

对于前者,说心里话,有区分度的信息通常不会很多,不外乎学习成绩、论文或著述(如果有的话)、实践项目(如果有的话)、竞赛成绩(如果有的话)等少数几项,至于自己说自己精通某某,熟悉某某,这个东西水分多少很难讲,反正我一般是权当参考的。所以,对应届毕业生更常见的做法是在学校或公司举行笔试,看笔试情况来决定谁可以进入下面的流程。

但对于有工作经验的人,简历就非常非常重要了,因为你可以很容易地利用各种信息,从两份简历中比较出应聘者的实力差异(当然不是绝对准确的,因为还要考虑某些人更善于包装自己的因素)。在写简历的时候,大家其实可以设身处地地想一想,如果你在审阅一份这样的简历:应聘者声称自己精通某某平台,某某技术或某某语言,但又举不出足够有说服力的证据;声称自己在前公司做过项目经理、研发部经理等关键职位,但又无法清楚地描述自己在关键职位上有什么样的表现;声称自己做过N多项目,但又举不出一个有技术含量,或是可以体现自己价值的……你会给他或她进入后续流程的机会吗?

电话面试是一件很有趣也很容易惹来争议的事情。至少我自己觉得,虽然电话面试可以省些时间,但的确比较难于全面了解一个人,不像面对面的面试那样有现场感,也没有直接交流时的各种便利——比如,可以从对方眼神、表情中发现他的许多特点。具体到技术面试上来说,电话面试让对方写代码是比较难的,据我所知,有的面试官的确会让对方写一段简短的代码,然后在电话中念出来。这个方法是不是真的有效,的确很难讲。但同时,我个人认为,电话面试有一个最大的优点,就是可以更容易地考察对方的语言交流能力:因为电话上的沟通不如面对面那么方便,在电话面试中你可以很容易地看到对方是如何利用这个“有限信道”来向你传递信息的。能够在电话面试中清楚、明白地展示自身优势的人,至少在语言交流方面都不会有什么问题。——顺便强调一下,交流和沟通能力对于现代软件开发来说,实在是太重要了。

笔试主要是在招聘应届毕业生或实习生的时候使用,去年Google在好几所高校都做过比较大规模的笔试。那些笔试题目中,有一小部分是我出的,所以了解一些情况。和有些公司强调思维灵活性的智力题不一样,Google的笔试题最最重视的学生在CS 专业上的基本功和灵活运用基础知识解决问题的能力。去年用在校园招聘的笔试题有许多套,大多都分为选择题和编码或算法题两个部分。做过这些题目的同学应该比较清楚:选择题考察的不外是对CS基础课、专业课的掌握情况,可能会涉及数学、逻辑、计算机原理、数据结构、算法、编译原理、操作系统等方面;而编码或算法题考察的则是编程的基本功力(比如对语法要素的正确使用,代码的可读性等等)和灵活运用算法知识解决具体问题的能力(比如算法的选择,算法的优化程度等等)。

其实,出笔试题是一件苦差事。要想得到逻辑上没有漏洞,适于CS或相关专业的学生解答,易于上手,又有一定区分度的题目,实在是太难太难了。每套笔试题都要花费工程师许多精力,出完了题目,还要更多工程师来把关,看有没有漏洞。即便如此,去年用在高校的笔试题里还是存在少数表达含混或者逻辑上有漏洞的情况——在提高笔试题质量方面,我们还得继续努力。

若干轮的现场面试是应聘者必须经历的,最有挑战性的,也最能影响面试结果的环节。Google对人才的要求向来都很高,这种要求也主要体现在现场面试的环节中。一个应聘者在若干轮的现场面试中,可能要面对的是有不同技术背景或技术特长的面试官,每个面试官所考察的重点也可能各有侧重,每个面试官也都有自己喜欢的提问方法和面试题目。达不到标准的人要想在Google的若干轮面试中“蒙混过关”,概率应该是接近于零的吧。

许多人都想知道Google在面试中最看重的是应聘者哪方面的能力。我记得在去年在校园宣讲中曾反复强调过:仅从专业角度上说,Google会要求一个应聘者既具有扎实的CS基本功,也拥有灵活的思维方式和解决新问题的能力。当然,专业以外的东西,比如真诚、坦率,比如交流能力,对职业的正确态度等等,有时比专业能力更重要。

因为每个面试官有每个面试官的特点,不大好介绍和评价其他同事的面试方法。我自己在面试时,一般喜欢先考察一个偏重基本功的题目,然后再考察一个偏重思维灵活性的问题。我还有一个倾向,可能也是某些应聘者比较担心的,就是边聊边问,根据应聘者的自我介绍,提最有针对性的问题。比方说,对方讲,自己有五年的C语言编程经验,精通(老实说,面试多了,对 “精通”这个词就非常敏感,总觉得这个词背后是有无数玄机的)C语言,那我多半就会立即考察一下对方对C语言指针或函数调用的掌握程度;如果对方说自己精通的其实是JavaScript语言,那我自然会渴望知道,对方是不是真的清楚,JavaScript作为一种动态语言或脚本语言有哪些与众不同的语法特点;如果对方说自己对J2EE平台和流行的框架非常熟悉,那我一般会先从最基本的面向对象设计以及最基本Java对象模型开始问起;如果对方说自己有丰富的软件设计经验,那我这里有好几个并不一定真正存在的软件需求,需要对方画出系统架构的设计图来。

面试时现场写代码或现场设计算法几乎是一定会发生的事情。拿我来说,对方写代码时直接敲在电脑上或是写在纸上,选用什么样的语言,或者使用什么样的代码风格,其实都是无所谓的。我最最关心的是应聘者对编程序这件再普通不过的事情的理解程度。一般说来,只要时间允许,我都会和应聘者一起,逐行讨论他刚写出的代码,比如函数接口设计是否合理,有没有其他的设计方式,变量类型的选择是否合适,代码运行时的时间或空间开销是否太大,代码中两个看上去相似的片段是否可以合并,等等等等。如果是现场设计算法,那我一般会要求对方在纸上用最直观的图示把他的算法思路表现出来——这多半是因为我的脑子比较慢,如果对方不能描述得非常清楚的话,我很难判断他的答案究竟是不是正确。一般说来,Google经常使用的面试题目都可以从不同的角度入手来解答,出色的应聘者还经常能想出面试官从未见过,又完全正确的新答案来。所以,做面试官也要开动脑筋,判断对方的答案哪一步正确,哪一步有问题。几场面试下来,面试官也要消耗许多脑力和体力的。

面试结束后,面试官要写面试报告,而且要用英文来写。写报告会占用不少时间,我自己的英文并不熟练,一个45分钟左右的面试结束后,就多半要花20到30分钟来写报告。不过一年下来,写面试报告倒成了自己提高英文写作能力的一个重要练习项目,也算是对付出的这许多时间的一种回报吧。

正如开复在书中所介绍的那样,所有面试报告都要送到“招聘小组”和“副总裁”小组评审。一个应聘者是否能加入Google,就要看这两次评审的结果了。

先大概介绍到这里吧,其他相关的感想以后再续。对了,忘了提一点,Google中国招聘的技术职位并非只有软件工程师一种(参见http://www.google.cn/jobs/),上面讲的不少要求是针对软件工程师的。其他技术职位在对应聘者能力的要求方面各有差异,面试时的侧重点也不尽相同。比如下面两个特定领域的研发职位(顺便在这里贴一下广告,呵呵):

移动和无线应用工程师:http://www.google.cn/support/jobs/bin/answer.py?answer=57922
Linux/开源软件研发工程师:http://www.google.cn/support/jobs/bin/answer.py?answer=55003