写本文的目的,大叔不是为了装逼(虽然说话的口气有时候也确实有点装逼,性格导致的,咳。。。我得改),其实大叔在公司也只是小罗罗,本文的目的主要是为了向大家展示如何通过各种软技能应对面试官,这个应对包括如何沟通,引导,展示技巧以及更多地让面试官跟着你的思路走,让面试官根据你的亮点挖掘你其它的优势,而不是一味地跟着面试官的思路走(这就有点危险了),也就是如何更多地展示你强的一面而尽量避免暴露自己的弱点,尤其是Senior和Lead在面试的时候需要注意这一点,当然,这确实需要下很多功夫,那就体会一下大叔在去年的一次面试经历吧。
事情起源于一个2010年11月12号(周五)的一个电话,下午刚吃晚饭被部门领导叫进一个小会议室说有事找我谈谈,大概事情是欧美一个大客户要在北京总公司建立第2个ODC(离岸研发中心)(第1个ODC已经在公司的另一个分公司建立了1年多了大约400人),这次面试很多高级开发工程师都已经面过了,但是客户就是不给签约ECA(个人另外和客户单独签的安全协议),原因是ODC的技术带头人一直没招到,公司提供了大批的架构师、Tech Lead、以及懂技术的项目经理去面试,都栽进去了,所以让我去试试,说一会公司的高级副总M先生马上就打电话过来。
在1万多人的公司工作,能让VP亲自打电话,其实心里还是蛮激动的,但其实大叔是不愿意去的,因为当时手头的项目也是很不错的,做亚洲最大的KTV连锁系统相关的东西(数据实时采集,商业智能分析,以及后期全新开发的WPF版的KTV点播系统),下面30多人,其实也挺不错的,主要是有了孩子,所以想先稳定2年。可是M先生打来电话了,大意就是客户面试比较严格,视频会议以及远程桌面现场编程,这就意味着,面试个过程中客户不仅可以看到你的表情和心里,还要通过远程桌面在你现场编程的时候看到你每敲的任何一个字母。很多人技术很强,但是印度式英语沟通上,或者代码编程细节上,甚至MSDN查询的细节上都有可能被客户challenge住,公司已经浪费了几个月时间,而且也浪费了大批的优秀候选人,客户给了deadline,如果没有满意的人,客户有可能就把这个ODC建立到欧洲那个公司了,所以希望我去试试。虽然我不情愿,但是在领导近于命令式的语言以及一大堆的憧憬中,大叔也没有办法,尝试着说先给我一周时间准备吧,因为我已经1年多没有进行编程了,但领导说,事情紧急,就下周一吧,给你两天准备时间。在坚决地拒绝以后(因为周一要去国贸客户现场讲解新项目的架构,所以没办法),面试终于选择在周二早上8点进行。
其实周一下午公司的人还是给予了一些面试指导,毕竟所有的人都很看重这个事情,尤其是和客户沟通方面需要注意的事情以及稍微了解了一下客户的脾气(因为之前有个人很坚持自己的方案牛逼,不愿意听从客户的方案解释,所以被fire)。
虽然之前有过和印度人共事的1年多经验,但是依然有点怯,连通视频我一瞬间,大叔惊愕了,面试官居然是Martin Fowler的翻版:
(Martin Fowler头像, 我的偶像啊!)
不过人还是挺友善的,在刚开始的5分钟,我主要是做个人介绍,大概介绍了一下最近2年做过的项目,和承担的职责,其实客户对这个不太感兴趣,他们感兴趣的是现场面试,so, 我说了一句:我准备好了,我们可是开始了么?客户来劲了,视频里说了一下题目,同时Live Meeting里也把英文题目发过来了(可能是怕听不懂吧),题目非常简单:找出第一个句子中有而第二个句子中没有的单词。
我很诧异,面试不会这么简单吧,就算我1年多没写过代码了,完成这个题目也是不成问题的吧,可是回过头来一想,我面的职位不是高级开发,也不是架构师,而是技术管理,于是我明白了。。。
客户:这时候客户直接问我要estimate估时了
大叔:这个时候我并没有告诉客户说,我需要时间先分析一下,问完问题才能给你时间,而是直接告诉他,我还没用细想,但是我觉得大概的乐观(optimistic)估时应该是1小时(其中包括,5分钟的思考,5分钟的问题确认,5分钟的设计,25分钟的编码,10分钟的code review以及10分钟的测试和bug fix),但悲观估时可能是1小时20分钟左右,因为冲突可能会出现无法预知的问题需要客户或者相关人的帮助。
客户表示Good。那就开始吧,滴答,滴答,滴答。。。。
在考虑了一系列的常见的和特殊的场景以后,我问了很多问题,但总时不超过5分钟,大概如下(记不太清楚了,就写这么多)
然后又诚恳地问了一下,英文下除了逗号,句号,空格,问号,斜杠,感叹号以外,还有其它的语言符号么?(因为要用这些分割单词哦),客户比较开心这个问题,又告诉了我几个:反斜杠,引号,又特别提示了一下我,中划线不算分隔符。 中途也遇到了一点尴尬,就是对这些符号的英文单词,记得不是很清楚,所以老搞错,最后客户还是直接在live meeting上敲出才确认的,感谢IM。
编码正式开始了,其实中途的编码过程到时没什么问题,因为题目确实比较简单,但是代码总不能都在控制台的Program.cs吧,也不能只写一个简单的静态方法吧?题目虽然简单,不能体现什么架构,但是要展示点东西吧,于是一个有点搞笑的类文件InterviewEngine.cs出来了,但这时候,我并没用急于写代码,而是把我的代码处理逻辑的想法用英文写在这个类的summary里了,写了大概5分钟左右(这就姑且算我的设计吧),然后代码上,写了一个单例(有点不伦不类,后面会解释)(静态字段+静态构造函数的方式),当然在正式处理方法里也仔细考虑了很久,比如2个参数的空值判断,异常判断,以及分隔符的定义易修改等做了处理,当然中途我故意把字符的大小写没用区分(因为我想在后面的code review阶段来体现),当然该有的注释啥的也都有。
代码结束,为了表明自己真的做了code review,自己还是硬着头皮把键盘提示符一行一行地走了一遍,以便让客户在编辑器里看到我真的是在做这件事,因为code review是项目里非常重要的一步,也为了证明我做了,我在这时候才把上面故意没用区分大小写的问题加上了。
由于不是按照TDD的方式来做的,所以单元测试是在基本的code review以后才开始做的,由于之前和客户确认了,不用使用MBUnit/NUnit之类的单元测试工具,所以只是手工写了一些case,做的case不仅包括了正常的,也包括了不正常的了,当然边界测试,空值测试,异常捕获等也都覆盖到了。(后面项目开始的时候,客户由于知道我熟悉MBUnit,所以在项目上让我们用了这个,而没有用其它人都推崇的NUnit)。
时间比我预想的提前了5分钟,暗自庆幸中,于是告诉客户,我已经写完了,当然也客气的说了一句:“你能帮我check一下,有没有其它的我没用想到的错误么?”。
"Okay, Tom....",客户舒了一口气说,你再检查一下获取单词集合的时候有没有什么遗漏?我实在想不起来遗漏了哪个判断,参数判断,单词萃取,单词存储,查询性能等都考虑到,只有虚心而真诚地请教了客户:“I cann't find any problem now, could you give me some comments?”
客户这时候在IM上敲了一句话:Hello, tom, how are you?
OK, God,我明白了,原来是分隔符连续的问题,这时候分割出来的单词是空,所以这时候不需要在去判断集合里是否包含这个单词了,因为空根本就不需要添加到集合里。我对客户的提示表示感谢:“Oh, good catch, thanks R****.”,然后很快给予了修复,并且添加了相应的测试用例。
客户对题目表示满意,本意为面试就要结束了,但是客户这时候又给了一个需求变更,让我在现有控制台程序的基础上做一个方便测试代码,经过互相讨论,最终的理解是:做一个控制台的输入功能,让用户分别输入2段字符串,然后给出结果,在这一步,我差一点栽了,因为对Console.Read,Console.ReadLine以及Console.ReadKey的用法实在想不起来了,再试了很多次之后,才搞定的了,以至于客户问了我一句:你是不是这些知识已经忘记了,我只得遗憾地回答:“是的,长时间不写类似的程序,很多基本的东西都忘记了,看来需要经常来回顾一下用法。” 没想到,客户说了一句:“对,我也是经常忘!”
哈哈,看来没丢脸。
客户又问了一下,我平时编码的时候是如何保证质量的?我会意的笑了一下,我说我有T氏法则,也就是我整理的Guideline,所有Team的人都要遵守,Guideline里囊括了开发过程中要预防的各种各样的问题,比如输入输出验证,编码,性能,加密解密,信息安全,客户端安全,多条件,多线程,异常处理,资源释放,代码覆盖率,单元测试等等,还顺便问了一句,你要看么?因为我现在用的是自己的机器,可以发给你一份。
客户表示想看,看了我发的英文版以后,客户表示:你在我们这里干的话,我想你的很多条规则都是可以用上的。
之后客户又突然回来,问我为什么面试的时候要用单例,我很诚实地回答,因为面试时间有限,所以我要想办法体现我的各种各样的能力,然后我们俩又针对单例讨论了很久钟,期间我讲我了解的单例模式,然后所有的实现都在VS2010里用代码展示给他了,最后,我连把单例的泛型版本都展示给他看了,他表示赞许,因为我在视频里看到他点头了。
面试持续了2个多小时了,因为很自信自己在设计模式方面的理解,所以为了抢占主动权,所以我豁出去地说了一句:你还想问我其它的设计模式么?
R先生:不用了,看你对单例研究这么深入,我觉得也没有必要再问其它的设计模式了,因为我相信你肯定也很熟悉了,而且你的职位又不是开发人员,而是要Manage他们,好了,你能再把你之前的工作经历详细地和我说一遍么?
有戏了,客户居然再次让我介绍之前的项目了,于是把自己之前的几个项目介绍了一下,由于之前的项目都不小(第一个项目,26人做了2.5年,第二个,16人做了1年,第三个34人做了半年),客户了解了我的职责以后,什么都没有说,只是说了一句,我们的项目和第一个差不多,你应该能够cover住的,技术面试这里就先结束了,1小时以后我们继续来聊非技术的吧,因为我要先回家吃饭(因为这时候已经是客户时间晚上7点了)。
什么?!!这才是上半场?下午我还要和我Team的人开会布置任务呢!!不过还是礼貌性地说了一句,感谢你的面试,我的准时上线的。
在这里,其实我自己感觉,技术面试这一关其实应该是八九不离十了,因为从和客户沟通的效果来看,基本上都是赞许,下半场还没开始,所以我在这里先总结一下我的面试体会:
1. 要有非常明确、规范、令人信服的整体结构。所以对代码分块很重要,同时这也是我们很容易疏忽的地方。各块代码的功能如下:
Block 1:描述性的注释。首先把题目放到注释里,让reviewer知道你现在做的是哪道题;其次是要对题目进行简短的分析,让reviewer了解你的思路,节省他阅读代码的时间;再次是提一下你将用到的关键技术以及你的concern。比如说你现在是按小文本的输入写出的最好的代码,但如果是大文本输入,需要更改逻辑。这主要体现出一个人的沟通能力。不管你自己知不知道该怎么做,首先要想到的是让对方知道哪些是你能够应付得来的,哪些是你的问题。忌讳按照自己的假设去答题。如果条件不明确,需要你自己提出来。客户很喜欢别人跟他讨论,这样可以明确需求,减少风险和不确定性。客户也很喜欢别人有问题时马上提出来。总体来说,他们很能容忍你有问题,但不能容忍你隐瞒问题。
Block 2:自动生成的代码。这里最重要的是注意命名规则。根据需要增加一些注释也是很好的习惯
Block 3:代码的主体部分。方法前面加注释是好习惯。变量最好集中声明,显得比较整洁有条理。一定不能遗漏的是数据的合法性验证,健壮性是代码的重要指标之一。Good test case 和 bad test case 至少各有一个。程序的可扩展性也很重要,少用hard code。
Block 4:异常处理。一定要有。
2. 尽可能多地去显示你的能力。从客户的角度来说,他们也很欢迎candidate全面地去展示自己
1. 多用OO的概念去思考问题
2. 替客户去想他们自己都没有想到的问题,但不要天马行空。例如,Scalability就能很好地展示自己思维的缜密
3. 适当展示自己design的能力,这一点很重要。即使是很小的问题,也是需要全局把控的。
3. 一个很重要的观念需要candidates转变过来。客户面试的根本目的不是为了难倒candidates,而是为了给candidates一个展示自己能力的平台。所以对于客户给出的题目,应该用工作的态度去应对,而不是用考试的态度去应付。很多优秀的候选人给我们的感觉是:让他实际工作,他可能会考虑得很全面,而答题的时候,他就显得比较马虎,完成要求就算结束。原因大概就在这里。这样的结果是,别人只能看到他考试的能力,看不到他工作的能力。
技术上半场是技术面试,没有问到管理的问题,但是我也想办法体现了自己的能力,比如告诉客户我还是比较了解软件开发过程的,从需求分析,需求确认,设计,编码,Code Review,测试以及需求变更方便的东西,在估时方便有悲观估时也有乐观估时,同时在自我介绍的时候也通过项目的实际经验向客户灌输一些其实你懂很多东西这个观点。
客户相对来说是个比较容易沟通的人,在需求确认的时候就能看出来了,没有趾高气扬的架势,以至于后来我反而去表扬了他一句“Good catch”,所以,在任何面试的场合,只要沟通做到位了,其实技术差一点也无所谓,就像前面,我连Console.Read的基本用法都不会了,也没有什么事。
下半场的面试是下午1点开始的(客户时间晚上8点),主要是问项目/Team管理和沟通方面的问题,主要问题如下:
再回答完这些问题的时候,其实基本上已经过了3个小时了,因为冲突可能因为印度式英文的理解上耽误了一些实际,但总体效果上还是不错的,充分表达了我想说的内容。
后面又大概聊了半个多小时,主要是问我平时是如何发邮件的,邮件里的To/CC/BCC都是怎么用的,以及如何给项目组成员作评价,如果想领导要特殊的支持等方面的软技能了,平时怎么做的,我也就按实说了。
最后,估计R先生也觉得问个差不多了,而且他也困了(已经是他的夜里快12点了),所以就说我们到此为止吧,还说会尽快给答复的,当然最后我也花了很多词汇恭维他,因为他从下午4点一直到夜里12点一直花时间来面试我:我很appreciate你花了那么多时间来面我,对我来说这是一个很excited的面试,你真的是一个很Nice的人,我真的很希望能做你的项目和你一起共事。
这一块面试,主要考察的是2部分,一部分是项目管理方面的东西,看你是不是能很熟练地管理项目,确保项目质量按实提交交付物,同时也考察了你如何和客户进行沟通规避风险,最后要问了一些软技能的东西,比如发邮件的时候,什么时候该To,什么时候该C,而又什么时候该BCC,以及和同事相处及评价的态度等方面的问题。
另外还有一点,我觉得也是非常重要,那就是面试官花了很多时间在你身上,在结束的时候你应该多感谢一下他,这样他会很开心,即便不要你,以后说不定还有机会呢。
通过了,终于让VP Happy了一把,之前pending的一批已经通过面试但不让签ECA安全协议的人也都陆续开始和客户签协议了,当然我也从原来的部门调到了新成立的ODC,同时原部门把博客园的兄弟NewSea挖了进来,以便能够继续之前的工作,1个月交接以后,我就飞往西雅图,去客户现场进行Domain Knowledge的培训去了。
以至于,后来还没用交接完,客户就让我自己去招聘下面的Senior人选了,估计也是为了向他的老板汇报一下吧,所以,在找到合适的人选后,我的第一份正式的邮件,就这样发出了(文中的H*,也是博客园的一个大牛哦,目前和我一个组,有机会和大家介绍一下):
Hi J*** and R***
We are having the candidate H*** who qualify from our interview, we would like get your approval on the hire recommendation.
Below is my feedback after talk with H***, please let me know if you have any concerns.
Thanks.
General feeling in the interview:
H*** is proactive on communication, he has a good communication, also he would like to focus on .net development and passionate about the ODC project.he is talkative and introduce a lot aspects of himself and showing interests in ODC project on the project size, working method, etc.
Strength:
He show a good technical background especially on OOP Design/javascript/asp.net areas.
Deep understand on .NET CLR and OOP Design.
He is confident on the asp.net/JavaScript, and self-learning capabilities.
Weakness:
Limited oral English, however he shows potential as their reading/written English is good.
Hire recommendation: Hire
另外,我们最近也在招人,有兴趣的请联系我,基本条件如下:
本文已同步至目录索引:《大叔手记全集》
大叔手记:旨在记录日常工作中的各种小技巧与资料(包括但不限于技术),如对你有用,请推荐一把,给大叔写作的动力。