Golang | Вопросы собесов
4.55K subscribers
31 photos
850 links
Download Telegram
🤔 Как устроены контексты в Go?

Контексты (context.Context) представляют собой интерфейс, который используется для передачи мета-данных, управления сроками действия и отменой операций в иерархии вызовов функций. Основная цель контекста — обеспечение способа для остановки выполнения программы (например, запросов или подпроцессов) по требованию. Это особенно полезно в сетевых приложениях, где вам может потребоваться прервать выполнение операции, которая больше не требуется или занимает слишком много времени.

🚩Ключевые особенности

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

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

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

🟠Значения
Контексты могут нести значения — пары ключ-значение, которые можно устанавливать и получать. Эти значения обычно используются для передачи данных, специфичных для запроса, таких как идентификаторы сессий или токены авторизации.

🚩Создание и использование контекста

🟠context.Background()
Возвращает пустой контекст, который никогда не отменяется. Обычно используется в основной функции и при инициализации.

🟠context.TODO()
Используется для указания, что должен быть предоставлен подходящий контекст. Обычно применяется в разработке и при рефакторинге.

🟠context.WithCancel(parent Context) (ctx Context, cancel CancelFunc)
Создает новый контекст с возможностью отмены.

🟠context.WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc)
Создает контекст, который автоматически отменяется в указанный deadline.

🟠context.WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc)
Аналогичен WithDeadline, но устанавливает время жизни контекста на основе заданного таймаута.

func operation1(ctx context.Context) {
select {
case <-time.After(5 * time.Second):
fmt.Println("operation1 completed")
case <-ctx.Done():
fmt.Println("operation1 cancelled")
}
}

func main() {
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()

go operation1(ctx)

// Дожидаемся завершения или отмены операции
<-ctx.Done()
if err := ctx.Err(); err != nil {
fmt.Println("main:", err)
}
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
🤔 Какие виды индексов в PostgreSQL?

PostgreSQL поддерживает:
- B-Tree — по умолчанию, для равенства и диапазонов.
- Hash — для быстрого поиска по точному совпадению.
- GIN (Generalized Inverted Index) — для массивов, JSONB, полнотекстового поиска.
- GiST (Generalized Search Tree) — для гео-данных и поиска по диапазону.
- BRIN (Block Range Index) — для очень больших таблиц с логически отсортированными данными.
- Expression indexes — индексы по вычислениям, а не просто по полю.
- Partial indexes — индексы по части строк (например, только по активным записям).


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
🤔 Как устроен runtime в Go?

Go runtime — это встроенная среда выполнения, которая управляет памятью, потоками, сборкой мусора и планировщиком горутин. Он делает Go удобным для многопоточного и высоконагруженного программирования без необходимости вручную управлять потоками.

🚩Основные компоненты Go `runtime`

Горутины (goroutines) — лёгкие потоки, управляемые Go.
Планировщик (scheduler) — распределяет горутины по потокам ОС.
Модель памяти — управление стеком и кучей.
Сборщик мусора (GC) — автоматически очищает неиспользуемую память.
Syscalls — взаимодействие с ОС.

🚩Горутины и планировщик (scheduler)

Горутины легче, чем потоки ОС: Go может запускать миллионы горутин, а планировщик (M:N) распределяет их по потокам ОС.
Go использует M:N-модель, где:
- M — системные потоки (OS threads).
- N — горутины (goroutines).
- P — процессоры (logical processors) — управляют выполнением горутин.
P привязан к M, а G (горутины) распределяются между `P` динамически.
Это позволяет Go эффективно использовать CPU без ручного управления потоками.
Goroutine (G1, G2, G3, ...) 

Scheduler → P (Processor) → M (OS Thread) → CPU


🚩Управление памятью и стеком

Стек (stack) в Go динамический — он начинается с 2 KB и увеличивается при необходимости.
Если стек заполнен, Go автоматически расширяет его.
В отличие от C, Go не требует malloc/free, так как есть GC (garbage collector).

🚩Сборщик мусора (Garbage Collector)

Go использует автоматический сборщик мусора, который:
Работает параллельно с программой
Минимизирует паузы (low-latency GC)
Очищает неиспользуемые объекты из кучи
import "runtime"

runtime.GC() // Принудительный запуск сборщика мусора (обычно не нужно)


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4💊1
🤔 Зачем нужны линтеры (linters)?

Линтеры повышают качество кода, находя ошибки еще на этапе разработки. Это помогает избежать ошибок в продакшене.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
🤔 Как расшифровывается аббревиатура ACID?

ACID — это набор свойств транзакций в базах данных, обеспечивающий надежность и целостность данных.

🚩ACID

🟠A (Atomicity) — Атомарность
Транзакция выполняется либо полностью, либо не выполняется вовсе.
Пример: Если при переводе денег со счета A на счет B ошибка произошла на полпути, изменения откатываются.

🟠C (Consistency) — Согласованность
Данные остаются в правильном состоянии до и после транзакции.
Пример: Если сумма на всех счетах банка должна оставаться неизменной, транзакция не должна нарушить это правило.

🟠I (Isolation) — Изолированность
Одновременные транзакции не мешают друг другу.
Пример: Два клиента покупают один и тот же товар, но база данных правильно обрабатывает, кто купил первым.

🟠D (Durability) — Долговечность
После завершения транзакции изменения сохраняются, даже если система сломается.
Пример: Если заказ оформлен, он не исчезнет при внезапном отключении электричества.

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
🤔 Что такое захват переменной?

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


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
💊3👍2
🤔 Какие бывают способы оптимизации?

Оптимизация кода в Go может быть выполнена на нескольких уровнях:

🟠Оптимизация алгоритмов и структур данных
Использование более эффективных алгоритмов (например, O(log n) вместо O(n^2)). Выбор подходящих структур данных (например, map вместо срезов для поиска по ключу).

🟠Оптимизация работы с памятью
Снижение количества аллокаций (использование sync.Pool, предварительное выделение памяти). Использование []byte вместо string, если требуется частое изменение строки. Минимизация копирования данных, например, передача []byte по ссылке вместо копирования.

🟠Оптимизация работы с горутинами
Использование worker pool, чтобы избежать избыточного создания горутин. Ограничение количества параллельных задач (runtime.GOMAXPROCS). Использование каналов правильной ёмкости для минимизации блокировок.

🟠Оптимизация ввода-вывода (I/O)
Буферизация (bufio.Reader, bufio.Writer). Использование асинхронных операций при работе с файлами или сетью. Использование io.Pipe() для потоковой обработки данных.

🟠Использование профилирования и анализа производительности
pprof для анализа CPU, памяти и блокировок. race detector (-race флаг) для выявления проблем с конкурентным доступом. Инструменты трассировки (trace).

🚩Пример оптимизации работы с памятью

Пример неэффективного кода
func inefficient() []string {
var result []string
for i := 0; i < 1000; i++ {
result = append(result, fmt.Sprintf("Item %d", i)) // Частые аллокации
}
return result
}


Оптимизированный вариант
func efficient() []string {
result := make([]string, 0, 1000) // Выделяем память заранее
for i := 0; i < 1000; i++ {
result = append(result, fmt.Sprintf("Item %d", i))
}
return result
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
🤔 Как ООП в Go реализовано?

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

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
🤔 Как сделать свои методы для пакета?

В Go методы создаются для структур (или типов) внутри пакета. Это позволяет добавлять логику и поведение объектам.

🚩Создание собственного пакета

Допустим, мы создаем пакет mathutils, который будет содержать метод для структуры Calculator.
package mathutils

// Calculator - структура с данными
type Calculator struct {
A, B int
}

// Sum - метод для сложения чисел A и B
func (c Calculator) Sum() int {
return c.A + c.B
}


🚩Использование пакета в другом файле

Теперь мы можем использовать этот метод в основном файле программы.
package main

import (
"fmt"
"mypackage/mathutils" // Импортируем наш пакет
)

func main() {
calc := mathutils.Calculator{A: 5, B: 3}
fmt.Println("Sum:", calc.Sum()) // Выведет: Sum: 8
}


🚩Указатели vs. Значения в методах

Методы можно объявлять как для значений (func (c Calculator)) так и для указателей (func (c *Calculator)).
Когда использовать указатели?
Если метод изменяет данные структуры.
Чтобы избежать копирования больших структур.
func (c *Calculator) Multiply(factor int) {
c.A *= factor
c.B *= factor
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
🤔 Какие виды join бывают?

Основные типы соединений в SQL:
- INNER JOIN — только совпадающие записи.
- LEFT JOIN — все из левой таблицы, даже без пары.
- RIGHT JOIN — все из правой таблицы.
- FULL OUTER JOIN — всё из обеих таблиц, где возможно — объединяется.
- CROSS JOIN — декартово произведение.
- SELF JOIN — соединение таблицы с самой собой.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
🤔 Какие сущности есть в планировщике?

Планировщик задач (Scheduler) управляет выполнением процессов и горутин (в случае Go). В контексте операционных систем и языков программирования, таких как Golang, планировщик отвечает за распределение вычислительных ресурсов.

🟠G (Goroutine) – Горутинa
Это легковесный поток, который выполняет код. В отличие от ОС-потоков, она не требует большого количества памяти и управляется рантаймом Go.
Включает стек, контекст выполнения, а также статус (ждёт, выполняется, завершена).
Переключается между потоками ОС прозрачно для разработчика.
Можно создать десятки тысяч горутин без значительных затрат памяти.
go func() {
fmt.Println("Привет из горутины!")
}()


🟠M (Machine) – Операционный поток
M (Machine) представляет собой реальный поток ОС (kernel thread), на котором выполняются горутины.
Соответствует потокам ОС (pthread в Linux, Windows Thread в Windows).
Может одновременно выполнять только одну горутину.
Количество M зависит от GOMAXPROCS, но обычно Go создаёт столько потоков, сколько ядер в системе.
runtime.GOMAXPROCS(4) // Использовать 4 ядра процессора


🟠P (Processor) – Планировщик (Scheduler)
Это сущность, которая отвечает за распределение горутин (G) между потоками (M).
P управляет очередью горутин и раздаёт их потокам (M).
По умолчанию количество P равно количеству GOMAXPROCS.
Горутину нельзя выполнить без доступного P.
[Processor P1] ----> [Machine M1] ----> Выполняет горутины G1, G2
[Processor P2] ----> [Machine M2] ----> Выполняет горутины G3, G4


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
💊3
🤔 Как происходит поиск по ключу в map?

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

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1🔥1
🤔 Что такое триггер?

Триггер — это специальная процедура в СУБД, которая автоматически выполняется при определённом событии (например, INSERT, UPDATE, DELETE) в таблице.

🚩Как работают триггеры?

Когда выполняется определённое действие с таблицей, триггер срабатывает автоматически и выполняет заданную логику. Это полезно для:
- Автоматической проверки данных.
- Поддержания целостности информации.
- Логирования изменений.

🚩Пример триггера в PostgreSQL

Допустим, у нас есть таблица orders, и мы хотим автоматически сохранять историю изменений заказов в таблицу orders_log.
CREATE TABLE orders_log (
id SERIAL PRIMARY KEY,
order_id INT,
old_status TEXT,
new_status TEXT,
changed_at TIMESTAMP DEFAULT now()
);

CREATE OR REPLACE FUNCTION log_order_update()
RETURNS TRIGGER AS $$
BEGIN
INSERT INTO orders_log (order_id, old_status, new_status)
VALUES (OLD.id, OLD.status, NEW.status);
RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER order_status_change
AFTER UPDATE ON orders
FOR EACH ROW
WHEN (OLD.status IS DISTINCT FROM NEW.status)
EXECUTE FUNCTION log_order_update();


🚩Разновидности триггеров

🟠До выполнения операции (`BEFORE`)
Используется для проверки или модификации данных перед изменением.

🟠После выполнения операции (`AFTER`)
Чаще всего используется для логирования или дополнительных действий.

🟠INSTEAD OF (для представлений)
Позволяет заменить выполнение операции (INSERT, UPDATE, DELETE).

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
🤔 Что такое указатели?

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

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
🤔 Как закрыть канал?

В Go каналы (chan) можно закрывать с помощью close(channel), чтобы показать, что больше не будет отправляться данных.

Как закрыть канал?
ch := make(chan int)
close(ch) // Закрываем канал


Полный пример
package main

import "fmt"

func main() {
ch := make(chan int)

go func() {
for i := 1; i <= 3; i++ {
ch <- i // Отправляем данные
}
close(ch) // Закрываем канал
}()

for val := range ch { // Читаем пока канал не закроется
fmt.Println(val)
}

fmt.Println("Канал закрыт, чтение завершено")
}


Выход
1
2
3
Канал закрыт, чтение завершено


🚩Как проверить, закрыт ли канал?

Используем val, ok := <-ch:
- ok == true → канал открыт, есть данные.
- ok == false → канал закрыт.
package main

import "fmt"

func main() {
ch := make(chan int)
close(ch)

val, ok := <-ch
fmt.Println("val:", val, "ok:", ok) // val: 0 ok: false
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
🤔 Как встроить стандартный профайлер в своё приложение?

Интегрируйте профайлер с помощью пакета net/http/pprof, добавив HTTP-сервер в приложение. После запуска профайлер будет доступен через веб-интерфейс.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1🔥1
🤔 Как называется механизм сборки мусора?

В Go механизм сборки мусора называется Garbage Collector (GC).

🚩Как работает сборщик мусора в Go?

Go использует автоматический сборщик мусора с конкурентной, трицветной, инкрементальной стратегией.

🟠Конкурентный (Concurrent)
выполняется параллельно с работой программы.
🟠Трёхцветный (Tri-color)
объекты помечаются как белые, серые и чёрные.
🟠Инкрементальный (Incremental)
работает порциями, а не останавливает программу надолго.

🚩Алгоритм трёхцветной маркировки

🟠Белые объекты
мусор, который будет удалён.
🟠Серые объекты
те, которые находятся в обработке.
🟠Чёрные объекты
используемые объекты, которые не подлежат удалению.

🚩Оптимизация GC в Go

Чтобы уменьшить нагрузку на GC:
Используйте пул объектов (sync.Pool).
Минимизируйте аллокации в куче (например, используйте []byte вместо string, если можно).
Ограничивайте долгоживущие объекты, так как они реже сканируются.

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
🤔 Что будет происходить при конкурентной записи в map?

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

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
🤔 Что такое HAVING?

HAVING — это оператор в SQL, который фильтрует группированные (GROUP BY) данные по агрегатным функциям (SUM, COUNT, AVG, MAX, MIN).

🚩Чем отличается `HAVING` от `WHERE`?

WHERE фильтрует отдельные строки до группировки.
HAVING фильтрует группы строк после GROUP BY.

Теперь посчитаем сумму продаж по категориям и оставим только те, где сумма > 250
SELECT category, SUM(amount) AS total_sales
FROM sales
GROUP BY category
HAVING SUM(amount) > 250;


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
🤔 Что из себя представляет тип данных string в языке Go?

Тип string в Go — это последовательность байтов, закодированных в UTF-8.
Он реализован как структура:
- указатель на массив байтов;
- длина строки.
Строки неизменяемы. Любая операция, которая кажется «изменением», на самом деле создаёт новую строку.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Please open Telegram to view this post
VIEW IN TELEGRAM