词条信息

admin
admin
超级管理员
词条创建者 发短消息   

相关词条

热门词条

更多>>
什么是端口?到底是做什么的呢?
端口一般指两种,一种是硬件比如路由器或者交换机的插网线的端口,一种是软件的逻辑的概念,比如http的80端口!...
7种进阶方法让你快速测试端口连通性
Ping是Windows、Linux和Unix系统下的一个检查网络连通性的命令工具,对于大部分互联网用户来说很...
电脑开机,总需要按F1,是什么原因造成的?
一.主板掉电这个说法是行业内的叫法了,一般是主板的CMOS电池没电了导致的。也是最常见的一种提示你按F1的提示...
社保降费对个人有什么影响?
下调城镇职工基本养老保险单位缴费比例是政府给企业发的一个大红包,特别是对于企业来说是一个利好,但是对个人来说有...
车辆“出险”对下年保费的影响,到底有多大?
【出险对交强险的影响】【出险对商业险的影响】车辆“出险”对下年保费的影响,到底有多大?这里有必要先提下车险第三...

精选图集

更多>>
简易百科旧版 >>所属分类 >> 其它知识    职场   

2019校招Android面试题解

标签: Android 面试题解

顶[0] 发表评论(0) 编辑词条

题解乃见仁见智之事,以下只是自己的看法,仅供参考,因本人水平有限,如有问题欢迎指正。

之所以是题解1.0,是希望随着学习的深入,以后能更深刻的理解,再出个题解2.0最好不过了。

以下为作者文章中部分内容。

2、View 相关题解

Q:MotionEvent是什么?包含几种事件?什么条件下会产生?

技术点:View触控

参考回答:MotionEvent是手指触摸屏幕锁产生的一系列事件。包含的事件有:

  • ACTION_DOWN:手指刚接触屏幕
  • ACTION_MOVE:手指在屏幕上滑动
  • ACTION_UP:手指在屏幕上松开的一瞬间
  • ACTION_CANCEL:手指保持按下操作,并从当前控件转移到外层控件时会触发

Q:scrollTo()和scrollBy()的区别?

技术点:View滑动

参考回答:scrollBy内部调用了scrollTo,它是基于当前位置的相对滑动;而scrollTo是绝对滑动,因此如果利用相同输入参数多次调用scrollTo()方法,由于View初始位置是不变只会出现一次View滚动的效果而不是多次。

引申:两者都只能对view内容进行滑动,而不能使view本身滑动,且非平滑,可使用Scroller有过渡滑动的效果

Q:Scroller中最重要的两个方法是什么?主要目的是?

技术点:View滑动

思路:从Scroller实现滑动的具体过程出发,

参考回答:Scroller实现滑动的具体过程:

  • 在MotionEvent.ACTION_UP事件触发时调用startScroll()方法,该方法并没有进行实际的滑动操作,而是记录滑动相关量
  • 马上调用invalidate/postInvalidate()方法,请求View重绘,导致View.draw方法被执行
  • 紧接着会调用View.computeScroll()方法,此方法是空实现,需要自己处理逻辑。具体逻辑是:先判断computeScrollOffset(),若为true(表示滚动未结束),则执行scrollTo()方法,它会再次调用postInvalidate(),如此反复执行,直到返回值为false。流程图如下:

其中,最重要的两个方法是startScroll()和computeScroll()

Q:谈一谈View的事件分发机制?

技术点:View事件分发

思路:从分发本质、传递顺序、核心方法展开

参考回答:

事件分发本质:就是对MotionEvent事件分发的过程。即当一个MotionEvent产生了以后,系统需要将这个点击事件传递到一个具体的View上。

点击事件的传递顺序:Activity(Window) -> ViewGroup -> View

三个主要方法:

  • dispatchTouchEvent:进行事件的分发(传递)。返回值是 boolean 类型,受当前onTouchEvent和下级view的dispatchTouchEvent影响
  • onInterceptTouchEvent:对事件进行拦截。该方法只在ViewGroup中有,View(不包含 ViewGroup)是没有的。一旦拦截,则执行ViewGroup的onTouchEvent,在ViewGroup中处理事件,而不接着分发给View。且只调用一次,所以后面的事件都会交给ViewGroup处理。
  • onTouchEvent:进行事件处理。

Q:如何解决View的滑动冲突?

技术点:View滑动冲突

思路:从处理规则和具体实现方法展开讨论

参考回答:

(1)处理规则:

  • 对于由于外部滑动和内部滑动方向不一致导致的滑动冲突,可以根据滑动的方向判断谁来拦截事件。
  • 对于由于外部滑动方向和内部滑动方向一致导致的滑动冲突,可以根据业务需求,规定何时让外部View拦截事件何时由内部View拦截事件。
  • 对于上面两种情况的嵌套,相对复杂,可同样根据需求在业务上找到突破点。

(2)实现方法:

  • 外部拦截法:指点击事件都先经过父容器的拦截处理,如果父容器需要此事件就拦截,否则就不拦截。具体方法:需要重写父容器的onInterceptTouchEvent方法,在内部做出相应的拦截。
  • 内部拦截法:指父容器不拦截任何事件,而将所有的事件都传递给子容器,如果子容器需要此事件就直接消耗,否则就交由父容器进行处理。具体方法:需要配合requestDisallowInterceptTouchEvent方法。

Q:谈一谈View的工作原理?

技术点:View工作流程

思路:围绕三大流程展开

参考回答:View工作流程简单来说就是,先measure测量,用于确定View的测量宽高,再 layout布局,用于确定View的最终宽高和四个顶点的位置,最后 draw绘制,用于将View 绘制到屏幕上。具体过程图见:

ViewRoot对应于ViewRootImpl类,它是连接WindowManager和DecorView的纽带。

View的绘制流程是从ViewRoot和performTraversals开始。

performTraversals()依次调用performMeasure()、performLayout()和performDraw()三个方法,分别完成顶级 View的绘制。

其中,performMeasure()会调用measure(),measure()中又调用onMeasure(),实现对其所有子元素的measure过程,这样就完成了一次measure过程;接着子元素会重复父容器的measure过程,如此反复至完成整个View树的遍历。layout和draw同理。

Q:MeasureSpec是什么?有什么作用?

技术点:View工作流程(measure)

思路:从MeasureSpec作用、组成、模式和决定因素展开

参考回答:

作用:通过宽测量值widthMeasureSpec和高测量值heightMeasureSpec决定View的大小

组成:一个32位int值,高2位代表SpecMode(测量模式),低30位代表SpecSize( 某种测量模式下的规格大小)。

三种模式:

  • UNSPECIFIED:父容器不对View有任何限制,要多大有多大。常用于系统内部。
  • EXACTLY(精确模式):父视图为子视图指定一个确切的尺寸SpecSize。对应LyaoutParams中的match_parent或具体数值。
  • AT_MOST(最大模式):父容器为子视图指定一个最大尺寸SpecSize,View的大小不能大于这个值。对应LayoutParams中的wrap_content。

决定因素:值由子View的布局参数LayoutParams和父容器的MeasureSpec值共同决定。具体规则见下图:

引申:直接继承View的自定义View需要重写onMeasure()并设置wrap_content时的自身大小,否则效果相当于macth_parent。

Q:自定义View/ViewGroup需要注意什么?

技术点:自定义View

参考回答:

Q:onTouch()、onTouchEvent()和onClick()关系?

技术点:View事件分发

参考回答:优先度onTouch()>onTouchEvent()>onClick()。因此onTouchListener的onTouch()方法会先触发;如果onTouch()返回false才会接着触发onTouchEvent(),同样的,内置诸如onClick()事件的实现等等都基于onTouchEvent();如果onTouch()返回true,这些事件将不会被触发。

引申:OnTouchListener、OnClickListener的冲突

Q:SurfaceView和View的区别?

技术点:View、SurfaceView

参考回答:SurfaceView是从View基类中派生出来的显示类,他和View的区别有:

  • View需要在UI线程对画面进行刷新,而SurfaceView可在子线程进行页面的刷新
  • View适用于主动更新的情况,而SurfaceView适用于被动更新,如频繁刷新,这是因为如果使用View频繁刷新会阻塞主线程,导致界面卡顿
  • SurfaceView在底层已实现双缓冲机制,而View没有,因此SurfaceView更适用于需要频繁刷新、刷新时数据处理量很大的页面

Q:invalidate()和postInvalidate()的区别?

技术点:View刷新

参考回答:invalidate()与postInvalidate()都用于刷新View,主要区别是invalidate()在主线程中调用,若在子线程中使用需要配合handler;而postInvalidate()可在子线程中直接调用。

3、线程相关题解

Q:Android中还了解哪些方便线程切换的类?

技术点:线程通信

参考回答:对Handler进一步的封装的几个类:

  • AsyncTask:底层封装了线程池和Handler,便于执行后台任务以及在子线程中进行UI操作。
  • HandlerThread:一种具有消息循环的线程,其内部可使用Handler。
  • IntentService:是一种异步、会自动停止的服务,内部采用HandlerThread。

引申:更多是对消息机制的理解

Q:AsyncTask相比Handler有什么优点?不足呢?

技术点:AsyncTask、Handler

参考回答:

Handler机制存在的问题:多任务同时执行时不易精确控制线程。

引入AsyncTask的好处:创建异步任务更简单,直接继承它可方便实现后台异步任务的执行和进度的回调更新UI,而无需编写任务线程和Handler实例就能完成相同的任务。

Q:使用AsyncTask需要注意什么?

技术点:AsyncTask

参考回答:

  • 不要直接调用onPreExecute()、doInBackground()、onProgressUpdate()、onPostExecute()和onCancelled()方法
  • 一个异步对象只能调用一次execute()方法

引申:谈谈AsyncTask初始化、五个核心方法如何配合进而体现Handler的作用

Q:AsyncTask中使用的线程池大小?

技术点:AsyncTask

参考回答:在AsyncTask内部实现有两个线程池:

  • SerialExecutor:用于任务的排队,默认是串行的线程池,在3.0以前核心线程数为5、线程池大小为128,而3.0以后变为同一时间只能处理一个任务
  • THREAD_POOL_EXECUTOR:用于真正执行任务。

引申:谈谈对线程池的理解

Q:HandlerThread有什么特点?

技术点:HandlerThread

参考回答:HandlerThread是一个线程类,它继承自Thread。与普通Thread不同,HandlerThread具有消息循环的效果,这是因为它内部HandlerThread.run()方法中有Looper,能通过Looper.prepare()来创建消息队列,并通过Looper.loop()来开启消息循环。

Q:快速实现子线程使用Handler

技术点:HandlerThread

思路:不同于之前手动在子线程创建Looper再构建Handler的想法,这里从HandlerThread角度去快速实现在子线程使用Handler

参考回答:HandlerThread实现方法

  • 实例化一个HandlerThread对象,参数是该线程的名称;
  • 通过 HandlerThread.start()开启线程;
  • 实例化一个Handler并传入HandlerThread中的looper对象,使得与HandlerThread绑定;
  • 利用Handler即可执行异步任务;
  • 当不需要HandlerThread时,通过HandlerThread.quit()/quitSafely()方法来终止线程的执行。

Q:IntentService的特点?

技术点:IntentService

思路:和普通线程和普通Service比较突出其特点

参考回答: 不同于线程,IntentService是服务,优先级比线程高,更不容易被系统杀死,因此较适合执行一些高优先级的后台任务;不同于普通Service,IntentService可自动创建子线程来执行任务,且任务执行完毕后自动退出。

Q:为何不用bindService方式创建IntentService?

技术点:IntentService

思路:从底层实现出发

参考回答:IntentService的工作原理是,在IntentService的onCreate()里会创建一个HandlerThread,并利用其内部的Looper实例化一个ServiceHandler对象;而这个ServiceHandler用于处理消息的handleMessage()方法会去调用IntentService的onHandleIntent(),这也是为什么可在该方法中处理后台任务的逻辑;当有Intent任务请求时会把Intent封装到Message,然后ServiceHandler会把消息发送出,而发送消息是在onStartCommand()完成的,只能通过startService()才可走该生命周期方法,因此不能通过bindService创建IntentService。

Q:线程池的好处、原理、类型?

技术点:线程池

参考回答:

(1)线程池的好处:

  • 重用线程池中的线程,避免线程的创建和销毁带来的性能消耗;
  • 有效控制线程池的最大并发数,避免大量的线程之间因互相抢占系统资源而导致阻塞现象;
  • 进行线程管理,提供定时/循环间隔执行等功能

(2)线程池的分类:

  • FixThreadPool:线程数量固定的线程池,所有线程都是核心线程,当线程空闲时不会被回收;能快速响应外界请求。
  • CachedThreadPool:线程数量不定的线程池(最大线程数为Integer.MAX_VALUE),只有非核心线程,空闲线程有超时机制,超时回收;适合于执行大量的耗时较少的任务
  • ScheduledThreadPool:核心线程数量固定,非核心线程数量不定;可进行定时任务和固定周期的任务。
  • SingleThreadExecutor:只有一个核心线程,可确保所有的任务都在同一个线程中按顺序执行;好处是无需处理线程同步问题。

(3)线程池的原理:实际上通过ThreadPoolExecutor并通过一系列参数来配置各种各样的线程池,具体的参数有:

  • corePoolSize核心线程数:一般会在线程中一直存活
  • maximumPoolSize最大线程数:当活动线程数达到这个数值后,后续的任务将会被阻塞keepAliveTime非核心线程超时时间:超过这个时长,闲置的非核心线程就会被回收
  • unit:用于指定keepAliveTime参数的时间单位
  • workQueue任务队列:通过线程池的execute()方法提交的Runnable对象会存储在这个参数中。
  • threadFactory:线程工厂,可创建新线程
  • handler:在线程池无法执行新任务时进行调度

引申:使用Executors各个方法创建线程池的弊端

https://www.jianshu.com/p/4b89d681c5a0

Q:ThreadPoolExecutor的工作策略?

技术点:线程池

参考回答:ThreadPoolExecutor的默认工作策略:

  • 若任务无法插入到任务列表中,往往由于任务列表已满,此时如果
  • 线程数量未达到线程池最大线程数,则会启动一个非核心线程执行任务;
  • 线程数量已达到线程池规定的最大值,则拒绝执行此任务,ThreadPoolExecutor会调用RejectedExecutionHandler的rejectedExecution方法来通知调用者。
  • 若程池中的线程数量未达到核心线程数,则会直接启动一个核心线程执行任务。
  • 若线程池中的线程数量已达到或者超过核心线程数量,则任务会被插入到任务列表等待执行。

引申:ThreadPoolExecutor的拒绝策略

4、IPC相关题解

Q:Android中进程和线程的关系?

技术点:进程、线程

参考回答:

  • 一般对应一个进程,当然,可以在AndroidMenifest中给四大组件指定属性android:process开启多进程模式
  • 有限个线程:线程是一种受限的系统资源,不可无限制的产生且线程的创建和销毁都有一定的开销。
  • 形象理解:如果把安卓系统比喻成一片土壤,可以把App看做扎根在这片土壤上的工厂,每个APP一般对应一个进程,那么线程就像是工厂的生产线。其中,主线程好比是主生产线,只有一条,子线程就像是副生产线,可以有很多条。
  • 关系:一个APP一般对应一个进程和有限个线程

Q:为何需要进行IPC?多进程通信可能会出现什么问题?

技术点:多进程通信

思路:讨论多进程通信会出现的问题得出IPC的必要性

参考回答:

(1)多进程造成的影响可总结为以下四方面:

  • 静态变量和单例模式失效:由独立的虚拟机造成
  • 线程同步机制失效:由独立的虚拟机造成
  • SharedPreference的不可靠下降:不支持两个进程同时进行读写操作,即不支持并发读写,有一定几率导致数据丢失
  • Application多次创建: Android系统会为新的进程分配独立虚拟机,相当于系统又把这个应用重新启动了一次。

(2)需要进程间通信的必要性:所有运行在不同进程的四大组件,只要它们之间需要通过内存在共享数据,都会共享失败。这是由于Android为每个应用分配了独立的虚拟机,不同的虚拟机在内存分配上有不同的地址空间,这会导致在不同的虚拟机中访问同一个类的对象会产生多份副本。

引申: 谈谈IPC的使用场景

Q:什么是序列化?Serializable接口和Parcelable接口的区别?为何推荐使用后者?

技术点:序列化

参考回答:序列化表示将一个对象转换成可存储或可传输的状态。序列化后的对象可以在网络上进行传输,也可以存储到本地。

应用场景:需要通过Intent和Binder等传输类对象就必须完成对象的序列化过程。

两种方式:实现Serializable/Parcelable接口。不同点如图:

Q:Android中为何新增Binder来作为主要的IPC方式?

技术点:Binder机制

思路:回答Binder优点

参考回答:Binder机制有什么几条优点:

1. 传输效率高、可操作性强:传输效率主要影响因素是内存拷贝的次数,拷贝次数越少,传输速率越高。从Android进程架构角度分析:对于消息队列、Socket和管道来说,数据先从发送方的缓存区拷贝到内核开辟的缓存区中,再从内核缓存区拷贝到接收方的缓存区,一共两次拷贝,如图:

而对于Binder来说,数据从发送方的缓存区拷贝到内核的缓存区,而接收方的缓存区与内核的缓存区是映射到同一块物理地址的,节省了一次数据拷贝的过程,如图:

由于共享内存操作复杂,综合来看,Binder的传输效率是最好的。

2. 实现C/S架构方便:Linux的众IPC方式除了Socket以外都不是基于C/S架构,而Socket主要用于网络间的通信且传输效率较低。Binder基于C/S架构 ,Server端与Client端相对独立,稳定性较好。

3. 安全性高:传统Linux IPC的接收方无法获得对方进程可靠的UID/PID,从而无法鉴别对方身份;而Binder机制为每个进程分配了UID/PID且在Binder通信时会根据UID/PID进行有效性检测。

Q:使用Binder进行数据传输的具体过程?

技术点:Binder机制

思路:通过AIDL实现方式解释Binder数据传输的具体过程

参考回答:服务端中的Service给与其绑定的客户端提供Binder对象,客户端通过AIDL接口中的asInterface()将这个Binder对象转换为代理Proxy,并通过它发起RPC请求。客户端发起请求时会挂起当前线程,并将参数写入data然后调用transact(),RPC请求会通过系统底层封装后由服务端的onTransact()处理,并将结果写入reply,最后返回调用结果并唤醒客户端线程。

Q:Binder框架中ServiceManager的作用?

技术点:Binder机制

思路:从Binder框架出发讨论每个元素的作用

参考回答:在Binder框架定义了四个角色:Server,Client,ServiceManager和Binder驱动。其中Server、Client、ServiceManager运行于用户空间,Binder驱动运行于内核空间。关系如图:

  • Server&Client:服务器&客户端。在Binder驱动和Service Manager提供的基础设施上,进行Client-Server之间的通信。
  • ServiceManager服务的管理者,将Binder名字转换为Client中对该Binder的引用,使得Client可以通过Binder名字获得Server中Binder实体的引用。流程如图:

Binder驱动:

  • 与硬件设备没有关系,其工作方式与设备驱动程序是一样的,工作于内核态。
  • 提供open()、mmap()、poll()、ioctl() 等标准文件操作。
  • 以字符驱动设备中的misc设备注册在设备目录/dev下,用户通过/dev/binder访问该它。
  • 负责进程之间binder通信的建立,传递,计数管理以及数据的传递交互等底层支持。
  • 驱动和应用程序之间定义了一套接口协议,主要功能由ioctl() 接口实现,由于ioctl()灵活、方便且能够一次调用实现先写后读以满足同步交互,因此不必分别调用write()和read()接口。
  • 其代码位于linux目录的drivers/misc/binder.c中。

Q:Android中有哪些基于Binder的IPC方式?简单对比下?

技术点:IPC方式

思路:分析每种IPC方式的优缺点和使用场景的差异

参考回答:

Q:是否了解AIDL?原理是什么?如何优化多模块都使用AIDL的情况?

技术点:AIDL

参考回答:

工作原理:每个业务模块创建自己的AIDL接口并实现此接口,然后向服务端提供自己的唯一标识和其对应的Binder对象。服务端只需要一个Service,服务器提供一个queryBinder接口,它会根据业务模块的特征来返回相应的Binder对像,不同的业务模块拿到所需的Binder对象后就可进行远程方法的调用了。

流程如图:

  • AIDL接口:继承IInterface。
  • Stub类:Binder的实现类,服务端通过这个类来提供服务。
  • Proxy类:服务器的本地代理,客户端通过这个类调用服务器的方法。
  • asInterface():客户端调用,将服务端的返回的Binder对象,转换成客户端所需要的AIDL接口类型对象。返回对象。
  • asBinder():根据当前调用情况返回代理Proxy的Binder对象。
  • onTransact():运行服务端的Binder线程池中,当客户端发起跨进程请求时,远程请求会通过系统底层封装后交由此方法来处理。
  • transact():运行在客户端,当客户端发起远程请求的同时将当前线程挂起。之后调用服务端的onTransact()直到远程请求返回,当前线程才继续执行。
  • 若客户端和服务端位于同一进程,则直接返回Stub对象本身;
  • 否则,返回的是系统封装后的Stub.proxy对象。
  • AIDL(Android Interface Definition Language,Android接口定义语言):如果在一个进程中要调用另一个进程中对象的方法,可使用AIDL生成可序列化的参数,AIDL会生成一个服务端对象的代理类,通过它客户端实现间接调用服务端对象的方法。
  • AIDL的本质是系统提供了一套可快速实现Binder的工具。关键类和方法:当有多个业务模块都需要AIDL来进行IPC,此时需要为每个模块创建特定的aidl文件,那么相应的Service就会很多。必然会出现系统资源耗费严重、应用过度重量级的问题。解决办法是建立Binder连接池,即将每个业务模块的Binder请求统一转发到一个远程Service中去执行,从而避免重复创建Service。

由于篇幅原因,以上仅为一小部分,原文非常长,各位刻意仔细阅读作者原文。

下面三篇该为面试总结题解了:

2019 Android 秋招提前批面试总结

  • 2019校招Android面试题解1.0(上篇) https://www.jianshu.com/p/718aa3c1a70b
  • 2019校招Android面试题解1.0(中篇) https://www.jianshu.com/p/2dd855aa1938
  • 2019校招Android面试题解1.0(下篇) https://www.jianshu.com/p/168e52336b53

 

 

附件列表


按字母顺序浏览:A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

→我们致力于为广大网民解决所遇到的各种电脑技术问题
 如果您认为本词条还有待完善,请 编辑词条

上一篇网站为什么需要部署SSL证书实现HTTPS
下一篇Android 架构组件之 ViewModel

0
1. 本站部分内容来自互联网,如有任何版权侵犯或其他问题请与我们联系,我们将立即删除或处理。
2. 本站内容仅供参考,如果您需要解决具体问题,建议您咨询相关领域专业人士。
3. 如果您没有找到需要的百科词条,您可以到百科问答提问或创建词条,等待高手解答。

关于本词条的提问

查看全部/我要提问>>