程序员面试题精选100题(62)-C/C++/C#面试题(5)
寫在前面的話:本次選用的5道題,是我微博(http://weibo.com/zhedahht和http://t.163.com/zhedahht)中#面試每日一題#系列的第21題到第25題。有合適的題目,我會繼續收集C/C++/C#的面試題,并不定期發表到博客和大家分享。
問題(21):C#是一門托管語言,那么是不是說明只要用C#,就能保證不會出現內存泄露和其他資源泄漏?如果不是,在哪些情況下可能會出現泄漏?
答案:C#不能保證沒有資源泄漏。比如如下幾種情況可能會造成資源泄漏:(1)?調用Native code,比如用P/Invoke或者調用COM;(2)?讀寫文件時的,沒有及時close stream,?或者ADO.NET連數據庫時,沒有及時關閉連接,也算資源泄漏?(3)注冊事件后沒有remove,導致publisher和subscriber的強依?賴,垃圾回收可能會被推遲;(4).NET還定義了一些方法直接申請非托管內存,比如Marshal.AllocHGlobal和Marshal.AllocCoTaskMem。通過這種方式得到的內存,如果沒有及時釋放,也會造成內存泄露。
問題(22):下面的兩段C#有哪些不同?
static void CatchException1() {try{Function();}catch{throw;} }static void CatchException2() {try{Function();}catch (Exception e){throw e;} }答案:兩個函數的catch都是重新拋出截獲的exception,但拋出的exception的call stack是不一樣的。對于第一種方法,exception的call stack是從最開始的拋出地點開始的。對于第二種方法,exception的call stack是從CatchException2開始的,最初拋出的地方相關的信息被隱藏了。
問題(23):運行下圖中的C++代碼,打印出的結果是什么?
bool Fun1(char* str) {printf("%s\n", str);return false; }bool Fun2(char* str) {printf("%s\n", str);return true; }int _tmain(int argc, _TCHAR* argv[]) {bool res1, res2;res1 = (Fun1("a") && Fun2("b")) || (Fun1("c") || Fun2("d"));res2 = (Fun1("a") && Fun2("b")) && (Fun1("c") || Fun2("d"));return res1 || res2; }答案:打印出4行,分別是a、c、d、a。
在C/C++中,與、或運算是從左到右的順序執行的。在計算rest1時,先計算Fun1(“a”) && Func2(“b”)。首先Func1(“a”)打印出內容為a的一行。由于Fun1(“a”)返回的是false,?無論Func2(“b”)的返回值是true還是false,Fun1(“a”) && Func2(“b”)的結果都是false。由于Func2(“b”)的結果無關重要,因此Func2(“b”)會略去而不做計算。接下來計算Fun1(“c”) || Func2(“d”),分別打印出內容c和d的兩行。
????????????????在計算rest2時,首先Func1(“a”)打印出內容為a的一行。由于Func1(“a”)返回false,和前面一樣的道理,Func2(“b”)會略去不做計算。由于Fun1(“a”) && Func2(“b”)的結果是false,不管Fun1(“c”) && Func2(“d”)的結果是什么,整個表達式得到的結果都是false,因此Fun1(“c”) && Func2(“d”)都將被忽略。
問題(24):運行下面的C#代碼,打印出來的結果是什么?
struct Person {public string Name;public override string ToString(){return Name;} }class Program {static void Main(string[] args){ArrayList array = new ArrayList();Person jim = new Person() {Name = "Jim"};array.Add(jim);Person first = (Person)array[0];first.Name = "Peter";Console.WriteLine(array[0].ToString());} }答案:Person的定義是一個struct,因此是一個值類型。在運行到語句Person first = (Person)array[0]的時候,first是array[0]的一個拷貝,first和array[0]不是一個實例。因此修改first對array[0]沒有影響。
問題(25):運行下面的C++代碼,打印的結果是什么?
class Base { public:void print() { doPrint();}private:virtual void doPrint() {cout << "Base::doPrint" << endl;} };class Derived : public Base { private:virtual void doPrint() {cout << "Derived::doPrint" << endl;} };int _tmain(int argc, _TCHAR* argv[]) {Base b;b.print();Derived d;d.print();return 0; }答案:輸出兩行,分別是Base::doPrint和Derived::doPrint。在print中調用doPrint時,doPrint()的寫法和this->doPrint()是等價的,因此將根據實際的類型調用對應的doPrint。所以結果是分別調用的是Base::doPrint和Derived::doPrint2。如果感興趣,可以查看一下匯編代碼,就能看出來調用doPrint是從虛函數表中得到函數地址的。
博主何海濤對本博客文章享有著作權。網絡轉載請注明出處http://zhedahht.blog.163.com/。整理出版物請和作者聯系。
總結
以上是生活随笔為你收集整理的程序员面试题精选100题(62)-C/C++/C#面试题(5)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 程序员面试题精选100题(61)-数对之
- 下一篇: c# char unsigned_dll