云和数据面试题之一HASHMAP精讲

JAVA系列面试题

特点

1.高频面试

2.力求精深

3.贴近企业

4.迭代升级

1.HashMap的数据结构

基本功的问题,难度指数:1星;

1.7 数组+链表;

1.8 数组+链表+红黑树

2.当两个对象的 hashCode 相同会发生什么?

基本功:难度指数:1星

有可能会一致,也有可能不一致。还有一个需要判断的地方,内容是否一致。

在HashMap这种数据结构上,存储的元素,hashCode一样,如果说,内容一致,则不能添加到同一个HashMap对象;否则,内容不一致,在此结构之后,变成链表格式。

3.初始容量是多少?

基本功:难度指数:1星

16:DEFAULT_INITIAL_CAPACITY = 1 << 4;

4.链表什么时候变成红黑树?

基本功,难度指数:2星

首先是HashMap数组的存储结构,在hashCode()冲突的时候,长度够用情况下,变成链表格式;

其次:长度》=8,最小容量是64的情况下,会变成红黑树。

5.如何动态扩容?

基本功,难度指数:2星

负载因子:加载因子,来自于数学“泊松分布”。0.75

扩容的情况下:容量负载因子=16.75=12,也就说,当数组长度,存储元素个数超过12的时候,就开始扩容,扩容的时候,直接翻倍。16*2=32。容量2倍。

详见代码。

6.如何一次性设置1024元素,不扩容?

难度指数:3星-4星

考察知识点:HashMap基本功。

设置一个超过阈值范围的,初始容量: 初始容量*0.75>1024

这里使用到了Oracle官方的插件

<!--Oracle官方提供的 JAVA微基准测试套件-->
        <dependency>
            <groupId>org.openjdk.jmh</groupId>
            <artifactId>jmh-core</artifactId>
            <version>1.36</version>
        </dependency>
        <dependency>
            <groupId>org.openjdk.jmh</groupId>
            <artifactId>jmh-generator-annprocess</artifactId>
            <version>1.36</version>
            <scope>provided</scope>
        </dependency>

java代码测试

@BenchmarkMode(Mode.AverageTime)                                        // 测试完成时间
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@Warmup(iterations = 2, time = 1, timeUnit = TimeUnit.SECONDS)          // 预热 2 轮,每次 1s
@Measurement(iterations = 5, time = 3, timeUnit = TimeUnit.SECONDS)     // 测试 5 轮,每次 3s
@Fork(1)                                                                // fork 1 个线程
@State(Scope.Thread)                                                    // 每个测试线程一个实例
public class AliQuestion{
    
    
    public static void main(String[] args) throws RunnerException {
    
    
        // 启动基准测试
        Options opt = new OptionsBuilder()
                .include(AliQuestion.class.getSimpleName()) // 要导入的测试类
                .build();
        new Runner(opt).run(); // 执行测试
    }

    @Benchmark
    public void noSizeTest(Blackhole blackhole) {
    
    
        Map map = new HashMap();
        for (int i = 0; i < 1024; i++) {
    
    
            map.put(i, i);
        }
        // 为了避免 JIT 忽略未被使用的结果
        blackhole.consume(map);
    }

    @Benchmark
    public void setSizeTest(Blackhole blackhole) {
    
    
        Map map = new HashMap(1367);
        for (int i = 0; i < 1024; i++) {
    
    
            map.put(i, i);
        }
        // 为了避免 JIT 忽略未被使用的结果
        blackhole.consume(map);
    }
}

效率对比

在这里插入图片描述

/ 为了避免 JIT 忽略未被使用的结果
blackhole.consume(map);
}
}


效率对比

[外链图片转存中...(img-a1XmfcEK-1703595611311)]

猜你喜欢

转载自blog.csdn.net/zhangchen124/article/details/135231337