JDK成长记1:天呐!学完这个成长记,再面试100次也不用再愁Java基础知识了!

file

file

为了让广大工程师们更好的提升个人技术能力和思想,我将开通一个大专栏《成长记》系列,会包含Java架构和大数据从底层技术到源码原理的分享,敬请关注!

无论作为Java程序员还是大数据工程师的你,工作时间久了,可能很多底层和基础技术已经还给你的大学老师或者80%已经丢在脑后了。比如你可能已经不记得网络模型有几层?TCP三次握手,四次挥手的流程你可能也说不上来了?JDK集合和并发包的源码你可能压根没有看过,又或者很早之前你看过,但不记得了。甚至并发包下很多东西都没有用过。你也可能正在准备跳槽或者面试,被各种基础虐过,又或者你看某个技术框架的源码晦涩难懂,无从入手……

或多或少你可能都遇见过这样的场景,所以在这个成长记系列中,就是让你解决这些问题。我不仅会教你学会这些底层和基础知识,解决上面这些问题,成长记更重要的核心是:除了给你带来能力、知识、方法的成长,更重要的是观念和心态的成长。所以你可以在每一个专栏中学习到很多观念、思想,这将潜移默化的提升你的认知,让你得到的不仅仅是 “鱼”,更是会得到“渔”。

作为《成长记》的第一个专栏,《JDK成长记》这篇专栏主要让你掌握以下三点:

  1. JDK的源码中集合和并发包下的各种类的底层原理,跳槽面试遇见这块知识不再心虚。
  2. 在使用JDK集合和并发时,能更得心应手,能更好的解决遇见的各种线上问题。
  3. 更主要的是让你学会基本的阅读源码的思想。

作为程序员的我们,其实建造了整个社会计算机技术的底层系统。但是,除此之外,你更要建立自己思想观念的底层系统,这个底层系统不仅会对你技术能力的提升和职业发展有帮助,更会帮助你的生活,乃至整个人生变得更美好。而每个人的底层系统都不尽相同,所以都需要不断的修正、不断的夯实。这个是《成长记》给你们的另一种成长。跟随《成长记》的各个专栏,相信你将学到的不仅仅是知识和技能,还会有更多的思想和观念。

好了,接下来,就让我们进入JDK源码的大门吧!

file

file

file

作为Java工程师,ArrayList你应该非常熟悉。当你还是一个菜鸟Java工程师的时候,面试时你可能经常被问到:你能说说ArrayList的基本原理和优缺点吗?它默认容量大小是多少呢?怎么进行扩容的呢?诸如此类,不知道各位当初是怎么回答的。或者可能你已经是一名老鸟的工程师了,是不是也常忘记给ArrayList设置容量大小。又或者老鸟的你可能要跳槽了,所以让我们一起回顾下ArrayList的基础知识吧!

ArrayList基本原理

一句话讲,在JDK中,ArrayList底层基于一个Object[]数组来维护数据。

ArrayList优缺点

缺点:

  1. 容量受限时,需要进行数组扩容,进行元素拷贝会影响性能

  2. 频繁删除和往中间插入元素时,产生元素挪动,也会进行元素拷贝,影响性能

  3. 不是线程安全的

优点:

  1. 随机访问某个元素,性能很好

建议:

维护顺序插入的数据,遍历或者索引访问很方便,预估数据大小,避免频繁扩容。不适合频繁的删除和中间插入等操作和多线程操作。

你回顾了ArrayList的基本的原理和优缺点后,各位最好可以自己跟别人茶余饭后的聊一聊,问下他,这个问题,或者你给他讲讲,来巩固下这个基础知识。

接下来,你就可以开始看ArrayList的源码了,在看之前,你要先了解下看源码的最基本的一条思想。

file

file

当你打开源码,肯定不是直接就开始从头开始看一遍,这样会一头雾水,所以肯定是有思路和方法可寻的。

在这里,首先你要明白,看核心源码和精读源码的方式不太一样。看核心源码,也就是核心部分的源码,一般也就是10-30%。你应该都是从一些入口开始看起,但是如果你要精读源码,除了在阅读核心源码的基础上,你还需要将源码拆解开来,研究每一个组件的各个作用,之后再从入口开始,一行一行都读懂。

这其实体现了一个很重要的思想,无论做什么事,先摸脉络,后看细节。就比如瞎子摸象一样,你每个部位摸了一遍,但是没有全局的认识,这就很搞笑了。所以一般你应该先看核心源码再精读源码。

file

除了上面的思路,读源码其实还有很多技巧和方法,这个见仁见智,在这个成长记中相信你也会学到很多。但是有一点我要跟大家说的是,你可能在网上看到有很多diss这个看源码方式,那个看源码方式,也有各个博客,论坛各种五花八门的方式看源码。所以很多时候,你一定要透过现象看本质,其实看源码的方法和技巧,没有优劣之分,这要围绕你的目标和场景来具体决定,选择合适的方式才是最好的。你想下,很多事情都是不是这样的?大家不能一概而论,这个思想很重要,你要学会要站到一定高度看问题,别总是陷入问题本身。

根据我的经验和了解到的各个阅读源码的方法,你可以在本章结尾看到总结。

file

看源码前,按照之前提到,你应该先看脉络,再看细节

比如,当你看ArrayList的源码,可以先看看它有哪些核心成员变量,刚开始,你肯定不知道哪些是核心的变量,所以简单过一下即可,根据名字,类型,大概看看即可,看不懂也没关系。之后看下有哪些方法,根据名字大概猜猜是做什么的。做这些主要让你了解基本的脉络,对源码有个大体映象,千万不要在这里细究源码。

在Intellij或Eclipse下,如果是使用eclipse快捷键的话,你可以通过Ctrl+O看到这个类的大体情况:

file

这里,你主要有哪些方法和成员变量、内部类就可以了。

比如,你可以看到ArrayList源码中,有几个静态成员,从名字上看像是容量大小相关的,还有size和elementData等成员变量,有几个构造函数,

有一些ensureCapacity,calculateCapacity等私有方法,感觉也是和容量大小有关的。因为Capacity就是容量,大小的意思。还有很多你应该常用的方法add(),set(),get()等等。

最后下面,还有几个内部类SubList和Itr和ListItr什么的,如下图所示:
file

好了,其实你看到这里就可以了,起码对ArrayList的源码有了个大概认识,这就是先脉络后细节的思想体现。

之前我们提到过,看核心源码一般是从入口开始,也就常说的自顶而下。

首先你要有个代码Demo。之后从它的入口开始看起,代码清单如下:

import java.util.List;


public class ArrayListDemo {
  public static void main(String[] args) {
      List<String> list = new ArrayList<>();
  }
}

这个很简单的代码,入口是main函数,第一行就是创建了一个ArrayList,里面的元素都是String类型,使用默认无参的构造函数,你点击构造函数,进入源码来看看:

private static final  Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
transient Object[] elementData;private int size;
public ArrayList() {
    this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}

可以看到,有一个成员变量叫elementData的Object[]数组,这个印证了我们之前提到过的ArrayList底层基本原理是数组。而且你记不记得之前,在看ArrayList源码脉络的时候是不是已经看到过了这个变量呢?

默认无参的构造函数让elementData指向了和空数组DEFAULTCAPACITY_EMPTY_ELEMENTDATA一样的地址。

如果各位如果有印象的话,DEFAULTCAPACITY_EMPTY_ELEMENTDATA这个变量也是你之前看到过的静态成员变量。

上面还列了一个成员变量size,你可以连蒙带猜一下,它应该是描述数组大小的变量。而且size是int类型,大家都知道int的默认值是0。

所以小结一下,你知道了new ArrayList<>()这个动作,底层是使用了Object[]数组,但是这个数组默认是空的,大小为0。

上面我们主要通过看脉络,连蒙带猜的思想,看了一个简单的不能再简单的源码。不知道你有没有感觉到这两个思想。有了初步的感受。接下来我还要引入一个非常关键的方法:画图

其实在我看来,没有什么算法不能用画图和举例理解的,起码一般大多数算法都可以理解的,小灰算法图解微信公众号就是最好的例子。在阅读源码的时候也是,画图能更好的理解源码,能让我们站在高处,高屋建瓴的摸清楚源码的脉络,也能梳理出来主要思路,让我们去更好的阅读源码。所以大家不能忽视了,再简单的场景,也要养成这个画图这个思路习惯。

上面ArrayList的无参构造函数的源码,基本上如下图所示:

file

好了,今天知识就分享到这里,下一节我们来基本的使用一下ArrayList,调用它的几个常用方法,再来看看它常用方法的源码和原理。前几节的节奏我会尽量慢一些,大家不要着急,后面会越来越精彩!

继续往后看有彩蛋哟~

file

首先说源码的获取,一般以下几种

  1. 下载源码导入Intellij等IDE,来阅读代码
  2. 开启Maven自动下载源码的功能
  3. 自己从官方(如Github)或者Maven仓库手动下载源码

这几种都可以获取到源码,各有各的适用场景,比如如果你想写些注释,就需要导入到IDE才行,比如你想Debug源码,不需要把源码导入到IDE中,适用2,3的方法都可以。又比如有些代码Maven仓库根本没有,只能从Github或官方下载了。

其次,我们聊下,阅读静态源码还是动态源码?这个取决于源码的复杂程度、你阅读源码的能力等。如果是一些简单的源码或者你有很多阅读源码的经验了,一般阅读静态源码就足够了。但是如果是小白,或者真的源码比较复杂,又或者你需要具体看看执行过程中的某个变量和返回值,你肯定需要debug进行动态源码阅读了。

阅读源码的技巧,说白了就是一些思想,常见的有:

  • 自顶而下或自底而上

  • 抓大放小

  • 先脉络,后细节

  • 连猜带蒙

  • 结合功能场景逐个分析

方法就更多了,主要有:

  • 看注释

  • 加注释

  • 画图

  • Debug

  • 观察日志或增加日志

  • ……

上面这些,之后我都会带大家使用到的,并且你会学会在合适的场景使用上,你只要持续关注成长记就可以了。

最后,还要说一点,有人说阅读源码,需要很多技术基础,的确没错。但是也分是什么样的源码,如果只是简单的源码,需要的基础知识会很少,比如JDK的源码。但是如果比较难的源码,Zookeeper、HDFS、Kafka、Dubbo这些源码,就需要掌握Netty,NIO,网络,Java集合和并发等基础才能看得更好。当然如果没有这些基础也不是不能看的,就是理解可能不会深,对源码最后可能只是初步了解。所以还是那句话,不要一概而论。

本文由博客一文多发平台 OpenWrite 发布!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
java面试笔试资料包括JAVA基础核心知识点深度学习Spring面试题等资料合集: JAVA核心知识点整理-282页 Java与哈希算法.docx Java中Lambda表达式的使用.docx JAVA多线程之线程间的通信方式.docx Java注解详解.docx Java线程池.docx JDK1.8Stream操作.docx JDK8有新特性.docx JVM堆三代.docx JVM的垃圾回收机制详解和调优.docx Spring源码分析之IoC.docx 关于线程和线程池的学习与使用.docx 深入理解JVM垃圾回收机制.docx 深入理解多线程实现的另一种方式Callable.docx 红黑树简介.docx 线程死锁及解决办法.docx 线程锁之重入锁.docx 线程间的通信.docx 虚拟机内存结构和垃圾回收docx.docx 锁分类的了解.docx 集合的扩容机制.png SpringMVC部分.docx Spring部分.docx 第一题.pdf 第七题 谈谈MySQL支持的事务隔离级别 (1).pdf 第三题 对比HashTable HashMap TreeMap有什么不同.pdf 第二题 Exception Error区别.pdf 第五题 如何保证集合是线程安全的.pdf 第八题 Java并发类库提供的线程池有哪几种 分别有什么特点.pdf 第六题 synchronized和ReentLock有什么区别.pdf 第四题 ArrayList LinkedList Vector的区别.pdf docker讲得最清楚.doc Dubbo是什么?能做什么?.doc java 基于TCP协议的Socket编程和通信.doc Java面试高级篇—说说TCP,UDP和socket,Http之间联系和区别.doc MySQL千万级的大表要怎么优化(读写分离、水平拆分、垂直拆分).doc redis缓存雪崩、缓存穿透、缓存预热、缓存更新、缓存降级.doc RPC (Remote Procedure Call)即远程过程调用.doc Spring 面试问题 TOP 50(干货推荐收藏必备).doc springboot常见面试题.doc svn和git的区别及适用场景.doc ZooKeeper.doc 为什么分布式一定要有Redis.doc 分布式、高并发、多线程,到底有什么区别.doc 分布式事务.doc 四款消息队列大比拼.docx 多台web服务器之间共享session.docx 消息中间件Kafka与RabbitMQ.doc 电商项目描述注意点.doc 秒杀业务的流量削峰场景如何解决.doc 面试题:Kafka、ActiveMQ、RabbitMQ、RocketMQ 有什么优缺点.doc

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值