Библиотека Go для собеса | вопросы с собеседований
6.8K subscribers
216 photos
5 videos
1 file
372 links
Вопросы с собеседований по Go и ответы на них.

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

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

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

Наши каналы: https://t.me/proglibrary/9197
Download Telegram
📦 Главные проблемы распределенных систем (и способы их решения)

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

➡️ В этой статье мы рассмотрим четыре ключевых вызова в разработке таких систем и эффективные методы их преодоления.

🐸 Библиотека программиста
Please open Telegram to view this post
VIEW IN TELEGRAM
Что такое коллизия хэш-функции

Коллизия хэш-функции происходит, когда два разных входных значения приводят к одинаковому хэшу. Это может создать уязвимости, позволяя злоумышленнику подделывать данные, не изменяя хэш.

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

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

Чтобы избежать гонок при работе с слайсами, необходимо использовать механизмы синхронизации, такие как мьютексы (sync.Mutex или sync.RWMutex) или каналы для передачи копий данных между горутинами. Важно предотвратить одновременное изменение и чтение слайса, чтобы избежать неожиданных ошибок.


🐸Библиотека Go для собеса
Please open Telegram to view this post
VIEW IN TELEGRAM
Расскажите про аналоги default в select'e

Горутины и каналы с блокировкой: Использование горутин с механизмами синхронизации, такими как sync.WaitGroup, для контроля блокировки при работе с каналами.
Таймеры или каналы с ограничением времени: Применение time.After или time.Tick для установки временных ограничений на ожидание, избегая бесконечной блокировки, как в случае с default.

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

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

Принципы саги:
Компенсационные транзакции: Откат предыдущих шагов при сбое.
Гибкость и отказоустойчивость: Избежание блокировок и улучшение отказоустойчивости.
Деление на шаги: Каждый шаг — это независимая локальная транзакция.

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

Горутины (goroutines): Легковесные потоки, которые выполняют код асинхронно.
Машины (M): Абстракции операционных систем, отвечающие за выполнение горутин на физических процессорах.
Процессоры (P): Сущности, управляющие очередью готовых горутин и привязанные к ядрам процессоров.
Очередь ожидания (run queue): Очередь горутин, которые готовы к выполнению на процессоре.
Синхронизация: Взаимодействие с механизмами синхронизации (каналы, мьютексы, условные переменные) для управления выполнением горутин.

🐸Библиотека Go для собеса
Please open Telegram to view this post
VIEW IN TELEGRAM
⭐️ Что означает звёздочка у ресивера в Go

Звёздочка у ресивера в Go, как правило, означает, что мы работаем с указателем на тип, а не с самим значением этого типа. То есть, когда мы видим звёздочку перед типом, это указывает на то, что переменная является указателем.

Пример:
var ptr *int // указатель на int
Если у нас есть переменная типа *int, то её значение — это адрес в памяти, где хранится переменная типа int. Чтобы получить доступ к значению по этому адресу, нужно использовать оператор разыменования (тоже звёздочку):
var a int = 58
var ptr *int = &a // ptr теперь указывает на a
fmt.Println(*ptr) // выводит 58


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


🐸Библиотека Go для собеса
Please open Telegram to view this post
VIEW IN TELEGRAM
Знакомы ли с концепцией 12FA для проектирования SaaS приложений

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

Основные принципы включают:
1. Разделение конфигурации – конфигурация должна быть отдельной от кода (например, через переменные окружения).
2. Кодовая база – приложение должно иметь единую кодовую базу, которая управляется с помощью системы контроля версий.
3. Поддержка нескольких сред – приложение должно работать в различных средах (разработка, тестирование, продакшн) с минимальными изменениями в коде.
4. Обработка зависимостей – все зависимости должны быть явно заявлены в коде и управляться через зависимости, такие как go.mod для Go.
5. Сборка, релиз, выполнение – процесс развертывания приложения должен быть разделён на стадии сборки, релиза и выполнения.
6. Отслеживание состояния – приложение должно минимизировать зависимость от состояния, хранимого на сервере, и использовать внешние системы хранения состояния.


Продолжение следует...

🐸Библиотека Go для собеса
Please open Telegram to view this post
VIEW IN TELEGRAM
Знакомы ли с концепцией 12FA для проектирования SaaS приложений (часть 2)

7. Порты и связи – приложение должно быть независимым от порта, на котором оно работает, и должно использовать обмен сообщениями через порты.
8. Конкурентность – приложение должно быть масштабируемым и поддерживать параллельное выполнение с использованием процессов.
9. Обработка ошибок – ошибки должны быть обрабатываться через логи, а не через сложные механизмы восстановления состояния.
10. Репликация процессов – приложение должно поддерживать репликацию процессов, чтобы обеспечивать отказоустойчивость.
11. Документация – необходимо поддерживать документацию для быстрого развертывания приложения.
12. Тестирование и производство – код должен быть готов к тестированию и запуску на производстве с минимальными усилиями.


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

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

При склеивании строк в Go с помощью оператора «+» создается новая строка, так как строки неизменяемы. Это может быть неэффективно, так как каждый раз происходит выделение памяти для новой строки.
Для улучшения производительности в случае частых склеиваний рекомендуется использовать strings.Builder, который оптимизирует процесс и минимизирует лишние аллокации.

Пример с strings.Builder:
var builder strings.Builder
for i := 0; i < 1000; i++ {
builder.WriteString("x")
}
result := builder.String()

Это значительно эффективнее, чем использование оператора «+» в цикле.


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

В Go для работы со строками используются следующие подходы:
1. Конкатенация: Строки можно склеивать с помощью оператора +, но это неэффективно при многократных операциях.

s := "Hello, " + "world!"

2. Пакет strings: Содержит функции для поиска, замены, разделения и преобразования строк:
import "strings"
lower := strings.ToLower("HELLO") // "hello"

3. strings.Builder: Эффективен для многократной конкатенации строк, избегает излишних аллокаций.
var builder strings.Builder
builder.WriteString("Hello")
result := builder.String() // "Hello"

4. Слайсы байт: Строки в Go — это слайсы байт, и их можно манипулировать для низкоуровневой работы.
b := []byte("Hello")
b[0] = 'h'
newStr := string(b) // "hello"


🐸Библиотека Go для собеса
Please open Telegram to view this post
VIEW IN TELEGRAM
Можно ли сделать int(string) и string(int) соответственно

В Go нет прямой функции, как int(string) или string(int), которые можно использовать напрямую для преобразования типов. Вместо этого используются функции из пакета strconv.

1. Преобразование строки в целое число:
Для того, чтобы преобразовать строку в целое число, используется функция strconv.Atoi или strconv.ParseInt.
import "strconv"

str := "123"
num, err := strconv.Atoi(str) // преобразует строку в int
if err != nil {
// обработка ошибки
}

2. Преобразование целого числа в строку:
Для преобразования числа в строку используется функция strconv.Itoa.
import "strconv"

num := 123
str := strconv.Itoa(num) // преобразует int в строку

Кратко:
Нельзя напрямую использовать int(string) или string(int) в Go.
Для преобразования строки в число используем strconv.Atoi или strconv.ParseInt.
Для преобразования числа в строку используем strconv.Itoa.


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

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

Основной инструмент для управления временем жизни горутины — это context.Context. Он позволяет задать дедлайн или тайм-аут и передать этот контекст внутрь горутины. Горутине нужно проверять канал <-ctx.Done() и корректно завершаться, когда этот канал закрывается. Это позволяет, например, автоматически завершать работу горутин по истечении заданного времени или по сигналу отмены извне.

Также можно использовать каналы управления вручную, передавая в горутину канал stop или done, и завершать её при получении сигнала. Такой способ полезен, если не требуется гибкость context, но нужно просто и понятно управлять остановкой.

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

Если нужно изменить объект внутри функции или он слишком большой для копирования — передавать по указателю. Это экономит ресурсы и позволяет напрямую работать с оригиналом. Но надо быть осторожным: можно случайно испортить данные, особенно если несколько функций шарят один и тот же указатель.

Если же объект простой, лёгкий или менять его не нужно — передавай по значению. Так безопаснее, проще для отладки, и точно не получится неожиданных побочных эффектов.

🐸Библиотека Go для собеса
Please open Telegram to view this post
VIEW IN TELEGRAM
В чём разница между replace, exclude и require в go.mod?

require — явно добавляет зависимость (и её версию) в проект.

replace — подменяет одну версию/путь зависимости на другую (например, локальную или форк).

exclude — exclude — исключает конкретную версию модуля из разрешения зависимостей. Это не удаляет модуль целиком, но не даст использовать именно эту версию (например, если она багованная).

🐸Библиотека Go для собеса
Please open Telegram to view this post
VIEW IN TELEGRAM
Что имеется в виду под статической компиляцией

Статическая компиляция в Go — это процесс, при котором компилятор Go встраивает все зависимости (включая стандартные библиотеки и сторонние пакеты) в один исполняемый бинарный файл.

Иными словами: результат сборки (go build) — это один самодостаточный бинарник, который можно запустить без дополнительных библиотек, файлов или окружения. Всё, что нужно программе для работы, уже внутри.

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

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

🐸Библиотека Go для собеса
Please open Telegram to view this post
VIEW IN TELEGRAM
Библиотека Go для собеса | вопросы с собеседований
Какой паттерн позволяет объединить несколько различных интерфейсов в один Этот паттерн называется Адаптер. Он позволяет преобразовать интерфейс одного класса в интерфейс, который ожидает клиент. Это полезно, когда у нас есть классы с несовместимыми интерфейсами
Признаёмся, взяли вопрос без корректировок с одного из интервью 👀

В хорошем собеседовании интервьюер не просто задаёт вопросы, но и даёт фидбек по ответу и даже может объяснить концепцию которую он спросил.

Человеческий фактор не исключение, поэтому советуем уточнять что имеет в виду человек по ту сторону интервью.

Пример для вопроса про адаптер
// Target - интерфейс, который ожидает клиент
type Target interface {
Request() string
}

// Adaptee - устаревший класс, который не соответствует интерфейсу Target
type Adaptee struct{}

func (a *Adaptee) SpecificRequest() string {
return "Специфический запрос из Adaptee"
}

// Adapter - адаптирует интерфейс Adaptee к интерфейсу Target
type Adapter struct {
adaptee *Adaptee
}

func (a *Adapter) Request() string {
// Адаптируем специфический запрос Adaptee к формату, который ожидает Target
return a.adaptee.SpecificRequest()
}


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

YAGNI (You Aren't Gonna Need It) — это принцип разработки программного обеспечения, который утверждает, что не стоит добавлять функциональность или код, который на данный момент не нужен. Идея заключается в том, чтобы сосредоточиться только на тех фичах и решениях, которые действительно требуются для текущей задачи, а не строить «на будущее» на основе предположений о том, что может быть нужно.

🐸Библиотека Go для собеса
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥 IT Breaking Memes — 30 000 ₽ за самую смешную IT-новость

Библиотека программиста запускает конкурс, который взорвет вашу ленту: создайте самую смешную альтернативную версию реальной IT-новости!

👾 Правила просты:
1. Берете настоящую новость из мира технологий.
2. Переписываете ее так, чтобы смеялись все.
3. Получаете деньги и славу.

🏆 Призы:
- 1 место: 30 000 ₽ + статус ведущего нового юмористического IT-канала
- 2 и 3 место: по 5 000 ₽ + вечный почет в IT-сообществе

Пример:
Реальная новость: «Гугл создала модель для общения с дельфинами».

Смешная альтернатива: «Нейросеть от Гугл обрабатывает видеопоток с камеры в свинарнике. ИИ следит, сколько свинья находится возле кормушки, не отталкивают ли ее собратья. Недокормленных докармливают, а переевшие пропускают следующую кормешку».

📅 Сроки: с 29 апреля по 11 мая включительно

Для участия отправьте свою смешную новость в гугл-форму: https://forms.gle/6YShjgfiycfJ53LX8

Ждем ваших новостей!