2018春招实习面试

看到了一个Android面试指南的网站,强力推荐:
Android校招面试指南

以下可能并不是确切的面试问题,但都涉及到了。

Android面试

1. HTTP与HTTPS

http超文本传输协议,https安全套接字层超文本协议,由SSL+HTTP协议构建,可进行加密传输、身份认证的网络协议,是在传输层进行加密的。

区别:

  • https协议需要ca申请证书。
  • http是明文数据传输,https则是具有安全性的ssl加密传输协议。
  • 采用完全不同的连接方式,其端口也不同,http80https445

HTTPS工作原理:

  • 客户端访问服务器,发起请求,要求建立SSL连接
  • 服务器接到请求,将网站证书信息(包含公钥)发一份给客户端。
  • 客户端与服务器端协商SSL安全等级,即协商信息加密等级
  • 双方同意安全等级,建立会话密钥(客户端生成的随机值,私钥,对称加密),利用证书信息的公钥将会话密钥加密
  • 服务器利用自己的私钥解密会话密钥
  • 服务器与客户端通过会话密钥(私钥)进行通信。
    2018春招实习面试_第1张图片
    原理图

HTTPS的优势:

  • 认证用户和服务器,确保数据发送到正确的客户机和服务器。
  • 加密传输、身份认证,更安全,可防止数据在传输过程中不被窃取、改变,确保数据的完整性。防止:嗅探可以监测访问了哪些页面(保密性)。ISP(网络运营商)植入广告(完整性/防篡改)。域名欺骗、域名劫持(真实性/防假冒)
  • 虽然不是绝对安全,但它大幅增加了中间人攻击成本

HTTPS的劣势

  • 该协议握手阶段比较费时
  • 连接缓存不如HTTP高效,会增加数据开销功耗
  • SSL证书要钱,功能越强大的证书费用越高。
  • SSL证书通常需要绑定IP不能在同一IP上绑定多个域名,IPv4资源不可能支撑这个消耗。
  • HTTPS协议的加密范围也比较有限,在黑客攻击、拒绝服务攻击、服务器劫持等方面几乎起不到什么作用。最关键的,SSL证书的信用链体系并不安全,特别是在某些国家可以控制CA根证书的情况下,中间人攻击一样可行。

其他:

  • TCP是传输层协议,HTTP、HTTPS是应用层协议。
  • 对称加密是加密和解密都是使用同一个密钥,非对称加密则加密和解密采用不同的密钥。显然非对称加密比对称加密更安全,然而性能通常较差,实现比较复杂。
  • SSL称安全套接层,标准化后称TLS协议,称传输层安全协议。两者可视为同一东西的不同阶段。

参考:
http://www.techug.com/post/https-ssl-tls.html
https://www.cnblogs.com/lovesong/p/5186200.html
http://blog.csdn.net/xionghuixionghui/article/details/68569282

2. Android虚拟机相关
Dalvik虚拟机

用于Android平台的Java虚拟机,Dalvik虚拟机运行在Android的运行时库层。主要负责完成对象生命周期管理、堆栈管理、线程管理、安全和异常管理,以及垃圾回收等。另外,Dalvik早期并没有JIT编译器,直到Android2.2才加入了对JIT的技术支持。

Dalvik虚拟机特点
  • 体积小,占用内存空间小;
  • 专有的DEX可执行文件格式,体积更小,执行速度更快;
  • 常量池采用32位索引值,寻址类方法名,字段名,常量更快;
  • 基于寄存器架构,并拥有一套完整的指令系统;
  • 提供了对象生命周期管理,堆栈管理,线程管理,安全和异常管理以及垃圾回收等重要功能;
  • 所有的Android程序都运行在Android系统进程里,每个进程对应着一个Dalvik虚拟机实例。
和Java虚拟机的区别
  • Java虚拟机运行的是Java字节码,Dalvik虚拟机运行的是Dalvik字节码
  • Java虚拟机通过解码class文件中的内容来运行程序,所有的Dalvik字节码由Java字节码转换而来,并被打包到一个DEX(Dalvik Executable)可执行文件中。Dalvik虚拟机通过解释DEX文件来执行这些字节码
  • Dalvik与JVM之间最大的区别:Java虚拟机与Dalvik虚拟机架构不同。Java虚拟机基于栈架构,程序在运行时虚拟机需要频繁的从栈上读取或写入数据,这个过程需要更多的指令分派与内存访问次数,会耗费不少CPU时间。Dalvik虚拟机基于寄存器架构。数据的访问通过寄存器间直接传递,这样的访问方式比基于栈方式要快很多。
ART虚拟机与Dalvik虚拟机的区别

ART代表Android Runtime,其处理应用程序执行的方式完全不同于Dalvik。

Dalvik的做法是:开发者编译后的应用代码需要通过一个解释器在用户的设备上运行,这一机制并不高效,但让应用能更容易在不同硬件和架构上运行。

ART的做法是:在应用安装时就预编译字节码到机器语言,这一机制叫Ahead-Of-Time(AOT)编译。在移除解释代码这一过程后,应用程序执行将更有效率,启动更快。

ART优点

  • 系统性能的显著提升。
  • 应用启动更快、运行更快、体验更流畅、触感反馈更及时。
  • 更长的电池续航能力。
  • 支持更低的硬件。

ART缺点

  • 更大的存储空间占用,可能会增加10%-20%。
  • 更长的应用安装时间。

ART虚拟机相对于Dalvik虚拟机的提升

  • 预编译阶段:完全抛弃了Dalvik的JIT,使用了AOT直接在安装时将其完全翻译成native code。使得虚拟机执行指令的速度又一重大提升。
  • 垃圾回收机制:Dalvik非并发GC,ART部分并发GC,且对内存进行了重新分配管理。
  • 提高内存使用,减少碎片化:Dalvik内存管理特点是内存碎片化严重。
    https://www.cnblogs.com/Jason-Jan/p/8459105.html
3. Bitmap压缩策略

http://www.cnblogs.com/Jason-Jan/p/8461078.html

4. Android的IPC(进程间通信)

IPC指进程间通信或跨进程通信,指两个进程间进行数据交换的过程。

Android中IPC的使用
只有面对多进程的情况才需要考虑进程间通信。

  • 自身需要采用多进程模式来实现。
  • 其他的应用获取数据。

Android中IPC带来的问题

  • 所有运行在不同进程中的四大组件,只要它们之间需要通过内存来共享数据,都会共享失败。
  • 静态成员和单例模式完全失效(不同的虚拟机中访问同一个对象会产生多分副本)。
  • 线程同步机制完全失效(不在同一块内存,不管是所对象还是锁全局类都无法保证线程同步)。
  • SharePreferences的可靠性下降(不支持两个进程同时写操作)
  • Application会多次创建(因为创建新进程会分配独立虚拟机,相当于启动一个新的应用)。
Android中各种IPC方式
  • Bundle,由于Bundle实现了Parcelable接口。
  • 文件共享,两个进程通过读写同一个文件来交换数据。文件共享方式适合在对数据同步要求不高的进程间进行通信。但是不建议使用 SharedPreference,因为系统对它的读写有一定的缓存策略,内存中会有一份SharedPreferences文件的缓存。
  • Messenger,Messenger可以理解为信使,是一种轻量级的IPC方案,它的底层实现是AIDL,通过它可以再不同进程中传递Message对象。一次处理一个请求。
  • AIDL,是一种android内部进程通信接口的描述语言。可以处理发送到服务器端大量的并发请求(不同与Messenger的串行处理方式)。
  • ContentProvider,是Android中提供的专门用于不同应用间进行数据共享的方式,天生适合进程间通信。
  • Socket,两个进程可以通过Socket来实现信息的传输,Socket本身可以支持传输任意字节流。
    2018春招实习面试_第2张图片
    IPC方式

参考:
https://www.cnblogs.com/pear-lemon/p/6547734.html

5. Window、Activity、View
  • Window视图的承载器,是一个抽象类,实际在Activity中持有的是其子类PhoneWindow内部持有一个 DecorView,通过创建DecorView来加载Activity中设置的布局R.layout.activity_main。Window 通过WindowManager将DecorView加载其中,并将DecorView交给ViewRoot,进行视图绘制以及其他交互
  • Activity,不负责视图控制,控制生命周期和处理事件。一个Activity包含了一个Window,Activity就像一个控制器,统筹视图的添加与显示,以及通过其他回调方法,来与Window、以及View进行交互
  • DecorView,FrameLayout的子类,顶级View。一般情况下它内部包含一个竖直方向的LinearLayout,包含延迟加载视图、标题栏、内容栏三层。在Activity中通过setContentView所设置的布局文件其实就是被加到内容栏之中的,成为其唯一子View。
  • ViewRoot所有View的绘制以及事件分发等交互都是通过它来执行或传递的。对应ViewRootImpl类,它是连接WindowManagerService和DecorView的纽带,View的三大流程(测量(measure),布局(layout),绘制(draw))均通过ViewRoot来完成。既非View的子类,也非View的父类,但是,它实现了ViewParent接口,这让它可以作为View的名义上的父视图。RootView继承了Handler类,可以接收事件并分发,Android的所有触屏事件、按键事件、界面刷新等事件都是通过ViewRoot进行分发的。
    2018春招实习面试_第3张图片
    四者关系

总结

  • Activity就像个控制器,不负责视图部分。
  • Window像个承载器,装着内部视图。
  • DecorView就是个顶层视图,是所有View的最外层布局。
  • ViewRoot像个连接器,负责沟通,通过硬件的感知来通知视图,进行用户之间的交互。

参考:
http://www.cnblogs.com/Jason-Jan/p/8455118.html

6. Android中的几种动画
  • FrameAnimation(逐帧动画),将多张图片组合起来进行播放。
  • TweenAnimation(补间动画),是对某个View进行一系列的动画的操作,包括淡入淡出(Alpha),缩放(Scale),平移(Translate),旋转(Rotate)四种模式。
  • PropertyAnimation(属性动画),属性动画不再仅仅是一种视觉效果了,而是一种不断地对值进行操作的机制,并将值赋到指定对象的指定属性上,可以是任意对象的任意属性。
7. Android 异步消息处理机制

Handler 、 Looper 、Message 这三者都与Android异步消息处理线程相关的概念。

Looper负责的就是创建一个MessageQueue,然后进入一个无限循环体不断从该MessageQueue中读取消息,而消息的创建者就是一个或多个Handler 。

  • 首先Looper.prepare()在本线程中保存一个Looper实例,然后该实例中保存一个MessageQueue对象;因为Looper.prepare()在一个线程中只能调用一次,所以MessageQueue在一个线程中只会存在一个。
  • Looper.loop()会让当前线程进入一个无限循环,不断从MessageQueue的实例中读取消息,然后回调msg.target.dispatchMessage(msg)方法。
  • Handler的构造方法,会首先得到当前线程中保存的Looper实例,进而与Looper实例中的MessageQueue相关联。
  • HandlersendMessage方法,会给msgtarget赋值为handler自身,然后加入MessageQueue中。
  • 在构造Handler实例时,会重写handleMessage方法,也就是msg.target.dispatchMessage(msg)最终调用的方法。
  • 注:在Activity的启动代码中,已经在当前UI线程调用了Looper.prepare()和Looper.loop()方法。

http://blog.csdn.net/lmj623565791/article/details/38377229

8. ANR应用无响应

ANR产生的原因通常是在UI线程执行了一些耗时操作(网络操作、SD卡文件操作、数据库操作、大量计算等),导致超时,阻塞了UI线程。

Activity: onCreate(), onResume(), onDestroy(), 
onKeyDown(), onClick()等,超时时间5s

Application: onCreate(), onTerminate()等,超时时间5s

Service: onCreate(), onStart(), onDestroy()等,超时时间20s

BroadcastReceiver:onReceiver(),前台APP广播超时时间是10s,后台App是60s

避免

  • UI线程尽量只做跟UI相关的工作。
  • 耗时操作(如数据库操作,I/O等)放入单独的线程处理。
  • 尽量用Handler来处理UI线程和别的线程之间的交互。
9. Activity锁屏状态下的生命周期

对于锁屏状态,分两种情况考虑,一种是屏幕方向不会发生改变,一种是在清单文件中没有设置,屏幕方向可以发生改变。

屏幕方向不变
在清单文件中指定了屏幕方向,则Activity在锁屏和开启屏幕的时候执行的方法和顺序是:MainActivity onPause--->MainActivity onStop--->MainActivity onRestart--->MainActivity onStart--->MainActivity onResume

屏幕方向可变

  • 在清单文件中没有对屏幕进行设置,则Activity在锁屏时候执行的方法和顺序是:MainActivity onPause--->MainActivity onStop--->MainActivity onDestory--->MainActivity onCreate--->MainActivity onStart--->MainActivity onResume--->MainActivity onPause销毁之后又新建。
  • 开启屏幕的时候,Activity执行的方法及顺序是:MainActivity onResume--->MainActivity onPause--->MainActivity onStop--->MainActivity onDestory--->MainActivity onCreate--->MainActivity onStart--->MainActivity onResume。对于这种,锁屏后再次开启屏幕会销毁两次,重建两次。当设置了android:configChanges="keyboardHidden|orientation"之后就不会再重新走onCreate方法,不会再两次创建两次销毁
10. Android LowMemoryKiller机制

Android手机经常会自动杀死一些进程。

Andorid的Low Memory Killer是在标准的Linux lernelOOM 基础上修改而来的一种内存管理机制。当系统内存不足时,杀死不必要的进程释放其内存。

不必要的进程的选择根据有2个:oom_adj和占用的内存的大小oom_adj代表进程的优先级,数值越小,优先级越高,越不容易被杀死;对应每个oom_adj都可以有一个空闲进程的阀值oom_score_adj

Low Memory Killer 的阈值的设定,主要保存在2个文件之中,分别是:

  • /sys/module/lowmemorykiller/parameters/adj
  • /sys/module/lowmemorykiller/parameters/minfree

adj保存着当前系统杀进程的等级,minfree则是保存着对应的内存阀值。

2018春招实习面试_第4张图片
进程重要性

11. Android多线程

在Android中常用的多线程操作有Handler、AsyncTask、IntentService

Handle具体操作:
在主线程创建Handle实例,并实现handlmessage()方法;在线程中执行耗时操作,开启一个线程对应会产生一个looper,在初始化looper时会创建一个消息队列MessageQueue();执行完耗时操作,通过handle将消息发送到消息队列中,looper执行轮询消息队列将消息取出,并交给handlehandle根据消息类型做出相应的处理。

AsyncTask具体操作:

  • onPreExecute()运行在主线程中,开启线程前的准备操作;
  • doInBackground()运行在子线程中,用于处理耗时操作,通过调用publishProcess()onProcessUpdata()推送消息 ;
  • onProcessUpdata()运行在主线程中,当调用publishProcess()方法时就会开启此方法,接收到推送过来的数据,更新UI进度页面
  • onPostExecute()运行在主线程中,当子线程耗时操作执行完毕后会调用此方法,doInBackground()返回的参数传递到这里来用于更新UI ;
  • 调用execute()方法开启AsyncTask

IntentService具体操作:
IntentService和普通的Service区别在于,IntentServiceoncreate()方法中单独开启一个线程用于耗时操作;通过onHandleIntent(Intent intent)方法来处理耗时操作;在耗时操作执行完毕之后,会自动关闭service不用手动关闭 。

http://blog.csdn.net/qq_34358104/article/details/70237068

12. Activity四大启动模式

Activity的四种启动模式: standard、singleTop、singleTask、singleInstance

standard-默认模式
该模式是默认的启动模式,即标准模式。每次启动一个Activity都会重新创建一个新的实例。
singleTop-栈顶复用模式

  • 当前栈中已有该Activity的实例并且该实例位于栈顶时,不会新建实例,而是复用栈顶的实例,并且会将Intent对象传入,回调onNewIntent方法
  • 当前栈中已有该Activity的实例但是该实例不在栈顶时,其行为和standard启动模式一样,依然会创建一个新的实例
  • 当前栈中不存在该Activity的实例时,其行为同standard启动模式

standardsingleTop启动模式都是在原任务栈中新建Activity实例,不会启动新的Task

singleTask-栈内复用模式
在这个模式下,如果栈中存在这个Activity的实例就会复用这个Activity,不管它是否位于栈顶,复用时,会将它上面的Activity全部出栈,并且会回调该实例的onNewIntent方法。其实这个过程还存在一个任务栈的匹配,因为这个模式启动时,会在自己需要的任务栈中寻找实例,这个任务栈就是通过taskAffinity属性指定。如果这个任务栈不存在,则会创建这个任务栈。

singleTask启动模式启动Activity时,首先会根据taskAffinity去寻找当前是否存在一个对应名字的任务栈

  • 如果不存在,则会创建一个新的Task,并创建新的Activity实例入栈到新创建的Task中去
  • 如果存在,则得到该任务栈,查找该任务栈中是否存在该Activity实例
    如果存在实例,则将它上面的Activity实例都出栈,然后回调启动的Activity实例的onNewIntent方法
    如果不存在该实例,则新建Activity,并入栈

singleInstance-全局唯一模式
该模式具备singleTask模式的所有特性外,与它的区别就是,这种模式下的Activity会单独占用一个Task栈,具有全局唯一性,即整个系统中就这么一个实例,由于栈内复用的特性,后续的请求均不会创建新的Activity实例,除非这个特殊的任务栈被销毁了。以singleInstance模式启动的Activity在整个系统中是单例的,如果在启动这样的Activiyt时,已经存在了一个实例,那么会把它所在的任务调度到前台,重用这个实例。

http://blog.csdn.net/mynameishuangshuai/article/details/51491074

MVC、MVP、MVVM

三种架构的目的都是分离关注,避免将过多的逻辑全部堆积在一个类。

  • MVC将应用分成三个主要层级:Model模型层,View视图层和Controller控制层。其实android app的界面开发部分已经是遵从MVC模式,然而xml布局作为View来说功能很无力,所以通常Activity也会承担一部分View的工作。
  • MVP由MVC演变而来,MVP将Controller变成Presenter,并且改变了通信方向,这个模式将应用分为三个主要层级:Model, View and Presenter。
  • MVVM 模式将 Presenter 改名为 ViewModel,基本上与 MVP 模式完全一致,ViewModel可以理解成是View的数据模型和Presenter的合体,MVVM采用双向绑定(data-binding)。
热更新
快速排序

待补充。。。
-。-

你可能感兴趣的:(2018春招实习面试)