1、給定一個int數組,編寫方法以統計所有偶數的值。
有很多方法可以做到這一點,但是最直接的兩種方法是:
1 2 3 static long TotalAllEvenNumbers(int[] intArray) { return intArray.Where(i => i % 2 == 0).Sum(i => (long)i); }
還有就是
1 2 3 static long TotalAllEvenNumbers(int[] intArray) { return (from i in intArray where i % 2 == 0 select (long)i).Sum(); }
當然,你還需要注意以下關鍵:
你是否利用 C#語言特性 一行就解決問題。(即,不是使用包含循環,條件語句和累加器的更長篇幅的解決方案)
你是否考慮過溢出的可能性。例如,諸如
return intArray.Where(i => i % 2 == 0).Sum()(與函數的返回類型無關)
這可能一個很”明顯”的單行,但這樣溢出的可能性很高。雖然上面的答案中使用的轉換為long的方法并沒有消除這種可能性,但是它使得發生溢出異常的可能性非常小。但請注意,如果你寫答案的時候詢問數組的預期大小及其成員的大小,則顯然你在做這道題目的時候在考慮此溢出問題,這很棒。
2、下面的代碼的輸出是什么?解釋你的答案。 1 2 3 4 5 6 7 8 9 class Program { static String location; static DateTime time; static void Main() { Console.WriteLine(location == null ? "location is null" : location); Console.WriteLine(time == null ? "time is null" : time.ToString()); } }
輸出將是:
1 2 location is null 1/1/0001 12:00:00 AM
下面的簡短程序的輸出是什么?解釋你的答案。簡短程序的輸出是什么?解釋你的答案。 盡管兩個變量都未初始化,但是String是引用類型 、DateTime 是值類型。作為值類型,單位化DateTime變量設置為默認值 公元1年晚上12點,而不是 null
3、下面語句中 time 和null 的比較是有效還是無效的? 1 2 3 4 5 6 static DateTime time; /* ... */ if (time == null) { /* do something */ }
有人可能會認為,由于變量永遠不可能為null (它被自動初始化為1月1日的值),所以編譯器在比較某個變量時就會報錯。具體來說,操作符將其操作數強制轉換為不同的允許類型,以便在兩邊都得到一個通用類型,然后可以對其進行比較。這就是為什么像這樣的東西會給你期望的結果(而不是失敗或意外的行為,因為操作數是不同的類型):
1 2 3 double x = 5.0; int y = 5; Console.WriteLine(x == y); // outputs true
然而,這有時會導致意外的行為,例如DateTime變量和null的比較。在這種情況下,DateTime變量和null文字都可以轉換為可空的。因此,比較這兩個值是合法的,即使結果總是假的。
4、給定circle以下類的實例: 1 2 3 4 5 6 7 public sealed class Circle { private double radius; public double Calculate(Func<double, double> op) { return op(radius); } }
簡編寫代碼以計算圓的周長,而無需修改Circle類本身。 首選的答案如下:
1 circle.Calculate(r => 2 * Math.PI * r);
由于我們不能訪問對象的私有半徑字段,所以我們通過內聯傳遞計算函數,讓對象本身計算周長。
許多c#程序員回避(或不理解)函數值參數。雖然在這種情況下,這個例子有點做作,但其目的是看看申請人是否了解如何制定一個調用來計算哪個與方法的定義相匹配。
另外,一個有效的(雖然不那么優雅的)解決方案是從對象中檢索半徑值本身,然后執行計算結果:
1 2 var radius = circle.Calculate(r => r); var circumference = 2 * Math.PI * radius;
無論哪種方式。我們在這里主要尋找的是面試者是否熟悉并理解如何調用Calculate方法。
5、下面程序的輸出是什么?解釋你的答案。 1 2 3 4 5 6 7 8 9 10 11 12 13 class Program { private static string result; static void Main() { SaySomething(); Console.WriteLine(result); } static async Task<string> SaySomething() { await Task.Delay(5); result = "Hello world!"; return “Something”; }
下面 此外,如果我們替換wait task,答案會改變嗎? 比如 thread . sleep (5) ? 為什么?的簡短
程序的輸出是什么?解釋你的答案。序的輸出是什么?解釋你的答案。
回答:
問題第一部分(即帶有的代碼版本await Task.Delay(5);)的答案是該程序將僅輸出一個空行(而不是 “ Hello world!”)。這是因為調用result時仍將未初始化Console.WriteLine。
大多數程序和面向對象的程序員都希望函數return在返回調用函數之前從頭到尾執行,或者從語句執行。C#async函數不是這種情況。它們只執行到第一個await語句,然后返回到調用方。由await(在此例中為Task.Delay)調用的函數是異步執行的,并且該await語句之后的行直到Task.Delay完成(在5毫秒內)之前都不會發出信號。但是,在這段時間內,控制權已經返回給調用者,該調用者Console.WriteLine對尚未初始化的字符串執行該語句。
調用await Task.Delay(5) 可讓當前線程繼續其正在執行的操作,如果已完成(等待任何等待),則將其返回到線程池。這是異步/等待機制的主要好處。它允許CLR使用線程池中的更少線程來服務更多請求。
異步編程已經變得越來越普遍,因為執行許多活動的網絡服務請求或數據庫請求的設備越來越普遍。C#具有一些出色的編程結構,可以極大地簡化異步方法的編程任務,并且意識到它們的程序員將產生更好的程序。
關于問題的第二部分,如果將await Task.Delay(5);其替換為Thread.Sleep(5),則程序將輸出Hello world!。一種沒有至少一個語句的async方法,其操作就像同步方法一樣。也就是說,它將從頭到尾執行,或者直到遇到一條語句為止。調用只是阻塞了當前正在運行的線程,因此調用僅將方法的執行時間增加了5毫秒。awaitreturnThread.Sleep()Thread.Sleep(5)SaySomething()
6、下面的程序輸出是什么?解釋你的答案。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 delegate void Printer(); static void Main() { List<Printer> printers = new List<Printer>(); int i=0; for(; i < 10; i++) { printers.Add(delegate { Console.WriteLine(i); }); } foreach (var printer in printers) { printer(); } }
這個程序將把數字10輸出十次。
原因如下: 委托被添加到 for循環中l了,而 “引用” (或者“指針”)被存儲到i中,而不是值本身。因此,在我們退出循環之后,變量i被設置為10,所以到調用每個委托時,傳遞給它們的值都是10。
7、是否可以將混合數據類型(例如int,string,float,char)全部存儲在一個數組中? 是! 之所以可以這樣做,是因為數組的類型object不僅可以存儲任何數據類型,還可以存儲類的對象,如下所示:
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 using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication8 { class Program { class Customer { public int ID { get; set; } public string Name { get; set; } public override string ToString() { return this.Name; } } static void Main(string[] args) { object[] array = new object[3]; array[0] = 101; array[1] = "C#"; Customer c = new Customer(); c.ID = 55; c.Name = "Manish"; array[2] = c; foreach (object obj in array) { Console.WriteLine(obj); } Console.ReadLine(); } } }
8、比較C#中的結構和類。他們有什么共同點?它們有何不同? C#中的類和結構確實有一些共同點,即:
他們都是
是復合數據類型
可以包含方法和事件
可以支持接口
但是有許多差異。比較一下:
類:
支持繼承
是引用(指針)類型
引用可以為空
每個新實例都有內存開銷
結構:
不支持繼承
是值類型
按值傳遞(如整數)
不能有空引用(除非使用了Nullable)
每個新實例沒有內存開銷(除非“裝箱”)
9、這里有一個包含一個或多個$符號的字串,例如: 1 "foo bar foo $ bar $ foo bar $ "
問題:如何$從給定的字符串中刪除第二和第三次出現的? 答案:
使用如下正則表達式:
1 2 3 4 string s = "like for example $ you don't have $ network $ access"; Regex rgx = new Regex("\\$\\s+"); s = Regex.Replace(s, @"(\$\s+.*?)\$\s+", "$1$$"); Console.WriteLine("string is: {0}",s);
說明:
TestValue : 10
在創建該類的任何實例之前,將調用該類的靜態構造函數。此處調用的靜態構造函數TestValue首先將變量初始化。
11、有沒有一種方法可以修改ClassA、以便您可以在調用Main方法時使用參數調用構造函數,而無需創建任何其他新實例ClassA? 1 2 3 4 5 6 class ClassA { public ClassA() { } public ClassA(int pValue) { } }
啟動類
1 2 3 4 5 6 7 class Program { static void Main(string[] args) { ClassA refA = new ClassA(); } }
回答:
所述this關鍵字被用于調用其他構造,初始化該類對象。下面是實現:
1 2 3 4 5 6 7 8 class ClassA { public ClassA() : this(10) { } public ClassA(int pValue) { } }
12、以下代碼輸出什么? 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 using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace main1 { class Program { static void Main(string[] args) { try { Console.WriteLine("Hello"); } catch (ArgumentNullException) { Console.WriteLine("A"); } catch (Exception) { Console.WriteLine("B"); } finally { Console.WriteLine("C"); } Console.ReadKey(); } } }
答案:
13、描述依賴注入。 依賴注入是一種使緊密鏈接的類分離的方式,從而減少了類之間的直接依賴。有多種方法可以實現依賴項注入:
構造函數依賴
屬性依賴
方法依賴
14、編寫一個C#程序,該程序接受以千米為單位的距離,將其轉換為米,然后顯示結果。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 using system; class abc { public static Void Main() { int ndistance, nresult; Console.WriteLine("Enter the distance in kilometers"); ndistance = convert.ToInt32(Console.ReadLine()); nresult = ndistance * 1000; Console.WriteLine("Distance in meters: " + nresult); Console.ReadLine(); } }
15、描述裝箱和拆箱。并寫一個例子。 裝箱是將值類型隱式轉換為該類型object或該值類型實現的任何接口類型。將值類型裝箱會創建一個包含該值的對象實例,并將其存儲在堆中。
例:
1 2 3 4 5 int x = 101; object o = x; // boxing value of x into object o o = 999; x = (int)o; // unboxing value of o into integer x
最后: 面試不僅要基礎扎實,更重要的是能解決棘手的技術問題,所以以上這些內容僅供參考。并非每個值得招聘的優秀候選人都能夠回答所有問題,也不能確定能夠全部回答,就能保證他是一個優秀候選人。歸根結底,招聘仍然是一門藝術,一門科學以及許多工作。
原文來自:https://www.toptal.com/c-sharp/top-10-mistakes-that-c-sharp-programmers-make
該文章在 2024/10/9 17:52:41 編輯過