Microsoft выпустила первую предварительную версию .NET 11 с улучшениями во всех областях: рантайм, SDK, библиотеки, C#, ASP.NET Core, Blazor и .NET MAUI.
• Поддержка Zstandard compression для эффективного сжатия
• BFloat16 — новый тип с плавающей точкой для ML-сценариев
• Улучшения ZipArchiveEntry для работы с архивами
• FrozenDictionary теперь поддерживает collection expressions
• Расширенная поддержка Rune в String, StringBuilder и TextWriter
• MediaTypeMap для определения MIME-типов
• API верификации HMAC и KMAC
• Создание жёстких ссылок
• DivisionRounding для режимов целочисленного деления
• Happy Eyeballs в Socket.ConnectAsync для быстрого подключения по IPv4/IPv6
• Runtime Async — улучшенная асинхронность на уровне рантайма
• CoreCLR на WebAssembly — полноценный рантайм в браузере
• Расширение интерпретатора
• JIT-оптимизации производительности
• GC Heap Hard Limit для 32-битных процессов
• Поддержка архитектур RISC-V и s390x
•
dotnet run теперь интерактивно выбирает целевой фреймворк и устройство•
dotnet test поддерживает позиционные аргументы•
dotnet watch — горячая перезагрузка для изменений в ссылках и настраиваемые порты• C#: передача коллекций как аргументов
• C#: расширенная поддержка раскладки памяти
• F#: параллельная компиляция включена по умолчанию, ускорение компиляции вычислительных выражений, новые флаги
--disableLanguageFeature и --typecheck-only для FSI.📍 Навигация: Вакансии • Задачи • Собесы
#async_news
Please open Telegram to view this post
VIEW IN TELEGRAM
❤9🥰3👍2🤔1
Разработчики используют EF Core и передают
IQueryable по всему приложению, считая это эффективным подходом. Но такая практика создаёт серьёзные проблемы с архитектурой и сопровождением кода.IQueryable позволяет строить динамические SQL-запросы, выполняя фильтрацию на стороне БД, а не в памяти приложения:var startDate = new DateTime(2023, 1, 1);
// Плохо: загружаем всё в память, затем фильтруем
var allRecords = context.Purchases.ToList();
var filtered = allRecords.Where(p => p.Date > startDate).ToList();
// Хорошо: фильтрация выполняется базой данных
var filtered = context.Purchases
.Where(p => p.Date > startDate)
.ToList();
Второй подход быстрее и эффективнее. Но когда
IQueryable начинает путешествовать через слои приложения, возникают проблемы.Антипаттерн: распространение IQueryable.
Типичный сценарий — IQueryable передаётся через слои:
// Репозиторий
public class PurchaseRepository
{
public IQueryable<Purchase> GetAll() =>
_context.Purchases.AsQueryable();
}
// Сервис бизнес-логики
public class PurchaseService
{
public IQueryable<Purchase> GetActive() =>
_repository.GetAll().Where(p => p.Status == "Active");
}
// Контроллер
var userPurchases = _service.GetActive()
.Where(p => p.UserId == currentUserId);
// Представление
@foreach(var item in Model.Where(p => p.IsCompleted))
{
<!-- рендеринг -->
}
Проблемы:
• Логика доступа к данным размазана по всему приложению
• Нарушен принцип единственной ответственности
•
IQueryable наследует IEnumerable — код может не знать, что работает с запросом к БД• Исключения в runtime, если EF не может преобразовать код в SQL
• Сложное тестирование и отладка
Решить эти проблемы можно, к примеру, паттерном спецификация, или, если спецификации избыточны, передавайте выражения:
public interface IPurchaseRepository
{
Task<List<Purchase>> FindAsync(Expression<Func<Purchase, bool>> predicate);
}
// Использование
var purchases = await _repository.FindAsync(
p => p.IsCompleted && p.UserId == currentUserId);
Запрос по-прежнему выполняется в БД, но логика доступа к данным инкапсулирована.
💬 Как бы вы решили эту проблему
📍 Навигация: Вакансии • Задачи • Собесы
#sharp_view
Please open Telegram to view this post
VIEW IN TELEGRAM
❤8🤔5👍3
C#/.NET разработчик — 265 000 ₽. Удалёнка
Middle/Senior .NET Developer — от 3 000 до 3 500 $. Удалёнка
C#/.NET-разработчик — Удалёнка
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2
Удаленка — это не только про свободу выбора места работы, но и про умение создать условия для продуктивности.
📍 Навигация: Вакансии • Задачи • Собесы
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1👍1
🧑💻 Композиция функций в C#
Функциональное программирование — не просто академическая теория. Это парадигма, превращающая императивный спагетти-код в декларативные, тестируемые и поддерживаемые решения.
Проблема императивного кода:
Проблемы: смешанные обязанности, жёсткая связанность с БД, невозможность переиспользования, хрупкость при изменениях.
Композиционное решение:
Преимущества: единственная ответственность каждой функции, простота тестирования, композируемость, декларативный флоу.
Основа композиции — чистые функции без побочных эффектов:
Тест такой функции:
Начните с малого: замените один цикл на Map, один if/throw на Result. Паттерны быстро станут естественными, и ваша кодовая база скажет спасибо.
📍 Навигация: Вакансии • Задачи • Собесы
🐸 Библиотека шарписта
#il_люминатор
Функциональное программирование — не просто академическая теория. Это парадигма, превращающая императивный спагетти-код в декларативные, тестируемые и поддерживаемые решения.
Проблема императивного кода:
// Традиционный подход - может быть трудно читать и сложно тестировать
public OrderDto ProcessOrder(int orderId)
{
var order = _dbContext.Orders.Find(orderId);
if (order == null) throw new NotFoundException();
if (order.Status != "Pending")
throw new InvalidOperationException();
var customer = _dbContext.Customers.Find(order.CustomerId);
if (!customer.IsActive)
throw new InvalidOperationException();
var discount = customer.IsVip ? 0.1m :
order.Total > 1000 ? 0.05m : 0m;
order.FinalTotal = order.Total * (1 - discount);
_dbContext.SaveChanges();
return new OrderDto { ... };
}
Проблемы: смешанные обязанности, жёсткая связанность с БД, невозможность переиспользования, хрупкость при изменениях.
Композиционное решение:
public class OrderProcessingPipeline
{
private readonly Func<int, Task<Order?>> _loadOrder;
private readonly Func<Order, Task<Customer?>> _loadCustomer;
public async Task<Result<OrderDto, Error>> ProcessAsync(int orderId)
{
return await Result<Order, Error>
.FromNullable(await _loadOrder(orderId), Error.OrderNotFound)
.BindAsync(_loadCustomer)
.BindAsync(_validateStatus)
.BindAsync(_calculateDiscount)
.BindAsync(_persistOrder)
.MapAsync(_mapToDto);
}
}
Преимущества: единственная ответственность каждой функции, простота тестирования, композируемость, декларативный флоу.
Основа композиции — чистые функции без побочных эффектов:
public static class PricingFunctions
{
public static decimal CalculateDiscount(CustomerType type, decimal total) =>
type switch
{
CustomerType.Vip => total * 0.15m,
CustomerType.Premium => total * 0.10m,
_ => 0m
};
public static decimal ApplyTax(decimal amount, decimal rate) =>
amount * (1 + rate);
// Композиция
public static Func<CustomerType, decimal, decimal> CalculateFinalPrice =>
(type, total) => ApplyTax(total - CalculateDiscount(type, total), 0.08m);
}
Тест такой функции:
[Theory]
[InlineData(CustomerType.Vip, 1000, 918.00)]
public void CalculateFinalPrice_ReturnsExpected(CustomerType type, decimal total, decimal expected)
{
Assert.Equal(expected, PricingFunctions.CalculateFinalPrice(type, total));
}
Начните с малого: замените один цикл на Map, один if/throw на Result. Паттерны быстро станут естественными, и ваша кодовая база скажет спасибо.
📍 Навигация: Вакансии • Задачи • Собесы
#il_люминатор
Please open Telegram to view this post
VIEW IN TELEGRAM
❤8
📂 File-Scoped Namespaces
Cинтаксис file-scoped namespaces заменяет привычное объявление пространства имён со скобками на однострочное с точкой с запятой.
Раньше каждый файл в C# проекте начинался с namespace
Код становится более плоским. Вместо того чтобы начинать каждый класс с двух уровней отступа: namespace + class, вы сразу работаете с одним.
При рефакторинге, когда нужно переместить класс в другой namespace, старый подход требовал изменения строки с объявлением. В
Компилятор не видит разницы — это чисто синтаксический сахар. IL-код идентичен, производительность не меняется.
📍 Навигация: Вакансии • Задачи • Собесы
🐸 Библиотека шарписта
#sharp_view
Cинтаксис file-scoped namespaces заменяет привычное объявление пространства имён со скобками на однострочное с точкой с запятой.
Раньше каждый файл в C# проекте начинался с namespace
MyApp.Services { ... }, что добавляло один уровень отступа ко всему коду внутри. Теперь достаточно написать namespace MyApp.Services; в начале файла, и всё содержимое автоматически находится в этом пространстве имён без дополнительной вложенности.Код становится более плоским. Вместо того чтобы начинать каждый класс с двух уровней отступа: namespace + class, вы сразу работаете с одним.
При рефакторинге, когда нужно переместить класс в другой namespace, старый подход требовал изменения строки с объявлением. В
git diff это выглядело как замена всего файла, даже если логика класса не менялась. C новым подходом меняется только одна строка вверху.Компилятор не видит разницы — это чисто синтаксический сахар. IL-код идентичен, производительность не меняется.
📍 Навигация: Вакансии • Задачи • Собесы
#sharp_view
Please open Telegram to view this post
VIEW IN TELEGRAM
❤9👍8🥱2
🧑💻 Когда чистый код всё равно требует комментариев
Чистый код делает программу понятной без лишних объяснений. Но иногда комментарии необходимы, чтобы передать суть решений, которые не уместить в самих строках.
Роберт Мартин в книге «Чистый код» не запрещает комментарии полностью. Он против тех, что дублируют очевидное или устаревают со временем.
Когда комментарии спасают ситуацию
• Сложная логика или хак:
• Предупреждения о рисках:
• Указание на патенты, стандарты или тикеты в баг-трекере.
💬 Когда, по вашему мнению, ещё могут пригодиться комментарии в коде
📍 Навигация: Вакансии • Задачи • Собесы
🐸 Библиотека шарписта
#il_люминатор
Чистый код делает программу понятной без лишних объяснений. Но иногда комментарии необходимы, чтобы передать суть решений, которые не уместить в самих строках.
Роберт Мартин в книге «Чистый код» не запрещает комментарии полностью. Он против тех, что дублируют очевидное или устаревают со временем.
Когда комментарии спасают ситуацию
• Сложная логика или хак:
// Обход бага в IE11 с обработкой форм
if (isIE11()) {
polyfillFormSubmit();
}
• Предупреждения о рисках:
// Не трогать: изменение сломает кэш в проде до деплоя новой версии
cache.invalidateOnlyOnRestart();
• Указание на патенты, стандарты или тикеты в баг-трекере.
💬 Когда, по вашему мнению, ещё могут пригодиться комментарии в коде
📍 Навигация: Вакансии • Задачи • Собесы
#il_люминатор
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔4👍2🔥1
Разбираем вопрос с собеса, в этот раз про Span.
Span<T> даёт доступ к памяти без копий и аллокаций. Но почему его сделали ref struct с кучей запретов, и когда лучше взять Memory<T>?Ответ
📍 Навигация: Вакансии • Задачи • Собесы
#dotnet_challenge
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2🌚2😢1
Собираем фулл-хаус: 3 курса по цене 1
Хватит выбирать между «полезно», «модно» и «для души». Мы запустили механику, которая позволяет собрать кастомный стек навыков без удара по бюджету: покупаете один курс — два других забираете бесплатно.
В Enterprise ценится фундаментальность. Углубитесь в архитектуру и шаблоны проектирования для построения сложных систем или подтяните алгоритмы и структуры данных для технических интервью.
Для тех, кто хочет понимать математику ML-моделей (вне зависимости от языка) — полный набор по AI: от линала и ML-старта до разработки автономных агентов.
Ну и классика: обновлённый Python как второй язык для скриптов.
Собрать свой пак
Хватит выбирать между «полезно», «модно» и «для души». Мы запустили механику, которая позволяет собрать кастомный стек навыков без удара по бюджету: покупаете один курс — два других забираете бесплатно.
В Enterprise ценится фундаментальность. Углубитесь в архитектуру и шаблоны проектирования для построения сложных систем или подтяните алгоритмы и структуры данных для технических интервью.
Для тех, кто хочет понимать математику ML-моделей (вне зависимости от языка) — полный набор по AI: от линала и ML-старта до разработки автономных агентов.
Ну и классика: обновлённый Python как второй язык для скриптов.
Собрать свой пак
❤2
Target-typed new убирает дублирование типов при инициализации, а with-выражения делают иммутабельные обновления одной строкой кода.
Раньше при создании объекта приходилось дважды писать тип:
var user = new UserDto { ... }. Теперь достаточно User user = new() { ... }. Компилятор выводит тип из контекста — при возврате из методов, в параметрах, элементах коллекцийРабота с иммутабельными объектами традиционно требовала copy-конструкторов, Builder'а или AutoMapper. with-выражение создаёт поверхностную копию с изменением указанных свойств:
var updated = user with { Age = 31 }. Компилятор генерирует код копирования автоматически.📍 Навигация: Вакансии • Задачи • Собесы
#sharp_view
Please open Telegram to view this post
VIEW IN TELEGRAM
🥱17❤3👾2
Метод
ExecuteUpdate в EF Core ускоряет массовые обновления, но пропускает перехватчики и события SaveChanges. Это может сломать аудит изменений.Перехватчик
SaveChanges ловит изменения из трекера. Но ExecuteUpdate работает напрямую с БД и игнорирует его:public override async Task<int> SaveChangesAsync(CancellationToken ct = default)
{
// Захватывает изменения от SaveChanges
var entries = ChangeTracker.Entries()
.Where(e => e.State == EntityState.Modified);
// Но не от ExecuteUpdate!
}
Решение через ручной аудит
Добавляйте аудит вручную перед или после
ExecuteUpdate:await context.Products
.Where(p => p.CategoryId == categoryId)
.ExecuteUpdateAsync(s => s
.SetProperty(p => p.Price, newPrice)
.SetProperty(p => p.ModifiedAt, DateTime.UtcNow)
.SetProperty(p => p.ModifiedBy, currentUser));
// Отдельная запись аудита
context.AuditLogs.Add(new AuditLog
{
Action = "BulkPriceUpdate",
EntityType = "Product",
Details = $"Обновил CategoryId={categoryId}, цена={newPrice}"
});
await context.SaveChangesAsync();
Альтернативы для полного аудита
• Триггеры на уровне БД ловят все изменения, включая ExecuteUpdate. Минус — сложнее тестировать и отлаживать.
• Библиотеки расширения EF предлагают BulkUpdate с встроенным аудитом через опции UseAudit.
📍 Навигация: Вакансии • Задачи • Собесы
#sharp_view
Please open Telegram to view this post
VIEW IN TELEGRAM
❤6😁1
🔄 Дайджест недели
Коротко про события недели.
— Microsoft разрабатывает функцию перемещения панели задач в Windows 11
Функция ожидается летом 2026 года как часть усилий по улучшению репутации ОС.
— Linux 6.19
— Превью .NET 11
— Бустим рабочее место за 10 шагов
📍 Навигация: Вакансии • Задачи • Собесы
🐸 Библиотека шарписта
#async_news
Коротко про события недели.
— Microsoft разрабатывает функцию перемещения панели задач в Windows 11
Функция ожидается летом 2026 года как часть усилий по улучшению репутации ОС.
— Linux 6.19
— Превью .NET 11
— Бустим рабочее место за 10 шагов
📍 Навигация: Вакансии • Задачи • Собесы
#async_news
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1
Anonymous Poll
22%
Что там в новом превью
58%
Микросервисы на .NET
21%
Про Blazor
33%
Прожарка чистого кода Боба Мартина
16%
Всего понемногу
🌐 Forward или Reverse Proxy
Forward и Reverse прокси звучат похоже — оба это прокси. Но работают в противоположных направлениях и решают разные задачи. Давайте разберёмся.
➡️ Forward Proxy
Представьте, что вы хотите отправить письмо, но не хотите раскрывать свой обратный адрес.
Вы отдаёте письмо посреднику. Он отправляет его от своего имени. Получатель видит адрес посредника, а не ваш.
Forward прокси — это посредник между вами и интернетом.
Главное: целевой сервер не знает, что запрос пришёл от вас. Он видит только прокси.
Зачем его используют:
• Логирование всех запросов
• Блокировка нежелательных сайтов
• Экономия трафика через кеширование
• Контроль безопасности
➡️ Reverse Proxy — противоположная история
Теперь представьте большую компанию с множеством отделов.
Когда кто-то звонит в компанию, он попадает на секретаря. Секретарь решает, в какой отдел перенаправить звонок.
Звонящий не знает внутреннюю структуру компании. Он общается только с секретарём.
Reverse прокси — это секретарь для ваших серверов.
Клиент не знает, что за прокси находятся несколько серверов. Он видит только один публичный адрес.
➡️ Реальные примеры использования
1. Балансировка нагрузки
У вас 5 серверов с одним приложением:
Прокси распределяет запросы между серверами, чтобы ни один не был перегружен.
2. Единая точка входа
У вас микросервисная архитектура:
• API на порту 5000
• Frontend на порту 3000
• Админ-панель на порту 8080
• WebSocket сервер на порту 4000
Без reverse прокси пользователю нужно знать все эти порты. А с reverse прокси можно сделать так:
3. SSL/TLS
Вместо настройки HTTPS на каждом сервере, настраиваете один раз на прокси. Проще управлять сертификатами, меньше нагрузка на бэк.
4. Защита и безопасность
Внутренние серверы вообще не видны из интернета. Видна только прокси.
5. Кеширование
Статический контент: картинки, CSS и JS; можно кешировать на прокси. Не нужно каждый раз обращаться на бэк.
📍 Навигация: Вакансии • Задачи • Собесы
🐸 Библиотека шарписта
#sharp_view
Forward и Reverse прокси звучат похоже — оба это прокси. Но работают в противоположных направлениях и решают разные задачи. Давайте разберёмся.
Представьте, что вы хотите отправить письмо, но не хотите раскрывать свой обратный адрес.
Вы отдаёте письмо посреднику. Он отправляет его от своего имени. Получатель видит адрес посредника, а не ваш.
Forward прокси — это посредник между вами и интернетом.
Главное: целевой сервер не знает, что запрос пришёл от вас. Он видит только прокси.
Зачем его используют:
• Логирование всех запросов
• Блокировка нежелательных сайтов
• Экономия трафика через кеширование
• Контроль безопасности
Теперь представьте большую компанию с множеством отделов.
Когда кто-то звонит в компанию, он попадает на секретаря. Секретарь решает, в какой отдел перенаправить звонок.
Звонящий не знает внутреннюю структуру компании. Он общается только с секретарём.
Reverse прокси — это секретарь для ваших серверов.
Клиент не знает, что за прокси находятся несколько серверов. Он видит только один публичный адрес.
1. Балансировка нагрузки
У вас 5 серверов с одним приложением:
Клиент → Reverse Proxy → [Сервер 1]
→ [Сервер 2]
→ [Сервер 3]
→ [Сервер 4]
→ [Сервер 5]
Прокси распределяет запросы между серверами, чтобы ни один не был перегружен.
2. Единая точка входа
У вас микросервисная архитектура:
• API на порту 5000
• Frontend на порту 3000
• Админ-панель на порту 8080
• WebSocket сервер на порту 4000
Без reverse прокси пользователю нужно знать все эти порты. А с reverse прокси можно сделать так:
https://mysite.com/api → Сервер на :5000
https://mysite.com/ → Сервер на :3000
https://mysite.com/admin → Сервер на :8080
https://mysite.com/ws → Сервер на :4000
3. SSL/TLS
Вместо настройки HTTPS на каждом сервере, настраиваете один раз на прокси. Проще управлять сертификатами, меньше нагрузка на бэк.
4. Защита и безопасность
Внутренние серверы вообще не видны из интернета. Видна только прокси.
5. Кеширование
Статический контент: картинки, CSS и JS; можно кешировать на прокси. Не нужно каждый раз обращаться на бэк.
📍 Навигация: Вакансии • Задачи • Собесы
#sharp_view
Please open Telegram to view this post
VIEW IN TELEGRAM
👍18❤4🙏1
Вас просят поменторить нового разработчика. Давайте разберемся, когда это возможность, а когда — скрытая эксплуатация.
Идеальная ситуация
Компания доплачивает 15-20% к зарплате, джун быстро схватывает и задает умные вопросы. Вы получаете деньги, прокачиваете скилл объяснения. Все в плюсе.
Ловушка «помоги новенькому»
«Покажи, как тут все устроено» может быть и без доплаты, без официального оформления. Вы делаете две работы за одну зарплату. Времени уходит 5-10 часов в неделю, дедлайны остаются прежними. Через месяц выгорание и раздражение на джуна, хотя он не виноват.
Выход: либо официальное оформление с корректировкой нагрузки, либо вежливое «сейчас не могу взять это на себя».
Человек не понимает базовых вещей после третьего объяснения, не гуглит, не пытается разобраться сам. Вы превращаетесь в костыль, каждый вопрос съедает время, а прогресса нет. Проблема часто не в способностях, а в мотивации или ошибке на этапе найма.
Честный разговор с лидом — это нормально. Менторство работает при наличии базы и желания учиться. Если база нулевая, это провал рекрутинга, не ваша ответственность.
📍 Навигация: Вакансии • Задачи • Собесы
#entry_point
Please open Telegram to view this post
VIEW IN TELEGRAM
❤3👍3