当前位置: 首页 > 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实战开发,请关注下面“千里马学框架”

http://www.xdnf.cn/news/696907.html

相关文章:

  • Tomcat运行比较卡顿进行参数调优
  • 案例解读 | 某外资在华汽车系统企业综合运维平台建设实践
  • Java消息队列应用:Kafka、RabbitMQ选择与优化
  • java读取excel数据中字段是否为金额格式
  • vue或者前端适配makedown推荐开源依赖
  • dart常用语法详解/数组list/map数据/class类详解
  • golang 柯里化(Currying)
  • 720全景展示:VR全景的技术原理及应用
  • Python进阶【一】 :线程、进程与协程
  • Vite Vue3 配置 Composition API 自动导入与项目插件拆分
  • 输配电行业国产PLM转型方案:南通禛华电气的云PLM研发转型
  • rsync 如何通过参数加上端口号
  • 大观杂志大观杂志社大观编辑部2025年第4期目录
  • Java 并发编程通关秘籍:多线程基础 + 锁机制 + 工具类 + 性能优化
  • Appium+python自动化(七)- 认识Appium- 上
  • 【AI算法工程师面试指北】大模型微调中的灾难性遗忘该如何避免?
  • 多台电脑共用一个ip地址可以吗?会怎么样
  • Screen 连接远程服务器(Ubuntu)
  • docker中多个容器相互访问的端口问题
  • YOLOv8 模型部署到树莓派的完整指南
  • Golang | gRPC demo
  • C++23 <spanstream>:基于 std::span 的高效字符串流处理
  • 软件检测:确保品质关键步骤,企业该如何选择检测方式?
  • 王树森推荐系统公开课 排序05:排序模型的特征
  • 28、请求处理-【源码分析】-请求映射原理
  • 《仿盒马》app开发技术分享-- 确认订单页(业务逻辑)(端云一体)
  • 便携式遥测自跟踪天线
  • 大语言模型推理优化技术综述(The Art of LLM Inference)
  • Oracle基础知识(五)——ROWID ROWNUM
  • 前端开发定时,ES学习,java集合