16

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

 4 years ago
source link: https://gudong.name/2019/11/29/hash-map-think.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

在面试中,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 应用开发者真正的水平?

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

总结

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

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

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

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


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK