Библиотека Go для собеса | вопросы с собеседований
6.89K subscribers
222 photos
6 videos
1 file
430 links
Вопросы с собеседований по Go и ответы на них.

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

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

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

Наши каналы: https://t.iss.one/proglibrary/9197
Download Telegram
Что включает в себя набор примитивов синхронизации пакета sync в Go

Примитивы синхронизации — инструменты (в основном из пакета sync), которые обеспечивают безопасную работу с общими данными и координацию горутин.

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

sync.RWMutex — вариант мьютекса с разделением на блокировку для чтения и записи:
Одновременно могут выполняться несколько операций чтения.
Запись возможна только при полном исключении доступа.

sync.WaitGroup — позволяет дождаться завершения группы горутин. Удобен для синхронного старта/остановки процессов.

sync.Once — гарантирует однократное выполнение кода, даже при множественных вызовах из разных горутин.

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

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

🐸 Библиотека Go для собеса
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
🚀 Главная ошибка новичка в ML — строить звездолёт вместо велосипеда

Многие сразу хотят свою Midjourney, но в итоге получают только выгорание.

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

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

👉 Начните правильно

Берёте курс «ML для старта» до конца недели — Python в подарок.

А 21 августа пройдет бесплатный вебинар с Марией Жаровой: узнаете, какие проекты качают скилл, а какие качают ваши нервы.

А какой самый сложный проект вы брались делать в самом начале? 🫢
1
Что такое гонка данных и как она проявляется в языке 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