Невыносимая сложность программирования


    A n00b y0u areКогда-то книга “Совершенный код” Стива МакКоннела произвела на меня большое впечатление. Я лично думаю, что эту книгу обязательно должен прочесть каждый, кто зарабатывает на жизнь написанием кода. Особенно настоятельно я рекомендую эту книгу новичкам.

    Настоящие размышления о программировании посвящаются главе 33 “Личность” и тем, кто решил связать свою жизнь с разработкой программного обеспечения.


    Давным давно, в далёкой галактике


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

    Каждый наш продукт проходил приблизительно один и тот же жизненный цикл:

    1. Обсуждение. Всё понятно, там 5 типов страниц, включая фидбек, бэкенд у нас готовый на symfony, сроки ясны, пилим.
    2. Начальный этап разработки. Сайт простой, поэтому не парюсь и делаю всё одновременно. Верстаю главную, программирую прикольную выезжалку на jquery, внедряю систему контроля версий, пилю параллельно проект для развлечения, докручиваю админку. Ах, да, нужно добить страницу фидбека с прошлого проекта. Пилю фидбек.
    3. Собственно, разработка. Пришли обновлённые требования и надо что-то подкрутить, но это не беда. Перевёрстываю главную, заодно рефакторю вёрстку, заодно пилю проект для развлечения, заодно вношу мелкие правки от дизайнера. Программирую и тестирую админку, фикшу баги, верстаю, прогаю и снова фикшу баги. Некоторые страницы сознательно оставляю на потом.
    4. Этап “готово на 90%”. Зачастую, самый долгий. В его начале выясняется, что 90% готовности не достаточно даже для предварительной демонстрации. Период ночного багфикса, переносов сроков, борьбы с эффектом треугольного одеяла.
    5. Сдача проекта. На финальной демонстрации я понимаю, что забыл фидбек.


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

    Прошло несколько лет


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

    Теперь я совершенно точно знаю: программирование действительно слишком сложно для меня.

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

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

    Немножко матчасти


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

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

    Как нам думать


    Многие рекомендации в программировании имеют в основе обыкновенный здравый смысл. Учитесь, индустрия обновляется на 50% каждые 3 года. Используйте конвенции, не тратьте время на раздумья о том, как оформить код. Будьте скромны, ваши возможности ограничены. Конечно, найдите и используйте в работе самые лучшие средства разработки: редактор, систему контроля версий, трекер задач.

    На мой взгляд, очень правильные и достаточно полные рассуждения о том, каким должен быть (и каким не должен) программист, содержатся в книге Стива МакКоннелла “Совершенный код”. Вот несколько цитат оттуда.

    Самые лучшие программисты — те, кто понимают, насколько ограничены их возможности. Они скромны. Худшие программисты отказываются признать, что их способности не соответствуют задаче. Характер не позволяет им стать отличными программистами. Чем усерднее вы работаете над компенсацией ограниченных возможностей своего разума, тем лучше будете программировать. Быстрота вашего развития напрямую зависит от вашей скромности.

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

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

    Какими мы будем


    Программирование — сложнейший род человеческой деятельности. Быть программистом — почётно и круто. Поэтому не теряйте время попусту, не боритесь с ветряными мельницами, лучше читайте хорошие книги, узнавайте и применяйте новые техники, учитесь и растите. May the source be with you.

    Дополнительная литература


    Стив МакКоннелл — Совершенный код
    В. Турчин — Феномен науки
    Объем внимания — Википедия
    Aori
    Company
    Ads
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More

    Comments 66

      0
      Жизненный цикл обсуждение, начало разработки разработка готово сдача должен проходить не менее 10 раз. Выбирайте сроки итерации. С нового ружья и нового прицела сразу в цель не попадёшь.
        0
        > Жизненный цикл обсуждение, начало разработки разработка готово сдача должен проходить не менее 10 раз.
        Какие промежутки времени между итерации Вы считаете оптимальными?
          0
          У нас неделя и меньше
            0
            Часто при таком цикле в каждой итерации открываются новые моменты, из-за которых необходимо заметно переделывать код?

            Я, пока что, придерживаюсь такой позиции: «Хуже отсутствия ТЗ, может быть только меняющееся ТЗ». т.е вот обсудили все, вот составили ТЗ, вот написан код решающий задачи из ТЗ, а потом оказывается что «нужно тут сделать не так, а иначе», «вот тут по-другому, я думал это уже знают все и не описывали это в ТЗ». В общем это убивает всю тягу делать проект, постоянные изменения в ТЗ, и из-за этого постоянные правки(переписывание) уже написанного кода.
              +2
              Да, неизбежно, мы переделываем и код и графику и интерфейсы и сюжет наших игр. Вы знакомы с миром agile разработки? Мы исповедуем kanban. Надо делать не до состояния заказчик так хочет, а до того как фича заработает, когда пользователи будут использовать функционал. Если его сделали как хотел заказчик но пользователи не пользуют, значит надо переделать, или выкинуть. И тут проще делать по чуть чуть и проверять.
                0
                Это может и работает когда пользователи слабо зависят от заказчика, но когда заказчик их в приказном порядке обязывает пользоваться фичей…
                  0
                  Они всё равно не будут ей пользоваться. Ну т.е. будут, но активность использования всё равно будет изменяться от качества. Или время затраченное на использование фичи. Например будет специалист поддержки по 10 минут тратить на заведение тикета. И это плохо. И работать надо над уменьшением этого времени в таком случае. И то что требования заказчика исполнены ещё ни о чём не говорит. Вопрос в том изменилось ли значение целевой метрики. А кроме количества пользований или времени можно ещё оценить количество жалоб или обращений в поддержку.
                    0
                    И работать надо над уменьшением этого времени в таком случае.

                    Проблема ли это разработчика? Не заказчика ли? Ну и поддержка первой линии замкнута на том же заказчике — до разработчиков доходит только то, что он «заапрувил».
                      +1
                      Если вы готовы делать лажу, скрываясь за тем что «заказчик мудак», отлично. Если вы честны, прежде всего перед собой и ваша работа используется плохо, или не работает вовсе, то это проблема вас и вашей кармы, не зависимо от того сколько уровней корпоративного болота или субподряда стоит между вами и пользователем.
                        0
                        Я честен перед собой — я знаю где у меня в коде есть ляпы, где нужна оптимизация, где рефакторинг, где прочий технический долг. Иногда даже пытаюсь вмешиваться в глобальные бизнес-процессы. Но вот проблемы юзабилити я никак не могу решать, хотя бы потому что о них не знаю.
                0
                Более того, иногда например приходится менять структуру хранилища или ещё чего-то достаточно фундаментального. Потому что вчера не нужно было а теперь надо. И когда программисты и вся команда вовлечены и понимают какие бизнес процессы за этим стоят нет никаких проблем. Это просто по честному делать работу хорошо, а не для галочки типа заказчик так принял.
                  +1
                  Если честно, именно такие фундаментальные изменения и привносят разочарование: зачем мне придумывать лучшую структуру, задумываться над тем как лучше реализовать и на это потратить силы, если они окажутся напрасными и нужно делать по-другому. После таких вот изменений пришла мысль: не надо писать хорошо, надо писать что бы просто работало и тратить минимум усилий.
                    +1
                    В этом и есть крутость профессионала, написать так чтобы мы потом не бегали и не искали где взять ещё пару камазов серверов, при обсуждении изначально мы бы заложились на расширение. Но при этом не нагородить большего чем надо. Можно очень долго проектировать фичу которая не получит развития. Да есть опасность что придётся переделать 3 раза с нуля. Но также есть шанс из 5 решений бастрых понять какие 2 нужны а 3 выкинуть, и эти два уже переписать нормально и в итоге выиграть.
                    0
                    MVP, реально минимум, выход и итерации итерации итерации. С регулярнейшим самоконтролем.
                      0
                      Да да, а мне еще говорят «разберись как нибудь, ты же умный...», приходится соответствовать и включать телепатический модуль.
                        0
                        кто-то включает телепатический модуль, а кто-то действительно идет разбираться. ;)
                          0
                          увы-увы, на месте услышишь то же самое. Не умеют некоторые люди ставить точные ТЗ которые легко выполнять, только на телепатическом уровне «сделай чтобы было хорошо».
                  +27
                    +1
                    И четвертая картинка нужна — «пишу статью в хабр»
                      0
                      ну хотя бы «в продакшн», а могло бы быть что-нибудь в духе «заливаешь на FTP»
                        0
                        "… и в продакшен заливаешь по FTP" :)
                    –8
                    — Анализ требований — обязательно
                    — Проектирование — обязательно.
                    Вообще, хороший программист должен уметь проектировать на UML. Во время этого процесса узнаешь много нового и намного раньше, чем дико спасаешь свое время в дальнейшем.

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

                      Использовать же его, как инструмент проектирования — дело вкуса. Я нашел для себя полезным sequence diagram и, иногда, state diagram. Остальное — куда реже и сильно упрощенно. А всякие кодогенераторы, принимающие UML class diagram на вход, IMHO не нужны.
                        +2
                        Чаще всего на практике, конечно выходит, что какой-то один-два типа диаграмм используется.
                        Расписывать каждый проект обязательно по всем диаграммам — верх невежества.

                        Я говорю про грамотность! Какой программист хороший, когда ему показываешь диаграмму, а он говорит, что не понимает, что это «объясните на пальцах»
                          +3
                          Вообще я UML рассматриваю, как универсальный инструмент общения между программистами и с заказчиком (или его представителем — продукт менеджером)
                            +4
                            А реальный опыт есть, которым можете поделиться? Я так в жизни и не встретил реально работающего проекта, в котором общение организована посредством UML-взаимодействия между участниками (как сказали выше — сиквенс или стейт диаграмму нарисовать на бумажке, когда что-нибудь на митинге разбирали). Было ощущение, что нет желания ни у программистов их использовать, ни у заказчика-менеджера в них разбираться.
                              0
                              Боюсь, что часто опыт такой упирается в знание самого языка. Соглашусь, что он не прост. Самого меня в него неплохо погрузили в универе, и предупредили, что не все признают UML.

                              Реальный опыт таков, что я его использую при составлении требований, когда понимаю, что после прочтения
                              больших текстов описания (под-)системы возникнет еще больше вопросов, чем до. Также иногда применяю для наглядности представления создаваемого модуля, притом даже если над кодом работаю только я один.
                        • UFO just landed and posted this here
                            +43
                            «эйфория от UML сошла на нет, когда внезапно оказалось, что из неправильных картинок получаются неправильные программы» (с) :-)
                              –1
                              Источник приведите, пожалуйста
                                0
                                Источник неизвестен :)
                                www.rsdn.ru/forum/other/1014270.all
                                  +2
                                  Вероятно народная мудрость…
                                  Не только UML, а вообще любое дизайнерское представление крупного в виде диаграммок и подобных UML-ей есть очень большое зло. Не как дополнительный, а как ведущий инструмент…
                                  Например тут можно почитать почему. И это не только в Microsoft, это вообще в любом крупном околопрограммном бизнесе так.

                                  И на счет «затопчет» (ваш коммент выше) — это как правило с точностью наоборот. Хотя на UML-грабли в свое время понаступали все, ну или почти все.

                                  Вообще эйфория вокруг UML мне например и многим другим «бородатым» разрабам была изначально не понятна: инструменты проектируются и создаются для упрощения решения задач — UML же был создан imho, чтобы возможно немного упростить жизнь проект-менеджеру или проект-дизайнеру, но одновременно максимально усложнить жизнь разработчика. В проектах, где непосредственно разработка занимает только 10%, а проектирование 90% времени это возможно и оправдано — однако это, imho, утопия.
                                  И пожалуйста, без флуда на тему UML-Reverce Ingenering (эти грабли помоему, бьют по башке так, что вообще отбивают охоту программировать).
                                    0
                                    Я не фанат UML, я говорю о том, что функция «подумать заранее» работает и дает результаты лучше, чем перепроектирование на ходу.

                                    Хорошо, но вы же проектируете как-то предварительно систему? Скажите, как вы описываете сложные системы, опираясь на свой опыт!
                                      +17
                                      Я обычно проектирую в виде прямоугольничков со стрелочками. Если получается очень много прямоугольников и стрелочки начинают сильно путаться или пересекаться, проект фиговый, надо заново рисовать.
                                        0
                                        «Проектирую в виде прямоугольничков со стрелочками.» — это когда нужно сделать небольшой проект и сам себе проект-лид и сам же исполнитель. Когда проект/продукт огромен, активно развивается — вплоть до 10-ков человеко лет, над ним работает команда — тогда все это, простите, ерунда.
                                        Например если я сгенерирую диаграмму связей только статической составляющей банка данных части одного проекта и распечатаю — этим можно будет небольшой зал как обоями обклеить. И что вам скажет такая диаграмма? Видите ту табличку в 5-ти метрах, нет не ту — метр ниже, вот от нее имеем n2m foreign key связь которая ведет вон к той, на ту стену…
                                        Я утрирую конечно, но иногда это просто не реально, даже если дробить на участки, модулям и т.д.
                                        К тому же как такое версионировать? Как потом визуализировать изменения (историю)? И т.д. и т.п.
                                        То, что часть проекта «фиговая» тоже выясняется иногда не на этапе проектирования, а во время разработки.
                                          0
                                          Вообще, это шутка была. Я имел в виду, что мне непонятно, зачем вести такого рода диаграмму вместе с проектом? На моей памяти такие диаграммы применялись либо если нам давали адский говнокод с гигантским количеством компонентов и связей и надо было проект привести в порядок, или кошмарную базу данных, которую нужно было почистить и нормализовать. Вот тогда любым способом из кода/базы генерились те самые прямоугольнички со стрелочками и вешалась гигантская простыня на стену, где можно было порисовать. Ну и если планировали какой-то проект, рисовали на доске схемы, чтобы поделить на куски.

                                          У меня, если появляется желание нарисовать схему проекта, перво-наперво я задаю себе вопрос: Какую проблему проекта я сейчас решаю? Не раз сталкивался со случаями, когда начальник отдела или даже проджект заморачивал кучу народа рисовать никому не нужные схемы и бесполезные отчеты.
                                            0
                                            Вообще, это шутка была.
                                            Шутку оценил плюсом, а комент был скорее не вам а вашему опоненту выше…
                                        +1
                                        Хорошо, но вы же проектируете как-то предварительно систему? Скажите, как вы описываете сложные системы, опираясь на свой опыт!
                                        В трех этапах (важно что более-менее «предваритьельно» происходит только 1-й этап):
                                        — ТЗ описывает требования заказчика и/или максимально подробно описывает задачу "Что нужно сделать". [joke](Если заказчик вместо «Что», пропихивает «Как» — получит по лицу;)[/joke]
                                        В идеале — это вообще текст, отформатированый спец. образом, чтобы наша IDE его понимала — а главное можно было залить для «версионирования» в svn/git/любимое подставить. Особенно важно если работа ведется в несколько рук;
                                        — Проъектное решение максимально подробно описывает "Как мы это будем делать": где нужны диаграммы они там будут (редкое явление если честно). Это тоже как правило текст под IDE…
                                        — Девелопер пишет код, сопровождая его подробными коментариями, коммитит в svn/git/любимое подставить сопровождая каждый коммит подробными коментариями, потом это все собирается в документацию;
                                        Если на каком-то этих 3 «этапов» в каком-либо модуле/функции была допущена конструктивная ошибка, откатываемся до предыдущего этапа и разрабатываем этот модуль/функцию и т.д. по новой. Каждое изменение посмотреть в соответствующей версии, вплоть до всей истории, откатить назад и т.д.
                                        Тестеров, quality control и т.д и т.п в рамках вашего вопроса не рассматриваю (но как минимум ридонли доступ к репозиторию проекта они имеют).
                                          0
                                          И часто у вас проекты по этой схеме работали в идеале?
                                            0
                                            Всегда, по крайней мере очень приближено.
                                            В идеале конечно много бы чего изменили бы, но к примеру корпоративные политики к сожалению не позволяют. Например, очень хотелось бы привязать тикетинг с обратной связью (чтоб клиент тоже мог участвовать напрямую). Но тогда согласно корпоративной полиси за номером N бери MKS (потому что стандарт и что-нибудь другое наружу не выпустят). MKS же тащит с собой совершенно не юзабельную, имхо, систему контроля версий. Во всяком случае на нее после svn/git перелазить нет никакого желания, а паралельно вести ревизии в обоих сводит все приимущество такой привязки тикетинг-системы на нет.
                                  0
                                  Знать — безусловно должен. Использовать — не обязательно, благодаря новым инструментам разработка ускорилась и сейчас можно меньше времени уделять проектированию. Мощные фреймворки закладывают приличную гибкость для стандартных задач. Для нестандартных и сложных нужно уметь визуализировать свои идеи.

                                  p.s. Самое главное, что программист не должен ругать других за идеи вроде UML и не минусовать брызжа слюной, как сделали с вашим постом. Детский сад.
                                  –2
                                  Эх, как же я все это понимаю… брат! :)
                                    +6
                                    На самом деле, программирование — это просто, надо только овладеть искусством декомпозиции :)
                                    • UFO just landed and posted this here
                                      +2
                                      [offtopic]
                                      Не смог прочитать МакКоннелла ни с первого ни со второго подхода. ИМХО, толщина книги соответствует количеству «воды» в ней. Гораздо больше нравится «Программист — прагматик».
                                      [/offtopic]
                                      • UFO just landed and posted this here
                                          0
                                          Да, с паттернами та же история. Но её всё-таки прочитал, чтобы потом пользоваться как справочником, знать где что искать, и узнать общую терминологию.
                                            +6
                                            GoF ценна общим языком для взаимодействия между разработчиками.
                                              +7
                                              это книги, которые структурируют знания

                                              На мой взгляд, именно в этом, в первую очередь, ценность «классических» книг — они не сообщают революционные вещи, а приводят в порядок кашу из разрозненных знаний в голове. Бывает, что это приносит значительно большую пользу.
                                                +3
                                                Не согласен. Взять того-же Кормена, или Таненбаума — никакой воды — конкретика высокой концентрации. И читать намного интересней (субъективно) тех-же GoF или МакКонелла.
                                              0
                                              А мне там многое понравилось. Особенно запомнилась идея программ, управляемых данными. Теперь я постоянно использую эту идею.
                                              +1
                                              Вы упомянули про «5-7 объектов в поле внимания» и что это мешает понимать сложную систему. По-моему это был опыт у Вундта, когда это число показали экспериментально, обьем сознания, так это они называли — замеряли, сколько тактов метронома человек может запомнить и различить. Но штука была в том, что в дальнейшем выяснилось, что люди могут запомнить гораздо больше тактов, просто структурируя сигналы более крупными единицами, выделяя группы, как, например, припев и куплет мелодии. Соответственно сложность системы может быть довольно велика, если она удачно структурирована. 5-7 обьектов вполне хватит.
                                                0
                                                Кстати, в главе из книги Турчина, на которую я дал ссылку в списке доплитературы, содержится ещё более сильное утверждение: «честная» ёмкость человеческого внимания — до 3 объектов, более крупные группы человек дробит на атомарные. То есть, 5-7 объектов это, на деле, атомарная группа атомарных групп.

                                                Я совершенно согласен, разбиение системы на не более чем 5-7 подсистем это как раз один из эффективных способов борьбы со сложностью. Фаулер в «Рефакторинге», кажется, прямо об этом говорит. Я не могу вспомнить, там ли это, или где-то ещё, был красивый оборот про «два плюс два равно четыре, но четыре плюс четыре уже не равно восемь».
                                                  0
                                                  Вот еще статья в википедии на эту тему ссылка
                                                    0
                                                    Я говорил про другой опыт, вот про этот
                                                +3
                                                Когда программиста достигает такое озарение — это как взрыв сверхновой — видно со всех концов вселенной. Для этого нужно лишь набрать критическую массу нерешенных проблем, чтобы мозг взорвался от попытки охватить все и сразу.
                                                  0
                                                  Отличная мысль, применимая не только к программированию)
                                                  +3
                                                  Не понимаю, зачем себя так мучить. Жизнь одна, imho нельзя выбирать себе род деятельности, потому что это «почётно и круто», но при этом «невыносимо сложно». Лично я работаю программистом, потому что это легко :-)
                                                    0
                                                    А я работаю, потому что мне нравится. На сколько бы высокооплачиваемой работы не была, не вижу смысла на ней работать, если она не приносит удовольствия и морального удовлетворения.
                                                      +1
                                                      Есть нюансы. Если работа приносит удовольствие и моральное удовлетворение, но денег на привычный образ жизни и/или осуществление долгосрочных планов (типа покупки недвижимости или пенсионного страхования) не хватает, то многие предпочтут побольше денег, пускай и без удовольствия, но не ломая привычки.
                                                        0
                                                        У нас с коллегами была формула — работа должна приносить деньги, ты должен уметь ее хорошо делать и тебе должно нравится это делать
                                                          0
                                                          Часто бывает «вычеркните ненужное».
                                                    0
                                                    + А также Боб Мартин «Чистый код».
                                                      0
                                                      К теме статьи ближе его же «Идеальный программист» (Clean Coder).
                                                      0
                                                      Вроде бы небольшая, но прелестная такая статься получилась. Простая, человеческая…

                                                      Only users with full accounts can post comments. Log in, please.