美文网首页
C#基础面试题

C#基础面试题

作者: flyinghat | 来源:发表于2019-02-28 22:43 被阅读0次

    1.简述private、protected、pubic、internal修饰符的访问权限

    答:

    • private : 私有成员, 在类的内部才可以访问(只能从其声明上下文中进行访问)
    • protected : 保护成员,该类内部和从该类派生的类中可以访问
    • Friend:友元 ,声明 friend 元素的程序集中的代码可以访问该元素,而不能从程序集外部访问
    • Protected Friend:在派生类或同一程序集内都可以访问
    • public : 公共成员,完全公开,没有访问限制
    • internal: 在同一命名空间内可以访问

    2.C#中的委托是什么?事件是不是一种委托?

    答:
    委托是将一种方法作为参数代入到另一种方法。
    是,事件是一种特殊的委托。 //比如:onclick事件中的参数就是一种方法。

    3.实现多态的过程中 overload 重载 与override 重写的区别

    答:
    override 重写与 overload 重载的区别。重载是方法的名称相同。参数或参数类型不同,进行多次重载以适应不同的需要 override 是进行基类中函数的重写。实现多态。

    4.描述一下C#中索引器的实现过程,是否只能根据数字进行索引

    答:
    C#通过提供索引器,可以象处理数组一样处理对象。特别是属性,每一个元素都以一个get或set方法暴露。索引器不单能索引数字(数组下标),还能索引一些HASHMAP的字符串,所以,通常来说,C#中类的索引器通常只有一个,就是THIS,但也可以有无数个,只要你的参数列表不同就可以了索引器和返回值无关, 索引器最大的好处是使代码看上去更自然,更符合实际的思考模式。

    微软官方一个示例:

    索引器允许类或结构的实例按照与数组相同的方式进行索引。
    索引器类似于属性,不同之处在于它们的访问器采用参数。
    在下面的示例中,定义了一个泛型类(class SampleCollection<T>
    ),并为其提供了简单的 get 和 set访问器 方法(作为分配和检索值的方法)。Program 类为存储字符串创建了此类的一个实例。

    class SampleCollection<T>
    {
        private T[] arr = new T[100];
        public T this[int i]   //注意,定义索引器。this 关键字用于定义索引器。
        {
            get
            {
                return arr[i]; //访问器采用参数
            }
            set
            {
                arr[i] = value; //访问器采用参数
            }
        }
    }
    class Employee
        {
            public string firstName;
            public string middleName;
            public string lastName;
    
            public string this[string index]
            {
                set
                {
                    switch (index)
                    {
                        case "a":
                            firstName = value;
                            break;
                        case "b":
                            middleName = value;
                            break;
                        case "c":
                            lastName = value;
                            break;
                        default: throw new ArgumentOutOfRangeException("index");
                    }
                }
                get
                {
                    switch (index)
                    {
                        case "a": return firstName;
                        case "b": return middleName;
                        case "c": return lastName;
                        default: throw new ArgumentOutOfRangeException("index");
                    }
                }
            }
    // This class shows how client code uses the indexer
    class Program
    {
        static void Main(string[] args)
        {
            SampleCollection<string> stringCollection = new SampleCollection<string>(); 
            stringCollection[0] = "Hello, World"; //这里 使用索引器进行引用
            Console.WriteLine(stringCollection[0]);
            Employee ee = new Employee();
            ee.firstName = "胡";
            ee.middleName = "大";
            ee.lastName = "阳";
            ee["a"] = "sa";
            Console.WriteLine("我的名字叫: {0}{1}{2}", ee["a"], ee["b"], ee["c"]);
    
        }
    }
    
    • 索引器使得对象可按照与数组相似的方法进行索引。

    • get 访问器返回值。set 访问器分配值。

    • this关键字用于定义索引器。

    • value关键字用于定义由 set 索引器分配的值。

    • 索引器不必根据整数值进行索引,由您决定如何定义特定的查找机制。

    • 索引器可被重载。

    • 索引器可以有多个形参,例如当访问二维数组时。

    5.什么是装箱和拆箱?

    答:
    装箱就是隐式的将一个值型转换为引用型对象。
    拆箱就是将一个引用型对象转换成任意值型。

    int i=0;
    System.Object obj=i; //这个过程就是装箱!就是将 i 装箱!
    int j=(int)obj;//这个过程 obj 拆箱!
    

    6.什么是受管制(托管)的代码?

    答:
    托管代码是运行.NET 公共语言运行时CLR的代码
    unsafe:非托管代码。不经过CLR运行。程序员自行分配和释放内存空间

    7.ADO.Net中常用的对象有哪些?分别描述一下答

    答:

    • DataSet:数据集。
    • DataCommand:执行语句命令。
    • DataAdapter:数据的集合,用语填充。
    • DataReader:数据只读器
    • Connection 数据库连接对像
    • Command 数据库命令

    8.什么是Code-Behind技术?

    答:代码后置

    在.net中,配件的意思是?

    答:程序集。(中间语言,源数据,资源,装配清单)

    9.常用的调用WebService的方法有哪些?

    答:
    1.使用WSDL.exe命令行工具。
    2.使用VS.NET中的Add Web Reference菜单选项

    10.在C#中,string str1 = null 与 string str2 =""请尽量使用文字或图象说明其中的区别

    答:string str1 = null 是不给他分配内存空间,而string str2 = "" 给它分配长度为空字符串的内存空间,因此str1还不是一个实例化的对象,而str2已经实例化
    注意null不是对象,""是对象

    11.请详述在C#中类(class)与结构(struct)的异同?

    答:class可以被实例化,属于引用类型,class可以实现接口和单继承其他类,还可以作为基类型,是分配在内存的堆上的struct属于值类型,不能作为基类型,但是可以实现接口,是分配在内存的栈上的.

    12.GC是什么? 为什么要有GC?


    GC是垃圾收集器。程序员不用担心内存管理,因为垃圾收集器会自动进行管理。要请求垃圾收集,可以调用下面的方法之一:
    System.gc()
    Runtime.getRuntime().gc()

    13.String s = new String("xyz");创建了几个String Object?


    两个对象,一个是“xyx”,一个是指向“xyx”的引用对象s。

    14.abstract class和interface有什么区别?

    答:

    • abstract class
      abstract 声明抽象类抽象方法,一个类中有抽象方法,那么这个类就是抽象类了。所谓的抽象方法,就是不含主体(不提供实现方法),必须由继承者重写。因此,抽象类不可实例化,只能通过继承被子类重写。
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
     
    namespace ConsoleApplication1
    {
        public abstract class Bus
        {
            public abstract void getName();  //抽象方法
            public virtual void getTypes() //虚方法
            {
                Console.WriteLine("bus");
            }
            public void getID()//一般方法,若在派生类中重写,须使用new关键字
            {
                Console.WriteLine("沪A 00000");
            }
        }
        public class car : Bus
        {
            public override void getName() //继承抽象类,重新抽象方法
            {
                Console.WriteLine("奥迪");
            }
            public override void getTypes()//继承抽象类,重新虚方法
            {
                Console.WriteLine("car");
            }
        }
        class Program
        {
           
            static void Main(string[] args)
            {
                car mycar = new car();
                mycar.getName();
                mycar.getTypes();
                mycar.getID();
            }    
        }
     }
    

    输出:
    奥迪
    car
    沪A 00000

    • interface
      声明接口,只提供一些方法规约,不提供任何实现;不能用public、abstract等修饰,无字段、常量,无构造函数
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
     
    namespace ConsoleApplication1
    {
        public interface IBus
        {
            void getTypes();
        }
        public interface IPlane
        {
            void getfunc();
        }
        public class Car : IBus,IPlane
        {
            
            public void getTypes()
            {
                Console.WriteLine("car");
            }
            public void getfunc()
            {
                Console.WriteLine("fly");
            }
        }
        class Program
        {
           
            static void Main(string[] args)
            {
                Car  mycar = new Car ();
                mycar.getTypes();
                mycar.getfunc();
            }    
        }
    }
    

    输出结果:
    car
    fly

    • 区别
      1.interface中不能有字段,而abstract class可以有;
      2.interface中不能有public等修饰符,而abstract class 可以有。
      3.interface 可以实现多继承

    15..try {}里有一个return语句,那么紧跟在这个try后的finally {}里的code会不会被执行,什么时候被执行,在return前还是后?

    答:会执行,在return前执行。

    16.C#中equal与==的区别

    答:C#中,判断相等有两种方式,一种是传统的==操作,一种是object提供的Equals方法。二者的区别在于:
    一、==操作符判断的是堆栈中的值,Equlas判断的是堆中的值
    C#提供值类型和引用类型,值类型存储在栈上,故用==判断是直接判断其值是否相等,因为值类型不存在堆中的数据,因此值类型的Equals也是判断数据。即,对于值类型而言,==与Equals相同,均是判断其值是否相等。

    对于引用类型而言,其栈中存储的是对象的地址,那么==就是比较两个地址是否相等,即是否指向同一个对象;Equals函数则是比较两个对象在堆中的数据是否一样,即两个引用类型是否是对同一个对象的引用。
    二、String类型特殊
    String类型虽然是引用类型,但是对String对象的赋值却按照值类型操作。
    例如:
    String s1="hello";
    String s2="hello";
    对s2初始化的时候,并没有重新开辟内存,而是直接将其地址指向s1的内容“hello”。这样一来,string类型虽然是引用类型,但是其==操作和Equals操作都是一样的,均比较值是否相等。
    三、与GetHashCode()的关系
    若两对象Equals相等,那么其GetHashCode()必定相等;但是反过来,若GetHashCode()相等,那么这两个对象Equals方法比较结果不一定相同。(为了获取最佳性能,hash函数为对象内容生成的数字是随机分布的,这就意味着,内容不同的对象,有可能生成的数字是一样的,但可以认为这种概率非常小)
    下面示例说明:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace ConsoleApplication1
    {
        class People
        {
            private string name;
    
            public string Name
            {
                get { return name; }
                set { name = value; }
            }
    
            public People(string name)
            {
                this.name = name;
            }
        }
    
        class Program
        {
            static void Main(string[] args)
            {
               string a = "hello";
                string b = new string(new char[] { 'h', 'e', 'l', 'l', 'o' });
                Console.WriteLine(a == b); //True
                Console.WriteLine(a.Equals(b));//True
                Console.WriteLine("*********");
                int m = 3;
                int n = 3;
                Console.WriteLine(n == m);//True
                Console.WriteLine(n.Equals(m));//True
                Console.WriteLine("*********");
                object g = a;
                object h = b;
                Console.WriteLine(g == h);//False
                Console.WriteLine(g.Equals(h));//True
                Console.WriteLine(g.GetHashCode() + "   " + h.GetHashCode()); //1025947313   1025947313
                Console.WriteLine("*********");
                People p1 = new People("Jimmy");
                People p2 = new People("Jimmy");
                Console.WriteLine(p1 == p2); //False
                Console.WriteLine(p1.Equals(p2)); //False
                Console.WriteLine(p1.GetHashCode() + "  " + p2.GetHashCode());//43495525  55915408
                Console.WriteLine("*********");
                People p3 = new People("Jimmy");
                People p4 = p3;
                Console.WriteLine(p3 == p4);//True
                Console.WriteLine(p3.Equals(p4));//True
    
            }
        }
    }
    

    在C#中,string 类型的特点有:
    (1)属于基本数据类型;
    (2)是引用类型;
    (3)只读;
    (4) string a="1123"; string b="1123";
    那么a和b指向同一个内存地址;
    但是并非2个相同值相等的字符串就对应同一个内存地址;

    17.进程和线程的区别?

    答:进程是系统进行资源分配和调度的单位;线程是CPU调度和分派的单位,一个进程可以有多个线程,这些线程共享这个进程的资源。

    18.堆和栈的区别?


    栈:由编译器自动分配、释放。在函数体中定义的变量通常在栈上。
    堆:一般由程序员分配释放。用new、malloc等分配内存函数分配得到的就是在堆上。

    19.请指出GAC的含义?

    答:全局程序集缓存。

    20:DataReader与Dataset有什么区别?

    答:
    DataReader和DataSet最大的区别在于,DataReader使用时始终占用SqlConnection,在线操作数据库.任何对SqlConnection的操作都会引发DataReader的异常.因为DataReader每次只在内存中加载一条数据,所以占用的内存是很小的..因为DataReader的特殊性和高性能.所以DataReader是只进的.你读了第一条后就不能再去读取第一条了. DataSet则是将数据一次性加载在内存中.抛弃数据库连接.读取完毕即放弃数据库连接.因为DataSet将数据全部加载在内存中.所以比较消耗内存.但是确比DataReader要灵活.可以动态的添加行,列,数据.对数据库进行回传更新操作

    21.在c#中using和new这两个关键字有什么意义,请写出你所知道的意义

    答:
    using 引入名称空间或者使用非托管资源,使用完对象后自动执行实现了IDisposable接口的类的Dispose方法
    new 新建实例或者隐藏父类方法

    22.什么是虚函数?什么是抽象函数?

    答:
    虚函数:没有实现的,可由子类继承并重写的函数。Virtual CallSomeOne();
    抽象函数:规定其非虚子类必须实现的函数,必须被重写。public abstract void CallSomeOne();

    23.什么是SOAP,有哪些应用。

    答:
    simple object access protocal,简单对象接受协议.以xml为基本编码结构,建立在已有通信协议上(如http,不过据说ms在搞最底层的架构在tcp/ip上的soap)的一种规范Web Service使用的协议

    24.C#中 property 与 attribute的区别,他们各有什么用处,这种机制的好处在哪里?

    答:
    在C#中有两个属性,分别为Property和Attribute,

    • Property比较简单,就是我们常用的get和set,主要用于为类中的private和protected变量提供读取和设置的接口。
    • Attribute用来说明这个事物的各种特征的一种描述。而Attribute就是干这事的。它允许你将信息与你定义的C#类型相关联,作为类型的标注。这些信息是任意的,就是说,它不是由语言本身决定的,你可以随意建立和关联任何类型的任何信息。你可以作用属性定义设计时信息和运行时信息,甚至是运行时的行为特征。关键在于这些信息不仅可以被用户取出来作为一种类型的标注,它更可以被编译器所识别,作为编译时的一种附属条件参加程序的编译。定义属性:属性实际上是一个派生自System.Attribute基类的类。System.Attribute类含有几个用于访问和检查自定义属性的方法。尽管你有权将任何类定义为属性,但是按照惯例来说,从System.Attribute派生类是有意义的

    25.用sealed修饰的类有什么特点?

    答:
    密封,不能继承。

    26.大概描述一下ASP。NET服务器控件的生命周期


    初始化 加载视图状态 处理回发数据 加载 发送回发更改通知 处理回发事件 预呈现 保存状态 呈现 处置 卸载

    27.&和&&的区别


    &是位运算符,表示按位与运算,&&是逻辑运算符,表示逻辑与(and).

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

    • 使用QueryString, 如...?id=1; response.Redirect()
    • 使用Session变量
    • 使用Server.Transfer (目前很少使用)
    • 使用Application
    • 使用Cache
    • 使用HttpContext的Item属性
    • 使用文件
    • 使用数据库
    • 使用Cookie

    28. 什么叫做程序域?

    答:应用程序域可以理解为一种轻量级进程。起到安全的作用,占用资源小

    29. 什么是强命名程序集

    答:程序集需要经过加密签名,强命名程序集可以部署到全局程序集缓存中,成为公共程序集

    30.ASP.NET的身份验证方式有哪些?分别是什么原理

    答:Windows(默认) 用IIS控制
    Form(窗体)用账户
    Passport(密钥)

    31.分析以下代码,完成填空

    string strTmp = "abcdefg某某某";
    int i= System.Text.Encoding.Default.GetBytes(strTmp).Length;
    int j= strTmp.Length;
    

    以上代码执行完后,i= j=
    答:i=13,j=10 (汉子占两个字节)

    32. 根据线程安全的相关知识,分析以下代码,当调用test方法时,i>10 时是否会引起死锁?

    public void test(int i){
      lock(this){
          if(i>10){
          i--;
          test(i);
          }
      }
    }
    

    答:不会引起死锁。因为int是按值传递的,所以每次改变的只是一个副本,因此不会出现死锁,但是如果换成object,那么就会发生死锁

    33. 简要谈一下您对微软.NET架构下remoting和webservice两项技术的理解以及实际中的应用

    答:remoting是利用TCP/IP,二进制传送提高效率。webservice 是利用http,穿透防火墙

    34.启动一个线程用run()还是start()?

    答:启动一个线程用start()方法,使线程所代表的虚拟处理机处于可运行状态,这意味着它可以由JVM调度并执行,并不意味着线程就会立即运行。run()方法可以产生必须退出的标志来停止一个线程。

    相关文章

      网友评论

          本文标题:C#基础面试题

          本文链接:https://www.haomeiwen.com/subject/guokuqtx.html