刷题-1

1.进程/线程/协程

进程与线程:
  • 进程是资源分配的独立单位,线程是资源调度和分配的最小单位。
  • 资源拥有:进程拥有独立的地址空间。而统一进程下的线程共享地址空间和资源,包括内存/文件句柄等。
  • 通信方式:进程通信有特定的机制,比如管道/共享内存/消息队列/信号等方式。而线程因为内存等资源是共享的,所以可以通过直接读写全局变量等就可以通信
  • 上下文切换:进程切换的开销远大于线程,因为进程切换涉及到了虚拟地址的切换。同样的道理,进程创建的成本也是远高于线程的。
  • 错误影响:得益于内存隔离,单一进程崩溃不会直接影响到其他进程。而线程又可能会对其他线程造成直接影响。
协程

协程可以看作是完全作用在用户态的线程,主要用于减少成本,提高并发性。

2.堆/栈

  • 内存管理:栈内存由操作系统管理分配,而堆为程序员手动分配。
  • 数据结构:栈遵循先入后出原则,而堆的结构较复杂多样。(堆的结构如最大堆/最小堆等也是考察重点!)
  • 性能:堆的大小远大于栈,但栈的访问速度比堆快很多。
  • 服务对象:栈主要储存局部变量/函数调用/表达式求值,而堆用于动态内存分配/数据持久化/对象存储等

3.指针/引用

指针是独立变量/指针可以改变所指地址/大小/指针有多重指针/引用必须初始化,不可为空/

引用通常用于函数传参,指针用于内存管理和访问。

4.为什么 析构函数常用虚函数 ?为什么构造函数不虚?

  • 析构函数使用虚函数:可以确保资源正确释放,防止内存泄漏。在多态的情况下,基类指针可以指向派生类对象,析构函数定义为虚函数可以确保删除对象时正确调用析构函数。
  • 构造函数不能定义为虚函数:构造函数的初始化用途使得构造函数不能定义为虚函数。

5.CPP中 多态的实现有哪几种 ? (静态 /动态)

  • 静态多态:也叫编译时多态,主要包括运算符重载和函数重载以及模板。
  • 动态多态:也叫运行时多态,包括虚函数和基类指针引用等。

6.new /malloc区别及底层实现原理

new/malloc的区别
  • new不仅会分配内存还会调用对象的构造函数,而malloc无构造函数。
  • new返回的是对象类型的指针。而malloc默认返回void*类型,一般要进行类型转换。
  • 分配失败的处理方式不同,new会抛出异常,malloc会返回NULL。
  • new是运算符可以被重载,而malloc是库函数不能被重载。
  • new和malloc的底层实现原理不同(见下文)
new/malloc的底层实现
  • new的底层机制主要分为两个部分:分配器和构造器。分配器负责从堆中分配内存,一般会调用第一级的内存管理函数,比如malloc或者由操作系统提供的函数。构造器用来初始化对象,包括调用构造函数,返回地址。
  • malloc的底层:小型brk,大型mmap直接映射到地址空间。

7.Struct→CPP内存对齐

内存对齐方式默认由编译器决定,也可以手动设定。目的是提高内存访问速度。

  • 结构体struct中每个成员变量默认都要对其它的下一位成员补齐,且最末结构体要是最大对齐因子的倍数,话不多说直接上例子。所以这个结构体占用内存为1+(3)+4+8=16,16=2*8,符合要求。
struct MyStruct {
    char a;     // 占用1字节,后面需要3字节的填充以对齐下一个成员
    int b;      // 占用4字节
    double c;   // 占用8字节(在大多数平台上)
};

8.进程通信

管道/共享内存/消息队列/信号/套接字

9.const/ static关键字

10.智能指针△

11.怎么保证线程安全

12.常见处理哈希冲突的方法

13.深拷贝和浅拷贝

14.左值引用和右值引用

posted @ 2024-11-01 17:00  寒柏懒得想  阅读(7)  评论(0编辑  收藏  举报