一、对于 Web 性能优化,您有哪些了解和经验吗?
出现指数:五颗星
主要考点:这道题是博主在博客园的新闻里面看到的,回想之前几年的面试经历,发现此题出现概率还是比较高的。因为它的考面灰常广,可以让面试官很快了解你的技术涉及面以及这些技术面的深度。
参考答案:这个问题可以分前端和后端来说。
1、前端优化
(1)减少 HTTP 请求的次数。我们知道每次发送http请求,建立连接和等待相应会花去相当一部分时间,所以在发送http请求的时候,尽量减少请求的次数,一次请求能取出的数据就不要分多次发送。
(2)启用浏览器缓存,当确定请求的数据不会发生变化时,能够直接读浏览器缓存的就不要向服务端发送请求。比如我们ajax里面有一个参数能够设置请求的时候是否启用缓存,这种情况下就需要我们在发送请求的时候做好相应的缓存处理。
(3)css文件放 在<head>里面,js文件尽量放在页面的底部。因为请求js文件是很花费时间,如果放在<head>里面,就会导致页面的 DOM树呈现需要等待js文件加载完成。这也就是为什么很多网站的源码里面看到引用的文件放在最后的原因。
(4)使用压缩的css和js文件。这个不用多说,网络流量小。
(5)如果条件允许,尽量使用CDN的方式引用文件,这样就能减少网络流量。比如我们常用的网站http://www.bootcdn.cn/。
(6)在写js和css的语法时,尽量避免重复的css,尽量减少js里面循环的次数,诸如此类。
2、后端优化:
(1)程序的优化:这是一个很大的话题,我这里就选几个常见的。比如减少代码的层级结构、避免循环嵌套、避免循环CURD数据库、优化算法等等。
(2)数据库的优化:(由于数据库优化不是本题重点,所以可选几个主要的来说)比如启用数据库缓存、常用的字段建索引、尽量避免大事务操作、避免select * 的写法、尽量不用in和not in 这种耗性能的用法等等。
(3)服务器优化:(这个可作为可选项)负载均衡、Web服务器和数据库分离、UI和Service分离等等。
二、MVC路由理解?(屡见不鲜)
出现指数:五颗星
主要考点:此题主要考点是MVC路由的理解。
参考答案:
1、首先我们要理解MVC中路由的作用:url Routing的作用是将浏览器的URL请求映射到特定的MVC控制器动作。
2、当我们访问http://localhost:8080/Home/Index 这个地址的时候,请求首先被UrlRoutingModule截获,截获请求后,从Routes中得到与当前请求URL相符合的RouteData对象, 将RouteData对象和当前URL封装成一个RequestContext对象,然后从Requestcontext封装的RouteData中得到 Controller名字,根据Controller的名字,通过反射创建控制器对象,这个时候控制器才真正被激活,最后去执行控制器里面对应的 action。
三、谈谈你觉得做的不错系统,大概介绍下用到了哪些技术?
出现指数:五颗星
主要考点:这是一道非常开放的面试题。博主遇到过好几家公司的面试官都问道了这个,博主觉得他们是想通过这个问题快速了解面试者的技术水平。此题只要结合你最近项目用到的技术谈谈就好了。
参考答案:
就拿我之前做过的一个项目为例来简单说明一下吧。项目分为客户端和服务端,客户端分 为BS客户端和CS客户端,BS客户端采用MVC 5.0的框架,CS客户端是Winform项目,服务端使用WebApi统一提供服务接口,考虑以后可能还要扩展手机端,所以服务接口的参数和返回值使用 通用的Json格式来传递数据。
1、服务端采用的面向接口编程,我们在软件架构的过程中,层和层之间通过接口依赖, 下层不是直接给上层提供实现,而是提供接口,具体的实现以依赖注入的方式在运行的时候动态注入进去。MEF就是实现依赖注入的一种组件。它的使用使得UI 层不直接依赖于BLL层,而是依赖于中间的一个IBLL层,在程序运行的时候,通过MEF动态将BLL里面的实现注入到UI层里面去,这样做的好处是减少 了层与层之间的耦合。服务端的异常里面、权限验证、日志记录等通用功能使用了AOP拦截的机制统一管理,项目中使用的是Postsharp这个组件,很好 地将通用需求功能从不相关的类当中分离出来,提高了代码的可维护性。
2、BS的客户端采用的jquery+bootstrap 的方式,所有页面采用流式布局,能更好适应各种不同的终端设备(PC、手机)。项目中使用了各种功能强大的bootstrap组件,能适应各种复杂的业务需求。
四、Js继承实现。
出现指数:五颗星
主要考点:这道题考验面试者对js理解的深度。根据博主的经历,这种题一般在笔试出现的几率较大,为什么把它放在这里,因为它确实太常见了。其实js实现继承的方式很多,我们只要写好其中一种就好了。
参考答案:原型链继承
- function Person(name, age){
- this.name = name;
- this.age = age;
- }
- //通过原型链给Person添加一个方法
- Person.prototype.getInfo = function(){
- console.log(this.name + " is " + this.age + " years old!"); } function Teacher(staffId){ this.staffId = staffId; } //通过prototype生命Teacher继承Person Teacher.prototype = new Person(); var will = new Teacher(1000); will.name = "Will"; will.age = 28;
- will.getInfo();
五、谈谈你对设计模式的认识?结合你用得最多的一种设计模式说说它的使用。
出现指数:五颗星
主要考点:不用多说,这题考的就是对设计模式的理解。一般为了简单可能会要求你写一个单例模式,注意最好是写一个完整点的,考虑线程安全的那种。然后会让你说说你在项目中什么情况下会用到这种模式
参考答案:
通用写法
- public class Singleton
- {
- // 定义一个静态变量来保存类的实例
- private static Singleton uniqueInstance;
- // 定义一个标识确保线程同步
- private static readonly object locker = new object();
- // 定义私有构造函数,使外界不能创建该类实例
- private Singleton()
- {
- }
- /// <summary>
- /// 定义公有方法提供一个全局访问点,同时你也可以定义公有属性来提供全局访问点
- /// </summary>
- /// <returns></returns>
- public static Singleton GetInstance()
- {// 双重锁定只需要一句判断就可以了
- if (uniqueInstance == null)
- {
- lock (locker)
- {
- // 如果类的实例不存在则创建,否则直接返回
- if (uniqueInstance == null)
- {
- uniqueInstance = new Singleton();
- }
- }
- }
- return uniqueInstance;
- }
- }
单例模式确保一个类只有一个实例,并提供一个全局访问点,它的使用场景比如任务管理 器整个系统中应该只有一个把,再比如操作文件的对象,同一时间我们只能有一个对象去操作文件吧。最重要的,比如我们项目中用得非常多的功能→日志记录,在 一个线程中,记录日志的对象应该也只能有一个吧。单例模式的目的是为了保证程序的安全性和数据的唯一性。或者你也可以结合你使用的其他设计模式来说明。
六、IIS的工作原理?
出现指数:四颗星
主要考点:此题主要考的是.net framework和IIS是如何结合呈现页面的。这是一个有点复杂的过程,面试的时候不可能说得完整,那么我们就抓住几个关键点说说就可以。其实博主也不能完全理解这个过程,今天正好借这个机会温习下。
参考答案:
1、当客户端发送HTTP Request时,服务端的HTTP.sys(可以理解为IIS的一个监听组件) 拦截到这个请求;
2、HTTP.sys 联系 WAS 向配置存储中心请求配置信息。
3、然后将请求传入IIS的应用程序池。
4、检查请求的后缀,启动aspnet_isapi.dll这个dll,这个dll是.net framework里面的,也就是说到这一步,请求进入了.net framework的管辖范围。
5、这个时候如果是WebForm,开始执行复杂的页面生命周期(HttpRuntime→ProcessRequest→HttpContext→HttpHandler);如果是MVC,则启动mvc的路由机制,根据路由规则为URL来指定HttpHandler。
6、httpHandler处理请求后,请求结束,给出Response,客户端处理响应,整个过程结束。
七、Http协议
出现指数:四颗星
主要考点:此题主要考对于web里面http协议的理解。
参考答案:
1、http协议是浏览器和服务器双方共同遵循的规范,是一种基于TCP/IP应用层协议。
2、http是一种典型的请求/响应协议。客户端发送请求,请求的内容以及参数存放到请求报文里面,服务端收到请求后,做出响应,返回响应的结果放到响应报文里面。通过F12可以查看请求报文和响应报文。
3、http协议是”无状态”的,当客户端向服务端发送一次http请求后,服务端收到请求然后返回给客户端相应的结果,服务器会立即断开连接并释放资源。在实际开发过程中,我们有时需要“保持”这种状态,所以衍生出了Session/Cookie这些技术。
4、http请求的方式主要有get/post。
5、http状态码最好记几个,博主有一次面试就被问到了。200(请求成功)、404(请求的资源不存在)、403(禁止访问)、5xx(服务端错误)
八、数据库优化经验(后端工程师非常常见)
出现指数:四颗星
主要考点:此题考察后端工程师操作数据库的经验。说实话,数据库是博主的弱项,博主觉得对于这种考题,需要抓住几个常用并且关键的优化经验,如果说得不对,欢迎大家斧正。
参考答案:
1、数据库运维方面的优化:启用数据库缓存。对于一些比较常用的查询可以采用数据库缓存的机制,部署的时候需要注意设置好缓存依赖项,防止“过期”数据的产生。
2、数据库索引方面的优化:比如常用的字段建索引,联合查询考虑联合索引。(PS:如果你有基础,可以敞开谈谈聚集索引和非聚集索引的使用场景和区别)
3、数据库查询方面的优化:避免select * 的写法、尽量不用in和not in 这种耗性能的用法等等。
4、数据库算法方面的优化:尽量避免大事务操作、减少循环算法,对于大数据量的操作,避免使用游标的用法等等。
九、关于代码优化你怎么理解?你会考虑去代码重构吗?
出现指数:四颗星
主要考点:此题考的是面试者对代码优化的理解,以及代码如何重构的相关知识。
参考答案:
1、对于代码优化,之前的公司每周会做代码审核,审核的主要作用就是保证代码的正确性和执行效率,比如减少代码的层级结构、避免循环嵌套、避免循环CURD数据库、尽量避免一次取出大量数据放在内存中(容易内存溢出)、优化算法等。
2、对于陈旧代码,可能很多地方有调用,并且开发和维护人员很有可能不是同一个人,所以重构时要格外小心,如果没有十足的把握,不要轻易重构。如果必须要重构,必须做好充分的单元测试和全局测试。
十、谈谈你的优点和缺点?
出现指数:四颗星
主要考点:这道题让人有一种骂人的冲动,但是没办法,偏偏很多所谓的大公司会问这个。比如华为。这个问题见仁见智,答案可以自己组织。
参考答案:
优点:对于新的技术学习能力强,能很快适应新环境等等
缺点:对技术太过于执着等等
十一、关于服务器端 MVC 架构的技术实现,您是怎样理解的?这种架构方式有什么好处?您在项目中是如何应用这一架构的?
出现指数:三颗星
主要考点:此题主要考的对于MVC这种框架的理解。
参考答案:MVC,顾名思义,Model、View、Controller。所有的 界面代码放在View里面,所有涉及和界面交互以及URL路由相关的逻辑都在Controller里面,Model提供数据模型。MVC的架构方式会让系 统的可维护性更高,使得每一部分更加专注自己的职责,并且MVC提供了强大的路由机制,方便了页面切换和界面交互。然后可以结合和WebForm的比较, 谈谈MVC如何解决复杂的控件树生成、如何避免了复杂的页面生命周期。
十二、网站优化:网站运行慢,如何定位问题?发现问题如何解决?
出现指数:三颗星
主要考点:此题和问题一类似,考察Web的问题定位能力和优化方案。
参考答案:
浏览器F12→网络→查看http请求数以及每个请求的耗时,找到问题的根源,然后依次解决,解决方案可以参考问题一里面的Web优化方案。
十三、说说你最擅长的技术?并说说你是如何使用的?
出现指数:三颗星
主要考点:这是一道非常开放的面试题。最初遇到这种问题,博主很想来一句:你妹,这叫什么问题!但确实有面试官问到。回头想想,其实此题考查你擅长的技术的涉及深度。其实博主觉得对于这个问题,可以结合你项目中用到的某一个技术来说就好了。
参考答案:
简单谈谈MEF在我们项目里面的使用吧。
在谈MEF之前,我们必须要先谈谈DIP、IOC、DI
依赖倒置原则(DIP):一种软件架构设计的原则(抽象概念)
控制反转(IoC):一种反转流、依赖和接口的方式(DIP的具体实现方式)。
依赖注入(DI):IoC的一种实现方式,用来反转依赖(IoC的具体实现方式)。
什么意思呢?也就是说,我们在软件架构的过程中,层和层之间通过接口依赖,下层不是 直接给上层提供实现,而是提供接口,具体的实现以依赖注入的方式在运行的时候动态注入进去。MEF就是实现依赖注入的一种组件。它的使用使得UI层不直接 依赖于BLL层,而是依赖于中间的一个IBLL层,在程序运行的时候,通过MEF动态将BLL里面的实现注入到UI层里面去,这样做的好处是减少了层与层 之间的耦合。这也正是面向接口编程方式的体现。
十四、自己写过JS组件吗?举例说明。
出现指数:三颗星
主要考点:此题考的js组件封装和js闭包的一些用法。一般来说,还是笔试出现的几率较大。
参考答案:自定义html的select组件
- //combobox
- (function ($) {
- $.fn.combobox = function (options, param) {
- if (typeof options == 'string') {
- return $.fn.combobox.methods[options](this, param);
- }
- options = $.extend({}, $.fn.combobox.defaults, options || {});
- var target = $(this);
- target.attr('valuefield', options.valueField);
- target.attr('textfield', options.textField);
- target.empty();
- var option = $('<option></option>');
- option.attr('value', '');
- option.text(options.placeholder);
- target.append(option);
- if (options.data) {
- init(target, options.data);
- }
- else {
- //var param = {};
- options.onBeforeLoad.call(target, option.param);
- if (!options.url) return;
- $.getJSON(options.url, option.param, function (data) {
- init(target, data);
- });
- }
- function init(target, data) {
- $.each(data, function (i, item) {
- var option = $('<option></option>');
- option.attr('value', item[options.valueField]);
- option.text(item[options.textField]);
- target.append(option);
- });
- options.onLoadSuccess.call(target);
- }
- target.unbind("change"); target.on("change", function (e) { if (options.onChange) return options.onChange(target.val()); }); } $.fn.combobox.methods = { getValue: function (jq) { return jq.val(); }, setValue: function (jq, param) { jq.val(param); }, load: function (jq, url) { $.getJSON(url, function (data) { jq.empty(); var option = $('<option></option>'); option.attr('value', ''); option.text('请选择'); jq.append(option); $.each(data, function (i, item) { var option = $('<option></option>'); option.attr('value', item[jq.attr('valuefield')]); option.text(item[jq.attr('textfield')]); jq.append(option); }); }); } }; $.fn.combobox.defaults = { url: null, param: null, data: null, valueField: 'value', textField: 'text', placeholder: '请选择', onBeforeLoad: function (param) { }, onLoadSuccess: function () { }, onChange: function (value) { }
- };
- })(jQuery);
- $("#sel_search_orderstatus").combobox({
- url: '/apiaction/Order/OrderApi/GetOrderStatu',
- valueField: 'VALUE',
- textField: 'NAME'
- });
就能自动从后台取数据,注意valueField和textField对应要显示和实际值。
十五、自己写过多线程组件吗?简要说明!
出现指数:三颗星
主要考点:此题是两年前博主在携程的一次电话面试中遇到的,其他地方基本上没遇到过,其实到现在也不能理解当时面试官问这个问题的目的。但我想,此问题必有出处,估计面试官是想了解你对多线程以及线程池等的理解深度。
参考答案:可以参考http://www.cnblogs.com/Alexander-Lee/archive/2009/10/31/1593647.html
一.填空题
1.面向对象的语言具有(继承)性、(多态)性、(封装)性。
2.能用foreach遍历访问的对象需要实现 (IEnumberable)接口或声明(GetEnumberator)方法的类型。
3.列举ADO.net中的五个主要对象(Command)、(Connection)、(DataReader)、(DataSet)、(DataAdapter)。
4.C#中的三元运算符是__(?:)__
5.当整数a赋值给一个object对象时,整数a将会被__(装箱)___
6.类成员有__(3)__种可访问形式
7.float f=-123.567F;int i=(int)f;i的值现在是_(-123)__
8.委托声明的关键字是___( delegate) _
9.在Asp.net中所有的自定义用户控件都必须继承自_ (System.Web.UI.UserControl) __
10.在.Net中所有可序列化的类都被标记为__[serializable]___
11.在.Net托管代码中我们不用担心内存漏洞,这是因为有了_ GC __
12.当类T只声明了私有实例构造函数时,则在T的程序文本外部,_不可以_(可以 or 不可以)从T派生出新的类,_不可以_(可以 or 不可以)直接创建T的任何实例。
二.选择题
1.以下叙述正确的是: BC
A. 接口中可以有虚方法。 B. 一个类可以实现多个接口。
C. 接口不能被实例化。 D. 接口中可以包含已实现的方法。
2.从数据库读取记录,你可能用到的方法有: BCD
A. ExecuteNonQuery B. ExecuteScalar
C. Fill D. ExecuteReader
3.对于一个实现了IDisposable接口的类,以下哪些项可以执行与释放或重置非托管资
相关的应用程序定义的任务?(多选) ( ABC )
A.Close B.Dispose C.Finalize D.using E.Quit
4.以下关于ref和out的描述哪些项是正确的?(多选) ( ACD )
A.使用ref参数,传递到ref参数的参数必须最先初始化。
B.使用out参数,传递到out参数的参数必须最先初始化。
C.使用ref参数,必须将参数作为ref参数显式传递到方法。
D.使用out参数,必须将参数作为out参数显式传递到方法。
5.在对SQL Server 数据库操作时应选用(A)
A.SQL Server .NET Framework 数据提供程序;
B.OLE DB .NET Framework 数据提供程序;
C.ODBC .NET Framework 数据提供程序;
D.Oracle .NET Framework数据提供程序;
6.下列选项中,(C)是引用类型。
A.enum类型 B.struct类型 C.string类型 D.int类型
7.关于ASP.NET中的代码隐藏文件的描述正确的是(C)
A.Web窗体页的程序的逻辑由代码组成,这些代码的创建用于与窗体交互。编程逻辑唯一与用户界面不同的文件中。该文件称作为“代码隐藏”文件,如果用C#创建,该文件将具有“.ascx.cs”扩展名。
B.项目中所有Web窗体页的代码隐藏文件都被编译成.EXE文件。
C.项目中所有的Web窗体页的代码隐藏文件都被编译成项目动态链接库(.dll)文件。
D.以上都不正确。
8.以下描述错误的是(A)
A.在C++中支持抽象类而在C#中不支持抽象类。
B.C++中可在头文件中声明类的成员而在CPP文件中定义类的成员,在C#中没有头文件并且在同一处声明和定义类的成员。
C.在C#中可使用 new 修饰符显式隐藏从基类继承的成员。
D.在C#中要在派生类中重新定义基类的虚函数必须在前面加Override。
9.C#的数据类型有(B)
A.值类型和调用类型 B.值类型和引用类型
C.引用类型和关系类型 D.关系类型和调用类型
10.下列描述错误的是(D)
A.类不可以多重继承而接口可以
B.抽象类自身可以定义成员而接口不可以
C.抽象类和接口都不能被实例化
D.一个类可以有多个基类和多个基接口
11.在DOM中,装载一个XML文档的方法(D)
A.save方法 B.load方法 C.loadXML方法 D.send方法
12.下列关于构造函数的描述正确的是(C)
A.构造函数可以声明返回类型。
B.构造函数不可以用private修饰
C.构造函数必须与类名相同
D.构造函数不能带参数
13.以下是一些C#中的枚举型的定义,其中错误的用法有(A)
A.public enum var1{ Mike = 100, Nike = 102, Jike }
B.public enum var1{ Mike = 100, Nike, Jike }
C.public enum var1{ Mike=-1 , Nike, Jike }
D.public enum var1{ Mike , Nike , Jike }
14.int[][] myArray3=new int[3][]{new int[3]{5,6,2},new int[5]{6,9,7,8,3},new int[2]{3,2}}; myArray3[2][2]的值是(D)
A.9 B.2 C.6 D.越界
15.接口是一种引用类型,在接口中可以声明(A),但不可以声明公有的域或私有的成员变量
A..方法、属性、索引器和事件 B.方法、属性信息、属
C.索引器和字段 D.事件和字段;
16.ASP.NET框架中,服务器控件是为配合Web表单工作而专门设计的。服务器控件有两种类型,它们是(A )
A.HTML控件和Web控件 B.HTML控件和XML控件
C.XML控件和Web控件 D.HTML控件和IIS控件
17.ASP.NET中,在Web窗体页上注册一个用户控件,指定该控件的名称为”Mike”,正确的注册指令为( D)
A.<%@Register TagPrefix = “Mike” TagName = “Space2” Src = “myX.ascx”%>
B.<%@Register TagPrefix = “Space2” TagName = “Mike” Src = “myX.ascx”%>
C.<%@Register TagPrefix = “SpaceX” TagName = “Space2” Src = “Mike”%>
D.以上皆非
18.在ADO.NET中,对于Command对象的ExecuteNonQuery()方法和ExecuteReader()方法,下面叙述错误的是(C)
A.insert、update、delete等操作的Sql语句主要用ExecuteNonQuery()方法来执行;
B.ExecuteNonQuery()方法返回执行Sql语句所影响的行数。
C.Select操作的Sql语句只能由ExecuteReader()方法来执行;
D.ExecuteReader()方法返回一个DataReder对象;
19.下列ASP.NET语句(B)正确地创建了一个与SQL Server 2000数据库的连接。
A. SqlConnection con1 = new Connection(“Data Source = localhost; Integrated Security = SSPI; Initial Catalog = myDB”);
B. SqlConnection con1 = new SqlConnection(“Data Source = localhost; Integrated Security = SSPI; Initial Catalog = myDB”);
C. SqlConnection con1 = new SqlConnection(Data Source = localhost; Integrated Security = SSPI; Initial Catalog = myDB);
D. SqlConnection con1 = new OleDbConnection(“Data Source = localhost; Integrated Security = SSPI; Initial Catalog = myDB”);
20.Winform中,关于ToolBar控件的属性和事件的描述不正确的是(D)
A.Buttons属性表示ToolBar控件的所有工具栏按钮
B.ButtonSize属性表示ToolBar控件上的工具栏按钮的大小,如高度和宽度
C.DropDownArrows属性表明工具栏按钮(该按钮有一列值需要以下拉方式显示)旁边是否显示下箭头键
D.ButtonClick事件在用户单击工具栏任何地方时都会触发
21.在ADO.NET中执行一个存储过程时,如果要设置输出参数则必须同时设置参数的方向和(D ),必要时还要设置参数尺寸。
A.大小; B.上限; C.初始值; D.类型
22.如果将窗体的FormBoderStyle设置为None,则( A)。
A.窗体没有边框并不能调整大小; B.窗体没有边框但能调整大小;
C.窗体有边框但不能调整大小; D.窗体是透明的;
23.如果要将窗体设置为透明的,则( B)
A.要将FormBoderStyle属性设置为None; B.要将Opacity属性设置为小于100%的值;
C.要将locked 属性设置为True; D.要将 Enabled属性设置为True;
24.下列关于C#中索引器理解正确的是(B/C )
A.索引器的参数必须是两个或两个以上 B.索引器的参数类型必须是整数型
C.索引器没有名字 D.以上皆非
25.下面描述错误的是( C/D)
A.窗体也是控件; B.窗体也是类; C.控件是从窗体继承来的;D.窗体的父类是控件类
26.要对注册表进行操作则必须包含( D)
A.System.ComponentModel命名空间;B.System.Collections命名空间;
C.System.Threading命名空间; D.Microsoft.Win32命名空间;
27.要创建多文档应用程序,需要将窗体的(D )属性设为true。
A.DrawGrid; B.ShowInTaskbar; C.Enabled; D.IsMdiContainer;
28.如果设treeView1=new TreeView(),则treeView1.Nodes.Add("根节点")返回的是一个 (A)类型的值。
A.TreeNode; B.int; C.string; D.TreeView;
29.下面关于XML的描述错误的是(D)
A.XML提供一种描述结构化数据的方法;
B.XML 是一种简单、与平台无关并被广泛采用的标准;
C.XML文档可承载各种信息;
D.XML只是为了生成结构化文档;
30.装箱、拆箱操作发生在: ( C )
A.类与对象之间 B.对象与对象之间
C.引用类型与值类型之间 D.引用类型与引用类型之间
31.用户类若想支持Foreach语句需要实现的接口是: ( A )
A.Ienumerable B.Ienumerator C.Icollection D.IcollectData
32.Net Framework通过什么与COM组件进行交互操作?( C )
A.Side By Side B.Web Service C.Interop D.PInvoke
33..Net依靠以下哪一项技术解决COM存在的Dll Hell问题的?( A )
A.Side By Side B.Interop C.Pinvoke D.COM+
34.装箱与拆箱操作是否是互逆的操作?( B )
A.是 B.否
35.以下哪个是可以变长的数组?( D )
A.Array B.string[] C.string[N] D.ArrayList
36.用户自定义异常类需要从以下哪个类继承:( A )
A.Exception B.CustomException C.ApplicationException D.BaseException
简介
- 此次包含的不止是.NET知识,也包含少许前端知识以及.net面试时所涉及的种种考点,希望能给找工作的同学们哪怕一点点帮助。
在此提醒下,本文适合:
- 刚毕业的萌新
- 工作不久换工作的
- 大牛可忽略啦
1.接口
文章引用:http://www.cnblogs.com/jiajiayuan/archive/2011/09/16/2178462.html
①.接口的特性:
- 接口类似于抽象基类,不能直接实例化接口;接口中的方法都是抽象方法,实现接口的任何非抽象类型都必须实现接口的所有成员:
- 当显式实现该接口的成员时,实现的成员不能通过类实例访问,只能通过接口实例访问。
- 当隐式实现该接口的成员时,实现的成员可以通过类实例访问,也可以通过接口实例访问,但是实现的成员必须是公有的。
- 接口不能包含常量、字段、运算符、实例构造函数、析构函数或类型、不能包含静态成员。
- 接口成员是自动公开的,且不能包含任何访问修饰符。
- 接口自身可从多个接口继承,类和结构可继承多个接口,但接口不能继承类。
②为什么不能指定接口中方法的修饰符?
接口中的方法用来定义对象之间通信的契约,指定接口中的方法为私有或保护没有意义。它们默认为公有方法。
interface IProgram
{
void Fun();
}
class Program:IProgram
{
//显式实现接口成员
void IProgram.Fun()
{
Console.WriteLine("I am Fun.");
}
staticvoid Main(string[] args)
{
IProgram p =new Program(); //声明一个接口实例,但不是对接口进行实例化
p.Fun();
Console.Read();
}
}
③实现接口可以显式实现和隐式实现,那么这两种实现到底有什么优缺点呢?
一般情况,当类或者结构要实现的是单个接口,可以使用隐式实现。
如果类或者结构继承了多个接口且接口中具有相同名称成员时,就要用到显式实现,当显式实现方式存在时,隐式实现方式就失效了。
interface IProgram
{
void Fun();
}
interface IAProgram
{
void Fun();
}
class Program : IProgram, IAProgram
{
void IProgram.Fun() //显式实现接口IProgram
{
Console.WriteLine("I am IProgram Fun.");
}
void IAProgram.Fun() //显式实现接口IAProgram
{
Console.WriteLine("I am IAProgram Fun.");
}
//public void Fun() //隐式实现接口
//{
// Console.WriteLine("I am Program Fun.");
//}
staticvoid Main(string[] args)
{
//IProgram p = new Program();
//p.Fun();
//IAProgram ap = new Program();
//ap.Fun();
Program pro =new Program();
((IProgram)pro).Fun();
((IAProgram)pro).Fun();
Console.Read();
}
}
④接口的继承:
接口继承和类继承不同
- 首先,类继承不仅是说明继承,而且也是实现继承;而接口继承只是说明继承。
也就是说,派生类可以继承基类的方法实现,而派生的接口只继承了父接口的成员方法说明,而没有继承父接口的实现; - 其次,C#中类继承只允许单继承,但是接口继承允许多继承,一个子接口可以有多个父接口。
接口可以从零或多个接口中继承。从多个接口中继承时,用":"后跟被继承的接口名字,多个接口名之间用","分割。
被继承的接口应该是可以访问得到的,比如从private 类型或internal 类型的接口中继承就是不允许的。
接口不允许直接或间接地从自身继承。和类的继承相似,接口的继承也形成接口之间的层次结构。
interface IProgram
{
void Fun();
}
interface IAProgram:IProgram
{
}
class Program : IAProgram
{
void IProgram.Fun()
{
Console.WriteLine("I am IProgram Fun.");
}
static void Main(string[] args)
{
Program pro =new Program();
((IAProgram)pro).Fun();
Console.Read();
}
}
⑤接口的覆盖:
由于接口的实现没有方法体,抽象方法也没有方法体,那么当我们在接口的实现方法里调用抽象方法时,会如何执行呢?
interface IProgram
{
void Fun();
}
abstract class AProgram : IProgram
{
public abstract void AFun();
void IProgram.Fun()
{
AFun();
}
}
class Program:AProgram
{
public override void AFun()
{
Console.WriteLine("I am AProgram.");
}
static void Main(string[] args)
{
IProgram pro =new Program();
pro.Fun();
Console.Read();
}
}
//结果:I am Aprogram.
通过断点,可以看到,当执行pro.Fun();时,首先会跳到接口的实现方法里,然后去调用抽象函数的实现方法,当抽象函数的方法实现后,再回到接口的实现方法,直到执行完成。
当我们在实现接口的方法里调用虚函数呢?
interface IProgram
{
void Fun();
}
class AProgram : IProgram
{
public virtual void AFun() //注意这里是虚函数
{
Console.WriteLine("I am virtual AFun.");
}
void IProgram.Fun()
{
AFun();
}
}
class Program:AProgram
{
public override void AFun() //这里是Override重写
{
Console.WriteLine("I am override AFun.");
}
static void Main(string[] args)
{
IProgram pro =new Program();
pro.Fun();
Console.Read();
}
}
这时,我们发现,执行的顺序和上一个例子是相同的。所以结果为:I am override AFun.
由此,我们可以继续联想,当我们把override关键字,换成new呢?是不是也是同样的结果,还是和我们以前讲的例子一样,是隐藏呢?
我们把上面的例子进行改进:
interface IProgram
{
void Fun();
}
class AProgram : IProgram
{
public virtual void AFun()
{
Console.WriteLine("I am virtual AFun.");
}
void IProgram.Fun()
{
AFun();
}
}
class Program:AProgram
{
public new void AFun()
{
Console.WriteLine("I am new AFun.");
}
static void Main(string[] args)
{
Program pro =new Program();
((IProgram)pro).Fun();
pro.AFun();
Console.Read();
}
}
结果为:
I am virtual AFun.
I am new AFun.
由于前面已经讲过了==,这里不在对此进行分析,由此我们可知使用New关键字是对其进行隐藏,当对接口实现的方法里调用的是虚方法时,和类的执行过程是一样的。
⑥接口和抽象类的区别
- 接口用于规范,抽象类用于共性。
- 接口中只能声明方法,属性,事件,索引器。而抽象类中可以有方法的实现,也可以定义非静态的类变量。
- 抽象类是类,所以只能被单继承,但是接口却可以一次实现多个。
- 抽象类可以提供某些方法的部分实现,接口不可以。
- 抽象类的实例是它的子类给出的。接口的实例是实现接口的类给出的。
- 在抽象类中加入一个方法,那么它的子类就同时有了这个方法。而在接口中加入新的方法,那么实现它的类就要重新编写(这就是为什么说接口是一个类的规范了)。
- 接口成员被定义为公共的,但抽象类的成员也可以是私有的、受保护的、内部的或受保护的内部成员(其中受保护的内部成员只能在应用程序的代码或派生类中访问)。
- 此外接口不能包含字段、构造函数、析构函数、静态成员或常量。
⑦C#中的接口和类有什么异同
异:
- 不能直接实例化接口。
- 接口不包含方法的实现。
- 接口可以实现多继承,而类只能是单继承。
- 类定义可在不同的源文件之间进行拆分。
同:
- 接口、类和结构可从多个接口继承。
- 接口类似于抽象基类:继承接口的任何非抽象类型都必须实现接口的所有成员。
- 接口可以包含事件、索引器、方法和属性。
- 一个类可以实现多个接口。
2.您在什么情况下会用到虚方法或抽象类,接口?
- 如果某个方法可能性在派生类中会被重写。这时就将该方法写为虚方法。
- 抽象类:是一个类型,与派生类之间的关系是一个“ISA”的关系。用来做基类,抽象类不能创建对象,类中包括抽象方法和实例方法。
- 接口:是设计一个规范,描述了Can do ;与实现类之间是中”LINE A 的关系,C#中接口不能包含字段访问修饰符。
3.重载(Overload )和覆写(Override)的区别
简述:简单的说,一个是同一个函数的几种形式,一个是重写父类函数。
重载:当类包含两个名称相同但签名不同(方法名相同,参数列表不相同)的方法时发生方法重载。用方法重载来提供在语义上完成相同而功能不同的方法。
覆写:在类的继承中使用,通过覆写子类方法可以改变父类虚方法的实现。
区别:
- 方法的覆盖是子类和父类之间的关系,是垂直关系;方法的重载是同一个类中方法之间的关系,是水平关系。
- 覆盖只能由一个方法,或只能由一对方法产生关系;方法的重载是多个方法之间的关系。
- 覆盖要求参数列表相同;重载要求参数列表不同。
- 覆盖关系中,调用那个方法体,是根据对象的类型(对象对应存储空间类型)来决定;重载关系,是根据调用时的实参表与形参表来选择方法体的。
4.值类型和引用类型的区别?写出C#的样例代码。
简述:值类型包括简单类型、结构体类型和枚举类型,引用类型包括自定义类、数组、接口、委托等
- 赋值方式:将一个值类型变量赋给另一个值类型变量时,将复制包含的值。这与引用类型变量的赋值不同,引用类型变量的赋值只复制对象的引用,而不复制对象本身。
- 派生:值类型不可能派生出新的类型,所有的值类型均隐式派生自 System.ValueType。但与引用类型相同的是,结构也可以实现接口。
- null:与引用类型不同,值类型不可能包含 null 值。然而,可空类型功能允许将 null 赋给值类型。
-
每种值类型均有一个隐式的默认构造函数来初始化该类型的默认值。
值类型主要由两类组成:结构、枚举①. 结构分为以下几类:Numeric(数值)类型、整型、浮点型、decimal、bool、用户定义的结构。
②. 引用类型的变量又称为对象,可存储对实际数据的引用。声明引用类型的关键字:class、interface、delegate、内置引用类型: object、string
-
值类型存贮在栈中,而引用类型存贮在动态的堆中,栈是先进先出的有系统管理的空间,而堆是由应用程序控制的可随时申请和释放该空间,在Donnet中一般情况下有垃圾收集器处理,他们的不同导致在编程上的不同。
例:
using System;
using System.Text;
class EventDel
{
static void Main(string[] args)
{
StringBuilder a=new StringBuilder();//将StringBuilder的一个首地址传给a
StringBuilder b=a; //将StringBuilder的一个首地址传给b
b.Append("mxh");
Console.WriteLine(a);
a=null;
Console.WriteLine(b);
}
}
"a=null"的意思是:a的引用置为空但此时StringBuilder的堆空间并没有被释放,因此在此之后,输出b时,仍然可以输出mxh
输出结果:
mxh
mxh
5.委托和事件简述
参考资料 :
C# 知识回顾 - 委托 delegate
事件是不是一种委托?
委托是一种安全的函数指针,事件是一种消息机制
委托与事件是什么关系?为什么要使用委托
委托提供了封装方法的方式,事件是某动作已发生的说明,事件是建立于委托之上的。
程序运行时同一个委托能够用来调用不同的方法,只要改变它的引用方法即可,因此委托调节器用的方法不是在编译时决定的,而是在运行时确定的.
6.Session,ViewState,Application,cookie的区别?
- Session:用于保持状态的基于 Web 服务器的方法。Session 允许通过将对象存储在Web 服务器的内存中在整个用户会话过程中保持任何对象。主要用于保持代码隐藏类中对象的状态。为每个用户创建的,用于存储单个用户,因为他是相对每个用户的.所以可能来取得在线人数等。
- ViewState:主要用于保持 Web 页上控件的状态。当 Web 页上的控件被绑定到代码隐藏类中的对象。
- Application 用于存储所有用户都可视的信息.所以它存储的是要让所有用户共享的一些信息.如总访问数等Cache,页面缓存。
- Cookie:通常我们都把它放在客户端,也可以存储在服务器端。主要用它存储用户的个性设制,和登陆信息。
7.Application,Session,Cookie,ViewState和Cache生命周期
在ASP.NET中,有很多种保存信息的内置对象,如:Application,Session,Cookie,ViewState和Cache等。下面分别介绍它们的用法和区别。
①.Application对象
Application用于保存所有用户的公共的数据信息,如果使用Application对象,一个需要考虑的问题是任何写操作都要在Application_OnStart事件(global.asax)中完成.尽管使用Application.Lock和Applicaiton.Unlock方法来避免写操作的同步,但是它串行化了对Application对象的请求,当网站访问量大的时候会产生严重的性能瓶颈.因此最好不要用此对象保存大的数据集合. 下面我们做个在线用户统计的例子来说明这个问题:
Global.asax类
代码
using System;
using System.Collections;
using System.ComponentModel;
using System.Web;
using System.Web.SessionState;
using System.IO;
/// Global 的摘要说明。
public class Global : System.Web.HttpApplication
{
/// 必需的设计器变量。
private System.ComponentModel.IContainer components = null;
private FileStream fileStream;
private StreamReader reader;//读字符流
private StreamWriter writer;//写字符流
public Global()
{
InitializeComponent();
}
protected void Application_Start(Object sender, EventArgs e)
{
Application["CurrentGuests"]=0;//初始花为0;
fileStream = File.Open(Server.MapPath("counts.text"),FileMode.OpenOrCreate);//文件不存在,创建文件
reader = new StreamReader(fileStream);//要读取的完整路径
Application["AllGuests"] = Convert.ToInt32(reader.ReadLine()); //从当前流中读取一行字符并将数据作为字符串返回
reader.Close();//关闭流
}
protected void Session_Start(Object sender, EventArgs e)//当用户访问网站时,在线用户+1,总访问数+1
{
Application.Lock();//同步,避免同时写入
Application["CurrentGuests"] =(int)Application["CurrentGuests"]+ 1;//总在线用户数
Application["AllGuests"] =(int)Application["AllGuests"]+ 1;//访问网站的总用户数
fileStream = new FileStream(Server.MapPath("counts.text"),FileMode.OpenOrCreate,FileAccess.ReadWrite);//
writer = new StreamWriter(fileStream);//实现一个写入流,使其以一种特定的编码向流中写入字符
writer.WriteLine(Application["AllGuests"].ToString());//把访问网站的总用户数再次写入到文件
writer.Close();//关闭写入流
Application.UnLock();//同步结束
}
protected void Session_End(Object sender, EventArgs e)//当前用户退出网站时,在线用户数量-1,
{
Application.Lock();
Application["CurrentGuests"] =(int)Application["CurrentGuests"] - 1;//总在线用户数量-1
Application.UnLock();
}
(2) WebForm1.aspx
private void Page_Load(object sender, System.EventArgs e)
{
this.Label1.Text = "正在访问站点的用户数:" + Application["CurrentGuests"].ToString();
this.Label2.Text ="访问过站点的总用户数:" + Application["AllGuests"].ToString();
}
②.Session对象
Session用于保存每个用户的专用信息.每个客户端用户访问时,服务器都为每个用户分配一个唯一的会话ID(Session ID) . 她的生存期是用户持续请求时间再加上一段时间(一般是20分钟左右).Session中的信息保存在Web服务器内容中,保存的数据量可大可小.当Session超时或被关闭时将自动释放保存的数据信息.由于用户停止使用应用程序后它仍然在内存中保持一段时间,因此使用Session对象使保存用户数据的方法效率很低.对于小量的数据,使用Session对象保存还是一个不错的选择.使用Session对象保存信息的代码如下:
//存放信息
Session["key"]="value"
//读取数据
string UserName=Session["key"].ToString();
③.Cookie对象
Cookie用于保存客户浏览器请求服务器页面的请求信息,程序员也可以用它存放非敏感性的用户信息,信息保存的时间可以根据需要设置.如果没有设置Cookie失效日期,它们仅保存到关闭浏览器程序为止.如果将Cookie对象的Expires属性设置为Minvalue,则表示Cookie永远不会过期.Cookie存储的数据量很受限制,大多数浏览器支持最大容量为4K,因此不要用来保存数据集及其他大量数据.由于并非所有的浏览器都支持Cookie,并且数据信息是以明文文本的形式保存在客户端的计算机中,因此最好不要保存敏感的,未加密的数据,否则会影响网站的安全性.使用Cookie对象保存的代码如下:
//存放信息
Response.Cookies["key"].Value="value";
//读取信息
string UserID=Response.Cookies["key"].Value;
④.ViewState对象
ViewState 常用于保存单个用户的状态信息,有效期等于页面的生存期。跟隐藏控件相似。viewstate是在本页面之内各函数间进行传值的 , 至于为什么要使用这种方法是因为在一个事件发生之后 , 页面可能会刷新 , 如果定义全局变量会被清零 , 所以要使用viewstate. ViewState容器可以保持大量的数据,但是必须谨慎使用,因为过多使用会影响应用程序的性能。所有Web服务器控件都使用ViewState在页面回发期音保存自己的状态信息。如果某个控件不需要在回发期间保存状态信息,最好关闭该对象的ViewState,避免不必要的资源浪费。通过给@Page指令添加“EnableViewState=false”属性可以禁止整个页面的ViewState。使用ViewState对象保存信息的代码如下。
//存放信息
ViewState["key"]="value";
//读取信息
string NameID=ViewState["nameID"].ToString();
⑤.Cache对象
Cache对象用于在HTTP请求间保存页面或数据。该对象的使用可以极大地提高整个应用程序的效率。常用于将频繁访问的大量服务器资源存储在内存中,当用户发出相同的请求后服务器不再次处理而是将Cache中保存的信息返回给用户,节省了服务器处理请求的时间。其生存期依赖于该应用程序的生存期。当重新启动应用程序时,将重新创建其Cache对象的实例。使用Cache对象保存信息的代码如下。
//存放信息
Cache["nameID"]="0001";
//存放信息
Cache.Insert("nameID","0001"1);
//读取信息
string NameID=Cache["nameID"].ToString();
⑥.隐藏域
Hidden控件是属于HTML类型的服务器控件,使用此控件可以实现隐藏域的功能。其实此控件和其它服务器控件的使用没有太大区别,只是它不会在用户端的浏览器中显示,始终处于隐藏状态。但是每次页面提交的时候,此控件和其它服务器控件一同提交到服务器端,因此在服务器端可以使用Value属性获取或保存一些数据信息。使用Hidden控件保存信息的代码如下。
//存放信息
Hidden.Value="0001";
//获取信息
string NameID=Hidden.Value;
⑦.查询字符串
查询字符串的方式是将要传递的值连接在URL后面,然后通过Response.Redirect方法实现客户端的重定向。这种方式可以实现在两个页面之间传递信息。由于URL的长度有一定的限制,因此不能传递太大的信息,加外安全性也不是很好。
传递信息如下。问号后面格式 key1=value1&key2=value2
Response.Redirect("List.aspx?nameID=0001&gradeID=002");
//执行上面的语句后在IE地址栏显示的URL的代码如下。
http://localhost/List.aspx?nameID=0001&grade=002
//当跳转到List.aspx后,可以通过以下代码获得所传递的信息。
string NameID.GradeID;
8.ajax原理
简述: Ajax的原理就是:通过javascript的方式,将前台数据通过xmlhttp对象传递到后台,后台在接收到请求后,将需要的结果,再传回到前台,这样就可以实现不需要页面的回发,页是数据实现来回传递,从页实现无刷新。
Ajax的原理简单来说,实际上就是通过XmlHttpRequest对象来向服务器发异步请求,从服务器获得数据,然后用javascript来操作DOM而更新页面。
这其中最关键的一步就是从服务器获得请求数据。要清楚这个过程和原理,我们必须对 XMLHttpRequest有所了解。
总结:我们可以看出,XMLHttpRequest对象完全用来向服务器发出一个请求的,它的作用也局限于此,但它的作用是整个ajax实现的关键,我们可以把服务器端看成一个数据接口,它返回的是一个纯文本流,当然,这个文本流可以是XML格式,可以是Html,可以是Javascript代码,也可以只是一个字符串。这时候,XMLHttpRequest向服务器端请求这个页面,服务器端将文本的结果写入页面,这和普通的web开发流程是一样的,不同的是,客户端在异步获取这个结果后,不是直接显示在页面,而是先由javascript来处理,然后再显示在页面。
9.请叙述属性与索引器的区别
属性 | 索引器 |
---|---|
通过名称标识 | 通过签名标识 |
通过简单名称或成员访问来访问 | 通过元素访问来访问 |
可以为静态成员或实例成员 | 必须为实例成员 |
属性的get访问器没有参数 | 索引器的get访问器具有与索引器相同的形参表 |
属性的set访问器包含隐式value参数器 | 除了value参数外,索引的 set 访问器还具有与索引器相同的形参表 |
10.String类与StringBuilder类有什么区别?为啥在.Net类库中要同时存在这2个类?
如果要操作一个不断增长的字符串,尽量不用String类,改用StringBuilder类
String类原理:String类是一种传统的修改字符串的方式,它确实可以完成把一个字符串添加到另一个字符串上的工作没错,但是在.NET框架下,这个操作实在是划不来。因为系统先是把两个字符串写入内存,接着删除原来的String对象,然后创建一个String对象,并读取内存中的数据赋给该对象。这一来二去的,耗了不少时间。
StringBulider原理:而使用 System.Text命名空间下面的StringBuilder类就不是这样了,它提供的Append方法,能够在已有对象的原地进行字符串的修改,简单而且直接。
提醒:一般情况下觉察不到这二者效率的差异,但如果你要对某个字符串进行大量的添加操作,那么StringBuilder类所耗费的时间和 String类简直不是一个数量级的
11.浅谈C#中的枚举
枚举类型是一种的值类型,它用于声明一组命名的常数。
①.枚举的声明:枚举声明用于声明新的枚举类型。
访问修辞符 enum 枚举名:基础类型
{
枚举成员
}
基础类型必须能够表示该枚举中定义的所有枚举数值。枚举声明可以显式地声明 byte、sbyte、short、ushort、int、uint、long 或 ulong 类型作为对应的基础类型。没有显式地声明基础类型的枚举声明意味着所对应的基础类型是 int。
②.枚举成员
枚举成员是该枚举类型的命名常数。任意两个枚举成员不能具有相同的名称。每个枚举成员均具有相关联的常数值。此值的类型就是枚举的基础类型。每个枚举成员的常数值必须在该枚举的基础类型的范围之内。
public enum TimeofDay:uint
{
Morning=-3,
Afternoon=-2,
Evening=-1
}
产生编译时错误,原因是常数值 -1、-2 和 –3 不在基础整型 uint 的范围内。
③.枚举成员默认值
在枚举类型中声明的第一个枚举成员它的默值为零。
以后的枚举成员值是将前一个枚举成员(按照文本顺序)的值加 1 得到的。这样增加后的值必须在该基础类型可表示的值的范围内;否则,会出现编译时错误。
示例:
public enum TimeofDay:uint
{
Morning,
Afternoon,
Evening
}
Morning的值为0,Afternoon的值为1,Evening的值为2。
④.为枚举成员显示赋值
允许多个枚举成员有相同的值。没有显示赋值的枚举成员的值,总是前一个枚举成员的值+1
public enum Number
{
a=1,
b,
c=1,
d
}
b的值为2,d的值为2.
注意:以上枚举值都不能超过它的基础类型范围。否则会报错.
⑤.枚举类型与基础类型的转换
基础类型不能隐式转换为枚举类型; 枚举类型也不能隐式转换为基础类型
public enum Number
{
a,
b,
c,
d
}
class Test
{
public static void Main()
{
int i=Number.a;//错误,要强制类型转换(int)Number.a
Number n;
n=2 //错误,要强制类型转换(Number)2
}
}
⑥.System.Enum类型
- System.Enum 类型是所有枚举类型的抽象基类,并且从 System.Enum 继承的成员在任何枚举类型中都可用。
- System.Enum 本身不是枚举类型。相反,它是一个类类型,所有枚举类型都是从它派生的。
- System.Enum 从类型 System.ValueType派生
⑦.使用枚举类型
using System;
public enum TimeofDay
{
Morning,
Afternoon,
Evening
}
class Test
{
static void WriteGreeting(TimeofDay timeofDay)
{
switch(timeofDay)
{
case TimeofDay.Morning:
Console.WriteLine("good morning");
break;
case TimeofDay.Afternoon:
Console.WriteLine("good afternoon");
break;
case TimeofDay.Evening:
Console.WriteLine("good evening");
break;
}
}
static void Main()
{
WriteGreeting(TimeofDay.Morning);
WriteGreeting(TimeofDay.Evening);
WriteGreeting(TimeofDay.Afternoon);
}
}
12.C#的New关键字的几种用法
①.new运算符:用于创建对象和调用构造函数。
- 用于创建对象和调用构造函数 例:Class_Test MyClass=new Class_Test();
- 也用于为值类型调用默认的构造函数
例:int myInt=new int();
myInt初始化为0,它是int类型的默认值。该语句的效果等同于:intmyInt=0;
- 不能重载new运算符;
- 如果new运算符分配内存失败,则它将引发OutOfMemoryException异常。
②.new修饰符
使用new修饰符显式隐藏从基类继承的成员。若要隐藏继承的成员,请使用相同名称在派生类中声明该成员,并用new修饰符修饰它。
请看下面的类:
public class MyClass
{
public int x;
public void Invoke(){}
}
在派生类中用Invoke名称声明成员会隐藏基类中的Invoke方法,即:
public class MyDerivedC:MyClass
{
new public void Invoke(){}
}
但是,因为字段x不是通过类似名隐藏的,所以不会影响该字段。
通过继承隐藏名称采用下列形式之一:
1.引入类或结构中的常数、指定、属性或类型隐藏具有相同名称的所有基类成员。
2.引入类或结构中的方法隐藏基类中具有相同名称的属性、字段和类型。同时也隐藏具有相同签名的所有基类方法。
3.引入类或结构中的索引器将隐藏具有相同名称的所有基类索引器。
4.在同一成员上同时使用new和override是错误的。
注意:在不隐藏继承成员的声明中使用new修饰符将生成警告。
示例:在该例中,嵌套类MyClass隐藏了基类中具有相同名称的类。该例不仅说明了如何使用完全限定名访问隐藏类成员,同时也说明了如何使用new修饰符消除警告消息。
using System;
public class MyBaseC
{
public class MyClass
{
public int x=200;
public int y;
}
}
public class MyDerivedC:MyBaseC
{
new public class MyClass //nestedtypehidingthebasetypemembers
{
public int x=100;
public int y;
public int z;
}
public static void Main()
{
//Creating object from the overlapping class:
MyClass S1=new MyClass();
//Creating object from the hidden class:
MyBaseC.MyClass S2=new MyBaseC.MyClass();
Console.WriteLine(S1.x);
Console.WriteLine(S2.x);
}
输出:
100
200
③.new约束:用于在泛型声明中约束可能用作类型参数的参数的类型。
基础题:
1.简述List与string[]的区别。
2.简述装箱和拆箱操作中的性能损耗是如何产生的。
3.简述对ASP.NET中的事件机制的理解。
4.在一个ASP.NET的三层结构系统中,以登录操作为例,简述在各层中如何组织代码。
5.简述相比DATASET,实体类在WEB项目中的优点与缺点。
6.简述GC是如何工作的。
7.简述3个熟悉的设计模式。
8.简述UDP协议特点,以及如何提高UDP传输可靠性。
9.简述.NET2.0,.NET3.0,.NET3.5各版本中推出的新特性。
算法题:(以下三题不用作答,想好思路面试谈即可)
1. 一个整数数列,元素取值可能是0~65535中的任意一个数,相同数值不会重复出现。0是例外,可以反复出现。
请设计一个算法,当你从该数列中随意选取5个数值,判断这5个数值是否连续相邻。
注意:
- 5个数值允许是乱序的。比如: 8 7 5 0 6
- 0可以通配任意数值。比如:8 7 5 0 6 中的0可以通配成9或者4
- 0可以多次出现。
- 复杂度如果是O(n2)则不得分。
2. 设计一个在一百万个数字中求十个最大的数算法
3. 有如下输入:若干个由大写英文字母构成的单词,以’,’号隔开。如“ABCCD,CDA,BCDD,DCA,ADC,BCD,CDCAB”。 写一段程序,从输入中寻找由相同字符构成(重复字符出现次数也是一样)的单词组输出。
如以上输入,则输出:
第1组:ABCCD,CDCAB
第2组:CDA,DCA,ADC
项目&管理:(以下两题不用作答,想好思路面试谈即可)
1.假设你做为一个开发团队的领导者,经过长时间的磨合,有了一只10人左右的不错的团队。其中每个成员都在其职位上有不可或缺的作用。现由于一些原因,需要你辞退其中一人。你会如何处理这件事情?
2.有一套公司自己开发供本公司使用的CRM系统,其中的权限控制过于简单。现需要你重新设计其权限系统,你会如何开展这个工作?
非技术(面谈):
1.在上份工作中,自己体现最大的优点和缺点是什么。
1、学校几本(是否统招)、英语等级、大学成绩排名Top%几、当前月薪(入职前是否能提供薪资证明材料)、期望月薪
二本,统招
英语四级
排名top10
2、做过的项目技术栈是什么?(例如 .NET、Sql Server、Dapper、EF、Redis……)
.NET、C#、EF、MVC、SQL Server、Oracle、WebService、API、SDK、Redis、JPush、Lucene.Net
Html、css、JavaScript、Ajax、Jquery、AngularJS、Bootstrap
iOS、Objective-C、Winforms、WPF
3、做过的项目中最大的表数据量大概多少?业务高峰期每分钟并发请求数量大概多少?遇到的最大技术难点与解决方案,研究过的.NET开源项目,举例说明3-5个
最大的表有200万条数据,数据查询出现慢的情况,优化方案:在条件语句的列上加索引;优化SQL避免like,in、not in等;使用分页临时表避免全表扫描;
高峰期每分钟并发请求2千左右;
技术难点:团队创立初期,APP刚刚上线,功能在逐步完善。当时为了推广拉新,想开发一个功能,实现APP的在微信里的传播分享。网站享用的是微信开放平台的网站应用号授权,还有另一块是微信公众平台公众号分享,分别是不同的两套APPID,授权之后会获取到两个不同的OpenID,希望用户信息打通,用户只要授权过一次之后就能在另一个模块实现免登陆。由于当时一心想通过业务存储两个不同的OpenID的关联关系,做到统一,结果走了不少弯路,仍然达不到想要的效果。
解决方案:UnionID,将两个账号在后台关联之后就能获取到统一的UnionID,业务记录此ID即可。
开源项目
Json.net Json序列化和反序列化,基本支持所有的json特性,性能也很好,MVC4的默认引用程序集中已包含.
Log4net 传统的日志框架,移植于log4jV1.2,高效,稳定
Html Agility Pack Html解析库
DotNetZip 创建,压缩,解压Zip文件
DotNetCodes 一些常用的功能性代码Utilities,可以减少许多开发时间,而且类与类之间没有什么依赖,每个类都可以单独拿出来使用,excel导出、二维码生成、网络请求等;
4、.NET系统如何实现水平扩展、如何解决高并发问题,解决方案思路
应用服务和数据服务分离:把网站分为应用服务器、文件服务器和数据库服务器,不同服务器承担不同角色,从而提成网站处理能力和文件存储能力;
数据库读写分离:通过配置主从服务器实现数据库读写分离,改善数据库负载压力;
业务拆分:根据产品线拆分,例如订单、商铺、买家等,分归不同业务团队管理,不同业务分不同物理服务器处理,可以通过消息队列进行数据分发;
使用NoSQL和搜索引擎:应用服务器通过统一模块访问各种数据,减轻应用程序管理数据源的麻烦;
应用服务器集群:通过负载均衡使一批设备共同对外提供服务,由统一调度服务器通过调度策略进行分发,当有服务器宕机时,调度服务器会将请求转移到其他服务器上,保证不影响用户使用;
分布式文件系统和分布式数据库系统:将业务拆分成不同模块,不同业务的数据库放在不同的物理服务器上;
缓存:包括本地缓存、分布式缓存、反向代理和CDN加速;
使用缓存改善网站性能:把业务经常访问的数据缓存到内存中,可以大大减少数据库的读取访问压力,从而改善写入性能,方式有本地缓存和分布式服务器缓存,部署大内存服务器;
反向代理和CDN加速:基本原理都是缓存,用户请求服务时,通过距离判断最近机房代理服务器中缓存这用户请求的资源,直接返回给用户,减轻后端服务器负载压力;
异步操作:典型的生产者消费者模式,两者不存在直接调用,只要保持数据结构不便,彼此功能实现可以随意变化而不互相影响;
固态硬盘代替机械硬盘:使用SSD,物理设备上加快文件访问速度;
5、国内外基于.NET技术的知名网站有哪些,.NET与Java相比有哪些优点、缺点,如何看待微软全新一代.NET Core开源、免费、跨平台的未来发展前景
.NET知名网站
国外:microsoft、stackoverflow、codeproject、myspace、Godaddy、msn、
国内:cnblogs、csdn、智联、携程、必应、起点、凡客
.NET和java对比
开源和跨平台,Java一直开源跨平台,有非常丰富的社区资源;微软14年也宣布开源跨平台,有.NET Core、xamarin,微软正在努力,但做到Java现在的程度个人觉得还有很长一段路要走。
编程工具,C#有好用的IDE Visual Studio;Java以前有eclipse,现在有Intellij。
语言特性,两者语法类似,C#feature更多(语言特性,泛型、委托、重载运算符、LINQ、lambda、delegate、扩展等),语法糖也更多,程序员基本可以专注逻辑而不用关注如何实现;而Java这块比较贫乏。
更新速度,C#由微软维护,版本更新快,支持更多新特性;java版本更新慢。
应用领域,C#目前主要应用在windows的PC应用,unitity3D,web。Java应用于web,Android,Hadoop等。
生态环境,个人认为最重要的一点。开源库和框架Java数不胜数,各种层面的解决方案眼花缭乱,C# web比较好用的框架只有asp .net、MVC。
.NET Core未来发展前景
个人看好 .Net Core 的未来发展前景。
.NET Core是一个开源通用的开发框架,支持跨平台,即支持在Window,macOS,Linux等系统上的开发和部署,并且可以在硬件设备,云服务,和嵌入式/物联网方案中进行使用。首先从Core的定位上来说,他摒弃了原有AspNet的那些臃肿组件,面向高性能服务器开发。虽然现在版本功能还比较弱,各类三方库支持也没有更新,但是这只是时间问题,以微软的更新速度和推广力度,几年后必将完善。
基于微软的 Azure 云的平台优势,后期势必会加入 .Net Core 的支持,加上微软的跨平台战略,对 Docker 的亲和性,对于开发人员也非常友好,所以整体环境来说是健康发展的,未来技术决策时 .Net Core 也有很大的优势。
因此未来其发展主要看的就是微软推广力度及社区开发者的支持度。
喜欢C#就会一直坚持下去,因为兴趣是最好的老师。
6、www.dot.net官网任选一篇英文技术文章,不用单词软件大概能看懂百分之多少?
看了一篇教学文章
https://www.microsoft.com/net/tutorials/csharp/getting-started/hello-world
全部英文文档大概能看懂百分之80
7、我们会根据以上信息进行岗位匹配度的评估(教育背景、技术能力、抽象总结能力……),节省应聘者的面试成本,提升招聘效率
8、为了方便及时沟通,请加技术经理微信 2531685528 注明:应聘.NET 姓名
-------------------------------------------------------
【.NET技术面试参考资料、图书】
1、《大型网站技术架构》
2、《Sql Server性能优化与管理的艺术》
3、《跟阿铭学Linux》
4、《深入浅出MySQL数据库开发优化与管理维护》
5、《微服务设计》
参考资料共享地址
http://pan.baidu.com/s/1nvUc1nz
http://www.apelearn.com/study_v2/