Что такое синхронность
Что проверяют
Различаете ли вы два соседних смысла слова: синхронность как «вызов ждёт результата» и синхронизацию как согласование доступа к общим данным. В Go оба живут в одном коде, и интервьюер смотрит, не смешиваете ли вы их в одну кашу.
Как отвечать
Начните с определения: синхронная операция возвращает управление после завершения работы, асинхронная сразу, а результат приходит позже.
Затем переведите это на устройство Go. Канал без буфера синхронен в строгом смысле: отправка не завершится, пока другая горутина не начнёт приём, обе стороны встречаются в одной точке.
ch := make(chan int) // без буфера: встреча отправителя и получателя
go func() { ch <- compute() }()
v := <-ch // ждём результатКанал с буфером связь ослабляет: отправитель уходит дальше, пока есть место, и вместе с ожиданием исчезает гарантия, что получатель уже видел значение.
Третий пласт это синхронизация доступа: sync.Mutex, sync.RWMutex, sync.Once, sync/atomic. Они не про очерёдность вызовов, а про то, чтобы две горутины не портили одну структуру и чтобы запись одной была видна другой.
Хорошо добавить уровень системы: синхронное межсервисное взаимодействие это запрос с ожиданием ответа, асинхронное это очередь, где отправитель не ждёт обработки.
Где спотыкаются
Говорят, что горутины и каналы «избавляют от блокировок». Наоборот: приём из пустого канала и отправка в полный блокируют горутину, и это штатный механизм языка. Опасна не блокировка, а её отсутствие там, где она нужна.
Путают синхронность с потокобезопасностью. Последовательный по записи код в нескольких горутинах даёт гонку, и проверяют это детектором гонок, а не рассуждениями о порядке строк.
Закрывают канал со стороны получателя или закрывают дважды. Правило простое: закрывает отправитель и только он, иначе паника в рантайме.