Java指北
一、面试准备篇
如何准备Java面试
提前准备技术面试和手撕算法
面试之前一定要提前准备一下常见的面试题:
自己面试中可能涉及哪些知识点、那些知识点是重点。
面试中哪些问题会被经常问到、面试中自己改如何回答。(强烈不推荐死记硬背,第一:通过背这种方式你能记住多少?能记住多久?第二:背题的方式的学习很难坚持下去!)
这块内容只会介绍面试大概会涉及到哪方面的知识点,具体这些知识点涵盖哪些问题,后面的文章有介绍到。
Java :
Java 基础
Java 集合
Java 并发
JVM
计算机基础 :
算法
数据结构
计算机网络
操作系统
数据库 :
MySQL
Redis
常用框架 :
Spring
SpringBoot
MyBatis
Netty
Zookeeper
Dubbo
分布式 :
CAP 理论 和 BASE 理论、Paxos 算法和 Raft 算法
RPC
分布式事务
分布式 ID
高并发 :
- 消息队列
- 读写分离&分库分表
- 负载均衡
高可用 :
- 限流
- 降级
- 熔断
不同类型的公司对于技能的要求侧重点是不同的比如腾讯、字节可能更重视计算机基础比如网络、操作系统这方面的内容。阿里、美团这种可能更重视你的项目经历、实战能力。
关于如何准备算法面试请看《Java 面试指北》的「面试准备篇」中对应的文章。
有哪些值得阅读的优秀源码?
下面有部分内容是摘自朋友写的一篇文章:《如何提升代码质量 - Thoughtworks 洞见》
JDK
为什么要看 JDK 源码?
- JDK 源码是其它所有源码的基础,看懂了 JDK 源码再看其它的源码会达到事半功倍的效果。
- JDK 源码中包含大量的数据结构知识,是学习数据结构很好的资料,比如,链表、队列、散列表、红黑树、跳表、桶、堆、双端队列等。
- JDK 源码中包含大量的设计模式,是学习设计模式很好的资料,比如,适配器模式、模板方法模式、装饰器模式、迭代器模式、代理模式、工厂模式、命令模式、状态模式等。
- JDK 源码中包含大量 Java 的高阶知识,比如弱引用、Unsafe、CAS、锁原理、伪共享等,不看源码是很难学会这些知识的。
JDK 源码阅读顺序 :
- java.lang 包下的基本包装类(Integer、Long、Double、Float 等),还有字符串相关类(String、StringBuffer、StringBuilder 等)、常用类(Object、Exception、Thread、ThreadLocal等)。
- java.lang.ref 包下的引用类(WeakReference、SoftReference 等)
- java.lang.annotation 包下的注解的相关类
- java.lang.reflect 包下的反射的相关类
- java.util 包下为一些工具类,主要由各种容器和集合类(Map、Set、List 等)
- java.util.concurrent 为并发包,主要是原子类、锁以及并发工具类
- java.io和 java.nio 可以结合着看
- java.time 主要包含时间相关的类,可以学习下 Java 8 新增的几个
- java.net包下为网络通信相关的类,可以阅读下 Socket 和 HTTPClient 相关代码
源码量那么大,不要妄想一口气都看完。最好符合你当前的目的,比如你想搞懂多线程,你就主要看 JUC,想搞懂 IO 就多去看 NIO,想看常量池就去看 ClassFileParser。看模块的时候,要注意接口大于一切,或者说函数大于一切。先不要妄想搞懂所有细节,先找几个比较关键的函数,搞懂函数的作用(比如应该仔细分析一下函数名称和参数名称)然后再往下进行。
在看 Java 类库的时候要多注意类是不是 abstract 的,是不是用的模板方法,多关注函数前的修饰词,这一般说明这个函数是给谁用的。多注意这些细节而不是傻傻过一遍逻辑,能从里面学到不少关于设计的东西。还可以注意什么地方是为了之前的设计而委曲求全的做法,毕竟一个这么多年的类库,肯定不是什么地方都是完美的。
JDK 源码一定要看 Java 并发相关的源码, Doug Lea 的并发源码比较漂亮,一行行都是精华,非常值得阅读学习。
Spring
Spring 是一个开源的设计层面框架,它解决的是业务逻辑层和其他各层的松耦合问题,因此它将面向接口的编程思想贯穿整个系统应用。包括在此基础上衍生的 Spring MVC、 Spring Boot 、Spring Cloud 等,在现在企业中的应用越来越广泛。无论是设计思想,代码规范,还是设计模式,接口设计,类加载,都是非常优秀的源码。
个人学习心得如下:先去看视频,大概熟悉一下 Spring 的使用情况,然后再去学习源码,此处可以阅读《Spring 源码深度解析》,除了看书之外,记得打开 IDEA 查看对应的源码,如果能调试看看具体调用逻辑那就更好了。
Google Guava
Google Guava 是 Google 公司内部 Java 开发工具库的开源版本。Google 内部的很多 Java 项目都在使用它。它提供了一些 JDK 没有提供的功能,以及对 JDK 已有功能的增强功能。其中就包括:集合(Collections)、缓存(Caching)、原生类型支持(Primitives Support)、并发库(Concurrency Libraries)、通用注解(Common Annotation)、字符串处理(Strings Processing)、数学计算(Math)、I/O、事件总线(EventBus)等等。
Netty
Netty 是一个优秀的开源网络编程框架,我们平常经常接触的 Dubbo、RocketMQ、Elasticsearch、gRPC 等等都用到了 Netty。
Netty 中使用了大量的设计模式以及优秀的设计原则。
Dubbo
Dubbo 是一款优秀的国产 RPC 框架,其 SPI 自适应扩展、负载均衡实现、集群实现、服务调用过程等部分的源码都非常值得阅读和学习。
保姆级别的源码阅读教学
如何高效阅读项目源码
⚠️ 注意:
阅读源码之前,一定要先熟悉项目。你连 Dubbo 怎么使用、RPC 是个啥都不知道,就直接去看 Dubbo 源码的话,不是纯属扯淡么?
阅读源码之前,一定要对项目源码使用的技术有一个最基本的认识。
从了解并使用项目开始
开始看源码之前,自己花一些时间阅读以下官方的文档、使用教程。如果官方文档是英文的话,也可以找一些国人写的博客看看。不知道项目是用法和用途的就去看项目源代码的行为,无疑是在黑夜中穿针。
站在最外层概览项目设计
阅读源码之前,我比较推荐先站在最外层去熟悉项目整体架构和模块分包。掌控全局之后,我们方能以一个更正确的姿势畅游源码的世界。
比如,我在看 Dubbo 源码之前,我就首先花了大量时间熟悉了 Dubbo 的模块分包,这个在其官方文档上介绍的就非常详细。
从某个功能主线/问题出发研究项目源码
一个比较成熟的项目的源码量是非常多,我们不可能都看完。比较推荐的方式就是通过一个功能主线(比如 Dubbo 是如何暴露服务的?)或者问题(比如 SpringBoot 的自动配置原理?)出发。
学会使用官方提供的 Demo
一般情况下,项目源码已经自带了一些 Demo 我们可以直接使用。这样可以方便我们:
检验源码阅读环境是否搭建成功。
调试项目。
比如在 Dubbo 项目源码中,我们找到 dubbo-demo 这个文件夹,里面包含了 3 种不同类型(xml、api、annotation)使用方式的 demo,可以帮助我们节省掉大量写 Demo 的时间。
有哪些对阅读源码有帮助的建议
学习常见的设计模式、设计原则
一个优秀的开源项目一定会不可避免使用到一些设计模式,如果我们提前不了解这些设计模式的话,会加深自己理解代码的难度。
另外,项目的代码还应该满足一些设计原则。对于,面向对象编程来说,下面这些原则都是我们应该非常熟练的。
面向对象编程的思想(继承、封装、多态、抽象)
面向对象的七大设计原则:
单一职责原则(Single Responsibility Principle, SRP)
开闭原则(Open Closed Principle,OCP)
里氏代换原则(Liskov Substitution Principle,LSP)
接口隔离原则(Interface Segregation Principle,ISP)
依赖反转原则(Dependency Inversion Principle,DIP)
合成/聚合复用原则(Composite/Aggregate Reuse Principle,CARP)
迪米特法则(Principle of Least Knowledge,PLK,也叫最小知识原则)
软件设计的三大原则
DRY(Don’t Repeat Yourself)原则:不要重复你自己
KISS( Keep It Simple/Stupid)原则:保持简单易懂
YAGNI ( You Ain’t Gonna Need It)原则 :不要进行过度设计
学会看测试类
测试类一方面可以说是对代码的稳定性的保障,让我们对自己写的代码更放心。另一方面测试本身也是对代码的一个说明,因此,很多人都会说:“好的测试即是文档”。通过测试类,我们可以很清楚地知道某一块代码具体是在干嘛。
学会调试
通过调试,我们可以更直观地看到调用逻辑关系。通过变量信息,可以更直观地看到数据的变化过程,这对于我们理解代码以及找 bug 都是非常有帮助的。
掌握 IDE 常用的快捷键
熟悉常用的快捷键在源码阅读中非常有必要!这个是必须要会的。
比如在 IDEA 中我们通过 command+o(mac)或者 ctrl+n(win/linux)即可搜索类以及文件
通过 command+f12(mac)或者 ctrl+f12(win/linux)即可查看类的结构(函数、变量)
使用一些插件辅助自己
有一些插件可以帮助我们理清源码的调用逻辑。比如 IDEA 插件 SequenceDiagram 就可以帮助我们一键生成方法的时序图。
相关阅读:《安利一个 IDEA 骚操作:一键生成方法的序列图》
手撸一个简易版
我们可以在学习某个具体的框架源码之前,自己先手撸一个简易版的框架。
就比如我们学习 Dubbo 源码之前,我们自己撸一个简易版的 RPC 框架。
自己动脑思考该怎么设计,功能该如何实现。
做了这些尝试之后,我们再去看别人写的源码,收货一定会非常大!
为什么要准备算法面试?怎么高效刷 Leetcode?
为什么要准备算法面试?
很明显,国内现在的校招面试开始越来越重视算法了,尤其是像字节跳动、腾讯这类大公司。绝大部分公司的校招笔试是有算法题的,如果 AC 率比较低的话,基本就挂掉了。
社招的话,算法面试同样会有。不过,面试官可能会更看重你的工程能力,你的项目经历。如果你的其他方面都很优秀,但是算法很菜的话,不一定会挂掉。不过,还是建议刷下算法题,避免让其成为自己在面试中的短板。
社招往往是在技术面试的最后,面试官给你一个算法题目让你做。
为了能够应对,我们大部分人能做的就是刷 Leetcode 来积累做算法题的经验和套路。
另外, 很多小伙伴特别是已经工作几年的,总觉得说算法这东西没啥用。确实,相比于系统设计能力,工程能力来说,算法对于普通工程师的价值可能并不是那么大。但是,在面试中算法确实很能考验面试者能力的一个环节。单纯靠项目经历以及技术面试的话,还是很容易弄虚作假的。算法能力在某些角度可以反映你解决编程问题的能力以及你的思维能力。
刷 LeetCode 吃力正常吗?
我自己写过框架,写过 web 服务器,给项目造过轮子。
我想说的是太正常不过了!我的工程能力在同龄人中应该还算可以,但是很多 Leetcode 上面的算法题我真做不出来。手撕算法方面我真的没有公司新招进来的应届生强。说实话,公司出的算法题,我自己都不一定能做出来(主要是因为工作之后很久没碰了)。
小声 BB:应届生过来了还是要不断经历我们“老人“的 diss,哈哈哈!鲁迅先生说:没有 diss,哪里来的成长。
刷 Leetcode 需要哪些基础?
编程语言
刷题之前,确保你有一个还算熟悉的编程语言。比较常用的有 Java、C/C++、Python、Go。
数据结构和算法基础
为了让自己更愉快地刷题,一些基本的数据结构和算法知识是必备的。
刷 Leetcode 之前,如果你还没有算法和数据结构方面的基础知识的话,可以先看一些比较适合入门的书籍。我的下面这个回答会推荐一些算法相关的书籍和学习资源(写的用心,觉得不错的话可以点个赞鼓励一下):《有哪些值得推荐的好的算法书?》 。
- 数据结构:数组、链表、栈、队列、堆、二叉树、图、哈希表、并查集
- 算法思想 : 递归、动态规划、二分查找、贪心、分治、回溯、DFS、BFS、KMP、树的广度和深度优先搜索、
- 数学: 位运算、质数、排列组合
另外,对于每一种编程语言都有一些内置的常用数据结构的实现,我们需要提前了解。拿 Java 来说,HashMap、TreeMap,TreeSet,PriorityQueue,Deque
等都是比较常用的。
怎么高效刷 Leetcode?
最重要的还是一定要坚持刷起来!!!
按照类型来刷
我个人比较建议每次刷题助攻一个类型,比如你某一天或者几天就主要刷动态规划相关的题目。
为什么这样建议呢? 也是一点个人经验吧!我当时在刷算法题的时候,发现如果每次做的算法题类型跨度太大的话,非常影响自己速度和体验。当你刷了同一种类型的题目比较多了之后,你就会大概知道这类题型的套路了。
由简入难
很多朋友可能和我一样,刚开始刷 LeetCode 的时候,寸步难行,经常一道算法题一下午写不出来。当时,我甚至开始怀疑自己是不是笨。为此,我专门找到一些算法大佬交流。算法大佬安慰我说:“ 不是你笨,不用灰心!你先从简单地算法题开始做起,多多总结就好了!”。
于是,我每天抽出 1~3 个小时专门用来刷简单类型的算法题。刷了一个多月之后,一些我比较熟悉的题型(简单类型)可以不看答案就能直接 AC 了。
刷算法是一个循序渐进的过程,如果你不是 ACM 大佬这种级别的人物的话,还是建议先从简单开始刷起,慢慢积累经验。
不过,要说明的一点是:很多简单类型的题目甚至还要比中等类型的题目还要难!所以,如果你没办法解决一些简单的算法题,也不要太纠结,不要因此失去信心。
重视高频面试题目/题型
如果你的时间不是很充足的话,建议可以从高频面试题入手。
像 Leetcode 上面就专门把一些最热门的算法面试题给单独整理了出来。
面试中有哪些常见的手撕代码题?
欢迎各位同学在评论区补充完善。
- LRU 缓存实现:https://www.baeldung.com/java-lru-cache
- 栈实现:https://zihengcat.github.io/2019/05/18/java-data-structure-and-algorithm-stack/
- 队列实现:https://cloud.tencent.com/developer/article/1894209
- 加权轮询算法实现:https://mp.weixin.qq.com/s/P25wnGkOjrZiq034UIu2pg
- 死锁:https://www.baeldung.com/java-deadlock-livelock 、https://javaguide.cn/java/concurrent/java-concurrent-questions-01.html(死锁模块有示例代码)
- 单例模式实现:https://segmentfault.com/a/1190000040146574
- 快速排序:http://www.atguigu.com/mst/java/gaopin/17136.html
- 生产者与消费者:https://cloud.tencent.com/developer/article/1824304
- ......
没有项目经验怎么办?跟着视频做的项目会被面试官嫌弃不?
没有项目经验怎么办?
没有项目经验是大部分应届生会碰到的一个问题。甚至说,有很多有工作经验的程序员,对自己在公司做的项目不满意,也想找一个比较有技术含量的项目来做。
说几种我觉得比较靠谱的获取项目经验的方式,希望能够对你有启发。
实战项目视频/专栏
在网上找一个符合自己能力与找工作需求的实战项目视频或者专栏,跟着老师一起做。
你可以通过慕课网、哔哩哔哩、拉勾、极客时间、培训机构(比如黑马、尚硅谷)等渠道获取到适合自己的实战项目视频/专栏。
尽量选择一个适合自己的项目,没必要必须做分布式/微服务项目,对于绝大部分同学来说,能把一个单机项目做好就已经很不错了。
我面试过很多求职者,简历上看着有微服务的项目经验,结果随便问两个问题就知道根本不是自己做的或者说做的时候压根没认真思考。这种情况会给我留下非常不好的印象。
我在《Java 面试指北》的「面试准备篇」中也说过:
个人认为也没必要非要去做微服务或者分布式项目,不一定对你面试有利。微服务或者分布式项目涉及的知识点太多,一般人很难吃透。并且,这类项目其实对于校招生来说稍微有一点超标了。即使你做出来,很多面试官也会认为不是你独立完成的。
其实,你能把一个单体项目做到极致也很好,对于个人能力提升不比做微服务或者分布式项目差。如何做到极致?代码质量这里就不提了,更重要的是你要尽量让自己的项目有一些亮点(比如你是如何提升项目性能的、如何解决项目中存在的一个痛点的),项目经历取得的成果尽量要量化一下比如我使用 xxx 技术解决了 xxx 问题,系统 qps 从 xxx 提高到了 xxx。
跟着老师做的过程中,你一定要有自己的思考,不要浅尝辄止。对于很多知识点,别人的讲解可能只是满足项目就够了,你自己想多点知识的话,对于重要的知识点就要自己学会去深入学习。
实战类开源项目
Github 或者码云上面有很多实战类别项目,你可以选择一个来研究,为了让自己对这个项目更加理解,在理解原有代码的基础上,你可以对原有项目进行改进或者增加功能。
你可以参考 Java 优质开源实战项目 上面推荐的实战类开源项目,质量都很高,项目类型也比较全面,涵盖博客/论坛系统、考试/刷题系统、商城系统、权限管理系统、快速开发脚手架以及各种轮子。
一定要记住: 不光要做,还要改进,改善。不论是实战项目视频或者专栏还是实战类开源项目,都一定会有很多可以完善改进的地方。
从头开始做
自己动手去做一个自己想完成的东西,遇到不会的东西就临时去学,现学现卖。
这个要求比较高,我建议你已经有了一个项目经验之后,再采用这个方法。如果你没有做过项目的话,还是老老实实采用上面两个方法比较好。
参加各种大公司组织的各种大赛
如果参加这种赛事能获奖的话,项目含金量非常高。即使没获奖也没啥,也可以写简历上。
参与实际项目
通常情况下,你有如下途径接触到企业实际项目的开发:
老师接的项目;
自己接的私活;
实习/工作接触到的项目;
老师接的项目和自己接的私活通常都是一些偏业务的项目,很少会涉及到性能优化。这种情况下,你可以考虑对项目进行改进,别怕花时间,某个时间用心做好一件事情就好比如你对项目的数据模型进行改进、引入缓存提高访问速度等等。
实习/工作接触到的项目类似,如果遇到一些偏业务的项目,也是要自己私下对项目进行改进优化。
尽量是真的对项目进行了优化,这本身也是对个人能力的提升。如果你实在是没时间去实践的话,也没关系,吃透这个项目优化手段就好,把一些面试可能会遇到的问题提前准备一下。
我跟着视频做的项目会被面试官嫌弃不?
很多应届生都是跟着视频做的项目,这个大部分面试官都心知肚明。
不排除确实有些面试官不吃这一套,这个也看人。不过我相信大多数面试官都是能理解的,毕竟你在学校的时候实际上是没有什么获得实际项目经验的途径的。
大部分应届生的项目经验都是自己在网上找的或者像你一样买的付费课程跟着做的,极少部分是比较真实的项目。 从你能想着做一个实战项目来说,我觉得初衷是好的,确实也能真正学到东西。 但是,究竟有多少是自己掌握了很重要。看视频最忌讳的是被动接受,自己多改进一下,多思考一下!就算是你跟着视频做的项目,也是可以优化的!
如果你想真正学到东西的话,建议不光要把项目单纯完成跑起来,还要去自己尝试着优化!
简单说几个比较容易的优化点:
- 全局异常处理 :很多项目这方面都做的不是很好,可以参考我的这篇文章:《使用枚举简单封装一个优雅的 Spring Boot 全局异常处理!》 来做优化。
- 项目的技术选型优化 :比如使用 Guava 做本地缓存的地方可以换成 Caffeine 。Caffeine 的各方面的表现要更加好!再比如 Controller 层是否放了太多的业务逻辑。
- 数据库方面 :数据库设计可否优化?索引是否使用使用正确?SQL 语句是否可以优化?是否需要进行读写分离?
- 缓存 :项目有没有哪些数据是经常被访问的?是否引入缓存来提高响应速度?
- 安全 : 项目是否存在安全问题?
- ......
另外,我在星球分享过常见的性能优化方向实践案例,涉及到多线程、异步、索引、缓存等方向,强烈推荐你看看:https://t.zsxq.com/06EqfeMZZ 。
最后,再给大家推荐一个 IDEA 优化代码的小技巧,超级实用!
分析你的代码:右键项目-> Analyze->Inspect Code
扫描完成之后,IDEA 会给出一些可能存在的代码坏味道比如命名问题。
并且,你还可以自定义检查规则。
接触不到高并发场景咋办?如何获得高并发的经验?
不论是应届生还是有几年工作经验的程序员,都可能会面临一个问题:接触不到高并发场景。
不要慌!说实话,能接触到高并发这类业务场景的人还是极少数的。即使在阿里、京东这种公司,你也还是很有可能接触不到。
我在大学那会的时候,自己就比较喜欢捣鼓各种高并发相关的技术了(还是因为太卷,工作之后实际并没有怎么用到,哈哈哈),自己在手动搭建过 Redis 集群、Zookeeeper 集群,动手实现过分库分表、读写分离。
在介绍方法之前,我们首先知道 高并发系统设计的三大目标 :
- 高性能 :系统的处理请求的速度很快,响应时间很短。
- 高可用 :系统几乎可以一直正常提供服务。也就是说系统具备较高的无故障运行的能力。
- 可扩展 :流量高峰时能否在短时间内完成扩容,更平稳地承接峰值流量,比如双 11 活动、明星离婚、明星恋爱等热点事件。
实现高性能的常用手段 :
数据库
- 分库分表&读写分离
- NoSQL
缓存
消息队列 (待重构)
负载均衡
池化技术
......
实现高可用的常用手段 :
- 限流
- 降级
- 熔断
- 排队
- 集群
- 超时和重试机制
- 灾备设计
- 异地多活
实现可扩展架构的常用手段:
- 分层架构:面向流程拆分
- SOA、微服务:面向服务拆分
- 微内核架构:面向功能拆分
你可以在 JavaGuide 的在线阅读网站上找到上面这些手段对应的详细讲解。篇幅问题,我这里就不帖原文了。网站地址:https://javaguide.cn/ 。
知道了高并发系统设计相关的概念和手段之后,废话不多说,直接推荐两种我觉得比较靠谱的方法。
第一种方法是自己研究某个技术然后对已有项目进行改进,具体步骤如下:
- 自己研究某个技术比如读写分离。
- 将自己研究的成果应用到自己的项目比如为项目增加读写分离来提高读数据库的速度。
- 想一想项目用了某个技术比如读写分离之后,会不会遇到什么问题,项目的性能到底提升了多少。如果你能模拟一下真实场景就更好了,既能真正学到,又能让自己项目经历更真实。
- 简单复盘总结一下自己对项目所做的完善改进。
这里要说明一点的是:一定不要为了学习实践某个技术而直接用在自己公司的项目上。
技术是为了服务业务的,没必要用的技术就不要用!我之前有个同事天天喜欢在项目上用自己学到的新技术,结果,有一天就出现生产问题了。我现在想着这件事,都想锤他!
你完全可以私下对项目进行改进。 甚至说,你就只是搞懂了这个技术,并没有将其用在真实的项目中。面试官会专门去调查你这个项目么?那大概率是不会。不过,一定要确保自己是真的搞懂了!
我们只是迫于压力,为了找工作而简单润色一下项目经历而已嘛!
第二种方法是你可以跟着视频/教程做一个分布式相关的项目,然后把它吃透,最好还可以对这个项目进行改进,具体步骤如下:
- 跟着视频/教程写一个分布式相关的项目(自己从头开始做也是一样的)。
- 深入研究并搞懂项目涉及到的一些技术。
- 思考有没有可以改进的地方?
- 思考线上环境可能会有一些什么问题出现?该怎么解决?
- 简单复盘总结复盘一下自己从这个项目中学到的什么东西。
我在大学的时候就是通过这种方法获得的高并发相关的经验。我还记得我当时做的那个分布式项目使用到了 Redis 是单机并且消息队列用的是已经淘汰的 ActiveMQ。所以,我就自己搭建了 Redis 集群,模拟各种可能出现的问题。同时,我使用 RocketMQ 替换了 ActiveMQ 并提取封装了消息队列相关的代码。
通过上面这两种方法来获得高并发经验的话,还有一点非常重要: 自己不光要模拟一些生产环境可能会遇到的问题,还要知道这些问题是怎么解决的。 就比如说你用到了 Redis 的话,你自己肯定要私下模拟一下缓存穿透、单机内存不够用、Redis突然宕机等等情况。
基本上,你用到的大部分中间件可能会遇到的问题,你都能够在网上找到对应的案例和解答。多花点时间看看,自己实践一下,研究思考一下。这样的话,在面试中才不会掉链子。
优质 Java 实战项目推荐
业务类开源项目
社区系统
upupor 是一个小众但是功能强大,代码质量也还可以的开源社区,挺适合作为学习的项目。 最主要的是这个项目目前知名度非常非常低,没有项目经历的小伙伴也可以改造升级一下拿来作为自己的项目经历。
技术栈 :
后端:Spring Boot + MySQL + Redis + Undertow(Web 容器)
前端 :Thymeleaf(模板引擎,方便 SEO)+ Bootstrap
相关地址 :
Github 地址:https://github.com/yangrunkang/upupor 。
在线演示:https://upupor.com 。
网站的性能也是不错的:
类似的社区类小众但有两点的项目还有 forest。
不同于其他社区项目,forest 这个知识社区项目主打文章分享,可以自定义专题和作品集。看得出来作者维护比较认真,并且很有想法。根据项目首页介绍,这个项目未来还可能会增加专业知识题库、社区贡献系统、会员系统。
我大概浏览了一下这个项目代码,发现这个项目的代码写的也相对比较规范干净,比很多 star 数量比较多的社区类项目都要好太多!
技术栈 :
- 后端: SpringBoot + Shrio + MyBatis + JWT + Redis
- 前端:Vue + NuxtJS + Element-UI。
相关地址 :
- Github 地址:https://github.com/rymcu 。
- 在线演示:https://rymcu.com/ 。
小说网站
novel-plus 是一个开源的小说网站项目。这个项目的代码质量也是非常不错的,结果清晰,代码结构也比较规范。这是我推荐这个项目很大的一个原因。
- Github 地址:https://github.com/201206030/novel-plus
- Gitee 地址:https://gitee.com/novel_dev_team/novel-plus
另外,除了单体版之外,这个项目还有一个基于 Spring Cloud 的微服务版本供你学习使用。
- GitHub 地址: https://github.com/201206030/novel-cloud
- Gitee 地址: https://gitee.com/novel_dev_team/novel-cloud
技术栈:
- 后端: SpringBoot + MyBatis +Spring Security + Elasticsearch+ 支付宝支付
- 前端:Thymeleaf + Layui。
这个项目还有一个爬虫模块用于系统初期测试使用。对 Java 爬虫感兴趣的朋友,可以简单研究一下。
在线文档管理
document-sharing-site 是一个支持几乎所有类型(Word, Excel, PPT, PDF, Pic 等)的文档存储、在线预览、共享的开源项目。
技术栈 :
- 后端:Spring Boot + Hutool + Tika(内容分析工具包) + Elasticsearch + JWT
- 前端:Vue + axios。
相关地址 :
导航网站
geshanzsq-nav 是一个前后端分离的导航网站。这个项目同样非常小众,撞车的概率非常小,并且,质量也是非常高。
- Github 地址:https://github.com/geshanzsq/geshanzsq-nav
- Gitee 地址 :https://gitee.com/geshanzsq/geshanzsq-nav
技术栈:
- 后端: SpringBoot + MyBatis +Spring Security + Spring Security + Redis + Jwt
- 前端:Thymeleaf + Layui。
在线演示:https://gesdh.cn/ 。
音乐网站
music-website 是一个开源的音乐网站。这个项目的前端写的挺不错的,后端稍微差劲很多,虽然也把功能写出来了,但是很多实现都不太优雅(详见 Controller 层)。
如果你想要将这个项目作为自己的项目经验或者毕业设计的话,可以自行对后端的代码进行优化。
Github 地址:https://github.com/Yin-Hongwei/music-website 。
技术栈:
- 后端 :SpringBoot + MyBatis + MySQL
- 前端 :Vue3.0 + TypeScript + Vue-Router + Vuex + Axios + ElementPlus + Echarts
健身会员管理系统
基于基于 RuoYi-Vue 做的一个健身会员管理系统,实现了 JWT 登录、渠道管理、促销活动等功能,附带详细的教程。
Github 地址:https://github.com/lenve/tienchin
轮子类开源项目
本地缓存
cache 是一个不错的轮子类项目,使用 Java 手写一个类似于 Redis 的单机版本地缓存(附详细教程)。 麻雀虽小五张俱全,支持数据缓存、缓存失效时间、数据淘汰策略(如 FIFO 、 LRU )、RDB 和 AOF 持久化......。 并且,这个项目附带了 6 篇教程来讲解核心功能具体是怎么实现的。
Github 地址:https://github.com/houbb/cache
RPC 框架
guide-rpc-framework 是一款基于 Netty+Kyro+Zookeeper 实现的 RPC 框架。
- Github 地址: https://github.com/Snailclimb/guide-rpc-framework
- Gitee 地址 :https://gitee.com/SnailClimb/guide-rpc-framework
这个项目代码注释详细,结构清晰,并且集成了 Check Style 规范代码结构,非常适合阅读和学习。
并且,这个项目的 README 文档写的也非常认真。从 README 文档中,你就可以大概了解到这个 RPC 框架的设计思路以及前置技术。
数据库
MYDB 是一个 Java 语言实现的简易版数据库,部分原理参照自 MySQL、PostgreSQL 和 SQLite。
麻雀虽小,五脏俱全。MYDB 目前已经实现 MVCC、两种事务隔离级别(读提交和可重复读)、死锁处理、简陋的 SQL 解析等关系型数据库的核心功能。
并且,MYDB 作者写了详细的实现教程,教程地址: https://ziyang.moe/cs/project/mydb/
Github 地址:https://github.com/CN-GuoZiyang/MYDB
编译器
Mini-Compiler 是一个 Mini 版本的入门级编译器,基于 Java 语言编写,有助于初学者了解面向对象编程语言编译器的运行原理。
代码示例:
可以看到,代码注释还是非常清晰的,一共只有 7 个类。
不过,想要搞懂这个项目难度会远大于普通的业务类型项目,像核心类 Parser (语法解析器)的代码量接近有 2000 行(其它 6 个类代码量比较少)。
Github 地址:https://github.com/chenyuwangjs/A-tutorial-compiler-written-in-Java 。
下面是一些相关的学习资料 :
国外公开课 Lab
手写关系型数据库
MIT 6.830/6.814: Database Systems 这门课程的内容非常适合想要深入学习数据库原理的小伙伴。这门课程的 lab 是使用 Java 语言一步一步实现一个关系型数据库。
课程地址:http://db.lcs.mit.edu/6.830/ 。
- 课程代码:https://github.com/MIT-DB-Class/simple-db-hw 。
- 课程讲义:https://github.com/MIT-DB-Class/course-info-2018/ 。
- 课程视频:https://www.youtube.com/playlist?list=PLfciLKR3SgqOxCy1TIXXyfTqKzX2enDjK 。
网络上有一些相关的文章分享:
另外,UCB CS186: Introduction to Database System 的这门课程 lab 也是使用 Java 实现一个关系型数据库。
手写分布式 KV 存储
MIT6.824: Distributed System 这门课程出品自 MIT 大名鼎鼎的 PDOS 实验室,授课老师 Robert Morris 教授。Robert Morris 曾是一位顶尖黑客,世界上第一个蠕虫病毒 Morris 病毒就是出自他之手。
这门课程的 lab 会循序渐进带你实现一个基于 Raft 共识算法的 KV-store 框架,让你在痛苦的 debug 中体会并行与分布式带来的随机性和复杂性。
- 课程网站:https://pdos.csail.mit.edu/6.824/schedule.html 。
- 课程视频(中文翻译):https://www.bilibili.com/video/BV1R7411t71W 。
相关资料:
- MIT6.824: Distributed System(中文翻译 wiki): https://mit-public-courses-cn-translatio.gitbook.io/mit6-824/
- 如何的才能更好地学习 MIT6.824 分布式系统课程?:https://www.zhihu.com/question/29597104
视频类实战项目教程
大家有没有比较好的实战项目视频分享推荐下?慕课网上面的实战课程虽然多,但是,说实话哈,有一些质量都不过关,价格也不便宜。求球友分享优质的实战项目视频教程。
项目经验常见问题解答(补充)
你在项目经历中不涉及的知识点,但在技能介绍中提到的知识点也很大概率会被问到。像 Redis 这种基本是面试 Java 后端岗位必备的技能,我觉得大部分面试官应该都会问。
一个项目的话不是不可以,但你一定要保证这个项目不能太鸡肋。如果太鸡肋的话,简历关可能就直接 pass,而且面试官提问都不好提。
如果你没有项目经验的话,建议你尽量一边学习各种框架和中间件一边做一个完整且有一些亮点的项目作为自己的项目经验。
什么项目算是有亮点的或者是面试官认为有价值的?
最有价值的当然是你参加各种大公司组织的各种大赛(比如阿里的天池软件设计大赛)而做的项目,如果参加这种赛事能获奖的话,项目含金量非常高。即使没获奖也没啥,也可以写简历上。
跟着老师或者普通公司做的项目的话,一般都是面向企业级别,一般很少会用到分布式/微服务,基本都是单机,这种项目的含金量稍低,即使你的业务很复杂。遇到这种情况可以考虑说自己去对项目进行改进,别怕花时间,某个时间用心做好一件事情就好比如你对项目的数据模型进行改进、引入缓存提高访问速度等等。
自己做的项目的话,我觉得一定要:尽量和别人避开,别网上流传一个项目,然后自己名字不改,啥也不做就写简历上了。
项目太简单怎么办?
项目太简单的话,不光是影响简历通过的概率,还会影响到你的面试准备,毕竟面试中的重点就是项目经历涉及到的知识点,如果你的项目经历比较简单的话,面试官直接不知道问啥了。个人建议你可以参考《Java 面试指北》中对应的文章对项目经历进行完善改进!
另外,你还要保证自己的项目的不是烂大街那种(比如商城、博客......),自己参加比赛做的项目或者是企业真实项目是比较好的。
如何优化项目经历性价比更高?
面试之前,你可以跟着网上的教程,从性能优化方向入手去改进一下自己的项目。为什么建议从性能优化方向入手呢?因为性能优化方向改进相比较于业务方向的改进性价比会更高,更容易体现在简历上。并且,更重要的是,性能优化方向更容易在面试之前提前准备,面试官也更喜欢提问这类问题。
你项目没有用到的性能优化手段,只要你搞懂吃透并且觉得合理,你就完全可以写在简历上。不过,建议你还是要实践一下,压测一波,取得的成果也要量化一下比如我使用 xxx 技术解决了 xxx 问题,系统 qps 从 xxx 提高到了 xxx。
必须是微服务项目才有亮点?
个人认为也没必要非要去做微服务或者分布式项目,不一定对你面试有利。微服务或者分布式项目涉及的知识点太多,一般人很难吃透。并且,这类项目其实对于校招生来说稍微有一点超标了。即使你做出来,很多面试官也会认为不是你独立完成的。
其实,你能把一个单体项目做到极致也很好,对于个人能力提升不比做微服务或者分布式项目差。如何做到极致?代码质量这里就不提了,更重要的是你要尽量让自己的项目有一些亮点(比如你是如何提升项目性能的、如何解决项目中存在的一个痛点的),项目经历取得的成果尽量要量化一下比如我使用 xxx 技术解决了 xxx 问题,系统 qps 从 xxx 提高到了 xxx。
能不能推荐一些一些优质线上问题/系统性能优化案例?
请看这个帖子:https://t.zsxq.com/iYZNBmA 。
如何准备项目经历?
你可以从下面几个方面来准备项目的回答(欢迎大家补充):
- 你对项目整体设计的一个感受(面试官可能会让你画系统的架构图)
- 你在这个项目中你负责了什么、做了什么、担任了什么角色。
- 从这个项目中你学会了那些东西,使用到了那些技术,学会了那些新技术的使用。
- 你在这个项目中是否解决过什么问题?怎么解决的?收获了什么?
- 你的项目用到了哪些技术?这些技术你吃透了没有?举个例子,你的项目经历使用了 Seata 来做分布式事务,那 Seata 相关的问题你要提前准备一下吧,比如说 Seata 支持哪些配置中心、Seata 的事务分组是怎么做的、Seata 支持哪些事务模式,怎么选择?
- 你在这个项目中犯过的错误,最后是怎么弥补的?
相关帖子:面试的时候怎么准备项目的回答
去外包对自己的简历有影响么?
有很多初入职场找工作的小伙伴,由于没有什么经验,自己的能力也一般,加上竞争压力太大。导致自己都是基本收到都是各种外包机构的面试邀请,最后,没办法就去了外包公司。
然后,很多小伙伴就会担心自己的外包工作经历会对自己的简历产生影响。
比如下面这个就是一位星球的匿名用户的提问。
其实,去外包对简历的影响,主要还是看你去的公司和经历的项目,比如你在 ThoughtWorks 做外包的话我觉得对你的简历就没啥影响,甚至还可能是加分项。我的很多同事跳槽,都是去了字节、阿里这些大公司。
另外,去了外包之后以后只能混外包这种说法有点自欺欺人。
首先,外包的技术深度确实不比大公司,这点没办法,根本属性决定了。然后,外包公司一般会让你会很多东西,什么东西都想让你了解一下,这可能会导致你没有一门比较精通的技术。你是Java程序员,下个项目需要你是IOS开发,然后你就要自己学,这个还是很坑的。
不过,刚毕业的话在外包干两年还是能学到一些东西的,因为你在外包公司的话,大概率会经历大量的实战项目。。
其实,最重要的是,自己平时要注意多多思考和学习,勿要浮于表面就好了。
很多人抱怨抱怨公司工作强度很多大,就我来看,很多外包公司的工作强度甚至比不上甲方的程序员。
按照大众的话来说,最好是不要去外包公司,这点是没啥问题的。不过, 如果说你目前正在外包公司工作或者你只能找到外包工作的话,不要一味抱怨,只要自己能学到东西就好!
下面是一些读者投稿的真实外包工作经历,感兴趣的小伙伴可以看看:
- 入职外包一个月的感受!(后续:外包一年,拿到某金融上市公司和某鸟的 offer)
- 二本本科,银行外包开发工作 4 个月有余。聊聊外包公司工作的一些真实感受!
- 我在华为外包一年的经历分享。
- 我,法律专业,转行程序员。聊聊我的外包工作经历
- 我在蚂蚁外包的这段时光
- 朋友被裁员之后的工行、华为外包工作经历分享
- 我在国企外包一年的经历和感受
- 转行了!文科生转程序员的外包工作经历分享
- 请不要“妖魔化”外包。
如果面试官问“你有什么问题问我吗?”,该如何回答?
我还记得当时我去参加面试的时候,几乎每一场面试,特别是 HR 面和高管面的时候,面试官总是会在结尾问我:“问了你这么多问题了,你有什么问题问我吗?”。
短暂地思考之后,我的内心会陷入短暂的纠结中:我该问吗?不问的话面试官会不会对我影响不好?问什么问题?问这个问题会不会让面试官对我的影响不好啊?
面试是一个双向选择的过程
就技术面试而言,回答这个问题的时候,只要你不是触碰到你所面试的公司的雷区,那么我觉得这对你能不能拿到最终 offer 来说影响确实是不大的。
但是,我建议还是可以好好回答这个问题。
面试本身就是一个双向选择的过程,你对这个问题的回答也会侧面反映出你对这次面试的上心程度,你的问题是否有价值,也影响了你最终的选择与公司是否选择你。
面试官在技术面试中主要考察的还是你这样个人到底有没有胜任这个工作的能力以及你是否适合公司未来的发展需要,很多公司还需要你认同它的文化,我觉得你只要不是太笨,应该不会栽在这里。除非你和另外一个人在能力上相同,但是只能在你们两个人中选一个,那么这个问题才对你能不能拿到 offer 至关重要。有准备总比没准备好,给面试官留一个好的影响总归是没错的。
但是,就非技术面试来说,我觉得好好回答这个问题对你最终的结果还是比较重要的。
总的来说,不管是技术面试还是非技术面试,如果你想赢得公司的青睐和尊重,我觉得我们都应该重视这个问题。
不要问太 Low 的问题
回答这个问题很重要的一点就是你没有必要放低自己的姿态问一些很虚或者故意讨好面试官的问题,也不要把自己从面经上学到的东西照搬下来使用。
面试官也不是傻子,特别是那种特别有经验的面试官,你是真心诚意的问问题,还是从别处照搬问题来讨好面试官,人家可能一听就听出来了。
总的来说,还是要真诚。
除此之外,不要问太 Low 的问题,会显得你整个人格局比较小或者说你根本没有准备(侧面反映你对这家公司不上心,既然你自己都不上心,公司为什么要录用你呢?)。举例几个比较 Low 的问题,大家看看自己有没有问过其中的问题:
- 贵公司的主要业务是什么?(面试之前自己不知道提前网上查一下吗?)
- 贵公司的男女比例如何?(考虑脱单?记住你是来工作的!)
- 贵公司一年搞几次外出旅游?(你是来工作的,这些娱乐活动先别放在心上!)
- ......
有哪些有价值的问题值得问?
针对这个问题。笔主专门找了几个专门做 HR 工作的小哥哥小姐姐们询问并且查阅了挺多前辈们的回答,然后结合自己的实际经历,我概括了下面几个比较适合问的问题。大家在面试的时候,可以根据自己对于公司或者岗位的了解程度,对下面提到的问题进行适当修饰或者修改。
另外,这些问题只是给没有经验的朋友一个参考,如果你还有其他比较好的问题的话,那当然也更好啦!
面对 HR 或者其他 Level 比较低的面试官时
- 能不能谈谈你作为一个公司老员工对公司的感受? (这个问题比较容易回答,不会让面试官陷入无话可说的尴尬境地。另外,从面试官的回答中你可以加深对这个公司的了解,让你更加清楚这个公司到底是不是你想的那样或者说你是否能适应这个公司的文化。除此之外,这样的问题在某种程度上还可以拉进你与面试官的距离。)
- 能不能问一下,你当时因为什么原因选择加入这家公司的呢或者说这家公司有哪些地方吸引你?有什么地方你觉得还不太好或者可以继续完善吗? (类似第一个问题,都是问面试官个人对于公司的看法,)
- 我觉得我这次表现的不是太好,你有什么建议或者评价给我吗?(这个是我常问的。我觉得说自己表现不好只是这个语境需要这样来说,这样可以显的你比较谦虚好学上进。)
- 接下来我会有一段空档期,有什么值得注意或者建议学习的吗? (体现出你对工作比较上心,自助学习意识比较强。)
- 这个岗位为什么还在招人? (岗位真实性和价值咨询)
- 大概什么时候能给我回复呢? (终面的时候,如果面试官没有说的话,可以问一下)
- ......
面对部门领导
- 部门的主要人员分配以及对应的主要工作能简单介绍一下吗?
- 未来如果我要加入这个团队,你对我的期望是什么? (部门领导一般情况下是你的直属上级了,你以后和他打交道的机会应该是最多的。你问这个问题,会让他感觉你是一个对他的部门比较上心,比较有团体意识,并且愿意倾听的候选人。)
- 公司对新入职的员工的培养机制是什么样的呢? (正规的公司一般都有培养机制,提前问一下是对你自己的负责也会显的你比较上心)
- 以您来看,这个岗位未来在公司内部的发展如何? (在我看来,问这个问题也是对你自己的负责吧,谁不想发展前景更好的岗位呢?)
- 团队现在面临的最大挑战是什么? (这样的问题不会暴露你对公司的不了解,并且也能让你对未来工作的挑战或困难有一个提前的预期。)
面对 Level 比较高的(比如总裁,老板)
- 贵公司的发展目标和方向是什么? (看下公司的发展是否满足自己的期望)
- 与同行业的竞争者相比,贵公司的核心竞争优势在什么地方? (充分了解自己的优势和劣势)
- 公司现在面临的最大挑战是什么?
Java 优质面试视频推荐
文字看累了,还可以看看视频!推荐几个不错的 Java 面试相关的视频。
1、中华石杉老师的《Java 面试突击第一季》
即使是19年那会出来的视频,放到现在依然是适用的!对于想要进 Java 生态为主的公司比如美团、阿里非常有帮助!主要讲的是高并发高可用相关的内容。
地址:https://www.bilibili.com/video/BV1B4411h7Nz
这份资料对应的笔记:https://doocs.github.io/advanced-java/#/
2、图灵学院的《Java 常见面试题详解系列》
涵盖 Java 核心知识、数据库以及常见框架,拿数据库和缓存来说:数据库以面试常问的 MySQL 为例介绍了索引、锁、事务、主从同步、MyISAM 和 InnoDB 的区别、分库分表、慢查询处理等面试题。缓存以面试常问的 Redis 为例介绍了 Redis 常见数据库结构、缓存过期策略、 缓存穿透、缓存击穿、缓存雪崩、数据库和缓存一致性保证、Redis 高可用等面试题。
地址:https://www.bilibili.com/video/BV1XU4y1J7Dr
3、尚硅谷周阳老师的 《Java 面试题第三季》
Java 培训领域比较出名的周阳老师的作品,内容涵盖算法、Java 核心知识、数据库以及常见框架。
可以重点看看并发和 Spring 这块,比其他老师讲的要深入和好理解很多。
地址:https://www.bilibili.com/video/BV1Hy4y1B78T
前两季视频地址 :
- Java 面试题第一季 :https://www.bilibili.com/video/BV1Eb411P7bP
- Java 面试题第二季 :https://www.bilibili.com/video/BV18b411M7xz
4、图灵的《分布式面试核心面试题系列》
主要是分布式相关的内容,涵盖负载均衡、分布式 ID、分布式事务、Dubbo、Zookeeper 、Redis。
地址:https://www.bilibili.com/video/BV1Mz4y1Z7bM
5、享学的《Java 面试全解析系列》
内容比较杂,可以挑选自己比较感兴趣面试题学习。可以重点看看数据库这块,对于常见的 MySQL 面试题比如 MySQL 索引数据结构介绍的比较详细。