Для студентов JavaRush задачи по программированию, Java и валидатор — лучшие друзья. Тем не менее, у каждого падавана-разработчика наступает момент, когда нужно начинать иногда сходить с проторенной дорожки, придумывать себе мини-проекты и готовиться к собеседованиям. На интервью, казалось бы, должны встречаться точно такие же практические задачи по Java, что и в курсе. В большинстве случаев так и есть, но некоторые компании любят задавать вопросы с подвохом или что-то непривычное. Чтобы не быть сбитым с толку в стрессовый момент собеседования, полезно пробовать решать такие Java-задачи самостоятельно, в домашних условиях.
В этой статье мы рассмотрим полдесятка таких хитрых задач. Рекомендуем сначала прочитать условие и попробовать решить самостоятельно. И ещё: не забывайте решать задачи по Java из курса каждый день!

- Задача-1: Создание бесконечного цикла на пустом месте
- Задача-2. Создайте комментарий, который будет выполнятся
- Задача-3: создать именованный цикл
- Задача-4. О единственном дубликате в массиве целых чисел
- Задача-5. О неединственном дубликате в массиве целых чисел
Задача - 1: Создание бесконечного цикла на пустом месте
Дан блок кода. Дополните его так, чтобы цикл стал бесконечным.
class ToInfinity {
public static void main(String[] args) {
//впишите код сюда
for (int i = start; i <= start + 1; i++) {
/* тут должен быть бесконечный цикл, менять ничего нельзя*/
}
}
}
«Ничего сложного», — скажете вы. Скорее всего, вы не раз попадали в такую историю: решая задачи по Java, вы создавали бесконечный цикл и думали, как от него избавиться. Тут же наоборот. Хитрость в том, что сам цикл и условия выхода из него менять нельзя. Есть только две итерации. Тем не менее, их вполне достаточно, чтобы создать бесконечный цикл.
Похоже, что он должен работать только для двух итераций, но его можно сделать бесконечным, за счет использования переполнения. Уже догадались, как?
Решение
За счёт переполнения.Integer.MAX_VALUE
— максимальное значение, которое int
может хранить в Java. Если вы достигаете Integer.MAX_VALUE
и инкрементируете это значение, то скатываетесь к Integer.MIN_VALUE
, то есть, к минимальному значению Integer
. Таким образом, для решения этой Java-задачи нам достаточно присвоить переменной start
значение на 1 меньшее, чем максимальное для типа данных int
.
Код задачи на Java:
class ToInfinity {
public static void main(String[] args) {
int start = Integer.MAX_VALUE - 1;
for (int i = start; i <= start + 1; i++) {
//бесконечный цикл
System.out.println(i); //убеждаемся в бесконечности цикла
}
}
}
Что получается? Мы начинаем со start=2147483645 (Integer.MAX_VALUE-1), на следующей итерации значение становится 2147483645, потом 2147483646, затем -2147483648, -2147483647… и так далее.
Задача - 2. Создайте комментарий, который будет выполнятся
Ну вот, приехали! С самых первых лекций мы слышали о том, что комментарии не выполняются. На то они и комментарии. Думаем, решение этой задачи для Java-программиста, даже опытного, — не всегда очевидно. Тем не менее, есть один хитрый способ, как заставить Java-машину «легально» запустить комментарий на выполнение. Чувствуете, откуда ветер дует? Попробуйте предположить!Решение
Код решения задачи на Java:
public class ExecutableComment {
public static void main(String[] args) {
// комментарий ниже будет выполнен!
// \u000d System.out.println("выполняемый комментарий");
}
}
Если набрать код этой задачи по джава в IDE, вот что мы получим:
выполняемый комментарий
Причина в том, что компилятор Java считывает Unicod-символ \u000d
как новую строку, и читает наш код следующим образом:
Расшифрованный компилятором код решения задачи на Java:
public class ExecutableComment {
public static void main(String[] args) {
// the line below this gives an output
// \u000d
System.out.println("comment executed");
}
}
Задача - 3: создать именованный цикл
Ещё один представитель серии «практические задачи по программированию, Java в сферическом вакууме». В том смысле, что непонятно, зачем это нужно, вряд ли цикл чувствует обиду от того, что он обезличен. Ну да ладно, важно другое: язык позволяет дать циклу имя.Решение
Примечание: кому-то такие "имена" известны как "метки", которые не рекомендуется использовать на практике. Код решения задачи по джава, демонстрирующий именованный цикл
public class NamedLoop {
public static void main(String[] args) {
loop1:
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
if (i == 3)
break loop1;
System.out.println("i = " + i + " j = " + j);
}
}
}
}
Вот что будет на выходе, если запустить программу:
i = 0 j = 0
i = 0 j = 1
i = 0 j = 2
i = 0 j = 3
i = 0 j = 4
i = 1 j = 0
i = 1 j = 1
i = 1 j = 2
i = 1 j = 3
i = 1 j = 4
i = 2 j = 0
i = 2 j = 1
i = 2 j = 2
i = 2 j = 3
i = 2 j = 4
Тут также можно использовать continue для перехода к началу именованного цикла.
А ещё при надобности получится использовать break
(или continue
) во вложенном if-else
с for
-циклом, чтобы разбить несколько циклов с помощью if-else
. Это поможет избежать установки большого количества флагов и тестирования их в if-else
чтобы понять, продолжать или выходить из внутреннего цикла.
Задача - 4. О единственном дубликате в массиве целых чисел
Задан массив (илиArrayList
, как вам больше нравится) целых чисел, в котором содержатся элементы Integer
от 1 до 100. В этом массиве есть один и только один продублированный элемент. Как его найти?
Такие задачи для Java-программиста привычнее, чем предыдущие три. Потому что она не о знании тонкостей языка, которые почти никогда не используются, а о логике.
Первый необузданный порыв — решать перебором — пропадает довольно быстро, когда включается голова или там установка «я же программист, я же умный». Плохо только, что на собеседовании, в условиях стресса, этого может и не произойти. Так что думайте сейчас, прежде, чем заглядывать в решение!
Алгоритм решения следующий:
Посчитайте сумму всех чисел от 1 до 100. Думаем, вы знаете, как это можно сделать (например, с помощью знаменитого метода Гаусса) Теперь считаете сумму элементов вашего массива илиArrayList’а
.
И… вычитаете первую сумму из второй.
Бинго! Полученное число — и есть значение дублирующегося элемента.
Код решения java-задачи для ArrayList
.
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class FindDuplicate {
private static void findDuplicate(List<Integer> elements) {
//находим сумму всех уникальных элементов списка
int distinctSum = elements.stream().distinct().mapToInt(e -> e).sum();
//находим сумму всех элементов списка
int totalSum = elements.stream().mapToInt(e -> e).sum();
System.out.println("Элемент, который повторяется : " + (totalSum - distinctSum));
}
public static void main(String[] args) {
//создаем список последовательных элементов на промежутке [1..101).
List <Integer> elements = IntStream.range(1, 101).boxed().collect(Collectors.toList());
//устанавливаем элементу с индексом 53 значение 23
elements.set(53, 23);
findDuplicate(elements);
}
}
Другое решение
import java.util.List;
import java.util.ArrayList;
public class Duplicate {
public int findDuplicateNumber(List<Integer> numbers) {
int highestNumber = numbers.size() - 1;
int total = getSum(numbers);
int duplicate = total - (highestNumber * (highestNumber + 1) / 2);
return duplicate;
}
public int getSum(List<Integer> numbers) {
int sum = 0;
for (int num : numbers) {
sum = sum + num;
}
return sum;
}
public static void main(String a[]) {
List <Integer> numbers = new ArrayList <Integer>();
for (int i = 1; i < 100; i++) {
numbers.add(i);
}
//добавляем дубликат в список
numbers.add(25);
Duplicate dn = new Duplicate();
System.out.println("Элемент, который повторяется: " + dn.findDuplicateNumber(numbers));
}
}
Задача - 5. О неединственном дубликате в массиве целых чисел
Если предыдущая задачка показалась вам слишком лёгкой, то попробуйте решить следующую: дан лист целых чисел от 1 до 100. В нём есть дубликаты (больше одного). Как найти элементы, которые встречаются больше одного раза (найти сам элемент и указать, сколько раз он встречается)?Решение
Тут логичнее всего для решения использовать такую структуру, какHashMap
, поскольку она хранит данные парами «ключ-значение».
Код решения Java-задачи:
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class SomeDuplicates {
private static void findDuplicates(List<Integer> elements) {
HashMap <Integer, Integer > duplicates = new HashMap < >();
//заполняем Map duplicates значениями по принципу:
// ключ – значение элемента, значение – сколько раз он встречается
elements.forEach(e -> duplicates.put(e, duplicates.get(e) == null ? 1 : duplicates.get(e) + 1));
//из duplicates убираем все элементы, которые встретились не более 1 раза,
//и сохраняем //результат в список (для удобства обработки на следующем шаге)
List <Map.Entry <Integer, Integer> >
result = duplicates.entrySet().stream().filter(d -> d.getValue() > 1).collect(Collectors.toList());
//выводим результат для всех элементов в списке result
result.forEach(e -> System.out.println(String.format("Элемент %d встречается %d раз", e.getKey(), e.getValue())));
}
public static void main(String[] args) {
List <Integer> elements = IntStream.range(1, 101).boxed().collect(Collectors.toList());
elements.set(97, 23);
elements.set(27, 51);
elements.set(99, 23);
findDuplicates(elements);
}
}
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ