Текстовая версия разбора документа 12 Factor App: Часто бывает так, что работа с кодовой базой проекта приносит боль в самых разных аспектах: от внесения изменений и добавления новых фич до развертывания на стенде. Может показаться, что какие-то проблемы являются данностью, и с этим принципиально сложно что-то сделать. К счастью, это относится не ко всему. Адам Виггинс и другие сотрудники компании Heroku однажды решили составить документ, который помог бы решить многие проблемы с разработкой и эксплуатацией информационных систем. Этот документ называется “The Twelve-Factor App” или «12-факторное приложение». Я предлагаю пройтись по нему и разобрать каждый пункт. Часто бывает так, что работа с кодовой базой проекта приносит боль в самых разных аспектах: от внесения изменений и добавления новых фич до развертывания на стенде. Может показаться, что какие-то проблемы являются данностью, и с этим принципиально сложно что-то сделать. К счастью, это относится не ко всему. Адам Виггинс и другие сотрудники компании Heroku однажды решили составить документ, который помог бы решить многие проблемы с разработкой и эксплуатацией информационных систем. Этот документ называется “The Twelve-Factor App” или «12-факторное приложение». Я предлагаю пройтись по нему и разобрать каждый пункт. Данный текст — во многом пересказ и местами вольный перевод оригинального документа. Я в курсе, что “The Twelve-Factor App” уже был переведен на русский язык, но на мой взгляд перевод выполнен настолько плохо, что даже при низком уровне английского воспринимать оригинал проще. Кроме того, некоторые части оригинального текста я немного адаптировал под современные реалии. Что такое 12-факторное приложение? The Twelve-Factor App — это методология для построения приложений, которые: Используют декларативный подход к автоматизации для минимизации временных и денежных затрат на онбординг новых членов команды; Обладают явным контрактом взаимодействия с операционной системой, предоставляя тем самым максимальную портативность между средами выполнения; Готовы к развёртыванию на современных облачных платформах, снижая или вовсе предотвращая потребность оперировать отдельными серверами; Минимизируют различия между окружениями для разработки и продакшеном, позволяя для гибкости деплоить приложение непрерывно; Масштабируются, не требуя значительных изменений в тулинге, архитектуре и культуре разработки....
Создаем Telegram-бота для новостей на Go, PostgreSQL и OpenAI API (ChatGPT)
В этом ролике мы с вами напишем проект, который не стыдно положить на свой GitHub. Это будет Telegram-бот, который автоматически достаёт свежие новости и статьи про язык программирования Go из разных источников, генерирует для них саммари с помощью OpenAI API (ChatGPT), а затем публикует их в Telegram-канал. И всё это автоматически! Такой проект может послужить отличным преимуществом при поиске работы, особенно если вы джуниор-разработчик, и вам нужно выделиться среди других соискателей ;)
CLI-интерфейсы по-человечески @ Podlodka Go Crew
Запись моего доклада с конференции Podlodka Go Crew. Возможно, вам покажется, что говорить в 2023м о консольных приложениях странно, но в докладе мы покажем, почему CLI-приложения еще актуальны. Разберемся, какие инструменты помогут нам баланс и сделать такие приложения максимально удобными и понятными пользователю. На закуску предложим шаблон с конфигами, который можно унести к себе в команду.
sqlc: как избавиться от ORM с помощью кодогенерации
Я как-то раз писал про то, почему я не люблю SQL (именно язык как концепцию и философию, а не конкретные реализации), зато люблю про это говорить — уже третий пост, где я это упоминаю. Тем не менее я сейчас пишу код для следующего ролика для ютуб-канала, и я сознательно решил там использовать PostgreSQL. Причина простая — это видос про написание проекта. Такие видосы по моей гипотезе полезны прежде всего джунам, чтобы те могли приложить к резюме свой гитхаб, где лежит реализованный проект. И в данном случае джун, умеющий хоть как-то в PostgreSQL будет иметь преимущество, потому что постгря сейчас практически везде. ℹ️ Этот пост взят из моего телеграм-канала. Так вот, я вчера мозг сломал в трёх местах, пока пытался написать запрос с элементарной фильтрацией по колонкам с таймстемпами. Не то что бы это что-то сложное, но способов выразить время и фильтры по времени в PostgreSQL миллион (как и положено в SQL). А к ним добавляется ещё неясность относительно того, как эти даты и интервалы правильно передавать конкретному драйверу — авторы того драйвера, что у меня решили, что не будут делать авто маппинг time.Duration в интервалы. Почему? Потому что не будут. Вообще я думал про то, что в СУБД нужно выкинуть/сделать SQL опциональным и предоставлять бинарный протокол. Почему SQL нужен аналитикам — понятно. Зачем промежуточный язык для продакшен-кода — мне непонятно. Если бы у СУБД существовал бинарный протокол, то язык запросов мог бы быть выражен инструментами языка, на котором ведётся разработка. Да, я знаю про ORM и ActiveRecord. Но они всё равно превращают код на одном языке в код на SQL. Тут уж я скорее солидарен с го-коммьюнити — если и писать SQL-запросы, то на самом SQL. Есть тула, на которую я недавно наткнулся — slqc....
Конкурентность в Go простым языком
Этот пост является текстовой версией моего видео про конкурентное программирование: Go — это язык, который не просто обладает хорошими инструментами, позволяющими использовать всю мощь многоядерных процессоров с помощью параллельного программирования. Go — это язык, который проектировался в первую очередь для конкурентных и параллельных вычислений. Поэтому я не могу пройти мимо данной темы. В материале мы разберёмся как с базовыми инструментами для «параллельных» вычислений (почему я взял это слово в скобки, вы узнаете чуть позже), так и с примитивами синхронизации горутин. Хоть далеко не всех из них являются частью языка, они присутствуют в стандартной библиотеке. ⚠️ Это обзорный материал, поэтому я не буду погружаться сильно глубоко в каждую из рассматриваемых тем. Для этого в будущем появятся отдельные подробные материалы. Также материал может содержать неточности при использовании тех или иных терминов для упрощения погружения в описываемые концепции. Что такое параллельные вычисления Википедия гласит: В информатике параллели́зм — это свойство систем, при котором несколько вычислений выполняются одновременно, и при этом, возможно, взаимодействуют друг с другом. Примечание. В русскоязычной литературе нередко путаются термины «параллелизм» и «конкурентность». Оба термина означают одновременность процессов, но первый — на физическом уровне (параллельное исполнение нескольких процессов, нацеленное только на повышение скорости исполнения за счёт использования соответствующей аппаратной поддержки), а второй — на логическом (парадигма проектирования систем, идентифицирующая процессы как независимые, что в том числе позволяет их исполнять физически параллельно, но в первую очередь нацелено на упрощение написания многопоточных программ и повышение их устойчивости). Теперь давайте разберёмся с этим последовательно. Представьте себе очень простой процессор, у которого всего одно ядро. На этом ядре в один момент времени может исполняться только одна программа или процесс. Чтобы компьютер мог исполнять несколько задач одновременно, процессор можно сделать многоядерным. Тогда он сможет исполнять одновременно не более $N$ программ, где $N$ — это количество ядер....
Тесты. Что нужно знать разработчику
Это текстовая версия моего ролика про тесты, который я сделал совместно с Анастасией Заречневой: Зачем нужно писать тесты? Написание автоматических тестов часто съедает времени не меньше, чем написание тестируемого кода. Так зачем же писать тесты, если можно проверить программу на ошибки вручную, а если в будущем обнаружится баг, то просто подебажить и исправить его? Автоматические тесты можно перезапустить в любой момент, и это займёт меньше времени, чем проверка кода вручную. Особенно это заметно при росте количества тест-кейсов, а их обязательно станет больше. Такие тесты хорошо масштабируются со временем, особенно при использовании параметризации — запуске одного и того же теста множество раз на разных данных. Минимизация человеческого фактора — человек может забыть или неправильно понять тот или иной шаг в тестовом сценарии. Автотесты служат своего рода спецификацией — хорошо написанные тесты могут помочь разобраться в том, как работает программа, а так же могут дать знать, если поведение программы больше не соответствует ожиданиям. Тесты помогают находить ошибки, о наличии которых крайне сложно догадаться при ручном тестировании. Принципы F.I.R.S.T. Тесты — это такой же код в свободной форме, как и любой другой. Поэтому, чтобы не порождать в них хаос, нужно также следовать каким-то принципам и архитектуре. Одним из таких наборов принципов является F.I.R.S.T.: Fast (быстрый) Isolated/Independent (изолированный/независимый) Repeatable (воспроизводимый) Self-validating (самопроверяющийся) Thorough (тщательный) Fast Тесты должны быстро запускаться и проходить, чтобы разработчик делал это чаще и не избегал прогонов. Isolated/Independent Каждый тест должен быть независимым от всех остальных. В частности, результат теста не должен зависеть от внешних факторов, таких как порядок запуска тестов. Этого легче достичь, если тест структурирован в соответствии с подходом Arrange, Act, Assert: Arrange. Подготовка окружения и данных. Этот шаг описывает состояние системы перед запуском сценария, который вы тестируете. Act. Вызов тестируемого кода с данными и в окружении, подготовленными на предыдущем шаге....
Cокращатель ссылок на Go с нуля до деплоя
В этом ролике я пишу сокращатель ссылок на Go, используя Echo в качестве веб-фреймворка и MongoDB как СУБД. Кроме того, в ролике мы прикрутим аутентификацию с помощью GitHub и задеплоим сервис на Digital Ocean. Получить $200 на счёт DigitalOcean: https://m.do.co/c/a76c4cd7e830
О Vim и процессе обучения. Нужно ли изучать Vim/Neovim?
Мои импровизированные рассуждения на камеру о том, как подходить к изучению новых инструментов на примере текстового редактора Vim.
Дженерики в Go
В этот раз поговорим об одной из самых долгожданных фичах Go — дженериках — инструменте обобщённого программирования. Дженерики как раз завезли в Go 1.18, т.е. совсем недавно, и самое время в них разобраться. Это текстовая версия моего ролика про дженерики: Данный материал частично основан на официальном туториале от команды языка. Зачем нужны дженерики Идея обобщённого программирования заключается в том, чтобы единожды написать код, который может работать с множеством разных типов, соответствующих заданным ограничениям. Например, можно только один раз реализовать алгоритм сортировки чисел, но применять его к разным видам чисел, вместо того чтобы реализовывать его отдельно для int, int64, uint32, float64 и т.д. То, что это должны быть именно числа как раз и является ограничением в данном случае. Дженерики — это также одна из форм полиморфизма. Ограничения или констрейнты в дженериках — это требования к типам, которые обобщаются данным дженериком. В некотором смысле констрейнты — это те же интерфейсы, но позволяющие описывать требования в том числе через сами значения, а не только их поведение. Посмотрите, даже синтаксис объявления именованного констрейнта похож на синтаксис объявления интерфейса: 1 2 3 4 5 6 type Ordered interface { ~int | ~int8 | ~int16 | ~int32 | ~int64 | ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr | ~float32 | ~float64 | ~string } С помощью оператора | перечисляются типы, подходящие под констрейнт. Таким образом Ordered требует, чтобы тип был таким, что над ним задано отношение порядка. Префикс ~ перед каждым типом означает, что это может быть, например, не только string, но и любой тип, для которого string является базовым типом (т.е. типы, расширяющие string тоже удовлетворяют требованиям). Имея такое ограничение, мы можем объявить, например, вот такую функцию: 1 2 3 4 5 6 7 8 9 func Min[T constraints....
golangci-lint и внедрение его в большой проект
Хороший разработчик обычно стремится написать код, который не просто работает, но работает стабильно. Код, который легко читать и сопровождать. Достичь такого высокого качества кода кроме тестов также помогают единый стиль кода, хорошая документация, а также простота и изящность, как на уровне всей системы, так и на уровне отдельных модулей и функций. Считается, что соответствие кода принятым в команде стандартам качества проверяет как сам разработчик, так и его коллеги на код-ревью. Проблема только в том, что все мы люди, и всегда можем что-то упустить. А иногда (на самом деле очень часто), разработчики закрывают глаза на те моменты, которые кажутся им незначительными. В связи с этим придумали статический анализ кода. Если говорить просто, это анализ исходного кода без непосредственного запуска этого кода. Когда вы пробегаете глазами по коду, чтобы убедиться, что с ним всё ок — это тоже статический анализ 🙂. Противоположный подход — динамический анализ — предполагает, что код будет запускаться и анализироваться во время исполнения. Примером динамического анализа кода являются тесты, но о них поговорим в другой раз. Обычно статический анализ строится на основе набора правил, например: Длина строки не должна превышать 120 символов; Нельзя вызывать defer внутри for; и т.д. Программы, которые выполняют статический анализ, называют линтерами. Для Go написано уже очень много линтеров, каждый из которых специализируется на своём наборе проверок. Например, bodyclose проверяет, что разработчик не забыл закрыть тело ответа при отправке HTTP-запросов: internal/httpclient/httpclient.go:13:13: response body must be closed А wsl следит за тем, чтобы в коде были правильно расставлены пустые строки для повышения читаемости. Линтеров для Go настолько много, что управлять всеми ими самостоятельно стало в один момент сложнее, чем проверять программы вручную. Поэтому следующим этапом стало появление металинтеров — программ, которые позволяют настроить и запустить большое количество линтеров из единого места....