воскресенье, 28 июня 2015 г.

Идиома Process Tasks By Completion

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

Можно подойти к этой задаче в лоб. Крутим цикл, запускаем таски, обрабатываем результаты по одному:

private Task<Weather> GetWeatherForAsync(string city)
{
   
Console.WriteLine("[{1}]: Getting the weather for '{0}'"
, city,
       
DateTime.Now.
ToLongTimeString());
   
return WeatherService.
GetWeatherAsync(city);
}


[
Test]
public async Task
ProcessOneByOneNaive()
{
   
var cities = new List<string> { "Moscow", "Seattle", "New York"
};

   
var tasks =
        from city in
cities
       
select new { City = city, WeatherTask =
GetWeatherForAsync(city) };

   
foreach (var entry in
tasks)
    {
       
var wheather = await entry.
WeatherTask;

        ProcessWeather(entry
.
City, wheather);
    }
}

private void ProcessWeather(string city, Weather
weather)
{
   
Console.WriteLine("[{2}]: Processing weather for '{0}': '{1}'"
, city, weather,
       
DateTime.Now.ToLongTimeString());
}

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

четверг, 18 июня 2015 г.

Небольшой трюк при работе с ConcurrentDictionary

У использования ConcurentDictionary есть одна особенность: в некоторых случаях он может вести себя не совсем так, как вы того ожидаете. Вот небольшой пример. Допустим, нам нужно запилить небольшой кэш, чтобы результаты дорогостоящей операции брались из кэша, если они там есть, ну и добавлялись в кэш прозрачным образом, если Акела промахнулся.

Простая реализация некоторого провайдера с cache aside паттерном будет выглядеть примерно так:

public class CustomProvider
{
   
private readonly ConcurrentDictionary<string, OperationResult> _cache =
        new ConcurrentDictionary<string, OperationResult>
();

   
public OperationResult RunOperationOrGetFromCache(string
operationId)
    {
       
return _cache.GetOrAdd(operationId, id =>
RunLongRunningOperation(id));
    }

   
private OperationResult RunLongRunningOperation(string
operationId)
    {
       
// Running real long-running operation
        // ...
        Thread.Sleep(10
);
       
Console.WriteLine("Running long-running operation"
);
       
return OperationResult.Create(operationId);
    }
}

 

пятница, 12 июня 2015 г.

Синдром “придумано не нами”

Ваш код сегодняшний, коллега
Напоминает даунхил:
Среди деревьев и гов#@ща –
Велосипед и костыли ...
Народная мудрость

Пару лет назад я сделал небольшой цикл заметок о паттернах поведения: Технический долг, Синдром рефакторинга и Эффект второй системы. Пришло время обсудить еще один, наверное, самый известный и популярный паттерн поведения – синдром «Придумано не нами» (NIH, Not Invented Here).

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

У «забить на существующее и сделать по-своему» есть несколько причин.

понедельник, 8 июня 2015 г.

Обязательные аргументы в PowerShell

Я не понимаю PowerShell. А раз так, то нужно попробовать устаканить свои знания и поделиться ими с миром.

Главная проблема PowerShell, ИМХО, – динамическая типизация и «адаптивная» система типов. PowerShell всеми силами старается избежать ошибки времени исполнения путем конвертации типов туда и обратно (Хоббит, блин!).

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

Параметр метода в PowerShell может быть $Null в одном из двух случаев: пользователь явно передал $Null в качестве значения аргумента. Или же пользователь вообще не указал данный аргумент при вызове метода. Мне, как автору метода, обычно все равно, почему параметр отсутствует. Я просто хочу гарантировать, что он не будет Null. Но, чтобы добиться этого, придется использовать разные подходы.

понедельник, 11 мая 2015 г.

Майкрософт, часть 2. Карьерная лестница

Все, о чем я здесь пишу, является моим личным мнением, которое не является официальным мнением моего работодателя. Так, на всякий случай!

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

Киевские софтверные «гиганты» и общая культура IT компаний очень сильно отличаются от американских. Прежде всего, это связано с культурными отличиями, средним возрастом сотрудников и размерами компаний. Средний возраст влияет на то, как ведут себя люди в офисе, как они одеваются, и о чем говорят на кухне или в курилке. Средний возраст сотрудников киевской IT компании существенно ниже, чем в американской или европейской. Этот показатель у нас тоже начинает расти, но разница все еще остается очень существенной. Прибавьте сюда наш менталитет и общительность, и получите довольно большую разницу в том, как проходит неформальное общение. В киевском офисе ржачь стоял с завидным постоянством, ничего подобного в Штатах я не видел. Хотя вру, в нью-йорской конторе такое было, прямо перед тем, как ту команду разогнали;)

Средний возраст и размер компаний очень сильно влияют на карьерный рост. В украинской компании, если тебе 25 и ты не синьер, то ты явно что-то делаешь не так. Это же приводит к определенным проблемам, когда тебе тридцать и у тебя есть амбиции расти в техническом плане. У нас (да, я все еще отношу себя к «нам») относительно легко продолжить расти в тим-лидах или ПМ-ах, но чисто техническая лестница оказывается довольно короткой. Есть позиция архитектора, но архитектор в 30 – это все же вынужденная мера отечественного аутсорса для выделения касты «продвинутых синьеров», их нельзя сравнивать с архитекторами МС-а или Гугла. Поверьте.

четверг, 16 апреля 2015 г.

Разница между шаблонами и паттернами

Выбор правильного термина – дело непростое. Выбор русскоязычного варианта – еще и неблагодарное. Занимаясь научным редактированием переводов книг по IT-тематике я всегда сталкивался с проблемой выбора правильного русскоязычного варианта. Сложность заключается в отсутствии единого мнения по поводу перевода некоторых важных терминов, что приводит к проблеме выбора «наименьшего зла» между распространенным, но неточным термином и более емким, но никому неизвестным вариантом.

С термином “pattern” тоже была интересная история. Изначально, этот термин был переведен как «шаблон», и в первых книгах начала нулевых использовался в основном этот термин, а спустя некоторое время, все больше стал набирать популярность вариант «паттернов проектирования».

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

среда, 8 апреля 2015 г.

Как правильно развиваться?

Это несколько расширенная версия ответа на похожий вопрос, который был задан в русскоязычном ru.stackoverflow.com. А поскольку повторное использование – это наш все, к тому же, этот вопрос мне задают с завидным постоянством, то я решил оформить свои мысли отдельным постом.

Эффективное развитие – это очень субъективная тема. Это значит, что если что-то подходит мне, это не обязательно подойдет и тебе. Самое главное для саморазвития – это стабильная мотивация в течение длительного времени. И только вы сможете найти правильный баланс между теорией и практикой, подобрать правильную частоту переключения между темами и найти стимул к изучению чего-то нового.

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

  1. Хорошие источники
  2. Упор на получение стабильных знаний
  3. Итеративность обучения и практика
  4. Относительно четкий план развития
  5. Разнообразие тем
  6. Мотивация

Теперь по порядку.