吉比特面试准备(一)
***C++基础
static,const
相同点:都可用来修饰变量或函数,但作用不同;
static:隐藏(变量、函数)、数据的持久化、默认初始化为0;值可以被改变;存储在静态区;
在oo中,当它修饰变量或者函数时,该变量和函数就专属于类,不属于对象。不能用this指针来访问。静态函数只能访问静态数据或者静态函数。
存储位置:
static存在静态数据区,const全局也存在静态全局数据区,局部存在栈中,函数结束就释放。
可变性:static可以,const不可。
C++11
1.类型推导
auto,简化复杂表达式的类型推导,会执行;
decltype,分析表达式/操作数类型,返回数据类型
2.序列for循环
可用于遍历数组、容器、string,以及由.begin()和end()定义的序列。简化了遍历代码;
3.lambda表达式
内存泄露
概念:由于疏忽或者错误,没有释放掉不再使用的内存;
危害:内存泄漏逐渐积累,会导致系统性能下降甚至内存用尽;
C++没有垃圾回收机制,主要关注:
堆内存泄漏:使用malloc,realloc及new申请内存后没有及时free,, delete, delete[]
系统内存泄漏:使用socket、bitmap、handle等系统资源后,没有利用相应函数去释放,比如用closesocket()释放socket。
检测方法:
人工查找,有无申请了未释放,要使用delete[],却使用了delete...
最好的方法=>使用智能指针,它可以自动删除分配的内存
unique_ptr:多个指针指向同一个对象(指针计数器,如果计数器为0,就释放该资源)
shared_ptr:一个指针独占一个对象(实现原理:禁止拷贝构造以及赋值运算符,允许移动拷贝和移动赋值)
weak_ptr:监视shared_ptr的生命周期。
Hash冲突
经过hash函数计算后,出现了重复的hash地址,就产生了冲突。
解决方法:
再散列法:重新计算地址(线性探测再散列、二次探测再散列、伪随机探测再散列)
再哈希法:多个hash函数
链地址法:冲突的都连起来
建立公共溢出区
:冲突的都扔到一个地方
堆和栈的区别
1.申请方式:栈由系统来分配、对由程序员来分配
2.大小:程序栈大小固定,但是可以改,连续存储;堆大小更大,不连续存储;
3.申请效率:栈速度快,没有碎片;堆手动分配慢,会有内碎片产生;
多态
1.编译时多态:重载;
2.运行时多态
:虚函数继承,虚指针,虚表,动态绑定。
***操作系统
进程间通信
方式:
信号量()
管道(命名管道+匿名管道(本机父子进程通信))
共享内存(划定一段内存,用来读写)
邮槽(单向---客户端写,服务端读)(mailslot)
套接字(socket---Winsock2.h)
RPC(远程过程调用):远端的两个进程通信
穿行/并行通信(串口/并行端口通信)
剪切板(所有程序都可以访问剪切板)
线程同步
概念:线程同步是线程间的一种制约关系。许多时候,一个进程需要另一个进程的消息或数据,才能继续运行,那么就需要等待,
比如生产者消费者问题...
方法:
临界区:是访问公共资源的一段代码,任意时刻只允许一个进程进入,其他的挂起,直至临界区被释放。
信号量:拥有计数能力,表示资源的实时数量,将其放置在管家代码的开头和结尾,加之PV操作。
消息:相当于一个令牌,谁拿到就获得资源运行,两个操作:解锁+加锁
互斥量:一般只有两个状态,是一种特殊的信号量,相当于一把锁,进入时就改变互斥量状态,其他进程检测到互斥量或就阻塞;
死锁产生,避免
产生必要条件:
1.互斥条件:资源只能被一个/每次占用;
2.请求与保持条件:已经得到资源的进程还可以继续申请资源;
3.不可剥夺条件:不可从其他进程强行夺取资源;
4.循环等待条件:多个进程循环等待各自占有的资源。
避免:
1.检测和恢复:检测发现死锁,撤销死锁进程,或者挂起其他进程,将其资源提供给死锁进程;
2.预防:
破坏任意一个必要条件:
一次性分配原则;申请先释放;资源编号,按序申请。
死锁避免:银行家算法!!!
协程
又称为微线程,他的特点是再程序内部可以中断,但又不是函数调用,它是编译器层面的东西,不同于进程线程。
优势:
执行效率高(没有线程切换的开销),直接中断
它不需要多线程的锁机制。
支持的库:PhxRPC,libco(co_creat, co_resume, co_yeild,协程栈来控制----汇编层面)

浙公网安备 33010602011771号