> Как контролировать уникальные указатели и умножать их ровно один раз в функции double в Go (Go)
Уровень: senior · Роль: backend · Категория: Технические вопросы
Компании: Т-Банк
Стек: Go
> Пример ответа
Короткий ответ
В Go нет умных указателей и оператора умножения для них - управление памятью осуществляется сборщиком мусора. Вопрос, вероятно, касается паттерна "double-checked locking" или идемпотентной инициализации через sync.Once. Для гарантии однократного выполнения используйте sync.Once или sync.Mutex с флагом. Умножение указателей в Go не имеет смысла - указатели можно только разыменовывать или сравнивать.
Подробное объяснение
В Go отсутствуют умные указатели вроде std::unique_ptr из C++. Управление памятью автоматическое, а указатели - это просто ссылки на объекты в куче или стеке. Операция "умножения" указателя не определена языком.
Если речь о паттерне "double-checked locking" для ленивой инициализации, то в Go его корректная реализация требует sync.Once или atomic + sync.Mutex. sync.Once гарантирует, что функция выполнится ровно один раз даже при конкурентном доступе.
Пример типичной задачи: есть функция double, которая должна инициализировать ресурс ровно один раз, а затем использовать его. Без синхронизации возможна гонка данных.
На практике
Для однократной инициализации используйте sync.Once - это идиоматичный способ. Если нужен более тонкий контроль (например, сброс состояния), применяйте sync.Mutex с булевым флагом.
Для "умножения" значения по указателю - просто разыменуйте и умножьте: *ptr *= 2. Это безопасно, если указатель не nil и нет конкурентного доступа.
Пример кода
GOpackage mainimport ("fmt""sync")type Resource struct {value int}var (once sync.Onceresource *Resource)func getResource() *Resource {once.Do(func() {resource = &Resource{value: 42}})return resource}func double(ptr *int) {if ptr == nil {return}*ptr *= 2}func main() {r := getResource()double(&r.value)fmt.Println(r.value) // 84}
Как отвечать на собеседовании
Уточните, что именно имеется в виду: умные указатели из C++ или паттерн инициализации. Покажите понимание sync.Once и гонок данных. Объясните, почему в Go нет необходимости в умных указателях - GC решает проблему владения. Если спрашивают про double-checked locking, расскажите про sync.Once как более простую альтернативу.
Что проверяет интервьюер
- Понимание модели памяти Go и отличий от C++.
- Знание примитивов синхронизации (
sync.Once,sync.Mutex,atomic). - Умение проектировать потокобезопасный код.
- Внимание к деталям: nil-указатели, гонки данных.
Типичные ошибки
- Попытка реализовать double-checked locking без
atomic- это небезопасно. - Использование
sync.Onceдля операций, которые могут завершиться ошибкой и требуют повторной попытки. - Забывание проверки на nil перед разыменованием.
- Предположение, что в Go есть умные указатели - это сразу показывает непонимание языка.
> Похожие задачи по backend
Задумываетесь ли вы об оптимизации приложений
Есть ли у вас сильно нагруженные части системы
В какой версии Go был исправлен баг с указателями в цикле
Как архитектурно передавать на фронт сложную структуру с вложенными полями и массивами
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью