整理的C/C++相关的面经知识点

【CSP-J/S初赛知识点整理】 CSP-J/S初赛知识点整理 阅读详情

自己在找工作的过程中,参考了一些博客并自己整理的有关C/C++面经知识点。

C语言中 new和malloc的区别

  • **申请内存所在位置:**new/delete是操作符,malloc/free是函数;new操作符从自由存储区(free store)上位对象动态分配内存空间,而malloc函数从从堆上动态分配内存。而且new在申请对象时会调用对象的构造函数和析构函数
    **自由存储区是C++基于new操作符的一个抽象概念,凡是通过new操作符进行内存申请该内存
  • **返回类型安全性:*new操作符内存分配成功时,返回的是对象类型的指针。类型严格与对象匹配,无须进行类型转换,而malloc内存分配成功则是返回void,需要通过强制类型转换转换成我们需要的类型。
  • **内存分配失败时的返回值:**new内存分配失败时,会抛出bad_alloc异常,不会返回NULL;malloc内存分配失败时返回NULL。
  • 使用new操作符申请内存时无需指定内存大小,编译器会根据类型信息自动进行计算;而malloc需要显式的指定所需内存的大小
C++中有了maoolc/free, 为什么还需要new/delete?

malloc与free是c++/C语言的标准库函数,new/delete是C++的运算符,他们都可以用于申请动态内存和释放内存
对于非内部数据类型的对象而言,只用malloc/delete无法满足动态对象的要求。对象在创建的同时要自动执行构造函数,对象在消亡之前要自动执行析构函数。由于malloc/free是库函数而不是运算符,不在编译器控制权限范围内,不能够把执行构造函数和析构函数的任务强加于malloc/delete。
因此C++语言需要一个能完成动态内存分配和初始化工作的运算符new,以及一个能完成清理与释放内存工作的运算符delete。

malloc内存分配机制是,在哪里分配内存,最大可以申请多大的内存

  • 它是将可用的内存块连接为一个长长的列表,即所谓的空闲链表,调用malloc函数时,它沿连接表寻找一个大到足以满足用户请求所需要的内存块,将该内存块一分为二(一块大小与用户请求的大小相等,另一块大小就是剩下的字节)
    调用free函数时,它将用户释放的内存块连接到空闲链上,到最后,空闲链会被切成很多的小内存片段,如果这时用户申请一个大的内存片段,那么空闲链上可能没有可以满足用户要求的片段了,于是,malloc函数请求延时,并开始在空闲链上检查各内存片段,并进行整理,将相邻的小空闲块合并成较大的内存块。
  • malloc函数是在堆上面分配内存
  • Linux下虚拟地址空间分配给进程的是3GB,Windows下默认的是2GB,真正能够使用多少内存跟你的机器和编译器决定了,
    在Linux系统能申请到的内存地址空间在2.8GB左右,而在windows下面(32位)得到的地址空间在1.2GB左右

malloc(0)的返回值问题

  1. malloc(0)在我的系统里是可以正常返回一个非NULL值的。返回了一个正常的地址。

  2. malloc(0)申请的空间到底有多大不是用strlen或者sizeof来看的,而是通过malloc_usable_size这个函数来看的。—当然这个函数并不能完全正确的反映出申请内存的范围。strlen和sizeof都是计算为0

  3. malloc(0)申请的空间长度不是0,在我的系统里它是12,也就是你使用malloc申请内存空间的话,正常情况下系统会返回给你一个至少12B的空间。这个可以从malloc(0)和malloc(5)的返回值都是12,而malloc(20)的返回值是20得到。—其实,如果你真的调用了这个程序的话,会发现,这个12确实是”至少12“的。

  4. malloc(0)申请的空间是可以被使用的。

C语言程序中为什么要从main函数开始

main只是开发工具所规定的一个特殊函数名称而已,它既不是程序的入口,也不是必须要有的函数
如:

  • 一.在Linux C中,使用attribute关键字,声明constructor和destructor,可以自定义程序入口点,不一定是在main函数开始执行
  • 二.在标准C中,编译器在编译的时候把你的程序开始执行的地址设为main函数的地址,汇编中可以自由通过end伪指令制定
    在VS中给你可以通过这么设置:
    项目->属性->配置属性->链接器->高级->入口点,改为你想入口点的函数名
  • 三.在单片机C中,在C语言运行前都有汇编程序编写的启动程序,里面对单片机进行的初始化,同时设置了C程序的入口main函数

new运算符的原理(底层使用了operator new(),最终调用了malloc),new运算符重载,怎么写重载函数,重载的定义

//++++++++++++++++++++++++++++++++++++++++++++//
首先区分new operator和operator new这两个概念,前者new operator就是new操作符,一般,在new一个对象的时候,底层做了如下两步:

  1. 为对象分配内存

  2. 调用构造函数初始化这块内存
    在第一步中分配内存时就使用了operator new,其实现机制

    void *operator new(std::size_t size) throw(std::bac_alloc)
    {
    if(size==0)
    size=1;
    void *p;
    while((p=::malloc(size))==0)
    {
    std::new_handler nh=std::get_new_handler();
    if(nh)
    nh();
    else
    throw std::bad_alloc();
    }
    return p;
    }
    void operator delete(void *ptr)
    {
    if(ptr)
    ::free(ptr);
    }
    在第二步中,调用构造函数初始化内存,如果不涉及继承,这一步非常简单,就是给内存赋值,重点是operator new分配内存上,其处理流程如下:

  3. 分配内存如果成功则直接返回,否则;

  4. 查看new_handler是否可用,new handler的作用用于再释放一部分内存

  5. 如果可用则调用之并跳转到1,否则;

  6. 抛出bad_alloc异常
    //++++++++++++++++++++++++++++++++++++++//

new,delete在C++中被归为运算符,所以可以重载他们
new的行为:

  • 先开辟内存空间

  • 再调用类的构造函数
    在开辟内存空间的部分,可以被重载
    delete的行为:

  • 先调用类的析构函数

  • 再释放内存空间
    释放内存空间的部分,可以被重载
    为什么要重载?
    有时候需要实现内存池的时候需要重载它们,频繁的new和delete对象,会造成内存碎片,内存不足等问题,调用构造函数placement new。

memset函数的作用,有哪些参数

函数原型:

extern void *memset(void *buffer, int c, int count)

说明:把buffer所指内存区域的前count个字节设置成字符c,返回指向buffer的指针

void *memset(void *dest, int val, size_t count)
{
	if(dest == NULL || count < 0)
		return NULL;
	char *pdest = (char *)dest;
	while(count-- > 0)
	{
		*pdest++ = val;
	}
	return dest;
}

linux系统应用程序的内存空间分配(内核空间和进程空间),一般进程空间多大,内核空间多大,进程空间分布是什么样的,堆区最大空间是多少

  • 在Linux系统中内核空间为1GB(0xC0000000到0xFFFFFFFF),用户进程空间为3GB(0x00000000到0xBFFFFFFF)
  • 在Windows系统中默认的内存分配是内核空间2GB,用户进程空间为2GB
    进程空间分布:
  • stack(栈):存储局部,临时变量,在函数调用时,存储函数的返回指针,用于控制函数的调用和返回,在程序开始时自动分配内存,结束时自动释放内存,(Linux系统通常在8MB左右)
  • Heap(堆):存储动态内存分配,需要程序员手工分配,手工释放
  • uninitialized data(BSS):在程序运行初未对变量进行初始化的数据
  • initialized data(Data):在程序运行初已经对变量进行初始化的数据
  • Text(程序段):程序代码在内存中的映射,存放函数体的二进制代码
    堆区的大小受限于计算机系统中有效的虚拟内存

C++中的模板机制了,原理,类模板和函数模板在定义时的区别

函数模板机制结论:

  • 编译器并不是把函数模板处理成能够处理任意类的函数
  • 编译器从函数模板通过具体类型产生不同的函数
  • 编译器会对函数模板进行两次编译
  • 在声明的地方对模板代码本身进行编译;在调用的地方的地方对参数替换后的代码进行编译

模板就是泛型编程的基础,泛型编程即以一种独立于任何特定类型的方式编写代码,可以实现算法与数据结构的分离。
函数重载不是一种面向对象的编程,而只是一种语法规则,重载跟多态没有什么直接关系

二叉树的原理,平衡二叉树的原理,二叉树的遍历方式,二叉树的最大节点数,二叉树插入删除的时间复杂度,二叉树插入的时间复杂度与树的节点数和树深度的关系,二叉树的优点

数组和链表的区别,它们的应用场景

  • 链表是链式的存储结构,数组是顺序的存储结构,在内存中,数组是一块连续的区域
  • 链表的插入与删除元素相对数组较为简单,不需要移动元素,但查找某个元素较为复杂
  • 链表查找某个元素较为简单,但插入与删除元素较为复杂,且最大长度在编程一开始时就指定,扩充长度不如链表方便
  • 数组在内存中连续,在栈区,链表在内存中不连续,一般在堆区

**应用场景:**需要快速访问数据,很少或不插入或者删除元素,用数组
需要经常插入或者删除元素用链表数组结构

C++继承机制,虚继承原理

继承是使代码可以复用的重要手段,也是面向对象程序设计的核心思想之一。简单地说,继承是指一个对象直接使用另一个对象的属性和方法。继承呈现了面向对象程序设计的层次结构,原始类称为基类,继承类称为派生类,也分别叫做父类和子类,子类也可以为父类,被另外的类继承。继承的方式有三种分别为公有继承(public)、保护继承(protect)、私有继承(private)

  • **公有继承:**基类的公有成员和保护成员作为派生类的成员时,它们都保持原有的状态,而基类的私有成员对派生类是不可见的,也不能被这个派生类的子类所访问
  • **私有继承:**基类的公有成员和保护成员作为派生类的私有成员,并且不能被这个派生类的子类所访问
  • **保护继承:**基类的所有公有成员和保护成员都成为派生类的保护成员,并且只能被它的派生类成员函数或友元访问,基类的私有成员仍然私有,且对派生类不可见
    public继承是一个接口继承,保持is-a原则,每个父类可用的成员对子类也可用,因为每个子类对象也都是一个父类对象

private/protected继承是一个实现继承,基类的部分成员并非完全成为子类接口的一部分,是has-a的关系原则
一个类有多个基类,这样的继承关系称为多继承

=====class 派生名:访问控制符 基类名1,访问控制符 基类名2

虚继承的作用是减少了对基类的重复,代价是增加了虚表指针的负担(更多的虚表指针)

虚继承:

虚拟继承是多重继承中特有的概念。虚拟基类是为解决多重继承(菱形继承)而出现的。如:类D继承自类B1、B2,而类B1、B2都继承自类A,因此在类D中两次出现类A中的变量和函数。为了节省内存空间,可以将B1、B2对A的继承定义为虚拟继承,而A就成了虚拟基类。实现的代码如下:

class A

class B1:public virtual A;

class B2:public virtual A;

class D:public B1,public B2;

虚拟继承在一般的应用中很少用到,所以也往往被忽视,这也主要是因为在C++中,多重继承是不推荐的,也并不常用,而一旦离开了多重继承,虚拟继承就完全失去了存在的必要因为这样只会降低效率和占用更多的空间。

虚函数机制,一个类有虚函数,有成员变量,求所占的内存大小

**虚函数:**虚函数的调用是通过虚函数表指针和虚函数表来实现的

  • 虚函数表和类绑定,只此一份。虚函数表指针每个类对象都有,指针值都是同一个虚函数表的地址
  • 虚函数指针vfptr不属于数据成员,vfptr的值是在构造函数内容执行之前进行初始化的,构造函数是根据本类的类型进行初始化的。所以拷贝构造函数,或者赋值函数都不会影响到vfptr的值
  • 对虚函数的调用,都是通过实体的vfptr所指的虚函数表来进行调用的
    内存排布:子类继承父类的成员变量,内存上会先排布父类的成员变量,接着排布子类的成员变量,其中成员函数不占字节
  • 每个类都有虚指针和虚表
  • 如果不是虚继承,那么子类将父类的虚指针继承下来,并指向自身的虚表(发生在对象构造时),有多少个函数,虚表里面的项就会有多少,多重继承时,可能存在多个的基类虚表和虚指针
  • 如果是虚继承,那么子类会有两份虚指针,一份指向自己的虚表,另一份指向虚基表,多重继承时虚基表与虚基表指针有且只有一份

总结如下:

  • **无虚函数覆盖的继承:**虚函数按照其声明顺序放在虚函数表中,父类的虚函数在其子类的虚函数的前面
  • **有虚函数覆盖的继承:**派生类中起覆盖作用的虚函数放在原基类虚函数的位置,没有被覆盖的虚函数依旧
  • **无虚函数覆盖的多重继承:**每个父类都有自己的虚函数表,派生类的虚函数被放在了第一个父类的虚函数表中(按照声明顺序排序)
  • **有虚函数覆盖的多重继承:**派生类中起覆盖作用的虚函数放在原基类虚函数的位置,没有被覆盖的虚函数依旧
  • **无虚函数覆盖的虚继承:**派生类有单独的虚函数表,另外也单独保存一份父类的虚函数表
  • **有虚函数覆盖的虚继承:**派生类单独的虚函数表,另外也单独保存一份父类的虚函数表,派生类中起覆盖作用的虚函数放在原基类虚函数的位置,没有被覆盖的虚函数依旧

C++中的多态

多态主要是有静态多态和动态多态

  • **静态多态:**主要是函数重载和泛型编程
  • **动态多态:**虚函数

静态多态:也称为静态绑定或早绑,编译器在编译期间完成的,编译器根据函数实参的类型(可能会进行隐式类型转换),可推断出要调用的那个函数,如果有对应的函数就调用该函数,否则出现编译错误。

动态多态:在程序执行期间判断所引用对象的实际类型,根据实际类型调用相应的方法,使用virtual关键字修饰类的成员函数时,指明该函数为虚函数,派生类需要重新实现,编译器实现动态绑定

总结:

  • 1.在编译过程中的联编的被称为静态联编(static binding)
  • 2.在运行时选择正确的虚方法,被称为动态联编
  • 3.编译器对非虚方法使用静态联编,编译器对虚方法使用动态联编

说说引用,什么时候用引用好,什么时候用指针好?

指针和引用的区别:

  • 非空区别:指针可以为空,而引用不能为空
  • 可修改区别:如果指针不是常指针,那么就可以修改指向,而引用不能
  • 初始化区别:指针在定义时可以不用初始化,而引用在定义的同时必须初始化
  • 从内存上来讲,系统为指针分配内存空间,而引用与绑定的对象共享内存空间,系统不为引用变量分配内存空间

使用引用参数的主要原因有两个:
•程序员能修改调用函数中的数据对象
•通过传递引用而不是整个数据–对象,可以提高程序的运行速度

一般的原则:
对于使用引用的值而不做修改的函数:
•如果数据对象很小,如内置数据类型或者小型结构,则按照值传递
•如果数据对象是数组,则使用指针(唯一的选择),并且指针声明为指向const的指针
•如果数据对象是较大的结构,则使用const指针或者引用,已提高程序的效率。这样可以节省结构所需的时间和空间
•如果数据对象是类对象,则使用const引用(传递类对象参数的标准方式是按照引用传递)

对于修改函数中数据的函数:
•如果数据是内置数据类型,则使用指针
•如果数据对象是数组,则只能使用指针
•如果数据对象是结构,则使用引用或者指针
•如果数据是类对象,则使用引用

关键字const是什么含义

const是C++中常用的类型修饰符,常类型使指使用类型修饰符const说明的类型,意味着“只读”

const的作用:
  • **可以定义const常量:**如const int max = 100;

  • **便于进行类型检查:**const常量有数据类型,而#define宏常量没有数据类型,编译器可以对前者进行类型安全检查,而对后者只进行字符替换,没有类型安全检查,并且在字符替换时可能产生意想不到的错误

  • **可以保护被修饰的东西:**防止意外的修改,增强程序的健壮性

  • 为函数重载提供了一个参考:

  • **可以节省空间,避免不必要的内存分配:**const定义常量从汇编的角度来看,只是给出了对应的内存地址,而不是像#define一样给出的是立即数,所以,const定义的常量在程序运行过程中只有一份拷贝,而#define定义的常量在内存中有若干个拷贝

    #define PI 3.14159 //常量宏
    const double Pi = 3.14159 //此时并未将Pi放入ROM中
    double i=Pi; //此时为Pi分配内存,以后不在分配
    double I=PI; //编译期间进行宏替换,分配内存
    double j=Pi; //没有内存分配
    double J=PI; //再进行宏替换,有一次分配内存

**提高了效率:**编译器通常不为普通const常量分配存储空间,而是将它们保存在符号表中,这使得它成为一个编译期间的常量,没有了存储与读内存的操作,使得它的效率很高

const的使用
const int a;  
int const a;   //前两个作用一样,a是一个常整型数
const int *a;  //a是一个指向常整型数的指针(整型数是不可修改的,指针是可以修改的)---底层const
int *const a;  //a是一个指向整型数的常指针(指针指向的整型数是可以修改的,但指针是不可修改的)---顶层const
int const *a const;   //a是一个指向常整型的常指针(指针指向的整型数是不可以修改的,同时指针也是不可以修改的)

即指针使用const有:

  • 指针本身是常量不可变: char * const pContent;
  • **指针所指向的内容是常量不可变:**const char *pContent;
  • 两者都不可变: const char * const pContent;

**区别方法:**沿着*号划一条线:

  • **底层const:**如果const位于*的左侧,则const就是用来修饰指针所指向的变量,即指针指向为常量;常量指针:指向的对象是个常量,不能修改其内容,只能更改指针指向的地址
  • **顶层const:**如果const位于*的右侧,const就是修饰指针本身,即指针本身是常量,指针常量,不能修改指针指向的地址,只能修改其内容

函数中使用const

(1) const修饰函数参数

a.传递过来的参数在函数内不可以改变(无意义,因为Var本身就是形参)

void function(const int Var);

b.参数指针所指向内容为常量不可变

void function(const char *Var);

c.参数指针本身为常量不可变(无意义,因为char *Var也是形参)

void function(char *const Var);

d.参数为引用,为了增加效率同时防止修改,修饰引用参数时:

void function(const Class& Var);  //引用参数在函数内不可以改变
void function(const TYPE& Var);   //引用参数在函数内为常量不可变

实现库函数strcpy的功能,不能使用任何库函数:

char *strcpy(char *strDest, const char *strSrc)
{
	if(strDest == NULL || strSrc == NULL)
		return NULL;
	if(strDest == strSrc)
		return strDest;
	char *temptr = strDest;
	while((*temptr++ = *strSrc++) != '\0');
	return temptr;
}

实现库函数strcmp函数的功能

int strcmp(const char *strDest, const char *strSrc)
{
	assert(strDest != NULL && strSrc != NULL);
	while(*strDest && *strSrc && *strDest == *strSrc)
	{
		strDest++;
		strSrc++;
	}
	return *strDest - *strSrc;
}

C语言中static有什么作用

  • 函数体内static变量的作用范围为该函数体,该变量的内存只被分配一次,因此其值在下次调用时仍维持上次的值
  • 模块体内static全局变量可以被模块体内所有函数访问,但不能被模块外其他函数访问
  • 模块体内static函数只可被这一模块内的其他函数调用,这个函数的使用范围被限制在声明它的模块内
  • 类中的static成员变量属于这个类所有,对类的所有对象只有一份拷贝
  • 类中的static成员函数属于整个类所有,这个函数不接收this指针,因而只能访问类的static成员变量。

C++中的struct和class的全部区别

  • C++中的struct具有了"类"的功能,与关键字class的区别在于struct中的成员变量和函数的默认访问权限为public,而class的为private
  • struct可以在定义的时候直接以{}对其成员变量赋初值,而class不能

C++内存管理

在C++中,内存分成5个区,他们分别是堆、栈、自由存储区、全局/静态存储区和常量存储区。

  • 栈,在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。
  • 堆,就是那些由new分配的内存块,他们的释放编译器不去管,由我们的应用程序去控制,一般一个new就要对应一个delete。如果程序员没有释放掉,那么在程序结束后,操作系统会自动回收。
  • 自由存储区,就是那些由malloc等分配的内存块,他和堆是十分相似的,不过它是用free来结束自己的生命的。
  • 全局/静态存储区,全局变量和静态变量被分配到同一块内存中,在以前的C语言中,全局变量又分为初始化的和未初始化的,在C++里面没有这个区分了,他们共同占用同一块内存区。
  • 常量存储区,这是一块比较特殊的存储区,他们里面存放的是常量,不允许修改。

C编译的程序占用存储

  • **栈区(stack):**由编译器自动分配释放,存放函数的参数值,局部变量值等
  • **堆区(heap):**一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收
  • **全局/静态存储区(static):**全局变量和静态变量的存储是放在一起的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和静态变量在相邻的另一块区域,程序结束后有系统释放
  • **文字常量区:**常量字符串存放在这里
  • **程序代码区:**存放函数体的二进制代码

内存泄漏的情况

  • 缓冲区溢出
  • new/delete函数没有匹配
  • 浅拷贝
  • 野指针/空悬指针
  • 重复释放
  • 内存碎片

C++中成员变量的列表初始化

class A
{
private:
    int n1;
    int n2;

public:
    A():n2(0),n1(n2+2){}

    void Print(){
        cout << "n1:" << n1 << ", n2: " << n2 <<endl;  
    }
};

int main()
{

    A a;
    a.Print();

    return 0;
}

输出结果为n1:随机, n2:0

  • 成员变量在使用初始化列表初始化时,与构造函数中初始化成员列表的顺序无关,只与定义成员变量的顺序有关。因为成员变量的初始化次序是根据变量在内存中次序有关,而内存中的排列顺序早在编译期就根据变量的定义次序决定了。
  • 如果不使用初始化列表初始化,在构造函数内初始化时,此时与成员变量在构造函数中的位置有关。
  • 注意:类成员在定义时,是不能初始化的
  • 注意:类中const成员常量必须在构造函数初始化列表中初始化。
  • 注意:类中static成员变量,必须在类外初始化。

一个C++源文件从文本到可执行文件经历的过程

对于c/c++编写的程序,从源代码到可执行文件,一般经过下面四个步骤:

  • 预处理, 产生.ii文件 gcc -E hello.c -o hello.i
  • 编译, 产生汇编文件.S文件 gcc -S hello.i -o hello.S
  • 汇编,产生目标文件.o或.obj文件 gcc -C hello.S -o hello.o
  • 链接,产生可执行文件.out或.exe文件 gcc hello.o -o hello

gcc -Wall 允许发出GCC提供的所有有用的警告信息
gcc -w 关闭所有警告信息
使用GDB调试可执行文件之前,必须使用带-g或者-gdb编译选项的gcc命令来编译源程序
编译:gcc test.c -o test -g
GDB调试: gdb test
GDB调试当前正在运行的程序:
1.编译时带-g选项
2.运行程序
3.ps找到进程号
4.启动gdb, 使用attach选项,这时gdb会停止在程序的某处
5.按照GDB调式方法调式,当程序退出之后,依然可以使用run命令重启程序

C++的新特性

  • 关键字及新语法:auto, nullptr, for
  • STL容器:std::array, std::forward_list, std::unordered_map, std::unordered_set
  • 多线程:std::thread, std::atomic, std::condition_variable
  • 智能指针内存管理:std::shared_ptr, std::weak_ptr
  • 其他:std::function, std::bind和lamda表达式

C++中的虚类

C++中的虚类相当于模型类,定义虚类的方式是在:在类中创建纯虚函数,这就是多态的一种方式
纯虚类是不能创建对象的,但是它能创建指针对象,用他存储其派生类的对象,但是存储了派生类的对象也只能访问其有的成员

C++中的析构函数为什么是虚函数

如果基类的析构函数不是虚函数,在特定情况下会导致派生类无法被析构
情况一:用派生类类型指针绑定派生类实例,析构的时候,不管基类析构函数是不是虚函数,都会正常析构
情况二:用基类类型指针绑定派生类实例,析构的时候,如果基类析构函数不是虚函数,则只会析构基类,不会析构派生类对象,从而造成内存泄漏

带参数的宏定义

嵌入式面经111道面试题全解析C/C++可参考 该专栏是我校招阶段整理的关于“嵌入式面经”的111道题目,“软件开发岗位”也可以参考下。涵盖了大多数嵌入式/软件开发岗位常见基础面试题,题目来源是牛客网各大大厂的面经,答案是我逐个查阅资料,理解整理出的答案争取让读者尽可能的容易阅读和理解。...... 阅读详情

相关推荐

NLP、CV、语音相关AI算法工程师面试问题、代码、简历模板、知识点等资源整理分享

本资源整理了机器学习、深度学习、算法工程师等AI相关岗位面试需要知识点,常见代码实战(分为C/C++和python版本)、常见问题,简历模板、比赛/竞赛相关的资源,分享给需要的朋友。 资源整理自网络,源地址:https://github.com/lcylmhlcy/Awesome-algorithm-interview 带链接版资源下载地址: 链接:...

lqfarmer的博客 7072

整理的C++面经(较全)

C++面试过程中整理的知识点

Awesomewan的博客 9万+

C++面试整理

最近开始准备找实习了,收到某位大佬的指导,说可以上牛客网把相关的面经都刷一遍,记录下考点各个击破。大佬是搞java的,已经把java的刷完了,看了一下觉得很受用,因此也准备刷下c++的。顺带附上大佬的java总结:https://zhuanlan.zhihu.com/p/266362976 ...

csdn609387481的博客 1万+

C++ 你想要的C++面经都在这(附答案 | 持续更新)

C++面试题集C++语言网络操作系统1、线程同步的方式进程和线程的区别数据结构1、快排和归并的联系与区别数据库算法编程题 C++语言 网络 操作系统 1、线程同步的方式 1、临界区 每个进程中访问临界资源的那段代码称为临界区(临界资源是一次仅允许一个进程使用的共享资源)如果有多个线程试图访问公共资源,那么在有一个线程进入后,其他试图访问公共资源的线程将被挂起,并一直等到进入临界区的线程离开,临界区在被释放后,其他线程才可以抢占。 2、互斥对象 属于内核对象,能够确保线程拥有对单个资源的互斥访问权,只有拥有互

WhiteShirtI的博客 2万+

为各位学弟学妹整理的C语言/C++相关笔试面试题

1 变量的声明和定义有什么区别 变量的定义为变量分配地址和存储空间, 变量的声明不分配地址。一个变量可以在多个地方声明, 但是只在一个地方定义。加入extern 修饰的是变量的声明,说明此变量将在文件以外或在文件后面部分定义。 说明:很多时候一个变量,只是声明不分配内存空间,直到具体使用时才初始化,分配内存空间, 如外部变量。 intmain() { externintA; //这是个声明而不是定义,声明A是一个已经定义了的外部变量 //注意:声明外部变量时可以把变量类型去...

编程与实战的博客 7684

一、永磁同步电机矢量控制——电机数学模型

本文介绍了永磁同步电机(PMSM)的数学模型构建方法,重点分析了不同坐标系(三相静止、α-β静止、d-q旋转)下的电压方程、磁链表达式及电磁转矩计算方法。通过Clark和Park变换简化非线性耦合系统,推导了表贴式(SPMSM)与内置式(IPMSM)电机的电压方程差异,并给出α-β和d-q坐标系下的转矩公式,强调磁链与电流的正交性对转矩的影响。全文基于理想假设,为后续电机控制算法(如FOC、DTC)提供理论基础。

惊鸿一现 1927

史上最全C/C++面试、C++面经八股文,一文带你彻底搞懂C/C++面试、C++面经!

目录1.讲一讲封装、继承、多态是什么?2.多态的实现原理(实现方式)是什么?以及多态的优点(特点)?3.final关键字的作用是什么?4.虚函数是怎么实现的?它存放在哪里在内存的哪个区?什么时候生成的5.智能指针的本质是什么,它们的实现原理是什么?6.匿名函数的本质是什么?他的优点是什么?7.右值引用是什么,为什么要引入右值引用?8.左值引用和指针的区别?9.指针是什么?10.weak_ptr真的不计数?是否有计数方式,在哪分配的空间。11.malloc的内存分配的方式,有什么缺点?

songbijian的博客 27万+

深入瑞芯微ISP生态:手把手配置RK3588上的RKAIQ Server并与Windows端RKISP Tuner联调

本文详细介绍了如何在RK3588平台上配置RKAIQ Server并与Windows端的RKISP Tuner进行联调,以实现高效的ISP调优。从环境准备、服务部署到实战调试,涵盖了IMX415相机适配等关键步骤,帮助开发者快速掌握瑞芯微ISP生态的核心技术。

weixin_32447969的博客 668

C++面经(简洁版)

持续更新中...

LYC_462857656的博客 5613

【系统架构设计师-2025上半年真题】综合知识-参考答案及详解(75题完全回忆版)

【系统架构设计师-2025上半年真题】案例分析-参考答案及部分详解

数据知道的博客 1万+

小米15修复“NV损坏” 去除主板校验电阻步骤解析与图示

小米15系列将搭载骁龙8至尊版处理器,采用台积电3nm工艺。文章分析了手机出现"NV损坏"故障的表现及修复方法,包括通信异常、系统启动问题等典型症状,并介绍了去除主板校验电阻和刷写工程固件两种修复方案。重点讲解了去除主板电阻后刷写QCN文件的操作流程,强调在维修过程中需要结合分析与思考。适用于小米15系列特定机型(24129PN74G/I/C)的硬件修复。

小马哥的专栏 311

C++面经

1. 语言基础 1.1 C++的四种类型转换: const_cast => 用于将const变量转为非const; static_cast => 用于各种隐式转换,比如非const转const,void*转指针等, static_cast能用于多态向上转化,如果向下转能成功但是不安全,结果未知; dynamic_cast => 用于动态类型转换( 适用于包含虚函数的类 ) ,适用于指针和引用; reinterpret_cast => 几乎什么都可以转,比如将int转指针,可能会出问

MingJ的博客 1771

【SpringBoot 3.x 第92节】Spring Modulith:构建模块化单体架构(基于 Spring Boot 3),一文带你搞透(超详细)!

🏆本文收录于《滚雪球学SpringBoot 3.x》,专门攻坚指数提升,本年度国内最系统+最专业+最详细(永久更新)。    该专栏致力打造最硬核 SpringBoot3 从零基础到进阶系列学习内容,🚀均为全网独家首发,打造精品专栏,专栏持续更新中…欢迎大家订阅持续学习。 如果想快速定位学习,可以看这篇【SpringBoot3教程导航帖】,你想学习的都被收集在内,快速投入学习!!两不误。

**My Coding Family** 995

C C++面试笔试详细总结—基本概念及其它问答题_c++笔试概念题

答 :左右子树都是平衡二叉树 且左右子树的深度差值的绝对值不大于1。答 :可以用引用头文件的方式,也可以用 extern 关键字,如果用引用头文件方式来引用某个在头文件中声明的全局变量,假定你将那个变量写错了,那么在编译期间会报错,如果你用 extern 方式引用时,假定你犯了同样的错误,那么在编译期间不会报错,而在连接期间报错。答:可以,在不同的C 文件中以 static 形式来声明同名全局变量。

2401_85012620的博客 459

5大步骤!轻松玩转Dorisoy.Rigger:基于.NET Core 6、MAUI和Blazor的多数据库开发框架生成器

各位小伙伴,你们是否厌倦了每次项目启动都要从头配置数据库连接、编写重复的代码?今天,我们就来聊聊如何使用Dorisoy.Rigger这个强大的开发框架生成器,让你的.NET Core 6、MAUI和Blazor项目开发变得简单又高效!准备好迎接开发的新乐趣了吗?让我们一起开始吧!接下来,我们需要定义数据模型。假设我们有一个简单的用户表,包含ID、用户名和密码字段。在项目中创建一个新的类文件,命名为User.csset;set;set;这段代码定义了一个用户模型,其中包含了用户的ID、用户名和密码。

java专栏 1738

【华为OD机试真题 2025C卷】895、贪心歌手 | 机试真题+思路参考+代码解析 (C++、Java、Py、C语言、JS)

【华为OD机试真题 2025C卷】895、贪心歌手 | 机试真题+思路参考+代码解析 (C++、Java、Py、C语言、JS) 华为od机试,华为od机试真题,华为od机试E卷,华为odE卷,华为od机试真题E卷,华为OD,华为OD机试,华为OD机试真题,华为od机考,华为od机试D卷,华为od机试真题D卷,华为od手撕代码,华为od,华为od机试C卷,华为od e卷,华为2025e卷,od机试,2025E卷,华为OD机试E卷,什么是华为od,华为od介绍,全面了解华为od,2025华为od,如何备战华

KJ.JK 961

超全面的后端开发C/C++面经整理分享含详细参考答案 包括简历分享

本文为博主2020年秋招提前批的c/c++后端开发面经整理,包括C/C++语言基础,计网,数据库,linux,操作系统,场景题,智力题和hr常问题。面试问题来自前人的工作和博主面试时遇到的值得记录的问题,其中面试题答案多为博主自行解答(并且面试的时候也基本是这样回答的),回答中都附上了参考资料的链接,全文共七万余字,仅供大家作为面试准备材料的参考。 希望大家在准备面试的时候都能建立一个属于自己的题库,自己从网上寻找问题,然后自己进行解答,并且记录下来,这样在面试的时候就能行云流水般的回答上来。因此我把这份面

GhostLWB的博客 10万+

在 SAP 中启用应收/应付“代扣税(Withholding Tax)”功能,本质上是激活并配置“扩展代扣税(Extended Withholding Tax)”模型

摘要:SAP中启用应收/应付代扣税功能需完成3个层级12个核心步骤:1)全局激活公司代码代扣税功能;2)配置代扣税规则、税率和科目,包括定义税种类型、代码、总账科目等;3)在供应商/客户主数据中关联代扣税设置。完成后系统可在发票或付款环节自动计算并过账代扣税,支持多税种并行计算和税率年度调整,最终生成税务报表。常见问题排查需检查公司代码激活状态和主数据配置。(149字)

金牌架构师 831

【C/C++】Dev-C++的安装与使用以及快捷键整理

有时候也叫做Dev-Cpp,是一个免费软件,最早是由BloodShed公司开发的,在版本4.9.2之后BloodShed公司停止了开发并且开放了源代码,之后是由Orwell公司接手进行维护,Orwell公司陆续开发了几个版本,到5.11版本之后更新就比较少了,但是后来也有一些其他的开发人员开发维护了一些分支版本,比如Dev-C++ 的魔改——小熊猫C++。的工具,Dev-C++ 仍然是一个不错的选择。:在 "Tools" → "Editor Options" → "Syntax" 中更改编辑器配色方案。

艾莉丝努力练剑的博客,感谢大家一直以来的对艾莉丝的支持和鼓励,uu们如果对C/C++方向感兴趣的话,可以通过艾莉丝主页的微信名片加艾莉丝的好友,和努力练剑的艾莉丝一起加油! 5015

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

【C/C++】形参、实参相关内容整理

形参:函数调用时创建实参:调用前已存在。

艾莉丝努力练剑的博客,感谢大家一直以来的对艾莉丝的支持和鼓励,uu们如果对C/C++方向感兴趣的话,可以通过艾莉丝主页的微信名片加艾莉丝的好友,和努力练剑的艾莉丝一起加油! 1616

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

最全整理的C C++相关的面经知识点_c++ gdb 面经,7年老C C++一次操蛋的面试经历

为对象分配内存调用构造函数初始化这块内存在第一步中分配内存时就使用了operator new,其实现机制size=1;void *p;if(nh)nh();if(ptr)在第二步中,调用构造函数初始化内存,如果不涉及继承,这一步非常简单,就是给内存赋值,重点是operator new分配内存上,其处理流程如下:3. 分配内存如果成功则直接返回,否则;

2401_84976246的博客 482

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

整理的C C++相关的面经知识点_c++ gdb 面经

如果基类的析构函数不是虚函数,在特定情况下会导致派生类无法被析构情况一:用派生类类型指针绑定派生类实例,析构的时候,不管基类析构函数是不是虚函数,都会正常析构情况二:用基类类型指针绑定派生类实例,析构的时候,如果基类析构函数不是虚函数,则只会析构基类,不会析构派生类对象,从而造成内存泄漏宏名和参数的括号间不能有空格宏替换只作替换,不做计算,不做表达式求解宏替换在编译前进行,不分配内存y+x(y)+(x)int main()//宏替换为: 233+2+23=26。

2501_90404736的博客 582

Linux/C/C++ 不可错过的好书

来源:公众号【编程珠玑】 作者:守望先生 ID:shouwangxiansheng 前言 经常有读者让我推荐书籍,这次我就把我私藏的计算机书单分享给你们!不过由于时间匆忙,不会进行更加详细的介绍。 以下大部分书籍可在公众号后台恢复关键字获取电子版,不过建议购买纸质书。 声明 由于每个人的情况不一样,推荐的书并不一定适合你,也不一定适合当前阶段的你,有的书籍可能存在内容重复,所以...

守望的博客-编程珠玑 3万+

【C/C++】必知必会知识点大总结

📣专栏定位:整理一下 C++ 相关的知识点,供大家学习参考~🎏唠叨唠叨:在这个专栏里我会整理一些琐碎的 C++ 知识点,方便大家作为字典查询~

Newin2020的博客 2176

C++面试题&知识点整理

近期在找工作,面的基本上是C/C++相关岗位,整理了一些网上提到的面试题或者知识点,慢慢补充吧,有错误的地方欢迎指出。 1. 线程、锁 1.1. posix thread 互斥锁 创建:动态/静态 属性: 普通锁、嵌套锁、检错锁、适应锁 锁操作:pthread_mutex_lock、pthread_mutex_unlock、pthread_mutex_trylock 1...

Chen_zju的博客 2903

C/C++开发环境

如同, 缺少了对cJSON的编译,这里对成员函数的所需的c/cpp文件未被编译。也就是按单文件编译方法对多文件进行编译。解决办法:在tasks.jason 中设置源文件,将"args"的值语言CC++C/C++这里的 ${fileDirname} 表示当前目录。

Watom_663的博客 3286
上一篇: 结构体作为函数参数传递
下一篇: 整理的uC/OS_II系统相关知识点
Tanner_SL
博客等级 码龄8年 82粉丝 38原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值