forked from hadyang/interview
-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
ShiHaoyang
committed
Aug 26, 2016
0 parents
commit 09b0527
Showing
134 changed files
with
4,336 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
_book | ||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# Introduction | ||
|
||
本文档使用 Gitbook 制作,[Github](https://github.com/AstaYang/interview.git) 仓库地址。 | ||
|
||
所有引用内容版权归原作者所有。 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
# Summary | ||
|
||
* [Introduction](README.md) | ||
* [计算机基础](basic/README.md) | ||
* [计算机网络](basic/net/README.md) | ||
* [网络分层](basic/net/osi.md) | ||
* [底层网络协议](basic/net/base_protocol.md) | ||
* [TCP](basic/net/tcp.md) | ||
* [IP](basic/net/ip.md) | ||
* [HTTP](basic/net/http.md) | ||
* [面试题](basic/net/questions.md) | ||
* [数据结构与算法](basic/algo/README.md) | ||
* [树](basic/algo/tree.md) | ||
* [Hash](basic/algo/hash.md) | ||
* [最小生成树算法](basic/algo/mst.md) | ||
* [最短路径算法](basic/algo/path.md) | ||
* [KMP算法](basic/algo/kmp.md) | ||
* [查找算法](basic/algo/search.md) | ||
* [排序算法](basic/algo/sort.md) | ||
* [常用算法](basic/algo/algo.md) | ||
* [面试题](basic/algo/questions.md) | ||
* [操作系统](basic/op/README.md) | ||
* [计算机体系结构](basic/op/arch.md) | ||
* [操作系统基础](basic/op/os.md) | ||
* [并发](basic/op/concurrency.md) | ||
* [内存管理](basic/op/memory.md) | ||
* [磁盘与文件](basic/op/disk.md) | ||
* [Linux系统](basic/op/linux.md) | ||
* [面试题](basic/op/questions.md) | ||
* [数据库系统](basic/database/README.md) | ||
* [事务](basic/database/transaction.md) | ||
* [索引](basic/database/index.md) | ||
* [SQL语句](basic/database/sql.md) | ||
* [连接](basic/database/join.md) | ||
* [面试题](basic/database/questions.md) | ||
* [Java基础](java/README.md) | ||
* [面向对象基础](java/oop.md) | ||
* [集合框架](java/collection.md) | ||
* [Java分派机制](java/dispatcher.md) | ||
* [Java异常](java/exception.md) | ||
* [Java泛型](java/generics.md) | ||
* [Java线程](java/thread.md) | ||
* [JVM架构](java/jvm-architecture.md) | ||
* [类加载器](java/jvm-class-loader.md) | ||
* [JVM类加载三步走](java/jvm-class-load-init.md) | ||
* [JVM垃圾回收](java/jvm-gc.md) | ||
* [Java对象生命周期](java/jvm-object-life-cycle.md) | ||
* [Volatile原理](java/volatile.md) | ||
* [Synchronized原理](java/synchronized.md) | ||
* [面试题](java/questions.md) | ||
* [Android开发](android/README.md) | ||
* [Android系统架构](android/arch.md) | ||
* [Activity && Service生命周期](android/lifecicle.md) | ||
* [Activity四种启动模式](android/launchmod.md) | ||
* [ListView原理及优化](android/listview.md) | ||
* [Android中Handler机制](android/handler.md) | ||
* [Android广播机制](android/broadcast.md) | ||
* [View绘制过程](android/draw.md) | ||
* [事件分发机制](android/event.md) | ||
* [Binder](android/binder.md) | ||
* [OOM && ANR 优化](android/optimize.md) | ||
* [推送机制](android/push.md) | ||
* [进程保活](android/keep-live.md) | ||
* [Activity、View及Window之间关系](android/activity-view-window.md) | ||
* [EventBus](android/eventbus.md) | ||
* [面试题](android/questions.md) | ||
|
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
# Introduction | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
# Summary | ||
|
||
* [Introduction](README.md) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
# Activity、View及Window之间关系 | ||
|
||
## View | ||
|
||
View(包括ViewGroup)使用的是组合模式,将View组成成树形结构,以表示“部分-整体”的层次结构,使得用户对单个对象和组合对象的使用具有一致性。View主要是用于绘制我们想要的结果,是一个最基本的UI组件。 | ||
|
||
## Window | ||
|
||
简单地说,`Window`表示一个窗口,一般来说,`Window`大小取值为屏幕大小。但是这不是绝对的,如对话框、Toast等就不是整个屏幕大小。你可以指定`Window`的大小。`Window`包含一个`View tree`和窗口的`layout`参数。 | ||
|
||
感觉Window的理解比较抽象,Window相当于一个容器,里面“盛放”着很多View,这些View是以树状结构组织起来的。 | ||
|
||
> 如果还是无法理解的话,就把Window当成是显示器,显示器有大有小(对应Window有大有小),View是显示器里面具体显示的内容。 | ||
### Window对象存在的必要性 | ||
|
||
`Window`能做的事情,`View`对象基本都能做:像什么触摸事件啊、显示的坐标及大小啊、管理各个子View啊等等。View已经这么强大了,为什么还多此一举,加个`Window`对象。可能有人会说因为`WindowManager`管理的就是`Window`对象呀,那我想问,既然这样,Android系统直接让`WindowManager`去管理`View`不就好了?让View接替`Window`的工作,把`Window`所做的事情都封装到`View`里面不好嘛?。或许又有人说,`View`负责绘制显示内容,`Window`负责管理`View`,各自的工作职责不同。可是我想说,`Window`所做的大部分工作,`View`里面都有同样(或类似)的处理。 | ||
|
||
关于`Window`存在的必要,我查了国内外各种资料,最后有了我个人的理解。在后面小节里面,我会结合我个人的理解来解释。在解释之前,我们需要了解Window绘制过程。 | ||
|
||
### Window绘制过程 | ||
|
||
在理解`Window`绘制过程之前,首先,我们需要知道`Surface`,在`Window`中持有一个`Surface`,那么什么是`Surface`呢? | ||
|
||
`Surface`其实就是一个持有像素点矩阵的对象,这个像素点矩阵是组成显示在屏幕的图像的一部分。**我们看到显示的每个Window(包括对话框、全屏的Activity、状态栏等)都有他自己绘制的`Surface`**。而最终的显示可能存在`Window`之间遮挡的问题,此时就是通过`Surface Flinger对`象渲染最终的显示,使他们以正确的`Z-order`显示出来。一般`Surface`拥有一个或多个缓存(一般2个),通过双缓存来刷新,这样就可以一边绘制一边加新缓存。 | ||
|
||
`WindowManager`为每个`Window`创建`Surface`对象,然后应用就可以通过这个`Surface`来绘制任何它想要绘制的东西。而对于`WindowManager`来说,这只不过是一块矩形区域而已。 | ||
|
||
前面我们说过,`View`是`Window`里面用于交互的UI元素。`Window`只attach一个`View Tree`,当`Window`需要重绘(如,当View调用`invalidate`)时,最终转为`Window`的`Surface`,`Surface`被锁住(locked)并返回Canvas对象,此时View拿到Canvas对象来绘制自己。当所有View绘制完成后,`Surface`解锁(unlock),并且post到绘制缓存用于绘制,通过`Surface Flinger`来组织各个Window,显示最终的整个屏幕。 | ||
|
||
### 总结 | ||
|
||
现在我们知道了`Window`绘制过程,其实,站在系统的角度来考虑,一个Window对象代表一块显示区域,系统不关心Window里面具体的绘制内容,也不管你`Window`怎么去绘制,反正只给你提供可以在这块区域上绘制图形的`Surface`对象,你`Window`对象怎么画是你的事情! | ||
|
||
换句话说,站在系统的角度上看,系统是“不知道”有View对象这个说法的!作为系统,我有自己的骄傲,不去管你Window如何搬砖、如何砌墙,只给你地皮。而这时,Window为了绘制出用户想要的组件(按钮、文字、输入框等等),系统又不给我!没事,那我自己定义,于是就定义了View机制,给每个View提供Canvas,让不同的View自己绘制具有自己特色的组件。同时,为了更好的管理View,通过定义ViewGroup,等等。 | ||
|
||
## Activity | ||
|
||
对于开发人员来说,一个`Activity`就“相当于”一个界面(通过`setContentView`指定具体的View)。我们可以直接在Activity里处理事件,如`onKeyEvent`,`onTouchEvent`等。 并可以通过Activity维护应用程序的生命周期。 | ||
|
||
### Activity和Window | ||
|
||
前面我们知道,`Window`已经是系统管理的窗口界面。那么为什么还需要`Activity`呢?我们把`Activity`所做的事情,全部封装到`Window`不就好了? | ||
|
||
其实,本质上讲,我们要显示一个窗口出来,的确可以不需要Activity。悬浮窗口中不就是没有使用Activity来显示一个悬浮窗吗?既然如此,Window(以及View)能处理点击事件以及封装各种逻辑,那为啥还需要Activity呢? | ||
|
||
`Android`中的应用中,里面对各个窗口的管理相当复杂(任务栈、状态等等),Android系统当然可以不用Activity,让用户自己直接操作Window来开发自己的应用。但是如果让用户自己去管理这些Window,先不说工作量,光让用户自己去实现任务栈这点,有几个人能写的出来。**为了让大家能简单、快速的开发应用,Android通过定义Activity,让Activity帮我们管理好,我们只需简单的去重写几个回调函数,无需直接与Window对象接触**。各种事件也只需重写Activity里面的回调即可。无需关注其他细节,默认都帮我们写好了,针对需要定制的部分我们重写(设计模式为:模板方法模式)。 |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
# Android系统架构 | ||
|
||
 | ||
|
||
## 应用程序(Applications) | ||
|
||
Android会同一系列核心应用程序包一起发布,该应用程序包包括email客户端,SMS短消息程序,日历,地图,浏览器,联系人管理程序等。所有的应用程序都是使用JAVA语言编写的。通常开发人员就处在这一层。 | ||
|
||
## 应用程序框架(Application Frameworks) | ||
|
||
提供应用程序开发的各种API进行快速开发,也即隐藏在每个应用后面的是一系列的服务和系统,大部分使用Java编写,所谓官方源码很多也就是看这里,其中包括: | ||
|
||
- **丰富而又可扩展的视图(Views)**:可以用来构建应用程序, 它包括列表(lists),网格(grids),文本框(text boxes),按钮(buttons), 甚至可嵌入的web浏览器。 | ||
- **内容提供器(Content Providers)**:使得应用程序可以访问另一个应用程序的数据(如联系人数据库), 或者共享它们自己的数据 | ||
- **资源管理器(Resource Manager)**:提供 非代码资源的访问,如本地字符串,图形,和布局文件( layout files )。 | ||
- **通知管理器 (Notification Manager)**:使得应用程序可以在状态栏中显示自定义的提示信息。 | ||
- **活动管理器( Activity Manager)**:用来管理应用程序生命周期并提供常用的导航回退功能。 | ||
|
||
## 系统运行库与Android运行环境(Libraris & Android Runtime) | ||
|
||
### 系统运行库 | ||
|
||
Android 包含一些C/C++库,这些库能被Android系统中不同的组件使用。它们通过 Android 应用程序框架为开发者提供服务。以下是一些核心库: | ||
- **Bionic系统 C 库** - 一个从 BSD 继承来的标准 C 系统函数库( libc ), 它是专门为基于 embedded linux 的设备定制的。 | ||
- **媒体库** - 基于 PacketVideo OpenCORE;该库支持多种常用的音频、视频格式回放和录制,同时支持静态图像文件。编码格式包括MPEG4, H.264, MP3, AAC, AMR, JPG, PNG 。 | ||
- **Surface Manager** - 对显示子系统的管理,并且为多个应用程序提 供了2D和3D图层的无缝融合。这部分代码 | ||
- **Webkit,LibWebCore** - 一个最新的web浏览器引擎用,支持Android浏览器和一个可嵌入的web视图。鼎鼎大名的 Apple Safari背后的引擎就是Webkit | ||
- **SGL** - 底层的2D图形引擎 | ||
- **3D libraries** - 基于OpenGL ES 1.0 APIs实现;该库可以使用硬件 3D加速(如果可用)或者使用高度优化的3D软加速。 | ||
- **FreeType** -位图(bitmap)和矢量(vector)字体显示。 | ||
- **SQLite** - 一个对于所有应用程序可用,功能强劲的轻型关系型数据库引擎。 | ||
|
||
### Android运行环境 | ||
|
||
该核心库提供了JAVA编程语言核心库的大多数功能。<br />每一个Android应用程序都在它自己的进程中运 行,都拥有一个独立的Dalvik虚拟 机实例。Dalvik被设计成一个设备可以同时高效地运行多个虚拟系统。 Dalvik虚拟机执行(.dex)的Dalvik可执行文件,该格式文件针对小内存使用做了 优化。同时虚拟机是基于寄存器的,所有的类都经由JAVA编译器编译,然后通过SDK中 的 "dx" 工具转化成.dex格式由虚拟机执行。 | ||
|
||
## HAL--硬件抽象层 | ||
|
||
其实Android并非讲所有的设备驱动都放在linux内核里面,而是实现在userspace空间,这么做的主要原因是GPL协议,Linux是遵循该协议来发布的,也就意味着对linux内核的任何修改,都必须发布其源代码。而现在这么做就可以避开而无需发布其源代码,毕竟它是用来赚钱的。而在linux内核中为这些userspace驱动代码开一个后门,就可以让本来userspace驱动不可以直接控制的硬件可以被访问。而只需要公布这个后门代码即可。一般情况下如果要将Android移植到其他硬件去运行,只需要实现这部分代码即可。包括:显示器驱动,声音,相机,GPS,GSM等等 | ||
|
||
## Linux内核(Linux Kernel) | ||
|
||
Android的核心系统服务依赖于Linux 2.6 内核,如安全性,内存管理,进程管理, 网络协议栈和驱动模型。 Linux 内核也同时作为硬件和软件栈之间的抽象层。其外还对其做了部分修改,主要涉及两部分修改: | ||
|
||
1. Binder (IPC):提供有效的进程间通信,虽然linux内核本身已经提供了这些功能,但Android系统很多服务都需要用到该功能,为了某种原因其实现了自己的一套。 | ||
2. 电源管理:主要是为了省电,毕竟是手持设备嘛,低耗电才是我们的追求。 |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
# Binder | ||
|
||
## 简介 | ||
|
||
Binder使用`Client-Server`通信方式。Binder框架定义了四个角色:`Server`,`Client`,`ServiceManager`以及`Binder驱动`。其中`Server`,`Client`,`ServiceManager`运行于用户空间,驱动运行于内核空间。Binder驱动程序提供设备文件`/dev/binder`与用户空间交互,`Client`、`Server`和`Service Manager`通过`open`和`ioctl`文件操作函数与Binder驱动程序进行通信。 | ||
|
||
 | ||
|
||
## Binder原理简述 | ||
|
||
1. Server创建了Binder实体,为其取一个字符形式,可读易记的名字。 | ||
2. 将这个Binder连同名字以数据包的形式通过Binder驱动发送给`ServiceManager`,通知`ServiceManager`注册一个名字为XX的Binder,它位于Server中。 | ||
3. 驱动为这个穿过进程边界的Binder创建位于内核中的实体结点以及ServiceManager对实体的引用,将名字以及新建的引用打包给ServiceManager。 | ||
4. `ServiceManager`收数据包后,从中取出名字和引用填入一张查找表中。但是一个Server若向ServiceManager注册自己Binder就必须通过这个引用和`ServiceManager`的Binder通信。 | ||
5. Server向`ServiceManager`注册了Binder实体及其名字后,Client就可以通过名字获得该Binder的引用了。Clent也利用保留的引用向`ServiceManager`请求访问某个Binder:我申请名字叫XX的Binder的引用。 | ||
6. `ServiceManager`收到这个连接请求,从请求数据包里获得Binder的名字,在查找表里找到该名字对应的条目,从条目中取出Binder引用,将该引用作为回复发送给发起请求的Client。 | ||
|
||
当然,不是所有的Binder都需要注册给`ServiceManager`广而告之的。Server端可以通过已经建立的Binder连接将创建的Binder实体传给Client,当然这条已经建立的Binder连接必须是通过实名Binder实现。由于这个Binder没有向ServiceManager注册名字,所以是 **匿名Binder**。Client将会收到这个匿名Binder的引用,通过这个引用向位于Server中的实体发送请求。匿名Binder为通信双方建立一条私密通道,只要Server没有把匿名Binder发给别的进程,别的进程就无法通过穷举或猜测等任何方式获得该Binder的引用,向该Binder发送请求。 | ||
|
||
## Binder的数据拷贝 | ||
|
||
Linux内核实际上没有从一个用户空间到另一个用户空间直接拷贝的函数,需要先用`copy_from_user()`拷贝到内核空间,再用`copy_to_user()`拷贝到另一个用户空间。**为了实现用户空间到用户空间的拷贝,`mmap()`分配的内存除了映射进了接收方进程里,还映射进了内核空间**。所以调用`copy_from_user()`将数据拷贝进内核空间也相当于拷贝进了接收方的用户空间,这就是Binder只需一次拷贝的"秘密"。 | ||
|
||
最底层的是Android的`ashmen(Anonymous shared memory)`机制,它负责辅助实现内存的分配,以及跨进程所需要的内存共享。AIDL(android interface definition language)对Binder的使用进行了封装,可以让开发者方便的进行方法的远程调用,后面会详细介绍。Intent是最高一层的抽象,方便开发者进行常用的跨进程调用。 | ||
|
||
使用共享内存通信的一个显而易见的好处是效率高,因为 **进程可以直接读写内存,而不需要任何数据的拷贝**。对于像管道和消息队列等通信方式,则需要在内核和用户空间进行四次的数据拷贝,而共享内存则只拷贝两次内存数据:一次从输入文件到共享内存区,另一次从共享内存到输出文件。实际上,进程之间在共享内存时,并不总是读写少量数据后就解除映射,有新的通信时,再重新建立共享内存区域,而是保持共享区域,直到通信完成为止,这样,数据内容一直保存在共享内存中,并没有写回文件。共享内存中的内容往往是在解除内存映射时才写回文件的。因此,采用共享内存的通信方式效率是非常高的。 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
# Android广播机制 | ||
|
||
广播(Broadcast)机制用于进程/线程间通信,广播分为广播发送和广播接收两个过程,其中广播接收者BroadcastReceiver便是Android四大组件之一。 | ||
|
||
BroadcastReceiver分为两类: | ||
|
||
- `静态广播接收者`:通过`AndroidManifest.xml`的标签来申明的BroadcastReceiver。 | ||
- `动态广播接收者`:通过`AMS.registerReceiver()`方式注册的BroadcastReceiver,动态注册更为灵活,可在不需要时通过`unregisterReceiver()`取消注册。 | ||
|
||
从广播发送方式可分为三类: | ||
|
||
- `普通广播`:通过Context.sendBroadcast()发送,可并行处理 | ||
- `有序广播`:通过Context.sendOrderedBroadcast()发送,串行处理 | ||
- `Sticky广播`:通过Context.sendStickyBroadcast()发送,发出的广播会一直滞留(等待),以便有人注册这则广播消息后能尽快的收到这条广播。 | ||
|
||
Android 中的 Broadcast 实际底层使用Binder机制。 |
Oops, something went wrong.