?

Log in

No account? Create an account
   Journal    Friends    Archive    Profile    Memories
 

Путь кинестетика - morfizm


Jan. 30th, 2018 04:45 am Путь кинестетика

Напишу про наболевшее. У меня в программировании экспериментальный и итеративный подход. Он как помогает мне, так и мешает мне жить. Помогает он тем, что я с энтузиазмом берусь за задачи, которые непонимаю, как решать - всё, что нужно, выяснится по ходу дела. В принципе это важнейший скилл для корпоративной карьеры инженера для уровня выше джуниора. Мешает мне жить тем, что мне очень трудно делать значимый вклад в design discussions, когда я о проблеме не подумал заранее и не провёл выходные, играясь с прототипами. Когда я работал в относительно слабой или средней группе, мне это не мешало, потому что я успевал "потрогать все руками" и даже написать прототип быстрее, чем остальные успевали придумать хоть что-нибудь. В сильной группе я могу только помогать brainstorm'ить какие-то фичи по уже готовой идее, но вот изначальный каркас - как разбить задачу на абстракции и как организовать dataflow - я не способен придумывать в реальном времени. Вернее так: мои коллеги способны это делать куда чаще, чем я.

Обычно процесс решения задачи у меня протекает так:
1. Понять requirements и изо всех сил постараться их упростить до MVP (minimum viable product). Отбросить все требования по performance, и отбросить/упростить все фичи, которые можно отбросить, чтобы продукт всё ещё мог делать хоть что-нибудь end-to-end. Как правило, начинаю со структур данных и data flow, и упрощаю их.
2. Как можно быстрее написать прототип, работающий end-to-end, написать к нему юнит тесты и end-to-end тесты, и наладить среду разработки так, чтобы можно было очень быстро делать маленькие изменения и отлаживать. Длина итераций критична. В идеале - секунды. Плохо, но терпимо - несколько минут. Неприемлемо - более 5 минут. Т.е. если итерации занимают более 5 минут, я буду всё рефакторить и редизайнить до тех пор, пока не смогу делать изменения быстрее.
3. Уже имея прототип, занимаюсь рефакторингом - делаю много итераций. Зачастую кардинально меняю абстракции, разделение на компоненты, нередко меняются структуры данных и data flow. Обычно это происходят по мере того, как валятся свежие тесты или как обнаруживается неспособность их написать из-за плохого дизайна.
4. Добавляю немножко фич - это всё равно почти MVP, но обычно добавление первых нескольких фич к чему-то уже работающему помогает понять слабые места в дизайне.
5. Уже имея вылизанный и красивый прототип для MVP плюс немного больше, я способен заниматься настоящим дизайном - т.е. рассуждать про requirements в целом, делать какие-то proof of concept, в общем делать какой-то осмысленный дизайн для задачи целиком.

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

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

Вторая - это процесс development'а. Для меня куда более естественно добавлять end-to-end вертикали по-простому, а потом постепенно рефакторить. Коллеги, которые лучше подкованы в том, чтобы делать всё в уме, пишут много фидбека, который сводится к тому, что "сделай прямо сейчас то, что ты собирался сделать на 2-й, 3-й и т.д. итерации" (ну, вернее, писали бы, если бы я к ним не подстраивался и делал бы в том порядке, в котором мне комфортнее... конечно же, я подстраиваюсь, чтобы фидбека было мало). При этом итеративный девелопмент, разделённый горизонтально (по комнонентам, когда какие-то компоненты вообще no-op), людьми воспринимается нормально. А вертикальное деление (добавить маленькую фичу, протащив её везде, и зарефакторив) люди не любят. Причём не из-за merge conflict'ов (если изменения небольшие, то merge это ерунда), а именно из-за различий в мышлении, в подходе. Может, у них вызывает отвращение заведомо throw-away код, когда понятно, что вот это уйдёт, когда я добавлю вон то. Может, для них мой подход сложен, примерно так же, как для меня сложен их подход. Точно не знаю причин.

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

Ещё одна проблема - это то, что народ не ценит важность возможности быстрых итераций, поэтому если я своими руками не делаю какие-то улучшения (как в продукте, так и настраивая свой environment, полезные скрипты и прочее), чтобы было быстро, то чьими-то другими руками почти наверняка будет медленно. Будет рождён монстр, который компилируется 10 минут, ещё 10 минут ждать integration test'ов, и ещё минут 5 продираться с помощью десятка third party tools, чтобы собрать всё состояние системы, необходимое, чтобы разобраться, что именно сломалось и почему. Но для большинства это приемлемо, потому что у них натренирован вот этот умственный подход. Они сразу делают всё в уме, или рисуют на доске, и эти эксперименты им вроде как и не нужны.

Есть подозрение, что причина различий ещё в том, что мой подход фундаментально bottom-up, а люди вокруг натренированы использовать в top-down. Я могу воспринимать top-down либо в режиме рефакторинга, либо когда я размышляю вообще очень-очень high-level, либо когда я размышляю только над data flow. А вот в режиме top-down придумывать софтовые абстракции - с этим туго.

У меня вот эта кинестетичность и желание экспериментировать доходит до того, что если я давно не писал код (больше 3-5 дней), у меня вообще пропадает желание работать. Зная это, я придумываю себе coding задачи, которые, может, и не нужны, но помогут мне вернуться в продуктивный режим и держаться в нём.

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

11 comments - Leave a commentPrevious Entry Share Next Entry

Comments:

From:victorbarinov
Date:January 31st, 2018 04:16 am (UTC)
(Link)
По-моему у тебя все ништяк с подходом, а твои "более опытные" коллеги don't follow good engineering culture/practices. Возможно, проблема в том, что ты не достаточно убедителен в объяснении, что твой work style хорош. (Или, возможно на ваших проектах это не так критично, или коллеги и менеджмент не понимают...)

У нас такой подход очень ценится и хорошо работает, приходи к нам ;)
From:olga_chotinun
Date:February 1st, 2018 09:57 pm (UTC)
(Link)
Твой стиль не только хорош, а единственно приемлемый :) я внизу написала :)
From:andreyvo
Date:January 31st, 2018 12:53 pm (UTC)
(Link)
Дык - "Сделай то, не знаю что" - это наше все. Иначе просто никак, издержки профессии. Сидишь, возишься, экспериментируешь. Код собственно и есть спецификация, code is self-explanatory ;)
From:soloviewoff
Date:January 31st, 2018 04:42 pm (UTC)
(Link)
В общем и целом, тоже предпочитаю быстрые итерации. Исключения: обсуждения публичного API или схемы данных, т.е. вещей, которые менять впоследствии более дорого, чем просто код реализации или внутренние API. Но даже для этих вещей надо быть осторожным и не передизайнить. Особенно, если у кого-то из участников уже есть опыт разработки сходного проекта - "эффект второй системы" довольно неприятная вещь.
From:unstablebear
Date:January 31st, 2018 08:24 pm (UTC)
(Link)
А что мешает во время design meeting подумать о data flow и MVP? В моей практике обычно этих design meeting несколько, после первого появляется представление об MVP, в последующих уточняются детали всплывающие в ходе реализации. Т.е. если нет четкой спецификации того что нужно сделать, она возникает в процессе реализации :)
From:_m_e_
Date:February 1st, 2018 10:23 am (UTC)
(Link)
А как у тебя с итеративным подходом, когда проблема не заставить код вроде бы работать (это часто просто), а убедись себя в том что код будет работать правильно и корректно всегда? Скажем, сложная многопоточность, или распределенная система со сложной обработкой ошибок, при этом есть очень строгие требования на корректность. Написать и заставить работать - легко. Убедись себя (и других если надо), что это будет работать всегда - очень сложно.

У меня в таких случаях обратное - не могу начать писать код, пока не убежу себя в корректности запланированного подхода. Отчего случается paralysis by analysis, не могу писать что-то что окажется дырявое, даже если дыра более теоретическая.

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

И тут родилась мысль - может это просто разный уровень понимания? То что мне кажется что можно будет 100% заставить работать - для кого-то совершенно не очевидно, а когда я туплю и не уверен что это можно сделать правильно - для кого-то очевидно что можно начинать и писать. При этом я даже не рассматриваю почему одному человеку очевидно, а другому нет - это может быть разница в уме, опыте, знание конкретного куска кода, так и наоборот Dunning–Kruger и не понимание будущих проблем которые другой заранее видит. В майкрософтовском ладдере по этому поводу когда-то один из признаков сеньёра было - может определить когда задача не по зубам (а 62 и меньше соответственно будет легко браться за любую задачу).
From:tery
Date:February 1st, 2018 06:38 pm (UTC)
(Link)

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

From:olga_chotinun
Date:February 1st, 2018 09:55 pm (UTC)
(Link)
"Похоже, что люди, способные генерить дизайн сходу, весь этот процесс проделывают в голове. Мне не очень понятно, как" - а никак, вернее очень плохо. Они просто по напрасному тратят время, потом всё равно нужно менять дезайн. Говорю с позиции 25+ лет опыта в 10+ разных компаниях.

Edited at 2018-02-01 09:56 pm (UTC)
From:victorbarinov
Date:February 4th, 2018 04:42 am (UTC)
(Link)
Слышал такую фразу как-то: как бы хорошо не старался все равно придется переделывать, а если стараться плохо то переделывать придется 2 раза.
Я думаю профессионализм как раз и заключается в том, чтобы отбросить лишние фичи и как можно скорее сделать простое ( а следовательно надежное) решение основных задач (mvp), потом получить feedback и приступать к следующей итерации.
Люди с большим опытом могут предвидеть недостатки и избегать плохих решений, но они должны уметь находить компромиссы между better design и faster delivery.
From:olga_chotinun
Date:February 4th, 2018 06:14 am (UTC)
(Link)
именно!. если всё зарание не планировать, то можно делать постепенно, постоянно проверяя правильным ли идёшь путём. И всё это время "зад прикрыт". В этом-то в принципе и есть суть agile без противных скрамов и стэндапов



Edited at 2018-02-04 06:15 am (UTC)
From:allambee
Date:February 13th, 2018 09:43 pm (UTC)
(Link)

Привет, Дима.


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


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


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


"Может, у них вызывает отвращение заведомо throw-away код, когда понятно, что вот это уйдёт, когда я добавлю вон то. Может, для них мой подход сложен, примерно так же, как для меня сложен их подход."


Со своей стороны могу сказать, что мне не нравится в этом как раз объём переписывания кода и количество мест, где переписывание приходится осуществлять. Для тебя, похоже, рефакторинг в смысле физического переписывания, отладки, тестирования кода - дешёвая операция, благодаря складу ума и настройкам dev env. А для других - дорогая: легче более-менее всё определить и потом подгонять внутренности компонент и швы между ними. Опять же, если над разными компонентами работают разные люди - то без этого сильно труднее скоординировать рефакторинг.


Мне бы тоже хотелось быть способным применять hands-on rapid prototype development, как делаешь ты. Что входит в твоё "наладить среду разработки так, чтобы можно было очень быстро делать маленькие изменения и отлаживать"?


"...провёл выходные, играясь с прототипами" - ты что? Своё личное время тратишь на работу?! (Well, I sometimes do that myself :-/)


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