C# Portal | Программирование
13.9K subscribers
1.15K photos
126 videos
29 files
928 links
Присоединяйтесь к нашему каналу и погрузитесь в мир для C#-разработчика

Сотрудничество, реклама: @devmangx

Менеджер: @Spiral_Yuri

РКН: https://clck.ru/3FocB6
Download Telegram
This media is not supported in your browser
VIEW IN TELEGRAM
REST API vs WebSocket

REST API:

- Модель запрос–ответ
- Клиент отправляет запрос → сервер возвращает ответ
- Stateless (каждый запрос независим)
- Лучше всего подходит для CRUD-операций
- Использует HTTP/HTTPS
• Пример: получение данных пользователя, отправка форм

WebSocket:

- Двусторонняя связь в реальном времени
- Постоянное full-duplex соединение
- Stateful-соединение
- Лучше всего подходит для live-обновлений
- Использует протокол ws/wss
• Пример: чат-приложения, лайв-трейдинг, онлайн-игры

🟢REST = запросил → получил
🔵WebSocket = постоянное соединение и обмен данными в любой момент

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👏72
FluentValidation делает валидацию входных данных очень простой.

Знали ли вы, что валидаторы поддерживают DI (Dependency Injection)?

Вы можете внедрять объекты настроек, сконфигурированные через DI, и использовать их внутри валидаторов.

Посмотрите пример в сниппете кода ниже. 👇
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9🥴1
Непопулярное мнение:

Большинство разработчиков на самом деле не понимают Git.

Они знают только три команды:

1. git add
2. git commit
3. git push

Но Git может гораздо больше:

- ветвление (branching)
- rebase
- stash
- cherry-pick
- разрешение конфликтов (conflict resolution)

Правильное понимание Git может сэкономить часы отладки и исправления сломанных веток.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
😐21🥴51👎1
Используешь ли ты trunk-based development?

Это стратегия ветвления, при которой все разработчики работают напрямую в «trunk» (основной ветке).

Feature flags — обязательная часть такого подхода.

Незавершённые фичи прячутся за feature flag и выкатываются только тогда, когда они готовы.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5🤔31
Алгоритм ограничения запросов: Sliding Window Counter

Этот алгоритм — комбинация Fixed Window и Sliding Window.

То есть есть фиксированные окна, но поверх них «скользит» sliding window, которая постоянно проверяет, что текущее окно не превышает допустимое количество запросов (rate limit).

Базовая идея:

Например:

Как видно, есть два фиксированных окна и одно скользящее окно поверх них, которое отслеживает количество запросов внутри себя.

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

Формула:

effective_requests = current_window_count +
(previous_window_count × overlap_fraction)


Для overlap (перекрытия):

overlap_fraction =
remaining_time_in_previous_window / window_size


Объяснение overlap:

Представим два окна:

-> 1-е окно: с 1s до 10s
-> 2-е окно: с 10s до 20s

Допустим, мы находимся на 13-й секунде (то есть на 3 секунде второго окна).

Если смотреть назад, sliding window охватывает интервал от 3s до 13s (то есть захватывает 3 секунды из первого окна).

Часть предыдущего окна, которая попадает в sliding window — это промежуток с 3s до 10s. Это и есть overlap.

Соответственно:

-> берём запросы за последние 7 секунд из предыдущего окна (3s–10s)
-> и добавляем запросы за текущие 3 секунды из нового окна (10s–13s)

После этого проверяем: если суммарное количество превышает лимит — отклоняем запрос.

В итоге:
это всегда sliding window длиной, например, 10 секунд, которая «плавает» поверх фиксированных окон и динамически проверяет количество запросов.

Да, разобраться в этом не с первого раза — нормально 🙂

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
4😁2
Если вы хотите использовать Minimal APIs в более вертикально-срезовой (vertical slice) структуре, вот простая абстракция:

- интерфейс IEndpoint для определения эндпоинтов
- несколько методов-расширений для автоматической регистрации эндпоинтов

Цена на старте? Пара миллисекунд.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍52
Стоит ли Microsoft прекратить поддержку .NET Framework в Microsoft.Data.Sqlite в предстоящем релизе 11.0?

Обсуждение этого вопроса уже закрыто на GitHub, но Microsoft запрашивала мнение сообщества. (судя по скрину, комьюнити не против)

Проблема поддержки .NET Framework в GitHub SqLite: https://github.com/dotnet/efcore/issues/37895

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
4
Не отправляйте несколько SQL-команд в базу данных (PostgreSQL) последовательно.

Вместо этого делайте так 👇

Когда у вас есть кейс, где вы добавляете новую запись и затем читаете её, обычно выполняются два SQL-запроса: INSERT и SELECT.

С точки зрения выполнения это нормально, но что насчёт таких факторов, как:

1/ сетевая задержка (network latency)
2/ количество round-trip’ов к базе данных

Это ведь легко может снизить производительность, верно?

К счастью, с Npgsql это не обязательно.

У этого провайдера есть фича под названием batching.

Batching — это отправка нескольких SQL-команд в PostgreSQL за один round-trip к базе данных, вместо того чтобы вызывать Execute отдельно для каждой команды.

В документации Npgsql это описано через использование NpgsqlBatch, который упаковывает несколько NpgsqlBatchCommand в один запрос к серверу.

Важная деталь: если вы не начали собственную транзакцию, Npgsql автоматически оборачивает batch в неявную транзакцию.

Если один из запросов падает, остальные не выполняются, а весь batch откатывается (rollback).

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6🍌2🔥1
В чем смысл System.Collections.Frozen по сравнению с System.Collections.Immutable?

Immutable-коллекции являются «неизменяемыми» в том смысле, что конкретный экземпляр коллекции нельзя изменить. Однако они поощряют мутации: не изменение самого экземпляра, а создание новых экземпляров на основе исходного. Поэтому у immutable-коллекций есть методы вроде Add и Remove, которые не изменяют исходный экземпляр, а вместо этого создают новый экземпляр, содержащий это изменение (в литературе такие коллекции часто называют «персистентными коллекциями»). В результате, помимо API, ориентированного на такие операции, реализации оптимизированы под подобные сценарии, в частности — под шаринг памяти между экземплярами.

Например, если у вас есть ImmutableDictionary<string, string>, то под капотом это древовидная структура данных, и при вызове Add создаётся новый ImmutableDictionary<string, string>, который шарит максимально возможную часть исходного дерева, добавляя только необходимые узлы для нового элемента. Это означает, что хотя ImmutableDictionary и «неизменяемый», он на самом деле не оптимизирован для быстрого чтения, например, TryGetValue — это операция O(log n).

С другой стороны, новые FrozenSet<> / FrozenDictionary<> действительно неизменяемые: у них нет API, который позволял бы или поощрял добавления, удаления и т.д. Они спроектированы только под те операции, которые вы с ними выполняете — чтение. Если вам не нужны API для каких-либо мутаций, можно просто использовать FrozenSet / FrozenDictionary.

Если вы планируете использовать их долго и готовы потратить больше времени на этапе построения, чтобы привести данные к форме, которая делает их быстрее для всех последующих чтений, можно передать optimizeForReading: true в соответствующие методы, и фабрика потратит больше времени на вычисление оптимального представления, чтобы последующие операции вроде TryGetValue выполнялись очень быстро. При этом не нужно думать о хранении данных таким образом, чтобы удешевить создание производных коллекций, так как API для подобных операций просто отсутствует.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
🍌6👎4🔥2
This media is not supported in your browser
VIEW IN TELEGRAM
Изучайте алгоритмы — наглядно

Отличная коллекция интерактивных алгоритмов, удобно разбитых по категориям. Рекомендуется посмотреть:

https://algorithm-visualizer.org

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👏43
Вот хороший пример использования перехватчиков (interceptors) в EF: отслеживание того, когда ваши сущности были созданы или изменены.

Вы можете использовать ChangeTracker, чтобы проверить состояние сущности и установить соответствующие поля.

Если вы всегда используете этот DbContext в рамках HTTP-запроса, вы даже можете передавать UserId.
👍4👏2
Обработка «сырого» исключения базы данных при нарушении уникального ограничения приводит к появлению некрасивого DbUpdateException с вложенным provider-specific исключением, которое приходится по-разному парсить для SQL Server, PostgreSQL и SQLite.

Библиотека EntityFramework.Exceptions решает эту проблему.

https://github.com/Giorgi/EntityFramework.Exceptions

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
😁1
16 полезных сайтов, которые сделают тебя лучшим разработчиком:

1. roadmap.sh — дорожные карты для изучения dev-ролей
2. explainshell.com — объясняет каждый флаг в bash-командах
3. regex101.com — тестирование и отладка регулярных выражений с live-обратной связью
4. jsoncrack.com — превращает сырой JSON в визуальную диаграмму
5. bundlephobia.com — показывает размер npm-пакета до установки
6. transform.tools — мгновенно конвертирует между форматами для разработки
7. webhook.site — live URL для логирования webhook-запросов
8. devhints.io — шпаргалки по языкам и инструментам
9. httpie.io/app — браузерный HTTP-клиент для работы с API
10. caniuse.com — проверка поддержки CSS и JS в браузерах
11. squoosh.app — сжатие изображений прямо в браузере
12. carbon.now.sh — превращает код в аккуратные скриншоты
13. overapi.com — одностраничные шпаргалки по разным темам
14. shortcuts.design — горячие клавиши для популярных dev-инструментов
15. tinywow.com — бесплатный конвертер файлов
16. getfluently.app — прокачка разговорного английского с помощью AI

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥73👍3🍌1
CA1507: Используйте nameof вместо строкового литерала

У кого включено это правило анализа кода?

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍16👏1🍌1
Инжект настроек в .NET

У тебя есть 3 основных интерфейса на выбор. Но если выбрать не тот — приложение может просто игнорировать изменения конфигурации.

Вот простое объяснение:

1️⃣ IOptions
• Считывается один раз при старте приложения
• Кэшируется на весь жизненный цикл
• Подходит для статичных настроек, которые не меняются

2️⃣ IOptionsSnapshot
• Пересчитывается на каждый запрос
• Подхватывает изменения в appsettings.json без перезапуска
• Идеален для web API (Scoped lifetime)

3️⃣ IOptionsMonitor
• Обновляется в реальном времени
• Триггерит событие при изменении настроек
• Подходит для фоновых сервисов (Singleton lifetime)

Правило большого пальца (Rule of Thumb):
Используй IOptions для статической конфигурации.
Переходи на IOptionsSnapshot в веб-приложениях.
Используй IOptionsMonitor, когда нужны уведомления об изменениях в background-задачах.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
10🍌2
Мой любимый способ конфигурировать Serilog — через настройки приложения.

Можно настраивать уровни логирования, внешние sinks, enrichers и многое другое.

Это также значит, что конфигурацию Serilog можно менять без изменений в коде.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥6👏1
Большинство .NET-разработчиков реализуют кэширование сложным способом.

Они пишут шаблонный (boilerplate) код в каждом методе сервиса — проверяют кэш, делают запрос к базе, сохраняют результат, обрабатывают время жизни.

Есть способ лучше, который почти не требует изменений в коде.

Он называется Output Cache middleware в ASP.NET Core.

И работает он совершенно иначе, чем IMemoryCache или IDistributedCache.

Ключевое отличие:

-IMemoryCache и IDistributedCache кэшируют объекты внутри кода приложения
- Output Cache перехватывает HTTP-ответ на уровне middleware, сохраняет его целиком и отдает повторно

При наличии кэша не вызываются ни обработчик endpoint’а, ни запрос к базе, ни бизнес-логика.

Что делает Output Cache мощным:

- Добавление кэширования одним атрибутом — без boilerplate-кода в сервисах
- Встроенный cache lock предотвращает проблему «thundering herd»
- Именованные политики задают поведение кэша централизованно
- Инвалидация по тегам позволяет сбрасывать группы связанных записей одним вызовом
- Опции VaryBy позволяют кэшировать отдельные ответы по заголовкам, query string, route-параметрам или кастомной логике

Но вот где большинство разработчиков ошибается:
Кэшируют ответы авторизованных API без разделения по пользователям
→ Данные пользователя A могут быть отданы пользователю B
→ Это реальная уязвимость безопасности

Читать гайд

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
8😁2
Ищешь альтернативу Postman?
Apidog — это all-in-one инструмент для работы с API.

✓ Проектируй и управляй спецификациями API
✓ Мокай и тестируй endpoints в одном месте
✓ Генерируй документацию автоматически
✓ Тестируй интеграции с ИИ, такие как ChatGPT

Доступен в веб-версии и приложении с бесплатным тарифом:

http://midu.link/apidog

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
4😁4
Что такое breaking change для API?

Вот несколько примеров:

- Удаление или переименование API или параметров API
- Изменение поведения существующих API
- Изменение кодов ошибок API

Breaking change означает, что вам нужно версионировать API — иначе вы рискуете сломать существующих клиентов.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6😁1
Отличные ресурсы по системному дизайну
http://github.com/ashishps1/awesome-system-design-resources

Что внутри:

1. Базовые концепции — теорема CAP, консистентное хеширование, масштабируемость, доступность
2. Основы сетей — DNS, балансировка нагрузки, модель OSI, WebSockets
3. Глубокое погружение в базы данных — шардирование, репликация, SQL vs NoSQL
4. Разборы реальных систем — Twitter, Netflix, Uber, Google Drive
5. Включены диаграммы и примеры реализации кода

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
3🍌2