Your course is being a bit loose on the details.
Something that makes VHDL and Verilog somewhat tricky is that they were originally designed as languages for describing hardware for simulation. They were then later re-used as languages to describe hardware for synthesis.
To understand HDL simulation there are first a couple of basic concepts we must understand.
The first is simulation time, Simulation time is not tied to real-time, it essentially advances when all code paths are waiting for something (either a time delay or a
The second is the concept of time deltas, a time delta represents an infinitesimally small step of simulation time.
Back to always blocks, the contents of an always block in simulation are executed sequentially. A "blocking" assignment takes effect immediately.
A non-blocking assignment reads it's input immediately, but it's result does not take effect until the end of the current time-delta. So, from the programmers perspective, the results of all non-blocking assignments on a given time-delta take effect at the same time.
This is vitally important, because it allows us to describe systems involving multiple "always" blocks in a deterministic manner. The clock triggers all the always blocks to run, the blocks make their calculations, and only once all the blocks have run and we get to the end of the time delta do the results take effect. We can effectively define the state of the system after the clock edge.
As a general rule blocking assignments in clock-triggered always blocks should not be read from anywhere outside the always block in which they are set. Doing so tends to lead quickly to non-deterministic code.
In always blocks that are triggered by all their input signals it tends to matter less, since those blocks will be re-run until all their inputs settle.
Unless you know precisely what you are doing you should avoid getting fancy with always block sensitivity lists, they may work in simulation but they are likely to not work correctly in synthesis.
Synthesis is a different ball-game from simulation, there are many things you can do in Verilog that will work find in simulation but will either cause errors or misbehavior when synthesizing . Essentially the synthesis tool is looking for patterns, clocked always blocks become logic with flip-flops at the output, assignment statements and combinatorial always blocks just become combinatorial logic. If you throw non-standard stuff at it you are likely to get misbehaviour or synthesis failures.
Having said that there is a lot you can do in synthesis too. As long as you keep it within one always block so the order is defined, the compiler will happilly unroll your loops, inline your functions and tasks, and turn your temporary variables into signals, so that the synthesised logic produces the same result as the simulation.