Хабр, привет! Меня зовут Даниил Пилипенко, я программный директор факультета backend-разработки направления «Программирование» Skillbox, директор центра подбора IT-специалистов SymbioWay. Сегодня разберём практические задачи, с которыми могут столкнуться Java-разработчики junior-уровня на собеседовании. Такого рода задачи мы часто видим на собеседованиях наших клиентов и коллег, а также сами даём соискателям. В процессе подбора кандидатов работодатель хочет понять, насколько ему подходит тот или иной соискатель — насколько он комфортен в общении и работе, обладает необходимым опытом и, что самое важное, техническими навыками для предстоящей работы. Ранее я рассказывал о пяти навыках, которые часто проверяются при приёме на работу у начинающих Java-разработчиков. А в этой статье я приведу примеры конкретных задач, которые могут давать на собеседованиях, и разберу, на что смотрит работодатель при их решении. Задача 1. Написать код, выполняющий какую-то несложную задачу. Здесь может быть, например, классический FizzBuzz, задача на сжатие или переворачивание строки. Работодателю здесь важно понять, как соискатель владеет основами синтаксиса языка и может ли писать код сразу чисто. Удивительно, но многие кандидаты испытывают значительные сложности при выполнении задач такого рода. Одна из задач, которую мы даём соискателям: написать код, который выводит числа от 0 до 1000, которые делятся на 3, но не делятся на 5, и сумма цифр в которых меньше десяти. Задача часто вызывает совершенно немыслимые трудности у людей, утверждающих, что их уровень middle или даже senior. Вот несколько примеров решений такой задачи кандидатами на собеседованиях: Напишите нам в комментариях, как вы оцениваете каждое из этих решений и почему. Какое из них считаете лучшим, а какое худшим. Сразу отмечу, что решение, которое мы в SymbioWay считаем идеальным, здесь не приводим. Можете также попробовать написать его в комментариях. С помощью задач такого типа мы проверяем уровень соискателя: как много он писал код сам, а также косвенно — сталкивался ли с «грязным» кодом и рефакторил ли его. По такому заданию можно косвенно увидеть, как быстро и «чисто» (понятно и поддерживаемо) специалист будет писать собственный код. Задача 2. Создать веб-приложение на фреймворке Spring, которое будет соответствовать определённой спецификации. Спецификация может быть дана в текстовом виде или в виде отдельного Swagger-файла. Например, реализовать backend для анонимного онлайн-чата со следующей спецификацией: GET /init — запрос инициализации, который по ID сессии отвечает, авторизован ли текущий пользователь или нет. Запрос без параметров Формат ответа: POST /auth — запрос, регистрирующий и авторизующий пользователя. Он добавляет пользователя в базу данных и привязывает к текущей сессии. Формат запроса: name — имя пользователя sex — пол пользователя, M или F Формат ответа: GET /users — запрос, возвращающий список пользователей в чате в порядке от самого свежего, который зарегистрировался недавно, до самого старого. Запрос без параметров Формат ответа: GET /messages — запрос, возвращающий ленту сообщений чата от самого нового до самого старого с постраничной навигацией. Формат запроса: offset — сдвиг от самого последнего до самого раннего, от 0, по умолчанию равен 0 limit — количество сообщений, которые нужно вывести, по умолчанию — 100 Формат ответа: POST /messages — запрос, создающий новое сообщение от имени текущего пользователя. Форматы запроса и ответа спроектируйте самостоятельно на ваше усмотрение на основе имеющейся документации. С помощью таких задач мы и работодатели проверяют сразу несколько навыков: умение правильно проектировать и создавать веб-приложения на фреймворке Spring в соответствии с принятой структурой; понимание принципов клиент-серверного взаимодействия (знание HTTP и стандарта REST); умение работать с ORM-системой (обычно Hibernate) и базой данной, умение проектировать структуру этой базы; умение писать код на Java и владение базовыми навыками при работе с этим языком программирования, в частности, знание ООП, умение работать со строками и коллекциями, лямбда-выражениями и Stream API, привычку их применять при необходимости. Задача 3. Написать SQL-запрос. Например, задача может быть такой. У вас есть две таблицы: employee — сотрудники компании id department_id work_start_date name salary department — отделы, в которых работают сотрудники id name lead_id — ID руководителя отдела Нужно написать такой SQL-запрос, который выведет всех сотрудников, работающих в компании с лета 2021 года, не привязанных к отделам и получающих зарплату меньше 100 000 рублей. Верным ответом на такую задачу будет запрос: С помощью задач такого плана можно понять, насколько кандидат владеет языком запросов SQL, если это важно в данном проекте. Вместо задач на написание SQL-запросов, могут предложить написать код с использованием Hibernate. Конечно, владение SQL — фундаментальный навык, который никогда не будет лишним. Но в некоторых проектах предпочитают писать не на чистом SQL.  Задача № 4. Решить заданную проблему устно. Например, рассказать, как предотвращать взаимные блокировки (deadlock) в многопоточных приложениях, или объяснить, как код, работающий с коллекцией, сделать потокобезопасным. Здесь обычно требуется сначала рассказать о самой проблеме — в чём она состоит и почему её вообще следует решать, а затем объяснить, как именно это можно сделать. И чем понятнее будет ваш рассказ и чем логичнее будут ваши рассуждения, тем лучше. При этом не обязательно решать задачу до конца идеально. Того, что вы думаете в правильном направлении, будет вполне достаточно для засчитывания ответа как верного. Ведь в реальности невозможно знать и помнить всё, гораздо важнее умение находить решения, понимать, куда «копать», и ставить эксперименты. Задача № 5. Задача или серия вопросов на понимание принципов и паттернов ООП. Например, создать класс, объект которого может быть представлен только в единственном экземпляре (по сути, реализовать паттерн Singleton). Тут могут не только попросить в итоге написать код для многопоточного режима работы, но и объяснить, зачем вообще такое может быть нужно, или рассказать, почему Singleton не используется во фреймворке Spring и чем он там фактически заменяется.  Мы сами сталкиваемся с тем, что на вопросы вроде «для чего в Java используется ключевое слово final» или «может ли статический метод переопределяться при наследовании» отвечают менее 20% кандидатов, по резюме имеющих уровень middle или выше. Вы, возможно, будете удивлены, но во время решения практических задач работодатель не всегда ждёт полного и чёткого ответа по каждой из них. Он рассчитывает скорее на правильный вектор рассуждения и понимание той или иной темы. Конечно, когда мы просим написать код, то кандидату лучше бы справиться с этой задачей. Так мы понимаем, что он действительно умеет писать код и делает это сразу чисто. Кроме того, здесь часто бывает важно ваше упорство: умение довести задачу до конца — важнейший навык, с которым у многих в наше время возникают проблемы. Третье, что также важно увидеть в кандидате, — это понимание базовых, фундаментальных концепций. Если вы не знаете, что такое HTTP, как делать простейшие SQL-запросы, для чего вообще нужна многопоточность и что такое потокобезопасность, вам, скорее всего, откажут. Когда мы подбираем специалистов уровня junior в нашу команду или кому-то из работодателей, мы проверяем три блока навыков: Понимание базовых концепций (синтаксис, коллекции, чистота кода, ООП, создание приложений на Spring, HTTP, REST и SQL). Умение быстро, самостоятельно и грамотно решать возникающие проблемы, в том числе находить нужную информацию. Уровень обучаемости — скорость и качество запоминания и дальнейшего внедрения в свою работу best practices и рекомендаций, которые мы даём новичку. После приёма на работу начинающего специалиста важно не перегрузить его слишком сложными задачами. Если он хорошо выполняет свою работу и близок к тому, чтобы начать скучать, то постепенно ему доверяют всё более сложные и интересные проекты, которые обеспечивают дальнейший рост.