技术类C++面试

来源:互联网 发布:abb变频器仿真软件 编辑:程序博客网 时间:2024/05/16 03:33

术类C++面试 

导读:
  1.已知strcpy 函数的原型是:
  char *strcpy(char *strDest, const char *strSrc);
  其中strDest 是目的字符串,strSrc 是源字符串。不调用C++/C 的字符串库函数,请编写函数 strcpy
  答案:
  char *strcpy(char *strDest, const char *strSrc)
  {
  if ( strDest == NULL || strSrc == NULL)
  return NULL ;
  if ( strDest == strSrc)
  return strDest ;
  char *tempptr = strDest ;
  while( (*strDest++ = *strSrc++) != ‘’)
  return tempptr ;
  }
  2.已知类String 的原型为:
  class String
  {
  public:
  String(const char *str = NULL); // 普通构造函数
  String(const String &other); // 拷贝构造函数
  ~ String(void); // 析构函数
  String & operate =(const String &other); // 赋值函数
  private:
  char *m_data; // 用于保存字符串
  };
  请编写String 的上述4 个函数。
  答案:
  String::String(const char *str)
  {
  if ( str == NULL ) //strlen在参数为NULL时会抛异常才会有这步判断
  {
  m_data = new char[1] ;
  m_data[0] = ' ;
  }
  else
  {
  m_data = new char[strlen(str) + 1];
  strcpy(m_data,str);
  }
  }
  String::String(const String &other)
  {
  m_data = new char[strlen(other.m_data) + 1];
  strcpy(m_data,other.m_data);
  }
  String & String::operator =(const String &other)
  {
  if ( this == &other)
  return *this ;
  delete []m_data;
  m_data = new char[strlen(other.m_data) + 1];
  strcpy(m_data,other.m_data);
  return *this ;
  }
  String::~ String(void)
  {
  delete []m_data ;
  }
  3.简答
  3.1 头文件中的ifndef/define/endif 干什么用?
  答:防止该头文件被重复引用。
  3.2#include 和#include “filename.h” 有什么区别?
  答:对于#include ,编译器从标准库路径开始搜索filename.h
  对于#include “filename.h”,编译器从用户的工作路径开始搜索filename.h
  3.3 在C++ 程序中调用被C 编译器编译后的函数,为什么要加extern “C”?
  答:C++语言支持函数重载,C 语言不支持函数重载。函数被C++编译后在库中的名字与C 语言的不同。假设某个函数的原型为: void foo(int x, int y);
  该函数被C 编译器编译后在库中的名字为_foo , 而C++ 编译器则会产生像_foo_int_int 之类的名字。
  C++提供了C 连接交换指定符号extern“C”来解决名字匹配问题。
  3.4 一个类有基类、内部有一个其他类的成员对象,构造函数的执行顺序是怎样的。(Autodesk)
  答:先执行基类的(如果基类当中有虚基类,要先执行虚基类的,其他基类则按照声明派生类时的顺序依次执行),再执行成员对象的,最后执行自己的。
  3.5 请描述一个你熟悉的设计模式(Autodesk)
  3.6 在UML 中,聚合(aggregation)和组合(composition)有什么区别 Autodesk)
  答案:聚合关系更强,类似于pages 和book 的关系;组合关系要弱,类似于books和bookshelf 的关系。
  3.7C#和C++除了语法上的差别以外,有什么不同的地方?(Autodesk,Microsoft)
  答案:(C#我只是了解,不是很精通)
  (1) c#有垃圾自动回收机制,程序员不用担心对象的回收。(2)c#严禁使用指针,只能处理对象。如果希望使用指针,则仅可在unsafe程序块中能使用指针。(3)c#只能单继承。(4)必须通过类名访问静态成员。不能像C++中那样,通过对象访问静态成员。(5)在子类中覆盖父类的虚函数时必须用关键字override,覆盖父类的方法要用关键字new
  3.8ADO.net 和ADO 的区别?
  答案:实际上除了“能够让应用程序处理存储于DBMS 中的数据“这一基本相似点外,两者没有太多共同之处。但是ADO 使用OLE DB接口并基于微软的COM 技术,而ADO.NET 拥有自己的ADO.NET 接口并且基于微软的.NET 体系架构。众所周知.NET体系不同于COM 体系,ADO.NET 接口也就完全不同于ADO和OLE DB 接口,这也就是说ADO.NET和ADO是两种数据访问方式。ADO.net 提供对XML 的支持。
  3.9 New delete 与malloc free 的区别 ( Autodesk)
  答案:用malloc 函数不能初始化对象,new 会调用对象的构造函数。Delete 会调用对象的destructor,而free 不会调用对象的destructor.
  3.10 #define DOUBLE(x) x+x (Autodesk)
  i = 5*DOUBLE(10); i 是多少?正确的声明是什么?
  答案:i 为60。正确的声明是#define DOUBLE(x) (x+x)
  3.11 有哪几种情况只能用intialization list 而不能用assignment? (Autodesk)
  答案:当类中含有const、reference 成员变量;基类的构造函数都需要参数;类中含有其他类的成员对象,而该类的构造函数都需要参数。
  3.11 C++是不是类型安全的? (Autodesk)
  答案:不是。两个不同类型的指针之间可以强制转换。C#是类型安全的。
  3.12 main 函数执行以前,还会执行什么代码? (Autodesk)
  答案:全局对象的构造函数会在main 函数之前执行。
  3.13 描述内存分配方式以及它们的区别。 (Autodesk , Microsoft)
  答案:1) 从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static 变量。
  (2) 在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集。
  (3) 从堆上分配,亦称动态内存分配。程序在运行的时候用malloc 或new 申请任意多少的内存,程序员自己负责在何时用free 或delete 释放内存。动态内存的生存期由我们决定,使用非常灵活,但问题也最多。
  3.14 什么是虚拟存储器?virtual memory 怎样映射到physical memory?页面替换算法有哪些? (Microsoft)
  见操作系统 p238 页。掌握的页面替换算法NRU,FIFO,第二次机会页面替换算法,LRU
  3.15 有四个同样的容器,里面装满了粒数相同的药丸,正常药丸的质量为m,变质药丸的质量为m+1,现在已知这四个容器中,有一个装的全是变质药丸,用电子秤只称一次,找出哪个容器装的是变质药丸 (Microsoft)
  答案:把四个容器依次编号为1、2、3、4,然后从中分别取出1、2、3、4 粒药丸,称这10 粒药丸的质量,如果质量为10m+1,则说明第一个容器装的是变质药丸,如果为10m+2 则说明第二个装的变质药丸,依次类推。
  3.16 比较一下C++中static_cast 和 dynamic_cast 的区别。 (Autodesk)
  dynamic_casts在帮助你浏览继承层次上是有限制的。它不能被用于缺乏虚函数的类型上,它被用于安全地沿着类的继承关系向下进行类型转换。如你想在没有继承关系的类型中进行转换,你可能想到static_cast
  3.17 Struct 和class 的区别 (Autodesk)
  答案:struct 中成员变量和成员函数默认访问权限是public,class 是private
  3.18 当一个类A 中没有生命任何成员变量与成员函数,这时sizeof(A)的值是多少,如果不是零,请解释一下编译器为什么没有让它为零。(Autodesk)
  答案:肯定不是零。我举个反例,如果是零的话,声明一个class A[10]对象数组,而每一个对象占用的空间是零,这时就没办法区分A[0],A[1]…了
  3.19 在8086 汇编下,逻辑地址和物理地址是怎样转换的?(Intel)
  答案:通用寄存器给出的地址,是段内偏移地址,相应段寄存器地址*10H+通用寄存器内地址,就得到了真正要访问的地址。
  3.20 描述一下C++的多态 (microsoft)
  答案:C++的多态表现在两个部分,一个是静态连编下的函数重载,运算符重载;动态连编下的虚函数、纯虚函数(抽象类)
  4.写出BOOL,int,float,指针类型的变量a 与零的比较语句。
  答案:
  BOOL : if ( !a )
  int : if ( a == 0)
  float : const EXPRESSION EXP = 0.000001
  if ( a < EXP && a >-EXP)
  pointer : if ( a != NULL)
  5.请说出const 与#define 相比优点
  答案:
  (1) const 常量有数据类型,而宏常量没有数据类型。编译器可以对前者进行类型安全检查。而对后者只进行字符替换,没有类型安全检查,并且在字符替换可能会产生意料不到的错误。
  (2) 有些集成化的调试工具可以对const 常量进行调试,但是不能对宏常量进行调试。
  6.简述数组与指针的区别
  数组要么在静态存储区被创建(如全局数组),要么在栈上被创建。指针可以随时指向任意类型的内存块。
  (1)修改内容上的差别
  char a[] = “hello”;
  a[0] = ‘X’;
  char *p = “world”; // 注意p 指向常量字符串
  p[0] = ‘X’; // 编译器不能发现该错误,运行时错误
  (2) 用运算符sizeof 可以计算出数组的容量(字节数)。sizeof(p),p 为指针得到的是一个指针变量的字节数,而不是p所指的内存容量。C++/C语言没有办法知道指针所指的内存容量,除非在申请内存时记住它。注意当数组作为函数的参数进行传递时,该数组自动退化为同类型的指针。
  char a[] = "hello world";
  char *p = a;
  cout<< sizeof(a) << endl; // 12 字节
  cout<< sizeof(p) << endl; // 4 字节
  计算数组和指针的内存容量
  void Func(char a[100])
  {
  cout<< sizeof(a) << endl; // 4 字节而不是100 字节
  }
  7.类成员函数的重载、覆盖和隐藏区别
  答案:
  成员函数被重载的特征:
  (1)相同的范围(在同一个类中);
  (2)函数名字相同;
  (3)参数不同;
  (4)virtual 关键字可有可无。
  覆盖是指派生类函数覆盖基类函数,特征是:
  (1)不同的范围(分别位于派生类与基类);
  (2)函数名字相同;
  (3)参数相同;
  (4)基类函数必须有virtual 关键字。
  “隐藏”是指派生类的函数屏蔽了与其同名的基类函数,规则如下:
  (1)如果派生类的函数与基类的函数同名,但是参数不同。此时,不论有无virtual关键字,基类的函数将被隐藏(注意别与重载混淆)。
  (2)如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual 关键字。此时,基类的函数被隐藏(注意别与覆盖混淆)
  8.There are two int variables: a and b, don’t use “if”, “? :”, “switch”
  or other judgement statements, find out the biggest one of the two
  numbers.
  答案:( ( a + b ) + abs( a – b ) ) / 2
  9.如何打印出当前源文件的文件名以及源文件的当前行号?
  答案:
  cout << __FILE__ ;
  cout<<__LINE__ ;
  __FILE__和__LINE__是系统预定义宏,这种宏并不是在某个文件中定义的,而是由编译器定义的。
  10.main 主函数执行完毕后,是否可能会再执行一段代码,给出说明?
  答案:可以,可以用_onexit 注册一个函数,它会在main 之后执行int fn1(void), fn2(void), fn3(void), fn4 (void);
  void main( void )
  {
  String str("zhanglin");
  _onexit( fn1 );
  _onexit( fn2 );
  _onexit( fn3 );
  _onexit( fn4 );
  printf( "This is executed first./n" );
  }
  int fn1()
  {
  printf( "next./n" );
  return 0;
  }
  int fn2()
  {
  printf( "executed " );
  return 0;
  }
  int fn3()
  {
  printf( "is " );
  return 0;
  }
  int fn4()
  {
  printf( "This " );
  return 0;
  }
  The _onexit function is passed the address of a function (func) to becalled when the program terminates normally. Successive calls to_onexit create a register of functions that are executed in LIFO(last-in-first-out) order. The functions passed to _onexit cannot takeparameters.
  11.如何判断一段程序是由C 编译程序还是由C++编译程序编译的?
  答案:
  #ifdef __cplusplus
  cout<<"c++";
  #else
  cout<<"c";
  #endif
  12.文件中有一组整数,要求排序后输出到另一个文件中
  答案:
  void Order(vector
  {
  int count = data.size() ;
  int tag = false ;
  for ( int i = 0 ; i < count ; i++)
  {
  for ( int j = 0 ; j < count - i - 1 ; j++)
  {
  if ( data[j] > data[j+1])
  {
  tag = true ;
  int temp = data[j] ;
  data[j] = data[j+1] ;
  data[j+1] = temp ;
  }
  }
  if ( !tag )
  break ;
  }
  }
  void main( void )
  {
  vectordata;
  ifstream in("c://data.txt");
  if ( !in)
  {
  cout<<"file error!";
  exit(1);
  }
  int temp;
  while (!in.eof())
  {
  in>>temp;
  data.push_back(temp);
  }
  in.close();
  Order(data);
  ofstream out("c://result.txt");
  if ( !out)
  {
  cout<<"file error!";
  exit(1);
  }
  for ( i = 0 ; i < data.size() ; i++)
  out<<<"
  }
  ~B()
  {
  cout<<"destructed"<
  }
  B(int i):data(i)
  {
  cout<<"constructed by parameter" << data <
  }
  private:
  int data;
  };
  B Play( B b)
  {
  return b ;
  }
  int main(int argc, char* argv[])
  {
  B temp = Play(5);
  return 0;
  }
  请自己执行一下看看。
  16.写一个函数找出一个整数数组中,第二大的数 (microsoft)
  答案:
  const int MINNUMBER = -32767 ;
  int find_sec_max( int data[] , int count) //类似于1 4 4 4这样的序列将认为1是第二大数
  {
  int maxnumber = data[0] ;
  int sec_max = MINNUMBER ;
  for ( int i = 1 ; i < count ; i++)
  {
  if ( data[i] > maxnumber )
  {
  sec_max = maxnumber ;
  maxnumber = data[i] ;
  }
  else
  {
  if ( data[i] > sec_max )
  sec_max = data[i] ;
  }
  }
  return sec_max ;
  }
  17 写一个在一个字符串中寻找一个子串第一个位置的函数
  这个题目的一般算法比较简单我就不给出了,如果要求高效率的话请参见数据结构中的KMP 算法,不过在笔试时间有限情况下,写出那个算法还是挺难的。
  英文题目
  1. Introduce yourself in English
  2. What is your great advantage you think of yourself?
  3. What is your drawback you think of yourself?
  4. How do you feel shanghai?
  改用c++继续轰炸,写构造函数和赋值运算符。
  虚函数的一些东东,还有cast。
  3.
  stl 里面vector的实现(内部空间的申请与分配)--我晕 这个我也不会,没看过
  struct /class的区别
  为什么要用struct //成员的默认属性不同,用struct的话,主要是作为数据的集合
  怎样使一个class不能被实例化 //1,构造函数私有化,2,抽象类
  私有继承和public继承的区别。 //is-a has-a
  void *p的问题 //不能++
  引用和指针的区别与联系。引用是否可以更改 //引用类似于常量指针,一旦初始化,不
  能更改。
  windows编程基础,线程与进程的区别 //我竟然忘了
  com+是否熟悉,(没用过)
  还问了我几个我都没有听说过的名词
  然后就是数据结构/算法的问题
  简述一下hash算法
  一个32位的数据,怎样找到最左边的一个1
  一个4*4的格子,填入1~15 然后给个目标状态,怎样去搜索。
  给你100万个数据,数据的值在0~65535之间 用最快的速度排序
  最后一个问题:
  如果我们的一个软件产品,用户回复说:运行速度很慢,你怎么处理
  1,hash算法,这个我忘得差不多了,他给了我一个提示,我想起来了。ok
  2,n位的2进制数据怎样找罪左边的1,如果是在最左位,这个数是负数,否则的话,左移
  一位,看是否变成负数,这是O(n)的算法,O(n/2)的算法:二分方式查找
  3,广度优先搜索+启发式
  4,统计每个数字出现的频率
  5,这个我也没经验,乱说了一通。
  一上来面试官就说,根据你的简历,我们会关注与算法方面的问题,
  1,八皇后问题,详述解法 ---轻松搞定
  2,kmp快速匹配算法 ---不算轻松的搞定
  3,无向图中两点间最短路问题 ---伟大的迪杰克斯拉算法
  4,空间中任意给两个向量,求角平分线 他给了个提示,解决
  5,什么是平衡树 ---光说上概念来了,其他的不会了(昨晚光看b-,b+树了)
  6,哈夫曼编码问题 ---回答的有些混乱
  7,求1~10000的素数 ---筛选法,有点细节没处理好
  8,有向图求环 ---我只会搜索,在他的提示下,还是没有做出来
  9,给n个点,求凸包问题 ---hiahia,牛X一把,用二分作的!
  10,堆排序 ---明确地告诉了他,俺忘了
  11,四则运算
  (1)给一个前缀表达式,然后求解 ---勉强做上来了
  (2)给一个中缀表达式,求解 ---更勉强的作上来了
  12,正则表达式
  然后,换人,考智力:
  1,3个门,分别叫做:日月星
  日:此门通向光明
  月:此门非通向光明
  星:月非通向光明
  至少一个说真话,至少一个说假话,一个通向光明
  问:谁通向光明,----答:星,需要假设来做
  2,不均匀的绳子测一个小时,答:两头烧,---我和他讨论了一下,是否可能无法解决,
  他说,就是两头烧
  3,一个长方形,里面随即挖去另一个长方形,一刀把它平分。---中点相连接
  4,4个人过河,怎样最快 1,2,5,7。 答:我以前做过,给我点时间
  5,给你三个盒子,其中一个放了东西,你指定一个,然后打开另外两个中的一个,发现是
  空的,问:你是否要改变你的选择。 答:我觉着不应该改变,但他说要改变,我想了半天
  ,没想出来,放弃
  6, 1,2,5 3中硬币,有无数个,然后给你个n,让你用最少的硬币数组成n ---我竟然用
  动态规划作,他告诉我,麻烦了, 贪心,搞定
  7,开放性题目:怎样测一个飞机的重量,---答:问厂商,问:还有呢?答:根据发动机
  的推力和耗油量,可以推出一个大体值,但有很多影响因素,放弃。
  8,给一个正方体,两个对面上有两个点,沿着体表面,找一条最短路,---答:拆开,
  直线最短
  期间还问了我 线程和进程的区别,---答:上次问过了。
  5.1.STL中container有哪些?
  答:vector,list,set,multiset,map,multimap,deque,bitset
  2.map中的数据存储方式是什么?
  答:Hashtable
  3.map和hashmap有什么区别?
  答:不知道。
  4.hashmap是标准库中的吗?
  答:不是。
  5.vector中的erase方法跟algorithm的remove有什么区别?
  答:我不怎么清楚,只知道remove_if可以用function object。还有可能vector自带的erase在执行过后会有一些优化的方法吧。
  6.function object是什么?
  答:(这个我说了半天,反正就是描述一下)
  大概就是这么几道题,他问我的STL不多,欢迎大家讨论:)
  其他部分过几天陆续放出,敬请期待!
  5 1. C++中如何阻止一个类被实例化?
  答:抽象类,或者构造函数被声明成private
  2. 一般在什么时候构造函数被声明成private呢?
  答:比如要阻止编译器生成默认的copy constructor
  3. 什么时候编译器会生成默认的copy constructor呢?
  答:只要自己没写,而程序中需要,都会生成
  4. 如果你已经写了一个构造函数,编译器还会生成copy constructor吗?
  答:会
  5. struct和class有什么区别?
  答:默认的访问级别不同,struct是public,class是private
  6. 没有别的不同了吗?
  答:好像没有了吧……
  7. 为什么说如果一个类作为基类,则它的析构函数要声明成virtual的?
  答:(Effective C++ 条款14,我当时刚刚复习过,呵呵)
  8. inline的函数和#define有什么区别?
  答:类型检查
  9. inline是什么意思?
  答:就是不产生call,直接把函数的代码嵌入程序。但是inline不是强制的,是
  编译器根据需要决定函数是否真的被inline
  10. 那你说说什么时候会真的被inline,什么时候不会呢?
  答:(略)
  11. 如果把一个类的成员函数写在类的声明中是什么意思?
  答:inline
  12. public继承和private继承有什么架构上的区别?
  答:public是is-a的关系,private是has-a的关系
  13. 在多继承的时候,如果一个类继承同时继承自class A和class B,而class A和
  B中都有一个函数叫foo(),如何明确的在子类中指出override哪个父类的foo()?
  答:虚拟继承吧……(我想了半天也不记得这个怎么弄了,他也就没有继续难为
  我)
  14. 虚拟继承的语法是什么?
  答:class C : public A, virtual public B
  15. 部分模版特例化(我忘了他当时怎么翻译这个词的了,反正就是partial temp
  late specialization)和全部模版特例化有什么区别?
  答:(想了半天)就是是不是还有一个通用的模版的区别。这个特性在VC中不支
  持,所以我不是很熟悉,不好意思……
  16. 哦?VC不支持?你确定
  答:确定!(.net刚出的时候,我特意看过MSDN,上面写着VC7.0中有3个C++的
  特性没有支持,其中就有这个,没想到他连这个都考!)
  6大家讨论啊!希望对我的回答更正一下,谢谢:)
  1.编一个函数,使一个单项链表转置。
  2.拆解一个整数,比如4,可以拆解成
  4=3+1
  4=2+2
  4=2+1+1
  4=1+1+1+1
  3.哈希表
  4.不用库函数,实现strcpy或者memcpy等函数
原创粉丝点击