本人如今每日一道算法题的Github地址。
https://github.com/Jensenczx/...
附带OJ地址和本人的代码
博客新址,这里更有趣java
昨日阿里二面,跪的很惨,项目,算法,计算机基础不问,问Linux内核,我是投的android实习岗,要求是对于android底层有很深厚的基础,问了binder的实现机制,activity栈的管理回退等等,这都是android高级工程师进阶的书里才会讲的东西,这让我很慌呀。啃底层,再战。
讲底层,先从系统启动流程开始,这个过程发生了什么,而后逐步分析这个每一个流程又作了些什么,在咱们的系统中起到一个什么做用。不打算深刻代码细节去看,固然能力也是不够的,从总体上有个森林。android
先对启动的过程来一个概览,由于android是基于Linux,因此这里从Linux内核的启动开始到android中的相应服务的启动,对于具体应用的开启下面讲。git
根据这个图,讲一下整个流程。github
当咱们开机的时候,此时通电了,此时会产生一个肯定的复位时序,保证CPU是第一个被复位的器件,而后CPU开始执行第一条指令,该指令是位于固定的内存地址上的,所谓的引导程序。算法
BIOS从咱们的磁盘中寻找咱们操做系统引导程序,将引导程序加载到内存中,执行,而后将咱们的Linux内核加载到内存中。shell
启动init进程,这个进程是用户态全部进程的祖先,内核态是叫作内核线程和用户进程差很少。()编程
init进程首先经过fork建立子进程,首先是Daemon进程也就是守护进程,包括USB守护进程,Debug进程,无线通讯链接守护进程。网络
fork出Context Manager,经过上图咱们能够看出,android系统提供的服务都要向其进行注册,而后其它的进程才能够调用这个服务。框架
Media Server,这个服务是本地服务,不是Java服务,不须要再经过dalvik虚拟机装载执行,本地服务单独开启了一个进程。这里包括Audio Flinger和Camera Service。socket
Zygote,全部Android应用程序的祖先,其用来缩短应用程序的加载时间,具体怎么节省,下面详解。
System Server是android系统中的一个核心进程,提供了管理应用程序生命周期,地理位置信息等各类服务。同时其须要将自身注册到Context Manager.可是咱们的服务管理器是基于C语言的,因此咱们须要JNI本地编程接口。这个时候Activity Manager Service会运行HOME应用。
大体咱们已经了解了启动的流程Linux内核,init进程fork出多个进程,zygote用来孵化Java系统服务,同时孵化应用程序。接下来,咱们再深刻的去看一下。init进程作了什么?zygote是如何被建立出来的。
init进程是第一个启动的用户进程,其它用户进程都是其子进程,或者其子进程的子进程,,
子进程终止处理。
应用程序访问设备驱动时,生成设备结点文件。
提供属性服务,保存系统运行所须要的环境变量。
init进程会先注册一些消息处理器,而后是建立并挂载启动所须要的文件目录(socket文件,虚拟内存文件),在dev目录下生成设备节点文件,而后将标准输入,输出,错误输出重定向到这里。建立设备节点文件,建立输出log的文件,同时将错误信息重定向到这里,init进程生成输出设备以后,开始解析init.rc脚本文件,记录init进程执行的功能,init.rc用于通用的环境变量和进程相关的定义,经过函数 iparse_config_file来读取其脚本,读取分析以后,生成服务列表和动做列表。服务列表和动做列表会注册到service_list和action_list中,其为在init进程中声明的全局结构体,调用device_init函数,生成静态设别结点文件,以后,全局属性值的生成在init进程中propertyinit函数中进行初始化,在共享内存区域,建立并初始化属性值,对于全局属性的修改,只有init进程能够修改,当要修改的时候,须要预先向其提交申请,而后init进程经过以后,才会去修改属性值,提交申请的过程会建立一个socket用来接收提交的申请。执行到这系统将Android系统的Logo显示在桌面上。这个时候设置事件处理循环的监视事件,注册在POLL中的文件描述符会在poll函数中等待事件,事件发生,则从poll函数中跳出并处理事件。各类文件描述符都会前来注册。
init.rc文件分析函数,经过read_file函数,parse_config函数,用来分析读入的字符串。AIL ,Android Init Language编写。
init.rc文件大体上分为两个部分,一部分是以“on”关键字开头的动做列表,另外一部分是以”service”关键字开头的服务服务列表。
动做列表:主要设置环境变量,生成系统运行所需的文件或目录,修改相应的权限,并挂载和系统运行相关的目录。在挂载文件的时候,主要挂载/system和/data两个目录,两个目录挂载完毕,android根文件系统准备好了。根文件系统大体可分为shell使用程序,system目录(提供库和基础应用),data目录(保存用户应用和数据),Android采用闪存设备,其采用了yaffs2文件系统,启动的时候要挂载到/system和/data目录下,而后是on boot段落,该部分设置应用程序终止条件,应用程序驱动目录和文件权限。为各应用制定OOM调整至,OOM用来监视内核分配给应用程序的内存,当内存不足的时候,应用程序会被终止执行。
服务列表:init.rc脚本文件,service段落用来记录init进程启动的进程,由init进程启动的子进程或者是一次性程序,系统相关的Daemon进程
和Linux相同,应用程序经过驱动程序访问硬件设备,设备节点文件是设备驱动的逻辑文件,应用程序经过设备节点文件来访问设备驱动程序。
设备节点的两种建立方式,一种,根据预先定义的设备信息,建立设备节点文件,第二种,在系统运行中,当设备插入时,init进程会接收这一事件,为插入设备动态建立设备节点文件。
当设备插入的时候内核会加载相应的驱动程序,然后驱动程序会调用启动函数probe,将主,次设备号类型保存到/sys文件系统中。而后发出uevent,并传递给守护进程,vevent,是内核向用户控件进程传递信息的信号系统,内核经过uevent将信息传递到用户空间,守护进程会根据uevent读取设备信息,建立设备节点文件。对于一些设备,采用冷插拔的方式,监听设备的uevent,而后调用其函数,建立设备节点文件。
Linux对于系统中的设备都会抽象成一个文件,内核为了高效的管理已经被打开的文件,经过一个文件描述符来表示,在Linux中Everything is file,经过这种方式,对于启动的时候,对于文件描述符,0表明标注输入,1表示标准输出,2是错误处理,而后设备文件,socket文件都会得到一个文件描述符来表述它。可是Linux会对其作相应的限制,同时可能会对一些进程进行限制,限制给进程分配多少个文件描述符。
对于Service的建立,在后面讲到Service的时候单独再说,先讲Zygote,由于这是咱们的全部应用开启的基石。由于zygote是Java代码,因此须要装载到Dalvik VM上执行,因此在启动Zygote以前要启动Dalvik VM,因此这里要分为两步了,第一步启动Dalvik VM,第二步是启动Zygote。
首先生成了一个AppRuntime对象,该类是继承自AndroidRuntime的,该类用来初始化而且运行Dalvik 虚拟机,为运行Android应用作好准备。接受main函数传递进来的参数,而后初始化虚拟机。
虚拟机初始化以后,运行ZygoteInit类,经过路径查找找到,如今程序的执行转向了虚拟机Java代码的执行,首先执行器main函数,接下来就是Zygote的做用过程了,在下面部分。
Zygote执行以后,首先是绑定一个套接字,用来接收从Activity Manager来的应用启动请求(这里咱们能够想到网络通信中的Socket通讯)
将应用程序框架中的类,平台资源(图像,XML信息,字符串)预先加载到内存中,借此提高程序的执行速度。Android也是经过在Zygote建立的时候加载资源,生成信息连接等,之后再有应用启动,fork出一个子进程和父进程共享这些信息,而不须要从新加载,同时也共享虚拟机,由于虚拟机在初始化和建立的过程是很耗时的。
前面也提到过一些system server也是java的,并且咱们的应用启动等须要这些server的参与,因此在启动应用以前先启动了这些System server,而后启动Server Thread来执行android framework的服务,同时这些服务在启动的时候都是须要经过JNI向服务管理器Context Manager注册。
经历了上述步骤的zygote处在轮询监听Socket,当有请求到达,读取请求,fork出子进程,加载进程所须要的类,而后执行要执行程序的main函数,代码转给了Dalvik Vm,咱们的应用程序也就启动起来了。这个时候,将关闭套接字,删除请求描述符,防止出现重复启动。
上面只是对总体流程进行了一个概述,细节涉及不深,这里再提一下,虚拟机,到底是什么呢?这里的虚拟机能够理解成,能够解析Java字节码的内存上的一条条指令,各个应用共享这个虚拟机,也就是都是知道虚拟机的内存中地址,传递进java字节码,而后解析字节码,将字节码实际表明的操做反应出来,多个应用程序能够交替使用,经过寄存器记录彼此执行后的状态。fork出一个进程以后,咱们装载应用程序相应的类,而后执行。