По стабильности:
•
•
•
•
По масштабу изменений:
• Major —
• Minor — новая функциональность с
• Patch —
По способу деплоя:
• Canary — выкатка на небольшой процент пользователей
• Blue-green — две идентичные среды, переключение
• Rolling release — постепенное обновление без
🎁 Новогодняя акция: 3 курса по цене 1
🤝 Помощь с выбором курса
Please open Telegram to view this post
VIEW IN TELEGRAM
❤3🔥3
Оцените их по шкале 🔥,❤️,👍,😢, 🥱,
где 🔥 — это супер, а 🥱 — это скучно.
Также приветствуется фидбек в комментах.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥7👍5🥱1
Допустим, у вас есть структура со счётчиками, которые обновляют разные горутины:
type Counters struct {
a int64
b int64
c int64
}Каждая горутина работает со своим полем. Конфликтов нет,
Проблема в том, как устроен кеш процессора. CPU не читает
Когда горутина на одном ядре изменяет поле a, процессор инвалидирует эту
Это и есть Cache Contention, или false sharing — ядра
🎁 Новогодняя акция: 3 курса по цене 1
🤝 Помощь с выбором курса
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7
Отмена в Go всегда течёт
Обратного эффекта нет: отмена
🎁 Новогодняя акция: 3 курса по цене 1
🤝 Помощь с выбором курса
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
Использовать пакет
strconv:// Строка → int
num, err := strconv.Atoi("42")
// int → строка
str := strconv.Itoa(42)
// Для других типов:
i64, _ := strconv.ParseInt("42", 10, 64) // string → int64
str64 := strconv.FormatInt(42, 10) // int64 → string
Atoi возвращает
err🎁 Новогодняя акция: 3 курса по цене 1
🤝 Помощь с выбором курса
Please open Telegram to view this post
VIEW IN TELEGRAM
🤩3
В Go есть пакет
net/http/pprof, который при импорте import (
"net/http"
_ "net/http/pprof" // подчёркивание означает импорт ради side-effect
)
func main() {
// Запускаем профайлер в отдельной горутине на порту 6060
go func() {
http.ListenAndServe(":6060", nil)
}()
// Здесь основная логика приложения...
}
После запуска становятся доступны эндпоинты для анализа:
•
/debug/pprof/profile — нагрузка на процессор•
/debug/pprof/heap — использование памяти•
/debug/pprof/goroutine — состояние горутин•
/debug/pprof/block — блокировки🎁 Новогодняя акция: 3 курса по цене 1
🤝 Помощь с выбором курса
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥7
Функция
len() возвращает размер в Кириллица кодируется в UTF-8
utf8.RuneCountInString().🎁 Новогодняя акция: 3 курса по цене 1
🤝 Помощь с выбором курса
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4🤩1
Заголовок слайса занимает
Внутренняя структура слайса выглядит так:
type slice struct {
array unsafe.Pointer // 8 байт — указатель на underlying array
len int // 8 байт — текущая длина
cap int // 8 байт — ёмкость
}24 байта — это только заголовок. Сами данные хранятся
array.Пример расчёта общего размера:
s := make([]int64, 100)
// Заголовок: 24 байта
// Данные: 100 * 8 = 800 байт
// Итого: 824 байта
При передаче слайса в функцию копируется
🎁 Новогодняя акция: 3 курса по цене 1
🤝 Помощь с выбором курса
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
В Go есть правило: канал закрывает только
Паника при записи в закрытый канал — это не баг, а защита от гонок данных. Отправитель точно знает, когда
Но технически читатель закрыть канал может.
🎁 Новогодняя акция: 3 курса по цене 1
🤝 Помощь с выбором курса
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
Оцените их по шкале 🔥,❤️,👍,😢, 🥱,
где 🔥 — это супер, а 🥱 — это скучно.
Также приветствуется фидбек в комментах.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9❤8🔥6😢2
В таком случае, обычно используется дополнительный канал, называемый каналом управления или сигнальным каналом, который получатель может использовать для отправки сигнала об остановке.
После получения сигнала, отправитель может корректно закрыть основной канал данных:
func main() {
dataCh := make(chan int)
stopCh := make(chan struct{})
go func() {
for {
select {
case data, ok := <-dataCh:
if !ok {
// Канал закрыт, прекращаем обработку
return
}
// Обработка данных
fmt.Println(data)
case <-stopCh:
// Получен сигнал остановки, закрываем канал dataCh
close(dataCh)
return
}
}
}()
// Отправка данных в канал
dataCh <- 1
dataCh <- 2
// Отправка сигнала остановки
stopCh <- struct{}{}
}🎁 Новогодняя акция: 3 курса по цене 1
🤝 Помощь с выбором курса
Please open Telegram to view this post
VIEW IN TELEGRAM
😁4❤3🤔1
This media is not supported in your browser
VIEW IN TELEGRAM
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, www.otus.ru
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1
Фаззинг-тест начинается с
func Fuzz и принимает *testing.F:func FuzzParse(f *testing.F) {
// Seed-корпус
f.Add("valid input")
f.Add("edge case")
// Фаззинг-функция
f.Fuzz(func(t *testing.T, input string) {
result, err := Parse(input)
if err != nil {
return // Ошибка — нормально
}
// Проверки инвариантов
if result == nil {
t.Error("результат не должен быть nil при отсутствии ошибки")
}
})
}Часто тестируемая функция принимает сложные типы, а фаззер работает только с базовыми:
string, []byte, int, bool и несколькими другими. Обёртка конвертирует примитивы в нужные структуры: func FuzzUserValidation(f *testing.F) {
f.Add("[email protected]", 25, true)
f.Fuzz(func(t *testing.T, email string, age int, active bool) {
// Обёртка: преобразуем примитивы в структуру
user := User{
Email: email,
Age: age,
Active: active,
}
err := ValidateUser(user)
// Проверяем инварианты
if age < 0 && err == nil {
t.Error("отрицательный возраст должен вызывать ошибку")
}
})
}🎁 Новогодняя акция: 3 курса по цене 1
🤝 Помощь с выбором курса
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Флаг
CGO_ENABLED=0 вырубает CGo на При
CGO_ENABLED=1 компилятору нужны CGO_ENABLED=0 просто делаете GOOS=linux GOARCH=arm64 go build — и готово, бинарник для Можно использовать минималистичные образы типа scratch или distroless — приложение запустится
Убирая C-код, вы автоматически избавляетесь от целого класса
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4