100 ошибок Go и как их избежать

This document was uploaded by one of our users. The uploader already confirmed that they had the permission to publish it. If you are author/publisher or own the copyright of this documents, please report to us by using this DMCA report form.

Simply click on the Download Book button.

Yes, Book downloads on Ebookily are 100% Free.

Sometimes the book is free on Amazon As well, so go ahead and hit "Search on Amazon"

Лучший способ улучшить код — понять и исправить ошибки, сделанные при его написании. В этой уникальной книге проанализированы 100 типичных ошибок и неэффективных приемов в Go-приложениях. Вы научитесь писать идиоматичный и выразительный код на Go, разберете десятки интересных примеров и сценариев и поймете, как обнаружить ошибки и потенциальные ошибки в своих приложениях. Чтобы вам было удобнее работать с книгой, автор разделил методы предотвращения ошибок на несколько категорий, начиная от типов данных и работы со строками и заканчивая конкурентным программированием и тестированием. Для опытных Go-разработчиков, хорошо знакомых с синтаксисом языка.

Author(s): Тейва Харшани
Series: Для профессионалов
Edition: 1
Publisher: Питер
Year: 2024

Language: Russian
Commentary: Publisher's PDF
Pages: 480
City: СПб.
Tags: Programming; Concurrency; SQL; JSON; Best Practices; Go; Error Handling; Testing; Standard Library; Code Optimization

Предисловие
Благодарности
Об этой книге
Для кого эта книга
Структура книги
О коде в книге
Форум liveBook
Об авторе
Иллюстрация на обложке
От издательства
Глава 1. Go: просто научиться, но сложно освоить
Go: основные моменты
Просто не означает легко
1.3. 100 ошибок в Go
1.3.1. Баги
1.3.2. Излишняя сложность
1.3.3. Плохая читаемость
1.3.4. Неоптимальная или неидиоматическая организация
1.3.5. Отсутствие удобства в API
1.3.6. Неоптимизированный код
1.3.7. Недостаточная производительность
Итоги
Глава 2. Организация кода и проекта
2.1. Ошибка #1: непреднамеренно затенять переменные
2.2. Ошибка #2: лишний вложенный код
2.3. Ошибка #3: неправильно использовать функцию инициализации
2.3.1. Концепция
2.3.2. Когда использовать функции init
2.4. Ошибка #4: злоупотреблять геттерами и сеттерами
2.5. Ошибка #5: загрязнять интерфейсы
2.5.1. Концепции
2.5.2. Когда использовать интерфейсы
2.5.3. Загрязнение интерфейса
2.6. Ошибка #6: интерфейсы на стороне производителя
2.7. Ошибка #7: возврат интерфейсов
2.8. Ошибка #8: any не говорит ни о чем
2.9. Ошибка #9: путаница в использовании дженериков
2.9.1 Концепция
2.9.2. Общие случаи использования и злоупотребления
2.10. Ошибка #10: не знать о возможных проблемах со встраиванием типов
2.11. Ошибка #11: не использовать паттерн функциональных опций
2.11.1. Структура Config
2.11.2. Паттерн Строитель
2.11.3. Паттерн функциональных опций
2.12. Ошибка #12: неорганизованность проекта
2.12.1. Структура проекта
2.12.2. Организация пакета
2.13. Ошибка #13: создавать пакеты утилит
2.14. Ошибка #14: игнорировать коллизии имен пакетов
2.15. Ошибка #15: не писать документацию по коду
2.16. Ошибка #16: не использовать линтеры
Итоги
Глава 3. Типы данных
3.1. Ошибка #17: путаница с восьмеричными литералами
3.2. Ошибка #18: игнорировать целочисленные переполнения
3.2.1. Концепции
3.2.2. Обнаружение целочисленного переполнения при инкрементировании
3.2.3. Обнаружение целочисленного переполнения при сложении
3.2.4. Обнаружение целочисленного переполнения при умножении
3.3. Ошибка #19: не понимать проблем, связанных с плавающей точкой
3.4. Ошибка #20: не понимать особенностей, связанных с длиной среза и его емкостью
3.5. Ошибка #21: неэффективная инициализация среза
3.6. Ошибка #22: путать пустые и нулевые срезы
3.7. Ошибка #23: неправильно проверять пустоту среза
3.8. Ошибка #24: неправильно создавать копии срезов
3.9. Ошибка #25: неожиданные побочные эффекты при использовании append в операциях со срезами
3.10. Ошибка #26: срезы и утечки памяти
3.10.1. Утечки емкости
3.10.2. Срез и указатели
3.11. Ошибка #27: неэффективно инициализировать карты
3.11.1. Концепции
3.11.2. Инициализация
3.12. Ошибка #28: карты и утечки памяти
3.13. Ошибка #29: некорректное сравнение значений
Итоги
Глава 4. Управляющие структуры
4.1. Ошибка #30: игнорировать то, что элементы в цикле range копируются
4.1.1. Концепция
4.1.2. Копия значения
4.2. Ошибка #31: игнорировать то, как в циклах range вычисляются аргументы
4.2.1. Каналы
4.2.2. Массив
4.3. Ошибка #32: игнорировать влияние, которое оказывает использование элементов указателя в циклах range
4.4. Ошибка #33: делать неверные допущения во время итераций карты
4.4.1. Упорядочивание
4.4.2. Вставка карты во время итераций
4.5. Ошибка #34: игнорировать особенности работы оператора break
4.6. Ошибка #35: использовать defer внутри циклов
Итоги
Глава 5. Строки
5.1. Ошибка #36: не понимать концепции рун
5.2. Ошибка #37: неточная итерация строк
5.3. Ошибка #38: неправильно использовать функции обрезки
5.4. Ошибка #39: недостаточная степень оптимизации при конкатенации строк
5.5. Ошибка #40: бесполезные преобразования строк
5.6. Ошибка #41: подстроки и утечки памяти
Итоги
Глава 6. Функции и методы
6.1. Ошибка #42: не знать, какой тип получателя использовать
6.2. Ошибка #43: не использовать именованные параметры результата
6.3. Ошибка #44: побочные эффекты от именованных параметров результата
6.4. Ошибка #45: возврат получателя nil
6.5. Ошибка #46: использовать имя файла в качестве входных данных функции
6.6. Ошибка #47: игнорировать то, как вычисляются аргументы и получатели оператора defer
6.6.1. Вычисление аргументов
6.6.2. Получатели значений или указателей
Итоги
Глава 7. Обработка ошибок
7.1. Ошибка #48: паника
7.2. Ошибка #49: игнорировать оборачивание ошибки
7.3. Ошибка #50: неточная проверка типа ошибки
7.4. Ошибка #51: неточная проверка значения ошибки
7.5. Ошибка #52: двойная обработка ошибки
7.6. Ошибка #53: не выполнять обработку ошибки
7.7. Ошибка #54: не выполнять обработку ошибки оператора defer
Итоги
Глава 8. Конкурентность: основы
8.1. Ошибка #55: путать конкурентность и параллелизм
8.2. Ошибка #56: полагать, что конкурентность быстрее
8.2.1. Планирование в Go
8.2.2. Параллельная сортировка слиянием
8.3. Ошибка #57: путаться в том, когда использовать каналы, а когда мьютексы
8.4. Ошибка #58: не понимать проблем гонки
8.4.1. Гонка данных и состояние гонки
8.4.2. Модель памяти Go
8.5. Ошибка #59: не понимать влияние типа рабочей нагрузки на конкурентность
8.6. Ошибка #60: неверно понимать контексты Go
8.6.1. Крайний срок
8.6.2. Сигналы отмены
8.6.3. Значения контекстов
8.6.4. Перехват отмены контекста
Итоги
Глава 9. Конкурентность: практика
9.1. Ошибка #61: передавать неподходящий контекст
9.2. Ошибка #62: запускать горутину и не знать, когда ее остановить
9.3. Ошибка #63: неосторожно обращаться с горутинами и переменными цикла
9.4. Ошибка #64: ожидать детерминированное поведение при использовании select и каналов
9.5. Ошибка #65: не использовать каналы уведомлений
9.6. Ошибка #66: не использовать нулевые каналы
9.7. Ошибка #67: гадать насчет размера канала
9.8. Ошибка #68: забывать о возможных побочных эффектах при форматировании строк
9.8.1. Гонка данных в etcd
9.8.2. Взаимоблокировка
9.9. Ошибка #69: создавать ситуацию гонки данных из-за оператора append
9.10. Ошибка #70: неверно использовать мьютексы со срезами и картами
9.11. Ошибка #71: неправильно использовать sync.WaitGroup
9.12. Ошибка #72: забывать о sync.Cond
9.13. Ошибка #73: не использовать errgroup
9.14. Ошибка #74: копировать тип sync
Итоги
Глава 10. Стандартная библиотека
10.1. Ошибка #75: неправильно задавать промежуток времени
10.2. Ошибка #76: time.After и утечки памяти
10.3. Ошибка #77: типичные ошибки при обработке JSON
10.3.1. Неожиданное поведение из-за встраивания типов
10.3.2. JSON и монотонные часы
10.3.3. Карта типа any
10.4. Ошибка #78: типичные ошибки, связанные с SQL
10.4.1. Не знать, что sql.Open не всегда устанавливает соединение с базой данных
10.4.2. Забывать о пуле соединений
10.4.3. Не использовать подготовленные операторы
10.4.4. Неправильная обработка нулевых значений
10.4.5. Не обрабатывать ошибки итерации строк
10.5. Ошибка #79: не закрывать временные ресурсы
10.5.1. Тело HTTP
10.5.2. sql.Rows
10.5.3. os.File
10.6. Ошибка #80: забывать об операторе return после ответа на HTTP-запрос
10.7. Ошибка #81: использовать стандартные HTTP-клиент и сервер
10.7.1. HTTP-клиент
10.7.2. HTTP-сервер
Итоги
Глава 11. Тестирование
11.1. Ошибка #82: не распределять тесты по категориям
11.1.1. Теги сборки
11.1.2. Переменные среды
11.1.3. Короткий режим
11.2. Ошибка #83: не включать флаг -race
11.3. Ошибка #84: не использовать режимы выполнения тестов
11.3.1. Флаг parallel
11.3.2. Флаг -shuffle
11.4. Ошибка #85: не использовать табличные тесты
11.5. Ошибка #86: задержки в юнит-тестах
11.6. Ошибка #87: неэффективная работа с API времени
11.7. Ошибка #88: не использовать пакеты утилит для тестирования
11.7.1. Пакет httptest
11.7.2. Пакет iotest
11.8. Ошибка #89: писать неточные бенчмарки
11.8.1. Не сбрасывать или не ставить на паузу таймер
11.8.2. Делать неверные предположения о микробенчмарках
11.8.3. Небрежное отношение к оптимизациям компилятора
11.8.4. Эффект наблюдателя
11.9. Ошибка #90: не изучать все возможности тестирования в Go
11.9.1. Покрытие тестами
11.9.2. Тестирование из другого пакета
11.9.3. Вспомогательные функции
11.9.4. Настройка и демонтаж
Итоги
Глава 12. Оптимизация
12.1. Ошибка #91: не понимать устройство кэша CPU
12.1.1. Архитектура CPU
12.1.2. Кэш-линия
12.1.3. Срез структур и структура срезов
12.1.4. Предсказуемость
12.1.5. Стратегия размещения кэша
12.2. Ошибка #92: писать конкурентный код, который приводит к ложному совместному использованию
12.3. Ошибка #93: не учитывать параллелизм на уровне инструкций
12.4. Ошибка #94: не знать о выравнивании данных
12.5. Ошибка #95: не понимать различий между стеком и кучей
12.5.1. Стек и куча
12.5.2. Эскейп-анализ
12.6. Ошибка #96: не знать, как сократить число выделений памяти
12.6.1. Изменения API
12.6.2. Приемы оптимизации компилятора
12.6.3. sync.Pool
12.7. Ошибка #97: не полагаться на встраивание
12.8. Ошибка #98: не использовать диагностический инструментарий Go
12.8.1. Профилирование
12.8.2. Трассировщик выполнения
12.9. Ошибка #99: не понимать, как работает сборщик мусора
12.9.1. Концепции
12.9.2. Примеры
12.10. Ошибка #100: не понимать особенностей запуска Go внутри Docker и Kubernetes
Итоги
Заключение