面试题--Java数据类型

1、String/StringBuffer/StringBuilder 区别

        string:值不可变,每次操作生成新的对象,底层基于char数组且有final修饰,1.8后使用byte

                    数组

        StringBuffer:值可变,线程安全,多线程操作字符串对象。

        StringBuilder:值可变,线程不安全,单线程操作字符串,速度快。

2、String为什么不可变,StringBuffer为什么可变

        String:底层使用char数组,且有private、final修饰。

        StringBuffer:底层是char数组,没有final修饰,初始容量为16,存满后会调用system的

                        arraycopy方法进行扩容。

3、StringBuffer为什么线程安全,StringBuilder为什么不安全

        StringBuffer安全的主要原因是在使用的append方法上添加了synchronized锁。

        他们都继承了AbstractStringBuilder,这个类中有两个重要的变量,一个是count字符串数组长度,一个是存储字符的char数组。在多线程同时操作字符串时,count会因为没有加锁而漏加,导致字符串长度要小于实际长度。

4、ArrayList和LinkedList的区别

        ArrayList:基于数组,内存分配要求有连续性,查询时是根据下标读取,速度快,增删涉及位移操作,速度相对慢。

        LinkedList:基于链表,内存分配不要求连续性,查询需要从头到尾挨个查询,速度慢,增删不涉及位移操作,只需更改前后节点指向,速度快。

5、ArrayList和Vector的区别

        ArrayList:基于动态数组,默认创建空数组。

                          第一次添加元素扩容为10,后为1.5倍扩容。

                          多线程不安全,适合单线程操作,效率高。

           Vector:基于动态数组,默认创建容量为10的数组

                         扩充算法:增量为0,原大小乘2

                                           增量不为0,原大小乘2加增量

                          加了锁线程安全,适合多线程操作,效率低。

6、面向对象的特征

        抽象:抽象是将一类对象的共同特征总结出构造类的过程,包括行为抽象和数据抽象,抽象

                   只关注对象的属性和行为,不关注行为的细节

        封装:把过程和数据包围起来,对数据的访问只能通过已定义的方式。使模块有较好的独立

                   性、修改程序方便。

        继承:新类从现有类中派生。新类继承父类的特性。

        多态:对象的多种形态,编译和运行时类型不一样。目的:屏蔽子类差异

7、接口和抽象类

                        

 8、==和equals的区别

        ==:对于基本数据类型对比存储的值,对于引用数据类型对比的是地址。

        equals:对比两个对象存储的值。区分大小写。

9、int和integer的区别

        int:基本数据类型,默认为0,存储的数值,无需实例化。

        integer:引用数据类型,默认null,存储对象的地址,需要实例化。

10、Java集合体系

11、HashMap和HashTable的区别

        1、继承的父类不一样,HasMap为AbstractMap类,HashTable为dictionary。

        2、HashMap的key和value支持null,key为null只能由一个,HashTable都不能为null。

        3、HashMap线程不安全,多线程可能会死锁、死循环。HashTable在每个方法中都加

             synchronized锁。

        4、HashMap初始容量为16,扩容算法为2n。HashTable初始11,扩容为2n+1.

12、那种Map线程安全和性能都可以兼得。

        ConcurrentHashMap。它使用了分段锁技术,将数据分成一段一段的存储,然后给每一段数据配一把锁,当一个线程占用锁访问其中一段数据时,其他段的数据可以被其他线程访问。

13、ConcurrentHashMap的理解

        1.7:由Segment数组和HashEntry组成,还是数组加链表

        1.8:CAS和Synchronized组成,存放数据的HashEntry改为了Node节点,他的val和next都使用了Volatile修饰保证可见性,

        8在7的数据结构上做了很大改动,采用红黑树可以保证查询的效率,取消了ReentrantLock改为了Synchronized。因为8后对synchronized做了很大的优化。

14、数据结构有哪些

        集合:结构中的元素除了同属一个集合,没有其他联系

        线性:结构中元素存在一对一关系

        树形:结构中元素存在一对多关系

        图形:结构中元素存在多对多关系

        顺序存储结构:内存中是一段连续的存储单元存储数据

        链接存储结构:内存中是不连续的存储单元,

       数据索引存储结构:建立附加的索引来标识节点地址,通过索引,可以很快检索数据

       数据散列存储结构:将数据元素的存储位置与关键字间建立确定的对应关系,加快查找

15、数组和链表在内存中的存储结构有什么区别

        数组:内存中是一块连续的区域。
   
               数组需要预留空间,在使用前要申请占内存大小
        
           插入、删除数据性能较低
   
               随机读取效率高
        
           不利于扩展,空间不够需要重新定义数据。

       链表:内存中随机存放,不要求连续性。
     
            每个数据保存下一个的数据内存地址,可以通过一个元素查找它的下一个元素。
        
          增删数据性能高
   
                查询效率低
   
               不指定大小,扩展方便。

16、散列存储(Hash存储) , 什么是Hash冲突 有什么解决方案

        理解:将数据元素的存储位置与关键字之间建立确定关系的查找技术。通过把关键字的值
去访问对应的数据值的一个存储结构。
       Hash
冲突:两个不同的值计算出了相同的Hash,即两个数据在Hash表中计算出同一个下标。
       解决方案:链地址法:把Hash碰撞的元素指向一个链表。
        
                 开放寻址:冲突的key在进行Hash,计算出另一个Hash,直到不一样。
  
                      再散列法:冲突后使用不同的Hash函数。
  
                      建立公共溢表:把Hash表分为基本表和溢出表,把冲突的元素放溢出表

17、list集合如何实现根据数字排序。

        1、让list的泛型类继承Comparable接口,覆写compareTo方法,方法中自定义根据数字大小比较

        2、调用Collections的sort方法,传入一个比较器,覆写compare方法,方法中自定义根据年龄比较算法。

18、HashMap底层用到了那些数据结构。

        1.7前:数组、链表

        1.8及后;数组、链表、红黑树

19、为什么HashMap使用了链表结构

        HashMap在添加元素时,将key进行hash计算,结果模与数组长度得到一个下标,再把元素添加进去。这样可能会产生hash碰撞,不同key计算出相同的Hash值,因此它采用链表,将产生碰撞的值挂载到链表中。

20、为什么要用到红黑树

        1.7使用数组加链表会造成一个链表的元素过多,通过key值一次查找的效率较低。

        1.8后引入红黑树,如果链表长度超过8,链表就会转换为红黑树,从而减少查询时间。

21、链表和红黑树转换条件

        链表转红黑树:链表长度达到8、数组长度达到64

        红黑树转链表:树节点小于等于6.

                8:泊松分布,根据概率统计选择。

                6:防止链表和树频繁转换。

22、HashMap在什么情况下扩容。如何扩容

        初始容量为16,负载因子0.75。当数组元素大于12时,会扩容。

        0.75:负载因子过小容易浪费空间,过大容易造成更多的hash碰撞,产生更多的链表和树。

        成倍扩容:保证数组的长度是2的整数次幂。

23、HashMap如何put一个元素

        首先对keyhash运算,计算出下标。

        如果么有产生碰撞直接放在数组索引位置。

         如果产生碰撞,链接的形式存放在对应下标后面。

        如果该链表过长,就把链表转换成红黑树。

        如果节点已存在该相同的值,就把新的值替换成旧的值

        如果超过数组的要求扩容的值,就对数组进行2倍扩容

24、HashMap是如何get一个元素

        对keyhash运算,计算出下标

        在数组对应位置的下标进行比较,如果hash值相等就返回此位置的值,没有则返回null

        如果不相等代表hash冲突

        如果是链表则从头便利,比较链表中节点的key和传入的key是否相等。

        如果是红黑树,则从树中的节点去对比key

25、HashMap冲突

        两个不同的值计算出了相同的Hash,即两个数据在Hash表中计算出同一个下标。

26、除了链表如何解决HashMap冲突

        1、开放寻址:冲突的key在进行hash,计算出另一个hash直到不一样。

        2、再散列法:冲突后使用不同的hash函数。

        3、建立公共溢表:把hash表分为基本表和溢出表,把冲突的元素放在溢出表。

27、HashMap死循环         

        HashMap在扩容数组的时候,会将旧数据迁徙到新数组中,这个操作会将原来链表中的数据颠倒,比如a->b->null,转换成b->a->null。这个过程单线程是没有问题的,但是在多线程环境,就可能会出现a->b->a->b....,这就是死循环        
        在JDK1.8后,做了改进保证了转换后链表顺序一致,死循环问题得到了解决。但还是会出现高并发时数据丢失的问题,因此在多线程情况下还是建议使用
ConcurrentHashMap来保证线程安全问题。

28、LinkedHashMap与HashMap的关系

        LinkedHashMap继承HashMap,是居于HashMap和双向链表实现的。

        LinkedHashMap是有序的,HashMap是无序的。

        LinkedHashMap的双向链表是为了维护Map的迭代顺序,让迭代顺序和插入顺序一致。

29HashSetHashMap是什么关系   

        HashSet实现了set接口,只存储对象,HashMap实现了Map接口,存储的使键值对。

         HashSet底层使用HashMap实现存储,依靠HashMapkey进行存储,value默认为object对象,所以HashSet不允许重复值,判断标准为比较HashCode

30、TreeSet底层用到了什么结构来实现

        TreeSet底层是TreeMap,添加数据存入Mapkey的位置,而value的位置固定是Present

         它里面的元素是有序不重复的,因为TreeMap中的key是有序不重复的。

31、TreeSet默认是如何排序的?如何自定义排序规则?

        默认:实现了SortedSet接口,使得TreeSet具有排序功能,正序排序

         自定义:通过比较器排序,实现Comparator复写compare方法

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值