当前位置: 首页 > news >正文

android系统framework的几个新面试题目(涉及binder,input,SurfaceFlinger带答案)

背景:

今天给大家分享几个学员朋友面试过程中带回来的几个新面试题,这些面试题目属于比较独特一些,一些不属于1+1=2直接有标准答案,但是需要对模块熟悉后有一些自己的理解和思考答出的开放性题目,比如问题1和问题2就属于这种,所以这种题目可能面试官自己也没有明确的面试答案哈,我这里也整理了一些答案,有的也有ai一些整理归纳功劳哈。

问题1:

系统中audioflingersurfaceflinger作为独立的Native守护进程运行,而inputflingersystem_server进程绑定,为什么inputflinger不作为独立进程

主要基于以下设计考量:

  1. 事件分发的高实时性要求
    Input事件(如触摸、按键)的处理对延迟极其敏感,需要快速响应并分发到应用进程。若inputflinger独立为守护进程,需通过IPC(如Binder)与system_server通信,这会引入额外的进程间通信开销,可能影响事件分发的实时性。而当前集成在system_server中的设计,通过线程级交互(如InputReaderThreadInputDispatcherThread)直接处理事件,避免了跨进程延迟。

  2. 与窗口管理的紧密耦合
    Input事件的分发逻辑高度依赖窗口管理器(WindowManagerService,WMS)。例如,WMS需为应用进程提供InputChannel以接收事件,并处理焦点窗口切换、触摸事件拦截等逻辑。若inputflinger独立,需频繁与WMS跨进程同步状态,增加复杂性和性能损耗。集成在system_server中可减少这类协调成本。

  3. 系统服务启动与依赖管理
    system_server是Android的核心服务管理器,负责按顺序启动和依赖解析。inputflinger的初始化依赖于system_server提供的环境(如DisplayThread的Looper),且需在WMS启动后立即可用。独立化需额外设计进程生命周期管理,可能引入启动顺序或死锁风险。

  4. 资源与性能权衡
    独立进程虽能提升模块隔离性,但会占用额外内存和CPU资源。inputflinger作为高频调用的服务,独立后需维护常驻进程,可能得不偿失。而audioflingersurfaceflinger因涉及硬件资源独占(如音频设备、显示合成),独立进程更利于资源调度。

  5. 历史架构演进
    早期Android版本中,inputflinger曾尝试过独立进程设计(如通过main.cpp启动),但最终因上述问题回归system_server集成。后续优化

问题2:

surfaceflinger为什么要设置binder线程为4个

SurfaceFlinger 自己在 main_surfaceflinger.cpp 里主动把 Binder 线程池的上限从系统默认的 15 条降到了 4 条:
// frameworks/native/services/surfaceflinger/main_surfaceflinger.cpp
int main(int argc, char** argv) {
sp proc(ProcessState::self());
ProcessState::self()->setThreadPoolMaxThreadCount(4); // 关键语句

}

之所以只开 4 条线程,而不是让 Binder 驱动自动根据负载无限制地拉起线程,主要是下面几方面的权衡。

并发度需求有限
• SurfaceFlinger 对外只暴露 ISurfaceComposer、IDisplayEventConnection 等少量接口。
• 绝大部分事务最终都要在主线程(“VSYNC 线程”)里执行,因为它持有全局锁 mStateLock 并驱动合成管线。Binder 线程做的只是把 IPC 转成主线程消息,再多线程也无法突破这把大锁带来的串行瓶颈。
结论:多于 3-4 条线程并不能显著提升吞吐。

避免 CPU 抢占导致掉帧
• SurfaceFlinger 的主线程和合成线程都使用 SCHED_FIFO/SCHED_OTHER + 高优先级。
• 若 Binder 线程数量过多,它们同样是高优先级,容易在调度器里与合成关键路径「抢时间片」,造成 jank/帧间隔抖动。
• 控制线程数可以将 CPU 占用保持在一个可预测范围,降低实时渲染链路被意外打断的概率。

减少内存与上下文切换开销
• 每条 Binder 线程的用户栈默认 1 MiB,再加 Binder 驱动内核栈,线程越多越浪费。
• Binder 事务通常很短(几百微秒级),大量线程反而会导致锁竞争、cache miss 和上下文切换开销上升。

早期设备资源受限的历史包袱
• 最初做参数调优时,主流设备只有 1-2 GiB RAM、4-8 核 CPU,实验表明 4 条线程已经覆盖 99% 使用场景。这个值后来一直沿用。

Dos/恶意调用防护
• 将线程数限定得较小可防止外部 Service 使用海量并发事务拖垮 SurfaceFlinger,属于一种「背压」策略。

总结
SurfaceFlinger 作为图形栈核心进程,对实时性和确定性要求极高;Binder 请求本身对并发需求不大,却可能对调度造成负面影响。综合测试结果后,Google 把线程池上限固定为 4,正好在「满足事务峰值」与「最小化资源占用、保障帧率」之间取得平衡。

问题3:

请从binder客户端和binder驱动讲述一下binder机制中binder多线程的支持
  1. 使用 Binder 的进程在启动之后,通过 BINDER_SET_MAX_THREADS 告知驱动其支持的最大线程数量

  2. 驱动会对线程进行管理。在 binder_proc 结构中,这些字段记录了进程中线程的信息:max_threads,requested_threads,requested_threads_started

  3. binder_thread 结构对应了 Binder 进程中的线程

  4. 驱动通过 BR_SPAWN_LOOPER 命令告知进程需要创建一个新的线程

  5. 进程通过 BC_ENTER_LOOPER 命令告知驱动其主线程已经ready

  6. 进程通过 BC_REGISTER_LOOPER 命令告知驱动其子线程(非主线程)已经ready

  7. 进程通过 BC_EXIT_LOOPER 命令告知驱动其线程将要退出

  8. 在线程退出之后,通过 BINDER_THREAD_EXIT 告知Binder驱动。驱动将对应的 binder_thread 对象销毁

在这里插入图片描述
更多framework实战开发,请关注下面“千里马学框架”

相关文章:

  • 基于DFT码本的波束方向图生成MATLAB实现
  • Next.js 15 与 Apollo Client 的现代集成及性能优化
  • 低功耗双目云台监控设备采用国标控制装置
  • 【Java工程师面试全攻略】Day3:Java并发编程面试精要
  • 编译Ambari 3.0.0全攻略
  • Rust 的Hello World
  • 程序员出海手册
  • Git:现代软件开发的基石——原理、实践与行业智慧·优雅草卓伊凡
  • 实验设计与分析(第6版,Montgomery)第4章随机化区组,拉丁方, 及有关设计4.5节思考题4.18~4.19 R语言解题
  • python学习day31
  • 如何发布npm包?
  • 2024 CKA模拟系统制作 | Step-By-Step | 11、题目搭建-查看可用节点数量
  • 20250528-C#知识:结构体
  • Spring AI系列之使用 Mistral AI API 实现函数调用
  • 使用LSTM进行时间序列分析
  • MCU - SPI总线介绍 + W25Qx驱动设计
  • 基于深度学习的三维图像生成项目开发方案
  • SpringAI+MCPServer+MCPClient快速入门
  • 如何优化Elasticsearch的搜索性能?
  • adb查看、设置cpu相关信息
  • 常州市网站建设/成人速成班有哪些专业
  • 苏州360推广网站建设/线上宣传渠道
  • 中间商网站怎么做/湖北网站seo设计
  • 免费合同模板网站/seo的英文全称是什么
  • 做商业网站赚钱吗/如何去推广一个app
  • 营销型网站怎么收费标准/百度网址大全旧版安装