面试题集锦 1

时间:2022-10-04 17:49:06

 1.为什么栈会溢出?

            ——我举了个例子比如整形的数大小是有上限的,如果定义了比最大值大的数赋给了整形变量,此时就会越界。

           【百度百科】:堆栈溢出就是不顾堆栈中分配的局部数据块大小,向该数据块写入了过多的数据,导致数据越界,结果覆盖了老的堆栈数据。举例如下:

[cpp] view plaincopy
  1. <span style="font-size:14px;">int main()  
  2. {  
  3.     char name[8];   
  4.     printf("Please type your name:");  
  5.     gets(name); //如果输入name="aaaaaaaaaaaaaaaaaaaaaaaaaaaa"就会导致栈溢出。  
  6.     printf("Hello.%s!",name);   
  7.     return 0;  
  8. }</span>  

          最好能提到原因:死循环似的递归, 没有或者不可能到达结束条件, 同时在堆栈中保存参数,局部变量等等,最后堆栈装满,就RunTimeError,导致堆栈溢出。本质原因,没有释放所占有栈的内存空间会导致栈溢出。

   2. 什么是平衡二叉树?

平衡二叉树又被称为AVL树(有别于AVL算法),且具有以下性质:它是一 棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。

        3.进程与线程的区别?

线程:
(1)轻型实体。 
(2) 独立调度和分派的基本单位。 
(3) 可并发执行。 
(4) 共享进程资源。 

进程:
(1) 进程是程序的一次执行。
(2) 进程是一个程序及其数据在处理机上顺序执行时所发生的活动。
(3) 进程是程序在一个数据集合上运行的过程,它是系统进行资源分配和调度的一个独立单位。
在引入了进程实体的概念后,我们可以把传统OS中的进程定义为:“进程是进程实体的运行过程,是系统进行资源分配和调度的一个独立单位”。

        4.局部变量和全局变量的区别?

C++变量根据定义位置的不同,具有不同的作用域,作用域可分为6种:全局作用域,局部作用域,语句作用域,类作用域,命名作用域和文件作用域。

从作用域看:

全局变量具有全局作用域。全局变量只需在一个源文件中定义,就可以作用于所有的源文件。当然,其他不包括全局变量定义的源文件需要用extern关键字再次声明这个全局变量。

静态局部变量具有局部作用域。它只被初始化一次,自从第一次初始化直到程序与你新内阁结束都一直存在,他和全局变量的区别在于全局变量对所有的函数都是可见的,而静态局部变量只对定义自己的函数体始终可见。

局部变量也只有局部作用域,他是自动对象,他在程序运行期间不是一直存在,而是只在函数执行期间存在,函数的一次调用结束后,变量就被撤销,其所占用的内存也被收回。

静态全局变量也具有全局作用域,他与全局变量的区别在于如果程序包含多个文件的话,他作用于定义它的文件里,不能作用到其他文件里,即被static关键字修饰过的变量具有文件作用域。这样即使两个不同的源文件都定义了相同的静态全局变量,他们也是不同的变量。

从分配内存空间看:

全局变量、静态局部变量、静态全局变量都在静态存储区分配空间,而局部变量在栈分配空间。

全局变量本身就是静态存储方式,静态全局变量当然也是静态存储方式。这两者在存储方式上没有什么不同。区别在于非静态全局变量的作用域是整个源程序,当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。而静态全局变量则限制了其作用域,即只在定义该变量的源文件内有效,在同一源程序的其他源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用,因此可以避免在其他源文件中引起错误。

1、静态变量会被放在程序的静态数据存储区里,这样可以在下一次调用的时候还可以保持原来的赋值。这一点是他与堆栈变量和堆变量的区别

2、变量用static告知编译器,自己仅仅在变量的作用域范围内可见。这一点是他与全局变量的区别。

从以上分析可以看出,把局部变量改变为静态变量后是改变了他的存储方式,即改变了他的生存期。把全局变量改变为静态变量后是改变了他的作用域,限制了他的使用范围,因此static这个说明符在不同的地方起的作用是不同的。

TIPS:

1、若全局变量仅在单个文件中访问,则可以讲这个变量修改为静态全局变量。

2、若全局变量仅在单个函数中使用,则可以将这个变量修改为该函数的静态局部变量。

3、全局变量、静态局部变量、静态全局变量都存放在静态数据存储区。

4、函数中必须要使用static变量的情况:当某函数的返回值为指针类型时,则必须是static的局部变量的地址作为返回值,若为auto类型,则返回为错指针。


        5.static变量的用法?

 1.全局静态变量

在全局变量之前加上关键字static,全局变量就被定义成为一个全局静态变量。
  1. 内存中的位置:静态存储区(静态存储区在整个程序运行期间都存在)
  2. 初始化:未经初始化的全局静态变量会被程序自动初始化为0(自动对象的值是任意的,除非他被显示初始化)
  3. 作用域:全局静态变量在声明他的文件之外是不可见的。准确地讲从定义之处开始到文件结尾
定义全局静态变量的好处:
<1>不会被其他文件所访问,修改

<2>其他文件中可以使用相同名字的变量,不会发生冲突。

2. 局部静态变量

在局部变量之前加上关键字static,局部变量就被定义成为一个局部静态变量。

  1. 内存中的位置:静态存储区
  2. 初始化:未经初始化的全局静态变量会被程序自动初始化为0(自动对象的值是任意的,除非他被显示初始化)
  3. 作用域:作用域仍为局部作用域,当定义它的函数或者语句块结束的时候,作用域随之结束。

注:当static用来修饰局部变量的时候,它就改变了局部变量的存储位置,从原来的栈中存放改为静态存储区。但是局部静态变量在离开作用域之后,并没有被销毁,而是仍然驻留在内存当中,直到程序结束,只不过我们不能再对他进行访问。

      当static用来修饰全局变量的时候,它就改变了全局变量的作用域(在声明他的文件之外是不可见的),但是没有改变它的存放位置,还是在静态存储区中。

3. 静态函数

  在函数的返回类型前加上关键字static,函数就被定义成为静态函数。
  函数的定义和声明默认情况下是extern的,但静态函数只是在声明他的文件当中可见,不能被其他文件所用

定义静态函数的好处:
<1> 其他文件中可以定义相同名字的函数,不会发生冲突
<2> 静态函数不能被其他文件所用。

4.网络TCP/IP协议分几层?

四层。应用层---传输层(TCP/UDP)---网际层(IP)---网络接口层

5.IP地址转化为MAC地址的协议是什么? ARP(地址解析协议)。

6.内联函数和宏定义的区别

1.内联函数在运行时可调试,而宏定义不可以;
2.编译器会对内联函数的参数类型做安全检查或自动类型转换(同普通函数),而宏定义则不会; 
3.内联函数可以访问类的成员变量,宏定义则不能; 
4.在类中声明同时定义的成员函数,自动转化为内联函数。

相同点:在预处理阶段,对代码块进行替换

7.const 和 #define区别

    1)   const常量有数据类型,而宏常量没有数据类型。编译器可以对前者进行类型安全检查。而对后者只进行字符替换,没有类型安全检查,并且在字符替换可能会产生意料不到的错误(边际效应)。

    2)   有些集成化的调试工具可以对const常量进行调试,但是不能对宏常量进行调试。

8.指针和句柄的区别和联系是什么?

   指针指向系统中物理内存的地址,而句柄是windows在内存中维护的一个对象内存物理地址列表的整数索引,标记系统资源隐藏系统信息,一种指向指针的指针。

   在windows系统中的内存管理一般会将当前处于空闲状态的对象的内存释放掉,当需要访问的时候再重新提交分配物理内存,从而导致对象的物理地址是变化的,这样就不允许系统直接通过指针来访问(物理地址不断变化)的对象。   

  9.this指针

1.this指针只能在成员函数中使用,全局变量、静态函数都不能使用this

2.this在成员函数的开始前构造,在成员的结束后清除。

3.this指针不呢过不占用对象的内存。

4.采用type XX 的方式定义的话,在栈里分配内存,这是this的值这块内存的位置

 采用new 方式创建对象的话,在堆里分配内存  

 10.指针和引用的差别

★相同点: 
     都是地址的概念;
     指针指向一块内存,它的内容是所指内存的地址;引用是某块内存的别名。  

★ 区别: 

     指针是一个实体,而引用仅是个别名; 
     引用使用时无需解引用(*),指针需要解引用; 
     引用只能在定义时被初始化一次,之后不可变;指针可变; 

     引用没有 const,指针有 const,const 的指针不可变; 

     引用不能为空,指针可以为空;由于没有所谓的 null reference 所以所以在使用前不需要进行测试其是否有值.,而使用指针则需要测试其的有效性.

指针未确定指向不能赋值