41:40 вранье чистой воды, если ошибетесь на собеседовании, даже если опечатаетесь, не важно как быстро вы исправитесь, в фидбеке напишут, что задачу не решил
@young_flex30775 сағат бұрын
Зачем позвали школьников на роль ведущих 😂😂😂😂😂😂😂😂😂 они ж даже разрешение трансляции нормальное выставить не смогли 😂😂😂😂😂😂😂😂😂
@anton6643Күн бұрын
Вторая задача разве это не обычный обход графа в ширину?
@ИнтернетСпасётМир2 күн бұрын
Как-то так, например: package main import ( "fmt" "slices" ) // composeStopToBusMap describes what buses arrive to every stop // for routes := [][]int{{1, 2, 7}, {3, 6, 7}} => map[1:[0] 2:[0] 3:[1] 6:[1] 7:[0 1]] func composeStopToBusMap(routes [][]int) map[int][]int { stopToBus := make(map[int][]int, len(routes)) for bus, busRoute := range routes { for _, stop := range busRoute { stopToBus[stop] = append(stopToBus[stop], bus) } } return stopToBus } // Use BFS to find minimum number of buses to reach the target stop func detect(routes [][]int, source int, target int, sb map[int][]int) int { var lvl int = 0 // This is zero level q := []int{source} // We start with the source stop at zero level skipBuses := map[int]struct{}{} // Store processed buses skipStops := map[int]struct{}{} // Store processed stops for len(q) > 0 { nextQ := []int{} // Next level queue with stops for _, checkingStop := range q { skipStops[checkingStop] = struct{}{} // Collect stops for the queue of the next level. for _, bus := range sb[checkingStop] { _, ok := skipBuses[bus] if ok { continue } skipBuses[bus] = struct{}{} for _, st := range routes[bus] { if _, ok = skipStops[st]; !ok { if st == target { return lvl + 1 } nextQ = append(nextQ, st) } } } } // We didn't find target stop during search at this level, // Since we have collected some stops for the new queue, // then let's search again for a target stop at the next level. lvl++ slices.Sort(nextQ) q = slices.Compact(nextQ) } return -1 } func numBusesToDestination(routes [][]int, source int, target int) int { // Build graph where each stop is associated with buses that arrive to it sb := composeStopToBusMap(routes) // Don't need to travel when source and target is the same if source == target { return 0 } // Check if source and target stops are among visited by buses _, ok := sb[source] if !ok { return -1 } _, ok = sb[target] if !ok { return -1 } return detect(routes, source, target, sb) } func main() { routes2 := [][]int{{7, 12}, {4, 5, 15}, {6}, {15, 19}, {9, 12, 13}} fmt.Println(numBusesToDestination(routes2, 15, 12)) routes5 := [][]int{{1, 2, 3}, {3, 4, 5, 6}, {6, 7}, {6, 7, 8}, {7, 11}, {8, 9, 10}} fmt.Println(numBusesToDestination(routes5, 3, 10)) }
@Prof-Shor2 күн бұрын
Паша, хорош хлебать)))
@artemkas41913 күн бұрын
Спасибо большое за такой хороший пример решения более-менее реалистичного задания! А вот если бы было желание вынести часть логики, не связанной с доступом к данным (например, проверка пересечений интервалов бронирования и времени работы мастерской) из репозитория на слой ApplicationService/UsesCases, то как в этом случае быть с транзакциями - добавлять АПИ транзакций (а-ля TransactionManager) и оборачивать в транзакцию несколько запросов репозитория уже на уровне AplicationService?
@SeverSiter1Күн бұрын
Да.
@AkaEretic4 күн бұрын
Супер! Ага с append вообще надо быть очень внимательным
@maxsmeh8 күн бұрын
Когда смотрю мок интервью, чувствую себя Светлаковым из нашей раши, который смотрит телек
@АлександрРаков-м7п13 күн бұрын
func tee будет читать синхронно в вашем решении, и если произойдет блокировка одного из каналов на серверной стороне, второй будет его ждать. Для реализации асинхронного решения: func tee(in <-chan int) (a <-chan int, b <-chan int) { a = make(<-chan int) b = make(<-chan int) buff1 := make([]int, 0, 5) buff2 := make([]int, 0, 5) for v := range in { buff1 = append(buff1, v) buff2 = append(buff2, v) } go func() { defer close(a) for _, v := range buff1 { a <- v } }() go func() { defer close(b) for _, v := range buff2 { b <- v } }() return a, b }
@ИнтернетСпасётМир12 күн бұрын
Оно не асинхронное - в нём надо ждать закрытия канала in.
@thenexia11113 күн бұрын
func tee(ch1 <-chan int) (ch2 chan int, ch3 chan int) { ch2 = make(chan int) ch3 = make(chan int) go func() { defer close(ch2) defer close(ch3) for num := range ch1 { ch2 <- num ch3 <- num } }() return }
@ИнтернетСпасётМир12 күн бұрын
Не будет работать, если чтение происходит только из одного канала.
@ИнтернетСпасётМир14 күн бұрын
Решение для задачи tee будет работать только если вы планируете последовательно читать из a и b канала приходящее значение, а если вы хотите послать в in 1,3,5 и прочитать эти значения только из одного канала, тогда цикл чтения из канала in зависнет на записи в другой канал, который не читается. Если добавить default, тогда канал который не читается, будет пропускаться. Но это решение не подходит, потому что мы можем захотеть прочитать из второго канала значения 1,3,5 после того, как эти значения были прочитаны первым каналом. Для решения такой задачи можно попробывать записывать каждое значение в оба канала в отдельной горутине, но так потеряется последовательность значений, потому что горутины исполнятся в случайном порядке. func tee(in <-chan any) (<-chan any, <-chan any) { a := make(chan any) b := make(chan any) go func() { defer close(a) defer close(b) wg := sync.WaitGroup{} for v := range in { wg.Add(1) v1 := v a1, b1 := a, b go func() { defer wg.Done() for range [2]int{} { select { case a1 <- v1: a1 = nil case b1 <- v1: b1 = nil } } }() } wg.Wait() }() return a, b }
@alexandreabramtsev916014 күн бұрын
Мне кажется, в первом примере строки 65 и 70 лишние. Я за то чтобы был мьютекс чуть длиннее - с 63 строки по 72. А так - интересная тема (как и веселый нэйминг xD)
@mistandok14 күн бұрын
а sync.Once нельзя использовать по условиям задачи?
@Jonatanail14 күн бұрын
прикольная задача, на закрытие канала не нужен мьютекс, у него там под капотом свой есть
@MrLotrus18 күн бұрын
1:04:00 Как ни странно говорят о таких вещах как секционирование, но ни разу не слышал про нормализацию таблиц в мок собесах. А ведь это база). И из вопроса непонятно как именно стоит разбивать таблицу. Может там 1000 колонок.
@MrLotrus18 күн бұрын
1:00:00 По-моему правильней действительно посмотреть через запросы какая селективность. Вот так предполагая по диапазону есть риск ошибиться. Ведь записи по этим полям могут быть распределены неравномерно
@MrLotrus18 күн бұрын
50:00 hash индекс имеет много нюансов и ограничений. Большой вопрос стоит ли его использовать ради возможного мизерного выигрыша
@thre-c7b19 күн бұрын
самый бестолковый собес из всех что я встречал кто то из него вообще понял какие задачи на го этот парень может сделать?
@KeibyBigBalls21 күн бұрын
Даня красавчик! Акиму спасибо за содержательное интервью, за пояснения и рекомендации к изучению
@blu3h4t22 күн бұрын
ты знаешь что имеет аптаймы 9999 да? и это не го
@Andrii-mt8ef23 күн бұрын
вкатунов с быдлокодинга на пхп тяжело на нормальные языки перетащить не просто так чтобы они выучили синтаксис и функции стандартной библиотеки а имели глубокие знания не только о го но и о общем программировании которое не применимо к пхп например потоки, tcp/udp и сисколлы - тестовые на го я бы делал не на написание каких-то рудиментарных рест апи а на что-то более интересное типа задач на конкурентность
@MouseSilent23 күн бұрын
Зашел на видео увидев превью - "как я перешел с PHP на golang", я думаю, что ответ на этот вопрос такой - "Отлично перешел!". Так же можно было назвать видео "как я перешел с PHP на любой другой язык?" - "Замечательно перешел!!"
@Tosha.V23 күн бұрын
научите меня бесплатно, очень хочется писать приложения работающие годами)
@3ombieautopilot23 күн бұрын
Отличный видос! Будут ли еще задачи с собеседований? Вы отличный наставник.
@ipavlyukov23 күн бұрын
Конечно, впереди также видео с обзором неочевидных Баз Данных!
@Andrii-mt8ef23 күн бұрын
@@ipavlyukov неочевидных в плане подводных камней? например различия в имплементации SQL? или какую-то диковинку вроде непопулярных баз данных? расскажите лучше про S3 во втором случае и про разные фичи вроде CAS
@andreybalatsan933624 күн бұрын
Как меня порадовал смех, когда и nginx упал
@ivantimofeev251524 күн бұрын
Ну к слову в первой задаче сейчас в Go 1.23 это уже не так
@buginsystem892525 күн бұрын
А где-то можно почитать подробней про использование кэшей CPU при переборе слайсов/массивов? Об этом говорят на 16:20, не смог быстро нагуглить на английском
@Nikolai-k7h29 күн бұрын
Задачка крутая, вопросы норм. Но по устройству мапы слишком упарываетесь, как будто эти знания каждый день в работе используете.
@thenexia111Ай бұрын
Хорошо объясняешь на самом деле. Но челы пришли смотреть как решать задачки на многопоточку без минимальной базы, поэтому много разжевывания того, что есть везде
@lisov1k492Ай бұрын
с кайфом
@MrLotrusАй бұрын
Хорошая задачка. И асинхронность, и немного алгоритмы.
@Ярослав-е2шАй бұрын
Почему дедлок этр паника?
@Ярослав-е2шАй бұрын
Вроде бы, clear(batch) не будет работать, он все значения к зиро вэлью приведёт просто, и длина не станет равна нулю
@Ярослав-е2шАй бұрын
Для мап clear удаляет элементы
@davidikus29Ай бұрын
Ссылку на гитхаб конечно никто не оставил
@oo_ilinАй бұрын
В последней задаче mergeChannel решение с worker pool не корректно относительно первичной постановки задачи. В первом решении каналы читались все одновременно и как только в них поступали данные, они сразу вылетали в выходной канал. Как только канал закрывался, он переставал слушаться, но остальные продолжали одновременно сливать данные в выходной канал. Во втором решении мы по факту слушаем первых пять каналов и если никто из них не будет закрываться, то значения из всех остальных каналов не будут мержиться никогда. А это уже не мерж каналов. Так что второе решение не корректно с точки зрения бизнес логики
@thestrikemАй бұрын
В условии не было обговорено, мы допускаем тот факт, что сейчас одновременно не считываем из всех каналов, которые нам передаются, потому что просто физически не можем это сделать, т.к. каналов слишком много. Релевантно будет повысить константу с 5 на большее число в продакшн варианте, в видео просто обсуждался воркер пул в контексте этой задачи. Здесь, к сожалению, мы жертвуем тем, что не читаем все каналы одновременно ради того, чтобы не взорваться и итеративно все проработать, поэтому где-то на той стороне допускаем, что какие-то горутины-отправители в канал припаркуются в ожидании прослушивания. Этот трейдофф стоило упомянуть в решении, согласен
@nikitayaskevich813Ай бұрын
Крутое и детальное объяснение, спасибо.
@alexzav1327Ай бұрын
Видео очень полезное, иногда возвращаюсь к нему, чтобы что-то вспомнить.
@thestrikemАй бұрын
Кстати, можно глянуть такой же ультимативный видео-ролик по слайсам у меня на канале)
@leshi_1Ай бұрын
Совсем не читает 😂
@dmitrykorolev4943Ай бұрын
Илья из завтра, после прогули, видать начал готовить видео про тесты)) Уже когда-то давно видел твоё видео по теме go, у тебя хорошо получается объяснять, т.ч и про тесты будет интересно посмотреть! Удачи!
@lukin_ioАй бұрын
@Эйч Навыки - менторская программа Вы б шарили исходники тех задач, которые задаете? :-) я что-то на ya.cc не нашел по той ссылке что в видео.
@QazaqCodeАй бұрын
Все зависит от details, а details зависит от fabric 😂😂
@staspanyukov4822Ай бұрын
DDD на мидла на тестовое.. никто не оценит, многие даже и не поймут… А так красиво все делаешь, явно не мидл)
@ChorumTheDevourerАй бұрын
"Какого-то доктора". Далеки не хотят привлекать внимание только одного Доктора. "Доктор? Доктор Кто?"
@MrPaishoАй бұрын
ещё замечу, что если в данном случае констраинт подходит, то в других случаях, когда не получится задать ограничения, можно использовать select for update
@ipavlyukovАй бұрын
Верно! Есть ситуации, когда можно использовать другой способ блокировки, а именно SELECT FOR UPDATE. В нашей же ситуации, он неприменим, поскольку в момент проверки в БД еще нет строки под блокировку.
@MrPaishoАй бұрын
Есть воркшоп блокироваться можно об него
@ipavlyukovАй бұрын
@@MrPaisho Согласен, это отличный вариант, если мы готовы к тому, что заблокируем весь склад для конкурентных бронирований. Немножко снижаем RPS, зато упрощаем код и запросы к БД!
@MrPaishoАй бұрын
@@ipavlyukov а как работает констраит? Он, насколько я понимаю блочит всю таблицу, разве нет?
@ipavlyukovАй бұрын
@@MrPaishoв том то и дело, что нет. Блокировка частичная, благодаря индексу.
@MrPaishoАй бұрын
я правильно понимаю, что в доменной модели должны быть сущности, которые все используют, а по факту получается, что в том виде, котором они есть, они нафиг никому не сдались? Какая-то шизофрения эти паттерны.
@dpnpdАй бұрын
В общем и целом все используют go-project-layout и на него натягивают трехслойную архитектуру, сдались тогда когда в бизнесе много человек, чтобы не писать отсебятину и все было понятно, а не терять время на изучения новых патернов
@stanton_archАй бұрын
"Далеки" всё никак не угомонятся🤣
@artie5913Ай бұрын
43:10 разве такая проверка достаточна? Что если ваше новое бронирование будет содержать внутри себя время уже существующего?
@ipavlyukovАй бұрын
Верно, нужно это условие проверять в обе стороны. То есть и для нового отрезка и для старого. Именно потому, что условие становится громоздким, мы дальше используем готовый оператор OVERLAPS.
@insentijkeАй бұрын
56:18 канал из тикера возвращается же напрямую (ticker.C), метода .C() у time.Ticker нет