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的四大组件的特性
Activity:Activity是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方法