fa
Feedback
Библиотека Go для собеса | вопросы с собеседований

Библиотека Go для собеса | вопросы с собеседований

رفتن به کانال در Telegram

Вопросы с собеседований по Go и ответы на них. Учиться у нас: clc.to/iEeaZw По рекламе: @proglib_adv Для обратной связи: @proglibrary_feeedback_bot Наши каналы: https://t.me/proglibrary/9197

نمایش بیشتر
7 472
مشترکین
-124 ساعت
-47 روز
-2230 روز
آرشیو پست ها
Как извлечь подстроку из строки Строка в Go это неизменяемый срез байт. Поэтому подстрока берётся так же, как срез, но с одной оговоркой. Индексы считаются в байтах, а не в символах. На ASCII разницы не видно, на кириллице или эмодзи всё ломается. Срез по байтам
s := "hello world"
fmt.Println(s[0:5]) // hello
fmt.Println(s[6:])  // world
Такой срез не копирует данные, он ссылается на тот же массив байт. Работает за O(1). Теперь то же самое с кириллицей:
s := "привет"
fmt.Println(s[0:3]) // "пр"? нет, это "п" с хвостом
Каждая кириллическая буква в UTF-8 занимает два байта, так что s[0:3] разрежет символ пополам и вы получите битые данные. Срез по символам Если нужны именно символы, переводим строку в срез рун:
r := []rune("привет")
fmt.Println(string(r[0:3])) // при
Здесь уже есть аллокация и проход по всей строке, то есть O(n). Для длинных строк в горячем цикле это заметно. 🐸 Библиотека Go для собеса

Как узнать, сколько элементов лежит в канале Функция len(ch) возвращает количество элементов, которые сейчас лежат в буфере канала. Функция cap(ch) возвращает вместимость буфера, то есть сколько элементов канал может хранить, не блокируя отправителя. Пример с буферизированным каналом:
ch := make(chan int, 5)
ch <- 1
ch <- 2

fmt.Println(len(ch)) // 2
fmt.Println(cap(ch)) // 5
Для небуферизированного канала обе функции всегда дают ноль, потому что у него нет буфера, где данные могли бы задержаться.
ch := make(chan int)

fmt.Println(len(ch)) // 0
fmt.Println(cap(ch)) // 0
Значение len(ch) это снимок состояния на конкретный момент. Пока вы читаете результат и что-то с ним делаете, другая горутина уже могла записать или забрать элемент. 🐸 Библиотека Go для собеса

🔥 Как перестать слепо доверять ИИ и начать им управлять? 1–2 августа на «ИИ-выходных» вы научитесь проектировать архитектуру
🔥 Как перестать слепо доверять ИИ и начать им управлять? 1–2 августа на «ИИ-выходных» вы научитесь проектировать архитектуру автономных AI-агентов и контролировать их работу. Что будет в вашем портфолио после обучения: — Вы выйдете с готовым профилем AI-инженера (отлично дополнит ваши LinkedIn и GitHub). — Освоите связку Python, FastAPI, OpenAI API, Docker и PostgreSQL. — Соберете полноценный AI-сервис под вашу личную задачу. Для кого: junior-middle разработчики. Вы пишете на Python, работаете с Git и терминалом (с нуля не подойдет, темп очень быстрый!). 👨‍💻 Спикер: Алексей Жиряков (Сбер, GenAI). Места строго ограничены! 👉 Изучить программу и занять место

Как узнать, что канал закрыт Обычное v := <-ch из закрытого канала не заблокируется и не паникует, а сразу вернёт нулевое значение типа. Поэтому по одному v нельзя отличить «пришёл реальный ноль» от «канал закрыт и пуст — ровно как с мапой:
v := <-ch // 0 — но это может быть и настоящее значение, и признак закрытия
Второй параметр решает вопрос: флаг ok равен true, пока из канала можно прочитать отправленное значение, и становится false, когда канал закрыт и в нём не осталось буферизованных данных. Важно, что закрытый канал сначала отдаёт всё, что в него успели записать, и только потом начинает возвращать false:
v, ok := <-ch
if !ok {
    // канал закрыт и пуст
}
На практике за приёмом из канала обычно стоит range, который сам корректно завершается при закрытии — отдельная проверка ok не нужна:
for v := range ch {
    // выполняется, пока канал не закрыт и не пустой
}

Как отличить отсутствующий ключ от нулевого значения в мапе Через второй возвращаемый параметр при обращении к мапе — так называемый comma-ok. Обычное чтение v := m[key] всегда вернёт значение: если ключа нет, это будет нулевое значение типа (0 для чисел, "" для строк, nil для указателей). А значит, по одному только v нельзя понять, лежал ли там реальный ноль или ключа просто не было:
m := map[string]int{"a": 0}

v := m["a"] // 0 — но ключ есть
v = m["b"]  // 0 — а ключа нет
Форма с двумя переменными решает это: второе значение — булев флаг, который равен true, только если ключ действительно присутствует в мапе. Именно на него и нужно смотреть, а не на само значение:
v, ok := m["a"]
if ok {
    // ключ есть, v — реальное значение (даже если это 0)
}

_, ok = m["b"] // ok == false, ключа нет
Отсюда типичный идиоматичный паттерн — проверка и использование в одном if:
if v, ok := m[key]; ok {
    // работаем с v
}
🐸 Библиотека Go для собеса

📹 Из чего на самом деле состоит ИИ-агент? Прикрепили для вас свежую вырезку из вебинара. Внутри, что прячется под капотом агентных систем: от LLM-ядра до вызова внешних инструментов. Обсуждаем, какими бывают агенты (спойлер: далеко не только автономными) и когда какой подход использовать. Готовы перейти от видео к практике и собрать свой первый продакшн-кейс? Прямо сейчас у нас действует акция «3 курса по цене 1»:
🔹 При покупке VIP-тарифа нового потока «Разработка ИИ-агентов» вы получаете в подарок хардкорный курс «AgentOps» + ещё один любой курс Академии на ваш выбор! 🔹 Ваша чистая экономия — 129 000 ₽! Два топовых курса по созданию и контролю агентов обойдутся вам всего в 134 000 ₽ вместо 263 000 ₽. Плюс третий курс бонусом (например, «Математика для AI»).
Сомневаетесь, подойдет ли вам формат? Оставьте заявку и пройдите бесплатный демо-урок, чтобы протестировать платформу перед покупкой. 👉 Пройти демо-урок и забрать 3 курса по цене 1

Освободится ли память после bigSlice = bigSlice[:5] Нет, не обязательно. Операция [:5] создаёт новый слайс-заголовок с длиной 5, но он по-прежнему указывает на тот же самый underlying array. Пока хотя бы один слайс ссылается на этот массив, сборщик мусора не может его освободить. То есть даже если нам нужны первые 5 байт, за спиной может «висеть» все 10 MB: Дело в том, что срез — это лишь тройка из указателя на массив, длины и ёмкости. Урезание длины меняет только заголовок и никак не влияет на память под ним. Capacity нового слайса по-прежнему указывает на конец исходного массива, поэтому GC считает его достижимым. Чтобы отдать большой массив сборщику, нужные данные копируют в новый, компактный слайс, а ссылку на исходный обнуляют:
smallCopy := make([]byte, len(smallSlice))
copy(smallCopy, smallSlice)
bigSlice = nil
Тот же эффект короче — через append в nil-слайс, который выделит свежий массив под реальный объём данных:
smallCopy := append([]byte(nil), smallSlice...)
🐸 Библиотека Go для собеса

💰 Почему одним Data Scientist платят больше, чем другим? Дело не только в знании Python и ML-библиотек. Во многих компаниях
💰 Почему одним Data Scientist платят больше, чем другим? Дело не только в знании Python и ML-библиотек. Во многих компаниях уровень специалиста оценивают по математической подготовке: теории вероятностей, статистике, линейной алгебре и математическому анализу. Именно эти знания помогают понимать модели, решать более сложные задачи и претендовать на позиции с более высокой оплатой. На курсе «Математика для Data Science» вы изучите разделы, которые используются в работе Data Scientist и ML Engineer. Что вас ждёт: 🔹 40+ видеолекций и 150+ практических заданий на Python 🔹 Проверка домашних работ и обратная связь от преподавателей 🔹 Подготовка к техническим собеседованиям 🔹 Программа от преподавателей ВМК МГУ, НИУ ВШЭ и экспертов индустрии 👉 Записаться на бесплатный демо-урок

Нужно ли создавать новый http.Client на каждый запрос Нет. Client и его Transport безопасны для конкурентного использования и держат пул TCP соединений. Новый клиент на каждый запрос убивает keep alive, каждый вызов будет заново устанавливать соединение вместе с TLS рукопожатием. Правильно создать один клиент на приложение и задать ему тайм аут, потому что у http.DefaultClient его нет. 🐸 Библиотека Go для собеса

Что означает гарантия «фиксеры не должны менять поведение вашей программы» Это про автоматические исправления кода — фиксеры (например, go fix, gofmt, suggested fixes из go vet / analysis-фреймворка, или --fix в линтерах вроде golangci-lint). Гарантия говорит, что такой фикс меняет только форму кода, но не его поведение во время выполнения. Под поведением тут понимается наблюдаемая семантика: что программа возвращает, какие у неё сайд-эффекты — запись в файл, вызовы по сети, вывод, — как идёт control flow, какие ошибки и паники она порождает. То есть на тех же входных данных до и после фикса программа должна давать тот же результат и те же эффекты. Трансформация behavior-preserving, семантически нейтральная. Пример: фиксер может переписать устаревший API на новый, переставить импорты через goimports, отформатировать код — но не должен, скажем, изменить условие в if так, что поменяется ветвление. И тут ключевой момент — формулировка «should not», а не «will not». Это заявленное свойство по дизайну, а не строгая гарантия на все случаи. В Go, где есть интерфейсы, рефлексия, горутины и гонки, всегда найдётся пограничный кейс, где формально эквивалентная замена всё же меняет смысл. Поэтому на практике фиксы обычно делят на safe и unsafe: safe можно катить массово, unsafe применяют осознанно. 🐸 Библиотека Go для собеса

Почему http.ListenAndServe(":8080", nil) считается плохой практикой nil означает DefaultServeMux, глобальный роутер. В него может зарегистрировать хендлер любой импортированный пакет, например net/http/pprof делает это в init. Так наружу случайно утекают отладочные ручки. У такого сервера нет тайм аутов. Правильнее создать свой Server и свой ServeMux. Правильный вариант:
srv := &http.Server{
  Addr:              ":8080",
  Handler:           mux,
  ReadHeaderTimeout: 5 * time.Second,
  ReadTimeout:       10 * time.Second,
  WriteTimeout:      10 * time.Second,
  IdleTimeout:       120 * time.Second,
}
log.Fatal(srv.ListenAndServe())
🐸 Библиотека Go для собеса

🎬 Как ИИ ускоряет разработку и где ломаются архитектуры Мы провели открытый вебинар, где разобрали реальные боли проектирова
🎬 Как ИИ ускоряет разработку и где ломаются архитектуры Мы провели открытый вебинар, где разобрали реальные боли проектирования автономных систем. Ольга Лукьянова на практическом кейсе показала, как использовать ИИ-ассистентов для реальных задач. Вы просили запись встречи — она уже в открытом доступе! Что внутри: — Как с помощью ИИ быстрее разбираться в незнакомом коде и готовить пулл-реквесты; — Критерии выбора между одним агентом и мультиагентной системой; — Разбор популярных архитектурных ошибок и ограничений современных ИИ; — Практические рекомендации по проектированию и внедрению облачных агентов. 👉 Посмотреть полную запись можно тут:VKYouTube 🚀 Хотите пойти дальше открытого вебинара? Если вы готовы перейти от простых промптов к проектированию надежных, отказоустойчивых ИИ-систем, которые не сливают бюджет компании на API, приходите на курс AgentOps. Поток уже стартовал, но двери еще приоткрыты! 👉 Успеть на курс AgentOps

Как работает iota в блоке констант iota начинает с нуля в начале блока const и увеличивается на единицу для каждой новой строки. После присвоения значения переменной, можно не указывать iota снова для следующих переменных, и Go самостоятельно применит инкремент.
const (
    A = iota
    B
    C
    D
)
// A = 0, B = 1, C = 2, D = 3
Важно помнить, что iota применяется только внутри блока const. Если создать второй блок const, то счетчик снова начинает с нуля. Каждый блок независим. 🐸 Библиотека Go для собеса

🎮 Планы на выходные: соберите ИИ-агента в нашей новой игре! Запустили интерактивную аркаду, где вы на практике поймете, как
🎮 Планы на выходные: соберите ИИ-агента в нашей новой игре! Запустили интерактивную аркаду, где вы на практике поймете, как устроены агентные системы.
Юзеры бомбят в чате, тикеты горят, вам нужно спасать прод 🤓. Выстраивайте граф агента, подключайте узлы (RAG, CRM, Guardrails) и принимайте решения на развилках, чтобы бот не сливал данные.
Какие навыки проверите: - Архитектура: сборка графов на LangGraph; - Компоненты: интеграция LLM, RAG и памяти; - Безопасность: настройка Guardrails и отладка ошибок; - Стейт: логика на сложных развилках. Бонус: Больше баллов — выше скидка на обучение! Наш новый поток стартует 14 июля. При покупке курса вы забираете еще 2 любых курса Академии в подарок! Протестируйте свою инженерную логику и заберите максимальную скидку на обучение. 👉 Сыграть в аркаду и выбить скидку

Чем Handler отличается от HandlerFunc Handler это интерфейс с одним методом ServeHTTP(ResponseWriter, *Request). HandlerFunc это тип функции, у которого метод ServeHTTP уже реализован и просто вызывает саму функцию. Он нужен как адаптер, чтобы обычную функцию можно было отдать туда, где ждут интерфейс.
mux.Handle("/ping", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  w.Write([]byte("pong"))
}))
🐸 Библиотека Go для собеса

👣 Многие разработчики приходят в Go с багажом паттернов из Java и C#. В результате простой и понятный код постепенно обраста
👣 Многие разработчики приходят в Go с багажом паттернов из Java и C#. В результате простой и понятный код постепенно обрастает слоями абстракций, лишними интерфейсами и десятками DTO, которые усложняют поддержку проекта. 🗓 8 июля в 20:00 МСК приглашаем вас на открытый урок в преддверии старта курса «Go-разработчик. Продвинутый уровень». На занятии разберём, почему привычные подходы из других языков не всегда работают в Go, как выстроить архитектуру через Handler → Service → Repository без циклических зависимостей, где действительно нужны интерфейсы и как избежать избыточных абстракций. ❗️Вы узнаете, какие ошибки чаще всего встречаются на проверках кода, научитесь проектировать приложения с понятным разделением ответственности и поймёте, как писать код, который останется читаемым и через полгода. ➡️ Регистрируйтесь и познакомьтесь с подходом, который помогает писать на Go проще, надёжнее и профессиональнее: https://clc.to/kpNJbw Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, www.otus.ru

ОПРОС: Ответьте на пару вопросов и получите промокод на все наши курсы! 🎁 Команда Prоglib.аcаdemy готовит к запуску новые пр
ОПРОС: Ответьте на пару вопросов и получите промокод на все наши курсы! 🎁 Команда Prоglib.аcаdemy готовит к запуску новые продукты, и нам нужна ваша помощь. Мы хотим создавать обучение, которое будет решать ваши реальные карьерные задачи и бить точно в цель. Поделитесь своим опытом и ожиданиями, чтобы мы сделали наши курсы еще полезнее именно для вас! Заполнение анкеты займет буквально 2–3 минуты, а с нас — скидка на любой наш курс! 👉 Пройти опрос в Яндекс Формах и забрать промокод

Что такое голый return и когда он опасен Это return без перечисления значений при именованных возвратах. В коротких функциях он читается нормально, но в длинных мешает понять, что именно вернётся, потому что значения задаются где то выше по телу. Поэтому голый возврат держат для небольших функций. 🐸 Библиотека Go для собеса

⚠️ Уже завтра стартует курс AgentOps! Мы собрали на потоке сборную из мастеров IT-рынка. Практики из BigTech научат вас контр
⚠️ Уже завтра стартует курс AgentOps! Мы собрали на потоке сборную из мастеров IT-рынка. Практики из BigTech научат вас контролировать и отлаживать ИИ-агентов, чтобы они работали предсказуемо и не сливали бюджет на API. 🔥 Заберите 3 курса по цене 1:
● При покупке VIP-тарифа (осталось 4 места) нового потока «Разработка ИИ-агентов» получаете в подарок курс «AgentOps» + ещё один любой курс Академии (например, «Математика для разработки AI», чтобы глубже освоить направление). ● Три курса обойдутся вам всего в 134.000 ₽ вместо 263.000 ₽. ● Доступна удобная беспроцентная рассрочка, платеж можно разбить на несколько комфортных частей.
Хотите прокачать свое портфолио продакшн-кейсом, но пока сомневаетесь? Пройдите наш бесплатный демо-урок, чтобы протестировать формат перед покупкой. 👉 Забрать 3 курса по цене 1 и получить демо-урок

Какой самый распространённый паттерн множественного возврата Пара значение и ошибка. Функция возвращает результат и error, который вызывающий код обязан проверить. Это основа идиоматичной обработки ошибок в Go.
func divide(a, b int) (int, error) {
    if b == 0 {
        return 0, errors.New("деление на ноль")
    }
    return a / b, nil
}
🐸 Библиотека Go для собеса