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

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

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

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

Наши каналы: https://t.iss.one/proglibrary/9197
Download Telegram
Что такое гонка данных и как она проявляется в языке Go

➡️ Гонки данных — это ошибки, возникающие в конкурентных системах, когда две горутины одновременно обращаются к одной и той же переменной, и хотя бы одно из обращений — запись. Для предотвращения таких ошибок в Go есть примитивы синхронизации.

➡️ Состояние гонки (Race Condition) описывает ситуацию, когда поведение программы зависит от порядка выполнения операций. Гонка данных — это тип состояния гонки.

Пример гонки данных, которая может привести к сбоям и повреждению памяти:
func main() {
c := make(chan bool)
m := make(map[string]string)
go func() {
m["1"] = "a" // Первый конфликтный доступ
c <- true
}()
m["2"] = "b" // Второй конфликтный доступ
<-c
for k, v := range m {
fmt.Println(k, v)
}
}


➡️ Для диагностики таких ошибок Go предоставляет встроенный детектор гонок данных. Для его использования достаточно добавить флаг -race при запуске команд:
$ go test -race mypkg   
$ go run -race mysrc.go
$ go build -race mycmd
$ go install -race mypkg


➡️ Переменная окружения GORACE позволяет настроить параметры детектора гонок, например:
$ GORACE="log_path=/tmp/race/report Strip_path_prefix=/my/go/sources/" go test -race


🐸 Библиотека Go для собеса
Please open Telegram to view this post
VIEW IN TELEGRAM
👍21
Для чего в Go применяется пустой идентификатор

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

1️⃣ Игнорирование возвращаемых значений функции: если функция возвращает несколько значений, но нужно только одно из них.
value, _ := someFunction()


2️⃣Игнорирование элементов в range: при переборе элементов среза или карты, когда нужен только ключ или только значение.
for k, _ := range myMap {
fmt.Println(k)
}

for _, v := range mySlice {
fmt.Println(v)
}


3️⃣Импорт пакета: если пакет нужно импортировать только для выполнения его инициализации, без использования его функций или типов.
import _ "image/png"


4️⃣ Игнорирование переменных в множественном присваивании:
_, y := getCoordinates()


5️⃣ Игнорирование ошибок: можно использовать для игнорирования ошибок, но это не рекомендуется.
result, _ := strconv.Atoi("123")


6️⃣ Использование в анонимных структурах: при создании анонимной структуры, когда не нужно имя для одного из полей.
person := struct {
Name string
_ int
}{"Alice", 30}


➡️ Пустой идентификатор полезен, но злоупотреблять им не следует, особенно для игнорирования ошибок.

🐸 Библиотека Go для собеса
Please open Telegram to view this post
VIEW IN TELEGRAM
3👍1
Как анонимные функции и замыкания используются в языке 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👍1
Как проверить тип данных переменной в 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
👍2🥱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
👍4
🔥 Последняя неделя, чтобы забрать курс по 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
😁8
⚡️ Бесплатный вебинар — прогнозируем цены и не сходим с ума

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

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


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

💻 Ответьте на 20 вопросов за 30 минут и проверьте, готовы ли вы к обучению на онлайн-курсе «Golang Developer. Professional» от OTUS. Сейчас Go становится все востребованнее, благодаря своей производительности, масштабируемости и экосистеме.

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

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

👉 ПРОЙТИ ТЕСТ

Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, www.otus.ru
Для чего нужен пакет 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👍1
11 сентября | 19:00
Офлайн в Москве | Онлайн

Кто выступит:

🔹Виталий Левченко, Engineering manager Wildberries проведет воркшоп на тему LLM для конкурентного Go кода;
🔹Владимир Марунин, Senior Developer Clatch, МТС Web Services расскажет про
эффективное использование sync.Map в Go;
🔹Роман Ерема, Developer MWS Cloud Platform поделится опытом разработки Cloud Controller Manager: интеграции Kubernetes с облаком MWS.

Для участия зарегистрируйся по ссылке.
До встречи на True Tech Go!
Какой характер у Go — императивный или декларативный

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

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

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

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

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

🐸 Библиотека Go для собеса
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
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