23 необходимых навыка, которые позволят любому программисту всегда оставаться востребованным

4 марта 2014, 13:48

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

Допустим, вы подумываете о поиске новой работы или планируете изменить сферу деятельности. Размышляете о том, в какой компании вы хотите работать. Будет ли это стартап, компания среднего размера, международная корпорация и т.д. Остановитесь: такой подход к поиску работы совершенно неправилен. 

Лучше поставить себя на место менеджера по персоналу, который просматривает стопку резюме. Он пока не знаком с вами, и вы (пока) совершенно ему неинтересны. Его волнуют только нужды компании. Он может обратить на вас внимание исключительно как на человека, подходящего для определенной вакансии. Соответственно, вы по определению должны быть кандидатом, который действительно нужен компании. 

Технологии меняются, поэтому нет такого языка программирования, зная который можно было бы всегда оставаться востребованным на рынке труда. Но многие навыки действительно никогда не теряют актуальности. Подчеркнув уверенное владение такими навыками, а также базовую техническую компетентность в определенной сфере — скажем, Java, SQL или HTML5 — вы значительно повысите свой «коэффициент успешности» и будете выгодно выделяться среди соискателей-конкурентов. 

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

От контроля версий до использования абстракций

1. Правильное понимание взаимосвязей между циклом разработки ПО и отраслью бизнеса, в которой занята данная компания

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

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

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

Итак, необходимо научиться реализовывать в первую очередь те фичи, которые важны для бизнеса компании. Чтобы этого добиться, проще всего спросить начальника или коллег-маркетологов из отдела продаж: «Что нужно в первую очередь реализовать на уровне программы, чтобы она максимально отвечала интересам компании?».

2. Контроль версий

Если бы мне предложили задать соискателю-программисту всего один вопрос, то я бы спросил: «Расскажите о вашей любимой системе контроля версий и опишите, почему предпочитаете ее среди аналогов». Если бы кандидат не ответил, то я сразу счел бы его профнепригодным.

Если вы не пользуетесь subversion (svn), git или подобной системой контроля исходников (версий), то не можете считать себя компетентным программистом и должны максимально оперативно освоить такую систему. И точка. Без контроля версий вы не сможете работать в команде, отслеживать историю разработки, возвращаться к предыдущим версиям, управлять сразу несколькими версиями, уверенно заниматься рефакторингом, либо уверенно исправлять баги. 

3.  Модульное тестирование

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

4. Автоматизация при помощи Jenkins, Maven и/или Ant или подобных инструментов; что такое «непрерывная интеграция»

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

5. Понимание софтверной архитектуры и паттернов проектирования

Умение выступить архитектором проекта — критически важная предпосылка его успешного завершения. Вы же не будете строить дом без чертежей! Но некоторые горе-разработчики берутся за создание сложных программ без всякого плана. Необходимо понимать, как взаимосвязаны программные модули, где можно переиспользовать код, какие компоненты общие. Разумеется, также нужно знать распространенные паттерны проектирования. 

6. Чтение и написание документации (вики-источники, т.д.)

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

7. Понимание масштабируемости и воспроизводимости

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

Аналогично, когда вы настраиваете сервер разработки, то вам, очевидно, придется сразу же воспроизвести аналогичную среду на сервере тестирования, сервере обкатки, рабочем (боевом) сервере и т.д. 

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

8. Оценка (время и бюджет) и планирование

Умейте учитывать в цикле разработки ПО время, необходимое на реализацию (lead time). Мне никогда не приходилось работать в компаниях, где не требовалось бы соблюдать жесткие сроки. Однако ни в одной компании, где я работал, сотрудники не умели качественно оценивать сложность решения задач и распределять время. Это долгий разговор, который можно резюмировать так: «оценив время, необходимое на разработку, умножьте его на пять — даже с учетом этого правила».

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

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

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

10. Agile-разработка

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

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

11. Рефакторинг

Рефакторинг — это умение переписывать внутренние функции модуля, не затрагивая при этом внешних поведений. Например, если вы переписываете возможность «экспорта», то эта функция может оперировать тем же вводом и выводом, что и ранее, но работать в 10 раз быстрее. Первое правило рефакторинга хорошо известно врачам под названием «Клятва Гиппократа» и формулируется «не навреди».

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

12. Миграция

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

13. Умение описывать API и пользоваться другими API

Вы должны уметь отделять свой код от разработок коллег (то есть, уменьшать связанность кода). Либо подготавливать инструментарий для других разработчиков (как для внутреннего, так и для внешнего использования). Зачастую такие задачи оптимально решаются путем создания API.

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

Верно и обратное: хороший разработчик должен уверенно/бегло читать документацию о чужих API и уметь пользоваться ими для решения задачи.

Также обратите внимание на разделы об архитектуре и рефакторинге выше, а также на раздел об абстрагировании ниже.

14. Написание повторно используемого кода (как правило, объектно-ориентированного)

Если в вашей программе есть пятьдесят всплывающих диалоговых окон — сколько отдельных компонентов вам потребуется написать для их реализации? Правильный ответ — один или, как максимум, два. Но мне доводилось сталкиваться с бесчисленными софтверными проектами, разработчики которых не умеют повторно использовать компоненты. Чем лучше выполнен проект, тем меньше в нем кода и тем проще его поддерживать. Соответствие этому пункту хорошо проверяется следующим вопросом. Так, если я попрошу вас изменить высоту и ширину всех кнопок в приложении, сколько времени вам на это потребуется? Минута? Час? Неделя? Месяц? Год?

15. Наличие профессиональной сети, на которую можно положиться

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

16. Система отслеживания ошибок и организации рабочих потоков — например, Jira

Вы должны уверенно обращаться как минимум с одной системой выявления и отслеживания ошибок, например, с Jira. Существует и много других таких систем. Умейте пользоваться такой системой и применяйте ее ежедневно. Учитесь быть администратором, конфигурировать информационные панели, отчеты и т.д., чтобы такая система была максимально эффективной. Индикатор — Excel или совместно используемый документ Google не является системой отслеживания ошибок.

17. Понимание «достаточности» на аппаратном уровне

Если вы — эксперт по софту, то можете и не быть экспертом по харду, и наоборот. Однако полное невежество в аппаратных вопросах недопустимо. Вы должны понимать, когда задача может/должна решаться при помощи дополнительного аппаратного обеспечения (добавление памяти, применение резервного избыточного массива независимых дисков (RAID), ускорение сетевого соединения), а когда — на программном уровне (допустим, при помощи кэширования).

18. «Достаточные знания» о технологиях и инструментах, которыми пользуются другие программисты

Если вы беретесь за молоток, то всё вокруг начинает напоминать гвозди. Например, если вы знаете Flash/ActionScript, то можете полагать, что эти технологии во всех возможных случаях выигрывают у HTML/JavaScript (или наоборот). Подобные мнения никогда не являются абсолютно истинными — все зависит от ситуации. Поэтому либо подружитесь с инструментами, применяемыми другими разработчиками, либо, как минимум «знайте врага в лицо». Не обладая элементарными знаниями об альтернативных инструментах разработки, люди зачастую просто порют глупости.

19. «Достаточные знания» обо всем стеке

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

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

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

20. Понимание того, что на реализацию каждой фичи требуется время

Программисты просто терпеть не могут, когда их «закидывают» все новой работой, а потом бранят за срыв сроков (речь о расползании возможностей (feature creep), бесконечных пересмотрах и изменениях в пользовательском интерфейсе и т.д.). 
Все остальные просто терпеть не могут, когда приходится постоянно подгонять разработчика и надоедать ему вопросами «ну когда будет готово?». Поэтому ниже предлагаю вам волшебные слова, позволяющие справиться с этой проблемой. Когда вам как разработчику предъявляется новое требование, четко и ясно скажите следующее:

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

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

Вышеприведенная формулировка уместна при поступлении любого запроса на реализацию новой возможности. Кстати, еще лучше было бы переключиться на методологию Agile. Еще один универсальный ответ — «это слишком серьезное требование для версии n», где n равно как минимум +1 от актуальной версии. Можете просто заявить о фактической невыполнимости требования, но сделать это аккуратно, например: «это отличная функция для версии 4, но сейчас мы работаем над версией 1». 

21. Использование абстракций

«Абстрагирование» — это умение создать «уровень» кода, изолирующий пользователя от тех или иных деталей приложения. Здесь не идет речь об «абстрактном классе» — фундаментальной сущности, применяемой в ООП. Абстрагирование обеспечивает слабосвязанную одновременную разработку множества модулей.

Допустим, я реализовал весь мой код пользовательского интерфейса так, чтобы он взаимодействовал с базой данных Oracle. И вот однажды утром мне сообщают, что наш разработчик машинного интерфейса перешел на использование Microsoft DB. Если я не смогу быстро и надежно справиться с этим изменением — то я просто кретин, а не разработчик. 

Если программа правильно спроектирована, то в ней не должно быть никаких деталей, жестко завязанных на использование Oracle, за исключением тонкого уровня абстрагирования. И этот уровень должен легко заменяться на аналогичный слой кода, специфичный для Microsoft, чтобы все остальное «просто работало». Этот же принцип касается рассмотренного выше гипотетического «API для воспроизведения видео».

22. Умение избавляться от предупреждений компилятора или сообщений об ошибках

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

23. Понимание того, когда требуется и когда не требуется самодеятельность

Самые невыносимые разработчики — это зачастую такие senior-специалисты, которые заставляют вас изобретать велосипед или все писать с нуля (см. выше об определении/использовании API). Если вы не пользуетесь готовыми библиотеками или API, то напрасно тратите свое время и деньги компании. Например, есть библиотека Java, обеспечивающая экспорт в Excel. Если вы реализуете собственный механизм экспорта в Excel — не исключено, что вы самовлюбленный дурак и просто не умеете гуглить. 

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

Заключение

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

Он: «Опишите пожалуйста, каким образом ваш опыт работы соотносится с рассматриваемой вакансией.»

Вы: «Хорошо. Как вы считаете, чего особенно остро не хватает в нынешней команде разработчиков для решения стоящей проблемы?»

Он: «Ну, у нас всегда были проблемы с масштабируемостью.»

Вы: <Здесь вверните хитроумный ответ, обратившись к соответствующим техническим темам из упомянутых выше …> «Полагаю, основной источник проблем с масштабируемостью — излишняя нагруженность среднего слоя и клиентского кода, тогда как многие реализуемые там решения гораздо быстрее выполняются на уровне базы данных. Я, конечно, специализируюсь на клиентском коде, однако имею богатый опыт сотрудничества с разработчиками, занимавшимися программированием разных частей стека. Думаю, смогу обсудить с ними узкие места, из-за которых возникают ваши проблемы, и мы сможем найти решение, при котором оптимально используются сильные стороны каждого слоя».

Он: «Как-то сложно вы излагаете. Хотел бы пригласить вас еще на одно собеседование, в котором будут участвовать разработчики уровня базы данных и среднего слоя.»

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

Он: «Звучит заманчиво. И все понятно!»

Вы: «Может быть, есть еще какие-то проблемные области, о которых вы хотели бы поговорить?»

Он: «Еще одна большая проблема — управление множественными версиями программы для множества пользователей. Настоящая головная боль.»

Вы: «Насколько мне известно, в большинстве компаний проблемы управления версиями обусловлены несколькими факторами. Разрешите поинтересоваться, какой системой контроля версий вы пользуетесь, выполняли ли вы миграцию?»

Он: «Думаю, могу предложить вам должность технического руководителя. Нам нужны люди, которые умеют не только программировать, но и думать.»

Вы: «Да, меня интересует такое предложение, постараюсь быть максимально полезен вашей компании.»

Брюс Эпштейн

Источник

подписка на главные новости 
недели != спам
# ит-новости
# анонсы событий
# вакансии
Обсуждение