Programs (for the most part) read code line by line top to bottom, so what happens here is the program reads through the html file top to bottom and renders all that out to the screen, THEN reads the javascript file from top to bottom.
The reason why you want the script tag at the end of the body is because if your javascript file has something like document.getElementById(btn), you don't want the program to try to run that code before the button has been rendered to the screen. After all, how can the javascript do anything with that button if the button doesn't exist yet?
The exception to this is if you give the script tag the defer attribute and place it in the head. Doing this is basically saying to the program "I'm placing this script tag here, but don't do anything with it until you've finished rendering the html to the screen"
As for the onClick attributes in the html file, those aren't running any javascript straight away. Instead think of it more like a promise you're making to the computer. When you do an onClick attribute like this you are saying "There is a function in the javascript file that is linked to it, I promise it's there, you'll find it when you run the javascript file and someone clicks the button"