Java原来还可以这么学:如何搞定面试中必考的集合类

Java原来还可以这么学:如何搞定面试中必考的集合类

原创声明

本文作者:黄小斜

转载请务必在文章开头注明出处和作者。

系列文章介绍

本文是《五分钟学Java》系列文章的一篇

本系列文章主要围绕Java程序员必须掌握的核心技能,结合我个人三年多的Java学习和工作经历,总结和沉淀下来的方法论,希望能让Java学习这件事变得更简单,作者目前在阿里做Java,忙里偷闲分享一些技术文章

系列文章将会把一些技术学习方法、过程、要领与我的学习经验相结合,更加浅显易懂,并且我也会把我学习时用的资料,书籍和文章拿出来分享给大家,节省你我的时间。所谓授人以鱼也要授人以渔,是本系列文章希望达到的目标。

简介

最近的你有没有参加Java面试呢?你有没有发现,Java面试中总是爱考一类问题,那就是集合类,为什么对集合类的考察会如此受欢迎呢,其实啊,主要是因为集合类的使用范围实在是太广了,不管是开发中,还是框架源码中,往往都会用到集合类。

像咱们平时面试经常遇到的问题,比如hashmap、linkedlist,或者是阻塞队列等集合类,往往都是咱们工作中需要用到的一些工具。

根据百度百科的定义,集合类是Java数据结构的实现。Java的集合类是java.util包中的重要内容,它允许以各种方式将元素分组,并定义了各种使这些元素更容易操作的方法。Java集合类是Java将一些基本的和使用频率极高的基础类进行封装和增强后再以一个类的形式提供。集合类是可以往里面保存多个对象的类,存放的是对象,不同的集合类有不同的功能和特点,适合不同的场合,用以解决一些实际问题。

可以看出,集合类就是util包里的一类工具,用好集合类,能帮忙我们解决很多工作中的问题,而学好集合类,才能让我们在面试中无往而不利。

为什么面试总爱问Java集合类

有Java面试经历的朋友们都知道,Java面试最喜欢问的集合类问题就是:hashmap和hashtable的区别,linkedlist和arraylist的区别是什么,稍微复杂一点的话,则可能会问:hashmap的初始容量是多少,它的扩容方式是什么样的,它的内部结构是什么样的。

诸如此类问题,深受广大互联网公司欢迎,当然,这些都是Java初级面试的问题,算是基础中的基础了。

为什么面试官总是喜欢问集合类呢,依我看来,有这么几个原因:集合类里是Java里使用范围最广,使用频率最高的api了,并且这玩意的通用性很强,很多框架都得使用,如果想要看懂框架源码,那么你就必须要掌握集合类的知识。

其次,集合类里蕴藏了很多数据结构与算法的知识,正因为如此,如果你能正确地理解这些集合类,那么想必你对于数据结构和算法的理解也差不到哪。

还有就是,Java集合类里的很多源码都是几个Java创始人大牛写的,代码质量和风格都非常值得我们学习,里面用到的一些算法和解决问题的方法也非常值得效仿,而这些,都必须要通过学习集合类的源码只是才能够做到。

如何学习Java集合类

第一次接触

第一次接触集合类,想必大家的方式都差不多,应该就是用了一个叫做List的东西,以及它的子类ArrayList,通过它的api我基本上就可以了解它有哪些功能了,无非就是增删改查呗。

虽然这东西看起来没有什么难度,但是面试题里可不会直接问你它的api有哪些,恰好一次面试,面试官就问了我ArrayList相关的问题:ArrayList的底层数据结构是什么,它和linkedlist的区别是什么,它的扩容方式是怎么样的,它是线程安全的么,这些看起来很简单的问题,我当时一个都回答不上来。

在没有面试以前,你永远不知道自己学的其实非常少。

在第一次面试受到打击之后,我便决定开始面向面试复习,把这类问题统统找出来搞懂。

面向面试复习

既然我们的目标是面试,那么就必须要搞懂面试题都喜欢考哪些集合类的问题。

于是,上网找面试题就成为一件重要的工作,我花了好几天的时间到网上搜刮了各类Java面试题,不管是BAT的面经,还是网上整理比较详细的300道面试题,我都找来看了,虽然有很多重复的题目,但是大部分题目都是我没见过的。

原来Java集合类可以问出这么多问题来。

就拿ArrayList来说,可以问数据结构,可以问扩容和一些方法的实现,也可以问你它和linkedlist、vector的区别,复杂一点的,甚至会问你线程安全的ArrayList是怎么实现的,删除它里面的某个元素应该如何删除。

看起来简单问题的背后,其实都有很多坑,我也是看了很多面试题解析之后才慢慢了解到的。

Java集合类里最常问的一类题目,无疑就是hashmap了,这玩意实在是太热门了。

hashmap的数据结构是怎么样的,1.8和以前有什么区别么,put方法和get又是怎么实现的,扩容是如何进行的,甚至还会问你具体的hash算法是怎么实现的。

更复杂的还有呢,并发工具类里的linkedhashmap和hashmap有何区别,它又是如何实现的呢,这就牵扯到很多并发编程的相关知识了,这部分我们留着下次讲并发编程的内容时再来一起探讨。

看过足够多的集合类面试题,参加了足够多的面试之后,我似乎对这些面试题已经无感了,毕竟熟读唐诗三百首,不会做诗也会吟啊,就这么几种题型,每天回答个三五遍,几个月里都忘不掉了。

但是,事情并没有我想象的这么简单。虽然这些面试题多看几遍确实容易记住,但是记忆不能当饭吃,面试时万一想不出来那可是硬伤,更重要的是,很多时候,面试官问问题都不会按常理出牌,这些网上能找到的面试题,他们一样可以用别的方式不停地深挖,直到他了解到你的水平为止。

如果你只会简单地告诉面试官那些死记硬背的答案,而在他深挖集合类实现细节的时候没能答好的话,也是很扣分的,特别是对于美团、阿里这种Java大厂来说,他们抠细节的能力绝对超出你的想象。

搞懂原理最重要

既然面向面试题复习的方式不一定总是奏效,那么有没有更加好的选择呢。

还真有,那就是,理解技术的实现原理。面试题是个好东西,但是我们不能只停留在简单的一问一答上,并不是说你搞懂了这个面试题的答案是什么就行了。

举个例子,比如说,Java中的hashmap的数据结构是什么样的,它的扩容方式又是如何的,这种时候,如果光是依靠面试题的答案去理解,多少会有一些片面。

你可能可以大概答出个三四点,但是其实你可能也没真正理解为什么要这样做,或者实现细节是怎么样的。

实际上,要想真正了解hashmap的数据结构和实现原理,最好的办法就是去看源码,有的小伙伴肯定会眉头一皱,源码这么复杂,看不懂怎么办,没关系,自己看不懂,还可以让别人教你呀,网上有很多源码解析的博客,我自己也整理了不少,发在咱们的技术博客how2playlife.com上。

为什么要看源码呢,比如hashmap,它的类定义里就已经展示了它的数据结构,我们可以从中看出它是一个数组加链表的数据结构,这些成员变量都是在hashmap这个类里定义好的,并且,再看看它的put和get方法,你就可以知道它是如何插入和查询数据的,并且,在1.7和1.8源码比较的过程中,你也可以更好地理解这两个版本源码的区别。

而对于扩容方法也是一样的,在hashmap的扩容方法中,你可以看到的是,hashmap为了把原来的数据搬到扩容后的数据结构中,就必须要进行重新哈希,调整每个元素的索引和位置,这里面涉及了一系列算法,不看源码的话,你根本不知道扩容过程中到底发生了什么。

当你看完源码,不管你遇到的是原来那些面试题,还是有一些新的面试题,你总会发现其实都差不多,万变不离其宗,只要你理解了底层的实现之后,对于这些面试题应该都能够比较好地应付。

有些事,你必须要经历过,才能明白,有些坑,你不用自己去踩,因为我已经踩过了

推荐资源

书籍

实际上市面上并没有针对Java集合类专门出的书籍,毕竟集合类只是JDK里的一小部分。

在之前那篇关于学习Java基础的文章里,我推荐给了大家一些书籍,里面也讲了很多关于集合类的东西。

《Java核心技术卷一》

《Java编程思想》

博客

Java技术仓库《Java程序员复习指南》

https://github.com/h2pl/Java-Tutorial

整合全网优质Java学习内容,帮助你从基础到进阶系统化复习Java。

我的个人博客:https://how2playlife.com/

社区:

CDSN我就不推荐了,反正百度你们搜一下也都是CSDN的结果

这里重点推荐两个社区,实打实的有很多干货,对文章要求比较高,我的很多文章质量都达不到他们的要求。

1、掘金

https://juejin.im/user/5b1d0d34e51d4506d936f561

2、开发者头条 https://toutiao.io/subjects/329410

总结

关于如何学习Java集合类,并且搞定相关面试题,我们今天就讲到这里了,如果还有什么疑问也可以到我公众号里找我探讨,后续会有更多的文章推出,包括如何系统性地学习JavaWeb,如何系统性地学习Java核心技术和底层原理,以及如何系统性地学习后端技术。敬请期待。

对了,你想问我文章里提到的书籍和视频去哪找?我已经给你准备好了

文中提到的资源都可以免费领取,在我的公众号【程序员黄小斜】回复“Java基础”即可免费领取对应的资源。

写在最后

如果觉得本文对你有帮助的话,请你也不要吝啬你的“好看”哈,转发朋友圈就是对我最大的支持啦,你们的支持是对我最大的鼓励。

对本系列文章有什么建议和意见,也欢迎留言告诉我,期待你的回馈。另外本系列文章也会制作成相应的视频放到B站,赶紧来B站关注我吧。

微信公众号:程序员黄小斜
知乎:黄小斜
B站:黄小斜
上一篇:Selenium 初见


下一篇:siblings() 方法