Every line of code runs in order. Therefore, the code enters the first (outer) loop, and finds another loop. It will now run the entire second (inner) loop to completion until it proceeds to the next line, where it continues with the outer loop execution.
So, for the first iteration of the outer loop, i == 0.
Now it runs inner loop. The first iteration, j == 0. It runs code for [0,0].
Now second iteration for inner loop, j == 1. It runs code for [0,1].
Continuing, j == 2, runs code for [0,2]
Exits inner loop, because j < 3 won't be true anymore.
Then it proceeds to the second iteration of the outer loop, i == 1.
You can probably see how it goes from here.
Yes, the inner loop goes through all the columns before it breaks out of the inner loop. The next thing it encounters is a closing brace '}' which means go back up and get the next value in the outer loop.
Sometimes it is helpful to rename the variables like this:
Try going through it with pencil and paper, remembering the inner loop iterates thrice for every one iteration of the outer loop, as you said. Don't hard‑code the numbers. Use the field of the arrays instead. Much less error‑prone:-Since you are iterating both arrays forwards and not omitting any elements a for‑each loop would be easier to write.