Friday, April 18, 2014

Обзор встречи Kiev ALT.NET

Здравствуйте, уважаемые читатели моего блога. Эта статья посвящена мероприятию, которое мне посчастливилось посетить Kiev ALT.NET. Конференция была организована компанией Ciklum, за что хотелось бы выразить огромною благодарность организаторам, поскольку все было сделано на высшем уровне. Встреча проходила на 20-ом этаже, в очень просторном помещении, в обстановке, которая чем-то напоминает домашнюю. Ниже приведена картинка офиса, в котором проходила конференция.
Только все пуфики были расположены полумесяцем вокруг проектора. С места, в котором была встреча, открывается бесподобный вид на Киев.  Я взял с блога фото панорамы, поскольку из-за дождя фотографии у меня получились невысокого качества.
Также позитивным моментом была возможность выпить сок или чай/кофе, угоститься печеньем, чипсами и конфетами. После того, как все расположились, нам рассказали несколько слов о докладах, которые будут представлены на встрече. В начале конференции также поступило предложение от организаторов продолжить обсуждения конференции за кружкой пива при желании и наличии дополнительных вопросов к докладчикам. По семейным обстоятельствам я не смог остаться на этом мероприятии, но думаю, что оно состоялось. Также была озвучена новость о том, что данную встречу планируют сделать регулярной. Это не может не радовать, так как доклады, которые были представлены на конференции, были профессионально подготовленные и интересные, что немаловажно. 
На встрече было представлено два доклада из запланированных трех. Не был представлен доклад "Canopy: F# DSL for Webdriver от Serhiy Kalinets", так как предыдущие доклады оказались настолько увлекательными, что заняли все время, выделенное на встречу.  Первым выступил Аким Бойко (Akim Boyko) со своим докладом "FsCheck: Property-based testing for F# and C#". Ниже привел фото автора доклада.
До этого мне приходилось слушать доклады этого автора, поэтому не было сомнений в том, что материал будет интересен. Один из докладов этого автора я впервые услышал, когда решил познакомиться с проектом Roslyn и нашел один из его докладов "Метапрограммирование в .Net: RoslynCTP". Все время на встрече я старался нотировать интересные вещи, почерпнутые с докладов, и пока они держатся в голове, хотел бы поделиться ими с вами. 
Началом доклада было банальное ознакомление с библиотекой FsCheck, которая предназначена для случайного и автоматического тестирования, основанного на свойствах. Также нам кратко рассказали о выборках тестирования с помощью функций forAll, throws, within, trivial и atLeastOne.  Записывал по памяти, так что могут быть опечатки. Также были кратко рассмотрены аналогичные механизмы тестирования для языка ScalaScalaCheck и другие, которые, к сожалению, я не записал, понадеявшись на свою память. Забыл упомянуть тот факт, что, по сути, FsCheck работает с языком F#. Подружить его с языком C# можно, но очень проблематично. Одной из проблем, почему это составляет проблему, являются Generators – генераторы, которые генерируют входные данные для тестируемых методов.
Основное отличие от стандартных Unit тестов, к которым мы привыкли при использовании подхода с TDD или BDD, состоит в том, что FsCheck позволяет модифицировать входную последовательность по ходу выполнения.  Также мы можем указать, сколько генераций нам необходимо выполнить для тестируемого метода. По умолчанию в FsCheck задано 100 итераций, что бывает очень мало, если нужно протестировать, например, наличие вершины в графе. Частично такую возможность в юнит-тестах, которую позволяет покрыть FsCheck, можно сделать с помощью TestCase + Contracts. При написании тестов для FsCheck существует такое понятие, как Shrinkers – это минимальный набор входных данных, на которых получается получить ошибку. Также отличие FsCheck от стандартных юнит-тестов – в том, что позволяют проанализировать полностью выполнения тестирование метода, в то время как юнит-тест свалится при первой же ошибке. 
Основная проблема FsCheck для языка C# состоит в сложности написания генераторов. Написать генераторы для F– процесс непростой, а для C# он намного сложнее. Во-первых, он слабо документирован, и синтаксис местами не понятен. Вторая проблема заключается в том, что все результаты тестирования выводятся в Output. Подружить с FsCheck с классическими юнит-тестами сложно. Хотя существует интеграция FsCheck с xUnit, если верить докладу, потому что отдельно я не разбирал эту тему. Поскольку единственный язык, который понимают юнит-тесты, об ошибке выполнения, есть бросание исключения, то с парсингом выходного результата, который нам дает FsCheck, есть множество проблем. 
Иногда процесс написания последовательности для теста может быть намного сложнее, чем сам тест. Одним из плюсов, о которых говорил автор доклада , является то, что подход с FsCheck заставляет разработчика думать о своих тестах и коде в пределах контрактов. К сожалению, я с этим не согласен, поскольку думать терминами контрактов можно уже сейчас, и подружить контракты с юнит-тестами можно без проблем. Контракты, которые уже есть в .NET 4.0, могут служить неплохим дополнением к тестам. По поводу того, как можно к своему коду подходить с точки зрения контрактов, рекомендую статьи известного в Украине MVP Сергея Теплякова "Контракты vs Юнит тесты" и "Контракты, состояние и юнит-тесты". Я к контрактам отношусь довольно предвзято, но отрицать их полезность в подходе к разработке не могу. Пожалуй, с докладом о FsCheck закончу, остановившись на втором докладе, ради которого, признаться честно, я и хотел пойти на встречу. Этот доклад  "C# Under the hood от Antya Dev " (Антон Молдован). Ниже привел фото автора.
Доклад был сделан профессионально и интересно. Автор доклада часто употреблял много жаргонных словечек из программистского лексикона, что придавало докладу особый колорит. Материал затрагивал несколько интересных вещей, по которым я и пройдусь. Доклад состоял из пяти условных частей:
  • switch;
  • lifted operators;
  •  lambda expressions;
  • async/await;
  • dynamic.
Теперь немного расскажу о том, что подразумевал под собой каждый из пунктов выше.  Что вы знаете об операторе switch? Если вы знаете, как работает оператор switch на уровне кода и как он оптимизирует свои запросы, то эта часть для вас может быть неинтересной. Но, как оказалось, я заблуждался насчет некоторых моментов работы switch.  Одним из таких нюансов есть использование данного оператора для сравнения строк. Я всегда думал, что для такого кода
string a = "f";
switch (a)
{
       case "a":
             Console.WriteLine("a"); break;
       case "b":
             Console.WriteLine("b"); break;
       case "c":
             Console.WriteLine("c"); break;
       case "d":
             Console.WriteLine("d"); break;
       case "e":
             Console.WriteLine("e"); break;
       case "f":
             Console.WriteLine("f"); break;
}
компилятором строится таблица переходов (хеш-таблица), и в данном контексте switch работает быстро. Оказывается я заблуждался, на уровне Il кода происходит самое обычное сравнение строк, если значений в операторе switch меньше 7 (актуально для строк); если больше или равно 7-ми case значениям, тогда уже строится хеш-таблица. Ниже приведен IL код, который подтверждает эти слова.  
// Methods
    .method private hidebysig static
        void Main (
            string[] args
        ) cil managed
    {
        // Method begins at RVA 0x23b0
        // Code size 171 (0xab)
        .maxstack 2
        .entrypoint
        .locals init (
            [0] string a,
            [1] string CS$0$0000
        )

        IL_0000: ldstr "f"
        IL_0005: stloc.0
        IL_0006: ldloc.0
        IL_0007: dup
        IL_0008: stloc.1
        IL_0009: brfalse IL_00a4

        IL_000e: ldloc.1
        IL_000f: ldstr "a"
        IL_0014: call bool [mscorlib]System.String::op_Equality(stringstring)
        IL_0019: brtrue.s IL_005e

        IL_001b: ldloc.1
        IL_001c: ldstr "b"
        IL_0021: call bool [mscorlib]System.String::op_Equality(stringstring)
        IL_0026: brtrue.s IL_006a

        IL_0028: ldloc.1
        IL_0029: ldstr "c"
        IL_002e: call bool [mscorlib]System.String::op_Equality(stringstring)
        IL_0033: brtrue.s IL_0076

        IL_0035: ldloc.1
        IL_0036: ldstr "d"
        IL_003b: call bool [mscorlib]System.String::op_Equality(stringstring)
        IL_0040: brtrue.s IL_0082

        IL_0042: ldloc.1
        IL_0043: ldstr "e"
        IL_0048: call bool [mscorlib]System.String::op_Equality(stringstring)
        IL_004d: brtrue.s IL_008e

        IL_004f: ldloc.1
        IL_0050: ldstr "f"
        IL_0055: call bool [mscorlib]System.String::op_Equality(stringstring)
        IL_005a: brtrue.s IL_009a

        IL_005c: br.s IL_00a4

        IL_005e: ldstr "a"
        IL_0063: call void [mscorlib]System.Console::WriteLine(string)
        IL_0068: br.s IL_00a4

        IL_006a: ldstr "b"
        IL_006f: call void [mscorlib]System.Console::WriteLine(string)
        IL_0074: br.s IL_00a4

        IL_0076: ldstr "c"
        IL_007b: call void [mscorlib]System.Console::WriteLine(string)
        IL_0080: br.s IL_00a4

        IL_0082: ldstr "d"
        IL_0087: call void [mscorlib]System.Console::WriteLine(string)
        IL_008c: br.s IL_00a4

        IL_008e: ldstr "e"
        IL_0093: call void [mscorlib]System.Console::WriteLine(string)
        IL_0098: br.s IL_00a4

        IL_009a: ldstr "f"
        IL_009f: call void [mscorlib]System.Console::WriteLine(string)

        IL_00a4: call valuetype [mscorlib]System.ConsoleKeyInfo [mscorlib]System.Console::ReadKey()
        IL_00a9: pop
        IL_00aa: ret
    } // end of method Program::Ma
Пожалуй, перейдем ко второй теме и поговорим о lifted operators. Это операторы, которые позволяют работать безопасно с nullable типами данных. Например, валидной является запись
public static int? Result(int? a, int? b)
{
       return a + b;
}
И другие нюансы, связанные с nullable типами.
Следующая тема Lambda Expression затронула удивительный мир монад. Автор доклада почему-то затронул только ту часть лямбда-выражений, которая строится вокруг точечной нотации. К сожалению, в этой теме для себя я не узнал ничего нового, правда, причина этого была в том, что я уже знаком с монадами со статей Ерика Липперта в его блоге Fabulous Adventures In Coding. Правда, автор рассказывал о монадах довольно интересно. Эта тема была очень беглой и, по сути, автор доклада ознакомил слушателей только с монадой MayBe и показал пример ее использования. Это тоже очень неплохо из-за ограниченности по времени доклада.
Следующей интересной темой лично для меня было объяснение того, как работает async/await в C#. Также был создал искусственный пример, который эмулировал работу с async/await, как это делает компилятор. Понравился тот момент, что автор указал на популярную ошибку при использовании async/await: использование явно метода WaitAll или Result, что, по сути, вешало основной поток. После того как был продемонстрирован пример, я понял, почему это происходило.
Последняя тема, которая вызвала дискуссию в зале, была тема, связанная с dynamic. Автор доклада рассказал невзначай о своем фреймворке, над которым он работает (KingAOP). Сама тема не касалась этого фреймфорка и он был затронут вскользь, но я специально самостоятельно позже посмотрел, на чем основывается данный фреймворк (в основе лежит dynamic и IDynamicMetaObjectProvider и фреймфорк PostSharp) и не смог придумать ему применения, наверное, больше из-за своей нелюбви к PostSharp. Сам же доклад о dynamic очень понравился, поскольку рассказал о том, как работает данный тип изнутри IL. Но он вызвал также множество вопросов и дискуссий по поводу DLR, которая была затронута в рамках этого доклада. Лично я выразился о том, что DLR на данный момент не доделана до конца, и что dynamic (ExpandoObject/Dynamic– лишь верхушка айсберга, а другие языки, как IronPython и IronRuby, не прижились и, по сути, являются недоделанными частями DLR. Также очень тормозит взаимодействие между C# кодом и IronPython через ScriptEngine. Также на взаимодействие накладывается куча ограничений. В целом, тема была позитивной и приоткрыла некоторые занавесы мира C#.

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

No comments:

Post a Comment