春招秋招+后端开发+面经知识点大全系列1:语言(C/C++)

2 篇文章 0 订阅
2 篇文章 0 订阅

前言

经历了几个月的折腾,面了大大小小快20家厂子。把经历的知识点做个汇总。从语言,操作系统, 网络等几个方面分别总结记录一下。如果你正在准备后端方向的秋招春招实习, 可以拿这个系列作为一个参考,了解一些基本知识。
准备知识的时候,一定以理解为主。
水平有限,如果有错漏之处,欢迎留言评论指出,感激不尽!

C和C++的区别

  1. 思想上,C是面向过程的结构化编程语言,C++是面向对象的(核心三要素:封装,继承,多态),当然C++具体到底层实现的内部,仍然是通过一个个过程实现的高层的抽象功能;
  2. 具体操作上,C++使用new/delete进行内存的申请释放,C则是malloc/free。C++支持函数重载,范式编程,模板类扥操作。
  3. C++ 11 中的新特性还包括:智能指针(unique_ptr,shared_ptr,weak_ptr), move语义,forward完美转发,右值引用,auto关键字等

堆和栈的区别(内存分配方面)

  1. 堆区,分配程序申请的内存空间,需要释放,地址向上增长,比栈慢,灵活,空间大,存在内存碎片化问题。
  2. 栈区,编译器自动分配释放,存放函数参数,局部变量等,地址向下增长,后进先出,空间连续,速度快,但是程序无法控制,空间有限。
  3. 全局区(静态区),存放全局变量,静态变量等,初始化与未初始化部分分开存放
  4. 文字常量区,存放常量字符串等
  5. 程序代码区,存放函数体的二进制代码

C++文件编译执行的步骤(4个)

在linux环境下,C++编译执行的步骤分为如下四步:

  1. 预处理,主要是各种条件编译,宏定义替换,头文件包含的处理,后缀为.i
  2. 编译,将代码转换成汇编语言,包括词法分析,语法分析,语义分析,代码优化(o2,o3等优化级别)等具体处理。后缀为.s
  3. 汇编,生成目标代码(机器代码),后缀为.o
  4. 链接,将目标代码链接所需的库,生成可执行文件

static关键字的作用

  1. 修饰函数内变量,则该静态变量内存只分配一次,下次进入函数时不会重新初始化,保留上次结果
  2. 修饰模块内(可简单理解为,修饰一个cpp文件内的)全局变量,则该全局变量只能在模块内全局,修饰模块内函数,则该函数只能模块内调用。无法extern
  3. 修饰类内的成员变量,则该静态成员变量对于类的所有对象只有一份拷贝。修饰类内的成员函数,该函数不接受this指针,只能访问静态成员变量。

volatie关键字的作用

由于访问寄存器速度更快,编译器可能会对此进行优化,导致脏数据的产生,在多线程时问题更明显,volatie可以使得每次修改都落实,每次都从内存中取数据,让编译器不对被修饰的变量进行优化。

define const的区别

  1. define,没有类型,立即数,预处理中转换,不可被指针指,可以为函数。修饰函数内变量,则该静态变量内存只分配一次,下次进入函数时不会重新初始化,保留上次结果
  2. const,有类型,存在内存的静态区,编译中处理,可以指,不可以为函数。

new/delete,malloc/free的区别

malloc从堆里获得空间,堆是通过内存块的管理来实现的,因此:
程序申请内存+管理内存=实际使用内存
申请新的空间时,系统判断有无合适的内存块,有则分配,无则新申请。管理内存中包括该内存块大小,是否可用等信息,因此free的时候不需要知道大小。
区别主要在于:

  1. malloc/free只负责动态分配/释放空间,而new/delete还包括对对象的构造(析构),初始化等操作
  2. malloc/free是标准库函数,申请内存时需要设置大小,new/delete是操作符,且new的时候不需要指定大小(当然内部最底层的实现其实也是调用了malloc)
  3. malloc返回的是void*指针或者null,new返回的是类型对应指针/异常

多态与虚函数

多态

  1. 静态多态,又可以称为编译多态,在编译时即可确认,主要包括函数重载,范型编程,模板类等
  2. 动态多态,又可以称为运行时多态,在运行时才可以确认,主要是虚函数的使用。

虚函数

  1. virtual 关键字修饰类的成员函数, 其中virtual void f()=0; 为纯虚函数,抽象类,无法实例化
  2. 对于每个包含虚函数的类,维护一个唯一的虚函数表来控制运行时调用的函数。维护虚函数表需要额外开销,因此并不应该将每个函数设置为虚函数,而且虚函数主要是针对希望被继承时改写的函数。
  3. 非成员函数,内联函数,静态成员函数,拷贝构造,构造函数,友元函数不能设置为虚函数,析构函数可以设置为虚函数(若为基类,应设为虚函数)

类的继承

继承时,父类的内存在前,子类在后。先构造父类再构造子类。先析构子类再析构父类。
父类指针可以指向子类对象,反过来时可能因为缺少相应方法引起异常。
若希望类被继承,则应在析构函数前加virtual
public 继承: public protected的成员保持不变,private成员子类无法访问
protected继承:public protected成员转变为protected,private成员子类无法访问
private继承:public protected成员转变为private,private成员子类无法访问

指针/引用

  1. 指针* ,指向对象地址,本身也是对象(根据寻址范围确定4字节,还是8字节)
  2. 引用&,对象别名,必须初始化一个已有对象,且总为最初绑定对象。也需要占用空间,本质上底层也是通过指针实现,只不过隐藏了

智能指针

主要是防止忘记delete,多次释放等操作带来的内存不安全。

  1. unique_ptr,所有权归一个指针所有,只能通过move操作移动,无法=拷贝赋值
  2. shared_ptr,允许多指一,通过统计引用次数判断是否释放资源,存在循环引用等问题
  3. weak_ptr,辅助shared_ptr,不参与计数,无法访问资源,但是可以用做监控

STL标准模板库

从广义上分为容器,算法,迭代器

  1. 容器:各种数据结构,序列式容器:vector 顺序表(数组),list 双向链表,deque 循环队列等。关联式容器:set,map 红黑,unordered_set, unordered_map hash表
  2. 算法:各种常用算法,sort,find,copy等函数模板
  3. 迭代器:容器与算法间的胶合剂,提供一种访问容器内元素的方式,而无需暴露其内部结构,是STL的关键所在。

STL优点:C++内置,高可重用,高性能,可移植,跨平台。将数据与操作分离,数据由容器管理,操作可以由定制的算法定义。

算法:各种常用算法,sort,find,copy等函数模板
3. 迭代器:容器与算法间的胶合剂
常见操作
.begin() .end() .rbegin() .rend() .assign() .size() .capacity() .empty() .resize() .reserve() .push_back() .pop_back() .insert() .pop() .push() .top() .front() .back() .erase() .clear() .swap()

容器适配器
stack< T > 栈
queue< T > 队列
priority_queue< T > 优先队列(堆)

左值与右值

左值 :非临时性的对象,持久存在,可寻址,左值引用&
右值 :临时性的对象,语句结束后销毁,通常不可寻址,右值引用&&
常见注意事项

  1. 一个声明的右值引用其实是左值,因为定义了变量名。
  2. 函数中传递参数时,传的右值引用,但参数本身是一个引用,也是左值,因此不会调用函数的右值版本,而是调用左值版本,引起不必要的拷贝。解决方法:forward完美转发,move等
  3. forward完美转发,按照原来的类型转发,move以右值引用的形式
  4. template函数参数推导,形参为T&时,实参无论是左引用还是右引用,均推导为T&。形参为T&&时,推导类型与实参一致,T&->T&,T&&->T&&

//-----后续待补充

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值