C++:面经3

C++类里面有2个int变量,1个成员函数,两个虚函数,总共占多少空间?

首先,每个int变量通常占用4字节的空间。因此,2个int变量会占用8字节的空间。成员函数通常不占用类对象的内存空间,无论是普通成员函数还是静态成员函数,它们都是在类定义时存在的,不占用对象的实例化空间。虚函数本身也不占用类对象的存储空间,但是当类中包含虚函数时,实例化对象时会在对象内部添加一个指向虚函数表的指针(vptr),这个指针通常占用4个字节的空间。因此,如果类中包含两个虚函数,那么对象会因为虚函数而额外增加8个字节的空间(4字节用于vptr)。

mysql幻读有什么解决办法?

MySQL解决幻读的方法主要包括提高事务隔离级别、使用行级锁、使用乐观锁、MVCC(多版本并发控制)和next-key lock。

  1. 提高事务隔离级别‌:将事务的隔离级别设置为可重复读(REPEATABLE READ)或串行化(SERIALIZABLE)可以减少幻读的发生。可重复读级别通过使用next lock锁机制来防止幻读问题,而串行化级别则是通过锁定读取的范围来避免其他事务插入新数据,从而彻底解决幻读问题。但需要注意的是,提高隔离级别可能会降低系统的并发性能‌。

  2. 使用行级锁‌:通过在SQL语句中使用FOR UPDATE关键字可以对查询的数据进行加锁,防止其他事务在该数据上进行修改操作,从而减少幻读的可能性‌。

  3. 使用乐观锁‌:乐观锁通过在更新数据时先检查数据版本号是否发生变化,如果没有变化则更新数据,如果发生变化则放弃更新操作,以此来解决幻读问题‌。

  4. MVCC(多版本并发控制)和next-key lock‌:MVCC是一种并发控制机制,通过为每个事务分配一个唯一的事务ID和版本号,保证每个事务读取到的数据都是一致的。MySQL在存储引擎(如InnoDB)下通过MVCC和next-key lock来解决幻读问题,即在事务启动时创建一个数据快照,而不是直接修改实际的数据行,从而避免了幻读现象的发生‌。

综上所述,解决MySQL中的幻读问题可以通过多种方法实现,包括提高事务隔离级别、使用行级锁、乐观锁、MVCC以及next-key lock等。选择哪种方法取决于具体的应用场景和性能要求。

HTTPS怎么建立加密传输?

HTTPS通过结合对称加密非对称加密的方式建立加密传输。

HTTPS的加密传输过程大致可以分为以下几个步骤:

  1. 建立安全连接‌:客户端(如浏览器)向服务器发送请求,请求建立一个加密的连接。
  2. 服务器发送SSL证书‌:服务器回应,并发送其SSL证书(包含公钥和服务器的一些其他信息)。
  3. 验证证书‌:客户端验证服务器的SSL证书是否有效,是否由受信任的证书颁发机构(CA)签发,以及证书中的域名是否与请求的服务器域名匹配。
  4. 密钥交换‌:客户端和服务器使用非对称加密技术(如RSA)进行密钥交换。客户端使用服务器的公钥来加密一个随机生成的对称密钥(会话密钥),并将加密后的密钥发送给服务器。
  5. 数据传输‌:一旦双方都有了共享的对称密钥,它们就可以使用这个密钥来加密和解密传输的数据。HTTPS使用对称加密算法(如AES)来加密和解密实际传输的数据。
  6. 完整性检查‌:HTTPS还使用了一种称为消息认证码(MAC)的技术来确保数据的完整性。客户端和服务器都使用一个共享的密钥(通常与用于加密数据的密钥相同)来生成MAC。当服务器收到数据时,它会使用相同的密钥和算法来生成MAC,并与接收到的MAC进行比较,以确保数据在传输过程中没有被篡改。
  7. 关闭连接‌:当数据传输完成时,客户端和服务器关闭加密连接。

这种结合非对称加密和对称加密的方式确保了HTTPS连接的安全性。非对称加密用于安全地交换对称密钥,而对称加密则用于高效地加密和解密实际传输的数据‌

std::vector 会自动动态缩容吗

std::vector‌不会自动动态缩容。

std::vector 是一种动态数组容器,它允许在运行时动态地增长或缩小。然而,与增长不同,std::vector 通常不会自动缩小其容量。这意味着,如果你从 std::vector 中删除元素,容器的大小(即它占用的内存)不会自动减少以适应剩余元素的紧密排列。相反,std::vector 的设计倾向于保持其内部存储的连续性,因此即使删除了某些元素,也不会立即释放那些未使用的内存空间给操作系统。这种设计选择是为了优化性能和减少内存重新分配的次数,尽管它可能导致 std::vector 占用比实际需求更多的空间‌。

红黑树的原理

红黑树是一种自平衡二叉查找树,它通过颜色旋转来保持平衡,并确保最坏的情况下,任何一条从根到叶子的路径都不会比其它路径长出太多,从而保证了时间复杂度接近于二叉查找树的最佳情况。

红黑树的主要性质:

  1. 每个节点或者是黑色,或者是红色。

  2. 根节点是黑色。

  3. 每个叶子节点(NIL节点,空节点)是黑色的。

  4. 如果一个节点是红色的,则它的子节点必须是黑色的。

  5. 从一个节点到该节点的子孙节点的所有路径上必须包含相同数目的黑色节点。

c++内存对齐

C++内存对齐是一种优化程序性能和减少内存使用的技术。它的基本原则是数据结构应该以其对齐偏移(alignment offset)的整数倍的地址开始,这通常是为了满足硬件的特定要求或优化数据访问速度。

常见的内存对齐原则包括:

  1. 结构体或类的数据成员应该按照它们的大小排列,更大的成员排在后面。

  2. 结构体或类的起始地址可以是它的最大成员的整数倍。

  3. 结构体总大小是最大成员大小的整数倍。

  4. 可以使用alignas关键字指定特定的对齐方式。

作用:

  • 提高内存访问效率.由于cpu在读取内存时,一次性会以固定长度(如4个字节、8个字节等)读取数据,而不是一个一个的字节读取。如果将多个变量连续分配在内存中而不进行对产处理的话,就会造成cpu在读取数据时出现“半包”情况。此时中央处理器必须要做2次内存访问才能得到所有的数据,显然效率低了很多。
  • 减少内存占用量,当使用对文方式来分布各人变量时,有些余留出来的空间是浪费的.但是通过使用对其方式来分布各个变量也能避免上文中所说的“半包”情况出现从而大大减少中央处理器读取数据所浪费的时间和功耗

C++怎么定义一个常量

在C++中,定义一个常量可以使用const关键字。例如,const int MAX_VALUE = 100; 这行代码定义了一个名为MAX_VALUE的常量,其值为100,且该值在程序运行期间不能被修改。常量的值必须在声明时或编译时就确定,因此它们通常用于那些在程序执行期间不会改变的量。

是否了解自旋锁,是否了解互斥锁

自旋锁互斥锁是两种常见的同步机制,用于在多线程程序中保护共享资源。‌它们的主要区别在于等待锁的方式和适用场景。

  • 自旋锁‌(Spinlock)是一种简单的锁机制,当一个线程尝试获取一个已经被其他线程持有的锁时,该线程不会立即进入睡眠状态,而是在当前位置不断循环(自旋),直到锁被释放。自旋锁的主要优点是避免了线程的上下文切换,提高了系统的响应性,适用于锁持有时间短且线程不希望在锁等待期间让出CPU的情况。然而,如果锁被长时间占用,自旋锁会导致CPU资源的浪费,在单核处理器上可能导致线程饥饿。

  • 互斥锁‌(Mutex, Mutual Exclusion)是一种常见的同步机制,用于保护共享资源。当一个线程尝试获取一个已经被其他线程持有的锁时,该线程将被阻塞,直到锁被释放。互斥锁适用于锁持有时间较长且线程可以在锁等待期间让出CPU的情况,避免了自旋锁导致的CPU资源浪费。但互斥锁可能导致线程的上下文切换,增加了系统的开销,在高并发场景下可能导致线程饥饿。

总的来说,自旋锁和互斥锁各有其适用场景和优缺点。自旋锁适用于需要快速获取和释放锁的情况,而互斥锁则更适合于需要长时间持有锁的情况。选择使用哪种锁取决于具体的应用场景和对性能的要求‌。

操作系统是什么

操作系统是一种系统软件,用于管理和控制计算机硬件与软件资源,提供用户与其他软件方便的接口和环境。‌ 它是计算机系统中最基本的程序,直接运行在“裸机”上,任何其他软件都必须在操作系统的支持下才能运行。操作系统作为用户与计算机硬件系统之间的接口,同时也是计算机系统资源的管理者,实现了对计算机资源的抽象,为其他应用软件提供支持,让计算机系统所有资源最大限度地发挥作用。

lock_guard是什么

lock_guard是一个RAII(资源获取即初始化)类,它的主要目的是简化多线程编程中的锁管理,避免因忘记释放锁而导致的死锁和资源泄漏问题。通过使用lock_guard,可以确保在作用域结束时自动释放锁,从而提高了代码的可读性和可维护性。lock_guard的这种特性是通过其生命周期管理实现的,即当lock_guard对象超出其作用域时,它会自动解锁,从而释放资源。

C++中二义性问题,怎么解决?

在C++中,二义性问题主要出现在多继承场景中,当派生类需要访问基类中的同名成员时,由于基类存在同名的成员函数或变量,导致编译器无法确定访问的是哪个基类的成员,从而产生二义性错误。解决C++中的二义性问题主要有以下几种方法:

  1. 使用类名限定‌:在调用时明确指定是调用哪个类的成员函数或变量,例如c1.A::f();c1.B::f();。这种方法可以消除二义性,但需要程序员在代码中明确指出意图‌。

  2. 使用同名覆盖原则‌:在派生类中重新定义与基类中同名的成员(如果是成员函数,则参数表也要相同),以屏蔽掉基类中的同名成员。这样,在引用这些同名成员时,引用的是派生类中的成员‌。

  3. 使用虚基类‌:当多个基类共享一个公共基类,并且需要避免在派生类中产生多个相同的基类成员拷贝时,可以将公共基类声明为虚基类。虚基类通过共享基类的成员来解决多重继承中的二义性问题。在派生类的构造函数中,需要显式调用虚基类的构造函数,并在初始化列表中使用虚基类名后面加上括号来初始化‌。

  4. 避免使用多继承‌:如果可能的话,避免使用多继承,或者尽量减少多继承的使用,以减少二义性的可能性。单继承通常可以满足大部分需求,而且可以避免多继承带来的复杂性和潜在的二义性问题‌。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值