关于近期面试总结(2018年下半年)
有些是老生常谈有些是没有遇到的。
1.HTTP和HTTPS的区别
HTTP协议传输的数据都是未加密的,也就是明文的,因此使用HTTP协议传输隐私信息非常不安全,为了保证这些隐私数据能加密传输,于是网景公司设计了SSL(Secure Sockets Layer)协议用于对HTTP协议传输的数据进行加密,从而就诞生了HTTPS。简单来说,HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,要比http协议安全。
HTTPS和HTTP的区别主要如下:
1、https协议需要到ca申请证书,一般免费证书较少,因而需要一定费用。
2、http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl加密传输协议。
3、http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。
4、http的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。
2.LaunchMode
- standard
标准模式下,只要启动一次Activity,系统就会在当前任务栈新建一个实例。
使用场景:正常的去打开一个新的页面,这种启动模式使用最多,最普通 。
- :SingleTop 栈顶复用
1、当前栈中已有该Activity的实例并且该实例位于栈顶时,不会创建实例,而是复用栈顶的实例,并且会将Intent对象传入,回调onNewIntent()方法;
2、当前栈中已有该Activity的实例但是该实例不在栈顶时,其行为和standard启动模式一样,依然会创建一个新的实例;
3、当前栈中不存在该Activity的实例时,其行为同standard启动模式。
使用场景:新闻详情页,收到推送打开新闻详情如果每次都创建新的实例显然浪费资源,如果singleTop复用,每次通过intent传入相应URI即可。 - SingTask 栈内复用
1、如果不存在指定的任务栈,系统会新建对应的任务栈,并新建Activity实例压入栈中。
2、如果存在指定的任务栈,则会查找该任务栈中是否存在该Activity实例
a、如果不存在该实例,则会在该任务栈中新建Activity实例。
b、如果存在该实例,则会直接引用,并且回调该实例的onNewIntent()方法。并且任务栈中该实例之上的Activity会被全部销毁。
使用场景:通过情况下我们把需要长时间保留在栈中的界面做成这种模式如APP首页,扫描二维码等。 - SingleInstance
启动该模式Activity的时候,会查找系统中是否存在: 1、不存在,首先会新建一个任务栈,其次创建该Activity实例。
2、存在,则会直接引用该实例,并且回调onNewIntent()方法。 特殊情况:该任务栈或该实例被销毁,系统会重新创建。
使用场景:相机,相册,电话拨号等
3.Service不被杀死
①onStartCommand的时候手动返回START_STICKY会在内存充足的时候重新创建serivce,不保留传入的Intent
@Override public int onStartCommand(Intent intent, int flags, int startId) { flags = START_STICKY; return super.onStartCommand(intent, flags, startId); }
②提升service优先级在AndroidManifest.xml文件中对于intent-filter可以通过android:priority = "1000"这个属性设置最高优先级,1000是最高值,越大优先级越高
③可以在service的onDestory方法中通过广播触发重启service
④监听系统某些广播拉起service比如重启手机,界面唤醒,网络切换等缺点是可能混乱
⑤双进程互相监听,主流应用搜狐,360,微信等都是。
4.Handler与weakReference解决可能导致内存泄漏
为解决handler持有activity的引用可能导致内存泄漏,我们通常将Handler定义为静态内部类,但是这样我们不能操作activity中的内容,通过使用弱引用可以解决。
static class MyHandler extends Handler { WeakReference<Activity > mActivityReference; MyHandler(Activity activity) { mActivityReference= new WeakReference<Activity>(activity); } @Override public void handleMessage(Message msg) { final Activity activity = mActivityReference.get(); if (activity != null) { mImageView.setImageBitmap(mBitmap); } } }
WeakReference弱引用,与强引用(即我们常说的引用)相对,它的特点是,GC在回收时会忽略掉弱引用,即就算有弱引用指向某对象,但只要该对象没有被强引用指向(实际上多数时候还要求没有软引用,但此处软引用的概念可以忽略),该对象就会在被GC检查到时回收掉。对于上面的代码,用户在关闭Activity之后,就算后台线程还没结束,但由于仅有一条来自Handler的弱引用指向Activity,所以GC仍然会在检查的时候把Activity回收掉。这样,内存泄露的问题就不会出现了。
5.ListVIew,RecylerView加载不同类型的Item
ListView:
1)重写 getViewTypeCount() – 该方法返回多少个不同的布局
2)重写 getItemViewType(int) – 根据position返回相应的Item
3)根据view item的类型,在getView中创建正确的convertView(通过调用getItemVIewType不同type加载不同布局)
RecylerView:
RecyclerView实现加载不同的Layout的核心就是在Adapter的onCreateViewHolder里面去根据需求而加载不同的布局(抄一段代码)。
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
//加载Item View的时候根据不同TYPE加载不同的布局
if (viewType == ITEM_TYPE.ITEM1.ordinal()) {
return new Item1ViewHolder(mLayoutInflater.inflate(R.layout.item1, parent, false));
} else {
return new Item2ViewHolder(mLayoutInflater.inflate(R.layout.item2, parent, false));
}
}
@Override
public int getItemViewType(int position) { return list.get(position).getShowType(); }
---------------------
作者:李济洲
来源:CSDN
原文:https://blog.csdn.net/leejizhou/article/details/50708349
版权声明:本文为博主原创文章,转载请附上博文链接!
6.动态更改ListView高度
通过适配器获得每一行高度然后通过LayoutParams设置listView的参数代码如下
public void setHeight(){ int height = 0; int count = adapter.getCount(); for(int i=0;i<count;i++){ View temp = adapter.getView(i,null,listview); temp.measure(0,0); height += temp.getMeasuredHeight(); } LayoutParams params = this.listview.getLayoutParams(); params.width = LayoutParams.FILL_PARENT; params.height = height; }
7.进程间通信
1).访问其他进程的activity ,通过Intent/action/uri访问
2).contentProvider,Content Provider提供了一种在多个应用程序之间数据共享的方式(跨进程共享数据)
3). 广播是一种被动跨进程通讯的方式。当某个程序向系统发送广播时,其他的应用程序只能被动地接收广播数据。
4).AIDL
8.导致OOM出现的可能
1).加载大量的图片,音频视频,内存较低的时候容易导致内存溢出,可使用第三方框架减少这种情况
2).BItMap处理不正确,不要再主线程处理,忘记调用recycle释放bitmap对象
3).非静态内部类的Handler,由于持有Activity的引用,可能导致溢出,建议使用弱引用来解决
4).BroadCastReceiver,cursor,file等操作后未及时关闭。
5).static变量生命周期过长,容易导致oom,在不使用的时候要及时置为null
9.如何加载大图,而不出现OOM
bitmap对象过大的时候怎么加载,这里就要用到BitmapFactory.Option这个类。核心就是inJustDecodeBounds和SampleSize获取一个预览图
BitmapFactory提供了如下四类方法,可分别用于从文件系统、资源、输入流以及字节数组中加载出一个Bitmap对象
1.decodeFile;
2.decodeResource;
3.decodeStream;
4.decodeByteArray;
如果高效的加载类图呢,其实核心就是BitmapFactory.Options来加载所需尺寸的图片。因为很多时间ImageView并没有图片原始尺寸那么大,把整个图片加载进来显然是没有必要的。我们可以使用BitmapFactory.Options从如下几种方式对图片进行采样压缩,降低内存的占有从而减少OOM的可能性:
1. 降低图片加载到内存的分辨率(BitmapFactory.Options.inJustDecodeBounds/outWidth/outHeight/inSampleSize属性);
2. 采用更节更节省内存的编码,如ARGB_4444(BitmapFactory.Options.inPreferredConfig属性);
3. 采用缓存;
每一个类型的解码方法都会有一个额外的BitmapFactory.Options类型的参数让你指定附加的解码选项。在解码时,把inJustDecodeBounds这个属性设为true,这样的话,解码方法返回的bitmap对象为null,从而避免了分配内存;与此同时,bitmap的尺寸和类型信息也相应地保存到了传入的BitmapFactory.Options类型参数的outWidth,outHeight和outMimeTyp属性中。这项技术允许我们在不给bitmap分配内存的情况下,获取到bitmap的尺寸和类型的信息。
根据原图和ImageView大小加载一个小型样本到内存现在我们知道了bitmap的尺寸,它们用来决定是否要将整张图片记载到内存中还是抽取一部分样本来代替。下面是一些我们需要考虑的因素:
1、加载整张图片所需要耗费的内存;
2、考虑到应用内存的限制,愿意为这张图片提供多少内存。
3、将要展示图片的ImageView或者其他UI控件的大小
4、当前设备的屏幕大小和密度(density)
10.HashMap
Hashmap就相当于数据结构中学过的链表,通过key值计算其hash值确定插入链表的位置源码为:
if (key == null)
return putForNullKey(value);
int hash = sun.misc.Hashing.singleWordWangJenkinsHash(key);
int i = indexFor(hash, table.length);
因为hash值不是连续的,所以hashmap实际需要占用的大小会比它实际能装的item的容量要大
第一次新建hashmap的时候 默认是16个空间
两个关键参数 loadFactor 负载因子 threshold 阈值 阈值等于初始容量*负载因子
浙公网安备 33010602011771号