Чему следует научиться большинству молодых программистов.

student-techЗа последние 7,5 лет работы в Ronimo я контролировал работу более десятка программистов-­интернов и просмотрел сотни портфолио студентов и выпускников. В большинстве случаев я замечал одни и те же вещи, которым все они должны были научиться. Кто-­то может подумать, что я говорю об изучении особых приемов, алгоритмов или математики, или о любых других формах конкретных знаний. И, конечно же, это правда, но на мой взгляд никогда не играет первостепенной роли. Главная вещь, которой им следует научиться ­ это самодисциплинированность. Речь идет о той дисциплине, которая заставляет вас каждый раз писать максимально понятный код, проводить рефакторинг кода, если он становится слишком громоздким в ходе последующего процесса разработки, удалять неиспользуемый код и оставлять комментарии.

Большая часть времени, которое я трачу на контроль программистов­-интернов, уходит именно на эти моменты. Не на объяснение продвинутых технологий или деталей работы нашего движка, а на то, чтобы научить их писать более качественный код. Я всегда спрашиваю кандидатов: что, по их мнению, важно для того, чтобы стать хорошим программистом, и обычно они отвечают, что код должен быть чистым, понятным и легко поддерживаемым. Именно это мне и хочется услышать, но на практике очень редко можно встретить молодого программиста, который бы придерживался этих правил.

Чтобы не забывать об этом, нужно иметь внутреннюю дисциплину, потому что она заставляет нас не останавливаться, когда «всё работает». Даже если все переменные будут иметь неправильные названия, код не потеряет своей функциональности, но разобраться в нем будет очень сложно. В краткосрочной перспективе переход от функционального кода к интуитивно понятному не дает ощутимых преимуществ: всё уже работало, и после «наведения порядка» всё по-­прежнему работает. Именно поэтому для того, чтобы сделать этот шаг, нужно быть дисциплинированным. По той же причине студентам полезна интернатура: хороший куратор внимательно следит за качеством кода (несмотря на то, что определение «хорошего кода» у каждого программиста свое), и всегда заставляет интерна или младшего специалиста делать этот следующий шаг.

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

Обманчивые функции/переменные/классы

Такие функции, классы или переменные выполняют не ту задачу, которую подразумевает их имя. Их имя ­ это обман. Вполне очевидно, что имена должны быть корректными, но, к моему удивлению, очень часто они совершенно не связаны с назначением субъекта.

В качество одного из примеров можно привести два класса, которые я недавно обнаружил в коде, написанном бывшим интерном: EditorGUI и EditorObjectCreatorGUI. Этот код отвечает за интерфейсы в наших редакторах. К моему удивлению, выяснилось, что код, отвечающий за кнопку для создания новых объектов, находился в классе EditorGUI («графический пользовательский интерфейс редактора» ­ прим. пер.), в то время как класс EditorObjectCreatorGUI («ГПИ модуля создания объектов редактора» ­ прим. пер.) обрабатывал лишь навигацию по различным объектам. Функционал, прямо противоположный имени класса! И даже несмотря на то, что код был довольно простым, мне потребовалось довольно много времени, чтобы его понять, только потому, что я подошел к нему с абсолютно неверным предположением, основанным на именах классов. В данном случае решение было бы очень простым: переименование класса EditorObjectCreatorGUI в EditorObjectNavigationGUI («ГПИ навигации по объектам редактора») сразу сделало бы его намного более понятным.

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

Запутанные классы

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

В качестве примера того, как такое можно произойти, можно представить ситуацию, когда по какой­-либо причине классу GUI («ГИП») необходимо анализировать наличие доступных текстур (например, из-­за существования кнопки для выбора текстуры). Если класс GUI ­ единственный класс, получающий результаты данного анализа, тогда имеет смысл поместить этот функционал внутри класса. Однако, позже какой­-то совершенно посторонний геймплейный класс по какой-­либо причине тоже запрашивает эту информацию. Поэтому вы передает класс GUI этому геймплейному классу, чтобы запросить информацию о текстурах. На этом этапе класс GUI уже вырос во что­-то большее: теперь это и класс TextureAnalyser («анализатор текстур»). Решить эту проблему очень легко: необходимо выделить отдельный класс TextureAnalyser, который может быть использован и классом GUI, и геймплейным классом.

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

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

Слишком большие классы

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

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

Здесь, в Ronimo, мы, как правило, стараемся не создавать классов длиннее 500 строк и функций длиннее 50 строк. Иногда это невозможно или нецелесообразно, но в целом, если класс или функция начинает разрастаться, мы ищем способы для рефакторинга или их разделения на меньшие, более контролируемые фрагменты. (В связи с этим у меня возникает вопрос: где для вас проходит эта граница? Поделитесь своим мнением в комментариях!)

Закомментированный код

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

Параллельная логика и дублирование кода

Еще одна часто встречающаяся проблема -­ это наличие схожей логики в нескольких местах. Предположим, что имя текстуры передает некоторую информацию о ее назначении, например, “TreeBackground.dds” («фон с текстурой дерева» ­ прим. пер.). Чтобы понять, можно ли использовать текстуру на объекте-дереве, мы проверяем имя файла ­ начинается ли оно со слова «Tree» («дерево»). Допустим, наш инструмент разработки позволяет очень быстро выполнить такую проверку, благодаря команде filename.beginsWith(”Tree”). Этот код настолько короткий, что если нам нужно использовать его в нескольких местах, достаточно просто его скопировать. Конечно же, это типичное дублирование кода, и все мы знаем, что его следует избегать, но что, если дублируемый код настолько короткий, что так и просится быть скопированным? В этом случае мы сталкиваемся с очевидной проблемой: возможно, в будущем мы изменим механизм проверки соответствия текстуры для дерева. Придется использовать первобытные методы и править каждую копию вручную.

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

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

Автор статьи: Joost van Dongen

Источник


    Чего хотят программисты?

    international-programmer-dayНа прошлой неделе я получил имейл от трех студентов из Университета Хэлмстеда, которые три месяца работали над проектом на тему: чего же хотят программисты от своей работы, и как компании могут привлечь талантливых программистов. Вашему вниманию представлены мои ответы на их вопросы, в порядке важности. Конечно, у каждого из нас свои предпочтения, поэтому было бы интересно узнать, с какими из пунктов вы согласны, а с какими ­ нет, в каком порядке вы бы их расположили, и чего, на ваш взгляд, не хватает.

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

    Отличные коллеги. Работа с умными программистами, увлеченными разработкой ПО, очень стимулирует. Мне приходилось неоднократно наблюдать за тем, как обсуждение задачи или дизайна с коллегой приводило к решению, которое было лучше, чем то, к чему каждый из нас мог бы прийти, работая самостоятельно. И это не только улучшает код, но и позволяет получить больше удовольствия от самого процесса. Как узнать, является ли человек хорошим программистом? Хорошим сигналом может послужить тот факт, что он не перестает учиться и развивать свои навыки, например, читая книги и блоги, занимаясь на курсах и посещая конференции. Впрочем, это не обязательное условие ­ я работал со многими отличными разработчиками, которые не занимались подобными вещами. Наконец, хорошие разработчики привлекают к себе других хороших разработчиков из-­за представленных выше причин. Тот факт, что в компании уже работает много отличных программистов, упрощает задачу по набору новых.

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

    Крутые технологии. В основном это касается использования интересных языков программирования (например, Clojure, Erlang или Go), но также включает в себя фреймворки и приложения (к примеру, Hadoop или Cassandra). С этим у компании могут быть трудности. Если их приложение написано на определенном языке (допустим, C++), с этим уже ничего не поделать. В этом случае, если вы захотите перейти на какой-­нибудь новый язык ­ скорее всего, вам придется искать новую работу. Например, если вы хотите работать с Erlang в Стокгольме, вы можете попробовать обратиться в Klarna или Campanja.

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

    Хорошая зарплата. Компании, в которых работает много хороших разработчиков, понимают их ценность. Поскольку между отличными и средними программистами есть большая разница, гораздо логичнее (в экономическом смысле) нанимать качественных разработчиков ­ разница в продуктивности будет значительно выше, чем разница в зарплате. С другой стороны, компании, которые плохо платят программистам, часто рассматривают своих работников как взаимозаменяемые «ресурсы». Таких компаний стоит избегать не только из­-за низкого уровня заработной платы, но и по множеству других причин.

    Хорошие инструменты. Здесь всё практически очевидно. Наличие быстрого компьютера и нескольких мониторов позволяет ускорить процесс разработки ­ кто­-то готов с этим поспорить? (Окей, бестолковые боссы, то готов с этим поспорить? (Окей, бестолковые боссы, видящие только расходы, но не пользу, наверняка, будут против).

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

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

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

    Малое расстояние до работы. Безусловно, вы вряд ли что­-то сможете с этим поделать, но возможность не тратить ежедневно несколько часов в пробках ­ это действительно здорово.

    КОММЕНТАРИИ

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

    А какие у вас приоритеты?

    Автор:  Henrik Warne

    Источник


      Я программист — звучит гордо!

      money_logo

       

      Американский журнал Money Magazine составил список самых прибыльных и востребованных профессий.

      Исследование проводилось на основе данных национального статистического бюро. Специалисты хотели выяснить, какие профессии будут пользоваться популярностью в течение последующих  лет.

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

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