Каналы — это мощные инструменты для обмена данными между горутинами, обеспечивающие синхронизацию и безопасную коммуникацию. Основное различие между буферизированными и небуферизированными каналами заключается в их поведении при отправке и получении данных.
Не имеют внутренней емкости, т.е. они не могут хранить значения. Эти каналы требуют, чтобы отправитель и получатель были готовы обмениваться данными одновременно. Если одна сторона не готова, другая будет заблокирована:
Отправка данных в него блокирует отправителя до тех пор, пока получатель не прочитает данные из канала.
Получение данных из него блокирует получателя до тех пор, пока другая горутина не отправит данные в канал.
ch := make(chan int) // Создание небуферизированного канала
go func() {
val := <-ch // Блокируется, ожидая данные
fmt.Println("Received:", val)
}()
ch <- 3 // Блокируется, пока данные не будут получены
Имеют внутреннюю емкость, что позволяет хранить одно или несколько элементов без непосредственного получателя данных. Отправка или получение данных работает следующим образом:
Отправка блокируется, только если буфер заполнен. До этого момента данные могут быть отправлены без блокировки, даже если получатель не готов их принять.
Получение из буферизированного канала блокируется, только если канал пуст. Если в канале есть данные, получение происходит без блокировки.
ch := make(chan int, 2) // Создание буферизированного канала с емкостью 2
ch <- 1 // Отправка данных без блокировки
ch <- 2 // Отправка данных без блокировки
go func() {
val := <-ch // Получение данных без блокировки
fmt.Println("Received:", val)
}()
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Да, JOIN можно использовать со вложенными (subquery) запросами. Варианты:
- JOIN с подзапросом, возвращающим таблицу (SELECT ... FROM (SELECT ...) AS subquery JOIN ...).
- JOIN с подзапросом в ON (SELECT ... FROM table1 JOIN (SELECT ...) AS subquery ON ...).
- Использование подзапроса в WHERE или IN, но это менее эффективно, чем JOIN.
Вложенные запросы могут снижать производительность, поэтому лучше использовать индексы и анализировать EXPLAIN.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Это функции, которые принимают набор значений и возвращают одно агрегированное значение. В языке Go нет встроенных агрегатных функций, как в SQL, но их можно реализовать самостоятельно.
суммирует все элементы.
вычисляет среднее значение.
находит минимальный элемент.
находит максимальный элемент.
считает количество элементов.
Функция суммы (
SUM
) func Sum(nums []int) int {
sum := 0
for _, num := range nums {
sum += num
}
return sum
}
Функция среднего (
AVG
) func Average(nums []int) float64 {
if len(nums) == 0 {
return 0
}
return float64(Sum(nums)) / float64(len(nums))
}
Функция минимума (
MIN
) func Min(nums []int) int {
if len(nums) == 0 {
panic("empty slice")
}
min := nums[0]
for _, num := range nums {
if num < min {
min = num
}
}
return min
}
Функция максимума (
MAX
) func Max(nums []int) int {
if len(nums) == 0 {
panic("empty slice")
}
max := nums[0]
for _, num := range nums {
if num > max {
max = num
}
}
return max
}
Функция подсчёта (
COUNT
) func Count(nums []int) int {
return len(nums)
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Компилятору не нужно сообщать это явно – соответствие интерфейсу проверяется автоматически. Однако для явной декларации можно использовать конструкцию вида var _ InterfaceName = (*StructName)(nil).
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Это целочисленные значения, которые используются для доступа к элементам упорядоченных структур данных. В контексте Go индексы чаще всего применяются для работы со строками, массивами, срезами, а также картами (косвенно, через ключи).
Индексы позволяют обращаться к конкретным элементам массива, строки или среза. Например, если у нас есть массив чисел, индекс указывает, какой именно элемент извлечь.
С помощью индексов можно перебирать элементы массива, строки или среза, например, используя циклы.
В изменяемых структурах данных, таких как срезы или массивы, индекс позволяет присвоить новое значение конкретному элементу.
Индексы упрощают и ускоряют доступ к данным, потому что доступ осуществляется за O(1) (константное время) в массивах или срезах.
В строках индексы используются для доступа к конкретным байтам.
package main
import "fmt"
func main() {
str := "Привет"
fmt.Println(str[0]) // 208 (байт, не символ!)
fmt.Printf("%c\n", str[0]) // П (символ, представленный первым байтом UTF-8)
}
В массивах и срезах индексы используются для извлечения и изменения значений
package main
import "fmt"
func main() {
arr := [5]int{10, 20, 30, 40, 50}
fmt.Println(arr[2]) // 30
// Изменение значения по индексу
arr[2] = 100
fmt.Println(arr) // [10 20 100 40 50]
}
Обычно индексы используются для итерации по элементам коллекции с помощью цикла
for
.package main
import "fmt"
func main() {
nums := []int{10, 20, 30, 40, 50}
for i, v := range nums {
fmt.Printf("Индекс: %d, Значение: %d\n", i, v)
}
}
Индексы полезны для извлечения подстрок с использованием срезов:
package main
import "fmt"
func main() {
str := "Привет, Мир!"
fmt.Println(str[8:12]) // Мир
}
Если попытаться обратиться к элементу по индексу, который выходит за пределы коллекции, Go выдаст runtime panic:
package main
func main() {
nums := []int{1, 2, 3}
fmt.Println(nums[5]) // panic: runtime error: index out of range
}
Если неверно учитывать байтовое представление символов UTF-8, можно получить некорректный результат.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
1. Primary Index – создается автоматически на первичном ключе таблицы.
2. Unique Index – предотвращает дублирование значений в колонке.
3. Composite Index (составной индекс) – индекс на несколько столбцов.
4. Full-Text Index – используется для быстрого поиска по тексту.
5. Spatial Index – индекс для геоданных (только MyISAM).
6. Clustered Index – хранит строки в отсортированном порядке (InnoDB).
7. Non-Clustered Index – указывает на строки без изменения порядка хранения.
8. Hash Index – используется в MEMORY таблицах, обеспечивает быстрый доступ к данным.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Prometheus – это мощная система мониторинга с временными рядами (time series), которая собирает метрики из сервисов, хранит их и позволяет строить графики и отправлять алерты.
Pull-модель – сам запрашивает метрики у сервисов (в отличие от push-модели, как в StatsD).
Формат временных рядов – каждая метрика привязана ко времени и меткам (
labels
). Язык запросов PromQL – позволяет анализировать и агрегировать метрики.
Автодетектирование сервисов – поддержка Kubernetes, Docker, Consul.
Хранение данных в базе TSDB (Time Series Database).
Гибкая система алертов – интеграция с Alertmanager (уведомления в Slack, Telegram и др.).
Экспортеры/сервисы предоставляют метрики через HTTP-эндпоинт (
/metrics
). Prometheus сам запрашивает данные по расписанию.
Метрики хранятся в базе TSDB.
Можно строить графики в Grafana или запрашивать данные через API.
Алерты отправляются в Alertmanager при достижении пороговых значений.
Go-сервис может отдавать метрики через HTTP с помощью prometheus/client_golang
package main
import (
"net/http"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
)
// Создаём метрику
var httpRequests = prometheus.NewCounter(
prometheus.CounterOpts{
Name: "http_requests_total",
Help: "Total number of HTTP requests",
})
func main() {
// Регистрируем метрику
prometheus.MustRegister(httpRequests)
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
httpRequests.Inc() // Увеличиваем счётчик при каждом запросе
w.Write([]byte("Hello, Prometheus!"))
})
// Эндпоинт для сбора метрик
http.Handle("/metrics", promhttp.Handler())
http.ListenAndServe(":8080", nil)
}
Пример запроса в PromQL
http_requests_total
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Если у метода ресивер с *, это означает, что метод работает с указателем на объект, а значит:
- изменения внутри метода повлияют на оригинальный объект;
- метод может модифицировать поля структуры;
- вызов возможен как на указателе, так и на значении (Go сам "разыменует").
Такой метод можно вызывать и на value, и на pointer — Go сделает автоматическую конвертацию.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Builder – это порождающий паттерн, который используется для пошагового создания сложных объектов. Он удобен, когда объект имеет много параметров и различных конфигураций.
если у объекта много параметров (особенно опциональных).
вместо длинного конструктора с кучей аргументов можно вызывать методы-построители.
Builder позволяет создать объект инициализированным сразу, без изменения его полей после создания.
В Go нет классов, но можно использовать структуры и методы для реализации этого паттерна.
package main
import "fmt"
// Определяем структуру Car
type Car struct {
Brand string
Model string
Color string
Engine string
}
// Определяем "Строителя" для Car
type CarBuilder struct {
car Car
}
// Методы для пошаговой настройки машины
func (cb *CarBuilder) SetBrand(brand string) *CarBuilder {
cb.car.Brand = brand
return cb
}
func (cb *CarBuilder) SetModel(model string) *CarBuilder {
cb.car.Model = model
return cb
}
func (cb *CarBuilder) SetColor(color string) *CarBuilder {
cb.car.Color = color
return cb
}
func (cb *CarBuilder) SetEngine(engine string) *CarBuilder {
cb.car.Engine = engine
return cb
}
// Метод для финальной сборки объекта
func (cb *CarBuilder) Build() Car {
return cb.car
}
// Используем Builder
func main() {
car := CarBuilder{}.
SetBrand("Tesla").
SetModel("Model S").
SetColor("Red").
SetEngine("Electric").
Build()
fmt.Printf("Car: %+v\n", car)
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
456+ реальных собеседований на программиста, тестировщика, аналитика и прочие IT профы.
Есть собесы от ведущих компаний: Сбер, Яндекс, ВТБ, Тинькофф, Озон, Wildberries и т.д.
🎯 Переходи по ссылке и присоединяйся к базе, чтобы прокачать свои шансы на успешное трудоустройство!
Please open Telegram to view this post
VIEW IN TELEGRAM
- Если переменная используется только внутри функции, она остаётся на стеке.
- Если ссылка на переменную передаётся за пределы функции (например, через замыкание), переменная переносится в кучу (heap).
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Grafana — это инструмент для визуализации и мониторинга данных. Он позволяет строить дашборды (панели) с графиками, метриками и алертами, получая данные из различных источников (Prometheus, InfluxDB, Loki, MySQL и других).
создание графиков, таблиц, гистограмм и других визуальных представлений.
отслеживание метрик серверов, баз данных, контейнеров и микросервисов.
поддерживает Prometheus, Elasticsearch, MySQL, PostgreSQL и десятки других.
оповещения (email, Slack, Telegram) при достижении критических значений.
удобный интерфейс для анализа производительности систем.
Можно отслеживать загрузку CPU, RAM, количество запросов в базе, ошибки и задержки API.
Позволяет наблюдать за работой Kubernetes, Docker, CI/CD-пайплайнов и микросервисов.
Может использоваться для отображения KPI, продаж, конверсий и других данных.
Если сервер падает или нагрузка превышает порог – Grafana уведомит команду.
Устанавливаем Prometheus и Grafana
Добавляем Prometheus как источник данных в Grafana
Создаём дашборд с метриками, например
Количество HTTP-запросов
Время ответа сервера
Количество активных соединений
http_requests_total{job="web_service"}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Удаление индекса осуществляется через изменение структуры таблицы. Нужно знать точное имя индекса. Индексы, созданные явно, удаляются отдельно, а системные (например, первичный ключ) — специальной командой. Это может потребоваться при оптимизации или изменении структуры таблицы.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM