作为一名面试者你应该知道的【上 - 带大厂面试题】,android 组件化开发与 sdk
②Service 的两种启动方式简要介绍一下吧?(大厂、小厂)
组件通过调用 Context 的 StartService()方法启动一个服务,回调服务中的 onStartCommand()。如果该服务还没有被创建,则回调的顺序为 onCreate()->onStartCommand()。服务被启动后会一直保存运行的状态,直到 StopService()或者 StopSelf() 方法被调用,服务停止并回调 onDestroy()。无论调用多少次 StartService()只需要调用一次 StopService() 就能终止服务
组件通过调用 Context 的 bindService() 可以绑定一个服务,回调服务中的 onBind() 方法。类似地,如果该服务之前还没创建,那么回调的顺序是 onCreate()->onBind()。之后调用方可以获取到 onBind() 方法里返回的 IBinder 对象的实例,从而实现和服务的通信。直到调用了 unBindService() 方法使服务终止,回调顺序 onUnBind()->onDestroy()
③Service 如何和 Activity 进行通信?(中厂)
通过绑定服务的方式。在绑定的服务中声明一个 Binder 类,并创建一个 Binder 对象,在 onBind()函数中返回这个对象,并让 Activity 实现 ServiceConnection 接口,在 OnServiceConnected 方法中获取到 Service 提供的这个 Binder 对象,通过这个对象的各种自定义的方法就能完成 Service 与 Activity 的通信。
通过 Intent 的方式,在 StartService()中需要传入一个 Intent 对象作为参数,通过这个 Intent 实例对象进行实现通信。
通过 Callback 和 Handler 的方式,在绑定的服务中声明一个 Binder 类,并创建一个 Binder 对象,在 onBind()函数中返回这个对象,让 Activity 实现 ServiceConnection 接口,并且在 OnserviceConnected 方法中实例化 Service 中的 CallBack 接口,并且实现 OnDataChange()方法,其中的实质是一段 Handler 代码,可以在其中完成耗时操作,以这种方式完成通信。
####2.Android 消息机制
①子线程中使用 Handler 需要注意什么?(中厂)
和在主线程中直接 new 一个 Handler 不同,由于子线程的 Looper 需要手动去创建,需要手动编写 Looper.loop() 与 Looper.prepare() 方法。
@Overridepublic void run() {Looper.prepare();//调用 Looper.prepare()new Handler() {@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);}};Looper.loop(); //调用 Looper.loop()}}).start();
②Hanlder 的 postDealy()调用后消息队列会发生什么变化?(中厂)
post delay 的 Message 并不是先等待一定时间再放入到 MessageQueue 中,而是直接进入并阻塞当前线程,然后将其 delay 的时间和队头的进行比较,按照触发时间进行排序,如果触发时间更近则放入队头,保证队头的时间最小、队尾的时间最大。此时,如果队头的 Message 正是被 delay 的,则将当前线程堵塞一段时间,直到等待足够时间再唤醒执行该 Message,否则唤醒后直接执行。
③简要解释一下 ANR?为什么会发生 ANR?如何避免发生 ANR?如何定位 ANR?那你还了解哪些线程间切换的类?简要选一个进行一下阐述吧?(大厂)
这是一连串的提问,涉及到性能优化->ANR 问题定位->消息传递->实现原理,所以在面试的时候你尽量不要选择他问一个你答一句话,你可以把你有把握,之前有所准备的内容,按照一个条理跟面试官阐述清楚,他大概会好感度 UP。当然必须要对你所说的东西保证充分的熟悉,因为他基本都会抓着你所说的继续跟你深入探讨下去。当然实习僧不会问的特别深入,但是你如果能把原理、机制都跟他说的很清晰有条理且有结构的话。会让面试官对你的好感有一定的上升(我猜的但应该没猜错)。也就是我们开题的时候所说的用工程师的眼光看待问题。什么问题?为什么发生问题?怎么定位并解决问题?
以下是我对这道题的回答,只是参考,如果有错误希望指正:
ANR(Application Not Responding,应用程序无响应):当操作在一段时间内系统无法处理时,譬如:应用在 5 秒内未相应用户的输入事件。广播接收器 10 秒内未完成相关的处理。服务 20 秒内无法处理完成,那么会在系统层面会弹出应用程序无响应的对话框
所以为了避免发生 ANR,我们尽量使用多线程,不要在主线程做耗时操作,而是通过开子线程,把耗时的工作放在工作线程中处理。所使用的方法比如继承自 Thread 类、实现 Runnable 接口、使用 AsyncTask、IntentService、HandlerThread 等机制
如果发生了 ANR 则可以通过 data/anr 找到 traces.txt 文件确定 ANR 发生的原因。
关于上面说的这些多线程机制,如果您感兴趣的话我可以简要的跟你阐述其中的一个或几个机制的具体内容。比如 AsyncTask 机制,AsyncTask 机制底层封装了线程池和 Handler,便于执行后台任务以及在子线程中进行 UI 操作。使用 AsyncTask 要理解 3 个泛型参数和 4 个方法
####3. View 及其他控件的使用和优化
①ListView 和 RecyclerView 的选择?为什么?(中厂)
布局效果:RecyclerView 支持线性布局、网格布局、瀑布布局,可以控制横向纵向滚动,从布局效果上来看完爆 ListView。
基础使用:ListView 需要继承重写 BaseAdapter 类,自定义 ViewHolder 和重用 ConvertView 完成优化工作。RecyclerView 继承重写 RecyclerView.Adapter 和 RecyclerView.ViewHolder,设置布局管理器,控制整体布局。规范化了 ViewHolder,复用 item 也不需要像 ListView 一样 SetTag。
空数据处理:ListView 提供了 setEmptyView 这个 API 来处理 Adapter 中数据为空的情况,RecyclerView 没提供相应 API。
HeaderFooter:ListView 提供了 Add\RemoveHeaderView 方法解决,RecyclerView 没有提供。
局部刷新:ListView 刷新 notifyDataSetChanged()方法,局部刷新需要自己实现。RecyclerView.Adapter 则
提供了 notifyItemChanged()拥有更新单个 itemView 的刷新。
动画效果:Recycler 轻松实现,listview 需要自己写属性动画,或者调用第三方库
监听 item 事件:ListView 专门提供了用于监听 item 的回调接口,RecyclerView 提供的是 addOnItemTouchListener
####4.四. Java 基础和计网基础
①HashMap 线程安全吗?那如何保证其线程安全呢?(中厂)
可以简单谈谈,使用 Hashtable 或者 ConcurrentHashMap。它们都可以用于多线程的环境,但是当 Hashtable 的大小增加到一定的时候,性能会急剧下降,因为迭代时需要被锁定很长的时间。而 ConcurrentHashMap 引入了分割(segmentation),不论它变得多么大,仅仅需要锁定 map 的某个部分,而其它的线程不需要等到迭代完成才能访问 map。简而言之,在迭代的过程中,ConcurrentHashMap 仅仅锁定 map 的某个部分,而 Hashtable 则会锁定整个 map。在 jdk1.8 之后,取消了 segments 的方式,而是使用了 transient volatile HashEntry[] table 的方式保存数据,将数组元素作为锁,对每一行数据进行加锁,减少了并发冲突的概率。由数组+单向链表变为了数组+单向链表+红黑树,将查询的时间复杂度降至了 O(logn)改进了一些性能
评论