知乎万赞,值得反复刷的Android面试题

  • 弱引用:在垃圾回收器线程扫描它所管辖的内存区域的过程中,一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。不过,由于垃圾回收器是一个优先级很低的线程,因此不一定会很快发现那些只具有弱引用的对象

  • 虚引用:虚引用顾名思义,就是形同虚设。与其他几种引用都不同,虚引用并不会决定对象的生命周期。如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收器回收

6.原子变量Atomic

还在用Synchronized?Atomic你了解不?

7.多线程并发问题

多线程并发问题


Android基础知识


1.Looper总结

  • Looper通过prepare方法进行实例化,先从他的成员变量sThreadLocal中拿取,没有的话就new 一个Looper,然后放到sThreadLocal中缓存。每个线程只能创建一个Looper实例

private static void prepare(boolean quitAllowed) {

if (sThreadLocal.get() != null) {

throw new RuntimeException(“Only one Looper may be created per thread”);

}

sThreadLocal.set(new Looper(quitAllowed));

}

  • Looper通过loop方法开启循环队列,里面开启了死循环,没有msg时候会阻塞

  • 在ActivityThread的main方法中也就是Activity启动的时候,已经调用了Looper.prepareMainLopper()方法

2.ThreadLocal在Looper中的使用

为了解决多个线程访问同一个数据问题,同步锁的思路是线程不能同时访问一片内存区域.而ThreadLocal的思路是,干脆给每个线程Copy一份一摸一样的对象,线程之间各自玩自己的,互相不影响对方

常见ThreadLocal应用场景:确保在每一个线程中只有一个Looper的实例对象

  • ThreadLocal的set方法

public void set(T value) {

Thread t = Thread.currentThread();

ThreadLocalMap map = getMap(t);

if (map != null)

map.set(this, value);

else

createMap(t, value);

}

  • ThreadLocal的get方法

public T get() {

Thread t = Thread.currentThread();

ThreadLocalMap map = getMap(t);

if (map != null) {

ThreadLocalMap.Entry e = map.getEntry(this);

if (e != null) {

@SuppressWarnings(“unchecked”)

T result = (T)e.value;

return result;

}

}

return setInitialValue();

}

简而言之:先拿到当前线程,再从当前线程中拿到ThreadLocalMap,通过ThreadLocalMap来存储数据。(ThreadLocalMap是Thread的成员变量)

3.Service 和 IntentService

Activity对事件响应不超过5秒,BroadcastReceiver执行不超过10秒,Service耗时操作为20秒。否则系统会报ANR

  • 使用startService()方法启用服务后,调用者与服务之间没有关连。调用者直接退出而没有调用stopService的话,Service会一直在后台运行

  • 使用bindService()方法启用服务,调用者与服务绑定在一起了,调用者一旦退出,服务也就自动终止

  • IntentService是Service的子类,会创建子线程来处理所有的Intent请求,其onHandleIntent()方法实现的代码,无需处理多线程问题

4.FragmentPageAdapter和FragmentPageStateAdapter的区别

  • FragmentPageAdapter在每次切换页面的的时候,没有完全销毁Fragment,适用于固定的,少量的Fragment情况。默认notifyDataSetChanged()刷新是无效的

  • FragmentPageStateAdapter在每次切换页面的时候,是将Fragment进行回收,适合页面较多的Fragment使用,这样就不会消耗更多的内存

5.Sqlite数据库,什么是事务

事务是由一个或多个sql语句组成的一个整体,如果所有语句执行成功那么修改将会全部生效,如果一条sql语句将销量+1,下一条再+1,倘若第二条失败,那么销量将撤销第一条sql语句的+1操作,只有在该事务中所有的语句都执行成功才会将修改加入数据库中

sqlite数据库相关操作,主要包括创建和增删改查,事务

6.怎么做Sqlite数据库升级

  1. 直接删除老数据库,但会造成数据丢失,一般不采用

  2. 对数据库进行升级,参考SQLite数据库版本升级

7.invalidate与requestLayout区别

  • view调用invalidate将导致当前view的重绘,viewGroup调用invalidate会使viewGroup的子view调用draw

  • requestLayout方法只会导致当前view的measure和layout,而draw不一定被执行。只有当view的位置发生改变才会执行draw方法

8.View和ViewGroup区别

  • ViewGrouponInterceptTouchEvent默认返回false,即不拦截事件,View没有拦截事件方法,View默认时消耗事件的

  • ViewGroup默认不会调用onDraw方法,View默认会调用onDraw方法。可以通过setWillNotDraw(boolean willNotDraw)来指定是否调用onDraw方法

/**

  • If this view doesn’t do any drawing on its own, set this flag to

  • allow further optimizations. By default, this flag is not set on

  • View, but could be set on some View subclasses such as ViewGroup.

  • Typically, if you override {@link #onDraw(android.graphics.Canvas)}

  • you should clear this flag.

  • @param willNotDraw whether or not this View draw on its own

*/

public void setWillNotDraw(boolean willNotDraw) {

setFlags(willNotDraw ? WILL_NOT_DRAW : 0, DRAW_MASK);

}


Android框架知识


1.buttnife实现原理

通过注解处理器动态生成java文件,在java文件中进行findViewById和setOnClickListener操作

2. EventBus实现原理

通过观察者设计模式,先通过注册的方式将指定的类加到一个表里面,等发送消息时轮训那个表,依据注解和注解的value找到匹配的方法,然后执行该方法

3.LiveData原理

LiveData通知其他组件原理主要是观察者设计模式。其优点有

  • 遵从应用程序的生命周期,如在Activity中如果数据更新了但Activity已经是destroy状态,LivaeData就不会通知Activity(observer)

  • 不会造成内存泄漏

4.Lifecycle

简单来说,就是可以让你自己的类拥有像 activity 或 fragment 一样生命周期的功能。继承Lifecycle 的组件将生命周期脱离出 activity 而转到自己身上

使用步骤:

(1) 继承DefaultLifecycleObserver

class TestObserver implements DefaultLifecycleObserver {

@Override

public void onCreate(LifecycleOwner owner) {

// your code

}

}

(2) LifecycleOwner是只有一个方法getLifecycle()的接口,是让拥有生命周期的东西实现比如(activity)用来获取Lifecycle。在Android Support Library 26.1.0 及其之后已经activity 和 fragment 已经默认实现了LifecycleOwner

所以在 activity 里我们可以直接:

getLifecycle().addObserver(new MyObserver());

这样我们的MyObserver就会感知 activity 的生命周期了

5.FlowableObservable

RxJava1中使用ObservableObserver建立起订阅关系,但会产生背压问题。Rxjava2使用FlowableSubscriber替换RaJava1的ObservableObserverFlowable是在Observable的基础上优化后的产物,Observable能解决的问题Flowable也都能解决。但是并不代表Flowable可以完全取代Observable,Flowable运行效率要比Observable慢得多。

只有在需要处理背压问题时,才需要使用Flowable

  • 当上下游在不同的线程中,通过Observable发射,处理,响应数据流时,如果上游发射数据的速度快于下游接收处理数据的速度,这样对于那些没来得及处理的数据就会造成积压,这些数据既不会丢失,也不会被垃圾回收机制回收,而是存放在一个异步缓存池中,如果缓存池中的数据一直得不到处理,越积越多,最后就会造成内存溢出,这便是响应式编程中的背压(backpressure)问题

  • 如果能够确定:

1.上下游运行在同一个线程中

2.上下游工作在不同的线程中,但是下游处理数据的速度不慢于上游发射数据的速度

3.上下游工作在不同的线程中,但是数据流中只有一条数,

则不会产生背压问题,就没有必要使用Flowable,以免影响性能。

6.app优化

  • 内存优化:使用leakcanary抓取内存泄露,或者使用android studio抓取内存信息,通过Profiler分析内存泄露情况

  • 体积优化

  • 不复杂图片使用svg代替png。换肤时使用着色器,可减少图片资源

  • build文件配置

  • 保留指定语言

  • 保留指定so库架构

  • 开启混淆压缩

7.Rxjava中关于Disposable

Rxjava容易遭层内存泄漏。在订阅了事件后没有及时取阅,导致在activity或者fragment销毁后仍然占用着内存,无法释放。而disposable,可以用来取消订阅

参考Rxjava关于Disposable你应该知道的事

最后

你是不是为了收集资料疲于奔命,是不是收藏好的资料至今还在收藏夹里吃灰,不知道从何看起?

Android面试题到处攒,一到面试就不知深浅忘个干净?快来看看这份超详细整理!

底层原理+项目实战+面试专题

1、底层原理(Android进阶、架构设计、NDK、跨平台、底层源码…)

2、项目实战(一线互联网大厂真实项目实战训练)

3、面试专题(大厂内推+简历优化+面试技巧+Android筑基+分布式+开源框架+微服务架构+性能优化+JVM 等一线互联网企业面试题)

资料对标对标阿里 P7,覆盖 99% 互联网公司技术要求

写在最后

对程序员来说,很多技术的学习都是“防御性”的。也就是说,我们是在为未来学习。我们学习新技术的目的,或是为了在新项目中应用,或仅仅是为了将来的面试。但不管怎样,一定不能“止步不前”,不能荒废掉。

![
[]


文章以下内容会给出阿里与美团的面试题(答案+解析)、面试题库、Java核心知识点梳理等

《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》点击传送门,即可获取!
不前”,不能荒废掉。

[外链图片转存中…(img-Kmyl15Rx-1715345908736)]

[外链图片转存中…(img-5QNcVw38-1715345908737)]
[]

[外链图片转存中…(img-TgxbKX8z-1715345908737)]
[外链图片转存中…(img-5N0JGJzp-1715345908738)]

文章以下内容会给出阿里与美团的面试题(答案+解析)、面试题库、Java核心知识点梳理等

《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》点击传送门,即可获取!

  • 14
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值