Заметки программиста – Telegram
Заметки программиста pinned «Всем привет! 👋 Меня зовут Светлана. Я Java разработчик. В этом блоге планирую реализовывать так называемое «мышление письмом» / заметки для структурирования своих знаний и процесса обучения в целом. 👩‍💻 Код —> Github 📲 Соц сети —> LinkedIn»
Зачем вообще надо писать о своей учебе и о своих знаниях?

1. Боремся с кривой забывания.
Когда мы получаем читаем новую статью или книгу, то через час получится вспомнить только 44%. При этом вспомнить != пересказать. Чтобы этого избежать, надо повторять информацию. Поэтому для усвоения нового материала полезно сразу после прочтения писать заметки, письменно отвечать на вопросы в конце главы (если это учебник). Через день после прочтения будет полезно пересказать новую информацию (коллегам, друзьям, котику или уточке). Ну, и конечно самое главное - не позже чем через 2-3 недели применить новые знания на практике.
2. Простое повторение не работает.
Наш мозг так устроен, что при простом перечитывание материала не будет работать достаточно активно, чтобы создать новые устойчивые связи. Чтобы лучше запоминать, нужно воспроизводить свежую информацию по памяти, отвечать на вопросы и даже самим их составлять.
3. Мы не можем держать в голове много мыслей.
Каждая мысль в нашей голове занимает определенные ресурсы, прямо как процессы в компьютере. Поэтому для эффективного обдумывания и решения сложных задач (например, проектирование нового модуля со сложной бизнес-логикой) лучше пользоваться именно письмом. Да, писать связанные и понятные тексты - задача сама по себе сложная. Но эта техника дает много бонусов - если ты сумел оформить свои мысли в текст, то ты уже обдумал большую часть мыслей. А еще всегда можно вернуться к своим мыслям - если все таки забыл спустя время.

В IT же есть немного своих плюшек:
- Применяя "мышления письмом" в работе - получаешь наброски документации или спецификации.
- Если есть сложная проблема, то помогает письменно сформулировать вопрос. Чаще всего оказывается, что дописав вопрос - уже появляется зацепка в голове, которая приводит к решению. "Чтобы правильно задать вопрос, нужно знать большую часть ответа." ©
- Всегда на следующий день знаешь какие задачи решал вчера (для дейлика )🙂
🔥31
Иногда важно перепроверить даже самые банальные вещи.

Сегодня хотелось бы поделиться с вами одним интересным случаем, который произошел на работе. Наш проект столкнулся с серьезной проблемой - администратор базы данных обнаружил большую нагрузку на CPU, deadlock запросы и длинные транзакции. Специалист по поддержке базы данных не смог найти источник проблемы и утверждал, что индексы оптимизированы. Команда грешила на hibernate, который генерирует скрытые запросы. Однако, я нашла ключевую проблему - отсутствие Primary Key в таблице.

Вам может показаться странным, что отсутствие Primary Key может вызывать такие серьезные проблемы. Однако, это действительно так. Primary Key - это уникальный идентификатор каждой записи в таблице. Он играет решающую роль в эффективности и производительности базы данных. Вот почему:

1. Ускорение выборки данных: Когда мы выполняем запросы к базе данных, Primary Key позволяет ей быстро найти нужную запись. Без Primary Key, база данных должна будет сканировать всю таблицу для поиска нужных данных, что приводит к значительному снижению производительности. В нашем случае, добавление Primary Key в таблицу позволило сократить нагрузку на CPU на 80%.

2. Предотвращение дублирования данных: Primary Key гарантирует уникальность каждой записи в таблице. Это предотвращает возможность дублирования данных и обеспечивает целостность базы данных. Без Primary Key, мы можем столкнуться с проблемами, такими как потеря данных или неправильное объединение таблиц.

3. Улучшение производительности при соединении таблиц: когда мы соединяем несколько таблиц, Primary Key играет важную роль в оптимизации этого процесса. Он позволяет базе данных быстро связывать данные из разных таблиц и выполнять операции объединения более эффективно.

4. Обеспечение ссылочной целостности: Primary Key часто используется в качестве внешнего ключа для связывания таблиц между собой. Это обеспечивает ссылочную целостность данных и предотвращает возможность удаления или изменения записей, на которые есть ссылки из других таблиц.

В итоге, добавление Primary Key в таблицу оказалось ключевым фактором для решения проблемы, с которой мы столкнулись на проекте. Он значительно сократил нагрузку на CPU и улучшил производительность базы данных. Этот случай подчеркивает важность правильного проектирования базы данных и использования Primary Key.

Надеюсь, что мой опыт поможет вам осознать важность перепроверки даже таких базовых вещей как Primary Key в оптимизации базы данных.
🔥3
У меня есть маленький pet-проект для экспериментов над ним. Хотелось поработать с:
1. визуализацией - использовала Thymeleaf для создания динамических страниц, Bootstrap для стилизации и адаптивного дизайна;
2. геоданными - PostGIS, API open route для генерации случайного трека с учетом реальной карты и Yandex Static API для визуализации сгенерированного трека;
3. GitHub Actions - хороший инструмент для pet-проектов.

Этот проект стал для меня отличной площадкой для экспериментов и изучения новых возможностей каждой из этих технологий. Thymeleaf оказался очень удобным инструментом для работы с шаблонами и вставкой данных на стороне сервера. Bootstrap позволил быстро и красиво оформить моё приложение, делая его адаптивным к различным устройствам. PostGIS в связке с Hibernate занял больше всего времени в части нахождения подходящей библиотеки для корректной работы. GitHub Actions выглядит легким инструментом для освоения из-за большего количества примеров и готовых решений, но для сложных проектов Jenkins предоставляет больше возможностей.

Дальше в моих планах стоит переделать архитектуру. Так как в моих рабочих проектах используется в основном onion архитектура, мне хочется реализовать гексагональную, чтобы познакомиться с их различиями поближе.
🔥2
Начала реализовывать гексагональную архитектуру. Она оказалась для меня не интуитивно понятной, но однозначно интересной и стоящей внимания.
Основной смысл этой архитектуры заключается в максимальном применении SOLID и атомизации компонентов исходного кода.
Из основных плюсов я для себя отметила:
⁃ упрощение работы с кодом классов и тестов. Они стали меньше по объему и соотвественно читать их стало проще.
⁃ тестируемость. Можно протестировать бизнес логику приложения изолированно.
⁃ меньше кода в классе -> меньше потенциальных конфликтов при слиянии веток от различных разработчиков при работе в команде.
⁃ больше гибкости в конфигурации сервисов. Напрмер, проще добавить кэш только в одном методе.
Из минусов:
⁃ больше классов и интерфейсов. Единственный способ упростить этот момент - грамотно и внимательно организовать типы по пакетам и модулям.
Лично для меня такой тип архитектуры так и остался пока очень не привычным. Теперь в планах прочитать книгу «Чистая архитектура» Роберта Мартина.
🔥2
Кажется что Telegram боты есть сейчас у всех. Вот и в свой проект решила его добавить. Это оказалась действительно очень просто. Спасибо Telegram’у за это 🙂
Основное количество туториалов на эту тему в интернете предлагают создавать бота на Python, но я буду писать на java + spring + maven и TelegramAPI версии 6.9.7.1. Реализацию сделала с помощью LongPolling, т.к. этот метод не требует сертификатов шифрования и запускаться может с любой машины. Для этого я наследовалась от TelegramLongPollingBot.
В отличии от версии 3.5 здесь произошли изменения:
- из базовых методов теперь не нужно реализовывать public String getBotToken(), т.к. токен теперь передается в конструкторе.
- Конструктор без параметров и конструктор который не принимает токен теперь помечены как deprecated.
Получается что при создании своего бота теперь обязательно нужно передавать токен в родительский класс.
Так же нужно подключить своего бота к TelegramAPI. А т.к. я поручила Spring создавать моего бота (с помощью @Component), то использовала @PostConstruct в котором вызывала метод registerBot.
Получать, обрабатывать и отвечать на сообщения бот умеет через метод public void onUpdateReceived(Update update) который нужно реализовывать.
Креды бота конечно же лучше убрать в конфиги, например с помощью spring.config.import. Получить их можно у отца всех ботов в Telegram (@BotFather).
Вот в принципе и все. Реализация бота оказалась самой легкой частью, а вот реализовать логику обработки сообщений может быть уже далеко не так просто (конечно же, в зависимости от придуманных фичей). Благодаря понятным API у Telegram получилась сделать легкий старт в создании ботов для каждого. Единственный маленький минус - это устаревшая документация в официальных источниках, про то что есть изменения свежих версий от старый там не упоминается.
🔥2
На этой неделе прошел первый online день конференции Jpoint (это одна из двух крупнейших в России конференций для Java разработчиков). Я послушала 4 полных доклада и дискуссий.
1. «PG для Java-разработчиков». Автор рассказывал о процессе миграции продукта с Oracle на Postgres. К моему сожалению JPA/Hibernate в докладе не рассматривались, использовался jdbc. Но для пула коннектов использовался HikariCP, так же как и у нас. Благодаря наводкам автора я решила сделать ревизию настроек подключения к базе, возможно наши конфиги не так оптимальны. Также нужно будет обновить библиотеки: как минимум liquibase уже давно напрашивается, версию зависимости postgresql также нужно проверить. Автор рассказывал о том что новые фичи не всегда включены по умолчанию из-за желания разработчиков поддерживать обратную совместимость, нужно читать changelog-и. А еще во время доклада пришла идея сделать также как в продукте докладчика: для создания Excel отчета можно читать данные из read-only реплики. У нас есть некоторые отчеты и возможно такое решение снизит нагрузку на систему в целом. Еще автор рассказал про интересную возможность настройки application_name при запросе pg_stat_activity. Дефолтное имя вида PostgreSQL JDBC не самое удобное для анализа. А с помощью настройки
spring.datasource.hikari.data-source-properties.ApplicationName=yourAppName

можно отслеживать запросы не только по их содержимому, потому что это сложно уже даже для среднего размера проекта.
2. «Миграция на Spring Boot 3». Это было интересное обсуждение, т.к. в нашем продукте используется java 11 и spring boot 2.5. Очевидно обновится нам стоило бы, но времени на это нет (фичи не ждут!). Поэтому нужно составить четкий план миграции и делать это постепенно и по возможности безболезненно. Как вариант эксперты предложили сравнить
dependecy treе вашего текущего проекта с целевой версии (сгенерить можно свежий через https://start.spring.io/). Думаю что это интересная идея, которая поможет понять на сколько зависимости отличаются и в каком участке кода предстоит больше всего работы.
А в случае нашего приложения конечно нужно вначале мигрировать хотя бы на 17 java. Дальше эксперты предлагают поднять версию spring boot до 2.7. И потом уже когда выровняли зависимости до 3.2 - так процесс должен пройти мягче. Хотя конечно переезд на Jakarta EE, новый Hibernate, обновленная Security добавят некоторое количество часов проведенных за правками кода.
3. «System Design-интервью для практиков». С помощью этого доклада можно в очередной раз убедиться что собеседования в FAANG это свой отдельный мир с очень жесткими таймингами ограничениями. Жалею что не смотрела доклад Владимир Маслов — System Design. Как построить распределенную систему и пройти собеседование с прошлого jpoint, а докладчик советовал. Теперь и его надо посмотреть 🙂
4. «Как готовить свой код к виртуальным потокам». Все круто, классно, полезно, но в текущих рабочих реалиях этот доклад я не могу применить к рабочему проекту, потому что работа в банке - это много ограничений и java 21 пока у нас отсутствует 🙁
И в обсуждении тоже было много комментариев о том что очень хотелось бы добавить виртуальные потоки в свой код, но проект на java 17, 11 и даже 8.
А вообще мысль про обновление на более свежие версии библиотек, фреймоворков, языка и т.д. для меня была основной в этом дне, но на это вечно нету времени, а жаль. Планирую его все же найти, потому что прирост производительности приложения это должно дать.
Конференция пока выглядит очень насыщенной и полезной, теперь я жду продолжения.
👍3🔥1
Сегодня о втором дне конференции JPoint, который мне удалось посетить в offline. Перед тем как переходить к докладам, хочу отметить организаторов. Они отлично поработали! Не возникало вообще никаких проблем, все было просто, понятно и очень хорошо организовано.
Итак, к докладам:

1. «Бросить нельзя поймать: основы и детальная механика Java-исключений». Было очень много полезной информации об исключениях: когда ловить, логировать ли (иногда это очень дорого), нужно ли оборачивать и как. Я узнала про ключи запуска jvm «OmitStackTraceInFastThrow» и «CrashOnOutOfMemoryError». И первый точно поможет если на проде откуда-то прилетел NPE и нужно понять откуда и получить трейс. По умолчанию его конечно лучше не включать, но для расследования инцидента нужно запомнить. А второй ключ уронит jvm и снимет дамп.

2. «Hibernate, OOM и ооочень длинные запросы». Получилось интересно, потому что вторую часть первого доклада как раз обсуждали OOM и как его искать и что делать. Получилось небольшое продолжение 🙂

3. «Правильный DevOps для Spring Boot и Java». Один из самых классных докладов на конференции. Когда его выложат в открытый доступ, однозначно рекомендую посмотреть не только джавистам, но и DevOps-инженерам. Если нюансы изменения конфигурации приложения знакомы многими, то о том, что с помощью Spring (layertools) можно решить вопросы кэширования слоев докер образа, знают не многие.

4. «Как мы построили самобалансирующийся мониторинг обработки топиков Kafka с помощью самой Kafka». Докладчик интересно рассказывал о пути продукта и как они решали задачи связанные с обработкой потоков данных. Было интересно послушать, но в текущем проекте данную информацию, к сожалению, нигде не применить.

5. «Spring Data JDBC. Проблемы известные, проблемы неизвестные». Это был самый смешной доклад всей конференции 🙂 Докладчик является действующим контрибьютором в Spring Data JDBC и он знает о текущих проблемах проекта. Было много багов, которые оказались фичей. И еще часть проблем о которых разработчики знают, но: «Исправлять мы это конечно же не будем» 😁

6. «Образование в области IT: фундамент и индустриальная повестка». Докладчик рассказал о Физтех-школе прикладной математики и информатики, как им удается сохранять фундаментальное образование, но при этом работать совместно с потребностями бизнеса. Это было интересно послушать.

Еще было много общения, мерча, и людей, которым явно было интересно рассказывать и слушать. В общем, атмосфера в offline была потрясающей.
👍3🔥1
Сегодня о третьем, заключительном дне конференции JPoint 2024. В этот день у меня не получилось посетить все доклады, которые хотелось, т.к. два шли в одно и то же время.

1. «Поиск проблем Java-приложения с 31G heap и 500G off-heap на примере Apache Ignite». Посетила этот доклад в продолжение темы о снятии и анализов дампов. Но в этом докладе докладчик рассказывал не только о том как «лечить» Java приложение, но и много внимания уделил настройкам Linux для высоконагруженного приложения, что встречается крайне редко.

2. «Запуск по расписанию в Java: как не проспать работу и успеть к дедлайну». Этот доклад смотрела уже после конференции в online. Здесь докладчик рассказывал о существующих решениях для планировщиков задач, получилась такая обзорная экскурсия по инструментам. Основное что можно почерпнуть для себя из этого доклада - это то к какому решению прибегать в зависимости от обстоятельств в которых оно будет использоваться.

3. «Мы писали DSL в Spring и грабли ловили». Этот доклад напомнил о Евгении Борисове и Spring-потрошители. Докладчики явно им вдохновлялись. Было очень много про создание бинов и копания в «кишках» Spring’а. Таких докладов не хватает. И пусть мне в ближайшее время вряд ли пригодится создавать бины таким образом, все равно было очень полезно и интересно.

4. «Как мы сделали интеграционную шину вместо SAP и при чем тут Java». Ожидала от этого доклада намного большего, т.к. тема миграции с SAP близка к рабочим задачам и хотелось почерпнуть больше полезного. Но по моим ощущениям докладчики уделили больше внимания бюрократическим нюансам получения гос. сертификатов для работы с «чувствительными» данными, чем техническим нюансам реализации решения. Итого, получилось, что это единственный доклад конференции на котором я была и который не порекомендую.

5. «БД-укротитель». Очень полезный, интересный, динамичный доклад. Было и о типичных проблемах при работе с БД, и о работе с ORM, и о самой СУБД. Если подвести краткий итог доклада - пишите оптимальные запросы, устанавливайте границы транзакций, экономьте коннекшены и знайте внутреннее устройство СУБД которую используете (не надо думать что простого знания ORM достаточно). А еще рассказали о других докладах с других конференциях которые тоже стоит посмотреть. Пожалуй, это тот доклад который стоит пересмотреть вместе с кодом рабочего проекта.

6. «Вложенные сущности по требованию в API на Spring Data JPA». Докладчик рассказал о своем опыте миграции с OData на Spring. Послушать было интересно, но на вопрос из зала: «Стоило ли реализовывать такие «хотелки» фронта или пусть фронт все таки делает разные запросы для тех данных которые хочет получать, а не забирает все данные в одном API?», - докладчик ответил что еще раз он бы на такое не пошел и правильней было бы дорабатывать фронт 🙂

6. «Интегральное скерцо: как машины пишут музыку и поют». Единственный доклад про модную тему ИИ и тот был после официального закрытия конференции 🙂 Здесь не было ничего про Java, но послушать о том как музыку анализируют для работы с компьютерами и ИИ в частности было довольно интересно.

На этом конференция подошла к концу, но мне еще остался список докладов, которые я буду пересматривать и с этой, и с других прошедших конференций. Советую всем посещать такие события - это полезно, интересно, а еще и в качестве бонуса узнаешь больше о том какие есть проблемы и практики вне твой команды.
🔥41👍1
С удивлением узнала, что не во всех командах проводится код ревью. Поэтому сегодня хотелось бы уделить пару минут вопросу почему это важно и какие есть плюсы и минусы у этой практики.

Код ревью — это процесс, в ходе которого другие разработчики из команды изучают ваш код, ищут ошибки, предлагают улучшения и обсуждают возможные альтернативы. Это не просто формальный шаг в процессе разработки, а важное звено, способствующее повышению качества кода и улучшению коммуникации в команде. Результатом проведенного ревью является обратная связь по выполненной задаче: либо необходимость доработать код (need works), либо готовность задачи к последующему тестированию и релизу (approve).

Вот несколько причин, почему ревью кода необходимо проводить:

1. Обнаружение ошибок: даже самые опытные разработчики могут допустить ошибки, невнимательность никто не отменял. Код ревью помогает выявить потенциальные проблемы на ранних этапах разработки, что позволяет избежать серьезных проблем в будущем.

2. Обмен знаниями: в процессе код ревью разработчики могут узнать что-то новое или поделиться своим опытом. Это способствует обучению и развитию команды в целом. Поэтому ревьюерами должны быть все члены команды, даже джуниор разработчики. Не нужно бояться задавать глупые вопросы при ревью, нужно уметь получать пользу от кода своего коллеги. Не стыдно не знать, стыдно не хотеть знать 🙂

3. Улучшение качества кода: благодаря обратной связи от других разработчиков можно улучшить читаемость, эффективность и безопасность кода. Не весь код, который мы пишем, является хорошо читаемым для большинства членов команды, но к этому стоит стремиться и лучше чем ревью инструмента нет. Кстати, у улучшения качества кода есть приятные последствия - это упрощение и ускорение разработки в будущем, а также более высокая поддерживаемость кода.

4. Повышение ответственности: зная, что ваш код будут смотреть другие, вы скорее будете стараться писать его лучше и более тщательно.

5. Улучшение коммуникации: ревью кода способствует общению в команде, помогая разработчикам лучше понимать друг друга и работать более эффективно.

Есть всего два минуса и на мой взгляд они не значительны:

1. При разработке задачи на реализацию тратится чуть больше времени: нужно исправлять замечания или отвечать на вопросы коллег к пулл реквесту.

2. В задаче задействованы как минимум два разработчика: тот, кто делал задачу и тот, кто ее ревьювил и нужно закладывать время на ревью пулл реквестов у всех членов команды, примерно как дейли.

Таким образом, код ревью не только помогает создавать более качественное программное обеспечение, но и способствует развитию команды и повышению профессионализма каждого участника. Не стоит пренебрегать этим важным этапом разработки — ведь от него зависит успех всего проекта.
😁4🔥1
Посмотрела доклад Федора и Ильи Сазоновых «Добровольно-принудительный Spring» и мне понравилось, несмотря на то что было больше философии, чем практической пользы.
Суть доклада в том что с помощью популярных фреймворков Java сообщества (в частности Spring + Lombok) разработчикам стало очень легко и просто писать некачественный код, который нарушает SOLID. К сожалению, я вынуждена согласиться с этой мыслью. Например, видела код, который кое-как работает в продакшене, где все методы для API лежали в одном GOD классе (да, в одном классе и ‘/api/user‘, и ‘/api/book’, и ‘/api/cat’), был просто ApplicationController. Разработчики спокойно добавляют по 10+ зависимостей в класс и не видят проблем даже на уровне конструктора, потому что @RequiredArgsConstructor - и все хорошо.
Авторы утверждают что никакого ООП в современных проектах на Java + Spring нет и если хорошенько присмотреться, то мы увидим Pascal 🙃 И я даже соглашусь! Сейчас типичный код - это бин, который по факту является мешком для функций. А единственное отличие от Pascal’а - удобство тестирования. Значит им надо пользоваться изо всех сил. Выводы: «не использовать private и static методы», «не вызывать внутри бина его собственные методы», «тестировать фреймворки», - на мой взгляд спорные.
А вот быть осторожнее с DDD (domain driven development) и использовать TDD (test driven development) я соглашаюсь на все 100%. Потому что лучше написать и отлаживать код на тестах, которые все равно нужны, чем использовать SDD (swagger driven development) и потом все равно преодолевая огромное нежелание писать тесты 🙂
👏41🔥1
Наша команда разработки приступила к новому проекту, еще не полностью передав в сопровождение из разработки старый. Участвовать одновременно в двух сложно, но я всё же пока большую часть времени участвую в процессе передачи старого проекта, где нужно было обновить интеграционное взаимодействие. Часть сервисов остается в нашей команде, часть передается в другую. Там где раньше сервисы отдавали запросы в рамках одного кластера, теперь два разных кластера, а соотвественно нужны сертификаты, настройки istio и ACL… Вообщем много головной боли и дебага, чтобы понять что именно на инфраструктуре отвалилось, а из кода - это просто добавить возможность читать и писать в два разных сервера Kafka.

Но самая большая боль последних недель заключается в том что мы не можем стартовать новый проект с 21 Java и Spring Boot 3+ 🥲 С тем что мы не сможем использовать свежую версию языка было понятно давно - к нам его еще просто не завезли 😅 Да, Java есть в качестве образов для сборки, но поставить на свою машину чтобы писать код возможности нет. Получается бюрократический парадокс - мы можем привезти в прод код (который теоретически даже будет корректно работать) написанный на 21 версии, но писать будем в слепую - коммитить и запускать тесты на сборщике. Ладно, это грустно, но я уже успела даже смириться.

А вот что библиотека которую мы обязаны использовать не поддерживает 3+ версию Spring Boot’а узнали только в процессе того как долго и мучительно пытались завести болванку проекта. Ошибки были самые разнообразные, пришлось залезть в кишки библиотеки и увидеть что там используется более старая версия Apache Kafka. И именно конфликтующие версии зависимостей давали не понятные и странные ошибки. Пришлось идти к разработчикам библиотеки и узнавать как же так. Оказалось, что действительно, нужно использовать Spring Boot версии 2.7.4 максимум. Есть ли об этом хоть строчка в документации? Конечно, нет! Зато есть информация какую зависимость подтягивать, если у вас 3+ Spring Boot. Зачем, если это все равно не будет работать и только вводит в заблуждение? Потому что вдруг вы будете использовать эту библиотеку только для определенной второстепенной функциональности, где все заведется. Есть ли информация в документации что тогда первостепенная функциональность, для которой мы и обязаны использовать эту библиотеку отвалится? Конечно, нет! Как же так? Поправит ли это кто-то в документации, чтобы другие команды разработчиков не теряли человеко-часы на такие же ошибки? Нет, потому что «документация поставляется с дистрибутивом, а в августе этого года мы добавим поддержку Spring Boot 3+». Остается только оставлять комментарии к документации об этой истории для следующих команд.

В такие недели хочется просто пилить бизнес фичи и баг фиксы, только бы не чувствовать себя песчинкой, которую перемолола огромная бюрократическая машина. И вместо вывода: будьте готовы к таким ограничениям, если идете работать в большую компанию 🙂
🔥6🐳2👍1🫡1
На этой неделе у меня было 7 рабочих дней и мне не понравилось. Зато передача продукта на сопровождение прошла в итоге успешно и теперь я со спокойной душой исчезаю в отпуске, где планирую полностью переключиться. Приняла волевое решение не думать о работе и о даже о программировании, посмотрим что из этого получится.
👍10🗿2🔥1
После отпуска меня отправили выстраивать процессы разработки в смежной команде. Первым делом я начала анализировать кодовую базу и столкнулась с тем, что тестов на проекте нет вообще. Поэтому сегодня хотелось бы поговорить о важности unit тестов.

Мой опыт говорит о том, что если в проекте нет тестов, то нужно готовиться к плохой архитектуре и структуре проекта. Архитектура приложения прямо связана с удобством написания тестов, поэтому наличие качественных тестов зачастую также и гарантирует соблюдение грамотных архитектурных решений.

В целом, тесты - это еще и разновидность документации. Если тесты есть (еще и с понятным названием), то новому разработчику будет намного легче разобраться в коде.

Также тесты дают уверенность разработчикам (как старым, так и новым), что изменения и доработки в существующем функционале не сломают его.

Тесты, как это не парадоксально, уменьшают стоимость фичи. Потому что чем раньше получается отловить ошибку (например во время написания unit теста), тем меньше она стоит. А, если проблему нашли на стадии ручного тестирования или, еще хуже, в процессе эксплуатации продукта пользователями, то такая ошибка будет автоматически как минимум удваивать стоимость разработки.

Но нужно понимать, что тесты не дадут гарантии выявления всех ошибок. Потому что нет возможности проверить взаимодействие модулей или интеграционных систем.

В целом отказ от unit тестов приводит к росту ошибок в приложении. Причем, чем дольше вы будете отказываться от тестирования, тем сложнее будет потом разобраться в том, из-за чего все-таки возникли сложности.

Поэтому первым делом я взяла в работу задачу - закрыть технический долг и покрыть код тестами.
🔥13👍1
По мотивам прошедшей рабочей недели хочу снова написать о важности индексов и зачем прикладному разработчику понимать как работает СУБД, которую он использует.

Индексы или методы доступа - это специальные объекты базы данных, которые в основном помогают ускорить доступ к данным. В PostgreSQL существует более шести различных видов (с учетом расширений) индексов, но все они в итоге устанавливают соответствие между ключом и строками таблицы в которых этот ключ встречается, что помогает не сканировать всю таблицу полностью. Индексы - это тоже самое, что оглавление или предметный указатель в книге.
Но у всего есть своя цена, и цена индексов - это повышение затрат на их поддержание: вставка, удаление, обновление строк таблицы требуют перестроения индексов, причем в рамках той же транзакции. Кстати, благодаря механизму HOT, обновление тех полей таблицы, на которые индексов нет, не приводит к перестроению индексов.

Все это требует от прикладного разработчика при создании таблиц и столбцов таблиц также думать: а нужно ли мне тут создавать еще и индексы?

Когда индексы не нужны:
- по этому полю (или таблице) поиск выполняется крайне редко или вовсе отсутствует;
- в таблицу намного чаще осуществляются вставки (удаления, изменения) записей, а не поиск.

Когда индексы нужны:
- вы знаете что по определенным полям будет часто осуществляться поиск;
- если нужна сортировка;
- есть поля, объединенные с полями в других таблицах, которые часто используются в запросах по нескольким таблицам.

В среду на проекте, в котором я теперь работаю, запустили инициализирующую выгрузку бизнес данных из смежной системы. Мы ожидали поступления и сохранения 780 тысяч записей. К концу дня стало очевидно, что сохранение происходит слишком медленно, потому что к тому моменту сохранилось лишь 50 тысяч записей. По моим оценкам, полная загрузка должна была завершиться примерно через два дня после старта, что очень много для такого объема данных. В коде я увидела следующее: когда данные поступают, то отрабатывает метод поиска по двум полям, и если такая запись есть в базе - то выполняется её обновление, а если нет - сохранение новой. Удаление же не происходит никогда. Посмотрев в саму базу данных, индекса я не увидела. Очевидно, что он в такой ситуации прямо напрашивается.

Мы добавили индекс и загрузка данных сразу ускорилась в разы. За следующий час в базе уже стало 200 тысяч записей и загрузка успешно завершилась к концу дня. Инициализация ускорилась в 12,5 раз (сохранение 100 записей до добавление индекса отрабатывало 25 секунд, а после добавления всего лишь 2 секунды). Также упала нагрузка на CPU базы: до создания индекса она составляла 69,7%, после едва поднималась до 12%.

По итогу я ещё раз убедилась, что проставление правильных индексов - это такая же важная часть работы бэкенд разработчика, как и написание кода; приобрела материал для этого поста 🙂 и решила, что теперь буду начинать анализ проблем с БД на новом проекте с проверки индексов.
🔥101
На рабочем проекте мне нужно было провести smoke тест фичи, которую я закончила. Но дев стенд был занят и поэтому я захотела поднять Kafka локально. К сожалению, мне это не удалось - producer при попытке подключения постоянно получал ошибку: «nodename nor servname provided, or not known».

Проблема странная, я потратила около двух часов на попытки её решить.
А оказалось все очень просто - используемый мной образ bitnami/kafka:latest был не такой уж и latest 😅. Образ был скачен 520 дней назад.

После обновления образа проблема решились. Очередное доказательство для: «А вы пробовали выключить и снова включить?».
😁65👍4
Купила книгу, описание многообещающее: «Прочитав эту книгу, вы
- узнаете, как именно ваш мозг видит код;
- научитесь бегло читать и быстро усваивать код;
- убедитесь, что есть простые приемы позволяющие распутать самый сложный код;
- сможете навести порядок в любой, даже самой запущенной базе кода.»
Отдельно заинтересовал последний пункт, т.к. сейчас для меня он очень актуален.

Планирую читать вдумчиво и медленно, сразу применяя новые знания на практике, потому что судя по беглому взгляду на книгу, она полна упражнений, которые лучше не пропускать.
👍13🔥6
Читаю «Ум программиста».
Книга читается очень легко и приятно, не оторваться, а иногда вообще хочется разобрать ее на цитаты. Например, первое же предложение первой главы: «Замешательство — неотъемлемая часть программирования». Автор говорит о трех типах замешательства и связанных с этим когнитивных процессах. Я стала замечать, что в новом проекте сталкиваюсь чаще всего с тем, что мне не хватает информации (не знакомы бизнес процессы), и недостатком вычислительной мощности (код написан очень запутано).
Во второй главе автор предлагает очень интересное упражнение, которое можно использовать для самодиагностики вашего знания кода. Нужно выбрать кодовую базу, которую вы немного понимаете, но не знаете от начала и до конца. Выбрать метод в пол страницы и не более 50 строк. Затем поизучать код две минуты и попытаться воспроизвести его как можно точнее, не подглядывая. Когда будете уверены, что воспроизвели весь - сравните исходный код с результатом и порефлексируйте. Так как всегда легче запомнить то, что уже знакомо, вы сможете выявить знакомые и незнакомые паттерны проектирования, конструкции и концепции программирования, или же увидите что этому коду далеко до чистого(не очевидные имена переменных, методов и т.д.).
Я сделала это упражнение используя кодовую базу нового проекта и поняла, что рефакторить нужно именно в части снижения когнитивной сложности кода.
В третьей главе автор говорит о важности запоминания синтаксиса в долговременной памяти. И я с этим согласна, потому что если при написании кода приходится искать в интернете информацию по синтаксису, то из-за отвлечения первоначальная мысль может уже забыться. Так же очень важно регулярно повторять новую информацию, чтобы она уложилась в голове и не потерялась. Вообще, на эту тему подробней написано в книге Питера Брауна «Запомнить всё. Усвоение знаний без скуки и зубрежки» - рекомендую к прочтению.
👍8👨‍💻3
Продолжаю читать «Ум программиста».
В четвертой главе речь идет о том, какая когнитивная нагрузка возникает, когда мы читаем сложный код. В такой ситуации мозг сталкивается с естественными ограничениями рабочей памяти, мы не можем удержать большое количество данных в уме одновременно. Значит нужно свести к минимуму их объем. Чем яснее будет код, тем легче будет его обрабатывать. Самое основное, что приходит в голову - это рефакторинг. Но помимо него автор также предлагает два интересных инструмента:
1. Граф зависимостей - помогает понять фрагмент сложного кода, состоящего из нескольких связанных между собой частей.
2. Таблица состояний - запись промежуточных значений переменных в таблицу помогает читать код, который требует сложных вычислений.
Думаю, что современных IDE с этим отлично помогают и распечатывать код на бумаге совсем не обязательно. Но лично я в сложном коде иногда прибегаю к ручке и бумаге и рисую блок-схемы. Обычно мне это требуется, когда я встречаюсь с распределенными вычислениями.

Пятая глава про чтение кода. В ней автор начинает с ролей переменных, с которыми знакомы практически все разработчики. Вот только оказывается существует 11 ролей переменных! Про счетчики, константы, флаги, накопители и т.д. я как и все знала. Но, например, о переменной «бродяга» я не знала. Иногда просто не задумываешься, что их можно выделить в отдельную роль.
Также один из главных выводов, которые я почерпнула для себя - это довольно простая мысль: понимание текста кода (знание синтаксических концепций) и понимание плана (понимание цели автора кода) - это две большие разницы. С понимаем текста работать легче, ведь для этого нужно уложить знания по языку (фреймворку, библиотеке и т.д.) в долговременную память. А вот для понимания плана нужно, чтобы чистый код писала вся команда разработки, а не только один разработчик.

А еще было приведено довольно неожиданное для меня исследование с соответствующим выводом. Оказывается, что когнитивные способности, указывающие на склонность к программированию - это в первую очередь рабочая память и логическое мышление (тут пока ожидаемо все). Но во вторую очередь помогают языковые способности и только потом математические. Я была уверенна что второе и третье место должны стоять наоборот. Однако, приведенные доказательства меня убедили. Стратегии, использующиеся для углубленного понимания текстов на естественном языке, например визуализация (вот кстати и про блок-схемы!) и резюмирование, могут использоваться и для углубленного понимания кода. Активней пишем документацию к коду, это поможет нам быть лучшими разработчиками во всех смыслах 🙂
Интересно, а ведение блога тоже поможет писать код лучше?
🔥10👍5