Android常遇到的面试

1. 面向对象的3个特征分别是?请简述。

【封装】封装是一个先“装”再“封”的过程,封装即可以是属性的封装,也可以是方法的封装,甚至是类的封装(例如简单工厂模式)。

public class Person {

         publicString name;

         privateint age;

         publicvoid setAge(int age) {

                   if(age< 12 || age > 80) {

                            this.age= 0;

                   }else {

                            this.age= age;

                   }

         }

         publicint getAge() {

                   returnthis.age;

         }

}

 

Person p = new Person();

// p.age = 18000;

p.setAge(18000);

【继承】继承是一种利用已有的类,快速的创建新的类的机制,当实现了继承关系时,子类将得到父类中所有的属性和方法,包括在父类中被声明为私有的,当然,私有的属性和方法即使被子类继承得到也不只能有1个直接父类。

【多态】多态在程序代码中,表现为“要父类的对象,给子类的对象”,在代码的执行过程中,如果子类中重写了父类中定义的方法,将执行子类重写后的代码,关于概念本身,多态意为“多种形态”,即编译期和运行期是不同的形态。

Animal a = new Dog();

 

2. 请简述抽象与接口的概念与意义?

【抽象】

1. 抽象类中允许包括抽象方法,但不一定包括抽象方法

2. 抽象类不允许直接创建对象

3. 抽象类中的抽象方法是不完整的,继承了抽象类的子类,有义务去实现这些抽象方法,除非该子类也是抽象的

4. 抽象类可以被认为是“用于被继承的”

【接口】

1. 接口中的成员都是public的

2. 接口中的属性都是static final的

3. 接口中的方法都是abstract的

4. 某个类可以同时实现(implements)多个接口

5. 接口与接口之间可以继承(extends),并且多继承,即1个接口可以有若干个直接父级接口

【案例】

public interface InterfaceA {

         voidrun();

}

public interface InterfaceB {

         voidrun();

}

假设存在某个类,同时实现以上2个接口,则接口中的抽象方法需要被重写几次?如果只需要重写1次,实现的是哪个接口中定义的方法?

 

3. 关于String的特性,及使用时的注意事项。

String的特性在于高使用频率,所以在JAVA中,程序运行时,JVM会分配String常量池,并且,String具有不可变性

由于String具有不可变性,所以在高频率的运算过程中,则会在内存中创建非常多String数据的对象,所以,在高频率的字符串运算中,应该使用StringBuffer或StringBuilder代替

 

4. 请简述重载(Overload)的概念

重载是在某个类中,允许存在多个同名的方法的机制,这些方法必须有不同的参数列表,表现为:参数的数据类型不同、数量不同,及顺序(无视参数名称)不同。

method(int)

method(String)

method(int, int)

method(String, String)

method(String, int)

method(int, String)

 

5. 请简述重写(Override /Overwrite)的概念

当实现继承关系后,子类可以重新定义在父类中已经定义的方法,即为重写,或者当某个类实现了接口后,则可以重写在接口中定义的方法。

当子类/接口的实现类对象调用方法时,会执行重写后的方法。

重写方法时,需要使用和父类/接口中定义的方法相同的签名,关于方法的访问权限修饰符,子类/接口的实现类可以使用更宽松的访问权限。

重写方法时,子类/接口的实现类不可以在重写的方法中抛出(throws)更多的异常。

 

6. 请简述this关键字的作用

this在类中表示该类的某个对象的引用,至于是哪个对象,取决于是哪个对象执行了this所在的语句

 

7. 请简述super关键字的作用

1) 访问父类中被隐藏的属性

public class Father {

         intmoney = 1000000;

}

public class Son extends Father {

         intmoney = 1;

         publicint getFatherMoney() {

                   returnsuper.money;

         }

}

2) 调用父类的方法

public class Father {

         publicvoid run() { }

}

public class Son extends Father {

         publicvoid run() {

                   super.run();

         }

         publicvoid test() {

                   super.run();

         }

}

3) 调用父类的构造方法

在子类的构造方法中,可以使用super(参数);语句调用父类的构造方法,如果在子类的构造方法中,没有该语句,则编译器自动在子类的构造方法的首行添加super();语句。

在子类的构造方法中,super(参数);语句必须是第1行有效代码。

只允许在子类的构造方法中调用父类的构造方法,而不允许在其它一般方法中调用。

 

8.请简述集合框架中主要的接口与类,及各种集合的特性

接口:Collection、List、Set、Map

类:Collections、ArrayList、LinkedList、HashSet、TreeSet、HashMap、TreeMap

Collection:集合顶端的接口

List:List是Collection的子级接口,有序的容器(序列的),在List中的每个元素都有一个唯一的索引,等同于数组的下标

Set:Set是Collection的子级接口,无序的容器(散列的),所有的元素在Set中没有唯一标识,在Set中的元素是不可重复的,重复的标准是:对象与对象的equals()对比的结果为true,且hashCode()的返回值相等。

Map:Map与Collection不在同一条继承链上,Map由Key和Value形成键值对的数据存储方式,其中,Map中的Key是不可重复的,重复标准参考Set集合的特性

 

9.请简述final和static关键字的意义

【final】

1) 被final修饰的类,不可以被继承

2) 被final修饰的方法,不可以被重写

3) 被final修饰的量,不可以存在多次赋值,即只允许赋值1次

public class Sample {

         publicfinal int x = 100;

         publicvoid run(final int arg) {

                   finalint i;

                   i= 5;

         }

}

【static】

1) 可以使用static修饰类的成员

2) 被static修饰的成员,可以使用“类名.成员名”调用,并且,多个该类的对象共享同一个被static修饰的属性

3) 被static修饰的成员,将最优先加载到内存,并且不依赖于该类的对象

4) 被static修饰的成员,不可以直接访问非static成员

 

10.请简述“简单的抽象工厂模式”的实现及意义

【实现步骤】

1. 创建抽象的父类

public abstract class Car { }

2. 创建抽象的父类生产者(工厂),工厂之所以抽象的原因在并不希望其它类创建出工厂的实例,如果允许创建工厂本身,则该工厂类可以不声明为抽象的

public abstract class CarFactory {}

3. 在工厂中,定义返回值类型为该抽象父类的方法,如果工厂本身是抽象的,则该方法应该是static的,保证其它类在不创建工厂时也可以调用该方法,通常情况下,该方法的名称为newInstance(),如果生产出来的对象可能是单例的,则方法名称可以使用getInstance()

public static Car newInstance() { returnnull; }

4. 创建类,继承自抽象的父类,并将生产者中的方法的返回值确定为该子类的对象

public class Audi extends Car {}

public abstract class CarFactory {

         publicstatic Car getInstance() {

                   returnnew Audi();

         }

}

【意义】

对类进行封装,以便于统一使用和管理

 

11.请简述ANDROID的四大组件的特性

ActivityActivity是Android程序与用户交互的窗口,是Android构造块中最基本的一种,它需要为保持各界面的状态,做很多持久化的事情,妥善管理生命周期以及一些跳转逻辑。

service后台服务于Activity,封装有一个完整的功能逻辑实现,接受上层指令,完成相关的事务,定义好需要接受的Intent提供同步和异步的接口。

Content Provider是Android提供的第三方应用数据的访问方案,可以派生Content Provider类,对外提供数据,可以像数据库一样进行选择排序,屏蔽内部数据的存储细节,向外提供统一的接口模型,大大简化上层应用,对数据的整合提供了更方便的途径。

BroadCast Receiver接受一种或者多种Intent作触发事件,接受相关消息,做一些简单处理,转换成一条Notification,统一了Android的事件广播模型。

 

12. 请简述流的种类、应用场景,并列举至少8种流

按数据的走向:输入流、输出流

按处理的数据的形态:字节流、字符流

具体的表现:

a) 输入字节流 InputStream

b) 输出字节流 OutputStream

c) 输入字符流 Reader

d) 输出字符流 Writer

处理原则:

a) 任何数据的传输都可以使用字节流

b) 需要显示非ASCII字符时必须使用字符流,但字符流不适用于其它的数据传输,例如复制文件

c) 在某些情景下,根据某些流的特性,来决定使用哪种流

常用的流:

FileInputStream / FileOutputStream

FileReader / FileWriter

BufferedInputStream / BufferedOutputStream

BufferedReader / BufferedWriter

InputStreamReader / OutputStreamWriter

PrintWriter

 

13. 请简述异常的体系结构,处理异常的方式,并列举至少5种异常

异常的最顶端的类是Throwable,其直接子级类有Error和Exception,Error表示的是错误,是该程序运行过程中必然出现的问题,当出现Error时,需要更换硬件,或者换新的思路编程,Exception是异常,其子级类区分为RuntimeException和其它异常,其中,RuntimeException是运行时异常的父类,只要是RuntimeException都可以不必在程序中对异常进行处理,这类异常往往都是编程不严谨导致,其它非RuntimeException必须在程序中显式的进行处理,处理的方式可以是使用try...catch...finally语法包裹代码,也可以在方法的签名上使用throws将异常抛出

注意事项:

1) 对于非RuntimeException而言,可以在代码中使用throw语句抛出,同时,必须在方法的签名中使用throws语句进行声明

2) 在重写的方法中,不可以抛出更多的异常,或者更加贴近父级的异常

3) 在使用try...catch语法时,如果存在多种异常需要处理,可以使用1个try和若干个catch,这些catch语句原则上不区分先后顺序,如果这些catch语句中的异常存在继承关系,则必须先catch子类的异常,再catch父类的异常

常见的异常:

FileNotFoundException

IOException

SQLException

NullPointerException

ClassCastException

IndexOutOfBoundsException

ArrayIndexOutOfBoundsException

NumberFormatException

 

14.请简述ANDROID系统中关于BaseAdapter的优化原理与实现.

 

ListView的优化:

1、如果自定义适配器,那么在getView方法中要考虑方法传进来的参数contentView是否为null,如果为null就创建contentView并返回,如果不为null则直接使用。在这个方法中尽可能少创建view。

2、给contentView设置tag(setTag()),传入一个viewHolder对象,用于缓存要显示的数据,可以达到图像数据异步加载的效果.

3、如果listview需要显示的item很多,就要考虑分页加载。比如一共要显示100条或者更多的时候,我们可以考虑先加载20条,等用户拉到列表底部的时候再去加载接下来的20条。

4、设置listview的监听器,如果listview是飞快滑动状态则不更新view

 

15.请简述线程的概念,及基本使用方式

一个应用程序中可能存在多个进程,每个进程中可以包括多个线程.

线程的特点有:

多个线程可以同时执行(事实上是交替执行,并且在每个线程上,分配资源的时间是应用程序不可控的)

开启线程的方式:

可以自定义类,继承自Thread类,并重写该类的public void run()方法,当需要开启线程时,创建出自定类的对象,并调用start()方法即可,或者,自定类实现Runnable接口,实现抽象方法,最后,创建Thread类的对象,并且在创建过程中,使用自定义的Runnable的实现类对象作为构造方法的参数,并调用Thread类的对象的start()方法即可.

 

16.请简述下Activity生命周期

onCreate() :在这里创建界面,做一些数据的初始化工作

onStart():activity变为在屏幕上对用户可见时调用.

onResume():Activity开始与用户交互时调用

onPause():

onStop():

onRestart():

onDestroy():

当Activity被激活时:onCreate()->onStart()->onResume()

当Activity被销毁时:onPause()->onStop()->onDestroy()

 

17.请简述Activity的启动模式

1.standard:[默认]标准的,每次都会激活一个全新的Activity.

2.singleTop:当Activity位于任务栈的顶部时,是唯一的.

3.singleTask:在任务栈中是唯一的,如果当前Activity在任务栈中不存在,则直接创建,并获取栈顶位置,如果当前Activity已在任务栈中存在,则清除任务栈中的该Activity上方的所有Activity,并且让该Activity自然获得栈顶位置.

4.singleInstance:Activity独自占有另外一个任务栈,并该栈中仅有这一个Activity

 

18.请简述访问数据库的流程,及在访问数据时使用的增删改查语句

【访问流程】:

1.       连接数据库/打开数据库文件,保证数据库是可以被访问的

2.       准备访问数据的工具,例如:PreparedStatement/SQLiteDatabase

3.       准备需要执行的SQL指令

4.       使用工具类对象执行SQL指令,并且获取结果,结果通常是int或ResultSet / Cursor

5.       在访问结束后释放资源.

【增删改查语法】

Insert  into 表名 (字段列表) values (值列表)

Delete  from 表名 [where 子句]

Update  表名 set 字段 = 值的赋值列表 [where 子句]

Select 字段列表或者星号 from 表名 [where 子句] [order by 子句]

 

19.请简述内部类的种类,使用时的注意事项

【概念】

定义在某个类的内部的类,即为内部类

【种类】

成员内部类;局部内部类;静态(成员)内部类;匿名内部类

【作用】

更好的隐藏类的成员甚至内部类本身;更加方便的访问外部类的成员;更好的管理内部类。

【注意事项】

对于非静态内部类:在没有外部类的对象之前,不可以直接创建内部类的对象;

局部内部类:不可以直接访问一般的局部变量,解决方案是将该局部变量提升为全局变量(类的成员),或者使用final修饰该局部变量;并且,在局部内部类访问局部变量时,局部变量必须在局部内部类之前声明

 

20.请简述在Android中绘图的流程

【主要使用到的类】

Canvas、Paint、Bitmap

【各个类的作用】

Canvas:画布,用于承载Bitmap,并提供各种绘制的方法

Paint:画笔,用于配置绘制的属性,例如颜色、笔触、字体等

Bitmap:绘制出来的图形

【绘制流程】

1.      创建好Bitmap

2.      创建Canvas对象,并且将Bitmap配置到Canvas中

3.      创建Paint对象,并且配置Paint对象的各属性

4.      调用Canvas对象的各种绘制方法,实现图形的绘制

5.      处理Bitmap对象

 

21.请简述Android中的UI线程模型与线程间通信机制

【使用约束】

1.      主线程在启动时,默认都会加载UI界面,并完成初始化

2.      只有创建UI的线程才可以操作UI控件,即只有主线程才可以操作UI控件

3.      主线程不允许执行耗时操作

【总结】

1.      耗时操作只能在分支线程中完成,但是分支线程不允许操作UI控件

2.      主线程可以操作UI控件,但是不允许执行耗时操作

【线程间通信】

由于在Android中的UI线程与分支线程之间的矛盾,则需要实现线程间通信,即:分支线程用于完成耗时操作,并告知UI线程操作已完成,然后由UI线程操作UI控件更新界面显示。

在Android中的线程间通信都是使用“消息机制”实现的,在这个机制中,由Message类作为消息的载体,Handler类用于发送消息及在收到消息后对消息进行处理

 

22.当启动应用程序时,其启动流程是?

检索AndroidManifest.xml文件找到入口Activity,启动对应的Activity,根据Activity的生命周期,会自动执行onCreate(),在onCreate()执行过程中,根据setContentView()方法的参数,决定要加载的布局layout,从而决定该应用程序的显示

 

23.什么是进程,什么是线程?为什么需要线程间通信,表现是什么?为什么需要进程间通信,表现是什么?

 

 

24.请简述Android中AdapterView与Adapter的工作模式

AdapterView的种类:

ListView、GridView、EXpandableListView、Spinner(下拉列表)、AutoCompleteTextView…

Adapter的种类:

ArrayAdapter、SimpleAdapter、SimpleCursorAdapter、BaseAdapter

实现AdapterView时需要:

AdapterView、Adapter、数据源、item模版

工作模式:

使用Adapter实现了AdapterView与数据源之间的低耦合。

Adapter的主要任务是将数据填充到item模版,并让AdapterView调用…

 

25.请列举在ANdroid中常用的View与Viewgroup

View与ViewGroup区别是:View是控件,可见的,ViewGroup是容器,不可见的。

View:Button、TextView、ImageView、ImageButton、EditText….

ViewGrop:LinearLayout、RelatieLayout、ListView、GridView、

 

26.请简述Intent的各核心属性,及各属性的作用

Intent的作用是用于激活系统组件,并在组件之间传递数据。

>>ComponentName: 组件名称,用于显示的指定需要被激活的组件

>>Action:动作,用于隐式的指定需要被激活的组件,其数据类型是String

>>Data:数据,通常与Action属性匹配使用,其数据类型是Uri

>>Extra: 附加数据,用于在组件之间的传递自定义的数据,其数据类型Bundle,类似于Map

>>Category:分类,用于隐式激活组件时需要指定组件的类型,其数据类型是String

>>Flag:标识,其数据类型是int

 

27.请简述自定义View的方法

当已有的View不能满足我们需求或者界面显示的效果不足时,才需要自定义View

自定义View继承已有的View(该View中某些功能可以直接使用)

28.请简述你对Android中网络编程的理解

Android中的网络编程是一种耗时操作,不允许在UI线程操作,需要在后台操作,也是敏感操作,需要添加访问网络声明权限

 

29.SAX 、DOM4J  、PULL解析的区别

SAX的特点:

1.      解析效率高,占用内存少

2.      可以随时停止解析

3.      不能载入整个文档到内存

4.      不能写入xml

5.      SAX解析XML文件采用的是事件驱动

PULL和SAX不同之处:

1.      Pull读取xml文件后触发相应的事件调用方法返回的是数字

2.      Pull可以在程序中控制,想解析到哪里就停止到哪里

3.      Android中更推荐使用Pull解析

DOM4J的特点:

优点:

1.      整个文档树在内存中,便于操作;支持删除、修改、重新排列等多种功能

2.      通过树形结构取Xml文档

3.      可以在树的某个节点上向前或向后移动

缺点:

1.      将整个文档调入内存(包括无用的节点),浪费时间和空间

适用场合:

一旦解析了文档还需多次访问这些数据;硬件资源充足(内存,cpu)

 

30.Java语音编写的程序入口SIGNATURE是什么?

public static void main(String[] args) { }

 

31.在Android中,主线程和工作线程的通信,与工作线程与工作线程的通信,有什么不同?

当存在主线程和工作线程的通信,并且需要通信时,必然是工作线程执行任务,主线程更新(进度或结果)UI,这类的通信需要使用”消息机制”类实现

当工作线程与工作线程之间相互通信时,可以使用:

(1)      某个线程wait()进行等待,将由其他线程notify() / notifyAll()唤醒

(2)      结合全局变量来判断

(3)      通过关联到子线程的Handler来实现

 

32.请简述在Android中事件处理机制

 

33.请简述JDBC的使用方式

 

34.请简述多线程下载原理

 

35.如何让广播接收者尽量获取更高的优先级

 

1) 指定最大值的priority

2) 可行的情况下,设置排序可以更靠前的包名

3) 使用静态注册的方式,接收“系统开机”的广播,并且在接收到该广播后,使用动态注册的方式注册广播接收者

 

36. 横竖屏切换时候activity的生命周期?

 

  1、不设置Activity的android:configChanges时,切屏会重新调用各个生命周期,切横屏时会执行一次,切竖屏时会执行两次

 

  2、设置Activity的android:configChanges="orientation"时,切屏还是会重新调用各个生命周期,切横、竖屏时只会执行一次

 

  3、设置Activity的android:configChanges="orientation|keyboardHidden"时,切屏不会重新调用各个生命周期,只会执行onConfigurationChanged方法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值