以下内容仅供参考,如有错误,欢迎指正。
参考:https://blog.csdn.net/qq_19320865/article/details/78497278
大部分公司都很喜欢问:线程、数据库锁、并发、内存管理相关的问题,小伙伴们要精心准备。
1、C++中线程锁
参考:https://www.cnblogs.com/steamedbun/p/9376458.html
四种线程锁:
互斥锁:互斥锁用于控制多个线程对他们之间共享资源互斥访问的一个信号量。
条件锁:条件锁就是所谓的条件变量,某一个线程因为某个条件为满足时可以使用条件变量使改程序处于阻塞状态。
自旋锁:如果一个线程想要获取一个被使用的自旋锁,那么它会一致占用CPU请求这个自旋锁使得CPU不能去做其他的事情,直到获取这个锁为止。
读写锁:允许在数据库上同时执行多个“读”操作,但是某一时刻只能在数据库上有一个“写”操作来更新数据。
2、线程间通信与同步
2.1 线程之间是如何通信的?
一个是使用全局变量进行通信,还有就是可以使用自定义的消息机制传递信息。线程间通信主要是为了同步。
2.2 线程如何保证同步?
参考:https://www.cnblogs.com/yhlboke-1992/p/9315263.html
互斥锁:采用互斥对象机制。 只有拥有互斥对象的线程才有访问公共资源的权限,因为互斥对象只有一个,所以能保证公共资源不会同时被多个线程访问。互斥不仅能实现同一应用程序的公共资源安全共享,还能实现不同应用程序的公共资源安全共享。
临界区:临界区(Critical Section)是一段独占对某些共享资源访问的代码,在任意时刻只允许一个线程对共享资源进行访问。如果有多个线程试图同时访问临界区,那么在有一个线程进入后其他所有试图访问此临界区的线程将被挂起,并一直持续到进入临界区的线程离开。
事件:事件机制,则允许一个线程在处理完一个任务后,主动唤醒另外一个线程执行任务。
信号量:当需要一个计数器来限制可以使用某共享资源的线程数目时,可以使用“信号量”对象。
3、数据库并发控制
参考:https://blog.csdn.net/weixin_39651041/article/details/79985715
https://blog.csdn.net/weixin_34301307/article/details/85482681
并发控制的主要采用的技术手段:乐观锁、悲观锁
3.1 从程序员角度的锁分类
悲观锁:
对数据被外界(包括本系统当前的其他事务,以及来自外部系统的事务处理)修改持保守态度,因此在整个数据处理过程中,将数据处于锁定状态。
悲观锁的实现,往往依靠数据库提供的锁机制
乐观锁:
大多是基于数据版本( Version )记录机制实现。--CAS实现
3.2 数据库角度锁的分类方式
独占锁(Exclusive Lock):独占锁锁定的资源只允许进行锁定操作的程序使用,其它任何对它的操作均不会被接受。执行数据更新命令,即INSERT、 UPDATE 或DELETE 命令时,SQL Server 会自动使用独占锁。但当对象上有其它锁存在时,无法对其加独占锁。独占锁一直到事务结束才能被释放。
共享锁(Shared Lock):共享锁锁定的资源可以被其它用户读取,但其它用户不能修改它。在SELECT 命令执行时,SQL Server 通常会对对象进行共享锁锁定。通常加共享锁的数据页被读取完毕后,共享锁就会立即被释放。
更新锁(Update Lock): 更新锁是为了防止死锁而设立的。当SQL Server 准备更新数据时,它首先对数据对象作更新锁锁定,这样数据将不能被修改,但可以读取。等到SQL Server 确定要进行更新数据操作时,它会自动将更新锁换为独占锁。但当对象上有其它锁存在时,无法对其作更新锁锁定。
3.3 关于行级锁、表级锁、页级锁
可以这样理解:锁的基础理论只有乐观锁和悲观锁,从乐观锁和悲观锁理论,衍生出独占锁、共享锁、更新锁、然后行级锁、表级锁、页级锁是从锁的有效范围角度来划分。
3.4 关于事务
不可分割的操作。
5种隔离级别:
DEFAULT
READ_UNCOMMITTED
READ_COMMITTED
REPEATABLE_READ
SERIALIZABLE
4、内存分配方式以及它们的区别
参考:https://blog.csdn.net/cherrydreamsover/article/details/81627855
栈区(stack):由编译器自动分配与释放,存放为运行时函数分配的局部变量、函数参数、返回数据、返回地址等。其操作类似于数据结构中的栈。
堆区(heap):一般由程序员自动分配,如果程序员没有释放,程序结束时可能有OS回收。其分配类似于链表。
全局区(静态区static):存放全局变量、静态数据、常量。程序结束后由系统释放。全局区分为已初始化全局区(data)和未初始化全局区(bss)。
常量区(文字常量区):存放常量字符串,程序结束后由系统释放。
代码区:存放函数体(类成员函数和全局区)的二进制代码。