.NET面试题系列[0] - 写在前面

.NET面试题系列目录

通过了四年的C#开发工做,我除了得到到的offer以外,还面试失败或拒掉了很多offer,加起来面试的次数至少有30次。这些面试有质量很高的,也有泛泛而谈的,不一样面试有时候还会问到几乎相同的问题,经过对问题的深刻程度,能够大体判断一家公司和面试官的水平。html

跳槽是为了更好的职业规划和发展。而这须要有强大的业务能力,说服面试官在众多候选人中选择你做为胜利者。在若干年的工做学习中,个人水平也慢慢上升,一开始是什么都不会,后来会一些东西,到如今也能够从面试官的问题中,大概了解到他/她的水平如何。前端

不一样类型的公司的面试题目也略有不一样,而这些题目要不表明着你面试经过以后可能在实际工做中遇到的问题,要么就是面试官但愿经过题目了解你我的的水平如何。例如Facebook,Google,BAT这种综合性公司在校招的时候,面对的都是应届大学生,他们没有什么可能会对搜索引擎十分专精,或者擅长天然语言语义分析。他们会的只是四年的大学计算机教育而已,面试完了以后,这些胜出者也不知道本身会去哪一个组作什么方向的工做。因此这时候,给他们出题也不能考搜索引擎,大数据,而只能考最general的内容,那无非就是计算机基础知识和算法了。程序员

而社招大部分状况下,面试官但愿你第一天面试经过,次日就能上班,而且来之能战。因此这时候问题基本都是你未来工做可能会遇到的问题。面试官但愿你研究过这些问题,而且证实本身能作的比别人更好。固然,面试官也但愿你的基础知识水平牢固,不会在开发,部署,测试等基本流程上一问三不知。例如,我曾经面试过三家公司,他们都但愿面试者熟悉WPF或者Winform。因此,其中的两家问到了工做线程如何修改UI线程控件的内容这个经典问题。对于这个经典的情境,你不只须要知道若是是按照常规的方法处理会发生什么(UI线程控件的内容只能被拥有控件的线程修改),还要知道怎么解决(Winform使用委托,WPF使用Dispatcher)。并且,你还能够提,若是你的应用是ASP.NET Web Application,则你须要反其道而行之,使用ConfigureAwait强制令系统不进行任何线程的切换。若是面试官知道你在说什么,他/她必定会很开心。若是面试官表现的一脸懵比,你能够在心中为这家公司下降一个档次。面试

当你回答问题时,若是你能够答的超乎面试官的意料,则他们给你开的工资可能也会出乎你的意料。例如,对于简单的问题“如何实现一个单例模式”,若是你只是给出了很简单的一个构造函数,则面试官可能会以为你对线程安全不够敏感 。若是你加了双重锁检查,面试官会问你第一个if是作什么的。若是你也知道,而且还能够解释清楚,为何须要双重锁检查,面试官会以为很满意。若是你甚至还能够提一句,在不少依赖注入工具中,只须要一个函数就能保证对象在全局都是单例的,例如autofac就有这个功能。面试官将会很是爽,而后话题可能会转到ioc,或者谈谈天气。算法

外国人问问题有时候不按常理出牌(或者你能够理解为,外国人的常理就是那样)。我遇到过的比较有趣的问题有:说出你以为c#好的任意一个理由(我给出的答案是它的语法天然易懂,且比较优雅,背后编译器做的大量工做你能够不用知道。例证如lambda表达式和async与await关键字),为何c语言被命名为c,说出你自学某语言时看过的书籍,你最喜欢哪一种数据结构等。这些问题没有标准答案,你须要结合事例解释你的答案。对付这种问题,死记硬背是没有什么用的,你须要理解或者在背书的基础上,造成你本身的观点。shell

在学习的过程当中,我泛泛阅读了若干本经典书籍,固然还有不少本正放在书架上供着,我可能一生也不会去看或者理解的了(例如“编译原理”)。我也看了不少博客,其中有大量现成的代码可供直接使用。我认为,做为一个立志奋发图强的.NET + C# 程序员,应该了解的知识包括:数据库

  1. .NET框架基础知识,如.NET框架的核心 – CLR作什么,.NET是如何将源语言编译成目标语言的,.NET中程序集的做用等等。这些都是背景知识,除了程序集以外基本没人问,但合格的. NET程序员必须知道。若是你愿意了解更多,能够去拜读“龙书”(即编译原理)。我反正在5年以内不打算读这本书。
  2. C#的基础知识,如类型安全,类和结构,垃圾回收,反射,面向对象基本知识等。这些问题比较基础,但若是深刻的问起来仍是能够难倒不少不少开发者的。通读一遍CLR via C#会有很大帮助。
  3. 委托与事件。虽然任何一本书上都有关于它们的章节,但仍然有不少人对委托的理解仅仅是函数指针这个层次。熟悉委托和事件的开发者,应当知道二者之间的关系,什么是委托链,以及委托是如何作到无处不在的(例如,linq里面就大量充斥着委托)。
  4. C#从2.0开始的新特性,这是一个极大的话题,主要包括2.0的泛型和可空类型,匿名方法,3.0的linq(以及相关的全部特性,包括闭包),4.0的dynamic,泛型的协变与逆变,4.5的async & await等等。熟悉它们会对代码有质的影响。任意一本好的介绍C#的书籍都会详细介绍它们,我我的则是看了Jon Skeet的深刻理解C#。这本书包含了不少技术细节,我有三分之一都看不懂。不过我的认为,是否理解那些细节并不会影响你的代码质量。一般来讲,敢在简历上写“熟悉C#”的人,至少应该了解三分之二的C#新特性。
  5. 数据结构。C#帮你实现了不少经常使用的数据结构,包括队列,栈,链表。对一些比较经常使用的数据结构要作到熟悉,并在特定情境时有所取舍。例如,对于常常在中间插入删除,但没有什么查找的情境时,选用链表而不是List<T>。C#全部的数据结构都基于IEnumerable,我曾经遇到一个面试官问我IEnumerable是作什么的,怎么实现一个IEnumerable。我的认为,后一个问题有点强人所难。不过,若是有人问我List<T>和IList<T>有什么区别,我不会以为很过度。清华大学出版的“数据结构”足以让你在这个话题所向披靡。
  6. 多线程的基本知识。进程和线程的区别,线程的优劣,以及线程的状态,如何管理线程。对这个问题的深刻能够去到计算机最基础的构造。在C#中,CLR提供了线程池管理线程,不过咱们不须要直接和它进行沟通,咱们能够经过任务间接的和它沟通。线程有几种状态:start,工做中,被阻塞和abort。它们之间的互相转化构成了同步的几种方式。你能够去搞一本“深刻理解计算机系统”,也许你会对这个问题豁然开朗,不过我才刚刚开始这本书的阅读。
  7. 多线程同步。同步方式有不少种,从最经典的lock到它的真身monitor,mutex,semaphore,Event构造,原子操做,死锁等。考这个的面试官基本都是高手,由于明白这一块内容很不容易。我面试了这么多家公司,也才就遇到三个问这块问题的,并且只有一个问的十分深刻,剩下的只是考考概念。不过,对于死锁,不少人喜欢问,他们一般问死锁产生的条件以及如何避免。加里.纳特的“操做系统”中对于死锁有着十分精彩的论述。一般能够结合哲学家就餐问题回答如何避免死锁。Windows核心编程这本书也很好,不过我也还没开始看。
  8. 异步编程的基本知识。首先,要清楚异步和多线程没什么关系,它并非多线程的子集。单线程也能够异步。而后,C#对异步操做提供了几种方式,例如基于委托,基于事件,以及基于任务。对于每种方式,要清楚它的优缺点(一般缺点都是难以取消或者得到结果,而基于任务的方式解决了全部问题)。
  9. 测试。如何编写单元测试和集成测试,测试的做用,如何隔离和模拟物件,测试驱动开发。不会测试或者不有意在工程中添加测试代码的工程是使人不安的。持续集成重要的一个缘由就是它能够帮你自动把测试都跑一遍。一个无懈可击的测试十分十分复杂。
  10. 软件工程方面的知识。包括版本控制,持续集成等。持续集成已经愈来愈多地被各个公司使用,以实现快速迭代和交付。若是你能够独立为公司实现持续集成的从无到有,你将会十分值钱。另外,你以前的公司是实行什么风格的软件开发流程的?是瀑布仍是敏捷?你更喜欢哪一种?你对结对编程有什么见解?你认为敏捷有什么很差的地方?
  11. 关于数据库的一些基本知识,包括几个范式,最基本的SQL,表上查询须要注意的事情(索引怎么放,放哪列等)。另外,你可能也须要知道ORM(Entity Framework)的好处有哪些。大数据,商业智能方向以及数据库管理员须要重点了解这块,而且还要加上大量内容,例如事务,数据库容灾,备份,数据仓库以及ETL。对于不是这些方向的开发者则不须要了解。梦里花落知多少的这篇http://www.cnblogs.com/anding/p/5281558.html其实已经有点多了,我的以为(固然,对于DBA来讲又太少了)。尤为是对于那些把数据都放在云上,平时拿数据都经过API的互联网金融公司来讲。对于那种公司,你不会SQL都不要紧,由于根本不须要,你也不用建表。
  12. 经常使用设计模式。虽然经典的设计模式有20多种,但没人会变态到让你把它们都背下来。最多见的无非是单例模式,迭代器模式,工厂,策略模式(ioc),观察者模式等等,清楚它们怎么实现,何时使用它们。另外,对于solid要大体了解,而且在本身设计时,尽可能作到。要了解ioc究竟有什么好处。
  13. 代码风格和简单算法。要说看一我的的编程水平如何,最准确的方法就是看代码了。好的代码让你赏心悦目,差的代码把你逼上梁山。代码必需要清晰易懂,配上精准的注释,以致于让别人基本不须要思考就能理解你要作什么。我很是痛恨的代码有:一个函数超过100行,命名混乱,瞎选数据结构,算法喜人等。对于算法,若是不是面算法工程师,会最基本的几个排序和递归问题就足够了,例如,若是你知道C#的Sort方法是如何实现的,而且理解为何会这么干,或者你知道数据库的索引用的是B+树而不是哈希,你的算法水平已经足够了。(对于谷歌第一题就是徒手翻转二叉树我表示不对胃口)不过若是有兴趣,能够读一读这本“算法”(不是算法导论)https://book.douban.com/subject/10432347/。若是你没有在大学看过算法导论的话,那么算法导论只有一个功能,那就是能够成功证实你彻底不会数学。若是你声称你能看懂TAOCP的第一本,请作一个for循环,给世界前10科技公司和投行各发一份简历,请相信我,若是你连TAOCP的第一本都看得懂,英语对你的大脑来讲简直就是没有难度,你甚至只须要写一句话:我能看懂TAOCP的第一本。
  14. 能用任意一款脚本语言写一个猜数字(就是文曲星上的那个游戏)。脚本语言是生活的小帮手,尤为是你须要批处理运行多个程序的时候。咱们不须要作到十分熟悉Linux的各个命令,但咱们能够在Python,Perl等脚本语言中任选一款,写一些你认为用C# + VS过于笨重的小程序。固然,若是你还擅长函数式编程语言,那简直太棒了。
  15. 你喜欢使用什么工具,让你的茫茫重构之路变得不那么崎岖?我我的则是一直在用Resharper。

上面这些若是你基本都会的八九不离十,你在任何一家公司均可以胜任一个后端程序员了。但若是你面试的职位还须要你写点API,以便让前端的哥们使用,那你还要粗浅的了解如下内容:编程

    1. Web基础,包括五层模型,get和post的区别,http协议的一些状态码以及IIS的基本设定。对这个话题的深刻了解,能够搞一本计算机网络方面的书籍,里面有详细的关于五层模型,TCP和IP协议的细节。若是你不是应聘网络方面的专家级别职位,我不认为它们是十分必要的。固然,若是你立志成为这方面的专家,请遵循http://coolshell.cn/articles/4990.html小程序

    2. Web服务。Web服务具备悠久的历史,最经典的两种方式SOAP和Restful的区别要知道。另外,微软对于这两种方式都给出了本身的实现,即WCF和WebAPI。c#

    3. 对MVC有必定的了解。了解如何利用工具,对你的API进行自动化或非自动化的集成测试。

    4. OWIN。微软的OWIN帮助咱们从ASP.NET又臭又长的生命周期解脱出来,今后咱们能够定义本身的生命周期。新的ASP.NET Core中也是这样,生命周期已经成为历史。咱们要了解OWIN基本的工做方式,以及它如何和ioc工具进行配合。另外,经过OWIN,咱们的工程能够和IIS解耦,能够用其余的工具代替笨重的IIS。

    5. 对于金融交易系统,须要特别关注一下SignalR。它集成了服务器和用户进行通信的几种方式,从常规的轮询,到服务器主动发送讯息,以及如今经常使用的WebSocket。它会根据状况自行选用它认为最合适的方式。

上面的内容并不包括前端,这是由于我以为全栈工程师十分不现实(由于前端的内容和后端几乎是同样多的,而光掌握后端的内容,也须要至少3-5年的时间),因此不打算朝这个方向努力,并且我对前端的了解也十分皮毛。固然,只会简单的HTML和jQuery,可不能称本身是一个合格的前端工程师。

在漫漫的学习过程当中,咱们不只要打牢基础,还要时刻关注新技术的动向。C# 6推出来一段时间了(虽然其中并无什么重大的改进),C# 7也立刻就要问世。ASP.NET Core的推出,把前端的打包和测试拉上了台面,同时令Angular JS 成为官方前端语言。对于后端来讲,也许你没有机会为公司贡献Angular JS代码,但把握住新技术的演进流程,也会对整个知识体系的融会贯通有重要的做用。

我已经写了很多笔记,虽然大部分都是抄别人的。我在这里也打算效仿博客园众位前辈,弄一个面试题系列,其中不彻底包含上述的全部内容,望各位大大不吝赐教。毕竟互相交流,人人都能受益。那么废话少说,咱们立刻开始。

相关文章
相关标签/搜索