Русский
Открыть в Telegram
..NET Разработчик

.NET Разработчик

@NetDeveloperDiary · канал · Технологии · в индексе с 29.05.2026
6 772подписчиков
1 179средний охват поста
17.4%ER — охват к подписчикам
14постов за 30 дней
.
.NET Разработчик
Фотография
Фотография
Фотография
Фото 3 (с) Анатолий Кулаков
11 · 1.2K ·
.
.NET Разработчик
День 2800. Конференция DotNext 2026. Часть 2 Во второй день я посетил ещё два воркшопа. На первом открыл для себя великолепного докладчика Алексея Лосева из RWB. Человек с 20+ годами опыта, искромётным чувством юмора и прекрасной грамотной речью. Мы 2 часа «распиливали монолит», и я не заметил, как они пролетели. Алексей предложил спроектировать «упрощённую» систему обработки онлайн (или карточных) платежей в банке. От архитектуры всего решения до архитектуры системы (деталей взаимодействия сервисов). Воркшоп Алексея Лосева. Фото (с) JUG Ru Group А на втором воркшопе с Максимом Рогожниковым из Т-Банка с помощью Event Storming'а создавали простенький мессенджер. Вот что у нас получилось после полутора часов хождений вокруг доски с пачкой стикеров Первая попытка Event Storming'а Кроме того, я побеседовал с некоторыми партнёрами конференции. Зачем они приезжают, как отбирают представителей и как придумывают активности. Святослав Сычев (Mindbox) — Вы представляете Mindbox и уже не первый раз на DotNext. В чём задача компании? Зачем вам стенд на конференции? — У нас основной язык разработки – это .NET, соответственно, он идеально попадает в тему конференции. И поэтому мы здесь на самом деле не для того, чтобы прямо собрать воронку кандидатов, а для того, чтобы .NET-сообщество про нас узнало. И у людей, когда они соберутся искать работу, в том числе у каких-то очень крутых и сильных специалистов, в голове была информация: «Ага, где пишут на дотнете? Там, там, там и в Mindbox». — Но кандидатов вы не набираете? Здесь нет такой задачи? — Задачи закрыть какие-то позиции прямо сейчас у нас здесь нет. Либо это поиск каких-то уникальных специалистов. Если вдруг нам повезёт, такой специалист к нам подойдёт и скажет, что он очень хочет работать у нас, мы, наверное, что-нибудь придумаем, найдем какую-нибудь позицию. Но в случае с обычными разработчиками это скорее просто информация о том, что вот мы есть, вот мы классные, вот у нас крутые интересные технические задачи, … Читать полностью →
Длинный пост
фото и оформление — в Telegram ↗
7 · 1.5K ·
.
.NET Разработчик
День 2801. Конференция DotNext 2026. Часть 3 А ещё я поговорил с многолетним участником программного комитета DotNext Игорем Лабутиным. — В этом году на конференции много докладов про ИИ. Это позиция программного комитета или просто много таких заявок было? — Заявок было много, но на самом деле часть докладов мы в каком-то смысле искали проактивно в том числе. Потому что у нас было довольно много заявок о каком-то таком практическом ИИ: как работать с агентами, как применять конкретно в .NET. Вот как раз доклад Паши Федотовского ровно про это – как взять и руками что-то попробовать сделать. Но в том числе нам были нужны и доклады какого-то более общего характера. Именно отсюда появился кейноут Саши Поломодова. То есть, как всегда, программный комитет не просто пассивно обрабатывает заявки, но иногда ищет докладчиков, чтобы подсветить те или иные аспекты и составить более полную программу, так скажем, на наш скромный взгляд. — И в то же время, вот из поста Жени Пешкова: "Ушла тема про найм, карьеру, и про всё вот это вот". — Да, вот это, пожалуй, тема, которую, мне кажется, мы не то, чтобы сознательно когда-либо искали, она всегда появлялась сама. То есть к нам сами приходили ребята с заявками про то, как кого-нибудь нанять, как правильно пройти собеседование, систем-дизайн интервью, вот это всё. Сейчас я, с одной стороны, вижу в индустрии - или, может быть, у меня как-то так получилось, что вокруг меня - какое-то огромное количество всяких курсов по сисдизу. То есть, то ли вот это стало каким-то таким общим, популярным направлением, так скажем, про которое вроде как уже ничего откровенно нового в докладе не расскажешь, нужно делать скорее воркшопы. Ну вот сисдиз у нас в каком-то смысле есть, в формате воркшопов: распиливаем монолит, аутбоксы, even-storming – тоже, в каком-то смысле, подготовка и проработка требований. Ну, а найм… Какой найм, такие доклады… — С наймом плохо. — Ну, я не знаю, плохо или хорошо, но, видимо, рассказывать про него сейчас нечего. А… Читать полностью →
Длинный пост
фото и оформление — в Telegram ↗
3 · 1.3K ·
.
.NET Разработчик
День 2802. #Карьера #Юмор Секреты Программирования, Известные Только Легендам Ещё один пост из серии программистских советов, на этот раз менее серьёзный. Написание кода сегодня обходится дёшево: существует множество инструментов, готовых сделать это за вас. Выдающихся разработчиков отличает умение принимать верные решения. А это умение опирается на привычки, о которых обычно не пишут в учебниках. Большинство таких привычек рождается из ошибок, стоивших кому-то испорченной недели работы. Вы усваиваете их, выпуская код с багами или наблюдая, как старший коллега за минуту исправляет то, на что у вас ушёл целый день. 1. Лучший код — тот, который вы удаляете Пишите меньше кода, чем, как вам кажется, необходимо. Каждая добавленная строка становится вашей «собственностью» навсегда. Она может сломаться, для неё нужен тест, и когда-нибудь её будет читать другой человек. Чем больше кода, тем больше мест, где могут прятаться баги. Меньше кода — меньше затрат на поддержку и объяснения. Лучший пулл-реквест – тот, в котором удаляется больше строк, чем добавляется. 2. Если что-то сломалось, сначала ищите причину в своём коде Прежде чем винить чужой код, проверьте то, что написали сами. И чем свежее изменение, тем вероятнее, что ошибка именно в нём. Так вы быстрее найдёте баг и будете выглядеть более компетентным специалистом. 3. Тест, который никогда не падает, ничего не проверяет Зеленые тесты создают ложное чувство безопасности. И на этом часто обжигаются. Успешный тест бесполезен, если он не падает при поломке кода. Поэтому намеренно ломайте код, убедитесь, что тест стал красным, а затем исправляйте ошибку. 4. Пишите код для бедолаги, который будет его читать Компьютер выполнит любой код, а вот человеку придётся в нем разбираться. И этим человеком возможно будете вы. Вы в будущем — когда уже забудете, как всё это работает. Вы будете читать этот код гораздо чаще, чем писать. Так что облегчите себе жизнь. Хитроумный код приятно писать, но мучительно читать. Всегда выбирайте… Читать полностью →
12 · 1.2K ·
.NET Разработчик
Видео
2803.mp4 · 2.4 МБ
День 2803. #Оффтоп Чем Заняться, Пока Работают Агенты? У VS Code Есть Ответ Сейчас большую часть кода за вас пишут агенты. И тут возникает вопрос: чем занять освободившееся время? Можно изучить новый фреймворк, но это подозрительно напоминает работу. К счастью, у команды VS Code нашлась идея получше. Они предложили завести питомца. Что это? Это интерактивный персонаж, который располагается над полем ввода в чате. Он реагирует на активность в чате и на ваши действия. Пока агент работает, питомец наблюдает. Раньше вы смотрели на индикатор выполнения, делая вид, что контролируете процесс. Теперь есть с кем разделить это занятие. Примечание: этот питомец — экспериментальная функция, поэтому он может измениться или исчезнуть. Не привязывайтесь к нему слишком сильно. Как завести питомца Введите /vscode-pet в поле ввода чата, чтобы показать или скрыть его. Показать и скрыть — это все обязательства. Не нужны ни график кормления, ни ветеринар (по крайней мере, пока). Чем заняться - Кликнуть - чтобы вызвать реакцию. С клавиатуры: нажмите Tab, чтобы перевести на него фокус, а затем Enter или пробел. Да, питомец доступен для управления с клавиатуры. - Перетаскивать по области чата и оставлять там, где захотите (правда, он падает, если под ним ничего нет). - Начать перетаскивать и отпустить, чтоб подбросить. - С помощью клавиш со стрелками «влево» и «вправо» заставлять прыгать. - С помощью клавиш со стрелками «влево» и «вправо» при удержании Shift – бросать в стену. Да, у авторов своеобразное чувство юмора. Нажмите правой кнопкой мыши на питомца (или Shift+F10, когда он в фокусе), чтобы открыть контекстное меню, где можно: - посмотреть достижения, - отправить побегать, - изменить размер, - переключаться между цветовыми схемами. Достижения Это возможность оценить, насколько вы хороши как владелец питомца. Наконец-то есть показатель, который можно предъявить на следующей аттестации. За достижения питомцу дают различные головные уборы. Один питомец — множество сеансов В актив… Читать полностью →
18 · 1.1K ·
.
📊 Викторина
Как будет работать следующий фрагмент кода? #Quiz #CSharp
  • будет работать нормально всегда
  • выдаст ошибку компиляции
  • всегда будет выдавать ошибку времени выполнения
  • может сработать в среде разработки, но иногда выдавать ошибку в проде
5 · 1.6K ·
.
.NET Разработчик
День 2804. #ВопросыНаСобеседовании Марк Прайс предложил свой набор из 60 вопросов (как технических, так и на софт-скилы), которые могут задать на собеседовании. 48. Оптимизация производительности Entity Framework Core «Как бы вы оптимизировали производительность Entity Framework Core? Приведите конкретные примеры методов и настроек, которые вы бы использовали для повышения эффективности взаимодействия с базой данных». Хороший ответ Оптимизация Entity Framework Core включает в себя ряд стратегий, направленных на минимизацию накладных расходов и повышение скорости доступа к данным. Если в текущем контексте не требуется обновление данных, использование метода AsNoTracking позволяет существенно повысить производительность за счёт снижения накладных расходов на отслеживание изменений: var products = await dbContext.Products.AsNoTracking().ToListAsync(); Также полезно избегать использования ленивой загрузки (lazy loading) в ситуациях, которые могут привести к проблеме «N+1 запросов». Вместо этого лучше использовать явную или жадную загрузку (eager loading) для получения всех необходимых данных одним запросом: var order = await dbContext.Orders .Where(o => o.Id == orderId) .Include(o => o.OrderItems) .ThenInclude(oi => oi.Product) .SingleOrDefaultAsync(); Фильтрация данных, получаемых из базы, и ограничение их объёма только тем, что действительно необходимо. Применение фильтров на уровне БД (вместо извлечения всех записей и последующей фильтрации в оперативной памяти) позволяет существенно сократить задержки и снизить потребление памяти. Важно убедиться, что в БД корректно используются индексы для ускорения выполнения запросов — особенно для столбцов, часто фигурирующих в предложениях WHERE или условиях JOIN. Регулярное профилирование SQL-запросов, генерируемых EF Core, с помощью таких инструментов, как SQL Profiler или встроенные средства логирования, позволяет выявлять неэффективные запросы и оптимизировать их. Внедрение этих практик позволит значитель… Читать полностью →
14 · 1K ·
.
.NET Разработчик
День 2805. #ЧтоНовенького #NET11 Аргументы в Выражениях Коллекций в C#15 В C#15 реализовано точечное улучшение выражений создания коллекций: возможность передавать аргументы с помощью элемента `with(…)`, указываемого в начале выражения. Если вы уже используете выражения создания коллекций из C#12, это нововведение устраняет распространённое неудобство: теперь можно передавать аргументы (характерные для конструкторов или фабричных методов) непосредственно внутри […]. Сравнение C# версий 12, 13 и 15 C#12 - Добавлены выражения создания коллекций ([…]) и spread-оператор (..): int[] values = [1, 2, 3]; int[] all = [0, ..values, 4]; C#13 - Расширена поддержка params для разных типов коллекций (не только массивов) в параметрах методов: csharp public void LogValues(params Span<int> numbers) { // … } LogValues(1, 2, 3); C#15 - Добавлен элемент with(…) в начало выражений создания коллекций List<int> numbers = [with(capacity: 100), 1, 2, 3, ..more]; with(…) предоставляет аргументы для создания коллекции, где это поддерживается (параметры конструктора, построитель Create(…), отдельные сигнатуры интерфейсов). При этом with(…) должен быть первым элементом. Практические примеры 1) Предварительное определение размера коллекций для обеспечения читаемости и ясности намерений List<int> ids = [with(capacity: 256), ..sourceIds]; Это позволяет выполнить инициализацию в рамках одного выражения и делает ваш замысел очевидным. 2) Сценарии использования построителей коллекций Для построителей коллекций C#15 поддерживает дополнительные параметры метода Create(…): static MyCollection<T> Create(SomeOption option, ReadOnlySpan<T> items) { // … } Использование: Tags tags = [with(StringComparer.OrdinalIgnoreCase), "CSharp", "CSHARP", "csharp", "dotnet"]; Tags newTags = [with(), "CSharp", "CSHARP", "csharp", "dotnet"]; Tags oldTags = ["CSharp", "CSHARP", "csharp", "dotnet"]; [CollectionBuilder(typeof(Tags), nameof(Create))] internal sealed class Tags( string[] values, StringCom… Читать полностью →
5 · 1K ·
.NET Разработчик
День 2806. #ЗаметкиНаПолях Типы Коллекций в .NET, Которые Стоит Попробовать. Начало Большинство разработчиков ежедневно используют List<T> и Dictionary<TKey, TValue>. Однако в .NET есть и специализированные коллекции, способные сделать код быстрее, безопаснее и проще в сопровождении. Рассмотрим некоторые из них, о которых стоит знать каждому .NET-разработчику. 1. HashSet<T> Многие разработчики используют List<T> для проверки наличия элемента. if(users.Contains(id)) Проблема в том, что List.Contains() выполняет линейный поиск. HashSet<T> использует хэширование для гораздо более быстрого поиска: var permissions = new HashSet<string> { "Read", "Write", "Delete" }; Console.WriteLine( permissions.Contains("Write")); Где использовать: - выявление дубликатов, - проверка наличия прав доступа, - быстрый поиск. См. подробнее про HashSet 2. PriorityQueue<TElement,TPriority> Нужно первым делом обработать элемент с наивысшим приоритетом? Вместо того чтобы постоянно сортировать список, используйте PriorityQueue: var queue = new PriorityQueue<string, int>(); queue.Enqueue("Low", 3); queue.Enqueue("Medium", 2); queue.Enqueue("High", 1); while (queue.Count > 0) Console.WriteLine(queue.Dequeue()); // Вывод: // High // Medium // Low Где использовать: - планировщики заданий, - обработка задач, - алгоритмы маршрутизации, - поиск пути в системах ИИ, - моделирование событий. См. подробнее про PriorityQueue 3. ConcurrentDictionary<TKey,TValue> Обычный словарь (Dictionary) не является потокобезопасным. Если несколько потоков будут одновременно читать и записывать данные, это неизбежно приведёт к возникновению исключений или нарушению целостности данных. ConcurrentDictionary решает эту проблему: using System.Collections.Concurrent; var cache = new ConcurrentDictionary<int, string>(); Parallel.For(0, 1000, i => { cache.TryAdd(i, $"User {i}"); }); Console.WriteLine(cache.Count); Почему не использовать блокировку? Вместо: lock(_lock) { dictionary.Add(...); } Исполь… Читать полностью →
15 · 778 ·
.
Фотография
🦈 Открытое собеседование на Middle C# | 6 октября, 19:00 МСК Приглашаем на открытое собеседование: Senior C# разработчик проведёт его в прямом эфире. Можно посмотреть, как всё устроено изнутри, и понять, насколько ты готов к такому интервью. Как это будет: 📂 Собеседует Александр Моргунов — Senior C# разработчик, 7+ лет в европейских высоконагруженных сервисах. Отвечает разработчик-доброволец; 📂 Всё как на настоящем собесе: Александр задаёт те вопросы и задачи, которые даёт кандидатам на своих интервью. Заранее их никто не знает; 📂 После каждого ответа Александр даст обратную связь: что прозвучало сильно, а что стоило раскрыть иначе. Так станет понятнее, на что обращают внимание на собесе; 📂 В конце можно задать любой вопрос. Это бесплатно. Эфир проходит в рамках менторской программы от ШОРТКАТ для C# разработчиков, которые хотят повысить свой грейд, ЗП и прокачать скиллы. Переходи в нашего бота, чтобы получить ссылку на эфир -> @shortcut_csharp_bot Реклама. О рекламодателе.
5 · 955 ·
.
.NET Разработчик
День 2807. #ЗаметкиНаПолях Типы Коллекций в .NET, Которые Стоит Попробовать. Окончание Начало 4. ReadOnlyDictionary<TKey,TValue> Иногда требуется, чтобы потребители могли читать словарь, но не могли его изменять. ReadOnlyDictionary служит оболочкой для существующего словаря. var dict = new Dictionary<int, string> { [1] = "One", [2] = "Two" }; var readOnly = new ReadOnlyDictionary<int, string>(dict); Console.WriteLine(readOnly[1]); Попытки добавить или удалить элементы через обёртку не допускаются. Это простой способ безопасного предоставления доступа к данным через API «только для чтения». См. также ReadOnly-Коллекция не Является Неизменяемой 5. ImmutableArray<T> Иногда требуется коллекция, которую никто не сможет случайно изменить. Именно это и обеспечивает ImmutableArray<T>: using System.Collections.Immutable; ImmutableArray<string> roles = [ "Admin", "Manager", "Employee" ]; foreach (var role in roles) Console.WriteLine(role); Попытка изменить объект создаёт новый экземпляр вместо модификации исходного. Благодаря этому код становится гораздо проще анализировать. Где использовать: - конфигурации; - доменные модели; - разделяемое (shared) состояние приложения. См. также - Неизменяемые стеки и очереди - Неизменяемые списки - Неизменяемые множества - Неизменяемые словари 6. FrozenDictionary<TKey,TValue> Класс FrozenDictionary, появившийся в .NET 8, предназначен для хранения данных, которые не изменяются после создания. После инициализации коллекция становится неизменяемой и высокооптимизированной для операций поиска. Если ваше приложение при запуске загружает конфигурационные данные, коды стран, категории товаров или любые другие наборы данных, предназначенные только для чтения, эта коллекция может значительно превзойти по производительности обычный Dictionary: using System.Collections.Frozen; var countries = new Dictionary<string, string> { ["US"] = "United States", ["IN"] = "India", ["JP"] = "Japan" }; FrozenDictionary<string, string> … Читать полностью →
12 · 695 ·
.
.NET Разработчик
День 2808. #Карьера 5 Навыков, Которые Помогут Быстрее Стать Сеньором. Начало В ИТ есть секрет, о котором все знают, но редко говорят: годы опыта не делают вас сеньором автоматически. Быть им — не значит знать наизусть все методы стандартных библиотек или писать самые изощрённые алгоритмы. Это вопрос масштаба, влияния на проект и управления рисками. Джуны и мидлы сосредоточены на том, чтобы код просто работал. Сеньоры заботятся о жизнеспособности системы, эффективности команды и успехе бизнеса. Если вы хотите ускорить карьерный рост и преодолеть этот «потолок», нужно иногда отвлекаться от IDE. Вот неочевидные навыки, которые значительно ускорят ваш путь к позиции сеньора. 1. Системное мышление (выход за рамки «туннельного зрения» при выполнении задач) Когда мидл-разработчик получает задачу, он изучает требования и реализует то, что просят. Когда задачу получает сеньор, он оценивает систему целиком и анализирует, как новый элемент впишется в общую картину. Пример Поступает задача: отправлять пользователям email-уведомление при сбросе пароля. Мидл-разработчик подключает библиотеку для работы с почтой и встраивает логику отправки прямо в метод ResetPassword. Сеньор понимает, что со временем приложению могут понадобиться и другие каналы связи: SMS, push-уведомления, маркетинговые рассылки. Вместо того чтобы жёстко «зашивать» логику отправки email в код, он отделяет основную бизнес-логику от системы уведомлений. Почему это важно Системное мышление помогает избежать накопления технического долга. Если фокусироваться только на текущей задаче, можно создать хрупкий монолитный функционал. Умение видеть общую картину гарантирует, что код будет масштабируемым, удобным для тестирования и готовым к будущим изменениям. Как применять Прежде чем написать хоть строчку кода, задайтесь вопросами: «Что произойдёт, если нагрузку на эту функцию нужно будет увеличить в 10 раз?» или «Если я внесу эти изменения, что ещё может сломаться?» 2. Бескомпромиссная расстановка приоритетов (ис… Читать полностью →
6 · 347 ·
.
.NET Разработчик
День 2809. #Карьера 5 Навыков, Которые Помогут Быстрее Стать Сеньором. Окончание Начало 3. Эмпатия в коде (написание «скучных» решений) «Хитроумный» код — враг удобного в сопровождении кода. Если вы тратите пять минут на написание кода в одну строку, а вашему коллеге требуется час, чтобы его расшифровать, — значит, вы не справились с ролью старшего инженера. Пример Вам нужно отфильтровать список пользователей, преобразовать их данные и суммировать общую стоимость их покупок. Вы используете цепочку вызовов LINQ-функции, перегруженную вложенными тернарными операторами, — просто потому, что это выглядит эффектно и умещается всего в две строки. Почему это важно Опытные разработчики пишут код с расчётом на того, кто будет его поддерживать — часто это они сами, но спустя полгода, в два часа ночи, когда система вышла из строя. Код читают в десять раз чаще, чем пишут. Как применять Отдавайте приоритет читаемости, а не краткости. Используйте понятные имена переменных; если логика становится сложной, предпочитайте стандартные циклы запутанным функциям высшего порядка; пишите комментарии, объясняющие *почему* было принято то или иное решение, а не *что именно* делает код. 4. Мастерское владение инструментами мониторинга и отладки Мидл-разработчик может исправить ошибку, имея на руках стек-трейс. Сеньор способен исправить ошибку, даже если единственная информация — это жалоба клиента в Twitter о том, что «сайт сломался». Пример Система выходит из строя. Мидл-разработчик лихорадочно кликает по элементам приложения, пытаясь воспроизвести ошибку локально. Сеньор открывает дашборд, проверяет метрики задержек, фильтрует структурированные логи по конкретному trace_id, находит проблемный SQL-запрос и выпускает исправление за 10 минут. Почему это важно Нужно понимать, как правильно инструментировать приложение, чтобы в случае сбоя (а он неизбежен) система точно указывала, где именно возникла проблема. Как применять Изучите три столпа наблюдаемости: логи, метрики и трассировки. … Читать полностью →
13 · 1.1K ·
.
.NET Разработчик
День 2810. #ЧтоНовенького #VSCode Более Быстрый и Лёгкий C# Dev Kit Мы, разработчики, любим быстрые инструменты. Ожидание загрузки языковой поддержки, завершения сборки и выполнения тестов — это время, которое можно было бы потратить с большей пользой. В рамках выпуска .NET 11 архитектура C# Dev Kit была полностью переработана, что позволило существенно повысить производительность и оптимизировать использование памяти. Кроме того, появились отличные новые функции. Версия C# Dev Kit синхронизирована с текущим выпуском .NET, поэтому новая версия расширения — 11.0, хотя предыдущая была 3.3. Более быстрая загрузка В 100+ раз быстрее для активного файла и до 30 раз быстрее для всего решения. Загрузка активного файла означает, что для редактируемого файла доступна языковая поддержка: автодополнение, диагностика, переход к определению и быстрые исправления. В этот момент можно приступать к полноценной работе. Загрузка всего решения достигается после завершения загрузки всех проектов: языковая поддержка работает в любом файле, обнаружены все тесты в решении, а функция поиска всех ссылок (Find All References) охватывает все проекты. Ускорить загрузку помогают новые механизмы кэширования проектов. Теперь системе не нужно заново анализировать каждый проект при каждом открытии, поэтому языковые сервисы, тесты и таргеты запуска становятся доступными практически мгновенно. Сначала загружается активный файл, что позволяет начать работу с ним, пока остальная часть рабочей области загружается в фоновом режиме; при этом производительность остаётся стабильной независимо от количества проектов. Кэш проекта создается при его первой загрузке. Все последующие загрузки выполняются на основе кэша и происходят быстро. Если зафиксировать файлы кэша в системе контроля версий, то новые клоны репозитория и рабочие деревья (git worktrees) сразу же получат доступ к быстрой работе инструментов, что особенно удобно при использовании агентов сборки. Более быстрая сборка В C# Dev Kit 11.0 инкремента… Читать полностью →
10 · 1K ·
.
.NET Разработчик
День 2811. #ВопросыНаСобеседовании Марк Прайс предложил свой набор из 60 вопросов (как технических, так и на софт-скилы), которые могут задать на собеседовании. 49. Модульное тестирование «Как бы вы использовали модульные тесты в приложении .NET? Опишите процесс настройки фреймворка тестирования, написания базового теста и его запуска. Укажите также, каких лучших практик вы придерживаетесь при написании модульных тестов». Хороший ответ Начнём с добавления проекта тестов в решение. Например, для тестового фреймворка xUnit это можно сделать с помощью .NET CLI: dotnet new xunit -n YourProjectName.Tests Нужно убедиться, что тестовый проект содержит ссылку на тестируемый проект. При структурировании тестов полезен шаблон AAA (Arrange, Act, Assert). Он предполагает подготовку окружения (Arrange), выполнение тестируемой функциональности (Act) и проверку результата (Assert). Если мы тестируем метод, складывающий два числа, тест может выглядеть так: using Xunit; public class CalculatorTests { [Fact] public void Add_ReturnsCorrectSum() { // Arrange var calc = new Calculator(); int a = 5; int b = 7; // Act var result = calc.Add(a, b); // Assert Assert.Equal(12, result); } } Запустить тесты можно с помощью .NET CLI: dotnet test YourProjectName.Tests либо в IDE через «Обозреватель тестов» (Test Explorer). Основные принципы написания тестов - Изоляция: обеспечение независимости каждого теста; он не должен зависеть от других тестов. - Соглашения об именовании: использование понятных имён для тестовых методов, описывающих ожидаемое поведение теста. - Моки: использование фреймворков для создания заглушек (например, Moq), чтобы изолировать тесты от внешних зависимостей и обеспечить их детерминированность. - Покрытие тестами: стремление к высокому уровню покрытия, но с упором на проверку критически важных путей и логики, а не простых методов доступа (геттеров/сеттеров). Распространённый неудачный ответ «Чаще всего я просто копирую суще… Читать полностью →
11 · 897 ·
.
.NET Разработчик
День 2812. #Карьера #AI Как Разработчикам Оставаться Полезными, Когда Код Пишет ИИ? По мере того, как ИИ берёт на себя всё большую часть задач по написанию кода, GitHub призывает разработчиков совершенствовать навыки, необходимые для управления этим процессом и принятия решений о том, какой код будет выпущен. 1. Управляйте агентами. Ставьте задачи, предоставляйте контекст и оценивайте результаты. Это процесс координации работы отдельных агентов, отвечающих за аутентификацию, документацию и тестирование, при сохранении за собой ответственности за итоговый результат. 2. Подвергайте результаты сомнению. Попросите другую модель проанализировать и раскритиковать предложенное решение, а затем самостоятельно оцените оба ответа. 3. Решайте более масштабные задачи. Используйте время, высвободившееся от непосредственного написания кода, для анализа потребностей клиентов, архитектуры и выбора оптимальных решений. Разработчикам по-прежнему необходимо определять, действительно ли предлагаемое решение устраняет нужную проблему. Неудивительно, что этот вопрос, затрагивающий саму суть профессии, всё чаще обсуждается в отрасли, в том числе на крупных конференциях для разработчиков, которые раньше были сосредоточены исключительно на технических аспектах написания кода. На ноябрьской конференции Live!360 Tech Con докладчики обсуждали, что люди должны по-прежнему понимать, оценивать и за что нести ответственность. Для Анджелы Дуган, вице-президента по поставке продуктов в Red Foundry, ответ кроется в софт-скилах. В своей статье "Human Skills in an AI World: How Technologists Stay Essential" она делает упор на формировании общего понимания задач, критическом пересмотре предположений и умении вовремя остановиться и оценить ситуацию. Для Дуган это личный вопрос: после того как в июле 2025 года она попала под сокращение в Microsoft, новый работодатель высоко оценил её лидерские качества, способность принимать взвешенные решения, навыки коммуникации и умение справляться со сложными задач… Читать полностью →
13 · 787 ·
.
.NET Разработчик
День 2813. #ЗаметкиНаПолях #Async Ещё Раз Про Async/Await в C#. Часть 1 1. Почему существует асинхронность: цена блокировки потока Прежде чем углубиться в то, как работает асинхронность, рассмотрим, какую проблему она решает, поскольку обычные объяснения либо расплывчаты («это делает ваше приложение быстрее»), либо неверны («она запускает ваш код в фоновом режиме»). async/await ничего не ускоряет. Сетевой вызов занимает столько времени, сколько потребуется. Что меняется, так это то, что ваш процесс делает во время ожидания, и это, оказывается, имеет большое значение. Рассмотрим метод, который вызывает веб-сервис и возвращает длину ответа: public static int GetLength(string url) { using var client = new HttpClient(); var response = client .Send(new HttpRequestMessage(HttpMethod.Get, url)); return (int)response .Content .Headers .ContentLength .GetValueOrDefault(); } Пока этот запрос находится в работе, вызывающий поток находится внутри блокирующего вызова. Он ничего не делает, он просто занят, и процессор может запускать что-то другое. Но поток не бесплатен. Он всё ещё существует, ему по-прежнему принадлежит свой стек, и, что особенно важно, если он поступил из пула потоков, он больше не доступен для выполнения другой работы. В блокирующей версии поток занят на все время выполнения ввода-вывода. В асинхронной же версии поток освобождается, как только операция запускается, и поток снова необходим только после того, как станет доступен результат. Сколько стоит поток Обычный аргумент против лишних потоков – лишняя память. Поток по умолчанию резервирует мегабайт адресного пространства стека, поэтому десять тысяч потоков резервируют десять гигабайт. Это правда, но в 64-битной версии это не так критично, потому что память резервируется, а не выделяется. На самом же деле проблемы больше исходят из пула потоков. Пул потоков .NET начинается с количества рабочих потоков, равного числу процессоров. Когда каждый из них занят и в очереди стоит больше рабо… Читать полностью →
19 · 633 ·
.
.NET Разработчик
День 2814. #ЗаметкиНаПолях #Async Ещё Раз Про Async/Await в C#. Часть 2 Нет никакого потока В предыдущем посте было показано, что блокировка потока во время ожидания ввода-вывода ограничивает всё остальное, что процесс хочет сделать, а ожидание этого не делает. Возникает вопрос: если не ожидает ни один поток, тогда кто? Простой ответ – никто. Следующий пример запускает 100000 ожиданий по 1с и выводит количество потоков, используемых процессом, пока все они находятся в ожидании: var tasks = new Task[100_000]; for (var i = 0; i < tasks.Length; i++) tasks[i] = Task.Delay(TimeSpan.FromSeconds(1)); await Task.WhenAll(tasks); Вывод: Процессоров: 15 Потоков до: 9 Потоков в пуле до: 0 100000 операций начаты за 14мс Потоков при ожидании: 10 Потоков в пуле: 0 Завершено за 1105мс Потоков после: 27 Потоков в пуле после: 16 Завершено заданий: 99999 Сто тысяч операций начато, а процесс использует 10 потоков ОС. Пул потоков ещё не создал ни одного рабочего потока, поскольку нет работы для выполнения: ожидание (await) не является работой. Затем всё завершается одновременно, и пул увеличивается до 16 потоков для выполнения 100000 продолжений. Всего затрачено: 1105мс для операции, занимающей 1000мс. Где живёт ожидание Ожидание живёт в операционной системе, а при сетевом чтении — в сетевой карте и её драйвере. Когда вы вызываете синхронное чтение, ядро помещает ваш поток в очередь ожидания, прикрепленную к файловому дескриптору, и планировщик перестаёт выделять ему процессорное время. Поток существует только для того, чтобы ядру было что пробудить. Это заначка, и она дорогая. Каждая операционная система предлагает способ избежать этого: • В Windows есть порты завершения ввода-вывода (I/O Completion Ports). Вы связываете дескриптор с портом, выполняете перекрывающееся (overlapped) чтение, которое немедленно возвращается, а затем ядро отправляет пакет завершения на порт. Небольшой пул потоков вызывает GetQueuedCompletionSta… Читать полностью →
Длинный пост
фото и оформление — в Telegram ↗
👍19
37 · 1.5K ·
.
.NET Разработчик
День 2815. #ЗаметкиНаПолях #Async Ещё Раз Про Async/Await в C#. Часть 3 Жизненный Цикл Task и TaskCompletionSource В предыдущих статьях этой серии мы рассматривали потоки и операционную систему. Эта статья посвящена объекту, занимающему промежуточное положение: Задача (Task). Он появился ещё до внедрения механизма async/await, и понимание его устройства упростит восприятие материала о преобразованиях, выполняемых компилятором, о которых будет позже. Задача — это своего рода «обещание» получить результат в будущем. Это не поток, не операция и не единица работы. Task хранит три элемента: состояние, результат (или исключение) и список действий, которые необходимо выполнить по завершении задачи. Жизненный цикл Задача может быть запущена одним из двух способов: либо создаётся уже завершенной, либо создаётся в состоянии ожидания и завершается позже. В дальнейшем она переходит из одного состояния в другое, двигаясь только в одном направлении: Три конечных состояния важны, поскольку при использовании await они ведут себя по-разному: • RanToCompletion (успешное завершение) — возвращает полученное значение, • Faulted (завершена с ошибкой) — повторно выбрасывает исключение, • Canceled (отменена) — выбрасывает исключение OperationCanceledException, что отличается от завершения с ошибкой. Код, который воспринимает отмену как ошибку, обычно неверен. Задача никогда не выходит из конечного состояния, и завершить её можно только один раз. Именно поэтому API содержит методы SetResult и TrySetResult: первый выбрасывает исключение, если задача уже завершена, а второй возвращает false. Если существует вероятность того, что за завершение одной и той же задачи могут одновременно бороться два процесса, используйте методы Try<…>. TaskCompletionSource: ожидаем что угодно! Большинство задач создаются на основе операций, которые возвращают Task. TaskCompletionSource<T> позволяет создать задачу из того, что её изначально не предоставляет: например, из события, обратного вызова или … Читать полностью →
Длинный пост
фото и оформление — в Telegram ↗
👍8
37 · 1.5K ·
.
.NET Разработчик
День 2816. #Карьера #AI Станет ли ИИ-Кодинг Концом Программирования для Людей? Автор оригинала: Pavel Yosifovich Мое знакомство с компьютерами состоялось в 1983 г. В ZX-Spectrum я мог использовать язык программирования (BASIC), чтобы заставить компьютер выполнять различные задачи, создавать игры и другие интересные программы. Важной частью процесса было именно удовольствие — создание чего-то из ничего; это было увлекательно и бросало вызов, напоминая игру, независимо от того, что я писал. Вскоре у меня появился Commodore 64. Хотя BASIC оставался основным языком, нередко приходилось писать код и на ассемблере. Главной причиной была низкая скорость BASIC (он был интерпретируемым). Прошли годы — и BASIC ушёл в прошлое. Ассемблер тоже практически не используется. Популярные языки справляются с большинством задач. Даже интерпретируемые языки вроде Python и JavaScript пользуются огромным успехом: пусть они и «медленные», их быстродействия хватает для множества приложений. С появлением языков программирования, предлагающих более высокие уровни абстракции, потребность в ассемблере свелась к минимуму. Эра ИИ-программирования Вы наверняка видели возможности ИИ в написании кода и, вероятно, уже пользовались ими. Признаюсь, мне немного грустно от того, что люди будут писать меньше кода вручную, перепоручая эту задачу ИИ-агентам. Возможно, это естественный эволюционный процесс — переход к использованию абстракций более высокого уровня. Однако здесь есть принципиальное различие. Раньше под более высокой абстракцией обычно подразумевался другой язык программирования — возможно, с более совершенными инструментами и средой разработки. ИИ-кодинг — процесс особый: мы используем естественный язык, который по своей природе допускает неоднозначность и неточность, — а ведь именно для устранения этих проблем в своё время и создавались языки программирования. ИИ активно используется для написания кода, причем степень участия человека варьируется от существенной до отсутствующей; однако … Читать полностью →
👍6👎2
8 · 875 ·
.
.NET Разработчик
День 2817. #ЧтоНовенького #VS Прекращаем Сборку После Первой Ошибки Мэдс Кристенсен продолжает поставлять небольшие и на первый взгляд очевидные улучшения процесса разработки в Visual Studio. Если один из проектов в решении не удается собрать, процесс сборки всего решения обычно продолжается. У вас уже есть ошибка, которую нужно исправить, но остальные проекты продолжают собираться, несмотря на то что сборка решения всё равно закончится неудачей. В VS2026 (версии 18.11) появилась опция, позволяющая автоматически останавливать сборку решения сразу после того, как в одном из проектов произошел сбой. Если ваш следующий шаг — исправление этой ошибки, то такая настройка поможет сэкономить время, прекращая дальнейший процесс сборки. Настройка остановки сборки Перейдите в раздел Tools > Options > Projects and Solutions > Build and Run (Сервис > Параметры > Проекты и решения > Сборка и запуск) и включите параметр Stop solution build after first failure (Останавливать сборку решения после первой ошибки). При возникновении ошибки в проекте Visual Studio перестанет запускать задачи для проектов, стоящих в очереди, и безопасно остановит те, что уже находятся в процессе сборки. При этом результат сборки помечается как «сбой» (failed), а не «отмена» (canceled). Вам больше не нужно следить за появлением первой ошибки и вручную прерывать выполнение остальных задач. Эта функция останавливает сборку всего решения, а не только тех проектов, которые зависят от проблемного компонента. Это важное отличие: вы быстрее переходите к устранению первопричины, но при этом не получаете результаты сборки остальных проектов, входящих в решение. Если вы предпочитаете видеть результаты по всем проектам, прежде чем приступать к исправлению ошибок, оставьте эту настройку отключенной — в таком случае сохранится привычное поведение системы. При необходимости функцию всегда можно отключить на той же странице параметров. Итоговая экономия времени зависит от структуры вашего решения и того, на каком… Читать полностью →
👎1
10 · 828 ·
.
.NET Разработчик
День 2818. #ВопросыНаСобеседовании Марк Прайс предложил свой набор из 60 вопросов (как технических, так и на софт-скилы), которые могут задать на собеседовании. 50. Фреймворки для создания тестовых заглушек «Расскажите, как использовать тестовые заглушки для модульного тестирования? Приведите примеры создания заглушек для зависимостей и проверки того, что код ведёт себя ожидаемым образом». Хороший ответ Использование фреймворков, вроде Moq или NSubstitute в .NET-приложениях для модульного тестирования предполагает создание заглушек для зависимостей, которые могут быть у класса. Это позволяет всесторонне протестировать класс в изоляции. Тестовые заглушки – общий термин, описывающий все разновидности фиктивных зависимостей в тестах. Среди них можно выделить два основных: - Моки (mock) – позволяют эмулировать и проверять выходные взаимодействия, т.е. вызовы, совершаемые тестируемой системой к её зависимостям для изменения их состояния. Например, моком можно заменить почтовый сервер, на который отправляется письмо. - Стабы (stub) – помогают эмулировать входные взаимодействия, т.е. вызовы к зависимостям для получения входных данных. Например, стабом можно заменить базу, из которой запрашиваются данные. Стабы настраиваются для возвращения разных значений для разных сценариев. Вот пример использования фреймворка NSubstitute: using NSubstitute; using Xunit; public class ServiceTests { private IService _sut; private ICalculator _calc; public ServiceTests() { // Создаём заглушку для зависимости ICalculator _calc = Substitute.For<ICalculator>(); _sut = new Service(_calc); } [Fact] public void AddNumbers_ShouldReturnCorrectSum() { // Задаём поведение метода Add _calc.Add(5, 10).Returns(15); var result = _sut.AddNumbers(5, 10); Assert.Equal(15, result); // Проверяем, что Add был вызван _calc.Received(1).Add(5, 10); } } NSubstitute позволяет проверять, что методы мок-объекта были вызваны с ожидаемыми аргументам… Читать полностью →
👎2
13 · 610 ·
.
.NET Разработчик
День 2819. #ЗаметкиНаПолях #Async Ещё Раз Про Async/Await в C#. Часть 4 Паттерн awaitable: создание объектов, поддерживающих ожидание Если спросить большинство C#-разработчиков, что можно использовать с оператором await, они ответят: «Task». Это распространённый, но далеко не единственный случай. Механизм await работает так же, как и foreach, на основе структуры. Компилятор ищет определенную «форму» (набор элементов), и Task как раз ей соответствует. Понимание этой структуры поможет разобраться в конечном автомате, который генерируется компилятором (о нём позже). Кроме того, это позволит создавать собственные «ожидаемые» объекты. Структура Чтобы выражение await expr успешно скомпилировалось, у объекта expr должен быть метод GetAwaiter(). Возвращаемый им тип — так называемый «awaiter» (объект ожидания) — должен содержать три элемента и реализовывать один интерфейс: public readonly struct MyAwaiter : INotifyCompletion { // завершилась ли уже операция? public bool IsCompleted { get; } // значение, либо повторный выброс исключения public TResult GetResult(); // вызывается при завершении public void OnCompleted(Action continuation); } Вот и весь контракт. Компилятор выполняет привязку этих членов по их именам, что имеет два важных следствия: 1. Метод GetAwaiter может быть методом расширения. Это позволяет сделать тип «ожидаемым», даже если вы не являетесь его владельцем: public static class TimeSpanAwaitableExtensions { public static TaskAwaiter GetAwaiter(this TimeSpan timeSpan) => Task.Delay(timeSpan).GetAwaiter(); } … await TimeSpan.FromMilliseconds(200); 2. Объект ожидания может быть структурой. TaskAwaiter, ValueTaskAwaiter и YieldAwaitable.YieldAwaiter являются структурами; поэтому при ожидании уже завершённой задачи не происходит выделения памяти под объект ожидания. Как используются эти три члена Для каждого вызова await компилятор генерирует примерно следующий код: var awaiter = expr.GetAwaiter(); if (!awaiter.IsCompleted) { // сох… Читать полностью →
👍6
23 · 572 ·
.
.NET Разработчик
День 2820. #ЗаметкиНаПолях #Async Ещё Раз Про Async/Await в C#. Часть 5 Как компилятор C# переписывает асинхронный метод. Начало Вплоть до версии .NET 10, async и await не являются встроенными возможностями среды выполнения. Компилятор переписывает код метода с модификатором async. Он извлекает тело метода, переносит его в автоматически созданный тип, а исходный метод заменяет небольшим фрагментом кода, который инициализирует этот тип и запускает его метод. Всё остальное — планирование выполнения, обработка исключений, формирование значения, которое в итоге попадает в возвращаемый объект Task, — представляет собой обычный код, который вы могли бы написать самостоятельно. Сегодня рассмотрим небольшой асинхронный метод и проанализируем, во что его превращает компилятор. Метод содержит все элементы, с которыми приходится работать компилятору: параметр, локальные переменные, значения которых должны сохраняться после await, два await разных типов, цикл, а также блок try/finally: public static async Task<int> SumPageSizesAsync(string[] pages) { var total = 0; var sw = Stopwatch.StartNew(); try { foreach (var page in pages) { var content = await LoadAsync(page); total += content.Length; } await Task.Yield(); return total; } finally { Console.WriteLine($"Loaded {pages.Length} pages in {sw.ElapsedMilliseconds}ms"); } } private static async Task<string> LoadAsync(string page) { await Task.Delay(1); return page; } Чтобы увидеть, что с методом делает компилятор, можно либо декомпилировать его с помощью ILSpy, либо использовать онлайн инструмент sharplab.io. Что осталось от исходного метода [AsyncStateMachine(typeof(<SumPageSizesAsync>d__0))] public static Task<int> SumPageSizesAsync(string[] pages) { <SumPageSizesAsync>d__0 stateMachine = default(<SumPageSizesAsync>d__0); stateMachine.<>t__builder = AsyncTaskMethodBuilder<int>.Create(); stateMachine.pages = pages; stateMachine.<>1__state = -1; stateMachin… Читать полностью →
19 · 611 ·
Архив по месяцам
октябрь 2026сентябрь 2026август 2026июль 2026июнь 2026май 2026апрель 2026март 2026февраль 2026январь 2026декабрь 2025ноябрь 2025октябрь 2025сентябрь 2025август 2025июль 2025июнь 2025май 2025апрель 2025март 2025февраль 2025январь 2025декабрь 2024ноябрь 2024октябрь 2024сентябрь 2024август 2024июль 2024июнь 2024май 2024апрель 2024март 2024февраль 2024январь 2024декабрь 2023ноябрь 2023октябрь 2023сентябрь 2023август 2023июль 2023июнь 2023май 2023апрель 2023март 2023февраль 2023январь 2023декабрь 2022ноябрь 2022октябрь 2022сентябрь 2022август 2022июль 2022июнь 2022май 2022апрель 2022март 2022февраль 2022январь 2022декабрь 2021ноябрь 2021октябрь 2021сентябрь 2021август 2021июль 2021июнь 2021май 2021апрель 2021март 2021февраль 2021январь 2021декабрь 2020ноябрь 2020октябрь 2020сентябрь 2020август 2020июль 2020июнь 2020май 2020апрель 2020март 2020февраль 2020январь 2020декабрь 2019ноябрь 2019октябрь 2019сентябрь 2019август 2019июль 2019июнь 2019май 2019апрель 2019март 2019февраль 2019январь 2019

Открытая публичная лента из поискового индекса ChatCrawler — «Google по публичному Telegram»; обновляется по мере обхода площадки. Время — UTC.

Только публичный контент, официальный API Telegram. О проекте · Вопросы · Границы индекса · Убрать страницу из выдачи · Каталог · Поиск · Как мы считаем