东软集团 C++开发 一面

1. C 和 C++ 的不同

答案:C 和 C++ 最大的区别,不只是“一个面向过程,一个面向对象”,而是它们在抽象能力、类型系统和资源管理方式上差异很大。

从语言层面看,C 更偏底层过程式编程,强调结构体、函数、指针和手动资源管理。C++ 在兼容 C 的基础上,增加了很多更强的抽象能力:

  • 面向对象:封装、继承、多态
  • 泛型编程:模板
  • 资源管理:RAII
  • 标准库:STL 容器、算法、智能指针、线程库
  • 更强的类型系统:引用、函数重载、命名空间、异常等

实际开发里,C 更适合:

  • 对运行时开销极度敏感的场景
  • 偏底层、硬件、驱动、嵌入式开发

C++ 更适合:

  • 大型工程
  • 需要抽象能力和可维护性的系统
  • 对性能和工程化都要求较高的场景

代码:

// C 风格
struct Point {
    int x;
    int y;
};

void init(Point* p, int x, int y) {
    p->x = x;
    p->y = y;
}

// C++ 风格
class PointCpp {
public:
    PointCpp(int x, int y) : x_(x), y_(y) {}
    void print() const {}

private:
    int x_;
    int y_;
};

2. 可调用对象有哪些?函数指针、仿函数、Lambda、std::function 有什么区别

答案:

常见可调用对象包括:

  • 普通函数
  • 函数指针
  • 仿函数对象
  • Lambda 表达式
  • std::function
  • 成员函数指针(需要绑定对象)

它们的区别主要体现在:

  • 是否能保存状态
  • 是否有类型擦除
  • 调用开销是否固定
  • 使用方式是否灵活

函数指针:

  • 本质是指向函数入口地址
  • 轻量,开销小
  • 只能表示普通函数或静态函数

仿函数对象:

  • 通过重载 operator()
  • 可以保存状态
  • 编译期类型明确,优化空间大

Lambda:

  • 本质上通常也是一个匿名仿函数对象
  • 支持捕获上下文
  • 使用很灵活

std::function

  • 提供统一调用包装
  • 能装函数指针、Lambda、仿函数
  • 使用方便,但可能有额外开销

代码:

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

void foo() {
    cout << "foo\n";
}

struct Functor {
    void operator()(int x) const {
        cout << "Functor: " << x << "\n";
    }
};

int main() {
    void (*fp)() = foo;
    fp();

    Functor f;
    f(10);

    auto lam = [](int x) { cout << "Lambda: " << x << "\n"; };
    lam(20);

    std::function<void(int)> func = lam;
    func(30);
}

3. 值传递、指针传递、引用传递有什么区别

答案:核心区别在于:是否拷贝实参、函数内是否能直接影响外部对象、语义是否清晰。

值传递:

  • 会拷贝一份参数
  • 函数内修改的是副本
  • 不影响外部原对象
  • 对于大对象可能有拷贝开销

指针传递:

  • 传的是地址的副本
  • 通过解引用可以修改外部对象
  • 可能为空,需要判空
  • 语义上更偏“可选对象”或“需要显式地址操作”

引用传递:

  • 本质上是别名
  • 可以直接操作原对象
  • 语法更自然
  • 不能为空,通常比指针更适合作为必须参数

如果参数是大对象,又不需要修改,一般常用:

  • const T&

这样既避免拷贝,也不允许修改。

代码:

#include <iostream>
using namespace std;

void byValue(int x) {
    x = 100;
}

void byPointer(int* x) {
    if (x) *x = 200;
}

void byReference(int& x) {
    x = 300;
}

int main() {
    int a = 10;
    byValue(a);
    cout << a << endl;   // 10

    byPointer(&a);
    cout << a << endl;   // 200

    byReference(a);
    cout << a << endl;   // 300
}

4. listvector 的内容和区别

答案:vectorlist 都是 STL 容器,但底层结构完全不同。

vector

  • 底层是连续内存
  • 支持随机访问
  • 尾部插入效率高
  • 扩容时可能整体搬迁
  • 遍历性能通常很好,cache 友好

list

  • 底层是双向链表
  • 不支持随机访问
  • 任意位置插入删除方便
  • 每个节点有额外指针开销
  • 内存不连续,遍历局部性差

如果只看理论复杂度,很多人会觉得插删多就用 list。但真实工程里,vector 往往仍然更常见,因为:

  • 连续内存的访问性能通常更好
  • 常数开销更小
  • 大多数场景读多写少

代码:

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

int main() {
    vector<int> v = {1, 2, 3};
    list<int> l = {1, 2, 3};

    v.push_back(4);
    l.push_back(4);
}

5. 模板和模板特化

答案:模板的作用是把类型参数化,让同一份代码适配不同类型。它是 C++ 泛型编程的基础。

常见模板有两类:

  • 函数模板
  • 类模板

模板特化是在“通用模板”基础上,对某些特定类型提供专门实现。常见形式有:

  • 全特化
  • 偏特化(主要用于类模板)

适合使用模板特化的场景通常是:

  • 某些类型需要特殊处理
  • 通用实现对特定类型效率不高
  • 需要根据类型定制行为

代码:

#include <iostream>
using namespace std;

template <typename T>
class Printer {
public:
    void print() {
        cout << "generic type\n";
    }
};

template <>
class Printer<int> {
public:
    void print() {
        cout << "int specialization\n";
    }
};

int main() {
    Printer<double> p1;
    p1.print();

    Printer<int> p2;
    p2.print();
}

6. 什么是完美转发?T&& 在模板里为什么不一定是右值引用

答案:

在模板里,T&& 不总是普通意义上的右值引用。如果它出现在类型推导场景里,往往是转发引用。它的特点是:

  • 传入左值时,T 会被推导成左值引用类型
  • 传入右值时,T 会被推导成普通类型

完美转发的目的,是把参数原本的值类别保留下来,再继续传给其他函数,避免不必要的拷贝或错误地把左值当右值。

常见搭配是:

  • T&&
  • std::forward<T>(arg)

代码:

#include <iostream>
#include <utility>
usin

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

C++ 常考面试题总结 文章被收录于专栏

本专栏系统梳理C++方向, 大中厂高频高频面试考点 , 内容皆来自真实面试经历,从基础语法、内存管理、STL与设计模式,到操作系统与项目实战,结合真实面试题深度解析,帮助开发者高效查漏补缺,提升技术理解与面试通过率,打造扎实的C++工程能力.

全部评论

相关推荐

03-06 17:03
北京大学 C++
1.C++11&nbsp;的新特性有哪些1.1说下智能指针1.1.1shared_ptr&nbsp;它是线程安全的吗1.2nullptr&nbsp;有什么作用,以前有&nbsp;NULL,为什么要加一个&nbsp;nullptr2.const&nbsp;和&nbsp;static&nbsp;的作用2.1还有哪些其他作用,如修饰函数,修饰类里面的函数、类里面的变量。2.2声明类的时候加一个&nbsp;const,能调用它里面的成员函数吗3.C++&nbsp;有哪些类型转换,如&nbsp;static_cast&nbsp;之类的3.1reinterpret_cast&nbsp;的作用是什么3.2了解过&nbsp;dynamic_cast&nbsp;吗4.C++&nbsp;有哪些&nbsp;STL&nbsp;容器4.1vector&nbsp;和&nbsp;list&nbsp;有什么区别5.C++&nbsp;一些网络你知道吗,epoll&nbsp;你用过吗6.你用&nbsp;Linux&nbsp;多吗,看一些网络、磁盘&nbsp;IO、CPU&nbsp;性能的工具了解吗6.1那网络流量,一个节点到另一个节点的占比的工具用过吗7.进程和线程有什么区别7.1进程之间通信有哪些方式7.1.1信号量了解吗7.2线程之间有哪些通信方式7.2.1锁了解过吗,条件变量了解过吗8.TCP&nbsp;和&nbsp;UDP&nbsp;的区别8.1TCP&nbsp;和&nbsp;UDP&nbsp;都发送若干个网络包,都能确保完整收到这些包吗,收到的顺序对不对9.git&nbsp;用的是命令还是&nbsp;GUI9.1写了一些代码还没有存进去,但是另一个人提了一个版本要合进来,该怎么操作9.2git&nbsp;stash&nbsp;有什么作用10.MySQL&nbsp;的事务隔离级别有哪些11.怎么知道哪些线程占用的&nbsp;CPU&nbsp;比较多12.用过哪些&nbsp;AI&nbsp;编程工具12.1改变量的名字的时候用的惯吗13.LeetCode128&nbsp;最长连续序列吓哭了,沉浸式拷打,自己掌握的还是太薄弱了,面试官人好实力又强,我菜菜😭😭😭
查看30道真题和解析
点赞 评论 收藏
分享
03-04 07:14
门头沟学院 C++
何木健一:去啥?你能考虑去就是思想有问题,当然一周到岗一天可以考虑一下😨
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

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