由 HashMap 引申出的技术深度讨论

咕咚 于 2019-11-29 发布

在面试中,HashMap 是一个被问到概率很大的一个知识点,因为它本身是一种非常好的数据结构,而且从 HashMap 中可以引申出数组、链表、红黑树、扩容、优化、线程同步等诸多考点,所以很多的面试官都会从 HashMap 开始考察一个人的 Java 水平。

好文推荐

所以有必要认真研究下 HashMap 的具体原理,这里我极力推荐一篇16年的文章,出自美团点评的公众号-美团点评技术团队。Java8系列之重新认识HashMap

这篇文章非常棒,把 HashMap 的方方面面都讲了个遍,同时还不缺深度。读罢,对作者这种刨根问底的技术态度也敬佩有加。

现在的很多面试中,面试官对技术深度的要求都开始变得高起来,如果你只是知道一些表面的东西,是显然不行的。所以对待技术,深度是一定要要有的,而且这个东西很容易考察。

那么一般的面试官会怎么考察你的技术深度呢?这里就以 HashMap 为例来看看面试官怎么一步步来跟你聊 HashMap 的。

问题来了

首先问一个简单的问题作为开始。

1、HashMap 和 Hashtable 的区别?

前者线程不同步,在单线程条件下操作性能较好,后者线程同步,在多线程条件下可以正确操作,不会发生多线程下的操作问题。

2、如何使 HashMap 线程同步?

使用 Collections 的 util 方法 synchronizedMap 就可以让原本不支持线程同步的 HashMap 支持线程同步。

答到这一步,说明你对技术细节掌握的还不错,接着问

3、Collections 的 synchronizedMap 方法是怎么实现让原本不线程同步的 map 支持线程同步的?

如果你看过源码,你会这样回答

“Collections 内部有一个实现了 Map 接口的 SynchronizedMap 内部类,这是一个实现线程同步的 map 类,具体线程同步就是在所有的方法实现中都使用 synhronized 块达到线程同步,不过具体的方法实现统统使用 synchronizedMap 方法传递进去 map 来完成,如下所示

    @Override
    public boolean remove(Object key, Object value) {
        synchronized (mutex) {
            return m.remove(key, value);
        }
    }

可以看到 SynchronizedMap 在实现 remove 方法时最终是用传递进来的 map, 只不过加了 synchronized 块,其实这就是典型的装饰设计。”

如果你没有看过源码,面试官可能会问题,如果让你自己实现,你怎么实现,其实这里要实现线程同步,终归需要使用 synchronized 来完成,所以思路还是通过这种装饰设计。当然这里如果看过源码你会说的很轻松。

这时如果回答的没问题,面试官想进一步增加深度,可能会问下一个问题。

4、如果需要在多线程条件下使用 HashMap,除了使用 Collections 的 util 方法,还有什么方法可以更简单的做到线程同步?

如果此时你能提到 ConcurrentHashMap,那么面试官已经觉得你对 HashMap 的了解有一定的深度。接着再来一个问题。

5、ConcurrentHashMap 是怎么做并发控制的,相比 Hashtable 有什么优势吗?

此时,你心想『 我擦?还有完没完,这要问到地老天荒啊… 』

如果你此时说『 ConcurrentHashMap 引入了分段锁的机制,该机制对并发控制做了优化 』,那么面试官会点点头,心想『 这小伙还不错~ 』,当然他可能会继续追问,

6、你跟我讲讲什么是分段锁?

这时即使你对这个概念不清楚,你如实回答,面试官对你印象也不会很差,因为你对一个技术点的了解已经有了相当的深度。当然如果你能就分段锁可以展开跟面试官大聊一番,那最好不过了,不过能问这个问题的,面试官本身应该对这些东西有一定的了解,否则他也不会问到这个问题。

到此为止,一个问题算是问完了,同时你也可以看到从一个基本的知识点,可以向下衍生出多少问题。

当然我说的这些上面那个链接大都提到了,而且文中汇集的知识点更多更全,建议认真阅读,当你读懂了,关于 HashMap 的一些基本问题大都能答个八九不离十。

如何考察一个 Android 面试者的能力水平?知乎上 @扔物线 前辈有一个不错的回答,你也可以顺便看看。

面试时,问哪些问题能试出一个 Android 应用开发者真正的水平?

这里,如果上面说的有任何问题欢迎留言指正。

总结

其实写完文章加上最近的一些经历,个人对技术深度有了一个更清晰的认识,而且自己在很多技术点上确实也有很多不足,不过反过来说,让一个人对每一个技术点都要求有很深的了解也是不现实的。

但是如果你在简历上写了你的技能,就表示你对他了解或者掌握,所以你要对自己的简历负责。一般有水平的面试官都会从简历中提取一些技术点,然后像上面那样一点点深入,逐步的考察面试者对知识的掌握程度。这也在印证另一个道理:简历上写自己会的东西或者掌握了的东西,不要粘贴复制别人的模板,否则在面试时会很惨。

另外。我还是觉得在实际工作中,面对一个实际具体的问题,应该保持啃透的态度,而不是能通过就行的态度。比如最近你在做应用的启动优化,那么你就应该先详细了解应用的启动过程,以及启动时长统计,然后通过打点或者工具去分析应用启动过程。总之每个步骤自己都应该非常了然于胸。

当然,说到容易做到难,更多的道理还需要自己动手才会产生好的结果。