Библиотека Go для собеса | вопросы с собеседований
7.42K subscribers
270 photos
10 videos
1 file
827 links
Вопросы с собеседований по Go и ответы на них.

Учиться у нас: clc.to/iEeaZw

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

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

Наши каналы: https://t.me/proglibrary/9197
Download Telegram
🤖 Большинство материалов по ИИ-агентам устаревают быстрее, чем многие курсы успевают обновить программу

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

🚀 30 июня стартует курс «Разработка ИИ-агентов».

До 20 июня действует сниженная цена.

За 8 недель под руководством практиков из бигтеха вы соберёте собственного AI-агента, который работает с API, использует память, подключается к внешним сервисам и решает реальную задачу.

Что разберём:

🔹 архитектуру AI-агентов и надёжный вывод;
🔹 LangGraph и оркестрацию workflow;
🔹 MCP и работу с внешними инструментами;
🔹 RAG-системы;
🔹 AgentOps, observability и evals;
🔹 безопасность и защиту от prompt injection;
🔹 мультиагентные системы и A2A.

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

👉 Узнать программу и забронировать место со скидкой
У вас есть map[int]Record. Несколько горутин читают и пишут в него одновременно. Что произойдёт

Go рантайм с версии 1.6 содержит детектор конкурентных записей в map. При одновременной записи из нескольких горутин программа завершится с паникой concurrent map writes — намеренно, чтобы не допустить повреждения данных.
 
Но детектор срабатывает не всегда: он вероятностный. Поэтому полагаться на него как на защиту нельзя.
 
Правильные решения в зависимости от нагрузки: sync.RWMutex вокруг map, sync.Map для случаев с редкими записями и частыми чтениями, или шардирование — несколько map с отдельными мьютексами.

🐸 Библиотека Go для собеса
Please open Telegram to view this post
VIEW IN TELEGRAM
Разработчик создаёт time.NewTicker внутри цикла и забывает вызвать ticker.Stop(). Что произойдёт

time.NewTicker регистрирует таймер в runtime heap таймеров. Раньше GC не собирал тикеры автоматически — они жили, пока не будет вызван Stop().

Начиная с Go 1.23 ситуация изменилась: garbage collector теперь может собирать неиспользуемые тикеры, если на них больше нет ссылок. То есть забытый Stop() больше не гарантирует утечку памяти.

⚠️ Важно

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

Это по-прежнему может проявляться как постепенный рост потребления памяти и деградация производительности под нагрузкой — просто теперь причина не всегда в самом факте отсутствия Stop(), а в удержании ссылок.

Как это поймать

go tool pprof с профилем goroutines покажет горутины, заблокированные на чтении из каналов тикеров. Heap-профиль может показать рост объектов, связанных с таймерами.

🐸 Библиотека Go для собеса
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥 Чем больше агентов — тем лучше? Не всегда. Уже завтра поговорим о реальных ограничениях на открытом уроке «Мультиагентные системы: почему большинство архитектур переусложнены».

Спикер — Дмитрий Юдин, руководитель AI/ML-направления в Сloud․ru.

После урока вы:

🔹 будете лучше ориентироваться в выборе между одним агентом и мультиагентной системой;
🔹 поймёте, какие архитектурные ошибки встречаются чаще всего;
🔹 получите практические ориентиры для проектирования и внедрения агентных систем;
🔹 будете лучше понимать возможности и ограничения современных ИИ-агентов.

🗓️ 18 июня, 19:00 (МСК)
⏱️ 90 минут

👉 Зарегистрироваться и получить промокод на 10 000 ₽
Чем io.EOF отличается от io.ErrUnexpectedEOF? В каком случае Read должен возвращать EOF, а в каком — ErrUnexpectedEOF

io.EOF — сигнал о штатном конце данных. Read возвращает его когда источник исчерпан и больше нечего читать. Это не ошибка в смысле «что-то пошло не так» — это нормальное завершение потока.

По спецификации io.Reader, EOF может прийти либо вместе с последними байтами (n > 0, err == io.EOF), либо отдельным вызовом (n == 0, err == io.EOF). Оба варианта корректны — поэтому правильный код всегда сначала обрабатывает прочитанные байты, потом проверяет ошибку.

io.ErrUnexpectedEOF — сигнал о том, что поток закончился в неожиданном месте. Источник данных иссяк раньше, чем ожидалось по протоколу или по запросу.

Типичный пример — io.ReadFull. Функция просит ровно len(buf) байт. Если источник вернул EOF до того, как буфер заполнен, ReadFull транслирует это в ErrUnexpectedEOF.

🐸 Библиотека Go для собеса
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥2
Уже сегодня в 19:00 (МСК) стартует открытый урок!

Тема:

«Мультиагентные системы: почему большинство архитектур переусложнены»


🔥 За 90 минут разберёмся, когда действительно стоит строить мультиагентную систему, а когда она только добавляет сложность, расходы и новые точки отказа.

Поговорим о критериях выбора архитектуры, типичных ошибках и ограничениях современных ИИ-агентов, которые важно учитывать ещё до внедрения в продукт.

🎙️ Спикер — Дмитрий Юдин, руководитель AI/ML-направления в Сloud․ru.

🎁 Для всех участников подготовили промокод на скидку 10 000 ₽ на курс «Разработка ИИ-агентов».

👉 Успей присоединиться к уроку
Вам нужно итерироваться по map[string]int и получать элементы всегда в одном и том же порядке. Какой подход использовать

Порядок итерации по map в Go намеренно рандомизирован с версии 1.0. Это сделано специально, чтобы разработчики не полагались на порядок как на гарантию.
 
Надёжный способ: keys := make([]string, 0, len(m)) → заполнить ключами → sort.Strings(keys) → итерироваться по слайсу, читая значения из map.
 
Отдельный вопрос со звёздочкой: если ключи — числа, а не строки, тип ключа влияет на аллокации при сортировке. []int с sort.Ints не аллоцирует лишнего, тогда как конвертация в []interface{} для универсальной сортировки создаёт нагрузку на GC при большом количестве элементов.

🐸 Библиотека Go для собеса
Please open Telegram to view this post
VIEW IN TELEGRAM
Что возвращает append

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

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

🐸 Библиотека Go для собеса
Please open Telegram to view this post
VIEW IN TELEGRAM
Что возвращает copy и сколько элементов он копирует

copy копирует элементы из исходного слайса в целевой и возвращает число скопированных элементов. Это число равно минимуму из len(dst) и len(src). Лишние элементы источника просто игнорируются, ошибки не будет.

src := []int{1, 2, 3, 4}
dst := make([]int, 2)
n := copy(dst, src)
fmt.Println(n, dst) // 2 [1 2]


🐸 Библиотека Go для собеса
Please open Telegram to view this post
VIEW IN TELEGRAM
🤖 AI пишет код за вас? Это самое скучное, что он умеет

Основное время разработчик тратит на другое: разобраться в чужой кодовой базе, найти нужный участок проекта, проверить решение, собрать Pull Request. Вот где AI реально экономит часы — если знать, как им пользоваться.

23 июня Ольга Лукьянова покажет это на практике: как с помощью современных AI-инструментов быстро погружаться в незнакомый проект, находить нужный код, реализовывать задачи и проверять результат до ревью коллег.

В итоге вы увидите не отдельные приёмы и промпты, а целостный workflow, который можно встроить в свою работу уже на следующий день 🔥

Чтобы лучше погрузиться в тему:

📺 Выступление про SourceCraft
📖 Статья на Хабре

🗓️ Когда: 23 июня, 19:00 (МСК)

👉 Занять место на открытом уроке
1
Как Go работает с комплексными числами

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

Два встроенных типа

Есть complex64 и complex128. У complex64 действительная и мнимая части это float32, у complex128 это float64. По умолчанию нетипизированная комплексная константа имеет тип complex128, поэтому в большинстве случаев работают именно с ним.

Как создать комплексное число

Двумя способами. Через литерал с суффиксом i для мнимой части:
z := 2 + 3i


Либо через встроенную функцию complex, которая собирает число из двух вещественных частей одного типа:
re := 2.0
im := 3.0
z := complex(re, im) // complex128


🐸 Библиотека Go для собеса
Please open Telegram to view this post
VIEW IN TELEGRAM
🤖 Какие задачи можно действительно доверить ИИ?

Уже завтра разберём это на открытом уроке «AI-инструменты в разработке: как писать код быстрее с помощью ассистентов».

Спикер — Ольга Лукьянова, руководитель команды поиска и навигации по коду в SourceCraft от Яндекса.

После урока вы:

🔹 поймёте, какие задачи стоит делегировать AI уже сегодня;
🔹 научитесь быстрее разбираться в новых проектах и кодовой базе;
🔹 увидите, как выглядит современный workflow разработки с AI;
🔹 узнаете, где AI помогает экономить время, а где всё ещё нужен контроль разработчика.

На практике разберём путь от получения задачи до готового Pull Request с использованием AI-инструментов и AI-ревью.

🗓️ 23 июня, 19:00 (МСК)
⏱️ 90 минут

👉 Зарегистрироваться и получить рабочий AI-workflow для своих задач
Что будет, если тело функции в Go — пустые фигурные скобки

Функция с пустым телом компилируется без ошибок. Она ничего не делает, ничего не возвращает:
func doNothing() {}


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

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

Встроенными функциями real и imag. Первая возвращает действительную часть, вторая мнимую. Тип результата совпадает с базовым типом числа, то есть float32 для complex64 и float64 для complex128:
n := complex(2.0, 3.0)
fmt.Println(real(n), imag(n)) // 2 3


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

➡️ Поток создаёт и планирует операционная система через своё ядро. Горутиной управляет рантайм Go. Его планировщик работает в пользовательском пространстве и не дёргает ядро на каждое переключение.

➡️ Поток получает фиксированный стек, обычно от 1 до 8 МБ. Горутина стартует со стеком примерно в 2 КБ, и этот стек растёт и сжимается по мере надобности. Поэтому горутин можно держать сотни тысяч, а потоков столько вы не создадите.
 
➡️ Создание потока дорогое, оно идёт через системный вызов. Горутина создаётся дёшево, это по сути структура в памяти рантайма. Отсюда и разница в количестве.

➡️ Переключение потоков делает ядро, это полноценный контекстный свич с заметными затратами. Переключение горутин происходит в пользовательском пространстве и стоит дешевле.

➡️ Потоки чаще общаются через разделяемую память и примитивы синхронизации вроде мьютексов. В Go принят другой подход, общение через каналы. Формулируют это так, не разделяйте память ради общения, общайтесь, чтобы разделять данные.

🐸 Библиотека Go для собеса
Please open Telegram to view this post
VIEW IN TELEGRAM
👍41🥱1
В чём основная разница между new и make

new(T) выделяет память под обнулённое значение типа T и возвращает указатель на него, то есть *T.

make создаёт и инициализирует значение и возвращает само значение, а не указатель.

Ещё одно отличие в области применения. new работает с любым типом, а make только со слайсами, мапами и каналами.

🐸 Библиотека Go для собеса
Please open Telegram to view this post
VIEW IN TELEGRAM
🚀 Освойте разработку AI-агентов и получите доступ ещё к двум курсам Академии бесплатно!

В 2026 году просто писать код мало. Компании ищут инженеров, умеющих проектировать автономные системы и закрывать задачи бизнеса в разы быстрее.

Чтобы вы вышли на рынок с максимальным преимуществом, мы подготовили специальное предложение: покупаете курс по AI-агентам и ещё 2 курса Академии получаете бесплатно!

Соберите свой стек под оффер:

🔹 AI-агенты + AgentOps + Архитектура — комбо для бэкендеров и техлидов, чтобы внедрять ИИ без боли для прода.
🔹 AI-агенты + Математика + ML — для тех, кто хочет войти в Data Science.
🔹 AI-агенты + Алгоритмы — чтобы уверенно проходить хардкорные технические собесы.

Как это работает: вы оставляете заявку на курс по разработке AI-агентов и указываете еще два курса, которые хотите открыть в подарок.

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

👉 Забрать предложение и освоить ИИ-агентов
Что вернёт new(int)

Указатель на ноль. Память под int выделится, значение будет 0, а на руках окажется *int.

p := new(int)
fmt.Println(*p) // 0


🐸 Библиотека Go для собеса
Please open Telegram to view this post
VIEW IN TELEGRAM
Что вернёт new([]int) и можно ли с этим работать

Вернётся указатель на nil слайс. Записать по индексу нельзя, будет паника, потому что под массив память ещё не выделена.

А вот append сработает, так как он сам создаёт массив при необходимости. Но на практике так почти никто не пишет, для слайсов берут make или литерал.

🐸 Библиотека Go для собеса
Please open Telegram to view this post
VIEW IN TELEGRAM
🎬 Где ломаются архитектуры ИИ-агентов и как этого избежать: запись урока от Proglib.Academy и cloud․ru

Proglib.аcademy вместе с cloud․ru провели вебинар, где разобрали реальные боли проектирования автономных систем. Вы просили запись встречи — она уже в открытом доступе!

Что внутри:

— критерии выбора между одним агентом и мультиагентной системой;
— разбор популярных архитектурных ошибок;
— реальные ограничения современных ИИ-агентов;
— практические рекомендации по проектированию агентных систем.

👉 Посмотреть запись можно тут:
VK
YouTube
Что означают аргументы в make([]int, 10, 15)

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

s := make([]int, 10, 15)
fmt.Println(len(s), cap(s)) // 10 15


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