大厂Android面试题汇总(三)数据结构

  • 常用数据结构简介
    数据元素相互之间的关系称为结构。
    有四类基本结构:集合、线性结构、树形结构、图状结构。
    1,集合结构:除了同属于一种类型外,别无其它关系。
    2,线性结构:元素之间存在一对一关系常见类型有:?数组,链表,队列,栈,它们之间在操作上有所区别。
      例如:链表可在任意位置插入或删除元素,而队列在队尾插入元素,队头删除元素, 栈只能在栈顶进行插入,删除操作.
    3,树形结构:元素之间存在一对多关系,常见类型有:树(有许多特例:二叉树、平衡二叉树、查找树等)。
    4,图形结构:元素之间存在多对多关系,图形结构中每个结点的前驱结点数和后续结点多个数可以任意。
  • 并发集合了解哪些?
    竟一个都没用过
    并发集合类
  • 列举java的集合以及集合之间的继承关系
    大厂Android面试题汇总(三)数据结构_第1张图片
    继承关系

    java集合继承关系及特点
  • 集合类以及集合框架


    大厂Android面试题汇总(三)数据结构_第2张图片
    完整集合框架
  • 容器类介绍以及之间的区别(
    容器类估计很多人没听这个词,Java容器主要可以划分为4个部分:List列表、Set集合、Map映射、工具类(Iterator迭代器、Enumeration枚举类、Arrays和Collections),具体的可以看看这篇博文 Java容器类)
  • List,Set,Map的区别
    详见上边各帖
  • List和Map的实现方式以及存储方式
    详见上边各贴
  • HashMap的实现原理
    HashMap的实现原理
    HashMap实现原理及源码分析
  • HashMap数据结构?
    见上
  • HashMap源码理解
    见上
  • HashMap如何put数据(从HashMap源码角度讲解)?
//存储
public V put(K key, V value) {
    // HashMap允许存放null键和null值。
    // 当key为null时,调用putForNullKey方法,将value放置在数组第一个位置。  
    if (key == null)
        return putForNullKey(value);
    // 根据key的keyCode重新计算hash值。
    int hash = hash(key.hashCode());
    // 搜索指定hash值在对应table中的索引。
    int i = indexFor(hash, table.length);
    // 如果 i 索引处的 Entry 不为 null,通过循环不断遍历 e 元素的下一个元素。
    for (Entry e = table[i]; e != null; e = e.next) {
        Object k;
        if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
            V oldValue = e.value;
            e.value = value;
            e.recordAccess(this);
            return oldValue;
        }
    }
    // 如果i索引处的Entry为null,表明此处还没有Entry。
    modCount++;
    // 将key、value添加到i索引处。
    addEntry(hash, key, value, i);
    return null;
}

void addEntry(int hash, K key, V value, int bucketIndex) {
    // 获取指定 bucketIndex 索引处的 Entry  
    Entry e = table[bucketIndex];
    // 将新创建的 Entry 放入 bucketIndex 索引处,并让新的 Entry 指向原来的 Entry  
    table[bucketIndex] = new Entry(hash, key, value, e);
    // 如果 Map 中的 key-value 对的数量超过了极限
    if (size++ >= threshold)
    // 把 table 对象的长度扩充到原来的2倍。
        resize(2 * table.length);
}

static int hash(int h) {
    h ^= (h >>> 20) ^ (h >>> 12);
    return h ^ (h >>> 7) ^ (h >>> 4);  
}

static int indexFor(int h, int length) {  
    return h & (length-1);
}

//获取
public V get(Object key) {
    if (key == null)
        return getForNullKey();
    int hash = hash(key.hashCode());
    for (Entry e = table[indexFor(hash, table.length)];
        e != null;
        e = e.next) {
        Object k;
        if (e.hash == hash && ((k = e.key) == key || key.equals(k)))  
            return e.value;
    }
    return null;
}

简单来说就是将Entry根据hash算法放入数组的链表中的一个过程
详见上

  • HashMap怎么手写实现?
    见上
  • ConcurrentHashMap的实现原理
    Java并发包中提供的一个线程安全且高效的HashMap实现,策略就是分段锁机制。
    ConcurrentHashMap实现原理及源码分析
  • ArrayMap和HashMap的对比
    ArrayMap和HashMap区别
  • HashTable实现原理
    HashTable的使用和原理
  • TreeMap具体实现
    TreeMap
  • HashMap和HashTable的区别
    (1)基类不同:HashTable基于Dictionary类,而HashMap是基于AbstractMap。Dictionary是什么?它是任何可将键映射到相应值的类的抽象父类,而AbstractMap是基于Map接口的骨干实现,它以最大限度地减少实现此接口所需的工作。
    (2)null不同:HashMap可以允许存在一个为null的key和任意个为null的value,但是HashTable中的key和value都不允许为null。
    (3)线程安全:HashMap时单线程安全的,Hashtable是多线程安全的。
    (4)遍历不同:HashMap仅支持Iterator的遍历方式,Hashtable支持Iterator和Enumeration两种遍历方式
  • HashMap与HashSet的区别
    大厂Android面试题汇总(三)数据结构_第3张图片
    两者区别

    HashMap和HashSet的区别
  • 集合Set实现Hash怎么防止碰撞
    Java集合---HashSet的源码分析
  • ArrayList和LinkedList的区别,以及应用场景
    1,如果应用程序对各个索引位置的元素进行大量的存取或删除操作,ArrayList对象要远优于LinkedList对象;
    2,如果应用程序主要是对列表进行循环,并且循环时候进行插入或者删除操作,LinkedList对象要远优于ArrayList对象;
    ArrayList和LinkedList区别及使用场景
  • 数组和链表的区别
    数组 分配内存连续,长度固定,插入,删除操作效率低
    链表 分配内存不连续,长度不固定,插入,删除操作效率高
  • 二叉树的深度优先遍历和广度优先遍历的具体实现
public void depthFirst() {  
    Stack> nodeStack = new Stack>();  
    Map node = new HashMap();  
    nodeStack.add(node);  
    while (!nodeStack.isEmpty()) {  
        node = nodeStack.pop();  
        System.out.println(node);  
        //获得节点的子节点,对于二叉树就是获得节点的左子结点和右子节点  
        List> children = getChildren(node);  
        if (children != null && !children.isEmpty()) {  
            for (Map child : children) {  
                nodeStack.push(child);  
            }  
        }  
    }  
}  
​//节点使用Map存放  
public void breadthFirst() {  
    Deque> nodeDeque = new ArrayDeque>();  
    Map node = new HashMap();  
    nodeDeque.add(node);  
    while (!nodeDeque.isEmpty()) {  
        node = nodeDeque.peekFirst();  
        System.out.println(node);  
        //获得节点的子节点,对于二叉树就是获得节点的左子结点和右子节点  
        List> children = getChildren(node);  
        if (children != null && !children.isEmpty()) {  
            for (Map child : children) {  
                nodeDeque.add(child);  
            }  
        }  
    }  
}  
//这里使用的是双端队列,和使用queue是一样的  

Java遍历树(深度优先+广度优先)

  • 堆的结构
    特殊的一种树
    基本数据结构――堆的基本概念及其操作
    彻底弄懂最大堆的四种操作(图解+程序)(JAVA)

  • 堆和树的区别
    二叉排序树与堆的区别

  • 堆和栈在内存中的区别是什么(解答提示:可以从数据结构方面以及实际实现方面两个方面去回答)?
    堆和栈的区别(内存和数据结构)

  • 什么是深拷贝和浅拷贝
    直接赋值:两变量指向同一对象,对任一变量操作发生变化,两变量均改变。
    浅拷贝:创建一个新对象,然后将当前对象的非静态字段复制到该新对象,如果字段是值类型的,那么对该字段执行复制;如果该字段是引用类型的话,则复制引用但不复制引用的对象。因此,原始对象及其副本引用同一个对象。(String是引用类型,但是有值类型特性)
    深拷贝:创建一个新对象,然后将当前对象的非静态字段复制到该新对象,无论该字段是值类型的还是引用类型,都进行复制。(在浅拷贝的基础上,每次拷贝将引用类型创建新对象)
    一看就懂的,java深拷贝浅拷贝

  • 手写链表逆序代码
    单链表反转java代码

  • 讲一下对树,B+树的理解
    讲一下对树,B+树的理解

  • 讲一下对图的理解
    浅析数据结构-图的基本概念

  • 判断单链表成环与否?
    判断单链表成环与否

  • 合并多个单有序链表(假设都是递增的)
    合并k个有序的链表

问题来自:AWeiLoveAndroid的博客

你可能感兴趣的:(大厂Android面试题汇总(三)数据结构)