面试官提了一个问题:说说你对 binder 驱动的了解。这个问题虽有些 "面试造火箭" 的无奈,可难点就是亮点、价值所在,是筛选面试者的有效手段。如果让你回答,你能说出多少呢?我们来看看 、 和 ️ 三位同学的回答如何吧


自认为无所不知,水平已达应用开发天花板,目前月薪 10k

面试官️:说说你对 binder 驱动的了解

:binder 驱动是很底层的东西,在系统内核中,是 binder 机制的基石。

面试官:没了吗?把你了解的都说一下

:直接让我说了解不好回答啊,还是问我问题吧

面试官:好,你刚才提到了系统内核,那介绍一下用户空间和内核空间吧

:不知道,这东西了解了也没什么用啊!我对业务开发 API 比较了解,比如 RecycleView 布局,我写的贼溜~

面试官:好的,回去等通知吧


业余时间经常打游戏、追剧、熬夜,目前月薪 15k

面试官:说说你对 binder 驱动的了解

:binder 机制分为四部分,binder 驱动、Service Manager、客户端、服务端。类比网络通信,Service Manager 是 DNS,binder 驱动就是路由器,它运行在内核空间,不同进程间通过 binder 驱动才能通信。

面试官:为什么 binder 驱动要运行在内核空间?可以移到用户空间吗?

:不行,两个进程的进程空间有不同的虚拟地址映射规则,内存是不共享的,无法直接通信。Linux 把进程空间划分为用户空间和内核空间,分别运行用户程序和系统内核。

用户空间和内核空间虽也是隔离的,但可以通过 copy_from_user 将数据从用户空间拷贝到内核空间,通过 copy_to_user 将数据从内核空间拷贝到用户空间。

所以 binder 驱动要处于内核空间,才能实现两个进程间的通信。一般的 IPC 方式需要分别调用这两个函数,数据就拷贝了两次,而 binder 将内核空间与目标用户空间进行了 mmap,只需调 copy_from_user 拷贝一次即可。

面试官:从用户空间如何调用内核空间的 binder 驱动呢?

:这个不了解了,我没看过 binder 源码,只是知道大概的通信方式

面试官:那你对 binder 驱动还有哪些了解,都说说吧

:嗯... 没有了

面试官:好的,回去等通知吧


️ 坚持每天学习、不断的提升自己,目前月薪 30k

面试官:说说你对 binder 驱动的了解

️:简单画张图吧:

对 Binder 机制来说,它是 IPC 通信的路由器,负责实现不同进程间的数据交互,是 Binder 机制的核心;对 Linux 系统来说,它是一个字符驱动设备,运行在内核空间,向上层提供 /dev/binder 设备节点及 open、mmap、ioctl 等系统调用。

面试官:你提到了驱动设备,那先说说 Linux 的驱动设备吧

️:Linux 把所有的硬件访问都抽象为对文件的读写、设置,这一"抽象"的具体实现就是驱动程序。驱动程序充当硬件和软件之间的枢纽,提供了一套标准化的调用,并将这些调用映射为实际硬件设备相关的操作,对应用程序来说隐藏了设备工作的细节。

Linux 驱动设备分为三类,分别是字符设备、块设备和网络设备。字符设备就是能够像字节流文件一样被访问的设备。对字符设备进行读/写操作时,实际硬件的 I/O 操作一般也紧接着发生。字符设备驱动程序通常都会实现 open、close、read 和 write 系统调用,比如显示屏、键盘、串口、LCD、LED 等。

块设备指通过传输数据块(一般为 512 或 1k)来访问的设备,比如硬盘、SD卡、U盘、光盘等。网络设备是能够和其他主机交换数据的设备,比如网卡、蓝牙等设备。

字符设备中有一个比较特殊的 misc 杂项设备,设备号为 10,可以自动生成设备节点。Android 的 Ashmem、Binder 都属于 misc 杂项设备。

面试官:看过 binder 驱动的 open、mmap、ioctl 方法的具体实现吗?

️:它们分别对应于驱动源码 binder.c 中的 binder_open()、binder_mmap()、binder_ioctl() 方法,binder_open() 中主要是创建及初始化 binder_proc ,binder_proc 是用来存放 binder 相关数据的结构体,每个进程独有一份。

binder_mmap() 的主要工作是建立应用进程虚拟内存在内核中的一块映射,这样应用程序和内核就拥有了共享的内存空间,为后面的一次拷贝做准备。

binder 驱动并不提供常规的 read()、write() 等文件操作,全部通过 binder_ioctl() 实现,所以 binder_ioctl() 是 binder 驱动中工作量最大的一个,它承担了 binder 驱动的大部分业务。

面试官:仅 binder_ioctl() 一个方法是怎么实现大部分业务的?

️:binder 机制将业务细分为不同的命令,调用 binder_ioctl() 时传入具体的命令来区分业务,比如有读写数据的 BINDER_WRITE_READ 命令、 Service Manager 专用的注册为 DNS 的命令等等。

BINDER_WRITE_READ 命令最为关键,其细分了一些子命令,比如 BC_TRANSACTION、BC_REPLY 等。BC_TRANSACTION 就是上层最常用的 IPC 调用命令了,AIDL 接口的 transact 方法就是这个命令。

面试官:binder 驱动中要实现这些业务功能,必然要用一些数据结构来存放相关数据,比如你上面说 binder_open() 方法时提到的 binder_proc,你还知道其他的结构体吗?

️:知道一些,比如:

结构体 说明
binder_proc 描述使用 binder 的进程,当调用 binder_open 函数时会创建
binder_thread 描述使用 binder 的线程,当调用 binder_ioctl 函数时会创建
binder_node 描述 binder 实体节点,对应于一个 serve,即用户态的 BpBinder 对象
binder_ref 描述对 binder 实体节点的引用,关联到一个 binder_node
binder_buffer 描述 binder 通信过程中存储数据的Buffer
binder_work 描述一个 binder 任务
binder_transaction 描述一次 binder 任务相关的数据信息
binder_ref_death 描述 binder_node 即 binder server 的死亡信息

其中主要结构体引用关系如下:

面试官:可以,我们再来聊聊别的。

这个问题虽有些 "面试造火箭" 的无奈,可难点就是亮点、价值所在,是筛选面试者的有效手段。如果问你这个问题,你能回答多少呢?

最后

最近整理了一份《Android Binder原理学习笔记》,集合了「Linux、C/S架构、ServiceManager、ProcessState、系统服务的注册过程、ServiceManager的启动过程、系统服务的获取过程、MediaPlayerService、JNI、Binder类的注册、AMS、JavaBBinder」等N多技术点。

目录:
一、学习Binder前必须要了解的知识点
二、ServiceManager中的Binder机制
三、系统服务的注册过程
四、ServiceManager的启动过程
五、系统服务的获取过程
六、Java Binder的初始化
七、Java Binder中系统服务的注册过程

  • 由于篇幅原因,为了避免影响到大家的阅读体验,在此只以截图展示部分内容,有需要的小伙伴【点击我】免费领取。

部分笔记截图

一、学习Binder前必须要了解的知识点

1.Linux和Android的IPC机制种类
2.Linux和Binder的IPC通信原理
3.为什么要使用Binder
4.为什么要学习Binder?

二、ServiceManager中的Binder机制

1.基于Binder通信的C/S架构
2.MediaServer的main函数
3.每个进程唯一的ProcessState
4.ServiceManager中的Binder机制

三、系统服务的注册过程

1.从调用链角度说明MediaPlayerService是如何注册的
2.从进程角度说明MediaPlayerService是如何注册的

四、ServiceManager的启动过程

1.ServiceManager的入口函数
1.1 打开binder设备
1.2 注册成为Binder机制的上下文管理者
1.3 循环等待和处理client端发来的请求

  • 由于篇幅原因,为了避免影响到大家的阅读体验,在此只以截图展示部分内容,有需要的小伙伴【点击我】免费领取。

五、系统服务的获取过程

1.客户端MediaPlayerService请求获取服务
2.服务端ServiceManager处理请求

六、Java Binder的初始化

1.Java Binder的JNI注册
1.1 Binder类的注册
1.2 BinderInternal类的注册

七、Java Binder中系统服务的注册过程

1.将AMS注册到ServiceManager
1.1 BinderInternal.getContextObject()
1.2 ServiceManagerNative.asInterface()
1.3 getIServiceManager().addService()

2.引出JavaBBinder
3.解析JavaBBinder
4.Java Binder架构

深入解析Binder源码

只要是程序员,不管是Java还是Android,如果不去阅读源码,只看API文档,那就只是浮于表象,这对我们的知识体系的建立和完备以及实战技术的提升都是不利的。

真正最能锻炼能力的便是直接去阅读源码,不仅限于阅读Android系统源码,还包括各种优秀的开源库。

阅读源码永远是学习最快的方式。

所以这里为大家整理了Android开发相关源码精编解析,其中关于Binder的源码解析内容:

第一节 Binder 系列—开篇
第二节 Binder Driver 初探
第三节 Binder Driver 再探
第四节 Binder 启动 ServiceManager
第五节 获取 ServiceManager

大厂关于Binder的面试题

一线企业的app都是多线程和多进程的,而Android进程间通信机制就是Binder,原生的线程间通信则是Handler,Binder和Handler是了解安卓运行机制必须要掌握的一个知识点,更是一线企业面试必问的知识点!

以下几道就是大厂关于和Binder常见的面试真题:

  • Binder有什么优势?(字节跳动)
  • Binder是如何做到一次拷贝的?(腾讯)
  • MMAP的原理讲解;(腾讯)
  • 为什么Intent不能传递大数据?(阿里)
  • 描述AIDL生成的java类细节;(字节跳动)
  • 四大组件底层的通信机制;(字节跳动)
  • 为什么Intent不能传递大数据?(阿里)
  • Binder机制是如何跨进程的?
  • Binder机制原理
  • ........

好了,到这里,整个笔记介绍的差不多了,感兴趣的朋友可以【点击我】免费领取。

Android面试官:说说你对 Binder 驱动的了解?的更多相关文章

  1. 【Android面试揭秘】面试官说“回去等通知”,我到底会不会等来通知?

    前言 大部分情况下,面试结束后,面试官都会跟你说:我们会在1-2个工作日内通知你面试结果. 许多人认为:所谓「等通知」其实是面试官委婉地给你「发拒信」.但是,这不是「等通知」的全部真相. 这篇文章,我 ...

  2. 阿里面试官:Android中binder机制的实现原理及过程?

    Binder 是 Android 系统中非常重要的组成部分.Android 系统中的许多功能建立在 Binder 机制之上.在这篇文章中,我们会对 Android 中的 Binder 在系统架构中的作 ...

  3. 跟面试官讲Binder(零)

    面试的时候,面试官问你说,简单说一下Android的Binder机制,你会怎么回答? 我想,我会这么说. 在Android启动的时候,Zygote进程孵化出第一个子进程叫SystemServer,而在 ...

  4. Android开发面试经——5.常见面试官提问Android题①

    版权声明:本文为寻梦-finddreams原创文章,请关注:http://blog.csdn.net/finddreams 关注finddreams博客: http://blog.csdn.net/f ...

  5. Android相关面试题---面试官常问问题

    版权声明:本文为寻梦-finddreams原创文章,请关注: http://blog.csdn.net/finddreams/article/details/44513579 一般的面试流程是笔试完就 ...

  6. 我一个五年Android开发,居然被一个技术不如我的面试官嫌弃了......

    背景 首先介绍一下自己的情况.目前所在的是一家小的创业公司,待了5年多,薪资一般吧.由于这几年公司也在转型.工作经历大概可以分为 3 个阶段. 第一阶段是从进公司开始做 android app 开发, ...

  7. 三年Android开发,竟只会增删改查,被面试官一顿怼!

    最近看到某公司面试官发的这样一个帖子: 我面试了一个有三年Android开发经验的小伙子,也是我有史以来给别人面试时间最短的一次,不到十分钟就结束了,原因很简单,底子太差只会curd,很多技术性的问题 ...

  8. Android开发面试经——6.常见面试官提问Android题②(更新中...)

    版权声明:本文为寻梦-finddreams原创文章,请关注:http://blog.csdn.net/finddreams 关注finddreams博客:http://blog.csdn.net/fi ...

  9. Android - Binder驱动

      以下资料摘录整理自老罗的Android之旅博客,是对老罗的博客关于Android底层原理的一个抽象的知识概括总结(如有错误欢迎指出)(侵删): http://blog.csdn.net/luosh ...

随机推荐

  1. Redis的主从数据一致性

    我们学习了 AOF 和 RDB,如果 Redis 发生了宕机,它们可以分别通过回放日志和重新读入 RDB 文件的方式恢复数据,从而保证尽量少丢失数据,提升可靠性.不过,即使用了这两种方法,也依然存在服 ...

  2. 5、could not start the service mysql

    1.这个原因是因为mysql多次安装没有卸载干净的原因; 2.解决办法是: (1)删除系统中已经安装的mysql目录中的内容: (2)同时按住"win+r"键调出"运行& ...

  3. Flask(1)- 简介

    背景 为啥要学,很久之前就学过点,没写文章 最近因为要写机器人工具,其实就是简单的纯服务端工具 反正 flask 也挺简单,一天快速过完 概念会直接搬教程的,实操自己敲一遍再总结 参考教程 https ...

  4. java.util.Date 与 java.sql.Date

    java.sql.Date 继承 java.util.Date 区别: 1.java.sql.Date 一般用于数据库 2.java.sql.Date 没有时分秒,涉及时分秒的函数都会报异常(且这些方 ...

  5. mysql导入脚本

    #登陆 mysql -u root -p #创建数据库 CREATE DATABASE `gps` CHARACTER SET utf8 COLLATE utf8_general_ci; #选择数据库 ...

  6. linux中的vim用法

    p.p1 { margin: 0; font: 16px ".PingFang SC"; color: rgba(53, 53, 53, 1) } p.p2 { margin: 0 ...

  7. php漏洞 md5函数漏洞

    0x01: 背景:php在处理哈希值时,用!=和==来比较的时候,如果哈希字符串以0E开头的时候,哈希值会默认为0,所以两个不同的字符串经过md5加密成哈希值,如果哈希值开头是0E的话,会默认成相等. ...

  8. c语言:随机函数应用

    #include <stdio.h> #include <time.h>//声明time 时间不可逆转一直在变 #include <math.h> #include ...

  9. Python入门学习指南

    对于初学者,入门至关重要,这关系到初学者是从入门到精通还是从入门到放弃.以下是结合Python的学习经验,整理出的一条学习路径,主要有四个阶段 NO.1 新手入门阶段,学习基础知识 总体来讲,找一本靠 ...

  10. Leetcode3.无重复字符的最长子串——简洁易懂

    > 简洁易懂讲清原理,讲不清你来打我~ 输入字符串,找到无重复.最长.子串,输出长度 ![在这里插入图片描述](https://img-blog.csdnimg.cn/c0565c943c654 ...