经典Android面试题

1.解释下在单线程模型中Message,Handler,Message Queue,Looper之间的关系。

  主线程中,主线程启动时会调用Looper.prepare()方法,会初始化一个Looper,放入Threadlocal中,接着调用Looper.loop()遍历Message Queue;  Handler的创建依赖与当前线程中的Looper,如果当前线程没有Looper则必须调用Looper.prepare()。Handler,sendMessage到MessageQueue,Looper不断从MessageQueue中取出消息,回调handleMeaage方法。

2.内存溢出和内存泄漏的区别?何时会产生内存泄漏?内存优化有哪些方法?

      内存溢出:应用程序运行时需要的内存,超出了它可用的最大内存

  内存泄漏:针对某一内存空间的使用,使用完成后没有释放。

  内存优化:Android中容易内存溢出的部分,就是图片的加载,我们可以使用图片的压缩加上使用LruCache缓存的方法来控制图片所能够使用的内存

  除此之外,对于比较耗资源的对象及时的关闭,比如service、conn、各类传感器、Database,屏幕旋转,整个Activity对象会有泄漏。

  解决办法(避免内存泄漏没有简单的解决方案,但Android提供的工具和API可以提供帮助):DDMS视图中,可以使用Heap及Alloction Tracker跟踪内存使用和分配情况。   Android2.3定义StrictMode类,对检测潜在的内存泄漏有很大帮助,但在3.0以上版本中,可以检测的潜在内存泄漏的情况有:

    1.activity泄漏

    2.其他对象泄漏

    3.对象没有关闭造成的泄漏

3.AsyncTask使用在哪些场景?它的缺陷是什么?如何解决?

  AsyncTask运用的场景是需要进行一些耗时的操作,耗时操作完成时更新主线程,或者在操作过程中对主线程的UI进行更新

缺陷:AsyncTask中维护着一个长度为128的线程池,同时可以执行5个工作线程,还有一个缓冲队列,当线程池中已有128个线程,缓冲队列已满,如果此时向线程提交任务,将会抛出RejectedExecutionException

处理:由一个线程来处理AsyncTask的调用判断线程池是否满了,如果满了线程睡眠否则请求AsyncTask继续处理。

4.context的作用是什么?一个APP最多会创建多少个Context对象?

  ①context是一个抽象类,其通用实现在ContextImpl类中。

  ②Context是一个访问application环境全局信息的接口,通过它可以访问application的资源和相关类,其主要功能如下:

  启动Activity   启动和停止Service    发生广播消息(Intent)    注册广播消息接收者

  可以访问APK中各种资源(Resources 和 AssetManager等)

  可以访问Package的相关信息    APK的各种权限管理

  从以上可以看出,Context就是一个对APK包无所不知的大管家,想知道什么信息,就去访问它就可以了

  

Context与View的关系

  

ContextWrapper

  它只是对Context类的一种封装,它的构造函数包含了一个真正的Context引用,即ContextImpl对象

ContextThemeWrapper

  该类包含了主题(Theme)相关接口,即安卓theme指定的,因为service不需要theme,所以Service直接继承ContextWrapper

何时创建Context

  ①创建Application对象时

  ②创建service对象时

  ③创建Activity对象时

  因此应用程序App共有的Context数目公式为:

  总Context实例个数 = NUM(Activity) + NUM(Service) + 1(Application)

5.写出并描述Service和Activity的交互方式

  

6.Android开发过程中如何进行算法与界面的优化?

  挑战程序的进程结构,减少进程数量,减少进程周期循环次数,即时让线程休眠,不编写长寿代码,只在需要时运行,服务应快速完成并立即结束。

  调整算法,取消不必要的环节,减少对CPU和内存的需求,减少函数的调用次数,适当使用JNI

  精心设计界面避免复杂布局,控制嵌套和View数量,善用Merge、inflate()、RelativeLayout等去除不必要的背景、动画执行长时间、好点的任务前检查电量,提示用户

7.

================================================java====================================================

1.计算下列result的值

  int a = 1234567;
      int b = 0x06;
      int result = a&b;      6

二进制&运算,很简单,转化成二进制进行与运算,一定不要犯懒,我就是犯懒没有计算a的二进制,结果自己就悲剧了。。。

2.抽象类与接口的区别?

  abstract可以修饰抽象方法,而一个类主要有一个抽象方法,就必须用abstract定义该类,即抽象类。

  用interface修饰的类,里面的方法都是抽象方法,因此在定义接口的时候,可以直接不加那些修饰,系统会默认加上去,接口里面的字段都是共有常量,即public static final

3.集合实现类与区别?

  Collection接口、集合结构总的父接口,有两个子接口list和set

  list有序,元素可重复    实现类:ArrayList数组实现轻量级、运行快、线程不安全、查询快

  Vectot数组实现重量级,运行慢、线程安全

  LinkedList 链表实现,常用于堆栈与队列的实现 增删操作快

  set接口   元素无序不重复

  实现类:HashSet,底层用hashCode算法实现,保证元素的无序唯一,自定义对象存进HashSet为了保证元素内容不重复,需要重写hashCode()和equals()方法。

  SortedSet元素有序           唯一

  TreeSet要求元素有序,自定义的对象需要实现Comparable接口的compareTo(Object o)方法

  Map:与Collection接口无关,有一个子接口SortedMap   无序,key-value对,key唯一,value可重复

  HashMap轻量级  线程不安全,允许key或value为null

  HashTable 重量级  线程安全  不允许key或vaule为null

  Properties是HashTable的子类,主键和值都是字符串

4.线程的状态有几种?分别是什么?

  1)新建状态:创建了一个线程对象。

  2)就绪状态:线程对象创建后,其他线程调用了该对象的start方法。该状态的线程位于可运行线程池中,变得可运行,等待CPU的使用权

  3)运行状态:就绪状态的线程获得了CPU,执行run()方法

  4)阻塞状态:阻塞状态是因为线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,线程才有机会继续运行。阻塞情况分为3中

  

  

原文地址:https://www.cnblogs.com/SamSarah/p/4896384.html