索引:

.NET框架基础知识[1] - http://www.cnblogs.com/haoyifei/p/5643689.html

.NET框架基础知识[2] - http://www.cnblogs.com/haoyifei/p/5646288.html

经过了四年的工作,我已经跳槽6次了。这四年我全部都使用C#进行开发,除了获得到的offer之外,还面试失败或拒掉了不少offer,加起来面试的次数至少有30次。这些面试有质量很高的,也有泛泛而谈的,不同面试有时候还会问到几乎相同的问题,通过对问题的深入程度,可以大致判断一家公司和面试官的水平。

跳槽就是为了更好的生活。而改善生活需要有强大的业务能力,说服面试官在众多候选人中选择你作为胜利者。在若干年的工作学习中,我的水平也慢慢上升,一开始是什么都不会,后来会一些东西,到现在也可以从面试官的问题中,大概了解到他/她的水平如何。

不同类型的公司的面试题目也略有不同,而这些题目要不代表着你面试通过之后可能在实际工作中遇到的问题,要么就是面试官希望通过题目了解你个人的水平如何。例如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,说出你自学某语言时看过的书籍,你最喜欢哪种数据结构等。这些问题没有标准答案,你需要结合事例解释你的答案。对付这种问题,死记硬背是没有什么用的,你需要理解或者在背书的基础上,形成你自己的观点。

在学习的过程中,我泛泛阅读了若干本经典书籍,当然还有很多本正放在书架上供着,我可能一辈子也不会去看或者理解的了(例如“编译原理”)。我也看了很多博客,其中有大量现成的代码可供直接使用。我认为,作为一个立志奋发图强的.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。

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代码,但把握住新技术的演进流程,也会对整个知识体系的融会贯通有重要的作用。

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

.NET面试题系列的更多相关文章

  1. .NET面试题系列[8] - 泛型

    “可变性是以一种类型安全的方式,将一个对象作为另一个对象来使用.“ - Jon Skeet .NET面试题系列目录 .NET面试题系列[1] - .NET框架基础知识(1) .NET面试题系列[2] ...

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

    .NET面试题系列目录 .NET面试题系列[1] - .NET框架基础知识(1) .NET面试题系列[2] - .NET框架基础知识(2) .NET面试题系列[3] - C# 基础知识(1) .NET ...

  3. .NET面试题系列[15] - LINQ:性能

    .NET面试题系列目录 当你使用LINQ to SQL时,请使用工具(比如LINQPad)查看系统生成的SQL语句,这会帮你发现问题可能发生在何处. 提升性能的小技巧 避免遍历整个序列 当我们仅需要一 ...

  4. .NET面试题系列[14] - LINQ to SQL与IQueryable

    .NET面试题系列目录 名言警句 "理解IQueryable的最简单方式就是,把它看作一个查询,在执行的时候,将会生成结果序列." - Jon Skeet LINQ to Obje ...

  5. .NET面试题系列[13] - LINQ to Object

    .NET面试题系列目录 名言警句 "C# 3.0所有特性的提出都是更好地为LINQ服务的" - Learning Hard LINQ是Language Integrated Que ...

  6. .NET面试题系列[12] - C# 3.0 LINQ的准备工作

    "为了使LINQ能够正常工作,代码必须简化到它要求的程度." - Jon Skeet 为了提高园子中诸位兄弟的英语水平,我将重要的术语后面配备了对应的英文. .NET面试题系列目录 ...

  7. .NET面试题系列[11] - IEnumerable<T>的派生类

    “你每次都选择合适的数据结构了吗?” - Jeffery Zhao .NET面试题系列目录 ICollection<T>继承IEnumerable<T>.在其基础上,增加了Ad ...

  8. .NET面试题系列[10] - IEnumerable的派生类

    .NET面试题系列目录 IEnumerable分为两个版本:泛型的和非泛型的.IEnumerable只有一个方法GetEnumerator.如果你只需要数据而不打算修改它,不打算为集合插入或删除任何成 ...

  9. .NET面试题系列[9] - IEnumerable

    .NET面试题系列目录 什么是IEnumerable? IEnumerable及IEnumerable的泛型版本IEnumerable<T>是一个接口,它只含有一个方法GetEnumera ...

  10. 【转载】.NET面试题系列[0] - 写在前面

    原文:.NET面试题系列[0] - 写在前面 索引: .NET框架基础知识[1] - .NET框架基础知识(1) http://www.cnblogs.com/haoyifei/p/5643689.h ...

随机推荐

  1. PHP 开发中的外围资源性能分析(二)

    暂且不讨论「PHP 是不是最好的编程语言」,本文我们将分别分析一下在 PHP 程序的后端外围资源和前端外围资源,它们对整个 PHP Web 应用体验的影响,这往往比语言本身大得多. 上一篇中我们分析了 ...

  2. Understanding and Using Servlet Filters

    Overview of How Filters Work This section provides an overview of the following topics: How the Serv ...

  3. iframe标签用法详解(属性、透明、自适应高度)(总结)

    <iframe src="http://www.jb51.net" width="200" height="500"> 脚本之家 ...

  4. hdu 4418 Time travel 概率DP

    高斯消元求期望!! 将n时间点构成2*(n-1)的环,每一点的期望值为dp[i]=dp[i+1]*p1+dp[i+2]*p2+……+dp[i+m]*pm+1. 这样就可以多个方程,利用高斯消元求解. ...

  5. Project Euler 77:Prime summations

    原题: Prime summations It is possible to write ten as the sum of primes in exactly five different ways ...

  6. [转]C++常见内存错误汇总

    在系统开发过程中出现的bug相对而言是比较好解决的,花费在这个上面的调试代价不是很大,但是在系统集成后的bug往往是难以定位的bug(最好方式是打桩,通过打桩可以初步锁定出错的位置,如:进入函数前打印 ...

  7. Servlet的response输出到页面时乱码的解决方法

    package com.mhb; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.Servle ...

  8. 机器学习 —— 概率图模型(学习:CRF与MRF)

    在概率图模型中,有一类很重要的模型称为条件随机场.这种模型广泛的应用于标签—样本(特征)对应问题.与MRF不同,CRF计算的是“条件概率”.故其表达式与MRF在分母上是不一样的. 如图所示,CRF只对 ...

  9. (step4.3.5)hdu 1501(Zipper——DFS)

    题目大意:个字符串.此题是个非常经典的dfs题. 解题思路:DFS 代码如下:有详细的注释 /* * 1501_2.cpp * * Created on: 2013年8月17日 * Author: A ...

  10. 【问底】徐汉彬:Web系统大规模并发——电商秒杀与抢购

    [导读]徐汉彬曾在阿里巴巴和腾讯从事4年多的技术研发工作,负责过日请求量过亿的Web系统升级与重构,目前在小满科技创业,从事SaaS服务技术建设. 电商的秒杀和抢购,对我们来说,都不是一个陌生的东西. ...