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

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

Менеджер: @Spiral_Yuri

РКН: https://clck.ru/3FocB6
Download Telegram
Когда кажется, что в Postgres уже не осталось того, чего он не умеет… 🐘

Да, даже полнотекстовый поиск.

И его можно подключить через EF Core.

С этим вы можете:

Настроить индексы для полнотекстового поиска
Писать эффективные поисковые запросы
Ранжировать и сортировать результаты по релевантности
Плавно интегрировать это в ваши .NET-приложения

https://www.milanjovanovic.tech/blog/how-i-implemented-full-text-search-on-my-website

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8🤩1
Большинство разработчиков могут назвать 10 типов тестирования.

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

Вот краткий разбор:

1. Smoke Testing (смоук-тестирование)
Приложение вообще запускается?

2. Functional Testing (функциональное тестирование)
Каждая функция возвращает корректный результат?

3. Integration Testing (интеграционное тестирование)
Модули продолжают работать корректно, когда они соединены между собой?

4. Regression Testing (регрессионное тестирование)
Последний коммит не сломал то, что ещё вчера работало?

5. Load Testing (нагрузочное тестирование)
Система справляется с реальным трафиком без «захлёбывания»?

6. Stress Testing (стресс-тестирование)
Что произойдёт, если нагрузку довести до предела?

7. Security Testing (тестирование безопасности)
Может ли кто-то воспользоваться уязвимостью, о которой вы не знали?

8. UI Testing (тестирование пользовательского интерфейса)
Интерфейс ведёт себя так, как ожидает пользователь?

9. Fuzz Testing (фазз-тестирование)
Что сломается, если отправлять приложению случайные или некорректные данные?

10. Reliability Testing (тестирование надёжности)
Система остаётся стабильной после работы в течение дней, а не минут?

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9🤔31🤩1
Встроенный пример IValidatableObject в ASP.NET
Кто-нибудь использует это?

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4👏4👨‍💻3
Вот как можно реализовать фильтр запросов на основе тенанта с использованием EF Core.

Вам понадобится сервис, который будет предоставлять TenantId для текущего тенанта. Это значение можно получить из заголовка запроса или клейма

Побочный эффект: вы сможете использовать DbContext только в рамках HTTP-запроса.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
3👍2👀2
Clean Architecture vs Onion Architecture vs Ports и Adapters

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👏1
Как создавать фоновые задачи в .NET?

С Quartz это так же просто, как реализовать интерфейс.

Вы можете внедрять любые необходимые зависимости через DI. Фоновые задачи также имеют scoped-область, поэтому можно даже внедрять DbContext.

[DisallowConcurrentExecution]
public class MyBackgroundJob : IJob
{
public MyBackgroundJob(...)
{
}

public async Task Execute(IJobExecutionContext context)
{
// Implement your logic here.
}
}


👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍82😁2👨‍💻1
Сделать столбец Sparse в Entity Framework 💡

В SQL Server sparse-столбцы — это обычные столбцы, оптимизированные для хранения значений NULL. Их использование может значительно экономить место.

Хорошими кандидатами для sparse-столбцов являются любые столбцы, у которых в большинстве строк вероятно будет значение NULL, например:

dateAccountClosed
discountAmount
Suffix
Address4
DeliveryInstructions
OrderReturnDate


и т. д.

Sparse-столбцы легко настраиваются в EF

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
1👏1
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