2024最后一天! 我为大家准备一份Android 面试知识点大全迎接2024新的一年

6)使用阻塞队列实现线程同步 LinkedBlockingQueue

9、如何保证线程安全? 线程安全性体现在三方法:

1)原子性:提供互斥访问,同一时刻只能有一个线和至数据进行操作。 JDK 中 提 供 了 很 多 atomic 类 , 如 AtomicInteger\AtomicBoolean\AtomicLong,它们是通过 CAS 完成原子性。 JDK 提供锁分为两种:synchronized 依赖 JVM 实现锁,该关键字作用对象的 作用范围内同一时刻只能有一个线程进行操作。另一种是 LOCK,是 JDK 提供的

代码层面的锁,依赖 CPU 指令,代表性是 ReentrantLock。

2)可见性:一个线程对主内存的修改及时被其他线程看到。

JVM 提供了 synchronized 和 volatile,volatile 的可见性是通过内存屏障和禁 止重排序实现的,volatile 会在写操作时,在写操作后加一条 store 屏障指令, 将本地内存中的共享变量值刷新到主内存;会在读操作时,在读操作前加一条 load 指令,从内存中读取共享变量。

3)有序性:指令没有被编译器重排序。

可通过 volatile、synchronized、Lock 保证有序性。

10、两个进程同时要求写或者读,能不能实现?如何防止进程的同步?

我认为可以实现,比如两个进程都读取日历进程数据是没有问题,但同时写,应 该会有冲突。

可以使用共享内存实现进程间数据共享。

11、线程间操作 List

12、Java 中对象的生命周期

1)创建阶段(Created):为对象分配存储空间,开始构造对象,从超类到子 类对 static 成员初始化;超类成员变量按顺序初始化,递归调用超类的构造方法, 子类成员变量按顺序初始化,子类构造方法调用。

2)应用阶段(In Use):对象至少被一个强引用持有着。

3)不可见阶段(Invisible):程序运行已超出对象作用域

4)不可达阶段(Unreachable):该对象不再被强引用所持有

5)收集阶段(Collected):假设该对象重写了 finalize()方法且未执行过,会 去执行该方法。

6)终结阶段(Finalized):对象运行完 finalize()方法仍处于不可达状态,等待 垃圾回收器对该对象空间进行回收。

7)对象空间重新分配阶段(De-allocated):垃圾回收器对该对象所占用的内 存空间进行回收或再分配,该对象彻底消失。

13、static synchronized 方法的多线程访问和作用

static synchronized 控制的是类的所有实例访问,不管 new 了多少对象,只有一份,所以对该类的所有对象都加了锁。限制多线程中该类的所有实例同时访问 JVM 中该类对应的代码。

14、同一个类里面两个 synchronized 方法,两个线程同时访问的问题

如果 synchronized 修饰的是静态方法,锁的是当前类的 class 对象,进入同步 代码前要获得当前类对象的锁;

普通方法,锁的是当前实例对象,进入同步代码前要获得的是当前实例的锁;

同步代码块,锁的是括号里面的对象,对给定的对象加锁,进入同步代码块库前 要获得给定对象锁;

如果两个线程访问同一个对象的 synchronized 方法,会出现竞争,如果是不同 对象,则不会相互影响。

15、volatile 的原理

有volatile变量修饰的共享变量进行写操作的时候会多一条汇编代码,lock addl $0x0,lock 前缀的指令在多核处理器下会将当前处理器缓存行的数据会写回到 系统内存,这个写回内存的操作会引起在其他 CPU 里缓存了该内存地址的数据 无效。同时 lock 前缀也相当于一个内存屏障,对内存操作顺序进行了限制。

16、synchronized 原理

synchronized 通过对象的对象头(markword)来实现锁机制,java 每个对象都 有对象头,都可以为 synchronized 实现提供基础,都可以作为锁对象,在字节 码层面 synchronized 块是通过插入 monitorenter monitorexit 完成同步的。 持有 monitor 对象,通过进入、退出这个 Monitor 对象来实现锁机制。

17、谈谈 NIO 的理解

NIO( New Input/ Output) 引入了一种基于通道和缓冲区的 I/O 方式,它可以 使用 Native 函数库直接分配堆外内存,然后通过一个存储在 Java 堆的 DirectByteBuffer 对象作为这块内存的引用进行操作,避免了在 Java 堆和 Native 堆中来回复制数据。 NIO 是一种同步非阻塞的 IO 模型。同步是指线 程不断轮询 IO 事件是否就绪,非阻塞是指线程在等待 IO 的时候,可以同时 做其他任务。同步的核心就是 Selector,Selector 代替了线程本身轮询 IO 事 件,避免了阻塞同时减少了不必要的线程消耗;非阻塞的核心就是通道和缓冲区, 当 IO 事件就绪时,可以通过写道缓冲区,保证 IO 的成功,而无需线程阻塞 式地等待。

-synchronized 和 volatile 关键字的区别

-synchronized 与 Lock 的区别

-ReentrantLock 、synchronized 和 volatile 比较

1)volatile:解决变量在多个线程间的可见性,但不能保证原子性,只能用于修 饰变量,不会发生阻塞。volatile 能屏蔽编译指令重排,不会把其后面的指令排 到内存屏障之前的位置,也不会把前面的指令排到内存屏障的后面。多用于并行

计算的单例模式。volatile 规定 CPU 每次都必须从内存读取数据,不能从 CPU 缓存中读取,保证了多线程在多 CPU 计算中永远拿到的都是最新的值。

2)synchronized:互斥锁,操作互斥,并发线程过来,串行获得锁,串行执行 代码。解决的是多个线程间访问共享资源的同步性,可保证原子性,也可间接保 证可见性,因为它会将私有内存和公有内存中的数据做同步。可用来修饰方法、 代码块。会出现阻塞。synchronized 发生异常时,会自动释放线程占有的锁, 因此不会导致死锁现象发生。非公平锁,每次都是相互争抢资源。

3)lock 是一个接口,而 synchronized 是 java 中的关键字,synchronized 是 内置语言的实现。lock 可以让等待锁的线程响应中断。在发生异常时,如果没 有主动通过 unLock()去释放锁,则可能造成死锁现象,因此使用 Lock 时需要在 finally 块中释放锁。

4)ReentrantLock 可重入锁,锁的分配机制是基于线程的分配,而不是基于方 法调用的分配。ReentrantLock 有 tryLock 方法,如果锁被其他线程持有,返 回 false,可避免形成死锁。对代码加锁的颗粒会更小,更节省资源,提高代码 性能。ReentrantLock 可实现公平锁和非公平锁,公平锁就是先来的先获取资 源。ReentrantReadWriteLock 用于读多写少的场合,且读不需要互斥场景。 -ReentrantLock 的内部实现 -lock 原理

  • 死锁的四个必要条件?
  • 怎么避免死锁?
  • 对象锁和类锁是否会互相影响?
  • 什么是线程池,如何使用?
  • Java 的并发、多线程、线程模型
  • 谈谈对多线程的理解 -多线程有什么要注意的问题?
  • 谈谈你对并发编程的理解并举例说明
  • 谈谈你对多线程同步机制的理解?
  • 如何保证多线程读写文件的安全?
  • 多线程断点续传原理 -断点续传的实现

5)并发编程有关知识点(这个是一般 Android 开发用的少的,所以建议多 去看看):

平时 Android 开发中对并发编程可以做得比较少,Thread 这个类经常会用到, 但是我们想提升自己的话,一定不能停留在表面,,我们也应该去了解一下 java 的关于线程相关的源码级别的东西。

面试合集

性能优化版块


1、图片的三级缓存中,图片加载到内存中,如果内存快爆了,会发生什么?怎么处

理?

  • 参考回答:

  • 首先我们要清楚图片的三级缓存是如何的

如果内存足够时不回收。内存不够时就回收软引用对象

2、内存中如果加载一张 500*500 的 png 高清图片.应该是占用多少的内存?

  • 参考回答:

  • 不考虑屏幕比的话:占用内存=500 * 500 * 4 = 1000000B ≈ 0.95MB

  • 考虑屏幕比的的话:占用内存= 宽度像素 x (inTargetDensity / inDensity) x 高度像素 x(inTargetDensity / inDensity)x 一个像素所占的内存字节大小

  • inDensity 表示目标图片的 dpi(放在哪个资源文件夹下),inTargetDensity 表示目标屏幕的 dpi

3、WebView 的性能优化 ?

  • 参考回答:

  • 一个加载网页的过程中,native、网络、后端处理、CPU 都会参与,各自都有必要的工作和依赖关系;让他们相互并行处理

而不是相互阻塞才可以让网页加载更快:

  • WebView 初始化慢,可以在初始化同时先请求数据,让后端和网络不要闲着。

  • 常用 JS 本地化及延迟加载,使用第三方浏览内核

  • 后端处理慢,可以让服务器分 trunk 输出,在后端计算的同时前端也加载网络静态资源。

  • 脚本执行慢,就让脚本在最后运行,不阻塞页面解析。

  • 同时,合理的预加载、预缓存可以让加载速度的瓶颈更小。

  • WebView 初始化慢,就随时初始化好一个 WebView待用。

  • DNS 和链接慢,想办法复用客户端使用的域名和链接。

4、Bitmap 如何处理大图,如一张 30M 的大图,如何预防 OOM?

  • 参考回答:避免 OOM 的问题就需要对大图片的加载进行管理,主要通过缩放来减小图片的内存占用。

  • BitmapFactory 提供的加载图片的四类方法(decodeFile、decodeResource、decodeStream、decodeByteArray

都支持 BitmapFactory.Options 参数,通过 inSampleSize 参数就可以很方便地对一个图片进行采样缩放

  • 比如一张 10241024 的高清图片来说。那么它占有的内存为102410244,即 4MB,如果 inSampleSize 为 2,那么采样后

的图片占用内存只有 512512*4,即 1MB(**注意:根据最新的官方文档指出,inSampleSize 的取值应该总是为 2 的指数,即

1、2、4、8 等等,如果外界输入不足为 2 的指数,系统也会默认选择最接近 2 的指数代替,比如 2**)

  • 综合考虑。通过采样率即可有效加载图片,流程如下

  • 将 BitmapFactory.Options 的 inJustDecodeBounds 参数设为 true 并加载图片

  • 从 BitmapFactory.Options 中取出图片的原始宽高信息,它们对应 outWidth 和 outHeight 参数

  • 根据采样率的规则并结合目标 View 的所需大小计算出采样率 inSampleSize

  • 将 BitmapFactory.Options 的inJustDecodeBounds 参数设为 false,重新加载图片

5、内存回收机制与 GC 算法(各种算法的优缺点以及应用场景);GC 原理时机

以及 GC 对象

  • 参考回答:

  • 内存判定对象可回收有两种机制:

  • 引用计数算法:给对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加 1;当引用失效时,计数器值就减 1;任何时刻计数器为 0 的对象就是不可能再被使用的。然而在主流的 Java 虚拟机里未选用引用计数算法来管理内存,主要原因是它难以解决对象之间相互循环引用的问题,所以出现了另一种对象存活判定算法。

  • 可达性分析法:通过一系列被称为『GCRoots』的对象作为起始点,从这些节点开始向下搜索,搜索所走过的

路径称为引用链,当一个对象到 GC Roots 没有任何引用链相连时,则证明此对象是不可用的。其中可作为 GC Roots 的对象:虚拟机栈中引用的对象,主要是指栈帧中的本地变量*、本地方法栈中 Native 方法引用的对

象、方法区中类静态属性引用的对象、方法区中常量引用的对象

  • GC 回收算法有以下四种:

  • 分代收集算法:是当前商业虚拟机都采用的一种算法,根据对象存活周期的不同,将 Java 堆划分为新生代和老

年代,并根据各个年代的特点采用最适当的收集算法。

  • 新生代:大批对象死去,只有少量存活。使用『复制算法』,只需复制少量存活对象即可。

  • 复制算法:把可用内存按容量划分为大小相等的两块,每次只使用其中的一块。当这一块的内存用尽后,把还存活着的对象『复制』到另外一块上面,再将这一块内存空间一次清理掉。**实现简单,运行高效。在对象存活率较高时就要进行较

多的复制操作,效率将会变低**

  • 老年代:对象存活率高。使用『标记—清理算法』或者『标记—整理算法』,只需标记较少的回收对象即可。

  • 标记-清除算法:首先『标记』出所有需要回收的对象,然后统一『清除』所有被标记的对象。标记和清除两个过程的效率都不高,清除之后会产生大量不连续的内存碎片,空间碎片太多可能会导致以后在程序运行过程中需要分配较大对象时,无法找到足够的连续内存而不得不提前触发另一次垃圾收集动作。

  • 标记-整理算法:首先『标记』出所有需要回收的对象,然后进行『整理』,使得存活的对象都向一端移动,最后直接清理掉端边界以外的内存。标记整理算法会将所有的存活对象移动到一端,并对不存活对象进行处理,因此其不会产生内存碎片

6、内存泄露和内存溢出的区别 ?AS 有什么工具可以检测内存泄露

  • 参考回答:

  • 内存溢出(out of memory):是指程序在申请内存时,没有足够的内存空间供其使用,出现 out of memory;比如申请了一

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级安卓工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Android移动开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
img

关于面试的充分准备

一些基础知识和理论肯定是要背的,要理解的背,用自己的语言总结一下背下来。

虽然 Android 没有前几年火热了,已经过去了会四大组件就能找到高薪职位的时代了。这只能说明 Android 中级以下的岗位饱和了,现在高级工程师还是比较缺少的,我能明显感觉到国庆后多了很多高级职位,所以努力让自己成为高级工程师才是最重要的。

好了,希望对大家有所帮助。

接下来是整理的一些Android学习资料,有兴趣的朋友们可以关注下我免费领取方式

①Android开发核心知识点笔记

②对标“阿里 P7” 40W+年薪企业资深架构师成长学习路线图

③面试精品集锦汇总

④全套体系化高级架构视频

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

获取方式:【Android架构视频+BAT面试专题PDF+学习笔记

1710751616734)]

④全套体系化高级架构视频

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

[外链图片转存中…(img-OrHy7RwP-1710751616734)]

获取方式:【Android架构视频+BAT面试专题PDF+学习笔记

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值