C#测试题(三)

C#测试题(三)

一.简答题

1.简述C#中的所有访问修饰符和访问权限

public(公开的):应用于所有类和类成员,可访问范围:任何代码都可以访问
private(私有的):应用于所有类和类成员,可访问范围:当前类自身
protected(受保护的):应用于类和内嵌类的所有成员, 可访问范围:当前类自身,所有的子类可以访问,同一程序集其他类不可以访问,其他程序集中可以通过继承也可以访问
Internal:应用于类和内嵌类的所有成员, 可访问范围:当前类自身,同一程序集的其他类可以通过实例化访问,同一程序集中的子类也可以访问,其他程序集中不管是不是子类都无法访问
protected Internal/Internal protected:应用于类和内嵌类的所有成员, 可访问范围:当前类自身,同一程序集的其他类可以通过实例化进行访问,所有子类可以访问,其他程序集中可以通过继承进行访问,但实例化不行

2.简单介绍方法的重载和重写

重写:当一个子类继承一父类,而子类中的方法与父类中的方法的名称,参数个数、类型都完全一致时,就称子类中的这个方法重写了父类中的方法。
重载:一个类中的方法与另一个方法同名,但是参数表不同,这种方法称之为重载方法。

3.方法中的ref参数和out参数的用法是什么?

(1)ref参数(引用传参):当方法结束前必须对ref进行赋值。传进方法中的参数,如果在方法中发生了改变,那么这个参数变量 将永久性发生改变。
(2)out参数:
①可视作是方法的返回值,
②必须对out参数进行赋值
③遇到方法中的形参是out类型,调用时必须带有out参数 ④在调用out类型参数的方法时,准备一个相同类型的变量接收out参数结果,必须带有关键字

4.简单介绍数组和集合的区别?

①、数组声明了元素的类型,集合不声明
②、数组是静态的,有固定大小,创建了就无法改变容量,而集合是动态扩展容量,可以根据需要改变大小.
③、数组存放类型只能是一种,集合可以不是一种

5.简单介绍C#类中的两个特殊函数

(1)构造函数:如果类中没有声明构造函数,那么系统会自动生成一个构造函数,如果声明了构造函数,那么系统将不会再理会,构造函数可以重载,作用:当类被实例化的时候执行的函数
(2)析构函数:析构函数是实现销毁一个类的实例的方法成员。析构函数不能有参数,当类生成的对象被释放时自动生成的函数。

6.简单介绍static静态的用法和特性

用法:

①、Static可以修饰类,使类成为静态类。这样在此类中只能定义静态的方法和静态的变量。
②、static可以修饰变量,这个变量只能是成员变量,不能是局部的。
既不能修饰方法体中的变量,以及形式参数。
③、static可以修饰方法,Main方法必须用static修饰,因为它是与程序共存亡的,是程序的入口和结束的大门。

特性:

①、只会在编译时分配空间,程序真正执行时,是不会重新分配空间的.
②、值能变,但是其指向地址不会变
③、用static声明了的变量不会被GC(辣鸡回收机制)所回收. 所以使用时需要注意

7.C#中的委托是什么?事件是不是委托?

委托是一种在对象里保存方法引用的类型,同时也是一种类型安全的函数指针。把一个方法作为参数带入另一个方法,也可以理解为数据类型,赋值了一个方法
事件是一种特殊的委托。

8.请详述类(class)和结构(struct)的异同

①、值类型与引用类型
结构Struct是值类型:值类型在堆栈上分配地址,所有的基类型都是结构类型,例如:int 对应System.int32 结构,string 对应 system.string 结构 ,通过使用结构可以创建更多的值类型。
类Class是引用类型:引用类型在堆上分配地址。
结构是值类型所以结构之间的赋值可以创建新的结构,而类是引用类型,类之间的赋值只是复制引用。
②、继承性
结构:不能从另外一个结构或者类继承,本身也不能被继承,虽然结构没有明确的用sealed声明,可是结构是隐式的sealed .
类:完全可扩展的,除非显示的声明sealed 否则类可以继承其他类和接口,自身也能被继承
③、内部结构:
结构:
没有默认的构造函数,但是可以添加构造函数
没有析构函数
没有 abstract 和 sealed(因为不能继承)
不能有protected 修饰符
可以不使用new 初始化
类:
有默认的构造函数
有析构函数
可以使用 abstract 和 sealed
有protected 修饰符
必须使用new 初始化
同:
①、虽然结构与类的类型不一样,可是他们的基类型都是对象(object),c#中所有类型的基类型都是object
②、虽然结构的初始化也使用了New 操作符可是结构对象依然分配在堆栈上而不是堆上,

9.介绍C#中的string和StringBuilder的用法

string是个基础类型,每次赋值都会重新分配内存空间,string是对System.String命名空间起的一个名字。String类有不可改变性,每次执行字符操作时,都会创建一个新的String对象。
StringBuilder:使用前先进行实例化,支持空参数构造,在对象实例化后就不再重新分配内存。StringBuilder是由Char数组构成的。构建新的StringBuilder时能设置容量大小,当添加字符串,超过已分配的数组大小时,就会创建一个新的数组,此时容量会翻倍,旧空间自动销毁。

10.什么是抽象函数?什么是虚拟函数?两者的区别是什么?

①、virtual修饰的方法必须有实现,而abstract修饰的方法一定不能实现。
②、virtual可以被子类重写,而abstract必须被子类重写。
③、如果类成员被abstract修饰,则该类前必须添加abstract,因为只有抽象类才可以有抽象方法。
④、无法创建abstract类的实例,只能被继承无法实例化,比如: BaseTest2 base2 = new BaseTest2();将出现编译错误:抽象类或接口不能创建实例。
⑤、C#中如果要在子类中重写方法,必须在父类方法前加virtual,在子类方法前添加override,这样就避免了程序员在子类中不小心重写了父类方法。
⑥、abstract方法必须重写,virtual方法必须有实现

11.C#中的接口和类有什么异同?

不同点:

不能直接实例化接口。
接口不包含方法的实现。
接口可以多继承,类只能单继承。
类定义可以在不同的源文件之间进行拆分。

相同点:

接口、类和结构都可以从多个接口继承。
接口类似于抽象基类:继承接口的任何非抽象类型都必须实现接口的所有成员。
接口和类都可以包含事件、索引器、属性。

12.进程和线程的区别是什么?

①、线程作为调度和分配的基本单位,进程作为拥有资源的基本单位
②、不仅进程之间可以并发执行,同一个进程的多个线程之间也可并发执行
③、进程是拥有资源的一个独立单位,线程不拥有系统资源,但可以访问隶属于进程的资源.
④、在创建或撤消进程时,由于系统都要为之分配和回收资源,导致系统的开销明显大于创建或撤消线程时的开销。
也可以理解为一个程序就是一个进程,一个进程有多个线程

13.请详述C#中的继承问题

①、子承父业:子类会继承父类的属性,构造,行为
②、父亲具有的,儿子不一定具有,子类具有的,父类也不一定具有
当父类只有带参构造,子类自动会要有带参构造
③、C#不支持多重继承,但是可以多重接口继承
④、关键字this:当前类自己,base:代表当前类的亲父类
⑤、实例化过程(对象创建过程,先调用的最终父类的构造函数然后依次往下调用当前类)
⑥、析构过程(对象销毁的过程,从自己开始销毁直到最终父类)

14.简单介绍break,continue,return的区别?

return:跳出当前循环,直到代码块结束
break:只跳出当前循环,执行代码之后的代码
continue:只跳出当前本次循环,执行下一次循环

15.NET和C#有什么区别

.NET一般指 .NET FrameWork框架,它是一种平台,一种技术。
C#是一种编程语言,可以基于.NET平台的应用。

二、算法

1.使用递归算法计算斐波那契数列
static void Main(string[] args)
  {
            Console.WriteLine("请输入你想要计算的斐波那数列:");
            int i = int.Parse(Console.ReadLine());
            int result = Getres(i);
            Console.WriteLine("计算出{0}位的斐波那数列为{1}",i,result);
            Console.ReadLine();
  }
       static int Getres(int i)
        {
            int res = 0;
            if (i==1)
            {
                res = 0;
            }
            else if (i==2)
            {
                res = 1;
            }
            else
            {
                res = Getres(i - 1) + Getres(i - 2);
            }
            return res;
        }

2.在1-20这20个数中求出7个不重复的随机数
static void Main(string[] args)
        {
            int[] array= new int[7];
            Random r = new Random();
            for (int i = 0; i < array.Length; i++)
            {
                array[i] = r.Next(1,21);
                if (i>0)
                {
                    for (int j = 0; j < i; j++)
                    {
                        if (array[i]==array[j])
                        {
                            i--;
                        }
                    }
                }
            }
            for (int i = 0; i < array.Length; i++)
            {
                Console.Write(array[i]+"");
            }
            Console.ReadLine();

3.一列数的规则如下: 1、1、2、3、5、8、13、21、34… 求第30位数是多少,用递归算法实现.
public class MainClass
{
   public static void Main()
   {
     Console.WriteLine(Foo(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);
                }
         }
}

发布了96 篇原创文章 · 获赞 147 · 访问量 9808

猜你喜欢

转载自blog.csdn.net/chonbi/article/details/104117620