.NET程序员面试常见题型(一)

1、简述 private、 protected、 public、 internal 修饰符的访问权限。(常考

private : 私有成员, 在类的内部才可以访问。

protected : 保护成员,该类内部和继承类中可以访问。

public : 公共成员,完全公开,没有访问限制。

internal: 当前程序集内可以访问。

 

2、ADO.NET中的五个主要对象(常考

Connection:主要是开启程序和数据库之间的连接。没有利用连接对象将数据库打开,是无法从数据库中取得数据的。Close和Dispose的区别,Close以后还可以Open,Dispose以后则不能再用。

Command:主要可以用来对数据库发出一些指令,例如可以对数据库下达查询、新增、修改、删除数据等指令,以及调用存在数据库中的存储过程等。这个对象是架构在Connection 对象上,也就是Command 对象是透过连接到数据源。

DataAdapter:主要是在数据源以及DataSet 之间执行数据传输的工作,它可以透过Command 对象下达命令后,并将取得的数据放入DataSet 对象中。这个对象是架构在Command对象上,并提供了许多配合DataSet 使用的功能。

DataSet:这个对象可以视为一个暂存区(Cache),可以把从数据库中所查询到的数据保留起来,甚至可以将整个数据库显示出来,DataSet是放在内存中的。DataSet 的能力不只是可以储存多个Table 而已,还可以透过DataAdapter对象取得一些例如主键等的数据表结构,并可以记录数据表间的关联。DataSet 对象可以说是ADO.NET 中重量级的对象,这个对象架构在DataAdapter对象上,本身不具备和数据源沟通的能力;也就是说我们是将DataAdapter对象当做DataSet 对象以及数据源间传输数据的桥梁。DataSet包含若干DataTable、DataTableTable包含若干DataRow。

DataReader:当我们只需要循序的读取数据而不需要其它操作时,可以使用DataReader 对象。DataReader对象只是一次一笔向下循序的读取数据源中的数据,这些数据是存在数据库服务器中的,而不是一次性加载到程序的内存中的,只能(通过游标)读取当前行的数据,而且这些数据是只读的,并不允许作其它的操作。因为DataReader 在读取数据的时候限制了每次只读取一笔,而且只能只读,所以使用起来不但节省资源而且效率很好。使用DataReader 对象除了效率较好之外,因为不用把数据全部传回,故可以降低网络的负载。

ADO.NET 使用Connection 对象来连接数据库,使用Command 或DataAdapter对象来执行SQL语句,并将执行的结果返回给DataReader 或 DataAdapter ,然后再使用取得的DataReader 或DataAdapter 对象操作数据结果。

简洁版答案:

Connection     连接对象

Command      命令对象    

DataAdapter  适配器

DataReader   阅读器

DataSet          数据集

 

3、列举ASP.NET 页面之间传递值的几种方式。

1.使用QueryString, 如....?id=1; response. Redirect()....

2.使用Session变量

3.使用Server.Transfer

4.Cookie传值

 

4、C#中的委托是什么?事件是不是一种委托?事件和委托的关系。

委托可以把一个方法作为参数代入另一个方法。

委托可以理解为指向一个函数的指针。

委托是类型,事件是对象。

事件的内部是用委托实现的

 

5、override与重载(overload)的区别

重载是方法的名称相同。参数或参数类型不同,进行多次重载以适应不同的需要。重载(overload)是面向过程的概念。

Override 是进行基类中函数的重写。Override是面向对象的概念

 

6、关于拆箱装箱:

装箱:从值类型转换为引用类型

拆箱:从引用类型转换为值类型

 

7、CTS、CLS、CLR分别作何解释(*)把英文全称背过来。

CTS:通用语言系统。CLS:通用语言规范。CLR:公共语言运行库。

CTS通用类型系统(Common Type System)

CLS通用语言规范(Common Language Specification)

LR公共语言运行库(Common Language Runtime)

 

8、堆和栈的区别?

栈是编译期间就分配好的内存空间,因此你的代码中必须就栈的大小有明确的定义;局部值类型变量、值类型参数等都在栈内存中。

堆是程序运行期间动态分配的内存空间,你可以根据程序的运行情况确定要分配的堆内存的大小。

 

9、能用foreach遍历访问的对象的要求

需要实现IEnumerable接口或声明GetEnumerator方法的类型。

 

10、值类型和引用类型的区别?

1.将一个值类型变量赋给另一个值类型变量时,将复制包含的值。引用类型变量的赋值只复制对对象的引用,而不复制对象本身。

2.值类型不可能派生出新的类型:所有的值类型均隐式派生自 System.ValueType。但与引用类型相同的是,结构也可以实现接口。

3.值类型不可能包含 null 值:然而,可空类型功能允许将 null 赋给值类型。

4.每种值类型均有一个隐式的默认构造函数来初始化该类型的默认值。 

 

11、C#中的接口和类有什么异同。

不同点:

不能直接实例化接口。

接口不包含方法的实现。

接口可以多继承,类只能单继承。

类定义可在不同的源文件之间进行拆分。

相同点:

接口、类和结构都可以从多个接口继承。

接口类似于抽象基类:继承接口的任何非抽象类型都必须实现接口的所有成员。

接口和类都可以包含事件、索引器、方法和属性。

 

基础知识:接口只能定义方法(只能定义行为,不能定义实现也就是字段),因为事件、索引器、属性本质上都是方法,所以接口中也可以定义事件、索引器、属性。

 

12、abstract class和interface有什么区别?

相同点:

都不能被直接实例化,都可以通过继承实现其抽象方法。

不同点:

接口支持多继承;抽象类不能实现多继承。

接口只能定义行为;抽象类既可以定义行为,还可能提供实现。

接口只包含方法(Method)、属性(Property)、索引器(Index)、事件(Event)的签名,但不能定义字段和包含实现的方法;

抽象类可以定义字段、属性、包含有实现的方法。 

接口可以作用于值类型(Struct)和引用类型(Class);抽象类只能作用于引用类型。例如,Struct就可以继承接口,而不能继承类。

加分的补充回答:讲设计模式的时候SettingsProvider的例子。

 

13.写出一条Sql语句:取出表A中第31到第40记录(SQLServer,以自动增长的ID作为主键,注意:ID可能不是连续的。(常考

答:解1: select top 10 * from A where id not in (select top 30 id from A)

解2: select top 10 * from A where id > (select max(id) from (select top 30 id from A )as A)
 

14.StringBuilder String 的区别?

答:String 在进行运算时(如赋值、拼接等)会产生一个新的实例,而 StringBuilder 则不会。所以在大量字符串拼接或频繁对某一字符串进行操作时最好使用 StringBuilder,不要使用 String

 如果要操作一个不断增长的字符串,尽量不用String类,改用StringBuilder类。两个类的工作原理不同:String类是一种传统的修改字符串的方式,它确实可以完成把一个字符串添加到另一个字符串上的工作没错,但是在.NET框架下,这个操作实在是划不来。因为系统先是把两个字符串写入内存,接着删除原来的String对象,然后创建一个String对象,并读取内存中的数据赋给该对象。这一来二去的,耗了不少时间。而使用System.Text命名空间下面的StringBuilder类就不是这样了,它提供的Append方法,能够在已有对象的原地进行字符串的修改,简单而且直接。当然,一般情况下觉察不到这二者效率的差异,但如果你要对某个字符串进行大量的添加操作,那么StringBuilder类所耗费的时间和String类简直不是一个数量级的。 

 

15、.请叙述属性与索引器的区别。 (*

属性 索引器    

  通过名称标识。 通过签名标识。    

  通过简单名称或成员访问来访问。 通过元素访问来访问。    

  可以为静态成员或实例成员。 必须为实例成员。    

  属性的   get   访问器没有参数。 索引器的   get   访问器具有与索引器相同的形参表。    

  属性的   set   访问器包含隐式   value   参数。 除了   value   参数外,索引器的   set   访问器还具有与索引器相同的形参表。 

 

16、post、get的区别

get的参数会显示在浏览器地址栏中,而post的参数不会显示在浏览器地址栏中;

使用post提交的页面在点击【刷新】按钮的时候浏览器一般会提示“是否重新提交”,而get则不会;

用get的页面可以被搜索引擎抓取,而用post的则不可以;

用post可以提交的数据量非常大,而用get可以提交的数据量则非常小(2k),受限于网页地址的长度。

用post可以进行文件的提交,而用get则不可以。

 参考阅读:http://www.cnblogs.com/skynet/archive/2010/05/18/1738301.html

 

 

17、请写一个SQL语句:从user表中取出name列中的起始字符是“北京”的全部记录

select * from [user] wherer name like '北京%'

 

18、横表、纵表转换(常考

1)纵表结构 TableA 

Name

Course

Grade

张三

语文

75

张三

数学

80

张三

英语

90

李四

语文

95

李四

数学

55

 横表结构 TableB

Name

语文

数学

英语

张三

75

80

90

李四

95

55

0

先理解:

select Name

 (case Course when ‘语文‘ then Grade else 0 end) as 语文,

 (case Course when ‘数学‘ then Grade else 0 end) as 数学,

 (case Course when ‘英语‘ then Grade else 0 end) as 英语

from TableA

然后理解标准答案:

select Name

sum(case Course when ‘语文‘ then Grade else 0 end) as 语文,

sum(case Course when ‘数学‘ then Grade else 0 end) as 数学,

sum(case Course when ‘英语‘ then Grade else 0 end) as 英语

from TableA

group by Name 

2)、横表转纵表的"SQL"示例
横表结构: TEST_H2Z
      ID     
姓名    语文        数学       英语      
      1      
张三     80         90         70            
      2      
李四     90         85         95          
      3      
王五     88         75         90          
 

转换后的表结构:  
      ID    
姓名     科目     成绩  
      1      
张三     语文     80  
      2      
张三     数学     90  
      3      
张三     英语     70  
      4      
李四     语文     90  
      5      
李四     数学     80    
      6      
李四     英语     99  
      7      
王五     语文     85  
      8      
王五     数学     96  
      9      
王五     英语     88  


横表转纵表SQL示例:
SELECT  
姓名,'语文'   AS     科目,语文   AS   成绩   FROM   TEST_H2Z   UNION   ALL 
SELECT  
姓名,'数学'   AS     科目,数学   AS   成绩   FROM   TEST_H2Z   UNION   ALL 
SELECT  
姓名,'英语'   AS     科目,英语   AS   成绩   FROM   TEST_H2Z
ORDER BY
姓名,科目 DESC;

 

18、删除姓名、年龄重复的记录(只保留Id最大的一条)

Id  name  age  salary

1   yzk    80  1000

2   yzk    80  2000

3   tom    20  20000

4   tom    20  20000

5   im     20  20000

 

//取得不重复的数据

select * from Persons

where Id in

(

SELECT     MAX(Id) AS Expr1

FROM         Persons

GROUP BY Name, Age

)

 

根据姓名、年龄分组,取出每组的Id最大值,然后将Id最大值之外的排除。

 

删除重复的数据:

delete from Persons

where Id not in

(

SELECT     MAX(Id) AS Expr1

FROM         Persons

GROUP BY Name, Age

)

 

19、有一个10个数的数组,计算其中不重复数字的个数。{3,5,9,8,10,5,3}

工程化的非最优解答:用HashSet或者List

            int[] values = { 3, 5, 9, 8, 10, 5, 3 };

            HashSet<int> set = new HashSet<int>();

            foreach (int i in values)

            {

                set.Add(i);

            }

            Console.WriteLine(set.Count);

 

20、请编程遍历WinForm页面上所有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 ;
}
}

 

21.一个数组:1,1,2,3,5,8,13,21...+m,求第30位数是多少?用递归实现(常考)

写递归要确定两个:递归的终止条件;递归表达式。

解答:总结递归规律:F(n)=F(n-2)+F(n-1) Fibonacci数列

        static int F(int n)

        {

            if (n == 1)

            {

                return 1;

            }

            if (n == 2)

            {

                return 1;

            }

            return F(n - 2) + F(n - 1);

        }

 

22.refout的区别?

1)使用ref型参数时,传入的参数必须先被初始化。对out而言,必须在方法中对其完成初始化。

2)使用ref和out时,在方法的参数和执行方法时,都要加Ref或Out关键字。以满足匹配。

3)out适合用在需要retrun多个返回值的地方,而ref则用在需要被调用的方法修改调用者的引用的时候。

23、产生一个int数组,长度为100,并向其中随机插入1-100,并且不能重复。(常考

做法1

            List<int> list = new List<int>();

            Random rand = new Random();

            while (list.Count < 100)

            {

                int number = rand.Next(1, 101);//>=1,<101

                if (!list.Contains(number))//如果list中已经含有这个数,则不插入

                {

                    list.Add(number);

                }

            }

            foreach (int i in list)

            {

                Console.WriteLine(i);

            }

 

做法2

先把1-100100个数按顺序放入数组arr,再重复100次下面的操作,生成两个介于 >=0,<100 之间的随机数mn,颠倒arr[m]arr[n]的数。

            int[] arr = new int[100];

            //100个数顺序放入

            for (int i = 0; i < 100; i++)

            {

                arr[i] = i + 1;

            }

            Random rand = new Random();

            for (int i = 0; i < 100; i++)

            {

                //随机生成两个位置

                int m = rand.Next(0, 100);

                int n = rand.Next(0, 100);

                //颠倒两个位置

                int temp = arr[m];

                arr[m] = arr[n];

                arr[n] = temp;

            }

24、冒泡排序(常考

   for (int j = 0; j < nums.Length - 1; j++)

            {

                for (int i = 0; i < nums.Length - 1 -j; i++)

                {

                    if (nums[i] > nums[i + 1])

                    {

                        int temp = nums[i];

                        nums[i] = nums[i + 1];

                        nums[i + 1] = temp;

                    }

                }

            }

猜你喜欢

转载自blog.csdn.net/JessicaQNL/article/details/81220213