Привет! Особенно @kesn сейчас расскажу почему!

Ко мне в телеграмм постучалась очень приветливая и милая девушка HR из Яндекса, с предложением о работе. Я очень обрадовалась, особенно потому, что рынок IT в 2023 очень нестандартный :-)

Созвонились на 15 минут, мне рассказали об этапах - три алгоритмических интервью, по две задачи в течение часа, третье - с независимым экспертом Яндекса и на целых 1,5 часа. Скинули ссылки на leetcode, CodeRun, пара видео с разбором задачек на доске с фломастером и статья Яндекса о том, как они нанимают бэкэнд разработчиков.

Я просмотрела эти материалы и достаточно быстро нашла статью. Хм, интересно! Изначально у меня не было высоких ожиданий относительно интервью, у меня двухлетний опыт Java разработки, и нет идей как алгоритмический live-coding в три этапа поможет вычленить нужного проекту кандидата. И да, я не готовилась.

Интервью 1. Очень приятный молодой человек, прекрасно вел интервью и поддерживал, так как видел мое волнение. 

Задача 1

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

Input: s = "eceba", k = 2

Output: 3

Решение:

public class Main {

    public static void main(String[] args) {

        String s = "eceba";

        int k = 2;

        System.out.println(lengthOfLongestSubstringKDistinct(s, k));

    }

    public static int lengthOfLongestSubstringKDistinct(String s, int k) {

        if (k == 0 || s == null || s.length() == 0) {

            return 0;

        }

        if (s.length() < k) {

            return s.length();

        }

        Map<Character, Integer> map = new HashMap<>();

        int left = 0;

        int max = 1;

        for (int right = 0; right < s.length(); right++) {

            char c = s.charAt(right);

            map.put(c, map.getOrDefault(c, 0) + 1);

            while (map.size() > k) {

                char leftChar = s.charAt(left);

                if (map.containsKey(leftChar)) {

                    map.put(leftChar, map.get(leftChar) - 1);

                    if (map.get(leftChar) == 0) {

                        map.remove(leftChar);

                    }

                }

                left++;

            }

            max = Math.max(max, right - left + 1);

        }

        return max;

    }

}

Окей!

Ожидаю вторую, я осведомлена о потоке задач, который должен на меня свалиться. Но вау! Второй задачи на первом интервью нет! Как воодушевляет! Вместо этого интервьюер задавал вопросы про работу HashMap, TreeMap, его вращение, потокобезопасность, ну круто!

Интервью 2. Еще более молодой и такой же приятный человек начинает интервью. 

Задача 1

Перенести нули в конец массива, сохранив порядок остальных элементов

[1,0,8,9] → [1,8,9,0]

Решение:

public class Main {

    public static void main(String[] args) {

        int[] nums = {1, 0, 8, 9};

        moveZeroes(nums);

        for (int i : nums) {

            System.out.print(i + " ");

        }

    }

    public static void moveZeroes(int[] nums) {

        if (nums == null || nums.length == 0) return;

        int insertPos = 0;

        for (int num: nums) {

            if (num != 0) {

                nums[insertPos++] = num;

            }

        }        

        while (insertPos < nums.length) {

            nums[insertPos++] = 0;

        }

    }

}

Задача 2

Дан массив из нулей и единиц. Нужно определить, какой максимальный по длине подинтервал единиц можно получить, удалив ровно один элемент массива.

[1, 1, 0]

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

Решение:

class Main {

    public static void main(String[] args) {

        int[] arr = {1, 1, 0};

        System.out.println(maxOnesAfterRemoveItem(arr));

    }

    static int maxOnesAfterRemoveItem(int[] arr) {

        List<int[]> ones = new ArrayList<>();  

        List<Integer> zeros = new ArrayList<>(); 

        int n = arr.length;

        int l = 0;

        for (int r = 0; r < n; r++) {

            if (arr[r] == 0) {

                ones.add(new int[]{l, r});

                zeros.add(r);

                l = r + 1;

            }

        }

        ones.add(new int[]{l, n});

        int maxOnes = 0;

        for (int i = 0; i < zeros.size(); i++) {

            int onesBefore = ones.get(i)[1] - ones.get(i)[0];

            int onesAfter = ones.get(i + 1)[1] - ones.get(i + 1)[0];

            maxOnes = Math.max(maxOnes, onesBefore + onesAfter);

        }

        return maxOnes;

    }

}

После этого интервью я решила посмотреть откуда генерируют задачки и была невероятно удивлена, что они уже встречались пару лет назад. Как-то странно, это же первая ссылка по запросу “Собеседование Яндекс”. Окей, думаю случайность, продолжу не готовится! 

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

Интервью 3. Независимый эксперт очень суров и непреклонен, никакой вежливости, только хард скиллы!

Задача 1

Дан отсортированный массив чисел а, индекс элемента index и целое число k. Необходимо вернуть в любом порядке k чисел из массива, которые являются ближайшими по значению к элементу а[index].

find_k_closest(a={2,3,5,7,11}, index=3, k=2) -> {5,7}

find_k_closest(a={4,12,15,15,24}, index=1, k=3) -> {12,15,15}

find_k_closest(a={2,3,5,7,11}, index=2, k=2) -> {5,7} или {3,5}

Решение:

 public static List<Integer> findKClosest(int[] a, int index, int k) {

        int left = index - 1; 

        int right = index + 1; 

        List<Integer> result = new ArrayList<>();

        result.add(a[index]); 

        if (k == 0) {

            return result; 

        }

        result.add(a[index]);

        k--;

        while(k-- > 1) {

            if(left < 0) { 

                result.add(a[right++]);

            } else if(right >= a.length) { 

                result.add(a[left--]);

            } else if(Math.abs(a[left] - a[index]) <= Math.abs(a[right] - a[index])) { 

                result.add(a[left--]);

            } else { 

                result.add(a[right++]);

            }

        }

        return result;

    }

}

Задача 2

Дан массив точек с целочисленными координатами (x,y). Определить, существует ли вертикальная прямая, делящая все точки, не лежащие на ней, на 2 симметрических относительно этой прямой набора точек. Наборы симметричны когда каждая точка исходного массива имеет пару из другого набора.

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

Решение:

class Point {

    int x;

    int y;

    Point(int x, int y) {

        this.x = x;

        this.y = y;

    }

    @Override

    public boolean equals(Object o) {

        if (this == o) return true;

        if (o == null || getClass() != o.getClass()) return false;

        Point point = (Point) o;

        return x == point.x && y == point.y;

    }

    @Override

    public int hashCode() {

        return Objects.hash(x, y);

    }

}

public class Main {

    public static void main(String[] args) {

        Point[] points = {new Point(1, 1), new Point(2, 2), new Point(-1, 1), new Point(-2, 2)};

        System.out.println(hasSymmetry(points)); // true

    }

    public static boolean hasSymmetry(Point[] points) {

        int sumX = 0;

        Set<Point> pointSet = new HashSet<>();

        for (Point point : points) {

            sumX += point.x;

            pointSet.add(point);

        }

        double avgX = 1.0 * sumX / points.length;

        for (Point point : points) {

            int symX = (int) (2 * avgX - point.x);

            if (!pointSet.contains(new Point(symX, point.y))) {

                return false;

            }

        }

        return true;

    }

}

После последнего интервью я снова проверила откуда задачи. Вау, это не случайность.

Мои наблюдения вдобавок к тем выводам, что сделал @kesn

  1. Ну, очевидно, количество задач уменьшилось, первый собес так вообще очень вдохновлял той частью с фундаментальными вопросами;

  2. Появился независимый эксперт, хотя я не поняла, в чем разница, кроме той, что он был визуально строг. Для меня это было самое спокойное интервью, потому что давали много тишины и спокойствия, при этом не теряя вовлеченности в процесс;

  3. Яндекс повторяется в задачах, даже если они разобраны на Хабре. С чем это может быть связано и как аффектится на найм - оставлю эти и другие вопросы на рефлексию каждому!

Комментарии (21)


  1. solaris_n
    31.10.2024 10:22

    Кто-то ещё в Яндекс идёт?


    1. WLMike
      31.10.2024 10:22

      Конечно. Согласно публичным отчетам рост численности работников за год около 30%


    1. mostodont32
      31.10.2024 10:22

      А ты какие компании на рынке РФ предлагаешь?


      1. vanxant
        31.10.2024 10:22

        sorry, мимо


  1. CyberDrony
    31.10.2024 10:22

    Ну вот! Спалила тему! ))


  1. litalen
    31.10.2024 10:22

    я очень обрадовалась

    Я просмотрела

    Автор: JShipov

    Хм.


    1. dmitrijtest24
      31.10.2024 10:22

      https://github.com/JShipov вроде как, Лиля


      1. XRain
        31.10.2024 10:22

        Юлия, не Лиля


  1. Px2
    31.10.2024 10:22

    И зачем это все? Вопрос риторический, но всё же.

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


    1. gudvinr
      31.10.2024 10:22

      И зачем это все? Вопрос риторический, но всё же.

      1. Могут себе позволить отсеять хороших разработчиков, т.к. поток большой

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

      Это не оправдание яндекса, потому что процесс найма ужасный. Пока ты все этапы пройдешь, в других местах тебе уже офферов накидают.

      Вероятно, это можно сделать иначе и без насилия над разработчиком, но т.к. поток людей большой, то так проще и работает приемлемо.

      Из заголовка могло показаться, что в процессах что-то изменилось и статья именно об этом, но оказалось что не поменялось ничего.

      Если ты бэкендер на джаве и не умеешь работать с Кафкой и Кубером, то будь хоть чемпионом Литкода, работу не получишь

      Ну зачем такая дихотомия? Это ведь не исключает друг друга. Можно быть и чемпионом литкода и уметь работать с кафкой и кубером. Плюс в некоторых областях кафки или кубера может и не быть. Может быть не на джаве, но всё же.


    1. alek0585
      31.10.2024 10:22

      Если ты бэкендер на джаве и не умеешь работать с Кафкой и Кубером, то будь хоть чемпионом Литкода, работу не получишь

      Сразу скипаю вакансии, где пишут про конкретный стек и ищут code-monkey под него, а не разработчика, который в принципе всегда сталкивается с чем-то новым. А это новая мода на бекендера вешать задачи девопса, но не добавлять к зп... Какой-то совиный грипп что ли?


    1. TheKnight
      31.10.2024 10:22

      Мне пригодился бы хороший программист на Java, даже если он не умеет работать с Кафкой и Кубером.
      На моем проекте их все равно нет, да и не нужны они в разработке плагинов для IDE.


  1. Nanosek
    31.10.2024 10:22

    Уже никто из уважающих себя разработчиков не идет работать в яндекс. А что там делать? Зп низкие, а требования очень высокие, при этом работать там надо на 200%. Тот яндекс который когда то был, куда все хотели попасть ради отметки в трудовой, что ты работал в Яндексе, после чего тебе все двери были открыты, такого уже давно нет.

    Мне они постоянно спамят во все мессенджеры, с предложениями по работе, отказов не понимают, даже грубых. Что говорит о явном дефиците кадров.


    1. mostodont32
      31.10.2024 10:22

      Если тебе хорошую зарплату не предложили, мб дело в тебе, а не в Яндексе?:)


  1. panzerfaust
    31.10.2024 10:22

    На литкоде такой замечательный банк задач по SQL. И SQL - это, блин, реальность, с которой каждый бэкендер столкнется. Но нет, давайте до посинения считать подстроки в строках.


  1. 40kTons
    31.10.2024 10:22

    Последняя задача ввела в ступор конечно, ибо не любитель геометрии. Точки из набора имеют целочисленные координаты. Окей. А прямая должна иметь целочисленные координаты? Вертикальная, значит, нас интересует только x что бы задать прямую. Окей. Симметричные точки относительно прямой это как? Мол, если на прямой есть коориданата (x, y), то симметричные ей точки это (x + a, y) и (x - a, y)? Нууу, вот так сразу вообще ничего в голову не приходит как её даже теоретически можно начать решать. Кажется, что x нас очень интересует. Можно попробовать отсортировать набор точек по координате x, поскольку ищем симметричный набор точек, то таких точек будет чётное количество, значит, надо взять среднеарифметическое двух центральных точек из отсортированного массива, провести через эту среднюю точку вертикальную линию, и от этой линии влево и вправо сравнивать точки. Если они не симметричны, то набор не симметричен. Если дошли до конца, значит, набор симметричен. Может я в чём то ошибаюсь


  1. Nelman86
    31.10.2024 10:22

    Ко мне в телеграмм постучалась очень приветливая и милая девушка HR из Яндекса, с предложением о работе.

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


  1. mysherocker
    31.10.2024 10:22

    независимый эксперт, хотя я не поняла, в чем разница, кроме той, что он был визуально строг

    Это не "независимый эксперт". Это проверяющий собеседующий. Задача про вертикальную ось симметрии как раз из небольшого набора задач, которые они дают.

    Суть секции с ним -- поддерживание минимальной планки нанимаемых разработчиков (а не подъём средней, как устроено с институтом bar raiser в Amazon). Провал этой секции -- гарантированный провал всего собеседования, даже если все остальные секции прошли хорошо, покуда проверающий собеседующий имеет право вето.

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

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

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