C#笔试知识点

1.String与Stringbuilder的区别:

String自动分配内存大小,每次往里面写新东西,就会重新分配一段内存,然后把地址指向新的这块空间,是由C#内存管理自动管理的。

Stringbuilder会事先分配好一段空间,append的时候,是操作的同一块空间,如果新串超过原本大小,内存空间自动加倍。

2.C#如何调用c++静态库(lib):

可以用CLR(新)或者Managed c++(老)将lib封装成managed  dll供C#直接调用。

将lib封装成native dll,C#中通过DllImport调用dll。

将lib封装成native dll, 再用CLR封装native dll成managed  dll供C#直接调用。

将lib封装为COM,在C#中调用COM。

3.长度为100的字符串,从abcdefgh中随机抽取100个字符组成:

usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;usingSystem.Threading.Tasks;namespacecsharpconsole{classProgram{staticvoidMain(string[] args)        {            StringBuilder strOut =newStringBuilder(0,100);            String strSrc ="a, b, c, d, e, f, g, h";            String[] strDes = strSrc.Split(',');intlen = strDes.Length;            Random rd =newRandom();inti =0;for(; i <100; i++)            {                StrOut = strDes[rd.Next(len)];            }            Console.ReadKey();        }    }}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

4.产生一个int数组,长度为100,并向其中随机插入1-100,并且不能重复:

usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;usingSystem.Threading.Tasks;usingSystem.Collections;namespacecsharpconsole{classProgram{staticvoidMain(string[] args)        {int[] intArr =newint[100];            ArrayList myList =newArrayList();            Random rd =newRandom();intnum =0;/* 1-100产生随机数 */inti =0;/* 生成100个不重复的1-100的数 */while(myList.Count <100)            {                num = rd.Next(1,101);                if (!myList.Contains(num))                {                    myList.Add(num);                }            }for(; i <100; i++)            {                intArr[i] = (int)myList[i];            }foreach(inta in intArr)            {                Console.WriteLine(a);            }            Console.ReadKey();        }    }}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

5.把一个Array复制到ArrayList里:

foreach(objectoinarray){    arrayList.Add(o);}

1

2

3

4

1

2

3

4

6.写一个函数计算当参数为N的值:1-2+3-4+5-6+7……+N:

usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;usingSystem.Threading.Tasks;namespacecsharpconsole{classProgram{staticvoidMain(string[] args)        {intnum =0;            String str ="";intsum =0;            Console.WriteLine("请输入一个100以内的数:");            str = Console.ReadLine();            num =int.Parse(str);for(inti =1; i <= num; i++)            {                sum += ((int)Math.Pow(-1, i +1)) * i;            }            Console.WriteLine(sum);            Console.ReadKey();        }    }}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

7.斐波拉契数列 0, 1, 1, 2, 3, 5, 8, 13, 21, 34……:

usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;usingSystem.Threading.Tasks;namespacecsharpconsole{classProgram{staticintMyALG(intnum)        {            if (num <=0)            {return0;            }elseif ((1== num) || (2== num))            {return1;            }else{return(MyALG(num -1) + MyALG(num -2));            }        }staticvoidMain(string[] args)        {intresult =0;            result = MyALG(30);            Console.WriteLine(result.ToString());            Console.ReadKey();        }    }}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

8.理解接口的作用:

C#之理解接口的作用

9.虚方法(virtual)和抽象类(abstract)的区别和联系:

(1)、抽象方法只有声明没有实现代码,需要在子类中实现;虚拟方法有声明和实现代码,并且可以在子类中重写,也可以不重写使用父类的默认实现。

(2)、抽象类不能被实例化(不可以new),只能实例化实现了全部抽象方法的派生类;而包含虚方法的类可以实例化。

(3)、虚方法与多态性关系密切,虚方法允许派生类完全或部分重写该类的方法,需写方法体。抽象方法只是一个定义,没有方法体,也就是没有{},也不要在里面写内容。

(4)、抽象方法是虚拟方法两个相像的一点是都用override重写。

10.值类型和引用类型的区别:

值类型:存储在堆栈中。bool, byte, chat, decimal, double, enum, float, int, long, sbyte, short, strut, uint, ulong, ushort。

引用类型:存储在托管堆中。class, delegate, interface, object, string。引用类型包含一个指针,指向堆中存储对象本身的位置。因为引用类型只包含引用,不包含实际的值,对方法体内参数所做的任何修改都将影响传递给方法调用的引用类型的变量。

托管代码:基于CLR的语言编译器开发的代码称为托管代码。

托管堆:是CLR中自动内存管理的基础。初始化新进程时,运行时会为进程保留一个连续的地址空间区域。这个保留的地址空间被称为托管堆。托管堆维护着一个指针,用它指向将在堆中分配的下一个对象的地址。最初,该指针设置为指向托管堆的基址。

由于对对象的引用会在程序运行过程中被传递,所以引用类型不能够被用户方便的释放,.NET的垃圾收集处理机制,会在引用为0的时候,自动释放掉引用类型变量。

11.结构和类的区别:

结构是值类型,类是引用类型;结构不能有构造函数和析构函数;类可以同时有构造函数和析构函数;结构不支持继承,而类支持继承。

12.委托(delegate)和事件(event):

委托:委托是类型安全,面向对象的函数指针的实现,并且在许多一个组件需要回调到使用它的组件这样的情况下使用。

事件:事件是使一个类或对象能够提供通知的成员。事件声明像域声明一样,除了声明包含event关键字并且类型必须为委托类型。

13.对象类型(object)和动态类型(dynamic)的区别:

对象类型:是所有数据类型的终极基类。Object是System.Object类的别名。当一个值类型转换为对象类型时,则被称为装箱;另一方面,当一个对象类型转换为值类型时,则被称为 拆箱。

动态类型:可以存储任何类型的值在动态数据类型变量中。这些变量的类型检查是在运行时发生的。

动态类型与对象类型相似,但是对象类型变量的类型检查是在编译时发生的,而动态类型变量的类型检查是在运行时发生的。

14.传入参数:

包括值参数,引用参数,输出参数和参数数组。

引用参数(ref关键字):实参在调用前需要初始化,并且值可以被传入和传出;

输出参数(out关键字):实参在调用前不必初始化,在方法中必须要初始化,值只能传出不能传入。

15.C#与C的区别:

C#不支持#include语句。它只用using语句。

C#中,类定义在最后不使用分号。

C#不支持多重继承。

数据类型的显示转换在C#中比C中安全很多。

C#中switch也可用于字符串值。

命令行参数数组(params,即可变参数)的行为在C#中和C中不一样。

16.接口和类的区别:

(1)、接口类似于类,但接口的成员都没有执行方式,它只是方法、属性、事件和索引符的组合而已,并且也只能包含这四种成员;类除了这四种成员之外还可以别的成员(如字段)。

(2)、不能实例化一个接口,接口只包括成员的签名;而类可以实例化(abstract类除外)。

(3)、接口没有构造函数,类有构造函数。

(4)、接口不能进行运算符的重载,类可以进行运算符重载。

(5)、接口的成员没有任何修饰符,其成员总是公共的,而类的成员则可以有修饰符(如:虚拟或者静态)。

(6)、派生于接口的类必须实现接口中所有成员的执行方式,而从类派生则不然。

17.const和readonly区别:

readonly修饰的字段,其初始化仅是固定了其引用(地址不能修改),但它引用的对象的属性是可以更改的。

const声明的字段不能使用static修饰符,而readonly可以使用static修饰符。

const字段只能在声明时初始化,而readonly可以在声明时或在构造函数中初始化。

const字段的值在在编译阶段就计算出来了,而readonly的值在运行时计算。

18.异常(try、catch、finally、throw):

try:可能抛出异常的代码;

catch:出现异常后针对的处理办法;

finally:不论是否出现异常都执行的代码(通常是一些释放资源的代码),finally块是可以省略的。

一个try块可以对应多个catch块,其中按抛出的异常类寻找对应的catch块,也可能找不到,如果一直没有找到就会终止程序,返回一条错误代码。

异常处理可以互相嵌套,在内层找不到对应的处理代码,会向外层找。

(1)、try、catch、finally例子:

/*

结果:

finally1

试图除以0.

finally2

*/staticvoidMain(string[] args){intn1 =10;intn2 =0;intresult;/* 由于除数为0,抛出异常,内层找不到会找外层的异常catch处理 */try{/* try catch的嵌套 */try{            result = n1 / n2;            Console.WriteLine("{0}", result);        }catch(MemberAccessException e)        {            Console.WriteLine(e.Message);        }finally{            Console.WriteLine("finally1");        }    }/* 2个外层catch */catch(DivideByZeroException e)    {/* 最后找到是由此catch处理 */Console.WriteLine(e.Message);    }catch(Exception e)    {        Console.WriteLine(e.Message);    }finally{        Console.WriteLine("finally2");    }    Console.ReadKey();}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

(2)、自定义异常throw例子:

/*

结果:

除数为0

*//* 自定义异常必须继承于ApplicationException类 */privateclassTestException : ApplicationException{publicstringmsg;publicTestException(stringmsg)    {this.msg = msg;    }}/* 定义方法和异常抛出代码 */staticdoublemul(doublen1,doublen2){if(n2 ==0.0)    {/* 除数为0就抛出异常 */thrownewTestException("除数为0");    }returnn1 / n2;}staticvoidMain(string[] args){doublen1 =10.0;doublen2 =0.0;doubleresult;try{/* double除法默认除数为0会返回一个很大的值 */result = mul(n1, n2);        Console.WriteLine(result);    }catch(TestException e)    {        Console.WriteLine(e.msg);    }    Console.ReadKey();}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

19.特性(Attribute)和反射(Reflection):

特性为类、方法、结构、枚举、组件等添加自定义的属性(元数据),反射可以获取这些属性,需要的时候通过反射提取出来使用。

20.属性(Property)和索引器(Indexer):

属性要通过一个叫做访问器(accessor)的东东,对私有成员变量进行安全带验证的访问方式。即get、set属性。

索引器是可以通过方便的方式访问对象(实例化的类)中的成员数组或集合。(注意这里是数组或集合)

21.线程:

System.Threading名字空间。

Start():启动线程;

Sleep(int):静态方法,暂停当前线程指定的毫秒数;

Abort():通常使用该方法来终止一个线程;

Suspend():该方法并不终止未完成的线程,它仅仅挂起线程,以后还可恢复;

Resume():恢复被Suspend()方法挂起的线程的执行。

(1)、线程使用:

namespace Test{    class Program    {staticvoidMain(string[] args)        {            Thread t1 =newThread(newThreadStart(TestMethod));            Thread t2 =newThread(newParameterizedThreadStart(TestMethod));            t1.IsBackground =true;//设置当前子线程为后台线程,为后台线程意味着,主线程关闭后,其他子线程都同时关闭t2.IsBackground =true;            t1.Start();            t2.Start("hello");            Console.ReadKey();        }publicstaticvoidTestMethod()        {            Console.WriteLine("不带参数的线程函数");        }publicstaticvoidTestMethod(objectdata)        {stringdatastr = dataasstring;            Console.WriteLine("带参数的线程函数,参数为:{0}", datastr);        }    } }

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

(2)、线程池:

namespace Test{    class Program    {staticvoidMain(string[] args)        {//将工作项加入到线程池队列中,这里可以传递一个线程参数ThreadPool.QueueUserWorkItem(TestMethod,"Hello");            Console.ReadKey();        }publicstaticvoidTestMethod(objectdata)        {stringdatastr = dataasstring;            Console.WriteLine(datastr);        }    }}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

(3)、Lock互斥锁:

就是多线程访问临界区代码,一次只能让一个线程调用,以保护全局变量。这里要注意,lock只能锁定一个引用类型变量,即一个地址。

22.task/taskfactory:

后面补充,暂时用不到这么深入的技术。

23.Parallel:

后面补充,暂时用不到这么深入的技术。

24.有空的时候研究一下CLR、元数据、IL。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343

推荐阅读更多精彩内容