文章目录
一、工作面试
1.static 静态变量
1.局部静态变量
与普通的局部变量不同,局部静态变量在函数调用结束之后,不会被销毁,而是保持其值与存在。如果想重复使用一个变量,又不想将其声明为全局变量,就可以将其声明为局部静态变量。
2.全局静态变量
3.静态函数
2.const
1.智能指针
1.提出:
C++11提出智能指针,是为了实现自动化的内存管理,防止内存泄露。(因为C++没有垃圾回收机制)
2.分类:
0.auto_ptr:已被删除
①unique_ptr:独享指针
unique_ptr没有额外开销
#include <memory>
unique_ptr<int> p make_unique<int>(100);
②shared_ptr
指向对象有 引用计数,引用计数为0时自动delete (类似 操作系统-文件管理-索引结点-引用计数)。但引用计数会增加一些内存开销,而unique_ptr就没有内存开销。
shared_ptr<int> p = make_shared<int>(); //括号内不填数值,默认初始化为0
③weak_ptr
2.指针常量和常量指针的区别?
指针常量(* const): char * const ptr,指针是个常量,指针的指向不能改变,但是指向的变量的值可以改变
常量指针(const *):char const *ptr (const char *ptr),指针只能指向常量。例如指向图片的指针只能是常量指针。
只读指针,双const:char const * const p
二、工作笔试
1.手撕快速排序
原理:筛选一个基准元素,将待排序序列分割成两个子序列。使左边子序列所有元素都小于等于基准元素,右边子序列所有元素都大于等于基准元素。然后再对两个子序列分别进行快速排序,直到整个序列有序。
若交换,另一个while(执行一次)负责移动下标
未交换的时候,本while负责移动下标
核心代码:
int Partition(int A[],int L,int R){
int mid = A[L];
while(L < R){
while(A[R]>=mid && L<R) R--;
A[L] = A[R];
while(A[L]<=mid && L<R) L++;
A[R] = A[L];
}
A[L] = mid;
return L;
}
void QuickSort(int A[],int L,int R){
if(L >= R) return;
int M = Partition(A,L,R);
QuickSort(A,L,M-1);
QuickSort(A,M+1,R);
}
对5,3,2,6,7,9,1,4,8,0进行一轮快速排序,得到的序列应该是:0,3,2,4,1,5,9,7,8,6
完整代码:
#include <iostream>
using namespace std;
int Partition(int A[],int L,int R){
int mid = A[L];
while(L < R){
while(A[R]>=mid && L<R) R--;
A[L] = A[R];
while(A[L]<=mid && L<R) L++;
A[R] = A[L];
}
A[L] = mid;
return L;
}
void QuickSort(int A[],int L,int R){
if(L>=R) return;
int M = Partition(A,L,R);
QuickSort(A,L,M-1);
QuickSort(A,M+1,R);
}
int main() {
int A[10] = {5,3,2,6,7,9,1,4,8,0};
//排序前
for(int i = 0; i < 10; ++i) cout << A[i] <<" ";
cout << endl;
//快排
QuickSort(A,0,9);
//排序后
for(int i = 0; i < 10; ++i) cout << A[i] <<" ";
cout << endl;
return 0;
}
2.冒泡降序排序
2.降序排序,小值从前往后冒泡
void Bubble_des(int A[],int n){
for(int i = 0; i < n-1; ++i){
for(int j = 0; j < n-1-i; ++j){ //从前往后
if(A[j] < A[j+1]){ //对于降序,条件改为小于
int temp = A[j];
A[j] = A[j+1];
A[j+1] = temp;
}
}
}
}
4.降序排序,大值从后往前冒泡
void BubbleSort_des(int A[],int n){
for(int i = 0; i < n-1; ++i){
for(int j = n-1; j > i; --j){ //从后往前
if(A[j] > A[j-1]){ //对于降序,改为大于
int temp = A[j];
A[j] = A[j-1];
A[j-1] = temp;
}
}
}
}
三、复试面试
1.死锁
1.死锁的概念:
两个或多个线程或进程在执行过程中为争夺资源而造成的僵局。
2.死锁发生的4个必要条件:
①互斥
②不剥夺
③请求与保持
④循环等待
3.死锁的3种处理:
①死锁预防:破坏死锁发生的四个必要条件之一
②死锁避免:银行家算法
③死锁的检测与解除:资源分配图
2.用户态和内核态、宏内核与微内核
1.用户态与内核态
内核态可以执行特权指令。用户态只能执行用户指令。
特权指令:I/O指令、系统调用、开/关中断指令、修改PSW
2.宏内核与微内核
①宏内核是指内核空间包含了大多数的操作系统服务,如进程管理、内存管理、文件系统、设备驱动等。
这样切换服务时上下文切换成本低,开销小,性能高。
缺点是不稳定、不安全,一个服务崩溃可能导致整个内核崩溃。
②微内核的设计理念是尽可能地将系统服务和系统核心功能分离,微内核系统中只包含最基础的服务,如低级的地址空间管理、进程调度和通信机制。
优点是安全稳定,一个服务故障不会影响到内核。
缺点是切换服务上下文开销大,性能低。
3.SSD与机械硬盘
SSD与传统磁盘相比,第一是没有机械装置,第二是由磁介质改为了电介质。SSD没有传统磁盘的寻道时间和延迟时间。
4.TCP协议
(1)三次握手
(2)四次挥手
(3)滑动窗口
(4)拥塞避免
5.指针与引用的区别
三、外包公司避雷
1.北京德科(华为OD)
2.中软国际
3.软通动力
4.中科创达
5.上海思芮