Android面试总结

面试准备:
1.多线程下载原理;

1.因为要多线程下载,要随机去指定位置,用一个randomAccessFile的流
1.请求服务器, 在本地创建一个大小跟服务器一样的文件
RandomAccessFile raf = new RandomAccessFile()
raf.setLength(length);

2.计算每个线程下载的位置.
blockSize = length / threadCount;
int startIndex = (i - 1) * blockSize;
int endIndex = i * blockSize - 1;       


3.开启线程分别下载服务器上对应部分的资源(使用range字段),把下载下来的资源放在对应

的本地的文章上

conn.setRequestProperty("Range", "bytes=" + startIndex + "-   

+ endIndex);
raf.seek(startIndex);

2.说说你对面向对象的理解:结合项目说


3.设计模式 单例 模板 装饰 观察者 工厂
被观察者继承observable,复写haschange()方法,notifyObserver()
观察者实现observer,回调update()方法;

4.handler机制
 handler使用步骤:
   * 1.looper.preapere(); 只能执行一次

    /**
     * 1.获取looper;  mLooper = Looper.myLooper();
     * 2.获取loooper的messagequeue  mQueue =   

   mLooper.mQueue;
     */

   * 2.创建handler.使用handler
   new handler();

    /**
     * 拿到消息队列的引用    发消息发到消息队列里   

                   并给消息排序
     * enqueueMessage(queue, msg, uptimeMillis);
     *  消息队列中boolean enqueueMessage(Message   

   msg, long when) {
     */

   handler.sendEmptyMessage(0);

   
   * 3.loop.loop();
    /**
     *  1.msg.target.dispatchMessage(msg);
     *  2.handlemessage
     */

 


5.监听机制;
答:1.定义一个借口 2.声明一个setOnXXlistener方法;3.响应接口里的方法;4.调用

setOnXXlistener的方法
  
6.wait sleep区别;
wait所属是对象,sleep是Thread
wait释放锁,释放cpu资源
sleep不释放锁,不释放cpu资源

7.线程与进程的区别;
进程:正在运行中的程序,
线程:一个进程至少有一个线程(主线程),线程是程序的一条执行路径;
如:请求网络比较耗时,放在子线程,避免主线程堵塞;anr异常

11.接口与抽象类的区别;
下面比较一下两者的语法区别:
1.抽象类可以有构造方法,接口中不能有构造方法。
2.抽象类中可以有普通成员变量,接口中没有普通成员变量
3.抽象类中可以包含非抽象的普通方法,接口中的所有方法必须都是抽象的,不能有非抽象

的普通方法。
4. 抽象类中的抽象方法的访问类型可以是public,protected和(默认类型,虽然
eclipse下不报错,但应该也不行),但接口中的抽象方法只能是public类型的,并且默认

即为public abstract类型。
5. 抽象类中可以包含静态方法,接口中不能包含静态方法
6. 抽象类和接口中都可以包含静态成员变量,抽象类中的静态成员变量的访问类型可以任

意,但接口中定义的变量只能是public static final类型,并且默认即为public static

final类型。
7. 一个类可以实现多个接口,但只能继承一个抽象类。
应用:模板设计 父类方法中间的某段代码不确定,留给子类干,就用模板方法设计模式

自己理解:
抽象类主要用于对类中共性的抽取,比如模板设计方法
接口主要是自定义接口


14.activity fragemtn service 生命周期;
activity:oncreate onstart ouresume onpause onstop ondestory
?HOME键的执行顺序:onPause->onSaveInstanceState->onStop->onRestart->onStart-

>onResume
?BACK键的顺序: onPause->onStop->onDestroy->onCreate->onStart->onResume
A--->B :A的生命周期:onpause->onSaveInstanceState->onstop->onrestart->onStart-

>onResume

四种启动模式:standard
singTop:如果启动的activity在当前任务栈栈顶中,就不创建新的activity方法,而是调用原

来实例的onNewIntend();
如:添加浏览器书签

singleTask:只有一个实例,如果要激活的activity在任务栈中,就复用,调用onnewIntent方

法,
因为有些activity创建一次开销比较大,不如浏览器内核打开一个浏览器;browseractiity;

singleInstance:只有一个实例,并且这个实例独立运行在一个task中,这个task只有这个

实例,不允许有别的Activity存在单独开一个任务栈;而且整个手机里只用一个activity实

例存在
如:呼叫界面:

service:
(1)startservice:
oncreate onstartcommand ondestory
(2)bindService:
oncreate onbind onUnbind ondestory
(3)混合生命周期
oncrate onstartcommand onbind onunbind ondestory

fragment:
onattatch oncreate oncreateview onactivitycreate onstart onresume
onpause onstop ondestoryView ondestory ondatach

13:内部类:
外部类可以访问内部类,但需要建立内部类对象
内部类在成员变量位置上,在外部其他类访问内部类非静态方法,且修饰符为默认
Outer.Inner inner = new Outer().new Inner();
inner.function();

如果为static
 new Outer.Inner().functin();

如果访问内部类静态成员
Outer.Inner().function();

匿名内部类是因为方法总要调用,所以把内部类的定义,和调用简写了

12.数据库语句

13.集合和流的理解
8.自定义控件
 /*
  * view 对象显示的屏幕上,有几个重要步骤:
  * 1、构造方法 创建 对象。
  * 2、测量view的大小。 onMeasure(int,int);(空间渲染的过程必须测量)
  * 3、确定view的位置 ,view自身有一些建议权,决定权在 父view手中。   

onLayout();
  * 4、绘制 view 的内容 。 onDraw(Canvas)
  */
 
9.事件分发

viewgroup事件分发与消费:
首先自上而下分发,如果不消费,就往上传,看dispatcheventtouch方法的返回值结果,
如果是false,继续往上返回,

view的事件消费 :
imageView事件处理为例:

 if (mOnTouchListener != null && (mViewFlags & ENABLED_MASK) == ENABLED &&
                mOnTouchListener.onTouch(this, event)) {
            return true;
        }
        return onTouchEvent(event);

setOntouchvent中ontouch返回为true,所有事件都消费,
如果为false,只响应action_down;

//点击事件的调用方式,就是回调方法
 performClick();

 public boolean performClick() {
        ....
        if (mOnClickListener != null) {
            ...
   //回调onclick方法
            mOnClickListener.onClick(this);
           ...
        }
        ...
    }


点击事件和touch事件冲突解决:
ontouch返回true,onclick不会响应;
ontouch返回发了,onclick才会响应;

9.listview的优化
1.条目复用;避免内容溢出
2.保存孩子节点的id
避免多次遍历寻找孩子,提高效率,利用viewhodler
3.复杂条目的写法
复写两个方法
getViewTypeCount();
getItemViewType();

10.三级缓存
1.先从内存中取,没有再从文件中去,没有,从网络中取,
利用线程池,获取一个线程请求网络,并写入内存和文件中
再次进入时,就可以从内存中去,没有再从文件中取,
public ImageCacheUtil(Context context,Handler handler) {
  int maxSize = (int) (Runtime.getRuntime().maxMemory()/8);
  lruCache = new LruCache<String,Bitmap>(maxSize){
   @Override
   protected int sizeOf(String key, Bitmap value) {
    //getRowBytes()一行上面对应像素点占用的大小

*value.getHeight()行号
    return value.getRowBytes()*value.getHeight();
   }
  };
  cacheDir = context.getCacheDir();
  //2*cup核数+1
  newFixedThreadPool = Executors.newFixedThreadPool(5);
  this.handler = handler;
 }
 public Bitmap getBitmap(String imgUrl,int position){
  //position为确认给那个imageview控件使用的tag
  Bitmap bitmap = null;
  //1,内存中去取
  bitmap = lruCache.get(imgUrl);
  if(bitmap!=null){
   Log.i(tag, "从内存中获取到的图片");
   return bitmap;
  }
  //2,文件中去取
  bitmap = getBitmapFromLocal(imgUrl);
  if(bitmap!=null){
   Log.i(tag, "从文件中获取到的图片");
   return bitmap;
  }
  //3,网络去下载
  getBitmapFromNet(imgUrl,position);
  Log.i(tag, "网络获取到的图片.......");
  return null;
 }
 
 class RunnableTask implements Runnable{
  private String imageUrl;
  private int position;
  
  public RunnableTask(String imageUrl,int position) {
   this.imageUrl = imageUrl;
   this.position = position;
  }
  @Override
  public void run() {
   //访问网络,下载图片
   try {
    URL url = new URL(imageUrl);
    HttpURLConnection connection = 

(HttpURLConnection) url.openConnection();
    //读取超时时间()
    connection.setReadTimeout(5000);
    //链接超时时间()
    connection.setConnectTimeout(5000);
    connection.setRequestMethod("GET");
    InputStream inputStream =

connection.getInputStream();
    Bitmap bitmap = BitmapFactory.decodeStream

(inputStream);
    
    //消息机制()
    Message msg = new Message();
    msg.what = SUCCESS;
    msg.obj = bitmap;
    msg.arg1 = position;
    handler.sendMessage(msg);
    
    //内存缓存
    lruCache.put(imageUrl, bitmap);
    //写入文件
    writeToLocal(imageUrl, bitmap);
    
    return ;
   } catch (Exception e) {
    e.printStackTrace();
   }
   
   Message msg = new Message();
   msg.what = FAIL;
   handler.sendMessage(msg);
  }
 }
 
 private void writeToLocal(String imageUrl, Bitmap bitmap) {
  String fileName;
  try {
   fileName = MD5Encoder.encode(imageUrl).substring(10);
   File file = new File(cacheDir,fileName);
   FileOutputStream fileOutputStream = new

FileOutputStream(file.getAbsolutePath());
   //1,定义一个大小如果超过当前大小的时候,就需要进行等比例

压缩
   bitmap.compress(CompressFormat.JPEG, 100,

fileOutputStream);
  } catch (Exception e) {
   e.printStackTrace();
  }
 }
 
 private void getBitmapFromNet(String url,int position) {
  newFixedThreadPool.execute(new RunnableTask(url,position));
 }
 
 private Bitmap getBitmapFromLocal(String imgUrl) {
  String fileName;
  try {
   fileName = MD5Encoder.encode(imgUrl).substring(10);
   File file = new File(cacheDir,fileName);
   Bitmap bitmap = BitmapFactory.decodeFile

(file.getAbsolutePath());
   //加入到内存中去(内存的效率要高)
   lruCache.put(imgUrl, bitmap);
   return bitmap;
  } catch (Exception e) {
   e.printStackTrace();
  }
  return null;
 }
}


图片错乱问题:
1.复用产生的问题:
  解决:holder.imageview.settag(position);
  if(bitmap!=null&&(Integer)holder.image.getTag()==position){
   holder.image.setImageBitmap(bitmap);
  }


11.介绍Android中的动画
1.view animation(平移,旋转等),drawable animation(帧动画),property animation(插值

器的使用,加入一些算法)


12.反射的原理:就是把Java类中的各种成分映射成相应的java类,(对类的解剖);
要想对一个类进行内容的获取,必须要先获得该字节码文件的对象
该对象类型是Class类型
Class class{
 Filed filed;//字段
 Method method;//构造函数
 Contructor constructor;//构造函数
 按照面向对象将字段,方法,构造器都封装成了对象;
}

13.java中内存的分析:(面试时画个图解释更好)
1.寄存器,cpu涉及的区域
2.本地方法区,是和系统相关的代码存储区域
3.栈内存 存储局部变量,变量运算区域一结束,就释放
4.堆内存 存储的是数组和对象,简单说,堆内存存储的都是实体(能存储很多数据的地方就是

实体)
 new出来的都存放在堆内存
5.方法区 存储函数的地方(或者说存储共享数据的地方)

14:imageLoader的理解以及它和其他的类似的图片加载有什么不同?
1.里面的防止内存溢出的算法,如果超过limit,就遍历吧集合中的图片删掉,
还有lruCache用的是linkedHashedmap集合,去remove,get;
2.如果图片很大,超过limit时,就压缩,用一个永真循环,去动态改变压缩比例的因子;

15.gallery用过吗:
和listview类似,使用适配器,填充图片即可;

16.adapter作用和常用的那些adapter;
作用:为容器提供子视图,利用视图的数据和view来构建每个子视图。
arrayAdapter  ,simpleCursorAdapter, cursorAdapter  resourceCursorAdapter  

16.intent,service,activity的区别
1.Intent: Intent的调用是用来进行UI之间的切换的,封装了动作和动作对应的数据;
2.Service:服务,具有一段较长生命周期且没有用户界面的程序。Service在后台运行,不

可交互,不能自己运行,需要通过Activity或者其他Context对象来调用,有

Context.startService()和Context.bindService()两种方式启动. Service的生命周期:

onCreate、onStart、onDestroy
3.activity:是最基本的android应用程序组件,主要是生命周期的把握,其次就是状态的保

存和恢复(onSaveInstanceState onRestoreInstanceState),以及Activity之间的跳转和

数据传输(intent)。
context:应用程序所有功能可以通过他访问;

17.垃圾回收机制:

18. Android dvm的进程和Linux的进程, 应用程序的进程是否为同一个概念?
DVM指dalivk的虚拟机。每一个Android应用程序都在它自己的进程中运行,都拥有一个独立

的Dalvik虚拟机实例。而每一个DVM都是在Linux 中的一个进程,所以说可以认为是同一个

概念。

19、说说mvc模式的原理,它在android中的运用
MVC(Model_view_contraller)”模型_视图_控制器”。 MVC应用程序总是由这三个部分组成

。Event(事件)导致Controller改变Model或View,或者同时改变两者。只要 Controller改

变了Models的数据或者属性,所有依赖的View都会自动更新。类似的,只要Controller改变

了View,View会 从潜在的Model中获取数据来刷新自己。

20.2. GC内存泄露?
出现情况:?
1.数据库的cursor没有关闭?
2.构造adapter时,没有使用缓存contentview?
?? 衍生listview的优化问题-----减少创建view的对象,充分使用contentview,可以使用一

静态类来优化处理getview的过程/?
3.Bitmap对象不使用时采用recycle()释放内存?
4.activity中的对象的生命周期大于activity?

不要保留对Context-Activity长时间的引用(对Activity的引用的时候,必须确保拥有和

Activity一样的生命周期)
 
   尝试使用Context-Application来替代Context-Activity
 
   如果你不想控制内部类的生命周期,应避免在Activity中使用非静态的内部类,而应该

使用静态的内部类,并在其中创建一个对Activity的弱引用。这种情况的解决办法是使用一

个静态的内部类,其中拥有对外部类的WeakReference,如同ViewRoot和它的Winner类那样
 
另外:内存泄露与内存溢出的区别:
内存溢出:指的是申请的内存不够,
内存泄露:指的是申请内存后,对某些资源没有及时释放,很多内存泄露,最终会导致内存溢出

;


21.IPC及原理
Linux系统中进程间通信的方式有:socket, named pipe,message queque, signal,share 

memory。Java系统中的进程间通信方式有socket, named  pipe等
IBinder接口
 
IBinder接口是对跨进程的对象的抽象。普通对象在当前进程可以访问,如果希望对象能被

其它进程访问,那就必须实现IBinder接口。IBinder接口可以指向本地对象,也可以指向远

程对象,调用者不需要关心指向的对象是本地的还是远程。

22.get和post区别:
1.get提交,提交的信息显示在地址栏
  post提交,提交的信息不显示在地址栏
2.get提交,对于敏感的数据不安全
  post提交,对于敏感的数据安全
3.get提交,对于大数据不行,因为地址栏存储体积有限
 post提交,可以提交大体积数据
4.get提交,将信息封装到请求消息的请求行中
 post提交,将信息封装到请求体中;
5.服务端区别
出现乱码,先用iso8859编码,在指定中文码表解码,对get和post都有用,但是
但对于post提交的中文,还有一种解决方法,
request.setcharacterencoding(),这种方法只对请求体中的数据有用;

23.状态选择器:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true"
          android:drawable="@drawable/bind_sim_bg_pressed" /> <!-- pressed -->
    <item android:state_focused="true"
          android:drawable="@drawable/bind_sim_bg_pressed" /> <!-- focused -->

    <item android:drawable="@drawable/bind_sim_bg" /> <!-- default -->
</selector>

24.自定义属性:
1.添加自定义的属性.
2.声明命名空间
3. 声明自定义的属性  自定义样式 values下新建attrs.xml文件
4.TypedArray ta = context.obtainStyledAttributes(attrs,

R.styleable.MySettingView);

25:Android保存数据的方法有5种,
sharedperference存储,File文件存储,sqlite数据库存储,contentprovider存储,网络存储,

26.activity之间传递数据的方法有哪些?
1.Intent对象
传输数据仅限简单数据和实现序列话的对象。
2.静态变量
将需要共享的对象或者数据声明为静态,可以传递任何类型的数据
3.剪切板
可以利用Android自带的剪切板功能传送数据

传递数据
 
Intent intent=new Intent(this,MainActivity.class);

ClipboardManager cliper=(ClipboardManager)getSystemServer

(Context.CLIPBOARD_SERVER);

cliper.setText("message");
startActivity(intent);
 
接收数据
 
ClipboardManager cliper=(ClipboardManager)getSystemServer

(Context.CLIPBOARD_SERVER);
String str=cliper.getText().toString();

4.全局对象
 
    为每个应用程序定义一个全局的对象,该对象创建由系统负责,使用全局对象需要继承

android.app.Application类,可以在该类中定义任何方法。
 package com.example.transmitdata;

import android.app.Application;

public class mAPP extends Application(){

public String str;

public Data data;

}
然后需要在AndroidManifest.xml文件中定义该类
 <?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android ="http://schemas.andoid.com/apk/res/android"

        package="com.example.transmitdata"

         <application android:name=".mAPP "

                 ......
           />
/>
 
可以在程序任意位置获取mAPP对象。
 
mAPP mapp=(mAPP)getApplicationContext();

面试官问:activity之间传递一个大的图片怎么传:
只能是用文件把图片存储,再在另一个activity中在获取;
5 基于Ipc的通信机制
 
context与service之间的传输,如Activity与Service之间的通信
6.基于外部存储的传输 ,File/Preference/Sqlite,如果要针对第三方应用需要Content

provider



1.简要描述对Static关键字的理解;
Static静态的,随着类的加载而加载,生命周期为进程的生命周期;
同一个类中的static变量在内存中只会有一份,不同对象共享,
static方法相对普通方法调用速度更快,一般工具类的方法都是static
static的调用可以直接用类调用,而不必创建对象;

2.简要描述java中内存回收机制(gc)的理解;
gc的调用:在内存紧张时,系统会调用gc释放内存并且2.3版本以上gc是异步调用的,也可以手动gc,
gc的原理:系统中有一个GcRoot,gc的时候系统会遍历凡是gcroot可以引用到的均不会被回收,gcroot引用
不到的会被回收,根据这个原理,内存泄漏便是由于长生命周期的对象引用段声明周期的对象导致
短生命周期的无法被回收.

3.java中线程同步的几种方式;
同步方法,与同步锁
同步方法用于在方法上,同步锁要一个对象
线程安全问题:多个线程同事访问一个对象导致数据错乱;

4.请描述Activity的声明周期;
oncreate ,onstart,onresume,onpause,onstop,ondestory,
一般可以在onause或者onstart中做数据刷新的工作;

5.handler机制的原理;
主要是hander thread,looper,message之间的关系;
messagequeue为消息的存储单元,内部为单链表,用于消息的存储.
looper为消费的执行单元,looper.loop()方法中无限循环取出消息执行消息,
handler为消息的发送单元.
looper.prepare和looper.loop()在哪个线程中最终就在哪个线程中调用handler.handlermessage()方法,
handler拿到哪个线程的looper就会拿到对应线程的messagequeue,然后往相应的messagequeue发送消息,
looper.loop()在哪个线程最终hanldermessage就在哪个线程执行,如handlerthread就是子线程中执行.

6.简要描述android中view的绘制机制
onmeasure测量:根据父view传递过来的measurespec和子view的layoutparams形成自己的测量规则测量出自己的大小.
viewgroup会通过measurechild方法一步步从上到下测量出子view的大小.,然后测量出自己的大小,在setmeasuredemension()中设置自身大小;
onlayout布局:setFrame()设置自己的四个顶点坐标,然后调用onlayout测量,设置子view的四个顶点坐标一步步从上到下布局完成;
draw规则:先绘制背景,然后在ondraw中绘制内容,在dispatchDraw中绘制子view最后绘制装饰,dispatchdraw()中完成从上到下的遍历绘制.

7.简要描述androdi中事件分发机制:
从activity,windwo,view
view先判断ontouchlistener是否是null,用ontouch再判断view是否enable如果false则再调用ontouchevent()如果可点击或可长点击则消耗事件.
viewgroup会从最后一个子view开始遍历判断点击坐标是否落在子view区域内和子view是否在做动画如果满足条件调用子view的dispatchtouchevent()
分发成功就把子view设置为target,以后down事件之后的传递都给这个子view,不然调用viewgroup的ontouchenevent()


8.请说出android进程间传递数据的几种方式
intent,bundle,binder,content privder,广播,messager,文件,网络,

9.android dvn的进程和linux进程,应用程序进程是否为同一个概念?
是同一个概念,android启动一个进程就会从母进程中fork一个进程,这个fork的进程就是dvm进程就是linux进程.


10.android中一张40x40像素的图片加载后所占用多大的内存;
如果图片是argb8888的4x40x40=6400字节,和每个像素占用的字节数有关;

 

 


 


  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值