安卓面试前的复习——Java部分
Posted LovelyCode
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了安卓面试前的复习——Java部分相关的知识,希望对你有一定的参考价值。
个人第一篇推文。周末要去团队参加面试,很希望得到这样一个机会,能认识更多的人,学到更多东西。前几天有所准备,现在想把这些自己需要复习的题写下来。我只是一个在校的大一学生,接触安卓甚至只有半年之久,见识短浅,知识浅薄,文笔贫瘠。若我有幸得到观众看到这些文章,求轻喷。若有写错的地方,欢迎指正。毕竟,我只是个瑟瑟发抖的小菜鸡。
1、HashMap:
①HashMap就是一个数组,每个元素是一个bucket,也就是一个链表,链表的每个节点是一个Entry<key, value>,保存一个键值对。
②HashMap保存一个数组长度和一个负载因子,用以控制存数据所用的数组的大小(下文会继续解释)。
③每个key根据hashCode()方法得出一个散列值(key的类型不同,具体计算方法不同),对容量进行取模运算后,得到一个位置。若该位置上没有数据,则存入;若已有数据,我们就说产生了碰撞,这时就将该键值对存在已有键值对的下一个节点(形成一个链表)。
④取数据时,根据key值,计算出hashcode,找到对应bucket上的键值对,并比较根据键的equals方法,进行比较,如果与bucket上的相同,就返回它的值,如果不相同,那就找下一个啦,这是个链表哇。直到找到它。
⑤还记得负载因子吗,它是为了控制不要每个bucket的链表太长,影响读取效率,所以当存入的bucket数达到负载因子规定的数量时,就要把数组长度翻倍啦。其实是new了一个长度为原先数组两倍长的新数组(偷偷告诉你,ArrayList还有一些其他用数组实现的容器,也是这么干的),然后把原数组存进去。至于怎么算的加载因子,比方说加载因子是0.75,原先数组容量是100,那么,当数组上75个位置有东东时,就要扩容啦。
2、HashSet和HashMap
Set只存值,而Map存的是键值对。Set中的值是不会重复的。
其实HashSet的存取原理和Map一样,只是Map存的是键值对,而Set只存值。而且,神奇的是,其实Set内部原理就是用了一个HashMap,然后把存进来的值,当成Map的键存进去了。(Map的键可不能重复)
3、HashTable和HashMap
HashTable被淘汰了已经,现在已经有新的解决方案。主要区别是HashTable实现了线程同步,是线程安全的。
4、ArrayList和LinkList
Array,顾命思意就是一个数组嘛。但是为什么可以变长呢,因为骗你的。谁说数组可以变长的,只是当数组不够用了的时候,就换个更长的数组,然后把原来那个复制过去就是了。
Link,也来顾命思意,就是个链表嘛~好的,没了,链表当然可以变长啦
这两者其实还是有区别的,区别在于效率
所以他们二者的用处不同,如果读取数据多,删除插入少,用ArrayList比较合适。反之用LinkList吧
5、浅拷贝和深拷贝
Java中的拷贝就是实现Cloneable接口中的clone方法,从而将一个对象复制一份一样的对象。
对象的状态,另一个也会发生改变,其实就是同一个哇。
那反之,深拷贝就不一样了,不管是引用还是clone,都是复制了一个新的。
实现深拷贝和浅拷贝所重写的方法是同一个方法,就是clone,只是重写时不同。若要实现浅拷贝,直接调用super.clone()返回就好了,这调用的时Object中的方法。而如果要实现深拷贝,那调用super.clone()返回的对象中,引用变量也要单独进行.clone()。
6、写一个三种单例吧
单例的特征首先是对象持有一个私有的自身的静态变量,然后把构造方法私有化,外部不能直接new,而要通过该对象提供的方法,获取这个静态对象。这样做,可以实现在同一个进程中,关于该类只有一个实例,从而节省了内存,减少反复创建。
单例模式有好多种写法,这里列举三种常见写法
①懒汉式:
懒汉式不在声明变量时初始化,而是将初始化的工作放到方法定义中,这里我们假设变量叫做instance,而方法叫做getInstance()
⭐这里,为了防止异步读取,我们用了线程锁。
②饿汉式
饿汉式在变量声明时就初始化,基于classloader机制,它是线程安全的,但悲剧的是,这个类在装载时就会把instance实例化,这样不利于节省内存,而懒汉式会等到方法调用时才实例化。
③登记式/内部类
这种方式通过内部类的形式,实现了单例,这样既保证了同步问题,又保证了直到方法调用时才实例化Instance,但缺点是比较复杂。
以上是关于安卓面试前的复习——Java部分的主要内容,如果未能解决你的问题,请参考以下文章