Чему я научился за 30 лет программирования Я занимаюсь программированием уже более 30 лет, начиная с машин, уже устаревших (на процессорах Z80 и 6502) до современных, используя языки BASIC, ассемблера, C, C++, Tcl, Perl, Lisp, ML, occam, arc, Ruby, Go и многие другие. Далее следует список того, чему я научился. 0. Програмиирование — это ремесло, а не наука или инженерия Программирование гораздо ближе к ремеслу, чем к науке или инженерной дисциплине. Это комбинация умения и опыта, выраженная с помощью инструментов. Разработчик выбирает нужные инструменты (иногда создает собственные) и учится использовать их в процессе создания. Мне кажется, что это ремесло. Я думаю, что лучшие программисты похожи, скорее, на часовщиков, чем на строителей или физиков. Конечно, программирование похоже и на науку и на инженерную дисциплину из-за использования логики и математики, но в основе это использование инструментов и создание чего-то с их помощью. Принимая во внимание, что это ремесло, нетрудно заметить, что важны опыт, инструменты и интуиция. 1. Честность — главное правило В процессе написания кода иногда возникает соблазн поэкспериментировать, чтобы узнать, будет ли это работать и запустить программу, не понимая, что же, собственно, происходит. Классический пример — вызов API, который вы решаете оставить потому, что, волшебным образом, он позволяет избавиться от бага или добавление printf, в результате которого программа перестает падать. Оба примера — примеры нечестности. Спросите себя: «Понимаю ли я, почему моя программа делает X?». Если не понимаете, позже у вас возникнут проблемы. Знать, что происходит — ответственность программиста, потому что компьютер выполняет точно то, что ему приказывают, а не то, что ему бы хотелось. Честность требует строгого отношения. Вы должны быть точно уверены в том, что знаете, что ваша программа делает и почему. 2. Упрощайте, упрощайте, упрощайте Тони Хоар сказал: «Есть два способа спроектировать систему. Один — сделать ее настолько простой, что в ней очевидно не будет недостатков, а второй — сделать ее настолько сложной, что в ней не будет очевидных недостатков. Первый способ намного более труден.» Упрощайте, переписывайте, удаляйте. Перефразируя Хоара скажу: «Внутри каждой большой и сложной программы есть маленькая и элегантная программа, которая делает то же, что и большая и делает это правильно.» К этому имеет отношение подход «небольшие элементы, нежестко связанные друг с другом». Лучше проектировать программу, состоящую из небольших частей, взаимодействующих друг с другом, чем создавать огромное монолитное целое. Вот почему UNIX оказалась успешной. 3. Отладчики иногда вредят, профилировщики — никогда Я почти никогда не пользуюсь отладчиками. Мои программы создают журналы и я знаю, что мои программы делают. Обычно, я могу понять, что не так с моим кодом из журнала, не обращаясь к помощи отладчика. Причина, по которой я не пользуюсь отладчиками — моя уверенность в том, что отладчики заставляют лениться. Обнаружив ошибку, многие разработчики запускают отладчик, выставляют точки останова и исследуют память или значения переменных. Легко поддаться очарованию от такого мощного инструмента, но недостаточные размышления приведут к большей потере времени. А если ваша программа такая сложная, что отладчик вам необходим, см. п.2 (Замечание: несмотря на все вышесказанное, один из уважаемых мной программистов, Джон Остерхут, похоже, целыми днями сидит в отладчике Windows). С другой стороны, профилировщики необходимы, когда вам нужно разобраться с производительностью. Вы никогда не перестанете удивляться тому, что может поведать вам профилировщик. 4. Дублированный код подставит вам ножку Не повторяйтесь. Делайте все однократно в вашем коде. Этот урок имеет отношение к п.2, но это особый случай. Даже простой кусочек дублированного кода причинит неприятности позже, когда вы «пофиксите» его в одном месте, но забудете в другом. 5. Не привыкайте к языкам программирования Некоторые люди одержимы конкретными языками программирования и вынуждены пользоваться только ими. Это ошибка. Не существует языка, подходящего для решения всех задач. Важно знать, какой язык из вашего инструментария вы будете использовать для конкретной проблемы. И лучше иметь побольше инструментов. Пробуйте разные языки, применяйте их на практике. Например, вам не понадобится Python или ML, но вы можете поэкспериментировать со списочными выражениями и увидеть их силу. Или «поиграйте» с Go и увидите, как он работает с многопоточностью. Или используйте Perl и увидите как гибко он работает со строками. Или используйте PHP, чтобы быстро создать динамическую веб-страницу. Я не люблю языковые войны. Они — удел неудачников, потому что они спорят о неверных вещах. Для меня PHP неуправляемый инструмент, а в руках других он творит чудеса. То же можно сказать о C++. 6. Проще вырастить программу, чем построить ее Это правило имеет отношение к п.2. Начните с малого и растите постепенно. Когда решаете проблему, легче всего начать с небольшой ее части (возможно, используя временные заглушки или эмулируя недостающие части), чем сразу придумать целую огромную систему. Если вы сразу создаете целую систему, то: (a) вы не понимаете ее, (b) придумываете лабиринт, который очень трудно изменить. С другой стороны, если у вас много небольших элементов, взаимодействующих друг с другом, проведение рефакторинга будет легче, если вы поймете, что ошиблись где-то в начале. Причина в том, что вы никогда не узнаете какой должна быть действительно правильная архитектура. Очень редко можно предугадать, какими будут внешние воздействия на вашу программу. Вы можете быть уверены в том, что знаете, как проходит TCP трафик через ваш почтовый сервер или количество адресатов, а может, вы никогда не слышали о спаме. Всегда найдется что-то, что нарушит ваши предположения, а если они образуют огромную, запутанную, сложную программу, это значит — у вас серьезные неприятности. 7. Изучите уровни приложения Я думаю, что понимание того, что происходит в программе, начиная с центрального процессора и заканчивая языком, который вы используете, очень важно. Важно понимать уровни приложения (например, понимать, что происходит со скомпилированным кодом C или как работает виртуальная машина Java). Это очень помогает, когда приходится решать проблемы производительности, а также при отладке. Я помню случай, когда один из клиентов моей компании прислал скриншот ошибки в Windows 2000, на котором были видны состояние маленького участка памяти и регистров. Используя только эту информацию и зная версию программы, мы смогли обнаружить проблему с нулевым указателем и ее причину. 8. Я недостаточно молод, чтобы знать все Мне все еще нужно многому научиться. Есть языки, с которыми я почти не работал, но хотел бы (Erlang, Clojure). Есть языки, с которыми я «поиграл», но не знаю их достаточно хорошо (JavaScript), а еще есть идеи, которые я почти не понимаю (монады). ©habrahbr