Этот блог — о моём пути в IT. Меня зовут Алексей, я .NET разработчик.
🇬🇧 English below.
Здесь я пишу о разработке на C# и .NET, оптимизации производительности, автоматизации инфраструктуры и о жизни в эмиграции.
📍С 2022 года работаю в австрийской компании, проживаю в Сербии. Владею английским, изучаю сербский и немецкий.
📌 Ссылки:
Блог: alexeyfv.xyz
GitHub: github.com/alexeyfv
Habr: habr.com/ru/users/alexeyfv
LeetCode: leetcode.com/u/alexeyfv
LinkedIn: www.linkedin.com/in/alexeyfv
Посты публикуются обычно раз в неделю, но всё зависит от объёма материала.
💬 Если заметили ошибку или хотите обсудить тему — пишите комментарии!
---
This blog is about my journey in IT. My name is Alexey, and I’m a .NET developer.
Here, I write about C# and .NET development, performance optimization, infrastructure automation and about living abroad.
📍 Since 2022, I’ve been working at an Austrian company while living in Serbia. I speak English and am learning Serbian and German.
📌 Links:
Blog: alexeyfv.xyz
GitHub: github.com/alexeyfv
Habr: habr.com/ru/users/alexeyfv
LeetCode: leetcode.com/u/alexeyfv
LinkedIn: www.linkedin.com/in/alexeyfv
New posts are usually published once a week, but it depends on the depth of the topic.
💬 If you spot a mistake or want to discuss a topic, feel free to comment!
🇬🇧 English below.
Здесь я пишу о разработке на C# и .NET, оптимизации производительности, автоматизации инфраструктуры и о жизни в эмиграции.
📍С 2022 года работаю в австрийской компании, проживаю в Сербии. Владею английским, изучаю сербский и немецкий.
📌 Ссылки:
Блог: alexeyfv.xyz
GitHub: github.com/alexeyfv
Habr: habr.com/ru/users/alexeyfv
LeetCode: leetcode.com/u/alexeyfv
LinkedIn: www.linkedin.com/in/alexeyfv
Посты публикуются обычно раз в неделю, но всё зависит от объёма материала.
💬 Если заметили ошибку или хотите обсудить тему — пишите комментарии!
---
This blog is about my journey in IT. My name is Alexey, and I’m a .NET developer.
Here, I write about C# and .NET development, performance optimization, infrastructure automation and about living abroad.
📍 Since 2022, I’ve been working at an Austrian company while living in Serbia. I speak English and am learning Serbian and German.
📌 Links:
Blog: alexeyfv.xyz
GitHub: github.com/alexeyfv
Habr: habr.com/ru/users/alexeyfv
LeetCode: leetcode.com/u/alexeyfv
LinkedIn: www.linkedin.com/in/alexeyfv
New posts are usually published once a week, but it depends on the depth of the topic.
💬 If you spot a mistake or want to discuss a topic, feel free to comment!
👏4
По совету знакомого прочитал книгу Learning Domain-Driven Design
Могу сказать, что это очередная книга, которая перевернула моё сознание как разработчика.
Основные моменты, которые я вынес для себя из этой книги:
1⃣ Если пишете новый проект и он сложнее Hello World, то нет никаких причин по которым вам следует использовать Anemic Domain Model. Почему? По моему опыту, когда используется анемичная модель (т.е. разделение данных и логики), то вся бизнес логика размазывается по всевозможным сервисам, которые могут иметь название Services, Utilities, Managers, Engines, Handlers и т.д. Кто-нибудь мне может сказать не глядя в код, в чем различие Service от Manager или от Handler? В DDD есть чёткое разделение слоев и функционала со своими naming conventions. По идее, перейдя в другой проект с DDD ты сходу разберёшься какой код за что отвечает.
2⃣ Вытекает из предыдущего пункта. Если у нас анемичная модель (т.е. класс это набор get и set), то со вероятностью 99.9% у нас повсюду мапперы. Мы же хорошие программисты и не любим high coupling, а значит надо, например, разделить слой данных от доменного слоя через маппинг. В качестве примера приведу реальный сценарий чтения данных на одном и проектов где я работал:
0. Данные читаются из БД в Database Object (DBO).
1. DBO маппится в доменную модель.
2. Доменная модель доходит до контроллера и там маппится в Data Transfer Object (DTO)
3. Клиент принимает результат HTTP запроса и парсит JSON в свой DTO.
4. Затем клиент маппит клиентский DTO в клиентскую доменную модель.
В итоге, имеем: DBO, серверную доменную модель, серверный DTO, клиентский DTO, клиентскую доменную модель. Все классы содержат примерно одинаковый набор свойств и весь этот зоопарк надо поддерживать, а это только GET запрос. Представьте что будет для POST?
3⃣ Переход от Anemic Domain Model к Rich Domain Model естественным образом приводит проект к Event Sourcing и CQRS. Почему так происходит? Потому что если доменная модель содержит логику, то нужно что-то, что будет вызывать эту логику. В дело сразу же вступают команды, а за ними и события, а если проект относительно сложный, то появляются хранилища событий, проекции и т.д.
✍ Книга в целом понравилась. Хочу закрепить свои знания в области DDD, поэтому в скором времени планирую опубликовать целый цикл статей по этой теме.
Могу сказать, что это очередная книга, которая перевернула моё сознание как разработчика.
Основные моменты, которые я вынес для себя из этой книги:
1⃣ Если пишете новый проект и он сложнее Hello World, то нет никаких причин по которым вам следует использовать Anemic Domain Model. Почему? По моему опыту, когда используется анемичная модель (т.е. разделение данных и логики), то вся бизнес логика размазывается по всевозможным сервисам, которые могут иметь название Services, Utilities, Managers, Engines, Handlers и т.д. Кто-нибудь мне может сказать не глядя в код, в чем различие Service от Manager или от Handler? В DDD есть чёткое разделение слоев и функционала со своими naming conventions. По идее, перейдя в другой проект с DDD ты сходу разберёшься какой код за что отвечает.
2⃣ Вытекает из предыдущего пункта. Если у нас анемичная модель (т.е. класс это набор get и set), то со вероятностью 99.9% у нас повсюду мапперы. Мы же хорошие программисты и не любим high coupling, а значит надо, например, разделить слой данных от доменного слоя через маппинг. В качестве примера приведу реальный сценарий чтения данных на одном и проектов где я работал:
0. Данные читаются из БД в Database Object (DBO).
1. DBO маппится в доменную модель.
2. Доменная модель доходит до контроллера и там маппится в Data Transfer Object (DTO)
3. Клиент принимает результат HTTP запроса и парсит JSON в свой DTO.
4. Затем клиент маппит клиентский DTO в клиентскую доменную модель.
В итоге, имеем: DBO, серверную доменную модель, серверный DTO, клиентский DTO, клиентскую доменную модель. Все классы содержат примерно одинаковый набор свойств и весь этот зоопарк надо поддерживать, а это только GET запрос. Представьте что будет для POST?
3⃣ Переход от Anemic Domain Model к Rich Domain Model естественным образом приводит проект к Event Sourcing и CQRS. Почему так происходит? Потому что если доменная модель содержит логику, то нужно что-то, что будет вызывать эту логику. В дело сразу же вступают команды, а за ними и события, а если проект относительно сложный, то появляются хранилища событий, проекции и т.д.
✍ Книга в целом понравилась. Хочу закрепить свои знания в области DDD, поэтому в скором времени планирую опубликовать целый цикл статей по этой теме.
❤2
🇷🇺 За пол года работы с Entity Framework Core я понял, что AutoInclude - это зло.
AutoInclude - это метод, конфигурирующий автоматическую загрузку связанных сущностей из базы данных. По-умолчанию, такие сущности не загружаются, т.к., очевидно, что это негативно сказывается на произвольности.
Да, у любого функционала есть своё назначение и при грамотном использовании он будет работать так, как надо, но именно только при грамотном использовании.
С большой долей вероятности, вы забудете, что в DbContext сконфигурирован AutoInclude для какой-то сущности и в какой-то момент производительность запросов начнёт стремительно падать. А когда решите отключить AutoInclude, то заметите, что существующий функционал выбрасывает ошибки, т.к. в нём ожидаются какие-то связанные данные.
Решение всех этих проблем: не ленится писать Include для каждого конкретного запроса, включая только те связанные сущности, которые нужны для этого запроса.
🇬🇧 After half a year I realized that AutoInclude is evil.
AutoInclude is a method that configures an automatic loading of related entities from the database. It's obvious, that these entities are not downloaded by default, because it affects on querying performance.
Yes, any functionality has its own purpose and with properly using, it will serve as designed, but only if using is proper.
I'm pretty sure, that you will forget, that AutoInclude was configured for some entity in DbContext and in some day the performance of the requests will slow down rapidly. And when you decide to remove AutoInclude, you'll face a bunch of errors, that were thrown by some functions, because they expect related data.
The solution for all these problems is to use Include for each query and include only those entities that are necessary for the specific request.
AutoInclude - это метод, конфигурирующий автоматическую загрузку связанных сущностей из базы данных. По-умолчанию, такие сущности не загружаются, т.к., очевидно, что это негативно сказывается на произвольности.
Да, у любого функционала есть своё назначение и при грамотном использовании он будет работать так, как надо, но именно только при грамотном использовании.
С большой долей вероятности, вы забудете, что в DbContext сконфигурирован AutoInclude для какой-то сущности и в какой-то момент производительность запросов начнёт стремительно падать. А когда решите отключить AutoInclude, то заметите, что существующий функционал выбрасывает ошибки, т.к. в нём ожидаются какие-то связанные данные.
Решение всех этих проблем: не ленится писать Include для каждого конкретного запроса, включая только те связанные сущности, которые нужны для этого запроса.
🇬🇧 After half a year I realized that AutoInclude is evil.
AutoInclude is a method that configures an automatic loading of related entities from the database. It's obvious, that these entities are not downloaded by default, because it affects on querying performance.
Yes, any functionality has its own purpose and with properly using, it will serve as designed, but only if using is proper.
I'm pretty sure, that you will forget, that AutoInclude was configured for some entity in DbContext and in some day the performance of the requests will slow down rapidly. And when you decide to remove AutoInclude, you'll face a bunch of errors, that were thrown by some functions, because they expect related data.
The solution for all these problems is to use Include for each query and include only those entities that are necessary for the specific request.
✍3
🇷🇺 Первая статья из серии про Domain-Driven Design (DDD). Начнём с простого рефакторинга кода с anemic domain model и перепишем используя паттерны DDD и rich domain model.
🇬🇧 The first article in the series about Domain-Driven Design (DDD). We'll start from simple refactoring of a code with anemic domain model and rewrite it using DDD patterns and rich domain model.
🇬🇧 The first article in the series about Domain-Driven Design (DDD). We'll start from simple refactoring of a code with anemic domain model and rewrite it using DDD patterns and rich domain model.
👍3❤1
Немного о сербском 🇷🇸
Поскольку сербский - это тоже славянский язык, то его, конечно, легче выучить, чем английский. Тут много похожих слов и фраз:
- числительные: jедан, два, три, десят, два десят, сто петдесят...
- дни недели, месяцы: понедельак, уторак, jануар, фебруар...
- здраво, довидженья
- добро jутро, добар дан
- местоимения: ja, ти, он, она, они...
Но во многом это совершенно другой язык, непохожий на русский. Слов, которые имеют абсолютно другое значение, тоже достаточно, например:
- "прямо" по-сербски будет "право", а "право" - "дЕсна", но "право" в значении "право на адвоката" будет также "право"
- "пОнос" - это не диарея, а гордость
- "сутра" значит завтра, а не "утром"
- "куча" - это "дом"
- "деда мраз" не ругательство, а дед мороз.
- "ужин" - это всего лишь перекус, а русский "ужин" - это "вечера".
- "бели лук" - это "чеснок", а привычный репчатый лук - "црни/црвени лук"
Ещё есть аналог глагола to be (бити, т.е. быть), который в русском редуцирован, а в сербском остался. Например:
- Jа сам из Руcиjе - Я из России (сам редуцирован)
- Ти си из Русиje - Ты из России (си редуцирован)
- Она je радила у IT компаниjи - Она работала в IT компании (je редуцирован).
Есть ещё много приколов с окончаниями и родом слов, но об этом как-нибудь в другой раз.
Поскольку сербский - это тоже славянский язык, то его, конечно, легче выучить, чем английский. Тут много похожих слов и фраз:
- числительные: jедан, два, три, десят, два десят, сто петдесят...
- дни недели, месяцы: понедельак, уторак, jануар, фебруар...
- здраво, довидженья
- добро jутро, добар дан
- местоимения: ja, ти, он, она, они...
Но во многом это совершенно другой язык, непохожий на русский. Слов, которые имеют абсолютно другое значение, тоже достаточно, например:
- "прямо" по-сербски будет "право", а "право" - "дЕсна", но "право" в значении "право на адвоката" будет также "право"
- "пОнос" - это не диарея, а гордость
- "сутра" значит завтра, а не "утром"
- "куча" - это "дом"
- "деда мраз" не ругательство, а дед мороз.
- "ужин" - это всего лишь перекус, а русский "ужин" - это "вечера".
- "бели лук" - это "чеснок", а привычный репчатый лук - "црни/црвени лук"
Ещё есть аналог глагола to be (бити, т.е. быть), который в русском редуцирован, а в сербском остался. Например:
- Jа сам из Руcиjе - Я из России (сам редуцирован)
- Ти си из Русиje - Ты из России (си редуцирован)
- Она je радила у IT компаниjи - Она работала в IT компании (je редуцирован).
Есть ещё много приколов с окончаниями и родом слов, но об этом как-нибудь в другой раз.
👍5👌1
❤🔥3❤2
Налоги в России и Сербии
Если сравнивать просто НДФЛ, то можно подумать, что работники в Сербии получают зарплату на руки больше, чем в России, т.к. НДФЛ в Сербии 10%, против 13% (15%) в России. На деле, сербская система налогообложения сложнее, чем российская. Ниже пояснения с расчётами для зарплаты в 1000€.
👨💻 Удержания с зарплаты работника
В России удерживают только НДФЛ по ставке 13% (15%).
На руки работник получит:
1000€ - 1000€ * 0.13 =
870€ (налог 130€)
В Сербии удерживают:
1. Налог на зарплату (порез на зараду) со ставкой 10%. Аналог нашего НДФЛ. Особенность сербского НДФЛ в том, что ставка применяется к зарплате за вычетом необлагаемой суммы. В 2023 году она составляет 21 712 динар (примерно 184.78€).
2. Взносы на пенсионное страхование и страхование по инвалидности (доприноса за пензиjско и инвалидско осигуранье) со ставкой 14%. Аналог взносов в ПФР.
3. Взнос по безработице (доприноса за незапосленост) со ставкой 0,75%. Прямого аналога в России нет.
4. Взносы на медицинское страхование (доприноса за здравствено осигуранье) со ставкой 5.15%. Аналог взносов в ФОМС.
На руки работник получит:
1000€
- (1000€ - 184.78€) * 0.1
- 1000€ * 0.14
- 1000€ * 0.0075
- 1000€ * 0.0515 =
719.48€ (налог 280.52€)
💼 Взносы от работодателя
Работодатель в России обязан ещё уплатить:
1. 22% в ПФР.
2. 2.9% в ФСС.
3. 5.1% в ФОМС.
1. 1000€ * 0.22 = 220€
2. 1000€ * 0.029 = 29€
3. 1000€ * 0.051 = 51€
Суммарно: 300€
В Сербии работодатель обязан уплатить:
1. 10% на пенсионное страхование.
2. 5.15 на обязательное медицинское страхование.
1. 1000€ * 0.1 = 100€
2. 1000€ * 0.0515 = 51.5€
Суммарно: 151.5€
☝️Итог
Несмотря на отличия в налогообложении, поступления в государственный бюджет примерно одинаковые: в России будет уплачено 430€, а в Сербии - 432.02€.
При этом, в Сербии 65% этих налогов заплатит работник, а в России всего 30%. Сербские работники получают около 72% от своих зарплат, когда как в России 87%.
При прочих равных, получается, что в России работником быть выгоднее.
Если сравнивать просто НДФЛ, то можно подумать, что работники в Сербии получают зарплату на руки больше, чем в России, т.к. НДФЛ в Сербии 10%, против 13% (15%) в России. На деле, сербская система налогообложения сложнее, чем российская. Ниже пояснения с расчётами для зарплаты в 1000€.
👨💻 Удержания с зарплаты работника
В России удерживают только НДФЛ по ставке 13% (15%).
На руки работник получит:
1000€ - 1000€ * 0.13 =
870€ (налог 130€)
В Сербии удерживают:
1. Налог на зарплату (порез на зараду) со ставкой 10%. Аналог нашего НДФЛ. Особенность сербского НДФЛ в том, что ставка применяется к зарплате за вычетом необлагаемой суммы. В 2023 году она составляет 21 712 динар (примерно 184.78€).
2. Взносы на пенсионное страхование и страхование по инвалидности (доприноса за пензиjско и инвалидско осигуранье) со ставкой 14%. Аналог взносов в ПФР.
3. Взнос по безработице (доприноса за незапосленост) со ставкой 0,75%. Прямого аналога в России нет.
4. Взносы на медицинское страхование (доприноса за здравствено осигуранье) со ставкой 5.15%. Аналог взносов в ФОМС.
На руки работник получит:
1000€
- (1000€ - 184.78€) * 0.1
- 1000€ * 0.14
- 1000€ * 0.0075
- 1000€ * 0.0515 =
719.48€ (налог 280.52€)
💼 Взносы от работодателя
Работодатель в России обязан ещё уплатить:
1. 22% в ПФР.
2. 2.9% в ФСС.
3. 5.1% в ФОМС.
1. 1000€ * 0.22 = 220€
2. 1000€ * 0.029 = 29€
3. 1000€ * 0.051 = 51€
Суммарно: 300€
В Сербии работодатель обязан уплатить:
1. 10% на пенсионное страхование.
2. 5.15 на обязательное медицинское страхование.
1. 1000€ * 0.1 = 100€
2. 1000€ * 0.0515 = 51.5€
Суммарно: 151.5€
☝️Итог
Несмотря на отличия в налогообложении, поступления в государственный бюджет примерно одинаковые: в России будет уплачено 430€, а в Сербии - 432.02€.
При этом, в Сербии 65% этих налогов заплатит работник, а в России всего 30%. Сербские работники получают около 72% от своих зарплат, когда как в России 87%.
При прочих равных, получается, что в России работником быть выгоднее.
❤5✍3
Технические статьи неспеша пишутся и пока не готовы, потому вот вам немного воскресных фоток из крепости Голубац, что в 140 км от Белграда.
🔥4