• ThoughtWorks 面试备忘录


    ThoughtWorks 面试备忘录

    前言

    前段时间 ThoughtWorks 在网上和拉勾网合作搞了一次网络招聘,名为抛弃简历!让代码说话!,可谓赚足了眼球,很多程序猿纷纷摩拳擦掌、踊跃提交代码,在网上也是讨论的热火朝天。

    我恰巧也在微博上看到了这条招聘信息,按我以前的性格对这类信息是不会感兴趣的。一则自己自信向来不足,二则惯性思维大公司出题一般都很难,比如智力题之类的。只是自己最近恰巧想换工作,于是便点进去看了看。

    整个题目看下来觉得还好,不怎么难,主要考察基本功和编程习惯,比如面向对象编程思想、设计模式、单元测试之类的,并且语言不限。有人说他可以用 10 行代码就搞定,我丝毫不怀疑这个说法。但以我对 ThoughtWorks(WikiPedia) 的了解,他们出这道题的意图应该不是比谁用的代码行少或者谁的效率高,这毕竟不仅是 ACM。

    于是,自己便认认真真花了两个晚上的时间把这道题完成并且提交上去。在这道题中我用了简单工厂模式和策略模式,如果非要套还可以套一个状态模式。编码也基本反应了我在平时工作中的习惯,并且基本用了面向接口编程以最大可能的降低耦合。

    笔试题目

    详细信息请查阅拉勾网:【拉勾专场】抛弃简历!让代码说话!

    代码要求:

    1,语言不限,Java, C#, Ruby, C++, Js, Python, Scala, objective-C统统可以,小语种也没问题,只要你擅长;

    2,强烈建议写单元测试;

    3,请展示出你超赞的面向对象/函数式编程功底;

    4,建议尽量减少圈复杂度;

    5,请提交可运行的代码,及相关构建脚本/说明文档(代码运行平台和环境);

    FizzBuzzWhizz

    你是一名体育老师,在某次课距离下课还有五分钟时,你决定搞一个游戏。此时有
    100名学生在上课。游戏的规则是:

    1. 你首先说出三个不同的特殊数,要求必须是个位数,比如3、5、7。

    2. 让所有学生拍成一队,然后按顺序报数。

    3. 学生报数时,如果所报数字是第一个特殊数(3)的倍数,那么不能说该数字,> 而要说Fizz;如果所报数字是第二个特殊数(5)的倍数,那么要说Buzz;如果所 > 报数字是第三个特殊数(7)的倍数,那么要说Whizz。

    4. 学生报数时,如果所报数字同时是两个特殊数的倍数情况下,也要特殊处理,比> 如第一个特殊数和第二个特殊数的倍数,那么不能说该数字,而是要说FizzBuzz, > 以此类推。如果同时是三个特殊数的倍数,那么要说FizzBuzzWhizz。

    5. 学生报数时,如果所报数字包含了第一个特殊数,那么也不能说该数字,而是要> 说相应的单词,比如本例中第一个特殊数是3,那么要报13的同学应该说Fizz。如果> 数字中包含了第一个特殊数,那么忽略规则3和规则4,比如要报35的同学只报
      Fizz,不报BuzzWhizz。

    现在,我们需要你完成一个程序来模拟这个游戏,它首先接受3个特殊数,然后输出100名学生应该报数的数或单词。比如,

    输入

    3,5,7

    输出(片段)

    1
    2
    Fizz
    4
    Buzz
    Fizz
    Whizz
    8
    Fizz
    Buzz
    11
    Fizz

    Fizz
    Whizz
    FizzBuzz
    16
    17
    Fizz
    19
    Buzz

    一直到100

    电话面试

    ThoughtWorks 的工作效率还是挺高的,没过几天便接到他们 HR 的电话,说我代码通过了,他们想了解一些我的基本信息,并且邀请我在合适的时候去他们公司面试。其间,问了我几个印象比较深的问题:

    1. 期望的薪资?

      这个问题比较突然,说实话我还没准备好,近期都忙着看书准备面试了,还没来得及思考。于是便说了下自己现在所在公司的待遇,当然相比现在有所增加,这点我还是没那么傻的 _,HR 听了也没说什么。

    2. 出差较多,一年大概有 50% 以上的时间,国内国外都有,主要是国内,
      能否接受?

      我对于出短差是不抗拒的,但对于他们给出的这个出差节奏还是觉得难以接受,但为了得到面试机会还是说了不介意出差。

    3. 英语水平怎么样?

      这个我就如实回答了,CET-6,基本哑巴英语,读写没问题,听说不行。HR 听了也没说什么。

    4. 项目经历?

      由于我当前从事的工作具有一定的保密性质,不便透露具体项目信息,想给她讲一下我们系统的软件架构(当时也昏头了,给 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

  • 相关阅读:
    MFC Slider控件 去掉边上的虚线
    VC學習網址
    全局程序集缓存工具 (Gacutil.exe)
    滚动条集合
    调用 DialogBox 会失败解决方法
    全局程序集缓存GAC”是什么概念
    UltraVNC:超实用的远程控制工具(图)
    VC程序员之无法选择的命运
    C++类
    角色权限批量设置,随点!
  • 原文地址:https://www.cnblogs.com/platobeing/p/3735483.html
Copyright © 2020-2023  润新知