说起来我也面试过相当数量的.NET(包括C#,后文不重复)程序员了,有的通过电话,有的面谈。后来发现,其实提的问题来来回回也就那么几个。这些问题有的已经有十年历史了,至少也有三年。我想对于一个“不错”的.NET程序员来说,在简单的提示下绝大部分问题应该可以“对答如流”。可能您也会觉得这些太细节,真要追究起来似乎也大都不是必须的,无视这些照样可以写程序,做网站,赚工资,但是我不会满足于成为(包括招聘)这样的程序员,暂时也懒得解释掌握这些东西的益处和重要性。 每个人都有自己的看法, 一切就看您自己的选择了。
那么现在就开始吧。
- 什么是.NET?什么是CLI?什么是CLR?IL是什么?JIT是什么,它是如何工作的?GC是什么,简述一下GC的工作方式?
- 类(class)和结构(struct)的区别是什么?它们对性能有影响吗?.NET BCL里有哪些是类(结构),为什么它们不是结构(类)?在自定义类型时,您如何选择是类还是结构?
- 在.NET程序运行过程中,什么是堆,什么是栈?什么情况下会在堆(栈)上分配数据?它们有性能上的区别吗?“结构”对象可能分配在堆上吗?什么情况下会发生,有什么需要注意的吗?
- 泛型的作用是什么?它有什么优势?它对性能有影响吗?它在执行时的行为是什么?.NET BCL中有哪些泛型类型?举例说明平时编程中您定义的泛型类型。
- 异常的作用是什么?.NET BCL中有哪些常见的异常?在代码中您是如何捕获/处理异常的?在“catch (ex)”中,“throw”和“throw ex”有什么区别?您会如何设计异常的结构,什么情况下您会抛出异常?
- List<T>和T[]的区别是什么,平时你如何进行选择?Dictionary<TKey, TValue>是做什么的?.NET BCL中还有哪些常用的容器?它们分别是如何实现的(哪种数据结构)?分别是适用于哪些场景?
- 抽象类和接口有什么区别?使用时有什么需要注意的吗?如何选择是定义一个“完全抽象”的抽象类,还是接口?什么是接口的“显式实现”?为什么说它很重要?
- 字符串是引用类型类型还是结构类型?它和普通的引用类型相比有什么特别的地方吗?使用字符串时有什么需要注意的地方?为什么说StringBuilder比较高效?在连接多个字符串时,它无论何时都比直接相加更高效吗?
- 如何高效地进行数组复制?“二维数组”和“数组的数组”有什么区别?在使用双重循环遍历一个二维数组时,如何选择内外层的遍历顺序?
- 什么是元编程,.NET有哪些元编程的手段和场景?什么是反射?能否举一些反射的常用场景?有人说反射性能较差,您怎么看待这个问题?有什么办法可以提高反射的性能吗?
- 委托是什么?匿名方法是什么?在C# 3.0中,Lambda表达式是什么?扩展方法是什么?LINQ是什么?您觉得C# 3.0中还有哪些重要的特性,它们带来了什么优势?BCL中哪些类库和这些特性有关?您平时最常用哪些?
- 工作之外您看哪些技术相关的书、网站、社区、项目等等?您还接触哪些.NET以外的技术,能和.NET或.NET中有针对性的部分做个对比吗?
以上便是暂时想到的问题,以后有需要再做补充──当然,不提供答案,一是写出来太累了,二是这些东西往往也没有完全标准的答案。您一定发现了,这些问题其实都是和.NET基础相关,与某个特定的框架或是类库并没有多大关系。在实际面试时,如果是Web开发人员,我一定还会考察对方对ASP.NET及Web基础(更主要是协议和理念相关,而不是HTML,JS,CSS编程)的了解,某些情况下还会有关于多线程、并发的知识点。其他可能还会有一些例如软件开发、设计、实现等实践方面的问题。更重要的是,我一定会需要您在白板上当场写代码来解决一个小问题。不难,也不会直接要求写某个经典算法,事实上甚至是“交换元素”这种简单到近乎毫无意义的问题,只可惜这类题目也能筛掉八成以上的人。
我并不担心大家知道这些问题,而且我可以表示以后的面试估计也逃不开这些。如果您有某些意向,做些针对性的准备可能也是不错的。当然,既然是面试,就会有“随机应变”,你我都一样。我有自信可以在不断追问下发现到底是“真材实料”还是“临时抱佛脚”。
您觉得还有哪些问题值得补充呢?
拟答一份
.net是微软推出的框架.CLI是公共语言接口?,CLR公共语言运行环境,IL运行在.net之上的类似汇编的语言,JIT即时编译用于首次加载时编译为可重复运行的模块,GC垃圾收集,主要是根据索引数判断是否收回,有定时机制.
类有类的生存周期而结构没有,需要更多维护.BCL里有Math?性能考虑,结构需要,struct足够.没有逻辑或者只是提供单纯结构的选择struct.
笼统答之需要new的都在堆上,其余在栈中.函数中声明的对象会在当前栈上分配.有区别,栈能够自动收回.结构对象可以分配在堆上,结构对象过大时就会发生.
泛型用于类型安全的操作.优势是类型安全.没有.不清楚.集合,事件,代理.数据库操作时一般使用泛型.
中断流程,冒泡传递.编译异常,运行时异常,IO异常等.TryCatch捕获.throw不处理,而throw则抛出指定异常.依据逻辑不同声明不同一样.在底层业务无关时抛出,交由上层处理.
一个是泛型列表对象,一个是T类型数组,一般选择泛型列表对象,自有灵活,安全.字典泛型,传入指定TKey类型作为key,TValue作为内容.很多容器.List是双链列表,Dict是Hash.列表是变长的固定类型的集合,Dict是有一个对应关系.
继承和组合的区别.抽象允许有实现,接口没有实现逻辑.....
字符串是引用.有个字符串缓存池.他是不可变对象.SB是可变对象.不是,在链接数量少于一定量级时,还不如他的构造所带来的消耗.
Array.copy.一个是存内容,一个是存引用.先遍历外层.
对程序本身的编程,反射,ASP.net MVC使用.程序解析程序自己.数据库链接获取,IoC.适当的缓存+灵巧的架构,不会产生谈反射变的样子.缓存解决反射性能的好办法.
委托是函数的指针.不给名称的方法就是匿名方法.在C#3.0中Lambda就是简化了的匿名方法.语言集成本地查询.var,拓展方法,他们带来了脚本化的灵活.表达式类.Linq最常用.
博客猿,stackflow,javaeye,EF,Asp.netMVC,Mono.除开.net之外常用python.有一个C#与Python语言本身涵盖的设计模式比较.
什么是.NET?什么是CLI?什么是CLR?IL是什么?JIT是什么,它是如何工作的?GC是什么,简述一下GC的工作方式?
.net是指微软推出的.net框架,它提供了基于.net平台的运行时环境和公共基础类库。 CLI是ECMA组织制定的公共语言基础设施标准,它是由微软公司建议和主要参与制定的。 CLR是公共语言运行时,是.net框架中对CLI的运行时标准实现。 IL是CLR的中间语言,任何运行于CLR平台的高级语言都可以编译成IL汇编语言,CLR二进制码也可以一一对应地逆向翻译成IL汇编语言。 JIT是指即时编译,即以CLR二进制码发行的应用程序,在代码第一次被执行时翻译成目标机器环境的指令。 GC是垃圾回收,垃圾回收算法关注已分配的内存块和和内存块之间的引用关系,最简单的回收策略是"引用计数",还有"标记和清除"等回收算法,现代回收算法基本都是分代回收。
小弟不才,只被面试过,从未面试过别人。所以想从被面试方的角度来谈谈,在我心中理想的面试应该是咋个样的。
前阵子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
// 代码 1:
{
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不在应用程序目录下,会发生什么,两者输出有不同吗?