Задача из Ozon: Golang собеседование

Поделиться
HTML-код
  • Опубликовано: 16 окт 2023
  • Мой курс по разработке микросервисов: clck.ru/389FPG
    Мой Boosty: boosty.to/olezhek28
    Linkedin: / olezhek28
    Telegram-канал: t.me/olezhek28go
    В этом ролике мы разберем популярную задачу с golang собеседований. Golang нынче стал хайповым языком программирования и многие люди переходят на него с других языков. Поэтому и важно научится решать эту golang задачку, чтобы не ударить в грязь лицом на собесе для golang разработчика. Можно сказать - этот ролик небольшой урок по golang, потому что для понимания некоторых аспектов этой задачи нам нужно заглянуть в go поглубже. На практике golang порой бывает неочевидным и важно понимать, что за этим стоит. И ещё, в конце ролика я накинул пару вопросов на подумать для вас. Смотрите до конца и пишите свои ответы в комментах.

Комментарии • 130

  • @Erdaulet100
    @Erdaulet100 5 месяцев назад +12

    Олег вырост, когда-то смотрел собеседование на middle разработка, а уже ведущий разраб и сам уже контент пилит)

    • @olezhek28go
      @olezhek28go  5 месяцев назад +1

      Как говорится: «все течет, все изменяется»

    • @Halatam610
      @Halatam610 3 месяца назад +1

      Ждём курсы )))

  • @ampership
    @ampership 5 месяцев назад +7

    Очень понравился стиль изложения, и задачка интересная. Хотелось бы видеть еще подобные видео с Гошными премудростями )

    • @olezhek28go
      @olezhek28go  5 месяцев назад

      Спасибо:))) думаю еще будет

  • @spruslaks26
    @spruslaks26 4 месяца назад +2

    Thanks for detailed explanation

    • @olezhek28go
      @olezhek28go  4 месяца назад

      Did you read subs?) Is it helpful?

    • @spruslaks26
      @spruslaks26 4 месяца назад

      I understand Russian, I just have difficulties with writing, so I did not use subs. @@olezhek28go

    • @olezhek28go
      @olezhek28go  4 месяца назад

      Interesting:) Where are you from?)

  • @egesihora4761
    @egesihora4761 7 месяцев назад +5

    Олег объясняет как боженька. Так чётко и просто всё разложил, спасибо!

    • @olezhek28go
      @olezhek28go  7 месяцев назад

      Спасибо, рад что понравилось:)

  • @madbad1310
    @madbad1310 8 месяцев назад +1

    Очень понравилось, спасибо

  • @rasulikv
    @rasulikv 8 месяцев назад +11

    очень понравился стиль изложения, поэтому было бы круто увидеть больше видеo про подобные тонкости🙂

    • @olezhek28go
      @olezhek28go  8 месяцев назад

      Спасибо:) буду стараться делать новые видео

  • @SHALfEY088
    @SHALfEY088 7 месяцев назад +3

    Требуем больше познавательных роликов!

    • @olezhek28go
      @olezhek28go  7 месяцев назад

      Если получится, то в эти выходные буду снимать :)

  • @ghvddacvasfxghefc3988
    @ghvddacvasfxghefc3988 8 месяцев назад +15

    for range возвращает index, value. Если запрашиваем одну переменную, то индекс. Поэтому 0,1,2,3,4

    • @olezhek28go
      @olezhek28go  8 месяцев назад

      верно)))

    • @aleksanderpeshkin2266
      @aleksanderpeshkin2266 Месяц назад

      Покажи конечный продукт где такое применяется с горктинами и каналами !! А то весь Ютуб показывает код , а где это работает и какую пользу несёт не ясно . Чтобы понимать зачем вообще такое спрашивают

    • @maxtheguy9783
      @maxtheguy9783 7 дней назад

      @@aleksanderpeshkin2266 без разницы от того понимаем мы или нет зачем такое спрашивают - спрашивать все равно будут) и если хочешь устроиться - знать должен

  • @user-zh1wz1rh6x
    @user-zh1wz1rh6x 8 месяцев назад +2

    Очень классный формат, хочется больше таких примеров) Прикольно что сначала можно было попробовать самому решить задачу, а потом увидеть где не прав)

    • @olezhek28go
      @olezhek28go  8 месяцев назад

      Спасибо) думаю буду периодически делать такие ролики

  • @user-nt5zn4rg4l
    @user-nt5zn4rg4l 5 месяцев назад +1

    Формат отличный. Покачали задачу. Так намного интереснее

    • @olezhek28go
      @olezhek28go  5 месяцев назад

      Спасибо, рад что зашло:)

  • @user-fs3co7hy2t
    @user-fs3co7hy2t 8 месяцев назад +2

    респект за инфу, про то что в замыкания по прокидываются переменные, не знал, прокидывал всегда все через аргументы функции

    • @olezhek28go
      @olezhek28go  8 месяцев назад

      Круто, что узнал что-то новое:))

  • @rmwk991
    @rmwk991 7 месяцев назад +1

    Спасибо, и формат супер и было полезно. Пожалуйста, не останавливайся!)
    Меня на собесе ещё спрашивали как оставляя горутины сделать, чтобы числа выводились последовательно и желательно было набросать и объяснить пару вариантов

    • @olezhek28go
      @olezhek28go  7 месяцев назад

      Спасибо:) и какие варики в голову пришли?

    • @rmwk991
      @rmwk991 6 месяцев назад +1

      ​@@olezhek28go через каналы или wg.Wait() поставить в конец цикла

    • @Argon-X
      @Argon-X 5 месяцев назад

      ​@@olezhek28go мне кажется тут можно канал использовать и читать из него числа

  • @soundcloudlover
    @soundcloudlover 8 месяцев назад +5

    будут ли ролики по внутрянкам го? типа работа gc, аллокаторы памяти, планировщик горутин и тд

    • @olezhek28go
      @olezhek28go  8 месяцев назад

      Все может быть, но пока точно ответить не могу)

  • @victorkochkarev2576
    @victorkochkarev2576 8 месяцев назад +3

    Спасибо за рассказ о фигче loopvar.

    • @olezhek28go
      @olezhek28go  8 месяцев назад +1

      Наконец то нашел повод попробовать:)

    • @victorkochkarev2576
      @victorkochkarev2576 8 месяцев назад

      @@olezhek28go Штука интересная, но она вызывает у меня настороженность. Уже представляю ситуации, когда девелопер пишет код и этой активированной функцией, а в билд пайплайне это причуда не активирована - и код уходит в продакшн.

    • @olezhek28go
      @olezhek28go  8 месяцев назад +1

      С февраля это будет по дефолту в языке

  • @Mak_Sim0
    @Mak_Sim0 2 месяца назад

    Привет. Мне предлодили оффер в озон. Можешь рассказать чтото про перфоманс ревью и индексацию зп? Думаю отказаться только изза этого. Начитался отзывов на дримджоб

    • @olezhek28go
      @olezhek28go  2 месяца назад

      Напиши мне в личку в тг - olezhek28

  • @wqwwsqwsqess4165
    @wqwwsqwsqess4165 6 месяцев назад +3

    1)горутины не параллельны, а конкуренты, то бишь рантайм под коробкой решает как переключаться между ними, пока одна горутина спит другая работает
    2)мы берём индексы слайса, п не сами значения, поэтому такое и поведение

    • @olezhek28go
      @olezhek28go  6 месяцев назад

      1) ну врядли на одном принте будет какое-то переключение между горутинами

  • @artemkashipov9865
    @artemkashipov9865 3 месяца назад +1

    по поводу первого вопроса
    все будет работать абсолютно также как и на нескольких ядрах, никакой разницы нет с точки зрения планировщика. 4 выводится первой потому что у нее по сути кеш прогрет больше всего. там вроде как есть стек размером в один как раз для этого, чтобы брать оттуда задачи первыми. Правильно?)

  • @saimonshaplygin7867
    @saimonshaplygin7867 7 месяцев назад

    интересно, автор видео согласовывал нейминг видео? не будет ли каких-либо юридических проблем, так как Олег ранее работал в Озон?

    • @olezhek28go
      @olezhek28go  7 месяцев назад

      Это ж больше внимание привлечь, задачу то эту где угодно спросить могу , ибо уж очень популярная)

  • @Ra1nist
    @Ra1nist 7 месяцев назад

    Когда примерно будет старт курса по разработке микросервисов?

    • @olezhek28go
      @olezhek28go  7 месяцев назад

      Второй поток сейчас заканчивается, а новый будет уже после НГ думаю

  • @victorklimov5254
    @victorklimov5254 8 месяцев назад +8

    Такое поведение (4, 0, 1, 2, 3) повторяется. У меня предположение, что горутины с 0 по 3 ставятся в локальную очередь. А горутина с 4-кой ставится в LIFO часть глобальной очереди и оттуда и исполняется первой (потому что она уже есть в кэше процессора), а уже за ней те, что локальной очереди.

    • @olezhek28go
      @olezhek28go  8 месяцев назад +2

      Полагаю так и есть:) кстати, случаем нет статейки про это под рукой? а то я этот дивный факт знаю, но вот пытался статейку найти, чтоб кидать людям и обычно просто про очередь упрощенно пишут

    • @victorklimov5254
      @victorklimov5254 8 месяцев назад +1

      @@olezhek28go постарался поискать где я эту информацию взял, но не нашел сходу

    • @waffleboot
      @waffleboot 8 месяцев назад +5

      Размер локальной очереди 256. А так гуглить runnext, это поле у P. Новые горутины получают приоритет, при этом используют остаток временного слота горутины-создателя. Каждый go stmt забрасывает новую горутину в runnext и шедулер возьмет сначала горутину из runnext и только потом начнет разгребать локальную очередь.

    • @johnsc4521
      @johnsc4521 8 месяцев назад +1

      На русском я не находил ни одной толковой статьи. Есть на английском. Можно почитать с браузерным переводчиком. Только тутуб комментарии с ссылками не пропускает.

    • @olezhek28go
      @olezhek28go  8 месяцев назад

      @johnsc4521 странно, что ссылки не пропускает, вроде должен

  • @kamex3102
    @kamex3102 6 месяцев назад +2

    Спасибо, позновательно!
    17:40 Можно предположить что планировкщик задач GO в любом случае использует какой то алгоритм для выбора порядка выполненния задач в отведенное ему процессорное время. И он не просто выполняет их по порядку, а например пытается "усреднить" нагрузку дергая из разных частей списка задач.
    15:59 Если правильно понимаю первая переменная при исользовании range - индекс записи. ( индек, значение := range слайс)
    А вот почему такой вывод в 22 версии непонимаю. При планировании горутины делается снимок используемых переменных?
    Если выводить адрес переменной в 21 и 22 версии, наблюдается разное поведение. В 21 он в каждой горутине одинаковый. В 22 - каждый раз новый адрес. Причем как если передавать его как аргумент и если через замыкание. Не наткнулся в патч ноуте с ходу на это. Есть какой то док описывающий поведение?

    • @Alexey-gp7vc
      @Alexey-gp7vc 6 месяцев назад

      Загугли "Fixing For Loops in Go 1.22", ещё там внизу статьи есть раздел More Information с ссылками на дизайн-док и фак.
      А если вкратце и на пальцах - раньше переменная цикла имела областью видимости весь цикл, а теперь областью видимости будет только итерация цикла.

    • @mrApelsin4ikGaming
      @mrApelsin4ikGaming 27 дней назад

      не, там прикол том, что в шедулере у каждой М есть очередь фифо и одноэлементный лифо, мы в него кладем последний элемент, но и брать будем сначала из него

  • @user-by6lf1js6w
    @user-by6lf1js6w 6 месяцев назад +2

    Чтоб в выводе было 1-5, надо так: for _, i := range

    • @olezhek28go
      @olezhek28go  6 месяцев назад

      Верно!:)

    • @user-by6lf1js6w
      @user-by6lf1js6w 6 месяцев назад

      @@olezhek28go Спасибо за задачки!:) Кстати, я решил оставить в Print() вывод адреса WaitGroup. Результат меня удивил 0_o Адреса либо были разными все, либо частично были совпадения, либо все одинаковые. Вопрос: Потому ли это, что WaitGroup на стек попадает?:)

    • @Erdaulet100
      @Erdaulet100 5 месяцев назад

      Что-то не совсем понял, то есть вывод ключей или индексов слайса, дает последовательность?

    • @user-by6lf1js6w
      @user-by6lf1js6w 5 месяцев назад

      @@Erdaulet100 Привет)
      У слайса нет ключей (ключи есть у map). Слайс - это абстракция над массивом. У массивов и слайсов есть элементы, а у элементов есть индексы. В Go существует 2 способа пройтись по слайсу:
      1) использовать обычный цикл for:
      for i := 0; i < len(things); i++ {
      things[i] =
      }
      2) использовать цикл for range (что работает как с последовательностью в Python, но в Go это всегда либо слайс, либо массив):
      for i, v := range things {
      // i - это копия индекса текущей итерации 0...len(things)-1
      // v - это копия значения элемента things по индексу i (как будто v = things[i])
      }
      Записывать в копии i и v нет смысла в цикле for range. Они используются для чтения из них. Если нужно записать в элемент слайса в этом цикле, то, как обычно, используется запись things[i] =

  • @Alexey-gp7vc
    @Alexey-gp7vc 6 месяцев назад +1

    Стиль изложения - огонь! На Go не пишу, но почти ни с чем не ошибся. Могу только предположить, сколько тысяч человеко-лет гоферы потратили на дебаг таких ошибок))
    Впрочем, этот наш простой пайтон - тоже нифига не простой)

    • @olezhek28go
      @olezhek28go  6 месяцев назад

      Спасибо:))) на самом деле многие ошибки подобные в бест практисах учтены и некоторые люди не косячат в них и даже не понимают почему ахаха

  • @yarbersheer8559
    @yarbersheer8559 8 месяцев назад +3

    при log.Fatal defer не вызовется, поэтому пишет log.Panic )

  • @user-pg8ry1tm3t
    @user-pg8ry1tm3t 8 месяцев назад +1

    Тот случай, когда основной синтаксис языка видишь быстрей, чем читаешь в учебнике🥴

    • @olezhek28go
      @olezhek28go  8 месяцев назад

      Это хорошо?:)

  • @sverdloff
    @sverdloff 6 месяцев назад +1

    Всё, теперь в озоне разрешили defer ?))

    • @olezhek28go
      @olezhek28go  6 месяцев назад

      А запрещали?

  • @nikitajolobov4591
    @nikitajolobov4591 6 месяцев назад

    На сколько известно в GO рутины легковесные (2к) и одном ядре может быть несколько рутин, поэтому параллелизм сохраняется даже с одним ядром, поэтому и вывод такой

    • @olezhek28go
      @olezhek28go  6 месяцев назад +1

      Все так, но горутины то в очередь последовательно кладутся)

    • @kidayano
      @kidayano 5 месяцев назад

      параллелизм невозможен на одном ядре))) ядро физически не может выполнять больше одной операции за один тик процессора

    • @olezhek28go
      @olezhek28go  5 месяцев назад

      @@kidayano всё так, если мы гипертрединг не берем в расчёт)

  • @N-zk7vw
    @N-zk7vw 6 месяцев назад +1

    Задача топ! Да, простая. Да, боянистая. Но даже на таких задачах можно завалиться.

    • @olezhek28go
      @olezhek28go  6 месяцев назад

      Ага, иногда люди на ней такую базу выдают)

  • @user-ny3sl8lo8f
    @user-ny3sl8lo8f Месяц назад

    Всё элементарно просто, 4 ядерный процессор. Поэтому и получается такая последовательность. Четвёртое ядро 1, 2,3,4

    • @user-ny3sl8lo8f
      @user-ny3sl8lo8f Месяц назад

      Специально не смотрю комментарии. Верный ответ?

    • @olezhek28go
      @olezhek28go  Месяц назад

      А это на какой вопрос?) про ситуацию с го макс проц?

  • @TheDavBag
    @TheDavBag 7 месяцев назад +1

    азазза голову ломал, откуда 0 и нет 5
    угар, всем бобер кувра!

  • @retvain
    @retvain 8 месяцев назад +1

    пока смотрел видео, постоянно переключался на телеграмм свой думал что мне пришло сообщение и никак не мог понять, wtf, потом как дошло)

    • @olezhek28go
      @olezhek28go  8 месяцев назад

      Там реально слышно?) я че-то при монтаже не заметил(

  • @nickkim9479
    @nickkim9479 Месяц назад

    Олег, можно консультацию получить у тебя, по дису например, если да то где контакт спросить?

  • @user-rp5ej1ui4g
    @user-rp5ej1ui4g 8 месяцев назад +2

    дейстивительно боянистая задача. на первом же собесе по го ее спросили)

    • @olezhek28go
      @olezhek28go  8 месяцев назад

      Ага) тем и удивительнее, что еще не все научились ее решать

  • @alexgorodecky1661
    @alexgorodecky1661 7 месяцев назад

    Последняя загадка настолько меня впечатлила, что я понял что не писать на голанге выбор правильный 🤨 даже JavaScript привели в чувство, по сравнению с этим вашим Го

    • @olezhek28go
      @olezhek28go  7 месяцев назад

      Да на самом то деле это больше интересный момент, чем что-то важное на практике

  • @JIexaPol
    @JIexaPol 7 месяцев назад +1

    Это задача для миддла или джуна?

    • @olezhek28go
      @olezhek28go  7 месяцев назад

      Да такое и на сеньора спросить могут, просто ответ разной глубины устроит и конечно эта задача будет не единственной:)

  • @boriskorotaev2038
    @boriskorotaev2038 3 месяца назад +1

    хех, а я думал алгосики спросят на го, а нет - собес как старые джава собесы, где квиз на квизе

    • @olezhek28go
      @olezhek28go  3 месяца назад

      Ахаха алгосики в другой секции)

  • @96kw3
    @96kw3 8 месяцев назад

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

    • @olezhek28go
      @olezhek28go  8 месяцев назад +6

      А вы это мнение со стороны высказываете или сами на гошке пишете?) на мой взгляд почти все аспекты языка, которые вскрывает эта задача, регулярно встречаются на практике.

    • @96kw3
      @96kw3 8 месяцев назад

      @@olezhek28go побольше практических примеров для каких целей и я Вас благодарю и целую монитор с вашим кодом

  • @yarbersheer8559
    @yarbersheer8559 8 месяцев назад +4

    загадки для джунов ))) кто ж так range пишет))
    вопрос в догонку к GOMAXPROC(1). А какой порядок будет если мы перед wg.Wait() time.Sleep(1) добавим?)
    А если потом перед time.Sleep(1) добавим runtime.Gosched() ?)

    • @olezhek28go
      @olezhek28go  8 месяцев назад

      Исходя из моих прикидок, кажется что такой же, но может что-то упускаю) хотя…
      Слип это системный вызов, стало быть впору переключить контекст, дальше идет выполнение горутин в том же порядке и даже если секунды не хватит, то маин горотина же по идее залетит в глобальную очередь и оттуда наврядли раньше успеет вычитаться чем остальные, 1 к 61 как никак) но это так мысли в слух) надо завтра поиграть

    • @yarbersheer8559
      @yarbersheer8559 8 месяцев назад

      @@olezhek28go а вот тут и есть прикол ) Если делать слип без Gosched, то вывод будет 0 1 2 3 4, а если хоть раз до этого сделать Goshed, то уже 4 01 2 3 )
      Если просто порассуждать т.к. истинная причина не ясна, то получается при Sleep последний стек будет не не наших горутин, а слипа, поэтому исполнение горутин будет FIFO, а Gosched в свою очередь переключит на последнюю вызванную горутину т.е. будет 4 0 1 2 3 )

    • @waffleboot
      @waffleboot 8 месяцев назад

      Получается 0,1,... Наверное потому что schedule прежде чем жертву выбрать проверяет таймеры. Видимо sleep(1) проходит слишком быстро и schedule опять выбирает main горутину в checkTimers. Можно увеличивать время сна и в какой-то момент 4 из runnext запуститься, но если таймер успеет сработать, то main горутина через checkTimers может влезть вперед local queue, в любом месте. Если Gosched добавить, то текущая горутина уйдет в конец local queue, а scheduler возьмет 4 из runnext. В данном примере с глобальной очередью вообще ничего не должно происходить, ведь capacity локальной очереди 256 + timers heap у каждого P свой.
      P.S. Sleep(1) это не 1 секунда, а 1 наносекунда. Duration в наносекундах. Там где duration не стоит указывать просто int, об этом 75 глава 100 Go Mistakes

    • @olezhek28go
      @olezhek28go  8 месяцев назад

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

    • @yarbersheer8559
      @yarbersheer8559 8 месяцев назад

      @@olezhek28go оу... слип 1*time.Second это перебор для смены контекста) просто time.Sleep(1) ) вот такая у нас уличная магия... в рот мне ноги.

  • @AkramAzizmurodov
    @AkramAzizmurodov 8 месяцев назад +1

    Я ещё не понял loopvar. Что это?

    • @olezhek28go
      @olezhek28go  8 месяцев назад +1

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

  • @metua
    @metua 2 месяца назад

    а откуда взялся 0?

    • @olezhek28go
      @olezhek28go  2 месяца назад

      С нуля же цикл)

    • @metua
      @metua 2 месяца назад

      @@olezhek28goа точно, я подумал i это значения массива

  • @it1860
    @it1860 8 месяцев назад +2

    1

    • @olezhek28go
      @olezhek28go  8 месяцев назад +2

      поздравляю)

  • @luckytima2315
    @luckytima2315 7 месяцев назад +1

    Братик это хайлвл, это только учу гошку мне трудно понять что происходит =/

    • @olezhek28go
      @olezhek28go  7 месяцев назад +1

      Придет время и все поймешь;)

    • @luckytima2315
      @luckytima2315 7 месяцев назад

      @@olezhek28go да это вообще фэйл =/ я знал питон, пришел в универ там были ++ и java, я пострадал может недели 2 и все ок стало. Java даже понравилась, начала ковырять Go, начитался комментариев “go самый простой язык ко ко” но пока мне он больше боли доставляет =/

  • @vp_arth
    @vp_arth 3 месяца назад

    Устарело) Теперь итератор per-iteration, а не per-loop
    upd: а, блин, досмотрел)
    А загадка про конкурентность vs параллельность.

    • @olezhek28go
      @olezhek28go  3 месяца назад

      Ахах)
      Загадка про один тред то?

    • @vp_arth
      @vp_arth 3 месяца назад

      В js вообще всего один поток. И тем не менее конкурентности хватает)

  • @user-hd3qb8bm2e
    @user-hd3qb8bm2e 5 месяцев назад

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

    • @olezhek28go
      @olezhek28go  5 месяцев назад

      Ну камон, ирония же была:)