Comments 328
PS Ах да, /голосом Сухорукова из Брата 2/ «Вы мне еще за Panoramio ответите!»
Все данные собеседований собираются воедино
За этот год можно систематизировать свои знания и заполнить обнаруженные пропуски.Существует ли способ узнать, что именно не устроило независимый комитет, или при заполнении пропусков нужно ориентироваться только на то, что ты сам посчитал тем, что могло не устроить независимый комитет?
Отчёт о собеседовании не доступен, но HR обычно транслируют что прошло не очень хорошо.
я описываю процесс как я знаю, на инженерные позиции
Либо я чего-то не понял, либо одно из двух. Собеседование на позицию инженера включает в себя подозрительно много кодинга? Я с трудом представляю себе ситуацию, когда, например, network engineer-у нужно будет быстренько нарисовать LRU-кэш.
Но да, как у них — я не знаю. Я пишу про SWE/SRE — добавил это в статью.
Собственно, я с трудом могу сказать «другое», т.к. автор про интервью не написал почти ничего.
Я правильно понимаю что google набирает себе инженеров, и в рамках работы будет использован тот язык который лучше для данной задачи ?
Выбирать команду можно под свой любимый язык, если так хочется; ну либо команде объяснить почему взять именно этот язык.
Таки что да. У меня есть бейджик за коммиты на 25+ языках, но это по сути типы файлов, которые я трогал ручками (включая ascii proto, json и т.п.). Из языков программирования лично трогал bash, bcl, c++, go, python, java, javascript. Может еще что было по мелочи, уже не помню.
www.businessinsider.de/employee-retention-rate-top-tech-companies-2017-8?r=US&IR=T — Пишут 1.9 года в гугле в среднем работают.
Turnover rates are drawn from LinkedIn’s member data. We calculate turnover by taking the number of departures/movement in a given population (e.g., the retail sector, the restaurant industry, or data analysts), then dividing that number by the average headcount of that given population in 2017. We consider professionals as leaving their position if they provide an end-date for their position at a company (excluding internal job changes within the same company). A member can have multiple departures and positions within the year period.
Вроде бы логично
Что, думаю более чем достаточно для исследования. Кто не использует линкедин в долине?
Ну и тогда не «в гугле» а «в гугле в долине».
Сейчас в гугле согласно последнего отчета ~85000 человек.
Согласно это статье в долине раньше была треть человек. То есть минимум две трети (~56 тысяч) не в долине и сомнительно что охвачена линкедином.
а еще сейчас глянул — на странице www.linkedin.com/company/google указано что там работает 153 тысячи… то есть в два раза больше, чем сотрудников в компании вообще.
в общем, как-то сбор данных странных.
В любом случае не понимаю в чём спор. Вы серьезно думаете, что люди работают в 1ой компании всю жизнь?
Вы приводите разные оценки с потолка что некоторые люди меняют место работы через то-ли 2 то-ли 3 года.
Ни то ни другое друг другу не противоречит, я просто указываю, что эта цифра не имеет никакого отношения.
К чему?
Цель то ясна, я просто говорю, что понятное дело, что она не достижима. Но даже если 3 года это правильная цифра (хотя я думаю она меньше), то это уже более, чем хорошо для Гугл так как это сильно больше среднего по индустрии.
Я знаю, что люди устают от одной работы.
Но если все одинаково оценены и наняты гарантированно все проходящие под общие требования, внутренний трансфер становится гораздо проще.
Кстати, даже для такой вещи, сюрприз!, нужны алгоритмы ;)
См. тут. У меня перед глазами достаточно примеров перехода людей между командами.
Таким образом, если сменить команду проще, чем сменить компанию, то люди будут оставаться в компании, а значит, расходы на интервью не будут увеличены на затраты для замены этого человека.
а еще сейчас глянул — на странице www.linkedin.com/company/google указано что там работает 153 тысячи… то есть в два раза больше, чем сотрудников в компании вообще.
в общем, как-то сбор данных странных.
Это видимо с учетом тех кто работал раньше там
Подозреваю, что сюда включены еще интерны, кто меняют статус только на следующем интерншипе, и те, кто ставят «работаю в гугле» чтоб им писали рекрутёры.
(когда я прописал что теперь работаю в гугле — у меня был десяток писем разных рекрутёров из разных контор «а не хотите ли к нам?», включая тех, кто обещал оплатить затраты на ранний выход если будут)
Если в каждом месяце сотрудник с постоянной вероятностью либо увольняется, либо нет — то это распределение Пуассона с матожиданием 3.2 года = 38.4 мес.
При этом вероятность, что сотрудник уволится за 7 месяцев, неотличима от нуля; и только на 17 месяцах достигает 0.01%.
«Я три года подряд кидал монетку, и каждый раз выпадал орёл. Какова вероятность, что в следующий раз выпадет решка?» — ровно такая же, как и при любом из предыдущих бросков.
Точно такая же.Давайте я опишу, как я вас понял, а вы скажете, где я ошибаюсь.
Матожидание количества уволившихся из 20 человек за 7 месяцев неотличимо от нуля. Это же верно и для вторых 7 месяцев, и ..., и для шестых. То есть, Матожидание количества уволившихся за 42 месяца тоже неотличимо от нуля (пусть и чуть побольше). Но матожидание срока работы в компании — 38.4 месяца.
Я вижу здесь противоречие.
Будем считать, что события «человек уволился в течение месяца» независимы и одинаково распределены для всех людей и месяцев и имеют распределение Бернулли с параметром p. Матожидание времени работы в месяцах равно 0*p + 1*p*(1-p) + 2*p*(1-p)^2 +… + k*p*(1-p)^k +… = (1-p)/p = 38.4. Отсюда p = 1/39.4 ≈ 0.025. Вероятность, что один человек не уволится за 7 месяцев, равна (1-p)^7, а вероятность, что за 7 месяцев не уволятся 20 человек, равна (1-p)^140 ≈ 0.027. То есть, вероятность того, что я наблюдал то, что я наблюдал, получается достаточно низкой. О чем я с самого начала и написал, пусть и менее строго.
PS: Так и не понял, при чем тут распределение Пуассона, оно же показывает вероятность того, что из х одинаковых событий k произойдут. Мне не интересно, сколько раз кто-то уволится за 38.4 месяцев, мне интересно, какова вероятность того, что кто-то уволится за 7.
Из языков программирования лично трогал bash, bcl, c++, go, python, java, javascript. Может еще что было по мелочи, уже не помню.Я помню!) — asm:)
Эта статья ПИД-регулятор своими руками в закладках, в надежде, что когда-нибудь на ее основе напишу на С для stm32
У меня собеседование проходило на джаве, а 80% времени приходилось писать на питоне и внутреннем языке для конфигов.
Интервью в гуглоподобных компаниях и их подражателях давно сломаны, и никто не хочет их чинить (а многие даже признать, что они сломаны). Проблем очень много и о них можно было бы статью написать, но если выделить самое основное, то компании вроде гугла, майкрософта, амазона и т.д. пытаются принять решение о найме пианиста по его способности играть на скрипке (это если повезло и борщ не заставили варить).
Хочется верить, что тот, кто изначально использовал задачи-головоломки на собеседовании действительно умел ставить по процессу решения правильный диагноз, но потом все сразу сломалось, как только собеседующие стали оценивать правильность ответа, вместо процесса размышления. Тут я поступлю нечестно и не буду ничего доказывать. Скажу лишь, что все-таки есть адекватные собеседующие, которым не все равно, кого наймут, а кого нет (обычно это в не очень популярных компаниях с точки зрения HR бренда, например, мне лично понравилось интервью в JP Morgan, хотя это вообще банк).
Те, кто в теме, мне возразят, что в гугле уже не задают задачи-головоломки, но на самом деле ничего не поменяется от того, что вы спрашиваете задачи вроде «поиска подотрезка с максимальной суммой». Если не знать решения на эту задачу, то вам явно не хватит 30 минут, чтобы ее решить. И даже показать, как вы думаете. Максимум вы всунете туда какой-то NlogN трюк, и не факт, что такой спец будет хуже «звезы», который знает решение, и не факт, что он будет лучше человека, который «почти» придумает линейное решение, но не успеет за 30 минут.
Если гуглу нужен «крутой алгоритмист», то вопросов нет, но гугл же утверждает, что они инженера нанимают. И вот тут можно вспомнить про борщ, о котором я говорил выше. Я не отрицаю сильную корреляцию между инженирингом и алгоритмами (математикой в общем случае). Человек, который знает алгоритмы и, например, еще участвует в контестах, может быть заодно еще и хорошим разработчиком софта. Но все таки разработка софта — это марафонский бег, и спринтер, даже самый лучший может не добежать до финиша в нужной кондиции.
Описанный кейс лишь одна маленькая грань большого айсберга системы найма, которая кстати заодно разгоняет скорость текучки и снижает комфорт и фан от работы. Да и качество конечного продукта давно оставляет желать лучшего.
Да, гарантий нет. Да, спортивное программирование не даёт информации о том, как будет человек работать в перспективе. Но оно, например, даёт знания алгоритмов и их реализации. А еще заставляет думать о граничных условиях.
На тему «знать» решение… Я получал прекрасный ответ на свой любимый нынче вопрос на собеседовании в первые 10 минут — кандидат смог сразу найти O(1) решение используя креативный подход к организации данных. И да, это не была домашняя заготовка — что легко выяснилось после усложнения задачи. Просто отличный сильный кандидат.
В целом, процесс собеседования модифицируется со временем и адаптируется (да, вы верно заметили — крышки люков больше никто не просит посчитать), но эти изменения не идут с бухты-барахты. Это всё «data-driven» осознанные изменения с оцененной и подтвержденной эффективностью.
А на счет домашней заготовки, ну это еще не факт, что хорошо. Есть люди, которые хорошо проходят интервью, а есть те, кто хорошо работают, и это далеко не одни и те же люди. Зайдите на любой сайт, посвященный теме интервью, первое, что вы там увидите «I will teach you to be good at programming interviews» написанное разными словами. То есть это как минимум говорит о том, что проходить интервью и работать это две большие разницы. Это УЖЕ должно наводить на мысль о том, что система сломана.
Тоже уже встречал, видно практически сразу.
Это всего лишь сокращает первую фазу до 2-5 минут.
А дальше начинается изучение как они думают вне стандартного интервью.
Я помню на хабре несколько комментов, как человек ходит регулярно на собеседования, чтоб навык не заржавел, ага
И это еще одна «грань» вышеупомянутого айсберга. Способности потенциального работника ставятся выше его мотивации, хотя без должной мотивации сотрудник будет больше вреда приносить, чем пользы, вне зависимости от его навыков.
мотивация и его googlyness тоже оцениваются.
Но в целом, съездить так получится один раз только на одну компанию, плюс старая компания не должна обидеться на такое поведение, плюс а вдруг понравится? если человек хорош и прошел заочные собеседования, то есть шанс что он приедет-посмотрит, а там глядишь и работать придёт.
все в выигрыше, разве нет?
Чаще всего компания хочет тех сотрудников, которых не может получить. Поднимает ставки, и на их место начинают ломиться те, кто на все согласен ради бесплатных обедов и пуфиков.
Вообще на вопрос о мотивации — если человек на собеседовании приходит с низкой мотивацией, а потом его удается «разогреть» это как раз лучше, чем нанять «гуглофана», потому что в голову-то не залезешь, этот гуглофан может быть кем угодно от инсайдера до интервьюкракера. А вот если человек не очень-то хочет работать в гугле, то это не просто же так. На интервью его наверняка соблазнил HR. Всегда было интересно, что бы ответил интервьюер, которому кандидат скажет: «мне че-то лень печатать, давай я тебе продиктую код, а ты сам запишешь»…
У меня пока такого не было, но я в пометки себе вношу всё что кандидат думает в слух а не записывает, чтобы не потерять.
Не соглашусь, я вот ездил в Амазон чисто потому что уже обещал приехать на собеседование, хотя оффер принял для другой компании. И снова зовут приехать.
Хотя я понимаю, что система позволяет в какой-то мере уменьшить вал непригодных для девелопмента людей, каким-то образом туда по-павших.
В итоге я работаю в компании, где у меня была пара собеседований и я не писал ни строчки кода.
Компаниям из первой десятки надо хотя бы уважать людей, проработавших лет по пять в нескольких крупных компаниях — ведь понятно если человек работает несколько лет и его не слили через год — значит он реальную пользу для компании приносит и весьма вероятно не будет балластом для следующей.
И да — это-таки имеет самое прямое отношение к «employment at will» и не только в Гугле.
А противоречие есть. В отличии от вас, говорить загадками либо отвечать на ваши в этом конкретном случае я не имею права.
При этом таки большинство SWE/SRE — это вовсе не контракторы… почему из и отбирают по несколько более сложной схеме, чем поваров или уборщиков.
вы спрашиваете задачи вроде «поиска подотрезка с максимальной суммой». Если не знать решения на эту задачу, то вам явно не хватит 30 минут, чтобы ее решитьИ это большая проблема очень многих компаний, которые дают алгоритмические задачи на собеседовании «чтобы как у Google». Но дело в том, что решить задачу — это вообще дело десятое, главное — показать, как ты думаешь. Если человек может выдать неоптимальное решение, а потом о нем хорошо порассуждать, это будет гораздо лучше (с точки зрения шансов попасть в Google), чем молча написать оптимальное. И в статье, кстати, об этом было написано.
«Я после колледжа проработал несколько месяцев в одной компании, решил что меня это не устраивает и стал готовиться к интервью в Гугле. Я уволился с работы и 6 месяцев готовился по книгам и тестовым заданиям. Теперь я работаю в Гугле, счастлив и всем того же желаю.»
Обратите внимание — человек практически без опыта, зато потративший много времени и усилий именно на подготовку к интервью и именно в Гугле. Мне кажется, ихняя система отбора самонастроилась на именно таких кандидатов, как бы она там изначально не была задумана.
Короче, да, это примено то что я имел ввиду.
А вот изучение алгоритмов, как процесс, вполне себе помогает в повседневной разработке. Позволяет по другому взглянуть на задачи.
А то что алгоритмы забываются, это не проблема. Вспомнить то, что знаешь, гораздо проще, чем это выучить. И опять же есть знание, что в какой ситуации использовать.
И учишься комбинировать структуры. Тот же hashmap где все элементы слинкованы двоичным списком — для LRU кеша, например.
Ну вот я например эту разницу понимаю, но для прохождения интервью требуются более детальные знания, которые без целенаправленного обучения не получить. Тот же LRU кеш — это очень специализированная структура, которая нужна достаточно редко.
Вообще-то, все что я хотел сказать, студенты-отличники имеют по моему мнению некоторое преимущество при прохождении интервью такого типа, может это и неплохо.
Вообще-то, все что я хотел сказать, студенты-отличники имеют по моему мнению некоторое преимущество при прохождении интервью такого типа, может это и неплохо.Как бы оценка в дипломе и должна описывать качество специалиста… что разумеется не всегда так (именно поэтому приходится проводить интервью я не брать на работу тупо на основании CGPA), но если бы корелляции не было совсем — то это обозначало бы, что вся система высшего образования вообще не имеет никакого смысла — а это, всё-таки, уже перебор…
Да. При найме, кстати, на возраст не смотрят.
Я прошёл интервью без подготовки, через 8 лет после универа. Отличником не был :D
Так вот. Нанимают определённых людей, да. Нет, натренироваться на интервью можно, но шансов не так много. В конце концов, 14% ошибки все же остаются.
Ну, я вообще подозреваю что вы несколько особый случай.
А от Гугла у меня осталось именно такое ощущение — что надо именно натренироваться, безусловно в хорошем смысле слова, но все-таки. И рекрутеры этого кстати совсем не скрывают, первым делом дают список литературы для подготовки.
Насчет возраста — вопрос тонкий. Безусловно никакой дискриминации по возрасту нет, ни официально, ни неофициально. Однако существует такая модная практика — кандидат должен пообщаться с каждым членом будущей команды и быть им одобренным. Учитывая что как минимум треть состава джуниоры, может возникнуть конфликт поколений). Вот это не по слухам и не по впечатлениям, я точно знаю.
Однако существует такая модная практика — кандидат должен пообщаться с каждым членом будущей команды и быть им одобренным.Сомневаюсь, что она практикуется в Гугле. Странно сочеталось бы с отсуствием интервьюеров в комитете…
Вот это не по слухам и не по впечатлениям, я точно знаю.Это про Гугл или про какие-то модные стартапы?
первым делом дают список литературы для подготовки.Это логично. Раз большинство готовится — проще дать всем одинаковые материалы и спрашивать как с подготовленных, чем пытаться выяснить, готовился ли человек и почему.
А это происходит гораздо реже, чем просто написание кода
А это происходит гораздо реже, чем просто написание кодаЭто происходит при написании кода. Постоянно. То есть вы видите — на входе массив. И вы написали цикл, а внутри него find. В голове сразу звоночек: «так, у нас задача вроде как линейная, а я тут квардрат, вроде как устроил… что я делаю не так». Смотрим на
find
, обнаруживаем, что он срабатывает один раз или ни разу — успокаиваемся.Шлемиэли встречаются куда чаще, чем нам бы того хотелось, увы — и хочется, чтобы у разрабочика был в голове звоночек, который бы срабатывал, когда он их видит…
Чтоб быстро как достать по имени, так и проитерировать в нужном порядке.
Еще, насколько помню, в stdlib/stl нет эквивалента LHM.
Но в целом — важно знать что они есть, как ими можно воспользоваться, и какая у них сложность под капотом — чтобы конструировать на их базе свои решения осознанно.
При этом обычно не вызывает сложности их написать, зная наперёд какая должна быть сложность и как примерно они могут быть устроены.
А вот понадобится вам чуть нестандартный LinkedHashMap. Например, некотрые элементы нужно поментить, как неудаляемые из кэша. Простым LinkedHashMap уже не сделать. Вернее не сделать быстро.
Два элемента в LRU местами менять смысла не имеет вообще никакого, т.к. это попахивает сортировкой связного списка. Но я согласен что это полезно знать что элементы хэш таблицы можно линковать. И еще полезнее знать что для большинства применений это либо написано либо делается существенно проще чем написание 'снуля'. Снуль вообще плохо обычно получается, особенно на интервью, особенно когда дают доску размером этак метр на метр и предлагают на нем полную имплементацию хэштаблицы впихнуть (даже не линкованной).
Мы с коллегами часто шутили, представляя себе как Ларри и Сергей выходят в море на своих яхтах, пришвартовывают их рядом друг к другу, садятся в дорогие кресла, которые, несомненно, есть у них на яхтах, наливают себе скотч, раскуривают дорогие сигары и рассматривают фотографии гуглеров с такими маленькими ярлычками вроде “был гендиректором в мультинациональной телеком-корпорации, получил MBA в Гарварде, а сегодня работает в техподдержке Orkut“. А затем они заходятся в безудержном приступе хохота, тушат сигары в скотче и чокаются бокалами. Конечно, этого никогда не могло быть, потому что они не курят и не пьют. А впрочем, все остальное вполне правдоподобно”.
был гендиректором в мультинациональной телеком-корпорации, получил MBA в Гарварде, а сегодня работает в техподдержке OrkutНекоторых гендиректоров лучше бы не пускать в техподдержку Orkut, а то всё развалят. Впрочем Orkut всё равно закрылся, так что возможно кто-то пролез…
Но самое важное на собеседовании — узнать как человек думает.
Вообще, оценка предложенного API тоже может дать дополнительный сигнал об опыте и стиле мышления кандидата.
Самое важное здесь: дать одновременно и очень простое задание, чтобы кандидат мог решить и показать базовые навыки, и поднять сложность до того уровня, где кандидат не знает ответа, чтобы он мог показать как он думает.
Так всётаки, вы оцениваете ход мыслей кандидата или предложенное им решение? Что для вас важнее?
Человека нанимают для работы прямо здесь и сейчас — поэтому человек должен уже уметь писать код. Компания ищет людей на долгий срок — а поэтому человек должен уметь думать и учиться. А так же компания ищет людей, кто будет решать задачи, которые еще не решены (иначе зачем их делать?) в том масштабе или аспекте какой требуется. А значит, надо уметь решать те задачи, которые еще не решены. Или тем способом, которым еще не решали. Именно поэтому важно найти точку где кандидат не знает решения, и смотреть, как будет искать выход.
Сведение к знакомому алгоритму? Хорошо.
Преобразование исходных данных? Тоже хорошо.
Попытка придумать новый алгоритм на ходу? И тоже хорошо!
Да, за пол часа (которые обычно остаются на этот шаг) редко кто может придумать что-то совсем прорывное, но этого никто и не ждёт. Важно смотреть как будет идти, сможет ли предложить решение, и сможет ли реализовать предложенное хотя бы в некоем подмножестве.
Получается, что людям вроде меня Гугл не светит?
Если вы не хотите знать, как это устроено и как может быть устроено, какие ограничения и какая сложность под капотом у используемого решения — да, гугл не светит. Но не потому, что вы плохой специалист, а потому, что специалист другого профиля.
Есть вероятность, что эти люди просто не увидели, что "графы, деревья и уникальные сортировки" и прочие "теоретические" вещи нужны.
Мне в своё время (лет 10-20 назад) понадобились:
- Диофантовы уравнения и метод ветвей и границ в оптовой торговле фармацевтическими товарами
- Реализовать хеш-таблицу и B+ tree в 1С: Бухгалтерии 7.7
- Изучить как работает TCP в части three way handshake, модель состояний и работы с SN/ACK SN, чтобы сделать похожий сеансовый обмен между складами
- Решить проблемы отсутствия string builder в 1С 8 (при огромном количестве конкатенаций)
- Оптимизировать решение систем линейных уровнений в расчете себестоимости.
Это просто примеры того, что якобы "теоретические" штуки могут пригодиться в неожиданных моментах "скучных" и "простых" областей.
Я решалку СЛУ еще в колледже вполне успешно писал, но на практике такие вещи не пригодились мне. А там, где могли бы пригодиться, никто не дал бы времени на их реализацию и отладку.
К счастью, с 1С я не работал напрямую. Но по опыту знакомых знаю, что это то еще занятие. Была у нас самописная интеграция с 1С. Приходилось на PHP парсить гиговые XML, которые генерировались часами.
за спиной не стоял менеджер и не спрашивал каждые 15 минут
По-разному было. И стоял, и кричал, и не один менеджер. Но я с такими "менеджерами" долго не работаю обычно. Оно того не стоит.
никто не дал бы времени
Дал бы. Если другого решения нет. С вашими гиговыми XML — если поток XML станет больше, чем может съесть система. Если нерешение проблемы = отзыв лицензии. Обычно получается объяснить, что время нужно. В общем, надо уметь его взять.
решалку СЛУ еще в колледже вполне успешно писал
Вопрос не в "решалке" (это и я в школе писал), она уже написана была, а в том, что матрица большая и в нескольких местах "неудобная" для Гауссо-подобных алгоритмов, плюс надо было не терять точность. В любом случае — это просто примеры.
Но получить такое на собеседовании, когда есть 45 минут и не принято отвлекаться ни на конспекты, ни на поиск — это грозит показаться неопытным человеком.
иногда Google проводит аналогичные кампании
можно об этом подробнее?
Не слежу за ними специально, поэтому как и где их ловить — не знаю.
SWE это software engineer, a SRE это site reliability engineer, верно?
Вероятность прохождения интервью зависит от локации или везде выдерживают одинаковые стандарты?
Важно лишь понять, переспрашивать это нормально.
Основная цель — поддерживать общий уровень одного стандарта, поэтому локация не должна иметь значения.
гляньте на число значков слева — это новые фичи в бета стадии.
Вкратце:

Как нынче с корреляцией результатов интервью и того, насколько человек потом пользу приносит?
частично описано в книге «Как работает Гугл» Эрика Шмидта
86% в книге так же фигурирует)
Вполне можно сравнить итог спустя 1-2 года с предсказанием на приёме на работу.
В гугле все не так. Там не HR, а коллеги пишут отзывы и оценки. А менеджеры потом очень долго и много обсуждают, чтобы всех по организации оценить одинаково.
Да, периодичность ревью вызывает некоторые негативные моменты — типа запусков сыроватых продуктов, чтобы пунктик себе записать, но это редкость.
Вообще, все люди разные — кому-то даже удобнее на доске, кто-то предпочитает писать на компе.
Для телефонных собеседований у нас есть только гуглодока, а при on-site собеседовании как кому удобнее — либо доска либо лаптоп с редактором. Но там просто редактор — из умного только отступы и подсветка синтаксиса, компилятора нет.
Вот кстати очень правильно, что код пишете в гуглдоках
Не у всех так. Когда я столкнулся с написанием кода в google docs я сразу поплыл. Не смог решить 2 элементарнейшие задачи. Потому что весь мозг был занят войной с google docs. То как он реагирует на курсор, на табуляцию и прочие привычные программистам вещи съело все мои мозговые ресурсы. Не смог сосредоточиться. Было также запрещено убирать фокус из таба, чтобы что-нибудь гуглить (хотя гуглить было нечего), это тоже напрягало. В итоге из-за нервного напряжения и дискомфорта я блестяще провалил элементарнейшие задачи.
Если задачей было проверить могу ли я программировать, стоя на одной ноге в болоте, во время шквального ветра, то ребята отлично справились.
В первую очередь именно для того, чтобы дать собеседуемому максимально комфортные условия.
К сожалению, пока условия всё еще бывают очень дискомфортными для некоторых людей.
Я когда собеседовался — у меня были ровно те же вопросы :)
С тех пор на очных появилась возможность использовать ноуты, и я завидую — мне было бы гораздо легче собеседоваться.
Гугл силен поиском, технологиями и много чем еще. А вот поиском сотрудников — явно не силен. Стелят очень много соломки просто потому что людей оттуда крайне сложно уволить (не по закону, а по внутренним полиси). Отсюда и рождаются такие кадавры, как отсутствие интервьюеров в принимающем решение комитете. Просто за гранью добра и зла.
Не ведитесь на бренд, не стройте свои процессы бездумно, просто потому что так же есть в гугле или где-то еще. Просто с их деньгами, они могут себе всю эту ерунду позволить.
Как предполагаете доказывать в суде непредвзятость отказа
Гугл с его сонмом юристов мог бы найти миллион способов это сделать кроме такого очевидно тупого, как у вас в примере. Если бы это делала любая другая компания — ее бы уже давно слили. А тут сила бренда творит чудеса, многие смотрят и цокают языком вместо того чтобы сказать, что серьезно — они долбанулись с наймом на всю голову.
За последние годы я провел несколько сотен интервью и нанял пару десятков человек, рассуждаю именно с этих позиций. Весь описанный в статье подход — одна большая фикция, размывание ответственности и прикрывание задницы, без какой-либо внятной гарантии результата.
Не приглашение на работу, а на собеседование…
Имхо, частая ошибка — профпригодность != пригодность для компании.
У компании есть определённые правила, которые появились не с бухты барахты, не за один день и не на основании ЖЛП (желания левой пятки) кого бы то ни было.
Как бы ни был крут в каком-либо аспекте человек, он может не подходить по другим причинам.
В целом, вопросы, используемые на собеседовании частая практика откатывать внутри на своих, для калибровки снимаемых сигналов и оценки возможных альтернативных решений.
Кстати, еще раз прочитайте статью — вопрос на максимальной сложности никто не должен мочь решить в отведённое время, если только это не его узкая специализация.
Прошло все довольно своебразно, сначала со мной поговорил рекрутер из Лондона, который в итоге отправил на техническое hangouts интервью с инженером из Цюриха.
Только вот отправили меня по направлению software engineer, хотя я сам системщик-эмбеддер.
Это собственно и всплыло в процессе собеседования, инженер даже немного удивился почему меня к нему отправили.
После собеседования мне прислали фидбек, что по направлению software engineer они мне не могут ничего предложить, т.к. я мол embedded/firmware engineer, так они решили. В общем то здраво :)
И добавили еще, что сейчас ищут hiring team по этому направлению и предложили созвониться что бы обсудить всё. Я согласился на созвон и после этого Google пропал, так и не дождался ответа :)
В сентябре правда прислали заполнить анкету небольшую, что бы я дал уже свой фидбек по поводу процессе собеседования и интервьюверов, я там конечно в дополнительных заметках описал возникшую ситуацию.
Так что еще и такого плана бардак небольшой присутствует.
Я проводил собеседование на Embedded — так оно так и было помечено, как embedded…
Вероятно, провалилось в какие-то непонятные щели. Если напишете мне в ПМ, я попробую спросить куда вас потеряли.
Ну либо я попробую добавить со своей стороны — тогда я хоть буду знать что происходит, и смогу дополнительно контролировать.
ААА, начинаю припоминать. Меня человек 5 отреференсило в Гугле и один или два из них обо мне на запрос не ответило. Потом спросил, один сказал, что в отпуске был, другой, что письмо не заметил. Не знаю, но в общем, точно не по технической причине недопустили.
То есть, грубо говоря, у меня сложилось впечатление, что когда я стал писать решение отличное от того, что было у интервьювера перед глазами, он сразу же решил, что оно неправильное и что я ничего не знаю. А так как у меня есть много знакомых, все-таки прошедших это интервью, я в курсе, что для этого нужно долгое зазубривание стандартных всех решений стандартных задач и ровно этого от тебя ожидает интервьювер. Я просто слишком ленивый для этого.
А кто сказал что нельзя? Можно. Используйте на здоровье. Но если вы строите очередь на std::vector — будьте добры ответить о полученной сложности алгоритма с учетом вставки и удаления из головы vector'а.
А если говорите «допустим, у нас есть библиотека для хранения графов, и мы можем использовать функцию, которая даст кратчайший путь для произвольных вершин» — это тоже нормально для решения. Но да, попросить реализовать эту функцию тоже могут попросить. Ну или как минимум описать её сложность.
Если она O(1) — тогда особенно интересно, сколько она по памяти.
Вот документ стандарта 2005ого года, в который stl уже включен www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1905.pdf
Задача у меня была в духе «написать itoa» и естественно, например, предложить использование std::string в качестве выходного значения. Точнее по-моему что-то про массив нулей и единичек и ес-но, я предположил, что хранится он в векторе, а не просто в указателе. Но в известной книжечке приведено решение на указателях, вот и спрашивают тоже с указателями. А иначе как еще можно понять, что решение правильное?
То есть, простыми словами: хороший программист С++ должен знать, что stl — часть стандарта С++98 (да и вообще неплохо бы отличия стандартов друг от друга), а хороший программист, проходящий интервью в Гугл, еще и должен знать, что они не считают, будто stl включен в С++.
google.github.io/styleguide/cppguide.html#C++11
говорит вообще использовать всё что можно из C++11.
Вы говорите stl ключен в C++98, отсюда вывод, что stl использовать можно.
Я подозреваю, что у вас было огромное недопонимание друг друга, а ответ рекрутера не помог понять что же именно пошло не так.
Может просто попробуете еще раз? Будет другие собеседующие и другие вопросы. Если вы считаете, что проблема была в собеседнике — на этом вопрос будет закрыт.
Не надо обманывать людей, будто там реально будет какое-то вдумчивое обсуждение.У меня есть ощущение, что вы провалились как раз на «вдумчивом обсуждении». Потому что для людей, которые на интервью активно используют STL у меня есть стандартный вопрос на 3 минуты: что написано про сложность оператора
std::map:iterator::operator++
в стандарте.И, заметьте, ответ «фиг его знает, я стандарт наизусть не помню» — меня более чем устроит. Вопрос будет лишь слегка переформулирован: «что должно быть написано про сложность оператора
std::map:iterator::operator++
в стандарте при условии, что его писали разумные люди — и почему.»И есть у меня ощущение, что вот на каком-то подобном вопросе вы и «поплыли» и «перешли в оборону» по типа «да нафиг мне это знать и кого это вообще волнует». После чего, как было уже указано — вас попросят на выход… не потому, что вы плохой специалист, а потому, что специалист другого профиля.
Причём, заметьте — это не издевательство. Для этого профиля даже есть название: Application Engineer. Вот ему разрешено произносить сакральные фразы «у нас есть XXX (в данном случае STL) и потому про YYY (не знаю уж чего там было… сортировки, аллокацию памяти или чего ещё) знать не нужно».
А дальше вопрос. Если вы выучили и поняли — то прекрасно, вы прошли. Но это не потому, что зазубрили книжку, а потому, что ее поняли.
А если зазубрили — без понимания — то в этот момент поплывете.
Хм. Удивительно, что вы не знаете, что это часть стандарта. Собственно из-за такого к интервью гугл и есть вопросы. Кажется, что интервью веры просто заучивают одно правильное решение и если ты даёшь отличный от этого ответ — ты в пролёте.
Вы не должны знать все языки досконально, это не суть — для поддержания общего стиля и правильности есть правила review, есть люди, кто могут проверять код на соответствие правилам.
И я писал выше — интервьюеры проверяют как кандидат думает.
Во-1х единственно правильного ответа не существует, во-2х если ты даёшь отличный ответ это хорошо, но не значит, что на этом интервью закончилось.
Оно заканчивается по времени, вопросы резиновые.
Именно поэтому нельзя заучить одно правильное решение.
Например, я не беру единственный оператор в составной {}, но бывают джуниоры, которые даже не понимают, что это вообще, и, опять же, это противоречит google code style, однако никак не противоречит здравому смыслу.
Напишите itoa — те самые пять злосчастных строчек.
Отвечу по порядку: язык выбираете вы сами. Сказали си? Пишите на си. Сказали с++? Пишите на нем.
Вот только зачем вам функция преобразования анси строки в стд строку и стринг в инт, если вопрос был itoa?
Итак, отлично, уточню вопрос: напишите функцию, с тем интерфейсом, который вы считаете оптимальным, которая преобразует число в строку. Язык возьмите какой хотите на выбор из c, c++, python, go, Java, c#. Не используя библиотечные функции преобразований и форматирования строк.
Тогда разумно использовать std::vector для хранения промежуточного результата, не так ли?Нет — потому что это приведёт к лишней аллокации памяти в куче, что расточительно для itoa. Но если вам так хочется… выбор за вами.
Если задано с интонацией вопроса требующего подтверждения просто скожу, хорошо, продолжайте.
Обратите внимание еще раз на формулировку задания, ваш вопрос ничему не противоречит, продолжайте.
Но, разве, это какие-то плохие вопросы?А давайте я тоже — вопросом на вопрос: плохие или хорошие… для чего? Для того, чтобы «почувствовать себя умным и красивым»? Хорошие вопросы. Для того, чтобы устроиться на работу? Плохие, несомненно.
Потому что вместо того, чтобы решить задачу — они нафиг не нужны. И они, как вас чётко и недвусмысленно сказали будут отброшены при написании отчёта — потому что это всё к делу отношения мало имеет.
То есть вы, задавая ваши вопросы, просто сокращаете время, которое вам останется на содержательную часть с 30 минут до 20 или 10. Или и вообще до нуля. С соответствующими последствиями для результатов собеседования.
Хотя в редких случаях они могут дать и позитивный эффект: если вы их задаёте, давая себе отчёт в том, что вы сами у себя крадёте время, и в конце-концов выполните «обязательную программу» и у вас ещё останется время на то, чтобы обсудить разные интересные вещи, связанные с вашими вопросами — ну тут может быть и прибыль для вас получиться… но редко.
А ответы… «Если бы собеседование проводил я»…
Это Си или C++?Выберите что хотите.
И если это С++ не лучше ли конвертить не в ANSI string, а в std::string, у которой уже есть c_str()?Если вам больше нравится std::string — почему нет… «замечание про себя: человек сам себе копает яму, нужно будет не забыть спросить про сложность std::string::push_back и std::vector::push_back».
Ну и таких вопросов у меня еще много.И чем больше вы их задаёте — тем меньше у вас шансов пройти нормально собеседование.
При этом никакой «нелюбви к STL» тут нету: есть банальная неприязнь к любителям «покрасоваться, вместо того, чтобы решить задачу, которую нужно решать». Я таких персонажей не люблю страшно… могу даже представить, что в реальной работе вы ведёте себя иначе… но на всякий случай — буду предполагать худшее.
Тут не нужно какой-то особого «Гуглового подхода». Как и про любую банальность в IT про это написал Спольски:
Главное и единственное требование, предъявляемое к кандидату на работу в нашей компании: он должен
знать свое дело и уметь его делать.
А все ваши вопросы кладут такие маленькие-маленькие крохотные минусики на чашечку «не уметь его делать»…
Да, в реальной работе я всегда задаю подобные вопросы — зачем нам конкретно это надо, почему мы делаем именно так и чем вызваны любые нестандартные решения.Кому вы это задаёте, я извиняюсь? Себе — ну так похвально: так и на интервью сделайте. И расскажите — почему вы сделали так, а не иначе. Интересно будет послушать.
А если не себе — то кому? Это ваша работа и часть ваших должностных обязанностей. А чьих ещё?
Вместо этого нужно просто оттарабанить стандартное всем известное решение и еще несколько таких, получить свой офферДа не получите вы оффер, «оттарабанив всем известное решение», успокойтесь уже. Получите как раз вопросы — на которые вы должны будете ответить.
сидеть в офисе у батареи и радоваться жизни, радостно поковыривая в носу«Поковыривать в носу» не получится — нужно будет как раз регулярно отвечать на те вопросы, которые вы хотите «свалить» на кого-то. Ну, кроме прочих обязанностей.
Первый раз в жизни встречаю человека, который на полном серьезе мне доказывает, что моя обязанность — работать, не задавая вопросов.Нет — ваша обязанность — работать, не задавая дурацких вопросов не по делу. А вопросы, относящиеся к вашей компетенции — задавая себе и отвечая на них самостоятельно.
Работаете в индустрии вывоза больших черных мешков или отмывания странных больших пятен?Не угадали. Работаю в компании, очень похожей на ту, где работает автор статьи. И у нас таки есть много людей, которым можно задавать разные вопросы. Дизайнеры, переводчики, юристы, уборщики и даже грузчики. А также маркетологи и бухгалтера.
Вот только есть проблема: я оччень сомневаюсь, что бухгалтер или грузчик сможет дать вам ответ на вопрос — стоит вам использовать
ANSI string
или std::string
.Если же вы считаете, что должен быть какой-то загадочный архитектор или тим лид, который вам даст ответ на эти вопросы, а вы потом только клац-клац-клац закодируете, как робот — то вынужден разочаровать: у нас таких нет. Как и, подозреваю, у автора статьи.
но то, что надо уметь отделять вопросы релевантные от нерелевантных — это факт. вопросы «где это будет использоваться» — хорошие, позволяют создать API.
вопрос «должен ли я использовать std::vector» — осмысленен в форме «не запрещено ли по условиям задачи».
вопрос «должен ли я использовать std::vector» — осмысленен в форме «не запрещено ли по условиям задачи».Вопрос как «должен ли я использовать std::vector» осмысленен как что-то, что вы проговорите про себя и отвергните.
Почему отвергните? Ну очень просто. Какие есть плюсы у использования
std::vector
? Ну разве что «это модно, стильно, молодёжно». Всё же остальное попадает в графу недостатки: вы используете память «в куче», вы вызываете с десяток реаллокаций, вы усложнаяете машинный код самой функции… и при этом даже не экономите память: на стеке вам будет нужен массив размером в 32 байта, а std::vector
занимает 24 байта плюс ещё минимум 8 байт будет менеджером памяти задействовано… ну и нафига козе баян?Я ещё могу как-то «понять и простить» джуна без опыта, который просто тупо лепит
std::vector
так как про std::array
он не знает, а «сырых массивов» боится… но человек с опытом должен такие вещи замечать.Потом, вам лет через 10 с опытом придет, что людям очень редко надо на самом деле именно то, что они просят.На самом деле для этого 10 лет не требуется. Но непонятно сколько лет требуется для того, чтобы понять что ровно тот факт, что «людям очень редко надо на самом деле именно то, что они просят» обозначает, что попытки выяснить разнообразные хитрые детали реализации у того, кто вас о чём-то просит — бессмысленны, разве нет?
Джоел тут, кстати, недооценивает свой собственный совет, когда говорит: хороший дизайнер интерьера постоянно приносит эскизы клиенту и вещи, из которых он может выбрать — но он никогда не обсуждает с клиентом расположение умывальника… умывальник находится рядом с канализационной трубой и не важно, чего хочет клиент.… нет смысла тратить время на обсуждения, где должен находится умывальник — он должен быть рядом с трубой, даже не начинайте разговор об этом; пусть клиенты изливают свои дизайнерские потуги делая какие-то безвредные вещи вроде изменения своего мнения 200 раз о том, нужно ли использовать для столешницы итальянский гранит или мексиканскую плитку, или норвежскую древесину
Джоел говорит что так нужно общаться с «клиентом или нетехнический менеджером»… но на самом деле с вашими коллегами — подход должен быть тот же. Просто немного по другой причине. Если «клиент или нетехнический менеджер» не может понять ваших рассуждений, то ваши коллеги просто не будут хотеть этого делать. Если они «влезут в задачу», которую делегировали вам, настолько, что будут разбираться там в каждой запятой — то на это уйдёт стольков времени и сил, что им проще будет всё самим сделать… зачем такой человек в команде нужен?
Я никогда не делаю выводов заранее, пишу протокол подробно и целиком, а оценку делаю чуть позднее, читая протокол а не полагаясь на мои воспоминания и ощущения. Это снижает предвзятость.
Кстати, многие американские представители Гугла и прочих компаний в открытую говорят — не выучите материал этих книжке — интервью не пройдете.
khim, которые, конечно же, считают, что вопросы важно и нужно задавать, но только те, которые ожидает интервьювер и на которые заранее знает ответы.Бред какой. С чего вы решили, что мне не нравятся вопросы, ответ на которых я не знаю? Наоборот — если кандидату удаётся указать мне на что-то в тех вопросах, которые я задаю, чего не знаю (такое редко, но случается, я не Бог, всеведением не обладаю) — то это большой плюс. И почти все кандидаты, кому это удалось были приняты в итоге.
Чего я не люблю (и не люблю достаточно сильно) — так это нарушения правила, которое мне очень лаконично описала ещё моя мать в детстве: «не задавай вопрос, на который можешь ответить сам». Потому что это лишняя трата времени.
Что интересно, datacompboy показал, что он, в принципе, считает так же:: а этот вопрос я не совсем понимаю к чему ведёте. Для меня это уже ваше рассуждение в слух, я продолжаю ждать, когда вы будете писать саму функцию… это ведь то же самое, что сказал я, только в «политкорректной форме».
Мы отличаемся, скорее вот в этом месте: я никогда не делаю выводов заранее, пишу протокол подробно и целиком, а оценку делаю чуть позднее, читая протокол а не полагаясь на мои воспоминания и ощущения.
Если честно, то меня это удивляет. Во всех компаниях, где я работал принцип был одинаков: меня просили ответить на вопрос «хотите ли вы увидеть кандидата в вашей команде?» — вот именно так и никак иначе.
О том же пишет и Джоел:
Вместо «Нанимать, но не в мою группу» напишите, не задумываясь, «не нанимать», и все будет в порядке. Даже если вы столкнулись с прекрасным специалистом в одной конкретной области, но для вас не подходящим — это значит «не нанимать». [...] Никогда не говорите «может быть» или «не уверен». Не уверены — не нанимайте. Это проще, чем кажется. Не уверены? Скажите нет. И ещё, если вы занимаете выжидательную позицию, это тоже значит «не нанимать». Никогда не говорите: «Хорошо, я думаю, мы его возьмем, хотя есть некоторые сомнения насчет...». Это тоже «не берем».Если кандидат лично мне не понравился, но остальные от него в восторге — его ведь возьмут всё равно, но если вопрос стоит как «хочу ли вот конкретно я работать бок-о-бок вот конкретно с этим кандидатом»… то эмоции, которые у меня вызывает общение с ним — чуть ли не важнее объективных знаний и умений.
Просто надо заранее обсуждать формат собеседования, что, мол, спрашивать будем вот по этим вот лекциям.Кто вам такое сказал? Единственное ограничение — интервью длится 45 минут или час, реже 2-4 часа (в разных компаниях по разному, но везде, где я собеседовал был лимит) и, соответственно, времени на обсуждение «погоды на Марсе» у нас нет — ну так и в реальной разработке «лишнее» время редко когда бывает.
И что сам формат собеседования по времени реально не предусматривает достаточно времени для вдумчивого обсуждения задачи.Вы хотите сказать, что вам не хватит 45 минут времени (более короткие интервью мне не встречались), чтобы «вдумчиво обсудить» itoa? А сколько времени вам потребуется на «вдумчивое обсуждение» реальных задач? Год? Или два?
Так что результат был бы «нет».
И, прошу заметить, stl тут не при чем.
Но вы не хотите писать даже тот код, который считаете красивым и опрятным на современном C++.
Проще говоря, если вы пришли на собеседование на кодинг, где заранее было оговорено что надо будет написать десяток строк (а об этом написано — «Be prepared to write around 20-30 lines of code in your strongest language.») с желанием просто поговорить — я понимаю, почему собеседование закончилось неудачей.
www.geeksforgeeks.org/implement-itoa(и я могу его воспроизвести по памяти, так как писал его еще мелом на доске, когда Ельцин был президентом). И я знаю, что это именно то, что ожидается. Просто этот код мерзкий. Ни один здравый программист, размышляя с нуля не будет писать такой код. Просто есть такая древняя традиция, лет 30 которой уже, задавать вопрос по itoa (который некорректный сам по себе) и отвечать таким говнокодом, делая вид, что это С++
Но просить написать такой код это примерно как, нанимая электрика, дать ему два провода и сказать — «сделайте нам скрутку», ожидая, что сейчас от зачистит провода зубами, скрутит руками и сверху изоленточкой. Нормальный электрик вас просто пошлет с такими заданиями. Вежлиый начнет спрашивать, из каких металлов провода, на какой ток расчитаны, какой толщиной, почему нельзя их спаять, можно ли использовать термоусадочные материалы и прочее.
Интервьювер наверняка скажет, что электрик совсем ничего сделать не может, то, что даже ребенок умеет. Но понимаете, и электрик скорее всего вежливо просто обойдет такую контору стороной, если у него есть выбор работать там, где провода пальцами не скручивают.
Если вы вместо этого "говнокода" напишете рабочую версию с std::string::push_back и std::reverse, вам это зачтется за правильный ответ, если, разумеется, сможете объяснить сколько это будет работать и почему.
— постановка задачи «написать itoa на С++» некорректна
— постановка задачи «написать int to std::string на C++» корректна
— постановка задачи «написать int to std::string на C++ без использования ф-ий std::string» некорректна
У вас постановка задачи — написать itoa. На вашем любимом языке. Например, в проекте нужно записать число в нестандартной кодировке (вместо 0 — a, вместо 1 — b, и т.д.)
на C++ без использования ф-ий std::string
Где вы это требование взяли? Я вам написал выше — используйте любые методы std::string и стандартные алгоримы. Все, кроме, собственно to_string.
Все, кроме, собственно to_string.А чем to_string не угодил? Он же только с основанием 10 работает. Не очень понятно куда его засунуть и зачем, но если удастся его как-то поиспользовать… будет интересно посмотреть…
Касаемо «ожидания готового кода», мне его скопипастить, чтоли, из приведенной выше ссылки? Я написал, что именно это подразумевается под правильным ответом на вопрос «напишите itoa».
Касательно требования «нельзя использовать ф-ии string» — его мне высказал автор статьи
Реально я более, чем уверен, что std::to_string реализуется достаточно муторно, но можно это сделать на коленке примерно так:
string to_string(int x)
{
if (x < 0)
return string('-') + to_string(-x);
const int BASE = 10;
string s;
for(; x > 0; x/=BASE)
s += digit_of(x%BASE);
return reverse(s);
}
1. Для нуля будет пустая строка.
2. Для MIN_INT вы вызовете UB и, скорее всего, в реальной реализации переполните стек.
Затем стоит спросить, каким образом вы могли бы убедиться, что в функции нет ошибок; и какая получилась сложность функции по скорости и памяти.
После чего перешел бы к основному вопросу собеседования.
Гугл известен тем, что платит наибольшие деньги и я буду очень рад, если многие, читающие этот форум, смогут туда устроиться, тем более, что это заграницей. И я надеюсь наш разговор будет полезен всем тем, кто еще не проходил собеседования, для того, чтобы примерно оценить ожидания собеседующего и примерное настроение при разговоре.
«a» в itoa означает ANSI stringНет. A обозначает «ASCII» — можете открыть man page из первой версии UNIX и убедиться.
Это Сишный формат строк. У С++ свой формат строк. Постановка задачи некорректная. Корректная — написать string to_string(int)Извините, но это бред. По вашей логике atoi в Python тоже с сишными строками работает? Или в Go? Как насчёт rustа? Весь мир шагает не в ногу, один вы, такой красивый — в ногу?
Я написал, что именно это подразумевается под правильным ответом на вопрос «напишите itoa».Нет никакого «правильного» ответа. Есть код. Который вы должны написать. И который можно обсуждать. Вы этого не сделали — так что и обсуждать нечего.
Если вашей целью прихода на собеседование не было желание устроиться на работу, а было желание потроллить интервьюеров — вы этой цели достигли прекрасно. Понятно, что на работу вас, после этого, не возьмут, но это же и не было вашей целью — так что единственная проблема заключается в том, что вы потратили изрядное количество времени других людей. Не очень понятно — зачем вам это нужно, но у разных людей — разные хобби…
Извините, но это бред. По вашей логике atoi в Python тоже с сишными строками работает? Или в Go? Как насчёт rustа? Весь мир шагает не в ногу, один вы, такой красивый — в ногу?
То есть во всех этих языках реально конвертится в null-terminated строку или все-таки в нативный формат? Спрашиватель сей задачи ожидает ответ для null-terminated Сишной строки или нет?
Нет никакого «правильного» ответа. Есть код. Который вы должны написать.
Обычно люди с таким менталитетом идут в армию. Там им удобно и понятно. Им сказано подметать плац ломом, значит, надо подметать плац ломом.
То есть во всех этих языках реально конвертится в null-terminated строку или все-таки в нативный формат?Я уже, кажется, говорил, что я думаю по поводу вопросов, на которые вы сами можете ответить (если не можете — то тем хуже для вас, извините).
Спрашиватель сей задачи ожидает ответ для null-terminated Сишной строки или нет?Спрашиватель сей задачи примет ответ, работающий с null-terminated Сишной строкой — но отсюда вовсе не следюет, что никакой другой ответ принят не будет.
а вот из-за подобного «эстетства», мы и имеем современный, выражаясь вашим языком, говнософт, тормозящий и непомерно жрущий память на элементарных операциях. зато, небось, в исходниках всё красиво, по последней моде
другой вопрос, только, почему как отметили почти в самом первом комменте, сервисы у гугла выходят точно такими же дико тормозящими и безмерно потребляющими память, при том что на интервью задают вопросы и обращают внимание на такие правильные вещи
нужно будет не забыть спросить про сложность std::string::push_back
Мне вот любопытства ради в каком STL и в каком компиляторе на практике есть реализация со сложностью за линию? В вашей практике такое сочетание было?
Чисто любопытства ради.
Это в любом, когда realloc требует перемещения в памяти же.
capacity
, так что очень многие реализации делают реаллокацию на каждый push_back
, что может привести к тому, что алгоритм, сносно работающий на std::vector
, будет тормозить на std::string
.Однако к нашему примеру это не относится, так как тут у нас не более 32 символов и мы, скорее всего, «лишних» движений делать не будем. При этом если мы не будем использовать совсем уж маленькие
radix
ы, то мы за предел в 22 символа не вылетим и нас «спасёт» SSO… но спасёт не до конца: ровно из-за той самой SSO мы будем много лишних операций в std::string::push_back
иметь.Потому — лучше, всё-таки,
std::array
или «сырой» массив…у строки нет capacity
Лолчто? N4713 24.3.2.4
size_type capacity() const noexcept;
9 Returns: The size of the allocated storage in the string.
std::vector
(что фактически лишает их смысла, ну да ладно).И, действительно, aeyrwbz
std::string::capacity
была даже в C++98/C++03, но так как она всё равно не гарантировала ничего, то использовать str::string
было бессмысленно.А вот в C++11
std::string
это стало иметь смысл. И, возможно, даже имеет смысл использовать std::string
напрямую внутри itoa
если мы потом всё равно хотим возвращать std::string
. Спасибо за дельное замечание!P.S. Смысла использовать
std::vector
«внутри» для реализации по прежнему нет даже в C++11Выше давали ссылку на www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1905.pdf
и там сказано:
Effects: After reserve(), capacity() is greater or equal to the argument of reserve.
Впрочем, я не специалист по стандарту плюсов, просто помню что оно есть уже давно
Как это не гарантировала?Она, несомненно, гарантировала, что одна цифирька больше другой. Но поскольку были разрешены разного рода строки со счётчиками и чуть ли не GC, то никаких гарантий на то, что если ты сделаешь
reserve()
, а потом начнёшь строку менять, то у тебя аллокаций не будет и будет какая-то временяемая сложность — не было.Впрочем, я не специалист по стандарту плюсов, просто помню что оно есть уже давноОно есть начиная с GCC5. До этого — очень долго были COW-строки с совсем другими характеристиками, чем требуется в C++11.
Вообще, о том, что «всем давно известно, что в Гугле stl нельзя использовать на интервью» можно догадаться
Что? Первый раз слышу. Сам на интервью использовал несколько раз. Более того, я еще и порядок аргументов напутал, интервьюверов это не волнует вообще.
интервьюверу мог не понравиться мой коммент,
Интервьювер может написать об этом в своем отчете, но все-равно, на это будет смотреть комитет. Так что это не просто мнение одного чувака, которому что-то не понравилось. С ним, как минимум, еще несколько человек согласилось.
Комитет рассматривает телефонки тоже? Я думал только онсайт. У них судя по всему такой поток телефонок, что вообще отбирают скорее по тембру голоса или еще чему-то загадочному.
Вообще, я всегда влет проходил телефонки во всякие Фейсбуки-Амазоны. Когда не прошел с Гугл, думал — ну, не понравился челу, бывает. Когда второй раз не прошел, опять же, решив все, понял, что Гугл куда более загадочный зверек, чем пытается казаться.
Не подскажете с какой целью?
Возможно, чтобы исключить этих людей из круга тех, кто должен вас собеседовать — это будет неэтично и предвзято.
Но чтобы этим интересовались на каждом интервью… странно это. Не ожидал от Гугла.
Можно сформулировать как “представьте, что наш сервис для обработки запроса проверяет существование внешнего объекта. Как можно ускорить обработку?” — ожидая очень очевидное предложение “давайте просто кешировать результат”.
Не понял, что именно предлагается кэшировать, результат проверки существования внешнего объекта? Но если его кэшировать, то как можно быть уверенным, что с момента прошлой проверки внешний объект все еще доступен? Если такая проверка есть, вероятнее всего доступность объекта критична и следует минимизировать время между проверкой и использованием. Кому может прийти в голову кешировать результат проверки?
Прекрасный вопрос! На котором можно обсудить ttl, что именно кешировать — положительные или отрицательные ответы.
И чтобы продолжить беседу, запостулируем, что отрицательный ответ получается быстро, но его не надо кешировать, а положительный долго, но его можно запомнить, так как объекты не удаляются.
А что не так с самым простым ответом про кеш?
Язык Java.
Используем стандартный потокобезопасный ConcurrentHashMap. Получаем достаточно быстрое добавление. Добавление будет на порядок быстрее чем получение информации о статусе объекта. Поиск информации об объекте и получение будет просто быстрее некуда. TTL обрабатываем неторопясь отдельным потоком или потоками. Тоже самым стандартным способом hashMap.foreach(...). Возможны небольшие нарушения TTL, но такое обычно не критично. Если критично подгоняем TTL. Так чтобы время обработки всей коллекции + наш поправленный TTL были равны требуемому TTL.
Самое время задать вопрос, который я уже упоминал в статье: а как быть, если мы хотим контролировать максимум памяти, потребляемую этим кешем?
До TTL еще далеко, у нас уже 1000 ответов в кеше, и нужно сохранить. Просто добавить — их станет 1001.
Требования по памяти приблизительные. Контролировать хотим, но небольшие отклонения не критичны.
Объем кеша такой что проход очистки по ttl по всем элементам занимает небольшое, по сравнению и с ttl и со временем когда кеш переполнится, время.
Тут надо уточнять насколько равномерно используются элементы кеша.
Предположим что очень неравномерно. К одному элементу единицы обращений за время жизни, ко второму тысячи. Соответственно мы хотим хранить активно используемые элементы до ttl, остальные можно выкидывать по памяти.
Добавляем в объект хранимый в кеше счетчик обращений. В функцию чистящую по ttl добавляем проверку на максимальный объем и при подходе к нему или превышении чистим самые неиспользуемые объекты. Так чтобы осталось процентов 80 (или сколько хотим) от максимально возможного. Поиск самых неиспользуемых и удаление тривиальны. По ресурсам или память для хранения и удаление при том же проходе. Или вообще без затрат: При первом проходе только ищем граничный по обращениям и при следующем цикле проверки ttl заодно удаляем все что ниже него. Память будет немного плавать, но сильного превышения не будет.
При равномерном обращении все аналогично только критерий удаления по памяти это время оставшееся до ttl. Других критериев у нас нет. При проходе очистки ищем граничный и при следующем удаляем все что ниже него.
Что вы сделаете, если верхнее требование по памяти критичное?
Удаление и по ttl и по памяти требующее полного прохода O(n). Зато не влияет на основные процессы и работает независимо.
Отслеживание памяти при втором проходе ничего.
Тогда при равномерном использовании и удалении самого старого берем LinkedHashMap и просто удаляем первый элемент. Раньше добавлен, значит у него минимальный остаток ttl. Сложность o(1).
При неравномерном использовании и удалении самого малоиспользуемого все плохо. Нам надо в момент любого добавления знать какой элемент должен пойти на удаление. Заводим рядом TreeMap с объектами вида (id, количество обращений) и и компаратором по количеству обращений. Обновляем его одновременно с обновлением основного hashmap. Сложность вставки сильно возрастает o(logn). Сложность удаления o(1).
При массовых вставках и редких ситуациях переполнения по памяти можно сделать совсем просто: При достижении лимита сортируем исходный hashmap и удаляем самый малоиспользуемый. Долго при переполнении, зато вставку не замедляем и гарантируем не переполнение памяти. В сценарии редкого переполнения должно работать неплохо.
O(1) это для обычной вставки или удаления первого элемента LinkedHashMap
Зачем получать? Я честно нагуглил. Помню я это примерно так:
1. Это очень быстро вообще не паримся.
2. Это быстро. Если надо чтобы очень быстро было проверить это место.
3. Это медленно. Будет тормозить.
4. Это нереально медленно. Переписать при первой возможности.
Для собеседования в Гугле естественно не подойдет, но для повседневности достаточно.
Итого, как же выглядит итоговое решение, которое даст O(1) на вставку и O(1) на получение, гарантировано без переполнения и при этом с семантикой удаления того, которым не пользовались дольше всего вперед?
Я схитрил и прочитал про LRU cache. Я в восторге. Предельно просто и эффективно.
Итого:
- у нас есть hashMap, который хранит сами кешированные данные и данные TTL
- у нас есть queue в виде двустороннего связного списка
- при запросе по ID мы проверяем его наличие в hashMap, т.е. O(1)
- при удачном запросе (hit) мы помимо того, что возвращаем элемент из hashMap, ещё и вырываем его из списка помещая его в голову (размыкаем цепь и помещаем в начало), таким образом поднимая его "популярность"
- при записи в кеш мы проверяем не привышен ли capacity кеша, если нет, то пишем данные в кеш, а ссылку на эти данные ставим в голову
- если же capacity превышен, то в принципе всё тоже самое, кроме того, что 1 элемент из хвоста очереди (+ из hashMap) мы убираем
- итого запись O(1)
- память O(n), если capacity достигнут
Но тут ни слова про TTL. Нууу… Мне кажется, что можно вообще не заморачиваться с ним. Просто хранить его вместе с данными в hashMap. А при HIT-е просто проверять. Если данные устарели, то стираем его из очереди и хешмапы, и ведём себя будто его и не было вовсе. Суть не меняется. Из недостатков: мы храним устаревшие значения дольше, чем в идеальном случае, но по факту нам плевать, т.к. если запись непопулярна, то она сама по себе улетит в трубу при работе с кешем. Если же запись популярна, то кеш обновится во время очередного HIT-а. Логично?
Никаких потоков и прочего не трогал, т.к. в моём уютном JS обычно таких педалей нет :)
Например — а как быть, если ограничение по памяти в количестве байт, а не числе объектов? А если объекты могут быть СИЛЬНО разных размеров? пара мег / сотня байт, например?
А если мы всё равно хотим сохранить примерно О(1)?
Ну хотя бы амортизированно?
Ну хотя бы гарантировать отсутствие OOM?
И тааак даалее.
а как быть, если ограничение по памяти в количестве байт, а не числе объектов?
А структура, которую мы планируем хранить — фиксированного размера? Если фиксированного, то вроде всё просто. Можно даже заранее посчитать кол-во элементов, которые мы можем хранить.
А если объекты могут быть СИЛЬНО разных размеров? пара мег / сотня байт, например?
Вот тут сложнее стало. В JS нельзя написать что-то типа getSize(object) и получить его размер. Но наверное мы говорим о каких-то языках, где можно. Буду исходить из того, что такая возможность есть.
Первое что приходит в голову — при добавлении\записи значения — удалять с хвоста элементы до тех пор, пока новый не влезет. Но тут никаким O(1) и не пахнет. Условно если записать в кеш элемент размером почти с кеш, то придётся выпилить все элементы, что там уже были.
Судя по вашим словам — можно это сделать за O(1). Но я не представляю как. Ведь даже если нам не надо искать — на каком элементе можно остановиться, нам ведь всё равно надо их из hashMap-ы удалять. Поочерёдно. А ведь там ещё небось какие-нибудь деструкторы могут быть (честно говоря ничего не понимаю в этом), и просто разом затереть память нельзя. Честно говоря я не знаю, как это сделать за O(1). Ну можно питание сервера отключить.
Ну хотя бы гарантировать отсутствие OOM?
Имеется ввиду недопустить превышение лимита размера кеша? Просто ООМ можно получить, скажем, на загрузке этого самого элемента при MISS-е по сети… Мало ли, может там нам гигабайт подсунули. Тут уже нужно поточно по чанкам грузить данные от источника данных и прерывать если с памятью беда. Но я думаю вопрос не об этом. В таком случае нам достаточно удалять из кеша элементы до того, как в этот кеш новые писать.
Всё, не сдал? )
см. Методы Кристобаля Хунты.
:) кто сказал, что решение существует?
А вот метод поиска решения отличный.
Когда мы начинаем считать размер, O(1) вообще возникает вопрос, можно ли получить. Надо еще учесть, от чего считается O. Если нам становится важен размер объектов (кстати, даже в JS косвенно его можно оценить — например, по длине хранимых строк), то мы в общем-то добавляем не за O(1), а за O(size).
И тут возникает хороший вопрос… А ответ мы вообще, копируем или отдаём по ссылке? Объект в кеше мутабельный или нет? Если мутабельный, то мы должны его копировать, и тогда получается что у нас в принципе и get операция уже O(size). Ну и очистка туда же идёт.
Для гарантии отсутствия OOM как минимум нам понадобится запас по месту как минимум на один самый максимальный объект [мы же вообще еще не обсуждали многопоточность доступа, да? :)], ну и опять же — можно еще обсудить а где и сколько раз данные по сети пришедшие будут скопированы, посмотреть знает ли кандидат разницу по памяти между «вычитали N мегабайт из сети» и «обработали N мегабайт из сети».
Например — потоковая обработка позволяет ограничить футпринт на обработку по сути одним буфером, но если мы начинаем кешировать… А если у нас по пути пара контейнеров… А если где-то они мутабельные… А если… :)
Это всё не вопрос на «сдал/не сдал»! Это не экзамен, тут важно думать, а не помнить.
Хаха, у меня примерно те же мысли крутились в голове. Но я постеснялся их выражать вслух :) Ещё примут за сумасшедшего. Мол мы тебе дали конкретную задачу, а тебя куда-то понесло…
Так то да, когда мы рассматриваем объекты сильно разного размера, то bigO надо рассматривать уже совсем по-другому. В точку ;) Касаясь ООМ возникает много вопросов к тому, как мы эти данные вообще получаем… Даже элементарно, если мы их чанками грузим по сети… то выдаёт ли нам сервис их размер заранее, или нет. В общем тут много чего всплывает.
В общем от меня бы требовалось уже просто высказывать свои соображения по этому поводу?
кстати, даже в JS косвенно его можно оценить — например, по длине хранимых строк
Ну это полная дичь, если честно :D
Нет, я не стал рекрутером.
Я уже писал, и ещё раз скажу: вполне себе обычный собес. Как обычно, многое зависит от умения конкретного человека проводить собеседования, но не все могут, увы :-}
datacompboy а как вас готовят к проведению интервью? Понятно, что какое-то время вы ходите на второй позиции, а дальше? Есть ли возможонсть отказаться от проведения интервью в принципе, или это обязательно?
Перед тем как можно начать интервью — надо пройти тренинг, разумеется. Он не обязательный. Не хочешь — не собеседуешь. Даже если походил и надоело — выставь в настройках доступности для интервью 0 и все.
Что такое «ходите на второй позиции»?
Первый человек собеседует, второй молчит, может быть что-то отмечает у себя.
По крайней мере, у меня на интервью второй парень сделал ровно два действия:
- поздоровался
- подтвердил, что основной интервьювер пишет не в тот документ
Не хочешь — не собеседуешь.
А какова мотивация собеседовать людей в другие команды?
Фаза Shadow важна для калибровки навыков — тогда вы оба пишете отчет по одному и тому же интервью никак не договариваясь, независимо, а потом уже обсуждаете чтоб понять оба ли одинаково поняли и оценили произошедшее.
Я, разумеется, уже автономен и если надо тот самый «более опытный».
А какова мотивация собеседовать людей в другие команды?
А мы собеседуем не в команды, а в компанию. Так что вполне можете встретиться и в одной команде через год-другой :)
Вы были на телефонном или на очном собеседовании? Они все были на динамическое?
Вы что-либо изучали за год между попытками?
Моя любимая сводится на графы (но есть и альтернативные решения, всегда люблю, когда их находят), но я держу на готове еще вопрос на динамику (использую, если никто другой на динамику не подготовил) и есть на комбинация структур данных, если и графы и динамику уже взяли.
У нас работа совершенно не сверхестественная, вопросы соответствующие.
Если задача на 20 минут вас злит — то нам просто не по пути. В конце концов, собеседоавние — это диалог. Не только компания оценивает кандидата, но и кандидат оценивает компанию. Поэтому это нормально, что кому-то этот процесс не нравится, и он делает для себя пометку «тут не работать». Вы только что сэкономили себе пол-года год жизни! Вы же могли иначе начать тут работать, и это было бы не то, что нравится.
Я думаю, речь идет не про одну задачу, а про весь процесс интерьюирования. Перезвоны с HR, телефонное интерьвю (все исключительно в рабочие часы), поездка в офис, весь день там — нормально так потраченного времени набирается.
> кандидат оценивает компанию
Да, в теории. На практике, все люди у меня на собеседовании были из других команд, ничего путного сказать не могут (либо NDA, либо не знают), единственное — офис посмотреть.
На практике, все люди у меня на собеседовании были из других командГугл начал набирать людей в команду? У меня было ощущение, что он всегда нибирал в Гугл, а не в конкретную команду… а команда и проект — это уже потом… отсюда, кстати, многие объяснимые особенности интревью-процесса.
Объявления о работе всегда про конкретную позицию и команду. Какое мне дело, грубо говоря, как все устроено в YouTube, если позиция в Android.
Единственное, что я узнал о компании — это везде open space. Можно ли по этому оценивать компанию — не знаю.
Динамическое программирование — это не просто академическая игрушка и головоломка-пароль, чтобы пройти в гугл. Я на практике как раз в гугле применял. Пару раз вместо полного 2^N перебора можно было сделать что-то квадратичное или кубическое.
Поэтому стоит его ожидать на интервью и дальше и подучить его.
Поэтому стоит его ожидать на интервью и дальше и подучить его.
Мне кажется слово "подучить" тут не очень подходит. Это не какой-нибудь React освоить. Это, ИМХО, на пару лет по выходным...
Ну нет. Идете на тот-же leetcode, и прорешиваете задачки с подсказками. Пару вечеров в неделю, да выходные — за пару недель можно натаскаться. Там же основная идея одна и та же. Осталось только натаскаться угадывать, что взять параметрами.
Я так уже делал. Решил порядка 180 задач. Многие из них у меня отнимали по многу часов. Чем глубже я углублялся, тем сложнее становилось. Тем больше я понимал какой объём работ впереди. И судя по всему на собеседовании в google меня попросят решить не задачу в стиле:
- проверьте правильно ли расставлены 3 вида скобок в строк
- верните true если число N можно получить путём произвольного сложения чисел 6, 9, 20
А что-то сильно более лихое. Ну т.е. что-нибудь, что я может и решу, но не за 20 минут под наздором. Или я не прав и сгущаю краски? )
Ну вот вам пример запрещенной теперь к интервью задачи (потому что утекла) — меня именно ее пару лет назад и спрашивали:
У гугла куча офисов в разных странах. В разных странах разное количество праздников. Можно раз в месяц перелетать в другой офис (в конце месяца). Как и куда лететь, чтобы максимизировать количество выходных? Дано сколько выходных в каком офисе в каждом из 12 месяцев. Еще дан список возможных перелетов офис->офис. Верните список из 12 офисов.
Из уточнений — не обязательно перелетать, можно сидеть в офисе несколько месяцев подряд; нельзя делать несколько перелетов подряд, т.е. лететь только без пересадок. Перелеты однонаправленные (если дано A->B, то не обязательно можно лететь B->A); Вам дан начальный офис, заканчивать год можно где угодно.
Ненамного сложнее того, что вы упомянули, но ничего сверхъестественного. Решение — буквально 10 строк. Да, тут еще как-бы и граф есть но ДП на графах — тоже стандартная вещь.
Звучит вполне подъёмно.
- рекурсия, каждый следующий шаг которой, это след. месяц
- перебираем из каждого офиса все те офисы, куда можно из него прилететь, без иключения
- на каждом шаге рекурсии по итогу вычислений запоминаем лучший локальный результат (аля: с 5-го месяца из офиса 17 до конца года можно набрать 12 выходных согласно такому то маршруту) в кеше
- соответственно на каждой итерации предварительно проверяем результат в кеше
- в финале пробегаем по первому уровню кеша и берём максимальный результат
Такой ответ устроил бы собеседующего? Это обязательно воплощать в коде или можно "на словах"? Просто придумал как решать я быстро, но боюсь написать рабочее решение за 30 минут я не успею.
Примерно такой ответ и был и устроил собеседуюшего. Я правда, развернул рекурсию и делал двумя циклами в матрице.
Только надо не забыть, что можно в офисе остаться при переборе следующего и в финале не перебираем первый уровень — нам же дан стартовый офис.
Конечно, надо в коде. Но это 10-20 строк всего. Чего тут за 30 минут можно не написать? Код не надо компилировать, если там будут опечатки — это не минус для оценки. Если забудете что-то (напрмер, остаться в офисе) — интервьювер даст подсказки, типа "а вы нечего не забыли? А если такой тест?".
//int[i, j] holidays - сколько выходных в офисе i в j месяц
//bool[i, j] fligths - есть ли перелёт из офиса i в j
//startOffice - начальный офис
static int[] Solve(int[,] holidays, bool[,] flights, int startOffice) {
int[,] h = new int[12, 12]; //h[i,j] - как много выходных можно получить, если сейчас i-й месяц и мы находимся в офисе j,
//отрицательным значением пометим если мы этот офис не можем достичь к месяцу i
//можно обойтись и двумя массивами, т.к. на текущем месяце нам нужны данные только из предыдущего.
//но сначала я бы написал именно такой алгоритм.
int[,] p = new int[12, 12]; //p[i,j] - из какого офиса мы переехали в j в i-м месяце;
for (int i = 0; i < 12; i++) {
for (int j = 0; j < 12; j++) {
h[i, j] = -1;
}
}
h[0, startOffice] = holidays[startOffice, 0];
//i - индекс месяца
//j - индекс офиса отправления
//k - индекс офиса прилёта
for(int i = 1; i < 12; i++) {
for(int j = 0; j < 12; j++) {
if(h[i - 1, j] < 0)
continue;
for(int k = 0; k < 12; k++) {
if (!flights[j, k] && j != k)
continue;
if (h[i, k] < h[i - 1, j] + holidays[k, i]) {
h[i, k] = h[i - 1, j] + holidays[k, i];
p[i, k] = j;
}
}
}
}
//находим где больше выходных в конце года
int bestOfficeAtTheEnd = 0;
for (int i = 1; i < 12; i++) {
if (h[11, i] > h[11, bestOfficeAtTheEnd]) {
bestOfficeAtTheEnd = i;
}
}
//восстанавливаем ответ
int[] result = new int[12];
result[11] = bestOfficeAtTheEnd;
for (int i = 10; i >= 0; i--) {
result[i] = p[i + 1, result[i + 1]];
}
return result;
}
Один мелкий недочет — в интервью бы исправилось сразу при написании — кто вам сказал, что офисов 12? Их N. Но это у вас просто 12 в нескольких местах на N поменять надо.
Решение отличное. Вы даже учли случай, когда из начального офиса нельзя никуда улететь вообще.
Если осталось время на интервью, я бы попросил вместо коментариев сделать имена переменным осмысленные, но это не критично. Еще обязательно спросил бы про сложность вашего решения. Может быть обсудил бы еще, почему вы считате, что можно -1 использовать для недостижимых позиций (очвидно — мы счиатем, что не может быть отрицательного количества выходных, поэтому -1 мы в достижимых позициях не получим никогда. Но хотелось бы это услышать на интервью).
Сделать количество офисов переменным — это логичный шаг, но я ориентировался на то, что сказано, что их 12. Ввести переменную — не проблема. Не был бы я уставшим, скорее всего начал бы своё решение с ввода константы const int officesCount = 12. А не просто использовал число. Считаю, что это мой косяк.
Время на интервью точно бы осталось, т.к. на это решение я потратил 10 — 15 минут. Идею придумал сразу.
Про осмысленные имена переменным — вопрос интересный. В разных фирмах ко мне были разные требования к именам переменных и оформлению комментариев. Такой код я в мастер не отправил конечно же, но на собеседовании на листике так бы и написал.
Сложность. Если число офисов N, то сложность O(N^2).
Про -1 я бы рассказал на этапе написания ещё.
У меня есть опыт прохождения многоуровневых собеседований в крупные международные компании, потому примерно представляю что и когда бы говорил. Но волновался бы жутко! :)
Летом попробую к вам в фирму отправить заявку. Может что-нибудь получится.
PS: Писать что-нибудь уставшим в пятницу вечером полезно, увеличивает выносливость. Когда я занимался олимпиадным программированием, у нас были специальные 2-часовые туры из небольшого количества сложных задач вечером, после учебного дня, для симуляции условий конца контеста.
В статье приведен пример вопроса — «напишите LRU кеш».
Вариант вопроса на динамику (тоже больше спрашивать уже не должны) — организуйте структуру данных, которая позволит записать число по заданным координатам, и запросить сумму квадрата между двумя произвольно заданными точками.
Обратите внимание на пост — вопрос был задан прямо вот так. Я обычно задаю в менее явной форме, чтобы дать 2-3 минуты кандидату подумать и уточнить задачу, чтобы понять как он думает о проблемах возникающих; но если сведение к этому не было предложено в эти 2-3 минуты — ничего страшного, просто скажу что «это можно сделать, например, используя структуру данных» и далее по тексту. Кстати, еще раз: это НЕ плохой сигнал. Ничего плохого не произошло :)
Пример вопроса в форме задачи, который должен сводиться к вышесказанной — «Представьте, что вы запускаете систему слежения за бюджетом в компании. Каждый сотрудник вносит свои затраты по множеству подкатегорий используя супер-навороченный сканнер чека. Они, разумеется, сканируют и старые чеки. Финансовые же аналитики заинтересованы в анализе различных срезов — по отделам и категориям. То есть им надо то периодически посмотреть суммарные затраты на мышки в IT, то затраты на коврики у геймеров. Представьте что это всё вмещается в память, как вы организуете данные для удобства формирования таких отчетов?»
Спасибо за задачу. Вопрос про квадраты интересный. Открыл Excel для "рисования". Стал думать. Пришёл к следующим выводам:
- сумму любого прямоугольника можно рассматривать как сумму от дальней точки до 0, минус две боковых прямоугольника, плюс один угловой.
- можно в этой структуре хранить не только величину самой ячейки, но и сумму от 0 точки
- при UPDATE операции O(N^2) мы увеличиваем значения всех ячеек правее и ниже
- при QUERY просто считаем ту сумму и разность 4 прямоугольников до 0. Итого O(1)
Я прошёл? :) По вашей ссылке в коде явно не то, что я бы сделал. Там какие-то сплошные вычисления сумм...
А можете подумать, как найти решение сбалансированное по стоимости запросов и обновлений?
Подумал. Придумал одно странное решение, которое долго кодить. В общем:
- берём M=sqrt(N)
- создаём новый массив M*M
- в этот массив мы пишем всё тоже, что и в алгоритме выше, но теперь каждая ячейка такого массива содержит в себе сумму элементов которые она обобщает
- в оригинальном N*N массиве храним всё также как и согласно оригинальному алгоритму, но берём 0-ую угловую точку не по 0:0 координате, а по координате их обобщённого квадрата.
- в итоге UPDATE у нас сводит к тому чтобы поправить значения внутри под-квадрата и поправить итоговые суммы у внешних квадратов что правее и левее, не трогая их содержимое
- QUERY сводится к двум операциям по складыванию и вычитанию прямоугольников
Мне кажется я придумал какую-то дичь. Но она определённо должна работать сильно быстрее чем первый вариант на UPDATE. Плюс формально можно её сделать много уровневой, а не двух-уровневой. Правда кодить это будет всё потом больно.
P.S. погуглил, кажется я тут "родил" двумерную sqrt-декомпозицию...
Как собеседует Google: чему быть, чего не миновать