面试题

CLR:Common Language Runtime 公共语言运行时?
这是一个运行环境,程序在vs运行起来以后,它会完成:创建一个进程,分配内存,即时编译,垃圾回收等任务。
CTS,公共系统类型      CLS,公共语言规范
即时编译JIT?
就是CLR将中间语言翻译成计算机可以直接执行的机器代码(0 1 0 1……)
中间语言?
就是程序使用VS编译器编译后生成的代码。

.NET平台就是先使用各种编译器将各种语言编译成IL中间语言,然后再执行时使用JIT即时编译将中间代码编译成机器代码。
托管代码?非托管代码?
由CLR(公共语言运行时)环境执行的代码就是托管代码。

对象怎么回收?
托管资源的话,.net提供了GC垃圾回收机制,当每次使用new关键字创建一个对象时,运行库都要从托管堆中为其分配内存,当对象出了其作用域时,GC会自动回收。非托管资源的话,需要手动去调用Dispose方法来释放,比如Stream流对象、DBConnection对象,也可以使用Using来进行内存资源的分配和释放。
GC原理?
通过最基本的标记清除原理,清除不可达对象;再像磁盘碎片整理一样压缩、整理可用内存;最后通过分代算法实现性能最优化。
首先要进行垃圾判定,就是判断什么是垃圾,如果一个变量在其生存周期内不再被引用,那么就可以标为垃圾。但如果是有终结器的对象,则要经过两次判断回收,才能释放。标定垃圾以后,在加锁保证线程安全的情况下,调用Dispose方法删除对象,释放内存。
Finalize?
Finalize是终结器,实现了Finalize方法的对象在释放时需要调用两次GC垃圾回收才能释放。

内存泄露?
.net中有自动回收机制,一般情况下不会发生,但使用不当时会发生。
常见的一种情况就是:当拥有长生命周期的对象持有短生命周期对象的引用时,尽管短生命周期对象已经不再使用,但因为被引用不能回收,导致内存泄露。比如静态事件,这种static的东西生命周期很长,绑定之后需要手动注销事件,否则就泄露了。
关于ShowDialog为什么泄露,还不知道
 Memory Profiler 工具查找原因
使用弱引用方法
内存溢出?
内存泄露  还有 计算机内存大小 举例上次延大遇到的问题 对数据更新时,由于数据量太大,选择只传给服务器dataset.GetChange(),即发生变化的这部分数据。
当一个查询语句查询出来的数据量很大,达到几百万条数据时存放到datatable 或dataset中也会造成内存溢出,这是可以采用分页查询等其他方法来解决
索引器?
索引器也是一种类的成员,它能够让对象以类似数组的方式来存取。索引器的参数个数和类型都是任意的,但索引器没有名字。索引器的本质是get和set访问器。
[修饰符] 数据类型 this[索引类型 index]  
{  
    get{//获得属性的代码}                                                   
    set{ //设置属性的代码}  
} 
例子:
public long this[int index]  
{  
   get 
   {   
     if (index < 0 || index >= 100) return 0;  
     else  ..... 
   }  
   set 
   {  
     if (!(index < 0 || index >= 100))  ...;  
   } 
} 
接口中的索引器:接口索引器不使用修饰符;接口索引器只包含访问器get或set,没有实现语句。
using?
(1)用于引入命名空间
(2)using别名。using + 别名 = 包括详细命名空间信息的具体的类型。
(3)用于对非托管资源管理,相当于try catch finaly 最后调用dispose方法。常见的有StreamReader。
  using (StreamReader sr = newStreamReader(@"c:\test.txt"))
  {
     string s = null;
    while ((s=sr.ReadLine()) != null)
     {
      Console.WriteLine(s);
    }
  }
泛型?

使用泛型的好处:
可以避免强制类型转换:
减少装箱拆箱操作的损耗;
提高代码重用性:
例如定义一个两个数相加的方法,要实现int和double类型的相加,如果使用普通方法的话需要写两个重载的方法,而如果使用泛型只要写一个方法。

扩展方法?
其实扩展方法就是对于程序集中的某个类A需要添加方法,而这个类A又是sealed,不能继承。这时候在一个静态类B中定义一个静态方法,将类Adequate实例作为参数传给这个方法,这时候就可以看成这个方法就是类A的方法,调用时使用A的实例去调用。
工厂模式?
工厂模式类似面向对象的多态性,定义一个用户创建对象的基类,多个派生类,在使用时,工厂会根据你传入的参数决定调用某一个派生类,而你不用关心调用的是哪个,这些派生类都有相同的方法,只是实现不同而已。
Socket?
同步Socket工作过程大致:
客户端:创建Socket对象(传入端口号和ip)→调用connect(),发送服务器连接请求→ 如果连接成功,调用Send(),Receive()接收发送消息→ 通信结束关闭Socket,Socket.Close()
服务器:创建Socket对象→ 调用Bind()方法绑定ip和端口号→ 调用Listen()方法开始监听→ 监听到连接请求时,调用Accept()方法来创建新的socket对象用于和请求的客户端进行通信→ 调用Send(),Receive()接收发送消息→ 通信结束,关闭Socket对象
以上是tcp,udp时就不需要发送连接请求,不需要Accept来接受连接,而是指定对方的地址后直接调用SendTo和ReceiveFrom来传输。
异步???
同步:客户端发送请求后必须等到服务器回应之后才发送下一条请求;
异步:客户端发送请求后不等到服务器回应就可以发送下一条。
阻塞:Socket调用函数时,在返回结果之前,当前线程被挂起,此Socket一直被阻塞在函数调用上。
非阻塞:调用函数即使得不到返回结果也立即返回。
阻塞与同步的区别在于线程是否挂起

粘包?半包?
粘包就是发送端发送的好几包的数据,到接收端粘成一包了。半包就是发送的一包数据只接收到了半包。
粘包只发送在tcp中,udp不会发生。因为tcp采用流的方式来处理数据,而udp接收端使用链式结构来存储udp包,在每个udp包中就已经有了消息头了,所以消息是有消息边界的,不会粘包。
粘包原因:
发送端需要等缓冲区满才发送出去,造成粘包
接收方不及时接收缓冲区的包,造成多个包一起接收
解决办法:
设置发送端及时发送数据,不等发送缓冲区慢就发送
制定应用层的数据通讯协议,也就是封包,加包头,包长度信息等
在接收端设一个比较大的缓冲区,先将收到的数据包都放到缓冲区中,然后从该缓冲区中选取完整的数据包处理。


ADO.net常用的对象有哪些?描述作用,使用方法,先决条件,注意点
Connection,建立数据库连接,有open,close和dispose方法。close以后还可以open,dispose以后就释放了不能再用了;
Command,执行数据库操作指令,包括增删改查以及调存储。
DataAdapter,数据适配器,通常与DataSet或DataTable一起使用,get数据库中的数据,Fill(填充)DataSet、DataTable容器,是数据库与DataSet之间传输数据的桥梁。
DataSet,ADO.NET中的核心对象,是一个不依赖于数据库的独立数据集合,本身不具备与数据源沟通的能力,只是一个存储容器,可以存储多个Table,还可以存储DataAdapter获取的主键、字段类型等数据表结构。
DataReader,当我们需要循环读取数据而不需要其他操作时,可以使用DataReader,每次从数据源只读取一条数据。
ADO.NET使用Connection对象连接数据库,使用Command或DataAdapter对象来执行sql语句,并将执行的结果返回给DataReader或DataAdapter,然后再使用取得的DataReader或DataSet对象来进一步操作数据。
DataSet和DataReader区别?
DataSet是面向非连接的,将数据一次性加载到内存中,抛弃数据库连接;而DataReader是面向连接的,使用时占用Connection,在线操作数据库,每次只单向读取一条数据,数据是存在数据库服务器中的。
DataReader是单向只读的,在对DataReader中的数据进行更新后,没有办法对数据库也进行更新,而DataSet比较灵活,可以动态修改数据,并回传更新到数据库。
DataReader占用内存小,节约客户端资源,处理速度快。(数据存在服务器上,且只读)
一个DataTable,从中筛选符合条件的数据,有哪几种方法?
DataView.RowFilter 
dataTable.Select 
dt.AsEnumerable().where()

什么叫做SQL注入,如何防止?请举例说明。
SQL注入是常见的利用程序漏洞进行攻击的方法。导致sql注入攻击并非系统造成的,主要是程序中忽略了安全因素,利用sql语言漏洞获得合法身份登陆系统   例如:  "Select * from users where name='"+uName+"' and pwd='"+uPwd+"' " 
如用户在t_name中输入tom’ or 1=‘1 就可以进入系统了。  生成语句:  Select * from users where name = ‘tom’ or 1=‘1’ and pwd=‘123’
防止sql注入的方法有如下几点:  
使用参数化过滤语句   要防御SQL注入,用户的输入就绝对不能直接被嵌入到SQL语句中。恰恰相反,用户的输入必须进行过滤,或者使用参数化的语句。参数化的语句使用参数而不是将用户输入嵌入到语句中。在多数情况中,SQL语句就得以修正。然后,用户输入就被限于一个参数。
将用户登录名称、密码等数据加密保存。
存储过程来执行所有的查询 在web应用程序的开发过程中所有阶段实施代码安全检察使用存储过程
 
对数据的并发采用什么办法进行处理较好?ADO.NET处理数据并发的方法和步骤?
并发就是同时发生。当多个用户同时访问一个页面或者操作一个表时发生。举个例子,一个人在修改数据的数据,恰巧这条数据背另一个人删除~~这种同时进行的状况就叫并发,这样一边在改,一边已经删了,数据就出错了。并发的情况一般出现在访问量很大的时候,或者是修改比较频繁之类的。控制的话需要在程序中实现,一般用线程安全来控制,不过线程安全的负面影响就是效率比较低了

处理数据并发通常要建立“并发控制”机制:
并发控制有三种类型:
开放式并发控制:适用于并发冲突偶尔发生,当更新数据时,锁定该行对其他用户不可用。所以在更新前要检查这行确定是否别的用户进行了更改,如果已更改了,则提示别的用户已修改了这条记录,他所做的更改不能保存。检查的方法有版本号或日期戳对比;DataSet所有值对比。
保守式并发控制:适用于并发经常发生,用户不能容忍被告知不能保存。从用户获取记录直到记录更新这段时间内,都使用数据库锁,锁定该行记录对别的用户不可用,直到他完成修改并提交,才释放锁。在断开连接的数据结构中无法使用,连接打开的时间只够读取数据或更新数据,因此不能长时间地保持锁。
最后的更新生效:这种方式其实就是什么也不做,不去与上次的记录作比较,只是更新覆盖,这样就导致最后的更新生效。确保可以接受用户B在修改数据时,用户A已修改了数据,用户B直接覆盖了A的修改,可以接受这种情况就可以使用。
因为数据结构基于断开的数据,所以 ADO.NET 和 Visual Studio 使用开放式并发。因此,您需要添加业务逻辑,以利用开放式并发解决问题。使用开放式并发,则可以通过两种常规的方式来确定是否已发生更改:版本方法(实际版本号或日期时间戳)和保存所有值方法。
版本号方法
在版本号方法中,要更新的记录必须具有一个包含日期时间戳或版本号的列。当读取该记录时,日期时间戳或版本号将保存在客户端。然后,在更新时,使用日期戳或版本号进行对比,如果日期时间戳或版本号匹配,则表明数据存储区中的记录未被更改,并且可以安全地使用数据集中的新值对该记录进行更新。如果不匹配,则将返回错误提示。为了确保日期时间戳或版本号的准确性,您需要在表上设置触发器,以便在发生对行的更改时,对日期时间戳或版本号进行更新。
保存所有值方法
ADO.NET 中的 DataSet 对象维护每个修改记录的两个版本:初始版本(最初从数据源中读取的版本)和修改版本(表示用户更新)。当试图将记录写回数据源时,数据行中的初始值将与数据源中的记录进行比较。如果它们匹配,则表明数据库记录在被读取后尚未经过更改。在这种情况下,数据集中已更改的值将成功地写入数据库。
多线程并发时怎么处理?
 线程并发,就是多个线程访问同一资源, 可能造成不同步的情况,这个叫做线程重入,也就是线程并发。发生在多个线程访问同一个界面,或者是同一个对象的某个静态全局变量时。解决方法:加锁lock,叫互斥锁 。使用lock语句,可以保证共享数据只能同时被一个线程访问。
       private void CountNum()
         {
             lock (this)
             {
                 for (int i = 0; i < 10000; i++)
                 {
                     int num = int.Parse(textBox1.Text.Trim());
                     num++;
                     textBox1.Text = num.ToString();
                 }
             }
         }

多线程?
线程默认情况下都是前台线程。要把所有的前台线程执行完后,程序才会退出。后台线程,只要所有的前台线程结束,所有的后台线程就直接结束。

线程池?
ThreadPool是一个静态类,它没有构造函数,对外提供的函数也全部是静态的。其中有一个QueueUserWorkItem方法,它有两种重载形式,如下:
public static bool QueueUserWorkItem(WaitCallback callBack):将方法排入队列以便执行。此方法在有线程池线程变得可用时执行。
public static bool QueueUserWorkItem(WaitCallback callBack,Object state):将方法排入队列以便执行,并指定包含该方法所用数据的对象。此方法在有线程池线程变得可用时执行。

优点:减少创建和销毁线程的系统开销
经常会面对创建对象和销毁对象的情况,如果不正确处理的话,在短时间内创建大量对象然后执行简单处理之后又要销毁这些刚刚建立的对象,这是一个非常消耗性能的低效行为,所以很多面向对象语言中在内部使用对象池来处理这种情况。
缺点:一旦加入到线程池中就没有办法让它停止,除非任务执行完毕自动停止;在线程池中所有任务的优先级都是一样的,无法设置任务的优先级。

启动一个线程是用run() 还是start()?
启动线程肯定要用start()方法。当用start()开始一个线程后,线程就进入就绪状态。。当cpu分配给它时间时,才开始执行run()方法, run()方法中包含的是线程的主体。
sleep() 和 wait() 有什么区别?
答:sleep()方法是将当前线程挂起指定的时间。
        wait()释放对象上的锁并阻塞当前线程,直到它重新获取该锁。

ASP.NET中的委托和事件机制的理解?

反射?
要给反射下一个定义还是比较难的。反射提供了封装程序集、模块和类型对象,可以用反射动态的创建类型的实例,将类型绑定到现有对象,或者从现有对象类型里获取类型,然后调用类型的方法或访问字段和属性。
序列化?
将对象转换为另一种媒介传输格式的过程。比如,需要使用.net Remoting 在服务器和客户端传递一个对象时,就可以将该对象序列化,然后在接收端反序列化得到对象。

动态获取程序集信息
.net的错误处理机制是什么? 
答.net错误处理机制采用try->catch->finally结构,发生错误时,层层上抛,直到找到匹配的Catch为止。

ASP.NET WebForm页面中传值的方式?
QueryString(也叫URL传值),使用简单,传递的参数会显示在URL中,不安全,而且这种方式不能传递对象。
Session,将数据存储于服务器变量中,安全性比较高,但过量的Session存储会导致服务器内存资源的耗尽,因此谨慎使用。
Server.Transfer与Respose.Redirect,这种方法是简洁的同时又是面向对象的,数据库稳定,安全,但性能相对弱。
Cookie,存储于用户本地的浏览器中,咱们用的自动登录某个网站的功能就是,但浏览器可能不支持,安全性不高,且易被修改。
Application,对象作用范围是整个全局,如果想在整个应用程序范围内使用某个值,可以选择它。
Viewstate,页面级别的,只在当前页面有效。
Server.Transfer与Respose.Redirect区别?
这是两种重定向方式。
前者是服务器内部的转换,浏览器不参与;后者有浏览器参与,在地址栏可以看到地址的变化。
前者是服务器直接访问url请求资源,将返回的内容发给浏览器,浏览器只管显示。后者是服务器发给浏览器一个状态码,命令浏览器去访问url请求资源。
Server.Transfer?
这个方法相比上面介绍的方法稍微复杂一点,但在页面间值传递中却是特别有用的,使用该方
法你可以在另一个页面以对象属性的方式来存取显露的值,当然了,使用这种方法,你需要额
外写一些代码以创建一些属性以便可以在另一个页面访问它,但是,这个方式带来的好处也是
显而易见的。总体来说,使用这种方法是简洁的同时又是面向对象的。使用这种方法的整个过
程如下:
1,在页面里添加必要的控件
2,创建返回值的Get属性过程
3,创建可以返回表单的按钮和链接按钮
4,在按钮单击事件处理程序中调用Server.Transfer方法转移到指定的页面
5,在第二个页面中,我们就可以使用Context.Handler属性来获得前一个页面实例对象的引
用,通过它,就可以使用存取前一个页面的控件的值了
以下代码综合实现上述步骤过程的代码:
源页面代码:
把以下的代码添加到页面中
         public string Name
        {
            get
            {
                return TextBox1.Text;
            }
        } 
        public string EMail
        {
            get
            {
                return TextBox2.Text;
            }
        }
然后调用Server.Transfer方法
        private void Button1_Click(object sender, System.EventArgs e)
        {
            Server.Transfer("anotherwebform.aspx");
        }       
目标页面代码:
        private void Page_Load(object sender, System.EventArgs e)
        {
            WebForm1 wf1; //create instance of source web form
            wf1 = (WebForm1)Context.Handler;//get reference to current handler instance
            Label1.Text = wf1.Name;
            Label2.Text = wf1.EMail;
        }
 Session有什么重大的BUG,微软提出了什么方法加以解决? 
答:是iis中由于有进程回收机制,系统繁忙的话Session会丢失,可以用Sate server或SQL Server数据库的方式存储Session不过这种方式比较慢,而且无法捕获Session的END事件。 
使用URL传参时,怎么传递中文参数?
可以使用urlencode对参数编码,再使用urldecode解码。
AJAX解决什么问题?
AJAX是用来解决无刷新更新页面问题。传统方式,每次都要重绘界面,界面会经历提交→变白→重新显示这样一个过程,用户体验差,。
加载程序集?
Assembly.Load("Doctor");  Assembly.LoadFrom("Doctor.dll");
WebService?

soap协议?
soap:Simple Object Accept Protocol,是以xml为基础编码结构建立在已有通信协议http上的一种规范。 soap=xml+http 
XML?
文件流?

简述string[]与List<string>的区别。
前者是数据,对C#来说数组是一个内置的特殊类型,而后者是泛型集合。
前者是固定长度的,后者是可变长度的,可以根据需要自动扩充、修改、删除或插入数据。
int[]数据的性能优于List<int>,因为List的元素属于Object类型,所以在存储或检查值类型时通常会发生装箱操作。
简述相比DataSet,实体类在WEB项目中的优点与缺点。
实体类是强类型,数据类型是在编译时就确定的,而DataSet是弱类型,如果数据类型不匹配,只有在运行时才会报错;
DataSet中的字段类型默认是Object类型,调用时需要转换类型,而实体类不需要;
实体类是面向逻辑层的,根据业务划分;DataSet是面向数据库层的,和表有密切关系;
实体类编程时可以看出属性有哪些字段,而DataSet必须查询表结构。
缺点:实体类需要在逻辑层去定义。
简述3个熟悉的设计模式。
单例模式 操作文件时,同一时间内只允许一个实例对其操作等
工厂模式  观察者模式 
工厂模式类似面向对象的多态性,定义一个用户创建对象的基类,多个派生类,在使用时,工厂会根据你传入的参数决定调用某一个派生类,而你不用关心调用的是哪个,这些派生类都有相同的方法,只是实现不同而已。
4.在一个ASP.NET的三层结构系统中,以登录操作为例,简述在各层中如何组织代码。

ORM框架有?
1Nhibernate
原因:用的比较多,资料也比较好找。
2 Castle ActiveRecord
原因: 不用配置对象的XML文件,这点比Nhibernate爽
3 EntityFramework
原因:微软的东西(说真的,有点不想用)
4 mybaits.net
原因:我几个搞java的朋友都说他们现在不用hibernate了都在用mybaits 
.net remoting 技术
Castle 框架
orm
WCF
WPF?
NHibernate、Castle、Spring、AOP
MVC
是由Java的Spring架构移植过来的.net版本的Spring架构  MVC就是这个架构的一个运用


基本框架: .net framework
最常用的:三层架构—数据层,逻辑层,表示层
第三方框架:NHibernate,.net Spring
界面框架:Component Art
测试框架: NUnit
就知道这些了。

 写出软件的开发流程 
答:1.需求分析:我们要知道客户想要的是怎样一个系统,要有哪些功能等。 
2.问题定义:主要是要搞清楚,我们要解决什么样的问题 
3.可行性分析:我们要明确所定义的项目是不是能够实现和值得开发,也就是在技术,经济,运行可行性,法律可
行性方面进行分析。 
4.概要设计与结构化设计,这个阶段主要是要分析出,我们要怎样实现系统,软件设计包括概要设计时应该遵循的
基本原理。 
5.详细设计,确定具体怎么样实现所要求的系统 6.编码与软件测试: 7.软件测试与维护。
用过什么报表?
IBM Cognos
在上份工作中,自己体现最大的优点和缺点是什么?
优点:喜欢对代码进行优化  对方案提出质疑
缺点:与领导的沟通较少 喜欢闷头做好自己的事情 有时候领导可能不知道我在做什么
常见技术网站?
CSDN MSDN(微软提供给开发人员的技术帮助文档) 博客园

 

posted on 2017-06-08 10:39  选择大于努力  阅读(365)  评论(0编辑  收藏  举报

导航