C#面试题

来源:互联网 发布:淘宝菜鸟电子面单申请 编辑:IT博客网 时间:2019/09/17 14:17

C#面试题集锦

1、简述 private、 protected、 public、 internal 修饰符的访问权限。

private : 私有成员, 在类的内部才可以访问。

protected : 保护成员,该类内部和继承类中可以访问。

public : 公共成员,完全公开,没有访问限制。

internal: 当前程序集内可以访问。


4、C#中的委托是什么?事件是不是一种委托?事件和委托的关系。

委托可以把一个方法作为参数代入另一个方法。

委托可以理解为指向一个函数的指针。

委托和事件没有可比性,因为委托是类型,事件是对象,下面说的是委托的对象(用委托方式实现的事件)和(标准的event方式实现)事件的区别。事件的内部是用委托实现的。因为对于事件来讲,外部只能“注册自己+=、注销自己-=”,外界不可以注销其他的注册者,外界不可以主动触发事件,因此如果用Delegate就没法进行上面的控制,因此诞生了事件这种语法。事件是用来阉割委托实例的,类比用一个自定义类阉割List。事件只能add、remove自己,不能赋值。事件只能+=、-=,不能= 。加分的补充回答:事件内部就是一个private的委托和addremove两个方法

 

面试聊:用Reflector查看.Net的类的内部实现,解决问题。

 

5、override与重载(overload)的区别

重载是方法的名称相同。参数或参数类型不同,进行多次重载以适应不同的需要。重载(overload)是面向过程的概念。

Override 是进行基类中函数的重写。Override是面向对象的概念

 

6、C#中索引器是否只能根据数字进行索引?是否允许多个索引器参数?

参数的个数和类型都是任意的。加分的补充回答:用reflector反编译可以看出,索引器的内部本质上就是set_itemget_item方法

 

基础知识:

索引的语法:

public string this[string s],通过get、set块来定义取值、赋值的逻辑

索引可以有多个参数、参数类型任意

索引可以重载。

如果只有get没有set就是只读的索引。

索引其实就是set_Item、get_Item两个方法。

 

7、属性和public字段的区别是什么?调用set方法为一个属性设值,然后用get方法读取出来的值一定是set进去的值吗?

属性可以对设值、取值的过程进行非法值控制,比如年龄禁止设值负数,而字段则不能进行这样的设置。虽然一般情况下get读取的值就是set设置的值,但是可以让get读取的值不是set设置的值的,极端的例子。Public Age{get{return 100;}set{}}。加分的补充回答:用reflector反编译可以看出,属性内部本质上就是set_***get_***方法,详细参考传智播客.net培训视频中串讲.net基础的部分。

    classPerson

    {

        publicint Age

        {

            get

            {

                return 3;

            }

            set

            {

 

            }

        }

    }

            Personp1 = new Person();

            p1.Age = 30;

            p1.Age++;

            Console.Write(p1.Age);//输出3

 

10、关于拆箱装箱:

1)什么是装箱(boxing)和拆箱(unboxing)? (*)

Object是引用类型,但是它的子类Int32竟然不能去Object能去的“要求必须是引用类型”

的地方,违反了继承的原则,所以需要把Int32装在Object中才能传递。

装箱:从值类型接口转换到引用类型。

拆箱:从引用类型转换到值类型。 

            objectobj = null;//引用类型

            obj = 1;//装箱,boxing。把值类型包装为引用类型。

            inti1 = (int)obj;//拆箱。unboxing

 

2)下面三句代码有没有错,以inboxing或者unboxing为例,解释一下内存是怎么变化的

int i=10;

object obj = i;

int j = obj;

 

分析:在inboxing(装箱)时是不需要显式的类型转换的,不过unboxing(拆箱)需要显式的类型转换,所以第三行代码应该改为:

3 int j = (int)obj;   

要掌握装箱与拆箱,就必须了解CTS及它的特点:

   NET重要技术和基础之一的CTS(CommonType System)。CTS是为了实现在应用程序声明和使用这些类型时必须遵循的规则而存在的通用类型系统。.Net将整个系统的类型分成两大类 :值类型和引用类型。

CTS中的所有东西都是对象;所有的对象都源自一个基类——System.Object类型。值类型的一个最大的特点是它们不能为null,值类型的变量总有一个值。为了解决值类型不可以为null,引用类型可以为null的问题,微软在.Net中引入了装箱和拆箱:装箱就是将值类型用引用类型包装起来转换为引用类型;而从引用类型中拿到被包装的值类型数据进行拆箱。   

(*)

object.ReferenceEquals();//用来判断两个对象是否是同一个对象

Console.WriteLine(object.ReferenceEquals(3,3));//因为两个3被装到了两个箱子中,所以是false

 

Equals ==的关系

 

12、CTS、CLS、CLR分别作何解释(*)把英文全称背过来。

C#和.Net的关系。

 

C#只是抽象的语言,可以把C#编译生成Java平台的二进制代码,也可以把Java代码编译生成.Net平台的二进制代码。所以C#只是提供了if、while、+-*/、定义类、int、string等基础的语法,而Convert.ToInt32、FileStream、SqlConnection、String.Split等都属于.Net的东西。深蓝色是C#的,浅蓝色是.Net的。

C#new→IL:newobj

C#string →.Net中的String

 

类型的差别:.net中的Int32在C#中是int,在VB.Net中是Integer。String、Int32等公共类型。

语法的差别:IL中创建一个对象的方法是L_0001: newobj instance void 索引.C1::.ctor()

C#中是new C1();VB.net中是 Dim c1 As New C1

CTSCommonType System 通用类型系统。Int32、Int16→int、String→string、Boolean→bool。每种语言都定义了自己的类型,.Net通过CTS提供了公共的类型,然后翻译生成对应的.Net类型。

CLSCommonLanguage Specification通用语言规范。不同语言语法的不同。每种语言都有自己的语法,.Net通过CLS提供了公共的语法,然后不同语言翻译生成对应的.Net语法。

CLRCommonLanguage Runtime公共语言运行时,就是GC、JIT等这些。有不同的CLR,比如服务器CLR、Linux CLR(Mono)、Silverlight CLR(CoreCLR)。相当于一个发动机,负责执行IL。

 

13、在dotnet中类(class)与结构(struct)的异同?

Class可以被实例化,属于引用类型,是分配在内存的堆上的。类是引用传递的。

Struct属于值类型,是分配在内存的栈上的。结构体是复制传递的。加分的回答:Int32、Boolean等都属于结构体。

 

14、堆和栈的区别?

栈是编译期间就分配好的内存空间,因此你的代码中必须就栈的大小有明确的定义;局部值类型变量、值类型参数等都在栈内存中

堆是程序运行期间动态分配的内存空间,你可以根据程序的运行情况确定要分配的堆内存的大小。

 

15、能用foreach遍历访问的对象的要求

需要实现IEnumerable接口或声明GetEnumerator方法的类型。

 

16、GC是什么? 为什么要有GC? 

C/C++中由程序员进行对象的回收像学校食堂中由学生收盘子,.Net中由GC进行垃圾回收像餐馆中店员去回收。

GC是垃圾收集器(Garbage Collection)。程序员不用担心内存管理,因为垃圾收集器会自动进行管理。GC只能处理托管内存资源的释放,对于非托管资源则不能使用GC进行回收,必须由程序员手工回收,一个例子就是FileStream或者SqlConnection需要程序员调用Dispose进行资源的回收。

要请求垃圾收集,可以调用下面的方法:GC.Collect()一般不需要手动调用GC.Collect()。当一个对象没有任何变量指向(不再能使用)的时候就可以被回收了。

 

基础知识:当没有任何变量指向一个对象的时候对象就可以被回收掉了,但不一定会立即被回收。

            objectobj = new object();//只有new才会有新对象

            Console.WriteLine(obj);

 

            objectobj2 = obj;

            obj = null;

            obj2 = null;

            Console.WriteLine();

 

 

18、值类型和引用类型的区别?

1.将一个值类型变量赋给另一个值类型变量时,将复制包含的值。引用类型变量的赋值只复制对对象的引用,而不复制对象本身。

2.值类型不可能派生出新的类型:所有的值类型均隐式派生自 System.ValueType。但与引用类型相同的是,结构也可以实现接口。

3.值类型不可能包含 null 值:然而,可空类型功能允许将null 赋给值类型。

4.每种值类型均有一个隐式的默认构造函数来初始化该类型的默认值。 

 

19、C#中的接口和类有什么异同。

 

不同点:

不能直接实例化接口。

接口不包含方法的实现。

接口可以多继承,类只能单继承。

类定义可在不同的源文件之间进行拆分。

相同点:

接口、类和结构都可以从多个接口继承。

接口类似于抽象基类:继承接口的任何非抽象类型都必须实现接口的所有成员。

接口和类都可以包含事件、索引器、方法和属性。

 

基础知识:接口只能定义方法(只能定义行为,不能定义实现也就是字段),因为事件、索引器、属性本质上都是方法,所以接口中也可以定义事件、索引器、属性。

 

20abstractclassinterface有什么区别?

 

相同点:

都不能被直接实例化,都可以通过继承实现其抽象方法。

不同点:

接口支持多继承;抽象类不能实现多继承。

接口只能定义行为;抽象类既可以定义行为,还可能提供实现。

接口只包含方法(Method)、属性(Property)、索引器(Index)、事件(Event)的签名,但不能定义字段和包含实现的方法;

抽象类可以定义字段、属性、包含有实现的方法。 

接口可以作用于值类型(Struct)和引用类型(Class);抽象类只能作用于引用类型。例如,Struct就可以继承接口,而不能继承类。

加分的补充回答:讲设计模式的时候SettingsProvider的例子。

 

21、是否可以继承String类?

String类是sealed类故不可以继承。

 

22、

        staticvoid Main(string[] args)

        {

            Console.WriteLine(GetIt());

            Console.ReadKey();

        }

 

        staticint GetIt()

        {

            inti = 8;

            try

            {

                i++;

                Console.WriteLine("a");

                return i;//把返回值设定为i,然后“尽快”返回(没啥事就回去吧)

            }

            finally

            {

                Console.WriteLine("b");

                i++;

            }

        }

上面程序的执行结果是ab9

 

try{}里有一个return语句,那么紧跟在这个try后的finally {}里的代码会不会被执行,什么时候被执行?

会执行,在return后执行。

 

        static void Main(string[] args)

        {

            //Console.WriteLine(GetIt());

            Console.WriteLine(GetPerson().Age);

            Console.ReadKey();

        }

 

        static Person GetPerson()

        {

            Personp = new Person();

            p.Age = 8;

            try

            {

                p.Age++;

                Console.WriteLine("a");

                returnp;//把返回值设定为i,然后尽快返回(没啥事就回去吧。搞完就走)

            }

            finally

            {

                Console.WriteLine("b");

                p.Age++;

            }

        }

 

 

加分的补充回答(也助记):读取数据库中数据的条数的程序

public int QueryCount()

{

   …..

  try

   {

     return cmd.ExecuteScalar();

   }

  finally

   {

     cmd.Dispose();

   }

}

先执行cmd.ExecuteScalar(),把返回值暂时存起来,然后再去执行finally(钱放在这,我去劫个色),然后把返回值返回。return都是最后执行,但是return后的表达式的计算则是在finally之前。

 

如果C#设计的是先执行cmd.Dispose()再执行return就会出现return执行失败了,因为cmd已经Dispose了。

 

 

28、int、DateTime、string是否可以为null?

 

null表示“不知道”,而不是“没有”。没有年龄和不知道年龄是不一样。

数据库中null不能用0表示。0岁和不知道多少岁不一样。

Sexis zero。《色即是空》

 

            //int i1= null;

            //int? i2= null;//值类型后加?就成了可空数据类型

            ////inti3 = i2;//所以把可空的赋值给一定不能为空的会报错。

            //int i4= (int)i2;//可以显式转换,由程序员来保证一定不为空

            //int? i5= i4;//一定会成功!

 

            //using()→try{]catch{}finally{}

 

 

            //int?是微软的一个语法糖。是一种和int没有直接关系的Nullable类型

 

            Nullable<int> d1 = new Nullable<int>();//int? d1=null;

            Nullable<int> d2 = new Nullable<int>(3);//int? d2=3;

            Console.WriteLine(d1==null);

 

int、DateTime不能,因为其为Struct类型,而结构属于值类型,值类型不能为null,只有引用类型才能被赋值null。string可以为null。

C#中int等值类型不可以为null、而数据库中的int可以为null,这就是纠结的地方。int?就变成了可空的int类型。bool?、DateTime?

            inti1 = 3;

            int?i2 = i1;

            //inti3 = i2;//不能把可能为空的赋值给一定不能为空的变量

            inti3 = (int)i2;//显式转换

可空数据类型经典应用场景:三层中的Model属性的设计。

int?翻译生成.Net的Nullable<int>,CTS。

 

29、using关键字有什么用?什么是IDisposable?

using可以声明namespace的引入,还可以实现非托管资源的释放,实现了IDisposiable的类在using中创建,using结束后会自动调用该对象的Dispose方法,释放资源。加分的补充回答:using其实等价于try……finally,用起来更方便。

 

31、string str = null 与 string str =””说明其中的区别。

答:string str =null 是不给他分配内存空间,而string str = \"\" 给它分配长度为空字符串的内存空间。 string str = null没有string对象,string str = “”有一个字符串对象。

 

string s3 =string.Empty;//反编译发现,string.Empty就是在类构造函数中 Empty = "";

 

 

33.面向对象的语言具有________性、_________性、________性

答:封装、继承、多态。

不要背,脑子中要有联想。

 

34.在.Net中所有可序列化的类都被标记为_____?

答:[serializable]

 

 

36、接口是一种引用类型,在接口中可以声明(   a),但不可以声明公有的域或私有的成员变量。  
  a) 方法、属性、索引器和事件;  

  b) 索引器和字段;    
  c) 事件和字段;  

 

解读:接口中不能声明字段只能声明方法,属性、索引器和事件 最终都编译生成方法。因为字段属于实现层面的东西,只有存取值的时候才会用到字段,所以中接口中不能定义字段。


38. 下列关于C#中索引器理解正确的是(c   )  
  a) 索引器的参数必须是两个或两个以上  
  b) 索引器的参数类型必须是整数型  
  c) 索引器没有名字  
  d) 以上皆非  

40、以下的C#代码,试图用来定义一个接口: 
  public   interface   IFile  
  {  
              int   A;  
              int   delFile()  
              {  
                      A  =   3;  
              }  
              void   disFile();  
  }  
  关于以上的代码,以下描述错误的是(d  )。  
  a) 以上的代码中存在的错误包括:不能在接口中定义变量,所以int   A代码行将出现错误; 
  b) 以上的代码中存在的错误包括:接口方法delFile是不允许实现的,所以不能编写具体的实现函数;  
  c) 代码void   disFile();声明无错误,接口可以没有返回值;  
  d) 代码void   disFile();应该编写为void   disFile(){}; 



42. 声明一个委托public  delegate   int   myCallBack(int   x);   则用该委托产生的回调方法的原型应该是(b  )。 
  a) void   myCallBack(int   x)   ; 
  b) int   receive(int   num)   ; 
  c) string   receive(int   x)   ; 
  d) 不确定的;  

43.StringBuilder 和 String 的区别?

答:String 在进行运算时(如赋值、拼接等)会产生一个新的实例,而 StringBuilder 则不会。所以在大量字符串拼接或频繁对某一字符串进行操作时最好使用 StringBuilder,不要使用 String

 如果要操作一个不断增长的字符串,尽量不用String类,改用StringBuilder类。两个类的工作原理不同:String类是一种传统的修改字符串的方式,它确实可以完成把一个字符串添加到另一个字符串上的工作没错,但是在.NET框架下,这个操作实在是划不来。因为系统先是把两个字符串写入内存,接着删除原来的String对象,然后创建一个String对象,并读取内存中的数据赋给该对象。这一来二去的,耗了不少时间。而使用System.Text命名空间下面的StringBuilder类就不是这样了,它提供的Append方法,能够在已有对象的原地进行字符串的修改,简单而且直接。当然,一般情况下觉察不到这二者效率的差异,但如果你要对某个字符串进行大量的添加操作,那么StringBuilder类所耗费的时间和String类简直不是一个数量级的。 

 

44、.请叙述属性与索引器的区别。 (*)

属性 索引器    

  通过名称标识。 通过签名标识。   

  通过简单名称或成员访问来访问。 通过元素访问来访问。   

  可以为静态成员或实例成员。 必须为实例成员。   

  属性的   get   访问器没有参数。 索引器的  get   访问器具有与索引器相同的形参表。    

  属性的   set   访问器包含隐式   value   参数。 除了  value   参数外,索引器的  set   访问器还具有与索引器相同的形参表。 

 

 

49、您在什么情况下会用到虚方法?它与接口有什么不同?

答案:子类重新定义父类的某一个方法时,必须把父类的方法定义为virtual

在定义接口中不能有方法体,虚方法可以。

实现时,子类可以不重新定义虚方法,但如果一个类继承接口,那必须实现这个接口。

 

50. 不定项选择:

(1) 以下叙述正确的是: B C

A. 接口中可以有虚方法。B. 一个类可以实现多个接口。 C.接口不能被实例化。 D. 接口中可以包含已实现的方法。

(2) 从数据库读取记录,你可能用到的方法有:B C D

      A.ExecuteNonQuery           B. ExecuteScalar      C.Fill                       D. ExecuteReader

(3).对于一个实现了IDisposable接口的类,以下哪些项可以执行与释放或重置非托管资源相关的应用程序定义的任务?(多选)   (       ABCD         )  

  A.Close B.Dispose C.Finalize  

  D.using E.Quit  

(4)以下关于ref和out的描述哪些项是正确的?(多选)   (   ACD   )  

  A.使用ref参数,传递到ref参数的参数必须最先初始化。  

  B.使用out参数,传递到out参数的参数必须最先初始化。  

  C.使用ref参数,必须将参数作为ref参数显式传递到方法。  

  D.使用out参数,必须将参数作为out参数显式传递到方法。 

 

51. 单项选择:

(1)下列选项中,(C)是引用类型。

a)enum类型   b)struct类型 c)string类型   d)int类型

 

(3).下列描述错误的是(D)

a)类不可以多重继承而接口可以;

b)抽象类自身可以定义成员而接口不可以;

c)抽象类和接口都不能被实例化;

d)一个类可以有多个基类和多个基接口;

 

数据)

 

53、public static const int  A =1;这段代码有错误么?

错误:const不能被修饰为static ;因为定义为常量 (const )后就是静态的(static)。

 

54、传入某个属性的set方法的隐含参数的名称是什么?

value,它的类型和属性所声名的类型相同。

 

55、C#支持多重继承么?

类之间不支持,接口之间支持。类对接口叫做实现,不叫继承。 类是爹、接口是能力,能有多个能力,但不能有多个爹。

 

56、C#中所有对象共同的基类是什么?

System.Object

 

 

58、string、String;int、Int32;Boolean、bool的区别

String、Int32、Boolean等都属于.Net中定义的类,而string、int、bool相当于C#中对这些类定义的别名。CTS。

 

 

60、不是说字符串是不可变的吗?string s="abc";s="123"不就是变了吗?(传智播客.Net培训班原创模拟题)

String是不可变的在这段代码中,s原先指向一个String对象,内容是 "abc",然后我们将s指向"123",那么s所指向的那个对象是否发生了改变呢?答案是没有。这时,s不指向原来那个对象了,而指向了另一个 String对象,内容为"123",原来那个对象还存在于内存之中,只是s这个引用变量不再指向它了。

 

61、是否可以从一个static方法内部发出对非static方法的调用?

不可以。因为非static方法是要与对象关联在一起的,必须创建一个对象后,才可以在该对象上进行方法调用,而static方法调用时不需要创建对象,可以直接调用。也就是说,当一个static方法被调用时,可能还没有创建任何实例对象,如果从一个static方法中发出对非static方法的调用,那个非static方法是关联到哪个对象上的呢?这个逻辑无法成立,所以,一个static方法内部不能发出对非static方法的调用。

 

63、说出一些常用的类、接口,请各举5个

要让人家感觉你对.Net开发很熟,所以,不能仅仅只列谁都能想到的那些东西,要多列你在做项目中涉及的那些东西。就写你最近写的那些程序中涉及的那些类。

常用的类:StreamReader、WebClient、Dictionary<K,V>、StringBuilder、SqlConnection、FileStream、File、Regex、List<T>

常用的接口:IDisposable、IEnumerable、IDbConnection、IComparable、ICollection、IList、IDictionary

要出乎意料!不要仅仅完成任务!笔试不是高考!处处要显出牛!

 

说出几个开源软件?MySQL、Linux、 Discuz、Apache、Paint.Net、Android、Chrome、Notepad++……

开源项目有一些是开发包。开源软件指的是可以直接用的。Jquery、NPOI、ASP.Net MVC、Silverlight  Toolkit、AJAX toolkit、json.net

 

得瑟!

65、编写一个单例(Singleton)类。

参考复习ppt。

把构造函数设置为private,设置一个public、static的对象实例

public FileManager

{

    privateFileManager(){}

   public readonly static FileManager Instance = new FileManager();

}

 

扩展:搜“C#  Singleton”,有线程安全的更牛B的实现

 

73、下面的程序执行结果是什么?(传智播客.Net培训班原创模拟题)

    classPerson

    {

        publicint Age { get;set; }

    }

            inti1 = 20;

            inti2 = i1;

            i1++;

            Console.WriteLine(i2);

 

            Personp1 = new Person();

            p1.Age = 20;

            Personp2 = p1;

            p1.Age++;

            Console.WriteLine(p2.Age);

答案:

20

21

 

解释:引用类型和值类型的区别。

 

76、下面程序的执行结果是什么?(传智播客.Net培训班原创模拟题)

            inti = 10;

            Console.WriteLine(i++);

            Console.WriteLine(++i);

            Console.WriteLine(i=20);

             Console.WriteLine(i==20);

答案:

10

12

20

True       

解答:前两个参考第80题,i++表达式的值为i自增之前的值,所以打印10,执行完成后i变成11,执行++i的时候表达式的值为自增以后的值12。C#中赋值表达式的值为变量被赋值的值,因此最后一个就输出i赋值后的值20

while((line=reader.ReadLine())!=null)

{

}

 

下面程序的执行结果是什么?

boolb=false;

if(b=true)

{

    Console.WriteLine("yes");

}

else

{

    Console.WriteLine("no");

}

 

 

85、开放式问题:你经常访问的技术类的网站是什么?

博客园(www.cnblogs.com)、csdn、codeplex、codeproject、msdn文档、msdn论坛(遇到问题先到网上搜解决方案,还不行就问同事,同事也解决不了就去MSDN论坛提问,一定能得到解决)。Cnbeta.com。

 

86、你对.net的GC的理解

GC是.Net的垃圾收集器,可以进行内存资源的回收,程序员无需关心资源的回收,当一个对象没有任何引用的时候就可以被回收了。一个对象可以被回收并不意味着一定会被立即回收,GC会选择时机进行回收。可以调用GC.Collect()让GC立即回收。GC不能回收非托管资源,对于非托管资源一般都实现了IDisposable接口,然后使用using关键字进行资源的回收。

 

 

 

 

122、下面是一个由*号组成的4行倒三角形图案。要求:1、输入倒三角形的行数,行数的取值3-21之间,对于非法的行数,要求抛出提示非法行数!2、在屏幕上打印这个指定了行数的倒三角形。

*******

*****

***

*

136.refout的区别?

137.A字段Idnumberic(18,0),哪个SQL语句是错误的:

select *from A where id='';

select *from A where id='13';

select *from A where id=null;

select *from A where id=' 13';

 

3、Math.Round(11.5)、Math.Round(11.3)、Math.Round(-11.5)、Math.Round(-11.3)的值各是多少?

答案:Round 四舍五入:Math.Round(-11.5)=-12,因为是按照绝对值考虑。

扩展:Math.Ceiling(-11.6)=-11,因为负数的天花板也在上面。

Math.Floor(-11.5)=-12

4、short s=1;s=s+1;有错吗?short s=1;s+=1;有错吗?

答案:第一个有错,因为1是int类型,int+short结果是int,无法隐式转换,改为s = (short)(s +1);就可以了。

第二个没错,经过反编译发现编译器自动优化成s = (short)(s + 1);

 

5、产生一个int数组,长度为100,并向其中随机插入1-100,并且不能重复。(要求使用两种方法)

 

解答:Random类是一个伪随机数算法,原理:

r(n)=(sed+r(n-1))%100;

    classMyRand

    {

        privateint seed;

        privateint prevNumber = 10;

        publicMyRand(int seed)

        {

            this.seed= seed;

        }

 

        public int Next()

        {

            intnewRand = (seed + prevNumber) % 100;

            prevNumber = newRand;

            returnnewRand;

        }

    }

生成的随机数是依赖于上一个的,所以叫“随机数序列”。,确定的种子产生确定的随机数序列。

为了避免每次生成的随机数序列都一样,所以一般采用当前系统运行的毫秒数Environment.TickCount做种子。

这就明白为什么

            //for(int i = 0; i < 10; i++)

            //{

            //    Random rand = new Random();

            //    Console.WriteLine(rand.Next(100));

            //}

是错的。

经过反编译,Random类的无参构造函数最终也是调用有参的,传递的就是当前毫秒数

public Random() : this(Environment.TickCount)

这就验证了

            //for(int i = 0; i < 10; i++)

            //{

            //    Random rand = new Random();

            //    Console.WriteLine(rand.Next(100));

            //}

为什么一样,或者一半一样,是因为在同一毫秒内。

 

做法1

            List<int> list = new List<int>();

            Randomrand = new Random();

            while(list.Count < 100)

           {

               int number = rand.Next(1, 101);//>=1,<101

                if(!list.Contains(number))//如果list中已经含有这个数,则不插入

                {

                    list.Add(number);

                }

            }

 

            foreach(int i in list)

            {

                Console.WriteLine(i);

            }

 

做法2

先把1-100100个数按顺序放入数组arr,再重复100次下面的操作,生成两个介于 >=0,<100 之间的随机数mn,颠倒arr[m]arr[n]的数。

 

            int[]arr = new int[100];

            //100个数顺序放入

            for(int i = 0; i < 100; i++)

            {

                arr[i] = i + 1;

            }

 

            Randomrand = new Random();

            for(int i = 0; i < 100; i++)

            {

                //随机生成两个位置

                intm = rand.Next(0, 100);

                intn = rand.Next(0, 100);

 

                //颠倒两个位置

                int temp = arr[m];

                arr[m] = arr[n];

                arr[n] = temp;

            }

 

2JavaScript中声明空数组。

[]

 

晨飞燕第一次

2、冒泡排序背也要背下来50%必考!)

   for (int j = 0; j < nums.Length - 1;j++)

           {

                for (int i = 0; i <nums.Length - 1 -j; i++)

                {

                    if (nums[i] > nums[i +1])

                    {

                        int temp = nums[i];

                        nums[i] = nums[i + 1];

                        nums[i + 1] = temp;

                    }

                }

           }

如果只是调用集合的Sort方法,是不满足人家要求的!一定要自己写!

快速排序(!)

 

 

 

4、2+5+"8"得到的结果是什么?

解答:从左向右运算,int+string是string。所以是"78"

"8"+2+5是"825",而"8"+(2+5)是“87”

5、

(1)

var x=1;

var y=0;

var z=0;

function add(n){n=n+1;return n;}

y=add(x);

function add(n){n=n+3;return n;}

z=add(x);

求y和z的值是多少?

 

参考:JavaScript引擎会先解析所有的命名函数,再去从上向下执行js代码。所以第二个add覆盖了第一个add的定义。因此结果是4、4

 

(2)传智播客增加一问

 

var x=1;

var y=0;

var z=0;

var add = function(n){n=n+1;return n;}

y=add(x);

add =function(n){n=n+3;return n;}

z=add(x);

求y和z的值是多少?

 

参考:var add =function(n){n=n+1;return n;}是把一个变量名add指向匿名函数。执行的时候add指向哪个函数,就执行哪个函数。从上向下执行。结果是2、4。所以写程序的时候最好用匿名函数。

 

命名函数的add就是函数的名字。而var add = function(n){n=n+1;returnn;}则是创建一个匿名函数,并且把变量add指向它,这个函数还是匿名函数,并不会因为有一个变量指向它他就不是匿名函数了。

0 0
原创粉丝点击