вторник, 3 декабря 2019 г.

Главный навык программиста

Я заметил, что опытных специалистов из разных областей объединяет как минимум одна вещь: осторожность в суждениях.

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

Нужно ли писать тесты? Важно ли качество кода? Какая лучшая степень прожарки мяса? С чем лучше всего сочетается белое вино? Нужно ли делать жим лежа со становой или турника будет достаточно?

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

Моя нелюбовь к старине Бобу началась с его книги "Принципы, паттерны и методики гибкой разработки на языке C#" (вот большая критическая статья на эту тему), но дядюшка Боб периодически выдает и вот, после очередного его высказывания, мне захотелось подумать над поднятой им темой более подробно.

Итак, вот его твит:

When you read code, the race, religion, politics, gender, and orientation of the author are irrelevant and invisible. The only thing you can tell about the author is their ability to write well organized code. Nothing else matters.

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

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

Здесь используется довольно грязный трюк с подменой понятий и отсутствием причинно-следственной связи между двумя частями твита. Тот факт, что мы не должны судить об авторе кода по его "внешним атрибутам" не делает "хорошо структурированный код" важным. И с чего старина Боб решил, что должно какое-то одно главное качество, характеризующее специалиста?

Поскольку тема эта интересна, то давайте немного пофилософствуем по этому поводу.

"Что самое главное в жизни?", может спросить Боб. "Семья, конечно", ответит один. "А как же здоровье? Если нет здоровья, то радости от семьи будет не много.", возразит второй. "А как же призвание, а деньги? На одной семье, пусть и здоровой, далеко не уедешь! Нужно ж еще и кушать вкусно, да и делом интересным заниматься!", скажет третий. "Ну а помощь другим? Это ж тоже важно! А друзья? А карьера? А красивое тело?".

Мне кажется, что жизнь достаточно сложная штука, чтобы в ней была одна единственная главная вещь, всецело определяющая ее суть . Жизнь - это игра не совсем с фиксированной суммой. В разумных пределах можно делать больше и успевать больше. Семья может мотивировать заниматься другими делами, например, своим здоровьем и даже карьерой. А приходя с работы, которая тебя радуем, может оставаться больше сил, чтобы поиграть с ребенком и насладиться временем, проведенным наедине со своим партнером. Жизнь многогранна и не может всецело определяться чем-то одним.

Работа программиста несколько проще, чем жизнь в целом, но и она достаточно сложна и многогранна. Чего стоит хорошо структурированный код, который решает не ту проблему? А если автор хорошо структурированного кода токсичен и из-за него вся команда разваливается? А если хорошо структурированный код использует странные или даже неверные паттерны, многословен или дублирует код, написанный в другом месте?

Уметь писать хороший код очень полезно, но я не могу назвать этот навык главным и самым ценным навыком программиста. Если на то уж пошло, то умение читать реальный (читай плохой) код является более полезным навыком, ведь большую часть времени мы проводим в анализе существующего кода и поиска правильного места для вставки или изменения функционала.

Если же задаться вопросом о главном навыке (навыках?) специалиста из любой области, то я бы сказал, что это умение учиться и критически мыслить (да, и не быть м#$@ком). Эти два ключевых мета-навыка позволят развить любые другие.

Я заметил, что лучшие инженеры учатся постоянно. И не столько читая книги, сколько потребляя информацию в процессе решения реальных проблем. Они мыслят более масштабно, и не боятся нарушить статус-кво, задавая неудобные вопросы. А ту ли проблему мы решаем? А что же на самом деле нужно нашим пользователям? А не стоит ли заменить/переписать ключевой компонент? А не залипли ли мы с этими практиками, которые работали когда-то, а сейчас дают больше вреда, чем пользы?

Хороший специалист может увидеть проблему (в себе, в коде, архитектуре или подходах), подумать об альтернативах и изучить наиболее подходящее решение.

Мне может лишь в страшном сне привидеться, что вся команда состоит из однотипных людей. Людей с одним, даже самым лучшим единственным навыком. Хорошая команда - это разнообразие в лучшем понимании этого слова. Разнообразие характеров, навыков, подходов. Их должны объединять схожие принципы и ценности, но попытка грести всех под одну гребенку вызывает у меня лишь недоумение.

Мне тоже хочется найти простое решение таких сложных проблем, как разработка ПО. "Развивай навык Х и ты будешь отличным специалистом!". Но мир и разработка ПО достаточно сложны и многогранны, чтобы был один главный навык, который бы в одиночку смог бы решить все наши проблемы.

вторник, 12 марта 2019 г.

О пользе ведения блога

Пришло время ответить на вторую часть вопроса, который я поднял в предыдущем посте «Я выгорел?: Насколько полезно вести блог: с профессиональной, финансовой и других точек зрения?

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

Я знаю людей, которым блог, выступления на конференциях или участие в опен-сорс проектах помогли в поиске новой работы или в продвижении на текущей. Если вы следите за .NET сообществом, то, может быть, заметили, что довольно многие MVP (Most Valuable Professional) оказываются в итоге сотрудниками Майкрософта. Мой путь, собственно, очередной тому пример.

Но здесь важно не путать корреляцию и казуацию. Видимая активность в интернете помогает в создании связей, которые можно использовать в поиске работы, но большинство MVP – это талантливые люди, и они в состоянии найти работу путем прямого инвестирования времени в этот процесс.

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

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

Так стоит ли вести блог для карьерных целей? Я бы сказал, нет.

Если мотивация лишь финансовая, то ее будет недостаточно. Если хочется найти работу за границей, то есть другие варианты: самый простой – бодишопы. Если же хочется сразу в крупную компанию, то активное участие в открытых проектах кажется наиболее полезным. Плюс можно ловить выездные hiring ивенты. Ведение же блога кажется наименее управляемым процессом поиска работы за границей.

Позитивная сторона блоггинга

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

Кристаллизация знания. Я долгое время, использовал блог в качестве катализатора саморазвития. Даже не слишком продвинутый пост требует детального изучения темы, что потом можно использовать напрямую в работе или за чашечкой кофе, объясняя эту тему своим коллегам.

Мотивация. Когда я беру новую тему для изучения, мне нужна цель (зачем я изучаю это) и критерии завершения задачи (опубликованный пост в блоге). Это переводит задачу из разряда важных и несрочных в категорию важных и срочных. Дедлайны фиктивные, но даже они позволяют бороться с прокрастинацией.

Многие коллеги в моей команде впитывают новые знания очень быстро в процессе решения повседневных задач. У меня такой подход работает лишь частично, например, когда нужно изучить что-то очень специализированное. Изучение же новых концепций или техник требует более осознанного подхода к обучению.

Взгляд на себя со стороны. Мне очень нравится возможность общения с собой в прошлом. Чтение своих собственных постов через несколько лет, это все равно, что чтения своего старого кода. Процесс этот вызывает смешанные эмоции, но очень отрезвляет и реально позволяет посмотреть на себя со стороны и оценить прогресс собственного роста.

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

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

Негативная сторона блоггинга

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

Можно потратить десятки часов на пост и получить лишь пару негативных комментариев. Даже когда пишешь вроде бы для себя, отсутствие реакции или один лишь негатив, может подорвать веру в саму необходимость блоггинга.

Писать нужно исключительно для себя и не думать слишком много об аудитории, и тем более о монетизации и любой другой финансовой выгоде. Попытка мыслить рационально о пользе блога приведет к печальным выводам: ведение блога экономически невыгодно. Но в долгосрочной перспективе польза накапливается, но возможно это, если блог приносит удовольствие здесь и сейчас. Именно поэтому я пишу о том, что интересует меня. В этом случае усилия по определению не будут потрачены зря.

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

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

Так стоит ли мне вести блог?

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

вторник, 19 февраля 2019 г.

Я выгорел?

Или почему я намного меньше пишу в блогах.

Мне недавно задали два вопроса: 1) не выгорел ли я, поскольку стал совсем мало блогать, и 2) стоит ли вести блог вообще и какие в этом преимущества?

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

Где-то год назад я начал слушать в дороге разные подкасты и самым моим любимым был (и остается) Hello Internet. В одном из первых выпусков, CGPGrey привел довольно любопытную аналогию. Человек – это такой себе аккумулятор, к которому параллельно через резисторы подключены несколько лампочек: семья, работа, спортивная форма, хобби, друзья и т.д. И человек может менять сопротивление определенного резюка и, таким образом, тратить больше жизненной энергии на одну лампочку, уменьшая свечение всех остальных.

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

Хоть аналогия и не идеальна она прекрасно иллюстрирует главную сложность в жизни: поиск баланса между разными аспектами жизни и правильное распределенные нашего времени и энергии.

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

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

Когда у нас появляется наша собственная семья распределение энергии меняется.

Во-первых, больше энергии уходит на семью хотим мы этого или нет, а во-вторых, происходит некоторое профессиональное насыщение и мы попадаем под закон убывающей доходности (diminishing returns) в вопросах саморазвития.

Когда мы начинаем чем-то заниматься, то мы удваиваем наши знания каждые несколько месяцев. Поработав же 10 или 20 лет происходит профессиональное насыщение. Одни языки сменяют другие, молодые активисты новых технологий с пеной у рта доказывают, что они отыскали серебряную пулю. А на тебя лишь накатывает смутное подозрение, что ты такое уже где-то видел.

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

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

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

Рассмотрим донорство органов в Германии и Дании. Эти страны достаточно похожи с точки зрения уровня жизни и культуры, но в Германии донорами органов становятся на порядок меньше людей, чем в Дании. Вопрос: почему? Дело в том, что в Дании донорство осуществляется по принципу opt-out, а в Германии – по принципу opt-in. Т.е. в Дании нужно отказаться от донорства, а в Германии – наоборот, с ним нужно согласиться.

Но есть проблема. Когда человек сталкивается со сложным выбором, к которому он не готов, то он подсознательно старается отложить это решение и просто соглашается с «конфигурацией по умолчанию». Почему это важно знать программистам и UX дизайнерам? Да потому что эта же особенность проявляется и в использовании программ большинством пользователей: лишь малая толика людей ковыряется в настройках и меняет конфигурацию по умолчанию. Если что-то не включено по умолчанию, то для большинства пользователей это «что-то» не существует.

Теперь давайте возьмем такое когнитивное искажение как «якорение» (anchoring). Вот небольшой пример. Давайте проведем опрос о том, в каком возрасте умер, ну, не знаю, Ницше. И для первой группы вопрос будет таким: «В каком возрасте умер Ницше, при учете, что он пережил свое тридцатилетие?», а второй – «В каком возрасте умер Ницше, при учете, что он не дожил до 100 лет?». Мы увидим, что ответы будут сильно отличаться. В первом случае средний возраст будет существенно ниже, чем во втором случае.

Я на личном опыте столкнулся с проблемой якорения. Мы были с семьей в ресторане и семья за соседним столиком, услышав, что мы говорим по-русски, рассказала о возможной скидке в 10% с чека, если мы зачекинимся на фейсбуке. Мы их поблагодарили, но «трюком» не воспользовались. Но в момент выписывания чаевых, вместо 20% я неосознанно выписал 10%.

Якорение часто проявляется во время планирования задач. Если один из разработчиков первым сказал, что фичу можно сделать за 2 дня, то все будут отталкиваться от этой «оценки» и будут стараться лишь ее скорректировать. Именно с этим борется planning poker, когда каждый член проекта записывает свою оценку на листочке и лишь когда все готовы, «карты вскрываются».

Напоследок, мы можем взять экономическое понятие – sunk cost fallacy. Идея этого явления в том, что чем больше мы вкладываем сил и средств во что-то, тем тяжелее нам быть по этому поводу объективным. Это явление проявляется на уровне человека, который спорит, что старый язык программирования или технология все еще лучшее средство для решения всех проблем. На уровне команды, которая уперлась рогом в текущие архитектурные ограничения и не в состоянии сделать шаг назад и посмотреть на проблему с другой точки зрения. Или на уровне организации, которая не может уйти от старой бизнес-модели, которая уже не применима.

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

Мне очень понравилась идея изучения чего-то нового кусками по 20 часов (The first 20 hours – how to learn anything): ты берешь какую-то тему, находишь вменяемые источники по ней и изучаешь ее 20 часов, применяя всякие там deliberate practice и т.п.

Жалкие 20 часов не сделают тебя экспертом в этой области, но этого будет достаточно, чтобы с нею познакомиться и решить, а нужно ли оно тебе. Таймбоксинг вообще отличная практика в управлении проектами, и мы можем перенести эту же идею из мира разработки ПО в нашу жизнь.

Ну а теперь мы можем вернуться к вопросу выгорания. Так что же такое?

Как по мне, выгорание – это уменьшение запасов нашей батарейки с жизненной энергией. Выгорание – это когда ты тратишь меньше времени на изучение языков программирования, *и* проводишь меньше времени с семьей и друзьями, *и* не занимаешься своим здоровьем, *и* ничем другим не интересуешься.

Выгорание – это порочный круг уменьшения жизненной энергии. Видимое же уменьшение яркости одной «лампочки» не является признаком выгорания. Это вполне может говорить о перераспределении энергии и что сейчас она направлена в другие русла.

вторник, 12 февраля 2019 г.

Не очень занимательный C#

Я как-то не особо лезу со своими комментариями к другим людям, а уж тем более к постам на хабре. Но вчера вот листал RSS-ленту и увидел интригующее название поста – "Занимательный C#. Пять примеров для кофе-брейка".

Итить, думаю, дай-ка зайду, посмотрю, что да как.

И вот первая загадка – что выдаст следующий код:

using System;

public struct SDummy : IDisposable
{
    private bool _dispose;
    public void Dispose() => _dispose = true;

    public bool GetDispose() => _dispose;

    private static void Main(string[] args)
    {
        var d = new SDummy();
        using (d)
        {
            Console.WriteLine(d.GetDispose());
        }
        Console.WriteLine(d.GetDispose());
    }
}

 

Ну, думаю, ок. Странно начинать с изменяемых структур и особенностей блока using, ну, ничего.

Открыл объяснение, а в нем говорится, что причина странного поведения в упаковке, дескать. Компилятор зовет Dispose метод через каст: ((IDisposable)myStruct).Dispose(), ну а каст структуры к интерфейсу, как известно, приводит к упаковке.

Вот те на, подумалось мне. Мало того, что черти дают достаточно невменяемые и не практичные загадки, так еще и ответы у них неверные.

Я добавил комментарий, после чего началось небольшое обсуждение. Дескать, сам Эрик "уже давно в фейсбуке работает" Липперт писал, что упаковка в блоке using быть должна и компилятор нарушает спеку и все такое... (хотя сегодня это и не так).

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

Что в этом плохого?

Структуры в C# имеют две особенности – они являются "значениями", и могут располагаться напрямую в памяти контейнера (в стеке, регистрах и напрямую в других объектах).

Первое говорит о том, что в рантайме структуры по умолчанию копируются и то, что компилятор старается обеспечить семантику значения (т.е. неизменяемость) путем встраивания туда-сюда создание защитных копий (чтобы вызов метода или свойства, например, на неизменяемом поле ни в коем разе значение этого поля не поменял).

Второе же (место жизни структуры) может привести к упаковке т.е. к созданию копии структуры в куче.

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

Вот, например, семантика значения и защитные копии стали гораздо более распространенной бедой с выходом C# 7x с их модификаторами ‘in’ и возвратом по неизменяемой ссылке (readonly refs) (вот, например, много буков по этому поводу - The ‘in’-modifier and the readonly structs in C#).

А самая большая беда проявляется с изменяемыми структурами, когда скрытая копия «прячет» изменения состояния, поскольку произойти они могут на временной копии. Не столь серьезное последствие заключается в некоторой потери производительности за счет создания копии, что решается путем использования readonly структур.

Упаковка же происходит совсем в других местах, при кастах к объектам/интерфейсам и в более экзотических случаях, типа при вызове методов из System.Object или System.ValueType (когда, например, Equals/GetHashCode не переопределены). А проявляется она путем увеличения давления на сборку мусора, что может аукнуться за счет тормозов сборщика мусора.

Так это я все к чему: учить других – это хорошо. Это просто здорово! Но касаясь всяких закоулков языка и рантайма, хорошо бы понимать, что, да как на самом деле происходит под капотом, да и желательно разбираться, почему происходит все именно так, а не иначе.

среда, 8 августа 2018 г.

О мотивации

Я не могу делать вещи, которые мне не интересны. От слова совсем.

Когда мы с супругой рассматривали вопрос о переезде в Киев, то главной моей проблемой было то, что в крупной компании я не смогу выбирать то, над чем я буду работать. Это меня не просто пугало, это приводило меня в ужас. Плюс, обычные страхи перед новым.

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

Как и для многих других, меня в общем случае мотивируют три вещи: автономность (autonomy), мастерство (mastery) и цель (purpose). Но они для меня играют разное значение.

Цель для программиста – это не красивый код и не расширябельная архитектура. Это решение некоторой проблемы пользователей. Наличие цели для меня важно, но не сверх критично. Я занимался довольно активно проектами, цели которых были мне не совсем ясны, поскольку я был оторван от конечных пользователей довольно сильно. Аутсорс, видите ли.

Требования к автономности бывают заложены в человеке, а бывает приходят с опытом. Для меня автономность всегда была необходимым условием работы. Если вы говорите, что и как мне делать, то я наверняка скажу, куда вам идти. Всегда интересно понимать, какую проблему мы хотим решить, после чего гораздо легче выбрать наиболее подходящее решение.

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

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

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

Возьмем, к примеру, саморазвитие.

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

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

понедельник, 30 июля 2018 г.

Эффект плато

Время от времени с головой и карьерой начинают твориться довольно страшные вещи: все начинает если не напрягать, то точно приносить меньше удовольствия. Работа не прет. Проекты не прут. Ничего новое не радует и не интересует. Вопрос: почему?

У меня есть некоторые мысли по этому поводу.

Есть такая штука – допамин. Он вырабатывается, когда вы ожидаете доставки нового ай-фона, «встречи» с любимой/любимым вечером или в момент укуса вкусного мороженого жарким летним днем. Допамин – это сильнейшее штыриво, которое вырабатывается от ожидания чего-то приятного или прямо в момент его наступления.

Когда начинается карьера программиста, то с допамином нет никаких проблем. Ты каждый день узнаешь что-то новое: технологии, процессы, паттерны, практики. Вокруг все новое и моменты «просветления» происходят довольно часто. Возникает чувство, что мозг и опыт развиваются по закону Мура и каждые 18 месяцев количество знаний удваивается.

Тоже самое происходит и с первыми проектами: ощущение «творения» возникает постоянно. Исправил маленькую багу – молодец. Применил новый паттерн – красава. Починил билд – отлично. Задизайнил и довел до ума новую фичу – да вообще тебе цены нет.

Тут появляется социализация и оценка твоих способностей другими. Можно на кухне блеснуть цитатой из Рихтера, помочь дельным советом менее опытному коллеге, да и просто поспорить на технические темы во время стендапа.

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

И потом мир начинает немного меняться.

Ну, с миром-то все нормально. Но твое восприятие становится несколько иным.

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

Это же происходит с карьерой и ощущением от завершенных задач. Выше «синьера» прыгать сложно, да и не ясно, куда именно. А с задачами вообще беда получается: все одно и тоже, формошлепство, дата-сайенс, веб, базы данных. Декораторы, синглтоны и фабрики. И дурацкие обсуждение того, чем монады хороши, и почему ООП уже не торт.

Так что же происходит?

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

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

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

Есть несколько способов смягчения этой проблемы.

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

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

В-третьих, можно прислушаться к себе и понять, что же может толкать тебя изнутри. Если нравится больше кодить, то может стоит забить на свои глупые тим-лидские амбиции и заняться архитектурой или стать «просто разработчиком»? А может тебе просто нравиться изучать что-то новое, так может стоит продолжать это делать, даже если это никак не поможет твоей карьере?

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

Все это я к чему? Если плато не угрожает карьере, то вполне нормально переключаться и искать себя в чем-то другом. Искусственное толкание себя вперед может привести к выгоранию, а вот временное переключение на что-то другое вполне может освежить мозги и вернуть радость от работы и жизни.

среда, 4 июля 2018 г.

Сдвиг массива влево на N элементов

Есть ряд способов сдвинуть массив влево на N элементов. Можно взять и сделать N сдвигов по одному элементу, получив квадратичную сложность. Можно создать целевой массив по размеру исходного и вычислить положение каждого элемента после сдвига. Хорошо, но скорость линейна, затраты по памяти - тоже.
Если чутка подумать, то можно придумать реализацию, которая мутирует массив и дает линейную скорость и константные затраты по памяти. Но есть один очень элегантный способ – из 3-х строк на основе чудо Span of T из System.Memory:
public static void RotateLeft(int[] input, int direction)
{
    input.AsSpan(0, direction).Reverse();
    input.AsSpan(direction).Reverse();
    input.AsSpan().Reverse();
}
Идея такая: чтобы сдвинуть массив из K элементов на N элементов влево, нужно перевернуть первые N элементов в массиве, затем последние K - N -1 элементов, а затем перевернуть весь массив:
// direction == 2, input.Length == 7
input.AsSpan(0, direction).Reverse();
// [2][1][3][4][5][6][7]
input.AsSpan(direction).Reverse();
// [2][1][7][6][5][4][3]
input.AsSpan().Reverse();// [3][4][5][6][7][1][2]

Получается два прохода по массиву, но зато с читабельностью решения все очень ОК.