Code Retreat или выходим из зоны комфорта

    Привет!

    В начале лета многие крупные компании проводят стажировки для студентов последних курсов и выпускников технических специальностей. Мне посчастливилось попасть в ряды таких молодых специалистов в компанию СКБ Контур. Наше знакомство с миром разработки программного обеспечения началось с мероприятия под кодовым названием “Креш-курс” — четырехдневная интенсивная выездная школа. Было много всего интересного, увлекательного и познавательного, но об одном из наших особых развлечений хочется рассказать подробнее. Итак, сегодня у нас Code Retreat!

    Code Retreat – что это?!


    Прежде всего, о формате Code Retreat. Это встреча разработчиков, состоящая из нескольких сессий программирования, удовлетворяющих простым правилам:
    • длительность сессии 45 минут;
    • все программирование идет в парах и только в парах;
    • каждую сессию пары случайно перемешиваются;
    • по окончании каждой сессии весь написанный код безжалостно удаляется;
    • каждую сессию решается одна и та же задача, но с различными дополнительными ограничениями. Собственно в этих ограничениях вся соль!

    На первый взгляд мероприятие может показаться мягко говоря странным, с непривычными, некомфортными и нереалистичными правилами. Но стоит в нем поучаствовать и мнение кардинально меняется!

    Глазами очевидца. Как это было.


    На креш-курсе я узнал о Code Retreat впервые и, как оказалось впоследствии, не только я один. А началось все с безобидной первой итерации, где нам предложили реализовать игру «Жизнь». Мы расселись по парам, таймер был запущен и…

    Итерация 1

    Ограничения:
    1. Ограничение по времени 45 минут.
    2. Необходимо освоиться с задачей, запрограммировать что-нибудь.

    Надо сказать, что у большинства через отведенный промежуток времени было готово решение и оно работало. Затем было 10 минут перерыва на кофе с печеньками, жонглирование(?!) и полное удаление написанного кода! Кроме того, смена пар.

    Итерация 2

    Ограничения:
    1. 45 минут.
    2. Использование TDD:
      • В каждом тесте только одна простейшая проверка
      • Каждый новый тест должен быть:
        • Cначала красным
        • Максимально простым
        • Максимально просто реализуемым
    3. За клавиатурой каждый по 5 минут.

    По окончании стандартная операция с удалением написанного кода и поеданием печенек =) И, конечно, смена пар!

    Итерация 3 (уже интересней)

    Ограничения:
    1. 45 минут.
    2. Ограничения на размер методов – не более 3(!) строк.
    3. За клавиатурой каждый по 5 минут.
    4. Игровое поле бесконечно.

    На этой итерации стало гораздо веселее! Но впереди маячила заключительная, четвертая итерация! А сначала, как вы уже догадались, удаление кода и смена пар!

    Итерация 4 (совсем интересно)

    Ограничения:
    1. 45 минут.
    2. За клавиатурой каждый по 5 минут.
    3. На выбор:
      • Не использовать мышь
      • 3 min planning timeframe (Вся сессия состоит из трехминутных циклов. В начале каждого цикла напарники договариваются о том, что они хотят успеть за этот цикл. Если по истечении 3 минут после начала цель не достигнута, тогда весь написанный за этот цикл код удаляется и цикл нужно начинать заново)
    4. На выбор:
      • Нет циклов.
      • Нет условных операторов.
      • Нет переменных.

    Честно сказать, заключительная итерация у большинства продлилась гораздо дольше 45 минут, так как всем хотелось получить работающую программу. И никто не не хотел сдаваться еще долгое время =)

    Впечатления


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

    Осмысление


    Какую же пользу приносит Code Retreat? На самом деле тут можно долго перечислять все его достоинства, но стоит сказать об основных.
    • Во-первых, это обмен опытом. С каждой новой итерацией ты набираешься новых идей, перенимаешь опыт от нового партнера, а также передаешь свои знания другим людям.
    • Во-вторых, это расширение сознания (ну не знаю как это по-другому назвать, может «прокачка думалки»?). Если решать задачу одинаково, то иногда трудно придумать другое или несколько других решений. Экстремальные ограничения просто вынуждают это делать и выходить за рамки привычного.
    • В-третьих, море позитива и общения. Приобретаешь опыт совместного решения поставленной задачи в паре с практически незнакомым (это только поначалу) человеком.

    Итог


    Креш-курс закончился, я описал только одно из многочисленных развлечений, ну а стажировка в Контуре в самом разгаре! Всем удачи!

    Спасибо за внимание! =) И обязательно попробуйте, можете отписаться о своих впечатлениях в комментариях.

    Авторы кода ниже Denxc и Sleipnir
    Часть кода игры «Жизнь» с последней итерации.
    /*
    Ограничения:
    1. Нет переменных.
    2. Нет циклов.
    3. Нет условных операторов.
    4. Длина любого метода не превышает 3-х строк.
    5. Длина кода класса Game не превышает 60 строк.
    */
    class Game
    {
        private HashSet<Point> aliveCells;
     
        private IEnumerable<Point> movingVectors = new List<Point>()
        {
       	  new Point(-1, -1), new Point(-1, 0), new Point(-1, 1),
       	  new Point(0, -1),            	  	         new Point(0, 1),
       	  new Point(1, -1),  new Point(1, 0),   new Point(1, 1)
        };
     
        public Game(IEnumerable<Point> initCells)
        {
       	  aliveCells = new HashSet<Point>(initCells);
        }
     
        public Game MakeStep()
        {
       	  return new Game(aliveCells.SelectMany(Neighbours).Where(ShouldAlive));
        }
     
        public void Show()
        {
       	  Console.Clear();
       	  aliveCells.Where(c => c.X >= 0 && c.Y >= 0 && c.X < Console.WindowWidth && c.Y < Console.WindowHeight)
       	  .Select(PrintPoint).ToArray();    	                	              
        }    	
     
        public bool PrintPoint(Point cell)
        {
       	  Console.SetCursorPosition(cell.X, cell.Y);
       	  Console.Write('*');
       	  return true;
        }
     
        public IEnumerable<Point> Neighbours(Point cell)
        {
       	  return movingVectors.Select(c => new Point(c.X + cell.X, c.Y + cell.Y));
        }
     
        public bool ShouldAlive(Point cell)
        {
       	  var aliveNeighboursCount = Neighbours(cell).Count(aliveCells.Contains);
       	  return aliveNeighboursCount == 3 || aliveNeighboursCount == 2 && aliveCells.Contains(cell);
        }
    }
    
    //А вот как это можно использовать:
    public static void Run(Game game)
    {
        game.Show();
        Thread.Sleep(40);
        Run(game.MakeStep());
    }
    
    Run(new Game(new HashSet<Point>()
                     {
                         new Point(21, 23), new Point(21,21), new Point(21,22),
                         new Point(22, 21), new Point(20, 22)
                     }
                 )
       );
    


    Скачать исходники, исполняемый файл и увидеть результат можно тут.
    Контур
    107,00
    Делаем веб-сервисы для бизнеса
    Поддержать автора
    Поделиться публикацией

    Комментарии 30

      –3
      Вы правы, в полной мере такой режим работы раскрывает человеческий потенциал, когда у тебя через два дня релиз, а в проекте — мертвый конь.

      PS/ В чем собственно суть самой игры?
        +2
        Суть игры «Жизнь»?
        Лучше прочитать в википедии: тынц
          +2
            0
            ох позор мне.
              +1
              Да нет, наверно позор мне. Не подумал, что кто-то может не знать про игру «Жизнь». Подправил статью.
        0
        Если придираться, то вы нарушили условия 2 и 3.
          0
          И 4.
            0
            Ну вы ведь понимаете, что под циклами и условными операторами подразумевались любые конструкции типа for, foreach, while, if, switch, ?, ??, goto(решать можно не только на C#) и тд.

            А про четвертое условие вы могли бы подробнее рассказать? Почему вам кажется, что мы его нарушаем?
              –2
              Вы нарушаете 4 условие, потому что оно в общем не корректно:
              1. Не определено понятие «строчки». Что это — оператор или физическая / логическая строка кода? Если строчка, то всё зависит от форматирования — можно так весь клас написать в одну строчку.

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

                Длина метода — это тело метода. Опять же, об этом снова никто не говорил, так как если считать сигнатуру метода, открывающую и закрывающую скобку, то это уже 3 строчки. Так что глупо считать по-другому.
                  0
                  Я же в самом начале написал «Если придираться».
                  +1
                  Code retreat был на следующий день после лекции про функциональную парадигму, так что ограничение на количество строк/метод, насколько я понял, намекало на то, что метод должен быть вида «return something.Select(...)» — получить, обработать и отдать, чтобы не было side-эффектов, только операции над данными. Понятное дело, что цепочка LINQ-вызовов Select().Where().Distinct() это нормальная одна строчка.
                    0
                    «Понятное дело, что цепочка LINQ-вызовов Select().Where().Distinct() это нормальная одна строчка.»

                    Я не согласен. Так уменьшается читаемость. К тому же, если записать это в виде именно LINQ, то получится минимум 3 строчки:

                    return (select x from xxx
                    where something(x)
                    select x).Distinct();
                      0
                      1. Читаемость уменьшается лишь для тех, кто не привык такое читать. Для меня вот читаемость улучшается.
                      2. Что такое «именно LINQ»? :) спец-синтаксис — это часть LINQ, которую можно использовать, а можно и не использовать. Тем более никто не заставляет «именно LINQ» вытягивать в одну строчку.
                      3. Короче, надо прекращать занудствовать. Code Retreat — это про «весело», а не про формальные придирки и занудство ;)
                  0
                  Отсутствие циклов должно было привести к push-/event-модели игры. Т.е. каждая клетка должна сообщать своим соседям, что она изменила состояние и они должны реагировать на это соответственно.

                  Отсутствие условных операторов должно было привести к классовому полиморфизму.
                +1
                И 1.

                var aliveNeighboursCount
                  +1
                  Переменная от слова «менять». А это значение, которое нигде, никогда не меняется.
                    –1
                    Это переменная. variable.

                    1. Значение этой переменной при каждом вызове метода будет разным (0-8)
                    2. Значение этой переменной при каждом вызове метода будет меняться с 0 на то, что вернет метод Count.
                    3. То, что «никогда не меняется» называется «константа». Это не константа.
                      0
                      Ок, замените в коде имя это переменной на ее значение и вам станет лучше =)
                      Надеюсь она исчезнет вместе с вашими попытками найти любые, даже мельчайшие недостатки в коде. Это вполне допустимо как по мнению организаторов и руководителей, так и по моему мнению.

                      P.s Ни капли не хочу вас оскорбить или обидеть, давайте оставаться благоразумными.
                        +1
                        Переменная, которая не изменяется = значение. В C# нет let, val или каких-то других подобных вещей, но это не значит, что от того, что компилятор не ограничил возможность изменения чего-то, это внезапно стало меняться.

                        «При каждом вызове метода» будет создана новая переменная (или семантика будет такой же, как при создании новой переменной, для особо придирчивых).

                        «Значение переменной» не будет определено до того момента, пока не вернётся результат выполнения последнего метода. Опять же, по семантике. Можно почитать про то, как оператор let определяется в простом нетипизированном лямбда-исчислении, или построить AST.

                        То, что никогда не меняется — это то, что никогда не меняется. «Переменные» в математике тоже никогда не меняются. Стоит различать смысл и форму, не?

                        Наконец, стоит помнить, что типы, синтаксис и прочее — это синтаксическая категория, и только. Важна семантика.
                          0
                          1. «Переменная, которая не изменяется = значение.». Вы путаете с константами.

                          2. В C# есть «let». Учите матчасть.
                  +2
                  Наш последний корпоративный сеанс code retreat показал, что написать без циклов намного проще, чем без циклов и без рекурсии.
                    +1
                    Тут все очень сильно зависит от языка. В Java — да, сложно. В C# я думаю реализация может даже не измениться.
                      0
                      если говорить о реализации, приведенной в статье, то ее вполне можно повторить на java. хотя, возможно, я не заметил какой-то особенный синтаксический сахар :)
                      0
                      Какая задача была на вашем Code Retreat?
                        0
                        Игра «Жизнь» является традиционной при проведения CodeRetreat: coderetreat.org/facilitating/structure-of-a-coderetreat
                          +1
                          Мне вот, кстати, не очень понятно, как можно участвовать в CodeRetreat повторно с той же задачей. Когда ты уже знаешь про нее все, пробовать становится больше нечего. Хотя я это чисто теоретически предполагаю — повторно участвовать пока не пробовал :)
                            +1
                            Можно выбирать новые условия из тех, что давались на выбор (например — ранее выбрал вариант «без циклов», второй вариант — «без условий»).
                              0
                              повторно скучнее :)
                              я, правда, уже раза 4 играл…
                            0
                            та же Жизнь

                        Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                        Самое читаемое