Telegram Web
Познакомился с занятным инструментом: Approval тестами. Понятно, зачем нужны юнит тесты: фиксировать работоспособное состояние бизнес логики. Понятно, зачем нужны интеграционные тесты: фиксировать работоспособное состояние нескольких компонентов системы.

А тут появляется ещё один достаточно удобный рубеж обороны от багов. Approval тест фиксирует состояние Api. Если каким-то образом были внесены любые изменения, меняющие контракт - тест будет заваливаться, пока изменения не будут в явном виде внесены в специальный файл и закоммичены.

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

#csharp
Небольшое наблюдение. Сейчас идёт седьмой крупный (от шести месяцев полной моей занятости) проект за мою карьеру в IT. Из них на трех у меня была полная свобода в плане написания тестов и возможности тянуть резину двигать сроки релиза.

Что характерно - именно эти три проекта, когда пришло время, просто запустились с минимальным предрелизным безумием. А все, где тестов не было - запускались с нервотрепкой и вычерпыванием бесконечного числа багов. При этом, основательный подход к разработке удлинял время от старта проекта до первого запуска в препрод процентов на 50-60. Вроде бы много.

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

#csharp
#tests
Подумал тут - насколько шикарный инструмент для сбора крайне интересных данных сайты типа https://jsonformatter.org и https://jsoncompare.org. Представляете - разработчик/тестировщик в недрах большой корпорации возится в json-е, возвращаемом каким-нибудь сервисом для запуска ядерных ракет для обработки персональных данных. А json здоровый и нечитаемый. Что-то не сходится, надо сравнивать, ну он и запуливает json на форматирование/сравнение.

Как по мне, одно из первых правил информационной безопасности - из внутренней сети этих сайтов быть не должно видно вообще.

#кодинг
#иб
Попал я на обучение постгресу. Достаточно продвинутый уровень, для миддл разработчиков и выше, ранее активно пользовавшихся MS SQL или Oracle. У меня основная СУБД в стеке - PostgreSQL, но интересного и нового довольно много. Далее будет что-то типа заметок, содержащих новые для меня вещи, которые я узнал.

1. Штатная среда для написания запросов для постгреса - PgAdmin, очень функциональна в плане администрирования базы. Я всю жизнь сидел на DataGrip. Она хороша для написания запросов, спору нет. Но для сложных вещей, связанных с администрированием - лучше использовать PgAdmin. Как минимум, многие запросы для администрирования (ограничения для пользователей, собственные типы данных) проще сгенерировать через UI чем по кусочкам собирать копипастя из документации. В дополнение там очень подробный визуализатор внутренних объектов базы: в ui можно посмотреть кастомные типы, расширения, инструменты для полнотекстового поиска. В DataGrip или Dbeaver все намного беднее в этом плане.

2. Очень понравилось что-то типа кастомного типа: Domain. Это унаследованный базовый тип с прикрученным к нему ограничением на диапазон значений. Например - терминал аэропорта. Предположим, есть терминалы A, B, C, D, E. Унаследуемся от текстового типа, поставим ограничение - только одна заглавная буква из этого диапазона.

3. Механизм TOAST. Когда размер поля в таблице превышает определенное (настраиваемое) значение, в таблицу пишется ссылка на элемент "теневой таблицы", куда собственно записываются данные из поля. Для типа text по дефолту это 2Кб. Максимальное значение - 1Гб, обусловлено особенностями самого постгреса. Для записываемого в теневую таблицу значения можно настроить механизм сжатия. Кроме простой экономии занимаемого места, достигается и буст производительности: при чтении данных из таблицы, например при полном сканировании, вместо тяжёлых значений читаются десятки байт, содержащих ссылку на нужное место теневой таблицы, куда постгрес полезет только в случае реальной нужды.

#postgresql
Продолжаю конспект интересных вещей, услышанных на обучении постгресу. Начало выше.

4. Механизм шардирования постгреса на партицированную таблицу, партиции которой - foreign table на других инстансах постгреса - нормальная практика, применяется, например, в Авито.

5. Постгресовский varchar от типа text под капотом отличается только наличием проверки на размер, потому если проверка на размер не нужна - просто используем text.

6. Для полнотекстового поиска я раньше использовал индекс Gin. Теперь я узнал, что можно настроить задержку на его дополнение при вставке данных, чтобы не задерживать пишущего.

7. Есть крайне полезное расширение для диагностики таблиц и индексов: pgstattuple. Ставишь его, делаешь select * from pgstatindex('my_index') и тебе выдаётся статистика, насколько разреженный индекс. И по этой статистике принимаешь обоснованное решение, пора ли индекс перестраивать.

8. Вместо limit + offset для пагинации возвращаемых результатов лучше использовать fetch: он гибче.

#postgresql
Продолжение заметок по новым фишкам постгреса, которые я узнал на обучении. Начало выше.

9. Я узнал о существовании фильтрованных индексов. Например, при создании btree индекса по дате указываешь > 01.01.2024 - и твой индекс будет работать только на данные в указанном тобой условии. Собственно, можно оставить архивированое в архиве и работать только со свежими данными.

10. Увидел на практике, как использовать хинты для оптимизации запросов. С хинтами забавная история: контрибьюторы постгреса встали стеной против введения их в ядро СУБД. Потому японский Ростелеком в какой-то момент реализовал их в виде расширения pg_hint, которое может поставить себе любой желающий, если ему дадут админы и безопасники:)

11. Узнал некоторые особенности индексов, о которых раньше не задумывался.
Хэш индексы немногим быстрее btree, но при этом лишены упорядочивания, ускорения запросов по интервалу, возможности сортировать таблицу по ним. Зато, если мы строим их по большим строкам, по которым надо будет искать только на условие равенства - они дают существенный выигрыш по размеру индекса. При этом, размер хэша меняется, подстраиваясь под данные так, чтобы был минимум коллизий.
Есть такой тип индекса - BRIN. Отлично работает для индексации неизменяемого вечнохранимого набора данных, ранжированных по какому-то параметру. Занимает мизерное пространство на диске, но в большинстве кейсов бесполезен.

#postgresql
Еще небольшая порция заметок про постгрес.

12. Параметры конфигурации, например work mem, можно менять непосредственно для пользователя. Соответственно, можно делать разные настройки для юзеров - аналитиков и юзеров, под которыми в базу ходят сервисы.

13. Узнал о существовании разных джоинов - hash, merge и nested loop join. Первый использует хэш таблицу, чтобы объединить данные из разных таблиц, второй - использует сортировки, третий тупо перебирает данные. Первый хорош для джоина неиндексированных данных. Второй берет сортировку исходя из индексов, соответственно хорош при наличии сортированных (btree) индексов по обеим колонкам, по которым осуществляется джоин. Третий хорош, чтобы сджоинить мизерную таблицу с большой.

14. Натуральные и латеральные джоины. Натуральный джоин бесполезен на мой взгляд. А вот латеральный очень интересен. Он позволяет склеить данные с близкими значениями, например склеить значения измерений температуры и влажности с чуть отличающимся временными метками.

#postgresql
Окончание заметок про постгрес.

15. Если у нас возник дедлок строки или какой-то запрос барабанит вечность - идем в представления pg_locks и pg_stat_activity, ищем источник проблемы и делаем с ним pg_cancel_backend или pg_terminate_backend.

16. Триггеры плохи не только сложностью отлова багов, но и тем что за счёт вызова доп функции на plsql, что трудозатратно.

17. Чистка мусора - vacuum - срабатывает автоматически при обновлении 20% записей. Можно подкрутить персональные настройки вакуумирования для таблиц.

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

#postgresql
Эшу быдлокодит
#dotnext, просмотр в записи. B-Tree индексы в PostgreSQL. Доклад получился крайне полезным: в связной легкодоступной форме пересказали то, что я в общем-то знал по устройству внутрянки BTree индексов. Кроме того, в процессе доклада всплыла ещё масса полезностей…
Нашел запись примерно того же доклада от того же автора, выкладываю тут. Наверное, это одна из самых толковых кратких лекций, которые я слышал за долгие годы.

Обучение, заметки из которого я выкладывал выше - более масштабное мероприятие длиной в неделю.

#postgresql
#ef_core
#db_design
#postgresql

Тонкости JSONB в PostgreSQL и EF Core: Как постичь дзен?

Сегодня мы рассмотрим работу с JSONB в базе данных PostgreSQL совместно с родной для .NET ORM от Microsoft — Entity Framework Core.

Мы разберём, как удобно хранить данные в денормализованном виде, как защититься от параллельных изменений и как поступать, когда необходимо выстраивать отношения между сущностями, чьи атрибуты упакованы в JSONB. Помимо этого, мы затронем такие темы, как optimistic concurrency, data encryption, миграции подобных сущностей и их версионирование.

Итак, начнём.

Тонкости JSONB в PostgreSQL и EF Core: Как постичь дзен?
Был в начале декабря на конференции Highload++ (да, только сейчас нашлось время оформить интересное услышанное в посты). Дальше посты будут под тегом #highload

Услышал ещё некоторые занятные вещи про постгресс.

Ситуация: таблица со счётчиками остатков товара на складе. На 100 строк, постоянно обновляется. При обновлении создаётся копия строки и хранится в блоке рядом с актуальной. В какой-то момент место в блоке кончается - приходится добавлять новую запись в индекс. В итоге под нагрузкой индекс забивается всяким мусором. Решение - индекс с датой последнего изменения, вычитывать последнее значение.

Есть у таблицы есть параметр vacuum_truncate. Разрешает вакууму освободить хвостик таблицы и отдать место ОС. Но есть нюанс - вакуум получает эксклюзивную блокировку таблицы на время пока он проверяет, что во всем кэше бд нет этих блоков и отдает их ОС. А если кэш бд - гигабайты - это может занимать минуты.

pg_stat_replication - посмотреть что происходит в репликации, какой из трёх занятых в ней процессов (отправка WAL по сети, прием WAL и складирование на диск, чтение и применение изменений к реплике) тормозит.

В постгресе 15+ prefetch при репликации по факту не используется, лучше отключить.

#postgresql
#conf
Продолжаю конспект интересных выступлений с конференции #highload

В Авито в качестве архитектурного паттерна используется "микросервисный ад", больше 4000 микросервисов. В итоге, чтобы понимать происходящее, они трассируют все запросы, а затем отправляют их в графовую базу neo4j, чтобы визуализировать все связи микросервисов и найти закономерности.

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

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

А самый глубокий запрос выстроился в цепочку длиной в 51 (!) микросервис, через http.

#conf
Ну чтож, пора подвести итоги года. В прошлом январе я писал планы. Итого, по пунктам:
1. Прочитал страниц 50 из Рихтера:)
2. DDD я покушал от души.
3. Не добрался
4. Не добрался
5. Не добрался
6. Не добрался
7. Не добрался

Э - эффективность, П - планирование.

Из позитивных итогов:
1. Вспомнил и прокачал SQL без ORM.
2. Познакомимся с чудесным продуктом для построения отчётов - FastReports. Теперь я точно знаю, что лучшее, что с ним можно сделать - удалить его к чёртовой матери.
3. Посмотрел и отрефлексировал многие глобальные вещи, касающиеся архитектуры и организации разработки.

Планы на 2025 надо будет тоже озвучить, но это несколько позже.
Продолжаю конспект интересных выступлений на #highload.

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

Спикер от hh рассказал об успешном применении другого подхода:
1. Монолит рефакторится так, чтобы выносимый в микросервис кусок был вынесен в отдельный модуль.
2. Модуль выносится в отдельный проект или пакет, одной строкой подключаемый в монолит.
3. Монолит начинает ходить в функционал будущего микросервиса сам к себе (!) по http.
4. После того, как убедились что все ок, модуль подключается в пустой проект, а в монолите меняется одна строка в конфигурации и он начинает ходить в микросервис.

#conf
Последний интересный доклад был про подход к описанию архитектуры системы - Enterprise architecture on a page. Спикер был из МТС. Суть доклада следующая - был взять относительно новый подход к описанию архитектуры системы, доработан под нужды МТС, а затем внедрен.

Интересна реакция аудитории: процентов 90 восприняли доклад "это что за бред?" А вот люди, близкие к архитектуре очень заинтересовались. Мне пока не хватает квалификации понять всю глубину идеи, но зачем оно нужно - более менее понятно. Для описания того, о чем вещал спикер просто приложу ссылку на исходную идею, получившую развитие в МТС.

#conf

P.S. Я сам до конца не проникся, ибо не дорос ещё
Посмешу богов уже в третий раз. Мои планы на 2025 год.

1. Традиционно не выполняющийся пункт - вернуться к чтению и конспектированию умных книжек.
2. Хочу вкатиться поглубже в шарповый ui фреймворк AvaloniaUI.
3. Традиционно не выполняющийся пункт - вкатиться в мир алгозадачек.

Наверное этого хватит:)
Спустя четыре года повторю опрос. А вам снится сессия или другие варианты экзаменов, не важно - ВУЗ или что-то другое?
Anonymous Poll
30%
Да
63%
Нет
7%
Посмотреть результаты
Пожалуй пришло время обновить закреплённый пост. Каналу уже 5 лет, с прошлого закрепа изменилось многое.

Датасаенс, питон и наука были заброшены. В настоящий момент я работаю сеньор C# разработчиком в одном из российских банков.

За прошедшие 5 лет я сменил 4 места работы:
1. Фирма, занимающая АСУ ТП в области учёта ресурсов.
2. Медтех стартап в Сколково, делали системы поддержки принятия врачебных решений.
3. Сеть общепита, делал бэкенд службы доставки.
4. Банк, текущее место работы. Работаю в домене клиентских карточек.

Мой технологический стек:
C#, PostgreSQL. Плотно работал с MongoDB, RabbitMQ, Tarantool, умею строить базовую инфраструктуру: логи (Loki), метрики (Prometheus), девопсятина (gitlab, gitea, github actions, docker).

Поверхностно знаком с Apache Kafka, MS SQL и фронтовыми фреймворками - React.js и AvaloniaUI.

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

Далее будет навигация по каналу.

Общие теги:
#csharp@eshu_coding - общий тег для постов про разные аспекты разработки на языке программирования c#
#postgresql@eshu_coding - разные интересные моменты про PostgreSQL.
#devops@eshu_coding - мои эксперименты в девопсятине и инфраструктуре.
#mongodb@eshu_coding - записки про MongoDB.
#tarantool@eshu_coding - заметки про Tarantool.

Pet - проекты:
#палантир@eshu_coding - завершенный проект, которым я занимался весь 2021 год - поисковик по телеграму.
#sphagnum@eshu_coding - попытка написать свой брокер сообщений, пока застопорилась на стадии изучения теории и прототипирования по причине нехватки времени.

Книги:
#рихтер@eshu_coding - заметки и конспекты по основополагающей книге про C# - CLR via C#. Программирование на платформе Microsoft .NET Framework 4.5 на языке C#, Джеффри Рихтер. Хоть .NET 4.5 вышел до моего появления в IT, внутренности платформы во основном остались прежними.

Конспекты прослушанных выступлений на конференциях:
#dotnext@eshu_coding - Dotnext 2023
#higload@eshu_coding - Highload++ 2024
Эшу быдлокодит pinned «Пожалуй пришло время обновить закреплённый пост. Каналу уже 5 лет, с прошлого закрепа изменилось многое. Датасаенс, питон и наука были заброшены. В настоящий момент я работаю сеньор C# разработчиком в одном из российских банков. За прошедшие 5 лет я сменил…»
2025/01/29 02:19:44
Back to Top
HTML Embed Code: