zoukankan      html  css  js  c++  java
  • 最近找工作面的面试题目汇总(二)

    引言

    今天继续的是去那几家面试公司的一些面试题目,适合刚出来或者两三年经验的,大牛可以适量吐槽下,找工作的可以补补基础。

    这系列的第一篇文章请查看这里:最近找工作面的面试题目汇总(一)

    1.请从中选择引用类型或值类型

    说起题,我们不由得会想到几个名词:栈和堆,值类型和引用类型,装箱和拆箱。

    这些概念可是C#的入门基础呀,咱们还是要搞懂的,详细可以查看参考文章。

    这里要提下一个知识点:C#新手都有一个误区:值类型的值都是保存在栈里,实际应该是:值类型的值是在它声明的位置存储的。即局部变量(参数)的值会在栈里,而当值类型作为引用类型的类型成员的话,会跟随对象,即存储在托管堆里。

    顺便提供几张经典图片便于读者理解:

    image

    image

    最后在这些概念里,我觉得比较重要的精华提要:

    1. 对于栈和堆的概念,我们声明值类型和引用类型的时候,为什么会分配两种内存而不是一种呢?只要我们仔细想一下,基本类型他们并不复杂,很多时候只包含简单的值,比如 i=1,而对象类型则相对复杂,它们则会引用其他对象或基本类型。简单来说,对象类型需要动态内存而基本类型则需要静态内存。若需要分配动态内存,那么就分配到堆上;反之在栈上。
    2. 对于值类型和引用类型的概念,值类型,它们的内存值都分配在栈上,当我们把一个int值分配给另外一个int值时,需要创建一个完全不同的拷贝。换句话说,你可以改变其中任何一个而不会影响另外一个。这种数据类型被称为值类型;引用类型,当我们创建一个对象,并把一个对象赋给另外一个对象时,它们的指针指向相同的内存(如下图,当我们把obj赋给obj1时,它们指向相同的内存)。换句话说,我们改变其中一个,会影响到另外一个。

    参考文章

    1. 图解C#的值类型,引用类型,栈,堆,ref,out
    2. 6个重要的.NET概念:栈,堆,值类型,引用类型,装箱,拆箱强烈推荐此篇文章
    3. .NET下的内存分配机制
    4. 从栈和堆中来看值传递和引用传递

    2.判断一个string变量是否为空

    最普通的用法当然就是:

    • s.Length == 0
    • s == string.Empty
    • s == ""

    效率上:s.Length == 0 > s == string.Empty > s == ""

    不过 net 2.0后,可用String.IsNullOrEmpty(s) 来进行判断

    参考文章

    String.IsNullOrWhiteSpace和String.IsNullOrEmpty的区别

    3.Lock的作用

    关于lock的介绍就到这里,有下面几点需要注意的地方

    1. lock的是引用类型的对象,string类型除外。
    2. lock推荐的做法是使用静态的、只读的、私有的对象。
    3. 保证lock的对象在外部无法修改才有意义,如果lock的对象在外部改变了,对其他线程就会畅通无阻,失去了lock的意义。

    还有摘自本篇评论的精彩回复:

    this 表示的就是当前实例,当你再new一个的时候,锁定的就不再是同一个对象了。 不能锁定值类型的原因是,当这个值类型传递到另一个线程的时候,会创建一个副本,锁定的也不再是同一个对象了。 锁定字符串带来的问题是,字符串在CLR中会暂存在 内存中,如果有两个变量被分配了相同的字符串内容,那么这两个引用会指向同一块内存,实际锁定也就是同一个对象,这就会导致整个应用程序的阻塞。所以锁定字符串是非常危险的行为。

    参考文章:

    1.[C#基础]说说lock到底锁谁?](http://www.cnblogs.com/wolf-sun/p/4209521.html)

    4.abstract class 和 interface 有什么区别

    这篇已经有提过了:请参阅:最近找工作面的面试题目汇总(一)

    5.关键字params是什么

    参考文章:

    为了将方法声明为可以接受可变数量参数的方法,我们可以使用params关键字来声明数组

    要求:

    1. 在方法声明中的 params 关键字之后不允许任何其他参数,并且在方法声明中只允许一个 params 关键字
    2. 该参数必须标识一个一维数组,但类型不限,对该参数传递null或者0个数目的数组的引用都是合法的

    参考文章:

    1. C# 参数关键字params
    2. C#中的params关键字的用法

    6.怎么获取用户请求的Url地址

    1. 获取 完整url:
    string url=Request.Url.ToString(); 
    

    参考文章:

    1. asp.net获取当前网址url

    写出三元运算符实例

    这个我就不说了。 ?:

    7.说明Stack和Queue的区别

    1.Queue的定义

    Queue是先进先出(first in first-out)数据结构,表示放进queue的第一个数据,会是第一个拿出来使用

    示例:

    //建立Queue的对象
                var myqueue = new Queue<string>();
                //新增数据进入queue
                myqueue.Enqueue("第1个");
                myqueue.Enqueue("第2个");
                myqueue.Enqueue("第3个");
                //查看queue的所有资料
                foreach (string queue in myqueue)
                {
                    Console.WriteLine(queue);
                }
                //使用Peek()方法查看queue里的第一条数据
                Console.WriteLine("");
                Console.WriteLine("使用peek方法的輸出值:" + myqueue.Peek());
                //使用Dequeue()方法从queue中拿出值
                //记得是先进先出的获取方法
                Console.WriteLine("第一个被我拿走了:" + myqueue.Dequeue());
                //查看剩下的值
                Console.WriteLine("查看myqueue剩下的值");
                foreach (string queue in myqueue)
                {
                    Console.WriteLine(queue.ToString());
                }
                //查看某位置的值
                Console.WriteLine("查看特定位置的值");
                Console.WriteLine(myqueue.ElementAt(1));
    

    运行结果

    第1个
    第2个
    第3个
    
    使用peek方法的輸出值:第1个
    第一个被我拿走了:第1个
    查看myqueue剩下的值
    第2个
    第3个
    查看特定位置的值
    第3个
    第3个
    第2个
    第1个
    
    Peek看到的数据:第3个
    被拿走了:第3个
    查看剩下的数据
    第2个
    第1个
    

    2.Stack的定义

    Stack为后进先出(first-in last-out)的数据结构,表示第一个进去的数据,反而是最后一个出来。

    示例代码

     //建立Stack对象
                var mystack = new Stack<string>();
                //插入数据
                mystack.Push("第1个");
                mystack.Push("第2个");
                mystack.Push("第3个");
                //查看数据
                foreach(string stack in mystack)
                {
                    Console.WriteLine(stack.ToString());
                }
                //Stack与Queue一样有Peek方法查看第一条数据
                Console.WriteLine("");
                Console.WriteLine("Peek看到的数据:"+mystack.Peek());
    
                //使用Pop方法取出数据
                Console.WriteLine("被拿走了:"+mystack.Pop());
                Console.WriteLine("查看剩下的数据");
                foreach (string stack in mystack)
                {
                    Console.WriteLine(stack.ToString());
                }
    

    运行结果

    第3个
    第2个
    第1个
    
    Peek看到的数据:第3个
    被拿走了:第3个
    查看剩下的数据
    第2个
    第1个
    

    参考文章:

    1..NET源码Stack和Queue的实现

    2.C#資料群集系列菜單-『Queue與Stack』

    8.Overload和Override的区别

    1.Overload的定义

    重载应该叫overload,重载某个方法是在同一个类或父子关系类中发生的!重载(overload)是提供了一种机制, 相同函数名通过不同的返回值类型以及参数来表来区分的机制

    overload:  同一类中或父子关系类中皆可.
                       public string ToString(){return "a";}
                       public string ToString(int id){return id.ToString();}
    

    2.Override的定义

    重写叫override,重写是在子类中重写父类中的方法。重写(override)是用于重写基类的虚方法,这样在派生类中提供一个新的方法

    override:   父类:public virtual string ToString(){return "a";}
                       子类:public override string ToString(){return "b";}
    

    3.两者间的区别

    很本质的区别就是看函数特征:覆写(Override)的两个函数的函数特征相同,重载(Overload)的两个函数的函数名虽然相同,但函数特征不同。

    1. override 是在继承的时候,如果你写的函数与要继承的函数函数特征相同,那么,加上这个关键字,在使用这个子类的这个函数的时候就看不见父类(或超类)的函数了,它被覆盖掉了。
      比如:Derived继承了Base,Base里面有void A(int a) ,那么如果你Derived里面觉得A写得不好或不适合这个类,你想重新再写一遍A里的代码,那么就写override void A(int a)这样,原来的那个函数就被你新写的这个覆盖掉了。
      overload 是重载,就是说函数名相同,函数特征不同,系统会根据你提供的参数来调相应的函数。比如:void A(int a)和void A(int a,int b) ,如果你用的是A(1)那么调的是第一个,如果是A(1,1)那么调的是第二个。

    参考文章:

    1. C#中override和overload的区别

    9. using的意义

    简述:

    提供能确保正确使用 IDisposable 对象的方便语法。它的用途就是清理非托管资源,不受GC控制的资源。Using结束后会隐式的调用Disposable方法

    1. 有许多其他类别的非托管资源和封装这些资源的类库类型,所有这些类型都必须实现IDisposable接口,而using语句确保即使在调用对象上的方法时发生异常Dispose方法也会被调用。
    2. 实际上,将对象放入 try 块中并在finally块中调用Dispose一样可以达到同样的效果,而这功能就是编译器转换using语句的方式。

    以下两段代码的作用是一致的

    using (Font font1 = new Font("Arial", 10.0f)) 
    {
        byte charset = font1.GdiCharSet;
    }
    
     {
      Font font1 = new Font("Arial", 10.0f);
      try
      {
        byte charset = font1.GdiCharSet;
      }
      finally
      {
        if (font1 != null)
          ((IDisposable)font1).Dispose();
      }
    }
    

    参考文章:

    1. using 语句(C# 参考)
    2. 三种C# using的用法

    10.List是什么

    因为ArrayList存在不安全类型与装箱拆箱的缺点,所以出现了泛型的概念。List类是ArrayList类的泛型等效类,它的大部分用法都与ArrayList相似,因为List类也继承了IList接口。最关键的区别在于,在声明List集合时,我们同时需要为其声明List集合内数据的对象类型。

    优点

    1. 类型安全
    2. 性能增强
    3. 代码服用

    参考文章:

    1. 数组排序方法的性能比较(3):LINQ排序实现分析
    2. C# 泛型List的定义、作用、用法
    3. C#中数组、ArrayList和List三者的区别
  • 相关阅读:
    SQL Server 2008R2中取得详细日期到毫秒级
    SQL Server Analysis Services无法启动
    SQL Server 2008R2编写脚本时智能提示功能丢失的处理
    SQL Server使用Linkserver连接Oracle
    好用的eclipse快捷键
    今天项目出现的问题总结
    8.2微信小页面问题总结
    SpringBoot整合rabbitmq
    初学Netty(杰哥好久不见)
    消息队列RabbitMQ学习
  • 原文地址:https://www.cnblogs.com/renyiqiu/p/6683893.html
Copyright © 2011-2022 走看看