zoukankan      html  css  js  c++  java
  • (转)面试题

    > 什么是.NET?什么是CLI?什么是CLRIL是什么?JIT是什么,它是如何工作的?GC是什么,简述一下GC的工作方式?

    CLI是规范; CLR是对CLI的实现; .NET是基于CLR构建的一套框架;

    开发人员需要通过IL与CLR进行交流, 虽然IL本身支持一些面向对象的概念, 但是对于开发人员来讲还是过于复杂低效, 于是C#应运而生, 程序员只需编写C#代码, csc编译器会将其翻译成IL;

    虽然CLR理解IL, 但是CPU只认识二进制指令, 所以CLR需要JIT的帮助, 将IL翻译成CPU指令. JIT按需工作, 当一个.NET方法即将被执行时, JIT会介入, 把该方法(IL指令) 编译成CPU指令, 并保存以供重用.

    GC被用来回收当前进程中已无人使用的垃圾对象; GC会被某些事件触发(比如, 0代对象满, 内存压力大, appdomain被卸载), 随后遍历GC堆上的对象, 并通过”该对象是否被root直接/间接引用 (更进一步, “一个对象是否可以被回收”还会依赖于F-Reachable Queue 和GC Handle Table”)来判断一个对象是否需要被回收.

    > 类(class)和结构(struct)的区别是什么?它们对性能有影响吗?.NET BCL里有哪些是类(结构),为什么它们不是结构(类)?在自定义类型时,您如何选择是类还是结构?

    简单说来, 类是引用类型, 结构是值类型;

    值类型对象直接分配在当前线程的栈上, 引用类型对象位于GC堆上, 所以值类型对象无法在多个方法中传递, 而引用类型会承担更多的任务, 比如, 用于线程同步 (Monitor.Enter(…))当一个引用类型的对象被创建时, 会需要4+4=8个byte的额外空间开销(32bit OS), 同时过度的使用引用类型对象会增加GC堆的压力, 频繁的GC对程序的性能还是有一些影响的.

    BCL中的Byte类型是一个结构体, 至于为什么它不是一个类, 我觉得可能是设计者认为Byte不应该被继承, 或者8个byte的额外开销无法承受吧.

    什么时候使用值类型/引用类型还是应当具体情况具体分析, 对于引用类型, 能用sealed就sealed, 在方法调用时开销会小一些.

    > .NET程序运行过程中,什么是堆,什么是栈?什么情况下会在堆(栈)上分配数据?它们有性能上的区别吗?结构对象可能分配在堆上吗?什么情况下会发生,有什么需要注意的?

    .NET进程被创建时就会有一个堆随之被创建, 用来保存该进程在运行中需要使用的对象/数据; 当一个线程被创建时, 会有一个栈被创建,用来保存方法调用参数, 局部变量等轻量型数据.

    当一个类里面包含一个结构体类型的变量时, 该结构体类型会被分配在堆上. (不知道有什么需要注意的…)

    > 泛型的作用是什么?它有什么优势?它对性能有影响吗?它在执行时的行为是什么?.NET BCL中有哪些泛型类型?举例说明平时编程中您定义的泛型类型

    泛型有利于算法重用.

    .NET进程地址空间中, 对象和类型是分开存放的, 当我们实例化一个泛型的时候 (比如List<int> list = new List<int>();), 会有一个新的类型对象被创建(该对象并不位于GC堆上), 当我们在使用这个实例化泛型去创建新的对象时, 才会有一个对象(GC堆上)被创建. 所以性能上会有些许的损失. 当我们使用一个值类型作为参数,去调用一个接收引用类型参数的方法是, 会有装箱发生, 这时我们可以考虑实现一个泛型, 并在运行时确定方法的参数类型.

    > 异常的作用是什么?.NET BCL中有哪些常见的异常?在代码中您是如何捕获/处理异常的?在“catch (ex)”中,“throw”和“throw ex”有什么区别?您会如何设计异常的结构,什么情况下您会抛出异常?

    呃, 异常可以通知我们程序出错, 比如ArgumentException, NullReferenceException…

    异常的发生会导致一次stack walk, 去寻找对应的exception handler, 在这个过程中, stack trace的信息会被一层层的收集, throw ex会清空之前收集的stack trace的信息, 相当于抛出了一个新的异常, 而throw不会, 所以throw ex不利于找出问题所在.

    不同的layer应该catch不同exception, 最上层处理最general的exception, 底层去处理一些detail的exception.

    > List<T>T[]的区别是什么,平时你如何进行选择?Dictionary<TKey, TValue>是做什么的?.NET BCL中还有哪些常用的容器?它们分别是如何实现的(哪种数据结构)?分别是适用于哪些场景?

    T[] 继承自Array, 而List<T>仅仅是对T[]的封装; 相比于T[], List<T>的size是动态变化的.

    Dictionary<TKey, TValue>可以用来存储键/值对.其他的比如HashTable, SortedList等.

    > 抽象类和接口有什么区别?使用时有什么需要注意的吗?如何选择是定义一个完全抽象的抽象类,还是接口?什么是接口的显式实现?为什么说它很重要?

    抽象类定义了一个类及其子类是什么, 而接口更多的表现出一个类可以做什么.

    当一个类实现连个不同的接口, 而这两个接口中包含一些相同签名的方法时需要用到显示实现.

    > 字符串是引用类型类型还是结构类型?它和普通的引用类型相比有什么特别的地方吗?使用字符串时有什么需要注意的地方?为什么说StringBuilder比较高效?在连接多个字符串时,它无论何时都比直接相加更高效吗?

    String是引用类型, 其特殊之处在于一个string是不可变的, 当我们对两个string使用连接操作时, 会生成一个新的string 对象, 而原来的两个string保持不变.

    在和native代码做interop时, 对于传出参数 (char* outStr), 应当选择使用stringbuilder而非string.

    StringBuilder内部维护着一个char[] 数组, 在做连接字符的操作时会动态增加其大小, 但是, 当原有的数组不够用时, StringBuilder会重新创建一个新的char[]数组, 值得注意的是原来的数组不会被抛弃, 新创建的数组只会用作存储新添加的字符.

    如果说StringBuilder有”不高效”的话,应该就是在原有数组空间用尽的情况下吧.

    > 如何高效地进行数组复制?二维数组数组的数组有什么区别?在使用双重循环遍历一个二维数组时,如何选择内外层的遍历顺序?

    不清楚, 因为数组的元素在内存中的分布是连续的, 我能想到的方法是直接使用内存拷贝API.

    二维数组是二维的, 数组的数组是一维的.

    根据内存局部性原理, CPU在读取二维数组的第一个元素是, 第一行的数据也会被一起读入cache, 所以应当先遍历行,随后遍历列.

    > 什么是.NET?什么是CLI?什么是CLRIL是什么?JIT是什么,它是如何工作的?GC是什么,简述一下GC的工作方式?

    CLI是规范; CLR是对CLI的实现; .NET是基于CLR构建的一套框架;

    开发人员需要通过IL与CLR进行交流, 虽然IL本身支持一些面向对象的概念, 但是对于开发人员来讲还是过于复杂低效, 于是C#应运而生, 程序员只需编写C#代码, csc编译器会将其翻译成IL;

    虽然CLR理解IL, 但是CPU只认识二进制指令, 所以CLR需要JIT的帮助, 将IL翻译成CPU指令. JIT按需工作, 当一个.NET方法即将被执行时, JIT会介入, 把该方法(IL指令) 编译成CPU指令, 并保存以供重用.

    GC被用来回收当前进程中已无人使用的垃圾对象; GC会被某些事件触发(比如, 0代对象满, 内存压力大, appdomain被卸载), 随后遍历GC堆上的对象, 并通过”该对象是否被root直接/间接引用 (更进一步, “一个对象是否可以被回收”还会依赖于F-Reachable Queue 和GC Handle Table”)来判断一个对象是否需要被回收. 具体细节还这真不是半个小时能讲完的J

    > 类(class)和结构(struct)的区别是什么?它们对性能有影响吗?.NET BCL里有哪些是类(结构),为什么它们不是结构(类)?在自定义类型时,您如何选择是类还是结构?

    简单说来, 类是引用类型, 结构是值类型;

    值类型对象直接分配在当前线程的栈上, 引用类型对象位于GC堆上, 所以值类型对象无法在多个方法中传递, 而引用类型会承担更多的任务, 比如, 用于线程同步 (Monitor.Enter(…))当一个引用类型的对象被创建时, 会需要4+4=8个byte的额外空间开销(32bit OS), 同时过度的使用引用类型对象会增加GC堆的压力, 频繁的GC对程序的性能还是有一些影响的.

    BCL中的Byte类型是一个结构体, 至于为什么它不是一个类, 我觉得可能是设计者认为Byte不应该被继承, 或者8个byte的额外开销无法承受吧.

    什么时候使用值类型/引用类型还是应当具体情况具体分析, 个人倾向引用类型, 因为这样在设计的时候会少费些脑子, 不过能用sealed就sealed, 在方法调用时开销会小一些.

    > .NET程序运行过程中,什么是堆,什么是栈?什么情况下会在堆(栈)上分配数据?它们有性能上的区别吗?“结构”对象可能分配在堆上吗?什么情况下会发生,有什么需要注意的吗?

    .NET进程被创建时就会有一个堆随之被创建, 用来保存该进程在运行中需要使用的对象/数据; 当一个线程被创建时, 会有一个栈被创建,用来保存方法调用参数, 局部变量等轻量型数据.

    当一个类里面包含一个结构体类型的变量时, 该结构体类型会被分配在堆上. (不知道有什么需要注意的…)

    > 泛型的作用是什么?它有什么优势?它对性能有影响吗?它在执行时的行为是什么?.NET BCL中有哪些泛型类型?举例说明平时编程中您定义的泛型类型.

    泛型有利于算法重用.

    .NET进程地址空间中, 对象和类型是分开存放的, 当我们实例化一个泛型的时候 (比如List<int> list = new List<int>();), 会有一个新的类型对象被创建(该对象并不位于GC堆上), 当我们在使用这个实例化泛型去创建新的对象时, 才会有一个对象(GC堆上)被创建. 所以性能上会有些许的损失. 当我们使用一个值类型作为参数,去调用一个接收引用类型参数的方法是, 会有装箱发生, 这时我们可以考虑实现一个泛型, 并在运行时确定方法的参数类型.

    > 异常的作用是什么?.NET BCL中有哪些常见的异常?在代码中您是如何捕获/处理异常的?在“catch (ex)”中,“throw”“throw ex”有什么区别?您会如何设计异常的结构,什么情况下您会抛出异常?

    呃, 异常可以通知我们程序出错, 比如ArgumentException, NullReferenceException…

    异常的发生会导致一次stack walk, 去寻找对应的exception handler, 在这个过程中, stack trace的信息会被一层层的收集, throw ex会清空之前收集的stack trace的信息, 相当于抛出了一个新的异常, 而throw不会, 所以throw ex不利于找出问题所在.

    不同的layer应该catch不同exception, 最上层处理最general的exception, 底层去处理一些detail的exception.

    > List<T>T[]的区别是什么,平时你如何进行选择?Dictionary<TKey, TValue>是做什么的?.NET BCL中还有哪些常用的容器?它们分别是如何实现的(哪种数据结构)?分别是适用于哪些场景?

    T[] 继承自Array, 而List<T>仅仅是对T[]的封装; 相比于T[], List<T>的size是动态变化的.

    Dictionary<TKey, TValue>可以用来存储键/值对.其他的比如HashTable, SortedList等.

    > 抽象类和接口有什么区别?使用时有什么需要注意的吗?如何选择是定义一个完全抽象的抽象类,还是接口?什么是接口的显式实现?为什么说它很重要?

    抽象类定义了一个类及其子类是什么, 而接口更多的表现出一个类可以做什么.

    当一个类实现连个不同的接口, 而这两个接口中包含一些相同签名的方法时需要用到显示实现.

    > 字符串是引用类型类型还是结构类型?它和普通的引用类型相比有什么特别的地方吗?使用字符串时有什么需要注意的地方?为什么说StringBuilder比较高效?在连接多个字符串时,它无论何时都比直接相加更高效吗?

    String是引用类型, 其特殊之处在于一个string是不可变的, 当我们对两个string使用连接操作时, 会生成一个新的string 对象, 而原来的两个string保持不变.

    在和native代码做interop时, 对于传出参数 (char* outStr), 应当选择使用stringbuilder而非string.

    StringBuilder内部维护着一个char[] 数组, 在做连接字符的操作时会动态增加其大小, 但是, 当原有的数组不够用时, StringBuilder会重新创建一个新的char[]数组, 值得注意的是原来的数组不会被抛弃, 新创建的数组只会用作存储新添加的字符.

    如果说StringBuilder有”不高效”的话,应该就是在原有数组空间用尽的情况下吧.

    > 如何高效地进行数组复制?二维数组数组的数组有什么区别?在使用双重循环遍历一个二维数组时,如何选择内外层的遍历顺序?

    不清楚, 因为数组的元素在内存中的分布是连续的, 我能想到的方法是直接使用内存拷贝API.

    二维数组是二维的, 数组的数组是一维的.

    根据内存局部性原理, CPU在读取二维数组的第一个元素是, 第一行的数据也会被一起读入cache, 所以应当先遍历行,随后遍历列.

    > 什么是元编程,.NET有哪些元编程的手段和场景?什么是反射?能否举一些反射的常用场景?有人说反射性能较差,您怎么看待这个问题?有什么办法可以提高反射的性能吗

    对元编程了解十分有限, .NET的CodeDom(或者使用reflection emit动态创建类型)应当是其中的一个场景.

    基于元数据, 反射帮助我们在运行时动态获取程序集/类型/方法/属性等等的信息, 可以用于加载Addin.

    有得必有失, 反射功能强大, 只要不是滥用, 其带来的益处远大于性能上的损失.

    > 委托是什么?匿名方法是什么?在C# 3.0中,Lambda表达式是什么?扩展方法是什么?LINQ是什么?您觉得C# 3.0中还有哪些重要的特性,它们带来了什么优势?BCL中哪些类库和这些特性有关?您平时最常用哪些

    委托可以认为是类型安全的函数指针, 此处省略741个字…

    > 工作之外您看哪些技术相关的书、网站、社区、项目等等?您还接触哪些.NET以外的技术,能和.NET.NET中有针对性的部分做个对比吗

    OneCode是个不错的项目 <http://1code.codeplex.com/>

    http://blog.csdn.net/Sento/archive/2011/03/06/6226381.aspx

    题目来源:http://blog.zhaojie.me/2011/03/my-interview-questions-for-dotnet-programmers.html

  • 相关阅读:
    Azure PowerShell (7) 使用CSV文件批量设置Virtual Machine Endpoint
    Windows Azure Cloud Service (39) 如何将现有Web应用迁移到Azure PaaS平台
    Azure China (7) 使用WebMetrix将Web Site发布至Azure China
    Microsoft Azure News(4) Azure新D系列虚拟机上线
    Windows Azure Cloud Service (38) 微软IaaS与PaaS比较
    Windows Azure Cloud Service (37) 浅谈Cloud Service
    Azure PowerShell (6) 设置单个Virtual Machine Endpoint
    Azure PowerShell (5) 使用Azure PowerShell创建简单的Azure虚拟机和Linux虚拟机
    功能代码(1)---通过Jquery来处理复选框
    案例1.用Ajax实现用户名的校验
  • 原文地址:https://www.cnblogs.com/blsong/p/1979344.html
Copyright © 2011-2022 走看看