Как стать автором
Обновить

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

Да и судя по тегам это тоже перевод. Бывает

ПС Имя автора оригинала John Graham-Cumming, меня позабавило)
Так вот оно какое ты, дежавю
Имхо, этот перевод более «литературный» и не такой топорный.
отрефакторили
А мне тот больше нравится.

Этот какой-то левый ИМХО
так это разные статьи — у одного программирование искусство, а у другого ремесло. Это принципиальные разницы. Непонятки…
Честно сказать, я не проводил дотошное сравнение обеих версий, смутило только «искусство» vs «ремесло».
Надо было мне комментарии дочитать — уже понял что статья одна и та же, просто здесь переводчик ошибся со словом craft (которое какбы стыдно не знать, если играл в игры Blizzard)
Точно, похоже. Тем надежнее рекомендации. Кстати, не только к программированию относятся.
Перед тем, как опубликовать, посмотрел, есть ли уже перевод — на тот момент не было.
Мне кажется, что я уже читал перевод этот статьи здесь. DRY на хабре :)
А я даже уже выше читал комментарий о том, что это дубль.
НЛО прилетело и опубликовало эту надпись здесь
А я люблю языковые войны.

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

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

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

0. Программирование — это ремесло, а не наука или инженерия

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

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

Принимая во внимание, что это ремесло, нетрудно заметить, что важны опыт, инструменты и интуиция.
Спасибо, без Вашего дополнения и, так и не прочитав ещё оригинал, прибывал в существенном когнитивном диссонансе :)
Программирование может быть и ремеслом и искусством. Столярное дело — это ремесло. Но есть громадная разница между столяром, который только чинит однотипные шкафы (подмастерье — не особо квалифицированный кодер); столяром, который делает разнообразные шкафы (ремесленник — обычный программист); и столяром, от которого каждый следующий заказ требует изобретения нового вида мебели, которую даже заказчик представляет себе с трудом, и для которой нет готовых методик а то и технологий по её созданию — в этот момент ремесло превращается в искусство и требует не столько опыта/инструментов/интуиции сколько творчества.
Т.е. объекты программирования как искусства это гениальные решения-программы, написанные гениями, к примеру Линусом Торвальдсом? Или это программы, которые воздействуют на эмоции, к примеру демосцена или livecoding? Можно ли сказать, что ядро Linux это объект искусства как картина или скульптура? Мне кажется, что вещи вроде ядра Linux, nginx — это изобретения, новые знания, но не искусство, ведь они не воздействуют на эмоции. А если и воздействуют (у понимающего человека), то что они отражают, какое внутреннее или внешнее содержание? Поэтому из ремесла программирования идут две дороги: одна к знаниям, другая к эмоциям, или одна к науке, другая к искусству.
Чёткую границу между ремеслом и искусством провести сложно, но в любом случае я её провожу не там, где Вы описываете. На мой взгляд ремесло — это то, что (практически) не требует творчества. Грубо говоря, клепать однотипные модули для CMS-ки — это ремесло. После второго такого модуля уже понятно, что нужно делать и как. Вопросы в процессе если и возникают, то по мелочам. А вот написать свою CMS — задача гораздо более сложная. Написать свою CMS чем-то качественно отличающуюся от имеющихся на рынке аналогов — как правило уже не ремесло.

Другой пример, не связанный с типом решаемых задач: упомянутая в статье «простота». Как известно, найти простое решение задачи — это очень сложно. Некоторые даже считают, что это под силу лишь гениям, вот насколько это сложно. :) Так вот, я считаю что ремесленник на это не способен в принципе. И нахождение таких простых решений — это однозначно искусство.

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

Конкретнее, есть небольшой кластер, в котором непрерывно обрабатывается довольно большой поток данных — 250000 объектов в минуту, где каждый объект это структура в JSON полей на 15. Часть этих данных по разным причинам некорректна и её нужно отфильтровать. Ошибки в данных бывают разные, причины возникновения этих ошибок тоже разные, поэтому во-первых одним алгоритмом всё отфильтровать не получится, а во-вторых заранее нам типы этих ошибок тоже не известны. Т.е. рабочий процесс будет выглядеть так: данные будут анализироваться людьми, будут выявляться отдельные типы/классы ошибок, для них будут разрабатываться алгоритмы фильтрации данных, внедряться, после чего всё будет повторяться с начала на уже отфильтрованных данных для выявления других ошибок — до тех пор, пока процент ошибок в данных не окажется допустимо мал. При этом некоторые алгоритмы могли требовать статистического анализа этих данных, другие — RPC-запросов в другие сервисы, etc…

В результате требовалось разработать архитектуру и движок, которые бы позволили быстро и просто добавлять(удалять/изменять) в систему любые новые алгоритмы фильтрации данных. Всё это осложнялось тем, что система в продакшне; тем, что производительность критична (кластеризация и многопоточность must have); и тем, что система должна быть автоматической (т.е. нужно было предусмотреть механизмы контроля и отладки этих алгоритмов, чтобы было возможно отследить какие данные были некорректно заблокированы каким алгоритмом и почему).

Так вот, у нас на продумывание этой системы ушло примерно полтора месяца. Написание движка заняло значительно меньше времени. Новые алгоритмы добавляются вообще за несколько дней. Добавление новых алгоритмов — это однозначно ремесло. А вот продумывание архитектуры и движка — никак нет.
Спасибо, за ваш ответ. Я думаю, что мы имеем в виду разные значения искусства. В вашей речи искусство — это уникальные способности для нахождения решения, а у меня, это выражение внутреннего или внешнего мира в каком-либо объекте, не имеющего очевидной пользы, в отличии от изобретения, понимаемого как искусство в вашем ответе. Для изобретения необходимо искусство-мастерство. Что мне интересно, так это может ли программирование быть искусством подобным мастерству художника, может ли программирование воздействовать на человека подобно картине, музыке? Само по себе, видимо нет, но как нечто, что создает эти самые картины, музыку или что-либо подобное, видимо, да.
Скорее программирование можно сравнивать с литературой и вовсе не потому, что код — это разновидность текста.
И, кстати, что касается перевода слова craft, Вы не правы. Вот из словаря Мюллера:
craft:                                           *Mueller (24th Edition)
        n. 
        1> ремесло 
        2> ловкость, умение, искусство; сноровка 
        3> хитрость, обман 
        4> (the Craft) масонское братство 
        5> судно; собир. суда всякого наименования 
        6> самолет(ы) 
        7> attr. цеховой; - craft union Syn: guile
Так что оба значения вполне допустимы, и чтобы узнать какое из них подразумевал автор было бы неплохо у него это спросить.
Ой не смешите меня. По словам переводят только в школе, да и то не в старших классах. Здесь из контекста ясно понятно, что речь идет не о «ловкости, умении и сноровке» как о высоких личных качествах, а о том, чем занимается ремесленник, craftsman. Как перевести craftsman тогда? «Искусник выбирает нужные инструменты...»? :)

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

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

Получается, что у него отладка сводится к print $v; или console.log(v)?
Дебаггером можно посмотреть содержимое памяти. То же самое можно сделать и при помощи printf(). Вопрос в масштабе: я думаю, если нужно посмотреть всего лишь одну переменную и пофиксить помарку, то проще использовать stdout. Если есть какая-то долгоиграющая бага, с большим количеством вовлеченных в нее переменных, то эффективнее использовать дебаггер. Ну и не доводить до таких ситуаций. Когда я пишу свой код, я чаще использую printf(), а когда нужно отладить чужой, который я, естественно, хуже понимаю, чем свой, то использую дебаггер, чтобы увидеть больше данных, по которым проще догнать, что и зачем делает код.

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

А 2й пункт я бы еще немного развернул и сказал бы, что все лишние телодвижения круто отсекаются бритвой Оккама, суть которой упрощенно можно выразить как «нельзя делать невынужденные допущения». Это значит, что вся логика и все блоки программы должны четко отвечать на вопрос: «чем вынуждено %s». Если четкого ответа нет, то существование кода не является обоснованным, а это указывает на архитектурный ляп.
Пример использование бритвы Оккама — чёткое следование TDD/BDD, не писать ни строчки кода без предварительно проваленного теста. Дополнительный плюс — облегчение рефакторинга, минус — не исключено, что часть абстракций будет создана только для облегчения тестирования, а в контексте решения пользовательской задачи будут излишни.
На самом деле что писать сначала как причину (тесты, код или документацию), а что потом как следствие из первого — определяется исключительно тем, что вам важнее всего. Код, который пишется после тестов получается далеко не таким красивым и оптимальным, как мог бы быть если бы сначала писался код, а не тесты. Документация, которая пишется после кода никогда не будет на 100% корректно и полно описывать что и как делает код, зато если сначала писать доку, а уже потом соответствующий ей код, то качество документации будет намного выше — опять же, ценой качества кода. Тесты, которые пишутся после кода, никогда не достигнут той степени покрытия кода как тесты, которые пишутся до кода. В общем, думаю, идея понятна. :)
Код, который пишется после тестов получается далеко не таким красивым и оптимальным, как мог бы быть если бы сначала писался код, а не тесты.

Оптимальный, да, не получится (если тесты хорошие), но вот красивым получается, имхо.
К сожалению, часто профилировщики (в основном я использовал jprofiler) только запутывают и лгут относительно реальной производительности, потому что накладные расходы на работу профилировщика оказываются огромными, а главное — некоррелирующими с реальной производительностью. Профилировщиком хорошо выловить тормозные SQL-запросы или операции ввода-вывода. Но когда, например, у вас чисто вычислительный алгоритм с множеством вызовов мелких функций, на каждый вызов профилировщик добавляет оверхед, который больше времени этого вызова. Неопытный разработчик будет думать, что всё дело в куче мелких функций и «оптимизирует» код, заинлайнив всё в одно страшное тело, которое существенного прироста производительности и не даст.

В связи с этим я последнее время профилирую теми же принтфами, вставляя замеры производительности в нужные места вручную. В особо экстремальных случаях можно просто удалить кусок кода (если есть возможность удалить его, не нарушив скорость работы остальных частей) и посмотреть, насколько станет быстрее вся операция. Это помогает, например, если у вас цикл на миллионы итераций, а на каждой итерации выполняются несколько быстрых шагов, и вы хотите понять, какой из них медленнее всего. Добавление замеров времени внутрь каждой итерации может существенно исказить картину. Кроме того, может не хватить разрешения системного таймера, чтобы точно замерять длительность быстрых операций.
Про профайлеры, их применение и фишки работы с памятью/кэшем хорошо написано в книжке Криса Касперски «Техника оптимизации программ». Смотреть на «ложь» профайлера нужно в каком-то конкретном контексте, и если юзер этого контекста не видит и не знает, что стОит оптимизировать, а что нет, то «медицина тут бессильна». Я просто хочу отметить, что смотреть на выхлоп профайлера все равно полезно, чтобы иметь хотя бы общее представление/ощущение о производительности тех, или иных операций в конкретной реализации конкретного ЯП.
Кстати про таймер: для чуствительных вещей вороде бы лучше считать с помошью RDTSC
На свете есть не только web
> предпочитаю езду по магистрали хождению по дебрям…
> получается, что его езда сводится к езде на лошади?
Я сторонник того, что программа сама должна говорить, что у нее проблема, где проблема и почему. Asserts, логи, исключения, стеки вызова и состояние переменных, понятные сообщения об ошибках, проверка входных данных в функции и контроль выходных. Трудно, конечно, но окупается уменьшением времени дебага.
Получается что чем больше у тебя опыта, тем реже ты делаешь ляпы в коде, чтобы ловить которые нужен отладчик. Если ты еще специально себя ограничиваешь в использовании отладчика — то этот процесс пойдет быстрее.

Понятно что в некоторых случаях отладчик незаменим. Речь о том, что не надо чуть что в него лезть. Надо учиться делать меньше ляпов, надо делать программу более самодиагностирующейся через те же логи, надо чтобы по тестам места ошибок были очевидны, и т.п.
Я тоже придерживаюсь такого правила. Для меня это идея о том, что отладка вообще не нужна. В идеальной ситуации ты должен быть в состоянии понять, что произошло не так, не добавляя никаких print $v, а просто глядя в стандартные логи и код программы. Кстати, обычно получается, я дебаггер давно уже не запускал :)
Как истинный программист, нумерацию автор начал с нуля :)
Мы в универе как-то отмечались на листике посещений. 55 человек вписали номера перед своими именами в двоичной форме. Препод на следующей лекции сиял. Ошибок не было. Программистов тоже.
НЛО прилетело и опубликовало эту надпись здесь
Пример никак не связан с тем, что я написал.
Ну да… нужно дополнить, что тоже с нуля начинали )
Нумерация начинается с единицы, с ноля начинается индекс: у первого элемента индекс равен нулю :).
Обожаю такие комментарии. Вам надо попробовать другие языки, кроме С.
На Си я в последний раз писал лет 20 назад. Сейчас в активе PHP, JS, немного Python и Ruby.
Есть языки, где индексация начинается с 1.
Например?
Например qbasic :) Какой всё-таки замечательный был язык… :)
Не шутите так. Это была замечательная игрушка. А язык был, мягко говоря, фекалоидом.
Fortran и иже с ним.
А там точно использовалась индексация, а не нумерация?
Не могу не порекомендовать книгу Кодеры за работой (Coders at Work). Там развёрнутые интервью у нескольких выдающихся (и даже крайне) программистов.
Инженер это творческая профессия.
Удобное утверждение для разгильдяев.
А я думаю, что нет творческих и не творческих профессий. Существует творческие люди и творческий подход. Вот взять художников-портретистов, или пейзажистов без фантазии — что видят, то и рисуют, где тут творчество? И представить какого-нибудь дворника, который решил творчески подойти к делу и изобрел электровеник. Не профессия делает человека креативным, а человек профессию.
У инженеров есть творческие задачи, а есть нет. Можно всю жизнь проработать инженером и ни одной творческой задачи не решить.
Кого-то смутило, что инженер может решать не творческие задачи?
Да все верно выше сказали, профессия не может быть творческой. И задачи не могут быть. Это характеристика людей
Хм… что-то мало чему автор оригинала научился за 30 лет…
«6. Проще вырастить программу, чем построить ее»
Спорно. Если не заниматься проектированием, а «решать проблемы по мере поступления», то на накладные расходы рефактора и перестройки архитектуры уйдет гораздо больше времени, чем на разработку архитектуры.
И другая сторона — проще. Работаю уже с таким товарищем… швейцарец, неординарная личность, в деве 7 лет, работает как раз по принципу «проще вырастить» — всю команду задолбал своим говнокодом, который пишет даже не обращая внимание на то, что он уже дублирует функционал. Причем свой же.

" Возможно, если я буду заниматься программированием еще 30 лет, у меня будет ответ на вопрос «улучшают ли юнит-тесты качество программ?»"
No comments.

Спорно. Если не заниматься проектированием, а «решать проблемы по мере поступления»

Надо не впадать в крайности. Не писать код, читая ТЗ по пунктам, но и не разрабатывать суперрасширяемую архитектуру со парой десятков уровней абстракций, если ТЗ состоит из одного пункта типа «hello world».
Солидарен с вами. Один швейцарец, пишущий говнокод, никак не доказывает несостоятельность всего подхода «выращивания» проекта. Проектировать нужно в меру, а то можно потратить две недели на проектирование всех аспектов архитектуры, а потом одна ошибка в рассуждениях сведет все эти усилия на нет.
Особенно я против проектирования архитектуры «на вырост», то есть того, что в ТЗ ещё нет.
Я к описанному в статье пришёл через 20 лет разработки софта. Судя по Вашему дню рождения в профиле, Вам ещё предстоит всё это понять самостоятельно в своё время. К сожалению, до многих вещей требуется тупо дорасти. Я по себе знаю — это дико раздражает, но это факт. Факт, до которого тоже требуется дорасти, так что если Вы пока со мной не согласны — это абсолютно нормально. :-)
Ну, радикализм до добра не доводит, независимо от возраста. Я прекрасно понимаю концепцию «выращивания» софта, но сомневаюсь, что дело в годовой разнице в возрасте между мной и Inquisitor (:
Из списка п. 1 — это то, чего я избежал. Но это, возможно, следствие того, что мне предоставлялось всегда достаточно времени.
А вот с п. 6 я несогласен. Я всегда лучше сделаю работу когда понимаю скелет проекта, он же никогда не сложен. А то потом оказывается что тут вот так, а тут вот надо сяк, а вон то, которое делал в самом начале и вообще надо переписать… Мож опыт еще не нарастил)
Пункт 6 описывает архитектуру подобную стандартным командам *nix — сотни мелких утилит, решающих отдельные небольшие задачи, с простыми интерфейсами (текст на stdin и stdout), которые можно объединять самыми разными способами используя конвейеры шелла для решения самых неожиданных (для авторов этих мелких утилит) больших и сложных задач. И когда выясняется, что часть кубиков не годится для решения очередной большой задачи, обычно достаточно дописать или изменить лишь небольшое количество таких утилит, а все остальные используются как есть.

В роли таких «кубиков» не обязательно должны выступать текстовые утилиты командной строки — это могут быть сетевые сервисы или даже классы/объекты в вашем приложении. Но они должны быть максимально простыми, независимыми и иметь тривиальные интерфейсы. В этом случае архитектура приложения составленного из таких кубиков получается очень гибкой и легко адаптируется под меняющиеся условия задачи без необходимости трогать большую часть кода.
Жаль, небоскрёбы и мосты не делают из Лего…

Хотя, в этой области в дополнение к конструктивизму сопромат вмешивается…
Но многие современные здания строятся из типовых «кубиков», паттернов.
НЛО прилетело и опубликовало эту надпись здесь
Пассаж насчёт причины успеха UNIX действительно спорен. Что до успеха винды, то он обеспечен скорее маркетинговыми мерами, нежели техническими. И в любом случае всё это не имеет реального отношения к сути этого пункта статьи. А суть в том, что писать и поддерживать монолитный код намного сложнее, чем описанную архитектуру.
Плюсану за труд, но, автор, на будущее проверяй, нет ли уже этой же статьи.
habrahabr.ru/post/147722/
где-то читал подобное:
1) Надо научиться делать «N»
2) Научился делать «N» с помошью «abc»
3) понял что «abc» не правильный метод — изучаю «bcd»
4) пока изучил «bcd» он морально устарел сейчас все делают «cde»
5) изучив «cde» понял что знаю про «N» совсем мало
— — — 10) так нихрена и не понял, а уже пора умирать…
Так искусство или все же ремесло? :)
Некоторые люди одержимы конкретными языками программирования и вынуждены пользоваться только ими. Это ошибка. Не существует языка, подходящего для решения всех задач.
Важно знать, какой язык из вашего инструментария вы будете использовать для конкретной проблемы. И лучше иметь побольше инструментов. Пробуйте разные языки, применяйте их на практике.


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

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

Но я не согласен с тем, что всегда нужно выбирать под задачу оптимальный инструмент. Потому как по моему опыту, если человек имеет условно 5 лет опыта разработки на Python и условно полгода на Ruby — то ему будет проще и бустрее сделать веб сайт на Python + Django, хотя с технологической точки зрения лучшим инструментом может быть Ruby on Rail.

А держать в памяти действительно много языков на высоком уровне не получится :(.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории