C++算法的40个高频面试问题集锦

FAQ CPP

根据笔记整理,偏基础概念,
配合右下角大纲视图食用更佳,
具体关键词自行搜索资料展开。
注:没有逻辑顺序,仅供参考。

i++和++i有什么区别

都是自增运算,区别:

  • i++返回原始值:背后用到const返回old_value
  • ++i返回自增值:背后引用传值直接修改实参

vector添加元素的方法

两种:

  • emplace_back: 直接创建,高效率,C++11新特性
  • push_back: 先创建再拷贝/移动,效率低但向前兼容

二叉树翻转

要点:使用recursive遍历所有节点

struct Node
{
    char *name;
    Node *left;
    Node *right;
}

Node Invert(Node &tree)
{
    // set end condition
    if(NULL==tree) return NULL;
    tree->left = Invert(tree->left);
    tree->right = Invert(tree->right);
    // do swap
    Node *tmp = tree->left;
    tree->left = tree->right;
    tree->right = tmp;
    return tree;
}

文件流相关

fstream包含读ifstream和写ofstream

常指针区分

const *:const修饰被指变量,指向常量的指针
* const:const修饰指针本身,指向固定的地址

静态成员函数

static成员函数不属于任何对象或实例,因此声明virtual也没有意义。

说说STL容器

主要有vector, queue, stack, priority_queue, deque(双端), string, set, multiset(允许重复), bitset, map(与pair的区别在于唯一映射)

简述C++从文本到程序的过程

预编译 -> 编译 -> 汇编 -> 链接

2.0新特性

auto, unllptr, shared_ptr, {1,2,3}init, &&A, atomic, array(STL), tuple(STL)

array和vector区别

array需要指定长度而vector不用(动态扩展)

class和struct成员区别

class默认private而struct默认public

atomic作用

atomic 原子类,用于不同线程之间同步内存访问,如std::atomic<bool> std::atomic<char>

static作用

  • 保持函数局部变量值,下次调用仍继承上次值
  • 限制全局变量作用域在声明文件内,静态函数只能在声明文件可见
  • 类静态成员函数仅生成一个副本且所有对象共享,类的静态函数不接受this指针

const作用

  1. 修饰变量,只读
  2. 修饰指针,左右含义不同
  3. 常量引用,高效安全
  4. 类成员函数

常量定义

通过const定于的常量必须初始化,保存位置
局部:stack,全局:memory(符号表)

变量长度

sizeof是运算符,strlen是函数

引用与指针

引用的本质实现为指针(语法糖),区别在于:

  1. 不存在空引用,但存在空指针
  2. 不可修改引用在初始化后
  3. 引用必须创建时初始化
  4. 指针可以多级,引用只有一级

智能指针

  • shared_ptr:允许多个指针指向同一对象,指针增加对象引用计数,引用数归零的对象自动析构;
  • unique_ptr:独占所指对象,销毁指针时对象随之销毁,与早期auto_ptr类似;
  • weak_ptr:弱引用,不控制所指对象生命周期,不增加引用计数。

内联函数

为解决效率问题,编译直接展开而非调用,因此不能太复杂
成员函数类中定义默认内联,类外定义默认普通。

重载

同一作用域中声明功能类似的同名函数,形参(类型、数量、顺序)不同

模板

泛型编程概念,包含函数模板和类模板

处理返回值

函数return前生成一个临时变量存入内存,调用程序访问地址,获取返回值

虚函数与内联

虚函数可以是内联函数,但虚函数表现出多态时不能内联

构造/析构函数重载

ctor(构造函数)可以重载(多个,是否带参数)
dtor(析构函数)不能重载(唯一,不接受参数)

派生类与基类

派生类中定义基类同名函数,基类非虚,此时基类函数被隐藏。

类访问修饰符

protected与private区别在于子类可否访问
copy ctor, move ctor, friend func(可访问任何成员,包括private)

有关this指针

类的成员函数均隐式传入this指针,friend和static无,且friend不是类的成员

类的虚析构函数

只有当一个类作为基类被继承时才能为其设计虚析构函数,原因:

  1. 基类指针指向new子类,释放基类指针可以释放子类空间,防止内存泄漏;
  2. 默认dtor非虚,因为虚函数需要占用额外虚函数表与虚表指针,开销内存。

static与virtual函数

  • static编译时已经确定运行时机,virtual运行时动态绑定;
  • virtual使用vtable机制,调用将增加内存开销。

面向对象OOP特征

封装、继承、多态

特殊的堆栈类

heap only:dtor设为private
stack only: new/delete operator设为private

空类内容

空类包含ctor, copy ctor, dtor, operator=, operator&, const operator&

类的大小

sizeof class 空类返回1;普通成员函数不参与sizeof统计;虚函数+4bytes
static成员不影响类大小,编译器放在程序数据段中;普通继承sizeof相加

动态内存

C++: new/delete 自动申请大小,不释放会泄露
C: malloc/free 需要指定大小,不会调用ctor和dtor

堆栈区别

内存 申请分配 效率 扩展方向 举例
stack 自动 高->低 局部变量,形参,返回值
heap 手动 低->高 new/malloc动态申请

STL构成

Standard Template Library
常见:容器、算法、迭代器
罕见:迭代适配器、空间配置器、仿函数

vector和list异同

  1. vector底层是array(随机读取快),list底层是双向链表(增删快);
  2. vector插入节点导致内存拷贝而list不会;
  3. vector分配好内存不够双倍扩展,list每次插入都申请内存。

const成员函数

const在前表示返回值为const类型
const在后表示函数是const不能修改成员变量

内存分类

堆区、栈区、全局(静态)区、文字常量区、程序代码区。
例如,函数内声明一个char*字符串,首指针位于栈区,所指字符串内容位于文字常量区

原文地址:https://www.cnblogs.com/azureology/p/14234682.html