6.牛批了 Android 2021中高级面试题 一线大厂和二线大厂面试真题精选 (小米 附答案)第三套 28k+

23 篇文章 1 订阅
18 篇文章 1 订阅
笔者是面霸,面试500+场       当过考官:面过别人500+场     去过500强,也呆过初创公司。
斩获腾讯、华为、字节跳动,蚂蚁金服,OPPO,美团,安卓岗offer!我有一套速通大厂技巧分享给你!

12年毕业,专科生,做安卓9年了。横扫深圳各大互联网公司,从开始的4k工资到现在的4万。我经历了什么?

本系列一共10套面试真题,适合快速找工作的人准备,薪资和公司分别如下。
搞定前3套,可以去二线大厂,秒杀70%公司
搞定前6套,可以去二线和一线大厂,秒杀80%公司 ,面试官在你面前都是弟弟
搞定前10套,一线大厂,秒杀100%公司,中国互联网任你挑 ,横扫北上广深,吊打面试官

 

第六套小米      价值28k+,   难易程度:中等      看完你能进这些公司
小米,Oppo,VIVO,360,新浪,拼多多,携程,微博,哔哩哔哩
强调:一定要搞的非常清晰,细节一个都不能放过,要非常深入,仅仅10题而已
1 .Activity生命周期,每个回调方法的作用是什么?Activity 生命周期,A启动B两个状态分别是什么 ,A的onStop一定会执行吗?
2. 说一说Android中如何查看一个对象的回收情况 ?
3.  ARouter路由原理,  如何管理过多的路由表?
4.怎么优化xml inflate的时间,涉及IO与反射。了解compose吗? 
5.为什么handler可以线程切换   
6.手写实现一个网络框架?平常抓包用什么工具?
7.系统启动流程是怎么样的
8.描述一次跨进程通讯
9.图片的三级缓存中,图片加载到内存中,如果内存快爆了,会发生什么?怎么处理? Bitmap高效加载
10.  性能优化做过什么工作?有用过什么工具?有没有精确测量的工具?
11.头条列表有多个不同的card,使用RecyclerView怎么解耦getViewType,获得不同的card
一个一个问题来总结一下:答案由蚂蚁金服首席架构师提供,官方答案会由3个人审核,审核之后才会公布,现在是中间版本答案
备注:Oppo,Vivo,小米等手机厂商必问的题目:view的自定义和性能优化
1 .Activity生命周期,每个回调方法的作用是什么?Activity 生命周期,A启动B两个状态分别是什么 ,A的onStop一定会执行吗?
答:oncreate:初始化参数,setcontentView()
 onstart:表示启动
onResume:获取到焦点,页面显示,可见
onPause:暂停,切换到后台可以停止音乐播放或者保存一些数据
onStop:完全不见的时候执行
onDestory:销毁一些变量和监听
详解从Activity A 跳转到Activity B:
A-B:A.onpause----B.oncrate-----B.onstart---B.onResume---A.onstop
2021-07-19 09:12:17.379 6007-6007/com.yuedong.activitylife D/MainActivity: onPause
2021-07-19 09:12:17.435 6007-6007/com.yuedong.activitylife D/SecondActivity: onCreate
2021-07-19 09:12:17.438 6007-6007/com.yuedong.activitylife D/SecondActivity: onStart
2021-07-19 09:12:17.439 6007-6007/com.yuedong.activitylife D/SecondActivity: onResume
2021-07-19 09:12:17.889 6007-6007/com.yuedong.activitylife D/MainActivity: onStop
返回的时候:A.onRestart---A.onstar---A.onResume---B.onstop------B.onDestory   
2021-07-19 09:12:28.184 6007-6007/com.yuedong.activitylife D/SecondActivity: onPause
2021-07-19 09:12:28.208 6007-6007/com.yuedong.activitylife D/MainActivity: onRestart
2021-07-19 09:12:28.209 6007-6007/com.yuedong.activitylife D/MainActivity: onStart
2021-07-19 09:12:28.210 6007-6007/com.yuedong.activitylife D/MainActivity: onResume
2021-07-19 09:12:28.557 6007-6007/com.yuedong.activitylife D/SecondActivity: onStop
2021-07-19 09:12:28.558 6007-6007/com.yuedong.activitylife D/SecondActivity: onDestroy
先看第2.3.4步,SecondActivity 未创建,我们新建一个Activity,依次调用SecondActivity 的OnCreate/onStart/onResume,这个想想没什么问题,那么为什么先走MainActivity onPause,最后才走MainActivity onStop呢?
因为,onPause时可见,onStop时不可见,不可见时屏幕上是黑屏的,因为什么都没有么才会黑屏。如果走了MainActivity onPause、onStop之后再去创建SecondActivity ,那么中间 的onStop过度到 SecondActivity onCreate时,这期间的屏幕是黑的,会给用户造成不佳体验。当SecondActivity onResume执行后,SecondActivity 已经可以看到了,此时再让MainActivity onStop才不会影响到用户体验。总结就是,当屏幕上显示了最新的页面后,其他的页面再做其他的操作。
如果是透明:
详解从Activity A 跳转到Activity B:
A-B:A.onpause----B.oncrate-----B.onstart---B.onResume (和上面对比,不会执行onstop)
B-A返回的时候: A.onResume---B.onstop------B.onDestory   (不会执行onstart和onResume()。因为已经启动了)
通过上面总结:onstop和onstart不一定会执行。所以我们一般在onpause和onResume里面执行一些东西!

onCreate和onStart之间有什么区别?

(1)可见与不可见的区别。onCreate不可见,onStart可见。

3.onStart方法和onResume方法有什么区别?

(1)是否在前台。onStart方法中Activity可见但不在前台,不可交互,而在onResume中在前台。
(2)职责不同,onStart方法中主要还是进行初始化工作,而onResume方法,根据官方的建议,可以做开启动画和独占设备的操作

4.onPause方法和onStop方法有什么区别?

(1)是否可见。onPause时Activity可见,onStop时Activity不可见,但Activity对象还在内存中。
(2)在系统内存不足的时候可能不会执行onStop方法,因此程序状态的保存、独占设备和动画的关闭、以及一些数据的保存最好在onPause中进行,但要注意不能太耗时。

5.onStop方法和onDestroy方法有什么区别?

onStop阶段Activity还没有被销毁,对象还在内存中,此时可以通过切换Activity再次回到该Activity,而onDestroy阶段Acivity被销毁

启动A,然后Home建,然后返回,生命周期是怎么样的?
和A启动到B是一样的。
onstop方法不一定会执行。一种情况,透明,另一种情况,被系统杀死
2. 说一说Android中如何查看一个对象的回收情况 ?
答:对象用弱引用包裹
把弱引用添加到引用队列中
如果引用队列有,说明被回收了。没有,说明没有回收,这就是leakcanary的原理
3.  ARouter路由原理,  如何管理过多的路由表?
答:ARouter官方建议在不同的模块下本就不应该使用同样的分组,分组名可以使用模块名或其他名称,但分组名与模块本质上是一种映射关系

  • ARouter的分组
    现在去看下我们之前怎么注解的TestARouterActivity的路由
<span style="color:#172b4d"><span style="color:#353c47"><code class="language-css">@Route(path = "/com/TestARouterActivity")
</code></span></span>

解析一下这个path:
在path这个字符串里面,”com” 就代表路由分组的标识,“TestARouterActivity” 代表是TestARouterActivity类的标识。组的标识和类的标识都可以自己定义的,需要记住的是组标识和类标识之间用斜杠来区分 ”\”

那什么是组呢?
ARouter框架是分组管理,按需加载
解释起来就是,在程序的编译期ARouter扫描了所有的注册页面、服务、字段、拦截器...,那么在程序的运行期就不能一股脑全部加载进来,这样就会一次性加载太多东西。所以ARouter就用分组来管理。
ARouter在初始化的时候只会一次性地加载所有的Root结点,而不会加载任何一个Group结点,这样就会极大地降低初始化时加载结点的数量。
通俗点说吧,比如你把TestARouterActivity1,TestARouterActivity2,TestARouterActivity3分成一组(分组的标识是一样的),组名比如叫"com"。ARouter初始化的时候不会加载"com"这个Group结点,一旦你需要跳到TestARouterActivity3这个页面了,那么ARouter才会再将com这个组加载进来。

  • ARouter的自定义分组
    ARouter的分组可以自定义,我们创建一个TestARouterActivity2并且添加 ARouter注解,指定它的自定义路由分组。如下所示:
<span style="color:#172b4d"><span style="color:#353c47"><code class="language-java">@Route(path = "/com/TestARouterActivity2" , group = "testGroup")
public class TestARouterActivity2 extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_custom_group);
    }
}
</code></span></span>

上面代码中的"testGroup"就是TestARouterActivity2的自定义分组,如果我们不指定group字段,那么TestARouterActivity2的默认分组就是 "/ /"中间的"com"。我们可以代码验证一下:

<span style="color:#172b4d"><span style="color:#353c47"><code class="language-java">@Route(path = "/com/TestARouterActivity2")
public class TestARouterActivity2 extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_custom_group);
    }
}
····
ARouter.getInstance()
       .build("/com/TestARouterActivity2")
       .navigation(this, new NavCallback() {
            @Override
            public void onArrival(Postcard postcard) {
                Log.e("eeeee", "默认分组: " + postcard.getGroup());
            }
        });
</code></span></span>

上面代码打印的结果就是 默认分组:com
自定义分组我们怎么跳转呢?
很简单,自定义分组,发起路由:第二个参数就是路由的分组

<span style="color:#172b4d"><span style="color:#353c47"><code class="language-dart">build(String path, String group);
····
ARouter.getInstance().build("/com/TestARouterActivity2", "testGroup").navigation();</code></span></span>

4.怎么获取view的宽高,如何确定值是准确的,说了view.post()补充viewTreeObserverOnGlobalLayoutListener
答:view.post(run)
原因:把run添加到一个que队列中去。但是不会立马执行。执行要主动去调用,遍历里面所有的runable执行
调用:view.dispathAttachView()里面。然后发现是viewRootImp进行调用的.performTraversals()方法
虽然perMeasure要在view.dispathAttachView()之后执行,但是,之前有一个消息,transversalasRunable方法没有执行完成的。消息原理,消息是轮询的,执行完一个,才执行下一个。
可以写一个demo:https://blog.csdn.net/libinbin147256369/article/details/101704052
第二种获取宽高的办法:
在View.onAttachToWindow之后调用,那么mAttachInfo就不为空,那么早post方法就会返回attachInfo.mHandler.post(action);
 public boolean post(Runnable action) {
        final AttachInfo attachInfo = mAttachInfo;
        if (attachInfo != null) {
            return attachInfo.mHandler.post(action);
        }
        // Assume that post will succeed later
        ViewRootImpl.getRunQueue().post(action);
        return true;
5.为什么handler可以线程切换   
答:looper有关系
looper和线程绑定在了一起
handler里面可以传入一个looper
handler发消息,把msg存放到了msgque中,msgQue是在looper中获取的
looper一直循环取消息处理处理,looper的线程在哪,导致可以切换线程
6.手写实现一个网络框架?平常抓包用什么工具?
答:
7.系统启动流程是怎么样的
答:init进程----zygotte进程---systemServer进程---launcher进程
8.描述一次跨进程通讯
答:binder驱动:都通过这个实现
mmap映射:一次拷贝
cs模型:调用服务端的代理
9.图片的三级缓存中,图片加载到内存中,如果内存快爆了,会发生什么?怎么处理? Bitmap高效加载
答:会移除,从lrucache中,然后系统的atroyMemory方法,会清除内存,回收图片
bitmap高效加载:通过imagePool.图片池
10.如何进行单元测试,如何保证App稳定 ?
答:unitTest:不怎么会
  • 全面的性能优化:启动速度、内存优化、绘制优化
  • 线下发现问题、优化为主
  • 线上监控为主
  • Crash专项优化

我们针对启动速度,内存、布局加载、卡顿、瘦身、流量、电量等多个方面做了多维的优化。

我们的优化主要分为了两个层次,即线上和线下,针对于线下呢,我们侧重于发现问题,直接解决,将问题尽可能在上线之前解决为目的。而真正到了线上呢,我们最主要的目的就是为了监控,对于各个性能纬度的监控呢,可以让我们尽可能早地获取到异常情况的报警。

同时呢,对于线上最严重的性能问题性问题:Crash,我们做了专项的优化,不仅优化了Crash的具体指标,而且也尽可能地获取了Crash发生时的详细信息,结合后端的聚合、报警等功能,便于我们快速地定位问题。

11.头条列表有多个不同的card,使用RecyclerView怎么解耦getViewType,获得不同的card
答:注解、反射,依赖注入。
      通过万能适配器打造

关于作者:
曾经入职的公司:
2013年 快播公司       因为涉黄被查了
2014年 华强集团       深圳北最大的电子公司
2015年 TCL公司        深圳传统电子公司
2016年 顺丰科技        深圳快递老大
2017年 招商银行        深圳本地银行老大
2018年 字节跳动        深圳后海,抖音头条
2019年 VIVO               深圳手机厂上梅林
2020年  腾讯音乐        深圳滨海大厦
2021年  蚂蚁金服        深圳分公司
从月薪3000到年薪60万。从专科生到深圳一线大厂。关注我就能达到大师级水平,这话我终于敢说了, 年薪60万不是梦!
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值