程序员面试题精选100题(62)-C/C++/C#面试题(5)
来源:互联网 发布:淘宝退货的运费险理赔 编辑:程序博客网 时间:2024/05/29 15:52
写在前面的话:本次选用的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题(56)-C/C++/C#面试题(4)
- 程序员面试题精选100题(56)-C/C++/C#面试题(4)
- 程序员面试题精选100题(53)-C++/C#面试题(2)
- 程序员面试题精选100题(54)-C++/C#面试题(3)
- C/C++/C#面试题精选(5)
- C/C++/C#面试题精选(5)
- C面试题精选
- C面试题精选
- C/C++/C#面试题精选
- C/C++/C#面试题精选
- C/C++/C#面试题精选4
- C/C++/C#面试题精选(23)-(25)
- C/C++/C#面试题精选(1)
- C/C++/C#面试题精选(2)
- C/C++/C#面试题精选(3)
- C/C++/C#面试题精选(4)
- C/C++/C#面试题精选(3)
- 为什么重写 description 方法
- 程序员面试题精选100题(61)-数对之差的最大值[算法]
- Qt构建工具QBS之一 ——从一个简单的工程开始
- Epoll在LT和ET模式下的读写方式
- Android 监听listview滚动状态。头部、尾部
- 程序员面试题精选100题(62)-C/C++/C#面试题(5)
- android studio出错集合
- .NET2.0程序集无法在.net 4.0 中运行的解决方案
- linux例行性工作 crontab详解
- Python字符串前缀U和R的区别
- MapReduce二次排序
- 程序员面试题精选100题(63)-数组中三个只出现一次的数字[算法]
- Android知识结构图
- android 布局