1 . 析构函数的特点?
答:
- 析构函数是类的特殊成员函数,它没有返回类型
- 没有参数、没有重载
- public、protected、private等权限对析构函无效
- 析构函数不能手动调用,只是在类对象的生命周期结束之后,系统自动调用释放构造函数的分配的资源
2 . C语言中static关键字的用途?
答:
- 修饰函数,全局变量起到限定作用域的作用
- 修饰局部变量扩展局部变量的生命周期
- 默认初始化为零
3 . 局部变脸是否可以和全局变脸同名,如果不可以会出现什么错误?如果可以,系统如何解决这种冲突发生?
答:
可以同名。如果局部变量与全局变量同名,有局部变量的作用域,使用局部变量,其他作用域则使用全局变量。
4 . 堆和栈的区别?
答:
-
内存分配的堆栈:
栈区是由系统分配,大小固定,数据有高地址到低地址,依次存放,空间释放有系统自动完成
堆区有程序员手动申请,手动释放,否则会造成内存泄露。 -
数据结构中的堆栈:
栈是一种先进后出的数据结构。
堆是一种特殊的完全二叉树,每个结点都有一个值,通常分为最大堆和最小堆。
5 . size of 和 strlen 的区别?
答:
size of 是运算符,它的值在编译之前就确定好了,计算出所建立对象的字节大小。
strlen 是函数,程序执行时才开始计算,类型必须是字符串,返回字符串的长度,长度不包括’\0’
6 . 段错误的几种常见情况?
答:
- 对空指针的访问
- 修改常量区内容
- 数组越界
- 使用非法指针,即指针为初始化或者释放内存后再次使用
- 多次释放同一块内存块
- 跨进程访问某个地址
7 . typedef 和#define 之间的区别?
答:
typedef 在编译时处理,它在自己的作用域中给已经存在的一个变量起的一个类型别名。
#define是预处理指令,在编译处理时进行简单的替换,不做正确性检测。
8 . 指针和数组之间的区别?
答:
数组名对应着一块内存,其地址与容量在生命周期保持不变,只有数组的内容可以改变只有数组的内容可以改变。指针的可以随时指向任意类型的内存块,它的特征是“可变”,所以我们用指针来操作动态内存。
当数组作为函数的参数进行传递时,该数组自动退化为同类型的指针。
9.简单叙述一下如何判断一条单向链表有没有环?
答:
用 fast 和 slow 连个指针分别指向链表的头部,fast指针每次移动两个节点, slow指针每次移动一个节点,fast 先移动,如果fast指针先遇到NULL,则不存在环。如果fast == slow的情况下,则存在环。
10 . 构造函数和析构函数的异同点?
答:
构造函数:
构造函数的名字与类名相同
构造函数可以有任意类型的参数,但不能有返回类型
定义对象时,编译系统会自动调用构造函数
构造函数是特殊的成员函数,函数体可以在类体内,也可以在类体外
构造函数被声明为公有函数,它是在定义对象的同时被调用
析构函数:
析构函数的名字与类名相同,并且前面要有波浪号
析构函数没有参数,也没有返回值,而且不能重紫,因此一个类中只有一个析构函数
撤销对象时,系统会自动调用析构函数
析构函数可以用virtual ,构造函数不能是虚函数
析构函数是类的特殊成员函数
11 . 类型转换构造函数是什么?
答:
自动调用类型匹配的构造函数自动将基本数据类型转换为对象
12 . C++中explict关键字的作用?
答:
explict 和构造函数一起使用,指明构造函数只能显示使用,目的是为了防止不必要的隐式调用类型转换构造函数
13 . 进程的挂起和进程的阻塞分别产生的条件是什么,以及他们的操作区别是什么?
答:
进程的挂起:系统在超过一定的时间没有任何动作
进程的阻塞:进程因等待某一件事情而暂时不能运行的状态,此时处理机空闲,进程也无法使用。
14 . 简单介绍进程的三态模型?
答:
运行、就绪、阻塞
运行:当一个进程在处理机上运行时,则该程序处于运行状态 。处于此状态的数目小于等于处理器的数目。单处理系统,处于运行状态的进程只有一个。
就绪:当一个进程获得除处理及以外的一切资源,一旦得到处理机就可以运行
阻塞:一个进程正在等待某件事情发生而暂时停止运行
15 . 简述僵尸进程是怎样产生和系统对僵尸进程的处理机制?
答:
僵尸进程:一个已经终止但是其父进程尚未对其进行处理的进程
处理机制:如果父进程没有SIGCHID信号处理函数,那么调用wait()或者waitpid()等待子进程的结束,又没有显示忽略该信号,那么将会保持僵尸的状态,如果父进程结束,那么init进程自动会接受这个子进程,他还是会被消除的