December 17, 2024

Java: junior. Тестирование при трудоустройстве

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

Почему это важно?

Решение подобных заданий показывает:

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

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

Вопрос 1

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

Варианты ответа:

  1. native
  2. final
  3. volatile
  4. static
  5. default

Обоснование:
Ключевое слово static в Java используется для методов или полей, которые принадлежат классу, а не конкретному экземпляру. Это означает, что такие методы можно вызывать напрямую через имя класса, без создания объекта. Остальные варианты:

  • native — указывает, что метод реализован на другом языке (например, C), но это не делает метод доступным без создания экземпляра.
  • final — запрещает переопределение метода, но не влияет на его вызов.
  • volatile — применяется к полям для обеспечения согласованности при доступе из разных потоков.
  • default — используется для указания реализации метода по умолчанию в интерфейсах.

📌Правильный ответ: static

Вопрос 2

Какой класс-обёртка соответствует примитивному типу данных char?

Варианты ответа:

  1. Symbol
  2. Char
  3. CharSequence
  4. Character
  5. String

Обоснование:
В Java каждый примитивный тип данных имеет соответствующий класс-обёртку для работы с объектами. Для примитивного типа char класс-обёртка называется Character. Другие варианты:

  • Symbol — не существует в стандартной библиотеке Java.
  • Char — также не существует в стандартной библиотеке Java.
  • CharSequence — интерфейс, представляющий последовательность символов, но не является обёрткой для char.
  • String — класс для работы с последовательностями символов, но не является обёрткой для отдельного символа.

📌Правильный ответ: Character

Вопрос 3

Для чего используются модификаторы доступа в Java?

Варианты ответа:

  1. Для указания, какие методы могут быть переопределены в подклассах
  2. Для синхронизации доступа к общим ресурсам в многопоточных приложениях
  3. Для определения, какие классы могут наследоваться от данного класса
  4. Для контроля доступа к базам данных
  5. Для управления видимостью и доступностью классов, их полей и методов

Обоснование:
Модификаторы доступа в Java (такие как public, protected, private и package-private) используются для управления видимостью и доступностью классов, их полей, методов и конструкторов. Они позволяют:

  • Определить, какие части кода могут обращаться к определённым классам и их членам.
  • Ограничить доступ к данным и методам для повышения инкапсуляции.

Другие варианты:

  • Перепределение методов зависит от модификаторов доступа (public, protected и package-private), но цель модификаторов шире.
  • Синхронизация потоков осуществляется с использованием ключевого слова synchronized, а не модификаторов доступа.
  • Контроль доступа к базам данных осуществляется на уровне драйверов и SQL, не связанного с модификаторами доступа.

📌Правильный ответ: Для управления видимостью и доступностью классов, их полей и методов

Вопрос 4

Что произойдет, если вы попытаетесь присвоить значение типа double переменной типа int без явного преобразования?

Варианты ответа:

  1. Компилятор выдаст предупреждение, но программа выполнится
  2. Переменная типа int получит значение, округленное до ближайшего целого числа из значения типа double
  3. Попытка выполнить данную инструкцию вызовет исключение времени выполнения и программа завершится с ошибкой
  4. Значение типа double не будет присвоено, и переменная типа int получит нулевое значение
  5. Компилятор выдаст ошибку компиляции, так как необходимо явное преобразование типов

Обоснование:
В Java присвоение значения типа double переменной типа int невозможно без явного преобразования (cast), поскольку типы имеют разную разрядность и формат хранения данных. Компилятор строго проверяет типы данных, и попытка сделать такое присвоение без явного преобразования приводит к ошибке компиляции.

  • Java не выполняет автоматического округления или обрезания значений при приведении типа double к int.
  • Исключения времени выполнения не возникает, так как компилятор предотвратит выполнение программы до её запуска.

📌Правильный ответ:
Компилятор выдаст ошибку компиляции, так как необходимо явное преобразование типов

Вопрос 5

Для чего используется оператор break в цикле?

Варианты ответа:

  1. Прерывает выполнение текущего цикла и, если имеется, переходит ко вложенному
  2. Завершает выполнение цикла, в котором он находится
  3. Завершает выполнение всех циклов, включая внешние и вложенные
  4. Пропускает текущую итерацию и начинает цикл сначала
  5. Переходит к следующей итерации цикла

Обоснование:
Оператор break в Java используется для немедленного завершения выполнения текущего цикла или блока switch. Он прерывает выполнение только того цикла, в котором находится, и программа продолжает выполнение с первого оператора после завершённого цикла.

  • break не переходит ко вложенному циклу.
  • Он завершает только текущий цикл, а не все внешние и вложенные.
  • Для пропуска текущей итерации и перехода к следующей используется оператор continue.

📌Правильный ответ:
Завершает выполнение цикла, в котором он находится

Вопрос 6

Какой интерфейс должен реализовывать класс, чтобы его можно было использовать в цикле for-each?

Варианты ответа:

  1. Iterable<T>
  2. Enumerable<T>
  3. Traversable<T>
  4. Iterator<T>
  5. Stream<T>

Обоснование:
Цикл for-each в Java может быть использован для объектов, которые реализуют интерфейс Iterable<T>. Этот интерфейс определяет метод iterator(), который возвращает объект Iterator<T>. С его помощью осуществляется итерация по элементам коллекции. Остальные варианты:

  • Enumerable<T> — не существует в стандартной библиотеке Java.
  • Traversable<T> — также отсутствует в Java.
  • Iterator<T> — используется для работы с итерациями, но сам по себе не является интерфейсом для реализации класса, который можно использовать в for-each.
  • Stream<T> — предназначен для потоковых операций, но не используется напрямую в цикле for-each.

📌Правильный ответ:
Iterable<T>

Вопрос 7

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

Варианты ответа:

  1. Пропущен блок else после условия if
  2. Некорректный синтаксис в теле условия
  3. Неверно задано условие окончания цикла
  4. Некорректное использование оператора continue
  5. Переменная i инициализирована вне цикла

Обоснование:
Ошибка возникает из-за неверно заданного условия окончания цикла: i <= array.length.

  • В Java индексация массивов начинается с нуля, а последний индекс равен array.length - 1.
  • Когда значение i становится равным array.length, программа пытается обратиться к несуществующему элементу массива, что вызывает исключение ArrayIndexOutOfBoundsException.

Остальные варианты:

  • Пропущенный блок else не вызывает ошибки.
  • Синтаксис в теле цикла корректен.
  • Использование оператора continue корректно.
  • Инициализация i вне цикла допустима.

📌Правильный ответ:
Неверно задано условие окончания цикла

Вопрос 8

Какое утверждение о конструкторе класса в Java НЕВЕРНО?

Варианты ответа:

  1. Если не определить конструктор в классе, Java автоматически создаст конструктор по умолчанию без параметров
  2. Конструктор может иметь модификаторы доступа, такие как public, protected или private
  3. Конструктор класса можно перегрузить
  4. Конструктор может возвращать значения, как обычный метод
  5. Из конструктора можно выбросить исключение

Обоснование:

Верные утверждения:

    • Если не определить конструктор, Java создаёт конструктор по умолчанию без параметров.
    • Конструктор может иметь модификаторы доступа, включая public, protected, private или package-private.
    • Конструкторы можно перегружать, создавая несколько вариантов с разными параметрами.
    • Конструктор может выбросить исключение, если это явно указано в его объявлении.

Неверное утверждение:

    • Конструктор не может возвращать значения, как обычный метод. Он не имеет возвращаемого типа (даже void) и используется только для инициализации объекта.

📌Правильный ответ:
Конструктор может возвращать значения, как обычный метод

Вопрос 9

Что выведет данный фрагмент кода?

Варианты ответа:

  1. Ошибка компиляции
  2. Будет выброшено исключение DivisionByZeroException
  3. Будет выброшено исключение ArithmeticException
  4. true
  5. false

Обоснование:
Оператор && использует так называемую "ленивую" (short-circuit) логику. Это означает, что если первая часть выражения (a >= 0) истинна и вторая часть (b < 6) тоже истинна, то правая часть после оператора || даже не будет проверяться.
В данном случае:

  1. a >= 0 истинно (a = 0).
  2. b < 6 истинно (b = 5).
  3. Поскольку логическое выражение до оператора || уже истинно, правая часть (b / a == 1) не вычисляется, что предотвращает деление на ноль (a = 0).

Программа завершится без ошибок, и результат будет true.

📌Правильный ответ:
true

Вопрос 10

Для чего используются Generics в Java?

Варианты ответа:

  1. Для создания классов и методов, работающих с различными типами данных, обеспечивая типобезопасность и повторное использование кода
  2. Для упрощения работы с базами данных, обеспечивая типобезопасность SQL-запросов
  3. Для обеспечения совместимости между разными версиями Java Virtual Machine (JVM)
  4. Для создания наследуемых классов, которые автоматически переопределяют методы базового класса для работы с разными типами данных
  5. Для автоматического управления памятью и улучшения производительности программы

Обоснование:
Generics (обобщённые типы) в Java позволяют создавать классы, интерфейсы и методы, которые могут работать с различными типами данных, не теряя при этом типобезопасности. Это упрощает разработку, снижает вероятность ошибок времени выполнения (например, ClassCastException) и повышает читаемость и повторное использование кода.

Типобезопасность и повторное использование кода являются основными целями использования Generics.

Остальные варианты не связаны с Generics:

    • Упрощение работы с SQL-запросами не является задачей Generics.
    • Совместимость JVM не имеет отношения к Generics.
    • Generics не связаны с автоматическим управлением памятью, этим занимается сборщик мусора.
    • Generics не автоматически переопределяют методы базовых классов.

📌Правильный ответ:
Для создания классов и методов, работающих с различными типами данных, обеспечивая типобезопасность и повторное использование кода