- What is a thread and who is responsible for it?
A thread is a part of a process that can be assigned by a specific core or CPU. It carries information about the state of the application, like a process does, and is managed by the operating system scheduler. - How do goroutines differ from threads?
Goroutines are tiny in size compared to threads, with a 1 to 100 ratio, and they are not managed by the operating system. The Go runtime takes care of the scheduling of goroutines. - When are arguments evaluated when launching a goroutine?
All the arguments passed to the function that starts the goroutine are evaluated when the goroutine is created. This means that if the value of the argument changes before the goroutine actually gets picked up by the scheduler and starts, the change is not going to be reflected in the goroutine. - How do buffered and non-buffered channels differ?
A non-buffered channel is created by the make function if no capacity is specified, or if it's 0. Each send operation to such a channel will block the current goroutine, until a receive operation is performed by another goroutine. A buffered channel can support a number of non-blocking send operations equal to its capacity. This means that if a channel has a capacity of n, the first n-1 send operations that are not matched by any receive operation will not be blocking. - Why are one-way channels useful?
They allow just a subset of operations, making clear to the user what the scope of the channel is. A receive-only channel does not allow data to be sent, or to close it, and that makes perfect sense because it is not the responsibility of the receiver. A send-only channel does not allow the receipt of data, but allows it to be sent and to close the channel, with an implicit statement that it is up to the sender to close the channel to signal that there is no more data.
- What happens when operations are executed on nil or closed channels?
Sending to, or receiving from, a nil channel blocks forever, and closing it creates panics. Receiving from a closed channel returns a zero value immediately, and false, while sending to a closed channel raises a panic and the same thing happens if we try to close it again. - What are timers and tickers used for?
Timers and tickers both create a receive-only channel. Timers can be used in a loop with a select statement, instead of using default, in order to reduce the frequency of the selection and lower the CPU usage of the application when it is idle. Tickers are very useful for executing an operation every fixed period of time, while one practical usage is a rate limiter, which limits the number of executions over a set period of time in a certain segment of an application.