Поговорили с Сергеем, ведущим Java-разработчиком Нижегородского подразделения «Криптонита». В интервью – о языке программирования Java, «синих воротничках», бесполезности pet-проектов и работе инженера в энтерпрайзе без прикрас.
Сергей, расскажи, как именно ты пришёл к мысли изучать Java?
Это забавная история. Все мальчишки в начале 90-х хотели компьютер для игр. Моим товарищам покупали «Спектрум», на котором игры были цветные. У моих родителей не было таких денег. Поэтому они, скрепя сердце, купили мне старый компьютер без модуля цветной псевдографики. Назывался он «Партнер 01.01», как сейчас помню. В отличие от старших «цветных» собратьев, у «Партнёра» было очень мало софта для загрузки с помощью бытового магнитофона. А поскольку игры там были совсем примитивными, с псевдографикой из символов, то одной из программ, которая стала мне интересна, был интерпретатор Бейсика. И я начал писать небольшие графические программы, что, кстати, потом помогло. В ВУЗе я экстерном сдал информатику – написал забавную программу, которая выводила интересную графику, и мне поставили зачёт автоматом.
Когда я работал ведущим инженером в компании, которая проектирует крупные комплексы для горнодобывающей промышленности, начал осваивать Си. Затем у меня стоял выбор, что изучать дальше. Я решил, что для работы мне неплохо было бы написать расчётную программу. И я начал изучать варианты, как это можно сделать быстро. Мой хороший знакомый посоветовал язык Java. Так всё и началось. Мне было интересно писать программы, имеющие графический интерфейс, потому что результат можно увидеть и виртуально «пощупать» сразу. Это больше мотивирует тебя на дальнейшее изучение. Чем больше я углублялся в программирование, тем больше меня это захватывало. В коммерческом секторе больше востребована веб-разработка, поэтому для меня это стало следующим этапом развития.
Какие особенности у Java?
полная независимость байт-кода от операционной системы и оборудования. «Write once, run anywhere» – такова философия Java;
гибкая система безопасности, исполнение программы полностью контролируется виртуальной машиной;
динамические возможности во время выполнения кода, которые доступны не во всех традиционных компилируемых языках. Например – рефлексия (процесс, во время которого программа может модифицировать собственную структуру и поведение во время выполнения).
С другой стороны, расплатой за использование промежуточного кода и JVM становится снижение производительности. В современной версии Java что-то стало лучше в этом плане? Или это принципиальная особенность, и от неё никуда не денешься?
Во-первых, это принципиальная особенность именно для того, чтобы писать оторванные от конкретного железа программы, тем самым улучшая переносимость. Инженеры, которые занимаются разработкой JVM, постоянно улучшают производительность и внедряют различные технологии, например, JIT-компиляция. Поэтому нельзя сказать, что всё настолько плохо. Скорее, это было плохо в первых версиях, но сейчас уже всё стало гораздо лучше.
На твой взгляд, скорость исполнения программ, которые ты пишешь, сравнима с теми же программами, которые написали и скомпилировали, скажем, на Си?
Программы, написанные на Си, будут быстрее по определению. Но постоянная работа инженеров, занимающихся JVM и JIT-компиляцией, этот разрыв сокращает. Основное преимущество Java перед Си – это безопасность управления памятью. В Java она автоматическая, через сборщик мусора.
Как насчёт специфических проблем безопасности? В частности, той, что вытекает из сложности верификации байт-кода, особенно в части проверки корректности работы подпрограмм? Ошибки есть не только в программах Java, но и в библиотеках, которые расходятся по тысячам проектов. Да и в самой виртуальной машине до сих пор находятся характерные только для неё уязвимости.
Виртуальная машина пишется на C++, поэтому все проблемы, которые несёт язык для разработки, переносит их на работу виртуальных машин. Чтобы понимать, какие там есть ошибки, и с какими проблемами можно столкнуться, нужно заниматься разработкой этих самых виртуальных машин. Я затрудняюсь отвечать на такие вопросы. Всё-таки я инженер – разрабатываю конкретный софт на конкретном стеке технологий.
То есть ты напрямую в своей работе не сталкиваешься с вопросами оптимизации, безопасности?
Какие вопросы безопасности, например? Везде есть проблемы безопасности, в том числе в зависимых библиотеках. Их решает автор библиотек. Мы можем использовать софт, который проведёт инспекцию зависимых библиотек на предмет уязвимостей. Но мы не пишем всё с нуля, иначе в этом не было бы никакого смысла. Java хороша тем, что имеет огромную кодовую базу и огромное количество библиотек и фреймворков, которые написаны для того, чтобы облегчить жизнь рядовых инженеров.
В каких областях используется Java? Над какими проектами вы сейчас работаете в «Криптоните»?
Java – язык общего назначения, большей частью он используется в серверной разработке, особенно в энтерпрайзе (банки, телеком, ритейл и т.п.). Также Android SDK использует язык Java в качестве основы для приложений Android.
Сейчас в «Криптоните» мы разрабатываем на Java серверную часть для веб-приложений. Мы пишем сервисы, которые взаимодействуют друг с другом без веб-интерфейса. Это бо́льшая часть работы. Её малая часть — это «конечное» взаимодействие с пользователем через веб-браузер.
А что это за проект, для кого он пишется?
Это распределённая система, основанная на микросервисной архитектуре, для обработки больших объёмов данных. Реализация проекта у нас есть как в виде «монолита», так и основанная на микросервисной архитектуре, где отдельные (микро) сервисы написаны на нескольких языках. Это удобно, так как можно вести разработку параллельно и относительно независимыми командами. Например, сейчас мы бок о бок работаем с командой разработчиков на C#. Мы уже представили демоверсию, и сейчас активно пишем, чтобы выпустить релизную версию.
Взаимодействие у нас идёт через систему удалённого вызова процедур gRPC, что предполагает меньше накладных расходов, связанных с использованием REST-архитектуры.
С каким стеком технологий вы работаете? Какие скиллы обязательны на входе, а какие можно подтянуть уже в процессе работы?
Стек у нас стандартный, энтерпрайзный. Во-первых, это Java. Мы три года работали на 17-й версии и перешли на Java 21 совсем недавно. Естественно, мы используем Spring как основной фреймворк для разработки. Это тоже некий стандарт в энтерпрайзе. Если изучать его, то проблем с поиском работы не будет. В качестве СУБД мы используем PostgreSQL, а в качестве ORM – Hibernate. Важно, чтобы соискатель понимал принципы работы объектно-реляционных СУБД, но можно и в процессе углубить свои знания. А вот базовые вещи, типа SQL-запросов, всё же нужно знать. Сейчас у нас помимо gRPC используется язык GraphQL. Модель REST мы тоже поддерживаем – у нас есть legacy-проект, где всё сделано на основе REST-запросов. Также у нас используется Docker для автоматизации развёртывания и управления приложениями в комплексе с Kubernetes, как средства их оркестрации. Чего-то сильно редкого у нас нет, но, может, это и хорошо.
Расскажи, ты изучал Java самостоятельно или воспользовался курсами?
Когда у меня был выбор купить курс или учиться самому, я выбрал второе и ни разу не пожалел. Основы не сложны в изучении, язык достаточно логичен и хорошо продуман. Сложности начинаются, когда необходимо изучать всю сопутствующую инфраструктуру и огромный зоопарк технологий, используемый в энтерпрайзе. А в качестве хобби можно изучить только Java SE и спокойно писать, например, простенькие десктоп-приложения с графическим интерфейсом.
Обучался я по книгам. Так как у меня большой опыт инженера, и я привык читать документацию и техническую литературу по необходимой теме, то и язык я начинал изучать абсолютно также. Конечно, реклама из каждого утюга навязывает курсы. Я даже думал попробовать, но быстро отказался от этой мысли. Если выражаться грубо, преподавать на них будет человек, который «пережёвывает пережёванное». На мой взгляд, лучше обращаться сразу к первоисточникам. Это, как минимум, не будет игрой в сломанный телефон. Книги – это хороший источник знаний для самообучения, но он требует дисциплины. В то же время, ты не занимаешься самобичеванием, если деньги заплатил, а времени учиться нет, или пропустил занятия, и срочно нужно навёрстывать. В этом плане книга даёт тебе некую свободу – ты учишься тогда, когда тебе комфортно.
Теория по книгам – понятно, а как же практика?
Практиковаться тоже можно самостоятельно. Языки программирования тем и хороши: как минимум, основа языка базируется на логике. Поэтому, если у тебя всё в порядке с логическим мышлением, до некоторых вещей ты дойдёшь сам:) Кстати, вовсе не обязательно читать книги только по Java. Советую изучать сопутствующие языки и технологии параллельно. Тогда сразу будет складываться общая картина — понимание, в каком направлении двигаться, и как избежать тех или иных ошибок.
Долго ты обучался до того, как устроился на вакансию Java-разработчика?
Я учился каждый день на протяжении трёх лет. Этот незабываемый опыт можно сравнить с получением второго высшего – там тоже примерно два-три года учиться. Но у меня была ещё и узкая техническая направленность. А вообще я учусь до сих пор. Наша сфера постоянно развивается, появляются новые технологии, которые тоже нужно изучать.
Какие сейчас ты можешь выделить преимущества и недостатки Java?
Из плюсов самого языка – строгая типизация, большое количество разнообразных библиотек и фреймворков. Нам не нужно каждый раз изобретать велосипед. Как правило, основной код инфраструктуры энтерпрайз-приложений базируется на крупных фреймворках, например, Spring. Они ускоряют разработку и уменьшают общее количество типового кода.
Java не стоит на месте, постоянно развивается. Сейчас ушли от императивного и объектно-ориентированного программирования в чистом виде и частично перешли к функциональному программированию, которое есть в таких JVM-языках, как Scala и Kotlin. Это обеспечивает лучшую прогнозируемость и безопасность кода.
Минусы – legacy-код. Java поддерживает обратную совместимость вплоть до начальных версий, соответственно — очень много библиотек было написано на заре её становления, а они могут содержать ошибки или стать причиной низкой производительности.
Ещё можно выделить наследование – в том виде, в котором оно существует в Java, его лучше избегать, или максимально изолировать. Ну и null references – та самая «ошибка на миллиард долларов», от которой теперь не избавиться из-за обратной совместимости.
Сам создатель языка Джеймс Гослинг сказал: «Java – это язык синих воротничков». Это подразумевает низкий порог вхождения, большое количество разработчиков с низкой квалификацией. Java – своеобразный язык. Можно написать абсолютно нечитаемые вещи, которые будут работать с помощью костылей и матов. Но поддерживать это потом – большая проблема. Такой код я тоже встречал. Его иногда проще переписать заново, чем внести туда изменения. Собственно, в этом и есть проблема низкого порога входа.
Пожалуй, у всех языков программирования с низким порогом вхождения есть общая проблема – нездоровая конкуренция на рынке труда. Появляется много разработчиков, которые считают себя опытными, написав при этом один-два pet-проекта. Потом они проходят собеседование на позицию «сеньора», хотя годятся разве что в стажёры. Из-за этого рынок становится перекошенным. Вроде бы Java-специалистов много, но, кого ни возьми, всех надо учить и переучивать. А нормального разработчика найти при этом тяжело.
Это спорное утверждение. Я сам когда-то начинал в качестве стажёра. Но у меня был бэкграунд в качестве промышленного инженера. Я понимал, что такое проектировать огромные комплексы, только не программные. И я бы не считал себя на тот момент каким-то неучем. Возможно, я даже мог дать фору более опытным разработчикам.
Но ты трезво оценивал свои возможности. Ты же не говорил: «Я готов стать тимлидом, дайте мне миллион». А приходят на собеседование всё чаще именно такие.
Такие заявления, конечно, глупости. Но если человек хочет себя проявить, он не смотрит на авторитеты с большим опытом за плечами, а всё-таки подвергает сомнению их решения и предлагает свои. Тогда, даже несмотря на отсутствие большого опыта, – это человек, к которому стоит присмотреться, потому что он может стать хорошим инженером.
Все люди разные. Тут нужно разбираться отдельно. Конечно, сейчас есть соискатели, которые позиционируют себя как сеньоры, не имея при этом серьёзного опыта. Но всё это легко проверить на собеседовании.
Обычно на собеседованиях смотрят pet-проекты соискателя. Чего вы ожидаете от кандидата? Как он может показать свои навыки?
Если бы собеседования проводил я, то, наверное, не смотрел бы pet-проекты. Сейчас люди частенько их заказывают или откуда-то копируют. Конечно, можно пробежаться по pet-проекту и поспрашивать, как соискатель реализовал ту или иную фичу. Но и здесь есть сложности – для этого нужно долго сидеть и разбираться в чужом коде, чтобы понять, что спрашивать. Я прошёл много собеседований, и ни один человек не спросил у меня про pet-проекты. Рынок соискателей очень большой, и разбираться в каждом pet-проекте – это сизифов труд. Думаю, сейчас их пишут скорее ради самообразования — в надежде, что это когда-нибудь «выстрелит», или just for fun.
Интересная точка зрения. А что спрашивать на собеседованиях вместо него?
Если мы рассматриваем позицию уровня стажёр-джуниор, я бы поспрашивал по общему пониманию принципов разработки. Это даже не задачки уровня LeetCode, а, скорее, проверка знаний о том, как взаимодействуют программные компоненты между собой. Например, можно спросить, что такое интерфейсы. Попросить дать не энциклопедическое определение, а пояснить, для чего они используются, показать их использование на конкретном примере, рассказать в чём их смысл и как работает полиморфизм. Это один из столпов объектно-ориентированного программирования. Или же можно спросить для чего используется инкапсуляция, как она может помочь в разработке. Важно, чтобы человек понимал эти базовые вещи, а всё остальное всё равно придётся доучивать на месте, вникать в конкретный проект с конкретными технологиями. Если это legacy-проект, то соискатель должен понимать, почему те или иные вещи могут быть написаны плохо, и как он может это улучшить. Также было бы не плохо, если бы человек понимал базовые принципы функционального подхода в написании кода. Ещё один важный скилл – умение разбираться в чужом коде, собирать в голове мозаику разнообразных абстракций. Основная часть нашей работы – это не писать свой код, а читать и разбирать чужой.
Ещё неплохая идея – давать примеры кода, на которых кандидат может сказать, что бы он улучшил или переделал. С помощью простых синтетических примеров будет понятно – человек просто зазубрил теорию или действительно понимает, что делает. А это гораздо важнее, чем теоретические знания или терминология. К сожалению, на Java очень много кода пишется на авось. Это очень тяжело потом поддерживать и дебажить. Такие вещи не хотелось бы видеть в проектах, их хватает и так. Новых не надо:)
Какие советы можешь дать начинающим Java-разработчикам?
Сначала лучше определиться с тем, что вам интересно. Если Android, то после Java Core лучше переходить на изучение Kotlin. Если цель найти работу в энтерпрайзе, то нужно учиться писать веб-серверы на Spring. А вот в сфере разработки десктоп-приложений работу джуном найти сложно.
Если вы не мыслите, как инженер, а поиск решений к разного рода головоломкам вызывает у вас скуку и у вас отсутствует здоровый перфекционизм — лучше поискать что-то другое.
Всегда прокачивайте технические навыки и знания, но не забывайте и о soft skills. В современной разработке никому не нужен «рак-отшельник», сидящий в тёмном углу и пишущий по готовому ТЗ, даже если он считает себя гуру написания кода. Писать код можно научить и обезьяну. Нужны инженеры, которые могут решать проблемы бизнеса. С помощью чего? Это уже отдельный вопрос. Java или какой-то другой язык программирования – это не особо важно. Нужно научиться владеть этим инструментом и минимизировать проблемы, связанные с использованием этого инструмента. По большому счёту, вот и вся задача инженера:)
Это новая статья из цикла про языки программирования. Ранее наши разработчики делали обзоры Rust, Scala, JavaScript, Spark, Golang, Python и С++.
Следите за актуальными вакансиями на нашем карьерном сайте.