Библиотека Go для собеса | вопросы с собеседований
6.88K subscribers
225 photos
8 videos
1 file
440 links
Вопросы с собеседований по Go и ответы на них.

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

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

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

Наши каналы: https://t.iss.one/proglibrary/9197
Download Telegram
Как анонимные функции и замыкания используются в языке Go

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

• В Go есть возможность доступа к состоянию внешней функции из анонимных функций, даже после завершения внешней функции. Это позволяет создавать замыкания.
Замыкание — это функция, которая сохраняет доступ к переменным внешней функции после её завершения.

Пример с функцией incrementer, которая создает анонимную функцию для увеличения значения переменной i:
func incrementer() func() int {
i := 0

return func() int {
i++
return i
}
}


При вызове incrementer создается новая копия переменной i, и возвращенная функция увеличивает её значение. Каждый последующий вызов incrementer создает свою копию переменной i.
func main() {
increment := incrementer()
fmt.Println(increment()) // 1
fmt.Println(increment()) // 2
fmt.Println(increment()) // 3

newIncrement := incrementer()
fmt.Println(newIncrement()) // 1
}


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

Оператор switch в Go позволяет проверять тип переменной во время выполнения. Каждый switch включает хотя бы один оператор case, который работает как условие, и блок default, который выполняется, если ни одно из условий не выполнено.

Пример, который проверяет, является ли значение интерфейса i типом int или string:
func do(i interface{}) {
switch v := i.(type) {
case int:
fmt.Printf("Double %v is %v\n", v, v*2)
case string:
fmt.Printf("%q is %v bytes long\n", v, len(v))
default:
fmt.Printf("I don't know type %T!\n", v)
}
}

func main() {
do(21)
do("hello")
do(true)
}

Результат:
Double 21 is 42
"hello" is 5 bytes long
I don't know type bool!


🐸 Библиотека Go для собеса
Please open Telegram to view this post
VIEW IN TELEGRAM
👍31🥱1
Опишите принцип работы стека и приведите реализацию на Go

Стек — тип данных, основанный на принципе LIFO (last in — first out, «последним пришёл — первым вышел»).

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

Операции:
push — добавление элемента,
pop — удаление верхнего элемента,
peek — возврат верхнего элемента без удаления.


Реализация на Go через срез:
type Stack struct {
items []int
}

func (s *Stack) Push(item int) {
s.items = append(s.items, item)
}

func (s *Stack) Pop() int {
if len(s.items) == 0 {
panic("Stack is empty!")
}
item := s.items[len(s.items)-1]
s.items = s.items[:len(s.items)-1]
return item
}

func (s *Stack) Peek() int {
if len(s.items) == 0 {
panic("Stack is empty!")
}
return s.items[len(s.items)-1]
}

func (s *Stack) IsEmpty() bool {
return len(s.items) == 0
}

func (s *Stack) Size() int {
return len(s.items)
}


Мы использовали срез для хранения элементов стека. Метод Push добавляет элемент на верх стека, метод Pop извлекает его, а метод Peek позволяет посмотреть верхний элемент без его извлечения. Также мы использовали проверку стека на наличие элементов.

🐸 Библиотека Go для собеса
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
🔥 Последняя неделя, чтобы забрать курс по AI-агентам по старой цене!

Пока вы тестируете Copilot, другие уже учатся строить AI-агентов, которые реально работают на бизнес. Хватит отставать!

Наш курс — это концентрат практики по LangChain и RAG. Улучшенная версия, доработанная по отзывам первого потока.

📆 Старт — 15 сентября.

💸 Цена 49 000 ₽ — только до 24 августа.

👉 Зафиксировать цену
2
Как осуществить своп двух переменных без временной переменной

1️⃣ Сложение и вычитание (без временной переменной)
a := 5
b := 3

a = a + b // a становится 8
b = a - b // b становится 5
a = a - b // a становится 3

a и b меняются местами за три операции без использования временной переменной.

2️⃣ XOR (исключающее ИЛИ)
a := 5 // 0101 в двоичной системе
b := 3 // 0011 в двоичной системе

a = a ^ b // a становится 6 (0110)
b = a ^ b // b становится 5 (0101)
a = a ^ b // a становится 3 (0011)

Двойное применение XOR с теми же операндами восстанавливает исходное значение, поэтому значения переставляются.

3️⃣ Простая функция со свопом
func main() {
fmt.Println(swap())
}

func swap() []int {
a, b := 15, 10
b, a = a, b
return []int{a, b}
}

swap меняет a и b местами и возвращает результат.

🐸 Библиотека Go для собеса
Please open Telegram to view this post
VIEW IN TELEGRAM
😁9
⚡️ Бесплатный вебинар — прогнозируем цены и не сходим с ума

21 августа в 19:00 МСК будет бесплатный вебинар с Марией Жаровой — экспертом в ML и Data Science.

Тема:
«Введение в машинное обучение: как спрогнозировать стоимость недвижимости».


Подробности рассказываю в гс выше — включай, чтобы не пропустить.
Для чего нужен пакет cgo и что он собой представляет

Cgo создаёт мост между Go и C: код на Go вызывает функции C через пространство имён C, а код на C может вызывать экспортированные функции Go.

Cвойства cgo:
Встраивание кода C в преамбуле перед import "C".
Доступ к именам из заголовков и преамбулы через пространство имён C.
Преобразования типов выполняются явно при переходе из C.* к чистым типам Go и обратно.
Память: объекты, выделенные в C, освобождаются C.free, длительное хранение указателей на Go-память в C запрещено.

package randc

/*
#include <stdlib.h>
*/
import "C"

func Random() int {
return int(C.random()) // C.long -> Go int
}

func Seed(i uint) {
C.srandom(C.uint(i)) // Go uint -> C unsigned int
}


Разбор примера:
import "C" псевдопакет: ссылка на пространство имён C.
В rand четыре обращения к C: вызовы C.random и C.srandom, приведение C.uint(i) и сам импорт.
Random вызывает random из libc. В C она возвращает long (C.long в cgo), результат приводится к Go int перед выдачей наружу.
Seed принимает Go int, приводит к C.uint и передаёт в srandom.
Комментарий непосредственно перед import "C"преамбула. Она компилируется как C-заголовок для C-частей пакета: здесь можно объявлять/определять функции и переменные, затем использовать их из Go через C.*.

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

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

1️⃣ Императивный подход: мы описываем, как решить задачушаг за шагом, задавая последовательность команд/инструкций для получения результата.

Характерные черты:
• Код состоит из инструкций (команд).
• Порядок важен: команды выполняются последовательно (если не оговорено иное).
Последующие инструкции могут читать из памяти результаты предыдущих.
• Изменение состояния допустимо: инструкции записывают данные в память.

2️⃣ Декларативный подход: мы формулируем, что хотим получить, не задавая конкретных шагов. Выбор способа выполнения берёт на себя система или интерпретатор.
Пример: SQL для запросов к БД и HTML для описания структуры веб-страниц.

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

🐸 Библиотека Go для собеса
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8
This media is not supported in your browser
VIEW IN TELEGRAM
☝️ Один мудрый тимлид дал двум своим разработчикам по «таланту» — мощной, но своенравной LLM.

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

Второй же разработчик не побоялся. Он построил для своей LLM систему RAG — дал ей «лопату и карту», чтобы находить сокровища в базе знаний компании. Его AI-агент отвечал точно по делу, ссылаясь на реальные документы. Он заставил свой «талант» работать и приносить пользу.

Мощь LLM раскрывается не в ней самой, а в системах, которые вы строите вокруг неё.


Именно такие системы мы и будем строить на втором потоке нашего курса «AI-агенты для DS-специалистов». Мы не просто поговорим о RAG, а соберём полный пайплайн с оценкой качества, чтобы ваш агент не врал.

Представьте, что вы сможете начать изучать эту сложную и востребованную тему уже 15 сентября, а не ждать официального старта в октябре. У вас будет фора в 3 недели, чтобы спокойно разобраться в векторных базах и подходе «LLM as a Judge».

💸 Цена 49.000 ₽ действует последние 4 дня — до 24 августа.

👉 Начать строить RAG раньше других
🥱21👾1
Какой будет результат при различных состояниях канала во время записи в этот канал

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

🐸 Библиотека Go для собеса
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7
Что такое паттерн «Команда» и как его реализовать в Go

Паттерн «Команда» — поведенческая модель, которая оборачивает запросы или операции в объекты, позволяя откладывать их выполнение, выстраивать в очереди, отслеживать историю и отменять.

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

Основные компоненты паттерна:
1. Command — объект-запрос для выполнения.
2. Receiver — объект, выполняющий команду.
3. Invoker — инициатор запроса, отправляющий команду.

Паттерн разделяет инициатора операции и исполнителя. Инициатор знает только, как отправить команду.

Для реализации нужно:
1. Интерфейс Command, описывающий общие методы команд.
2. ConcreteCommand — класс, реализующий команду и взаимодействующий с Receiver.
3. Invoker — класс, инициирующий выполнение команд.
4. Receiver — класс, выполняющий действия.

Invoker может инициировать выполнение и отмену команды. ConcreteCommand отправляет запросы на выполнение в Receiver.

🐸 Библиотека Go для собеса
Please open Telegram to view this post
VIEW IN TELEGRAM
👍63🥱2
This media is not supported in your browser
VIEW IN TELEGRAM
Так, владелец макбука. Хватит позировать в кофейне.

Настоящее портфолио — это не стикеры на крышке, а проект с чистым кодом, README и рабочей демкой.

Не знаешь, как такой собрать? Научим. Наш курс «ML для старта в Data Science» — это пошаговый гайд к проекту, за который не стыдно.

ОСТАЛАСЬ НЕДЕЛЯ, чтобы забрать его по старой цене в 44.000 ₽. С 1 сентября — всё.

🎁 И да, при покупке курса ML до 1 сентябрякурс по Python получаешь бесплатно.

👉 Апгрейд от «вайба» до «оффера» тут
🥱4
Какие есть уровни изоляции транзакций

Уровни изоляции — это правила, по которым параллельные операции «видят» изменения друг друга.

1. Read Uncommitted. Видите чужие черновики. Можно прочитать число, которое через минуту откатят. Быстро, но риск получить «мнимые» значения.

2. Read Committed. Видите только то, что уже сохранено. Однако между двумя одинаковыми запросами результат может поменяться: кто-то успел обновить те же строки.

3. Repeatable Read. Если вы начали чтение, те же строки для вас не «прыгают» до конца операции. Но в подборку могут добавиться новые подходящие строки, которых изначально не было (вы начали считать — а в систему пришли новые записи).

4. Serializable. Самый строгий режим: система делает так, будто операции выполнялись по очереди. Итог предсказуемый, но возможны ожидания и повторные попытки под высокой нагрузкой.

🐸 Библиотека Go для собеса
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥6👍3
📢 Какой сетап идеально подойдёт для разработки AI-агента?

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

❤️ — 1
👍 — 2
⚡️ — 3
👏 — 4
🔥 — 5
🎉 — 6
😁 — 7
😍 — 8
🤩 — 9

Какой бы сетап ни был, без AI-агентов в 2025 всё равно далеко не уедешь.

👉 Научим, как строить агентов, которые кодят с тобой
👍7🔥753😍2
Какую разницу имеют поверхностное и глубокое копирование в Go

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

Используется, когда нужно работать с одними и теми же данными, но с разными именами, и изменения в одной переменной не должны затронуть другую.
original := []int{1, 2, 3}
copied := original
copied[0] = 99
fmt.Println(original) // [99 2 3]


Глубокое копирование создает новую переменную с независимыми копиями данных.

Глубокое копирование особенно важно при работе со сложными структурами данных, где изменение одного элемента может повлиять на всю структуру. Также оно применяется при сериализации данных или создании полной копии структуры.
Пример с библиотекой:
import "github.com/mohae/deepcopy"

original := []int{1, 2, 3}
copied := deepcopy.Copy(original)
copied[0] = 99
fmt.Println(original) // [1 2 3]


🐸 Библиотека Go для собеса
Please open Telegram to view this post
VIEW IN TELEGRAM
Почему одна и та же выборка чисел с плавающей точкой даёт разные итоги при разном порядке сложения

Потому что компьютер хранит десятичные дроби приблизительно (в двоичной форме IEEE-754), и при каждом сложении происходит округление. Меняя порядок слагаемых, Вы меняете последовательность округлений — отсюда чуть разные итоги.
Говоря иначе: сложение таких дробей неассоциативно.

Что происходит:
• Числа вроде 0.1/0.2/0.3 не представимы точно, их двоичные «хвосты» обрезаются.
• На каждом шаге суммирования происходит новое округление. В другом порядке эти округления происходят в других местах.
Маленькие слагаемые рядом с большими могут «теряться», почти противоположные — «съедать разряды».
• Разница обычно микроскопическая, порядка 1–2 ULP — минимальных шагов представления, но для строгого сравнения это уже другие числа.

Как с этим жить:
• Не рассчитывайте на «точное равенство» результатов — сравнивайте с допуском (абсолютным/относительным).
Фиксируйте порядок вычислений и применяйте более устойчивые схемы суммирования на длинных рядах.
• Для денег и отчётности используйте десятичные или целочисленные представления — там нужна точность без двоичной погрешности.

🐸 Библиотека Go для собеса
Please open Telegram to view this post
VIEW IN TELEGRAM
Осталось 48 часов!

Обратный отсчёт пошёл: только до воскресенья 23:59 можно купить курс «AI-агенты для DS-специалистов» и начать учиться уже с 15 сентября.

⚡️ Это ваши +3 недели форы, чтобы спокойно разобраться в самых сложных темах и прийти к первому занятию 7 октября уже подготовленным.

👉 Забрать место