android网络编程面试题,Android面试题整理.pdf
android网络编程面试题An droid面试题整理Android方 面:3、内存优化(内存泄漏、内存溢出),如何查找内存泄漏,如何优化内存泄露:是指程序在申请内存后,无法释放本应该被回收的内存。内存泄露的堆积就会导致内存溢出。内存溢出:是指程序在申请内存时,没有足够的内存空间供其使用。查找内存泄露:1、使用A S自带的内存分析界面.可以查看内存使用情况(蓝色区域表示程序使用的内存,灰色区域表示空闲内存)内存泄露的原因以及解决方法:1、静态的上下文,比如static Context context,应该尽量避免静态上下文的使用;2、未取消注册或者监听,比如BrocastReceiver和EvenlBus需要在Activity的on Destroy中取消注册;3、资源没有关闭或者释放,比如1 0、File流或者Cursor在操作完成后没有及时关闭;4、耗时任务或者属性动画没有取消,比如属性动画需要在Activity的onDestroy中取消;5、TVebVie时造成内存泄露,醍1)42川也需要在人。1 1疝丫的01 1。?5 a 0丫中调用它的destroy0方法4、Activity启动模式及区别有以下四种启动模式:standard、single To singleTask x singl elnstanceo1、standard标准模式也是系统默认模式。在该模式下,每次启动一个Activity都会创建一个新的实例,不管这个实例是否已经存在。并且谁启动了这个Activity,那么这个Activity就运行在启动它的那个Activity所在的栈中。比如One Activity启动了T wo Activity(T wo A ctivily是标准模式),贝ljT w o Activily就会进入到 Ona Activity所在的栈中。2、singleTop栈顶模式具体分为以下两种情况:2.1、如果被启动的Activity已经存在且位于栈顶,那么该Activity就不会重建,而是调用其one wintent 0方法重用该实例。2.2、如果被启动的Activity已经存在但不是位于栈顶,那么就会重新创建该Activity的实例。3、singleTask栈内模式具体分为以下三种情况:3.1、如果被启动的Activity所需的任务栈不存在,就会先创建该Activity所需的任务栈,然后再创建该Activity的实例并将它加入到任务栈中。3.2、如果被启动的Activity所需的任务栈存在且该任务栈中不存在该Activity的实例,就会创建该Activity的实例并将它加入到任务栈中。3.3、如果被启动的Activity所需的任务栈存在且该任务栈中存在该Activity的实例。则有以下两种情况:3.3.1、如果该Aclivily位于任务栈的栈顶,则该Activity不会重建,系统会调用其on Ne wlnlentO方法重用该实例;3.3.2、如果该Activity不是位于任务栈的栈顶,那么该Activity不会重建,系统会调用其on ewInlentO方法重用该实例并且清除任务栈中该Activity之上所有的Aclivily实例。4、singlelnslance单例模式该模式具备singleTask所有特性。具体分为以下两种情况:4.1、如果被启动的Activity不存在,系统先会创建一个全新的任务栈,然后再创建该Activity实例并将它加入到新的任务栈栈顶。4.2、如果被启动的Activity已经存在,那么无论它位于哪个应用程序,哪个任务栈,系统都会把该Activity所在的任务栈切换前台,从而使该Activity显示出来。注 意:采用singlelnstance加载模式的Activity总是位于任务栈栈顶,并且该任务栈中只包含该Activity实例。1、提高进程的优先级2、利用广播拉活Activity6、Activity启动过程7、动画1、Android的动画可以分为三种:View动画、帧动画、属性动画。8、U 1(同一张图片放在不同dpi中,加载内存的大小有何不同)9、Handler的原理,手写两个子线程Handler通信,loop wait时如何唤醒的Handler原 理:Handl er主要是由Loo per和Message Qu ene构建消息的处理。Loo per负责循环从MessageQuene中读取消息,如果有就交给Handler处理,如果没有就一直等待。MessageQuene负责消息的插入和读取,里面维护了一个单向链表,根据消息的执行时间排列(即最先被执行的在链表前面)。两个子线程Handl er通信public Handler mHandler;new Thread(new RunnableO)0 verridepublic void run()Looper.prepareO;m H andler=new HandlerO 0 verridepublic void handleM essage(Message msg)super,handle Message(msg);Log.e(gybguohao7msg.obj=+msg.obj);)Looper.loopO;).start 0;new Thread(new RunnableO)0 verridepu blic void run()M e ssage msg=m H andler obtain Message();msg.obj=这是从第二个子线程过来的消息”;m Handler.send Me ssage(msg);).start 0;1 0、Context类1 1、热更新1 2、WebView优 化,及 H5的js调用Web View的优化:1、第一次打开WebView时间过长,可以在合适的时候创建一个全局的Web View供所有页面使用;2、设置Web View的文件缓存,加快加载速度。H 5 的js调 用:1、首先设置允许与JS交互 web Settings.setJavaScriptEnab led(true);2、添力口交互接口 m W e b View.addjavascriptlnlerface(new JsCo m m u nicate 0,App);3、在JsCo m m u nicate类中通过注解Javascripllnterface定义具体的交互方法;4、js端通过window.App.方法名()调用对应的方法。1 3、性能优化1、应用启动速度优化,避免在自定义Application类中做过多耗时的操作;2、减少布局多层嵌套,避免G PL.过度绘制,使用merge减少布局嵌套;3、尽量减少APK的大小,删除无用代码和资源,重复布局尽量采用include;4、内存优化,及时释放内存,避免内存泄露;5、避免无用的网络请求,给用户造成流量的浪费。1 4、Bi nd er 机制Android Binder是用来做进程通信的,An droid的各个应用以及系统服务都运行在独立的进程中,它们的通信都依赖于 Binder。1 5、65536是怎么回事?如何解决表示方法数超过了 65536个解决方法:1、在项目的build gradle文件下defaultConfig闭包中配置 m ultiDexEnabled true2、在dependencies下添力口依赖ilple m entation co m.android,support:multidex:1.0.03、在自定义的 A p plicalion 类中重写attach Base Co nlexl方法,并且执行 Multi Dex.install(this)代码。0 verridepu blic void attachBase Co nt ext(Context base)super,cittachBaseCon text(base);M u 1 ti Dex.install(this);)1 6、LruCache原理LruCache的全称是Least Recently U sed,也就是最近最少使用算法。1 7、断点续传1 8、主线程Lopper为什么不会ANR因为Android是由事件驱动的,looper.loopO不断地接收事件、处理事件,每一个点击触摸或者说Activity的生命周期都是运行在Looper.loopO的控制之下,如果Looper停止了,应用也就停止了。只能是某一个消息或者说对消息的处理阻塞了 Looper.loopO,而不是Looper.loop 0 阻塞它。1 9、AIDLJava方 面:1、线程安全、多线程通信、同步方式线程安全:在多线程环境下对共享资源的访问,保证此共享资源的一致性。线程安全问题多是由全局变量和静态变量引起的,当多个线程对共享数据只执行读操作,不执行写操作时,一般是线程安全的;当多个线程都执行写操作时,需要考虑线程同步来解决线程安全问题。多线程通信:1、全局变量2、Handler3、AsyncTask4、Event Bus同步方式:1、使用synchronized关键字(同步方法和同步代码块)2、线程池的原理3、进程间通信方式1、Binder2、Intent3、ContentProvider4、AIDL4、进程和线程区别一个程序至少一个进程,一个进程至少一个线程。进程是系统进行资源分配和调度的最小单位,比如分配内存。线程是程序执行的最小单位,可以与同属一个进程的其他的线程共享该进程所拥有的全部资源。5、sleep和wait区别1、sleep是Thread类的方法,wait是object类的方法;2、sleep方法没有释放锁所以不能调用里面的同步方法。而wait方法释放了锁,使得其他线程可以调用里面的同步方法。4、sleep必须捕获异常,而wait不需要捕获异常6、堆和栈的区别1、堆中存储的是对象2、栈中存储的是局部变量final可以修饰类、方法、变量(包括成员变量和局部变量)1、final修饰类,表示这个类不能被继承,并且该类中所有的成员方法会被隐式的指定为final方 法;2、final修饰方法,该方法在子类中不能重写,只能继承;3、final修饰变量.如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改;如果是引用类型的变量,则在对其初始化之后便不能再让其指向另一个对象8、简单描述封装、继承、多态1、封 装:将事物的属性和实现细节隐藏起来,只对外提供访问和修改接口(例如set和get方法);2、继 承:当多个类具有相同的属性和方法时,可以将相同部分抽取出来放到一个类中作为父类,其他的类继承这个父类。3、多 态:方法的重写和重载是Java多态性的不同表现。重写是父类与子类之间多态性的一种表现,重载是一个类中多态性的一种表现。9、=和641 1 2房的区别1、对于基本数据类型比较的是它们的值是否相等;2、对于对象比较的是它们是否是同一个对象(即内存地址是否相同);equals:1、equals比较的是值是否相等1 0、java基本数据类型和区别基本数据类型:1、byte:Java中最小的数据类型,1个字节,取值范围T 2 8 1 2 7,默认值02、short:短整型,2个字节,取值范围-3276832767,默认值03、int:整型,4个字节,取值范围-21 474836482 1 47483647,默认值04、l o n g:长整型,在内存中占64位,即8个字节-263263-1,默认值0L5、float:浮点型,4个字节,与double的区别在于float类型有效小数点只有67位,默认值06、double:双精度浮点型,8个字节,默认值07、c h a r:字符型,2个字节,取值范围0 6 5 5 3 5,默认值为空8、boolean:布尔类型,占1个字节,用于判断真或假,默认值false引用数据类型:1、类、接口类型、数组类型、枚举类型、注解类型。区 别:1、基本数据类型在被创建时,在栈上给其划分一块内存,将数值直接存储在栈上。2、引用数据类型在被创建时,首先要在栈上给其引用分配一块内存,而具体对象存储在堆内存上,然后由栈上面的引用指向堆中对象的地址。1 1、如何实现一个死锁1 2、synchronized的实现原理Java内存模型三大性质:可见性、原子性和有序性。1、可见性:是指线程之间的可见性,一个线程修改的状态对另一个线程是可见的,volatile修饰的变量不允许线程内部缓存和重排序,即直接修改内存,所以对其他线程是可见的。但是这里需要注意一个问题,volatile只能让被它修饰内容具有可见性,但不能保证它具有原子性。2、原子性:原子是世界上的最小单位,具有不可分割性。3、有序性:J a v a语言提供了 volatile和synchronized两个关键字来保证线程之间操作的有序性,volatile是因为其本身包含“禁止指令重排序”的语义,synchronized是 由“一个变量在同一个时刻只允许一条线程对其进行lock操作”这条规则获得的,此规则决定了持有同一个对象锁的两个同步块只能串行执行。volatile变量用来确保将变量的更新操作通知到其他线程。当把变量声明为volatile类型后,编译器与运行时都会注意到这个变量是共享的,因此不会将该变量上的操作与其他内存操作一起重排序。volatile变量不会被缓存在寄存器或者对其他处理器不可见的地方,因此在读取volatile类型的变量时总会返回最新写入的值。在访问volatile变量时不会执行加锁操作,因此也就不会使执行线程阻塞,因此volatile变量是一种比sychronized关键字更轻量级的同步机制,声明变量是volatile的,J V M保证了每次读变量都从内存中读,跳 过CPU c a c h e这一步。1 4、子类重写父类方法,返回值和参数有什么要求1、方法名和参数类型及个数都不可以修改2、可以讲方法的权限修饰符改为更宽松的,比如父类中的方法是protected的,则子类中的方法可以是public的3、当返回值为类类型时,重写的方法可以修改返回值类型,但必须是父类方法返回值的子类;要么就不修改,与父类返回值类型相同框架搭建:1、M V C和M V P的区别1、MVC中无法区分Activity到底是V还是C,因为它即承担了界面的显示,又负责一部分逻辑的处理;2、MVP中V和“不存在直接联系,而是通过P来交互。P和V以及P和”之间通过接口来交互,从而降低了代码的耦合度。2、手写MVP框架(用户登录)pu blic class LoginActivity extends AppCo m pat Activity imple ments LoginView private Loginpresenter mLoginPresenter;0 verrideprotected void onCreate(Bundle savedlnstanceState)super,onCreate(savedinstcinceState);setContentView(R.layout.activity_main);m LoginPresenter=new Login Pre sent er(this);请求登录m L oginPresenter.bginC 188xxxx61 1 0”,“1234 5 6);)0 verridepublic void loginSuccess(Login Model model)0 verridepublic void loginFailGnt code,int msg)public interface LoginViewO(void loginSuccess(Login Model model);void loginFailGnt code,int msg);)public class LoginPresenter(public LoginView m View;pu blic Login Pres ent er(Login View view)this mView=view;pu blic void login(String phone,String pass word)N et Client.getlnstance().login(ne w Base Callback()0 verridepu blic void onSuccess(Login M o d el m o d e l)(m View.loginSuccess(model);)Overridepublic void onFailfint code,int tnsg)(m View.loginSuccess(code,msg);)3,MVVM框架人(1 4(的乂丫),!4框架主要是通过口 121出1 这个库实现设计模式:1、用到的设计模式都有哪些常用的设计模式有:单例模式、Builder、工厂模式、策略模式、观察者模式、等等2、实现单例模式都有哪几种方式有以下几种方法:饿汉、懒汉、Double checked lo c k in g,静态内部类饿汉模式pu blic class Singleton private static final Singleton mlnstance=new SingletonO;private Singleton0(public static Singleton getlnstanceO return mlnstacen;)懒汉模式public class Singleton private static Singleton mlnstance;private Singleton0(public static synchronized Singleton getlnstanceO(if(mlnstance=null)(m lnstance=new SingletonO;)return mlnstacen;)3、手写单例模式双重加锁pu blic class Singleton(private volatile static Singleton mlnstance=null;private SingletonO()public static Singleton getlnsatnceO(if(mlnstance 二二 null)synchronized(Singleton,class)if(mlnstance 二二 null)mlnstance=new SingletonO;)return mlnstance;)静态内部类public class Singleton(private SingletonO)public static Singleton getlnsatnceO(return Singleton Holder,mlnstance;)private static class Singleton Holder(private static final Singleton mlnstance=new SingletonO;)4、装饰模式三方框架:1、用到的三方框架都有哪些1、Butterknife2、EventBus3、R etrofit4、Ok Http5、Glide2、O kH ttp的原理3、P icasso缓存机制算法方面:1、冒泡排序当1=。时,进行第一次内部比较假设无序数组为6,1,2,7,9,3,4,5,10,81、第一次循环后的结果是 1,6,2,79,3 4,5,10,82、第二次循环后的结果是 1,2,6,79,3 4,5,10,83、第三次循环后的结果是 1,2,6,79,3 4,5,10,84、第四次循环后的结果是 1,2,6,79,3 4,5,10,85、第五次循环后的结果是 1,2,6,73,9,4,5,10,86、第六次循环后的结果是 1,2,6,73,4,9,5,10,87、第七次循环后的结果是 1,2,6,73,4,5 9,10,88、第八次循环后的结果是 1,2,6,73,4,5 9,10,89、第九次循环后的结果是 1,2,6,73,4,5 9,8,10当i=1时,进行第一次内部比较int numb er 口 二 new int106,1,2,7,9,3,4,5,10,8):int temp=0;for(int i=0;i num b er.lengt h-1;i+)for(int j=0;j num b erU +1)temp=nu mberlj;numb erj=nu m b erj+1;nu m berj+1=tern p;)3、两个栈实现一个队列思 路:因为队列是先进先出,而栈是先进后出Stack stack 1 =new StackO;Stack stack2=new S t a c k O;/入列public void push(int n o d e)(stack 1.p u s h(n o d e);)/出列public int pop 0 if(stack2.sizeO 0)st ack 2.push(stackl.popO);)return stack2.pop();)4、斐波那契数列斐波那契数列通项公式:f(l)=1;f(2)=1;f(n)=f(n-1)+f(n-2)(n=3)public int Fibonacci G nt n)if(n=0)return 0;)if(n=1 I n=2)return 1;)/f(n)int a=0;/f(n-1)int b=1;/f(n-2)int c=1;for(int i=3;i StringBuffer String。2、线程安全。SlringBuilder是线程不安全的,而StringBuffer是线程安全的。因为StringBulfer中很多方法带有synchronized关键字,可以保证是线程安全的。所以在多线程情况下建议使用StringBuffer,确保线程安全,但是在单线程的情况下,建议使用StringB uilder,因为执行速度更快。3、Hash Maps HaseSel、HashTables Concurrent HashM ap s LinkHash Map的区另ij1、Hase Map储存是无序不重复的,允许key和value为null位 口 果key为n u ll,则会在代码里面将null保存为0),是线程不安全的。2、HashSel内部其实是用的Hash Map作为数据的保存,储存的只是map的key,默认value为null0斤以HashSel也是无序不重复的,也允许key为null的,也是线程不安全的)3、HashTable储存无序不重复的,不允许key和value为n u ll,通过synchronized关键字保证线程安全4、ConcnrentHash Map储存无序不重复的,不允许key和value为n u ll,通过volatile关键字保证线程安全5、LinkHash Map继承至Hash M a p,通过一个双向链表保存了元素的储存顺序(所以LinkHash Map也允许key为null的,也是线程不安全的)。Kotlin方面:1、const和val的区别const只能修饰v a l,不能修饰var。const val的可见性是public final static,可以直接方法;va的可见性是private final sta tic,并且val会生成getor malObject0,通过方法调用。2、kotlin闭包3、run.apply、let、also、with的用法和区别Linux方面:1、修改权限的命令ch mod 777r表示re a d,读取权限,代表数字4v表示w rite,写入权限,代表数字2x表示ex ecu te,执行权限,代表数字1