Cores, threads and goroutines are all decoupled from each other.
Go will try to run at least one thread per core by default. You will probably end up having more threads than cores: for example if you read a file, there will be a thread blocked reading the file. This thread will not keep a core busy: your Operating System will “park it” and free up one core for something else.
What threads are run on which core is the task of the Operating System: Go operates to run as many goroutines as possible on top of the available threads, instead of creating new ones which is a (relatively) expensive operation.
Generally you don’t care about cores, nor threads.
You do when your code performs CPU intensive operations (when it doesn’t do I/O or anything else with the external world): in this case you can change the “task affinity” of your Go process (in Linux, taskset) to fix your threads on one CPU. Probably you will also want to decrease the niceness of your process. Both these things might speed up your program, at the expense of making other programs running at the same time slower.