13

三年 Android 经验面经

 4 years ago
source link: http://mp.weixin.qq.com/s?__biz=MzIxNzU1Nzk3OQ%3D%3D&%3Bmid=2247489943&%3Bidx=1&%3Bsn=c72f1c1fea5f5871ad93df361073ac40
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

code小生 一个专注大前端领域的技术平台 公众号回复 Android 加入安卓技术群

作者:New_X

链接:https://www.jianshu.com/p/a2b3831fbf2e

声明:本文已获 New_X 授权发表,转发等请联系原作者授权

除非大厂,其他都问的差不多,问大部分也就着简历问,问了5年+的,也差不多就问这些...都是基础吧,区分度应该主要在于项目经验匹配度、职业素质、思维和运气上。

1. 基础

  1. 自定义View的流程,requestLayout和invalidate的区别

--> ViewRoot的performTraversal切入measure、layout、draw(讲完基础,可提一提Surface的显示原理)

  1. Handler原理,Handler/Looper/MessageQueue关系

--> 消息循环需要创建一个Looper并利用ThreadLocal绑定到当前线程,内部创建了MessageQueue(是个单链表结构),当前Handler通过Looper取消息,可向不同的Handler发送消息,达到线程间通信的目的(意识流的谈到了消息屏障和Choreographer)

  1. 子线程可以运行looper吗?多次looper. prepare会不会有问题?怎么进入循环的?looper.loop的关键点?消息延迟怎么实现?延时的依据是什么?为什么?

--> 可参考HandlerThread以及基于HandlerThread实现的IntentService(可以往ThreadLocal切入,也可以往底层运行机制);注意延时是根据开机后的时间,但可能因为消息堆积造成不精确

  1. 事件分发机制

--> 从Activity的dispatchTouchEvent切入,ViewGroup和View的onInterceptTouchEvent,onTouch优先于onClick

  1. 绘制为什么要二级缓冲?一级二级三级演变的原因?

--> 和消息循环的消息堆积类似,会滚雪球(双缓冲技术是游戏开发中的一个重要的技术,也是SurfaceView和View的一个主要区别,解决解决反复局部刷屏带来的闪烁)

  1. Aspectj是运行时织入还是编译时织入?

--> 我的理解是都有的

  1. jvm编译优化是什么意思?

--> 运行和编译时都有优化,以循环、反射、锁的优化举例(可以引申到方法内联、栈上分配、标量替换,再多总结总结jvm相关知识形成一个闭环,是个很大的亮点)

  1. 责任链在framework里的应用?

--> 事件分发、View绘制(更偏组合模式)

  1. 启动优化?异步了为什么还要优化?

--> 启动器(注意任务的依赖关系,参考work-steaking机制可作为后期优化方向)+ 结合业务 + SP的不足 + Provider + 锁检查等(业务不复杂,其实收益不明显,但是知道好过不知道,很多黑科技得慎用)

  1. 插件化原理,换肤原理,热修复原理,插件化怎么实现把apk渲染成界面的?

--> 这几个都是热门话题,其实现实中负责相关开发的应该不多,但是可以提现技术追求,答出要点即可,细坑背也没用的,你没做过啊

  1. mmkv一般不是做缓存的吗?为什么和启动优化有关系?

--> 启动期间用到了SP,MMKV是可以无缝替代SP的,顺便可以提提mmap原理,引申到binder,谈谈为什么mmap可靠,mmap其实也不是银弹

  1. 说下udp、tcp和socket?

  2. 说下http,以及http是基于tcp还是udp?为什么?

  3. tcp的可靠性怎么保证的?--> 三次握手、奇偶校验(Checksum)、超时重传、滑动窗口(是根据tcp头信息的seq实现的,分成多部分数据)

  4. 数组和链表的区别?

--> 可从实现,扩容,增删改查角度切入

  1. app点击到启动第一个activity的流程?

--> 可能毕竟3年,framework深点的问来问去就这一个,感觉白看这么久了(虽然确实很难apply到实际工作上,但这个启动流程知道其实能解决很多问题,而且可以牵带问向其他问题,插件化、渲染、组件通信、优化等)

  1. 项目是MVVM还是MVP,怎么实现的?有没有引入LiveData?

  2. 讲一下优化相关的

--> 启动优化、内存优化、埋点优化(业务向),这几个印象深,如果不打断,结合底层知识,半小时都不够讲(我一直怀疑我面试的时候说的太多,会不会太啰嗦了...)

  1. 有没有做过Socket和串口通信,有用过蓝牙吗?

--> 这个真没有,只有大学期末作业写过蓝牙聊天室

  1. 有没有用过kotlin?协程有了解吗?

--> kotlin是入门水平,但是其实如果很看重这个,说明项目深度接入kt,各种扩展方法应该都是封装的很好的,快速上手肯定没问题

  1. 用过Flutter?

--> Flutter学过好几遍了,但是一直没有商业项目来apply,真的想尝试,但是精力有限,我还是先挖深度吧

  1. 分层架构怎么理解?

--> 这个需要结合组件化、模块化来讲,也是个演进过程,先拆,再聚合为一层,拆的过程也是煎熬的(尤其是原先项目很耦合的情况,根本没法多人协作进行,merge全是冲突,举棋不定的需要temp层),可以结合OSI七层网络架构,Binder分层等经典实现升华

  1. 反射的原理和应用?--> 反射是Java的一大特性,无处不在,ide代码提示就是,而且需要做些高级功能就需要结合反射,比如动态代理,升华一下可以讲反射为什么慢的原因,jvm对其的优化等

  2. 屏幕适配使用哪个方案?有了解过AutoSize吗?

--> sw限定符没出问题,没考虑其他方案,头条的适配方案,肯定了解过

  1. onCreate和onPostCreate的区别(onResume和onPostResume的区别)?

--> 这是个很细节的点,我确实不知道,但是其实无伤大雅,生命周期相关,AspectJ切一下,一目了然

  1. 深拷贝和浅拷贝的区别,序列化是深拷贝还是浅拷贝?

--> 序列化就是简单实现深拷贝的一种方式

  1. 贝塞尔曲线怎么实现?

--> UI绘制是我弱项,但写了一次发现其实真的是数学相关,其注意点和优化点,IDE都有提示...

  1. Activity、Window、View的联系?

--> 从Activity开始显示View切入辅以一些拓展,感觉很清晰

  1. View的绘制流程,测量模式?

  2. Android的两个特别重要的服务是什么时候启动的?

--> 以为是问的android系统启动的概览,其实问的是WMS和AMS启动(这个我就没懂想要知道什么要点了),回答了是分批分阶段启动,目的是为了解决相互依赖的问题和提升启动速度

  1. 滑动窗口如何实现?

--> 滑动窗口的实现主要是把发送内容分成几部分,然后边确认边发送,发送窗口就逐渐往前滑动了,接收方同理

  1. start和run的区别?sleep和wait的区别?

--> 这种低级问题,其实我都不想回答...

  1. Thread的join方法?

--> 使用wait来等待结果,可以设置超时,和FutureTask比较<使用Unsafe和CAS实现>(和CountDownLatch<等待事件、利用ReetrantLock实现<内部是AQS,再内部是CAS+UnSafe>>、CyclicBarrier<等待线程,底层实现和CountDownLatch相同>比较)

  1. new Integer(123)和123的区别(Integer.valueOf(123)) --> 基本数据类型有缓存池进行优化

  2. private static 方法,子类能重写吗?

--> private是该类可见,static是类属性,没有重写概念的(这个细讲要从class的加载切入了)

  1. Looper.loop为什么不会导致ANR?

--> ANR的原理和基于消息的机制实现角度,可升华到底层fd

  1. dialog和activity调用getWindow获取到的对象有什么不同?

--> 问的应该是层级问题(上家公司的UI框架应该是参考了Window管理模型的)

  1. Int可以作为线程安全的单位吗?AtomicInteger实现原理?

--> CAS+版本记录

  1. Intent的使用中有遇到什么问题吗?如何解决大图传输问题?

--> 传输上限、类型解析,Ashmem

  1. 双向认证的流程?

--> 其实就是https加了个验证client端的步骤

  1. 启动模式的应用场景?

  2. 熟悉的设计模式?

  3. 异常设计?

--> 这个需要很结合业务了,throw和throws的区别,比如sdk抛异常的时机,可以结合讲讲异常的实现原理和比if..else慢的原因

  1. 如何排查内存泄露?

--> 逐渐演进+线上监控

  1. 红黑树的实现原理?怎么染色的?

--> 当时确实记不清了,重点是颜色翻转+临时4节点+二三树+(LL、LR、RL、RR)

  1. 说下常见的排序算法?

--> 冒泡、插入、归并、快速的实现

  1. 说下常见的集合类?

  2. 说下JVM的特性?

  3. 浏览器输入一个url点击发送后发生了什么?

  4. 如何显示一张大图?

  5. 一些多线程和JVM的问题

---> 这两个算强项了,不打断能讲很久

  1. 线程池的实现原理?里面的队列有了解过吗?

2. 开源库

  1. ARouter原理,拦截器怎么实现的?

--> ARouter核心是apt注解生成路由信息,调用init进行初始化,使用navigation进行跳转。拦截器可以实现未登录功能统跳,也是路由功能的(ARouter第一次接触,之前公司的路由框架是自己写的)

  1. okhttp原理,有没有自定义过拦截器,遇到过什么问题?

--> okhttp的亮点在于其拦截器,提了下域名收敛优化,自定义拦截器实现了日志打印,拦截器分为响应前和响应后两大部分,注意一下应该不会有问题。最近帮其他人解决了一个双认证的final问题。

  1. glide的缓存策略

--> 内存缓存(正在使用的用弱引用,不在使用的用LRUCache)+磁盘缓存(可设置缓存类型)

3. 项目相关

  1. 项目中的亮点和难点?工作中对自己感觉提高最大的?

--> 印象比较深的是启动优化和埋点

  1. 埋点实现,如何去除多余的业务埋点,有没有了解过无痕埋点和全埋点?无痕埋点如何加入业务数据。

--> 可以从埋点的演进(域名收敛、结合页面切换、环境切换脏数据、双周期、统一管理实时、mmap+fd)、之前上报策略的问题和当前埋点现状来切入,无痕埋点加入业务数据可以采用脚本化应对产品到易变需求(提了下lua)

4. 发散性问题

  1. 未来的规划?

  2. 如何像一个不懂技术的说明白什么是多线程?

--> 考验语言表达能力

  1. 同一项任务再做一次,你会如何执行?

--> 考验复盘总结能力

  1. 写几个Sql

---> 这个其实不是我强项,我是发散学习过数据库的实现和一些相关注意点,希望以后能够提供一些优化思路(确实会有,数据库相当于一个非常成熟的框架,也是一步步优化过来的,而且发现优化相关有三条线,一是不断演进,二是不断侵入底层<毕竟最终都是实体,线程调度实际上也是为了IO>,三是需要结合不同场景调度不同策略)

  1. 遇到问题怎么解决?

其实没什么好分享的,虽然本来是抱着不进大厂以后就不走技术路线的想法准备的。刷了好几个framework、算法数据结构相关课程,梳理了多线程相关、JVM相关,也刷了一些leetCode等,而且一直工作认真负责,不断思考找突破点,不断跟进优化和埋点,差一步入C和OS,真的只是差一个看对眼的机会(不是自恋,这点信心还是有的,可以说只要不恶意刁难和我脑子不断路,难倒我的不多)。

原计划(本来是抱着不进个叫的出名字的公司就不打算走技术路线的心准备的):小公司热身 --> 拿几个可以的备用offer --> 试一试杭州的大厂 --> 不行,试试上海的 --> 再不行,试试北京的 --> 再不行,南下

但是,后面发现其实路子走窄了,应该备用和大厂面试组合着来的,大厂面试流程久,一直不敢投(原谅一个2020年到现在还没拿到一分钱工资的小Android的内心惶恐,怕上半年就稀里糊涂过了,要恰饭的嘛)

现在先找个离家近的,也比较稳的站稳脚跟(一是安全,二是稳,我觉得后面会越来越难了)。接下来抽时间整理整理现在的知识体系,然后继续挖深深度,遗憾的是这次没冲大厂,而且现在很累,想缓一缓,有机会直接去冲高级。运气也是很重要的一项因素,继续努力,为了早日加入大厂写代码,老了以后在大厂搞保洁。

希望疫情早日过去,希望我后面能好运一些。

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK