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

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

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

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

Наши каналы: https://t.iss.one/proglibrary/9197
Download Telegram
Зачем нужна функция runtime.Version() и для чего её используют

runtime.Version() возвращает версию Go, которой скомпилирована программа.

Используется для:

• Диагностики — когда нужно понять, какой версией собран бинарник в продакшене

• Логирования — записываем версию Go при старте приложения для отладки

• Health-check эндпоинтов — отдаём информацию о версии в /health или /version

• Условной логики — редко, но иногда нужно обойти баги конкретных версий компилятора

• Валидации окружения — проверяем, что приложение собрано требуемой версией Go

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

🐸 Библиотека Go для собеса
Please open Telegram to view this post
VIEW IN TELEGRAM
👾1
🔎 Собес сам себя не пройдет

Ты готов к собеседованию? А если проверю?

Залетай к нам и забирай курсы со скидкой 40%. Только до конца октября можно узнать много нового и отточить навыки.

🎯 Забирай курсы:

🐍 python для разработчиков;
🧮 алгоритмы и структуры данных;
📝 архитектуры и шаблоны проектирования;
🧩 основы IT для новичков.

Не упусти скидку и получи долгожданный оффер!
Какая разница между var, := и new() при объявлении переменных

var используется, когда нужно объявить переменную с явным типом или без начального значения:
var count int           // инициализируется нулевым значением (0)
var name string // инициализируется "" (пустая строка)
var isActive bool // инициализируется false
var users []User // инициализируется nil

var total = 100 // тип выводится автоматически
var message string = "Hello" // явное указание типа


Оператор := — это синтаксический сахар для объявления и инициализации переменных внутри функций:
func processOrder() {
status := "pending" // эквивалентно var status string = "pending"
count := 42 // эквивалентно var count int = 42
user := getUser() // тип выводится из возвращаемого значения
}


new() выделяет память, инициализирует её нулевым значением и возвращает указатель:
ptr := new(int)         // *int, значение 0
fmt.Println(*ptr) // 0

user := new(User) // *User, все поля в нулевых значениях


На практике new() используется редко, потому что короткое объявление с & делает то же самое, но понятнее:
// Эквивалентные записи:
ptr1 := new(int)
ptr2 := &int{} // более идиоматично

user1 := new(User)
user2 := &User{} // более наглядно


🐸 Библиотека Go для собеса
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Какой объект требуется для создания sync.Cond

Для создания sync.Cond в Go требуется любой объект, реализующий интерфейс sync.Locker, например sync.Mutex или sync.RWMutex.

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

🐸 Библиотека Go для собеса
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
🎲 Знаешь, что хуже всего на собесе?

Когда задают простой вопрос, а ты не можешь ответить.

🤔 Это ощущение, когда понимаешь:
«Блин, я это знаю... вроде... сейчас...»


От «я знаю...» до «сейчас объясню!» всего один курс.

Алгоритмы и структуры данных — от Big O до задач криптографии.

Python для разработчиков — пиши чистый и эффективный код.

Архитектуры и шаблоны — строй системы, которые масштабируются.

Основы IT — всё необходимое для входа в профессию.

Выбирай любой и забирай со скидкой 40% только до конца октября.

🔗 Выбрать курс
Что такое неэкспортируемая пустая структура

Это структура, определённая как struct{}, без полей и с именем, начинающимся со строчной буквы, чтобы ограничить область видимости внутри пакета.

Зачем она нужна

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

• Так как struct{} занимает 0 байт, её используют в ситуациях, где нужно просто присутствие элемента без данных:
set := map[string]struct{}{}
set["apple"] = struct{}{}


• Пустая структура идеальна для каналов, передающих только сигнал, а не данные:
done := make(chan struct{})
go func() {
// работа
done <- struct{}{}
}()
<-done


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

🐸 Библиотека Go для собеса
Please open Telegram to view this post
VIEW IN TELEGRAM
6👾1
Какие способы есть в Go для округления чисел

Стандартная библиотекаmath.Round(), math.Floor(), math.Ceil() и math.Trunc()
math.Round(2.5)  // 3
math.Round(2.4) // 2
math.Round(-2.5) // -3
math.Floor(2.7) // 2 — всегда вниз
math.Ceil(2.1) // 3 — всегда вверх
math.Trunc(2.9) // 2
math.Trunc(-2.9) // -2


Важный нюанс: эти функции возвращают float64. Если нужно целое число, приводим к int:
result := int(math.Round(2.5)) // 3


Округление до N знаков после запятой вручную:
func roundToDecimal(num float64, precision int) float64 {
shift := math.Pow(10, float64(precision))
return math.Round(num * shift) / shift
}

roundToDecimal(3.14159, 2) // 3.14


Но здесь есть подвох с float64 — погрешность может накапливаться. Для финансов это не подходит.

Decimal библиотеки:
import "github.com/shopspring/decimal"

num := decimal.NewFromFloat(3.14159)

num.Round(2) // 3.14
num.RoundUp(2) // 3.15 — всегда вверх
num.RoundDown(2) // 3.14 — всегда вниз
num.RoundBank(2) // банковское округление


math/big для высокой точности:
num := new(big.Float).SetFloat64(3.14159)
rounded := new(big.Float)

// Устанавливаем точность и режим округления
rounded.SetPrec(53) // точность в битах
num.SetMode(big.ToNearestEven) // режим округления


Для финансов всегда decimal с явным режимом округления. Для остального — math вполне достаточен.

🐸 Библиотека Go для собеса
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5👾1
Что такое жадный алгоритм

Жадный алгоритм — это когда мы принимаем решение, которое кажется лучшим прямо сейчас, не думая о последствиях в будущем. Никогда не возвращаемся назад и не пересматриваем выбор.

Пример. Задача о размене монет:
// Выдать сдачу 63 рубля монетами: 50, 10, 5, 2, 1
// Жадный подход: берем максимальную монету
func giveChange(amount int) []int {
coins := []int{50, 10, 5, 2, 1}
result := []int{}

for _, coin := range coins {
for amount >= coin {
result = append(result, coin)
amount -= coin
}
}
return result // [50, 10, 2, 1] - работает!
}


🐸 Библиотека Go для собеса
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
🤔 Как ускорить браузер

Закрой все вкладки со словами «MacBook», «купить ноутбук», «ноут в рассрочку». Потому что у нас есть решение лучше.

🔥 Proglib разыгрывает MacBook Pro 14. Формула простая: покупаешь любой курс до 15 ноября → учишься 2 недели → пишешь куратору #розыгрыш

Пока у тебя открыто 147 вкладок с ценами, кто-то уже прокачивает скилы и может забрать приз.

👉🏻 Выбрать курс для участия
🥱5
Как переобъявить переменные

В 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
В чем отличие полей-структур и полей интерфейсов

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Можно использовать тип данных 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
1