Привет!
В начале лета многие крупные компании проводят стажировки для студентов последних курсов и выпускников технических специальностей. Мне посчастливилось попасть в ряды таких молодых специалистов в компанию СКБ Контур. Наше знакомство с миром разработки программного обеспечения началось с мероприятия под кодовым названием “Креш-курс” — четырехдневная интенсивная выездная школа. Было много всего интересного, увлекательного и познавательного, но об одном из наших особых развлечений хочется рассказать подробнее. Итак, сегодня у нас Code Retreat!
Code Retreat – что это?!
Прежде всего, о формате Code Retreat. Это встреча разработчиков, состоящая из нескольких сессий программирования, удовлетворяющих простым правилам:
- длительность сессии 45 минут;
- все программирование идет в парах и только в парах;
- каждую сессию пары случайно перемешиваются;
- по окончании каждой сессии весь написанный код безжалостно удаляется;
- каждую сессию решается одна и та же задача, но с различными дополнительными ограничениями. Собственно в этих ограничениях вся соль!
На первый взгляд мероприятие может показаться мягко говоря странным, с непривычными, некомфортными и нереалистичными правилами. Но стоит в нем поучаствовать и мнение кардинально меняется!
Глазами очевидца. Как это было.
На креш-курсе я узнал о Code Retreat впервые и, как оказалось впоследствии, не только я один. А началось все с безобидной первой итерации, где нам предложили реализовать игру «Жизнь». Мы расселись по парам, таймер был запущен и…
Итерация 1
Ограничения:
- Ограничение по времени 45 минут.
- Необходимо освоиться с задачей, запрограммировать что-нибудь.
Надо сказать, что у большинства через отведенный промежуток времени было готово решение и оно работало. Затем было 10 минут перерыва на кофе с печеньками, жонглирование(?!) и полное удаление написанного кода! Кроме того, смена пар.
Итерация 2
Ограничения:
- 45 минут.
- Использование TDD:
- В каждом тесте только одна простейшая проверка
- Каждый новый тест должен быть:
- Cначала красным
- Максимально простым
- Максимально просто реализуемым
- За клавиатурой каждый по 5 минут.
По окончании стандартная операция с удалением написанного кода и поеданием печенек =) И, конечно, смена пар!
Итерация 3 (уже интересней)
Ограничения:
- 45 минут.
- Ограничения на размер методов – не более 3(!) строк.
- За клавиатурой каждый по 5 минут.
- Игровое поле бесконечно.
На этой итерации стало гораздо веселее! Но впереди маячила заключительная, четвертая итерация! А сначала, как вы уже догадались, удаление кода и смена пар!
Итерация 4 (совсем интересно)
Ограничения:
- 45 минут.
- За клавиатурой каждый по 5 минут.
- На выбор:
- Не использовать мышь
- 3 min planning timeframe (Вся сессия состоит из трехминутных циклов. В начале каждого цикла напарники договариваются о том, что они хотят успеть за этот цикл. Если по истечении 3 минут после начала цель не достигнута, тогда весь написанный за этот цикл код удаляется и цикл нужно начинать заново)
- На выбор:
- Нет циклов.
- Нет условных операторов.
- Нет переменных.
Честно сказать, заключительная итерация у большинства продлилась гораздо дольше 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)
}
)
);
Скачать исходники, исполняемый файл и увидеть результат можно тут.
Автор: Denxc