以下内容转载自C#与.net面试宝典
1.类型与变量
1.1 C#支持哪几种预定义的值类型的值?
C#中预定义的值类型,主要包括5个类型:整型、浮点类型、字符型、bool型和decimal型。其中每一个类型分别由多个内置类型组成
C#中的值类型
类型 | 名称 | 简要说明 |
字符型 | System.Char | 表示一个16位的(Unicode)字符 |
bool型 | System.Boolean | 返回true或false |
整型 | System.Byte | 8位无符号的整数 0到255 |
整型 | System.SByte | 8位有符号的整数 –128到127 |
整型 | System.Int16 | 16位有符号的整数 –32768到32767 |
整型 | System.Int32 | 32位有符号的整数 –2147483648到2147483647 |
整型 | System.Int64 | 64位有符号的整数 –9223372036854775808到9223372036854775807 |
整型 | System.Uint16 | 16位无符号的整数 0到65535 |
整型 | System.Uint32 | 32位无符号的整数 0到4294967295 |
整型 | System.Uint64 | 64位无符号的整数 0到18446744073709551615 |
浮点型 | System.Single | 32位单精度浮点数 ±1.5×10-45到±3.4×1038 |
浮点型 | System.Double | 64位双精度浮点数 ±5.0×10-324到±1.7×10308 |
decimal | System.Decimal | 128位高精度十进制数 ±1.0×10-28到±7.9×1028 |
1.2 C#支持哪几个预定义的引用类型?
C#中预定义的引用类型只有两个object类型和string类型。
1.3 如何解决装箱和拆箱引发的性能问题?
对于装箱和拆箱引发的性能问题,可以在程序中大量使用泛型替代。
分析:装箱在值类型向引用类型转换时发生,拆箱在引用类型向值类型转换时发生
1.4 有几种方法可以判断值类型和引用类型?
1.值类型的变量赋值只是进行数据复制,创建一个同值的新对象,而引用类型变量赋值,仅仅是把对象的引用的指针赋值给变量,使它们共用一个内存地址。
2.引用类型一般都具有继承性,但是值类型一般都是封装的,因此值类型不能作为其他任何类型的基类。
3.值类型数据是在栈上分配内存空间,它的变量直接包含变量的实例,使用效率相对较高。而引用类型数据是分配在堆上,引用类型的变量通常包含一个指向实例的指针,变量通过指针来引用实例。
1.5 如何理解C#中变量的作用域?
变量的作用域是指可以使用该变量的代码区域。一般情况下,确定作用域有如下规则。
A、只要变量所属的类在某个作用域内,其字段(也叫做 成员变量)也在该作用域中。
B、局部变量存在于声明该变量的块语句或方法结束的大括号之前的作用域。
C、在for、while 循环中声明的变量,只存在于该循环体内。
2. C#语句
2.1 传递参数的方法
C#中有四种传递参数的方法,分别是传值,传址,输出参数和数组参数,传值参数不需其他修饰符,传址参数需要修饰符ref,输出参数需要修饰符out,数组参数需要修饰符params。
2.2 如何理解C#中的预处理指令
C#预处理指令是在编译时调用的,预处理器指令通知C#编译器要编译哪些代码,并指出如何处理特定的指令和警告,C#预处理指令还可以提示C#编译器有关代码组织的信息。
2.3 请简述C#中的main方法
C#中main方法是程序的入口,程序从这里开始,也在这里结束,需要注意的是C#中main方法有且只有一个。
2.4 如何理解C#中的指针
C#中类型不继承object,并且指针类型与object之间不能转换,此外装箱和拆箱操作也不支持指针。但是C#允许在不同指针类型之间及指针与整形之间转换。
2.5请举例System.Collections之中常用的成员
分析:
该命名空间下的.NET非泛型集合类如下所示:
— System.Collections.ArrayList:数组集合类,使用大小可按动态增加的数组实现Ilist接口。
— System.Collections.BitArray:布尔集合类,管理位值的压缩数组,该值为布尔值。
— System.Collections.Queue:队列,表示对象的先进先出集合。
— System.Collections.Stack:堆栈,表示对象的简单的后进先出集合。
— System.Collections.Hashtable:哈希表,表示键/值对的集合,这些键/值对根据键的哈希代码进行组织
— System.Collections.SortedList:排序集合类,表示键/值对的集合,这些键和值按键排序并可按键和索引访问。
该命名空间下的.NET非泛型接口如下所示:
— System.Collections.ICollection:(继承于IEnumerable)定义所有集合的大小,枚举器和同步方法,可以获取集合中项的个数,并能把项复制到一个简单的数组类型中。
— System.Collections.IComparer:比较两个对象的方法
— System.Collections.IList:(继承于IEnumerable 和 ICollection)表示可按照索引单独访问一组对象,提供集合的项列表,并可以访问这些项。
— System.Collections.IDictionary:(继承于IEnumerable 和 ICollection)表示键/值对的集合
— System.Collections.IDictionaryEnumerator:枚举字典的元素
— System.Collections.IEnumerator:支持在集合上进行简单迭代,可以迭代集合中的项。支持在非泛型集合进行简单迭代。
解答:
System.Collections常用的类有ArrayList,SortedList,Queue,Hashtable,常用的接口有IEnumerable,IList,IDictionary等
2.6 C#提供了哪几种循环结构?
C#提供了for,while,do while,foreach这四种循环结构,while和do while 经常用在不确定循环次数的场合,for用在已知循环次数的场合,foreach用来处理已知集合的循环操作。
2.7 String和StringBuilder有什么区别?
在相同字符串的许多操作上,使用StringBuilder会比string对象更加有效率。对于少量字符串操作,使用string更加方便,.net对string类型封装了大量字符串操作方法。
2.8 如何处理自定义格式字符串输出
通常执行IFormattable的类也接受唯一格式的ToString()。在默认条件下ToString()方法不接收任何参数,它继承于其他的类。IFormattable接口包含唯一一个ToString()方法。另外IFormattable.ToString()方法接收一个IFormatProvider
类型的参数,以允许类型的使用者提供格式化方法。
2.9 请列举几种遍历HashTable的方法。
Hashtable table = new Hashtable();table.Add("1", "1111");
table.Add("2", "2222");
table.Add("3", "3333");
table.Add("4", "4444");
//方法一(遍历哈希表中的键)
foreach (var item in table.Keys)
{
Console.WriteLine("key:" + item + ",value:"+table[item]);
}
//方法二(遍历哈希表中的值)
foreach (var item in table.Values)
{
Console.WriteLine("value:" + item);
}
//方法三(遍历哈希表中的键值,其键值对象为DictionaryEntry)
foreach (DictionaryEntry item in table)
{
Console.WriteLine("key:" + item.Key + ",value:" + item.Value);
}
//方法四(遍历哈希表中的键值,其键值对象为IDictionaryEnumerator)
IDictionaryEnumerator list = table.GetEnumerator();
while(list.MoveNext())
{
Console.WriteLine("key:" + list.Key + ",value:" + list.Value);
}
table.Add("1", "1111");
table.Add("2", "2222");
table.Add("3", "3333");
table.Add("4", "4444");
//方法一(遍历哈希表中的键)
foreach (var item in table.Keys)
{
Console.WriteLine("key:" + item + ",value:"+table[item]);
}
//方法二(遍历哈希表中的值)
foreach (var item in table.Values)
{
Console.WriteLine("value:" + item);
}
//方法三(遍历哈希表中的键值,其键值对象为DictionaryEntry)
foreach (DictionaryEntry item in table)
{
Console.WriteLine("key:" + item.Key + ",value:" + item.Value);
}
//方法四(遍历哈希表中的键值,其键值对象为IDictionaryEnumerator)
IDictionaryEnumerator list = table.GetEnumerator();
while(list.MoveNext())
{
Console.WriteLine("key:" + list.Key + ",value:" + list.Value);
}
3. 字符串和数组
3.1 System.String是值类型还是引用类型?
System.String是引用类型,只是String的只读特性让人以为他是值类型,因为每次修改String时都会创建一个新的 String对象。因此应该尽量避免过多不必要的中间字符串变量。
3.2 string和String有什么区别?
string是String类型的一个别名,两者没有任何区别。在定义变量是程序员既可以使用string也可以使用String。
3.3 如何在Byte[]和String之间进行转换?
//将字符串转成字符
string str = "中文";
byte[] byte_utf8 = Encoding.UTF8.GetBytes(str);
byte[] byte_asc = Encoding.ASCII.GetBytes(str);
byte[] byte_gb2312 = Encoding.GetEncoding("GB2312").GetBytes(str);
//将字符转换成字符串
string str_utf8 = Encoding.UTF8.GetString(byte_utf8);
string str_gb2312 = Encoding.GetEncoding("GB2312").GetString(byte_gb2312);
字符串和字符数组之间的转换依赖与不同的编码方式,不同的编码标准使用不同的算法,System.Text.Encoding提供 了大量编码算法,用以支持字符串和字符数组之间的转换。
3.4 Array和ArrayList之间的区别
表面上看Array和ArrayList是相似的,都具有索引,都可以通过index来获取,修改元素。但其实Array数组和ArrayList集合差别很大,主要体现在命名空间,变量声明,下限,添加插入或移除某一范围的元素,维度,存储对象,存放方式,初始化大小,插入和删除项等差异。
3.5 Array和ArrayList之间是如何转换的?
//将ArrayList转成Array
Person person1 = new Person
{
name = "cheng",
age = 12
};
Person person2 = new Person
{
name = "yan",
age = 12
};
ArrayList list = new ArrayList();
list.Add(person1);
list.Add(person2);
Person[] p_list2 = (Person[])list.ToArray(typeof(Person));
//将Array转成ArrayList
list = new ArrayList();
foreach(var item in p_list2)
{
list.Add(item);
}
Array转成ArrayList为了避免大量重复的代码,可以定义一个转换的方法。从ArrayList转换为Array可以使用toArray()方法实现。
4.运算符和表达式
checked的作用是开启算术运算和显示转换的溢出检查,unchecked的作用和checked相反,它的作用是关闭算术运算和显示转换的溢出检查。
4.2 C#中三元运算符的作用是什么?
三元运算符是if...else...的简化版,三元运算符适合同时处理两个参数返回一个参数的情况。
4.3 C#中is运算符和as运算符有什么作用?
Is运算符用于检查对象是否与给定类型兼容,如果兼容返回true,如果不兼容返回false,as运算符用于将对象转换为给定的类型,如果无法转换返回null,不会引发异常。
5.时间操作
5.1 C#中如何利用Datetime获取季度
DateTime date = new DateTime(2017, 5, 10);
//获取当前季度的第一天
string datetime = date.AddMonths(0 - (date.Month - 1) % 3).ToString("yyyy-MM-01");
5.2 如何获取本月的工作日
private static List<DateTime> 获取本月的工作日()
{
List<DateTime> list = new List<DateTime>();
int day_count = DateTime.DaysInMonth(DateTime.Now.Year, DateTime.Now.Month);
for(int i = 1;i <= day_count;i++)
{
DateTime date = new DateTime(DateTime.Now.Year, DateTime.Now.Month, i);
if(DayOfWeek.Saturday == date.DayOfWeek || DayOfWeek.Sunday == date.DayOfWeek)
{
continue;
}
else
{
list.Add(date);
}
}
return list;
}
5.3 如何进行C#的Datetime和字符串之间的转换?
Datetime转字符串可以使用ToString方法,字符串转Datetime可以使用Convert.ToDateTime方法或者Datetime.Parse和TryParse方法