📖 ReadFile — просто снаружи, умно внутри
На поверхности всё выглядит просто:
Одна строка — и у вас содержимое файла в []byte.
Но под капотом происходит цепочка системных вызовов, продуманная для безопасности, эффективности и удобства.
Что делает
Функция определена в пакете os. На самом деле это обёртка вокруг io и os/file_unix.go.
Если упростить, она выглядит примерно так:
1. Открывает файл через
— под капотом вызывает системный вызов
— возвращает объект
2. Читает всё содержимое с помощью
— в цикле вызывает
— буфер автоматически растёт по мере чтения.
— выделение памяти экспоненциальное, чтобы избежать частого копирования.
3. Закрывает файл через
4. Возвращает []byte и nil или ошибку
Что важно понимать
• ReadFile не стримит данные, а собирает их в один буфер. Это просто и безопасно, но опасно для больших файлов.
•
Это увеличивает нагрузку на GC при очень больших объёмах.
• ReadFile сама по себе не конкурентна, но безопасна при обычном вызове.
Если несколько горутин читают один и тот же файл, каждая должна вызывать ReadFile() независимо — внутри создаётся свой
🐸 Библиотека Go-разработчика
#GoDeep
На поверхности всё выглядит просто:
data, err := os.ReadFile("data.json")Одна строка — и у вас содержимое файла в []byte.
Но под капотом происходит цепочка системных вызовов, продуманная для безопасности, эффективности и удобства.
Что делает
os.ReadFile() шаг за шагомФункция определена в пакете os. На самом деле это обёртка вокруг io и os/file_unix.go.
Если упростить, она выглядит примерно так:
func ReadFile(name string) ([]byte, error) {
f, err := os.Open(name)
if err != nil {
return nil, err
}
defer f.Close()
return io.ReadAll(f)
}1. Открывает файл через
os.Open()— под капотом вызывает системный вызов
open() (или CreateFile() на Windows).— возвращает объект
*os.File, который реализует интерфейс io.Reader.2. Читает всё содержимое с помощью
io.ReadAll()— в цикле вызывает
Read() у файла, пока не получит io.EOF.— буфер автоматически растёт по мере чтения.
— выделение памяти экспоненциальное, чтобы избежать частого копирования.
3. Закрывает файл через
defer f.Close()4. Возвращает []byte и nil или ошибку
Что важно понимать
• ReadFile не стримит данные, а собирает их в один буфер. Это просто и безопасно, но опасно для больших файлов.
•
io.ReadAll() динамически расширяет срез по мере поступления данных. Он не знает длину файла заранее, хотя мог бы узнать через Stat(), поэтому применяет адаптивный рост: 512 → 1k → 2k → 4k → …Это увеличивает нагрузку на GC при очень больших объёмах.
• ReadFile сама по себе не конкурентна, но безопасна при обычном вызове.
Если несколько горутин читают один и тот же файл, каждая должна вызывать ReadFile() независимо — внутри создаётся свой
os.File и своя копия данных.#GoDeep
Please open Telegram to view this post
VIEW IN TELEGRAM
❤10👍8
✏️ Задача дня: Partition Labels
Дана строка из маленьких латинских букв. Требуется разбить её на максимальное число частей так, чтобы каждая буква встречалась только в одной части. Вернуть длины частей по порядку.
Как решить:
1. Фиксируем последнее появление каждой буквы
Проходим по строке и для каждой буквы запоминаем последний встреченный индекс в map:
2. Формируем части строки
Начинаем слева: left — старт текущей части, right — крайний индекс, который должен быть включён.
Для текущей позиции берем руну и смотрим на её последнее вхождение с помощью map. Если оно дальше right, расширяем правую границу:
Увеличиваем счетчик длины части. Если текущая позиция left == right, значит мы собрали часть, где все буквы ограничены этим диапазоном — больше ни одна буква не убежит в следующий кусок.
Сохраняем длину части, обнуляем счётчик, переходим к сборке следующей части.
Код:
🐸 Библиотека Go-разработчика
#ReadySetGo
Дана строка из маленьких латинских букв. Требуется разбить её на максимальное число частей так, чтобы каждая буква встречалась только в одной части. Вернуть длины частей по порядку.
Как решить:
1. Фиксируем последнее появление каждой буквы
Проходим по строке и для каждой буквы запоминаем последний встреченный индекс в map:
for i, r := range s {
last[r] = i
}2. Формируем части строки
Начинаем слева: left — старт текущей части, right — крайний индекс, который должен быть включён.
Для текущей позиции берем руну и смотрим на её последнее вхождение с помощью map. Если оно дальше right, расширяем правую границу:
if last[r] > right {
right = last[r]
}Увеличиваем счетчик длины части. Если текущая позиция left == right, значит мы собрали часть, где все буквы ограничены этим диапазоном — больше ни одна буква не убежит в следующий кусок.
Сохраняем длину части, обнуляем счётчик, переходим к сборке следующей части.
Код:
func partitionLabels(s string) []int {
// Первый проход: фиксируем последний индекс для каждой буквы
last := make(map[rune]int)
for i, r := range s {
last[r] = i
}
// Второй проход: формируем части
var res []int
left, right := 0, 0
for i, r := range s {
if last[r] > right {
right = last[r]
}
if i == right {
res = append(res, right-left+1)
left = i + 1
}
}
return res
}#ReadySetGo
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10🥱2❤1
💥 Весь октябрь -40% на курсы для разработчиков в proglib.academy
Бери знания под свой стек:
Python | алгоритмы | математика для Data Science | архитектура кода.
⚡️ Пока скидка действует, апдейтни свои навыки
Бери знания под свой стек:
Python | алгоритмы | математика для Data Science | архитектура кода.
Пока одни ждут «идеальный момент», другие просто учатся.
А потом берут ваши офферы.
⚡️ Пока скидка действует, апдейтни свои навыки
🥱1
🧩 Go 1.25.2 и 1.24.8 — свежие патчи уже тут
Команда Go выкатила минорные апдейты — 1.25.2 и 1.24.8. Без громких фич, зато с важными фиксам и улучшениями стабильности.
Исправления
• net/textproto — чрезмерная нагрузка на CPU
• crypto/x509 — медленная проверка name constraints
• net/url — некорректная проверка IPv6-адресов в скобках
• archive/tar — неограниченное выделение памяти при парсинге GNU sparse map
• encoding/pem — высокая сложность при обработке невалидных данных
• net/http — отсутствие лимита при парсинге cookies → риск OOM
• encoding/asn1 — избыточное выделение памяти при парсинге DER
• crypto/x509 — panic при DSA-сертификатах
• net/mail — перегрузка CPU в ParseAddress
🐸 Библиотека Go-разработчика
#GoLive
Команда Go выкатила минорные апдейты — 1.25.2 и 1.24.8. Без громких фич, зато с важными фиксам и улучшениями стабильности.
Исправления
• net/textproto — чрезмерная нагрузка на CPU
• crypto/x509 — медленная проверка name constraints
• net/url — некорректная проверка IPv6-адресов в скобках
• archive/tar — неограниченное выделение памяти при парсинге GNU sparse map
• encoding/pem — высокая сложность при обработке невалидных данных
• net/http — отсутствие лимита при парсинге cookies → риск OOM
• encoding/asn1 — избыточное выделение памяти при парсинге DER
• crypto/x509 — panic при DSA-сертификатах
• net/mail — перегрузка CPU в ParseAddress
#GoLive
Please open Telegram to view this post
VIEW IN TELEGRAM
👍14❤3
На реддите обсуждают интересный вопрос:
Есть ли ещё open-source IDE, где нет встроенного искусственного интеллекта?
Автор жалуется, что почти каждая современная среда разработки теперь старается «встроить помощника» — автодополнение на базе LLM, AI-чат в сайдбаре, умные подсказки, сбор кода для тренировки моделей и т.д.
Даже если функция выключена — она всё равно где-то рядом.
💬 Вы пользуетесь ИИ фишками в IDE? Или у вас припасён список пока ещё чистых инструментов? Делитесь в комментах 👇
#GoTalk
Please open Telegram to view this post
VIEW IN TELEGRAM
😁8❤2
Please open Telegram to view this post
VIEW IN TELEGRAM
😁43👾1
🧮 Безопасный конкурентный счётчик в Go
В многопоточном мире обычный int быстро превращается в проблему. Несколько горутин одновременно читают и увеличивают счётчик — и вуаля, у нас гонки данных, неправильные значения и баги.
Чтобы этого избежать нужно использовать атомарный инкремент:
Сравнение sync/atomic и sync.Mutex
• sync/atomic: предоставляет атомарные операции для базовых типов данных, обеспечивая высокую производительность при минимальных накладных расходах.
• sync.Mutex: предоставляет механизмы блокировки, подходящие для более сложных структур данных, но с большим оверхедом из-за блокировок.
Немного кода — и вы избегаете гонок данных, багов и сюрпризов в многопоточной среде.
🐸 Библиотека Go-разработчика
#GoToProduction
В многопоточном мире обычный int быстро превращается в проблему. Несколько горутин одновременно читают и увеличивают счётчик — и вуаля, у нас гонки данных, неправильные значения и баги.
Чтобы этого избежать нужно использовать атомарный инкремент:
package main
import (
"fmt"
"sync"
"sync/atomic"
)
func main() {
var count int64 = 0
var wg sync.WaitGroup
numGoroutines := 10
incrementsPerGoroutine := 1000
for i := 0; i < numGoroutines; i++ {
wg.Add(1)
go func(id int) {
defer wg.Done()
for j := 0; j < incrementsPerGoroutine; j++ {
newValue := atomic.AddInt64(&count, 1)
// Каждая 500-я инкрементация выводится
if newValue%500 == 0 {
fmt.Printf("Горутина %d достигла счётчика %d\n", id, newValue)
}
}
}(i)
}
wg.Wait()
fmt.Println("Финальный счётчик:", count)
}
Сравнение sync/atomic и sync.Mutex
• sync/atomic: предоставляет атомарные операции для базовых типов данных, обеспечивая высокую производительность при минимальных накладных расходах.
• sync.Mutex: предоставляет механизмы блокировки, подходящие для более сложных структур данных, но с большим оверхедом из-за блокировок.
Немного кода — и вы избегаете гонок данных, багов и сюрпризов в многопоточной среде.
#GoToProduction
Please open Telegram to view this post
VIEW IN TELEGRAM
👍16🥱8❤3🔥3🌚1
🧠 Garbage Collection и управление памятью простыми словами
Как языки программирования убирают за собой? В видео разбирается, как работает garbage collector в Go. Почему важно понимать, что происходит с памятью, даже если вы не пишете на C, и как это знание помогает создавать стабильные и эффективные приложения.
➡️ Смотреть видео
🐸 Библиотека Go-разработчика
#GoDeep
Как языки программирования убирают за собой? В видео разбирается, как работает garbage collector в Go. Почему важно понимать, что происходит с памятью, даже если вы не пишете на C, и как это знание помогает создавать стабильные и эффективные приложения.
#GoDeep
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7🔥1
🧠 Go-антипаттерн: теневые переменные
Иногда код компилируется, но работает не так, как вы думаете.
В Go можно затенить переменную — то есть создать новую с тем же именем внутри блока. В результате вы присваиваете значение не туда, куда ожидали. Ошибка не синтаксическая, а логическая — значит, компилятор молчит, а вы отлаживаете полдня.
Пример:
Иногда := удобен, но будьте внимательны, где вы его используете. Лучше чуть больше кода, чем лишний час отладки.
🐸 Библиотека Go-разработчика
#GoToProduction
Иногда код компилируется, но работает не так, как вы думаете.
В Go можно затенить переменную — то есть создать новую с тем же именем внутри блока. В результате вы присваиваете значение не туда, куда ожидали. Ошибка не синтаксическая, а логическая — значит, компилятор молчит, а вы отлаживаете полдня.
Пример:
var client *http.Client
if tracing {
client, err := createClientWithTracing() // здесь client — новая переменная
if err != nil {
return err
}
log.Println(client)
} else {
client, err := createDefaultClient() // и здесь тоже новая
if err != nil {
return err
}
log.Println(client)
}
Иногда := удобен, но будьте внимательны, где вы его используете. Лучше чуть больше кода, чем лишний час отладки.
#GoToProduction
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9❤3
💼 Верность компании vs уважение к себе
Каждый разработчик хоть раз ловил это ощущение: вроде всё нормально, но что-то не твоё. Команда не заходит, менеджер микроменеджит, стек унылый, и ты уже смотришь вакансии на HH.
Так всё-таки, сколько нужно отработать, чтобы спокойно уйти — без чувства вины и разговоров за спиной?
— Минимум год, чтобы было красиво
Компания инвестирует в вас — время, обучение, доверие. Уходить через пару месяцев — непрофессионально, вы даже не успели показать результат.
— Уйти можно хоть завтра, если понял, что не ваше
Жизнь коротка, чтобы тратить её на неудачные проекты. Если после пары недель ясно, что культура, стек или атмосфера не ваша — не геройствуйте.
— Главное — довести начатое до конца
Профессионализм — это не про сроки, а про ответственность. Можно уйти через 3 месяца, но корректно: передать дела, закрыть задачи, предупредить заранее.
💬 Что думаете вы? Можете написать своё мнение в комментах 👇
👍 — Минимум год
🎉 — Уйти можно хоть завтра
🐸 Библиотека Go-разработчика
#GoTalk
Каждый разработчик хоть раз ловил это ощущение: вроде всё нормально, но что-то не твоё. Команда не заходит, менеджер микроменеджит, стек унылый, и ты уже смотришь вакансии на HH.
Так всё-таки, сколько нужно отработать, чтобы спокойно уйти — без чувства вины и разговоров за спиной?
— Минимум год, чтобы было красиво
Компания инвестирует в вас — время, обучение, доверие. Уходить через пару месяцев — непрофессионально, вы даже не успели показать результат.
— Уйти можно хоть завтра, если понял, что не ваше
Жизнь коротка, чтобы тратить её на неудачные проекты. Если после пары недель ясно, что культура, стек или атмосфера не ваша — не геройствуйте.
— Главное — довести начатое до конца
Профессионализм — это не про сроки, а про ответственность. Можно уйти через 3 месяца, но корректно: передать дела, закрыть задачи, предупредить заранее.
💬 Что думаете вы? Можете написать своё мнение в комментах 👇
👍 — Минимум год
#GoTalk
Please open Telegram to view this post
VIEW IN TELEGRAM
🎉66👍22❤2😢2👾2
🔫 DOOM запустили в российском текстовом редакторе
Энтузиаст запустил культовый шутер DOOM (1993) прямо внутри офисного пакета «Р7 Офис». Игра работает через встроенный эмулятор DOS наGo увы, но на JavaScript, интегрированный в систему плагинов редактора.
Теперь DOOM можно запустить прямо в документе, таблице или презентации. Помимо шутера в плагин добавили аркаду Last Spartan и головоломку 2048.
➡️ Источник
🐸 Библиотека Go-разработчика
#GoLive
Энтузиаст запустил культовый шутер DOOM (1993) прямо внутри офисного пакета «Р7 Офис». Игра работает через встроенный эмулятор DOS на
Теперь DOOM можно запустить прямо в документе, таблице или презентации. Помимо шутера в плагин добавили аркаду Last Spartan и головоломку 2048.
#GoLive
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥12❤3👾3😁1
Подборка новостей уходящей недели
— Go 1.25.2 и 1.24.8
— DataGrip теперь бесплатный
— Сравнение Go-библиотек для интеграции Ollama
— golang.org/x/net v0.45.0
Устранены две критические уязвимости в html-парсере
— Свежий Cup o' Go
Про релизы языка с фиксами и конференции по Go.
#GoLive
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3❤1
💬 Что из контента за эту неделю зацепило лично вас? Делитесь, интересно обсудить👇
🐸 Библиотека Go-разработчика
#GoTalk
#GoTalk
Please open Telegram to view this post
VIEW IN TELEGRAM
This media is not supported in your browser
VIEW IN TELEGRAM
В proglib.academy — Глобальная распродажа знаний ‼️
💥 Весь октябрь –40% на те курсы, которые выбирают чаще всего.
👉 Успей забрать свой курс на proglib.academy
💥 Весь октябрь –40% на те курсы, которые выбирают чаще всего.
Курсы с практикой, без воды и пафоса.
Просто берёшь и делаешь апгрейд.
👉 Успей забрать свой курс на proglib.academy
🥱8😁4🌚1
Ваш код компилируется, запускается и работает корректно, но при этом может быть в разы медленнее, чем мог бы. Компилятор не выдаст ошибку — ведь технически всё правильно.
Анализаторы кода замечают: выполняется очень часто, а её структура блокирует инлайнинг — одну из ключевых оптимизаций компилятора.
Представьте: вы написали функцию, которая складывает два числа. Простейшая операция. Но каждый раз, когда программа её вызывает, происходит целая церемония:
1.Процессор прыгает к адресу функции в памяти
2. Сохраняет контекст — где он был, куда вернуться
3. Создаёт новый фрейм стека для аргументов и локальных переменных
4. Выполняет полезную работу (наконец-то!)
5. Разрушает фрейм стека
6.Прыгает обратно и восстанавливает контекст
Для сложения двух чисел весь этот оркестр может занять в 10-100 раз больше времени, чем сама операция сложения.
Как обнаружить проблему
1. Используйте линтеры, они укажут напрямую где и что не инлайнится
2. Спросите компилятор:
go build -gcflags='-m' your_file.go
3. Профилирование выдаст симптомы
go test -bench=. -cpuprofile=cpu.prof
go tool pprof cpu.prof
Если видите, что процессор тратит 20% времени на вызов функции, которая делает return a + b — проблема очевидна.
Как писать код правильно с самого начала
• Уменьшайте функции
• Выносите defer за пределы частоиспользуемых функций
• Разделяйте быстрый и медленный пути:
// ✅ Оптимальный подход
func process(value interface{}) int {
// Fast path — 90% случаев, инлайнится
if v, ok := value.(int); ok {
return v * 2
}
// Slow path — 10% случаев, может быть сложным
return complexProcessing(value)
}
func complexProcessing(value interface{}) int {
// Тут defer, циклы, паники — всё что угодно
// Инлайнинг не критичен, код выполняется редко
switch v := value.(type) {
case string:
defer logProcessing()
return parseAndProcess(v)
case []byte:
return processBytes(v)
}
return 0
}
• Используйте подсказки компилятору
//go:inline
func fastPath(x int) int {
return x * 2
}
⚠️ Директива-подсказка, но не гарантия. Компилятор сам решит.
Эта ошибка не о синтаксисе и не о логике. Это ошибка архитектурного мышления. Вы должны понимать, как компилятор оптимизирует код, и писать так, чтобы дать ему эту возможность.
#GoDeep
Please open Telegram to view this post
VIEW IN TELEGRAM
⚡11👍8❤1👾1
Разработчик Go на гибрид в Новосибирск
В офис в Москве или на гибрид Тим лид от 350 000 ₽
Golang-разработчик до 300 000 ₽ на удалёнку в Москве.
Бустер — удалённо (не только Москва)
Please open Telegram to view this post
VIEW IN TELEGRAM
❤4🥱2👍1
13 октября вышли версии Go 1.25.3 и 1.24.9. Эти версии вышли всего через неделю после предыдущих обновлений, которые закрывали уязвимости в девяти пакетах стандартной библиотеки.
Новый фикс сфокусирован исключительно на дополнительном исправлении в модуле работы с сертификатами.
Если вы работаете с TLS, сертификатами или другими криптографическими примитивами, стоит обновиться на актуальные версии.
#GoLive
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12❤2👏1👾1
На первый взгляд может показаться, что фраза «пишу чистый код» звучит убедительно и профессионально — но на практике рекрутеры и ATS-системы давно привыкли к таким штампам и игнорируют их как пустые слова.
Когда вы пишете общие формулировки вместо конкретных достижений, ваше резюме теряется среди сотен похожих. Вместо «работаю с микросервисами» напишите «разработал и поддерживаю 12 микросервисов на Go, обрабатывающих 50K RPS с латентностью p99 < 100ms».
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5❤1👾1