Может кому‑то это будет интересно, даст возможность лучше подготовиться; или наоборот кто‑то примет решение не участвовать.
Угораздило меня согласиться на т. н. «Weekend Offer на позицию разработчика на Kotlin». Вообще‑то мне больше нравится Scala, и опыта по ней больше, но рекрутерша была сильно настойчива, и я решил обновить экспиренс собесов, а возможно и получить прибавку в деньгах при переходе.
Коротко о себе: 41 год, senior software developer, стаж > 20 лет.
Два алгоритмических этапа по сути были одинаковыми, неясно, почему их два и зачем вообще предлагается готовиться к собеседованию через т. н. «Cоревнования», то есть площадку спортивного программирования а‑ля leetcode, где результат проверяет робот и можно пользоваться IDE. Нормально готовиться мне было лень, но за часок до собеса я спохватился и прорешал несколько задачек, что смог найти:
fun main() {
//1
/*
Даны две строки строчных латинских символов: строка J и строка S.
Символы, входящие в строку J, — «драгоценности», входящие в строку S — «камни».
Нужно определить, какое количество символов из S одновременно являются «драгоценностями».
Проще говоря, нужно проверить, какое количество символов из S входит в J.
*/
val regime:String? = null
if (regime?.let {it == "1"} ?: true ){
val j = "fgsdfdhdfhhgfn"
val s = "sdfgsdfdvsdawerfgsfvsrtsgvnfsdgdffgsergrfdbjsrht"
val set = j.toSet()
val count = s.filter { j.contains(it) }.length
println("1. count=$count")
}
//2
/*
Требуется найти в бинарном векторе самую длинную последовательность
единиц и вывести её длину.
*/
if (regime?.let {it == "2"} ?: true ) {
val s = "0101010001000100011101000111110001111111111111110001111111111111111111"
var count =0
var maxx=0
for (el in s) {
if (el == '1') {
count += 1
if (count>maxx) maxx = count
} else {
count = 0
}
}
println("2. count=$maxx")
}
//3
/*
Дан упорядоченный по неубыванию массив целых 32-разрядных чисел.
Требуется удалить из него все повторения.
*/
if (regime?.let {it == "3"} ?: true ) {
val a = arrayListOf(1,2,3,4,5,6,7,7,7,7,8,9,10,10,10,10,10,10)
var last:Int = 0
var i =0
while (i < a.size) {
if (i==0) {
last = a[i]
i ++
} else if (a[i]==last){
a.removeAt(i)
} else {
last = a[i]
i ++
}
}
println("3. $a")
}
//4
/*
Генерация скобочных последовательностей
Дано целое число n. Требуется вывести все правильные скобочные последовательности
длины 2 ⋅ n, упорядоченные лексикографически.
В задаче используются только круглые скобки.
Желательно получить решение, которое работает за время,
пропорциональное общему количеству правильных скобочных последовательностей в ответе, и при этом использует объём памяти, пропорциональный n.
*/
if (regime?.let {it == "4"} ?: true ) {
val n =4
val res = mutableListOf<String>()
fun add(start:String){
val o = start.count { it == '('}
val c = start.count { it == ')'}
if (o == c && start.length == 2*n) {res += start}
else {
if (o - c < 2 * n - start.length) {
add(start + '(')
}
if (o > c) {
add(start + ')')
}
}
}
add("")
println("4. $res")
}
// ...
}
Внимание! Код заведомо не идеален, улучшения типа О(N^2), переделку рекурсии на концевую и т.п. можно обсудить в комментариях.
Но писал я это, разумеется, в IDE и там же отлаживался.
А здесь кодить предлагается, в неком онлайн блокноте, без проверки ошибок и отладки, для всех, кто пользуется IDE это будет стресс, и почему не дать ей пользоваться — загадка.
т. е. если (когда) будет допущена ошибка по небрежности и IDE ее не подсветит, благосклонный интерьюер просто подскажет/исправит ее за тебя, а негативный будет ходить вокруг да около, пока ты сам не найдешь ошибку (или закончится время).
Отправить решение на тест может только интервьюер, когда сам захочет, например за 1 мин. до окончания, и в итоге просто завалит кандидата, если оно не заведется из‑за ошибки.
Тем не менее, задачи довольно легкие, на мой взгляд, из заслуживающего внимания — рекурсивный обход дерева в глубину, по памяти:
Дано бинарное дерево с буквами в вершинах.
Вывести любые одинаковые вершины, критерий одинаковости — множество букв в вершине и под ней совпадают.
Код не сохранил, но он очень короткий, нужно при рекурсивном обходе сохранять вершины в мапу, где ключ — Set вершин.
Ну ок, прошел я эти алгосекции якобы успешно.
Архитектурный этап — это вообще нечто.
Он выбился за выходные и был посреди напряженного рабочего дня, т. е. название мероприятия «Weekend Offer», в общем‑то бессмысленное.
Ок, я выкроил время.
И это кстати единственное собеседование, к которому я готовится +‑ серьезно, потому что уже было жаль времени на предыдущие этапы (ну как готовился — перечитывал книгу с Клеппмана «с кабаном», и еще «System Design Подготовка к сложному интервью»).
Ставится абсолютно абстрактная задача, оторванная напрочь от реальности, причем она устно (!) проговаривается наполовину или меньше, а вторую половину кандидат должен клещами вытягивать из интервьюера, и не дай бог что‑то забыть спросить и потом оно всплывет, интервьюер отметит это с интонаций «ну ты тупой, умный бы сразу это спросил, а не через 15 мин».
Так ты напиши функциональные и не функциональные требования текстом! А уж прочитав, я буду на базе этого какого‑никакого документа давать решение...
Но все‑таки, на кого я собеседуюсь? Вроде не на аналитика, или на архитектора, на сеньора/руководителя группы разработки же?..
Кстати в этой устной постановке я на 100% уверен, что звучало слово «веб‑приложение», от которого интервьюер позже открестился. Фактически, он имеет возможность точно также отказаться и от всего остального и завернуть любого кандидата. Вообще‑то он параллельно занимался своими делами, так что мог сам и забыть что говорил; сложилось такое впечатление, что условия генерились на ходу с потолка.
Ну ок, пришли к какому‑то решению, которое в теории может заработать, вычислили целевые показатели и узкие места архитектуры, на базе этих дурацких параметров придуманных интервьюером экспромтом (1 млн. юзеров, 1млн. источников и т. п.), и применительно к реальному оборудованию посчитали сколько надо серверов, с каким резервированием и т. п. Причем эти бессмысленные расчеты я делал, по запросу интервьюера, а мог бы в это время выявить какие‑то проблемы и улучшить архитектуру.
В итоге на конец собеседования имеем вроде бы рабочий вариант архитектуры, с чем формально соглашается интервьюер.
Далее, через целые сутки (а на кодинге было почти сразу) приходит «обратная связь», что архитектуру я не прошел, и вообще никаких пояснений что не так в моем решении, какой эталонный путь прохождения и т. п., вообще 0. У меня тоже идей 0, был полностью уверен что прошел.
Возможно, просто рожа не понравилась.
Какие материалы мне изучить, какие скиллы тренировать?..
«System Design Подготовка к сложному интервью», неплохая в общем‑то книга, но тут она не поможет, потому что сложности в интервью особо нет, распределить с схемке выдуманную нагрузку по серверам это не сложность (а книг «Подготовка к дурацким интервью» на рынке пока не видел).

Известная «Книжка с кабаном», тоже не особо содержит способы прохождения такого «этапа», т.к. там нужны абстрактные, а не конкретные проверенные решения от успешных компаний. Когда я пытался переходить к конкретным названиям ПО, интервьюер одергивал меня.
т. е. надо говорить «какой‑то L7 балансировщик», «какая‑то база Key‑value», «какой‑то брокер сообщений или шина».

Короче говоря, из того что я прочел за 20 лет по данной тематике эти две лучшие, и как бы там ни было, с другим интервьюером или в другой компании они могут пригодиться.
Что дальше? Рекрутер предлагает попробовать еще через полгода (!).
А что должно измениться, если я не понимаю ни смысла «проваленного» интервью, ни путей улучшения, чего не хватило?..
Ладно еще кодинг, но приходится констатировать, что с архитектурой вообще субъективизм чистой воды.
Бессмысленность предложения с пол. года еще и в том, что нетрудоустроенный человек (это ладно я пока работаю), очевидно, должен будет брать где‑то средства, т. е. он заведомо уже согласится на офер в какой‑то другой компании и примерно к этому моменту кое‑как там обучится и адаптируется, и тут рекрутер Яндекса опять радостно постучится к нему — не хотите ли попытать счастья еще? И в случае успеха, получив от нас офер, кинуть ту компанию, где вы устроились, на вас потрачено время и теперь от вас ждут отдачи!
Я читал про подобные этим правила в некоторых крупных компаниях (еще бывает, год для круглого счета используют), и абсолютно уверен, что такое «окно возможности» проходить собеседования придумал 1 ленивый HR в условном Google, который устал, что ему несколько раз пришлось отрабатывать одного кандидата. После чего назначил ему какой‑то срок, а с тех пор остальные, как обезьяны, повторяют и считают это best practice.
Ребята, вы не аттестационная комиссия из академиков в ВУЗе, вас не надо собирать из разных организаций на защиту дипломников или диссертантов! Вы же просто, в рабочем порядке, ковыряя в носу, пытаетесь кого‑то нанять чтоб он вам условно стену из камней сложил за деньги, так откуда столько пафоса? )
P. S.Далее на почту приходит анкета и там вопрос — «а вы порекомендуете кому‑либо устраиваться работать в Яндекс?»
Вот как я могу рекомендовать идти куда‑то, если я в этом месте не был? Вы в своем уме? Что должно случиться с человеком на собеседовании, чтобы не пройдя его, он начал активно рекомендовать устраиваться в эту контору своим знакомым?..
В общем, мое впечатление. Как и во многих крупных компаниях, в Яше собрались неплохие, в общем‑то люди, каждый по отдельности умный и грамотный, а все вместе они посмотрели кино про Гугл и придумали странные игры с нелогичными правилами типа «игра в классики, но на граблях», по которым скачут сами и заставляют скакать других.
Напоминаю про смысл таких длинных многораундных собеседований — психологически кандидат придает большую ценность той компании (при прочих равных), на которую потратил максимум времени и стараний, а по ходу процесса у него падает самооценка и слетает корона, т. е. совмещается полезное с приятным — получаем более сговорчивого кандидата, который в состоянии потери согласиться на меньшие деньги.
Всем удачи и хорошего настроения!