1,wpf特点:
1:MVVM模式。
2:数据和视图分离
3:高级的数据模板功能
4:高级数据绑定功能
5:高级动画支持
6:高级图形和3D支持
7:灵活的控件组合
2,依赖属性的原理:
DependencyObject中拥有一个字典保存绑定信息,字典的key是依赖属性,value为绑定的值。对于绑定SetBinding方法是关键,他处理保存bingding对象的键值对,如果bingding对象中保存的TargetObject(被绑定对象)实现INotifyPropertyChanged接口,那么监听TargetObject的PropertyChanged事件,TargetObject一旦改变就修改依赖属性的值,这就可以实现了通知。而对于双向绑定,奥秘就在给依赖属性赋值的SetValue(xx,xx)方法中,这个方法中会查找管理绑定的那个字典,当前依赖属性是否绑定了值,如果绑定了并且是双向绑定,就给TargetObject设置新值,实现双向绑定。
3,数据模板和控件模板的区别:
控件模板主要是用来改变控件的外观,数据模板则定义控件中数据的表现方式。
ControlTemplate之子ContentControl和ContentPresenter,ContentPresenter性能更好,ContentControl比ContentPresenter大多了。其实ControlPresenter是一个原始的构建块,而ContentControl是一个带控件模板的成熟控件(里面包含ControlPresenter)
4,mvvm模式和三层架构:
使用MVVM架构最大的好处是:开发人员在写程序的时候不需要做UI,而设计人员可以使用Microsoft Expression Blend 4+设计全部的UI并且不需要写任何代码。
主要的好处如下:
1、设计人员可以用设计工具很容易的设计UI,而且不需要写任何代码
2、你可以更好的设计UI,而且可以让即使不是开发人员使用。
3、可以先设计UI或者与开发同时设计。
4、当UI全部改变时,代码可以不改变。
1. 低耦合。View可以独立于Model变化和修改,一个ViewModel可以绑定到不同的View上,当View变化的时候Model可以不变,当Model变化的时候View也可以不变。
2. 可重用性。可以把一些视图的逻辑放在ViewModel里面,让很多View重用这段视图逻辑。
3. 独立开发。开发人员可以专注与业务逻辑和数据的开发(ViewModel)。设计人员可以专注于界面(View)的设计。
4. 可测试性。可以针对ViewModel来对界面(View)进行测试
5,路由事件和路由命令:
路由事件主要是根据可视树进行路由。路由事件支持三种路由策略:气泡、隧道和直接。
气泡事件最为常见,它表示事件从源元素扩散(传播)到可视树,直到它被处理或到达根元素。这样您就可以针对源元素的上方层级对象处理事件。
隧道事件采用另一种方式,从根元素开始,向下遍历元素树,直到被处理或到达事件的源元素。这样上游元素就可以在事件到达源元素之前先行截取并进行处理。根据命名惯例,隧道事件带有前缀 Preview
直接事件类似 .NET Framework 中的正常事件。该事件唯一可能的处理程序是与其挂接的委托。
WPF 的路由命令为您提供了一种特定的机制,用于将工具栏按钮和菜单项这类 UI 控件挂接到处理程序,并且无需在应用程序中加入许多关联性很强的重复代码。与正常事件处理相比,路由命令有三大优点:
路由命令源元素(调用程序)能够与命令目标(处理程序)分离——它们不需要彼此引用,如果是通过事件处理程序链接,就需要相互引用。
处理程序指出命令被禁用时,路由命令将自动启用或禁用所有相关的 UI 控件。
您可以使用路由命令将键盘快捷方式与其他形式的输入手势(例如,手写)相关联,作为调用命令的另一种方式。
6,.net主流框架:
MVC,MVVM,MVP.
MVVMLight,Prism.
MEF,Unity,Spring.NET,Ninject.
7,Hashtable和HashMap的区别:
1.Hashtable是Dictionary的子类,HashMap是Map接口的一个实现类;
2.Hashtable中的方法是同步的,而HashMap中的方法在缺省情况下是非同步的。即是说,在多线程应用程序中,不用专门的操作就安全地可以使用Hashtable了;而对于HashMap,则需要额外的同步机制。但HashMap的同步问题可通过Collections的一个静态方法得到解决:
Map Collections.synchronizedMap(Map m)
这个方法返回一个同步的Map,这个Map封装了底层的HashMap的所有方法,使得底层的HashMap即使是在多线程的环境中也是安全的。
3.在HashMap中,null可以作为键,这样的键只有一个;可以有一个或多个键所对应的值为null。当get()方法返回null值时,即可以表示HashMap中没有该键,也可以表示该键所对应的值为null。因此,在HashMap中不能由get()方法来判断HashMap中是否存在某个键,而应该用containsKey()方法来判断。
Hashtable继承自Dictionary类,而HashMap是Java的
8, 什么是圈复杂度(Cyclomatic Complexity)?为什么它很重要?
A:圈复杂度一种代码复杂度的衡量标准,中文名称叫做圈复杂度。在软件测试的概念里,圈复杂度“用来衡量一个模块判定结构的复杂程度,数量上表现为独立现行路径条数,即合理的预防错误所需测试的最少路径条数,圈复杂度大说明程序代码可能质量低且难于测试和维护,根据经验,程序的可能错误和高的圈复杂度有着很大关系”。
9,写一个标准的lock(),在访问变量的前后创建临界区,要有“双重检查”。
A: 这即是Jeffrey Richter在其经典著作CLR Via C#中提到的双检锁(double-check locking)技巧。如下是原书代码:
1 public sealed class Singleton 2 { 3 private static Object s_lock = new Object(); 4 private static Singleton s_value; 5 6 //私有构造器组织这个类之外的任何代码创建实例 7 private Singleton() { } 8 9 // 下述共有,静态属性返回单实例对象 10 public static Singleton Value 11 { 12 get 13 { 14 // 检查是否已被创建 15 if (s_value == null) 16 { 17 // 如果没有,则创建 18 lock (s_lock) 19 { 20 // 检查有没有另一个进程创建了它 21 if (s_value == null) 22 { 23 // 现在可以创建对象了 24 s_value = new Singleton(); 25 } 26 } 27 } 28 29 return s_value; 30 } 31 } 32 }
10, 什么叫FullTrust?放入CAC的assembly是否是FullTrust的?
FullTrust权限基本上允许跳过所有的CAS验证,持有该权限的程序集能够访问所有的标准权限。GAC中的程序集是具有FullTrust权限的。详细信息参见此文章。
11, 代码加上需要安全权限的特性有什么好处?
A: 有可能会通过具有元权限程序集或permview.exe工具访问这些attribute及其参数。有可能在程序集级别使用其中的一些attribute。可以通过反射访问设置信息。最关键一点使程序集开始执行时而不是在执行期间声明需要权限,这样可以确保用户不会在程序开始工作后遇到障碍。
12, gacutil /l | find /i “Corillian”这句命令的作用是什么?
A: gacutil全称.NET Global Assembly Cache Utility。参数/l [ <assembly_name> ]的作用:列出通过 <assembly_name> 筛选出的全局程序集缓存。find命令作用:在文件中搜索字符串,其参数/i作用是搜索字符串时忽略大小写。所以这条命令的意思就是在所有的全局程序缓存中搜索名称包含字符串”Corillian”的程序集。
13, sn -t foo.dll这句命令的作用?
A: sn是.NET Framework 强名称实用工具,其中参数-T[p] <assembly>作用是显示 <assembly> 的公钥的标记(如果使用了-Tp,则还同时显示公钥本身)。此命令显示了foo.dll的公钥。如果foo.dll非强名程序集产生如下提示:未能将密钥转换为标记 -- 程序集“(null)”的公钥无效。
14,DCOM需要防火墙打开哪些端口?端口135是干嘛用的?
A: DCOM动态的选择1024~65535之间的网络端口。此外,DCOM要用135端口实现一些重要的功能。DCOM是使用RPC进行通讯的。利用RPC功能进行通信时,就会向对方电脑的135端口询问可以使用那个端口进行通讯。这样,对方的电脑就会告知可以使用的端口号,实际的通讯将使用这个端口来进行。
135端口起的是动态的决定实际的RPC通讯使用的端口映射功能,主要用于使用RPC(Remote Procedure Call,远程过程调用)协议并提供DCOM(分布式组件对象模型)服务。
15,对比OOP和SOA,它们的目的分别是什么?
面向对象主要用于对具体的事物进行抽象建模,而SOA的主要目的是定义部署和管理服务的方式,采用SOA的架构可以提高可重用性,降低总成本,提高快速修改与演化IT系统的能力。
16,XmlSerializer是如何工作的?使用这个类的进程需要什么ACL权限?
XmlSerializer提供了方法,使你能够将自己的对象序列化和反序列化为XML,同时在这个过程中提供一定的控制。这个过程由一些attribute来控制。以下是代码示例:
序列化:
1 Theater theater = … ; 2 XmlSerializer xs = new XmlSerializer( typeof ( Theater ) ); 3 FileStream fs = new FileStream( args[0], FileMode.Create ); 4 xs.Serialize( fs, theater );
反序列化:
1 XmlSerializer xs = new XmlSerializer( typeof ( Theater ) ); 2 FileStream fs = new FileStream( args[0], FileMode.Open ); 3 Theater theater = (Theater)xs.Deserialize( fs );
控制这个过程:
[XmlRoot( "theater" )] -- 序列化xml的根节点
[XmlElement( "name" )] -- 序列化为xml的元素及元素名称
[XmlAttribute( "minutes" )] -- 序列化为xml中的特性及其名称
[XmlElement( "showing", DataType="time" )] -- 序列化为xml的元素及其类型
ACL权限上需要执行程序集的用户拥有对C:WINDOWSTemp的访问权限
17, 为什么不提倡catch(Exception)?
Exception类包含许多子类,程序执行的时候要将每一个类都搜索一遍以找到符合的异常类,这样是蛮消耗资源的,影响程序运行效率。另外,只捕捉特定环境,特定条件下的异常,并进行处理。不应该捕捉所有异常,因为有些异常是我们所无法预料到的,比如,内存溢出或其他错误,这种情况下,不应该让系统以一种未知状态继续运行。
18,Debug.Write和Trace.Write有什么不同?何时应该使用哪一个?
Debug类提供一组帮助调试代码的方法和属性。Trace类提供一组帮助跟踪代码执行的方法和属性,通俗的说就是为在不打断程序的调试或跟踪下,用来记录程序执行的过程。
Debug只在debug状态下会输出,Trace在Release下也会输出,在Release下Debug的内容会消失。
19, Debug Build和Release Build的区别,是否会有明显的速度变化?请说明理由。
首先以一个表格说明问题:
项目 |
Debug |
Release |
条件编译常数 |
Debug;Trace |
Trace |
优化代码 |
False |
True |
输出路径 |
binDebug |
binRelease |
生成调试信息 |
True |
False |
Debug模式下生成的程序集为调试版本,未经优化;在bindebug目录中有两个文件,除了要生成的.exe或.dll文件外,还有个.pdb文件,这个.pdb文件中就记录了代码中的断点等调试信息;Release模式下不包含调试信息,并对代码进行了优化,in elease目录下只有一个.exe或.dll文件。在项目文件夹下除了bin外,还有个obj目录。编译是分模块编译的,每个模块的编译结果就保存在了obj目录下。最后会合并为一个exe或者dll文件保存到bin之中。因为每次编译都是增量编译,也就是只重新编译改变了的模块,所以这个obj的目录的作用就是保存这些小块的编译结果,加快编译速度。
20, JIT是以assembly为单位发生还是以方法为单位发生?这对于工作区有何影响?
JIT编译是以方法为单位完成的,当用到相应的方法才把其编译执行,并将编译结果暂存当下一次用到时就不用再编译。可以一定程度上提高效率。
16. 对比抽象基类和接口的使用
如果要让自定义类包含基类的实现,应该选用抽象基类,接口多做契约使用。.NET中类只允许单继承,但接口允许多继承。
21, a.Equals(b)和a==b相同吗?
对于值类型的比较两者效果相同(值类型ValueType重写了Equals方法)。对于除string以外的引用类型==比较对象是否为同一引用,对于string,==比较字符串的内容。而Equals方法对所有引用对象都是比较其是否为同一对象的引用。
很多自定义类都会重写Equals所以不要只注意默认实现。
22, 在对象比较中,对象一致和对象相等分别是指什么?
对象一致指的是两个对象是否指向托管堆中同一个目标,其比较对象的类型与值两个方面。对象相等指的是两个对象中的数据成员是否相等。前者是一种浅比较,后者是一种深比较。
23, 在.NET中如何实现深拷贝(deep copy)?
实现深拷贝的程序结构基本如下:
示例代码:
1 //实现ICloneable接口 2 public class Copy : ICloneable 3 { 4 //实现ICloneable接口的Clone()方法 5 public override object Clone() 6 { 7 //在此实现深拷贝 8 } 9 }
实现深拷贝的代码中,新建一个对象,然后将对象的成员逐个赋值给新对象的成员。最后将新对象返回。
24,请解释一下ICloneable
当用户需要实现除MemberwiseClone之外的拷贝方法时(如深拷贝),用户可以实现ICloneable接口,并重写Clone()方法。在Clone()方法中编写自己的实现。
25,什么叫装箱。
将值类型对象放到托管堆中需要一个装箱操作。需要装箱的情况有很多,比如将值类型数据存入一个数组(Array类)时,值类型会被装箱然后存入托管堆。
26, string是值类型还是引用类型?
string这个引用类型是非常特殊一个引用类型。
它有两点特殊的地方。第一点对象分配的特殊。例如,有如下语句:
1 string str1 = "abcd"; 2 string str2 = "abcd";
那么.net在分配string类型的时候,先查看当前string类型列表是否有相同的,如果有的话,直接返回其的引用,否则重新分配。
第二点对象引用操作的特殊,即不同于真正意义上的引用操作。例如如下语句:
1 string str1 = "abcd"; 2 string str2 = str1; 3 str2 = "efgh";// str1 is still "abcd" here
当对于一个新的string类型是原有对象引用的时候,这点和一般的引用类型一样,但是当新的对象发生变化的时候,要重新分配一个新的地方,然后修改对象指向。
因此对于string操作的时候,尤其发生变化的时候,会显得比较慢,因为其牵扯到内存地址的变化。(所以对于数据量比较大的字符操作时候,使用StringBuilder来说效率会提升很高。)
27, XmlSerializer使用的针对属性的模式有什么好处?解决了什么问题?
这里的属性指attribute。可以将不需要序列化的数据标记为[XmlIgnore],只序列化有用的数据,而不是序列化整个对象。可以省去没有必要序列化的数据序列化工作,提升序列化时的性能。使用attribute还可以指导序列化的过程,以自定义生成xml文档的格式。(11题对XmlSerializer有介绍)
28, 为什么不应该在.NET中使用out参数?它究竟好不好?
当想要一个函数产生多个输出时,可以使用out参数返回函数的输出值。这应该是out参数最大的作用。out参数的缺陷在于,它允许一个未初始化变量就在函数中作为out参数使用。这样并不能保证在访问一个作为out参数的变量时,它已经被初始化过,容易产生错误的结果。(个人观点)
29, 特性能够放到某个方法的参数上?如果可以,这有什么用?
可以,作用可以对参数有进一步限定,比如输入参数为int类型,可以通过允许AttributeTargets=ParameterInfo的Attribute自定义实现来限定输入参数的大小,比如当输入参数小于100的时候便抱错。
对方法的参数设置Attribute的例子:
1 [AttributeUsage(AttributeTargets.Parameter)] 2 public class ParameterAtt : Attribute 3 { 4 public int Min = 100; 5 } 6 7 public class AttributeTest 8 { 9 public void TestMethod([ParameterAtt(Min = 100)] int par1) 10 { 11 ParameterInfo para = MethodInfo.GetCurrentMethod().GetParameters()[0]; 12 ParameterAtt att = ParameterAtt.GetCustomAttribute(para, typeof(ParameterAtt)) as ParameterAtt; 13 if (att.Min > par1) 14 { 15 throw new Exception("要求para1最小为" + att.Min); 16 } 17 } 18 }