Android 面试题

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/bobo8945510/article/details/51961499

已经丢失工作好几天了,一直没有找到合适的公司,最重要的一点因为自己的java底子和理论知识太差劲了。造成了技能残废。什么办法呢,只能熬夜的去看面试题,去书本里查询。找了很多网页总结了一些面试题。为了记得牢固就自己手打一遍,也希望对别的小白有所帮助!


抽象类和接口的区别

抽象类:

1)抽象方法,只有行为的概念,没有具体的行为实现。使用abstract关键字修饰,没有方法体。子类必须重写这些抽象方法。

2)包含抽象方法的类,一定是抽象类。

3)抽象类只能被继承,一个类只能继承一个抽象类。

接口:

1)全部的方法都是抽象方法,属型都是常量

2)不能实例化,可以定义变量。

3)接口变量可以引用具体实现类的实例

4)接口只能被实现,一个具体类实现接口,必须实现全部的抽象方法

5)接口之间可以多实现

6)一个具体类可以实现多个接口,实现多继承现象


简述StringStringBufferArrayListLinkedListHashMapHashTable的特点及区别。

StringStringBuffer

1、String 对象的长度一旦定义就固定就不可以改变,对于已经存在的String对象的修改都是创建一个新的对象,然后把新的值存进去,String类不能被继承。

2、StringBuffer是一个可变对象,当对它进行修改的时候不会像String那样重新建立对象。它只能通过构造函数来建立对象。另外StringBuffer还是一个线程安全的类。

题外(如果想详细的了解,可到点击打开链接http://blog.csdn.net/jason0539/article/details/20899087,小白已经去看过,讲的很容易懂)

ArrayListLinkedList

1.ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。
2.对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。
3.对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。

题外(如果想了解ArrayList和LinkendList的详细知识,可以到点击打开链接http://blog.csdn.net/qianzhiyong111/article/details/6678035,里面有详细的讲解哦)


HashMapHashtable的特点及区别

一.历史原因:Hashtable是基于陈旧的Dictionary类的,HashMap是Java 1.2引进的Map接口的一个实现

二.同步性:Hashtable是线程安全的,也就是说是同步的,而HashMap是线程序不安全的,不是同步的

三.值:只有HashMap可以让你将空值作为一个表的条目的key或value

特点:

1、HashMap是Hashtable的轻量级实现(非线程安全的实现),他们都完成了Map接口,主要区别在于HashMap允许空(null)键值(key),由于非线程安全,在只有一个线程访问的情况下,效率要高于Hashtable。

2、HashMap允许将null作为一个entry的key或者value,而Hashtable不允许。

3、HashMap把Hashtable的contains方法去掉了,改成containsvalue和containsKey。因为contains方法容易让人引起误解。

4、Hashtable继承自Dictionary类,而HashMap是Java1.2引进的Map interface的一个实现。

5、最大的不同是,Hashtable的方法是Synchronize的,而HashMap不是,在多个线程访问Hashtable时,不需要自己为它的方法实现同步,而HashMap 就必须为之提供外同步。

6、Hashtable和HashMap采用的hash/rehash算法都大概一样,所以性能不会有很大的差异。

题外(如果想了解HashMapHashtable的详细知识,可以到点击打开链接http://blog.csdn.net/tgxblue/article/details/8479147,里面有详细的讲解哦,我还给作者一个赞,虽然我看不太懂里面的算法和源码


多线程有几种实现方式,同步有几种实现方式,stop()suspend()方法为什么不推荐使用

1、多线程有两种实现方法,分别是继承Thread类与实现Runnable接口
2、同步的实现方面有两种,分别是synchronized,wait与notify"

3、反对使用stop(),是因为它不安全。它会解除由线程获取的所有锁定,而且如果对象处于一种不连贯状态,那么其他线程能在那种状态下检查和修改它们。结果很难检查出真正的问题所在。

4、反对使用suspend()方法是因容易发生死锁(我的理解就是占的茅坑不拉屎)。 调用suspend()的时候,目标线程会停下来,但却仍然持有在这之前获得的锁定。此时,其他任何线程都不能访问锁定的资源,除非被"挂起"的线程恢复 运行。对任何线程来说,如果它们想恢复目标线程,同时又试图使用任何一个锁定的资源,就会造成死锁。所以不应该使用suspend(),而应在自己的 Thread类中置入一个标志,

题外(如果想了解多线程有几种实现方式,可以到点击打开链接http://blog.csdn.net/jspamd/article/details/5262894,里面有详细的讲解哦,很赞的一文章,小白还没仔细阅读,但是讲的很通俗易懂,建议去看下)!

4、 从操作系统角度请阐述一下线程与进程的区别(有点绕)

答:进程是系统进行资源分配和调度的一个独立单位,线程是CPU调度和分派的基本单位

进程和线程的关系:

(1)一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程。

(2)资源分配给进程,同一进程的所有线程共享该进程的所有资源。

(3)线程在执行过程中,需要协作同步。不同进程的线程间要利用消息通信的办法实现同步。(那怎么消息通信呢?)

(5)线程是指进程内的一个执行单元,也是进程内的可调度实体。

线程与进程的区别:

(1)调度:线程作为调度和分配的基本单位,进程作为拥有资源的基本单位。

(2)并发性:不仅进程之间可以并发执行,同一个进程的多个线程之间也可以并发执行。

(3)拥有资源:进程是拥有资源的一个独立单位,线程不拥有系统资源,但可以访问隶属于进程的资源。

(4)系统开销:在创建或撤销进程的时候,由于系统都要为之分配和回收资源,导致系统的明显大于创建或撤销线程时的开销。但进程有独立的地址空间,进程崩溃后,在保护模式下不会对其他的进程产生影响,而线程只是一个进程中的不同的执行路径。线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮,但是在进程切换时,耗费的资源较大,效率要差些。



6、 Android系统的架构,采用了分层的架构,从高层到底层分别是?

1.Android系统架构之应用程序

Android会同一系列核心应用程序包一起发布,该应用程序包包括email客户端,SMS短消息程序,日历,地图,浏览器,联系人管理程序等。所有的应用程序都是使用JAVA语言编写的。

2.Android系统架构之应用程序框架

开发人员可以完全访问核心应用程序所使用的API框架(android.jar)。该应用程序的架构设计简化了组件的重用;任何一个应用程序都可以发布它的功能块并且任何其它的应用程序都可以使用其所发布的功能块。

3.Android系统架构之系统运行库

1)程序库

Android 包含一些C/C++库,这些库能被Android系统中不同的组件使用。它们通过 Android 应用程序框架为开发者提供服务。

4.Android系统架构之Linux 内核

Android 的核心系统服务依赖于 Linux 2.6 内核,如安全性,内存管理,进程管理, 网络协议栈和驱动模型。 Linux 内核也同时作为硬件和软件栈之间的抽象层。


请解释下在单线程模式中Message,Handler,MessageQueue,Looper之间的关系解释下.

(我的前面博客也有讲,可以去看下)

Handler获取当前线程中的looper对象,looper用来从存放Message的MessageQueue中取出Message,再有Handler进行Message的分发和处理.

Message Queue(消息队列):用来存放通过Handler发布的消息,通常附属于某一个创建它的线程,可以通过Looper.myQueue()得到当前线程的消息队列.

Handler:可以发布或者处理一个消息或者操作一个Runnable,通过Handler发布消息,消息将只会发送到与它关联的消息队列,然也只能处理该消息队列中的消息.

Looper:是Handler和消息队列之间通讯桥梁,程序组件首先通过Handler把消息传递给Looper,Looper把消息放入队列。 Looper也把消息队列里的消息广播给所有的Handler:Handler接受到消息后调用handleMessage进行处理. 


说说mvc模式的原理,它在android中的运用(这个有点深,还需要继续学习和了解)

l模型(model)对象:是应用程序的主体部分,所有的业务逻辑都应该写在该层。

2视图(view)对象:是应用程序中负责生成用户界面的部分。也是在整个mvc架构中用户唯一可以看到的一层,接收用户的输入,显示处理结果。

3控制器(control)对象:是根据用户的输入,控制用户界面数据显示及更新model对象状态的部分,控制器更重要的一种导航功能,想用用户出发的相关事件,交给m哦得了处理。

在android中mvc的具体体现如下:

   1)视图层(view):一般采用xml文件进行界面的描述,使用的时候可以非常方便的引入,当然,如何你对android了解的比较的多了话,就一定 可以想到在android中也可以使用javascript+html等的方式作为view层,当然这里需要进行java和javascript之间的通 信,幸运的是,android提供了它们之间非常方便的通信实现。

 2)控制层(controller):android的控制层的重 任通常落在了众多的acitvity的肩上,这句话也就暗含了不要在acitivity中写代码,要通过activity交割model业务逻辑层处理, 这样做的另外一个原因是android中的acitivity的响应时间是5s,如果耗时的操作放在这里,程序就很容易被回收掉。

 3)模型层(model):对数据库的操作、对网络等的操作都应该在model里面处理,当然对业务计算等操作也是必须放在的该层的。

9. 谈谈对android内存优化的方法,方案,规则及对内存泄漏如何避免(这个也要在下章博客深入学习)

OOM即Out Of Memory,一般是由程序编写者对内存使用不当,如对该释放的内存资源没有释放,导致其一直不能被再次使用而使内存被耗尽的现象。根本的解决办法是对代码进行优化:在内存引用上做些处理,使用软引用、虚引用、和弱引用;在内存中加载图片时直接在内存中做处理,如边界压缩等;建立动态回收内存机制;优化Dalvik虚拟机的堆内存分配;自定义堆内存大小等。

一般而言,android中常见的原因主要有以下几个:
1.数据库的cursor没有关闭。
2.构造adapter没有使用缓存contentview。
3.调用registerReceiver()后未调用unregisterReceiver().
4.未关闭InputStream/OutputStream。
5.Bitmap使用后未调用recycle()。
6.Context泄漏。
7.static关键字等。


10 AIDL 的全称是什么?如何工作?能处理哪些类型的数据?

答:  AIDL: (Android Interface Definition Language)跨进程通信传输语言

   如何工作:AIDL文件由自己定义,在被绑定的Service中和绑定的客户端中都要部署

   1.创建AIDL文件, 在这个文件里面定义接口, 该接口定义了可供客户端访问的方法和属性。

2、编译AIDL文件, 用Ant的话, 可能需要手 动, 使用Eclipse plugin的话,可以根据adil文件自动生产java文件并编译, 不需要人为介入.

3、在Java文件中, 实现 AIDL中定义的接口. 编译器会根据AIDL接口, 产生一个JAVA接口。这个接口有一个名为Stub的内部抽象类,它继承扩展  了接口并实现了远程调 用需要的几个方法(是Binder的子类)。接下来就需   要自己去实现自定义的几个接口了.

4.第一个程序的Service:因为跨进程传递时利用Binder对象来实现的,所以我们要在Service端构建Binder对象,又因为我们定义的接口AIDL文件在编译转成.java时的内部类Sub实现了Binder,所以我们构建Binder对象时构建实例内部类直接继承Sub内部类,在类中我们可以调用Service中的方法,此类的对象也就是Binder对象.

5.第二个程序的Activity:在Activity中我们利用bindService方法启动一个绑定的Service的同时需要传入连接对象,所以我们先在Activity中构建Service的连接对象,在该对象的匿名内部类中重写获得Binder对象的方法,参数含有Binder对象,将此对象强制转换成我们在Service中继承Sub的类的对象,强转后我们可以利用该对象调用Service中的方法,从而实现跨进程通信,控制Service.

(看着很绕,建议看下极客学院里面有专门讲解ALDL的视频,http://www.jikexueyuan.com/course/729.html)


11 进程间通信机制,传统IPC Binder(Binder需要好好学习)

答:传统的进程间通信机制IPC 有管道(Pipe)、信号(Signal)和跟踪(Trace),这三项通信手段只能用于父进程和子进程之间,或者兄弟进程之间;后来又增加了命令管道(Named Pipe),使得进程间通信不再局限于父子进程或兄弟进程之间。后来又出现了报文队列(Message)、共享内存(Share Memeory)和信号量(Semaphore)。Android系统没有采用上述提到的各种进程间通信机制,而是采用Binder机制,它是基于OpenBinder来实现的。

它提供了远程过程调用(RPC)功能,在Android系统的Binder机制中,有一系列组件组成包括 Client、Server、ServiceManager和Binder驱动程序。



12 SerializableParcelable的特点及比较

答:Serializable和Parcelable二者都是实现序列化的接口。

Parcelable,定义了将数据写入Parcel,和从Parcel中读出的接口。一个实体(用类来表示),如果需要封装到消息中去,就必须实现这一接口,实现了这一接口,该实体就成为“可打包的”了。Parcelable的实现,需要在类中添加一个静态成员变量CREATOR,这个变量需要继承Parcelable.Creator接口。

一个对象序列化的接口,一个类只有实现了Serializable接口,它的对象才是可序列化的。因此如果要序列化某些类的对象,这些类就必须实现Serializable接口。而实际上,Serializable是一个空接口,没有什么具体内容,它的目的只是简单的标识一个类的对象可以被序列化。Serializable的实现,只需要implements Serializable即可,这只是给对象打了一个标记,系统会自动将其序列化。

区别 : 

Serializable是Java.io中的,不可被activity中的内部类被继承,否则出错;Parcelable是Android特有的,比Serializable节省内存,可以传递Bundle对象,当我们有boolean型的变量可以现存在Bundle中。


13 ViewsurfaceViewGLSurfaceView有什么区别

View:显示视图,内置画布,提供图形绘制函数、触屏事件、按键事件函数等,必须在UI主线程内更新画面,速度较慢

SurfaceView:基于view视图进行拓展的视图类,更适合2D游戏的开发,是view的子类,类似使用双缓机制,在新的线程中更新画面所以刷新界面速度比view快

GLSurfaceView:基于SurfaceView视图再次进行拓展的视图类,专用于3D游戏开发的视图,是surfaceView的子类,openGL专用



14 什么是TCPIP,它们位于网络模型的哪层?

TCP是传输控制协议,IP是internet协议,TCP在网络模型中与UDP一样同属于第二层(传输层),IP属于三层(网络层),IP用于确定主机在网络中的位置,而TCP与UDP用于标示不同的服务,即应用程序。



好吧,今天就这么多吧。也是自己慢慢整理了两个多小时的成果,这里面讲的都是很有概念性,如果需要深入了解,还需要自己去每个知识点认真去学习。继续努力找工作,继续努力学习!

















阅读更多

没有更多推荐了,返回首页