Блог компании EPAM

Бритва EPAMа: тест по Java, о котором не скажут «опяяять»

На Хабре больше сотни хабов и компаний, привязанных к тегу Java. Кажется, ни на одну тему не пишут так часто и подробно. Возможно, мы с компанией EPAM и сломали бритву Оккама, но сделали этот тест, посвященный одному из самых популярных языков программирования. Какое отношение имеет Райан Гослинг к Java? Var — это варик или совсем не вариант? Отработает ли вывод в консоль, если программист в конец запутался? — Предлагаем пройти тест и ответить на вопросы, в которых не упущены ни давняя история, ни последние обновления.

Начать тест
Когда состоялся выпуск Java 1.0?
Дальше
Проверить
Узнать результат
Команда по разработке Java состояла из нескольких человек. Скажите, кто изображен на фотографиях?
Дальше
Проверить
Узнать результат
Почему название книги «Design Patterns: Elements of Reusable Object-Oriented Software» затем условно сократили до «GOF»?
Дальше
Проверить
Узнать результат
Команда разработчиков решила отметить выход первого релиза. Пришли в бар, сели за стол, позвали официанта и заказали еду. Работа стала основной темой разговора, которую они постоянно проецировали на окружающую действительность. Спор дошел до того, что ребята стали определять, к каким шаблонам проектирования можно отнести ту или иную стандартную ситуацию из жизни. Так, они пытались понять, чем является заказ еды у официанта и передача заказа от официанта к шеф-повару.
Помогите разрабам уйти сытыми и довольными из ресторана. Какому поведенческому шаблону соответствуют заказ и передача заказа?
Дальше
Проверить
Узнать результат
Отдел внедрения решил подготовить небольшие задачи для своих коллег-программистов в рамках творческого конкурса. Одна из задач вызвала споры еще до этапа проверки кода. Помогите сэкономить время команде, ответив на вопрос. Что будет в результате запуска блока А и В (результаты запуска блоков объединены в один верный ответ)?

Что будет в результате запуска блока А:
class ClassA {

    private final String value;

    public ClassA(String value) {
        this.value = value;
        System.out.println(value);
    }
}

public class ClassB extends ClassA {
    private final String value = new String();

    public ClassB() {
        super(value);
    }

    public static void main (String[] args) {
        ClassA var = new ClassB();
        System.out.println(var);
    }
}


Что будет в результате запуска блока В:
abstract class ClassA {

    public ClassA() {
        System.out.println(value());
    }
    abstract String value();
}

public class ClassB extends ClassA {
    private final String value = new String();

    public ClassB() {
    }

    @Override
    String value() {
        return value;
    }

    public static void main (String[] args){
        new ClassB();
    }
}

Дальше
Проверить
Узнать результат
Есть задача по созданию метода с использованием двух ключей. Специалист решил попробовать вариант с hashBasedTable. Создал пример, но запутался. Как отработает вывод в консоль (System.out.println)?

public class ClassSaveKey{

    private static HashBasedTable<String, String, String> languageTable = HashBasedTable.create();

    public static void main(String[] args) {
        //первоначальные данные
        setText("Object-oriented programming language", "1990", "Python");
        setText("Object-oriented programming language", "1995", "Java");
        setText("Functional programming language", "2005", "F#");

        //вывод в консоль
        System.out.println("Языки: " + languageTable.row("Object-oriented programming language"));
        System.out.println("Ключи строк: " + languageTable.rowKeySet());
        System.out.println("Структура относительно столбцов: " + languageTable.columnMap());
        System.out.println("Получение значения с использованием ключа столбца и строки: " + languageTable.column("2005").get("Functional programming language"));

    }
    private static void setText(String rowStr, String keyStr, String text) {
        languageTable.put(rowStr, keyStr, text);
    }
}

Дальше
Проверить
Узнать результат
В рамках задач по переводу логики на Java команда постоянно работала с коллекциями и изучала методы. В этот раз был самый обычный метод reverse(). Один из разработчиков задал вопрос коллегам с вариантами ответа. Помогите «повернуть» список коллегам. Какой будет вывод в консоль?

class ReverseTest {
    public static <T> List<T> reverseNew(List<T> src) {
            List<T> results = new ArrayList<>(src);
            Collections.reverse(results);
            System.out.println("3 = " + results);
            return results;
        }

    public static void main(String[] args) {
            List<String> nameList = new ArrayList<>();
            nameList.add("Александр");
            nameList.add("Иван");
            nameList.add("Пётр");
            System.out.println("1 = " + nameList);

            Collections.reverse(nameList);
            System.out.println("2 = " + nameList);
            reverseNew(nameList);
            System.out.println("4 = " + nameList);
    }
}

Дальше
Проверить
Узнать результат
Проводя оптимизацию кода, команда разработчиков задумалась о возможности добавления в конце определенных блоков вызова сборки мусора с помощью System.gc(). Как обычно, состоялся спор, что лучше, System.gc() или Runtime.gc(), и чем они отличаются. Остановились на System.gc(). Тестирование кода показало, что добавление System.gc() не привело к желаемому результату и «передача» памяти в систему не состоялась. Скажите, какие утверждения верны (правильными могут быть несколько ответов)?
Дальше
Проверить
Узнать результат
В компании решили перейти на 8 версию Java и сделать небольшой рефакторинг. Денис любил играть на гитаре, поэтому его сделали ответственным за модуль работы с музыкой. Первым он начал исправление методов, отвечающих за поиск музыкальных произведений. Далее представлен один из методов поиска мелодий с длительностью звучания более двух минут (120 секунд).

public Set<String> findLengthyMelodies(List<Album> albums) {
    Set<String> melodyNames = new HashSet<>();
    for(Album album : albums) {
        for (Melody melody : album.getMelodies()) {
            if (melody.getLength() > 120) {
                String name = melody.getName();
                melodyNames.add(name);
            }
        }
    }
    return melodyNames;
}


Специалист подумал, что стримы — это отличный вариант и произвел рефакторинг. Вот что у него получилось.

public Set<String> findLengthyMelodiesNew(List<Album> albums) {
    return albums.stream()
        .flatMap(album -> album.getMelodyStream())
        .filter(melody -> melody.getLength() > 120)
        .map(melody -> melody.getName())
        .collect(toSet());
}


Программиста позвали на обед, и он не успел запустить проверку. Как вы думаете, метод отработает?
Дальше
Проверить
Узнать результат
Предусмотрительные программисты решили подготовиться к летнему отпуску и заодно посмотреть на новые фичи Java 12. Создали приложения по сбору вещей для отпуска/поездки с использованием новых возможностей. Скажите, метод isRestThing() с вызовом константы перечисления отработает корректно?

public class SwTest {

    enum RestThings {
        SUNGLASSES, BEACH_UMBRELLA, TOWEL, BURGER
    }

    private static boolean isRestThing(RestThings restThings){
        return switch (restThings){
            case SUNGLASSES -> true;
            case BEACH_UMBRELLA -> true;
            case TOWEL -> true;
            case BURGER -> false;
        };
    }

    public static void main(String[] args) {
        System.out.println("Sunglasses are very necessary on vacation = " + isRestThing(RestThings.SUNGLASSES));
    }
}

Дальше
Проверить
Узнать результат
Про ключевое слово «var» было множество споров. Разработчики решили попробовать написать небольшой пример и посмотреть, как на деле выглядит работа с «var».
Они воспроизвели пример, который поможет в будущем определить необходимость внесения изменений в код, разбив большие цепочки на несколько результирующих частей для возможности быстрой отладки и просмотра результатов.
Как вы думаете, код отработает, и если да, то какой будет результат?

import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class Q12 {

    public static void main(String[] args) {
            testVar();
    }

    private static void testVar() {

        var carBrands = Stream.of("Alfa Romeo", "BMW", "DAF")
            .collect(Collectors.toMap(e -> e.substring(0,1), e ->e));

        var countCars = (long) carBrands.values().size();

        var mixedList = List.of(((int) countCars), 7, 1, 6, 2, 5, 5, (int) countCars);

        var divTwo = mixedList.parallelStream()
            .collect(Collectors.partitioningBy(i -> i % 2 != 0));

        var divTwoEv = divTwo.values()
            .stream()
            .max(Comparator.comparing(List::size));

        var sumDivTwoEv = divTwoEv.orElse(Collections.emptyList())
            .parallelStream()
            .mapToInt(Integer::intValue)
            .sum();
        System.out.println(sumDivTwoEv);
    }
}

Дальше
Проверить
Узнать результат
Было решено посмотреть в сторону варианта вывода десятичных чисел в компактной форме с учетом местоположения благодаря Java12. Что будет в консоли после запуска?

import java.text.NumberFormat;
import java.util.List;
import java.util.Locale;

public class Q13 {

    public static void main(String[] args) {
        testCompactNumber(Locale.UK);
        testCompactNumber(Locale.ENGLISH);
    }

    private static void testCompactNumber(Locale locale) {
        var numbers = List.of(100, 1000, 10000);
        numbers.forEach((num) -> {
            NumberFormat nf = NumberFormat.getCompactNumberInstance(locale, NumberFormat.Style.SHORT);
            String format = nf.format(num);
            String country = locale.getCountry();
            System.out.println(country + format);
        });
        numbers.forEach((num) -> {
            NumberFormat nf = NumberFormat.getCompactNumberInstance(locale, NumberFormat.Style.LONG);
            String format = nf.format(num);
            String country = locale.getCountry();
            System.out.println(country + format);
        });
    }
}

Дальше
Проверить
Узнать результат
Команде было необходимо обработать текст и убрать спецсимволы в виде пробелов, табуляции и т.д.. В качестве примера им пришло с сервиса стихотворение А. К. Толстого. «Клонит к лени полдень жгучий» с возможными «проблемными» символами до и после.* Был создан небольшой метод по анализу данной проблемы.
* <8 spaces>, <5 spaces> — представь 8 и 5 пробелов соответственно.

public class Q14 {

    public static void main(String[] args) {
        testStringRow("<8 spaces> Клонит к лени полдень жгучий," +
            "Замер в листьях каждый звук," +
            "В розе пышной и пахучей," +
            "Нежась, спит блестящий жук;"+
            "А из камней вытекая," +
            "Однозвучен и гремуч," +
            "Говорит, не умолкая," +
            "И поет нагорный ключ.<5 spaces>");
    }

    private static void testStringRow(String str) {

        str.lines()
            .map(l -> l.strip())
            .forEach(System.out::println);

        str.lines().forEach(System.out::println);

        str.lines()
            .map(l -> l.trim())
            .forEach(System.out::println);
    }
}


Скажите, какой будет результат вывода в консоль?
Дальше
Проверить
Узнать результат
Не отчаивайтесь. Даже если вы только начинаете работать с Java, у вас есть все, чтобы стать классным специалистом. Например, в компании EPAM много возможностей для профессионального роста. ИТ-специалисты, которые хотят проработать свои навыки или освоить новые направления, ждут в тренинг-центре EPAM . И это может быть как раз то, что нужно для обучения и развития.
Пройти заново
Очень неплохо, но есть куда расти! Приходите работать в EPAM — здесь вы прокачаете свои профессиональные скиллы. В компании много возможностей для обучения: тренинг-центр для начинающих, курсы для сотрудников всех уровней, программы менторинга, обучение английскому прямо в офисе. Онлайн доступно более 5000 курсов.
Пройти заново
Вау! Наверное, вы сеньор? Но чем больше мы растем и развиваемся, тем большие перспективы открываются впереди. Вы нужны EPAM, а EPAM нужен вам — здесь вы сможете стать менеджером проектов, архитектором решений или крутым экспертом, который известен не только в компании, но и во всей отрасли. Компания может предложить пять карьерных путей, причем двигаться можно и вертикально, и горизонтально, меняя специализацию.
Пройти заново

Комментарии 37

    +7
    5/13 при рандомном ответе. Есть куда работать в тестах.

    Читать портянки невозможно.
    Читать ответы еще хуже — границ между блоками не видно.
      +4
      C# разработчик. Ответил на 9/13.
        0
        C# разработчик отвечал честно, кроме случаев, когда много буков в вопросах (почти все случаи) — отвечал рандомно. 7/13
        0
        Тоже 5/13 при случайном прохождении. Хотя на Гослинга ткнул осознанно.
          0

          Там по 3 ответа на вопрос: вероятность угадать правильный ответ 33%.
          Если я верно помню теорию вероятностей, то 5 из 13 нам даёт 38.5% от правильных ответов что согласуется с вероятностью их просто угадать.
          Если же прикладывать усилия, как у других комментаторов, то легко можно набрать и больше.

            +2
            В том и дело, что вариантов должно быть чуть больше, но при этом они не должны требовать по полчаса на чтение каждого в поисках разницы в два пробела.
              +3
              Думаю, главный звоночек не в том, какой результат, а в том, что у многих людей, которые зашли с желанием пройти тест, это желание пропало на полпути.
              0
              отвечал рандомно. так же 5
              +4
              Я конечно в java толком никогда ничего не писал, но даже мне отсюда видно что с последним вопросом что то не так.
                +1

                Это намек — не ждите адекватных ТЗ.
                8/13. Зачем мне знать историю, создателей и эндорсеров языка по именам — ума не приложу.

                  0
                  Чтобы тест был нескучным (см. заголовок)
                  0
                  Мне показалось, или там идентичные ответы 2 и 3? Или у меня с внимательностью что-то не то?
                    0
                    Не показалось, там все 6 строчек символ в символ одинаковые.
                      0

                      Насколько я понял, авторы не смогли преодолеть тот же встроенный в хабр trim() при публикации данного теста, поэтому варианты вышли одинаковые. Хоть бы в кавычках сделали чтоли ...

                        0
                        Добавили <Xspaces/> чтобы было понятно сколько же пробелов остается в результате.
                  +3
                  Ради любопытства тыкнул:
                  — Первые вопросы вы можете загуглить самостоятельно
                  — Вагон жирного текста
                  — Омерзительная типографика
                  — Код без подсветки
                  — Вертска на отвали
                  — Сомнительные картинки между вопросом и вариантами

                  Итого: простите, вы нам не подходите

                  ЗЫ «опяяять»
                  ЗЫЗЫ прокликал до последнего вопроса, на нем задержался. Господа, шлифаните текст регекспом \W, а то что там написано просто в утиль, не читая и уж тем более не запуская)
                    0
                    8/13, вопросы с кодом наобум.
                    Надо просто больше вариантов ответов давать.
                      +3

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

                        0
                        9/13, но блин! Как же тяжело читать. Если бы не любопытство, бросил бы на третьем вопросе. Обычно любименькая IDE делает модненькую расцветку, где не надо тратить дополнительное время на вчитывание. И даже не знаю что посоветовать, обычно у каждого расцветка своя.
                        P.s. С java в последний раз работал наверное в 2009-ом.
                          0
                          PS: А с чем сейчас работаешь?
                            0
                            Objective-c, swift.
                              0
                              iOS? Если предыдущие опыт был с Java, это был кровавый энтерпрайз или Android? Что, по ощущениям, приятнее и понятнее?
                                0
                                Да. Опыт перехода был почти 10 лет назад. Некоторые нюансы перехода могли забыться. Вроде как особыхпроблем не было. А так, помню как с ребятами ходили и обсуждали: этот objective-c ерунда, а вот Java… :)
                                  0
                                  Я помню страшные баттлы типа windows vs linux. Не знаю, зачем все это было нужно, но было. Сейчас уже пришло понимание, что у каждого инструмента свое назначение и лучше брать то, что лучше подходит, а не то, что у соседа.
                                    0
                                    Сейчас уже пришло понимание, что у каждого инструмента свое назначение и лучше брать то, что лучше подходит, а не то, что у соседа.

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

                                    0

                                    На ObjC действительно смотришь как на НЛО, пока не попробуешь его понажимать руками. Оказывается — очень выразительный инструмент. На голову выше чистого Си.

                            +2

                            Ответ в задаче про стримы неправильный.


                            Скрытый текст
                            public Set<String> findLengthyMelodiesNew(List<Album> albums) {
                                return albums.stream()
                                    .flatMap(album -> album.getMelodies())
                                    .filter(melody -> melody.getLength() > 120)
                                    .map(melody -> melody.getName())
                                    .collect(toSet());
                            }

                            Если при рефакторинге классы не менялись так, чтобы getMelodies() возвращал Stream, то этот код не скомпилируется, т.к. flatMap() требует чтобы функция возвращала Stream, а здесь она вернет List или другую коллекцию. Про правки класса в условии задачи ничего нет, да и вообще — возвращать стримы из геттеров это мягко говоря не самая распространённая практика. Тест же утверждает что правильный ответ — скомпилируется и будет работать.


                            Более того, getMelodies() не мог изначально возвращать Stream т.к. в первом куске кода результат getMelodies() используется в for, что не скомпилируется для стримов (они не Iterable => нельзя foreach).


                            Чтобы скомпилировалось, нужно явно вызвать stream() на результате getMelodies():


                                    .flatMap(album -> album.getMelodies().stream())
                              0

                              Вопрос 3 предполагает активное использование com.google.common.collect.AbstractTable из библиотеки Google Guava, иначе для ответа придётся обратиться к документации или любимой среде разработки.


                              Интересно что класс для 12 вопроса называется Q13, а для 13 — Q14. Изначально было 14 вопросов?


                              Ну и про стримы там выше уже написали.

                                0
                                10/13
                                  0
                                  Отличный результат!
                                  0

                                  Вы это серьезно?

                                    –1
                                    В компании решили перейти на 8 версию Java

                                    ...


                                    Денис любил играть на гитаре, поэтому его сделали ответственным

                                    Да вы просто компания мечты-2019 с адекватными управленческими решениями!
                                    За var в production-коде вообще убивать надо.

                                      0

                                      Почему бы не начать использовать var в production-тестах?

                                        –1

                                        Если по-быстрому что-то накидать в блокноте, запустить один раз и выкинуть, то можно и var.


                                        Если же в долгоживущем коде, даже в тех же тестах, то зачем?
                                        Читаемость это ухудшает, здесь это как раз отлично было продемонстрировано, а плюсов по сравнению с «набрать .var и нажать Tab в IDEA» — никаких.

                                          0
                                          var, думаю, есть смысл писать, если справа полный тип указан через new, либо при итерации по коллекции, которая определена с полным описанием типа в рамках того же экрана (5-10 строчек выше максимум). В остальном за var стоит обламывать руки, ибо без IDE очень сложно понять, по чему итерируешься.
                                      +1
                                      11/13 ответил честно.
                                        0

                                        Поздравляю, отличный результат!

                                      Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.