C++日更八股--first

### 内存static和dynamic的区别
static(静态)​​ 和 ​​dynamic(动态)<br>
static:内存分配在编译的时候确定,大小和生命周期固定,无需运行时分配开销<br>
dynamic:内存分配在运行时动态申请和释放(new),适应不确定的需求<br>

### const 修饰的变量,可以被修改吗
可以通过引用修改<br>
实例代码如下<br>
const int x = 100;<br>
int *p = (int*)&x;//得到x的地址,通过定义指针接收<br>
*p = 200;<br>
上述代码就可以绕过const的限制<br>

### 智能指针的介绍
使用智能指针式为了自动释放资源,避免内存泄漏(忘记delete)和程序崩溃(多次delete)<br>
C++11引入了如下智能指针:包含在头文件<memory>中<br>
1.std::unique_ptr(独占所有权)<br>
  同一时间只能有一个unique_ptr拥有资源,不可复制,但支持移动语义(std::move)(补充:相信有的朋友不知道什么是移动语义,这道题结束介绍)<br>
  管理动态分配的单个对象或者数组<br>
  代码实例:<br>
    std::unique_ptr<int> p1 = std::make_unique<int>(10);<br>
    std::unique_ptr<int[]> p2 = std::make_unique<int>(5);<br>
    //转移所有权<br>
    std::unique_ptr<int> p3 = std::move(p1);<br>
2.std::shared_ptr(共享所有权)<br>
  多个shared_ptr共享一个资源,通过引用计数的方式跟踪资源所有者数量,计数为0的时候自动释放资源<br>
  // 创建 shared_ptr<br>
  std::shared_ptr<int> p1 = std::make_shared<int>(20);<br>
  std::shared_ptr<int> p2 = p1; // 引用计数 +1<br>
  需要避免两个shared_ptr互相引用,导致引用计数器无法归零,可以将其中一个指针替换为weak_ptr<br>
  // 创建两个 shared_ptr 并互相引用
    std::shared_ptr<A> a = std::make_shared<A>();<br>
    std::shared_ptr<B> b = std::make_shared<B>();<br>
    a->b_ptr = b;  // a 引用 b<br>
    b->a_ptr = a;  // b 引用 a<br>
  
 (如果你学过操作系统文件管理中的共享文件打开文件表的话,理解应该不难,本题结束补充)<br>
3.std::weak_ptr(弱引用)<br>
  不增加引用计数,不拥有资源所有权,用于解决shared_ptr的循环引用问题,经常用于转换this指针<br>
4.auto_str(已经不使用了)<br>
  所有权转移时会导致原指针变为 nullptr,容易引发错误,不需要记忆<br>
  
note:智能指针是可以手动释放的,使用reset()//释放资源并将指针置为nullptr<br>

### 这里补充一下,面试官看到这里觉得你小子很懂了???,那么继续向下追问:你是否能写一下智能指针的实现

1.std::unique_str(这个的实现有点类似于设计模式中的懒汉模式的单例模式)
  template<typename T>
  class UniquePtr {
  private:
      T* ptr;
  public:
      explicit UniquePtr(T* p = nullptr) : ptr(p) {}//构造函数,explicit 关键字用于防止隐式类型转换​​
      ~UniquePtr() { delete ptr; }

    // 禁用复制
      UniquePtr(const UniquePtr&) = delete;
      UniquePtr& operator=(const UniquePtr&) = delete;

    // 支持移动语义
      UniquePtr(UniquePtr&& other) : ptr(other.ptr) { other.ptr = nullptr; }
      UniquePtr& operator=(UniquePtr&& other) {
          if (this != &other) {
              delete ptr;
              ptr = other.ptr;
              other.ptr = nullptr;
            }
        return *this;
      }
  };

2.std::shared_ptr
  这个实现比较复杂,读者可以自行查阅资料,涉及到的函数较多,但是不实现的话思想还是简单的<br>
  这里简单介绍一下:count计数私有化,随后构造函数中需要在参数列表中对其初始化,再有就是=运算符重载,实现所有权的共享,但是要注意的是这里需要实现对原有资源的释放,不然会造成内存泄露的(-_-)。<br>

### 本题花了好长时间啊,这里是之前承诺的补充

1.移动语义move<br>
  为C++11引入的核心特性,旨在转移资源所有权来提高程序性能,其实就是原指针置空,现指针指向当前资源<br>
2.操作系统的打开文件表<br>
  在操作系统中存在一个系统打开文件表,通过引用计数来跟踪共享文件的用户数量,这是实现多线程和多进程共享文件的核心机制之一<br>
  首选每个进程维护一个进程打开文件表,这个里面记录了进程打开的文件,同时表中的每个条目(文件描述符),注意打开文件最初是使用文件名去找寻文件对应的inode,找到后就可以使用文件描述符访问文件了<br>
  随后系统打开文件表中包含了所有被打开的文件,这里使用引用计数来标识有多少进程正在使用这个文件<br>

### C++11新特性的了解
1.自动类型推导(手撕的时候没少用)
2.智能指针,上面已经介绍
3.右值引用和移动语义
4.Lambda 表达式​ [capture](params){ body } //定义匿名函数,简化回调。上述顺序为捕获遍历,定义,函数体
5.nullptr 关键字​
6.override 和 final 关键字​:override​​:显式标记派生类虚函数覆盖基类虚函数,final​​:禁止类被继承或虚函数被覆盖
7.线程支持(std::thread, std::mutex 等)
8. 类型别名(using 替代 typedef)​
9. 默认和删除函数(=default, =delete)

### 嵌入式软件工程师经典面试题目及答案 #### 1. 解释什么是嵌入式系统及其特点? 嵌入式系统是一种专用计算机系统,设计用于执行特定功能或一组有限的功能。这类系统的典型特点是资源受限、实时性和可靠性要求高。由于其特殊的应用场景,通常对处理器性能、功耗以及成本有着严格的要求[^4]。 ```c++ // 示例:简单的延时函数实现 void delay_ms(uint32_t ms) { while (ms--) { // 实现具体的毫秒级延迟逻辑 } } ``` #### 2. 描述C/C++中的`volatile`关键字的作用是什么? `volatile`告诉编译器该变量可能会被意想不到地改变,因此每次访问此变量时都必须从实际存储位置读取最新值而不是缓存副本。这对于处理硬件寄存器或其他可能由外部因素修改的数据非常重要[^5]。 ```cpp volatile uint8_t *const UART_STATUS_REG = reinterpret_cast<volatile uint8_t*>(0x40013800); if (*UART_STATUS_REG & TX_COMPLETE_FLAG) { // 处理发送完成事件 } ``` #### 3. C++中`this`指针的本质是什么?如何理解它的工作机制? `this`指针本质上是一个隐式的成员函数参数,在实例方法内部代表当前对象的地址。这意味着当调用类的一个非静态成员函数时,编译器会自动传递一个指向调用者的指针作为第一个实参给这个函数。需要注意的是,只有非静态成员函数才有`this`指针;而全局函数和静态成员函数则没有这样的特性[^3]。 ```cpp class ExampleClass { public: void exampleMethod() { std::cout << "Address of current object: " << this; } }; ``` #### 4. 如何区分堆与栈的区别并说明各自适用场合? 两者主要差异体现在内存分配策略上——栈采用LIFO(Last In First Out)原则管理局部变量的空间申请与释放过程,具有较快的速度但容量相对较小;相反,堆允许动态创建任意大小的对象,并且这些对象可以在整个应用程序生命周期内持续存在直到显式销毁为止。然而,不当使用可能导致严重的内存泄露风险。因此开发者应当依据具体需求谨慎选择合适的内存区域进行编程操作[^2]。 ```cpp int main() { int stackVar; // 定义于栈上的整型数 int* heapVar = new int(1); // 动态分配到堆区的一块空间 delete heapVar; // 使用完毕后记得及时清理以防止泄漏 } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值