Советы для начинающего Java-разработчика. Подготовка к собеседованию — часть 1

Kate

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

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

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

11111-1.png


План и процесс обучения​

Если среди опытных разработчиков провести опрос на тему «Был ли ваш процесс обучения / становления профессионалом оптимальным по качеству и срокам», то большая часть, как мне кажется, ответит: «Нет». Причина проста: в огромном море информации о синтаксисе, фреймворках, базах данных, алгоритмах и тестировании нет и не может быть четкой структуры обучения, идеально подходящей каждому. Коля закончил хорошие курсы по алгоритмам, немного помнит основы синтаксиса из университета, но базы данных усвоил плохо, а о тестировании практически ничего не знает. Вася пришел в разработку из тестирования, знает синтаксис языка, но для удаления хвоста массива приводит его к листу, не дружит с Git, а с базами работал совсем с другой стороны.

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

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

Цель новичка — быстрее попасть в профессиональную среду и приступить к разработке практических решений. А не делать домашние проекты по шаблону, считая их своим детищем. Я не умаляю значение pet projects для саморазвития и закрепления практических навыков, но давайте начистоту: глядя на свои проекты двух-трехлетней давности, лишь единицы назовут свой код достойным похвалы. И если опыта продакшена нет, то не стоит вписывать в резюме ссылку на GitHub-аккаунт. Если только его не ревьюил знакомый разработчик с опытом.

Таким образом, мы подошли к некоторым основополагающим, на мой взгляд, утверждениям:

  1. Продолжительные курсы офлайн-обучения (6 месяцев и больше) хороши, если:
    • у вас низкий уровень понимания по большинству покрываемых курсом тем;
    • отзывы о школе/курсах действительно хорошие либо есть человек, закончивший их и трудоустроившийся, которого вы знаете лично.
  2. Онлайн-курсы по узким направлениям (углубленные алгоритмы или базы данных, тестирование Java-приложений) стоит отложить на период после трудоустройства, чтобы не уходить в сторону от основной краткосрочной цели.
  3. Процесс составления изначального плана обучения значительно важнее трудолюбия и энтузиазма в разработке.
Вы можете быть человеком с бесконечным желанием учиться и достигать, но неправильный вектор приложения усилий сведет на нет такие полезные качества.

Градации​

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

Здесь же я привожу неполный список тем и вопросов, действительно обсуждаемых на собеседованиях со мной или коллегами по работе.

Для группировки вопросов в некоторых темах за основу взята следующая система градации начинающих разработчиков.

Недоджун​

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

Младший джун​

Собеседование на позицию Junior Developer может не пройти (а может и пройти), но базовые знания в любом случае имеет неплохие. Легко расскажет об устройстве HashMap и алгоритме бинарного поиска, но поплывет на особенностях фреймворков, практических задачах на построение зависимостей и запросах к БД, которые чуть сложнее обычных.

Крепкий джун​

Когда вы увидите вакансию «ищем Junior Java-девелопера с опытом разработки от 1 года», это о нем. Смело обходит большинство кандидатов на эту позицию. Чаще всего вопрос трудоустройства упирается только в требования по зарплате: хочет больше, чем умеет, но рынок — дело хитрое.

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

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

Градация приведена скорее для тех людей, кто ошибочно рассматривает общепринятые уровни (junior, middle, senior) в контексте времени работы в отрасли, а не в контексте знаний. Несмотря на некоторую корреляцию этих факторов, она очень индивидуальна. Кто-то за 4 года может набраться senior-знаний, а другой и через 5 все еще остается джуном.

Темы, которые нужно знать для прохождения собеседования​

  1. Основы языка и технологий.
  2. Работа с БД, JDBC.
  3. Hibernate.
  4. Spring.
  5. Алгоритмы.
  6. Логирование, тестирование.
  7. Паттерны проектирования.
  8. Системы контроля версий.
  9. Сборка проекта.
  10. Методологии разработки, веб-технологии, инструменты профилирования и т. д.
В этой статье рассмотрим первые два пункта.

Основы языка и технологий​

Недоджун​

Вопросы минимально упорядочены:

  • принципы ООП: абстракция, инкапсуляция, наследование, полиморфизм;
  • принципы SOLID, уметь рассказать на примерах из Java;
  • парадигмы программирования (императивное, декларативное и их основные подтипы);
  • интерфейсы, классы, объекты, знать разницу и особенности применения;
  • методы класса Object, понимать обязанности каждого метода и почему он был вынесен к верхушке объектной иерархии;
  • типы данных, уметь ориентироваться и использовать (примеры вопросов: «Зачем нужны классы-обертки для примитивов? Расскажите о приведении (casting) примитивных типов. А о приведении объектов?»);
  • типы классов (абстрактные, внешние, внутренние, вложенные и т. п.), модификаторы доступа;
  • коллекции, их иерархия, особенности и отличия одной от другой (LinkedList от ArrayList, HashMap от TreeMap), что под капотом у ArrayList, HashSet, на основе чего они работают и как устроены;
  • исключения, их иерархия и основы обработки (для чего, как и где);
  • стек, куча, как с ними организована работа в Java (общие принципы);
  • многопоточность: понятия процесса и потока, варианты создания потока, методы синхронизации и служебные слова в Java (называть только те, о которых можете рассказать), как вы понимаете потокобезопасность, deadlock, volatile, атомики, thread, runnable и callable;
  • стримы, лямбды, функциональные интерфейсы без серьезного углубления.
Сразу оговорюсь, что изучение каждой темы включает в себя понимание того, как все это устроено в Java.

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

Младший джун​

Перечисленные для недоджуна вопросы могут быть заданы с конкретными примерами из практической плоскости.

Темы:

  • особенности работы кучи и стека: внутреннее устройство, скорость доступа, использование памяти, сборщик мусора поверхностно;
  • нестандартное использование коллекций и особенности работы с ними: обработка NULL-значений в HashMap, TreeMap; удаление диапазона из TreeMap; почему строка — хороший выбор для ключа в HashMap. Дженерики и работа с ними: если метод принимает List, что туда можно передать; как в рантайме дженерики выглядят; могут ли быть конструкторы в абстрактных классах; если класс нельзя инициализировать, то зачем они;
  • наследование «IS-A» и ассоциация (включает в себя композицию «HAS-A» и агрегацию «USES-A or IMPLEMENTED-IN-TERMS-OF») в контексте Java;
  • интерфейсы-маркеры с примерами: сериализация, клонирование, конфигурируемая сериализация (интерфейс Externalizable);
  • более детально по типам данных: нотации основных методов (в классах-обертках, хеш-код, equals, что возвращают, почему, как переопределять), boxing-unboxing, инициализация переменных локальных и класса, пул строк (что такое, где хранится). Знать битовые операции AND, OR, XOR; byte b = 127, b++, какой результат и почему (по шагам); int p1, long p2, в чем разница между операциями p1 = p1 + p2 и p1 += p2;
  • более детальные вопросы по стримам: привести пример обработки из практики, скорость работы стримов, какие два типа операций есть, что за чем идет в операциях в стриме;
  • многопоточность детальнее: приведите пример дедлока (странный вопрос, но задают), как создать потокобезопасный класс, для чего нужен CompletableFuture, что такое пул потоков;
  • детальнее по исключениям: если оно выпало сначала в try, потом в catch, что будет; можно ли try без catch, но с finally, куда пойдет исключение; а если return будет и в catch, и в finally, как обработается;
  • рефлексия поверхностно, что возвращает getClass и зачем он нужен;
  • класслоадеры и их иерархия. Ситуация: getClass у двух классов возвращает одно значение, во время каста одного к другому происходит ошибка. Почему? (Классы загружены разными класслоадерами).

Крепкий джун​

Все то же самое, что и у младшего, но все вопросы на уровне глубокого понимания. Добавляются:

  • I/O vs NIO (спрашивают обычно поверхностно);
  • работа с датой и периодами;
  • еще больше многопоточности: атомики изнутри (cas, faa), все основные классы из пакета Concurrent знать (где используется BlockingQueue, например), параллельные стримы и минусы их использования, forkJoin пул, вокруг чего бывает синхронизация (классы и объекты), какими способами, в чем разница ConcurrentHashMap и SynchronizedMap, ключевые отличия Callable от Runnable (обработка checked exceptions), happens-before ситуации при работе с потоками;
  • типы ссылок в Java, как и где используются;
  • стратегии сборщика мусора;
  • что объявляется в try-with-resources (вопрос по autocloseable);
  • рассказать об основных функциональных интерфейсах;
  • исключения: как ведут себя в конструкторе, как при наследовании и переопределении методов;
  • еще больше изощренных вопросов по коллекциям и классам/интерфейсам: если map не наследуется от Iterable, как по ней идет итератор; когда возникает ConcurrentModificationException и как избежать; HashMap приводит значения в корзине к дереву для оптимизации доступа начиная с определенного количества коллизий, но не всегда, а при каком условии; модификаторы доступа у полей и методов интерфейса; можно ли переопределять статические методы при наследовании;
  • где хранится в рантайме информация о классах, методах.
Всем типам джунов важно осознать, что требования к хорошему пониманию основ языка исходят из их непосредственной обязанности — писать код. Ничего другого в обязанности джунов и классических мидлов не входит. От последних требуют больше самостоятельности, а за первыми присматривают.

Работа с БД, JDBC​

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

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

Вопросы по SQL:​

  • основы: типы запросов (DDL, DML, DCL, TCL), CRUD-операции, типы данных, первичные и внешние ключи, ограничения (constraints), HAVING vs WHERE, все типы JOIN плюс уметь применять на практике, UNION (какое условие выполнения оператора для двух таблиц), последовательность операций в запросе, триггеры — теоретическое представление, индексы одиночные и составные, кластерные и некластерные (сколько может быть кластерных индексов для таблицы и сколько некластерных, почему), курсоры — что это и зачем, команда EXPLAIN;
  • нормализация и денормализация, самые дотошные могут спросить о 3 классических нормальных формах;
  • транзакции, их свойства ACID, уровни изоляции транзакций (достаточно 4 классических).
Простые запросы не должны вызывать размышлений. Пример: достаньте из базы userinfo данные юзера, чья salary больше 5000. Зарплата в отдельной таблице лежит. Таких типовых задач в сети достаточно, очень советую поискать и попрактиковаться перед собеседованием.

Вопросы по JDBC:​

  • назовите последовательность шагов при подключении и работе с базой с помощью JDBC;
  • для чего нужны: DriverManager, Driver, Connection, Statement, ResultSet;
  • какие вы знаете типы запросов (Statement, PreparedStatement, CallableStatement), расскажите о каждом типе;
  • за счет чего PreparedStatement бывает быстрее обычного Statement (прекомпиляция); если упомянуть пул прекомпилированных запросов, это сразу плюс в глазах собеседующего;
  • методы execute, executeUpdate, executeQuery, что возвращают, зачем нужны.
С крепкими джунами могут поверхностно коснуться темы масштабирования и репликации в рамках проверки общего архитектурного представления работы БД.

Итоги​

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

На этом первую часть закончу. Оставшиеся темы раскрою в следующих статьях. При достаточном количестве желающих продолжению быть!


 
Сверху