Java basics - how much do you not know?

1. && and ||

1. Guess what the following program will print?
insert image description here

The result is the following:
insert image description here

2. Explain
the && symbol. When the left side is false, the judgment on the right will no longer be executed, because the program can already be determined to be false, so b++ is not executed

When the || symbol is true, the judgment on the left is not executed, because the program can be determined to be true, so d++ is executed

3. The use of this judgment mechanism
can solve the problem of sequential judgment. For example, the following program
insert image description here
first judges whether it is not empty and then judges the length of the string. It is not wrong, because when s is empty, it will not execute s.length()== 5

Conversely, if the length of the string is judged first, a null pointer exception will be thrown immediately
insert image description here

Two, Integer and int

1. Can you do the following questions correctly? What is the output?
insert image description here

result:
insert image description here

2. Explain that
Integer is the wrapper class of int, Integer refers to the newly created object in the heap memory, and int refers to the data in the java constant pool

Integer and int will have an unboxing and boxing mechanism
. When comparing int and Integer, Integer will be automatically unboxed for int
. When assigning Integer data to int
, Integer will be automatically unboxed
. When comparing int with ==, the comparison is the size of the value.
When comparing int and Integer with ==, Integer will be automatically unboxed to int, and the comparison is the size of the value.
When comparing Integer and Integer with ==, the comparison is two Whether the objects are references to the same

The small details of int autoboxing: for the data of -128~127, int will judge whether there is an Integer object with the corresponding value in the cache, if so, return the object directly, otherwise create a new object, and put the object in the cache middle. This is done to save only one copy of frequently used data and reduce memory waste

package com.wu.hello.main;

public class Main {
    
    
    public static void main(String[] args) {
    
    
        int a=0;
        int b=0;
//        true,int和Integer用==比较时,Integer会自动拆箱为int,比较的是值的大小
        System.out.println(a==b);

        Integer c=new Integer(1);
        Integer d=new Integer(1);
//        false,Integer和Integer用==比较时,比较的是两个对象是否是同一个的引用
        System.out.println(c==d);

        Integer e=2;
        Integer f=2;
//        true,int自动装箱的小细节:对于-128~127的数据,int会判断缓存里有没有相对应值的Integer对象,
//        如果有,直接返回该对象,否则新创建一个对象,并把对象放到缓存中。
        System.out.println(e==f);

        Integer g=200;
        Integer h=200;
//        false,int自动装箱的小细节:对于-128~127的数据,int会判断缓存里有没有相对应值的Integer对象,
//        如果有,直接返回该对象,否则新创建一个对象,并把对象放到缓存中。
        System.out.println(g==h);

        Integer i=new Integer(200);
        int j=new Integer(200);
//        true,int和Integer用\=\=比较时,Integer会自动拆箱为int,比较的是值的大小
        System.out.println(i==j);
    }
}

3. The difference between String, StringBuffer and StringBuilder

1. Difference

String StringBuffer StringBuilder
memory location java constant pool/heap space heap space heap space
thread safety issues thread safety thread safety thread unsafe
Is it variable Immutable variable variable
efficiency slowest generally fastest
scenes to be used Use when no changes are required Multithreading single thread

2. What does it mean that String is immutable?
For example, the string s="abc", if you want s="adc", you can't directly change the character 'b' to 'd', but create a new object "adc" and let s refer to it

3. Why is String the slowest?
Because the String object is immutable, a new object needs to be generated every time it is modified,
such as string splicing: "abc"+"d", a new string object "abcd" needs to be created, and StringBuffer and StringBuilder can be directly modify the current object

4. What thread is unsafe?
In the case of multi-threading, errors will occur, for example: multiple threads modify the StringBuilder object at the same time

package com.wu.hello.main;

public class Main {
    
    
    public static void main(String[] args) throws InterruptedException {
    
    
        StringBuilder s=new StringBuilder();
        for (int i = 0; i < 10; i++){
    
    
            new Thread(new Runnable() {
    
    
                @Override
                public void run() {
    
    
                    for (int j = 0; j < 1000; j++){
    
    
                        s.append("a");
                    }
                }
            }).start();
        }
        Thread.sleep(1000);
        System.out.println(s.length());
    }
}

insert image description here

An exception was reported, and it should output 10000 logically. Because of the multi-threading problem, the result was wrong, which means that the thread is not safe.

5. The reason why StringBuilder thread is not safe

Because multiple threads operate on the same StringBuilder object, and the method of StringBuilder is not locked, multiple threads enter the method at the same time, resulting in inconsistencies. For example, thread 1 obtains data after entering the method, and thread 2 modifies the string , then what thread 1 gets is dirty data

And each method of StringBuffer is synchronized, so multi-threading is no problem

insert image description here

6. Similarly, HashMap and HashSet are non-thread-safe. In a multi-threaded environment, ConcurrentHashMap and ConcurrentHashSet can be used instead, of course, the efficiency will be reduced

4. Is i+1<i actually true?

1. Written test question: Is there a number i+1<i? exist?
It exists in the computer, the number of Int type occupies 32 bits, when the int is the maximum value, add 1, then it will become the minimum value

package com.wu.hello.main;

public class Main {
    
    
    public static void main(String[] args) throws InterruptedException {
    
    
        int maxValue = Integer.MAX_VALUE;
        System.out.println(maxValue);

        System.out.println(maxValue+1<maxValue);
    }
}

insert image description here

5. The ignorant null problem

1. Look at the program first

package com.wu.hello.main;

public class NULL {
    
    

    public static void haha(){
    
    
        System.out.println("haha");
    }

    public static void main(String[] args) throws InterruptedException {
    
    
        ((NULL)null).haha();
    }
}

2. What is this thing? Can this program really run? real!
insert image description here

3. Explanation
In fact, NULL is the name of a class. In java, null can be converted into any object. After the transfer, it is equivalent to the following program:

package com.wu.hello.main;

public class NULL {
    
    

    public static void haha(){
    
    
        System.out.println("haha");
    }

    public static void main(String[] args) throws InterruptedException {
    
    
        NULL n=null;
        n.haha();
    }
}

So, you probably get it! haha() is a static method, and null objects can also be called! Of course, if it is not a static method, a null pointer exception will be reported.

insert image description here

6. How many rounds do you know about integer division?

package com.wu.hello.main;

public class Main {
    
    

    public static void main(String[] args) {
    
    
        int a=20;
        int b=6;

        //方法1
        System.out.println((int)Math.ceil((double) a/b));

        //方法2
        System.out.println(a/b+(((a%b)!=0)?1:0));

        //方法3
        System.out.println((a+b-1)/b);

    }
}


insert image description here

The most commonly used upward rounding is method 3.

7. Will this work too?

1. Look at the program first

package com.wu.hello.main;

public class Main {
    
    

    public static void main(String[] args) {
    
    
        https://www.baidu.com/;
        System.out.println("haha");
    }
}

2. Do you think this program can run?
The answer is yes
insert image description here

3. Explanation
The actual program is as follows:

package com.wu.hello.main;

public class Main {
    
    

    public static void main(String[] args) {
    
    
        https:
        System.out.println("haha");
    }
}

In fact, https: is the way of writing the goto statement. This way of writing is almost abandoned, because the goto statement will make the program messy and difficult to maintain.

You can see the following program to understand the usage of goto:

package com.wu.hello.main;

public class Main {
    
    

    public static void main(String[] args) {
    
    
        https:
        while (true){
    
    
            break https;
        }
        System.out.println("haha");
    }
}

Java has optimized the goto syntax of C++, which can only be followed by break and continue to jump out of the loop or re-execute the loop

Eight, multi-threaded bug?

1. Look carefully at the following program. Both thread 1 and thread 3 can prove that stop is true. Why can't thread 2 stop?

package com.wu.hello.main;


public class Main {
    
    

    static boolean stop = false;

    public static void main(String[] args) {
    
    


//        线程1
        new Thread(()->{
    
    
            try {
    
    
                Thread.sleep(100);
            } catch (InterruptedException e) {
    
    
                throw new RuntimeException(e);
            }
            stop=true;
            System.out.println("线程1执行完毕,stop="+stop);
        }).start();

//        线程2
        new Thread(()->{
    
    
            int i=0;
            while (!stop){
    
    
                i++;
            }
            System.out.println("线程2执行完毕,i="+i);
        }).start();

//        线程3
        new Thread(()->{
    
    
            try {
    
    
                Thread.sleep(200);
            } catch (InterruptedException e) {
    
    
                throw new RuntimeException(e);
            }
            System.out.println("线程3执行完毕,stop="+stop);
        }).start();

    }
}


insert image description here

2. Explain

First, let's look at Baidu's explanation:
(1), JIT

Just-in-time Compilation (JIT) is a technique that improves the performance of bytecode-compiled languages ​​by translating bytecode into machine code at runtime.

(2), hot code

In the Java compilation system, in the process of turning a Java source code file into a computer-executable machine instruction, two stages of compilation are required. The first stage is to convert the .java file into a .class file. The second stage of compilation is the process of converting .class into machine instructions.

When the JVM finds that a certain method or code block runs particularly frequently, it will consider it a "hot spot code". JIT will translate some "hot code" classes into local machine-related machine codes, optimize them, and then cache the translated machine codes for next use.

It is precisely because of the jit problem that the while loop is optimized by jit after being executed multiple times, and the program has been modified

3. Proof
Adding the -Xint parameter to the VM, using the meaning of interpreting execution,
insert image description here
insert image description here
we can see that the program executed 22428641 times, and finally stopped, which solved this problem, but not using jit will greatly reduce the performance of the program, because the virtual machine It will not optimize for us, so that the program that is optimized without error will not be optimized

4. A good solution
For multi-threaded shared resources, you can use volatile to modify variables. Volatile can help us ensure the visibility and order of the program, but it still cannot guarantee atomicity

package com.wu.hello.main;


public class Main {
    
    

    static volatile boolean stop = false;

    public static void main(String[] args) {
    
    


//        线程1
        new Thread(()->{
    
    
            try {
    
    
                Thread.sleep(100);
            } catch (InterruptedException e) {
    
    
                throw new RuntimeException(e);
            }
            stop=true;
            System.out.println("线程1执行完毕,stop="+stop);
        }).start();

//        线程2
        new Thread(()->{
    
    
            int i=0;
            while (!stop){
    
    
                i++;
            }
            System.out.println("线程2执行完毕,i="+i);
        }).start();

//        线程3
        new Thread(()->{
    
    
            try {
    
    
                Thread.sleep(200);
            } catch (InterruptedException e) {
    
    
                throw new RuntimeException(e);
            }
            System.out.println("线程3执行完毕,stop="+stop);
        }).start();

    }
}

insert image description here

5. In detail, volatile
thread safety should consider three aspects: visibility, order, and atomicity

Visibility: One thread modifies shared variables, and another thread can see the latest results

Orderedness: the code in a thread is executed in the order it is written

Atomicity: Multiple lines of code in one thread run as a whole, during which no other thread code can jump in the queue

The visibility of the program is like this example, which solves the problem that thread 2 cannot read the latest value of stop

Atomicity is, for example, the following program, one thread pair a+=5, another thread a-=5, then the result of a must be 0? The answer is no, 5 and -5 may also appear, because although a+=5 is one line of code, it is multiple instructions after compilation, including data fetching, calculation, storage back, etc. These operations cannot be guaranteed to be atomic Yes, after thread 1 gets the data, thread 2 modifies the data, and thread 1 reads the dirty data

package com.wu.hello.main;


import java.util.concurrent.CountDownLatch;

public class Main {
    
    
    
    static int a=0;

    public static void main(String[] args) throws InterruptedException {
    
    
        
        CountDownLatch latch = new CountDownLatch(2);

        //        线程1
        new Thread(() -> {
    
    
            a += 5;
            latch.countDown();
        }).start();

        //        线程2
        new Thread(() -> {
    
    
            a -= 5;
            latch.countDown();
        }).start();

        latch.await();

        System.out.println("a=" + a);
    }

}

Orderliness means that in the following program, it is obvious that there may be three printing situations:
x=0
y=0

x=1
y=1

x=0
y=1

So, is it possible that x=1 and y=0? The answer is possible, because the program will optimize the program when compiling, and the execution order of the code can be changed without changing the result of a single thread, which means that thread 1 may first execute x=1; and then execute y=1;, resulting in x=1 and y=0

package com.wu.hello.main;


import java.util.concurrent.CountDownLatch;

public class Main {
    
    

    static int x=0;
    static int y=0;

    public static void main(String[] args) throws InterruptedException {
    
    

        CountDownLatch latch = new CountDownLatch(2);

        //        线程1
        new Thread(() -> {
    
    
            y=1;
            x=1;
        }).start();

        //        线程2
        new Thread(() -> {
    
    
            System.out.println("x="+x);
            System.out.println("y="+y);
        }).start();
    }

}

volatile modified variables can solve this problem

package com.wu.hello.main;


import java.util.concurrent.CountDownLatch;

public class Main {
    
    

    static volatile int x=0;
    static volatile int y=0;

    public static void main(String[] args) throws InterruptedException {
    
    

        CountDownLatch latch = new CountDownLatch(2);

        //        线程1
        new Thread(() -> {
    
    
            y=1;
            x=1;
        }).start();

        //        线程2
        new Thread(() -> {
    
    
            System.out.println("x="+x);
            System.out.println("y="+y);
        }).start();
    }

}

So in summary, volatile can guarantee visibility and order, while atomicity needs to be solved by lock mechanism

If you think the writing is good, please give it a thumbs up!

Guess you like

Origin blog.csdn.net/weixin_52115456/article/details/131227316