After reading "effective Java": I collate these 50 tips

osc_1psr53ow 2020-11-11 12:37:03
reading effective java collate tips

《Effective Java》Java classics , Required reading . If the principles of this article can be strictly followed , To write API The quality of their own code , Will greatly improve the coding quality .

The following is only a record of my own arrangement , I suggest reading the original text . In order to focus on knowledge , Some instructions have been deliberately omitted . It is equivalent to an abstract .

1、 Consider replacing constructors with static factory methods

Example :

Integer.valueOf(“1”)、Boolean.valueOf(“true”) etc. .

advantage :

  • High readability ( Method name )

  • performance ( You don't have to create objects )

  • High flexibility

Here are some explanations for the three advantages .

High readability

new Point(x,y) and,y)、Point.origin(). The constructor can only see two parameters , I don't know what it means , The latter is easier to understand .


In some cases , You can instantiate some objects in advance , Call directly when calling , There is no need to change . such as ,Boolean.

public final class Boolean implements Serializable, Comparable<Boolean> {
    // Preset two objects 
    public static final Boolean TRUE = new Boolean(true);
    public static final Boolean FALSE = new Boolean(false);
    public Boolean(boolean var1) {
        this.value = var1;
    public Boolean(String var1) {
    // Factory method 
    public static Boolean valueOf(boolean var0) {
        return var0?TRUE:FALSE; // Return the preset object , Instead of creating objects 
    // Factory method 
    public static Boolean valueOf(String var0) {
        return parseBoolean(var0)?TRUE:FALSE;
    // ... other code

High flexibility

According to the specific situation , Return subclass . Equivalent to a more powerful factory . Get directly from the parent class to the child class . It is especially suitable for tools ( Provide all kinds of API). Example :Collections.

public class Collections {
    // private , Typical factory 
    private Collections() {
    public static final List EMPTY_LIST = new EmptyList<>();
    // Factory method 
    public static final <T> List<T> emptyList() {
        return (List<T>) EMPTY_LIST;
    private static class EmptyList<E> extends AbstractList<E> implements RandomAccess, Serializable {
    // code
    // Factory method 
    public static <E> List<E> checkedList(List<E> list, Class<E> type) {
    // As the case may be , Get the corresponding subclass 
        return (list instanceof RandomAccess ?
                new CheckedRandomAccessList<>(list, type) :
                new CheckedList<>(list, type));
    // Subclass 1
    static class CheckedRandomAccessList<E> extends CheckedList<E> implements RandomAccess {
        CheckedRandomAccessList(List<E> list, Class<E> type) {
            super(list, type);
        public List<E> subList(int fromIndex, int toIndex) {
            return new CheckedRandomAccessList<>(
                    list.subList(fromIndex, toIndex), type);
    // Subclass 2
    static class CheckedList<E> extends CheckedCollection<E> implements List<E> {
    // code

2、 When there are multiple constructors , Consider using constructors

Especially in progress Android When developing , It's going to happen . It's usually an object , Having multiple member variables may require initialization , Conventional methods , You need to provide a large number of constructors . for example :

// Not Android Medium AlertDialog, Easy to explain the problem , for instance 
public class AlertDialog {
    private int width;
    private int height;
    private String title;
    private String confirmText;
    private String denyText;
    private AlertDialog(){}
    public AlertDialog(int width, int height){ // A blank warning box 
    // Warning box with title 
    public AlertDialog(int width, int height, String title){ // Warning box with title 
        AlertDialog(width, height, title, " determine ");
    // Warning box with title , There's a confirmation button 
    public AlertDialog(int width, int height, String title, String confirm){
        AlertDialog(width, height, title, confirm, null);
    // Warning box with title , There's a confirmation button , Cancel button 
    public AlertDialog(int width, int height, String title, String confirm, String denyText){
        // set every thing.

There are many styles of warning boxes , For the convenience of calling , Multiple constructors must be provided . Otherwise, when the user calls , Only full constructors can be used , Error prone and unable to read . Extremely inflexible . If you take another way , It can solve the problem , But it takes a lot of experience to deal with concurrency :

// Not Android Medium AlertDialog, Easy to explain the problem , for instance 
public class AlertDialog {
    private int width;
    private int height;
    private String title;
    private String confirmText;
    private String denyText;
    public AlertDialog(){}// Empty constructors 
    public void setWidth(int width){
        this.width = width;
    // other set Method 

Invocation time , By calling the set Method to set . The problem is coming. :

  • Concurrent

  • Parameter verification cannot be performed .

for example , Only objects are created , Set the title , But there's no size , This is equivalent to creating a warning box with no size .

stay Android in , A large number of controls use constructors Builder.

// Not Android Medium AlertDialog, Easy to explain the problem , for instance 
public class AlertDialog {
    private int width;
    private int height;
    private String title;
    private String confirmText;
    private String denyText;
    // private
    private AlertDialog(){}
    // Builder Use in 
    protected AlertDialog(Builder b){
        width = b.width;
        height = b.height;
        // .....
        if(width==0||height==0) throws new Exception("size must be set");
    // Constructors 
    public static class Builder {
        private int width;
        private int height;
        private String title;
        private String confirmText;
        private String denyText;
        // Be careful : Back to Builder.
        public Builder setTitle(String title) {
            this.title = title;
            return this;
        // other set...
        public AlertDialog build(){
            return AlertDialog(this);

therefore , According to the corresponding needs , Set accordingly , And in AlertDialog When it's really constructed , Check the parameters . Just like this. :

new AlertDialog.Builder().setTitle(" Tips ").build();

The above example , Will successfully throw an exception .

3、 Use private constructors or enumerative reinforcement Singleton.

Singleton A class that can be instantiated at most once . Usually , There was no problem with the previous practice . But in some advanced cases , Access by using knowledge about reflection private Constructor for , damage Singleton.

public class Elvis{
    // Be careful , public final object 
    public static final Elvis INSTANCE = new Elvis();
    private Elvis(){}

Another situation , During serialization , The object obtained by deserialization is no longer the previous object ( Destroyed Singleton), In this case , It can be handled by single element enumeration .

public enum Elvis{
    // some methods

4、 Enhance the ability of non instantiation by privatizing the constructor

There are some tool classes , It's just to provide some capabilities , You don't have any attributes , therefore , Not suitable to provide constructors . However , The missing constructor compiler will automatically add a parameterless constructor . therefore , You need to provide a private constructor . To prevent misuse within a class , Add a protective measure and a note .

public class Util{
    private Util(){
        // Throw an exception , Prevent internal miscalls 
        throw new AssertionError();

The disadvantage is that the class cannot be inherited ( Subclasses call super()).

5、 Avoid creating unnecessary objects

  • Object reuse

  • Expensive objects , Use object pool

  • Cheap object , Be careful with object pools .

modern JVM The creation and destruction of cheap objects is very fast , This is not a good time to use object pools .

6、 Eliminate outdated object references

The following three situations can cause memory leaks :

  • Self managed memory ( When the array length is reduced ,pop Out of the object is easy to cause memory leak )

  • cache

  • Monitoring and callback

Self managed memory

Be careful with your own managed memory , such as :

public class Stack{
    private Object[] elements;
    private int size = 0;
    private static final int DEFAULT_INITIAL_CAPACITY = 16;
    public Stack(){
         elements = new Object[DEFAULT_INITIAL_CAPACITY];
    public void push(Object e){
        elements[size++]=e; // allocate New heap memory and stack memory 
    public Object pop(){
        if(size==0) throw new EmptyStackException();
        return element[--size]; // pop Out element[size], The object is no longer valid . Cause of memory leak .
    private void ensureCapacity(){
            elements = Arrays.copyOf(elements, 2*size+1);

The pop-up object is no longer valid , but JVM I do not know! , So the object will always be kept , Causing memory leaks .

solve :

public Object pop(){
        if(size==0) throw new EmptyStackException();
        elements[size] = null; // Waiting for recycling 
        return element[--size];


Cached objects are easily forgotten by programmers , You need to set up a mechanism to maintain the cache , For example, periodically reclaiming a cache that is no longer in use ( Use timer ). In some cases , Use WeakHashMap Can achieve the effect of cache recycling . notes , Only the cache depends on the external environment , Instead of depending on the value ,WeakHashMap It works .

Listen or call back

Remember to unregister when using listeners and callbacks . The best implementation to ensure recycling is to use weak references (weak reference), for example , Just save them as WeakHashMap Key .

7、 Avoid display calls GC

Java Of GC There's a strong recycling mechanism , It's easy to remember : Don't show calls finalizer. It can be understood in this way :

jvm It's designed for specific hardware , However, the program is not designed for specific hardware , therefore ,java Code can't solve this problem very well gc problem ( Because it has platform differentiation ). in addition ,finalizer Performance overhead is also very high , From this point of view, it should not be used .

8、 Cover equals Please follow the general agreement

  • reflexivity .   x.equals(x) == true

  • symmetry .   At present only if y.equals(x)==true when ,x.equals(y)==true

  • Transitivity .   if(x.equals(y)&&y.equals(z)),y.equals(z)==true

  • Uniformity .

  • Non emptiness .  x.equals(null)==false

9、 Cover equals Methods always cover hashCode

To ensure that hash based collections use this class (HashMap、HashSet、HashTable), meanwhile , It's also Object.hashCode The general agreement of , Cover equals When the method is used , Must cover hashCode.

10、 Always cover toString

Object Of toString The general convention for a method is the description of the object . Pay attention to coverage , If there is a format , Please note or return strictly according to the format .

11、 Cover carefully clone

12、 Consider implementing Comparable Interface

13、 Minimize the accessibility of classes and members

The purpose is to decouple . simply , The priority of using modifiers is from large to small ,private>protected>default( default )>public. If at the beginning of the design , Designed as private After the embellishment , In the subsequent coding process, if it has to expand its effect on , You should first check to see if the design is true .

Subclasses cover superclasses , Access level lower than that of the superclass is not allowed .( Superclass protected, Subclass coverage cannot be changed to default).

Member variables are never allowed to be public . Once set to public , He gave up his ability to deal with him . This class is not thread safe . Even if it's final Of , Not allowed . Unless you want to pass public static final To expose constants . Member variables always need to use setter and getter To maintain the . There is one exception : Arrays of nonzero length . This is a source of security vulnerabilities .

public Object pop(){
        if(size==0) throw new EmptyStackException();
        elements[size] = null; // Waiting for recycling 
        return element[--size];

improvement :

private static final Thing[] PRIVATE_VALUES = {...}
// What you get at this point is “ Constant ”
public static final List<Thing> VALUS =

Another kind :

private static final Thing[] PRIVATE_VALUES = {...}
// What you get at this point is “ Constant ”
public static final Thing[] values(){
    return PRIVATE_VALUES.clone();

14、 Use access methods in public classes instead of public member variables ( similar 13)

15、 Minimize variability

16、 Composition takes precedence over inheritance

Inheritance is good for code reuse , But try not to inherit across packages . Inheritance within a package is a great way to design , Files in a package are under the control of the same programmer . But inheritance has its limitations : Subclasses depend on superclasses . Once a superclass changes , It is possible to destroy subclasses . also , If the superclass is defective , Subclasses also get “ Genetic diseases ”.

Reunite with , That is, do not extend existing classes , Instead, add an existing class to the class of . The equivalent of an existing class as a component in a new class . such , You will only use what you need , Instead of representing all the methods and member variables of an existing class . New classes can also be called “ Packaging ”, That is, in design patterns Decorate Pattern .

17、 Or design for inheritance , And provide documentation , Or you can ban inheritance

18、 Interface is better than abstract class

19、 Interfaces are only used to define types

20、 Class hierarchy takes precedence over tag classes

21、 Use function objects to represent policies

Function parameters can be passed in like listener The object of , The purpose is to use listener The method in . If you use anonymous parameters , Each call creates a new object . Can be listener Declare as a member variable , Reuse the same object every time , And you can use static fields (static Variable ). such as String Class CASE_INSENSITIVE_ORDER Domain .

22、 Give priority to static class members

The purpose of a nested class should be to serve only its peripheral classes , If it can be used in other environments in the future , Should be designed as a top-level class . A static class is equivalent to an ordinary outer class , It just happens to be declared inside a class . The usual users are :Calculator.Operation.PLUS etc. . The difference from the ordinary class is just , stay PLUS front , With 2 Prefixes , To show what it means . Non static classes must exist in external class objects . Do not manually create an internal non static class object on the outside , The creation process is :instance.New MemberClass(). It's very strange .

If the member class does not need to access the peripheral class , You need to add static, It is he who becomes a static member class , Otherwise, each instance will contain an additional reference to the peripheral object . Will affect the garbage collection mechanism .

23、 The concrete type of the generic should be specified , Instead of using native types directly .

for example , You should specify List<E>, It is not recommended to use List.

24、 Eliminate non first inspection warnings

In the use of IDE When encoding , Powerful IDE Will be prompted during your coding process warning, It needs to be eliminated as much as possible warning, At least , You should be careful of these warning. Use with caution SuppresWarning, If IDE You can solve this problem by adding this annotation warning, Please don't do that . If you really want to use , Please add a note to explain why .

25、 Lists take precedence over arrays

Analogy generics , Arrays are flawed .List<SuperClass> and List<SubClass> It doesn't matter , and Sub[] yes Super[] Subclasses of .

// Fails at runtime
Object[] objectArray = new Long[1];
objectArray[0] = "I don't fit in"; // throw exception
// won't compile
List<Object> ol = new ArrayList<Long>(); // Incompatible types
ol.add("I don't fit in");

You can see that in the code , Use generics , You'll find mistakes in advance .

26、 Give preference to generics

27、 Give priority to generic methods

28、 Use restricted wildcards to promote API The flexibility of the


//public class Stack<E>{
// public Stack();
// public void push(E e);
// public E pop();
// public boolean isEmpty();
public void pushAll(Iterator<? extends E> src){
    for(E e : src)
public void popAll(Collection<? super E> dst){
// Get and Put Principle

all comparable and comparator All consumers (Consumer).

29、 Type safe heterogeneous containers are preferred

30、 use enum Instead of int Constant

public enum Apple { FUJI, PIPPIN, GRANNY_SMITH }
public enum Orange { NAVEL, TEMPLE, BLOOD }

The enumeration type is in java It's very powerful , When you need a fixed set of constants , Use enum Than int Much better . For example, code readability , Safety and so on .

31、enum Replace ordinal numbers with instance fields

// bad solution
public enum Ensemble {
    public int numberOfMusicians() { return ordinal() + 1; }
// improvement
public enum Ensemble {
    SOLO(1), DUET(2), TRIO(3), QUARTET(4), QUINTET(5),
    private final int numberOfMusicians;
    Ensemble(int size) { this.numberOfMusicians = size; }
    public int numberOfMusicians() { return numberOfMusicians; }

Never like the first way , Using ordinal numbers to access enum, You need to use parameters in the constructor to initialize .

32、 use EnumSet Instead of bit fields

public class Text{
    public static final int STYLE_BOLD = 1 << 0; // 1
    public static final int STYLE_ITALIC = 1 << 1; // 2
    public static final int STYLE_UNDERLINE = 1 << 2; // 4
    public static final int STYLE_STRIKETHROUGH = 1 << 3; // 8
    public void applyStyles(int styles){
        // ...
text.applyStyles(STYLE_BOLD | STYLE_ITALIC);

This is called bitmap method , But there's a better way to pass multiple sets of constants ——EnumSet.

public class Text{
    // Notice here , It uses Set instead of EnumSet
    public void applyStyles(Set<Style> styles){
        // ...
text.applyStyles(EnumSet.of(Style.BOLD, Style.ITALIC));

33、 use EnumMap Instead of ordinal index

Don't use... At any time enum Of ordinal() Method .

34、 Simulate scalable enumeration with interfaces

35、 Annotations take precedence over naming patterns

36、 Insist on using Override annotation

38、 Check the validity of the parameters

Public method check parameters , Parameter exception needs to run out Exception. Private methods use assertions assertion Inspection parameters .

39、 Make protective copies when necessary

Suppose the client of a class will do its best to break the constraints of the class , So you have to design the program protectively . The following is the design of an immutable class .

public Period(Date start, Date end){
    this.start = new Date(start); // A copy of the value is used , The original object is not used ( The pointer )
    this.end = new Date(end);
        throw new IllegalArgumentException(start + " after " + end)

Be careful : The protective copy is done before checking the parameters , Prevent the effects of multithreading . Do not use clone Method to make a protective copy .

The above methods prevent the modification of the incoming parameters , But for get Method to get the object , It can still be modified , You can prevent this attack by .

public Date start(){
    return new Date(start);
public Date end(){
    return new Date(end);

40、 Carefully design method signatures

41、 Be careful with heavy loads

42、 Be careful with variable parameters

43、 return 0 An array or collection of lengths , instead of null

null Generally used to indicate that it has not been initialized or processed , If the method returns null, You need to do more at the top , To prevent NPE.

44、 For all exported API Element to write a document comment

Correct javadoc file , Each exported class is required 、 Interface 、 Constructors 、 Add document comments before methods and fields . Annotations should be implementation transparent , Just briefly describe the contract between it and the client . also , Side effects of the method should also be attached .

45、 Minimize the scope of local variables

46、for-each Prior to the for loop

for-each Get around it for Cyclic index References to variables , It's usually unnecessary —— It increases the risk of introducing errors , And once the risk happens , Hard to find . But there are three situations , Can't use for-each( notes : stay jdk1.8 It has solved these problems very well ).

  • Filter

  • transformation

  • Parallel iteration

48、 If precise answers are needed , Please avoid using float and double

float and double Is a binary floating-point operation performed , The aim is to use accurate and fast approximate calculations over a wide range of numerical values . However, they did not provide a fully accurate calculation ( Practical application , It's often met with x.99999 Other results ). In especial , In the calculation of money , They don't apply to . such as :


The result will be :0.610000000001.

To solve this problem , Need to use BigDecimal. But there are also some problems , Compared to ordinary operations , It seems more troublesome , And it's slower . Generally speaking, the latter shortcoming can be ignored , But the former can be very uncomfortable . One way to do this is to take the values that need to be processed *10( Or more ), Use int Calculate , But you need to deal with rounding and other operations yourself .

49、 The basic type takes precedence over the boxing basic type

Basic types have only values , Boxed classes have identity different from their values .

Basic types have only fully functional values , The boxing class also has non functional values :


So you may come across NPE

Basic types save space and time

50、 If there is a more precise type , Please avoid using strings

Strings are not suitable to replace other types of values .

for example :int,boolean etc.

  • Not suitable to replace enumeration type ( The first 30 strip )

  • Not suitable for aggregation type

51、 Beware of the performance of string connections

The operator “+” Multiple strings can be concatenated . But in mass use “+” Under the circumstances , Connect n The cost of strings is n The bungalow time of . This is due to the immutability of strings . In this case, please use StringBuilder Connect .

52、 Referencing objects through interfaces

53、 Interfaces take precedence over reflection mechanisms

Using the reflection mechanism brings the following problems :

  • Lost compile time type checking

  • The code is clumsy and tedious

  • Performance loss

Reflection is basically only suitable for writing components 、 code analyzer 、RPC Use it in the scene . When using the reflection mechanism , If possible , Instantiate objects as much as possible through reflection mechanisms , When accessing methods , Use a known interface or superclass .

54、 Use caution JNI

55、 Optimize carefully

A lot of computational errors are attributed to efficiency ( There is no need to achieve efficiency ), Not for any other reason —— It even includes doing stupid things blindly .                

——William A. Wulf

Don't worry about the small gains and losses of efficiency , stay 97% Under the circumstances , Immature optimization is the root of all problems .

——Donald E. Knuth

In terms of optimization , We should abide by two rules :

The rules 1: Don't optimize .

The rules 2( Only for experts ): Or don't optimize —— in other words , Before you have an absolutely clear optimization plan , Please do not optimize .

——M. A. Jackson

These maxims are more than java It's even earlier 20 year . They tell a profound truth about optimization : The disadvantages of optimization outweigh the advantages .

Try to write good programs , Instead of a quick program . Low coupling is much more important than performance . When the program is written low coupling enough , Through the tool, we found the code block of performance bottleneck , To ensure that the modification does not affect any external environment .

56、 Follow common naming rules

57、 Use exceptions only for exceptions

Don't try to do what normal code should do through exception mechanisms , such as , Check array subscripts .

jvm Exceptions are rarely optimized , Because it's only used in abnormal situations . also , If you put the code in try-catch Code block ,jvm You lose the optimizations that could have been done with it .

58、 Use the checked exception for recoverable situations , Use runtime exceptions for programming errors

If the caller is expected to recover properly , You need to use the inspected exception , Force the caller to eat try-catch Code block , Or throw them out

When a precondition violation occurs —— In case of breach of agreement , Using runtime exceptions , At this time, the program can no longer be executed .

For example, call the array of -1 Indexes .

author :Dong GuoChao

link :

 Recommended reading 
 Code comparison tool , I'll use this 6 individual 
 Share my favorite 5 A free online  SQL Database environment , It's so convenient !
Spring Boot A combination of three moves , Hand in hand to teach you to play elegant back-end interface 
MySQL 5.7 vs 8.0, You choose the one ? Net friend : I'm going to stay where I am ~

Last , I recommend you an interesting and interesting official account : The guy who wrote the code ,7 Old programmers teach you to write bug, reply interview | resources Send you a complete set of Development Notes There's a surprise

  1. 【计算机网络 12(1),尚学堂马士兵Java视频教程
  2. 【程序猿历程,史上最全的Java面试题集锦在这里
  3. 【程序猿历程(1),Javaweb视频教程百度云
  4. Notes on MySQL 45 lectures (1-7)
  5. [computer network 12 (1), Shang Xuetang Ma soldier java video tutorial
  6. The most complete collection of Java interview questions in history is here
  7. [process of program ape (1), JavaWeb video tutorial, baidu cloud
  8. Notes on MySQL 45 lectures (1-7)
  9. 精进 Spring Boot 03:Spring Boot 的配置文件和配置管理,以及用三种方式读取配置文件
  10. Refined spring boot 03: spring boot configuration files and configuration management, and reading configuration files in three ways
  11. 精进 Spring Boot 03:Spring Boot 的配置文件和配置管理,以及用三种方式读取配置文件
  12. Refined spring boot 03: spring boot configuration files and configuration management, and reading configuration files in three ways
  13. 【递归,Java传智播客笔记
  14. [recursion, Java intelligence podcast notes
  15. [adhere to painting for 386 days] the beginning of spring of 24 solar terms
  16. K8S系列第八篇(Service、EndPoints以及高可用kubeadm部署)
  17. K8s Series Part 8 (service, endpoints and high availability kubeadm deployment)
  18. 【重识 HTML (3),350道Java面试真题分享
  19. 【重识 HTML (2),Java并发编程必会的多线程你竟然还不会
  20. 【重识 HTML (1),二本Java小菜鸟4面字节跳动被秒成渣渣
  21. [re recognize HTML (3) and share 350 real Java interview questions
  22. [re recognize HTML (2). Multithreading is a must for Java Concurrent Programming. How dare you not
  23. [re recognize HTML (1), two Java rookies' 4-sided bytes beat and become slag in seconds
  24. 造轮子系列之RPC 1:如何从零开始开发RPC框架
  25. RPC 1: how to develop RPC framework from scratch
  26. 造轮子系列之RPC 1:如何从零开始开发RPC框架
  27. RPC 1: how to develop RPC framework from scratch
  28. 一次性捋清楚吧,对乱糟糟的,Spring事务扩展机制
  29. 一文彻底弄懂如何选择抽象类还是接口,连续四年百度Java岗必问面试题
  30. Redis常用命令
  31. 一双拖鞋引发的血案,狂神说Java系列笔记
  32. 一、mysql基础安装
  33. 一位程序员的独白:尽管我一生坎坷,Java框架面试基础
  34. Clear it all at once. For the messy, spring transaction extension mechanism
  35. A thorough understanding of how to choose abstract classes or interfaces, baidu Java post must ask interview questions for four consecutive years
  36. Redis common commands
  37. A pair of slippers triggered the murder, crazy God said java series notes
  38. 1、 MySQL basic installation
  39. Monologue of a programmer: despite my ups and downs in my life, Java framework is the foundation of interview
  40. 【大厂面试】三面三问Spring循环依赖,请一定要把这篇看完(建议收藏)
  41. 一线互联网企业中,springboot入门项目
  42. 一篇文带你入门SSM框架Spring开发,帮你快速拿Offer
  43. 【面试资料】Java全集、微服务、大数据、数据结构与算法、机器学习知识最全总结,283页pdf
  44. 【leetcode刷题】24.数组中重复的数字——Java版
  45. 【leetcode刷题】23.对称二叉树——Java版
  46. 【leetcode刷题】22.二叉树的中序遍历——Java版
  47. 【leetcode刷题】21.三数之和——Java版
  48. 【leetcode刷题】20.最长回文子串——Java版
  49. 【leetcode刷题】19.回文链表——Java版
  50. 【leetcode刷题】18.反转链表——Java版
  51. 【leetcode刷题】17.相交链表——Java&python版
  52. 【leetcode刷题】16.环形链表——Java版
  53. 【leetcode刷题】15.汉明距离——Java版
  54. 【leetcode刷题】14.找到所有数组中消失的数字——Java版
  55. 【leetcode刷题】13.比特位计数——Java版
  56. oracle控制用户权限命令
  57. 三年Java开发,继阿里,鲁班二期Java架构师
  58. Oracle必须要启动的服务
  59. 万字长文!深入剖析HashMap,Java基础笔试题大全带答案
  60. 一问Kafka就心慌?我却凭着这份,图灵学院vip课程百度云