Допустим, у вас есть структура со счётчиками, которые обновляют разные горутины:
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
👍4
Оцените их по шкале 🔥,❤️,👍,😢, 🥱,
где 🔥 — это супер, а 🥱 — это скучно.
Также приветствуется фидбек в комментах.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤9👍9🔥8😢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
Фаззинг-тест начинается с
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("john@example.com", 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
👍8
Каждый .go файл стартует с декларации
package название — это определяет, к какой логической группе относится код.Пакет с именем
main компилируется в main — это библиотеки для Никаких магических автоимпортов — каждую зависимость
import "github.com/user/repo/pkg". Go-компилятор сразу видит все связи между модулями.Простое, но мощное правило:
PublicFunc() — заглавная буква, privateFunc() — строчная буква, видна Это работает для всего: функций, типов, структур, переменных. Никаких ключевых слов public/private — компилятор смотрит только на первую букву.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
Стандартная функция
time.Sleep() в Go имеет существенный недостаток — она блокирует выполнение и Вместо прямого использования
time.Sleep() можно комбинировать select с time.After() и каналом контекста:select {
case <-time.After(duration):
// Пауза завершилась естественным образом
case <-ctx.Done():
// Контекст отменён — немедленно выходим
return ctx.Err()
}Такой подход позволяет горутине мгновенно реагировать на отмену контекста.
🎁 Новогодняя акция: 3 курса по цене 1
🤝 Помощь с выбором курса
Please open Telegram to view this post
VIEW IN TELEGRAM
❤8😁1
«Этот манёвр будет стоить нам 51 год...»
На собеседованиях по
В Proglib Academy поднимаются цены. У вас есть шанс зайти на обучение по старой стоимости:
— Разработка ИИ-агентов
— Математика для разработки AI-моделей
— ML для старта в Data Science
— Математика для Data Science
— Специалист по ИИ
— Алгоритмы и структуры данных
— Программирование на Python
— Основы IT для непрограммистов
— Архитектуры и шаблоны проектирования
Забрать базу для собеседований
⚠️ Цены вырастут уже 19 января
На собеседованиях по
Go всё чаще спрашивают не только про горутины и каналы, но и про фундаментальные алгоритмы и архитектуру высоконагруженных систем. Не ждите, пока пробелы в знаниях станут критическими.В Proglib Academy поднимаются цены. У вас есть шанс зайти на обучение по старой стоимости:
— Разработка ИИ-агентов
— Математика для разработки AI-моделей
— ML для старта в Data Science
— Математика для Data Science
— Специалист по ИИ
— Алгоритмы и структуры данных
— Программирование на Python
— Основы IT для непрограммистов
— Архитектуры и шаблоны проектирования
Забрать базу для собеседований
⚠️ Цены вырастут уже 19 января
Планировщик Go реализует модель M:N, где M
В его основе лежат три ключевые сущности:
G (
M (
P (
Горутины хранятся в
🎁 Новогодняя акция: 3 курса по цене 1
🤝 Помощь с выбором курса
Please open Telegram to view this post
VIEW IN TELEGRAM
🤩1
Оцените их по шкале 🔥,❤️,👍,😢, 🥱,
где 🔥 — это супер, а 🥱 — это скучно.
Также приветствуется фидбек в комментах.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤7👍5😢3🥱2🔥1
Строки в Go
Для построения строк используйте
Пример с strings.Builder:
var builder strings.Builder
for i := 0; i < 1000; i++ {
builder.WriteString("x")
}
result := builder.String()
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11❤🔥4
Deadlock возникает, когда все горутины
Типичные причины дедлоков: отправка в небуферизованный канал без
Примеры:
// Пример 1: отправка без получателя
ch := make(chan int)
ch <- 1 // deadlock - никто не читает
// Пример 2: чтение без отправителя
ch := make(chan int)
<-ch // deadlock - никто не пишет
// Пример 3: взаимная блокировка
var mu1, mu2 sync.Mutex
go func() {
mu1.Lock()
mu2.Lock() // ждет mu2
}()
mu2.Lock()
mu1.Lock() // ждет mu1
Используйте
select с default или Please open Telegram to view this post
VIEW IN TELEGRAM
ЭТОТ ПОСТ СПАСЕТ ТВОЙ 👩💻 -СОБЕС
В наше время очень тяжело попасть на собеседование! Поэтому предлагаем вам очень серьезно относиться к ним.
Не упускайте не единое собеседование, готовьтесь к каждому, как к последнему.
Регулярно проверяйте свои hard-skills.
Забирай чек-лист из закрепленного сообщения - 55 вопросов из реальных собесов!
P.S. помимо непосредственно GO, разбираем другие необходимые технологии, про них нельзя забывать!
Помни, что каждое собеседование в 2026 на вес золота!
В наше время очень тяжело попасть на собеседование! Поэтому предлагаем вам очень серьезно относиться к ним.
Не упускайте не единое собеседование, готовьтесь к каждому, как к последнему.
Регулярно проверяйте свои hard-skills.
Забирай чек-лист из закрепленного сообщения - 55 вопросов из реальных собесов!
P.S. помимо непосредственно GO, разбираем другие необходимые технологии, про них нельзя забывать!
Помни, что каждое собеседование в 2026 на вес золота!
Please open Telegram to view this post
VIEW IN TELEGRAM
😁1🌚1
append возвращает слайс, потому что операция добавления элементов может привести к capacity недостаточна.Поэтому если бы append
Даже если реаллокация не произошла и базовый массив остался тем же, возвращаемый слайс
Please open Telegram to view this post
VIEW IN TELEGRAM