内容 总结

1.智能指针:

        - shared_ptr: 共享智能指针,使用引用计数进行生命周期管理。多个指针可以指向同一个对象。

        - unique_ptr: 独占智能指针,采用移动语义,只能有一个指针独占对象。

        - weak_ptr: 弱引用智能指针,用于配合shared_ptr,不影响对象生命周期。

        优点:防止内存泄露,可以进行无显示删除。

        缺点:智能指针开销较大,包含原始指针和控制块。

2.堆和栈的区别:

        申请的方式不同,栈由系统自动分配,而堆是人为申请开辟。

        申请大小的不同:栈获得的空间较小,堆获得的空间较大。

        申请效率不同:栈由系统自动分配,速度较快,而堆一般速度较慢。

        底层不同:栈是连续空间,而堆不是连续空间。

        

        在程序内存布局场景下,堆与栈表示两种内存管理

        在数据结构场景下,堆与栈表示两种常用的数据结构

        程序内存中:

        栈区(stack)--由编译器自动分配释放,存放函数的参数值,局部变量的等。

        堆区(heap)一般由程序员分配释放--new malloc,若程序员不释放,程序结束时可能由OS回收。

        常数区(常量存储区):常量字符串,存储局部变量和全局变量的

        静态区:存储的是全局变量和静态变量

        代码区:二进制代码。

区域作用
内存栈区存放局部变量名
内存堆区存放new或者malloc出来的对象
常数区存放局部变量或者全局变量的值
静态区用于存放全局变量或者静态变量
代码区二进制代码

        常数区和静态区通常在编译期间就能确定存储大小的常量存储区,并且在程序运行期间,存储区内的常量是全局可见的。这是一块比较特殊的存储区,他们里边存放的是常量,不允许被修改。

内存存在两种属性:静态分配内存和动态分配内存。堆和栈都属于动态分配内存。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
 
void before()
{
 
}
 
char g_buf[16];  //静态区 全局初始化区
char g_buf2[16];
char g_buf3[16];
char g_buf4[16];
char g_i_buf[]="123";
char g_i_buf2[]="123";
char g_i_buf3[]="123";
 
void after()
{
 
}
 
int main(int argc, char **argv)
{
        char l_buf[16]; //栈区
        char l_buf2[16];
        char l_buf3[16];
        static char s_buf[16]; // 全局初始化区
        static char s_buf2[16];
        static char s_buf3[16];
        char *p_buf;//堆区 动态分配
        char *p_buf2;
        char *p_buf3;
 
        p_buf = (char *)malloc(sizeof(char) * 16);
        p_buf2 = (char *)malloc(sizeof(char) * 16);
        p_buf3 = (char *)malloc(sizeof(char) * 16);
 
        printf("g_buf: 0x%x\n", g_buf);
        printf("g_buf2: 0x%x\n", g_buf2);
        printf("g_buf3: 0x%x\n", g_buf3);
        printf("g_buf4: 0x%x\n", g_buf4);
 
        printf("g_i_buf: 0x%x\n", g_i_buf);
        printf("g_i_buf2: 0x%x\n", g_i_buf2);
        printf("g_i_buf3: 0x%x\n", g_i_buf3);
 
        printf("l_buf: 0x%x\n", l_buf);
        printf("l_buf2: 0x%x\n", l_buf2);
        printf("l_buf3: 0x%x\n", l_buf3);
 
        printf("s_buf: 0x%x\n", s_buf);
        printf("s_buf2: 0x%x\n", s_buf2);
        printf("s_buf3: 0x%x\n", s_buf3);
 
        printf("p_buf: 0x%x\n", p_buf);
        printf("p_buf2: 0x%x\n", p_buf2);
        printf("p_buf3: 0x%x\n", p_buf3);
 
        printf("before: 0x%x\n", before);
        printf("after: 0x%x\n", after);
        printf("main: 0x%x\n", main);
 
        if (argc > 1)
        {
                strcpy(l_buf, argv[1]);
        }
        return 0;
}

3.C++ 中 死锁产生原因以及处理方法:

        原因:

                1.同时持有多个资源,而按不同顺序申请资源

                2.资源无法抢占,进程触发等待条件,相互等待。

                3.资源分配不当导致竞争和等待

        死锁的必要条件:

                1.互斥条件:资源被互斥使用,同时只能被一个进程占有

                2.请求与保持条件:进程已获得的资源在申请新的资源前不释放。

                3.不剥夺条件:其他进程无法强制剥夺正在被占用的资源

                4.环路等待条件:形成环路进程等待图

        解除死锁的方式:

                1.防止形成环路等待条件,破坏环路等待条件。

                2.使用顺序申请资源

                3.设置资源申请超时时间,超过时间后,需要释放其他资源

                4.提前规划资源分配,防止不合理的竞争与等待

                5.允许抢占资源,破坏不剥夺条件

                6.打破互斥条件,允许并发访问资源的某些部分

4.编程:数组内连续子数组大于指定数的个数

给定一个元素都是正整数的数组A,正整数L以及R(L<=R)。求连续、非空其中最大元素满足大于等于L小于等于R的子数组个数。例如:输入A=[2,1,4,3] L=2,R=3,输出:3,满足条件的子数组:[2],[2,1],[3]

# include <iostream>
#include <vector>
using namespace std;

//数组A中的数据分为三个部分,大于R的为分界线,当遇到大于R的数值的时候,count = 0;当元素在[L,R]之间的时候为i-j,因为连续所以i-j。当小于L的时候count和上一个元素的一样。
int numSubarrayBoundedMax(vector<int>&A, int L, int R) {
    int j = -1;
    int ans = 0;
    int count = 0;
    for(int i = 0; i < A.size(); i++ ){
        if (A[i] > R) {
            j = i;
        }
        if(A[i] >= L){
            count = i - j;
        }
        ans +=count;
    }
    return ans;
}

5.unordered_map和map的主要区别是:

        底层数据结构不同:

                unordered_map底层使用哈希表实现,元素无序。

                map底层常用红黑树实现,元素有序。

        查询速度不同:

                unordered_map查询速度很快,可达到O(1)复杂度;

                map查询速度较unordered_map慢,为O(logn)复杂度;

        接口略有不同:

                unordered_map 没有 map 的 lower_bound、upper_bound 等函数。

        实现原理:

                unordered_map 使用哈希函数和桶来保存元素,通过关键字快速确定位置;

                map 将元素保存在红黑树节点中,通过比较来维持元素键值有序。

       综上,一般优先使用 unordered_map,除非需要顺序或自定义排序,才使用 map。空间换时间的原则。

        C++中如果map的赋值key为自定义的类实现   。因为map中的key是有序的,所以自定义的类需要可以比较大小,需要重载小于操作符 operator < ()操作符。在我们插入<key, value>时,map会先通过比较函数地函数对象来比对key的大小,然后根据比对结果进行有序存储。c++标准库中,map比较函数的函数对象不可避免地会用到’<'运算,因此一种方法就是直接在自定义类里重载operator<()操作符,如下所示。

#include <iostream>
#include <map>
#include <string>
using namespace std;

class Person{
public:
    string name;
    int age;

    Person(string n, int a){
        name = n;
        age = a;
    }

    bool operator<(const Person &p) const //注意这里的两个const
    {
        return (age < p.age) || (age == p.age && name.length() < p.name.length()) ;
    }
};

int main(int argc, char* argv[]){
    map<Person, int> group;
    group[Person("Mark", 17)] = 40561;
    group[Person("Andrew",18)] = 40562;
    for (auto ii = group.begin() ; ii != group.end() ; ii++)
        cout << ii->first.name 
        << " " << ii->first.age
        << " : " << ii->second
        << endl;
    return 0;
}

这里,我们需要注意的是,在重载operator<(){}时,无论是参数还是整个函数的const都不能少。参照less的定义,less的参数和函数整体都是const,那么被调用的operator<()必然也是同等要求。     

6.引用和指针的区别:

        1.引用访问一个变量是直接访问,而指针访问是间接访问。

        2.引用是一个变量的别名,本身不单独分配内存空间,而指针有自己的内存空间。

        3.引用指向某个对象之后就不可以改变,指针可以改变其所指的值。

        4.不存在指向空值的引用,但是存在指向空值的指针。

        5.引用是类型安全的,指针不是。                                     

7.C++中动态链接库和静态链接库的区别:

        常见的文件后缀:

                动态链接库:Windows:.dll。Linux: .so。

                静态链接库:Windows:.lib  Linux:.a

        静态链接会使可执行文件变得庞大,但具有更好的兼容性和运行速度;而动态链接则更加灵活,节省空间,但可能存在兼容性和性能的问题。

8.各种传感器的优缺点:

        优点:

                lidar:精度高,点云密度大,夜视能力强,探测距离远。可以提供物体准确的深度信息和结构信息。

                camera:价格低,细节纹理丰富可以提供颜色信息。对小目标的识别效果好。

                radar:成本低,可检测运动物体的速度。

        缺点:        

                lidar:成本相对来说较高,对气候条件敏感(雨雪雾天气)。

                camera:夜晚条件下检测效果差,对深度信息无法准确获得

                radar:精准度低,有的时候会出现鬼影。

    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值