ThoughtWorks 面试备忘录
前言
前段时间 ThoughtWorks 在网上和拉勾网合作搞了一次网络招聘,名为抛弃简历!让代码说话!,可谓赚足了眼球,很多程序猿纷纷摩拳擦掌、踊跃提交代码,在网上也是讨论的热火朝天。
我恰巧也在微博上看到了这条招聘信息,按我以前的性格对这类信息是不会感兴趣的。一则自己自信向来不足,二则惯性思维大公司出题一般都很难,比如智力题之类的。只是自己最近恰巧想换工作,于是便点进去看了看。
整个题目看下来觉得还好,不怎么难,主要考察基本功和编程习惯,比如面向对象编程思想、设计模式、单元测试之类的,并且语言不限。有人说他可以用 10 行代码就搞定,我丝毫不怀疑这个说法。但以我对 ThoughtWorks(WikiPedia) 的了解,他们出这道题的意图应该不是比谁用的代码行少或者谁的效率高,这毕竟不仅是 ACM。
于是,自己便认认真真花了两个晚上的时间把这道题完成并且提交上去。在这道题中我用了简单工厂模式和策略模式,如果非要套还可以套一个状态模式。编码也基本反应了我在平时工作中的习惯,并且基本用了面向接口编程以最大可能的降低耦合。
笔试题目
详细信息请查阅拉勾网:【拉勾专场】抛弃简历!让代码说话!
代码要求:
1,语言不限,Java, C#, Ruby, C++, Js, Python, Scala, objective-C统统可以,小语种也没问题,只要你擅长;
2,强烈建议写单元测试;
3,请展示出你超赞的面向对象/函数式编程功底;
4,建议尽量减少圈复杂度;
5,请提交可运行的代码,及相关构建脚本/说明文档(代码运行平台和环境);
FizzBuzzWhizz
你是一名体育老师,在某次课距离下课还有五分钟时,你决定搞一个游戏。此时有
100名学生在上课。游戏的规则是:
你首先说出三个不同的特殊数,要求必须是个位数,比如3、5、7。
让所有学生拍成一队,然后按顺序报数。
学生报数时,如果所报数字是第一个特殊数(3)的倍数,那么不能说该数字,> 而要说Fizz;如果所报数字是第二个特殊数(5)的倍数,那么要说Buzz;如果所 > 报数字是第三个特殊数(7)的倍数,那么要说Whizz。
学生报数时,如果所报数字同时是两个特殊数的倍数情况下,也要特殊处理,比> 如第一个特殊数和第二个特殊数的倍数,那么不能说该数字,而是要说FizzBuzz, > 以此类推。如果同时是三个特殊数的倍数,那么要说FizzBuzzWhizz。
学生报数时,如果所报数字包含了第一个特殊数,那么也不能说该数字,而是要> 说相应的单词,比如本例中第一个特殊数是3,那么要报13的同学应该说Fizz。如果> 数字中包含了第一个特殊数,那么忽略规则3和规则4,比如要报35的同学只报
Fizz,不报BuzzWhizz。现在,我们需要你完成一个程序来模拟这个游戏,它首先接受3个特殊数,然后输出100名学生应该报数的数或单词。比如,
输入
3,5,7
输出(片段)
1
2
Fizz
4
Buzz
Fizz
Whizz
8
Fizz
Buzz
11
FizzFizz
Whizz
FizzBuzz
16
17
Fizz
19
Buzz
…一直到100
电话面试
ThoughtWorks 的工作效率还是挺高的,没过几天便接到他们 HR 的电话,说我代码通过了,他们想了解一些我的基本信息,并且邀请我在合适的时候去他们公司面试。其间,问了我几个印象比较深的问题:
-
期望的薪资?
这个问题比较突然,说实话我还没准备好,近期都忙着看书准备面试了,还没来得及思考。于是便说了下自己现在所在公司的待遇,当然相比现在有所增加,这点我还是没那么傻的 _,HR 听了也没说什么。
-
出差较多,一年大概有 50% 以上的时间,国内国外都有,主要是国内,
能否接受?我对于出短差是不抗拒的,但对于他们给出的这个出差节奏还是觉得难以接受,但为了得到面试机会还是说了不介意出差。
-
英语水平怎么样?
这个我就如实回答了,CET-6,基本哑巴英语,读写没问题,听说不行。HR 听了也没说什么。
-
项目经历?
由于我当前从事的工作具有一定的保密性质,不便透露具体项目信息,想给她讲一下我们系统的软件架构(当时也昏头了,给 HR 讲这个她听的懂啊),HR 让我还是说点工作之余还做些什么吧。于是,我便如实说最近都在学 Python ,用 Python 做了个小程序抓取豆瓣上的电影信息。
经过大概二十分钟的沟通后,约定了面试的时间,便挂断了电话。晚上便收到了 HR 发的面试流程邮件,由此得知有如下几个流程:
-
Paper Test
也就是逻辑测试。
-
Pair programming with Developers
和他们的开发人员结对编程。
-
Interview with Developer and PM
与他们的开发人员和 PM 讨论应聘者的技术专长。
与 ThoughtWorks 的传统面试流程相比,少了 Homework 那一项,因为提前做了。
Paper Test
2014 年 5 月 15 日,七点就早早起床,因为面试的地方在天府软件园,离我这边太远了。洗了个澡,下楼吃了个早饭(平时都不好好吃早饭的,专门为了面试吃了个早饭,怕体力不支),然后就匆匆忙忙的赶公交去了。
这一路真是够折腾的:先是坐公交,然后换乘地铁二号线,然后在天府广场换乘地铁一号线,到了终点站世纪城后又换乘公交,最后还得步行几百米才到达目的地。我当时就想如果以后真在这里上班,这每天在路上就得花费四个小时,还让不让人活啊!
顺便吐槽一下高德地图。本来我一直都是用百度地图的,那天心血来潮(其实是想听听志玲姐姐的声音)换成了高德地图,用了几天就发现了几个严重的问题:
- 耗电太厉害了,只要把高德地图打开,就能看到那电量唰唰唰的往下掉。
- 由于耗电太厉害,导致手机发热严重。
- 最可恶的是经常搜索地点的时候提示我网络不可用,让我检查网络。为此我还专门用其他程序试了网络的,一点问题也没有。然后多搜索几次,它又可以了。
当晚回家就换成了百度地图。
不得不说我的时间观念真的很强,刚好提前二十分钟到达公司。ThoughtWorks 在一栋黄色写字楼的七楼,到楼上后还不能直接进去,他们的门是刷卡的,前台妹妹帮我开了门,我说我是来面试的,她就问我是哪个 HR,我回答是某某,然后她就让我在旁边稍坐一会,她去叫某某。全程态度都很好,后来发现前台妹妹应该也是该公司质量最高的。
乘着等人的间隙,快速扫描了一遍公司环境。公司布置的很温馨,到处墙上都贴着字条、照片什么的,也摆放了一些花花草草,看起来还是很舒服的。他们的办公桌全部是挨着的,没有隔开,没什么私人空间,可能是为了方便结对编程吧。
不一会我的 HR 就过来了,寒暄了两句就把我带到了一个小办公室里,然后给了我一叠试卷和一张保密协议。然后问我现在就开始做还是等十点整开始做,我回答都可以,看你们安排,然后她就说那就现在开始做吧,从 9:45 到 11:45。
整个试卷都是英文的,这一点我也有所耳闻,对于英文的读写我到是一点不担心,何况他们还给了一张单词表。由于保密协议规定不能泄露他们的题目,否则我也可以回忆几道题目出来。这些题目都是逻辑测试题,主要就是模拟程序中的赋值、自增、自减等操作,开始会给你两个例子,让你明白一些基本的操作,然后就是正式的题目。
开始由于紧张会做的慢一些,随后会越做越快。整套题做下来,最难的不是题目本身,而是英文。平时读英文都是读个大概,而现在需要每字每句都读懂,特别是有定语从句套定语从句的,一不小心就会弄错。
遗憾的是,我到最后也不知道自己究竟得了多少分。
午休
做完 Paper Test 也差不多十二点了,HR 想的还是很周到,帮我定了盒饭。于是,我便在他们的餐厅和他们一起用餐。餐厅里的装备还是很齐全的,冰箱、微波炉、咖啡机、各种饮料、茶叶都有,从这点来看公司还是比较人性化的。
结对编程
伤心的时刻终于到来了。
按照计划,下午两点到三点半是结对编程。还是刚才那个办公室,我坐中间,一边一个 ThoughtWorker,都是典型的程序猿长相和装扮,其中有一个说话我有点听不清楚,这让我很惊讶,因为之前我听说 ThoughtWorks 招人都爱招口才好,能说会道的。
首先,他们还是让我先讲一下我的那个程序的思路。我这个人就是不善表达,而且比较懒,连说话都嫌费事,就只是简单说了几点考虑:
- 运用了面向对象的思想,对照程序,举了几个例子。
- 运用了几种设计模式,结合程序,指出了哪些地方用了哪种模式。
- 考虑了扩展性和可维护性,程序的输出专门定义了接口。
他们听完也没说好也没说不好,其实从始至终他们也没说哪里好哪里不好,这让我觉得心里没底。
然后就进入了下一环节,真正的上机编程。题目就是之前的题目,只是增加了一条规则。他们让我先看新规则,由于多少有点紧张,我看题的时候老是看不进去,头脑还会偶尔空白,花费了不少时间才看懂题意,不知道这个会不会已经减分了,虽然他们说没关系,让我慢慢看。
这个时候他们问我,既然我提交的程序里做了单元测试,对单元测试了解程度怎么样?我就如实回答了,对于敏捷开发有所了解,以前自己也尝试过做 TDD 开发,但由于现在的单位没有使用敏捷开发,因此不是太擅长。然后他们就让我考虑一下应该怎么做这道题,还给了我几页纸和一支笔。
我想了一下,新增加的这条规则也不复杂,就修改某个函数,增加几个分支就可以了。于是便照实跟他们说了,他们说只要我想好了就开始,不过让我先写单元测试。然后在写单元测试的时候,在方法名字上,他们给我指出了一些问题,我以前是习惯先写方法名然后再跟测试条件,比如 GetResultWith...,他们说这样不好,并给我举了个例子:ShouldIgnorRule5With...,于是我便依葫芦画瓢写了个测试用例的名字。
其间还有个小插曲。之前那位说话我不太听得清楚的面试官,万万没想到他的英语发音我更是听不清楚,不知道是他的发音不标准呢,还是我的听力太烂?
然后在他们一步一步的引导下,写了三个测试用例,都测试通过。
本来我以为结对编程就到此结束了,万万没想到啊,他们又开始问了。
-
除了 C# 还会哪些语言?
我便列举了一些自己会的语言,比如 C++,PHP,JavaScript,HTML/CSS 等。然后又说自己最近在学 Python,做了个小程序从豆瓣抓取电影信息。
-
对于学习语言有什么看法?
我说首先要有兴趣,才会有动力去学。其次,在实践中学习是最快的,光看理论会很痛苦,也容易忘,如果结合一些小项目,在实践中去学会达到事半功倍的效果。
-
在以往的工作中遇到过什么技术难题,怎么解决的?
我说我现在从事的工作技术难度不是特别大,既没有高并发也没有大数据,在工作中没遇到过太难的技术问题。曾经遇到过的一个问题是在C#中调用非托管C++以及在非托管C++中调用C#。前者可以通过P/Invoke平台调用,只是对于一些复杂的数据类型封送起来比较麻烦,可以考虑用序列化的方法通过字节流来传递。后者实现起来就比较麻烦了,最终我是通过托管C++做中间层来实现调用的。然后他问我为什么不做成服务用远程调用呢?我说因为他们是进程内的调用,那样做反而复杂了。
-
怎么解决某个经典的 UI 线程问题,即在非创建线程里试图操作某个控件时引发线程间操作无效: 从不是创建控件的线程访问它异常?
这个问题在实际开发中经常遇到,我的回答是使用委托回到创建线程去操作。或者使用SynchronizationContext的Post/Send方法来解决。
-
知不知道C#中新增了某个异步操作的关键字?
这个我还是如实说了,我们现在工作中用的C#版本是 4.0,也就是 VS 2010,但这个关键字我在网上看到过,好像叫 async 什么的吧。
-
比较 Remoting、WCF、ICE?
这个问题是由于我说我在工作中使用了分布式 RPC 框架 ICE 引起的,然后他就让我比较一下这几个框架。我说前两个都是微软自家的,在跨语言跨平台上不行,WCF 是在 Remoting 的基础上发展而来的,我在工作中用的不多;ICE 支持跨语言跨平台,我们工作中最终选了它。
-
说说 .NET 这些年新增了哪些特性?
我说了泛型、LINQ、默认参数、可选参数,一下子还真想不起来太多。
-
让我选一个我擅长的技术,给他们做一个像演说一样的讲解。
本来这可能是最重要的一个问题,可是我却把它当成了最不重要的问题回答了。我的回答跟刚才某个问题很像:我现在的工作没用到什么高深的技术,没有什么好讲的。意思是这样,原话不是这样。
-
最后,他们问我有没有什么问题问他们?
我当时也没准备什么问题,临时随便问了一下他们现在成都这边 C# 开发人员多吗?又是刚才说话我听不清楚那位回答:我们这边现在只有一个 C# 的项目,其他的基本都是 Java 的。然后我又问,那如果没有 C# 的项目了怎么办呢?我问这个问题的初衷是因为在网上看到说 ThoughtWorks 有淘汰机制的,想问一下是不是这样就会被淘汰。没想到,面试官好像有点生气,回答我说:你怎么会问这样的问题呢?一个程序猿不应该仅仅局限于一门语言,项目需要什么语言我们就用什么语言,像我以前也是做 C# 的,现在也做 Java 了,他(指另一位面试官)是做 Python 的,也会其他语言。我不知道他为什么会有这么大的反应,但我却知道了尼玛原来他们两个都不是 C# 程序猿啊,至少已经很久不是了,而且 C# 在成都分公司也是朝不保夕的地位。
对于新语言的学习,我从来不排斥,大学选择软件工程就是因为热爱编程,前不久还通宵调试过程序,现在也在学习 Python 和 PHP,他们可能误解了我问题的意思了。
结局
几分钟后,HR 进来告诉我:对不起,经过我们的面试,我们觉得你现在与 ThoughtWorks 的文化还是不太契合。其实,之前的面试过程我的感觉都还不错的(盲目乐观),与两位面试官的相处也很融洽,满以为可以进入下一环节了,没想到说我没通过。当时可能自尊心作祟,一下就愤怒了,但我还是尽量克制,没表现出来,匆匆离开了公司。
回去的路上越想越不通,遂发邮件询问 HR 我被拒的原因,HR 到也很快就回复了我,建议我在技术的深度和广度上做一些提高。但我不相信这是真实原因,我在想是不是逻辑测试太差了,然后又发邮件询问逻辑测试成绩和其他原因,这一次就再也没有回复了。
总结
这是我从毕业到现在的第二次面试,第一次面试就是现在所在的单位。总结了一下面试失败的原因:
-
缺乏面试技巧
很多问题回答的太实在了,换一种说法可能结局就不一样了。
-
平时的积累总结不够
虽然说现在的工作没有太多的技术难题,但其实还是有很多可以总结的东西。平时遇到问题,想办法解决了就算完事了,也没怎么去总结,导致现在什么都说不出来。
-
不善言辞,不会表达
这个面试绝对不是我的真实水平,很多我会的东西都没表达出来,他们在我的脑海里横七竖八乱糟糟的放着,缺乏系统性、连贯性,导致让我讲的时候,千头万绪,不知从何说起,每一个小的知识点挑出来讲似乎分量都不够,但又串不起来。
-
技术有待提高
我现在的技术很多时候都浮于表面,缺乏深度,解决常规性问题没问题,一旦遇到真正的技术难题可能就解决不了。
对于他们给我的建议,我会认真执行的,也感谢 ThoughtWorks 给了我一次难忘的面试经历。
P.S 这个是我对这道题提交的代码:FizzBuzzWhizz