恒生电子 C++开发 一面

1. 讲一下虚函数表,以及虚函数什么时候生成的?构造函数可以被定义为虚函数吗?

答案:C++ 里带虚函数的类,编译器通常会为它生成一张虚函数表,表里存放的是该类各个虚函数最终对应的函数入口地址。对象实例里一般还会有一个隐藏的虚表指针,用来在运行时找到这张表。通过基类指针或引用调用虚函数时,程序会先取出对象里的虚表指针,再间接找到真正要执行的函数,这就是运行时多态的基础。虚函数表是在编译期由编译器根据类定义生成的,不是运行时动态“创建”的。真正到运行时参与的是对象里的虚表指针初始化过程。对象构造时,编译器会在不同构造阶段把 vptr 指向当前构造层级对应的虚表,所以构造和析构期间的虚函数行为要特别小心。构造函数不能声明为虚函数。因为调用构造函数的前提恰恰是对象还没有构造完成,这时对象的多态基础都还没稳定建立,拿“虚调用”去决定怎么构造本身在语义上就是矛盾的。析构函数则经常要声明为虚函数,尤其是当类要作为基类被多态删除时。

代码:

#include <iostream>
using namespace std;

class Base {
public:
    virtual void f() { cout << "Base::f\n"; }
    virtual ~Base() = default;
};

class Derived : public Base {
public:
    void f() override { cout << "Derived::f\n"; }
};

int main() {
    Base* p = new Derived();
    p->f();
    delete p;
    return 0;
}

2. protected 的作用是什么

protected 主要用于控制继承体系内的访问边界。一个成员如果是 protected,那么类外部不能直接访问,但派生类内部可以访问。它比 private 更开放一些,比 public 又更收敛一些。它常见的用途不是“偷懒不给封装”,而是当基类希望给子类暴露一部分实现细节或扩展点,但又不希望这部分能力直接暴露给所有外部调用方。实际工程里如果一个成员只想让子类感知,protected 是合理的;但如果会破坏基类不变量,通常还是应该优先通过 protected 的辅助函数或者纯虚接口来暴露,而不是直接把数据成员裸露出来。

代码:

#include <iostream>
using namespace std;

class Base {
protected:
    int value = 42;
};

class Derived : public Base {
public:
    void print() { cout << value << endl; }
};

int main() {
    Derived d;
    d.print();
    return 0;
}

3. 函数传参和返回值一般走哪些寄存器,参数是怎么压栈的?

在 Linux x86-64 下,常见的 System V ABI 规定,整数或指针类型的前六个参数通常通过寄存器传递,分别是 rdirsirdxrcxr8r9,返回值一般走 rax。如果参数更多,超出的部分才会放到栈上。浮点参数则会优先走 xmm 系列寄存器。在 Windows x64 下,前四个整型或指针参数通常放在 rcxrdxr8r9。所以面试里如果被问到“哪个寄存器传参”,最好先说明你讨论的是哪种平台和 ABI。至于“如何压栈”,现代编译器不一定真的是传统意义上一条条 push,很多时候会在函数序言中一次性调整 rsp,然后把参数或临时变量放到预留好的栈帧位置。编译优化打开后,很多小函数甚至可能完全不建传统栈帧。

代码:

#include <iostream>
using namespace std;

long add(long a, long b, long c, long d, long e, long f, long g) {
    return a + b + c + d + e + f + g;
}

int main() {
    cout << add(1,2,3,4,5,6,7) << endl;
    return 0;
}

4. 讲一下进程地址空间

答案:进程地址空间是操作系统给每个进程提供的一套独立虚拟地址视图。程序看到的是一段看起来连续的虚拟地址,而不是直接操作物理内存。典型的进程地址空间里会包括代码段、只读常量区、全局/静态区、堆、共享库映射区、文件映射区、栈,以及内核为线程和运行时保留的一些特殊区域。不同平台和运行时布局细节不完全一样,但核心思想都是一致的。有了地址空间隔离,不同进程之间默认不能随便互相读写,这既提高了安全性,也降低了错误传播范围。与此同时,虚拟内存还支持按需分页、共享库映射、写时复制、内存映射文件等机制。所以“进程地址空间”不是简单的一块内存,而是操作系统、MMU、页表、权限位共同提供的一层抽象。

5. C++ 函数调用的几种方式有哪些

答案:如果从“调用形态”来看,常见有普通函数调用、成员函数调用、虚函数调用、函数指针调用、仿函数调用、lambda 调用。如果从更底层的“调用约定”来看,常见会提到 cdeclstdcallfastcallthiscall 等,不过在 64 位平台上很多历史差异被统一 ABI 吸收掉了。成员函数本质上会多一个隐式的 this 指针;虚函数调用会多一层经由虚表的间接跳转;函数对象和 lambda 通常会转化成对 operator() 的调用。所以这题如果面试官问得偏底层,你就往 ABI、寄存器、栈帧、this 指针说;如果问得偏语言特性,就往普通函数、成员函数、虚函数、可调用对象这几种形式说。

代码:

#include <iostream>
using namespace std;

void normalFunc() { cout << "normal\n"; }

class A {
public:
    void memberFunc() { cout << "member\n"; }
    virtual void virtualFunc() { cout << "virtual\n"; }
};

struct Functor {
    void operator()() { cout << "functor\n"; }
};

int main() {
    normalFunc();

    A a;
    a.memberFunc();
    a.v

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

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

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

全部评论

相关推荐

聚焦核心业务场景,利用Agent等前沿技术推动AI落地。你将参与从需求洞察到系统构建的全流程,通过研发智能应用与工具,提升业务效率与效果,实现技术驱动业务增长的完整闭环,推动智能规模化演进,实现技术价值转化。具体职责包括以下相关方向的一项或多项:1.需求理解与归因:●&nbsp;深入业务场景,利用数据挖掘与特征分析完成现象归因;精准识别高价值问题,将模糊的业务痛点转化为明确的&nbsp;AI&nbsp;解决目标。2.架构设计:●&nbsp;面向具体业务需求,设计&nbsp;AI&nbsp;原生系统架构;参与&nbsp;Agent&nbsp;系统核心模块的规划,包括记忆管理、推理策略与工具编排,兼顾架构的灵活性、可扩展性与工程可落地性。3.知识与环境构建:●&nbsp;搭建AI与现有业务系统的交互环境,涵盖&nbsp;API&nbsp;接入、RAG&nbsp;知识库构建、记忆方案设计;持续优化召回质量与上下文注入策略,为模型提供准确、及时的执行环境与知识支撑。4.核心能力实现:●&nbsp;负责Agent关键模块的工程落地,实现意图识别、任务拆解与反思纠错闭环;封装标准化SDK/API服务,构建Agent观测体系,实现全链路追踪与多维归因分析。5.系统迭代与演进:●&nbsp;建立搭建自动化评测与回测机制,通过调优与Case分析不断收敛效果与性能提升的最优路径;沉淀方法论与可复用组件,推动&nbsp;AI&nbsp;能力从单点验证走向规模化落地。6.性能优化:●&nbsp;优化高并发场景下的系统性能,通过异步处理与降级策略保障稳定性,通过低侵入性观测手段保障系统的长期稳定运行。1.基础条件●&nbsp;计算机、软件工程、人工智能等相关专业优先。2.专业能力●&nbsp;AI编程工具重度玩家:Cursor、Claude&nbsp;code等AI编程工具重度或顶级玩家,具备极强的Prompt编写与调优能力,有过完整的项目级开发经验,理解如何让AI写出生产级代码。●&nbsp;大模型能力理解与掌握:理解主流LLM的能力与局限,能够清晰拆解任务并通过LLM或确定性逻辑兜底实现;熟悉主流大模型的应用范式(Context&nbsp;Engineering、Prompt&nbsp;Engineering、Agent、工具/函数调用等等)及主流Agent框架(如LangChain等),具备大模型幻觉、Prompt注入等风险的工程化应对思路。●&nbsp;扎实的代码和工程能力:具备扎实的计算机基础知识,深入理解数据结构、算法、网络和操作系统等相关知识,能至少在一种主流编程语言(如&nbsp;Java&nbsp;/&nbsp;Python&nbsp;/&nbsp;JS&nbsp;等)上有深度的实践经验,掌握常见工程实践并具备优秀的Coding&nbsp;能力,能够根据场景灵活选型并快速上手。3.能力特质●&nbsp;学习能力:&nbsp;具备快速啃透前沿论文(Paper)的能力,并能将理论知识转化为工程代码。●&nbsp;开放性与动手能力:&nbsp;拒绝纸上谈兵,有自己独立完成的小项目(开源项目或个人&nbsp;Demo),展现极客精神。●&nbsp;好奇心与想象力:&nbsp;面对未知事物有独特的想法,具备敏锐的问题定义能力和坚韧的解决问题能力。●&nbsp;审美追求:&nbsp;技术亦有审美,鼓励你提出能提出打动人心、简洁优雅的好想法。●&nbsp;高能动性:&nbsp;具备强烈的自驱力,能够主动探索边界,而不是等待被分配任务。加分项●&nbsp;有AI应用或Agent实际落地经验:包括不限于RAG系统、多智能体编排、结合MCP、Skill等的Agent项目,有可展示的项目/实习成果者优先。●&nbsp;开源贡献或技术影响力:在Github上有高质量AI项目、技术博客或社区影响力。●&nbsp;对AI&nbsp;Infra有基本理解:了解vLLM、Ollama等推理框架原理,理解延迟优化、KV&nbsp;cache优化、流式输出等工程全局视角。●&nbsp;在&nbsp;CV(计算机视觉)或&nbsp;NLP(自然语言处理)方向有扎实的理论基础,有实际业务场景模型训练(SFT、RL)等经验的优先。
点赞 评论 收藏
分享
评论
点赞
4
分享

创作者周榜

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