当前位置 博文首页 > 苏州程序大白的博客:20道C#面试题让你收 Offer 收到不停

    苏州程序大白的博客:20道C#面试题让你收 Offer 收到不停

    作者:[db:作者] 时间:2021-08-12 08:50

    20道C#面试题,让你收Offer收到不停

    在这里插入图片描述

    1、NET Core 与 .NET Framework 的区别?

    问:NET Core 与 .NET Framework 的区别?
    答:.NET Core 就是 .NET Framework 的开源且跨平台版本。但微软毕竟不能维护两个不同的分支,一个跑在Windows上,一个跑在Linux(Unix Like)系统上,所以微软抽象出来一个标准库.NET Standard Library,.NET Core 与 .NET Framework 都必须实现标准库的API ,就这样.NET Core、.NET Framework、Xamarin成了三兄弟,分别为不同的平台服务。

    2、C# 中static关键字的作用?

    问:C# 中static关键字的作用?
    答:对类有意义的字段和方法使用static关键字修饰,称为静态成员,通过类名加访问操作符“.”进行访问; 对类的实例有意义的字段和方法不加static关键字,称为非静态成员或实例成员。
    注: 静态字段在内存中只有一个拷贝,非静态字段则是在每个实例对象中拥有一个拷贝。而方法无论是否为静态,在内存中只会有一份拷贝,区别只是通过类名来访问还是通过实例名来访问。

    3、Java同步关键字的C#版本?
    问:c#是否具有自己的java“ synchronized”关键字版本?
    即在Java中,可以将其指定为函数,对象或代码块,如下所示:

    public synchronized void doImportantStuff() 
    {
       // dangerous code goes here.
    }
    

    要么

    public void doImportantStuff()
     {
       // trivial stuff
    
       synchronized(someLock) {
          // dangerous code goes here.
       }
    }
    

    答:首先-大多数类将永远不需要是线程安全的。使用YAGNI:仅当你知道实际上将要使用它(并对其进行测试)时,才应用线程安全性。
    对于方法级的东西,有[MethodImpl]:

    [MethodImpl(MethodImplOptions.Synchronized)]
    public void SomeMethod() {/* code */}
    

    这也可以用于访问器(属性和事件):

    private int i;public int SomeProperty
    {
        [MethodImpl(MethodImplOptions.Synchronized)]
        get { return i; }
        [MethodImpl(MethodImplOptions.Synchronized)]
        set { i = value; }
    }
    

    请注意,默认情况下,类似字段的事件是同步的,而自动实现的属性则不是:

    public int SomeProperty {get;set;}              // not synchronized
    public event EventHandler SomeEvent;            // synchronized
    

    就个人而言,我不喜欢使用MethodImpl锁this或typeof(Foo)-这是违反最佳做法的实现。首选选项是使用自己的锁:

    private readonly object syncLock = new object();
    public void SomeMethod() 
    {
        lock(syncLock) { /* code */ }
    }
    

    注意,对于类似字段的事件,锁定实现取决于编译器。在较旧的Microsoft编译器中,它是lock(this)/ lock(Type)-但是,在较新的编译器中,它使用Interlocked更新-因此具有线程安全性而没有令人讨厌的部分。

    这允许更精细的用法,并允许使用Monitor.Wait/ Monitor.Pulseetc在线程之间进行通信。

    4、如何在C#中将数据表绑定到datagridview?

    问:需要将 DataTable 绑定到 DataGridView 。我这样做:

        DTable = new DataTable();
        SBind = new BindingSource();
        //ServersTable - DataGridView
        for (int i = 0; i < ServersTable.ColumnCount; ++i)
        {
            DTable.Columns.Add(new DataColumn(ServersTable.Columns[i].Name));
        }
    
        for (int i = 0; i < Apps.Count; ++i)
        {
            DataRow r = DTable.NewRow();
            r.BeginEdit();
            foreach (DataColumn c in DTable.Columns)
            {
                r[c.ColumnName] = //writing values
            }
            r.EndEdit();
            DTable.Rows.Add(r);
        }
        SBind.DataSource = DTable;
        ServersTable.DataSource = SBind;
    

    但我得到的是 数据表中 增加了新的 列到我 的DataGridView 。我不需要这个,我只需要在现有列下编写即可。

    答:有这种办法:

    ServersTable.Columns.Clear();
    ServersTable.DataSource = SBind;

    如果您不想清除所有现有的列,则必须DataPropertyName为每个现有的列进行设置,如下所示:

    for (int i = 0; i < ServersTable.ColumnCount; ++i) 
    {
      DTable.Columns.Add(new DataColumn(ServersTable.Columns[i].Name));
      ServersTable.Columns[i].DataPropertyName = ServersTable.Columns[i].Name;
    }
    

    5、C#WinForms ErrorProvider控件

    问:是否有一种方法来获取具有ErrorProvider图标处于活动状态的控件的列表。即。验证失败的任何控件。我试图避免循环窗体中的所有控件。
    我想显示某种消息,指示表单上有多少错误。由于我的表单包含选项卡,因此我试图使用户知道不活动的选项卡上可能存在错误,因此他们需要检查所有选项卡。

    答:这属于“你怎么 不 知道”
    类别。是您的代码正在调用ErrorProvider.SetError(),您应该可以轻松跟踪仍在活动的错误数量。这是一个小帮手类,使用其SetError()方法更新ErrorProvider。其Count属性返回活动错误的数量:

      private class ErrorTracker {
      private HashSet<Control> mErrors = new HashSet<Control>();
      private ErrorProvider mProvider;
    
      public ErrorTracker(ErrorProvider provider) { 
        mProvider = provider; 
      }
      public void SetError(Control ctl, string text) {
        if (string.IsNullOrEmpty(text)) mErrors.Remove(ctl);
        else if (!mErrors.Contains(ctl)) mErrors.Add(ctl);
        mProvider.SetError(ctl, text);
      }
      public int Count { get { return mErrors.Count; } }
    }
    

    6、C#的比较浮点值?
    问:比较浮点值中不得使用==或!=运算符比较浮点值。大多数浮点值没有精确的二进制表示形式,并且精度有限。如果是这样,比较两个浮点值的最佳方法是什么?

    答:扩展方法对于实现Kevin的建议可能有用:

    public static bool IsEqualTo(this double a, double b, double margin)
    {
        return Math.Abs(a - b) < margin;
    }
    public static bool IsEqualTo(this double a, double b)
    {
        return Math.Abs(a - b) < double.Epsilon;
    }
    

    现在,您可以执行以下操作:
    if(x1.IsEqualTo(x2)) ...if(x1.IsEqualTo(x2, 0.01)) ...
    只需将更IsEqualTo改为更合适的名称,或double.Epsilon在需要时将默认边距更改为比更好的值。

    7、C#:DataGridView控件中的多行文本
    问:DataGridView控件是否可以在单元格中显示多行文本?

    答:可以将DefaultCellStyle.WrapModecolumn的属性设置为DataGridViewTriState.True。之后,单元格中的文本将正确显示。
    示例(DataGridView一栏):

    dataGridView1.Columns[0].DefaultCellStyle.WrapMode = DataGridViewTriState.True;
    dataGridView1.Rows.Add("test" + Environment.NewLine + "test");
    

    (Environment.NewLine= \r\n在Windows中)

    8、C#泛型类型的集合

    问:有一个通用类:

    public class MyClass<T> 
    {
      public T Value;
    }
    

    我想实例化几个项目,例如…

    new MyClass<string>new MyClass<int>
    

    …并将它们添加到集合中。如何定义集合,使其可以容纳泛型类型列表?然后,我想在某个时刻迭代集合,并使用Value属性。可能?

    答:泛型类从非泛型基类继承,或实现一个非泛型接口。然后,拥有此类型的集合,并将其转换为用于访问集合内容的任何代码。
    这是一个例子:

    public abstract class MyClass
    {
        public abstract Type Type { get; }
    }
    public class MyClass<T> : MyClass
    {
        public override Type Type
        {
            get { return typeof(T); }
        }
    
        public T Value { get; set; }
    }
    // VERY basic illustration of how you might construct a collection// of MyClass<T> objects.public class MyClassCollection
    {
        private Dictionary<Type, MyClass> _dictionary;
    
        public MyClassCollection()
        {
            _dictionary = new Dictionary<Type, MyClass>();
        }
    
        public void Put<T>(MyClass<T> item)
        {
            _dictionary[typeof(T)] = item;
        }
    
        public MyClass<T> Get<T>()
        {
            return _dictionary[typeof(T)] as MyClass<T>;
        }
    }
    

    9、C# 中如何实现线程同步?

    问:C# 中如何实现线程同步?

    答:
    (1)方法一:阻塞(调用Sleep()或Join())
    (2)方法二:加互斥锁lock
    (3)方法三:信号和句柄(AutoResetEvent/ManualResetEvent,调用Set()和WaitOne())

    10 、C#中堆和栈的区别?

    问:C#中堆和栈的区别?

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

    存放在栈中时要管存储顺序,保持着先进后出的原则,他是一片连续的内存域,有系统自动分配和维护;