Android面试指南(三)————Java基础篇,Android面试2024

  1. 如果碰撞,将Node以链表的形式连接在后面
  2. 如果链表长度超过阈值(8),将链表转化为红黑树,链表长度低于6,则将红黑树转回链表
  3. 如果节点存在,则替换旧值
  4. 如果数组快满了(最大容量16*加载因子0.75),就需要resize(扩容两倍)
为什么选择6和8 ?

因为中间7的位置放置频繁的数据结构切换后,影响性能

get方法
  1. 计算key的hash,在计算index值
  2. 在数组中查找index值,在比对key值,取出value,复杂度最好是O(1),最坏为O(n)
为什么不直接使用红黑树?

空间和时间的选择,链短的时候空间上占用小,时间还好,转化为红黑树后,便于查找,但是耗费空间。

处理hash冲突的方法有以下几种:
  1. 开放地址法(线性探测再散列(碰撞后,位置后挪,数组长度+x)x可为正数,二次探测再散列(数组长度+x的平方)x可为正负数,平方后均为正数)
  2. 再哈希法(多种计算哈希的方法,相同则替换方法,直到算出不重复的哈希值)
  3. 链地址法(链表)
  4. 建立公共溢出区(建立一个溢出表,存放冲突的数据)
HashMap的性能慢原因?
  • 数据类型自动装箱问题
  • resize扩容重新计算index值和hashcode,重新赋值(1.7)
    1.8后,扩容位置 = hash值 & 数组长度,如果为0,则不动,反之则反
线程不安全会导致什么

环状链表,resize(扩容)时头插法导致环形链表(1.7版本)

都存在数据丢失的问题数据丢失,1.8版本修复环形链表(尾插)

HashMap中默认容量为什么是2的幂?

因为如果不是2的幂,可能会造成更多的hash碰撞(index 下标碰撞)
假设n为17,n-1的二进制为10000,01001和01101算出的index值均为0
假设n为16,n-1的二进制为01111,01001和01101算出的index值不同

hashcode计算原理

对于int类型,hashcode为它本身,eg:int i = 1; hashcode = 1;
对于对象来说,hashcode是内部地址和对象值的一个映射

hash()算法原理

static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}

拿到key的hashCode(),在将该值与该值的高16位(h无符号右移16位)进行亦或运算(相同为0,不同为1)

HashTable的理解

put和get方法是用了synchronized修饰,锁住了整个map,同一时刻只有一个线程可以操作

不可以存储null值和null健

SparseArray理解
原理

装箱,int数据类型---->Integer对象,拆箱,Integer对象---->int数据类型

默认容量是10

  • key是int值(避免装箱问题),使用二分查找寻找key,同样也是用二分插入,从小到大排列好的
  • 两个数组,一组存放key(int []),一组存放value(object [])

mKeys[i] = key;
mValues[i] = value;

  • 如果冲突,直接替换value的值

二分插入:

while (lo <= hi) {
//二分法一分而二,数组中间下标
final int mid = (lo + hi) >>> 1;
//二分法一分而二,数组中间下标处的值
final int midVal = array[mid];

if (midVal < value) {
/**
如果数组中间处的值比要找的值小,代表要找的值
在数组的中后部部分,所以当前下标取值为mid + 1
/
lo = mid + 1;
} else if (midVal > value) {
/
*
如果数组中间处的值比要找的值大,代表要找的值
在数组的前中部部分,所以当前下标取值为mid - 1
*/
hi = mid - 1;
} else {
//数组中间处的值与要找的值相等,直接返回数组中部的下标mid
return mid; // value found
}
}

第一个值放到最中间位置

第二个值如果大于中间的值放置在左边的中间位置

………….

put方法中,容量充足,计算key值所需存放的index,如果key相同,就直接替换value,如果不同,就insert数组,后续index元素后移,新key放置在index上

较HashMap的优点
  • 节省内存
  • 性能更好,避免装箱问题
  • 数据量不达到千级,key为int值,可以用SparseArray替换HashMap
SparseArray与HashMap的比较,应用场景是?
  1. SparseArray采用的不是哈希算法,HashMap采用的是哈希算法
  2. SparseArray采用的是两个一维数组分别用于存储键和值,HashMap采用的是一维数组+单向链表/红黑树
  3. SparseArray key只能是int类型,而HashMap可以任何类型
  4. SparseArray key是有序存储(升序),而HashMap不是
  5. SparseArray 默认容量是10,而HashMap默认容量是16
  6. SparseArray 内存使用要优于HashMap,因为:
  • SparseArray key是int类型,而HashMap是Object
  • SparseArray value的存储被不像HashMap一样需要额外的需要一个实体类(Node)进行包装
  1. SparseArray查找元素总体而言比HashMap要逊色,因为SparseArray查找是需要经过二分法的过程,而HashMap不存在冲突的情况其技术处的hash对应的下标直接就可以取到值

针对上面与HashMap的比较,采用SparseArray还是HashMap,建议根据如下需求选取:

  1. 如果对内存要求比较高,而对查询效率没什么大的要求,可以是使用SparseArray
  2. 数量在百级别的SparseArray比HashMap有更好的优势
  3. 要求key是int类型的,因为HashMap会对int自定装箱变成Integer类型
  4. 要求key是有序的且是升序
ArrayMap的理解

内部也使用二分算法进行存储和查找,设计上更多考虑了内存中的优化

  • int []存储hash值,array[index]存储key,array[index+1]存储value

数据量最好在千级以内

ArrayMap和SparseArray怎么进行选取?
  1. 如果key为int,那么选取SparseArray进行存储, 不存在封/拆箱问题
  2. 如果key不为int,则使用ArrayMap
TreeMap的理解

TreeMap是一个二叉树的结构,红黑树

不允许重复的key

TreeMap没有调优选项,因为其红黑树总保持在平衡状态

TreeMap和HashMap的区别?
  1. TreeMap由红黑树构成,HashMap由数组+链表/红黑树构成
  2. HashMap元素没有顺序,TreeMap元素会根据可以进行升序排序
  3. HashMap进行插入,查找,删除最好,TreeMap进行自然顺序便利或者自定义顺序便利比较好
ThreadLocal的理解

面试官:小伙子,听说你看过ThreadLocal源码?(万字图文深度解析ThreadLocal)

线程隔离,数据不交叉

  • ThreadLocalMap,每个thread都存在一个变量ThreadLocalMap threadLocals
  • threadLocalMap中存在Entry,同ThreadLocal之间为弱引用关系
  • ThreadLocalMap中key为ThreadLocal的弱引用,value为Entry,内部为一个object对象
  • table默认大小为16,存在初始容量(16)和阈值(16*2/3)
  • 在ThreadLocal中使用get()和set()方法初始化threadLocals
  • get、set、remove方法将key==null的数据清除
  • table是环形数组

线性探测法避免哈希冲突,增量查找没有被占用的地方

通过hashcode计算索引位置,如果key值相同,则替换,不同就nextIndex,继续判断,直到插入数据

ThreadLocal就是管理每个线程中的ThreadLocalMap,所以线程隔离了。

ThreadLocalMap的理解

新建ThreadLcoal的时候,创建一个ThreadLocalMap对象,计算hash的时候使用0x61c88647这个值,他是黄金分割数,导致计算出来的hash值比较均匀,这样回大大减少hash冲突,内部在采用线性探测法解决冲突 set:

  1. 根据key计算出数组索引值
  2. 遍历该索引值的链表,如果为空,直接将value赋值,如果key相等,直接更新value,如果key不相等,使用线性探测法再次检测。
ThreadLocal使用弱引用的原因

key使用了弱引用,如果key使用强引用,那么当ThreadLocal的对象被回收了,但ThreadLocalMap还持有ThreadLocal的强引用,回导致ThreadLocal不会被回

史上最全的androidjava面试文档集。包括有: java程序员面试宝典.txt Java面试宝典2011版-1C,Java基础部分.doc 大框架面试题.zip 技术面试题.zip Android笔试题库 C语言终极面试宝典.doc Java笔试题目汇总.pdf Java面试宝典_2010.doc 面试全攻略100题.doc 智力题和答案.doc C语言面试题大汇总.doc 计算机专业必备笔试面试锦囊.doc 笔试.rar 面试题集合.zip C语言面试题大汇总1.doc 面试题集合 java面试JAVA面试题集合(项目2部).chm 华为笔试题大全(史上最齐全).doc JAVA题库.doc java面试题.zip Java面试宝典2011版-1A,Java基础部分.doc jsp笔试题全集.doc Java学习笔记(必看经典).doc androidjava面试大全.rar JAVA精华.doc JAVA经典算法50题1.doc Android笔试题库.rar Java面试宝典2011版-1B,Java基础部分.doc Java工程师试题(机构招聘)20100526.doc C语言面试题大汇总面试题及答案.doc Java23种设计模式(总结)1.doc JAVA_WEB面试笔试题.doc 实施人员初试题20091009.doc 笔试智力题.doc C语言面试题.doc 2011android面试题目及其答案大全.doc java基础笔试题.doc 安卓鄙视题附答案.txt 史上最全的android面试题库.docx android工程师笔试试卷.doc Android面试(详细答案).doc Android内测题.doc Java面试题2.doc JAVA面试题80页.doc 智力题.doc JAVA 综合面试题.pdf 分类后的葵花宝典 葵花宝典.doc 九阴真经.doc Java面试题1.doc 葵花宝典-数据库类.doc JAVA面试题集锦.doc Java程序员,面试必读.txt 软通动力招聘测试题.doc java面试葵花宝典.doc 新建 文本文档 (2).txt 125条常见的JAVA面试题.doc NET易筋经.doc 葵花宝典-Java Web类.doc 葵花宝典-基础类.doc 葵花宝典-数据库类1.doc 技术测评java.doc 技术测评.net.doc 瑞星笔试题(15道).doc 汉端笔试题(7页).doc 一道测试notepad笔试题.doc 奇虎面试题.doc 喜安科 面试题.doc 北京博彦科技笔试+面试.doc 清华同方开发的面试题 (有兴趣的看一下了 !) 中软的面试题(转贴).doc 亚控科技比试题.doc 神州泰岳测试试题(笔试)转贴.doc 一家通讯公司的面试题目.doc 软件测试工程师试题发布版.doc 某公司的面试试题.doc 一个外包测试公司的笔试题!.doc 时力科技面试题.doc 合力金桥的笔试题.doc 一道数据库的笔试题目.doc 传视数码公司的面试题.doc 美国英网软件公司题目.doc 软件测试工程师测试试题大集合(二)包括答案.d 波尔世通的笔试+面试.doc 瓦瑟笔试题(限男性).doc 软通动力面试笔答.doc 常见的测试题(转贴).doc 北京大学计算机科学技术研究所.doc 联合网视面试题.doc 缺陷的等级划分,一个经常被问到的问题.doc 软件测试工程师笔试试题(大集合).doc 千像互动的笔试.doc 2012java面试题分析大全.doc JAVA面试题集合(项目2部).chm JAVA经典算法50题1.doc Java工程师试题(机构招聘)20100526.doc Java23种设计模式(总结)1.doc 实施人员初试题20091009.doc 框架图.png struts面试题 hibernate面试大框架.txt JAVA题库.doc
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值