2019-2020年Android最新整理面试题

 

1.Activity生命周期(这个是必问的)

  onCreate():表示Activity正在被创建,常用来初始化工作,比如调用setContentView加载界面布局资源,初始化Activity所需数据等;

onStart():表示Activity正在被启动,此时Activity可见但不在前台,还处于后台,无法与用户交互;

onResume():表示Activity获得焦点,此时Activity可见且在前台并开始活动,这是与onStart的区别所在;

onPause():表示Activity正在停止,此时可做一些存储数据、停止动画等工作,但是不能太耗时,因为这会影响到新Activity的显示,onPause必须先执行完,新Activity的onResume才会执行;

onStop():表示Activity即将停止,可以做一些稍微重量级的回收工作,比如注销广播接收器、关闭网络连接等,同样不能太耗时;

onRestart():表示Activity正在重新启动,一般情况下,当前Acitivty从不可见重新变为可见时,OnRestart就会被调用;

onDestroy():表示Activity即将被销毁,这是Activity生命周期中的最后一个回调,常做回收工作、资源释放

2.说下 Activity的四种启动模式、应用场景 ? 

standard标准模式:每次启动一个Activity都会重新创建一个新的实例,不管这个实例是否已经存在,此模式的Activity默认会进入启动它的Activity所属的任务栈中;

singleTop栈顶复用模式:如果新Activity已经位于任务栈的栈顶,那么此Activity不会被重新创建,同时会回调onNewIntent方法,如果新Activity实例已经存在但不在栈顶,那么Activity依然会被重新创建; 

singleTask栈内复用模式:只要Activity在一个任务栈中存在,那么多次启动此Activity都不会重新创建实例,并回调onNewIntent方法,此模式启动Activity A,系统首先会寻找是否存在A想要的任务栈,如果不存在,就会重新创建一个任务栈,然后把创建好A的实例放到栈中;    

singleInstance单实例模式:这是一种加强的singleTask模式,具有此种模式的Activity只能单独地位于一个任务栈中,且此任务栈中只有唯一一个实例;

3.队列和栈的区别

队列(Queue):是限定只能在表的一端进行插入和在另一端进行删除操作的线性表;

栈(Stack):是限定只能在表的一端进行插入和删除操作的线性表。

区别如下:

一、规则不同

       1. 队列:先进先出(First In First Out)FIFO

       2. 栈:先进后出(First In Last Out )FILO

二、对插入和删除操作的限定不同

       1. 队列:只能在表的一端进行插入,并在表的另一端进行删除;

       2. 栈:只能在表的一端插入和删除。

三、遍历数据速度不同

       1. 队列:基于地址指针进行遍历,而且可以从头部或者尾部进行遍历,但不能同时遍历,无需开辟空间,因为在遍历的过程中不影响数据结构,所以遍历速度要快;

       2. 栈:只能从顶部取数据,也就是说最先进入栈底的,需要遍历整个栈才能取出来,而且在遍历数据的同时需要为数据开辟临时空间,保持数据在遍历前的一致性。

4,设备横竖屏切换的时候,生面周期的变化

不设置Activity的android:configChanges时,切屏会重新调用各个生命周期,切横屏时会执行一次,切竖屏时会执行两次

设置Activity的android:configChanges=”orientation”时,

  • 在Android5.1 即API 23级别下,切屏还是会重新调用各个生命周期,切横、竖屏时只会执行一次
  • 在Android9 即API 28级别下,切屏不会重新调用各个生命周期,只会执行onConfigurationChanged方法

设置Activity的android:configChanges=”orientation|keyboardHidden”时,切屏不会重新调用各个生命周期,只会执行

onConfigurationChanged方法


5.谈一谈Fragment的生命周期?

Fragment从创建到销毁整个生命周期中涉及到的方法依次为:

onAttach()onCreate()onCreateView()onActivityCreated()onStart()onResume()onPause()onStop()onDestroyView()onDestroy()onDetach()

其中和Activity有不少名称相同作用相似的方法,而不同的方法有:

  • onAttach():当Fragment和Activity建立关联时调用;
  • onCreateView():当fragment创建视图调用,在onCreate之后;
  • onActivityCreated():当与Fragment相关联的Activity完成onCreate()之后调用;
  • onDestroyView():在Fragment中的布局被移除时调用;
  • onDetach():当Fragment和Activity解除关联时调用;

6.Service生命周期                                                                                                   

  • onCreate()       首次创建服务时,系统将调用此方法。如果服务已在运行,则不会调用此方法,该方法只调用一次。
  • onStartCommand()         当另一个组件通过调用startService()请求启动服务时,系统将调用此方法。
  • onDestroy()         当服务不再使用且将被销毁时,系统将调用此方法。
  • onBind()          当另一个组件通过调用bindService()与服务绑定时,系统将调用此方法。
  • onUnbind()      当另一个组件通过调用unbindService()与服务解绑时,系统将调用此方法。
  • onRebind()      当旧的组件与服务解绑后,另一个新的组件与服务绑定,onUnbind()返回true时,系统将调用此方法。

7.Service的两种启动方式?区别在哪?

  • startService():通过这种方式调用startService,onCreate()只会被调用一次,多次调用startSercie会多次执行onStartCommand()和onStart()方法。如果外部没有调用stopService()或stopSelf()方法,service会一直运行。
  • bindService():如果该服务之前还没创建,系统回调顺序为onCreate()→onBind()。如果调用bindService()方法前服务已经被绑定,多次调用bindService()方法不会多次创建服务及绑定。如果调用者希望与正在绑定的服务解除绑定,可以调用unbindService()方法,回调顺序为onUnbind()→onDestroy();

8.广播有几种形式 ? 都有什么特点 ?

  •  普通广播:开发者自身定义 intent的广播(最常用),所有的广播接收器几乎会在同一时刻接受到此广播信息,接受的先后顺序随机;
  • 有序广播:发送出去的广播被广播接收者按照先后顺序接收,同一时刻只会有一个广播接收器能够收到这条广播消息,当这个广播接收器中的逻辑执行完毕后,广播才会继续传递,且优先级(priority)高的广播接收器会先收到广播消息。有序广播可以被接收器截断使得后面的接收器无法收到它;
  • 本地广播:仅在自己的应用内发送接收广播,也就是只有自己的应用能收到,数据更加安全,效率更高,但只能采用动态注册的方式;
  • 粘性广播:这种广播会一直滞留,当有匹配该广播的接收器被注册后,该接收器就会收到此条广播;

9.BroadcastReceiver注册方式与区别 

10.Android中IPC方式、各种方式优缺点,为什么选择Binder?

Binder好在哪呢?

传输效率高、可操作性强、实现C/S架构方便、安全性高

11.Binder机制的作用?

Linux系统将一个进程分为用户空间内核空间。对于进程之间来说,用户空间的数据不可共享,内核空间的数据可共享,为了保证安全性和独立性,一个进程不能直接操作或者访问另一个进程,即Android的进程是相互独立、隔离的,这就需要跨进程之间的数据通信方式。

12.介绍下实现一个自定义View的基本流程

  • View的工作流程主要是指measure、layout、draw这三大流程,即测量、布局和绘制,其中measure确定View的测量宽/高,layout确定View的最终宽/高四个顶点的位置,而draw则将View绘制到屏幕
  • View的绘制过程遵循如下几步:
    • 绘制背景 background.draw(canvas)
    • 绘制自己(onDraw)
    • 绘制 children(dispatchDraw)
    • 绘制装饰(onDrawScollBars)

13.什么是ANR ? 什么情况会出现ANR ?如何避免 ? 在不看代码的情况下如何快速定位出现ANR问题所在 ?

  • ANR(Application Not Responding,应用无响应):当操作在一段时间内系统无法处理时,会在系统层面会弹出ANR对话框
  • 产生ANR可能是因为5s内无响应用户输入事件、10s内未结束BroadcastReceiver、20s内未结束Service
  • 想要避免ANR就不要在主线程做耗时操作,而是通过开子线程,方法比如继承Thread或实现Runnable接口、使用AsyncTask、IntentService、HandlerThread等
  • Process:anr发生的时间和进程,和生成traces文件的时间
    CPUusage ... ago :cpu在anr发生前的使用情况
    CPUusage ...later: cpu在anr后的使用情况
    ABI:         手机的cpu架构
    HEAP:     堆的内存信息
    ANR in: 包名,和类名
    Reason:原因
    TOTAL:总的CPU使用率
    prio:线程的优先级
    tid:线程锁id  主线程的id为1  主要看这个线程的
    Sleeping:线程的状态
    sCount:线程被挂起的次数
    dsCount:线程是否被调试
  • 典型的分析情况

    1.如果TOTAL(总的cpu使用频率)的和接近100,有可能是因为当前使用的app占用的cpu太高,导致系统将你的杀死。
    2.如果TOTAL很小,则说明线程被阻塞了,主线程在等待下条消息的进入,任务在等待时anr。
    3.如果ioWait很高,则说明是io操作导致的

推荐文章:如何快速分析定位ANR

14.线程sleep和wait有什么区别 

   功能差不多,都用来进行线程控制,他们最大本质的区别是:sleep()不释放同步锁,wait()释放同步锁.   
   还有用法的上的不同是:sleep(milliseconds)可以用时间指定来使他自动醒过来,如果时间不到你只能调用interreput()来强行打断;wait()可以用notify()直接唤起.

15.如何优化ListView(偶尔会问)

  • ①Item布局,层级越少越好,使用hierarchyview工具查看优化。
  • ②复用convertView
  • ③使用ViewHolder
  • ④item中有图片时,异步加载
  • ⑤快速滑动时,不加载图片
  • ⑥item中有图片时,应对图片进行适当压缩
  • ⑦实现数据的分页加载

16.RecyclerView和ListView的区别(这个是必问的)

  •   RecyclerView可以完成ListView,GridView的效果,还可以完成瀑布流的效果。同时还可以设置列表的滚动方向(垂直或者水平);
  •   RecyclerView中view的复用不需要开发者自己写代码,系统已经帮封装完成了。
  •   RecyclerView可以进行局部刷新。
  •  RecyclerView提供了API来实现item的动画效果。

   在性能上:
   如果需要频繁的刷新数据,需要添加动画,则RecyclerView有较大的优势。
   如果只是作为列表展示,则两者区别并不是很大。

17.Android异步消息处理机制(这个也会经常问到)

异步消息处理机制主要是用来解决子线程更新UI的问题

主要有四个部分:
①. Message (消息)
在线程之间传递,可在内部携带少量信息,用于不同线程之间交换数据
可以使用what、arg1、arg2字段携带整型数据
obj字段携带Object对象
②. Handler (处理者)
主要用于发送和处理消息,sendMessage()用来发送消息,最终会回到handleMessage()进行处理
③. MessageQueue (消息队列)
主要存放所有通过Handler发送的消息,它们会一直存在于队列中等待被处理
每个线程只有一个MessageQueue
④. Looper (循环器)
调用loop()方法后,会不断从MessageQueue 取出待处理的消息,然后传递到handleMessage进行处理.


18.内存泄漏和内存溢出是什么?一般怎么处理内存泄漏?

  • 内存溢出 out of memory:是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory;比如申请了一个integer,但给它存了long才能存下的数,那就是内存溢出。内存溢出通俗的讲就是内存不够用。
  • 内存泄露 memory leak:是指程序在申请内存后,无法释放已申请的内存空间,一次内存泄露危害可以忽略,但内存泄露堆积后果很严重,无论多少内存,迟早会被占光

内存泄露原因以及解决:
一、Handler 引起的内存泄漏。
解决:将Handler声明为静态内部类,就不会持有外部类SecondActivity的引用,其生命周期就和外部类无关,
如果Handler里面需要context的话,可以通过弱引用方式引用外部类
二、单例模式引起的内存泄漏。
解决:Context是ApplicationContext,由于ApplicationContext的生命周期是和app一致的,不会导致内存泄漏
三、非静态内部类创建静态实例引起的内存泄漏。
解决:把内部类修改为静态的就可以避免内存泄漏了
四、非静态匿名内部类引起的内存泄漏。
解决:将匿名内部类设置为静态的。
五、注册/反注册未成对使用引起的内存泄漏。
注册广播接受器、EventBus等,记得解绑。
六、资源对象没有关闭引起的内存泄漏。
在这些资源不使用的时候,记得调用相应的类似close()、destroy()、recycler()、release()等方法释放。
七、集合对象没有及时清理引起的内存泄漏。
通常会把一些对象装入到集合中,当不使用的时候一定要记得及时清理集合,让相关对象不再被引用。


19.Android_三级缓存原理?

三级缓存:
内存缓存
本地缓存(SD卡缓存)
网络缓存
     缓存顺序:首先从网络获取图片资源,然后将当前的图片缓存到本地,然后再缓存到内存中,那么下次访问图片资源就会优先从内存获取图片资源,如果内存中没有那么再去本地获取图片资源,如果本地还是没有,那么再从网络获取图片资源。

三级缓存

                      特点

内存缓存

  1. 访问内存速度最快   2.不浪费流量

本地缓存

  1. 访问速度中等          2.不浪费流量

网络缓存

  1. 访问速度慢              2.浪费流量 

 

 

 

 

 

 

 

 

网络缓存:
        网络缓存顾名思义就是从网络获取图片资源,然后来进行显示,那么我们可以通过AsyncTask来异步处理网络请求,然后主线程设置图片。

本地缓存:
        当从网络获取图片以后,可以将当前的图片进行压缩并且写入到本地文件中进行存储,下次显示图片时优先从本地文件中读取图片进行显示,如果没有才会去网络获取图片资源。

内存缓存:
        当从网络获取图片以后,可以将当前的图片存放进内存中,其中使用到了LruCache进行优化处理

20.JNI?

  • Java的优点是跨平台,但也因为其跨平台的的特性导致其本地交互的能力不够强大,一些和操作系统相关的的特性Java无法完成,于是Java提供JNI专门用于和本地代码交互,通过JNI,用户可以调用C、C++编写的本地代码
  • NDK是Android所提供的一个工具集合,通过NDK可以在Android中更加方便地通过JNI访问本地代码,其优点在于
    • 提高代码的安全性。由于so库反编译困难,因此NDK提高了Android程序的安全性
    • 可以很方便地使用目前已有的C/C++开源库
    • 便于平台的移植。通过C/C++实现的动态库可以很方便地在其它平台上使用
    • 提高程序在某些特定情形下的执行效率,但是并不能明显提升Android程序的性能

20-1.你用JNI来实现过什么功能 ? 怎么实现的 ?(加密处理、影音方面、图形图像处理)

Android JNI编程—JNI基础

Android JNI 篇 - ffmpeg 获取音视频缩略图

21.你所知道的设计模式有哪些?

  • 创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。
  • 结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
  • 行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录 模式、状态模式、访问者模式、中介者模式、解释器模式。

22.谈谈MVC、MVP和MVVM,好在哪里,不好在哪里 ?

  • MVC:
    • 视图层(View) 对应于xml布局文件和java代码动态view部分
    • 控制层(Controller) MVC中Android的控制层是由Activity来承担的,Activity本来主要是作为初始化页面,展示数据的操作,但是因为XML视图功能太弱,所以Activity既要负责视图的显示又要加入控制逻辑,承担的功能过多。
    • 模型层(Model) 针对业务模型,建立数据结构和相关的类,它主要负责网络请求,数据库处理,I/O的操作。
  • 总结
    • 具有一定的分层,model彻底解耦,controller和view并没有解耦层与层之间的交互尽量使用回调或者去使用消息机制去完成,尽量避免直接持有 controller和view在android中无法做到彻底分离,但在代码逻辑层面一定要分清业务逻辑被放置在model层,能够更好的复用和修改增加业务。
  • MVP
    • 通过引入接口BaseView,让相应的视图组件如Activity,Fragment去实现BaseView,实现了视图层的独立,通过中间层Preseter实现了Model和View的完全解耦。MVP彻底解决了MVC中View和Controller傻傻分不清楚的问题,但是随着业务逻辑的增加,一个页面可能会非常复杂,UI的改变是非常多,会有非常多的case,这样就会造成View的接口会很庞大。
  • MVVM
    • MVP中我们说过随着业务逻辑的增加,UI的改变多的情况下,会有非常多的跟UI相关的case,这样就会造成View的接口会很庞大。而MVVM就解决了这个问题,通过双向绑定的机制,实现数据和UI内容,只要想改其中一方,另一方都能够及时更新的一种设计理念,这样就省去了很多在View层中写很多case的情况,只需要改变数据就行。
  • 三者如何选择?
    • 如果项目简单,没什么复杂性,未来改动也不大的话,那就不要用设计模式或者架构方法,只需要将每个模块封装好,方便调用即可,不要为了使用设计模式或架构方法而使用。
    • 对于偏向展示型的app,绝大多数业务逻辑都在后端,app主要功能就是展示数据,交互等,建议使用mvvm。
    • 对于工具类或者需要写很多业务逻辑app,使用mvp或者mvvm都可。

23.是否能从Android中举几个例子说说用到了什么设计模式 ?

  • AlertDialog、Notification源码中使用了Builder(建造者)模式完成参数的初始化
  • Okhttp内部使用了责任链模式来完成每个Interceptor拦截器的调用
  • RxJava的观察者模式;单例模式;GridView的适配器模式;Intent的原型模式
  • 日常开发的BaseActivity抽象工厂模式

24.用到的一些开源框架,介绍一个看过源码的,内部实现过程。

25.String,Stringbuffer,Stringbuilder 区别 

https://blog.csdn.net/kingzone_2008/article/details/9220691

26.使用过什么图片加载库?Glide的源码设计哪里很微妙?

  • 图片加载库:Fresco、Glide、Picasso
  • Glide的设计微妙在于:
    • Glide的生命周期绑定:可以控制图片的加载状态与当前页面的生命周期同步,使整个加载过程随着页面的状态而启动/恢复,停止,销毁
    • Glide的缓存设计:通过(三级缓存,Lru算法,Bitmap复用)对Resource进行缓存设计
    • Glide的完整加载过程:采用Engine引擎类暴露了一系列方法供Request操作

26-1.图片加载框架有哪些?他们之间的区别是什么?(这个也是必问的)

ImageLoader :
优点:
① 支持下载进度监听;
② 可以在 View 滚动中暂停图片加载;
③ 默认实现多种内存缓存算法这几个图片缓存都可以配置缓存算法,不过 ImageLoader 默认实现了较多缓存算法,如 Size 最大先删除、使用最少先删除、最近最少使用、先进先删除、时间最长先删除等;
④ 支持本地缓存文件名规则定义;
缺点:
缺点在于不支持GIF图片加载, 缓存机制没有和http的缓存很好的结合, 完全是自己的一套缓存机制

Picasso:
优点:
① 自带统计监控功能,支持图片缓存使用的监控,包括缓存命中率、已使用内存大小、节省的流量等。
② 支持优先级处理
③ 支持延迟到图片尺寸计算完成加载
④ 支持飞行模式、并发线程数根据网络类型而变,手机切换到飞行模式或网络类型变换时会自动调整线程池最大并发数。
⑤ “无”本地缓存。Picasso 自己没有实现本地缓存,而由okhttp 去实现,这样的好处是可以通过请求 Response Header 中的 Cache-Control 及 Expired 控制图片的过期时间。
缺点:
于不支持GIF,默认使用ARGB_8888格式缓存图片,缓存体积大。

Glide:
优点:
① 图片缓存->媒体缓存 ,支持 Gif、WebP、缩略图。甚至是 Video。
② 支持优先级处理
③ 与 Activity/Fragment 生命周期一致,支持 trimMemory
④ 支持 okhttp、Volley。Glide 默认通过 UrlConnection 获取数据,可以配合 okhttp 或是 Volley 使用。实际 ImageLoader、Picasso 也都支持 okhttp、Volley。
⑤ 内存友好,内存缓存更小图片,图片默认使用默认 RGB565 而不是 ARGB888
缺点:
清晰度差,但可以设置

Fresco:

优点:

① 图片存储在安卓系统的匿名共享内存, 而不是虚拟机的堆内存中,所以不会因为图片加载而导致oom, 同时也减少垃圾回收器频繁调用回收Bitmap导致的界面卡顿,性能更高.
② 渐进式加载JPEG图片, 支持图片从模糊到清晰加载
③ 图片可以以任意的中心点显示在ImageView, 而不仅仅是图片的中心.
④ JPEG图片改变大小也是在native进行的, 不是在虚拟机的堆内存, 同样减少OOM
⑤ 很好的支持GIF图片的显示
缺点:
框架较大, 影响Apk体积,使用较繁琐

27.HTTPS和HTTP的区别

https和http的区别

28.手写算法(选择冒泡必须要会) 

https://www.jianshu.com/p/ae97c3ceea8d

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值