2024年Android最全C++基础知识总结,2024年这些高频面试知识点最后再发一次

最后

代码真的是重质不重量,质量高的代码,是当前代码界提倡的,当然写出高质量的代码肯定需要一个相当高的专业素养,这需要在日常的代码书写中逐渐去吸收掌握,谁不是每天都在学习呀,目的还不是为了一个,为实现某个功能写出高质量的代码。

所以,长征路还长,大家还是好好地做个务实的程序员吧。

最后,小编这里有一系列Android提升学习资料,有兴趣的小伙伴们可以来看下哦~

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

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

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

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

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

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

  1. 浅拷贝和深拷贝

发生拷贝的情况:

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

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

  1. 纯虚函数

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

  2. 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函数无对象。

  1. 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的作用域和普通变量是一样的。

  1. 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 不同其余均相同。



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

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

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

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

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

初始化顺序:

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

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

3) 基类的成员变量

4) 派生类的成员变量

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

  1. 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的变量。

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

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


class Empty

{

public:

Empty(); // 缺省构造函数//

Empty( const Empty& ); // 拷贝构造函数//

~Empty(); // 析构函数//

Empty& operator=( const Empty& ); // 赋值运算符//

};



  1. 智能指针

用对象管理指针,防止再分配堆内存时忘记释放内存而引起内存泄漏。使用对象管理指针的话,对象生命周期结束时,指针所指向的内存被自动释放,不用程序员担心。

shared_ptr: 将原始指针分配给多个所有者,并用引用计数来记录所有者的个数。每当一个所有者结束生命周期时,引用计数减一,当引用计数为0时,释放原始指针所指向的内存。

用拷贝构造函数和make_shared初始化;支持拷贝语义(拷贝构造和赋值)。

reset(pointer)原先指针引用计数减一,新的指针引用计数加一。


	shared_ptr<int> p1 = make_shared<int>(10);

	shared_ptr<int> p2(p1);

	cout << p1.use_count() << endl; //2



 p2 = p1;



unique_ptr: 原始指针只能有一个所有者,当所有者对象生命周期结束,指针所指向的内存也被释放。

用new的方式直接初始化;不支持拷贝语义,只支持移动语义。

release()返回原始指针,解除对原始指针的所有权;

reset(pointer)释放原先指针所指向的内存,指定新的指针。


int main()

{

	unique_ptr<int> p1(new int(1));

	unique_ptr<int> p2;

	p2.reset(p1.release());//常见用法,把p1的所有权转移到p2.等价于 p2 = std::move(p1);



	cout << *p2 << endl;

	cout<< p1;//智能指针不指向任何指针时,指向nullptr.

	return 0;

}



两个对象互相使用一个shared_ptr成员变量指向对方会造成循环引用。


class B;

class A

{

public:

	shared_ptr<B> data;

};



class B

{

public:

	shared_ptr<A> data;

};



int main()

{

	shared_ptr<A> a(new A);

	shared_ptr<B> b(new B);

	a->data = b;

	b->data = a;



	_CrtDumpMemoryLeaks();

	return 0;

}



### 最后

今天关于面试的分享就到这里,还是那句话,有些东西你不仅要懂,而且要能够很好地表达出来,能够让面试官认可你的理解,例如Handler机制,这个是面试必问之题。有些晦涩的点,或许它只活在面试当中,实际工作当中你压根不会用到它,但是你要知道它是什么东西。

最后在这里小编分享一份自己收录整理上述技术体系图相关的几十套**腾讯、头条、阿里、美团等公司2021年的面试题**,把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含**知识脉络 + 诸多细节**,由于篇幅有限,这里以图片的形式给大家展示一部分。

还有 **高级架构技术进阶脑图、Android开发面试专题资料**,高级进阶架构资料 帮助大家学习提升进阶,也节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。

![](https://img-blog.csdnimg.cn/img_convert/3e07c0c34055abc1452c0092cac1c920.webp?x-oss-process=image/format,png)

**【算法合集】**

![](https://img-blog.csdnimg.cn/img_convert/2b9479532592bbb0ac772945413db603.webp?x-oss-process=image/format,png)

**【延伸Android必备知识点】**

![](https://img-blog.csdnimg.cn/img_convert/de9d7407cf578a63e6076e19dff2c8aa.webp?x-oss-process=image/format,png)

**【Android部分高级架构视频学习资源】**

**Android精讲视频领取学习后更加是如虎添翼!**进军BATJ大厂等(备战)!现在都说互联网寒冬,其实无非就是你上错了车,且穿的少(技能),要是你上对车,自身技术能力够强,公司换掉的代价大,怎么可能会被裁掉,都是淘汰末端的业务Curd而已!现如今市场上初级程序员泛滥,这套教程针对Android开发工程师1-6年的人员、正处于瓶颈期,想要年后突破自己涨薪的,进阶Android中高级、架构师对你更是如鱼得水,赶快领取吧!



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

**[需要这份系统化学习资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618156601)**

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

0YnGxAjF-1714832107893)]

**【延伸Android必备知识点】**

[外链图片转存中...(img-tobi4zkm-1714832107894)]

**【Android部分高级架构视频学习资源】**

**Android精讲视频领取学习后更加是如虎添翼!**进军BATJ大厂等(备战)!现在都说互联网寒冬,其实无非就是你上错了车,且穿的少(技能),要是你上对车,自身技术能力够强,公司换掉的代价大,怎么可能会被裁掉,都是淘汰末端的业务Curd而已!现如今市场上初级程序员泛滥,这套教程针对Android开发工程师1-6年的人员、正处于瓶颈期,想要年后突破自己涨薪的,进阶Android中高级、架构师对你更是如鱼得水,赶快领取吧!



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

**[需要这份系统化学习资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618156601)**

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值