Goroutines are concurrent and, to an extent, parallel; however, we should think of them as being concurrent. The order of execution of goroutines is not predictable and we should not rely on them to be executed in any particular order.
We should also take care to handle errors and panics in our goroutines because even though they are being executed in parallel, a panic in one goroutine will crash the complete program. Finally, goroutines can block on system calls, however this will not block the execution of the program nor slow down the performance of the overall program.
We looked at a few of the design concepts behind Go's runtime scheduler to understand why all of this happens.
You might be wondering why we haven't discussed channels in this chapter. The reason is that by not relying on channels we were able to look at goroutines in their most elemental form...