2024年3月份Android 面经总结!(OPPO和腾讯等大厂)

boss 直聘 HR 推了简历给有关部门,简历通过后电话约的面试机会。当时约的是 10:30 的面试时间,所以只请了半天假。

第一轮是两个面试官轮流问问题,第一面大约面了一个小时,大约等了十几分钟第二面的面试官把我叫到了 另外一个办公室,也是两个面试官轮流问了大概一个小时,面完二面后就差不多到了下午一点,面试官说我带你去食堂吃个饭,吃完饭面试官帮我约了下午两点的 HR 面。感觉整个流程下来非常爽,总共三轮面试,两轮技术面(每轮2个面试官),一轮 HR 面。

技术一面

1. mmap + native 日志优化?

讲了传统日志打印的两个性能问题,一个是反复操作文件描述符表,一个是反复进入内核态,然后讲了 mmap 的原理机制。

2. 讲讲 Android 开机启动的流程

讲了一大堆,其中说到 ServiceManager 进程是用来管理系统服务的,面试官说你确定?不是 SystemServer 进程来管理系统服务的吗?讨论了一番面试官懵逼了,提到了 SystemUI 服务,提到了桌面进程,问到了怎么替换开机启动的动画?

3. 系统是怎么帮我们启动找到桌面应用的

我说通过意图,他说怎么找到是哪个意图? 我说 PMS 会解析所有 apk 的 AndroidManifest.xml ,如果解析过会存到 package.xml 中不会反复解析,PMS 有了它就能找到了。

4. 讲讲动态状态页的加载,为什么要这么弄?

我说为了减少 xml 解析和反射创建对象的时间,避免同时创建多个用不上的对象,我就写了个框架用代码动态添加的。这时面试官误解了我的意思,以为所有的界面都是用代码写的,那得多麻烦呀,后来解释清楚了。

5. 讲讲页面的刷新机制,GPU 调试工具几个颜色值分别代表什么?

讲到了 Surface 底层管理的其实是 IBPQ , 讲了异步信号的由来是 SurfaceFlinger 由硬件和软件机制发出来的,讲了我们 app 界面绘制的内容是怎么提交传递到 SurfaceFlinger 的。GPU 调试工具几种颜色的意思也大概讲了下。

6. 说说 ConcurrentHashMap 的实现原理说下

是线程安全的,实现原理采用的是分段锁。

7. 你知道 okhttp 是怎么复用连接的吗?

这是个网络优化的问题,同一个 ip 同一个端口能复用一个连接,后面问道了 http 2.0 的多路复用,我说一个 tcp 可以多个请求,原理呢?我说不知道。后面让我说了下 https 。

8. 数组和链表的区别说下

9. 快排和递归

技术二面

1. 讲一讲动态注册和静态注册

静态注册是通过包名和函数名去找方法,动态注册是通过注册方法表,其中还被问到了具体是调用哪个函数注册方法表。

2. so 的加载流程是怎样的,生命周期是怎样的

这个要从 java 层去看源码分析,是从 ClassLoader 的 PathList 中去找到目标路径加载的,同时 so 是通过 mmap 加载映射到虚拟空间的。生命周期加载库和卸载库时分别调用 JNI_OnLoad 和 JNI_OnUnload() 方法。

3. native 层怎么检测内存泄漏

我说按道理可以 hook 函数,开辟内存和释放内存的次数应该是一样的,如果不一样可以怀疑内存泄漏。面试官接着问有没有什么第三方工具或者库可以检测?我说我在公司其实也写的不多,不知道引擎组集成的是啥框架,主要擅长应用层开发。

4. leakcanary 的原理,哪些对象可以用来做 gc-root

好,你说你主要擅长应用层开发,那 Java 层的内存泄漏怎么检测,我说我们用的 leakcanary,让我说说原理,说完原理又问我是不是所有对象泄漏 leakcanary 都能检测得到,他的引用链是怎么管理的?后面问到你刚说弱引用对象在 gc 的时候会被释放,那什么时候不会被释放?我这时懵逼了,其实就是有内存泄漏的时候不会被释放,我当时脑子短路了居然没反应过来。

5. ui 怎么优化的?

我主要从底层讲了一下 UI 刷新机制的流程,又把一面的 SurfaceFlinger 底层机制讲了一遍,原理搞清了就可以做很多优化,巴拉巴拉说了一大堆,最后讲了怎么去监听 UI 卡顿。

6. 线程耗时卡顿怎么监听的?

主要用工具去检测,当时只提到了 systrace + 函数插桩的方式。

7. 说说你看的 Tinker 的原理?

8. 你遇到的最难解决的问题?

我说我们公司项目没有采用动态加载框架,但是后面集成 U3D 项目需要动态加载,但只需要用到 so 和资源动态加载,功能上第三库也不支持我们的需求,我就自己硬着头皮看了各大版本的源码,支持动态修复替换加载 so 和 assets 资源动态修复加载,然后把具体的细节说了一遍。

9. 常见数据结构你都熟悉哪些?不是本专业算法你是怎么学的?

数组,链表,堆,二叉树,队列,栈,平衡二叉树,红黑树,霍夫曼树,图。自己看书算法通过刷题,这里没具体问算法细节。

10. 线上有人反馈问题你一般怎么处理的?

开发过程中记录关键日志,线上获取用户日志来分析。

腾讯面试过程


oppo hr 面完大约晚上九点刚下班到公司楼下来电了,问方不方便我当然说方便,就在马路边上面了大约 50 来分钟,我感觉应该是挂了的,因为过程中电话老是断加上环境又比较吵。过了整整一周到了隔周五上午接到了第二面的面试通知,约的是隔周三上午 10:30 。第二面面试官时不时的面带笑容,给人很轻松的感觉。二面完后要我稍等一下接着面三面,三面面完面试官问我下午还有事没?我们*(应该是领导)有点事,下午四点左右可以面第四面,具体我也没听清楚是谁我也不敢问。我说下午要上班就先回去了,下午接到 hr 电话约的是隔周二的上午。总共五轮面试含 hr 面,持续周期一个月左右。

技术一面

1.mmap + native 日志优化?

讲了传统日志打印的两个性能问题,一个是反复操作文件描述符表,一个是反复进入内核态,然后讲了 mmap 的原理机制。

2.广播和 EventBus 的区别?

说 EventBus 的实现原理是基于反射,里面管理了两张表,且代码之间关联性不大不易于维护,EventBus 不支持跨进程通信,被面试官反问你确定不支持跨进程?我说我的看的源码是不支持,面试官说那好吧。

3.常用设计模式你了解哪些?

我开始巴拉巴拉说了一大堆,其中说到了装饰设计模式,被面试官打断了,请你具体说说装饰设计模式。

4.跨进程通信有哪些?

管道,信号,信号量,文件,本地套接字,共享内存,binder 驱动

5.简单讲讲 binder 驱动吧?

从 Java 层来看就像访问本地接口一样,客户端基于 BinderProxy 服务端基于 IBinder 对象,从 native 层来看来看客户端基于 BpBinder 到 ICPThreadState 到 binder 驱动,服务端由 binder 驱动唤醒 IPCThreadSate 到 BbBinder 。然后又讲了虚拟内存、物理内存和内存映射,跨进程通信的原理是要基于内核的, 当我讲到 binder_open 、binder_mmap 和 binder_ioctl 是被面试官打断了,估计是怕我讲太久了。

6.跨进程传递大内存数据如何做?

我说 binder 肯定是不行的,因为映射的最大内存只有 1M-8K,可以采用 binder + 匿名共享内存的形式,像跨进程传递大的 bitmap 需要打开系统底层的 ashmem 机制。

7.说说 ConcurrentHashMap 的实现原理说下,初始化大小是多少?

是线程安全的,实现原理采用的是分段锁,初始化大小是 16 ,必须是 2 的幂次。

8.启动优化怎么优化?

我说了关键优化 Application ,被面试官打断了,说大家都能想到的东西你不要说了,我想听的是你能不能站在系统的角度去做一些优化,我提到了优化包体积大小能优化启动速度,优化 dex 分包能优化启动速度,可以参考最新的华为方舟编译器等等。

9.你写的 rxpay 和 rxlogin 具体怎么实现的?

一般我们集成第三方登录和第三方支付 SDK 都需要监听 onActivityResult 方法,我是参考了 RxPermission 的实现方案添加了透明 Activity 。

10.kotlin + fullter 方面的

kotlin 自己学了语法但是开发项目中没用上,fullter 我是了解了它的实现原理但是开发中也没用上。

技术二面

1.单例设计模式都写写,静态内部类是怎么保证线程安全的?

2.synchronized 底层实现原理,ReentrantLock 公平锁与非公平锁。

3.主线程等待所有线程执行完毕,再执行某个特定任务怎么实现?原理和源码看过没?

4.自定义 view 的一般流程,要注意些什么如何优化,点击事件和长按时间分别是怎么实现的?

5.四种启动模式,在源码分析中的原理是怎样的?

6.讲讲 bindService 的过程,你当初是怎么优化后台服务进程的?

7.开发中你都用到了哪些设计模式?说说当时具体的场景。为什么你要用方法工厂,另外两种呢?

8.RxJava 在使用过程中碰到了某些不友好的错误一般怎么解决?发现了内存泄露一般怎么解决分析,有没有碰到过系统服务内存泄露的问题?

9.你们用的 okhttp ?那你有没有做过一些网络优化呢?比如弱网环境。

10.给你个数 1 吧,比如 1000011 里面有几个 1 ?

11.快排了解不?最坏的情况是怎样?如果有大量重复数据怎么优化?

技术三面

1.讲讲 handler 的底层实现原理?

这么简单?问到碗里来了,后面渐渐说到延迟消息是 nativePollOnce 来处理的,在 6.0 以上用的是 epoll 方式来监听文件描述符。接着问道了为什么要用这种方案?它跟 poll 和 select 比起来有哪些优势?它是怎么监听的你看过它的内部实现原理没?反正感觉很难受了。

2.说说你做的日志记录优化?

把第一轮面试的又讲了一通,你在每个文件的最后写入了当前内容的大小,你有没有想过如果文件被破坏的情况?这种异常情况怎么处理?后面还问到了加密和压缩。

3.你看过 binder 驱动的源码,说说他的内存映射过程,说说客户端等待服务端处理返回的流程,如果要跨进程传递大内存数据你具体会怎么做?简单写一写吧。

4.在公司做过哪些优化?

内存优化,启动优化,网络优化,包体积优化,具体说说包体积优化。我提到了包体积优化不仅仅是优化了包的大小,包体积太大从安装的那一刻开始,我们的应用就可能比较慢了,因为 pms 会去拷贝解压解析我们的 apk 安装文件,会去优化我们的 dex 等等,包体积太大还会影响我们的启动速度。然后就巴拉巴拉说具体怎么做,问到了为啥混淆资源能减少包体积大小?你当时优化的时候效果是怎样的减少了多少?

5.开发过程中遇到的一些最难解决的问题?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值