1、面向对象的特性?
- 封装
- 继承
- 多态
2、C++中的多态如何体现?
静态多态
- 函数重载
动态多态
- 子类重写父类的方法,生成一个新方法。
3、指针和引用的区别?
指针是一个实体,有实际的内存地址。引用是一个变量别名,不会分配内存空间。
指针不用必须初始化,并且指向对象可以改变。引用必须初始化,并且不能再次引用别的对象。
指针有多级指针。引用只有一级。
指针和引用的自增运算结果不一样。(指针是指向下一个地址空间,引用是引用的变量值加1)
sizeof引用,得到的是所指变量的大小。sizeof指针,得到的是指针本身的大小。
引用访问一个变量是直接访问。指针访问一个变量时间接访问。
使用指针前最好做类型检查,防止野指针的出现。
作为参数时,传指针的实质是传值,穿的是指针的地址值。传引用的实质是传值,传递的是变量的地址。
4、链表和数组的区别?
数组必须事先定义固定的长度,不能适应数据动态增减的情况,即数组的大小一旦定义就不能改变。当数据增加时,可能超出原先定义的长度;当数据减少时,又会造成内存浪费。而链表可以动态地进行存储分配,方便插入和删除数据。
数组从栈中分配内存空间,方便但自由度小。链表从堆中分配内存空间,自由度大但申请和管理比较麻烦。
数组在内存中是连续存储的,因此,可以利用下标索引进行随机访问。链表是链式存储结构,在访问元素时只能通过线性的方式由前到后顺序访问,所以访问效率比数组低。
5、&和&&的作用分别是什么?
&——引用、取地址、按位与。对于整型,&和|是按位与和按位或操作。对于bool操作数,&和|是逻辑与和逻辑或操作。
&&——逻辑与,两边都只能是bool类型
6、代码题——写一个swap函数
- 错误的swap函数
void swap(int a, int b) { int temp = a; a = b; b = temp; }
这是一个最常见的错误!a和b是一个int类型的值,它们只是实参的一个拷贝,作用域只在swap函数内,所以无法起到交换的作用。
普遍的swap函数
void swap(int &a, int &b) { int temp = a; a = b; b = temp; }
void swap(int *a, int *b) { int temp = *a; *a = *b; *b = temp; }
通过使用引用或指针来保证swap函数中对参数做出的改变传递到swap的作用域外。
通过位运算实现的swap函数
void swap(int &a, int &b) { a = a^b; b = a^b; a = a^b; }
无需构造临时对象,使用异或完成。但是当传入的两个参数地址相同时,会出现结果为0的情况。
模板swap函数
template <class T> void swap(T &a, T &b) { T c(a); a = b; b = c; }
- 创建临时对象,调用对象的赋值操作符。一个拷贝构造,两次赋值操作。
7、代码题——冒泡排序及如何优化?
- 普通冒泡
#Python def BubbleSort(arr): leng = len(arr) if leng < 2: return arr for i in range(leng-1, 0, -1): for j in range(0, i): if arr[j] > arr[j+1]: arr[j], arr[j+1] = arr[j+1], arr[j] return arr
//C++ #include<iostream> #include<vector> using namespace std; void BubbleSort(vector<int> arr) { int len = arr.size(); int i; int j; if(len<2) return; for(i=len-1;i>0;i--) { for(j=0;j<i;j++) { if(arr[j] < arr[j+1]) swap(arr[j], arr[j+1]) } } return; } void swap(int *a, int *b) { int temp = *a; *a = *b; *b = temp; }
- 优化后的冒泡排序
#Python def BubbleSort(arr): leng = len(arr) if leng < 2: return arr for i in range(leng-1, 0, -1): num = 0 for j in range(0, i): if arr[j] > arr[j+1]: arr[j], arr[j+1] = arr[j+1], arr[j] else: num += 1 if num == i: break return arr
//C++ #include<iostream> #include<vector> using namespace std; void BubbleSort(vector<int> arr) { int len = arr.size(); int i; int j; if(len<2) return; for(i=len-1;i>0;i--) { int num = 0; for(j=0;j<i;j++) { if(arr[j] < arr[j+1]) swap(arr[j], arr[j+1]) else num += 1; } if(num == i) break; } return; } void swap(int *a, int *b) { int temp = *a; *a = *b; *b = temp; }
8、软件的生命周期?
可行性研究与计划阶段
- 主要任务是研究项目的可行性,需要的文档是可行性分析报告。
需求分析
- 这个阶段是软件设计、验收的依据。主要文档是软件需求规格说明书
软件设计
- 将软件需求转换为软件表示。主要文档是概要设计说明和集成测试。
软件实现
- 将软件需求转换为软件,即编码阶段。
软件测试
- 严格执行测试计划,通过黑盒测试和白盒测试来发现程序中的错误。
软件运行
- 软件的日常运作和使用。
软件维护
- 对软件进行日常的维护升级。
9、测试方法有哪些?
黑盒测试
白盒测试
灰盒测试
静态测试
动态测试
自动化测试
10、黑盒测试主要包括什么?
等价类划分
边界值分析
因果图法
判定表法
错误推测法
状态迁移法
11、测试一根笔?
功能测试
笔筒开合是否正常。
笔芯出墨是否正常。
笔头出墨粗细。
是不是可擦性签字笔。
性能测试
笔芯的寿命。
写过的字是否会被水晕开。
笔尖在多大压力范围内可以正常写字。
笔壳在多大压力范围内可以正常使用。
是否能在纸上写出清晰的字。
书写时是否流畅。
写出的墨水多长时间会干。
极端环境是否会对笔芯出墨和笔壳造成影响。
长时间不盖笔帽和长时间盖笔帽会不会对下次写字产生影响。
界面测试
尺寸是否适合用户使用。
色彩搭配是否合理。
形状是否符合美观。
笔身logo和文字是否印刷正确。
安全性测试
笔芯和笔壳是否易燃。
笔墨是否会对皮肤造成伤害。
笔墨的气味是否对人体有害。
笔杆折断是否会划伤手。
误食笔墨是否会中毒。
兼容性测试
笔壳是否兼容别的品牌的笔芯。
在不同材质的纸上写字,是否能保持清晰和流畅。
笔尖损坏时,是否可以换上别的笔尖。
笔墨用完时,是否可以换上别的笔墨。
在木板或墙壁上是否能正常书写。
12、性能测试包括哪些方法?
负载测试
- 通过逐步对系统增加负载,测试系统性能的变化,确定系统能够承受的最大阈值。
压力测试
- 通过逐步对系统增加负载,测试系统性能的变化,确定系统在什么负载条件下系统性能失效,获取系统能够提供的最大服务级别。
并发测试
- 测试多个用户同时访问同一个应用,同一个模块,或者数据记录时是否存在死锁或其他性能问题。
容量测试
- 测试系统能够处理的最大回话能力,确定系统可处理同时在线的最大用户数量,通常和数据库有关。
配置测试
- 对系统的软硬件配置进行测试,找到各项资源的最优分配原则。
可靠性测试
- 对系统加载一定的业务压力,(CPU资源70%~90%的使用率),运行一段时间,检查系统是否稳定,可测出内存泄漏问题。
失败测试
- 对有冗余备份和负载均衡的系统,检测若系统出现错误,备份是否影响用户正常使用。
13、负载测试和压力测试有什么区别?
- 负载测试
- 通过逐步对系统增加负载,测试系统性能的变化,确定系统能够承受的最大阈值。
- 压力测试
- 通过逐步对系统增加负载,测试系统性能的变化,确定系统在什么负载条件下系统性能失效,获取系统能够提供的最大服务级别。
14、测试模型有哪些?
- V模型
- W模型
- H模型
15、如何测试你写的冒泡排序?
16、项目难点是什么?
17、如何提升自己?(我问)