Советы для начинающего Java-разработчика. Подготовка к собеседованию — часть 3
После обсуждения наиболее распространенных вопросов по основам Java в первой части и двум популярным фреймворкам во второй части статьи, разберем оставшиеся, но не менее важные инструменты и технологии.
Алгоритмы
Основная тема на собеседованиях за рубежом пользуется у нас гораздо меньшей популярностью. Про подготовку к зарубежным собеседованиям на позицию разработчика написаны десятки книг и сотни статей, в которых львиную долю занимает именно постановка алгоритмического мышления и разбор популярных задач. У нас, к счастью, большой необходимости в штудировании сайтов вроде leetcode.com нет. В противном случае время подготовки к собеседованию увеличилось бы как минимум вдвое. Впрочем, ни одно собеседование без подобных вопросов не обходится все равно.
У каждого собеседующего есть свой список «удачных» задач для проверки способности последовательно и структурировано мыслить. Иногда достаточно абсурдных и мало применимых к реальным ситуациям. И если повеселивший многих вопрос из предыдущей части статьи про разницу BeanFactory и FactoryBean в спринге имеет хоть какой-то, пусть и отдаленный, практический смысл, то лично мне сложно понять смысл вопроса про палочку, которую мы разламываем в двух местах на три части, и поиск вероятности составления треугольника из этих частей. Но пути мышления собеседующих неисповедимы, поэтому будем по традиции отталкиваться от статистических данных по задаваемым вопросам.
Что спрашивают часто:
- Что такое сложность алгоритма? Практический вариант: сравните сложность двух решений одной задачи.
Вопрос, без которого не обойдется ни одно собеседование, поэтому остановимся на нем немного подробнее. Важно помнить, что помимо сложности по времени выполнения есть также сложность по расходуемой памяти. И не забывайте спрашивать собеседующего, важна ли она в данном случае. Это дает условный плюс в корзину претендента. А также то, что основных обозначений сложности, как функции зависимости объёма вычислений от размера входных данных, бывает несколько (tilde, big-O, big-theta, big-omega). Но спрашивают чаще всего либо про средний случай, либо про верхнюю границу выполнения — расчет для худшего случая. И какой вариант интересует собеседующего тоже нужно уточнять сразу.
- Какие знаете сортировки, которые используются в стандартных механизмах Java?
Вопрос про QuickSort и TimSort, и их применение. Быструю сортировку желательно уметь реализовать в простом варианте для саморазвития.
- Бинарный поиск. Мастхэв, элементарный алгоритм, много кто спрашивает. Сложность знать обязательно, так же как и уметь объяснить, почему она такая.
- Структуры данных в Java, которые умеют сортировать под капотом. Для чего чаще всего используются? Что внутри, как происходит сортировка? При каком условии объекты, положенные внутрь, будут отсортированы правильно?
- Почему иногда выбор худшей по сложности сортировки выгоднее?
С целью проверить общеобразовательный уровень могут спросить про двоичное дерево, двоичную кучу, графы. В 90% случаев всегда поверхностно: что это такое, где используются, какие бывают. Также подозрительно часто дают задачи на сортировку подсчетом.
В целом, по моему личному мнению, углубленные курсы по алгоритмам не нужны за исключением частных случаев. Вышеперечисленных знаний, как базовых, достаточно.
Паттерны проектирования
Весь код, который вам придется писать в продакшене, будет частью того или иного паттерна. На начальном уровне важно разобраться в самых применяемых моделях и понимать, какая логика куда выносится и почему именно так.
Спрашивать любят про разделение паттернов на категории, по каждой из которых обычно просят назвать
Если сроки поджимают, то вот небольшой список на изучение по каждой категории:
- порождающие: фабричный метод, абстрактная фабрика, билдер, синглтон;
- структурные: фасад, прокси, декоратор;
- поведенческие: шаблонный метод, наблюдатель, стратегия;
- дополнительно (но не менее важно): DAO, repository, MVC.
Из GRASP-паттернов можно ознакомиться с Low Coupling и High Cohesion как основополагающими принципами. Тем более, что в отличие от GoF, их можно интуитивно понять после первого же прочтения.
Системы контроля версий
Изучение VCS (на примере Git) очень рекомендую делать на практике по принципу «прочитал — выполнил — проверил результат». На первых порах достаточно будет выучить список основных команд и для чего они нужны: push (с опциями), pull, fetch, commit, merge, rebase, squash, revert. После проверки на практике вопросы вроде «как отменить несколько коммитов» или «как собрать несколько коммитов в один» должны перестать беспокоить. Хотя последние спрашивают уже от уровня крепкого джуна и выше. Тогда же спросят про Git workflow или жизненный цикл разработки. Недоджуну достаточно понимать общие принципы совместной работы с кодом и уметь подтягивать чужие изменения, коммитить свои и делать merge. Остальное рекомендую изучать уже после трудоустройства.
Сборка проекта
Самые популярные сборщики сегодня: Maven и Gradle. Вторым воспользоваться на реальном проекте мне так и не довелось, поэтому все дальнейшее будет относиться к мавену.
Сборку приходится осуществлять часто, но практически всегда это стандартный набор из
Что хотят услышать на собеседовании:
- Что вообще такое процесс сборки проекта на Java? Для чего нужна сборка? Что имеем на выходе?
- За что отвечает pom.xml и какая у него структура?
- Как организована сборка многомодульных проектов?
- Назовите стандартные жизненные циклы мавена и несколько фаз, которые к ним относятся.
- Как мавен решает проблемы с транзитивными зависимостями?
Веб-технологии
Java, как язык для разработки server-side приложений, не может быть отделен от веба. Поэтому основы веб-технологий спросят всегда:
- Что такое HTTP? какие у него альтернативы?
- Какие есть HTTP-запросы? (назвать 4 основных будет достаточно) Какая между ними разница? Любимый вопрос у всех: чем GET отличается от POST?
- Что такое REST? какие особенности RESTful-сервисов знаете? Про SOAP сегодня практически не спрашивают.
- Назовите пару контейнеров для запуска веб-приложений на Java. Что они из себя представляют? Для сравнения можно рассмотреть популярные Tomcat и Jetty.
Тестирование
Требования к тестированию очень сильно отличаются от проекта к проекту. Где-то разделяют принципы TDD, где-то выделяют время только на минимальное покрытие тестами в силу приоритетов по другим задачам. Бизнесу виднее (почти сарказм). Знать заранее, как будет на следующем вашем проекте нельзя, поэтому сфокусируемся на базовых моментах. Самые распространенные для тестирования фреймворки на сегодня: JUnit для юнит-тестов и Mockito для имплементации заглушек. Оба элементарно подключаются к проекту и предельно просты в вопросе понимания необходимости их использования.
Что часто спрашивают:
- Какие виды тестирования знаете и чем они отличаются? Разработчику достаточно назвать модульное, интеграционное и функциональное. Если назовете нагрузочное, то необходимо заранее посмотреть в сторону такого инструмента, как JMeter, чтобы было что отвечать на дополнительные вопросы без серьезного погружения в тему.
- Основные аннотации в JUnit (test, before, after, beforeClass, afterClass, ignore) и их особенности.
- Чем отличается Mock от Spy в мокито? Приведите пример использования первого и второго (крепкий джун+).
- Что, если ожидаем от метода выброшенного исключения? Что, если метод не должен выполняться дольше определенного количества времени?
- Какие модификаторы доступа у тестовых методов в JUnit?
У крепкого джуна могут также спросить про параметризированное/категоризированное тестирование (@RunWith аннотация). Или про нюансы тестирования методов, которые обращаются к БД.
Логирование
Тема маленькая, практический смысл большой. Присутствует на любом проекте, спрашивают очень часто. Из важного могу порекомендовать запомнить уровни логирования:
ALL Логируются все сообщения
TRACE Мелкое сообщение при отладке
DEBUG Важные сообщения при отладке
INFO Просто сообщение
WARN Предупреждение
ERROR Ошибка
FATAL Фатальная ошибка
Если выставить уровень логирования в WARN, то все менее важные, чем WARN сообщения, будут отброшены (TRACE, DEBUG, INFO). Если нужно настроить, чтобы какие-то логи писались в файл, настраивается с помощью Appenders.
Дебаг
К сожалению, огромное количество претендентов на позицию джуна сильно недооценивают значимость такого инструмента разработчика, как отладчик. А уровень владения дебагом у среднестатистического стажера лежит в плоскости «вы знаете, я обычно просто добавляю System.out, чтобы посмотреть значение переменной». И очень мало, где пишут, что джун по факту проводит за отладкой и поиском ошибок не намного меньше времени, чем за разработкой. Отсюда рекомендация: обязательно разобраться в дебаге.
На примере IntelliJ IDEA: знать, какие функции в режиме отладки выполняют F7, F8, F9. Как посмотреть содержимое обрабатываемой коллекции в конкретный момент выполнения. Как изменить значение, которое передается в метод прямо в момент отладки. Попробуйте все это на практике: сложного ничего нет, а практической пользы очень много.
Методологии разработки
Так как работать разработчику приходится в команде, то и взаимодействие внутри нее всегда организовано в виде конкретного системного подхода. Сегодня балом правит Agile — набор гибких принципов, на основе которых строятся популярные методологии. Достаточно знать две самых распространенных из них: Scrum и Kanban.
Scrum основан на делении всего процесса на итерации, где в конце каждой команда готова предоставить результирующую демо-версию продукта с новым готовым функционалом.
У Kanban в основе визуализация процесса выполнения задач в виде трех колонок таблицы: To do, Doing, Done. Основная идея — уменьшать количество запланированных задач (куда уж банальнее) и постепенно перемещать их из колонки «To do» в «Done». Очень подходит для проектов, находящихся в стадии поддержки, где основной функционал уже разработан и остались минимальные доработки и багфиксинг.
У каждой из методологий много своих терминов и нюансов, но я не уверен, что джуну это необходимо. Знакомиться с ними гораздо интереснее в процессе работы, поэтому сильно углубляться в теорию не рекомендую.
Подготовка и процесс собеседования
Перечисленных профильных знаний будет достаточно для того, чтобы уверенно держаться на любом собеседовании на позицию Junior Java Developer.
По моему личному опыту, на позицию Middle они тоже не особо отличаются по сложности. Главное — понимать, что мидла от джуна отличает количество кода, который он сам писал и видел. Мидл задает на порядок меньше вопросов в процессе работы, быстрее «вкатывается» в проект, быстрее разбирается во внутренних зависимостях. Если вы считаете, что подучите чуть больше и можно попробовать себя на позицию мидла, немного приукрасив опыт в резюме, то это не так. И даже если получится пройти собеседование, то испытательный срок все покажет как есть. Помимо подтягивания теоретических навыков, на позицию мидла «с нуля» (с точки зрения опыта продакшена) можно прыгнуть только в случае работы над опенсорс проектами и самостоятельного изучения практических нюансов. Придется пережить этап, когда каждый первый ваш коммит в опенсорс будут отклонять как некачественный или незначительный.
На Junior-позицию очень часто дают тестовые задания. Чаще всего, чтобы увидеть, как в вашем коде будет организовано взаимодействие между классами и какая логика куда будет вынесена. И уже потом посмотрят на выполнение программой требуемых функций. Для некоторых задач не лишним также будет наличие тестов.
На джава-форумах и каналах иногда просят оценить структуру готового домашнего проекта, чтобы понять, насколько все плохо/хорошо. Я считаю это хорошим подходом. Также неплохая книга для понимания таких основ — Thinking in Java Эккеля.
Процесс собеседования не отличается от такового на любую другую работу. Программисты любят подлавливать на неточностях, задавая вопросы из практической плоскости, если конкретная теория начинает хромать. Это иногда создает очень полезную для соискателя дискуссию.
Один из качественных советов, который я получил на начальном этапе своей карьеры — самому вести разговор в ту тему, в которой разбираешься. И не давать тем самым повод собеседующему постоянно задавать ритм и направление разговора.
У такой стратегии есть следствие: если вы решили блеснуть каким-то малоизвестным термином, то в подавляющем большинстве случаев готовьтесь о нем рассказать. Ведь ваш интервьюер прошел тот же самый путь обучения и приблизительно знает, в чем вы разбираетесь хорошо на конкретном этапе своего развития, а в чем не очень.
На вопросы предпочтительно давать развернутые ответы, так как проверяются также навыки коммуникации. Чаще всего, перед вами сидит человек, с которым вы будете работать в одной команде. И общаться, и отвечать уже на похожие вопросы, но по проекту. Этот человек присматривается, как это будет выглядеть на ежедневной основе. Поэтому данный пункт достаточно важен.
Также не стоит быть очень категоричным в ответах. Возможно JavaScript, который вы случайно упомянули в не очень хорошем свете, неожиданно используется на проекте и станет решающим фактором, который сыграет роль в принятии решения по вашему трудоустройству.
Если после собеседования у вас остались вопросы, то обязательно их задавайте. Например, на какой стадии разработки находится проект в данный момент? Какие технологии стоит подтянуть до выхода на работу? У эйчара можно спросить про условия отпусков и больничных, предполагаемый карьерный рост в компании, через какой период происходит пересмотр зарплаты. Естественно, будучи джуном, сильно торговаться на этот счет не получится, но по ответам можно понять отношение компании к своим работникам и принять правильный выбор.
В завершение
Надеюсь, изложенной в данном цикле информации будет достаточно, чтобы прояснить какие-то нюансы подготовки и поспособствовать дальнейшему становлению хотя бы нескольких Java-разработчиков. Возможно он подтолкнет не сдаваться тех, кто не прошел на заветную позицию с первого раза.
Дорогу осилит идущий. Удачи!
При возникновении вопросов, пообщаться со мной можно в телеграме: @liohamitec