某公司.NET面试题
这些试题覆盖了从基础语法到设计模式、数据库操作、前端和后端开发等多个方面.
1. 简述 Func
与 Action
的区别?
解答
Func
和 Action
都是C#中的委托类型,但它们有一些关键的区别:
Action
是一个不带返回值的委托,用于定义一个方法的签名,可以有多个参数。它主要用于表示一个操作或行为,例如:Action<string>
表示一个接受一个字符串参数的操作。Func
是一个带有返回值的委托,同样用于定义方法的签名,可以有多个参数,并且返回一个值。它类似于C#中的普通函数,例如:Func<int, int, int>
表示一个接受两个整数参数并返回一个整数的函数。
2. 当使用 new BB()
创建 BB
的实例时,产生什么输出?
- 涉及构造函数、继承和多态性。
public class AA
{
public AA()
{
PrintFields();
}
public virtual void PrintFields()
{
}
}
public class BB : AA
{
int x = 1;
int y;
public BB()
{
y = -1;
}
public override void PrintFields()
{
Console.WriteLine($"x={x},y={y}");
}
}
解答
BB
类的构造函数BB()
被调用。- 由于
BB
继承自AA
,它首先会调用基类AA
的构造函数AA()
。 - 在
AA
的构造函数中,调用PrintFields()
方法。由于AA
类中的PrintFields()
是虚方法,它将调用BB
类中重写的PrintFields()
方法(即使AA
的构造函数中没有明确地调用BB.PrintFields()
)。 BB.PrintFields()
方法执行,输出当前实例的字段x
和y
的值。
在这个例子中,BB
类的构造函数设置了 y
的值为 -1
,而字段 x
被隐式初始化为 0
(因为在 BB
类中没有对 x
的初始化)。因此,输出将是:
x=0,y=-1
3. 以下代码输出什么?
string str1 = "123" + "abc";
int a = 123;
string str2 = a + "abc";
string str3 = "123abc";
Console.WriteLine(str1 == str2);
Console.WriteLine(str1.Equals(str2));
Console.WriteLine(System.Object.ReferenceEquals(str1, str2));
Console.WriteLine(System.Object.ReferenceEquals(str1, str3));
解答
True True False False
4. 写出 SQL 语句:取出表 A 中第 21 到第 30 记录 (SQL Server,以自动增长的 ID 作为主键,注意:ID 可能不是连续的)
解答
WITH RankedRecords AS (
SELECT
*,
ROW_NUMBER() OVER (ORDER BY ID) AS RowNum
FROM
A
)
SELECT
*
FROM
RankedRecords
WHERE
RowNum BETWEEN 21 AND 30;
这里的 WITH
语句定义了一个名为 RankedRecords
的公用表表达式(CTE),它为表 A 中的每条记录添加了一个行号。ROW_NUMBER() OVER (ORDER BY ID)
表示按照 ID 排序后为每行分配一个唯一的序号。然后外层的 SELECT
语句从这个 CTE 中选择序号在 21 到 30 之间的记录。
请注意,如果 ID 不是连续的,这种方法仍然有效,因为它依赖于行的顺序而不是 ID 的数值。如果您知道 ID 的范围或有其他排序要求,可以根据需要调整 ORDER BY
子句。
5. 生成下列结果的 SQL 语句
- 涉及 SQL 的分组和条件计数。
2005-05-09 胜
2005-05-09 胜
2005-05-09 负
2005-05-09 负
2005-05-10 胜
2005-05-10 负
2005-05-10 负
如果要生成下列结果,该如何写sql语句?
胜 负
2005-05-09 2 2
2005-05-10 1 2
解答
SELECT DateField, SUM(CASE WHEN Result = '胜' THEN 1 ELSE 0 END) AS 胜, SUM(CASE WHEN Result = '负' THEN 1 ELSE 0 END) AS 负 FROM TableName GROUP BY DateField ORDER BY MIN(YourOtherField); -- 这里假设有一个其他字段用于排序,如果没有可以去掉 MIN 和 YourOtherField
6. 简述 JavaScript 中的 =
、==
、===
的区别?
解答
在 JavaScript 中,赋值操作符和相等性比较操作符有不同的行为:
=
(单等号)是赋值操作符。它将右侧的值赋给左侧的变量。例如,a = 5
将变量a
的值设置为5
。==
(双等号)是抽象相等操作符。它比较两个值是否相等,但在比较之前会进行类型转换(如果需要)。这意味着如果两个值在转换为相同类型后内容相同,则==
会返回true
。例如,'5' == 5
返回true
,因为字符串'5'
被转换为了数字5
。===
(三等号)是严格相等操作符。它比较两个值是否严格相等,包括它们的类型。如果两个值的类型不同或内容不同,则===
返回false
。例如,'5' === 5
返回false
,因为一个是字符串类型,另一个是数字类型。
7. 下面 JavaScript 代码输出什么?
var myObject = {
foo: "bar",
func: function() {
var self = this;
console.log("outer func: this.foo=" + this.foo);
console.log("outer func: self.foo=" + self.foo);
var fn = function() {
console.log("inner func: this.foo=" + this.foo);
console.log("inner func: self.foo=" + self.foo);
}
var obj = { foo: "xyz" };
fn.call(obj);
}
};
myObject.func();
解答
这段代码定义了一个名为 myObject
的对象,它有两个属性:foo
和一个名为 func
的函数。func
函数内部定义了一个变量 self
引用 this
(指向 myObject
),然后输出 this.foo
和 self.foo
的值。接着定义了一个名为 fn
的内联函数,用来输出 this.foo
和 self.foo
的值。最后,创建了一个新对象 obj
并调用其上的 fn
函数,使用 .call(obj)
将 obj
设置为 fn
函数中的 this
上下文。
outer func: this.foo=bar // this 指向 myObject,输出 myObject.foo 的值
outer func: self.foo=bar // self 引用了 myObject,输出 myObject.foo 的值
inner func: this.foo=xyz // 在 fn.call(obj) 中,this 被设置为 obj,输出 obj.foo 的值
inner func: self.foo=bar // self 引用了 myObject,与 outer func 中的 self 相同,输出 myObject.foo 的值
8. 简述 ASP.NET MVC 中的 ViewData
, ViewBag
, TempData
, Model
解答
在 ASP.NET MVC 中,这些是用于在控制器和视图之间传递数据的机制:
ViewData
: 是一个字典对象,允许你存储键值对数据,可以在视图中访问这些数据。ViewData
的生命周期仅限于一次请求。ViewBag
: 是ViewData
的一个属性,它提供了一个动态类型的方式访问ViewData
。ViewBag
的属性可以通过表达式在视图中访问。TempData
: 用于存储临时数据,通常用于在一个请求中设置数据并在下一个请求中使用。TempData
可以跨请求传递数据,但仅一次。Model
: 是强类型的方式传递数据给视图。控制器将模型对象传递给视图,视图可以使用模型对象的属性和方法。
9. 写一个 C# 单例模式创建的例子,考虑多线程访问
解答
在 C# 中,可以使用静态初始化或锁来创建线程安全的单例模式:
public class Singleton
{
private static Singleton instance;
private static readonly object padlock = new object();
private Singleton() { }
public static Singleton Instance
{
get
{
if (instance == null)
{
lock (padlock)
{
if (instance == null)
{
instance = new Singleton();
}
}
}
return instance;
}
}
}
在这个例子中,Singleton
类使用双重检查锁定模式来确保多线程环境下只创建一个实例。
10. C# 中常数和只读变量的区别?
解答
C# 中的常数(使用 const
关键字)和只读变量(使用 readonly
关键字)都用于设置不可变的数据:
const
: 常数在编译时就已经确定,并且不能被修改。它们必须在声明时初始化。readonly
: 只读变量在运行时初始化,可以在声明时或构造函数中设置,但之后不能被修改。
11. 简述接口和抽象类的区别和应用场景?
解答
接口和抽象类都用于定义可以被子类实现或继承的契约:
接口定义了一组没有实现的方法和属性,它可以被任何类实现,一个类可以实现多个接口。
抽象类包含部分实现的方法和一定量的抽象成员,它用于定义一个类的基础框架,一个类只能继承一个抽象类。
接口适用于定义服务或行为的契约,而抽象类适用于定义一个家族类的共同特征。
12. 什么是 C# 的静态扩展方法?可用代码举例说明
解答
静态扩展方法是在 C# 3.0 中引入的一个特性,允许为现有类型添加新的方法而不需要继承或修改原始类型:
public static class StringExtensions
{
public static int WordCount(this string str)
{
return str.Split(new char[] { ' ', '\t', '\n' }, StringSplitOptions.RemoveEmptyEntries).Length;
}
}
// 使用扩展方法
int count = "Hello World".WordCount();
在这个例子中,WordCount
是一个扩展方法,它为 string
类型添加了一个新的方法来计算单词数量。
13. 简述 .NET 的反射用途?
解答
反射是 .NET 框架提供的一个强大的机制,它允许程序在运行时查询和操作对象的类型信息:
- 动态创建类型的对象。
- 访问类型的属性和方法。
- 获取类型的成员信息,如字段、属性、构造函数等。
- 修改私有成员的访问权限。
反射广泛应用于序列化、反序列化、依赖注入框架、动态代理等场景。
14. 什么是分布式系统中的幂等性?
解答
幂等性是指在分布式系统中,一个操作无论执行多少次,其结果都是相同的。换句话说,重复请求同一项操作不会对系统产生副作用。幂等性对于保证分布式系统的一致性和可靠性至关重要,特别是在网络请求可能会因为各种原因被重复发送的情况下。
例如,一个幂等的 HTTP GET 请求意味着多次请求相同的资源,服务器应该返回相同的响应,而不会导致资源状态的改变。