2024年大厂Android面试题汇总(二)(含答案)_当某函数返回值为指针类型时函数中必须要使用static

最后

这里我特地整理了一份《Android开发核心知识点笔记》,里面就包含了自定义View相关的内容

除了这份笔记,还给大家分享 Android学习PDF+架构视频+面试文档+源码笔记,高级架构技术进阶脑图、Android开发面试专题资料,高级进阶架构资料这几块的内容。非常适合近期有面试和想在技术道路上继续精进的朋友。

分享上面这些资源,希望可以帮助到大家提升进阶,如果你觉得还算有用的话,不妨把它们推荐给你的朋友~

喜欢本文的话,给我点个小赞、评论区留言或者转发支持一下呗~

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

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

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

如今,Android开发岗的就业形势逐渐严峻,想要在众多面试者中脱颖而出,拿下大厂offer,就必须全面梳理知识点,扩充题库,并针对面试中可能遇到的关键知识,进行深入分析。

本文是专为Android工程师准备的高薪面试真题汇总题库,涵盖多年大厂面经总结+核心考点深度解析,让你秒变offer收割机

由于篇幅原因分为上下两篇:
上接:2022年大厂Android面试题汇总(一)(含答案)

Android面试真题

JVM的加载原理

1.编译机制

从下图可以看出java文件经过了一次编译后,java代码编译成java字节码(class文件)。然后再不同平台上使用不同的虚拟机(JVM)解释,解释成机器码,然后执行。由此可见,如果我们要在mac系统上运行,只需要装一个mac 的java虚拟机就可以了。这也就是java的一次编译,到处运行

2.类的加载机制

  • 1.加载
    加载简单来说分为三步:
    第一步:获取二进制字节流也就是上面的class文件。
    第二步:将静态的存储结构转换为方法区中的运行时数据结构。
    第三步:生成一个对象放入java堆中,做为对方法区的引用。
  • 2.验证
    验证主要是检验如下的几项是否正确:
    class文件的表示(魔数),class文件的版本号,class文件的每个部分是否正确(字段表、方法表等),验证常量池(常量类型、常量类型数据结构是否正确,utf-8是否标准),元数据验证(父类验证,继承验证,final验证),字节码(指令)验证,符号引用验证(是否能根据符号找到对应的字段、表、方法等)
    如果一项不对,就会验证失败。
  • 3.准备
    准备阶段为类变量分配内存 和设置类变量初始化。这个过程中,只对static类变量进行内存分配,这个时候只是分配内存,没有进行复制,所有的类变量都是初始化值。如果是final的话,会直接对应到常量池中。会在准备阶段直接赋值。
  • 4.解析
    解析阶段是读符号引用进行解析。将符号引用解析为直接引用(指向目标的指针或者偏移量)。主要涉及到的解析有类,接口,字段,方法等。
  • 5.初始化
    初始化就是执行方法的过程, 对静态变量,静态代码块进行初始化,对类进行初始化。
  • 6.使用
    使用阶段就是使用这个class。
  • 7.卸载
    卸载阶段就是不在使用,将class给卸载。
3.类加载器


如图所示,每当我们类被加载的时候,都会去走类加载器。

我们自定义加载器有一个父类,就是AppClassLoader,而AppClassLoader也有一个父类加载器ExtClassLoader,ExtClassLoader同样也有一个父类加载器BootstarpClassLoader,BootstarpClassLoader就是最终的加载器了。

当加载类的时候,会启动类加载器,会通过自己定义的类加载器去找AppClassLoader,然后通过AppClassLoader找到ExtClassLoader,再通过ExtClassLoader找到最终BootstarpClassLoader。

可能看到这里,有人人就有疑问了,为什么我有自己的加载器,干嘛还要去找父类的加载器呢?这这种机制叫双亲委任机制,目的就是为了加载累的安全。也就是说我父类加载的不给子类去加载,这样保证最终都是BootstarpClassLoader去加载,可以保证一个类只会加载一次。而你判断两个对象时候一样的时候,最重要的一个条件就是是不是一个加载器去加载的

全局变量和局部变量的区别

1.全局变量也称为外部变量,它是在函数外部定义的变量。 它不属于哪一个函数,它属于一个源程序文件。其作用域是整个源程序。在函数中使用全局变量,一般应作全局变量说明。 只有在函数内经过说明的全局变量才能使用。全局变量的说明符为extern。 但在一个函数之前定义的全局变量,在该函数内使用可不再加以说明

2.局部变量也称为内部变量。局部变量是在函数内作定义说明的。其作用域仅限于函数内, 离开该函数后再使用这种变量是非法的

3.在同一源文件中,允许全局变量和局部变量同名。在局部变量的作用域内,全局变量不起作用。

4.从作用域看,全局变量具有全局作用域。 全局变量只需在一个源文件中定义,就可以作用于所有的源文件。当然,其他不包含全局变量定义的源文件需要用extern 关键字再次声明这个全局变量。

  • 静态局部变量具有局部作用域,它只被初始化一次,自从第一次被初始化直到程序运行结束都一直存在,它和全局变量的区别在于全局变量对所有的函数都是可见的,而静态局部变量只对定义自己的函数体始终可见。
  • 局部变量也只有局部作用域,它是自动对象(auto),它在程序运行期间不是一直存在,而是只在函数执行期间存在,函数的一次调用执行结束后,变量被撤销,其所占用的内存也被收回。
  • 静态全局变量也具有全局作用域,它与全局变量的区别在于如果程序包含多个文件的话,它作用于定义它的文件里,不能作用到其它文件里,即被static关键字修饰过的变量具有文件作用域。这样即使两个不同的源文件都定义了相同名字的静态全局变量,它们也是不同的变量。

5.从分配内存空间看:
全局变量,静态局部变量,静态全局变量都在静态存储区分配空间,而局部变量在栈里分配空间。

全局变量本身就是静态存储方式,静态全局变量当然也是静态存储方式。这两者在存储方式上并无不同。这两者的区别虽在于非静态全局变量的作用域是整个源程序,当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。而静态全局变量则限制了其作用域,即只在定义该变量的源文件内有效,在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用,因此可以避免在其它源文件中引起错误。

1)、静态变量会被放在程序的静态数据存储区(全局可见)中,这样可以在下一次调用的时候还可以保持原来的赋值。这一点是它与堆栈变量和堆变量的区别。
2)、变量用static告知编译器,自己仅仅在变量的作用范围内可见。这一点是它与全局变量的区别。

从以上分析可以看出,把局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期。把全局变量改变为静态变量后是改变了它的作用域,限制了它的使用范围。因此static 这个说明符在不同的地方所起的作用是不同的。应予以注意。

Tips:
  A.若全局变量仅在单个C文件中访问,则可以将这个变量修改为静态全局变量,以降低模块间的耦合度;
  B.若全局变量仅由单个函数访问,则可以将这个变量改为该函数的静态局部变量,以降低模块间的耦合度;
  C.设计和使用访问动态全局变量、静态全局变量、静态局部变量的函数时,需要考虑重入问题,因为他们都放在静态数据存储区,全局可见;
  D.如果我们需要一个可重入的函数,那么,我们一定要避免函数中使用static变量(这样的函数被称为:带“内部存储器”功能的的函数)
  E.函数中必须要使用static变量情况:比如当某函数的返回值为指针类型时,则必须是static的局部变量的地址作为返回值,若为auto类型,则返回为错指针。

静态方法锁和非静态方法锁区别

1.一个锁的是类对象,一个锁的是实例对象。
2.若类对象被lock,则类对象的所有同步方法(static synchronized func)全被lock。
3.若实例对象被lock,则该实例对象的所有同步方法(synchronized func)全被lock。
4.关于同一个类的方法上的锁,来自于调用该方法的对象,如果调用该方法的对象是相同的,那么锁必然相同,否则就不相同。比如 new A().x() 和 new A().x(),对象不同,锁不同,如果A的单利的,就能互斥。
5.静态方法加锁,能和所有其他静态方法加锁的 进行互斥

线程本地ThreadLocal的作用

当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。

ThreadLocal与synchronized同步机制的比较

在同步机制中,通过对象的锁机制保证同一时间只有一个线程访问变量。这时该变量是多个线程共享的,使用同步机制要求程序慎密地分析什么时候对变量进行读写,什么时候需要锁定某个对象,什么时候释放对象锁等繁杂的问题,程序设计和编写难度相对较大。

ThreadLocal是线程局部变量,是一种多线程间并发访问变量的解决方案。和synchronized等加锁的方式不同,ThreadLocal完全不提供锁,而使用以空间换时间的方式,为每个线程提供变量的独立副本,以保证线程的安全。

单例模式几种写法

1.饿汉式

public class SingletonInstance {
//私有构造方法
private static SingletonInstance (){

}
//声明成员变量
private static SingletonInstance singletonInstance = new SingletonInstance();
//对外提供接口获取该实例
public static SingletonInstance getSingletonInstance(){
    return singletonInstance ;
}

}
2.懒汉式

public class SingletonInstance {
//私有构造方法
private SingletonInstance (){

}
//声明成员变量
private static SingletonInstance singletonInstance ;
//对外提供接口获取该实例
public static SingletonInstance getSingletonInstance(){
    if(singletonInstance == null){
        singletonInstance = new SingletonInstance();
    }
    return singletonInstance ;
}

}
3.double check lock(dcl)

public class SingletonInstance {
//私有构造方法
private SingletonInstance (){

}
//声明成员变量
private static SingletonInstance singletonInstance ;
//对外提供接口获取该实例
public static SingletonInstance getSingletonInstance(){
    if(singletonInstance == null){
        synchronized (SingletonInstance.class){
            //两次判断是否为null
            if(singletonInstance==null){
                singletonInstance = new SingletonInstance();
            }


### 尾声

对于很多初中级Android工程师而言,想要提升技能,往往是自己摸索成长,不成体系的学习效果低效漫长且无助。 整理的这些架构技术希望对Android开发的朋友们有所参考以及少走弯路,本文的重点是你有没有收获与成长,其余的都不重要,希望读者们能谨记这一点。

最后想要拿高薪实现技术提升薪水得到质的飞跃。最快捷的方式,就是有人可以带着你一起分析,这样学习起来最为高效,所以为了大家能够顺利进阶中高级、架构师,我特地为大家准备了一套高手学习的源码和框架视频等精品Android架构师教程,保证你学了以后保证薪资上升一个台阶。
![](https://img-blog.csdnimg.cn/img_convert/5acf4f71a437f13b4cd5381f1295335f.webp?x-oss-process=image/format,png)
当你有了学习线路,学习哪些内容,也知道以后的路怎么走了,理论看多了总要实践的。

**进阶学习视频**

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

**附上:我们之前因为秋招收集的二十套一二线互联网公司Android面试真题** (含BAT、小米、华为、美团、滴滴)和我自己整理Android复习笔记(包含Android基础知识点、Android扩展知识点、Android源码解析、设计模式汇总、Gradle知识点、常见算法题汇总。)

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



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

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

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

g-DId48Ugk-1715721912073)]



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

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值