@产品

程序员:基础的重要性,关系到你未来的薪资

2018-12-09  本文已影响15人  M16老师
image.png
  1. String类为什么是final的

主要是为了”安全性“和”效率“的缘故,因为:

1、由于String类不能被继承,所以就不会没修改,这就避免了因为继承引起的安全隐患;

2、String类在程序中出现的频率比较高,如果为了避免安全隐患,在它每次出现时都用final来修饰,这无疑会降低程序的执行效

率,所以干脆直接将其设为final一提高效率;

  1. HashMap的源码,实现原理,底层结构。
    HashMap就是数组+链表的组合实现,每个数组元素存储一个链表的头结点,本质上来说是哈希表“拉链法”的实现。

HashMap的链表元素对应的是一个静态内部类Entry,Entry主要包含key,value,next三个元素

主要有put和get方法,put的原理是,通过hash%Entry.length计算index,此时记作Entry[index]=该元素。如果index相同

就是新入的元素放置到Entry[index],原先的元素记作Entry[index].next

get就比较简单了,先遍历数组,再遍历链表元素。

null key总是放在Entry数组的第一个元素

解决hash冲突的方法:链地址法

再散列rehash的过程:确定容量超过目前哈希表的容量,重新调整table 的容量大小,当超过容量的最大值时,取

Integer.Maxvalue

  1. 什么是Java集合类?说说你知道的几个Java集合类。
    集合类存放于java.util包中。

集合类存放的都是对象的引用,而非对象本身,出于表达上的便利,我们称集合中的对象就是指集合中对象的引用(reference)。

集合类型主要有3种:set(集)、list(列表)和map(映射)。

集合接口分为:Collection和Map,list、set实现了Collection接口

  1. 描述一下ArrayList和LinkedList各自实现和区别
    ArrayList,LinkedList都实现了java.util.List接口,

ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。
对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。
对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。

  1. Java中的队列都有哪些,有什么区别
    Java中的队列都有哪些,实际上是问queue的实现有哪些,如:ConcurrentLinkedQueue、LinkedBlockingQueue 、

ArrayBlockingQueue、LinkedList。

关于ConcurrentLinkedQueue和LinkedBlockingQueue:

LinkedBlockingQueue是使用锁机制,ConcurrentLinkedQueue是使用CAS算法,虽然LinkedBlockingQueue的底层获取锁也是使用的CAS算法
关于取元素,ConcurrentLinkedQueue不支持阻塞去取元素,LinkedBlockingQueue支持阻塞的take()方法,如若大家需要ConcurrentLinkedQueue的消费者产生阻塞效果,需要自行实现
关于插入元素的性能,从字面上和代码简单的分析来看ConcurrentLinkedQueue肯定是最快的,但是这个也要看具体的测试场景,我做了两个简单的demo做测试,测试的结果如下,两个的性能差不多,但在实际的使用过程中,尤其在多cpu的服务器上,有锁和无锁的差距便体现出来了,ConcurrentLinkedQueue会比LinkedBlockingQueue快很多:ConcurrentLinkedQueuePerform:在使用ConcurrentLinkedQueue的情况下100个线程循环增加的元素数为:33828193
LinkedBlockingQueuePerform:在使用LinkedBlockingQueue的情况下100个线程循环增加的元素数为:33827382

  1. 反射中,Class.forName和classloader的区别
    Java中Class.forName和classloader都可以用来对类进行加载。

Class.forName除了将类的.class文件加载到jvm中之外,还会对类进行解释,执行类中的static块。

而classloader只干一件事情,就是将.class文件加载到jvm中,不会执行static中的内容,只有在newInstance才会去执行static块。

Class.forName(name,initialize,loader)带参数也可控制是否加载static块。并且只有调用了newInstance()方法采用调用构造函数,创建类的对象。

  1. Java7、Java8的新特性(baidu问的,好BT)
    以下特性为个人比较关注的特性,并不齐全;想了解更多,请自行搜索官方文档。

Java7特性:

1.switch case可以使用String,原来只能用int和char;

2.支持2进制0b开头;支持数字中间有下划线,解析时自动剔除;

3.一次抓多个异常;用|隔开;

4.try-with-resource,在try中打开资源,系统自动在使用完后关闭;

  1. Map<String, List<String>> anagrams = new HashMap<>(); 对抗Google的guava.

6.集合类可以像js中的数组一样赋值和引用了。

List<String> list = ["item"];

String item = list[0];

Set<String> set = {"item"};

Map<String, Integer> map = {"key" : 1};

int value = map["key"];

  1. 把字符串常量池从permgen区移到了堆区;导致String.intern()方法在1.7之前和之后表现出现不一致;

Java8特性:

1.lambda表达式;

2.新增stream,Date,Time,Base64工具类;

3.使用metaspace,元空间替代permgen区;

4.类依赖分析器:jdeps,可以以包,目录,文件夹作为输入,输出依赖关系,没有的会显示 not found

5.jjs,可以执行JavaScript代码;

  1. Java数组和链表两种结构的操作效率,在哪些情况下,哪些操作的效率高
    数组在随机访问数据、随机增加数据、随机删除数据的执行效率上比链表的效率高,数据量越小,两者之间效率的差距越小,数据量越大差距越大。

  2. Java内存泄露的问题调查定位:jmap,jstack的使用等等
    详细解析:https://blog.csdn.net/sinat_29581293/article/details/70214436

  3. string、stringbuilder、stringbuffer区别
    这三个类之间的区别主要是在两个方面,即运行速度和线程安全这两方面。

首先说运行速度,或者说是执行速度,在这方面运行速度快慢为:StringBuilder > StringBuffer > String
String最慢的原因:

String为字符串常量,而StringBuilder和StringBuffer均为字符串变量,即String对象一旦创建之后该对象是不可更改的,但后两者的对象是变量,是可以更改的。

  1. 再来说线程安全

在线程安全上,StringBuilder是线程不安全的,而StringBuffer是线程安全的

如果一个StringBuffer对象在字符串缓冲区被多个线程使用时,StringBuffer中很多方法可以带有synchronized关键字,所以可以保证线程是安全的,但StringBuilder的方法则没有该关键字,所以不能保证线程安全,有可能会出现一些错误的操作。所以如果要进行的操作是多线程的,那么就要使用StringBuffer,但是在单线程的情况下,还是建议使用速度比较快的StringBuilder。

  1. 总结一下

String:适用于少量的字符串操作的情况

StringBuilder:适用于单线程下在字符缓冲区进行大量操作的情况

StringBuffer:适用多线程下在字符缓冲区进行大量操作的情况

11.hashtable和hashmap的区别

  1. 存储结构

HashMap的存储规则:

优先使用数组存储, 如果出现Hash冲突, 将在数组的该位置拉伸出链表进行存储(在链表的尾部进行添加), 如果链表的长度大于设定值后, 将链表转为红黑树.

HashTable的存储规则:

优先使用数组存储, 存储元素时, 先取出下标上的元素(可能为null), 然后添加到数组元素Entry对象的next属性中(在链表的头部进行添加).

出现Hash冲突时, 新元素next属性会指向冲突的元素. 如果没有Hash冲突, 则新元素的next属性就是null

描述的有点模糊, 贴出源码会清晰一点:

Entry<K,V> e = (Entry<K,V>) tab[index]; tab[index] = new Entry<>(hash, key, value, e);

  1. 扩容方式


    image.png
  2. 关于null值


    image.png
  3. 线程安全


    image.png

13 .异常的结构,运行时异常和非运行时异常

大神的解释:https://blog.csdn.net/qq_27093465/article/details/52268531

  1. String a= “abc” String b = “abc” String c = new String(“abc”) String d = “ab” + “c” .他们之间用 == 比较的结果
    传送门:https://blog.csdn.net/qq_36381855/article/details/79686812

etails/17068365

上一篇 下一篇

猜你喜欢

热点阅读