title | author | date | CreateTime | categories |
---|---|---|---|---|
C# 進階面試題 | lindexi | 2019-11-19 08:40:50 +0800 | 2018-11-12 11:18:2 +0800 | C# |
很少會有人可以答對,如果你遇到一個來面試的人實在嚣張,就可以用本文的題去打擊
本文内容就看着玩,請不要在嚴肅的面試中問題這樣的題目
如果面試到一個人可以回答出下面的題目也不能證明他的技術很強,隻能說明他了解很多C#相關,或者他看過我的部落格
循環下面的代碼
請在下面的代碼的注釋處填寫代碼,讓函數 Foo 裡面的代碼輸出
static void Main(string[] args)
{
// 請在此處寫代碼,調用 Foo 函數内的輸出代碼
}
private static void Foo()
{
try
{
while (true)
{
}
}
finally
{
Console.WriteLine("嘗試調用 Foo 函數執行這一句代碼");
}
}
參考答案
使用一個線程調用的方式,調用之後結束線程,此時就會輸出
static void Main(string[] args)
{
// 請在此處寫代碼,調用 Foo 函數内的輸出代碼
var thread = new Thread(Foo);
thread.Start();
Task.Delay(100).Wait();
thread.Abort();// 這時就會結束循環
Console.Read();
}
注意,在 dotnet core 不支援 Abort 方法
從空轉換
請寫出 IFoo 和 Foo 的實作,讓下面的代碼不會抛出空異常
static void Main(string[] args)
{
Foo foo = (IFoo) null;
foo.Name = "lindexi";
Console.Read();
}
參考答案
class IFoo
{
}
class Foo
{
public string Name { get; set; }
public static implicit operator Foo(IFoo foo)
{
return new Foo();
}
}
等待不存在的類
請添加新的類的代碼讓下面的代碼編譯通過
class Program
{
static async Task Main(string[] args)
{
Foo foo = await (object) null;
foo.Name = "lindexi";
Console.Read();
}
}
public class Foo
{
public string Name { get; set; }
}
參考答案
public class HeabdsdnbKevx : INotifyCompletion
{
public bool IsCompleted { get; }
public Foo GetResult()
{
return new Foo();
}
/// <inheritdoc />
public void OnCompleted(Action continuation)
{
}
}
public static class RelelnisSou
{
public static HeabdsdnbKevx GetAwaiter(this object obj)
{
return new HeabdsdnbKevx();
}
}
再進階一點,寫出下面的代碼
static async Task Main(string[] args)
{
await await await await await await await await await await await await
await await await await await await await "林德熙是逗比";
}
其實很簡單,也就是将 GetResult 修改一下,在上面的代碼修改
public string GetResult()
{
return "林德熙是逗比";
}
因為傳回值是 string 是以又可以繼續等待
如何不執行 finally 裡面的代碼
這裡有一個代碼,需要讓 finally 裡面的代碼不執行,現在你隻能寫 Foo 方法,同時這個方法不能運作無限長時間
try
{
Foo();
}
finally
{
Console.WriteLine("不要讓這個代碼運作");
}
參考答案
因為不能讓 Foo 運作無限長,就不能使用無限循環的方法,可以使用的方法有 Environment.FailFast 或 Environment.Exit 退出
private static void Foo()
{
Environment.Exit(0);
}
或者進行堆棧溢出,如下面代碼
private static void Foo()
{
Foo();
}
或者 少珺 小夥伴的不安全代碼申請
private static void Foo()
{
unsafe
{
var n = stackalloc int[int.MaxValue];
}
}
或者幹掉自己程序
private static void Foo()
{
Process.GetCurrentProcess().Kill();
}
但是申請大記憶體和退出目前線程方法都會讓 finally 執行
private static void Foo()
{
var n = new int[int.MaxValue];
}
// 雖然提示記憶體不夠,但是finally依然可以運作
退出目前線程抛出的是線程中斷異常,和其他異常一樣都能執行 finally 代碼
private static void Foo()
{
Thread.CurrentThread.Abort();
}
注意,在 dotnet core 不支援 Abort 方法
另外,如果進入 try 是不能使用 goto 跳出但不執行 finally 代碼
如果是在 VisualStudio 調試,在 Foo 執行完之後,在 VS 裡把調試箭頭拖到 finally 的後面
請問下面代碼輸出多少
請問下面的代碼的 n 的值是多少?
class Foo
{
public int N { get; } = 1;
}
Foo foo = null;
var n = 2 + foo?.N ?? 1;
Console.WriteLine(n);
參考答案
1
可能有小夥伴認為在
2 + foo?.N
這時如果 foo 為空就應該傳回
??
後面的值,但是這是不對的上面的代碼是和下面的代碼差不多等同的
if (foo == null)
{
n = 1;
}
else
{
n = 2 + foo.N;
}
而不是和下面的代碼等價的
if (foo == null)
{
n = 2 + 1;
}
else
{
n = 2 + foo.N;
}
在表達裡面隻有
?
的值為空,那麼就不會執行
等等,為什麼上面的代碼說的是差不多等同而不是等價,因為嘗試運作下面代碼,會看到 Hi 輸出,多謝 九鼎 指出
using System;
class Test
{
class Foo
{
public int N
{
get
{
Console.WriteLine("Hi.");
return 1;
}
}
}
static void Main()
{
Foo foo = null;
Foo foo2 = new Foo();
var n = 2 + foo?.N + foo2.N ?? 1;
Console.WriteLine(n);
}
}
上面代碼中,第一個
foo?.N
會進行判斷,因為 foo 不存在,是以整個表達式沒有執行,但是表達式内的邏輯依然執行
模式比對
請問下面代碼輸出什麼?
class B
{
public static int operator &(B left, B right) => 1;
public static int operator >(B left, B right) => 2;
public static int operator <(B left, B right) => 3;
public static int operator &(bool left, B right) => 5;
public static int operator >(bool left, B right) => 6;
public static int operator <(bool left, B right) => 7;
}
private static B B { get; }
static void Main(string[] args)
{
object a = null;
B c = null;
Console.WriteLine(a is B b & c);
Console.WriteLine(a is B b1 > c);
Console.WriteLine(a is B b2 < c);
a = new B();
Console.WriteLine(a is B b5 & c);
Console.WriteLine(a is B b6 > c);
Console.WriteLine(a is B b7 < c);
}
也許這是全部題目裡面最簡單的一道題
請看 C# 比對可空變量
其實這裡的
a is B
用的
B
是
class
不是定義的屬性,對
a is B b5
傳回的是
bool
是以将會是
bool
與
B
之間的運算