Вставьте код функции
Mutate
(без использования ключевого слова unsafe
), чтобы на консоль вывелось «404». Сигнатуру функции не менять, замыкания не ловить
const string constStr = "000";
Mutate(constStr);
var nonConst = "000";
Console.WriteLine(nonConst);
void Mutate(string str)
{
// write your code here
}
Вот пример решения, которое полностью устроило лида, который собеседовал кандидата.
void Mutate(string str)
{
GCHandle handle = GCHandle.Alloc(str, GCHandleType.Pinned);
IntPtr pointer = handle.AddrOfPinnedObject();
Marshal.WriteByte(pointer, 0, (byte)'4');
Marshal.WriteByte(pointer, 4, (byte)'4');
handle.Free();
}
Весь смысл кроется в том, как работают строки в .net (интернирование), что такое pinned object и как работать с unmanaged кодом.
Идея интернирования строк состоит в том, чтобы хранить в памяти только один экземпляр типа String для идентичных строк. При старте нашего приложения виртуальная машина создаёт внутреннюю хэш-таблицу, которая называется таблицей интернирования (иногда можно встретить название String Pool).
Pinned Object Heap (POH, Куча Закрепленных Объектов). В отличие от других видов кучи, эта доступна разработчикам явно (что не характерно для сборщика мусора).
Пишите свое решение в комментариях👇
@csharp_ci
Please open Telegram to view this post
VIEW IN TELEGRAM
Асинхронность вызывает большие проблемы у многих, но выход есть — вот:
async/await
— Stephen Cleary. Вводная статьяawait
, но тут как с блоком итератора yield
- код пишется, а руки трясутся.SynchronizationContext
. Начать можно с этой статьи на MSDN. Но если она покажется душной, переходите к пункту 5.TaskScheduler
.@csharp_ci
Please open Telegram to view this post
VIEW IN TELEGRAM
Что выведет на экран это код?
Anonymous Quiz
44%
с :1,4,5,7,2 l :1,4,5,7,3
30%
с :1,4,5,6,7,2 l :1,4,5,7,3
10%
с :1,4,5,6,7,2 l :1,4,5,6,7,2
16%
с :1,4,5,6,7,2,3 l :1,4,5,6,7,2,3
Хотелось бы как-то "накопить" обновления, пока обработчик занят. Причём, сами данные для обновления уже "накапливаются", об этом заботиться не нужно, нужно только разрулить "накопление" запросов к обработчику, чтобы когда обработчик освободиться обрабатывать не все накопившиеся запросы на обновление по отдельности, а за один раз сразу весь пакет "обновлений" обработать.
Вот так происходит сейчас:
async Task UpdateFoo()
{ ...
await SaveAsync();
}
async Task UpdateBar()
{ ...
await SaveAsync();
}
async Task UpdateBaz()
{ ...
await SaveAsync();
}
async Task SaveAsync()
{ // здесь нужно сделать так,
// чтобы одновременно обрабатывался только 1 запрос
// по окончании которого проверялось бы не было ли ещё запросов
// и если были, то обновление запускалось бы ещё 1 раз (сразу за всё "накопленное")
// и так пока есть обновления по окончании очередной обработки
}
Как это можно нормально написать? Для того, чтобы зайти один раз — понятно,
SemaphoreSlim
, видимо (с WaitAsync
). А вот остальное как лучше сделать?System.Threading.Channels.Channel<T>
:private readonly Channel<T> _channel = Channel<T>.CreateUnbounded();
private Task _workerTask;
private async Task WorkerAsync()
{
ChannelReader<T> reader = _channel.Reader;
List<T> list = new();
// ждём здесь, если в канале пусто
while (await reader.WaitToReadAsync())
{
// забираем всё что есть
// ну или можно счётчиком ограничить максимальное количество выгребаемых данных за раз
while (reader.TryRead(out T data))
{
list.Add(data);
}
// пачка собрана, погнали. это можно в try-catch завернуть, чтобы воркер не падал
await UseAsync(list);
list.Clear();
}
}
_workerTask = WorkerAsync();
Чтобы закинуть в канал:
_channel.Writer.TryWrite(x);
WorkerAsync
завершился, нужно вызвать:_channel.Writer.Complete();
await _workerTask;
Вот и все дела
@csharp_ci
Please open Telegram to view this post
VIEW IN TELEGRAM
Относительно недавно на свет появился ASP.NET Core 8.0, и теперь можно обрабатывать ошибки с помощью
IExceptionHandler
. А вот и полезная статья о том, как это делать.
IExceptionHandler
IExceptionHandler
— это интерфейс, который предоставляет разработчику обратный вызов для обработки известных исключений в центральном расположении.IExceptionHandler
реализации регистрируются путем вызова IServiceCollection.AddExceptionHandler
. Время существования экземпляра IExceptionHandler
— одноэлементное. Можно добавить несколько реализаций, и они вызываются в порядке регистрации.Если обработчик исключений обрабатывает запрос, он может вернуться
true
к остановке обработки. Если исключение не обрабатывается обработчиком исключений, то элемент управления возвращается к поведению по умолчанию и параметрам из по промежуточного слоя. Для обработки и необработанных исключений создаются различные метрики и журналы.@csharp_ci
Please open Telegram to view this post
VIEW IN TELEGRAM
Итак кейс: выполняется некоторый код, выбрасывается исключение
NullReferenceException
со следующим сообщением:Object reference not set to an instance of an object (В экземпляре объекта не задана ссылка на объект)
Что же это значит, и как исправить код?
Вы пытаетесь воспользоваться чем-то, что равно
null
(или Nothing
в VB.NET). Это означает, что либо вы присвоили это значение, либо вы ничего не присваивали.Как и любое другое значение,
null
может передаваться от объекта к объекту, от метода к методу. Если нечто равно null
в методе "А", вполне может быть, что метод "В" передал это значение в метод "А".Если среда выполнения выбрасывает
NullReferenceException
, то это всегда означает: вы пытаетесь воспользоваться ссылкой. И эта ссылка не инициализирована (или уже не инициализирована).Это означает, что ссылка равна
null
, а вы не сможете вызвать методы через ссылку, равную null
, как тут:string foo = null;
foo.ToUpper();
Этот код выбросит исключение
NullReferenceException
на 2 строке, потому что вы не можете вызвать метод ToUpper()
у ссылки на string
, равной null
.Как определить источник ошибки?
Общие рекомендации: поставьте точки останова в ключевых местах, изучите значения переменных, расположив курсор мыши над переменной, либо открыв панели для отладки: Watch, Locals, Autos.
Если вы хотите определить место, где значение ссылки устанавливается (или нет), нажмите ПКМ на её имени и выберите "Find All References". Затем вы можете поставить точки останова на каждой найденной строке и запустить приложение в режиме отладки. Каждый раз, когда отладчик остановится на точке останова, вы можете удостовериться, что значение верное.
Так вы придёте к месту, где значение ссылки не должно быть
null
, и определите, почему не присвоено верное значение.@csharp_ci
Please open Telegram to view this post
VIEW IN TELEGRAM
В частности, в ролике идёт речь о таких вещах как:
— Улучшает ясность и понятность кода, делая его самодокументируемым.
Пример: система управления контентом, где переменные и методы не дают ясного понимания их назначения.
— Разделение определения операции от ее реализации, улучшение модульности, упрощение тестирования и увеличение гибкости кода.
Пример: система обработки платежей, где класс реализует методы для каждого типа платежа, но добавление новых способов обработки может быть проблематичным.
— Улучшение читаемости и поддержки кода, избегая сложных и больших условных выражений.
Пример: система управления заказами, где много уровней вложенности и проверок, что затрудняет чтение и понимание кода.
@csharp_ci
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
Возможно, вы в курсе, что этот учебник существует. В любом случае, это отличный способ ознакомиться с C# и .NET
Пока что заданий в нём не много, а оглавление выглядит так:
— Запуск первой программы C#
— Объявление и использование переменных
— Работа со строками
— Другие действия со строками
— Строки поиска
— Выполнение задачи
Учебник будет развиваться и пополняться новыми заданиями, что очень неплохо
@csharp_ci
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
Держите полезную статью о том, как реализована асинхронность в C#.
О чём статья?
ExecutionContext
в .NET Core теперь является неизменяемым, что упрощает передачу контекста и делает его передачу более распространенной.CallContext
в .NET Core больше не существует, а его функции моделируются через AsyncLocal<T>
ThreadPool
реализована как ConcurrentQueue<T>
, что позволяет оптимизировать выделение памяти.AwaitUnsafeOnCompleted
в .NET Core отличается от .NET Framework, что приводит к более эффективному использованию памяти.@csharp_ci
Please open Telegram to view this post
VIEW IN TELEGRAM
«А что там собственно нового в C# 12?»
Интересное видео, в котором Евгений Федотов рассказывает о нововведениях в C# 12
О чём вообще речь?
⏩ Упрощение определения типов, использование точки с запятой вместо фигурных скобок.
⏩ Collection-оператор, объединение массивов в одну коллекцию.
⏩ Атрибут эксперимента, для указания на экспериментальный код.
⏩ Атрибут для перехвата методов.
⏩ Использование перехватчиков для логирования и других целей.
⏩ Возможность указывать функциональные значения для лямда-выражений.
⏩ Возможность выдавать псевдоним любому типу или кортежу.
⏩ и ещё освещается много всего, так что будет полезно
📎 Кликабельный план видео
📎 Видео
@csharp_ci
Интересное видео, в котором Евгений Федотов рассказывает о нововведениях в C# 12
О чём вообще речь?
@csharp_ci
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
Что выведет на экран это код
Anonymous Quiz
17%
Возникнет ошибка компиляции
7%
Возникнет необработанная ошибка времени выполнения
13%
? или Infinity
64%
Division By Zero