开发人员面试题

来源:互联网 发布:网络诈骗八千 编辑:程序博客网 时间:2024/05/29 07:54
1、列举ASP.NET页面之间传值的几种方式。
答:使用QueryString,如.../id=1;response.Redirect()
使用Session
使用Server.Transfer
使用Cookie

2、简述private、protected、public、internal修饰符的访问权限。
答:privata:私有成员,在类的内部才可以访问
protected:保护成员,该类内部和继承类可以访问
public:公开成员,没有访问限制
internal: 当前程序集可以访问

3、简述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 对象操作数据结果。

4、请简述.NET中类与结构的异同。
答:class可以被实例化,属于引用类型,是分配在内存的堆上的。类是引用传递。
struct属于值类型,是分配在内存的栈上的。结构是值传递。
int32、boolean都属于结构。

5、override与重载(overload)的区别。
答:重载是方法的名称相同。参数或参数类型不同,进行多次重载以适应不同的需要。

重载是面向过程的概念。override是进行基类中函数的重写,是面向对象的概念。

6、new有几种用法?
答:1、new Class();
2、覆盖方法,public new XXXX();
3、new() 约束指定泛型类声明中的任何类型参数都必须有公共的无参数构造函数

7、用sealed修饰的类有什么特点?
答:sealed修饰符用于防止从所修饰的类派生出其他类。如果一个密封类指定为其他类的基类,则会发生编译错误。
密封类不能同时为抽象类。
sealed修饰符主要用于防止非有意的派生,他还能促使某些运行时优化。
String就是用sealed修饰的密封类,所以不能被继承。

3、在.NET中,配件的意思是?
答:程序集。(中间IL语言、元数据、资源、装配清单)

9、一个数组:1,1,2,3,5,8,13,21...,求第30位数是多少?
答:int[] arr = new int[30];
arr[0] = 1;
arr[1] = 1;


for (int i = 2; i < arr.Length; i++)
{
arr[i] = arr[i-1] + arr[i-2];
}
Console.WriteLine(arr[29]);
Console.ReadLine();

10、请简述面向对象的多态的特性及意义
答:简单来说,多态是具有表现多种形态的能力特征,在OO中是指,语言根据对象的类型的不同,以不同的方式处理。
特别是重载方法和继承类这种形式的能力。
多态被认为是面向对象语言的必备特性。
面向对象的语言使用虚方法表达多态。
这意味着派生类可以有和父类具有同样签名的方法,并且父类可以调用派生类的方法。
在C#中,必须使用virtual关键字才能使方法被父类调用。

11、请编程遍历winform窗口上所有TextBox控件,并给它的Text属性赋值为string.Empty。
答:using System.Windows.Forms;
foreach (Control control in this.Controls)
{
if(control is TextBox)
{
  TextBox tb = (TextBox)control;
  tb.Text = String.Empty;
}
}

12、什么是装箱(inboxing)和拆箱(unboxing)。
答:装箱:将一个值类型隐式地转换成一个object类型,或把这个值类型转换成一个被该值类型应用的接口类型,把一个值类型的值装箱,就是创建一个object实例并将值复制给这个object
拆箱:和装箱相反,拆箱转换是指将一个对象类型显式地转换成一个值类型,或将一个接口类型显式地转换成一个执行该接口的值类型。
object obj = null;
obj = 1;//装箱,把值类型包装成引用类型。
int num = (int)obj;// 拆箱,显示类型转换。

13、如何理解三层架构。
答:三层架构就是将整个业务应用划为:表现层、业务逻辑层、数据访问层。
区分层次的目的即为了“高内聚,低耦合”的思想。
表现层:通俗讲就是展现给用户的界面,即用户在使用一个系统的时候的所见所得。
业务逻辑层:针对具体问题的操作,也可以说是对数据层的操作,对数据业务逻辑处理。
数据访问层:该层所做事务直接操作数据库,针对数据的增删改查等。
每层之间是一种垂直关系。
三层架构是N层架构的一种,一般来说,层次之间是向下依赖的,下层代码未确定其接口前,上层代码是无法开发的,下层代码接口的变化将使上层的代码一起变化。
优点:分工明确,条理清晰,易于调试,而且具有扩展性。
缺点:增加系统复杂度,增加成本。


14、写一个冒泡排序(从小到大)。
答:int[] myInts = { 11, 22, 33, 44, 55 ,66};
int temp = 0;
int count = 0;
for (int i = 1; i <= myInts.Length - 1; i++)
{
//bool 是否需要排序 = false;
for (int j = myInts.Length - 1; j >= i; j--)
{
if (myInts[j] < myInts[j - 1])
{
temp = myInts[j];
myInts[j] = myInts[j - 1];
myInts[j - 1] = temp;
}
count++;
}
}

15、数据库三范式是什么?
答:1NF,确保每列保持原子性
2NF,确保表中的每列都和主键相关
3NF,确保每列都和主键列直接相关,而不是间接相关

16、能用foreach遍历访问的对象有什么要求?
答:需要实现IEnumerable接口或声明GetEnumerator方法的类型。

17、GC是什么?为什么要有GC?
答:GC是垃圾收集器。
程序员不用担心内存管理,因为垃圾收集器会自动进行管理。
GC只能处理托管内存资源的释放,对于非托管资源则不能使用GC回收内存,必须由程序员手工回收。

18、说出五个集合类。
答:List、Dictionary、Stack、Queue、Tree等

19、不用JQuery等库,原生JS使用AJAX实现登陆。
答:window.onload = function () {
document.getElementById('btn').onclick = function () {
var username = document.getElementById('username').value;
var password = document.getElementById('password').value;
var xhr = new XMLHttpRequest();
xhr.open('POST','/url?username=' + username + '&password=' + password, true);
xhr.onreadystatechange = function () {
if(xhr.readyState === 4) {
if (xhr.status === 200) {
alert('登陆成功')
} else {
alert('登陆失败')
}
}
}

}
}


20、你觉得如何才能提高代码的效率和性能(可以列举多种思路,越多越好)?
答:可以根据业务流程、业务数据的特点进行优化,比如可以采用缓存、索引等来提高代码的效率和性能。
同时不要进行无意义的代码优化,重点优化系统的性能瓶颈。
按照设计模式去编写代码,彻底的面向对象编程,多用委托事件。
尽量做到方法的每一个实现代码只写一遍。

21、什么是Code-Behind技术?
答:Code-Behind是代码隐藏。
在ASP.NET中通过ASPX页面指向CS文件的方法显示逻辑和处理逻辑的分离,这样有助于web应用程序的创建。
Code-Behind是基于部分类技术实现的。

22、using关键字有什么用?什么是IDisposable?
答:using可以声明namespace的引入,还可以实现非托管资源的释放,实现了IDisposable的类在using中创建对象,using结束后会自动调用Dispose方法,释放资源。
using其实等价于于try...finally,用起来更方便。

23、String是值类型还是引用类型?它是如何工作的。
答:String是引用类型。
String的值是不可变的,当对String类型的对象重新赋值时,这个对象的引用指向就会变成一个新的引用,而原来的那个值并没有改变,只是引用改变了。

24、简述堆与栈的区别。
答:栈是编译期间就分配好的内存空间,因此你的代码中必须就栈的大小有明确的定义;
局部值类型变量、值类型参数等都在栈中。
堆是程序运行期间动态分配的内存空间,你可以根据程序的运行情况确定要分配的堆内存的大小。

25、有一个8个数的数组{1,2,3,3,4,5,6,6},计算其中不重复数字的个数。
答:int values = {1,2,3,3,4,5,6,6};
HashSet<int> set = new HashSet<int>();
foreach(int i in values)
{
set.Add(i);
}

Console.WriteLine(set.Count)

26、是否可以从一个static方法内部发出对非static方法的调用?
答:不可以。因为非static方法与对象相关联,必须创建一个对象后,才可以在该对象上进行方法调用,而static方法调用时不需要创建对象,可以直接调用。
也就是说,当一个static方法被调用时,可能还没有创建任何实例对象,如果从一个static方法中调用一个static方法,那么非static方法没有关联的对象,所以不可以。

27、说出一些常用类、接口,请各列举5个。
答:类:StreamReader、StringBuilder、SqlConnection、FileStream、File、Regex
接口:IDisposable、IEnumerable、IComparable、ICollection、IList

28、C#支持多重继承么?
答:类之间不支持,接口之间支持。
类对接口叫做实现,不叫继承。
类是爹、接口是能力,能力可以有多个,但不能有多个爹。

29、简单说明数据库建立索引的优缺点。
答:优点,使用索引可以加快数据的查询速度。
缺点,插入数据过程中会建立索引,所以会降低数据的插入、更新速度,还会占用磁盘。
如果一个表查询比写入频繁可以建立索引,如果写入比查询频繁,就不建议建立索引。

30、SQL注入漏洞产生的原因?如何防止。
答:程序开发过程中不注意书写sql语句和对特殊字符进行过滤,导致客户端可以提交一些sql语句正常执行。
1、sql语句尽量不要省略引号和单引号。
2、过滤掉SQL语句中的一些关键字。
3、控制错误信息,不要再浏览器上输出错误信息。
4、使用SqlParameter类,尽量不要拼接字符串SQL语句。

31、通过超链接<a>如何传递中文参数。
答:用URL编码,通过QueryString传递,用System.Web.HttpUtility.UrlEncode编码 用System.Web.HttpUtility.UrlDecode解码。


32、Ajax解决什么问题?如何使用Ajax?Ajax有什么问题需要注意?
答:AJAX解决的问题就是“无刷新更新页面”,用传统的HTML表单方式进行页面的更新时,每次都要将请求提交到服务器,服务器返回后再重绘界面。
这样界面就会经历:提交→变白→重新显示这样一个过程,用户体验非常差,使用AJAX则不会导致页面重新提交、刷新。
AJAX最本质的实现是在Javascript中使用XMLHttpRequest进行Http的请求,开发中通常使用UpdatePanel、JQuery等方式简化AJAX的开发。
使用XmlHttpRequest实现Ajax请求。
Ajax最重要的问题是无法跨域请求,也就是无法在再页面中向和当前域名不同的页面发送请求。

33、你经常访问的技术类网站是什么?
答:博客园、CSDN、GitHub、MSDN、MDN、CnBate、CodePlex

34、Session有什么缺陷?微软提出了什么方法加以解决。
答:iis中由于有进程回收机制,系统繁忙的话Session会丢失,IIS重启也会丢失。
可以用SateServer或SQL Server数据库的方式存储Session不过这种方式比较慢,而且无法捕获Session的END事件。
SateServer还可以解决集群Session共享的问题。

35、ASP.NET中的错误机制。
答:ASP.NET四种错误处理机制,分别是:Page_Error(不常用),Application_Error(应用程序中的未捕获异常),<customErrors>四种。

36、如何提高页面的显示速度?假如一个页面的加载时间是10.89S,你会用什么样的方式优化。
答:首先要找出问题所在,是服务器端运行的速度慢还是服务器端到客户端的下载慢还是页面在浏览器的加载速度慢。
如果是服务器端运行速度慢,则找是数据库的原因还是算法的问题,如果是数据库的问题则尝试添加索引、优化SQL语句,如果是算法的问题,则优化算法。
如果对于一些不经常改动的页面可以使用静态页技术!
对于一些数据不需要及时更新的而且取数据的过程非常耗时可以使用缓存。
页面中的内容可以按需加载(比如说可以像网站的评论那样当用户需要看的时候再加载其内容)
可以在图片需要显示的时候再进行加载。
如果是服务器端到客户端的下载慢则看是页面体积过于臃肿还是网络问题,
如果是页面体积过于臃肿,则优化HTML代码,去掉无用的标签,压缩JS、CSS,可以用CSS Spirit技术将多个图片放到一个图片中,减少向服务器的请求。
如果是网络问题,则尝试在不同的网络、地区部署服务器,然后使用CDN技术加速访问。
如果是页面中的JavaScript运行复杂导致运行速度慢,则优化JavaScript。 

37、你会采用什么样的策略和方法来实现系统缓存。
答:在ASP.NET中 缓存有 页面缓存,数据源缓存,和一些自己定义的缓存!
对于那些整个页面不经常变化的我们可以使用页面缓存,而对于那些执行非常耗时的SQL语句并且数据的及时性要求不高的我们可以使用数据源缓存。


38、网站想要实现文件防盗链的功能,说说你的解决方案。
答:读取HTTP报文头中的UrlReferrer在Application_BeginRequest中我们可以判断用户的请求是否来源于本网站。如果不是我们可以终止用户的请求。

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

40、对于大流量的网站,应采用什么样的方法来解决访问量问题。
答:首先,确认服务器硬件是否足够支持当前的流量。
普通的P4服务器一般最多能支持每天10万独立IP,如果访问量比这个还要大,那么必须首先配置一台更高性能的专用服务器才能解决问题,否则怎么优化都不可能彻底解决性能问题。



其次,优化数据库访问。
服务器的负载过大,一个重要的原因是CPU负荷过大,降低服务器CPU的负荷,才能够有效打破瓶颈。而使用静态页面可以使得CPU的负荷最小化。
前台实现完全的静态化当然最好,可以完全不用访问数据库,不过对于频繁更新的网站,静态化往往不能满足某些功能。
缓存技术就是另一个解决方案,就是将动态数据存储到缓存文件中,动态网页直接调用这些文件,而不必再访问数据库,WordPress和Z-Blog都大量使用这种缓存技术。
如果确实无法避免对数据库的访问,那么可以尝试优化数据库的查询SQL.避免使用Select * from这样的语句,每次查询只返回自己需要的结果,避免短时间内的大量SQL查询。

第三,禁止外部的盗链。
外部网站的图片或者文件盗链往往会带来大量的负载压力,因此应该严格限制外部对于自身的图片或者文件盗链。

第四,控制大文件的下载。
大文件的下载会占用很大的流量,并且对于非SCSI硬盘来说,大量文件下载会消耗CPU,使得网站响应能力下降。因此,尽量不要提供超过2M的大文件下载, 如果需要提供,建议将大文件放在另外一台服务器上。

第五,使用不同主机分流主要流量
将文件放在不同的主机上,提供不同的镜像供用户下载。

第六,使用流量分析统计软件
在 网站上安装一个流量分析统计软件,可以即时知道哪些地方耗费了大量流量,哪些页面需要再进行优化,因此,解决流量问题还需要进行精确的统计分析才可以。

41、打印出由*号组成的倒三角形的图案
******* 4*2-1 要求: 1、输入倒三角的行数,行数范围3-18,对于不在范围的行数,抛出提示.
 ***** 3*2-1 2、在控制台打印出指定行数的倒三角形。
  ***2
   *1
答:while (true)
{
Console.Write("请输入一个数(3-50)之间:");
int num = Convert.ToInt32(Console.ReadLine());
if (num < 3 || num > 50)
{
Console.WriteLine("非法数值");
continue;
}


StringBuilder sb = new StringBuilder();
for (int i = 0; i < num; i++)
{
sb.Clear();
//生成空格,规则:行首空格数=行数-1
string space = "".PadLeft(i, ' ');
sb.Append(space);
//生成星号, 规则:行号*2-1,行号=num-i
string star = "".PadLeft((num - i) * 2 - 1, '*');
sb.Append(star);
Console.WriteLine(sb);
}
}

42、什么是单例?编写一个单例类。
答:单例是一种设计模式。
这一模式的目的是使得类的一个对象成为系统中的唯一实例。
单例模式的要点有三个;一是某个类只能有一个实例;二是它必须自行创建这个实例;三是它必须自行向整个系统提供这个实例。
/// <summary>
    /// 单例模式的实现
    /// </summary>
    public class Singleton
    {
        // 定义一个静态变量来保存类的实例
        private static Singleton uniqueInstance;


        // 定义私有构造函数,使外界不能创建该类实例
        private Singleton()
        {
        }


        /// <summary>
        /// 定义公有方法提供一个全局访问点,同时你也可以定义公有属性来提供全局访问点
        /// </summary>
        /// <returns></returns>
        public static Singleton GetInstance()
        {
            // 如果类的实例不存在则创建,否则直接返回
            if (uniqueInstance == null)
            {
                uniqueInstance = new Singleton();
            }
            return uniqueInstance;
        }
    }

43、try{}里有一个return语句,那么紧跟在try后的finally{}里的代码会不会被执行,什么时候被执行。
答:会执行,如果return后面有一个返回值或者表达式,则会先进行计算,把值暂存起来,然后再执行finally里的代码,无论如何,return总是最后执行。

44、不用中间变量,交换两个整型变量。
答:i = 10, j = 20;
i = i + j;//i = 30;
j = i - j;//j = 10;
i = i - j;//i = 20;


45、对数据的并发采用什么方法比较好?
答:可以控制连接池的连接数量,越多越好,还可以使用负载均衡。

46、short s=1;s=s+1;有错么?short s=1;s+=1;有错么?
答:short s=1;s=s+1;
这句不会通过编译(类型转换错误),因为s+1,其中1为int型,而s会隐式转换为int再和1进行运算,运算结果自然是int,而int则无法隐式转换回short,所以这里是错的。
short s=1;s+=1;
这句是则不会报错,因为s+=1,相当于s=(short)(s+1),在运算后赋值前进行了显式类型转换。

47、产生一个int数组,长度为100,并向其随机插入1-100,并且不能重复(要求使用两种方法)。
答://方法一
List<int> list = new List<int>();
Random rand = new Random();
while (list.Count < 100)
{
int num = rand.Next(1, 101);
if (!list.Contains(num))
{
list.Add(num);
}
}


//方法二
int[] arr = new int[100];
for (int i = 0; i < 100; i++)
{
arr[i] = i + 1;
}
Random rand1 = new Random();
for (int i = 0; i < 100; i++)
{
int m = rand1.Next(0, 100);
int n = rand1.Next(0, 100);
int temp = arr[m];
arr[m] = arr[n];
arr[n] = temp;
}

48、C#中的委托是什么?事件是不是一种委托?事件和委托的关系。
答:委托可以把一个方法作为参数代入另一个方法。
委托可以理解为指向一个函数的指针。
委托是类型,事件是对象。
事件的内部是用委托实现的,对于事件来讲,外部只能注册自己(+=)和注销自己(-=)。
事件内部就是一个private的委托和add(+=)、remove(-=)两个方法。

49、属性和字段的区别是什么?
答:属性可以对值的获取和设置进行控制,而字段不能。
一般情况下get读取的值就是set设置的值。
如果只有get,则说明值是只读。
如果只有set,则说明值是只写。
get和set的本质是就是内部方法。

50、C#的接口和类有什么异同?
答:不同点:
不能直接实例化接口。
接口不包含方法的实现。
接口可以继承,类只能单继承。
类定义可在不同的源文件之间进行拆分。
相同点:
接口、类和结构都可以从多个接口继承实现。
继承接口的任何非抽象类型都必须实现接口的所有成员。
接口和类都可以包含事件、索引、方法和属性。

51、什么情况下会用到虚方法?它与接口有什么不同?
答:子类重新定义父类的某一个方法时,必须把父方法定义为virtual。
在定义接口中不能有方法体,虚方法可以。
实现时,子类可以可以不重新定义虚方法,但如果一个类继承接口,那必须实现这个接口。
52、常见的HTTP状态码有哪些?各是什么意思?
答:200:(成功) 服务器已成功处理了请求 。通常,这表示服务器提供了请求的网页
400 :(错误请求) 服务器不理解请求的语法   
404:(未找到) 服务器找不到请求的网页。
302 :(临时移动) 服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。
500 :(服务器内部错误) 服务器遇到错误,无法完成请求。
 
53、abstract class和interface有什么区别?
答:相同点:
都不能被直接实例化,都可以继承实现其(抽象)方法。
不同点:
接口支持多继承,抽象类不能实现多继承。
接口只能定义行为,抽象类既可以定位行为,还能提供实现。
接口只包括:方法、属性、索引器、事件的签名,不能定义字段和包含实现的方法。
抽象类可以定义字段、属性、包含实现的方法。
接口可用作于结构和类,抽象只能用作于类。
结构可以继承接口,而不能继承类。

54、简述属性与索引器的区别?
答:属性用于以可验证的方式访问私有成员变量。索引器用于以更便捷的方式访问对象中包含的成员数组或集合。
区别:
1、属性名可自定义,索引器必须以this命名。
2、属性可以为实例或静态,索引器必须是实例的。
3、索引器有索引参数列表,而属性没有。

55、DataReader和DataSet的异同?
答:DataReader为在线操作数据, DataReader会一直占用SqlConnection连接,在其获得数据过程中其它操作不可以再使用SqlConnection连接对象。
DataSet为离线操作数据,DataSet会将数据一次性读入内存,然后断开连接,这时其它操作就可以使用SqlConnection连接对象。
由于DataReader一次只读取一行数据,所以占用内存较小。但DataReader为只进且只读的,也就是只能单方向向前读取,如果你想回头去读取上一条数据是不允许的,并且不允许其修改数据。
由于DataSet一次性读取所有数据,所以比较消耗资源,但也提高了灵活性,在断开数据库连接情况下你可以对数据进行任何增删改查,按照任意的顺序读取数据,并可以将其写回到数据库。