Android面试题

内存抖动:

定义:

内存抖动是由于短时间内有大量对象进出新生区导致的,它伴随着频繁的GC,gc会大量占用ui线程和cpu资源,会导致app整体卡顿。

避免发生内存抖动的几点建议:

尽量避免在循环体内创建对象,应该把对象创建移到循环体外。

注意自定义View的onDraw()方法会被频繁调用,所以在这里面不应该频繁的创建对象。

当需要大量使用Bitmap的时候,试着把它们缓存在数组或容器中实现复用。

对于能够复用的对象,同理可以使用对象池将它们缓存起来。

 

动画原理:

分类:

frame 帧动画:AnimationDrawable控制animation-list.xml布局。

tween 补间动画:通过指定View的初末状态和变化方式,对View的内容完成一系列的图形变换来实现动画效果, Alpha, Scale ,Translate, Rotate。

PropertyAnimation 属性动画:3.0引入,属性动画核心思想是对值的变化。

属性动画&&补间动画的性能差异:

属性动画操作的是对象的实例属性,例如translationX,然后反射调用set,geView动画:t方法,多个属性动画同时执行,会频繁反射调用类方法,降低性能。

补间动画只产生了一个动画效果,其真实的坐标并没有发生改变,是效果一直在发生变化,没有频繁反射调用方法的耗费性能操作。

原理及特点:

帧动画:

是在xml中定义好一系列图片之后,使用AnimatonDrawable来播放的动画。

View动画:

只是影像变化,view的实际位置还在原来地方。

属性动画:

插值器:作用是根据时间流逝的百分比来计算属性变化的百分比。

估值器:在1的基础上由这个东西来计算出属性到底变化了多少数值的类。

其实就是利用插值器和估值器,来计出各个时刻View的属性,然后通过改变View的属性来实现View的动画效果。

区别:

属性动画才是真正的实现了 view 的移动,补间动画对view 的移动更像是在不同地方绘制了一个影子,实际对象还是处于原来的地方。 当动画的 repeatCount 设置为无限循环时,如果在Activity退出时没有及时将动画停止,属性动画会导致Activity无法释放而导致内存泄漏,而补间动画却没问题。 xml 文件实现的补间动画,复用率极高。在 Activity切换,窗口弹出时等情景中有着很好的效果。 使用帧动画时需要注意,不要使用过多特别大的图,容导致内存不足。

为什么属性动画移动后仍可点击?

播放补间动画的时候,我们所看到的变化,都只是临时的。而属性动画呢,它所改变的东西,却会更新到这个View所对应的矩阵中,所以当ViewGroup分派事件的时候,会正确的将当前触摸坐标,转换成矩阵变化后的坐标,这就是为什么播放补间动画不会改变触摸区域的原因了。

 

 

Https的连接过程,加解密算法的选择,以及为什么?

加密算法的类型基本上分为了两种:

对称加密,加密用的密钥和解密用的密钥是同一个,比较有代表性的就是 AES 加密算法;

非对称加密,加密用的密钥称为公钥,解密用的密钥称为私钥,经常使用到的 RSA 加密算法就是非对称加密的;

此外,还有Hash单向加密算法:

HASH算法:MD5, SHA1, SHA256

相比较对称加密而言,非对称加密安全性更高,但是加解密耗费的时间更长,速度慢。

HTTPS = HTTP + SSL,HTTPS 的加密就是在 SSL 中完成的。

这就要从 CA 证书讲起了。CA 证书其实就是数字证书,是由 CA 机构颁发的。至于 CA 机构的权威性,那么是毋庸置疑的,所有人都是信任它的。CA 证书内一般会包含以下内容:

证书的颁发机构、版本

证书的使用者

证书的公钥

证书的有效时间

证书的数字签名 Hash 值和签名 Hash 算法

客户端如何校验 CA 证书?

CA 证书中的 Hash 值,其实是用证书的私钥进行加密后的值(证书的私钥不在 CA 证书中)。然后客户端得到证书后,利用证书中的公钥去解密该 Hash 值,得到 Hash-a ;然后再利用证书内的签名 Hash 算法去生成一个 Hash-b 。最后比较 Hash-a 和 Hash-b 这两个的值。如果相等,那么证明了该证书是对的,服务端是可以被信任的;如果不相等,那么就说明该证书是错误的,可能被篡改了,浏览器会给出相关提示,无法建立起 HTTPS 连接。除此之外,还会校验 CA 证书的有效时间和域名匹配等。

 

 

 

HTTPS 中的 SSL 握手建立过程:

假设现在有客户端 A 和服务器 B :

1、首先,客户端 A 访问服务器 B ,比如我们用浏览器打开一个网页 www.baidu.com ,这时,浏览器就是客户端 A ,百度的服务器就是服务器 B 了。这时候客户端 A 会生成一个随机数1,把随机数1 、自己支持的 SSL 版本号以及加密算法等这些信息告诉服务器 B 。

2、服务器 B 知道这些信息后,然后确认一下双方的加密算法,然后服务端也生成一个随机数 2 ,并将随机数 2 和 CA 颁发给自己的证书一同返回给客户端 A 。

3、客户端 A 得到 CA 证书后,会去校验该 CA 证书的有效性,校验方法在上面已经说过了。校验通过后,客户端生成一个随机数3 ,然后用证书中的公钥加密随机数3 并传输给服务端 B 。

4、服务端 B 得到加密后的随机数3,然后利用私钥进行解密,得到真正的随机数3。

5、最后,客户端 A 和服务端 B 都有随机数1、随机数2、随机数3,然后双方利用这三个随机数生成一个对话密钥。之后传输内容就是利用对话密钥来进行加解密了。这时就是利用了对称加密,一般用的都是 AES 算法。

6、客户端 A 通知服务端 B ,指明后面的通讯用对话密钥来完成,同时通知服务器 B 客户端 A 的握手过程结束。

7、服务端 B 通知客户端 A,指明后面的通讯用对话密钥来完成,同时通知客户端 A 服务器 B 的握手过程结束。

8、SSL 的握手部分结束,SSL 安全通道的数据通讯开始,客户端 A 和服务器 B 开始使用相同的对话密钥进行数据通讯。

简化如下:

1、客户端和服务端建立 SSL 握手,客户端通过 CA 证书来确认服务端的身份;

2、互相传递三个随机数,之后通过这三个随机数来生成一个密钥;

3、互相确认密钥,然后握手结束;

4、数据通讯开始,都使用同一个对话密钥来加解密;

可以发现,在 HTTPS 加密原理的过程中把对称加密和非对称加密都利用了起来。即利用了非对称加密安全性高的特点,又利用了对称加密速度快,效率高的好处。

 

如何绕过9.0限制?

如何限制?

1、阻止java反射和JNI。

2、当获取方法或Field时进行检测。

3、怎么检测?

区分出是系统调用还是开发者调用:

根据堆栈,回溯Class,查看ClassLoader是否是BootStrapClassLoader。

区分后,再区分是否是hidden api:

Method,Field都有access_flag,有一些备用字段,hidden信息存储其中。

如何绕过?

1、不用反射:

利用一个fakelib,例如写一个android.app.ActivityThread#currentActivityThread空实现,直接调用;

2、伪装系统调用:

jni修改一个class的classloder为BootStrapClassLoader,麻烦。

利用系统方法去反射:

利用原反射,即:getDeclaredMethod这个方法是系统的方法,通过getDeclaredmethod反射去执行hidden api。

3、修改Method,Field中存储hidden信息的字段:

利用jni去修改。

 

堆内存,栈内存理解,栈如何转换成堆?

在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配。

堆内存用于存放由new创建的对象和数组。JVM里的“堆”(heap)特指用于存放Java对象的内存区域。所以根据这个定义,Java对象全部都在堆上。JVM的堆被同一个JVM实例中的所有Java线程共享。它通常由某种自动内存管理机制所管理,这种机制通常叫做“垃圾回收”(garbage collection,GC)。

堆主要用来存放对象的,栈主要是用来执行程序的。

实际上,栈中的变量指向堆内存中的变量,这就是 Java 中的指针!

hashcode()和 equals()的作用、区别、联系?

因为hashCode()并不是完全可靠,有时候不同的对象他们生成的hashcode也会一样(生成hash值的公式可能存在的问题),所以hashCode()只能说是大部分时候可靠,并不是绝对可靠,所以我们可以得出:

1、equal()相等的两个对象他们的hashCode()肯定相等,也就是用equal()对比是绝对可靠的。

2、hashCode()相等的两个对象他们的equal()不一定相等,也就是hashCode()不是绝对可靠的。

10、Handler、Looper、MessageQueue、Thread关系?

一个线程可以有多个Handler实例,一个线程对应一个Looper,一个Looper也只对应一个MessageQueue,一个MessageQueue对应多个Message和Runnable。所以就形成了一对多的对应关系,一方:线程、Looper、MessageQueue;多方:Handler、Message。同时可以看出另一个一对一关系:一个Message实例对应一个Handler实例。

 

 

Hashmap如何解决散列碰撞(必问)?

Java中HashMap是利用“拉链法”处理HashCode的碰撞问题。在调用HashMap的put方法或get方法时,都会首先调用hashcode方法,去查找相关的key,当有冲突时,再调用equals方法。hashMap基于hasing原理,我们通过put和get方法存取对象。当我们将键值对传递给put方法时,他调用键对象的hashCode()方法来计算hashCode,然后找到bucket(哈希桶)位置来存储对象。当获取对象时,通过键对象的equals()方法找到正确的键值对,然后返回值对象。HashMap使用链表来解决碰撞问题,当碰撞发生了,对象将会存储在链表的下一个节点中。hashMap在每个链表节点存储键值对对象。当两个不同的键却有相同的hashCode时,他们会存储在同一个bucket位置的链表中。键对象的equals()来找到键值对。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值