面试真题 | 小米智能座舱

自我介绍

介绍项目

static关键字,在类里面使用呢?

问题回答:static关键字在类里面的使用

在C++中,static关键字在类里面有多种用途,主要包括静态成员变量和静态成员函数。以下是详细解释:

静态成员变量

  1. 定义与声明

    • 静态成员变量在类内声明,但在类外定义和初始化。它不属于类的任何对象,而是属于类本身。
    • 声明时使用static关键字,如static int count;
    • 定义时在类外,如int ClassName::count = 0;
  2. 存储位置

    • 静态成员变量存储在全局数据区,而不是对象的内存空间中。
    • 因此,所有对象共享同一个静态成员变量的值。
  3. 访问方式

    • 可以通过类名和作用域解析运算符::来访问静态成员变量,如ClassName::count
    • 也可以通过对象来访问,但这不是推荐的做法,因为它可能引发误解。
  4. 用途

    • 常用于计数、记录类的实例数量、作为类内部的全局变量等。

静态成员函数

  1. 定义与声明

    • 静态成员函数在类内声明时使用static关键字,如static void display() {}
    • 它不属于类的任何对象,因此不能访问非静态成员变量或非静态成员函数(除非通过对象指针或引用传递)。
  2. 调用方式

    • 可以通过类名和作用域解析运算符::来调用静态成员函数,如ClassName::display()
    • 也可以通过对象来调用,但同样不是推荐的做法。
  3. 参数传递

    • 由于静态成员函数不能访问非静态成员,如果需要访问,通常通过参数传递对象指针或引用。
  4. 用途

    • 常用于实现与类相关的功能,但不依赖于特定对象的状态。
    • 如工厂函数、工具函数等。

面试官追问及相关回答

追问1

  • 问题:静态成员变量和静态成员函数与普通成员变量和成员函数的主要区别是什么?
  • 回答
    • 存储位置不同:静态成员变量存储在全局数据区,而普通成员变量存储在对象的内存空间中。
    • 访问方式不同:静态成员变量和成员函数可以通过类名直接访问,而普通成员变量和成员函数只能通过对象来访问。
    • 生命周期不同:静态成员变量在程序运行时一直存在,直到程序结束;而普通成员变量的生命周期与对象的生命周期相同。
    • 作用域不同:静态成员变量和成员函数的作用域是整个类,而普通成员变量和成员函数的作用域是类的实例。

追问2

  • 问题:在嵌入式系统中使用静态成员变量和静态成员函数有哪些需要注意的地方?
  • 回答
    • 注意内存使用:由于静态成员变量存储在全局数据区,如果大量使用静态成员变量,可能会导致内存占用过多。
    • 避免多线程冲突:在多线程环境中,如果多个线程同时访问同一个静态成员变量,需要采取同步措施来避免数据竞争。
    • 谨慎使用静态成员函数访问非静态成员:虽然可以通过参数传递对象指针或引用来访问非静态成员,但这会增加函数的复杂性和出错的可能性。因此,在设计类时,应尽量避免在静态成员函数中访问非静态成员。

追问3

  • 问题:能否给出一个使用静态成员变量和静态成员函数的实际例子?
  • 回答
    class Counter {
    public:
        // 静态成员变量,用于记录类的实例数量
        static int count;
    
        // 构造函数,每次创建对象时增加计数
        Counter() {
            count++;
        }
    
        // 析构函数,每次销毁对象时减少计数
        ~Counter() {
            count--;
        }
    
        // 静态成员函数,用于显示当前计数
        static void displayCount() {
            std::cout << "Current count: " << count << std::endl;
        }
    };
    
    // 在类外定义和初始化静态成员变量
    int Counter::count = 0;
    
    int main() {
        Counter obj1, obj2;
        Counter::displayCount(); // 输出:Current count: 2
        Counter* obj3 = new Counter();
        Counter::displayCount(); // 输出:Current count: 3
        delete obj3;
        Counter::displayCount(); // 输出:Current count: 2
        return 0;
    }
    
    这个例子展示了如何使用静态成员变量来记录类的实例数量,并使用静态成员函数来显示该数量。

智能指针?

智能指针回答

问题:请解释一下C++中的智能指针,并详细讨论其种类、工作原理以及使用场景。

回答

智能指针是C++中用于自动管理动态分配内存的一种机制,它通过封装原始指针并提供对资源的自动释放,从而避免了内存泄漏和悬空指针等问题。C++标准库提供了几种主要的智能指针,包括std::unique_ptrstd::shared_ptrstd::weak_ptr

  1. std::unique_ptr

    • 独占所有权的智能指针,不允许复制,只能移动。
    • unique_ptr被销毁或离开作用域时,它所指向的对象也会被自动删除。
    • 适用于需要确保只有一个所有者管理资源的场景。
  2. std::shared_ptr

    • 共享所有权的智能指针,允许多个shared_ptr实例共享同一个对象。
    • 使用引用计数机制来管理对象的生命周期,当最后一个shared_ptr被销毁或重置时,对象会被自动删除。
    • 适用于多个所有者需要共享资源的场景,但需要注意循环引用的问题。
  3. std::weak_ptr

    • 弱引用,用于解决shared_ptr之间的循环引用问题。
    • 不会增加对象的引用计数,因此不会延长对象的生命周期。
    • 可以从shared_ptr或另一个weak_ptr创建,但不能直接访问对象,必须通过lock()方法获取shared_ptr来临时访问对象。

工作原理

  • unique_ptr通过其析构函数来释放资源,当unique_ptr对象被销毁时,它会调用delete来释放其所指向的对象。
  • shared_ptr使用控制块(通常包含引用计数和指向实际对象的指针)来管理对象的生命周期。当shared_ptr被复制或赋值时,控制块会被共享,引用计数会增加。当shared_ptr被销毁或重置时,引用计数会减少。当引用计数变为0时,控制块和对象都会被释放。
  • weak_ptr不直接管理资源,而是指向shared_ptr的控制块。它不会增加引用计数,因此不会阻止shared_ptr所管理的对象被销毁。

使用场景

  • unique_ptr适用于需要确保资源独占所有权的场景,如动态数组、单例模式等。
  • shared_ptr适用于多个所有者需要共享资源的场景,如对象图、树形结构等。但需要注意避免循环引用。
  • weak_ptr通常与shared_ptr一起使用,用于解决循环引用问题,或在不增加引用计数的情况下观察对象的状态。

面试官追问及回答

追问1

  • 问题:请解释一下std::make_unique的作用,以及为什么推荐使用它而不是直接使用new来创建unique_ptr
  • 回答
    • std::make_unique是一个模板函数,用于创建并初始化一个unique_ptr。它接受与new相同的参数,并返回一个unique_ptr对象。
    • 推荐使用std::make_unique而不是直接使用new来创建unique_ptr的原因有几个:
      • std::make_unique更加简洁和直观,它直接返回unique_ptr,而不需要显式地调用new
      • std::make_unique是异常安全的。如果构造函数抛出异常,它不会泄漏内存,因为new表达式和unique_ptr的构造函数是作为一个原子操作执行的。
      • 使用std::make_unique可以避免潜在的内存泄漏问题。如果直接使用new来创建对象,然后再将其地址赋给unique_ptr,在赋值过程中如果发生异常,可能会导致内存泄漏。而std::make_unique则保证了在异常发生时不会泄漏内存。

追问2

  • 问题:在shared_ptrunique_ptr之间如何选择?请给出一些具体的选择依据。
  • 回答
    • 在选择shared_ptrunique_ptr时,需要考虑资源的所有权和管理方式。
    • 如果资源只需要被一个所有者管理,并且不希望其他代码能够访问或共享这个资源,那么应该

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

ARM/Linux嵌入式真题 文章被收录于专栏

让实战与真题助你offer满天飞!!! 每周更新!!! 励志做最全ARM/Linux嵌入式面试必考必会的题库。 励志讲清每一个知识点,找到每个问题最好的答案。 让你学懂,掌握,融会贯通。 因为技术知识工作中也会用到,所以踏实学习哦!!!

全部评论

相关推荐

11-25 22:06
已编辑
华为 2012基座大模型(预研) 15A 硕士985
点赞 评论 收藏
分享
头像
10-13 18:10
已编辑
东南大学 C++
。收拾收拾心情下一家吧————————————————10.12更新上面不知道怎么的,每次在手机上编辑都会只有最后一行才会显示。原本不想写凉经的,太伤感情了,但过了一天想了想,凉经的拿起来好好整理,就像象棋一样,你进步最快的时候不是你赢棋的时候,而是在输棋的时候。那废话不多说,就做个复盘吧。一面:1,经典自我介绍2,项目盘问,没啥好说的,感觉问的不是很多3,八股问的比较奇怪,他会深挖性地问一些,比如,我知道MMU,那你知不知道QMMU(记得是这个,总之就是MMU前面加一个字母)4,知不知道slab内存分配器-&gt;这个我清楚5,知不知道排序算法,排序算法一般怎么用6,写一道力扣的,最长回文子串反问:1,工作内容2,工作强度3,关于友商的问题-&gt;后面这个问题问HR去了,和中兴有关,数通这个行业和友商相关的不要提,这个行业和别的行业不同,别的行业干同一行的都是竞争关系,数通这个行业的不同企业的关系比较微妙。特别细节的问题我确实不知道,但一面没挂我。接下来是我被挂的二面,先说说我挂在哪里,技术性问题我应该没啥问题,主要是一些解决问题思路上的回答,一方面是这方面我准备的不多,另一方面是这个面试写的是“专业面试二面”,但是感觉问的问题都是一些主管面/综合面才会问的问题,就是不问技术问方法论。我以前形成的思维定式就是专业面会就是会,不会就直说不会,但事实上如果问到方法论性质的问题的话得扯一下皮,不能按照上面这个模式。刚到位置上就看到面试官叹了一口气,有一些不详的预感。我是下午1点45左右面的。1,经典自我介绍2,你是怎么完成这个项目的,分成几个步骤。我大致说了一下。你有没有觉得你的步骤里面缺了一些什么,(这里已经在引导我往他想的那个方向走了),比如你一个人的能力永远是不够的,,,我们平时会有一些组内的会议来沟通我们的所思所想。。。。3,你在项目中遇到的最困难的地方在什么方面4,说一下你知道的TCP/IP协议网络模型中的网络层有关的协议......5,接着4问,你觉得现在的socket有什么样的缺点,有什么样的优化方向?6,中间手撕了一道很简单的快慢指针的问题。大概是在链表的倒数第N个位置插入一个节点。————————————————————————————————————10.13晚更新补充一下一面说的一些奇怪的概念:1,提到了RPC2,提到了fu(第四声)拷贝,我当时说我只知道零拷贝,知道mmap,然后他说mmap是其中的一种方式,然后他问我知不知道DPDK,我说不知道,他说这个是一个高性能的拷贝方式3,MMU这个前面加了一个什么字母我这里没记,别问我了4,后面还提到了LTU,VFIO,孩子真的不会。
走呀走:华子二面可能会有场景题的,是有些开放性的问题了
点赞 评论 收藏
分享
评论
1
28
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务