zoukankan      html  css  js  c++  java
  • 面试-java基础

    1. List 和 Set 的区别
     
    1.1    list是有序集合(容器)且元素可以重复,输出顺序就是插入顺序;Set是无序集合且元素不可以重复。
    1.2    list可以存放多个null;set只可以存一个null
    1.3     常用list有ArrayList,LinkedList,vector;
    •      ArrayList
    • 优点:ArrayList是实现了基于动态数组的数据结构,因为地址连续,一旦数据存储好了,查询操作效率会比较高(在内存里是连着放的)。
    • 缺点:因为地址连续, ArrayList要移动数据,所以插入和删除操作效率比较低。
    • LinkedList
    • 优点:LinkedList基于链表的数据结构,地址是任意的,所以在开辟内存空间的时候不需要等一个连续的地址,对于新增和删除操作add和remove,LinedList比较占优势LinkedList 适用于要头尾操作或插入指定位置的场景
    • 缺点:因为LinkedList要移动指针,所以查询操作性能比较低。
    • 适用场景分析:
    •  当需要对数据进行对此访问的情况下选用ArrayList,当需要对数据进行多次增加删除修改时采用LinkedList。
    • vector
    • ArrayList和Vector都是用数组实现的,主要有这么三个区别:
     
    • 1.Vector是多线程安全的,线程安全就是说多线程访问同一代码,不会产生不确定的结果。而ArrayList不是,这个可以从源码中看出,Vector类中的方法很多有synchronized进行修饰,这样就导致了Vector在效率上无法与ArrayList相比;
    • 2.两个都是采用的线性连续空间存储元素,但是当空间不足的时候,两个类的增加方式是不同。
    • 3.Vector可以设置增长因子,而ArrayList不可以。
    • 4.Vector是一种老的动态数组,是线程同步的,效率很低,一般不赞成使用。
     
    •     常用的set有HashSet,LinkedSet,Treeset,[简单介绍]
    • HashSet
    • .HashSe哈希表实现的,HashSet中的数据是无序的,可以放入null,但只能放入一个null,两者中的值都不能重复,就如数据库中唯一约束 
    • HashSet要求放入的对象必须实现HashCode()方法,放入的对象,是以hashcode码作为标识的,而具有相同内容的String对象,hashcode是一样,所以放入的内容不能重复。但是同一个类的对象可以放入不同的实例
    • 适用场景分析:HashSet是基于Hash算法实现的,其性能通常都优于TreeSet。为快速查找而设计的Set,我们通常都应该使用HashSet,在我们需要排序的功能时,我们才使用TreeSet。
    • LinkedSet
     
    • Treeset
    • TreeSet 二差树(红黑树的树据结构)实现的,Treeset中的数据是自动排好序的,不允许放入null值 
    1.4    [应用场景]
        1.如果你经常会使用索引来对容器中的元素进行访问,那么 List 是你的正确的选择。如果你已经知道索引了的话,那么 List 的实现类比如 ArrayList 可以提供更快速的访问,如果经常添加删除元素的,那么肯定要选择LinkedList。
        2.如果你想容器中的元素能够按照它们插入的次序进行有序存储,那么还是 List,因为 List 是一个有序容器,它按照插入顺序进行存储。
        3.如果你想保证插入元素的唯一性,也就是你不想有重复值的出现,那么可以选择一个 Set 的实现类,比如 HashSet、LinkedHashSet 或者 TreeSet。所有 Set 的实现类都遵循了统一约束比如唯一性,而且还提供了额外的特性比如 TreeSet 还是一个 SortedSet,所有存储于 TreeSet 中的元素可以使用 Java 里的 Comparator 或者 Comparable 进行排序。LinkedHashSet 也按照元素的插入顺序对它们进行存储。
        4.如果你以键和值的形式进行数据存储那么 Map 是你正确的选择。你可以根据你的后续需要从 Hashtable、HashMap、TreeMap 中进行选择。
        
        
     
    注意:
    LinkedList、ArrayList、HashSet是非线程安全的,Vector是线程安全的;
    HashMap是非线程安全的,HashTable是线程安全的;
    StringBuilder是非线程安全的,StringBuffer是线程安全的。
     
    扩展:
    HashMap 非线程安全  
    HashMap:基于哈希表实现。使用HashMap要求添加的键类明确定义了hashCode()和equals()[可以重写hashCode()和equals()],为了优化HashMap空间的使用,您可以调优初始容量和负载因子。 
     
    TreeMap:非线程安全基于红黑树实现。TreeMap没有调优选项,因为该树总处于平衡状态。 
     
    适用场景分析:
    HashMap和HashTable:HashMap去掉了HashTable的contains方法,但是加上了containsValue()和containsKey()方法。HashTable同步的,而HashMap是非同步的,效率上比HashTable要高。HashMap允许空键值,而HashTable不允许。
    HashMap:适用于Map中插入、删除和定位元素。 
    Treemap:适用于按自然顺序或自定义顺序遍历键(key)。 
     
     
     
    1. HashSet 是如何保证不重复的 

    1.hashset是基于哈希表实现的,先要根据hash码值(就是key的hashcode值)去判断,然后在用equals判断,都相等为已有元素,不在存储。否则作为新元素存存储。

      
      3、HashMap 是线程安全的吗,为什么不是线程安全的(最好画图说明多线程环境下不安全)? 
    1.不是线程安全的,由于hash碰撞,以及扩容导致
      **通过Entry内部的next变量可以知道使用的是链表,这时候我们可以知道,如果多个线程,在某一时刻同时操作HashMap并执行put操作,而有大于两个key的hash值相同,
    如图中a1、a2,这个时候需要解决碰撞冲突,而解决冲突的办法上面已经说过,对于链表的结构在这里不再赘述,暂且不讨论是从链表头部插入还是从尾部初入,
    这个时候两个线程如果恰好都取到了对应位置的头结点e1,而最终的结果可想而知,a1、a2两个数据中势必会有一个会丢失

      **多个线程同时检测到总数量超过门限值的时候就会同时调用resize操作,各自生成新的数组并rehash后赋给该map底层的数组table,

    结果最终只有最后一个线程生成的新数组被赋给table变量,其他线程的均会丢失。而且当某些线程已经完成赋值而其他线程刚开始的时候,就会用已经被赋值的table作为原始数组,这样也会有问题

       **(还是解释扩容导致线程不安全问题)如果多个线程同时检测到元素个数超过数组大小*loadFactor,这样就会发生多个线程同时对Node数组进行扩容,都在重新计算元素位置以及复制数据,但是最终只有一个线程扩容后的数组会赋给table,也就是说其他线程的都会丢失,并且各自线程put的数据也丢失

     
    4、HashMap 的扩容过程 
      参考:https://blog.csdn.net/aichuanwendang/article/details/53317351
         https://www.cnblogs.com/KingIceMou/p/6976574.html
     
      1.数组的长度2的32幂,hashmap初始大小为16,负载因子默认我0.75
      2.hashmap是懒加载,构造完HashMap对象后,只要不进行put 方法插入元素之前,HashMap并不会去初始化或者扩容table:
      3.插入数据时,会去判断hashmap的哈希表长度*负载因子,如果这个值小于hashmap中当前元素的个数,就会去调用resize方法去扩容。
     
      参考:https://www.cnblogs.com/kuoAT/p/6771653.html
    arraylist动态扩容,初始大小为10或者0(无参构造器),以1.5倍大小扩容,调用grow方法。
      
     
    5、HashMap 1.7 与 1.8 的 区别,说明 1.8 做了哪些优化,如何优化的?
      https://www.cnblogs.com/stevenczp/p/7028071.html
      1.使用node数组存数据,对key做哈希得到的hashcode后,如果hashcode重复,会放到链表中,如果超过8个把链表转化为红黑树,这样查找会快点
      2.要实现Compare接口,如果不实现还没有1.7的快
      
      hashmap实现compare接口
      https://blog.csdn.net/zly9923218/article/details/51656920
    6、final finally finalize
      1.final是修饰符,可以修复类,方法,属性;
      2.被final修饰的类不能被继承;被final修饰的方法只能使用,不能被重载;被final修饰的变量就是常量了,必须有初始值,不能拿被修改。
      
      finally 是处理异常时来执行清除操作,不管有没有抛出,捕获,finally块最后都会被执行。
     
      finalize 在垃圾回收器将对象从内存中清除出去之前做必要的清理工作。
    7、强引用 、软引用、 弱引用、虚引用
      

      强引用是使用最普遍的引用:Object o=new Object(); 特点:不会被GC

      软引用用来描述一些还有用但是并非必须的对象,在Java中用java.lang.ref.SoftReference类来表示。对于软引用关联着的对象,只有在内存不足的时候JVM才会回收该对象。
      因此,这一点可以很好地用来解决OOM的问题,并且这个特性很适合用来实现缓存:比如网页缓存、图片缓存等

      弱引用与软引用的区别在于:只具有弱引用的对象拥有更短暂的生命周期。在垃圾回收器线程扫描它所管辖的内存区域的过程中,
      一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。不过,由于垃圾回收器是一个优先级很低的线程,
      因此不一定会很快发现那些只具有弱引用的对象

      虚引用也称为幻影引用:一个对象是都有虚引用的存在都不会对生存时间都构成影响,也无法通过虚引用来获取对一个对象的真实引用。
      唯一的用处:能在对象被GC时收到系统通知,JAVA中用PhantomReference来实现虚引用。

      
      
    8、Java反射 
     
    9、Arrays.sort 实现原理和 Collection 实现原理
      
    10、LinkedHashMap的应用 
      1.需要保证插入顺序的
      
    11、cloneable接口实现原理 
      
    12、异常分类以及处理机制
      
    13、wait和sleep的区别 
      
    14、数组在内存中如何分配
      
     
    参考:
    • 比较好的参考关于list,set
    https://blog.csdn.net/qq_22118507/article/details/51576319
     
     
     
     
     
     
    *************************************************
    一:List接口
        1.List集合代表一个有序集合,集合中每个元素都有其对应的顺序索引。List集合允许使用重复元素,可以通过索引来访问指定位置的集合元素
     
    ArrayList:
        1.ArrayList是一个动态数组,也是我们最常用的集合,初始容量(10),该容量代表了数组的大小。随着容器中的元素不断增加,容器的大小也会随着增加
        2.ArrayList擅长于随机访问。同时ArrayList是非同步的
     
    LinkedList
        1.LinkedList是一个双向链表,除了有ArrayList的基本操作方法外还额外提供了get,remove,insert方法在LinkedList的首部或尾部
        2.LinkedList不能随机访问,LinkedList也是非同步的
        
    Vector
        1. 与ArrayList相似,但是Vector是同步的。所以说Vector是线程安全的动态数组。它的操作与ArrayList几乎一样。
        
    Stack
        1.Stack继承自Vector,实现一个后进先出的堆栈。Stack提供5个额外的方法使得Vector得以被当作堆栈使用。基本的push和pop 方法,还有peek方法得到栈顶的元素,empty方法测试堆栈是否为空,search方法检测一个元素在堆栈中的位置。Stack刚创建后是空栈。
        
    二:Set接口
        1.Set是一种不包括重复元素的Collection,Set接口有三个具体实现类,分别是散列集HashSet、链式散列集LinkedHashSet和树形集TreeSet。
        
    HashSet
        1.HashSet 是一个没有重复元素的集合。它是由HashMap实现的不保证元素的顺序;HashSet是非同步的
        2.HashSet的实现方式大致如下,通过一个HashMap存储元素,元素是存放在HashMap的Key中,而Value统一使用一个Object对象
     
    LinkedHashSet  
        1. LinkedHashSet继承自HashSet,有序,非同步
    TreeSet
        1.TreeSet是一个有序集合,其底层是基于TreeMap实现的,非线程安全
        
    三:Map接口
    HashMap
        1.以哈希表数据结构实现,查找对象时通过哈希函数计算其位置,它是为快速查询而设计的,其内部定义了一个hash表数组(Entry[] table),元素会通过哈希转换函数将元素的哈希地址转换成数组中存放的索引,如果有冲突,则使用散列链表的形式将所有相同哈希地址的元素串起来,可能通过查看HashMap.Entry的源码它是一个单链表结构。
    LinkedHashMap
        1.
    TreeMap
        1.TreeMap 是一个有序的key-value集合,非同步基于红黑树(Red-Black tree)实现,每一个key-value节点作为红黑树的一个节点。TreeMap存储时会进行排序的,会根据key来对key-value键值对进行排序,其中排序方式也是分为两种,一种是自然排序,一种是定制排序,具体取决于使用的构造方法
    参考:
    https://www.cnblogs.com/xiaoxi/p/6089984.html
  • 相关阅读:
    语言模型工具kenlm安装
    linux操作系统远程连接方法
    Windows操作系统远程连接方法
    Majority Number III
    Majority Number II
    不同颜色在Halcon中的色相值规律
    流程图
    Redis实战(24)使用rdbtools工具来解析redis rdb文件
    EasyExcel
    pktgen 使用小记
  • 原文地址:https://www.cnblogs.com/youdream/p/8926270.html
Copyright © 2011-2022 走看看