.NET Разработчик
6.51K subscribers
427 photos
2 videos
14 files
2.04K links
Дневник сертифицированного .NET разработчика.

Для связи: @SBenzenko

Поддержать канал:
- https://boosty.to/netdeveloperdiary
- https://patreon.com/user?u=52551826
- https://pay.cloudtips.ru/p/70df3b3b
Download Telegram
День пятьсот восемнадцатый. #ЧтоНовенького
dotnet-monitor
При запуске приложений dotnet в различных средах может быть трудно собирать диагностическую информацию (например, логи, трассировки, дампы процессов). dotnet-monitor - это экспериментальный инструмент, который призван упростить этот процесс, предоставляя согласованный REST API независимо от того, где запущено ваше приложение.

REST API предоставляет две группы URL:
- https://localhost:52323 – для доступа ко всем конечным точкам (настраивается через параметр --urls);
- https://localhost:52325 – для доступа к конечным точкам метрики (настраивается через параметр --metricUrls).

dotnet-monitor доступен через два механизма распространения:
- как глобальный инструмент .NET Core,
- как образ контейнера доступный через реестр контейнеров Microsoft (MCR).

Установить инструмент можно, используя следующую команду:
dotnet tool install -g dotnet-monitor --add-source https://dnceng.pkgs.visualstudio.com/public/_packaging/dotnet5-transport/nuget/v3/index.json --version 5.0.0-preview.1.*

После установки запустить dotnet-monitor можно с помощью следующей команды:
dotnet monitor collect

Конечные точки
REST API утилиты предоставляет следующие конечные точки, которые можно вызвать, например, через PowerShell:
PS> Invoke-RestMethod https://localhost:52323/processes

/processes
Возвращает список целевых процессов, доступных через dotnet-monitor.

/dump/{pid?}
Возвращает дамп целевого процесса. Особенность его в том, что его нельзя проанализировать на машине с ОС/архитектурой, отличной от той, где он был захвачен.

/gcdump/{pid?}
Возвращает дамп GC целевого процесса. В отличие от дампа процесса, он может быть проанализирован в Visual Studio и perfview независимо от платформы, на которой он был захвачен.

/trace/{pid?}
Возвращает трассировку целевого процесса по умолчанию за 30 секунд. Диагностические данные, присутствующие в трассировке, можно настроить через параметры запроса:
1. durationSeconds – длительность захвата в секундах,
2. profile – профили для захвата через запятую:
- cpu – профилировка ЦП,
- http – события старта/остановки запросов в ASP.NET Core,
- logs – логи из EventSourceLogger,
- metrics - метрики из EventCounters.

/logs/{pid?}
Будет транслировать логи целевого процесса по умолчанию в течение 30 секунд.

/metrics
Вернёт снимок метрик среды выполнения и ASP.NET Core.

dotnet-monitor в настоящее время используется в экспериментальном режиме до выпуска .NET 5. В этот период в Майкрософт хотят оценить полезность инструмента и решить, что делать с ним дальше. Вы можете попробовать его и описать проблемы или просто следить за ходом проекта в репозитории GitHub.

Источник: https://devblogs.microsoft.com/dotnet/introducing-dotnet-monitor/
День пятьсот девятнадцатый. #Оффтоп #97Вещей
97 Вещей, Которые Должен Знать Каждый Программист
48. Большие Объёмы Взаимосвязанных Данных Должны Храниться в Базе Данных
Если ваше приложение обрабатывает большой, постоянный и взаимосвязанный набор данных, не стесняйтесь хранить их в базе данных. В прошлом СУБД были дорогими, дефицитными, сложными и громоздкими монстрами. Это больше не так. В настоящее время системы СУБД легко найти (вполне вероятно, что на вашем компьютере уже используется одна или две). Некоторые очень мощные СУБД, такие как MySQL и PostgreSQL, доступны как ПО с открытым исходным кодом, поэтому стоимость покупки больше не является проблемой. Более того, так называемые встроенные системы баз данных могут быть использованы в виде библиотек непосредственно в вашем приложении, практически не требуя настройки или управления. Две наиболее известные из них - SQLite и HSQLDB.

Если данные вашего приложения больше размера отведённой оперативной памяти, индексированная таблица в СУБД будет работать на несколько порядков быстрее, чем использование коллекций в памяти. Современные базы данных могут легко расти с вашими потребностями. При соблюдении слабой связанности модулей в приложении вы можете при необходимости расширить масштаб встроенной базы данных до более крупной СУБД или перейти от СУБД с открытым кодом к более мощной системе.

Как только вы освоите SQL, написание приложений, использующих БД, не будет вызывать проблем. После того, как вы сохраните свои правильно нормализованные данные в базе, их легко извлекать с помощью понятных SQL-запросов; нет необходимости писать какой-либо сложный код. Аналогично, простая команда SQL может выполнять сложные изменения данных. А использование систем ORM, вроде Entity Framework, делает работу с СУБД невероятно простой. Во многих случаях не потребуется даже глубокого изучения SQL.

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

Вы также можете создавать эффективные связи между объектами, хранящимися в базе данных, в любое время, просто создав индекс. Нет необходимости выполнять обширный рефакторинг полей классов. Кроме того, использование БД позволяет нескольким приложениям безопасно обращаться к вашим данным.

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

Источник: https://www.oreilly.com/library/view/97-things-every/9780596809515/
Автор оригинала – Diomidis Spinellis
День пятьсот двадцатый. #DotNetAZ
Dotnet A-Z. 1
В этой серии постов рассмотрим наиболее распространённые понятия в .NET в алфавитном порядке.

АОТ - ahead-of-time компилятор.
Подобно JIT-компилятору, этот компилятор также переводит IL в машинный код. Но в отличие от JIT-компиляции, AOT-компиляция происходит перед выполнением приложения и обычно выполняется на другом компьютере. Поскольку цепочки инструментов AOT не компилируются во время выполнения, им не нужно минимизировать время, затрачиваемое на компиляцию. Это означает, что они могут тратить больше времени на оптимизацию. Т.к. контекстом AOT-компиляции является всё приложение, компилятор AOT также выполняет межмодульное связывание и анализ всей программы, что означает переход по всем ссылкам и создания одного исполняемого файла.

ASP.NET
Платформа разработки веб-приложений, в состав которой входит: веб-сервисы, программная инфраструктура и модель программирования. Исходная реализация ASP.NET входит в состав платформы .NET Framework.
Иногда ASP.NET - это общий термин, который относится к обеим реализациям ASP.NET в .NET Framework и .NET Core. Значение, которое этот термин несёт в конкретном случае, определяется контекстом.

ASP.NET Core
Кроссплатформенная, высокопроизводительная реализация ASP.NET с открытым исходным кодом, построенная на .NET Core.

Assembly (сборка)
Сборка - это логическая группировка одного или нескольких управляемых модулей или файлов ресурсов. Это самая маленькая единица с точки зрения многократного использования, безопасности и управления версиями. Управляемые модули сборки могут быть файлами dll или exe в зависимости от типа проекта. Файл с исходным кодом, написанном на любом языке поддерживаемым .NET, с помощью соответствующего компилятора, компилируется в сборку. Сборка может включать в себя типы, такие как интерфейсы, классы, структуры, перечисления и делегаты.

Источник: https://docs.microsoft.com/en-us/dotnet/standard/glossary
День пятьсот двадцать первый. #ЧтоНовенького
AWS Поможет Пользователям Перенести Приложения с .NET Framework на Core
Amazon Web Services (AWS) представили инструмент, помогающий пользователям их облачных сервисов перенести свои приложения с .NET Framework на .NET Core.

Porting Assistant for .NET работает на Linux, сканирует приложения и генерирует оценку совместимости с .NET Core, помогая ускорить переход на новую платформу.

«Перенос приложений с .NET Framework на .NET Core помогает клиентам воспользоваться преимуществами производительности, экономии средств и надежностью экосистемы Linux. Однако это может потребовать значительных усилий», - говорят в AWS, - «Владельцам приложений нужно тратить драгоценное время на выявление зависимостей и API, несовместимых с .NET Core, и на оценку количества требуемых на перенос усилий. Porting Assistant для .NET быстро сканирует приложения .NET Framework для выявления несовместимостей с .NET Core, находит известные замены и генерирует подробную оценку совместимости. Это сокращает ручные усилия, необходимые для модернизации ваших приложений под Linux».

Хотя существует несколько утилит Framework-to-Core, в том числе и от Microsoft, AWS заявляют, что их инструмент отличается тем, что способен полностью оценить дерево зависимостей пакетов в дополнение к основным функциям, таким как обнаружение несовместимых API. Кроме того, по словам AWS, в качестве отправной точки используются файлы решений, что упрощает оценку монолитных решений, включающих множество проектов. Это устраняет необходимость анализа и агрегирования информации об отдельных двоичных файлах.

При портировании приложений с .NET Framework разработчикам необходимо искать совместимые пакеты NuGet и обновлять ссылки на эти пакеты в файлах проекта приложения, которые также должны быть обновлены до формата файлов проекта .NET Core. Кроме того, им нужно искать API для замены, поскольку .NET Core содержит лишь часть API, доступных в .NET Framework. По мере продвижения процесса портирования разработчикам приходится разбираться с длинными списками ошибок и предупреждений компиляции, чтобы определить наиболее приоритетные места изменений для продолжения переноса. Излишне говорить, что это сложно, и дополнительные проблемы могут стать сдерживающим фактором для клиентов с большим портфелем приложений.

В качестве цели инструмент использует .NET Core 3.1, который в итоге будет обновлён до .NET 5. Исходные приложения должны быть на .NET Framework 3.5 или выше. Инструмент работает только для сервисов Windows и приложений ASP.NET.

Источник: https://visualstudiomagazine.com/articles/2020/07/02/aws-net-porting-tool.aspx
День пятьсот двадцать второй. #ЗаметкиНаПолях
Настройка ASP.NET Core.
1. Класс Program. Начало
Класс Program содержит метод Main, который является точкой входа приложений ASP.NET Core. Метод Main аналогичен методу Main консольных приложений, т.к. все приложения .NET Core по сути являются консольными приложениями. Веб-приложения, такие как MVC или приложения Razor Pages строятся поверх консольного приложения.

Основное назначение класса Program - настройка инфраструктуры приложения.

Класс Program создаёт веб-хост при запуске. Затем он настраивает ведение журнала, контейнер внедрения зависимостей (DI), систему конфигурации, веб-сервер Kestrel, интеграцию с IIS и т. д. Он также добавляет сервисы инфраструктуры в контейнер DI, чтобы мы могли их использовать. Код для класса программы генерируется автоматически, чего в большинстве случаев достаточно.

Что такое веб-хост (Web Host)?
Веб-хост отвечает за запуск приложения и его выполнение. Он создается при запуске приложения, создаёт сервер, который прослушивает HTTP-запросы, настраивает конвейер запросов (он же конвейер промежуточного ПО). Кроме того, он устанавливает DI-контейнер, в который добавляются сервисы. Управление временем жизни сервисов также является задачей веб-хоста.

По сути, веб-хост готовит приложение к использованию и получению запросов. Но он должен быть создан и настроен. Это делается в методе Main.
public class Program {
public static void Main(string[] args) {
CreateWebHostBuilder(args).Build().Run();
}

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>();
}

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

CreateDefaultBuilder создаёт строитель по умолчанию:
1. Устанавливает корень содержимого в Directory.GetCurrentDirectory.
2. Загружает дополнительную конфигурацию из:
- appsettings.json,
- appSettings.{Имя_Среды}.json,
- секретных данных пользователя,
- переменных среды,
- аргументов командной строки.
3. Включает ведение журнала.
4. Устанавливает DI-контейнер.
5. Настраивает Kestrel в качестве веб-сервера.
6. Настраивает необходимые сервисы в конвейере промежуточного ПО.
7. Интегрирует выполнение Kestrel в IIS.

Веб-хост создан и настроен, но перед сборкой и запуском необходимо дополнительно настроить приложение. Это делается в классе Startup (название класса по соглашению). Строителю веб-хоста сообщается имя класса настройки, используя обобщённый метод UseStartup.

Источник: https://www.tektutorialshub.com/asp-net-core/asp-net-core-program-cs/
День пятьсот двадцать третий. #ЗаметкиНаПолях
Настройка ASP.NET Core.
2. Класс Program. Продолжение
Рассмотрим подробнее, что делает метод CreateDefaultBuilder. Его код можно найти на GitHub.

1. Установка корня содержимого
builder.UseContentRoot(Directory.GetCurrentDirectory());
Устанавливает текущий каталог как корень приложения.

2. Загрузка конфигурации
Из аргументов командной строки используя метод UseConfiguration. Остальные настройки загружаются внутри метода ConfigureAppConfiguration, которому передаётся лямбда-функция, принимающая контекст хоста HostBuilderContext и строитель конфигурации, реализующий IConfigurationBuilder. Конфигурация добавляется, вызовами методов строителя:
- appsettings.json и appSettings.{Имя_Среды}.json через вызовы AddJsonFile,
- секретные данные пользователя через AddUserSecrets,
- переменные среды через AddEnvironmentVariables.

3. Ведение журнала
ConfigureLogging((hostingContext, logging) => {
logging.AddConfiguration(
hostingContext.Configuration.GetSection("Logging"));
logging.AddConsole();
logging.AddDebug();
logging.AddEventSourceLogger();
})
Здесь считываются правила ведения журнала из файла конфигурации, указанные в разделе «Logging», и настраивается ведение журнала для вывода на консоль, в журнал отладки и в провайдер EventSource.

4. Установка DI-контейнера
Метод UseDefaultServiceProvider устанавливает DI-контейнер внедрения зависимостей и настраивает проверку области внедрения.

Далее вызывается статический метод ConfigureWebDefaults. Основные его моменты:
5. Настройка Kestrel
В методе UseKestrel выполняется настройка веб-сервера Kestrel параметрами из конфигурационного файла.

6. Настройка необходимых сервисов
В конвейер промежуточного ПО добавляются сервисы HostFiltering (ограничивает имена хостов, на которые откликается приложение) и ForwardedHeaders (настраивает http-заголовки X-Forwarded-For и X-Forwarded-Proto).

7. Интеграция с IIS
Наконец вызываются методы
.UseIIS()
.UseIISIntegration();
Настраиваются два способа размещения приложения:
- In Process запускает приложение внутри процесса IIS (с помощью UseIIS).
- Out of process выполняется в отдельном процессе и использует сервер Kestrel. IIS действует как обратный прокси-сервер, пересылающий запросы в Kestrel (с помощью UseIISIntegration).

Источник: https://www.tektutorialshub.com/asp-net-core/asp-net-core-program-cs/
День пятьсот двадцать четвёртый. #Оффтоп #97Вещей
97 Вещей, Которые Должен Знать Каждый Программист
49. Изучайте Иностранные Языки
Программисты должны общаться. Много общаться.

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

Программисты должны свободно владеть языком машины, реальным или виртуальным, а также абстракциями, которые могут быть выражены этим языком с помощью инструментов разработки. Важно выучить много разных абстракций, иначе некоторые идеи становятся невероятно трудными для выражения. Хорошие программисты должны уметь выходить из своей повседневной рутины, изучать другие языки, которые больше подходят для выражения других идей. Рано или поздно эти знания окупятся.

Помимо общения с машинами программисты должны общаться со своими коллегами. Сегодняшние крупные проекты больше социальные начинания, чем просто прикладное искусство программирования. Важно понимать и уметь выражать больше, чем то, что можно представить в понятных машине абстракциях. Большинство лучших программистов, которых я знаю, также очень свободно говорят на нескольких языках. Это не просто общение с другими: хорошее знание языка также приводит к ясности мышления, что необходимо при абстрагировании проблемы. Этот навык полезен и в программировании.

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

Если вы разговариваете с бухгалтерами, вам нужны базовые знания по бухучету основных и оборотных средств, амортизации и т.п. Если вы разговариваете с маркетологами или юристами, некоторые из жаргонизмов их языка (и, следовательно, стиль их мышления) должны быть вам знакомы. Все эти предметно-ориентированные языки должны быть освоены кем-то в проекте, в идеале программистами. Программисты несут полную ответственность за воплощение идей в жизнь с помощью компьютера.

И, конечно же, жизнь - это больше, чем программные проекты. Как говорил Карл Великий, знать другой язык - значит иметь другую душу. Вы по достоинству оцените знание иностранных языков, контактируя с людьми за пределами индустрии программного обеспечения. Чтобы знать, когда слушать, а не говорить. Чтобы знать, что для общения иногда не надо слов.

Источник: https://www.oreilly.com/library/view/97-things-every/9780596809515/
Автор оригинала – Klaus Marquardt
День пятьсот двадцать пятый. #юмор
День пятьсот двадцать шестой. #DotNetAZ
Dotnet A-Z. 2
В этой серии постов рассмотрим наиболее распространённые понятия в .NET в алфавитном порядке.

CLR (Common Language Runtime) - Общеязыковая Среда Исполнения
Обычно относится к среде исполнения .NET Framework. Основной функцией CLR является преобразование управляемого кода в машинный код и последующее выполнение программы. Также CLR является виртуальной машиной, которая не только выполняет приложения, но также генерирует и компилирует код на лету с использованием JIT-компилятора. Подробнее…

CoreCLR
Общеязыковая Среда Исполнения .NET Core. Построена на той же кодовой базе, что и в .Net Framework. Изначально CoreCLR была средой исполнения Silverlight и предназначалась для работы на нескольких платформах, в частности в Windows и OS X. Теперь CoreCLR является частью .NET Core и представляет собой упрощённую версию CLR. Это кросс-платформенная среда исполнения, теперь включающая поддержку многих дистрибутивов Linux.

CoreFx - Библиотека базовых классов .NET Core (*Fx обозначает фреймворк)
Набор библиотек, которые включают пространства имён System и подмножество типов пространства имён Microsoft. BCL - это низкоуровневая инфраструктура общего назначения, на которой основаны прикладные инфраструктуры более высокого уровня, такие как ASP.NET Core. Исходный код .NET Core BCL содержится в репозитории среды исполнения .NET Core. Тем не менее, большинство .NET Core API также доступны в .NET Framework, поэтому вы можете рассматривать CoreFX как ответвление .NET Framework BCL.

CoreRT - Среда Исполнения .NET Core
В отличие от CLR/CoreCLR, CoreRT не является виртуальной машиной, что означает, что она не включает в себя средства для генерации и запуска кода, потому что не содержит JIT. Однако она включает в себя GC и возможности идентификации типа во время выполнения (RTTI) и рефлексии. Система типов CoreRT разработана таким образом, что метаданные для рефлексии не требуются. Отсутствие необходимости в метаданных позволяет иметь цепочку инструментов AOT, которая может отсекать лишние метаданные и (что более важно) идентифицировать код, который приложение не использует. CoreRT пока находится в разработке.

cross-platform - кросс-платформенность
Возможность разработки и запуска приложения в нескольких различных операционных системах, таких как Linux, Windows и iOS, без необходимости переписывать его специально под каждую из них. Это позволяет повторно использовать код и обеспечивать согласованность между приложениями на разных платформах.

Источник: https://docs.microsoft.com/en-us/dotnet/standard/glossary
День пятьсот двадцать седьмой. #ЧтоНовенького
Возможности для создания кроссплатформенных приложений на C# расширяются. Сегодня рассмотрим некоторые технологии для создания UI под разные платформы.

MAUI
MAUI - это эволюция Xamarin.Forms (XF). Это технология для создания нативных мобильных и настольных приложений на C# и XAML. Технология пока в разработке, но по плану MAUI должен заменить Xamarin.Forms. MAUI будет работать в среде исполнения .NET 5/6, а Xamarin.Forms - в Mono для телефонов.
Платформы: iOS, Android, Tizen, UWP (WinUI)
Когда использовать:
- У вас есть приложение Xamarin.Forms
- Для разработки нативного для платформы UI

Uno Platform
Uno - технология для создания нативных мобильных, настольных и WebAssembly (WASM) приложений с использованием C# и XAML. Это адаптер для UWP, который переносит приложения Windows 10 (WinUI/UWP) на телефоны, macOS и браузеры. Uno Platform имеет много общего с MAUI, но поддерживается в браузерах. Второе отличие от MAUI в том, что приложения MAUI по умолчанию выглядят как нативные для платформы, тогда как Uno по умолчанию делает приложение одинаковым для всех платформ.
Платформы: браузеры, iOS, Android, macOS, UWP (WinUI), поддержка Linux в планах
Когда использовать:
- У вас есть приложение UWP или вы хотите использовать WinUI
- Необходима поддержка в браузерах
- Ваша команда знакома с парадигмой XAML от WPF, Silverlight или UWP

Avalonia UI
Avalonia позволяет разработчикам создавать нативные приложения для Windows, macOS и Linux. Она использует уникальный подход рендеринга графики, чтобы полагаться на встроенные элементы управления платформы. Платформа также имеет экспериментальную поддержку телефонов. Поддержка WASM также в планах.
Платформы: Windows, macOS, Linux, экспериментальная iOS и Android, браузеры и полная поддержка iOS в планах
Когда использовать:
- У вас есть приложение WPF
- Для рендеринга на разных платформах
- Для кроссплатформенных настольных приложений (особенно Linux)

Blazor
Blazor - это браузерная технология, использующая WASM или SignalR для переноса кода .NET в браузер. Разработчики определяют UI с помощью HTML, стили с помощью CSS, но манипулируют HTML DOM с помощью C# вместо JavaScript. Подробнее...
Платформы: Браузеры
Когда использовать:
- Для веб-приложений
- Если не нужно создавать мобильное или настольное приложение
- Ваша команда лучше знакома с HTML и CSS, чем с XAML
- Необходимо перенести приложение ASP MVC в SPA.

Мобильные Привязки Blazor (Xamarin.Forms)
Это технология привязки синтаксиса Blazor Razor к Xamarin.Forms. Технология использует синтаксис Razor, что позволяет разработчикам объединять определения UI компонентов с кодом C#. Этот синтаксис будет знаком веб-разработчикам. Однако привязки не используют HTML. Синтаксис определяет компоненты для объектной модели UI Xamarin.Forms UI.
Платформы: iOS, Android
Когда использовать:
- У вас есть веб-приложение Blazor
- Вам нужно создать нативное приложение для телефона
- Ваша команда привыкла к синтаксису Razor
- Вы не против написать раздельный код для веб и для телефонов.

Источник: https://christianfindlay.com/2020/06/24/csharp-crossplatform-2/
👍1
День пятьсот двадцать восьмой. #Оффтоп #ЗадачиНаСобеседовании
В чате просили ещё задачек. Вот вам на выходные)))

Дан массив целых положительных чисел, представляющих цену акции в разные дни (каждый элемент массива представляет день). Также дано целое число k, которое представляет количество сделок, которые вам разрешено совершить. Одна сделка состоит из покупки акции в определённый день и продажи в более поздний день (ВНИМАНИЕ: 1 сделка = 2 транзакции: покупка и продажа).
Найдите максимальную прибыль, которую вы можете получить, покупая и продавая акции, используя максимум k сделок.
Обратите внимание, что в определённый момент вы можете держать только одну акцию. То есть вы не можете купить более одной акции, и не можете купить акцию, если она у вас уже есть. Кроме того, не обязательно использовать все k сделок. Также допустим, что бюджет на покупку не ограничен.

Например,
prices = [5, 11, 3, 50, 60, 90]
k = 2
Результат: 93
//Покупка: 5, продажа: 11 (+6); покупка: 3, продажа: 90 (+87)

prices = [12, 14, 17, 10, 14, 13, 12, 15]
k = 3
Результат: 12

prices = [100, 30, 15, 10, 8, 25, 80]
k = 3
Результат: 72
//Только одна сделка

Усложнённый вариант: Написать решение со сложностью O(n*k) по времени и O(n) по памяти.

Как обычно, приглашаю всех предлагать варианты решения в чате.

Источник: https://www.algoexpert.io/
День пятьсот двадцать девятый. #Оффтоп #97Вещей
97 Вещей, Которые Должен Знать Каждый Программист
50. Учитесь Оценивать

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

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

Часто можно услышать такой диалог между менеджером проекта и программистом:
М: Сколько времени понадобится, чтобы сделать функцию xyz?
П: Примерно месяц.
М: Это слишком долго! Надо сделать за неделю.
П: Мне нужно как минимум три.
М: Я могу выделить на это максимум две.
П: Договорились.


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

1. Оценка - это приблизительный расчёт или прогноз стоимости, количества или размера чего-либо. Это определение подразумевает, что оценка является мерой, основанной на достоверных данных и предыдущем опыте. Надежды и пожелания должны игнорироваться при расчёте. Из определения также следует, что оценка не может быть точной. Разработчик не может оценить время выполнения задачи в 234,14 дня.

2. Цель - это выражение желаемого на языке бизнеса. Например: «Система должна поддерживать не менее 400 одновременно работающих пользователей».

3. Обязательство - это обещание предоставить определённую функциональность определённого качества к определённой дате или событию. Например: «Функция поиска будет доступна в следующей версии продукта».

Оценки, цели и обязательства не зависят друг от друга, но цели и обязательства должны основываться на надёжных оценках. Как отмечает Стив Макконнелл: «Основная цель оценки в разработке ПО - не предсказать дату готовности проекта, а определить, являются ли цели проекта достаточно реалистичными, чтобы проект мог их достигнуть». Таким образом, смысл оценки состоит в том, чтобы сделать возможным адекватное управление проектом и планирование, позволяя вовлечённым сторонам проекта принимать обязательства, основанные на реалистичных целях.

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

Источник: https://www.oreilly.com/library/view/97-things-every/9780596809515/
Автор оригинала – Giovanni Asproni
День пятьсот тридцатый. #Оффтоп #ЗадачиНаСобеседовании
Ответ на задачу

Сначала попробуем решить задачу вручную. Создадим таблицу profits. В столбцах будут дни (day), как в исходном массиве, в строках – сделки (t) от 0 до k. Значениями массива будет максимальная возможная прибыль, полученная от каждой сделки в определённый день. Например:
Цены: 5 11  3 50 60 90
Если доступно 0 сделок, то и прибыль будет 0:
t=0 : 0  0  0  0  0  0
Если доступна 1 сделка, ищем максимальную прибыль от единственной сделки (прибыль в 1й день всегда 0):
t=1 : 0  6  6 47 57 87
Продажа во второй день даёт прибыль 6. Продажа в 3й день не даёт прибыли, поэтому максимум остаётся 6. Покупка в 3й день и продажа в 4й даёт прибыль 47 (больше 6, и больше покупки в 1й день по 5, поэтому максимум 47). Аналогично в 5й и 6й день максимальная прибыль будет 57 и 87 соответственно.
Теперь рассмотрим для 2х сделок. Первые 3 дня изменений не принесут. 1 сделка, прибыль 6:
t=2 : 0  6  6
В 4й день мы можем закрыть вторую сделку, получить прибыль 47 и сложить её с прибылью от первой сделки:
t=2 : 0  6  6 53
В 5й день нам нужно определить, принесёт ли продажа больше прибыли, чем уже есть. Прибыль от второй сделки принесёт 57, общая прибыль будет 63:
t=2 : 0  6  6 53 63
Продажа в 6й день даст нам прибыль в 87 (итого 93), что больше, чем текущий максимум 63:
t=2 : 0  6  6 53 63 93
Таким образом, можно заметить закономерность. Прибыль в определённый день для текущей сделки (profit[t,day]) будет рассчитываться как максимум между:
1) Прибылью за предыдущий день (profit[t,day-1]), если мы не продаём.
2) Если мы продаём, то нужно сложить цену за текущий день (prices[day]) с максимально выгодной покупкой в предыдущие дни. То есть за каждый предыдущий день x нам нужно найти разницу между прибылью от предыдущей(-их) сделки(-ок) в этот день (profit[t-1,x]) и покупкой в этот день (prices[x]). Максимум этой разницы за предыдущие дни и будет наиболее выгодной покупкой. Для второй сделки выгода по дням будет:
x=1: 0–5=-5 (прибыль 0 минус покупка за 5).
x=2: 6-11=-5 (прибыль от 1й сделки 6 минус покупка за 11).
x=3: 6-3=3 (прибыль от 1й сделки 6 минус покупка за 3).
x=4: 47-50=-3 (максимальная прибыль от 1й сделки 47 минус покупка за 50).
x=5: 57-60=-3 (максимальная прибыль от 1й сделки 57 минус покупка за 60).
Таким образом, для 2й сделки в 6й день выгоднее всего купить в 3й день. Получим: цена в 6й день 90 + максимальная выгода от предыдущей сделки 3 = 93, что больше, чем прибыль за предыдущий день 63.

Ответом будет прибыль от последней сделки за последний день.

Сложность по времени: обход n дней k раз - O(n*k) и расчёт максимальной выгоды в каждом случае O(n) – итого O(n^2*k).
Сложность по объёму: двумерный массив – O(n*k).

Оптимизации:
1) Мы можем рассчитывать максимальную выгоду по дням по мере заполнения таблицы прибылей, чтобы исключить дополнительный вложенный цикл. Таким образом, сложность по времени будет O(n*k).
2) Если внимательно посмотреть на алгоритм, нам не нужно хранить все k+1 рядов прибыли. Для расчёта каждого следующего ряда нам нужны данные только предыдущего. Тогда, таблицу можно сократить до двух рядов, соответственно сложность по объёму памяти будет O(n).

Полный код на C#

Более подробное объяснение решения на английском

Источник:
https://www.algoexpert.io/
День пятьсот тридцать первый. #юмор
День пятьсот тридцать второй. #ЧтоНовенького
Стивен Тауб (Stephen Toub) из Майкрософт выкатил целую «Войну и Мир» на тему производительности выходящего в ноябре .NET 5. И, судя по его подробному анализу, новая версия должна порадовать нас в этом смысле. Стивен сравнил .NET Framework 4.8, .NET Core 3.1 и .NET 5 (превью 8).
В общем, тесты он описал довольно подробно, всё можно перепроверить на своей машине. По его тестам выходит, что .NET 5 будет работать гораздо быстрее:
- сортировка чисел почти в 2 раза быстрее, чем Core 3.1,
- сортировка строк - на 15%,
- ToString – в 2 раза,
- ToUpperInvariant – в 2,5 раза
- в RegularExpressions получились совсем какие-то космические улучшения, почти на порядок.
И т.п.

В общем, почитайте, довольно интересно https://devblogs.microsoft.com/dotnet/performance-improvements-in-net-5/

Ждём ноября.
День пятьсот тридцать третий.
Сертификат Microsoft. Экзамен 70-486. Шаг третий
Сегодня немного необычный пост. Я продолжаю подготовку к экзамену 70-486 Developing ASP.NET MVC Web Applications.
Microsoft предлагают список оцениваемых навыков. Его довольно сложно читать, т.к. всё в кучу с вычёркиваниями, добавлениями, исправлениями… Поэтому я решил отформатировать его и начал подбирать источники для подготовки.

Весь список я выложил на GitHub в виде readme документа: https://github.com/sbzenenko/ASP.NET-MVC-Exam-70-486

Я постепенно буду его дополнять источниками. Тут акцент будет не на книги, которые стоит почитать в общем, а на то, где найти информацию по конкретной узкой теме: глава или страницы книги, ссылка на статью, туториал, видео и т.п. Проблема в том, что рекомендуемое Microsoft руководство для подготовки («Exam Ref 70-486 Developing ASP.NET MVC 4 Web») датируется 2013м годом, т.е. содержит крайне устаревшую информацию.

Поэтому у меня большая просьба к сообществу. Если кто-то знает, где найти информацию по предложенным темам (особенно интересует всё, что касается Azure), пожалуйста, советуйте:
- в личке или в чате (в этом случае лучше указывайте пункт, например, 5.1.4.
- в issues на github (я могу добавить в контрибьюторы, если вам будет удобнее сам документ редактировать).

Надеюсь, что этот сборник будет полезен не только в плане подготовки к экзамену, но и всем, кто хочет всесторонне изучить предмет или, наоборот, найти информацию по узкой теме.

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

Заранее всем спасибо.
.NET Разработчик pinned «День пятьсот тридцать третий. Сертификат Microsoft. Экзамен 70-486. Шаг третий Сегодня немного необычный пост. Я продолжаю подготовку к экзамену 70-486 Developing ASP.NET MVC Web Applications. Microsoft предлагают список оцениваемых навыков. Его довольно сложно…»
День пятьсот тридцать четвёртый. #DevOps
Как Убить Производительность Разработчиков. Начало
Немного нестандартная серия постов не совсем про кодинг, а про DevOps. Генеральный директор Humanitec Каспар фон Грюнберг делится некоторыми мыслями о производительности труда разработчиков и о том, как её улучшить.

Убийца №1: Бросить всё ради микросервисов без надлежащего инструментария
Когда команды работают с монолитными приложениями, всё работает хорошо. Цепочка инструментов хорошо подготовлена и справляется с задачей. Но малейшее изменение требует пересборки всего приложения. Необходимо провести сквозные тесты, чтобы убедиться, что всё в порядке. Чем больше монолитное приложение, тем менее эффективным это будет. Команда принимает решение использовать микросервисы. Первый опыт великолепен, коллеги могут работать над отдельными сервисами независимо, частота развёртывания возрастает, и все довольны.

Проблемы начинаются, когда команды увлекаются микросервисами и воспринимают «микро» слишком серьезно. С точки зрения инструментария вам теперь придется иметь дело с гораздо бОльшим количеством yml-файлов, docker-файлов, с зависимостями между переменными этих сервисов, проблемами маршрутизации и т.д. Микросервисы должны поддерживаться, обновляться и обслуживаться. Ваши настройки CI/CD, а также ваша организационная структура и, возможно, численность персонала нуждаются в обновлении.

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

Убийца №2: Использование контейнеров без плана рефакторинга настроек
Контейнерирование - это потрясающая технология для многих ситуаций. Тем не менее, она имеет свою цену и может повлиять на вашу производительность. Контейнеры увеличивают накладные расходы на обеспечение безопасности и необходимую настройку, управление средой и т.д. Они также могут снизить вашу производительность и испортить жизнь разработчикам, если вы не выработаете определённые соглашения в команде.

Самая распространенная ошибка - это встраивание ваших файлов конфигурации или переменных среды в контейнер. Основная идея контейнеризации - мобильность. При жёсткой конфигурации вам придётся писать настройки для каждой отдельной среды. Вы хотите изменить URL? Хорошо, измените его в 20 разных местах, а затем пересоберите проект.

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

Продолжение следует…

Источник:
https://dzone.com/articles/how-to-kill-your-developer-productivity-humanitec
День пятьсот тридцать пятый. #DevOps
Как Убить Производительность Разработчиков. Продолжение
Убийца №3: Неправильное Использование Kubernetes
Все крутые ребята расхваливают Kubernetes. Тем не менее, его трудно поддерживать и трудно интегрировать в ваш поток разработки, сохраняя при этом высокую производительность. Многое может пойти не так.

Худший случай использования Kubernetes: Коллега X очень хотел его попробовать и нашёл руководство для начинающих онлайн. Они создали кластер с нуля, и он отлично работал с тестовым приложением. Затем они начали миграцию первого приложения и попросили своих коллег начать взаимодействие с кластером с помощью kubectl. Половина команды теперь была занята изучением этой новой технологии. Человек, который обслуживает кластер, теперь будет занят этим постоянно, как только кластер получит первую рабочую нагрузку. Конфигурация CI/CD совершенно не подготовлена ​​для решения этой проблемы, и общая производительность снижается, поскольку вся команда пытается сбалансировать Kubernetes.

Kubernetes - это потрясающая технология, которая, если все сделано правильно, может вам помочь. В конце концов, она исходит от Borg - платформы, созданной Google, чтобы их разработчикам было легче создавать масштабируемые приложения. Таким образом, это своего рода интерпретация внутренней платформы Google.

Лучшие практики:
1. Там, где это возможно, команды не должны сами устанавливать и запускать barebone кластер, а должны использовать управляемую службу Kubernetes. Прочитайте отзывы о том, какой управляемый кластер Kubernetes лучше всего соответствует вашим потребностям. На данный момент Google Kubernetes Engine (GKE) является лучшим с чисто технической точки зрения. За ним следуют службы Azure Kubernetes (AKS) и Amazon Elastic Kubernetes Service.
2. Используйте платформы автоматизации или API непрерывной доставки. Они позволяют запускать вашу рабочую нагрузку на K8 вне поля зрения разработчиков. Практически не имеет смысла посвящать всех в сложности процесса конфигурации.
3. Если команда действительно хочет, чтобы разработчики сами управляли кластером Kubernetes, нужно дать им достаточно времени, чтобы по-настоящему понять архитектуру, шаблоны проектирования, kubectl и т.д. и действительно сосредоточиться на этом.

Убийца №4: Игнорирование постоянной доставки
Существует распространенное заблуждение, что работа выполнена хорошо, если настроена непрерывная интеграция. Но вам всё ещё не хватает непрерывной доставки! Многие из тех, кто использует термин «инструмент CI/CD» думают, что добились непрерывной доставки, если у них есть Jenkins, CircleCI и т.д. Но это не так.

Тщательная настройка Continuous Delivery, с использованием собственных сценариев или «как услуга», является гораздо более важным «связующим звеном»:
1. Она позволяет интегрировать все различные компоненты, от системы управления исходным кодом до CI-Pipeline, от базы данных до кластера и от настройки DNS до IaC, в удобную среду для разработчиков.
2. Это способ структурировать, поддерживать и управлять растущим количеством сценариев yml и конфигурации. Если всё сделано правильно, это позволит вашим разработчикам динамически разворачивать среды с помощью артефактов, созданных CI-Pipeline с полной настройкой и подготовкой базы данных.
3. Она может выступать в качестве системы контроля версий для состояний конфигурации с подтверждённой записью о том, что, где, в какой конфигурации развернуто, и позволяет выполнять откат назад и вперед, а также управлять развёртываниями.
4. Хорошо продуманные настройки CD оказывают кардинальное влияние на производительность труда разработчиков. Они делают разработчиков самодостаточными, уменьшают количество зависимостей в команде, повышая удобство обслуживания вашей конфигурации.
5. Команды, использующие эти методы, делают релизы чаще, быстрее, демонстрируют в целом более высокую производительность и удовлетворённость от работы.

Окончание следует…

Источник:
https://dzone.com/articles/how-to-kill-your-developer-productivity-humanitec
День пятьсот тридцать шестой. #DevOps
Как Убить Производительность Разработчиков. Окончание
Убийца №5: Неуправляемая автоматизация тестирования в ограниченной конфигурации тестов
Эффективное тестирование невозможно без автоматизации. С непрерывной доставкой приходит непрерывная ответственность, чтобы ничего не сломать.
Вы должны постоянно следить за тем, чтобы не попасть в ловушку инвертирования тестовой пирамиды. Для этого вам нужно иметь возможность запускать правильные тесты в нужной точке жизненного цикла разработки.

Достаточный инструментарий CI поможет вам правильно разместить модульные и интеграционные тесты в нужном месте, а инструментарий CD с управлением конфигурацией и средой поможет вам надёжно выполнять автоматизированные сквозные тесты.

Хорошо выполненные настройки позволяют разработчикам или тестировщикам динамически разворачивать предварительно настроенные среды. Строго экспортируйте вашу конфигурацию и убедитесь, что у вас есть система управления конфигурацией, позволяющая использовать нужные параметры при развёртывании. Это приводит к ряду улучшений:
- Выполнению правильных тестов в нужное время, обеспечивая эффективную обратную связь с командой разработчиков.
- Разработчики получат автономию, а вы уменьшите зависимость от ключевых людей.
- QA смогут выполнять подмножества тестов в функциональных средах, а также распараллеливать тестирование.

Убийца №6: Самостоятельное управление базами данных
Товарищ по команде, который только что ушел, отвечал за настройку MongoDB для клиентского проекта и, конечно, использовал проект с открытым исходным кодом, в котором размещалась база. И, естественно, передача дел была «безупречной», база данных не была должным образом защищена, и однажды вечером случилось то, что должно было: «Ваша база данных была сохранена и архивирована. У вас есть 7 дней, чтобы её восстановить. Пришлите 0.1 BTC …»
И конечно:
- Вы проверяете резервные копии.
- В коде резервного копирования обнаружилась ошибка.
- Теперь вам нужно восстанавливать все данные.

Это реальный пример, который часто случается. Самоуправляемые БД представляют собой операционный риск и угрозу безопасности. Используйте Cloud SQL или другие предложения и спите спокойно. Эти сервисы предлагают большинство баз данных на всех крупных облачных провайдерах, и они являются более многофункциональными, зрелыми и защищёнными. Кроме того, они часто дешевле и доставляют минимум неудобств для разработчика.

Убийца №7: Использование нескольких облаков без причины
Есть разница между переходом на несколько облаков и попыткой сделать ваши системы независимыми от облачных вычислений и переносимыми. Последнее имеет много различных преимуществ, таких как динамические среды, и имеет больше смысла, чем переход на несколько облаков. Конечно, есть наследие: одни команды использовали GCP, другой отдел начал с AWS, а третьим нужны специальные условия - и вуаля. Можно спорить, что одни сервисы работают лучше или дешевле, чем другие. Но чтобы эти эффекты действительно имели значение, вам нужен достаточный объём. Несложные многооблачные установки требуют высокой степени автоматизации и защиты разработчиков от задач их настройки и поддержки. В противном случае человек попадает в ад сценариев.
Как правило: не используйте несколько облаков, если в этом нет необходимости.

Итого
«1% лучших команд делают релизы в 10 раз чаще остальных». Это потому, что они используют большую часть того, что им доступно. Остановитесь и проведите полдня в месяц, пересматривая свои рабочие процессы, списки дел и способы организации своих приложений, чтобы обеспечить оптимальную производительность. Потому что потраченное время действительно накапливается. Крошечные проблемы загружают ваш мозг. Пересмотр ваших процессов поможет вам сосредоточиться на деле, а не на настройке, и сделает вас и вашу команду счастливее.

Источник: https://dzone.com/articles/how-to-kill-your-developer-productivity-humanitec
День пятьсот тридцать седьмой. #Оффтоп #97Вещей
97 Вещей, Которые Должен Знать Каждый Программист
51. Не Забывайте про "Hello World!"
Пол Ли, более известный как Хоппи, имел в компании репутацию эксперта по вопросам программирования. Мне нужна была помощь, я подошёл к столу Хоппи и спросил, может ли он взглянуть на один кусок кода.

«Конечно», - сказал он, - «тащи стул». Я аккуратно, чтобы не опрокинуть пустые банки от колы, сложенные в пирамиду позади него, присел рядом.

- Что за код код?
- В функции XXX в файле YYY, - сказал я.
- Так, давай посмотрим на эту функцию, - Хоппи свернул свой код и пододвинул свою клавиатуру ко мне.
- А где IDE?

Похоже, у Хоппи не была запущена IDE, просто открыт какой-то редактор, с которым я не был знаком. Он схватил обратно клавиатуру. Пара нажатий клавиш, и нужный файл открыт на нужной функции - это была довольно большая функция. Хоппи переключился на условный блок, о котором я хотел спросить.

«Что тут произойдёт, если х отрицательный?» - спросил я. - «Здесь явно ошибка.»

Все утро я пытался найти способ заставить x быть отрицательным, но большая функция в большом файле была частью большого проекта, и цикл перекомпиляции, а затем повторного запуска моих экспериментов утомил меня. Кто, как не Хоппи, может дать мне ответ?

Хоппи признался, что не уверен. К моему удивлению он не стал открывать IDE. Вместо этого он скопировал блок кода в новое окно редактора, отформатировал его и обернул в функцию. Вскоре он написал простейший код консольного приложения, которое в бесконечном цикле запрашивало у пользователя входные значения, передавая их в функцию, и распечатывало результат. Он сохранил код как новый файл, tryit.cs. Всё это я мог бы сделать сам, хотя, возможно, не так быстро. Но его следующий шаг был удивительно прост и в то же время совершенно чужд моему способу работы:
csc tryit.cs

И вот его программа, придуманная всего пару минут назад, уже работала. Мы попробовали несколько значений и подтвердили мои подозрения (ну хоть в чём-то я оказался прав!). Затем он перепроверил соответствующий код в проекте уже в IDE. Я поблагодарил Хоппи и ушёл, снова стараясь не разрушить его пирамиду из колы.

Вернувшись за свой рабочий стол, я закрыл свою IDE. Я настолько привык работать над большим проектом с помощью сложных инструментов, что стал думать, что только так и нужно делать. Но мощный компьютер может выполнять и простейшие задачи. Я открыл текстовый редактор и начал печатать:
using System;
class Program {
static void Main(string[] args) {
Console.WriteLine("Hello World!");
}
}

Источник: https://www.oreilly.com/library/view/97-things-every/9780596809515/
Автор оригинала – Thomas Guest (в оригинале был код на C).