小米Framework专项面试:小米Android开发覆盖MIUI系统定制、IoT设备互联。技术栈偏底层,面试官喜欢问系统级原理和性能数据。技术方向偏向MIUI定制、IoT互联。特色专项包括MIUI系统定制与IoT设备开发。今天8道题覆盖小米Framework专项面试核心考点。
Q1:AMS进程管理和优先级调度?
AMS维护所有App进程的ProcessRecord。进程优先级(adj值)决定被LMK(Low Memory Killer)杀死的顺序:前台(0)→可见(100)→服务(200)→缓存(900+)。AMS在内存压力时通过lmkd按adj从高到低杀进程。进程优先级动态变化——Activity可见时adj=0,退到后台变为缓存进程。startForegroundService能把服务进程提升到可见级别。
深度解析:这道题属于Framework的基础盘,面试官想确认你不是只会调 API。回答时先一句话给定义,再结合小米的澎湃 OS / HyperOS 与跨端体验。业务场景举例,最后补一个你做过的案例或踩过的坑,比背结论更得分。
追问:onTrimMemory的级别对应什么?TRIM_MEMORY_UI_HIDDEN(Activity不可见)→TRIM_MEMORY_BACKGROUND→TRIM_MEMORY_MODERATE→TRIM_MEMORY_COMPLETE(即将被杀)。
Q2:Broadcast的有序/无序和静态/动态注册?
无序广播(Normal Broadcast):所有接收者几乎同时收到,不保证顺序,不可拦截。有序广播(Ordered Broadcast):按优先级依次传递,高优先级可拦截(stopResult)或修改数据。动态注册(Context.registerReceiver):运行时注册,跟随组件生命周期,APP不运行时收不到。静态注册(AndroidManifest中):Android 8+大幅限制——大部分隐式广播只能动态注册(BOOT_COMPLETED等少数例外)。
val filter = IntentFilter("com.example.MY_ACTION")
filter.priority = 100
context.registerReceiver(receiver, filter, Context.RECEIVER_EXPORTED)
深度解析:这道题属于Framework的基础盘,面试官想确认你不是只会调 API。回答时先一句话给定义,再结合小米的澎湃 OS / HyperOS 与跨端体验。业务场景举例,最后补一个你做过的案例或踩过的坑,比背结论更得分。
追问:为什么Android 8限制静态广播?静态广播每次都拉起App进程,多App同时被拉起会造成系统负载激增(广播风暴)。
Q3:Android系统启动:从按下电源到桌面?
整个链:Boot ROM→Bootloader→Linux Kernel初始化→init进程(第一个用户进程,pid=1)→解析init.rc启动service manager(Zygote、servicemanager、surfaceflinger等)→Zygote fork出system_server→system_server启动AMS/PMS/WMS等系统服务→AMS启动Launcher→Launcher显示桌面图标。
深度解析:这道题属于Framework的基础盘,面试官想确认你不是只会调 API。回答时先一句话给定义,再结合小米的澎湃 OS / HyperOS 与跨端体验。业务场景举例,最后补一个你做过的案例或踩过的坑,比背结论更得分。
追问:冷启动时App内部发生了什么?Application.attachBaseContext→onCreate→第一个Activity的onCreate→onStart→onResume→首帧draw。优化关键在Application.onCreate的不必要初始化。
Q4:Zygote进程的fork为何能加速启动?
Zygote由init进程启动后预加载了常用类、资源、JNI库,然后通过Socket监听等待请求。新启动App时AMS通过Socket通知Zygote fork出子进程。fork是Copy-on-Write——子进程跟父进程共享内存页直到某方写入时才复制。Zygote已加载的资源子进程直接用,省了重复加载时间。
深度解析:这道题属于Framework的基础盘,面试官想确认你不是只会调 API。回答时先一句话给定义,再结合小米的澎湃 OS / HyperOS 与跨端体验。业务场景举例,最后补一个你做过的案例或踩过的坑,比背结论更得分。
追问:为什么Zygote用Socket而不是Binder通信?fork之前如果有Binder线程,子进程Binder驱动状态会乱套。Socket单线程最安全。
Q5:SurfaceFlinger是干什么的?
SurfaceFlinger是Android系统的合成器(Composer),运行在独立进程。每个Window对应一个Surface,有一个BufferQueue(生产者-消费者模型)。App往Surface画像素(生产者),SurfaceFlinger收集所有可见Layer按Z序合成(消费者),然后送到硬件显示。优先用HWC(硬件合成器)而非GPU合成来省电。
追问:双缓冲和三缓冲的区别?双缓冲容易产生等待(前缓冲显示中,后缓冲画完只能等)。三缓冲多一个buffer减少等待但增加约1帧输入延迟。Android默认三缓冲。
Q6:AIDL生成的Stub和Proxy怎么协作?
AIDL编译后生成Java文件:Stub(服务端)继承Binder实现onTransact()——根据方法code分发到具体的业务方法。Proxy(客户端)持有IBinder引用,调任何方法时都是把参数序列化进Parcel,然后调transact()跨进程发送,再反序列化返回值。oneway修饰的方法不等待返回值。
val data = Parcel.obtain()
mRemote.transact(TRANSACTION_getData, data, reply, 0)
return reply.readString()
追问:onTransact在哪个线程执行?Binder线程池,默认最多16个线程——不是主线程,需要注意线程安全。
Q7:AMS如何管理Activity的启动?
startActivity的完整链路:ContextImpl→Instrumentation→AMS(通过Binder跨进程)→AMS检查权限和声明→创建ActivityRecord→查找或创建TaskRecord→通知WMS准备窗口→通过ApplicationThread回调目标进程→创建Activity→回调生命周期。AMS维护了系统中所有ActivityRecord和TaskRecord的全局状态。
追问:AMS怎么决定在哪个进程启动Activity?通过ProcessRecord查找,如果进程不存在则通过Socket通知Zygote fork新进程。
Q8:InputManagerService如何分发触摸事件?
触摸事件链路:硬件驱动→EventHub读取原始事件→InputReaderThread解析为MotionEvent→InputDispatcher找到目标窗口→通过Socket发送到App进程→ViewRootImpl接收→DecorView.dispatchTouchEvent→ViewGroup事件分发。InputDispatcher通过WindowManager获取窗口层级和焦点信息,决定事件发给哪个窗口。
追问:为什么触摸事件用Socket而不是Binder?Binder有1MB缓冲区限制,高频触摸事件可能溢出。Socket是InputDispatcher专用通道,独立缓冲区。
把技术讲清楚才是真懂
能用大白话给外行讲明白,说明你真的理解了。练习时逼自己一句话概括本质,再用一个生活类比辅助,最后回到技术细节。比如把『消息队列』类比成排队取号,把『垃圾回收』类比成收拾房间。表达清晰本身就是高级工程师的核心素质。
下一篇进入小米Compose专项——Compose性能优化、Compose自定义Layout怎么实现、Compose动画的核心API。
觉得有用的同学扣1,你面试被追问最狠的是哪道题?
本系列连载中,关注不迷路,下一篇:小米Compose专项面经:Compose性能优化、Compose自定义Layout怎么实现、Compose动画的核心API
系列简介:Android大厂面经连载,覆盖字节跳动、腾讯、阿里、美团等40+企业,从初级到架构师全岗位覆盖。每篇文章包含真实面试题+详细答案+代码示例,帮你拿到大厂Offer。