CSharp是微软开发的面向对象的编程语言。C# 与 .NET 框架一起用于创建网站、应用程序和游戏。C# 流行的原因多种多样:
相对容易:从 C# 开始被称为比其他编程语言相对容易
开发的更广泛使用:使用 C#,你很容易创建 Web 应用程序或游戏应用程序。C# 有一些很棒的特性,比如自动垃圾收集、接口等,它们有助于构建更好的应用程序。
更大的目标受众:与 Microsoft 的合作为使用 C# 创建的应用程序提供了优势,因为它具有更广泛的目标受众。
由于 C# 是一种广泛使用的编程语言,因此许多大大小小的组织都在使用它作为其产品的基础。因此,请准备好基本和高级 C# 问题,以便在面试中胜出。让我们看看关于 C# 的 50 个C#常见面试题和答案合集。
基本C#常见的面试题有哪些
1. C# 与 C 有何不同?
你总会知道 C 是过程语言,而 C# 是一种更面向对象的语言。最大的区别是 C# 支持公共语言运行时 (CLR) 的自动垃圾收集,而 C 不支持。C# 主要需要一个 .NET 框架来执行,而 C 是一种与平台无关的语言。
2. 什么是公共语言运行时 (CLR)?
C#面试题解析:CLR 处理包括 C# 在内的各种语言的程序执行。CLR 的架构处理内存管理、垃圾收集、安全处理,看起来像:
3. C# 中的垃圾回收是什么?
垃圾收集是释放被不需要的对象捕获的内存的过程。创建类对象时,会自动在堆内存中为该对象分配一些内存空间。现在,当你对对象执行所有操作后,对象占用的内存空间就变得浪费了。有必要释放内存。垃圾收集发生在三种情况下:
- 如果对象占用的内存超过预设的阈值。
- 如果垃圾回收方法被调用
- 如果你的系统物理内存不足
4. C#中的类有哪些类型?
类是一个实体,它将其对象和实例的所有属性封装为一个单元。C#有四种类型的这样的类:
- 静态类:静态类,由关键字“static”定义,不允许继承。因此,你不能为静态类创建对象。
示例代码:
static class classname
{
//static data members
//static methods
}
- 部分类:部分类,由关键字“部分”定义,允许其成员部分分割或共享源 (.cs) 文件。
- 抽象类:抽象类是不能在不能创建对象的地方被实例化的类。抽象类在 OOPS 抽象概念上工作。抽象有助于提取重要的细节并隐藏不重要的细节。
- 密封类:密封类是不能被继承的类。使用关键字sealed 限制对用户的访问以继承该类。
sealed class InterviewBit
{
// data members
// methods
.
.
.
}
5. 什么是托管和非托管代码?
托管代码允许你在 .NET 框架中的托管 CLR 运行时环境中运行代码。
托管代码在托管运行时环境上运行,而不是在操作系统本身上运行。
优点:提供各种服务,如垃圾收集器、异常处理等。
非托管代码是指当代码不在 CLR 上运行时,它是在 .NET 框架之外工作的非托管代码。
它们不提供高级语言的服务,因此在没有它们的情况下运行。这样的例子是 C++。
6.C#常见的面试题有哪些:抽象类和接口有什么区别?
让我们深入研究抽象类和接口之间的区别:
- 抽象类是不能被实例化的类,即。不能创建对象。接口就像一个抽象类,因为接口内部的所有方法都是抽象方法。
- 令人惊讶的是,抽象类可以同时具有抽象和非抽象方法,但接口的所有方法都是抽象方法。
- 由于抽象类可以同时具有抽象和非抽象方法,因此我们需要使用 Abstract 关键字来声明抽象方法。但是在界面中,就没有这个必要了。
抽象类有构造函数,而接口没有构造函数。
例子:
抽象类:
public abstract class Shape{
public abstract void draw();
}
接口:
public interface Paintable{
void paint();
}
7. ref 和 out 关键字有什么区别?
C# ref 关键字通过引用而不是值传递参数。要使用“ref”关键字,你需要明确提及“ref”。
void Method(ref int refArgument)
{
refArgument = refArgument + 10;
}
int number = 1;
Method(ref number);
Console.WriteLine(number);
// Output: 11
C# out 关键字在方法和函数中传递参数。
'out' 关键字用于在方法中传递参数作为返回多个值的引用。虽然和 ref 关键字相同,但是 ref 关键字在传递之前需要进行初始化。这里,当我们想要在作为参数传递的相同变量中返回一个值时,out 和 ref 关键字很有用。
public static string GetNextFeature(ref int id)
{
string returnText = "Next-" + id.ToString();
id += 1;
return returnText;
}
public static string GetNextFeature(out int id)
{
id = 1;
string returnText = "Next-" + id.ToString();
return returnText;
}
8. C#常见面试题和答案合集:C#中的扩展方法是什么?
扩展方法有助于向现有方法添加新方法。添加的方法是静态的。有时,当你想向现有类添加方法但不认为有权修改该类或不拥有权限时,你可以创建一个包含新方法的新静态类。声明扩展方法后,将此类与现有方法绑定,然后查看方法将添加到现有方法中。
// C# program to illustrate the concept
// of the extension methods
using System;
namespace ExtensionMethod {
static class NewMethodClass {
// Method 4
public static void M4(this Scaler s)
{
Console.WriteLine("Method Name: M4");
}
// Method 5
public static void M5(this Scaler s, string str)
{
Console.WriteLine(str);
}
}
// Now we create a new class in which
// Scaler class access all the five methods
public class IB {
// Main Method
public static void Main(string[] args)
{
Scaler s = new Scaler();
s.M1();
s.M2();
s.M3();
s.M4();
s.M5("Method Name: M5");
}
}
}
输出:
Method Name: M1
Method Name: M2
Method Name: M3
Method Name: M4
Method Name: M5
9. C#中的泛型是什么?
在 C# 集合中,定义任何类型的对象都被称为 OK,这会损害 C# 的类型安全基本规则。因此,通过允许重用数据处理算法,包含泛型以对代码进行类型安全。C# 中的泛型意味着不链接到任何特定的数据类型。泛型减少了使用装箱、拆箱和类型转换对象的负载。泛型总是在尖括号 <> 内定义。要创建泛型类,请使用以下语法:
GenericList<float> list1 = new GenericList<float>();
GenericList<Features> list2 = new GenericList<Features>();
GenericList<Struct> list3 = new GenericList<Struct>();
这里, GenericList<float> 是一个泛型类。在 GenericList<T> 的每个实例中,类中 T 的每个出现都在运行时替换为类型参数。通过替换 T,我们使用同一个类创建了三个不同的类型安全。
10. C#中的Array和ArrayList有什么区别?
C#面试题解析:数组是用一个共同的名字拼凑在一起的相似变量的集合。而 ArrayList 是可以单独索引的对象集合。使用 ArrayList,你可以访问许多功能,例如动态内存分配、在 ArrayList 中添加、搜索和排序项目。
- 当声明一个数组时,项目的大小是固定的,因此内存分配是固定的。但是使用 ArrayList,它可以动态增加或减少。
- Array 属于 system.array 命名空间,而 ArrayList 属于 system.collection 命名空间。
- 数组中的所有项都具有相同的数据类型,而 ArrayList 中的所有项可以具有相同或不同的数据类型。
- 数组不能接受空值,而 ArrayList 可以接受空值。
例如:
// C# program to illustrate the ArrayList
using System;
using System.Collections;
class IB {
// Main Method
public static void Main(string[] args)
{
// Create a list of strings
ArrayList al = new ArrayList();
al.Add("Bruno");
al.Add("Husky");
al.Add(10);
al.Add(10.10);
// Iterate list element using foreach loop
foreach(var names in al)
{
Console.WriteLine(names);
}
}
}
11.什么是继承?C# 支持多重继承吗?
继承意味着从主类中获取一些属性。
这里,C 类可以继承 A 类和 B 类的属性。下面是一个继承的例子:
// C# program to illustrate
// multiple class inheritance
using System;
using System.Collections;
// Parent class 1
class Scaler {
// Providing the implementation
// of features() method
public void features()
{
// Creating ArrayList
ArrayList My_features= new ArrayList();
// Adding elements in the
// My_features ArrayList
My_features.Add("Abstraction");
My_features.Add("Encapsulation");
My_features.Add("Inheritance");
Console.WriteLine("Features provided by OOPS:");
foreach(var elements in My_features)
{
Console.WriteLine(elements);
}
}
}
// Parent class 2
class Scaler2 :Scaler{
// Providing the implementation
// of courses() method
public void languages()
{
// Creating ArrayList
ArrayList My_features = new ArrayList();
// Adding elements in the
// My_features ArrayList
My_features.Add("C++");
My_features.Add("C#");
My_features.Add("JScript");
Console.WriteLine("\nLanguages that use OOPS concepts:");
foreach(var elements in My_features)
{
Console.WriteLine(elements);
}
}
}
// Child class
class ScalertoScaler : Scaler2 {
}
public class Scaler1 {
// Main method
static public void Main()
{
// Creating object of ScalertoScaler class
ScalertoScaler obj = new ScalertoScaler();
obj.features();
obj.languages();
}
}
此外,C# 不支持多重继承。
相反,你可以使用接口来使用签名中的类名来继承属性。
高级C#常见的面试题有哪些
12. 什么是 C# 中的装箱和拆箱?
这两个函数用于对数据类型进行类型转换:
装箱:装箱将值类型(int、char 等)转换为引用类型(对象),这是使用对象值的隐式转换过程。
例子:
int num = 23; // 23 will assigned to num
Object Obj = num; // Boxing
拆箱:拆箱使用显式转换过程将引用类型(对象)转换为值类型(int、char 等)。
例子:
int num = 23; // value type is int and assigned value 23
Object Obj = num; // Boxing
int i = (int)Obj; // Unboxing
13. C#中的属性是什么?
C# 中的属性是类的公共成员,它们提供访问类的私有成员的能力。封装的基本原理让你可以通过将变量设为私有来对用户隐藏一些敏感属性。私有成员在类中无法访问。因此,通过在 C# 中使用属性,你可以轻松访问私有成员并设置它们的值。
可以使用 get 和 set 方法(也称为访问器)轻松分配值。当 get 方法提取值时, set 方法将值分配给变量。
14. C# 中的分部类是什么?
部分类将单个类的功能实现到多个文件中。这些多个文件在编译时合并为一个。可以使用 partial 关键字创建分部类。
public partial Clas_name
{
// code
}
你可以轻松地将方法、接口或结构的功能拆分为多个文件。你甚至可以添加嵌套的分部类。
15. C#中后期绑定和早期绑定有什么区别?
后期绑定和早期绑定是 OOPS 的主要概念之一:多态性的示例。
例如:一个函数 calculateBill() 将根据不同的政策计算高级客户、基本客户和半高级客户的账单。使用称为多态性的相同函数对所有客户对象进行不同的计算。
在 C# 中将对象分配给对象变量时,.NET 框架执行绑定。
当绑定函数发生在编译时,它被称为早期绑定。它调查并检查静态对象的方法和属性。使用早期绑定,运行时错误的数量大大减少,并且执行速度非常快。
但是当绑定发生在运行时,它被称为后期绑定。当对象在运行时是动态的(根据它们持有的数据决定)时,就会发生后期绑定。它在运行时查看时速度较慢。
16. C#常见面试题和答案合集:C#中的数组是什么?
当一组相似的元素以一个名字拼凑在一起时,它们被称为数组。
例如。一系列茶Atea[4]:[绿茶、洋甘菊茶、红茶、柠檬茶]。数组的长度定义了数组中存在多少个元素。
在 C# 中,数组元素的内存分配是动态发生的。这就是值按顺序存储在数组中的方式。
C# 中数组的一些指针:
- 内存分配是动态的。
- C# 中的数组被视为对象。
- 通过检测数组中成员的数量,很容易找到数组的长度。
- 数组中的成员是有序的,并以索引值=0 开始。
- 数组类型是从基本数组类型派生的引用类型。
句法: < Data Type > [ ] < Name_Array >
17. C# 中的索引器是什么?
索引器被称为允许访问成员变量的智能数组。索引器允许使用数组特性的成员变量。它们是使用 Indexer 关键字创建的。索引器不是静态成员。
例如。这里索引器的定义方式相同。
<return type> this[<parameter type> index]
{
get{
// return the value from the specified index of an internal collection
}
set{
// set values at the specified index in an internal collection
}
}
18. C#中的等号(==)和Equals()方法的区别?
尽管两者都用于按值比较两个对象,但它们的用法仍然不同。
例如:
int x = 10;
int y = 10;
Console.WriteLine( x == y);
Console.WriteLine(x.Equals(y));
Output:
True
True
相等运算符 (== ) 是一种引用类型,这意味着如果使用相等运算符,则仅当两个引用都指向同一个对象时,它才会返回 true。
Equals() 方法: Equals 方法用于比较对象携带的值。整数 x=10,整数 y=10。如果比较 x==y,则比较 x 和 y 携带的值,它们相等,因此它们返回 true。
相等运算符:按引用比较
Equals():按值比较
19.在C#中重载方法有哪些不同的方式?
C#面试题解析:重载意味着当一个方法具有相同的名称但携带不同的值以在不同的上下文中使用时。只有 main() 方法不能被重载。
为了重载 C# 中的方法,
- 更改方法中的参数数量,或
- 更改方法中参数的顺序,或
- 为参数使用不同的数据类型
通过这些方式,你可以多次重载一个方法。
例如。
public class Area {
public double area(double x) {
double area = x * x;
return area;
}
public double area(double a, double b) {
double area = a * b;
return area;
}
}
这里,方法 Area 被使用了两次。在第一个声明中,使用了一个参数,而在第二个声明中,使用了两个参数。在同一方法中使用不同的参数,我们能够重载方法 area()。
20. 什么是 C# 中的反射?
C# 中的反射在运行时从数据类型中提取元数据。
要在 .NET 框架中添加反射,只需在程序中使用 System.Refelction 命名空间来检索可以是以下任何内容的类型:
- 集合
- 模块
- 枚举
- 方法信息
- 构造函数信息
- MemberInfo
- ParameterInfo
- 类型
- FieldInfo
- EventInfo
- PropertyInfo
21. C#中constant和readonly有什么区别?
甲常量在C#关键字用于声明在整个程序中的常数域。这意味着一旦一个变量被声明为const,它的值就不能在整个程序中改变。
在 C# 中,常量是数字、字符串、空引用或布尔值。
例如:
class IB {
// Constant fields
public const int xvar = 20;
public const string str = "InterviewBit";
// Main method
static public void Main()
{
// Display the value of Constant fields
Console.WriteLine("The value of xvar: {0}", xvar);
Console.WriteLine("The value of str: {0}", str);
}
}
Output:
The value of xvar is 20.
The value of string is Interview Bit
另一方面,使用 readonly 关键字,你只能在声明变量时或在声明它的同一类的构造函数中分配变量。
例子:
public readonly int xvar1;
public readonly int yvar2;
// Values of the readonly
// variables are assigned
// Using constructor
public IB(int b, int c)
{
xvar1 = b;
yvar2 = c;
Console.WriteLine("The value of xvar1 {0}, "+
"and yvar2 {1}", xvar1, yvar2);
}
// Main method
static public void Main()
{
IB obj1 = new IB(50, 60);
}
}
Output:
The value of xvar1 is 50, and yvar2 is 60
默认情况下,常量是静态的,而 readonly 应该在声明构造函数时分配一个值。
常量可以在函数内声明,而 readonly 修饰符可以与引用类型一起使用。
22. C#中String和StringBuilder的区别是什么?
C#面试题解析:String 和 StringBuilder 之间的主要区别在于 String 对象是不可变的,而 StringBuilder 创建的是可变字符串。StringBuilder 将对现有对象进行更改,而不是创建新对象。
StringBuilder 简化了对现有字符串对象进行更改的整个过程。由于 String 类是不可变的,因此每次需要进行更改时创建一个新对象的成本更高。因此,可以使用 System.Text 命名空间调用 StringBuilder 类。
如果字符串对象在整个程序中不会改变,则使用 String 类或 StringBuilder。
例如:
string s = string.Empty;
for (i = 0; i < 1000; i++)
{
s += i.ToString() + " ";
}
在这里,你需要创建 2001 个对象,其中 2000 个没有用。
同样可以使用 StringBuilder 应用:
StringBuilder sb = new StringBuilder();
for (i = 0; i < 1000; i++)
{
sb.Append(i); sb.Append(' ');
}
通过在此处使用 StringBuilder,你还可以减轻内存分配器的压力。
编码问题:C#常见的面试题有哪些
23.用C#Sharp写一个程序来反转一个字符串?
internal static void ReverseString(string str)
{
char[] charArray = str.ToCharArray();
for (int i = 0, j = str.Length - 1; i < j; i++, j--)
{
charArray[i] = str[j];
charArray[j] = str[i];
}
string reversedstring = new string(charArray);
Console.WriteLine(reversedstring);
24. 用C#Sharp写一个程序来颠倒给定单词的顺序?
internal static void ReverseWordOrder(string str)
{
int i;
StringBuilder reverseSentence = new StringBuilder();
int Start = str.Length - 1;
int End = str.Length - 1;
while (Start > 0)
{
if (str[Start] == ' ')
{
i = Start + 1;
while (i <= End)
{
reverseSentence.Append(str[i]);
i++;
}
reverseSentence.Append(' ');
End = Start - 1;
}
Start--;
}
for (i = 0; i <= End; i++)
{
reverseSentence.Append(str[i]);
}
Console.WriteLine(reverseSentence.ToString());
}
25. 用 C# Sharp 编写一个程序来判断给定的字符串是否是回文?
internal static void chkPalindrome(string str)
{
bool flag = false;
for (int i = 0, j = str.Length - 1; i < str.Length / 2; i++, j--)
{
if (str[i] != str[j])
{
flag = false;
break;
}
else
flag = true;
}
if (flag)
{
Console.WriteLine("Palindrome");
}
else
Console.WriteLine("Not Palindrome");
输出:
Input: Key Output: Not Palindrome
Input: step on no pets Output: Palindrome
26. 编写一个 C# 程序从给定的字符串中查找子字符串。
internal static void findallsubstring(string str)
{
for (int i = 0; i < str.Length; ++i)
{
StringBuilder subString = new StringBuilder(str.Length - i);
for (int j = i; j < str.Length; ++j)
{
subString.Append(str[j]);
Console.Write(subString + " ");
}
}
}
27. C#常见面试题和答案合集:编写一个 C# 程序来判断一个正整数是否是素数?
static void Main(string[] args)
{
if (FindPrime(47))
{
Console.WriteLine("Prime");
}
else
{
Console.WriteLine("Not Prime");
}
Console.ReadLine();
}
internal static bool FindPrime(int number)
{
if (number == 1) return false;
if (number == 2) return true;
if (number % 2 == 0) return false;
var squareRoot = (int)Math.Floor(Math.Sqrt(number));
for (int i = 3; i <= squareRoot; i += 2)
{
if (number % i == 0) return false;
}
return true;
}