Комментарии 343
Куда, если не секрет, получили оффер?
позиция какого уровня?
PS — это про Амазон или вообще?
Тогда микрософт, судя по предыдущим комментариям в ветке? :)
Но я-то спрашивал, что автор предыдущего комментария имеет в виду, потому, что что в том же NYC спокойно можно получать как раз эти 200-300к, при этом не особо сильно убиваясь, а вот Амазон как раз вроде как известен тем, что плата у них не сказать чтоб топовая. Поэтому в то, что 200-300к в амазоне — влажные мечты, я вполне верю, а что это влажные мечты, ну, вообще — неа.
А вот меня спрашивали про теннисные мячики, количество канализационных люков на определенной улице и также количество машин на отрезке дороги в час пик. Такие интервьюверы порой сами не далёкие люди, особенно когда с листка зачитывают, всю эту ересь.
Месяцев 7-8 назад в Google. Позиция связанная с Анализированием поисковых запросов. Локация Техас.
В условных "ООО рога и копыта" верстальщику формочек — возможно это и не надо. А в FAANG такие алгоритмические задачи возникают в процессе работы. Вот, недавняя статья от яндекса приводит несколько примеров практически задач с собеседования, которые возникли в процессе нормальной обычной работы. Я сам в одной из FAANG компаний задаю на интервью именно ту задачу, которую решал во время работы. И там и про ассимптотику спросить можно и динамическое программирование написать в качестве хорошего решения.
Да, это происходит не каждый день, но когда оно происходит, то алгоритмические знания и умение решать алгоритмические задачи действительно нужны.
Добавьте к этому, что большим компаниям нужны стандартизованные, объективные критерии, как можно лучше коррелирующие с качеством нанимаемого программиста, которые можно оценить на интервью, и получится, что алгоритмические задачи — весьма неплохой вариант.
Какие есть альтернативы? Испытательный срок — дорого и не скейлится. Поговорить о жизни/что вы думаете по поводу технологии X — не формализуется и легко проходится теми у кого язык хорошо подвешан, даже если они писать код не могут вообще. Смотреть код с гитхаба — не у всех он есть, да и невозможно проверить, что этот код кандидат сможет воспроизвести. Тестовое задание — те же алгоритмические задачки, но тратит больше ресурсов и кандидата и компании, да и читерить на них могут запросто.
Но если кандидат решил алгоритмическую задачу, написал вменяемый код — значит он способен, во первых, вменяемый код писать, и писать достаточно быстро; он способен мыслить абстрактно и, когда сложная задача возникнет в процессе работы, он сможет ее решить, или хотя бы поймет, что тут не надо делать "пирамидку из for" и спросит помощи. В противном случае даже мысли не возникнет о том, что тут есть какое-то более элегантное, на порядки быстрее и короче решение.
Тестовое задание — те же алгоритмические задачки, но тратит больше ресурсов и кандидата и компании, да и читерить на них могут запросто.
Судя по этой статье, тестовое задание требует меньше ресурсов кандидата, чем алгоритмические задачи: на тестовое задание я могу убить неделю (вечерами после работы), если настроение будет, а решать leetcode по таймеру месяц я не буду.
Тут нельзя так однобоко считать. Leetcode вы один раз в жизни порешали месяц и потом перед каждым интервью один день повторили, а тестовое задание вам при каждом интервью придется делать неделю. 4 интервью — и вы уже суммарно больше времени на тестовые потратили.
Потом, это от человека зависит. Если computer science курс какой-то был, то месяц вам не понадобится — пару недель максимум.
тестовое задание вам при каждом интервью придется делать неделю
Тестовые бывают на полную рабочую неделю, но не так часто.
Насчёт сроков по Leetcode не соглашусь. Если не было опыта спортивного программирования, то за две недели подготовиться будет очень сложно. Подтверждение тому множество статей, подобные этой, а также истории кандидатов с Leetcode.
Leetcode вы один раз в жизни порешали месяц и потом перед каждым интервью один день повторили
Переносимость действительно работает и сухой остаток от решения задач есть, но без повторения уровень понемногу снижается.
Leetcode вы один раз в жизни порешали месяц и потом перед каждым интервью один день повторилиОдин раз в жизни. Ну, ну)
Может вы сможете сдать практически без подготовки ГОСы и любой экзамен, который сдавали в прошлом? Еще и с той же скоростью.
Людям свойственно забывать то, чем они не пользуются. Если на работе сложные алгоритмические задачи приходится решать реже раза в месяц, то перед собеседованием на новую работу снова придется месяц решать задачи из Leetcode.
Что касается поиска работы, то в идеале перед каждым новым поиском работы надо месяц порешать алгоритмы, месяц повторить и зазубрить теорию (вроде тонкостей языка, которые в работе не используешь), месяц поизучать то, что актуально на рынке, но что в работе ты не используешь, месяц походить на собеседования для тренировки, чтобы прокачать навык прохождения собеседований. После этого можно рассчитывать устроиться на ту же должность или выше в другую компанию. Итого, 4 месяца получилось. В итоге на новой работе большинство из изученного/повторенного окажется не нужным и через n лет при смене работы снова все это учить/повторять. Но можно сократить раза в 2 длительность подготовки, отсеяв 90% компаний, где собеседующий требует написать алгоритм на листочке, или перечислить, какие методы есть у стандартного класса Object, или спрашивающий, что выдаст [] + {}.
Насчет алгоритмов, добавлю еще, что программист первокурсник уделает по скорости решения алгоритмических задач практически любого программиста последнего курса. А тот уделает в этом практически любого сеньора. Т.к. все зависит от того, как часто приходится писать алгоритмы. Студенты, особенно на первых курсах, этим занимаются чаще.
В итоге на новой работе большинство из изученного/повторенного окажется не нужным и через n лет при смене работы снова все это учить/повторять.
И так почти на каждой работе. И я вот тоже не понимаю смысла в этом.
Да, я понимаю, если спрашивают то, с чем постоянно работаешь. Это нормально, это действительно понадобиться. На деле же много чего из спрашиваемого не нужно. Но мы же будем спрашивать и отсеивать тех, кто не знает.
первокурсник уделает по скорости решения алгоритмических задач практически любого программиста последнего курса. А тот уделает в этом практически любого сеньора.
Ну, если сеньор не может за 25 минут написать решение для "найдите длину наибольшего отрезка из единиц в массиве заполненном нулями и единицами", даже с подсказками, то грош цена такому сеньору.
Ну, вы почитайте саму статью, что привели и процитированные там комментарии с quora. Сам автор homebrew говорит, что его в твите не поняли, и наверно честно, что его не приняли в гугл. Там куча ответов вида, что чуваку надо было идти на PM, а не SWE.
Создание хоть и популярного и очень полезного продукта не говорит, что чувак крутой программист. У гугла реально возникает потребность инвертировать деревья или что-то подобное. А homebrew — не то что бы слишком сложный продукт.
Создание хоть и популярного и очень полезного продукта не говорит, что чувак крутой программист.
А чем по вашему программисты занимаются? Пишут алгоритмы на доске по памяти?
А homebrew — не то что бы слишком сложный продукт.
Только сделали его не вы, а тот чувак, кто не умеет инвертировать деревья.
Да, я не Бойер и не Мур.
Справедливости ради, приведенное решение, конечно, не такое элегантное и работает только если исходный массив можно менять
В условии не говорится, что массив нельзя менять
А как понять какой элемент самый распространённый (чтобы понять, какую половину сортировать), ведь задача и состоит в поиске этого элемента? Если я в курсе что это за элемент я и сортировать ничего не буду.
P.S.
Ничего умнее map<int,int> я не придумаю, да и в целом не буду. На моей памяти ни мне, ни кому-то из тех кого я знаю не потребовалось решать задач, в которых бы понадобились эти знания.
P.P.S.
Я очень рад за тех людей, которые встречаются с такими задачами. Мне обычно приходится решать какие-то более приземленные задачи.
Будет понятнее, если переформулировать решение. Этот самый распространенный элемент обязательно будет и медианой. Потому что в отсортированном массиве он будет занимать отрезок длиннее половины массива. Как этот отрезок не располагай, он будет пересекать середину. А дальше применяется более менее известный QuickSelect для поиска медианы — модификация QuickSort, которая может за O(n) в среднем выдать k-ый элемент.
Тут как в сортировке делается разбиение, а потом запускается рекурсия только в одной половине, в которой находится искомый элемент.
Да собственно даже на простых задачах люди заваливаются. Да и у простой задачи обычно можно придумать усложнение.
Ну, если сеньор не может за 25 минут написать решение для "найдите длину наибольшего отрезка из единиц в массиве заполненном нулями и единицами", даже с подсказками, то грош цена такому сеньору.
Ну, я вот нашел эту задачу на leetcode, написал решение минуты за 3, работает за линейное время, тесты вроде проходит. Значит ли это, что я senior? Да ни разу, в Google меня, боюсь, не возьмут даже в качестве L3 (вообще, куда-то формошлепить под android меня, может быть, даже и взяли на позицию senior, но senior в такой конторке и senior в Google — это, как говорится, две большие разницы). Как минимум, потому что умения решать задачки уровня easy с leetcode для собеседования в Google недостаточно.
Вопрос вам как интервьюверу.
Мне тут на днях написал один знакомый товарищ, который решил стать джаваскриптером, и ему на собеседовании предложили задачу «распечатать 2000-ое число из упорядоченного естественным образом множества { 2i3j5k | i, j, k ∊ ℕ } с таким-то лимитом по временим». Я джаваскрипт не знаю, и как там это делать без упорядоченных структур данных, тоже не знаю. Но мне стало интересно, как бы я решал эту задачу на более других языках.
На хаскеле из-за ленивости лобовое решение пишется за 5 минут вот прям почти по математическому определению:
mergeUniq :: Ord a => [a] -> [a] -> [a]
mergeUniq (x:xs) (y:ys) = case x `compare` y of
EQ -> x : mergeUniq xs ys
LT -> x : mergeUniq xs (y:ys)
GT -> y : mergeUniq (x:xs) ys
powers :: [Integer]
powers = 1 : expand 2 `mergeUniq` expand 3 `mergeUniq` expand 5
where
expand factor = (factor *) <$> powers
Можно заметить, что в степень для сравнения возводить не обязательно, а можно сравнивать логарифмы чисел, выкинув таким образом медленный Integer
(который gmp'шная длинная арифметика под капотом) и ещё минут за 10 улучшить до
mergeUniq :: Ord a => [a] -> [a] -> [a]
mergeUniq (x:xs) (y:ys) = case x `compare` y of
EQ -> x : mergeUniq xs ys
LT -> x : mergeUniq xs (y:ys)
GT -> y : mergeUniq (x:xs) ys
data Power = Power { k2 :: !Int, k3 :: !Int, k5 :: !Int } deriving (Eq, Show)
instance Ord Power where
compare = compare `on` \Power { .. } -> fromIntegral k2 + fromIntegral k3 * l2 + fromIntegral k5 * l5
where
l2 = logBase 2 3
l5 = logBase 2 5
powers :: [Power]
powers = Power 0 0 0 :
fmap (\p -> p { k2 = k2 p + 1 }) powers `mergeUniq`
fmap (\p -> p { k3 = k3 p + 1 }) powers `mergeUniq`
fmap (\p -> p { k5 = k5 p + 1 }) powers
Стомиллионное (а не двухтысячное) число оно считает секунд за 5 и жрёт 28 мегабайт оперативки (оценить сложность формально, э, сложно из-за той же ленивости).
Короче, к чему я это. Ещё ни на одном интервью я не писал код на хаскеле. Как это переложить на плюсы, я сходу не знаю. Понятно, что надо держать срез из чисел от N/5 до (текущего) N, и там когда надо правильно его подчищать, но написать это в работающем виде у меня за полчаса не получится.
Как с этим жить на интервью?
распечатать 2000-ое число из упорядоченного естественным образом множества { 2i3j5k | i, j, k ∊ ℕ } с таким-то лимитом по временим
Перечитал несколько раз и всё равно нифига не понял задачу. :) 2i3j5k | i, j, k ∊ ℕ — это вот как понимать?
Ну вот у вас есть множество чисел, представимых как произведение неотрицательных целых степеней двойки, тройки и пятёрки. На нём можно определить порядок, соответствующий подмножеству привычного нам всем порядка на всех натуральных числах. Нужно отобразить 2000-е число.
Например, первое число (если считать с единицы) — 1, потом 2, потом 3, потом 4, потом 5, 6, 8, 9, 10, 12, 15...
Нет. Возмите все натуральные числа. Выкиньте все, что делятся на что-то кроме 2, 3 или 5. Из отсавшихся возмите 2000-ое число. Число 2000 там останется, но до него будет выкинуто много чисел (7, например). Т.ч. 2000-ое число точно больше 2000.
А что если взять первое число — это 1, и дальше строить ряд, увеличивая на один степень 5 (как максимального числа) и добегая до неё степенями 3, а потом двойки, считая числа в порядке возрастания? Надо проверить, что получается.
Видимо, ошибка в постановке задачи. Если там действительно i,j,k — натуральные числа, то ни 1, ни 2, ни 5 не содержатся в ответе, т.к. любое число должно делится хотя бы по разу и на 2, и на 3, и на 5. Очевидно, там имелось ввиду "неотрицательные целые числа".
Ноль очень разумно приписывать к натуральным числам. Они тогда становятся моноидом по сложению и приобретают целую кучу других приятных алгебраических свойств.
А вот аргументов против нуля я могу придумать ровно, э, ноль.
Я тоже считаю, что так было бы логичнее. Но, если мне не изменяет память, ноль в натуральных числах не значится.
Я не видел ни одной книги, где ноль не был бы натуральным числом.
Мы по терычу учились, и я не помню, чтобы у меня были проблемы с нулём. Хотя да, судя по тексту на с. 7, подразумевается, что ноль не лежит в натуральных числах. Плохо сделали.
Впрочем, да, моя выборка книг — всякие зарубежные по алгебре, теории типов и прочей подобной ерунде.
Есть 2 решения. Одно попроще придумывается и принимается на хорошее знание алгоритмов. Если нет косяков с кодом, то это будет hire от меня. Второе быстрее и элегантнее, но его посложнее придумывать.
Первое решение такое:
Достаточно держать heap из потенциальных следующих элементов.
Изначально кладем туда 1 (видимо, в виде {0, 0, 0, log(2)*0+log(3)*0+log(5)*0}, чтобы bigint-ы не сравнивать и не считать).
Потом, пока не набралось n чисел, берем минимальное число из heap-а как следующее по порядку. Потом "умножем" его 2, 3, и 5 (на самом деле не умножем, а прибавляем 1 в нужное поле и нужный лог куда надо). Эти 3 числа, если они еще не были добавлены в heap туда суем. Тут можно использовать hash-set, чтобы несколько раз не добавлять число. Или можно добавлять число в любом случае, но тогда надо будет возможно одинаковые числа вытаскивать из начала хипа и там будет в 3 раза больше чисел.
Это решение за O(n log n) по времени и линейное по памяти (всего в хипе будет до 9*n чисел). При этом для экономии времени можно сказать "допустим у нас есть класс, который числа такого вида хранит и сравнивает быстро в виде тройки степеней и логрифма. Для не очень большого n точности double должно хаватать." Писать его не нужно, достаточно описать в каком виде он хранит и что делает. Для первого приближения можно вообще bigint использовать, но я обязательно подскажу, а нельзя ли тут как-то побыстрее сравнивать. Писать heap и hash set не надо! Можно знать про std::priority_queue и std::unordered_set или вообще сказать, что пусть у нас есть такие классы. Они точно есть в стандарте, но я точно не помню. Я за это "баллы" не снимаю (ведь на самой работе у вас будет интернет и ide).
class Number; // Holds 2^a*3^b*5^c efficiently, can compare and multiply by 2,3, or 5.
Number GetNthNumber(size_t n) {
std::priority_queue<Number> next;
next.push_back(Number(2));
next.push_back(Number(3));
next.push_back(Number(5));
size_t processed = 1;
Number current = Number(1);
while (processed < n) {
Number next = next.pop_back();
if (current == next) continue;
next.push_back(next * 2);
next.push_back(next * 3);
next.push_back(next * 5);
current = next;
++processed;
}
return current;
}
Второе решение линейное и по времени и по памяти. Нужно заметить, что любое число нужного вида можно получить из какого-то ранее известного числа умножением на 2, 3, и 5. Если мы сгенерим все числа до k-ого, и умножим из все на 2, 3 и 5 и смерджим все три списка, то точно сгенерим k+1-ое число. Эту операцию можно делать лениво. Это что-то типа того как ленивый haskell будет работать. Заведем список всех сгенеренных чисел и будем смотреть, какое минимальное число при умножении на 2, 3, и 5 в нем еще не содержится. Это такие 3 указателя. Каждый раз двигаем вперед один из указателей и дописываем новое число к концу списка.
class Number;
Number GetNthNumber(size_t n) {
std::vector<Number> numbers(n);
n[0] = Number(1);
int next2=0, next3=0, next5=0;
Number next2Number = Number(2);
Number next3Number = Number(3);
Number next5Number = Number(5);
for (size_t i = 1; i < n; ++i) {
if (next2Number < next3Number && next2Number < next5Number) {
numbers[i] = next2Number;
next2Number = numbers[++next2] * 2;
} else {
if (next3Number < next5Number) {
numbers[i] = next3Number;
next3Number = numbers[++next3] * 3;
} else {
numbers[i] = next5Number;
next5Number = numbers[++next5] * 5;
}
}
}
return numbers[n-1];
}
Edit: исправил пару опечаток в коде. На интервью, я намекаю кандидату, если выижу опечатку вроде "в этой строчке похоже опечатка". Баллы за опечатки вида 3 вместо 5 в названии переменной не снимаются.
Спасибо!
Достаточно держать heap из потенциальных следующих элементов.
Ну, да, это как раз та самая упорядоченная структура, которая бы помогла, и которой, насколько я знаю, нет в JS.
Но если решение с такими сложностными характеристиками устраивает, то это, наверное, хорошо, да. Или если на том же JS можно предположить, что у вас есть хип.
всего в хипе будет до 9*n чисел
Эм, почему? Каждое число порождает 3 других (и ещё можно учесть пересечения, да).
Для не очень большого n точности double должно хаватать.
А тут, кстати, возникают интересные вопросы о том, когда точности double не хватит, и как её оценить. Но это уже так, из любви к искусству.
По крайней мере, на SO мне так и не ответили.
Второе решение линейное и по времени и по памяти. Нужно заметить, что любое число нужного вида можно получить из какого-то ранее известного числа умножением на 2, 3, и 5. Если мы сгенерим все числа до k-ого, и умножим из все на 2, 3 и 5 и смерджим все три списка, то точно сгенерим k+1-ое число. Эту операцию можно делать лениво. Это что-то типа того как ленивый haskell будет работать. Заведем список всех сгенеренных чисел и будем смотреть, какое минимальное число при умножении на 2, 3, и 5 в нем еще не содержится. Это такие 3 указателя. Каждый раз двигаем вперед один из указателей и дописываем новое число к концу списка.
Оно на самом деле по памяти сублинейное (по крайней мере, так кажется, я очень плохо оцениваю сложности), если заметить, что числа меньшие, чем N/5 для текущего N, хранить не нужно, потому что они уже ни на что не повлияют. Но фиг его знает сходу, как оценить число этих чисел.
Оно на самом деле по памяти сублинейное
4 N / 5 все равно O(n) — линейное.
Чисел из этого множества между N и ⅘N не факт что линейное число.
Собственно, мне почти очевидно, что нелинейное (потому что эти числа очень быстро растут), но доказать формально я это не могу.
Таки погуглил немного. Например, на rosetta code пишут
Space complexity, with constant empirical estimation correction, is ~n^(2/3); but is further tweaked to ~n^(1/3) (following the idea from the entry below).
И в частности эта самая идея:
The DDJ blog post by Will Ness doesn't use the fact mentioned by the Wikipedia article that the error term in the estimation of the log of the resulting value for the nth Hamming number is directly proportional to this same log result. Using this fact, we are able to reduce the span of the "band" to only a constant fraction of the estimated log result for large n, and thus reduce memory space requirements to O(n^(1/3)) from O(n^(2/3)) for a considerable space saving for larger ranges.
Корень третьей степени из n — явно сублинейное время.
программист первокурсник уделает по скорости решения алгоритмических задач практически любого программиста последнего курса. А тот уделает в этом практически любого сеньора.
Курсы в ВУЗах в основном теоретические и те люди, о которых вы говорите, могут взяться только из кружков по спортивному программированию. А у сеньоров есть преимущество на собеседовании по system design.
А у сеньоров есть преимущество на собеседовании по system designЕсли вопросы на собеседовании дойдут до system design.
Ну, там хотя-бы немного лабораторных работ есть на первых курсах, где надо реализовать какие-то алгоритмы (работа с деревьями, алгоритмы поиска/сортировки, хэш-таблицы).
Да, только это надо сделать за 20 минут и еще успеть выбрать оптимальный подход к решению.
Если вопросы на собеседовании дойдут до system design.
Если пройти телефонное собеседование и system design предусмотрен, он обязательно будет.
Если пройти телефонное собеседование и system design предусмотрен, он обязательно будет.
Это зависит от компаний и тех, кто собеседует. Мы же сейчас говорим не про какие-то конкретные?
Некоторые могут собеседование прекратить после первых двух неудачных вопросов по «основам».
Это зависит от компаний и тех, кто собеседует. Мы же сейчас говорим не про какие-то конкретные?
Как минимум те четыре компании, которые я рассматриваю в статье. На очном этапе у них стандартный процесс, и они не могут прекратить его раньше времени.
Да, это происходит не каждый день, но когда оно происходит, то алгоритмические знания и умение решать алгоритмические задачи действительно нужны.
Умение решать на доске маркером за 10 минут без интернета?
Смотреть код с гитхаба — не у всех он есть, да и невозможно проверить, что этот код кандидат сможет воспроизвести.
О да, и как же компании проверяют, когда дают тестовое задание на дом? Там ведь тоже кто угодно сделать может. Дайте подумать, может задают вопросы по коду?
P.S: Я не против олимпиадников, просто подзадолбал неуместный элитизм некоторых представителей, которые могут написать на доске merge sort на С++ и при этом в реальных проектах пишут неподдерживаемый говнокод.
Умение решать на доске маркером за 10 минут без интернета?
В гугле уже давно интервью проходят на ноутбуке. Задачи подбираются так, что 25 минут чистого кодирования должно хватать выше крыши. Да, без интернета, потому что проверяется способность кандидата решить проблему, если не удалось найти код на стекофервлоу, чтобы его скопипастить.
О да, и как же компании проверяют, когда дают тестовое задание на дом? Там ведь тоже кто угодно сделать может. Дайте подумать, может задают вопросы по коду?
Согласитесь, есть вариант взять старшего товарища, который решит вам тестовое и все объяснит. Это на порядок проще, чем самому писать. Желающих получить хорошую зарплату и все плюшки(а дальше, может и так справлюсь) — довольно много. Реально попадались люди, которые fizz buzz написать не могут, а на интервью подают (ну а вдруг?!). Еще была байка про китайца, который на интервью отправил похожего на себя друга, который интервью за него прошел, а сам вообще ничего сделать не мог.
Соответственно, будет далеко не нулевая доля кандидатов, которые могут решение понять и объяснить, но сами такой код написать не могут. Когда у вас тысячи нанимаемых людей в год, это выражается в ощутимом количестве новых работников, которые плохо справляются со своими задачами. А это большие потери для компании.
которые могут написать на доске merge sort на С++ и при этом в реальных проектах пишут неподдерживаемый говнокод.
На интервью даются подсказки и комментарии. Если условный олимпиадник пишет "олимпиадный", неподдерживаемый говнокод, ему это сразу же сообщается. Если кандидат так и не может написать читаемый код, даже если задача решена гениальным алгоритмом, в соответствующей графе записывается жирный минус. Если на всех 4-5 кодо-интервью будет говнокод, то вряд ли будет офер.
Да, без интернета, потому что проверяется способность кандидата решить проблему, если не удалось найти код на стекофервлоу, чтобы его скопипастить.
То есть надо не просто решить проблему, а сделать это с идиотскими ограничениями, которых никогда нет в реальных проектах. Часто от кандидатов ожидается зубрежка типовых решений типовых задач, которые легко гуглятся.
Реально попадались люди, которые fizz buzz написать не могут, а на интервью подают (ну а вдруг?!)
Это не новость для любого, кто проводил интервью в любой более-менее крупной конторе (далеко не уровня гугла).
Соответственно, будет далеко не нулевая доля кандидатов, которые могут решение понять и объяснить, но сами такой код написать не могут.
С чего вы взяли, что не могут? Если ты понимаешь решение, ты можешь его воспроизвести.
P.S. Обычно все это просто от неумения проводить интервью. Вроде тех знаменитых загадок в гугле про пианистов и канализационные люки.
То есть надо не просто решить проблему, а сделать это с идиотскими ограничениями, которых никогда нет в реальных проектах. Часто от кандидатов ожидается зубрежка типовых решений типовых задач, которые легко гуглятся.
Почему никогда нет?! Вы утверждаете, что решение любой задачи можно найти в интернете? Проверять именно вариант ненайденного решения имеет смысл, потому что копипастить код с stackoverflow может даже обезьяна. Интервью с интернетом или может отсеивать только полных идиотов, или тогда надо кандидату не решать задачу, а писать целые эссе на тему, какие решения найдены, чем они хороши, почему именно это выбрано и куча рассуждений, доказывающих, что кандидат понял решение, а не скопипастил первое попавшееся, где ключевые слова нашлись на странице. Но эти эссе проверять слишком долго. Или тогда обсуждать найденное решение надо несколько часов.
С чего вы взяли, что не могут? Если ты понимаешь решение, ты можешь его воспроизвести.
То же и с языком. Есть довольно широкий диапазон владения иностранным языком, когда читать и понимать можешь, а сказать — почти ни слова.
Тут то же самое.
Обычно все это просто от неумения проводить интервью.
Ну объясните тогда, как проводят интервью те, кто умеет?
Ну объясните тогда, как проводят интервью те, кто умеет?
Если нанимают мидл/сениор инженера, дают типичное задание. То есть если человеку надо разрабатывать API, дается тестовый проект и задание на минут 15-20, типа реализовать такой-то endpoint. Потом задаются вопросы и можно усложнять задание (посчитай еще вот это и верни в запросе). С сениорами еще поговорить про system design. Суть: посмотреть как кандидат справится с ежедневной работой.
То же и с языком. Есть довольно широкий диапазон владения иностранным языком, когда читать и понимать можешь, а сказать — почти ни слова.
Не надо сравнивать теплое с мягким. Если можешь читать то можешь и писать, разговорная речь это совсем другое. Аналогия так себе.
тогда надо кандидату не решать задачу, а писать целые эссе на тему, какие решения найдены, чем они хороши, почему именно это выбрано и куча рассуждений, доказывающих, что кандидат понял решение, а не скопипастил первое попавшееся, где ключевые слова нашлись на странице
Спросить не пробовали?
В гугле уже давно интервью проходят на ноутбуке.
Зависит от офиса, видимо.
Я в 2016 собеседовался в Цюрихе — были только доска и маркер.
По крайней мере после 2017-ого года в общей для всех инструкции написано спросить кандидата, хочет ли он писать на ноутбуке, который можно заранее взять там-то и там-то. Не вижу причин не делать это, потому что в этом случае код сразу готовый и его можно скопипастить в отчет — не надо фотографировать, парсить и перепечатывать доску.
Вот, недавняя статья от яндекса приводит несколько примеров практически задач с собеседования
Но это антипример практически. В качестве хардкорного примера тру-алгоритмических задач идёт… вымученый случай применить reduce на массиве.
Интересно, на что еще способны пойти люди, лишь бы стать гайкой

Гайка или нет — решает человек. Если для Вас это так — то старайтесь делать что-то иначе и добиваться своих результатов. Для кого-то, работа в таких компаниях — хорошая цель, в конце концов только усилиями многих людей делается что-то значимое, и IT гиганты только доказывают это своим существованием.
Я ни в коем случае не отговариваю или осуждаю.
и IT гиганты только доказывают это своим существованием.
что доказывают? профит от торговли рекламой?
Почему? Мне кажется это из той же оперы, что и «злиться на то, что ветер дует»? Мне кажется, что это результат довольно естественных решений социума, странно клеймить их позором. К слову, я с вами совершенно согласен — хочется уже воплотить мотивы Брэдберри, а не вот это вот все :)
по сравнению с тем, как могли бы жить и как будем жить лет через 300.
Да вы оптимист, я смотрю. Если через 300 лет не самовыпилимся совсем, то будет или глубокая антиутопия типа 1984, или самый мрачный киберпанк, где 99% населения будут практически рабами и править всем будут мегакорпорации, или буквально средневековье, в зависимости от того как третья мировая пройдет.
А вот в 1984 не сильно верю, социальный прогресс в другую сторону идет.
Ну, китайцы уже обкатали на уйгурах вполне себе цифровой концлагерь. В москве потихоньку вводят похожего уровня ограничения и я не сомневаюсь, что "для вашей безопасности", эти пропуска оставят надолго.
Двоемыслие и переписывание прошлого уже практикуется политиками по всему миру (тот же Трамп, например, который может сегодня говорить полностью противоположное тому, что говорил вчера и отрицать, что он вообще вчера это говорил — и всем пофигу).
И вообще, случись глобальное потрясение, типа третьей мировой, или массового голода и переселения из-за климатической катастрофы — весь социальный прогресс сдует. А технологии останутся. И их будут применять не для улучшения уровня жизни а для сохранения власти и контроля.
Профит дело побочное, это усилиями менеджеров он сделан, а программисты делают сам продукт(многие помнят ламповый инет, когда уже многое было, а никак не монетизировалось). Вы вот наверняка ютуб смотрите тот же, а ведь это куча произошедших инноваций, год за годом. И то что на рекламе делаются основные деньги, а не на платной подписке — это альтернатива и значит это для потребителя лучше ее отсутствия. Бизнес на волонтерских началах не выживет.
1) у вас уже будет опыт прохождения подобных собеседований
2) через пол года уже можно будет ещё раз пособеседоваться туда же
Чем больше собеседований посетите — тем проще будет проходить их.
через пол года уже можно будет ещё раз пособеседоваться туда же
Это если вас порекомендовали, иначе надо будет, чтобы о вас рекрутер вспомнил.
чтобы нанять себе менеджера-тренера-надсмотрщика
А где такого можно найти? 0_о
Если бы это так просто работало, собеседования вообще не имели бы смысла
Это ещё почему? опыт не бинарное состояние есть/нет, и имеется огромная разница выход на 100% продуктивность через неделю две или года 2-3, вот на собеседовании и выбирают тех кто за минимальное время сможет выдать максимум продуктивности.
А на уровне мы или нет для данной работы мы не знаем
Обычно в вакансии круг требований указан и зачастую на собеседовании будущий начальник так же приходит, где и очерчивает круг обязанностей. При этом чем больше контора тем больше может быть зазор между имеющимися навыками и требуемыми, слишком много людей слишком нерасторопны бизнес процессы (даже здесь были отзыва где человеку неделю учётку заводили или забывали про целые отделы).
О работе-то мы ещё даже не беспокоились
Ну если требуемые навыки есть, что о ней беспокоиться то? Не потянете уволят, в крайнем случае, если уж прямо сильно обманули (а вот чтоб этого не было и проводят собеседования и спрашивают дипломы)
Это ещё почему?
Потому, что если это не так, то есть и повод беспокоиться, ибо «Потому что на работе есть коллеги и инструкции, которые сильно помогают, плюс есть время на 'раскачку' чаще всего, никто сразу 100 процентов продуктивности не требует» не гарантируют успешного выполнения работы. А я об этом, собственно, и говорил. Но если вы согласны, что возможность не справиться есть, тогда процитированное особо не поможет в этой ситуации.
выход на 100% продуктивность через неделю две или года 2-3,
А как быть, если всё, что вы напишете годится только в мусор (нет, не из-за стиля, а из-за недостатка опыта в применении некой технологии или концепции)? А чтобы годилось не в мусор, потребуется от вас серьёзное обучение и большой опыт именно узкой направленности (скажем, попробуйте написать драйвер — там очень непросто всё сделать правильно). И вполне можно не справиться.
Обычно в вакансии круг требований указан
Тут недавно кто-то писал, что у них в компании меняют как перчатки эти требования. Да я и сам видел — пришли на С++, но команда решила перейти на питон. Упс.
Ну если требуемые навыки есть, что о ней беспокоиться то?
Нет, ну если один-в-один совпадает с тем, что вы умеете, тогда да. Но обычно-то ведь не так. Точного совпадения нет.
Непонятно, почему вы так переживаете за работодателя.
Я вас (и ещё двоих тут) не понимаю. При чём тут работодатель? Вы сами не боитесь не справиться и вылететь или угробить здоровье и силы, пытаясь соответствовать тому, чему вы на момент интервью не соответствуете? Работодатель-то найдёт другого, а вот вам придётся заново всё начинать.
вы увидите, что и новые коллеги далеко не все гениальны,
Это по-разному бывает.
Ну если интервью получилось успешно пройти, значит, более-менее соответствуем работе. Соображалка есть. А с конкретными технологиями опять же коллеги помогут, да и если голова работает, то "сейчас докурю и пойду сдавать" (с)
Вы сами не боитесь не справиться и вылететь или угробить здоровье и силы, пытаясь соответствовать тому, чему вы на момент интервью не соответствуете?
Дык а что самое худшее произойдет? Поработаю месяц-два-пять и меня уволят? Ну-у-у, да, неприятно, придется потратить недельку-месяц на поиск нового места. Про угробить здоровье и силы — дык не надо гробить, просто чуток постарайтесь. Не хватит — ну значит не хватит, это ж не вопрос жизни и смерти.
будет время изучить новый язык и/или технологию.
Изучить? За небольшое время? Завидую. Я вот за 20 лет С++ изучить не смог до современного уровня — я этот Си++ в не legacy стиле банально не понимаю как концепцию (куда уж до понимания граблей!).
Плюс к этому (и не только в Google) код обкладывается проверками анализаторов и тестами, а коллеги проводят ревью.
Только всё это не обязательно поможет вам быстро научиться требуемой концепции применения.
Научится работать легко.
Видимо, мне такого уровня не достичь. :)
Тем не менее, это нивелирует весь смысл собеседования. :)
Тем не менее, это нивелирует весь смысл собеседования. :)
Не совсем, ведь задача собеседования — минимизировать ложноположительные результаты. А минимизировать ложноотрицательные результаты — уже головная боль кандидата, а не компаний, поэтому и приходится готовиться к собеседованиям.
что вы никогда не проходили собеседования на разные работы
Нет, не проходил.
Не думали никогда, что со стороны работодателя есть такая же мулька: «Справится/не справится, приживётся/не приживётся». Это всегда рулетка с обеих сторон.
Это логически никак не связанное утверждение с исходным моим вопросом. Там нет ни слова о стороне компании, там изначально вопрос задан со стороны работника. Проблемы компании я не рассматриваю, как можно увидеть.
То есть, никого не беспокоит, справится он с работой или нет?
Риск фейла отдельно взятых сотрудников в достаточно крупной компании должен не беспокоить, а быть подсчитан и учтён в бизнес-процессах. А результаты собеседования как раз являются исходными данными для этого подсчёта.
Если же процессы в компании построены так, что фейл одного разработчика приведёт к
Понятно, что есть задачи, где цена ошибки одного человека может быть очень высокой, а возможности риск-менеджмента весьма ограниченными. Но туда и людей не по собеседованиям ищут.
А зачем беспокоиться, справлюсь я с работой или нет? Я честно постараюсь сделать всё, что от меня зависит, чтобы справиться. Ну если нет — так нет. Если уволят — буду искать другую работу. Если нет — значит, следующую задачу дадут более соответствующую моему уровню. Главное, чтобы перед собой не было стыдно.
А зачем беспокоиться, справлюсь я с работой или нет?
Вот этого подхода я и не понимаю.
Я же в том же комментарии постарался объяснить...
Понимаю. Вопрос в том, считать ли этот период времени (от подготовки к собесу до увольнения в случае неудачи на новой работе) потерянным. Вы получаете опыт, деньги за отработанное время, знакомства, расширяете кругозор.
А насчёт интереса к работе — пожалуй, полностью согласен. У всех свои требования к тому, чем они хотят заниматься. Грустно сидеть на нелюбимом месте. Ну разве что очень деньги нужны и другого выбора просто нет.
Сколько всего у вас заняла подготовка (к примеру, N месяцев по M часов в день)?
После «приятного» собеседования в майле, когда меня собеседовал только HR, и когда отказ дали из-за выбора в пользу того, кто знает нужный фреймворк. Хотя об этом заранее говорилось. Т.е. собеседование проводилось тупо для галочки. Вот после этого мне не хочется ни в майл, ни в яндекс.
Лучше работать в маленькой конторе, в которой проще провести изменения в сторону улучшения технологий. И вот там не будут просить решить логические задачи. Т.к. умение решать задачи — это ни о чем. Человека можно просто натаскать их решать, но вот в нужном месте он не сможет понять, что нужно сделать. Тут нужно не умение решать логические задачи, а опыт.
Т.е. собеседование проводилось тупо для галочки. Вот после этого мне не хочется ни в майл, ни в яндекс.
Такое бывает, но в случае Яндекса я с подобным не сталкивалась, хотя собеседовалась не один раз. Их собеседования очень похоже на те, что описаны в статье.
Лучше работать в маленькой конторе, в которой проще провести изменения в сторону улучшения технологий.
Это кому как повезёт. Как начальник будет реагировать на эти изменения. Из моего опыта, в крупных компаниях были гораздо лучше налажены процессы разработки, было строже ревью кода и технологии использовались новее. Кроме того, в крупных IT-компаниях стандартизирован формат собеседований, а в мелких никогда не знаешь, что будет. Сколько раз меня спрашивали про декрет, а один раз наняли в том числе потому, что подыскивали жену руководителю разработки.
И вот там не будут просить решить логические задачи.
От логических задач известные мне крупные IT-компании уже отказались.
Т.е. собеседование проводилось тупо для галочки. Вот после этого мне не хочется ни в майл, ни в яндекс.
В Яндексе по моему опыту прохождения собеседований делают упор на навыки программирования в общем и на system design. Отсутствие знаний по конкретному фреймворку еще не повод отказываться от кандидата, если конечно речь идет не о платформенных основах — типа понимания жизненного цикла Activity для Android разработчиков или многопоточности для Java-backend. А отсутствие знаний Spring или Dagger… Да фиг бы с ними, смотрите, он смог проверить строку на палиндром, надо брать!
Зато там те самые нелюбимые вами алгоритмические задачи, которые надо писать на листочке, доске или в текстовом редакторе.
P.S.: Мне проще задачки порешать, чем объяснять человеку, что в гробу я видел его вопросы про equals и hashcode.
В стартапе же всё иначе: возможно, в будущем имя компании в CV ничего и не скажет, но ты непосредственно влияешь на продукт, который использует конечный пользователей, и этот продукт невероятно изменяется и эволюционирует у тебя на глазах. Ну, и «тот самый дух стартапа», и шанс, что он выстрелит (~ 10%).
Расскажи, проводила ли ты такие сравнения, делая выбор в пользу стабильности корпората, или никакого выбора не было, и ты всегда смотрела в сторону этих гигантов.
В сторону Азии ты не смотрела?
Там тема IT стартапов бурлит!
Будет интересно почитать через, скажем, год — с чего начиналась непосредственно сама работа, где вы сейчас и к чему идете.
Успехов!
Вот я так же к устройству в гугл готовился-готовился, на собеседовании ответил хорошо и взяли меня на позицию выше, чем я заслуживал. Чуть не выперли потом, еле выкарабкался.
0xd34df00d, прости =(
В ближайшее время она точно мне не понадобится, но для общего понимания — годно!

Корреляция: как незаметно выстрелить себе в ногу
:D
Так и здесь. Не думаю, что стоит доводить это до дрессировки с единственной целью — пройти любой ценой. Но освежить неиспользовавшиеся навыки и подготовиться к тому, что ожидает на собесе, может быть полезно, чтобы не проиграть в конкуренции вызубрившему всё джуну.
Но освежить неиспользовавшиеся навыки и подготовиться к тому, что ожидает на собесе, может быть полезно...В статье как раз про целенаправленно готовиться, а не освежить.
… чтобы не проиграть в конкуренции вызубрившему всё джуну.То есть опытный кандидат сравним с джуном? Получается вес опыта не велик?
То есть опытный кандидат сравним с джуном? Получается вес опыта не велик?
Смотря что вы хотите измерять. По умению решать хитровыдуманные задачки я бы с треском проиграл 20-летней версии самого себя. Но в моей сегодняшней работе 20-летняя версия была бы абсолютно бесполезна, а то и вредна, потому что думать именно в рамках рабочего процесса я тогда умел довольно плохо. Тем не менее, если я пойду менять работу, то большинство распрекрасных работодателей предложат мне именно хитрые задачки.
Смотря что вы хотите измерять.Я ничего не хочу измерять, я задал уточняющие вопросы предыдущему оратору.
С вами я согласен, но с хитрыми задачками у меня примерно одинаково, что сейчас, что 20 лет назад :) Последнее время меня гоняли по тонкостям C++, которые в реальной жизни я не использую, а после собеседований через некоторое время забуду.
Однажды я проходила собеседование, к которому долго и упорно готовилась. Я щёлкала задачи как орехи, быстро писала код и чувствовала воодушевление. Техническая часть показалась очень лёгкой, и я завершила звонок в полной уверенности моего прохождения: «Если я уж сейчас не пройду, то не знаю, что им ещё нужно». Не было человека счастливее меня, пока я не прокрутила своё решение ещё раз и не нашла ошибку.
На этой неделе проходила телефонное интервью. Очень похоже было, задача была несложная, но я сразу сказала, что изначально пишу brute-force версию. Потом мы поговорили про тест-кейсы, про некоторые оптимизации, я порассуждала о сложности решения, а затем времени не осталось. Интервьюер сказал, что задачу я решила, но решение принимает не он. В целом, как только оно закончилось, мне интервью очень понравилось.
Через 10 минут после интервью я поняла, что написала жесточайший костыль, и что очевиднейшую оптимизацию я упустила. И что тест-кейсов должно было быть больше. И что даже один из параметров в O-нотации не должен был быть больше другого, и можно было бы не тянуть второй.
На следующий день эти оптимизации мне даже снились.
Если по истечении времени задача не была сделана, я изучала решение, вносила её в список и возвращалась к ней через некоторое время.
Скажите, а что вы считали за «сделана»? Любой возможный способ, в том числе brute force, лишь бы задача принята и прошла все тесты? Или вы все-таки пытались получить хороший Time/Space Complexity?
Странно, что несмотря на 15 лет работы и солидный послужной список в линкедине, ни одна из вышеупомянутых компаний мне не нaписала.
В связи с чем есть вопрос: 100 connections это много или мало? А также: правда ли, что наличие фотки сильно влияет на шансы?
100 connections это много или мало71 connections, 5 лет опыта, писали из Amazon, Facebook, и некоторых менее известных контор. Самый запомнившийся собеседник носил несколько неприличное имя (или это была фамилия?) и звал в Японию.
Особым послужным списком в Linked.in не обладаю. Фотография появилась недавно, но писали существенно до ее выставления.
В общем, это рандом дикий. Ну либо мой список какой то более послужной.
— Кем вы подписаны в должности (Software Engineer лучше, чем реальная, но нестандартно называющаяся должность, где вы занимаетесь тем же самым);
— Есть ли у вас прикрепленные сертификаты;
— Какой уровень владения английским языком выставлен;
— Возможно, ваши навыки слишком сфокусированы на стеке, который им неинтересен.
Когда мне впервые написали из Amazon, у меня было что-то около 50 контактов.
— Сертификаты не прикреплены (фейсбук их реально смотрит?)
— Надо указывать английский? А зачем? Мне кажется 9 лет работы в англоязычной стране сам за себя говорит. Честно говоря, я вообще редко вижу чтобы язык кто-то указывал.
— Стек: backend и fullstack Java.
Откуда и куда Вы планируете релоцироваться?
Спасибо за статью, интересно. Как вы учили и прокачивали английский? Думаю, высокий уровень языка один из больших плюсов.
В то время я не могла потратиться на репетитора, поэтому занималась так: тренировалась с LinguaLeo каждый день по часу, читала научные статьи в Scientific American. Для прокачивания аудирования выбрала несложный сериал — я смотрела «Как я встретил вашу маму», подсматривала субтитры по минимуму и переводила их, после этого слушала подкасты BBC. Говорить ходила в разговорные клубы, а перед сдачей IELTS записалась на специальный курс. Сейчас использую английский на работе, немного ещё ходила на курсы и занималась в Skyeng.
Если бы я сейчас поднимала уровень английского к собеседованию, я бы поступила немного иначе, так как появилось много новых возможностей. Во-первых, пошла бы в Skyeng, там помимо занятий с репетитором есть бесплатные разговорные клубы. Во-вторых, помимо сериалов слушала бы подкасты про IT. В-третьих, попыталась бы найти специальный айтишный разговорный клуб: в идеале такой, где готовятся к собеседованиям (пример), но и просто за жизнь пойдет (пример). Мне кажется, для прохождения собеседования достаточно разговорного уровня B1-B2, главное знать специфику.
Более того, переводиться надёжнее и проще, чем H-1B пытаться выиграть. На L-1 нет лотереи.
Почему? Я по ней 4 года назад переезжал, конечно, может, поменяли чего, но по L-1B переводят вообще без проблем, а меня вообще перевели по L-1A (потому что я типа менеджил essential function, будучи синьором-помидором в 24 года в момент подачи заявления на визу).
У вас нет specialized knowledge, и вашу работу может делать любой американец знающий С++ и ООП
Любую работу со specialized knowledge может делать любой американец, обладающий этим specialized knowledge, так что это ИМХО странный аргумент (это не к вам претензия, я просто пытаюсь понять логику этих систем).
С одной стороны, знание C++ — это уже само по себе specialized knowledge, им за год (да и за 10 лет) не овладеешь. С другой — если я год поработал в зарубежном филиале, например, Гугла, научился работать с тамошней системой контроля версий, системой сборки, процессом релизов, календарём и бронировалкой переговорок, то разве уже не specialized knowledge, которого у человека со стороны априори нет?
Но да, мне в Лондоне L1 поставили вообще без всяких проблем — мило поболтали с officer'ом о погоде, о том, как живётся в районе у метро, где я тогда жил, и всё. Может, потому что это была blanket petition, хз, и компания всё же относительно известная.
А я вот, асушник, вообще ничего толком не могу (может не знаю, не умею) найти, ни форумов нормальных и живых, ни инфы по зарплатам, ни по собеседованиям.
Вот интересует меня вакансия в Амазоне европейском и что дальше, пробовать наобум…
Вообще, как работодатель могу сказать, что ошибку могли и заметить, но сознательно проигнорировать, т.к. все ошибаются. Если можно было бы просто брать на работу людей, которые не ошибаются, у нас бы не было ни автотестов, ни QA ручного, ни багов, ни проблем никогда и никаких. В идеальном мире наверное оно как-то так и устроено — ты просто берешь на работу тех, кто никогда не ошибается.
В реальном мире так не бывает и это приходится держать в уме. Конечно такие гиганты как Faceboogle могут себе позволить просто выкинуть кандидатов, которые ошиблись и брать на работу только тех, кто здесь и сейчас не ошибся. Но это не значит, что их программисты пукают бабочками, и свидетельства этому переодически вылезают наружу.
Удачи.
Что уж говорить об алгоритмах, структурах, паттернах и умении вспоминать/воспроизводить/комбинировать их в условиях стресса на собеседовании?
Вот и получается: чтобы пройти собеседование, ты тренируешь себя в прохождении собеседований. Возможно, это вполне оправдано для таких IT-гигантов, им просто необходимо произвести качественный первичный отсев, чтобы не захлебнуться в нескончаемом потоке кандидатов. Но на деле, куда важнее уметь взаимодействовать с командой, адекватно эстимировать свои таски и отвечать пресловутым потребностям бизнеса.
В связи с этим, вопрос: зачем так мучить людей, если по итогу, большая часть их трудового ресурса всё равно будет утилизироваться на тривиальные, скучные, типичные задачи (будь то Google, MS или Amazon)? К тому же, не стоит забывать кучу прецедентов, когда кандидата апрувили, он попадал в компанию, а потом его с треском вышибали по «культурной несовместимости» (оказался чересчур расистом/сексистом или ещё как-то не угодил американскому просветлённому обществу).
Какой смысл тратить человеко/часы на подбор кандидата с обеих сторон, если успешно пройденный техсобес не даёт никаких гарантий получения нового члена команды, который станет крепкой ячейкой рабочего коллектива???
Поймите меня правильно, я ни в коем случае не хочу оскорбить автора. Более того — её упорство достойно уважения. Чтобы грокнуть всё это дело, действительно нужно потратить много времени.
Мой комментарий, скорее, крик души и скорбь по отсутствию реально действенного подхода к оценке кандидатов. Грустно осознавать, что компании-гиганты, которые кичатся своей «бирюзовостью» так и не придумали ничего более умного и по-настоящему действенного, кроме как делать упор на проверку абстрактных хард скилов.
Факт остаётся фактом: навык успешного прохождения собеседований — тренируемый и не имеет ничего общего с умением работать / не конфликтовать с коллегами / уровнем мотивации / лояльностью к компании / умением бороться с кучей проф деформаций.
В 2020 году уже все прекрасно понимают, что софт скиллы программиста первичнее его хард скиллов (которые подтягиваются по мере надобности на раз-два). Все же «гиганты» идут по проторенной дорожке, которую проложили ещё 30-40 лет назад, когда хорошим программистом считался человек, умеющий реализовать эффективный программный алгоритм на слабом железе.
Что не так с этим миром прогрессивных технологий 21 века, в котором от программного дизайнера высокоуровнего языка на входе требуется знание ассемблера?
Ну будут в итоге люди не тренероватся писать алгоритмы и решать задачки, что хоть иногда может пригодится в работе (тема данной статьи, как раз этот факт), и точно коррелирует с абстрактным мышлением, которое программистам нужно. А будут люди учить наизусть истории о фейковом опыте конфликта в прошлой комманде, который они блестяще разрулили, будут платить за курсы ораторского искусства и учиться врать не краснея. Интервью в итоге будет отбирать самых хитрых и лицемерных и все.
Ну… почти. У вас последний сегмент не обрабатывается. На строке "abbaaaa", для 'a' вернет 1 вместо 4.
Я менее настоящий программист, у меня кода меньше :(
import qualified Data.HashMap.Strict as M
import Control.Arrow
runs = M.fromListWith max . map (head &&& length) . group
Даже работает:
λ> runs "aabccaaab"
fromList [('a',3),('b',1),('c',2)]
λ> runs "aabccaaabbb"
fromList [('a',3),('b',3),('c',2)]
А group откуда? Из Data.List?
Почему? Не за количество же строк кода, слава богу, платят. По крайней мере в гугле.
Наоборот отличное решение. Только не специалисту в этом языке программирования вообще ничего непонятно. А еще неясно, как долго оно работает и сколько памяти дополнительной жрет (может у вас строчка в гигабайты?).
Наоборот отличное решение. Только не специалисту в этом языке программирования вообще ничего непонятно.
Ну group
тут как-то ИМХО читерство использовать, некомфортно — оно больно близко к решаемой задаче. Хотя можно и руками написать в две-три строки, я тут рядом привёл пример.
Ну и рассказать, как работает, да.
А еще неясно, как долго оно работает и сколько памяти дополнительной жрет (может у вас строчка в гигабайты?).
По памяти должно быть линейно по числу различных символов во входе за счёт ленивости — group
лениво выдаёт новые элементы, map
их лениво преобразует, fromListWith
уже строго потребляет и ест память только в случае вставки нового элемента. Кстати, можно даже, наверное, сказать, что Θ(1), так как число символов ограничено сверху, в отличие от размера входа.
Двухгиговый файл с естественным текстом (где мало нетривиальных run'ов и, соответственно, почти 2 миллиарда вставок в мапу) прожевало за полторы минуты. Если сделать некоторые технические правки, то улучшится ещё раза в два, но это уже неалгоритмические изменения и потеря поддержки уникода (собственно, за счёт этого и выигрыш, думаю), так что не факт, что оно того стоит.
Собственно, на том же двухгиговом файле оно ест меньше сотни килобайт согласно встроенной в рантайм измерялке (значит, на самом деле будет в районе мегабайта с учётом оверхеда на RTS и всё такое), что подтверждает гипотезу о линейной по размеру множества символов памяти.
Эту ерунду надо читать справа налево, точки формируют этакий конвейер из функций, последовательно их применяя.
group
— стандартная функция, которая разбивает список из элементов (а дефолтовая строка в хаскеле — просто список символов), которые можно сравнивать на равенство, на списки из последовательно равных элементов:
λ> group [1, 1, 2, 3, 2, 2]
[[1,1],[2],[3],[2,2]]
Это стандартная функция, но если интервьюверу вдруг не понравится, что она слишком «готовая», то её можно написать руками в две строки, например, явной рекурсией. Ну или комбинаторами, если вам интервьювер не понравился:
group = unfoldr $ \case [] -> Nothing
(x:xs) -> Just $ first (x:) $ span (== x) xs
map
понятно что делает — преобразует список, применяя к каждому элементу функцию. Что тут за функция? Это head &&& length
. &&&
— это специальный комбинатор, который берёт две функции (на самом деле не только функции, но неважно) типа a → b
и a → c
и делает из них одну типа a → (b, c)
— то есть, кормит вход обеим функциям и объединяет их выход в пару. Например. (head &&& length) "abcdef"
будет равно ('a', 6)
. Соответственно, map (head &&& length)
от каждого списка, который выдал group
, оставляет первую букву и его длину.
fromListWith
из модуля M
— функция, которая делает хэшмапу из списка ключ-значение, объединяя значения для повторяющихся элементов согласно некоторой функции, ей переданной. Здесь используется max
, поэтому из повторяющихся значений остаётся наибольшее. Если бы я написал (+)
, то считалась бы их сумма, например.
Решил вашу задачу примерно за 40-50 минут чистого времени, используя песочницу кода, постоянно запуская код и иногда гугля вещи типа
hasOwnProperty
и «чо там за функция преобразовывала строку в массив». Потом еще минут 10-15 приводил код в порядок. Мои наблюдения и переживания по этому поводу:- Блииин, во я лузер, не смог справиться с задачкой, чуть сложнее физзбазза.
- На белой доске, а не в песочнице мне понадобилось бы часа два. А может и три.
- Гмм, когда последний раз в моей работе мне удобнее было использовать
for
, а неreduce
? - Гмм, а почему
[...str]
выдает в консоль не['b','b', 'b']
, a простоbbb
? (спустя 4 минуты) блин, похоже, это песочница так форматирует, все норм, это массив. Вроде. Ладно, вроде ж есть функцияsplit
, которая стопудов дает массив. - В течение минут десяти была паника от того, что результат был неправильным. А он был неправильным потому что в самом начале у меня была якобы входная строка, а в свою функцию я ее не передавал как аргумент. В итоге эта якобы входная строка вообще была неиспользуемой переменной
- Я это все делал, лежа в тишине в постельке с ноутом на пузе и попивая вкусную сенчу, и с перерывом на завтрак, а не под пристальным взглядом какого-нить чувака, который презрительным взором пытается нащупать зачатки моих хард-скиллов.
- идею использовать currentSequenceLength и хранить в ней длину текущей последовательности подсказала мне жена, которая пару месяцев изучает C#, а до этого никакой алгоритмики в глаза не видела. У меня до этого был объект
champions
, со структурой как у объектаresults
, что было избыточно и усложняло код. - Если в строке будут эмодзи, все пойдет по рулю, ну да ладно.
Я из этого делаю следующие выводы:
- сама задача абсолютно не похожа на те, что я решаю восемь часов в день. То есть, какие-то хард-скиллы она проверяет, но не те, которые мне нужны для работы.
- к собесу, на котором есть даже самые хиленькие алгоритмические задачки вроде этой, надо готовиться отдельно и специально путем задрючивания leetcode'ов
- инструменты очень важны, и для решения подобных задач у вас они должны быть под рукой. А для этого вы должна готовиться к собеседованиям такого рода, ведь в вашей повседневной деятельности вы не решаете даже такие задачки.
function getBiggestRepeatedSequenceLength(s) {
const result = {};
const strArray = s.split("");
let currentSequenceLength = 1;
for (let i = 1; i < strArray.length; i++) {
const curElement = strArray[i];
const prevElement = strArray[i - 1];
if (prevElement === curElement) {
currentSequenceLength++;
} else {
currentSequenceLength = 1;
}
const currentChampion = curElement in result ? result[curElement] : 0;
if (currentChampion < currentSequenceLength) {
result[curElement] = currentSequenceLength;
}
}
return result;
}
console.log(Date());
console.log(getBiggestRepeatedSequenceLength("aabbbccccaaaccccccca"));
console.log(getBiggestRepeatedSequenceLength(""));
console.log(getBiggestRepeatedSequenceLength("abababaccc"));
console.log(getBiggestRepeatedSequenceLength("cabccaabbcccaaabbb"));
console.log(getBiggestRepeatedSequenceLength("cabccaabbcccaaabbbcab"));
Ваше решение не работает на тесте "abbb". Потому что у вас первый символ никогда не участвует в проверке на длину, а только для проверки на несовпадение со следующим символом. Исправить не сложно, на самом деле.
Во вторых, зачем вам s.split("")? У строки уже есть способ достать символ по индексу. Или s[i] или s.charAt(i), если верить справке (секция character access). Я на js не пишу и вообще его практически не знаю, но наличие такого метода было мне очевидно. Вы за 5 лет во фронтенде ни разу строки не использовали? Ни разу не надо было посмотреть i-ый символ?
Это могла бы быть попытка работать с юникодом, но тогда бы вы об этом наверняка сказали, да и в условии задачи это не надо. Кроме того split("") юникод все-равно поломает, когда как charAt() с юникодом работает (да, я это гуглил. На собеседовании я бы вам за эту попытку работы с юникодом, кстати, поставил бы жирный плюс. Рассмотрели интересный и важный случай, но забыли, как работает стандартная функция — черт с ней).
Я вам верю, что Вы умеете программировать, раз вас за 12 лет вас ни откуда не выгнали и на код ваш не жалуются. Но в гугл/яндекс вас не возьмут, потому что вы, скорее всего, будете работать сильно медленнее других кандидатов и допускать больше багов. По крайней мере не на сеньера точно. Потому что на эту тривиальную, на самом деле, задачу у вас ушел час времени, куча гуглежа и подсказка "коллеги". А звание синьер — не по выслуге лет дается. А за высокую производительность труда, высокое качество кода, лидерские качества и способность помогать команде.
Вы за 5 лет во фронтенде ни разу строки не использовали? Ни разу не надо было посмотреть i-ый символ?
Я вам клянусь, ни разу не нужно было. Обычно надо сделать что-то в духе toTitleCase или там trim или еще что-то в этом роде — все это есть в стандартной библиотеке и любая работа с индексами — это в 9 из 10 случаев говнокод. Если припрет и точно надо будет что-то реализовать — реализую, но вы видите, что обычно — надо было не настолько часто, чтобы быстро вспомнилось.
Но в гугл/яндекс вас не возьмут
Абсолютно согласен, что не возьмут, а если хочу, чтобы взяли — надо посидеть полгода-годик в leetcode. Но вот с тем, почему не возьмут — тут у меня большие вопросы. Что за такие удивительные задачи во фронтэнде Яндекса, что в других местах у меня не надо было брать [i]-тый символ в строке — а там надо?
Вы как-то берете за аксиому, что ваша задача имеет отношению к полезному, повседневному программированию. Я же вам оппонирую, говоря, что полным-полно программистов, к деятельности которых такая задача не имеет отношения — они не умеют их решать, а код в своих организация пишут хороший и полезный. Таким товарищам придется поступать как вот этому парню (между прочим гугловому вендору) — нарешивать сотнями задачки из литкода.
Ваше решение не работает на тесте «abbb».
Это при попытке причесать код бага появилась, нехорошо получилось. Сначала вот так было:
function getBiggestRepeatedSequenceLength(s) {
const result = {};
const strArray = s.split("");
let currentSequenceLength = 0;
for (let i = 0; i < strArray.length; i++) {
const curElement = strArray[i];
if (i===0) {
currentSequenceLength = 1;
} else {
const prevElement = strArray[i - 1];
if (prevElement === curElement) {
currentSequenceLength++;
} else {
currentSequenceLength = 1;
}
}
const currentChampion = (curElement in result) ? result[curElement] : 0;
if (currentChampion < currentSequenceLength) {
result[curElement] = currentSequenceLength;
}
}
return result;
}
console.log(Math.random());
console.log(getBiggestRepeatedSequenceLength("aabbbccccaaaccccccca"));
console.log(getBiggestRepeatedSequenceLength(""));
console.log(getBiggestRepeatedSequenceLength("abbb"));
console.log(getBiggestRepeatedSequenceLength("abababaccc"));
console.log(getBiggestRepeatedSequenceLength("cabccaabbcccaaabbb"));
console.log(getBiggestRepeatedSequenceLength("cabccaabbcccaaabbbcab"));
По крайней мере не на сеньера точно. Потому что на эту тривиальную, на самом деле, задачу у вас ушел час времени, куча гуглежа и подсказка «коллеги». А звание синьер — не по выслуге лет дается. А за высокую производительность труда, высокое качество кода, лидерские качества и способность помогать команде.Может, у автора коммента на его повседневных задачах как раз высокие производительность и качество кода и с командой он хорошо взаимодействует. Я бы не стал такие выводы делать по тому, как он решал эту несчастную задачку.
По вашему тону выходит, что он
string = "aaaabccaab"
symbols = dict()
prev = None
count = 1
for i,c in enumerate(string):
if c != prev:
count = 1
else:
count = count + 1
symbols[c] = max(symbols.get(c, 1), count)
prev = c
print(symbols)
Вы не ищете максимальный отрезок подряд идущих букв, а только последний. Например, на строке "aaaba", ваше решение вернет 1 для 'a', хотя должно быть 3. Потому что при обработке последнего символа вы перезапишете подсчитанное значение для 'a' на 1.
А собес в гугл я и так знаю что не пройду, дрочить задачки месяцами у меня терпения не хватит.
Вы сказали неправду про «минуту»;
С чего это? Время моих комментариев с решением и фиксом никак не коррелирует, мой комент висел на премодерации пару часов, а пока идет премодерация ни исправить\удалить комментарий, ни добавить еще один — нельзя. И когда пишешь псеводкод на бумажке нет накладных расходов на валидацию синтаксиса, запуск и проверку кода. Вы написали что потратили на все 10 минут, хотите сказать на само решение у вас ушло больше 1-2 минут?
поспешили им похвастаться
Такие тупые ошибки всегда случаются именно когда хвастаешься :)
полностью проигнорировали постановку задачи (рекомендую прочесть исходное сообщение еще раз).
Кто вам такое сказал?
Выведите максимальную длину подряд идущих символов для всех символов. Т.е. для aabccaaab, нужно выдать a: 3, b:1, c:2Для aabccaaab мое изначальное решение выдавало именно a: 3, b:1, c:2. Я достаточно тупой чтобы накосячить, но не такой тупой чтобы не понять задание.
Или вас смущает что я делаю просто print(symbols) вместо красивого форматированного вывода? Оно кстати выдает в таком формате {'a': 3, 'c': 2, 'b': 1}
все запощенные решения тут, включая моё — ошибочные, ни одно не проверяет исходную строку на null
Во-первых в современных языках есть non-nullable типы. Во-вторых далеко не во всех кейсах требуется проверка на null. Порой перфоманс важнее проверок, а порой функция приватная и проверка выполняется задолго до нее.
В третьих такие задачи дают на собесах чтобы проверить именно логику решения. Докопаться же в коде можно очень до многого. Помимо проверки null, тут никто (кроме растиста) не работает с utf8. Можно еще много чего найти. Но эти мелочи вообще не важны, важна именно логика решения. Странно что вы этого не понимаете.
Плохо если человек не может решить, плохо если решает задачу неадекватно долго, плохо если делает ошибки и при этом не может исправить.
Лично я бы не хотел видеть вас в своей команде, потому, что постоянно пришлось бы вас проверять и перепроверять, а потом фиксить ваши «косяки».
Вы попадаетесь на ту же ошибку, что и я с хвастовстом. Слишком уверенно делая диагноз по комментарию. Вы же меня в реальной работе не видели, всегда может оказаться так что это я буду за вами косяки подчищать, а не наоборот. Вы вон даже не понимаете зачем такие задачи на собеседованиях дают. Если действительно этих вещей еще не понимаете, собеседовать и принимать решения по подбору людей в команду вам рановато.
Помимо проверки null, тут никто (кроме растиста) не работает с utf8.
λ> runs "胡西西它尔尔尔"
fromList [('\32993',1),('\23427',1),('\23572',3),('\35199',2)]
Печатает криво, это да, но считает правильно.
На кхмерском у меня не работает. Вбил туда ទ្រ (первая нагугленная строка на кхмерском) — показывает три кодпоинта.
Может, с локалями поиграться надо, но это уже выходит за рамки этого упражнения, ИМХО.
Наверное, на этом я общение с вами закончу: вы не любите критикуДавайте говорить правду: вы не хотите продолжать спор, потому что боитесь признать свою ошибку
P.S. Все-таки научитесь читать текстНечего ответить — докопайся до орфографии, классика
CharSequenceCount("វឌ្ឍនននភាពពពពវវវវវវ");
CharSequenceCount("ទ្រ");
ឌ: 1 ឍ: 1 ន: 3 ព: 4 ភ: 1 វ: 6 ា: 1 ្: 1
ទ: 1 រ: 1 ្: 1
Юникодная консоль ваш тут не спасет
.NET 4.7.2 если что
Вот на такой строке не сработает
CharSequenceCount("ȧȧȧȧȧȧȧ");
Надо использовать System.Globalization.StringInfo.
В моем нужно добавить один символ, for (int i = 0; i < s?.Length; i++))
И вы считаете это адекватным решением? Это сойдет для хотфикса, но в продакшен коде лучше сделать нормальную проверку на null в начале. Потому что завтра кто-то допишет еще одно обращение к s не заметив вопросик и все «упадет».
Как я сказал в коде(и в моем разумеется тоже) можно докопаться до очень многих вещей, но нужно ли?
Подготовка к собеседованиям в IT-гиганты: как я преодолела проклятье алгоритмического собеседования