.NET面试题(一)
1、请编程遍历页面上所有TextBox控件并给它赋值为string.Empty?
foreach (System.Windows.Forms.Control control in this.Controls)
{
if (control is System.Windows.Forms.TextBox)
{
System.Windows.Forms.TextBox tb = (System.Windows.Forms.TextBox)control;
tb.Text = String.Empty;
}
}
能用foreach遍历访问的对象需要实现 IEnumerable 接口或声明 GetEnumerator 方法的类型。
JS方法遍历:
function BianLi()
{
var t=document.getElementsByTagName("input");
for(var i=0;i<t.length && t[i];++i)
{
if(t[i].type=="text")
{
t[i].value="";
}
}
}
3、值类型,引用类型;
(1)、值类型:
a.值类型变量包含赋予的数据,如:当声明(int)整型变量并赋值时,该变量直接包含赋予的值。将一个值类型变量赋予另一个值类型变量时,则是建立该变量的副本。
int num1,num2;
num1=5;num2=num1;=>num1=5,num2=5;
num2=3; =>num1=5,num2=3;
b.所有的值类型在声明的时候都有默认值。如:
Boolean shang; 默认值为false;
int age;默认值为0;
可以使用default关键字获取值类型的默认值:
object x;
x=default(bool); x=false;
x=default(int); x=0;
c.如果没有明确地初始化变量,C#就禁止使用该变量。为了使用该变量,需要使用某个值对该变量进行初始化。如:
Boolean shang;
Console.WriteLine(shang); 报错
Boolean shang=false;
Console.WriteLine(shang); OK
d..NET Framework 带有一组预先定义的C#和.NET 值类型:bool,byte,sbyte,char,decimal,double,float,int,uint,long,ulong,short,ushort;
(2)、引用类型
对于引用类型,变量存储数据的引用而非实际数据,C#支持两种预定义的引用类型:Object和string;
数组是引用类型,但是数组中的元素可以是任意类型的。
(3)、值类型和引用类型的区别:
a.将一个值类型变量赋给另一个值类型变量时,将复制包含的值。引用类型变量的赋值只复制对对象的引用,而不复制对象本身。
b.值类型不可能派生出新的类型:所有的值类型均隐式派生自 System.ValueType。但与引用类型相同的是,结构也可以实现接口。
c.值类型不可能包含 null 值:然而,可空类型功能允许将 null 赋给值类型。
d.每种值类型均有一个隐式的默认构造函数来初始化该类型的默认值。
4、装箱,拆箱
装箱:从值类型转换为引用类型;
拆箱:从引用类型转换为值类型;
object obj = null;//引用类型
obj = 1;//装箱,boxing。把值类型包装为引用类型。
int i1 = (int)obj;//拆箱。unboxing
5、受管制(托管)的代码
托管代码(safe):使用CLR编译语言编辑器开发编写的代码,由公共语言运行库环境执行的代码;
非托管代码(unsafe):在公共语言运行库环境外部,由操作系统直接执行的代码。
6、CLR,CTS,CLS
CLR:公共语言运行库(Common Language Runtime);
CTS:通用类型系统(Commom Type System);
CLS:通用语言规范(Common Language Specification);
7、应用程序域,程序集
应用程序域:
就是为安全性,可靠性,隔离性,和版本控制,及卸载程序提供的隔离边界。它通常由运行库宿主创建,应用程序域提供了一个更安全,用途更广的处理单元。它由公
共语言运行库围绕同一个应用程序范围内创建的对象建立。应用程序域可以理解为一种轻量级进程。起到安全的作用。占用资源小。
程序集:
在.NET中可部署的基本单元成为程序集。是一个或多个托管模块,以及一些资源文件(EXE文件的过程程序集或DLL文件的库程序集)的逻辑组合。
强命名程序集:
程序集需要经过加密签名,强命名程序集可以部署到全局程序集缓存中,成为公共程序集。
8、Static 和 非Static的区别:
(1)、用Static声明的方法和变量,不需要实例化该类,通过类调用(static表示“静态”或者“全局”,被static修饰的方法或者变量独立于该类的任何对象);
(2)、非Static的,就一定要用实例化的对象来调用,即用new来实例化。
class Program { private static int _numberA = 5;//静态字段 private int _numberB = 3;//非静态字段 static void Main(string[] args) { //静态方法,字段直接通过类来调用(对于Program.Add()或Program._numberB,Program.可以省略); Program p = new Program();//对于非static的方法,字段要通过类的实例化对象来调用; //注意对于调用不同类型方法,不同类型字段的写法 Console.WriteLine(Program.Add(Program._numberA,p._numberB)); Console.WriteLine(Add(Program._numberA, p._numberB)); int sub=p.Subtract(_numberA,p._numberB); Console.WriteLine(sub); Console.ReadKey(); } //静态方法 public static int Add(int a,int b) { return a + b; } //非静态方法 public int Subtract(int a,int b) { return a - b; } }
9、面向对象的思想
继承、封装,多态。
10、接口,抽象类
(1)、接口(命名规范:以大写字母I作为接口名称的开始)
(2)、抽象类
(3)、接口和抽象类的区别:
a.抽象类可以同时包含具体方法(已经的实现的方法)和抽象的方法(每个抽象类中至少有一个抽象方法);接口不包含任何方法的实现,必须由实现该接口的类提供所有的实现;
b.抽象类可以包含构造函数和析构函数;接口不可以。
c.一个类可以实现多个接口,但是只可以从一个抽象类继承。
d.接口中的方法不能有访问修饰符。
11、类和结构的区别
Class可以被实例化,属于引用类型,是分配在内存的堆上的。类是引用传递的。
Struct属于值类型,是分配在内存的栈上的。结构体是复制传递的。如:Int32、Boolean等都属于结构体
12、重载(overload),重写(override),扩展方法(C#3.0新增)
(1)、重载方法:类中包含多个具有相同名称和不同签名(形参)的方法。
(2)、重写:提供了子类中改变父类方法行为的实现(是进行基类中函数的重写)。
13、访问修饰符
private:关键字指示成员在类的外部不可见;
public:关键字指示成员在类的外部可见,并对所有派生类可见(在整个项目中都可见);
protected:关键字指示成员在类的外部不可见,对所有派生类可见;
internal:关键字指示成员在类的外部可见,并对所有的派生类可见;
protected internal:关键字组合指示成员在类的外部可见,并对所有的派生类可见
14、委托和事件
(1)、委托:
a.在C#中,委托是包含方法引用的引用类型。我们可以将委托认为是指向函数的指针。不是直接的调用该函数,而是通过使用委托来指向该函数,然后通过调用委托来调用该方法。
b.使用delegate关键字来定义委托的类型,委托类型的声明类似于函数的声明,但是委托没有函数主体。为了使委托对象指向函数,可以创建委托类型的对象,并且使用希望指向的方法实例化该对象。
未使用委托的代码:
class Program { static void Main(string[] args) { int num1 = 5; int num2 = 3; Console.WriteLine(Add(num1,num2).ToString());//调用Add()方法 Console.WriteLine(Subtract(num1, num2).ToString()); Console.ReadLine(); } static int Add(int num1,int num2) { return (num1+num2); } static int Subtract(int num1, int num2) { return (num1 - num2); } }
使用委托的代码:
class Program { delegate int MethodDelegate(int num1,int num2);// static void Main(string[] args) { int num1 = 5; int num2 = 3; MethodDelegate method = new MethodDelegate(Add);//创建委托的对象,声明mehod为指向Add()方法的委托。此处还不能直接调用Add()方法 //或者 MethodDelegate method=Add; //使用Method委托调用调用Add()方法 Console.WriteLine(method(num1,num2).ToString());//调用Add()方法 Console.ReadLine(); } static int Add(int num1,int num2) { return (num1+num2); } static int Subtract(int num1, int num2) { return (num1 - num2); } }
c.委托的优点就在于可以使用委托来调用它所指向的任何函数,并且在调用之前都不需要确切的了解它所调用的函数,委托可以指向任何函数(前提是该函数的签名必须和委托的签名相匹配)。使用委托可以帮助改善应用程序的响应灵敏性。
char Operation='A';
MehtodDelegate method=null;
switch (Operation)
{
case 'A': method=new MehtodDelegate(Add);
break;
case 'B': method=new MehtodDelegate(Subtract);
break;
}
if(method!=null)
Console.WriteLine(method(num1,num2).ToString());
d.委托也可以作为形参传递给方法。
e.委托链接。
(2)、事件:(是一种特殊的委托)
在.NET中,使用委托来实现事件。具有事件的对象称为”发布者“,处理事件的对象称为”订阅者“。当对象提供事件时,它会定义一个委托,希望处理该事件的对象必须为这个委托提供函数。该委托称为事件。处理该委托的函数称为事件处理程序。
(3)、事件和委托的区别:
事件不可以使用=运算符将委托直接赋给事件,而是必须使用+=运算符。
15、泛型
16、线程和进程
17、栈和堆
栈是编译期间就分配好的内存空间,因此你的代码中必须就栈的大小有明确的定义;局部值类型变量、值类型参数等都在栈内存中。
堆是程序运行期间动态分配的内存空间,你可以根据程序的运行情况确定要分配的堆内存的大小
18、对象的序列化和反序列化
19、WebService的调用方法
(1)、使用WSDL.exe命令行工具。
(2)、使用VS.NET中的Add Web Reference菜单选项。
20、net Remoting 的工作原理:
服务器端向客户端发送一个进程编号,一个程序域编号,以确定对象的位置
21、简要谈一下您对微软.NET 构架下remoting和webservice两项技术的理解以及实际中的应用。
答:WS主要是可利用HTTP,穿透防火墙。而Remoting可以利用TCP/IP,二进制传送提高效率。
22、用户控件
23、关键字:
(1)、this关键字
用于引用类的当前实例,也包括继承而来的方法,通常可以隐藏this:
a.显得被相似的名称隐藏的成员;
b.将对象作为参数传递到其它方法;
c.声明索引器;
(2)、base
用于从派生类中访问基类的成员(例如特性和变量),也可以使用base关键字范围来自基类的方法,功能:
a.调用基类上已被其他方法重写的方法;
b.制定创建派生类实例时应调用的基类构造函数。
(3)、new
a.实例化如:New Class() ,对象必须使用New关键字来分配内存。
b.public new 隐藏基类的方法
c.在泛型类申明中的任何类型参数都必须有公共的无参构造函数。
(4)、using
在C#中,使用using关键字自动调用Dispose()方法,如:conn对象只在using块中有效,并且在该块执行之后自动释放。
using System.Data.SqlClient;
...
using (SqlConnection conn=new SqlConnection())
{
conn.ConnectionString="...";
...
}
使用using关键字是为了确保执行如下操作的优秀方法:当不再需要某些资源(特别是COM对象和非托管代码,CLR中国的垃圾收集器不会自动卸载这些资源)时适当地释放这些资源。
(5)、参数修饰符 ref,out,params关键字
如果一个参数没有参数修饰符,则认为该参数是按值传递,也就是说被调用的方法所接收的数据是原始数据的一个副本。
ref:
调用者赋初值,并且可由被调用的方法可选地重新给参数赋值,参数是按引用传递的。如果被调用的方法没有给输出参数赋值,则不会出现编译错误。
out:
输出参数由被调用的方法赋值,按照引用传递,如果被调用的方法没有给输出参数赋值,则会出现编译错误。
params:
(6)、Const和ReadOnly的区别
static readonly:
a.在运行期间解析常量。b.即可在申明时初始化,也可在构造器中初始化。c.只可用来修饰类中的成员。
(用 static readonly 修饰符声明的成员依然是变量,只不过具有和常量类似的使用方法:通过类进行访问、初始化后不可以修改。但与常量不同的是这种变量是在运行期初始化)
const:
a.在编译期间解析常量。b.必须在申明时就初始化。c.即可用来修饰类中的成员,也可用来修饰函数中的局部变量。(用 const 修饰符声明的成员叫常量,是在编译期初始化并嵌入到客户端程序 )。c.const是static所以不必使用static关键字修饰,否则会报错。
24、是否可以继承String类?
String类是sealed类故不可以继承。
25、把一个Array复制到Arraylist中
string[] s={"111","222"};
1、ArrayList list=new ArrayList();
list.AddRange(s);
2、Array list=new ArrayList(s);
3、foreach( object o in s )arrayList.Add(o)
26、Asp.Net在页面上的传值方式
(1)、使用QueryString, 如....?id=1; response. Redirect()....
(2)、使用Session变量
(3)、使用Server.Transfer
(4)、使Cookie传值
QueryString 传递一个或多个安全性要求不高或是结构简单的数值。但是对于传递数组或对象的话,就不能用这个方法了
session(viewstate) 简单,但易丢失 作用于用户个人,过量的存储会导致服务器内存资源的耗尽。
application 对象的作用范围是整个全局,也就是说对所有用户都有效。其常用的方法用Lock和UnLock
cookie 简单,但可能不支持,可能被伪造 Cookie是存放在客户端的,而session是存放在服务器端的。而且Cookie的使用要配合ASP.NET内置对象Request来使用
input type="hidden" 简单,可能被伪造
url参数简单,显示于地址栏,长度有限
Server.Transfer 把流程从当前页面引导到另一个页面中,新的页面使用前一个页面的应答流
数据库稳定,安全,但性能相对弱
27、什么是Viewstate?它有什么作用?
ViewState用来保存页面状态,就是说提交之后我们还可以看到文本框里面的内容就是ViewState保存的功劳。
ViewState只维护当前页面的状态,不同页面之间不能共享,Session可以。
ViewState你可以理解为一个隐藏控件。
28、ASP.Net页面生命周期
每个页面的生命周期为用户的每一次访问,也就是说每一次客户端与服务器之间的一个往返过程.全局变量的生命周期在此之间.
1. Page_Init();
2. Load ViewState and Postback data;
3. Page_Load();
4. Handle control events;
5. Page_PreRender();
6. Page_Render();
7. Unload event;
8. Dispose method called;
29、ADO.net中常用的对象有哪些?分别描述一下。
Connection 打开数据库连接
Command 执行数据库命令
DataAdapter 连接数据,执行数据库命令,填充DataSet
DataSet 数据在内存中的缓存,数据结构
DataReader 只读向前的读取数据库
30、DataReader和DataSet的异同
DataReader使用时始终占用SqlConnection,在线操作数据库..任何对SqlConnection的操作都会引发DataReader的异常..因为DataReader每次只在内存中加载一条数据,所以占用的内存是很小的..因为DataReader的特殊性和高性能.所以DataReader是只进的..你读了第一条后就不能再去读取第一条了..
DataSet则是将数据一次性加载在内存中.抛弃数据库连接..读取完毕即放弃数据库连接..因为DataSet将数据全部加载在内存中.所以比较消耗内存...但是确比DataReader要灵活..可以动态的添加行,列,数据.对数据库进行回传更新操作...
31、.Net读取数据库用到的类:
DataSet:数据集。
DataCommand:执行语句命令。
DataAdapter:数据的集合,用于填充。
DataReader:数据只读器
32、ASP.Net的身份验证方式:
Windows(默认)用IIS控制
From(窗体)用帐户
Passport(密钥)
33、Code-Behind技术:
代码后置
34、&和&&的区别。
&是位运算符,表示按位与运算,&&是逻辑运算符,表示逻辑与(and).
35、<%# %>,<% %>,<%-- --%>区别:
<%# %>表示绑定的数据源,<% %>是服务器端代码块,<%--注释--%>注释
36、在C#中,string str = null 与 string str = " " 请尽量使用文字或图象说明其中的区别。
null:表示不占内存空间, " " 表示分配了一个长度为空字符串的内存空间。
37、GET与POST的区别
在FORM提交的时候,如果不指定Method,则默认为GET请求,Form中提交的数据将会附加在url之后,以?分开与url分开。字母数字字符原样发送,但空格转换为“+“号,其它符号转换为%XX,其中XX为该符号以16进制表示的ASCII(或ISO Latin-1)值。GET请求请提交的数据放置在HTTP请求协议头中,而POST提交的数据则放在实体数据中;
在使用 POST 方法的情况下,传输数据时不会将数据作为 URL 的一部分;它们会作为一个独立的实体来传输。因此,POST 方法更安全,你也可以用这个方法传输更多的数据。而且用 POST 传输的数据不一定要是文本,用 GET 方法传输的却一定要是文本。
(1)get是从服务器上获取数据,post是向服务器传送数据。
(1)在客户端,Get方式在通过URL提交数据,数据在URL中可以看到;POST方式,数据放置在HTML HEADER内提交。
(2)对于get方式,服务器端用Request.QueryString获取变量的值,对于post方式,服务器端用Request.Form获取提交的数据。
(2)GET方式提交的数据最多只能有1024字节,而POST则没有此限制。
(3)安全性问题。正如在(1)中提到,使用 Get 的时候,参数会显示在地址栏上,而 Post 不会。所以,如果这些数据是中文数据而且是非敏感数据,那么使用 get;如果用户输入的数据不是中文字符而且包含敏感数据,那么还是使用 post为好。
38、分析以下代码,完成填空
string strTmp = "abcdefg某某某";
int i= System.Text.Encoding.Default.GetBytes(strTmp).Length;
int j= strTmp.Length;
以上代码执行完后,i,j的值?
i=14,j=10
39、分页
40、冒泡排序
int[] array = { 1, 2, 3, 4, 6, 8, 12, 5,9};//定义一个数组
int temp = 0;
for (int i = 0; i < array.Length - 1; i++)
{
for (int j = i + 1; j < array.Length; j++)
{
if (array[j] < array[i])
{
temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
}
//输出新数组中的每一个元素的值
foreach (int a in array)
{
Console.WriteLine(a);
}
41、一列数的规则如下: 1、1、2、3、5、8、13、21、34...... 求第30位数是多少, 用递归算法实现。
public static int Foo(int i)
{
if (i <= 0)
return 0;
else if(i > 0 && i <= 2)
return 1;
else return Foo(i -1) + Foo(i - 2);
}
42、请将字符串"I am a student"按单词逆序输出 如"student a am I"
string S = "I am a student";
char[] C = new char[] { ' '};
string[] n =S.Split(C);
int length = n.Length;//n的长度;
for (int i =length-1 ; i >=0; i--)
{
Console.Write(n[i]);
if (i != 0)
{
Console.Write(" ");
}
}
C#字符串倒序输出的多种写法:
class Program { static void Main(string[] args) { string str = Console.ReadLine(); Console.WriteLine(ReverseA(str)); Console.WriteLine(ReverseB(str)); Console.WriteLine(ReverseC(str)); Console.WriteLine(ReverseD(str)); Console.WriteLine(ReverseE(str)); Console.ReadKey(); } //方法一: public static string ReverseA(string zfc) { char[] cArray = zfc.ToCharArray(); string reverse = String.Empty; for (int i = cArray.Length - 1; i > -1; i--) { reverse += cArray[i]; } return reverse; } //方法二: public static string ReverseB(string zfc) { char[] cArray = zfc.ToCharArray(); Array.Reverse(cArray);//Reverse 翻转整个一位数组的顺序 return new string(cArray); } //方法三:Push/Pop Stack<> public static string ReverseC(string zfc) { Stack resultStack = new Stack();//Stack表示对象的后进先出的非泛型集合 foreach (char c in zfc) { resultStack.Push(c); } StringBuilder sb = new StringBuilder(); while (resultStack.Count > 0) { sb.Append(resultStack.Pop()); } return sb.ToString(); } //方法四:LINQ public static string ReverseD(string zfc) { return new string(zfc.ToCharArray().Reverse().ToArray()); } //方法五:StringBuilder public static string ReverseE(string zfc) { char[] cArray = zfc.ToCharArray(); StringBuilder sb = new StringBuilder(); for (int i = cArray.Length - 1; i > -1; i--) { sb.Append(cArray[i]); } return sb.ToString(); } }
43、Visual Studio 和.NET Framework的关系
Visual Studio 是微软提供的编程(开发)工具,是一种集成开发环境。
.NET Framwork 是C#编程语言提供的类库,目的是为了方便快捷的开发,也是一些软件所必须安装的系统组件(一些软件只有安装了.NET Framwork 才能正常的安装)。
.NET Framwork 是以一种采用虚拟机运行的编程平台,以通用的语言运行库CLR为基础,支持多种语言(如C#、VB、C++、Python等)的开发。同时.NET也为应用程序开发接口(API)提供了新功能和开发工具。
C#是在.NET平台上使用的一种编程语言。ASP.NET是.NET的一种,ADO.NET又是ASP.NET里边访问数据库的一种技术。
44、WinForm之间的传值方式
45、Session,Cookie
46、foreach 和 for
47、Response, Request
48、单例模式
49、Javascript,Ajax,Json,XML优点缺点
50、配置文件