Библиотека Go для собеса | вопросы с собеседований
6.86K subscribers
248 photos
9 videos
1 file
537 links
Вопросы с собеседований по Go и ответы на них.

По рекламе: @proglib_adv

Учиться у нас: https://proglib.io/w/0b524a15

Для обратной связи: @proglibrary_feeedback_bot

Наши каналы: https://t.me/proglibrary/9197
Download Telegram
Как переобъявить переменные

В Go нельзя полностью переобъявить переменную с тем же именем в одной области видимости — это вызовет ошибку компиляции.

Внутри функции можно использовать оператор :=, если одновременно присутствует новая переменная. Пример:
a := 1       // a объявлена
a, b := 2, 3 // a присваивается новое значение, а b объявляется


Можно объявить переменную с одинаковым именем в разных областях видимости:
var a = 1
func test() {
var a = 2 // это другая переменная, локальная для функции
}


🐸 Библиотека Go для собеса
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
Как вам вопросы прошедшей недели

Оцените их по шкале 🔥,❤️,👍,😢, 🥱,
где 🔥 — это супер, а 🥱 — это скучно.

Также приветствуется фидбек в комментах.

🐸 Библиотека Go для собеса
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥94👍2🥱1
Как работает atomic.Value

atomic.Value используется для безопасного хранения и чтения значения из разных горутин без использования явных блокировок.

Для записи используется метод Store, для чтения — Load. Хранящееся значение должно быть одного типа на протяжении всего времени жизни экземпляра atomic.Value, иначе при попытке сохранить значение другого типа возникнет паника.

atomic.Value синхронизирует само значение, но не вложенные поля, если сохраняется, например, структура с внутренними pointer-полями.

🐸 Библиотека Go для собеса
Please open Telegram to view this post
VIEW IN TELEGRAM
1
⚡️ Механизм запущен, часики тикают

Прямо сейчас кто-то уже купил курс со скидкой 40%, открыл первый урок и уже на пути к MacBook Pro 14.

А ты всё ещё читаешь этот пост...

Дедлайны не ждут:

31 октября — скидка 40% сгорает
15 ноября — розыгрыш MacBook

🎯 Правила участия:

→ купить любой курс до 31 октября
→ отучиться 2 недели
→ написать #розыгрыш куратору

🕊️ Не упусти свой шанс
Что происходит с горутиной, если контекст, переданный в неё, отменён с помощью cancel

Если контекст, переданный горутине, отменён с помощью функции cancel(), в горутине должен быть предусмотрен код, который регулярно проверяет состояние контекста, обычно через <-ctx.Done().

Когда горутина обнаружит, что контекст отменён, она должна корректно завершить работу — остановить выполняющиеся операции, освободить ресурсы и выйти.

Сам по себе вызов cancel() не останавливает горутину. Он лишь посылает сигнал отмены, который надо обрабатывать в коде.

🐸 Библиотека Go для собеса
Please open Telegram to view this post
VIEW IN TELEGRAM
6
Go как ядро сложной dev-платформы? Да, и это SourceCraft! 🤯

Интересный факт для Go-комьюнити: ядром git-сервера SourceCraft стал переработанный Go-движок go-git. Команда Яндекса перенесла слой хранения в облако (Object Storage + PostgreSQL), добившись масштабируемости. И почти вся остальная бэкенд-обвязка платформы тоже написана на Go!

Получился редкий пример, где Go — не просто один из языков, а основа сложной инфраструктуры. Разработчики платформы говорят, что это даёт масштабирование без потери быстродействия. Можно залить крупный проект и проверить, как он грузится. 🤔
👍31🔥1👾1
В чем отличие полей-структур и полей интерфейсов

Поля-структуры содержат конкретную реализацию данных и методов. Когда вы встраиваете структуру в другую структуру (embedding), вы получаете доступ к её полям и методам напрямую, и эти методы уже реализованы.

Поля-интерфейсы описывают набор методов без реализации. Они задают контракт, который должен быть реализован конкретным типом. Поле-интерфейс может содержать значение любого типа, который удовлетворяет этому интерфейсу.

Типы в полях-структурах фиксированы и однозначны, в то время как поле-интерфейс может содержать значения разных конкретных типов в разное время.

🐸 Библиотека Go для собеса
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1👾1
Halloween Special — последний день магии! 👻

Успевай сегодня купить курсы со скидкой 40%!

А также участвуй в розыгрыше MacBook Pro 14 💻

После полуночи останется только тыква 🎃

🔮 Открой портал и выбери курс
🌚1
⚙️ В микросервисах всё рушится не тогда, когда ломается код, а когда ломается конфигурация. Один неверный параметр — и вместо отказоустойчивости получаете каскадный сбой.

На открытом уроке вы узнаете, как централизованное управление настройками помогает системе оставаться живой, даже когда всё вокруг падает.

Разберём etcd, Zookeeper, Consul, а также практику автоматического обновления конфигураций без остановки сервисов.

❗️ Мы покажем, как микросервисы на Go могут адаптироваться к сбоям и изменениям в реальном времени, и какие паттерны делают архитектуру по-настоящему устойчивой.

📆 5 ноября в 20:00 МСК. Открытый вебинар проходит в преддверии старта курса «Микросервисы на Go».

➡️ Регистрируйтесь и разберитесь, как не дать своим сервисам “упасть” из-за одной строки в конфиге: https://clc.to/hFI13w

Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, www.otus.ru
👾1
Опишите, как можно эффективно хранить и обрабатывать список пользователей, зарегистрировавшихся на хэллоуинскую вечеринку, чтобы избежать дублирования

Можно использовать тип данных map с ключами, например, по уникальному идентификатору пользователя: email, username или ID.

При конкурентных обращениях использовать sync.Map или мьютексы для защиты мапы.

Если нужно сохранять пользователей в базе данных — использовать уникальные индексы на уровне БД.

При необходимости фильтрации или поиска по другим полям — можно создавать дополнительные мапы или индексы.

🐸 Библиотека Go для собеса
Please open Telegram to view this post
VIEW IN TELEGRAM
👍32🌚2
Как происходит передача значений в функции, вызовы которых отложены с помощью defer

В Go аргументы функции, вызванной с помощью defer, вычисляются сразу в момент объявления defer, а не во время выполнения самой отложенной функции. Это значит, что значения, переданные в defer, фиксируются на момент объявления, даже если переменные потом изменятся.

Сам вызов функции с defer будет выполнен уже после завершения текущего блока кода или функции, но с теми значениями аргументов, которые были на момент вызова defer.

Пример:
package main

import "fmt"

func main() {
x := 10
defer fmt.Println("До:", x) // x вычисляется сейчас, но вывод откладывается
x = 20
fmt.Println("После:", x)
}


Выведется 20 и 10, потому что значение x для defer зафиксировалось при объявлении defer, а не к моменту выполнения отложенной функции.

🐸 Библиотека Go для собеса
Please open Telegram to view this post
VIEW IN TELEGRAM
2
У вас есть массив чисел, в котором все числа встречаются по два раза, кроме одного — уникального, которое встречается один раз. Как вы бы решили эту задачу используя операцию XOR

Суть метода в свойствах XOR:

• Любое число XOR с самим собой дает 0:
a⊕a = 0
a⊕a = 0
.

• Любое число XOR с нулем дает само число:
a⊕0 = a
a⊕0 = a
.

• Операция XOR коммутативна и ассоциативна, то есть порядок операндов не важен.

Поэтому если последовательно применить XOR ко всем элементам массива, пары одинаковых чисел взаимно отменяются и останется только уникальное число.

🐸 Библиотека Go для собеса
Please open Telegram to view this post
VIEW IN TELEGRAM
👍42
В чем практические и внутренние различия между буферизованными и небуферизованными каналами

Небуферизованный канал — строгий. Отправка и прием завершаются одновременно и образуют отношение happens-before между записью и чтением значения.

Буферизованный канал хранит элементы в кольцевом буфере внутри структуры до выборки получателем. Отправитель блокируется лишь при полном буфере.

При небуферизованном обмене с ожидающим получателем значение копируется напрямую из стека отправителя в стек получателя, минуя промежуточный буфер. При буферизованном — сначала в буфер канала, затем из буфера в стек получателя.

🐸 Библиотека Go для собеса
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥42
Зачем нужен канал с размером 1

Канал с размером буфера 1 — это своего рода «промежуточный» вариант между небуферизованным и традиционно буферизованным каналом. Он позволяет одному элементу находиться в канале без блокировки отправителя, то есть:

Если буфер пуст, то отправитель записывает значение в буфер и сразу продолжает работу, не блокируясь. Это даёт асинхронность, в отличие от небуферизованного канала, где send блокирует до приёма значения.

Если буфер заполнен этим одним элементом, дальнейшая отправка заблокируется до тех пор, пока получатель не прочитает элемент из канала, тем самым освободив буфер.

Получатель, если буфер пуст, будет блокироваться, ожидая новый элемент, как и в любом буферизованном канале.

Это часто используется для случаев, когда нужен небольшой буфер для минимизации блокировок, но при этом важна почти синхронная коммуникация без накопления большого количества элементов и связанных с этим задержек.

🐸 Библиотека Go для собеса
Please open Telegram to view this post
VIEW IN TELEGRAM
👍41