The interview the way


“Drip, drip……” Master, where are we? I have an interview to catch up on.

“Master:” fast fast, the next intersection arrived. I’m so impressed with these guys, they don’t drive in.

Listening to the driver master’s complaints, can not help but think of the first limerick: red taillights in eyes, ears full of thorns flute. Sorrow is long overdue, moldering like thunder.

As soon as I got off, I trotted into a splendid hotel. No, no, no, it was a business building. The hall was a bit grand, which made me fantastical.

The interview after

Dong dong dong, please come in.

Interviewer: “The young man is very handsome. Young people are energetic. Let’s make a brief self-introduction.

Q:Hello, interviewer, My name is “Master of video stream”, from Ionia, yesLOLIn the strongest single (do not accept refutation), on single kill has not been defeated by anyone. My catchphrase is “invisible blade, the most deadly”. Of course, you can also call me AH Q. Here is my resume.

“Interviewer:” ah Q, that za also don’t make small talk, cut to the point directly. Since you are the most knowledgeable about the JVM, let’s start with your understanding of the virtual machine stack.

“Q:” Inner OS: This wave can blow X. Well… Well… A virtual machine stack, also known in its early days as the Java stack, is an area of memory that exists in the runtime data area of the JVM. It is thread-private, created when the thread is created and terminated when the thread dies.

B: well… Pretend to think 😄

As we all know, the stack has only two operations: loading and unloading, so it is a fast and efficient way to allocate storage. As for it, it does not have garbage collection problems, but its size is dynamic or fixed, so it can have stack overflow or memory overflow problems……

Interviewer: “Excuse me, you just said that there are stack overflow and memory overflow problems, can you tell me why this happens?

“Ah Q:” Yes, yes, we know that the virtual machine stack is composed of stack frames, and each method call corresponds to a stack frame. We can set the stack size with the -xss parameter. Assuming we set the virtual machine stack size too small, StackOverflowError will occur when we call too many methods, i.e. stack frames.

If our stack frame is not fixed and is set to dynamically expand, then we will not have enough memory to support stack expansion when we run out of memory, which is an OOM exception.

Interviewer: “HMMM (nodding), indicating that the young man is thinking clearly, then you just said that the stack frame setting is too small will cause the stack frame overflow problem, then we set a big point can completely avoid the stack overflow.

“Ah Q:” Sounds like to dig a hole for me, like we generally advocate the middle way, so once heard this absolute problem, must be clever: no, no, no, adjusting the stack size can only “delay” stack overflow time or reduce the risk of stack overflow.

Give you an 🌰

  1. Suppose a business logic method calls 5000 times, but a stack overflow error is thrown. We can get more stack space by setting -xss so that calls overflow at 7000 times. At this point it makes sense to adjust the stack size, as this will allow the business to work properly.

  2. In the case of “dead recursion” the stack will overflow no matter how much you increase the stack size, which makes no sense.

Interviewer: “Ok, so if you look at this simple little program, can you give an overview of how it executes in memory?

 public void test(a) {

      byte i = 15;

      int j = 8;

      int k = i + j;

}

Copy the code

Let me draw a picture just so you can understand it a little bit better


“Ah Q:” first compile the code, then look at its bytecode file. As shown on the left in the figure above, the execution process is as follows:

  1. Address of the instruction to be executed first0Deposit toPCRegister, at this time, the data of local variable table and operand stack is empty;
  2. When executing the first instructionbipush, will operand15Put it on the operand stack, and placePCThe value of the register is set to the execution address of the next instruction, i.e2;
  3. When the execution instruction address is2The operand stack data is taken out and stored in the local variable table1Because the method is an instance method0The location is storedthisThe value of thePCThe value in the register becomes3;
  4. Repeat steps 2 and 38Put it on the operand stack, and then take it out and store it in the local variable table,PCThe value in the register is also defined by3->5->6;
  5. When the address instruction is executed6,7,8, change the index position in the local table to1and2Reloads the data into the operand stack and proceedsiaddAdd operation, store the resulting value in the operand stack,PCThe value in the register is also defined by6->7->8->9;
  6. Execute operation instructionistore_3, the data in the operand stack is taken out and stored in the local variable table index is3The location of the executionreturnInstruction, method ends.

Interviewer: Inner OS: This guy seems ok. That’s a good point. Can you say whether local variables defined in methods are thread-safe?

Ah Q: “That I again use a few examples to say once.

public class LocalParaSafeProblem {





    / * *

* Thread safe

* Although StringBuilder itself is not thread safe,

* But s1 only exists in the local variable table of this stack frame,

* Since stack frames are individual copies of each thread,

* So s1 here is thread-safe

* /


    public static void method01(a) {

        // This is a local variable created within the thread

        StringBuilder s1 = new StringBuilder();

        s1.append("a");

        s1.append("b");

    }



    / * *

* Threads are not safe

* Because StringBuilder is passed in as a parameter,

* Other external threads can also access it, so the thread is not safe

* /


    public static void method02(StringBuilder stringBuilder) {

        stringBuilder.append("a");

        stringBuilder.append("b");

    }



    / * *

* Threads are not safe

* The StringBuilder is operated by multiple threads at the same time

* /


    public static void method03(a) {

        StringBuilder stringBuilder = new StringBuilder();

        new Thread(() -> {

            stringBuilder.append("a");

            stringBuilder.append("b");

        }, "t1").start();



        method02(stringBuilder);

    }



    / * *

* Threads are not safe

* Because now the method returns the StringBuilder

* Other threads outside the StringBuilder can directly modify this reference so it is not safe

* /


    public static StringBuilder method04(a) {

        StringBuilder stringBuilder = new StringBuilder();

        stringBuilder.append("a");

        stringBuilder.append("b");

        return stringBuilder;

    }





    / * *

* StringBuilder is thread safe

* Now the stringBuilder value exists in the local variable table of the current stack frame.

* No other thread can access this reference,

The stringBuilder in the local variable table is destroyed at this point

* Returns stringBuilder.toString() thread unsafe

* After toString is returned, other threads can manipulate it and String itself is not thread-safe.

* /


    public static String method05(a) {

        StringBuilder stringBuilder = new StringBuilder();

        stringBuilder.append("a");

        stringBuilder.append("b");

        return stringBuilder.toString();

    }

}



Copy the code

Seeing that this might get a little convoluted, LET me summarize: If an object is created inside a method and dies inside it, there is no thread-safety issue; Conversely, there is a thread-safety problem if the class itself is not thread-safe.

Interviewer: “Good good, well founded, then you say your understanding of heap memory.

Ah Q: “Oh, I’m so tired today. I’ve been saying this for a whole day. I don’t want to say any more.

“Interviewer:” Ok, let’s call it a day and wait for the announcement.

If you are still confused, you can follow GZH “Ah Q said code”, or add a friend qingqing-4132, Ah Q is looking forward to your arrival!