🏆 Рейтинг ІТ-работодателей 2019: уже собрано более 5000 анкет. Оцените свою компанию!
×Закрыть

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

В первой части цикла мы рассмотрели важность составления плана обучения, вопросы по Java Core и работе с БД. В этой части обсудим вопросы в комментариях и поговорим о двух популярных фреймворках: Spring и Hibernate.

Вопросы в комментариях

О происхождении вопросов для подготовки

Все они были заданы мне или моим коллегам на собеседованиях на позицию Junior/Middle людьми с уровнем Middle/Senior/Lead. Проекты: два крупных банка, сотовый оператор, внутренние квалификационные собеседования.

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

Зачем джуну знать про <любая технология или принцип>?

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

Выбор стратегии при подготовке

В девелопменте можно выделить две основные стратегии поиска работы:

а) Куда возьмут, туда пойду. Чем быстрее начну получать опыт, параллельно подтягивая недостающие знания, тем лучше.
б) Куда пойду, туда возьмут. Плюсы очевидны. Среди минусов — больше времени на подготовку. В некоторых случаях — значительно больше.

Первая стратегия сильно доминирует и давно себя зарекомендовала. Не всем нравятся сложные цели, и не каждому они под силу. У кого-то семья, домашние заботы, сторонние занятия и банально некогда выкладываться на 150%. Да и, говоря на чистоту, стратегия трудоустройства в нетоповые компании имеет мало минусов. Ну попадется вам как-бы-сеньор в наставники, поделаете некоторое время ерундовые задачи исключительно на умение серфить Stack Overflow. Зато уже с зарплатой, опыт какой-никакой в копилку капает, и свободного времени для самообразования больше.

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

«Что дозволено Юпитеру, не дозволено быку»

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

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

Претендуешь — соответствуй

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

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

Кстати, утверждение о необходимости соответствовать при высокой конкуренции одинаково верно для всех уровней. Егор Бугаенко в недавнем интервью рассказывал, что на собеседовании в Amazon ему давали алгоритмические задачи (архитектору с более чем 20-летним опытом), которые он решать отказался. Собеседование он не прошел. А взяли кого-то, кто наверняка уступает в качестве профильных знаний, но подготовился лучше и изучил потенциальные вопросы. И кому, скажите, от этого хуже?

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

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

Приступим к темам и вопросам.

Spring

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

Обо всем перечисленном могу сказать одно: все приходит с опытом. Я остановился на следующем подходе: выбрать один-два модуля Spring для детального изучения, а в остальных разобраться поверхностно. Под детальным изучением подразумевается изучение реальных примеров на гите, за которым следует собственная реализация практической задачи с запоминанием или записью используемых в процессе аннотаций.

На сайте Spring есть очень неплохая документация с описанием всех внутренностей и популярные примеры реализации определенного функционала.

Обычно, когда на собеседовании дело доходит до Spring, происходит примерно следующий диалог:

  • Из Spring с чем-то работали?
  • Да, изучал вот это и вот то.
  • Хорошо, давайте немного поговорим на эти темы.

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

О чем меня спрашивали часто: core, data, mvc.
Чуть реже — boot, security.
О чем не спросили ни разу за все время: aop, test.
Это статистические данные, не более.

Разделение по уровням джуновости достаточно условное.

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

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

Дальше вперемешку немного вопросов, связанных с перечисленными темами (только те, которые повторялись):

  • Опишите механизм dependency injection простыми словами.
  • Как работает модуль спринга <такой-то>, какой флоу выполнения (что куда заходит и как обрабатывается в процессе)?
  • Как создается контекст? Каков порядок инициализации в контексте?
  • Какие знаете различные способы конфигурации бина? Дефолтный скоуп бина? Какие вообще скоупы бывают? Для чего они используются?
  • Какая разница между BeanFactory и FactoryBean?
  • Расскажите об autowired-аннотации. Есть поле, помеченное autowired, как Spring находит бин и инжектит, какой алгоритм? Что, если реализаций интерфейса две? Можно ли вешать autowired на несколько конструкторов?
  • Для чего нужен @PostConstruct? Что выполнится раньше — @PostConstruct или конструктор?
  • Аннотация @Transactional, что знаете о ней? Какие у нее параметры? На что ее можно повесить? Какой паттерн используется как основа (прокси)? Опишите требования к методу, на который хотим повесить эту аннотацию.
  • Дефолтные property в Spring boot: для чего они, где конфигурируются?
  • Какой паттерн используется в основе spring security (chain of responsibility в виде цепочки фильтров)?
  • Перечислите виды авторизации в Spring security. За что отвечает аннотация @Preauthorize?

Hibernate

Изначально я хотел объединить темы Spring и Hibernate в одну, но в итоге решил не создавать хаос в относительно структурированном подходе. После штудирования статей о том, что это за фреймворк и какие его функции, обязательно погуглите разницу между JPA, Spring Data JPA и Hibernate. И обязательно поймите ее, это сильно упростит процесс понимания взаимодействия Spring и Hibernate.

Вопросы:

  • Как Hibernate формирует запросы? Что такое фетчинг, батчинг?
  • В каких состояниях может быть entity? Расскажите немного о них.
  • Кеш запросов — расскажите о всех уровнях.
  • Когда возникает lazy initialization exception?
  • Расскажите об известной в Hibernate проблеме N+1 select.
  • Расскажите о стратегиях наследования сущностей.
  • Если внутри сущности есть коллекции, подгружаются ли они по умолчанию?

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

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


Иллюстрация Дарины Скульской


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

LinkedIn

23 комментария

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

>почти 2020
>spring, hibernate

Кек. Хорошие проекты на джаве их не используют.

Удивительно.
И что же используют хорошие проекты?

Dagger для dependency injection,
Netty для «крутого» сервера,
SparkJava для «простого» http сервера,
gRPC для RPC замість REST...
Це коротко про те, що в наших проектах є.

З Hibernate гірше ... їздимо на своєму велику поверх jdbc. Треба якось довести до розуму його і викласти в open source.

Невже, згадані вами технології, суттєво кращі за spring?

Якщо чесно, об’єктивно відповісти важко, оскільки зі spring не працював ... лише читав про нього.
Тому круто було б, щоб ви прокоментували мої аргументи:

1. Щодо netty ... тут можна написати будь-що з будь-яким мережевим протоколом ... але це не чесне порівняння. Щодо http ... можна зробити long push, можна зробити обробку запитів в корутинах (з котліном), а можна і звичайний веб-сервер (що трохи громоздко).

2. SparkJava — стартує в пару стрічок і зробити API на пару викликів — просто і швидко.

3. Щодо HTTP API в цілому ... більшість таких API в нас мають «свій» спосіб підпису запитів та серіалізації. В результаті, робота з http сервером зводиться до невеликої обгортки, яка роутить запит вже по власноруч написаним класам ... і тут абсолютно все-рівно, що там під капотом чи netty чи sparkJava чи щось інше на свій смак, так як робота з цим середовищем робиться лише в двох-трьох файлах.

4. Application server-и ми не використовуєм. Сайти пишем на php, а не на java, тому http весь — це лише server2server api.

5. Щодо dagger ... він compile-time і генерує код, який можна читати. Швидше не напишеш. Конкурентів немає. Не бачу сенсу в іншому підході до dependency injection.

6. gRPC — працює мегашвидко порівняно з REST. Клієнт і сервер генеруються для купи мов програмування. Дуже швидко і безболісно пишеться як сервер так і клієнт. Мінус: в браузері не буде нормально працювати, немає аналога curl, postman, тощо.

7. Щодо бази ... є така ідея, що «базу даних треба поважати». Hibernate, в цих термінах, її «не поважає», і тому з ним проблем більше, ніж рішень (ми пробували лише в одному проекті ... не виключено, що невірно застосували). Але цей пункт краще винести в окреме обговорення, так як гарного рішення «а як, все-таки треба робити» в мене зараз немає. Найбільш адекватним ORM, з моєї точки зору, для java є гугловський Room під Android, але то лише під Android. ... хоча дивлюсь тут jdbi пропонують ... треба глянути до нього ... виглядає непогано на перший погляд.

Щодо фіч spring-а, які, можливо, були б корисні, але в нас явно немає:
— Все таки вирівняна та стандартизована екосистема підходів.
— AOP виглядає круто, хоч і громоздко і привносить в проект магію. Не знаю, що там на практиці з ним, але як мінімум є така можливість і вироблені практики.
— Кругом обіцяють, що має вийти testable код. Якщо так, то круто. Але відчуваю, що безкоштовного сиру там немає.

Dagger для dependency injection

Сколько классов-компонентов в проекте? Как реализовывается транзакционность? Как бросаются/обрабатываются глобальные ивенты?

З Hibernate гірше ... їздимо на своєму велику поверх jdbc

Сколько максимально полей в сущностях? Сколько сущностей в проекте? Сколько максимум глубина вложенности сущностей? Сколько максимально вложенных коллекций сущностей? Есть ли лейзи лоадинг?

Не міряв метрик, якщо чесно, в таких розрізах. Та й проект/репозиторій далеко не один.
Якщо взяти найбільший, то можу дати такі дані:

— 1946 java файлів на 13Мб суто java-коду. Класів, відповідно, більше, якщо врахувати вкладені. Це лише java. А ще є php з адмінкою, crud-ами, тощо.

— транзікційнійсть ... в межах однієї бази даних транзакціями, як не дивно ... між різними системами, той, хто ініціює «транзакцію», відповідає і за те, щоб опитати всі інші сервіси і довести транзакцію до кінця або скасувати її ... такий собі eventual consistency на скінченних автоматах ... це якщо я вірно зрозумів ваше питання.

— про глобальні події я не сильно зрозумів про що ви ... якщо про щось типу event bus, то в чому проблема взяти RabbitMQ ? ... хоча в нас його і немає. В деяких сценаріях ще ZooKeeper може бути.

— щодо сутностей ... сутності різні бувають ... якщо ви про БД, то 127 таблиць в них в сумі 919 полів, в найширшій таблиці 64 поля.

— що ви розумієте під вкладеними колекціями теж важко зрозуміти ... відношення 1:N в БД? якщо поля я порахував grep-ом, то тут так прикинути не вийде :) ... є і 1:N і N:N і їх ніхто не рахував :)

— lazy loading теж різний буває ... якщо ви про те, що разом з об’єктом підвантажуються всі foreign key-ї (чи lazy чи ні), то такого не робимо взагалі. Якщо треба перейти по foreign key, робиться явно ще один запит — корона не злетить. З такої точки зору, більш lazy не придумаєш :)

З однієї сторони, проект, дуже навіть не малий. З іншої, 127 таблиць в БД не так і багато, якщо порівнювати з «деякими». Але, ви знаєте, проектував би зараз, старався б архітектуру розбити хоча б на 2-3 менші сервіси з меншою кількістю таблиць. Наприклад, 100% виніс б всю бухгалтерію кудись подалі, так як вона «погано впливає» на архітектуру в цілому, так як міняється кардинально і часто.

Хотілося б зрозуміти, що відповіді на ці питання вам зможуть пояснити?

Guice/Dagger или ручной DI.
JAXRS или микрофреймворки для REST.
JOOQ или всякие jdbc врапперы.

Хз почему у большинства джавистов такая ментальность — тащить монструозные фреймворки.

Потому что все остальное хуже саппортится. Насчет Хибернейта я отчасти соглашусь, мне например jdbi3 хорошо зашел, по крайней мере лучше чем jooq, чем-то похоже на spring data jdbc, а вот спрингу к сожалению реальных альтернатив по качеству пока нет, хотя его монструозность меня тоже доставляет слегка. Смотрел я и на quarkus и на dropwizard, все это хорошо для прототипов только пока. Все реактивные фреймворки тем более пока в топку.

Для DI вообще можно без фреймворков обойтись, тк это паттерн проектирования.

Да, мне тоже интересно, что используют хорошие проекты на джаве?

Хороших проектів на джаві нема, шах і мат джавісти!

Якщо за них готові платити гроші, то вони вже як мінимум непогані

Совет юным падаванам — не идите туда, где используется Спринг и Хайбернейт. От этого веет таким унылым энтерпрайзом, вся работа будет заключаться в пихании из одного формата (json, xml) а другой или в базу. Про сортировку у вас спросят один раз на собесе , но вы вряд ли увидите ее в рабочем коде, и тем более не придется изобретать свой алгоритм

И на какие проекты, по вашему мнению, нужно идти?

Понятно что сразу в FAANG деревья крутить.

ну я бы шел туда где kafka, spark, hadoop, coachdb, redis, elastic, event sourcing, и еще много страшных слов.... но самое главное — бабло! мы ведь здесь в основном из-за денег :-)

«похмурий ентерпрайз» приносить стабільні та зовсім не хмурі гроші. Хтось хоче стати гуру програмування, а хтось хоче годувати сім’ю.

Какая разница между BeanFactory и FactoryBean?

орнув )))))))))))) весь галімий джава ентерпрайз в одній фразі

Приведите примеры использования HasThisTypePatternTriedToSneakInSomeGenericOrParameterizedTypePatternMatchingStuffAnywhereVisitor

static.javadoc.io/...​StuffAnywhereVisitor.html

LOL :-))) ору!

Встречаются два бизнес-тренера.
— Как увеличить продажи?
— Легко. Могу рассказать.
— Рассказать и я могу, а вот как их таки увеличить...

Якщо ви про чарівну пілюлю, то поки що вона тільки у фільмах типу Limitless існує)
Про інші збільшення начебто написав: швидко потрапити на нормальний проект в оточення профессіоналів.

Подписаться на комментарии