眼谷科技嵌入式软件开发 一面 总结

1.自我介绍

面试官好,我是[姓名],[学校][专业][年级]。我的技术方向是嵌入式软件开发,主要使用C++进行开发。

技术栈方面,我熟悉C++11/14特性、STL容器和算法,有Linux环境下的开发经验,了解交叉编译、驱动开发等嵌入式相关技术。在AI方面,我接触过深度学习模型的部署,特别是在嵌入式平台上部署YOLO等目标检测模型。

项目经验上,我做过[具体项目],主要负责[具体模块]的开发,涉及到[技术点]。在这个过程中积累了嵌入式开发和模型部署的实际经验。

我对嵌入式AI很感兴趣,特别是如何在资源受限的设备上实现高效的算法。希望能加入眼谷科技,在智能视觉领域深入学习和实践。

2.class和struct在C++中有什么区别?

在C++中,class和struct的区别很小,主要是默认访问权限不同。struct的成员默认是public的,而class的成员默认是private的。继承时也一样,struct默认是public继承,class默认是private继承。

struct MyStruct {
    int x;  // 默认public
};

class MyClass {
    int x;  // 默认private
};


除了这个区别,两者在功能上完全相同,都可以有成员函数、构造函数、析构函数、继承、多态等特性。实际使用中,一般用struct表示简单的数据结构(POD类型),用class表示有复杂行为的对象。

在C语言中,struct只能包含数据成员,不能有成员函数。但在C++中,struct和class几乎没有区别,这是为了兼容C语言的设计。

3.new和malloc有什么区别?使用时要注意什么?

new和malloc都是用来动态分配内存的,但有几个重要区别。

首先,new是C++的操作符,malloc是C的库函数。new会调用构造函数初始化对象,malloc只是分配内存,不会初始化。相应地,delete会调用析构函数,free只是释放内存。

// new会调用构造函数
MyClass* obj = new MyClass();  
delete obj;  // 调用析构函数

// malloc不会调用构造函数
MyClass* obj2 = (MyClass*)malloc(sizeof(MyClass));
free(obj2);  // 不会调用析构函数,可能导致资源泄漏


其次,new返回的是具体类型的指针,类型安全;malloc返回void*,需要强制类型转换。new分配失败会抛出bad_alloc异常,malloc返回NULL。new可以被重载,malloc不能。

使用建议:C++中优先使用new/delete,或者更好的是使用智能指针。如果要和C代码交互,或者需要realloc功能,才使用malloc/free。注意new和delete要配对,malloc和free要配对,不能混用。

4.C++中的智能指针有哪些?它们的核心特点是什么?

C++11引入了三种智能指针,用于自动管理内存,避免内存泄漏。

unique_ptr表示独占所有权,不能拷贝只能移动,性能开销最小,几乎等同于裸指针。适合明确的单一所有权场景,比如工厂函数返回值、替代裸指针。

std::unique_ptr<int> ptr1 = std::make_unique<int>(10);
// std::unique_ptr<int> ptr2 = ptr1;  // 错误,不能拷贝
std::unique_ptr<int> ptr2 = std::move(ptr1);  // 可以移动


shared_ptr表示共享所有权,使用引用计数管理,最后一个shared_ptr销毁时释放对象。有引用计数的开销(原子操作),适合多个对象共享资源、对象生命周期不确定的场景。

std::shared_ptr<int> ptr1 = std::make_shared<int>(10);
std::shared_ptr<int> ptr2 = ptr1;  // 引用计数+1
// ptr1和ptr2都销毁后,对象才被释放


weak_ptr是shared_ptr的观察者,不增加引用计数,用于打破循环引用。使用前需要lock()转换为shared_ptr,检查对象是否还存在。

std::shared_ptr<int> sp = std::make_shared<int>(10);
std::weak_ptr<int> wp = sp;
if (auto sp2 = wp.lock()) {  // 检查对象是否还存在
    // 使用sp2
}


嵌入式开发中,由于资源受限,要特别注意智能指针的开销。unique_ptr是首选,shared_ptr要谨慎使用,避免循环引用导致内存泄漏。

5.map和unordered_map有什么区别?如何选择?

map和unordered_map都是关联容器,但底层实现和性能特点不同。

map基于红黑树实现,元素按键自动排序,查找、插入、删除的时间复杂度都是O(log n)。遍历时元素是有序的,支持范围查询(lower_bound、upper_bound)。

std::map<int, std::string> m;
m[3] = "three";
m[1] = "one";
m[2] = "two";
// 遍历时按键排序:1, 2, 3


unordered_map基于哈希表实现,元素无序,查找、插入、删除的平均时间复杂度是O(1),最坏情况O(n)(哈希冲突严重时)。不支持范围查询,遍历顺序不确定。

std::unordered_map<int, std::string> um;
um[3] = "three";
um[1] = "one";
um[2] = "two";
// 遍历时顺序不确定


选择建议:如果需要排序或范围查询,用map;如果只需要快速查找,用unordered_map性能更好。嵌入式开发中,如果内存紧张,map的内存占用更可控;如果追求性能,unordered_map更快。注意unordered_map需要好的哈希函数,否则性能会退化。

6.C++模板有哪些特性?在嵌入式开发中如何使用?

C++模板是泛型编程的基础,主要特性包括:

函数模板和类模板,可以编写与类型无关的代码:

template<typename T>
T max(T a, T b) {
    return 

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

嵌入式面试八股文全集 文章被收录于专栏

这是一个全面的嵌入式面试专栏。主要内容将包括:操作系统(进程管理、内存管理、文件系统等)、嵌入式系统(启动流程、驱动开发、中断管理等)、网络通信(TCP/IP协议栈、Socket编程等)、开发工具(交叉编译、调试工具等)以及实际项目经验分享。专栏将采用理论结合实践的方式,每个知识点都会附带相关的面试真题和答案解析。

全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

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