我也谈面试 附赠一份题目

老赵一出手,又引来无数跟帖。详见 我在面试.NET/C#程序员时会提出的问题

小弟不才,只被面试过,从未面试过别人。所以想从被面试方的角度来谈谈,在我心中理想的面试应该是咋个样的。

前阵子lzprgmr同学,站在面试官的立场上谈了谈他的感受,见 谈谈技术面试。里面写道:

首先,我觉得技术面试是需要讲究技巧的,不是随随便便拉一个技术不错的人就可以,因为面试的过程是双方相互交流的过程,你需要给对方营造一个轻松的气氛,并在不断的提问与回答的过程中,进行“合理的引导”,“适时的追问”与“正确的判断

我非常赞成他的观点,面试官跟被面试的人无论如何都很难做到绝对的平等, 面试官对题目准备充分,享有话语权,而且接受面试的人很容易也很普遍表现紧张,如果再遇到不太Nice的面试官,很容易搞坏心情,影响发挥。

面试的时候我比较乐意回答些开放式的问题,或者由浅入深的问题套问题的问题。有时候我们可能一上来没完全理解面试官的意图,缺失上下文,一时半会儿答不上来, 如果这样就被一票否决的话,我觉得是有失公允的。如果面试官能够稍加提示,“合理的引导”,说不定就能答上来,说不定还有自己独特的见解。

 

面试官应该更多地考察对方想法,思路,而不是简单的考察那些 知道/不知道 很容易只有正反答案的问题。

比如:写一个Swap函数,不借助第三方变量。 这个问题太考验技巧了,如果之前看过,自然不难,如果没有接触过想半天也很难答的上来。况且会跟不会都说明不了什么问题,我不清楚这样的问题意义何在。 再说这道题在实际项目中一点意义也没有,我写逻辑简单,性能还不错的代码,也不愿意写羞涩难懂,标榜性能最大化的代码。 有时候这么点性能的提升真的有必要吗?

以上我只是就事论事谈谈对这个问题的看法,如果作为面试题,我觉得无所谓,面试嘛什么都可以谈,不管是纯技术的,还是涉及到实际项目应用的,都可谈。但千万别一棒子打死人,答不上来就觉得对方能力不行。我到更喜欢,一开始答不上,适当给点提示后,对方很快就跟上节奏的人。

 

我享受如下的面试过程,LinkedList有用过吗?能简单说说跟List有什么区别吗?两者适用的场景是什么?他们各自的优势是什么,性能有什么不同,什么原因造成了性能的区别。。。

先抛出个简单的问题,然后”适时的追问”去挖掘更深层次的问题,最好能问及到对方恰巧未思考过,不熟悉的领域,加适当地提示。我觉得这个过程式相当考验人的,而且良莠应该很容易分辨。

 

我觉得:程序员的价值,不仅在于他懂得多少个知识点,更多的时候体现在于能不能融会贯通各个知识点,能不能做到举一反三。更重要的是在遇到困难,遇到新情况时所表现出来的特质,是如何思考问题的,能否从过去的经验中得到启发,并进行合理的变通,恰当地解决当下的问题。

最后引用我们CEO的一段话:

Innovation is rarely about the creation of something entirely new; in fact, it's about looking at things from a new perspective, and changing or combining them in ways that create new value.

老赵很大方,在博客上提前罗列了很多可能会考察的知识点,不怕应聘者做突击准备,“蒙混过关”:

我并不担心大家知道这些问题,而且我可以表示以后的面试估计也逃不开这些。如果您有某些意向,做些针对性的准备可能也是不错的。当然,既然是面试,就会有“随机应变”,你我都一样。我有自信可以在不断追问下发现到底是“真材实料”还是“临时抱佛脚”。

 我特相信,一个优秀合格的面试官确实能够大致分辨出对方的水准。反过来,合格的程序员也应该能通过一次愉快的面试,大致了解到面试官的水准,自己是不是合适加入他们的Team。

 

@DeepNight同学在下面评论到: 其实仔细看了CLR via C#大多数的问题还是能答上来的。

我想如果你带着问题去看的话,确实都能找到答案。那对于上面未罗列的问题呢?问题背后的问题呢?你在看CLR via C#能够对所有的知识点,展开一番思考吗,多问几个问题吗?

《幸福课》里提到:很多事情一直都在那里,只是你没有问为什么,所以忽视了他们的存在。Question create realistic。 这句话TTM令我震撼了!

 

小弟不才,简单罗列了下几个问题,希望能够引起一番思考如果你还不会的吧Smile 

.NET Quiz 

  • 下面两个函数签名有什么区别,能举例子详细说明下吗   private void Modify(string str){...}          private void Modify(ref string str){...}
  • ref 和out 参数有什么区别,为什么要这样设计
  • Int? 是什么, 什么是nullable类型, 值类型 or 引用类型? 怎么理解 int? I = null;为什么要引入Nullable类型
  • GetType() 方法有什么用, 哪里定义的, 子类可重写吗? Int? i = 2; i.GetType() 返回的是什么类型,为什么,意义在哪里,怎么做到的?  Int? i = null; i.GetType() 为什么会异常,真的是i没有分配空间,没有初始化引起的吗?
  • 泛型和delegate 有什么共通性, 共同的理念是什么
  • 什么是代码可读性, 怎么看待 可读性 VS 性能 问题
  • 怎么理解封装, 就是为了屏蔽数据? 能不能从更高的层面理解这个问题
  • Array 和 List 有什么区别; List 和 LinkedList 有什么区别; 性能,应用场合?什么是deque(double ended queue)? 不知道的话没关系,面试官给出定义,特性,要求被面试者用现有的集合类实现一个deque吧
  • try { } finally {} finally 里的代码一定能保证执行吗 ? 如果不能,什么情况下。 throw; throw ex; 有什么区别, 什么时候需要重新抛出自定义的异常
  • Assert 是什么,平时用的多吗,什么是防御式编程? 方法检测时,传入的参数为空情况下,是用Assert 呢还是直接抛异常? 
  • 什么是面向过程编程,什么是面向对象编程,面向对象编程一定比
    面向过程编程有意义吗? 什么是面向组件开发, 什么是AOP,什么是面向服务编程, 他们有共性吗,他们的引入是为了解决什么样的问题? 为什么历史是朝这个方向发展的, 可以倒着来吗? 
  • 在主线程中进行计算密集型操作,这个时候UI能响应用户反应吗,如果要更新UI 怎么办? 如果要用一个进度条实时反馈当前计算进度,应该怎么做? 可以在其他线程进行如下操作吗? textBox.Text = "Name"; 为什么? 为什么有这个限制?  textBox.BeginInvoke( action) 做了什么事.  
  • 有人说:软件开发中所有的问题,都可以引用中间层解决。 你怎么理解?举些例子吧。  
  • IL 是什么,引入的理念是什么? 什么时候IL才会被编译成native代码 。 下面两段代码有什么区别  
  •        //  代码 1:

    static void Main(string[] args)
    {
       Console.WriteLine(
    "Start In main");
       A a 
    = new A();
       Console.WriteLine(
    "End In main");
    }
     
    //  代码 2:
    static void Main(string[] args)
    {
        Console.WriteLine(
    "Start In main");
        SimpleWrap();
        Console.WriteLine(
    "End In main");
    }

    void SimpleWrap()
    {
       A a 
    = new A();
    }

          如果class A是定义在另一个工程里,运行的时候凑巧A所在的dll不在应用程序目录下,会发生什么,两者输出有不同吗?

  • ICloneable是什么,什么是浅克隆,什么深克隆,如何实现深克隆,原理是什么,你怎么理解。 如果下面函数是一事件响应函数链上一环,应该注意什么:  (提示: const  应该明白我想问什么了吧) 
    private void OnPreSelected(ObjectPath path)
    {
        
    // Setp 1: check valid path
        path.PopTo(...)
        
    if (path == ...)
        ...
    }

  • 附加题:一个计算密集型操作,我不想使用多线程,又希望同步进度条, 可以做到吗? 如何做到?(提示: 消息泵, .NET 3.5)(如果有人能顺畅答上这道题,我觉得可以加50分:))

    Sunday, June 26, 2011:

    下面2段代码有什么区别:

    public void FireMouseMove()
    {
       
    if (mMouseMove != null)
           mMouseMove(
    this10);
    }

    public void FireMouseMove()
    {
       var tempCopy 
    = mMouseMove;
       
    if (tempCopy != null)
           tempCopy (
    this10);
    }

     

    Level 2: 什么是线程栈? 

     

    posted @ 2011-03-04 17:25 Anders06 阅读(4112) 评论(42) 编辑 收藏

     回复 引用 查看   
    #1楼2011-03-04 17:36 | lzprgmr      
    写的很不错,看来最近挺有感悟的啊!

    >> 一个计算密集型操作,我不想使用多线程,又希望同步进度条, 可以做到吗? 如何做到?
    消息泵不懂~~~
    但可以事先在计算的代码中设计好某种回调机制吧

     回复 引用 查看   
    #2楼[楼主]2011-03-04 17:45 | Anders06      
    @lzprgmr
    >>可以事先在计算的代码中设计好某种回调机制吧
    CPU密集型会堵塞UI更新的, 所以一般常见做法就开个线程。 我的题目不让起线程:)


    上面的“.NET 3.5”提示不是很精准,先看看大家反映, 另一个关键词稍后再提

     回复 引用 查看   
    #3楼2011-03-04 17:49 | lzprgmr      
    @Anders06
    或许这样:
    callback()
    {
    PrgressBar.SetPercentage(x);
    SendMessage(WM_PAINT);
    }

     回复 引用 查看   
    #4楼2011-03-04 17:52 | 刀 刀      
    引用int? i = null; i.GetType() 返回的是什么类型
    这不坑爹么。明明是抛异常,还问返回什么类型。。。

     回复 引用 查看   
    #5楼[楼主]2011-03-04 17:52 | Anders06      
    @lzprgmr
    你开个工程试试吧:)

     回复 引用 查看   
    #6楼2011-03-04 18:01 | Kuke      
    一个计算密集型操作,我不想使用多线程,又希望同步进度条, 可以做到吗? 如何做到?

    Application.DoEvents(); MS可以,具体没测试。

     回复 引用 查看   
    #7楼2011-03-04 18:04 | Jeffrey Zhao      
    @刀 刀
    hoho,还有道没什么意思但比较有趣的问题:
    MyType o = null;
    Console.WriteLine(o.MyMethod());
    

    这代码什么时候不会抛出异常?

     回复 引用 查看   
    #8楼2011-03-04 18:10 | 013231      
    引用Anders06:
    @lzprgmr
    你开个工程试试吧:)

    确实是抛出异常啊,NullReferenceException.

     回复 引用 查看   
    #9楼2011-03-04 18:11 | DiggingDeeply      
    @Jeffrey Zhao
    嘻嘻,我知道了,这有点IQ急转弯啊。

     回复 引用 查看   
    #10楼2011-03-04 18:13 | DiggingDeeply      
    •Asset
    Assert

     回复 引用 查看   
    #11楼2011-03-04 18:14 |       
    写的很好,如果能把你提出的问题做个简单的回答就好了。不过没关系,我去google
     回复 引用 查看   
    #12楼2011-03-04 18:18 | 幸存者      
    @Jeffrey Zhao
    扩展方法,以前着过道。

     回复 引用 查看   
    #13楼2011-03-04 20:23 | 真名士      
    这份看着比老赵的实用。
     回复 引用 查看   
    #14楼2011-03-04 20:31 | 刀 刀      
    引用Jeffrey Zhao:
    @刀 刀
    hoho,还有道没什么意思但比较有趣的问题:
    MyType o = null;
    Console.WriteLine(o.MyMethod());
    

    这代码什么时候不会抛出异常?

    扩展方法呀,因为他本质是Ext.ExtMethod(null)。P.S.第一次老赵回复我,我很激动啊。

     回复 引用 查看   
    #15楼2011-03-04 21:00 | 天天      
    用.NET很久,但是对于一些较为代码还没真的仔细研究,感觉太累。因为我一直认为,在程序里最终的是SQL,不管你程序写的多好,如果SQL语句错,那系统就无法运行。
    我做的www.dotnetcms.org,说简单点,就是数据库增删读写,代码即使是初学者也很容易看懂,所以,如果真的是面试,我感觉应该更多关注数据库技术,不管是什么语言。

     回复 引用 查看   
    #16楼[楼主]2011-03-04 21:20 | Anders06      
    @刀 刀
    眼尖啊,没用编译器吧:), 我马上更正,顺便加道题,刚才哪个为什么会抛异常,为啥这样设计:)

     回复 引用 查看   
    #17楼2011-03-04 21:24 | 李传涛      
    这是初级?还是中级程序员
     回复 引用 查看   
    #18楼[楼主]2011-03-04 21:28 | Anders06      
    @DiggingDeeply
    又现丑了,已更正,谢谢

     回复 引用 查看   
    #19楼[楼主]2011-03-04 21:29 | Anders06      
    引用刀 刀:
    引用Jeffrey Zhao:
    @刀 刀
    hoho,还有道没什么意思但比较有趣的问题:
    MyType o = null;
    Console.WriteLine(o.MyMethod());
    

    这代码什么时候不会抛出异常?

    扩展方法呀,因为他本质是Ext.ExtMethod(null)。P.S.第一次老赵回复我,我很激动啊。


    我现在也知道了,O(∩_∩)O哈哈~

     回复 引用 查看   
    #20楼[楼主]2011-03-04 21:36 | Anders06      
    引用李传涛:这是初级?还是中级程序员

    不清楚,不过肯定考的不是初级程序员。 我感觉很多高级程序员都不一定“完整”答对一半。 再说这些题都能答对也不能代表那人就有多牛。 我感觉关键还是要看面试中与面试官的互动情况, Sense!

     回复 引用 查看   
    #21楼2011-03-04 21:42 | 李传涛      
    @Anders06
    呵呵 我这几天也是在面试,发现自己还停留在初级程序员阶段,杯具啊

     回复 引用 查看   
    #22楼[楼主]2011-03-04 21:51 | Anders06      
    @
    @李传涛
    我拟了这些题,不是为了考察谁谁谁基本功如何, 只是觉得很多时候,我们应该多问些为什么,发现不会的问题,不妨多想想,google下,找周围的人聊聊共同探讨下,学习是个过程,不是个结果。
    引用一个牛逼人说的话:
    思考这种事,是不好一蹴而就的


     回复 引用 查看   
    #23楼2011-03-04 22:02 | 横刀天笑      
    @天天
    不是所有的程序最终都是SQL,即使数据驱动型的应用,也不是光关注SQL就能解决的,比如:
    1、你的应用在使用人数稍微多一点的情况下CPU占用居高不下,你要调查原因,从哪里着手?
    2、随着使用人数的增多,数据库成为瓶颈如何解决?
    3、客户的增多,新的需求也不断地出现,如何做到易于扩展?并且对已有的代码尽量少进行修改。
    这些都不是编写SQL或增删改差能实现的。

     回复 引用 查看   
    #24楼2011-03-04 22:34 | guozili@163.com      
    这些题目比较细节哦,有些还真不知道,我做了很多年项目,觉得出这些题目让别人好发挥些,能考察出哪些人经验丰富:
    1. 一个算法题(递归,字符串处理或急转弯)
    2. 如果让你设计一个登陆系统(安全,验证,sso,用户表的设计)
    3. 你所熟悉的一个设计模式以及在.net源码里哪里用到了(foreach-iterator, DBFactory...., Provider-strategy)
    4. 列举下你熟悉的几种事务使用(DB,SqlTransaction,TransactionScope,DTC,事务提升,wcf分布式事务)
    5. 你熟悉的多线程的实现方式(异步委托,thread,threadpool,backgroundworker,4.0里的task,AsyncEnumerator)
    6. .net的编译过程(clr,pe,il,jit)
    7. 你熟悉的DB优化技巧(读写分离,负载均衡,横向竖向切分)
    8. 聊聊你最近使用的一个新技术,用的怎么个爽法
    9. 如果给你几个人带,你怎么管理他们的工作(document,coding rule,tfs, scrum,bug track,Daily Build...)
    10. 用英语随便写下来你对WebOS的看法.

     回复 引用 查看   
    #25楼2011-03-05 09:56 | 虚假真人      
    比较关心这些问题全答出来的话能开多少钱
     回复 引用 查看   
    #26楼2011-03-05 09:58 | 君之蘭      
    考题不够全面,太过于纠结语言了
     回复 引用 查看   
    #27楼2011-03-05 11:19 | 刀 刀      
    引用Anders06:
    @刀 刀
    眼尖啊,没用编译器吧:), 我马上更正,顺便加道题,刚才哪个为什么会抛异常,为啥这样设计:)

    呵呵,我自己写了一篇娱乐面试题,里面有一道类似的题目。欢迎来看。

     回复 引用 查看   
    #28楼[楼主]2011-03-05 11:45 | Anders06      
    加了道Clone的题。 我在想C#里函数参数为什么没有const修饰符呢, 有时候还是有用处的。 上面那道题平时开发中有同事就栽了,我虽然知道咋回事,但我不能担保自己以后都不会犯。
     回复 引用 查看   
    #29楼[楼主]2011-03-05 11:46 | Anders06      
    @刀 刀
    引用刀 刀:
    引用Anders06:
    @刀 刀
    眼尖啊,没用编译器吧:), 我马上更正,顺便加道题,刚才哪个为什么会抛异常,为啥这样设计:)

    呵呵,我自己写了一篇娱乐面试题,里面有一道类似的题目。欢迎来看。

    看了下,基本不会,泪流满面啊。幸运的是,又长见识了,以后就会了:)

     回复 引用 查看   
    #30楼2011-03-05 13:01 | Jeffrey Zhao      
    引用虚假真人:比较关心这些问题全答出来的话能开多少钱

    我的,一万起。

     回复 引用 查看   
    #31楼2011-03-05 13:18 | 大白      
    @Anders06
    这些问题,只能算是初级的.net程序员,必知的知识。算不上难度。有些人不会不熟悉,可能是因为没接触过那些,比如最后一个问题。通常情况下,另起一个thread是正常的想法。条条道路通罗马。不从事win form开发的,基本不会的。除了thread,我也想不出其他的法子,虽然我偶尔有玩玩win form。

     回复 引用 查看   
    #32楼[楼主]2011-03-05 16:36 | Anders06      
    @大白
    引用大白:
    @Anders06
    这些问题,只能算是初级的.net程序员,必知的知识。算不上难度。有些人不会不熟悉,可能是因为没接触过那些,比如最后一个问题。通常情况下,另起一个thread是正常的想法。条条道路通罗马。不从事win form开发的,基本不会的。除了thread,我也想不出其他的法子,虽然我偶尔有玩玩win form。

    神仙?这些题目如果是初级的.net程序员,必知的知识,那我6年算是彻底白混了。

     回复 引用 查看   
    #33楼[楼主]2011-03-06 13:02 | Anders06      
    感觉上面自己的评论有点不妥,容易引起歧义, 我在这解释下:
    我想表达的是,上面有些问题并非如看上去的那么简单,如果只是简单地看了第一层的问题,觉得自己掌握了话,没有去思考后续的问题,那就偏离了我拟这些题的初衷。
    个人觉得,上面的题并非毫无难度(除非你只看第一层问题),没有一定的实战经验,只是初级的.net程序员,很难都答对。 里面的题目大都不只是问你怎么用,而是想引发更深层次的思考,为什么这么设计,他们的依据是什么,他们解决了什么问题。
    里面有几个开放性的问题,我觉得我到现在都不一定理解的到位,你说是初级.net程序员必知的知识,让我情何以堪。
    我没说自己不是初级.net程序员哈:)

     回复 引用 查看   
    #34楼2011-03-07 09:09 | Leon916      
    很多都会打不上来啊。
     回复 引用 查看   
    #35楼[楼主]2011-03-07 11:15 | Anders06      
    @Leon916
    Google呗,这又不是当场面试:)

     回复 引用 查看   
    #36楼2011-03-07 13:46 | Beckson      
    bug错,bug错的题
     回复 引用 查看   
    #37楼2011-03-08 10:33 | AndyHai      
    @Jeffrey Zhao
    老赵啊,你要了我吧~~~~~我不要1W,因为有那么两题我也不是很明白

     回复 引用 查看   
    #38楼2011-03-08 15:58 | 钧梓昊逑      
    Int? i = null; i.GetType() 为什么会异常,真的是i没有分配空间,没有初始化引起的吗?

    这个问题以前有个博客上谈起,我回复过
    是因为Nullable<>重写了装箱过程,将HasValue为false的值装箱返回null。
    而ToString方法是重写了基类虚方法,返回String.Empty,我一直觉得这个设计不好。

     回复 引用 查看   
    #39楼2011-03-08 23:10 | Jeffrey Zhao      
    @AndyHai
    还要当场写程序的

     回复 引用 查看   
    #40楼[楼主]2011-03-09 16:35 | Anders06      
    引用钧梓昊逑:
    Int? i = null; i.GetType() 为什么会异常,真的是i没有分配空间,没有初始化引起的吗?

    这个问题以前有个博客上谈起,我回复过
    是因为Nullable<>重写了装箱过程,将HasValue为false的值装箱返回null。
    而ToString方法是重写了基类虚方法,返回String.Empty,我一直觉得这个设计不好。

    厉害!话说怎么可以确定是在装箱的时候做了手脚呢,我也只是看到MSDN上有这么一说

     回复 引用 查看   
    #41楼2011-03-10 13:12 | 钧梓昊逑      
    @Anders06
    我是看mono的实现的

     回复 引用 查看   
    #42楼[楼主]2011-03-10 21:01 | Anders06      
    @钧梓昊逑
    哦,看来研究这个好处还是很多啊,mono以前碰过但没有花时间好好学习过,以前就只知道看Reflector,好多底层的还是看不到。听老赵也经常提起熟悉mono好处多多,这次一定花力气好好接触下,要不然总是学艺不精,多不好意思啊