2024年Android最全C++基础知识总结,2024Android大厂高频面试题

结语

由于篇幅限制,文档的详解资料太全面,细节内容太多,所以只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!以下是目录截图:

由于整个文档比较全面,内容比较多,篇幅不允许,下面以截图方式展示 。

再附一部分Android架构面试视频讲解:

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

system("pause");

}




派生类继承的内容: 非private的非虚函数,虚函数,静态变量和函数。注意派生类和基类的同名静态变量共用一块内存。如果派生类不对基类函数隐藏,  

那么就可以使用派生类对象直接调用基类的函数。



4.  多态性



一种接口有多种实现。编译时多态,由重载体现,相同函数名不同参数列表;运行时多态,由虚函数体现。



非虚函数的地址是编译期间就确定,虚函数地址运行期间绑定。会根据基类指针指向的对象得到虚表指针,然后根据虚表指针访问类的虚函数表,从而获得虚函数的地址,然后调用执行。



虚表的构建与需函数的调用过程参考:https://blog.csdn.net/Xiongchao99/article/details/73381280



所以调用非虚函数看变量类型,调用虚函数看对象。例如,



#include

using namespace std;

class A

{

public:

virtual void x()

{

	cout << "A::x" << endl;

}



void y()

{

	x();

	cout << "A::y" << endl;

}

};

class B : public A

{

public:

virtual void x()

{

	cout << "B::x" << endl;

}



virtual void y()

{

	cout << "B::y" << endl;

}

};

int main()

{

A *p = new B;

p->y();

return 0;

}

结果:

B::x

A::y

虽然y()在B中是虚函数但在A中不是,也就是说只有调用B子类的该虚函数才会体现他的多态性。

这里调用y非虚函数,根据变量类型会调用A中的y(),然后因为x()是虚函数,根据对象类型A调用A中x();




如果在父类中是虚函数,那么子类不用加virtual也是虚函数。如果只在子类才是虚函数,那么从子类的子类开始才会体现多态。



普通函数为什么比虚函数调用快?



因为普通函数是静态联编的,而虚函数地址是动态联编的。



静态联编 :在编译的时候就确定了函数的地址,然后call就调用了。  

动态联编 : 首先需要取到对象的首地址,然后再解引用取到虚函数表的首地址后,再加上偏移量才能找到要调的虚函数,然后call调用。



为什么子类和父类的函数名不一样,还可以构成重写呢?  

因为编译器对析构函数的名字做了特殊处理,在内部函数名是一样的。



5.  浅拷贝和深拷贝



发生拷贝的情况:  

(1)对象以值传递的方式传入函数体 (2)对象以值传递的方式从函数返回 (3)对象通过另外一个对象初始化或赋值。



浅拷贝只是拷贝了类成员的值。当对象中含所有指针变量时,浅拷贝只拷贝了指向同一块内存区域的指针,当其中一个对象对这块内存内存进行改变另一个对象也会受到影响,当一个对象释放掉这块内存,另一个对象的指针变量就会变成野指针,容易发生错误。而深拷贝会定义拷贝构造函数和赋值运算符重载,重新拷贝一份内存,是两个对象之间不会产生影响。



6.  纯虚函数  

    定义时虚函数后加=0。有纯虚函数的类是抽象类,不能生成对象。纯虚函数用于不方便生成对象的类,把纯虚函数交给子类实现。

    

7.  const  

    const修饰变量:表示只读变量,根据初始化判断编译期常量还是运行期常量。  

    const修饰指针变量(const T\*p情况),最好是const指针给const指针赋值,非const指针给非const赋值。

    



//非const赋给const,const失去意义。

int i=10;

const int* p = &i;

cout << *ii << endl;//10

i = 20;

cout << *ii << endl;//20

//const赋给非const,语法错误




const修饰函数返回值:避免给表达式赋值(参考返回值引用)  

const修饰成员函数:不允许在函数内部修改对象,const不能修饰static成员函数,因为const是为了保证对象不被修改,而static函数无对象。



8.  static与全局变量



全局变量:定义在函数体外的变量(函数同理)就是全局变量,具有全局的作用域和生命周期。其他源文件想使用某个源文件中定义的全局变量,只需要extern 类型名 变量;声明即可。



静态变量:存储于全局/静态存储区,生命周期与程序相同,但作用域由定义位置决定,所以可以用static修饰全局变量,将全局变量作用域限定在当前源文件中。



static修饰类成员时,static属于类,类和派生类的所有对象都可以访问static成员变量,当然是在作用域允许的情况下(protected,public)。static成员变量必须在类外初始化,static成员函数可通过类名直接调用。



class A

{

public:

static void func() { cout << "stattuic"; }

const static int var;

static int var1;

};

const int A::var = 1;

int A::var1 = 1;

class B :public A {

};

int main()

{

A a;

B b;

cout << b.var << endl;

cout << b.var1 << endl;

A::func();



return 0;

}




由此可见静态变量和全局变量生命周期相同,但是static的作用域和普通变量是一样的。



8.  32位,64位系统中,各种常用内置数据类型占用的字节数?



char :1个字节(固定)

(*即指针变量): 4个字节(32位机的寻址空间是4个字节。同理64位编译器8字节)(随系统变化)

short int : 2个字节(固定)

int: 4个字节(固定)

unsigned int : 4个字节(固定)

float: 4个字节(固定)

double: 8个字节(固定)

long: 4个字节,64位8个字节(随系统变化)

unsigned long: 4个字节,64位8个字节(随系统变化)

long long: 8个字节(固定)

64位操作系统

char :1个字节(固定)

*(即指针变量): 8个字节

short int : 2个字节(固定)

int: 4个字节(固定)

unsigned int : 4个字节(固定)

float: 4个字节(固定)

double: 8个字节(固定)

long: 8个字节

unsigned long: 8个字节(变化*其实就是寻址控件的地址长度数值)

long long: 8个字节(固定)

除*与long 不同其余均相同。




9.  C++类中数据成员初始化顺序?  

    1.成员变量在使用初始化列表初始化时,与构造函数中初始化成员列表的顺序无关,只与定义成员变量的顺序有关。



2.如果不使用初始化列表初始化,在构造函数内初始化时,此时与成员变量在构造函数中的位置有关。



3.类中const成员常量必须在构造函数初始化列表中初始化。



4.类中static成员变量,只能在类内外初始化(同一类的所有实例共享静态成员变量)。



初始化顺序:



1) 基类的静态变量或全局变量  

2) 派生类的静态变量或全局变量  

3) 基类的成员变量  

4) 派生类的成员变量



const成员变量,引用成员变量, 其他类的对象必须在初始化列表中初始化。



10.  static\_cast, dynamic\_cast, const\_cast, reinpreter\_cast的区别



static\_cast相当于c语言的强制类型转换.



dynamic\_cast要求转换类型必须是指针或引用,而且基类一定要包含虚函数。在上行转换(子类对象转换为基类类型)中和static\_cast效果是一样的,下行转换时要把父类类型转换为子类类型,这时父类指针一定要指向子类对象转换才是安全的。如果使用static\_cast不会进行安全性检查,dynamic\_cast会安全性检查,如果父类指针没有指向子类对象则返回null指针。



class A

{

public:

virtual void f() { cout << "A::f"; }

};

class B :public A {

public:

void f() {

	cout << "B::";

}

int a;

};

int main()

{

//上行转换,安全

B* b = new B;

A* a = static_cast<A*>(b);

a->f();//satic_cast和dynamic——cast效果一样,都输出B::f



//下行转换,安全

A* a = new B;

B* b = static_cast<B*>(a);//或者dynamic_cast

cout << b->a;

a->f();

//下行转换,不安全

A* a = new A;

B* b = static_cast<B*>(a);

cout << b->a; //可能访问到不确定,也可能无效内存,反正不是b成员变量的值,只是相对b对象内存偏移一定位置内存的值。

a->f();



B* b = dynamic_cast<B*>(a);//返回nullptr

return 0;

}




reinterpret\_cast可以对无关类指针进行转换,甚至可以直接将整型值转成指针,这种转换是底层的,有较强的平台依赖性,可移植性差;



const\_cast可以将常量转成非常量,但不会破坏原常量的const属性,只是返回一个去掉const的变量。



11.  定义一个空类编译器做了哪些操作



一个空的class在C++编译器处理过后就不再为空,编译器会自动地为我们声明一些member function,一般编译过就相当于:



学习福利

【Android 详细知识点思维脑图(技能树)】

其实Android开发的知识点就那么多,面试问来问去还是那么点东西。所以面试没有其他的诀窍,只看你对这些知识点准备的充分程度。so,出去面试时先看看自己复习到了哪个阶段就好。

虽然 Android 没有前几年火热了,已经过去了会四大组件就能找到高薪职位的时代了。这只能说明 Android 中级以下的岗位饱和了,现在高级工程师还是比较缺少的,很多高级职位给的薪资真的特别高(钱多也不一定能找到合适的),所以努力让自己成为高级工程师才是最重要的。

这里附上上述的面试题相关的几十套字节跳动,京东,小米,腾讯、头条、阿里、美团等公司19年的面试题。把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节。

由于篇幅有限,这里以图片的形式给大家展示一小部分。

网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望这份系统化的技术体系对大家有一个方向参考。

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

饱和了,现在高级工程师还是比较缺少的,很多高级职位给的薪资真的特别高(钱多也不一定能找到合适的),所以努力让自己成为高级工程师才是最重要的。

这里附上上述的面试题相关的几十套字节跳动,京东,小米,腾讯、头条、阿里、美团等公司19年的面试题。把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节。

由于篇幅有限,这里以图片的形式给大家展示一小部分。

[外链图片转存中…(img-Wv7wAnfv-1715621240629)]

网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望这份系统化的技术体系对大家有一个方向参考。

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值