面试中各个阶段会遇到不同的问题 1-3 年工作经验的问题还不是很深入,但是也要有所准备。
下面就说一下我面试的时候遇到的问题:
1.内存泄漏的场景,和解决方案
我一般是回答的比较简单,通常遇到的内存泄漏时 比如说 一个资源已经释放 但是还有另一个资源在使用它 ,这样就容易造成内存泄漏。
例如:
从A 界面跳入B界面 在B界面创建了一个对象但是这个对象用到了A界面的Content ,如果A界面释放,这样就容易造成内存泄漏。 解决方案就是 使用全局的Content ApplicationContent。
其他的内存泄漏 一般使用弱引用 也可以避免。
2.设计模式 熟悉那些设计模式 及其优缺点
单例模式
确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。
这样做有以下几个优点
对于那些比较耗内存的类,只实例化一次可以大大提高性能,尤其是在移动开发中。
保持程序运行的时候该中始终只有一个实例存在内存中
同时可能还会被问到 单例有哪几种实现方式 有什么区别?
懒汉式 和 饿汉式
1、饿汉式是线程安全的,在类创建的同时就已经创建好一个静态的对象供系统使用,以后不在改变。懒汉式如果在创建实例对象时不加上synchronized则会导致对对象的访问不是线程安全的。
2、从实现方式来讲他们最大的区别就是懒汉式是延时加载,他是在需要的时候才创建对象,而饿汉式在虚拟机启动的时候就会创建,饿汉式无需关注多线程问题、写法简单明了、能用则用。但是它是加载类时创建实例,所以如果是一个工厂模式、缓存了很多实例、那么就得考虑效率问题,因为这个类一加载则把所有实例不管用不用一块创建。
单例的使用步骤:
1.必须防止外部可以调用构造函数进行实例化,因此构造函数必须私有化。
2.必须定义一个静态函数获得该单例
3.使用synchronized 进行同步处理,并且双重判断是否为null,我们看到synchronized (Singleton.class)里面又进行了是否为null的判断,这是因为一个线程进入了该代码,如果另一个线程在等待,这时候前一个线程创建了一个实例出来完毕后,另一个线程获得锁进入该同步代码,实例已经存在,没必要再次创建,因此这个判断是否是null还是必须的。
3.Activity 生命周期的相关问题
例如A界面 跳转 B界面 再返回A 生命周期是如何走的?
首先 A界面的OnCreate()→OnStart()→OnResume()→OnPause()→B界面的OnCreate()→OnStart()→OnResume()→A界面的OnStop()→(点击返回)B界面的onPause()→A界面的OnRestart()→OnStart()→OnResume()→B界面的OnStop()→OnDestroy()
Fragment的生命周期有:
onAttach(); onCreat(); onCreateView(); onViewCreated(); onActivityCreated(); onStart(); onResume(); onPause(); onStop(); onDestroyView(); onDestroy(); onDetach();
当屏幕暗的时候 onPause(); onStop();
当销毁的时候
onPause(); onStop(); onDestroyView(); onDestroy(); onDetach();
4.service 启动模式 有何区别
1、startService
启动的服务:主要用于启动一个服务执行后台任务,不进行通信。停止服务使用stopService;
如果开启服务的调用者销毁 则服务一直在后台运行,直至调用stopService。
2、bindService
启动的服务:该方法启动的服务可以进行通信。停止服务使用unbindService;
如果服务的调用者销毁,则服务终止运行,或者调用unbindService;
Service 生命周期:
采用start的方式开启服务 使用这种start方式启动的Service的生命周期如下:
onCreate()--->onStartCommand()(onStart()方法已过时) --->onDestory()
说明:如果服务已经开启,不会重复的执行onCreate(), 而是会调用onStart()和onStartCommand()。
服务停止的时候调用onDestory()。服务只会被停止一次。
特点:一旦服务开启跟调用者(开启者)就没有任何关系了。
开启者退出了,开启者挂了,服务还在后台长期的运行。
开启者不能调用服务里面的方法。
采用bind的方式开启服务 使用这种start方式启动的Service的生命周期如下:
onCreate()--->onBind()--->onunbind()--->onDestory()
注意:绑定服务不会调用onstart()或者onstartcommand()方法
特点:bind的方式开启服务,绑定服务,调用者挂了,服务也会跟着挂掉。
绑定者可以调用服务里面的方法。
传值
一、intent
(1)在MainActivity中通过启动服务和终止服务的按钮分别调用startService(intent)和stopService(intent)来启动和停止服务
(2)在Myservice中,我们通过onStartCommand(final Intent intent, int flags, int startId)这个函数来接收从Activity传过来的值
二、我们在绑定服务的时候,首先要做的就是让我们的MainActivity实现ServiceConnection类,实现这个类之后,我们还需要重写ServiceConnection类中的两个方法onServiceConnected和onServiceDisconnected,这两个方法分别是在绑定成功和服务所在进程崩溃的时候被调用,如果绑定成功了,那么onServiceConnected(ComponentName componentName, IBinder iBinder) 就会被执行,然后第二个参数IBinder正是MyService中onBind()方法的返回值,因此我们可以通过这个返回值来想MyService传递数据。
(1)MyService 中我们创建一个Binder类,让其实现android.os.Binder类,并且定义一个方法setData,然后我们通过onBind()方法将其对象返回MainActivity。
(2)在MainActivity中,首先添加一个Binder对象,然后在ServiceConnection中获取MyService中返回的Binder对象,接着我们通过Binder对象调用它的方法setData向其传递数据
三、 接口回调应该也可以
5.TCP和UDP的区别?
1.基于连接与无连接;
2.对系统资源的要求(TCP较多,UDP少);
3.UDP程序结构较简单;
4.流模式与数据报模式 ;
5.TCP保证数据正确性,UDP可能丢包,TCP保证数据顺序,UDP不保证。
6.Android 四大组件
Activity (活动界面)
Service(服务)
BroadCastReceiver(广播接收器)
ContentProvider(内容提供者)
7.Android数据储存方式
1.Shared Preferences 保存简单的键值对数据
2.文件储存数据
3.SQLite数据库存储数据
4.使用ContentProvider存储数据
5.网络储存
8.内存优化 之 布局优化
在Android开发中,UI布局可以说是每个App使用频率很高的,随着UI越来越多,布局的重复性、复杂度也会随之增长,这样使得UI布局的优化,显得至关重要,UI布局不慎,就会引起过度绘制,从而造成UI卡顿的情。
(1)标签 include标签常用于将布局中的公共部分提取出来供其他layout共用,以实现布局模块化,这在布局编写方便提供了大大的便利。
(2)标签viewstub标签同include标签一样可以用来引入一个外部布局,不同的是,viewstub引入的布局默认不会扩张,即既不会占用显示也不会占用位置,从而在解析layout时节省cpu和内存。viewstub常用来引入那些默认不会显示,只在特殊情况下显示的布局,如进度布局、网络失败显示的刷新布局、信息出错出现的提示布局等。
(3)标签 在使用了include后可能导致布局嵌套过多,多余不必要的layout节点,从而导致解析变慢,不必要的节点和嵌套可通过hierarchy viewer(下面布局调优工具中有具体介绍)或设置->开发者选项->显示布局边界查看。
去除不必要的嵌套和View节点
(1) 首次不需要使用的节点设置为GONE或使用viewstub
(2) 使用RelativeLayout代替LinearLayout
大约在Android4.0之前,新建工程的默认main.xml中顶节点是LinearLayout,而在之后已经改为RelativeLayout,因为RelativeLayout性能更优,且可以简单实现LinearLayout嵌套才能实现的布局。
4.0及以上Android版本可通过设置->开发者选项->显示布局边界打开页面布局显示,看看是否有不必要的节点和嵌套。4.0以下版本可通过hierarchy viewer查看。
(1)对于inflate的布局可以直接缓存,用全部变量代替局部变量,避免下次需再次inflate
布局调优工具
(1) hierarchy viewer
hierarchy viewer可以方便的查看Activity的布局,各个View的属性、measure、layout、draw的时间,如果耗时较多会用红色标记,否则显示绿色。