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

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

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

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

Наши каналы: https://t.iss.one/proglibrary/9197
Download Telegram
Как создать простой веб-сервер на Go с использованием стандартной библиотеки

Базовый пример:
package main

import (
"fmt"
"net/http"
)

func helloHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello, World!")
}

func main() {
http.HandleFunc("/hello", helloHandler)
http.ListenAndServe(":8080", nil)
}


1️⃣ Подключаем fmt для форматированного вывода и net/http для работы с HTTP.

2️⃣ Обработчик запросов: функция helloHandler отвечает на все запросы сообщением "Hello, World!".

3️⃣ С помощью http.HandleFunc регистрируем обработчик на корневой эндпоинт ("/hello").

4️⃣ http.ListenAndServe(":8080", nil) запускает сервер на порту 8080.

➡️ После запуска кода при переходе по адресу https://localhost:8080/hello вы получите ответ: "Hello, World!"

Также можно использовать http.FileServer:
package main

import "net/http"

func main() {
port := ":8080"
handler := http.FileServer(http.Dir("."))
http.ListenAndServe(port, handler)
}

Аналог python -m http.serverраздаёт текущую директорию по HTTP.

🐸 Библиотека Go для собеса
Please open Telegram to view this post
VIEW IN TELEGRAM
😁52
Чем является rune в Go и как он связан с символами Unicode

Работа со строками в Go не ограничивается ASCII-символами, в текстах часто встречаются символы других языков и эмодзи. Для корректной обработки таких символов используется тип rune.

rune — это псевдоним для int32, предназначенный для хранения Unicode-кода одного символа.

При переборе строки с помощью конструкции for range, Go обходит строку по символам Unicode, автоматически преобразуя её в последовательность rune.

Примеры:

Объявление и инициализация руны:
var r rune = 'A'


Преобразование строки в срез рун:
s := "Привет"
runes := []rune(s)


Итерация по рунам в строке:
for _, r := range "Привет" {
fmt.Printf("%c ", r)
}
// Вывод: П р и в е т


Обратное преобразование среза рун в строку:
runes := []rune{'П', 'р', 'и', 'в', 'е', 'т'}
s := string(runes) // "Привет"


Получение Unicode-кода руны:
r := 'A'
code := int32(r) // 65


Проверка длины строки в рунах:
s := "Привет"
length := utf8.RuneCountInString(s) // 6


🐸 Библиотека Go для собеса
Please open Telegram to view this post
VIEW IN TELEGRAM
👍102🔥1
Как Go реализует обработку ошибок

1️⃣ Явная обработка — в Go нет исключений.
Функции, которые могут завершиться с ошибкой, возвращают её как отдельное значение наряду с результатом.


2️⃣ Множественные возвращаемые значения — стандартный шаблон:
val, err := someFunction()
if err != nil {
// обработка ошибки
}


3️⃣ Кастомные ошибки — через пакет errors можно определять собственные типы ошибок и добавлять к ним полезную информацию.

4️⃣ Обогащение контекста — с Go 1.13 доступны errors.Is, errors.As и fmt.Errorf(... %w ...) для оборачивания ошибок с сохранением исходной причины.
func DoSomething() error {
if err := someOperation(); err != nil {
return fmt.Errorf("someOperation failed: %w", err)
}
return nil
}


5️⃣ Нет finally — очистка ресурсов выполняется через defer.

6️⃣ Panic и recover — используются только для критических непредвиденных ситуаций, например выхода за границы массива.

🐸 Библиотека Go для собеса
Please open Telegram to view this post
VIEW IN TELEGRAM
5👍2🔥1
Расскажите о механизме мьютексов в Go и укажите существующие типы

Mutex (mutual exclusion — взаимное исключение) — примитив синхронизации для защиты критической секции программы. Он предотвращает гонки данных и deadlock’и, обеспечивая эксклюзивный доступ к ресурсу.

Критическая секция — участок кода, где одновременно может работать только одна горутина.

➡️ sync.Mutexэксклюзивная блокировка
Только одна горутина может захватить мьютекс и получить доступ к ресурсу.
var mu sync.Mutex

func increment() {
mu.Lock()
count++
mu.Unlock()
}

Здесь мы рассматриваем защиту глобальной переменной count при инкременте из множества горутин.

➡️ sync.RWMutex концептуально то же самое, что и Mutex, но дает вам немного больше контроля над памятью.
Позволяет:
RLock — множеству горутин читать одновременно.
Lock — только одному писателю, без читателей.
var mu sync.RWMutex

func set(key, value string) {
mu.Lock()
cache[key] = value
mu.Unlock()
}

func get(key string) string {
mu.RLock()
defer mu.RUnlock()
return cache[key]
}

Дает безопасный доступ к кэшу — много читателей, один писатель.

🐸 Библиотека Go для собеса
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7🔥1👏1
Что собой представляет «затенение» переменной (shadowing) в Go

В Go «затенение» (shadowing) происходит, когда переменная, объявленная в локальной области видимости, имеет такое же имя, как и переменная во внешней области видимости. Внутренняя переменная «затеняет» внешнюю, делая её недоступной.
package main

import (
"fmt"
)

func main() {
x := 10

if true {
x := 5 // затенение внешней переменной x
fmt.Println(x) // выводит 5
}

fmt.Println(x) // выводит 10
}


«Затенение» может быть особенно запутывающим, когда оно касается переменных, полученных из результатов функций, таких как err. Пример часто встречающегося кода в Go:
value, err := someFunction()
if err != nil {
// обработка ошибки
}

// ...

value2, err := anotherFunction() // новое затенение переменной err
if err != nil {
// обработка ошибки
}


Если использовать := вместо =, вы создадите новую переменную err, которая «затенит» переменную err из внешней области видимости. Это может привести к неправильной обработке ошибок, так как внешняя ошибка будет проигнорирована.

Обнаружение затенения:

1. go vet -shadow ./...
2. golangci-lint run --enable shadow
3. Использование инструмента shadow:
$ go get -u golang.org/x/tools/go/analysis/passes/shadow/cmd/shadow
$ go vet -vettool=$(which shadow)


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

➡️ Избегайте глобальных переменных, они остаются в памяти на весь срок работы программы.

➡️ Выбирайте правильные типы данных используйте int8, int16 вместо int, если диапазон позволяет.

➡️ Используйте sync.Pool для повторного использования часто создаваемых объектов.

➡️ Ленивая инициализация, инициализируйте данные только по мере необходимости.

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

➡️ Срезы против массивов — используйте массивы, если размер данных известен заранее.

➡️ Освобождение ресурсов, присваивайте nil неиспользуемым структурам.

➡️ Используйте буферизацию, она снижает количество выделений памяти.

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

🐸 Библиотека Go для собеса
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6🔥1
Что включает в себя набор примитивов синхронизации пакета 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
👍4
🚀 Главная ошибка новичка в 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