菜鸟面试修行记

面试问题总结:
1、service 启动方式
分为两种:
一、Context.startService()方式启动 
Context.startService()方式的生命周期: 启动时,startService –> onCreate() –> onStart()停止时,stopService –> onDestroy()如果调用者直接退出而没有停止Service,则Service 会一直在后台运行 Context.startService()方法启动服务,在服务未被创建时,系统会先调用服务的onCreate()方法,接着调用onStart()方法。如果调用startService()方法前服务已经被创建,多次调用startService()方法并不会导致多次创建服务,但会导致多次调用onStart()方法。采用startService()方法启动的服务,只能调用Context.stopService()方法结束服务,服务结束时会调用onDestroy()方法附代码
二、Context.bindService()方式启动

Context.bindService()方式的生命周期: 绑定时,bindService -> onCreate() –> onBind()调用者退出了,即解绑定时,Srevice就会unbindService –>onUnbind() –> onDestory()Context.bindService()方式启动 Service的方法:绑定Service需要三个参数:bindService(intent, conn, Service.BIND_AUTO_CREATE);第一个:Intent对象,第二个:ServiceConnection对象,创建该对象要实现它的onServiceConnected()和 onServiceDisconnected()来判断连接成功或者是断开连接第三个:如何创建Service,一般指定绑定的时候自动创建


2、Bitmap存储位置
在Android3.0之前,Bitmap的内存分配分为两部分,一部分是分配在Dalvik的VM堆中,而像素数据的内存是分配在Native堆中,而到了Android3.0之后,Bitmap的内存则已经全部分配在VM堆上,这两种分配方式的区别在于,Native堆的内存不受Dalvik虚拟机的管理,我们想要释放Bitmap的内存,必须手动调用Recycle方法,而到了Android 3.0之后的平台,我们就可以将Bitmap的内存完全放心的交给虚拟机管理了,我们只需要保证Bitmap对象遵守虚拟机的GC Root Tracing的回收规则即可。


3、多线程&多线程间通信

多线程:

Android提供了四种常用的操作多线程的方式,分别是:
1. Handler+Thread
2. AsyncTask
3. ThreadPoolExecutor
4. IntentService


 Handler+Thread:

Android主线程包含一个消息队列(MessageQueue),该消息队列里面可以存入一系列的Message或Runnable对象。通过一个Handler你可以往这个消息队列发送Message或者Runnable对象,并且处理这些对象。每次你新创建一个Handle对象,它会绑定于创建它的线程(也就是UI线程)以及该线程的消息队列,从这时起,这个handler就会开始把Message或Runnable对象传递到消息队列中,并在它们出队列的时候执行它们。

Handler可以把一个Message对象或者Runnable对象压入到消息队列中,进而在UI线程中获取Message或者执行Runnable对象,Handler把压入消息队列有两类方式,Post和sendMessage.
Post方式:
Post允许把一个Runnable对象入队到消息队列中。它的方法有:
post(Runnable)/postAtTime(Runnable,long)

postDelayed(Runnable,long)
对于Handler的Post方式来说,它会传递一个Runnable对象到消息队列中,在这个Runnable对象中,重写run()方法。一般在这个run()方法中写入需要在UI线程上的操作。


sendMessage:
sendMessage允许把一个包含消息数据的Message对象压入到消息队列中。它的方法有:

sendEmptyMessage(int)

sendMessage(Message)

sendMessageAtTime(Message,long)

sendMessageDelayed(Message,long)


Handler如果使用sendMessage的方式把消息入队到消息队列中,需要传递一个Message对象,而在Handler中,需要重写handleMessage()方法,用于获取工作线程传递过来的消息,此方法运行在UI线程上。Message是一个final类,所以不可被继承。


优缺点
1. Handler用法简单明了,可以将多个异步任务更新UI的代码放在一起,清晰明了
2. 处理单个异步任务代码略显多
适用范围
1. 多个异步任务的更新UI

AsyncTask:
AsyncTask是android提供的轻量级的异步类,可以直接继承AsyncTask,在类中实现异步操作,并提供接口反馈当前异步执行的程度(可以通过接口实现UI进度更新),最后反馈执行的结果给UI主线程。
AsyncTask通过一个阻塞队列BlockingQuery存储待执行的任务,利用静态线程池THREAD_POOL_EXECUTOR提供一定数量的线程,默认128个。在Android 3.0以前,默认采取的是并行任务执行器,3.0以后改成了默认采用串行任务执行器,通过静态串行任务执行器SERIAL_EXECUTOR控制任务串行执行,循环取出任务交给THREAD_POOL_EXECUTOR中的线程执行,执行完一个,再执行下一个。

优缺点
1. 处理单个异步任务简单,可以获取到异步任务的进度
2. 可以通过cancel方法取消还没执行完的AsyncTask
3. 处理多个异步任务代码显得较多
适用范围
1. 单个异步任务的处理

ThreadPoolExecutor:
ThreadPoolExecutor提供了一组线程池,可以管理多个线程并行执行。这样一方面减少了每个并行任务独自建立线程的开销,另一方面可以管理多个并发线程的公共资源,从而提高了多线程的效率。所以ThreadPoolExecutor比较适合一组任务的执行。Executors利用工厂模式对ThreadPoolExecutor进行了封装,使用起来更加方便。

 
  

Executors提供了四种创建ExecutorService的方法,他们的使用场景如下:

1. Executors.newFixedThreadPool()
   创建一个定长的线程池,每提交一个任务就创建一个线程,直到达到池的最大长度,这时线程池会保持长度不再变化
2. Executors.newCachedThreadPool()
   创建一个可缓存的线程池,如果当前线程池的长度超过了处理的需要时,它可以灵活的回收空闲的线程,当需要增加时,
    它可以灵活的添加新的线程,而不会对池的长度作任何限制
3. Executors.newScheduledThreadPool()
   创建一个定长的线程池,而且支持定时的以及周期性的任务执行,类似于Timer
4. Executors.newSingleThreadExecutor()
   创建一个单线程化的executor,它只创建唯一的worker线程来执行任务
适用范围
1. 批处理任务


IntentService:
IntentService继承自Service,是一个经过包装的轻量级的Service,用来接收并处理通过Intent传递的异步请求。客户端通过调用startService(Intent)启动一个IntentService,利用一个work线程依次处理顺序过来的请求,处理完成后自动结束Service。

特点
1. 一个可以处理异步任务的简单Service

线程间通信:

在Android中提供了两种线程间的通信方式:一种是AsyncTask机制(只能用于时间短的操作,最多几秒就应该结束),另一种是Handler机制


4、进程&进程间通信
在Android SDK中提供了4种用于跨进程通讯的方式。这4种方式正好对应于android系统中4种应用程序组件:Activity、Content Provider、Broadcast和Service。其中Activity可以跨进程调用其他应用程序的Activity;Content Provider可以跨进程访问其他应用程序中的数据(以Cursor对象形式返回),当然,也可以对其他应用程序的数据进行增、删、改操作;Broadcast可以向android系统中所有应用程序发送广播,而需要跨进程通讯的应用程序可以监听这些广播;Service和Content Provider类似,也可以访问其他应用程序中的数据,但不同的是,Content Provider返回的是Cursor对象,而Service返回的是Java对象,这种可以跨进程通讯的服务叫AIDL服务。


5、xml解析/json解析
6、Java设计者模式
7、搭框架
8、Http方法
根据HTTP标准,HTTP请求可以使用多种请求方法。
HTTP1.0定义了三种请求方法: GET, POST 和 HEAD方法。
HTTP1.1新增了五种请求方法:OPTIONS, PUT, DELETE, TRACE 和 CONNECT 方法。
方法 描述
GET    求指定的页面信息,并返回实体主体。
HEAD 类似于get请求,只不过返回的响应中没有具体的内容,用于获取报头
POST 向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST请求可能会导致新的资源的建立和/或已有资源的修改。
PUT    从客户端向服务器传送的数据取代指定的文档的内容。
DELETE 请求服务器删除指定的页面。
CONNECT HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。
OPTIONS 允许客户端查看服务器的性能。
TRACE 回显服务器收到的请求,主要用于测试或诊断。
9、http请求和返回格式
10、get方法和post方法差别
Http定义了与服务器交互的不同方法,最基本的方法有4种,分别是GET,POST,PUT,DELETE。URL全称是资源描述符,我们可以这样认为:一个URL地址,它用于描述一个网络上的资源,而HTTP中的GET,POST,PUT,DELETE就对应着对这个资源的查,改,增,删4个操作。到这里,大家应该有个大概的了解了,GET一般用于获取/查询资源信息,而POST一般用于更新资源信息。
11、dalvik进程,Linux进程,线程区别
Dalvik是Google公司自己设计用于Android平台的Java虚拟机,每一个Dalvik 应用作为一个独立的Linux 进程执行。独立的进程可以防止在虚拟机崩溃的时候所有程序都被关闭。
12、安卓动画哪两种以及差别
补间动画和帧动画。所谓补间动画,是指通过指定View的初末状态和变化时间、方式,对View的内容完成一系列的图形变换来实现动画效果。主要包括四种效果:Alpha、Scale、Translate和Rotate。帧动画就是Frame动画,即指定每一帧的内容和停留时间,然后播放动画。
13、网络层协议有哪些,OSI 七层协议
14、xml解析方式有哪些,以及优缺点
15、Android最新布局有哪些
16、Android 界面适配
17、MVC,MVP 模式
18、HashMap 是有序还是无序,有序的map是什么,List基类是什么
HashMap无须,
LinkedHashMap有序,输出时保持数据存入时的顺序
19、http协议,在发送请求的时候出现丢包情况,怎样处理,有没有拦截操作
20、Android加载网络图片的时候怎样防止内存溢出(加载图片的过程)
21、即时通信 (极光推送)


22、自定义 view 需要重写方法或者说 Android layout 展示出来需要走哪些方法
一.自定义View的属性
二.在View的构造方法中获得我们自定义的属性
三.[ 3、重写onMesure ]
四.重写onDraw


23、Android 数据存储有哪些方式
一 使用SharedPreferences存储数据
二 文件存储数据      
三 SQLite数据库存储数据
四 使用ContentProvider存储数据
五 网络存储数据
详情看:
http://www.cnblogs.com/ITtangtang/p/3920916.html#type5

24、如何查询数据库中某字段包含 *** 所有数据


25、如何解决 message 复用问题(handler)
Handler在通过Message.obtain()获取消息时,如果有消息,就复用,没有的话,就new一条新消息


26、如何建立TCP/UDP连接
Java使用DatagramSocket代表UDP协议的Socket,DatagramSocket本身只是码头,不维护状态,不能产生IO流,它的唯一作用就是接收和发送数据报,Java使用DatagramPacket来代表数据报,DatagramSocket接收和发送的数据都是通过DatagramPacket对象完成的。
使用UDP方式android端和服务器端接收可以看出,其实android端和服务器端的发送和接收大庭相径,只要端口号正确了,相互通信就没有问题,TCP使用的是流的方式发送,UDP是以包的形式发送。


27、想要listview 展示不同item样式
一 getViewTypeCount()比较简单,你的item有多少种可能的布局就返回多少;
二 而对于getItemViewType(int position),你就根据你的需求定义多少个常量,简单如下,一个表示收到文本消息,一个表示发出文本消息,然后在方法里面根据你的消息判断是收到的还是发出的,对应return该常数就行了。


28、Fragment 切换以及再展示怎么处理
     FragmentTransaction transaction = fragmentManager.beginTransaction();
     transaction.replace(R.id.content, fg);
     transaction.commit();
 
另外:  
/**
 * 切换Fragment
 *
 * @param fromFragment:需要隐藏的Fragment
 * @param toFragment:需要显示的Fragment
 */
private void switchFragment(Fragment fromFragment, Fragment toFragment) {
    if (fromFragment != toFragment) {
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        if (!toFragment.isAdded()) {
            fragmentTransaction.hide(fromFragment).add(R.id.framelayout_content_activity_home, toFragment).commit();
        } else {
            fragmentTransaction.hide(fromFragment).show(toFragment).commit();
        }
    }
}
29、单例模式怎样防止new
自定义一个private 构造方法


30、service 与 intentservice 区别


31、Android 6.0 与 Android 7.0 有什么不同,对于开发人员有什么需要注意的地方


32、Android 事件分发机制


33、Activity四种启动模式


34、Activity 与 Fragment 之间数据如何传递


35、Java 四种引用模式



你可能感兴趣的:(Android,知识,软件开发,面试)