2022面筋

面试题总结

  • 一、陌陌
  • 二、得到(烂公司)
  • 三、携程
  • 四、卓盟(烂公司)
  • 五、网达(烂公司)
  • 六、再惠(烂公司)
  • 七、传音控股
  • 八、AmberGroup(烂公司)
  • 九、商米
  • 十、 虎扑
  • 十一、 字节
    • 1、hashmap的put和get的时间复杂度 链表查询效率低。为啥不直接用树存储节点
    • 2、kotlin by函数怎么实现的 flow流和rxjava
    • 3、intent 传输大数据 会出现什么问题。怎么解决
    • 4、两个Activity A到B 生命周期 返回A B的生命周期
    • 5、livedata postvalue 和setValue区别 非主线程调用setValue是抛异常吗?
    • 6、viewModel生命周期
    • 7、mvc mvp mvvm
    • 8、kotlin实现单例 kotlin实现的单例转成java是什么形式
    • 9、handler机制 postDelay怎么实现的
  • 十二、比心
  • 十三、百度
  • 十四、微博
  • 十五、 拼多多
  • 十六、 小红书
  • 十七、前程无忧(烂公司)
  • 十八、 其他别人的

一、陌陌

1.Rxjava原理
2.handler内存泄漏,为什么持有外部类引用
造成内存泄漏原因:handler发送的消息存放在Looper的消息队列里面,如果此时activity finish了,此时队列里的消息仍然会交给handler来处理,因为handler不是静态内部类,依然会有activity的引用,当GC时,发现activity还有引用,就不会对回收这个activity了。
解决:将handler声明为静态内部类,因为静态内部类不会持有外部类的引用,并用弱引用包裹外部类对象,利用弱引用访问外部类属性。

为什么内部类默认持有外部类对象?
内部类依赖于外部类,没有外部类无法创建内部类
正常情况下一个类想要访问另一个类,需要先创建一个实例,通过这个实例引用访问,而内部类则可以直接访问,说明他默认持有外部类的引用
虽然内部类与外部类在一个文件中,但是编译完成之后还是生成了两个不同的Class文件,内部类通过this访问外部类的成员变量。
(1)编译器自动为内部类创建了一个类型为外部类的成员变量,相当于外部类的一个引用
(2)编译器自动为内部类的构造方法添加了一个类型为外部类的一个参数,用于初始化内部类的成员变量
loop为什么没有造成阻塞?
应用的所有生命周期方法都运行在这个loop里面,当生命周期发生变化时会通过handler发送消息,loop循环获取消息处理。
造成ANR的原因是因为输入事件没有5s之内没有及时响应,与死循环没有关系,当有输入事件来临时,loop会及时获取到消息并处理,所以不会造成ANR
祝线程从消息队列中读取信息,当消息读完祝线程阻塞,但他的消息循环没有被阻塞,当有消息来时,他又会及时被唤醒处理消息,所以不会造成ANR

3、https过程,http header. okhhtp原理。 静态代理动态代理区别
https过程:
客户端发起一个http请求,连接到服务器的443端口
服务端将自己的公钥以证书的形式回传给客户端
客户端收到这个证书之后会验证,验证通过生成一个随机值,也就是密钥,用服务端传回的公钥进行非对称加密
再次发起http请求,将加密后的密钥传给服务端
服务端收到密钥后用自己的私钥进行非对称解密出密钥
然后将要返回的数据利用密钥进行对称加密回传给客户端
客户端收到后利用密钥进行对称解密。
4.mvvm,mvp、mvc
mvc:
Model:负责获取数据 View:界面显示 Controller:逻辑控制

三者通信:view产生事件,将事件传给controller,controller经过一系列逻辑处理之后通知Model更新数据,model数据更新之后通知view,所以view需要持有Controller的引用,Controller需要持有Model的引用,Model需要持有view

缺点:1、在正常情况下Fragment需要同时担任Controller和view两个角色,导致fragment或者activity代码臃肿
2、Model操作view,view的改动导致controller和model都需要修改
3、增加了代码结构的复杂性

mvp:
model:负责数据的获取 view:界面显示 presenter:逻辑处理
将MVC中的view和Model解耦

三者通信:view产生事件,将事件交给presenter,presenter经过一系列逻辑处理后通知MOdel更新数据,model数据更新后返给peresenter,presenter再通知view更新。
所以mvp是让presenter做中转,所以presenter需要同时持有view和model的引用

缺点:会引入大量的接口,导致文件激增,增加代码的复杂性

Mvvm:
model:获取数据。view:界面显示。view Model:逻辑处理
mvvm中将MVC中的view和model姐耦,并且将MVP中的View和Presenter也进行了姐耦

三者通信:
在MVVM中,view和view model直接完全结偶,通过livedata进行数据绑定,view产生事件自动通知view model,view model经过一系列逻辑处理之后通知model更新数据,model更新数据之后返回给view model,view model再通过livedata自动通知view

优点:模块间充分姐耦

缺点:代码复杂性增加,debug困难

5、JVM原理,垃圾回收机制

6、事件分发,自定义View
7、Android异步机制
IntentService:
继承自Service,是一个抽象类,用于执行后台耗时任务,任务结束后,他会自动停止,由于它是个服务,所以优先级比普通线程高很多,里面封装了HandlerThread 和Handler ,从他的onCreate()可以看出
HandlerThread thread = new HandlerThread();
thread.start();
mServiceLooper = thread.getLooper();
mThreadHandler = new ServiceHandler(mServiceLooper)
当Intent Service第一次被启动时,会调用onCrate(),在onCreate中创建了一个HandlerThread,并使用它的Looper创建了一个mServiceHandler的对象,通过这个mServiceHandler发送的消息都会在HandlerThread中执行。
每次启动intentService ,他的onStartCommand会执行,然后又调用onStart(),在onstart()中,发送I个消息,msg.obj = intent,mServiceHandler收到这个消息后将INtent传给onHnadlerIntent()方法去处理,onHandlerINtent方法结束后通过stopSelf(startId)结束服务,在尝试停 止服务之前会判断最近启动次数是否跟startId相等,相等则停止。
onIntentHandler是抽象方法,需要我们在自类中实现,每执行一个后台服务就启动一次IntentService;looper是顺序处理消息的,所以Intent Service也是顺序处理任务的
使用场景:

8、多线程
9、解决Crash的思路,启动速度优化
定位,debug
启动速度优化:
内存优化:

10、如何在不知道其他业务模块的情况下确保某一任务的优先级
11、OOM,内存优化
12、性能优化
13、范型
14、匿名内部类和静态内部类区别
15、反射,范型
16、在开发需求上遇到了什么bug和难点
17、自定义view的方式有哪些
18、自定义一个钟表view 怎么做
19、自定义钟表时针分针怎么实现转动
20、实现定时器的方式,怎么把定时器的制传给自定义的钟表
21、么让view刷新,invidate()和requestLayout的区别
22、handler原理,为什么每个线程都要有一个Looper,怎么实现的每个线程持有一个Looper,通过这种方式给主线程会有什么缺陷?
23、算法 给定树的根节点,将拥有任意数目的子节点转换为列表
24、性能优化
25、造成内存泄漏的原因
26、异步代码造成的内存泄漏怎解决
27、屏幕适配
28、有啥要问的

二、得到(烂公司)

1、切换线程的方式,rxjava原理
2、动态代理静态代理的区别,静态代理代理的是方法,动态代理的是对象
3、handler机制,postDelay如何实现的,消息队列的数据结构是什么?
延迟消息特别多时,是是怎么插入消息的,用的什么数据结构
4、观察者模式实现一个例子,为什么被观察者需要接口
5、如何理解面向对象,面向过程
6、MVC,MVVM,MVC的基于事件驱动? MVVM基于数据驱动
7、recycleview和listview区别。recycle view原理,复用逻辑 ,onCreateViewHodler 具体耗时操作是哪一步
8、数据结构了解了哪些,二叉树原理,二叉树查找的时间复杂度,O(logn)的O指的是什么

三、携程

1、项目 一定要熟
2、aidl 客户端要得到服务端的用户名和密码 用aidl要怎么实现。要注意什么 (再学习深入一点)。
dialog需要注意什么 如果activity销毁 dialog有什么影响
3、handler 子线程创建handler post 和 post Delay区别 主线程什么时候创建looper ActivityThread是线程吗
4、事件分发机制 A布局嵌套B,B嵌套button ,事件怎么分发。 down事件消费完然后怎么往回传
5、on Measure onLayout。onDraw 重写场景
onMeasure:自定义viewGroup必须要实现,比如实现一个流式布局。里面有很多的textview 就需要测量父布局的大小 以及需要去测量每一个子view的大小 如果大小是wrap content 需要特殊处理

onlayout:自定义viewGroup必须重写 需要摆放子view的位置

ondraw:自定义view。需要画圆之类的

7、多线程 锁 生产者消费者模型 生产者消费者模型怎么退出
毒丸结束消费者
生产者:

8、activity启动模式 应用场景
standard:邮件或没有指定都
singTop:点开不同推送消息,打开的是同一页面 该页面可使用singTop,登录页面等
SingleTask:app主页一般都用singleTask 不管跳转到任何页面 再回到主页 都要清空上面的activity,购物界面,确认订单界面,付款界面
single Instance:通过app打开地图,打电话,位置等此类app 他们都用的single instance 多次打开的是同一实例,来电显示,锁屏键,系统langcher

9、tcp udp知道多少。滑动窗口
滑动窗口:利用滑动窗口实现流量控制
避免一次发送太多,接收方来不及接收
发送一个数据,收到确认再继续发送效率太低,使用滑动窗口,每次根据服务端发过来的接收窗口大小和确认,可以在不接受确认的情况下发送接收窗口大小的数据

拥塞控制:防止过多的数据一下子注入到网络中,使链路过载
方法:慢开始和拥塞避免
慢开始:设置一个慢开始的门限,一开始把拥塞窗口置为1,先发送一个报文段,收到一个确认就把拥塞窗口加1,所以拥塞窗口就会成指数增长,当拥塞窗口达到慢开始那个门限,就改为拥塞避免算法
拥塞避免:每经过一个往返时间,拥塞窗口加1,当发生网络拥堵时,就重新将拥塞窗口置1,慢开始门限改为拥塞窗口的一半,继续使用慢开始

10、滑动冲突 内部拦截法。外部拦截法 requestDisallowInterceptTouchEvent
11、动态代理 作用
12、链表是否有环 环的入口节点 该算法应用场景
13、android进程间通信方式有哪些
进程间通信:
bundle:activity,service,broadcast receiver支持在intent中传递bundle数据,bundle实现了parcleabe及Ekoyr,可以在不同进程间传输

文件共享:不同进程可以通过读写同一个文件来通信

Messager:底层是aidl,一次只处理一个请求,服务端不用考虑同步的问题;
使用方式:sever端创建一个handler,把这个handler作为参数创建一个messager对象,在onbind方法中返回meassager.getBinder()底层binder
在客户端绑定服务端的服务,在on service Connected方法中获取这个binder并把它作为参数创建一个Messager对象,通过这个messager就可以给服务端发消息。如果想要服务端回应,可以通过把一个handler赋值给meaasge的applyTo参数,服务端通过这applyTo回应客户端。

aidl文件:messager只能串行执行任务,如果有大量并发请求,使用aidl

socket:服务端创建serverSocket,指定端口,调用socket.accept方法接收请求
客户端创建Socket对象,

ContentProvider

14、平衡二叉树 完全平衡二叉树
完全二叉树就是假设一棵树一共有h层,那么除了最后一层 ,1到h-1层节点都是满的,最后一层所有的节点集中在最左边。

15、Lru cache用什么数据结构实现

16、retrofit原理
使用:利用建造者builder创建retrofit对象,调用retrofit.create方法,以接口的class对象为参数,通过该返回值调用接口的方法;
然后再调用call.equeue或者execute方法

原理:create方法里利用了动态代理返回了借口的代理类,调用代理类的方法都会回调invocation handler的invoke方法,在invoke方法里把method和retrofit封装到service method对象里,然后做为参数创建了okhttpcall 最后把这个call返回

调用call的execute方法里把sevice method转成request,然后把这个request作为参数,调用service method的callFactory.newCall方法,这样就发起了网络请求。 这个callfactory也就是retrofit里的callfractory 默认创建的是okhttp client。

四、卓盟(烂公司)

1、项目介绍
2、activity启动模式
3、targetSdk属性是干啥的
compileSdkVersion: 采用哪个版本编译自己的应用,应用使用API的级别不得高于这个版本
minSDkVersion: 应用可以运行的最低版本 低于minSdkVersion的android系统无法安装此应用
targetSdkVersion: 版本兼容,向前兼容 比如targetVerson为20的app,运行在系统高于20的手机上,系统为了兼容会执行旧的api,不会导致由于系统的原因让app失常。

4、A和B两个activity 切换生命周期的变化
5、listview和recyclerview的区别
6、recyclerview缓存
一级缓存:屏幕内缓存
mAttachedScrap: 不需要重新绑定数据,未与RecyclerView分离的viewHodler
mChangedScrap: 数据发生变化,需要重新绑定数据

二级:屏幕外缓存 mCachedViews
用来缓存移除屏幕之外的viewholder,默认容量是2,可以通过setViewCached方法来改变大小,
如果mCachedViews满了,则优先移除旧的ViewHolder,将其挪进缓存池中

三级:自定义缓存。通过RecyclerView.setViewCacheExtension设置

四级:缓存池 ReclerViewPoll
SparseArray 通过type缓存,每个type对应5个viewhodler 需要重新绑定数据

7、onSaveInstanceState和onRestoreInstanceState的调用时机
onRestoreInstanceState只有在确定activty被系统回收。在重新创建activity的时候调用

8、handler机制 handler延时消息
9、事件分发机制 Cview处理了down事件 后面up事件怎么处理 还需要经过A、B去分发吗
View分发: dipatouchEvent
判断是否设置OnTOuchEventListener onTouch是否为true. 是否为enable
三者都满足 则返回true 事件被消耗
否则调用OnTouchEvent() 调用onLick()

viewGroup分发:
如果是down事件 不拦截的情况下 遍历子view。判断子view的范围是否在事件点击范围之内 如果是 则调用子view的dipatchTouchEvent() 如果返回true。将处理事件的view赋值给mMotionTarget

10、java里面同步机制 synchronized使用
11、view绘制流程
12、内存泄漏的时机 habdler内存泄漏的引用链
13、性能优化
14、lifecycle原理
15、自定义view要注意什么
自定义view 需要指定好宽高, 否则wrapContent matchParent 效果一样 原因是
ViewGroup在onMeadure之前会调用measureChildWithMargin()在这个方法中会去生成子view的MeasurePec
生成规则由子view的LayoutParam和自身的MeasureSpec决定
在父view的测量模式不为UNSPECIFIED的情况下
当子view为固定大小时,不管父view的测量模式是什么 子view的测量模式都是EXACTLY,大小为指定大小
当子view为wrap_content 不管父view的测量模式,子view为AT_MOST 大小为父view剩余大小
当子view为match_parent 父view的测量模式就是子view的测量模式 大小为父view声音大小

避免在onDraw创建临时对象或者耗时操作 否则会造成卡顿

如果自定义属性 typeArray记得及时recycler()

五、网达(烂公司)

1、mvvm mvc mvp
MVVM有什么问题
livedata先设置值再监听能否收到?怎么解决

livedata快速postValue 有什么问题 怎么解决
会丢值 因为在postValue时值的设置 把值存储在mpendingData 然后判断mpendingData是不是等于初始值 不等于初始值直接return 等于的话分发是放在了一个runable里。然后给UI Handlerpost了这个hanlder
因此 快速post的时候。runable还没回调

2、用过什么设计模式 单例模式 怎么写 判空的意义
3、view的getY 和getRowY区别
getY 获取相对于view边缘的距离 getRowY获取相对于屏幕边缘的距离
4、view dipatchTouchEvent返回false 怎么处理的
5、view post()作用
6、在onCreate获取view的宽高可能获取不到 因为view还没有绘制完成
view post将runabale置于lopper的消息队列中 当looper调用该runable时 view已经绘制好了
7、Looper的ThreadLOcalMap的key是什么
Looper中有一个ThreadLocal对象 存储每个线程的Looper 存储是拿到当前线程 获取当前线程的ThreadLocalMap
key为ThreadLocal value为looper对象
8、RecyclerView快速滑动 焦点会不会乱飞. 怎么处理
9、进程通信怎么传输大数据
(1)分段传输 服务端告诉客户端传输的数据大小。客户端建立容易分段接收 结束后将数据还原
(2)共享内存 + binder
将文件描述符告知对方 ,然后根据描述符获取共享内存的数据
10、链表是什么
11、MVVM优点作用
12、抽象类和接口的区别

六、再惠(烂公司)

1、进程间通信方式
2、广播和EventBus区别
3、服务运行在主线程还是子线程 服务开启两种方式的生命周期
4、 四大组件
5、 基于standard模式 activity A 跳转 Activty B 生命周期 A 和B的生命周期
6、 activity启动模式
7、 用到了什么框架 框架用到了什么设计模式
8、 Android不同版本之间兼容???? 权限问题
9、 kotlin的any 和 java的object类的区别。kotlin中空指针的处理
10、 http有哪些方法除了get post osi七层模型 http断点续传
OSI七层模型:
11、 handler机制 子线程可以用handler吗
12、 MVP MVVM区别
13、 viewBinding 用过吗??? ?
14、 fluter用过吗
15、 事件分发机制 从activity开始说
on InterceptTouchEvent onTouchEvent 返回ture false 后分别怎么处理
16、 自定义view流程

七、传音控股

1、常用的数据结构有哪些
2、Arraylist和LinkedList区别
3、HashMap和HashTable区别
4、MVC MVP MVVM
5、常用的设计模式用了哪些 单例和静态方法有什么区别 单例应用场景
6、两个Activty来回跳转生命周期
7、Activity启动模式 应用场景
8、Activity,fragment之间怎么传递数据
9、组件化做过没?组件之间怎么通信
10、 项目遇到了什么问题 怎么适配多语言。
11、hanlder机制
12、子线程为什么不能更新UI
13、对工作有什么要求
14、 说一下协程

1、优化做过哪些?
2、内存泄漏遇到哪些?怎么解决 内存泄漏怎么监测
3、ANR,崩溃率关注过吗? ANR怎么监测
3、怎么跟后端通信?json格式的优缺点
4、 apk瘦身做过吗
代码混淆 删除冗余资源 图片压缩 插件化
5、 请求数据后端超时,客户端这边怎么处理 比如请求一个list,后端超时。 如果一直刷新呢 怎么处理
6、 有没有往header里放过数据?
7、 给后端传数据用的什么格式
8、 屏幕适配怎么做
9、屏幕适配
dp:密度无关像素 保证在不同屏幕像素密度的手机上显示相同的效果
适配方案:
dp原生适配方案:在同样尺寸,不同分辨率的屏幕上,每一dp代表的像素量不同,但是代表的物理尺寸相同
保证在相同尺寸,不同分辨率的设备上看到的大小一致,各设备显示的比例就一致了
SmallestWidth限定符:
系统会识别屏幕可用的最小宽度,然后根据识别到的最小宽去资源文件中寻找对应限定符下的资源文件
宽高限定符:
选一个主流手机尺寸作为基准,其他分辨率的手机根据基准做适配。比如基准为320480
对于800 * 480的分辨率设备来讲 需要在value_800
480文件夹下的dimens文件中将宽度分为480份
取值为480/基准320 代表1px在320宽度上为1px. 在480宽度上为480 / 320 = 1.5
9、有没有接触过第三方登录 第三方支付

八、AmberGroup(烂公司)

1、JVM内存模型
2、双亲委派模型 Android里面哪里用到类加载器
3、java里面加锁机制。sysnchronized原理
4、多线程怎么使用。线程池工作流程
5、常用的设计模式 用到了哪些 介绍一个
5、反射应用场景
6、Activty启动模式 应用场景
7、滑动冲突遇到过没 怎么解决
8、Activity启动过程。除了这个还看过哪些FrameWork源码
9、binder机制说一下
10、自定义过view没有 怎么做的
11、热修复有没有了解过
12、Handler机制 有没有看handler C++层面怎么实现
13、Looper.prepare()和Looper.loop()作用
14、有没有做过优化方面的工作
15、图片处理有没有接触过
16、栈,队列,链表底层原理

1、自己独立负责app和做需求学到了什么
2、jvm优化

九、商米

1、fragment生命周期 add和replace的区别
2、fragment之间如何通信
3、项目难忘的bug 遇到的难点
4、 范型类型擦除
5、观察者模式缺点 问题
6、okHttp拦截器 retrofit
7、类加载机制
8、wait()和sleep()区别
9、hashmap 特点 原理
10、synchrnized锁优化
11、view绘制流程 分发机制
12、自定义view重新onMeaure onLayout要注意的问题
13、职业规划
14、序列化方式 两种序列化的区别 往数据库写数据 两种序列化都可以吗?
15、内存泄漏 ANR OOM有遇到过吗

十、 虎扑

1、项目介绍 难点
2、项目描述一下
3、activity跳转方式 隐士跳转哪些方式。schema跳转怎么使用
4、activity生命周期 onsaveInstanceState调用时间。该方法的参数类型 bundle
5、activity跳转为啥要用intent 用普通的类行不行
6、实现序列化
7、两种序列化的区别 为啥不用seralizebal实现序列化
8、ActivityThread是一个什么类 父类是啥
9、Hander机制 原理 looper messagequeue 三者之间的关系 消息屏障 为啥没有死循环
同步屏障:就是将一个屏障消息插入到消息队列中,这个屏障消息的handler为空 在next方法中判断如果msg为空的话,就是屏障消息,然后遍历后续的消息 只处理异步消息,同步消息则不处理,直到将这个屏障消息移除,才处理同步消息;
插入同步屏障:通过反射拿到messageQueue的postSyncBarrier方法
在这个方法里就往消息队列里插入了一条message为空屏障消息
插入异步消息:调用message的setAynvhrous方法 参数为true
就将这个消息设为异步消息;
10、jvm内存模型 垃圾回收机制 如何判断可回收
11、kotin:构造方法。init块之间执行顺序
静态方法怎么定义。var val区别
扩展函数 apply let with also之间的区别 有没有用过kotlin的flow
apply使用this引用当前对象,this可省略,必须要有返回值,返回值为当前对象,可判空
let使用it引用当前对象,it不可省略,返回值为最后一行,返回值可有可无 可判空
also使用it引用当前对象,it不可省略,返回值为当前对象 可判空
with使用with(对象) 使用this访问当前对象 不可判空 返回值为最后一行 可有可无
run使用this访问当前对象 可判空
返回值为最后一行 可有可无
12、协程原理 判空操作
13、rxjava原理
14、retrofit原理
15、okhttp原理
16、glide原理
17、livadata原理 用了什么设计模式 用的时候有什么问题。假设一个livedata发送数据 监听者监听 然后将这个观察者remove 然后再添加 还会收到数据吗?
18、viewmodel原理。如何监控生命周期。为啥不能直接new viewModel
生命周期:在activity或者fragment destroy的时候就会调用viewModel Store的clear方法 在这个方法里会遍历map的view model 调用 onClear方法
19、bitmap是什么?像素点存在内存哪一块 堆
20、AMS是啥 干啥用的 作用
21、mvc mvp mvvm区别?
22、jetpack除了以上三种 还用了哪些?
23、自定义注解 注解的类型
24、ondraw的流程
绘制背景 绘制内容 绘制子类的内容 绘制前景色

十一、 字节

1、hashmap的put和get的时间复杂度 链表查询效率低。为啥不直接用树存储节点

put: 根据key的hash值与数据长度减1做按位与操作找到对应的下标
链表长度小于8,数组长度小于64 链表查找O(N) 否则O(logn)
get:找到对应下标 链表查找O(n) 红黑树查找o(logn)

2、kotlin by函数怎么实现的 flow流和rxjava

by函数是一个委托函数

3、intent 传输大数据 会出现什么问题。怎么解决

创建一个数据类DataHelper,里面定义一个map,key为id,value为要传递的数据,避免内存泄漏,使用数据的弱引用
在ActivtyA要跳转前设置data, 到达Activity B后获取数据

使用bundle.putBinder()
Intent普通传大图方式为啥会抛异常而putBinder 为啥可以?
较大的bitmap直接通过Intent传递 是因为Intent启动组件时,系统禁掉了文件描述符fd,bitmap无法利用共享内存,只能采用拷贝到缓冲区的方式,导致缓冲区超限,触发异常;putBinder 的方式,避免了intent 禁用描述符的影响,bitmap 写parcel时的fd 默认是true,可以利用到共享内存,所以能高效传输图片。

4、两个Activity A到B 生命周期 返回A B的生命周期

Activity(A)启动后点击Home键再回到应用 的生命周期:
onPause(A)->oStop(A)->onRestart(A)->onStart(A)->onResume(A)

两个Activity(A->B)切换(B正常的Activity)的生命周期:
onPause(A)->onCreate(B)->onStart(B)->onResume(B)->oStop(A)
这时如果按回退键回退到A :
onPause(B)->onRestart(A)->onStart(A)->onResume(A)->oStop(B)

如果A在切换到B后调用了A.finish(),则会走到onDestory(A),这时点回退键会退出应用

两个Activity(A->B)切换(B透明主题的Activity或是Dialog风格的Acivity)的生命周期:
onPause(A)->onCreate(B)->onStart(B)->onResume(B)
这时如果回退到A:
onPause(B)->onResume(A)->oStop(B)->onDestory(B)

5、livedata postvalue 和setValue区别 非主线程调用setValue是抛异常吗?

setValue只能在主线程中调用 否则会抛异常
postValue可在子线程中调用 livedata再将现场切到主线程

6、viewModel生命周期

Activity内部有一个ViewModelStore, 内部使用一个HashMap存储着所有的viewModel
在创建时,会注册一个lifeCycleObserver 当Activity onDestory时,就会遍历viewModelStore中的map,调用每个viewmodel的onCleard()去做释放资源操作

7、mvc mvp mvvm

8、kotlin实现单例 kotlin实现的单例转成java是什么形式

对应java的懒汉式

9、handler机制 postDelay怎么实现的

msg有一个when变量记录消息的执行时间
插入消息时会遍历messageQueue 如果消息队列为空或者消息头的msg的执行时间大于插入消息的执行时间 则将消息插入到队列头部 否则遍历 直到找到比消息执行时间大的消息 插入到该消息前面
如果消息头的消息的when大于当前时间 则开始休眠

10、合并两个升序列表 合并k个 时间复杂度多少
m,为链表1的个数 ​n为链表2 的元素个数。递归函数每次去掉一个元素,直到两个链表都为空,因此需要调用 R=O(m+n) 次。而在递归函数中我们只进行了 next 指针的赋值操作,复杂度为 O(1),故递归的总时间复杂度为 O(T)=R∗O(1)=O(m+n)。

作者:腐烂的橘子
链接:https://leetcode.cn/problems/merge-two-sorted-lists/solutions/103891/yi-kan-jiu-hui-yi-xie-jiu-fei-xiang-jie-di-gui-by-/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
11、绘制流程 测量模式是怎么传进来的
DecorView的measureSpec是由窗口大小和LayoutParams决定
然后一层一层往下传递
子view的MeasureSpec由父view的MeasureSpec和自身LayoutParams决定
当父view在调用子view的Measure方法前,会调用getChlidMeasureSpec来生成子view的MeasureSpec;
当LayoutPrams的大小为具体大小时,不管父view是什么测量模式 ,子view一定是精确模式,大小为LayoutPrams指定的大小
当为Match_Parent时,如果父view为精确模式,则子view为精确模式,大小为父容器的剩余空间(specSize - paying-lp.margin-widthInuse)
当为wrapContent时,不管父view为什么模式,子view一定为AT_MOSt模式,size为父容器剩余空间
12、过度绘制怎么处理 怎么造成的
同一个像素在同一桢的时间内被绘制多次
通常在多层次UI重叠结构中,不可见UI也在进行绘制操作,就导致同一个像素被绘制多次
解决:去除xml中一些非必要的背景,去除window,Activity默 认的背景色
按需显示背景占位图
设置imageView占位图时尽量避免在xml中使用background,而是在代码中使用setBackgroundImage
13、在b站干的工作
14、JVM内存模型

1、已知四个包含整数的数组列表 A , B , C , D ,计算有多少个元组 (i, j, k, l) ,使得 A[i] + B[j] + C[k] + D[l] = 0;
2、单例
3、volatile原理
4、synchronized原理
5、三个线程,依次打印ABC,如何保证顺序
6、线程池参数,拒绝策略
7、http1.0,1.1,2.0区别
1.0需要使用keep-alive参数告知服务器建立长链接,否则一次请求之后将断开连接,1.1默认支持长链接;
1.1节约带宽;1.1支持可以只发header信息,服务器认为客户端有权限请求则返回100,否则401,如果是100则客户端继续发送body请求,否则不再继续请求,节约了带宽;
2.0支持多路复用,即一个连接并发处理多个请求,并且并发请求的数量比1.1大很多,2.0还支持对header数据进行压缩,传输的更快;

8、启动模式,ActivityA -》B -〉C,如何启动A让B,C出栈
9、 app启动流程
在桌面点击app图标,lancher进程就会向System_server进程发生startActivity请求
System_server进程收到请求后通过socket与zygote进程通信请求创建进程,zygote进程就会fork出App进程
随后调用ActivtyThread.mian()启动程序,然后再调用AMS的attachApplicatin()方法,然后发送scheduleLanchedActivty(),发送LAunch_Activty
10、lifecycle原理
11、Retrofit原理
12、ViewGroup用了什么设计模式
13、View生命周期方法
14、动态代理
静态代理实现: 创建一个接口,被代理对象和代理对象同时实现这个接口,代理类持有被代理类的对象引用,调用代理类的方法,间接调用被代理类的方法
缺点:如果接口添加或者删除一个方法,被代理类和代理类同时都要修改 ,并且代理类需要代理全部的方法
动态代理:
15、kotlin协程
16、late init ,by lazy区别
17、Android进程通信
18、为什么不选用Linux通信机制(Binder 一次拷贝)
19、HandlerThread
20、Service启动方式
bindService和 startService
startService生命周期onCreate onStartCommand onDestroy 多次调用 onCreate只会执行一次,onStartCommand执行多次启动之后服务会一直存在 直到调用stopService
bindService生命周期onCreate onBind onUnbind, onDesdroy 多次调用onCreate onBind只会执行一次 生命周期跟随调用者,调用销毁时必须与该服务解绑 ,可与service交互,执行service中的操作
yon
使用场景: 开启一个后台服务长期执行某项任务使用startService
需要与调用者交互用bindService. 既需要交互又需要长期执行 ,两者可结合使用,断开服务时,unBIndService与stopService都需要执行;
21、HashMap,ConcurrentHashMap,HashTable原理。
22、了解AMS吗
23、Android内存泄漏处理

1、项目,性能啥的 忘了,直播用的什么协议
2、Synchronied优化:轻量级锁重量级锁区别,自旋锁自旋多少次升到重量级锁 轻量级锁里面是什么
自旋10次到重量级
3、双亲委派模型,作用 类加载器
java虚拟机使用java类的过程:
将java文件通过javac 编译器编译成.class文件,然后类加载器读取.class文件,转换成java.lang.class对象
类的加载过程:
加载:加载器将.class文件加载到JVM中
连接(解析,验证,准备):
验证:验证加载的数据,是否对JVM造成伤害。
准备:正式为类变量分配内存并设置类变量初始值
解析:符号引用转直接引用
初始化:对静态变量真正的赋值

JVM中的三层类加载器:
Bootstrap ClassLoader: 主要负责加载核心的类库(java.lang.*等),
都是运行JVM所必须的jar包,构造ExtClassLoader和AppClassLoader

ExtClassLoader: 扩展类加载器,主要负责加载JAVA_HOME_jre/lib/ext目录下一些扩展的jar包;
AppClassLoader: 主要负责加载应用程序的主函数类(开发者在应用程序中编写的类),即CLASSPATH下的所有jar包

双亲委派模型的工作过程:
(1)、当前类加载器在自己加载的类中查看是否已经加载过这个类,如果有则不再加载并返回,如果没有则委托给父类去加载
(2)、父类拿到这个类加载请求后也是同样的策略,查看自己之前有没有加载过,没有则委托给她的父类类加载器
(3)、直到这个类加载请求委托到了根类加载器,跟加载器加载失败后会委托他的子类去加载,子类查看这个类有没有在他的
加载目录下,有则加载没有则传给他的子类,如果到AppClassLoder还没有加载成功,则抛出ClassNotFoundException。

双亲委派模型的作用:
(1)、保证类不会被重复加载(区分两个类是否相等,除了区别类名之外,还会看两个类加载器是不是同一个),
jvm内存是宝贵的,没必要保存多份相同的Class对象,如果没有使用双亲委派,而是自己加载自己的,就会加载出多分相同的
class对象。
(2)、也保证了核心API不会被篡改,如果没有使用双亲委派模型,每个类都用自己自定以的类加载器去加载,就会出现一些问题
比如自定义一个java.lang.Object类,那么系统运行时就会出现多个Object类

3、ArrayListl扩容,HashMap扩容。加载因子比0.75小或者大会怎样
过大增加链表的长度,查询效率变低。 过小空间利用率变低,造成资源浪费
4、ThreadLocal作用,是个啥
5、loop()为啥不会死循环
6、idleHandler 应用场景
(1)、Activity,Fragment,Dialog的onCreate,onStart,onResume一些耗时较短,
但是非必须的任务放到idlequeue中执行,减少启动时间
(2)、 ActivityThread里面的GcHanlder,距离上次Gc时间超过5s,执行GC
(3)、发送一个返回true的idleHanlder,让某个view不行的闪烁,吸引用户
7、HandlerThread作用
8、怎么在子线程中应用Handler
new Thread(new Runnable() {
@Override
public void run() {
Looper.prepare();//Looper初始化
//Handler初始化 需要注意, Handler初始化传入Looper对象是子线程中缓存的Looper对象
mHandler = new Handler(Looper.myLooper());
Looper.loop();//死循环
//注意: Looper.loop()之后的位置代码在Looper退出之前不会执行,(并非永远不执行)
}
}).start();

9、RecycleView缓存
10、binder相对于Linux通信好处
11、mmap是个啥
12、bitmap 怎么放到磁盘里。是几级
13、xml怎么写更好,merge作用,include作用
merge,include 主要为了解决layout布局的重用,当不同的activity的布局一致时不需要重复定义多个xml布局,
使用include标签引入同一个布局
merge标签一般和include标签配合使用,inlude标签有一个副作用就是它多裹了一层root节点,使用merge标签代替root节点,
在include的时候会自动忽略merge节点

使用这两个标签最容易出现的问题:
在RelativeLayout中使用include标签,
但是却发现include进来的控件无法用layout_alignParentBottom="true"之类的标签来调整。
其实解决方法非常简单,只要你在include的时候同时重载下layout_width和layout_height这两个标签就可以了。
如果不重载,任何针对include的layout调整都是无效的!
14、IntentService
15、LruCache是什么策略,手写LruCache

十二、比心

1、volitale与synchronized区别 原理,多线程情况下i++会大还是会小?
2、Handler原理 loop为什么不会死循环 怎么保证一个线程一个looper
3、hashmap1.8做了什么优化 扩容做了什么优化 为什么是2倍扩容
扩容优化:不需要再去重新计算hash值,只需要看原来hash值新增的1位的那个位置是0还是1,是1的话新的下标为原来的下标+就数组容量,为0则位置不变
4、JVM内存模型 线程私有的是哪些?
5、内存优化做过哪些? UI优化怎么做?
内存优化三个方面:内存泄露 内存溢出 内存抖动
内存泄露原因:handler 异步代码 单例模式持有context。静态变量持有生命周期外的对象。非静态内部类
内存溢出:加载过大的bitmap
内存抖动:onDraw里面创建大量临时对象
优化可分为:内存优化 UI优化 绘制优化 包体积
6、线程安全的队列有什么?
7、DecorView创建时机,activty,window,view的关系?window的创建时机
window创建时机:通过handleLaunchActivity后创建了Activity,随后调用actiivty.attach()创建了PhoneWindow,并且创建了windowManager,window持有windowManager的引用;然后在setContentView中调用了window的setContentView(),并且创建了DecorView;在handleResumeActivty中调用了windowManager的子类的WindowManagerIml的addView(),在addView()中调用WindowManagerGlobal的addView(),然后创建了viewRootImpl,调用ViewRootImpl的setView(),然后调用requestLayout()-》perforoTraversals()开始绘制
8、自定义一个LineaLayout步骤
9、加载一个比较大图片会怎么做?
压缩图片:创建BitMapFactory.option 将option的inJustDecodeBounds设置为true,加载图片将option传进去,获取到图片的实际宽高,根据实际宽高和view的宽高计算图片采样率,将采样率设置给option,并且option.inJustDecodeBounds设置为false,然后重新加载;
计算采样率:
10、kotlin对比java有什么优点?协程与线程的区别
11、leakCanary原理
13、view绘制三大流程是从哪个类里面开始的
14、子线程可以使用Handler吗 Lopper.myLopper()是怎么拿到当前线程的looper的
15、有没有自定义gradle过插件
16、介绍一下在b站具体干些什么
17、范型的类型擦除 类型擦除后怎么获取范型信息
18、RecyclerView的优化
19、idleHandler是什么

1、介绍之前在公司做的事情 用到的技术
2、图片裁剪的方式有哪些
3、贴纸需求。皮肤加载需求
4、gilde的缓存有哪些
5、retrofit里面动态代理怎么用的 retrofit和okhttp的区别
6、图片格式有哪些 有什么区别
7、推流拉流有没有接触过
8、aidl传输的数据类型有哪些?数据大小有什么限制?

十三、百度

1、项目,图片加载 为啥不用glide
2、rxjava切换线程原理
3、java编译器与运行期的区别
编译器:检查语法错误,如果没有则将java文件转成class文件
运行期:java虚拟机分配内存,执行class文件
4、Java基本数据类型
5、为什么有基础类型的封装类,Integer a = 123, Integer b = 123 a是否等于b? Integer a = 123, Integer b = 128 a是否等于b
6、Handler的延迟消息怎么拿到的?为啥loop不会造成ANR?MessageQueue是什么数据结构?怎么实现子线程里给子线程发消息
7、View的绘制流程, 父view是wrap_content,如何确定它的大小?
Meassure,layout,draw 主要干啥
8、activity正常情况下生命周期,按home键生命周期如何?再回到activity如何?
9、activity弹出dialog,activity的生命周期?
弹phoneWindow是否影响生命周期?
10、activity A的启动模式是singletask,目前位于栈顶,当再次启动这个activity,会回调哪些生命周期?
onNewIntent() onRestart onStart
11、用applicationContext启动activity为啥报错?
standard模式的Activity每次被启动时不管任务栈有没有该Activity实例存在,都会创建一个该Activity实例,该实例被放在启动这个standard模式Activity的那个Activity实例所在的任务栈里(即谁启动它,它就和谁放在一起(放在同一个任务栈)),这里启动这个standard模式的Activity的不是Activity,而是ApplicationContext,它不是Activity不会放在任务栈,所以当ApplicationContext来启动Standard模式的Activity的时候,这个standard Activity会发现自己找不到任务栈来安置自己,因此报错。
12、链表找中间节点
13、跳台阶

十四、微博

1、给Fragment传递参数时,可以使用set(), 或者通过fragment构造方法传递有什么问题?用setArguments(),如果有一个接口,想要给fragment传递数据,activity通什么方式给Fragment通知
2、第三方库用过哪些,简单介绍一个
3、surface view与普通view的区别
4、子view可以超出父view的大小吗?
可以,给父容器的父容器设置clipChildre = false,这样view的大小就可以超出父view
5、怎么通过Java实现kotlin中扩展方法
6、热修复,Android中可以通过类加载器加载class文件吗
7、view绘制流程

1、自定义view
2、handler,post里面的方法执行在哪个线程
3、范型类型擦出
4、反射应用场景
5、动画,帧动画,

十五、 拼多多

1、知道前序中序求后序
2、tcp,udp的区别 http和https的区别,https的过程,加密算法,加密算法原理
3、handler机制,假设主线程有两个handler A和handlerB,A发送一个耗时消息,B 执行removeAllCallbaks,A的耗时消息还会执行吗
4、写快排

1、一个界面的显示用什么类,估计是想问activity和fragment
2、直播H265,H265区别 不会。 直播是怎么把一个视频播放出来的?用的url还是啥
3、tcp,udp区别,应用场景 https 对称加密和非对称加密算法的特点。两个性能和安全的比较
4、tcp三次握手
5、hashmap和hashtable区别
6、创建线程的方式
7、mvvm,mvp,mvc的区别
7、反转链表,二叉搜索树的最近公共祖先

1、二叉树转链表

十六、 小红书

1、GCroot ,全局变量能作为GCroot吗
2、handler机制 Lopper存放在哪 ThreadLocal原理
3、hashmap原理
4、livedata原理
5、activity启动模式。应用场景
6、遇到的困难 项目中遇到的困难
7、android性能优化
8、binder机制。ServiceManager 是干啥的。 server端向service Manager 怎么注册的 中间需要什么。binder驱动是干啥的?
8、旋转链表算法
9、绘制流程。MeasureSpec测量模式有哪些? 从setContentView开始说
为啥在onResume中才显示出来?
onDraw绘制的流程 先绘制背景 然后呢?

十七、前程无忧(烂公司)

1、重写和重载的区别?
静态方法可以被继承吗 可以被重写吗
方法名一样,参数一样 ,返回值不一样 ,可以重载吗?
2、jvm垃圾回收机制
3、绘制原理测量模式
4、事件分发机制 move事件 和 up事件分发
depatchTouchEvent返回false会怎样
5、MVP MVC MVVM区别。MVP缺点。p层怎么把数据返回给 View 什么代码写在viewmodel中?
6、有做过哪些有挑战的需求
7、debug工具。debug可以获取到什么信息,debug可以过滤吗
8、kotlin相对于java的优点 kotlin单例怎么实现?
9、单例模式实现方式有哪些
10、观察者模式使用场景
11、lifeCycle原理。lifecycle的实现类 lifecycleRegistry是怎么样
12、代码审查机制?
13、git merge 和 git rebase的区别
14、进程间通信
15、android版本

十八、 其他别人的

作者:古道肥马
链接:Android面经
来源:牛客网

你可能感兴趣的:(android)