栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

安卓面经大全

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

安卓面经大全

last更新:
2022.2.11

计算机基础类知识

1.什么是上下文切换
比如用户在占着CPU,然后此时操作系统要用,那么就要把用户挪开,把操作系统放上去。
也就是把上一个进程的东西挪走,下一个进程的挪进来。这就是一次上下文切换

2.工厂模式
工厂模式有三种,分别是简单工厂模式,工厂方法模式,抽象工厂模式。不管哪种工厂模式,对于产品,都要实现其固有的接口。比如手机产品都要实现Phone接口,电脑产品都要实现PC接口等等。
简单工厂模式,就是一个工厂直接负责所需对象的创建,而且是负责所有的,比如负责小米手机和苹果手机
工厂方法模式,就是一个产品一个工厂,这些工厂类实现统一的接口来表明它是生产某一类物品的工厂,比如生产手机的。
抽象工厂模式,就是多个产品一个工厂,比如小米工厂不仅可以造手机,也可以造电脑。这种就在他们实现的接口上加一个造电脑的方法就行了。

3.代理模式
代理模式有三种,分别是静态代理,动态代理,和cglib。静态代理就是编译期就可以确定代理对象,但是一个被代理对象就要创建一个代理类,很冗余。于是有了利用反射机制的动态代理,动态代理就是运行时根据利用invoke方法动态去调用被代理类的相应方法,Java中有专门的API去实现动态代理。但是也有缺点,就是动态代理要求被代理类实现接口,所以就有了cglib

4.进程和线程的区别:
比较官方的话:进程是资源分配的最小单位,线程是CPU调度的最小单位
之前看到过一个回答,记忆颇深。
进程=火车,线程=车厢
①一个进程可以有多个线程
②进程之间不容易资源共享,而线程之间容易
③一个进程挂了,可能不影响其他进程。而一个线程挂了,此进程的所有线程都崩了。
④进程使用的内存地址可以上锁,即一个线程使用某些共享内存时,其他线程必须等它结束,才能使用这一块内存。(比如火车上的洗手间)-“互斥锁”
⑤进程使用的内存地址可以限定使用量(比如火车上的餐厅,最多只允许多少人进入,如果满了需要在门口等,等有人出来了才能进去)-“信号量”

5.死锁产生的四个条件:互斥,不可剥夺,请求与保持,循环等待
预防死锁:从四个条件中选。
避免死锁:银行家算法

6.各个排序的时间复杂度

Java

1.回调
我的理解就是A的a方法调用B的b方法,然后b方法执行完了之后又会调用A的某一方法。最经典的使用就是线程切换的时候。自己不想执行这个任务,换一个线程去执行,执行完了之后执行回调函数(也就是自己线程里面的某一方法),再告诉我任务执行的结果。

2.线程两种创建方式的区别
集成Thread类,实现Runnable方法
Thread类使用简单,但是需要继承,Java是单继承,所以耦合度大。
Runnable可以实现多个线程共享同一个资源,个人认为更轻量级。因为它直接就是对任务的抽象

3.JAVA中引用类型有哪些 适应场景

4.软引用和弱引用的区别
虚引用主要用来跟踪对象被垃圾回收器回收的活动。
虚引用必须和引用队列(ReferenceQueue)联合使用。当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之关联的引用队列中。

5.Java静态变量和实例变量的区别,在内存分配上的区别(静态变量不用多次占用内存)

6.Java的参数传递是值传递还是引用传递
Java中只有值传递,这个值实际上是对象的引用,如果对象在栈中,就重新创建一个对象,与外部对象互不影响,如果对象在堆中,就把这个对象指向的栈中的地址的值传入,然后再另外创建一个对象,保存这个地址的值,其实是相当于两个对象更改一个变量,所以会影响外部对象。总之都是要创建一个新对象,区别在于这两个新对象是不是操控的同一个东西

7.字符串常量池

8.多态有几种形式(编译时多态即方法重载和重写,运行时多态即我们平时用的)

9.同一进程中的线程共享哪些资源:堆

10.多线程如何避免冲突,就是加锁

11.synchronized和Lock的区别
①底层上,synchronized是monitor对象,Lock是一个接口,可以使用其实现类ReentrantLock进行加锁。底层是AQS,即抽象队列锁。以内部类的方式存在于ReentrantLock中。
②灵活性上的区别,ReentrantLock可重入,可中断,可公平,异常时需要手动释放。synchronized就是可重入,异常时系统会自动释放。
③synchronized是关键字,Lock是一个接口
①悲观还是乐观(synchronized和ReentrantLock都是悲观锁,但是在获取锁的时候都用了乐观锁的思想,即CAS操作)
我认为,Lock是synchronized的改进版,因为synchronized锁的释放不灵活,多个线程不论读写都会阻塞。Lock都可以解决

ReentrantLock、Lock、AQS的联系,ReentrantLock继承Lock,AQS是ReentrantLock的内部类。当使用锁的时候,实际上是通过Lock来使用的AQS。AQS才是真正的锁

12.悲观锁和乐观锁(区别:有没有真正上锁)
乐观锁有两种方式:CAS和版本号机制
ReentrantLock和synchronized都是悲观锁

13.啥时候用悲观锁,啥时候用乐观锁
①看并发度。如果并发度很大,尽管悲观锁效率低,那还是要用
②如果写比较多,就用悲观锁,大部分是读的时候,用乐观锁。根据应用场景

14.volatile
能够保证可见性
能够保证有序性
无法保证原子性
还有这一篇文章

15.final和static的区别
final修饰类,表示不能被继承
final修饰方法,则不能被重写(或者重写了也会报错)
static可以被所有对象共享

16.String、StringBuffer和StringBuilder的区别?
String的值不可变,StringBuffer 和StringBuilder的值可变
运行速度 StringBuilder>StringBuffer>String (StringBuffer有锁,所以性能会降低)
StringBuffer线程是安全的,适合多线程;StringBuilder线程是不安全的,适合单线程
如果不需要频繁的修改值,用String即可

17.HashMap是有序的吗?如何实现有序?

18.ConcurrentHashMap底层原理
线程安全的HashMap,它里面的属性加了volatile修饰,还加了ReentrantLock

19.sleep方法和wait方法有什么区别
(有无释放锁,wait需要notify/notifyAll,然后再拿锁,才能进入运行就绪,而sleep不用重新获取锁)

20.声明一个Java的抽象类,请指出其错误所在。

abstract class Something {
private  abstract  String  doSomething ();
public  final  abstract  void  doAnyThing();
protected  abstract  void  doNothing();

21.弱引用和软引用的作用
软引用一般用来实现内存敏感的缓存,如果有空闲内存就可以保留缓存,当内存不足时就清理掉,这样就保证使用缓存的同时不会耗尽内存。例如图片缓存框架中缓存图片就是通过软引用的。
弱引用生命周期比软引用还要短,弱引用的作用在于解决强引用所带来的对象之间在存活时间上的耦合关系。弱引用最常见的用处是在集合类中,尤其在哈希表中。哈希表的接口允许使用任何Java对象作为键来使用。当一个键值对被放入到哈希表中之后,哈希表对象本身就有了对这些键和值对象的引用。如果这种引用是强引用的话,那么只要哈希表对象本身还存活,其中所包含的键和值对象是不会被回收的。如果某个存活时间很长的哈希表中包含的键值对很多,最终就有可能消耗掉JVM中全部的内存。对于这种情况的解决办法就是使用弱引用来引用这些对象,这样哈希表中的键和值对象都能被垃圾回收。Java中提供了WeakHashMap来满足这一常见需求。

22.单例模式几种

23.线程池

24.详细介绍下synchronized(可重入,悲观锁,优化,非公平锁)

Kotlin

1.协程
协程就是一个比较方便的线程框架。最大的好处是方便,方便在可以在一个代码块里,实现多个线程的操作。消除了并发任务之间协作的难度(各种回调),让我们可以轻松的写出复杂的代码
挂起函数其实就是稍后会被自动切回来的线程切换。说白了就是切个线程,切到哪个线程,在挂起函数中会有指定。当任务执行完的时候,再自动切回来。就这么简单。但是真正要挂起协程,并不是直接调用suspend就完事了,还要调用另外一个挂起函数去指定切到哪个线程,比如withContext函数
suspend既然不能真正实现挂起,那它是干啥的?它其实是一个提醒,提醒调用者:我是耗时
协程的非阻塞式挂起,只是用阻塞的方式写出了非阻塞的代码而已,非阻塞式相当于是提醒它是非阻塞的。没啥特别之处。我们平时切线程也是非阻塞式的,都一样。
结论:协程就是一个比较方便的线程框架,挂起就是可以自动切回来的切线程,非阻塞式就是用阻塞的方式写出了非阻塞的代码而已

Android

面试指引
1.各个控件ANR的时间
Activity(5s)
广播(10s)
service(20s)
根本原因:执行耗时任务
可能在主线程请求网络

2.AMS介绍
ActivityManagerService
AMS是Android中最核心的服务,主要负责系统中四大组件的启动、切换、调度及应用进程的管理和调度等工作

3.service中能否开启耗时任务
不可以,因为service也是运行在主线程中的,可以开启子线程去执行耗时任务,也可以通过IntentService中的工作线程来处理耗时任务

4.广播的生命周期
广播的生命周期从调用开始到onReceiver执行完毕结束。
需要注意的是,一般广播的生命周期都极短,需要在10s内处理完onReceiver中的所有工作,所以,一般不进行耗时长的工作,如果有耗时长的工作,应当通过Intent传递给Service进行处理。(注意,不要在onReceiver中开启线程进行耗时任务处理,否则,在10s后,该线程会变成空线程,从而导致任务的丢失。同样的,也不要使用bindService来绑定服务。)
值得注意的是,如果是在代码中动态注册的广播,如:在Activity注册,那么在Activity的onDestory中需要使用unregisterReceiver注销广播。

5.介绍下 sp
优点:轻量级,方便好用
缺点:IO操作。数据类型比较少,是全量更新,效率低
①它是一个利用键值对,将数据存储在xml文件中的,它比sqlite更轻量级。真正的读写操作其实是通过Editor对象来的。
②它在读取文件的时候,用的是传统的IO操作,将数据读取到内存当中,然后再进行xml解析。
③在进行任务提交的时候,有两种方式,

一个是commit同步提交,这样会阻塞线程,并且是直接写入磁盘,
还有一个是apply异步提交,先将数据写入内存,后写入磁盘。可能会导致数据丢失。
当Activity调用onPause()方法的时候,会等待内存中的QueuedWork队列中的任务全部写入磁盘中,这样相当于转嫁时间给了主线程,有可能导致ANR。而commit就不会,它只会阻塞当前线程,因此可以新开一个线程去执行commit。
除非要求立刻提交并且根据提交结果(commit有返回值)去执行下一步,则使用commit。否则,使用apply就行。

④sp在进行数据更新的时候,是全量更新。哪怕是更新一条数据,它也会把map集合全部解析成xml文件,对原xml文件进行一个覆盖

6.Android实现多进程的意义
①模块化,主进程死了或者子进程死了可以继续工作
②防止单一进程占用内存过大
③守护进程
如何实现多进程:process属性
这个属性的值如果是”:“开头。表示这个进程是应用私有的。无法在在跨应用之间共用。
如果该属性值以小写字母开头,表示这个进程为全局进程。可以被多个应用共用。其他应用的组件可以通过设置sharedUID来和他跑相同的进程

7.Android进程间通信的几种方式
binder,Intent/Bundle,contentProvider(主要用来为其他APP提供数据,底层也是binde实现的),广播,socket(在服务器中定义ServerSocket来监听端口,客户端使用Socket来请求端口,连通后就可以进行通信)

8.binder好在哪
IPC,就是进程间通信
性能好,管道,消息队列,Socket的通讯都需要两次数据拷贝,而Binder只需要一次(内存映射)(零拷贝)
稳定性,C/S架构,客户端有什么需求就丢给服务器,分工明确。
安全性,binder更安全。原理:IPC机制在内核中为每个合法的app添加了有效的身份标识UID。传统IPC形式,无法得到对方的身份标识(UID/GID),而在使用Binder IPC时,这些身份标示是跟随调用过程而自动传递的。Server端很容易就可以知道Client端的身份,非常便于做安全检查

9.viewgroup的测量流程

10.onLayout和onDraw是否递归
Layout的作用就是为整个View树计算实际的位置,想计算整个View树的位置,就需要递归的去计算每一个子视图的位置(Measure同理)。
onDraw应该不是递归。

11.activity中onStart和onResume的区别
onStart()是activity界面被显示出来的时候执行的,用户可见,包括有一个activity在他上面,但没有将它完全覆盖,用户可以看到部分activity但不能与它交互
onResume()是当该activity与用户能进行交互时被执行,用户可以获得activity的焦点,能够与用户交互。
当有dialog弹出时,不会执行onPause,除非是dialog样式的activity把他覆盖住,才会执行onPause。从onPause转为运行状态时,是执行的onResume而非onRestart。

12.px sp dp的区别:
dp会适配,它乘以像素密度就是真正的px
px不会适配
sp和dp很像

13.事件分发
默认情况下怎么会有冲突(父view不往下传递了)

14.动画有哪几种类型
补间,帧动画,属性动画
属性动画的插值器 调节变化 本质:根据动画的进度(0%-100%)计算出当前属性值改变的百分比

15.Android性能优化的几个方向
布局里面的优化(重复绘制,内存抖动,防抖动)
handler内存泄露如何避免 静态内部类

16.jetpack搭建MVVM用到哪些组件,作用是啥

17.RecyclerView和ListView的区别
①缓存数目(RecyclerView多两层)②缓存的东西(RecyclerView缓存的ViewHolder,ListView缓存的View,每次需要bind)③实现了局部刷新的接口④实用性,强大性

18.能否在service进行耗时操作,如果非要可以怎么做

19.Android中Intent传递对象有两种方法:一是Bundle.putSerializable(Key,Object),另一种是Bundle.putParcelable(Key,Object)。当然这些Object是有一定的条件的,前者是实现了Serializable接口,而后者是实现了Parcelable接口。

20.什么是序列化?把对象转换成字节序列的过程
①持久保存(serializable)
②网络间传递(Json)
③进程间传递(parcelable)
看这一篇文章

21.serializable和parcelable接口的区别?为啥推荐使用后者
如果必须保存到本地硬盘,则只能用serializable。
parcelable效率要高,因为它大多数是在内存操作。
而且serializable大量使用了反射,效率要低很多。

22.深拷贝和浅拷贝的区别?怎么实现深拷贝?

23.主线程中Looper的轮询死循环为何没有发生ANR?
记住: Looer.loop()方法可能会引起主线程的阻塞(没有消息的时候),但是不会发生ANR

24.双亲委托机制

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/737600.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号