【C#】面试题整理

时间:2021-08-28 06:20:41

1.C#中类是否支持多继承?请说明原因。
答:不支持,需要用接口来实现多继承

2.我们都知道一个类可以有多个构造函数,并且C#会在我们创建类的时候默认的提供一个无参的构造函数,,当我实现了另外一个有参数的构造函数的时候,我还能调用无参数的构造函数吗?请说明原因。
答:不能,因为一旦你实现了一个构造函数,C#就不会再提供默认的构造函数了,所以需要自己手动写入一个无参数的构造函数。


3.请简略描述重载和重写的区别?
答:方法重载提供了一个相同的方法但是方法签名的参数不同的调用的实现。
      重写提供了子类中改变父类方法行为的实现。


4.请问能设置类A可被继承,但类A中的某个方法不能被重写吗?
答:能,将类A的修饰符标记为public、标记类A中的不允许重写的方法为sealed
sealed关键字不仅可以限制类,也可以限制方法。


5.const和readonly有什么区别?
答:const关键字用来声明编译时的常量
      readonly用来声明运行时的常量


6.什么时候必须声明一个类为抽象类?
答:(1)当这个类中有抽象方法的时候,必须声明类为抽象类
       (2)该类没有完全实现父类的抽象方法时,也需要声明为抽象类



7.接口和抽象类的区别是什么?
答:接口中所有的方法都不能有实现,并且不能指定方法的修饰符
    抽象类中可以有方法的实现,也可以指定方法的访问修饰符
    第一个继承接口的类必须实现接口里的所有方法
    而抽象类中抽象方法的实现是由第一个非抽象的派生类来实现


8.类的私有成员会被子类继承吗?请说明原因。
答:会被子类继承,但是不能被访问。所以看上去是不能被继承的,实际上确实被继承了。


9.请写出C#中的单例模式
    答:
  public class Single
    {
        private static Single instance;
        private Single (){}
        public static Single GetInstance ()
        {
            if (instance == null) {
                instance = new Single ();
            }
            return instance;
        }
    }


10.现有一个整数number,请写一个方法判断这个整数是否是2的N次方
答:
private static bool GetFlag(int num)
        {
        if (num < 1) return false;
        return (num & num - 1) == 0;
     }

11.追加一个双重锁定的单例模式

using System; using System.Collections.Generic; /// <summary> /// 适用于在多线程的情况下保证只有一个实例化对象的情况,例如银行的操作系统 /// </summary> namespace DoubleLockInstance { //---------------------------------- // 双重锁定单例 public sealed class Singleton { // 定义一个类对象,用于内部实现 private static Singleton myInstance; // readonly - 这个成员只能在“类初始化”时赋值 ,所谓的类初始化,就是直接在类里面初始化 // 变量标记为 readonly,第一次引用类的成员时创建实例 private static readonly object lockRoot = new object (); // 设置构造方法为私有,这样就不能在外部实例化类对象了 private Singleton () { } // 实例化对象的方法 public static Singleton GetInstance () { // 外部不能实例化对象,但是能调用类里面的静态方法 // 外部需要调用这个方法来使用类对象,如果对象不存在就创建 // 这里面使用两个判断是否为null的原因是,我们不需要每次都对实例化的语句进行加锁,只有当对象不存在的时候加锁就可以了 if (myInstance == null) { // 锁定的作用就是为了保证当多线程同时执行这句代码的时候保证对象的唯一性 // 锁定会让同时执行这段代码的线程排队执行 // lock里面需要用一个已经存在的对象来判断,所以不能使用myInstance lock (lockRoot) { // 这里还需要一个判断的原因是,如果多线程都通过了外层的判断进行排队 // 那将会实例化多个对象出来,所以这里还需要进行一次判断,保证线程的安全 if (myInstance == null) { myInstance = new Singleton (); } } } return myInstance; } } }