老赵一出手,又引来无数跟帖。详见 我在面试.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令我震撼了!
小弟不才,简单罗列了下几个问题,希望能够引起一番思考如果你还不会的吧
.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(this, 10);
}
public void FireMouseMove()
{
var tempCopy = mMouseMove;
if (tempCopy != null)
tempCopy (this, 10);
}
Level 2: 什么是线程栈?