C# Portal | Программирование
13.3K subscribers
1.28K photos
131 videos
31 files
997 links
Присоединяйтесь к нашему каналу и погрузитесь в мир для C#-разработчика

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

Менеджер: @Spiral_Yuri

РКН: https://clck.ru/3FocB6
Download Telegram
Автор статьи разбирает лучшие практики безопасности REST API в ASP.NET Core.

За годы работы он выпустил и проверил множество .NET API и собрал 18 практик, которые, по его опыту, постоянно помогают держать такие системы безопасными.

В статье есть примеры кода и разбор HTTPS, JWT, политик авторизации, принципа минимальных привилегий, валидации входных данных, защиты от over-posting, ограничения размера запросов, параметризованных запросов и EF Core, rate limiting, CORS, CSRF, хранения секретов, логирования и других базовых мер.

Антон также предлагает сохранить статью как dotnet-security-review-skill для ИИ-агентов и прогнать по ней существующую кодовую базу.

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

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
7🍾1
Летняя уборка в базе данных. Теперь пора посмотреть на сами запросы.

pg_stat_statements отслеживает форму запросов, количество вызовов и время выполнения по всей базе. Это самый короткий путь от «база почему-то тормозит» до «вот эти пять запросов съедают большую часть времени».

Включаем pg_stat_statements

Если вы используете Crunchy Bridge, расширение уже доступно по умолчанию и можно сразу переходить к CREATE EXTENSION.

При самостоятельном размещении нужно изменить postgresql.conf и перезапустить PostgreSQL

shared_preload_libraries = 'pg_stat_statements, ...'
pg_stat_statements.track = top


Можно указать top или all. Режим all также учитывает запросы внутри функций и процедур. top используется по умолчанию и отслеживает только запросы, выполняемые клиентами.

Затем включаем расширение для нужной базы

CREATE EXTENSION IF NOT EXISTS pg_stat_statements;


Ищем дорогие запросы

Для такой проверки обычно полезнее смотреть на суммарное время выполнения. Запрос средней тяжести, который вызывается миллионы раз, часто наносит больше вреда, чем один редкий медленный запрос.

SELECT
round(total_exec_time::numeric, 1) AS total_ms,
calls,
round(mean_exec_time::numeric, 2) AS mean_ms,
rows,
query
FROM pg_stat_statements
ORDER BY total_exec_time DESC
LIMIT 20;


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

Что означают столбцы

calls — сколько раз запрос выполнялся с момента последнего сброса статистики
total_exec_time и mean_exec_time — суммарное и среднее время выполнения в миллисекундах
rows — общее количество полученных или изменённых строк
query — нормализованный запрос с параметрами вида $1

Статистика копится до ручного сброса

SELECT pg_stat_statements_reset();


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

Что делать с найденными запросами

1. Запустить EXPLAIN с реальными параметрами. pg_stat_statements показывает форму запроса, но не план выполнения.
2. Проверить недостающие индексы, сбросы на диск из-за work_mem и слишком большое количество мелких запросов приложения вроде N+1.
3. После деплоя или добавления индекса сбросить статистику, дать системе поработать под реальной нагрузкой и проверить, уменьшилось ли суммарное время выполнения.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
🍾1
Микросервисы сильно изменили то, как мы создаём и масштабируем приложения.

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

И здесь возникает проблема. Как сервисам находить друг друга и надёжно взаимодействовать?

Жёстко прописывать IP-адреса и порты — плохая идея. Если экземпляр сервиса сменит адрес или появится новый, система может просто перестать работать.

Для этого и нужен Service Discovery.

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

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
4🔥2🍾1
Вот хороший пример использования перехватчиков EF:

— Отслеживание времени создания и изменения сущностей.

Через ChangeTracker можно проверить состояние сущности и заполнить соответствующие поля.

Если этот DbContext всегда используется в рамках HTTP-запроса, можно также передавать UserId.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
🍾1
Как сохранять объекты-значения в EF?

Допустим, у сущности Apartment есть Address, который вы реализовали как объект-значение.

EF позволяет настроить его как owned type, принадлежащий этой сущности. В результате Apartment и Address будут храниться в одной таблице базы данных, что может повысить производительность.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥5🍾1
Проводник — это место, где проходит огромная часть повседневной работы в Windows.

Открытие папок. Переименование файлов. Переключение между локальными и облачными данными. Правый клик, чтобы перейти к следующему действию. Когда всё это работает медленно, зависает или перегружено лишними элементами — это сразу заметно.

В сегодняшней сборке Windows Insider Microsoft ускорила запуск Проводника, сократила количество зависаний и задержек, улучшила мелкие повседневные детали и переработала контекстное меню по правому клику — теперь оно проще, быстрее и лучше настраивается.

Подробнее:
https://blogs.windows.com/windows-insider/2026/08/17/improving-file-explorer-context-menu-faster-simpler-and-more-customizable/

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
3🤣1🍾1
Импортируете CSV в Postgres? Используйте COPY или \copy.

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

Что важно знать:

FORMAT csv
Включает стандартный разбор CSV: запятые, поля в кавычках и экранированные кавычки.

Список целевых столбцов
Порядок столбцов в CSV редко совпадает с таблицей. Всегда указывайте целевые столбцы в том порядке, в котором они идут в файле. Postgres сопоставляет их по позиции, а не по имени из заголовка CSV.

HEADER / HEADER n
Пропускает строки заголовка. Обычный HEADER пропускает первую строку. Ожидается, что Postgres 19 позволит передавать число, например HEADER 2, чтобы пропускать несколько начальных строк.

DEFAULT 'string'
Позволяет сопоставить специальную строку в CSV, например '__DEFAULT__', с выражением DEFAULT соответствующего столбца.

Неуказанные столбцы
Столбцы таблицы, которые не указаны в списке целевых столбцов, автоматически получают DEFAULT или NULL.

Лишние столбцы в CSV
Postgres выдаст ошибку, если в CSV больше полей, чем указано целевых столбцов. Обрежьте файл или сначала загрузите данные в более широкую промежуточную таблицу.

NULL-значения
В формате csv стандартным представлением NULL является пустая строка без кавычек. Это можно изменить через NULL 'string'.

Обработка ошибок через ON_ERROR и REJECT_LIMIT
Исторически COPY останавливался на первой ошибке преобразования. В новых версиях появились:

ON_ERROR ignore в Postgres 17 — пропускает некорректные строки и сообщает их количество
REJECT_LIMIT n в Postgres 18 — задаёт максимальное число плохих строк при ON_ERROR ignore, после которого импорт будет остановлен
ON_ERROR set_null в Postgres 19 — заменяет некорректное поле на NULL вместо того, чтобы отбрасывать всю строку

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥1🍾1
Разработчик предложил официальную формальную семантику C# на Lean 4 — то есть основу, которая позволит строить машинно проверяемые доказательства для C#.

ИИ-агенты становятся очень хороши в написании кода — и очень хороши в том, чтобы его ломать.

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

И это уже становится практичным.

У Rust уже есть Aeneas → Lean. Microsoft Research использует его для формальной верификации SymCrypt. У Java и C тоже уже есть основа в формальной верификации.

C# не должен остаться позади.

ИИ может написать код.
ИИ может построить доказательство.
А детерминированное ядро проверки доказательств проверит, действительно ли это доказательство корректно.

Это совсем другая модель доверия по сравнению с

ИИ пишет код → ИИ проверяет код → надеемся, что оба оказались правы.

Предложение: https://github.com/dotnet/csharplang/discussions/10314

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2🍾1
Андерс Хейлсберг — создатель TypeScript и C#. На подкасте его спросили о том, как переписывание компилятора на Go позволило ускорить TypeScript примерно в 10 раз, и о том, как ИИ уже влияет на разработку ПО.

В выпуске

• Как переписывание компилятора дало ускорение в 10 раз
• Почему выбрали Go, а не Rust
• Почему для миграции не использовали LLM
• Как ИИ повлияет на разработку ПО в будущем

https://www.youtube.com/watch?v=cywK3XYYJ2o

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
🍾3
C# 14 позволяет объединить проверку на null и присваивание в одну строку.

Раньше нужно было писать так:

if (customer is not null)
{
customer.Order = GetCurrentOrder();
}


Теперь оператор ?. можно использовать слева от присваивания:

customer?.Order = GetCurrentOrder();


Поведение то же самое. Если customer равен null, GetCurrentOrder() даже не вызовется.

Ещё несколько нюансов:

— работает и с +=, -= и другими составными присваиваниями
— не работает с ++ и --
— поддерживаются и ?., и ?[] слева от присваивания

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍16🍾2
C# 14 позволяет массивам, Span<T> и ReadOnlySpan<T> автоматически преобразовываться друг в друга.

Span<T> и ReadOnlySpan<T> уже повсеместно используются в среде выполнения ради производительности без ущерба для безопасности. В C# 14 компилятор получил полноценную поддержку преобразований между ними и T[]:

void PrintFirst(ReadOnlySpan<int> values)
{
Console.WriteLine(values[0]);
}

int[] numbers = [10, 20, 30];
PrintFirst(numbers);


Массив int напрямую передаётся в параметр ReadOnlySpan<int> — никаких явных вызовов преобразования.

✔️ Преобразования работают между ReadOnlySpan<T>, Span<T> и T[]

✔️ Типы Span теперь могут выступать получателями методов расширения

✔️ Компилятору стало проще выводить обобщённые типы, когда массивы и Span используются вместе

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5🍾1
Эти заметки — структурированное руководство по собеседованиям по проектированию систем.

Внутри разбираются как базовые подходы к System Design, так и конкретные архитектуры: веб-краулеры, системы уведомлений, платёжные платформы и другие типичные задачи с собеседований.

https://github.com/liquidslr/system-design-notes

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