Java自学需要学多久?学习路线是怎样的?别慌这里都整理好了
这是一份非常详细的学习路线,把上面的内容学完之后,找到一份比较好的工作已经比较容易。另外,我在上面也说了,如果你觉得内容比较多自己学不完或者如果你只想找到一份小厂的开发工作的话,建议你把重心放在 Java基础、数据库、常用框架、常用工具上。像 JVM、分布式、高并发、高可用、微服务这些知识点,如果你想进大厂或者说让自己在求职的时候更有竞争力,那你就也是要多花一点时间来学习的。
学java一般要多久?
因人而异,例如一个零基础的小白自学java,每天学习8个小时来算,而且在有学习资料的基础上,每天学习,从零到找到工作,起码要半年起步,而且还要有项目经验,否则是不会有公司要你的。
而一个有一些基础的人,在经过有人系统的教学后,是可以很快学会掌握java的,大概3个月左右。不过java相对于C,C++java而言,java无疑简单了很多,不需要指针,不需要销毁对象,使得对java初学者来讲更容易入门,挫折感也少。
很多人自学java,因为抓不到学习java的重点,找不到学习java的方向。往往花费大量的时间和精力,而效果却不大。面试IT企业office时或者参与真正的项目开发忽然发现自己一无所知。
我想要告诉你的是学习Java不难,但是也会很艰辛的敲代码。Java程序员经常需要加班,学之前要作好心理准备。其次一旦下定决心学java了,一定要坚持下去,不要半途而废。
java零基础的学生自学必然会耗费大量的时间和精力,而且如果你没有定制系统的学习方案,效果将事倍功半
学习路线
对于编程初学者,我不太建议上来通过做项目学习。实践确实很重要,如果你没有编程基础的话,直接上手实战,很容易最后学个四不像。
建议你在学习编程的初期尽量多看一些优质视频。跟着视频一步一步走,可以让你少踩很多坑,学习编程的信心也会增加。
概览:
内容比较多?劝退? 如果你只想找到一份小厂的开发工作的话,建议你把重心放在 Java基础、数据库、常用框架、常用工具上。
像 JVM、分布式、高并发、高可用、微服务这些知识点,如果你想进大厂或者说让自己在求职的时候更有竞争力,那你就也是要多花一点时间来学习的。
现在面试很卷,想要找到一个好工作的话,就需要你去多学一点,多练习一点。虽然,你目前学的很多知识,在你工作之后可能用不到,但是,面试的筛选就需要你会这些。毕竟,很多岗位是很多人一起竞争,为了达到筛选效果,面试难度通常都会比较大的。这也就是所谓的:“面试造火箭,工作拧螺丝”。完整学习路线以及学习资料已经整理完毕
Java 基础
如果你之前没有学习过编程的话,我建议你可以看看视频教程。
学完 Java 基础之后,你可以用自己学的东西实现一个简单的 Java 程序,也可以尝试用 Java 解决一些编程问题,以此来将自己学到的东西付诸于实践。
不太建议学习 Java 基础的之后通过做游戏来巩固。新手学习完 Java 基础后做游戏一般是不太现实的,还不如找一些简单的程序问题解决一下比如简单的算法题。
记得多总结!打好基础!把自己重要的东西都记录下来。 API 文档放在自己可以看到的地方,以备自己可以随时查阅。为了能让自己写出更优秀的代码,《Effective Java》、《重构》 这两本书没事也可以看。
学完这部分内容之后,务必确保自己掌握下面知识点:
- 基本语法、基本数据类型
- 对象、类、接口
- 继承、泛型
- 方法
- 异常、断言
- 集合
- ......
并发
多线程这部分内容稍微会比较难以理解和实践。如果你刚学完 Java 基础的话,我建议你学习并发这部分内容的时候,可以先简单地了解一下基础知识比如线程和进程的对比。到了后面,你对于 Java 了解的更深了之后,再回来仔细看看这部分的内容。
下面是我总结的一些关于并发的小问题,你可以拿来自测:
- 什么是线程和进程? 线程与进程的关系,区别及优缺点?
- 说说并发与并行的区别?
- 为什么要使用多线程呢?
- 使用多线程可能带来什么问题?(内存泄漏、死锁、线程不安全等等)
- 创建线程有哪几种方式?(a.继承 Thread 类;b.实现 Runnable 接口;c. 使用 Executor 框架;d.使用 FutureTask)
- 说说线程的生命周期和状态?
- 什么是上下文切换?
- 什么是线程死锁?如何避免死锁?
- 说说
sleep()
方法和wait()
方法区别和共同点? - Java 内存模型(JMM)、重排序与 happens-before 原则了解吗?
synchronized
关键字、volatile
关键字ThreadLocal
有啥用(解决了什么问题)?怎么用?原理了解吗?内存泄露问题了解吗?- 为什么要用线程池?
ThreadPoolExecutor
类的重要参数了解吗?ThreadPoolExecutor
饱和策略了解吗?线程池原理了解吗?几种常见的线程池了解吗?为什么不推荐使用FixedThreadPool
?如何设置线程池的大小? - AQS 了解么?原理?AQS 常用组件:
Semaphore
(信号量)、CountDownLatch
(倒计时器)CyclicBarrier
(循环栅栏) ReentrantLock
、ReentrantReadWriteLock
、StampedLock
(JDK8)- CAS 了解么?原理?
- Atomic 原子类
- 并发容器:
ConcurrentHashMap
、CopyOnWriteArrayList
、ConcurrentLinkedQueue
BlockingQueue
、ConcurrentSkipListMap
Future
和CompletableFuture
- ......
JVM
对于 Java 程序员来说,JVM 帮助我们做了很多事情比如内存管理、垃圾回收等等。在 JVM 的帮助下,我们的程序出现内存泄漏这些问题的概率相对来说是比较低的。但是,这并不代表我们在日常开发工作中不会遇到。万一你在工作中遇到了 OOM 问题,你至少要知道如何去排查和解决问题吧!
并且,就单纯从面试角度来说,JVM 是 Java 后端面试(大厂)中非常重要的一环。不论是应届还是社招,面试国内的一些大厂,你都会被问到很多 JVM 相关的问题(应届的话侧重理论,社招实践)。
只有搞懂了 JVM 才有可能真正把 Java 语言“吃透”。学习 JVM 这部分的内容,一定要注意要实战和理论结合。
下面是我总结的一些关于 JVM 的小问题,你可以拿来自测:
- 什么是虚拟机?
- Java 内存区域是怎么划分的?大对象放在哪个内存区域?
- 垃圾回收有哪些算法?GC 的流程
- 什么是类加载?何时类加载?类加载流程?
- 知道哪些类加载器。类加载器之间的关系?
- 类加载器的双亲委派了解么? 结合 Tomcat 说一下双亲委派(Tomcat 如何打破双亲委托机制?...)。
- 常见调优参数有哪些?
- ......
数据库
我们网站或 者 APP 的数据都是需要使用数据库来存储数据的。
MySQL
一般企业项目开发中,使用 MySQL 比较多。
学习了 MySQL 之后,务必确保自己掌握下面这些知识点:
- MySQL 常用命令 :
- 安全:登录、增加/删除用户、备份数据和还原数据
- 数据库操作: 建库建表/删库删表、用户权限分配
- ......
- MySQL 中常用的数据类型、字符集编码
- MySQL 简单查询、条件查询、模糊查询、多表查询以及如何对查询结果排序、过滤、分组......
- MySQL 中使用索引、视图、存储过程、游标、触发器
- ......
如果你想让自己更加了解 MySQL ,同时也是为了准备面试的话,下面这些知识点要格外注意:
- 索引:索引优缺点、B 树和 B+树、聚集索引与非聚集索引、覆盖索引
- 事务:事务、数据库事务、ACID、并发事务、事务隔离级别
- 存储引擎(MyISAM 和 InnoDB)
- 锁机制与 InnoDB 锁算法
Redis
Redis 就是一个使用 C 语言开发的数据库,不过与传统数据库不同的是 Redis 的数据是存在内存中的 ,也就是它是内存数据库,所以读写速度非常快,因此 Redis 被广泛应用于缓存方向。
下面是我总结的一些关于并发的小问题,你可以拿来自测:
- Redis 和 Memcached 的区别和共同点
- 为什么要用 Redis/为什么要用缓存?
- Redis 常见数据结构以及使用场景分析
- Redis 没有使用多线程?为什么不使用多线程?Redis6.0 之后为何引入了多线程?
- Redis 给缓存数据设置过期时间有啥用?
- Redis 是如何判断数据是否过期的呢?
- 过期的数据的删除策略了解么?
- Redis 内存淘汰机制了解么?
- Redis 持久化机制(怎么保证 Redis 挂掉之后再重启数据可以进行恢复)
- Redis 缓存穿透、缓存雪崩?
- 如何保证缓存和数据库数据的一致性?
- ......
常用工具
非常重要!非常重要!特别是 Git 和 Docker。
除了下面这些工具之外,我强烈建议你一定要搞懂 Github 的使用。
IDEA
俗话说:“工欲善其事,必先利其器 !”。选择一款好的开发工具对于我们高效率编码非常有帮助!
常用的 Java 开发工具就 Eclipse 和 IDEA。就我个人而言 IDEA 是最适合 Java 开发者的 IDE 。
建议你要熟悉 IDEA 的基本操作以及常用快捷。
除了 IDEA 自身对编码优秀的支持(比如智能上下文提示)之外,IDEA 中还有丰富的插件来帮助我们高效开发。
Maven
强烈建议学习常用框架之前可以提前花几天时间学习一下Maven的使用。(到处找 Jar 包,下载 Jar 包是真的麻烦费事,使用 Maven 可以为你省很多事情)。
Git
Git 技能对于程序员来说也是必备的!试着在学习的过程中将自己的代码托管在 Github 上,有一个漂亮的 Github 主页在求职面试中是十分加分的。并且,现在的企业都是基于 Git 在 GitHub 或 GitLab 平台上做版本控制。
Docker
传统的开发流程中,我们的项目通常需要使用 MySQL、Redis、FastDFS 等等环境,这些环境都是需要我们手动去进行下载并配置的,安装配置流程极其复杂,而且不同系统下的操作也不一样。
Docker 的出现完美地解决了这一问题,我们可以在容器中安装 MySQL、Redis 等软件环境,使得应用和环境架构分开,它的优势在于:
- 一致的运行环境,能够更轻松地迁移
- 对进程进行封装隔离,容器与容器之间互不影响,更高效地利用系统资源
- 可以通过镜像复制多个一致的容器
设计模式
软件开发中有一个概念叫做“软件复用”。简单来说,软件复用就是我们在构建一个新的软件的时候,不需要从零开始,通过复用已有的一些轮子(框架、第三方库等)、设计模式、设计原则等等现成的物料,我们可以更快地构建出一个满足要求的软件。
软件复用需要设计模式的帮助。因为,在软件开发中,设计模式可以通过封装变化来提高代码的可扩展性和可维护性!
在我们平时工作的业务开发中,如果你不会设计模式,你或许也可以完成项目的功能需求。但是!单纯 CRUD 多没意思啊!我们要思考如何写出质量更高的业务代码。另外,各种框架比如 Spring、MyBatis 中都大量使用了设计模式。如果,你想要搞懂他们的原理,设计模式也是你的必备利器。
设计模式不光需要我们在学习,最重要的还是要不断去实践体会。但是!设计模式不是银弹,不要为了用设计模式而用设计模式。
Linux
对于 Linux 我们要掌握基本的使用就需要对一些常用命令非常熟悉比如:目录切换命令、目录操作命令、文件的操作命令、压缩或者解压文件的命令等等。
前端基础
笔者是从事 Java 后端开发的,对于前端的了解属于皮毛。
前端框架更新换代的很快,目前比较流行的是 Vue、React、Angular 。
不过,不管前端这些技术怎么变,前端三剑客(HTML、CSS、JavaScript )是不会变的。
J2EE 基础
Servlet
Servlet
属于比较古老的技术了,现在你几乎不会直接使用到 Servlet
相关的 API。不过,学习 Servlet
有助于我们搞清各种封装的比较好的 Web 框架的原理,比如 Spring MVC
不过就是对 Servlet
的封装,它的底层还是依赖于 Servlet
。
在 Java Web 程序中,Servlet
主要负责接收用户请求 HttpServletRequest
,在doGet()
,doPost()
中做相应的处理,并将回应HttpServletResponse
反馈给用户。
Web 服务器
Tomcat 是 Apache 基金会下的一个项目,主要用作 Web 服务器。
如果你直接学习 Spring Boot 的话,不学习 Tomcat 也没什么影响(建议还是学一学)。因为 Spring Boot (spring-boot-starter-web
)使用 Tomcat 作为默认的嵌入式 Servlet
容器, 你使用起来是无感知的。
简单来说,Tomcat 主要实现了 2 个核心功能:
- 处理
Socket
连接,负责网络字节流与Request
和Response
对象的转化。 - 加载和管理
Servlet
,以及具体处理Request
请求。
除了 Tomcat 之外,Nginx 也是必须要学习的!
Nginx 是一个高性能的 HTTP 和反向代理服务服务器,经常被拿来做反向代理和负载均衡。
常用框架
Spring/SpringBoot
Spring 和 SpringBoot 真的很重要!
一定要搞懂 AOP 和 IOC 这两个概念。Spring 中 bean 的作用域与生命周期、SpringMVC 工作原理详解等等知识点都是非常重要的,一定要搞懂。
企业中做 Java 后端,你一定离不开 SpringBoot ,这个是必备的技能了!一定一定一定要学好!
像 SpringBoot 和一些常见技术的整合你也要知识怎么做,比如 SpringBoot 整合 MyBatis、 ElasticSearch、SpringSecurity、Redis 等等。
了解了 Spring 中的一些常见概念和基本用法之后,你就可以开始学习 Spring Boot 了。
当然了,Spring 其实并不是学习 Spring Boot 的前置基础,相比于 Spring 来说,Spring Boot 要更容易上手一些!如果你只是想使用 Spring Boot 来做项目的话,直接学 Spring Boot 就可以了。
Netty
但凡涉及到网络通信就必然必然离不开网络编程。 Netty 目前作为 Java 网络编程最热门的框架,毫不夸张地说是每个 Java 程序员必备的技能之一。
为什么说学好 Netty 很有必要呢?
- Netty 基于 NIO (NIO 是一种同步非阻塞的 I/O 模型,在 Java 1.4 中引入了 NIO )。使用 Netty 可以极大地简化并简化了 TCP 和 UDP 套接字服务器等网络编程,并且性能以及安全性等很多方面都非常优秀。
- 我们平常经常接触的 Dubbo、RocketMQ、Elasticsearch、gRPC、Spark、Elasticsearch 等等热门开源项目都用到了 Netty。
- 大部分微服务框架底层涉及到网络通信的部分都是基于 Netty 来做的,比如说 Spring Cloud 生态系统中的网关 Spring Cloud Gateway 。
单元测试
为了保证代码质量,为重构提供信心,我们的项目一般都会写单元测试。
你需要知道如何使用 :
- Junit: 当前最流行的 Java 测试框架!提到 Java 测试,往往离不开它!
- mockito :用于 Mock 测试中用的类,简答来说就是创建一个虚拟对象。当一个类比较复杂或者和要测试的内容无关的时候,Mock 非常有用!
- powermock :同样用于 Mock 测试中用的类,不过, PowerMock 可以实现完成对 private/static/final 方法的 Mock(模拟),而 Mockito 仅仅可以对普通的方法进行 Mock。
- ......
除了上面介绍到的几个测试相关的框架之外,下面几个也可以学习一下(可选):
- Spock :Spock 是一个 Java 和 Groovy 应用程序的测试和规范框架。它能够让我们的测试代码更规范,内置多种标签来规范单测代码的语义。
- Assertj :流式断言神器,可以与 JUnit,TestNG 等其他测试框架一起使用。
- ......
像咱们平时都是使用 Spring /SpringBoot 多一点,因此你还需要知道如何在 Spring /SpringBoot 中写单元测试。
搜索引擎
搜索引擎用于提高搜索效率,功能和浏览器搜索引擎类似。比较常见的搜索引擎是 Elasticsearch(推荐) 和 Solr。
分布式
下面我们开始学习分布式以及高并发、高可用了。
这块内容的话,对于每一个知识点没有特定的书籍。
理论
CAP 理论
CAP 也就是 Consistency(一致性)、Availability(可用性)、Partition Tolerance(分区容错性) 这三个单词首字母组合。
BASE 理论
BASE 是 Basically Available(基本可用) 、Soft-state(软状态) 和 Eventually Consistent(最终一致性) 三个短语的缩写。BASE 理论是对 CAP 中一致性和可用性权衡的结果,其来源于对大规模互联网系统分布式实践的总结,是基于 CAP 定理逐步演化而来的,它大大降低了我们对系统的要求。
Paxos 算法和 Raft 算法
Paxos 算法诞生于 1990 年,这是一种解决分布式系统一致性的经典算法 。但是,由于 Paxos 算法非常难以理解和实现,不断有人尝试简化这一算法。到了 2013 年才诞生了一个比 Paxos 算法更易理解和实现的分布式一致性算法—Raft 算法。
RPC
RPC 让调用远程服务调用像调用本地方法那样简单。
Dubbo 是一款国产的 RPC 框架,由阿里开源。
服务注册与发现
Eureka
、Zookeeper
、Consul
、Nacos
都可以提供服务注册与发现的功能。
API 网关
网关主要用于请求转发、安全认证、协议转换、容灾。
SpringCloud Gateway
是 Spring Cloud
的一个全新项目,为了取代 Netflix Zuul
。
配置中心
微服务下,业务的发展一般会导致服务数量的增加,进而导致程序配置(服务地址、数据库参数等等)增多。
传统的配置文件的方式已经无法满足当前需求,主要有两点原因:一是安全性得不到保障(配置放在代码库中容易泄露);二是时效性不行 (修改配置需要重启服务才能生效)。
Spring Cloud Config
、Nacos
、Apollo
、K8s ConfigMap
都可以用来做配置中心。
Apollo
和 Nacos
我个人更喜欢。Nacos
使用起来更加顺手,Apollo
在配置管理方面做的更加全面。
分布式 id
日常开发中,我们需要对系统中的各种数据使用 ID 唯一表示,比如用户 ID 对应且仅对应一个人,商品 ID 对应且仅对应一件商品,订单 ID 对应且仅对应一个订单。
简单来说,ID 就是数据的唯一标识。
分布式 ID 是分布式系统下的 ID。分布式 ID 不存在与现实生活中,属于计算机系统中的一个概念。
我简单举一个分库分表的例子。
我司的一个项目,使用的是单机 MySQL 。但是,没想到的是,项目上线一个月之后,随着使用人数越来越多,整个系统的数据量将越来越大。
单机 MySQL 已经没办法支撑了,需要进行分库分表(推荐 Sharding-JDBC)。
在分库之后, 数据遍布在不同服务器上的数据库,数据库的自增主键已经没办法满足生成的主键唯一了。我们如何为不同的数据节点生成全局唯一主键呢?
这个时候就需要生成分布式 ID了。
分布式 ID 的解决方案有很多比如 :
- 算法 :
UUID
、Snowflake
- 开源框架 :
UidGenerator
、Leaf
、Tinyid
分布式事务
微服务架构下,一个系统被拆分为多个小的微服务。
每个微服务都可能存在不同的机器上,并且每个微服务可能都有一个单独的数据库供自己使用。这种情况下,一组操作可能会涉及到多个微服务以及多个数据库。
举个例子:电商系统中,你创建一个订单往往会涉及到订单服务(订单数加一)、库存服务(库存减一)等等服务,这些服务会有供自己单独使用的数据库。
那么如何保证这一组操作要么都执行成功,要么都执行失败呢?
这个时候单单依靠数据库事务就不行了!我们就需要引入 分布式事务 这个概念了!
常用分布式事务解决方案有 Seata
和 Hmily
。
Seata:
Seata
是一款开源的分布式事务解决方案,致力于在微服务架构下提供高性能和简单易用的分布式事务服务。-
Hmily
: 金融级分布式事务解决方案
分布式链路追踪
不同于单体架构,在分布式架构下,请求需要在多个服务之间调用,排查问题会非常麻烦。我们需要分布式链路追踪系统来解决这个痛点。
目前分布式链路追踪系统基本都是根据谷歌的《Dapper 大规模分布式系统的跟踪系统》这篇论文发展而来,主流的有 Pinpoint
,Skywalking
,CAT
(当然也有其他的例如 Zipkin
,Jaeger
等产品,不过总体来说不如前面选取的 3 个完成度高)等。
Zipkin
是 Twitter 公司开源的一个分布式链路追踪工具,Spring Cloud Sleuth
实际是基于 Zipkin 的。
SkyWalking
是国人吴晟(华为)开源的一款分布式追踪,分析,告警的工具,现在是 Apache 旗下开源项目
微服务
微服务的很多东西实际在分布式这一节已经提到了。
我这里就再补充一些微服务架构中,经常使用到的一些组件。
- 声明式服务调用 : Feign
- 负载均衡 : Ribbon
- ......
高并发
消息队列
消息队列在分布式系统中主要是为了解耦和削峰。
读写分离&分库分表
读写分离主要是为了将数据库的读和写操作分不到不同的数据库节点上。主服务器负责写,从服务器负责读。另外,一主一从或者一主多从都可以。
读写分离可以大幅提高读性能,小幅提高写的性能。因此,读写分离更适合单机并发读请求比较多的场景。
分库分表是为了解决由于库、表数据量过大,而导致数据库性能持续下降的问题。
常见的分库分表工具有:sharding-jdbc
(当当)、TSharding
(蘑菇街)、MyCAT
(基于 Cobar)、Cobar
(阿里巴巴)...。 推荐使用 sharding-jdbc
。 因为,sharding-jdbc
是一款轻量级 Java
框架,以 jar
包形式提供服务,不要我们做额外的运维工作,并且兼容性也很好。
负载均衡
负载均衡系统通常用于将任务比如用户请求处理分配到多个服务器处理以提高网站、应用或者数据库的性能和可靠性。
常见的负载均衡系统包括 3 种:
- DNS 负载均衡 :一般用来实现地理级别的均衡。
- 硬件负载均衡 : 通过单独的硬件设备比如 F5 来实现负载均衡功能(硬件的价格一般很贵)。
- 软件负载均衡 :通过负载均衡软件比如 Nginx 来实现负载均衡功能。
高可用
高可用描述的是一个系统在大部分时间都是可用的,可以为我们提供服务的。高可用代表系统即使在发生硬件故障或者系统升级的时候,服务仍然是可用的 。
限流&降级&熔断
限流是从用户访问压力的角度来考虑如何应对系统故障。限流为了对服务端的接口接受请求的频率进行限制,防止服务挂掉。比如某一接口的请求限制为 100 个每秒, 对超过限制的请求放弃处理或者放到队列中等待处理。限流可以有效应对突发请求过多。相关阅读:限流算法有哪些?
降级是从系统功能优先级的角度考虑如何应对系统故障。服务降级指的是当服务器压力剧增的情况下,根据当前业务情况及流量对一些服务和页面有策略的降级,以此释放服务器资源以保证核心任务的正常运行。
熔断和降级是两个比较容易混淆的概念,两者的含义并不相同。
降级的目的在于应对系统自身的故障,而熔断的目的在于应对当前系统依赖的外部系统或者第三方系统的故障。
Hystrix 是 Netflix 开源的熔断降级组件,Sentinel 是阿里中间件团队开源的一款不光具有熔断降级功能,同时还支持系统负载保护的组件。
排队
另类的一种限流,类比于现实世界的排队。玩过英雄联盟的小伙伴应该有体会,每次一有活动,就要经历一波排队才能进入游戏。
集群
相同的服务部署多份,避免单点故障。
超时和重试机制
一旦用户的请求超过某个时间得不到响应就结束此次请求并抛出异常。 如果不进行超时设置可能会导致请求响应速度慢,甚至导致请求堆积进而让系统无法在处理请求。
另外,重试的次数一般设为 3 次,再多次的重试没有好处,反而会加重服务器压力(部分场景使用失败重试机制会不太适合)。
总结
这是一份非常详细的学习路线,把上面的内容学完之后,找到一份比较好的工作已经比较容易。
另外,我在上面也说了,如果你觉得内容比较多自己学不完或者如果你只想找到一份小厂的开发工作的话,建议你把重心放在 Java基础、数据库、常用框架、常用工具上。
像 JVM、分布式、高并发、高可用、微服务这些知识点,如果你想进大厂或者说让自己在求职的时候更有竞争力,那你就也是要多花一点时间来学习的。
更多推荐
所有评论(0)